gistools/readers/las/
util.rs

1/// Fold a number between 0 and 255
2///
3/// ## Parameters
4/// - `n`: the number to fold
5///
6/// ## Returns
7/// The folded number
8pub fn u8_fold(n: u32) -> u8 {
9    if n > 255 { (n - 256) as u8 } else { n as u8 }
10}
11
12/// Clamp a number between 0 and 255
13///
14/// ## Parameters
15/// - `n`: the number to clamp
16///
17/// ## Returns
18/// The clamped number
19pub fn u8_clamp(n: u32) -> u8 {
20    if n > 255 { 255 } else { n as u8 }
21}
22
23/// Clamp a number between -128 and 127
24///
25/// ## Parameters
26/// - `n`: the number to clamp
27///
28/// ## Returns
29/// The clamped number
30pub fn i8_clamp(n: i32) -> i8 {
31    if n <= -128 {
32        -128
33    } else if n >= 127 {
34        127
35    } else {
36        n as i8
37    }
38}
39
40/// zero the least significant bit
41///
42/// ## Parameters
43/// - `n`: the number to zero
44///
45/// ## Returns
46/// The zeroed number
47pub fn u32_zero_bit0(n: u32) -> u32 {
48    n & 0xfffffffe
49}
50
51/// Quantize a signed 16-bit number
52///
53/// ## Parameters
54/// - `n`: the number to quantize
55///
56/// ## Returns
57/// The quantized number
58pub fn i16_quantize(n: f64) -> i16 {
59    if (n) >= 0. { ((n) + 0.5) as i16 } else { ((n) - 0.5) as i16 }
60}
61
62/// A special buffer that stores a 64-bit number and can be converted to different types
63/// respecting bit positions
64#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
65pub struct U64I64F64 {
66    bytes: [u8; 8],
67}
68
69impl U64I64F64 {
70    /// Creates a new U64I64F64
71    pub fn new(value: impl IntoValue64, ty: ValueType64) -> Self {
72        let mut out = Self { bytes: [0; 8] };
73        out.set(value, ty);
74        out
75    }
76    /// Sets the value
77    pub fn set(&mut self, value: impl IntoValue64, ty: ValueType64) {
78        match ty {
79            ValueType64::U64 => self.bytes = value.into_u64().to_le_bytes(),
80            ValueType64::I64 => self.bytes = value.into_i64().to_le_bytes(),
81            ValueType64::F64 => self.bytes = value.into_f64().to_le_bytes(),
82        }
83    }
84    /// Get the u64
85    pub fn u64(&self) -> u64 {
86        u64::from_le_bytes(self.bytes)
87    }
88    /// Set u64
89    pub fn set_u64(&mut self, value: u64) {
90        self.bytes = value.to_le_bytes();
91    }
92    /// Get i64
93    pub fn i64(&self) -> i64 {
94        i64::from_le_bytes(self.bytes)
95    }
96    /// Set i64
97    pub fn set_i64(&mut self, value: i64) {
98        self.bytes = value.to_le_bytes();
99    }
100    /// Get f64
101    pub fn f64(&self) -> f64 {
102        f64::from_le_bytes(self.bytes)
103    }
104    /// Set f64
105    pub fn set_f64(&mut self, value: f64) {
106        self.bytes = value.to_le_bytes();
107    }
108}
109
110/// A special buffer that stores a 64-bit number and can be converted to different types
111/// respecting bit positions
112#[derive(Debug, Clone, Copy, PartialEq, Eq)]
113pub enum ValueType64 {
114    /// Unsigned 64-bit number
115    U64,
116    /// Signed 64-bit number
117    I64,
118    /// 64-bit float
119    F64,
120}
121/// A trait for converting to different types
122pub trait IntoValue64 {
123    /// Converts to u64
124    fn into_u64(self) -> u64;
125    /// Converts to i64
126    fn into_i64(self) -> i64;
127    /// Converts to f64
128    fn into_f64(self) -> f64;
129}
130impl IntoValue64 for u64 {
131    fn into_u64(self) -> u64 {
132        self
133    }
134    fn into_i64(self) -> i64 {
135        self as i64
136    }
137    fn into_f64(self) -> f64 {
138        self as f64
139    }
140}
141impl IntoValue64 for i64 {
142    fn into_u64(self) -> u64 {
143        self as u64
144    }
145    fn into_i64(self) -> i64 {
146        self
147    }
148    fn into_f64(self) -> f64 {
149        self as f64
150    }
151}
152impl IntoValue64 for f64 {
153    fn into_u64(self) -> u64 {
154        self.to_bits()
155    }
156    fn into_i64(self) -> i64 {
157        self.to_bits() as i64
158    }
159    fn into_f64(self) -> f64 {
160        self
161    }
162}
163
164/// A special buffer that stores a 32-bit number and can be converted to different types
165/// respecting bit positions
166#[derive(Debug, Clone, Copy, PartialEq, Eq)]
167pub struct U32I32F32 {
168    bytes: [u8; 4],
169}
170impl U32I32F32 {
171    /// Creates a new U32I32F32
172    pub fn new(value: impl IntoValue32, ty: ValueType32) -> Self {
173        let mut out = Self { bytes: [0; 4] };
174        out.set(value, ty);
175        out
176    }
177    /// Sets the value
178    pub fn set(&mut self, value: impl IntoValue32, ty: ValueType32) {
179        match ty {
180            ValueType32::U32 => self.bytes = value.into_u32().to_le_bytes(),
181            ValueType32::I32 => self.bytes = value.into_i32().to_le_bytes(),
182            ValueType32::F32 => self.bytes = value.into_f32().to_le_bytes(),
183        }
184    }
185    /// Get the u32
186    pub fn u32(&self) -> u32 {
187        u32::from_le_bytes(self.bytes)
188    }
189    /// Set u32
190    pub fn set_u32(&mut self, value: u32) {
191        self.bytes = value.to_le_bytes();
192    }
193    /// Get i32
194    pub fn i32(&self) -> i32 {
195        i32::from_le_bytes(self.bytes)
196    }
197    /// Set i32
198    pub fn set_i32(&mut self, value: i32) {
199        self.bytes = value.to_le_bytes();
200    }
201    /// Get f32
202    pub fn f32(&self) -> f32 {
203        f32::from_le_bytes(self.bytes)
204    }
205    /// Set f32
206    pub fn set_f32(&mut self, value: f32) {
207        self.bytes = value.to_le_bytes();
208    }
209}
210
211/// A enum for converting to different types
212#[derive(Debug, Clone, Copy, PartialEq, Eq)]
213pub enum ValueType32 {
214    /// Unsigned 32-bit number
215    U32,
216    /// Signed 32-bit number
217    I32,
218    /// 32-bit float
219    F32,
220}
221/// A trait for converting to different types
222pub trait IntoValue32 {
223    /// Converts to u32
224    fn into_u32(self) -> u32;
225    /// Converts to i32
226    fn into_i32(self) -> i32;
227    /// Converts to f32
228    fn into_f32(self) -> f32;
229}
230
231impl IntoValue32 for u32 {
232    fn into_u32(self) -> u32 {
233        self
234    }
235    fn into_i32(self) -> i32 {
236        self as i32
237    }
238    fn into_f32(self) -> f32 {
239        self as f32
240    }
241}
242impl IntoValue32 for i32 {
243    fn into_u32(self) -> u32 {
244        self as u32
245    }
246    fn into_i32(self) -> i32 {
247        self
248    }
249    fn into_f32(self) -> f32 {
250        self as f32
251    }
252}
253impl IntoValue32 for f32 {
254    fn into_u32(self) -> u32 {
255        self.to_bits()
256    }
257    fn into_i32(self) -> i32 {
258        self.to_bits() as i32
259    }
260    fn into_f32(self) -> f32 {
261        self
262    }
263}