diff --git a/ext/standard/basic_functions.stub.php b/ext/standard/basic_functions.stub.php index 09f63860f1163..7ad3234b81345 100644 --- a/ext/standard/basic_functions.stub.php +++ b/ext/standard/basic_functions.stub.php @@ -646,6 +646,11 @@ * @cvalue IMAGE_FILETYPE_AVIF */ const IMAGETYPE_AVIF = UNKNOWN; +/** + * @var int + * @cvalue IMAGE_FILETYPE_HEIF + */ +const IMAGETYPE_HEIF = UNKNOWN; /** * @var int * @cvalue IMAGE_FILETYPE_UNKNOWN diff --git a/ext/standard/basic_functions_arginfo.h b/ext/standard/basic_functions_arginfo.h index 37df4de7bdfcd..8407d9643c146 100644 --- a/ext/standard/basic_functions_arginfo.h +++ b/ext/standard/basic_functions_arginfo.h @@ -3645,6 +3645,7 @@ static void register_basic_functions_symbols(int module_number) REGISTER_LONG_CONSTANT("IMAGETYPE_ICO", IMAGE_FILETYPE_ICO, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("IMAGETYPE_WEBP", IMAGE_FILETYPE_WEBP, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("IMAGETYPE_AVIF", IMAGE_FILETYPE_AVIF, CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("IMAGETYPE_HEIF", IMAGE_FILETYPE_HEIF, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("IMAGETYPE_UNKNOWN", IMAGE_FILETYPE_UNKNOWN, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("IMAGETYPE_COUNT", IMAGE_FILETYPE_COUNT, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("INFO_GENERAL", PHP_INFO_GENERAL, CONST_PERSISTENT); diff --git a/ext/standard/image.c b/ext/standard/image.c index eeb1f1fa2813a..ef0ddade3be3c 100644 --- a/ext/standard/image.c +++ b/ext/standard/image.c @@ -51,6 +51,10 @@ PHPAPI const char php_sig_iff[4] = {'F','O','R','M'}; PHPAPI const char php_sig_ico[4] = {(char)0x00, (char)0x00, (char)0x01, (char)0x00}; PHPAPI const char php_sig_riff[4] = {'R', 'I', 'F', 'F'}; PHPAPI const char php_sig_webp[4] = {'W', 'E', 'B', 'P'}; +PHPAPI const char php_sig_ftyp[4] = {'f', 't', 'y', 'p'}; +PHPAPI const char php_sig_mif1[4] = {'m', 'i', 'f', '1'}; +PHPAPI const char php_sig_heic[4] = {'h', 'e', 'i', 'c'}; +PHPAPI const char php_sig_heix[4] = {'h', 'e', 'i', 'x'}; /* REMEMBER TO ADD MIME-TYPE TO FUNCTION php_image_type_to_mime_type */ /* PCX must check first 64bytes and byte 0=0x0a and byte2 < 0x06 */ @@ -1254,6 +1258,8 @@ PHPAPI char * php_image_type_to_mime_type(int image_type) return "image/webp"; case IMAGE_FILETYPE_AVIF: return "image/avif"; + case IMAGE_FILETYPE_HEIF: + return "image/heif"; default: case IMAGE_FILETYPE_UNKNOWN: return "application/octet-stream"; /* suppose binary format */ @@ -1339,6 +1345,10 @@ PHP_FUNCTION(image_type_to_extension) case IMAGE_FILETYPE_AVIF: imgext = ".avif"; break; + case IMAGE_FILETYPE_HEIF: + imgext = ".heif"; + break; + break; } if (imgext) { @@ -1423,6 +1433,11 @@ PHPAPI int php_getimagetype(php_stream *stream, const char *input, char *filetyp return IMAGE_FILETYPE_JP2; } + if (twelve_bytes_read && !memcmp(filetype + 4, php_sig_ftyp, 4) && + (!memcmp(filetype + 8, php_sig_mif1, 4) || !memcmp(filetype + 8, php_sig_heic, 4) || !memcmp(filetype + 8, php_sig_heix, 4))) { + return IMAGE_FILETYPE_HEIF; + } + if (!php_stream_rewind(stream) && php_is_image_avif(stream)) { return IMAGE_FILETYPE_AVIF; } @@ -1515,6 +1530,11 @@ static void php_getimagesize_from_stream(php_stream *stream, char *input, zval * case IMAGE_FILETYPE_AVIF: result = php_handle_avif(stream); break; + case IMAGE_FILETYPE_HEIF: + if (!php_stream_rewind(stream)) { + result = php_handle_avif(stream); + } + break; default: case IMAGE_FILETYPE_UNKNOWN: break; diff --git a/ext/standard/php_image.h b/ext/standard/php_image.h index a41273e6745ae..f0f3edb7283eb 100644 --- a/ext/standard/php_image.h +++ b/ext/standard/php_image.h @@ -44,6 +44,7 @@ typedef enum IMAGE_FILETYPE_ICO, IMAGE_FILETYPE_WEBP, IMAGE_FILETYPE_AVIF, + IMAGE_FILETYPE_HEIF, /* WHEN EXTENDING: PLEASE ALSO REGISTER IN basic_function.stub.php */ IMAGE_FILETYPE_COUNT } image_filetype; diff --git a/ext/standard/tests/image/getimagesize.phpt b/ext/standard/tests/image/getimagesize.phpt index 472be1d25e366..085bf96287b91 100644 --- a/ext/standard/tests/image/getimagesize.phpt +++ b/ext/standard/tests/image/getimagesize.phpt @@ -23,7 +23,7 @@ GetImageSize() var_dump($result); ?> --EXPECT-- -array(17) { +array(18) { ["test-1pix.bmp"]=> array(6) { [0]=> @@ -216,6 +216,23 @@ array(17) { ["mime"]=> string(9) "image/gif" } + ["test4pix.heic"]=> + array(7) { + [0]=> + int(54) + [1]=> + int(84) + [2]=> + int(20) + [3]=> + string(22) "width="54" height="84"" + ["bits"]=> + int(8) + ["channels"]=> + int(3) + ["mime"]=> + string(10) "image/heif" + } ["test4pix.iff"]=> array(6) { [0]=> diff --git a/ext/standard/tests/image/image_type_to_mime_type.phpt b/ext/standard/tests/image/image_type_to_mime_type.phpt index 5877efe531fd9..0102955babe73 100644 --- a/ext/standard/tests/image/image_type_to_mime_type.phpt +++ b/ext/standard/tests/image/image_type_to_mime_type.phpt @@ -24,7 +24,7 @@ image_type_to_mime_type() var_dump($result); ?> --EXPECT-- -array(17) { +array(18) { ["test-1pix.bmp"]=> string(9) "image/bmp" ["test12pix.webp"]=> @@ -49,6 +49,8 @@ array(17) { string(10) "image/webp" ["test4pix.gif"]=> string(9) "image/gif" + ["test4pix.heic"]=> + string(10) "image/heif" ["test4pix.iff"]=> string(9) "image/iff" ["test4pix.png"]=> diff --git a/ext/standard/tests/image/image_type_to_mime_type_basic.phpt b/ext/standard/tests/image/image_type_to_mime_type_basic.phpt index bf5a1ee250990..6aaa25551bd44 100644 --- a/ext/standard/tests/image/image_type_to_mime_type_basic.phpt +++ b/ext/standard/tests/image/image_type_to_mime_type_basic.phpt @@ -22,7 +22,8 @@ $image_types = array ( IMAGETYPE_WBMP, IMAGETYPE_JPEG2000, IMAGETYPE_XBM, - IMAGETYPE_WEBP + IMAGETYPE_WEBP, + IMAGETYPE_HEIF ); foreach($image_types as $image_type) { @@ -51,5 +52,6 @@ string(18) "image/vnd.wap.wbmp" string(24) "application/octet-stream" string(9) "image/xbm" string(10) "image/webp" +string(10) "image/heif" Done image_type_to_mime_type() test diff --git a/ext/standard/tests/image/image_type_to_mime_type_variation3.phpt b/ext/standard/tests/image/image_type_to_mime_type_variation3.phpt index fc17cb5ecd947..6626dc5a07c03 100644 --- a/ext/standard/tests/image/image_type_to_mime_type_variation3.phpt +++ b/ext/standard/tests/image/image_type_to_mime_type_variation3.phpt @@ -75,4 +75,7 @@ string\(10\) "image\/webp" string\(10\) "image\/avif" -- Iteration 20 -- +string\(10\) "image\/heif" + +-- Iteration 21 -- string\(24\) "application\/octet-stream" diff --git a/ext/standard/tests/image/test4pix.heic b/ext/standard/tests/image/test4pix.heic new file mode 100644 index 0000000000000..93ca3ed1faf9c Binary files /dev/null and b/ext/standard/tests/image/test4pix.heic differ