1use crate::error::DecodeError;
18
19fn compute_row_stride(width: u32, comps: u8, bpc: u8) -> usize {
23 (width as usize * comps as usize * bpc as usize).div_ceil(8)
24}
25
26pub trait ScanlineDecoder {
36 fn width(&self) -> u32;
38
39 fn height(&self) -> u32;
41
42 fn count_comps(&self) -> u8;
45
46 fn bpc(&self) -> u8;
48
49 fn row_stride(&self) -> usize;
51
52 fn decode_scanline(&mut self) -> Result<Option<&[u8]>, DecodeError>;
57
58 fn reset(&mut self) -> Result<(), DecodeError>;
60
61 fn current_line(&self) -> Option<usize>;
63}
64
65pub struct RandomAccessDecoder<D: ScanlineDecoder> {
71 inner: D,
72 next_line: i32,
73 last_scanline: Vec<u8>,
74}
75
76impl<D: ScanlineDecoder> RandomAccessDecoder<D> {
77 pub fn new(inner: D) -> Self {
79 Self {
80 inner,
81 next_line: -1,
82 last_scanline: Vec::new(),
83 }
84 }
85
86 pub fn get_scanline(&mut self, line: usize) -> Result<Option<&[u8]>, DecodeError> {
92 let line_i32 = line as i32;
93
94 if self.next_line == line_i32 + 1 && !self.last_scanline.is_empty() {
96 return Ok(Some(&self.last_scanline));
97 }
98
99 if self.next_line < 0 || self.next_line > line_i32 {
101 self.inner.reset()?;
102 self.next_line = 0;
103 }
104
105 while self.next_line < line_i32 {
107 if self.inner.decode_scanline()?.is_none() {
108 return Ok(None);
109 }
110 self.next_line += 1;
111 }
112
113 match self.inner.decode_scanline()? {
115 Some(data) => {
116 self.last_scanline.clear();
117 self.last_scanline.extend_from_slice(data);
118 self.next_line += 1;
119 Ok(Some(&self.last_scanline))
120 }
121 None => Ok(None),
122 }
123 }
124
125 pub fn inner(&self) -> &D {
127 &self.inner
128 }
129
130 pub fn width(&self) -> u32 {
132 self.inner.width()
133 }
134
135 pub fn height(&self) -> u32 {
137 self.inner.height()
138 }
139
140 pub fn count_comps(&self) -> u8 {
142 self.inner.count_comps()
143 }
144
145 pub fn bpc(&self) -> u8 {
147 self.inner.bpc()
148 }
149
150 pub fn row_stride(&self) -> usize {
152 self.inner.row_stride()
153 }
154}
155
156pub struct FlateScanlineDecoder {
161 data: Vec<u8>,
162 width: u32,
163 height: u32,
164 comps: u8,
165 bpc: u8,
166 row_stride: usize,
167 offset: usize,
168}
169
170impl FlateScanlineDecoder {
171 pub fn new(
176 compressed: &[u8],
177 width: u32,
178 height: u32,
179 comps: u8,
180 bpc: u8,
181 ) -> Result<Self, DecodeError> {
182 let data = crate::flate::decode(compressed, None, None, None, None)?;
183 let row_stride = compute_row_stride(width, comps, bpc);
184 Ok(Self {
185 data,
186 width,
187 height,
188 comps,
189 bpc,
190 row_stride,
191 offset: 0,
192 })
193 }
194
195 pub fn from_decoded(data: Vec<u8>, width: u32, height: u32, comps: u8, bpc: u8) -> Self {
197 let row_stride = compute_row_stride(width, comps, bpc);
198 Self {
199 data,
200 width,
201 height,
202 comps,
203 bpc,
204 row_stride,
205 offset: 0,
206 }
207 }
208}
209
210impl ScanlineDecoder for FlateScanlineDecoder {
211 fn width(&self) -> u32 {
212 self.width
213 }
214
215 fn height(&self) -> u32 {
216 self.height
217 }
218
219 fn count_comps(&self) -> u8 {
220 self.comps
221 }
222
223 fn bpc(&self) -> u8 {
224 self.bpc
225 }
226
227 fn row_stride(&self) -> usize {
228 self.row_stride
229 }
230
231 fn decode_scanline(&mut self) -> Result<Option<&[u8]>, DecodeError> {
232 if self.row_stride == 0 || self.offset >= self.data.len() {
233 return Ok(None);
234 }
235 let end = (self.offset + self.row_stride).min(self.data.len());
236 let row = &self.data[self.offset..end];
237 self.offset = end;
238 Ok(Some(row))
239 }
240
241 fn reset(&mut self) -> Result<(), DecodeError> {
242 self.offset = 0;
243 Ok(())
244 }
245
246 fn current_line(&self) -> Option<usize> {
247 if self.row_stride == 0 || self.offset == 0 {
248 None
249 } else {
250 Some(self.offset / self.row_stride - 1)
251 }
252 }
253}
254
255pub struct DctScanlineDecoder {
260 data: Vec<u8>,
261 width: u32,
262 height: u32,
263 comps: u8,
264 bpc: u8,
265 row_stride: usize,
266 offset: usize,
267}
268
269impl DctScanlineDecoder {
270 pub fn new(
275 jpeg_data: &[u8],
276 width: u32,
277 height: u32,
278 comps: u8,
279 bpc: u8,
280 ) -> Result<Self, DecodeError> {
281 let data = crate::jpeg::decode(jpeg_data)?;
282 let row_stride = compute_row_stride(width, comps, bpc);
283 Ok(Self {
284 data,
285 width,
286 height,
287 comps,
288 bpc,
289 row_stride,
290 offset: 0,
291 })
292 }
293
294 pub fn from_decoded(data: Vec<u8>, width: u32, height: u32, comps: u8, bpc: u8) -> Self {
296 let row_stride = compute_row_stride(width, comps, bpc);
297 Self {
298 data,
299 width,
300 height,
301 comps,
302 bpc,
303 row_stride,
304 offset: 0,
305 }
306 }
307}
308
309impl ScanlineDecoder for DctScanlineDecoder {
310 fn width(&self) -> u32 {
311 self.width
312 }
313
314 fn height(&self) -> u32 {
315 self.height
316 }
317
318 fn count_comps(&self) -> u8 {
319 self.comps
320 }
321
322 fn bpc(&self) -> u8 {
323 self.bpc
324 }
325
326 fn row_stride(&self) -> usize {
327 self.row_stride
328 }
329
330 fn decode_scanline(&mut self) -> Result<Option<&[u8]>, DecodeError> {
331 if self.row_stride == 0 || self.offset >= self.data.len() {
332 return Ok(None);
333 }
334 let end = (self.offset + self.row_stride).min(self.data.len());
335 let row = &self.data[self.offset..end];
336 self.offset = end;
337 Ok(Some(row))
338 }
339
340 fn reset(&mut self) -> Result<(), DecodeError> {
341 self.offset = 0;
342 Ok(())
343 }
344
345 fn current_line(&self) -> Option<usize> {
346 if self.row_stride == 0 || self.offset == 0 {
347 None
348 } else {
349 Some(self.offset / self.row_stride - 1)
350 }
351 }
352}
353
354#[cfg(test)]
355mod tests {
356 use super::*;
357 use flate2::Compression;
358 use flate2::write::ZlibEncoder;
359 use std::io::Write;
360
361 fn zlib_compress(data: &[u8]) -> Vec<u8> {
362 let mut encoder = ZlibEncoder::new(Vec::new(), Compression::default());
363 encoder.write_all(data).unwrap();
364 encoder.finish().unwrap()
365 }
366
367 #[test]
368 fn flate_scanline_basic() {
369 let raw = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
371 let compressed = zlib_compress(&raw);
372 let mut decoder = FlateScanlineDecoder::new(&compressed, 4, 3, 1, 8).unwrap();
373
374 assert_eq!(decoder.row_stride(), 4);
375 assert_eq!(decoder.width(), 4);
376 assert_eq!(decoder.height(), 3);
377 assert_eq!(decoder.count_comps(), 1);
378 assert_eq!(decoder.bpc(), 8);
379
380 let row1 = decoder.decode_scanline().unwrap().unwrap();
381 assert_eq!(row1, &[1, 2, 3, 4]);
382
383 let row2 = decoder.decode_scanline().unwrap().unwrap();
384 assert_eq!(row2, &[5, 6, 7, 8]);
385
386 let row3 = decoder.decode_scanline().unwrap().unwrap();
387 assert_eq!(row3, &[9, 10, 11, 12]);
388
389 assert!(decoder.decode_scanline().unwrap().is_none());
391 }
392
393 #[test]
394 fn flate_scanline_count() {
395 let raw = vec![0u8; 100];
397 let compressed = zlib_compress(&raw);
398 let mut decoder = FlateScanlineDecoder::new(&compressed, 10, 10, 1, 8).unwrap();
399
400 let mut count = 0;
401 while decoder.decode_scanline().unwrap().is_some() {
402 count += 1;
403 }
404 assert_eq!(count, 10);
405 }
406
407 #[test]
408 fn flate_scanline_matches_batch() {
409 let raw: Vec<u8> = (0..120).map(|i| (i % 256) as u8).collect();
411 let compressed = zlib_compress(&raw);
412 let mut decoder = FlateScanlineDecoder::new(&compressed, 10, 12, 1, 8).unwrap();
413
414 let mut collected = Vec::new();
415 while let Some(row) = decoder.decode_scanline().unwrap() {
416 collected.extend_from_slice(row);
417 }
418 assert_eq!(collected, raw);
419 }
420
421 #[test]
422 fn flate_scanline_none_after_last() {
423 let raw = vec![1u8; 4];
425 let compressed = zlib_compress(&raw);
426 let mut decoder = FlateScanlineDecoder::new(&compressed, 4, 1, 1, 8).unwrap();
427
428 assert!(decoder.decode_scanline().unwrap().is_some());
429 assert!(decoder.decode_scanline().unwrap().is_none());
430 assert!(decoder.decode_scanline().unwrap().is_none());
431 }
432
433 #[test]
434 fn flate_scanline_reset() {
435 let raw = vec![1, 2, 3, 4, 5, 6, 7, 8];
437 let compressed = zlib_compress(&raw);
438 let mut decoder = FlateScanlineDecoder::new(&compressed, 4, 2, 1, 8).unwrap();
439
440 let row1 = decoder.decode_scanline().unwrap().unwrap().to_vec();
441 decoder.decode_scanline().unwrap(); assert!(decoder.decode_scanline().unwrap().is_none());
443
444 decoder.reset().unwrap();
445 let row1_again = decoder.decode_scanline().unwrap().unwrap();
446 assert_eq!(row1, row1_again);
447 }
448
449 #[test]
450 fn flate_scanline_row_stride_calc() {
451 let raw = vec![0u8; 1920 * 2];
453 let compressed = zlib_compress(&raw);
454 let decoder = FlateScanlineDecoder::new(&compressed, 640, 2, 3, 8).unwrap();
455 assert_eq!(decoder.row_stride(), 1920);
456 assert_eq!(decoder.width(), 640);
457 assert_eq!(decoder.count_comps(), 3);
458 }
459
460 #[test]
461 fn flate_scanline_zero_stride() {
462 let decoder = FlateScanlineDecoder::from_decoded(vec![1, 2, 3], 0, 1, 1, 8);
464 let mut decoder: Box<dyn ScanlineDecoder> = Box::new(decoder);
465 assert!(decoder.decode_scanline().unwrap().is_none());
466 }
467
468 #[test]
469 fn dct_scanline_from_decoded() {
470 let raw = vec![10, 20, 30, 40, 50, 60];
472 let mut decoder = DctScanlineDecoder::from_decoded(raw.clone(), 1, 2, 3, 8);
473
474 assert_eq!(decoder.width(), 1);
475 assert_eq!(decoder.height(), 2);
476 assert_eq!(decoder.count_comps(), 3);
477 assert_eq!(decoder.bpc(), 8);
478 assert_eq!(decoder.row_stride(), 3);
479
480 let row1 = decoder.decode_scanline().unwrap().unwrap();
481 assert_eq!(row1, &[10, 20, 30]);
482
483 let row2 = decoder.decode_scanline().unwrap().unwrap();
484 assert_eq!(row2, &[40, 50, 60]);
485
486 assert!(decoder.decode_scanline().unwrap().is_none());
487 }
488
489 #[test]
490 fn dct_scanline_reset() {
491 let raw = vec![1, 2, 3, 4, 5, 6];
493 let mut decoder = DctScanlineDecoder::from_decoded(raw, 1, 2, 3, 8);
494
495 decoder.decode_scanline().unwrap();
496 decoder.decode_scanline().unwrap();
497 assert!(decoder.decode_scanline().unwrap().is_none());
498
499 decoder.reset().unwrap();
500 let first = decoder.decode_scanline().unwrap().unwrap();
501 assert_eq!(first, &[1, 2, 3]);
502 }
503
504 #[test]
505 fn scanline_decoder_trait_object_safety() {
506 fn assert_obj_safe(_: &dyn ScanlineDecoder) {}
507 let decoder = FlateScanlineDecoder::from_decoded(vec![0; 4], 2, 1, 1, 8);
509 assert_obj_safe(&decoder);
510 }
511
512 #[test]
513 fn partial_last_row() {
514 let raw = vec![1, 2, 3, 4, 5];
517 let mut decoder = FlateScanlineDecoder::from_decoded(raw, 3, 2, 1, 8);
518
519 let row1 = decoder.decode_scanline().unwrap().unwrap();
520 assert_eq!(row1, &[1, 2, 3]);
521
522 let row2 = decoder.decode_scanline().unwrap().unwrap();
523 assert_eq!(row2, &[4, 5]); assert!(decoder.decode_scanline().unwrap().is_none());
526 }
527
528 #[test]
529 fn metadata_getters_flate() {
530 let raw = vec![0u8; 8 * 6 * 2]; let compressed = zlib_compress(&raw);
533 let decoder = FlateScanlineDecoder::new(&compressed, 8, 6, 1, 16).unwrap();
535 assert_eq!(decoder.width(), 8);
536 assert_eq!(decoder.height(), 6);
537 assert_eq!(decoder.count_comps(), 1);
538 assert_eq!(decoder.bpc(), 16);
539 assert_eq!(decoder.row_stride(), 16);
540 }
541
542 #[test]
543 fn metadata_getters_dct() {
544 let data = vec![0u8; 10 * 4]; let decoder = DctScanlineDecoder::from_decoded(data, 10, 4, 1, 8);
547 assert_eq!(decoder.width(), 10);
548 assert_eq!(decoder.height(), 4);
549 assert_eq!(decoder.count_comps(), 1);
550 assert_eq!(decoder.bpc(), 8);
551 assert_eq!(decoder.row_stride(), 10);
552 }
553
554 #[test]
555 fn compute_row_stride_1bpc() {
556 let d8 = FlateScanlineDecoder::from_decoded(vec![0; 1], 8, 1, 1, 1);
558 assert_eq!(d8.row_stride(), 1);
559 let d9 = FlateScanlineDecoder::from_decoded(vec![0; 2], 9, 1, 1, 1);
560 assert_eq!(d9.row_stride(), 2);
561 }
562
563 #[test]
564 fn compute_row_stride_16bpc() {
565 let decoder = FlateScanlineDecoder::from_decoded(vec![0; 24], 4, 1, 3, 16);
567 assert_eq!(decoder.row_stride(), 24);
568 }
569
570 #[test]
575 fn random_access_sequential() {
576 let raw = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
578 let decoder = FlateScanlineDecoder::from_decoded(raw, 4, 3, 1, 8);
579 let mut ra = RandomAccessDecoder::new(decoder);
580
581 let row0 = ra.get_scanline(0).unwrap().unwrap().to_vec();
582 assert_eq!(row0, &[1, 2, 3, 4]);
583
584 let row1 = ra.get_scanline(1).unwrap().unwrap().to_vec();
585 assert_eq!(row1, &[5, 6, 7, 8]);
586
587 let row2 = ra.get_scanline(2).unwrap().unwrap().to_vec();
588 assert_eq!(row2, &[9, 10, 11, 12]);
589 }
590
591 #[test]
592 fn random_access_cached() {
593 let raw = vec![10, 20, 30, 40, 50, 60];
595 let decoder = FlateScanlineDecoder::from_decoded(raw, 1, 2, 3, 8);
596 let mut ra = RandomAccessDecoder::new(decoder);
597
598 let row0 = ra.get_scanline(0).unwrap().unwrap().to_vec();
599 assert_eq!(row0, &[10, 20, 30]);
600
601 let row0_again = ra.get_scanline(0).unwrap().unwrap().to_vec();
603 assert_eq!(row0_again, &[10, 20, 30]);
604 }
605
606 #[test]
607 fn random_access_rewind() {
608 let raw = vec![1, 2, 3, 4, 5, 6, 7, 8, 9];
610 let decoder = FlateScanlineDecoder::from_decoded(raw, 3, 3, 1, 8);
611 let mut ra = RandomAccessDecoder::new(decoder);
612
613 let row2 = ra.get_scanline(2).unwrap().unwrap().to_vec();
615 assert_eq!(row2, &[7, 8, 9]);
616
617 let row0 = ra.get_scanline(0).unwrap().unwrap().to_vec();
619 assert_eq!(row0, &[1, 2, 3]);
620
621 let row1 = ra.get_scanline(1).unwrap().unwrap().to_vec();
622 assert_eq!(row1, &[4, 5, 6]);
623 }
624
625 #[test]
626 fn random_access_skip_forward() {
627 let raw: Vec<u8> = (0..40).collect();
629 let decoder = FlateScanlineDecoder::from_decoded(raw, 10, 4, 1, 8);
630 let mut ra = RandomAccessDecoder::new(decoder);
631
632 let row3 = ra.get_scanline(3).unwrap().unwrap().to_vec();
634 assert_eq!(row3, &[30, 31, 32, 33, 34, 35, 36, 37, 38, 39]);
635 }
636
637 #[test]
638 fn random_access_out_of_bounds() {
639 let raw = vec![1, 2, 3];
641 let decoder = FlateScanlineDecoder::from_decoded(raw, 3, 1, 1, 8);
642 let mut ra = RandomAccessDecoder::new(decoder);
643
644 let result = ra.get_scanline(1).unwrap();
646 assert!(result.is_none());
647 }
648
649 #[test]
650 fn random_access_inner_ref() {
651 let raw = vec![1, 2, 3, 4];
653 let decoder = FlateScanlineDecoder::from_decoded(raw, 2, 1, 1, 8);
654 let ra = RandomAccessDecoder::new(decoder);
655 assert_eq!(ra.inner().row_stride(), 2);
656 assert_eq!(ra.row_stride(), 2);
657 assert_eq!(ra.width(), 2);
658 assert_eq!(ra.height(), 1);
659 assert_eq!(ra.count_comps(), 1);
660 assert_eq!(ra.bpc(), 8);
661 }
662
663 #[test]
664 fn current_line_before_read() {
665 let decoder = FlateScanlineDecoder::from_decoded(vec![1, 2, 3, 4], 2, 2, 1, 8);
667 assert_eq!(decoder.current_line(), None);
668 }
669
670 #[test]
671 fn current_line_after_read() {
672 let mut decoder = FlateScanlineDecoder::from_decoded(vec![1, 2, 3, 4], 2, 2, 1, 8);
673 decoder.decode_scanline().unwrap();
674 assert_eq!(decoder.current_line(), Some(0));
675 decoder.decode_scanline().unwrap();
676 assert_eq!(decoder.current_line(), Some(1));
677 }
678
679 #[test]
680 fn current_line_after_reset() {
681 let mut decoder = FlateScanlineDecoder::from_decoded(vec![1, 2, 3, 4], 2, 2, 1, 8);
682 decoder.decode_scanline().unwrap();
683 decoder.reset().unwrap();
684 assert_eq!(decoder.current_line(), None);
685 }
686}