Skip to content

Commit 4768348

Browse files
committed
Fix libgd 223: gdImageRotateGeneric() does not properly interpolate
We port the respective upstream fix[1]. We only run the test against bundled libgd, since external libgd may yield different results. Cf. <libgd/libgd@2b26be8>. Closes GH-17380.
1 parent ec90367 commit 4768348

File tree

4 files changed

+32
-16
lines changed

4 files changed

+32
-16
lines changed

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ PHP NEWS
1010
transparency). (cmb)
1111
. Fixed bug GH-17373 (imagefttext() ignores clipping rect for palette
1212
images). (cmb)
13+
. Ported fix for libgd 223 (gdImageRotateGeneric() does not properly
14+
interpolate). (cmb)
1315

1416
- Intl:
1517
. Fixed bug GH-11874 (intl causing segfault in docker images). (nielsdos)

ext/gd/libgd/gd_interpolation.c

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -748,8 +748,8 @@ static int getPixelInterpolateWeight(gdImagePtr im, const double x, const double
748748
*/
749749
int getPixelInterpolated(gdImagePtr im, const double x, const double y, const int bgColor)
750750
{
751-
const int xi=(int)((x) < 0 ? x - 1: x);
752-
const int yi=(int)((y) < 0 ? y - 1: y);
751+
const int xi=(int)(x);
752+
const int yi=(int)(y);
753753
int yii;
754754
int i;
755755
double kernel, kernel_cache_y;
@@ -1713,13 +1713,6 @@ gdImagePtr gdImageRotateGeneric(gdImagePtr src, const float degrees, const int b
17131713
int new_width, new_height;
17141714
gdRect bbox;
17151715

1716-
const gdFixed f_slop_y = f_sin;
1717-
const gdFixed f_slop_x = f_cos;
1718-
const gdFixed f_slop = f_slop_x > 0 && f_slop_y > 0 ?
1719-
(f_slop_x > f_slop_y ? gd_divfx(f_slop_y, f_slop_x) : gd_divfx(f_slop_x, f_slop_y))
1720-
: 0;
1721-
1722-
17231716
if (bgColor < 0) {
17241717
return NULL;
17251718
}
@@ -1745,15 +1738,10 @@ gdImagePtr gdImageRotateGeneric(gdImagePtr src, const float degrees, const int b
17451738
long m = gd_fxtoi(f_m);
17461739
long n = gd_fxtoi(f_n);
17471740

1748-
if ((n <= 0) || (m <= 0) || (m >= src_h) || (n >= src_w)) {
1741+
if (m < -1 || n < -1 || m >= src_h || n >= src_w ) {
17491742
dst->tpixels[dst_offset_y][dst_offset_x++] = bgColor;
1750-
} else if ((n <= 1) || (m <= 1) || (m >= src_h - 1) || (n >= src_w - 1)) {
1751-
register int c = getPixelInterpolated(src, n, m, bgColor);
1752-
c = c | (( gdTrueColorGetAlpha(c) + ((int)(127* gd_fxtof(f_slop)))) << 24);
1753-
1754-
dst->tpixels[dst_offset_y][dst_offset_x++] = _color_blend(bgColor, c);
17551743
} else {
1756-
dst->tpixels[dst_offset_y][dst_offset_x++] = getPixelInterpolated(src, n, m, bgColor);
1744+
dst->tpixels[dst_offset_y][dst_offset_x++] = getPixelInterpolated(src, gd_fxtod(f_n), gd_fxtod(f_m), bgColor);
17571745
}
17581746
}
17591747
dst_offset_y++;

ext/gd/tests/gd223.phpt

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
--TEST--
2+
libgd bug 223 (gdImageRotateGeneric() does not properly interpolate)
3+
--EXTENSIONS--
4+
gd
5+
--SKIPIF--
6+
<?php
7+
if (!GD_BUNDLED) die("skip only for bundled libgd");
8+
?>
9+
--FILE--
10+
<?php
11+
require_once __DIR__ . "/func.inc";
12+
13+
$im = imagecreatetruecolor(64, 64);
14+
for ($j = 0; $j < 64; $j++) {
15+
for ($i = 0; $i < 64; $i++) {
16+
imagesetpixel($im, $i, $j, ($i % 2 || $j % 2) ? 0x000000 : 0xffffff);
17+
}
18+
}
19+
20+
imagesetinterpolation($im, IMG_BICUBIC);
21+
$im = imagerotate($im, 45, 0xff0000);
22+
23+
test_image_equals_file(__DIR__ . "/gd223.png", $im);
24+
?>
25+
--EXPECT--
26+
The images are equal.

ext/gd/tests/gd223.png

9.49 KB
Loading

0 commit comments

Comments
 (0)