diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebCore/platform/image-decoders/ImageDecoder.cpp | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/WebCore/platform/image-decoders/ImageDecoder.cpp')
-rw-r--r-- | Source/WebCore/platform/image-decoders/ImageDecoder.cpp | 163 |
1 files changed, 49 insertions, 114 deletions
diff --git a/Source/WebCore/platform/image-decoders/ImageDecoder.cpp b/Source/WebCore/platform/image-decoders/ImageDecoder.cpp index b9656552f..ad6e40298 100644 --- a/Source/WebCore/platform/image-decoders/ImageDecoder.cpp +++ b/Source/WebCore/platform/image-decoders/ImageDecoder.cpp @@ -1,4 +1,5 @@ /* + * Copyright (C) 2016 Apple Inc. All rights reserved. * Copyright (C) 2008-2009 Torch Mobile, Inc. * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved. * @@ -95,138 +96,35 @@ bool matchesCURSignature(char* contents) } -ImageDecoder* ImageDecoder::create(const SharedBuffer& data, ImageSource::AlphaOption alphaOption, ImageSource::GammaAndColorProfileOption gammaAndColorProfileOption) +RefPtr<ImageDecoder> ImageDecoder::create(const SharedBuffer& data, AlphaOption alphaOption, GammaAndColorProfileOption gammaAndColorProfileOption) { static const unsigned lengthOfLongestSignature = 14; // To wit: "RIFF????WEBPVP" char contents[lengthOfLongestSignature]; unsigned length = copyFromSharedBuffer(contents, lengthOfLongestSignature, data, 0); if (length < lengthOfLongestSignature) - return 0; + return nullptr; if (matchesGIFSignature(contents)) - return new GIFImageDecoder(alphaOption, gammaAndColorProfileOption); + return adoptRef(*new GIFImageDecoder(alphaOption, gammaAndColorProfileOption)); if (matchesPNGSignature(contents)) - return new PNGImageDecoder(alphaOption, gammaAndColorProfileOption); + return adoptRef(*new PNGImageDecoder(alphaOption, gammaAndColorProfileOption)); if (matchesICOSignature(contents) || matchesCURSignature(contents)) - return new ICOImageDecoder(alphaOption, gammaAndColorProfileOption); + return adoptRef(*new ICOImageDecoder(alphaOption, gammaAndColorProfileOption)); if (matchesJPEGSignature(contents)) - return new JPEGImageDecoder(alphaOption, gammaAndColorProfileOption); + return adoptRef(*new JPEGImageDecoder(alphaOption, gammaAndColorProfileOption)); #if USE(WEBP) if (matchesWebPSignature(contents)) - return new WEBPImageDecoder(alphaOption, gammaAndColorProfileOption); + return adoptRef(*new WEBPImageDecoder(alphaOption, gammaAndColorProfileOption)); #endif if (matchesBMPSignature(contents)) - return new BMPImageDecoder(alphaOption, gammaAndColorProfileOption); - - return 0; -} - -ImageFrame::ImageFrame() - : m_hasAlpha(false) - , m_status(FrameEmpty) - , m_duration(0) - , m_disposalMethod(DisposeNotSpecified) - , m_premultiplyAlpha(true) -{ -} - -ImageFrame& ImageFrame::operator=(const ImageFrame& other) -{ - if (this == &other) - return *this; - - copyBitmapData(other); - setOriginalFrameRect(other.originalFrameRect()); - setStatus(other.status()); - setDuration(other.duration()); - setDisposalMethod(other.disposalMethod()); - setPremultiplyAlpha(other.premultiplyAlpha()); - return *this; -} - -void ImageFrame::clearPixelData() -{ - m_backingStore.clear(); - m_bytes = 0; - m_status = FrameEmpty; - // NOTE: Do not reset other members here; clearFrameBufferCache() calls this - // to free the bitmap data, but other functions like initFrameBuffer() and - // frameComplete() may still need to read other metadata out of this frame - // later. -} - -void ImageFrame::zeroFillPixelData() -{ - memset(m_bytes, 0, m_size.width() * m_size.height() * sizeof(PixelData)); - m_hasAlpha = true; -} - -void ImageFrame::zeroFillFrameRect(const IntRect& rect) -{ - ASSERT(IntRect(IntPoint(), m_size).contains(rect)); - - if (rect.isEmpty()) - return; - - size_t rectWidthInBytes = rect.width() * sizeof(PixelData); - PixelData* start = m_bytes + (rect.y() * width()) + rect.x(); - for (int i = 0; i < rect.height(); ++i) { - memset(start, 0, rectWidthInBytes); - start += width(); - } - - setHasAlpha(true); -} - -bool ImageFrame::copyBitmapData(const ImageFrame& other) -{ - if (this == &other) - return true; - - m_backingStore = other.m_backingStore; - m_bytes = m_backingStore.data(); - m_size = other.m_size; - setHasAlpha(other.m_hasAlpha); - return true; -} - -bool ImageFrame::setSize(int newWidth, int newHeight) -{ - ASSERT(!width() && !height()); - size_t backingStoreSize = newWidth * newHeight; - if (!m_backingStore.tryReserveCapacity(backingStoreSize)) - return false; - m_backingStore.resize(backingStoreSize); - m_bytes = m_backingStore.data(); - m_size = IntSize(newWidth, newHeight); - - zeroFillPixelData(); - return true; -} - -bool ImageFrame::hasAlpha() const -{ - return m_hasAlpha; -} - -void ImageFrame::setHasAlpha(bool alpha) -{ - m_hasAlpha = alpha; -} - -void ImageFrame::setColorProfile(const ColorProfile& colorProfile) -{ - m_colorProfile = colorProfile; -} + return adoptRef(*new BMPImageDecoder(alphaOption, gammaAndColorProfileOption)); -void ImageFrame::setStatus(FrameStatus status) -{ - m_status = status; + return nullptr; } namespace { @@ -270,11 +168,17 @@ template <MatchType type> int getScaledValue(const Vector<int>& scaledValues, in } +bool ImageDecoder::frameIsCompleteAtIndex(size_t index) +{ + ImageFrame* buffer = frameBufferAtIndex(index); + return buffer && buffer->isComplete(); +} + bool ImageDecoder::frameHasAlphaAtIndex(size_t index) const { if (m_frameBufferCache.size() <= index) return true; - if (m_frameBufferCache[index].status() == ImageFrame::FrameComplete) + if (m_frameBufferCache[index].isComplete()) return m_frameBufferCache[index].hasAlpha(); return true; } @@ -284,7 +188,38 @@ unsigned ImageDecoder::frameBytesAtIndex(size_t index) const if (m_frameBufferCache.size() <= index) return 0; // FIXME: Use the dimension of the requested frame. - return m_size.area() * sizeof(ImageFrame::PixelData); + return (m_size.area() * sizeof(RGBA32)).unsafeGet(); +} + +float ImageDecoder::frameDurationAtIndex(size_t index) +{ + ImageFrame* buffer = frameBufferAtIndex(index); + if (!buffer || buffer->isEmpty()) + return 0; + + // Many annoying ads specify a 0 duration to make an image flash as quickly as possible. + // We follow Firefox's behavior and use a duration of 100 ms for any frames that specify + // a duration of <= 10 ms. See <rdar://problem/7689300> and <http://webkit.org/b/36082> + // for more information. + const float duration = buffer->duration() / 1000.0f; + if (duration < 0.011f) + return 0.100f; + return duration; +} + +NativeImagePtr ImageDecoder::createFrameImageAtIndex(size_t index, SubsamplingLevel, const std::optional<IntSize>&) +{ + // Zero-height images can cause problems for some ports. If we have an empty image dimension, just bail. + if (size().isEmpty()) + return nullptr; + + ImageFrame* buffer = frameBufferAtIndex(index); + if (!buffer || buffer->isEmpty() || !buffer->hasBackingStore()) + return nullptr; + + // Return the buffer contents as a native image. For some ports, the data + // is already in a native container, and this just increments its refcount. + return buffer->backingStore()->image(); } void ImageDecoder::prepareScaleDataIfNecessary() |