From 727c9b7710992a7c631d85299def16af9ec1502e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Wed, 5 Mar 2025 15:08:25 +0400 Subject: [PATCH] refactor(session): generalize apply_rgb24() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add an optional "flip" argument for inverting bitmaps. Signed-off-by: Marc-André Lureau --- crates/ironrdp-session/src/fast_path.rs | 2 +- crates/ironrdp-session/src/image.rs | 52 ++++++++++++++++--------- 2 files changed, 34 insertions(+), 20 deletions(-) diff --git a/crates/ironrdp-session/src/fast_path.rs b/crates/ironrdp-session/src/fast_path.rs index d0a25da0..59db1326 100644 --- a/crates/ironrdp-session/src/fast_path.rs +++ b/crates/ironrdp-session/src/fast_path.rs @@ -114,7 +114,7 @@ impl Processor { usize::from(update.width), usize::from(update.height), ) { - Ok(()) => image.apply_rgb24_bitmap(&buf, &update.rectangle)?, + Ok(()) => image.apply_rgb24(&buf, &update.rectangle, true)?, Err(err) => { warn!("Invalid RDP6_BITMAP_STREAM: {err}"); update.rectangle.clone() diff --git a/crates/ironrdp-session/src/image.rs b/crates/ironrdp-session/src/image.rs index 138b3dfb..a2c8c78e 100644 --- a/crates/ironrdp-session/src/image.rs +++ b/crates/ironrdp-session/src/image.rs @@ -570,43 +570,57 @@ impl DecodedImage { } // FIXME: this assumes PixelFormat::RgbA32 - pub(crate) fn apply_rgb24_bitmap( + fn apply_rgb24_iter<'a, I>( &mut self, - rgb24: &[u8], + rgb24: I, update_rectangle: &InclusiveRectangle, - ) -> SessionResult { + ) -> SessionResult + where + I: Iterator, + { const SRC_COLOR_DEPTH: usize = 3; const DST_COLOR_DEPTH: usize = 4; let image_width = self.width as usize; - let rectangle_width = usize::from(update_rectangle.width()); let top = usize::from(update_rectangle.top); let left = usize::from(update_rectangle.left); let pointer_rendering_state = self.pointer_rendering_begin(update_rectangle)?; - rgb24 - .chunks_exact(rectangle_width * SRC_COLOR_DEPTH) - .rev() - .enumerate() - .for_each(|(row_idx, row)| { - row.chunks_exact(SRC_COLOR_DEPTH) - .enumerate() - .for_each(|(col_idx, src_pixel)| { - let dst_idx = ((top + row_idx) * image_width + left + col_idx) * DST_COLOR_DEPTH; + rgb24.enumerate().for_each(|(row_idx, row)| { + row.chunks_exact(SRC_COLOR_DEPTH) + .enumerate() + .for_each(|(col_idx, src_pixel)| { + let dst_idx = ((top + row_idx) * image_width + left + col_idx) * DST_COLOR_DEPTH; - // Copy RGB channels as is - self.data[dst_idx..dst_idx + SRC_COLOR_DEPTH].copy_from_slice(src_pixel); - // Set alpha channel to opaque(0xFF) - self.data[dst_idx + 3] = 0xFF; - }) - }); + // Copy RGB channels as is + self.data[dst_idx..dst_idx + SRC_COLOR_DEPTH].copy_from_slice(src_pixel); + // Set alpha channel to opaque(0xFF) + self.data[dst_idx + 3] = 0xFF; + }) + }); let update_rectangle = self.pointer_rendering_end(pointer_rendering_state)?; Ok(update_rectangle) } + pub(crate) fn apply_rgb24( + &mut self, + rgb24: &[u8], + update_rectangle: &InclusiveRectangle, + flip: bool, + ) -> SessionResult { + const SRC_COLOR_DEPTH: usize = 3; + let rectangle_width = usize::from(update_rectangle.width()); + let lines = rgb24.chunks_exact(rectangle_width * SRC_COLOR_DEPTH); + if flip { + self.apply_rgb24_iter(lines.rev(), update_rectangle) + } else { + self.apply_rgb24_iter(lines, update_rectangle) + } + } + // FIXME: this assumes PixelFormat::RgbA32 pub(crate) fn apply_rgb32_bitmap( &mut self,