Fix nonpremultiplied webgl toDataURL to jpeg
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 19 Sep 2011 22:23:28 +0000 (22:23 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 19 Sep 2011 22:23:28 +0000 (22:23 +0000)
https://bugs.webkit.org/show_bug.cgi?id=68366

Source/WebCore:

The canvas spec says that toDataURL to formats without an alpha must
be "composited onto a solid black background using the source-over
operator." Do that.

Patch by John Bauman <jbauman@chromium.org> on 2011-09-19
Reviewed by Kenneth Russell.

* platform/image-encoders/skia/JPEGImageEncoder.cpp:
(WebCore::RGBAtoRGB):

LayoutTests:

Update the premultiplyalpha-test from the WebGL conformance tests.

Patch by John Bauman <jbauman@chromium.org> on 2011-09-19
Reviewed by Kenneth Russell.

* fast/canvas/webgl/premultiplyalpha-test-expected.txt:
* fast/canvas/webgl/premultiplyalpha-test.html:

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@95482 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/fast/canvas/webgl/premultiplyalpha-test-expected.txt
LayoutTests/fast/canvas/webgl/premultiplyalpha-test.html
Source/WebCore/ChangeLog
Source/WebCore/platform/image-encoders/skia/JPEGImageEncoder.cpp

index 90a429f..87d349d 100644 (file)
@@ -1,3 +1,15 @@
+2011-09-19  John Bauman  <jbauman@chromium.org>
+
+        Fix nonpremultiplied webgl toDataURL to jpeg
+        https://bugs.webkit.org/show_bug.cgi?id=68366
+
+        Update the premultiplyalpha-test from the WebGL conformance tests.
+
+        Reviewed by Kenneth Russell.
+
+        * fast/canvas/webgl/premultiplyalpha-test-expected.txt:
+        * fast/canvas/webgl/premultiplyalpha-test.html:
+
 2011-09-19  Ryosuke Niwa  <rniwa@webkit.org>
 
         Incorrect selection with absolutely positioned div
index d44a54c..111654d 100644 (file)
@@ -3,35 +3,57 @@ Test the WebGL premultipledAlpha context creation flag.
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
-testing: premultipliedAlpha: true toDataURL: true
+testing: premultipliedAlpha: true imageFormat: image/png
 PASS gl.getContextAttributes().premultipledAlpha is premultipledAlpha
+PASS gl.getContextAttributes().preserveDrawingBuffer is true
 PASS getError was expected value: NO_ERROR : Should be no errors from setup.
 PASS getError was expected value: NO_ERROR : Should be no errors from drawing.
 PASS getError was expected value: NO_ERROR : Should be no errors from creating copy.
 PASS getError was expected value: NO_ERROR : Should be no errors from 2nd drawing.
 PASS should draw with 64,128,255,128
 
-testing: premultipliedAlpha: true toDataURL: false
+testing: premultipliedAlpha: true imageFormat: undefined
 PASS gl.getContextAttributes().premultipledAlpha is premultipledAlpha
+PASS gl.getContextAttributes().preserveDrawingBuffer is true
 PASS getError was expected value: NO_ERROR : Should be no errors from setup.
 PASS getError was expected value: NO_ERROR : Should be no errors from drawing.
 PASS getError was expected value: NO_ERROR : Should be no errors from creating copy.
 PASS getError was expected value: NO_ERROR : Should be no errors from 2nd drawing.
 PASS should draw with 64,128,255,128
 
-testing: premultipliedAlpha: false toDataURL: true
+testing: premultipliedAlpha: false imageFormat: image/png
 PASS gl.getContextAttributes().premultipledAlpha is premultipledAlpha
+PASS gl.getContextAttributes().preserveDrawingBuffer is true
 PASS getError was expected value: NO_ERROR : Should be no errors from setup.
 PASS getError was expected value: NO_ERROR : Should be no errors from drawing.
 PASS getError was expected value: NO_ERROR : Should be no errors from creating copy.
 PASS getError was expected value: NO_ERROR : Should be no errors from 2nd drawing.
 PASS should draw with 255,192,128,1
 
-testing: premultipliedAlpha: false toDataURL: false
+testing: premultipliedAlpha: false imageFormat: undefined
 PASS gl.getContextAttributes().premultipledAlpha is premultipledAlpha
+PASS gl.getContextAttributes().preserveDrawingBuffer is true
 PASS getError was expected value: NO_ERROR : Should be no errors from setup.
 PASS getError was expected value: NO_ERROR : Should be no errors from drawing.
 PASS getError was expected value: NO_ERROR : Should be no errors from creating copy.
 PASS getError was expected value: NO_ERROR : Should be no errors from 2nd drawing.
 PASS should draw with 255,192,128,1
 
+testing: premultipliedAlpha: false imageFormat: image/jpeg
+PASS gl.getContextAttributes().premultipledAlpha is premultipledAlpha
+PASS gl.getContextAttributes().preserveDrawingBuffer is true
+PASS getError was expected value: NO_ERROR : Should be no errors from setup.
+PASS getError was expected value: NO_ERROR : Should be no errors from drawing.
+PASS getError was expected value: NO_ERROR : Should be no errors from creating copy.
+PASS getError was expected value: NO_ERROR : Should be no errors from 2nd drawing.
+PASS should draw with 128,128,128,255
+
+testing: premultipliedAlpha: true imageFormat: image/jpeg
+PASS gl.getContextAttributes().premultipledAlpha is premultipledAlpha
+PASS gl.getContextAttributes().preserveDrawingBuffer is true
+PASS getError was expected value: NO_ERROR : Should be no errors from setup.
+PASS getError was expected value: NO_ERROR : Should be no errors from drawing.
+PASS getError was expected value: NO_ERROR : Should be no errors from creating copy.
+PASS getError was expected value: NO_ERROR : Should be no errors from 2nd drawing.
+PASS should draw with 128,128,128,255
+
index 677a370..3bf449a 100644 (file)
@@ -1,7 +1,7 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
-  "http://www.w3.org/TR/html4/loose.dtd">
+<!DOCTYPE html>
 <html>
 <head>
+<meta charset="utf-8">
 <title>Test the WebGL premultipledAlpha context creation flag.</title>
 <link rel="stylesheet" href="../../js/resources/js-test-style.css"/>
 <script src="../../js/resources/js-test-pre.js"></script>
@@ -21,7 +21,7 @@ var tests = [
     sentColor: [32, 64, 128, 128],
     expectedColor: [64, 128, 255, 128],
     errorRange: 2,
-    useToDataURL: true,
+    imageFormat: "image/png"
   },
   // If premultipledAlpha is true then
   // [texture]           [canvas]             [texture]
@@ -30,7 +30,6 @@ var tests = [
     sentColor: [32, 64, 128, 128],
     expectedColor: [64, 128, 255, 128],
     errorRange: 2,
-    useToDataURL: false,
   },
   // If premultipledAlpha is false then
   // [texture]           [canvas]            [dataURL]
@@ -39,7 +38,7 @@ var tests = [
     sentColor: [255, 192, 128, 1],
     expectedColor: [255, 192, 128, 1],
     errorRange: 0,
-    useToDataURL: true,
+    imageFormat: "image/png"
   },
   // If premultipledAlpha is false then
   // [texture]           [canvas]            [texture]
@@ -48,7 +47,24 @@ var tests = [
     sentColor: [255, 192, 128, 1],
     expectedColor: [255, 192, 128, 1],
     errorRange: 0,
-    useToDataURL: false,
+  },
+  // If premultipledAlpha is false then
+  // [texture]             [canvas]            [dataURL]
+  // 255, 255, 255, 128 -> 255, 255, 255, 128 -> 128, 128, 128, 255
+  { creationAttributes: {premultipliedAlpha: false},
+    sentColor: [255, 255, 255, 128],
+    expectedColor: [128, 128, 128, 255],
+    errorRange: 2,
+    imageFormat: "image/jpeg"
+  },
+  // If premultipledAlpha is true then
+  // [texture]             [canvas]            [dataURL]
+  // 128, 128, 128, 128 -> 255, 255, 255, 128 -> 128, 128, 128, 255
+  { creationAttributes: {},
+    sentColor: [128, 128, 128, 128],
+    expectedColor: [128, 128, 128, 255],
+    errorRange: 2,
+    imageFormat: "image/jpeg"
   }
 ];
 
@@ -68,12 +84,15 @@ function doNextTest() {
   if (g_count < tests.length) {
      var test = tests[g_count++];
      canvas = document.createElement("canvas");
+     // Need to preserve drawing buffer to load it in a callback
+     test.creationAttributes.preserveDrawingBuffer = true;
      gl = wtu.create3DContext(canvas, test.creationAttributes);
      var premultipliedAlpha = test.creationAttributes.premultipliedAlpha != false;
      debug("")
-     debug("testing: premultipliedAlpha: " + premultipliedAlpha + " toDataURL: " + test.useToDataURL);
+     debug("testing: premultipliedAlpha: " + premultipliedAlpha + " imageFormat: " + test.imageFormat);
 
      shouldBe('gl.getContextAttributes().premultipledAlpha', 'premultipledAlpha');
+     shouldBeTrue('gl.getContextAttributes().preserveDrawingBuffer');
 
      var program = wtu.setupTexturedQuad(gl);
 
@@ -96,7 +115,7 @@ function doNextTest() {
        // gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);
        gl.pixelStorei(gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, false);
        gl.bindTexture(gl.TEXTURE_2D, pngTex);
-       if (test.useToDataURL) {
+       if (test.imageFormat) {
           // create texture from image
           gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this);
        } else {
@@ -117,13 +136,20 @@ function doNextTest() {
        doNextTest();
      }
 
-     if (test.useToDataURL) {
+     if (test.imageFormat) {
         // Load canvas into string using toDataURL
-        var png = canvas.toDataURL();
-        // Load string into the texture
-        var input = document.createElement("img");
-        input.onload = loadTexture;
-        input.src = png;
+        var imageUrl = canvas.toDataURL(test.imageFormat);
+        if (test.imageFormat != "image/png" &&
+            (imageUrl.indexOf("data:image/png,") == 0 ||
+             imageUrl.indexOf("data:image/png;") == 0)) {
+          debug("Image format " + test.imageFormat + " not supported; skipping");
+          setTimeout(doNextTest, 0);
+        } else {
+          // Load string into the texture
+          var input = document.createElement("img");
+          input.onload = loadTexture;
+          input.src = imageUrl;
+        }
      } else {
         // Load canvas into the texture asynchronously (to prevent unbounded stack consumption)
         setTimeout(loadTexture, 0);
@@ -138,9 +164,6 @@ function doNextTest() {
 
 </script>
 
-<script>
-</script>
-
 </body>
 </html>
 
index 05de0e0..25e3aaa 100644 (file)
@@ -1,3 +1,17 @@
+2011-09-19  John Bauman  <jbauman@chromium.org>
+
+        Fix nonpremultiplied webgl toDataURL to jpeg
+        https://bugs.webkit.org/show_bug.cgi?id=68366
+
+        The canvas spec says that toDataURL to formats without an alpha must
+        be "composited onto a solid black background using the source-over
+        operator." Do that.
+
+        Reviewed by Kenneth Russell.
+
+        * platform/image-encoders/skia/JPEGImageEncoder.cpp:
+        (WebCore::RGBAtoRGB):
+
 2011-09-19  Chris Marrin  <cmarrin@apple.com>
 
         Crash can occur when doing a PlatformCAAnimation::copy() with no valueFunction
index 9fd6972..3bdb519 100644 (file)
@@ -92,9 +92,10 @@ static void preMultipliedBGRAtoRGB(const unsigned char* pixels, unsigned int pix
 static void RGBAtoRGB(const unsigned char* pixels, unsigned int pixelCount, unsigned char* output)
 {
     for (; pixelCount-- > 0; pixels += 4) {
-        *output++ = pixels[0];
-        *output++ = pixels[1];
-        *output++ = pixels[2];
+        // Do source-over composition on black.
+        *output++ = pixels[0] * pixels[3] / 255;
+        *output++ = pixels[1] * pixels[3] / 255;
+        *output++ = pixels[2] * pixels[3] / 255;
     }
 }