@@ -79,9 +79,9 @@ pub enum DynamicRawColors<'a> {
7979 /// 32 bits per pixel
8080 Bpp32 ( RawColors < ' a , RawU32 > ) ,
8181 /// RLE encoded with 4 bits per pixel
82- Bpp4Rle ( Rle4Colors < ' a > ) ,
82+ Bpp4Rle ( RleColors < RawU4 , Rle4Runs < ' a > > ) ,
8383 /// RLE encoded with 8 bits per pixel
84- Bpp8Rle ( Rle8Colors < ' a > ) ,
84+ Bpp8Rle ( RleColors < RawU8 , Rle8Runs < ' a > > ) ,
8585}
8686
8787impl core:: fmt:: Debug for DynamicRawColors < ' _ > {
@@ -193,22 +193,59 @@ impl Iterator for PixelPoints {
193193 }
194194}
195195
196- /// Iterator over individual BMP RLE8 encoded pixels.
197- ///
198- /// Each pixel is returned as a `u32` regardless of the bit depth of the source image.
196+ /// Iterator over individual BMP RLE encoded pixels.
199197#[ derive( Debug ) ]
200- pub struct Rle8Colors < ' a > {
201- /// Our source data
198+ pub struct RleColors < C , I : Iterator < Item = ( C , usize ) > > {
199+ runs : I ,
200+ run : Option < ( C , usize ) > ,
201+ }
202+
203+ impl < C , I : Iterator < Item = ( C , usize ) > > RleColors < C , I > {
204+ /// Create a new RLE pixel iterator.
205+ pub ( crate ) fn new ( runs : I ) -> Self {
206+ Self { runs, run : None }
207+ }
208+
209+ /// Get a mutable reference to the underlying runs iterator.
210+ pub fn runs ( & mut self ) -> & mut I {
211+ & mut self . runs
212+ }
213+ }
214+
215+ impl < C : Copy , I : Iterator < Item = ( C , usize ) > > Iterator for RleColors < C , I > {
216+ type Item = C ;
217+
218+ fn next ( & mut self ) -> Option < Self :: Item > {
219+ loop {
220+ let ( raw, count) = match self . run . as_mut ( ) {
221+ Some ( run) => run,
222+ None => {
223+ self . run = Some ( self . runs . next ( ) ?) ;
224+ self . run . as_mut ( ) . unwrap ( )
225+ }
226+ } ;
227+ if * count > 0 {
228+ * count -= 1 ;
229+ return Some ( * raw) ;
230+ } else {
231+ self . run = None ;
232+ }
233+ }
234+ }
235+ }
236+
237+ /// Iterator over BMP RLE8 runs.
238+ #[ derive( Debug ) ]
239+ pub struct Rle8Runs < ' a > {
202240 data : & ' a [ u8 ] ,
203- /// Our state
204241 rle_state : RleState ,
205242 start_of_row : bool ,
206243}
207244
208- impl < ' a > Rle8Colors < ' a > {
245+ impl < ' a > Rle8Runs < ' a > {
209246 /// Create a new RLE pixel iterator.
210- pub ( crate ) fn new ( raw_bmp : & RawBmp < ' a > ) -> Rle8Colors < ' a > {
211- Rle8Colors {
247+ pub ( crate ) fn new ( raw_bmp : & RawBmp < ' a > ) -> Rle8Runs < ' a > {
248+ Rle8Runs {
212249 data : raw_bmp. image_data ( ) ,
213250 rle_state : RleState :: Starting ,
214251 start_of_row : false ,
@@ -221,15 +258,14 @@ impl<'a> Rle8Colors<'a> {
221258 }
222259}
223260
224- impl < ' a > Iterator for Rle8Colors < ' a > {
225- type Item = RawU8 ;
261+ impl Iterator for Rle8Runs < ' _ > {
262+ type Item = ( RawU8 , usize ) ;
226263
227264 fn next ( & mut self ) -> Option < Self :: Item > {
228265 loop {
229266 match self . rle_state {
230- RleState :: EndOfBitmap => {
231- return None ;
232- }
267+ RleState :: EndOfBitmap => return None ,
268+
233269 RleState :: Absolute {
234270 remaining,
235271 is_odd,
@@ -250,28 +286,25 @@ impl<'a> Iterator for Rle8Colors<'a> {
250286 } else {
251287 self . data = self . data . get ( 1 ..) ?;
252288 }
253- return Some ( RawU8 :: from ( value) ) ;
289+ return Some ( ( RawU8 :: from ( value) , 1 ) ) ;
254290 }
255291 RleState :: Running {
256292 remaining,
257293 value,
258- is_odd,
294+ is_odd : _ ,
259295 } => {
260- if remaining == 0 {
261- self . rle_state = RleState :: Starting ;
262- } else {
263- self . rle_state = RleState :: Running {
264- remaining : remaining. saturating_sub ( 1 ) ,
265- value,
266- is_odd,
267- } ;
268- }
269- return Some ( RawU8 :: from ( value) ) ;
296+ // total pixels represented by this run
297+ let total_pixels = ( remaining as usize ) + 1 ;
298+
299+ // consume whole run
300+ self . rle_state = RleState :: Starting ;
301+
302+ return Some ( ( RawU8 :: from ( value) , total_pixels) ) ;
270303 }
304+
271305 RleState :: Starting => {
272- let length = * self . data . get ( 0 ) ?;
273- let param = * self . data . get ( 1 ) ?;
274- self . data = & self . data . get ( 2 ..) ?;
306+ let ( & [ length, param] , rest) = self . data . split_first_chunk ( ) ?;
307+ self . data = rest;
275308 match length {
276309 0 => {
277310 // The first byte of the pair can be set to zero to
@@ -320,22 +353,20 @@ impl<'a> Iterator for Rle8Colors<'a> {
320353 }
321354}
322355
323- /// Iterator over individual BMP RLE4 encoded pixels.
324- ///
325- /// Each pixel is returned as a `u32` regardless of the bit depth of the source image.
356+ /// Iterator over BMP RLE4 runs.
326357#[ derive( Debug ) ]
327- pub struct Rle4Colors < ' a > {
358+ pub struct Rle4Runs < ' a > {
328359 /// Our source data
329360 data : & ' a [ u8 ] ,
330361 /// Our state
331362 rle_state : RleState ,
332363 start_of_row : bool ,
333364}
334365
335- impl < ' a > Rle4Colors < ' a > {
366+ impl < ' a > Rle4Runs < ' a > {
336367 /// Create a new RLE pixel iterator.
337- pub ( crate ) fn new ( raw_bmp : & RawBmp < ' a > ) -> Rle4Colors < ' a > {
338- Rle4Colors {
368+ pub ( crate ) fn new ( raw_bmp : & RawBmp < ' a > ) -> Rle4Runs < ' a > {
369+ Rle4Runs {
339370 data : raw_bmp. image_data ( ) ,
340371 rle_state : RleState :: Starting ,
341372 start_of_row : false ,
@@ -348,15 +379,13 @@ impl<'a> Rle4Colors<'a> {
348379 }
349380}
350381
351- impl < ' a > Iterator for Rle4Colors < ' a > {
352- type Item = RawU4 ;
382+ impl < ' a > Iterator for Rle4Runs < ' a > {
383+ type Item = ( RawU4 , usize ) ;
353384
354385 fn next ( & mut self ) -> Option < Self :: Item > {
355386 loop {
356387 match self . rle_state {
357- RleState :: EndOfBitmap => {
358- return None ;
359- }
388+ RleState :: EndOfBitmap => return None ,
360389 RleState :: Absolute {
361390 remaining,
362391 is_odd,
@@ -398,7 +427,8 @@ impl<'a> Iterator for Rle4Colors<'a> {
398427 // remove the padding byte too
399428 self . data = self . data . get ( 1 ..) ?;
400429 }
401- return Some ( RawU4 :: from ( nibble_value) ) ;
430+
431+ return Some ( ( RawU4 :: from ( nibble_value) , 1 ) ) ;
402432 }
403433 RleState :: Running {
404434 remaining,
@@ -417,27 +447,38 @@ impl<'a> Iterator for Rle4Colors<'a> {
417447 // | +-- remaining is 2, is_odd is 0, we want right
418448 // +-- remaining is 3, is_odd is 0, we want left
419449
450+ // determine which nibble we should return next (same logic as in Iterator::next)
420451 let remaining_is_odd = ( remaining % 2 ) != 0 ;
421452 let want_left = remaining_is_odd != is_odd;
422-
423453 let nibble_value = if want_left { value >> 4 } else { value & 0x0F } ;
424454
425- if remaining == 0 {
455+ // total pixels represented by this run
456+ let total_pixels = ( remaining as usize ) + 1 ;
457+
458+ let hi = value >> 4 ;
459+ let lo = value & 0x0F ;
460+
461+ if hi == lo {
462+ // entire run is a single repeated nibble -> consume whole run
426463 self . rle_state = RleState :: Starting ;
464+ return Some ( ( RawU4 :: from ( nibble_value) , total_pixels) ) ;
427465 } else {
428- self . rle_state = RleState :: Running {
429- remaining : remaining. saturating_sub ( 1 ) ,
430- value,
431- is_odd,
432- } ;
466+ // alternating pattern -> only one pixel of this color now
467+ if remaining == 0 {
468+ self . rle_state = RleState :: Starting ;
469+ } else {
470+ self . rle_state = RleState :: Running {
471+ remaining : remaining. saturating_sub ( 1 ) ,
472+ value,
473+ is_odd,
474+ } ;
475+ }
476+ return Some ( ( RawU4 :: from ( nibble_value) , 1 ) ) ;
433477 }
434-
435- return Some ( RawU4 :: from ( nibble_value) ) ;
436478 }
437479 RleState :: Starting => {
438- let length = * self . data . get ( 0 ) ?;
439- let param = * self . data . get ( 1 ) ?;
440- self . data = & self . data . get ( 2 ..) ?;
480+ let ( & [ length, param] , rest) = self . data . split_first_chunk ( ) ?;
481+ self . data = rest;
441482 match length {
442483 0 => {
443484 // The first byte of the pair can be set to zero to
@@ -452,10 +493,8 @@ impl<'a> Iterator for Rle4Colors<'a> {
452493 return None ;
453494 }
454495 }
455- 1 => {
456- // End of bitmap
457- self . rle_state = RleState :: EndOfBitmap ;
458- }
496+ // End of bitmap
497+ 1 => self . rle_state = RleState :: EndOfBitmap ,
459498 2 => {
460499 // Delta encoding is unsupported.
461500 return None ;
@@ -501,15 +540,17 @@ impl<'a> RawPixels<'a> {
501540 let header = raw_bmp. header ( ) ;
502541 match header. compression_method {
503542 CompressionMethod :: Rle4 => {
504- let colors = Rle4Colors :: new ( raw_bmp) ;
543+ let runs = Rle4Runs :: new ( raw_bmp) ;
544+ let colors = RleColors :: new ( runs) ;
505545 let points = PixelPoints :: new ( header. image_size , RowOrder :: BottomUp ) ;
506546 Self {
507547 colors : DynamicRawColors :: Bpp4Rle ( colors) ,
508548 points,
509549 }
510550 }
511551 CompressionMethod :: Rle8 => {
512- let colors = Rle8Colors :: new ( raw_bmp) ;
552+ let runs = Rle8Runs :: new ( raw_bmp) ;
553+ let colors = RleColors :: new ( runs) ;
513554 let points = PixelPoints :: new ( header. image_size , RowOrder :: BottomUp ) ;
514555 Self {
515556 colors : DynamicRawColors :: Bpp8Rle ( colors) ,
0 commit comments