2828 RawDataSlice < ' a , R , LittleEndian > : IntoIterator < Item = R > ,
2929{
3030 /// Create a new raw color iterator.
31- pub fn new ( raw_bmp : & ' a RawBmp < ' a > ) -> Self {
31+ pub ( crate ) fn new ( raw_bmp : & ' a RawBmp < ' a > ) -> Self {
3232 let header = raw_bmp. header ( ) ;
3333
3434 let width = header. image_size . width as usize ;
@@ -62,24 +62,25 @@ where
6262 }
6363}
6464
65- /// Iterator over dynamic color. Positions are dependent on the row order.
66- #[ allow( missing_debug_implementations) ]
65+ /// Iterator over the raw colors in the image.
66+ ///
67+ /// See [`RawBmp::colors`](RawBmp::colors) for more information.
6768pub enum DynamicRawColors < ' a > {
6869 /// 1 bit per pixel
6970 Bpp1 ( RawColors < ' a , RawU1 > ) ,
70- /// 4 bit per pixel
71+ /// 4 bits per pixel
7172 Bpp4 ( RawColors < ' a , RawU4 > ) ,
72- /// 8 bit per pixel
73+ /// 8 bits per pixel
7374 Bpp8 ( RawColors < ' a , RawU8 > ) ,
74- /// 16 bit per pixel
75+ /// 16 bits per pixel
7576 Bpp16 ( RawColors < ' a , RawU16 > ) ,
76- /// 24 bit per pixel
77+ /// 24 bits per pixel
7778 Bpp24 ( RawColors < ' a , RawU24 > ) ,
78- /// 32 bit per pixel
79+ /// 32 bits per pixel
7980 Bpp32 ( RawColors < ' a , RawU32 > ) ,
80- /// 4 bit per pixel RLE encoded
81+ /// RLE encoded with 4 bits per pixel
8182 Bpp4Rle ( Rle4Colors < ' a > ) ,
82- /// 8 bit per pixel RLE encoded
83+ /// RLE encoded with 8 bits per pixel
8384 Bpp8Rle ( Rle8Colors < ' a > ) ,
8485}
8586
@@ -102,13 +103,14 @@ impl DynamicRawColors<'_> {
102103 /// Get the row order of the bitmap.
103104 pub fn row_order ( & self ) -> RowOrder {
104105 match self {
105- DynamicRawColors :: Bpp1 ( _)
106- | DynamicRawColors :: Bpp4 ( _)
107- | DynamicRawColors :: Bpp8 ( _)
108- | DynamicRawColors :: Bpp16 ( _)
109- | DynamicRawColors :: Bpp24 ( _)
110- | DynamicRawColors :: Bpp32 ( _) => RowOrder :: TopDown ,
111- DynamicRawColors :: Bpp4Rle ( _) | DynamicRawColors :: Bpp8Rle ( _) => RowOrder :: BottomUp ,
106+ DynamicRawColors :: Bpp1 ( colors) => colors. row_order ,
107+ DynamicRawColors :: Bpp4 ( colors) => colors. row_order ,
108+ DynamicRawColors :: Bpp8 ( colors) => colors. row_order ,
109+ DynamicRawColors :: Bpp16 ( colors) => colors. row_order ,
110+ DynamicRawColors :: Bpp24 ( colors) => colors. row_order ,
111+ DynamicRawColors :: Bpp32 ( colors) => colors. row_order ,
112+ DynamicRawColors :: Bpp4Rle ( _) => RowOrder :: BottomUp ,
113+ DynamicRawColors :: Bpp8Rle ( _) => RowOrder :: BottomUp ,
112114 }
113115 }
114116}
@@ -124,8 +126,8 @@ impl Iterator for DynamicRawColors<'_> {
124126 DynamicRawColors :: Bpp16 ( colors) => colors. next ( ) . map ( |r| u32:: from ( r. into_inner ( ) ) ) ,
125127 DynamicRawColors :: Bpp24 ( colors) => colors. next ( ) . map ( |r| r. into_inner ( ) ) ,
126128 DynamicRawColors :: Bpp32 ( colors) => colors. next ( ) . map ( |r| r. into_inner ( ) ) ,
127- DynamicRawColors :: Bpp4Rle ( state ) => state . next ( ) . map ( |r| u32:: from ( r. into_inner ( ) ) ) ,
128- DynamicRawColors :: Bpp8Rle ( state ) => state . next ( ) . map ( |r| u32:: from ( r. into_inner ( ) ) ) ,
129+ DynamicRawColors :: Bpp4Rle ( colors ) => colors . next ( ) . map ( |r| u32:: from ( r. into_inner ( ) ) ) ,
130+ DynamicRawColors :: Bpp8Rle ( colors ) => colors . next ( ) . map ( |r| u32:: from ( r. into_inner ( ) ) ) ,
129131 }
130132 }
131133}
@@ -152,66 +154,72 @@ enum RleState {
152154}
153155
154156pub struct PixelPoints {
155- /// The location of the next pixel
157+ /// The location of the next pixel.
156158 next_pixel : Point ,
157- /// The width of a line in pixels
159+ /// The number of pixels in a row.
158160 width : u32 ,
159- }
160-
161- /// Iterator over individual BMP RLE8 encoded pixels.
162- ///
163- /// Each pixel is returned as a `u32` regardless of the bit depth of the source image.
164- #[ derive( Debug ) ]
165- pub struct Rle8Colors < ' a > {
166- /// Our source data
167- data : & ' a [ u8 ] ,
168- /// Our state
169- rle_state : RleState ,
170- start_of_line : bool ,
161+ /// Delta for row movement. It is negative to ensure proper saturation behavior.
162+ neg_delta_y : i32 ,
171163}
172164
173165impl PixelPoints {
174- fn next_up_dir ( & mut self ) -> Point {
175- let old_position = self . next_pixel ;
176- self . next_pixel . x += 1 ;
177- if self . next_pixel . x == self . width as i32 {
178- self . next_pixel . x = 0 ;
179- self . next_pixel . y = self . next_pixel . y . saturating_sub ( 1 ) ;
166+ pub ( crate ) fn new ( image_size : Size , row_order : RowOrder ) -> Self {
167+ let next_pixel = match row_order {
168+ RowOrder :: TopDown => Point :: new ( 0 , 0 ) ,
169+ RowOrder :: BottomUp => Point :: new ( 0 , ( image_size. height - 1 ) as i32 ) ,
170+ } ;
171+ let neg_delta_y = match row_order {
172+ RowOrder :: TopDown => -1 ,
173+ RowOrder :: BottomUp => 1 ,
174+ } ;
175+ Self {
176+ next_pixel,
177+ width : image_size. width ,
178+ neg_delta_y,
180179 }
181- old_position
182180 }
181+ }
183182
184- fn next_down_dir ( & mut self ) -> Point {
183+ impl Iterator for PixelPoints {
184+ type Item = Point ;
185+ fn next ( & mut self ) -> Option < Self :: Item > {
185186 let old_position = self . next_pixel ;
186187 self . next_pixel . x += 1 ;
187188 if self . next_pixel . x == self . width as i32 {
188189 self . next_pixel . x = 0 ;
189- self . next_pixel . y += 1 ;
190+ // When moving BottomUp, we will not move past y=0
191+ // When moving TopDown, we will just increment y
192+ self . next_pixel . y = self . next_pixel . y . saturating_sub ( self . neg_delta_y ) ;
190193 }
191- old_position
194+ Some ( old_position)
192195 }
193196}
194197
198+ /// Iterator over individual BMP RLE8 encoded pixels.
199+ ///
200+ /// Each pixel is returned as a `u32` regardless of the bit depth of the source image.
201+ #[ derive( Debug ) ]
202+ pub struct Rle8Colors < ' a > {
203+ /// Our source data
204+ data : & ' a [ u8 ] ,
205+ /// Our state
206+ rle_state : RleState ,
207+ start_of_row : bool ,
208+ }
209+
195210impl < ' a > Rle8Colors < ' a > {
196211 /// Create a new RLE pixel iterator.
197- pub ( crate ) fn new ( raw_bmp : & RawBmp < ' a > ) -> ( Rle8Colors < ' a > , PixelPoints ) {
198- let header = raw_bmp. header ( ) ;
199- let points = PixelPoints {
200- width : header. image_size . width ,
201- // RLE encoded bitmaps are upside down
202- next_pixel : Point :: new ( 0 , ( header. image_size . height - 1 ) as i32 ) ,
203- } ;
204- let this = Rle8Colors {
212+ pub ( crate ) fn new ( raw_bmp : & RawBmp < ' a > ) -> Rle8Colors < ' a > {
213+ Rle8Colors {
205214 data : raw_bmp. image_data ( ) ,
206215 rle_state : RleState :: Starting ,
207- start_of_line : false ,
208- } ;
209- ( this, points)
216+ start_of_row : false ,
217+ }
210218 }
211219
212220 /// Indicate that a new line is starting. Required for correct RLE decoding.
213- pub fn start_a_line ( & mut self ) {
214- self . start_of_line = true ;
221+ pub fn start_row ( & mut self ) {
222+ self . start_of_row = true ;
215223 }
216224}
217225
@@ -276,7 +284,7 @@ impl<'a> Iterator for Rle8Colors<'a> {
276284 // the pair, which can be one of the following values.
277285 match param {
278286 0 => {
279- if !self . start_of_line {
287+ if !self . start_of_row {
280288 return None ;
281289 }
282290 }
@@ -323,29 +331,22 @@ pub struct Rle4Colors<'a> {
323331 data : & ' a [ u8 ] ,
324332 /// Our state
325333 rle_state : RleState ,
326- start_of_line : bool ,
334+ start_of_row : bool ,
327335}
328336
329337impl < ' a > Rle4Colors < ' a > {
330338 /// Create a new RLE pixel iterator.
331- pub ( crate ) fn new ( raw_bmp : & RawBmp < ' a > ) -> ( Rle4Colors < ' a > , PixelPoints ) {
332- let header = raw_bmp. header ( ) ;
333- let points = PixelPoints {
334- width : header. image_size . width ,
335- // RLE encoded bitmaps are upside down
336- next_pixel : Point :: new ( 0 , ( header. image_size . height - 1 ) as i32 ) ,
337- } ;
338- let this = Rle4Colors {
339+ pub ( crate ) fn new ( raw_bmp : & RawBmp < ' a > ) -> Rle4Colors < ' a > {
340+ Rle4Colors {
339341 data : raw_bmp. image_data ( ) ,
340342 rle_state : RleState :: Starting ,
341- start_of_line : false ,
342- } ;
343- ( this, points)
343+ start_of_row : false ,
344+ }
344345 }
345346
346347 /// Indicate that a new line is starting. Required for correct RLE decoding.
347- pub fn start_a_line ( & mut self ) {
348- self . start_of_line = true ;
348+ pub fn start_row ( & mut self ) {
349+ self . start_of_row = true ;
349350 }
350351}
351352
@@ -449,7 +450,7 @@ impl<'a> Iterator for Rle4Colors<'a> {
449450 // the pair, which can be one of the following values.
450451 match param {
451452 0 => {
452- if !self . start_of_line {
453+ if !self . start_of_row {
453454 return None ;
454455 }
455456 }
@@ -502,24 +503,23 @@ impl<'a> RawPixels<'a> {
502503 let header = raw_bmp. header ( ) ;
503504 match header. compression_method {
504505 CompressionMethod :: Rle4 => {
505- let ( colors, points) = Rle4Colors :: new ( raw_bmp) ;
506+ let colors = Rle4Colors :: new ( raw_bmp) ;
507+ let points = PixelPoints :: new ( header. image_size , RowOrder :: BottomUp ) ;
506508 Self {
507509 colors : DynamicRawColors :: Bpp4Rle ( colors) ,
508510 points,
509511 }
510512 }
511513 CompressionMethod :: Rle8 => {
512- let ( colors, points) = Rle8Colors :: new ( raw_bmp) ;
514+ let colors = Rle8Colors :: new ( raw_bmp) ;
515+ let points = PixelPoints :: new ( header. image_size , RowOrder :: BottomUp ) ;
513516 Self {
514517 colors : DynamicRawColors :: Bpp8Rle ( colors) ,
515518 points,
516519 }
517520 }
518521 CompressionMethod :: Rgb | CompressionMethod :: Bitfields => {
519- let points = PixelPoints {
520- width : header. image_size . width ,
521- next_pixel : Point :: zero ( ) ,
522- } ;
522+ let points = PixelPoints :: new ( header. image_size , header. row_order ) ;
523523 let colors = match header. bpp {
524524 Bpp :: Bits1 => DynamicRawColors :: Bpp1 ( RawColors :: new ( raw_bmp) ) ,
525525 Bpp :: Bits4 => DynamicRawColors :: Bpp4 ( RawColors :: new ( raw_bmp) ) ,
@@ -539,11 +539,7 @@ impl Iterator for RawPixels<'_> {
539539
540540 fn next ( & mut self ) -> Option < Self :: Item > {
541541 let color = self . colors . next ( ) ?;
542- let position = match self . colors . row_order ( ) {
543- RowOrder :: TopDown => self . points . next_down_dir ( ) ,
544- RowOrder :: BottomUp => self . points . next_up_dir ( ) ,
545- } ;
546-
542+ let position = self . points . next ( ) ?;
547543 Some ( RawPixel { position, color } )
548544 }
549545}
0 commit comments