// A BMP inside of an ICO has *2 height because of the AND mask // that follows the actual bitmap. The BMP shouldn't know about // this difference though. bool nsICODecoder::FixBitmapHeight(PRInt8 *bih) { // Get the height from the BMP file information header PRInt32 height; memcpy(&height, bih + 8, sizeof(height)); height = LITTLE_TO_NATIVE32(height); // The bitmap height is by definition * 2 what it should be to account for // the 'AND mask'. It is * 2 even if the `AND mask` is not present. height /= 2; if (height > 256) { return false; } // We should always trust the height from the bitmap itself instead of // the ICO height. So fix the ICO height. if (height == 256) { mDirEntry.mHeight = 0; } else { mDirEntry.mHeight = (PRInt8)height; } // Fix the BMP height in the BIH so that the BMP decoder can work properly height = NATIVE32_TO_LITTLE(height); memcpy(bih + 8, &height, sizeof(height)); return true; }
PRInt32 nsICODecoder::ExtractBIHSizeFromBitmap(PRInt8 *bih) { PRInt32 headerSize; memcpy(&headerSize, bih, sizeof(headerSize)); headerSize = LITTLE_TO_NATIVE32(headerSize); return headerSize; }
// The BMP information header's bits per pixel should be trusted // more than what we have. Usually the ICO's BPP is set to 0 PRInt32 nsICODecoder::ExtractBPPFromBitmap(PRInt8 *bih) { PRInt32 bitsPerPixel; memcpy(&bitsPerPixel, bih + 14, sizeof(bitsPerPixel)); bitsPerPixel = LITTLE_TO_NATIVE32(bitsPerPixel); return bitsPerPixel; }
int32_t nsICODecoder::ExtractBIHSizeFromBitmap(int8_t *bih) { int32_t headerSize; memcpy(&headerSize, bih, sizeof(headerSize)); headerSize = LITTLE_TO_NATIVE32(headerSize); return headerSize; }
// We should always trust the contained resource for the width // information over our own information. bool nsICODecoder::FixBitmapWidth(PRInt8 *bih) { // Get the width from the BMP file information header PRInt32 width; memcpy(&width, bih + 4, sizeof(width)); width = LITTLE_TO_NATIVE32(width); if (width > 256) { return false; } // We should always trust the width from the bitmap itself instead of // the ICO width. if (width == 256) { mDirEntry.mWidth = 0; } else { mDirEntry.mWidth = (PRInt8)width; } return true; }