1mod interlace_info;
2mod read_decoder;
3pub(crate) mod stream;
4pub(crate) mod transform;
5mod unfiltering_buffer;
6mod zlib;
7
8use self::read_decoder::{ImageDataCompletionStatus, ReadDecoder};
9use self::stream::{DecodeOptions, DecodingError, FormatErrorInner, CHUNK_BUFFER_SIZE};
10use self::transform::{create_transform_fn, TransformFn};
11use self::unfiltering_buffer::UnfilteringBuffer;
12
13use std::io::Read;
14use std::mem;
15
16use crate::adam7::{self, Adam7Info};
17use crate::common::{
18 BitDepth, BytesPerPixel, ColorType, Info, ParameterErrorKind, Transformations,
19};
20use crate::FrameControl;
21
22pub use interlace_info::InterlaceInfo;
23use interlace_info::InterlaceInfoIter;
24
25#[derive(Debug, PartialEq, Eq)]
40pub struct OutputInfo {
41 pub width: u32,
43 pub height: u32,
45 pub color_type: ColorType,
47 pub bit_depth: BitDepth,
49 pub line_size: usize,
51}
52
53impl OutputInfo {
54 pub fn buffer_size(&self) -> usize {
58 self.line_size * self.height as usize
59 }
60}
61
62#[derive(Clone, Copy, Debug)]
63pub struct Limits {
65 pub bytes: usize,
67}
68
69impl Limits {
70 pub(crate) fn reserve_bytes(&mut self, bytes: usize) -> Result<(), DecodingError> {
71 if self.bytes >= bytes {
72 self.bytes -= bytes;
73 Ok(())
74 } else {
75 Err(DecodingError::LimitsExceeded)
76 }
77 }
78}
79
80impl Default for Limits {
81 fn default() -> Limits {
82 Limits {
83 bytes: 1024 * 1024 * 64,
84 }
85 }
86}
87
88pub struct Decoder<R: Read> {
90 read_decoder: ReadDecoder<R>,
91 transform: Transformations,
93}
94
95#[derive(Clone, Copy, Debug)]
97pub struct InterlacedRow<'data> {
98 data: &'data [u8],
99 interlace: InterlaceInfo,
100}
101
102impl<'data> InterlacedRow<'data> {
103 pub fn data(&self) -> &'data [u8] {
104 self.data
105 }
106
107 pub fn interlace(&self) -> &InterlaceInfo {
108 &self.interlace
109 }
110}
111
112#[derive(Clone, Copy, Debug)]
114pub struct Row<'data> {
115 data: &'data [u8],
116}
117
118impl<'data> Row<'data> {
119 pub fn data(&self) -> &'data [u8] {
120 self.data
121 }
122}
123
124impl<R: Read> Decoder<R> {
125 pub fn new(r: R) -> Decoder<R> {
127 Decoder::new_with_limits(r, Limits::default())
128 }
129
130 pub fn new_with_limits(r: R, limits: Limits) -> Decoder<R> {
132 let mut read_decoder = ReadDecoder::new(r);
133 read_decoder.set_limits(limits);
134
135 Decoder {
136 read_decoder,
137 transform: Transformations::IDENTITY,
138 }
139 }
140
141 pub fn new_with_options(r: R, decode_options: DecodeOptions) -> Decoder<R> {
143 let mut read_decoder = ReadDecoder::with_options(r, decode_options);
144 read_decoder.set_limits(Limits::default());
145
146 Decoder {
147 read_decoder,
148 transform: Transformations::IDENTITY,
149 }
150 }
151
152 pub fn set_limits(&mut self, limits: Limits) {
176 self.read_decoder.set_limits(limits);
177 }
178
179 pub fn read_header_info(&mut self) -> Result<&Info<'static>, DecodingError> {
184 self.read_decoder.read_header_info()
185 }
186
187 pub fn read_info(mut self) -> Result<Reader<R>, DecodingError> {
189 self.read_header_info()?;
190
191 let mut reader = Reader {
192 decoder: self.read_decoder,
193 bpp: BytesPerPixel::One,
194 subframe: SubframeInfo::not_yet_init(),
195 remaining_frames: 0, unfiltering_buffer: UnfilteringBuffer::new(),
197 transform: self.transform,
198 transform_fn: None,
199 scratch_buffer: Vec::new(),
200 finished: false,
201 };
202
203 if reader.info().checked_raw_row_length().is_none() {
205 return Err(DecodingError::LimitsExceeded);
206 }
207
208 let (width, height) = reader.info().size();
210 let (color, depth) = reader.output_color_type();
211 let rowlen = color
212 .checked_raw_row_length(depth, width)
213 .ok_or(DecodingError::LimitsExceeded)?
214 - 1;
215 let height: usize =
216 std::convert::TryFrom::try_from(height).map_err(|_| DecodingError::LimitsExceeded)?;
217 if rowlen.checked_mul(height).is_none() {
218 return Err(DecodingError::LimitsExceeded);
219 }
220
221 reader.read_until_image_data()?;
222
223 reader.remaining_frames = match reader.info().animation_control.as_ref() {
224 None => 1, Some(animation) => {
226 let mut num_frames = animation.num_frames as usize;
227 if reader.info().frame_control.is_none() {
228 num_frames += 1;
231 }
232 num_frames
233 }
234 };
235 Ok(reader)
236 }
237
238 pub fn set_transformations(&mut self, transform: Transformations) {
243 self.transform = transform;
244 }
245
246 pub fn set_ignore_text_chunk(&mut self, ignore_text_chunk: bool) {
257 self.read_decoder.set_ignore_text_chunk(ignore_text_chunk);
258 }
259
260 pub fn set_ignore_iccp_chunk(&mut self, ignore_iccp_chunk: bool) {
271 self.read_decoder.set_ignore_iccp_chunk(ignore_iccp_chunk);
272 }
273
274 pub fn ignore_checksums(&mut self, ignore_checksums: bool) {
277 self.read_decoder.ignore_checksums(ignore_checksums);
278 }
279}
280
281pub struct Reader<R: Read> {
285 decoder: ReadDecoder<R>,
286 bpp: BytesPerPixel,
287 subframe: SubframeInfo,
288 remaining_frames: usize,
290 unfiltering_buffer: UnfilteringBuffer,
292 transform: Transformations,
294 transform_fn: Option<TransformFn>,
297 scratch_buffer: Vec<u8>,
301 finished: bool,
303}
304
305struct SubframeInfo {
312 width: u32,
313 height: u32,
314 rowlen: usize,
315 current_interlace_info: Option<InterlaceInfo>,
316 interlace_info_iter: InterlaceInfoIter,
317 consumed_and_flushed: bool,
318}
319
320impl<R: Read> Reader<R> {
321 pub fn next_frame_info(&mut self) -> Result<&FrameControl, DecodingError> {
329 let remaining_frames = if self.subframe.consumed_and_flushed {
330 self.remaining_frames
331 } else {
332 self.remaining_frames - 1
334 };
335 if remaining_frames == 0 {
336 return Err(DecodingError::Parameter(
337 ParameterErrorKind::PolledAfterEndOfImage.into(),
338 ));
339 }
340
341 if !self.subframe.consumed_and_flushed {
342 self.subframe.current_interlace_info = None;
343 self.finish_decoding()?;
344 }
345 self.read_until_image_data()?;
346
347 Ok(self.info().frame_control.as_ref().unwrap())
351 }
352
353 fn read_until_image_data(&mut self) -> Result<(), DecodingError> {
356 self.decoder.read_until_image_data()?;
357
358 self.subframe = SubframeInfo::new(self.info());
359 self.bpp = self.info().bpp_in_prediction();
360 self.unfiltering_buffer = UnfilteringBuffer::new();
361
362 let buflen = self.output_line_size(self.subframe.width);
364 self.decoder.reserve_bytes(buflen)?;
365
366 Ok(())
367 }
368
369 pub fn info(&self) -> &Info<'static> {
373 self.decoder.info().unwrap()
374 }
375
376 pub fn next_frame(&mut self, buf: &mut [u8]) -> Result<OutputInfo, DecodingError> {
390 if self.remaining_frames == 0 {
391 return Err(DecodingError::Parameter(
392 ParameterErrorKind::PolledAfterEndOfImage.into(),
393 ));
394 } else if self.subframe.consumed_and_flushed {
395 self.read_until_image_data()?;
398 }
399
400 if buf.len() < self.output_buffer_size() {
401 return Err(DecodingError::Parameter(
402 ParameterErrorKind::ImageBufferSize {
403 expected: buf.len(),
404 actual: self.output_buffer_size(),
405 }
406 .into(),
407 ));
408 }
409
410 let (color_type, bit_depth) = self.output_color_type();
411 let output_info = OutputInfo {
412 width: self.subframe.width,
413 height: self.subframe.height,
414 color_type,
415 bit_depth,
416 line_size: self.output_line_size(self.subframe.width),
417 };
418
419 if self.info().interlaced {
420 let stride = self.output_line_size(self.info().width);
421 let samples = color_type.samples() as u8;
422 let bits_pp = samples * (bit_depth as u8);
423 while let Some(InterlacedRow {
424 data: row,
425 interlace,
426 ..
427 }) = self.next_interlaced_row()?
428 {
429 let adam7info = interlace.get_adam7_info().unwrap();
431 adam7::expand_pass(buf, stride, row, adam7info, bits_pp);
432 }
433 } else {
434 let current_interlace_info = self.subframe.current_interlace_info.as_ref();
435 let already_done_rows = current_interlace_info
436 .map(|info| info.line_number())
437 .unwrap_or(self.subframe.height);
438
439 for row in buf
440 .chunks_exact_mut(output_info.line_size)
441 .take(self.subframe.height as usize)
442 .skip(already_done_rows as usize)
443 {
444 self.next_interlaced_row_impl(self.subframe.rowlen, row)?;
445 }
446 }
447
448 self.finish_decoding()?;
450
451 Ok(output_info)
452 }
453
454 fn mark_subframe_as_consumed_and_flushed(&mut self) {
455 assert!(self.remaining_frames > 0);
456 self.remaining_frames -= 1;
457
458 self.subframe.consumed_and_flushed = true;
459 }
460
461 fn finish_decoding(&mut self) -> Result<(), DecodingError> {
464 assert!(self.subframe.current_interlace_info.is_none());
467
468 if !self.subframe.consumed_and_flushed {
470 self.decoder.finish_decoding_image_data()?;
471 self.mark_subframe_as_consumed_and_flushed();
472 }
473
474 Ok(())
475 }
476
477 pub fn next_row(&mut self) -> Result<Option<Row>, DecodingError> {
479 self.next_interlaced_row()
480 .map(|v| v.map(|v| Row { data: v.data }))
481 }
482
483 pub fn next_interlaced_row(&mut self) -> Result<Option<InterlacedRow>, DecodingError> {
485 let interlace = match self.subframe.current_interlace_info.as_ref() {
486 None => {
487 self.finish_decoding()?;
488 return Ok(None);
489 }
490 Some(interlace) => *interlace,
491 };
492 if interlace.line_number() == 0 {
493 self.unfiltering_buffer.reset_prev_row();
494 }
495 let rowlen = match interlace {
496 InterlaceInfo::Null(_) => self.subframe.rowlen,
497 InterlaceInfo::Adam7(Adam7Info { width, .. }) => {
498 self.info().raw_row_length_from_width(width)
499 }
500 };
501 let width = match interlace {
502 InterlaceInfo::Adam7(Adam7Info { width, .. }) => width,
503 InterlaceInfo::Null(_) => self.subframe.width,
504 };
505 let output_line_size = self.output_line_size(width);
506
507 let mut output_buffer = mem::take(&mut self.scratch_buffer);
510 output_buffer.resize(output_line_size, 0u8);
511 let ret = self.next_interlaced_row_impl(rowlen, &mut output_buffer);
512 self.scratch_buffer = output_buffer;
513 ret?;
514
515 Ok(Some(InterlacedRow {
516 data: &self.scratch_buffer[..output_line_size],
517 interlace,
518 }))
519 }
520
521 pub fn finish(&mut self) -> Result<(), DecodingError> {
524 if self.finished {
525 return Err(DecodingError::Parameter(
526 ParameterErrorKind::PolledAfterEndOfImage.into(),
527 ));
528 }
529
530 self.remaining_frames = 0;
531 self.unfiltering_buffer = UnfilteringBuffer::new();
532 self.decoder.read_until_end_of_input()?;
533
534 self.finished = true;
535 Ok(())
536 }
537
538 fn next_interlaced_row_impl(
540 &mut self,
541 rowlen: usize,
542 output_buffer: &mut [u8],
543 ) -> Result<(), DecodingError> {
544 self.next_raw_interlaced_row(rowlen)?;
545 let row = self.unfiltering_buffer.prev_row();
546 assert_eq!(row.len(), rowlen - 1);
547
548 let transform_fn = {
550 if self.transform_fn.is_none() {
551 self.transform_fn = Some(create_transform_fn(self.info(), self.transform)?);
552 }
553 self.transform_fn.as_deref().unwrap()
554 };
555 transform_fn(row, output_buffer, self.info());
556
557 self.subframe.current_interlace_info = self.subframe.interlace_info_iter.next();
558 Ok(())
559 }
560
561 pub fn output_color_type(&self) -> (ColorType, BitDepth) {
564 use crate::common::ColorType::*;
565 let t = self.transform;
566 let info = self.info();
567 if t == Transformations::IDENTITY {
568 (info.color_type, info.bit_depth)
569 } else {
570 let bits = match info.bit_depth as u8 {
571 16 if t.intersects(Transformations::STRIP_16) => 8,
572 n if n < 8
573 && (t.contains(Transformations::EXPAND)
574 || t.contains(Transformations::ALPHA)) =>
575 {
576 8
577 }
578 n => n,
579 };
580 let color_type =
581 if t.contains(Transformations::EXPAND) || t.contains(Transformations::ALPHA) {
582 let has_trns = info.trns.is_some() || t.contains(Transformations::ALPHA);
583 match info.color_type {
584 Grayscale if has_trns => GrayscaleAlpha,
585 Rgb if has_trns => Rgba,
586 Indexed if has_trns => Rgba,
587 Indexed => Rgb,
588 ct => ct,
589 }
590 } else {
591 info.color_type
592 };
593 (color_type, BitDepth::from_u8(bits).unwrap())
594 }
595 }
596
597 pub fn output_buffer_size(&self) -> usize {
600 let (width, height) = self.info().size();
601 let size = self.output_line_size(width);
602 size * height as usize
603 }
604
605 pub fn output_line_size(&self, width: u32) -> usize {
607 let (color, depth) = self.output_color_type();
608 color.raw_row_length_from_width(depth, width) - 1
609 }
610
611 fn next_raw_interlaced_row(&mut self, rowlen: usize) -> Result<(), DecodingError> {
613 while self.unfiltering_buffer.curr_row_len() < rowlen {
615 if self.subframe.consumed_and_flushed {
616 return Err(DecodingError::Format(
617 FormatErrorInner::NoMoreImageData.into(),
618 ));
619 }
620
621 match self
622 .decoder
623 .decode_image_data(self.unfiltering_buffer.as_mut_vec())?
624 {
625 ImageDataCompletionStatus::ExpectingMoreData => (),
626 ImageDataCompletionStatus::Done => self.mark_subframe_as_consumed_and_flushed(),
627 }
628 }
629
630 self.unfiltering_buffer.unfilter_curr_row(rowlen, self.bpp)
631 }
632}
633
634impl SubframeInfo {
635 fn not_yet_init() -> Self {
636 SubframeInfo {
637 width: 0,
638 height: 0,
639 rowlen: 0,
640 current_interlace_info: None,
641 interlace_info_iter: InterlaceInfoIter::empty(),
642 consumed_and_flushed: false,
643 }
644 }
645
646 fn new(info: &Info) -> Self {
647 let (width, height) = if let Some(fc) = info.frame_control {
650 (fc.width, fc.height)
651 } else {
652 (info.width, info.height)
653 };
654
655 let mut interlace_info_iter = InterlaceInfoIter::new(width, height, info.interlaced);
656 let current_interlace_info = interlace_info_iter.next();
657 SubframeInfo {
658 width,
659 height,
660 rowlen: info.raw_row_length_from_width(width),
661 current_interlace_info,
662 interlace_info_iter,
663 consumed_and_flushed: false,
664 }
665 }
666}