@@ -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,12 @@ 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 = ( zend_long ) GD_HEIF_CODEC_HEVC ;
40754109 gdImagePtr im ;
40764110 gdIOCtx * ctx = NULL ;
40774111 zval * to_zval = NULL ;
4112+ char * chroma = NULL ;
4113+ size_t chroma_len ;
40784114
40794115 if (image_type == PHP_GDIMG_TYPE_GIF ) {
40804116 if (zend_parse_parameters (ZEND_NUM_ARGS (), "O|z!" , & imgind , gd_image_ce , & to_zval ) == FAILURE ) {
@@ -4088,6 +4124,10 @@ static void _php_image_output_ctx(INTERNAL_FUNCTION_PARAMETERS, int image_type,
40884124 if (zend_parse_parameters (ZEND_NUM_ARGS (), "O|z!ll" , & imgind , gd_image_ce , & to_zval , & quality , & speed ) == FAILURE ) {
40894125 RETURN_THROWS ();
40904126 }
4127+ } else if (image_type == PHP_GDIMG_TYPE_HEIF ) {
4128+ if (zend_parse_parameters (ZEND_NUM_ARGS (), "O|z!lls" , & imgind , gd_image_ce , & to_zval , & quality , & codec , & chroma , & chroma_len ) == FAILURE ) {
4129+ RETURN_THROWS ();
4130+ }
40914131 } else {
40924132 if (zend_parse_parameters (ZEND_NUM_ARGS (), "O|z!l" , & imgind , gd_image_ce , & to_zval , & quality ) == FAILURE ) {
40934133 RETURN_THROWS ();
@@ -4143,6 +4183,34 @@ static void _php_image_output_ctx(INTERNAL_FUNCTION_PARAMETERS, int image_type,
41434183 gdImageAvifCtx (im , ctx , (int ) quality , (int ) speed );
41444184 break ;
41454185#endif
4186+ #ifdef HAVE_GD_HEIF
4187+ case PHP_GDIMG_TYPE_HEIF :
4188+ if (quality < -1 ) {
4189+ zend_argument_value_error (3 , "must be greater than or equal to -1" );
4190+ ctx -> gd_free (ctx );
4191+ RETURN_THROWS ();
4192+ }
4193+ if (codec < GD_HEIF_CODEC_HEVC || codec > GD_HEIF_CODEC_AV1 ) {
4194+ zend_argument_value_error (4 , "must be between HEIF_CODEC_HEVC or HEIF_CODEC_AV1" );
4195+ ctx -> gd_free (ctx );
4196+ RETURN_THROWS ();
4197+ }
4198+ if (chroma == NULL ) {
4199+ chroma = GD_HEIF_CHROMA_420 ;
4200+ chroma_len = strlen (chroma );
4201+ }
4202+ if (chroma_len != 3 ||
4203+ (strcmp (chroma , GD_HEIF_CHROMA_420 ) &&
4204+ strcmp (chroma , GD_HEIF_CHROMA_422 ) &&
4205+ strcmp (chroma , GD_HEIF_CHROMA_444 ))) {
4206+ zend_argument_value_error (5 , "must be between HEIF_CHROMA_420, HEIF_CHROMA_422 or HEIF_CHROMA_444" );
4207+ ctx -> gd_free (ctx );
4208+ RETURN_THROWS ();
4209+ }
4210+
4211+ gdImageHeifCtx (im , ctx , (int ) quality , (gdHeifCodec )codec , chroma );
4212+ break ;
4213+ #endif
41464214#ifdef HAVE_GD_PNG
41474215 case PHP_GDIMG_TYPE_PNG :
41484216 if (quality < -1 || quality > 9 ) {
0 commit comments