diff --git a/Zend/Optimizer/zend_func_infos.h b/Zend/Optimizer/zend_func_infos.h index 8ebd9e228728b..d4d820ca82728 100644 --- a/Zend/Optimizer/zend_func_infos.h +++ b/Zend/Optimizer/zend_func_infos.h @@ -121,6 +121,9 @@ static const func_info_t func_infos[] = { #endif #if defined(HAVE_GD_WEBP) F1("imagecreatefromwebp", MAY_BE_OBJECT|MAY_BE_FALSE), +#endif +#if defined(HAVE_GD_HEIF) + F1("imagecreatefromheif", MAY_BE_OBJECT|MAY_BE_FALSE), #endif F1("imagecreatefromxbm", MAY_BE_OBJECT|MAY_BE_FALSE), #if defined(HAVE_GD_XPM) diff --git a/ext/gd/config.m4 b/ext/gd/config.m4 index 5c1c7a867c2f8..95ce612a15de9 100644 --- a/ext/gd/config.m4 +++ b/ext/gd/config.m4 @@ -195,6 +195,7 @@ AC_DEFUN([PHP_GD_CHECK_VERSION],[ PHP_GD_CHECK_FORMAT([Xpm], [HAVE_GD_XPM]) PHP_GD_CHECK_FORMAT([Bmp], [HAVE_GD_BMP]) PHP_GD_CHECK_FORMAT([Tga], [HAVE_GD_TGA]) + PHP_GD_CHECK_FORMAT([Heif], [HAVE_GD_HEIF]) PHP_CHECK_LIBRARY(gd, gdFontCacheShutdown, [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 ]) diff --git a/ext/gd/gd.c b/ext/gd/gd.c index ea7aa92fe0a99..11816719d2bdb 100644 --- a/ext/gd/gd.c +++ b/ext/gd/gd.c @@ -458,6 +458,9 @@ PHP_MINFO_FUNCTION(gd) #endif #ifdef HAVE_GD_TGA php_info_print_table_row(2, "TGA Read Support", "enabled"); +#endif +#ifdef HAVE_GD_HEIF + php_info_print_table_row(2, "HEIF Support", "enabled"); #endif php_info_print_table_end(); DISPLAY_INI_ENTRIES(); @@ -520,6 +523,11 @@ PHP_FUNCTION(gd_info) #else add_assoc_bool(return_value, "TGA Read Support", 0); #endif +#ifdef HAVE_GD_HEIF + add_assoc_bool(return_value, "HEIF Support", 1); +#else + add_assoc_bool(return_value, "HEIF Support", 0); +#endif #ifdef USE_GD_JISX0208 add_assoc_bool(return_value, "JIS-mapped Japanese Font Support", 1); #else @@ -1300,6 +1308,9 @@ PHP_FUNCTION(imagetypes) #ifdef HAVE_GD_AVIF ret |= PHP_IMG_AVIF; #endif +#ifdef HAVE_GD_HEIF + ret |= PHP_IMG_HEIF; +#endif if (zend_parse_parameters_none() == FAILURE) { RETURN_THROWS(); @@ -1351,6 +1362,11 @@ static int _php_image_type(zend_string *data) return PHP_GDIMG_TYPE_BMP; } else if(!memcmp(ZSTR_VAL(data), php_sig_riff, sizeof(php_sig_riff)) && !memcmp(ZSTR_VAL(data) + sizeof(php_sig_riff) + sizeof(uint32_t), php_sig_webp, sizeof(php_sig_webp))) { return PHP_GDIMG_TYPE_WEBP; + } else if (!memcmp(ZSTR_VAL(data), php_sig_heifheic, sizeof(php_sig_heifheic)) || + !memcmp(ZSTR_VAL(data), php_sig_heifheix, sizeof(php_sig_heifheix)) || + !memcmp(ZSTR_VAL(data), php_sig_heifmif1, sizeof(php_sig_heifmif1)) || + !memcmp(ZSTR_VAL(data), php_sig_heifmsf1, sizeof(php_sig_heifmsf1))) { + return PHP_GDIMG_TYPE_HEIF; } php_stream *image_stream = php_stream_memory_open(TEMP_STREAM_READONLY, data); @@ -1469,7 +1485,15 @@ PHP_FUNCTION(imagecreatefromstring) php_error_docref(NULL, E_WARNING, "No AVIF support in this PHP build"); RETURN_FALSE; #endif - +#ifdef HAVE_GD_HEIF + case PHP_GDIMG_TYPE_HEIF: + abort(); + im = _php_image_create_from_string(data, "HEIF", gdImageCreateFromHeifCtx); + break; +#else + php_error_docref(NULL, E_WARNING, "No HEIF support in this PHP build"); + RETURN_FALSE; +#endif default: php_error_docref(NULL, E_WARNING, "Data is not in a recognized format"); RETURN_FALSE; @@ -1674,6 +1698,12 @@ PHP_FUNCTION(imagecreatefromwbmp) _php_image_create_from(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_WBM, "WBMP", gdImageCreateFromWBMP, gdImageCreateFromWBMPCtx); } /* }}} */ +#ifdef HAVE_GD_HEIF +PHP_FUNCTION(imagecreatefromheif) +{ + _php_image_create_from(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_HEIF, "HEIF", gdImageCreateFromHeif, gdImageCreateFromHeifCtx); +} +#endif /* {{{ Create a new image from GD file or URL */ PHP_FUNCTION(imagecreatefromgd) @@ -1900,6 +1930,12 @@ PHP_FUNCTION(imagejpeg) } /* }}} */ #endif /* HAVE_GD_JPG */ +#ifdef HAVE_GD_HEIF +PHP_FUNCTION(imageheif) +{ + _php_image_output_ctx(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_HEIF, "HEIF"); +} +#endif /* {{{ Output WBMP image to browser or file */ PHP_FUNCTION(imagewbmp) @@ -4071,10 +4107,13 @@ static gdIOCtx *create_output_context(void) { static void _php_image_output_ctx(INTERNAL_FUNCTION_PARAMETERS, int image_type, char *tn) { zval *imgind; - zend_long quality = -1, basefilter = -1, speed = -1; + zend_long quality = -1, basefilter = -1, speed = -1, codec = -1; gdImagePtr im; gdIOCtx *ctx = NULL; zval *to_zval = NULL; + char *chroma = NULL; + size_t chroma_len; + bool codec_is_null = true; if (image_type == PHP_GDIMG_TYPE_GIF) { if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|z!", &imgind, gd_image_ce, &to_zval) == FAILURE) { @@ -4088,6 +4127,10 @@ static void _php_image_output_ctx(INTERNAL_FUNCTION_PARAMETERS, int image_type, if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|z!ll", &imgind, gd_image_ce, &to_zval, &quality, &speed) == FAILURE) { RETURN_THROWS(); } + } else if (image_type == PHP_GDIMG_TYPE_HEIF) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|z!l!ls", &imgind, gd_image_ce, &to_zval, &quality, &codec, &codec_is_null, &chroma, &chroma_len) == FAILURE) { + RETURN_THROWS(); + } } else { if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|z!l", &imgind, gd_image_ce, &to_zval, &quality) == FAILURE) { RETURN_THROWS(); @@ -4143,6 +4186,37 @@ static void _php_image_output_ctx(INTERNAL_FUNCTION_PARAMETERS, int image_type, gdImageAvifCtx(im, ctx, (int) quality, (int) speed); break; #endif +#ifdef HAVE_GD_HEIF + case PHP_GDIMG_TYPE_HEIF: + if (quality < -1) { + zend_argument_value_error(3, "must be greater than or equal to -1"); + ctx->gd_free(ctx); + RETURN_THROWS(); + } + if (codec_is_null) { + codec = GD_HEIF_CODEC_HEVC; + } + if (codec < GD_HEIF_CODEC_HEVC || codec > GD_HEIF_CODEC_AV1) { + zend_argument_value_error(4, "must be between HEIF_CODEC_HEVC or HEIF_CODEC_AV1"); + ctx->gd_free(ctx); + RETURN_THROWS(); + } + if (chroma == NULL) { + chroma = GD_HEIF_CHROMA_420; + chroma_len = strlen(chroma); + } + if (chroma_len != 3 || + (strcmp(chroma, GD_HEIF_CHROMA_420) && + strcmp(chroma, GD_HEIF_CHROMA_422) && + strcmp(chroma, GD_HEIF_CHROMA_444))) { + zend_argument_value_error(5, "must be between HEIF_CHROMA_420, HEIF_CHROMA_422 or HEIF_CHROMA_444"); + ctx->gd_free(ctx); + RETURN_THROWS(); + } + + gdImageHeifCtx(im, ctx, (int) quality, (gdHeifCodec)codec, chroma); + break; +#endif #ifdef HAVE_GD_PNG case PHP_GDIMG_TYPE_PNG: if (quality < -1 || quality > 9) { diff --git a/ext/gd/gd.stub.php b/ext/gd/gd.stub.php index 347e43e728b87..b59032366f3cc 100644 --- a/ext/gd/gd.stub.php +++ b/ext/gd/gd.stub.php @@ -53,6 +53,11 @@ */ const IMG_TGA = UNKNOWN; +/** + * @var int + * @cvalue PHP_IMG_HEIF + */ +const IMG_HEIF = UNKNOWN; /* constant for webp encoding */ #ifdef gdWebpLossless @@ -412,6 +417,39 @@ */ const IMG_FILTER_SCATTER = UNKNOWN; +#ifdef HAVE_GD_HEIF +/** + * @var string + * @cvalue GD_HEIF_CHROMA_420 + */ +const HEIF_CHROMA_420 = UNKNOWN; +/** + * @var string + * @cvalue GD_HEIF_CHROMA_422 + */ +const HEIF_CHROMA_422 = UNKNOWN; +/** + * @var string + * @cvalue GD_HEIF_CHROMA_444 + */ +const HEIF_CHROMA_444 = UNKNOWN; +/** + * @var int + * @cvalue GD_HEIF_CODEC_UNKNOWN + */ +const HEIF_CODEC_UNKNOWN = UNKNOWN; +/** + * @var int + * @cvalue GD_HEIF_CODEC_HEVC + */ +const HEIF_CODEC_HEVC = UNKNOWN; +/** + * @var int + * @cvalue GD_HEIF_CODEC_AV1 + */ +const HEIF_CODEC_AV1 = UNKNOWN; +#endif + #ifdef GD_VERSION_STRING /** * @var string @@ -569,6 +607,11 @@ function imagecreatefrompng(string $filename): GdImage|false {} function imagecreatefromwebp(string $filename): GdImage|false {} #endif +#ifdef HAVE_GD_HEIF +/** @refcount 1 */ +function imagecreatefromheif(string $filename): GdImage|false {} +#endif + /** @refcount 1 */ function imagecreatefromxbm(string $filename): GdImage|false {} @@ -626,6 +669,11 @@ function imagejpeg(GdImage $image, $file = null, int $quality = -1): bool {} /** @param resource|string|null $file */ function imagewbmp(GdImage $image, $file = null, ?int $foreground_color = null): bool {} +#ifdef HAVE_GD_HEIF +/** @param resource|string|null $file */ +function imageheif(GdImage $image, $file = null, int $quality = -1, ?int $codec = null, ?string $chroma = null): bool {} +#endif + function imagegd(GdImage $image, ?string $file = null): bool {} function imagegd2(GdImage $image, ?string $file = null, int $chunk_size = 128, int $mode = IMG_GD2_RAW): bool {} diff --git a/ext/gd/gd_arginfo.h b/ext/gd/gd_arginfo.h index f68b34d5e101b..01a16d48f5b75 100644 --- a/ext/gd/gd_arginfo.h +++ b/ext/gd/gd_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 0f8a22bff1d123313f37da400500e573baace837 */ + * Stub hash: 5d369508d02201da41e26a46d4d017c1ab4206fd */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_gd_info, 0, 0, IS_ARRAY, 0) ZEND_END_ARG_INFO() @@ -171,6 +171,12 @@ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_imagecreatefromwebp, 0, 1, G ZEND_END_ARG_INFO() #endif +#if defined(HAVE_GD_HEIF) +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_imagecreatefromheif, 0, 1, GdImage, MAY_BE_FALSE) + ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0) +ZEND_END_ARG_INFO() +#endif + #define arginfo_imagecreatefromxbm arginfo_imagecreatefromgif #if defined(HAVE_GD_XPM) @@ -256,6 +262,16 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_imagewbmp, 0, 1, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, foreground_color, IS_LONG, 1, "null") ZEND_END_ARG_INFO() +#if defined(HAVE_GD_HEIF) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_imageheif, 0, 1, _IS_BOOL, 0) + ZEND_ARG_OBJ_INFO(0, image, GdImage, 0) + ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, file, "null") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, quality, IS_LONG, 0, "-1") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, codec, IS_LONG, 1, "null") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, chroma, IS_STRING, 1, "null") +ZEND_END_ARG_INFO() +#endif + ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_imagegd, 0, 1, _IS_BOOL, 0) ZEND_ARG_OBJ_INFO(0, image, GdImage, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, file, IS_STRING, 1, "null") @@ -619,6 +635,9 @@ ZEND_FUNCTION(imagecreatefrompng); #if defined(HAVE_GD_WEBP) ZEND_FUNCTION(imagecreatefromwebp); #endif +#if defined(HAVE_GD_HEIF) +ZEND_FUNCTION(imagecreatefromheif); +#endif ZEND_FUNCTION(imagecreatefromxbm); #if defined(HAVE_GD_XPM) ZEND_FUNCTION(imagecreatefromxpm); @@ -648,6 +667,9 @@ ZEND_FUNCTION(imagewebp); ZEND_FUNCTION(imagejpeg); #endif ZEND_FUNCTION(imagewbmp); +#if defined(HAVE_GD_HEIF) +ZEND_FUNCTION(imageheif); +#endif ZEND_FUNCTION(imagegd); ZEND_FUNCTION(imagegd2); #if defined(HAVE_GD_BMP) @@ -758,6 +780,9 @@ static const zend_function_entry ext_functions[] = { #endif #if defined(HAVE_GD_WEBP) ZEND_FE(imagecreatefromwebp, arginfo_imagecreatefromwebp) +#endif +#if defined(HAVE_GD_HEIF) + ZEND_FE(imagecreatefromheif, arginfo_imagecreatefromheif) #endif ZEND_FE(imagecreatefromxbm, arginfo_imagecreatefromxbm) #if defined(HAVE_GD_XPM) @@ -788,6 +813,9 @@ static const zend_function_entry ext_functions[] = { ZEND_FE(imagejpeg, arginfo_imagejpeg) #endif ZEND_FE(imagewbmp, arginfo_imagewbmp) +#if defined(HAVE_GD_HEIF) + ZEND_FE(imageheif, arginfo_imageheif) +#endif ZEND_FE(imagegd, arginfo_imagegd) ZEND_FE(imagegd2, arginfo_imagegd2) #if defined(HAVE_GD_BMP) @@ -882,6 +910,7 @@ static void register_gd_symbols(int module_number) REGISTER_LONG_CONSTANT("IMG_WEBP", PHP_IMG_WEBP, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("IMG_BMP", PHP_IMG_BMP, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("IMG_TGA", PHP_IMG_TGA, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("IMG_HEIF", PHP_IMG_HEIF, CONST_PERSISTENT); #if defined(gdWebpLossless) REGISTER_LONG_CONSTANT("IMG_WEBP_LOSSLESS", gdWebpLossless, CONST_PERSISTENT); #endif @@ -953,6 +982,24 @@ static void register_gd_symbols(int module_number) REGISTER_LONG_CONSTANT("IMG_FILTER_SMOOTH", IMAGE_FILTER_SMOOTH, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("IMG_FILTER_PIXELATE", IMAGE_FILTER_PIXELATE, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("IMG_FILTER_SCATTER", IMAGE_FILTER_SCATTER, CONST_PERSISTENT); +#if defined(HAVE_GD_HEIF) + REGISTER_STRING_CONSTANT("HEIF_CHROMA_420", GD_HEIF_CHROMA_420, CONST_PERSISTENT); +#endif +#if defined(HAVE_GD_HEIF) + REGISTER_STRING_CONSTANT("HEIF_CHROMA_422", GD_HEIF_CHROMA_422, CONST_PERSISTENT); +#endif +#if defined(HAVE_GD_HEIF) + REGISTER_STRING_CONSTANT("HEIF_CHROMA_444", GD_HEIF_CHROMA_444, CONST_PERSISTENT); +#endif +#if defined(HAVE_GD_HEIF) + REGISTER_LONG_CONSTANT("HEIF_CODEC_UNKNOWN", GD_HEIF_CODEC_UNKNOWN, CONST_PERSISTENT); +#endif +#if defined(HAVE_GD_HEIF) + REGISTER_LONG_CONSTANT("HEIF_CODEC_HEVC", GD_HEIF_CODEC_HEVC, CONST_PERSISTENT); +#endif +#if defined(HAVE_GD_HEIF) + REGISTER_LONG_CONSTANT("HEIF_CODEC_AV1", GD_HEIF_CODEC_AV1, CONST_PERSISTENT); +#endif #if defined(GD_VERSION_STRING) REGISTER_STRING_CONSTANT("GD_VERSION", GD_VERSION_STRING, CONST_PERSISTENT); #endif diff --git a/ext/gd/php_gd.h b/ext/gd/php_gd.h index 8d27f8cc75a60..ee7885ff2ebbf 100644 --- a/ext/gd/php_gd.h +++ b/ext/gd/php_gd.h @@ -43,6 +43,7 @@ #define PHP_GDIMG_TYPE_BMP 12 #define PHP_GDIMG_TYPE_TGA 13 #define PHP_GDIMG_TYPE_AVIF 14 +#define PHP_GDIMG_TYPE_HEIF 15 #define PHP_IMG_GIF 1 #define PHP_IMG_JPG 2 @@ -54,6 +55,7 @@ #define PHP_IMG_BMP 64 #define PHP_IMG_TGA 128 #define PHP_IMG_AVIF 256 +#define PHP_IMG_HEIF 384 /* Section Filters Declarations */ /* IMPORTANT NOTE FOR NEW FILTER @@ -103,6 +105,10 @@ PHPAPI extern const char php_sig_bmp[2]; PHPAPI extern const char php_sig_riff[4]; PHPAPI extern const char php_sig_webp[4]; PHPAPI extern const char php_sig_avif[4]; +PHPAPI extern const char php_sig_heifheic[12]; +PHPAPI extern const char php_sig_heifheix[12]; +PHPAPI extern const char php_sig_heifmif1[12]; +PHPAPI extern const char php_sig_heifmsf1[12]; extern zend_module_entry gd_module_entry; #define phpext_gd_ptr &gd_module_entry diff --git a/ext/gd/tests/imageheif.phpt b/ext/gd/tests/imageheif.phpt new file mode 100644 index 0000000000000..e1f924bb32322 --- /dev/null +++ b/ext/gd/tests/imageheif.phpt @@ -0,0 +1,28 @@ +--TEST-- +heif support +--EXTENSIONS-- +gd +--SKIPIF-- + +--FILE-- + + +--EXPECT-- +object(GdImage)#1 (0) { +} +bool(true) diff --git a/ext/gd/tests/imageheif_basic.heif b/ext/gd/tests/imageheif_basic.heif new file mode 100644 index 0000000000000..23cd8683d94b9 Binary files /dev/null and b/ext/gd/tests/imageheif_basic.heif differ diff --git a/ext/standard/basic_functions.stub.php b/ext/standard/basic_functions.stub.php index 2e89f446d4624..12af2f3e0884c 100644 --- a/ext/standard/basic_functions.stub.php +++ b/ext/standard/basic_functions.stub.php @@ -666,6 +666,11 @@ * @cvalue IMAGE_FILETYPE_AVIF */ const IMAGETYPE_AVIF = UNKNOWN; +/** + * @var int + * @cvalue IMAGE_FILETYPE_HEIF + */ +const IMAGETYPE_HEIF = UNKNOWN; /** * @var int * @cvalue IMAGE_FILETYPE_UNKNOWN diff --git a/ext/standard/basic_functions_arginfo.h b/ext/standard/basic_functions_arginfo.h index f3d04ad2544d9..98768033c0bf1 100644 --- a/ext/standard/basic_functions_arginfo.h +++ b/ext/standard/basic_functions_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 7d588414e84ed62088cd5b1c668b29c0e51d406f */ + * Stub hash: 2b831219f66ed17c8cebe9e176aa79b8dc34a026 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_set_time_limit, 0, 1, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO(0, seconds, IS_LONG, 0) @@ -3794,6 +3794,7 @@ static void register_basic_functions_symbols(int module_number) REGISTER_LONG_CONSTANT("IMAGETYPE_ICO", IMAGE_FILETYPE_ICO, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("IMAGETYPE_WEBP", IMAGE_FILETYPE_WEBP, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("IMAGETYPE_AVIF", IMAGE_FILETYPE_AVIF, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("IMAGETYPE_HEIF", IMAGE_FILETYPE_HEIF, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("IMAGETYPE_UNKNOWN", IMAGE_FILETYPE_UNKNOWN, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("IMAGETYPE_COUNT", IMAGE_FILETYPE_COUNT, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("INFO_GENERAL", PHP_INFO_GENERAL, CONST_PERSISTENT); diff --git a/ext/standard/image.c b/ext/standard/image.c index 2bd5429efac35..5298d9c17ac46 100644 --- a/ext/standard/image.c +++ b/ext/standard/image.c @@ -52,6 +52,11 @@ PHPAPI const char php_sig_ico[4] = {(char)0x00, (char)0x00, (char)0x01, (char)0x PHPAPI const char php_sig_riff[4] = {'R', 'I', 'F', 'F'}; PHPAPI const char php_sig_webp[4] = {'W', 'E', 'B', 'P'}; +PHPAPI const char php_sig_heifheic[12] = {'f', 't', 'y', 'p', 'h', 'e', 'i', 'c'}; +PHPAPI const char php_sig_heifheix[12] = {'f', 't', 'y', 'p', 'h', 'e', 'i', 'x'}; +PHPAPI const char php_sig_heifmif1[12] = {'f', 't', 'y', 'p', 'm', 'i', 'f', '1'}; +PHPAPI const char php_sig_heifmsf1[12] = {'f', 't', 'y', 'p', 'm', 's', 'f', '1'}; + /* REMEMBER TO ADD MIME-TYPE TO FUNCTION php_image_type_to_mime_type */ /* PCX must check first 64bytes and byte 0=0x0a and byte2 < 0x06 */ @@ -1249,6 +1254,8 @@ PHPAPI char * php_image_type_to_mime_type(int image_type) return "image/webp"; case IMAGE_FILETYPE_AVIF: return "image/avif"; + case IMAGE_FILETYPE_HEIF: + return "image/heif"; default: case IMAGE_FILETYPE_UNKNOWN: return "application/octet-stream"; /* suppose binary format */ @@ -1334,6 +1341,9 @@ PHP_FUNCTION(image_type_to_extension) case IMAGE_FILETYPE_AVIF: imgext = ".avif"; break; + case IMAGE_FILETYPE_HEIF: + imgext = ".heif"; + break; } if (imgext) { @@ -1408,6 +1418,11 @@ PHPAPI int php_getimagetype(php_stream *stream, const char *input, char *filetyp return IMAGE_FILETYPE_IFF; } else if (!memcmp(filetype, php_sig_ico, 4)) { return IMAGE_FILETYPE_ICO; + } else if (!memcmp(filetype, php_sig_heifheic, 12) || + !memcmp(filetype, php_sig_heifheix, 12) || + !memcmp(filetype, php_sig_heifmif1, 12) || + !memcmp(filetype, php_sig_heifmsf1, 12)) { + return IMAGE_FILETYPE_HEIF; } /* WBMP may be smaller than 12 bytes, so delay error */ @@ -1510,6 +1525,11 @@ static void php_getimagesize_from_stream(php_stream *stream, char *input, zval * case IMAGE_FILETYPE_AVIF: result = php_handle_avif(stream); break; + /* + case IMAGE_FILETYPE_HEIF: + result = php_handle_heif(stream); + break; + */ default: case IMAGE_FILETYPE_UNKNOWN: break; diff --git a/ext/standard/php_image.h b/ext/standard/php_image.h index a41273e6745ae..f0f3edb7283eb 100644 --- a/ext/standard/php_image.h +++ b/ext/standard/php_image.h @@ -44,6 +44,7 @@ typedef enum IMAGE_FILETYPE_ICO, IMAGE_FILETYPE_WEBP, IMAGE_FILETYPE_AVIF, + IMAGE_FILETYPE_HEIF, /* WHEN EXTENDING: PLEASE ALSO REGISTER IN basic_function.stub.php */ IMAGE_FILETYPE_COUNT } image_filetype; diff --git a/ext/standard/tests/image/image_type_to_mime_type_variation3.phpt b/ext/standard/tests/image/image_type_to_mime_type_variation3.phpt index fc17cb5ecd947..184ca8b53d189 100644 --- a/ext/standard/tests/image/image_type_to_mime_type_variation3.phpt +++ b/ext/standard/tests/image/image_type_to_mime_type_variation3.phpt @@ -1,5 +1,5 @@ --TEST-- -image_type_to_mime_type() (passinf equivalent integer values) +image_type_to_mime_type() (passing equivalent integer values) --CREDITS-- Sanjay Mantoor --FILE-- @@ -75,4 +75,7 @@ string\(10\) "image\/webp" string\(10\) "image\/avif" -- Iteration 20 -- +string\(10\) "image\/heif" + +-- Iteration 21 -- string\(24\) "application\/octet-stream"