laswriteitemcompressed_v1.cpp
Go to the documentation of this file.
1 /*
2 ===============================================================================
3 
4  FILE: laswriteitemcompressed_v1.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 /*
38 ===============================================================================
39  LASwriteItemCompressed_POINT10_v1
40 ===============================================================================
41 */
42 
43 struct LASpoint10
44 {
45  I32 x;
46  I32 y;
47  I32 z;
48  U16 intensity;
49  U8 return_number : 3;
55  U8 user_data;
57 };
58 
60 {
61  U32 i;
62 
63  /* set encoder */
64  assert(enc);
65  this->enc = enc;
66 
67  /* create models and integer compressors */
68  ic_dx = new IntegerCompressor(enc, 32); // 32 bits, 1 context
69  ic_dy = new IntegerCompressor(enc, 32, 20); // 32 bits, 20 contexts
70  ic_z = new IntegerCompressor(enc, 32, 20); // 32 bits, 20 contexts
71  ic_intensity = new IntegerCompressor(enc, 16);
72  ic_scan_angle_rank = new IntegerCompressor(enc, 8, 2);
73  ic_point_source_ID = new IntegerCompressor(enc, 16);
74  m_changed_values = enc->createSymbolModel(64);
75  for (i = 0; i < 256; i++)
76  {
77  m_bit_byte[i] = 0;
78  m_classification[i] = 0;
79  m_user_data[i] = 0;
80  }
81 }
82 
84 {
85  U32 i;
86  delete ic_dx;
87  delete ic_dy;
88  delete ic_z;
89  delete ic_intensity;
90  delete ic_scan_angle_rank;
91  delete ic_point_source_ID;
92  enc->destroySymbolModel(m_changed_values);
93  for (i = 0; i < 256; i++)
94  {
95  if (m_bit_byte[i]) enc->destroySymbolModel(m_bit_byte[i]);
96  if (m_classification[i]) enc->destroySymbolModel(m_classification[i]);
97  if (m_user_data[i]) enc->destroySymbolModel(m_user_data[i]);
98  }
99 }
100 
102 {
103  U32 i;
104 
105  /* init state */
106  last_x_diff[0] = last_x_diff[1] = last_x_diff[2] = 0;
107  last_y_diff[0] = last_y_diff[1] = last_y_diff[2] = 0;
108  last_incr = 0;
109 
110  /* init models and integer compressors */
111  ic_dx->initCompressor();
112  ic_dy->initCompressor();
113  ic_z->initCompressor();
114  ic_intensity->initCompressor();
115  ic_scan_angle_rank->initCompressor();
116  ic_point_source_ID->initCompressor();
117  enc->initSymbolModel(m_changed_values);
118  for (i = 0; i < 256; i++)
119  {
120  if (m_bit_byte[i]) enc->initSymbolModel(m_bit_byte[i]);
121  if (m_classification[i]) enc->initSymbolModel(m_classification[i]);
122  if (m_user_data[i]) enc->initSymbolModel(m_user_data[i]);
123  }
124 
125  /* init last item */
126  memcpy(last_item, item, 20);
127 
128  return TRUE;
129 }
130 
132 {
133  // find median difference for x and y from 3 preceding differences
134  I32 median_x;
135  if (last_x_diff[0] < last_x_diff[1])
136  {
137  if (last_x_diff[1] < last_x_diff[2])
138  median_x = last_x_diff[1];
139  else if (last_x_diff[0] < last_x_diff[2])
140  median_x = last_x_diff[2];
141  else
142  median_x = last_x_diff[0];
143  }
144  else
145  {
146  if (last_x_diff[0] < last_x_diff[2])
147  median_x = last_x_diff[0];
148  else if (last_x_diff[1] < last_x_diff[2])
149  median_x = last_x_diff[2];
150  else
151  median_x = last_x_diff[1];
152  }
153 
154  I32 median_y;
155  if (last_y_diff[0] < last_y_diff[1])
156  {
157  if (last_y_diff[1] < last_y_diff[2])
158  median_y = last_y_diff[1];
159  else if (last_y_diff[0] < last_y_diff[2])
160  median_y = last_y_diff[2];
161  else
162  median_y = last_y_diff[0];
163  }
164  else
165  {
166  if (last_y_diff[0] < last_y_diff[2])
167  median_y = last_y_diff[0];
168  else if (last_y_diff[1] < last_y_diff[2])
169  median_y = last_y_diff[2];
170  else
171  median_y = last_y_diff[1];
172  }
173 
174  // compress x y z coordinates
175  I32 x_diff = ((LASpoint10*)item)->x - ((LASpoint10*)last_item)->x;
176  I32 y_diff = ((LASpoint10*)item)->y - ((LASpoint10*)last_item)->y;
177 
178  ic_dx->compress(median_x, x_diff);
179  // we use the number k of bits corrector bits to switch contexts
180  U32 k_bits = ic_dx->getK();
181  ic_dy->compress(median_y, y_diff, (k_bits < 19 ? k_bits : 19));
182  k_bits = (k_bits + ic_dy->getK()) / 2;
183  ic_z->compress(((LASpoint10*)last_item)->z, ((LASpoint10*)item)->z, (k_bits < 19 ? k_bits : 19));
184 
185  // compress which other values have changed
186  I32 changed_values = ((((LASpoint10*)last_item)->intensity != ((LASpoint10*)item)->intensity) << 5) |
187  ((last_item[14] != item[14]) << 4) | // bit_byte
188  ((last_item[15] != item[15]) << 3) | // classification
189  ((last_item[16] != item[16]) << 2) | // scan_angle_rank
190  ((last_item[17] != item[17]) << 1) | // user_data
191  ((((LASpoint10*)last_item)->point_source_ID != ((LASpoint10*)item)->point_source_ID));
192 
193  enc->encodeSymbol(m_changed_values, changed_values);
194 
195  // compress the intensity if it has changed
196  if (changed_values & 32)
197  {
198  ic_intensity->compress(((LASpoint10*)last_item)->intensity, ((LASpoint10*)item)->intensity);
199  }
200 
201  // compress the edge_of_flight_line, scan_direction_flag, ... if it has changed
202  if (changed_values & 16)
203  {
204  if (m_bit_byte[last_item[14]] == 0)
205  {
206  m_bit_byte[last_item[14]] = enc->createSymbolModel(256);
207  enc->initSymbolModel(m_bit_byte[last_item[14]]);
208  }
209  enc->encodeSymbol(m_bit_byte[last_item[14]], item[14]);
210  }
211 
212  // compress the classification ... if it has changed
213  if (changed_values & 8)
214  {
215  if (m_classification[last_item[15]] == 0)
216  {
217  m_classification[last_item[15]] = enc->createSymbolModel(256);
218  enc->initSymbolModel(m_classification[last_item[15]]);
219  }
220  enc->encodeSymbol(m_classification[last_item[15]], item[15]);
221  }
222 
223  // compress the scan_angle_rank ... if it has changed
224  if (changed_values & 4)
225  {
226  ic_scan_angle_rank->compress(last_item[16], item[16], k_bits < 3);
227  }
228 
229  // compress the user_data ... if it has changed
230  if (changed_values & 2)
231  {
232  if (m_user_data[last_item[17]] == 0)
233  {
234  m_user_data[last_item[17]] = enc->createSymbolModel(256);
235  enc->initSymbolModel(m_user_data[last_item[17]]);
236  }
237  enc->encodeSymbol(m_user_data[last_item[17]], item[17]);
238  }
239 
240  // compress the point_source_ID ... if it has changed
241  if (changed_values & 1)
242  {
243  ic_point_source_ID->compress(((LASpoint10*)last_item)->point_source_ID, ((LASpoint10*)item)->point_source_ID);
244  }
245 
246  // record the difference
247  last_x_diff[last_incr] = x_diff;
248  last_y_diff[last_incr] = y_diff;
249  last_incr++;
250  if (last_incr > 2) last_incr = 0;
251 
252  // copy the last item
253  memcpy(last_item, item, 20);
254  return TRUE;
255 }
256 
257 /*
258 ===============================================================================
259  LASwriteItemCompressed_GPSTIME11_v1
260 ===============================================================================
261 */
262 
263 #define LASZIP_GPSTIME_MULTIMAX 512
264 
266 {
267  /* set encoder */
268  assert(enc);
269  this->enc = enc;
270  /* create entropy models and integer compressors */
271  m_gpstime_multi = enc->createSymbolModel(LASZIP_GPSTIME_MULTIMAX);
272  m_gpstime_0diff = enc->createSymbolModel(3);
273  ic_gpstime = new IntegerCompressor(enc, 32, 6); // 32 bits, 6 contexts
274 }
275 
277 {
278  enc->destroySymbolModel(m_gpstime_multi);
279  enc->destroySymbolModel(m_gpstime_0diff);
280  delete ic_gpstime;
281 }
282 
284 {
285  /* init state */
286  last_gpstime_diff = 0;
287  multi_extreme_counter = 0;
288 
289  /* init models and integer compressors */
290  enc->initSymbolModel(m_gpstime_multi);
291  enc->initSymbolModel(m_gpstime_0diff);
292  ic_gpstime->initCompressor();
293 
294  /* init last item */
295  last_gpstime.u64 = *((U64*)item);
296  return TRUE;
297 }
298 
300 {
301  U64I64F64 this_gpstime;
302  this_gpstime.i64 = *((I64*)item);
303 
304  if (last_gpstime_diff == 0) // if the last integer difference was zero
305  {
306  if (this_gpstime.i64 == last_gpstime.i64)
307  {
308  enc->encodeSymbol(m_gpstime_0diff, 0); // the doubles have not changed
309  }
310  else
311  {
312  // calculate the difference between the two doubles as an integer
313  I64 curr_gpstime_diff_64 = this_gpstime.i64 - last_gpstime.i64;
314  I32 curr_gpstime_diff = (I32)curr_gpstime_diff_64;
315  if (curr_gpstime_diff_64 == (I64)(curr_gpstime_diff))
316  {
317  enc->encodeSymbol(m_gpstime_0diff, 1); // the difference can be represented with 32 bits
318  ic_gpstime->compress(0, curr_gpstime_diff, 0);
319  last_gpstime_diff = curr_gpstime_diff;
320  }
321  else
322  {
323  enc->encodeSymbol(m_gpstime_0diff, 2); // the difference is huge
324  enc->writeInt64(this_gpstime.u64);
325  }
326  last_gpstime.i64 = this_gpstime.i64;
327  }
328  }
329  else // the last integer difference was *not* zero
330  {
331  if (this_gpstime.i64 == last_gpstime.i64)
332  {
333  // if the doubles have not changed use a special symbol
334  enc->encodeSymbol(m_gpstime_multi, LASZIP_GPSTIME_MULTIMAX-1);
335  }
336  else
337  {
338  // calculate the difference between the two doubles as an integer
339  I64 curr_gpstime_diff_64 = this_gpstime.i64 - last_gpstime.i64;
340  I32 curr_gpstime_diff = (I32)curr_gpstime_diff_64;
341  // if the current gpstime difference can be represented with 32 bits
342  if (curr_gpstime_diff_64 == (I64)(curr_gpstime_diff))
343  {
344  // compute multiplier between current and last integer difference
345  I32 multi = (I32)(((F32)curr_gpstime_diff / (F32)last_gpstime_diff) + 0.5f);
346 
347  // limit the multiplier into some bounds
348  if (multi >= LASZIP_GPSTIME_MULTIMAX-3)
349  {
350  multi = LASZIP_GPSTIME_MULTIMAX-3;
351  }
352  else if (multi <= 0)
353  {
354  multi = 0;
355  }
356  // compress this multiplier
357  enc->encodeSymbol(m_gpstime_multi, multi);
358  // compress the residual curr_gpstime_diff in dependance on the multiplier
359  if (multi == 1)
360  {
361  // this is the case we assume we get most often
362  ic_gpstime->compress(last_gpstime_diff, curr_gpstime_diff, 1);
363  last_gpstime_diff = curr_gpstime_diff;
364  multi_extreme_counter = 0;
365  }
366  else
367  {
368  if (multi == 0)
369  {
370  ic_gpstime->compress(last_gpstime_diff/4, curr_gpstime_diff, 2);
371  multi_extreme_counter++;
372  if (multi_extreme_counter > 3)
373  {
374  last_gpstime_diff = curr_gpstime_diff;
375  multi_extreme_counter = 0;
376  }
377  }
378  else if (multi < 10)
379  {
380  ic_gpstime->compress(multi*last_gpstime_diff, curr_gpstime_diff, 3);
381  }
382  else if (multi < 50)
383  {
384  ic_gpstime->compress(multi*last_gpstime_diff, curr_gpstime_diff, 4);
385  }
386  else
387  {
388  ic_gpstime->compress(multi*last_gpstime_diff, curr_gpstime_diff, 5);
389  if (multi == LASZIP_GPSTIME_MULTIMAX-3)
390  {
391  multi_extreme_counter++;
392  if (multi_extreme_counter > 3)
393  {
394  last_gpstime_diff = curr_gpstime_diff;
395  multi_extreme_counter = 0;
396  }
397  }
398  }
399  }
400  }
401  else
402  {
403  // if difference is so huge ... we simply write the double
404  enc->encodeSymbol(m_gpstime_multi, LASZIP_GPSTIME_MULTIMAX-2);
405  enc->writeInt64(this_gpstime.u64);
406  }
407  last_gpstime.i64 = this_gpstime.i64;
408  }
409  }
410  return TRUE;
411 }
412 
413 /*
414 ===============================================================================
415  LASwriteItemCompressed_RGB12_v1
416 ===============================================================================
417 */
418 
420 {
421  /* set encoder */
422  assert(enc);
423  this->enc = enc;
424 
425  /* create models and integer compressors */
426  m_byte_used = enc->createSymbolModel(64);
427  ic_rgb = new IntegerCompressor(enc, 8, 6);
428 
429  /* create last item */
430  last_item = new U8[6];
431 }
432 
434 {
435  enc->destroySymbolModel(m_byte_used);
436  delete ic_rgb;
437  delete [] last_item;
438 }
439 
441 {
442  /* init state */
443 
444  /* init models and integer compressors */
445  enc->initSymbolModel(m_byte_used);
446  ic_rgb->initCompressor();
447 
448  /* init last item */
449  memcpy(last_item, item, 6);
450  return TRUE;
451 }
452 
454 {
455  U32 sym = ((((U16*)last_item)[0]&0x00FF) != (((U16*)item)[0]&0x00FF)) << 0;
456  sym |= ((((U16*)last_item)[0]&0xFF00) != (((U16*)item)[0]&0xFF00)) << 1;
457  sym |= ((((U16*)last_item)[1]&0x00FF) != (((U16*)item)[1]&0x00FF)) << 2;
458  sym |= ((((U16*)last_item)[1]&0xFF00) != (((U16*)item)[1]&0xFF00)) << 3;
459  sym |= ((((U16*)last_item)[2]&0x00FF) != (((U16*)item)[2]&0x00FF)) << 4;
460  sym |= ((((U16*)last_item)[2]&0xFF00) != (((U16*)item)[2]&0xFF00)) << 5;
461  enc->encodeSymbol(m_byte_used, sym);
462  if (sym & (1 << 0)) ic_rgb->compress(((U16*)last_item)[0]&255,((U16*)item)[0]&255, 0);
463  if (sym & (1 << 1)) ic_rgb->compress(((U16*)last_item)[0]>>8,((U16*)item)[0]>>8, 1);
464  if (sym & (1 << 2)) ic_rgb->compress(((U16*)last_item)[1]&255,((U16*)item)[1]&255, 2);
465  if (sym & (1 << 3)) ic_rgb->compress(((U16*)last_item)[1]>>8,((U16*)item)[1]>>8, 3);
466  if (sym & (1 << 4)) ic_rgb->compress(((U16*)last_item)[2]&255,((U16*)item)[2]&255, 4);
467  if (sym & (1 << 5)) ic_rgb->compress(((U16*)last_item)[2]>>8,((U16*)item)[2]>>8, 5);
468  memcpy(last_item, item, 6);
469  return TRUE;
470 }
471 
472 /*
473 ===============================================================================
474  LASwriteItemCompressed_WAVEPACKET13_v1
475 ===============================================================================
476 */
477 
478 struct LASwavepacket13
479 {
480  U64 offset;
481  U32 packet_size;
482  U32I32F32 return_point;
483  U32I32F32 x;
484  U32I32F32 y;
485  U32I32F32 z;
486 };
487 
489 {
490  /* set encoder */
491  assert(enc);
492  this->enc = enc;
493 
494  /* create models and integer compressors */
495  m_packet_index = enc->createSymbolModel(256);
496  m_offset_diff[0] = enc->createSymbolModel(4);
497  m_offset_diff[1] = enc->createSymbolModel(4);
498  m_offset_diff[2] = enc->createSymbolModel(4);
499  m_offset_diff[3] = enc->createSymbolModel(4);
500  ic_offset_diff = new IntegerCompressor(enc, 32);
501  ic_packet_size = new IntegerCompressor(enc, 32);
502  ic_return_point = new IntegerCompressor(enc, 32);
503  ic_xyz = new IntegerCompressor(enc, 32, 3);
504 
505  /* create last item */
506  last_item = new U8[28];
507 }
508 
510 {
511  enc->destroySymbolModel(m_packet_index);
512  enc->destroySymbolModel(m_offset_diff[0]);
513  enc->destroySymbolModel(m_offset_diff[1]);
514  enc->destroySymbolModel(m_offset_diff[2]);
515  enc->destroySymbolModel(m_offset_diff[3]);
516  delete ic_offset_diff;
517  delete ic_packet_size;
518  delete ic_return_point;
519  delete ic_xyz;
520  delete [] last_item;
521 }
522 
524 {
525  /* init state */
526  last_diff_32 = 0;
527  sym_last_offset_diff = 0;
528 
529  /* init models and integer compressors */
530  enc->initSymbolModel(m_packet_index);
531  enc->initSymbolModel(m_offset_diff[0]);
532  enc->initSymbolModel(m_offset_diff[1]);
533  enc->initSymbolModel(m_offset_diff[2]);
534  enc->initSymbolModel(m_offset_diff[3]);
535  ic_offset_diff->initCompressor();
536  ic_packet_size->initCompressor();
537  ic_return_point->initCompressor();
538  ic_xyz->initCompressor();
539 
540  /* init last item */
541  item++;
542  memcpy(last_item, item, 28);
543  return TRUE;
544 }
545 
547 {
548  enc->encodeSymbol(m_packet_index, (U32)(item[0]));
549  item++;
550 
551  // calculate the difference between the two offsets
552  I64 curr_diff_64 = ((LASwavepacket13*)item)->offset - ((LASwavepacket13*)last_item)->offset;
553  I32 curr_diff_32 = (I32)curr_diff_64;
554  // if the current difference can be represented with 32 bits
555  if (curr_diff_64 == (I64)(curr_diff_32))
556  {
557  if (curr_diff_32 == 0) // current difference is zero
558  {
559  enc->encodeSymbol(m_offset_diff[sym_last_offset_diff], 0);
560  sym_last_offset_diff = 0;
561  }
562  else if (curr_diff_32 == (I32)((LASwavepacket13*)last_item)->packet_size) // current difference is size of last packet
563  {
564  enc->encodeSymbol(m_offset_diff[sym_last_offset_diff], 1);
565  sym_last_offset_diff = 1;
566  }
567  else //
568  {
569  enc->encodeSymbol(m_offset_diff[sym_last_offset_diff], 2);
570  sym_last_offset_diff = 2;
571  ic_offset_diff->compress(last_diff_32, curr_diff_32);
572  last_diff_32 = curr_diff_32;
573  }
574  }
575  else
576  {
577  enc->encodeSymbol(m_offset_diff[sym_last_offset_diff], 3);
578  sym_last_offset_diff = 3;
579  enc->writeInt64(((LASwavepacket13*)item)->offset);
580  }
581  ic_packet_size->compress(((LASwavepacket13*)last_item)->packet_size, ((LASwavepacket13*)item)->packet_size);
582  ic_return_point->compress(((LASwavepacket13*)last_item)->return_point.i32, ((LASwavepacket13*)item)->return_point.i32);
583  ic_xyz->compress(((LASwavepacket13*)last_item)->x.i32, ((LASwavepacket13*)item)->x.i32, 0);
584  ic_xyz->compress(((LASwavepacket13*)last_item)->y.i32, ((LASwavepacket13*)item)->y.i32, 1);
585  ic_xyz->compress(((LASwavepacket13*)last_item)->z.i32, ((LASwavepacket13*)item)->z.i32, 2);
586  memcpy(last_item, item, 28);
587  return TRUE;
588 }
589 
590 /*
591 ===============================================================================
592  LASwriteItemCompressed_BYTE_v1
593 ===============================================================================
594 */
595 
597 {
598  /* set encoder */
599  assert(enc);
600  this->enc = enc;
601  assert(number);
602  this->number = number;
603 
604  /* create models and integer compressors */
605  ic_byte = new IntegerCompressor(enc, 8, number);
606 
607  /* create last item */
608  last_item = new U8[number];
609 }
610 
612 {
613  delete ic_byte;
614  delete [] last_item;
615 }
616 
618 {
619  /* init state */
620 
621  /* init models and integer compressors */
622  ic_byte->initCompressor();
623 
624  /* init last point */
625  memcpy(last_item, item, number);
626  return TRUE;
627 }
628 
630 {
631  U32 i;
632  for (i = 0; i < number; i++)
633  {
634  ic_byte->compress(last_item[i], item[i], i);
635  }
636  memcpy(last_item, item, number);
637  return TRUE;
638 }
int BOOL
Definition: mydefs.hpp:57
I64 i64
Definition: mydefs.hpp:61
float F32
Definition: mydefs.hpp:51
#define LASZIP_GPSTIME_MULTIMAX
unsigned int U32
Definition: mydefs.hpp:39
unsigned short U16
Definition: mydefs.hpp:40
long long I64
Definition: mydefs.hpp:48
unsigned char U8
Definition: mydefs.hpp:41
LASwriteItemCompressed_BYTE_v1(EntropyEncoder *enc, U32 number)
char I8
Definition: mydefs.hpp:37
int I32
Definition: mydefs.hpp:35
virtual EntropyModel * createSymbolModel(U32 n)=0
#define TRUE
Definition: mydefs.hpp:137
U64 u64
Definition: mydefs.hpp:61
unsigned long long U64
Definition: mydefs.hpp:47


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