mirror of
https://github.com/php/php-src.git
synced 2025-08-15 21:48:51 +02:00
AVIF support for getimagesize() and imagecreatefromstring()
Thanks to Joe Drago for help with the AVIF detection code. Co-authored-by: Nikita Popov <nikita.ppv@googlemail.com> Co-authored-by: Christoph M. Becker <cmbecker69@gmx.de> Closes GH-7091.
This commit is contained in:
parent
a5360e80c2
commit
cee33bab16
13 changed files with 208 additions and 38 deletions
55
ext/gd/gd.c
55
ext/gd/gd.c
|
@ -31,8 +31,10 @@
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include "SAPI.h"
|
#include "SAPI.h"
|
||||||
#include "php_gd.h"
|
#include "php_gd.h"
|
||||||
|
#include "ext/standard/php_image.h"
|
||||||
#include "ext/standard/info.h"
|
#include "ext/standard/info.h"
|
||||||
#include "php_open_temporary_file.h"
|
#include "php_open_temporary_file.h"
|
||||||
|
#include "php_memory_streams.h"
|
||||||
#include "zend_object_handlers.h"
|
#include "zend_object_handlers.h"
|
||||||
#include "zend_interfaces.h"
|
#include "zend_interfaces.h"
|
||||||
|
|
||||||
|
@ -145,7 +147,7 @@ static void _php_image_output(INTERNAL_FUNCTION_PARAMETERS, int image_type, char
|
||||||
static gdIOCtx *create_stream_context_from_zval(zval *to_zval);
|
static gdIOCtx *create_stream_context_from_zval(zval *to_zval);
|
||||||
static gdIOCtx *create_stream_context(php_stream *stream, int close_stream);
|
static gdIOCtx *create_stream_context(php_stream *stream, int close_stream);
|
||||||
static gdIOCtx *create_output_context(void);
|
static gdIOCtx *create_output_context(void);
|
||||||
static int _php_image_type(char data[12]);
|
static int _php_image_type(zend_string *data);
|
||||||
|
|
||||||
/* output streaming (formerly gd_ctx.c) */
|
/* output streaming (formerly gd_ctx.c) */
|
||||||
static void _php_image_output_ctx(INTERNAL_FUNCTION_PARAMETERS, int image_type, char *tn, void (*func_p)());
|
static void _php_image_output_ctx(INTERNAL_FUNCTION_PARAMETERS, int image_type, char *tn, void (*func_p)());
|
||||||
|
@ -1469,33 +1471,45 @@ static int _php_ctx_getmbi(gdIOCtx *ctx)
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ _php_image_type */
|
/* {{{ _php_image_type
|
||||||
|
* Based on ext/standard/image.c
|
||||||
|
*/
|
||||||
static const char php_sig_gd2[3] = {'g', 'd', '2'};
|
static const char php_sig_gd2[3] = {'g', 'd', '2'};
|
||||||
|
|
||||||
static int _php_image_type (char data[12])
|
static int _php_image_type(zend_string *data)
|
||||||
{
|
{
|
||||||
/* Based on ext/standard/image.c */
|
if (ZSTR_LEN(data) < 12) {
|
||||||
|
/* Handle this the same way as an unknown image type. */
|
||||||
if (data == NULL) {
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!memcmp(data, php_sig_gd2, sizeof(php_sig_gd2))) {
|
if (!memcmp(ZSTR_VAL(data), php_sig_gd2, sizeof(php_sig_gd2))) {
|
||||||
return PHP_GDIMG_TYPE_GD2;
|
return PHP_GDIMG_TYPE_GD2;
|
||||||
} else if (!memcmp(data, php_sig_jpg, sizeof(php_sig_jpg))) {
|
} else if (!memcmp(ZSTR_VAL(data), php_sig_jpg, sizeof(php_sig_jpg))) {
|
||||||
return PHP_GDIMG_TYPE_JPG;
|
return PHP_GDIMG_TYPE_JPG;
|
||||||
} else if (!memcmp(data, php_sig_png, sizeof(php_sig_png))) {
|
} else if (!memcmp(ZSTR_VAL(data), php_sig_png, sizeof(php_sig_png))) {
|
||||||
return PHP_GDIMG_TYPE_PNG;
|
return PHP_GDIMG_TYPE_PNG;
|
||||||
} else if (!memcmp(data, php_sig_gif, sizeof(php_sig_gif))) {
|
} else if (!memcmp(ZSTR_VAL(data), php_sig_gif, sizeof(php_sig_gif))) {
|
||||||
return PHP_GDIMG_TYPE_GIF;
|
return PHP_GDIMG_TYPE_GIF;
|
||||||
} else if (!memcmp(data, php_sig_bmp, sizeof(php_sig_bmp))) {
|
} else if (!memcmp(ZSTR_VAL(data), php_sig_bmp, sizeof(php_sig_bmp))) {
|
||||||
return PHP_GDIMG_TYPE_BMP;
|
return PHP_GDIMG_TYPE_BMP;
|
||||||
} else if(!memcmp(data, php_sig_riff, sizeof(php_sig_riff)) && !memcmp(data + sizeof(php_sig_riff) + sizeof(uint32_t), php_sig_webp, sizeof(php_sig_webp))) {
|
} 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))) {
|
||||||
return PHP_GDIMG_TYPE_WEBP;
|
return PHP_GDIMG_TYPE_WEBP;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
|
php_stream *image_stream = php_stream_memory_open(TEMP_STREAM_READONLY, data);
|
||||||
|
|
||||||
|
if (image_stream != NULL) {
|
||||||
|
bool is_avif = php_is_image_avif(image_stream);
|
||||||
|
php_stream_close(image_stream);
|
||||||
|
|
||||||
|
if (is_avif) {
|
||||||
|
return PHP_GDIMG_TYPE_AVIF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
gdIOCtx *io_ctx;
|
gdIOCtx *io_ctx;
|
||||||
io_ctx = gdNewDynamicCtxEx(8, data, 0);
|
io_ctx = gdNewDynamicCtxEx(8, ZSTR_VAL(data), 0);
|
||||||
if (io_ctx) {
|
if (io_ctx) {
|
||||||
if (_php_ctx_getmbi(io_ctx) == 0 && _php_ctx_getmbi(io_ctx) >= 0) {
|
if (_php_ctx_getmbi(io_ctx) == 0 && _php_ctx_getmbi(io_ctx) >= 0) {
|
||||||
io_ctx->gd_free(io_ctx);
|
io_ctx->gd_free(io_ctx);
|
||||||
|
@ -1504,7 +1518,7 @@ static int _php_image_type (char data[12])
|
||||||
io_ctx->gd_free(io_ctx);
|
io_ctx->gd_free(io_ctx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
@ -1540,21 +1554,12 @@ PHP_FUNCTION(imagecreatefromstring)
|
||||||
zend_string *data;
|
zend_string *data;
|
||||||
gdImagePtr im;
|
gdImagePtr im;
|
||||||
int imtype;
|
int imtype;
|
||||||
char sig[12];
|
|
||||||
|
|
||||||
if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &data) == FAILURE) {
|
if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &data) == FAILURE) {
|
||||||
RETURN_THROWS();
|
RETURN_THROWS();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ZSTR_LEN(data) < sizeof(sig)) {
|
imtype = _php_image_type(data);
|
||||||
/* Handle this the same way as an unknown image type. */
|
|
||||||
php_error_docref(NULL, E_WARNING, "Data is not in a recognized format");
|
|
||||||
RETURN_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(sig, ZSTR_VAL(data), sizeof(sig));
|
|
||||||
|
|
||||||
imtype = _php_image_type(sig);
|
|
||||||
|
|
||||||
switch (imtype) {
|
switch (imtype) {
|
||||||
case PHP_GDIMG_TYPE_JPG:
|
case PHP_GDIMG_TYPE_JPG:
|
||||||
|
|
|
@ -628,7 +628,6 @@ gdImagePtr gdImageCreateFromGif(FILE *fd);
|
||||||
gdImagePtr gdImageCreateFromGifCtx(gdIOCtxPtr in);
|
gdImagePtr gdImageCreateFromGifCtx(gdIOCtxPtr in);
|
||||||
gdImagePtr gdImageCreateFromGifSource(gdSourcePtr in);
|
gdImagePtr gdImageCreateFromGifSource(gdSourcePtr in);
|
||||||
|
|
||||||
//TODO: we may not need all of these
|
|
||||||
void gdImageAvif(gdImagePtr im, FILE *outfile);
|
void gdImageAvif(gdImagePtr im, FILE *outfile);
|
||||||
void gdImageAvifEx(gdImagePtr im, FILE *outfile, int quality, int speed);
|
void gdImageAvifEx(gdImagePtr im, FILE *outfile, int quality, int speed);
|
||||||
void *gdImageAvifPtr(gdImagePtr im, int *size);
|
void *gdImageAvifPtr(gdImagePtr im, int *size);
|
||||||
|
|
|
@ -18,6 +18,9 @@
|
||||||
#ifndef PHP_GD_H
|
#ifndef PHP_GD_H
|
||||||
#define PHP_GD_H
|
#define PHP_GD_H
|
||||||
|
|
||||||
|
#include "zend_string.h"
|
||||||
|
#include "php_streams.h"
|
||||||
|
|
||||||
#if defined(HAVE_LIBGD) || defined(HAVE_GD_BUNDLED)
|
#if defined(HAVE_LIBGD) || defined(HAVE_GD_BUNDLED)
|
||||||
|
|
||||||
/* open_basedir and safe_mode checks */
|
/* open_basedir and safe_mode checks */
|
||||||
|
|
29
ext/gd/tests/imagecreatefromstring_avif.phpt
Normal file
29
ext/gd/tests/imagecreatefromstring_avif.phpt
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
--TEST--
|
||||||
|
imagecreatefromstring() - AVIF format
|
||||||
|
--EXTENSIONS--
|
||||||
|
gd
|
||||||
|
--SKIPIF--
|
||||||
|
<?php
|
||||||
|
if (!(imagetypes() & IMG_AVIF)) {
|
||||||
|
die('skip AVIF support required');
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
echo "Reading image whose major brand is 'avif':\n";
|
||||||
|
$im = imagecreatefromstring(file_get_contents(__DIR__ . '/imagecreatefromstring_major_brand.avif'));
|
||||||
|
var_dump(imagesx($im));
|
||||||
|
var_dump(imagesy($im));
|
||||||
|
|
||||||
|
echo "Reading image with a compatible brand that's 'avif':\n";
|
||||||
|
$im = imagecreatefromstring(file_get_contents(__DIR__ . '/imagecreatefromstring_compatible_brand.avif'));
|
||||||
|
var_dump(imagesx($im));
|
||||||
|
var_dump(imagesy($im));
|
||||||
|
?>
|
||||||
|
--EXPECT--
|
||||||
|
Reading image whose major brand is 'avif':
|
||||||
|
int(250)
|
||||||
|
int(375)
|
||||||
|
Reading image with a compatible brand that's 'avif':
|
||||||
|
int(480)
|
||||||
|
int(270)
|
BIN
ext/gd/tests/imagecreatefromstring_compatible_brand.avif
Normal file
BIN
ext/gd/tests/imagecreatefromstring_compatible_brand.avif
Normal file
Binary file not shown.
BIN
ext/gd/tests/imagecreatefromstring_major_brand.avif
Normal file
BIN
ext/gd/tests/imagecreatefromstring_major_brand.avif
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.7 KiB |
|
@ -88,6 +88,7 @@ PHP_MINIT_FUNCTION(imagetypes)
|
||||||
REGISTER_LONG_CONSTANT("IMAGETYPE_XBM", IMAGE_FILETYPE_XBM, CONST_CS | CONST_PERSISTENT);
|
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_ICO", IMAGE_FILETYPE_ICO, CONST_CS | CONST_PERSISTENT);
|
||||||
REGISTER_LONG_CONSTANT("IMAGETYPE_WEBP", IMAGE_FILETYPE_WEBP, 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_UNKNOWN", IMAGE_FILETYPE_UNKNOWN, CONST_CS | CONST_PERSISTENT);
|
||||||
REGISTER_LONG_CONSTANT("IMAGETYPE_COUNT", IMAGE_FILETYPE_COUNT, CONST_CS | CONST_PERSISTENT);
|
REGISTER_LONG_CONSTANT("IMAGETYPE_COUNT", IMAGE_FILETYPE_COUNT, CONST_CS | CONST_PERSISTENT);
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
|
@ -1148,6 +1149,99 @@ static struct gfxinfo *php_handle_webp(php_stream * stream)
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
/* {{{ php_handle_avif
|
||||||
|
* There's no simple way to get this information - so, for now, this is unsupported.
|
||||||
|
* Simply return 0 for everything.
|
||||||
|
*/
|
||||||
|
static struct gfxinfo *php_handle_avif(php_stream * stream) {
|
||||||
|
return ecalloc(1, sizeof(struct gfxinfo));
|
||||||
|
}
|
||||||
|
/* }}} */
|
||||||
|
|
||||||
|
/* {{{ php_ntohl
|
||||||
|
* Convert a big-endian network uint32 to host order -
|
||||||
|
* which may be either little-endian or big-endian.
|
||||||
|
* Thanks to Rob Pike via Joe Drago:
|
||||||
|
* https://commandcenter.blogspot.nl/2012/04/byte-order-fallacy.html
|
||||||
|
*/
|
||||||
|
static uint32_t php_ntohl(uint32_t val) {
|
||||||
|
uint8_t data[4];
|
||||||
|
|
||||||
|
memcpy(&data, &val, sizeof(data));
|
||||||
|
return ((uint32_t)data[3] << 0) |
|
||||||
|
((uint32_t)data[2] << 8) |
|
||||||
|
((uint32_t)data[1] << 16) |
|
||||||
|
((uint32_t)data[0] << 24);
|
||||||
|
}
|
||||||
|
/* }}} */
|
||||||
|
|
||||||
|
/* {{{ php_is_image_avif
|
||||||
|
* detect whether an image is of type AVIF
|
||||||
|
*
|
||||||
|
* An AVIF image will start off a header "box".
|
||||||
|
* This starts with with a four-byte integer containing the number of bytes in the filetype box.
|
||||||
|
* This must be followed by the string "ftyp".
|
||||||
|
* Next comes a four-byte string indicating the "major brand".
|
||||||
|
* If that's "avif" or "avis", this is an AVIF image.
|
||||||
|
* Next, there's a four-byte "minor version" field, which we can ignore.
|
||||||
|
* Next comes an array of four-byte strings containing "compatible brands".
|
||||||
|
* These extend to the end of the box.
|
||||||
|
* If any of the compatible brands is "avif" or "avis", then this is an AVIF image.
|
||||||
|
* Otherwise, well, it's not.
|
||||||
|
* For more, see https://mpeg.chiariglione.org/standards/mpeg-4/iso-base-media-file-format/text-isoiec-14496-12-5th-edition
|
||||||
|
*/
|
||||||
|
bool php_is_image_avif(php_stream * stream) {
|
||||||
|
uint32_t header_size_reversed, header_size, i;
|
||||||
|
char box_type[4], brand[4];
|
||||||
|
|
||||||
|
ZEND_ASSERT(stream != NULL);
|
||||||
|
|
||||||
|
if (php_stream_read(stream, (char *) &header_size_reversed, 4) != 4) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
header_size = php_ntohl(header_size_reversed);
|
||||||
|
|
||||||
|
/* If the box type isn't "ftyp", it can't be an AVIF image. */
|
||||||
|
if (php_stream_read(stream, box_type, 4) != 4) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (memcmp(box_type, "ftyp", 4)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If the major brand is "avif" or "avis", it's an AVIF image. */
|
||||||
|
if (php_stream_read(stream, brand, 4) != 4) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!memcmp(brand, "avif", 4) || !memcmp(brand, "avis", 4)) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Skip the next four bytes, which are the "minor version". */
|
||||||
|
if (php_stream_read(stream, brand, 4) != 4) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Look for "avif" or "avis" in any member of compatible_brands[], to the end of the header.
|
||||||
|
Note we've already read four groups of four bytes. */
|
||||||
|
|
||||||
|
for (i = 16; i < header_size; i += 4) {
|
||||||
|
if (php_stream_read(stream, brand, 4) != 4) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!memcmp(brand, "avif", 4) || !memcmp(brand, "avis", 4)) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ php_image_type_to_mime_type
|
/* {{{ php_image_type_to_mime_type
|
||||||
* Convert internal image_type to mime type */
|
* Convert internal image_type to mime type */
|
||||||
PHPAPI char * php_image_type_to_mime_type(int image_type)
|
PHPAPI char * php_image_type_to_mime_type(int image_type)
|
||||||
|
@ -1183,6 +1277,8 @@ PHPAPI char * php_image_type_to_mime_type(int image_type)
|
||||||
return "image/vnd.microsoft.icon";
|
return "image/vnd.microsoft.icon";
|
||||||
case IMAGE_FILETYPE_WEBP:
|
case IMAGE_FILETYPE_WEBP:
|
||||||
return "image/webp";
|
return "image/webp";
|
||||||
|
case IMAGE_FILETYPE_AVIF:
|
||||||
|
return "image/avif";
|
||||||
default:
|
default:
|
||||||
case IMAGE_FILETYPE_UNKNOWN:
|
case IMAGE_FILETYPE_UNKNOWN:
|
||||||
return "application/octet-stream"; /* suppose binary format */
|
return "application/octet-stream"; /* suppose binary format */
|
||||||
|
@ -1265,6 +1361,9 @@ PHP_FUNCTION(image_type_to_extension)
|
||||||
case IMAGE_FILETYPE_WEBP:
|
case IMAGE_FILETYPE_WEBP:
|
||||||
imgext = ".webp";
|
imgext = ".webp";
|
||||||
break;
|
break;
|
||||||
|
case IMAGE_FILETYPE_AVIF:
|
||||||
|
imgext = ".avif";
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (imgext) {
|
if (imgext) {
|
||||||
|
@ -1277,7 +1376,7 @@ PHP_FUNCTION(image_type_to_extension)
|
||||||
|
|
||||||
/* {{{ php_imagetype
|
/* {{{ php_imagetype
|
||||||
detect filetype from first bytes */
|
detect filetype from first bytes */
|
||||||
PHPAPI int php_getimagetype(php_stream * stream, const char *input, char *filetype)
|
PHPAPI int php_getimagetype(php_stream *stream, const char *input, char *filetype)
|
||||||
{
|
{
|
||||||
char tmp[12];
|
char tmp[12];
|
||||||
int twelve_bytes_read;
|
int twelve_bytes_read;
|
||||||
|
@ -1349,17 +1448,24 @@ PHPAPI int php_getimagetype(php_stream * stream, const char *input, char *filety
|
||||||
return IMAGE_FILETYPE_JP2;
|
return IMAGE_FILETYPE_JP2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!php_stream_rewind(stream) && php_is_image_avif(stream)) {
|
||||||
|
return IMAGE_FILETYPE_AVIF;
|
||||||
|
}
|
||||||
|
|
||||||
/* AFTER ALL ABOVE FAILED */
|
/* AFTER ALL ABOVE FAILED */
|
||||||
if (php_get_wbmp(stream, NULL, 1)) {
|
if (php_get_wbmp(stream, NULL, 1)) {
|
||||||
return IMAGE_FILETYPE_WBMP;
|
return IMAGE_FILETYPE_WBMP;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!twelve_bytes_read) {
|
if (!twelve_bytes_read) {
|
||||||
php_error_docref(NULL, E_NOTICE, "Error reading from %s!", input);
|
php_error_docref(NULL, E_NOTICE, "Error reading from %s!", input);
|
||||||
return IMAGE_FILETYPE_UNKNOWN;
|
return IMAGE_FILETYPE_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (php_get_xbm(stream, NULL)) {
|
if (php_get_xbm(stream, NULL)) {
|
||||||
return IMAGE_FILETYPE_XBM;
|
return IMAGE_FILETYPE_XBM;
|
||||||
}
|
}
|
||||||
|
|
||||||
return IMAGE_FILETYPE_UNKNOWN;
|
return IMAGE_FILETYPE_UNKNOWN;
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
@ -1431,6 +1537,9 @@ static void php_getimagesize_from_stream(php_stream *stream, char *input, zval *
|
||||||
case IMAGE_FILETYPE_WEBP:
|
case IMAGE_FILETYPE_WEBP:
|
||||||
result = php_handle_webp(stream);
|
result = php_handle_webp(stream);
|
||||||
break;
|
break;
|
||||||
|
case IMAGE_FILETYPE_AVIF:
|
||||||
|
result = php_handle_avif(stream);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
case IMAGE_FILETYPE_UNKNOWN:
|
case IMAGE_FILETYPE_UNKNOWN:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -43,6 +43,7 @@ typedef enum
|
||||||
IMAGE_FILETYPE_XBM,
|
IMAGE_FILETYPE_XBM,
|
||||||
IMAGE_FILETYPE_ICO,
|
IMAGE_FILETYPE_ICO,
|
||||||
IMAGE_FILETYPE_WEBP,
|
IMAGE_FILETYPE_WEBP,
|
||||||
|
IMAGE_FILETYPE_AVIF,
|
||||||
/* WHEN EXTENDING: PLEASE ALSO REGISTER IN image.c:PHP_MINIT_FUNCTION(imagetypes) */
|
/* WHEN EXTENDING: PLEASE ALSO REGISTER IN image.c:PHP_MINIT_FUNCTION(imagetypes) */
|
||||||
IMAGE_FILETYPE_COUNT
|
IMAGE_FILETYPE_COUNT
|
||||||
} image_filetype;
|
} image_filetype;
|
||||||
|
@ -54,4 +55,6 @@ PHPAPI int php_getimagetype(php_stream *stream, const char *input, char *filetyp
|
||||||
|
|
||||||
PHPAPI char * php_image_type_to_mime_type(int image_type);
|
PHPAPI char * php_image_type_to_mime_type(int image_type);
|
||||||
|
|
||||||
|
PHPAPI bool php_is_image_avif(php_stream *stream);
|
||||||
|
|
||||||
#endif /* PHP_IMAGE_H */
|
#endif /* PHP_IMAGE_H */
|
||||||
|
|
|
@ -23,7 +23,7 @@ GetImageSize()
|
||||||
var_dump($result);
|
var_dump($result);
|
||||||
?>
|
?>
|
||||||
--EXPECT--
|
--EXPECT--
|
||||||
array(16) {
|
array(17) {
|
||||||
["test-1pix.bmp"]=>
|
["test-1pix.bmp"]=>
|
||||||
array(6) {
|
array(6) {
|
||||||
[0]=>
|
[0]=>
|
||||||
|
@ -69,6 +69,19 @@ array(16) {
|
||||||
["mime"]=>
|
["mime"]=>
|
||||||
string(9) "image/bmp"
|
string(9) "image/bmp"
|
||||||
}
|
}
|
||||||
|
["test1pix.avif"]=>
|
||||||
|
array(5) {
|
||||||
|
[0]=>
|
||||||
|
int(0)
|
||||||
|
[1]=>
|
||||||
|
int(0)
|
||||||
|
[2]=>
|
||||||
|
int(19)
|
||||||
|
[3]=>
|
||||||
|
string(20) "width="0" height="0""
|
||||||
|
["mime"]=>
|
||||||
|
string(10) "image/avif"
|
||||||
|
}
|
||||||
["test1pix.bmp"]=>
|
["test1pix.bmp"]=>
|
||||||
array(6) {
|
array(6) {
|
||||||
[0]=>
|
[0]=>
|
||||||
|
|
|
@ -23,7 +23,8 @@ image_type_to_extension()
|
||||||
"IMAGETYPE_WBMP" => IMAGETYPE_WBMP,
|
"IMAGETYPE_WBMP" => IMAGETYPE_WBMP,
|
||||||
"IMAGETYPE_JPEG2000" => IMAGETYPE_JPEG2000,
|
"IMAGETYPE_JPEG2000" => IMAGETYPE_JPEG2000,
|
||||||
"IMAGETYPE_XBM" => IMAGETYPE_XBM,
|
"IMAGETYPE_XBM" => IMAGETYPE_XBM,
|
||||||
"IMAGETYPE_WEBP" => IMAGETYPE_WEBP
|
"IMAGETYPE_WEBP" => IMAGETYPE_WEBP,
|
||||||
|
"IMAGETYPE_AVIF" => IMAGETYPE_AVIF,
|
||||||
);
|
);
|
||||||
foreach($constants as $name => $constant) {
|
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));
|
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
|
Constant: IMAGETYPE_WEBP
|
||||||
With dot: .webp
|
With dot: .webp
|
||||||
Without dot: webp
|
Without dot: webp
|
||||||
|
Constant: IMAGETYPE_AVIF
|
||||||
|
With dot: .avif
|
||||||
|
Without dot: avif
|
||||||
bool(false)
|
bool(false)
|
||||||
bool(false)
|
bool(false)
|
||||||
Done
|
Done
|
||||||
|
|
|
@ -24,13 +24,15 @@ image_type_to_mime_type()
|
||||||
var_dump($result);
|
var_dump($result);
|
||||||
?>
|
?>
|
||||||
--EXPECT--
|
--EXPECT--
|
||||||
array(16) {
|
array(17) {
|
||||||
["test-1pix.bmp"]=>
|
["test-1pix.bmp"]=>
|
||||||
string(9) "image/bmp"
|
string(9) "image/bmp"
|
||||||
["test12pix.webp"]=>
|
["test12pix.webp"]=>
|
||||||
string(10) "image/webp"
|
string(10) "image/webp"
|
||||||
["test1bpix.bmp"]=>
|
["test1bpix.bmp"]=>
|
||||||
string(9) "image/bmp"
|
string(9) "image/bmp"
|
||||||
|
["test1pix.avif"]=>
|
||||||
|
string(10) "image/avif"
|
||||||
["test1pix.bmp"]=>
|
["test1pix.bmp"]=>
|
||||||
string(9) "image/bmp"
|
string(9) "image/bmp"
|
||||||
["test1pix.jp2"]=>
|
["test1pix.jp2"]=>
|
||||||
|
|
|
@ -72,4 +72,7 @@ string\(24\) "image\/vnd.microsoft.icon"
|
||||||
string\(10\) "image\/webp"
|
string\(10\) "image\/webp"
|
||||||
|
|
||||||
-- Iteration 19 --
|
-- Iteration 19 --
|
||||||
|
string\(10\) "image\/avif"
|
||||||
|
|
||||||
|
-- Iteration 20 --
|
||||||
string\(24\) "application\/octet-stream"
|
string\(24\) "application\/octet-stream"
|
||||||
|
|
BIN
ext/standard/tests/image/test1pix.avif
Normal file
BIN
ext/standard/tests/image/test1pix.avif
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
Loading…
Add table
Add a link
Reference in a new issue