Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(998)

Unified Diff: Source/platform/image-decoders/bmp/BMPImageReader.cpp

Issue 279433002: BMP-in-ICO should respect alpha in Windows V3 32bpp RGB bitmaps. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: Source/platform/image-decoders/bmp/BMPImageReader.cpp
diff --git a/Source/platform/image-decoders/bmp/BMPImageReader.cpp b/Source/platform/image-decoders/bmp/BMPImageReader.cpp
index 5463802947861377c44c116d9f1ec5b95e3f49c2..c2186fd8c72ce0e75baa04b6737e0303cce71c79 100644
--- a/Source/platform/image-decoders/bmp/BMPImageReader.cpp
+++ b/Source/platform/image-decoders/bmp/BMPImageReader.cpp
@@ -66,7 +66,7 @@ const uint8_t nBitTo8BitlookupTable[] = {
namespace WebCore {
-BMPImageReader::BMPImageReader(ImageDecoder* parent, size_t decodedAndHeaderOffset, size_t imgDataOffset, bool usesAndMask)
+BMPImageReader::BMPImageReader(ImageDecoder* parent, size_t decodedAndHeaderOffset, size_t imgDataOffset, bool isInICO)
: m_parent(parent)
, m_buffer(0)
, m_decodedOffset(decodedAndHeaderOffset)
@@ -79,7 +79,8 @@ BMPImageReader::BMPImageReader(ImageDecoder* parent, size_t decodedAndHeaderOffs
, m_needToProcessColorTable(false)
, m_seenNonZeroAlphaPixel(false)
, m_seenZeroAlphaPixel(false)
- , m_andMaskState(usesAndMask ? NotYetDecoded : None)
+ , m_isInICO(isInICO)
+ , m_decodingAndMask(false)
{
// Clue-in decodeBMP() that we need to detect the correct info header size.
memset(&m_infoHeader, 0, sizeof(m_infoHeader));
@@ -126,7 +127,7 @@ bool BMPImageReader::decodeBMP(bool onlySize)
}
// Decode the data.
- if ((m_andMaskState != Decoding) && !pastEndOfImage(0)) {
+ if (!m_decodingAndMask && !pastEndOfImage(0)) {
if ((m_infoHeader.biCompression != RLE4) && (m_infoHeader.biCompression != RLE8) && (m_infoHeader.biCompression != RLE24)) {
const ProcessingResult result = processNonRLEData(false, 0);
if (result != Success)
@@ -137,7 +138,7 @@ bool BMPImageReader::decodeBMP(bool onlySize)
// If the image has an AND mask and there was no alpha data, process the
// mask.
- if ((m_andMaskState == NotYetDecoded) && !m_buffer->hasAlpha()) {
+ if (m_isInICO && !m_decodingAndMask && !m_buffer->hasAlpha()) {
// Reset decoding coordinates to start of image.
m_coord.setX(0);
m_coord.setY(m_isTopDown ? 0 : (m_parent->size().height() - 1));
@@ -145,9 +146,9 @@ bool BMPImageReader::decodeBMP(bool onlySize)
// The AND mask is stored as 1-bit data.
m_infoHeader.biBitCount = 1;
- m_andMaskState = Decoding;
+ m_decodingAndMask = true;
}
- if (m_andMaskState == Decoding) {
+ if (m_decodingAndMask) {
const ProcessingResult result = processNonRLEData(false, 0);
if (result != Success)
return (result == Failure) ? m_parent->setFailed() : false;
@@ -241,14 +242,14 @@ bool BMPImageReader::readInfoHeader()
if (m_isOS21x) {
m_infoHeader.biWidth = readUint16(4);
m_infoHeader.biHeight = readUint16(6);
- ASSERT(m_andMaskState == None); // ICO is a Windows format, not OS/2!
+ ASSERT(!m_isInICO); // ICO is a Windows format, not OS/2!
m_infoHeader.biBitCount = readUint16(10);
return true;
}
m_infoHeader.biWidth = readUint32(4);
m_infoHeader.biHeight = readUint32(8);
- if (m_andMaskState != None)
+ if (m_isInICO)
m_infoHeader.biHeight /= 2;
m_infoHeader.biBitCount = readUint16(14);
@@ -440,7 +441,8 @@ bool BMPImageReader::processBitmasks()
//
// To complicate things, Windows V3 BMPs, which lack this mask, can specify
// 32bpp format, which to any sane reader would imply an 8-bit alpha
- // channel -- and indeed, there exist BMPs in this format which clearly
+ // channel -- and for BMPs-in-ICOs, that's precisely what's intended to
+ // happen. There also exist standalone BMPs in this format which clearly
// expect the alpha channel to be respected. However, there are many other
// BMPs which, for example, fill this channel with all 0s, yet clearly
// expect to not be displayed as a fully-transparent rectangle.
@@ -460,9 +462,10 @@ bool BMPImageReader::processBitmasks()
//
// So it's impossible to display every BMP in the way its creators intended,
// and we have to choose what to break. Given the paragraph above, we match
- // other browsers and ignore alpha in Windows V3 BMPs.
+ // other browsers and ignore alpha in Windows V3 BMPs except inside ICO
+ // files.
if (!isWindowsV4Plus())
- m_bitMasks[3] = 0;
+ m_bitMasks[3] = (m_isInICO && (m_infoHeader.biCompression != BITFIELDS) && (m_infoHeader.biBitCount == 32)) ? static_cast<uint32_t>(0xff000000) : 0;
// We've now decoded all the non-image data we care about. Skip anything
// else before the actual raster data.
@@ -726,7 +729,7 @@ BMPImageReader::ProcessingResult BMPImageReader::processNonRLEData(bool inRLE, i
uint8_t pixelData = m_data->data()[m_decodedOffset + byte];
for (size_t pixel = 0; (pixel < pixelsPerByte) && (m_coord.x() < endX); ++pixel) {
const size_t colorIndex = (pixelData >> (8 - m_infoHeader.biBitCount)) & mask;
- if (m_andMaskState == Decoding) {
+ if (m_decodingAndMask) {
// There's no way to accurately represent an AND + XOR
// operation as an RGBA image, so where the AND values
// are 1, we simply set the framebuffer pixels to fully

Powered by Google App Engine
This is Rietveld 408576698