<!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>[170675] trunk</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/170675">170675</a></dd>
<dt>Author</dt> <dd>dino@apple.com</dd>
<dt>Date</dt> <dd>2014-07-01 16:26:12 -0700 (Tue, 01 Jul 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>[iOS] Subsampled JPEG images do not draw correctly via the canvas APIs
https://bugs.webkit.org/show_bug.cgi?id=134513
&lt;rdar://problem/12078860&gt;
&lt;rdar://problem/16745393&gt;

Reviewed by Tim Horton.

Source/WebCore:
Subsampled images (e.g. JPEG) were not consistently using
their original dimensions and subsampled dimensions. This caused
things like texImage2D to pack the pixels incorrectly, or drawImage
to squish the rendering.

Renamed m_scale to m_subsamplingScale on FrameData.

Tests: fast/canvas/image-potential-subsample.html
       fast/canvas/webgl/tex-image-and-sub-image-2d-with-potentially-subsampled-image.html

* platform/graphics/BitmapImage.cpp:
(WebCore::BitmapImage::cacheFrame): Rename to m_subsamplingScale.
(WebCore::BitmapImage::frameAtIndex): Ditto.
* platform/graphics/BitmapImage.h:
(WebCore::FrameData::FrameData): Ditto.
* platform/graphics/cg/BitmapImageCG.cpp:
(WebCore::FrameData::clear): Ditto.
(WebCore::BitmapImage::BitmapImage): Ditto.
(WebCore::BitmapImage::draw): Use a scaledSrcRect that reflects the subsampled size,
rather than assuming the srcRect accurately reflects how many pixels we have
in the Bitmap.
(WebCore::BitmapImage::copyUnscaledFrameAtIndex):
* platform/graphics/cg/GraphicsContext3DCG.cpp:
(WebCore::GraphicsContext3D::ImageExtractor::extractImage): Similar fix, although this
time we just ask the image decoder to take into account the subsampled size
when it is &quot;generating&quot; a frame, causing it to use the bitmap data it has already
decoded.

LayoutTests:
Add Canvas2D and WebGL tests that exercise a very large JPEG image.

The WebGL test is mostly copied from the WebGL test suite, so please
excuse the coding style.

* fast/canvas/image-potential-subsample-expected.txt: Added.
* fast/canvas/image-potential-subsample.html: Added.
* fast/canvas/resources/image-8000x8000.jpg: Added.
* fast/canvas/webgl/resources/tex-image-and-sub-image-2d-with-potentially-subsampled-image.js: Added.
(.init):
(.runOneIteration):
(.runTestOnImage):
(.runTest):
(generateTest):
* fast/canvas/webgl/tex-image-and-sub-image-2d-with-potentially-subsampled-image-expected.txt: Added.
* fast/canvas/webgl/tex-image-and-sub-image-2d-with-potentially-subsampled-image.html: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</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="#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>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsfastcanvasimagepotentialsubsampleexpectedtxt">trunk/LayoutTests/fast/canvas/image-potential-subsample-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastcanvasimagepotentialsubsamplehtml">trunk/LayoutTests/fast/canvas/image-potential-subsample.html</a></li>
<li><a href="#trunkLayoutTestsfastcanvasresourcesimage8000x8000jpg">trunk/LayoutTests/fast/canvas/resources/image-8000x8000.jpg</a></li>
<li><a href="#trunkLayoutTestsfastcanvaswebglresourcesteximageandsubimage2dwithpotentiallysubsampledimagejs">trunk/LayoutTests/fast/canvas/webgl/resources/tex-image-and-sub-image-2d-with-potentially-subsampled-image.js</a></li>
<li><a href="#trunkLayoutTestsfastcanvaswebglteximageandsubimage2dwithpotentiallysubsampledimageexpectedtxt">trunk/LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-potentially-subsampled-image-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastcanvaswebglteximageandsubimage2dwithpotentiallysubsampledimagehtml">trunk/LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-potentially-subsampled-image.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (170674 => 170675)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2014-07-01 23:22:03 UTC (rev 170674)
+++ trunk/LayoutTests/ChangeLog        2014-07-01 23:26:12 UTC (rev 170675)
</span><span class="lines">@@ -1,3 +1,29 @@
</span><ins>+2014-07-01  Dean Jackson  &lt;dino@apple.com&gt;
+
+        [iOS] Subsampled JPEG images do not draw correctly via the canvas APIs
+        https://bugs.webkit.org/show_bug.cgi?id=134513
+        &lt;rdar://problem/12078860&gt;
+        &lt;rdar://problem/16745393&gt;
+
+        Reviewed by Tim Horton.
+
+        Add Canvas2D and WebGL tests that exercise a very large JPEG image.
+
+        The WebGL test is mostly copied from the WebGL test suite, so please
+        excuse the coding style.
+
+        * fast/canvas/image-potential-subsample-expected.txt: Added.
+        * fast/canvas/image-potential-subsample.html: Added.
+        * fast/canvas/resources/image-8000x8000.jpg: Added.
+        * fast/canvas/webgl/resources/tex-image-and-sub-image-2d-with-potentially-subsampled-image.js: Added.
+        (.init):
+        (.runOneIteration):
+        (.runTestOnImage):
+        (.runTest):
+        (generateTest):
+        * fast/canvas/webgl/tex-image-and-sub-image-2d-with-potentially-subsampled-image-expected.txt: Added.
+        * fast/canvas/webgl/tex-image-and-sub-image-2d-with-potentially-subsampled-image.html: Added.
+
</ins><span class="cx"> 2014-07-01  Chris Fleizach  &lt;cfleizach@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         AX: HTML indeterminate IDL attribute not mapped to checkbox value=2
</span></span></pre></div>
<a id="trunkLayoutTestsfastcanvasimagepotentialsubsampleexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/canvas/image-potential-subsample-expected.txt (0 => 170675)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/canvas/image-potential-subsample-expected.txt                                (rev 0)
+++ trunk/LayoutTests/fast/canvas/image-potential-subsample-expected.txt        2014-07-01 23:26:12 UTC (rev 170675)
</span><span class="lines">@@ -0,0 +1,5 @@
</span><ins>+PASS: Pixel (10, 10) was close to 255,0,0,255
+
+PASS: Pixel (200, 200) was close to 0,255,0,255
+
+PASS: Pixel (390, 390) was close to 0,0,255,255
</ins><span class="cx">Property changes on: trunk/LayoutTests/fast/canvas/image-potential-subsample-expected.txt
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkLayoutTestsfastcanvasimagepotentialsubsamplehtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/canvas/image-potential-subsample.html (0 => 170675)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/canvas/image-potential-subsample.html                                (rev 0)
+++ trunk/LayoutTests/fast/canvas/image-potential-subsample.html        2014-07-01 23:26:12 UTC (rev 170675)
</span><span class="lines">@@ -0,0 +1,61 @@
</span><ins>+&lt;script&gt;
+
+if (window.testRunner) {
+    window.testRunner.dumpAsText();
+    window.testRunner.waitUntilDone();
+}
+
+function getPixel(canvas, x, y) {
+    var context = canvas.getContext(&quot;2d&quot;);
+    var data = context.getImageData(x, y, 1, 1);
+    if (!data)
+        return [-1, -1, -1, -1];
+
+    var result = new Array(data.data.length)
+    for (var i = 0; i &lt; data.data.length; i++)
+        result[i] = data.data[i];
+
+    return result;
+}
+
+function checkArrayValues(a1, a2, tolerance) {
+    for (var i = 0, length = a1.length; i &lt; length; i++) {
+        if (Math.abs(a1[i] - a2[i]) &gt; tolerance)
+            return false;
+    }
+    return true;
+}
+
+function pixelShouldBe(canvas, x, y, color, tolerance) {
+    var output = document.createElement(&quot;p&quot;);
+    var value = getPixel(canvas, x, y);
+    if (checkArrayValues(color, value, tolerance))
+        output.innerText = &quot;PASS: Pixel (&quot; + x + &quot;, &quot; + y + &quot;) was close to &quot; + color;
+    else
+        output.innerText = &quot;FAIL: Pixel (&quot; + x + &quot;, &quot; + y + &quot;) was &quot; + value + &quot;. Expected &quot; + color;
+    document.body.appendChild(output);
+}
+
+function run() {
+    var canvas = document.createElement(&quot;canvas&quot;);
+    document.body.appendChild(canvas);
+    canvas.width = 400;
+    canvas.height = 400;
+    var ctx = canvas.getContext(&quot;2d&quot;);
+    var img = new Image()
+    img.addEventListener(&quot;load&quot;, function() {
+        ctx.fillStyle = &quot;red&quot;;
+        ctx.fillRect(0, 0, 400, 400);
+        ctx.drawImage(img, 0, 0, 400, 400);
+        pixelShouldBe(canvas, 10, 10, [255, 0, 0, 255], 5);
+        pixelShouldBe(canvas, 200, 200, [0, 255, 0, 255], 5);
+        pixelShouldBe(canvas, 390, 390, [0, 0, 255, 255], 5);
+
+       if (window.testRunner)
+           testRunner.notifyDone();
+    }, false)
+    img.src = &quot;resources/image-8000x8000.jpg&quot;;
+}
+
+window.addEventListener(&quot;load&quot;, run, false);
+&lt;/script&gt;
</ins><span class="cx">Property changes on: trunk/LayoutTests/fast/canvas/image-potential-subsample.html
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkLayoutTestsfastcanvasresourcesimage8000x8000jpg"></a>
<div class="binary"><h4>Added: trunk/LayoutTests/fast/canvas/resources/image-8000x8000.jpg</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Property changes on: trunk/LayoutTests/fast/canvas/resources/image-8000x8000.jpg
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<a id="trunkLayoutTestsfastcanvaswebglresourcesteximageandsubimage2dwithpotentiallysubsampledimagejs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/canvas/webgl/resources/tex-image-and-sub-image-2d-with-potentially-subsampled-image.js (0 => 170675)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/canvas/webgl/resources/tex-image-and-sub-image-2d-with-potentially-subsampled-image.js                                (rev 0)
+++ trunk/LayoutTests/fast/canvas/webgl/resources/tex-image-and-sub-image-2d-with-potentially-subsampled-image.js        2014-07-01 23:26:12 UTC (rev 170675)
</span><span class="lines">@@ -0,0 +1,93 @@
</span><ins>+function generateTest(pixelFormat, pixelType, pathToTestRoot, prologue) {
+    var wtu = WebGLTestUtils;
+    var gl = null;
+    var textureLoc = null;
+    var successfullyParsed = false;
+    var imgCanvas;
+    var red = [255, 0, 0];
+    var green = [0, 255, 0];
+    var blue = [0, 0, 255];
+
+    var init = function()
+    {
+        if (window.initNonKhronosFramework) {
+            window.initNonKhronosFramework(true);
+        }
+
+        description('Verify texImage2D and texSubImage2D code paths with potentially subsampled images (' + pixelFormat + '/' + pixelType + ')');
+
+        gl = wtu.create3DContext(&quot;example&quot;);
+
+        if (!prologue(gl)) {
+            finishTest();
+            return;
+        }
+
+        var program = wtu.setupTexturedQuad(gl);
+
+        gl.clearColor(0,0,0,1);
+        gl.clearDepth(1);
+
+        textureLoc = gl.getUniformLocation(program, &quot;tex&quot;);
+
+        wtu.loadTexture(gl, pathToTestRoot + &quot;/../resources/image-8000x8000.jpg&quot;, runTest);
+    }
+
+    function runOneIteration(image, useTexSubImage2D, flipY, topColor, middleColor, bottomColor)
+    {
+        debug('Testing ' + (useTexSubImage2D ? 'texSubImage2D' : 'texImage2D') +
+              ' with flipY=' + flipY);
+        gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+        var texture = gl.createTexture();
+        // Bind the texture to texture unit 0
+        gl.bindTexture(gl.TEXTURE_2D, texture);
+        // Set up texture parameters
+        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+        // Set up pixel store parameters
+        gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flipY);
+        gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);
+        gl.pixelStorei(gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, gl.NONE);
+        // Upload the image into the texture
+        if (useTexSubImage2D) {
+            // Initialize the texture to black first
+            gl.texImage2D(gl.TEXTURE_2D, 0, gl[pixelFormat], image.width, image.height, 0,
+                          gl[pixelFormat], gl[pixelType], null);
+            gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl[pixelFormat], gl[pixelType], image);
+        } else {
+            gl.texImage2D(gl.TEXTURE_2D, 0, gl[pixelFormat], gl[pixelFormat], gl[pixelType], image);
+        }
+
+        // Point the uniform sampler to texture unit 0
+        gl.uniform1i(textureLoc, 0);
+        // Draw the triangles
+        wtu.drawQuad(gl, [0, 0, 0, 255]);
+
+        // Check the pixels at the top left, middle and bottom right.
+
+        debug(&quot;Checking upper left corner&quot;);
+        wtu.checkCanvasRect(gl, 2, gl.canvas.height - 2, 1, 1, topColor, &quot;shouldBe &quot; + topColor, 5);
+        debug(&quot;Checking middle&quot;);
+        wtu.checkCanvasRect(gl, gl.canvas.width / 2, gl.canvas.height / 2, 1, 1, middleColor, &quot;shouldBe &quot; + middleColor, 5);
+        debug(&quot;Checking bottom right corner&quot;);
+        wtu.checkCanvasRect(gl, gl.canvas.width - 2, 2, 1, 1, bottomColor, &quot;shouldBe &quot; + bottomColor, 5);
+    }
+
+    function runTestOnImage(image) {
+        runOneIteration(image, false, true, red, green, blue);
+        runOneIteration(image, false, false, green, green, green);
+        runOneIteration(image, true, true, red, green, blue);
+        runOneIteration(image, true, false, green, green, green);
+    }
+
+    function runTest(image)
+    {
+        runTestOnImage(image);
+        glErrorShouldBe(gl, gl.NO_ERROR, &quot;should be no errors&quot;);
+        finishTest();
+    }
+
+    return init;
+}
</ins><span class="cx">Property changes on: trunk/LayoutTests/fast/canvas/webgl/resources/tex-image-and-sub-image-2d-with-potentially-subsampled-image.js
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkLayoutTestsfastcanvaswebglteximageandsubimage2dwithpotentiallysubsampledimageexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-potentially-subsampled-image-expected.txt (0 => 170675)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-potentially-subsampled-image-expected.txt                                (rev 0)
+++ trunk/LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-potentially-subsampled-image-expected.txt        2014-07-01 23:26:12 UTC (rev 170675)
</span><span class="lines">@@ -0,0 +1,37 @@
</span><ins>+Verify texImage2D and texSubImage2D code paths with potentially subsampled images (RGBA/UNSIGNED_BYTE)
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+Testing texImage2D with flipY=true
+Checking upper left corner
+PASS shouldBe 255,0,0
+Checking middle
+PASS shouldBe 0,255,0
+Checking bottom right corner
+PASS shouldBe 0,0,255
+Testing texImage2D with flipY=false
+Checking upper left corner
+PASS shouldBe 0,255,0
+Checking middle
+PASS shouldBe 0,255,0
+Checking bottom right corner
+PASS shouldBe 0,255,0
+Testing texSubImage2D with flipY=true
+Checking upper left corner
+PASS shouldBe 255,0,0
+Checking middle
+PASS shouldBe 0,255,0
+Checking bottom right corner
+PASS shouldBe 0,0,255
+Testing texSubImage2D with flipY=false
+Checking upper left corner
+PASS shouldBe 0,255,0
+Checking middle
+PASS shouldBe 0,255,0
+Checking bottom right corner
+PASS shouldBe 0,255,0
+PASS getError was expected value: NO_ERROR : should be no errors
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins><span class="cx">Property changes on: trunk/LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-potentially-subsampled-image-expected.txt
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkLayoutTestsfastcanvaswebglteximageandsubimage2dwithpotentiallysubsampledimagehtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-potentially-subsampled-image.html (0 => 170675)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-potentially-subsampled-image.html                                (rev 0)
+++ trunk/LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-potentially-subsampled-image.html        2014-07-01 23:26:12 UTC (rev 170675)
</span><span class="lines">@@ -0,0 +1,20 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;meta charset=&quot;utf-8&quot;&gt;
+&lt;script src=&quot;../../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;resources/webgl-test.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;resources/webgl-test-utils.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;resources/tex-image-and-sub-image-2d-with-potentially-subsampled-image.js&quot;&gt;&lt;/script&gt;
+&lt;script&gt;
+function testPrologue(gl) {
+    return true;
+}
+&lt;/script&gt;
+&lt;/head&gt;
+&lt;body onload='generateTest(&quot;RGBA&quot;, &quot;UNSIGNED_BYTE&quot;, &quot;.&quot;, testPrologue)()'&gt;
+&lt;canvas id=&quot;example&quot; width=&quot;200px&quot; height=&quot;200px&quot;&gt;&lt;/canvas&gt;
+&lt;div id=&quot;description&quot;&gt;&lt;/div&gt;
+&lt;div id=&quot;console&quot;&gt;&lt;/div&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins><span class="cx">Property changes on: trunk/LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-potentially-subsampled-image.html
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (170674 => 170675)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2014-07-01 23:22:03 UTC (rev 170674)
+++ trunk/Source/WebCore/ChangeLog        2014-07-01 23:26:12 UTC (rev 170675)
</span><span class="lines">@@ -1,3 +1,40 @@
</span><ins>+2014-07-01  Dean Jackson  &lt;dino@apple.com&gt;
+
+        [iOS] Subsampled JPEG images do not draw correctly via the canvas APIs
+        https://bugs.webkit.org/show_bug.cgi?id=134513
+        &lt;rdar://problem/12078860&gt;
+        &lt;rdar://problem/16745393&gt;
+
+        Reviewed by Tim Horton.
+
+        Subsampled images (e.g. JPEG) were not consistently using
+        their original dimensions and subsampled dimensions. This caused
+        things like texImage2D to pack the pixels incorrectly, or drawImage
+        to squish the rendering.
+
+        Renamed m_scale to m_subsamplingScale on FrameData.
+
+        Tests: fast/canvas/image-potential-subsample.html
+               fast/canvas/webgl/tex-image-and-sub-image-2d-with-potentially-subsampled-image.html
+
+        * platform/graphics/BitmapImage.cpp:
+        (WebCore::BitmapImage::cacheFrame): Rename to m_subsamplingScale.
+        (WebCore::BitmapImage::frameAtIndex): Ditto.
+        * platform/graphics/BitmapImage.h:
+        (WebCore::FrameData::FrameData): Ditto.
+        * platform/graphics/cg/BitmapImageCG.cpp:
+        (WebCore::FrameData::clear): Ditto.
+        (WebCore::BitmapImage::BitmapImage): Ditto.
+        (WebCore::BitmapImage::draw): Use a scaledSrcRect that reflects the subsampled size,
+        rather than assuming the srcRect accurately reflects how many pixels we have
+        in the Bitmap.
+        (WebCore::BitmapImage::copyUnscaledFrameAtIndex):
+        * platform/graphics/cg/GraphicsContext3DCG.cpp:
+        (WebCore::GraphicsContext3D::ImageExtractor::extractImage): Similar fix, although this
+        time we just ask the image decoder to take into account the subsampled size
+        when it is &quot;generating&quot; a frame, causing it to use the bitmap data it has already
+        decoded.
+
</ins><span class="cx"> 2014-07-01  Joseph Pecoraro  &lt;pecoraro@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Web Inspector: Selected DOM element highlights invisible near bottom of the viewport (topContentInset?)
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsBitmapImagecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/BitmapImage.cpp (170674 => 170675)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/BitmapImage.cpp        2014-07-01 23:22:03 UTC (rev 170674)
+++ trunk/Source/WebCore/platform/graphics/BitmapImage.cpp        2014-07-01 23:26:12 UTC (rev 170675)
</span><span class="lines">@@ -166,7 +166,7 @@
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(IOS)
</span><span class="cx">     m_frames[index].m_frame = m_source.createFrameAtIndex(index, &amp;scaleHint);
</span><del>-    m_frames[index].m_scale = scaleHint;
</del><ins>+    m_frames[index].m_subsamplingScale = scaleHint;
</ins><span class="cx"> #else
</span><span class="cx">     m_frames[index].m_frame = m_source.createFrameAtIndex(index);
</span><span class="cx"> #endif
</span><span class="lines">@@ -431,7 +431,7 @@
</span><span class="cx"> 
</span><span class="cx">     if (index &gt;= m_frames.size() || !m_frames[index].m_frame)
</span><span class="cx">         cacheFrame(index, scaleHint);
</span><del>-    else if (std::min(1.0f, scaleHint) &gt; m_frames[index].m_scale) {
</del><ins>+    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><span class="cx">         ASSERT(static_cast&lt;int&gt;(m_decodedSize) + sizeChange &gt;= 0);
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsBitmapImageh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/BitmapImage.h (170674 => 170675)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/BitmapImage.h        2014-07-01 23:22:03 UTC (rev 170674)
+++ trunk/Source/WebCore/platform/graphics/BitmapImage.h        2014-07-01 23:26:12 UTC (rev 170675)
</span><span class="lines">@@ -71,7 +71,7 @@
</span><span class="cx">         : m_frame(0)
</span><span class="cx">         , m_orientation(DefaultImageOrientation)
</span><span class="cx"> #if PLATFORM(IOS)
</span><del>-        , m_scale(0)
</del><ins>+        , m_subsamplingScale(0)
</ins><span class="cx">         , m_haveInfo(false)
</span><span class="cx"> #endif
</span><span class="cx">         , m_duration(0)
</span><span class="lines">@@ -94,7 +94,7 @@
</span><span class="cx">     NativeImagePtr m_frame;
</span><span class="cx">     ImageOrientation m_orientation;
</span><span class="cx"> #if PLATFORM(IOS)
</span><del>-    float m_scale;
</del><ins>+    float m_subsamplingScale;
</ins><span class="cx">     bool m_haveInfo;
</span><span class="cx"> #endif
</span><span class="cx">     float m_duration;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicscgBitmapImageCGcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/cg/BitmapImageCG.cpp (170674 => 170675)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/cg/BitmapImageCG.cpp        2014-07-01 23:22:03 UTC (rev 170674)
+++ trunk/Source/WebCore/platform/graphics/cg/BitmapImageCG.cpp        2014-07-01 23:26:12 UTC (rev 170675)
</span><span class="lines">@@ -61,7 +61,7 @@
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(IOS)
</span><span class="cx">     m_frameBytes = 0;
</span><del>-    m_scale = 1;
</del><ins>+    m_subsamplingScale = 1;
</ins><span class="cx">     m_haveInfo = false;
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="lines">@@ -114,7 +114,7 @@
</span><span class="cx">     m_frames[0].m_haveMetadata = true;
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(IOS)
</span><del>-    m_frames[0].m_scale = 1;
</del><ins>+    m_frames[0].m_subsamplingScale = 1;
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     checkForSolidColor();
</span><span class="lines">@@ -199,11 +199,12 @@
</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><span class="cx">     CGImageRef image;
</span><del>-#if !PLATFORM(IOS)
-    startAnimation();
</del><ins>+    FloatRect srcRectForCurrentFrame = srcRect;
</ins><span class="cx"> 
</span><del>-    image = frameAtIndex(m_currentFrame);
-#else
</del><ins>+#if PLATFORM(IOS)
+    if (m_originalSize.width() &amp;&amp; m_originalSize.height())
+        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><span class="cx"> 
</span><span class="cx">     CGRect transformedDestinationRect = CGRectApplyAffineTransform(destRect, CGContextGetCTM(ctxt-&gt;platformContext()));
</span><span class="lines">@@ -212,10 +213,15 @@
</span><span class="cx">     if (CGContextGetType(ctxt-&gt;platformContext()) == kCGContextTypePDF)
</span><span class="cx">         imagePossiblyCopied = adoptCF(copyUnscaledFrameAtIndex(m_currentFrame));
</span><span class="cx">     else
</span><del>-        imagePossiblyCopied = frameAtIndex(m_currentFrame, std::min&lt;float&gt;(1.0f, std::max(transformedDestinationRect.size.width  / srcRect.width(), transformedDestinationRect.size.height / srcRect.height())));
-    
</del><ins>+        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">     image = imagePossiblyCopied.get();
</span><ins>+#else
+    startAnimation();
+
+    image = frameAtIndex(m_currentFrame);
</ins><span class="cx"> #endif
</span><ins>+
</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">@@ -226,7 +232,7 @@
</span><span class="cx"> 
</span><span class="cx">     float scale = 1;
</span><span class="cx"> #if PLATFORM(IOS)
</span><del>-    scale = m_frames[m_currentFrame].m_scale;
</del><ins>+    scale = m_frames[m_currentFrame].m_subsamplingScale;
</ins><span class="cx"> #endif
</span><span class="cx">     FloatSize selfSize = currentFrameSize();
</span><span class="cx">     ImageOrientation orientation;
</span><span class="lines">@@ -234,7 +240,7 @@
</span><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, selfSize, styleColorSpace, destRect, srcRect, scale, 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="lines">@@ -249,7 +255,7 @@
</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_scale == 1 &amp;&amp; !m_source.isSubsampled())
</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></pre></div>
<a id="trunkSourceWebCoreplatformgraphicscgGraphicsContext3DCGcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp (170674 => 170675)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp        2014-07-01 23:22:03 UTC (rev 170674)
+++ trunk/Source/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp        2014-07-01 23:26:12 UTC (rev 170675)
</span><span class="lines">@@ -332,7 +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><ins>+#if PLATFORM(IOS)
+        float scaleHint = 1;
+        if (m_image-&gt;isBitmapImage()) {
+            IntSize originalSize = toBitmapImage(m_image)-&gt;originalSize();
+            if (originalSize.width() &amp;&amp; originalSize.height())
+                scaleHint = std::min&lt;float&gt;(1.0f, 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></pre>
</div>
</div>

</body>
</html>