mirror of
https://github.com/php/php-src.git
synced 2025-08-15 13:38:49 +02:00
Refactor imagegammacorrect()
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.
This commit is contained in:
parent
47f1666f7c
commit
65ee87f20d
5 changed files with 81 additions and 7 deletions
16
ext/gd/gd.c
16
ext/gd/gd.c
|
@ -3025,7 +3025,7 @@ PHP_FUNCTION(imagegammacorrect)
|
||||||
zval *IM;
|
zval *IM;
|
||||||
gdImagePtr im;
|
gdImagePtr im;
|
||||||
int i;
|
int i;
|
||||||
double input, output;
|
double input, output, gamma;
|
||||||
|
|
||||||
if (zend_parse_parameters(ZEND_NUM_ARGS(), "rdd", &IM, &input, &output) == FAILURE) {
|
if (zend_parse_parameters(ZEND_NUM_ARGS(), "rdd", &IM, &input, &output) == FAILURE) {
|
||||||
return;
|
return;
|
||||||
|
@ -3036,6 +3036,8 @@ PHP_FUNCTION(imagegammacorrect)
|
||||||
RETURN_FALSE;
|
RETURN_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gamma = input / output;
|
||||||
|
|
||||||
if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
|
if ((im = (gdImagePtr)zend_fetch_resource(Z_RES_P(IM), "Image", le_gd)) == NULL) {
|
||||||
RETURN_FALSE;
|
RETURN_FALSE;
|
||||||
}
|
}
|
||||||
|
@ -3048,9 +3050,9 @@ PHP_FUNCTION(imagegammacorrect)
|
||||||
c = gdImageGetPixel(im, x, y);
|
c = gdImageGetPixel(im, x, y);
|
||||||
gdImageSetPixel(im, x, y,
|
gdImageSetPixel(im, x, y,
|
||||||
gdTrueColorAlpha(
|
gdTrueColorAlpha(
|
||||||
(int) ((pow((pow((gdTrueColorGetRed(c) / 255.0), input)), 1.0 / output) * 255) + .5),
|
(int) ((pow((gdTrueColorGetRed(c) / 255.0), gamma) * 255) + .5),
|
||||||
(int) ((pow((pow((gdTrueColorGetGreen(c) / 255.0), input)), 1.0 / output) * 255) + .5),
|
(int) ((pow((gdTrueColorGetGreen(c) / 255.0), gamma) * 255) + .5),
|
||||||
(int) ((pow((pow((gdTrueColorGetBlue(c) / 255.0), input)), 1.0 / output) * 255) + .5),
|
(int) ((pow((gdTrueColorGetBlue(c) / 255.0), gamma) * 255) + .5),
|
||||||
gdTrueColorGetAlpha(c)
|
gdTrueColorGetAlpha(c)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
@ -3060,9 +3062,9 @@ PHP_FUNCTION(imagegammacorrect)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < gdImageColorsTotal(im); i++) {
|
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->red[i] = (int)((pow((im->red[i] / 255.0), gamma) * 255) + .5);
|
||||||
im->green[i] = (int)((pow((pow((im->green[i] / 255.0), input)), 1.0 / output) * 255) + .5);
|
im->green[i] = (int)((pow((im->green[i] / 255.0), gamma) * 255) + .5);
|
||||||
im->blue[i] = (int)((pow((pow((im->blue[i] / 255.0), input)), 1.0 / output) * 255) + .5);
|
im->blue[i] = (int)((pow((im->blue[i] / 255.0), gamma) * 255) + .5);
|
||||||
}
|
}
|
||||||
|
|
||||||
RETURN_TRUE;
|
RETURN_TRUE;
|
||||||
|
|
72
ext/gd/tests/imagegammacorrect_variation2.phpt
Normal file
72
ext/gd/tests/imagegammacorrect_variation2.phpt
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
--TEST--
|
||||||
|
Apply imagegammacorrect() to a step wedge
|
||||||
|
--SKIPIF--
|
||||||
|
<?php
|
||||||
|
if (!extension_loaded('gd')) die('skip gd extension not available');
|
||||||
|
?>
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
require __DIR__ . DIRECTORY_SEPARATOR . 'func.inc';
|
||||||
|
|
||||||
|
test_gamma_both(1, 2);
|
||||||
|
test_gamma_both(1, 1);
|
||||||
|
test_gamma_both(2, 1);
|
||||||
|
|
||||||
|
function test_gamma_both($in, $out)
|
||||||
|
{
|
||||||
|
test_gamma($in, $out, 'imagecreate');
|
||||||
|
test_gamma($in, $out, 'imagecreatetruecolor');
|
||||||
|
}
|
||||||
|
|
||||||
|
function test_gamma($in, $out, $constructor)
|
||||||
|
{
|
||||||
|
$im = $constructor(640, 480);
|
||||||
|
for ($j = 0; $j < 4; $j++) {
|
||||||
|
for ($i = 0; $i < 32; $i++) {
|
||||||
|
draw_cell($im, $i, $j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
imagegammacorrect($im, $in, $out);
|
||||||
|
|
||||||
|
$filename = __DIR__ . DIRECTORY_SEPARATOR
|
||||||
|
. "imagegammacorrect_variation2_{$in}_{$out}.png";
|
||||||
|
$kind = $constructor === 'imagecreate' ? 'palette' : 'truecolor';
|
||||||
|
echo "$kind gamma ($in, $out): ";
|
||||||
|
test_image_equals_file($filename, $im);
|
||||||
|
}
|
||||||
|
|
||||||
|
function draw_cell($im, $x, $y)
|
||||||
|
{
|
||||||
|
$x1 = 20 * $x;
|
||||||
|
$y1 = 120 * $y;
|
||||||
|
$x2 = $x1 + 19;
|
||||||
|
$y2 = $y1 + 119;
|
||||||
|
$color = cell_color($im, $x, $y);
|
||||||
|
imagefilledrectangle($im, $x1,$y1, $x2,$y2, $color);
|
||||||
|
}
|
||||||
|
|
||||||
|
function cell_color($im, $x, $y)
|
||||||
|
{
|
||||||
|
$channel = 8 * $x + 4;
|
||||||
|
switch ($y) {
|
||||||
|
case 0:
|
||||||
|
return imagecolorallocate($im, $channel, $channel, $channel);
|
||||||
|
case 1:
|
||||||
|
return imagecolorallocate($im, $channel, 0, 0);
|
||||||
|
case 2:
|
||||||
|
return imagecolorallocate($im, 0, $channel, 0);
|
||||||
|
case 3:
|
||||||
|
return imagecolorallocate($im, 0, 0, $channel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
===DONE===
|
||||||
|
--EXPECT--
|
||||||
|
palette gamma (1, 2): The images are equal.
|
||||||
|
truecolor gamma (1, 2): The images are equal.
|
||||||
|
palette gamma (1, 1): The images are equal.
|
||||||
|
truecolor gamma (1, 1): The images are equal.
|
||||||
|
palette gamma (2, 1): The images are equal.
|
||||||
|
truecolor gamma (2, 1): The images are equal.
|
||||||
|
===DONE===
|
BIN
ext/gd/tests/imagegammacorrect_variation2_1_1.png
Normal file
BIN
ext/gd/tests/imagegammacorrect_variation2_1_1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2 KiB |
BIN
ext/gd/tests/imagegammacorrect_variation2_1_2.png
Normal file
BIN
ext/gd/tests/imagegammacorrect_variation2_1_2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.1 KiB |
BIN
ext/gd/tests/imagegammacorrect_variation2_2_1.png
Normal file
BIN
ext/gd/tests/imagegammacorrect_variation2_2_1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.1 KiB |
Loading…
Add table
Add a link
Reference in a new issue