imagesize/formats/
jpeg.rs
1use crate::util::*;
2use crate::{ImageError, ImageResult, ImageSize};
3
4use std::io::{BufRead, Seek, SeekFrom};
5
6pub fn size<R: BufRead + Seek>(reader: &mut R) -> ImageResult<ImageSize> {
7 let mut marker = [0; 2];
8 let mut depth = 0i32;
9
10 reader.seek(SeekFrom::Start(2))?;
12
13 loop {
14 reader.read_exact(&mut marker)?;
16
17 if marker[0] != 0xFF {
18 return Err(ImageError::CorruptedImage);
20 }
21
22 let page = marker[1];
23
24 if (0xC0..=0xC3).contains(&page)
26 || (0xC5..=0xC7).contains(&page)
27 || (0xC9..=0xCB).contains(&page)
28 || (0xCD..=0xCF).contains(&page)
29 {
30 if depth == 0 {
32 reader.seek(SeekFrom::Current(3))?;
34 break;
35 }
36 } else if page == 0xD8 {
37 depth += 1;
38 } else if page == 0xD9 {
39 depth -= 1;
40 if depth < 0 {
41 return Err(ImageError::CorruptedImage);
42 }
43 }
44
45 let page_size = read_u16(reader, &Endian::Big)? as i64;
47 reader.seek(SeekFrom::Current(page_size - 2))?;
48 }
49
50 Ok(ImageSize {
51 height: read_u16(reader, &Endian::Big)? as usize,
52 width: read_u16(reader, &Endian::Big)? as usize,
53 })
54}
55
56pub fn matches(header: &[u8]) -> bool {
57 header.starts_with(b"\xFF\xD8\xFF")
58}