1mod interlace_info;
2mod stream;
3pub(crate) mod transform;
4mod zlib;
5
6pub use self::stream::{DecodeOptions, Decoded, DecodingError, StreamingDecoder};
7use self::stream::{FormatErrorInner, CHUNK_BUFFER_SIZE};
8use self::transform::{create_transform_fn, TransformFn};
9
10use std::io::{BufRead, BufReader, ErrorKind, Read};
11use std::mem;
12
13use crate::adam7::{self, Adam7Info};
14use crate::chunk;
15use crate::common::{
16 BitDepth, BytesPerPixel, ColorType, Info, ParameterErrorKind, Transformations,
17};
18use crate::filter::{unfilter, FilterType};
19
20pub use interlace_info::InterlaceInfo;
21use interlace_info::InterlaceInfoIter;
22
23#[derive(Debug, PartialEq, Eq)]
38pub struct OutputInfo {
39 pub width: u32,
41 pub height: u32,
43 pub color_type: ColorType,
45 pub bit_depth: BitDepth,
47 pub line_size: usize,
49}
50
51impl OutputInfo {
52 pub fn buffer_size(&self) -> usize {
56 self.line_size * self.height as usize
57 }
58}
59
60#[derive(Clone, Copy, Debug)]
61pub struct Limits {
63 pub bytes: usize,
65}
66
67impl Limits {
68 pub(crate) fn reserve_bytes(&mut self, bytes: usize) -> Result<(), DecodingError> {
69 if self.bytes >= bytes {
70 self.bytes -= bytes;
71 Ok(())
72 } else {
73 Err(DecodingError::LimitsExceeded)
74 }
75 }
76}
77
78impl Default for Limits {
79 fn default() -> Limits {
80 Limits {
81 bytes: 1024 * 1024 * 64,
82 }
83 }
84}
85
86pub struct Decoder<R: Read> {
88 read_decoder: ReadDecoder<R>,
89 transform: Transformations,
91}
92
93#[derive(Clone, Copy, Debug)]
95pub struct InterlacedRow<'data> {
96 data: &'data [u8],
97 interlace: InterlaceInfo,
98}
99
100impl<'data> InterlacedRow<'data> {
101 pub fn data(&self) -> &'data [u8] {
102 self.data
103 }
104
105 pub fn interlace(&self) -> &InterlaceInfo {
106 &self.interlace
107 }
108}
109
110#[derive(Clone, Copy, Debug)]
112pub struct Row<'data> {
113 data: &'data [u8],
114}
115
116impl<'data> Row<'data> {
117 pub fn data(&self) -> &'data [u8] {
118 self.data
119 }
120}
121
122impl<R: Read> Decoder<R> {
123 pub fn new(r: R) -> Decoder<R> {
125 Decoder::new_with_limits(r, Limits::default())
126 }
127
128 pub fn new_with_limits(r: R, limits: Limits) -> Decoder<R> {
130 let mut decoder = StreamingDecoder::new();
131 decoder.limits = limits;
132
133 Decoder {
134 read_decoder: ReadDecoder {
135 reader: BufReader::with_capacity(CHUNK_BUFFER_SIZE, r),
136 decoder,
137 at_eof: false,
138 },
139 transform: Transformations::IDENTITY,
140 }
141 }
142
143 pub fn new_with_options(r: R, decode_options: DecodeOptions) -> Decoder<R> {
145 let mut decoder = StreamingDecoder::new_with_options(decode_options);
146 decoder.limits = Limits::default();
147
148 Decoder {
149 read_decoder: ReadDecoder {
150 reader: BufReader::with_capacity(CHUNK_BUFFER_SIZE, r),
151 decoder,
152 at_eof: false,
153 },
154 transform: Transformations::IDENTITY,
155 }
156 }
157
158 pub fn set_limits(&mut self, limits: Limits) {
182 self.read_decoder.decoder.limits = limits;
183 }
184
185 pub fn read_header_info(&mut self) -> Result<&Info<'static>, DecodingError> {
190 let mut buf = Vec::new();
191 while self.read_decoder.info().is_none() {
192 buf.clear();
193 if self.read_decoder.decode_next(&mut buf)?.is_none() {
194 return Err(DecodingError::IoError(ErrorKind::UnexpectedEof.into()));
195 }
196 }
197 Ok(self.read_decoder.info().unwrap())
198 }
199
200 pub fn read_info(mut self) -> Result<Reader<R>, DecodingError> {
202 self.read_header_info()?;
203
204 let mut reader = Reader {
205 decoder: self.read_decoder,
206 bpp: BytesPerPixel::One,
207 subframe: SubframeInfo::not_yet_init(),
208 fctl_read: 0,
209 next_frame: SubframeIdx::Initial,
210 data_stream: Vec::new(),
211 prev_start: 0,
212 current_start: 0,
213 transform: self.transform,
214 transform_fn: None,
215 scratch_buffer: Vec::new(),
216 };
217
218 if reader.info().checked_raw_row_length().is_none() {
220 return Err(DecodingError::LimitsExceeded);
221 }
222
223 let (width, height) = reader.info().size();
225 let (color, depth) = reader.output_color_type();
226 let rowlen = color
227 .checked_raw_row_length(depth, width)
228 .ok_or(DecodingError::LimitsExceeded)?
229 - 1;
230 let height: usize =
231 std::convert::TryFrom::try_from(height).map_err(|_| DecodingError::LimitsExceeded)?;
232 if rowlen.checked_mul(height).is_none() {
233 return Err(DecodingError::LimitsExceeded);
234 }
235
236 reader.read_until_image_data()?;
237 Ok(reader)
238 }
239
240 pub fn set_transformations(&mut self, transform: Transformations) {
245 self.transform = transform;
246 }
247
248 pub fn set_ignore_text_chunk(&mut self, ignore_text_chunk: bool) {
259 self.read_decoder
260 .decoder
261 .set_ignore_text_chunk(ignore_text_chunk);
262 }
263
264 pub fn set_ignore_iccp_chunk(&mut self, ignore_iccp_chunk: bool) {
275 self.read_decoder
276 .decoder
277 .set_ignore_iccp_chunk(ignore_iccp_chunk);
278 }
279
280 pub fn ignore_checksums(&mut self, ignore_checksums: bool) {
283 self.read_decoder
284 .decoder
285 .set_ignore_adler32(ignore_checksums);
286 self.read_decoder.decoder.set_ignore_crc(ignore_checksums);
287 }
288}
289
290struct ReadDecoder<R: Read> {
291 reader: BufReader<R>,
292 decoder: StreamingDecoder,
293 at_eof: bool,
294}
295
296impl<R: Read> ReadDecoder<R> {
297 fn decode_next(&mut self, image_data: &mut Vec<u8>) -> Result<Option<Decoded>, DecodingError> {
300 while !self.at_eof {
301 let (consumed, result) = {
302 let buf = self.reader.fill_buf()?;
303 if buf.is_empty() {
304 return Err(DecodingError::IoError(ErrorKind::UnexpectedEof.into()));
305 }
306 self.decoder.update(buf, image_data)?
307 };
308 self.reader.consume(consumed);
309 match result {
310 Decoded::Nothing => (),
311 Decoded::ImageEnd => self.at_eof = true,
312 result => return Ok(Some(result)),
313 }
314 }
315 Ok(None)
316 }
317
318 fn finish_decoding(&mut self) -> Result<(), DecodingError> {
319 while !self.at_eof {
320 let buf = self.reader.fill_buf()?;
321 if buf.is_empty() {
322 return Err(DecodingError::IoError(ErrorKind::UnexpectedEof.into()));
323 }
324 let (consumed, event) = self.decoder.update(buf, &mut vec![])?;
325 self.reader.consume(consumed);
326 match event {
327 Decoded::Nothing => (),
328 Decoded::ImageEnd => self.at_eof = true,
329 Decoded::ChunkComplete(_, _) | Decoded::ChunkBegin(_, _) | Decoded::ImageData => {}
331 Decoded::ImageDataFlushed => return Ok(()),
332 Decoded::PartialChunk(_) => {}
333 new => unreachable!("{:?}", new),
334 }
335 }
336
337 Err(DecodingError::IoError(ErrorKind::UnexpectedEof.into()))
338 }
339
340 fn info(&self) -> Option<&Info<'static>> {
341 self.decoder.info.as_ref()
342 }
343}
344
345pub struct Reader<R: Read> {
349 decoder: ReadDecoder<R>,
350 bpp: BytesPerPixel,
351 subframe: SubframeInfo,
352 fctl_read: u32,
356 next_frame: SubframeIdx,
357 data_stream: Vec<u8>,
359 prev_start: usize,
361 current_start: usize,
363 transform: Transformations,
365 transform_fn: Option<TransformFn>,
368 scratch_buffer: Vec<u8>,
372}
373
374struct SubframeInfo {
381 width: u32,
382 height: u32,
383 rowlen: usize,
384 current_interlace_info: Option<InterlaceInfo>,
385 interlace_info_iter: InterlaceInfoIter,
386 consumed_and_flushed: bool,
387}
388
389#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
391enum SubframeIdx {
392 Initial,
396 Some(u32),
398 End,
400}
401
402impl<R: Read> Reader<R> {
403 fn read_until_image_data(&mut self) -> Result<(), DecodingError> {
406 loop {
407 let mut buf = Vec::new();
411 let state = self.decoder.decode_next(&mut buf)?;
412 assert!(buf.is_empty());
413
414 match state {
415 Some(Decoded::ChunkBegin(_, chunk::IDAT))
416 | Some(Decoded::ChunkBegin(_, chunk::fdAT)) => break,
417 Some(Decoded::FrameControl(_)) => {
418 self.next_frame = SubframeIdx::Some(self.fctl_read);
420 self.fctl_read += 1;
424 }
425 None => {
426 return Err(DecodingError::Format(
427 FormatErrorInner::MissingImageData.into(),
428 ))
429 }
430 _ => {}
433 }
434 }
435
436 let info = self
437 .decoder
438 .info()
439 .ok_or(DecodingError::Format(FormatErrorInner::MissingIhdr.into()))?;
440 self.bpp = info.bpp_in_prediction();
441 self.subframe = SubframeInfo::new(info);
442 self.data_stream.clear();
443 self.current_start = 0;
444 self.prev_start = 0;
445
446 let buflen = self.output_line_size(self.subframe.width);
448 self.decoder.decoder.limits.reserve_bytes(buflen)?;
449
450 self.prev_start = self.current_start;
451
452 Ok(())
453 }
454
455 pub fn info(&self) -> &Info<'static> {
459 self.decoder.info().unwrap()
460 }
461
462 pub fn next_frame(&mut self, buf: &mut [u8]) -> Result<OutputInfo, DecodingError> {
476 if self.next_frame == SubframeIdx::End {
477 return Err(DecodingError::Parameter(
478 ParameterErrorKind::PolledAfterEndOfImage.into(),
479 ));
480 } else if self.subframe.consumed_and_flushed {
481 self.read_until_image_data()?;
484 }
485
486 if buf.len() < self.output_buffer_size() {
487 return Err(DecodingError::Parameter(
488 ParameterErrorKind::ImageBufferSize {
489 expected: buf.len(),
490 actual: self.output_buffer_size(),
491 }
492 .into(),
493 ));
494 }
495
496 let (color_type, bit_depth) = self.output_color_type();
497 let output_info = OutputInfo {
498 width: self.subframe.width,
499 height: self.subframe.height,
500 color_type,
501 bit_depth,
502 line_size: self.output_line_size(self.subframe.width),
503 };
504
505 if self.info().interlaced {
506 let stride = self.output_line_size(self.info().width);
507 let samples = color_type.samples() as u8;
508 let bits_pp = samples * (bit_depth as u8);
509 while let Some(InterlacedRow {
510 data: row,
511 interlace,
512 ..
513 }) = self.next_interlaced_row()?
514 {
515 let adam7info = interlace.get_adam7_info().unwrap();
517 adam7::expand_pass(buf, stride, row, adam7info, bits_pp);
518 }
519 } else {
520 let current_interlace_info = self.subframe.current_interlace_info.as_ref();
521 let already_done_rows = current_interlace_info
522 .map(|info| info.line_number())
523 .unwrap_or(self.subframe.height);
524
525 for row in buf
526 .chunks_exact_mut(output_info.line_size)
527 .take(self.subframe.height as usize)
528 .skip(already_done_rows as usize)
529 {
530 self.next_interlaced_row_impl(self.subframe.rowlen, row)?;
531 }
532 }
533
534 if !self.subframe.consumed_and_flushed {
536 self.decoder.finish_decoding()?;
537 self.subframe.consumed_and_flushed = true;
538 }
539
540 let past_end_subframe = self
542 .info()
543 .animation_control()
544 .map(|ac| ac.num_frames)
545 .unwrap_or(0);
546 self.next_frame = match self.next_frame {
547 SubframeIdx::End => unreachable!("Next frame called when already at image end"),
548 SubframeIdx::Initial if past_end_subframe == 0 => SubframeIdx::End,
550 SubframeIdx::Initial => SubframeIdx::Some(0),
552 SubframeIdx::Some(idx) if past_end_subframe <= idx + 1 => SubframeIdx::End,
554 SubframeIdx::Some(idx) => SubframeIdx::Some(idx + 1),
556 };
557
558 Ok(output_info)
559 }
560
561 pub fn next_row(&mut self) -> Result<Option<Row>, DecodingError> {
563 self.next_interlaced_row()
564 .map(|v| v.map(|v| Row { data: v.data }))
565 }
566
567 pub fn next_interlaced_row(&mut self) -> Result<Option<InterlacedRow>, DecodingError> {
569 let interlace = match self.subframe.current_interlace_info.as_ref() {
570 None => return Ok(None),
571 Some(interlace) => *interlace,
572 };
573 if interlace.line_number() == 0 {
574 self.prev_start = self.current_start;
575 }
576 let rowlen = match interlace {
577 InterlaceInfo::Null(_) => self.subframe.rowlen,
578 InterlaceInfo::Adam7(Adam7Info { width, .. }) => {
579 self.info().raw_row_length_from_width(width)
580 }
581 };
582 let width = match interlace {
583 InterlaceInfo::Adam7(Adam7Info { width, .. }) => width,
584 InterlaceInfo::Null(_) => self.subframe.width,
585 };
586 let output_line_size = self.output_line_size(width);
587
588 let mut output_buffer = mem::take(&mut self.scratch_buffer);
591 output_buffer.resize(output_line_size, 0u8);
592 let ret = self.next_interlaced_row_impl(rowlen, &mut output_buffer);
593 self.scratch_buffer = output_buffer;
594 ret?;
595
596 Ok(Some(InterlacedRow {
597 data: &self.scratch_buffer[..output_line_size],
598 interlace,
599 }))
600 }
601
602 pub fn finish(&mut self) -> Result<(), DecodingError> {
605 self.next_frame = SubframeIdx::End;
606 self.data_stream.clear();
607 self.current_start = 0;
608 self.prev_start = 0;
609 loop {
610 let mut buf = Vec::new();
611 let state = self.decoder.decode_next(&mut buf)?;
612
613 if state.is_none() {
614 break;
615 }
616 }
617
618 Ok(())
619 }
620
621 fn next_interlaced_row_impl(
623 &mut self,
624 rowlen: usize,
625 output_buffer: &mut [u8],
626 ) -> Result<(), DecodingError> {
627 self.next_raw_interlaced_row(rowlen)?;
628 assert_eq!(self.current_start - self.prev_start, rowlen - 1);
629 let row = &self.data_stream[self.prev_start..self.current_start];
630
631 let transform_fn = {
633 if self.transform_fn.is_none() {
634 self.transform_fn = Some(create_transform_fn(self.info(), self.transform)?);
635 }
636 self.transform_fn.as_deref().unwrap()
637 };
638 transform_fn(row, output_buffer, self.info());
639
640 self.subframe.current_interlace_info = self.subframe.interlace_info_iter.next();
641 Ok(())
642 }
643
644 pub fn output_color_type(&self) -> (ColorType, BitDepth) {
647 use crate::common::ColorType::*;
648 let t = self.transform;
649 let info = self.info();
650 if t == Transformations::IDENTITY {
651 (info.color_type, info.bit_depth)
652 } else {
653 let bits = match info.bit_depth as u8 {
654 16 if t.intersects(Transformations::STRIP_16) => 8,
655 n if n < 8
656 && (t.contains(Transformations::EXPAND)
657 || t.contains(Transformations::ALPHA)) =>
658 {
659 8
660 }
661 n => n,
662 };
663 let color_type =
664 if t.contains(Transformations::EXPAND) || t.contains(Transformations::ALPHA) {
665 let has_trns = info.trns.is_some() || t.contains(Transformations::ALPHA);
666 match info.color_type {
667 Grayscale if has_trns => GrayscaleAlpha,
668 Rgb if has_trns => Rgba,
669 Indexed if has_trns => Rgba,
670 Indexed => Rgb,
671 ct => ct,
672 }
673 } else {
674 info.color_type
675 };
676 (color_type, BitDepth::from_u8(bits).unwrap())
677 }
678 }
679
680 pub fn output_buffer_size(&self) -> usize {
683 let (width, height) = self.info().size();
684 let size = self.output_line_size(width);
685 size * height as usize
686 }
687
688 pub fn output_line_size(&self, width: u32) -> usize {
690 let (color, depth) = self.output_color_type();
691 color.raw_row_length_from_width(depth, width) - 1
692 }
693
694 fn next_raw_interlaced_row(&mut self, rowlen: usize) -> Result<(), DecodingError> {
698 while self.data_stream.len() - self.current_start < rowlen {
700 if self.subframe.consumed_and_flushed {
701 return Err(DecodingError::Format(
702 FormatErrorInner::NoMoreImageData.into(),
703 ));
704 }
705
706 if self.prev_start > 0 {
708 self.data_stream.copy_within(self.prev_start.., 0);
709 self.data_stream
710 .truncate(self.data_stream.len() - self.prev_start);
711 self.current_start -= self.prev_start;
712 self.prev_start = 0;
713 }
714
715 match self.decoder.decode_next(&mut self.data_stream)? {
716 Some(Decoded::ImageData) => (),
717 Some(Decoded::ImageDataFlushed) => self.subframe.consumed_and_flushed = true,
718 _ => (),
719 }
720 }
721
722 let (prev, row) = self.data_stream.split_at_mut(self.current_start);
724
725 let filter = FilterType::from_u8(row[0]).ok_or(DecodingError::Format(
727 FormatErrorInner::UnknownFilterMethod(row[0]).into(),
728 ))?;
729 unfilter(
730 filter,
731 self.bpp,
732 &prev[self.prev_start..],
733 &mut row[1..rowlen],
734 );
735
736 self.prev_start = self.current_start + 1;
737 self.current_start += rowlen;
738
739 Ok(())
740 }
741}
742
743impl SubframeInfo {
744 fn not_yet_init() -> Self {
745 SubframeInfo {
746 width: 0,
747 height: 0,
748 rowlen: 0,
749 current_interlace_info: None,
750 interlace_info_iter: InterlaceInfoIter::empty(),
751 consumed_and_flushed: false,
752 }
753 }
754
755 fn new(info: &Info) -> Self {
756 let (width, height) = if let Some(fc) = info.frame_control {
759 (fc.width, fc.height)
760 } else {
761 (info.width, info.height)
762 };
763
764 let mut interlace_info_iter = InterlaceInfoIter::new(width, height, info.interlaced);
765 let current_interlace_info = interlace_info_iter.next();
766 SubframeInfo {
767 width,
768 height,
769 rowlen: info.raw_row_length_from_width(width),
770 current_interlace_info,
771 interlace_info_iter,
772 consumed_and_flushed: false,
773 }
774 }
775}