summaryrefslogtreecommitdiff
path: root/Source/WebCore/platform/image-decoders/ImageDecoder.cpp
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
commit1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch)
tree46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebCore/platform/image-decoders/ImageDecoder.cpp
parent32761a6cee1d0dee366b885b7b9c777e67885688 (diff)
downloadWebKitGtk-tarball-master.tar.gz
Diffstat (limited to 'Source/WebCore/platform/image-decoders/ImageDecoder.cpp')
-rw-r--r--Source/WebCore/platform/image-decoders/ImageDecoder.cpp163
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()