<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[206156] trunk/Source/WebCore</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/206156">206156</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2016-09-20 11:24:41 -0700 (Tue, 20 Sep 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Rename FrameData to ImageFrame, move it to a separate file and use it for all ports
https://bugs.webkit.org/show_bug.cgi?id=159819

Patch by Said Abou-Hallawa &lt;sabouhallawa@apple.com&gt; on 2016-09-20
Reviewed by Simon Fraser.

Rename FrameData to ImageFrame and move it to a separate file so caching
it can be managed outside the BitmapImage object. Make the data members
of FrameData be private and add getters to return their values. Add backing
store and disposalMethod members, getter and setters to ImageFrame so it can
replace the non-CG ImageFrame class.

* CMakeLists.txt:
* WebCore.xcodeproj/project.pbxproj:
Add ImageFrame class to WebCore project.

* platform/graphics/BitmapImage.cpp:
(WebCore::BitmapImage::BitmapImage): The metadata for the non-decoder case is now calculated in the ImageFrame::initialize().
(WebCore::BitmapImage::haveFrameImageAtIndex): Call ImageFrame's getters instead of access private members.
(WebCore::BitmapImage::destroyDecodedData): Pass ImageFrame::Caching::Metadata to ImageFrame::clear() to clear the image only.
(WebCore::BitmapImage::destroyDecodedDataIfNecessary): ImageFrame::usedFrameBytes() is now renamed to ImageFrame::frameBytes().
(WebCore::BitmapImage::cacheFrame): Call ImageFrame::initialize() to set the image and cache the frame's metadata.
(WebCore::BitmapImage::dataChanged): Pass ImageFrame::Caching::Empty to ImageFrame::clear() to clear the frame's image and metadata.
(WebCore::BitmapImage::ensureFrameAtIndexIsCached): Call ImageFrame's getters instead of access private members.
(WebCore::BitmapImage::frameImageAtIndex): Call ImageFrame's getters instead of access private members.
(WebCore::BitmapImage::frameIsCompleteAtIndex): Pass ImageFrame::Caching::Metadata to ensureFrameAtIndexIsCached() to ensure the frame's metadata is cached.
(WebCore::BitmapImage::frameDurationAtIndex): Pass ImageFrame::Caching::Metadata to ensureFrameAtIndexIsCached() to ensure the frame's metadata is cached.
(WebCore::BitmapImage::frameHasAlphaAtIndex): Pass ImageFrame::Caching::Metadata to ensureFrameAtIndexIsCached() to ensure the frame's metadata is cached.
(WebCore::BitmapImage::frameOrientationAtIndex): Pass ImageFrame::Caching::Metadata to ensureFrameAtIndexIsCached() to ensure the frame's metadata is cached.
(WebCore::BitmapImage::singlePixelSolidColor): Call ImageFrame's getters instead of access private members.
(WebCore::BitmapImage::repetitionCount): Change the return type to be RepetitionCount instead of int.
(WebCore::BitmapImage::shouldAnimate): Use a simpler condition since RepetitionCountNone is equal to zero.
(WebCore::BitmapImage::startAnimation): Replace the cAnimation* constants by the new RepetitionCount* enum.
(WebCore::BitmapImage::internalAdvanceAnimation): Replace the cAnimation* constants by the new RepetitionCount* enum.

* platform/graphics/BitmapImage.h: FrameData is renamed to ImageFrame and moved to a separate file named ImageFrame.h.
(WebCore::FrameData::FrameData): Deleted.
(WebCore::FrameData::~FrameData): Deleted.
(WebCore::FrameData::clear): Deleted.
(WebCore::FrameData::usedFrameBytes): Deleted.

* platform/graphics/ImageBackingStore.h:
(WebCore::ImageBackingStore::fillRect): Make it efficient to fill a rect in the ImageBackingStore with the same color.
(WebCore::ImageBackingStore::pixelAt): Asserts the point is in the bounds of the ImageBackingStore size.
(WebCore::ImageBackingStore::setPixel): Use pixelValue().
(WebCore::ImageBackingStore::inBounds): Private functions check whether a point or a rect is in the bounds of the ImageBackingStore size.
(WebCore::ImageBackingStore::pixelValue): Calculate the RGBA value form red, green, blue and alpha values.

* platform/graphics/ImageFrame.cpp: Added.
(WebCore::ImageFrame::ImageFrame):
(WebCore::ImageFrame::~ImageFrame):
(WebCore::ImageFrame::operator=):
(WebCore::ImageFrame::fillMetaData): Caches the ImageFrame's metadata.
(WebCore::ImageFrame::clearImage): Deletes all the allocated memory by ImageFrame which can be the ImageBackingStore or the NativeImagePtr.
(WebCore::ImageFrame::clear): Deletes the allocated memory and may or may not clears the metadata also.
(WebCore::ImageFrame::initialize): Sets a new ImageBackingStore or a new NativeImagePtr in the ImageFrame.
(WebCore::ImageFrame::size): Returns the size of the ImageFrame which can be the size of ImageBackingStore or the size of NativeImagePtr.
(WebCore::ImageFrame::singlePixelSolidColor): Returns whether the ImageFrame can be drawn by filling the image rectangle with a solid color.

* platform/graphics/ImageFrame.h: Added.
(WebCore::operator++): SubsamplingLevel is strongly typed but RepetitionCount is not since it can be any unsigned value in addition to -1.
(WebCore::ImageFrame::ImageFrame):
(WebCore::ImageFrame::setDecoding):
(WebCore::ImageFrame::decoding):
(WebCore::ImageFrame::isEmpty):
(WebCore::ImageFrame::isPartial):
(WebCore::ImageFrame::isComplete):
(WebCore::ImageFrame::sizeRespectingOrientation):
(WebCore::ImageFrame::frameBytes):
(WebCore::ImageFrame::subsamplingLevel):
(WebCore::ImageFrame::setDisposalMethod):
(WebCore::ImageFrame::disposalMethod):
(WebCore::ImageFrame::image):
(WebCore::ImageFrame::setOrientation):
(WebCore::ImageFrame::orientation):
(WebCore::ImageFrame::setDuration):
(WebCore::ImageFrame::duration):
(WebCore::ImageFrame::setHasAlpha):
(WebCore::ImageFrame::hasAlpha):
(WebCore::ImageFrame::hasImage):
(WebCore::ImageFrame::hasInvalidImage):
(WebCore::ImageFrame::hasMetadata):
(WebCore::ImageFrame::backingStore):
(WebCore::ImageFrame::hasBackingStore):
Setters and getters for the private members.

* platform/graphics/ImageSource.cpp:
(WebCore::ImageSource::calculateMaximumSubsamplingLevel): allowSubsamplingOfFrameAtIndex() is renamed to frameAllowSubsamplingAtIndex().
(WebCore::ImageSource::subsamplingLevelForScale): Use the values of the enum class SubsamplingLevel.
(WebCore::ImageSource::size): Use the values of the enum class SubsamplingLevel.
(WebCore::ImageSource::sizeRespectingOrientation): Use the values of the enum class SubsamplingLevel.
(WebCore::ImageSource::repetitionCount): Replace the constants cAnimation* by the enum RepetitionCount*.
(WebCore::ImageSource::frameAllowSubsamplingAtIndex): Rename allowSubsamplingOfFrameAtIndex() to frameAllowSubsamplingAtIndex().
(WebCore::ImageSource::frameSizeAtIndex): Replace the call to orientationAtIndex() by frameOrientationAtIndex().
(WebCore::ImageSource::frameOrientationAtIndex): Rename orientationAtIndex() to frameOrientationAtIndex().
(WebCore::ImageSource::dump): Replace the call to orientationAtIndex() by frameOrientationAtIndex().
(WebCore::ImageSource::allowSubsamplingOfFrameAtIndex): Deleted.
(WebCore::ImageSource::orientationAtIndex): Deleted.

* platform/graphics/ImageSource.h:
(WebCore::ImageSource::decoder): We need this function temporarily till we move caching the frames outside BitmapImage.

* platform/graphics/NativeImage.h: Change SubImages() to Subimages(). See Darin's comment in https://bugs.webkit.org/show_bug.cgi?id=159819#c6.
* platform/graphics/cairo/NativeImageCairo.cpp:
(WebCore::clearNativeImageSubimages):
(WebCore::clearNativeImageSubImages): Deleted.

* platform/graphics/cg/ImageDecoderCG.cpp:
(WebCore::createImageSourceOptions): Use the values of the enum class SubsamplingLevel.
(WebCore::imageSourceOptions): Use the values of the enum class SubsamplingLevel.
(WebCore::ImageDecoder::repetitionCount): Change the return type to be RepetitionCount instead of int.
(WebCore::ImageDecoder::frameOrientationAtIndex): orientationAtIndex() is renamed to frameOrientationAtIndex().
(WebCore::ImageDecoder::frameAllowSubsamplingAtIndex): allowSubsamplingOfFrameAtIndex() is renamed to frameAllowSubsamplingAtIndex().
(WebCore::ImageDecoder::orientationAtIndex): Deleted.
(WebCore::ImageDecoder::allowSubsamplingOfFrameAtIndex): Deleted.
* platform/graphics/cg/ImageDecoderCG.h:

* platform/graphics/cg/NativeImageCG.cpp:
(WebCore::clearNativeImageSubimages): Change SubImages() to Subimages().
(WebCore::clearNativeImageSubImages): Deleted.

* platform/image-decoders/ImageDecoder.cpp:
(WebCore::ImageDecoder::frameIsCompleteAtIndex): Use ImageFrame::isComplete() instead of checking the value of the decoding status().
(WebCore::ImageDecoder::frameHasAlphaAtIndex): Use ImageFrame::isComplete() instead of checking the value of the decoding status().
(WebCore::ImageDecoder::frameDurationAtIndex): Use ImageFrame::isEmpty() instead of checking the value of the decoding status().
(WebCore::ImageDecoder::createFrameImageAtIndex): Access the ImageBackingStore::image() function directly.
(WebCore::ImageFrame::ImageFrame): Deleted.
(WebCore::ImageFrame::operator=): Deleted.
(WebCore::ImageFrame::clearPixelData): Deleted.
(WebCore::ImageFrame::zeroFillPixelData): Deleted.
(WebCore::ImageFrame::zeroFillFrameRect): Deleted.
(WebCore::ImageFrame::initializeBackingStore): Deleted.
(WebCore::ImageFrame::hasAlpha): Deleted.
(WebCore::ImageFrame::setHasAlpha): Deleted.
(WebCore::ImageFrame::setOriginalFrameRect): Deleted.
(WebCore::ImageFrame::setStatus): Deleted.

* platform/image-decoders/ImageDecoder.h:
(WebCore::ImageDecoder::repetitionCount): Use the type RepetitionCount and the enum RepetitionCount* values.
(WebCore::ImageDecoder::frameOrientationAtIndex): Rename orientationAtIndex() to frameOrientationAtIndex().
(WebCore::ImageDecoder::frameAllowSubsamplingAtIndex): Rename allowSubsamplingOfFrameAtIndex() to frameAllowSubsamplingAtIndex().
(WebCore::ImageDecoder::subsamplingLevelForScale): Use the enum class SubsamplingLevel value instead of integer values.
(WebCore::ImageFrame::ImageFrame): Deleted.
(WebCore::ImageFrame::copyRowNTimes): Deleted.
(WebCore::ImageFrame::size): Deleted.
(WebCore::ImageFrame::asNewNativeImage): Deleted.
(WebCore::ImageFrame::backingStore): Deleted.
(WebCore::ImageFrame::hasBackingStore): Deleted.
(WebCore::ImageFrame::originalFrameRect): Deleted.
(WebCore::ImageFrame::status): Deleted.
(WebCore::ImageFrame::duration): Deleted.
(WebCore::ImageFrame::disposalMethod): Deleted.
(WebCore::ImageFrame::setDuration): Deleted.
(WebCore::ImageFrame::setDisposalMethod): Deleted.
(WebCore::ImageFrame::pixelAt): Deleted.
(WebCore::ImageFrame::setPixel): Deleted.
(WebCore::ImageFrame::blendPixel): Deleted.
(WebCore::ImageDecoder::orientationAtIndex): Deleted.
(WebCore::ImageDecoder::allowSubsamplingOfFrameAtIndex): Deleted.

* platform/image-decoders/bmp/BMPImageDecoder.cpp:
(WebCore::BMPImageDecoder::frameBufferAtIndex): Call ImageFrame::isComplete() instead of checking the value of the decoding status().
(WebCore::BMPImageDecoder::decode): Ditto.

* platform/image-decoders/bmp/BMPImageReader.cpp:
(WebCore::BMPImageReader::decodeBMP): Call ImageFrame::isEmpty(). ImageBuffer::initializeBackingStore() is renamed to initialize().
(WebCore::BMPImageReader::processNonRLEData): Replace ImageFrame::zeroFillPixelData() by ImageBackingStore::clear() and ImageFrame::setAlpha().

* platform/image-decoders/bmp/BMPImageReader.h:
(WebCore::BMPImageReader::setPixel): Call ImageBackingStore::setPixel() directly.
(WebCore::BMPImageReader::fillRGBA): Replace an efficient loop to call setPixel() by ImageBackingStore::fillRect().

* platform/image-decoders/gif/GIFImageDecoder.cpp:
(WebCore::GIFImageDecoder::GIFImageDecoder): Move the initialization of m_repetitionCount to the header file.
(WebCore::GIFImageDecoder::repetitionCount): Change the return type.
(WebCore::GIFImageDecoder::frameBufferAtIndex): Call ImageFrame::isComplete() instead of checking the value of the decoding status().
(WebCore::GIFImageDecoder::clearFrameBufferCache): Use the values of the new enum class ImageFrame::DisposalMethod.
(WebCore::GIFImageDecoder::haveDecodedRow): Call the ImageBackingStore API's directly.
(WebCore::GIFImageDecoder::frameComplete): Use the values of the new enum class ImageFrame::DisposalMethod.
(WebCore::GIFImageDecoder::initFrameBuffer): Move calling ImageBackingStore::setFrameRect() to be after initializing the ImageBackingStore itself.

* platform/image-decoders/gif/GIFImageDecoder.h: Make repetitionCount() returns RepetitionCount and use the new enum class ImageFrame::DisposalMethod.

* platform/image-decoders/gif/GIFImageReader.cpp:
(GIFImageReader::parse):

* platform/image-decoders/gif/GIFImageReader.h:
(GIFFrameContext::GIFFrameContext): Use new enum class ImageFrame::DisposalMethod.

* platform/image-decoders/ico/ICOImageDecoder.cpp:
(WebCore::ICOImageDecoder::frameBufferAtIndex): Call ImageFrame::isComplete() instead of checking the value of the decoding status().
(WebCore::ICOImageDecoder::decode): Ditto.

* platform/image-decoders/jpeg/JPEGImageDecoder.cpp:
(WebCore::JPEGImageDecoder::frameBufferAtIndex): Call ImageFrame::isComplete() instead of checking the value of the decoding status().
(WebCore::setPixel): Call ImageBackingStore::setPixel() directly.
(WebCore::JPEGImageDecoder::outputScanlines): ImageFrame::initializeBackingStore() is renamed to initialize().
(WebCore::JPEGImageDecoder::jpegComplete): ImageFrame::setStatus() is renamed to ImageFrame::setDecoding().
(WebCore::JPEGImageDecoder::decode): Call ImageFrame::isComplete() instead of checking the value of the decoding status().

* platform/image-decoders/png/PNGImageDecoder.cpp:
(WebCore::PNGImageDecoder::frameBufferAtIndex): Call ImageFrame::isComplete() instead of checking the value of the decoding status().
(WebCore::PNGImageDecoder::rowAvailable): Call the ImageBackingStore APIs directly.
(WebCore::PNGImageDecoder::pngComplete): ImageFrame::setStatus() is renamed to setDecoding().
(WebCore::PNGImageDecoder::readChunks): Use the values of the new enum class ImageFrame::DisposalMethod.
(WebCore::PNGImageDecoder::clearFrameBufferCache): Replace the call to ImageFrame::clearPixelData() by  ImageFrame::clear().
(WebCore::PNGImageDecoder::initFrameBuffer): Move calling ImageBackingStore::setFrameRect() to be after initializing the ImageBackingStore itself.
(WebCore::PNGImageDecoder::frameComplete): Call the ImageBackingStore APIs directly.

* platform/image-decoders/png/PNGImageDecoder.h: Call ImageFrame::isComplete() instead of checking the value of the decoding status().

* platform/image-decoders/webp/WEBPImageDecoder.cpp:
(WebCore::WEBPImageDecoder::frameBufferAtIndex): Call ImageFrame::isComplete() instead of checking the value of the decoding status().
(WebCore::WEBPImageDecoder::decode): ImageFrame::setStatus() is renamed to setDecoding(). And initializeBackingStore() is renamed to initialize().</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreCMakeListstxt">trunk/Source/WebCore/CMakeLists.txt</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreWebCorexcodeprojprojectpbxproj">trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsBitmapImagecpp">trunk/Source/WebCore/platform/graphics/BitmapImage.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsBitmapImageh">trunk/Source/WebCore/platform/graphics/BitmapImage.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsImageBackingStoreh">trunk/Source/WebCore/platform/graphics/ImageBackingStore.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsImageSourcecpp">trunk/Source/WebCore/platform/graphics/ImageSource.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsImageSourceh">trunk/Source/WebCore/platform/graphics/ImageSource.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsNativeImageh">trunk/Source/WebCore/platform/graphics/NativeImage.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicscairoNativeImageCairocpp">trunk/Source/WebCore/platform/graphics/cairo/NativeImageCairo.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicscgImageDecoderCGcpp">trunk/Source/WebCore/platform/graphics/cg/ImageDecoderCG.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicscgImageDecoderCGh">trunk/Source/WebCore/platform/graphics/cg/ImageDecoderCG.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicscgNativeImageCGcpp">trunk/Source/WebCore/platform/graphics/cg/NativeImageCG.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformimagedecodersImageDecodercpp">trunk/Source/WebCore/platform/image-decoders/ImageDecoder.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformimagedecodersImageDecoderh">trunk/Source/WebCore/platform/image-decoders/ImageDecoder.h</a></li>
<li><a href="#trunkSourceWebCoreplatformimagedecodersbmpBMPImageDecodercpp">trunk/Source/WebCore/platform/image-decoders/bmp/BMPImageDecoder.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformimagedecodersbmpBMPImageReadercpp">trunk/Source/WebCore/platform/image-decoders/bmp/BMPImageReader.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformimagedecodersbmpBMPImageReaderh">trunk/Source/WebCore/platform/image-decoders/bmp/BMPImageReader.h</a></li>
<li><a href="#trunkSourceWebCoreplatformimagedecodersgifGIFImageDecodercpp">trunk/Source/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformimagedecodersgifGIFImageDecoderh">trunk/Source/WebCore/platform/image-decoders/gif/GIFImageDecoder.h</a></li>
<li><a href="#trunkSourceWebCoreplatformimagedecodersgifGIFImageReadercpp">trunk/Source/WebCore/platform/image-decoders/gif/GIFImageReader.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformimagedecodersgifGIFImageReaderh">trunk/Source/WebCore/platform/image-decoders/gif/GIFImageReader.h</a></li>
<li><a href="#trunkSourceWebCoreplatformimagedecodersicoICOImageDecodercpp">trunk/Source/WebCore/platform/image-decoders/ico/ICOImageDecoder.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformimagedecodersjpegJPEGImageDecodercpp">trunk/Source/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformimagedecoderspngPNGImageDecodercpp">trunk/Source/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformimagedecoderspngPNGImageDecoderh">trunk/Source/WebCore/platform/image-decoders/png/PNGImageDecoder.h</a></li>
<li><a href="#trunkSourceWebCoreplatformimagedecoderswebpWEBPImageDecodercpp">trunk/Source/WebCore/platform/image-decoders/webp/WEBPImageDecoder.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreplatformgraphicsImageFramecpp">trunk/Source/WebCore/platform/graphics/ImageFrame.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsImageFrameh">trunk/Source/WebCore/platform/graphics/ImageFrame.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/CMakeLists.txt (206155 => 206156)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/CMakeLists.txt        2016-09-20 18:12:54 UTC (rev 206155)
+++ trunk/Source/WebCore/CMakeLists.txt        2016-09-20 18:24:41 UTC (rev 206156)
</span><span class="lines">@@ -2220,6 +2220,7 @@
</span><span class="cx">     platform/graphics/ISOVTTCue.cpp
</span><span class="cx">     platform/graphics/Image.cpp
</span><span class="cx">     platform/graphics/ImageBuffer.cpp
</span><ins>+    platform/graphics/ImageFrame.cpp
</ins><span class="cx">     platform/graphics/ImageOrientation.cpp
</span><span class="cx">     platform/graphics/ImageSource.cpp
</span><span class="cx">     platform/graphics/IntPoint.cpp
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (206155 => 206156)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-09-20 18:12:54 UTC (rev 206155)
+++ trunk/Source/WebCore/ChangeLog        2016-09-20 18:24:41 UTC (rev 206156)
</span><span class="lines">@@ -1,3 +1,219 @@
</span><ins>+2016-09-20  Said Abou-Hallawa  &lt;sabouhallawa@apple.com&gt;
+
+        Rename FrameData to ImageFrame, move it to a separate file and use it for all ports
+        https://bugs.webkit.org/show_bug.cgi?id=159819
+
+        Reviewed by Simon Fraser.
+
+        Rename FrameData to ImageFrame and move it to a separate file so caching
+        it can be managed outside the BitmapImage object. Make the data members
+        of FrameData be private and add getters to return their values. Add backing
+        store and disposalMethod members, getter and setters to ImageFrame so it can
+        replace the non-CG ImageFrame class.
+
+        * CMakeLists.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+        Add ImageFrame class to WebCore project.
+        
+        * platform/graphics/BitmapImage.cpp:
+        (WebCore::BitmapImage::BitmapImage): The metadata for the non-decoder case is now calculated in the ImageFrame::initialize().
+        (WebCore::BitmapImage::haveFrameImageAtIndex): Call ImageFrame's getters instead of access private members.
+        (WebCore::BitmapImage::destroyDecodedData): Pass ImageFrame::Caching::Metadata to ImageFrame::clear() to clear the image only.
+        (WebCore::BitmapImage::destroyDecodedDataIfNecessary): ImageFrame::usedFrameBytes() is now renamed to ImageFrame::frameBytes().
+        (WebCore::BitmapImage::cacheFrame): Call ImageFrame::initialize() to set the image and cache the frame's metadata.
+        (WebCore::BitmapImage::dataChanged): Pass ImageFrame::Caching::Empty to ImageFrame::clear() to clear the frame's image and metadata.
+        (WebCore::BitmapImage::ensureFrameAtIndexIsCached): Call ImageFrame's getters instead of access private members.
+        (WebCore::BitmapImage::frameImageAtIndex): Call ImageFrame's getters instead of access private members.
+        (WebCore::BitmapImage::frameIsCompleteAtIndex): Pass ImageFrame::Caching::Metadata to ensureFrameAtIndexIsCached() to ensure the frame's metadata is cached.
+        (WebCore::BitmapImage::frameDurationAtIndex): Pass ImageFrame::Caching::Metadata to ensureFrameAtIndexIsCached() to ensure the frame's metadata is cached.
+        (WebCore::BitmapImage::frameHasAlphaAtIndex): Pass ImageFrame::Caching::Metadata to ensureFrameAtIndexIsCached() to ensure the frame's metadata is cached.
+        (WebCore::BitmapImage::frameOrientationAtIndex): Pass ImageFrame::Caching::Metadata to ensureFrameAtIndexIsCached() to ensure the frame's metadata is cached.
+        (WebCore::BitmapImage::singlePixelSolidColor): Call ImageFrame's getters instead of access private members.
+        (WebCore::BitmapImage::repetitionCount): Change the return type to be RepetitionCount instead of int.
+        (WebCore::BitmapImage::shouldAnimate): Use a simpler condition since RepetitionCountNone is equal to zero.
+        (WebCore::BitmapImage::startAnimation): Replace the cAnimation* constants by the new RepetitionCount* enum.
+        (WebCore::BitmapImage::internalAdvanceAnimation): Replace the cAnimation* constants by the new RepetitionCount* enum.
+
+        * platform/graphics/BitmapImage.h: FrameData is renamed to ImageFrame and moved to a separate file named ImageFrame.h.
+        (WebCore::FrameData::FrameData): Deleted.
+        (WebCore::FrameData::~FrameData): Deleted.
+        (WebCore::FrameData::clear): Deleted.
+        (WebCore::FrameData::usedFrameBytes): Deleted.
+
+        * platform/graphics/ImageBackingStore.h: 
+        (WebCore::ImageBackingStore::fillRect): Make it efficient to fill a rect in the ImageBackingStore with the same color.
+        (WebCore::ImageBackingStore::pixelAt): Asserts the point is in the bounds of the ImageBackingStore size.
+        (WebCore::ImageBackingStore::setPixel): Use pixelValue().
+        (WebCore::ImageBackingStore::inBounds): Private functions check whether a point or a rect is in the bounds of the ImageBackingStore size.
+        (WebCore::ImageBackingStore::pixelValue): Calculate the RGBA value form red, green, blue and alpha values.
+
+        * platform/graphics/ImageFrame.cpp: Added.
+        (WebCore::ImageFrame::ImageFrame): 
+        (WebCore::ImageFrame::~ImageFrame):
+        (WebCore::ImageFrame::operator=):
+        (WebCore::ImageFrame::fillMetaData): Caches the ImageFrame's metadata.
+        (WebCore::ImageFrame::clearImage): Deletes all the allocated memory by ImageFrame which can be the ImageBackingStore or the NativeImagePtr.
+        (WebCore::ImageFrame::clear): Deletes the allocated memory and may or may not clears the metadata also.
+        (WebCore::ImageFrame::initialize): Sets a new ImageBackingStore or a new NativeImagePtr in the ImageFrame.
+        (WebCore::ImageFrame::size): Returns the size of the ImageFrame which can be the size of ImageBackingStore or the size of NativeImagePtr.
+        (WebCore::ImageFrame::singlePixelSolidColor): Returns whether the ImageFrame can be drawn by filling the image rectangle with a solid color.
+        
+        * platform/graphics/ImageFrame.h: Added.
+        (WebCore::operator++): SubsamplingLevel is strongly typed but RepetitionCount is not since it can be any unsigned value in addition to -1.
+        (WebCore::ImageFrame::ImageFrame):
+        (WebCore::ImageFrame::setDecoding):
+        (WebCore::ImageFrame::decoding):
+        (WebCore::ImageFrame::isEmpty):
+        (WebCore::ImageFrame::isPartial):
+        (WebCore::ImageFrame::isComplete):
+        (WebCore::ImageFrame::sizeRespectingOrientation):
+        (WebCore::ImageFrame::frameBytes):
+        (WebCore::ImageFrame::subsamplingLevel):
+        (WebCore::ImageFrame::setDisposalMethod):
+        (WebCore::ImageFrame::disposalMethod):
+        (WebCore::ImageFrame::image):
+        (WebCore::ImageFrame::setOrientation):
+        (WebCore::ImageFrame::orientation):
+        (WebCore::ImageFrame::setDuration):
+        (WebCore::ImageFrame::duration):
+        (WebCore::ImageFrame::setHasAlpha):
+        (WebCore::ImageFrame::hasAlpha):
+        (WebCore::ImageFrame::hasImage):
+        (WebCore::ImageFrame::hasInvalidImage):
+        (WebCore::ImageFrame::hasMetadata):
+        (WebCore::ImageFrame::backingStore):
+        (WebCore::ImageFrame::hasBackingStore):
+        Setters and getters for the private members.
+
+        * platform/graphics/ImageSource.cpp:
+        (WebCore::ImageSource::calculateMaximumSubsamplingLevel): allowSubsamplingOfFrameAtIndex() is renamed to frameAllowSubsamplingAtIndex().
+        (WebCore::ImageSource::subsamplingLevelForScale): Use the values of the enum class SubsamplingLevel.
+        (WebCore::ImageSource::size): Use the values of the enum class SubsamplingLevel.
+        (WebCore::ImageSource::sizeRespectingOrientation): Use the values of the enum class SubsamplingLevel.
+        (WebCore::ImageSource::repetitionCount): Replace the constants cAnimation* by the enum RepetitionCount*.
+        (WebCore::ImageSource::frameAllowSubsamplingAtIndex): Rename allowSubsamplingOfFrameAtIndex() to frameAllowSubsamplingAtIndex().
+        (WebCore::ImageSource::frameSizeAtIndex): Replace the call to orientationAtIndex() by frameOrientationAtIndex().
+        (WebCore::ImageSource::frameOrientationAtIndex): Rename orientationAtIndex() to frameOrientationAtIndex().
+        (WebCore::ImageSource::dump): Replace the call to orientationAtIndex() by frameOrientationAtIndex().
+        (WebCore::ImageSource::allowSubsamplingOfFrameAtIndex): Deleted.
+        (WebCore::ImageSource::orientationAtIndex): Deleted.
+        
+        * platform/graphics/ImageSource.h:
+        (WebCore::ImageSource::decoder): We need this function temporarily till we move caching the frames outside BitmapImage. 
+
+        * platform/graphics/NativeImage.h: Change SubImages() to Subimages(). See Darin's comment in https://bugs.webkit.org/show_bug.cgi?id=159819#c6.
+        * platform/graphics/cairo/NativeImageCairo.cpp:
+        (WebCore::clearNativeImageSubimages):
+        (WebCore::clearNativeImageSubImages): Deleted.
+
+        * platform/graphics/cg/ImageDecoderCG.cpp:
+        (WebCore::createImageSourceOptions): Use the values of the enum class SubsamplingLevel.
+        (WebCore::imageSourceOptions): Use the values of the enum class SubsamplingLevel.
+        (WebCore::ImageDecoder::repetitionCount): Change the return type to be RepetitionCount instead of int.
+        (WebCore::ImageDecoder::frameOrientationAtIndex): orientationAtIndex() is renamed to frameOrientationAtIndex().
+        (WebCore::ImageDecoder::frameAllowSubsamplingAtIndex): allowSubsamplingOfFrameAtIndex() is renamed to frameAllowSubsamplingAtIndex().
+        (WebCore::ImageDecoder::orientationAtIndex): Deleted.
+        (WebCore::ImageDecoder::allowSubsamplingOfFrameAtIndex): Deleted.
+        * platform/graphics/cg/ImageDecoderCG.h:
+
+        * platform/graphics/cg/NativeImageCG.cpp:
+        (WebCore::clearNativeImageSubimages): Change SubImages() to Subimages().
+        (WebCore::clearNativeImageSubImages): Deleted.
+
+        * platform/image-decoders/ImageDecoder.cpp:
+        (WebCore::ImageDecoder::frameIsCompleteAtIndex): Use ImageFrame::isComplete() instead of checking the value of the decoding status().
+        (WebCore::ImageDecoder::frameHasAlphaAtIndex): Use ImageFrame::isComplete() instead of checking the value of the decoding status().
+        (WebCore::ImageDecoder::frameDurationAtIndex): Use ImageFrame::isEmpty() instead of checking the value of the decoding status().
+        (WebCore::ImageDecoder::createFrameImageAtIndex): Access the ImageBackingStore::image() function directly.
+        (WebCore::ImageFrame::ImageFrame): Deleted.
+        (WebCore::ImageFrame::operator=): Deleted.
+        (WebCore::ImageFrame::clearPixelData): Deleted.
+        (WebCore::ImageFrame::zeroFillPixelData): Deleted.
+        (WebCore::ImageFrame::zeroFillFrameRect): Deleted.
+        (WebCore::ImageFrame::initializeBackingStore): Deleted.
+        (WebCore::ImageFrame::hasAlpha): Deleted.
+        (WebCore::ImageFrame::setHasAlpha): Deleted.
+        (WebCore::ImageFrame::setOriginalFrameRect): Deleted.
+        (WebCore::ImageFrame::setStatus): Deleted.
+
+        * platform/image-decoders/ImageDecoder.h:
+        (WebCore::ImageDecoder::repetitionCount): Use the type RepetitionCount and the enum RepetitionCount* values.
+        (WebCore::ImageDecoder::frameOrientationAtIndex): Rename orientationAtIndex() to frameOrientationAtIndex().
+        (WebCore::ImageDecoder::frameAllowSubsamplingAtIndex): Rename allowSubsamplingOfFrameAtIndex() to frameAllowSubsamplingAtIndex().
+        (WebCore::ImageDecoder::subsamplingLevelForScale): Use the enum class SubsamplingLevel value instead of integer values.
+        (WebCore::ImageFrame::ImageFrame): Deleted.
+        (WebCore::ImageFrame::copyRowNTimes): Deleted.
+        (WebCore::ImageFrame::size): Deleted.
+        (WebCore::ImageFrame::asNewNativeImage): Deleted.
+        (WebCore::ImageFrame::backingStore): Deleted.
+        (WebCore::ImageFrame::hasBackingStore): Deleted.
+        (WebCore::ImageFrame::originalFrameRect): Deleted.
+        (WebCore::ImageFrame::status): Deleted.
+        (WebCore::ImageFrame::duration): Deleted.
+        (WebCore::ImageFrame::disposalMethod): Deleted.
+        (WebCore::ImageFrame::setDuration): Deleted.
+        (WebCore::ImageFrame::setDisposalMethod): Deleted.
+        (WebCore::ImageFrame::pixelAt): Deleted.
+        (WebCore::ImageFrame::setPixel): Deleted.
+        (WebCore::ImageFrame::blendPixel): Deleted.
+        (WebCore::ImageDecoder::orientationAtIndex): Deleted.
+        (WebCore::ImageDecoder::allowSubsamplingOfFrameAtIndex): Deleted.
+
+        * platform/image-decoders/bmp/BMPImageDecoder.cpp:
+        (WebCore::BMPImageDecoder::frameBufferAtIndex): Call ImageFrame::isComplete() instead of checking the value of the decoding status().
+        (WebCore::BMPImageDecoder::decode): Ditto.
+
+        * platform/image-decoders/bmp/BMPImageReader.cpp:
+        (WebCore::BMPImageReader::decodeBMP): Call ImageFrame::isEmpty(). ImageBuffer::initializeBackingStore() is renamed to initialize().
+        (WebCore::BMPImageReader::processNonRLEData): Replace ImageFrame::zeroFillPixelData() by ImageBackingStore::clear() and ImageFrame::setAlpha().
+
+        * platform/image-decoders/bmp/BMPImageReader.h:
+        (WebCore::BMPImageReader::setPixel): Call ImageBackingStore::setPixel() directly.
+        (WebCore::BMPImageReader::fillRGBA): Replace an efficient loop to call setPixel() by ImageBackingStore::fillRect().
+
+        * platform/image-decoders/gif/GIFImageDecoder.cpp:
+        (WebCore::GIFImageDecoder::GIFImageDecoder): Move the initialization of m_repetitionCount to the header file.
+        (WebCore::GIFImageDecoder::repetitionCount): Change the return type.
+        (WebCore::GIFImageDecoder::frameBufferAtIndex): Call ImageFrame::isComplete() instead of checking the value of the decoding status().
+        (WebCore::GIFImageDecoder::clearFrameBufferCache): Use the values of the new enum class ImageFrame::DisposalMethod.
+        (WebCore::GIFImageDecoder::haveDecodedRow): Call the ImageBackingStore API's directly.
+        (WebCore::GIFImageDecoder::frameComplete): Use the values of the new enum class ImageFrame::DisposalMethod.
+        (WebCore::GIFImageDecoder::initFrameBuffer): Move calling ImageBackingStore::setFrameRect() to be after initializing the ImageBackingStore itself.
+
+        * platform/image-decoders/gif/GIFImageDecoder.h: Make repetitionCount() returns RepetitionCount and use the new enum class ImageFrame::DisposalMethod.
+        
+        * platform/image-decoders/gif/GIFImageReader.cpp:
+        (GIFImageReader::parse):
+
+        * platform/image-decoders/gif/GIFImageReader.h:
+        (GIFFrameContext::GIFFrameContext): Use new enum class ImageFrame::DisposalMethod.
+        
+        * platform/image-decoders/ico/ICOImageDecoder.cpp:
+        (WebCore::ICOImageDecoder::frameBufferAtIndex): Call ImageFrame::isComplete() instead of checking the value of the decoding status().
+        (WebCore::ICOImageDecoder::decode): Ditto.
+
+        * platform/image-decoders/jpeg/JPEGImageDecoder.cpp:
+        (WebCore::JPEGImageDecoder::frameBufferAtIndex): Call ImageFrame::isComplete() instead of checking the value of the decoding status().
+        (WebCore::setPixel): Call ImageBackingStore::setPixel() directly.
+        (WebCore::JPEGImageDecoder::outputScanlines): ImageFrame::initializeBackingStore() is renamed to initialize().
+        (WebCore::JPEGImageDecoder::jpegComplete): ImageFrame::setStatus() is renamed to ImageFrame::setDecoding().
+        (WebCore::JPEGImageDecoder::decode): Call ImageFrame::isComplete() instead of checking the value of the decoding status().
+
+        * platform/image-decoders/png/PNGImageDecoder.cpp:
+        (WebCore::PNGImageDecoder::frameBufferAtIndex): Call ImageFrame::isComplete() instead of checking the value of the decoding status().
+        (WebCore::PNGImageDecoder::rowAvailable): Call the ImageBackingStore APIs directly.
+        (WebCore::PNGImageDecoder::pngComplete): ImageFrame::setStatus() is renamed to setDecoding().
+        (WebCore::PNGImageDecoder::readChunks): Use the values of the new enum class ImageFrame::DisposalMethod.
+        (WebCore::PNGImageDecoder::clearFrameBufferCache): Replace the call to ImageFrame::clearPixelData() by  ImageFrame::clear().
+        (WebCore::PNGImageDecoder::initFrameBuffer): Move calling ImageBackingStore::setFrameRect() to be after initializing the ImageBackingStore itself.
+        (WebCore::PNGImageDecoder::frameComplete): Call the ImageBackingStore APIs directly.
+
+        * platform/image-decoders/png/PNGImageDecoder.h: Call ImageFrame::isComplete() instead of checking the value of the decoding status().
+
+        * platform/image-decoders/webp/WEBPImageDecoder.cpp:
+        (WebCore::WEBPImageDecoder::frameBufferAtIndex): Call ImageFrame::isComplete() instead of checking the value of the decoding status().
+        (WebCore::WEBPImageDecoder::decode): ImageFrame::setStatus() is renamed to setDecoding(). And initializeBackingStore() is renamed to initialize().
+
</ins><span class="cx"> 2016-09-20  Don Olmstead  &lt;don.olmstead@am.sony.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [WinCairo] Use find_package cairo in build
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (206155 => 206156)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2016-09-20 18:12:54 UTC (rev 206155)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2016-09-20 18:24:41 UTC (rev 206156)
</span><span class="lines">@@ -2268,6 +2268,8 @@
</span><span class="cx">                 550A0BCA085F6039007353D6 /* QualifiedName.h in Headers */ = {isa = PBXBuildFile; fileRef = 550A0BC8085F6039007353D6 /* QualifiedName.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 555B87EC1CAAF0AB00349425 /* ImageDecoderCG.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 555B87EA1CAAF0AB00349425 /* ImageDecoderCG.cpp */; };
</span><span class="cx">                 555B87ED1CAAF0AB00349425 /* ImageDecoderCG.h in Headers */ = {isa = PBXBuildFile; fileRef = 555B87EB1CAAF0AB00349425 /* ImageDecoderCG.h */; };
</span><ins>+                5576A5641D88A70800CCC04C /* ImageFrame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5576A5621D88A70800CCC04C /* ImageFrame.cpp */; };
+                5576A5651D88A70800CCC04C /* ImageFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = 5576A5631D88A70800CCC04C /* ImageFrame.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 55A336F71D8209F40022C4C7 /* NativeImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 55A336F61D8209F40022C4C7 /* NativeImage.h */; };
</span><span class="cx">                 55A336F91D821E3C0022C4C7 /* ImageBackingStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 55A336F81D821E3C0022C4C7 /* ImageBackingStore.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 5709E8CD1D413D47003244AC /* WebKitSubtleCrypto.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5709E8CA1D413CE3003244AC /* WebKitSubtleCrypto.cpp */; };
</span><span class="lines">@@ -9296,6 +9298,8 @@
</span><span class="cx">                 550A0BC8085F6039007353D6 /* QualifiedName.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = QualifiedName.h; sourceTree = &quot;&lt;group&gt;&quot;; tabWidth = 8; usesTabs = 0; };
</span><span class="cx">                 555B87EA1CAAF0AB00349425 /* ImageDecoderCG.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageDecoderCG.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 555B87EB1CAAF0AB00349425 /* ImageDecoderCG.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageDecoderCG.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                5576A5621D88A70800CCC04C /* ImageFrame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageFrame.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                5576A5631D88A70800CCC04C /* ImageFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageFrame.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 55A336F61D8209F40022C4C7 /* NativeImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NativeImage.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 55A336F81D821E3C0022C4C7 /* ImageBackingStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageBackingStore.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 55D408F71A7C631800C78450 /* SVGImageClients.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGImageClients.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -20722,6 +20726,8 @@
</span><span class="cx">                                 43D2597613C816F400608559 /* ImageBuffer.cpp */,
</span><span class="cx">                                 B2A10B910B3818BD00099AA4 /* ImageBuffer.h */,
</span><span class="cx">                                 22BD9F7D1353625C009BD102 /* ImageBufferData.h */,
</span><ins>+                                5576A5621D88A70800CCC04C /* ImageFrame.cpp */,
+                                5576A5631D88A70800CCC04C /* ImageFrame.h */,
</ins><span class="cx">                                 BC7F44A70B9E324E00A9D081 /* ImageObserver.h */,
</span><span class="cx">                                 A8748D7412CC3F89001FBA41 /* ImageOrientation.cpp */,
</span><span class="cx">                                 A8748D6612CC3763001FBA41 /* ImageOrientation.h */,
</span><span class="lines">@@ -27024,6 +27030,7 @@
</span><span class="cx">                                 FE0D84E910484348001A179E /* WebEvent.h in Headers */,
</span><span class="cx">                                 225A16B50D5C11E900090295 /* WebEventRegion.h in Headers */,
</span><span class="cx">                                 A19D93471A9FEC7200B46C24 /* WebFilterEvaluatorSPI.h in Headers */,
</span><ins>+                                5576A5651D88A70800CCC04C /* ImageFrame.h in Headers */,
</ins><span class="cx">                                 D3F3D36E1A69B7E00059FC2B /* WebGL2RenderingContext.h in Headers */,
</span><span class="cx">                                 A7D20F6D107F438B00A80392 /* WebGLActiveInfo.h in Headers */,
</span><span class="cx">                                 1AFFC4581D5E865500267A66 /* WebGLBlacklist.h in Headers */,
</span><span class="lines">@@ -28929,6 +28936,7 @@
</span><span class="cx">                                 E51A81DF17298D7700BFCA61 /* JSPerformance.cpp in Sources */,
</span><span class="cx">                                 CB38FD511CCF938900592A3F /* JSPerformanceEntry.cpp in Sources */,
</span><span class="cx">                                 CB38FD571CD21E2A00592A3F /* JSPerformanceEntryCustom.cpp in Sources */,
</span><ins>+                                5576A5641D88A70800CCC04C /* ImageFrame.cpp in Sources */,
</ins><span class="cx">                                 8A9A587011E84C36008ACFD1 /* JSPerformanceNavigation.cpp in Sources */,
</span><span class="cx">                                 CB38FD5A1CD2325800592A3F /* JSPerformanceResourceTiming.cpp in Sources */,
</span><span class="cx">                                 0F43C85F189E15A600019AE2 /* JSPerformanceTiming.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsBitmapImagecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/BitmapImage.cpp (206155 => 206156)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/BitmapImage.cpp        2016-09-20 18:12:54 UTC (rev 206155)
+++ trunk/Source/WebCore/platform/graphics/BitmapImage.cpp        2016-09-20 18:24:41 UTC (rev 206156)
</span><span class="lines">@@ -68,15 +68,12 @@
</span><span class="cx">     , m_haveFrameCount(true)
</span><span class="cx">     , m_animationFinishedWhenCatchingUp(false)
</span><span class="cx"> {
</span><del>-    // Since we don't have a decoder, we can't figure out the image orientation.
-    // Set m_sizeRespectingOrientation to be the same as m_size so it's not 0x0.
-    m_sizeRespectingOrientation = m_size = nativeImageSize(image);
</del><ins>+    m_frames.grow(1);
+    m_frames[0].initialize(WTFMove(image));
+
+    m_size = m_frames[0].size();
+    m_sizeRespectingOrientation = m_size;
</ins><span class="cx">     m_decodedSize = m_size.area() * 4;
</span><del>-
-    m_frames.grow(1);
-    m_frames[0].m_hasAlpha = nativeImageHasAlpha(image);
-    m_frames[0].m_haveMetadata = true;
-    m_frames[0].m_image = WTFMove(image);
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> BitmapImage::~BitmapImage()
</span><span class="lines">@@ -93,7 +90,7 @@
</span><span class="cx">     if (index &gt;= m_frames.size())
</span><span class="cx">         return false;
</span><span class="cx"> 
</span><del>-    return m_frames[index].m_image;
</del><ins>+    return m_frames[index].hasNativeImage();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void BitmapImage::destroyDecodedData(bool destroyAll)
</span><span class="lines">@@ -108,7 +105,7 @@
</span><span class="cx">         // The underlying frame isn't actually changing (we're just trying to
</span><span class="cx">         // save the memory for the framebuffer data), so we don't need to clear
</span><span class="cx">         // the metadata.
</span><del>-        frameBytesCleared += m_frames[i].clear(false);
</del><ins>+        frameBytesCleared += m_frames[i].clearImage();
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     m_source.clear(destroyAll, clearBeforeFrame, data(), m_allDataReceived);
</span><span class="lines">@@ -132,7 +129,7 @@
</span><span class="cx"> 
</span><span class="cx">     unsigned allFrameBytes = 0;
</span><span class="cx">     for (auto&amp; frame : m_frames)
</span><del>-        allFrameBytes += frame.usedFrameBytes();
</del><ins>+        allFrameBytes += frame.frameBytes();
</ins><span class="cx"> 
</span><span class="cx">     if (allFrameBytes &gt; largeAnimationCutoff) {
</span><span class="cx">         LOG(Images, &quot;BitmapImage %p destroyDecodedDataIfNecessary destroyingData: allFrameBytes=%u cutoff=%u&quot;, this, allFrameBytes, largeAnimationCutoff);
</span><span class="lines">@@ -158,7 +155,7 @@
</span><span class="cx">         imageObserver()-&gt;decodedSizeChanged(this, -safeCast&lt;int&gt;(frameBytesCleared));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void BitmapImage::cacheFrame(size_t index, SubsamplingLevel subsamplingLevel, ImageFrameCaching frameCaching)
</del><ins>+void BitmapImage::cacheFrame(size_t index, SubsamplingLevel subsamplingLevel, ImageFrame::Caching caching)
</ins><span class="cx"> {
</span><span class="cx">     size_t numFrames = frameCount();
</span><span class="cx">     ASSERT(m_decodedSize == 0 || numFrames &gt; 1);
</span><span class="lines">@@ -166,25 +163,16 @@
</span><span class="cx">     if (m_frames.size() &lt; numFrames)
</span><span class="cx">         m_frames.grow(numFrames);
</span><span class="cx"> 
</span><del>-    if (frameCaching == CacheMetadataAndFrame) {
-        m_frames[index].m_image = m_source.createFrameImageAtIndex(index, subsamplingLevel);
-        m_frames[index].m_subsamplingLevel = subsamplingLevel;
-    }
</del><ins>+    if (caching == ImageFrame::Caching::MetadataAndImage) {
+        NativeImagePtr image = m_source.createFrameImageAtIndex(index, subsamplingLevel);
+        m_frames[index].initialize(WTFMove(image), *m_source.decoder(), index, subsamplingLevel, repetitionCount(false));
+    } else
+        m_frames[index].initialize(nullptr, *m_source.decoder(), index, subsamplingLevel, repetitionCount(false));
</ins><span class="cx"> 
</span><del>-    m_frames[index].m_orientation = m_source.orientationAtIndex(index);
-    m_frames[index].m_haveMetadata = true;
-    m_frames[index].m_isComplete = m_source.frameIsCompleteAtIndex(index);
</del><ins>+    LOG(Images, &quot;BitmapImage %p cacheFrame %lu (%s%u bytes, complete %d)&quot;, this, index, caching == ImageFrame::Caching::Metadata ? &quot;metadata only, &quot; : &quot;&quot;, m_frames[index].frameBytes(), m_frames[index].isComplete());
</ins><span class="cx"> 
</span><del>-    if (repetitionCount(false) != cAnimationNone)
-        m_frames[index].m_duration = m_source.frameDurationAtIndex(index);
-
-    m_frames[index].m_hasAlpha = m_source.frameHasAlphaAtIndex(index);
-    m_frames[index].m_frameBytes = m_source.frameBytesAtIndex(index, subsamplingLevel);
-
-    LOG(Images, &quot;BitmapImage %p cacheFrame %lu (%s%u bytes, complete %d)&quot;, this, index, frameCaching == CacheMetadataOnly ? &quot;metadata only, &quot; : &quot;&quot;, m_frames[index].m_frameBytes, m_frames[index].m_isComplete);
-
-    if (m_frames[index].m_image) {
-        int deltaBytes = safeCast&lt;int&gt;(m_frames[index].m_frameBytes);
</del><ins>+    if (m_frames[index].hasNativeImage()) {
+        int deltaBytes = safeCast&lt;int&gt;(m_frames[index].frameBytes());
</ins><span class="cx">         m_decodedSize += deltaBytes;
</span><span class="cx">         // The fully-decoded frame will subsume the partially decoded data used
</span><span class="cx">         // to determine image properties.
</span><span class="lines">@@ -273,8 +261,8 @@
</span><span class="cx">         // NOTE: Don't call frameIsCompleteAtIndex() here, that will try to
</span><span class="cx">         // decode any uncached (i.e. never-decoded or
</span><span class="cx">         // cleared-on-a-previous-pass) frames!
</span><del>-        if (frame.m_haveMetadata &amp;&amp; !frame.m_isComplete)
-            frameBytesCleared += frame.clear(true);
</del><ins>+        if (frame.hasMetadata() &amp;&amp; !frame.isComplete())
+            frameBytesCleared += frame.clear();
</ins><span class="cx">     }
</span><span class="cx">     destroyMetadataAndNotify(frameBytesCleared, ClearedSource::No);
</span><span class="cx"> #else
</span><span class="lines">@@ -281,7 +269,7 @@
</span><span class="cx">     // FIXME: why is this different for iOS?
</span><span class="cx">     int deltaBytes = 0;
</span><span class="cx">     if (!m_frames.isEmpty()) {
</span><del>-        if (int bytes = m_frames[m_frames.size() - 1].clear(true)) {
</del><ins>+        if (int bytes = m_frames[m_frames.size() - 1].clear()) {
</ins><span class="cx">             deltaBytes += bytes;
</span><span class="cx">             deltaBytes += m_decodedPropertiesSize;
</span><span class="cx">             m_decodedPropertiesSize = 0;
</span><span class="lines">@@ -340,15 +328,15 @@
</span><span class="cx">     return m_sizeAvailable;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool BitmapImage::ensureFrameAtIndexIsCached(size_t index, ImageFrameCaching frameCaching)
</del><ins>+bool BitmapImage::ensureFrameAtIndexIsCached(size_t index, ImageFrame::Caching caching)
</ins><span class="cx"> {
</span><span class="cx">     if (index &gt;= frameCount())
</span><span class="cx">         return false;
</span><span class="cx"> 
</span><span class="cx">     if (index &gt;= m_frames.size()
</span><del>-        || (frameCaching == CacheMetadataAndFrame &amp;&amp; !m_frames[index].m_image)
-        || (frameCaching == CacheMetadataOnly &amp;&amp; !m_frames[index].m_haveMetadata))
-        cacheFrame(index, 0, frameCaching);
</del><ins>+        || (caching == ImageFrame::Caching::MetadataAndImage &amp;&amp; !m_frames[index].hasNativeImage())
+        || (caching == ImageFrame::Caching::Metadata &amp;&amp; !m_frames[index].hasMetadata()))
+        cacheFrame(index, SubsamplingLevel::Default, caching);
</ins><span class="cx"> 
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="lines">@@ -364,11 +352,11 @@
</span><span class="cx"> 
</span><span class="cx">     // We may have cached a frame with a higher subsampling level, in which case we need to
</span><span class="cx">     // re-decode with a lower level.
</span><del>-    if (index &lt; m_frames.size() &amp;&amp; m_frames[index].m_image &amp;&amp; subsamplingLevel &lt; m_frames[index].m_subsamplingLevel) {
-        LOG(Images, &quot;  subsamplingLevel was %d, resampling&quot;, m_frames[index].m_subsamplingLevel);
</del><ins>+    if (index &lt; m_frames.size() &amp;&amp; m_frames[index].hasInvalidNativeImage(subsamplingLevel)) {
+        LOG(Images, &quot;  subsamplingLevel was %d, resampling&quot;, m_frames[index].subsamplingLevel());
</ins><span class="cx"> 
</span><span class="cx">         // If the image is already cached, but at too small a size, re-decode a larger version.
</span><del>-        int sizeChange = -m_frames[index].clear(true);
</del><ins>+        int sizeChange = -m_frames[index].clear();
</ins><span class="cx">         invalidatePlatformData();
</span><span class="cx">         m_decodedSize += sizeChange;
</span><span class="cx">         if (imageObserver())
</span><span class="lines">@@ -376,10 +364,10 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // If we haven't fetched a frame yet, do so.
</span><del>-    if (index &gt;= m_frames.size() || !m_frames[index].m_image)
-        cacheFrame(index, subsamplingLevel, CacheMetadataAndFrame);
</del><ins>+    if (index &gt;= m_frames.size() || !m_frames[index].hasNativeImage())
+        cacheFrame(index, subsamplingLevel, ImageFrame::Caching::MetadataAndImage);
</ins><span class="cx"> 
</span><del>-    return m_frames[index].m_image;
</del><ins>+    return m_frames[index].nativeImage();
</ins><span class="cx"> }
</span><span class="cx">     
</span><span class="cx"> NativeImagePtr BitmapImage::nativeImage()
</span><span class="lines">@@ -423,27 +411,27 @@
</span><span class="cx"> 
</span><span class="cx"> bool BitmapImage::frameIsCompleteAtIndex(size_t index)
</span><span class="cx"> {
</span><del>-    if (!ensureFrameAtIndexIsCached(index, CacheMetadataOnly))
</del><ins>+    if (!ensureFrameAtIndexIsCached(index, ImageFrame::Caching::Metadata))
</ins><span class="cx">         return false;
</span><span class="cx"> 
</span><del>-    return m_frames[index].m_isComplete;
</del><ins>+    return m_frames[index].isComplete();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> float BitmapImage::frameDurationAtIndex(size_t index)
</span><span class="cx"> {
</span><del>-    if (!ensureFrameAtIndexIsCached(index, CacheMetadataOnly))
</del><ins>+    if (!ensureFrameAtIndexIsCached(index, ImageFrame::Caching::Metadata))
</ins><span class="cx">         return 0;
</span><span class="cx"> 
</span><del>-    return m_frames[index].m_duration;
</del><ins>+    return m_frames[index].duration();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool BitmapImage::frameHasAlphaAtIndex(size_t index)
</span><span class="cx"> {
</span><del>-    if (!ensureFrameAtIndexIsCached(index, CacheMetadataOnly))
</del><ins>+    if (!ensureFrameAtIndexIsCached(index, ImageFrame::Caching::Metadata))
</ins><span class="cx">         return true;
</span><span class="cx"> 
</span><del>-    if (m_frames[index].m_haveMetadata)
-        return m_frames[index].m_hasAlpha;
</del><ins>+    if (m_frames[index].hasMetadata())
+        return m_frames[index].hasAlpha();
</ins><span class="cx"> 
</span><span class="cx">     return m_source.frameHasAlphaAtIndex(index);
</span><span class="cx"> }
</span><span class="lines">@@ -455,13 +443,13 @@
</span><span class="cx"> 
</span><span class="cx"> ImageOrientation BitmapImage::frameOrientationAtIndex(size_t index)
</span><span class="cx"> {
</span><del>-    if (!ensureFrameAtIndexIsCached(index, CacheMetadataOnly))
</del><ins>+    if (!ensureFrameAtIndexIsCached(index, ImageFrame::Caching::Metadata))
</ins><span class="cx">         return ImageOrientation();
</span><span class="cx"> 
</span><del>-    if (m_frames[index].m_haveMetadata)
-        return m_frames[index].m_orientation;
</del><ins>+    if (m_frames[index].hasMetadata())
+        return m_frames[index].orientation();
</ins><span class="cx"> 
</span><del>-    return m_source.orientationAtIndex(index);
</del><ins>+    return m_source.frameOrientationAtIndex(index);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> Color BitmapImage::singlePixelSolidColor()
</span><span class="lines">@@ -484,7 +472,7 @@
</span><span class="cx">         return Color();
</span><span class="cx"> 
</span><span class="cx">     ASSERT(m_frames.size());
</span><del>-    m_solidColor = nativeImageSinglePixelSolidColor(m_frames[0].m_image);
</del><ins>+    m_solidColor = nativeImageSinglePixelSolidColor(m_frames[0].nativeImage());
</ins><span class="cx">     
</span><span class="cx">     ASSERT(m_solidColor);
</span><span class="cx">     return m_solidColor.value();
</span><span class="lines">@@ -497,16 +485,16 @@
</span><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-int BitmapImage::repetitionCount(bool imageKnownToBeComplete)
</del><ins>+RepetitionCount BitmapImage::repetitionCount(bool imageKnownToBeComplete)
</ins><span class="cx"> {
</span><span class="cx">     if ((m_repetitionCountStatus == Unknown) || ((m_repetitionCountStatus == Uncertain) &amp;&amp; imageKnownToBeComplete)) {
</span><span class="cx">         // Snag the repetition count. If |imageKnownToBeComplete| is false, the
</span><span class="cx">         // repetition count may not be accurate yet for GIFs; in this case the
</span><del>-        // decoder will default to cAnimationLoopOnce, and we'll try and read
</del><ins>+        // decoder will default to RepetitionCountOnce, and we'll try and read
</ins><span class="cx">         // the count again once the whole image is decoded.
</span><span class="cx">         m_repetitionCount = m_source.repetitionCount();
</span><span class="cx">         didDecodeProperties();
</span><del>-        m_repetitionCountStatus = (imageKnownToBeComplete || m_repetitionCount == cAnimationNone) ? Certain : Uncertain;
</del><ins>+        m_repetitionCountStatus = (imageKnownToBeComplete || m_repetitionCount == RepetitionCountNone) ? Certain : Uncertain;
</ins><span class="cx">     }
</span><span class="cx">     return m_repetitionCount;
</span><span class="cx"> }
</span><span class="lines">@@ -578,7 +566,7 @@
</span><span class="cx"> 
</span><span class="cx"> bool BitmapImage::shouldAnimate()
</span><span class="cx"> {
</span><del>-    return (repetitionCount(false) != cAnimationNone &amp;&amp; !m_animationFinished &amp;&amp; imageObserver());
</del><ins>+    return repetitionCount(false) &amp;&amp; !m_animationFinished &amp;&amp; imageObserver();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool BitmapImage::canAnimate()
</span><span class="lines">@@ -617,7 +605,7 @@
</span><span class="cx">     // yet and our repetition count is potentially unset. The repetition count
</span><span class="cx">     // in a GIF can potentially come after all the rest of the image data, so
</span><span class="cx">     // wait on it.
</span><del>-    if (!m_allDataReceived &amp;&amp; repetitionCount(false) == cAnimationLoopOnce &amp;&amp; m_currentFrame &gt;= (frameCount() - 1))
</del><ins>+    if (!m_allDataReceived &amp;&amp; repetitionCount(false) == RepetitionCountOnce &amp;&amp; m_currentFrame &gt;= (frameCount() - 1))
</ins><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     // Determine time for next frame to start. By ignoring paint and timer lag
</span><span class="lines">@@ -722,9 +710,7 @@
</span><span class="cx">         // Get the repetition count again. If we weren't able to get a
</span><span class="cx">         // repetition count before, we should have decoded the whole image by
</span><span class="cx">         // now, so it should now be available.
</span><del>-        // Note that we don't need to special-case cAnimationLoopOnce here
-        // because it is 0 (see comments on its declaration in ImageSource.h).
-        if (repetitionCount(true) != cAnimationLoopInfinite &amp;&amp; m_repetitionsComplete &gt; m_repetitionCount) {
</del><ins>+        if (repetitionCount(true) != RepetitionCountInfinite &amp;&amp; m_repetitionsComplete &gt; m_repetitionCount) {
</ins><span class="cx">             m_animationFinished = true;
</span><span class="cx">             m_desiredFrameStartTime = 0;
</span><span class="cx">             --m_currentFrame;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsBitmapImageh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/BitmapImage.h (206155 => 206156)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/BitmapImage.h        2016-09-20 18:12:54 UTC (rev 206155)
+++ trunk/Source/WebCore/platform/graphics/BitmapImage.h        2016-09-20 18:24:41 UTC (rev 206156)
</span><span class="lines">@@ -50,53 +50,6 @@
</span><span class="cx"> 
</span><span class="cx"> class Timer;
</span><span class="cx"> 
</span><del>-// ================================================
-// FrameData Class
-// ================================================
-
-struct FrameData {
-public:
-    FrameData()
-        : m_haveMetadata(false)
-        , m_isComplete(false)
-        , m_hasAlpha(false)
-    {
-    }
-
-    ~FrameData()
-    {
-        clearNativeImageSubImages(m_image);
-    }
-
-    unsigned clear(bool clearMetadata)
-    {
-        unsigned frameBytes = usedFrameBytes();
-        
-        if (clearMetadata)
-            m_haveMetadata = false;
-
-        m_subsamplingLevel = DefaultSubsamplingLevel;
-        m_image = nullptr;
-
-        return frameBytes;
-    }
-    
-    unsigned usedFrameBytes() const { return m_image ? m_frameBytes : 0; }
-
-    NativeImagePtr m_image;
-    ImageOrientation m_orientation { DefaultImageOrientation };
-    SubsamplingLevel m_subsamplingLevel { DefaultSubsamplingLevel };
-    float m_duration { 0 };
-    bool m_haveMetadata : 1;
-    bool m_isComplete : 1;
-    bool m_hasAlpha : 1;
-    unsigned m_frameBytes { 0 };
-};
-
-// =================================================
-// BitmapImage Class
-// =================================================
-
</del><span class="cx"> class BitmapImage final : public Image {
</span><span class="cx"> public:
</span><span class="cx">     static Ref&lt;BitmapImage&gt; create(NativeImagePtr&amp;&amp; nativeImage, ImageObserver* observer = nullptr)
</span><span class="lines">@@ -212,11 +165,10 @@
</span><span class="cx">     ImageOrientation frameOrientationAtIndex(size_t);
</span><span class="cx"> 
</span><span class="cx">     // Decodes and caches a frame. Never accessed except internally.
</span><del>-    enum ImageFrameCaching { CacheMetadataOnly, CacheMetadataAndFrame };
-    void cacheFrame(size_t index, SubsamplingLevel, ImageFrameCaching = CacheMetadataAndFrame);
</del><ins>+    void cacheFrame(size_t index, SubsamplingLevel, ImageFrame::Caching = ImageFrame::Caching::MetadataAndImage);
</ins><span class="cx"> 
</span><span class="cx">     // Called before accessing m_frames[index] for info without decoding. Returns false on index out of bounds.
</span><del>-    bool ensureFrameAtIndexIsCached(size_t index, ImageFrameCaching = CacheMetadataAndFrame);
</del><ins>+    bool ensureFrameAtIndexIsCached(size_t index, ImageFrame::Caching = ImageFrame::Caching::MetadataAndImage);
</ins><span class="cx"> 
</span><span class="cx">     // Called to invalidate cached data. When |destroyAll| is true, we wipe out
</span><span class="cx">     // the entire frame buffer cache and tell the image source to destroy
</span><span class="lines">@@ -246,7 +198,7 @@
</span><span class="cx">     void didDecodeProperties() const;
</span><span class="cx"> 
</span><span class="cx">     // Animation.
</span><del>-    int repetitionCount(bool imageKnownToBeComplete);  // |imageKnownToBeComplete| should be set if the caller knows the entire image has been decoded.
</del><ins>+    RepetitionCount repetitionCount(bool imageKnownToBeComplete); // |imageKnownToBeComplete| should be set if the caller knows the entire image has been decoded.
</ins><span class="cx">     bool shouldAnimate();
</span><span class="cx">     void startAnimation(CatchUpAnimation = CatchUp) override;
</span><span class="cx">     void advanceAnimation();
</span><span class="lines">@@ -279,12 +231,12 @@
</span><span class="cx">     mutable IntSize m_sizeRespectingOrientation;
</span><span class="cx"> 
</span><span class="cx">     size_t m_currentFrame { 0 }; // The index of the current frame of animation.
</span><del>-    Vector&lt;FrameData, 1&gt; m_frames; // An array of the cached frames of the animation. We have to ref frames to pin them in the cache.
</del><ins>+    Vector&lt;ImageFrame, 1&gt; m_frames; // An array of the cached frames of the animation. We have to ref frames to pin them in the cache.
</ins><span class="cx"> 
</span><span class="cx">     std::unique_ptr&lt;Timer&gt; m_frameTimer;
</span><del>-    int m_repetitionCount { cAnimationNone }; // How many total animation loops we should do. This will be cAnimationNone if this image type is incapable of animation.
</del><ins>+    RepetitionCount m_repetitionCount { RepetitionCountNone }; // How many total animation loops we should do. This will be cAnimationNone if this image type is incapable of animation.
</ins><span class="cx">     RepetitionCountStatus m_repetitionCountStatus { Unknown };
</span><del>-    int m_repetitionsComplete { 0 }; // How many repetitions we've finished.
</del><ins>+    RepetitionCount m_repetitionsComplete { RepetitionCountNone }; // How many repetitions we've finished.
</ins><span class="cx">     double m_desiredFrameStartTime { 0 }; // The system time at which we hope to see the next call to startAnimation().
</span><span class="cx"> 
</span><span class="cx"> #if USE(APPKIT)
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsImageBackingStoreh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/ImageBackingStore.h (206155 => 206156)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/ImageBackingStore.h        2016-09-20 18:12:54 UTC (rev 206155)
+++ trunk/Source/WebCore/platform/graphics/ImageBackingStore.h        2016-09-20 18:24:41 UTC (rev 206156)
</span><span class="lines">@@ -90,6 +90,20 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    void fillRect(const IntRect &amp;rect, unsigned r, unsigned g, unsigned b, unsigned a)
+    {
+        if (rect.isEmpty() || !inBounds(rect))
+            return;
+
+        RGBA32* start = pixelAt(rect.x(), rect.y());
+        RGBA32 pixelValue = this-&gt;pixelValue(r, g, b, a);
+        for (int i = 0; i &lt; rect.height(); ++i) {
+            for (int j = 0; j &lt; rect.width(); ++j)
+                start[j] = pixelValue;
+            start += m_size.width();
+        }
+    }
+
</ins><span class="cx">     void repeatFirstRow(const IntRect&amp; rect)
</span><span class="cx">     {
</span><span class="cx">         if (rect.isEmpty() || !inBounds(rect))
</span><span class="lines">@@ -106,24 +120,22 @@
</span><span class="cx"> 
</span><span class="cx">     RGBA32* pixelAt(int x, int y) const
</span><span class="cx">     {
</span><ins>+        ASSERT(inBounds(IntPoint(x, y)));
</ins><span class="cx">         return m_pixelsPtr + y * m_size.width() + x;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    void setPixel(int x, int y, unsigned r, unsigned g, unsigned b, unsigned a)
</del><ins>+    void setPixel(RGBA32* dest, unsigned r, unsigned g, unsigned b, unsigned a)
</ins><span class="cx">     {
</span><del>-        setPixel(pixelAt(x, y), r, g, b, a);
</del><ins>+        ASSERT(dest);
+        *dest = pixelValue(r, g, b, a);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    void setPixel(RGBA32* dest, unsigned r, unsigned g, unsigned b, unsigned a)
</del><ins>+    void setPixel(int x, int y, unsigned r, unsigned g, unsigned b, unsigned a)
</ins><span class="cx">     {
</span><del>-        if (m_premultiplyAlpha &amp;&amp; !a)
-            *dest = 0;
-        else if (m_premultiplyAlpha &amp;&amp; a &lt; 255)
-            *dest = makePremultipliedRGBA(r, g, b, a);
-        else
-            *dest = makeRGBA(r, g, b, a);
</del><ins>+        setPixel(pixelAt(x, y), r, g, b, a);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><ins>+#if ENABLE(APNG)
</ins><span class="cx">     void blendPixel(RGBA32* dest, unsigned r, unsigned g, unsigned b, unsigned a)
</span><span class="cx">     {
</span><span class="cx">         if (!a)
</span><span class="lines">@@ -149,12 +161,8 @@
</span><span class="cx">         else
</span><span class="cx">             *dest = makeUnPremultipliedRGBA(r, g, b, a);
</span><span class="cx">     }
</span><ins>+#endif
</ins><span class="cx"> 
</span><del>-    bool inBounds(const IntRect&amp; rect) const
-    {
-        return IntRect(IntPoint(), m_size).contains(rect);
-    }
-
</del><span class="cx">     static bool isOverSize(const IntSize&amp; size)
</span><span class="cx">     {
</span><span class="cx">         static unsigned long long MaxPixels = ((1 &lt;&lt; 29) - 1);
</span><span class="lines">@@ -179,6 +187,27 @@
</span><span class="cx">         m_pixelsPtr = m_pixels.data();
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    bool inBounds(const IntPoint&amp; point) const
+    {
+        return IntRect(IntPoint(), m_size).contains(point);
+    }
+
+    bool inBounds(const IntRect&amp; rect) const
+    {
+        return IntRect(IntPoint(), m_size).contains(rect);
+    }
+
+    RGBA32 pixelValue(unsigned r, unsigned g, unsigned b, unsigned a) const
+    {
+        if (m_premultiplyAlpha &amp;&amp; !a)
+            return 0;
+
+        if (m_premultiplyAlpha &amp;&amp; a &lt; 255)
+            return makePremultipliedRGBA(r, g, b, a);
+
+        return makeRGBA(r, g, b, a);
+    }
+
</ins><span class="cx">     Vector&lt;RGBA32&gt; m_pixels;
</span><span class="cx">     RGBA32* m_pixelsPtr { nullptr };
</span><span class="cx">     IntSize m_size;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsImageFramecpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/platform/graphics/ImageFrame.cpp (0 => 206156)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/ImageFrame.cpp                                (rev 0)
+++ trunk/Source/WebCore/platform/graphics/ImageFrame.cpp        2016-09-20 18:24:41 UTC (rev 206156)
</span><span class="lines">@@ -0,0 +1,165 @@
</span><ins>+/*
+ * Copyright (C) 2016 Apple Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    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 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 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
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include &quot;config.h&quot;
+#include &quot;ImageFrame.h&quot;
+
+#if USE(CG)
+#include &quot;ImageDecoderCG.h&quot;
+#else
+#include &quot;ImageDecoder.h&quot;
+#endif
+
+namespace WebCore {
+
+ImageFrame::ImageFrame()
+{
+}
+
+ImageFrame::~ImageFrame()
+{
+    clearImage();
+}
+
+ImageFrame&amp; ImageFrame::operator=(const ImageFrame&amp; other)
+{
+    if (this == &amp;other)
+        return *this;
+
+    m_decoding = other.m_decoding;
+    m_size = other.m_size;
+
+#if !USE(CG)
+    if (other.backingStore())
+        initialize(*other.backingStore());
+    else
+        m_backingStore = nullptr;
+    m_disposalMethod = other.m_disposalMethod;
+#endif
+
+    m_nativeImage = other.m_nativeImage;
+    m_subsamplingLevel = other.m_subsamplingLevel;
+
+    m_orientation = other.m_orientation;
+    m_duration = other.m_duration;
+    m_hasAlpha = other.m_hasAlpha;
+    return *this;
+}
+
+void ImageFrame::fillMetadata(ImageDecoder&amp; decoder, size_t index, SubsamplingLevel subsamplingLevel, bool animating)
+{
+    m_decoding = decoder.frameIsCompleteAtIndex(index) ? Decoding::Complete : Decoding::Partial;
+    m_size = decoder.frameSizeAtIndex(index, subsamplingLevel);
+
+    m_subsamplingLevel = subsamplingLevel;
+
+    m_orientation = decoder.frameOrientationAtIndex(index);
+    if (animating)
+        m_duration = decoder.frameDurationAtIndex(index);
+    m_hasAlpha = decoder.frameHasAlphaAtIndex(index);
+}
+
+unsigned ImageFrame::clearImage()
+{
+#if !USE(CG)
+    if (hasBackingStore())
+        m_backingStore = nullptr;
+#endif
+
+    if (!hasNativeImage())
+        return 0;
+
+    unsigned frameBytes = this-&gt;frameBytes();
+
+    clearNativeImageSubimages(m_nativeImage);
+    m_nativeImage = nullptr;
+
+    return frameBytes;
+}
+
+unsigned ImageFrame::clear()
+{
+    unsigned frameBytes = clearImage();
+    *this = ImageFrame();
+    return frameBytes;
+}
+
+void ImageFrame::initialize(NativeImagePtr&amp;&amp; nativeImage, ImageDecoder&amp; decoder, size_t index, SubsamplingLevel subsamplingLevel, bool animating)
+{
+    m_nativeImage = WTFMove(nativeImage);
+
+    if (!hasMetadata())
+        fillMetadata(decoder, index, subsamplingLevel, animating);
+    else if (!isComplete())
+        m_decoding = decoder.frameIsCompleteAtIndex(index) ? Decoding::Complete : Decoding::Partial;
+}
+
+void ImageFrame::initialize(NativeImagePtr&amp;&amp; nativeImage)
+{
+    m_nativeImage = WTFMove(nativeImage);
+
+    m_decoding = Decoding::Complete;
+    m_size = nativeImageSize(m_nativeImage);
+    m_hasAlpha = nativeImageHasAlpha(m_nativeImage);
+}
+
+#if !USE(CG)
+bool ImageFrame::initialize(const ImageBackingStore&amp; backingStore)
+{
+    if (&amp;backingStore == this-&gt;backingStore())
+        return true;
+
+    m_backingStore = ImageBackingStore::create(backingStore);
+    return m_backingStore != nullptr;
+}
+
+bool ImageFrame::initialize(const IntSize&amp; size, bool premultiplyAlpha)
+{
+    if (size.isEmpty())
+        return false;
+
+    m_backingStore = ImageBackingStore::create(size, premultiplyAlpha);
+    return m_backingStore != nullptr;
+}
+#endif
+
+IntSize ImageFrame::size() const
+{
+#if !USE(CG)
+    if (hasBackingStore())
+        return backingStore()-&gt;size();
+#endif
+    return m_size;
+}
+
+Color ImageFrame::singlePixelSolidColor() const
+{
+    if (!hasNativeImage() || m_size != IntSize(1, 1))
+        return Color();
+
+    return nativeImageSinglePixelSolidColor(m_nativeImage);
+}
+
+}
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsImageFrameh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/platform/graphics/ImageFrame.h (0 => 206156)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/ImageFrame.h                                (rev 0)
+++ trunk/Source/WebCore/platform/graphics/ImageFrame.h        2016-09-20 18:24:41 UTC (rev 206156)
</span><span class="lines">@@ -0,0 +1,151 @@
</span><ins>+/*
+ * Copyright (C) 2016 Apple Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    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 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 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
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include &quot;Color.h&quot;
+#include &quot;ImageBackingStore.h&quot;
+#include &quot;ImageOrientation.h&quot;
+#include &quot;IntSize.h&quot;
+#include &quot;NativeImage.h&quot;
+
+namespace WebCore {
+
+class Color;
+class ImageDecoder;
+
+// There are four subsampling levels: 0 = 1x, 1 = 0.5x, 2 = 0.25x, 3 = 0.125x.
+enum class SubsamplingLevel {
+    Undefinded = -1,
+    First = 0,
+    Default = First,
+    Level0 = First,
+    Level1,
+    Level2,
+    Level3,
+    Last = Level3,
+    Max
+};
+
+inline SubsamplingLevel&amp; operator++(SubsamplingLevel&amp; subsamplingLevel)
+{
+    subsamplingLevel = static_cast&lt;SubsamplingLevel&gt;(static_cast&lt;int&gt;(subsamplingLevel) + 1);
+    ASSERT(subsamplingLevel &lt;= SubsamplingLevel::Max);
+    return subsamplingLevel;
+}
+
+typedef int RepetitionCount;
+
+enum {
+    RepetitionCountNone = 0,
+    RepetitionCountOnce = 1,
+    RepetitionCountInfinite = -1,
+};
+
+class ImageFrame {
+public:
+    enum class Caching { Empty, Metadata, MetadataAndImage };
+    enum class Decoding { Empty, Partial, Complete };
+
+    ImageFrame();
+    ImageFrame(NativeImagePtr&amp;&amp;);
+    ImageFrame(const ImageFrame&amp; other) { operator=(other); }
+
+    ~ImageFrame();
+
+    ImageFrame&amp; operator=(const ImageFrame&amp; other);
+
+    unsigned clearImage();
+    unsigned clear();
+
+    // FIXME: Calling ImageDecoder::repetitionCount() is expensive to be done for every frame.
+    // Remove the 'animating' flag from this function when calling repetitionCount() is cheap
+    // because it will be cached by ImageDecoder or a sub-class of it.
+    void initialize(NativeImagePtr&amp;&amp;, ImageDecoder&amp;, size_t, SubsamplingLevel, bool animating);
+    void initialize(NativeImagePtr&amp;&amp;);
+#if !USE(CG)
+    bool initialize(const ImageBackingStore&amp;);
+    bool initialize(const IntSize&amp;, bool premultiplyAlpha);
+#endif
+
+    void setDecoding(Decoding decoding) { m_decoding = decoding; }
+    Decoding decoding() const { return m_decoding; }
+    bool isEmpty() const { return m_decoding == Decoding::Empty; }
+    bool isPartial() const { return m_decoding == Decoding::Partial; }
+    bool isComplete() const { return m_decoding == Decoding::Complete; }
+
+    IntSize size() const;
+    IntSize sizeRespectingOrientation() const { return !m_orientation.usesWidthAsHeight() ? size() : size().transposedSize(); }
+    unsigned frameBytes() const { return hasNativeImage() ? size().area() * sizeof(RGBA32) : 0; }
+    SubsamplingLevel subsamplingLevel() const { return m_subsamplingLevel; }
+
+#if !USE(CG)
+    enum class DisposalMethod { Unspecified, DoNotDispose, RestoreToBackground, RestoreToPrevious };
+    void setDisposalMethod(DisposalMethod method) { m_disposalMethod = method; }
+    DisposalMethod disposalMethod() const { return m_disposalMethod; }
+#endif
+
+    NativeImagePtr nativeImage() const { return m_nativeImage; }
+
+    void setOrientation(ImageOrientation orientation) { m_orientation = orientation; };
+    ImageOrientation orientation() const { return m_orientation; }
+
+    void setDuration(unsigned duration) { m_duration = duration; }
+    float duration() const { return m_duration; }
+
+    void setHasAlpha(bool hasAlpha) { m_hasAlpha = hasAlpha; }
+    bool hasAlpha() const { return m_hasAlpha; }
+
+    bool hasNativeImage() const { return m_nativeImage; }
+    bool hasInvalidNativeImage(SubsamplingLevel subsamplingLevel) const { return hasNativeImage() &amp;&amp; subsamplingLevel &lt; m_subsamplingLevel; }
+    bool hasMetadata() const { return !size().isEmpty(); }
+
+#if !USE(CG)
+    ImageBackingStore* backingStore() const { return m_backingStore ? m_backingStore.get() : nullptr; }
+    bool hasBackingStore() const { return backingStore(); }
+#endif
+
+    Color singlePixelSolidColor() const;
+
+private:
+    void fillMetadata(ImageDecoder&amp;, size_t, SubsamplingLevel, bool animating);
+
+    Decoding m_decoding { Decoding::Empty };
+    IntSize m_size;
+
+#if !USE(CG)
+    std::unique_ptr&lt;ImageBackingStore&gt; m_backingStore;
+    DisposalMethod m_disposalMethod { DisposalMethod::Unspecified };
+#endif
+
+    NativeImagePtr m_nativeImage;
+    SubsamplingLevel m_subsamplingLevel { SubsamplingLevel::Default };
+
+    ImageOrientation m_orientation { DefaultImageOrientation };
+    float m_duration { 0 };
+    bool m_hasAlpha { true };
+};
+
+}
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsImageSourcecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/ImageSource.cpp (206155 => 206156)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/ImageSource.cpp        2016-09-20 18:12:54 UTC (rev 206155)
+++ trunk/Source/WebCore/platform/graphics/ImageSource.cpp        2016-09-20 18:24:41 UTC (rev 206156)
</span><span class="lines">@@ -93,8 +93,8 @@
</span><span class="cx"> 
</span><span class="cx"> SubsamplingLevel ImageSource::calculateMaximumSubsamplingLevel() const
</span><span class="cx"> {
</span><del>-    if (!m_allowSubsampling || !allowSubsamplingOfFrameAtIndex(0))
-        return DefaultSubsamplingLevel;
</del><ins>+    if (!m_allowSubsampling || !frameAllowSubsamplingAtIndex(0))
+        return SubsamplingLevel::Default;
</ins><span class="cx">     
</span><span class="cx">     // FIXME: this value was chosen to be appropriate for iOS since the image
</span><span class="cx">     // subsampling is only enabled by default on iOS. Choose a different value
</span><span class="lines">@@ -101,12 +101,12 @@
</span><span class="cx">     // if image subsampling is enabled on other platform.
</span><span class="cx">     const int maximumImageAreaBeforeSubsampling = 5 * 1024 * 1024;
</span><span class="cx"> 
</span><del>-    for (SubsamplingLevel level = MinSubsamplingLevel; level &lt; MaxSubsamplingLevel; ++level) {
</del><ins>+    for (SubsamplingLevel level = SubsamplingLevel::First; level &lt;= SubsamplingLevel::Last; ++level) {
</ins><span class="cx">         if (frameSizeAtIndex(0, level).area() &lt; maximumImageAreaBeforeSubsampling)
</span><span class="cx">             return level;
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    return MaxSubsamplingLevel;
</del><ins>+    return SubsamplingLevel::Last;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void ImageSource::updateMetadata()
</span><span class="lines">@@ -124,15 +124,14 @@
</span><span class="cx"> SubsamplingLevel ImageSource::subsamplingLevelForScale(float scale)
</span><span class="cx"> {
</span><span class="cx">     if (!(scale &gt; 0 &amp;&amp; scale &lt;= 1))
</span><del>-        return 0;
</del><ins>+        return SubsamplingLevel::Default;
</ins><span class="cx"> 
</span><span class="cx">     updateMetadata();
</span><span class="cx">     if (!m_maximumSubsamplingLevel)
</span><del>-        return 0;
</del><ins>+        return SubsamplingLevel::Default;
</ins><span class="cx"> 
</span><del>-    // There are four subsampling levels: 0 = 1x, 1 = 0.5x, 2 = 0.25x, 3 = 0.125x.
-    SubsamplingLevel result = std::ceil(std::log2(1 / scale));
-    return std::min(result, m_maximumSubsamplingLevel.value());
</del><ins>+    int result = std::ceil(std::log2(1 / scale));
+    return static_cast&lt;SubsamplingLevel&gt;(std::min(result, static_cast&lt;int&gt;(m_maximumSubsamplingLevel.value())));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> size_t ImageSource::bytesDecodedToDetermineProperties()
</span><span class="lines">@@ -147,12 +146,12 @@
</span><span class="cx"> 
</span><span class="cx"> IntSize ImageSource::size() const
</span><span class="cx"> {
</span><del>-    return frameSizeAtIndex(0, DefaultSubsamplingLevel);
</del><ins>+    return frameSizeAtIndex(0, SubsamplingLevel::Default);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> IntSize ImageSource::sizeRespectingOrientation() const
</span><span class="cx"> {
</span><del>-    return frameSizeAtIndex(0, DefaultSubsamplingLevel, RespectImageOrientation);
</del><ins>+    return frameSizeAtIndex(0, SubsamplingLevel::Default, RespectImageOrientation);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> size_t ImageSource::frameCount()
</span><span class="lines">@@ -161,9 +160,9 @@
</span><span class="cx">     return m_frameCount;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-int ImageSource::repetitionCount()
</del><ins>+RepetitionCount ImageSource::repetitionCount()
</ins><span class="cx"> {
</span><del>-    return initialized() ? m_decoder-&gt;repetitionCount() : cAnimationNone;
</del><ins>+    return initialized() ? m_decoder-&gt;repetitionCount() : RepetitionCountNone;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> String ImageSource::filenameExtension() const
</span><span class="lines">@@ -186,9 +185,9 @@
</span><span class="cx">     return !initialized() || m_decoder-&gt;frameHasAlphaAtIndex(index);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool ImageSource::allowSubsamplingOfFrameAtIndex(size_t index) const
</del><ins>+bool ImageSource::frameAllowSubsamplingAtIndex(size_t index) const
</ins><span class="cx"> {
</span><del>-    return initialized() &amp;&amp; m_decoder-&gt;allowSubsamplingOfFrameAtIndex(index);
</del><ins>+    return initialized() &amp;&amp; m_decoder-&gt;frameAllowSubsamplingAtIndex(index);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> IntSize ImageSource::frameSizeAtIndex(size_t index, SubsamplingLevel subsamplingLevel, RespectImageOrientationEnum shouldRespectImageOrientation) const
</span><span class="lines">@@ -200,7 +199,7 @@
</span><span class="cx">     if (shouldRespectImageOrientation != RespectImageOrientation)
</span><span class="cx">         return size;
</span><span class="cx"> 
</span><del>-    return orientationAtIndex(index).usesWidthAsHeight() ? size.transposedSize() : size;
</del><ins>+    return frameOrientationAtIndex(index).usesWidthAsHeight() ? size.transposedSize() : size;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> unsigned ImageSource::frameBytesAtIndex(size_t index, SubsamplingLevel subsamplingLevel) const
</span><span class="lines">@@ -213,9 +212,9 @@
</span><span class="cx">     return initialized() ? m_decoder-&gt;frameDurationAtIndex(index) : 0;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-ImageOrientation ImageSource::orientationAtIndex(size_t index) const
</del><ins>+ImageOrientation ImageSource::frameOrientationAtIndex(size_t index) const
</ins><span class="cx"> {
</span><del>-    return initialized() ? m_decoder-&gt;orientationAtIndex(index) : ImageOrientation();
</del><ins>+    return initialized() ? m_decoder-&gt;frameOrientationAtIndex(index) : ImageOrientation();
</ins><span class="cx"> }
</span><span class="cx">     
</span><span class="cx"> NativeImagePtr ImageSource::createFrameImageAtIndex(size_t index, SubsamplingLevel subsamplingLevel)
</span><span class="lines">@@ -228,7 +227,7 @@
</span><span class="cx">     if (m_allowSubsampling)
</span><span class="cx">         ts.dumpProperty(&quot;allow-subsampling&quot;, m_allowSubsampling);
</span><span class="cx">     
</span><del>-    ImageOrientation orientation = orientationAtIndex(0);
</del><ins>+    ImageOrientation orientation = frameOrientationAtIndex(0);
</ins><span class="cx">     if (orientation != OriginTopLeft)
</span><span class="cx">         ts.dumpProperty(&quot;orientation&quot;, orientation);
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsImageSourceh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/ImageSource.h (206155 => 206156)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/ImageSource.h        2016-09-20 18:12:54 UTC (rev 206155)
+++ trunk/Source/WebCore/platform/graphics/ImageSource.h        2016-09-20 18:24:41 UTC (rev 206156)
</span><span class="lines">@@ -27,6 +27,7 @@
</span><span class="cx"> #ifndef ImageSource_h
</span><span class="cx"> #define ImageSource_h
</span><span class="cx"> 
</span><ins>+#include &quot;ImageFrame.h&quot;
</ins><span class="cx"> #include &quot;ImageOrientation.h&quot;
</span><span class="cx"> #include &quot;IntPoint.h&quot;
</span><span class="cx"> #include &quot;NativeImage.h&quot;
</span><span class="lines">@@ -43,34 +44,6 @@
</span><span class="cx"> class SharedBuffer;
</span><span class="cx"> class ImageDecoder;
</span><span class="cx"> 
</span><del>-// 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
-// animated GIF should be cycled.  If the loop count is absent, the animation
-// cycles once; if it is 0, the animation cycles infinitely; otherwise the
-// animation plays n + 1 cycles (where n is the specified loop count).  If the
-// GIF decoder defaults to cAnimationLoopOnce in the absence of any loop count
-// and translates an explicit &quot;0&quot; loop count to cAnimationLoopInfinite, then we
-// get a couple of nice side effects:
-//   * By making cAnimationLoopOnce be 0, we allow the animation cycling code in
-//     BitmapImage.cpp to avoid special-casing it, and simply treat all
-//     non-negative loop counts identically.
-//   * By making the other two constants negative, we avoid conflicts with any
-//     real loop count values.
-const int cAnimationLoopOnce = 0;
-const int cAnimationLoopInfinite = -1;
-const int cAnimationNone = -2;
-
-// SubsamplingLevel. 0 is no subsampling, 1 is half dimensions on each axis etc.
-using SubsamplingLevel = int;
-
-enum : SubsamplingLevel {
-    NilSubsamplingLevel = -1,
-    MinSubsamplingLevel = 0,
-    MaxSubsamplingLevel = 3,
-    DefaultSubsamplingLevel = MinSubsamplingLevel
-};
-
</del><span class="cx"> class ImageSource {
</span><span class="cx">     WTF_MAKE_NONCOPYABLE(ImageSource);
</span><span class="cx">     friend class BitmapImage;
</span><span class="lines">@@ -112,6 +85,8 @@
</span><span class="cx">     // decoders in some cases can reconstruct them correctly.
</span><span class="cx">     void clear(bool destroyAll, size_t clearBeforeFrame = 0, SharedBuffer* data = nullptr, bool allDataReceived = false);
</span><span class="cx"> 
</span><ins>+    // FIXME: Remove the decoder() function from this class when caching the ImageFrame is moved outside BitmapImage.
+    ImageDecoder* decoder() const { return m_decoder.get(); }
</ins><span class="cx">     bool initialized() const { return m_decoder.get(); }
</span><span class="cx"> 
</span><span class="cx">     void setData(SharedBuffer* data, bool allDataReceived);
</span><span class="lines">@@ -128,27 +103,27 @@
</span><span class="cx">     IntSize sizeRespectingOrientation() const;
</span><span class="cx"> 
</span><span class="cx">     size_t frameCount();
</span><del>-    int repetitionCount();
</del><ins>+    RepetitionCount repetitionCount();
</ins><span class="cx">     String filenameExtension() const;
</span><span class="cx">     Optional&lt;IntPoint&gt; hotSpot() const;
</span><span class="cx"> 
</span><span class="cx">     bool frameIsCompleteAtIndex(size_t); // Whether or not the frame is completely decoded.
</span><span class="cx">     bool frameHasAlphaAtIndex(size_t); // Whether or not the frame actually used any alpha.
</span><del>-    bool allowSubsamplingOfFrameAtIndex(size_t) const;
</del><ins>+    bool frameAllowSubsamplingAtIndex(size_t) const;
</ins><span class="cx">     
</span><span class="cx">     // Size of optionally subsampled frame.
</span><del>-    IntSize frameSizeAtIndex(size_t, SubsamplingLevel = DefaultSubsamplingLevel, RespectImageOrientationEnum = DoNotRespectImageOrientation) const;
</del><ins>+    IntSize frameSizeAtIndex(size_t, SubsamplingLevel = SubsamplingLevel::Default, RespectImageOrientationEnum = DoNotRespectImageOrientation) const;
</ins><span class="cx">     
</span><span class="cx">     // Return the number of bytes in the decoded frame. If the frame is not yet
</span><span class="cx">     // decoded then return 0.
</span><del>-    unsigned frameBytesAtIndex(size_t, SubsamplingLevel = DefaultSubsamplingLevel) const;
</del><ins>+    unsigned frameBytesAtIndex(size_t, SubsamplingLevel = SubsamplingLevel::Default) const;
</ins><span class="cx">     
</span><span class="cx">     float frameDurationAtIndex(size_t);
</span><del>-    ImageOrientation orientationAtIndex(size_t) const; // EXIF image orientation
</del><ins>+    ImageOrientation frameOrientationAtIndex(size_t) const; // EXIF image orientation
</ins><span class="cx">     
</span><span class="cx">     // Callers should not call this after calling clear() with a higher index;
</span><span class="cx">     // see comments on clear() above.
</span><del>-    NativeImagePtr createFrameImageAtIndex(size_t, SubsamplingLevel = DefaultSubsamplingLevel);
</del><ins>+    NativeImagePtr createFrameImageAtIndex(size_t, SubsamplingLevel = SubsamplingLevel::Default);
</ins><span class="cx">     
</span><span class="cx"> private:
</span><span class="cx">     void clearFrameBufferCache(size_t);
</span><span class="lines">@@ -160,7 +135,7 @@
</span><span class="cx">     
</span><span class="cx">     bool m_needsUpdateMetadata { false };
</span><span class="cx">     size_t m_frameCount { 0 };
</span><del>-    Optional&lt;SubsamplingLevel&gt; m_maximumSubsamplingLevel { DefaultSubsamplingLevel };
</del><ins>+    Optional&lt;SubsamplingLevel&gt; m_maximumSubsamplingLevel { SubsamplingLevel::Default };
</ins><span class="cx"> 
</span><span class="cx">     // The default value of m_allowSubsampling should be the same as defaultImageSubsamplingEnabled in Settings.cpp
</span><span class="cx"> #if PLATFORM(IOS)
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsNativeImageh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/NativeImage.h (206155 => 206156)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/NativeImage.h        2016-09-20 18:12:54 UTC (rev 206155)
+++ trunk/Source/WebCore/platform/graphics/NativeImage.h        2016-09-20 18:24:41 UTC (rev 206156)
</span><span class="lines">@@ -61,6 +61,6 @@
</span><span class="cx"> float subsamplingScale(GraphicsContext&amp;, const FloatRect&amp; destRect, const FloatRect&amp; srcRect);
</span><span class="cx"> 
</span><span class="cx"> void drawNativeImage(const NativeImagePtr&amp;, GraphicsContext&amp;, const FloatRect&amp;, const FloatRect&amp;, const IntSize&amp;, CompositeOperator, BlendMode, const ImageOrientation&amp;);
</span><del>-void clearNativeImageSubImages(const NativeImagePtr&amp;);
</del><ins>+void clearNativeImageSubimages(const NativeImagePtr&amp;);
</ins><span class="cx">     
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicscairoNativeImageCairocpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/cairo/NativeImageCairo.cpp (206155 => 206156)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/cairo/NativeImageCairo.cpp        2016-09-20 18:12:54 UTC (rev 206155)
+++ trunk/Source/WebCore/platform/graphics/cairo/NativeImageCairo.cpp        2016-09-20 18:24:41 UTC (rev 206156)
</span><span class="lines">@@ -96,7 +96,7 @@
</span><span class="cx">     context.restore();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void clearNativeImageSubImages(const NativeImagePtr&amp;)
</del><ins>+void clearNativeImageSubimages(const NativeImagePtr&amp;)
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicscgImageDecoderCGcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/cg/ImageDecoderCG.cpp (206155 => 206156)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/cg/ImageDecoderCG.cpp        2016-09-20 18:12:54 UTC (rev 206155)
+++ trunk/Source/WebCore/platform/graphics/cg/ImageDecoderCG.cpp        2016-09-20 18:24:41 UTC (rev 206156)
</span><span class="lines">@@ -59,7 +59,7 @@
</span><span class="cx"> 
</span><span class="cx"> static RetainPtr&lt;CFDictionaryRef&gt; createImageSourceOptions(SubsamplingLevel subsamplingLevel)
</span><span class="cx"> {
</span><del>-    if (!subsamplingLevel) {
</del><ins>+    if (subsamplingLevel == SubsamplingLevel::First) {
</ins><span class="cx">         const unsigned numOptions = 3;
</span><span class="cx">         const void* keys[numOptions] = { kCGImageSourceShouldCache, kCGImageSourceShouldPreferRGB32, kCGImageSourceSkipMetadata };
</span><span class="cx">         const void* values[numOptions] = { kCFBooleanTrue, kCFBooleanTrue, kCFBooleanTrue };
</span><span class="lines">@@ -66,8 +66,8 @@
</span><span class="cx">         return CFDictionaryCreate(nullptr, keys, values, numOptions, &amp;kCFTypeDictionaryKeyCallBacks, &amp;kCFTypeDictionaryValueCallBacks);
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    short constrainedSubsamplingLevel = std::min&lt;short&gt;(3, std::max&lt;short&gt;(0, subsamplingLevel));
-    int subsampleInt = 1 &lt;&lt; constrainedSubsamplingLevel; // [0..3] =&gt; [1, 2, 4, 8]
</del><ins>+    subsamplingLevel = std::min(SubsamplingLevel::Last, std::max(SubsamplingLevel::First, subsamplingLevel));
+    int subsampleInt = 1 &lt;&lt; static_cast&lt;int&gt;(subsamplingLevel); // [0..3] =&gt; [1, 2, 4, 8]
</ins><span class="cx">     
</span><span class="cx">     RetainPtr&lt;CFNumberRef&gt; subsampleNumber = adoptCF(CFNumberCreate(nullptr,  kCFNumberIntType,  &amp;subsampleInt));
</span><span class="cx">     const CFIndex numOptions = 4;
</span><span class="lines">@@ -76,12 +76,12 @@
</span><span class="cx">     return adoptCF(CFDictionaryCreate(nullptr, keys, values, numOptions, &amp;kCFTypeDictionaryKeyCallBacks, &amp;kCFTypeDictionaryValueCallBacks));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static RetainPtr&lt;CFDictionaryRef&gt; imageSourceOptions(SubsamplingLevel subsamplingLevel = 0)
</del><ins>+static RetainPtr&lt;CFDictionaryRef&gt; imageSourceOptions(SubsamplingLevel subsamplingLevel = SubsamplingLevel::Default)
</ins><span class="cx"> {
</span><del>-    if (subsamplingLevel)
</del><ins>+    if (subsamplingLevel &gt; SubsamplingLevel::First)
</ins><span class="cx">         return createImageSourceOptions(subsamplingLevel);
</span><span class="cx">     
</span><del>-    static NeverDestroyed&lt;RetainPtr&lt;CFDictionaryRef&gt;&gt; options = createImageSourceOptions(0);
</del><ins>+    static NeverDestroyed&lt;RetainPtr&lt;CFDictionaryRef&gt;&gt; options = createImageSourceOptions(SubsamplingLevel::First);
</ins><span class="cx">     return options;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -166,11 +166,11 @@
</span><span class="cx">     return CGImageSourceGetCount(m_nativeDecoder.get());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-int ImageDecoder::repetitionCount() const
</del><ins>+RepetitionCount ImageDecoder::repetitionCount() const
</ins><span class="cx"> {
</span><span class="cx">     RetainPtr&lt;CFDictionaryRef&gt; properties = adoptCF(CGImageSourceCopyProperties(m_nativeDecoder.get(), imageSourceOptions().get()));
</span><span class="cx">     if (!properties)
</span><del>-        return cAnimationLoopOnce;
</del><ins>+        return RepetitionCountOnce;
</ins><span class="cx">     
</span><span class="cx">     CFDictionaryRef gifProperties = (CFDictionaryRef)CFDictionaryGetValue(properties.get(), kCGImagePropertyGIFDictionary);
</span><span class="cx">     if (gifProperties) {
</span><span class="lines">@@ -178,13 +178,13 @@
</span><span class="cx">         
</span><span class="cx">         // No property means loop once.
</span><span class="cx">         if (!num)
</span><del>-            return cAnimationLoopOnce;
</del><ins>+            return RepetitionCountOnce;
</ins><span class="cx">         
</span><del>-        int loopCount;
</del><ins>+        RepetitionCount loopCount;
</ins><span class="cx">         CFNumberGetValue(num, kCFNumberIntType, &amp;loopCount);
</span><span class="cx">         
</span><span class="cx">         // A property with value 0 means loop forever.
</span><del>-        return loopCount ? loopCount : cAnimationLoopInfinite;
</del><ins>+        return loopCount ? loopCount : RepetitionCountInfinite;
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     CFDictionaryRef pngProperties = (CFDictionaryRef)CFDictionaryGetValue(properties.get(), kCGImagePropertyPNGDictionary);
</span><span class="lines">@@ -191,15 +191,15 @@
</span><span class="cx">     if (pngProperties) {
</span><span class="cx">         CFNumberRef num = (CFNumberRef)CFDictionaryGetValue(pngProperties, WebCoreCGImagePropertyAPNGLoopCount);
</span><span class="cx">         if (!num)
</span><del>-            return cAnimationLoopOnce;
</del><ins>+            return RepetitionCountOnce;
</ins><span class="cx">         
</span><del>-        int loopCount;
</del><ins>+        RepetitionCount loopCount;
</ins><span class="cx">         CFNumberGetValue(num, kCFNumberIntType, &amp;loopCount);
</span><del>-        return loopCount ? loopCount : cAnimationLoopInfinite;
</del><ins>+        return loopCount ? loopCount : RepetitionCountInfinite;
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     // Turns out we're not an animated image after all, so we don't animate.
</span><del>-    return cAnimationNone;
</del><ins>+    return RepetitionCountNone;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> Optional&lt;IntPoint&gt; ImageDecoder::hotSpot() const
</span><span class="lines">@@ -249,7 +249,7 @@
</span><span class="cx">     return CGImageSourceGetStatusAtIndex(m_nativeDecoder.get(), index) == kCGImageStatusComplete;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-ImageOrientation ImageDecoder::orientationAtIndex(size_t index) const
</del><ins>+ImageOrientation ImageDecoder::frameOrientationAtIndex(size_t index) const
</ins><span class="cx"> {
</span><span class="cx">     RetainPtr&lt;CFDictionaryRef&gt; properties = adoptCF(CGImageSourceCopyPropertiesAtIndex(m_nativeDecoder.get(), index, imageSourceOptions().get()));
</span><span class="cx">     if (!properties)
</span><span class="lines">@@ -292,7 +292,7 @@
</span><span class="cx">     return duration;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool ImageDecoder::allowSubsamplingOfFrameAtIndex(size_t) const
</del><ins>+bool ImageDecoder::frameAllowSubsamplingAtIndex(size_t) const
</ins><span class="cx"> {
</span><span class="cx">     RetainPtr&lt;CFDictionaryRef&gt; properties = adoptCF(CGImageSourceCopyPropertiesAtIndex(m_nativeDecoder.get(), 0, imageSourceOptions().get()));
</span><span class="cx">     if (!properties)
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicscgImageDecoderCGh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/cg/ImageDecoderCG.h (206155 => 206156)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/cg/ImageDecoderCG.h        2016-09-20 18:12:54 UTC (rev 206155)
+++ trunk/Source/WebCore/platform/graphics/cg/ImageDecoderCG.h        2016-09-20 18:24:41 UTC (rev 206156)
</span><span class="lines">@@ -54,19 +54,20 @@
</span><span class="cx">     // Always original size, without subsampling.
</span><span class="cx">     IntSize size() const;
</span><span class="cx">     size_t frameCount() const;
</span><del>-    int repetitionCount() const;
</del><ins>+
+    RepetitionCount repetitionCount() const;
</ins><span class="cx">     Optional&lt;IntPoint&gt; hotSpot() const;
</span><span class="cx">     
</span><del>-    IntSize frameSizeAtIndex(size_t, SubsamplingLevel = DefaultSubsamplingLevel) const;
</del><ins>+    IntSize frameSizeAtIndex(size_t, SubsamplingLevel = SubsamplingLevel::Default) const;
</ins><span class="cx">     bool frameIsCompleteAtIndex(size_t) const;
</span><del>-    ImageOrientation orientationAtIndex(size_t) const;
</del><ins>+    ImageOrientation frameOrientationAtIndex(size_t) const;
</ins><span class="cx">     
</span><span class="cx">     float frameDurationAtIndex(size_t) const;
</span><span class="cx">     bool frameHasAlphaAtIndex(size_t) const;
</span><del>-    bool allowSubsamplingOfFrameAtIndex(size_t) const;
-    unsigned frameBytesAtIndex(size_t, SubsamplingLevel = 0) const;
</del><ins>+    bool frameAllowSubsamplingAtIndex(size_t) const;
+    unsigned frameBytesAtIndex(size_t, SubsamplingLevel = SubsamplingLevel::Default) const;
</ins><span class="cx">     
</span><del>-    NativeImagePtr createFrameImageAtIndex(size_t, SubsamplingLevel) const;
</del><ins>+    NativeImagePtr createFrameImageAtIndex(size_t, SubsamplingLevel = SubsamplingLevel::Default) const;
</ins><span class="cx">     
</span><span class="cx">     void setData(CFDataRef, bool allDataReceived);
</span><span class="cx">     void setData(SharedBuffer&amp;, bool allDataReceived);
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicscgNativeImageCGcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/cg/NativeImageCG.cpp (206155 => 206156)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/cg/NativeImageCG.cpp        2016-09-20 18:12:54 UTC (rev 206155)
+++ trunk/Source/WebCore/platform/graphics/cg/NativeImageCG.cpp        2016-09-20 18:24:41 UTC (rev 206156)
</span><span class="lines">@@ -96,7 +96,7 @@
</span><span class="cx">     context.drawNativeImage(image, subsampledImageSize, destRect, adjustedSrcRect, op, mode, orientation);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void clearNativeImageSubImages(const NativeImagePtr&amp; image)
</del><ins>+void clearNativeImageSubimages(const NativeImagePtr&amp; image)
</ins><span class="cx"> {
</span><span class="cx"> #if CACHE_SUBIMAGES
</span><span class="cx">     if (image)
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformimagedecodersImageDecodercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/image-decoders/ImageDecoder.cpp (206155 => 206156)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/image-decoders/ImageDecoder.cpp        2016-09-20 18:12:54 UTC (rev 206155)
+++ trunk/Source/WebCore/platform/image-decoders/ImageDecoder.cpp        2016-09-20 18:24:41 UTC (rev 206156)
</span><span class="lines">@@ -127,93 +127,6 @@
</span><span class="cx">     return nullptr;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-ImageFrame::ImageFrame()
-    : m_hasAlpha(false)
-    , m_status(FrameEmpty)
-    , m_duration(0)
-    , m_disposalMethod(DisposeNotSpecified)
-{
-} 
-
-ImageFrame&amp; ImageFrame::operator=(const ImageFrame&amp; other)
-{
-    if (this == &amp;other)
-        return *this;
-
-    if (other.backingStore())
-        initializeBackingStore(*other.backingStore());
-
-    setHasAlpha(other.m_hasAlpha);
-    setStatus(other.status());
-    setDuration(other.duration());
-    setDisposalMethod(other.disposalMethod());
-    return *this;
-}
-
-void ImageFrame::clearPixelData()
-{
-    m_backingStore = nullptr;
-    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()
-{
-    m_backingStore-&gt;clear();
-    m_hasAlpha = true;
-}
-
-void ImageFrame::zeroFillFrameRect(const IntRect&amp; rect)
-{
-    if (rect.isEmpty())
-        return;
-
-    m_backingStore-&gt;clearRect(rect);
-    setHasAlpha(true);
-}
-
-bool ImageFrame::initializeBackingStore(const ImageBackingStore&amp; backingStore)
-{
-    if (&amp;backingStore == this-&gt;backingStore())
-        return true;
-
-    m_backingStore = ImageBackingStore::create(backingStore);
-    return m_backingStore != nullptr;
-}
-
-bool ImageFrame::initializeBackingStore(const IntSize&amp; size, bool premultiplyAlpha)
-{
-    if (size.isEmpty())
-        return false;
-
-    m_backingStore = ImageBackingStore::create(size, premultiplyAlpha);
-    return m_backingStore != nullptr;
-}
-
-bool ImageFrame::hasAlpha() const
-{
-    return m_hasAlpha;
-}
-
-void ImageFrame::setHasAlpha(bool alpha)
-{
-    m_hasAlpha = alpha;
-}
-
-void ImageFrame::setOriginalFrameRect(const IntRect&amp; frameRect)
-{
-    if (m_backingStore)
-        m_backingStore-&gt;setFrameRect(frameRect);
-}
-
-void ImageFrame::setStatus(FrameStatus status)
-{
-    m_status = status;
-}
-
</del><span class="cx"> namespace {
</span><span class="cx"> 
</span><span class="cx"> enum MatchType {
</span><span class="lines">@@ -258,7 +171,7 @@
</span><span class="cx"> bool ImageDecoder::frameIsCompleteAtIndex(size_t index)
</span><span class="cx"> {
</span><span class="cx">     ImageFrame* buffer = frameBufferAtIndex(index);
</span><del>-    return buffer &amp;&amp; buffer-&gt;status() == ImageFrame::FrameComplete;
</del><ins>+    return buffer &amp;&amp; buffer-&gt;isComplete();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool ImageDecoder::frameHasAlphaAtIndex(size_t index) const
</span><span class="lines">@@ -265,7 +178,7 @@
</span><span class="cx"> {
</span><span class="cx">     if (m_frameBufferCache.size() &lt;= index)
</span><span class="cx">         return true;
</span><del>-    if (m_frameBufferCache[index].status() == ImageFrame::FrameComplete)
</del><ins>+    if (m_frameBufferCache[index].isComplete())
</ins><span class="cx">         return m_frameBufferCache[index].hasAlpha();
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="lines">@@ -281,7 +194,7 @@
</span><span class="cx"> float ImageDecoder::frameDurationAtIndex(size_t index)
</span><span class="cx"> {
</span><span class="cx">     ImageFrame* buffer = frameBufferAtIndex(index);
</span><del>-    if (!buffer || buffer-&gt;status() == ImageFrame::FrameEmpty)
</del><ins>+    if (!buffer || buffer-&gt;isEmpty())
</ins><span class="cx">         return 0;
</span><span class="cx">     
</span><span class="cx">     // Many annoying ads specify a 0 duration to make an image flash as quickly as possible.
</span><span class="lines">@@ -301,12 +214,12 @@
</span><span class="cx">         return nullptr;
</span><span class="cx"> 
</span><span class="cx">     ImageFrame* buffer = frameBufferAtIndex(index);
</span><del>-    if (!buffer || buffer-&gt;status() == ImageFrame::FrameEmpty)
</del><ins>+    if (!buffer || buffer-&gt;isEmpty() || !buffer-&gt;hasBackingStore())
</ins><span class="cx">         return nullptr;
</span><span class="cx"> 
</span><span class="cx">     // Return the buffer contents as a native image. For some ports, the data
</span><span class="cx">     // is already in a native container, and this just increments its refcount.
</span><del>-    return buffer-&gt;asNewNativeImage();
</del><ins>+    return buffer-&gt;backingStore()-&gt;image();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void ImageDecoder::prepareScaleDataIfNecessary()
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformimagedecodersImageDecoderh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/image-decoders/ImageDecoder.h (206155 => 206156)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/image-decoders/ImageDecoder.h        2016-09-20 18:12:54 UTC (rev 206155)
+++ trunk/Source/WebCore/platform/image-decoders/ImageDecoder.h        2016-09-20 18:24:41 UTC (rev 206156)
</span><span class="lines">@@ -44,107 +44,6 @@
</span><span class="cx"> 
</span><span class="cx"> using ColorProfile = Vector&lt;char&gt;;
</span><span class="cx"> 
</span><del>-    // 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
-        };
-
-        ImageFrame();
-
-        ImageFrame(const ImageFrame&amp; 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&amp; operator=(const ImageFrame&amp; other);
-
-        // These do not touch other metadata, only the raw pixel data.
-        void clearPixelData();
-        void zeroFillPixelData();
-        void zeroFillFrameRect(const IntRect&amp;);
-        
-        // 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)
-        {
-            m_backingStore-&gt;repeatFirstRow(IntRect(startX, startY, endX -startX , endY - startY));
-        }
-
-        // 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 initializeBackingStore(const ImageBackingStore&amp;);
-
-        // Allocates space for the pixel data. Returns whether allocation succeeded.
-        bool initializeBackingStore(const IntSize&amp;, bool premultiplyAlpha);
-
-        IntSize size() const { return m_backingStore ? m_backingStore-&gt;size() : IntSize(); }
-
-        // 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()).
-        NativeImagePtr asNewNativeImage() const { return m_backingStore ? m_backingStore-&gt;image() : nullptr; }
-
-        inline ImageBackingStore* backingStore() const { return m_backingStore ? m_backingStore.get() : nullptr; }
-        inline bool hasBackingStore() const { return backingStore(); }
-        
-        bool hasAlpha() const;
-        IntRect originalFrameRect() const { return m_backingStore ? m_backingStore-&gt;frameRect() : IntRect(); }
-        FrameStatus status() const { return m_status; }
-        unsigned duration() const { return m_duration; }
-        FrameDisposalMethod disposalMethod() const { return m_disposalMethod; }
-
-        void setHasAlpha(bool alpha);
-        void setOriginalFrameRect(const IntRect&amp;);
-        void setStatus(FrameStatus status);
-        void setDuration(unsigned duration) { m_duration = duration; }
-        void setDisposalMethod(FrameDisposalMethod method) { m_disposalMethod = method; }
-
-        inline RGBA32* pixelAt(int x, int y)
-        {
-            ASSERT(m_backingStore);
-            return m_backingStore-&gt;pixelAt(x, y);
-        }
-
-        inline void setPixel(int x, int y, unsigned r, unsigned g, unsigned b, unsigned a)
-        {
-            ASSERT(m_backingStore);
-            m_backingStore-&gt;setPixel(x, y, r, g, b, a);
-        }
-
-        inline void setPixel(RGBA32* dest, unsigned r, unsigned g, unsigned b, unsigned a)
-        {
-            ASSERT(m_backingStore);
-            m_backingStore-&gt;setPixel(dest, r, g, b, a);
-        }
-
-#if ENABLE(APNG)
-        inline void blendPixel(RGBA32* dest, unsigned r, unsigned g, unsigned b, unsigned a)
-        {
-            ASSERT(m_backingStore);
-            m_backingStore-&gt;blendPixel(dest, r, g, b, a);
-        }
-#endif
-
-    private:
-        std::unique_ptr&lt;ImageBackingStore&gt; m_backingStore;
-        bool m_hasAlpha;
-        FrameStatus m_status;
-        unsigned m_duration;
-        FrameDisposalMethod m_disposalMethod;
-    };
-
</del><span class="cx">     // ImageDecoder is a base for all format-specific decoders
</span><span class="cx">     // (e.g. JPEGImageDecoder).  This base manages the ImageFrame cache.
</span><span class="cx">     //
</span><span class="lines">@@ -225,7 +124,7 @@
</span><span class="cx">         // decode call out and use it here.
</span><span class="cx">         virtual size_t frameCount() { return 1; }
</span><span class="cx"> 
</span><del>-        virtual int repetitionCount() const { return cAnimationNone; }
</del><ins>+        virtual RepetitionCount repetitionCount() const { return RepetitionCountNone; }
</ins><span class="cx"> 
</span><span class="cx">         // Decodes as much of the requested frame as possible, and returns an
</span><span class="cx">         // ImageDecoder-owned pointer.
</span><span class="lines">@@ -246,9 +145,9 @@
</span><span class="cx">         void setIgnoreGammaAndColorProfile(bool flag) { m_ignoreGammaAndColorProfile = flag; }
</span><span class="cx">         bool ignoresGammaAndColorProfile() const { return m_ignoreGammaAndColorProfile; }
</span><span class="cx"> 
</span><del>-        ImageOrientation orientationAtIndex(size_t) const { return m_orientation; }
</del><ins>+        ImageOrientation frameOrientationAtIndex(size_t) const { return m_orientation; }
</ins><span class="cx">         
</span><del>-        bool allowSubsamplingOfFrameAtIndex(size_t) const { return false; }
</del><ins>+        bool frameAllowSubsamplingAtIndex(size_t) const { return false; }
</ins><span class="cx"> 
</span><span class="cx">         enum { iccColorProfileHeaderLength = 128 };
</span><span class="cx"> 
</span><span class="lines">@@ -261,7 +160,7 @@
</span><span class="cx"> 
</span><span class="cx">         static size_t bytesDecodedToDetermineProperties() { return 0; }
</span><span class="cx">         
</span><del>-        static SubsamplingLevel subsamplingLevelForScale(float, SubsamplingLevel) { return 0; }
</del><ins>+        static SubsamplingLevel subsamplingLevelForScale(float, SubsamplingLevel) { return SubsamplingLevel::Default; }
</ins><span class="cx"> 
</span><span class="cx">         static bool inputDeviceColorProfile(const char* profileData, unsigned profileLength)
</span><span class="cx">         {
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformimagedecodersbmpBMPImageDecodercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/image-decoders/bmp/BMPImageDecoder.cpp (206155 => 206156)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/image-decoders/bmp/BMPImageDecoder.cpp        2016-09-20 18:12:54 UTC (rev 206155)
+++ trunk/Source/WebCore/platform/image-decoders/bmp/BMPImageDecoder.cpp        2016-09-20 18:24:41 UTC (rev 206156)
</span><span class="lines">@@ -74,7 +74,7 @@
</span><span class="cx">         m_frameBufferCache.resize(1);
</span><span class="cx"> 
</span><span class="cx">     ImageFrame* buffer = &amp;m_frameBufferCache.first();
</span><del>-    if (buffer-&gt;status() != ImageFrame::FrameComplete)
</del><ins>+    if (!buffer-&gt;isComplete())
</ins><span class="cx">         decode(false);
</span><span class="cx">     return buffer;
</span><span class="cx"> }
</span><span class="lines">@@ -96,7 +96,7 @@
</span><span class="cx">         setFailed();
</span><span class="cx">     // If we're done decoding the image, we don't need the BMPImageReader
</span><span class="cx">     // anymore.  (If we failed, |m_reader| has already been cleared.)
</span><del>-    else if (!m_frameBufferCache.isEmpty() &amp;&amp; (m_frameBufferCache.first().status() == ImageFrame::FrameComplete))
</del><ins>+    else if (!m_frameBufferCache.isEmpty() &amp;&amp; m_frameBufferCache.first().isComplete())
</ins><span class="cx">         m_reader = nullptr;
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformimagedecodersbmpBMPImageReadercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/image-decoders/bmp/BMPImageReader.cpp (206155 => 206156)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/image-decoders/bmp/BMPImageReader.cpp        2016-09-20 18:12:54 UTC (rev 206155)
+++ trunk/Source/WebCore/platform/image-decoders/bmp/BMPImageReader.cpp        2016-09-20 18:24:41 UTC (rev 206156)
</span><span class="lines">@@ -77,11 +77,11 @@
</span><span class="cx"> 
</span><span class="cx">     // Initialize the framebuffer if needed.
</span><span class="cx">     ASSERT(m_buffer);  // Parent should set this before asking us to decode!
</span><del>-    if (m_buffer-&gt;status() == ImageFrame::FrameEmpty) {
-        if (!m_buffer-&gt;initializeBackingStore(m_parent-&gt;size(), m_parent-&gt;premultiplyAlpha()))
</del><ins>+    if (m_buffer-&gt;isEmpty()) {
+        if (!m_buffer-&gt;initialize(m_parent-&gt;size(), m_parent-&gt;premultiplyAlpha()))
</ins><span class="cx">             return m_parent-&gt;setFailed(); // Unable to allocate.
</span><span class="cx"> 
</span><del>-        m_buffer-&gt;setStatus(ImageFrame::FramePartial);
</del><ins>+        m_buffer-&gt;setDecoding(ImageFrame::Decoding::Partial);
</ins><span class="cx">         m_buffer-&gt;setHasAlpha(false);
</span><span class="cx"> 
</span><span class="cx">         if (!m_isTopDown)
</span><span class="lines">@@ -117,7 +117,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // Done!
</span><del>-    m_buffer-&gt;setStatus(ImageFrame::FrameComplete);
</del><ins>+    m_buffer-&gt;setDecoding(ImageFrame::Decoding::Complete);
</ins><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -702,7 +702,8 @@
</span><span class="cx">                 } else {
</span><span class="cx">                     m_seenNonZeroAlphaPixel = true;
</span><span class="cx">                     if (m_seenZeroAlphaPixel) {
</span><del>-                        m_buffer-&gt;zeroFillPixelData();
</del><ins>+                        m_buffer-&gt;backingStore()-&gt;clear();
+                        m_buffer-&gt;setHasAlpha(true);
</ins><span class="cx">                         m_seenZeroAlphaPixel = false;
</span><span class="cx">                     } else if (alpha != 255)
</span><span class="cx">                         m_buffer-&gt;setHasAlpha(true);
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformimagedecodersbmpBMPImageReaderh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/image-decoders/bmp/BMPImageReader.h (206155 => 206156)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/image-decoders/bmp/BMPImageReader.h        2016-09-20 18:12:54 UTC (rev 206155)
+++ trunk/Source/WebCore/platform/image-decoders/bmp/BMPImageReader.h        2016-09-20 18:24:41 UTC (rev 206156)
</span><span class="lines">@@ -248,7 +248,7 @@
</span><span class="cx">                             unsigned blue,
</span><span class="cx">                             unsigned alpha)
</span><span class="cx">         {
</span><del>-            m_buffer-&gt;setPixel(m_coord.x(), m_coord.y(), red, green, blue, alpha);
</del><ins>+            m_buffer-&gt;backingStore()-&gt;setPixel(m_coord.x(), m_coord.y(), red, green, blue, alpha);
</ins><span class="cx">             m_coord.move(1, 0);
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -262,8 +262,10 @@
</span><span class="cx">                              unsigned blue,
</span><span class="cx">                              unsigned alpha)
</span><span class="cx">         {
</span><del>-            while (m_coord.x() &lt; endCoord)
-                setPixel(red, green, blue, alpha);
</del><ins>+            if (endCoord &lt;= m_coord.x())
+                return;
+            m_buffer-&gt;backingStore()-&gt;fillRect(IntRect(m_coord.x(), m_coord.y(), endCoord - m_coord.x(), 1), red, green, blue, alpha);
+            m_coord.setX(endCoord);
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         // Resets the relevant local variables to start drawing at the left edge
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformimagedecodersgifGIFImageDecodercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp (206155 => 206156)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp        2016-09-20 18:12:54 UTC (rev 206155)
+++ trunk/Source/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp        2016-09-20 18:24:41 UTC (rev 206156)
</span><span class="lines">@@ -31,10 +31,8 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-GIFImageDecoder::GIFImageDecoder(ImageSource::AlphaOption alphaOption,
-                                 ImageSource::GammaAndColorProfileOption gammaAndColorProfileOption)
</del><ins>+GIFImageDecoder::GIFImageDecoder(ImageSource::AlphaOption alphaOption, ImageSource::GammaAndColorProfileOption gammaAndColorProfileOption)
</ins><span class="cx">     : ImageDecoder(alphaOption, gammaAndColorProfileOption)
</span><del>-    , m_repetitionCount(cAnimationLoopOnce)
</del><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -78,7 +76,7 @@
</span><span class="cx">     return m_frameBufferCache.size();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-int GIFImageDecoder::repetitionCount() const
</del><ins>+RepetitionCount GIFImageDecoder::repetitionCount() const
</ins><span class="cx"> {
</span><span class="cx">     // This value can arrive at any point in the image data stream.  Most GIFs
</span><span class="cx">     // in the wild declare it near the beginning of the file, so it usually is
</span><span class="lines">@@ -105,7 +103,7 @@
</span><span class="cx">     // later in the stream. It is also possible that no frames are in the
</span><span class="cx">     // stream. In these cases we should just loop once.
</span><span class="cx">     if (failed() || (m_reader &amp;&amp; (!m_reader-&gt;imagesCount())))
</span><del>-        m_repetitionCount = cAnimationLoopOnce;
</del><ins>+        m_repetitionCount = RepetitionCountOnce;
</ins><span class="cx">     else if (m_reader &amp;&amp; m_reader-&gt;loopCount() != cLoopCountNotSeen)
</span><span class="cx">         m_repetitionCount = m_reader-&gt;loopCount();
</span><span class="cx">     return m_repetitionCount;
</span><span class="lines">@@ -117,7 +115,7 @@
</span><span class="cx">         return 0;
</span><span class="cx"> 
</span><span class="cx">     ImageFrame&amp; frame = m_frameBufferCache[index];
</span><del>-    if (frame.status() != ImageFrame::FrameComplete)
</del><ins>+    if (!frame.isComplete())
</ins><span class="cx">         decode(index + 1, GIFFullQuery);
</span><span class="cx">     return &amp;frame;
</span><span class="cx"> }
</span><span class="lines">@@ -156,25 +154,25 @@
</span><span class="cx">     // not to have non-empty frames after the frame we're currently decoding.
</span><span class="cx">     // So, scan backwards from |end| as follows:
</span><span class="cx">     //   * If the frame is empty, we're still past any frames we care about.
</span><del>-    //   * If the frame is complete, but is DisposeOverwritePrevious, we'll
</del><ins>+    //   * If the frame is complete, but is DisposalMethod::RestoreToPrevious, we'll
</ins><span class="cx">     //     skip over it in future initFrameBuffer() calls.  We can clear it
</span><span class="cx">     //     unless it's |end|, and keep scanning.  For any other disposal method,
</span><span class="cx">     //     stop scanning, as we've found the frame initFrameBuffer() will need
</span><span class="cx">     //     next.
</span><span class="cx">     //   * If the frame is partial, we're decoding it, so don't clear it; if it
</span><del>-    //     has a disposal method other than DisposeOverwritePrevious, stop
</del><ins>+    //     has a disposal method other than DisposalMethod::RestoreToPrevious, stop
</ins><span class="cx">     //     scanning, as we'll only need this frame when decoding the next one.
</span><span class="cx">     Vector&lt;ImageFrame&gt;::iterator i(end);
</span><del>-    for (; (i != m_frameBufferCache.begin()) &amp;&amp; ((i-&gt;status() == ImageFrame::FrameEmpty) || (i-&gt;disposalMethod() == ImageFrame::DisposeOverwritePrevious)); --i) {
-        if ((i-&gt;status() == ImageFrame::FrameComplete) &amp;&amp; (i != end))
-            i-&gt;clearPixelData();
</del><ins>+    for (; (i != m_frameBufferCache.begin()) &amp;&amp; (i-&gt;isEmpty() || (i-&gt;disposalMethod() == ImageFrame::DisposalMethod::RestoreToPrevious)); --i) {
+        if (i-&gt;isComplete() &amp;&amp; (i != end))
+            i-&gt;clear();
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // Now |i| holds the last frame we need to preserve; clear prior frames.
</span><span class="cx">     for (Vector&lt;ImageFrame&gt;::iterator j(m_frameBufferCache.begin()); j != i; ++j) {
</span><del>-        ASSERT(j-&gt;status() != ImageFrame::FramePartial);
-        if (j-&gt;status() != ImageFrame::FrameEmpty)
-            j-&gt;clearPixelData();
</del><ins>+        ASSERT(!j-&gt;isPartial());
+        if (j-&gt;isEmpty())
+            j-&gt;clear();
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // When some frames are cleared, the reader is out of sync, since the caller might ask for any frame not
</span><span class="lines">@@ -213,16 +211,16 @@
</span><span class="cx"> 
</span><span class="cx">     // Initialize the frame if necessary.
</span><span class="cx">     ImageFrame&amp; buffer = m_frameBufferCache[frameIndex];
</span><del>-    if (((buffer.status() == ImageFrame::FrameEmpty) &amp;&amp; !initFrameBuffer(frameIndex)) || !buffer.hasBackingStore())
</del><ins>+    if ((buffer.isEmpty() &amp;&amp; !initFrameBuffer(frameIndex)) || !buffer.hasBackingStore())
</ins><span class="cx">         return false;
</span><span class="cx"> 
</span><del>-    RGBA32* currentAddress = buffer.pixelAt(xBegin, yBegin);
</del><ins>+    RGBA32* currentAddress = buffer.backingStore()-&gt;pixelAt(xBegin, yBegin);
</ins><span class="cx">     // Write one row's worth of data into the frame.  
</span><span class="cx">     for (int x = xBegin; x &lt; xEnd; ++x) {
</span><span class="cx">         const unsigned char sourceValue = rowBuffer[(m_scaled ? m_scaledColumns[x] : x) - frameContext-&gt;xOffset];
</span><span class="cx">         if ((!frameContext-&gt;isTransparent || (sourceValue != frameContext-&gt;tpixel)) &amp;&amp; (sourceValue &lt; colorMapSize)) {
</span><span class="cx">             const size_t colorIndex = static_cast&lt;size_t&gt;(sourceValue) * 3;
</span><del>-            buffer.setPixel(currentAddress, colorMap[colorIndex], colorMap[colorIndex + 1], colorMap[colorIndex + 2], 255);
</del><ins>+            buffer.backingStore()-&gt;setPixel(currentAddress, colorMap[colorIndex], colorMap[colorIndex + 1], colorMap[colorIndex + 2], 255);
</ins><span class="cx">         } else {
</span><span class="cx">             m_currentBufferSawAlpha = true;
</span><span class="cx">             // We may or may not need to write transparent pixels to the buffer.
</span><span class="lines">@@ -233,7 +231,7 @@
</span><span class="cx">             // beyond the first, or the initial passes will &quot;show through&quot; the
</span><span class="cx">             // later ones.
</span><span class="cx">             if (writeTransparentPixels)
</span><del>-                buffer.setPixel(currentAddress, 0, 0, 0, 0);
</del><ins>+                buffer.backingStore()-&gt;setPixel(currentAddress, 0, 0, 0, 0);
</ins><span class="cx">         }
</span><span class="cx">         ++currentAddress;
</span><span class="cx">     }
</span><span class="lines">@@ -240,27 +238,29 @@
</span><span class="cx"> 
</span><span class="cx">     // Tell the frame to copy the row data if need be.
</span><span class="cx">     if (repeatCount &gt; 1)
</span><del>-        buffer.copyRowNTimes(xBegin, xEnd, yBegin, yEnd);
</del><ins>+        buffer.backingStore()-&gt;repeatFirstRow(IntRect(xBegin, yBegin, xEnd - xBegin , yEnd - yBegin));
</ins><span class="cx"> 
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool GIFImageDecoder::frameComplete(unsigned frameIndex, unsigned frameDuration, ImageFrame::FrameDisposalMethod disposalMethod)
</del><ins>+bool GIFImageDecoder::frameComplete(unsigned frameIndex, unsigned frameDuration, ImageFrame::DisposalMethod disposalMethod)
</ins><span class="cx"> {
</span><span class="cx">     // Initialize the frame if necessary.  Some GIFs insert do-nothing frames,
</span><span class="cx">     // in which case we never reach haveDecodedRow() before getting here.
</span><span class="cx">     ImageFrame&amp; buffer = m_frameBufferCache[frameIndex];
</span><del>-    if ((buffer.status() == ImageFrame::FrameEmpty) &amp;&amp; !initFrameBuffer(frameIndex))
</del><ins>+    if (buffer.isEmpty() &amp;&amp; !initFrameBuffer(frameIndex))
</ins><span class="cx">         return false; // initFrameBuffer() has already called setFailed().
</span><span class="cx"> 
</span><del>-    buffer.setStatus(ImageFrame::FrameComplete);
</del><ins>+    buffer.setDecoding(ImageFrame::Decoding::Complete);
</ins><span class="cx">     buffer.setDuration(frameDuration);
</span><span class="cx">     buffer.setDisposalMethod(disposalMethod);
</span><span class="cx"> 
</span><span class="cx">     if (!m_currentBufferSawAlpha) {
</span><ins>+        IntRect rect = buffer.backingStore()-&gt;frameRect();
+        
</ins><span class="cx">         // The whole frame was non-transparent, so it's possible that the entire
</span><span class="cx">         // resulting buffer was non-transparent, and we can setHasAlpha(false).
</span><del>-        if (buffer.originalFrameRect().contains(IntRect(IntPoint(), scaledSize())))
</del><ins>+        if (rect.contains(IntRect(IntPoint(), scaledSize())))
</ins><span class="cx">             buffer.setHasAlpha(false);
</span><span class="cx">         else if (frameIndex) {
</span><span class="cx">             // Tricky case.  This frame does not have alpha only if everywhere
</span><span class="lines">@@ -268,22 +268,23 @@
</span><span class="cx">             // true, we check the start state of the frame -- if it doesn't have
</span><span class="cx">             // alpha, we're safe.
</span><span class="cx">             //
</span><del>-            // First skip over prior DisposeOverwritePrevious frames (since they
</del><ins>+            // First skip over prior DisposalMethod::RestoreToPrevious frames (since they
</ins><span class="cx">             // don't affect the start state of this frame) the same way we do in
</span><span class="cx">             // initFrameBuffer().
</span><span class="cx">             const ImageFrame* prevBuffer = &amp;m_frameBufferCache[--frameIndex];
</span><del>-            while (frameIndex &amp;&amp; (prevBuffer-&gt;disposalMethod() == ImageFrame::DisposeOverwritePrevious))
</del><ins>+            while (frameIndex &amp;&amp; (prevBuffer-&gt;disposalMethod() == ImageFrame::DisposalMethod::RestoreToPrevious))
</ins><span class="cx">                 prevBuffer = &amp;m_frameBufferCache[--frameIndex];
</span><span class="cx"> 
</span><del>-            // Now, if we're at a DisposeNotSpecified or DisposeKeep frame, then
</del><ins>+            // Now, if we're at a DisposalMethod::Unspecified or DisposalMethod::DoNotDispose frame, then
</ins><span class="cx">             // we can say we have no alpha if that frame had no alpha.  But
</span><span class="cx">             // since in initFrameBuffer() we already copied that frame's alpha
</span><span class="cx">             // state into the current frame's, we need do nothing at all here.
</span><span class="cx">             //
</span><del>-            // The only remaining case is a DisposeOverwriteBgcolor frame.  If
</del><ins>+            // The only remaining case is a DisposalMethod::RestoreToBackground frame. If
</ins><span class="cx">             // it had no alpha, and its rect is contained in the current frame's
</span><span class="cx">             // rect, we know the current frame has no alpha.
</span><del>-            if ((prevBuffer-&gt;disposalMethod() == ImageFrame::DisposeOverwriteBgcolor) &amp;&amp; !prevBuffer-&gt;hasAlpha() &amp;&amp; buffer.originalFrameRect().contains(prevBuffer-&gt;originalFrameRect()))
</del><ins>+            IntRect prevRect = prevBuffer-&gt;backingStore()-&gt;frameRect();
+            if ((prevBuffer-&gt;disposalMethod() == ImageFrame::DisposalMethod::RestoreToBackground) &amp;&amp; !prevBuffer-&gt;hasAlpha() &amp;&amp; rect.contains(prevRect))
</ins><span class="cx">                 buffer.setHasAlpha(false);
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="lines">@@ -342,66 +343,68 @@
</span><span class="cx">     // Initialize the frame rect in our buffer.
</span><span class="cx">     const GIFFrameContext* frameContext = m_reader-&gt;frameContext();
</span><span class="cx">     IntRect frameRect(frameContext-&gt;xOffset, frameContext-&gt;yOffset, frameContext-&gt;width, frameContext-&gt;height);
</span><del>-
-    // Make sure the frameRect doesn't extend outside the buffer.
-    if (frameRect.maxX() &gt; size().width())
-        frameRect.setWidth(size().width() - frameContext-&gt;xOffset);
-    if (frameRect.maxY() &gt; size().height())
-        frameRect.setHeight(size().height() - frameContext-&gt;yOffset);
-
</del><span class="cx">     ImageFrame* const buffer = &amp;m_frameBufferCache[frameIndex];
</span><del>-    int left = upperBoundScaledX(frameRect.x());
-    int right = lowerBoundScaledX(frameRect.maxX(), left);
-    int top = upperBoundScaledY(frameRect.y());
-    int bottom = lowerBoundScaledY(frameRect.maxY(), top);
-    buffer-&gt;setOriginalFrameRect(IntRect(left, top, right - left, bottom - top));
</del><span class="cx"> 
</span><span class="cx">     if (!frameIndex) {
</span><span class="cx">         // This is the first frame, so we're not relying on any previous data.
</span><del>-        if (!buffer-&gt;initializeBackingStore(scaledSize(), m_premultiplyAlpha))
</del><ins>+        if (!buffer-&gt;initialize(scaledSize(), m_premultiplyAlpha))
</ins><span class="cx">             return setFailed();
</span><span class="cx">     } else {
</span><span class="cx">         // The starting state for this frame depends on the previous frame's
</span><span class="cx">         // disposal method.
</span><span class="cx">         //
</span><del>-        // Frames that use the DisposeOverwritePrevious method are effectively
</del><ins>+        // Frames that use the DisposalMethod::RestoreToPrevious method are effectively
</ins><span class="cx">         // no-ops in terms of changing the starting state of a frame compared to
</span><span class="cx">         // the starting state of the previous frame, so skip over them.  (If the
</span><span class="cx">         // first frame specifies this method, it will get treated like
</span><del>-        // DisposeOverwriteBgcolor below and reset to a completely empty image.)
</del><ins>+        // DisposalMethod::RestoreToBackground below and reset to a completely empty image.)
</ins><span class="cx">         const ImageFrame* prevBuffer = &amp;m_frameBufferCache[--frameIndex];
</span><del>-        ImageFrame::FrameDisposalMethod prevMethod = prevBuffer-&gt;disposalMethod();
-        while (frameIndex &amp;&amp; (prevMethod == ImageFrame::DisposeOverwritePrevious)) {
</del><ins>+        ImageFrame::DisposalMethod prevMethod = prevBuffer-&gt;disposalMethod();
+        while (frameIndex &amp;&amp; (prevMethod == ImageFrame::DisposalMethod::RestoreToPrevious)) {
</ins><span class="cx">             prevBuffer = &amp;m_frameBufferCache[--frameIndex];
</span><span class="cx">             prevMethod = prevBuffer-&gt;disposalMethod();
</span><span class="cx">         }
</span><del>-        ASSERT(prevBuffer-&gt;status() == ImageFrame::FrameComplete);
</del><span class="cx"> 
</span><del>-        if ((prevMethod == ImageFrame::DisposeNotSpecified) || (prevMethod == ImageFrame::DisposeKeep)) {
</del><ins>+        ASSERT(prevBuffer-&gt;isComplete());
+
+        if ((prevMethod == ImageFrame::DisposalMethod::Unspecified) || (prevMethod == ImageFrame::DisposalMethod::DoNotDispose)) {
</ins><span class="cx">             // Preserve the last frame as the starting state for this frame.
</span><del>-            if (!prevBuffer-&gt;backingStore() || !buffer-&gt;initializeBackingStore(*prevBuffer-&gt;backingStore()))
</del><ins>+            if (!prevBuffer-&gt;backingStore() || !buffer-&gt;initialize(*prevBuffer-&gt;backingStore()))
</ins><span class="cx">                 return setFailed();
</span><span class="cx">         } else {
</span><span class="cx">             // We want to clear the previous frame to transparent, without
</span><span class="cx">             // affecting pixels in the image outside of the frame.
</span><del>-            IntRect prevRect = prevBuffer-&gt;originalFrameRect();
</del><ins>+            IntRect prevRect = prevBuffer-&gt;backingStore()-&gt;frameRect();
</ins><span class="cx">             const IntSize&amp; bufferSize = scaledSize();
</span><span class="cx">             if (!frameIndex || prevRect.contains(IntRect(IntPoint(), scaledSize()))) {
</span><span class="cx">                 // Clearing the first frame, or a frame the size of the whole
</span><span class="cx">                 // image, results in a completely empty image.
</span><del>-                if (!buffer-&gt;initializeBackingStore(bufferSize, m_premultiplyAlpha))
</del><ins>+                if (!buffer-&gt;initialize(bufferSize, m_premultiplyAlpha))
</ins><span class="cx">                     return setFailed();
</span><span class="cx">             } else {
</span><span class="cx">                 // Copy the whole previous buffer, then clear just its frame.
</span><del>-                if (!prevBuffer-&gt;backingStore() || !buffer-&gt;initializeBackingStore(*prevBuffer-&gt;backingStore()))
</del><ins>+                if (!prevBuffer-&gt;backingStore() || !buffer-&gt;initialize(*prevBuffer-&gt;backingStore()))
</ins><span class="cx">                     return setFailed();
</span><del>-                buffer-&gt;zeroFillFrameRect(prevRect);
</del><ins>+                buffer-&gt;backingStore()-&gt;clearRect(prevRect);
+                buffer-&gt;setHasAlpha(true);
</ins><span class="cx">             }
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    // Make sure the frameRect doesn't extend outside the buffer.
+    if (frameRect.maxX() &gt; size().width())
+        frameRect.setWidth(size().width() - frameContext-&gt;xOffset);
+    if (frameRect.maxY() &gt; size().height())
+        frameRect.setHeight(size().height() - frameContext-&gt;yOffset);
+
+    int left = upperBoundScaledX(frameRect.x());
+    int right = lowerBoundScaledX(frameRect.maxX(), left);
+    int top = upperBoundScaledY(frameRect.y());
+    int bottom = lowerBoundScaledY(frameRect.maxY(), top);
+    buffer-&gt;backingStore()-&gt;setFrameRect(IntRect(left, top, right - left, bottom - top));
+
</ins><span class="cx">     // Update our status to be partially complete.
</span><del>-    buffer-&gt;setStatus(ImageFrame::FramePartial);
</del><ins>+    buffer-&gt;setDecoding(ImageFrame::Decoding::Partial);
</ins><span class="cx"> 
</span><span class="cx">     // Reset the alpha pixel tracker for this frame.
</span><span class="cx">     m_currentBufferSawAlpha = false;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformimagedecodersgifGIFImageDecoderh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/image-decoders/gif/GIFImageDecoder.h (206155 => 206156)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/image-decoders/gif/GIFImageDecoder.h        2016-09-20 18:12:54 UTC (rev 206155)
+++ trunk/Source/WebCore/platform/image-decoders/gif/GIFImageDecoder.h        2016-09-20 18:24:41 UTC (rev 206156)
</span><span class="lines">@@ -46,7 +46,7 @@
</span><span class="cx">         bool isSizeAvailable() override;
</span><span class="cx">         bool setSize(const IntSize&amp;) override;
</span><span class="cx">         size_t frameCount() override;
</span><del>-        int repetitionCount() const override;
</del><ins>+        RepetitionCount repetitionCount() const override;
</ins><span class="cx">         ImageFrame* frameBufferAtIndex(size_t index) override;
</span><span class="cx">         // CAUTION: setFailed() deletes |m_reader|.  Be careful to avoid
</span><span class="cx">         // accessing deleted memory, especially when calling this from inside
</span><span class="lines">@@ -56,7 +56,7 @@
</span><span class="cx"> 
</span><span class="cx">         // Callbacks from the GIF reader.
</span><span class="cx">         bool haveDecodedRow(unsigned frameIndex, const Vector&lt;unsigned char&gt;&amp; rowBuffer, size_t width, size_t rowNumber, unsigned repeatCount, bool writeTransparentPixels);
</span><del>-        bool frameComplete(unsigned frameIndex, unsigned frameDuration, ImageFrame::FrameDisposalMethod disposalMethod);
</del><ins>+        bool frameComplete(unsigned frameIndex, unsigned frameDuration, ImageFrame::DisposalMethod);
</ins><span class="cx">         void gifComplete();
</span><span class="cx"> 
</span><span class="cx">     private:
</span><span class="lines">@@ -72,7 +72,7 @@
</span><span class="cx">         bool initFrameBuffer(unsigned frameIndex);
</span><span class="cx"> 
</span><span class="cx">         bool m_currentBufferSawAlpha;
</span><del>-        mutable int m_repetitionCount;
</del><ins>+        mutable RepetitionCount m_repetitionCount { RepetitionCountOnce };
</ins><span class="cx">         std::unique_ptr&lt;GIFImageReader&gt; m_reader;
</span><span class="cx">     };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformimagedecodersgifGIFImageReadercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/image-decoders/gif/GIFImageReader.cpp (206155 => 206156)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/image-decoders/gif/GIFImageReader.cpp        2016-09-20 18:12:54 UTC (rev 206155)
+++ trunk/Source/WebCore/platform/image-decoders/gif/GIFImageReader.cpp        2016-09-20 18:24:41 UTC (rev 206156)
</span><span class="lines">@@ -568,14 +568,14 @@
</span><span class="cx"> 
</span><span class="cx">             // We ignore the &quot;user input&quot; bit.
</span><span class="cx"> 
</span><del>-            // NOTE: This relies on the values in the FrameDisposalMethod enum
</del><ins>+            // NOTE: This relies on the values in the DisposalMethod enum
</ins><span class="cx">             // matching those in the GIF spec!
</span><span class="cx">             int disposalMethod = ((*currentComponent) &gt;&gt; 2) &amp; 0x7;
</span><del>-            currentFrame-&gt;disposalMethod = static_cast&lt;WebCore::ImageFrame::FrameDisposalMethod&gt;(disposalMethod);
</del><ins>+            currentFrame-&gt;disposalMethod = static_cast&lt;WebCore::ImageFrame::DisposalMethod&gt;(disposalMethod);
</ins><span class="cx">             // Some specs say that disposal method 3 is &quot;overwrite previous&quot;, others that setting
</span><span class="cx">             // the third bit of the field (i.e. method 4) is. We map both to the same value.
</span><span class="cx">             if (disposalMethod == 4)
</span><del>-                currentFrame-&gt;disposalMethod = WebCore::ImageFrame::DisposeOverwritePrevious;
</del><ins>+                currentFrame-&gt;disposalMethod = WebCore::ImageFrame::DisposalMethod::RestoreToPrevious;
</ins><span class="cx">             currentFrame-&gt;delayTime = GETINT16(currentComponent + 1) * 10;
</span><span class="cx">             GETN(1, GIFConsumeBlock);
</span><span class="cx">             break;
</span><span class="lines">@@ -624,7 +624,7 @@
</span><span class="cx"> 
</span><span class="cx">                 // Zero loop count is infinite animation loop request.
</span><span class="cx">                 if (!m_loopCount)
</span><del>-                    m_loopCount = WebCore::cAnimationLoopInfinite;
</del><ins>+                    m_loopCount = WebCore::RepetitionCountInfinite;
</ins><span class="cx"> 
</span><span class="cx">                 GETN(1, GIFNetscapeExtensionBlock);
</span><span class="cx">             } else if (netscapeExtension == 2) {
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformimagedecodersgifGIFImageReaderh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/image-decoders/gif/GIFImageReader.h (206155 => 206156)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/image-decoders/gif/GIFImageReader.h        2016-09-20 18:12:54 UTC (rev 206155)
+++ trunk/Source/WebCore/platform/image-decoders/gif/GIFImageReader.h        2016-09-20 18:24:41 UTC (rev 206156)
</span><span class="lines">@@ -155,7 +155,7 @@
</span><span class="cx">     unsigned width;
</span><span class="cx">     unsigned height;
</span><span class="cx">     int tpixel; // Index of transparent pixel.
</span><del>-    WebCore::ImageFrame::FrameDisposalMethod disposalMethod; // Restore to background, leave in place, etc.
</del><ins>+    WebCore::ImageFrame::DisposalMethod disposalMethod; // Restore to background, leave in place, etc.
</ins><span class="cx">     size_t localColormapPosition; // Per-image colormap.
</span><span class="cx">     int localColormapSize; // Size of local colormap array.
</span><span class="cx">     int datasize;
</span><span class="lines">@@ -174,7 +174,7 @@
</span><span class="cx">         , width(0)
</span><span class="cx">         , height(0)
</span><span class="cx">         , tpixel(0)
</span><del>-        , disposalMethod(WebCore::ImageFrame::DisposeNotSpecified)
</del><ins>+        , disposalMethod(WebCore::ImageFrame::DisposalMethod::Unspecified)
</ins><span class="cx">         , localColormapPosition(0)
</span><span class="cx">         , localColormapSize(0)
</span><span class="cx">         , datasize(0)
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformimagedecodersicoICOImageDecodercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/image-decoders/ico/ICOImageDecoder.cpp (206155 => 206156)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/image-decoders/ico/ICOImageDecoder.cpp        2016-09-20 18:12:54 UTC (rev 206155)
+++ trunk/Source/WebCore/platform/image-decoders/ico/ICOImageDecoder.cpp        2016-09-20 18:24:41 UTC (rev 206156)
</span><span class="lines">@@ -113,7 +113,7 @@
</span><span class="cx">         return 0;
</span><span class="cx"> 
</span><span class="cx">     ImageFrame* buffer = &amp;m_frameBufferCache[index];
</span><del>-    if (buffer-&gt;status() != ImageFrame::FrameComplete)
</del><ins>+    if (!buffer-&gt;isComplete())
</ins><span class="cx">         decode(index, false);
</span><span class="cx">     return buffer;
</span><span class="cx"> }
</span><span class="lines">@@ -176,7 +176,7 @@
</span><span class="cx">     // If we're done decoding this frame, we don't need the BMPImageReader or
</span><span class="cx">     // PNGImageDecoder anymore.  (If we failed, these have already been
</span><span class="cx">     // cleared.)
</span><del>-    else if ((m_frameBufferCache.size() &gt; index) &amp;&amp; (m_frameBufferCache[index].status() == ImageFrame::FrameComplete)) {
</del><ins>+    else if ((m_frameBufferCache.size() &gt; index) &amp;&amp; m_frameBufferCache[index].isComplete()) {
</ins><span class="cx">         m_bmpReaders[index] = nullptr;
</span><span class="cx">         m_pngDecoders[index] = nullptr;
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformimagedecodersjpegJPEGImageDecodercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp (206155 => 206156)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp        2016-09-20 18:12:54 UTC (rev 206155)
+++ trunk/Source/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp        2016-09-20 18:24:41 UTC (rev 206156)
</span><span class="lines">@@ -537,7 +537,7 @@
</span><span class="cx">         m_frameBufferCache.resize(1);
</span><span class="cx"> 
</span><span class="cx">     ImageFrame&amp; frame = m_frameBufferCache[0];
</span><del>-    if (frame.status() != ImageFrame::FrameComplete)
</del><ins>+    if (!frame.isComplete())
</ins><span class="cx">         decode(false);
</span><span class="cx">     return &amp;frame;
</span><span class="cx"> }
</span><span class="lines">@@ -555,7 +555,7 @@
</span><span class="cx"> 
</span><span class="cx">     switch (colorSpace) {
</span><span class="cx">     case JCS_RGB:
</span><del>-        buffer.setPixel(currentAddress, jsample[0], jsample[1], jsample[2], 0xFF);
</del><ins>+        buffer.backingStore()-&gt;setPixel(currentAddress, jsample[0], jsample[1], jsample[2], 0xFF);
</ins><span class="cx">         break;
</span><span class="cx">     case JCS_CMYK:
</span><span class="cx">         // Source is 'Inverted CMYK', output is RGB.
</span><span class="lines">@@ -568,7 +568,7 @@
</span><span class="cx">         // From CMY (0..1) to RGB (0..1):
</span><span class="cx">         // R = 1 - C =&gt; 1 - (1 - iC*iK) =&gt; iC*iK  [G and B similar]
</span><span class="cx">         unsigned k = jsample[3];
</span><del>-        buffer.setPixel(currentAddress, jsample[0] * k / 255, jsample[1] * k / 255, jsample[2] * k / 255, 0xFF);
</del><ins>+        buffer.backingStore()-&gt;setPixel(currentAddress, jsample[0] * k / 255, jsample[1] * k / 255, jsample[2] * k / 255, 0xFF);
</ins><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="lines">@@ -592,7 +592,7 @@
</span><span class="cx">         if (destY &lt; 0)
</span><span class="cx">             continue;
</span><span class="cx"> 
</span><del>-        RGBA32* currentAddress = buffer.pixelAt(0, destY);
</del><ins>+        RGBA32* currentAddress = buffer.backingStore()-&gt;pixelAt(0, destY);
</ins><span class="cx">         for (int x = 0; x &lt; width; ++x) {
</span><span class="cx">             setPixel&lt;colorSpace&gt;(buffer, currentAddress, samples, isScaled ? m_scaledColumns[x] : x);
</span><span class="cx">             ++currentAddress;
</span><span class="lines">@@ -614,10 +614,10 @@
</span><span class="cx"> 
</span><span class="cx">     // Initialize the framebuffer if needed.
</span><span class="cx">     ImageFrame&amp; buffer = m_frameBufferCache[0];
</span><del>-    if (buffer.status() == ImageFrame::FrameEmpty) {
-        if (!buffer.initializeBackingStore(scaledSize(), m_premultiplyAlpha))
</del><ins>+    if (buffer.isEmpty()) {
+        if (!buffer.initialize(scaledSize(), m_premultiplyAlpha))
</ins><span class="cx">             return setFailed();
</span><del>-        buffer.setStatus(ImageFrame::FramePartial);
</del><ins>+        buffer.setDecoding(ImageFrame::Decoding::Partial);
</ins><span class="cx">         // The buffer is transparent outside the decoded area while the image is
</span><span class="cx">         // loading. The completed image will be marked fully opaque in jpegComplete().
</span><span class="cx">         buffer.setHasAlpha(true);
</span><span class="lines">@@ -628,7 +628,7 @@
</span><span class="cx"> #if defined(TURBO_JPEG_RGB_SWIZZLE)
</span><span class="cx">     if (!m_scaled &amp;&amp; turboSwizzled(info-&gt;out_color_space)) {
</span><span class="cx">         while (info-&gt;output_scanline &lt; info-&gt;output_height) {
</span><del>-            unsigned char* row = reinterpret_cast&lt;unsigned char*&gt;(buffer.pixelAt(0, info-&gt;output_scanline));
</del><ins>+            unsigned char* row = reinterpret_cast&lt;unsigned char*&gt;(buffer.backingStore()-&gt;pixelAt(0, info-&gt;output_scanline));
</ins><span class="cx">             if (jpeg_read_scanlines(info, &amp;row, 1) != 1)
</span><span class="cx">                 return false;
</span><span class="cx">          }
</span><span class="lines">@@ -661,7 +661,7 @@
</span><span class="cx">     // empty.
</span><span class="cx">     ImageFrame&amp; buffer = m_frameBufferCache[0];
</span><span class="cx">     buffer.setHasAlpha(false);
</span><del>-    buffer.setStatus(ImageFrame::FrameComplete);
</del><ins>+    buffer.setDecoding(ImageFrame::Decoding::Complete);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void JPEGImageDecoder::decode(bool onlySize)
</span><span class="lines">@@ -678,7 +678,7 @@
</span><span class="cx">         setFailed();
</span><span class="cx">     // If we're done decoding the image, we don't need the JPEGImageReader
</span><span class="cx">     // anymore.  (If we failed, |m_reader| has already been cleared.)
</span><del>-    else if (!m_frameBufferCache.isEmpty() &amp;&amp; (m_frameBufferCache[0].status() == ImageFrame::FrameComplete))
</del><ins>+    else if (!m_frameBufferCache.isEmpty() &amp;&amp; (m_frameBufferCache[0].isComplete()))
</ins><span class="cx">         m_reader = nullptr;
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformimagedecoderspngPNGImageDecodercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp (206155 => 206156)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp        2016-09-20 18:12:54 UTC (rev 206155)
+++ trunk/Source/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp        2016-09-20 18:24:41 UTC (rev 206156)
</span><span class="lines">@@ -261,7 +261,7 @@
</span><span class="cx">         m_frameBufferCache.resize(1);
</span><span class="cx"> 
</span><span class="cx">     ImageFrame&amp; frame = m_frameBufferCache[index];
</span><del>-    if (frame.status() != ImageFrame::FrameComplete)
</del><ins>+    if (!frame.isComplete())
</ins><span class="cx">         decode(false, index);
</span><span class="cx">     return &amp;frame;
</span><span class="cx"> }
</span><span class="lines">@@ -420,9 +420,9 @@
</span><span class="cx">         return;
</span><span class="cx"> #endif
</span><span class="cx">     ImageFrame&amp; buffer = m_frameBufferCache[m_currentFrame];
</span><del>-    if (buffer.status() == ImageFrame::FrameEmpty) {
</del><ins>+    if (buffer.isEmpty()) {
</ins><span class="cx">         png_structp png = m_reader-&gt;pngPtr();
</span><del>-        if (!buffer.initializeBackingStore(scaledSize(), m_premultiplyAlpha)) {
</del><ins>+        if (!buffer.initialize(scaledSize(), m_premultiplyAlpha)) {
</ins><span class="cx">             longjmp(JMPBUF(png), 1);
</span><span class="cx">             return;
</span><span class="cx">         }
</span><span class="lines">@@ -438,7 +438,7 @@
</span><span class="cx">             }
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        buffer.setStatus(ImageFrame::FramePartial);
</del><ins>+        buffer.setDecoding(ImageFrame::Decoding::Partial);
</ins><span class="cx">         buffer.setHasAlpha(false);
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(APNG)
</span><span class="lines">@@ -503,7 +503,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // Write the decoded row pixels to the frame buffer.
</span><del>-    RGBA32* address = buffer.pixelAt(0, y);
</del><ins>+    RGBA32* address = buffer.backingStore()-&gt;pixelAt(0, y);
</ins><span class="cx">     int width = scaledSize().width();
</span><span class="cx">     unsigned char nonTrivialAlphaMask = 0;
</span><span class="cx"> 
</span><span class="lines">@@ -512,7 +512,7 @@
</span><span class="cx">         for (int x = 0; x &lt; width; ++x, ++address) {
</span><span class="cx">             png_bytep pixel = row + m_scaledColumns[x] * colorChannels;
</span><span class="cx">             unsigned alpha = hasAlpha ? pixel[3] : 255;
</span><del>-            buffer.setPixel(address, pixel[0], pixel[1], pixel[2], alpha);
</del><ins>+            buffer.backingStore()-&gt;setPixel(address, pixel[0], pixel[1], pixel[2], alpha);
</ins><span class="cx">             nonTrivialAlphaMask |= (255 - alpha);
</span><span class="cx">         }
</span><span class="cx">     } else
</span><span class="lines">@@ -522,7 +522,7 @@
</span><span class="cx">         if (hasAlpha) {
</span><span class="cx">             for (int x = 0; x &lt; width; ++x, pixel += 4, ++address) {
</span><span class="cx">                 unsigned alpha = pixel[3];
</span><del>-                buffer.setPixel(address, pixel[0], pixel[1], pixel[2], alpha);
</del><ins>+                buffer.backingStore()-&gt;setPixel(address, pixel[0], pixel[1], pixel[2], alpha);
</ins><span class="cx">                 nonTrivialAlphaMask |= (255 - alpha);
</span><span class="cx">             }
</span><span class="cx">         } else {
</span><span class="lines">@@ -546,7 +546,7 @@
</span><span class="cx">     }
</span><span class="cx"> #endif
</span><span class="cx">     if (!m_frameBufferCache.isEmpty())
</span><del>-        m_frameBufferCache.first().setStatus(ImageFrame::FrameComplete);
</del><ins>+        m_frameBufferCache.first().setDecoding(ImageFrame::Decoding::Complete);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void PNGImageDecoder::decode(bool onlySize, unsigned haltAtFrame)
</span><span class="lines">@@ -643,11 +643,11 @@
</span><span class="cx">                 buffer.setDuration(m_delayNumerator * 1000 / m_delayDenominator);
</span><span class="cx"> 
</span><span class="cx">             if (m_dispose == 2)
</span><del>-                buffer.setDisposalMethod(ImageFrame::DisposeOverwritePrevious);
</del><ins>+                buffer.setDisposalMethod(ImageFrame::DisposalMethod::RestoreToPrevious);
</ins><span class="cx">             else if (m_dispose == 1)
</span><del>-                buffer.setDisposalMethod(ImageFrame::DisposeOverwriteBgcolor);
</del><ins>+                buffer.setDisposalMethod(ImageFrame::DisposalMethod::RestoreToBackground);
</ins><span class="cx">             else
</span><del>-                buffer.setDisposalMethod(ImageFrame::DisposeKeep);
</del><ins>+                buffer.setDisposalMethod(ImageFrame::DisposalMethod::DoNotDispose);
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         m_frameInfo = true;
</span><span class="lines">@@ -730,16 +730,16 @@
</span><span class="cx">     const Vector&lt;ImageFrame&gt;::iterator end(m_frameBufferCache.begin() + clearBeforeFrame);
</span><span class="cx"> 
</span><span class="cx">     Vector&lt;ImageFrame&gt;::iterator i(end);
</span><del>-    for (; (i != m_frameBufferCache.begin()) &amp;&amp; ((i-&gt;status() == ImageFrame::FrameEmpty) || (i-&gt;disposalMethod() == ImageFrame::DisposeOverwritePrevious)); --i) {
-        if ((i-&gt;status() == ImageFrame::FrameComplete) &amp;&amp; (i != end))
-            i-&gt;clearPixelData();
</del><ins>+    for (; (i != m_frameBufferCache.begin()) &amp;&amp; (i-&gt;isEmpty() || (i-&gt;disposalMethod() == ImageFrame::DisposalMethod::RestoreToPrevious)); --i) {
+        if (i-&gt;isComplete() &amp;&amp; (i != end))
+            i-&gt;clear();
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // Now |i| holds the last frame we need to preserve; clear prior frames.
</span><span class="cx">     for (Vector&lt;ImageFrame&gt;::iterator j(m_frameBufferCache.begin()); j != i; ++j) {
</span><del>-        ASSERT(j-&gt;status() != ImageFrame::FramePartial);
-        if (j-&gt;status() != ImageFrame::FrameEmpty)
-            j-&gt;clearPixelData();
</del><ins>+        ASSERT(!j-&gt;isPartial());
+        if (j-&gt;isEmpty())
+            j-&gt;clear();
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -748,60 +748,63 @@
</span><span class="cx">     if (frameIndex &gt;= frameCount())
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    IntRect frameRect(m_xOffset, m_yOffset, m_width, m_height);
-
-    // Make sure the frameRect doesn't extend outside the buffer.
-    if (frameRect.maxX() &gt; size().width())
-        frameRect.setWidth(size().width() - m_xOffset);
-    if (frameRect.maxY() &gt; size().height())
-        frameRect.setHeight(size().height() - m_yOffset);
-
</del><span class="cx">     ImageFrame&amp; buffer = m_frameBufferCache[frameIndex];
</span><del>-    int left = upperBoundScaledX(frameRect.x());
-    int right = lowerBoundScaledX(frameRect.maxX(), left);
-    int top = upperBoundScaledY(frameRect.y());
-    int bottom = lowerBoundScaledY(frameRect.maxY(), top);
-    buffer.setOriginalFrameRect(IntRect(left, top, right - left, bottom - top));
</del><span class="cx"> 
</span><span class="cx">     // The starting state for this frame depends on the previous frame's
</span><span class="cx">     // disposal method.
</span><span class="cx">     //
</span><del>-    // Frames that use the DisposeOverwritePrevious method are effectively
</del><ins>+    // Frames that use the DisposalMethod::RestoreToPrevious method are effectively
</ins><span class="cx">     // no-ops in terms of changing the starting state of a frame compared to
</span><span class="cx">     // the starting state of the previous frame, so skip over them.  (If the
</span><span class="cx">     // first frame specifies this method, it will get treated like
</span><span class="cx">     // DisposeOverwriteBgcolor below and reset to a completely empty image.)
</span><span class="cx">     const ImageFrame* prevBuffer = &amp;m_frameBufferCache[--frameIndex];
</span><del>-    ImageFrame::FrameDisposalMethod prevMethod = prevBuffer-&gt;disposalMethod();
-    while (frameIndex &amp;&amp; (prevMethod == ImageFrame::DisposeOverwritePrevious)) {
</del><ins>+    ImageFrame::DisposalMethod prevMethod = prevBuffer-&gt;disposalMethod();
+    while (frameIndex &amp;&amp; (prevMethod == ImageFrame::DisposalMethod::RestoreToPrevious)) {
</ins><span class="cx">         prevBuffer = &amp;m_frameBufferCache[--frameIndex];
</span><span class="cx">         prevMethod = prevBuffer-&gt;disposalMethod();
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     png_structp png = m_reader-&gt;pngPtr();
</span><del>-    ASSERT(prevBuffer-&gt;status() == ImageFrame::FrameComplete);
</del><ins>+    ASSERT(prevBuffer-&gt;isComplete());
</ins><span class="cx"> 
</span><del>-    if (prevMethod == ImageFrame::DisposeKeep) {
</del><ins>+    if (prevMethod == ImageFrame::DisposalMethod::DoNotDispose) {
</ins><span class="cx">         // Preserve the last frame as the starting state for this frame.
</span><del>-        if (!prevBuffer-&gt;backingStore() || !buffer.initializeBackingStore(*prevBuffer-&gt;backingStore()))
</del><ins>+        if (!prevBuffer-&gt;backingStore() || !buffer.initialize(*prevBuffer-&gt;backingStore()))
</ins><span class="cx">             longjmp(JMPBUF(png), 1);
</span><span class="cx">     } else {
</span><span class="cx">         // We want to clear the previous frame to transparent, without
</span><span class="cx">         // affecting pixels in the image outside of the frame.
</span><del>-        IntRect prevRect = prevBuffer-&gt;originalFrameRect();
</del><ins>+        IntRect prevRect = prevBuffer-&gt;backingStore()-&gt;frameRect();
</ins><span class="cx">         if (!frameIndex || prevRect.contains(IntRect(IntPoint(), scaledSize()))) {
</span><span class="cx">             // Clearing the first frame, or a frame the size of the whole
</span><span class="cx">             // image, results in a completely empty image.
</span><del>-            buffer.zeroFillPixelData();
</del><ins>+            buffer.backingStore()-&gt;clear();
+            buffer.setHasAlpha(true);
</ins><span class="cx">         } else {
</span><span class="cx">             // Copy the whole previous buffer, then clear just its frame.
</span><del>-            if (!prevBuffer-&gt;backingStore() || !buffer.initializeBackingStore(*prevBuffer-&gt;backingStore())) {
</del><ins>+            if (!prevBuffer-&gt;backingStore() || !buffer.initialize(*prevBuffer-&gt;backingStore())) {
</ins><span class="cx">                 longjmp(JMPBUF(png), 1);
</span><span class="cx">                 return;
</span><span class="cx">             }
</span><del>-            buffer.zeroFillFrameRect(prevRect);
</del><ins>+            buffer.backingStore()-&gt;clearRect(prevRect);
+            buffer.setHasAlpha(true);
</ins><span class="cx">         }
</span><span class="cx">     }
</span><ins>+    
+    IntRect frameRect(m_xOffset, m_yOffset, m_width, m_height);
+
+    // Make sure the frameRect doesn't extend outside the buffer.
+    if (frameRect.maxX() &gt; size().width())
+        frameRect.setWidth(size().width() - m_xOffset);
+    if (frameRect.maxY() &gt; size().height())
+        frameRect.setHeight(size().height() - m_yOffset);
+
+    int left = upperBoundScaledX(frameRect.x());
+    int right = lowerBoundScaledX(frameRect.maxX(), left);
+    int top = upperBoundScaledY(frameRect.y());
+    int bottom = lowerBoundScaledY(frameRect.maxY(), top);
+    buffer.backingStore()-&gt;setFrameRect(IntRect(left, top, right - left, bottom - top));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void PNGImageDecoder::frameComplete()
</span><span class="lines">@@ -810,12 +813,12 @@
</span><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     ImageFrame&amp; buffer = m_frameBufferCache[m_currentFrame];
</span><del>-    buffer.setStatus(ImageFrame::FrameComplete);
</del><ins>+    buffer.setDecoding(ImageFrame::Decoding::Complete);
</ins><span class="cx"> 
</span><span class="cx">     png_bytep interlaceBuffer = m_reader-&gt;interlaceBuffer();
</span><span class="cx"> 
</span><span class="cx">     if (m_currentFrame &amp;&amp; interlaceBuffer) {
</span><del>-        IntRect rect = buffer.originalFrameRect();
</del><ins>+        IntRect rect = buffer.backingStore()-&gt;frameRect();
</ins><span class="cx">         bool hasAlpha = m_reader-&gt;hasAlpha();
</span><span class="cx">         unsigned colorChannels = hasAlpha ? 4 : 3;
</span><span class="cx">         bool nonTrivialAlpha = false;
</span><span class="lines">@@ -825,15 +828,15 @@
</span><span class="cx"> #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
</span><span class="cx">         for (int y = 0; y &lt; rect.maxY() - rect.y(); ++y) {
</span><span class="cx">             png_bytep row = interlaceBuffer + (m_scaled ? m_scaledRows[y] : y) * colorChannels * size().width();
</span><del>-            RGBA32* address = buffer.pixelAt(rect.x(), y + rect.y());
</del><ins>+            RGBA32* address = buffer.backingStore()-&gt;pixelAt(rect.x(), y + rect.y());
</ins><span class="cx">             for (int x = 0; x &lt; rect.maxX() - rect.x(); ++x) {
</span><span class="cx">                 png_bytep pixel = row + (m_scaled ? m_scaledColumns[x] : x) * colorChannels;
</span><span class="cx">                 unsigned alpha = hasAlpha ? pixel[3] : 255;
</span><span class="cx">                 nonTrivialAlpha |= alpha &lt; 255;
</span><span class="cx">                 if (!m_blend)
</span><del>-                    buffer.setPixel(address++, pixel[0], pixel[1], pixel[2], alpha);
</del><ins>+                    buffer.backingStore()-&gt;setPixel(address++, pixel[0], pixel[1], pixel[2], alpha);
</ins><span class="cx">                 else
</span><del>-                    buffer.blendPixel(address++, pixel[0], pixel[1], pixel[2], alpha);
</del><ins>+                    buffer.backingStore()-&gt;blendPixel(address++, pixel[0], pixel[1], pixel[2], alpha);
</ins><span class="cx">             }
</span><span class="cx">         }
</span><span class="cx"> #else
</span><span class="lines">@@ -841,28 +844,30 @@
</span><span class="cx">         png_bytep row = interlaceBuffer;
</span><span class="cx">         for (int y = rect.y(); y &lt; rect.maxY(); ++y, row += colorChannels * size().width()) {
</span><span class="cx">             png_bytep pixel = row;
</span><del>-            RGBA32* address = buffer.pixelAt(rect.x(), y);
</del><ins>+            RGBA32* address = buffer.backingStore()-&gt;pixelAt(rect.x(), y);
</ins><span class="cx">             for (int x = rect.x(); x &lt; rect.maxX(); ++x, pixel += colorChannels) {
</span><span class="cx">                 unsigned alpha = hasAlpha ? pixel[3] : 255;
</span><span class="cx">                 nonTrivialAlpha |= alpha &lt; 255;
</span><span class="cx">                 if (!m_blend)
</span><del>-                    buffer.setPixel(address++, pixel[0], pixel[1], pixel[2], alpha);
</del><ins>+                    buffer.backingStore()-&gt;setPixel(address++, pixel[0], pixel[1], pixel[2], alpha);
</ins><span class="cx">                 else
</span><del>-                    buffer.blendPixel(address++, pixel[0], pixel[1], pixel[2], alpha);
</del><ins>+                    buffer.backingStore()-&gt;blendPixel(address++, pixel[0], pixel[1], pixel[2], alpha);
</ins><span class="cx">             }
</span><span class="cx">         }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">         if (!nonTrivialAlpha) {
</span><del>-            if (buffer.originalFrameRect().contains(IntRect(IntPoint(), scaledSize())))
</del><ins>+            IntRect rect = buffer.backingStore()-&gt;frameRect();
+            if (rect.contains(IntRect(IntPoint(), scaledSize())))
</ins><span class="cx">                 buffer.setHasAlpha(false);
</span><span class="cx">             else {
</span><span class="cx">                 size_t frameIndex = m_currentFrame;
</span><span class="cx">                 const ImageFrame* prevBuffer = &amp;m_frameBufferCache[--frameIndex];
</span><del>-                while (frameIndex &amp;&amp; (prevBuffer-&gt;disposalMethod() == ImageFrame::DisposeOverwritePrevious))
</del><ins>+                while (frameIndex &amp;&amp; (prevBuffer-&gt;disposalMethod() == ImageFrame::DisposalMethod::RestoreToPrevious))
</ins><span class="cx">                     prevBuffer = &amp;m_frameBufferCache[--frameIndex];
</span><del>-                if ((prevBuffer-&gt;disposalMethod() == ImageFrame::DisposeOverwriteBgcolor)
-                    &amp;&amp; !prevBuffer-&gt;hasAlpha() &amp;&amp; buffer.originalFrameRect().contains(prevBuffer-&gt;originalFrameRect()))
</del><ins>+
+                IntRect prevRect = prevBuffer-&gt;backingStore()-&gt;frameRect();
+                if ((prevBuffer-&gt;disposalMethod() == ImageFrame::DisposalMethod::RestoreToBackground) &amp;&amp; !prevBuffer-&gt;hasAlpha() &amp;&amp; rect.contains(prevRect))
</ins><span class="cx">                     buffer.setHasAlpha(false);
</span><span class="cx">             }
</span><span class="cx">         } else if (!m_blend &amp;&amp; !buffer.hasAlpha())
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformimagedecoderspngPNGImageDecoderh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/image-decoders/png/PNGImageDecoder.h (206155 => 206156)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/image-decoders/png/PNGImageDecoder.h        2016-09-20 18:12:54 UTC (rev 206155)
+++ trunk/Source/WebCore/platform/image-decoders/png/PNGImageDecoder.h        2016-09-20 18:24:41 UTC (rev 206156)
</span><span class="lines">@@ -45,7 +45,7 @@
</span><span class="cx">         String filenameExtension() const override { return &quot;png&quot;; }
</span><span class="cx"> #if ENABLE(APNG)
</span><span class="cx">         size_t frameCount() override { return m_frameCount; }
</span><del>-        int repetitionCount() const override { return m_playCount-1; }
</del><ins>+        RepetitionCount repetitionCount() const override { return m_playCount-1; }
</ins><span class="cx"> #endif
</span><span class="cx">         bool isSizeAvailable() override;
</span><span class="cx">         bool setSize(const IntSize&amp;) override;
</span><span class="lines">@@ -73,7 +73,7 @@
</span><span class="cx">                 return false;
</span><span class="cx"> 
</span><span class="cx">             for (auto&amp; imageFrame : m_frameBufferCache) {
</span><del>-                if (imageFrame.status() != ImageFrame::FrameComplete)
</del><ins>+                if (!imageFrame.isComplete())
</ins><span class="cx">                     return false;
</span><span class="cx">             }
</span><span class="cx"> 
</span><span class="lines">@@ -82,7 +82,7 @@
</span><span class="cx"> 
</span><span class="cx">         bool isCompleteAtIndex(size_t index)
</span><span class="cx">         {
</span><del>-            return (index &lt; m_frameBufferCache.size() &amp;&amp; m_frameBufferCache[index].status() == ImageFrame::FrameComplete);
</del><ins>+            return (index &lt; m_frameBufferCache.size() &amp;&amp; m_frameBufferCache[index].isComplete());
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">     private:
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformimagedecoderswebpWEBPImageDecodercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/image-decoders/webp/WEBPImageDecoder.cpp (206155 => 206156)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/image-decoders/webp/WEBPImageDecoder.cpp        2016-09-20 18:12:54 UTC (rev 206155)
+++ trunk/Source/WebCore/platform/image-decoders/webp/WEBPImageDecoder.cpp        2016-09-20 18:24:41 UTC (rev 206156)
</span><span class="lines">@@ -82,7 +82,7 @@
</span><span class="cx">         m_frameBufferCache.resize(1);
</span><span class="cx"> 
</span><span class="cx">     ImageFrame&amp; frame = m_frameBufferCache[0];
</span><del>-    if (frame.status() != ImageFrame::FrameComplete)
</del><ins>+    if (!frame.isComplete())
</ins><span class="cx">         decode(false);
</span><span class="cx">     return &amp;frame;
</span><span class="cx"> }
</span><span class="lines">@@ -123,12 +123,12 @@
</span><span class="cx"> 
</span><span class="cx">     ASSERT(!m_frameBufferCache.isEmpty());
</span><span class="cx">     ImageFrame&amp; buffer = m_frameBufferCache[0];
</span><del>-    ASSERT(buffer.status() != ImageFrame::FrameComplete);
</del><ins>+    ASSERT(!buffer.isComplete());
</ins><span class="cx"> 
</span><del>-    if (buffer.status() == ImageFrame::FrameEmpty) {
-        if (!buffer.initializeBackingStore(size(), m_premultiplyAlpha))
</del><ins>+    if (buffer.isEmpty()) {
+        if (!buffer.initialize(size(), m_premultiplyAlpha))
</ins><span class="cx">             return setFailed();
</span><del>-        buffer.setStatus(ImageFrame::FramePartial);
</del><ins>+        buffer.setDecoding(ImageFrame::Decoding::Partial);
</ins><span class="cx">         buffer.setHasAlpha(m_hasAlpha);
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -137,7 +137,7 @@
</span><span class="cx">         if (!m_premultiplyAlpha)
</span><span class="cx">             mode = outputMode(false);
</span><span class="cx">         int rowStride = size().width() * sizeof(RGBA32);
</span><del>-        uint8_t* output = reinterpret_cast&lt;uint8_t*&gt;(buffer.pixelAt(0, 0));
</del><ins>+        uint8_t* output = reinterpret_cast&lt;uint8_t*&gt;(buffer.backingStore()-&gt;pixelAt(0, 0));
</ins><span class="cx">         int outputSize = size().height() * rowStride;
</span><span class="cx">         m_decoder = WebPINewRGB(mode, output, outputSize, rowStride);
</span><span class="cx">         if (!m_decoder)
</span><span class="lines">@@ -146,7 +146,7 @@
</span><span class="cx"> 
</span><span class="cx">     switch (WebPIUpdate(m_decoder, dataBytes, dataSize)) {
</span><span class="cx">     case VP8_STATUS_OK:
</span><del>-        buffer.setStatus(ImageFrame::FrameComplete);
</del><ins>+        buffer.setDecoding(ImageFrame::Decoding::Complete);
</ins><span class="cx">         clear();
</span><span class="cx">         return true;
</span><span class="cx">     case VP8_STATUS_SUSPENDED:
</span></span></pre>
</div>
</div>

</body>
</html>