@@ -458,6 +458,9 @@ PHP_MINFO_FUNCTION(gd)
458458#endif
459459#ifdef HAVE_GD_TGA
460460 php_info_print_table_row (2 , "TGA Read Support" , "enabled" );
461+ #endif
462+ #ifdef HAVE_GD_HEIF
463+ php_info_print_table_row (2 , "HEIF Support" , "enabled" );
461464#endif
462465 php_info_print_table_end ();
463466 DISPLAY_INI_ENTRIES ();
@@ -520,6 +523,11 @@ PHP_FUNCTION(gd_info)
520523#else
521524 add_assoc_bool (return_value , "TGA Read Support" , 0 );
522525#endif
526+ #ifdef HAVE_GD_HEIF
527+ add_assoc_bool (return_value , "HEIF Support" , 1 );
528+ #else
529+ add_assoc_bool (return_value , "HEIF Support" , 0 );
530+ #endif
523531#ifdef USE_GD_JISX0208
524532 add_assoc_bool (return_value , "JIS-mapped Japanese Font Support" , 1 );
525533#else
@@ -1300,6 +1308,9 @@ PHP_FUNCTION(imagetypes)
13001308#ifdef HAVE_GD_AVIF
13011309 ret |= PHP_IMG_AVIF ;
13021310#endif
1311+ #ifdef HAVE_GD_HEIF
1312+ ret |= PHP_IMG_HEIF ;
1313+ #endif
13031314
13041315 if (zend_parse_parameters_none () == FAILURE ) {
13051316 RETURN_THROWS ();
@@ -1351,6 +1362,11 @@ static int _php_image_type(zend_string *data)
13511362 return PHP_GDIMG_TYPE_BMP ;
13521363 } 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 ))) {
13531364 return PHP_GDIMG_TYPE_WEBP ;
1365+ } else if (!memcmp (ZSTR_VAL (data ), php_sig_heifheic , sizeof (php_sig_heifheic )) ||
1366+ !memcmp (ZSTR_VAL (data ), php_sig_heifheix , sizeof (php_sig_heifheix )) ||
1367+ !memcmp (ZSTR_VAL (data ), php_sig_heifmif1 , sizeof (php_sig_heifmif1 )) ||
1368+ !memcmp (ZSTR_VAL (data ), php_sig_heifmsf1 , sizeof (php_sig_heifmsf1 ))) {
1369+ return PHP_GDIMG_TYPE_HEIF ;
13541370 }
13551371
13561372 php_stream * image_stream = php_stream_memory_open (TEMP_STREAM_READONLY , data );
@@ -1469,7 +1485,13 @@ PHP_FUNCTION(imagecreatefromstring)
14691485 php_error_docref (NULL , E_WARNING , "No AVIF support in this PHP build" );
14701486 RETURN_FALSE ;
14711487#endif
1472-
1488+ #ifdef HAVE_GD_HEIF
1489+ im = _php_image_create_from_string (data , "HEIF" , gdImageCreateFromHeifCtx );
1490+ break ;
1491+ #else
1492+ php_error_docref (NULL , E_WARNING , "No HEIF support in this PHP build" );
1493+ RETURN_FALSE ;
1494+ #endif
14731495 default :
14741496 php_error_docref (NULL , E_WARNING , "Data is not in a recognized format" );
14751497 RETURN_FALSE ;
@@ -1674,6 +1696,12 @@ PHP_FUNCTION(imagecreatefromwbmp)
16741696 _php_image_create_from (INTERNAL_FUNCTION_PARAM_PASSTHRU , PHP_GDIMG_TYPE_WBM , "WBMP" , gdImageCreateFromWBMP , gdImageCreateFromWBMPCtx );
16751697}
16761698/* }}} */
1699+ #ifdef HAVE_GD_HEIF
1700+ PHP_FUNCTION (imagecreatefromheif )
1701+ {
1702+ _php_image_create_from (INTERNAL_FUNCTION_PARAM_PASSTHRU , PHP_GDIMG_TYPE_HEIF , "HEIF" , gdImageCreateFromHeif , gdImageCreateFromHeifCtx );
1703+ }
1704+ #endif
16771705
16781706/* {{{ Create a new image from GD file or URL */
16791707PHP_FUNCTION (imagecreatefromgd )
@@ -1900,6 +1928,12 @@ PHP_FUNCTION(imagejpeg)
19001928}
19011929/* }}} */
19021930#endif /* HAVE_GD_JPG */
1931+ #ifdef HAVE_GD_HEIF
1932+ PHP_FUNCTION (imageheif )
1933+ {
1934+ _php_image_output_ctx (INTERNAL_FUNCTION_PARAM_PASSTHRU , PHP_GDIMG_TYPE_HEIF , "HEIF" );
1935+ }
1936+ #endif
19031937
19041938/* {{{ Output WBMP image to browser or file */
19051939PHP_FUNCTION (imagewbmp )
@@ -4071,10 +4105,13 @@ static gdIOCtx *create_output_context(void) {
40714105static void _php_image_output_ctx (INTERNAL_FUNCTION_PARAMETERS , int image_type , char * tn )
40724106{
40734107 zval * imgind ;
4074- zend_long quality = -1 , basefilter = -1 , speed = -1 ;
4108+ zend_long quality = -1 , basefilter = -1 , speed = -1 , codec = -1 ;
40754109 gdImagePtr im ;
40764110 gdIOCtx * ctx = NULL ;
40774111 zval * to_zval = NULL ;
4112+ char * chroma = NULL ;
4113+ size_t chroma_len ;
4114+ bool codec_is_null = true;
40784115
40794116 if (image_type == PHP_GDIMG_TYPE_GIF ) {
40804117 if (zend_parse_parameters (ZEND_NUM_ARGS (), "O|z!" , & imgind , gd_image_ce , & to_zval ) == FAILURE ) {
@@ -4088,6 +4125,10 @@ static void _php_image_output_ctx(INTERNAL_FUNCTION_PARAMETERS, int image_type,
40884125 if (zend_parse_parameters (ZEND_NUM_ARGS (), "O|z!ll" , & imgind , gd_image_ce , & to_zval , & quality , & speed ) == FAILURE ) {
40894126 RETURN_THROWS ();
40904127 }
4128+ } else if (image_type == PHP_GDIMG_TYPE_HEIF ) {
4129+ 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 ) {
4130+ RETURN_THROWS ();
4131+ }
40914132 } else {
40924133 if (zend_parse_parameters (ZEND_NUM_ARGS (), "O|z!l" , & imgind , gd_image_ce , & to_zval , & quality ) == FAILURE ) {
40934134 RETURN_THROWS ();
@@ -4143,6 +4184,37 @@ static void _php_image_output_ctx(INTERNAL_FUNCTION_PARAMETERS, int image_type,
41434184 gdImageAvifCtx (im , ctx , (int ) quality , (int ) speed );
41444185 break ;
41454186#endif
4187+ #ifdef HAVE_GD_HEIF
4188+ case PHP_GDIMG_TYPE_HEIF :
4189+ if (quality < -1 ) {
4190+ zend_argument_value_error (3 , "must be greater than or equal to -1" );
4191+ ctx -> gd_free (ctx );
4192+ RETURN_THROWS ();
4193+ }
4194+ if (codec_is_null ) {
4195+ codec = GD_HEIF_CODEC_HEVC ;
4196+ }
4197+ if (codec < GD_HEIF_CODEC_HEVC || codec > GD_HEIF_CODEC_AV1 ) {
4198+ zend_argument_value_error (4 , "must be between HEIF_CODEC_HEVC or HEIF_CODEC_AV1" );
4199+ ctx -> gd_free (ctx );
4200+ RETURN_THROWS ();
4201+ }
4202+ if (chroma == NULL ) {
4203+ chroma = GD_HEIF_CHROMA_420 ;
4204+ chroma_len = strlen (chroma );
4205+ }
4206+ if (chroma_len != 3 ||
4207+ (strcmp (chroma , GD_HEIF_CHROMA_420 ) &&
4208+ strcmp (chroma , GD_HEIF_CHROMA_422 ) &&
4209+ strcmp (chroma , GD_HEIF_CHROMA_444 ))) {
4210+ zend_argument_value_error (5 , "must be between HEIF_CHROMA_420, HEIF_CHROMA_422 or HEIF_CHROMA_444" );
4211+ ctx -> gd_free (ctx );
4212+ RETURN_THROWS ();
4213+ }
4214+
4215+ gdImageHeifCtx (im , ctx , (int ) quality , (gdHeifCodec )codec , chroma );
4216+ break ;
4217+ #endif
41464218#ifdef HAVE_GD_PNG
41474219 case PHP_GDIMG_TYPE_PNG :
41484220 if (quality < -1 || quality > 9 ) {
0 commit comments