diff options
Diffstat (limited to 'src/3rdparty/webkit/WebCore/platform/graphics/qt/ImageDecoderQt.cpp')
-rw-r--r-- | src/3rdparty/webkit/WebCore/platform/graphics/qt/ImageDecoderQt.cpp | 104 |
1 files changed, 60 insertions, 44 deletions
diff --git a/src/3rdparty/webkit/WebCore/platform/graphics/qt/ImageDecoderQt.cpp b/src/3rdparty/webkit/WebCore/platform/graphics/qt/ImageDecoderQt.cpp index 9bcb3e9eb2..b10cc714f5 100644 --- a/src/3rdparty/webkit/WebCore/platform/graphics/qt/ImageDecoderQt.cpp +++ b/src/3rdparty/webkit/WebCore/platform/graphics/qt/ImageDecoderQt.cpp @@ -47,21 +47,17 @@ ImageDecoder* ImageDecoder::create(const SharedBuffer& data) } ImageDecoderQt::ImageDecoderQt() - : m_buffer(0) - , m_reader(0) - , m_repetitionCount(cAnimationNone) + : m_repetitionCount(cAnimationNone) { } ImageDecoderQt::~ImageDecoderQt() { - delete m_reader; - delete m_buffer; } void ImageDecoderQt::setData(SharedBuffer* data, bool allDataReceived) { - if (m_failed) + if (failed()) return; // No progressive loading possible @@ -77,10 +73,16 @@ void ImageDecoderQt::setData(SharedBuffer* data, bool allDataReceived) // Attempt to load the data QByteArray imageData = QByteArray::fromRawData(m_data->data(), m_data->size()); - m_buffer = new QBuffer; + m_buffer.set(new QBuffer); m_buffer->setData(imageData); - m_buffer->open(QBuffer::ReadOnly | QIODevice::Unbuffered); - m_reader = new QImageReader(m_buffer, m_format); + m_buffer->open(QIODevice::ReadOnly | QIODevice::Unbuffered); + m_reader.set(new QImageReader(m_buffer.get(), m_format)); + + // This will force the JPEG decoder to use JDCT_IFAST + m_reader->setQuality(49); + + // QImageReader only allows retrieving the format before reading the image + m_format = m_reader->format(); } bool ImageDecoderQt::isSizeAvailable() @@ -100,13 +102,12 @@ size_t ImageDecoderQt::frameCount() // Fixup for Qt decoders... imageCount() is wrong // and jumpToNextImage does not work either... so // we will have to parse everything... - if (imageCount == 0) + if (!imageCount) forceLoadEverything(); else m_frameBufferCache.resize(imageCount); - } else { + } else m_frameBufferCache.resize(1); - } } return m_frameBufferCache.size(); @@ -114,8 +115,21 @@ size_t ImageDecoderQt::frameCount() int ImageDecoderQt::repetitionCount() const { - if (m_reader && m_reader->supportsAnimation()) - m_repetitionCount = qMax(0, m_reader->loopCount()); + if (m_reader && m_reader->supportsAnimation()) { + m_repetitionCount = m_reader->loopCount(); + + // Qt and WebCore have a incompatible understanding of + // the loop count and we can not completely map everything. + // Qt | WebCore | description + // -1 | 0 | infinite animation + // 0 | cAnimationLoopOnce | show every frame once + // n | n | no idea if that is supported + // n/a | cAnimationNone | show only the first frame + if (m_repetitionCount == -1) + m_repetitionCount = 0; + else if (m_repetitionCount == 0) + m_repetitionCount = cAnimationLoopOnce; + } return m_repetitionCount; } @@ -130,13 +144,13 @@ RGBA32Buffer* ImageDecoderQt::frameBufferAtIndex(size_t index) // In case the ImageDecoderQt got recreated we don't know // yet how many images we are going to have and need to // find that out now. - int count = m_frameBufferCache.size(); - if (!m_failed && count == 0) { + size_t count = m_frameBufferCache.size(); + if (!failed() && !count) { internalDecodeSize(); count = frameCount(); } - if (index >= static_cast<size_t>(count)) + if (index >= count) return 0; RGBA32Buffer& frame = m_frameBufferCache[index]; @@ -155,10 +169,11 @@ void ImageDecoderQt::internalDecodeSize() // If we have a QSize() something failed QSize size = m_reader->size(); - if (size.isEmpty()) - return failRead(); + if (size.isEmpty()) { + setFailed(); + return clearPointers(); + } - m_format = m_reader->format(); setSize(size.width(), size.height()); } @@ -168,28 +183,31 @@ void ImageDecoderQt::internalReadImage(size_t frameIndex) if (m_reader->supportsAnimation()) m_reader->jumpToImage(frameIndex); - else if (frameIndex != 0) - return failRead(); + else if (frameIndex) { + setFailed(); + return clearPointers(); + } - internalHandleCurrentImage(frameIndex); + if (!internalHandleCurrentImage(frameIndex)) + setFailed(); // Attempt to return some memory - for (int i = 0; i < m_frameBufferCache.size(); ++i) + for (int i = 0; i < m_frameBufferCache.size(); ++i) { if (m_frameBufferCache[i].status() != RGBA32Buffer::FrameComplete) return; + } - delete m_reader; - delete m_buffer; - m_buffer = 0; - m_reader = 0; + clearPointers(); } -void ImageDecoderQt::internalHandleCurrentImage(size_t frameIndex) +bool ImageDecoderQt::internalHandleCurrentImage(size_t frameIndex) { // Now get the QImage from Qt and place it in the RGBA32Buffer QImage img; - if (!m_reader->read(&img)) - return failRead(); + if (!m_reader->read(&img)) { + clearPointers(); + return false; + } // now into the RGBA32Buffer - even if the image is not QSize imageSize = img.size(); @@ -198,6 +216,7 @@ void ImageDecoderQt::internalHandleCurrentImage(size_t frameIndex) buffer->setStatus(RGBA32Buffer::FrameComplete); buffer->setDuration(m_reader->nextImageDelay()); buffer->setDecodedImage(img); + return true; } // The QImageIOHandler is not able to tell us how many frames @@ -205,8 +224,8 @@ void ImageDecoderQt::internalHandleCurrentImage(size_t frameIndex) // increasing the m_frameBufferCache by one and try to parse // the image. We stop when QImage::read fails and then need // to resize the m_frameBufferCache to the final size and update -// the m_failed. In case we failed to decode the first image -// we want to keep m_failed set to true. +// the failed bit. If we failed to decode the first image +// then we truly failed to decode, otherwise we're OK. // TODO: Do not increment the m_frameBufferCache.size() by one but more than one void ImageDecoderQt::forceLoadEverything() @@ -215,24 +234,21 @@ void ImageDecoderQt::forceLoadEverything() do { m_frameBufferCache.resize(++imageCount); - internalHandleCurrentImage(imageCount - 1); - } while(!m_failed); + } while (internalHandleCurrentImage(imageCount - 1)); // If we failed decoding the first image we actually - // have no images and need to keep m_failed set to - // true otherwise we want to reset it and forget about + // have no images and need to set the failed bit. + // Otherwise, we want to forget about // the last attempt to decode a image. m_frameBufferCache.resize(imageCount - 1); - m_failed = imageCount == 1; + if (imageCount == 1) + setFailed(); } -void ImageDecoderQt::failRead() +void ImageDecoderQt::clearPointers() { - setFailed(); - delete m_reader; - delete m_buffer; - m_reader = 0; - m_buffer = 0; + m_reader.clear(); + m_buffer.clear(); } } |