summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristoph M. Becker <cmbecker69@gmx.de>2016-10-07 19:25:59 +0200
committerChristoph M. Becker <cmbecker69@gmx.de>2016-10-08 00:02:21 +0200
commit14d4ee93a8130c90ee7eb2a7136b7b299bdc0a3b (patch)
tree2e0e99235659e7275d972af280a76bad2de01428
parent61bf62a7c0b29a4bca9f681bae79bfdbd46910f1 (diff)
downloadphp-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--UPGRADING3
-rw-r--r--ext/standard/image.c46
-rw-r--r--ext/standard/php_image.h1
-rw-r--r--ext/standard/tests/image/getimagesize.phpt19
-rw-r--r--ext/standard/tests/image/image_type_to_extension.phpt6
-rw-r--r--ext/standard/tests/image/image_type_to_mime_type.phpt4
-rw-r--r--ext/standard/tests/image/image_type_to_mime_type_basic.phpt4
-rw-r--r--ext/standard/tests/image/image_type_to_mime_type_variation3.phpt3
-rw-r--r--ext/standard/tests/image/test3pix.webpbin0 -> 44 bytes
9 files changed, 82 insertions, 4 deletions
diff --git a/UPGRADING b/UPGRADING
index 68f3364b10..d197f84d71 100644
--- a/UPGRADING
+++ b/UPGRADING
@@ -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
new file mode 100644
index 0000000000..e5c6410fe3
--- /dev/null
+++ b/ext/standard/tests/image/test3pix.webp
Binary files differ