[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc
zmo at google.com
zmo at google.com
Wed Dec 22 12:35:48 UTC 2010
The following commit has been merged in the debian/experimental branch:
commit cf7ab46108d3461485715a01c660cd0f7209c4a0
Author: zmo at google.com <zmo at google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Wed Aug 25 20:28:59 2010 +0000
2010-08-24 Zhenyao Mo <zmo at google.com>
Reviewed by Kenneth Russell.
Passing premultiplyAlpha=false to tex{Sub}Image2D loses information (skia)
https://bugs.webkit.org/show_bug.cgi?id=38282
* src/WebImageDecoder.cpp:
(WebKit::WebImageDecoder::init): Add premultiplyAlpha flag.
2010-08-24 Zhenyao Mo <zmo at google.com>
Reviewed by Kenneth Russell.
Passing premultiplyAlpha=false to tex{Sub}Image2D loses information (skia)
https://bugs.webkit.org/show_bug.cgi?id=38282
Test: fast/canvas/webgl/gl-teximage.html
* platform/graphics/GraphicsContext3D.cpp: Fix a bug where alpha channel is ignored.
* platform/graphics/ImageSource.cpp: Add premultiplyAlpha flag.
(WebCore::ImageSource::ImageSource):
(WebCore::ImageSource::setData):
* platform/graphics/ImageSource.h: Ditto.
* platform/graphics/cg/ImageSourceCG.cpp: Ditto.
(WebCore::ImageSource::ImageSource):
* platform/graphics/qt/ImageDecoderQt.cpp: Ditto.
(WebCore::ImageDecoder::create):
(WebCore::ImageDecoderQt::ImageDecoderQt):
(WebCore::ImageDecoderQt::frameCount):
(WebCore::ImageDecoderQt::forceLoadEverything):
* platform/graphics/qt/ImageDecoderQt.h: Ditto.
* platform/graphics/skia/GraphicsContext3DSkia.cpp: Fix the premultiplyAlpha data loss issue in skia.
(WebCore::GraphicsContext3D::getImageData):
* platform/image-decoders/ImageDecoder.cpp: Add premultiplyAlpha flag.
(WebCore::ImageDecoder::create):
(WebCore::RGBA32Buffer::RGBA32Buffer):
(WebCore::RGBA32Buffer::operator=):
* platform/image-decoders/ImageDecoder.h: Ditto.
(WebCore::RGBA32Buffer::premultiplyAlpha):
(WebCore::RGBA32Buffer::setPremultiplyAlpha):
(WebCore::RGBA32Buffer::setRGBA):
(WebCore::ImageDecoder::ImageDecoder):
* platform/image-decoders/bmp/BMPImageDecoder.cpp: Ditto.
(WebCore::BMPImageDecoder::BMPImageDecoder):
(WebCore::BMPImageDecoder::frameBufferAtIndex):
* platform/image-decoders/bmp/BMPImageDecoder.h: Ditto.
* platform/image-decoders/gif/GIFImageDecoder.cpp: Ditto.
(WebCore::GIFImageDecoder::GIFImageDecoder):
(WebCore::GIFImageDecoder::frameCount):
* platform/image-decoders/gif/GIFImageDecoder.h: Ditto.
* platform/image-decoders/ico/ICOImageDecoder.cpp: Ditto.
(WebCore::ICOImageDecoder::ICOImageDecoder):
(WebCore::ICOImageDecoder::frameCount):
(WebCore::ICOImageDecoder::decodeAtIndex):
* platform/image-decoders/ico/ICOImageDecoder.h: Ditto.
* platform/image-decoders/jpeg/JPEGImageDecoder.cpp: Ditto.
(WebCore::JPEGImageDecoder::JPEGImageDecoder):
(WebCore::JPEGImageDecoder::frameBufferAtIndex):
* platform/image-decoders/jpeg/JPEGImageDecoder.h: Ditto.
* platform/image-decoders/png/PNGImageDecoder.cpp: Ditto.
(WebCore::PNGImageDecoder::PNGImageDecoder):
(WebCore::PNGImageDecoder::frameBufferAtIndex):
* platform/image-decoders/png/PNGImageDecoder.h: Ditto.
* platform/image-decoders/skia/ImageDecoderSkia.cpp: Ditto.
(WebCore::RGBA32Buffer::RGBA32Buffer):
(WebCore::RGBA32Buffer::operator=):
2010-08-24 Zhenyao Mo <zmo at google.com>
Reviewed by Kenneth Russell.
Passing premultiplyAlpha=false to tex{Sub}Image2D loses information (skia)
https://bugs.webkit.org/show_bug.cgi?id=38282
* fast/canvas/webgl/gl-teximage-expected.txt: Added.
* fast/canvas/webgl/gl-teximage.html: Added.
* fast/canvas/webgl/resources/3x3.png: Added.
* fast/canvas/webgl/resources/gray-ramp-256-with-128-alpha.png: Added.
* fast/canvas/webgl/resources/gray-ramp-256.png: Added.
* fast/canvas/webgl/resources/gray-ramp-default-gamma.png: Added.
* fast/canvas/webgl/resources/gray-ramp-gamma0.1.png: Added.
* fast/canvas/webgl/resources/gray-ramp-gamma1.0.png: Added.
* fast/canvas/webgl/resources/gray-ramp-gamma2.0.png: Added.
* fast/canvas/webgl/resources/gray-ramp-gamma4.0.png: Added.
* fast/canvas/webgl/resources/gray-ramp-gamma9.0.png: Added.
* fast/canvas/webgl/resources/gray-ramp.png: Added.
* fast/canvas/webgl/resources/webgl-test-utils.js: Sync with khronos.
(WebGLTestUtils):
* fast/canvas/webgl/resources/zero-alpha.png: Added.
* platform/chromium/test_expectations.txt: Don't run gl-teximage.html for mac.
* platform/mac/Skipped: Don't run gl-teximage.html for mac.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@66039 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index c565a4f..2aeb1ce 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,28 @@
+2010-08-24 Zhenyao Mo <zmo at google.com>
+
+ Reviewed by Kenneth Russell.
+
+ Passing premultiplyAlpha=false to tex{Sub}Image2D loses information (skia)
+ https://bugs.webkit.org/show_bug.cgi?id=38282
+
+ * fast/canvas/webgl/gl-teximage-expected.txt: Added.
+ * fast/canvas/webgl/gl-teximage.html: Added.
+ * fast/canvas/webgl/resources/3x3.png: Added.
+ * fast/canvas/webgl/resources/gray-ramp-256-with-128-alpha.png: Added.
+ * fast/canvas/webgl/resources/gray-ramp-256.png: Added.
+ * fast/canvas/webgl/resources/gray-ramp-default-gamma.png: Added.
+ * fast/canvas/webgl/resources/gray-ramp-gamma0.1.png: Added.
+ * fast/canvas/webgl/resources/gray-ramp-gamma1.0.png: Added.
+ * fast/canvas/webgl/resources/gray-ramp-gamma2.0.png: Added.
+ * fast/canvas/webgl/resources/gray-ramp-gamma4.0.png: Added.
+ * fast/canvas/webgl/resources/gray-ramp-gamma9.0.png: Added.
+ * fast/canvas/webgl/resources/gray-ramp.png: Added.
+ * fast/canvas/webgl/resources/webgl-test-utils.js: Sync with khronos.
+ (WebGLTestUtils):
+ * fast/canvas/webgl/resources/zero-alpha.png: Added.
+ * platform/chromium/test_expectations.txt: Don't run gl-teximage.html for mac.
+ * platform/mac/Skipped: Don't run gl-teximage.html for mac.
+
2010-08-25 Andreas Kling <andreas.kling at nokia.com>
Reviewed by Ariya Hidayat.
diff --git a/LayoutTests/fast/canvas/webgl/gl-teximage-expected.txt b/LayoutTests/fast/canvas/webgl/gl-teximage-expected.txt
new file mode 100644
index 0000000..727b9ee
--- /dev/null
+++ b/LayoutTests/fast/canvas/webgl/gl-teximage-expected.txt
@@ -0,0 +1,61 @@
+Test texImage2D conversions.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+PASS getError was expected value: NO_ERROR : Should be no errors from setup.
+
+check pixels are NOT pre-multiplied
+PASS getError was expected value: NO_ERROR : Should be no errors from setup
+PASS pixel 0, 15 should be 0, 0, 0, 255 was 0, 0, 0, 255
+PASS pixel 128, 15 should be 255, 0, 255, 255 was 255, 0, 0, 255
+PASS pixel 255, 15 should be 0, 0, 255, 255 was 0, 0, 255, 255
+PASS pixel 0, 8 should be 128, 128, 128, 255 was 128, 128, 128, 255
+PASS pixel 128, 8 should be 255, 255, 255, 255 was 255, 255, 255, 255
+PASS pixel 255, 8 should be 0, 255, 255, 255 was 0, 255, 255, 255
+PASS pixel 0, 0 should be 255, 0, 0, 255 was 255, 0, 0, 255
+PASS pixel 128, 0 should be 255, 255, 0, 255 was 255, 255, 0, 255
+PASS pixel 255, 0 should be 0, 255, 0, 255 was 0, 255, 0, 255
+
+check quantization
+PASS getError was expected value: NO_ERROR : Should be no errors from setup.
+PASS There should be 256 unique values in channel 0. Found 256
+PASS There should be 256 unique values in channel 1. Found 256
+PASS There should be 256 unique values in channel 2. Found 256
+PASS There should be 256 unique values in channel 3. Found 256
+PASS getError was expected value: NO_ERROR : Should be no errors from setup.
+PASS There should be 16 unique values in channel 0. Found 16
+PASS There should be 16 unique values in channel 1. Found 16
+PASS There should be 16 unique values in channel 2. Found 16
+PASS There should be 16 unique values in channel 3. Found 16
+PASS getError was expected value: NO_ERROR : Should be no errors from setup.
+PASS There should be 32 unique values in channel 0. Found 32
+PASS There should be 64 unique values in channel 1. Found 64
+PASS There should be 32 unique values in channel 2. Found 32
+PASS There should be 1 unique values in channel 3. Found 1
+PASS getError was expected value: NO_ERROR : Should be no errors from setup.
+PASS There should be 32 unique values in channel 0. Found 32
+PASS There should be 32 unique values in channel 1. Found 32
+PASS There should be 32 unique values in channel 2. Found 32
+PASS There should be 2 unique values in channel 3. Found 2
+
+check pixels are pre-multiplied
+PASS getError was expected value: NO_ERROR : Should be no errors from setup
+PASS pixels should all be 0.
+
+check pixels are flipped
+PASS getError was expected value: NO_ERROR : Should be no errors from setup
+PASS pixel 0, 15 should be 255, 0, 0, 255 was 255, 0, 0, 255
+PASS pixel 128, 15 should be 255, 255, 0, 255 was 255, 255, 0, 255
+PASS pixel 255, 15 should be 255, 0, 0, 255 was 255, 0, 0, 255
+PASS pixel 0, 8 should be 255, 0, 255, 255 was 255, 0, 255, 255
+PASS pixel 128, 8 should be 255, 0, 0, 255 was 255, 0, 0, 255
+PASS pixel 255, 8 should be 0, 255, 0, 255 was 0, 255, 0, 255
+PASS pixel 0, 0 should be 0, 0, 0, 255 was 0, 0, 0, 255
+PASS pixel 128, 0 should be 0, 0, 255, 255 was 0, 0, 255, 255
+PASS pixel 255, 0 should be 255, 0, 0, 255 was 255, 0, 0, 255
+PASS getError was expected value: NO_ERROR : Should be no errors
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/canvas/webgl/gl-teximage.html b/LayoutTests/fast/canvas/webgl/gl-teximage.html
new file mode 100644
index 0000000..016a5f6
--- /dev/null
+++ b/LayoutTests/fast/canvas/webgl/gl-teximage.html
@@ -0,0 +1,266 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<title>WebGL texImage2D conformance test.</title>
+<link rel="stylesheet" href="../../js/resources/js-test-style.css"/>
+<script src="../../js/resources/js-test-pre.js"></script>
+<script src="resources/webgl-test.js"> </script>
+<script src="resources/webgl-test-utils.js"> </script>
+</head>
+<body>
+<canvas id="example" width="256" height="16" style="width: 256px; height: 48px;"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+description("Test texImage2D conversions.");
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("example");
+var gl = wtu.create3DContext(canvas);
+var program = wtu.setupTexturedQuad(gl);
+
+glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup.");
+
+var imgURLs = [
+ 'resources/gray-ramp-256-with-128-alpha.png',
+ 'resources/gray-ramp-256.png',
+ 'resources/gray-ramp-default-gamma.png',
+ 'resources/gray-ramp-gamma0.1.png',
+ 'resources/gray-ramp-gamma1.0.png',
+ 'resources/gray-ramp-gamma2.0.png',
+ 'resources/gray-ramp-gamma4.0.png',
+ 'resources/gray-ramp-gamma9.0.png',
+ 'resources/gray-ramp.png',
+ 'resources/zero-alpha.png',
+ 'resources/3x3.png'];
+
+wtu.loadImagesAsync(imgURLs, runTests);
+
+function runTests(imgs) {
+
+ var loc = gl.getUniformLocation(program, "tex");
+ gl.uniform1i(loc, 0);
+
+ gl.disable(gl.BLEND);
+ gl.disable(gl.DEPTH_TEST);
+
+ var width = canvas.width;
+ var height = canvas.height;
+
+ function checkPixel(buf, x, y, color) {
+ var off = (y * width + x) * 4;
+ var msg = "pixel " + x + ", " + y + " should be " +
+ color[0] + ", " +
+ color[1] + ", " +
+ color[2] + ", " +
+ color[3] + " was " +
+ buf[off + 0] + ", " +
+ buf[off + 1] + ", " +
+ buf[off + 2] + ", " +
+ buf[off + 3];
+
+ for (var ii = 0; ii < 4; ++ii) {
+ if (buf[off + ii] != color[ii]) {
+ testFailed(msg);
+ return;
+ }
+ }
+ testPassed(msg);
+ }
+
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ 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);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+
+ var buf = new Uint8Array(width * height * 4);
+
+ debug("");
+ debug("check pixels are NOT pre-multiplied");
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE,
+ imgs['resources/zero-alpha.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);
+
+ var left = 0;
+ var middle = Math.floor(width / 2);
+ var right = width - 1;
+ var bottom = 0;
+ var center = Math.floor(height / 2);
+ var top = height - 1;
+ checkPixel(buf, left, top, [ 0, 0, 0, 255]);
+ checkPixel(buf, middle, top, [255, 0, 255, 255]);
+ checkPixel(buf, right, top, [ 0, 0, 255, 255]);
+ checkPixel(buf, left, center, [128, 128, 128, 255]);
+ checkPixel(buf, middle, center, [255, 255, 255, 255]);
+ checkPixel(buf, right, center, [ 0, 255, 255, 255]);
+ checkPixel(buf, left, bottom, [255, 0, 0, 255]);
+ checkPixel(buf, middle, bottom, [255, 255, 0, 255]);
+ checkPixel(buf, right, bottom, [ 0, 255, 0, 255]);
+
+ debug("");
+ debug("check quantization");
+ var quantInfo = [
+ {format: gl.RGBA, type: gl.UNSIGNED_BYTE, counts: [256, 256, 256, 256]},
+ {format: gl.RGBA, type: gl.UNSIGNED_SHORT_4_4_4_4, counts: [ 16, 16, 16, 16]},
+ {format: gl.RGB, type: gl.UNSIGNED_SHORT_5_6_5, counts: [ 32, 64, 32, 1]},
+ {format: gl.RGBA, type: gl.UNSIGNED_SHORT_5_5_5_1, counts: [ 32, 32, 32, 2]}];
+ for (var qq = 0; qq < quantInfo.length; ++qq) {
+ var info = quantInfo[qq];
+ gl.texImage2D(
+ gl.TEXTURE_2D, 0, info.format, info.format, info.type,
+ imgs['resources/gray-ramp-256.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);
+ var counts = [{ }, { }, { }, { }];
+ var numUniqueValues = [0, 0, 0, 0];
+ // Count the number of unique values in each channel.
+ for (var ii = 0; ii < width * height * 4; ii += 4) {
+ for (var jj = 0; jj < 4; ++jj) {
+ var v = buf[ii + jj];
+ if (!counts[jj][v]) {
+ counts[jj][v] = 1;
+ ++numUniqueValues[jj];
+ } else {
+ ++counts[jj][v];
+ }
+ }
+ }
+ for (var ii = 0; ii < 4; ++ii) {
+ assertMsg(numUniqueValues[ii] == info.counts[ii],
+ "There should be " + info.counts[ii] +
+ " unique values in channel " + ii + ". Found " +
+ numUniqueValues[ii]);
+ }
+ }
+
+// FIXME(zmo): fix the gamma correction and add back the commented out tests below.
+/*
+ debug("");
+ debug("Check that gamma settings don't effect 8bit pngs");
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE,
+ imgs['resources/gray-ramp-default-gamma.png']);
+ glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup.");
+ wtu.drawQuad(gl);
+ var ref = new Uint8Array(width * height * 4);
+ gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, ref);
+
+ var gammaImages = [
+ 'resources/gray-ramp-gamma0.1.png',
+ 'resources/gray-ramp-gamma1.0.png',
+ 'resources/gray-ramp-gamma2.0.png',
+ 'resources/gray-ramp-gamma4.0.png',
+ 'resources/gray-ramp-gamma9.0.png'];
+ for (var ii = 0; ii < gammaImages.length; ++ii) {
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE,
+ imgs[gammaImages[ii]]);
+ wtu.drawQuad(gl);
+ gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buf);
+ var same = true;
+ for (var jj = 0; jj < width * height * 4; ++jj) {
+ if (buf[jj] != ref[jj]) {
+ same = false;
+ break;
+ }
+ }
+ assertMsg(same, "pixels should be same regardless of gamma settings.");
+ }
+
+ debug("");
+ debug("check pixels are UN pre-multiplied");
+ var canvas2d = document.createElement("canvas");
+ canvas2d.width = 256;
+ canvas2d.height = 1;
+ //canvas2d.style.height = "40px";
+ //var description = document.getElementById("description");
+ //description.appendChild(canvas2d);
+ var ctx = canvas2d.getContext("2d");
+ 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);
+ glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup.");
+ 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() + "%");
+ }
+*/
+
+ debug("");
+ debug("check pixels are pre-multiplied");
+ gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
+ // TODO(gman): use different texture that won't pass on failure
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE,
+ imgs['resources/zero-alpha.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);
+
+ var same = true;
+ for (var jj = 0; jj < width * height * 4; ++jj) {
+ if (buf[jj] != 0) {
+ same = false;
+ break;
+ }
+ }
+ assertMsg(same, "pixels should all be 0.");
+
+ debug("");
+ debug("check pixels are flipped");
+ gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE,
+ imgs['resources/3x3.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);
+
+ checkPixel(buf, left, top, [255, 0, 0, 255]);
+ checkPixel(buf, middle, top, [255, 255, 0, 255]);
+ checkPixel(buf, right, top, [255, 0, 0, 255]);
+ checkPixel(buf, left, center, [255, 0, 255, 255]);
+ checkPixel(buf, middle, center, [255, 0, 0, 255]);
+ checkPixel(buf, right, center, [ 0, 255, 0, 255]);
+ checkPixel(buf, left, bottom, [ 0, 0, 0, 255]);
+ checkPixel(buf, middle, bottom, [ 0, 0, 255, 255]);
+ checkPixel(buf, right, bottom, [255, 0, 0, 255]);
+
+ glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors");
+
+ debug("");
+ successfullyParsed = true;
+ shouldBeTrue("successfullyParsed");
+ debug('<br /><span class="pass">TEST COMPLETE</span>');
+ if (window.layoutTestController)
+ layoutTestController.notifyDone();
+}
+</script>
+</body>
+</html>
+
diff --git a/LayoutTests/fast/canvas/webgl/resources/3x3.png b/LayoutTests/fast/canvas/webgl/resources/3x3.png
new file mode 100644
index 0000000..6cf1e74
Binary files /dev/null and b/LayoutTests/fast/canvas/webgl/resources/3x3.png differ
diff --git a/LayoutTests/fast/canvas/webgl/resources/gray-ramp-256-with-128-alpha.png b/LayoutTests/fast/canvas/webgl/resources/gray-ramp-256-with-128-alpha.png
new file mode 100644
index 0000000..183e55d
Binary files /dev/null and b/LayoutTests/fast/canvas/webgl/resources/gray-ramp-256-with-128-alpha.png differ
diff --git a/LayoutTests/fast/canvas/webgl/resources/gray-ramp-256.png b/LayoutTests/fast/canvas/webgl/resources/gray-ramp-256.png
new file mode 100644
index 0000000..01e486b
Binary files /dev/null and b/LayoutTests/fast/canvas/webgl/resources/gray-ramp-256.png differ
diff --git a/LayoutTests/fast/canvas/webgl/resources/gray-ramp-default-gamma.png b/LayoutTests/fast/canvas/webgl/resources/gray-ramp-default-gamma.png
new file mode 100755
index 0000000..a5a89be
Binary files /dev/null and b/LayoutTests/fast/canvas/webgl/resources/gray-ramp-default-gamma.png differ
diff --git a/LayoutTests/fast/canvas/webgl/resources/gray-ramp-gamma0.1.png b/LayoutTests/fast/canvas/webgl/resources/gray-ramp-gamma0.1.png
new file mode 100755
index 0000000..637c792
Binary files /dev/null and b/LayoutTests/fast/canvas/webgl/resources/gray-ramp-gamma0.1.png differ
diff --git a/LayoutTests/fast/canvas/webgl/resources/gray-ramp-gamma1.0.png b/LayoutTests/fast/canvas/webgl/resources/gray-ramp-gamma1.0.png
new file mode 100755
index 0000000..40ceeb0
Binary files /dev/null and b/LayoutTests/fast/canvas/webgl/resources/gray-ramp-gamma1.0.png differ
diff --git a/LayoutTests/fast/canvas/webgl/resources/gray-ramp-gamma2.0.png b/LayoutTests/fast/canvas/webgl/resources/gray-ramp-gamma2.0.png
new file mode 100755
index 0000000..73fcf7b
Binary files /dev/null and b/LayoutTests/fast/canvas/webgl/resources/gray-ramp-gamma2.0.png differ
diff --git a/LayoutTests/fast/canvas/webgl/resources/gray-ramp-gamma4.0.png b/LayoutTests/fast/canvas/webgl/resources/gray-ramp-gamma4.0.png
new file mode 100755
index 0000000..d878f1e
Binary files /dev/null and b/LayoutTests/fast/canvas/webgl/resources/gray-ramp-gamma4.0.png differ
diff --git a/LayoutTests/fast/canvas/webgl/resources/gray-ramp-gamma9.0.png b/LayoutTests/fast/canvas/webgl/resources/gray-ramp-gamma9.0.png
new file mode 100755
index 0000000..8a69ed1
Binary files /dev/null and b/LayoutTests/fast/canvas/webgl/resources/gray-ramp-gamma9.0.png differ
diff --git a/LayoutTests/fast/canvas/webgl/resources/gray-ramp.png b/LayoutTests/fast/canvas/webgl/resources/gray-ramp.png
new file mode 100755
index 0000000..a5a89be
Binary files /dev/null and b/LayoutTests/fast/canvas/webgl/resources/gray-ramp.png differ
diff --git a/LayoutTests/fast/canvas/webgl/resources/webgl-test-utils.js b/LayoutTests/fast/canvas/webgl/resources/webgl-test-utils.js
index 455b63b..bcb9647 100644
--- a/LayoutTests/fast/canvas/webgl/resources/webgl-test-utils.js
+++ b/LayoutTests/fast/canvas/webgl/resources/webgl-test-utils.js
@@ -29,6 +29,20 @@ var error = function(msg) {
}
};
+/**
+ * Converts a WebGL enum to a string
+ * @param {!WebGLContext} gl The WebGLContext to use.
+ * @param {number} value The enum value.
+ * @return {string} The enum as a string.
+ */
+var glEnumToString = function(gl, value) {
+ for (var p in gl) {
+ if (gl[p] == value) {
+ return p;
+ }
+ }
+ return "0x" + value.toString(16);
+};
var lastError = "";
@@ -110,19 +124,21 @@ var setupSimpleTextureFragmentShader = function(gl) {
* Creates a program, attaches shaders, binds attrib locations, links the
* program and calls useProgram.
* @param {!Array.<!WebGLShader>} shaders The shaders to attach .
- * @param {!Array.<string>} attribs The attribs names.
+ * @param {!Array.<string>} opt_attribs The attribs names.
* @param {!Array.<number>} opt_locations The locations for the attribs.
*/
-var setupProgram = function(gl, shaders, attribs, opt_locations) {
+var setupProgram = function(gl, shaders, opt_attribs, opt_locations) {
var program = gl.createProgram();
for (var ii = 0; ii < shaders.length; ++ii) {
gl.attachShader(program, shaders[ii]);
}
- for (var ii = 0; ii < attribs.length; ++ii) {
- gl.bindAttribLocation(
- program,
- opt_locations ? opt_locations[ii] : ii,
- attribs[ii]);
+ if (opt_attribs) {
+ for (var ii = 0; ii < opt_attribs.length; ++ii) {
+ gl.bindAttribLocation(
+ program,
+ opt_locations ? opt_locations[ii] : ii,
+ opt_attribs[ii]);
+ }
}
gl.linkProgram(program);
@@ -813,6 +829,7 @@ return {
drawQuad: drawQuad,
endsWith: endsWith,
getLastError: getLastError,
+ glEnumToString: glEnumToString,
glErrorShouldBe: glErrorShouldBe,
fillTexture: fillTexture,
loadImageAsync: loadImageAsync,
diff --git a/LayoutTests/fast/canvas/webgl/resources/zero-alpha.png b/LayoutTests/fast/canvas/webgl/resources/zero-alpha.png
new file mode 100755
index 0000000..e55630c
Binary files /dev/null and b/LayoutTests/fast/canvas/webgl/resources/zero-alpha.png differ
diff --git a/LayoutTests/platform/chromium/test_expectations.txt b/LayoutTests/platform/chromium/test_expectations.txt
index fb3ffde..0bcd58d 100644
--- a/LayoutTests/platform/chromium/test_expectations.txt
+++ b/LayoutTests/platform/chromium/test_expectations.txt
@@ -2565,6 +2565,9 @@ BUGWK37297 : fast/history/sibling-visited-test.html = TEXT
BUGWK36983 MAC : fast/canvas/webgl/null-object-behaviour.html = TEXT
BUGWK36983 MAC : fast/canvas/webgl/uniform-location.html = TEXT
+// Caused by premultiplying alphas in CG image decoding.
+BUG44566 MAC : fast/canvas/webgl/gl-teximage.html = TEXT
+
// Added in http://trac.webkit.org/changeset/57476. Fails in Chromium because
// LayoutTestController::computedStyleWithVisitedInfo() is missing.
BUG41206 : fast/history/multiple-classes-visited.html = TEXT TIMEOUT
diff --git a/LayoutTests/platform/mac/Skipped b/LayoutTests/platform/mac/Skipped
index 05261aa..4fa474a 100644
--- a/LayoutTests/platform/mac/Skipped
+++ b/LayoutTests/platform/mac/Skipped
@@ -292,3 +292,6 @@ animations/play-state.html
# https://bugs.webkit.org/show_bug.cgi?id=43332
inspector/dom-breakpoints.html
+
+# https://bugs.webkit.org/show_bug.cgi?id=44566
+fast/canvas/webgl/gl-teximage.html
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 6cdde62..aac132e 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,61 @@
+2010-08-24 Zhenyao Mo <zmo at google.com>
+
+ Reviewed by Kenneth Russell.
+
+ Passing premultiplyAlpha=false to tex{Sub}Image2D loses information (skia)
+ https://bugs.webkit.org/show_bug.cgi?id=38282
+
+ Test: fast/canvas/webgl/gl-teximage.html
+
+ * platform/graphics/GraphicsContext3D.cpp: Fix a bug where alpha channel is ignored.
+ * platform/graphics/ImageSource.cpp: Add premultiplyAlpha flag.
+ (WebCore::ImageSource::ImageSource):
+ (WebCore::ImageSource::setData):
+ * platform/graphics/ImageSource.h: Ditto.
+ * platform/graphics/cg/ImageSourceCG.cpp: Ditto.
+ (WebCore::ImageSource::ImageSource):
+ * platform/graphics/qt/ImageDecoderQt.cpp: Ditto.
+ (WebCore::ImageDecoder::create):
+ (WebCore::ImageDecoderQt::ImageDecoderQt):
+ (WebCore::ImageDecoderQt::frameCount):
+ (WebCore::ImageDecoderQt::forceLoadEverything):
+ * platform/graphics/qt/ImageDecoderQt.h: Ditto.
+ * platform/graphics/skia/GraphicsContext3DSkia.cpp: Fix the premultiplyAlpha data loss issue in skia.
+ (WebCore::GraphicsContext3D::getImageData):
+ * platform/image-decoders/ImageDecoder.cpp: Add premultiplyAlpha flag.
+ (WebCore::ImageDecoder::create):
+ (WebCore::RGBA32Buffer::RGBA32Buffer):
+ (WebCore::RGBA32Buffer::operator=):
+ * platform/image-decoders/ImageDecoder.h: Ditto.
+ (WebCore::RGBA32Buffer::premultiplyAlpha):
+ (WebCore::RGBA32Buffer::setPremultiplyAlpha):
+ (WebCore::RGBA32Buffer::setRGBA):
+ (WebCore::ImageDecoder::ImageDecoder):
+ * platform/image-decoders/bmp/BMPImageDecoder.cpp: Ditto.
+ (WebCore::BMPImageDecoder::BMPImageDecoder):
+ (WebCore::BMPImageDecoder::frameBufferAtIndex):
+ * platform/image-decoders/bmp/BMPImageDecoder.h: Ditto.
+ * platform/image-decoders/gif/GIFImageDecoder.cpp: Ditto.
+ (WebCore::GIFImageDecoder::GIFImageDecoder):
+ (WebCore::GIFImageDecoder::frameCount):
+ * platform/image-decoders/gif/GIFImageDecoder.h: Ditto.
+ * platform/image-decoders/ico/ICOImageDecoder.cpp: Ditto.
+ (WebCore::ICOImageDecoder::ICOImageDecoder):
+ (WebCore::ICOImageDecoder::frameCount):
+ (WebCore::ICOImageDecoder::decodeAtIndex):
+ * platform/image-decoders/ico/ICOImageDecoder.h: Ditto.
+ * platform/image-decoders/jpeg/JPEGImageDecoder.cpp: Ditto.
+ (WebCore::JPEGImageDecoder::JPEGImageDecoder):
+ (WebCore::JPEGImageDecoder::frameBufferAtIndex):
+ * platform/image-decoders/jpeg/JPEGImageDecoder.h: Ditto.
+ * platform/image-decoders/png/PNGImageDecoder.cpp: Ditto.
+ (WebCore::PNGImageDecoder::PNGImageDecoder):
+ (WebCore::PNGImageDecoder::frameBufferAtIndex):
+ * platform/image-decoders/png/PNGImageDecoder.h: Ditto.
+ * platform/image-decoders/skia/ImageDecoderSkia.cpp: Ditto.
+ (WebCore::RGBA32Buffer::RGBA32Buffer):
+ (WebCore::RGBA32Buffer::operator=):
+
2010-08-25 Adam Barth <abarth at webkit.org>
Reviewed by Eric Seidel.
diff --git a/WebCore/platform/graphics/GraphicsContext3D.cpp b/WebCore/platform/graphics/GraphicsContext3D.cpp
index 377be1c..170bb84 100644
--- a/WebCore/platform/graphics/GraphicsContext3D.cpp
+++ b/WebCore/platform/graphics/GraphicsContext3D.cpp
@@ -424,6 +424,7 @@ void packRGBA8ToRGBA8Premultiply(const uint8_t* source, uint8_t* destination)
destination[0] = sourceR;
destination[1] = sourceG;
destination[2] = sourceB;
+ destination[3] = source[3];
}
// FIXME: this routine is lossy and must be removed.
diff --git a/WebCore/platform/graphics/ImageSource.cpp b/WebCore/platform/graphics/ImageSource.cpp
index 7f6d323..c6d97fe 100644
--- a/WebCore/platform/graphics/ImageSource.cpp
+++ b/WebCore/platform/graphics/ImageSource.cpp
@@ -41,8 +41,9 @@ namespace WebCore {
unsigned ImageSource::s_maxPixelsPerDecodedImage = 1024 * 1024;
#endif
-ImageSource::ImageSource()
+ImageSource::ImageSource(bool premultiplyAlpha)
: m_decoder(0)
+ , m_premultiplyAlpha(premultiplyAlpha)
{
}
@@ -77,7 +78,7 @@ void ImageSource::setData(SharedBuffer* data, bool allDataReceived)
// If insufficient bytes are available to determine the image type, no decoder plugin will be
// made.
if (!m_decoder) {
- m_decoder = static_cast<NativeImageSourcePtr>(ImageDecoder::create(*data));
+ m_decoder = static_cast<NativeImageSourcePtr>(ImageDecoder::create(*data, m_premultiplyAlpha));
#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
if (m_decoder && s_maxPixelsPerDecodedImage)
m_decoder->setMaxNumPixels(s_maxPixelsPerDecodedImage);
diff --git a/WebCore/platform/graphics/ImageSource.h b/WebCore/platform/graphics/ImageSource.h
index b7efb99..19952b1 100644
--- a/WebCore/platform/graphics/ImageSource.h
+++ b/WebCore/platform/graphics/ImageSource.h
@@ -114,7 +114,7 @@ const int cAnimationNone = -2;
class ImageSource : public Noncopyable {
public:
- ImageSource();
+ ImageSource(bool premultiplyAlpha = true);
~ImageSource();
// Tells the ImageSource that the Image no longer cares about decoded frame
@@ -172,6 +172,7 @@ public:
private:
NativeImageSourcePtr m_decoder;
+ bool m_premultiplyAlpha;
#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
static unsigned s_maxPixelsPerDecodedImage;
#endif
diff --git a/WebCore/platform/graphics/cg/ImageSourceCG.cpp b/WebCore/platform/graphics/cg/ImageSourceCG.cpp
index 4a7aecc..5fa4896 100644
--- a/WebCore/platform/graphics/cg/ImageSourceCG.cpp
+++ b/WebCore/platform/graphics/cg/ImageSourceCG.cpp
@@ -63,8 +63,10 @@ void sharedBufferRelease(void* info)
}
#endif
-ImageSource::ImageSource()
+ImageSource::ImageSource(bool premultiplyAlpha)
: m_decoder(0)
+ // FIXME: m_premultiplyAlpha is ignored in cg at the moment.
+ , m_premultiplyAlpha(premultiplyAlpha)
{
}
diff --git a/WebCore/platform/graphics/qt/ImageDecoderQt.cpp b/WebCore/platform/graphics/qt/ImageDecoderQt.cpp
index 858cc44..02bb110 100644
--- a/WebCore/platform/graphics/qt/ImageDecoderQt.cpp
+++ b/WebCore/platform/graphics/qt/ImageDecoderQt.cpp
@@ -37,17 +37,18 @@
namespace WebCore {
-ImageDecoder* ImageDecoder::create(const SharedBuffer& data)
+ImageDecoder* ImageDecoder::create(const SharedBuffer& data, bool premultiplyAlpha)
{
// We need at least 4 bytes to figure out what kind of image we're dealing with.
if (data.size() < 4)
return 0;
- return new ImageDecoderQt;
+ return new ImageDecoderQt(premultiplyAlpha);
}
-ImageDecoderQt::ImageDecoderQt()
- : m_repetitionCount(cAnimationNone)
+ImageDecoderQt::ImageDecoderQt(bool premultiplyAlpha)
+ : ImageDecoder(premultiplyAlpha)
+ , m_repetitionCount(cAnimationNone)
{
}
@@ -104,10 +105,15 @@ size_t ImageDecoderQt::frameCount()
// we will have to parse everything...
if (!imageCount)
forceLoadEverything();
- else
+ else {
m_frameBufferCache.resize(imageCount);
- } else
+ for (size_t i = 0; i < m_frameBufferCache.size(); ++i)
+ m_frameBufferCache[i].setPremultiplyAlpha(m_premultiplyAlpha);
+ }
+ } else {
m_frameBufferCache.resize(1);
+ m_frameBufferCache[0].setPremultiplyAlpha(m_premultiplyAlpha);
+ }
}
return m_frameBufferCache.size();
@@ -236,6 +242,8 @@ void ImageDecoderQt::forceLoadEverything()
// Otherwise, we want to forget about
// the last attempt to decode a image.
m_frameBufferCache.resize(imageCount - 1);
+ for (size_t i = 0; i < m_frameBufferCache.size(); ++i)
+ m_frameBufferCache[i].setPremultiplyAlpha(m_premultiplyAlpha);
if (imageCount == 1)
setFailed();
}
diff --git a/WebCore/platform/graphics/qt/ImageDecoderQt.h b/WebCore/platform/graphics/qt/ImageDecoderQt.h
index ceef884..5014d53 100644
--- a/WebCore/platform/graphics/qt/ImageDecoderQt.h
+++ b/WebCore/platform/graphics/qt/ImageDecoderQt.h
@@ -41,7 +41,7 @@ namespace WebCore {
class ImageDecoderQt : public ImageDecoder
{
public:
- ImageDecoderQt();
+ ImageDecoderQt(bool premultiplyAlpha);
~ImageDecoderQt();
virtual void setData(SharedBuffer* data, bool allDataReceived);
diff --git a/WebCore/platform/graphics/skia/GraphicsContext3DSkia.cpp b/WebCore/platform/graphics/skia/GraphicsContext3DSkia.cpp
index ee0a874..61039f2 100644
--- a/WebCore/platform/graphics/skia/GraphicsContext3DSkia.cpp
+++ b/WebCore/platform/graphics/skia/GraphicsContext3DSkia.cpp
@@ -31,6 +31,7 @@
#include "GraphicsContext3D.h"
#include "Image.h"
+#include "ImageSource.h"
#include "NativeImageSkia.h"
#include <algorithm>
@@ -43,27 +44,28 @@ bool GraphicsContext3D::getImageData(Image* image,
bool premultiplyAlpha,
Vector<uint8_t>& outputVector)
{
- if (!image)
+ if (!image || !image->data())
return false;
- NativeImageSkia* skiaImage = image->nativeImageForCurrentFrame();
- if (!skiaImage)
+ ImageSource decoder(false);
+ decoder.setData(image->data(), true);
+ if (!decoder.frameCount() || !decoder.frameIsCompleteAtIndex(0))
return false;
- SkBitmap::Config skiaConfig = skiaImage->config();
- // FIXME: must support more image configurations.
+ bool hasAlpha = decoder.frameHasAlphaAtIndex(0);
+ OwnPtr<NativeImageSkia> pixels(decoder.createFrameAtIndex(0));
+ if (!pixels.get() || !pixels->isDataComplete() || !pixels->width() || !pixels->height())
+ return false;
+ SkBitmap::Config skiaConfig = pixels->config();
if (skiaConfig != SkBitmap::kARGB_8888_Config)
return false;
- SkBitmap& skiaImageRef = *skiaImage;
+ SkBitmap& skiaImageRef = *pixels;
SkAutoLockPixels lock(skiaImageRef);
- int height = skiaImage->height();
- int rowBytes = skiaImage->rowBytes();
- ASSERT(rowBytes == skiaImage->width() * 4);
- uint8_t* pixels = reinterpret_cast<uint8_t*>(skiaImage->getPixels());
- outputVector.resize(rowBytes * height);
+ ASSERT(pixels->rowBytes() == pixels->width() * 4);
+ outputVector.resize(pixels->rowBytes() * pixels->height());
AlphaOp neededAlphaOp = kAlphaDoNothing;
- if (!premultiplyAlpha)
- // FIXME: must fetch the image data before the premultiplication step
- neededAlphaOp = kAlphaDoUnmultiply;
- return packPixels(pixels, kSourceFormatBGRA8, skiaImage->width(), height, 0,
+ if (hasAlpha && premultiplyAlpha)
+ neededAlphaOp = kAlphaDoPremultiply;
+ return packPixels(reinterpret_cast<const uint8_t*>(pixels->getPixels()),
+ kSourceFormatBGRA8, pixels->width(), pixels->height(), 0,
format, type, neededAlphaOp, outputVector.data());
}
diff --git a/WebCore/platform/image-decoders/ImageDecoder.cpp b/WebCore/platform/image-decoders/ImageDecoder.cpp
index fadb9e3..c1e19d8 100644
--- a/WebCore/platform/image-decoders/ImageDecoder.cpp
+++ b/WebCore/platform/image-decoders/ImageDecoder.cpp
@@ -52,7 +52,7 @@ static unsigned copyFromSharedBuffer(char* buffer, unsigned bufferLength, const
return bytesExtracted;
}
-ImageDecoder* ImageDecoder::create(const SharedBuffer& data)
+ImageDecoder* ImageDecoder::create(const SharedBuffer& data, bool premultiplyAlpha)
{
// We need at least 4 bytes to figure out what kind of image we're dealing
// with.
@@ -64,24 +64,24 @@ ImageDecoder* ImageDecoder::create(const SharedBuffer& data)
// GIFs begin with GIF8(7 or 9).
if (strncmp(contents, "GIF8", 4) == 0)
- return new GIFImageDecoder();
+ return new GIFImageDecoder(premultiplyAlpha);
// Test for PNG.
if (!memcmp(contents, "\x89\x50\x4E\x47", 4))
- return new PNGImageDecoder();
+ return new PNGImageDecoder(premultiplyAlpha);
// JPEG
if (!memcmp(contents, "\xFF\xD8\xFF", 3))
- return new JPEGImageDecoder();
+ return new JPEGImageDecoder(premultiplyAlpha);
// BMP
if (strncmp(contents, "BM", 2) == 0)
- return new BMPImageDecoder();
+ return new BMPImageDecoder(premultiplyAlpha);
// ICOs always begin with a 2-byte 0 followed by a 2-byte 1.
// CURs begin with 2-byte 0 followed by 2-byte 2.
if (!memcmp(contents, "\x00\x00\x01\x00", 4) || !memcmp(contents, "\x00\x00\x02\x00", 4))
- return new ICOImageDecoder();
+ return new ICOImageDecoder(premultiplyAlpha);
// Give up. We don't know what the heck this is.
return 0;
@@ -94,6 +94,7 @@ RGBA32Buffer::RGBA32Buffer()
, m_status(FrameEmpty)
, m_duration(0)
, m_disposalMethod(DisposeNotSpecified)
+ , m_premultiplyAlpha(true)
{
}
@@ -107,6 +108,7 @@ RGBA32Buffer& RGBA32Buffer::operator=(const RGBA32Buffer& other)
setStatus(other.status());
setDuration(other.duration());
setDisposalMethod(other.disposalMethod());
+ setPremultiplyAlpha(other.premultiplyAlpha());
return *this;
}
diff --git a/WebCore/platform/image-decoders/ImageDecoder.h b/WebCore/platform/image-decoders/ImageDecoder.h
index 4b71ce7..38160ec 100644
--- a/WebCore/platform/image-decoders/ImageDecoder.h
+++ b/WebCore/platform/image-decoders/ImageDecoder.h
@@ -118,12 +118,14 @@ namespace WebCore {
FrameStatus status() const { return m_status; }
unsigned duration() const { return m_duration; }
FrameDisposalMethod disposalMethod() const { return m_disposalMethod; }
+ bool premultiplyAlpha() const { return m_premultiplyAlpha; }
void setHasAlpha(bool alpha);
void setRect(const IntRect& r) { m_rect = r; }
void setStatus(FrameStatus status);
void setDuration(unsigned duration) { m_duration = duration; }
void setDisposalMethod(FrameDisposalMethod method) { m_disposalMethod = method; }
+ void setPremultiplyAlpha(bool premultiplyAlpha) { m_premultiplyAlpha = premultiplyAlpha; }
inline void setRGBA(int x, int y, unsigned r, unsigned g, unsigned b, unsigned a)
{
@@ -153,11 +155,10 @@ namespace WebCore {
inline void setRGBA(PixelData* dest, unsigned r, unsigned g, unsigned b, unsigned a)
{
- // We store this data pre-multiplied.
- if (a == 0)
+ if (m_premultiplyAlpha && !a)
*dest = 0;
else {
- if (a < 255) {
+ if (m_premultiplyAlpha && a < 255) {
float alphaPercent = a / 255.0f;
r = static_cast<unsigned>(r * alphaPercent);
g = static_cast<unsigned>(g * alphaPercent);
@@ -192,6 +193,9 @@ namespace WebCore {
FrameDisposalMethod m_disposalMethod;
// What to do with this frame's data when
// initializing the next frame.
+ bool m_premultiplyAlpha;
+ // Whether to premultiply alpha into R, G, B
+ // channels; by default it's true.
};
// The ImageDecoder class represents a base class for specific image format
@@ -205,8 +209,9 @@ namespace WebCore {
// m_maxNumPixels. (Not supported by all image decoders yet)
class ImageDecoder : public Noncopyable {
public:
- ImageDecoder()
+ ImageDecoder(bool premultiplyAlpha)
: m_scaled(false)
+ , m_premultiplyAlpha(premultiplyAlpha)
, m_sizeAvailable(false)
, m_maxNumPixels(-1)
, m_isAllDataReceived(false)
@@ -219,7 +224,7 @@ namespace WebCore {
// Factory function to create an ImageDecoder. Ports that subclass
// ImageDecoder can provide their own implementation of this to avoid
// needing to write a dedicated setData() implementation.
- static ImageDecoder* create(const SharedBuffer& data);
+ static ImageDecoder* create(const SharedBuffer& data, bool premultiplyAlpha);
// The the filename extension usually associated with an undecoded image
// of this type.
@@ -333,6 +338,7 @@ namespace WebCore {
bool m_scaled;
Vector<int> m_scaledColumns;
Vector<int> m_scaledRows;
+ bool m_premultiplyAlpha;
private:
// Some code paths compute the size of the image as "width * height * 4"
diff --git a/WebCore/platform/image-decoders/bmp/BMPImageDecoder.cpp b/WebCore/platform/image-decoders/bmp/BMPImageDecoder.cpp
index 901f60d..1c117a8 100644
--- a/WebCore/platform/image-decoders/bmp/BMPImageDecoder.cpp
+++ b/WebCore/platform/image-decoders/bmp/BMPImageDecoder.cpp
@@ -40,8 +40,9 @@ namespace WebCore {
// don't pack).
static const size_t sizeOfFileHeader = 14;
-BMPImageDecoder::BMPImageDecoder()
- : m_decodedOffset(0)
+BMPImageDecoder::BMPImageDecoder(bool premultiplyAlpha)
+ : ImageDecoder(premultiplyAlpha)
+ , m_decodedOffset(0)
{
}
@@ -68,8 +69,10 @@ RGBA32Buffer* BMPImageDecoder::frameBufferAtIndex(size_t index)
if (index)
return 0;
- if (m_frameBufferCache.isEmpty())
+ if (m_frameBufferCache.isEmpty()) {
m_frameBufferCache.resize(1);
+ m_frameBufferCache.first().setPremultiplyAlpha(m_premultiplyAlpha);
+ }
RGBA32Buffer* buffer = &m_frameBufferCache.first();
if (buffer->status() != RGBA32Buffer::FrameComplete)
diff --git a/WebCore/platform/image-decoders/bmp/BMPImageDecoder.h b/WebCore/platform/image-decoders/bmp/BMPImageDecoder.h
index b08b32b..3996bf9 100644
--- a/WebCore/platform/image-decoders/bmp/BMPImageDecoder.h
+++ b/WebCore/platform/image-decoders/bmp/BMPImageDecoder.h
@@ -39,7 +39,7 @@ namespace WebCore {
// This class decodes the BMP image format.
class BMPImageDecoder : public ImageDecoder {
public:
- BMPImageDecoder();
+ BMPImageDecoder(bool premultiplyAlpha);
// ImageDecoder
virtual String filenameExtension() const { return "bmp"; }
diff --git a/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp b/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp
index ec16da7..a2397ee 100644
--- a/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp
+++ b/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp
@@ -29,8 +29,9 @@
namespace WebCore {
-GIFImageDecoder::GIFImageDecoder()
- : m_alreadyScannedThisDataForFrameCount(true)
+GIFImageDecoder::GIFImageDecoder(bool premultiplyAlpha)
+ : ImageDecoder(premultiplyAlpha)
+ , m_alreadyScannedThisDataForFrameCount(true)
, m_repetitionCount(cAnimationLoopOnce)
, m_readOffset(0)
{
@@ -83,6 +84,8 @@ size_t GIFImageDecoder::frameCount()
reader.read((const unsigned char*)m_data->data(), m_data->size(), GIFFrameCountQuery, static_cast<unsigned>(-1));
m_alreadyScannedThisDataForFrameCount = true;
m_frameBufferCache.resize(reader.images_count);
+ for (int i = 0; i < reader.images_count; ++i)
+ m_frameBufferCache[i].setPremultiplyAlpha(m_premultiplyAlpha);
}
return m_frameBufferCache.size();
diff --git a/WebCore/platform/image-decoders/gif/GIFImageDecoder.h b/WebCore/platform/image-decoders/gif/GIFImageDecoder.h
index e0f8173..21c1c57 100644
--- a/WebCore/platform/image-decoders/gif/GIFImageDecoder.h
+++ b/WebCore/platform/image-decoders/gif/GIFImageDecoder.h
@@ -36,7 +36,7 @@ namespace WebCore {
// This class decodes the GIF image format.
class GIFImageDecoder : public ImageDecoder {
public:
- GIFImageDecoder();
+ GIFImageDecoder(bool premultiplyAlpha);
virtual ~GIFImageDecoder();
enum GIFQuery { GIFFullQuery, GIFSizeQuery, GIFFrameCountQuery };
diff --git a/WebCore/platform/image-decoders/ico/ICOImageDecoder.cpp b/WebCore/platform/image-decoders/ico/ICOImageDecoder.cpp
index d667795..453efd2 100644
--- a/WebCore/platform/image-decoders/ico/ICOImageDecoder.cpp
+++ b/WebCore/platform/image-decoders/ico/ICOImageDecoder.cpp
@@ -44,8 +44,9 @@ namespace WebCore {
static const size_t sizeOfDirectory = 6;
static const size_t sizeOfDirEntry = 16;
-ICOImageDecoder::ICOImageDecoder()
- : m_decodedOffset(0)
+ICOImageDecoder::ICOImageDecoder(bool premultiplyAlpha)
+ : ImageDecoder(premultiplyAlpha)
+ , m_decodedOffset(0)
{
}
@@ -96,8 +97,11 @@ bool ICOImageDecoder::setSize(unsigned width, unsigned height)
size_t ICOImageDecoder::frameCount()
{
decode(0, true);
- if (m_frameBufferCache.isEmpty())
+ if (m_frameBufferCache.isEmpty()) {
m_frameBufferCache.resize(m_dirEntries.size());
+ for (size_t i = 0; i < m_dirEntries.size(); ++i)
+ m_frameBufferCache[i].setPremultiplyAlpha(m_premultiplyAlpha);
+ }
// CAUTION: We must not resize m_frameBufferCache again after this, as
// decodeAtIndex() may give a BMPImageReader a pointer to one of the
// entries.
@@ -197,7 +201,7 @@ bool ICOImageDecoder::decodeAtIndex(size_t index)
}
if (!m_pngDecoders[index]) {
- m_pngDecoders[index].set(new PNGImageDecoder());
+ m_pngDecoders[index].set(new PNGImageDecoder(m_premultiplyAlpha));
setDataForPNGDecoderAtIndex(index);
}
// Fail if the size the PNGImageDecoder calculated does not match the size
diff --git a/WebCore/platform/image-decoders/ico/ICOImageDecoder.h b/WebCore/platform/image-decoders/ico/ICOImageDecoder.h
index 48024a2..e2ee9e3 100644
--- a/WebCore/platform/image-decoders/ico/ICOImageDecoder.h
+++ b/WebCore/platform/image-decoders/ico/ICOImageDecoder.h
@@ -40,7 +40,7 @@ namespace WebCore {
// This class decodes the ICO and CUR image formats.
class ICOImageDecoder : public ImageDecoder {
public:
- ICOImageDecoder();
+ ICOImageDecoder(bool premultiplyAlpha);
virtual ~ICOImageDecoder();
// ImageDecoder
diff --git a/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp b/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp
index 4911bc9..6c6c782 100644
--- a/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp
+++ b/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp
@@ -361,7 +361,8 @@ void term_source(j_decompress_ptr jd)
src->decoder->decoder()->jpegComplete();
}
-JPEGImageDecoder::JPEGImageDecoder()
+JPEGImageDecoder::JPEGImageDecoder(bool premultiplyAlpha)
+ : ImageDecoder(premultiplyAlpha)
{
}
@@ -391,8 +392,10 @@ RGBA32Buffer* JPEGImageDecoder::frameBufferAtIndex(size_t index)
if (index)
return 0;
- if (m_frameBufferCache.isEmpty())
+ if (m_frameBufferCache.isEmpty()) {
m_frameBufferCache.resize(1);
+ m_frameBufferCache[0].setPremultiplyAlpha(m_premultiplyAlpha);
+ }
RGBA32Buffer& frame = m_frameBufferCache[0];
if (frame.status() != RGBA32Buffer::FrameComplete)
diff --git a/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h b/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h
index 43b35fd..5047019 100644
--- a/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h
+++ b/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h
@@ -37,7 +37,7 @@ namespace WebCore {
// This class decodes the JPEG image format.
class JPEGImageDecoder : public ImageDecoder {
public:
- JPEGImageDecoder();
+ JPEGImageDecoder(bool premultiplyAlpha);
virtual ~JPEGImageDecoder();
// ImageDecoder
diff --git a/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp b/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp
index 8186f33..940e4c4 100644
--- a/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp
+++ b/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp
@@ -169,8 +169,9 @@ private:
unsigned m_currentBufferSize;
};
-PNGImageDecoder::PNGImageDecoder()
- : m_doNothingOnFailure(false)
+PNGImageDecoder::PNGImageDecoder(bool premultiplyAlpha)
+ : ImageDecoder(premultiplyAlpha)
+ , m_doNothingOnFailure(false)
{
}
@@ -200,8 +201,10 @@ RGBA32Buffer* PNGImageDecoder::frameBufferAtIndex(size_t index)
if (index)
return 0;
- if (m_frameBufferCache.isEmpty())
+ if (m_frameBufferCache.isEmpty()) {
m_frameBufferCache.resize(1);
+ m_frameBufferCache[0].setPremultiplyAlpha(m_premultiplyAlpha);
+ }
RGBA32Buffer& frame = m_frameBufferCache[0];
if (frame.status() != RGBA32Buffer::FrameComplete)
diff --git a/WebCore/platform/image-decoders/png/PNGImageDecoder.h b/WebCore/platform/image-decoders/png/PNGImageDecoder.h
index 145fc4d..763b88f 100644
--- a/WebCore/platform/image-decoders/png/PNGImageDecoder.h
+++ b/WebCore/platform/image-decoders/png/PNGImageDecoder.h
@@ -36,7 +36,7 @@ namespace WebCore {
// This class decodes the PNG image format.
class PNGImageDecoder : public ImageDecoder {
public:
- PNGImageDecoder();
+ PNGImageDecoder(bool premultiplyAlpha);
virtual ~PNGImageDecoder();
// ImageDecoder
diff --git a/WebCore/platform/image-decoders/skia/ImageDecoderSkia.cpp b/WebCore/platform/image-decoders/skia/ImageDecoderSkia.cpp
index f763a15..149937e 100644
--- a/WebCore/platform/image-decoders/skia/ImageDecoderSkia.cpp
+++ b/WebCore/platform/image-decoders/skia/ImageDecoderSkia.cpp
@@ -33,6 +33,7 @@ RGBA32Buffer::RGBA32Buffer()
: m_status(FrameEmpty)
, m_duration(0)
, m_disposalMethod(DisposeNotSpecified)
+ , m_premultiplyAlpha(true)
{
}
@@ -49,6 +50,7 @@ RGBA32Buffer& RGBA32Buffer::operator=(const RGBA32Buffer& other)
setStatus(other.status());
setDuration(other.duration());
setDisposalMethod(other.disposalMethod());
+ setPremultiplyAlpha(other.premultiplyAlpha());
return *this;
}
diff --git a/WebKit/chromium/ChangeLog b/WebKit/chromium/ChangeLog
index 5d860ed..2824511 100644
--- a/WebKit/chromium/ChangeLog
+++ b/WebKit/chromium/ChangeLog
@@ -1,3 +1,13 @@
+2010-08-24 Zhenyao Mo <zmo at google.com>
+
+ Reviewed by Kenneth Russell.
+
+ Passing premultiplyAlpha=false to tex{Sub}Image2D loses information (skia)
+ https://bugs.webkit.org/show_bug.cgi?id=38282
+
+ * src/WebImageDecoder.cpp:
+ (WebKit::WebImageDecoder::init): Add premultiplyAlpha flag.
+
2010-08-25 Satish Sampath <satish at chromium.org>
Reviewed by Jeremy Orlow.
diff --git a/WebKit/chromium/src/WebImageDecoder.cpp b/WebKit/chromium/src/WebImageDecoder.cpp
index 9e1d1f4..160deee 100644
--- a/WebKit/chromium/src/WebImageDecoder.cpp
+++ b/WebKit/chromium/src/WebImageDecoder.cpp
@@ -56,10 +56,10 @@ void WebImageDecoder::init(Type type)
{
switch (type) {
case TypeBMP:
- m_private = new BMPImageDecoder();
+ m_private = new BMPImageDecoder(true);
break;
case TypeICO:
- m_private = new ICOImageDecoder();
+ m_private = new ICOImageDecoder(true);
break;
}
}
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list