diff options
Diffstat (limited to 'plugins/AdvaImg/src/FreeImage/PluginBMP.cpp')
-rw-r--r-- | plugins/AdvaImg/src/FreeImage/PluginBMP.cpp | 118 |
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; } |