[SCM] WebKit Debian packaging branch, webkit-1.3, updated. upstream/1.3.7-4207-g178b198

kbr at google.com kbr at google.com
Mon Feb 21 00:24:52 UTC 2011


The following commit has been merged in the webkit-1.3 branch:
commit bb1c5656b236098cb4e71147fb0f602d2b835796
Author: kbr at google.com <kbr at google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Mon Jan 31 05:11:00 2011 +0000

    2011-01-28  Kenneth Russell  <kbr at google.com>
    
            Reviewed by Chris Marrin.
    
            WebGL shows PNG Textures with indexed colors too dark
            https://bugs.webkit.org/show_bug.cgi?id=47477
    
            Added test case for upload of indexed PNG images to
            gl-teximage.html in the Khronos WebGL conformance tests.
            Synchronized this test with the Khronos repository.
    
            * fast/canvas/webgl/gl-teximage-expected.txt:
            * fast/canvas/webgl/gl-teximage.html:
            * fast/canvas/webgl/resources/red-indexed.png: Added.
    2011-01-28  Kenneth Russell  <kbr at google.com>
    
            Reviewed by Chris Marrin.
    
            WebGL shows PNG Textures with indexed colors too dark
            https://bugs.webkit.org/show_bug.cgi?id=47477
    
            Properly handle indexed PNG images by re-rendering them as RGBA
            images before upload. Verified with this layout test and the test
            cases from bugs 47477 and 53269.
    
            * platform/graphics/cg/GraphicsContext3DCG.cpp:
            (WebCore::GraphicsContext3D::getImageData):
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@77108 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index a79fee7..4d74701 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,18 @@
+2011-01-28  Kenneth Russell  <kbr at google.com>
+
+        Reviewed by Chris Marrin.
+
+        WebGL shows PNG Textures with indexed colors too dark
+        https://bugs.webkit.org/show_bug.cgi?id=47477
+
+        Added test case for upload of indexed PNG images to
+        gl-teximage.html in the Khronos WebGL conformance tests.
+        Synchronized this test with the Khronos repository.
+
+        * fast/canvas/webgl/gl-teximage-expected.txt:
+        * fast/canvas/webgl/gl-teximage.html:
+        * fast/canvas/webgl/resources/red-indexed.png: Added.
+
 2011-01-23  MORITA Hajime  <morrita at google.com>
 
         Reviewed by Eric Seidel.
diff --git a/LayoutTests/fast/canvas/webgl/gl-teximage-expected.txt b/LayoutTests/fast/canvas/webgl/gl-teximage-expected.txt
index ad48988..bc27210 100644
--- a/LayoutTests/fast/canvas/webgl/gl-teximage-expected.txt
+++ b/LayoutTests/fast/canvas/webgl/gl-teximage-expected.txt
@@ -48,6 +48,13 @@ PASS pixels should be same regardless of gamma settings.
 
 check pixels are UN pre-multiplied
 PASS getError was expected value: NO_ERROR : Should be no errors from setup.
+PASS Half the pixels in channel 0 should be >= 128,128,128. found 49%
+PASS Half the pixels in channel 0 should be < 128,128,128. found 51%
+PASS Half the pixels in channel 1 should be >= 128,128,128. found 49%
+PASS Half the pixels in channel 1 should be < 128,128,128. found 51%
+PASS Half the pixels in channel 2 should be >= 128,128,128. found 49%
+PASS Half the pixels in channel 2 should be < 128,128,128. found 51%
+PASS getError was expected value: NO_ERROR : Should be no errors from setup.
 PASS Half the pixels in channel 0 should be >= 128,128,128. found 50%
 PASS Half the pixels in channel 0 should be < 128,128,128. found 50%
 PASS Half the pixels in channel 1 should be >= 128,128,128. found 50%
@@ -55,6 +62,14 @@ PASS Half the pixels in channel 1 should be < 128,128,128. found 50%
 PASS Half the pixels in channel 2 should be >= 128,128,128. found 50%
 PASS Half the pixels in channel 2 should be < 128,128,128. found 50%
 
+check canvas pixels are UN pre-multiplied
+PASS getError was expected value: NO_ERROR : Should be no errors from setup.
+PASS pixel 0, 0 should be within 4 units of 255, 255, 255, 127 was 255, 255, 255, 127
+
+check canvas pixels are pre-multiplied
+PASS getError was expected value: NO_ERROR : Should be no errors from setup.
+PASS pixel 0, 0 should be within 4 units of 127, 127, 127, 127 was 127, 127, 127, 127
+
 check pixels are pre-multiplied
 PASS getError was expected value: NO_ERROR : Should be no errors from setup
 PASS pixels should all be 0.
@@ -102,6 +117,10 @@ PASS getError was expected value: NO_ERROR : Should be no errors from setup
 PASS getError was expected value: NO_ERROR : Should be no errors
 PASS uploading PNGs with same data but various ICC profiles should generate the same results
 
+check uploading of indexed PNG images
+PASS getError was expected value: NO_ERROR : Should be no errors from setup
+PASS pixel 128, 8 should be within 10 units of 255, 0, 0, 255 was 253, 0, 0, 255
+
 PASS successfullyParsed is true
 
 TEST COMPLETE
diff --git a/LayoutTests/fast/canvas/webgl/gl-teximage.html b/LayoutTests/fast/canvas/webgl/gl-teximage.html
index f163fa0..55715bd 100644
--- a/LayoutTests/fast/canvas/webgl/gl-teximage.html
+++ b/LayoutTests/fast/canvas/webgl/gl-teximage.html
@@ -34,6 +34,7 @@ var imgURLs = [
   'resources/zero-alpha.png',
   'resources/3x3.png',
   'resources/blue-1x1.jpg',
+  'resources/red-indexed.png',
   'resources/green-2x2-16bit.png',
   'resources/small-square-with-colorspin-profile.jpg',
   'resources/small-square-with-colorspin-profile.png',
@@ -43,10 +44,10 @@ var imgURLs = [
   'resources/small-square-with-smpte-c-profile.png',
   'resources/small-square-with-srgb-iec61966-2.1-profile.png'];
 
+
 wtu.loadImagesAsync(imgURLs, runTests);
 
 function runTests(imgs) {
-
   var loc = gl.getUniformLocation(program, "tex");
   gl.uniform1i(loc, 0);
 
@@ -202,44 +203,72 @@ function runTests(imgs) {
 
   debug("");
   debug("check pixels are UN pre-multiplied");
+  for (var ii = 0; ii < 2; ++ii) {
+    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+    if (ii == 0) {
+      var canvas2d = document.createElement("canvas");
+      canvas2d.width = 256;
+      canvas2d.height = 1;
+      var ctx = canvas2d.getContext("2d");
+      ctx.drawImage(imgs['resources/gray-ramp-256-with-128-alpha.png'], 0, 0);
+      gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, canvas2d);
+    } else {
+      gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE,
+                    imgs['resources/gray-ramp-256-with-128-alpha.png']);
+    }
+    glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup.");
+    wtu.drawQuad(gl);
+    var buf = new Uint8Array(width * height * 4);
+    gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buf);
+    var lt128Count = [0, 0, 0];
+    var ge128Count = [0, 0, 0];
+    for (var jj = 0; jj < width; ++jj) {
+      var off = jj * 4;
+      for (var cc = 0; cc < 3; ++cc) {
+        if (buf[off + cc] < 128) {
+          ++lt128Count[cc];
+        } else {
+          ++ge128Count[cc];
+        }
+      }
+    }
+    // Not sure the exact count here because gamma does effect drawing into the
+    // canvas but it should be close to 50% so I'll pass 45%
+    for (var jj = 0; jj < 3; ++jj) {
+      assertMsg(ge128Count[jj] > 256 * 0.45,
+                "Half the pixels in channel " + jj +
+                " should be >= 128,128,128. found " +
+                ((ge128Count[jj] / 256) * 100).toFixed() + "%");
+      assertMsg(lt128Count[jj] > 256 * 0.45,
+                "Half the pixels in channel " + jj +
+                " should be < 128,128,128. found " +
+                ((lt128Count[jj] / 256) * 100).toFixed() + "%");
+    }
+  }
+
+  debug("");
+  debug("check canvas pixels are UN pre-multiplied");
   var canvas2d = document.createElement("canvas");
-  canvas2d.width = 256;
+  canvas2d.width = 1;
   canvas2d.height = 1;
-  //canvas2d.style.height = "40px";
-  //var description = document.getElementById("description");
-  //description.appendChild(canvas2d);
   var ctx = canvas2d.getContext("2d");
+  ctx.fillStyle ="rgba(255,255,255,0.5)";
   ctx.fillRect(0, 0, 256, 1);
-  ctx.drawImage(imgs['resources/gray-ramp-256-with-128-alpha.png'], 0, 0);
-  gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, canvas2d);
+  gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, canvas2d);
+  wtu.drawQuad(gl);
+  gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buf);
   glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup.");
+  checkPixelRange(buf, 0, 0, [255, 255, 255, 127], 4);
+
+  debug("");
+  debug("check canvas pixels are pre-multiplied");
+  gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
+  gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, canvas2d);
   wtu.drawQuad(gl);
-  var ref = new Uint8Array(width * height * 4);
-  gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, ref);
-  var lt128Count = [0, 0, 0];
-  var ge128Count = [0, 0, 0];
-  for (var jj = 0; jj < width; ++jj) {
-    var off = jj * 4;
-    for (var cc = 0; cc < 3; ++cc) {
-      if (buf[off + cc] < 128) {
-        ++lt128Count[cc];
-      } else {
-        ++ge128Count[cc];
-      }
-    }
-  }
-  // Not sure the exact count here because gamma does effect drawing into the
-  // canvas but it should be close to 50% so I'll pass 45%
-  for (var jj = 0; jj < 3; ++jj) {
-    assertMsg(ge128Count[jj] > 256 * 0.45,
-              "Half the pixels in channel " + jj +
-              " should be >= 128,128,128. found " +
-              ((ge128Count[jj] / 256) * 100).toFixed() + "%");
-    assertMsg(lt128Count[jj] > 256 * 0.45,
-              "Half the pixels in channel " + jj +
-              " should be < 128,128,128. found " +
-              ((lt128Count[jj] / 256) * 100).toFixed() + "%");
-  }
+  gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buf);
+  glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup.");
+  checkPixelRange(buf, 0, 0, [127, 127, 127, 127], 4);
+
 
   debug("");
   debug("check pixels are pre-multiplied");
@@ -351,6 +380,16 @@ function runTests(imgs) {
   }
 
   debug("");
+  debug("check uploading of indexed PNG images");
+  gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE,
+                imgs['resources/red-indexed.png']);
+  glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup");
+  wtu.drawQuad(gl);
+  gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buf);
+  // The image should be red.
+  checkPixelRange(buf, middle, center, [ 255, 0, 0, 255 ], 10);
+
+  debug("");
   successfullyParsed = true;
   shouldBeTrue("successfullyParsed");
   debug('<br /><span class="pass">TEST COMPLETE</span>');
diff --git a/LayoutTests/fast/canvas/webgl/resources/red-indexed.png b/LayoutTests/fast/canvas/webgl/resources/red-indexed.png
new file mode 100644
index 0000000..242c3b4
Binary files /dev/null and b/LayoutTests/fast/canvas/webgl/resources/red-indexed.png differ
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 79f5820..592bbc6 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,17 @@
+2011-01-28  Kenneth Russell  <kbr at google.com>
+
+        Reviewed by Chris Marrin.
+
+        WebGL shows PNG Textures with indexed colors too dark
+        https://bugs.webkit.org/show_bug.cgi?id=47477
+
+        Properly handle indexed PNG images by re-rendering them as RGBA
+        images before upload. Verified with this layout test and the test
+        cases from bugs 47477 and 53269.
+
+        * platform/graphics/cg/GraphicsContext3DCG.cpp:
+        (WebCore::GraphicsContext3D::getImageData):
+
 2011-01-27  MORITA Hajime  <morrita at google.com>
 
         Reviewed by Dimitri Glazkov.
diff --git a/Source/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp b/Source/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp
index 4b42c92..52f262f 100644
--- a/Source/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp
+++ b/Source/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp
@@ -116,6 +116,35 @@ bool GraphicsContext3D::getImageData(Image* image,
     size_t height = CGImageGetHeight(cgImage);
     if (!width || !height)
         return false;
+
+    // See whether the image is using an indexed color space, and if
+    // so, re-render it into an RGB color space. The image re-packing
+    // code requires color data, not color table indices, for the
+    // image data.
+    RetainPtr<CGColorSpaceRef> colorSpace(AdoptCF, CGImageGetColorSpace(cgImage));
+    CGColorSpaceModel model = CGColorSpaceGetModel(colorSpace.get());
+    RetainPtr<CGContextRef> bitmapContext;
+    if (model == kCGColorSpaceModelIndexed) {
+        RetainPtr<CGColorSpaceRef> baseColorSpace(CGColorSpaceGetBaseColorSpace(colorSpace.get()));
+        // FIXME: we should probably manually convert the image by indexing into
+        // the color table, which would allow us to avoid premultiplying the
+        // alpha channel. Creation of a bitmap context with an alpha channel
+        // doesn't seem to work unless it's premultiplied.
+        bitmapContext.adoptCF(CGBitmapContextCreate(0, width, height, 8, width * 4,
+                                                    deviceRGBColorSpaceRef(),
+                                                    kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host));
+        if (!bitmapContext)
+            return false;
+
+        CGContextSetBlendMode(bitmapContext.get(), kCGBlendModeCopy);
+        CGContextSetInterpolationQuality(bitmapContext.get(), kCGInterpolationNone);
+        CGContextDrawImage(bitmapContext.get(), CGRectMake(0, 0, width, height), cgImage);
+
+        // Now discard the original CG image and replace it with a copy from the bitmap context.
+        decodedImage.adoptCF(CGBitmapContextCreateImage(bitmapContext.get()));
+        cgImage = decodedImage.get();
+    }
+
     size_t bitsPerComponent = CGImageGetBitsPerComponent(cgImage);
     size_t bitsPerPixel = CGImageGetBitsPerPixel(cgImage);
     if (bitsPerComponent != 8 && bitsPerComponent != 16)
@@ -168,10 +197,11 @@ bool GraphicsContext3D::getImageData(Image* image,
     AlphaFormat alphaFormat = AlphaFormatNone;
     switch (CGImageGetAlphaInfo(cgImage)) {
     case kCGImageAlphaPremultipliedFirst:
-        // This path is only accessible for MacOS earlier than 10.6.4.
         // This is a special case for texImage2D with HTMLCanvasElement input,
-        // in which case image->data() should be null.
-        ASSERT(!image->data());
+        // in which case image->data() should be null, or indexed color models,
+        // where we need premultiplied alpha to create the bitmap context
+        // successfully.
+        ASSERT(!image->data() || model == kCGColorSpaceModelIndexed);
         if (!premultiplyAlpha)
             neededAlphaOp = AlphaDoUnmultiply;
         alphaFormat = AlphaFormatFirst;

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list