png/decoder/
mod.rs

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/*
24pub enum InterlaceHandling {
25    /// Outputs the raw rows
26    RawRows,
27    /// Fill missing the pixels from the existing ones
28    Rectangle,
29    /// Only fill the needed pixels
30    Sparkle
31}
32*/
33
34/// Output info.
35///
36/// This describes one particular frame of the image that was written into the output buffer.
37#[derive(Debug, PartialEq, Eq)]
38pub struct OutputInfo {
39    /// The pixel width of this frame.
40    pub width: u32,
41    /// The pixel height of this frame.
42    pub height: u32,
43    /// The chosen output color type.
44    pub color_type: ColorType,
45    /// The chosen output bit depth.
46    pub bit_depth: BitDepth,
47    /// The byte count of each scan line in the image.
48    pub line_size: usize,
49}
50
51impl OutputInfo {
52    /// Returns the size needed to hold a decoded frame
53    /// If the output buffer was larger then bytes after this count should be ignored. They may
54    /// still have been changed.
55    pub fn buffer_size(&self) -> usize {
56        self.line_size * self.height as usize
57    }
58}
59
60#[derive(Clone, Copy, Debug)]
61/// Limits on the resources the `Decoder` is allowed too use
62pub struct Limits {
63    /// maximum number of bytes the decoder is allowed to allocate, default is 64Mib
64    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
86/// PNG Decoder
87pub struct Decoder<R: Read> {
88    read_decoder: ReadDecoder<R>,
89    /// Output transformations
90    transform: Transformations,
91}
92
93/// A row of data with interlace information attached.
94#[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/// A row of data without interlace information.
111#[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    /// Create a new decoder configuration with default limits.
124    pub fn new(r: R) -> Decoder<R> {
125        Decoder::new_with_limits(r, Limits::default())
126    }
127
128    /// Create a new decoder configuration with custom limits.
129    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    /// Create a new decoder configuration with custom `DecodeOptions`.
144    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    /// Limit resource usage.
159    ///
160    /// Note that your allocations, e.g. when reading into a pre-allocated buffer, are __NOT__
161    /// considered part of the limits. Nevertheless, required intermediate buffers such as for
162    /// singular lines is checked against the limit.
163    ///
164    /// Note that this is a best-effort basis.
165    ///
166    /// ```
167    /// use std::fs::File;
168    /// use png::{Decoder, Limits};
169    /// // This image is 32×32, 1bit per pixel. The reader buffers one row which requires 4 bytes.
170    /// let mut limits = Limits::default();
171    /// limits.bytes = 3;
172    /// let mut decoder = Decoder::new_with_limits(File::open("tests/pngsuite/basi0g01.png").unwrap(), limits);
173    /// assert!(decoder.read_info().is_err());
174    ///
175    /// // This image is 32x32 pixels, so the decoder will allocate less than 10Kib
176    /// let mut limits = Limits::default();
177    /// limits.bytes = 10*1024;
178    /// let mut decoder = Decoder::new_with_limits(File::open("tests/pngsuite/basi0g01.png").unwrap(), limits);
179    /// assert!(decoder.read_info().is_ok());
180    /// ```
181    pub fn set_limits(&mut self, limits: Limits) {
182        self.read_decoder.decoder.limits = limits;
183    }
184
185    /// Read the PNG header and return the information contained within.
186    ///
187    /// Most image metadata will not be read until `read_info` is called, so those fields will be
188    /// None or empty.
189    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    /// Reads all meta data until the first IDAT chunk
201    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        // Check if the decoding buffer of a single raw line has a valid size.
219        if reader.info().checked_raw_row_length().is_none() {
220            return Err(DecodingError::LimitsExceeded);
221        }
222
223        // Check if the output buffer has a valid size.
224        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    /// Set the allowed and performed transformations.
241    ///
242    /// A transformation is a pre-processing on the raw image data modifying content or encoding.
243    /// Many options have an impact on memory or CPU usage during decoding.
244    pub fn set_transformations(&mut self, transform: Transformations) {
245        self.transform = transform;
246    }
247
248    /// Set the decoder to ignore all text chunks while parsing.
249    ///
250    /// eg.
251    /// ```
252    /// use std::fs::File;
253    /// use png::Decoder;
254    /// let mut decoder = Decoder::new(File::open("tests/pngsuite/basi0g01.png").unwrap());
255    /// decoder.set_ignore_text_chunk(true);
256    /// assert!(decoder.read_info().is_ok());
257    /// ```
258    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    /// Set the decoder to ignore iccp chunks while parsing.
265    ///
266    /// eg.
267    /// ```
268    /// use std::fs::File;
269    /// use png::Decoder;
270    /// let mut decoder = Decoder::new(File::open("tests/iccp/broken_iccp.png").unwrap());
271    /// decoder.set_ignore_iccp_chunk(true);
272    /// assert!(decoder.read_info().is_ok());
273    /// ```
274    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    /// Set the decoder to ignore and not verify the Adler-32 checksum
281    /// and CRC code.
282    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    /// Returns the next decoded chunk. If the chunk is an ImageData chunk, its contents are written
298    /// into image_data.
299    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                // ignore more data
330                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
345/// PNG reader (mostly high-level interface)
346///
347/// Provides a high level that iterates over lines or whole images.
348pub struct Reader<R: Read> {
349    decoder: ReadDecoder<R>,
350    bpp: BytesPerPixel,
351    subframe: SubframeInfo,
352    /// Number of frame control chunks read.
353    /// By the APNG specification the total number must equal the count specified in the animation
354    /// control chunk. The IDAT image _may_ have such a chunk applying to it.
355    fctl_read: u32,
356    next_frame: SubframeIdx,
357    /// Vec containing the uncompressed image data currently being processed.
358    data_stream: Vec<u8>,
359    /// Index in `data_stream` where the previous row starts.
360    prev_start: usize,
361    /// Index in `data_stream` where the current row starts.
362    current_start: usize,
363    /// Output transformations
364    transform: Transformations,
365    /// Function that can transform decompressed, unfiltered rows into final output.
366    /// See the `transform.rs` module for more details.
367    transform_fn: Option<TransformFn>,
368    /// This buffer is only used so that `next_row` and `next_interlaced_row` can return reference
369    /// to a byte slice. In a future version of this library, this buffer will be removed and
370    /// `next_row` and `next_interlaced_row` will write directly into a user provided output buffer.
371    scratch_buffer: Vec<u8>,
372}
373
374/// The subframe specific information.
375///
376/// In APNG the frames are constructed by combining previous frame and a new subframe (through a
377/// combination of `dispose_op` and `overlay_op`). These sub frames specify individual dimension
378/// information and reuse the global interlace options. This struct encapsulates the state of where
379/// in a particular IDAT-frame or subframe we are.
380struct 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/// Denote a frame as given by sequence numbers.
390#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
391enum SubframeIdx {
392    /// The initial frame in an IDAT chunk without fcTL chunk applying to it.
393    /// Note that this variant precedes `Some` as IDAT frames precede fdAT frames and all fdAT
394    /// frames must have a fcTL applying to it.
395    Initial,
396    /// An IDAT frame with fcTL or an fdAT frame.
397    Some(u32),
398    /// The past-the-end index.
399    End,
400}
401
402impl<R: Read> Reader<R> {
403    /// Reads all meta data until the next frame data starts.
404    /// Requires IHDR before the IDAT and fcTL before fdAT.
405    fn read_until_image_data(&mut self) -> Result<(), DecodingError> {
406        loop {
407            // This is somewhat ugly. The API requires us to pass a buffer to decode_next but we
408            // know that we will stop before reading any image data from the stream. Thus pass an
409            // empty buffer and assert that remains empty.
410            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                    // The next frame is the one to which this chunk applies.
419                    self.next_frame = SubframeIdx::Some(self.fctl_read);
420                    // TODO: what about overflow here? That would imply there are more fctl chunks
421                    // than can be specified in the animation control but also that we have read
422                    // several gigabytes of data.
423                    self.fctl_read += 1;
424                }
425                None => {
426                    return Err(DecodingError::Format(
427                        FormatErrorInner::MissingImageData.into(),
428                    ))
429                }
430                // Ignore all other chunk events. Any other chunk may be between IDAT chunks, fdAT
431                // chunks and their control chunks.
432                _ => {}
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        // Allocate output buffer.
447        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    /// Get information on the image.
456    ///
457    /// The structure will change as new frames of an animated image are decoded.
458    pub fn info(&self) -> &Info<'static> {
459        self.decoder.info().unwrap()
460    }
461
462    /// Decodes the next frame into `buf`.
463    ///
464    /// Note that this decodes raw subframes that need to be mixed according to blend-op and
465    /// dispose-op by the caller.
466    ///
467    /// The caller must always provide a buffer large enough to hold a complete frame (the APNG
468    /// specification restricts subframes to the dimensions given in the image header). The region
469    /// that has been written be checked afterwards by calling `info` after a successful call and
470    /// inspecting the `frame_control` data. This requirement may be lifted in a later version of
471    /// `png`.
472    ///
473    /// Output lines will be written in row-major, packed matrix with width and height of the read
474    /// frame (or subframe), all samples are in big endian byte order where this matters.
475    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            // Advance until the next `fdAT`
482            // (along the way we should encounter the fcTL for this frame).
483            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                // `unwrap` won't panic, because we checked `self.info().interlaced` above.
516                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        // Advance over the rest of data for this (sub-)frame.
535        if !self.subframe.consumed_and_flushed {
536            self.decoder.finish_decoding()?;
537            self.subframe.consumed_and_flushed = true;
538        }
539
540        // Advance our state to expect the next frame.
541        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            // Reached the end of non-animated image.
549            SubframeIdx::Initial if past_end_subframe == 0 => SubframeIdx::End,
550            // An animated image, expecting first subframe.
551            SubframeIdx::Initial => SubframeIdx::Some(0),
552            // This was the last subframe, slightly fuzzy condition in case of programmer error.
553            SubframeIdx::Some(idx) if past_end_subframe <= idx + 1 => SubframeIdx::End,
554            // Expecting next subframe.
555            SubframeIdx::Some(idx) => SubframeIdx::Some(idx + 1),
556        };
557
558        Ok(output_info)
559    }
560
561    /// Returns the next processed row of the image
562    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    /// Returns the next processed row of the image
568    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        // TODO: change the interface of `next_interlaced_row` to take an output buffer instead of
589        // making us return a reference to a buffer that we own.
590        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    /// Read the rest of the image and chunks and finish up, including text chunks or others
603    /// This will discard the rest of the image if the image is not read already with [`Reader::next_frame`], [`Reader::next_row`] or [`Reader::next_interlaced_row`]
604    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    /// Fetch the next interlaced row and filter it according to our own transformations.
622    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        // Apply transformations and write resulting data to buffer.
632        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    /// Returns the color type and the number of bits per sample
645    /// of the data returned by `Reader::next_row` and Reader::frames`.
646    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    /// Returns the number of bytes required to hold a deinterlaced image frame
681    /// that is decoded using the given input transformations.
682    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    /// Returns the number of bytes required to hold a deinterlaced row.
689    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    /// Write the next raw interlaced row into `self.prev`.
695    ///
696    /// The scanline is filtered against the previous scanline according to the specification.
697    fn next_raw_interlaced_row(&mut self, rowlen: usize) -> Result<(), DecodingError> {
698        // Read image data until we have at least one full row (but possibly more than one).
699        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            // Clear the current buffer before appending more data.
707            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        // Get a reference to the current row and point scan_start to the next one.
723        let (prev, row) = self.data_stream.split_at_mut(self.current_start);
724
725        // Unfilter the row.
726        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        // The apng fctnl overrides width and height.
757        // All other data is set by the main info struct.
758        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}