info: decode WebP dimensions
This commit is contained in:
parent
a9b34ca3f2
commit
399c4bdf69
51
tools/info.c
51
tools/info.c
|
@ -109,6 +109,49 @@ detect_webp(const uint8_t *p, size_t len)
|
|||
return len >= 12 && !memcmp(p, "RIFF", 4) && !memcmp(p + 8, "WEBP", 4);
|
||||
}
|
||||
|
||||
static jv
|
||||
parse_webp_vp8(jv o, const uint8_t *p, size_t len)
|
||||
{
|
||||
if (len < 10 || (p[0] & 1) != 0 /* key frame */ ||
|
||||
p[3] != 0x9d || p[4] != 0x01 || p[5] != 0x2a) {
|
||||
return add_warning(o, "invalid VP8 chunk");
|
||||
}
|
||||
|
||||
o = jv_set(o, jv_string("width"), jv_number(u16le(p + 6) & 0x3fff));
|
||||
o = jv_set(o, jv_string("height"), jv_number(u16le(p + 8) & 0x3fff));
|
||||
return o;
|
||||
}
|
||||
|
||||
static jv
|
||||
parse_webp_vp8l(jv o, const uint8_t *p, size_t len)
|
||||
{
|
||||
if (len < 5 || p[0] != 0x2f)
|
||||
return add_warning(o, "invalid VP8L chunk");
|
||||
|
||||
// Reading LSB-first from a little endian value means reading in order.
|
||||
uint32_t header = u32le(p + 1);
|
||||
o = jv_set(o, jv_string("width"), jv_number((header & 0x3fff) + 1));
|
||||
header >>= 14;
|
||||
o = jv_set(o, jv_string("height"), jv_number((header & 0x3fff) + 1));
|
||||
header >>= 14;
|
||||
o = jv_set(o, jv_string("alpha_is_used"), jv_bool(header & 1));
|
||||
return o;
|
||||
}
|
||||
|
||||
static jv
|
||||
parse_webp_vp8x(jv o, const uint8_t *p, size_t len)
|
||||
{
|
||||
if (len < 10)
|
||||
return add_warning(o, "invalid VP8X chunk");
|
||||
|
||||
// Most of the fields in this chunk are duplicate or inferrable.
|
||||
// Probably not worth decoding or verifying.
|
||||
// TODO(p): For animations, we need to use the width and height from here.
|
||||
uint8_t flags = p[0];
|
||||
o = jv_set(o, jv_string("animation"), jv_bool((flags >> 1) & 1));
|
||||
return o;
|
||||
}
|
||||
|
||||
static jv
|
||||
parse_webp(jv o, const uint8_t *p, size_t len)
|
||||
{
|
||||
|
@ -144,7 +187,13 @@ parse_webp(jv o, const uint8_t *p, size_t len)
|
|||
chunks = jv_array_append(chunks, jv_string(fourcc));
|
||||
p += 8;
|
||||
|
||||
// TODO(p): Decode VP8 and VP8L chunk metadata.
|
||||
// TODO(p): Decode more chunks.
|
||||
if (!strcmp(fourcc, "VP8 "))
|
||||
o = parse_webp_vp8(o, p, chunk_size);
|
||||
if (!strcmp(fourcc, "VP8L"))
|
||||
o = parse_webp_vp8l(o, p, chunk_size);
|
||||
if (!strcmp(fourcc, "VP8X"))
|
||||
o = parse_webp_vp8x(o, p, chunk_size);
|
||||
if (!strcmp(fourcc, "EXIF"))
|
||||
o = parse_exif(o, p, chunk_size);
|
||||
if (!strcmp(fourcc, "ICCP"))
|
||||
|
|
Loading…
Reference in New Issue