[Mono-winforms-list] Are 16-bit and 24-bit pixel formats
supportedby libgdiplus?
Jonathan Gilbert
2a5gjx302 at sneakemail.com
Wed Nov 9 23:00:55 EST 2005
At 03:15 PM 09/11/2005 +0100, Kornel wrote:
>Hi,
>
>bmpcodec.c loads 16-bit and 24-bit bitmaps as 32-bit and has no support to
>save bitmaps in 16-bit or 24-bit format. Is this because libgdiplus has no
>support for these formats or is this only a limitation of bmpcodec.c?
When I first started playing with mono, libgdiplus had "support" for 24-
and 32-bit pixel formats only. By this I mean that it would, on the
exterior, appear to be using those different types, but internally, it
would *always* use 32-bit ARGB. This is convenient for most things because
it is what Cairo itself uses (all Cairo supports for many operations, if I
understand correctly), and for those few inconvenient things like
LockBits/UnlockBits, the code would allocate a second buffer and translate
the pixel format to/from whatever was requested. Thus, Bitmap.PixelFormat
would return Format24bppRgb, Format32bppRgb or Format32bppArgb, but
anything other than Format32bppArgb would result in translations. This is
actually still the case for non-indexed Bitmap data!
What I added to libgdiplus about 10 months ago was support for 1-, 4- and
8-bit indexed images. Actually, most of the code was already able to handle
8-bit images, as it can still compute the pixel size & stride & such in
terms of the depth & components, but a good amount of additional code was
required to do stuff like locking misaligned windows of 1- and 4-bit
images. Just recently, I augmented that original patch with a patch for the
rotation code (which was previously broken in another way too -- it didn't
refresh the Cairo surface object, so anything that wasn't simply accessing
the bits directly would cause a crash). Bitmap.RotateFlip now fully
supports 1-, 4- and 8-bit images as well as the previously-supported
32-bit. In fact, it works better than Microsoft's implementation, which has
an annoying bug for 5 RotateFlipType values with 1-bit images :-) (This
snags up the test suite when running on Windows, since the original
Microsoft GdiPlus.dll is used instead of libgdiplus, and thus RotateFlip
produces incorrect images for those combinations! I sent an e-mail to Jordi
about this a couple of weeks ago, but he still hasn't replied...)
The pivotal point of my support for 1-, 4- and 8-bit indexed images, apart
from alignment issues with LockBits, was, in order to make them usable with
Cairo's drawing functions (such as what Graphics.DrawImage uses ;-), to
produce translations of 1-, 4- and 8-bit Bitmaps to CAIRO_FORMAT_ARGB32 in
temporary buffers released after the call completed. If you're planning on
completing this area, this would probably be the road to go for 15-, 16-bit
bitmaps as well. You would simply need to do another check like I have done
in functions such as GdipDrawImageRectRect, where if the image is not
already in format CAIRO_FORMAT_ARGB32, a function is called to translate
the image to that format. Glancing at the Cairo source code, it appears
that it can natively handle PixelFormat.Format24bppRgb (as
CAIRO_FORMAT_RGB24), but you will need to do the conversions for 15- and
16-bit bitmaps.
Hope this helps :-)
Jonathan Gilbert
More information about the Mono-winforms-list
mailing list