Handle 32bit bitmaps with all-zero alpha channel as fully opaque.

This is what gimp does when opening such a file.
Tt saves the alpha channel with all-0xff, but other programs might use 0x00.
As a fully transparent image doesn't make sense this should be OK.

Also split the 32bit and 24bit case in the bmp reader, they're sufficiently different.

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30968 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Thomas Martitz 2011-11-11 22:03:29 +00:00
parent f1ee740f2b
commit caec07be65

View file

@ -191,8 +191,11 @@ struct bmp_args {
struct img_part part;
#endif
/* as read_part_line() goes through the rows it'll set this to true
* if it finds transparency. Initialize to false before calling */
bool alpha_detected;
* if it finds transparency. Initialize to 0 before calling */
int alpha_detected;
/* for checking transparency it checks the against the very first byte
* of the bitmap. Initalize to 0x80 before calling */
unsigned char first_alpha_byte;
};
static unsigned int read_part_line(struct bmp_args *ba)
@ -238,6 +241,15 @@ static unsigned int read_part_line(struct bmp_args *ba)
return 0;
}
/* detect if the image has useful alpha information.
* if all alpha bits are 0xff or 0x00 discard the information.
* if it has other bits, or is mixed with 0x00 and 0xff then interpret
* as alpha. assume no alpha until the opposite is proven. as mixed
* is alpha, compare to the first byte instead of 0xff and 0x00 separately
*/
if (depth == 32 && ba->first_alpha_byte == 0x80)
ba->first_alpha_byte = ibuf[3] ? 0xff : 0x0;
while (ibuf < ba->buf + (BM_MAX_WIDTH << 2))
{
switch (depth)
@ -283,13 +295,19 @@ static unsigned int read_part_line(struct bmp_args *ba)
buf++;
ibuf += 2;
break;
case 32:
case 24:
buf->blue = *ibuf++;
buf->green = *ibuf++;
buf->red = *ibuf++;
buf->alpha = (depth == 32) ? *ibuf++ : 0xff;
if (buf->alpha != 0xff) ba->alpha_detected = true;
buf->alpha = 0xff;
buf++;
break;
case 32:
buf->blue = *ibuf++;
buf->green = *ibuf++;
buf->red = *ibuf++;
buf->alpha = *ibuf++;
ba->alpha_detected |= (buf->alpha != ba->first_alpha_byte);
buf++;
break;
}
@ -732,7 +750,7 @@ int read_bmp_fd(int fd,
defined(HAVE_BMP_SCALING) || defined(PLUGIN)
.cur_row = 0, .cur_col = 0, .part = {0,0},
#endif
.alpha_detected = false,
.alpha_detected = false, .first_alpha_byte = 0x80,
};
#if (LCD_DEPTH > 1 || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1)) && \