@@ -2,11 +2,13 @@ mod interlace_info;
2
2
mod read_decoder;
3
3
pub ( crate ) mod stream;
4
4
pub ( crate ) mod transform;
5
+ mod unfiltering_buffer;
5
6
mod zlib;
6
7
7
8
use self :: read_decoder:: { ImageDataCompletionStatus , ReadDecoder } ;
8
9
use self :: stream:: { DecodeOptions , DecodingError , FormatErrorInner , CHUNK_BUFFER_SIZE } ;
9
10
use self :: transform:: { create_transform_fn, TransformFn } ;
11
+ use self :: unfiltering_buffer:: UnfilteringBuffer ;
10
12
11
13
use std:: io:: Read ;
12
14
use std:: mem;
@@ -15,7 +17,6 @@ use crate::adam7::{self, Adam7Info};
15
17
use crate :: common:: {
16
18
BitDepth , BytesPerPixel , ColorType , Info , ParameterErrorKind , Transformations ,
17
19
} ;
18
- use crate :: filter:: { unfilter, FilterType } ;
19
20
use crate :: FrameControl ;
20
21
21
22
pub use interlace_info:: InterlaceInfo ;
@@ -192,9 +193,7 @@ impl<R: Read> Decoder<R> {
192
193
bpp : BytesPerPixel :: One ,
193
194
subframe : SubframeInfo :: not_yet_init ( ) ,
194
195
remaining_frames : 0 , // Temporary value - fixed below after reading `acTL` and `fcTL`.
195
- data_stream : Vec :: new ( ) ,
196
- prev_start : 0 ,
197
- current_start : 0 ,
196
+ unfiltering_buffer : UnfilteringBuffer :: new ( ) ,
198
197
transform : self . transform ,
199
198
transform_fn : None ,
200
199
scratch_buffer : Vec :: new ( ) ,
@@ -288,12 +287,8 @@ pub struct Reader<R: Read> {
288
287
subframe : SubframeInfo ,
289
288
/// How many frames remain to be decoded. Decremented after each `IDAT` or `fdAT` sequence.
290
289
remaining_frames : usize ,
291
- /// Vec containing the uncompressed image data currently being processed.
292
- data_stream : Vec < u8 > ,
293
- /// Index in `data_stream` where the previous row starts.
294
- prev_start : usize ,
295
- /// Index in `data_stream` where the current row starts.
296
- current_start : usize ,
290
+ /// Buffer with not-yet-`unfilter`-ed image rows
291
+ unfiltering_buffer : UnfilteringBuffer ,
297
292
/// Output transformations
298
293
transform : Transformations ,
299
294
/// Function that can transform decompressed, unfiltered rows into final output.
@@ -362,16 +357,12 @@ impl<R: Read> Reader<R> {
362
357
363
358
self . subframe = SubframeInfo :: new ( self . info ( ) ) ;
364
359
self . bpp = self . info ( ) . bpp_in_prediction ( ) ;
365
- self . data_stream . clear ( ) ;
366
- self . current_start = 0 ;
367
- self . prev_start = 0 ;
360
+ self . unfiltering_buffer = UnfilteringBuffer :: new ( ) ;
368
361
369
362
// Allocate output buffer.
370
363
let buflen = self . output_line_size ( self . subframe . width ) ;
371
364
self . decoder . reserve_bytes ( buflen) ?;
372
365
373
- self . prev_start = self . current_start ;
374
-
375
366
Ok ( ( ) )
376
367
}
377
368
@@ -499,7 +490,7 @@ impl<R: Read> Reader<R> {
499
490
Some ( interlace) => * interlace,
500
491
} ;
501
492
if interlace. line_number ( ) == 0 {
502
- self . prev_start = self . current_start ;
493
+ self . unfiltering_buffer . reset_prev_row ( ) ;
503
494
}
504
495
let rowlen = match interlace {
505
496
InterlaceInfo :: Null ( _) => self . subframe . rowlen ,
@@ -537,9 +528,7 @@ impl<R: Read> Reader<R> {
537
528
}
538
529
539
530
self . remaining_frames = 0 ;
540
- self . data_stream . clear ( ) ;
541
- self . current_start = 0 ;
542
- self . prev_start = 0 ;
531
+ self . unfiltering_buffer = UnfilteringBuffer :: new ( ) ;
543
532
self . decoder . read_until_end_of_input ( ) ?;
544
533
545
534
self . finished = true ;
@@ -553,8 +542,8 @@ impl<R: Read> Reader<R> {
553
542
output_buffer : & mut [ u8 ] ,
554
543
) -> Result < ( ) , DecodingError > {
555
544
self . next_raw_interlaced_row ( rowlen) ?;
556
- assert_eq ! ( self . current_start - self . prev_start , rowlen - 1 ) ;
557
- let row = & self . data_stream [ self . prev_start .. self . current_start ] ;
545
+ let row = self . unfiltering_buffer . prev_row ( ) ;
546
+ assert_eq ! ( row. len ( ) , rowlen - 1 ) ;
558
547
559
548
// Apply transformations and write resulting data to buffer.
560
549
let transform_fn = {
@@ -619,51 +608,26 @@ impl<R: Read> Reader<R> {
619
608
color. raw_row_length_from_width ( depth, width) - 1
620
609
}
621
610
622
- /// Write the next raw interlaced row into `self.prev`.
623
- ///
624
- /// The scanline is filtered against the previous scanline according to the specification.
611
+ /// Unfilter the next raw interlaced row into `self.unfiltering_buffer`.
625
612
fn next_raw_interlaced_row ( & mut self , rowlen : usize ) -> Result < ( ) , DecodingError > {
626
613
// Read image data until we have at least one full row (but possibly more than one).
627
- while self . data_stream . len ( ) - self . current_start < rowlen {
614
+ while self . unfiltering_buffer . curr_row_len ( ) < rowlen {
628
615
if self . subframe . consumed_and_flushed {
629
616
return Err ( DecodingError :: Format (
630
617
FormatErrorInner :: NoMoreImageData . into ( ) ,
631
618
) ) ;
632
619
}
633
620
634
- // Clear the current buffer before appending more data.
635
- if self . prev_start > 0 {
636
- self . data_stream . copy_within ( self . prev_start .., 0 ) ;
637
- self . data_stream
638
- . truncate ( self . data_stream . len ( ) - self . prev_start ) ;
639
- self . current_start -= self . prev_start ;
640
- self . prev_start = 0 ;
641
- }
642
-
643
- match self . decoder . decode_image_data ( & mut self . data_stream ) ? {
621
+ match self
622
+ . decoder
623
+ . decode_image_data ( self . unfiltering_buffer . as_mut_vec ( ) ) ?
624
+ {
644
625
ImageDataCompletionStatus :: ExpectingMoreData => ( ) ,
645
626
ImageDataCompletionStatus :: Done => self . mark_subframe_as_consumed_and_flushed ( ) ,
646
627
}
647
628
}
648
629
649
- // Get a reference to the current row and point scan_start to the next one.
650
- let ( prev, row) = self . data_stream . split_at_mut ( self . current_start ) ;
651
-
652
- // Unfilter the row.
653
- let filter = FilterType :: from_u8 ( row[ 0 ] ) . ok_or ( DecodingError :: Format (
654
- FormatErrorInner :: UnknownFilterMethod ( row[ 0 ] ) . into ( ) ,
655
- ) ) ?;
656
- unfilter (
657
- filter,
658
- self . bpp ,
659
- & prev[ self . prev_start ..] ,
660
- & mut row[ 1 ..rowlen] ,
661
- ) ;
662
-
663
- self . prev_start = self . current_start + 1 ;
664
- self . current_start += rowlen;
665
-
666
- Ok ( ( ) )
630
+ self . unfiltering_buffer . unfilter_curr_row ( rowlen, self . bpp )
667
631
}
668
632
}
669
633
0 commit comments