planetarium/export/
raw.rs1use crate::{Canvas, EncoderError, Window};
11
12#[allow(clippy::unnecessary_wraps)]
13impl Canvas {
14 pub(super) fn export_raw8bpp(&self, window: Window) -> Result<Vec<u8>, EncoderError> {
16 let mut rawbuf: Vec<u8> = Vec::with_capacity(window.len());
18
19 for span in self.window_spans(window).unwrap() {
21 rawbuf.extend(span.iter().map(|p| self.gamma_curve.transform(*p)));
22 }
23
24 Ok(rawbuf)
25 }
26
27 pub(super) fn export_raw1xbpp<const X: u16>(
32 &self,
33 window: Window,
34 ) -> Result<Vec<u8>, EncoderError> {
35 let mut rawbuf: Vec<u8> = Vec::with_capacity(2 * window.len());
37
38 for span in self.window_spans(window).unwrap() {
40 for p in span {
41 let bytes = (p >> (16 - X)).to_le_bytes();
42 rawbuf.extend_from_slice(&bytes);
43 }
44 }
45
46 Ok(rawbuf)
47 }
48
49 pub(super) fn export_sub_raw8bpp(&self, factors: (u32, u32)) -> Result<Vec<u8>, EncoderError> {
52 let pixlen = self.pixbuf.len() / (factors.0 * factors.1) as usize;
54
55 let mut rawbuf: Vec<u8> = Vec::with_capacity(pixlen);
57
58 for i in 0..(self.height / factors.1) {
59 let loffset = (i * factors.1 * self.width) as usize;
60
61 for j in 0..(self.width / factors.0) {
62 let offset = loffset + (j * factors.0) as usize;
63 let xval = self.gamma_curve.transform(self.pixbuf[offset]);
64 rawbuf.push(xval);
65 }
66 }
67
68 Ok(rawbuf)
69 }
70
71 pub(super) fn export_sub_raw1xbpp<const X: u16>(
76 &self,
77 factors: (u32, u32),
78 ) -> Result<Vec<u8>, EncoderError> {
79 let pixlen = self.pixbuf.len() / (factors.0 * factors.1) as usize;
81
82 let mut rawbuf: Vec<u8> = Vec::with_capacity(2 * pixlen);
84
85 for i in 0..(self.height / factors.1) {
86 let loffset = (i * factors.1 * self.width) as usize;
87
88 for j in 0..(self.width / factors.0) {
89 let offset = loffset + (j * factors.0) as usize;
90 let bytes = (self.pixbuf[offset] >> (16 - X)).to_le_bytes();
91 rawbuf.extend_from_slice(&bytes);
92 }
93 }
94
95 Ok(rawbuf)
96 }
97}
98
99#[cfg(test)]
100mod tests {
101 use crate::{ImageFormat, SpotShape};
102
103 use super::*;
104
105 fn mkimage() -> Canvas {
107 let mut c = Canvas::new(256, 256);
108 c.set_background(1000);
109
110 let shape = SpotShape::default().scale(4.5);
111 let shape2 = shape.stretch(1.7, 0.7).rotate(45.0);
112
113 c.add_spot((100.6, 150.2), shape, 0.9);
114 c.add_spot((103.8, 146.5), shape2, 0.5);
115
116 c.draw();
117 c
118 }
119
120 #[test]
121 fn export_raw8bpp() {
122 let img = mkimage().export_image(ImageFormat::RawGamma8Bpp).unwrap();
123 assert_eq!(img.len(), 256 * 256);
124 assert_eq!(img[0], 33);
125 assert_eq!(img[150 * 256 + 100], 238);
126 }
127
128 #[test]
129 fn export_sub_raw8bpp() {
130 let img = mkimage()
131 .export_subsampled_image((2, 2), ImageFormat::RawGamma8Bpp)
132 .unwrap();
133 assert_eq!(img.len(), 256 * 256 / 2 / 2);
134 assert_eq!(img[0], 33);
135 assert_eq!(img[(150 * 128 + 100) / 2], 238);
136 }
137
138 #[test]
139 fn export_window_raw8bpp() {
140 let wnd = Window::new(32, 16).at(90, 140);
141
142 let img = mkimage()
143 .export_window_image(wnd, ImageFormat::RawGamma8Bpp)
144 .unwrap();
145 assert_eq!(img.len(), wnd.len());
146 assert_eq!(img[300], 185);
147 }
148
149 #[test]
150 fn export_raw10bpp() {
151 let img = mkimage()
152 .export_image(ImageFormat::RawLinear10BppLE)
153 .unwrap();
154 assert_eq!(img.len(), 256 * 256 * 2);
155 assert_eq!(img[0], 0x0F);
156 assert_eq!(img[1], 0x00);
157 assert_eq!(img[2 * (150 * 256 + 100)], 106);
158 assert_eq!(img[2 * (150 * 256 + 100) + 1], 3);
159 }
160
161 #[test]
162 fn export_sub_raw10bpp() {
163 let img = mkimage()
164 .export_subsampled_image((2, 2), ImageFormat::RawLinear10BppLE)
165 .unwrap();
166 assert_eq!(img.len(), 256 * 256 * 2 / 2 / 2);
167 assert_eq!(img[0], 0x0F);
168 assert_eq!(img[1], 0x00);
169 assert_eq!(img[2 * (150 * 128 + 100) / 2], 106);
170 assert_eq!(img[2 * (150 * 128 + 100) / 2 + 1], 3);
171 }
172
173 #[test]
174 fn export_window_raw10bpp() {
175 let wnd = Window::new(32, 16).at(90, 140);
176
177 let img = mkimage()
178 .export_window_image(wnd, ImageFormat::RawLinear10BppLE)
179 .unwrap();
180 assert_eq!(img.len(), 2 * wnd.len());
181 assert_eq!(img[300 * 2], 240);
182 assert_eq!(img[300 * 2 + 1], 1);
183 }
184
185 #[test]
186 fn export_raw12bpp() {
187 let img = mkimage()
188 .export_image(ImageFormat::RawLinear12BppLE)
189 .unwrap();
190 assert_eq!(img.len(), 256 * 256 * 2);
191 assert_eq!(img[0], 0x3E);
192 assert_eq!(img[1], 0x00);
193 assert_eq!(img[2 * (150 * 256 + 100)], 168);
194 assert_eq!(img[2 * (150 * 256 + 100) + 1], 13);
195 }
196
197 #[test]
198 fn export_sub_raw12bpp() {
199 let img = mkimage()
200 .export_subsampled_image((4, 2), ImageFormat::RawLinear12BppLE)
201 .unwrap();
202 assert_eq!(img.len(), 256 * 256 * 2 / 4 / 2);
203 assert_eq!(img[0], 0x3E);
204 assert_eq!(img[1], 0x00);
205 assert_eq!(img[2 * (150 / 2 * 64 + 100 / 4)], 168);
206 assert_eq!(img[2 * (150 / 2 * 64 + 100 / 4) + 1], 13);
207 }
208}