1use core::slice::Chunks;
2use tile::Tile;
3
4#[derive(Debug)]
13pub struct Bitplanes<'a> {
14 chunks: Chunks<'a, u8>,
15}
16
17impl<'a> Iterator for Bitplanes<'a> {
18 type Item = Tile;
19
20 fn next(&mut self) -> Option<Self::Item> {
21 self.chunks.next()
22 .map(|chunk| {
23 let (planes01, planes23) = chunk.split_at(16);
24 let mut result = [0; 64];
25 let mut cursor = 0;
26 for (bytes01, bytes23) in planes01.chunks(2).zip(planes23.chunks(2)) {
27 for n in (0..8).rev() {
28 let mask = 1 << n;
29 let mut px = 0;
30
31 if bytes23[1] & mask > 0 {
32 px += 1;
33 }
34 px <<= 1;
35 if bytes23[0] & mask > 0 {
36 px += 1;
37 }
38 px <<= 1;
39 if bytes01[1] & mask > 0 {
40 px += 1;
41 }
42 px <<= 1;
43 if bytes01[0] & mask > 0 {
44 px += 1;
45 }
46 result[cursor] = px;
47 cursor += 1;
48 }
49 }
50 Tile(result)
51 })
52 }
53
54 fn size_hint(&self) -> (usize, Option<usize>) {
55 self.chunks.size_hint()
56 }
57}
58
59impl<'a> Bitplanes<'a> {
60 pub fn new(bytes: &'a [u8]) -> Bitplanes<'a> {
78 assert!(bytes.len() % 32 == 0, "Byte slice doesn't fit into 32-byte tiles");
79 Bitplanes {
80 chunks: bytes.chunks(32),
81 }
82 }
83}
84
85#[cfg(test)]
86mod tests {
87 use super::{Bitplanes, Tile};
88
89 #[test]
90 fn snes_mode_4_4bpp() {
91 let encoded: &[u8] = &[
92 0b00101110, 0b00100000, 0b11101001, 0b10010101, 0b11111101, 0b10101011,
98 0b01000111,
99 0b00010101,
100 0b00110000,
101 0b01011100,
102 0b10011111,
103 0b00011101,
104 0b10010110,
105 0b01011010,
106 0b00010101,
107 0b00101110,
108
109 0b01000000, 0b00001111, 0b00010001, 0b11111011, 0b01000001, 0b10011100,
115 0b10000100,
116 0b11110110,
117 0b10110000,
118 0b00011000,
119 0b00100111,
120 0b00001001,
121 0b11101000,
122 0b00101010,
123 0b00010001,
124 0b10000011,
125 ];
126
127 let expected = Tile([
128 0b0000, 0b0100, 0b0011, 0b0000, 0b1001, 0b1001, 0b1001, 0b1000,
129 0b1011, 0b1001, 0b1001, 0b1110, 0b1001, 0b0010, 0b1000, 0b1111,
130 0b1011, 0b0101, 0b0011, 0b1001, 0b1011, 0b1001, 0b0010, 0b0111,
131 0b1100, 0b1001, 0b1000, 0b1010, 0b0000, 0b1111, 0b1001, 0b0011,
132 0b0100, 0b0010, 0b0101, 0b1111, 0b1010, 0b0010, 0b0000, 0b0000,
133 0b0001, 0b0000, 0b0100, 0b0011, 0b1011, 0b0111, 0b0101, 0b1111,
134 0b0101, 0b0110, 0b1100, 0b0011, 0b1110, 0b0001, 0b1011, 0b0000,
135 0b1000, 0b0000, 0b0010, 0b0101, 0b0010, 0b0011, 0b1010, 0b1101,
136 ]);
137
138 let mut decoded = Bitplanes::new(encoded);
139
140 assert_eq!(decoded.next(), Some(expected));
141 assert!(decoded.next().is_none());
142 }
143}