For a single comparison of arbitrary bitmaps, no.
There are some scenarios though that allow for certain optimizations.
1) If you need mip-maps of these bitmaps somewhere else in the code, and you have already calculated them, you can compare lower-resolution mipmap levels first (starting with the 1x1 degenerate case). This will cut your computing time for the more obvious reject cases, but it will increase computing time for the accept cases. In other words, the more similar the images are, the longer the comparison will take. So this would be beneficial only for cases where there are lots of fails and few passes.
2) If you are using some sort of pixel-perfect collision detection masks, you can first compare these. If the collision masks aren't equal, neither are the bitmaps.
3) In many cases, you can use direct access through the line pointers of the BITMAP struct. For lower color depths, this means that you can compare 2 or 4 pixels at once. This won't work with video or system bitmaps, though.
4) Store some sort of checksum along with the bitmap when loading / creating, and compare that first. A checksum comparison is very cheap once you have the checksum, but it may weed out a huge part of otherwise expensive comparisons. Again, this is only beneficial if the checksum generation process is less time-critical than the actual comparison. It's useless if you only ever compare the two bitmaps once in the program.
In many cases, you can use direct access through the line pointers of the BITMAP struct. For lower color depths, this means that you can compare 2 or 4 pixels at once.
Best to use libc's memcmp in that case; that will probably compare memory areas in the most optimal way already.
Good point.
But bitmaps might have some undefined bytes, like padding bytes in the end of a row, which might be different, even if the bitmaps are equal. memcmp() might make you believe they are different.
But bitmaps might have some undefined bytes, like padding bytes in the end of a row, which might be different, even if the bitmaps are equal. memcmp() might make you believe they are different.
Not if you tell it to only compare to the end of the line...
I've wrote a program - don't know if there's one already, but mine's better that takes in a bitmap file (e.g. a map of a game/screen/etc), extracts all the tiles, saves the unique ones out (resizing if you want it to) and generates a simple map file/array of the tile map. I'll post it to the depot later if anyone's interested. I just wanted to get it to go a bit faster, so I'll try the memcpy. At the minute a 16x16 tiled bitmap of a bitmap of 3000x400 pixels takes about 20 seconds, which isn't that bad considering it's not a real-time game or anything.
If you don't want to compare two bitmaps for their exact identity, but say find out how similar they are, there are better approaches. Not intending to sound vague, I don't want to force the information on you, and I also don't want to write long posts risking noone's even interested.
edit: And I did well not to spit out all the drivel. After re-reading your last post I can see now it would have been pointless. Leaving the original post for archiving purposes, even though it isn't helpful in any way.
Neil: I did this once as well. But the code is now lost in the mists of time..
Maybe this?
Comparing byte by byte, p1 and p2 will go over their memory starting at [0,0], the begining; if the memory pointed to is different 0 is returned. If all matches, while loop ends and 1 is returned.
The while condition means: while p1 points into a zone of memory in b1 (of course b1 and b2 must have equal h and w, so no matter what bitmap you use), go on. The &b1->line[b1->w * b1->h * 24] is the latest position of the bitmap isn't it?
Shouldn't that be != ?
Neil: I did this once as well. But the code is now lost in the mists of time..
Yeah, but mine works
I'll try that sample out and see if it's any faster.
Boo! Hiss!
Maybe this?
It doesn't work and it's no faster. I'll just leave it using the getpixel code thanks anyway.
It's not finished yet and just a windows binary, but
http://retrospec.sgn.net/users/nwalker/TileExtracter.zip
There are two maps in the zip, the config out of the box is for the last 10 or so rows of Marauder. Just change the offsets if you want to do the whole map.
If you do Rex (it's just two screens), change the tile size to 8 pixels and offsets to 0. All outputs go to the 'extract' directory. I plan on making it save to map/fmp format for Mappy as well. Delete the 'extract' directory before you run each as it won't do it for you.