@@ -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,15 @@ 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+ case PHP_GDIMG_TYPE_HEIF :
1490+ abort ();
1491+ im = _php_image_create_from_string (data , "HEIF" , gdImageCreateFromHeifCtx );
1492+ break ;
1493+ #else
1494+ php_error_docref (NULL , E_WARNING , "No HEIF support in this PHP build" );
1495+ RETURN_FALSE ;
1496+ #endif
14731497 default :
14741498 php_error_docref (NULL , E_WARNING , "Data is not in a recognized format" );
14751499 RETURN_FALSE ;
@@ -1674,6 +1698,12 @@ PHP_FUNCTION(imagecreatefromwbmp)
16741698 _php_image_create_from (INTERNAL_FUNCTION_PARAM_PASSTHRU , PHP_GDIMG_TYPE_WBM , "WBMP" , gdImageCreateFromWBMP , gdImageCreateFromWBMPCtx );
16751699}
16761700/* }}} */
1701+ #ifdef HAVE_GD_HEIF
1702+ PHP_FUNCTION (imagecreatefromheif )
1703+ {
1704+ _php_image_create_from (INTERNAL_FUNCTION_PARAM_PASSTHRU , PHP_GDIMG_TYPE_HEIF , "HEIF" , gdImageCreateFromHeif , gdImageCreateFromHeifCtx );
1705+ }
1706+ #endif
16771707
16781708/* {{{ Create a new image from GD file or URL */
16791709PHP_FUNCTION (imagecreatefromgd )
@@ -1900,6 +1930,12 @@ PHP_FUNCTION(imagejpeg)
19001930}
19011931/* }}} */
19021932#endif /* HAVE_GD_JPG */
1933+ #ifdef HAVE_GD_HEIF
1934+ PHP_FUNCTION (imageheif )
1935+ {
1936+ _php_image_output_ctx (INTERNAL_FUNCTION_PARAM_PASSTHRU , PHP_GDIMG_TYPE_HEIF , "HEIF" );
1937+ }
1938+ #endif
19031939
19041940/* {{{ Output WBMP image to browser or file */
19051941PHP_FUNCTION (imagewbmp )
@@ -4071,10 +4107,13 @@ static gdIOCtx *create_output_context(void) {
40714107static void _php_image_output_ctx (INTERNAL_FUNCTION_PARAMETERS , int image_type , char * tn )
40724108{
40734109 zval * imgind ;
4074- zend_long quality = -1 , basefilter = -1 , speed = -1 ;
4110+ zend_long quality = -1 , basefilter = -1 , speed = -1 , codec = -1 ;
40754111 gdImagePtr im ;
40764112 gdIOCtx * ctx = NULL ;
40774113 zval * to_zval = NULL ;
4114+ char * chroma = NULL ;
4115+ size_t chroma_len ;
4116+ bool codec_is_null = true;
40784117
40794118 if (image_type == PHP_GDIMG_TYPE_GIF ) {
40804119 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,
40884127 if (zend_parse_parameters (ZEND_NUM_ARGS (), "O|z!ll" , & imgind , gd_image_ce , & to_zval , & quality , & speed ) == FAILURE ) {
40894128 RETURN_THROWS ();
40904129 }
4130+ } else if (image_type == PHP_GDIMG_TYPE_HEIF ) {
4131+ 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 ) {
4132+ RETURN_THROWS ();
4133+ }
40914134 } else {
40924135 if (zend_parse_parameters (ZEND_NUM_ARGS (), "O|z!l" , & imgind , gd_image_ce , & to_zval , & quality ) == FAILURE ) {
40934136 RETURN_THROWS ();
@@ -4143,6 +4186,37 @@ static void _php_image_output_ctx(INTERNAL_FUNCTION_PARAMETERS, int image_type,
41434186 gdImageAvifCtx (im , ctx , (int ) quality , (int ) speed );
41444187 break ;
41454188#endif
4189+ #ifdef HAVE_GD_HEIF
4190+ case PHP_GDIMG_TYPE_HEIF :
4191+ if (quality < -1 ) {
4192+ zend_argument_value_error (3 , "must be greater than or equal to -1" );
4193+ ctx -> gd_free (ctx );
4194+ RETURN_THROWS ();
4195+ }
4196+ if (codec_is_null ) {
4197+ codec = GD_HEIF_CODEC_HEVC ;
4198+ }
4199+ if (codec < GD_HEIF_CODEC_HEVC || codec > GD_HEIF_CODEC_AV1 ) {
4200+ zend_argument_value_error (4 , "must be between HEIF_CODEC_HEVC or HEIF_CODEC_AV1" );
4201+ ctx -> gd_free (ctx );
4202+ RETURN_THROWS ();
4203+ }
4204+ if (chroma == NULL ) {
4205+ chroma = GD_HEIF_CHROMA_420 ;
4206+ chroma_len = strlen (chroma );
4207+ }
4208+ if (chroma_len != 3 ||
4209+ (strcmp (chroma , GD_HEIF_CHROMA_420 ) &&
4210+ strcmp (chroma , GD_HEIF_CHROMA_422 ) &&
4211+ strcmp (chroma , GD_HEIF_CHROMA_444 ))) {
4212+ zend_argument_value_error (5 , "must be between HEIF_CHROMA_420, HEIF_CHROMA_422 or HEIF_CHROMA_444" );
4213+ ctx -> gd_free (ctx );
4214+ RETURN_THROWS ();
4215+ }
4216+
4217+ gdImageHeifCtx (im , ctx , (int ) quality , (gdHeifCodec )codec , chroma );
4218+ break ;
4219+ #endif
41464220#ifdef HAVE_GD_PNG
41474221 case PHP_GDIMG_TYPE_PNG :
41484222 if (quality < -1 || quality > 9 ) {
0 commit comments