summaryrefslogtreecommitdiff
path: root/Source/WebCore/platform/image-decoders/ImageDecoder.h
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.h
parent32761a6cee1d0dee366b885b7b9c777e67885688 (diff)
downloadWebKitGtk-tarball-master.tar.gz
Diffstat (limited to 'Source/WebCore/platform/image-decoders/ImageDecoder.h')
-rw-r--r--Source/WebCore/platform/image-decoders/ImageDecoder.h303
1 files changed, 57 insertions, 246 deletions
diff --git a/Source/WebCore/platform/image-decoders/ImageDecoder.h b/Source/WebCore/platform/image-decoders/ImageDecoder.h
index 89657d000..758987cb9 100644
--- a/Source/WebCore/platform/image-decoders/ImageDecoder.h
+++ b/Source/WebCore/platform/image-decoders/ImageDecoder.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2006, 2016 Apple Inc. All rights reserved.
* Copyright (C) 2008-2009 Torch Mobile, Inc.
* Copyright (C) Research In Motion Limited 2009-2010. All rights reserved.
* Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)
@@ -13,10 +13,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -26,206 +26,55 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef ImageDecoder_h
-#define ImageDecoder_h
+#pragma once
+#include "ImageFrame.h"
#include "IntRect.h"
-#include "ImageSource.h"
+#include "IntSize.h"
#include "PlatformScreen.h"
#include "SharedBuffer.h"
#include <wtf/Assertions.h>
+#include <wtf/Optional.h>
#include <wtf/RefPtr.h>
#include <wtf/Vector.h>
#include <wtf/text/WTFString.h>
-#if USE(QCMSLIB)
-#include "qcms.h"
-#if OS(DARWIN)
-#include "GraphicsContextCG.h"
-#include <ApplicationServices/ApplicationServices.h>
-#include <wtf/RetainPtr.h>
-#endif
-#endif
-
namespace WebCore {
- // ImageFrame represents the decoded image data. This buffer is what all
- // decoders write a single frame into.
- class ImageFrame {
- public:
- enum FrameStatus { FrameEmpty, FramePartial, FrameComplete };
- enum FrameDisposalMethod {
- // If you change the numeric values of these, make sure you audit
- // all users, as some users may cast raw values to/from these
- // constants.
- DisposeNotSpecified, // Leave frame in framebuffer
- DisposeKeep, // Leave frame in framebuffer
- DisposeOverwriteBgcolor, // Clear frame to transparent
- DisposeOverwritePrevious // Clear frame to previous framebuffer
- // contents
- };
- typedef unsigned PixelData;
-
- ImageFrame();
-
- ImageFrame(const ImageFrame& other) { operator=(other); }
-
- // For backends which refcount their data, this operator doesn't need to
- // create a new copy of the image data, only increase the ref count.
- ImageFrame& operator=(const ImageFrame& other);
-
- // These do not touch other metadata, only the raw pixel data.
- void clearPixelData();
- void zeroFillPixelData();
- void zeroFillFrameRect(const IntRect&);
-
- // Makes this frame have an independent copy of the provided image's
- // pixel data, so that modifications in one frame are not reflected in
- // the other. Returns whether the copy succeeded.
- bool copyBitmapData(const ImageFrame&);
-
- // Copies the pixel data at [(startX, startY), (endX, startY)) to the
- // same X-coordinates on each subsequent row up to but not including
- // endY.
- void copyRowNTimes(int startX, int endX, int startY, int endY)
- {
- ASSERT(startX < width());
- ASSERT(endX <= width());
- ASSERT(startY < height());
- ASSERT(endY <= height());
- const int rowBytes = (endX - startX) * sizeof(PixelData);
- const PixelData* const startAddr = getAddr(startX, startY);
- for (int destY = startY + 1; destY < endY; ++destY)
- memcpy(getAddr(startX, destY), startAddr, rowBytes);
- }
-
- // Allocates space for the pixel data. Must be called before any pixels
- // are written. Must only be called once. Returns whether allocation
- // succeeded.
- bool setSize(int newWidth, int newHeight);
-
- // Returns a caller-owned pointer to the underlying native image data.
- // (Actual use: This pointer will be owned by BitmapImage and freed in
- // FrameData::clear()).
- PassNativeImagePtr asNewNativeImage() const;
-
- bool hasAlpha() const;
- const IntRect& originalFrameRect() const { return m_originalFrameRect; }
- 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 setColorProfile(const ColorProfile&);
- void setOriginalFrameRect(const IntRect& r) { m_originalFrameRect = 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)
- {
- setRGBA(getAddr(x, y), r, g, b, a);
- }
-
- inline PixelData* getAddr(int x, int y)
- {
- return m_bytes + (y * width()) + x;
- }
-
- inline bool hasPixelData() const
- {
- return m_bytes;
- }
-
- // Use fix point multiplier instead of integer division or floating point math.
- // This multipler produces exactly the same result for all values in range 0 - 255.
- static const unsigned fixPointShift = 24;
- static const unsigned fixPointMult = static_cast<unsigned>(1.0 / 255.0 * (1 << fixPointShift)) + 1;
- // Multiplies unsigned value by fixpoint value and converts back to unsigned.
- static unsigned fixPointUnsignedMultiply(unsigned fixed, unsigned v)
- {
- return (fixed * v) >> fixPointShift;
- }
-
- inline void setRGBA(PixelData* dest, unsigned r, unsigned g, unsigned b, unsigned a)
- {
- if (m_premultiplyAlpha && a < 255) {
- if (!a) {
- *dest = 0;
- return;
- }
-
- unsigned alphaMult = a * fixPointMult;
- r = fixPointUnsignedMultiply(r, alphaMult);
- g = fixPointUnsignedMultiply(g, alphaMult);
- b = fixPointUnsignedMultiply(b, alphaMult);
- }
- *dest = (a << 24 | r << 16 | g << 8 | b);
- }
-
- private:
- int width() const
- {
- return m_size.width();
- }
-
- int height() const
- {
- return m_size.height();
- }
-
- Vector<PixelData> m_backingStore;
- PixelData* m_bytes; // The memory is backed by m_backingStore.
- IntSize m_size;
- // FIXME: Do we need m_colorProfile anymore?
- ColorProfile m_colorProfile;
- bool m_hasAlpha;
- IntRect m_originalFrameRect; // This will always just be the entire
- // buffer except for GIF frames whose
- // original rect was smaller than the
- // overall image size.
- FrameStatus m_status;
- unsigned m_duration;
- FrameDisposalMethod m_disposalMethod;
- bool m_premultiplyAlpha;
- };
-
// ImageDecoder is a base for all format-specific decoders
// (e.g. JPEGImageDecoder). This base manages the ImageFrame cache.
//
// ENABLE(IMAGE_DECODER_DOWN_SAMPLING) allows image decoders to downsample
// at decode time. Image decoders will downsample any images larger than
// |m_maxNumPixels|. FIXME: Not yet supported by all decoders.
- class ImageDecoder {
+ class ImageDecoder : public RefCounted<ImageDecoder> {
WTF_MAKE_NONCOPYABLE(ImageDecoder); WTF_MAKE_FAST_ALLOCATED;
public:
- ImageDecoder(ImageSource::AlphaOption alphaOption, ImageSource::GammaAndColorProfileOption gammaAndColorProfileOption)
- : m_scaled(false)
- , m_premultiplyAlpha(alphaOption == ImageSource::AlphaPremultiplied)
- , m_ignoreGammaAndColorProfile(gammaAndColorProfileOption == ImageSource::GammaAndColorProfileIgnored)
- , m_sizeAvailable(false)
- , m_maxNumPixels(-1)
- , m_isAllDataReceived(false)
- , m_failed(false) { }
-
- virtual ~ImageDecoder() { }
-
- // Returns a caller-owned decoder of the appropriate type. Returns 0 if
- // we can't sniff a supported type from the provided data (possibly
+ ImageDecoder(AlphaOption alphaOption, GammaAndColorProfileOption gammaAndColorProfileOption)
+ : m_premultiplyAlpha(alphaOption == AlphaOption::Premultiplied)
+ , m_ignoreGammaAndColorProfile(gammaAndColorProfileOption == GammaAndColorProfileOption::Ignored)
+ {
+ }
+
+ virtual ~ImageDecoder()
+ {
+ }
+
+ // Returns nullptr if we can't sniff a supported type from the provided data (possibly
// because there isn't enough data yet).
- static ImageDecoder* create(const SharedBuffer& data, ImageSource::AlphaOption, ImageSource::GammaAndColorProfileOption);
+ static RefPtr<ImageDecoder> create(const SharedBuffer& data, AlphaOption, GammaAndColorProfileOption);
virtual String filenameExtension() const = 0;
+
+ bool premultiplyAlpha() const { return m_premultiplyAlpha; }
bool isAllDataReceived() const { return m_isAllDataReceived; }
- virtual void setData(SharedBuffer* data, bool allDataReceived)
+ virtual void setData(SharedBuffer& data, bool allDataReceived)
{
if (m_failed)
return;
- m_data = data;
+ m_data = &data;
m_isAllDataReceived = allDataReceived;
}
@@ -237,9 +86,9 @@ namespace WebCore {
return !m_failed && m_sizeAvailable;
}
- virtual IntSize size() const { return m_size; }
+ virtual IntSize size() { return isSizeAvailable() ? m_size : IntSize(); }
- IntSize scaledSize() const
+ IntSize scaledSize()
{
return m_scaled ? IntSize(m_scaledColumns.size(), m_scaledRows.size()) : size();
}
@@ -249,18 +98,18 @@ namespace WebCore {
// sizes. This does NOT differ from size() for GIF, since decoding GIFs
// composites any smaller frames against previous frames to create full-
// size frames.
- virtual IntSize frameSizeAtIndex(size_t) const
+ virtual IntSize frameSizeAtIndex(size_t, SubsamplingLevel)
{
return size();
}
// Returns whether the size is legal (i.e. not going to result in
// overflow elsewhere). If not, marks decoding as failed.
- virtual bool setSize(unsigned width, unsigned height)
+ virtual bool setSize(const IntSize& size)
{
- if (isOverSize(width, height))
+ if (ImageBackingStore::isOverSize(size))
return setFailed();
- m_size = IntSize(width, height);
+ m_size = size;
m_sizeAvailable = true;
return true;
}
@@ -269,24 +118,32 @@ namespace WebCore {
// possible), without decoding the individual frames.
// FIXME: Right now that has to be done by each subclass; factor the
// decode call out and use it here.
- virtual size_t frameCount() { return 1; }
+ virtual size_t frameCount() const { return 1; }
- virtual int repetitionCount() const { return cAnimationNone; }
+ virtual RepetitionCount repetitionCount() const { return RepetitionCountNone; }
// Decodes as much of the requested frame as possible, and returns an
// ImageDecoder-owned pointer.
virtual ImageFrame* frameBufferAtIndex(size_t) = 0;
+ bool frameIsCompleteAtIndex(size_t);
+
// Make the best effort guess to check if the requested frame has alpha channel.
- virtual bool frameHasAlphaAtIndex(size_t) const;
+ bool frameHasAlphaAtIndex(size_t) const;
// Number of bytes in the decoded frame requested. Return 0 if not yet decoded.
- virtual unsigned frameBytesAtIndex(size_t) const;
+ unsigned frameBytesAtIndex(size_t) const;
+
+ float frameDurationAtIndex(size_t);
+
+ NativeImagePtr createFrameImageAtIndex(size_t, SubsamplingLevel = SubsamplingLevel::Default, const std::optional<IntSize>& sizeForDraw = { });
void setIgnoreGammaAndColorProfile(bool flag) { m_ignoreGammaAndColorProfile = flag; }
bool ignoresGammaAndColorProfile() const { return m_ignoreGammaAndColorProfile; }
- ImageOrientation orientation() const { return m_orientation; }
+ ImageOrientation frameOrientationAtIndex(size_t) const { return m_orientation; }
+
+ bool frameAllowSubsamplingAtIndex(size_t) const { return false; }
enum { iccColorProfileHeaderLength = 128 };
@@ -297,6 +154,10 @@ namespace WebCore {
return !memcmp(&profileData[16], "RGB ", 4);
}
+ static size_t bytesDecodedToDetermineProperties() { return 0; }
+
+ static SubsamplingLevel subsamplingLevelForScale(float, SubsamplingLevel) { return SubsamplingLevel::Default; }
+
static bool inputDeviceColorProfile(const char* profileData, unsigned profileLength)
{
ASSERT_UNUSED(profileLength, profileLength >= iccColorProfileHeaderLength);
@@ -304,43 +165,6 @@ namespace WebCore {
return !memcmp(&profileData[12], "mntr", 4) || !memcmp(&profileData[12], "scnr", 4);
}
-#if USE(QCMSLIB)
- static qcms_profile* qcmsOutputDeviceProfile()
- {
- static qcms_profile* outputDeviceProfile = 0;
-
- static bool qcmsInitialized = false;
- if (!qcmsInitialized) {
- qcmsInitialized = true;
- // FIXME: Add optional ICCv4 support.
-#if OS(DARWIN)
- RetainPtr<CGColorSpaceRef> monitorColorSpace = adoptCF(CGDisplayCopyColorSpace(CGMainDisplayID()));
- CFDataRef iccProfile(CGColorSpaceCopyICCProfile(monitorColorSpace.get()));
- if (iccProfile) {
- size_t length = CFDataGetLength(iccProfile);
- const unsigned char* systemProfile = CFDataGetBytePtr(iccProfile);
- outputDeviceProfile = qcms_profile_from_memory(systemProfile, length);
- }
-#else
- // FIXME: add support for multiple monitors.
- ColorProfile profile;
- screenColorProfile(profile);
- if (!profile.isEmpty())
- outputDeviceProfile = qcms_profile_from_memory(profile.data(), profile.size());
-#endif
- if (outputDeviceProfile && qcms_profile_is_bogus(outputDeviceProfile)) {
- qcms_profile_release(outputDeviceProfile);
- outputDeviceProfile = 0;
- }
- if (!outputDeviceProfile)
- outputDeviceProfile = qcms_profile_sRGB();
- if (outputDeviceProfile)
- qcms_profile_precache_output_transform(outputDeviceProfile);
- }
- return outputDeviceProfile;
- }
-#endif
-
// 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. Subclasses may override this to also
@@ -358,13 +182,9 @@ namespace WebCore {
// compositing).
virtual void clearFrameBufferCache(size_t) { }
-#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
- void setMaxNumPixels(int m) { m_maxNumPixels = m; }
-#endif
-
// If the image has a cursor hot-spot, stores it in the argument
// and returns true. Otherwise returns false.
- virtual bool hotSpot(IntPoint&) const { return false; }
+ virtual std::optional<IntPoint> hotSpot() const { return std::nullopt; }
protected:
void prepareScaleDataIfNecessary();
@@ -376,9 +196,7 @@ namespace WebCore {
RefPtr<SharedBuffer> m_data; // The encoded data.
Vector<ImageFrame, 1> m_frameBufferCache;
- // FIXME: Do we need m_colorProfile any more, for any port?
- ColorProfile m_colorProfile;
- bool m_scaled;
+ bool m_scaled { false };
Vector<int> m_scaledColumns;
Vector<int> m_scaledRows;
bool m_premultiplyAlpha;
@@ -386,22 +204,15 @@ namespace WebCore {
ImageOrientation m_orientation;
private:
- // Some code paths compute the size of the image as "width * height * 4"
- // and return it as a (signed) int. Avoid overflow.
- static bool isOverSize(unsigned width, unsigned height)
- {
- unsigned long long total_size = static_cast<unsigned long long>(width)
- * static_cast<unsigned long long>(height);
- return total_size > ((1 << 29) - 1);
- }
-
IntSize m_size;
- bool m_sizeAvailable;
- int m_maxNumPixels;
- bool m_isAllDataReceived;
- bool m_failed;
+ bool m_sizeAvailable { false };
+#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
+ static const int m_maxNumPixels { 1024 * 1024 };
+#else
+ static const int m_maxNumPixels { -1 };
+#endif
+ bool m_isAllDataReceived { false };
+ bool m_failed { false };
};
} // namespace WebCore
-
-#endif