diff options
author | Christoph M. Becker <cmbecker69@gmx.de> | 2016-10-07 19:25:59 +0200 |
---|---|---|
committer | Christoph M. Becker <cmbecker69@gmx.de> | 2016-10-08 00:02:21 +0200 |
commit | 14d4ee93a8130c90ee7eb2a7136b7b299bdc0a3b (patch) | |
tree | 2e0e99235659e7275d972af280a76bad2de01428 | |
parent | 61bf62a7c0b29a4bca9f681bae79bfdbd46910f1 (diff) | |
download | php-git-14d4ee93a8130c90ee7eb2a7136b7b299bdc0a3b.tar.gz |
Implement #65038: IMAGETYPE_WEBP constant missing
We add WebP support for getimagesize(), getimagesizefromstring)(),
image_type_to_extension() and image_type_to_mime_type(). For now we
care only about the simple lossy WebP format (VP8) and ignore the
lossless (VP8L) and extended (VP8X) formats. We use image/webp as MIME
type as it appears to be pretty common, even though it is not yet
registered with IANA.
Relevant specifications:
* <https://developers.google.com/speed/webp/docs/riff_container>
* <https://tools.ietf.org/html/rfc6386>
-rw-r--r-- | UPGRADING | 3 | ||||
-rw-r--r-- | ext/standard/image.c | 46 | ||||
-rw-r--r-- | ext/standard/php_image.h | 1 | ||||
-rw-r--r-- | ext/standard/tests/image/getimagesize.phpt | 19 | ||||
-rw-r--r-- | ext/standard/tests/image/image_type_to_extension.phpt | 6 | ||||
-rw-r--r-- | ext/standard/tests/image/image_type_to_mime_type.phpt | 4 | ||||
-rw-r--r-- | ext/standard/tests/image/image_type_to_mime_type_basic.phpt | 4 | ||||
-rw-r--r-- | ext/standard/tests/image/image_type_to_mime_type_variation3.phpt | 3 | ||||
-rw-r--r-- | ext/standard/tests/image/test3pix.webp | bin | 0 -> 44 bytes |
9 files changed, 82 insertions, 4 deletions
@@ -383,6 +383,9 @@ PHP 7.1 UPGRADE NOTES PGSQL_NOTICE_ALL PGSQL_NOTICE_CLEAR +- Standard: + . IMAGETYPE_WEBP + ======================================== 11. Changes to INI File Handling ======================================== diff --git a/ext/standard/image.c b/ext/standard/image.c index 480246ab97..10386c3da0 100644 --- a/ext/standard/image.c +++ b/ext/standard/image.c @@ -55,6 +55,8 @@ PHPAPI const char php_sig_jp2[12] = {(char)0x00, (char)0x00, (char)0x00, (char)0 (char)0x0d, (char)0x0a, (char)0x87, (char)0x0a}; 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'}; /* 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 */ @@ -92,6 +94,7 @@ PHP_MINIT_FUNCTION(imagetypes) REGISTER_LONG_CONSTANT("IMAGETYPE_JPEG2000",IMAGE_FILETYPE_JPC, CONST_CS | CONST_PERSISTENT); /* keep alias */ 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_UNKNOWN", IMAGE_FILETYPE_UNKNOWN, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("IMAGETYPE_COUNT", IMAGE_FILETYPE_COUNT, CONST_CS | CONST_PERSISTENT); return SUCCESS; @@ -1119,6 +1122,32 @@ static struct gfxinfo *php_handle_ico(php_stream * stream) } /* }}} */ +/* {{{ php_handle_webp + */ +static struct gfxinfo *php_handle_webp(php_stream * stream) +{ + struct gfxinfo *result = NULL; + const char sig[4] = {'V', 'P', '8', ' '}; + unsigned char buf[18]; + + if (php_stream_read(stream, (char *) buf, 18) != 18) + return NULL; + + if (memcmp(buf, sig, 4)) { /* simple lossy WebP only */ + return NULL; + } + + result = (struct gfxinfo *) ecalloc(1, sizeof(struct gfxinfo)); + + result->width = (buf[14]) + ((buf[15] & 0x3F) << 8); + result->height = (buf[16]) + ((buf[17] & 0x3F) << 8); + result->bits = 8; /* always 1 byte */ + result->channels = 3; /* always YUV */ + + 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) @@ -1152,6 +1181,8 @@ PHPAPI char * php_image_type_to_mime_type(int image_type) return "image/xbm"; case IMAGE_FILETYPE_ICO: return "image/vnd.microsoft.icon"; + case IMAGE_FILETYPE_WEBP: + return "image/webp"; default: case IMAGE_FILETYPE_UNKNOWN: return "application/octet-stream"; /* suppose binary format */ @@ -1216,6 +1247,8 @@ PHP_FUNCTION(image_type_to_extension) RETURN_STRING(".xbm" + !inc_dot); case IMAGE_FILETYPE_ICO: RETURN_STRING(".ico" + !inc_dot); + case IMAGE_FILETYPE_WEBP: + RETURN_STRING(".webp" + !inc_dot); } RETURN_FALSE; @@ -1261,6 +1294,16 @@ PHPAPI int php_getimagetype(php_stream * stream, char *filetype) return IMAGE_FILETYPE_BMP; } else if (!memcmp(filetype, php_sig_jpc, 3)) { return IMAGE_FILETYPE_JPC; + } else if (!memcmp(filetype, php_sig_riff, 3)) { + if (php_stream_read(stream, filetype+3, 9) != 9) { + php_error_docref(NULL, E_NOTICE, "Read error!"); + return IMAGE_FILETYPE_UNKNOWN; + } + if (!memcmp(filetype+8, php_sig_webp, 4)) { + return IMAGE_FILETYPE_WEBP; + } else { + return IMAGE_FILETYPE_UNKNOWN; + } } if (php_stream_read(stream, filetype+3, 1) != 1) { @@ -1365,6 +1408,9 @@ static void php_getimagesize_from_stream(php_stream *stream, zval *info, INTERNA case IMAGE_FILETYPE_ICO: result = php_handle_ico(stream); break; + case IMAGE_FILETYPE_WEBP: + result = php_handle_webp(stream); + break; default: case IMAGE_FILETYPE_UNKNOWN: break; diff --git a/ext/standard/php_image.h b/ext/standard/php_image.h index 1b58b075eb..0810b4b2f5 100644 --- a/ext/standard/php_image.h +++ b/ext/standard/php_image.h @@ -52,6 +52,7 @@ typedef enum /* IMAGE_FILETYPE_JPEG2000 is a userland alias for IMAGE_FILETYPE_JPC */ IMAGE_FILETYPE_XBM, IMAGE_FILETYPE_ICO, + IMAGE_FILETYPE_WEBP, /* 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 04ddd8c82b..e088322104 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(13) { +array(14) { ["test-1pix.bmp"]=> array(6) { [0]=> @@ -137,6 +137,23 @@ array(13) { ["mime"]=> string(9) "image/gif" } + ["test3pix.webp"]=> + array(7) { + [0]=> + int(1) + [1]=> + int(3) + [2]=> + int(18) + [3]=> + string(20) "width="1" height="3"" + ["bits"]=> + int(8) + ["channels"]=> + int(3) + ["mime"]=> + string(10) "image/webp" + } ["test4pix.gif"]=> array(7) { [0]=> diff --git a/ext/standard/tests/image/image_type_to_extension.phpt b/ext/standard/tests/image/image_type_to_extension.phpt index c668e3408d..0c15890530 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_IFF" => IMAGETYPE_IFF, "IMAGETYPE_WBMP" => IMAGETYPE_WBMP, "IMAGETYPE_JPEG2000" => IMAGETYPE_JPEG2000, - "IMAGETYPE_XBM" => IMAGETYPE_XBM + "IMAGETYPE_XBM" => IMAGETYPE_XBM, + "IMAGETYPE_WEBP" => IMAGETYPE_WEBP ); 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)); @@ -86,6 +87,9 @@ Constant: IMAGETYPE_JPEG2000 Constant: IMAGETYPE_XBM With dot: .xbm Without dot: xbm +Constant: IMAGETYPE_WEBP + With dot: .webp + Without dot: webp Warning: image_type_to_extension() expects parameter 2 to be boolean, array given in %s on line %d bool(false) 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 9f7ffa1aa3..492c8434af 100644 --- a/ext/standard/tests/image/image_type_to_mime_type.phpt +++ b/ext/standard/tests/image/image_type_to_mime_type.phpt @@ -25,7 +25,7 @@ image_type_to_mime_type() var_dump($result); ?> --EXPECT-- -array(13) { +array(14) { ["test-1pix.bmp"]=> string(14) "image/x-ms-bmp" ["test1bpix.bmp"]=> @@ -40,6 +40,8 @@ array(13) { string(10) "image/jpeg" ["test2pix.gif"]=> string(9) "image/gif" + ["test3pix.webp"]=> + string(10) "image/webp" ["test4pix.gif"]=> string(9) "image/gif" ["test4pix.iff"]=> 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 b81bdbde5f..5506570494 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 @@ -31,7 +31,8 @@ $image_types = array ( IMAGETYPE_IFF, IMAGETYPE_WBMP, IMAGETYPE_JPEG2000, - IMAGETYPE_XBM + IMAGETYPE_XBM, + IMAGETYPE_WEBP ); foreach($image_types as $image_type) { @@ -59,5 +60,6 @@ string(9) "image/iff" string(18) "image/vnd.wap.wbmp" string(24) "application/octet-stream" string(9) "image/xbm" +string(10) "image/webp" 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 192f23dcee..7b06c0a145 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,5 +75,8 @@ string\(9\) "image\/xbm" string\(24\) "image\/vnd.microsoft.icon" -- Iteration 18 -- +string\(10\) "image\/webp" + +-- Iteration 19 -- string\(24\) "application\/octet-stream" ===DONE=== diff --git a/ext/standard/tests/image/test3pix.webp b/ext/standard/tests/image/test3pix.webp Binary files differnew file mode 100644 index 0000000000..e5c6410fe3 --- /dev/null +++ b/ext/standard/tests/image/test3pix.webp |