@@ -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,15 @@ 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
+ 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
1473
1497
default :
1474
1498
php_error_docref (NULL , E_WARNING , "Data is not in a recognized format" );
1475
1499
RETURN_FALSE ;
@@ -1674,6 +1698,12 @@ PHP_FUNCTION(imagecreatefromwbmp)
1674
1698
_php_image_create_from (INTERNAL_FUNCTION_PARAM_PASSTHRU , PHP_GDIMG_TYPE_WBM , "WBMP" , gdImageCreateFromWBMP , gdImageCreateFromWBMPCtx );
1675
1699
}
1676
1700
/* }}} */
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
1677
1707
1678
1708
/* {{{ Create a new image from GD file or URL */
1679
1709
PHP_FUNCTION (imagecreatefromgd )
@@ -1900,6 +1930,12 @@ PHP_FUNCTION(imagejpeg)
1900
1930
}
1901
1931
/* }}} */
1902
1932
#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
1903
1939
1904
1940
/* {{{ Output WBMP image to browser or file */
1905
1941
PHP_FUNCTION (imagewbmp )
@@ -4071,10 +4107,13 @@ static gdIOCtx *create_output_context(void) {
4071
4107
static void _php_image_output_ctx (INTERNAL_FUNCTION_PARAMETERS , int image_type , char * tn )
4072
4108
{
4073
4109
zval * imgind ;
4074
- zend_long quality = -1 , basefilter = -1 , speed = -1 ;
4110
+ zend_long quality = -1 , basefilter = -1 , speed = -1 , codec = -1 ;
4075
4111
gdImagePtr im ;
4076
4112
gdIOCtx * ctx = NULL ;
4077
4113
zval * to_zval = NULL ;
4114
+ char * chroma = NULL ;
4115
+ size_t chroma_len ;
4116
+ bool codec_is_null = true;
4078
4117
4079
4118
if (image_type == PHP_GDIMG_TYPE_GIF ) {
4080
4119
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,
4088
4127
if (zend_parse_parameters (ZEND_NUM_ARGS (), "O|z!ll" , & imgind , gd_image_ce , & to_zval , & quality , & speed ) == FAILURE ) {
4089
4128
RETURN_THROWS ();
4090
4129
}
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
+ }
4091
4134
} else {
4092
4135
if (zend_parse_parameters (ZEND_NUM_ARGS (), "O|z!l" , & imgind , gd_image_ce , & to_zval , & quality ) == FAILURE ) {
4093
4136
RETURN_THROWS ();
@@ -4143,6 +4186,37 @@ static void _php_image_output_ctx(INTERNAL_FUNCTION_PARAMETERS, int image_type,
4143
4186
gdImageAvifCtx (im , ctx , (int ) quality , (int ) speed );
4144
4187
break ;
4145
4188
#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
4146
4220
#ifdef HAVE_GD_PNG
4147
4221
case PHP_GDIMG_TYPE_PNG :
4148
4222
if (quality < -1 || quality > 9 ) {
0 commit comments