I put the interesting parts of my Litho test into a lib and uploaded it to my site. I haven't bothered to test the lib with MASM but don't really see any problems with it. The main source file has function descriptions and parameters, you can get the lib and source from the libs page on my website. If someone gets a chance to test it with MASM real soon I will address any problems. To see the effects you can download the litho program in this forum.
Posted on 2004-08-06 11:54:09 by donkey
I had a bit of time so I tested the lib with MASM and it works fine. This is the equivalent of the Litho program in MASM:

This one has the current version of the lib.

There was a small bug in the LoadDIBFromFile function, it has been corrected.
Posted on 2004-08-06 20:00:03 by donkey
Well, I got tired of the color problems with LoadImage/LR_LOADFROMFILE and NT4. Some bitmaps just look like crap when I use it so I wrote a replacement for LoadImage and added it to the library. LoadDIBFromFile will load a BMP image and properly convert it to a DIB section. It does not do any color dpeth adjustment so you will have to convert it to a 32bit DIB section to use it with the other functions.
Posted on 2004-08-07 10:47:34 by donkey
Added a couple of functions, Get/SetDIBPixel to directly get or set the color for a particular pixel in a DIB section, they are really for internal use so they require a bit of information but are fairly simple to use. Also added a pretty lame flood fill, it is a recursive flood fill so it can't really fill an area greater than about 175x175 but that was enough for TBPaint (max 48x48) which is what it was written for, I could never figure out the non-recursive flood fills. Also added a direct to DIB GradientRect, this will work under 95/NT4 as it uses no GDI functions (except GetObjectA), it also writes directly to the 32 bit DIB section.

New upload at my website.

BTW I use the FPU for the gradient fill, is there an algorithm that can do one in integers. I sort of came up with my own algo because I couldn't find any others.

Oh PS, almost forgot added a Bresenham Line routine as well.
Posted on 2004-08-08 14:23:36 by donkey
Well, I had hoped for a few comments or suggestions but I geuss not. At any rate, there doesn't appear to be much interest in this project so I'll stop bugging everyone, I just wanted to make sure that I made the interesting stuff from TBPaint available before I left. That way what I learned from it will still be around even if I am not here to answer questions. Here's a screenshot of the gradient fill...
Posted on 2004-08-08 14:57:11 by donkey
Really interesting work! :alright:

I have a suggestion: how about a variant of this functions that can work not on the whole picture, but a region of it (I mean a GDI region, consisting of an array of RECTs)?



There you go, I've shown interest and gave you a suggestion. So you've got no excuses to give up now ;) :grin:
Posted on 2004-08-08 15:25:56 by QvasiModo
Donkey, nice to see your work - I haven't had much time lately (school started, and I have some stuff to pay attention to), but your stuff sounds good.

As for gradient fill, I thought I saw a MMX routine for it somewhere here on the board, but couldn't find it :(
Posted on 2004-08-08 15:33:42 by f0dder
Hi QvasiModo,

I would have to think about that, the only functions that would need it are the colour effects and rotate. I had originally intended to have it done via a copy/paste inside TBPaint v2.0, where I would copy the part of the image I wanted then apply the effect and paste it. It would still be faster than modifying the functions to handle individual pixel positions. Right now the colour effects just blast through every pixel at high speed, not checking anything along the way. If I had to insert alot of conditionals it would be difficult to do it without reducing the speed alot. Perhaps a function to copy a portion of an image and then you could build your own routines ?
Posted on 2004-08-08 15:37:19 by donkey

Donkey, nice to see your work - I haven't had much time lately (school started, and I have some stuff to pay attention to), but your stuff sounds good.

As for gradient fill, I thought I saw a MMX routine for it somewhere here on the board, but couldn't find it :(


Tola had a routine but it has been removed, as well the MMX routine appears to have went south. I could not find a good (with no LineTo or SetPixel) routine anywhere on the board. However for my purposes it is still faster than the msimg function and is fast enough for TBPaint if I ever get back to it.
Posted on 2004-08-08 15:38:59 by donkey
Hi QvasiModo,

I have included a CopyDIBRects function. It uses the GDI for PatBlt and BitBlt because I can't beat those two functions as they take advantage of hardware acceleration. Other than that it can take an array of RECT structures, (x,y,w,h) and creates a new bitmap that is the minimum size to contain all the RECTs. It then fills the bitmap with the color specified and copies the portions of the image to it. This can be used for transparent bitmaps from regions I guess, if you set the background color to your transparency and then Blt the parts you want.
Posted on 2004-08-08 17:16:54 by donkey
Hi donkey,
I have some gradient routines, not really standalone procs since I used them in some my porgrams, so I can't post them here now since they will not be usefull, but I can put all that into one standalone example for you (MASM only, sorry I dont use FASM) so you can create lib or whatever. I have vertical and horizontal gradient procs and I used FillRect(). They are not MMX or FPU thought, I am not sure how fast they are, but they work fine for me esspecially since I use backbuffering.

Just let me know if you need them I will be glad to help ya and I can do that for tomorrow (too busy right now).
Posted on 2004-08-08 18:02:40 by Mikky
Hi Mikky,

Thanks for the offer but I figure that for the purposes that I am envisioning it is fine the way it is. I was mostly just wondering if anyone managed to do a smooth gradient without floats for the steps. The FillRect idea is a good one, I think that uses BitBlt which is very fast, actually faster than a DWORD copy for some reason when you have to access pixels by x/y position. My gradient fill uses a Bresenham line algo that writes directly to the DIB memory though like you I haven't tested it thoroughly, it outperformed GradientFill on my system, but that is secondary to the idea that it is WinNT4 and Win95 compatible. TBPaint was designed from the start to be compatible with all 32 bit versions of Windows and the missing gradient for those 2 in V1.x bugged me alot. Version 2 which may or may not be completed was supposed to have replacements for every GDI draw but the Blt functions and was supposed to be compatible across the board.

Others would probably be interested in a faster version though, there seem to be a lack of examples on the board. Not that it's hard to come up with one but it would be interesting to see which is the fastest way and see some comparisons.

PS GoAsm not FASM :)
Posted on 2004-08-08 18:15:56 by donkey
Ok here's my example, let me know what you find out :alright:
Posted on 2004-08-08 19:24:17 by Mikky
Hi Mikky,

Nice, I will have to design some speed tests, like maybe filling 1000 100x100 bitmaps and see how they do. Not tonight though.
Posted on 2004-08-08 20:19:47 by donkey
Hi Mikky,

I haven't tested it but I think your gradient is faster than mine, perhaps by quite a bit.
Posted on 2004-08-08 21:30:00 by donkey
There was a typo in the CopyDIBRects function that caused it to improperly calculate the size of the resulting bitmap. I have corrected it and uploaded a new version to my website. I think this takes care of the bugs for now, I have pretty much run the stuff through. I only tried the CopyDIBRects function with 4 rect structures but it should be OK for any number. It would have been nice to work out a scheme that would eliminate overlapping parts of each rect but I can't think of a way to do it efficiently.
Posted on 2004-08-08 22:22:11 by donkey
Donkey, perhaps you could use ExtCreateRegion + GetRegionData? ExtCreateRegion seems to optimize the RECT data it is passed... but it's probably way too much overhead.
Posted on 2004-08-09 02:14:14 by f0dder
Hi fodder,

I will look into it. I am trying to avoid any GDI functions except the Blt family as they are hardware accelerated on all OS versions as far as I know. 2K and XP have many more functions that have acceleration as does ME but since the lowest compatible OS versions have to be 95/NT4 I want to write to those OSes. Region functions aren't that bad but I doubt that any real optimization of the RECTs can be done in a way that would actually save time. I want to use this function to copy a single RECT as well. Also I have thought a bit about what the optimizer would have to do, not just find the intersection of RECTs but also create new RECT structures where the resulting RECTs are the fewest possible but also the largest possible in order to make optimal use of BitBlt. A pretty tall order but something to mull over.
Posted on 2004-08-09 02:28:08 by donkey
The ExtCreateRegion+GetRegionData calls will probably take up more time than overlapping would consume... and in most cases you probably won't get overlapping regions... I think in most cases people would feed sane RECTs to your code :)

I'll try thinking a bit about an algorithm at school today, nevertheless - there's a couple of boring subjects and I'd rather think about code :)


One place where these optimizations do matter, is when creating region data from bitmaps by transparent pixels - especially with silly "per-pixel" routines, but also the "pixel span" routines benefit from it...
Posted on 2004-08-09 02:44:25 by f0dder

Hi QvasiModo,

I have included a CopyDIBRects function. It uses the GDI for PatBlt and BitBlt because I can't beat those two functions as they take advantage of hardware acceleration. Other than that it can take an array of RECT structures, (x,y,w,h) and creates a new bitmap that is the minimum size to contain all the RECTs. It then fills the bitmap with the color specified and copies the portions of the image to it. This can be used for transparent bitmaps from regions I guess, if you set the background color to your transparency and then Blt the parts you want.

Great, I had thought of working directly with the RECTs but this is probably a lot faster. :)
It would have been nice to work out a scheme that would eliminate overlapping parts of each rect but I can't think of a way to do it efficiently.

Any region function from GDI would do the trick (ExtCreateRegion probably being the fastest, as f0dder pointed out), but it might not even be necessary if the region is precalculated, or used several times. So I wouldn't worry about that, it's best left to the caller to optimize the RECTs.
Posted on 2004-08-09 10:18:37 by QvasiModo