diff options
Diffstat (limited to 'WebCore/platform/image-decoders')
13 files changed, 60 insertions, 30 deletions
diff --git a/WebCore/platform/image-decoders/ImageDecoder.cpp b/WebCore/platform/image-decoders/ImageDecoder.cpp index 1946596..d4518fe 100644 --- a/WebCore/platform/image-decoders/ImageDecoder.cpp +++ b/WebCore/platform/image-decoders/ImageDecoder.cpp @@ -52,11 +52,15 @@ static unsigned copyFromSharedBuffer(char* buffer, unsigned bufferLength, const return bytesExtracted; } +<<<<<<< HEAD #if !OS(ANDROID) // This method requires BMPImageDecoder, PNGImageDecoder, ICOImageDecoder and // JPEGDecoder, which aren't used on Android, and which don't all compile. // TODO: Find a better fix. ImageDecoder* ImageDecoder::create(const SharedBuffer& data) +======= +ImageDecoder* ImageDecoder::create(const SharedBuffer& data, bool premultiplyAlpha) +>>>>>>> webkit.org at r66079 { // We need at least 4 bytes to figure out what kind of image we're dealing // with. @@ -68,24 +72,24 @@ ImageDecoder* ImageDecoder::create(const SharedBuffer& data) // GIFs begin with GIF8(7 or 9). if (strncmp(contents, "GIF8", 4) == 0) - return new GIFImageDecoder(); + return new GIFImageDecoder(premultiplyAlpha); // Test for PNG. if (!memcmp(contents, "\x89\x50\x4E\x47", 4)) - return new PNGImageDecoder(); + return new PNGImageDecoder(premultiplyAlpha); // JPEG if (!memcmp(contents, "\xFF\xD8\xFF", 3)) - return new JPEGImageDecoder(); + return new JPEGImageDecoder(premultiplyAlpha); // BMP if (strncmp(contents, "BM", 2) == 0) - return new BMPImageDecoder(); + return new BMPImageDecoder(premultiplyAlpha); // ICOs always begin with a 2-byte 0 followed by a 2-byte 1. // CURs begin with 2-byte 0 followed by 2-byte 2. if (!memcmp(contents, "\x00\x00\x01\x00", 4) || !memcmp(contents, "\x00\x00\x02\x00", 4)) - return new ICOImageDecoder(); + return new ICOImageDecoder(premultiplyAlpha); // Give up. We don't know what the heck this is. return 0; @@ -99,6 +103,7 @@ RGBA32Buffer::RGBA32Buffer() , m_status(FrameEmpty) , m_duration(0) , m_disposalMethod(DisposeNotSpecified) + , m_premultiplyAlpha(true) { } @@ -112,6 +117,7 @@ RGBA32Buffer& RGBA32Buffer::operator=(const RGBA32Buffer& other) setStatus(other.status()); setDuration(other.duration()); setDisposalMethod(other.disposalMethod()); + setPremultiplyAlpha(other.premultiplyAlpha()); return *this; } diff --git a/WebCore/platform/image-decoders/ImageDecoder.h b/WebCore/platform/image-decoders/ImageDecoder.h index f32536c..4012168 100644 --- a/WebCore/platform/image-decoders/ImageDecoder.h +++ b/WebCore/platform/image-decoders/ImageDecoder.h @@ -124,12 +124,14 @@ namespace WebCore { FrameStatus status() const { return m_status; } unsigned duration() const { return m_duration; } FrameDisposalMethod disposalMethod() const { return m_disposalMethod; } + bool premultiplyAlpha() const { return m_premultiplyAlpha; } void setHasAlpha(bool alpha); void setRect(const IntRect& r) { m_rect = r; } void setStatus(FrameStatus status); void setDuration(unsigned duration) { m_duration = duration; } void setDisposalMethod(FrameDisposalMethod method) { m_disposalMethod = method; } + void setPremultiplyAlpha(bool premultiplyAlpha) { m_premultiplyAlpha = premultiplyAlpha; } inline void setRGBA(int x, int y, unsigned r, unsigned g, unsigned b, unsigned a) { @@ -151,7 +153,7 @@ namespace WebCore { #elif PLATFORM(QT) m_image = m_pixmap.toImage(); m_pixmap = QPixmap(); - return reinterpret_cast<QRgb*>(m_image.scanLine(y)) + x; + return reinterpret_cast_ptr<QRgb*>(m_image.scanLine(y)) + x; #else return m_bytes.data() + (y * width()) + x; #endif @@ -159,11 +161,10 @@ namespace WebCore { inline void setRGBA(PixelData* dest, unsigned r, unsigned g, unsigned b, unsigned a) { - // We store this data pre-multiplied. - if (a == 0) + if (m_premultiplyAlpha && !a) *dest = 0; else { - if (a < 255) { + if (m_premultiplyAlpha && a < 255) { float alphaPercent = a / 255.0f; r = static_cast<unsigned>(r * alphaPercent); g = static_cast<unsigned>(g * alphaPercent); @@ -202,6 +203,9 @@ namespace WebCore { FrameDisposalMethod m_disposalMethod; // What to do with this frame's data when // initializing the next frame. + bool m_premultiplyAlpha; + // Whether to premultiply alpha into R, G, B + // channels; by default it's true. }; // The ImageDecoder class represents a base class for specific image format @@ -215,8 +219,9 @@ namespace WebCore { // m_maxNumPixels. (Not supported by all image decoders yet) class ImageDecoder : public Noncopyable { public: - ImageDecoder() + ImageDecoder(bool premultiplyAlpha) : m_scaled(false) + , m_premultiplyAlpha(premultiplyAlpha) , m_sizeAvailable(false) , m_maxNumPixels(-1) , m_isAllDataReceived(false) @@ -229,7 +234,7 @@ namespace WebCore { // Factory function to create an ImageDecoder. Ports that subclass // ImageDecoder can provide their own implementation of this to avoid // needing to write a dedicated setData() implementation. - static ImageDecoder* create(const SharedBuffer& data); + static ImageDecoder* create(const SharedBuffer& data, bool premultiplyAlpha); // The the filename extension usually associated with an undecoded image // of this type. @@ -343,6 +348,7 @@ namespace WebCore { bool m_scaled; Vector<int> m_scaledColumns; Vector<int> m_scaledRows; + bool m_premultiplyAlpha; private: // Some code paths compute the size of the image as "width * height * 4" diff --git a/WebCore/platform/image-decoders/bmp/BMPImageDecoder.cpp b/WebCore/platform/image-decoders/bmp/BMPImageDecoder.cpp index 901f60d..1c117a8 100644 --- a/WebCore/platform/image-decoders/bmp/BMPImageDecoder.cpp +++ b/WebCore/platform/image-decoders/bmp/BMPImageDecoder.cpp @@ -40,8 +40,9 @@ namespace WebCore { // don't pack). static const size_t sizeOfFileHeader = 14; -BMPImageDecoder::BMPImageDecoder() - : m_decodedOffset(0) +BMPImageDecoder::BMPImageDecoder(bool premultiplyAlpha) + : ImageDecoder(premultiplyAlpha) + , m_decodedOffset(0) { } @@ -68,8 +69,10 @@ RGBA32Buffer* BMPImageDecoder::frameBufferAtIndex(size_t index) if (index) return 0; - if (m_frameBufferCache.isEmpty()) + if (m_frameBufferCache.isEmpty()) { m_frameBufferCache.resize(1); + m_frameBufferCache.first().setPremultiplyAlpha(m_premultiplyAlpha); + } RGBA32Buffer* buffer = &m_frameBufferCache.first(); if (buffer->status() != RGBA32Buffer::FrameComplete) diff --git a/WebCore/platform/image-decoders/bmp/BMPImageDecoder.h b/WebCore/platform/image-decoders/bmp/BMPImageDecoder.h index b08b32b..3996bf9 100644 --- a/WebCore/platform/image-decoders/bmp/BMPImageDecoder.h +++ b/WebCore/platform/image-decoders/bmp/BMPImageDecoder.h @@ -39,7 +39,7 @@ namespace WebCore { // This class decodes the BMP image format. class BMPImageDecoder : public ImageDecoder { public: - BMPImageDecoder(); + BMPImageDecoder(bool premultiplyAlpha); // ImageDecoder virtual String filenameExtension() const { return "bmp"; } diff --git a/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp b/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp index ec16da7..a2397ee 100644 --- a/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp +++ b/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp @@ -29,8 +29,9 @@ namespace WebCore { -GIFImageDecoder::GIFImageDecoder() - : m_alreadyScannedThisDataForFrameCount(true) +GIFImageDecoder::GIFImageDecoder(bool premultiplyAlpha) + : ImageDecoder(premultiplyAlpha) + , m_alreadyScannedThisDataForFrameCount(true) , m_repetitionCount(cAnimationLoopOnce) , m_readOffset(0) { @@ -83,6 +84,8 @@ size_t GIFImageDecoder::frameCount() reader.read((const unsigned char*)m_data->data(), m_data->size(), GIFFrameCountQuery, static_cast<unsigned>(-1)); m_alreadyScannedThisDataForFrameCount = true; m_frameBufferCache.resize(reader.images_count); + for (int i = 0; i < reader.images_count; ++i) + m_frameBufferCache[i].setPremultiplyAlpha(m_premultiplyAlpha); } return m_frameBufferCache.size(); diff --git a/WebCore/platform/image-decoders/gif/GIFImageDecoder.h b/WebCore/platform/image-decoders/gif/GIFImageDecoder.h index e0f8173..21c1c57 100644 --- a/WebCore/platform/image-decoders/gif/GIFImageDecoder.h +++ b/WebCore/platform/image-decoders/gif/GIFImageDecoder.h @@ -36,7 +36,7 @@ namespace WebCore { // This class decodes the GIF image format. class GIFImageDecoder : public ImageDecoder { public: - GIFImageDecoder(); + GIFImageDecoder(bool premultiplyAlpha); virtual ~GIFImageDecoder(); enum GIFQuery { GIFFullQuery, GIFSizeQuery, GIFFrameCountQuery }; diff --git a/WebCore/platform/image-decoders/ico/ICOImageDecoder.cpp b/WebCore/platform/image-decoders/ico/ICOImageDecoder.cpp index d667795..453efd2 100644 --- a/WebCore/platform/image-decoders/ico/ICOImageDecoder.cpp +++ b/WebCore/platform/image-decoders/ico/ICOImageDecoder.cpp @@ -44,8 +44,9 @@ namespace WebCore { static const size_t sizeOfDirectory = 6; static const size_t sizeOfDirEntry = 16; -ICOImageDecoder::ICOImageDecoder() - : m_decodedOffset(0) +ICOImageDecoder::ICOImageDecoder(bool premultiplyAlpha) + : ImageDecoder(premultiplyAlpha) + , m_decodedOffset(0) { } @@ -96,8 +97,11 @@ bool ICOImageDecoder::setSize(unsigned width, unsigned height) size_t ICOImageDecoder::frameCount() { decode(0, true); - if (m_frameBufferCache.isEmpty()) + if (m_frameBufferCache.isEmpty()) { m_frameBufferCache.resize(m_dirEntries.size()); + for (size_t i = 0; i < m_dirEntries.size(); ++i) + m_frameBufferCache[i].setPremultiplyAlpha(m_premultiplyAlpha); + } // CAUTION: We must not resize m_frameBufferCache again after this, as // decodeAtIndex() may give a BMPImageReader a pointer to one of the // entries. @@ -197,7 +201,7 @@ bool ICOImageDecoder::decodeAtIndex(size_t index) } if (!m_pngDecoders[index]) { - m_pngDecoders[index].set(new PNGImageDecoder()); + m_pngDecoders[index].set(new PNGImageDecoder(m_premultiplyAlpha)); setDataForPNGDecoderAtIndex(index); } // Fail if the size the PNGImageDecoder calculated does not match the size diff --git a/WebCore/platform/image-decoders/ico/ICOImageDecoder.h b/WebCore/platform/image-decoders/ico/ICOImageDecoder.h index 48024a2..e2ee9e3 100644 --- a/WebCore/platform/image-decoders/ico/ICOImageDecoder.h +++ b/WebCore/platform/image-decoders/ico/ICOImageDecoder.h @@ -40,7 +40,7 @@ namespace WebCore { // This class decodes the ICO and CUR image formats. class ICOImageDecoder : public ImageDecoder { public: - ICOImageDecoder(); + ICOImageDecoder(bool premultiplyAlpha); virtual ~ICOImageDecoder(); // ImageDecoder diff --git a/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp b/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp index 4911bc9..6c6c782 100644 --- a/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp +++ b/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp @@ -361,7 +361,8 @@ void term_source(j_decompress_ptr jd) src->decoder->decoder()->jpegComplete(); } -JPEGImageDecoder::JPEGImageDecoder() +JPEGImageDecoder::JPEGImageDecoder(bool premultiplyAlpha) + : ImageDecoder(premultiplyAlpha) { } @@ -391,8 +392,10 @@ RGBA32Buffer* JPEGImageDecoder::frameBufferAtIndex(size_t index) if (index) return 0; - if (m_frameBufferCache.isEmpty()) + if (m_frameBufferCache.isEmpty()) { m_frameBufferCache.resize(1); + m_frameBufferCache[0].setPremultiplyAlpha(m_premultiplyAlpha); + } RGBA32Buffer& frame = m_frameBufferCache[0]; if (frame.status() != RGBA32Buffer::FrameComplete) diff --git a/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h b/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h index 43b35fd..5047019 100644 --- a/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h +++ b/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h @@ -37,7 +37,7 @@ namespace WebCore { // This class decodes the JPEG image format. class JPEGImageDecoder : public ImageDecoder { public: - JPEGImageDecoder(); + JPEGImageDecoder(bool premultiplyAlpha); virtual ~JPEGImageDecoder(); // ImageDecoder diff --git a/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp b/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp index 8186f33..940e4c4 100644 --- a/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp +++ b/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp @@ -169,8 +169,9 @@ private: unsigned m_currentBufferSize; }; -PNGImageDecoder::PNGImageDecoder() - : m_doNothingOnFailure(false) +PNGImageDecoder::PNGImageDecoder(bool premultiplyAlpha) + : ImageDecoder(premultiplyAlpha) + , m_doNothingOnFailure(false) { } @@ -200,8 +201,10 @@ RGBA32Buffer* PNGImageDecoder::frameBufferAtIndex(size_t index) if (index) return 0; - if (m_frameBufferCache.isEmpty()) + if (m_frameBufferCache.isEmpty()) { m_frameBufferCache.resize(1); + m_frameBufferCache[0].setPremultiplyAlpha(m_premultiplyAlpha); + } RGBA32Buffer& frame = m_frameBufferCache[0]; if (frame.status() != RGBA32Buffer::FrameComplete) diff --git a/WebCore/platform/image-decoders/png/PNGImageDecoder.h b/WebCore/platform/image-decoders/png/PNGImageDecoder.h index 145fc4d..763b88f 100644 --- a/WebCore/platform/image-decoders/png/PNGImageDecoder.h +++ b/WebCore/platform/image-decoders/png/PNGImageDecoder.h @@ -36,7 +36,7 @@ namespace WebCore { // This class decodes the PNG image format. class PNGImageDecoder : public ImageDecoder { public: - PNGImageDecoder(); + PNGImageDecoder(bool premultiplyAlpha); virtual ~PNGImageDecoder(); // ImageDecoder diff --git a/WebCore/platform/image-decoders/skia/ImageDecoderSkia.cpp b/WebCore/platform/image-decoders/skia/ImageDecoderSkia.cpp index 928524a..c7e2114 100644 --- a/WebCore/platform/image-decoders/skia/ImageDecoderSkia.cpp +++ b/WebCore/platform/image-decoders/skia/ImageDecoderSkia.cpp @@ -36,6 +36,7 @@ RGBA32Buffer::RGBA32Buffer() : m_status(FrameEmpty) , m_duration(0) , m_disposalMethod(DisposeNotSpecified) + , m_premultiplyAlpha(true) { } @@ -52,6 +53,7 @@ RGBA32Buffer& RGBA32Buffer::operator=(const RGBA32Buffer& other) setStatus(other.status()); setDuration(other.duration()); setDisposalMethod(other.disposalMethod()); + setPremultiplyAlpha(other.premultiplyAlpha()); return *this; } |