diff options
author | Steve Block <steveblock@google.com> | 2010-04-27 16:31:00 +0100 |
---|---|---|
committer | Steve Block <steveblock@google.com> | 2010-05-11 14:42:12 +0100 |
commit | dcc8cf2e65d1aa555cce12431a16547e66b469ee (patch) | |
tree | 92a8d65cd5383bca9749f5327fb5e440563926e6 /WebCore/platform/image-decoders | |
parent | ccac38a6b48843126402088a309597e682f40fe6 (diff) | |
download | external_webkit-dcc8cf2e65d1aa555cce12431a16547e66b469ee.zip external_webkit-dcc8cf2e65d1aa555cce12431a16547e66b469ee.tar.gz external_webkit-dcc8cf2e65d1aa555cce12431a16547e66b469ee.tar.bz2 |
Merge webkit.org at r58033 : Initial merge by git
Change-Id: If006c38561af287c50cd578d251629b51e4d8cd1
Diffstat (limited to 'WebCore/platform/image-decoders')
10 files changed, 110 insertions, 145 deletions
diff --git a/WebCore/platform/image-decoders/ImageDecoder.h b/WebCore/platform/image-decoders/ImageDecoder.h index 002395b..b063db2 100644 --- a/WebCore/platform/image-decoders/ImageDecoder.h +++ b/WebCore/platform/image-decoders/ImageDecoder.h @@ -214,10 +214,10 @@ namespace WebCore { public: ImageDecoder() : m_scaled(false) - , m_failed(false) , m_sizeAvailable(false) - , m_isAllDataReceived(false) , m_maxNumPixels(-1) + , m_isAllDataReceived(false) + , m_failed(false) { } @@ -236,6 +236,8 @@ namespace WebCore { virtual void setData(SharedBuffer* data, bool allDataReceived) { + if (failed()) + return; m_data = data; m_isAllDataReceived = allDataReceived; } @@ -277,10 +279,8 @@ namespace WebCore { // be set and the caller should immediately stop decoding. virtual bool setSize(unsigned width, unsigned height) { - if (isOverSize(width, height)) { - m_failed = true; - return false; - } + if (isOverSize(width, height)) + return setFailed(); m_size = IntSize(width, height); m_sizeAvailable = true; return true; @@ -303,8 +303,16 @@ namespace WebCore { // transparency. virtual bool supportsAlpha() const { return true; } + // Sets the "decode failure" flag. For caller convenience (since so + // many callers want to return false after calling this), returns false + // to enable easy tailcalling. + virtual bool setFailed() + { + m_failed = true; + return false; + } + bool failed() const { return m_failed; } - void setFailed() { m_failed = true; } // Wipe out frames in the frame buffer cache before |clearBeforeFrame|, // assuming this can be done without breaking decoding. Different @@ -327,11 +335,10 @@ namespace WebCore { int scaledY(int origY, int searchStart = 0); RefPtr<SharedBuffer> m_data; // The encoded data. + Vector<RGBA32Buffer> m_frameBufferCache; + bool m_scaled; Vector<int> m_scaledColumns; Vector<int> m_scaledRows; - bool m_scaled; - Vector<RGBA32Buffer> m_frameBufferCache; - bool m_failed; private: // Some code paths compute the size of the image as "width * height * 4" @@ -347,8 +354,9 @@ namespace WebCore { IntSize m_size; bool m_sizeAvailable; - bool m_isAllDataReceived; int m_maxNumPixels; + bool m_isAllDataReceived; + bool m_failed; }; } // namespace WebCore diff --git a/WebCore/platform/image-decoders/bmp/BMPImageDecoder.cpp b/WebCore/platform/image-decoders/bmp/BMPImageDecoder.cpp index fb9f9f2..a6d36ef 100644 --- a/WebCore/platform/image-decoders/bmp/BMPImageDecoder.cpp +++ b/WebCore/platform/image-decoders/bmp/BMPImageDecoder.cpp @@ -57,7 +57,7 @@ void BMPImageDecoder::setData(SharedBuffer* data, bool allDataReceived) bool BMPImageDecoder::isSizeAvailable() { - if (!ImageDecoder::isSizeAvailable() && !failed()) + if (!ImageDecoder::isSizeAvailable()) decode(true); return ImageDecoder::isSizeAvailable(); @@ -72,7 +72,7 @@ RGBA32Buffer* BMPImageDecoder::frameBufferAtIndex(size_t index) m_frameBufferCache.resize(1); RGBA32Buffer* buffer = &m_frameBufferCache.first(); - if (buffer->status() != RGBA32Buffer::FrameComplete && !failed()) + if (buffer->status() != RGBA32Buffer::FrameComplete) decode(false); return buffer; } @@ -131,12 +131,7 @@ bool BMPImageDecoder::processFileHeader(size_t* imgDataOffset) BITMAPARRAY = 0x4241, // "BA" */ }; - if (fileType != BMAP) { - setFailed(); - return false; - } - - return true; + return (fileType == BMAP) || setFailed(); } } // namespace WebCore diff --git a/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp b/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp index 807d57c..5965ae4 100644 --- a/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp +++ b/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp @@ -42,26 +42,32 @@ GIFImageDecoder::~GIFImageDecoder() void GIFImageDecoder::setData(SharedBuffer* data, bool allDataReceived) { - if (m_failed) + if (failed()) return; ImageDecoder::setData(data, allDataReceived); // We need to rescan the frame count, as the new data may have changed it. m_alreadyScannedThisDataForFrameCount = false; - - if (!m_reader && !m_failed) - m_reader.set(new GIFImageReader(this)); } bool GIFImageDecoder::isSizeAvailable() { - if (!ImageDecoder::isSizeAvailable() && !failed() && m_reader) + if (!ImageDecoder::isSizeAvailable()) decode(0, GIFSizeQuery); return ImageDecoder::isSizeAvailable(); } +bool GIFImageDecoder::setSize(unsigned width, unsigned height) +{ + if (!ImageDecoder::setSize(width, height)) + return false; + + prepareScaleDataIfNecessary(); + return true; +} + size_t GIFImageDecoder::frameCount() { if (!m_alreadyScannedThisDataForFrameCount) { @@ -108,8 +114,8 @@ RGBA32Buffer* GIFImageDecoder::frameBufferAtIndex(size_t index) return 0; RGBA32Buffer& frame = m_frameBufferCache[index]; - if (frame.status() != RGBA32Buffer::FrameComplete && m_reader) - decode(index + 1, GIFFullQuery); // Decode this frame. + if (frame.status() != RGBA32Buffer::FrameComplete) + decode(index + 1, GIFFullQuery); return &frame; } @@ -163,15 +169,6 @@ void GIFImageDecoder::clearFrameBufferCache(size_t clearBeforeFrame) } } -bool GIFImageDecoder::sizeNowAvailable(unsigned width, unsigned height) -{ - if (!setSize(width, height)) - return false; - - prepareScaleDataIfNecessary(); - return true; -} - void GIFImageDecoder::decodingHalted(unsigned bytesLeft) { m_readOffset = m_data->size() - bytesLeft; @@ -291,12 +288,16 @@ void GIFImageDecoder::gifComplete() void GIFImageDecoder::decode(unsigned haltAtFrame, GIFQuery query) { - if (m_failed) + if (failed()) return; - m_failed = !m_reader->read((const unsigned char*)m_data->data() + m_readOffset, m_data->size() - m_readOffset, query, haltAtFrame); + if (!m_reader) + m_reader.set(new GIFImageReader(this)); + + if (!m_reader->read((const unsigned char*)m_data->data() + m_readOffset, m_data->size() - m_readOffset, query, haltAtFrame)) + setFailed(); - if (m_failed) + if (failed()) m_reader.clear(); } @@ -321,10 +322,8 @@ bool GIFImageDecoder::initFrameBuffer(unsigned frameIndex) if (!frameIndex) { // This is the first frame, so we're not relying on any previous data. - if (!buffer->setSize(scaledSize().width(), scaledSize().height())) { - m_failed = true; - return false; - } + if (!buffer->setSize(scaledSize().width(), scaledSize().height())) + return setFailed(); } else { // The starting state for this frame depends on the previous frame's // disposal method. @@ -353,10 +352,8 @@ bool GIFImageDecoder::initFrameBuffer(unsigned frameIndex) if (!frameIndex || prevRect.contains(IntRect(IntPoint(), scaledSize()))) { // Clearing the first frame, or a frame the size of the whole // image, results in a completely empty image. - if (!buffer->setSize(bufferSize.width(), bufferSize.height())) { - m_failed = true; - return false; - } + if (!buffer->setSize(bufferSize.width(), bufferSize.height())) + return setFailed(); } else { // Copy the whole previous buffer, then clear just its frame. buffer->copyBitmapData(*prevBuffer); diff --git a/WebCore/platform/image-decoders/gif/GIFImageDecoder.h b/WebCore/platform/image-decoders/gif/GIFImageDecoder.h index 0aa5387..28a9a59 100644 --- a/WebCore/platform/image-decoders/gif/GIFImageDecoder.h +++ b/WebCore/platform/image-decoders/gif/GIFImageDecoder.h @@ -45,13 +45,13 @@ namespace WebCore { virtual String filenameExtension() const { return "gif"; } virtual void setData(SharedBuffer* data, bool allDataReceived); virtual bool isSizeAvailable(); + virtual bool setSize(unsigned width, unsigned height); virtual size_t frameCount(); virtual int repetitionCount() const; virtual RGBA32Buffer* frameBufferAtIndex(size_t index); virtual void clearFrameBufferCache(size_t clearBeforeFrame); // Callbacks from the GIF reader. - bool sizeNowAvailable(unsigned width, unsigned height); void decodingHalted(unsigned bytesLeft); bool haveDecodedRow(unsigned frameIndex, unsigned char* rowBuffer, unsigned char* rowEnd, unsigned rowNumber, unsigned repeatCount, bool writeTransparentPixels); void frameComplete(unsigned frameIndex, unsigned frameDuration, RGBA32Buffer::FrameDisposalMethod disposalMethod); diff --git a/WebCore/platform/image-decoders/gif/GIFImageReader.cpp b/WebCore/platform/image-decoders/gif/GIFImageReader.cpp index 755a48d..677853e 100644 --- a/WebCore/platform/image-decoders/gif/GIFImageReader.cpp +++ b/WebCore/platform/image-decoders/gif/GIFImageReader.cpp @@ -519,7 +519,7 @@ bool GIFImageReader::read(const unsigned char *buf, unsigned len, screen_height = GETINT16(q + 2); // CALLBACK: Inform the decoderplugin of our size. - if (clientptr && !clientptr->sizeNowAvailable(screen_width, screen_height)) + if (clientptr && !clientptr->setSize(screen_width, screen_height)) return false; screen_bgcolor = q[5]; @@ -746,7 +746,7 @@ bool GIFImageReader::read(const unsigned char *buf, unsigned len, y_offset = 0; // CALLBACK: Inform the decoderplugin of our size. - if (clientptr && !clientptr->sizeNowAvailable(screen_width, screen_height)) + if (clientptr && !clientptr->setSize(screen_width, screen_height)) return false; } diff --git a/WebCore/platform/image-decoders/ico/ICOImageDecoder.cpp b/WebCore/platform/image-decoders/ico/ICOImageDecoder.cpp index 1a202bc..325c506 100644 --- a/WebCore/platform/image-decoders/ico/ICOImageDecoder.cpp +++ b/WebCore/platform/image-decoders/ico/ICOImageDecoder.cpp @@ -88,14 +88,9 @@ IntSize ICOImageDecoder::frameSizeAtIndex(size_t index) const bool ICOImageDecoder::setSize(unsigned width, unsigned height) { - if (m_frameSize.isEmpty()) - return ImageDecoder::setSize(width, height); - // The size calculated inside the BMPImageReader had better match the one in // the icon directory. - if (IntSize(width, height) != m_frameSize) - setFailed(); - return !failed(); + return m_frameSize.isEmpty() ? ImageDecoder::setSize(width, height) : ((IntSize(width, height) == m_frameSize) || setFailed()); } size_t ICOImageDecoder::frameCount() @@ -193,15 +188,10 @@ bool ICOImageDecoder::decodeAtIndex(size_t index) } // Fail if the size the PNGImageDecoder calculated does not match the size // in the directory. - if (m_pngDecoders[index]->isSizeAvailable() && (m_pngDecoders[index]->size() != dirEntry.m_size)) { - setFailed(); - return false; - } + if (m_pngDecoders[index]->isSizeAvailable() && (m_pngDecoders[index]->size() != dirEntry.m_size)) + return setFailed(); m_frameBufferCache[index] = *m_pngDecoders[index]->frameBufferAtIndex(0); - if (!m_pngDecoders[index]->failed()) - return true; - setFailed(); - return false; + return !m_pngDecoders[index]->failed() || setFailed(); } bool ICOImageDecoder::processDirectory() @@ -220,10 +210,8 @@ bool ICOImageDecoder::processDirectory() ICON = 1, CURSOR = 2, }; - if (((fileType != ICON) && (fileType != CURSOR)) || (!idCount)) { - setFailed(); - return false; - } + if (((fileType != ICON) && (fileType != CURSOR)) || (!idCount)) + return setFailed(); // Enlarge member vectors to hold all the entries. m_dirEntries.resize(idCount); @@ -244,10 +232,8 @@ bool ICOImageDecoder::processDirectoryEntries() // Make sure the specified image offsets are past the end of the directory // entries. for (IconDirectoryEntries::iterator i(m_dirEntries.begin()); i != m_dirEntries.end(); ++i) { - if (i->m_imageOffset < m_decodedOffset) { - setFailed(); - return false; - } + if (i->m_imageOffset < m_decodedOffset) + return setFailed(); } // Arrange frames in decreasing quality order. diff --git a/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp b/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp index 9ed20b6..3d9fb8e 100644 --- a/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp +++ b/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp @@ -131,7 +131,8 @@ public: close(); } - void close() { + void close() + { decoder_source_mgr* src = (decoder_source_mgr*)m_info.src; if (src) fastFree(src); @@ -140,13 +141,14 @@ public: jpeg_destroy_decompress(&m_info); } - void skipBytes(long num_bytes) { + void skipBytes(long numBytes) + { decoder_source_mgr* src = (decoder_source_mgr*)m_info.src; - long bytesToSkip = std::min(num_bytes, (long)src->pub.bytes_in_buffer); + long bytesToSkip = std::min(numBytes, (long)src->pub.bytes_in_buffer); src->pub.bytes_in_buffer -= (size_t)bytesToSkip; src->pub.next_input_byte += bytesToSkip; - m_bytesToSkip = std::max(num_bytes - bytesToSkip, static_cast<long>(0)); + m_bytesToSkip = std::max(numBytes - bytesToSkip, static_cast<long>(0)); } bool decode(const Vector<char>& data, bool onlySize) @@ -192,7 +194,6 @@ public: m_info.out_color_space = JCS_CMYK; break; default: - m_state = JPEG_ERROR; return false; } @@ -212,10 +213,8 @@ public: m_state = JPEG_START_DECOMPRESS; // We can fill in the size now that the header is available. - if (!m_decoder->setSize(m_info.image_width, m_info.image_height)) { - m_state = JPEG_ERROR; + if (!m_decoder->setSize(m_info.image_width, m_info.image_height)) return false; - } if (m_decodingSizeOnly) { // We can stop here. Reduce our buffer length and available @@ -316,7 +315,8 @@ public: break; case JPEG_ERROR: - break; + // We can get here if the constructor failed. + return m_decoder->setFailed(); } return true; @@ -380,20 +380,9 @@ JPEGImageDecoder::~JPEGImageDecoder() { } -void JPEGImageDecoder::setData(SharedBuffer* data, bool allDataReceived) -{ - if (m_failed) - return; - - ImageDecoder::setData(data, allDataReceived); - - if (!m_reader && !m_failed) - m_reader.set(new JPEGImageReader(this)); -} - bool JPEGImageDecoder::isSizeAvailable() { - if (!ImageDecoder::isSizeAvailable() && !failed() && m_reader) + if (!ImageDecoder::isSizeAvailable()) decode(true); return ImageDecoder::isSizeAvailable(); @@ -417,7 +406,7 @@ RGBA32Buffer* JPEGImageDecoder::frameBufferAtIndex(size_t index) m_frameBufferCache.resize(1); RGBA32Buffer& frame = m_frameBufferCache[0]; - if (frame.status() != RGBA32Buffer::FrameComplete && m_reader) + if (frame.status() != RGBA32Buffer::FrameComplete) decode(false); return &frame; } @@ -430,10 +419,8 @@ bool JPEGImageDecoder::outputScanlines() // Initialize the framebuffer if needed. RGBA32Buffer& buffer = m_frameBufferCache[0]; if (buffer.status() == RGBA32Buffer::FrameEmpty) { - if (!buffer.setSize(scaledSize().width(), scaledSize().height())) { - m_failed = true; - return false; - } + if (!buffer.setSize(scaledSize().width(), scaledSize().height())) + return setFailed(); buffer.setStatus(RGBA32Buffer::FramePartial); buffer.setHasAlpha(false); @@ -474,8 +461,7 @@ bool JPEGImageDecoder::outputScanlines() buffer.setRGBA(x, destY, jsample[0] * k / 255, jsample[1] * k / 255, jsample[2] * k / 255, 0xFF); } else { ASSERT_NOT_REACHED(); - m_failed = true; - return false; + return setFailed(); } } } @@ -495,12 +481,16 @@ void JPEGImageDecoder::jpegComplete() void JPEGImageDecoder::decode(bool onlySize) { - if (m_failed) + if (failed()) return; - m_failed = !m_reader->decode(m_data->buffer(), onlySize); + if (!m_reader) + m_reader.set(new JPEGImageReader(this)); + + if (!m_reader->decode(m_data->buffer(), onlySize)) + setFailed(); - if (m_failed || (!m_frameBufferCache.isEmpty() && m_frameBufferCache[0].status() == RGBA32Buffer::FrameComplete)) + if (failed() || (!m_frameBufferCache.isEmpty() && m_frameBufferCache[0].status() == RGBA32Buffer::FrameComplete)) m_reader.clear(); } diff --git a/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h b/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h index 2a95dbe..45e14bc 100644 --- a/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h +++ b/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h @@ -42,7 +42,6 @@ namespace WebCore { // ImageDecoder virtual String filenameExtension() const { return "jpg"; } - virtual void setData(SharedBuffer* data, bool allDataReceived); virtual bool isSizeAvailable(); virtual bool setSize(unsigned width, unsigned height); virtual RGBA32Buffer* frameBufferAtIndex(size_t index); diff --git a/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp b/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp index 36f818f..de01d55 100644 --- a/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp +++ b/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp @@ -54,7 +54,6 @@ const unsigned long cMaxPNGSize = 1000000UL; // Called if the decoding of the image fails. static void PNGAPI decodingFailed(png_structp png, png_const_charp) { - static_cast<PNGImageDecoder*>(png_get_progressive_ptr(png))->decodingFailed(); longjmp(png->jmpbuf, 1); } @@ -96,7 +95,6 @@ public: , m_decodingSizeOnly(false) , m_interlaceBuffer(0) , m_hasAlpha(false) - , m_hasFinishedDecoding(false) , m_currentBufferSize(0) { m_png = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, decodingFailed, decodingWarning); @@ -117,33 +115,34 @@ public: delete[] m_interlaceBuffer; m_interlaceBuffer = 0; m_readOffset = 0; - m_hasFinishedDecoding = false; } unsigned currentBufferSize() const { return m_currentBufferSize; } - void setComplete() { m_hasFinishedDecoding = true; } - void decode(const SharedBuffer& data, bool sizeOnly) { m_decodingSizeOnly = sizeOnly; + PNGImageDecoder* decoder = static_cast<PNGImageDecoder*>(png_get_progressive_ptr(m_png)); // We need to do the setjmp here. Otherwise bad things will happen. if (setjmp(m_png->jmpbuf)) { close(); + decoder->setFailed(); return; } - PNGImageDecoder* decoder = static_cast<PNGImageDecoder*>(png_get_progressive_ptr(m_png)); const char* segment; while (unsigned segmentLength = data.getSomeData(segment, m_readOffset)) { m_readOffset += segmentLength; m_currentBufferSize = m_readOffset; png_process_data(m_png, m_info, reinterpret_cast<png_bytep>(const_cast<char*>(segment)), segmentLength); - if ((sizeOnly && decoder->isSizeAvailable()) || m_hasFinishedDecoding) + // We explicitly specify the superclass isSizeAvailable() because we + // merely want to check if we've managed to set the size, not + // (recursively) trigger additional decoding if we haven't. + if (sizeOnly ? decoder->ImageDecoder::isSizeAvailable() : decoder->isComplete()) return; } - if (!m_hasFinishedDecoding && decoder->isAllDataReceived()) + if (!decoder->isComplete() && decoder->isAllDataReceived()) decoder->pngComplete(); } @@ -165,7 +164,6 @@ private: png_infop m_info; png_bytep m_interlaceBuffer; bool m_hasAlpha; - bool m_hasFinishedDecoding; unsigned m_currentBufferSize; }; @@ -177,24 +175,23 @@ PNGImageDecoder::~PNGImageDecoder() { } -void PNGImageDecoder::setData(SharedBuffer* data, bool allDataReceived) -{ - if (m_failed) - return; - - ImageDecoder::setData(data, allDataReceived); - - if (!m_reader && !m_failed) - m_reader.set(new PNGImageReader(this)); -} bool PNGImageDecoder::isSizeAvailable() { - if (!ImageDecoder::isSizeAvailable() && !failed() && m_reader) + if (!ImageDecoder::isSizeAvailable()) decode(true); return ImageDecoder::isSizeAvailable(); } +bool PNGImageDecoder::setSize(unsigned width, unsigned height) +{ + if (!ImageDecoder::setSize(width, height)) + return false; + + prepareScaleDataIfNecessary(); + return true; +} + RGBA32Buffer* PNGImageDecoder::frameBufferAtIndex(size_t index) { if (index) @@ -204,17 +201,11 @@ RGBA32Buffer* PNGImageDecoder::frameBufferAtIndex(size_t index) m_frameBufferCache.resize(1); RGBA32Buffer& frame = m_frameBufferCache[0]; - if (frame.status() != RGBA32Buffer::FrameComplete && m_reader) - // Decode this frame. + if (frame.status() != RGBA32Buffer::FrameComplete) decode(false); return &frame; } -void PNGImageDecoder::decodingFailed() -{ - m_failed = true; -} - void PNGImageDecoder::headerAvailable() { png_structp png = m_reader->pngPtr(); @@ -224,19 +215,14 @@ void PNGImageDecoder::headerAvailable() // Protect against large images. if (png->width > cMaxPNGSize || png->height > cMaxPNGSize) { - m_failed = true; longjmp(png->jmpbuf, 1); return; } // We can fill in the size now that the header is available. - if (!ImageDecoder::isSizeAvailable()) { - if (!setSize(width, height)) { - // Size unreasonable, bail out. - longjmp(png->jmpbuf, 1); - return; - } - prepareScaleDataIfNecessary(); + if (!setSize(width, height)) { + longjmp(png->jmpbuf, 1); + return; } int bitDepth, colorType, interlaceType, compressionType, filterType, channels; @@ -299,7 +285,6 @@ void PNGImageDecoder::rowAvailable(unsigned char* rowBuffer, unsigned rowIndex, RGBA32Buffer& buffer = m_frameBufferCache[0]; if (buffer.status() == RGBA32Buffer::FrameEmpty) { if (!buffer.setSize(scaledSize().width(), scaledSize().height())) { - static_cast<PNGImageDecoder*>(png_get_progressive_ptr(m_reader->pngPtr()))->decodingFailed(); longjmp(m_reader->pngPtr()->jmpbuf, 1); return; } @@ -374,20 +359,21 @@ void PNGImageDecoder::rowAvailable(unsigned char* rowBuffer, unsigned rowIndex, void PNGImageDecoder::pngComplete() { - m_reader->setComplete(); - if (!m_frameBufferCache.isEmpty()) m_frameBufferCache.first().setStatus(RGBA32Buffer::FrameComplete); } void PNGImageDecoder::decode(bool onlySize) { - if (m_failed) + if (failed()) return; + if (!m_reader) + m_reader.set(new PNGImageReader(this)); + m_reader->decode(*m_data, onlySize); - if (m_failed || (!m_frameBufferCache.isEmpty() && m_frameBufferCache[0].status() == RGBA32Buffer::FrameComplete)) + if (failed() || isComplete()) m_reader.clear(); } diff --git a/WebCore/platform/image-decoders/png/PNGImageDecoder.h b/WebCore/platform/image-decoders/png/PNGImageDecoder.h index ba0e19a..3f0602c 100644 --- a/WebCore/platform/image-decoders/png/PNGImageDecoder.h +++ b/WebCore/platform/image-decoders/png/PNGImageDecoder.h @@ -41,16 +41,20 @@ namespace WebCore { // ImageDecoder virtual String filenameExtension() const { return "png"; } - virtual void setData(SharedBuffer* data, bool allDataReceived); virtual bool isSizeAvailable(); + virtual bool setSize(unsigned width, unsigned height); virtual RGBA32Buffer* frameBufferAtIndex(size_t index); // Callbacks from libpng - void decodingFailed(); void headerAvailable(); void rowAvailable(unsigned char* rowBuffer, unsigned rowIndex, int interlacePass); void pngComplete(); + bool isComplete() const + { + return !m_frameBufferCache.isEmpty() && (m_frameBufferCache.first().status() == RGBA32Buffer::FrameComplete); + } + private: // Decodes the image. If |onlySize| is true, stops decoding after // calculating the image size. |