Add imagegetinterpolation()

While `imagesetinterpolation()` is available as of PHP 5.5.0,
there is no according getter function, so users would have to track the
current interpolation method manually.

To remedy this, we introduce `imagegetinterpolation()` as thin wrapper
for `gdImageGetInterpolationMethod()` (which has been introduced with
libgd 2.1.1), and use `im->interpolation_id` as fallback for older
libgd.  Since our bundled libgd does not yet have this function, we add
it.

We also simplify the recently introduced bug79068.phpt, where it is
sufficient to check that the interpolation method has not been changed.
This commit is contained in:
Christoph M. Becker 2020-01-06 12:49:07 +01:00
parent 127d6f3f39
commit 03bd4333f6
12 changed files with 123 additions and 14 deletions

1
NEWS
View File

@ -26,6 +26,7 @@ PHP NEWS
. Made the $num_points parameter of php_imagepolygon optional. (cmb)
. Removed deprecated image2wbmp(). (cmb)
. Removed deprecated png2wbmp() and jpeg2wbmp(). (cmb)
. Added imagegetinterpolation(). (cmb)
- Intl:
. Removed deprecated INTL_IDNA_VARIANT_2003. (cmb)

View File

@ -394,6 +394,8 @@ PHP 8.0 UPGRADE NOTES
imagefilledpolygon() is now optional, i.e. these functions may be called
with either 3 or 4 arguments. If the arguments is omitted, it is calculated
as count($points)/2.
. The function imagegetinterpolation() to get the current interpolation method
has been added.
========================================
10. New Global Constants

View File

@ -120,14 +120,15 @@ AC_DEFUN([PHP_GD_JISX0208],[
])
AC_DEFUN([PHP_GD_CHECK_VERSION],[
PHP_CHECK_LIBRARY(gd, gdImageCreateFromPng, [AC_DEFINE(HAVE_GD_PNG, 1, [ ])], [], [ $GD_SHARED_LIBADD ])
PHP_CHECK_LIBRARY(gd, gdImageCreateFromWebp, [AC_DEFINE(HAVE_GD_WEBP, 1, [ ])], [], [ $GD_SHARED_LIBADD ])
PHP_CHECK_LIBRARY(gd, gdImageCreateFromJpeg, [AC_DEFINE(HAVE_GD_JPG, 1, [ ])], [], [ $GD_SHARED_LIBADD ])
PHP_CHECK_LIBRARY(gd, gdImageCreateFromXpm, [AC_DEFINE(HAVE_GD_XPM, 1, [ ])], [], [ $GD_SHARED_LIBADD ])
PHP_CHECK_LIBRARY(gd, gdImageCreateFromBmp, [AC_DEFINE(HAVE_GD_BMP, 1, [ ])], [], [ $GD_SHARED_LIBADD ])
PHP_CHECK_LIBRARY(gd, gdImageCreateFromTga, [AC_DEFINE(HAVE_GD_TGA, 1, [ ])], [], [ $GD_SHARED_LIBADD ])
PHP_CHECK_LIBRARY(gd, gdImageStringFT, [AC_DEFINE(HAVE_GD_FREETYPE, 1, [ ])], [], [ $GD_SHARED_LIBADD ])
PHP_CHECK_LIBRARY(gd, gdVersionString, [AC_DEFINE(HAVE_GD_LIBVERSION, 1, [ ])], [], [ $GD_SHARED_LIBADD ])
PHP_CHECK_LIBRARY(gd, gdImageCreateFromPng, [AC_DEFINE(HAVE_GD_PNG, 1, [ ])], [], [ $GD_SHARED_LIBADD ])
PHP_CHECK_LIBRARY(gd, gdImageCreateFromWebp, [AC_DEFINE(HAVE_GD_WEBP, 1, [ ])], [], [ $GD_SHARED_LIBADD ])
PHP_CHECK_LIBRARY(gd, gdImageCreateFromJpeg, [AC_DEFINE(HAVE_GD_JPG, 1, [ ])], [], [ $GD_SHARED_LIBADD ])
PHP_CHECK_LIBRARY(gd, gdImageCreateFromXpm, [AC_DEFINE(HAVE_GD_XPM, 1, [ ])], [], [ $GD_SHARED_LIBADD ])
PHP_CHECK_LIBRARY(gd, gdImageCreateFromBmp, [AC_DEFINE(HAVE_GD_BMP, 1, [ ])], [], [ $GD_SHARED_LIBADD ])
PHP_CHECK_LIBRARY(gd, gdImageCreateFromTga, [AC_DEFINE(HAVE_GD_TGA, 1, [ ])], [], [ $GD_SHARED_LIBADD ])
PHP_CHECK_LIBRARY(gd, gdImageStringFT, [AC_DEFINE(HAVE_GD_FREETYPE, 1, [ ])], [], [ $GD_SHARED_LIBADD ])
PHP_CHECK_LIBRARY(gd, gdVersionString, [AC_DEFINE(HAVE_GD_LIBVERSION, 1, [ ])], [], [ $GD_SHARED_LIBADD ])
PHP_CHECK_LIBRARY(gd, gdImageGetInterpolationMethod, [AC_DEFINE(HAVE_GD_GET_INTERPOLATION, 1, [ ])], [], [ $GD_SHARED_LIBADD ])
])
dnl

View File

@ -72,6 +72,7 @@ if (PHP_GD != "no") {
/D HAVE_LIBPNG \
/D HAVE_XPM \
/D HAVE_COLORCLOSESTHWB \
/D HAVE_GD_GET_INTERPOLATION \
/D USE_GD_IOCTX \
/D MSWIN32 \
");

View File

@ -294,6 +294,7 @@ static const zend_function_entry gd_functions[] = {
PHP_FE(imageaffine, arginfo_imageaffine)
PHP_FE(imageaffinematrixconcat, arginfo_imageaffinematrixconcat)
PHP_FE(imageaffinematrixget, arginfo_imageaffinematrixget)
PHP_FE(imagegetinterpolation, arginfo_imagegetinterpolation)
PHP_FE(imagesetinterpolation, arginfo_imagesetinterpolation)
PHP_FE(imagesettile, arginfo_imagesettile)
PHP_FE(imagesetbrush, arginfo_imagesetbrush)
@ -4100,6 +4101,26 @@ PHP_FUNCTION(imageaffinematrixconcat)
}
} /* }}} */
/* {{{ proto resource imagegetinterpolation(resource im)
Get the default interpolation method. */
PHP_FUNCTION(imagegetinterpolation)
{
zval *IM;
gdImagePtr im;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &IM, gd_image_ce) == FAILURE) {
RETURN_THROWS();
}
im = php_gd_libgdimageptr_from_zval_p(IM);
#ifdef HAVE_GD_GET_INTERPOLATION
RETURN_LONG(gdImageGetInterpolationMethod(im));
#else
RETURN_LONG(im->interpolation_id);
#endif
}
/* }}} */
/* {{{ proto resource imagesetinterpolation(resource im [, int method]])
Set the default interpolation method, passing -1 or 0 sets it to the libgd default (bilinear). */
PHP_FUNCTION(imagesetinterpolation)

View File

@ -232,6 +232,8 @@ function imageaffinematrixget(int $type, $options = UNKNOWN): array|false {}
function imageaffinematrixconcat(array $m1, array $m2): array|false {}
function imagegetinterpolation(GdImage $im): int {}
function imagesetinterpolation(GdImage $im, int $method = IMG_BILENEAR_FIXED): bool {}
function imageresolution(GdImage $im, int $res_x = UNKNOWN, int $res_y = UNKNOWN): array|bool {}

View File

@ -556,6 +556,8 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_imageaffinematrixconcat, 0, 2, M
ZEND_ARG_TYPE_INFO(0, m2, IS_ARRAY, 0)
ZEND_END_ARG_INFO()
#define arginfo_imagegetinterpolation arginfo_imagecolorstotal
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_imagesetinterpolation, 0, 1, _IS_BOOL, 0)
ZEND_ARG_OBJ_INFO(0, im, GdImage, 0)
ZEND_ARG_TYPE_INFO(0, method, IS_LONG, 0)

View File

@ -2534,6 +2534,29 @@ int gdImageSetInterpolationMethod(gdImagePtr im, gdInterpolationMethod id)
return 1;
}
/**
* Function: gdImageGetInterpolationMethod
*
* Get the current interpolation method
*
* This is here so that the value can be read via a language or VM with an FFI
* but no (portable) way to extract the value from the struct.
*
* Parameters:
* im - The image.
*
* Returns:
* The current interpolation method.
*
* See also:
* - <gdInterpolationMethod>
* - <gdImageSetInterpolationMethod>
*/
gdInterpolationMethod gdImageGetInterpolationMethod(gdImagePtr im)
{
return im->interpolation_id;
}
#ifdef _MSC_VER
# pragma optimize("", on)
#endif

View File

@ -134,6 +134,7 @@ PHP_FUNCTION(imagescale);
PHP_FUNCTION(imageaffine);
PHP_FUNCTION(imageaffinematrixget);
PHP_FUNCTION(imageaffinematrixconcat);
PHP_FUNCTION(imagegetinterpolation);
PHP_FUNCTION(imagesetinterpolation);
PHP_FUNCTION(imagesetthickness);

View File

@ -6,16 +6,12 @@ if (!extension_loaded('gd')) die('skip gd extension not available');
?>
--FILE--
<?php
require_once __DIR__ . '/func.inc';
$src = imagecreatetruecolor(100, 100);
imagefilledrectangle($src, 0, 0, 99, 99, 0xffffff);
imageline($src, 10, 10, 90, 90, 0x000000);
imagesetinterpolation($src, IMG_BSPLINE);
imageaffine($src, [1, 1, 1, 1, 1, 1]);
$dst = imagerotate($src, 80, 0xffffff);
test_image_equals_file(__DIR__ . '/bug79068.png', $dst);
var_dump(imagegetinterpolation($src) === IMG_BSPLINE);
?>
--EXPECT--
The images are equal.
bool(true)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 798 B

View File

@ -0,0 +1,59 @@
--TEST--
imagegetinterpolation() and imagesetinterpolation() basic test
--SKIPIF--
<?php
if (!extension_loaded('gd')) die('skip gd extension not available');
?>
--FILE--
<?php
$methods = array(
IMG_BELL,
IMG_BESSEL,
IMG_BILINEAR_FIXED,
IMG_BICUBIC,
IMG_BICUBIC_FIXED,
IMG_BLACKMAN,
IMG_BOX,
IMG_BSPLINE,
IMG_CATMULLROM,
IMG_GAUSSIAN,
IMG_GENERALIZED_CUBIC,
IMG_HERMITE,
IMG_HAMMING,
IMG_HANNING,
IMG_MITCHELL,
IMG_NEAREST_NEIGHBOUR,
IMG_POWER,
IMG_QUADRATIC,
IMG_SINC,
IMG_TRIANGLE,
IMG_WEIGHTED4,
);
$im = imagecreate(8, 8);
foreach ($methods as $method) {
imagesetinterpolation($im, $method);
var_dump(imagegetinterpolation($im) === $method);
}
?>
--EXPECT--
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)