lasreaditemcompressed_v2.cpp
Go to the documentation of this file.
1 /*
2 ===============================================================================
3 
4  FILE: lasreaditemcompressed_v2.cpp
5 
6  CONTENTS:
7 
8  see corresponding header file
9 
10  PROGRAMMERS:
11 
12  martin.isenburg@gmail.com
13 
14  COPYRIGHT:
15 
16  (c) 2011, Martin Isenburg, LASSO - 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 
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;
49  U8 user_data;
51 };
52 
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 
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 
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 
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 
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 
265 {
266  dec->destroySymbolModel(m_gpstime_multi);
267  dec->destroySymbolModel(m_gpstime_0diff);
268  delete ic_gpstime;
269 }
270 
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 
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);
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);
397  }
398  }
399  *((I64*)item) = last_gpstime[last].i64;
400 }
401 
402 /*
403 ===============================================================================
404  LASreadItemCompressed_RGB12_v2
405 ===============================================================================
406 */
407 
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 
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 
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 
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 
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 EntropyModel*[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 
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 
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 
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 }
int BOOL
Definition: mydefs.hpp:57
LASreadItemCompressed_RGB12_v2(EntropyDecoder *dec)
#define LASZIP_GPSTIME_MULTI_MINUS
unsigned int U32
Definition: mydefs.hpp:39
#define U32_ZERO_BIT_0(n)
Definition: mydefs.hpp:130
#define LASZIP_GPSTIME_MULTI_TOTAL
unsigned short U16
Definition: mydefs.hpp:40
#define LASZIP_GPSTIME_MULTI_UNCHANGED
LASreadItemCompressed_POINT10_v2(EntropyDecoder *dec)
#define LASZIP_GPSTIME_MULTI_CODE_FULL
#define U8_FOLD(n)
Definition: mydefs.hpp:94
long long I64
Definition: mydefs.hpp:48
unsigned char U8
Definition: mydefs.hpp:41
LASreadItemCompressed_BYTE_v2(EntropyDecoder *dec, U32 number)
#define LASZIP_GPSTIME_MULTI
char I8
Definition: mydefs.hpp:37
virtual EntropyModel * createSymbolModel(U32 n)=0
int I32
Definition: mydefs.hpp:35
const U8 number_return_map[8][8]
const U8 number_return_level[8][8]
#define TRUE
Definition: mydefs.hpp:137
unsigned long long U64
Definition: mydefs.hpp:47
#define U8_CLAMP(n)
Definition: mydefs.hpp:97


lvr2
Author(s): Thomas Wiemann , Sebastian Pütz , Alexander Mock , Lars Kiesow , Lukas Kalbertodt , Tristan Igelbrink , Johan M. von Behren , Dominik Feldschnieders , Alexander Löhr
autogenerated on Mon Feb 28 2022 22:46:07