1 /*
2 ===============================================================================
3
4 FILE: lasreaditemcompressed_v2.cpp
5
6 CONTENTS:
7
8 see corresponding header file
9
10 PROGRAMMERS:
11
12 martin.isenburg@rapidlasso.com - http://rapidlasso.com
13
14 COPYRIGHT:
15
16 (c) 2007-2017, martin isenburg, rapidlasso - fast tools to catch reality
17
18 This is free software; you can redistribute and/or modify it under the
19 terms of the GNU Lesser General Licence as published by the Free Software
20 Foundation. See the COPYING file for more information.
21
22 This software is distributed WITHOUT ANY WARRANTY and without even the
23 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
24
25 CHANGE HISTORY:
26
27 see corresponding header file
28
29 ===============================================================================
30 */
31
32 #include "lasreaditemcompressed_v2.hpp"
33
34 #include <assert.h>
35 #include <string.h>
36
37 struct LASpoint10
38 {
39 I32 x;
40 I32 y;
41 I32 z;
42 U16 intensity;
43 U8 return_number : 3;
44 U8 number_of_returns_of_given_pulse : 3;
45 U8 scan_direction_flag : 1;
46 U8 edge_of_flight_line : 1;
47 U8 classification;
48 I8 scan_angle_rank;
49 U8 user_data;
50 U16 point_source_ID;
51 };
52
LASreadItemCompressed_POINT10_v2(ArithmeticDecoder * dec)53 LASreadItemCompressed_POINT10_v2::LASreadItemCompressed_POINT10_v2(ArithmeticDecoder* dec)
54 {
55 U32 i;
56
57 /* set decoder */
58 assert(dec);
59 this->dec = dec;
60
61 /* create models and integer compressors */
62 m_changed_values = dec->createSymbolModel(64);
63 ic_intensity = new IntegerCompressor(dec, 16, 4);
64 m_scan_angle_rank[0] = dec->createSymbolModel(256);
65 m_scan_angle_rank[1] = dec->createSymbolModel(256);
66 ic_point_source_ID = new IntegerCompressor(dec, 16);
67 for (i = 0; i < 256; i++)
68 {
69 m_bit_byte[i] = 0;
70 m_classification[i] = 0;
71 m_user_data[i] = 0;
72 }
73 ic_dx = new IntegerCompressor(dec, 32, 2); // 32 bits, 2 context
74 ic_dy = new IntegerCompressor(dec, 32, 22); // 32 bits, 22 contexts
75 ic_z = new IntegerCompressor(dec, 32, 20); // 32 bits, 20 contexts
76 }
77
~LASreadItemCompressed_POINT10_v2()78 LASreadItemCompressed_POINT10_v2::~LASreadItemCompressed_POINT10_v2()
79 {
80 U32 i;
81
82 dec->destroySymbolModel(m_changed_values);
83 delete ic_intensity;
84 dec->destroySymbolModel(m_scan_angle_rank[0]);
85 dec->destroySymbolModel(m_scan_angle_rank[1]);
86 delete ic_point_source_ID;
87 for (i = 0; i < 256; i++)
88 {
89 if (m_bit_byte[i]) dec->destroySymbolModel(m_bit_byte[i]);
90 if (m_classification[i]) dec->destroySymbolModel(m_classification[i]);
91 if (m_user_data[i]) dec->destroySymbolModel(m_user_data[i]);
92 }
93 delete ic_dx;
94 delete ic_dy;
95 delete ic_z;
96 }
97
init(const U8 * item,U32 & context)98 BOOL LASreadItemCompressed_POINT10_v2::init(const U8* item, U32& context)
99 {
100 U32 i;
101
102 /* init state */
103 for (i=0; i < 16; i++)
104 {
105 last_x_diff_median5[i].init();
106 last_y_diff_median5[i].init();
107 last_intensity[i] = 0;
108 last_height[i/2] = 0;
109 }
110
111 /* init models and integer compressors */
112 dec->initSymbolModel(m_changed_values);
113 ic_intensity->initDecompressor();
114 dec->initSymbolModel(m_scan_angle_rank[0]);
115 dec->initSymbolModel(m_scan_angle_rank[1]);
116 ic_point_source_ID->initDecompressor();
117 for (i = 0; i < 256; i++)
118 {
119 if (m_bit_byte[i]) dec->initSymbolModel(m_bit_byte[i]);
120 if (m_classification[i]) dec->initSymbolModel(m_classification[i]);
121 if (m_user_data[i]) dec->initSymbolModel(m_user_data[i]);
122 }
123 ic_dx->initDecompressor();
124 ic_dy->initDecompressor();
125 ic_z->initDecompressor();
126
127 /* init last item */
128 memcpy(last_item, item, 20);
129
130 /* but set intensity to zero */
131 last_item[12] = 0;
132 last_item[13] = 0;
133
134 return TRUE;
135 }
136
read(U8 * item,U32 & context)137 inline void LASreadItemCompressed_POINT10_v2::read(U8* item, U32& context)
138 {
139 U32 r, n, m, l;
140 U32 k_bits;
141 I32 median, diff;
142
143 // decompress which other values have changed
144 I32 changed_values = dec->decodeSymbol(m_changed_values);
145
146 if (changed_values)
147 {
148 // decompress the edge_of_flight_line, scan_direction_flag, ... if it has changed
149 if (changed_values & 32)
150 {
151 if (m_bit_byte[last_item[14]] == 0)
152 {
153 m_bit_byte[last_item[14]] = dec->createSymbolModel(256);
154 dec->initSymbolModel(m_bit_byte[last_item[14]]);
155 }
156 last_item[14] = (U8)dec->decodeSymbol(m_bit_byte[last_item[14]]);
157 }
158
159 r = ((LASpoint10*)last_item)->return_number;
160 n = ((LASpoint10*)last_item)->number_of_returns_of_given_pulse;
161 m = number_return_map[n][r];
162 l = number_return_level[n][r];
163
164 // decompress the intensity if it has changed
165 if (changed_values & 16)
166 {
167 ((LASpoint10*)last_item)->intensity = (U16)ic_intensity->decompress(last_intensity[m], (m < 3 ? m : 3));
168 last_intensity[m] = ((LASpoint10*)last_item)->intensity;
169 }
170 else
171 {
172 ((LASpoint10*)last_item)->intensity = last_intensity[m];
173 }
174
175 // decompress the classification ... if it has changed
176 if (changed_values & 8)
177 {
178 if (m_classification[last_item[15]] == 0)
179 {
180 m_classification[last_item[15]] = dec->createSymbolModel(256);
181 dec->initSymbolModel(m_classification[last_item[15]]);
182 }
183 last_item[15] = (U8)dec->decodeSymbol(m_classification[last_item[15]]);
184 }
185
186 // decompress the scan_angle_rank ... if it has changed
187 if (changed_values & 4)
188 {
189 I32 val = dec->decodeSymbol(m_scan_angle_rank[((LASpoint10*)last_item)->scan_direction_flag]);
190 last_item[16] = U8_FOLD(val + last_item[16]);
191 }
192
193 // decompress the user_data ... if it has changed
194 if (changed_values & 2)
195 {
196 if (m_user_data[last_item[17]] == 0)
197 {
198 m_user_data[last_item[17]] = dec->createSymbolModel(256);
199 dec->initSymbolModel(m_user_data[last_item[17]]);
200 }
201 last_item[17] = (U8)dec->decodeSymbol(m_user_data[last_item[17]]);
202 }
203
204 // decompress the point_source_ID ... if it has changed
205 if (changed_values & 1)
206 {
207 ((LASpoint10*)last_item)->point_source_ID = (U16)ic_point_source_ID->decompress(((LASpoint10*)last_item)->point_source_ID);
208 }
209 }
210 else
211 {
212 r = ((LASpoint10*)last_item)->return_number;
213 n = ((LASpoint10*)last_item)->number_of_returns_of_given_pulse;
214 m = number_return_map[n][r];
215 l = number_return_level[n][r];
216 }
217
218 // decompress x coordinate
219 median = last_x_diff_median5[m].get();
220 diff = ic_dx->decompress(median, n==1);
221 ((LASpoint10*)last_item)->x += diff;
222 last_x_diff_median5[m].add(diff);
223
224 // decompress y coordinate
225 median = last_y_diff_median5[m].get();
226 k_bits = ic_dx->getK();
227 diff = ic_dy->decompress(median, (n==1) + ( k_bits < 20 ? U32_ZERO_BIT_0(k_bits) : 20 ));
228 ((LASpoint10*)last_item)->y += diff;
229 last_y_diff_median5[m].add(diff);
230
231 // decompress z coordinate
232 k_bits = (ic_dx->getK() + ic_dy->getK()) / 2;
233 ((LASpoint10*)last_item)->z = ic_z->decompress(last_height[l], (n==1) + (k_bits < 18 ? U32_ZERO_BIT_0(k_bits) : 18));
234 last_height[l] = ((LASpoint10*)last_item)->z;
235
236 // copy the last point
237 memcpy(item, last_item, 20);
238 }
239
240 /*
241 ===============================================================================
242 LASreadItemCompressed_GPSTIME11_v2
243 ===============================================================================
244 */
245
246 #define LASZIP_GPSTIME_MULTI 500
247 #define LASZIP_GPSTIME_MULTI_MINUS -10
248 #define LASZIP_GPSTIME_MULTI_UNCHANGED (LASZIP_GPSTIME_MULTI - LASZIP_GPSTIME_MULTI_MINUS + 1)
249 #define LASZIP_GPSTIME_MULTI_CODE_FULL (LASZIP_GPSTIME_MULTI - LASZIP_GPSTIME_MULTI_MINUS + 2)
250
251 #define LASZIP_GPSTIME_MULTI_TOTAL (LASZIP_GPSTIME_MULTI - LASZIP_GPSTIME_MULTI_MINUS + 6)
252
LASreadItemCompressed_GPSTIME11_v2(ArithmeticDecoder * dec)253 LASreadItemCompressed_GPSTIME11_v2::LASreadItemCompressed_GPSTIME11_v2(ArithmeticDecoder* dec)
254 {
255 /* set decoder */
256 assert(dec);
257 this->dec = dec;
258 /* create entropy models and integer compressors */
259 m_gpstime_multi = dec->createSymbolModel(LASZIP_GPSTIME_MULTI_TOTAL);
260 m_gpstime_0diff = dec->createSymbolModel(6);
261 ic_gpstime = new IntegerCompressor(dec, 32, 9); // 32 bits, 9 contexts
262 }
263
~LASreadItemCompressed_GPSTIME11_v2()264 LASreadItemCompressed_GPSTIME11_v2::~LASreadItemCompressed_GPSTIME11_v2()
265 {
266 dec->destroySymbolModel(m_gpstime_multi);
267 dec->destroySymbolModel(m_gpstime_0diff);
268 delete ic_gpstime;
269 }
270
init(const U8 * item,U32 & context)271 BOOL LASreadItemCompressed_GPSTIME11_v2::init(const U8* item, U32& context)
272 {
273 /* init state */
274 last = 0, next = 0;
275 last_gpstime_diff[0] = 0;
276 last_gpstime_diff[1] = 0;
277 last_gpstime_diff[2] = 0;
278 last_gpstime_diff[3] = 0;
279 multi_extreme_counter[0] = 0;
280 multi_extreme_counter[1] = 0;
281 multi_extreme_counter[2] = 0;
282 multi_extreme_counter[3] = 0;
283
284 /* init models and integer compressors */
285 dec->initSymbolModel(m_gpstime_multi);
286 dec->initSymbolModel(m_gpstime_0diff);
287 ic_gpstime->initDecompressor();
288
289 /* init last item */
290 last_gpstime[0].u64 = *((U64*)item);
291 last_gpstime[1].u64 = 0;
292 last_gpstime[2].u64 = 0;
293 last_gpstime[3].u64 = 0;
294 return TRUE;
295 }
296
read(U8 * item,U32 & context)297 inline void LASreadItemCompressed_GPSTIME11_v2::read(U8* item, U32& context)
298 {
299 I32 multi;
300 if (last_gpstime_diff[last] == 0) // if the last integer difference was zero
301 {
302 multi = dec->decodeSymbol(m_gpstime_0diff);
303 if (multi == 1) // the difference can be represented with 32 bits
304 {
305 last_gpstime_diff[last] = ic_gpstime->decompress(0, 0);
306 last_gpstime[last].i64 += last_gpstime_diff[last];
307 multi_extreme_counter[last] = 0;
308 }
309 else if (multi == 2) // the difference is huge
310 {
311 next = (next+1)&3;
312 last_gpstime[next].u64 = ic_gpstime->decompress((I32)(last_gpstime[last].u64 >> 32), 8);
313 last_gpstime[next].u64 = last_gpstime[next].u64 << 32;
314 last_gpstime[next].u64 |= dec->readInt();
315 last = next;
316 last_gpstime_diff[last] = 0;
317 multi_extreme_counter[last] = 0;
318 }
319 else if (multi > 2) // we switch to another sequence
320 {
321 last = (last+multi-2)&3;
322 read(item, context);
323 }
324 }
325 else
326 {
327 multi = dec->decodeSymbol(m_gpstime_multi);
328 if (multi == 1)
329 {
330 last_gpstime[last].i64 += ic_gpstime->decompress(last_gpstime_diff[last], 1);;
331 multi_extreme_counter[last] = 0;
332 }
333 else if (multi < LASZIP_GPSTIME_MULTI_UNCHANGED)
334 {
335 I32 gpstime_diff;
336 if (multi == 0)
337 {
338 gpstime_diff = ic_gpstime->decompress(0, 7);
339 multi_extreme_counter[last]++;
340 if (multi_extreme_counter[last] > 3)
341 {
342 last_gpstime_diff[last] = gpstime_diff;
343 multi_extreme_counter[last] = 0;
344 }
345 }
346 else if (multi < LASZIP_GPSTIME_MULTI)
347 {
348 if (multi < 10)
349 gpstime_diff = ic_gpstime->decompress(multi*last_gpstime_diff[last], 2);
350 else
351 gpstime_diff = ic_gpstime->decompress(multi*last_gpstime_diff[last], 3);
352 }
353 else if (multi == LASZIP_GPSTIME_MULTI)
354 {
355 gpstime_diff = ic_gpstime->decompress(LASZIP_GPSTIME_MULTI*last_gpstime_diff[last], 4);
356 multi_extreme_counter[last]++;
357 if (multi_extreme_counter[last] > 3)
358 {
359 last_gpstime_diff[last] = gpstime_diff;
360 multi_extreme_counter[last] = 0;
361 }
362 }
363 else
364 {
365 multi = LASZIP_GPSTIME_MULTI - multi;
366 if (multi > LASZIP_GPSTIME_MULTI_MINUS)
367 {
368 gpstime_diff = ic_gpstime->decompress(multi*last_gpstime_diff[last], 5);
369 }
370 else
371 {
372 gpstime_diff = ic_gpstime->decompress(LASZIP_GPSTIME_MULTI_MINUS*last_gpstime_diff[last], 6);
373 multi_extreme_counter[last]++;
374 if (multi_extreme_counter[last] > 3)
375 {
376 last_gpstime_diff[last] = gpstime_diff;
377 multi_extreme_counter[last] = 0;
378 }
379 }
380 }
381 last_gpstime[last].i64 += gpstime_diff;
382 }
383 else if (multi == LASZIP_GPSTIME_MULTI_CODE_FULL)
384 {
385 next = (next+1)&3;
386 last_gpstime[next].u64 = ic_gpstime->decompress((I32)(last_gpstime[last].u64 >> 32), 8);
387 last_gpstime[next].u64 = last_gpstime[next].u64 << 32;
388 last_gpstime[next].u64 |= dec->readInt();
389 last = next;
390 last_gpstime_diff[last] = 0;
391 multi_extreme_counter[last] = 0;
392 }
393 else if (multi >= LASZIP_GPSTIME_MULTI_CODE_FULL)
394 {
395 last = (last+multi-LASZIP_GPSTIME_MULTI_CODE_FULL)&3;
396 read(item, context);
397 }
398 }
399 *((I64*)item) = last_gpstime[last].i64;
400 }
401
402 /*
403 ===============================================================================
404 LASreadItemCompressed_RGB12_v2
405 ===============================================================================
406 */
407
LASreadItemCompressed_RGB12_v2(ArithmeticDecoder * dec)408 LASreadItemCompressed_RGB12_v2::LASreadItemCompressed_RGB12_v2(ArithmeticDecoder* dec)
409 {
410 /* set decoder */
411 assert(dec);
412 this->dec = dec;
413
414 /* create models and integer compressors */
415 m_byte_used = dec->createSymbolModel(128);
416 m_rgb_diff_0 = dec->createSymbolModel(256);
417 m_rgb_diff_1 = dec->createSymbolModel(256);
418 m_rgb_diff_2 = dec->createSymbolModel(256);
419 m_rgb_diff_3 = dec->createSymbolModel(256);
420 m_rgb_diff_4 = dec->createSymbolModel(256);
421 m_rgb_diff_5 = dec->createSymbolModel(256);
422 }
423
~LASreadItemCompressed_RGB12_v2()424 LASreadItemCompressed_RGB12_v2::~LASreadItemCompressed_RGB12_v2()
425 {
426 dec->destroySymbolModel(m_byte_used);
427 dec->destroySymbolModel(m_rgb_diff_0);
428 dec->destroySymbolModel(m_rgb_diff_1);
429 dec->destroySymbolModel(m_rgb_diff_2);
430 dec->destroySymbolModel(m_rgb_diff_3);
431 dec->destroySymbolModel(m_rgb_diff_4);
432 dec->destroySymbolModel(m_rgb_diff_5);
433 }
434
init(const U8 * item,U32 & context)435 BOOL LASreadItemCompressed_RGB12_v2::init(const U8* item, U32& context)
436 {
437 /* init state */
438
439 /* init models and integer compressors */
440 dec->initSymbolModel(m_byte_used);
441 dec->initSymbolModel(m_rgb_diff_0);
442 dec->initSymbolModel(m_rgb_diff_1);
443 dec->initSymbolModel(m_rgb_diff_2);
444 dec->initSymbolModel(m_rgb_diff_3);
445 dec->initSymbolModel(m_rgb_diff_4);
446 dec->initSymbolModel(m_rgb_diff_5);
447
448 /* init last item */
449 memcpy(last_item, item, 6);
450 return TRUE;
451 }
452
read(U8 * item,U32 & context)453 inline void LASreadItemCompressed_RGB12_v2::read(U8* item, U32& context)
454 {
455 U8 corr;
456 I32 diff = 0;
457 U32 sym = dec->decodeSymbol(m_byte_used);
458 if (sym & (1 << 0))
459 {
460 corr = dec->decodeSymbol(m_rgb_diff_0);
461 ((U16*)item)[0] = (U16)U8_FOLD(corr + (last_item[0]&255));
462 }
463 else
464 {
465 ((U16*)item)[0] = last_item[0]&0xFF;
466 }
467 if (sym & (1 << 1))
468 {
469 corr = dec->decodeSymbol(m_rgb_diff_1);
470 ((U16*)item)[0] |= (((U16)U8_FOLD(corr + (last_item[0]>>8))) << 8);
471 }
472 else
473 {
474 ((U16*)item)[0] |= (last_item[0]&0xFF00);
475 }
476 if (sym & (1 << 6))
477 {
478 diff = (((U16*)item)[0]&0x00FF) - (last_item[0]&0x00FF);
479 if (sym & (1 << 2))
480 {
481 corr = dec->decodeSymbol(m_rgb_diff_2);
482 ((U16*)item)[1] = (U16)U8_FOLD(corr + U8_CLAMP(diff+(last_item[1]&255)));
483 }
484 else
485 {
486 ((U16*)item)[1] = last_item[1]&0xFF;
487 }
488 if (sym & (1 << 4))
489 {
490 corr = dec->decodeSymbol(m_rgb_diff_4);
491 diff = (diff + ((((U16*)item)[1]&0x00FF) - (last_item[1]&0x00FF))) / 2;
492 ((U16*)item)[2] = (U16)U8_FOLD(corr + U8_CLAMP(diff+(last_item[2]&255)));
493 }
494 else
495 {
496 ((U16*)item)[2] = last_item[2]&0xFF;
497 }
498 diff = (((U16*)item)[0]>>8) - (last_item[0]>>8);
499 if (sym & (1 << 3))
500 {
501 corr = dec->decodeSymbol(m_rgb_diff_3);
502 ((U16*)item)[1] |= (((U16)U8_FOLD(corr + U8_CLAMP(diff+(last_item[1]>>8))))<<8);
503 }
504 else
505 {
506 ((U16*)item)[1] |= (last_item[1]&0xFF00);
507 }
508 if (sym & (1 << 5))
509 {
510 corr = dec->decodeSymbol(m_rgb_diff_5);
511 diff = (diff + ((((U16*)item)[1]>>8) - (last_item[1]>>8))) / 2;
512 ((U16*)item)[2] |= (((U16)U8_FOLD(corr + U8_CLAMP(diff+(last_item[2]>>8))))<<8);
513 }
514 else
515 {
516 ((U16*)item)[2] |= (last_item[2]&0xFF00);
517 }
518 }
519 else
520 {
521 ((U16*)item)[1] = ((U16*)item)[0];
522 ((U16*)item)[2] = ((U16*)item)[0];
523 }
524 memcpy(last_item, item, 6);
525 }
526
527 /*
528 ===============================================================================
529 LASreadItemCompressed_BYTE_v2
530 ===============================================================================
531 */
532
LASreadItemCompressed_BYTE_v2(ArithmeticDecoder * dec,U32 number)533 LASreadItemCompressed_BYTE_v2::LASreadItemCompressed_BYTE_v2(ArithmeticDecoder* dec, U32 number)
534 {
535 U32 i;
536
537 /* set decoder */
538 assert(dec);
539 this->dec = dec;
540 assert(number);
541 this->number = number;
542
543 /* create models and integer compressors */
544 m_byte = new ArithmeticModel*[number];
545 for (i = 0; i < number; i++)
546 {
547 m_byte[i] = dec->createSymbolModel(256);
548 }
549
550 /* create last item */
551 last_item = new U8[number];
552 }
553
~LASreadItemCompressed_BYTE_v2()554 LASreadItemCompressed_BYTE_v2::~LASreadItemCompressed_BYTE_v2()
555 {
556 U32 i;
557 for (i = 0; i < number; i++)
558 {
559 dec->destroySymbolModel(m_byte[i]);
560 }
561 delete [] m_byte;
562 delete [] last_item;
563 }
564
init(const U8 * item,U32 & context)565 BOOL LASreadItemCompressed_BYTE_v2::init(const U8* item, U32& context)
566 {
567 U32 i;
568 /* init state */
569
570 /* init models and integer compressors */
571 for (i = 0; i < number; i++)
572 {
573 dec->initSymbolModel(m_byte[i]);
574 }
575
576 /* init last item */
577 memcpy(last_item, item, number);
578 return TRUE;
579 }
580
read(U8 * item,U32 & context)581 inline void LASreadItemCompressed_BYTE_v2::read(U8* item, U32& context)
582 {
583 U32 i;
584 I32 value;
585 for (i = 0; i < number; i++)
586 {
587 value = last_item[i] + dec->decodeSymbol(m_byte[i]);
588 item[i] = U8_FOLD(value);
589 }
590 memcpy(last_item, item, number);
591 }
592