Bug 722555 - Add support for encoding RGBA BMPs - r=jgilbert

This commit is contained in:
Eddy Bruel 2012-06-08 12:58:07 -07:00
parent 348cb1d818
commit 6153d366da
5 changed files with 217 additions and 132 deletions

View File

@ -38,7 +38,7 @@ nsBMPDecoder::nsBMPDecoder(RasterImage &aImage, imgIDecoderObserver* aObserver)
mOldLine = mCurLine = 1; // Otherwise decoder will never start
mState = eRLEStateInitial;
mStateData = 0;
mLOH = WIN_HEADER_LENGTH;
mLOH = WIN_V3_HEADER_LENGTH;
mUseAlphaData = mHaveAlphaData = false;
}
@ -379,18 +379,18 @@ nsBMPDecoder::WriteInternal(const char* aBuffer, PRUint32 aCount)
}
}
}
else if (aCount && mBIH.compression == BI_BITFIELDS && mPos < (WIN_HEADER_LENGTH + BITFIELD_LENGTH)) {
else if (aCount && mBIH.compression == BI_BITFIELDS && mPos < (WIN_V3_HEADER_LENGTH + BITFIELD_LENGTH)) {
// If compression is used, this is a windows bitmap, hence we can
// use WIN_HEADER_LENGTH instead of mLOH
PRUint32 toCopy = (WIN_HEADER_LENGTH + BITFIELD_LENGTH) - mPos;
PRUint32 toCopy = (WIN_V3_HEADER_LENGTH + BITFIELD_LENGTH) - mPos;
if (toCopy > aCount)
toCopy = aCount;
memcpy(mRawBuf + (mPos - WIN_HEADER_LENGTH), aBuffer, toCopy);
memcpy(mRawBuf + (mPos - WIN_V3_HEADER_LENGTH), aBuffer, toCopy);
mPos += toCopy;
aBuffer += toCopy;
aCount -= toCopy;
}
if (mPos == WIN_HEADER_LENGTH + BITFIELD_LENGTH &&
if (mPos == WIN_V3_HEADER_LENGTH + BITFIELD_LENGTH &&
mBIH.compression == BI_BITFIELDS) {
mBitFields.red = LITTLE_TO_NATIVE32(*(PRUint32*)mRawBuf);
mBitFields.green = LITTLE_TO_NATIVE32(*(PRUint32*)(mRawBuf + 4));

View File

@ -58,8 +58,8 @@ private:
PRUint32 mPos;
BMPFILEHEADER mBFH;
BMPINFOHEADER mBIH;
char mRawBuf[36];
BITMAPV5HEADER mBIH;
char mRawBuf[WIN_V3_INTERNAL_BIH_LENGTH];
PRUint32 mLOH; ///< Length of the header

View File

@ -119,14 +119,15 @@ NS_IMETHODIMP nsBMPEncoder::StartImageEncode(PRUint32 aWidth,
}
// parse and check any provided output options
Version version;
PRUint32 bpp;
nsresult rv = ParseOptions(aOutputOptions, &bpp);
nsresult rv = ParseOptions(aOutputOptions, &version, &bpp);
if (NS_FAILED(rv)) {
return rv;
}
InitFileHeader(bpp, aWidth, aHeight);
InitInfoHeader(bpp, aWidth, aHeight);
InitFileHeader(version, bpp, aWidth, aHeight);
InitInfoHeader(version, bpp, aWidth, aHeight);
mImageBufferSize = mBMPFileHeader.filesize;
mImageBufferStart = static_cast<PRUint8*>(moz_malloc(mImageBufferSize));
@ -200,9 +201,8 @@ NS_IMETHODIMP nsBMPEncoder::AddImageFrame(const PRUint8* aData,
}
}
} else if (aInputFormat == INPUT_FORMAT_RGBA) {
// RBGA, but we need to strip the alpha
// simple RGBA, no conversion needed
for (PRInt32 y = 0; y < mBMPInfoHeader.height; y ++) {
StripAlpha(&aData[y * aStride], row, mBMPInfoHeader.width);
if (mBMPInfoHeader.bpp == 24) {
EncodeImageDataRow24(row);
} else {
@ -210,7 +210,7 @@ NS_IMETHODIMP nsBMPEncoder::AddImageFrame(const PRUint8* aData,
}
}
} else if (aInputFormat == INPUT_FORMAT_RGB) {
// simple RBG(A), no conversion needed
// simple RGB, no conversion needed
for (PRInt32 y = 0; y < mBMPInfoHeader.height; y ++) {
if (mBMPInfoHeader.bpp == 24) {
EncodeImageDataRow24(&aData[y * aStride]);
@ -249,16 +249,16 @@ NS_IMETHODIMP nsBMPEncoder::EndImageEncode()
// Parses the encoder options and sets the bits per pixel to use
// See InitFromData for a description of the parse options
nsresult
nsBMPEncoder::ParseOptions(const nsAString& aOptions, PRUint32* bpp)
nsBMPEncoder::ParseOptions(const nsAString& aOptions, Version* version,
PRUint32* bpp)
{
// If no parsing options just use the default of 24BPP
if (aOptions.Length() == 0) {
if (bpp) {
*bpp = 24;
}
return NS_OK;
if (version) {
*version = VERSION_3;
}
if (bpp) {
*bpp = 24;
}
// Parse the input string into a set of name/value pairs.
// From a format like: name=value;bpp=<bpp_value>;name=value
// to format: [0] = name=value, [1] = bpp=<bpp_value>, [2] = name=value
@ -279,6 +279,19 @@ nsBMPEncoder::ParseOptions(const nsAString& aOptions, PRUint32* bpp)
return NS_ERROR_INVALID_ARG;
}
// Parse the bpp portion of the string name=value;version=<version_value>;
// name=value
if (nameValuePair[0].Equals("version",
nsCaseInsensitiveCStringComparator())) {
if (nameValuePair[1].Equals("3")) {
*version = VERSION_3;
} else if (nameValuePair[1].Equals("5")) {
*version = VERSION_5;
} else {
return NS_ERROR_INVALID_ARG;
}
}
// Parse the bpp portion of the string name=value;bpp=<bpp_value>;name=value
if (nameValuePair[0].Equals("bpp", nsCaseInsensitiveCStringComparator())) {
if (nameValuePair[1].Equals("24")) {
@ -428,22 +441,6 @@ nsBMPEncoder::ConvertHostARGBRow(const PRUint8* aSrc, PRUint8* aDest,
}
}
// nsBMPEncoder::StripAlpha
//
// Input is RGBA, output is RGB
void
nsBMPEncoder::StripAlpha(const PRUint8* aSrc, PRUint8* aDest,
PRUint32 aPixelWidth)
{
for (PRUint32 x = 0; x < aPixelWidth; x ++) {
const PRUint8* pixelIn = &aSrc[x * 4];
PRUint8* pixelOut = &aDest[x * 3];
pixelOut[0] = pixelIn[0];
pixelOut[1] = pixelIn[1];
pixelOut[2] = pixelIn[2];
}
}
void
nsBMPEncoder::NotifyListener()
{
@ -472,13 +469,18 @@ nsBMPEncoder::NotifyListener()
// Initializes the BMP file header mBMPFileHeader to the passed in values
void
nsBMPEncoder::InitFileHeader(PRUint32 aBPP, PRUint32 aWidth, PRUint32 aHeight)
nsBMPEncoder::InitFileHeader(Version aVersion, PRUint32 aBPP, PRUint32 aWidth,
PRUint32 aHeight)
{
memset(&mBMPFileHeader, 0, sizeof(mBMPFileHeader));
mBMPFileHeader.signature[0] = 'B';
mBMPFileHeader.signature[1] = 'M';
mBMPFileHeader.dataoffset = WIN_HEADER_LENGTH;
if (aVersion == VERSION_3) {
mBMPFileHeader.dataoffset = WIN_V3_HEADER_LENGTH;
} else { // aVersion == 5
mBMPFileHeader.dataoffset = WIN_V5_HEADER_LENGTH;
}
// The color table is present only if BPP is <= 8
if (aBPP <= 8) {
@ -492,21 +494,34 @@ nsBMPEncoder::InitFileHeader(PRUint32 aBPP, PRUint32 aWidth, PRUint32 aHeight)
}
mBMPFileHeader.reserved = 0;
mBMPFileHeader.bihsize = WIN_BIH_LENGTH;
if (aVersion == VERSION_3) {
mBMPFileHeader.bihsize = WIN_V3_BIH_LENGTH;
} else { // aVersion == VERSION_5
mBMPFileHeader.bihsize = WIN_V5_BIH_LENGTH;
}
}
template<typename T> static void
Encode(PRUint8** pImageBufferCurr, const T& value)
{
memcpy(*pImageBufferCurr, &value, sizeof(T));
*pImageBufferCurr += sizeof(T);
}
// Initializes the bitmap info header mBMPInfoHeader to the passed in values
void
nsBMPEncoder::InitInfoHeader(PRUint32 aBPP, PRUint32 aWidth, PRUint32 aHeight)
nsBMPEncoder::InitInfoHeader(Version aVersion, PRUint32 aBPP, PRUint32 aWidth,
PRUint32 aHeight)
{
memset(&mBMPInfoHeader, 0, sizeof(mBMPInfoHeader));
mBMPInfoHeader.bpp = aBPP;
mBMPInfoHeader.planes = 1;
mBMPInfoHeader.colors = 0;
mBMPInfoHeader.important_colors = 0;
mBMPInfoHeader.width = aWidth;
mBMPInfoHeader.height = aHeight;
mBMPInfoHeader.planes = 1;
mBMPInfoHeader.bpp = aBPP;
mBMPInfoHeader.compression = 0;
mBMPInfoHeader.colors = 0;
mBMPInfoHeader.important_colors = 0;
if (aBPP <= 8) {
mBMPInfoHeader.image_size = aWidth * aHeight;
} else {
@ -515,6 +530,36 @@ nsBMPEncoder::InitInfoHeader(PRUint32 aBPP, PRUint32 aWidth, PRUint32 aHeight)
}
mBMPInfoHeader.xppm = 0;
mBMPInfoHeader.yppm = 0;
if (aVersion >= VERSION_5) {
mBMPInfoHeader.red_mask = 0x000000FF;
mBMPInfoHeader.green_mask = 0x0000FF00;
mBMPInfoHeader.blue_mask = 0x00FF0000;
mBMPInfoHeader.alpha_mask = 0xFF000000;
mBMPInfoHeader.color_space = LCS_sRGB;
mBMPInfoHeader.white_point.r.x = 0;
mBMPInfoHeader.white_point.r.y = 0;
mBMPInfoHeader.white_point.r.z = 0;
mBMPInfoHeader.white_point.g.x = 0;
mBMPInfoHeader.white_point.g.y = 0;
mBMPInfoHeader.white_point.g.z = 0;
mBMPInfoHeader.white_point.b.x = 0;
mBMPInfoHeader.white_point.b.y = 0;
mBMPInfoHeader.white_point.b.z = 0;
mBMPInfoHeader.gamma_red = 0;
mBMPInfoHeader.gamma_green = 0;
mBMPInfoHeader.gamma_blue = 0;
mBMPInfoHeader.intent = 0;
mBMPInfoHeader.profile_offset = 0;
mBMPInfoHeader.profile_size = 0;
mBMPInfoHeader.reserved = 0;
}
}
template<typename T>
static inline void
ConvertToLittle(T& value)
{
value = NATIVE32_TO_LITTLE(value);
}
// Encodes the BMP file header mBMPFileHeader
@ -522,90 +567,96 @@ void
nsBMPEncoder::EncodeFileHeader()
{
mozilla::image::BMPFILEHEADER littleEndianBFH = mBMPFileHeader;
littleEndianBFH.filesize = NATIVE32_TO_LITTLE(littleEndianBFH.filesize);
littleEndianBFH.reserved = NATIVE32_TO_LITTLE(littleEndianBFH.reserved);
littleEndianBFH.dataoffset= NATIVE32_TO_LITTLE(littleEndianBFH.dataoffset);
littleEndianBFH.bihsize = NATIVE32_TO_LITTLE(littleEndianBFH.bihsize);
ConvertToLittle(littleEndianBFH.filesize);
ConvertToLittle(littleEndianBFH.reserved);
ConvertToLittle(littleEndianBFH.dataoffset);
ConvertToLittle(littleEndianBFH.bihsize);
memcpy(mImageBufferCurr, &littleEndianBFH.signature,
sizeof(littleEndianBFH.signature));
mImageBufferCurr += sizeof(littleEndianBFH.signature);
memcpy(mImageBufferCurr, &littleEndianBFH.filesize,
sizeof(littleEndianBFH.filesize));
mImageBufferCurr += sizeof(littleEndianBFH.filesize);
memcpy(mImageBufferCurr, &littleEndianBFH.reserved,
sizeof(littleEndianBFH.reserved));
mImageBufferCurr += sizeof(littleEndianBFH.reserved);
memcpy(mImageBufferCurr, &littleEndianBFH.dataoffset,
sizeof(littleEndianBFH.dataoffset));
mImageBufferCurr += sizeof(littleEndianBFH.dataoffset);
memcpy(mImageBufferCurr, &littleEndianBFH.bihsize,
sizeof(littleEndianBFH.bihsize));
mImageBufferCurr += sizeof(littleEndianBFH.bihsize);
Encode(&mImageBufferCurr, littleEndianBFH.signature);
Encode(&mImageBufferCurr, littleEndianBFH.filesize);
Encode(&mImageBufferCurr, littleEndianBFH.reserved);
Encode(&mImageBufferCurr, littleEndianBFH.dataoffset);
Encode(&mImageBufferCurr, littleEndianBFH.bihsize);
}
// Encodes the BMP infor header mBMPInfoHeader
void
nsBMPEncoder::EncodeInfoHeader()
{
mozilla::image::BMPINFOHEADER littleEndianmBIH = mBMPInfoHeader;
littleEndianmBIH.width = NATIVE32_TO_LITTLE(littleEndianmBIH.width);
littleEndianmBIH.height = NATIVE32_TO_LITTLE(littleEndianmBIH.height);
littleEndianmBIH.planes = NATIVE16_TO_LITTLE(littleEndianmBIH.planes);
littleEndianmBIH.bpp = NATIVE16_TO_LITTLE(littleEndianmBIH.bpp);
littleEndianmBIH.compression = NATIVE32_TO_LITTLE(
littleEndianmBIH.compression);
littleEndianmBIH.image_size = NATIVE32_TO_LITTLE(
littleEndianmBIH.image_size);
littleEndianmBIH.xppm = NATIVE32_TO_LITTLE(littleEndianmBIH.xppm);
littleEndianmBIH.yppm = NATIVE32_TO_LITTLE(littleEndianmBIH.yppm);
littleEndianmBIH.colors = NATIVE32_TO_LITTLE(littleEndianmBIH.colors);
littleEndianmBIH.important_colors = NATIVE32_TO_LITTLE(
littleEndianmBIH.important_colors);
if (mBMPFileHeader.bihsize == 12) { // OS/2 Bitmap
memcpy(mImageBufferCurr, &littleEndianmBIH.width, 2);
mImageBufferCurr += 2; // Uint16 in OS/2 BMPs
memcpy(mImageBufferCurr, &littleEndianmBIH.height, 2);
mImageBufferCurr += 2; // Uint16 in OS/2 BMPs
memcpy(mImageBufferCurr, &littleEndianmBIH.planes,
sizeof(littleEndianmBIH.planes));
mImageBufferCurr += sizeof(littleEndianmBIH.planes);
memcpy(mImageBufferCurr, &littleEndianmBIH.bpp,
sizeof(littleEndianmBIH.bpp));
mImageBufferCurr += sizeof(littleEndianmBIH.bpp);
mozilla::image::BITMAPV5HEADER littleEndianmBIH = mBMPInfoHeader;
ConvertToLittle(littleEndianmBIH.width);
ConvertToLittle(littleEndianmBIH.height);
ConvertToLittle(littleEndianmBIH.planes);
ConvertToLittle(littleEndianmBIH.bpp);
ConvertToLittle(littleEndianmBIH.compression);
ConvertToLittle(littleEndianmBIH.image_size);
ConvertToLittle(littleEndianmBIH.xppm);
ConvertToLittle(littleEndianmBIH.yppm);
ConvertToLittle(littleEndianmBIH.colors);
ConvertToLittle(littleEndianmBIH.important_colors);
ConvertToLittle(littleEndianmBIH.red_mask);
ConvertToLittle(littleEndianmBIH.green_mask);
ConvertToLittle(littleEndianmBIH.blue_mask);
ConvertToLittle(littleEndianmBIH.alpha_mask);
ConvertToLittle(littleEndianmBIH.color_space);
ConvertToLittle(littleEndianmBIH.white_point.r.x);
ConvertToLittle(littleEndianmBIH.white_point.r.y);
ConvertToLittle(littleEndianmBIH.white_point.r.z);
ConvertToLittle(littleEndianmBIH.white_point.g.x);
ConvertToLittle(littleEndianmBIH.white_point.g.y);
ConvertToLittle(littleEndianmBIH.white_point.g.z);
ConvertToLittle(littleEndianmBIH.white_point.b.x);
ConvertToLittle(littleEndianmBIH.white_point.b.y);
ConvertToLittle(littleEndianmBIH.white_point.b.z);
ConvertToLittle(littleEndianmBIH.gamma_red);
ConvertToLittle(littleEndianmBIH.gamma_green);
ConvertToLittle(littleEndianmBIH.gamma_blue);
ConvertToLittle(littleEndianmBIH.intent);
ConvertToLittle(littleEndianmBIH.profile_offset);
ConvertToLittle(littleEndianmBIH.profile_size);
if (mBMPFileHeader.bihsize == OS2_BIH_LENGTH) {
Encode(&mImageBufferCurr, (PRUint16) littleEndianmBIH.width);
Encode(&mImageBufferCurr, (PRUint16) littleEndianmBIH.height);
} else {
Encode(&mImageBufferCurr, littleEndianmBIH.width);
Encode(&mImageBufferCurr, littleEndianmBIH.height);
}
else {
memcpy(mImageBufferCurr, &littleEndianmBIH.width,
sizeof(littleEndianmBIH.width));
mImageBufferCurr += sizeof(littleEndianmBIH.width);
memcpy(mImageBufferCurr, &littleEndianmBIH.height,
sizeof(littleEndianmBIH.height));
mImageBufferCurr += sizeof(littleEndianmBIH.height);
memcpy(mImageBufferCurr, &littleEndianmBIH.planes,
sizeof(littleEndianmBIH.planes));
mImageBufferCurr += sizeof(littleEndianmBIH.planes);
memcpy(mImageBufferCurr, &littleEndianmBIH.bpp,
sizeof(littleEndianmBIH.bpp));
mImageBufferCurr += sizeof(littleEndianmBIH.bpp);
memcpy(mImageBufferCurr, &littleEndianmBIH.compression,
sizeof(littleEndianmBIH.compression));
mImageBufferCurr += sizeof(littleEndianmBIH.compression);
memcpy(mImageBufferCurr, &littleEndianmBIH.image_size,
sizeof(littleEndianmBIH.image_size));
mImageBufferCurr += sizeof(littleEndianmBIH.image_size);
memcpy(mImageBufferCurr, &littleEndianmBIH.xppm,
sizeof(littleEndianmBIH.xppm));
mImageBufferCurr += sizeof(littleEndianmBIH.xppm);
memcpy(mImageBufferCurr, &littleEndianmBIH.yppm,
sizeof(littleEndianmBIH.yppm));
mImageBufferCurr += sizeof(littleEndianmBIH.yppm);
memcpy(mImageBufferCurr, &littleEndianmBIH.colors,
sizeof(littleEndianmBIH.colors));
mImageBufferCurr += sizeof(littleEndianmBIH.colors);
memcpy(mImageBufferCurr, &littleEndianmBIH.important_colors,
sizeof(littleEndianmBIH.important_colors));
mImageBufferCurr += sizeof(littleEndianmBIH.important_colors);
Encode(&mImageBufferCurr, littleEndianmBIH.planes);
Encode(&mImageBufferCurr, littleEndianmBIH.bpp);
if (mBMPFileHeader.bihsize > OS2_BIH_LENGTH) {
Encode(&mImageBufferCurr, littleEndianmBIH.compression);
Encode(&mImageBufferCurr, littleEndianmBIH.image_size);
Encode(&mImageBufferCurr, littleEndianmBIH.xppm);
Encode(&mImageBufferCurr, littleEndianmBIH.yppm);
Encode(&mImageBufferCurr, littleEndianmBIH.colors);
Encode(&mImageBufferCurr, littleEndianmBIH.important_colors);
}
if (mBMPFileHeader.bihsize > WIN_V3_BIH_LENGTH) {
Encode(&mImageBufferCurr, littleEndianmBIH.red_mask);
Encode(&mImageBufferCurr, littleEndianmBIH.green_mask);
Encode(&mImageBufferCurr, littleEndianmBIH.blue_mask);
Encode(&mImageBufferCurr, littleEndianmBIH.alpha_mask);
Encode(&mImageBufferCurr, littleEndianmBIH.color_space);
Encode(&mImageBufferCurr, littleEndianmBIH.white_point.r.x);
Encode(&mImageBufferCurr, littleEndianmBIH.white_point.r.y);
Encode(&mImageBufferCurr, littleEndianmBIH.white_point.r.z);
Encode(&mImageBufferCurr, littleEndianmBIH.white_point.g.x);
Encode(&mImageBufferCurr, littleEndianmBIH.white_point.g.y);
Encode(&mImageBufferCurr, littleEndianmBIH.white_point.g.z);
Encode(&mImageBufferCurr, littleEndianmBIH.white_point.b.x);
Encode(&mImageBufferCurr, littleEndianmBIH.white_point.b.y);
Encode(&mImageBufferCurr, littleEndianmBIH.white_point.b.z);
Encode(&mImageBufferCurr, littleEndianmBIH.gamma_red);
Encode(&mImageBufferCurr, littleEndianmBIH.gamma_green);
Encode(&mImageBufferCurr, littleEndianmBIH.gamma_blue);
Encode(&mImageBufferCurr, littleEndianmBIH.intent);
Encode(&mImageBufferCurr, littleEndianmBIH.profile_offset);
Encode(&mImageBufferCurr, littleEndianmBIH.profile_size);
Encode(&mImageBufferCurr, littleEndianmBIH.reserved);
}
}

View File

@ -34,21 +34,27 @@ public:
~nsBMPEncoder();
protected:
enum Version {
VERSION_3 = 3,
VERSION_5 = 5
};
// See InitData in the cpp for valid parse options
nsresult ParseOptions(const nsAString& aOptions, PRUint32* bpp);
nsresult ParseOptions(const nsAString& aOptions, Version* version,
PRUint32* bpp);
// Obtains data with no alpha in machine-independent byte order
void ConvertHostARGBRow(const PRUint8* aSrc, PRUint8* aDest,
PRUint32 aPixelWidth);
// Strips the alpha from aSrc and puts it in aDest
void StripAlpha(const PRUint8* aSrc, PRUint8* aDest,
PRUint32 aPixelWidth);
// Thread safe notify listener
void NotifyListener();
// Initializes the bitmap file header member mBMPFileHeader
void InitFileHeader(PRUint32 aBPP, PRUint32 aWidth, PRUint32 aHeight);
void InitFileHeader(Version aVersion, PRUint32 aBPP, PRUint32 aWidth,
PRUint32 aHeight);
// Initializes the bitmap info header member mBMPInfoHeader
void InitInfoHeader(PRUint32 aBPP, PRUint32 aWidth, PRUint32 aHeight);
void InitInfoHeader(Version aVersion, PRUint32 aBPP, PRUint32 aWidth,
PRUint32 aHeight);
// Encodes the bitmap file header member mBMPFileHeader
void EncodeFileHeader();
// Encodes the bitmap info header member mBMPInfoHeader
@ -66,7 +72,7 @@ protected:
// These headers will always contain endian independent stuff
// They store the BMP headers which will be encoded
mozilla::image::BMPFILEHEADER mBMPFileHeader;
mozilla::image::BMPINFOHEADER mBMPInfoHeader;
mozilla::image::BITMAPV5HEADER mBMPInfoHeader;
// Keeps track of the start of the image buffer
PRUint8* mImageBufferStart;

View File

@ -24,15 +24,28 @@ namespace mozilla {
#define BFH_INTERNAL_LENGTH 18
#define OS2_INTERNAL_BIH_LENGTH 8
#define WIN_INTERNAL_BIH_LENGTH 36
#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_BIH_LENGTH 40 // 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_HEADER_LENGTH (BFH_INTERNAL_LENGTH + WIN_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)
struct BMPINFOHEADER {
#define LCS_sRGB 0x73524742
struct xyz {
PRInt32 x, y, z;
};
struct xyzTriple {
xyz r, g, b;
};
struct BITMAPV5HEADER {
PRInt32 width; // Uint16 in OS/2 BMPs
PRInt32 height; // Uint16 in OS/2 BMPs
PRUint16 planes; // =1
@ -44,6 +57,21 @@ namespace mozilla {
PRUint32 yppm; // Pixels per meter, vertical
PRUint32 colors; // Used Colors
PRUint32 important_colors; // Number of important colors. 0=all
PRUint32 red_mask; // Bits used for red component
PRUint32 green_mask; // Bits used for green component
PRUint32 blue_mask; // Bits used for blue component
PRUint32 alpha_mask; // Bits used for alpha component
PRUint32 color_space; // 0x73524742=LCS_sRGB ...
// These members are unused unless color_space == LCS_CALIBRATED_RGB
xyzTriple white_point; // Logical white point
PRUint32 gamma_red; // Red gamma component
PRUint32 gamma_green; // Green gamma component
PRUint32 gamma_blue; // Blue gamma component
PRUint32 intent; // Rendering intent
// These members are unused unless color_space == LCS_PROFILE_*
PRUint32 profile_offset; // Offset to profile data in bytes
PRUint32 profile_size; // Size of profile data in bytes
PRUint32 reserved; // =0
};
struct colorTable {