Bug 1186112 - Get rid of the #define'd constants in BMPFileHeaders.h. r=tn

--HG--
extra : rebase_source : f9b19180e1a09adff4695a50eb65612f337392f3
This commit is contained in:
Seth Fowler 2015-07-22 15:49:49 -07:00
parent 2b0ef68d0c
commit 2697700b81
6 changed files with 190 additions and 169 deletions

View File

@ -5,9 +5,30 @@
#ifndef mozilla_image_BMPFileHeaders_h
#define mozilla_image_BMPFileHeaders_h
#include <stddef.h>
#include <stdint.h>
namespace mozilla {
namespace image {
// This is the real BIH size (as contained in the bihsize field of
// BMPFILEHEADER).
struct BIH_LENGTH {
enum {
OS2 = 12,
WIN_V3 = 40,
WIN_V5 = 124
};
};
struct BIH_INTERNAL_LENGTH {
enum {
OS2 = 8,
WIN_V3 = 36,
WIN_V5 = 120
};
};
struct BMPFILEHEADER {
char signature[2]; // String "BM"
uint32_t filesize;
@ -15,32 +36,22 @@ struct BMPFILEHEADER {
uint32_t dataoffset; // Offset to raster data
uint32_t bihsize;
// The length of the bitmap file header as defined in the BMP spec.
static const size_t LENGTH = 14;
// Internally we store the bitmap file header with an additional 4 bytes which
// is used to store the bitmap information header size.
static const size_t INTERNAL_LENGTH = 18;
};
// The length of the bitmap file header as defined in the BMP spec.
#define BFH_LENGTH 14
// Internally we store the bitmap file header with an additional 4 bytes which
// is used to store the bitmap information header size.
#define BFH_INTERNAL_LENGTH 18
#define OS2_INTERNAL_BIH_LENGTH 8
#define WIN_V3_INTERNAL_BIH_LENGTH 36
#define WIN_V5_INTERNAL_BIH_LENGTH 120
#define OS2_BIH_LENGTH 12 // This is the real BIH size (as contained in the
// bihsize field of BMPFILEHEADER)
#define WIN_V3_BIH_LENGTH 40 // This is the real BIH size (as contained in the
// bihsize field of BMPFILEHEADER)
#define WIN_V5_BIH_LENGTH 124 // This is the real BIH size (as contained in the
// bihsize field of BMPFILEHEADER)
#define OS2_HEADER_LENGTH (BFH_INTERNAL_LENGTH + OS2_INTERNAL_BIH_LENGTH)
#define WIN_V3_HEADER_LENGTH (BFH_INTERNAL_LENGTH + WIN_V3_INTERNAL_BIH_LENGTH)
#define WIN_V5_HEADER_LENGTH (BFH_INTERNAL_LENGTH + WIN_V5_INTERNAL_BIH_LENGTH)
#ifndef LCS_sRGB
#define LCS_sRGB 0x73524742
#endif
struct BMP_HEADER_LENGTH {
enum {
OS2 = BMPFILEHEADER::INTERNAL_LENGTH + BIH_INTERNAL_LENGTH::OS2,
WIN_V3 = BMPFILEHEADER::INTERNAL_LENGTH + BIH_INTERNAL_LENGTH::WIN_V3,
WIN_V5 = BMPFILEHEADER::INTERNAL_LENGTH + BIH_INTERNAL_LENGTH::WIN_V5
};
};
struct xyz {
int32_t x, y, z;
@ -78,6 +89,8 @@ struct BITMAPV5HEADER {
uint32_t profile_offset; // Offset to profile data in bytes
uint32_t profile_size; // Size of profile data in bytes
uint32_t reserved; // =0
static const uint32_t COLOR_SPACE_LCS_SRGB = 0x73524742;
};
struct colorTable {
@ -96,38 +109,34 @@ struct bitFields {
uint8_t greenRightShift;
uint8_t blueLeftShift;
uint8_t blueRightShift;
// Length of the bitfields structure in the BMP file.
static const size_t LENGTH = 12;
};
} // namespace image
} // namespace mozilla
struct BMPINFOHEADER {
// BMPINFOHEADER.compression definitions.
enum {
RGB = 0,
RLE8 = 1,
RLE4 = 2,
BITFIELDS = 3,
#define BITFIELD_LENGTH 12 // Length of the bitfields structure in the bmp file
#define USE_RGB
// ALPHABITFIELDS means no compression and specifies alpha bits. Valid only
// for 32bpp and 16bpp.
ALPHABITFIELDS = 4
};
};
// BMPINFOHEADER.compression defines
#ifndef BI_RGB
#define BI_RGB 0
#endif
#ifndef BI_RLE8
#define BI_RLE8 1
#endif
#ifndef BI_RLE4
#define BI_RLE4 2
#endif
#ifndef BI_BITFIELDS
#define BI_BITFIELDS 3
#endif
// BI_ALPHABITFIELDS means no compression and specifies alpha bits
// valid only for 32bpp and 16bpp
#ifndef BI_ALPHABITFIELDS
#define BI_ALPHABITFIELDS 4
#endif
// RLE Escape codes
#define RLE_ESCAPE 0
#define RLE_ESCAPE_EOL 0
#define RLE_ESCAPE_EOF 1
#define RLE_ESCAPE_DELTA 2
// RLE escape codes.
struct RLE {
enum {
ESCAPE = 0,
ESCAPE_EOL = 0,
ESCAPE_EOF = 1,
ESCAPE_DELTA = 2
};
};
/// enums for mState
enum ERLEState {
@ -141,4 +150,7 @@ enum ERLEState {
///< be read as padding
};
} // namespace image
} // namespace mozilla
#endif // mozilla_image_BMPFileHeaders_h

View File

@ -39,7 +39,7 @@ GetBMPLog()
nsBMPDecoder::nsBMPDecoder(RasterImage* aImage)
: Decoder(aImage)
, mPos(0)
, mLOH(WIN_V3_HEADER_LENGTH)
, mLOH(BMP_HEADER_LENGTH::WIN_V3)
, mNumColors(0)
, mColors(nullptr)
, mRow(nullptr)
@ -101,13 +101,14 @@ nsBMPDecoder::GetImageData()
int32_t
nsBMPDecoder::GetCompressedImageSize() const
{
// For everything except BI_RGB the header field must be defined
if (mBIH.compression != BI_RGB) {
// For everything except BMPINFOHEADER::RGB the header field must be defined
if (mBIH.compression != BMPINFOHEADER::RGB) {
return mBIH.image_size;
}
// mBIH.image_size isn't always filled for BI_RGB so calculate it manually
// The pixel array size is calculated based on extra 4 byte boundary padding
// mBIH.image_size isn't always filled for BMPINFOHEADER::RGB so calculate it
// manually. The pixel array size is calculated based on extra 4 byte
// boundary padding.
uint32_t rowSize = (mBIH.bpp * mBIH.width + 7) / 8; // + 7 to round up
// Pad to DWORD Boundary
@ -206,39 +207,39 @@ nsBMPDecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
return;
}
// This code assumes that mRawBuf == WIN_V3_INTERNAL_BIH_LENGTH
// and that sizeof(mRawBuf) >= BFH_INTERNAL_LENGTH
MOZ_ASSERT(sizeof(mRawBuf) == WIN_V3_INTERNAL_BIH_LENGTH);
MOZ_ASSERT(sizeof(mRawBuf) >= BFH_INTERNAL_LENGTH);
MOZ_ASSERT(OS2_INTERNAL_BIH_LENGTH < WIN_V3_INTERNAL_BIH_LENGTH);
// This code assumes that mRawBuf == BIH_INTERNAL_LENGTH::WIN_V3
// and that sizeof(mRawBuf) >= BMPFILEHEADER::INTERNAL_LENGTH
MOZ_ASSERT(sizeof(mRawBuf) == BIH_INTERNAL_LENGTH::WIN_V3);
MOZ_ASSERT(sizeof(mRawBuf) >= BMPFILEHEADER::INTERNAL_LENGTH);
MOZ_ASSERT(BIH_INTERNAL_LENGTH::OS2 < BIH_INTERNAL_LENGTH::WIN_V3);
// This code also assumes it's working with a byte array
MOZ_ASSERT(sizeof(mRawBuf[0]) == 1);
if (mPos < BFH_INTERNAL_LENGTH) { /* In BITMAPFILEHEADER */
// BFH_INTERNAL_LENGTH < sizeof(mRawBuf)
// mPos < BFH_INTERNAL_LENGTH
// BFH_INTERNAL_LENGTH - mPos < sizeof(mRawBuf)
// so toCopy <= BFH_INTERNAL_LENGTH
if (mPos < BMPFILEHEADER::INTERNAL_LENGTH) { /* In BITMAPFILEHEADER */
// BMPFILEHEADER::INTERNAL_LENGTH < sizeof(mRawBuf)
// mPos < BMPFILEHEADER::INTERNAL_LENGTH
// BMPFILEHEADER::INTERNAL_LENGTH - mPos < sizeof(mRawBuf)
// so toCopy <= BMPFILEHEADER::INTERNAL_LENGTH
// so toCopy < sizeof(mRawBuf)
// so toCopy > 0 && toCopy <= BFH_INTERNAL_LENGTH
uint32_t toCopy = BFH_INTERNAL_LENGTH - mPos;
// so toCopy > 0 && toCopy <= BMPFILEHEADER::INTERNAL_LENGTH
uint32_t toCopy = BMPFILEHEADER::INTERNAL_LENGTH - mPos;
if (toCopy > aCount) {
toCopy = aCount;
}
// mRawBuf is a byte array of size WIN_V3_INTERNAL_BIH_LENGTH
// mRawBuf is a byte array of size BIH_INTERNAL_LENGTH::WIN_V3
// (verified above)
// mPos is < BFH_INTERNAL_LENGTH
// BFH_INTERNAL_LENGTH < WIN_V3_INTERNAL_BIH_LENGTH
// mPos is < BMPFILEHEADER::INTERNAL_LENGTH
// BMPFILEHEADER::INTERNAL_LENGTH < BIH_INTERNAL_LENGTH::WIN_V3
// so mPos < sizeof(mRawBuf)
//
// Therefore this assert should hold
MOZ_ASSERT(mPos < sizeof(mRawBuf));
// toCopy <= BFH_INTERNAL_LENGTH
// mPos >= 0 && mPos < BFH_INTERNAL_LENGTH
// sizeof(mRawBuf) >= BFH_INTERNAL_LENGTH (verified above)
// toCopy <= BMPFILEHEADER::INTERNAL_LENGTH
// mPos >= 0 && mPos < BMPFILEHEADER::INTERNAL_LENGTH
// sizeof(mRawBuf) >= BMPFILEHEADER::INTERNAL_LENGTH (verified above)
//
// Therefore this assert should hold
MOZ_ASSERT(mPos + toCopy <= sizeof(mRawBuf));
@ -248,37 +249,37 @@ nsBMPDecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
aCount -= toCopy;
aBuffer += toCopy;
}
if (mPos == BFH_INTERNAL_LENGTH) {
if (mPos == BMPFILEHEADER::INTERNAL_LENGTH) {
ProcessFileHeader();
if (mBFH.signature[0] != 'B' || mBFH.signature[1] != 'M') {
PostDataError();
return;
}
if (mBFH.bihsize == OS2_BIH_LENGTH) {
mLOH = OS2_HEADER_LENGTH;
if (mBFH.bihsize == BIH_LENGTH::OS2) {
mLOH = BMP_HEADER_LENGTH::OS2;
}
}
if (mPos >= BFH_INTERNAL_LENGTH && mPos < mLOH) { /* In BITMAPINFOHEADER */
// mLOH == WIN_V3_HEADER_LENGTH || mLOH == OS2_HEADER_LENGTH
// OS2_HEADER_LENGTH < WIN_V3_HEADER_LENGTH
// BFH_INTERNAL_LENGTH < OS2_HEADER_LENGTH
// BFH_INTERNAL_LENGTH < WIN_V3_HEADER_LENGTH
if (mPos >= BMPFILEHEADER::INTERNAL_LENGTH && mPos < mLOH) { /* In BITMAPINFOHEADER */
// mLOH == BMP_HEADER_LENGTH::WIN_V3 || mLOH == BMP_HEADER_LENGTH::OS2
// BMP_HEADER_LENGTH::OS2 < BMP_HEADER_LENGTH::WIN_V3
// BMPFILEHEADER::INTERNAL_LENGTH < BMP_HEADER_LENGTH::OS2
// BMPFILEHEADER::INTERNAL_LENGTH < BMP_HEADER_LENGTH::WIN_V3
//
// So toCopy is in the range
// 1 to (WIN_V3_HEADER_LENGTH - BFH_INTERNAL_LENGTH)
// or 1 to (OS2_HEADER_LENGTH - BFH_INTERNAL_LENGTH)
// 1 to (BMP_HEADER_LENGTH::WIN_V3 - BMPFILEHEADER::INTERNAL_LENGTH)
// or 1 to (BMP_HEADER_LENGTH::OS2 - BMPFILEHEADER::INTERNAL_LENGTH)
//
// But WIN_V3_HEADER_LENGTH =
// BFH_INTERNAL_LENGTH + WIN_V3_INTERNAL_BIH_LENGTH
// and OS2_HEADER_LENGTH = BFH_INTERNAL_LENGTH + OS2_INTERNAL_BIH_LENGTH
// But BMP_HEADER_LENGTH::WIN_V3 =
// BMPFILEHEADER::INTERNAL_LENGTH + BIH_INTERNAL_LENGTH::WIN_V3
// and BMP_HEADER_LENGTH::OS2 = BMPFILEHEADER::INTERNAL_LENGTH + BIH_INTERNAL_LENGTH::OS2
//
// So toCopy is in the range
//
// 1 to WIN_V3_INTERNAL_BIH_LENGTH
// or 1 to OS2_INTERNAL_BIH_LENGTH
// and OS2_INTERNAL_BIH_LENGTH < WIN_V3_INTERNAL_BIH_LENGTH
// 1 to BIH_INTERNAL_LENGTH::WIN_V3
// or 1 to BIH_INTERNAL_LENGTH::OS2
// and BIH_INTERNAL_LENGTH::OS2 < BIH_INTERNAL_LENGTH::WIN_V3
//
// sizeof(mRawBuf) = WIN_V3_INTERNAL_BIH_LENGTH
// sizeof(mRawBuf) = BIH_INTERNAL_LENGTH::WIN_V3
// so toCopy <= sizeof(mRawBuf)
uint32_t toCopy = mLOH - mPos;
if (toCopy > aCount) {
@ -286,37 +287,37 @@ nsBMPDecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
}
// mPos is in the range
// BFH_INTERNAL_LENGTH to (WIN_V3_HEADER_LENGTH - 1)
// BMPFILEHEADER::INTERNAL_LENGTH to (BMP_HEADER_LENGTH::WIN_V3 - 1)
//
// offset is then in the range (see toCopy comments for more details)
// 0 to (WIN_V3_INTERNAL_BIH_LENGTH - 1)
// 0 to (BIH_INTERNAL_LENGTH::WIN_V3 - 1)
//
// sizeof(mRawBuf) is WIN_V3_INTERNAL_BIH_LENGTH so this
// sizeof(mRawBuf) is BIH_INTERNAL_LENGTH::WIN_V3 so this
// offset stays within bounds and this assert should hold
const uint32_t offset = mPos - BFH_INTERNAL_LENGTH;
const uint32_t offset = mPos - BMPFILEHEADER::INTERNAL_LENGTH;
MOZ_ASSERT(offset < sizeof(mRawBuf));
// Two cases:
// mPos = BFH_INTERNAL_LENGTH
// mLOH = WIN_V3_HEADER_LENGTH
// mPos = BMPFILEHEADER::INTERNAL_LENGTH
// mLOH = BMP_HEADER_LENGTH::WIN_V3
//
// offset = 0
// toCopy = WIN_V3_INTERNAL_BIH_LENGTH
// toCopy = BIH_INTERNAL_LENGTH::WIN_V3
//
// This will be in the bounds of sizeof(mRawBuf)
//
// Second Case:
// mPos = WIN_V3_HEADER_LENGTH - 1
// mLOH = WIN_V3_HEADER_LENGTH
// mPos = BMP_HEADER_LENGTH::WIN_V3 - 1
// mLOH = BMP_HEADER_LENGTH::WIN_V3
//
// offset = WIN_V3_INTERNAL_BIH_LENGTH - 1
// offset = BIH_INTERNAL_LENGTH::WIN_V3 - 1
// toCopy = 1
//
// This will be in the bounds of sizeof(mRawBuf)
//
// As sizeof(mRawBuf) == WIN_V3_INTERNAL_BIH_LENGTH (verified above)
// and WIN_V3_HEADER_LENGTH is the largest range of values. If mLOH
// was equal to OS2_HEADER_LENGTH then the ranges are smaller.
// As sizeof(mRawBuf) == BIH_INTERNAL_LENGTH::WIN_V3 (verified above)
// and BMP_HEADER_LENGTH::WIN_V3 is the largest range of values. If mLOH
// was equal to BMP_HEADER_LENGTH::OS2 then the ranges are smaller.
MOZ_ASSERT(offset + toCopy <= sizeof(mRawBuf));
memcpy(mRawBuf + offset, aBuffer, toCopy);
@ -386,7 +387,8 @@ nsBMPDecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
// Always allocate 256 even though mNumColors might be smaller
mColors = new colorTable[256];
memset(mColors, 0, 256 * sizeof(colorTable));
} else if (mBIH.compression != BI_BITFIELDS && mBIH.bpp == 16) {
} else if (mBIH.compression != BMPINFOHEADER::BITFIELDS &&
mBIH.bpp == 16) {
// Use default 5-5-5 format
mBitFields.red = 0x7C00;
mBitFields.green = 0x03E0;
@ -396,27 +398,30 @@ nsBMPDecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
// Make sure we have a valid value for our supported compression modes
// before adding the frame
if (mBIH.compression != BI_RGB && mBIH.compression != BI_RLE8 &&
mBIH.compression != BI_RLE4 && mBIH.compression != BI_BITFIELDS) {
if (mBIH.compression != BMPINFOHEADER::RGB &&
mBIH.compression != BMPINFOHEADER::RLE8 &&
mBIH.compression != BMPINFOHEADER::RLE4 &&
mBIH.compression != BMPINFOHEADER::BITFIELDS) {
PostDataError();
return;
}
// If we have RLE4 or RLE8 or BI_ALPHABITFIELDS, then ensure we
// have valid BPP values before adding the frame
if (mBIH.compression == BI_RLE8 && mBIH.bpp != 8) {
// If we have RLE4 or RLE8 or BMPINFOHEADER::ALPHABITFIELDS, then ensure
// we have valid BPP values before adding the frame.
if (mBIH.compression == BMPINFOHEADER::RLE8 && mBIH.bpp != 8) {
MOZ_LOG(GetBMPLog(), LogLevel::Debug,
("BMP RLE8 compression only supports 8 bits per pixel\n"));
PostDataError();
return;
}
if (mBIH.compression == BI_RLE4 && mBIH.bpp != 4 && mBIH.bpp != 1) {
if (mBIH.compression == BMPINFOHEADER::RLE4 &&
mBIH.bpp != 4 && mBIH.bpp != 1) {
MOZ_LOG(GetBMPLog(), LogLevel::Debug,
("BMP RLE4 compression only supports 4 bits per pixel\n"));
PostDataError();
return;
}
if (mBIH.compression == BI_ALPHABITFIELDS &&
if (mBIH.compression == BMPINFOHEADER::ALPHABITFIELDS &&
mBIH.bpp != 16 && mBIH.bpp != 32) {
MOZ_LOG(GetBMPLog(), LogLevel::Debug,
("BMP ALPHABITFIELDS only supports 16 or 32 bits per pixel\n"
@ -425,8 +430,9 @@ nsBMPDecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
return;
}
if (mBIH.compression != BI_RLE8 && mBIH.compression != BI_RLE4 &&
mBIH.compression != BI_ALPHABITFIELDS) {
if (mBIH.compression != BMPINFOHEADER::RLE8 &&
mBIH.compression != BMPINFOHEADER::RLE4 &&
mBIH.compression != BMPINFOHEADER::ALPHABITFIELDS) {
// mRow is not used for RLE encoded images
mRow = (uint8_t*)malloc((mBIH.width * mBIH.bpp) / 8 + 4);
// + 4 because the line is padded to a 4 bit boundary, but
@ -447,7 +453,8 @@ nsBMPDecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
MOZ_ASSERT(mImageData, "Should have a buffer now");
// Prepare for transparency
if ((mBIH.compression == BI_RLE8) || (mBIH.compression == BI_RLE4)) {
if ((mBIH.compression == BMPINFOHEADER::RLE8) ||
(mBIH.compression == BMPINFOHEADER::RLE4)) {
// Clear the image, as the RLE may jump over areas
memset(mImageData, 0, mImageDataLength);
}
@ -455,7 +462,7 @@ nsBMPDecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
if (mColors && mPos >= mLOH) {
// OS/2 Bitmaps have no padding byte
uint8_t bytesPerColor = (mBFH.bihsize == OS2_BIH_LENGTH) ? 3 : 4;
uint8_t bytesPerColor = (mBFH.bihsize == BIH_LENGTH::OS2) ? 3 : 4;
if (mPos < (mLOH + mNumColors * bytesPerColor)) {
// Number of bytes already received
uint32_t colorBytes = mPos - mLOH;
@ -488,62 +495,62 @@ nsBMPDecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
at = (at + 1) % bytesPerColor;
}
}
} else if (aCount && mBIH.compression == BI_BITFIELDS && mPos <
(WIN_V3_HEADER_LENGTH + BITFIELD_LENGTH)) {
// If compression is used, this is a windows bitmap (compression
// can't be used with OS/2 bitmaps),
// hence we can use WIN_V3_HEADER_LENGTH instead of mLOH.
// (verified below)
} else if (aCount &&
mBIH.compression == BMPINFOHEADER::BITFIELDS &&
mPos < (BMP_HEADER_LENGTH::WIN_V3 + bitFields::LENGTH)) {
// If compression is used, this is a windows bitmap (compression can't be
// used with OS/2 bitmaps), hence we can use BMP_HEADER_LENGTH::WIN_V3
// instead of mLOH. (verified below)
// If aCount != 0 then mPos should be >= mLOH due to the if statements
// at the beginning of the function
MOZ_ASSERT(mPos >= mLOH);
MOZ_ASSERT(mLOH == WIN_V3_HEADER_LENGTH);
MOZ_ASSERT(mLOH == BMP_HEADER_LENGTH::WIN_V3);
// mLOH == WIN_V3_HEADER_LENGTH (verified above)
// mLOH == BMP_HEADER_LENGTH::WIN_V3 (verified above)
// mPos >= mLOH (verified above)
// mPos < WIN_V3_HEADER_LENGTH + BITFIELD_LENGTH
// mPos < BMP_HEADER_LENGTH::WIN_V3 + bitFields::LENGTH
//
// So toCopy is in the range
// 0 to (BITFIELD_LENGTH - 1)
uint32_t toCopy = (WIN_V3_HEADER_LENGTH + BITFIELD_LENGTH) - mPos;
// 0 to (bitFields::LENGTH - 1)
uint32_t toCopy = (BMP_HEADER_LENGTH::WIN_V3 + bitFields::LENGTH) - mPos;
if (toCopy > aCount) {
toCopy = aCount;
}
// mPos >= WIN_V3_HEADER_LENGTH
// mPos < WIN_V3_HEADER_LENGTH + BITFIELD_LENGTH
// mPos >= BMP_HEADER_LENGTH::WIN_V3
// mPos < BMP_HEADER_LENGTH::WIN_V3 + bitFields::LENGTH
//
// offset is in the range
// 0 to (BITFIELD_LENGTH - 1)
// 0 to (bitFields::LENGTH - 1)
//
// BITFIELD_LENGTH < WIN_V3_INTERNAL_BIH_LENGTH
// and sizeof(mRawBuf) == WIN_V3_INTERNAL_BIH_LENGTH (verified at
// bitFields::LENGTH < BIH_INTERNAL_LENGTH::WIN_V3
// and sizeof(mRawBuf) == BIH_INTERNAL_LENGTH::WIN_V3 (verified at
// top of function)
//
// Therefore this assert should hold
const uint32_t offset = mPos - WIN_V3_HEADER_LENGTH;
const uint32_t offset = mPos - BMP_HEADER_LENGTH::WIN_V3;
MOZ_ASSERT(offset < sizeof(mRawBuf));
// Two cases:
// mPos = WIN_V3_HEADER_LENGTH
// mPos = BMP_HEADER_LENGTH::WIN_V3
//
// offset = 0
// toCopy = BITFIELD_LENGTH
// toCopy = bitFields::LENGTH
//
// This will be in the bounds of sizeof(mRawBuf)
//
// Second case:
//
// mPos = WIN_V3_HEADER_LENGTH + BITFIELD_LENGTH - 1
// mPos = BMP_HEADER_LENGTH::WIN_V3 + bitFields::LENGTH - 1
//
// offset = BITFIELD_LENGTH - 1
// offset = bitFields::LENGTH - 1
// toCopy = 1
//
// This will be in the bounds of sizeof(mRawBuf)
//
// As BITFIELD_LENGTH < WIN_V3_INTERNAL_BIH_LENGTH and
// sizeof(mRawBuf) == WIN_V3_INTERNAL_BIH_LENGTH
// As bitFields::LENGTH < BIH_INTERNAL_LENGTH::WIN_V3 and
// sizeof(mRawBuf) == BIH_INTERNAL_LENGTH::WIN_V3
//
// Therefore this assert should hold
MOZ_ASSERT(offset + toCopy <= sizeof(mRawBuf));
@ -553,8 +560,8 @@ nsBMPDecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
aBuffer += toCopy;
aCount -= toCopy;
}
if (mPos == WIN_V3_HEADER_LENGTH + BITFIELD_LENGTH &&
mBIH.compression == BI_BITFIELDS) {
if (mPos == BMP_HEADER_LENGTH::WIN_V3 + bitFields::LENGTH &&
mBIH.compression == BMPINFOHEADER::BITFIELDS) {
mBitFields.red = LittleEndian::readUint32(reinterpret_cast<uint32_t*>
(mRawBuf));
mBitFields.green = LittleEndian::readUint32(reinterpret_cast<uint32_t*>
@ -570,7 +577,7 @@ nsBMPDecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
if (aCount && ++mPos >= mBFH.dataoffset) {
// Need to increment mPos, else we might get to mPos==mLOH again
// From now on, mPos is irrelevant
if (!mBIH.compression || mBIH.compression == BI_BITFIELDS) {
if (!mBIH.compression || mBIH.compression == BMPINFOHEADER::BITFIELDS) {
uint32_t rowSize = (mBIH.bpp * mBIH.width + 7) / 8; // + 7 to
// round up
if (rowSize % 4) {
@ -689,10 +696,10 @@ nsBMPDecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
mRowBytes = 0;
}
} while (aCount > 0);
} else if ((mBIH.compression == BI_RLE8) ||
(mBIH.compression == BI_RLE4)) {
if (((mBIH.compression == BI_RLE8) && (mBIH.bpp != 8)) ||
((mBIH.compression == BI_RLE4) && (mBIH.bpp != 4) &&
} else if ((mBIH.compression == BMPINFOHEADER::RLE8) ||
(mBIH.compression == BMPINFOHEADER::RLE4)) {
if (((mBIH.compression == BMPINFOHEADER::RLE8) && (mBIH.bpp != 8)) ||
((mBIH.compression == BMPINFOHEADER::RLE4) && (mBIH.bpp != 4) &&
(mBIH.bpp != 1))) {
MOZ_LOG(GetBMPLog(), LogLevel::Debug,
("BMP RLE8/RLE4 compression only supports 8/4 bits per"
@ -715,7 +722,7 @@ nsBMPDecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
case eRLEStateNeedSecondEscapeByte:
byte = *aBuffer++;
aCount--;
if (mStateData != RLE_ESCAPE) { // encoded mode
if (mStateData != RLE::ESCAPE) { // encoded mode
// Encoded mode consists of two bytes:
// the first byte (mStateData) specifies the
// number of consecutive pixels to be drawn
@ -729,7 +736,7 @@ nsBMPDecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
uint32_t* d = reinterpret_cast<uint32_t*>
(mImageData) + PIXEL_OFFSET(mCurLine, mCurPos);
mCurPos += pixelsNeeded;
if (mBIH.compression == BI_RLE8) {
if (mBIH.compression == BMPINFOHEADER::RLE8) {
do {
SetPixel(d, byte, mColors);
pixelsNeeded --;
@ -744,18 +751,18 @@ nsBMPDecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
}
switch(byte) {
case RLE_ESCAPE_EOL:
case RLE::ESCAPE_EOL:
// End of Line: Go to next row
mCurLine --;
mCurPos = 0;
mState = eRLEStateInitial;
break;
case RLE_ESCAPE_EOF: // EndOfFile
case RLE::ESCAPE_EOF: // EndOfFile
mCurPos = mCurLine = 0;
break;
case RLE_ESCAPE_DELTA:
case RLE::ESCAPE_DELTA:
mState = eRLEStateNeedXDelta;
continue;
@ -834,7 +841,7 @@ nsBMPDecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
(mImageData) +
PIXEL_OFFSET(mCurLine, mCurPos);
uint32_t* oldPos = d;
if (mBIH.compression == BI_RLE8) {
if (mBIH.compression == BMPINFOHEADER::RLE8) {
while (aCount > 0 && mStateData > 0) {
byte = *aBuffer++;
aCount--;

View File

@ -64,8 +64,8 @@ private:
BMPFILEHEADER mBFH;
BITMAPV5HEADER mBIH;
char mRawBuf[WIN_V3_INTERNAL_BIH_LENGTH]; //< If this is changed,
// WriteInternal() MUST be updated
char mRawBuf[BIH_INTERNAL_LENGTH::WIN_V3]; //< If this is changed,
// WriteInternal() MUST be updated
uint32_t mLOH; //< Length of the header

View File

@ -125,7 +125,7 @@ nsICODecoder::FillBitmapFileHeaderBuffer(int8_t* bfh)
bfh[1] = 'M';
int32_t dataOffset = 0;
int32_t fileSize = 0;
dataOffset = BFH_LENGTH + BITMAPINFOSIZE;
dataOffset = BMPFILEHEADER::LENGTH + BITMAPINFOSIZE;
// The color table is present only if BPP is <= 8
if (mDirEntry.mBitCount <= 8) {

View File

@ -12,6 +12,7 @@
#include "nsAutoPtr.h"
using namespace mozilla;
using namespace mozilla::image;
NS_IMPL_ISUPPORTS(nsBMPEncoder, imgIEncoder, nsIInputStream,
nsIAsyncInputStream)
@ -484,9 +485,9 @@ nsBMPEncoder::InitFileHeader(Version aVersion, uint32_t aBPP, uint32_t aWidth,
mBMPFileHeader.signature[1] = 'M';
if (aVersion == VERSION_3) {
mBMPFileHeader.dataoffset = WIN_V3_HEADER_LENGTH;
mBMPFileHeader.dataoffset = BMP_HEADER_LENGTH::WIN_V3;
} else { // aVersion == 5
mBMPFileHeader.dataoffset = WIN_V5_HEADER_LENGTH;
mBMPFileHeader.dataoffset = BMP_HEADER_LENGTH::WIN_V5;
}
// The color table is present only if BPP is <= 8
@ -502,9 +503,9 @@ nsBMPEncoder::InitFileHeader(Version aVersion, uint32_t aBPP, uint32_t aWidth,
mBMPFileHeader.reserved = 0;
if (aVersion == VERSION_3) {
mBMPFileHeader.bihsize = WIN_V3_BIH_LENGTH;
mBMPFileHeader.bihsize = BIH_LENGTH::WIN_V3;
} else { // aVersion == VERSION_5
mBMPFileHeader.bihsize = WIN_V5_BIH_LENGTH;
mBMPFileHeader.bihsize = BIH_LENGTH::WIN_V5;
}
}
@ -538,7 +539,7 @@ nsBMPEncoder::InitInfoHeader(Version aVersion, uint32_t aBPP, uint32_t aWidth,
mBMPInfoHeader.green_mask = 0x0000FF00;
mBMPInfoHeader.blue_mask = 0x00FF0000;
mBMPInfoHeader.alpha_mask = 0xFF000000;
mBMPInfoHeader.color_space = LCS_sRGB;
mBMPInfoHeader.color_space = BITMAPV5HEADER::COLOR_SPACE_LCS_SRGB;
mBMPInfoHeader.white_point.r.x = 0;
mBMPInfoHeader.white_point.r.y = 0;
mBMPInfoHeader.white_point.r.z = 0;
@ -612,7 +613,7 @@ nsBMPEncoder::EncodeInfoHeader()
NativeEndian::swapToLittleEndianInPlace(&littleEndianmBIH.profile_offset, 1);
NativeEndian::swapToLittleEndianInPlace(&littleEndianmBIH.profile_size, 1);
if (mBMPFileHeader.bihsize == OS2_BIH_LENGTH) {
if (mBMPFileHeader.bihsize == BIH_LENGTH::OS2) {
uint16_t width = (uint16_t) littleEndianmBIH.width;
ENCODE(&mImageBufferCurr, width);
uint16_t height = (uint16_t) littleEndianmBIH.width;
@ -625,7 +626,7 @@ nsBMPEncoder::EncodeInfoHeader()
ENCODE(&mImageBufferCurr, littleEndianmBIH.planes);
ENCODE(&mImageBufferCurr, littleEndianmBIH.bpp);
if (mBMPFileHeader.bihsize > OS2_BIH_LENGTH) {
if (mBMPFileHeader.bihsize > BIH_LENGTH::OS2) {
ENCODE(&mImageBufferCurr, littleEndianmBIH.compression);
ENCODE(&mImageBufferCurr, littleEndianmBIH.image_size);
ENCODE(&mImageBufferCurr, littleEndianmBIH.xppm);
@ -634,7 +635,7 @@ nsBMPEncoder::EncodeInfoHeader()
ENCODE(&mImageBufferCurr, littleEndianmBIH.important_colors);
}
if (mBMPFileHeader.bihsize > WIN_V3_BIH_LENGTH) {
if (mBMPFileHeader.bihsize > BIH_LENGTH::WIN_V3) {
ENCODE(&mImageBufferCurr, littleEndianmBIH.red_mask);
ENCODE(&mImageBufferCurr, littleEndianmBIH.green_mask);
ENCODE(&mImageBufferCurr, littleEndianmBIH.blue_mask);

View File

@ -162,8 +162,9 @@ nsICOEncoder::AddImageFrame(const uint8_t* aData,
// Icon files that wrap a BMP file must not include the BITMAPFILEHEADER
// section at the beginning of the encoded BMP data, so we must skip over
// BFH_LENGTH bytes when adding the BMP content to the icon file.
mICODirEntry.mBytesInRes = BMPImageBufferSize - BFH_LENGTH + andMaskSize;
// BMPFILEHEADER::LENGTH bytes when adding the BMP content to the icon file.
mICODirEntry.mBytesInRes =
BMPImageBufferSize - BMPFILEHEADER::LENGTH + andMaskSize;
// Encode the icon headers
EncodeFileHeader();
@ -172,14 +173,14 @@ nsICOEncoder::AddImageFrame(const uint8_t* aData,
char* imageBuffer;
rv = mContainedEncoder->GetImageBuffer(&imageBuffer);
NS_ENSURE_SUCCESS(rv, rv);
memcpy(mImageBufferCurr, imageBuffer + BFH_LENGTH,
BMPImageBufferSize - BFH_LENGTH);
memcpy(mImageBufferCurr, imageBuffer + BMPFILEHEADER::LENGTH,
BMPImageBufferSize - BMPFILEHEADER::LENGTH);
// We need to fix the BMP height to be *2 for the AND mask
uint32_t fixedHeight = GetRealHeight() * 2;
NativeEndian::swapToLittleEndianInPlace(&fixedHeight, 1);
// The height is stored at an offset of 8 from the DIB header
memcpy(mImageBufferCurr + 8, &fixedHeight, sizeof(fixedHeight));
mImageBufferCurr += BMPImageBufferSize - BFH_LENGTH;
mImageBufferCurr += BMPImageBufferSize - BMPFILEHEADER::LENGTH;
// Calculate rowsize in DWORD's
uint32_t rowSize = ((GetRealWidth() + 31) / 32) * 4; // + 31 to round up