summaryrefslogtreecommitdiff
path: root/plugins/AdvaImg/src/FreeImage/PluginBMP.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/AdvaImg/src/FreeImage/PluginBMP.cpp')
-rw-r--r--plugins/AdvaImg/src/FreeImage/PluginBMP.cpp118
1 files changed, 66 insertions, 52 deletions
diff --git a/plugins/AdvaImg/src/FreeImage/PluginBMP.cpp b/plugins/AdvaImg/src/FreeImage/PluginBMP.cpp
index 4041d859fa..0ee1c5db30 100644
--- a/plugins/AdvaImg/src/FreeImage/PluginBMP.cpp
+++ b/plugins/AdvaImg/src/FreeImage/PluginBMP.cpp
@@ -35,10 +35,13 @@ static const BYTE RLE_ENDOFLINE = 0;
static const BYTE RLE_ENDOFBITMAP = 1;
static const BYTE RLE_DELTA = 2;
-static const BYTE BI_RGB = 0;
-static const BYTE BI_RLE8 = 1;
-static const BYTE BI_RLE4 = 2;
-static const BYTE BI_BITFIELDS = 3;
+static const BYTE BI_RGB = 0; // compression: none
+static const BYTE BI_RLE8 = 1; // compression: RLE 8-bit/pixel
+static const BYTE BI_RLE4 = 2; // compression: RLE 4-bit/pixel
+static const BYTE BI_BITFIELDS = 3; // compression: Bit field or Huffman 1D compression for BITMAPCOREHEADER2
+static const BYTE BI_JPEG = 4; // compression: JPEG or RLE-24 compression for BITMAPCOREHEADER2
+static const BYTE BI_PNG = 5; // compression: PNG
+static const BYTE BI_ALPHABITFIELDS = 6; // compression: Bit field (this value is valid in Windows CE .NET 4.0 and later)
// ----------------------------------------------------------
@@ -65,11 +68,11 @@ typedef struct tagBITMAPINFOOS2_1X_HEADER {
} BITMAPINFOOS2_1X_HEADER, *PBITMAPINFOOS2_1X_HEADER;
typedef struct tagBITMAPFILEHEADER {
- WORD bfType;
- DWORD bfSize;
- WORD bfReserved1;
- WORD bfReserved2;
- DWORD bfOffBits;
+ WORD bfType; //! The file type
+ DWORD bfSize; //! The size, in bytes, of the bitmap file
+ WORD bfReserved1; //! Reserved; must be zero
+ WORD bfReserved2; //! Reserved; must be zero
+ DWORD bfOffBits; //! The offset, in bytes, from the beginning of the BITMAPFILEHEADER structure to the bitmap bits
} BITMAPFILEHEADER, *PBITMAPFILEHEADER;
#ifdef _WIN32
@@ -452,7 +455,7 @@ LoadPixelDataRLE8(FreeImageIO *io, fi_handle handle, int width, int height, FIBI
// --------------------------------------------------------------------------
static FIBITMAP *
-LoadWindowsBMP(FreeImageIO *io, fi_handle handle, int flags, unsigned bitmap_bits_offset) {
+LoadWindowsBMP(FreeImageIO *io, fi_handle handle, int flags, unsigned bitmap_bits_offset, int type) {
FIBITMAP *dib = NULL;
try {
@@ -481,8 +484,9 @@ LoadWindowsBMP(FreeImageIO *io, fi_handle handle, int flags, unsigned bitmap_bit
case 4 :
case 8 :
{
- if ((used_colors == 0) || (used_colors > CalculateUsedPaletteEntries(bit_count)))
+ if ((used_colors == 0) || (used_colors > CalculateUsedPaletteEntries(bit_count))) {
used_colors = CalculateUsedPaletteEntries(bit_count);
+ }
// allocate enough memory to hold the bitmap (header, palette, pixels) and read the palette
@@ -494,6 +498,19 @@ LoadWindowsBMP(FreeImageIO *io, fi_handle handle, int flags, unsigned bitmap_bit
// set resolution information
FreeImage_SetDotsPerMeterX(dib, bih.biXPelsPerMeter);
FreeImage_SetDotsPerMeterY(dib, bih.biYPelsPerMeter);
+
+ // seek to the end of the header (depending on the BMP header version)
+ // type == sizeof(BITMAPVxINFOHEADER)
+ switch(type) {
+ case 40: // sizeof(BITMAPINFOHEADER) - all Windows versions since Windows 3.0
+ break;
+ case 52: // sizeof(BITMAPV2INFOHEADER) (undocumented)
+ case 56: // sizeof(BITMAPV3INFOHEADER) (undocumented)
+ case 108: // sizeof(BITMAPV4HEADER) - all Windows versions since Windows 95/NT4 (not supported)
+ case 124: // sizeof(BITMAPV5HEADER) - Windows 98/2000 and newer (not supported)
+ io->seek_proc(handle, (long)(type - sizeof(BITMAPINFOHEADER)), SEEK_CUR);
+ break;
+ }
// load the palette
@@ -512,10 +529,8 @@ LoadWindowsBMP(FreeImageIO *io, fi_handle handle, int flags, unsigned bitmap_bit
// seek to the actual pixel data.
// this is needed because sometimes the palette is larger than the entries it contains predicts
+ io->seek_proc(handle, bitmap_bits_offset, SEEK_SET);
- if (bitmap_bits_offset > (sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + (used_colors * sizeof(RGBQUAD))))
- io->seek_proc(handle, bitmap_bits_offset, SEEK_SET);
-
// read the pixel data
switch (compression) {
@@ -551,11 +566,15 @@ LoadWindowsBMP(FreeImageIO *io, fi_handle handle, int flags, unsigned bitmap_bit
case 16 :
{
- if (bih.biCompression == BI_BITFIELDS) {
- DWORD bitfields[3];
-
- io->read_proc(bitfields, 3 * sizeof(DWORD), 1, handle);
-
+ int use_bitfields = 0;
+ if (bih.biCompression == BI_BITFIELDS) use_bitfields = 3;
+ else if (bih.biCompression == BI_ALPHABITFIELDS) use_bitfields = 4;
+ else if (type == 52) use_bitfields = 3;
+ else if (type >= 56) use_bitfields = 4;
+
+ if (use_bitfields > 0) {
+ DWORD bitfields[4];
+ io->read_proc(bitfields, use_bitfields * sizeof(DWORD), 1, handle);
dib = FreeImage_AllocateHeader(header_only, width, height, bit_count, bitfields[0], bitfields[1], bitfields[2]);
} else {
dib = FreeImage_AllocateHeader(header_only, width, height, bit_count, FI16_555_RED_MASK, FI16_555_GREEN_MASK, FI16_555_BLUE_MASK);
@@ -573,14 +592,11 @@ LoadWindowsBMP(FreeImageIO *io, fi_handle handle, int flags, unsigned bitmap_bit
// header only mode
return dib;
}
+
+ // seek to the actual pixel data
+ io->seek_proc(handle, bitmap_bits_offset, SEEK_SET);
// load pixel data and swap as needed if OS is Big Endian
-
- if (bitmap_bits_offset > (sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER))) {
- // seek to the actual pixel data
- io->seek_proc(handle, bitmap_bits_offset, SEEK_SET);
- }
-
LoadPixelData(io, handle, dib, height, pitch, bit_count);
return dib;
@@ -590,11 +606,15 @@ LoadWindowsBMP(FreeImageIO *io, fi_handle handle, int flags, unsigned bitmap_bit
case 24 :
case 32 :
{
- if (bih.biCompression == BI_BITFIELDS) {
- DWORD bitfields[3];
-
- io->read_proc(bitfields, 3 * sizeof(DWORD), 1, handle);
-
+ int use_bitfields = 0;
+ if (bih.biCompression == BI_BITFIELDS) use_bitfields = 3;
+ else if (bih.biCompression == BI_ALPHABITFIELDS) use_bitfields = 4;
+ else if (type == 52) use_bitfields = 3;
+ else if (type >= 56) use_bitfields = 4;
+
+ if (use_bitfields > 0) {
+ DWORD bitfields[4];
+ io->read_proc(bitfields, use_bitfields * sizeof(DWORD), 1, handle);
dib = FreeImage_AllocateHeader(header_only, width, height, bit_count, bitfields[0], bitfields[1], bitfields[2]);
} else {
if( bit_count == 32 ) {
@@ -619,12 +639,10 @@ LoadWindowsBMP(FreeImageIO *io, fi_handle handle, int flags, unsigned bitmap_bit
// Skip over the optional palette
// A 24 or 32 bit DIB may contain a palette for faster color reduction
+ // i.e. you can have (FreeImage_GetColorsUsed(dib) > 0)
- if (FreeImage_GetColorsUsed(dib) > 0) {
- io->seek_proc(handle, FreeImage_GetColorsUsed(dib) * sizeof(RGBQUAD), SEEK_CUR);
- } else if ((bih.biCompression != BI_BITFIELDS) && (bitmap_bits_offset > sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER))) {
- io->seek_proc(handle, bitmap_bits_offset, SEEK_SET);
- }
+ // seek to the actual pixel data
+ io->seek_proc(handle, bitmap_bits_offset, SEEK_SET);
// read in the bitmap bits
// load pixel data and swap as needed if OS is Big Endian
@@ -735,8 +753,9 @@ LoadOS22XBMP(FreeImageIO *io, fi_handle handle, int flags, unsigned bitmap_bits_
// seek to the actual pixel data.
// this is needed because sometimes the palette is larger than the entries it contains predicts
- if (bitmap_bits_offset > (sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + (used_colors * 3)))
+ if (bitmap_bits_offset > (sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + (used_colors * 3))) {
io->seek_proc(handle, bitmap_bits_offset, SEEK_SET);
+ }
// read the pixel data
@@ -827,8 +846,9 @@ LoadOS22XBMP(FreeImageIO *io, fi_handle handle, int flags, unsigned bitmap_bits_
// Skip over the optional palette
// A 24 or 32 bit DIB may contain a palette for faster color reduction
- if (bitmap_bits_offset > (sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + (used_colors * 3)))
+ if (bitmap_bits_offset > (sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + (used_colors * 3))) {
io->seek_proc(handle, bitmap_bits_offset, SEEK_SET);
+ }
// read in the bitmap bits
// load pixel data and swap as needed if OS is Big Endian
@@ -1101,24 +1121,18 @@ Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
case 12:
// OS/2 and also all Windows versions since Windows 3.0
return LoadOS21XBMP(io, handle, flags, offset_in_file + bitmapfileheader.bfOffBits);
+
case 64:
// OS/2
return LoadOS22XBMP(io, handle, flags, offset_in_file + bitmapfileheader.bfOffBits);
- case 40:
- // BITMAPINFOHEADER - all Windows versions since Windows 3.0
- return LoadWindowsBMP(io, handle, flags, offset_in_file + bitmapfileheader.bfOffBits);
- case 52:
- // BITMAPV2INFOHEADER (undocumented)
- break;
- case 56:
- // BITMAPV3INFOHEADER (undocumented)
- break;
- case 108:
- // BITMAPV4HEADER - all Windows versions since Windows 95/NT4 (not supported)
- break;
- case 124:
- // BITMAPV5HEADER - Windows 98/2000 and newer (not supported)
- break;
+
+ case 40: // BITMAPINFOHEADER - all Windows versions since Windows 3.0
+ case 52: // BITMAPV2INFOHEADER (undocumented, partially supported)
+ case 56: // BITMAPV3INFOHEADER (undocumented, partially supported)
+ case 108: // BITMAPV4HEADER - all Windows versions since Windows 95/NT4 (partially supported)
+ case 124: // BITMAPV5HEADER - Windows 98/2000 and newer (partially supported)
+ return LoadWindowsBMP(io, handle, flags, offset_in_file + bitmapfileheader.bfOffBits, type);
+
default:
break;
}