Skip to content

Commit a72d0b1

Browse files
committed
Added suport for AVIF to getimagesize().
1 parent c3cf01b commit a72d0b1

8 files changed

+142
-4
lines changed

ext/standard/image.c

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ PHPAPI const char php_sig_iff[4] = {'F','O','R','M'};
5353
PHPAPI const char php_sig_ico[4] = {(char)0x00, (char)0x00, (char)0x01, (char)0x00};
5454
PHPAPI const char php_sig_riff[4] = {'R', 'I', 'F', 'F'};
5555
PHPAPI const char php_sig_webp[4] = {'W', 'E', 'B', 'P'};
56+
PHPAPI const char php_sig_avif[4] = {'a', 'v', 'i', 'f'};
5657

5758
/* REMEMBER TO ADD MIME-TYPE TO FUNCTION php_image_type_to_mime_type */
5859
/* PCX must check first 64bytes and byte 0=0x0a and byte2 < 0x06 */
@@ -91,6 +92,7 @@ PHP_MINIT_FUNCTION(imagetypes)
9192
REGISTER_LONG_CONSTANT("IMAGETYPE_XBM", IMAGE_FILETYPE_XBM, CONST_CS | CONST_PERSISTENT);
9293
REGISTER_LONG_CONSTANT("IMAGETYPE_ICO", IMAGE_FILETYPE_ICO, CONST_CS | CONST_PERSISTENT);
9394
REGISTER_LONG_CONSTANT("IMAGETYPE_WEBP", IMAGE_FILETYPE_WEBP, CONST_CS | CONST_PERSISTENT);
95+
REGISTER_LONG_CONSTANT("IMAGETYPE_AVIF", IMAGE_FILETYPE_AVIF, CONST_CS | CONST_PERSISTENT);
9496
REGISTER_LONG_CONSTANT("IMAGETYPE_UNKNOWN", IMAGE_FILETYPE_UNKNOWN, CONST_CS | CONST_PERSISTENT);
9597
REGISTER_LONG_CONSTANT("IMAGETYPE_COUNT", IMAGE_FILETYPE_COUNT, CONST_CS | CONST_PERSISTENT);
9698
return SUCCESS;
@@ -1165,6 +1167,103 @@ static struct gfxinfo *php_handle_webp(php_stream * stream)
11651167
}
11661168
/* }}} */
11671169

1170+
/* {{{ php_handle_avif
1171+
*/
1172+
static struct gfxinfo *php_handle_avif(php_stream * stream) {
1173+
struct gfxinfo *result = NULL;
1174+
unsigned int width = 0, height = 0;
1175+
unsigned char channels = 0, bits = 0, i, bits_tmp;
1176+
unsigned int size, type;
1177+
size_t begin, end, pos = 0;
1178+
int check_ispe = 0, check_pixi = 0, eof;
1179+
1180+
if (php_stream_seek(stream, 0, SEEK_SET)) {
1181+
return NULL;
1182+
}
1183+
for(;;) {
1184+
eof = php_stream_eof(stream);
1185+
if (eof == -1) {
1186+
return NULL;
1187+
} else if ((check_ispe == 1 && check_pixi == 1) || eof == 1) {
1188+
break;
1189+
}
1190+
1191+
begin = pos;
1192+
size = php_read4(stream); pos += 4;
1193+
type = php_read4(stream); pos += 4;
1194+
end = begin + size;
1195+
1196+
switch (type) {
1197+
case 1835365473u: /* meta */
1198+
if (php_stream_seek(stream, 4, SEEK_CUR)) {
1199+
return NULL;
1200+
}
1201+
pos += 4;
1202+
continue;
1203+
1204+
case 1768977008u: /* iprp */
1205+
case 1768973167u: /* ipco */
1206+
continue;
1207+
1208+
case 1769173093u: /* ispe */
1209+
if (php_stream_seek(stream, 4, SEEK_CUR)) {
1210+
return NULL;
1211+
}
1212+
pos += 4;
1213+
width = php_read4(stream); pos += 4;
1214+
height = php_read4(stream); pos += 4;
1215+
check_ispe = 1;
1216+
break;
1217+
1218+
case 1885960297u: /* pixi */
1219+
if (php_stream_seek(stream, 4, SEEK_CUR)) {
1220+
return NULL;
1221+
}
1222+
pos += 4;
1223+
1224+
/* channels */
1225+
if (php_stream_read(stream, (char *)&channels, 1) != 1) {
1226+
return NULL;
1227+
}
1228+
pos++;
1229+
1230+
/* bits */
1231+
for (i = 0; i < channels; i++) {
1232+
if (php_stream_read(stream, (char *)&bits_tmp, 1) != 1) {
1233+
return NULL;
1234+
}
1235+
pos++;
1236+
1237+
if (bits_tmp > bits) {
1238+
bits = bits_tmp;
1239+
}
1240+
}
1241+
check_pixi = 1;
1242+
break;
1243+
1244+
default:
1245+
break;
1246+
}
1247+
1248+
pos = end;
1249+
if (php_stream_seek(stream, end, SEEK_SET)) {
1250+
return NULL;
1251+
}
1252+
}
1253+
1254+
result = (struct gfxinfo *) ecalloc(1, sizeof(struct gfxinfo));
1255+
if (result == NULL) {
1256+
return NULL;
1257+
}
1258+
1259+
result->width = width;
1260+
result->height = height;
1261+
result->bits = bits;
1262+
result->channels = channels;
1263+
return result;
1264+
}
1265+
/* }}} */
1266+
11681267
/* {{{ php_image_type_to_mime_type
11691268
* Convert internal image_type to mime type */
11701269
PHPAPI char * php_image_type_to_mime_type(int image_type)
@@ -1200,6 +1299,8 @@ PHPAPI char * php_image_type_to_mime_type(int image_type)
12001299
return "image/vnd.microsoft.icon";
12011300
case IMAGE_FILETYPE_WEBP:
12021301
return "image/webp";
1302+
case IMAGE_FILETYPE_AVIF:
1303+
return "image/avif";
12031304
default:
12041305
case IMAGE_FILETYPE_UNKNOWN:
12051306
return "application/octet-stream"; /* suppose binary format */
@@ -1284,6 +1385,9 @@ PHP_FUNCTION(image_type_to_extension)
12841385
case IMAGE_FILETYPE_WEBP:
12851386
imgext = ".webp";
12861387
break;
1388+
case IMAGE_FILETYPE_AVIF:
1389+
imgext = ".avif";
1390+
break;
12871391
}
12881392

12891393
if (imgext) {
@@ -1366,6 +1470,8 @@ PHPAPI int php_getimagetype(php_stream * stream, char *input, char *filetype)
13661470
/* BYTES READ: 12 */
13671471
if (twelve_bytes_read && !memcmp(filetype, php_sig_jp2, 12)) {
13681472
return IMAGE_FILETYPE_JP2;
1473+
} else if (twelve_bytes_read && !memcmp(filetype+8, php_sig_avif, 4)) {
1474+
return IMAGE_FILETYPE_AVIF;
13691475
}
13701476

13711477
/* AFTER ALL ABOVE FAILED */
@@ -1450,6 +1556,9 @@ static void php_getimagesize_from_stream(php_stream *stream, char *input, zval *
14501556
case IMAGE_FILETYPE_WEBP:
14511557
result = php_handle_webp(stream);
14521558
break;
1559+
case IMAGE_FILETYPE_AVIF:
1560+
result = php_handle_avif(stream);
1561+
break;
14531562
default:
14541563
case IMAGE_FILETYPE_UNKNOWN:
14551564
break;

ext/standard/php_image.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ typedef enum
4949
IMAGE_FILETYPE_XBM,
5050
IMAGE_FILETYPE_ICO,
5151
IMAGE_FILETYPE_WEBP,
52+
IMAGE_FILETYPE_AVIF,
5253
/* WHEN EXTENDING: PLEASE ALSO REGISTER IN image.c:PHP_MINIT_FUNCTION(imagetypes) */
5354
IMAGE_FILETYPE_COUNT
5455
} image_filetype;

ext/standard/tests/image/getimagesize.phpt

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ GetImageSize()
2323
var_dump($result);
2424
?>
2525
--EXPECT--
26-
array(16) {
26+
array(17) {
2727
["test-1pix.bmp"]=>
2828
array(6) {
2929
[0]=>
@@ -268,4 +268,21 @@ array(16) {
268268
["mime"]=>
269269
string(10) "image/tiff"
270270
}
271+
["test8pix.avif"]=>
272+
array(7) {
273+
[0]=>
274+
int(8)
275+
[1]=>
276+
int(1)
277+
[2]=>
278+
int(19)
279+
[3]=>
280+
string(20) "width="8" height="1""
281+
["bits"]=>
282+
int(8)
283+
["channels"]=>
284+
int(3)
285+
["mime"]=>
286+
string(10) "image/avif"
287+
}
271288
}

ext/standard/tests/image/image_type_to_extension.phpt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ image_type_to_extension()
2323
"IMAGETYPE_WBMP" => IMAGETYPE_WBMP,
2424
"IMAGETYPE_JPEG2000" => IMAGETYPE_JPEG2000,
2525
"IMAGETYPE_XBM" => IMAGETYPE_XBM,
26-
"IMAGETYPE_WEBP" => IMAGETYPE_WEBP
26+
"IMAGETYPE_WEBP" => IMAGETYPE_WEBP,
27+
"IMAGETYPE_AVIF" => IMAGETYPE_AVIF
2728
);
2829
foreach($constants as $name => $constant) {
2930
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
8586
Constant: IMAGETYPE_WEBP
8687
With dot: .webp
8788
Without dot: webp
89+
Constant: IMAGETYPE_AVIF
90+
With dot: .avif
91+
Without dot: avif
8892
bool(false)
8993
bool(false)
9094
Done

ext/standard/tests/image/image_type_to_mime_type.phpt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ image_type_to_mime_type()
2424
var_dump($result);
2525
?>
2626
--EXPECT--
27-
array(16) {
27+
array(17) {
2828
["test-1pix.bmp"]=>
2929
string(9) "image/bmp"
3030
["test12pix.webp"]=>
@@ -57,4 +57,6 @@ array(16) {
5757
string(29) "application/x-shockwave-flash"
5858
["test4pix.tiff"]=>
5959
string(10) "image/tiff"
60+
["test8pix.avif"]=>
61+
string(10) "image/avif"
6062
}

ext/standard/tests/image/image_type_to_mime_type_basic.phpt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ $image_types = array (
2828
IMAGETYPE_WBMP,
2929
IMAGETYPE_JPEG2000,
3030
IMAGETYPE_XBM,
31-
IMAGETYPE_WEBP
31+
IMAGETYPE_WEBP,
32+
IMAGETYPE_AVIF
3233
);
3334

3435
foreach($image_types as $image_type) {
@@ -57,5 +58,6 @@ string(18) "image/vnd.wap.wbmp"
5758
string(24) "application/octet-stream"
5859
string(9) "image/xbm"
5960
string(10) "image/webp"
61+
string(10) "image/avif"
6062

6163
Done image_type_to_mime_type() test

ext/standard/tests/image/image_type_to_mime_type_variation3.phpt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,4 +77,7 @@ string\(24\) "image\/vnd.microsoft.icon"
7777
string\(10\) "image\/webp"
7878

7979
-- Iteration 19 --
80+
string\(10\) "image\/avif"
81+
82+
-- Iteration 20 --
8083
string\(24\) "application\/octet-stream"
333 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)