From b968d5bb92e7637c2376a070b8029a85fad4a235 Mon Sep 17 00:00:00 2001 From: y-hashida Date: Fri, 17 Jan 2020 21:25:13 +0900 Subject: [PATCH 1/3] Added suport for AVIF to getimagesize(). --- ext/standard/image.c | 109 ++++++++++++++++++ ext/standard/php_image.h | 1 + ext/standard/tests/image/getimagesize.phpt | 19 ++- .../tests/image/image_type_to_extension.phpt | 6 +- .../tests/image/image_type_to_mime_type.phpt | 4 +- .../image/image_type_to_mime_type_basic.phpt | 4 +- .../image_type_to_mime_type_variation3.phpt | 3 + ext/standard/tests/image/test8pix.avif | Bin 0 -> 333 bytes 8 files changed, 142 insertions(+), 4 deletions(-) create mode 100644 ext/standard/tests/image/test8pix.avif diff --git a/ext/standard/image.c b/ext/standard/image.c index 2154f8e32295b..7d9ea30935f71 100644 --- a/ext/standard/image.c +++ b/ext/standard/image.c @@ -50,6 +50,7 @@ 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_avif[4] = {'a', 'v', 'i', 'f'}; /* 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 */ @@ -88,6 +89,7 @@ PHP_MINIT_FUNCTION(imagetypes) REGISTER_LONG_CONSTANT("IMAGETYPE_XBM", IMAGE_FILETYPE_XBM, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("IMAGETYPE_ICO", IMAGE_FILETYPE_ICO, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("IMAGETYPE_WEBP", IMAGE_FILETYPE_WEBP, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("IMAGETYPE_AVIF", IMAGE_FILETYPE_AVIF, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("IMAGETYPE_UNKNOWN", IMAGE_FILETYPE_UNKNOWN, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("IMAGETYPE_COUNT", IMAGE_FILETYPE_COUNT, CONST_CS | CONST_PERSISTENT); return SUCCESS; @@ -1148,6 +1150,103 @@ static struct gfxinfo *php_handle_webp(php_stream * stream) } /* }}} */ +/* {{{ php_handle_avif + */ +static struct gfxinfo *php_handle_avif(php_stream * stream) { + struct gfxinfo *result = NULL; + unsigned int width = 0, height = 0; + unsigned char channels = 0, bits = 0, i, bits_tmp; + unsigned int size, type; + size_t begin, end, pos = 0; + int check_ispe = 0, check_pixi = 0, eof; + + if (php_stream_seek(stream, 0, SEEK_SET)) { + return NULL; + } + for(;;) { + eof = php_stream_eof(stream); + if (eof == -1) { + return NULL; + } else if ((check_ispe == 1 && check_pixi == 1) || eof == 1) { + break; + } + + begin = pos; + size = php_read4(stream); pos += 4; + type = php_read4(stream); pos += 4; + end = begin + size; + + switch (type) { + case 1835365473u: /* meta */ + if (php_stream_seek(stream, 4, SEEK_CUR)) { + return NULL; + } + pos += 4; + continue; + + case 1768977008u: /* iprp */ + case 1768973167u: /* ipco */ + continue; + + case 1769173093u: /* ispe */ + if (php_stream_seek(stream, 4, SEEK_CUR)) { + return NULL; + } + pos += 4; + width = php_read4(stream); pos += 4; + height = php_read4(stream); pos += 4; + check_ispe = 1; + break; + + case 1885960297u: /* pixi */ + if (php_stream_seek(stream, 4, SEEK_CUR)) { + return NULL; + } + pos += 4; + + /* channels */ + if (php_stream_read(stream, (char *)&channels, 1) != 1) { + return NULL; + } + pos++; + + /* bits */ + for (i = 0; i < channels; i++) { + if (php_stream_read(stream, (char *)&bits_tmp, 1) != 1) { + return NULL; + } + pos++; + + if (bits_tmp > bits) { + bits = bits_tmp; + } + } + check_pixi = 1; + break; + + default: + break; + } + + pos = end; + if (php_stream_seek(stream, end, SEEK_SET)) { + return NULL; + } + } + + result = (struct gfxinfo *) ecalloc(1, sizeof(struct gfxinfo)); + if (result == NULL) { + return NULL; + } + + result->width = width; + result->height = height; + result->bits = bits; + result->channels = channels; + return result; +} +/* }}} */ + /* {{{ php_image_type_to_mime_type * Convert internal image_type to mime type */ PHPAPI char * php_image_type_to_mime_type(int image_type) @@ -1183,6 +1282,8 @@ PHPAPI char * php_image_type_to_mime_type(int image_type) return "image/vnd.microsoft.icon"; case IMAGE_FILETYPE_WEBP: return "image/webp"; + case IMAGE_FILETYPE_AVIF: + return "image/avif"; default: case IMAGE_FILETYPE_UNKNOWN: return "application/octet-stream"; /* suppose binary format */ @@ -1265,6 +1366,9 @@ PHP_FUNCTION(image_type_to_extension) case IMAGE_FILETYPE_WEBP: imgext = ".webp"; break; + case IMAGE_FILETYPE_AVIF: + imgext = ".avif"; + break; } if (imgext) { @@ -1347,6 +1451,8 @@ PHPAPI int php_getimagetype(php_stream * stream, const char *input, char *filety /* BYTES READ: 12 */ if (twelve_bytes_read && !memcmp(filetype, php_sig_jp2, 12)) { return IMAGE_FILETYPE_JP2; + } else if (twelve_bytes_read && !memcmp(filetype+8, php_sig_avif, 4)) { + return IMAGE_FILETYPE_AVIF; } /* AFTER ALL ABOVE FAILED */ @@ -1431,6 +1537,9 @@ static void php_getimagesize_from_stream(php_stream *stream, char *input, zval * case IMAGE_FILETYPE_WEBP: result = php_handle_webp(stream); break; + case IMAGE_FILETYPE_AVIF: + 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 3649e62198b50..afd75138f2ddf 100644 --- a/ext/standard/php_image.h +++ b/ext/standard/php_image.h @@ -43,6 +43,7 @@ typedef enum IMAGE_FILETYPE_XBM, IMAGE_FILETYPE_ICO, IMAGE_FILETYPE_WEBP, + IMAGE_FILETYPE_AVIF, /* WHEN EXTENDING: PLEASE ALSO REGISTER IN image.c:PHP_MINIT_FUNCTION(imagetypes) */ IMAGE_FILETYPE_COUNT } image_filetype; diff --git a/ext/standard/tests/image/getimagesize.phpt b/ext/standard/tests/image/getimagesize.phpt index 582959f3ae6ee..0e6f7d7227bb5 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(16) { +array(17) { ["test-1pix.bmp"]=> array(6) { [0]=> @@ -268,4 +268,21 @@ array(16) { ["mime"]=> string(10) "image/tiff" } + ["test8pix.avif"]=> + array(7) { + [0]=> + int(8) + [1]=> + int(1) + [2]=> + int(19) + [3]=> + string(20) "width="8" height="1"" + ["bits"]=> + int(8) + ["channels"]=> + int(3) + ["mime"]=> + string(10) "image/avif" + } } diff --git a/ext/standard/tests/image/image_type_to_extension.phpt b/ext/standard/tests/image/image_type_to_extension.phpt index fd60fc454e10b..7353fc05fd94a 100644 --- a/ext/standard/tests/image/image_type_to_extension.phpt +++ b/ext/standard/tests/image/image_type_to_extension.phpt @@ -23,7 +23,8 @@ image_type_to_extension() "IMAGETYPE_WBMP" => IMAGETYPE_WBMP, "IMAGETYPE_JPEG2000" => IMAGETYPE_JPEG2000, "IMAGETYPE_XBM" => IMAGETYPE_XBM, - "IMAGETYPE_WEBP" => IMAGETYPE_WEBP + "IMAGETYPE_WEBP" => IMAGETYPE_WEBP, + "IMAGETYPE_AVIF" => IMAGETYPE_AVIF ); foreach($constants as $name => $constant) { printf("Constant: %s\n\tWith dot: %s\n\tWithout dot: %s\n", $name, image_type_to_extension($constant), image_type_to_extension($constant, false)); @@ -85,6 +86,9 @@ Constant: IMAGETYPE_XBM Constant: IMAGETYPE_WEBP With dot: .webp Without dot: webp +Constant: IMAGETYPE_AVIF + With dot: .avif + Without dot: avif bool(false) bool(false) Done 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 b4f6d3c403fa1..cf00544b507ec 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(16) { +array(17) { ["test-1pix.bmp"]=> string(9) "image/bmp" ["test12pix.webp"]=> @@ -57,4 +57,6 @@ array(16) { string(29) "application/x-shockwave-flash" ["test4pix.tiff"]=> string(10) "image/tiff" + ["test8pix.avif"]=> + string(10) "image/avif" } 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..882146ef3aeea 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_AVIF ); 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/avif" 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 49a53c468b1d3..fc17cb5ecd947 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 @@ -72,4 +72,7 @@ string\(24\) "image\/vnd.microsoft.icon" string\(10\) "image\/webp" -- Iteration 19 -- +string\(10\) "image\/avif" + +-- Iteration 20 -- string\(24\) "application\/octet-stream" diff --git a/ext/standard/tests/image/test8pix.avif b/ext/standard/tests/image/test8pix.avif new file mode 100644 index 0000000000000000000000000000000000000000..810007a3ef24abb9eba9c48db374723f101b0d92 GIT binary patch literal 333 zcmYjL!AiqG5S@($Q<0K`P*AA_Z$eGeqo;zGdiD#p+oT!HHbb%v6)#HrIsS-OkDmPj zzo5=+Tj+z~&3p4^X93_kbFZWu%zzx;sS^z@h4!y9E#r~k5 zJ4f|H9M93^%jvx-ZCv2uWw4BWLZTH?Ma<7greuyt*P_+FF0iJQdqK!0enhxJF;2oz zysmDN#}7D%voE|NWbSAlA&V7=k_9pWOBXBa}4EYo1GbTdqzte*RmJuFHi igVvanenpKuU$J>>XWAWI9Caf20|?%Kzu$&mpFjWI Date: Wed, 29 Jan 2020 20:06:24 +0900 Subject: [PATCH 2/3] update: re-create test8pix.avif --- ext/standard/tests/image/test8pix.avif | Bin 333 -> 367 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/ext/standard/tests/image/test8pix.avif b/ext/standard/tests/image/test8pix.avif index 810007a3ef24abb9eba9c48db374723f101b0d92..6e2224749bc458783e15f7f5670db2a28ba3affc 100644 GIT binary patch delta 174 zcmX@h^qxtDfq_9Gt)#Lbu`DwU$Yuc1xtVE(xtWP+zK(`Y3=E7C6BUA`iazTP%p}fq3q5>e>e`1X_zi?uip>rbx4+9sg1cznA z#8c8H=D8_}B@ix$k(vMl!-Pb`oTE!wcbAqGYKk&l+vIigTGO5audtaL8W`)Q|E#~T GZV>?GTQ6<^ delta 143 zcmaFQbe2hhfq_9Lt)#Lbu`DwU$Yuc1xtVE(xtWPTJ|o{mm0-@I%z~l Date: Wed, 29 Jan 2020 20:43:00 +0900 Subject: [PATCH 3/3] Add getimagesize()'s test for avif using monochrome. --- .../image/getimagesize_avif_monochrome.phpt | 34 ++++++++++++++++++ ext/standard/tests/image/monochrome.avif | Bin 0 -> 348 bytes 2 files changed, 34 insertions(+) create mode 100644 ext/standard/tests/image/getimagesize_avif_monochrome.phpt create mode 100644 ext/standard/tests/image/monochrome.avif diff --git a/ext/standard/tests/image/getimagesize_avif_monochrome.phpt b/ext/standard/tests/image/getimagesize_avif_monochrome.phpt new file mode 100644 index 0000000000000..d735749c9f0aa --- /dev/null +++ b/ext/standard/tests/image/getimagesize_avif_monochrome.phpt @@ -0,0 +1,34 @@ +--TEST-- +GetImageSize() for avif using monochrome format +--FILE-- + +--EXPECT-- +*** Testing getimagesize() : avif using monochrome format *** +array(7) { + [0]=> + int(8) + [1]=> + int(1) + [2]=> + int(19) + [3]=> + string(20) "width="8" height="1"" + ["bits"]=> + int(8) + ["channels"]=> + int(1) + ["mime"]=> + string(10) "image/avif" +} +array(0) { +} diff --git a/ext/standard/tests/image/monochrome.avif b/ext/standard/tests/image/monochrome.avif new file mode 100644 index 0000000000000000000000000000000000000000..488ced08678ffd3550878fe7bb33c16c8dd676fe GIT binary patch literal 348 zcmXwzze)o^5XNUiglHiF{}SZ5MnNH-mqO4&qG_~9Yrk%8bAz{cLv9na35Y?kw)A~` z0H4BIU%;6)&a!;J`SzP(0U);ik@O5LaEUs!sY7jtm+2LN+IE@O^2T+YkBZ430uUPi z&!R?#<8GXLPxX0{jM3-QyJJ(iq`>mNJ554Dq7fFA5oq>7@!?VzK_kW^#L@Kwu%%H^C(6e;# z1beWyvfDaa^x4`$a++0&zuHud=LO?|8)?5x^|spZ^7(ogeSiF%zTfr+`)}oZ_3Ia5 CdP6M$ literal 0 HcmV?d00001