mirror of
https://github.com/php/php-src.git
synced 2024-12-18 06:21:41 +08:00
Merge branch 'PHP-7.0' into PHP-7.1
* PHP-7.0: Fixed bug #65148 (imagerotate may alter image dimensions)
This commit is contained in:
commit
9c79de4d62
3
NEWS
3
NEWS
@ -19,6 +19,9 @@ PHP NEWS
|
||||
. Fixed bug #75301 (Exif extension has built in revision version). (Peter
|
||||
Kokot)
|
||||
|
||||
- GD:
|
||||
. Fixed bug #65148 (imagerotate may alter image dimensions). (cmb)
|
||||
|
||||
- intl:
|
||||
. Fixed bug #75317 (UConverter::setDestinationEncoding changes source instead
|
||||
of destination). (andrewnester)
|
||||
|
@ -1709,13 +1709,28 @@ gdImagePtr gdImageScale(const gdImagePtr src, const unsigned int new_width, cons
|
||||
return im_scaled;
|
||||
}
|
||||
|
||||
static int gdRotatedImageSize(gdImagePtr src, const float angle, gdRectPtr bbox)
|
||||
{
|
||||
gdRect src_area;
|
||||
double m[6];
|
||||
|
||||
gdAffineRotate(m, angle);
|
||||
src_area.x = 0;
|
||||
src_area.y = 0;
|
||||
src_area.width = gdImageSX(src);
|
||||
src_area.height = gdImageSY(src);
|
||||
if (gdTransformAffineBoundingBox(&src_area, m, bbox) != GD_TRUE) {
|
||||
return GD_FALSE;
|
||||
}
|
||||
|
||||
return GD_TRUE;
|
||||
}
|
||||
|
||||
gdImagePtr gdImageRotateNearestNeighbour(gdImagePtr src, const float degrees, const int bgColor)
|
||||
{
|
||||
float _angle = ((float) (-degrees / 180.0f) * (float)M_PI);
|
||||
const int src_w = gdImageSX(src);
|
||||
const int src_h = gdImageSY(src);
|
||||
const unsigned int new_width = (unsigned int)(abs((int)(src_w * cos(_angle))) + abs((int)(src_h * sin(_angle))) + 0.5f);
|
||||
const unsigned int new_height = (unsigned int)(abs((int)(src_w * sin(_angle))) + abs((int)(src_h * cos(_angle))) + 0.5f);
|
||||
const gdFixed f_0_5 = gd_ftofx(0.5f);
|
||||
const gdFixed f_H = gd_itofx(src_h/2);
|
||||
const gdFixed f_W = gd_itofx(src_w/2);
|
||||
@ -1726,6 +1741,12 @@ gdImagePtr gdImageRotateNearestNeighbour(gdImagePtr src, const float degrees, co
|
||||
unsigned int dst_offset_y = 0;
|
||||
unsigned int i;
|
||||
gdImagePtr dst;
|
||||
gdRect bbox;
|
||||
int new_height, new_width;
|
||||
|
||||
gdRotatedImageSize(src, degrees, &bbox);
|
||||
new_width = bbox.width;
|
||||
new_height = bbox.height;
|
||||
|
||||
if (new_width == 0 || new_height == 0) {
|
||||
return NULL;
|
||||
@ -1768,8 +1789,6 @@ gdImagePtr gdImageRotateGeneric(gdImagePtr src, const float degrees, const int b
|
||||
const int angle_rounded = (int)floor(degrees * 100);
|
||||
const int src_w = gdImageSX(src);
|
||||
const int src_h = gdImageSY(src);
|
||||
const unsigned int new_width = (unsigned int)(abs((int)(src_w * cos(_angle))) + abs((int)(src_h * sin(_angle))) + 0.5f);
|
||||
const unsigned int new_height = (unsigned int)(abs((int)(src_w * sin(_angle))) + abs((int)(src_h * cos(_angle))) + 0.5f);
|
||||
const gdFixed f_0_5 = gd_ftofx(0.5f);
|
||||
const gdFixed f_H = gd_itofx(src_h/2);
|
||||
const gdFixed f_W = gd_itofx(src_w/2);
|
||||
@ -1780,6 +1799,8 @@ gdImagePtr gdImageRotateGeneric(gdImagePtr src, const float degrees, const int b
|
||||
unsigned int dst_offset_y = 0;
|
||||
unsigned int i;
|
||||
gdImagePtr dst;
|
||||
int new_width, new_height;
|
||||
gdRect bbox;
|
||||
|
||||
const gdFixed f_slop_y = f_sin;
|
||||
const gdFixed f_slop_x = f_cos;
|
||||
@ -1792,6 +1813,10 @@ gdImagePtr gdImageRotateGeneric(gdImagePtr src, const float degrees, const int b
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gdRotatedImageSize(src, degrees, &bbox);
|
||||
new_width = bbox.width;
|
||||
new_height = bbox.height;
|
||||
|
||||
dst = gdImageCreateTrueColor(new_width, new_height);
|
||||
if (!dst) {
|
||||
return NULL;
|
||||
@ -1831,8 +1856,7 @@ gdImagePtr gdImageRotateBilinear(gdImagePtr src, const float degrees, const int
|
||||
float _angle = (float)((- degrees / 180.0f) * M_PI);
|
||||
const unsigned int src_w = gdImageSX(src);
|
||||
const unsigned int src_h = gdImageSY(src);
|
||||
unsigned int new_width = abs((int)(src_w*cos(_angle))) + abs((int)(src_h*sin(_angle) + 0.5f));
|
||||
unsigned int new_height = abs((int)(src_w*sin(_angle))) + abs((int)(src_h*cos(_angle) + 0.5f));
|
||||
unsigned int new_width, new_height;
|
||||
const gdFixed f_0_5 = gd_ftofx(0.5f);
|
||||
const gdFixed f_H = gd_itofx(src_h/2);
|
||||
const gdFixed f_W = gd_itofx(src_w/2);
|
||||
@ -1844,6 +1868,12 @@ gdImagePtr gdImageRotateBilinear(gdImagePtr src, const float degrees, const int
|
||||
unsigned int dst_offset_y = 0;
|
||||
unsigned int src_offset_x, src_offset_y;
|
||||
gdImagePtr dst;
|
||||
gdRect bbox;
|
||||
|
||||
gdRotatedImageSize(src, degrees, &bbox);
|
||||
|
||||
new_width = bbox.width;
|
||||
new_height = bbox.height;
|
||||
|
||||
dst = gdImageCreateTrueColor(new_width, new_height);
|
||||
if (dst == NULL) {
|
||||
@ -1863,7 +1893,7 @@ gdImagePtr gdImageRotateBilinear(gdImagePtr src, const float degrees, const int
|
||||
const unsigned int m = gd_fxtoi(f_m);
|
||||
const unsigned int n = gd_fxtoi(f_n);
|
||||
|
||||
if ((m > 0) && (m < src_h - 1) && (n > 0) && (n < src_w - 1)) {
|
||||
if ((m >= 0) && (m < src_h - 1) && (n >= 0) && (n < src_w - 1)) {
|
||||
const gdFixed f_f = f_m - gd_itofx(m);
|
||||
const gdFixed f_g = f_n - gd_itofx(n);
|
||||
const gdFixed f_w1 = gd_mulfx(f_1-f_f, f_1-f_g);
|
||||
@ -1871,11 +1901,6 @@ gdImagePtr gdImageRotateBilinear(gdImagePtr src, const float degrees, const int
|
||||
const gdFixed f_w3 = gd_mulfx(f_f, f_1-f_g);
|
||||
const gdFixed f_w4 = gd_mulfx(f_f, f_g);
|
||||
|
||||
if (n < src_w - 1) {
|
||||
src_offset_x = n + 1;
|
||||
src_offset_y = m;
|
||||
}
|
||||
|
||||
if (m < src_h-1) {
|
||||
src_offset_x = n;
|
||||
src_offset_y = m + 1;
|
||||
@ -1890,13 +1915,13 @@ gdImagePtr gdImageRotateBilinear(gdImagePtr src, const float degrees, const int
|
||||
register int pixel2, pixel3, pixel4;
|
||||
|
||||
if (src_offset_y + 1 >= src_h) {
|
||||
pixel2 = bgColor;
|
||||
pixel3 = bgColor;
|
||||
pixel4 = bgColor;
|
||||
pixel2 = pixel1;
|
||||
pixel3 = pixel1;
|
||||
pixel4 = pixel1;
|
||||
} else if (src_offset_x + 1 >= src_w) {
|
||||
pixel2 = bgColor;
|
||||
pixel3 = bgColor;
|
||||
pixel4 = bgColor;
|
||||
pixel2 = pixel1;
|
||||
pixel3 = pixel1;
|
||||
pixel4 = pixel1;
|
||||
} else {
|
||||
pixel2 = src->tpixels[src_offset_y][src_offset_x + 1];
|
||||
pixel3 = src->tpixels[src_offset_y + 1][src_offset_x];
|
||||
@ -1946,8 +1971,7 @@ gdImagePtr gdImageRotateBicubicFixed(gdImagePtr src, const float degrees, const
|
||||
const float _angle = (float)((- degrees / 180.0f) * M_PI);
|
||||
const int src_w = gdImageSX(src);
|
||||
const int src_h = gdImageSY(src);
|
||||
const unsigned int new_width = abs((int)(src_w*cos(_angle))) + abs((int)(src_h*sin(_angle) + 0.5f));
|
||||
const unsigned int new_height = abs((int)(src_w*sin(_angle))) + abs((int)(src_h*cos(_angle) + 0.5f));
|
||||
unsigned int new_width, new_height;
|
||||
const gdFixed f_0_5 = gd_ftofx(0.5f);
|
||||
const gdFixed f_H = gd_itofx(src_h/2);
|
||||
const gdFixed f_W = gd_itofx(src_w/2);
|
||||
@ -1963,7 +1987,11 @@ gdImagePtr gdImageRotateBicubicFixed(gdImagePtr src, const float degrees, const
|
||||
unsigned int dst_offset_y = 0;
|
||||
unsigned int i;
|
||||
gdImagePtr dst;
|
||||
gdRect bbox;
|
||||
|
||||
gdRotatedImageSize(src, degrees, &bbox);
|
||||
new_width = bbox.width;
|
||||
new_height = bbox.height;
|
||||
dst = gdImageCreateTrueColor(new_width, new_height);
|
||||
|
||||
if (dst == NULL) {
|
||||
@ -2206,8 +2234,11 @@ gdImagePtr gdImageRotateBicubicFixed(gdImagePtr src, const float degrees, const
|
||||
|
||||
gdImagePtr gdImageRotateInterpolated(const gdImagePtr src, const float angle, int bgcolor)
|
||||
{
|
||||
const int angle_rounded = (int)floor(angle * 100);
|
||||
|
||||
/* round to two decimals and keep the 100x multiplication to use it in the common square angles
|
||||
case later. Keep the two decimal precisions so smaller rotation steps can be done, useful for
|
||||
slow animations, f.e. */
|
||||
const int angle_rounded = fmod((int) floorf(angle * 100), 360 * 100);
|
||||
|
||||
if (bgcolor < 0) {
|
||||
return NULL;
|
||||
}
|
||||
@ -2224,6 +2255,18 @@ gdImagePtr gdImageRotateInterpolated(const gdImagePtr src, const float angle, in
|
||||
|
||||
/* no interpolation needed here */
|
||||
switch (angle_rounded) {
|
||||
case 0: {
|
||||
gdImagePtr dst = gdImageCreateTrueColor(src->sx, src->sy);
|
||||
if (dst == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
dst->transparent = src->transparent;
|
||||
dst->saveAlphaFlag = 1;
|
||||
dst->alphaBlendingFlag = gdEffectReplace;
|
||||
|
||||
gdImageCopy(dst, src, 0,0,0,0,src->sx,src->sy);
|
||||
return dst;
|
||||
}
|
||||
case -27000:
|
||||
case 9000:
|
||||
return gdImageRotate90(src, 0);
|
||||
|
179
ext/gd/tests/bug65148.phpt
Normal file
179
ext/gd/tests/bug65148.phpt
Normal file
@ -0,0 +1,179 @@
|
||||
--TEST--
|
||||
Bug #65148 (imagerotate may alter image dimensions)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded('gd')) die('skip gd extension is not available');
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$interpolations = array(
|
||||
'IMG_BELL' => IMG_BELL,
|
||||
'IMG_BESSEL' => IMG_BESSEL,
|
||||
'IMG_BICUBIC' => IMG_BICUBIC,
|
||||
'IMG_BICUBIC_FIXED' => IMG_BICUBIC_FIXED,
|
||||
'IMG_BILINEAR_FIXED' => IMG_BILINEAR_FIXED,
|
||||
'IMG_BLACKMAN' => IMG_BLACKMAN,
|
||||
'IMG_BOX' => IMG_BOX,
|
||||
'IMG_BSPLINE' => IMG_BSPLINE,
|
||||
'IMG_CATMULLROM' => IMG_CATMULLROM,
|
||||
'IMG_GAUSSIAN' => IMG_GAUSSIAN,
|
||||
'IMG_GENERALIZED_CUBIC' => IMG_GENERALIZED_CUBIC,
|
||||
'IMG_HERMITE' => IMG_HERMITE,
|
||||
'IMG_HAMMING' => IMG_HAMMING,
|
||||
'IMG_HANNING' => IMG_HANNING,
|
||||
'IMG_MITCHELL' => IMG_MITCHELL,
|
||||
'IMG_POWER' => IMG_POWER,
|
||||
'IMG_QUADRATIC' => IMG_QUADRATIC,
|
||||
'IMG_SINC' => IMG_SINC,
|
||||
'IMG_NEAREST_NEIGHBOUR' => IMG_NEAREST_NEIGHBOUR,
|
||||
'IMG_WEIGHTED4' => IMG_WEIGHTED4,
|
||||
'IMG_TRIANGLE' => IMG_TRIANGLE,
|
||||
);
|
||||
|
||||
$img = imagecreate(40, 20);
|
||||
$results = array();
|
||||
|
||||
foreach ($interpolations as $name => $interpolation) {
|
||||
imagesetinterpolation($img, $interpolation);
|
||||
$t = imagecolorallocatealpha($img, 0, 0, 0, 127);
|
||||
$imgr = imagerotate($img, -5, $t);
|
||||
$results[$name] = array('x' => imagesx($imgr), 'y' => imagesy($imgr));
|
||||
imagedestroy($imgr);
|
||||
}
|
||||
|
||||
imagedestroy($img);
|
||||
print_r($results);
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECT--
|
||||
Array
|
||||
(
|
||||
[IMG_BELL] => Array
|
||||
(
|
||||
[x] => 40
|
||||
[y] => 23
|
||||
)
|
||||
|
||||
[IMG_BESSEL] => Array
|
||||
(
|
||||
[x] => 40
|
||||
[y] => 23
|
||||
)
|
||||
|
||||
[IMG_BICUBIC] => Array
|
||||
(
|
||||
[x] => 40
|
||||
[y] => 23
|
||||
)
|
||||
|
||||
[IMG_BICUBIC_FIXED] => Array
|
||||
(
|
||||
[x] => 40
|
||||
[y] => 23
|
||||
)
|
||||
|
||||
[IMG_BILINEAR_FIXED] => Array
|
||||
(
|
||||
[x] => 40
|
||||
[y] => 23
|
||||
)
|
||||
|
||||
[IMG_BLACKMAN] => Array
|
||||
(
|
||||
[x] => 40
|
||||
[y] => 23
|
||||
)
|
||||
|
||||
[IMG_BOX] => Array
|
||||
(
|
||||
[x] => 40
|
||||
[y] => 23
|
||||
)
|
||||
|
||||
[IMG_BSPLINE] => Array
|
||||
(
|
||||
[x] => 40
|
||||
[y] => 23
|
||||
)
|
||||
|
||||
[IMG_CATMULLROM] => Array
|
||||
(
|
||||
[x] => 40
|
||||
[y] => 23
|
||||
)
|
||||
|
||||
[IMG_GAUSSIAN] => Array
|
||||
(
|
||||
[x] => 40
|
||||
[y] => 23
|
||||
)
|
||||
|
||||
[IMG_GENERALIZED_CUBIC] => Array
|
||||
(
|
||||
[x] => 40
|
||||
[y] => 23
|
||||
)
|
||||
|
||||
[IMG_HERMITE] => Array
|
||||
(
|
||||
[x] => 40
|
||||
[y] => 23
|
||||
)
|
||||
|
||||
[IMG_HAMMING] => Array
|
||||
(
|
||||
[x] => 40
|
||||
[y] => 23
|
||||
)
|
||||
|
||||
[IMG_HANNING] => Array
|
||||
(
|
||||
[x] => 40
|
||||
[y] => 23
|
||||
)
|
||||
|
||||
[IMG_MITCHELL] => Array
|
||||
(
|
||||
[x] => 40
|
||||
[y] => 23
|
||||
)
|
||||
|
||||
[IMG_POWER] => Array
|
||||
(
|
||||
[x] => 40
|
||||
[y] => 23
|
||||
)
|
||||
|
||||
[IMG_QUADRATIC] => Array
|
||||
(
|
||||
[x] => 40
|
||||
[y] => 23
|
||||
)
|
||||
|
||||
[IMG_SINC] => Array
|
||||
(
|
||||
[x] => 40
|
||||
[y] => 23
|
||||
)
|
||||
|
||||
[IMG_NEAREST_NEIGHBOUR] => Array
|
||||
(
|
||||
[x] => 40
|
||||
[y] => 23
|
||||
)
|
||||
|
||||
[IMG_WEIGHTED4] => Array
|
||||
(
|
||||
[x] => 40
|
||||
[y] => 23
|
||||
)
|
||||
|
||||
[IMG_TRIANGLE] => Array
|
||||
(
|
||||
[x] => 40
|
||||
[y] => 23
|
||||
)
|
||||
|
||||
)
|
||||
===DONE===
|
Binary file not shown.
Before Width: | Height: | Size: 739 B After Width: | Height: | Size: 741 B |
Loading…
Reference in New Issue
Block a user