]> granicus.if.org Git - php/commitdiff
Refactor imagegammacorrect()
authorChristoph M. Becker <cmbecker69@gmx.de>
Sun, 25 Sep 2016 07:47:23 +0000 (09:47 +0200)
committerChristoph M. Becker <cmbecker69@gmx.de>
Sun, 25 Sep 2016 09:28:39 +0000 (11:28 +0200)
We apply the law `(b**r)**s == b**(r*s)` which holds for all non-negative b
and positive r,s, so a single pow() suffices. Furthermore, we precompute the
gamma, so the refactored code is simpler and faster.

ext/gd/gd.c
ext/gd/tests/imagegammacorrect_variation2.phpt [new file with mode: 0644]
ext/gd/tests/imagegammacorrect_variation2_1_1.png [new file with mode: 0644]
ext/gd/tests/imagegammacorrect_variation2_1_2.png [new file with mode: 0644]
ext/gd/tests/imagegammacorrect_variation2_2_1.png [new file with mode: 0644]

index 692497d186fa6e9c00a7c66b20b99ae2fe6107fd..b726aab10cdb1140705a19b9cc89456f211ccd94 100644 (file)
@@ -3025,7 +3025,7 @@ PHP_FUNCTION(imagegammacorrect)
        zval *IM;
        gdImagePtr im;
        int i;
-       double input, output;
+       double input, output, gamma;
 
        if (zend_parse_parameters(ZEND_NUM_ARGS(), "rdd", &IM, &input, &output) == FAILURE) {
                return;
@@ -3036,6 +3036,8 @@ PHP_FUNCTION(imagegammacorrect)
                RETURN_FALSE;
        }
 
+       gamma = input / output;
+
        if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
                RETURN_FALSE;
        }
@@ -3048,9 +3050,9 @@ PHP_FUNCTION(imagegammacorrect)
                                c = gdImageGetPixel(im, x, y);
                                gdImageSetPixel(im, x, y,
                                        gdTrueColorAlpha(
-                                               (int) ((pow((pow((gdTrueColorGetRed(c)   / 255.0), input)), 1.0 / output) * 255) + .5),
-                                               (int) ((pow((pow((gdTrueColorGetGreen(c) / 255.0), input)), 1.0 / output) * 255) + .5),
-                                               (int) ((pow((pow((gdTrueColorGetBlue(c)  / 255.0), input)), 1.0 / output) * 255) + .5),
+                                               (int) ((pow((gdTrueColorGetRed(c)   / 255.0), gamma) * 255) + .5),
+                                               (int) ((pow((gdTrueColorGetGreen(c) / 255.0), gamma) * 255) + .5),
+                                               (int) ((pow((gdTrueColorGetBlue(c)  / 255.0), gamma) * 255) + .5),
                                                gdTrueColorGetAlpha(c)
                                        )
                                );
@@ -3060,9 +3062,9 @@ PHP_FUNCTION(imagegammacorrect)
        }
 
        for (i = 0; i < gdImageColorsTotal(im); i++) {
-               im->red[i]   = (int)((pow((pow((im->red[i]   / 255.0), input)), 1.0 / output) * 255) + .5);
-               im->green[i] = (int)((pow((pow((im->green[i] / 255.0), input)), 1.0 / output) * 255) + .5);
-               im->blue[i]  = (int)((pow((pow((im->blue[i]  / 255.0), input)), 1.0 / output) * 255) + .5);
+               im->red[i]   = (int)((pow((im->red[i]   / 255.0), gamma) * 255) + .5);
+               im->green[i] = (int)((pow((im->green[i] / 255.0), gamma) * 255) + .5);
+               im->blue[i]  = (int)((pow((im->blue[i]  / 255.0), gamma) * 255) + .5);
        }
 
        RETURN_TRUE;
diff --git a/ext/gd/tests/imagegammacorrect_variation2.phpt b/ext/gd/tests/imagegammacorrect_variation2.phpt
new file mode 100644 (file)
index 0000000..4a317b5
--- /dev/null
@@ -0,0 +1,72 @@
+--TEST--\r
+Apply imagegammacorrect() to a step wedge\r
+--SKIPIF--\r
+<?php\r
+if (!extension_loaded('gd')) die('skip gd extension not available');\r
+?>\r
+--FILE--\r
+<?php\r
+require __DIR__ . DIRECTORY_SEPARATOR . 'func.inc';\r
+\r
+test_gamma_both(1, 2);\r
+test_gamma_both(1, 1);\r
+test_gamma_both(2, 1);\r
+\r
+function test_gamma_both($in, $out)\r
+{\r
+    test_gamma($in, $out, 'imagecreate');\r
+    test_gamma($in, $out, 'imagecreatetruecolor');\r
+}\r
+\r
+function test_gamma($in, $out, $constructor)\r
+{\r
+    $im = $constructor(640, 480);\r
+    for ($j = 0; $j < 4; $j++) {\r
+        for ($i = 0; $i < 32; $i++) {\r
+            draw_cell($im, $i, $j);\r
+        }\r
+    }\r
+    \r
+    imagegammacorrect($im, $in, $out);\r
+    \r
+    $filename = __DIR__ . DIRECTORY_SEPARATOR\r
+        . "imagegammacorrect_variation2_{$in}_{$out}.png";\r
+    $kind = $constructor === 'imagecreate' ? 'palette' : 'truecolor';\r
+    echo "$kind gamma ($in, $out): ";\r
+    test_image_equals_file($filename, $im);\r
+}\r
+\r
+function draw_cell($im, $x, $y)\r
+{\r
+    $x1 = 20 * $x;\r
+    $y1 = 120 * $y;\r
+    $x2 = $x1 + 19;\r
+    $y2 = $y1 + 119;\r
+    $color = cell_color($im, $x, $y);\r
+    imagefilledrectangle($im, $x1,$y1, $x2,$y2, $color);\r
+}\r
+\r
+function cell_color($im, $x, $y)\r
+{\r
+    $channel = 8 * $x + 4;\r
+    switch ($y) {\r
+        case 0:\r
+            return imagecolorallocate($im, $channel, $channel, $channel);\r
+        case 1:\r
+            return imagecolorallocate($im, $channel, 0, 0);\r
+        case 2:\r
+            return imagecolorallocate($im, 0, $channel, 0);\r
+        case 3:\r
+            return imagecolorallocate($im, 0, 0, $channel);\r
+    }\r
+}\r
+?>\r
+===DONE===\r
+--EXPECT--\r
+palette gamma (1, 2): The images are equal.\r
+truecolor gamma (1, 2): The images are equal.\r
+palette gamma (1, 1): The images are equal.\r
+truecolor gamma (1, 1): The images are equal.\r
+palette gamma (2, 1): The images are equal.\r
+truecolor gamma (2, 1): The images are equal.\r
+===DONE===\r
diff --git a/ext/gd/tests/imagegammacorrect_variation2_1_1.png b/ext/gd/tests/imagegammacorrect_variation2_1_1.png
new file mode 100644 (file)
index 0000000..517010b
Binary files /dev/null and b/ext/gd/tests/imagegammacorrect_variation2_1_1.png differ
diff --git a/ext/gd/tests/imagegammacorrect_variation2_1_2.png b/ext/gd/tests/imagegammacorrect_variation2_1_2.png
new file mode 100644 (file)
index 0000000..9b9d7f0
Binary files /dev/null and b/ext/gd/tests/imagegammacorrect_variation2_1_2.png differ
diff --git a/ext/gd/tests/imagegammacorrect_variation2_2_1.png b/ext/gd/tests/imagegammacorrect_variation2_2_1.png
new file mode 100644 (file)
index 0000000..f7384be
Binary files /dev/null and b/ext/gd/tests/imagegammacorrect_variation2_2_1.png differ