dicom_toolkit_codec/jpeg_ls/
sample.rs1pub trait Sample:
8 Copy + Clone + Default + Into<i32> + std::fmt::Debug + Send + Sync + 'static
9{
10 const MAX_VAL_DEFAULT: i32;
12
13 const BYTES: usize;
15
16 fn from_i32_clamped(val: i32, max_val: i32) -> Self;
18
19 fn read_le(data: &[u8], offset: usize) -> Self;
21
22 fn write_le(data: &mut [u8], offset: usize, val: Self);
24}
25
26impl Sample for u8 {
27 const MAX_VAL_DEFAULT: i32 = 255;
28 const BYTES: usize = 1;
29
30 #[inline]
31 fn from_i32_clamped(val: i32, max_val: i32) -> Self {
32 val.max(0).min(max_val) as u8
33 }
34
35 #[inline]
36 fn read_le(data: &[u8], offset: usize) -> Self {
37 data[offset]
38 }
39
40 #[inline]
41 fn write_le(data: &mut [u8], offset: usize, val: Self) {
42 data[offset] = val;
43 }
44}
45
46impl Sample for u16 {
47 const MAX_VAL_DEFAULT: i32 = 65535;
48 const BYTES: usize = 2;
49
50 #[inline]
51 fn from_i32_clamped(val: i32, max_val: i32) -> Self {
52 val.max(0).min(max_val) as u16
53 }
54
55 #[inline]
56 fn read_le(data: &[u8], offset: usize) -> Self {
57 let lo = data[offset] as u16;
58 let hi = data[offset + 1] as u16;
59 lo | (hi << 8)
60 }
61
62 #[inline]
63 fn write_le(data: &mut [u8], offset: usize, val: Self) {
64 data[offset] = val as u8;
65 data[offset + 1] = (val >> 8) as u8;
66 }
67}
68
69pub fn needs_u16(bits_per_sample: u8) -> bool {
71 bits_per_sample > 8
72}
73
74#[cfg(test)]
77mod tests {
78 use super::*;
79
80 #[test]
81 fn u8_sample_basics() {
82 assert_eq!(u8::MAX_VAL_DEFAULT, 255);
83 assert_eq!(u8::BYTES, 1);
84 assert_eq!(u8::from_i32_clamped(100, 255), 100u8);
85 assert_eq!(u8::from_i32_clamped(300, 255), 255u8);
86 assert_eq!(u8::from_i32_clamped(-5, 255), 0u8);
87 }
88
89 #[test]
90 fn u16_sample_basics() {
91 assert_eq!(u16::MAX_VAL_DEFAULT, 65535);
92 assert_eq!(u16::BYTES, 2);
93 assert_eq!(u16::from_i32_clamped(1000, 4095), 1000u16);
94 assert_eq!(u16::from_i32_clamped(5000, 4095), 4095u16);
95 assert_eq!(u16::from_i32_clamped(-1, 4095), 0u16);
96 }
97
98 #[test]
99 fn u8_read_write_le() {
100 let mut buf = [0u8; 4];
101 u8::write_le(&mut buf, 0, 42);
102 u8::write_le(&mut buf, 1, 255);
103 assert_eq!(u8::read_le(&buf, 0), 42);
104 assert_eq!(u8::read_le(&buf, 1), 255);
105 }
106
107 #[test]
108 fn u16_read_write_le() {
109 let mut buf = [0u8; 8];
110 u16::write_le(&mut buf, 0, 0x1234);
111 u16::write_le(&mut buf, 2, 0xABCD);
112 assert_eq!(u16::read_le(&buf, 0), 0x1234);
113 assert_eq!(u16::read_le(&buf, 2), 0xABCD);
114 }
115
116 #[test]
117 fn into_i32_works() {
118 let a: u8 = 200;
119 let v: i32 = a.into();
120 assert_eq!(v, 200);
121
122 let b: u16 = 4095;
123 let v: i32 = b.into();
124 assert_eq!(v, 4095);
125 }
126
127 #[test]
128 fn needs_u16_dispatch() {
129 assert!(!needs_u16(2));
130 assert!(!needs_u16(8));
131 assert!(needs_u16(9));
132 assert!(needs_u16(12));
133 assert!(needs_u16(16));
134 }
135}