1use super::{
2 ItemReader,
3 arithmetic_decoder::{ArithmeticDecoder, ArithmeticModel},
4 integer_compressor::IntegerCompressor,
5};
6use crate::{
7 parsers::{RGBA, Reader},
8 readers::{LASPoint, WavePacket, util::U64I64F64},
9};
10use alloc::{rc::Rc, vec, vec::Vec};
11use core::cell::RefCell;
12
13const LASZIP_GPSTIME_MULTIMAX: u32 = 512;
14
15#[derive(Debug, Clone)]
17pub struct LAZPoint10v1Reader<T: Reader> {
18 last_item: LASPoint,
19 dec: Rc<RefCell<ArithmeticDecoder<T>>>,
20 last_x_diff: [i32; 3],
21 last_y_diff: [i32; 3],
22 last_incr: i32,
23 ic_dx: IntegerCompressor<T>,
24 ic_dy: IntegerCompressor<T>,
25 ic_z: IntegerCompressor<T>,
26 ic_intensity: IntegerCompressor<T>,
27 ic_scan_angle_rank: IntegerCompressor<T>,
28 ic_point_source_id: IntegerCompressor<T>,
29 m_changed_values: ArithmeticModel,
30 m_bit_byte: [Option<ArithmeticModel>; 256],
31 m_classification: [Option<ArithmeticModel>; 256],
32 m_user_data: [Option<ArithmeticModel>; 256],
33}
34impl<T: Reader> LAZPoint10v1Reader<T> {
35 pub fn new(dec: Rc<RefCell<ArithmeticDecoder<T>>>) -> Self {
37 Self {
38 dec: dec.clone(),
39 last_item: LASPoint::default(),
40 last_x_diff: [0, 0, 0],
41 last_y_diff: [0, 0, 0],
42 last_incr: 0,
43 ic_dx: IntegerCompressor::new(dec.clone(), Some(32), None, None, None),
44 ic_dy: IntegerCompressor::new(dec.clone(), Some(32), Some(20), None, None),
45 ic_z: IntegerCompressor::new(dec.clone(), Some(32), Some(20), None, None),
46 ic_intensity: IntegerCompressor::new(dec.clone(), Some(16), None, None, None),
47 ic_scan_angle_rank: IntegerCompressor::new(dec.clone(), Some(8), Some(2), None, None),
48 ic_point_source_id: IntegerCompressor::new(dec.clone(), Some(16), None, None, None),
49 m_changed_values: ArithmeticModel::new(64, false),
50 m_bit_byte: [const { None }; 256],
51 m_classification: [const { None }; 256],
52 m_user_data: [const { None }; 256],
53 }
54 }
55}
56impl<T: Reader> ItemReader for LAZPoint10v1Reader<T> {
57 fn init<R: Reader>(&mut self, item: &R, point: &mut LASPoint, _context: &mut u32) {
58 self.last_x_diff = [0, 0, 0];
60 self.last_y_diff = [0, 0, 0];
61 self.last_incr = 0;
62 self.ic_dx.init_decompressor();
64 self.ic_dy.init_decompressor();
65 self.ic_z.init_decompressor();
66 self.ic_intensity.init_decompressor();
67 self.ic_scan_angle_rank.init_decompressor();
68 self.ic_point_source_id.init_decompressor();
69 self.m_changed_values.init(None);
70 self.last_item.inject_point10(item, 0);
72 point.inject_point10(item, 0);
73 }
74
75 fn read(&mut self, item: &mut LASPoint, context: &mut u32) {
76 let median_x;
78 if self.last_x_diff[0] < self.last_x_diff[1] {
79 if self.last_x_diff[1] < self.last_x_diff[2] {
80 median_x = self.last_x_diff[1];
81 } else if self.last_x_diff[0] < self.last_x_diff[2] {
82 median_x = self.last_x_diff[2];
83 } else {
84 median_x = self.last_x_diff[0];
85 }
86 } else if self.last_x_diff[0] < self.last_x_diff[2] {
87 median_x = self.last_x_diff[0];
88 } else if self.last_x_diff[1] < self.last_x_diff[2] {
89 median_x = self.last_x_diff[2];
90 } else {
91 median_x = self.last_x_diff[1];
92 }
93
94 let median_y;
95 if self.last_y_diff[0] < self.last_y_diff[1] {
96 if self.last_y_diff[1] < self.last_y_diff[2] {
97 median_y = self.last_y_diff[1];
98 } else if self.last_y_diff[0] < self.last_y_diff[2] {
99 median_y = self.last_y_diff[2];
100 } else {
101 median_y = self.last_y_diff[0];
102 }
103 } else if self.last_y_diff[0] < self.last_y_diff[2] {
104 median_y = self.last_y_diff[0];
105 } else if self.last_y_diff[1] < self.last_y_diff[2] {
106 median_y = self.last_y_diff[2];
107 } else {
108 median_y = self.last_y_diff[1];
109 }
110
111 let x_diff = self.ic_dx.decompress(median_x, *context);
113 self.last_item.x += x_diff;
114 let mut k_bits = self.ic_dx.get_k();
116 let y_diff = self.ic_dy.decompress(median_y, if k_bits < 19 { k_bits } else { 19 });
117 self.last_item.y += y_diff;
118 k_bits = (k_bits + self.ic_dy.get_k()) / 2;
119 self.last_item.z =
120 self.ic_z.decompress(self.last_item.z, if k_bits < 19 { k_bits } else { 19 });
121
122 let changed_values = self.dec.borrow_mut().decode_symbol(&mut self.m_changed_values);
124
125 if changed_values != 0 {
126 if (changed_values & 32) != 0 {
128 self.last_item.intensity =
129 self.ic_intensity.decompress(self.last_item.intensity as i32, *context) as u16;
130 }
131
132 if (changed_values & 16) != 0 {
134 if self.m_bit_byte[self.last_item.flags as usize].is_none() {
135 let mut model = ArithmeticModel::new(256, false);
136 model.init(None);
137 self.m_bit_byte[self.last_item.flags as usize] = Some(model);
138 }
139 self.last_item.set_flags(
140 self.dec.borrow_mut().decode_symbol(
141 self.m_bit_byte[self.last_item.flags as usize].as_mut().unwrap(),
142 ) as u8,
143 false,
144 );
145 }
146
147 if (changed_values & 8) != 0 {
149 if self.m_classification[self.last_item.classification as usize].is_none() {
150 let mut model = ArithmeticModel::new(256, false);
151 model.init(None);
152 self.m_classification[self.last_item.classification as usize] = Some(model);
153 }
154 self.last_item.set_flags2(self.dec.borrow_mut().decode_symbol(
155 self.m_classification[self.last_item.classification as usize].as_mut().unwrap(),
156 ) as u8);
157 }
158
159 if (changed_values & 4) != 0 {
161 self.last_item.scan_angle_rank = self.ic_scan_angle_rank.decompress(
162 self.last_item.scan_angle_rank as i32,
163 if k_bits < 3 { 1 } else { 0 },
164 ) as i8;
165 }
166
167 if (changed_values & 2) != 0 {
169 if self.m_user_data[self.last_item.user_data as usize].is_none() {
170 let mut model = ArithmeticModel::new(256, false);
171 model.init(None);
172 self.m_user_data[self.last_item.user_data as usize] = Some(model);
173 }
174 self.last_item.user_data = self.dec.borrow_mut().decode_symbol(
175 self.m_user_data[self.last_item.user_data as usize].as_mut().unwrap(),
176 ) as u8;
177 }
178
179 if (changed_values & 1) != 0 {
181 self.last_item.point_source_id = self
182 .ic_point_source_id
183 .decompress(self.last_item.point_source_id as i32, *context)
184 as u16;
185 }
186 }
187
188 self.last_x_diff[self.last_incr as usize] = x_diff;
190 self.last_y_diff[self.last_incr as usize] = y_diff;
191 self.last_incr += 1;
192 if self.last_incr > 2 {
193 self.last_incr = 0;
194 }
195
196 *item = self.last_item.clone();
197 }
198
199 fn chunk_sizes<R: Reader>(&mut self, _reader: &R) {}
200}
201
202#[derive(Debug, Clone)]
204pub struct LAZGpsTime11v1Reader<T: Reader> {
205 last_item: U64I64F64,
206 dec: Rc<RefCell<ArithmeticDecoder<T>>>,
207 m_gpstime_multi: ArithmeticModel,
208 m_gpstime0_diff: ArithmeticModel,
209 ic_gpstime: IntegerCompressor<T>,
210 last_item_diff: i64,
211 multi_extreme_counter: u8,
212}
213impl<T: Reader> LAZGpsTime11v1Reader<T> {
214 pub fn new(dec: Rc<RefCell<ArithmeticDecoder<T>>>) -> Self {
216 Self {
217 dec: dec.clone(),
218 m_gpstime_multi: ArithmeticModel::new(LASZIP_GPSTIME_MULTIMAX, false),
220 m_gpstime0_diff: ArithmeticModel::new(3, false),
221 ic_gpstime: IntegerCompressor::new(dec, Some(32), Some(6), None, None),
222 last_item_diff: 0,
223 multi_extreme_counter: 0,
224 last_item: U64I64F64::default(),
225 }
226 }
227}
228impl<T: Reader> ItemReader for LAZGpsTime11v1Reader<T> {
229 fn init<R: Reader>(&mut self, item: &R, point: &mut LASPoint, _context: &mut u32) {
230 self.last_item_diff = 0;
232 self.multi_extreme_counter = 0;
233 self.m_gpstime_multi.init(None);
235 self.m_gpstime0_diff.init(None);
236 self.ic_gpstime.init_decompressor();
237 self.last_item.set_u64(item.uint64_le(Some(0)));
239 point.gps_time = Some(self.last_item.f64());
240 }
241
242 fn read(&mut self, item: &mut LASPoint, _context: &mut u32) {
243 let multi;
244 if self.last_item_diff == 0 {
245 multi = self.dec.borrow_mut().decode_symbol(&mut self.m_gpstime0_diff);
247 if multi == 1 {
248 self.last_item_diff = self.ic_gpstime.decompress(0, 0) as i64;
250 self.last_item.set_i64(self.last_item_diff + self.last_item.i64());
251 } else if multi == 2 {
252 self.last_item.set_u64(self.dec.borrow_mut().read_int64());
254 }
255 } else {
256 multi = self.dec.borrow_mut().decode_symbol(&mut self.m_gpstime_multi);
257
258 if multi < LASZIP_GPSTIME_MULTIMAX - 2 {
259 let gpstime_diff; if multi == 1 {
261 gpstime_diff = self.ic_gpstime.decompress(self.last_item_diff as i32, 1);
262 self.last_item_diff = gpstime_diff as i64;
263 self.multi_extreme_counter = 0;
264 } else if multi == 0 {
265 gpstime_diff = self.ic_gpstime.decompress((self.last_item_diff / 4) as i32, 2);
266 self.multi_extreme_counter += 1;
267 if self.multi_extreme_counter > 3 {
268 self.last_item_diff = gpstime_diff as i64;
269 self.multi_extreme_counter = 0;
270 }
271 } else if multi < 10 {
272 gpstime_diff =
273 self.ic_gpstime.decompress((multi as i64 * self.last_item_diff) as i32, 3);
274 } else if multi < 50 {
275 gpstime_diff =
276 self.ic_gpstime.decompress((multi as i64 * self.last_item_diff) as i32, 4);
277 } else {
278 gpstime_diff =
279 self.ic_gpstime.decompress((multi as i64 * self.last_item_diff) as i32, 5);
280 if multi == LASZIP_GPSTIME_MULTIMAX - 3 {
281 self.multi_extreme_counter += 1;
282 if self.multi_extreme_counter > 3 {
283 self.last_item_diff = gpstime_diff as i64;
284 self.multi_extreme_counter = 0;
285 }
286 }
287 }
288 self.last_item.set_i64(gpstime_diff as i64 + self.last_item.i64());
289 } else if multi < LASZIP_GPSTIME_MULTIMAX - 1 {
290 self.last_item.set_u64(self.dec.borrow_mut().read_int64());
291 }
292 }
293
294 item.gps_time = Some(self.last_item.f64());
295 }
296
297 fn chunk_sizes<R: Reader>(&mut self, _reader: &R) {}
298}
299
300#[derive(Debug, Clone)]
302pub struct LAZrgb12v1Reader<T: Reader> {
303 last_item: [u16; 3],
305 dec: Rc<RefCell<ArithmeticDecoder<T>>>,
306 m_byte_used: ArithmeticModel,
307 ic_rgb: IntegerCompressor<T>,
308}
309impl<T: Reader> LAZrgb12v1Reader<T> {
310 pub fn new(dec: Rc<RefCell<ArithmeticDecoder<T>>>) -> Self {
312 Self {
313 dec: dec.clone(),
314 m_byte_used: ArithmeticModel::new(64, false),
316 ic_rgb: IntegerCompressor::new(dec, Some(8), Some(6), None, None),
317 last_item: [0; 3],
318 }
319 }
320}
321impl<T: Reader> ItemReader for LAZrgb12v1Reader<T> {
322 fn init<R: Reader>(&mut self, item: &R, point: &mut LASPoint, _context: &mut u32) {
323 self.m_byte_used.init(None);
325 self.ic_rgb.init_decompressor();
326 let r = item.uint16_le(None);
327 let g = item.uint16_le(None);
328 let b = item.uint16_le(None);
329 self.last_item = [r, g, b];
330 point.rgba = Some(RGBA::from_u16s(r, g, b, u16::MAX));
331 }
332
333 fn read(&mut self, item: &mut LASPoint, _context: &mut u32) {
334 let mut curr_item: [u16; 3] = [0; 3];
335 let sym = self.dec.borrow_mut().decode_symbol(&mut self.m_byte_used);
336 if (sym & (1 << 0)) != 0 {
337 curr_item[0] = self.ic_rgb.decompress((self.last_item[0] & 255) as i32, 0) as u16;
338 } else {
339 curr_item[0] = self.last_item[0] & 0xff;
340 }
341 if (sym & (1 << 1)) != 0 {
342 curr_item[0] |=
343 (self.ic_rgb.decompress((self.last_item[0] >> 8) as i32, 1) as u16) << 8;
344 } else {
345 curr_item[0] |= self.last_item[0] & 0xff00;
346 }
347 if (sym & (1 << 2)) != 0 {
348 curr_item[1] = self.ic_rgb.decompress((self.last_item[1] & 255) as i32, 2) as u16;
349 } else {
350 curr_item[1] = self.last_item[1] & 0xff;
351 }
352 if (sym & (1 << 3)) != 0 {
353 curr_item[1] |=
354 (self.ic_rgb.decompress((self.last_item[1] >> 8) as i32, 3) as u16) << 8;
355 } else {
356 curr_item[1] |= self.last_item[1] & 0xff00;
357 }
358 if (sym & (1 << 4)) != 0 {
359 curr_item[2] = self.ic_rgb.decompress((self.last_item[2] & 255) as i32, 4) as u16;
360 } else {
361 curr_item[2] = self.last_item[2] & 0xff;
362 }
363 if (sym & (1 << 5)) != 0 {
364 curr_item[2] |=
365 (self.ic_rgb.decompress((self.last_item[2] >> 8) as i32, 5) as u16) << 8;
366 } else {
367 curr_item[2] |= self.last_item[2] & 0xff00;
368 }
369
370 self.last_item = curr_item;
371 item.rgba = Some(RGBA::from_u16s(curr_item[0], curr_item[1], curr_item[2], u16::MAX));
372 }
373
374 fn chunk_sizes<R: Reader>(&mut self, _reader: &R) {}
375}
376
377#[derive(Debug, Clone)]
379pub struct LAZwavepacket13v1Reader<T: Reader> {
380 dec: Rc<RefCell<ArithmeticDecoder<T>>>,
381 index: u32,
382 last_item: WavePacket,
383 m_packet_index: ArithmeticModel,
384 m_offset_diff: [ArithmeticModel; 4],
385 ic_offset_diff: IntegerCompressor<T>,
386 ic_packet_size: IntegerCompressor<T>,
387 ic_return_point: IntegerCompressor<T>,
388 ic_xyz: IntegerCompressor<T>,
389 last_diff32: i32,
390 sym_last_offset_diff: u32,
391}
392impl<T: Reader> LAZwavepacket13v1Reader<T> {
393 pub fn new(dec: Rc<RefCell<ArithmeticDecoder<T>>>) -> Self {
395 Self {
396 index: 0,
397 dec: dec.clone(),
398 m_packet_index: ArithmeticModel::new(256, false),
400 m_offset_diff: [
401 ArithmeticModel::new(4, false),
402 ArithmeticModel::new(4, false),
403 ArithmeticModel::new(4, false),
404 ArithmeticModel::new(4, false),
405 ],
406 ic_offset_diff: IntegerCompressor::new(dec.clone(), Some(32), None, None, None),
407 ic_packet_size: IntegerCompressor::new(dec.clone(), Some(32), None, None, None),
408 ic_return_point: IntegerCompressor::new(dec.clone(), Some(32), None, None, None),
409 ic_xyz: IntegerCompressor::new(dec, Some(32), Some(3), None, None),
410 last_item: WavePacket::default(),
411 last_diff32: 0,
412 sym_last_offset_diff: 0,
413 }
414 }
415}
416impl<T: Reader> ItemReader for LAZwavepacket13v1Reader<T> {
417 fn init<R: Reader>(&mut self, item: &R, point: &mut LASPoint, _context: &mut u32) {
418 self.index = 0;
420 self.last_diff32 = 0;
421 self.sym_last_offset_diff = 0;
422
423 self.m_packet_index.init(None);
425 for m in self.m_offset_diff.iter_mut() {
426 m.init(None);
427 }
428 self.ic_offset_diff.init_decompressor();
429 self.ic_packet_size.init_decompressor();
430 self.ic_return_point.init_decompressor();
431 self.ic_xyz.init_decompressor();
432
433 self.last_item = WavePacket::from_reader(item, 0);
434 point.wave_packet = Some(self.last_item.clone());
435 }
436
437 fn read(&mut self, item: &mut LASPoint, _context: &mut u32) {
438 let mut this_item_m = WavePacket::default();
440 self.index = self.dec.borrow_mut().decode_symbol(&mut self.m_packet_index);
441
442 self.sym_last_offset_diff = self
443 .dec
444 .borrow_mut()
445 .decode_symbol(&mut self.m_offset_diff[self.sym_last_offset_diff as usize]);
446
447 if self.sym_last_offset_diff == 0 {
448 this_item_m.offset = self.last_item.offset;
449 } else if self.sym_last_offset_diff == 1 {
450 this_item_m.offset = self.last_item.offset + self.last_item.length as u64;
451 } else if self.sym_last_offset_diff == 2 {
452 self.last_diff32 = self.ic_offset_diff.decompress(self.last_diff32, 0);
453 this_item_m.offset = (self.last_item.offset as i32 + self.last_diff32) as u64;
454 } else {
455 this_item_m.offset = self.dec.borrow_mut().read_int64();
456 }
457
458 this_item_m.length = self.ic_packet_size.decompress(self.last_item.length as i32, 0) as u32;
459 this_item_m.return_point =
460 self.ic_return_point.decompress(self.last_item.return_point as i32, 0) as f32;
461 this_item_m.x_t = self.ic_xyz.decompress(self.last_item.x_t as i32, 0) as f32;
462 this_item_m.y_t = self.ic_xyz.decompress(self.last_item.y_t as i32, 1) as f32;
463 this_item_m.z_t = self.ic_xyz.decompress(self.last_item.z_t as i32, 2) as f32;
464
465 item.wave_packet = Some(this_item_m.clone());
467 self.last_item = this_item_m;
468 }
469
470 fn chunk_sizes<R: Reader>(&mut self, _reader: &R) {}
471}
472
473#[derive(Debug, Clone)]
475pub struct LAZbyte10v1Reader<T: Reader> {
476 size: u32,
477 last_item: Vec<u8>,
478 ic_byte: IntegerCompressor<T>,
479}
480impl<T: Reader> LAZbyte10v1Reader<T> {
481 pub fn new(dec: Rc<RefCell<ArithmeticDecoder<T>>>, size: u32) -> Self {
483 Self {
484 size,
485 last_item: vec![0; size as usize],
486 ic_byte: IntegerCompressor::new(dec, Some(8), Some(size), None, None),
487 }
488 }
489}
490impl<T: Reader> ItemReader for LAZbyte10v1Reader<T> {
491 fn init<R: Reader>(&mut self, item: &R, _point: &mut LASPoint, _context: &mut u32) {
492 self.ic_byte.init_decompressor();
494 self.last_item = item.seek_slice(self.size as usize);
495 }
496
497 fn read(&mut self, _item: &mut LASPoint, _context: &mut u32) {
498 let mut this_item = vec![0; self.size as usize];
499 for (i, val) in self.last_item.iter().enumerate() {
500 this_item[i] = self.ic_byte.decompress(*val as i32, i as u32);
501 }
502 self.last_item = this_item.iter().map(|x| *x as u8).collect();
503 }
504
505 fn chunk_sizes<R: Reader>(&mut self, _reader: &R) {}
506}