1use crate::util::*;
2use crate::{ImageResult, ImageSize};
3
4use std::io::{BufRead, Seek, SeekFrom};
5
6pub fn size<R: BufRead + Seek>(reader: &mut R) -> ImageResult<ImageSize> {
7 let mut buffer: [u8; 4] = [0; 4];
8 reader.read_exact(&mut buffer)?;
9
10 if buffer[3] == b' ' {
11 webp_vp8_size(reader)
12 } else if buffer[3] == b'L' {
13 webp_vp8l_size(reader)
14 } else if buffer[3] == b'X' {
15 webp_vp8x_size(reader)
16 } else {
17 Err(std::io::Error::new(kind:std::io::ErrorKind::InvalidData, error:"Invalid VP8 Tag").into())
18 }
19}
20
21pub fn matches(header: &[u8]) -> bool {
22 header.len() >= 12 && &header[0..4] == b"RIFF" && &header[8..12] == b"WEBP"
23}
24
25fn webp_vp8x_size<R: BufRead + Seek>(reader: &mut R) -> ImageResult<ImageSize> {
26 reader.seek(pos:SeekFrom::Start(0x18))?;
27
28 Ok(ImageSize {
29 width: read_u24(reader, &Endian::Little)? as usize + 1,
30 height: read_u24(reader, &Endian::Little)? as usize + 1,
31 })
32}
33
34fn webp_vp8l_size<R: BufRead + Seek>(reader: &mut R) -> ImageResult<ImageSize> {
35 reader.seek(pos:SeekFrom::Start(0x15))?;
36
37 let dims: u32 = read_u32(reader, &Endian::Little)?;
38
39 Ok(ImageSize {
40 width: (dims & 0x3FFF) as usize + 1,
41 height: ((dims >> 14) & 0x3FFF) as usize + 1,
42 })
43}
44
45fn webp_vp8_size<R: BufRead + Seek>(reader: &mut R) -> ImageResult<ImageSize> {
46 reader.seek(pos:SeekFrom::Start(0x1A))?;
47
48 Ok(ImageSize {
49 width: read_u16(reader, &Endian::Little)? as usize,
50 height: read_u16(reader, &Endian::Little)? as usize,
51 })
52}
53