diff --git a/crates/ironrdp-server/src/display.rs b/crates/ironrdp-server/src/display.rs index e37a634f..b64e3e09 100644 --- a/crates/ironrdp-server/src/display.rs +++ b/crates/ironrdp-server/src/display.rs @@ -75,6 +75,7 @@ pub struct BitmapUpdate { pub format: PixelFormat, pub order: PixelOrder, pub data: Vec, + pub stride: usize, } impl std::fmt::Debug for BitmapUpdate { diff --git a/crates/ironrdp-server/src/encoder/mod.rs b/crates/ironrdp-server/src/encoder/mod.rs index 671b49dc..a8b6eb68 100644 --- a/crates/ironrdp-server/src/encoder/mod.rs +++ b/crates/ironrdp-server/src/encoder/mod.rs @@ -182,13 +182,23 @@ impl UpdateEncoder { } fn none_update(&mut self, mut bitmap: BitmapUpdate) -> Result> { + let stride = usize::from(bitmap.format.bytes_per_pixel()) * usize::from(bitmap.width.get()); let data = match bitmap.order { - PixelOrder::BottomToTop => mem::take(&mut bitmap.data), + PixelOrder::BottomToTop => { + if stride == bitmap.stride { + mem::take(&mut bitmap.data) + } else { + let mut data = Vec::with_capacity(stride * usize::from(bitmap.height.get())); + for row in bitmap.data.chunks(bitmap.stride) { + data.extend_from_slice(&row[..stride]); + } + data + } + } PixelOrder::TopToBottom => { - let row_len = usize::from(bitmap.width.get()) * usize::from(bitmap.format.bytes_per_pixel()); - let mut data = Vec::with_capacity(bitmap.data.len()); - for row in bitmap.data.chunks(row_len).rev() { - data.extend_from_slice(row); + let mut data = Vec::with_capacity(stride * usize::from(bitmap.height.get())); + for row in bitmap.data.chunks(bitmap.stride).rev() { + data.extend_from_slice(&row[..stride]); } data } diff --git a/crates/ironrdp-server/src/encoder/rfx.rs b/crates/ironrdp-server/src/encoder/rfx.rs index d744c69b..b09ee8c9 100644 --- a/crates/ironrdp-server/src/encoder/rfx.rs +++ b/crates/ironrdp-server/src/encoder/rfx.rs @@ -61,7 +61,6 @@ impl RfxEncoder { let bpp = usize::from(bitmap.format.bytes_per_pixel()); let width = usize::from(bitmap.width.get()); let height = usize::from(bitmap.height.get()); - let stride = width * bpp; let tiles_x = (width + 63) / 64; let tiles_y = (height + 63) / 64; @@ -77,12 +76,12 @@ impl RfxEncoder { let tile_width = std::cmp::min(width - x, 64); let tile_height = std::cmp::min(height - y, 64); - let input = &bitmap.data[y * stride + x * bpp..]; + let input = &bitmap.data[y * bitmap.stride + x * bpp..]; let y = &mut [0i16; 4096]; let cb = &mut [0i16; 4096]; let cr = &mut [0i16; 4096]; - to_64x64_ycbcr_tile(input, tile_width, tile_height, stride, bitmap.format, y, cb, cr); + to_64x64_ycbcr_tile(input, tile_width, tile_height, bitmap.stride, bitmap.format, y, cb, cr); let (y_data, new_rest) = rest.split_at_mut(4096); let (cb_data, new_rest) = new_rest.split_at_mut(4096); diff --git a/crates/ironrdp/examples/server.rs b/crates/ironrdp/examples/server.rs index 87863f49..29e9d1d1 100644 --- a/crates/ironrdp/examples/server.rs +++ b/crates/ironrdp/examples/server.rs @@ -182,6 +182,7 @@ impl RdpServerDisplayUpdates for DisplayUpdates { format: PixelFormat::BgrA32, order: PixelOrder::TopToBottom, data, + stride: usize::from(width.get()).checked_mul(4).unwrap(), }; Some(DisplayUpdate::Bitmap(bitmap)) }