Skip to content

Commit 3f9ddeb

Browse files
committed
Merge branch 'PHP-7.2' into PHP-7.3
* PHP-7.2: Fix #73281: imagescale(…, IMG_BILINEAR_FIXED) can cause black border
2 parents 1e40725 + 6b4cdba commit 3f9ddeb

File tree

3 files changed

+57
-81
lines changed

3 files changed

+57
-81
lines changed

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ PHP NEWS
1919
application/octet-stream). (Anatol)
2020

2121
- GD:
22+
. Fixed bug #73281 (imagescale(…, IMG_BILINEAR_FIXED) can cause black border).
23+
(cmb)
2224
. Fixed bug #77272 (imagescale() may return image resource on failure). (cmb)
2325
. Fixed bug #77391 (1bpp BMPs may fail to be loaded). (Romain Déoux, cmb)
2426

ext/gd/libgd/gd_interpolation.c

Lines changed: 10 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -662,43 +662,7 @@ static inline int getPixelOverflowTC(gdImagePtr im, const int x, const int y, co
662662
}
663663
return c;
664664
} else {
665-
register int border = 0;
666-
667-
if (y < im->cy1) {
668-
border = im->tpixels[0][im->cx1];
669-
goto processborder;
670-
}
671-
672-
if (y < im->cy1) {
673-
border = im->tpixels[0][im->cx1];
674-
goto processborder;
675-
}
676-
677-
if (y > im->cy2) {
678-
if (x >= im->cx1 && x <= im->cx1) {
679-
border = im->tpixels[im->cy2][x];
680-
goto processborder;
681-
} else {
682-
return gdTrueColorAlpha(0, 0, 0, 127);
683-
}
684-
}
685-
686-
/* y is bound safe at this point */
687-
if (x < im->cx1) {
688-
border = im->tpixels[y][im->cx1];
689-
goto processborder;
690-
}
691-
692-
if (x > im->cx2) {
693-
border = im->tpixels[y][im->cx2];
694-
}
695-
696-
processborder:
697-
if (border == im->transparent) {
698-
return gdTrueColorAlpha(0, 0, 0, 127);
699-
} else{
700-
return gdTrueColorAlpha(gdTrueColorGetRed(border), gdTrueColorGetGreen(border), gdTrueColorGetBlue(border), 127);
701-
}
665+
return bgColor;
702666
}
703667
}
704668

@@ -713,42 +677,7 @@ static inline int getPixelOverflowPalette(gdImagePtr im, const int x, const int
713677
}
714678
return colorIndex2RGBA(c);
715679
} else {
716-
register int border = 0;
717-
if (y < im->cy1) {
718-
border = gdImageGetPixel(im, im->cx1, 0);
719-
goto processborder;
720-
}
721-
722-
if (y < im->cy1) {
723-
border = gdImageGetPixel(im, im->cx1, 0);
724-
goto processborder;
725-
}
726-
727-
if (y > im->cy2) {
728-
if (x >= im->cx1 && x <= im->cx1) {
729-
border = gdImageGetPixel(im, x, im->cy2);
730-
goto processborder;
731-
} else {
732-
return gdTrueColorAlpha(0, 0, 0, 127);
733-
}
734-
}
735-
736-
/* y is bound safe at this point */
737-
if (x < im->cx1) {
738-
border = gdImageGetPixel(im, im->cx1, y);
739-
goto processborder;
740-
}
741-
742-
if (x > im->cx2) {
743-
border = gdImageGetPixel(im, im->cx2, y);
744-
}
745-
746-
processborder:
747-
if (border == im->transparent) {
748-
return gdTrueColorAlpha(0, 0, 0, 127);
749-
} else{
750-
return colorIndex2RGBcustomA(border, 127);
751-
}
680+
return bgColor;
752681
}
753682
}
754683

@@ -1306,11 +1235,11 @@ static gdImagePtr gdImageScaleBilinearPalette(gdImagePtr im, const unsigned int
13061235
f_b1, f_b2, f_b3, f_b4,
13071236
f_a1, f_a2, f_a3, f_a4;
13081237

1309-
/* zero for the background color, nothig gets outside anyway */
1238+
/* 0 for bgColor; (n,m) is supposed to be valid anyway */
13101239
pixel1 = getPixelOverflowPalette(im, n, m, 0);
1311-
pixel2 = getPixelOverflowPalette(im, n + 1, m, 0);
1312-
pixel3 = getPixelOverflowPalette(im, n, m + 1, 0);
1313-
pixel4 = getPixelOverflowPalette(im, n + 1, m + 1, 0);
1240+
pixel2 = getPixelOverflowPalette(im, n + 1, m, pixel1);
1241+
pixel3 = getPixelOverflowPalette(im, n, m + 1, pixel1);
1242+
pixel4 = getPixelOverflowPalette(im, n + 1, m + 1, pixel1);
13141243

13151244
f_r1 = gd_itofx(gdTrueColorGetRed(pixel1));
13161245
f_r2 = gd_itofx(gdTrueColorGetRed(pixel2));
@@ -1398,11 +1327,11 @@ static gdImagePtr gdImageScaleBilinearTC(gdImagePtr im, const unsigned int new_w
13981327
f_b1, f_b2, f_b3, f_b4,
13991328
f_a1, f_a2, f_a3, f_a4;
14001329
dwSrcTotalOffset = m + n;
1401-
/* 0 for bgColor, nothing gets outside anyway */
1330+
/* 0 for bgColor; (n,m) is supposed to be valid anyway */
14021331
pixel1 = getPixelOverflowTC(im, n, m, 0);
1403-
pixel2 = getPixelOverflowTC(im, n + 1, m, 0);
1404-
pixel3 = getPixelOverflowTC(im, n, m + 1, 0);
1405-
pixel4 = getPixelOverflowTC(im, n + 1, m + 1, 0);
1332+
pixel2 = getPixelOverflowTC(im, n + 1, m, pixel1);
1333+
pixel3 = getPixelOverflowTC(im, n, m + 1, pixel1);
1334+
pixel4 = getPixelOverflowTC(im, n + 1, m + 1, pixel1);
14061335

14071336
f_r1 = gd_itofx(gdTrueColorGetRed(pixel1));
14081337
f_r2 = gd_itofx(gdTrueColorGetRed(pixel2));

ext/gd/tests/bug73281.phpt

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
--TEST--
2+
Bug #73281 (imagescale(…, IMG_BILINEAR_FIXED) can cause black border)
3+
--SKIPIF--
4+
<?php
5+
if (!extension_loaded('gd')) die('skip gd extension not available');
6+
if (!GD_BUNDLED && version_compare(GD_VERSION, '2.2.3', '<=')) die('skip upstream fix not yet released');
7+
?>
8+
--FILE--
9+
<?php
10+
$coordinates = [[0, 0], [0, 199], [199, 199], [199, 0]];
11+
12+
$src = imagecreatetruecolor(100, 100);
13+
$white = imagecolorallocate($src, 255, 255, 255);
14+
imagefilledrectangle($src, 0,0, 99,99, $white);
15+
$dst = imagescale($src, 200, 200, IMG_BILINEAR_FIXED);
16+
echo "truecolor source\n";
17+
foreach ($coordinates as $coordinate) {
18+
list($x, $y) = $coordinate;
19+
printf("%3d, %3d: %x\n", $x, $y, imagecolorat($dst, $x, $y));
20+
}
21+
22+
$src = imagecreate(100, 100);
23+
$white = imagecolorallocate($src, 255, 255, 255);
24+
imagefilledrectangle($src, 0,0, 99,99, $white);
25+
$dst = imagescale($src, 200, 200, IMG_BILINEAR_FIXED);
26+
echo "\npalette source\n";
27+
foreach ($coordinates as $coordinate) {
28+
list($x, $y) = $coordinate;
29+
printf("%3d, %3d: %x\n", $x, $y, imagecolorat($dst, $x, $y));
30+
}
31+
?>
32+
===DONE===
33+
--EXPECT--
34+
truecolor source
35+
0, 0: ffffff
36+
0, 199: ffffff
37+
199, 199: ffffff
38+
199, 0: ffffff
39+
40+
palette source
41+
0, 0: ffffff
42+
0, 199: ffffff
43+
199, 199: ffffff
44+
199, 0: ffffff
45+
===DONE===

0 commit comments

Comments
 (0)