png/decoder/
interlace_info.rs
1use std::ops::Range;
2
3use crate::adam7::{Adam7Info, Adam7Iterator};
4
5#[derive(Clone, Copy, Debug)]
11pub enum InterlaceInfo {
12 Null(NullInfo),
14 Adam7(Adam7Info),
30}
31
32#[derive(Clone, Copy, Debug)]
33pub struct NullInfo {
34 line: u32,
35}
36
37impl InterlaceInfo {
38 pub(crate) fn line_number(&self) -> u32 {
39 match self {
40 InterlaceInfo::Null(NullInfo { line }) => *line,
41 InterlaceInfo::Adam7(Adam7Info { line, .. }) => *line,
42 }
43 }
44
45 pub(crate) fn get_adam7_info(&self) -> Option<&Adam7Info> {
46 match self {
47 InterlaceInfo::Null(_) => None,
48 InterlaceInfo::Adam7(adam7info) => Some(adam7info),
49 }
50 }
51}
52
53pub(crate) struct InterlaceInfoIter(IterImpl);
54
55impl InterlaceInfoIter {
56 pub fn empty() -> Self {
57 Self(IterImpl::None(0..0))
58 }
59
60 pub fn new(width: u32, height: u32, interlaced: bool) -> Self {
61 if interlaced {
62 Self(IterImpl::Adam7(Adam7Iterator::new(width, height)))
63 } else {
64 Self(IterImpl::None(0..height))
65 }
66 }
67}
68
69impl Iterator for InterlaceInfoIter {
70 type Item = InterlaceInfo;
71
72 fn next(&mut self) -> Option<InterlaceInfo> {
73 match self.0 {
74 IterImpl::Adam7(ref mut adam7) => Some(InterlaceInfo::Adam7(adam7.next()?)),
75 IterImpl::None(ref mut height) => Some(InterlaceInfo::Null(NullInfo {
76 line: height.next()?,
77 })),
78 }
79 }
80}
81
82enum IterImpl {
83 None(Range<u32>),
84 Adam7(Adam7Iterator),
85}
86
87#[cfg(test)]
88mod test {
89 use super::*;
90
91 #[test]
92 fn null() {
93 assert_eq!(
94 InterlaceInfoIter::new(8, 8, false)
95 .map(|info| info.line_number())
96 .collect::<Vec<_>>(),
97 vec![0, 1, 2, 3, 4, 5, 6, 7],
98 );
99 }
100
101 #[test]
102 fn adam7() {
103 assert_eq!(
104 InterlaceInfoIter::new(8, 8, true)
105 .map(|info| info.line_number())
106 .collect::<Vec<_>>(),
107 vec![
108 0, 0, 0, 0, 1, 0, 1, 0, 1, 2, 3, 0, 1, 2, 3, ],
116 );
117 }
118
119 #[test]
120 fn empty() {
121 assert_eq!(
122 InterlaceInfoIter::empty()
123 .map(|info| info.line_number())
124 .collect::<Vec<_>>(),
125 vec![],
126 );
127 }
128}