ironrdp_pdu/rdp/capability_sets/
bitmap.rs1#[cfg(test)]
2mod tests;
3
4use bitflags::bitflags;
5use ironrdp_core::{
6 ensure_fixed_part_size, invalid_field_err, read_padding, write_padding, Decode, DecodeResult, Encode, EncodeResult,
7 ReadCursor, WriteCursor,
8};
9
10const BITMAP_LENGTH: usize = 24;
11
12bitflags! {
13 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
14 pub struct BitmapDrawingFlags: u8 {
15 const ALLOW_DYNAMIC_COLOR_FIDELITY = 0x02;
16 const ALLOW_COLOR_SUBSAMPLING = 0x04;
17 const ALLOW_SKIP_ALPHA = 0x08;
18 const UNUSED_FLAG = 0x10;
19 }
20}
21
22#[derive(Debug, PartialEq, Eq, Clone)]
23pub struct Bitmap {
24 pub pref_bits_per_pix: u16,
25 pub desktop_width: u16,
26 pub desktop_height: u16,
27 pub desktop_resize_flag: bool,
28 pub drawing_flags: BitmapDrawingFlags,
29}
30
31impl Bitmap {
32 const NAME: &'static str = "Bitmap";
33
34 const FIXED_PART_SIZE: usize = BITMAP_LENGTH;
35}
36
37impl Encode for Bitmap {
38 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
39 ensure_fixed_part_size!(in: dst);
40
41 dst.write_u16(self.pref_bits_per_pix);
42 dst.write_u16(1); dst.write_u16(1); dst.write_u16(1); dst.write_u16(self.desktop_width);
46 dst.write_u16(self.desktop_height);
47 write_padding!(dst, 2);
48 dst.write_u16(u16::from(self.desktop_resize_flag));
49 dst.write_u16(1); dst.write_u8(0); dst.write_u8(self.drawing_flags.bits());
52 dst.write_u16(1); write_padding!(dst, 2);
54
55 Ok(())
56 }
57
58 fn name(&self) -> &'static str {
59 Self::NAME
60 }
61
62 fn size(&self) -> usize {
63 Self::FIXED_PART_SIZE
64 }
65}
66
67impl<'de> Decode<'de> for Bitmap {
68 fn decode(src: &mut ReadCursor<'de>) -> DecodeResult<Self> {
69 ensure_fixed_part_size!(in: src);
70
71 let pref_bits_per_pix = src.read_u16();
72
73 let _receive_1_bit_per_pixel = src.read_u16() != 0;
74 let _receive_4_bit_per_pixel = src.read_u16() != 0;
75 let _receive_8_bit_per_pixel = src.read_u16() != 0;
76 let desktop_width = src.read_u16();
77 let desktop_height = src.read_u16();
78 read_padding!(src, 2);
79 let desktop_resize_flag = src.read_u16() != 0;
80
81 let is_bitmap_compress_flag_set = src.read_u16() != 0;
82 if !is_bitmap_compress_flag_set {
83 return Err(invalid_field_err!(
84 "isBitmapCompressFlagSet",
85 "invalid compression flag"
86 ));
87 }
88
89 let _high_color_flags = src.read_u8();
90 let drawing_flags = BitmapDrawingFlags::from_bits_truncate(src.read_u8());
91
92 let _ = src.read_u16();
97
98 read_padding!(src, 2);
99
100 Ok(Bitmap {
101 pref_bits_per_pix,
102 desktop_width,
103 desktop_height,
104 desktop_resize_flag,
105 drawing_flags,
106 })
107 }
108}