draco1023 / aforge

Automatically exported from code.google.com/p/aforge
Other
0 stars 0 forks source link

Handle negative strides in UnmanagedImage.ToManagedImage #286

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
I have a third-party library that creates Bitmaps (and BitmapDatas) with 
negative strides. This is apparently used to indicate that the image is stored 
with lines in reverse order in memory.

An UnmanangedImage generated from this BitmapData also has a negative stride, 
and UnmanagedImage.ToManagedImage fails horribly. The attached patch fixes that 
case; I have not tested it in any other uses.

The only way I've found to generate such a Bitmap using the Bitmap constructor 
that takes a stride, and specifying a negative stride. Note that with a 
negative stride, scan0 points to the top-left pixel, not the first pixel in the 
buffer.

Also attached is the test program I used. (Yes, I know the code leaks all over 
the place.) Assuming a file called c:\data\image.bmp is present on your 
computer, it should create c:\data\image2.bmp and c:\data\image3.bmp. 2 and 3 
should be identical, and flipped vertically relative to image.bmp.

Original issue reported on code.google.com by dales...@gmail.com on 1 Feb 2012 at 10:20

Attachments:

GoogleCodeExporter commented 9 years ago
On further thought, image2.bmp and image3.bmp won't be very good duplicates of 
image.bmp unless the latter is 1bpp (50% chance) or 32bpp, or you copy the 
palettes, which I didn't do in my test.

Original comment by dales...@gmail.com on 2 Feb 2012 at 2:15

GoogleCodeExporter commented 9 years ago

Original comment by andrew.k...@gmail.com on 2 Feb 2012 at 9:49

GoogleCodeExporter commented 9 years ago
The suggested fix actually just touches the very top of big iceberg. To me it 
does not fit the problem completely, but just fixes one single function.

All other classes (image processing filter) simply don't even suspect that 
stride could be negative. Even the UnmanagedImage will fail in other method, 
like Clone():
>> IntPtr newImageData = System.Runtime.InteropServices.Marshal.AllocHGlobal( 
stride * height );

The issue needs to be fixed either for all methods/classes, which s quite a 
lot. Or the constructor of the UnmanagedImage needs to be fixed to throw 
exception for negative stride. And then some conversion routine needs to be 
added in user’s code, which takes care of converting 3rd party images into 
proper ones. I would go for the last one.

Original comment by andrew.k...@gmail.com on 2 Feb 2012 at 8:27

GoogleCodeExporter commented 9 years ago
I don't know why that vendor did things backward, but .NET handles such images 
correctly.

From a brief look through the edge detectors, I think the filters proper might 
not need to be changed at all. As far as I can tell, any time where stride is 
used as a pointer offset will work without modification, and the filters seem 
to only ever use the stride that way.

Looking around elsewhere, Apply(Bitmap) and Apply(BitmapData) will need to be 
touched in the base filters, so they don't barf on negative-stride 
bitmap(data)s. BaseUsingCopyPartialFilter would also need to be touched in 
ApplyInPlace(UnmanagedImage,Rectangle). I'm sure there are other places, but if 
it turns out to be merely "touch every base filter", it might still be worth 
the effort. I'll investigate more over the weekend.

Original comment by dales...@gmail.com on 2 Feb 2012 at 10:26