We've found that loader_bmp.c in imlib2 1.4.0 does not correctly handle
RGB565 Windows BMPs (compression method BI_BITFIELDS), nor does it
correctly shift the bits for RGB555 images into the MSBs of the 32 bit
output format.
The attached patch corrects loader_bmp.c's handling of 16 bit Windows
BMPs by doing the following:
* Introduce a left shift for each of the three colour components in
16-bit images
* Set this left shift to 3 for each colour component in RGB555 images
* For "bitfields" images (RGB565, for example), determine the value of
left shift by masking and shifting 0xFFFF until the byte value of the
component has the MSB set.
* When reading components, left shift them appropriately, to make the
byte values the MSBs of the output colour components.
We've also noticed that 16 bit BMP handling depends on a little-endian
processor; this is fine for us, so I've not fixed it, but if
endian-independence is a goal, the code underneath "THIS WAS OLD CODE"
needs re-evaluating (casting unsigned char * to unsigned short *, then
deferencing the pix pointer assumes that we're on a little-endian system).
I'm not subscribed to the list, so please CC me on any replies.
--
Thanks,
Simon Farnsworth
diff -urNp imlib2-1.4.0.orig/src/modules/loaders/loader_bmp.c imlib2-1.4.0/src/modules/loaders/loader_bmp.c
--- imlib2-1.4.0.orig/src/modules/loaders/loader_bmp.c 2007-04-09 23:40:40.000000000 +0100
+++ imlib2-1.4.0/src/modules/loaders/loader_bmp.c 2007-05-11 15:26:36.000000000 +0100
@@ -120,6 +120,7 @@ load(ImlibImage * im, ImlibProgressFunct
RGBQUAD rgbQuads[256];
unsigned long rmask = 0xff, gmask = 0xff, bmask = 0xff;
unsigned long rshift = 0, gshift = 0, bshift = 0;
+ unsigned long rleftshift = 0, gleftshift = 0, bleftshift = 0;
/*
* 21.3.2006:
@@ -221,16 +222,28 @@ load(ImlibImage * im, ImlibProgressFunct
{
int bit;
- ReadleLong(f, &bmask);
- ReadleLong(f, &gmask);
ReadleLong(f, &rmask);
+ ReadleLong(f, &gmask);
+ ReadleLong(f, &bmask);
for (bit = bitcount - 1; bit >= 0; bit--)
{
if (bmask & (1 << bit)) bshift = bit;
if (gmask & (1 << bit)) gshift = bit;
if (rmask & (1 << bit)) rshift = bit;
}
- }
+ while(((((0xffffL & bmask) >> bshift) << bleftshift) & 0x80) == 0)
+ {
+ bleftshift++;
+ }
+ while(((((0xffffL & gmask) >> gshift) << gleftshift) & 0x80) == 0)
+ {
+ gleftshift++;
+ }
+ while(((((0xffffL & rmask) >> rshift) << rleftshift) & 0x80) == 0)
+ {
+ rleftshift++;
+ }
+ }
else if (bitcount == 16)
{
rmask = 0x7C00;
@@ -239,6 +252,7 @@ load(ImlibImage * im, ImlibProgressFunct
rshift = 10;
gshift = 5;
bshift = 0;
+ rleftshift = gleftshift = bleftshift = 3;
}
else if (bitcount == 32)
{
@@ -656,13 +670,10 @@ load(ImlibImage * im, ImlibProgressFunct
* bshift;
* *ptr++ = 0xff000000 | (r << 16) | (g << 8) | b;
*/
- /* TODO: I don't know if [rgb]shift are calculated correctly, because we
- * 16 bit depth losses some values (bits).
- */
unsigned short pix = *(unsigned short *)buffer_ptr;
- *ptr++ = 0xff000000 | (((pix & rmask) >> rshift) << 16) |
- (((pix & gmask) >> gshift) << 8) |
- (((pix & bmask) >> bshift) ) ;
+ *ptr++ = 0xff000000 | ((((pix & rmask) >> rshift) << rleftshift) << 16) |
+ ((((pix & gmask) >> gshift) << gleftshift) << 8) |
+ ((((pix & bmask) >> bshift) << bleftshift) ) ;
buffer_ptr += 2;
}
ptr -= w * 2;
diff -urNp imlib2-1.4.0.orig/src/modules/loaders/loader_bmp.c imlib2-1.4.0/src/modules/loaders/loader_bmp.c
--- imlib2-1.4.0.orig/src/modules/loaders/loader_bmp.c 2007-04-09 23:40:40.000000000 +0100
+++ imlib2-1.4.0/src/modules/loaders/loader_bmp.c 2007-05-11 15:26:36.000000000 +0100
@@ -120,6 +120,7 @@ load(ImlibImage * im, ImlibProgressFunct
RGBQUAD rgbQuads[256];
unsigned long rmask = 0xff, gmask = 0xff, bmask = 0xff;
unsigned long rshift = 0, gshift = 0, bshift = 0;
+ unsigned long rleftshift = 0, gleftshift = 0, bleftshift = 0;
/*
* 21.3.2006:
@@ -221,16 +222,28 @@ load(ImlibImage * im, ImlibProgressFunct
{
int bit;
- ReadleLong(f, &bmask);
- ReadleLong(f, &gmask);
ReadleLong(f, &rmask);
+ ReadleLong(f, &gmask);
+ ReadleLong(f, &bmask);
for (bit = bitcount - 1; bit >= 0; bit--)
{
if (bmask & (1 << bit)) bshift = bit;
if (gmask & (1 << bit)) gshift = bit;
if (rmask & (1 << bit)) rshift = bit;
}
- }
+ while(((((0xffffL & bmask) >> bshift) << bleftshift) & 0x80) == 0)
+ {
+ bleftshift++;
+ }
+ while(((((0xffffL & gmask) >> gshift) << gleftshift) & 0x80) == 0)
+ {
+ gleftshift++;
+ }
+ while(((((0xffffL & rmask) >> rshift) << rleftshift) & 0x80) == 0)
+ {
+ rleftshift++;
+ }
+ }
else if (bitcount == 16)
{
rmask = 0x7C00;
@@ -239,6 +252,7 @@ load(ImlibImage * im, ImlibProgressFunct
rshift = 10;
gshift = 5;
bshift = 0;
+ rleftshift = gleftshift = bleftshift = 3;
}
else if (bitcount == 32)
{
@@ -656,13 +670,10 @@ load(ImlibImage * im, ImlibProgressFunct
* bshift;
* *ptr++ = 0xff000000 | (r << 16) | (g << 8) | b;
*/
- /* TODO: I don't know if [rgb]shift are calculated correctly, because we
- * 16 bit depth losses some values (bits).
- */
unsigned short pix = *(unsigned short *)buffer_ptr;
- *ptr++ = 0xff000000 | (((pix & rmask) >> rshift) << 16) |
- (((pix & gmask) >> gshift) << 8) |
- (((pix & bmask) >> bshift) ) ;
+ *ptr++ = 0xff000000 | ((((pix & rmask) >> rshift) << rleftshift) << 16) |
+ ((((pix & gmask) >> gshift) << gleftshift) << 8) |
+ ((((pix & bmask) >> bshift) << bleftshift) ) ;
buffer_ptr += 2;
}
ptr -= w * 2;
-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
enlightenment-devel mailing list
enlightenment-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel