Skip to content

Commit b968d5b

Browse files
committed
Added suport for AVIF to getimagesize().
1 parent 87b263d commit b968d5b

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
@@ -50,6 +50,7 @@ PHPAPI const char php_sig_iff[4] = {'F','O','R','M'};
5050
PHPAPI const char php_sig_ico[4] = {(char)0x00, (char)0x00, (char)0x01, (char)0x00};
5151
PHPAPI const char php_sig_riff[4] = {'R', 'I', 'F', 'F'};
5252
PHPAPI const char php_sig_webp[4] = {'W', 'E', 'B', 'P'};
53+
PHPAPI const char php_sig_avif[4] = {'a', 'v', 'i', 'f'};
5354

5455
/* REMEMBER TO ADD MIME-TYPE TO FUNCTION php_image_type_to_mime_type */
5556
/* PCX must check first 64bytes and byte 0=0x0a and byte2 < 0x06 */
@@ -88,6 +89,7 @@ PHP_MINIT_FUNCTION(imagetypes)
8889
REGISTER_LONG_CONSTANT("IMAGETYPE_XBM", IMAGE_FILETYPE_XBM, CONST_CS | CONST_PERSISTENT);
8990
REGISTER_LONG_CONSTANT("IMAGETYPE_ICO", IMAGE_FILETYPE_ICO, CONST_CS | CONST_PERSISTENT);
9091
REGISTER_LONG_CONSTANT("IMAGETYPE_WEBP", IMAGE_FILETYPE_WEBP, CONST_CS | CONST_PERSISTENT);
92+
REGISTER_LONG_CONSTANT("IMAGETYPE_AVIF", IMAGE_FILETYPE_AVIF, CONST_CS | CONST_PERSISTENT);
9193
REGISTER_LONG_CONSTANT("IMAGETYPE_UNKNOWN", IMAGE_FILETYPE_UNKNOWN, CONST_CS | CONST_PERSISTENT);
9294
REGISTER_LONG_CONSTANT("IMAGETYPE_COUNT", IMAGE_FILETYPE_COUNT, CONST_CS | CONST_PERSISTENT);
9395
return SUCCESS;
@@ -1148,6 +1150,103 @@ static struct gfxinfo *php_handle_webp(php_stream * stream)
11481150
}
11491151
/* }}} */
11501152

1153+
/* {{{ php_handle_avif
1154+
*/
1155+
static struct gfxinfo *php_handle_avif(php_stream * stream) {
1156+
struct gfxinfo *result = NULL;
1157+
unsigned int width = 0, height = 0;
1158+
unsigned char channels = 0, bits = 0, i, bits_tmp;
1159+
unsigned int size, type;
1160+
size_t begin, end, pos = 0;
1161+
int check_ispe = 0, check_pixi = 0, eof;
1162+
1163+
if (php_stream_seek(stream, 0, SEEK_SET)) {
1164+
return NULL;
1165+
}
1166+
for(;;) {
1167+
eof = php_stream_eof(stream);
1168+
if (eof == -1) {
1169+
return NULL;
1170+
} else if ((check_ispe == 1 && check_pixi == 1) || eof == 1) {
1171+
break;
1172+
}
1173+
1174+
begin = pos;
1175+
size = php_read4(stream); pos += 4;
1176+
type = php_read4(stream); pos += 4;
1177+
end = begin + size;
1178+
1179+
switch (type) {
1180+
case 1835365473u: /* meta */
1181+
if (php_stream_seek(stream, 4, SEEK_CUR)) {
1182+
return NULL;
1183+
}
1184+
pos += 4;
1185+
continue;
1186+
1187+
case 1768977008u: /* iprp */
1188+
case 1768973167u: /* ipco */
1189+
continue;
1190+
1191+
case 1769173093u: /* ispe */
1192+
if (php_stream_seek(stream, 4, SEEK_CUR)) {
1193+
return NULL;
1194+
}
1195+
pos += 4;
1196+
width = php_read4(stream); pos += 4;
1197+
height = php_read4(stream); pos += 4;
1198+
check_ispe = 1;
1199+
break;
1200+
1201+
case 1885960297u: /* pixi */
1202+
if (php_stream_seek(stream, 4, SEEK_CUR)) {
1203+
return NULL;
1204+
}
1205+
pos += 4;
1206+
1207+
/* channels */
1208+
if (php_stream_read(stream, (char *)&channels, 1) != 1) {
1209+
return NULL;
1210+
}
1211+
pos++;
1212+
1213+
/* bits */
1214+
for (i = 0; i < channels; i++) {
1215+
if (php_stream_read(stream, (char *)&bits_tmp, 1) != 1) {
1216+
return NULL;
1217+
}
1218+
pos++;
1219+
1220+
if (bits_tmp > bits) {
1221+
bits = bits_tmp;
1222+
}
1223+
}
1224+
check_pixi = 1;
1225+
break;
1226+
1227+
default:
1228+
break;
1229+
}
1230+
1231+
pos = end;
1232+
if (php_stream_seek(stream, end, SEEK_SET)) {
1233+
return NULL;
1234+
}
1235+
}
1236+
1237+
result = (struct gfxinfo *) ecalloc(1, sizeof(struct gfxinfo));
1238+
if (result == NULL) {
1239+
return NULL;
1240+
}
1241+
1242+
result->width = width;
1243+
result->height = height;
1244+
result->bits = bits;
1245+
result->channels = channels;
1246+
return result;
1247+
}
1248+
/* }}} */
1249+
11511250
/* {{{ php_image_type_to_mime_type
11521251
* Convert internal image_type to mime type */
11531252
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)
11831282
return "image/vnd.microsoft.icon";
11841283
case IMAGE_FILETYPE_WEBP:
11851284
return "image/webp";
1285+
case IMAGE_FILETYPE_AVIF:
1286+
return "image/avif";
11861287
default:
11871288
case IMAGE_FILETYPE_UNKNOWN:
11881289
return "application/octet-stream"; /* suppose binary format */
@@ -1265,6 +1366,9 @@ PHP_FUNCTION(image_type_to_extension)
12651366
case IMAGE_FILETYPE_WEBP:
12661367
imgext = ".webp";
12671368
break;
1369+
case IMAGE_FILETYPE_AVIF:
1370+
imgext = ".avif";
1371+
break;
12681372
}
12691373

12701374
if (imgext) {
@@ -1347,6 +1451,8 @@ PHPAPI int php_getimagetype(php_stream * stream, const char *input, char *filety
13471451
/* BYTES READ: 12 */
13481452
if (twelve_bytes_read && !memcmp(filetype, php_sig_jp2, 12)) {
13491453
return IMAGE_FILETYPE_JP2;
1454+
} else if (twelve_bytes_read && !memcmp(filetype+8, php_sig_avif, 4)) {
1455+
return IMAGE_FILETYPE_AVIF;
13501456
}
13511457

13521458
/* AFTER ALL ABOVE FAILED */
@@ -1431,6 +1537,9 @@ static void php_getimagesize_from_stream(php_stream *stream, char *input, zval *
14311537
case IMAGE_FILETYPE_WEBP:
14321538
result = php_handle_webp(stream);
14331539
break;
1540+
case IMAGE_FILETYPE_AVIF:
1541+
result = php_handle_avif(stream);
1542+
break;
14341543
default:
14351544
case IMAGE_FILETYPE_UNKNOWN:
14361545
break;

ext/standard/php_image.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ typedef enum
4343
IMAGE_FILETYPE_XBM,
4444
IMAGE_FILETYPE_ICO,
4545
IMAGE_FILETYPE_WEBP,
46+
IMAGE_FILETYPE_AVIF,
4647
/* WHEN EXTENDING: PLEASE ALSO REGISTER IN image.c:PHP_MINIT_FUNCTION(imagetypes) */
4748
IMAGE_FILETYPE_COUNT
4849
} 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
@@ -22,7 +22,8 @@ $image_types = array (
2222
IMAGETYPE_WBMP,
2323
IMAGETYPE_JPEG2000,
2424
IMAGETYPE_XBM,
25-
IMAGETYPE_WEBP
25+
IMAGETYPE_WEBP,
26+
IMAGETYPE_AVIF
2627
);
2728

2829
foreach($image_types as $image_type) {
@@ -51,5 +52,6 @@ string(18) "image/vnd.wap.wbmp"
5152
string(24) "application/octet-stream"
5253
string(9) "image/xbm"
5354
string(10) "image/webp"
55+
string(10) "image/avif"
5456

5557
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
@@ -72,4 +72,7 @@ string\(24\) "image\/vnd.microsoft.icon"
7272
string\(10\) "image\/webp"
7373

7474
-- Iteration 19 --
75+
string\(10\) "image\/avif"
76+
77+
-- Iteration 20 --
7578
string\(24\) "application\/octet-stream"
333 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)