<!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>[171964] 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/171964">171964</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2014-08-01 22:10:46 -0700 (Fri, 01 Aug 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Unreviewed, rolling out <a href="http://trac.webkit.org/projects/webkit/changeset/171957">r171957</a>.
https://bugs.webkit.org/show_bug.cgi?id=135538

Caused GTK assertions and test failures (Requested by smfr on
#webkit).

Reverted changeset:

&quot;Clean up image subsampling code, make it less iOS-specific&quot;
https://bugs.webkit.org/show_bug.cgi?id=134916
http://trac.webkit.org/changeset/171957</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreWebCoreexpin">trunk/Source/WebCore/WebCore.exp.in</a></li>
<li><a href="#trunkSourceWebCoreWebCorexcodeprojprojectpbxproj">trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebCoreloadercacheCachedImagecpp">trunk/Source/WebCore/loader/cache/CachedImage.cpp</a></li>
<li><a href="#trunkSourceWebCoreloadercacheCachedImageh">trunk/Source/WebCore/loader/cache/CachedImage.h</a></li>
<li><a href="#trunkSourceWebCorepageSettingscpp">trunk/Source/WebCore/page/Settings.cpp</a></li>
<li><a href="#trunkSourceWebCorepageSettingsin">trunk/Source/WebCore/page/Settings.in</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="#trunkSourceWebCoreplatformgraphicsGraphicsContexth">trunk/Source/WebCore/platform/graphics/GraphicsContext.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="#trunkSourceWebCoreplatformgraphicscairoBitmapImageCairocpp">trunk/Source/WebCore/platform/graphics/cairo/BitmapImageCairo.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicscgBitmapImageCGcpp">trunk/Source/WebCore/platform/graphics/cg/BitmapImageCG.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicscgGraphicsContext3DCGcpp">trunk/Source/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicscgGraphicsContextCGcpp">trunk/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicscgImageBufferCGcpp">trunk/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicscgImageSourceCGcpp">trunk/Source/WebCore/platform/graphics/cg/ImageSourceCG.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsmacImageMacmm">trunk/Source/WebCore/platform/graphics/mac/ImageMac.mm</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicswinceImageWinCEcpp">trunk/Source/WebCore/platform/graphics/wince/ImageWinCE.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (171963 => 171964)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2014-08-02 04:00:18 UTC (rev 171963)
+++ trunk/Source/WebCore/ChangeLog        2014-08-02 05:10:46 UTC (rev 171964)
</span><span class="lines">@@ -1,3 +1,17 @@
</span><ins>+2014-08-01  Commit Queue  &lt;commit-queue@webkit.org&gt;
+
+        Unreviewed, rolling out r171957.
+        https://bugs.webkit.org/show_bug.cgi?id=135538
+
+        Caused GTK assertions and test failures (Requested by smfr on
+        #webkit).
+
+        Reverted changeset:
+
+        &quot;Clean up image subsampling code, make it less iOS-specific&quot;
+        https://bugs.webkit.org/show_bug.cgi?id=134916
+        http://trac.webkit.org/changeset/171957
+
</ins><span class="cx"> 2014-08-01  Myles C. Maxfield  &lt;litherum@gmail.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [CMake] Allow CMake to find GLib on FreeBSD
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCoreexpin"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.exp.in (171963 => 171964)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.exp.in        2014-08-02 04:00:18 UTC (rev 171963)
+++ trunk/Source/WebCore/WebCore.exp.in        2014-08-02 05:10:46 UTC (rev 171964)
</span><span class="lines">@@ -521,7 +521,6 @@
</span><span class="cx"> __ZN7WebCore15GraphicsContext11clearShadowEv
</span><span class="cx"> __ZN7WebCore15GraphicsContext12setFillColorERKNS_5ColorENS_10ColorSpaceE
</span><span class="cx"> __ZN7WebCore15GraphicsContext14setStrokeColorERKNS_5ColorENS_10ColorSpaceE
</span><del>-__ZN7WebCore15GraphicsContext15drawNativeImageEP7CGImageRKNS_9FloatSizeENS_10ColorSpaceERKNS_9FloatRectES9_NS_17CompositeOperatorENS_9BlendModeENS_16ImageOrientationE
</del><span class="cx"> __ZN7WebCore15GraphicsContext15setFillGradientEN3WTF10PassRefPtrINS_8GradientEEE
</span><span class="cx"> __ZN7WebCore15GraphicsContext18setShouldAntialiasEb
</span><span class="cx"> __ZN7WebCore15GraphicsContext19setIsCALayerContextEb
</span><span class="lines">@@ -2238,6 +2237,7 @@
</span><span class="cx"> __ZN7WebCore13getRawCookiesERKNS_21NetworkStorageSessionERKNS_3URLES5_RN3WTF6VectorINS_6CookieELm0ENS6_15CrashOnOverflowEEE
</span><span class="cx"> __ZN7WebCore13toDeviceSpaceERKNS_9FloatRectEP8NSWindow
</span><span class="cx"> __ZN7WebCore14cookiesEnabledERKNS_21NetworkStorageSessionERKNS_3URLES5_
</span><ins>+__ZN7WebCore15GraphicsContext15drawNativeImageEP7CGImageRKNS_9FloatSizeENS_10ColorSpaceERKNS_9FloatRectES9_fNS_17CompositeOperatorENS_9BlendModeENS_16ImageOrientationE
</ins><span class="cx"> __ZN7WebCore15GraphicsContextC1EP9CGContext
</span><span class="cx"> __ZN7WebCore15ResourceRequest41updateFromDelegatePreservingOldPropertiesERKS0_
</span><span class="cx"> __ZN7WebCore16FontPlatformDataC1EP6NSFontfbbbNS_15FontOrientationENS_16FontWidthVariantE
</span><span class="lines">@@ -2588,6 +2588,7 @@
</span><span class="cx"> __ZN7WebCore15DatabaseTracker7trackerEv
</span><span class="cx"> __ZN7WebCore15GraphicsContext12drawBidiTextERKNS_4FontERKNS_7TextRunERKNS_10FloatPointENS1_24CustomFontNotReadyActionEPNS_10BidiStatusEi
</span><span class="cx"> __ZN7WebCore15GraphicsContext15drawLineForTextERKNS_10FloatPointEfbb
</span><ins>+__ZN7WebCore15GraphicsContext15drawNativeImageEP7CGImageRKNS_9FloatSizeENS_10ColorSpaceERKNS_9FloatRectES9_fNS_17CompositeOperatorENS_9BlendModeENS_16ImageOrientationE
</ins><span class="cx"> __ZN7WebCore15GraphicsContext22setEmojiDrawingEnabledEb
</span><span class="cx"> __ZN7WebCore15GraphicsContext23setIsAcceleratedContextEb
</span><span class="cx"> __ZN7WebCore15GraphicsContextC1EP9CGContextb
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (171963 => 171964)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2014-08-02 04:00:18 UTC (rev 171963)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2014-08-02 05:10:46 UTC (rev 171964)
</span><span class="lines">@@ -473,7 +473,6 @@
</span><span class="cx">                 0F1774801378B772009DA76A /* ScrollAnimatorIOS.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F17747E1378B771009DA76A /* ScrollAnimatorIOS.h */; };
</span><span class="cx">                 0F1774811378B772009DA76A /* ScrollAnimatorIOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0F17747F1378B772009DA76A /* ScrollAnimatorIOS.mm */; };
</span><span class="cx">                 0F29C16E1300C2E2002D794E /* AccessibilityAllInOne.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F29C16D1300C2E2002D794E /* AccessibilityAllInOne.cpp */; };
</span><del>-                0F3C725E1974874B00AEDD0C /* ImageSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F3C725D1974874B00AEDD0C /* ImageSource.cpp */; };
</del><span class="cx">                 0F3DD44F12F5EA1B000D9190 /* ShadowBlur.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F3DD44D12F5EA1B000D9190 /* ShadowBlur.cpp */; };
</span><span class="cx">                 0F3DD45012F5EA1B000D9190 /* ShadowBlur.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F3DD44E12F5EA1B000D9190 /* ShadowBlur.h */; };
</span><span class="cx">                 0F3F0E59157030C3006DA57F /* RenderGeometryMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F3F0E57157030C3006DA57F /* RenderGeometryMap.cpp */; };
</span><span class="lines">@@ -7415,7 +7414,6 @@
</span><span class="cx">                 0F17747E1378B771009DA76A /* ScrollAnimatorIOS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ScrollAnimatorIOS.h; path = ios/ScrollAnimatorIOS.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F17747F1378B772009DA76A /* ScrollAnimatorIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ScrollAnimatorIOS.mm; path = ios/ScrollAnimatorIOS.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F29C16D1300C2E2002D794E /* AccessibilityAllInOne.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AccessibilityAllInOne.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><del>-                0F3C725D1974874B00AEDD0C /* ImageSource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageSource.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</del><span class="cx">                 0F3DD44D12F5EA1B000D9190 /* ShadowBlur.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ShadowBlur.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F3DD44E12F5EA1B000D9190 /* ShadowBlur.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ShadowBlur.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F3F0E57157030C3006DA57F /* RenderGeometryMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderGeometryMap.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -20492,7 +20490,6 @@
</span><span class="cx">                                 A8748D6612CC3763001FBA41 /* ImageOrientation.h */,
</span><span class="cx">                                 49291E4A134172C800E753DE /* ImageRenderingMode.h */,
</span><span class="cx">                                 B27535430B053814002CE64F /* ImageSource.h */,
</span><del>-                                0F3C725D1974874B00AEDD0C /* ImageSource.cpp */,
</del><span class="cx">                                 07941793166EA04E009416C2 /* InbandTextTrackPrivate.h */,
</span><span class="cx">                                 07CE77D416712A6A00C55A47 /* InbandTextTrackPrivateClient.h */,
</span><span class="cx">                                 2D46F04D17B96FBD005647F0 /* IntPoint.cpp */,
</span><span class="lines">@@ -29441,7 +29438,6 @@
</span><span class="cx">                                 97BC6A441505F081001B74AC /* SQLResultSetRowList.cpp in Sources */,
</span><span class="cx">                                 97BC6A471505F081001B74AC /* SQLStatement.cpp in Sources */,
</span><span class="cx">                                 FE8A674716CDD19E00930BF8 /* SQLStatementBackend.cpp in Sources */,
</span><del>-                                0F3C725E1974874B00AEDD0C /* ImageSource.cpp in Sources */,
</del><span class="cx">                                 97BC6A4D1505F081001B74AC /* SQLStatementSync.cpp in Sources */,
</span><span class="cx">                                 97BC6A4F1505F081001B74AC /* SQLTransaction.cpp in Sources */,
</span><span class="cx">                                 FEE1811316C319E800084849 /* SQLTransactionBackend.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceWebCoreloadercacheCachedImagecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/cache/CachedImage.cpp (171963 => 171964)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/cache/CachedImage.cpp        2014-08-02 04:00:18 UTC (rev 171963)
+++ trunk/Source/WebCore/loader/cache/CachedImage.cpp        2014-08-02 05:10:46 UTC (rev 171964)
</span><span class="lines">@@ -289,7 +289,16 @@
</span><span class="cx">     }
</span><span class="cx"> #else
</span><span class="cx">     if (m_image-&gt;isBitmapImage() &amp;&amp; (renderer &amp;&amp; renderer-&gt;shouldRespectImageOrientation() == RespectImageOrientation))
</span><ins>+#if !PLATFORM(IOS)
</ins><span class="cx">         imageSize = LayoutSize(toBitmapImage(m_image.get())-&gt;sizeRespectingOrientation());
</span><ins>+#else
+    {
+        // On iOS, the image may have been subsampled to accommodate our size restrictions. However
+        // we should tell the renderer what the original size was.
+        imageSize = LayoutSize(toBitmapImage(m_image.get())-&gt;originalSizeRespectingOrientation());
+    } else if (m_image-&gt;isBitmapImage())
+        imageSize = LayoutSize(toBitmapImage(m_image.get())-&gt;originalSize());
+#endif // !PLATFORM(IOS)
</ins><span class="cx"> #endif // ENABLE(CSS_IMAGE_ORIENTATION)
</span><span class="cx"> 
</span><span class="cx">     else if (m_image-&gt;isSVGImage() &amp;&amp; sizeType == UsedSize) {
</span><span class="lines">@@ -343,7 +352,6 @@
</span><span class="cx">     // Create the image if it doesn't yet exist.
</span><span class="cx">     if (m_image)
</span><span class="cx">         return;
</span><del>-
</del><span class="cx"> #if USE(CG) &amp;&amp; !USE(WEBKIT_IMAGE_DECODERS)
</span><span class="cx">     else if (m_response.mimeType() == &quot;application/pdf&quot;)
</span><span class="cx">         m_image = PDFDocumentImage::create(this);
</span><span class="lines">@@ -352,10 +360,8 @@
</span><span class="cx">         RefPtr&lt;SVGImage&gt; svgImage = SVGImage::create(this);
</span><span class="cx">         m_svgImageCache = std::make_unique&lt;SVGImageCache&gt;(svgImage.get());
</span><span class="cx">         m_image = svgImage.release();
</span><del>-    } else {
</del><ins>+    } else
</ins><span class="cx">         m_image = BitmapImage::create(this);
</span><del>-        toBitmapImage(m_image.get())-&gt;setAllowSubsampling(m_loader &amp;&amp; m_loader-&gt;frameLoader()-&gt;frame().settings().imageSubsamplingEnabled());
-    }
</del><span class="cx"> 
</span><span class="cx">     if (m_image) {
</span><span class="cx">         // Send queued container size requests.
</span><span class="lines">@@ -512,6 +518,8 @@
</span><span class="cx"> bool CachedImage::currentFrameKnownToBeOpaque(const RenderElement* renderer)
</span><span class="cx"> {
</span><span class="cx">     Image* image = imageForRenderer(renderer);
</span><ins>+    if (image-&gt;isBitmapImage())
+        image-&gt;nativeImageForCurrentFrame(); // force decode
</ins><span class="cx">     return image-&gt;currentFrameKnownToBeOpaque();
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreloadercacheCachedImageh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/cache/CachedImage.h (171963 => 171964)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/cache/CachedImage.h        2014-08-02 04:00:18 UTC (rev 171963)
+++ trunk/Source/WebCore/loader/cache/CachedImage.h        2014-08-02 05:10:46 UTC (rev 171964)
</span><span class="lines">@@ -59,7 +59,7 @@
</span><span class="cx">     Image* image(); // Returns the nullImage() if the image is not available yet.
</span><span class="cx">     Image* imageForRenderer(const RenderObject*); // Returns the nullImage() if the image is not available yet.
</span><span class="cx">     bool hasImage() const { return m_image.get(); }
</span><del>-    bool currentFrameKnownToBeOpaque(const RenderElement*);
</del><ins>+    bool currentFrameKnownToBeOpaque(const RenderElement*); // Side effect: ensures decoded image is in cache, therefore should only be called when about to draw the image.
</ins><span class="cx"> 
</span><span class="cx">     std::pair&lt;Image*, float&gt; brokenImage(float deviceScaleFactor) const; // Returns an image and the image's resolution scale factor.
</span><span class="cx">     bool willPaintBrokenImage() const; 
</span></span></pre></div>
<a id="trunkSourceWebCorepageSettingscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/Settings.cpp (171963 => 171964)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/Settings.cpp        2014-08-02 04:00:18 UTC (rev 171963)
+++ trunk/Source/WebCore/page/Settings.cpp        2014-08-02 05:10:46 UTC (rev 171964)
</span><span class="lines">@@ -127,7 +127,6 @@
</span><span class="cx"> static const bool defaultMediaPlaybackAllowsInline = false;
</span><span class="cx"> static const bool defaultMediaPlaybackRequiresUserGesture = true;
</span><span class="cx"> static const bool defaultShouldRespectImageOrientation = true;
</span><del>-static const bool defaultImageSubsamplingEnabled = true;
</del><span class="cx"> static const bool defaultScrollingTreeIncludesFrames = true;
</span><span class="cx"> #else
</span><span class="cx"> static const bool defaultFixedPositionCreatesStackingContext = false;
</span><span class="lines">@@ -136,7 +135,6 @@
</span><span class="cx"> static const bool defaultMediaPlaybackAllowsInline = true;
</span><span class="cx"> static const bool defaultMediaPlaybackRequiresUserGesture = false;
</span><span class="cx"> static const bool defaultShouldRespectImageOrientation = false;
</span><del>-static const bool defaultImageSubsamplingEnabled = false;
</del><span class="cx"> static const bool defaultScrollingTreeIncludesFrames = false;
</span><span class="cx"> #endif
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorepageSettingsin"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/Settings.in (171963 => 171964)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/Settings.in        2014-08-02 04:00:18 UTC (rev 171963)
+++ trunk/Source/WebCore/page/Settings.in        2014-08-02 05:10:46 UTC (rev 171964)
</span><span class="lines">@@ -141,7 +141,6 @@
</span><span class="cx"> needsIsLoadingInAPISenseQuirk initial=false
</span><span class="cx"> 
</span><span class="cx"> shouldRespectImageOrientation initial=defaultShouldRespectImageOrientation
</span><del>-imageSubsamplingEnabled initial=defaultImageSubsamplingEnabled
</del><span class="cx"> wantsBalancedSetDefersLoadingBehavior initial=false
</span><span class="cx"> requestAnimationFrameEnabled initial=true
</span><span class="cx"> deviceSupportsTouch initial=false
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsBitmapImagecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/BitmapImage.cpp (171963 => 171964)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/BitmapImage.cpp        2014-08-02 04:00:18 UTC (rev 171963)
+++ trunk/Source/WebCore/platform/graphics/BitmapImage.cpp        2014-08-02 05:10:46 UTC (rev 171964)
</span><span class="lines">@@ -44,12 +44,12 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><ins>+// FIXME: We should better integrate the iOS and non-iOS code in this class. Unlike other ports, the
+// iOS port caches the metadata for a frame without decoding the image.
</ins><span class="cx"> BitmapImage::BitmapImage(ImageObserver* observer)
</span><span class="cx">     : Image(observer)
</span><del>-    , m_minimumSubsamplingLevel(0)
-    , m_imageOrientation(OriginTopLeft)
-    , m_shouldRespectImageOrientation(false)
</del><span class="cx">     , m_currentFrame(0)
</span><ins>+    , m_frames(0)
</ins><span class="cx">     , m_repetitionCount(cAnimationNone)
</span><span class="cx">     , m_repetitionCountStatus(Unknown)
</span><span class="cx">     , m_repetitionsComplete(0)
</span><span class="lines">@@ -61,9 +61,6 @@
</span><span class="cx">     // FIXME: We should expose a setting to enable/disable progressive loading remove the PLATFORM(IOS)-guard.
</span><span class="cx">     , m_progressiveLoadChunkTime(0)
</span><span class="cx">     , m_progressiveLoadChunkCount(0)
</span><del>-    , m_allowSubsampling(true)
-#else
-    , m_allowSubsampling(false)
</del><span class="cx"> #endif
</span><span class="cx">     , m_isSolidColor(false)
</span><span class="cx">     , m_checkedForSolidColor(false)
</span><span class="lines">@@ -83,17 +80,6 @@
</span><span class="cx">     stopAnimation();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool BitmapImage::haveFrameAtIndex(size_t index)
-{
-    if (index &gt;= frameCount())
-        return false;
-
-    if (index &gt;= m_frames.size())
-        return false;
-
-    return m_frames[index].m_frame;
-}
-
</del><span class="cx"> bool BitmapImage::hasSingleSecurityOrigin() const
</span><span class="cx"> {
</span><span class="cx">     return true;
</span><span class="lines">@@ -166,7 +152,11 @@
</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>+#if PLATFORM(IOS)
+void BitmapImage::cacheFrame(size_t index, float scaleHint)
+#else
+void BitmapImage::cacheFrame(size_t index)
+#endif
</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">@@ -174,27 +164,26 @@
</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_frame = m_source.createFrameAtIndex(index, subsamplingLevel);
-        m_frames[index].m_subsamplingLevel = subsamplingLevel;
-        if (numFrames == 1 &amp;&amp; m_frames[index].m_frame)
-            checkForSolidColor();
-    }
</del><ins>+#if PLATFORM(IOS)
+    m_frames[index].m_frame = m_source.createFrameAtIndex(index, &amp;scaleHint);
+    m_frames[index].m_subsamplingScale = scaleHint;
+#else
+    m_frames[index].m_frame = m_source.createFrameAtIndex(index);
+#endif
+    if (numFrames == 1 &amp;&amp; m_frames[index].m_frame)
+        checkForSolidColor();
</ins><span class="cx"> 
</span><span class="cx">     m_frames[index].m_orientation = m_source.orientationAtIndex(index);
</span><span class="cx">     m_frames[index].m_haveMetadata = true;
</span><span class="cx">     m_frames[index].m_isComplete = m_source.frameIsCompleteAtIndex(index);
</span><del>-
</del><span class="cx">     if (repetitionCount(false) != cAnimationNone)
</span><span class="cx">         m_frames[index].m_duration = m_source.frameDurationAtIndex(index);
</span><del>-
</del><span class="cx">     m_frames[index].m_hasAlpha = m_source.frameHasAlphaAtIndex(index);
</span><del>-    m_frames[index].m_frameBytes = m_source.frameBytesAtIndex(index, subsamplingLevel);
</del><ins>+    m_frames[index].m_frameBytes = m_source.frameBytesAtIndex(index);
</ins><span class="cx"> 
</span><del>-    const IntSize frameSize(index ? m_source.frameSizeAtIndex(index, subsamplingLevel) : m_size);
-    if (!subsamplingLevel &amp;&amp; frameSize != m_size)
</del><ins>+    const IntSize frameSize(index ? m_source.frameSizeAtIndex(index) : m_size);
+    if (frameSize != m_size)
</ins><span class="cx">         m_hasUniformFrameSize = false;
</span><del>-
</del><span class="cx">     if (m_frames[index].m_frame) {
</span><span class="cx">         int deltaBytes = safeCast&lt;int&gt;(m_frames[index].m_frameBytes);
</span><span class="cx">         m_decodedSize += deltaBytes;
</span><span class="lines">@@ -207,15 +196,30 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+#if PLATFORM(IOS)
+void BitmapImage::cacheFrameInfo(size_t index)
+{
+    size_t numFrames = frameCount();
+
+    if (m_frames.size() &lt; numFrames)
+        m_frames.resize(numFrames);
+
+    ASSERT(!m_frames[index].m_haveInfo);
+
+    if (shouldAnimate())
+        m_frames[index].m_duration = m_source.frameDurationAtIndex(index);
+    m_frames[index].m_hasAlpha = m_source.frameHasAlphaAtIndex(index);
+    m_frames[index].m_haveInfo = true;
+}
+#endif
+
</ins><span class="cx"> void BitmapImage::didDecodeProperties() const
</span><span class="cx"> {
</span><span class="cx">     if (m_decodedSize)
</span><span class="cx">         return;
</span><del>-
</del><span class="cx">     size_t updatedSize = m_source.bytesDecodedToDetermineProperties();
</span><span class="cx">     if (m_decodedPropertiesSize == updatedSize)
</span><span class="cx">         return;
</span><del>-
</del><span class="cx">     int deltaBytes = updatedSize - m_decodedPropertiesSize;
</span><span class="cx"> #if !ASSERT_DISABLED
</span><span class="cx">     bool overflow = updatedSize &gt; m_decodedPropertiesSize &amp;&amp; deltaBytes &lt; 0;
</span><span class="lines">@@ -234,13 +238,13 @@
</span><span class="cx"> 
</span><span class="cx">     m_size = m_source.size(description);
</span><span class="cx">     m_sizeRespectingOrientation = m_source.size(ImageOrientationDescription(RespectImageOrientation, description.imageOrientation()));
</span><del>-
</del><span class="cx">     m_imageOrientation = static_cast&lt;unsigned&gt;(description.imageOrientation());
</span><span class="cx">     m_shouldRespectImageOrientation = static_cast&lt;unsigned&gt;(description.respectImageOrientation());
</span><del>-
</del><ins>+#if PLATFORM(IOS)
+    m_originalSize = m_source.originalSize();
+    m_originalSizeRespectingOrientation = m_source.originalSize(RespectImageOrientation);
+#endif
</ins><span class="cx">     m_haveSize = true;
</span><del>-
-    determineMinimumSubsamplingLevel();
</del><span class="cx">     didDecodeProperties();
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -256,6 +260,29 @@
</span><span class="cx">     return m_sizeRespectingOrientation;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+#if PLATFORM(IOS)
+FloatSize BitmapImage::originalSize() const
+{
+    updateSize();
+    return m_originalSize;
+}
+
+IntSize BitmapImage::originalSizeRespectingOrientation() const
+{
+    updateSize();
+    return m_originalSizeRespectingOrientation;
+}
+#endif
+
+IntSize BitmapImage::currentFrameSize() const
+{
+    if (!m_currentFrame || m_hasUniformFrameSize)
+        return IntSize(size());
+    IntSize frameSize = m_source.frameSizeAtIndex(m_currentFrame);
+    didDecodeProperties();
+    return frameSize;
+}
+
</ins><span class="cx"> bool BitmapImage::getHotSpot(IntPoint&amp; hotSpot) const
</span><span class="cx"> {
</span><span class="cx">     bool result = m_source.getHotSpot(hotSpot);
</span><span class="lines">@@ -296,7 +323,6 @@
</span><span class="cx">     }
</span><span class="cx">     destroyMetadataAndNotify(frameBytesCleared);
</span><span class="cx"> #else
</span><del>-    // FIXME: why is this different for iOS?
</del><span class="cx">     int deltaBytes = 0;
</span><span class="cx">     if (!m_frames.isEmpty()) {
</span><span class="cx">         int bytes = m_frames[m_frames.size() - 1].m_frameBytes;
</span><span class="lines">@@ -364,59 +390,85 @@
</span><span class="cx">     return m_sizeAvailable;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool BitmapImage::ensureFrameIsCached(size_t index, ImageFrameCaching frameCaching)
</del><ins>+#if !PLATFORM(IOS)
+bool BitmapImage::ensureFrameIsCached(size_t index)
</ins><span class="cx"> {
</span><span class="cx">     if (index &gt;= frameCount())
</span><span class="cx">         return false;
</span><span class="cx"> 
</span><del>-    if (index &gt;= m_frames.size()
-        || (frameCaching == CacheMetadataAndFrame &amp;&amp; !m_frames[index].m_frame)
-        || (frameCaching == CacheMetadataOnly &amp;&amp; !m_frames[index].m_haveMetadata))
-        cacheFrame(index, 0, frameCaching);
</del><ins>+    if (index &gt;= m_frames.size() || !m_frames[index].m_frame)
+        cacheFrame(index);
+    return true;
+}
+#else
+bool BitmapImage::ensureFrameInfoIsCached(size_t index)
+{
+    if (index &gt;= frameCount())
+        return false;
</ins><span class="cx"> 
</span><ins>+    if (index &gt;= m_frames.size() || !m_frames[index].m_haveInfo)
+        cacheFrameInfo(index);
</ins><span class="cx">     return true;
</span><span class="cx"> }
</span><ins>+#endif
</ins><span class="cx"> 
</span><del>-PassNativeImagePtr BitmapImage::frameAtIndex(size_t index, float presentationScaleHint)
</del><ins>+PassNativeImagePtr BitmapImage::frameAtIndex(size_t index)
</ins><span class="cx"> {
</span><ins>+#if PLATFORM(IOS)
+    return frameAtIndex(index, 1.0f);
+#else
+    if (!ensureFrameIsCached(index))
+        return nullptr;
+    return m_frames[index].m_frame;
+#endif
+}
+
+#if PLATFORM(IOS)
+PassNativeImagePtr BitmapImage::frameAtIndex(size_t index, float scaleHint)
+{
</ins><span class="cx">     if (index &gt;= frameCount())
</span><span class="cx">         return nullptr;
</span><span class="cx"> 
</span><del>-    SubsamplingLevel subsamplingLevel = std::min(m_source.subsamplingLevelForScale(presentationScaleHint), m_minimumSubsamplingLevel);
-
-    // We may have cached a frame with a higher subsampling level, in which case we need to
-    // re-decode with a lower level.
-    if (index &lt; m_frames.size() &amp;&amp; m_frames[index].m_frame &amp;&amp; subsamplingLevel &lt; m_frames[index].m_subsamplingLevel) {
</del><ins>+    if (index &gt;= m_frames.size() || !m_frames[index].m_frame)
+        cacheFrame(index, scaleHint);
+    else if (std::min(1.0f, scaleHint) &gt; m_frames[index].m_subsamplingScale) {
</ins><span class="cx">         // If the image is already cached, but at too small a size, re-decode a larger version.
</span><span class="cx">         int sizeChange = -m_frames[index].m_frameBytes;
</span><ins>+        ASSERT(static_cast&lt;int&gt;(m_decodedSize) + sizeChange &gt;= 0);
</ins><span class="cx">         m_frames[index].clear(true);
</span><span class="cx">         invalidatePlatformData();
</span><span class="cx">         m_decodedSize += sizeChange;
</span><del>-        WTFLogAlways(&quot;BitmapImage %p frameAtIndex recaching, m_decodedSize now %u (size change %d)&quot;, this, m_decodedSize, sizeChange);
</del><span class="cx">         if (imageObserver())
</span><span class="cx">             imageObserver()-&gt;decodedSizeChanged(this, sizeChange);
</span><ins>+
+        cacheFrame(index, scaleHint);
</ins><span class="cx">     }
</span><del>-
-    // If we haven't fetched a frame yet, do so.
-    if (index &gt;= m_frames.size() || !m_frames[index].m_frame)
-        cacheFrame(index, subsamplingLevel, CacheMetadataAndFrame);
-
</del><span class="cx">     return m_frames[index].m_frame;
</span><span class="cx"> }
</span><ins>+#endif
</ins><span class="cx"> 
</span><span class="cx"> bool BitmapImage::frameIsCompleteAtIndex(size_t index)
</span><span class="cx"> {
</span><del>-    if (!ensureFrameIsCached(index, CacheMetadataOnly))
</del><ins>+#if PLATFORM(IOS)
+    // FIXME: cacheFrameInfo does not set m_isComplete. Should it?
+    if (!ensureFrameInfoIsCached(index))
</ins><span class="cx">         return false;
</span><del>-
</del><ins>+#else
+    if (!ensureFrameIsCached(index))
+        return false;
+#endif
</ins><span class="cx">     return m_frames[index].m_isComplete;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> float BitmapImage::frameDurationAtIndex(size_t index)
</span><span class="cx"> {
</span><del>-    if (!ensureFrameIsCached(index, CacheMetadataOnly))
</del><ins>+#if PLATFORM(IOS)
+    if (!ensureFrameInfoIsCached(index))
</ins><span class="cx">         return 0;
</span><del>-
</del><ins>+#else
+    if (!ensureFrameIsCached(index))
+        return 0;
+#endif
</ins><span class="cx">     return m_frames[index].m_duration;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -427,9 +479,13 @@
</span><span class="cx"> 
</span><span class="cx"> bool BitmapImage::frameHasAlphaAtIndex(size_t index)
</span><span class="cx"> {
</span><del>-    if (!ensureFrameIsCached(index, CacheMetadataOnly))
</del><ins>+#if PLATFORM(IOS)
+    if (!ensureFrameInfoIsCached(index))
+        return true; // FIXME: Why would an invalid index return true here?
+#else
+    if (m_frames.size() &lt;= index)
</ins><span class="cx">         return true;
</span><del>-
</del><ins>+#endif
</ins><span class="cx">     if (m_frames[index].m_haveMetadata)
</span><span class="cx">         return m_frames[index].m_hasAlpha;
</span><span class="cx"> 
</span><span class="lines">@@ -443,8 +499,14 @@
</span><span class="cx"> 
</span><span class="cx"> ImageOrientation BitmapImage::frameOrientationAtIndex(size_t index)
</span><span class="cx"> {
</span><del>-    if (!ensureFrameIsCached(index, CacheMetadataOnly))
</del><ins>+#if PLATFORM(IOS)
+    // FIXME: cacheFrameInfo does not set m_orientation. Should it?
+    if (!ensureFrameInfoIsCached(index))
</ins><span class="cx">         return DefaultImageOrientation;
</span><ins>+#else
+    if (!ensureFrameIsCached(index))
+        return DefaultImageOrientation;
+#endif
</ins><span class="cx"> 
</span><span class="cx">     if (m_frames[index].m_haveMetadata)
</span><span class="cx">         return m_frames[index].m_orientation;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsBitmapImageh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/BitmapImage.h (171963 => 171964)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/BitmapImage.h        2014-08-02 04:00:18 UTC (rev 171963)
+++ trunk/Source/WebCore/platform/graphics/BitmapImage.h        2014-08-02 05:10:46 UTC (rev 171964)
</span><span class="lines">@@ -70,7 +70,10 @@
</span><span class="cx">     FrameData()
</span><span class="cx">         : m_frame(0)
</span><span class="cx">         , m_orientation(DefaultImageOrientation)
</span><del>-        , m_subsamplingLevel(0)
</del><ins>+#if PLATFORM(IOS)
+        , m_subsamplingScale(0)
+        , m_haveInfo(false)
+#endif
</ins><span class="cx">         , m_duration(0)
</span><span class="cx">         , m_haveMetadata(false)
</span><span class="cx">         , m_isComplete(false)
</span><span class="lines">@@ -90,7 +93,10 @@
</span><span class="cx"> 
</span><span class="cx">     NativeImagePtr m_frame;
</span><span class="cx">     ImageOrientation m_orientation;
</span><del>-    SubsamplingLevel m_subsamplingLevel;
</del><ins>+#if PLATFORM(IOS)
+    float m_subsamplingScale;
+    bool m_haveInfo;
+#endif
</ins><span class="cx">     float m_duration;
</span><span class="cx">     bool m_haveMetadata : 1;
</span><span class="cx">     bool m_isComplete : 1;
</span><span class="lines">@@ -102,6 +108,9 @@
</span><span class="cx"> // BitmapImage Class
</span><span class="cx"> // =================================================
</span><span class="cx"> 
</span><ins>+// FIXME: We should better integrate the iOS and non-iOS code in this class. Unlike other ports, the
+// iOS port caches the metadata for a frame without decoding the image.
+
</ins><span class="cx"> class BitmapImage final : public Image {
</span><span class="cx">     friend class GeneratedImage;
</span><span class="cx">     friend class CrossfadeGeneratedImage;
</span><span class="lines">@@ -128,7 +137,11 @@
</span><span class="cx">     // FloatSize due to override.
</span><span class="cx">     virtual FloatSize size() const override;
</span><span class="cx">     IntSize sizeRespectingOrientation(ImageOrientationDescription = ImageOrientationDescription()) const;
</span><del>-
</del><ins>+#if PLATFORM(IOS)
+    virtual FloatSize originalSize() const override;
+    IntSize originalSizeRespectingOrientation() const;
+#endif
+    IntSize currentFrameSize() const;
</ins><span class="cx">     virtual bool getHotSpot(IntPoint&amp;) const override;
</span><span class="cx"> 
</span><span class="cx">     unsigned decodedSize() const { return m_decodedSize; }
</span><span class="lines">@@ -181,12 +194,8 @@
</span><span class="cx">     
</span><span class="cx">     bool canAnimate();
</span><span class="cx"> 
</span><del>-    bool allowSubsampling() const { return m_allowSubsampling; }
-    void setAllowSubsampling(bool allowSubsampling) { m_allowSubsampling = allowSubsampling; }
-    
</del><span class="cx"> private:
</span><span class="cx">     void updateSize(ImageOrientationDescription = ImageOrientationDescription()) const;
</span><del>-    void determineMinimumSubsamplingLevel() const;
</del><span class="cx"> 
</span><span class="cx"> protected:
</span><span class="cx">     enum RepetitionCountStatus {
</span><span class="lines">@@ -209,24 +218,30 @@
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     size_t currentFrame() const { return m_currentFrame; }
</span><ins>+#if PLATFORM(IOS)
+    PassNativeImagePtr frameAtIndex(size_t, float scaleHint);
+    PassNativeImagePtr copyUnscaledFrameAtIndex(size_t);
+#endif
</ins><span class="cx">     size_t frameCount();
</span><del>-
-    PassNativeImagePtr frameAtIndex(size_t, float presentationScaleHint = 1);
-    PassNativeImagePtr copyUnscaledFrameAtIndex(size_t);
-
-    bool haveFrameAtIndex(size_t);
-
</del><ins>+    PassNativeImagePtr frameAtIndex(size_t);
</ins><span class="cx">     bool frameIsCompleteAtIndex(size_t);
</span><span class="cx">     float frameDurationAtIndex(size_t);
</span><span class="cx">     bool frameHasAlphaAtIndex(size_t);
</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>+#if PLATFORM(IOS)
+    void cacheFrame(size_t index, float scaleHint);
</ins><span class="cx"> 
</span><ins>+    // Cache frame metadata without decoding image.
+    void cacheFrameInfo(size_t index);
</ins><span class="cx">     // Called before accessing m_frames[index] for info without decoding. Returns false on index out of bounds.
</span><del>-    bool ensureFrameIsCached(size_t index, ImageFrameCaching = CacheMetadataAndFrame);
</del><ins>+    bool ensureFrameInfoIsCached(size_t index);
+#else
+    void cacheFrame(size_t index);
+    // Called before accessing m_frames[index]. Returns false on index out of bounds.
+    bool ensureFrameIsCached(size_t index);
+#endif
</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">@@ -286,12 +301,13 @@
</span><span class="cx">     ImageSource m_source;
</span><span class="cx">     mutable IntSize m_size; // The size to use for the overall image (will just be the size of the first image).
</span><span class="cx">     mutable IntSize m_sizeRespectingOrientation;
</span><del>-
-    mutable SubsamplingLevel m_minimumSubsamplingLevel;
-
</del><span class="cx">     mutable unsigned m_imageOrientation : 4; // ImageOrientationEnum
</span><span class="cx">     mutable unsigned m_shouldRespectImageOrientation : 1; // RespectImageOrientationEnum
</span><span class="cx"> 
</span><ins>+#if PLATFORM(IOS)
+    mutable IntSize m_originalSize; // The size of the unsubsampled image.
+    mutable IntSize m_originalSizeRespectingOrientation;
+#endif
</ins><span class="cx">     size_t m_currentFrame; // The index of the current frame of animation.
</span><span class="cx">     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.
</span><span class="cx"> 
</span><span class="lines">@@ -320,7 +336,6 @@
</span><span class="cx">     uint16_t m_progressiveLoadChunkCount;
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-    bool m_allowSubsampling : 1; // Whether we should attempt subsampling if this image is very large.
</del><span class="cx">     bool m_isSolidColor : 1; // Whether or not we are a 1x1 solid image.
</span><span class="cx">     bool m_checkedForSolidColor : 1; // Whether we've checked the frame for solid color.
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsGraphicsContexth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/GraphicsContext.h (171963 => 171964)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/GraphicsContext.h        2014-08-02 04:00:18 UTC (rev 171963)
+++ trunk/Source/WebCore/platform/graphics/GraphicsContext.h        2014-08-02 05:10:46 UTC (rev 171964)
</span><span class="lines">@@ -283,7 +283,7 @@
</span><span class="cx">         void applyFillPattern();
</span><span class="cx">         void drawPath(const Path&amp;);
</span><span class="cx"> 
</span><del>-        void drawNativeImage(PassNativeImagePtr, const FloatSize&amp; selfSize, ColorSpace styleColorSpace, const FloatRect&amp; destRect, const FloatRect&amp; srcRect, CompositeOperator = CompositeSourceOver, BlendMode = BlendModeNormal, ImageOrientation = DefaultImageOrientation);
</del><ins>+        void drawNativeImage(PassNativeImagePtr, const FloatSize&amp; selfSize, ColorSpace styleColorSpace, const FloatRect&amp; destRect, const FloatRect&amp; srcRect, float scale = 1, CompositeOperator = CompositeSourceOver, BlendMode = BlendModeNormal, ImageOrientation = DefaultImageOrientation);
</ins><span class="cx"> 
</span><span class="cx">         // Allow font smoothing (LCD antialiasing). Not part of the graphics state.
</span><span class="cx">         void setAllowsFontSmoothing(bool);
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsImageSourcecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/ImageSource.cpp (171963 => 171964)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/ImageSource.cpp        2014-08-02 04:00:18 UTC (rev 171963)
+++ trunk/Source/WebCore/platform/graphics/ImageSource.cpp        2014-08-02 05:10:46 UTC (rev 171964)
</span><span class="lines">@@ -29,8 +29,6 @@
</span><span class="cx"> #include &quot;config.h&quot;
</span><span class="cx"> #include &quot;ImageSource.h&quot;
</span><span class="cx"> 
</span><del>-#if !USE(CG)
-
</del><span class="cx"> #include &quot;ImageDecoder.h&quot;
</span><span class="cx"> 
</span><span class="cx"> #include &quot;ImageOrientation.h&quot;
</span><span class="lines">@@ -96,16 +94,6 @@
</span><span class="cx">     return m_decoder ? m_decoder-&gt;filenameExtension() : String();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-SubsamplingLevel ImageSource::subsamplingLevelForScale(float) const
-{
-    return 0;
-}
-
-bool ImageSource::allowSubsamplingOfFrameAtIndex(size_t) const
-{
-    return true;
-}
-
</del><span class="cx"> bool ImageSource::isSizeAvailable()
</span><span class="cx"> {
</span><span class="cx">     return m_decoder &amp;&amp; m_decoder-&gt;isSizeAvailable();
</span><span class="lines">@@ -113,10 +101,10 @@
</span><span class="cx"> 
</span><span class="cx"> IntSize ImageSource::size(ImageOrientationDescription description) const
</span><span class="cx"> {
</span><del>-    return frameSizeAtIndex(0, 0, description);
</del><ins>+    return frameSizeAtIndex(0, description);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-IntSize ImageSource::frameSizeAtIndex(size_t index, SubsamplingLevel, ImageOrientationDescription description) const
</del><ins>+IntSize ImageSource::frameSizeAtIndex(size_t index, ImageOrientationDescription description) const
</ins><span class="cx"> {
</span><span class="cx">     if (!m_decoder)
</span><span class="cx">         return IntSize();
</span><span class="lines">@@ -148,8 +136,10 @@
</span><span class="cx">     return m_decoder ? m_decoder-&gt;frameCount() : 0;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-PassNativeImagePtr ImageSource::createFrameAtIndex(size_t index, SubsamplingLevel)
</del><ins>+PassNativeImagePtr ImageSource::createFrameAtIndex(size_t index, float* scale)
</ins><span class="cx"> {
</span><ins>+    UNUSED_PARAM(scale);
+
</ins><span class="cx">     if (!m_decoder)
</span><span class="cx">         return 0;
</span><span class="cx"> 
</span><span class="lines">@@ -207,7 +197,7 @@
</span><span class="cx">     return buffer &amp;&amp; buffer-&gt;status() == ImageFrame::FrameComplete;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-unsigned ImageSource::frameBytesAtIndex(size_t index, SubsamplingLevel) const
</del><ins>+unsigned ImageSource::frameBytesAtIndex(size_t index) const
</ins><span class="cx"> {
</span><span class="cx">     if (!m_decoder)
</span><span class="cx">         return 0;
</span><span class="lines">@@ -215,5 +205,3 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> }
</span><del>-
-#endif // USE(CG)
</del></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsImageSourceh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/ImageSource.h (171963 => 171964)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/ImageSource.h        2014-08-02 04:00:18 UTC (rev 171963)
+++ trunk/Source/WebCore/platform/graphics/ImageSource.h        2014-08-02 05:10:46 UTC (rev 171964)
</span><span class="lines">@@ -77,9 +77,6 @@
</span><span class="cx"> const int cAnimationLoopInfinite = -1;
</span><span class="cx"> const int cAnimationNone = -2;
</span><span class="cx"> 
</span><del>-// SubsamplingLevel. 0 is no subsampling, 1 is half dimensions on each axis etc.
-typedef short SubsamplingLevel;
-
</del><span class="cx"> class ImageSource {
</span><span class="cx">     WTF_MAKE_NONCOPYABLE(ImageSource);
</span><span class="cx"> public:
</span><span class="lines">@@ -134,15 +131,15 @@
</span><span class="cx">     void setData(SharedBuffer* data, bool allDataReceived);
</span><span class="cx">     String filenameExtension() const;
</span><span class="cx"> 
</span><del>-    SubsamplingLevel subsamplingLevelForScale(float) const;
-    bool allowSubsamplingOfFrameAtIndex(size_t) const;
-
</del><span class="cx">     bool isSizeAvailable();
</span><del>-    // Always original size, without subsampling.
</del><span class="cx">     IntSize size(ImageOrientationDescription = ImageOrientationDescription()) const;
</span><del>-    // Size of optionally subsampled frame.
-    IntSize frameSizeAtIndex(size_t, SubsamplingLevel = 0, ImageOrientationDescription = ImageOrientationDescription()) const;
</del><ins>+    IntSize frameSizeAtIndex(size_t, ImageOrientationDescription = ImageOrientationDescription()) const;
</ins><span class="cx"> 
</span><ins>+#if PLATFORM(IOS)
+    IntSize originalSize(RespectImageOrientationEnum = DoNotRespectImageOrientation) const;
+    bool isSubsampled() const { return m_baseSubsampling; }
+#endif
+
</ins><span class="cx">     bool getHotSpot(IntPoint&amp;) const;
</span><span class="cx"> 
</span><span class="cx">     size_t bytesDecodedToDetermineProperties() const;
</span><span class="lines">@@ -153,7 +150,7 @@
</span><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>-    PassNativeImagePtr createFrameAtIndex(size_t, SubsamplingLevel = 0);
</del><ins>+    PassNativeImagePtr createFrameAtIndex(size_t, float* scale = 0);
</ins><span class="cx"> 
</span><span class="cx">     float frameDurationAtIndex(size_t);
</span><span class="cx">     bool frameHasAlphaAtIndex(size_t); // Whether or not the frame actually used any alpha.
</span><span class="lines">@@ -162,7 +159,7 @@
</span><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 = 0) const;
</del><ins>+    unsigned frameBytesAtIndex(size_t) const;
</ins><span class="cx"> 
</span><span class="cx"> #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
</span><span class="cx">     static unsigned maxPixelsPerDecodedImage() { return s_maxPixelsPerDecodedImage; }
</span><span class="lines">@@ -179,6 +176,11 @@
</span><span class="cx"> #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
</span><span class="cx">     static unsigned s_maxPixelsPerDecodedImage;
</span><span class="cx"> #endif
</span><ins>+#if PLATFORM(IOS)
+    mutable int m_baseSubsampling;
+    mutable bool m_isProgressive;
+    CFDictionaryRef imageSourceOptions(ShouldSkipMetadata, int subsampling = 0) const;
+#endif
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicscairoBitmapImageCairocpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/cairo/BitmapImageCairo.cpp (171963 => 171964)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/cairo/BitmapImageCairo.cpp        2014-08-02 04:00:18 UTC (rev 171963)
+++ trunk/Source/WebCore/platform/graphics/cairo/BitmapImageCairo.cpp        2014-08-02 05:10:46 UTC (rev 171964)
</span><span class="lines">@@ -119,11 +119,6 @@
</span><span class="cx">         imageObserver()-&gt;didDraw(this);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void BitmapImage::determineMinimumSubsamplingLevel() const
-{
-    m_minimumSubsamplingLevel = 0;
-}
-
</del><span class="cx"> void BitmapImage::checkForSolidColor()
</span><span class="cx"> {
</span><span class="cx">     m_isSolidColor = false;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicscgBitmapImageCGcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/cg/BitmapImageCG.cpp (171963 => 171964)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/cg/BitmapImageCG.cpp        2014-08-02 04:00:18 UTC (rev 171963)
+++ trunk/Source/WebCore/platform/graphics/cg/BitmapImageCG.cpp        2014-08-02 05:10:46 UTC (rev 171964)
</span><span class="lines">@@ -29,7 +29,6 @@
</span><span class="cx"> #if USE(CG)
</span><span class="cx"> 
</span><span class="cx"> #include &quot;FloatConversion.h&quot;
</span><del>-#include &quot;GeometryUtilities.h&quot;
</del><span class="cx"> #include &quot;GraphicsContextCG.h&quot;
</span><span class="cx"> #include &quot;ImageObserver.h&quot;
</span><span class="cx"> #include &quot;SubimageCacheWithTimer.h&quot;
</span><span class="lines">@@ -59,8 +58,13 @@
</span><span class="cx">         m_haveMetadata = false;
</span><span class="cx"> 
</span><span class="cx">     m_orientation = DefaultImageOrientation;
</span><del>-    m_subsamplingLevel = 0;
</del><span class="cx"> 
</span><ins>+#if PLATFORM(IOS)
+    m_frameBytes = 0;
+    m_subsamplingScale = 1;
+    m_haveInfo = false;
+#endif
+
</ins><span class="cx">     if (m_frame) {
</span><span class="cx"> #if CACHE_SUBIMAGES
</span><span class="cx">         subimageCache().clearImage(m_frame);
</span><span class="lines">@@ -74,10 +78,8 @@
</span><span class="cx"> 
</span><span class="cx"> BitmapImage::BitmapImage(CGImageRef cgImage, ImageObserver* observer)
</span><span class="cx">     : Image(observer)
</span><del>-    , m_minimumSubsamplingLevel(0)
-    , m_imageOrientation(OriginTopLeft)
-    , m_shouldRespectImageOrientation(false)
</del><span class="cx">     , m_currentFrame(0)
</span><ins>+    , m_frames(0)
</ins><span class="cx">     , m_repetitionCount(cAnimationNone)
</span><span class="cx">     , m_repetitionCountStatus(Unknown)
</span><span class="cx">     , m_repetitionsComplete(0)
</span><span class="lines">@@ -101,62 +103,50 @@
</span><span class="cx">     // Set m_sizeRespectingOrientation to be the same as m_size so it's not 0x0.
</span><span class="cx">     m_sizeRespectingOrientation = m_size;
</span><span class="cx"> 
</span><ins>+#if PLATFORM(IOS)
+    m_originalSize = m_size;
+    m_originalSizeRespectingOrientation = m_size;
+#endif
+
</ins><span class="cx">     m_frames.grow(1);
</span><span class="cx">     m_frames[0].m_frame = CGImageRetain(cgImage);
</span><span class="cx">     m_frames[0].m_hasAlpha = true;
</span><span class="cx">     m_frames[0].m_haveMetadata = true;
</span><span class="cx"> 
</span><ins>+#if PLATFORM(IOS)
+    m_frames[0].m_subsamplingScale = 1;
+#endif
+
</ins><span class="cx">     checkForSolidColor();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void BitmapImage::determineMinimumSubsamplingLevel() const
-{
-    if (!m_allowSubsampling)
-        return;
</del><ins>+// Drawing Routines
</ins><span class="cx"> 
</span><del>-    if (!m_source.allowSubsamplingOfFrameAtIndex(0))
-        return;
-
-    // Values chosen to be appropriate for iOS.
-    const int cMaximumImageAreaBeforeSubsampling = 5 * 1024 * 1024;
-    const SubsamplingLevel maxSubsamplingLevel = 3;
-
-    SubsamplingLevel currentLevel = 0;
-    for ( ; currentLevel &lt;= maxSubsamplingLevel; ++currentLevel) {
-        IntSize frameSize = m_source.frameSizeAtIndex(0, currentLevel);
-        if (frameSize.area() &lt; cMaximumImageAreaBeforeSubsampling)
-            break;
-    }
-
-    m_minimumSubsamplingLevel = currentLevel;
-}
-
</del><span class="cx"> void BitmapImage::checkForSolidColor()
</span><span class="cx"> {
</span><span class="cx">     m_checkedForSolidColor = true;
</span><del>-    m_isSolidColor = false;
-
-    if (frameCount() &gt; 1)
</del><ins>+    if (frameCount() &gt; 1) {
+        m_isSolidColor = false;
</ins><span class="cx">         return;
</span><del>-
-    if (!haveFrameAtIndex(0)) {
-        IntSize size = m_source.frameSizeAtIndex(0, 0);
-        if (size.width() != 1 || size.height() != 1)
-            return;
-
-        if (!ensureFrameIsCached(0))
-            return;
</del><span class="cx">     }
</span><span class="cx"> 
</span><ins>+#if !PLATFORM(IOS)
+    CGImageRef image = frameAtIndex(0);
+#else
+    // Note, checkForSolidColor() may be called from frameAtIndex(). On iOS frameAtIndex() gets passed a scaleHint
+    // argument which it uses to tell CG to create a scaled down image. Since we don't know the scaleHint here, if
+    // we call frameAtIndex() again, we would pass it the default scale of 1 and would end up recreating the image.
+    // So we do a quick check and call frameAtIndex(0) only if we haven't yet created an image.
</ins><span class="cx">     CGImageRef image = nullptr;
</span><span class="cx">     if (m_frames.size())
</span><span class="cx">         image = m_frames[0].m_frame;
</span><span class="cx"> 
</span><span class="cx">     if (!image)
</span><del>-        return;
</del><ins>+        image = frameAtIndex(0);
+#endif
</ins><span class="cx"> 
</span><span class="cx">     // Currently we only check for solid color in the important special case of a 1x1 image.
</span><del>-    if (CGImageGetWidth(image) == 1 &amp;&amp; CGImageGetHeight(image) == 1) {
</del><ins>+    if (image &amp;&amp; CGImageGetWidth(image) == 1 &amp;&amp; CGImageGetHeight(image) == 1) {
</ins><span class="cx">         unsigned char pixel[4]; // RGBA
</span><span class="cx">         RetainPtr&lt;CGContextRef&gt; bitmapContext = adoptCF(CGBitmapContextCreate(pixel, 1, 1, 8, sizeof(pixel), deviceRGBColorSpaceRef(),
</span><span class="cx">             kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big));
</span><span class="lines">@@ -208,23 +198,30 @@
</span><span class="cx"> 
</span><span class="cx"> void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect&amp; destRect, const FloatRect&amp; srcRect, ColorSpace styleColorSpace, CompositeOperator compositeOp, BlendMode blendMode, ImageOrientationDescription description)
</span><span class="cx"> {
</span><ins>+    CGImageRef image;
+    FloatRect srcRectForCurrentFrame = srcRect;
+
</ins><span class="cx"> #if PLATFORM(IOS)
</span><ins>+    if (m_originalSize != m_size &amp;&amp; !m_originalSize.isEmpty())
+        srcRectForCurrentFrame.scale(m_size.width() / static_cast&lt;float&gt;(m_originalSize.width()), m_size.height() / static_cast&lt;float&gt;(m_originalSize.height()));
+
</ins><span class="cx">     startAnimation(DoNotCatchUp);
</span><del>-#else
-    startAnimation();
-#endif
</del><span class="cx"> 
</span><del>-    RetainPtr&lt;CGImageRef&gt; image;
</del><ins>+    CGRect transformedDestinationRect = CGRectApplyAffineTransform(destRect, CGContextGetCTM(ctxt-&gt;platformContext()));
+    RetainPtr&lt;CGImageRef&gt; imagePossiblyCopied;
</ins><span class="cx">     // Never use subsampled images for drawing into PDF contexts.
</span><del>-    if (wkCGContextIsPDFContext(ctxt-&gt;platformContext()))
-        image = adoptCF(copyUnscaledFrameAtIndex(m_currentFrame));
-    else {
-        CGRect transformedDestinationRect = CGRectApplyAffineTransform(destRect, CGContextGetCTM(ctxt-&gt;platformContext()));
-        float subsamplingScale = std::min&lt;float&gt;(1, std::max(transformedDestinationRect.size.width / srcRect.width(), transformedDestinationRect.size.height / srcRect.height()));
</del><ins>+    if (CGContextGetType(ctxt-&gt;platformContext()) == kCGContextTypePDF)
+        imagePossiblyCopied = adoptCF(copyUnscaledFrameAtIndex(m_currentFrame));
+    else
+        imagePossiblyCopied = frameAtIndex(m_currentFrame, std::min&lt;float&gt;(1.0f, std::max(transformedDestinationRect.size.width  / srcRectForCurrentFrame.width(), transformedDestinationRect.size.height / srcRectForCurrentFrame.height())));
</ins><span class="cx"> 
</span><del>-        image = frameAtIndex(m_currentFrame, subsamplingScale);
-    }
</del><ins>+    image = imagePossiblyCopied.get();
+#else
+    startAnimation();
</ins><span class="cx"> 
</span><ins>+    image = frameAtIndex(m_currentFrame);
+#endif
+
</ins><span class="cx">     if (!image) // If it's too early we won't have an image yet.
</span><span class="cx">         return;
</span><span class="cx">     
</span><span class="lines">@@ -233,27 +230,23 @@
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    // Subsampling may have given us an image that is smaller than size().
-    IntSize imageSize(CGImageGetWidth(image.get()), CGImageGetHeight(image.get()));
-    
-    // srcRect is in the coordinates of the unsubsampled image, so we have to map it to the subsampled image.
-    FloatRect scaledSrcRect = srcRect;
-    if (imageSize != m_size) {
-        FloatRect originalImageBounds(FloatPoint(), m_size);
-        FloatRect subsampledImageBounds(FloatPoint(), imageSize);
-        scaledSrcRect = mapRect(srcRect, originalImageBounds, subsampledImageBounds);
-    }
-    
</del><ins>+    float scale = 1;
+#if PLATFORM(IOS)
+    scale = m_frames[m_currentFrame].m_subsamplingScale;
+#endif
+    FloatSize selfSize = currentFrameSize();
</ins><span class="cx">     ImageOrientation orientation;
</span><ins>+
</ins><span class="cx">     if (description.respectImageOrientation() == RespectImageOrientation)
</span><span class="cx">         orientation = frameOrientationAtIndex(m_currentFrame);
</span><span class="cx"> 
</span><del>-    ctxt-&gt;drawNativeImage(image.get(), imageSize, styleColorSpace, destRect, scaledSrcRect, compositeOp, blendMode, orientation);
</del><ins>+    ctxt-&gt;drawNativeImage(image, selfSize, styleColorSpace, destRect, srcRectForCurrentFrame, scale, compositeOp, blendMode, orientation);
</ins><span class="cx"> 
</span><span class="cx">     if (imageObserver())
</span><span class="cx">         imageObserver()-&gt;didDraw(this);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+#if PLATFORM(IOS)
</ins><span class="cx"> PassNativeImagePtr BitmapImage::copyUnscaledFrameAtIndex(size_t index)
</span><span class="cx"> {
</span><span class="cx">     if (index &gt;= frameCount())
</span><span class="lines">@@ -262,11 +255,12 @@
</span><span class="cx">     if (index &gt;= m_frames.size() || !m_frames[index].m_frame)
</span><span class="cx">         cacheFrame(index, 1);
</span><span class="cx"> 
</span><del>-    if (!m_frames[index].m_subsamplingLevel)
</del><ins>+    if (m_frames[index].m_subsamplingScale == 1 &amp;&amp; !m_source.isSubsampled())
</ins><span class="cx">         return CGImageRetain(m_frames[index].m_frame);
</span><span class="cx"> 
</span><span class="cx">     return m_source.createFrameAtIndex(index);
</span><span class="cx"> }
</span><ins>+#endif
</ins><span class="cx"> 
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicscgGraphicsContext3DCGcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp (171963 => 171964)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp        2014-08-02 04:00:18 UTC (rev 171963)
+++ trunk/Source/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp        2014-08-02 05:10:46 UTC (rev 171964)
</span><span class="lines">@@ -332,8 +332,17 @@
</span><span class="cx">         decoder.setData(m_image-&gt;data(), true);
</span><span class="cx">         if (!decoder.frameCount())
</span><span class="cx">             return false;
</span><del>-
</del><ins>+#if PLATFORM(IOS)
+        float scaleHint = 1;
+        if (m_image-&gt;isBitmapImage()) {
+            FloatSize originalSize = toBitmapImage(m_image)-&gt;originalSize();
+            if (!originalSize.isEmpty())
+                scaleHint = std::min&lt;float&gt;(1, std::max(m_image-&gt;size().width() / originalSize.width(), m_image-&gt;size().width() / originalSize.height()));
+        }
+        m_decodedImage = adoptCF(decoder.createFrameAtIndex(0, &amp;scaleHint));
+#else
</ins><span class="cx">         m_decodedImage = adoptCF(decoder.createFrameAtIndex(0));
</span><ins>+#endif
</ins><span class="cx">         m_cgImage = m_decodedImage.get();
</span><span class="cx">     } else
</span><span class="cx">         m_cgImage = m_image-&gt;nativeImageForCurrentFrame();
</span><span class="lines">@@ -536,7 +545,7 @@
</span><span class="cx">     context-&gt;scale(FloatSize(1, -1));
</span><span class="cx">     context-&gt;translate(0, -imageHeight);
</span><span class="cx">     context-&gt;setImageInterpolationQuality(InterpolationNone);
</span><del>-    context-&gt;drawNativeImage(cgImage.get(), imageSize, ColorSpaceDeviceRGB, canvasRect, FloatRect(FloatPoint(), imageSize), CompositeCopy);
</del><ins>+    context-&gt;drawNativeImage(cgImage.get(), imageSize, ColorSpaceDeviceRGB, canvasRect, FloatRect(FloatPoint(), imageSize), 1, CompositeCopy);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicscgGraphicsContextCGcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp (171963 => 171964)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp        2014-08-02 04:00:18 UTC (rev 171963)
+++ trunk/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp        2014-08-02 05:10:46 UTC (rev 171964)
</span><span class="lines">@@ -169,11 +169,18 @@
</span><span class="cx">     m_data-&gt;m_userToDeviceTransformKnownToBeIdentity = false;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void GraphicsContext::drawNativeImage(PassNativeImagePtr imagePtr, const FloatSize&amp; imageSize, ColorSpace styleColorSpace, const FloatRect&amp; destRect, const FloatRect&amp; srcRect, CompositeOperator op, BlendMode blendMode, ImageOrientation orientation)
</del><ins>+void GraphicsContext::drawNativeImage(PassNativeImagePtr imagePtr, const FloatSize&amp; imageSize, ColorSpace styleColorSpace, const FloatRect&amp; destRect, const FloatRect&amp; srcRect, float scale, CompositeOperator op, BlendMode blendMode, ImageOrientation orientation)
</ins><span class="cx"> {
</span><span class="cx">     RetainPtr&lt;CGImageRef&gt; image(imagePtr);
</span><span class="cx"> 
</span><span class="cx">     float currHeight = orientation.usesWidthAsHeight() ? CGImageGetWidth(image.get()) : CGImageGetHeight(image.get());
</span><ins>+#if PLATFORM(IOS)
+    // Unapply the scaling since we are getting this from a scaled bitmap.
+    currHeight /= scale;
+#else
+    UNUSED_PARAM(scale);
+#endif
+
</ins><span class="cx">     if (currHeight &lt;= srcRect.y())
</span><span class="cx">         return;
</span><span class="cx"> 
</span><span class="lines">@@ -214,6 +221,9 @@
</span><span class="cx">             subimageRect.setHeight(ceilf(subimageRect.height() + topPadding));
</span><span class="cx">             adjustedDestRect.setHeight(subimageRect.height() / yScale);
</span><span class="cx"> 
</span><ins>+#if PLATFORM(IOS)
+            subimageRect.scale(scale, scale);
+#endif
</ins><span class="cx"> #if CACHE_SUBIMAGES
</span><span class="cx">             image = subimageCache().getSubimage(image.get(), subimageRect);
</span><span class="cx"> #else
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicscgImageBufferCGcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp (171963 => 171964)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp        2014-08-02 04:00:18 UTC (rev 171963)
+++ trunk/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp        2014-08-02 05:10:46 UTC (rev 171964)
</span><span class="lines">@@ -301,7 +301,7 @@
</span><span class="cx"> 
</span><span class="cx">     FloatRect adjustedSrcRect = srcRect;
</span><span class="cx">     adjustedSrcRect.scale(m_resolutionScale, m_resolutionScale);
</span><del>-    destContext-&gt;drawNativeImage(image.get(), m_data.m_backingStoreSize, colorSpace, destRect, adjustedSrcRect, op, blendMode);
</del><ins>+    destContext-&gt;drawNativeImage(image.get(), m_data.m_backingStoreSize, colorSpace, destRect, adjustedSrcRect, 1, op, blendMode);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void ImageBuffer::drawPattern(GraphicsContext* destContext, const FloatRect&amp; srcRect, const AffineTransform&amp; patternTransform, const FloatPoint&amp; phase, ColorSpace styleColorSpace, CompositeOperator op, const FloatRect&amp; destRect, BlendMode blendMode)
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicscgImageSourceCGcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/cg/ImageSourceCG.cpp (171963 => 171964)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/cg/ImageSourceCG.cpp        2014-08-02 04:00:18 UTC (rev 171963)
+++ trunk/Source/WebCore/platform/graphics/cg/ImageSourceCG.cpp        2014-08-02 05:10:46 UTC (rev 171964)
</span><span class="lines">@@ -38,17 +38,12 @@
</span><span class="cx"> #include &lt;ApplicationServices/ApplicationServices.h&gt;
</span><span class="cx"> #else
</span><span class="cx"> #include &lt;CoreGraphics/CGImagePrivate.h&gt;
</span><ins>+#include &lt;CoreGraphics/CoreGraphics.h&gt;
+#include &lt;ImageIO/CGImageSourcePrivate.h&gt;
</ins><span class="cx"> #include &lt;ImageIO/ImageIO.h&gt;
</span><del>-#include &lt;wtf/NeverDestroyed.h&gt;
</del><span class="cx"> #include &lt;wtf/RetainPtr.h&gt;
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-#if __has_include(&lt;ImageIO/CGImageSourcePrivate.h&gt;)
-#import &lt;ImageIO/CGImageSourcePrivate.h&gt;
-#else
-const CFStringRef kCGImageSourceSubsampleFactor = CFSTR(&quot;kCGImageSourceSubsampleFactor&quot;);
-#endif
-
</del><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="cx"> const CFStringRef WebCoreCGImagePropertyAPNGUnclampedDelayTime = CFSTR(&quot;UnclampedDelayTime&quot;);
</span><span class="lines">@@ -81,6 +76,10 @@
</span><span class="cx"> 
</span><span class="cx"> ImageSource::ImageSource(ImageSource::AlphaOption, ImageSource::GammaAndColorProfileOption)
</span><span class="cx">     : m_decoder(0)
</span><ins>+#if PLATFORM(IOS)
+    , m_baseSubsampling(0)
+    , m_isProgressive(false)
+#endif
</ins><span class="cx"> {
</span><span class="cx">     // FIXME: AlphaOption and GammaAndColorProfileOption are ignored.
</span><span class="cx"> }
</span><span class="lines">@@ -106,35 +105,39 @@
</span><span class="cx">         setData(data, allDataReceived);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static CFDictionaryRef createImageSourceOptions(ImageSource::ShouldSkipMetadata skipMetaData, SubsamplingLevel subsamplingLevel)
</del><ins>+#if !PLATFORM(IOS)
+static CFDictionaryRef imageSourceOptions(ImageSource::ShouldSkipMetadata skipMetaData)
</ins><span class="cx"> {
</span><del>-    const CFBooleanRef imageSourceSkipMetadata = (skipMetaData == ImageSource::SkipMetadata) ? kCFBooleanTrue : kCFBooleanFalse;
-    
-    if (!subsamplingLevel) {
</del><ins>+    static CFDictionaryRef options;
+
+    if (!options) {
</ins><span class="cx">         const unsigned numOptions = 3;
</span><ins>+        const CFBooleanRef imageSourceSkipMetadata = (skipMetaData == ImageSource::SkipMetadata) ? kCFBooleanTrue : kCFBooleanFalse;
</ins><span class="cx">         const void* keys[numOptions] = { kCGImageSourceShouldCache, kCGImageSourceShouldPreferRGB32, kCGImageSourceSkipMetadata };
</span><span class="cx">         const void* values[numOptions] = { kCFBooleanTrue, kCFBooleanTrue, imageSourceSkipMetadata };
</span><del>-        return CFDictionaryCreate(nullptr, keys, values, numOptions, &amp;kCFTypeDictionaryKeyCallBacks, &amp;kCFTypeDictionaryValueCallBacks);
</del><ins>+        options = CFDictionaryCreate(NULL, keys, values, numOptions, 
+            &amp;kCFTypeDictionaryKeyCallBacks, &amp;kCFTypeDictionaryValueCallBacks);
</ins><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]
-
-    RetainPtr&lt;CFNumberRef&gt; subsampleNumber = adoptCF(CFNumberCreate(nullptr,  kCFNumberIntType,  &amp;subsampleInt));
-    const CFIndex numOptions = 4;
-    const void* keys[numOptions] = { kCGImageSourceShouldCache, kCGImageSourceShouldPreferRGB32, kCGImageSourceSkipMetadata, kCGImageSourceSubsampleFactor };
-    const void* values[numOptions] = { kCFBooleanTrue, kCFBooleanTrue, imageSourceSkipMetadata, subsampleNumber.get() };
-    return CFDictionaryCreate(nullptr, keys, values, numOptions, &amp;kCFTypeDictionaryKeyCallBacks, &amp;kCFTypeDictionaryValueCallBacks);
</del><ins>+    return options;
</ins><span class="cx"> }
</span><del>-
-static CFDictionaryRef imageSourceOptions(ImageSource::ShouldSkipMetadata skipMetadata = ImageSource::SkipMetadata, SubsamplingLevel subsamplingLevel = 0)
</del><ins>+#else
+CFDictionaryRef ImageSource::imageSourceOptions(ShouldSkipMetadata skipMetaData, int requestedSubsampling) const
</ins><span class="cx"> {
</span><del>-    if (subsamplingLevel)
-        return createImageSourceOptions(skipMetadata, subsamplingLevel);
</del><ins>+    static CFDictionaryRef options[4] = {nullptr, nullptr, nullptr, nullptr};
+    int subsampling = std::min(3, m_isProgressive || requestedSubsampling &lt; 0 ? 0 : (requestedSubsampling + m_baseSubsampling));
</ins><span class="cx"> 
</span><del>-    static CFDictionaryRef options = createImageSourceOptions(skipMetadata, 0);
-    return options;
</del><ins>+    if (!options[subsampling]) {
+        int subsampleInt = 1 &lt;&lt; subsampling; // [0..3] =&gt; [1, 2, 4, 8]
+        RetainPtr&lt;CFNumberRef&gt; subsampleNumber = adoptCF(CFNumberCreate(nullptr,  kCFNumberIntType,  &amp;subsampleInt));
+        const CFIndex numOptions = 4;
+        const CFBooleanRef imageSourceSkipMetaData = (skipMetaData == ImageSource::SkipMetadata) ? kCFBooleanTrue : kCFBooleanFalse;
+        const void* keys[numOptions] = { kCGImageSourceShouldCache, kCGImageSourceShouldPreferRGB32, kCGImageSourceSubsampleFactor, kCGImageSourceSkipMetadata };
+        const void* values[numOptions] = { kCFBooleanTrue, kCFBooleanTrue, subsampleNumber.get(), imageSourceSkipMetaData };
+        options[subsampling] = CFDictionaryCreate(nullptr, keys, values, numOptions, &amp;kCFTypeDictionaryKeyCallBacks, &amp;kCFTypeDictionaryValueCallBacks);
+    }
+    return options[subsampling];
</ins><span class="cx"> }
</span><ins>+#endif
</ins><span class="cx"> 
</span><span class="cx"> bool ImageSource::initialized() const
</span><span class="cx"> {
</span><span class="lines">@@ -179,15 +182,6 @@
</span><span class="cx">     return WebCore::preferredExtensionForImageSourceType(imageSourceType);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-SubsamplingLevel ImageSource::subsamplingLevelForScale(float scale) const
-{
-    // There are four subsampling levels: 0 = 1x, 1 = 0.5x, 2 = 0.25x, 3 = 0.125x.
-    float clampedScale = std::max&lt;float&gt;(0.125, std::min&lt;float&gt;(1, scale));
-    int result = ceilf(log2f(1 / clampedScale));
-    ASSERT(result &gt;=0 &amp;&amp; result &lt;= 3);
-    return result;
-}
-
</del><span class="cx"> bool ImageSource::isSizeAvailable()
</span><span class="cx"> {
</span><span class="cx">     bool result = false;
</span><span class="lines">@@ -195,7 +189,7 @@
</span><span class="cx"> 
</span><span class="cx">     // Ragnaros yells: TOO SOON! You have awakened me TOO SOON, Executus!
</span><span class="cx">     if (imageSourceStatus &gt;= kCGImageStatusIncomplete) {
</span><del>-        RetainPtr&lt;CFDictionaryRef&gt; image0Properties = adoptCF(CGImageSourceCopyPropertiesAtIndex(m_decoder, 0, imageSourceOptions()));
</del><ins>+        RetainPtr&lt;CFDictionaryRef&gt; image0Properties = adoptCF(CGImageSourceCopyPropertiesAtIndex(m_decoder, 0, imageSourceOptions(SkipMetadata)));
</ins><span class="cx">         if (image0Properties) {
</span><span class="cx">             CFNumberRef widthNumber = (CFNumberRef)CFDictionaryGetValue(image0Properties.get(), kCGImagePropertyPixelWidth);
</span><span class="cx">             CFNumberRef heightNumber = (CFNumberRef)CFDictionaryGetValue(image0Properties.get(), kCGImagePropertyPixelHeight);
</span><span class="lines">@@ -218,67 +212,101 @@
</span><span class="cx">     return ImageOrientation::fromEXIFValue(exifValue);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool ImageSource::allowSubsamplingOfFrameAtIndex(size_t) const
</del><ins>+IntSize ImageSource::frameSizeAtIndex(size_t index, ImageOrientationDescription description) const
</ins><span class="cx"> {
</span><del>-    RetainPtr&lt;CFDictionaryRef&gt; properties = adoptCF(CGImageSourceCopyPropertiesAtIndex(m_decoder, 0, imageSourceOptions()));
</del><ins>+    RetainPtr&lt;CFDictionaryRef&gt; properties = adoptCF(CGImageSourceCopyPropertiesAtIndex(m_decoder, index, imageSourceOptions(SkipMetadata)));
+
</ins><span class="cx">     if (!properties)
</span><del>-        return false;
</del><ins>+        return IntSize();
</ins><span class="cx"> 
</span><del>-    CFDictionaryRef jfifProperties = static_cast&lt;CFDictionaryRef&gt;(CFDictionaryGetValue(properties.get(), kCGImagePropertyJFIFDictionary));
-    if (jfifProperties) {
-        CFBooleanRef isProgCFBool = static_cast&lt;CFBooleanRef&gt;(CFDictionaryGetValue(jfifProperties, kCGImagePropertyJFIFIsProgressive));
-        if (isProgCFBool) {
-            bool isProgressive = CFBooleanGetValue(isProgCFBool);
</del><ins>+    int w = 0, h = 0;
+    CFNumberRef num = (CFNumberRef)CFDictionaryGetValue(properties.get(), kCGImagePropertyPixelWidth);
+    if (num)
+        CFNumberGetValue(num, kCFNumberIntType, &amp;w);
+    num = (CFNumberRef)CFDictionaryGetValue(properties.get(), kCGImagePropertyPixelHeight);
+    if (num)
+        CFNumberGetValue(num, kCFNumberIntType, &amp;h);
+
+#if PLATFORM(IOS)
+    if (!m_isProgressive) {
+        CFDictionaryRef jfifProperties = static_cast&lt;CFDictionaryRef&gt;(CFDictionaryGetValue(properties.get(), kCGImagePropertyJFIFDictionary));
+        if (jfifProperties) {
+            CFBooleanRef isProgCFBool = static_cast&lt;CFBooleanRef&gt;(CFDictionaryGetValue(jfifProperties, kCGImagePropertyJFIFIsProgressive));
+            if (isProgCFBool)
+                m_isProgressive = CFBooleanGetValue(isProgCFBool);
</ins><span class="cx">             // Workaround for &lt;rdar://problem/5184655&gt; - Hang rendering very large progressive JPEG. Decoding progressive
</span><span class="cx">             // images hangs for a very long time right now. Until this is fixed, don't sub-sample progressive images. This
</span><span class="cx">             // will cause them to fail our large image check and they won't be decoded.
</span><span class="cx">             // FIXME: Remove once underlying issue is fixed (&lt;rdar://problem/5191418&gt;)
</span><del>-            return !isProgressive;
</del><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    return true;
</del><ins>+    if ((m_baseSubsampling == 0) &amp;&amp; !m_isProgressive) {
+        IntSize subsampledSize(w, h);
+        const int cMaximumImageSizeBeforeSubsampling = 5 * 1024 * 1024;
+        while ((m_baseSubsampling &lt; 3) &amp;&amp; subsampledSize.width() * subsampledSize.height() &gt; cMaximumImageSizeBeforeSubsampling) {
+            // We know the size, but the actual image is very large and should be sub-sampled.
+            // Increase the base subsampling and ask for the size again. If the image can be subsampled, the size will be
+            // greatly reduced. 4x sub-sampling will make us support up to 320MP (5MP * 4^3) images, which should be plenty.
+            // There's no callback from ImageIO when the size is available, so we do the check when we happen
+            // to check the size and its non - zero.
+            // Note: Some clients of this class don't call isSizeAvailable() so we can't rely on that.
+            ++m_baseSubsampling;
+            subsampledSize = frameSizeAtIndex(index, description.respectImageOrientation());
+        }
+        w = subsampledSize.width();
+        h = subsampledSize.height();
+    }
+#endif
+
+    if ((description.respectImageOrientation() == RespectImageOrientation) &amp;&amp; orientationFromProperties(properties.get()).usesWidthAsHeight())
+        return IntSize(h, w);
+
+    return IntSize(w, h);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-IntSize ImageSource::frameSizeAtIndex(size_t index, SubsamplingLevel subsamplingLevel, ImageOrientationDescription description) const
</del><ins>+ImageOrientation ImageSource::orientationAtIndex(size_t index) const
</ins><span class="cx"> {
</span><del>-    RetainPtr&lt;CFDictionaryRef&gt; properties = adoptCF(CGImageSourceCopyPropertiesAtIndex(m_decoder, index, imageSourceOptions(SkipMetadata, subsamplingLevel)));
</del><ins>+    RetainPtr&lt;CFDictionaryRef&gt; properties = adoptCF(CGImageSourceCopyPropertiesAtIndex(m_decoder, index, imageSourceOptions(SkipMetadata)));
+    if (!properties)
+        return DefaultImageOrientation;
</ins><span class="cx"> 
</span><ins>+    return orientationFromProperties(properties.get());
+}
+
+#if PLATFORM(IOS)
+IntSize ImageSource::originalSize(RespectImageOrientationEnum shouldRespectOrientation) const
+{
+    frameSizeAtIndex(0, shouldRespectOrientation);
+    RetainPtr&lt;CFDictionaryRef&gt; properties = adoptCF(CGImageSourceCopyPropertiesAtIndex(m_decoder, 0, imageSourceOptions(SkipMetadata, -1)));
+
</ins><span class="cx">     if (!properties)
</span><span class="cx">         return IntSize();
</span><span class="cx"> 
</span><span class="cx">     int width = 0;
</span><span class="cx">     int height = 0;
</span><del>-    CFNumberRef num = (CFNumberRef)CFDictionaryGetValue(properties.get(), kCGImagePropertyPixelWidth);
-    if (num)
-        CFNumberGetValue(num, kCFNumberIntType, &amp;width);
-    num = (CFNumberRef)CFDictionaryGetValue(properties.get(), kCGImagePropertyPixelHeight);
-    if (num)
-        CFNumberGetValue(num, kCFNumberIntType, &amp;height);
</del><ins>+    CFNumberRef number = (CFNumberRef)CFDictionaryGetValue(properties.get(), kCGImagePropertyPixelWidth);
+    if (number)
+        CFNumberGetValue(number, kCFNumberIntType, &amp;width);
+    number = static_cast&lt;CFNumberRef&gt;(CFDictionaryGetValue(properties.get(), kCGImagePropertyPixelHeight));
+    if (number)
+        CFNumberGetValue(number, kCFNumberIntType, &amp;height);
</ins><span class="cx"> 
</span><del>-    if ((description.respectImageOrientation() == RespectImageOrientation) &amp;&amp; orientationFromProperties(properties.get()).usesWidthAsHeight())
</del><ins>+    if ((shouldRespectOrientation == RespectImageOrientation) &amp;&amp; orientationFromProperties(properties.get()).usesWidthAsHeight())
</ins><span class="cx">         return IntSize(height, width);
</span><span class="cx"> 
</span><span class="cx">     return IntSize(width, height);
</span><span class="cx"> }
</span><ins>+#endif
</ins><span class="cx"> 
</span><del>-ImageOrientation ImageSource::orientationAtIndex(size_t index) const
-{
-    RetainPtr&lt;CFDictionaryRef&gt; properties = adoptCF(CGImageSourceCopyPropertiesAtIndex(m_decoder, index, imageSourceOptions()));
-    if (!properties)
-        return DefaultImageOrientation;
-
-    return orientationFromProperties(properties.get());
-}
-
</del><span class="cx"> IntSize ImageSource::size(ImageOrientationDescription description) const
</span><span class="cx"> {
</span><del>-    return frameSizeAtIndex(0, 0, description);
</del><ins>+    return frameSizeAtIndex(0, description);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool ImageSource::getHotSpot(IntPoint&amp; hotSpot) const
</span><span class="cx"> {
</span><del>-    RetainPtr&lt;CFDictionaryRef&gt; properties = adoptCF(CGImageSourceCopyPropertiesAtIndex(m_decoder, 0, imageSourceOptions()));
</del><ins>+    RetainPtr&lt;CFDictionaryRef&gt; properties = adoptCF(CGImageSourceCopyPropertiesAtIndex(m_decoder, 0, imageSourceOptions(SkipMetadata)));
</ins><span class="cx">     if (!properties)
</span><span class="cx">         return false;
</span><span class="cx"> 
</span><span class="lines">@@ -314,7 +342,7 @@
</span><span class="cx">     if (!initialized())
</span><span class="cx">         return cAnimationLoopOnce;
</span><span class="cx"> 
</span><del>-    RetainPtr&lt;CFDictionaryRef&gt; properties = adoptCF(CGImageSourceCopyProperties(m_decoder, imageSourceOptions()));
</del><ins>+    RetainPtr&lt;CFDictionaryRef&gt; properties = adoptCF(CGImageSourceCopyProperties(m_decoder, imageSourceOptions(SkipMetadata)));
</ins><span class="cx">     if (!properties)
</span><span class="cx">         return cAnimationLoopOnce;
</span><span class="cx"> 
</span><span class="lines">@@ -353,14 +381,22 @@
</span><span class="cx">     return m_decoder ? CGImageSourceGetCount(m_decoder) : 0;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-CGImageRef ImageSource::createFrameAtIndex(size_t index, SubsamplingLevel subsamplingLevel)
</del><ins>+CGImageRef ImageSource::createFrameAtIndex(size_t index, float* scale)
</ins><span class="cx"> {
</span><ins>+    UNUSED_PARAM(scale);
+
</ins><span class="cx">     if (!initialized())
</span><span class="cx">         return 0;
</span><span class="cx"> 
</span><del>-    RetainPtr&lt;CGImageRef&gt; image = adoptCF(CGImageSourceCreateImageAtIndex(m_decoder, index, imageSourceOptions(SkipMetadata, subsamplingLevel)));
</del><ins>+#if !PLATFORM(IOS)
+    UNUSED_PARAM(scale);
+    RetainPtr&lt;CGImageRef&gt; image = adoptCF(CGImageSourceCreateImageAtIndex(m_decoder, index, imageSourceOptions(SkipMetadata)));
+#else
+    // Subsampling can be 1, 2 or 3, which means quarter-, sixteenth- and sixty-fourth-size, respectively.
+    // A zero or negative value means no subsampling.
+    int subsampling = scale ? static_cast&lt;int&gt;(log2f(1.0f / std::max(0.1f, std::min(1.0f, *scale)))) : -1;
+    RetainPtr&lt;CGImageRef&gt; image = adoptCF(CGImageSourceCreateImageAtIndex(m_decoder, index, imageSourceOptions(SkipMetadata, subsampling)));
</ins><span class="cx"> 
</span><del>-#if PLATFORM(IOS)
</del><span class="cx">     // &lt;rdar://problem/7371198&gt; - CoreGraphics changed the default caching behaviour in iOS 4.0 to kCGImageCachingTransient
</span><span class="cx">     // which caused a performance regression for us since the images had to be resampled/recreated every time we called
</span><span class="cx">     // CGContextDrawImage. We now tell CG to cache the drawn images. See also &lt;rdar://problem/14366755&gt; -
</span><span class="lines">@@ -373,8 +409,15 @@
</span><span class="cx"> #if COMPILER(CLANG)
</span><span class="cx"> #pragma clang diagnostic pop
</span><span class="cx"> #endif
</span><ins>+    if (scale) {
+        if (subsampling &gt; 0)
+            *scale = static_cast&lt;float&gt;(CGImageGetWidth(image.get())) / size(DoNotRespectImageOrientation).width();
+        else {
+            ASSERT(static_cast&lt;int&gt;(CGImageGetWidth(image.get())) == size(DoNotRespectImageOrientation).width());
+            *scale = 1;
+        }
+    }
</ins><span class="cx"> #endif // !PLATFORM(IOS)
</span><del>-
</del><span class="cx">     CFStringRef imageUTI = CGImageSourceGetType(m_decoder);
</span><span class="cx">     static const CFStringRef xbmUTI = CFSTR(&quot;public.xbitmap-image&quot;);
</span><span class="cx">     if (!imageUTI || !CFEqual(imageUTI, xbmUTI))
</span><span class="lines">@@ -442,7 +485,7 @@
</span><span class="cx">     // a duration of &lt;= 10 ms. See &lt;rdar://problem/7689300&gt; and &lt;http://webkit.org/b/36082&gt;
</span><span class="cx">     // for more information.
</span><span class="cx">     if (duration &lt; 0.011f)
</span><del>-        return 0.1f;
</del><ins>+        return 0.100f;
</ins><span class="cx">     return duration;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -467,9 +510,9 @@
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-unsigned ImageSource::frameBytesAtIndex(size_t index, SubsamplingLevel subsamplingLevel) const
</del><ins>+unsigned ImageSource::frameBytesAtIndex(size_t index) const
</ins><span class="cx"> {
</span><del>-    IntSize frameSize = frameSizeAtIndex(index, subsamplingLevel, ImageOrientationDescription(RespectImageOrientation));
</del><ins>+    IntSize frameSize = frameSizeAtIndex(index, ImageOrientationDescription(RespectImageOrientation));
</ins><span class="cx">     return frameSize.width() * frameSize.height() * 4;
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsmacImageMacmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/mac/ImageMac.mm (171963 => 171964)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/mac/ImageMac.mm        2014-08-02 04:00:18 UTC (rev 171963)
+++ trunk/Source/WebCore/platform/graphics/mac/ImageMac.mm        2014-08-02 05:10:46 UTC (rev 171964)
</span><span class="lines">@@ -57,9 +57,9 @@
</span><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx"> #if USE(APPKIT)
</span><del>-    m_nsImage = nullptr;
</del><ins>+    m_nsImage = 0;
</ins><span class="cx"> #endif
</span><del>-    m_tiffRep = nullptr;
</del><ins>+    m_tiffRep = 0;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> PassRefPtr&lt;Image&gt; Image::loadPlatformResource(const char *name)
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicswinceImageWinCEcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/wince/ImageWinCE.cpp (171963 => 171964)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/wince/ImageWinCE.cpp        2014-08-02 04:00:18 UTC (rev 171963)
+++ trunk/Source/WebCore/platform/graphics/wince/ImageWinCE.cpp        2014-08-02 05:10:46 UTC (rev 171964)
</span><span class="lines">@@ -148,11 +148,6 @@
</span><span class="cx">     bmp-&gt;drawPattern(ctxt, tileRectIn, patternTransform, phase, styleColorSpace, op, destRect, m_source.size());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void BitmapImage::determineMinimumSubsamplingLevel() const
-{
-    m_minimumSubsamplingLevel = 0;
-}
-
</del><span class="cx"> void BitmapImage::checkForSolidColor()
</span><span class="cx"> {
</span><span class="cx">     if (m_checkedForSolidColor)
</span></span></pre>
</div>
</div>

</body>
</html>