446 lines
11 KiB
Diff
446 lines
11 KiB
Diff
|
|
Origin: upstream, r1832
|
||
|
|
Index: Source/FreeImage/PluginBMP.cpp
|
||
|
|
---
|
||
|
|
diff --git a/Source/FreeImage/PluginBMP.cpp b/Source/FreeImage/PluginBMP.cpp
|
||
|
|
--- a/Source/FreeImage/PluginBMP.cpp (revision 1831)
|
||
|
|
+++ b/Source/FreeImage/PluginBMP.cpp (revision 1832)
|
||
|
|
@@ -181,6 +181,7 @@
|
||
|
|
}
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
+
|
||
|
|
#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_RGB
|
||
|
|
if (bit_count == 24 || bit_count == 32) {
|
||
|
|
for(unsigned y = 0; y < FreeImage_GetHeight(dib); y++) {
|
||
|
|
@@ -202,7 +203,7 @@
|
||
|
|
@param handle FreeImage IO handle
|
||
|
|
@param width Image width
|
||
|
|
@param height Image height
|
||
|
|
-@param dib Image to be loaded
|
||
|
|
+@param dib 4-bit image to be loaded
|
||
|
|
@return Returns TRUE if successful, returns FALSE otherwise
|
||
|
|
*/
|
||
|
|
static BOOL
|
||
|
|
@@ -217,7 +218,9 @@
|
||
|
|
height = abs(height);
|
||
|
|
|
||
|
|
pixels = (BYTE*)malloc(width * height * sizeof(BYTE));
|
||
|
|
- if(!pixels) throw(1);
|
||
|
|
+ if (!pixels) {
|
||
|
|
+ throw(1);
|
||
|
|
+ }
|
||
|
|
memset(pixels, 0, width * height * sizeof(BYTE));
|
||
|
|
|
||
|
|
BYTE *q = pixels;
|
||
|
|
@@ -237,7 +240,7 @@
|
||
|
|
throw(1);
|
||
|
|
}
|
||
|
|
for (int i = 0; i < status_byte; i++) {
|
||
|
|
- *q++=(BYTE)((i & 0x01) ? (second_byte & 0x0f) : ((second_byte >> 4) & 0x0f));
|
||
|
|
+ *q++ = (BYTE)((i & 0x01) ? (second_byte & 0x0f) : ((second_byte >> 4) & 0x0f));
|
||
|
|
}
|
||
|
|
bits += status_byte;
|
||
|
|
}
|
||
|
|
@@ -252,7 +255,7 @@
|
||
|
|
// End of line
|
||
|
|
bits = 0;
|
||
|
|
scanline++;
|
||
|
|
- q = pixels + scanline*width;
|
||
|
|
+ q = pixels + scanline * width;
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
|
||
|
|
@@ -264,7 +267,6 @@
|
||
|
|
case RLE_DELTA:
|
||
|
|
{
|
||
|
|
// read the delta values
|
||
|
|
-
|
||
|
|
BYTE delta_x = 0;
|
||
|
|
BYTE delta_y = 0;
|
||
|
|
|
||
|
|
@@ -276,7 +278,6 @@
|
||
|
|
}
|
||
|
|
|
||
|
|
// apply them
|
||
|
|
-
|
||
|
|
bits += delta_x;
|
||
|
|
scanline += delta_y;
|
||
|
|
q = pixels + scanline*width+bits;
|
||
|
|
@@ -293,7 +294,7 @@
|
||
|
|
throw(1);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
- *q++=(BYTE)((i & 0x01) ? (second_byte & 0x0f) : ((second_byte >> 4) & 0x0f));
|
||
|
|
+ *q++ = (BYTE)((i & 0x01) ? (second_byte & 0x0f) : ((second_byte >> 4) & 0x0f));
|
||
|
|
}
|
||
|
|
bits += status_byte;
|
||
|
|
// Read pad byte
|
||
|
|
@@ -334,7 +335,9 @@
|
||
|
|
return TRUE;
|
||
|
|
|
||
|
|
} catch(int) {
|
||
|
|
- if(pixels) free(pixels);
|
||
|
|
+ if (pixels) {
|
||
|
|
+ free(pixels);
|
||
|
|
+ }
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
@@ -345,7 +348,7 @@
|
||
|
|
@param handle FreeImage IO handle
|
||
|
|
@param width Image width
|
||
|
|
@param height Image height
|
||
|
|
-@param dib Image to be loaded
|
||
|
|
+@param dib 8-bit image to be loaded
|
||
|
|
@return Returns TRUE if successful, returns FALSE otherwise
|
||
|
|
*/
|
||
|
|
static BOOL
|
||
|
|
@@ -354,103 +357,85 @@
|
||
|
|
BYTE second_byte = 0;
|
||
|
|
int scanline = 0;
|
||
|
|
int bits = 0;
|
||
|
|
+ int count = 0;
|
||
|
|
+ BYTE delta_x = 0;
|
||
|
|
+ BYTE delta_y = 0;
|
||
|
|
|
||
|
|
- for (;;) {
|
||
|
|
- if( io->read_proc(&status_byte, sizeof(BYTE), 1, handle) != 1) {
|
||
|
|
+ height = abs(height);
|
||
|
|
+
|
||
|
|
+ while(scanline < height) {
|
||
|
|
+
|
||
|
|
+ if (io->read_proc(&status_byte, sizeof(BYTE), 1, handle) != 1) {
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
- switch (status_byte) {
|
||
|
|
- case RLE_COMMAND :
|
||
|
|
- if(io->read_proc(&status_byte, sizeof(BYTE), 1, handle) != 1) {
|
||
|
|
- return FALSE;
|
||
|
|
- }
|
||
|
|
+ if (status_byte == RLE_COMMAND) {
|
||
|
|
+ if (io->read_proc(&status_byte, sizeof(BYTE), 1, handle) != 1) {
|
||
|
|
+ return FALSE;
|
||
|
|
+ }
|
||
|
|
|
||
|
|
- switch (status_byte) {
|
||
|
|
- case RLE_ENDOFLINE :
|
||
|
|
- bits = 0;
|
||
|
|
- scanline++;
|
||
|
|
- break;
|
||
|
|
+ switch (status_byte) {
|
||
|
|
+ case RLE_ENDOFLINE:
|
||
|
|
+ bits = 0;
|
||
|
|
+ scanline++;
|
||
|
|
+ break;
|
||
|
|
|
||
|
|
- case RLE_ENDOFBITMAP :
|
||
|
|
- return TRUE;
|
||
|
|
+ case RLE_ENDOFBITMAP:
|
||
|
|
+ return TRUE;
|
||
|
|
|
||
|
|
- case RLE_DELTA :
|
||
|
|
- {
|
||
|
|
- // read the delta values
|
||
|
|
+ case RLE_DELTA:
|
||
|
|
+ // read the delta values
|
||
|
|
+ delta_x = 0;
|
||
|
|
+ delta_y = 0;
|
||
|
|
+ if (io->read_proc(&delta_x, sizeof(BYTE), 1, handle) != 1) {
|
||
|
|
+ return FALSE;
|
||
|
|
+ }
|
||
|
|
+ if (io->read_proc(&delta_y, sizeof(BYTE), 1, handle) != 1) {
|
||
|
|
+ return FALSE;
|
||
|
|
+ }
|
||
|
|
+ // apply them
|
||
|
|
+ bits += delta_x;
|
||
|
|
+ scanline += delta_y;
|
||
|
|
+ break;
|
||
|
|
|
||
|
|
- BYTE delta_x = 0;
|
||
|
|
- BYTE delta_y = 0;
|
||
|
|
-
|
||
|
|
- if(io->read_proc(&delta_x, sizeof(BYTE), 1, handle) != 1) {
|
||
|
|
- return FALSE;
|
||
|
|
- }
|
||
|
|
- if(io->read_proc(&delta_y, sizeof(BYTE), 1, handle) != 1) {
|
||
|
|
- return FALSE;
|
||
|
|
- }
|
||
|
|
-
|
||
|
|
- // apply them
|
||
|
|
-
|
||
|
|
- bits += delta_x;
|
||
|
|
- scanline += delta_y;
|
||
|
|
-
|
||
|
|
- break;
|
||
|
|
+ default:
|
||
|
|
+ // absolute mode
|
||
|
|
+ count = MIN((int)status_byte, width - bits);
|
||
|
|
+ if (count < 0) {
|
||
|
|
+ return FALSE;
|
||
|
|
}
|
||
|
|
-
|
||
|
|
- default :
|
||
|
|
- {
|
||
|
|
- if(scanline >= abs(height)) {
|
||
|
|
- return TRUE;
|
||
|
|
- }
|
||
|
|
-
|
||
|
|
- int count = MIN((int)status_byte, width - bits);
|
||
|
|
-
|
||
|
|
- BYTE *sline = FreeImage_GetScanLine(dib, scanline);
|
||
|
|
-
|
||
|
|
- if(io->read_proc((void *)(sline + bits), sizeof(BYTE) * count, 1, handle) != 1) {
|
||
|
|
+ BYTE *sline = FreeImage_GetScanLine(dib, scanline);
|
||
|
|
+ if (io->read_proc((void *)(sline + bits), sizeof(BYTE) * count, 1, handle) != 1) {
|
||
|
|
+ return FALSE;
|
||
|
|
+ }
|
||
|
|
+ // align run length to even number of bytes
|
||
|
|
+ if ((status_byte & 1) == 1) {
|
||
|
|
+ if (io->read_proc(&second_byte, sizeof(BYTE), 1, handle) != 1) {
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
-
|
||
|
|
- // align run length to even number of bytes
|
||
|
|
-
|
||
|
|
- if ((status_byte & 1) == 1) {
|
||
|
|
- if(io->read_proc(&second_byte, sizeof(BYTE), 1, handle) != 1) {
|
||
|
|
- return FALSE;
|
||
|
|
- }
|
||
|
|
- }
|
||
|
|
-
|
||
|
|
- bits += status_byte;
|
||
|
|
-
|
||
|
|
- break;
|
||
|
|
}
|
||
|
|
- }
|
||
|
|
+ bits += status_byte;
|
||
|
|
+ break;
|
||
|
|
|
||
|
|
- break;
|
||
|
|
-
|
||
|
|
- default :
|
||
|
|
- {
|
||
|
|
- if(scanline >= abs(height)) {
|
||
|
|
- return TRUE;
|
||
|
|
- }
|
||
|
|
-
|
||
|
|
- int count = MIN((int)status_byte, width - bits);
|
||
|
|
-
|
||
|
|
- BYTE *sline = FreeImage_GetScanLine(dib, scanline);
|
||
|
|
-
|
||
|
|
- if(io->read_proc(&second_byte, sizeof(BYTE), 1, handle) != 1) {
|
||
|
|
- return FALSE;
|
||
|
|
- }
|
||
|
|
-
|
||
|
|
- for (int i = 0; i < count; i++) {
|
||
|
|
- *(sline + bits) = second_byte;
|
||
|
|
-
|
||
|
|
- bits++;
|
||
|
|
- }
|
||
|
|
-
|
||
|
|
- break;
|
||
|
|
+ } // switch (status_byte)
|
||
|
|
+ }
|
||
|
|
+ else {
|
||
|
|
+ count = MIN((int)status_byte, width - bits);
|
||
|
|
+ if (count < 0) {
|
||
|
|
+ return FALSE;
|
||
|
|
}
|
||
|
|
+ BYTE *sline = FreeImage_GetScanLine(dib, scanline);
|
||
|
|
+ if (io->read_proc(&second_byte, sizeof(BYTE), 1, handle) != 1) {
|
||
|
|
+ return FALSE;
|
||
|
|
+ }
|
||
|
|
+ for (int i = 0; i < count; i++) {
|
||
|
|
+ *(sline + bits) = second_byte;
|
||
|
|
+ bits++;
|
||
|
|
+ }
|
||
|
|
}
|
||
|
|
}
|
||
|
|
+
|
||
|
|
+ return FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
// --------------------------------------------------------------------------
|
||
|
|
@@ -463,10 +448,12 @@
|
||
|
|
BOOL header_only = (flags & FIF_LOAD_NOPIXELS) == FIF_LOAD_NOPIXELS;
|
||
|
|
|
||
|
|
// load the info header
|
||
|
|
-
|
||
|
|
BITMAPINFOHEADER bih;
|
||
|
|
+ memset(&bih, 0, sizeof(BITMAPINFOHEADER));
|
||
|
|
+ if (io->read_proc(&bih, sizeof(BITMAPINFOHEADER), 1, handle) != 1) {
|
||
|
|
+ throw FI_MSG_ERROR_INVALID_FORMAT;
|
||
|
|
+ }
|
||
|
|
|
||
|
|
- io->read_proc(&bih, sizeof(BITMAPINFOHEADER), 1, handle);
|
||
|
|
#ifdef FREEIMAGE_BIGENDIAN
|
||
|
|
SwapInfoHeader(&bih);
|
||
|
|
#endif
|
||
|
|
@@ -544,7 +531,7 @@
|
||
|
|
break;
|
||
|
|
|
||
|
|
case BI_RLE4 :
|
||
|
|
- if( LoadPixelDataRLE4(io, handle, width, height, dib) ) {
|
||
|
|
+ if( (bit_count == 4) && LoadPixelDataRLE4(io, handle, width, height, dib) ) {
|
||
|
|
return dib;
|
||
|
|
} else {
|
||
|
|
throw "Error encountered while decoding RLE4 BMP data";
|
||
|
|
@@ -552,7 +539,7 @@
|
||
|
|
break;
|
||
|
|
|
||
|
|
case BI_RLE8 :
|
||
|
|
- if( LoadPixelDataRLE8(io, handle, width, height, dib) ) {
|
||
|
|
+ if( (bit_count == 8) && LoadPixelDataRLE8(io, handle, width, height, dib) ) {
|
||
|
|
return dib;
|
||
|
|
} else {
|
||
|
|
throw "Error encountered while decoding RLE8 BMP data";
|
||
|
|
@@ -602,7 +589,7 @@
|
||
|
|
|
||
|
|
return dib;
|
||
|
|
}
|
||
|
|
- break; // 16-bit
|
||
|
|
+ break; // 16-bit RGB
|
||
|
|
|
||
|
|
case 24 :
|
||
|
|
case 32 :
|
||
|
|
@@ -679,10 +666,12 @@
|
||
|
|
BOOL header_only = (flags & FIF_LOAD_NOPIXELS) == FIF_LOAD_NOPIXELS;
|
||
|
|
|
||
|
|
// load the info header
|
||
|
|
-
|
||
|
|
BITMAPINFOHEADER bih;
|
||
|
|
+ memset(&bih, 0, sizeof(BITMAPINFOHEADER));
|
||
|
|
+ if (io->read_proc(&bih, sizeof(BITMAPINFOHEADER), 1, handle) != 1) {
|
||
|
|
+ throw FI_MSG_ERROR_INVALID_FORMAT;
|
||
|
|
+ }
|
||
|
|
|
||
|
|
- io->read_proc(&bih, sizeof(BITMAPINFOHEADER), 1, handle);
|
||
|
|
#ifdef FREEIMAGE_BIGENDIAN
|
||
|
|
SwapInfoHeader(&bih);
|
||
|
|
#endif
|
||
|
|
@@ -767,17 +756,19 @@
|
||
|
|
return dib;
|
||
|
|
|
||
|
|
case BI_RLE4 :
|
||
|
|
- if( LoadPixelDataRLE4(io, handle, width, height, dib) ) {
|
||
|
|
+ if ((bit_count == 4) && LoadPixelDataRLE4(io, handle, width, height, dib)) {
|
||
|
|
return dib;
|
||
|
|
- } else {
|
||
|
|
+ }
|
||
|
|
+ else {
|
||
|
|
throw "Error encountered while decoding RLE4 BMP data";
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
|
||
|
|
case BI_RLE8 :
|
||
|
|
- if( LoadPixelDataRLE8(io, handle, width, height, dib) ) {
|
||
|
|
+ if ((bit_count == 8) && LoadPixelDataRLE8(io, handle, width, height, dib)) {
|
||
|
|
return dib;
|
||
|
|
- } else {
|
||
|
|
+ }
|
||
|
|
+ else {
|
||
|
|
throw "Error encountered while decoding RLE8 BMP data";
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
@@ -863,9 +854,9 @@
|
||
|
|
}
|
||
|
|
}
|
||
|
|
} catch(const char *message) {
|
||
|
|
- if(dib)
|
||
|
|
+ if (dib) {
|
||
|
|
FreeImage_Unload(dib);
|
||
|
|
-
|
||
|
|
+ }
|
||
|
|
FreeImage_OutputMessageProc(s_format_id, message);
|
||
|
|
}
|
||
|
|
|
||
|
|
@@ -881,9 +872,13 @@
|
||
|
|
try {
|
||
|
|
BOOL header_only = (flags & FIF_LOAD_NOPIXELS) == FIF_LOAD_NOPIXELS;
|
||
|
|
|
||
|
|
+ // load the info header
|
||
|
|
BITMAPINFOOS2_1X_HEADER bios2_1x;
|
||
|
|
+ memset(&bios2_1x, 0, sizeof(BITMAPINFOOS2_1X_HEADER));
|
||
|
|
+ if (io->read_proc(&bios2_1x, sizeof(BITMAPINFOOS2_1X_HEADER), 1, handle) != 1) {
|
||
|
|
+ throw FI_MSG_ERROR_INVALID_FORMAT;
|
||
|
|
+ }
|
||
|
|
|
||
|
|
- io->read_proc(&bios2_1x, sizeof(BITMAPINFOOS2_1X_HEADER), 1, handle);
|
||
|
|
#ifdef FREEIMAGE_BIGENDIAN
|
||
|
|
SwapOS21XHeader(&bios2_1x);
|
||
|
|
#endif
|
||
|
|
@@ -1005,9 +1000,9 @@
|
||
|
|
}
|
||
|
|
}
|
||
|
|
} catch(const char *message) {
|
||
|
|
- if(dib)
|
||
|
|
+ if (dib) {
|
||
|
|
FreeImage_Unload(dib);
|
||
|
|
-
|
||
|
|
+ }
|
||
|
|
FreeImage_OutputMessageProc(s_format_id, message);
|
||
|
|
}
|
||
|
|
|
||
|
|
@@ -1090,19 +1085,20 @@
|
||
|
|
BITMAPFILEHEADER bitmapfileheader;
|
||
|
|
DWORD type = 0;
|
||
|
|
|
||
|
|
- // we use this offset value to make seemingly absolute seeks relative in the file
|
||
|
|
-
|
||
|
|
+ // we use this offset value to make seemingly absolute seeks relative in the file
|
||
|
|
long offset_in_file = io->tell_proc(handle);
|
||
|
|
|
||
|
|
// read the fileheader
|
||
|
|
+ memset(&bitmapfileheader, 0, sizeof(BITMAPFILEHEADER));
|
||
|
|
+ if (io->read_proc(&bitmapfileheader, sizeof(BITMAPFILEHEADER), 1, handle) != 1) {
|
||
|
|
+ return NULL;
|
||
|
|
+ }
|
||
|
|
|
||
|
|
- io->read_proc(&bitmapfileheader, sizeof(BITMAPFILEHEADER), 1, handle);
|
||
|
|
#ifdef FREEIMAGE_BIGENDIAN
|
||
|
|
SwapFileHeader(&bitmapfileheader);
|
||
|
|
#endif
|
||
|
|
|
||
|
|
// check the signature
|
||
|
|
-
|
||
|
|
if((bitmapfileheader.bfType != 0x4D42) && (bitmapfileheader.bfType != 0x4142)) {
|
||
|
|
FreeImage_OutputMessageProc(s_format_id, FI_MSG_ERROR_MAGIC_NUMBER);
|
||
|
|
return NULL;
|
||
|
|
@@ -1109,9 +1105,9 @@
|
||
|
|
}
|
||
|
|
|
||
|
|
// read the first byte of the infoheader
|
||
|
|
-
|
||
|
|
io->read_proc(&type, sizeof(DWORD), 1, handle);
|
||
|
|
io->seek_proc(handle, 0 - (long)sizeof(DWORD), SEEK_CUR);
|
||
|
|
+
|
||
|
|
#ifdef FREEIMAGE_BIGENDIAN
|
||
|
|
SwapLong(&type);
|
||
|
|
#endif
|
||
|
|
@@ -1138,7 +1134,7 @@
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
- FreeImage_OutputMessageProc(s_format_id, "unknown bmp subtype with id %d", type);
|
||
|
|
+ FreeImage_OutputMessageProc(s_format_id, "Unknown bmp subtype with id %d", type);
|
||
|
|
}
|
||
|
|
|
||
|
|
return NULL;
|
||
|
|
@@ -1418,6 +1414,7 @@
|
||
|
|
}
|
||
|
|
|
||
|
|
free(buffer);
|
||
|
|
+
|
||
|
|
#ifdef FREEIMAGE_BIGENDIAN
|
||
|
|
} else if (dst_bpp == 16) {
|
||
|
|
int padding = dst_pitch - dst_width * sizeof(WORD);
|
||
|
|
@@ -1439,6 +1436,7 @@
|
||
|
|
}
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
+
|
||
|
|
#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_RGB
|
||
|
|
} else if (dst_bpp == 24) {
|
||
|
|
int padding = dst_pitch - dst_width * sizeof(FILE_BGR);
|