@@ -458,6 +458,9 @@ PHP_MINFO_FUNCTION(gd)
458
458
#endif
459
459
#ifdef HAVE_GD_TGA
460
460
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" );
461
464
#endif
462
465
php_info_print_table_end ();
463
466
DISPLAY_INI_ENTRIES ();
@@ -520,6 +523,11 @@ PHP_FUNCTION(gd_info)
520
523
#else
521
524
add_assoc_bool (return_value , "TGA Read Support" , 0 );
522
525
#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
523
531
#ifdef USE_GD_JISX0208
524
532
add_assoc_bool (return_value , "JIS-mapped Japanese Font Support" , 1 );
525
533
#else
@@ -1300,6 +1308,9 @@ PHP_FUNCTION(imagetypes)
1300
1308
#ifdef HAVE_GD_AVIF
1301
1309
ret |= PHP_IMG_AVIF ;
1302
1310
#endif
1311
+ #ifdef HAVE_GD_HEIF
1312
+ ret |= PHP_IMG_HEIF ;
1313
+ #endif
1303
1314
1304
1315
if (zend_parse_parameters_none () == FAILURE ) {
1305
1316
RETURN_THROWS ();
@@ -1351,6 +1362,11 @@ static int _php_image_type(zend_string *data)
1351
1362
return PHP_GDIMG_TYPE_BMP ;
1352
1363
} 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 ))) {
1353
1364
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 ;
1354
1370
}
1355
1371
1356
1372
php_stream * image_stream = php_stream_memory_open (TEMP_STREAM_READONLY , data );
@@ -1469,7 +1485,13 @@ PHP_FUNCTION(imagecreatefromstring)
1469
1485
php_error_docref (NULL , E_WARNING , "No AVIF support in this PHP build" );
1470
1486
RETURN_FALSE ;
1471
1487
#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
1473
1495
default :
1474
1496
php_error_docref (NULL , E_WARNING , "Data is not in a recognized format" );
1475
1497
RETURN_FALSE ;
@@ -1674,6 +1696,12 @@ PHP_FUNCTION(imagecreatefromwbmp)
1674
1696
_php_image_create_from (INTERNAL_FUNCTION_PARAM_PASSTHRU , PHP_GDIMG_TYPE_WBM , "WBMP" , gdImageCreateFromWBMP , gdImageCreateFromWBMPCtx );
1675
1697
}
1676
1698
/* }}} */
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
1677
1705
1678
1706
/* {{{ Create a new image from GD file or URL */
1679
1707
PHP_FUNCTION (imagecreatefromgd )
@@ -1900,6 +1928,12 @@ PHP_FUNCTION(imagejpeg)
1900
1928
}
1901
1929
/* }}} */
1902
1930
#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
1903
1937
1904
1938
/* {{{ Output WBMP image to browser or file */
1905
1939
PHP_FUNCTION (imagewbmp )
@@ -4071,10 +4105,13 @@ static gdIOCtx *create_output_context(void) {
4071
4105
static void _php_image_output_ctx (INTERNAL_FUNCTION_PARAMETERS , int image_type , char * tn )
4072
4106
{
4073
4107
zval * imgind ;
4074
- zend_long quality = -1 , basefilter = -1 , speed = -1 ;
4108
+ zend_long quality = -1 , basefilter = -1 , speed = -1 , codec = -1 ;
4075
4109
gdImagePtr im ;
4076
4110
gdIOCtx * ctx = NULL ;
4077
4111
zval * to_zval = NULL ;
4112
+ char * chroma = NULL ;
4113
+ size_t chroma_len ;
4114
+ bool codec_is_null = true;
4078
4115
4079
4116
if (image_type == PHP_GDIMG_TYPE_GIF ) {
4080
4117
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,
4088
4125
if (zend_parse_parameters (ZEND_NUM_ARGS (), "O|z!ll" , & imgind , gd_image_ce , & to_zval , & quality , & speed ) == FAILURE ) {
4089
4126
RETURN_THROWS ();
4090
4127
}
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
+ }
4091
4132
} else {
4092
4133
if (zend_parse_parameters (ZEND_NUM_ARGS (), "O|z!l" , & imgind , gd_image_ce , & to_zval , & quality ) == FAILURE ) {
4093
4134
RETURN_THROWS ();
@@ -4143,6 +4184,37 @@ static void _php_image_output_ctx(INTERNAL_FUNCTION_PARAMETERS, int image_type,
4143
4184
gdImageAvifCtx (im , ctx , (int ) quality , (int ) speed );
4144
4185
break ;
4145
4186
#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
4146
4218
#ifdef HAVE_GD_PNG
4147
4219
case PHP_GDIMG_TYPE_PNG :
4148
4220
if (quality < -1 || quality > 9 ) {
0 commit comments