summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristoph M. Becker <cmbecker69@gmx.de>2020-06-05 16:36:00 +0200
committerChristoph M. Becker <cmbecker69@gmx.de>2020-06-12 14:05:54 +0200
commit86e1f0ea1197e878a657288562d0a11d6f427a18 (patch)
tree717ad65fa47b384312aac0d94c1e4fbd53e1a5c9
parent7ac0fb5ae48b2513c8949780c2b067be7bfdceb0 (diff)
downloadphp-git-86e1f0ea1197e878a657288562d0a11d6f427a18.tar.gz
Fix #79676: imagescale adds black border with IMG_BICUBIC
We have to loop over all image pixels to avoid the black border. This is also done in external libgd in `_gdScaleOneAxis` and `_gdScalePass`.
-rw-r--r--NEWS3
-rw-r--r--ext/gd/libgd/gd_interpolation.c8
-rw-r--r--ext/gd/tests/bug79676.phpt31
3 files changed, 38 insertions, 4 deletions
diff --git a/NEWS b/NEWS
index f16ac1d9b7..f93fbb35b7 100644
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,9 @@ PHP NEWS
- Filter:
. Fixed bug #73527 (Invalid memory access in php_filter_strip). (cmb)
+- GD:
+ . Fixed bug #79676 (imagescale adds black border with IMG_BICUBIC). (cmb)
+
- OpenSSL:
. Fixed bug #62890 (default_socket_timeout=-1 causes connection to timeout).
(cmb)
diff --git a/ext/gd/libgd/gd_interpolation.c b/ext/gd/libgd/gd_interpolation.c
index d723e652a8..741f45430c 100644
--- a/ext/gd/libgd/gd_interpolation.c
+++ b/ext/gd/libgd/gd_interpolation.c
@@ -931,7 +931,7 @@ static inline void _gdScaleRow(gdImagePtr pSrc, unsigned int src_width, gdImage
int *p_dst_row = dst->tpixels[row];
unsigned int x;
- for (x = 0; x < dst_width - 1; x++) {
+ for (x = 0; x < dst_width; x++) {
register unsigned char r = 0, g = 0, b = 0, a = 0;
const int left = contrib->ContribRow[x].Left;
const int right = contrib->ContribRow[x].Right;
@@ -967,7 +967,7 @@ static inline int _gdScaleHoriz(gdImagePtr pSrc, unsigned int src_width, unsigne
return 0;
}
/* Scale each row */
- for (u = 0; u < dst_height - 1; u++) {
+ for (u = 0; u < dst_height; u++) {
_gdScaleRow(pSrc, src_width, pDst, dst_width, u, contrib);
}
_gdContributionsFree (contrib);
@@ -977,7 +977,7 @@ static inline int _gdScaleHoriz(gdImagePtr pSrc, unsigned int src_width, unsigne
static inline void _gdScaleCol (gdImagePtr pSrc, unsigned int src_width, gdImagePtr pRes, unsigned int dst_width, unsigned int dst_height, unsigned int uCol, LineContribType *contrib)
{
unsigned int y;
- for (y = 0; y < dst_height - 1; y++) {
+ for (y = 0; y < dst_height; y++) {
register unsigned char r = 0, g = 0, b = 0, a = 0;
const int iLeft = contrib->ContribRow[y].Left;
const int iRight = contrib->ContribRow[y].Right;
@@ -1014,7 +1014,7 @@ static inline int _gdScaleVert (const gdImagePtr pSrc, const unsigned int src_wi
return 0;
}
/* scale each column */
- for (u = 0; u < dst_width - 1; u++) {
+ for (u = 0; u < dst_width; u++) {
_gdScaleCol(pSrc, src_width, pDst, dst_width, dst_height, u, contrib);
}
_gdContributionsFree(contrib);
diff --git a/ext/gd/tests/bug79676.phpt b/ext/gd/tests/bug79676.phpt
new file mode 100644
index 0000000000..1187bfa1df
--- /dev/null
+++ b/ext/gd/tests/bug79676.phpt
@@ -0,0 +1,31 @@
+--TEST--
+Bug #79676 (imagescale adds black border with IMG_BICUBIC)
+--SKIPIF--
+<?php
+if (!extension_loaded('gd')) die('skip gd extension not available');
+?>
+--FILE--
+<?php
+function test($image, $desc)
+{
+ echo "$desc - Test Result: ",
+ (imagecolorat($image, imagesx($image) - 1 , imagesy($image) - 1) != 0x000000 ? 'pass' : 'fail'),
+ PHP_EOL;
+}
+
+$size = 32;
+$src = imagecreatetruecolor($size, $size);
+imagefilledrectangle($src, 0, 0, $size - 1 , $size - 1, 0xff00ff);
+
+test($src, 'No scaling');
+test(imagescale($src, $size * 2, $size * 2), 'Scale 200%, default mode');
+test(imagescale($src, $size / 2, $size / 2), 'Scale 50%, default mode');
+test(imagescale($src, $size * 2, $size * 2, IMG_BICUBIC), 'Scale 200%, IMG_BICUBIC mode');
+test(imagescale($src, $size / 2, $size / 2, IMG_BICUBIC), 'Scale 50%, IMG_BICUBIC mode');
+?>
+--EXPECT--
+No scaling - Test Result: pass
+Scale 200%, default mode - Test Result: pass
+Scale 50%, default mode - Test Result: pass
+Scale 200%, IMG_BICUBIC mode - Test Result: pass
+Scale 50%, IMG_BICUBIC mode - Test Result: pass