From caec07be65b2e7197b539784c4fcd52ef4d4ba24 Mon Sep 17 00:00:00 2001 From: Thomas Martitz Date: Fri, 11 Nov 2011 22:03:29 +0000 Subject: [PATCH] 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 --- apps/recorder/bmp.c | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/apps/recorder/bmp.c b/apps/recorder/bmp.c index 75165528e7..43afcc5e98 100644 --- a/apps/recorder/bmp.c +++ b/apps/recorder/bmp.c @@ -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)) && \