Title: [198782] trunk/Source/WebCore
Revision
198782
Author
[email protected]
Date
2016-03-29 09:18:25 -0700 (Tue, 29 Mar 2016)

Log Message

Create a CG ImageDecoder class instead of defining it as CGImageSourceRef
https://bugs.webkit.org/show_bug.cgi?id=155422

Patch by Said Abou-Hallawa <sabouhallawa@apple,com> on 2016-03-29
Reviewed by Simon Fraser.

Move the image CG decoding code from the class ImageSource out to a new
class named ImageDecoder. The purpose of this split is to unify the code
of the ImageSource for all platforms. This class should be a container
for the ImageDecoder. All the direct frame manipulation like querying the
frame metadata or creating a frame image should be the responsibility of
the ImageDecoder. The ImageSource will be responsible of the image frame
caching. When responding to a frame metadata query, for example. the
ImageSource checks its cache first. If an entry does not exist for the
requested frame, the ImageSource will cache the image and the metadata
of this frame. The ImageSource will respond at the end from the image
frame cache.

The plan after this patch is is the following:
    -- Move the new class to separate files
    -- Merge the ImageSource.cpp and ImageSourceCG.cpp. in one file
    -- Move caching the FrameData from BitmapImage to ImageSource.

* loader/cache/CachedImage.cpp:
(WebCore::CachedImage::imageSizeForRenderer):
BitmapImage::sizeRespectingOrientation() does not take any argument now.
Fix the call to this function and delete the conditionally compiled code
since the code is the same for the two cases.

* platform/graphics/BitmapImage.cpp:
(WebCore::BitmapImage::updateSize):
(WebCore::BitmapImage::sizeRespectingOrientation):
(WebCore::BitmapImage::frameImageAtIndex):
(WebCore::BitmapImage::BitmapImage):
An image can have two sizes: size() and sizeRespectingOrientation(). The
sizeRespectingOrientation() is the transpose of size() iff the image
orientation has usesWidthAsHeight() is true. So there is no need for the
ImageOrientationDescription argument. So there is no need for the members
m_imageOrientation or m_shouldRespectImageOrientation. Also move
m_allowSubsampling and m_minimumSubsamplingLevel (which should be named
m_maximumSubsamplingLevel) to ImageSource instead.

(WebCore::BitmapImage::frameOrientationAtIndex): Replace DefaultImageOrientation
by ImageOrientation().

(WebCore::BitmapImage::dump): Move dumping the image metadata to the
ImageSource.

* platform/graphics/BitmapImage.h:

* platform/graphics/GraphicsContext.h:
* platform/graphics/ImageOrientation.h:
(WebCore::ImageOrientation::ImageOrientation):
(WebCore::ImageOrientation::fromEXIFValue):
(WebCore::ImageOrientation::operator ImageOrientationEnum):
Add a casting operator to ImageOrientation so it can be dumped as enum
value. Also add a default constructor and make the other constructor be
explicit. All the rvalues DefaultImageOrientation should be replaced by
ImageOrientation().

* platform/graphics/ImageSource.cpp:
(WebCore::ImageSource::ImageSource):
(WebCore::ImageSource::clear):
m_decoder is now a unique_ptr. To release it, assign it to nullptr.

(WebCore::ImageSource::ensureDecoderIsCreated): Ensure m_decoder is created.

(WebCore::ImageSource::setData): Call ensureDecoderIsCreated() before
actually setting the data.

(WebCore::ImageSource::isSizeAvailable): Use initialized();

(WebCore::ImageSource::size):
(WebCore::ImageSource::sizeRespectingOrientation):
(WebCore::ImageSource::frameSizeAtIndex):
These functions return the size of the image.

(WebCore::ImageSource::getHotSpot):
(WebCore::ImageSource::repetitionCount):
(WebCore::ImageSource::frameCount):
(WebCore::ImageSource::createFrameImageAtIndex):
(WebCore::ImageSource::frameDurationAtIndex):
(WebCore::ImageSource::orientationAtIndex):
(WebCore::ImageSource::frameHasAlphaAtIndex):
(WebCore::ImageSource::frameIsCompleteAtIndex):
(WebCore::ImageSource::frameBytesAtIndex):
Check for initialized() instead of checking m_decoder.

(WebCore::ImageSource::dump): Dump the image metadata.

(WebCore::ImageSource::initialized): Deleted.

* platform/graphics/ImageSource.h: The image decoder is now named
ImageDecoder for all platforms.

(WebCore::ImageSource::initialized): Moved to the header file.

(WebCore::ImageSource::setAllowSubsampling): Moved from BitmapImage.

* platform/graphics/cairo/BitmapImageCairo.cpp:
(WebCore::BitmapImage::BitmapImage):
(WebCore::BitmapImage::determineMinimumSubsamplingLevel): Deleted.
Delete initializing m_minimumSubsamplingLevel and determineMinimumSubsamplingLevel()
since they are moved to ImageSource.

* platform/graphics/cg/BitmapImageCG.cpp:
(WebCore::BitmapImage::BitmapImage):
(WebCore::BitmapImage::determineMinimumSubsamplingLevel): Deleted.
Delete members and methods which are now owned and calculated by ImageSource.

* platform/graphics/cg/ImageSourceCG.cpp:
(WebCore::ImageDecoder::create): Returns a CG ImageDecoder object.

(WebCore::orientationFromProperties):  Replace DefaultImageOrientation
by ImageOrientation().

(WebCore::ImageDecoder::ImageDecoder): Creates a native CG image decoder.

(WebCore::ImageDecoder::~ImageDecoder): Releases the native CG image decoder.

(WebCore::ImageDecoder::subsamplingLevelForScale): Moved from ImageSource.
A new argument named 'maximumSubsamplingLevel' is added to low filter the
return value.

(WebCore::ImageDecoder::bytesDecodedToDetermineProperties):
(WebCore::ImageDecoder::filenameExtension):
(WebCore::ImageDecoder::isSizeAvailable):
(WebCore::ImageDecoder::size):
(WebCore::ImageDecoder::frameCount):
(WebCore::ImageDecoder::repetitionCount):
(WebCore::ImageDecoder::hotSpot):
(WebCore::ImageDecoder::frameSizeAtIndex):
(WebCore::ImageDecoder::frameIsCompleteAtIndex):
(WebCore::ImageDecoder::orientationAtIndex):
(WebCore::ImageDecoder::frameDurationAtIndex):
(WebCore::ImageDecoder::allowSubsamplingOfFrameAtIndex):
(WebCore::ImageDecoder::frameHasAlphaAtIndex):
(WebCore::ImageDecoder::frameBytesAtIndex):
(WebCore::ImageDecoder::createFrameImageAtIndex):
(WebCore::ImageDecoder::setData):
The code of these function was moved from the functions of ImageSource.

(WebCore::ImageSource::ImageSource):
(WebCore::ImageSource::~ImageSource):
(WebCore::ImageSource::clear):
(WebCore::ImageSource::ensureDecoderIsCreated):
(WebCore::ImageSource::setData):
(WebCore::ImageSource::filenameExtension):
(WebCore::ImageSource::calculateMaximumSubsamplingLevel):
(WebCore::ImageSource::maximumSubsamplingLevel):
(WebCore::ImageSource::subsamplingLevelForScale):
(WebCore::ImageSource::isSizeAvailable):
(WebCore::ImageSource::allowSubsamplingOfFrameAtIndex):
(WebCore::ImageSource::frameSizeAtIndex):
(WebCore::ImageSource::orientationAtIndex):
(WebCore::ImageSource::size):
(WebCore::ImageSource::sizeRespectingOrientation):
(WebCore::ImageSource::getHotSpot):
(WebCore::ImageSource::bytesDecodedToDetermineProperties):
(WebCore::ImageSource::repetitionCount):
(WebCore::ImageSource::frameCount):
(WebCore::ImageSource::createFrameImageAtIndex):
(WebCore::ImageSource::frameIsCompleteAtIndex):
(WebCore::ImageSource::frameDurationAtIndex):
(WebCore::ImageSource::frameHasAlphaAtIndex):
(WebCore::ImageSource::frameBytesAtIndex):
Call m_decoder's function to do the real work.

(WebCore::ImageSource::dump): Dump the image metadata.

(WebCore::ImageSource::initialized): Deleted.

* platform/image-decoders/ImageDecoder.cpp:
(WebCore::ImageDecoder::create):
* platform/image-decoders/ImageDecoder.h:
Change the return of ImageDecoder::create() to be unique_ptr.

* platform/mac/DragImageMac.mm:
(WebCore::createDragImageFromImage): Delete unneeded argument.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (198781 => 198782)


--- trunk/Source/WebCore/ChangeLog	2016-03-29 15:42:46 UTC (rev 198781)
+++ trunk/Source/WebCore/ChangeLog	2016-03-29 16:18:25 UTC (rev 198782)
@@ -1,3 +1,184 @@
+2016-03-29  Said Abou-Hallawa  <sabouhallawa@apple,com>
+
+        Create a CG ImageDecoder class instead of defining it as CGImageSourceRef
+        https://bugs.webkit.org/show_bug.cgi?id=155422
+
+        Reviewed by Simon Fraser.
+
+        Move the image CG decoding code from the class ImageSource out to a new
+        class named ImageDecoder. The purpose of this split is to unify the code
+        of the ImageSource for all platforms. This class should be a container
+        for the ImageDecoder. All the direct frame manipulation like querying the
+        frame metadata or creating a frame image should be the responsibility of
+        the ImageDecoder. The ImageSource will be responsible of the image frame
+        caching. When responding to a frame metadata query, for example. the
+        ImageSource checks its cache first. If an entry does not exist for the
+        requested frame, the ImageSource will cache the image and the metadata
+        of this frame. The ImageSource will respond at the end from the image
+        frame cache.
+ 
+        The plan after this patch is is the following:
+            -- Move the new class to separate files
+            -- Merge the ImageSource.cpp and ImageSourceCG.cpp. in one file
+            -- Move caching the FrameData from BitmapImage to ImageSource.
+ 
+        * loader/cache/CachedImage.cpp:
+        (WebCore::CachedImage::imageSizeForRenderer):
+        BitmapImage::sizeRespectingOrientation() does not take any argument now.
+        Fix the call to this function and delete the conditionally compiled code 
+        since the code is the same for the two cases.
+ 
+        * platform/graphics/BitmapImage.cpp:
+        (WebCore::BitmapImage::updateSize):
+        (WebCore::BitmapImage::sizeRespectingOrientation):
+        (WebCore::BitmapImage::frameImageAtIndex):
+        (WebCore::BitmapImage::BitmapImage):
+        An image can have two sizes: size() and sizeRespectingOrientation(). The
+        sizeRespectingOrientation() is the transpose of size() iff the image
+        orientation has usesWidthAsHeight() is true. So there is no need for the
+        ImageOrientationDescription argument. So there is no need for the members
+        m_imageOrientation or m_shouldRespectImageOrientation. Also move
+        m_allowSubsampling and m_minimumSubsamplingLevel (which should be named
+        m_maximumSubsamplingLevel) to ImageSource instead.
+
+        (WebCore::BitmapImage::frameOrientationAtIndex): Replace DefaultImageOrientation
+        by ImageOrientation().
+        
+        (WebCore::BitmapImage::dump): Move dumping the image metadata to the
+        ImageSource.
+        
+        * platform/graphics/BitmapImage.h:
+        
+        * platform/graphics/GraphicsContext.h:
+        * platform/graphics/ImageOrientation.h:
+        (WebCore::ImageOrientation::ImageOrientation):
+        (WebCore::ImageOrientation::fromEXIFValue):
+        (WebCore::ImageOrientation::operator ImageOrientationEnum):
+        Add a casting operator to ImageOrientation so it can be dumped as enum
+        value. Also add a default constructor and make the other constructor be
+        explicit. All the rvalues DefaultImageOrientation should be replaced by
+        ImageOrientation().
+
+        * platform/graphics/ImageSource.cpp:
+        (WebCore::ImageSource::ImageSource):
+        (WebCore::ImageSource::clear):
+        m_decoder is now a unique_ptr. To release it, assign it to nullptr.
+
+        (WebCore::ImageSource::ensureDecoderIsCreated): Ensure m_decoder is created.
+        
+        (WebCore::ImageSource::setData): Call ensureDecoderIsCreated() before
+        actually setting the data.
+        
+        (WebCore::ImageSource::isSizeAvailable): Use initialized();
+        
+        (WebCore::ImageSource::size):
+        (WebCore::ImageSource::sizeRespectingOrientation):
+        (WebCore::ImageSource::frameSizeAtIndex):
+        These functions return the size of the image.
+    
+        (WebCore::ImageSource::getHotSpot):
+        (WebCore::ImageSource::repetitionCount):
+        (WebCore::ImageSource::frameCount):
+        (WebCore::ImageSource::createFrameImageAtIndex):
+        (WebCore::ImageSource::frameDurationAtIndex):
+        (WebCore::ImageSource::orientationAtIndex):
+        (WebCore::ImageSource::frameHasAlphaAtIndex):
+        (WebCore::ImageSource::frameIsCompleteAtIndex):
+        (WebCore::ImageSource::frameBytesAtIndex):
+        Check for initialized() instead of checking m_decoder.
+        
+        (WebCore::ImageSource::dump): Dump the image metadata.
+        
+        (WebCore::ImageSource::initialized): Deleted.
+        
+        * platform/graphics/ImageSource.h: The image decoder is now named
+        ImageDecoder for all platforms.
+        
+        (WebCore::ImageSource::initialized): Moved to the header file.
+
+        (WebCore::ImageSource::setAllowSubsampling): Moved from BitmapImage.
+        
+        * platform/graphics/cairo/BitmapImageCairo.cpp:
+        (WebCore::BitmapImage::BitmapImage):
+        (WebCore::BitmapImage::determineMinimumSubsamplingLevel): Deleted.
+        Delete initializing m_minimumSubsamplingLevel and determineMinimumSubsamplingLevel()
+        since they are moved to ImageSource.
+        
+        * platform/graphics/cg/BitmapImageCG.cpp:
+        (WebCore::BitmapImage::BitmapImage):
+        (WebCore::BitmapImage::determineMinimumSubsamplingLevel): Deleted.
+        Delete members and methods which are now owned and calculated by ImageSource.
+        
+        * platform/graphics/cg/ImageSourceCG.cpp:
+        (WebCore::ImageDecoder::create): Returns a CG ImageDecoder object.
+        
+        (WebCore::orientationFromProperties):  Replace DefaultImageOrientation
+        by ImageOrientation().
+        
+        (WebCore::ImageDecoder::ImageDecoder): Creates a native CG image decoder.
+        
+        (WebCore::ImageDecoder::~ImageDecoder): Releases the native CG image decoder.
+        
+        (WebCore::ImageDecoder::subsamplingLevelForScale): Moved from ImageSource.
+        A new argument named 'maximumSubsamplingLevel' is added to low filter the
+        return value.
+        
+        (WebCore::ImageDecoder::bytesDecodedToDetermineProperties):
+        (WebCore::ImageDecoder::filenameExtension):
+        (WebCore::ImageDecoder::isSizeAvailable):
+        (WebCore::ImageDecoder::size):
+        (WebCore::ImageDecoder::frameCount):
+        (WebCore::ImageDecoder::repetitionCount):
+        (WebCore::ImageDecoder::hotSpot):
+        (WebCore::ImageDecoder::frameSizeAtIndex):
+        (WebCore::ImageDecoder::frameIsCompleteAtIndex):
+        (WebCore::ImageDecoder::orientationAtIndex):
+        (WebCore::ImageDecoder::frameDurationAtIndex):
+        (WebCore::ImageDecoder::allowSubsamplingOfFrameAtIndex):
+        (WebCore::ImageDecoder::frameHasAlphaAtIndex):
+        (WebCore::ImageDecoder::frameBytesAtIndex):
+        (WebCore::ImageDecoder::createFrameImageAtIndex):
+        (WebCore::ImageDecoder::setData):
+        The code of these function was moved from the functions of ImageSource.
+        
+        (WebCore::ImageSource::ImageSource):
+        (WebCore::ImageSource::~ImageSource):
+        (WebCore::ImageSource::clear):
+        (WebCore::ImageSource::ensureDecoderIsCreated):
+        (WebCore::ImageSource::setData):
+        (WebCore::ImageSource::filenameExtension):
+        (WebCore::ImageSource::calculateMaximumSubsamplingLevel):
+        (WebCore::ImageSource::maximumSubsamplingLevel):
+        (WebCore::ImageSource::subsamplingLevelForScale):
+        (WebCore::ImageSource::isSizeAvailable):
+        (WebCore::ImageSource::allowSubsamplingOfFrameAtIndex):
+        (WebCore::ImageSource::frameSizeAtIndex):
+        (WebCore::ImageSource::orientationAtIndex):
+        (WebCore::ImageSource::size):
+        (WebCore::ImageSource::sizeRespectingOrientation):
+        (WebCore::ImageSource::getHotSpot):
+        (WebCore::ImageSource::bytesDecodedToDetermineProperties):
+        (WebCore::ImageSource::repetitionCount):
+        (WebCore::ImageSource::frameCount):
+        (WebCore::ImageSource::createFrameImageAtIndex):
+        (WebCore::ImageSource::frameIsCompleteAtIndex):
+        (WebCore::ImageSource::frameDurationAtIndex):
+        (WebCore::ImageSource::frameHasAlphaAtIndex):
+        (WebCore::ImageSource::frameBytesAtIndex):
+        Call m_decoder's function to do the real work.
+        
+        (WebCore::ImageSource::dump): Dump the image metadata.
+        
+        (WebCore::ImageSource::initialized): Deleted.
+        
+        * platform/image-decoders/ImageDecoder.cpp:
+        (WebCore::ImageDecoder::create):
+        * platform/image-decoders/ImageDecoder.h:
+        Change the return of ImageDecoder::create() to be unique_ptr.
+        
+        * platform/mac/DragImageMac.mm:
+        (WebCore::createDragImageFromImage): Delete unneeded argument.
+
 2016-03-29  Eric Carlson  <[email protected]>
 
         media/track/track-remove-track.html is flaky, crashing and failing

Modified: trunk/Source/WebCore/loader/cache/CachedImage.cpp (198781 => 198782)


--- trunk/Source/WebCore/loader/cache/CachedImage.cpp	2016-03-29 15:42:46 UTC (rev 198781)
+++ trunk/Source/WebCore/loader/cache/CachedImage.cpp	2016-03-29 16:18:25 UTC (rev 198782)
@@ -272,22 +272,14 @@
     if (!m_image)
         return LayoutSize();
 
-    LayoutSize imageSize(m_image->size());
+    LayoutSize imageSize;
 
-#if ENABLE(CSS_IMAGE_ORIENTATION)
-    if (renderer && is<BitmapImage>(*m_image)) {
-        ImageOrientationDescription orientationDescription(renderer->shouldRespectImageOrientation(), renderer->style().imageOrientation());
-        if (orientationDescription.respectImageOrientation() == RespectImageOrientation)
-            imageSize = LayoutSize(downcast<BitmapImage>(*m_image).sizeRespectingOrientation(orientationDescription));
-    }
-#else
-    if (is<BitmapImage>(*m_image) && (renderer && renderer->shouldRespectImageOrientation() == RespectImageOrientation))
+    if (is<BitmapImage>(*m_image) && renderer && renderer->shouldRespectImageOrientation() == RespectImageOrientation)
         imageSize = LayoutSize(downcast<BitmapImage>(*m_image).sizeRespectingOrientation());
-#endif // ENABLE(CSS_IMAGE_ORIENTATION)
-
-    else if (is<SVGImage>(*m_image) && sizeType == UsedSize) {
+    else if (is<SVGImage>(*m_image) && sizeType == UsedSize)
         imageSize = LayoutSize(m_svgImageCache->imageSizeForRenderer(renderer));
-    }
+    else
+        imageSize = LayoutSize(m_image->size());
 
     if (multiplier == 1.0f)
         return imageSize;

Modified: trunk/Source/WebCore/platform/graphics/BitmapImage.cpp (198781 => 198782)


--- trunk/Source/WebCore/platform/graphics/BitmapImage.cpp	2016-03-29 15:42:46 UTC (rev 198781)
+++ trunk/Source/WebCore/platform/graphics/BitmapImage.cpp	2016-03-29 16:18:25 UTC (rev 198782)
@@ -47,9 +47,6 @@
 
 BitmapImage::BitmapImage(ImageObserver* observer)
     : Image(observer)
-    , m_minimumSubsamplingLevel(0)
-    , m_imageOrientation(OriginTopLeft)
-    , m_shouldRespectImageOrientation(false)
     , m_currentFrame(0)
     , m_repetitionCount(cAnimationNone)
     , m_repetitionCountStatus(Unknown)
@@ -62,9 +59,6 @@
     // FIXME: We should expose a setting to enable/disable progressive loading remove the PLATFORM(IOS)-guard.
     , m_progressiveLoadChunkTime(0)
     , m_progressiveLoadChunkCount(0)
-    , m_allowSubsampling(true)
-#else
-    , m_allowSubsampling(false)
 #endif
     , m_isSolidColor(false)
     , m_checkedForSolidColor(false)
@@ -236,20 +230,15 @@
         imageObserver()->decodedSizeChanged(this, deltaBytes);
 }
 
-void BitmapImage::updateSize(ImageOrientationDescription description) const
+void BitmapImage::updateSize() const
 {
     if (!m_sizeAvailable || m_haveSize)
         return;
 
-    m_size = m_source.size(description);
-    m_sizeRespectingOrientation = m_source.size(ImageOrientationDescription(RespectImageOrientation, description.imageOrientation()));
+    m_size = m_source.size();
+    m_sizeRespectingOrientation = m_source.sizeRespectingOrientation();
 
-    m_imageOrientation = static_cast<unsigned>(description.imageOrientation());
-    m_shouldRespectImageOrientation = static_cast<unsigned>(description.respectImageOrientation());
-
     m_haveSize = true;
-
-    determineMinimumSubsamplingLevel();
     didDecodeProperties();
 }
 
@@ -259,9 +248,9 @@
     return m_size;
 }
 
-IntSize BitmapImage::sizeRespectingOrientation(ImageOrientationDescription description) const
+IntSize BitmapImage::sizeRespectingOrientation() const
 {
-    updateSize(description);
+    updateSize();
     return m_sizeRespectingOrientation;
 }
 
@@ -391,7 +380,7 @@
     if (index >= frameCount())
         return nullptr;
 
-    SubsamplingLevel subsamplingLevel = std::min(m_source.subsamplingLevelForScale(presentationScaleHint), m_minimumSubsamplingLevel);
+    SubsamplingLevel subsamplingLevel = m_source.subsamplingLevelForScale(presentationScaleHint);
 
     // We may have cached a frame with a higher subsampling level, in which case we need to
     // re-decode with a lower level.
@@ -452,7 +441,7 @@
 ImageOrientation BitmapImage::frameOrientationAtIndex(size_t index)
 {
     if (!ensureFrameIsCached(index, CacheMetadataOnly))
-        return DefaultImageOrientation;
+        return ImageOrientation();
 
     if (m_frames[index].m_haveMetadata)
         return m_frames[index].m_orientation;
@@ -710,13 +699,10 @@
         ts.dumpProperty("current-frame", m_currentFrame);
     }
     
-    if (allowSubsampling())
-        ts.dumpProperty("allow-subsampling", allowSubsampling());
     if (m_isSolidColor)
         ts.dumpProperty("solid-color", m_isSolidColor);
     
-    if (m_imageOrientation != OriginTopLeft)
-        ts.dumpProperty("orientation", m_imageOrientation);
+    m_source.dump(ts);
 }
 
 }

Modified: trunk/Source/WebCore/platform/graphics/BitmapImage.h (198781 => 198782)


--- trunk/Source/WebCore/platform/graphics/BitmapImage.h	2016-03-29 15:42:46 UTC (rev 198781)
+++ trunk/Source/WebCore/platform/graphics/BitmapImage.h	2016-03-29 16:18:25 UTC (rev 198782)
@@ -123,7 +123,7 @@
 
     // FloatSize due to override.
     FloatSize size() const override;
-    IntSize sizeRespectingOrientation(ImageOrientationDescription = ImageOrientationDescription()) const;
+    IntSize sizeRespectingOrientation() const;
 
     bool getHotSpot(IntPoint&) const override;
 
@@ -179,16 +179,14 @@
     
     bool canAnimate();
 
-    bool allowSubsampling() const { return m_allowSubsampling; }
-    void setAllowSubsampling(bool allowSubsampling) { m_allowSubsampling = allowSubsampling; }
+    void setAllowSubsampling(bool allowSubsampling) { m_source.setAllowSubsampling(allowSubsampling); }
 
     size_t currentFrame() const { return m_currentFrame; }
     
 private:
     bool isBitmapImage() const override { return true; }
 
-    void updateSize(ImageOrientationDescription = ImageOrientationDescription()) const;
-    void determineMinimumSubsamplingLevel() const;
+    void updateSize() const;
 
 protected:
     enum RepetitionCountStatus {
@@ -295,11 +293,6 @@
     mutable IntSize m_size; // The size to use for the overall image (will just be the size of the first image).
     mutable IntSize m_sizeRespectingOrientation;
 
-    mutable SubsamplingLevel m_minimumSubsamplingLevel;
-
-    mutable unsigned m_imageOrientation : 4; // ImageOrientationEnum
-    mutable unsigned m_shouldRespectImageOrientation : 1; // RespectImageOrientationEnum
-
     size_t m_currentFrame; // The index of the current frame of animation.
     Vector<FrameData, 1> m_frames; // An array of the cached frames of the animation. We have to ref frames to pin them in the cache.
 
@@ -327,8 +320,6 @@
     double m_progressiveLoadChunkTime;
     uint16_t m_progressiveLoadChunkCount;
 #endif
-
-    bool m_allowSubsampling : 1; // Whether we should attempt subsampling if this image is very large.
     bool m_isSolidColor : 1; // Whether or not we are a 1x1 solid image.
     bool m_checkedForSolidColor : 1; // Whether we've checked the frame for solid color.
 

Modified: trunk/Source/WebCore/platform/graphics/GraphicsContext.h (198781 => 198782)


--- trunk/Source/WebCore/platform/graphics/GraphicsContext.h	2016-03-29 15:42:46 UTC (rev 198781)
+++ trunk/Source/WebCore/platform/graphics/GraphicsContext.h	2016-03-29 16:18:25 UTC (rev 198782)
@@ -302,7 +302,7 @@
     const GraphicsContextState& state() const { return m_state; }
 
 #if USE(CG) || USE(CAIRO)
-    WEBCORE_EXPORT void drawNativeImage(const NativeImagePtr&, const FloatSize& selfSize, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator = CompositeSourceOver, BlendMode = BlendModeNormal, ImageOrientation = DefaultImageOrientation);
+    WEBCORE_EXPORT void drawNativeImage(const NativeImagePtr&, const FloatSize& selfSize, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator = CompositeSourceOver, BlendMode = BlendModeNormal, ImageOrientation = ImageOrientation());
 #endif
 
 #if USE(CG)

Modified: trunk/Source/WebCore/platform/graphics/ImageOrientation.h (198781 => 198782)


--- trunk/Source/WebCore/platform/graphics/ImageOrientation.h	2016-03-29 15:42:46 UTC (rev 198781)
+++ trunk/Source/WebCore/platform/graphics/ImageOrientation.h	2016-03-29 16:18:25 UTC (rev 198782)
@@ -84,7 +84,12 @@
 
 class ImageOrientation {
 public:
-    ImageOrientation(ImageOrientationEnum orientation = DefaultImageOrientation)
+    ImageOrientation()
+        : m_orientation(DefaultImageOrientation)
+    {
+    }
+
+    explicit ImageOrientation(ImageOrientationEnum orientation)
         : m_orientation(orientation)
     {
     }
@@ -101,14 +106,16 @@
     {
         // Values direct from images may be invalid, in which case we use the default.
         if (exifValue < OriginTopLeft || exifValue > OriginLeftBottom)
-            return DefaultImageOrientation;
-        return static_cast<ImageOrientationEnum>(exifValue);
+            return ImageOrientation();
+        return ImageOrientation(static_cast<ImageOrientationEnum>(exifValue));
     }
 
     // This transform can be used for drawing an image according to the orientation.
     // It should be used in a right-handed coordinate system.
     AffineTransform transformFromDefault(const FloatSize& drawnSize) const;
 
+    inline operator ImageOrientationEnum() const { return m_orientation; }
+    
     inline bool operator==(const ImageOrientation& other) const { return other.m_orientation == m_orientation; }
     inline bool operator!=(const ImageOrientation& other) const { return !(*this == other); }
 

Modified: trunk/Source/WebCore/platform/graphics/ImageSource.cpp (198781 => 198782)


--- trunk/Source/WebCore/platform/graphics/ImageSource.cpp	2016-03-29 15:42:46 UTC (rev 198781)
+++ trunk/Source/WebCore/platform/graphics/ImageSource.cpp	2016-03-29 16:18:25 UTC (rev 198782)
@@ -43,8 +43,7 @@
 #endif
 
 ImageSource::ImageSource(ImageSource::AlphaOption alphaOption, ImageSource::GammaAndColorProfileOption gammaAndColorProfileOption)
-    : m_decoder(0)
-    , m_alphaOption(alphaOption)
+    : m_alphaOption(alphaOption)
     , m_gammaAndColorProfileOption(gammaAndColorProfileOption)
 {
 }
@@ -62,29 +61,38 @@
         return;
     }
 
-    delete m_decoder;
-    m_decoder = 0;
+    m_decoder = nullptr;
+
     if (data)
         setData(data, allDataReceived);
 }
 
-bool ImageSource::initialized() const
+void ImageSource::ensureDecoderIsCreated(SharedBuffer* data)
 {
-    return m_decoder;
-}
-
-void ImageSource::setData(SharedBuffer* data, bool allDataReceived)
-{
+    if (initialized())
+        return;
+    
     // Make the decoder by sniffing the bytes.
     // This method will examine the data and instantiate an instance of the appropriate decoder plugin.
     // If insufficient bytes are available to determine the image type, no decoder plugin will be
     // made.
-    if (!m_decoder) {
-        m_decoder = static_cast<NativeImageDecoderPtr>(NativeImageDecoder::create(*data, m_alphaOption, m_gammaAndColorProfileOption));
+    m_decoder = ImageDecoder::create(*data, m_alphaOption, m_gammaAndColorProfileOption);
 #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
-        if (m_decoder && s_maxPixelsPerDecodedImage)
-            m_decoder->setMaxNumPixels(s_maxPixelsPerDecodedImage);
+    if (m_decoder && s_maxPixelsPerDecodedImage)
+        m_decoder->setMaxNumPixels(s_maxPixelsPerDecodedImage);
 #endif
+}
+
+void ImageSource::setData(SharedBuffer* data, bool allDataReceived)
+{
+    if (!data)
+        return;
+    
+    ensureDecoderIsCreated(data);
+    
+    if (!initialized()) {
+        ASSERT_NOT_REACHED();
+        return;
     }
 
     if (m_decoder)
@@ -108,29 +116,33 @@
 
 bool ImageSource::isSizeAvailable()
 {
-    return m_decoder && m_decoder->isSizeAvailable();
+    return initialized() && m_decoder->isSizeAvailable();
 }
 
-IntSize ImageSource::size(ImageOrientationDescription description) const
+IntSize ImageSource::size() const
 {
-    return frameSizeAtIndex(0, 0, description);
+    return frameSizeAtIndex(0, 0);
 }
 
-IntSize ImageSource::frameSizeAtIndex(size_t index, SubsamplingLevel, ImageOrientationDescription description) const
+IntSize ImageSource::sizeRespectingOrientation() const
 {
-    if (!m_decoder)
-        return IntSize();
+    return frameSizeAtIndex(0, 0, RespectImageOrientation);
+}
 
+IntSize ImageSource::frameSizeAtIndex(size_t index, SubsamplingLevel, RespectImageOrientationEnum shouldRespectImageOrientation) const
+{
+    if (!initialized())
+        return { };
+
     IntSize size = m_decoder->frameSizeAtIndex(index);
-    if ((description.respectImageOrientation() == RespectImageOrientation) && m_decoder->orientation().usesWidthAsHeight())
-        return IntSize(size.height(), size.width());
-
-    return size;
+    ImageOrientation orientation = m_decoder->orientation();
+    
+    return shouldRespectImageOrientation == RespectImageOrientation && orientation.usesWidthAsHeight() ? size.transposedSize() : size;
 }
 
 bool ImageSource::getHotSpot(IntPoint& hotSpot) const
 {
-    return m_decoder ? m_decoder->hotSpot(hotSpot) : false;
+    return initialized() && m_decoder->hotSpot(hotSpot);
 }
 
 size_t ImageSource::bytesDecodedToDetermineProperties() const
@@ -140,28 +152,28 @@
 
 int ImageSource::repetitionCount()
 {
-    return m_decoder ? m_decoder->repetitionCount() : cAnimationNone;
+    return initialized() ? m_decoder->repetitionCount() : cAnimationNone;
 }
 
 size_t ImageSource::frameCount() const
 {
-    return m_decoder ? m_decoder->frameCount() : 0;
+    return initialized() ? m_decoder->frameCount() : 0;
 }
 
 NativeImagePtr ImageSource::createFrameImageAtIndex(size_t index, SubsamplingLevel)
 {
-    if (!m_decoder)
+    if (!initialized())
         return nullptr;
 
-    ImageFrame* buffer = m_decoder->frameBufferAtIndex(index);
-    if (!buffer || buffer->status() == ImageFrame::FrameEmpty)
-        return nullptr;
-
     // 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 = m_decoder->frameBufferAtIndex(index);
+    if (!buffer || buffer->status() == ImageFrame::FrameEmpty)
+        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->asNewNativeImage();
@@ -169,7 +181,7 @@
 
 float ImageSource::frameDurationAtIndex(size_t index)
 {
-    if (!m_decoder)
+    if (!initialized())
         return 0;
 
     ImageFrame* buffer = m_decoder->frameBufferAtIndex(index);
@@ -188,19 +200,17 @@
 
 ImageOrientation ImageSource::orientationAtIndex(size_t) const
 {
-    return m_decoder ? m_decoder->orientation() : DefaultImageOrientation;
+    return initialized() ? m_decoder->orientation() : ImageOrientation();
 }
 
 bool ImageSource::frameHasAlphaAtIndex(size_t index)
 {
-    if (!m_decoder)
-        return true;
-    return m_decoder->frameHasAlphaAtIndex(index);
+    return !initialized() || m_decoder->frameHasAlphaAtIndex(index);
 }
 
 bool ImageSource::frameIsCompleteAtIndex(size_t index)
 {
-    if (!m_decoder)
+    if (!initialized())
         return false;
 
     ImageFrame* buffer = m_decoder->frameBufferAtIndex(index);
@@ -209,11 +219,19 @@
 
 unsigned ImageSource::frameBytesAtIndex(size_t index, SubsamplingLevel) const
 {
-    if (!m_decoder)
-        return 0;
-    return m_decoder->frameBytesAtIndex(index);
+    return initialized() ? m_decoder->frameBytesAtIndex(index) : 0;
 }
 
+void ImageSource::dump(TextStream& ts) const
+{
+    if (m_allowSubsampling)
+        ts.dumpProperty("allow-subsampling", m_allowSubsampling);
+    
+    ImageOrientation orientation = orientationAtIndex(0);
+    if (orientation != OriginTopLeft)
+        ts.dumpProperty("orientation", orientation);
 }
+    
+}
 
 #endif // USE(CG)

Modified: trunk/Source/WebCore/platform/graphics/ImageSource.h (198781 => 198782)


--- trunk/Source/WebCore/platform/graphics/ImageSource.h	2016-03-29 15:42:46 UTC (rev 198781)
+++ trunk/Source/WebCore/platform/graphics/ImageSource.h	2016-03-29 16:18:25 UTC (rev 198782)
@@ -29,6 +29,7 @@
 
 #include "ImageOrientation.h"
 #include "NativeImagePtr.h"
+#include "TextStream.h"
 
 #include <wtf/Forward.h>
 #include <wtf/Noncopyable.h>
@@ -45,20 +46,8 @@
 class IntPoint;
 class IntSize;
 class SharedBuffer;
-
-#if USE(CG)
-typedef CGImageSourceRef NativeImageDecoderPtr;
-#else
 class ImageDecoder;
-typedef ImageDecoder* NativeImageDecoderPtr;
-#endif
 
-#if USE(CG)
-#define NativeImageDecoder ImageDecoder
-#else
-typedef ImageDecoder NativeImageDecoder;
-#endif
-
 // Right now GIFs are the only recognized image format that supports animation.
 // The animation system and the constants below are designed with this in mind.
 // GIFs have an optional 16-bit unsigned loop count that describes how an
@@ -82,6 +71,7 @@
 
 class ImageSource {
     WTF_MAKE_NONCOPYABLE(ImageSource);
+    friend class BitmapImage;
 public:
     enum AlphaOption {
         AlphaPremultiplied,
@@ -122,19 +112,24 @@
                SharedBuffer* data = ""
                bool allDataReceived = false);
 
-    bool initialized() const;
+    bool initialized() const { return m_decoder.get(); }
 
     void setData(SharedBuffer* data, bool allDataReceived);
     String filenameExtension() const;
 
     SubsamplingLevel subsamplingLevelForScale(float) const;
     bool allowSubsamplingOfFrameAtIndex(size_t) const;
+    void setAllowSubsampling(bool allowSubsampling) { m_allowSubsampling = allowSubsampling; }
+    SubsamplingLevel maximumSubsamplingLevel() const;
 
     bool isSizeAvailable();
+    
     // Always original size, without subsampling.
-    IntSize size(ImageOrientationDescription = ImageOrientationDescription()) const;
+    IntSize size() const;
+    IntSize sizeRespectingOrientation() const;
+    
     // Size of optionally subsampled frame.
-    IntSize frameSizeAtIndex(size_t, SubsamplingLevel = 0, ImageOrientationDescription = ImageOrientationDescription()) const;
+    IntSize frameSizeAtIndex(size_t, SubsamplingLevel = 0, RespectImageOrientationEnum = DoNotRespectImageOrientation) const;
 
     bool getHotSpot(IntPoint&) const;
 
@@ -163,7 +158,17 @@
 #endif
 
 private:
-    NativeImageDecoderPtr m_decoder;
+    void ensureDecoderIsCreated(SharedBuffer*);
+    SubsamplingLevel calculateMaximumSubsamplingLevel() const;
+    void dump(TextStream&) const;
+    
+    std::unique_ptr<ImageDecoder> m_decoder;
+    
+#if PLATFORM(IOS)
+    bool m_allowSubsampling { true };
+#else
+    bool m_allowSubsampling { false };
+#endif
 
 #if !USE(CG)
     AlphaOption m_alphaOption;

Modified: trunk/Source/WebCore/platform/graphics/cairo/BitmapImageCairo.cpp (198781 => 198782)


--- trunk/Source/WebCore/platform/graphics/cairo/BitmapImageCairo.cpp	2016-03-29 15:42:46 UTC (rev 198781)
+++ trunk/Source/WebCore/platform/graphics/cairo/BitmapImageCairo.cpp	2016-03-29 16:18:25 UTC (rev 198782)
@@ -41,7 +41,6 @@
 BitmapImage::BitmapImage(RefPtr<cairo_surface_t>&& nativeImage, ImageObserver* observer)
     : Image(observer)
     , m_size(cairoSurfaceSize(nativeImage.get()))
-    , m_minimumSubsamplingLevel(0)
     , m_currentFrame(0)
     , m_repetitionCount(cAnimationNone)
     , m_repetitionCountStatus(Unknown)
@@ -122,11 +121,6 @@
         imageObserver()->didDraw(this);
 }
 
-void BitmapImage::determineMinimumSubsamplingLevel() const
-{
-    m_minimumSubsamplingLevel = 0;
-}
-
 void BitmapImage::checkForSolidColor()
 {
     m_isSolidColor = false;

Modified: trunk/Source/WebCore/platform/graphics/cg/BitmapImageCG.cpp (198781 => 198782)


--- trunk/Source/WebCore/platform/graphics/cg/BitmapImageCG.cpp	2016-03-29 15:42:46 UTC (rev 198781)
+++ trunk/Source/WebCore/platform/graphics/cg/BitmapImageCG.cpp	2016-03-29 16:18:25 UTC (rev 198782)
@@ -55,7 +55,6 @@
     if (clearMetadata)
         m_haveMetadata = false;
 
-    m_orientation = DefaultImageOrientation;
     m_subsamplingLevel = 0;
 
     if (m_image) {
@@ -70,9 +69,6 @@
 
 BitmapImage::BitmapImage(RetainPtr<CGImageRef>&& image, ImageObserver* observer)
     : Image(observer)
-    , m_minimumSubsamplingLevel(0)
-    , m_imageOrientation(OriginTopLeft)
-    , m_shouldRespectImageOrientation(false)
     , m_currentFrame(0)
     , m_repetitionCount(cAnimationNone)
     , m_repetitionCountStatus(Unknown)
@@ -105,28 +101,6 @@
     checkForSolidColor();
 }
 
-void BitmapImage::determineMinimumSubsamplingLevel() const
-{
-    if (!m_allowSubsampling)
-        return;
-
-    if (!m_source.allowSubsamplingOfFrameAtIndex(0))
-        return;
-
-    // Values chosen to be appropriate for iOS.
-    const int cMaximumImageAreaBeforeSubsampling = 5 * 1024 * 1024;
-    const SubsamplingLevel maxSubsamplingLevel = 3;
-
-    SubsamplingLevel currentLevel = 0;
-    for ( ; currentLevel <= maxSubsamplingLevel; ++currentLevel) {
-        IntSize frameSize = m_source.frameSizeAtIndex(0, currentLevel);
-        if (frameSize.area() < cMaximumImageAreaBeforeSubsampling)
-            break;
-    }
-
-    m_minimumSubsamplingLevel = currentLevel;
-}
-
 void BitmapImage::checkForSolidColor()
 {
     m_checkedForSolidColor = true;

Modified: trunk/Source/WebCore/platform/graphics/cg/ImageSourceCG.cpp (198781 => 198782)


--- trunk/Source/WebCore/platform/graphics/cg/ImageSourceCG.cpp	2016-03-29 15:42:46 UTC (rev 198781)
+++ trunk/Source/WebCore/platform/graphics/cg/ImageSourceCG.cpp	2016-03-29 16:18:25 UTC (rev 198782)
@@ -51,61 +51,53 @@
 #endif
 
 namespace WebCore {
+    
+class ImageDecoder {
+public:
+    ImageDecoder();
+    
+    static std::unique_ptr<ImageDecoder> create()
+    {
+        return std::make_unique<ImageDecoder>();
+    }
 
-const CFStringRef WebCoreCGImagePropertyAPNGUnclampedDelayTime = CFSTR("UnclampedDelayTime");
-const CFStringRef WebCoreCGImagePropertyAPNGDelayTime = CFSTR("DelayTime");
-const CFStringRef WebCoreCGImagePropertyAPNGLoopCount = CFSTR("LoopCount");
+    static size_t bytesDecodedToDetermineProperties();
+    static SubsamplingLevel subsamplingLevelForScale(float scale, SubsamplingLevel maximumSubsamplingLevel);
 
-const CFStringRef kCGImageSourceShouldPreferRGB32 = CFSTR("kCGImageSourceShouldPreferRGB32");
-const CFStringRef kCGImageSourceSkipMetadata = CFSTR("kCGImageSourceSkipMetadata");
+    String filenameExtension() const;
+    bool isSizeAvailable() const;
+    
+    // Always original size, without subsampling.
+    IntSize size() const;
+    size_t frameCount() const;
+    int repetitionCount() const;
+    bool hotSpot(IntPoint& hotSpot) const;
 
-#if !PLATFORM(COCOA)
-size_t sharedBufferGetBytesAtPosition(void* info, void* buffer, off_t position, size_t count)
-{
-    SharedBuffer* sharedBuffer = static_cast<SharedBuffer*>(info);
-    size_t sourceSize = sharedBuffer->size();
-    if (position >= sourceSize)
-        return 0;
+    IntSize frameSizeAtIndex(size_t, SubsamplingLevel) const;
+    bool frameIsCompleteAtIndex(size_t) const;
+    ImageOrientation orientationAtIndex(size_t) const;
 
-    const char* source = sharedBuffer->data() + position;
-    size_t amount = std::min<size_t>(count, sourceSize - position);
-    memcpy(buffer, source, amount);
-    return amount;
-}
+    float frameDurationAtIndex(size_t) const;
+    bool frameHasAlphaAtIndex(size_t) const;
+    bool allowSubsamplingOfFrameAtIndex(size_t) const;
+    unsigned frameBytesAtIndex(size_t, SubsamplingLevel = 0) const;
 
-void sharedBufferRelease(void* info)
-{
-    SharedBuffer* sharedBuffer = static_cast<SharedBuffer*>(info);
-    sharedBuffer->deref();
-}
-#endif
+    NativeImagePtr createFrameImageAtIndex(size_t, SubsamplingLevel) const;
 
-ImageSource::ImageSource(ImageSource::AlphaOption, ImageSource::GammaAndColorProfileOption)
-    : m_decoder(0)
-{
-    // FIXME: AlphaOption and GammaAndColorProfileOption are ignored.
-}
+    void setData(CFDataRef, bool allDataReceived);
+    void setData(SharedBuffer*, bool allDataReceived);
 
-ImageSource::~ImageSource()
-{
-    clear(true);
-}
+protected:
+    mutable IntSize m_size;
+    RetainPtr<CGImageSourceRef> m_nativeDecoder;
+};
 
-void ImageSource::clear(bool destroyAllFrames, size_t, SharedBuffer* data, bool allDataReceived)
-{
-    // Recent versions of ImageIO discard previously decoded image frames if the client
-    // application no longer holds references to them, so there's no need to throw away
-    // the decoder unless we're explicitly asked to destroy all of the frames.
-    if (!destroyAllFrames)
-        return;
+const CFStringRef WebCoreCGImagePropertyAPNGUnclampedDelayTime = CFSTR("UnclampedDelayTime");
+const CFStringRef WebCoreCGImagePropertyAPNGDelayTime = CFSTR("DelayTime");
+const CFStringRef WebCoreCGImagePropertyAPNGLoopCount = CFSTR("LoopCount");
 
-    if (m_decoder) {
-        CFRelease(m_decoder);
-        m_decoder = 0;
-    }
-    if (data)
-        setData(data, allDataReceived);
-}
+const CFStringRef kCGImageSourceShouldPreferRGB32 = CFSTR("kCGImageSourceShouldPreferRGB32");
+const CFStringRef kCGImageSourceSkipMetadata = CFSTR("kCGImageSourceSkipMetadata");
 
 static RetainPtr<CFDictionaryRef> createImageSourceOptions(SubsamplingLevel subsamplingLevel)
 {
@@ -135,173 +127,99 @@
     return options;
 }
 
-bool ImageSource::initialized() const
-{
-    return m_decoder;
-}
-
-void ImageSource::setData(SharedBuffer* data, bool allDataReceived)
-{
-#if PLATFORM(COCOA)
-    if (!m_decoder)
-        m_decoder = CGImageSourceCreateIncremental(0);
-    // On Mac the NSData inside the SharedBuffer can be secretly appended to without the SharedBuffer's knowledge.  We use SharedBuffer's ability
-    // to wrap itself inside CFData to get around this, ensuring that ImageIO is really looking at the SharedBuffer.
-    CGImageSourceUpdateData(m_decoder, data->createCFData().get(), allDataReceived);
-#else
-    if (!m_decoder)
-        m_decoder = CGImageSourceCreateIncremental(0);
-    // Create a CGDataProvider to wrap the SharedBuffer.
-    data->ref();
-    // We use the GetBytesAtPosition callback rather than the GetBytePointer one because SharedBuffer
-    // does not provide a way to lock down the byte pointer and guarantee that it won't move, which
-    // is a requirement for using the GetBytePointer callback.
-    CGDataProviderDirectCallbacks providerCallbacks = { 0, 0, 0, sharedBufferGetBytesAtPosition, sharedBufferRelease };
-    RetainPtr<CGDataProviderRef> dataProvider = adoptCF(CGDataProviderCreateDirect(data, data->size(), &providerCallbacks));
-    CGImageSourceUpdateDataProvider(m_decoder, dataProvider.get(), allDataReceived);
-#endif
-}
-
-String ImageSource::filenameExtension() const
-{
-    if (!m_decoder)
-        return String();
-    CFStringRef imageSourceType = CGImageSourceGetType(m_decoder);
-    return WebCore::preferredExtensionForImageSourceType(imageSourceType);
-}
-
-SubsamplingLevel ImageSource::subsamplingLevelForScale(float scale) const
-{
-    // There are four subsampling levels: 0 = 1x, 1 = 0.5x, 2 = 0.25x, 3 = 0.125x.
-    float clampedScale = std::max<float>(0.125, std::min<float>(1, scale));
-    int result = ceilf(log2f(1 / clampedScale));
-    ASSERT(result >=0 && result <= 3);
-    return result;
-}
-
-bool ImageSource::isSizeAvailable()
-{
-    // Ragnaros yells: TOO SOON! You have awakened me TOO SOON, Executus!
-    if (CGImageSourceGetStatus(m_decoder) < kCGImageStatusIncomplete)
-        return false;
-
-    RetainPtr<CFDictionaryRef> image0Properties = adoptCF(CGImageSourceCopyPropertiesAtIndex(m_decoder, 0, imageSourceOptions().get()));
-    if (!image0Properties)
-        return false;
-
-    return CFDictionaryContainsKey(image0Properties.get(), kCGImagePropertyPixelWidth)
-        && CFDictionaryContainsKey(image0Properties.get(), kCGImagePropertyPixelHeight);
-}
-
 static ImageOrientation orientationFromProperties(CFDictionaryRef imageProperties)
 {
     ASSERT(imageProperties);
     CFNumberRef orientationProperty = (CFNumberRef)CFDictionaryGetValue(imageProperties, kCGImagePropertyOrientation);
     if (!orientationProperty)
-        return DefaultImageOrientation;
+        return ImageOrientation();
 
     int exifValue;
     CFNumberGetValue(orientationProperty, kCFNumberIntType, &exifValue);
     return ImageOrientation::fromEXIFValue(exifValue);
 }
 
-bool ImageSource::allowSubsamplingOfFrameAtIndex(size_t) const
+#if !PLATFORM(COCOA)
+size_t sharedBufferGetBytesAtPosition(void* info, void* buffer, off_t position, size_t count)
 {
-    RetainPtr<CFDictionaryRef> properties = adoptCF(CGImageSourceCopyPropertiesAtIndex(m_decoder, 0, imageSourceOptions().get()));
-    if (!properties)
-        return false;
+    SharedBuffer* sharedBuffer = static_cast<SharedBuffer*>(info);
+    size_t sourceSize = sharedBuffer->size();
+    if (position >= sourceSize)
+        return 0;
 
-    CFDictionaryRef jfifProperties = static_cast<CFDictionaryRef>(CFDictionaryGetValue(properties.get(), kCGImagePropertyJFIFDictionary));
-    if (jfifProperties) {
-        CFBooleanRef isProgCFBool = static_cast<CFBooleanRef>(CFDictionaryGetValue(jfifProperties, kCGImagePropertyJFIFIsProgressive));
-        if (isProgCFBool) {
-            bool isProgressive = CFBooleanGetValue(isProgCFBool);
-            // Workaround for <rdar://problem/5184655> - Hang rendering very large progressive JPEG. Decoding progressive
-            // images hangs for a very long time right now. Until this is fixed, don't sub-sample progressive images. This
-            // will cause them to fail our large image check and they won't be decoded.
-            // FIXME: Remove once underlying issue is fixed (<rdar://problem/5191418>)
-            return !isProgressive;
-        }
-    }
-
-    return true;
+    const char* source = sharedBuffer->data() + position;
+    size_t amount = std::min<size_t>(count, sourceSize - position);
+    memcpy(buffer, source, amount);
+    return amount;
 }
 
-IntSize ImageSource::frameSizeAtIndex(size_t index, SubsamplingLevel subsamplingLevel, ImageOrientationDescription description) const
+void sharedBufferRelease(void* info)
 {
-    RetainPtr<CFDictionaryRef> properties = adoptCF(CGImageSourceCopyPropertiesAtIndex(m_decoder, index, imageSourceOptions(subsamplingLevel).get()));
-
-    if (!properties)
-        return IntSize();
-
-    int width = 0;
-    int height = 0;
-    CFNumberRef num = (CFNumberRef)CFDictionaryGetValue(properties.get(), kCGImagePropertyPixelWidth);
-    if (num)
-        CFNumberGetValue(num, kCFNumberIntType, &width);
-    num = (CFNumberRef)CFDictionaryGetValue(properties.get(), kCGImagePropertyPixelHeight);
-    if (num)
-        CFNumberGetValue(num, kCFNumberIntType, &height);
-
-    if ((description.respectImageOrientation() == RespectImageOrientation) && orientationFromProperties(properties.get()).usesWidthAsHeight())
-        return IntSize(height, width);
-
-    return IntSize(width, height);
+    SharedBuffer* sharedBuffer = static_cast<SharedBuffer*>(info);
+    sharedBuffer->deref();
 }
-
-ImageOrientation ImageSource::orientationAtIndex(size_t index) const
+#endif
+    
+ImageDecoder::ImageDecoder()
 {
-    RetainPtr<CFDictionaryRef> properties = adoptCF(CGImageSourceCopyPropertiesAtIndex(m_decoder, index, imageSourceOptions().get()));
-    if (!properties)
-        return DefaultImageOrientation;
-
-    return orientationFromProperties(properties.get());
+    m_nativeDecoder = adoptCF(CGImageSourceCreateIncremental(nullptr));
 }
+    
+SubsamplingLevel ImageDecoder::subsamplingLevelForScale(float scale, SubsamplingLevel maximumSubsamplingLevel)
+{
+    // There are four subsampling levels: 0 = 1x, 1 = 0.5x, 2 = 0.25x, 3 = 0.125x.
+    float clampedScale = std::max<float>(0.125, std::min<float>(1, scale));
+    SubsamplingLevel result = ceilf(log2f(1 / clampedScale));
+    ASSERT(result >=0 && result <= 3);
+    return std::min(result, maximumSubsamplingLevel);
+}
 
-IntSize ImageSource::size(ImageOrientationDescription description) const
+size_t ImageDecoder::bytesDecodedToDetermineProperties()
 {
-    return frameSizeAtIndex(0, 0, description);
+    // Measured by tracing malloc/calloc calls on Mac OS 10.6.6, x86_64.
+    // A non-zero value ensures cached images with no decoded frames still enter
+    // the live decoded resources list when the CGImageSource decodes image
+    // properties, allowing the cache to prune the partially decoded image.
+    // This value is likely to be inaccurate on other platforms, but the overall
+    // behavior is unchanged.
+    return 13088;
 }
+    
+String ImageDecoder::filenameExtension() const
+{
+    CFStringRef imageSourceType = CGImageSourceGetType(m_nativeDecoder.get());
+    return WebCore::preferredExtensionForImageSourceType(imageSourceType);
+}
 
-bool ImageSource::getHotSpot(IntPoint& hotSpot) const
+bool ImageDecoder::isSizeAvailable() const
 {
-    RetainPtr<CFDictionaryRef> properties = adoptCF(CGImageSourceCopyPropertiesAtIndex(m_decoder, 0, imageSourceOptions().get()));
-    if (!properties)
+    // Ragnaros yells: TOO SOON! You have awakened me TOO SOON, Executus!
+    if (CGImageSourceGetStatus(m_nativeDecoder.get()) < kCGImageStatusIncomplete)
         return false;
 
-    int x = -1, y = -1;
-    CFNumberRef num = (CFNumberRef)CFDictionaryGetValue(properties.get(), CFSTR("hotspotX"));
-    if (!num || !CFNumberGetValue(num, kCFNumberIntType, &x))
+    RetainPtr<CFDictionaryRef> image0Properties = adoptCF(CGImageSourceCopyPropertiesAtIndex(m_nativeDecoder.get(), 0, imageSourceOptions().get()));
+    if (!image0Properties)
         return false;
 
-    num = (CFNumberRef)CFDictionaryGetValue(properties.get(), CFSTR("hotspotY"));
-    if (!num || !CFNumberGetValue(num, kCFNumberIntType, &y))
-        return false;
+    return CFDictionaryContainsKey(image0Properties.get(), kCGImagePropertyPixelWidth)
+        && CFDictionaryContainsKey(image0Properties.get(), kCGImagePropertyPixelHeight);
+}
 
-    if (x < 0 || y < 0)
-        return false;
-
-    hotSpot = IntPoint(x, y);
-    return true;
+IntSize ImageDecoder::size() const
+{
+    if (m_size.isEmpty())
+        m_size = frameSizeAtIndex(0, 0);
+    return m_size;
 }
 
-size_t ImageSource::bytesDecodedToDetermineProperties() const
+size_t ImageDecoder::frameCount() const
 {
-    // Measured by tracing malloc/calloc calls on Mac OS 10.6.6, x86_64.
-    // A non-zero value ensures cached images with no decoded frames still enter
-    // the live decoded resources list when the CGImageSource decodes image
-    // properties, allowing the cache to prune the partially decoded image.
-    // This value is likely to be inaccurate on other platforms, but the overall
-    // behavior is unchanged.
-    return 13088;
+    return CGImageSourceGetCount(m_nativeDecoder.get());
 }
-    
-int ImageSource::repetitionCount()
+
+int ImageDecoder::repetitionCount() const
 {
-    if (!initialized())
-        return cAnimationLoopOnce;
-
-    RetainPtr<CFDictionaryRef> properties = adoptCF(CGImageSourceCopyProperties(m_decoder, imageSourceOptions().get()));
+    RetainPtr<CFDictionaryRef> properties = adoptCF(CGImageSourceCopyProperties(m_nativeDecoder.get(), imageSourceOptions().get()));
     if (!properties)
         return cAnimationLoopOnce;
 
@@ -335,61 +253,67 @@
     return cAnimationNone;
 }
 
-size_t ImageSource::frameCount() const
+bool ImageDecoder::hotSpot(IntPoint& hotSpot) const
 {
-    return m_decoder ? CGImageSourceGetCount(m_decoder) : 0;
+    RetainPtr<CFDictionaryRef> properties = adoptCF(CGImageSourceCopyPropertiesAtIndex(m_nativeDecoder.get(), 0, imageSourceOptions().get()));
+    if (!properties)
+        return false;
+
+    int x = -1, y = -1;
+    CFNumberRef num = (CFNumberRef)CFDictionaryGetValue(properties.get(), CFSTR("hotspotX"));
+    if (!num || !CFNumberGetValue(num, kCFNumberIntType, &x))
+        return false;
+
+    num = (CFNumberRef)CFDictionaryGetValue(properties.get(), CFSTR("hotspotY"));
+    if (!num || !CFNumberGetValue(num, kCFNumberIntType, &y))
+        return false;
+
+    if (x < 0 || y < 0)
+        return false;
+
+    hotSpot = IntPoint(x, y);
+    return true;
 }
 
-RetainPtr<CGImageRef> ImageSource::createFrameImageAtIndex(size_t index, SubsamplingLevel subsamplingLevel)
+IntSize ImageDecoder::frameSizeAtIndex(size_t index, SubsamplingLevel subsamplingLevel) const
 {
-    if (!initialized())
-        return nullptr;
+    RetainPtr<CFDictionaryRef> properties = adoptCF(CGImageSourceCopyPropertiesAtIndex(m_nativeDecoder.get(), index, imageSourceOptions(subsamplingLevel).get()));
 
-    RetainPtr<CGImageRef> image = adoptCF(CGImageSourceCreateImageAtIndex(m_decoder, index, imageSourceOptions(subsamplingLevel).get()));
+    if (!properties)
+        return { };
 
-#if PLATFORM(IOS)
-    // <rdar://problem/7371198> - CoreGraphics changed the default caching behaviour in iOS 4.0 to kCGImageCachingTransient
-    // which caused a performance regression for us since the images had to be resampled/recreated every time we called
-    // CGContextDrawImage. We now tell CG to cache the drawn images. See also <rdar://problem/14366755> -
-    // CoreGraphics needs to un-deprecate kCGImageCachingTemporary since it's still not the default.
-#if COMPILER(CLANG)
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
-#endif
-    CGImageSetCachingFlags(image.get(), kCGImageCachingTemporary);
-#if COMPILER(CLANG)
-#pragma clang diagnostic pop
-#endif
-#endif // PLATFORM(IOS)
+    int width = 0;
+    int height = 0;
+    CFNumberRef num = (CFNumberRef)CFDictionaryGetValue(properties.get(), kCGImagePropertyPixelWidth);
+    if (num)
+        CFNumberGetValue(num, kCFNumberIntType, &width);
 
-    CFStringRef imageUTI = CGImageSourceGetType(m_decoder);
-    static const CFStringRef xbmUTI = CFSTR("public.xbitmap-image");
+    num = (CFNumberRef)CFDictionaryGetValue(properties.get(), kCGImagePropertyPixelHeight);
+    if (num)
+        CFNumberGetValue(num, kCFNumberIntType, &height);
 
-    if (!imageUTI)
-        return image;
-
-    if (!CFEqual(imageUTI, xbmUTI))
-        return image;
-    
-    // If it is an xbm image, mask out all the white areas to render them transparent.
-    const CGFloat maskingColors[6] = {255, 255,  255, 255, 255, 255};
-    RetainPtr<CGImageRef> maskedImage = adoptCF(CGImageCreateWithMaskingColors(image.get(), maskingColors));
-    return maskedImage ? maskedImage : image;
+    return IntSize(width, height);
 }
 
-bool ImageSource::frameIsCompleteAtIndex(size_t index)
+bool ImageDecoder::frameIsCompleteAtIndex(size_t index) const
 {
     ASSERT(frameCount());
-    return CGImageSourceGetStatusAtIndex(m_decoder, index) == kCGImageStatusComplete;
+    return CGImageSourceGetStatusAtIndex(m_nativeDecoder.get(), index) == kCGImageStatusComplete;
 }
 
-float ImageSource::frameDurationAtIndex(size_t index)
+ImageOrientation ImageDecoder::orientationAtIndex(size_t index) const
 {
-    if (!initialized())
-        return 0;
+    RetainPtr<CFDictionaryRef> properties = adoptCF(CGImageSourceCopyPropertiesAtIndex(m_nativeDecoder.get(), index, imageSourceOptions().get()));
+    if (!properties)
+        return ImageOrientation();
 
+    return orientationFromProperties(properties.get());
+}
+
+float ImageDecoder::frameDurationAtIndex(size_t index) const
+{
     float duration = 0;
-    RetainPtr<CFDictionaryRef> properties = adoptCF(CGImageSourceCopyPropertiesAtIndex(m_decoder, index, imageSourceOptions().get()));
+    RetainPtr<CFDictionaryRef> properties = adoptCF(CGImageSourceCopyPropertiesAtIndex(m_nativeDecoder.get(), index, imageSourceOptions().get()));
     if (properties) {
         CFDictionaryRef gifProperties = (CFDictionaryRef)CFDictionaryGetValue(properties.get(), kCGImagePropertyGIFDictionary);
         if (gifProperties) {
@@ -420,15 +344,34 @@
     return duration;
 }
 
-bool ImageSource::frameHasAlphaAtIndex(size_t index)
+bool ImageDecoder::allowSubsamplingOfFrameAtIndex(size_t) const
 {
-    if (!m_decoder)
-        return false; // FIXME: why doesn't this return true?
+    RetainPtr<CFDictionaryRef> properties = adoptCF(CGImageSourceCopyPropertiesAtIndex(m_nativeDecoder.get(), 0, imageSourceOptions().get()));
+    if (!properties)
+        return false;
 
+    CFDictionaryRef jfifProperties = static_cast<CFDictionaryRef>(CFDictionaryGetValue(properties.get(), kCGImagePropertyJFIFDictionary));
+    if (jfifProperties) {
+        CFBooleanRef isProgCFBool = static_cast<CFBooleanRef>(CFDictionaryGetValue(jfifProperties, kCGImagePropertyJFIFIsProgressive));
+        if (isProgCFBool) {
+            bool isProgressive = CFBooleanGetValue(isProgCFBool);
+            // Workaround for <rdar://problem/5184655> - Hang rendering very large progressive JPEG. Decoding progressive
+            // images hangs for a very long time right now. Until this is fixed, don't sub-sample progressive images. This
+            // will cause them to fail our large image check and they won't be decoded.
+            // FIXME: Remove once underlying issue is fixed (<rdar://problem/5191418>)
+            return !isProgressive;
+        }
+    }
+
+    return true;
+}
+
+bool ImageDecoder::frameHasAlphaAtIndex(size_t index) const
+{
     if (!frameIsCompleteAtIndex(index))
         return true;
 
-    CFStringRef imageType = CGImageSourceGetType(m_decoder);
+    CFStringRef imageType = CGImageSourceGetType(m_nativeDecoder.get());
 
     // Return false if there is no image type or the image type is JPEG, because
     // JPEG does not support alpha transparency.
@@ -441,11 +384,245 @@
     return true;
 }
 
+unsigned ImageDecoder::frameBytesAtIndex(size_t index, SubsamplingLevel subsamplingLevel) const
+{
+    IntSize frameSize = frameSizeAtIndex(index, subsamplingLevel);
+    return frameSize.area() * 4;
+}
+
+NativeImagePtr ImageDecoder::createFrameImageAtIndex(size_t index, SubsamplingLevel subsamplingLevel) const
+{
+    RetainPtr<CGImageRef> image = adoptCF(CGImageSourceCreateImageAtIndex(m_nativeDecoder.get(), index, imageSourceOptions(subsamplingLevel).get()));
+
+#if PLATFORM(IOS)
+    // <rdar://problem/7371198> - CoreGraphics changed the default caching behaviour in iOS 4.0 to kCGImageCachingTransient
+    // which caused a performance regression for us since the images had to be resampled/recreated every time we called
+    // CGContextDrawImage. We now tell CG to cache the drawn images. See also <rdar://problem/14366755> -
+    // CoreGraphics needs to un-deprecate kCGImageCachingTemporary since it's still not the default.
+#if COMPILER(CLANG)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+#endif
+        CGImageSetCachingFlags(image.get(), kCGImageCachingTemporary);
+#if COMPILER(CLANG)
+#pragma clang diagnostic pop
+#endif
+#endif // PLATFORM(IOS)
+
+    CFStringRef imageUTI = CGImageSourceGetType(m_nativeDecoder.get());
+    static const CFStringRef xbmUTI = CFSTR("public.xbitmap-image");
+
+    if (!imageUTI)
+        return image;
+
+    if (!CFEqual(imageUTI, xbmUTI))
+        return image;
+
+    // If it is an xbm image, mask out all the white areas to render them transparent.
+    const CGFloat maskingColors[6] = {255, 255,  255, 255, 255, 255};
+    RetainPtr<CGImageRef> maskedImage = adoptCF(CGImageCreateWithMaskingColors(image.get(), maskingColors));
+    return maskedImage ? maskedImage : image;
+}
+
+void ImageDecoder::setData(CFDataRef data, bool allDataReceived)
+{
+    CGImageSourceUpdateData(m_nativeDecoder.get(), data, allDataReceived);
+}
+
+void ImageDecoder::setData(SharedBuffer* data, bool allDataReceived)
+{
+#if PLATFORM(COCOA)
+    // On Mac the NSData inside the SharedBuffer can be secretly appended to without the SharedBuffer's knowledge.
+    // We use SharedBuffer's ability to wrap itself inside CFData to get around this, ensuring that ImageIO is
+    // really looking at the SharedBuffer.
+    setData(data->createCFData().get(), allDataReceived);
+    CGImageSourceUpdateData(m_nativeDecoder.get(), data->createCFData().get(), allDataReceived);
+#else
+    // Create a CGDataProvider to wrap the SharedBuffer.
+    data->ref();
+    // We use the GetBytesAtPosition callback rather than the GetBytePointer one because SharedBuffer
+    // does not provide a way to lock down the byte pointer and guarantee that it won't move, which
+    // is a requirement for using the GetBytePointer callback.
+    CGDataProviderDirectCallbacks providerCallbacks = { 0, 0, 0, sharedBufferGetBytesAtPosition, sharedBufferRelease };
+    RetainPtr<CGDataProviderRef> dataProvider = adoptCF(CGDataProviderCreateDirect(data, data->size(), &providerCallbacks));
+    CGImageSourceUpdateDataProvider(m_nativeDecoder.get(), dataProvider.get(), allDataReceived);
+#endif
+}
+
+ImageSource::ImageSource(ImageSource::AlphaOption, ImageSource::GammaAndColorProfileOption)
+{
+    // FIXME: AlphaOption and GammaAndColorProfileOption are ignored.
+}
+
+ImageSource::~ImageSource()
+{
+    clear(true);
+}
+
+void ImageSource::clear(bool destroyAllFrames, size_t, SharedBuffer* data, bool allDataReceived)
+{
+    // Recent versions of ImageIO discard previously decoded image frames if the client
+    // application no longer holds references to them, so there's no need to throw away
+    // the decoder unless we're explicitly asked to destroy all of the frames.
+    if (!destroyAllFrames)
+        return;
+
+    m_decoder = nullptr;
+    
+    if (data)
+        setData(data, allDataReceived);
+}
+    
+void ImageSource::ensureDecoderIsCreated(SharedBuffer*)
+{
+    if (initialized())
+        return;
+    m_decoder = ImageDecoder::create();
+}
+
+void ImageSource::setData(SharedBuffer* data, bool allDataReceived)
+{
+    if (!data)
+        return;
+    
+    ensureDecoderIsCreated(data);
+    
+    if (!initialized()) {
+        ASSERT_NOT_REACHED();
+        return;
+    }
+    
+    m_decoder->setData(data, allDataReceived);
+}
+
+String ImageSource::filenameExtension() const
+{
+    return initialized() ? m_decoder->filenameExtension() : String();
+}
+    
+SubsamplingLevel ImageSource::calculateMaximumSubsamplingLevel() const
+{
+    if (!m_allowSubsampling || !allowSubsamplingOfFrameAtIndex(0))
+        return 0;
+
+    // Values chosen to be appropriate for iOS.
+    const int cMaximumImageAreaBeforeSubsampling = 5 * 1024 * 1024;
+    const SubsamplingLevel maxSubsamplingLevel = 3;
+
+    SubsamplingLevel currentLevel = 0;
+    for ( ; currentLevel <= maxSubsamplingLevel; ++currentLevel) {
+        IntSize frameSize = frameSizeAtIndex(0, currentLevel);
+        if (frameSize.area() < cMaximumImageAreaBeforeSubsampling)
+            break;
+    }
+
+    return currentLevel;
+}
+    
+SubsamplingLevel ImageSource::maximumSubsamplingLevel() const
+{
+#if PLATFORM(IOS)
+    return calculateMaximumSubsamplingLevel();
+#endif
+    return 0;
+}
+
+SubsamplingLevel ImageSource::subsamplingLevelForScale(float scale) const
+{
+    return ImageDecoder::subsamplingLevelForScale(scale, maximumSubsamplingLevel());
+}
+
+bool ImageSource::isSizeAvailable()
+{
+    return initialized() && m_decoder->isSizeAvailable();
+}
+
+bool ImageSource::allowSubsamplingOfFrameAtIndex(size_t index) const
+{
+    return initialized() && m_decoder->allowSubsamplingOfFrameAtIndex(index);
+}
+
+IntSize ImageSource::frameSizeAtIndex(size_t index, SubsamplingLevel subsamplingLevel, RespectImageOrientationEnum shouldRespectImageOrientation) const
+{
+    if (!initialized())
+        return { };
+    
+    IntSize size = m_decoder->frameSizeAtIndex(index, subsamplingLevel);
+    ImageOrientation orientation = m_decoder->orientationAtIndex(index);
+    
+    return shouldRespectImageOrientation == RespectImageOrientation && orientation.usesWidthAsHeight() ? size.transposedSize() : size;
+}
+
+ImageOrientation ImageSource::orientationAtIndex(size_t index) const
+{
+    return initialized() ? m_decoder->orientationAtIndex(index) : ImageOrientation();
+}
+
+IntSize ImageSource::size() const
+{
+    return frameSizeAtIndex(0, 0);
+}
+    
+IntSize ImageSource::sizeRespectingOrientation() const
+{
+    return frameSizeAtIndex(0, 0, RespectImageOrientation);
+}
+
+bool ImageSource::getHotSpot(IntPoint& hotSpot) const
+{
+    return initialized() && m_decoder->hotSpot(hotSpot);
+}
+
+size_t ImageSource::bytesDecodedToDetermineProperties() const
+{
+    return ImageDecoder::bytesDecodedToDetermineProperties();
+}
+    
+int ImageSource::repetitionCount()
+{
+    return initialized() ? m_decoder->repetitionCount() : cAnimationLoopOnce;
+}
+
+size_t ImageSource::frameCount() const
+{
+    return initialized() ? m_decoder->frameCount() : 0;
+}
+
+RetainPtr<CGImageRef> ImageSource::createFrameImageAtIndex(size_t index, SubsamplingLevel subsamplingLevel)
+{
+    return initialized() ? m_decoder->createFrameImageAtIndex(index, subsamplingLevel) : nullptr;
+}
+
+bool ImageSource::frameIsCompleteAtIndex(size_t index)
+{
+    return initialized() && m_decoder->frameIsCompleteAtIndex(index);
+}
+
+float ImageSource::frameDurationAtIndex(size_t index)
+{
+    return initialized() ? m_decoder->frameDurationAtIndex(index) : 0;
+}
+
+bool ImageSource::frameHasAlphaAtIndex(size_t index)
+{
+    return !initialized() || m_decoder->frameHasAlphaAtIndex(index);
+}
+
 unsigned ImageSource::frameBytesAtIndex(size_t index, SubsamplingLevel subsamplingLevel) const
 {
-    IntSize frameSize = frameSizeAtIndex(index, subsamplingLevel, ImageOrientationDescription(RespectImageOrientation));
-    return frameSize.width() * frameSize.height() * 4;
+    IntSize frameSize = frameSizeAtIndex(index, subsamplingLevel);
+    return frameSize.area() * 4;
 }
+    
+void ImageSource::dump(TextStream& ts) const
+{
+    if (m_allowSubsampling)
+        ts.dumpProperty("allow-subsampling", m_allowSubsampling);
+    
+    ImageOrientation orientation = orientationAtIndex(0);
+    if (orientation != OriginTopLeft)
+        ts.dumpProperty("orientation", orientation);
+}
 
 }
 

Modified: trunk/Source/WebCore/platform/image-decoders/ImageDecoder.cpp (198781 => 198782)


--- trunk/Source/WebCore/platform/image-decoders/ImageDecoder.cpp	2016-03-29 15:42:46 UTC (rev 198781)
+++ trunk/Source/WebCore/platform/image-decoders/ImageDecoder.cpp	2016-03-29 16:18:25 UTC (rev 198782)
@@ -95,35 +95,35 @@
 
 }
 
-ImageDecoder* ImageDecoder::create(const SharedBuffer& data, ImageSource::AlphaOption alphaOption, ImageSource::GammaAndColorProfileOption gammaAndColorProfileOption)
+std::unique_ptr<ImageDecoder> ImageDecoder::create(const SharedBuffer& data, ImageSource::AlphaOption alphaOption, ImageSource::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 std::unique_ptr<ImageDecoder> { std::make_unique<GIFImageDecoder>(alphaOption, gammaAndColorProfileOption) };
 
     if (matchesPNGSignature(contents))
-        return new PNGImageDecoder(alphaOption, gammaAndColorProfileOption);
+        return std::unique_ptr<ImageDecoder> { std::make_unique<PNGImageDecoder>(alphaOption, gammaAndColorProfileOption) };
 
     if (matchesICOSignature(contents) || matchesCURSignature(contents))
-        return new ICOImageDecoder(alphaOption, gammaAndColorProfileOption);
+        return std::unique_ptr<ImageDecoder> { std::make_unique<ICOImageDecoder>(alphaOption, gammaAndColorProfileOption) };
 
     if (matchesJPEGSignature(contents))
-        return new JPEGImageDecoder(alphaOption, gammaAndColorProfileOption);
+        return std::unique_ptr<ImageDecoder> { std::make_unique<JPEGImageDecoder>(alphaOption, gammaAndColorProfileOption) };
 
 #if USE(WEBP)
     if (matchesWebPSignature(contents))
-        return new WEBPImageDecoder(alphaOption, gammaAndColorProfileOption);
+        return std::unique_ptr<ImageDecoder> { std::make_unique<WEBPImageDecoder>(alphaOption, gammaAndColorProfileOption) };
 #endif
 
     if (matchesBMPSignature(contents))
-        return new BMPImageDecoder(alphaOption, gammaAndColorProfileOption);
+        return std::unique_ptr<ImageDecoder> { std::make_unique<BMPImageDecoder>(alphaOption, gammaAndColorProfileOption) };
 
-    return 0;
+    return nullptr;
 }
 
 ImageFrame::ImageFrame()

Modified: trunk/Source/WebCore/platform/image-decoders/ImageDecoder.h (198781 => 198782)


--- trunk/Source/WebCore/platform/image-decoders/ImageDecoder.h	2016-03-29 15:42:46 UTC (rev 198781)
+++ trunk/Source/WebCore/platform/image-decoders/ImageDecoder.h	2016-03-29 16:18:25 UTC (rev 198782)
@@ -248,7 +248,7 @@
         // Returns a caller-owned decoder of the appropriate type.  Returns 0 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 std::unique_ptr<ImageDecoder> create(const SharedBuffer& data, ImageSource::AlphaOption, ImageSource::GammaAndColorProfileOption);
 
         virtual String filenameExtension() const = 0;
 

Modified: trunk/Source/WebCore/platform/mac/DragImageMac.mm (198781 => 198782)


--- trunk/Source/WebCore/platform/mac/DragImageMac.mm	2016-03-29 15:42:46 UTC (rev 198781)
+++ trunk/Source/WebCore/platform/mac/DragImageMac.mm	2016-03-29 16:18:25 UTC (rev 198782)
@@ -91,7 +91,7 @@
     if (is<BitmapImage>(*image)) {
         ImageOrientation orientation;
         BitmapImage& bitmapImage = downcast<BitmapImage>(*image);
-        IntSize sizeRespectingOrientation = bitmapImage.sizeRespectingOrientation(description);
+        IntSize sizeRespectingOrientation = bitmapImage.sizeRespectingOrientation();
 
         if (description.respectImageOrientation() == RespectImageOrientation)
             orientation = bitmapImage.orientationForCurrentFrame();
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to