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