[Bf-blender-cvs] [ddb4870] staging-D1173-bmp_low_bitdepth: Fix loading of indexed .bmp files

Campbell Barton noreply at git.blender.org
Wed Mar 11 11:33:05 CET 2015


Commit: ddb487030215800dc5ba9837dc7e806fb793d295
Author: Campbell Barton
Date:   Wed Mar 11 21:32:00 2015 +1100
Branches: staging-D1173-bmp_low_bitdepth
https://developer.blender.org/rBddb487030215800dc5ba9837dc7e806fb793d295

Fix loading of indexed .bmp files

D1173 by @rdb

Support for 1,2,4 bit images

===================================================================

M	source/blender/imbuf/intern/bmp.c

===================================================================

diff --git a/source/blender/imbuf/intern/bmp.c b/source/blender/imbuf/intern/bmp.c
index bc1ca47..bc5ad96 100644
--- a/source/blender/imbuf/intern/bmp.c
+++ b/source/blender/imbuf/intern/bmp.c
@@ -105,7 +105,7 @@ static int checkbmp(unsigned char *mem)
 		if (u >= sizeof(BMPINFOHEADER)) {
 			if (bmi.biCompression == 0) {
 				u = LITTLE_SHORT(bmi.biBitCount);
-				if (u >= 8) {
+				if (u > 0 && u <= 32) {
 					ret_val = 1;
 				}
 			}
@@ -136,10 +136,15 @@ struct ImBuf *imb_bmp_decode(unsigned char *mem, size_t size, int flags, char co
 
 	colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE);
 
+	bmp = mem + LITTLE_LONG(*(int*)(mem + 10));
+
 	if (CHECK_HEADER_FIELD_BMP(mem)) {
 		/* skip fileheader */
 		mem += BMP_FILEHEADER_SIZE;
 	}
+	else {
+		return 0;
+	}
 
 	/* for systems where an int needs to be 4 bytes aligned */
 	memcpy(&bmi, mem, sizeof(bmi));
@@ -173,29 +178,43 @@ struct ImBuf *imb_bmp_decode(unsigned char *mem, size_t size, int flags, char co
 	}
 	else {
 		ibuf = IMB_allocImBuf(x, y, ibuf_depth, IB_rect);
-		bmp = mem + skip;
 		rect = (unsigned char *) ibuf->rect;
 
-		if (depth == 8) {
-			const int x_pad = (4 - (x % 4)) % 4;
-			const char (*palette)[4] = (void *)bmp;
-			bmp += bmi.biClrUsed * 4;
+		if (depth <= 8) {
+			const int rowsize = (depth * x + 31) / 32 * 4;
+			const char (*palette)[4] = (void *)(mem + skip);
+			const int startmask = ((1 << depth) - 1) << 8;
 			for (i = y; i > 0; i--) {
+				int index;
+				int bitoffs = 8;
+				int bitmask = startmask;
+				int nbytes = 0;
+				const char *pcol;
 				if (top_to_bottom) {
 					rect = (unsigned char *) &ibuf->rect[(i - 1) * x];
 				}
 				for (j = x; j > 0; j--) {
-					const char *pcol = palette[bmp[0]];
+					bitoffs -= depth;
+					bitmask >>= depth;
+					index = (bmp[0] & bitmask) >> bitoffs;
+					pcol = palette[index];
 					/* intentionally BGR -> RGB */
 					rect[0] = pcol[2];
 					rect[1] = pcol[1];
 					rect[2] = pcol[0];
 
 					rect[3] = 255;
-					rect += 4; bmp += 1;
+					rect += 4;
+					if (bitoffs == 0) {
+						/* Advance to the next byte */
+						bitoffs = 8;
+						bitmask = startmask;
+						nbytes += 1;
+						bmp += 1;
+					}
 				}
-				/* rows are padded to multiples of 4 */
-				bmp += x_pad;
+				/* Advance to the next row */
+				bmp += (rowsize - nbytes);
 			}
 		}
 		else if (depth == 16) {




More information about the Bf-blender-cvs mailing list