1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
use crate::{
chunk::{
Background, Chunk, CompressedText, ImageData, ImageEnd, ImageHeader,
InternationalText, Palette, Physical, Text, Time, Transparency,
},
consts,
decode::{Error, Result},
decoder::Parser,
};
use std::io::Read;
#[derive(Debug)]
pub struct Chunks<R: Read> {
dec: Parser<R>,
}
impl<R: Read> Chunks<R> {
pub(crate) fn new(dec: Parser<R>) -> Self {
Chunks { dec }
}
fn get_next(&mut self) -> Result<Option<Chunk>> {
let name = if let Some(name) = self.dec.prepare()? {
name
} else {
return Ok(None);
};
use consts::*;
let chunk = match name {
IMAGE_HEADER => ImageHeader::parse(&mut self.dec),
IMAGE_DATA => ImageData::parse(&mut self.dec),
IMAGE_END => ImageEnd::parse(),
PALETTE => Palette::parse(&mut self.dec),
BACKGROUND => Background::parse(&mut self.dec),
ITEXT => InternationalText::parse(&mut self.dec),
PHYSICAL => Physical::parse(&mut self.dec),
TEXT => Text::parse(&mut self.dec),
TIME => Time::parse(&mut self.dec),
TRANSPARENCY => Transparency::parse(&mut self.dec),
ZTEXT => CompressedText::parse(&mut self.dec),
id => {
self.dec.unknown_chunk()?;
self.dec.check_crc(&name)?;
return Err(Error::UnknownChunkType(id));
}
}?;
self.dec.check_crc(&name)?;
Ok(Some(chunk))
}
}
impl<R: Read> Iterator for Chunks<R> {
type Item = Result<Chunk>;
fn next(&mut self) -> Option<Self::Item> {
match self.get_next() {
Ok(Some(c)) => Some(Ok(c)),
Ok(None) => None,
Err(e) => Some(Err(e)),
}
}
}