2011-03-29 Matthew Delaney <mdelaney@apple.com>
authormdelaney@apple.com <mdelaney@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 30 Mar 2011 23:15:44 +0000 (23:15 +0000)
committermdelaney@apple.com <mdelaney@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 30 Mar 2011 23:15:44 +0000 (23:15 +0000)
        Reviewed by Simon Fraser.

        Use the Accelerate vImage vectorized (un)premultiplyImageData functions for ImageBufferCG

        https://bugs.webkit.org/show_bug.cgi?id=53134

        * wtf/Platform.h: Added in WTF flag for using the Accelerate framework
2011-03-29  Matthew Delaney  <mdelaney@apple.com>

        Reviewed by Simon Fraser.

        Use the Accelerate vImage vectorized (un)premultiplyImageData functions for ImageBufferCG

        https://bugs.webkit.org/show_bug.cgi?id=53134

        Test: fast/canvas/getPutImageDataPairTest.html

        * platform/graphics/cg/ImageBufferCG.cpp:
2011-03-25  Matthew Delaney  <mdelaney@apple.com>

        Reviewed by Simon Fraser.

        Use Accelerate vImage vectorized (un)premultiplyImageData functions for ImageBufferCG.cpp
        https://bugs.webkit.org/show_bug.cgi?id=53134

        * fast/canvas/canvas-getImageData-expected.txt: Resetting expected results for this test due to test change.
        * fast/canvas/canvas-getImageData.html: Removed the section of this test that incorrectly assumes the
          rounding behavior of initial inputed data.
        * fast/canvas/getPutImageDataPairTest-expected.txt: Added.
        * fast/canvas/getPutImageDataPairTest.html: A new test to make sure that a batch of paired putImageData(getImageData)
          calls doesn't accumulate any error per the spec.
        * fast/canvas/rgba-parsing-expected.txt: Reset the results for this test since the initial rgba rounding values are
          now different. Note: the spec does not define how they *should* be rounded, so having them there is basically just
          for bookkeeping to know when our rounding behavior changes since it could be early warning of related real issues.

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

LayoutTests/ChangeLog
LayoutTests/fast/canvas/canvas-getImageData-expected.txt
LayoutTests/fast/canvas/canvas-getImageData.html
LayoutTests/fast/canvas/getPutImageDataPairTest-expected.txt [new file with mode: 0644]
LayoutTests/fast/canvas/getPutImageDataPairTest.html [new file with mode: 0644]
LayoutTests/fast/canvas/rgba-parsing-expected.txt
LayoutTests/fast/canvas/script-tests/rgba-parsing.js
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/wtf/Platform.h
Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp

index 0754365..9cd7353 100644 (file)
@@ -1,3 +1,20 @@
+2011-03-25  Matthew Delaney  <mdelaney@apple.com>
+
+        Reviewed by Simon Fraser.
+
+        Use Accelerate vImage vectorized (un)premultiplyImageData functions for ImageBufferCG.cpp
+        https://bugs.webkit.org/show_bug.cgi?id=53134
+
+        * fast/canvas/canvas-getImageData-expected.txt: Resetting expected results for this test due to test change.
+        * fast/canvas/canvas-getImageData.html: Removed the section of this test that incorrectly assumes the 
+          rounding behavior of initial inputed data.
+        * fast/canvas/getPutImageDataPairTest-expected.txt: Added.
+        * fast/canvas/getPutImageDataPairTest.html: A new test to make sure that a batch of paired putImageData(getImageData)
+          calls doesn't accumulate any error per the spec.
+        * fast/canvas/rgba-parsing-expected.txt: Reset the results for this test since the initial rgba rounding values are
+          now different. Note: the spec does not define how they *should* be rounded, so having them there is basically just
+          for bookkeeping to know when our rounding behavior changes since it could be early warning of related real issues.
+
 2011-03-30  Jessie Berlin  <jberlin@apple.com>
 
         http/tests/uri/username-with-no-hostname.html is flaky due to preload scanner
index 500bf64..d399a72 100644 (file)
@@ -27,125 +27,4 @@ PASS: pixel at (96,0) was [0,255,0,255]
 PASS: pixel at (5,5) was [64,128,191,255]
 PASS: Correctly retrieved every pixel in a row
 PASS: Correct data for content outside canvas bounds
-PASS: pixel at (50,50) was [0,0,0,0]
-PASS: pixel at (50,54) was [0,0,0,1]
-PASS: pixel at (50,58) was [0,0,0,2]
-PASS: pixel at (50,62) was [0,0,0,16]
-PASS: pixel at (50,66) was [0,0,0,32]
-PASS: pixel at (50,70) was [0,0,0,64]
-PASS: pixel at (50,74) was [0,0,0,96]
-PASS: pixel at (50,78) was [0,0,0,128]
-PASS: pixel at (50,82) was [0,0,0,192]
-PASS: pixel at (50,86) was [0,0,0,254]
-PASS: pixel at (50,90) was [0,0,0,255]
-PASS: pixel at (54,50) was [0,0,0,0]
-PASS: pixel at (54,54) was [0,0,0,1]
-PASS: pixel at (54,58) was [0,0,0,2]
-PASS: pixel at (54,62) was [0,0,0,16]
-PASS: pixel at (54,66) was [0,0,0,32]
-PASS: pixel at (54,70) was [0,0,0,64]
-PASS: pixel at (54,74) was [0,0,0,96]
-PASS: pixel at (54,78) was [1,0,0,128]
-PASS: pixel at (54,82) was [1,0,0,192]
-PASS: pixel at (54,86) was [1,0,0,254]
-PASS: pixel at (54,90) was [1,0,0,255]
-PASS: pixel at (58,50) was [0,0,0,0]
-PASS: pixel at (58,54) was [0,0,0,1]
-PASS: pixel at (58,58) was [0,0,0,2]
-PASS: pixel at (58,62) was [0,0,0,16]
-PASS: pixel at (58,66) was [0,0,0,32]
-PASS: pixel at (58,70) was [3,0,0,64]
-PASS: pixel at (58,74) was [2,0,0,96]
-PASS: pixel at (58,78) was [1,0,0,128]
-PASS: pixel at (58,82) was [2,0,0,192]
-PASS: pixel at (58,86) was [2,0,0,254]
-PASS: pixel at (58,90) was [2,0,0,255]
-PASS: pixel at (62,50) was [0,0,0,0]
-PASS: pixel at (62,54) was [0,0,0,1]
-PASS: pixel at (62,58) was [0,0,0,2]
-PASS: pixel at (62,62) was [15,0,0,16]
-PASS: pixel at (62,66) was [15,0,0,32]
-PASS: pixel at (62,70) was [15,0,0,64]
-PASS: pixel at (62,74) was [15,0,0,96]
-PASS: pixel at (62,78) was [15,0,0,128]
-PASS: pixel at (62,82) was [15,0,0,192]
-PASS: pixel at (62,86) was [16,0,0,254]
-PASS: pixel at (62,90) was [16,0,0,255]
-PASS: pixel at (66,50) was [0,0,0,0]
-PASS: pixel at (66,54) was [0,0,0,1]
-PASS: pixel at (66,58) was [0,0,0,2]
-PASS: pixel at (66,62) was [31,0,0,16]
-PASS: pixel at (66,66) was [31,0,0,32]
-PASS: pixel at (66,70) was [31,0,0,64]
-PASS: pixel at (66,74) was [31,0,0,96]
-PASS: pixel at (66,78) was [31,0,0,128]
-PASS: pixel at (66,82) was [31,0,0,192]
-PASS: pixel at (66,86) was [32,0,0,254]
-PASS: pixel at (66,90) was [32,0,0,255]
-PASS: pixel at (70,50) was [0,0,0,0]
-PASS: pixel at (70,54) was [0,0,0,1]
-PASS: pixel at (70,58) was [127,0,0,2]
-PASS: pixel at (70,62) was [63,0,0,16]
-PASS: pixel at (70,66) was [63,0,0,32]
-PASS: pixel at (70,70) was [63,0,0,64]
-PASS: pixel at (70,74) was [63,0,0,96]
-PASS: pixel at (70,78) was [63,0,0,128]
-PASS: pixel at (70,82) was [63,0,0,192]
-PASS: pixel at (70,86) was [64,0,0,254]
-PASS: pixel at (70,90) was [64,0,0,255]
-PASS: pixel at (74,50) was [0,0,0,0]
-PASS: pixel at (74,54) was [0,0,0,1]
-PASS: pixel at (74,58) was [127,0,0,2]
-PASS: pixel at (74,62) was [95,0,0,16]
-PASS: pixel at (74,66) was [95,0,0,32]
-PASS: pixel at (74,70) was [95,0,0,64]
-PASS: pixel at (74,74) was [95,0,0,96]
-PASS: pixel at (74,78) was [95,0,0,128]
-PASS: pixel at (74,82) was [95,0,0,192]
-PASS: pixel at (74,86) was [96,0,0,254]
-PASS: pixel at (74,90) was [96,0,0,255]
-PASS: pixel at (78,50) was [0,0,0,0]
-PASS: pixel at (78,54) was [255,0,0,1]
-PASS: pixel at (78,58) was [127,0,0,2]
-PASS: pixel at (78,62) was [127,0,0,16]
-PASS: pixel at (78,66) was [127,0,0,32]
-PASS: pixel at (78,70) was [127,0,0,64]
-PASS: pixel at (78,74) was [127,0,0,96]
-PASS: pixel at (78,78) was [127,0,0,128]
-PASS: pixel at (78,82) was [127,0,0,192]
-PASS: pixel at (78,86) was [127,0,0,254]
-PASS: pixel at (78,90) was [128,0,0,255]
-PASS: pixel at (82,50) was [0,0,0,0]
-PASS: pixel at (82,54) was [255,0,0,1]
-PASS: pixel at (82,58) was [255,0,0,2]
-PASS: pixel at (82,62) was [191,0,0,16]
-PASS: pixel at (82,66) was [191,0,0,32]
-PASS: pixel at (82,70) was [191,0,0,64]
-PASS: pixel at (82,74) was [191,0,0,96]
-PASS: pixel at (82,78) was [191,0,0,128]
-PASS: pixel at (82,82) was [192,0,0,192]
-PASS: pixel at (82,86) was [191,0,0,254]
-PASS: pixel at (82,90) was [192,0,0,255]
-PASS: pixel at (86,50) was [0,0,0,0]
-PASS: pixel at (86,54) was [255,0,0,1]
-PASS: pixel at (86,58) was [255,0,0,2]
-PASS: pixel at (86,62) was [255,0,0,16]
-PASS: pixel at (86,66) was [255,0,0,32]
-PASS: pixel at (86,70) was [255,0,0,64]
-PASS: pixel at (86,74) was [255,0,0,96]
-PASS: pixel at (86,78) was [253,0,0,128]
-PASS: pixel at (86,82) was [253,0,0,192]
-PASS: pixel at (86,86) was [253,0,0,254]
-PASS: pixel at (86,90) was [254,0,0,255]
-PASS: pixel at (90,50) was [0,0,0,0]
-PASS: pixel at (90,54) was [255,0,0,1]
-PASS: pixel at (90,58) was [255,0,0,2]
-PASS: pixel at (90,62) was [255,0,0,16]
-PASS: pixel at (90,66) was [255,0,0,32]
-PASS: pixel at (90,70) was [255,0,0,64]
-PASS: pixel at (90,74) was [255,0,0,96]
-PASS: pixel at (90,78) was [255,0,0,128]
-PASS: pixel at (90,82) was [255,0,0,192]
-PASS: pixel at (90,86) was [255,0,0,254]
-PASS: pixel at (90,90) was [255,0,0,255]
 
index b864b65..5eaacfd 100644 (file)
@@ -95,20 +95,4 @@ if (matched)
 else
     log("FAIL: Did not get correct data for content outside canvas bounds: "+content);
 
-// Ensure returned values are not premultiplied
-var values = [0,1,2,16,32,64,96,128,192,254,255];
-
-// this function simply accounts for truncation due to premultiplication in the canvas implementation
-function premult(value, alpha) {
-    return alpha ? Math.floor(Math.round(value*alpha/255)*255/alpha) : 0;
-}
-
-for (var i = 0; i < values.length; i++) {
-    for (var a = 0; a < values.length; a++) {
-        context.fillStyle = "rgba(" + [values[i], 0, 0, values[a]/255] +")";
-        context.fillRect(50+i*4,50+a*4,2,2);
-        pixelShouldBe(context, 50+i*4, 50+a*4, [premult(values[i], values[a]), 0, 0, values[a]]);
-    }
-}
-
 </script>
diff --git a/LayoutTests/fast/canvas/getPutImageDataPairTest-expected.txt b/LayoutTests/fast/canvas/getPutImageDataPairTest-expected.txt
new file mode 100644 (file)
index 0000000..d830043
--- /dev/null
@@ -0,0 +1,4 @@
+Test that putImageData(getImageData) pair leaves canvas ImageData the same.
+
+Result: PASS
diff --git a/LayoutTests/fast/canvas/getPutImageDataPairTest.html b/LayoutTests/fast/canvas/getPutImageDataPairTest.html
new file mode 100644 (file)
index 0000000..4d61ff9
--- /dev/null
@@ -0,0 +1,64 @@
+<!DOCTYPE html>
+<title>putImageData(getImageData) pair test</title>
+<body class="show_output">
+<h3>Test that putImageData(getImageData) pair leaves canvas ImageData the same.</h3>
+<canvas id="c" class="output" width="64" height="64"><p class="fallback">FAIL (fallback content)</p></canvas>
+<br>
+Result: <a id="result"></a>
+<script>
+if (window.layoutTestController)
+    layoutTestController.dumpAsText();
+
+var canvas = document.getElementById("c");
+var ctx = canvas.getContext("2d");
+var passed = getPutImageData(50, ctx, 0, 0, 0, 0.0);
+passed |= getPutImageData(50, ctx, 0, 0, 0, 0.5);
+passed |= getPutImageData(50, ctx, 0, 0, 0, 1.0);
+passed |= getPutImageData(50, ctx, 127, 128, 129, 0.49);
+passed |= getPutImageData(50, ctx, 127, 128, 129, 0.51);
+passed |= getPutImageData(50, ctx, 127, 128, 129, 0.5);
+passed |= getPutImageData(50, ctx, 128, 128, 128, 0.0);
+passed |= getPutImageData(50, ctx, 128, 128, 128, 0.5);
+passed |= getPutImageData(50, ctx, 128, 128, 128, 1.0);
+
+var result_a = document.getElementById("result");
+if (!passed)
+    result_a.innerHTML = "FAIL";
+else
+    result_a.innerHTML = "PASS";
+
+function getPutImageData(numIters, ctx, r, g, b, a) {
+    var x = 0, y = 0, w = ctx.canvas.width, h = ctx.canvas.height;
+
+    // Paint the canvas green to start
+    ctx.fillStyle = color;
+    ctx.fillRect(x,y,w,h);
+
+    // Now paint the canvas a random hue of gray
+    var color = 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')'; 
+    ctx.fillStyle = color;
+    ctx.fillRect(x,y,w,h);
+
+    // Get the current "original" image data
+    var origImageData = ctx.getImageData(x, y, w, h);
+    ctx.putImageData(origImageData, x, y);
+
+    // Get and put the image data 'numIters' times
+    for(var i = 0; i < numIters; i++)
+        ctx.putImageData(ctx.getImageData(x,y,w,h), x,y);
+
+    // Grab new current image data
+    var currImageData = ctx.getImageData(x, y, w, h);
+
+    // Verify that original and new current image datas are equal
+    for(var i = 0; i < currImageData.data.length; i++) {
+        var origSubpixel = origImageData.data[i];
+        var currSubpixel = currImageData.data[i];
+
+        // If even 1 subpixel is off, return failure
+        if (origSubpixel != currSubpixel)
+            return false;
+    }
+    return true;
+}
+</script>
\ No newline at end of file
index 66067fd..15a9a62 100644 (file)
@@ -88,386 +88,6 @@ PASS parse('rgba(0, 0, 0, 0.996)') is 'RGBA[0, 0, 0, 254]'
 PASS parse('rgba(0, 0, 0, 0.997)') is 'RGBA[0, 0, 0, 255]'
 PASS parse('rgba(0, 0, 0, 0.998)') is 'RGBA[0, 0, 0, 255]'
 PASS parse('rgba(0, 0, 0, 0.999)') is 'RGBA[0, 0, 0, 255]'
-rgba(0, 0, 0, 0) => RGBA[0, 0, 0, 0]
-rgba(0, 0, 0, 0.01333) => RGBA[0, 0, 0, 3]
-rgba(0, 0, 0, 0.02666) => RGBA[0, 0, 0, 6]
-rgba(0, 0, 0, 0.03999) => RGBA[0, 0, 0, 10]
-rgba(0, 0, 0, 0.05332) => RGBA[0, 0, 0, 13]
-rgba(0, 0, 0, 0.06665) => RGBA[0, 0, 0, 17]
-rgba(0, 0, 0, 0.07998) => RGBA[0, 0, 0, 20]
-rgba(0, 0, 0, 0.09330999999999999) => RGBA[0, 0, 0, 23]
-rgba(0, 0, 0, 0.10663999999999998) => RGBA[0, 0, 0, 27]
-rgba(0, 0, 0, 0.11996999999999998) => RGBA[0, 0, 0, 30]
-rgba(0, 0, 0, 0.13329999999999997) => RGBA[0, 0, 0, 34]
-rgba(0, 0, 0, 0.14662999999999998) => RGBA[0, 0, 0, 37]
-rgba(0, 0, 0, 0.15996) => RGBA[0, 0, 0, 40]
-rgba(0, 0, 0, 0.17329) => RGBA[0, 0, 0, 44]
-rgba(0, 0, 0, 0.18662) => RGBA[0, 0, 0, 47]
-rgba(0, 0, 0, 0.19995000000000002) => RGBA[0, 0, 0, 51]
-rgba(0, 0, 0, 0.21328000000000003) => RGBA[0, 0, 0, 54]
-rgba(0, 0, 0, 0.22661000000000003) => RGBA[0, 0, 0, 58]
-rgba(0, 0, 0, 0.23994000000000004) => RGBA[0, 0, 0, 61]
-rgba(0, 0, 0, 0.25327000000000005) => RGBA[0, 0, 0, 64]
-rgba(0, 0, 0, 0.26660000000000006) => RGBA[0, 0, 0, 68]
-rgba(0, 0, 0, 0.27993000000000007) => RGBA[0, 0, 0, 71]
-rgba(0, 0, 0, 0.2932600000000001) => RGBA[0, 0, 0, 75]
-rgba(0, 0, 0, 0.3065900000000001) => RGBA[0, 0, 0, 78]
-rgba(0, 0, 0, 0.3199200000000001) => RGBA[0, 0, 0, 81]
-rgba(0, 0, 0, 0.3332500000000001) => RGBA[0, 0, 0, 85]
-rgba(0, 0, 0, 0.3465800000000001) => RGBA[0, 0, 0, 88]
-rgba(0, 0, 0, 0.3599100000000001) => RGBA[0, 0, 0, 92]
-rgba(0, 0, 0, 0.3732400000000001) => RGBA[0, 0, 0, 95]
-rgba(0, 0, 0, 0.38657000000000014) => RGBA[0, 0, 0, 98]
-rgba(0, 0, 0, 0.39990000000000014) => RGBA[0, 0, 0, 102]
-rgba(0, 0, 0, 0.41323000000000015) => RGBA[0, 0, 0, 105]
-rgba(0, 0, 0, 0.42656000000000016) => RGBA[0, 0, 0, 109]
-rgba(0, 0, 0, 0.43989000000000017) => RGBA[0, 0, 0, 112]
-rgba(0, 0, 0, 0.4532200000000002) => RGBA[0, 0, 0, 116]
-rgba(0, 0, 0, 0.4665500000000002) => RGBA[0, 0, 0, 119]
-rgba(0, 0, 0, 0.4798800000000002) => RGBA[0, 0, 0, 122]
-rgba(0, 0, 0, 0.4932100000000002) => RGBA[0, 0, 0, 126]
-rgba(0, 0, 0, 0.5065400000000002) => RGBA[0, 0, 0, 129]
-rgba(0, 0, 0, 0.5198700000000002) => RGBA[0, 0, 0, 133]
-rgba(0, 0, 0, 0.5332000000000001) => RGBA[0, 0, 0, 136]
-rgba(0, 0, 0, 0.5465300000000001) => RGBA[0, 0, 0, 139]
-rgba(0, 0, 0, 0.55986) => RGBA[0, 0, 0, 143]
-rgba(0, 0, 0, 0.57319) => RGBA[0, 0, 0, 146]
-rgba(0, 0, 0, 0.5865199999999999) => RGBA[0, 0, 0, 150]
-rgba(0, 0, 0, 0.5998499999999999) => RGBA[0, 0, 0, 153]
-rgba(0, 0, 0, 0.6131799999999998) => RGBA[0, 0, 0, 156]
-rgba(0, 0, 0, 0.6265099999999998) => RGBA[0, 0, 0, 160]
-rgba(0, 0, 0, 0.6398399999999997) => RGBA[0, 0, 0, 163]
-rgba(0, 0, 0, 0.6531699999999997) => RGBA[0, 0, 0, 167]
-rgba(0, 0, 0, 0.6664999999999996) => RGBA[0, 0, 0, 170]
-rgba(0, 0, 0, 0.6798299999999996) => RGBA[0, 0, 0, 174]
-rgba(0, 0, 0, 0.6931599999999996) => RGBA[0, 0, 0, 177]
-rgba(0, 0, 0, 0.7064899999999995) => RGBA[0, 0, 0, 180]
-rgba(0, 0, 0, 0.7198199999999995) => RGBA[0, 0, 0, 184]
-rgba(0, 0, 0, 0.7331499999999994) => RGBA[0, 0, 0, 187]
-rgba(0, 0, 0, 0.7464799999999994) => RGBA[0, 0, 0, 191]
-rgba(0, 0, 0, 0.7598099999999993) => RGBA[0, 0, 0, 194]
-rgba(0, 0, 0, 0.7731399999999993) => RGBA[0, 0, 0, 197]
-rgba(0, 0, 0, 0.7864699999999992) => RGBA[0, 0, 0, 201]
-rgba(0, 0, 0, 0.7997999999999992) => RGBA[0, 0, 0, 204]
-rgba(0, 0, 0, 0.8131299999999991) => RGBA[0, 0, 0, 208]
-rgba(0, 0, 0, 0.8264599999999991) => RGBA[0, 0, 0, 211]
-rgba(0, 0, 0, 0.839789999999999) => RGBA[0, 0, 0, 214]
-rgba(0, 0, 0, 0.853119999999999) => RGBA[0, 0, 0, 218]
-rgba(0, 0, 0, 0.8664499999999989) => RGBA[0, 0, 0, 221]
-rgba(0, 0, 0, 0.8797799999999989) => RGBA[0, 0, 0, 225]
-rgba(0, 0, 0, 0.8931099999999988) => RGBA[0, 0, 0, 228]
-rgba(0, 0, 0, 0.9064399999999988) => RGBA[0, 0, 0, 232]
-rgba(0, 0, 0, 0.9197699999999988) => RGBA[0, 0, 0, 235]
-rgba(0, 0, 0, 0.9330999999999987) => RGBA[0, 0, 0, 238]
-rgba(0, 0, 0, 0.9464299999999987) => RGBA[0, 0, 0, 242]
-rgba(0, 0, 0, 0.9597599999999986) => RGBA[0, 0, 0, 245]
-rgba(0, 0, 0, 0.9730899999999986) => RGBA[0, 0, 0, 249]
-rgba(0, 0, 0, 0.9864199999999985) => RGBA[0, 0, 0, 252]
-rgba(0, 0, 0, 0.9997499999999985) => RGBA[0, 0, 0, 255]
-rgba(63, 63, 63, 0) => RGBA[0, 0, 0, 0]
-rgba(63, 63, 63, 0.01333) => RGBA[85, 85, 85, 3]
-rgba(63, 63, 63, 0.02666) => RGBA[42, 42, 42, 6]
-rgba(63, 63, 63, 0.03999) => RGBA[51, 51, 51, 10]
-rgba(63, 63, 63, 0.05332) => RGBA[58, 58, 58, 13]
-rgba(63, 63, 63, 0.06665) => RGBA[60, 60, 60, 17]
-rgba(63, 63, 63, 0.07998) => RGBA[63, 63, 63, 20]
-rgba(63, 63, 63, 0.09330999999999999) => RGBA[66, 66, 66, 23]
-rgba(63, 63, 63, 0.10663999999999998) => RGBA[66, 66, 66, 27]
-rgba(63, 63, 63, 0.11996999999999998) => RGBA[59, 59, 59, 30]
-rgba(63, 63, 63, 0.13329999999999997) => RGBA[60, 60, 60, 34]
-rgba(63, 63, 63, 0.14662999999999998) => RGBA[62, 62, 62, 37]
-rgba(63, 63, 63, 0.15996) => RGBA[63, 63, 63, 40]
-rgba(63, 63, 63, 0.17329) => RGBA[63, 63, 63, 44]
-rgba(63, 63, 63, 0.18662) => RGBA[65, 65, 65, 47]
-rgba(63, 63, 63, 0.19995000000000002) => RGBA[65, 65, 65, 51]
-rgba(63, 63, 63, 0.21328000000000003) => RGBA[61, 61, 61, 54]
-rgba(63, 63, 63, 0.22661000000000003) => RGBA[61, 61, 61, 58]
-rgba(63, 63, 63, 0.23994000000000004) => RGBA[62, 62, 62, 61]
-rgba(63, 63, 63, 0.25327000000000005) => RGBA[63, 63, 63, 64]
-rgba(63, 63, 63, 0.26660000000000006) => RGBA[63, 63, 63, 68]
-rgba(63, 63, 63, 0.27993000000000007) => RGBA[64, 64, 64, 71]
-rgba(63, 63, 63, 0.2932600000000001) => RGBA[64, 64, 64, 75]
-rgba(63, 63, 63, 0.3065900000000001) => RGBA[62, 62, 62, 78]
-rgba(63, 63, 63, 0.3199200000000001) => RGBA[62, 62, 62, 81]
-rgba(63, 63, 63, 0.3332500000000001) => RGBA[63, 63, 63, 85]
-rgba(63, 63, 63, 0.3465800000000001) => RGBA[63, 63, 63, 88]
-rgba(63, 63, 63, 0.3599100000000001) => RGBA[63, 63, 63, 92]
-rgba(63, 63, 63, 0.3732400000000001) => RGBA[61, 61, 61, 95]
-rgba(63, 63, 63, 0.38657000000000014) => RGBA[62, 62, 62, 98]
-rgba(63, 63, 63, 0.39990000000000014) => RGBA[62, 62, 62, 102]
-rgba(63, 63, 63, 0.41323000000000015) => RGBA[63, 63, 63, 105]
-rgba(63, 63, 63, 0.42656000000000016) => RGBA[63, 63, 63, 109]
-rgba(63, 63, 63, 0.43989000000000017) => RGBA[63, 63, 63, 112]
-rgba(63, 63, 63, 0.4532200000000002) => RGBA[63, 63, 63, 116]
-rgba(63, 63, 63, 0.4665500000000002) => RGBA[62, 62, 62, 119]
-rgba(63, 63, 63, 0.4798800000000002) => RGBA[62, 62, 62, 122]
-rgba(63, 63, 63, 0.4932100000000002) => RGBA[62, 62, 62, 126]
-rgba(63, 63, 63, 0.5065400000000002) => RGBA[63, 63, 63, 129]
-rgba(63, 63, 63, 0.5198700000000002) => RGBA[63, 63, 63, 133]
-rgba(63, 63, 63, 0.5332000000000001) => RGBA[63, 63, 63, 136]
-rgba(63, 63, 63, 0.5465300000000001) => RGBA[62, 62, 62, 139]
-rgba(63, 63, 63, 0.55986) => RGBA[62, 62, 62, 143]
-rgba(63, 63, 63, 0.57319) => RGBA[62, 62, 62, 146]
-rgba(63, 63, 63, 0.5865199999999999) => RGBA[62, 62, 62, 150]
-rgba(63, 63, 63, 0.5998499999999999) => RGBA[63, 63, 63, 153]
-rgba(63, 63, 63, 0.6131799999999998) => RGBA[63, 63, 63, 156]
-rgba(63, 63, 63, 0.6265099999999998) => RGBA[63, 63, 63, 160]
-rgba(63, 63, 63, 0.6398399999999997) => RGBA[62, 62, 62, 163]
-rgba(63, 63, 63, 0.6531699999999997) => RGBA[62, 62, 62, 167]
-rgba(63, 63, 63, 0.6664999999999996) => RGBA[63, 63, 63, 170]
-rgba(63, 63, 63, 0.6798299999999996) => RGBA[63, 63, 63, 174]
-rgba(63, 63, 63, 0.6931599999999996) => RGBA[63, 63, 63, 177]
-rgba(63, 63, 63, 0.7064899999999995) => RGBA[62, 62, 62, 180]
-rgba(63, 63, 63, 0.7198199999999995) => RGBA[62, 62, 62, 184]
-rgba(63, 63, 63, 0.7331499999999994) => RGBA[62, 62, 62, 187]
-rgba(63, 63, 63, 0.7464799999999994) => RGBA[62, 62, 62, 191]
-rgba(63, 63, 63, 0.7598099999999993) => RGBA[63, 63, 63, 194]
-rgba(63, 63, 63, 0.7731399999999993) => RGBA[63, 63, 63, 197]
-rgba(63, 63, 63, 0.7864699999999992) => RGBA[63, 63, 63, 201]
-rgba(63, 63, 63, 0.7997999999999992) => RGBA[62, 62, 62, 204]
-rgba(63, 63, 63, 0.8131299999999991) => RGBA[62, 62, 62, 208]
-rgba(63, 63, 63, 0.8264599999999991) => RGBA[62, 62, 62, 211]
-rgba(63, 63, 63, 0.839789999999999) => RGBA[63, 63, 63, 214]
-rgba(63, 63, 63, 0.853119999999999) => RGBA[63, 63, 63, 218]
-rgba(63, 63, 63, 0.8664499999999989) => RGBA[63, 63, 63, 221]
-rgba(63, 63, 63, 0.8797799999999989) => RGBA[63, 63, 63, 225]
-rgba(63, 63, 63, 0.8931099999999988) => RGBA[62, 62, 62, 228]
-rgba(63, 63, 63, 0.9064399999999988) => RGBA[62, 62, 62, 232]
-rgba(63, 63, 63, 0.9197699999999988) => RGBA[62, 62, 62, 235]
-rgba(63, 63, 63, 0.9330999999999987) => RGBA[63, 63, 63, 238]
-rgba(63, 63, 63, 0.9464299999999987) => RGBA[63, 63, 63, 242]
-rgba(63, 63, 63, 0.9597599999999986) => RGBA[63, 63, 63, 245]
-rgba(63, 63, 63, 0.9730899999999986) => RGBA[63, 63, 63, 249]
-rgba(63, 63, 63, 0.9864199999999985) => RGBA[62, 62, 62, 252]
-rgba(63, 63, 63, 0.9997499999999985) => RGBA[63, 63, 63, 255]
-rgba(126, 126, 126, 0) => RGBA[0, 0, 0, 0]
-rgba(126, 126, 126, 0.01333) => RGBA[85, 85, 85, 3]
-rgba(126, 126, 126, 0.02666) => RGBA[127, 127, 127, 6]
-rgba(126, 126, 126, 0.03999) => RGBA[127, 127, 127, 10]
-rgba(126, 126, 126, 0.05332) => RGBA[117, 117, 117, 13]
-rgba(126, 126, 126, 0.06665) => RGBA[120, 120, 120, 17]
-rgba(126, 126, 126, 0.07998) => RGBA[127, 127, 127, 20]
-rgba(126, 126, 126, 0.09330999999999999) => RGBA[121, 121, 121, 23]
-rgba(126, 126, 126, 0.10663999999999998) => RGBA[122, 122, 122, 27]
-rgba(126, 126, 126, 0.11996999999999998) => RGBA[127, 127, 127, 30]
-rgba(126, 126, 126, 0.13329999999999997) => RGBA[127, 127, 127, 34]
-rgba(126, 126, 126, 0.14662999999999998) => RGBA[124, 124, 124, 37]
-rgba(126, 126, 126, 0.15996) => RGBA[127, 127, 127, 40]
-rgba(126, 126, 126, 0.17329) => RGBA[127, 127, 127, 44]
-rgba(126, 126, 126, 0.18662) => RGBA[124, 124, 124, 47]
-rgba(126, 126, 126, 0.19995000000000002) => RGBA[125, 125, 125, 51]
-rgba(126, 126, 126, 0.21328000000000003) => RGBA[127, 127, 127, 54]
-rgba(126, 126, 126, 0.22661000000000003) => RGBA[127, 127, 127, 58]
-rgba(126, 126, 126, 0.23994000000000004) => RGBA[125, 125, 125, 61]
-rgba(126, 126, 126, 0.25327000000000005) => RGBA[127, 127, 127, 64]
-rgba(126, 126, 126, 0.26660000000000006) => RGBA[127, 127, 127, 68]
-rgba(126, 126, 126, 0.27993000000000007) => RGBA[125, 125, 125, 71]
-rgba(126, 126, 126, 0.2932600000000001) => RGBA[125, 125, 125, 75]
-rgba(126, 126, 126, 0.3065900000000001) => RGBA[127, 127, 127, 78]
-rgba(126, 126, 126, 0.3199200000000001) => RGBA[125, 125, 125, 81]
-rgba(126, 126, 126, 0.3332500000000001) => RGBA[126, 126, 126, 85]
-rgba(126, 126, 126, 0.3465800000000001) => RGBA[124, 124, 124, 88]
-rgba(126, 126, 126, 0.3599100000000001) => RGBA[124, 124, 124, 92]
-rgba(126, 126, 126, 0.3732400000000001) => RGBA[126, 126, 126, 95]
-rgba(126, 126, 126, 0.38657000000000014) => RGBA[124, 124, 124, 98]
-rgba(126, 126, 126, 0.39990000000000014) => RGBA[125, 125, 125, 102]
-rgba(126, 126, 126, 0.41323000000000015) => RGBA[126, 126, 126, 105]
-rgba(126, 126, 126, 0.42656000000000016) => RGBA[126, 126, 126, 109]
-rgba(126, 126, 126, 0.43989000000000017) => RGBA[125, 125, 125, 112]
-rgba(126, 126, 126, 0.4532200000000002) => RGBA[125, 125, 125, 116]
-rgba(126, 126, 126, 0.4665500000000002) => RGBA[126, 126, 126, 119]
-rgba(126, 126, 126, 0.4798800000000002) => RGBA[125, 125, 125, 122]
-rgba(126, 126, 126, 0.4932100000000002) => RGBA[125, 125, 125, 126]
-rgba(126, 126, 126, 0.5065400000000002) => RGBA[126, 126, 126, 129]
-rgba(126, 126, 126, 0.5198700000000002) => RGBA[126, 126, 126, 133]
-rgba(126, 126, 126, 0.5332000000000001) => RGBA[125, 125, 125, 136]
-rgba(126, 126, 126, 0.5465300000000001) => RGBA[126, 126, 126, 139]
-rgba(126, 126, 126, 0.55986) => RGBA[126, 126, 126, 143]
-rgba(126, 126, 126, 0.57319) => RGBA[125, 125, 125, 146]
-rgba(126, 126, 126, 0.5865199999999999) => RGBA[125, 125, 125, 150]
-rgba(126, 126, 126, 0.5998499999999999) => RGBA[126, 126, 126, 153]
-rgba(126, 126, 126, 0.6131799999999998) => RGBA[125, 125, 125, 156]
-rgba(126, 126, 126, 0.6265099999999998) => RGBA[125, 125, 125, 160]
-rgba(126, 126, 126, 0.6398399999999997) => RGBA[126, 126, 126, 163]
-rgba(126, 126, 126, 0.6531699999999997) => RGBA[126, 126, 126, 167]
-rgba(126, 126, 126, 0.6664999999999996) => RGBA[126, 126, 126, 170]
-rgba(126, 126, 126, 0.6798299999999996) => RGBA[126, 126, 126, 174]
-rgba(126, 126, 126, 0.6931599999999996) => RGBA[125, 125, 125, 177]
-rgba(126, 126, 126, 0.7064899999999995) => RGBA[126, 126, 126, 180]
-rgba(126, 126, 126, 0.7198199999999995) => RGBA[126, 126, 126, 184]
-rgba(126, 126, 126, 0.7331499999999994) => RGBA[125, 125, 125, 187]
-rgba(126, 126, 126, 0.7464799999999994) => RGBA[125, 125, 125, 191]
-rgba(126, 126, 126, 0.7598099999999993) => RGBA[126, 126, 126, 194]
-rgba(126, 126, 126, 0.7731399999999993) => RGBA[125, 125, 125, 197]
-rgba(126, 126, 126, 0.7864699999999992) => RGBA[125, 125, 125, 201]
-rgba(126, 126, 126, 0.7997999999999992) => RGBA[126, 126, 126, 204]
-rgba(126, 126, 126, 0.8131299999999991) => RGBA[126, 126, 126, 208]
-rgba(126, 126, 126, 0.8264599999999991) => RGBA[125, 125, 125, 211]
-rgba(126, 126, 126, 0.839789999999999) => RGBA[126, 126, 126, 214]
-rgba(126, 126, 126, 0.853119999999999) => RGBA[126, 126, 126, 218]
-rgba(126, 126, 126, 0.8664499999999989) => RGBA[125, 125, 125, 221]
-rgba(126, 126, 126, 0.8797799999999989) => RGBA[125, 125, 125, 225]
-rgba(126, 126, 126, 0.8931099999999988) => RGBA[126, 126, 126, 228]
-rgba(126, 126, 126, 0.9064399999999988) => RGBA[126, 126, 126, 232]
-rgba(126, 126, 126, 0.9197699999999988) => RGBA[125, 125, 125, 235]
-rgba(126, 126, 126, 0.9330999999999987) => RGBA[126, 126, 126, 238]
-rgba(126, 126, 126, 0.9464299999999987) => RGBA[126, 126, 126, 242]
-rgba(126, 126, 126, 0.9597599999999986) => RGBA[125, 125, 125, 245]
-rgba(126, 126, 126, 0.9730899999999986) => RGBA[125, 125, 125, 249]
-rgba(126, 126, 126, 0.9864199999999985) => RGBA[126, 126, 126, 252]
-rgba(126, 126, 126, 0.9997499999999985) => RGBA[126, 126, 126, 255]
-rgba(189, 189, 189, 0) => RGBA[0, 0, 0, 0]
-rgba(189, 189, 189, 0.01333) => RGBA[170, 170, 170, 3]
-rgba(189, 189, 189, 0.02666) => RGBA[170, 170, 170, 6]
-rgba(189, 189, 189, 0.03999) => RGBA[178, 178, 178, 10]
-rgba(189, 189, 189, 0.05332) => RGBA[196, 196, 196, 13]
-rgba(189, 189, 189, 0.06665) => RGBA[195, 195, 195, 17]
-rgba(189, 189, 189, 0.07998) => RGBA[191, 191, 191, 20]
-rgba(189, 189, 189, 0.09330999999999999) => RGBA[188, 188, 188, 23]
-rgba(189, 189, 189, 0.10663999999999998) => RGBA[188, 188, 188, 27]
-rgba(189, 189, 189, 0.11996999999999998) => RGBA[187, 187, 187, 30]
-rgba(189, 189, 189, 0.13329999999999997) => RGBA[187, 187, 187, 34]
-rgba(189, 189, 189, 0.14662999999999998) => RGBA[186, 186, 186, 37]
-rgba(189, 189, 189, 0.15996) => RGBA[191, 191, 191, 40]
-rgba(189, 189, 189, 0.17329) => RGBA[191, 191, 191, 44]
-rgba(189, 189, 189, 0.18662) => RGBA[189, 189, 189, 47]
-rgba(189, 189, 189, 0.19995000000000002) => RGBA[190, 190, 190, 51]
-rgba(189, 189, 189, 0.21328000000000003) => RGBA[188, 188, 188, 54]
-rgba(189, 189, 189, 0.22661000000000003) => RGBA[189, 189, 189, 58]
-rgba(189, 189, 189, 0.23994000000000004) => RGBA[188, 188, 188, 61]
-rgba(189, 189, 189, 0.25327000000000005) => RGBA[187, 187, 187, 64]
-rgba(189, 189, 189, 0.26660000000000006) => RGBA[187, 187, 187, 68]
-rgba(189, 189, 189, 0.27993000000000007) => RGBA[190, 190, 190, 71]
-rgba(189, 189, 189, 0.2932600000000001) => RGBA[190, 190, 190, 75]
-rgba(189, 189, 189, 0.3065900000000001) => RGBA[189, 189, 189, 78]
-rgba(189, 189, 189, 0.3199200000000001) => RGBA[188, 188, 188, 81]
-rgba(189, 189, 189, 0.3332500000000001) => RGBA[189, 189, 189, 85]
-rgba(189, 189, 189, 0.3465800000000001) => RGBA[188, 188, 188, 88]
-rgba(189, 189, 189, 0.3599100000000001) => RGBA[188, 188, 188, 92]
-rgba(189, 189, 189, 0.3732400000000001) => RGBA[187, 187, 187, 95]
-rgba(189, 189, 189, 0.38657000000000014) => RGBA[189, 189, 189, 98]
-rgba(189, 189, 189, 0.39990000000000014) => RGBA[190, 190, 190, 102]
-rgba(189, 189, 189, 0.41323000000000015) => RGBA[189, 189, 189, 105]
-rgba(189, 189, 189, 0.42656000000000016) => RGBA[189, 189, 189, 109]
-rgba(189, 189, 189, 0.43989000000000017) => RGBA[188, 188, 188, 112]
-rgba(189, 189, 189, 0.4532200000000002) => RGBA[189, 189, 189, 116]
-rgba(189, 189, 189, 0.4665500000000002) => RGBA[188, 188, 188, 119]
-rgba(189, 189, 189, 0.4798800000000002) => RGBA[188, 188, 188, 122]
-rgba(189, 189, 189, 0.4932100000000002) => RGBA[188, 188, 188, 126]
-rgba(189, 189, 189, 0.5065400000000002) => RGBA[189, 189, 189, 129]
-rgba(189, 189, 189, 0.5198700000000002) => RGBA[189, 189, 189, 133]
-rgba(189, 189, 189, 0.5332000000000001) => RGBA[189, 189, 189, 136]
-rgba(189, 189, 189, 0.5465300000000001) => RGBA[188, 188, 188, 139]
-rgba(189, 189, 189, 0.55986) => RGBA[189, 189, 189, 143]
-rgba(189, 189, 189, 0.57319) => RGBA[188, 188, 188, 146]
-rgba(189, 189, 189, 0.5865199999999999) => RGBA[188, 188, 188, 150]
-rgba(189, 189, 189, 0.5998499999999999) => RGBA[188, 188, 188, 153]
-rgba(189, 189, 189, 0.6131799999999998) => RGBA[189, 189, 189, 156]
-rgba(189, 189, 189, 0.6265099999999998) => RGBA[189, 189, 189, 160]
-rgba(189, 189, 189, 0.6398399999999997) => RGBA[189, 189, 189, 163]
-rgba(189, 189, 189, 0.6531699999999997) => RGBA[189, 189, 189, 167]
-rgba(189, 189, 189, 0.6664999999999996) => RGBA[189, 189, 189, 170]
-rgba(189, 189, 189, 0.6798299999999996) => RGBA[189, 189, 189, 174]
-rgba(189, 189, 189, 0.6931599999999996) => RGBA[188, 188, 188, 177]
-rgba(189, 189, 189, 0.7064899999999995) => RGBA[188, 188, 188, 180]
-rgba(189, 189, 189, 0.7198199999999995) => RGBA[188, 188, 188, 184]
-rgba(189, 189, 189, 0.7331499999999994) => RGBA[189, 189, 189, 187]
-rgba(189, 189, 189, 0.7464799999999994) => RGBA[189, 189, 189, 191]
-rgba(189, 189, 189, 0.7598099999999993) => RGBA[189, 189, 189, 194]
-rgba(189, 189, 189, 0.7731399999999993) => RGBA[188, 188, 188, 197]
-rgba(189, 189, 189, 0.7864699999999992) => RGBA[189, 189, 189, 201]
-rgba(189, 189, 189, 0.7997999999999992) => RGBA[188, 188, 188, 204]
-rgba(189, 189, 189, 0.8131299999999991) => RGBA[188, 188, 188, 208]
-rgba(189, 189, 189, 0.8264599999999991) => RGBA[188, 188, 188, 211]
-rgba(189, 189, 189, 0.839789999999999) => RGBA[189, 189, 189, 214]
-rgba(189, 189, 189, 0.853119999999999) => RGBA[189, 189, 189, 218]
-rgba(189, 189, 189, 0.8664499999999989) => RGBA[189, 189, 189, 221]
-rgba(189, 189, 189, 0.8797799999999989) => RGBA[189, 189, 189, 225]
-rgba(189, 189, 189, 0.8931099999999988) => RGBA[189, 189, 189, 228]
-rgba(189, 189, 189, 0.9064399999999988) => RGBA[189, 189, 189, 232]
-rgba(189, 189, 189, 0.9197699999999988) => RGBA[188, 188, 188, 235]
-rgba(189, 189, 189, 0.9330999999999987) => RGBA[188, 188, 188, 238]
-rgba(189, 189, 189, 0.9464299999999987) => RGBA[188, 188, 188, 242]
-rgba(189, 189, 189, 0.9597599999999986) => RGBA[189, 189, 189, 245]
-rgba(189, 189, 189, 0.9730899999999986) => RGBA[189, 189, 189, 249]
-rgba(189, 189, 189, 0.9864199999999985) => RGBA[189, 189, 189, 252]
-rgba(189, 189, 189, 0.9997499999999985) => RGBA[189, 189, 189, 255]
-rgba(252, 252, 252, 0) => RGBA[0, 0, 0, 0]
-rgba(252, 252, 252, 0.01333) => RGBA[255, 255, 255, 3]
-rgba(252, 252, 252, 0.02666) => RGBA[255, 255, 255, 6]
-rgba(252, 252, 252, 0.03999) => RGBA[255, 255, 255, 10]
-rgba(252, 252, 252, 0.05332) => RGBA[255, 255, 255, 13]
-rgba(252, 252, 252, 0.06665) => RGBA[255, 255, 255, 17]
-rgba(252, 252, 252, 0.07998) => RGBA[255, 255, 255, 20]
-rgba(252, 252, 252, 0.09330999999999999) => RGBA[255, 255, 255, 23]
-rgba(252, 252, 252, 0.10663999999999998) => RGBA[255, 255, 255, 27]
-rgba(252, 252, 252, 0.11996999999999998) => RGBA[255, 255, 255, 30]
-rgba(252, 252, 252, 0.13329999999999997) => RGBA[255, 255, 255, 34]
-rgba(252, 252, 252, 0.14662999999999998) => RGBA[255, 255, 255, 37]
-rgba(252, 252, 252, 0.15996) => RGBA[255, 255, 255, 40]
-rgba(252, 252, 252, 0.17329) => RGBA[249, 249, 249, 44]
-rgba(252, 252, 252, 0.18662) => RGBA[249, 249, 249, 47]
-rgba(252, 252, 252, 0.19995000000000002) => RGBA[250, 250, 250, 51]
-rgba(252, 252, 252, 0.21328000000000003) => RGBA[250, 250, 250, 54]
-rgba(252, 252, 252, 0.22661000000000003) => RGBA[250, 250, 250, 58]
-rgba(252, 252, 252, 0.23994000000000004) => RGBA[250, 250, 250, 61]
-rgba(252, 252, 252, 0.25327000000000005) => RGBA[251, 251, 251, 64]
-rgba(252, 252, 252, 0.26660000000000006) => RGBA[251, 251, 251, 68]
-rgba(252, 252, 252, 0.27993000000000007) => RGBA[251, 251, 251, 71]
-rgba(252, 252, 252, 0.2932600000000001) => RGBA[251, 251, 251, 75]
-rgba(252, 252, 252, 0.3065900000000001) => RGBA[251, 251, 251, 78]
-rgba(252, 252, 252, 0.3199200000000001) => RGBA[251, 251, 251, 81]
-rgba(252, 252, 252, 0.3332500000000001) => RGBA[252, 252, 252, 85]
-rgba(252, 252, 252, 0.3465800000000001) => RGBA[252, 252, 252, 88]
-rgba(252, 252, 252, 0.3599100000000001) => RGBA[252, 252, 252, 92]
-rgba(252, 252, 252, 0.3732400000000001) => RGBA[252, 252, 252, 95]
-rgba(252, 252, 252, 0.38657000000000014) => RGBA[252, 252, 252, 98]
-rgba(252, 252, 252, 0.39990000000000014) => RGBA[252, 252, 252, 102]
-rgba(252, 252, 252, 0.41323000000000015) => RGBA[252, 252, 252, 105]
-rgba(252, 252, 252, 0.42656000000000016) => RGBA[252, 252, 252, 109]
-rgba(252, 252, 252, 0.43989000000000017) => RGBA[252, 252, 252, 112]
-rgba(252, 252, 252, 0.4532200000000002) => RGBA[252, 252, 252, 116]
-rgba(252, 252, 252, 0.4665500000000002) => RGBA[252, 252, 252, 119]
-rgba(252, 252, 252, 0.4798800000000002) => RGBA[252, 252, 252, 122]
-rgba(252, 252, 252, 0.4932100000000002) => RGBA[252, 252, 252, 126]
-rgba(252, 252, 252, 0.5065400000000002) => RGBA[251, 251, 251, 129]
-rgba(252, 252, 252, 0.5198700000000002) => RGBA[251, 251, 251, 133]
-rgba(252, 252, 252, 0.5332000000000001) => RGBA[251, 251, 251, 136]
-rgba(252, 252, 252, 0.5465300000000001) => RGBA[251, 251, 251, 139]
-rgba(252, 252, 252, 0.55986) => RGBA[251, 251, 251, 143]
-rgba(252, 252, 252, 0.57319) => RGBA[251, 251, 251, 146]
-rgba(252, 252, 252, 0.5865199999999999) => RGBA[251, 251, 251, 150]
-rgba(252, 252, 252, 0.5998499999999999) => RGBA[251, 251, 251, 153]
-rgba(252, 252, 252, 0.6131799999999998) => RGBA[251, 251, 251, 156]
-rgba(252, 252, 252, 0.6265099999999998) => RGBA[251, 251, 251, 160]
-rgba(252, 252, 252, 0.6398399999999997) => RGBA[251, 251, 251, 163]
-rgba(252, 252, 252, 0.6531699999999997) => RGBA[251, 251, 251, 167]
-rgba(252, 252, 252, 0.6664999999999996) => RGBA[252, 252, 252, 170]
-rgba(252, 252, 252, 0.6798299999999996) => RGBA[252, 252, 252, 174]
-rgba(252, 252, 252, 0.6931599999999996) => RGBA[252, 252, 252, 177]
-rgba(252, 252, 252, 0.7064899999999995) => RGBA[252, 252, 252, 180]
-rgba(252, 252, 252, 0.7198199999999995) => RGBA[252, 252, 252, 184]
-rgba(252, 252, 252, 0.7331499999999994) => RGBA[252, 252, 252, 187]
-rgba(252, 252, 252, 0.7464799999999994) => RGBA[252, 252, 252, 191]
-rgba(252, 252, 252, 0.7598099999999993) => RGBA[252, 252, 252, 194]
-rgba(252, 252, 252, 0.7731399999999993) => RGBA[252, 252, 252, 197]
-rgba(252, 252, 252, 0.7864699999999992) => RGBA[252, 252, 252, 201]
-rgba(252, 252, 252, 0.7997999999999992) => RGBA[252, 252, 252, 204]
-rgba(252, 252, 252, 0.8131299999999991) => RGBA[252, 252, 252, 208]
-rgba(252, 252, 252, 0.8264599999999991) => RGBA[252, 252, 252, 211]
-rgba(252, 252, 252, 0.839789999999999) => RGBA[251, 251, 251, 214]
-rgba(252, 252, 252, 0.853119999999999) => RGBA[251, 251, 251, 218]
-rgba(252, 252, 252, 0.8664499999999989) => RGBA[251, 251, 251, 221]
-rgba(252, 252, 252, 0.8797799999999989) => RGBA[251, 251, 251, 225]
-rgba(252, 252, 252, 0.8931099999999988) => RGBA[251, 251, 251, 228]
-rgba(252, 252, 252, 0.9064399999999988) => RGBA[251, 251, 251, 232]
-rgba(252, 252, 252, 0.9197699999999988) => RGBA[251, 251, 251, 235]
-rgba(252, 252, 252, 0.9330999999999987) => RGBA[251, 251, 251, 238]
-rgba(252, 252, 252, 0.9464299999999987) => RGBA[251, 251, 251, 242]
-rgba(252, 252, 252, 0.9597599999999986) => RGBA[251, 251, 251, 245]
-rgba(252, 252, 252, 0.9730899999999986) => RGBA[251, 251, 251, 249]
-rgba(252, 252, 252, 0.9864199999999985) => RGBA[251, 251, 251, 252]
-rgba(252, 252, 252, 0.9997499999999985) => RGBA[252, 252, 252, 255]
 PASS successfullyParsed is true
 
 TEST COMPLETE
index 81a3812..9a3b2ef 100644 (file)
@@ -98,13 +98,4 @@ shouldBe("parse('rgba(0, 0, 0, 0.997)')", "'RGBA[0, 0, 0, 255]'");
 shouldBe("parse('rgba(0, 0, 0, 0.998)')", "'RGBA[0, 0, 0, 255]'");
 shouldBe("parse('rgba(0, 0, 0, 0.999)')", "'RGBA[0, 0, 0, 255]'");
 
-// Dump a bunch of colors
-for (g = 0; g < 256; g += 63) {
-    for (a = 0.0; a < 1.0; a += 0.01333) {
-        rgba = 'rgba(' + g + ', ' + g + ', ' + g + ', ' + a + ')';
-        result = parse(rgba);
-        debug(rgba + ' => ' + result);
-    }
-}
-
 var successfullyParsed = true;
index 12ddb1d..f0b9c58 100644 (file)
@@ -1,3 +1,13 @@
+2011-03-29  Matthew Delaney  <mdelaney@apple.com>
+
+        Reviewed by Simon Fraser.
+
+        Use the Accelerate vImage vectorized (un)premultiplyImageData functions for ImageBufferCG
+
+        https://bugs.webkit.org/show_bug.cgi?id=53134
+
+        * wtf/Platform.h: Added in WTF flag for using the Accelerate framework
+
 2011-03-30  Steve Falkenburg  <sfalken@apple.com>
 
         Reviewed by Adam Roben.
index f03a3d4..e40b1a6 100644 (file)
 #define HAVE_SYS_PARAM_H 1
 #define HAVE_SYS_TIME_H 1
 #define HAVE_SYS_TIMEB_H 1
+#define WTF_USE_ACCELERATE 1
 
 #if !defined(TARGETING_TIGER) && !defined(TARGETING_LEOPARD)
 
index b6721cb..c1dfe5a 100644 (file)
@@ -1,3 +1,15 @@
+2011-03-29  Matthew Delaney  <mdelaney@apple.com>
+
+        Reviewed by Simon Fraser.
+
+        Use the Accelerate vImage vectorized (un)premultiplyImageData functions for ImageBufferCG
+
+        https://bugs.webkit.org/show_bug.cgi?id=53134
+
+        Test: fast/canvas/getPutImageDataPairTest.html
+
+        * platform/graphics/cg/ImageBufferCG.cpp:
+
 2011-03-30  Martin Robinson  <mrobinson@igalia.com>
 
         Try to fix the WinCairo build.
index 3c8f959..d62e66c 100644 (file)
 #include <wtf/Threading.h>
 #include <math.h>
 
+#if USE(ACCELERATE)
+#include <Accelerate/Accelerate.h>
+#endif
+
 #if USE(IOSURFACE_CANVAS_BACKING_STORE)
 #include <IOSurface/IOSurface.h>
 #endif
@@ -54,6 +58,16 @@ using namespace std;
 
 namespace WebCore {
 
+#if USE(ACCELERATE)
+// The vImage unpremultiply routine had a rounding bug before 10.6.7 <rdar://problem/8631548>
+static bool haveVImageRoundingErrorFix()
+{
+    SInt32 version;
+    static bool result = (Gestalt(gestaltSystemVersion, &version) == noErr && version > 0x1066);
+    return result;
+}
+#endif
+
 #if USE(IOSURFACE_CANVAS_BACKING_STORE)
 static const int maxIOSurfaceDimension = 4096;
 
@@ -280,7 +294,7 @@ PassRefPtr<ByteArray> getImageData(const IntRect& rect, const ImageBufferData& i
     int endx = rect.maxX();
     if (endx > size.width())
         endx = size.width();
-    int numColumns = endx - originx;
+    int width = endx - originx;
 
     int originy = rect.y();
     int desty = 0;
@@ -291,8 +305,11 @@ PassRefPtr<ByteArray> getImageData(const IntRect& rect, const ImageBufferData& i
     int endy = rect.maxY();
     if (endy > size.height())
         endy = size.height();
-    int numRows = endy - originy;
-    
+    int height = endy - originy;
+
+    if (width <= 0 || height <= 0)
+        return result.release();
+
     unsigned destBytesPerRow = 4 * rect.width();
     unsigned char* destRows = data + desty * destBytesPerRow + destx * 4;
 
@@ -302,9 +319,27 @@ PassRefPtr<ByteArray> getImageData(const IntRect& rect, const ImageBufferData& i
     if (!accelerateRendering) {
         srcBytesPerRow = 4 * size.width();
         srcRows = reinterpret_cast<unsigned char*>(imageData.m_data) + originy * srcBytesPerRow + originx * 4;
-        
-        for (int y = 0; y < numRows; ++y) {
-            for (int x = 0; x < numColumns; x++) {
+
+#if USE(ACCELERATE)
+        if (multiplied == Unmultiplied && haveVImageRoundingErrorFix()) {
+            vImage_Buffer src;
+            src.height = height;
+            src.width = width;
+            src.rowBytes = srcBytesPerRow;
+            src.data = srcRows;
+
+            vImage_Buffer dst;
+            dst.height = height;
+            dst.width = width;
+            dst.rowBytes = destBytesPerRow;
+            dst.data = destRows;
+
+            vImageUnpremultiplyData_RGBA8888(&src, &dst, kvImageNoFlags);
+            return result.release();
+        }
+#endif
+        for (int y = 0; y < height; ++y) {
+            for (int x = 0; x < width; x++) {
                 int basex = x * 4;
                 unsigned char alpha = srcRows[basex + 3];
                 if (multiplied == Unmultiplied && alpha) {
@@ -325,8 +360,8 @@ PassRefPtr<ByteArray> getImageData(const IntRect& rect, const ImageBufferData& i
         srcBytesPerRow = IOSurfaceGetBytesPerRow(surface);
         srcRows = (unsigned char*)(IOSurfaceGetBaseAddress(surface)) + originy * srcBytesPerRow + originx * 4;
         
-        for (int y = 0; y < numRows; ++y) {
-            for (int x = 0; x < numColumns; x++) {
+        for (int y = 0; y < height; ++y) {
+            for (int x = 0; x < width; x++) {
                 int basex = x * 4;
                 unsigned char alpha = srcRows[basex + 3];
                 if (multiplied == Unmultiplied && alpha) {
@@ -383,7 +418,7 @@ void putImageData(ByteArray*& source, const IntSize& sourceSize, const IntRect&
     int endx = destPoint.x() + sourceRect.maxX();
     ASSERT(endx <= size.width());
 
-    int numColumns = endx - destx;
+    int width = endx - destx;
 
     int originy = sourceRect.y();
     int desty = destPoint.y() + sourceRect.y();
@@ -394,7 +429,10 @@ void putImageData(ByteArray*& source, const IntSize& sourceSize, const IntRect&
 
     int endy = destPoint.y() + sourceRect.maxY();
     ASSERT(endy <= size.height());
-    int numRows = endy - desty;
+    int height = endy - desty;
+
+    if (width <= 0 || height <= 0)
+        return;
 
     unsigned srcBytesPerRow = 4 * sourceSize.width();
     unsigned char* srcRows = source->data() + originy * srcBytesPerRow + originx * 4;
@@ -404,8 +442,27 @@ void putImageData(ByteArray*& source, const IntSize& sourceSize, const IntRect&
     if (!accelerateRendering) {
         destBytesPerRow = 4 * size.width();
         destRows = reinterpret_cast<unsigned char*>(imageData.m_data) + desty * destBytesPerRow + destx * 4;
-        for (int y = 0; y < numRows; ++y) {
-            for (int x = 0; x < numColumns; x++) {
+
+#if USE(ACCELERATE)
+        if (haveVImageRoundingErrorFix() && multiplied == Unmultiplied) {
+            vImage_Buffer src;
+            src.height = height;
+            src.width = width;
+            src.rowBytes = srcBytesPerRow;
+            src.data = srcRows;
+
+            vImage_Buffer dst;
+            dst.height = height;
+            dst.width = width;
+            dst.rowBytes = destBytesPerRow;
+            dst.data = destRows;
+
+            vImagePremultiplyData_RGBA8888(&src, &dst, kvImageNoFlags);
+            return;
+        }
+#endif
+        for (int y = 0; y < height; ++y) {
+            for (int x = 0; x < width; x++) {
                 int basex = x * 4;
                 unsigned char alpha = srcRows[basex + 3];
                 if (multiplied == Unmultiplied && alpha != 255) {
@@ -426,8 +483,8 @@ void putImageData(ByteArray*& source, const IntSize& sourceSize, const IntRect&
         destBytesPerRow = IOSurfaceGetBytesPerRow(surface);
         destRows = (unsigned char*)(IOSurfaceGetBaseAddress(surface)) + desty * destBytesPerRow + destx * 4;
         
-        for (int y = 0; y < numRows; ++y) {
-            for (int x = 0; x < numColumns; x++) {
+        for (int y = 0; y < height; ++y) {
+            for (int x = 0; x < width; x++) {
                 int basex = x * 4;
                 unsigned char alpha = srcRows[basex + 3];
                 if (multiplied == Unmultiplied && alpha != 255) {