1 /*
2 ===============================================================================
3 
4   FILE:  lasreaditemcompressed_v3.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_v3.hpp"
33 
34 #include <assert.h>
35 #include <string.h>
36 
37 typedef struct LASpoint14
38 {
39   I32 X;
40   I32 Y;
41   I32 Z;
42   U16 intensity;
43   U8 legacy_return_number : 3;
44   U8 legacy_number_of_returns : 3;
45   U8 scan_direction_flag : 1;
46   U8 edge_of_flight_line : 1;
47   U8 legacy_classification : 5;
48   U8 legacy_flags : 3;
49   I8 legacy_scan_angle_rank;
50   U8 user_data;
51   U16 point_source_ID;
52 
53   // LAS 1.4 only
54   I16 scan_angle;
55   U8 legacy_point_type : 2;
56   U8 scanner_channel : 2;
57   U8 classification_flags : 4;
58   U8 classification;
59   U8 return_number : 4;
60   U8 number_of_returns : 4;
61 
62   // LASlib internal use only
63   U8 deleted_flag;
64 
65   // for 8 byte alignment of the GPS time
66   U8 dummy[2];
67 
68   // compressed LASzip 1.4 points only
69   BOOL gps_time_change;
70 
71   F64 gps_time;
72   U16 rgb[4];
73 //  LASwavepacket wavepacket;
74 } LASpoint14;
75 
76 #define LASZIP_GPSTIME_MULTI 500
77 #define LASZIP_GPSTIME_MULTI_MINUS -10
78 #define LASZIP_GPSTIME_MULTI_CODE_FULL (LASZIP_GPSTIME_MULTI - LASZIP_GPSTIME_MULTI_MINUS + 1)
79 
80 #define LASZIP_GPSTIME_MULTI_TOTAL (LASZIP_GPSTIME_MULTI - LASZIP_GPSTIME_MULTI_MINUS + 5)
81 
LASreadItemCompressed_POINT14_v3(ArithmeticDecoder * dec,const U32 decompress_selective)82 LASreadItemCompressed_POINT14_v3::LASreadItemCompressed_POINT14_v3(ArithmeticDecoder* dec, const U32 decompress_selective)
83 {
84   /* not used as a decoder. just gives access to instream */
85 
86   assert(dec);
87   this->dec = dec;
88 
89   /* zero instreams and decoders */
90 
91   instream_channel_returns_XY = 0;
92   instream_Z = 0;
93   instream_classification = 0;
94   instream_flags = 0;
95   instream_intensity = 0;
96   instream_scan_angle = 0;
97   instream_user_data = 0;
98   instream_point_source = 0;
99   instream_gps_time = 0;
100 
101   dec_channel_returns_XY = 0;
102   dec_Z = 0;
103   dec_classification = 0;
104   dec_flags = 0;
105   dec_intensity = 0;
106   dec_scan_angle = 0;
107   dec_user_data = 0;
108   dec_point_source = 0;
109   dec_gps_time = 0;
110 
111   /* mark the four scanner channel contexts as uninitialized */
112 
113   U32 c;
114   for (c = 0; c < 4; c++)
115   {
116     contexts[c].m_changed_values[0] = 0;
117   }
118   current_context = 0;
119 
120   /* zero num_bytes and init booleans */
121 
122   num_bytes_channel_returns_XY = 0;
123   num_bytes_Z = 0;
124   num_bytes_classification = 0;
125   num_bytes_flags = 0;
126   num_bytes_intensity = 0;
127   num_bytes_scan_angle = 0;
128   num_bytes_user_data = 0;
129   num_bytes_point_source = 0;
130   num_bytes_gps_time = 0;
131 
132   changed_Z = FALSE;
133   changed_classification = FALSE;
134   changed_flags = FALSE;
135   changed_intensity = FALSE;
136   changed_scan_angle = FALSE;
137   changed_user_data = FALSE;
138   changed_point_source = FALSE;
139   changed_gps_time = FALSE;
140 
141   requested_Z = (decompress_selective & LASZIP_DECOMPRESS_SELECTIVE_Z ? TRUE : FALSE);
142   requested_classification = (decompress_selective & LASZIP_DECOMPRESS_SELECTIVE_CLASSIFICATION ? TRUE : FALSE);
143   requested_flags = (decompress_selective & LASZIP_DECOMPRESS_SELECTIVE_FLAGS ? TRUE : FALSE);
144   requested_intensity = (decompress_selective & LASZIP_DECOMPRESS_SELECTIVE_INTENSITY ? TRUE : FALSE);
145   requested_scan_angle = (decompress_selective & LASZIP_DECOMPRESS_SELECTIVE_SCAN_ANGLE ? TRUE : FALSE);
146   requested_user_data = (decompress_selective & LASZIP_DECOMPRESS_SELECTIVE_USER_DATA ? TRUE : FALSE);
147   requested_point_source = (decompress_selective & LASZIP_DECOMPRESS_SELECTIVE_POINT_SOURCE ? TRUE : FALSE);
148   requested_gps_time = (decompress_selective & LASZIP_DECOMPRESS_SELECTIVE_GPS_TIME ? TRUE : FALSE);
149 
150   /* init the bytes buffer to zero */
151 
152   bytes = 0;
153   num_bytes_allocated = 0;
154 }
155 
~LASreadItemCompressed_POINT14_v3()156 LASreadItemCompressed_POINT14_v3::~LASreadItemCompressed_POINT14_v3()
157 {
158   U32 c, i;
159 
160   /* destroy all initialized scanner channel contexts */
161 
162   for (c = 0; c < 4; c++)
163   {
164     if (contexts[c].m_changed_values[0])
165     {
166       dec_channel_returns_XY->destroySymbolModel(contexts[c].m_changed_values[0]);
167       dec_channel_returns_XY->destroySymbolModel(contexts[c].m_changed_values[1]);
168       dec_channel_returns_XY->destroySymbolModel(contexts[c].m_changed_values[2]);
169       dec_channel_returns_XY->destroySymbolModel(contexts[c].m_changed_values[3]);
170       dec_channel_returns_XY->destroySymbolModel(contexts[c].m_changed_values[4]);
171       dec_channel_returns_XY->destroySymbolModel(contexts[c].m_changed_values[5]);
172       dec_channel_returns_XY->destroySymbolModel(contexts[c].m_changed_values[6]);
173       dec_channel_returns_XY->destroySymbolModel(contexts[c].m_changed_values[7]);
174       dec_channel_returns_XY->destroySymbolModel(contexts[c].m_scanner_channel);
175       for (i = 0; i < 16; i++)
176       {
177         if (contexts[c].m_number_of_returns[i]) dec_channel_returns_XY->destroySymbolModel(contexts[c].m_number_of_returns[i]);
178         if (contexts[c].m_return_number[i]) dec_channel_returns_XY->destroySymbolModel(contexts[c].m_return_number[i]);
179       }
180       dec_channel_returns_XY->destroySymbolModel(contexts[c].m_return_number_gps_same);
181       delete contexts[c].ic_dX;
182       delete contexts[c].ic_dY;
183       delete contexts[c].ic_Z;
184       for (i = 0; i < 64; i++)
185       {
186         if (contexts[c].m_classification[i]) dec_classification->destroySymbolModel(contexts[c].m_classification[i]);
187         if (contexts[c].m_flags[i]) dec_flags->destroySymbolModel(contexts[c].m_flags[i]);
188         if (contexts[c].m_user_data[i]) dec_user_data->destroySymbolModel(contexts[c].m_user_data[i]);
189       }
190       delete contexts[c].ic_intensity;
191       delete contexts[c].ic_scan_angle;
192       delete contexts[c].ic_point_source_ID;
193       dec_gps_time->destroySymbolModel(contexts[c].m_gpstime_multi);
194       dec_gps_time->destroySymbolModel(contexts[c].m_gpstime_0diff);
195       delete contexts[c].ic_gpstime;
196     }
197   }
198 
199   /* destroy all decoders and instreams */
200 
201   if (instream_channel_returns_XY)
202   {
203     delete dec_channel_returns_XY;
204     delete dec_Z;
205     delete dec_classification;
206     delete dec_flags;
207     delete dec_intensity;
208     delete dec_scan_angle;
209     delete dec_user_data;
210     delete dec_gps_time;
211 
212     delete instream_channel_returns_XY;
213     delete instream_Z;
214     delete instream_classification;
215     delete instream_flags;
216     delete instream_intensity;
217     delete instream_scan_angle;
218     delete instream_user_data;
219     delete instream_gps_time;
220   }
221 
222   if (bytes) delete [] bytes;
223 }
224 
createAndInitModelsAndDecompressors(U32 context,const U8 * item)225 inline BOOL LASreadItemCompressed_POINT14_v3::createAndInitModelsAndDecompressors(U32 context, const U8* item)
226 {
227   I32 i;
228 
229   /* should only be called when context is unused */
230 
231   assert(contexts[context].unused);
232 
233   /* first create all entropy models and integer decompressors (if needed) */
234 
235   if (contexts[context].m_changed_values[0] == 0)
236   {
237     /* for the channel_returns_XY layer */
238 
239     contexts[context].m_changed_values[0] = dec_channel_returns_XY->createSymbolModel(128);
240     contexts[context].m_changed_values[1] = dec_channel_returns_XY->createSymbolModel(128);
241     contexts[context].m_changed_values[2] = dec_channel_returns_XY->createSymbolModel(128);
242     contexts[context].m_changed_values[3] = dec_channel_returns_XY->createSymbolModel(128);
243     contexts[context].m_changed_values[4] = dec_channel_returns_XY->createSymbolModel(128);
244     contexts[context].m_changed_values[5] = dec_channel_returns_XY->createSymbolModel(128);
245     contexts[context].m_changed_values[6] = dec_channel_returns_XY->createSymbolModel(128);
246     contexts[context].m_changed_values[7] = dec_channel_returns_XY->createSymbolModel(128);
247     contexts[context].m_scanner_channel = dec_channel_returns_XY->createSymbolModel(3);
248     for (i = 0; i < 16; i++)
249     {
250       contexts[context].m_number_of_returns[i] = 0;
251       contexts[context].m_return_number[i] = 0;
252     }
253     contexts[context].m_return_number_gps_same = dec_channel_returns_XY->createSymbolModel(13);
254 
255     contexts[context].ic_dX = new IntegerCompressor(dec_channel_returns_XY, 32, 2);  // 32 bits, 2 context
256     contexts[context].ic_dY = new IntegerCompressor(dec_channel_returns_XY, 32, 22); // 32 bits, 22 contexts
257 
258     /* for the Z layer */
259 
260     contexts[context].ic_Z = new IntegerCompressor(dec_Z, 32, 20);  // 32 bits, 20 contexts
261 
262     /* for the classification layer */
263     /* for the flags layer */
264     /* for the user_data layer */
265 
266     for (i = 0; i < 64; i++)
267     {
268       contexts[context].m_classification[i] = 0;
269       contexts[context].m_flags[i] = 0;
270       contexts[context].m_user_data[i] = 0;
271     }
272 
273     /* for the intensity layer */
274 
275     contexts[context].ic_intensity = new IntegerCompressor(dec_intensity, 16, 4);
276 
277     /* for the scan_angle layer */
278 
279     contexts[context].ic_scan_angle = new IntegerCompressor(dec_scan_angle, 16, 2);
280 
281     /* for the point_source_ID layer */
282 
283     contexts[context].ic_point_source_ID = new IntegerCompressor(dec_point_source, 16);
284 
285     /* for the gps_time layer */
286 
287     contexts[context].m_gpstime_multi = dec_gps_time->createSymbolModel(LASZIP_GPSTIME_MULTI_TOTAL);
288     contexts[context].m_gpstime_0diff = dec_gps_time->createSymbolModel(5);
289     contexts[context].ic_gpstime = new IntegerCompressor(dec_gps_time, 32, 9); // 32 bits, 9 contexts
290   }
291 
292   /* then init entropy models and integer compressors */
293 
294   /* for the channel_returns_XY layer */
295 
296   dec_channel_returns_XY->initSymbolModel(contexts[context].m_changed_values[0]);
297   dec_channel_returns_XY->initSymbolModel(contexts[context].m_changed_values[1]);
298   dec_channel_returns_XY->initSymbolModel(contexts[context].m_changed_values[2]);
299   dec_channel_returns_XY->initSymbolModel(contexts[context].m_changed_values[3]);
300   dec_channel_returns_XY->initSymbolModel(contexts[context].m_changed_values[4]);
301   dec_channel_returns_XY->initSymbolModel(contexts[context].m_changed_values[5]);
302   dec_channel_returns_XY->initSymbolModel(contexts[context].m_changed_values[6]);
303   dec_channel_returns_XY->initSymbolModel(contexts[context].m_changed_values[7]);
304   dec_channel_returns_XY->initSymbolModel(contexts[context].m_scanner_channel);
305   for (i = 0; i < 16; i++)
306   {
307     if (contexts[context].m_number_of_returns[i]) dec_channel_returns_XY->initSymbolModel(contexts[context].m_number_of_returns[i]);
308     if (contexts[context].m_return_number[i]) dec_channel_returns_XY->initSymbolModel(contexts[context].m_return_number[i]);
309   }
310   dec_channel_returns_XY->initSymbolModel(contexts[context].m_return_number_gps_same);
311   contexts[context].ic_dX->initDecompressor();
312   contexts[context].ic_dY->initDecompressor();
313   for (i = 0; i < 12; i++)
314   {
315     contexts[context].last_X_diff_median5[i].init();
316     contexts[context].last_Y_diff_median5[i].init();
317   }
318 
319   /* for the Z layer */
320 
321   contexts[context].ic_Z->initDecompressor();
322   for (i = 0; i < 8; i++)
323   {
324     contexts[context].last_Z[i] = ((LASpoint14*)item)->Z;
325   }
326 
327   /* for the classification layer */
328   /* for the flags layer */
329   /* for the user_data layer */
330 
331   for (i = 0; i < 64; i++)
332   {
333     if (contexts[context].m_classification[i]) dec_classification->initSymbolModel(contexts[context].m_classification[i]);
334     if (contexts[context].m_flags[i]) dec_flags->initSymbolModel(contexts[context].m_flags[i]);
335     if (contexts[context].m_user_data[i]) dec_user_data->initSymbolModel(contexts[context].m_user_data[i]);
336   }
337 
338   /* for the intensity layer */
339 
340   contexts[context].ic_intensity->initDecompressor();
341   for (i = 0; i < 8; i++)
342   {
343     contexts[context].last_intensity[i] = ((LASpoint14*)item)->intensity;
344   }
345 
346   /* for the scan_angle layer */
347 
348   contexts[context].ic_scan_angle->initDecompressor();
349 
350   /* for the point_source_ID layer */
351 
352   contexts[context].ic_point_source_ID->initDecompressor();
353 
354   /* for the gps_time layer */
355 
356   dec_gps_time->initSymbolModel(contexts[context].m_gpstime_multi);
357   dec_gps_time->initSymbolModel(contexts[context].m_gpstime_0diff);
358   contexts[context].ic_gpstime->initDecompressor();
359   contexts[context].last = 0, contexts[context].next = 0;
360   contexts[context].last_gpstime_diff[0] = 0;
361   contexts[context].last_gpstime_diff[1] = 0;
362   contexts[context].last_gpstime_diff[2] = 0;
363   contexts[context].last_gpstime_diff[3] = 0;
364   contexts[context].multi_extreme_counter[0] = 0;
365   contexts[context].multi_extreme_counter[1] = 0;
366   contexts[context].multi_extreme_counter[2] = 0;
367   contexts[context].multi_extreme_counter[3] = 0;
368   contexts[context].last_gpstime[0].f64 = ((LASpoint14*)item)->gps_time;
369   contexts[context].last_gpstime[1].u64 = 0;
370   contexts[context].last_gpstime[2].u64 = 0;
371   contexts[context].last_gpstime[3].u64 = 0;
372 
373   /* init current context from last item */
374 
375   memcpy(contexts[context].last_item, item, sizeof(LASpoint14));
376   ((LASpoint14*)contexts[context].last_item)->gps_time_change = FALSE;
377 
378 //  fprintf(stderr, "INIT: current_context %d last item %.14g %d %d %d %d %d %d\n", current_context, ((LASpoint14*)item)->gps_time, ((LASpoint14*)item)->X, ((LASpoint14*)item)->Y, ((LASpoint14*)item)->Z, ((LASpoint14*)item)->intensity, ((LASpoint14*)item)->return_number, ((LASpoint14*)item)->number_of_returns);
379 
380   contexts[context].unused = FALSE;
381 
382   return TRUE;
383 }
384 
chunk_sizes()385 BOOL LASreadItemCompressed_POINT14_v3::chunk_sizes()
386 {
387   /* for layered compression 'dec' only hands over the stream */
388 
389   ByteStreamIn* instream = dec->getByteStreamIn();
390 
391   /* read bytes per layer */
392 
393   instream->get32bitsLE(((U8*)&num_bytes_channel_returns_XY));
394   instream->get32bitsLE(((U8*)&num_bytes_Z));
395   instream->get32bitsLE(((U8*)&num_bytes_classification));
396   instream->get32bitsLE(((U8*)&num_bytes_flags));
397   instream->get32bitsLE(((U8*)&num_bytes_intensity));
398   instream->get32bitsLE(((U8*)&num_bytes_scan_angle));
399   instream->get32bitsLE(((U8*)&num_bytes_user_data));
400   instream->get32bitsLE(((U8*)&num_bytes_point_source));
401   instream->get32bitsLE(((U8*)&num_bytes_gps_time));
402 
403   return TRUE;
404 }
405 
init(const U8 * item,U32 & context)406 BOOL LASreadItemCompressed_POINT14_v3::init(const U8* item, U32& context)
407 {
408   /* for layered compression 'dec' only hands over the stream */
409 
410   ByteStreamIn* instream = dec->getByteStreamIn();
411 
412   /* on the first init create instreams and decoders */
413 
414   if (instream_channel_returns_XY == 0)
415   {
416     /* create instreams */
417 
418     if (IS_LITTLE_ENDIAN())
419     {
420       instream_channel_returns_XY = new ByteStreamInArrayLE();
421       instream_Z = new ByteStreamInArrayLE();
422       instream_classification = new ByteStreamInArrayLE();
423       instream_flags = new ByteStreamInArrayLE();
424       instream_intensity = new ByteStreamInArrayLE();
425       instream_scan_angle = new ByteStreamInArrayLE();
426       instream_user_data = new ByteStreamInArrayLE();
427       instream_point_source = new ByteStreamInArrayLE();
428       instream_gps_time = new ByteStreamInArrayLE();
429     }
430     else
431     {
432       instream_channel_returns_XY = new ByteStreamInArrayBE();
433       instream_Z = new ByteStreamInArrayBE();
434       instream_classification = new ByteStreamInArrayBE();
435       instream_flags = new ByteStreamInArrayBE();
436       instream_intensity = new ByteStreamInArrayBE();
437       instream_scan_angle = new ByteStreamInArrayBE();
438       instream_user_data = new ByteStreamInArrayBE();
439       instream_point_source = new ByteStreamInArrayBE();
440       instream_gps_time = new ByteStreamInArrayBE();
441     }
442 
443     /* create decoders */
444 
445     dec_channel_returns_XY = new ArithmeticDecoder();
446     dec_Z = new ArithmeticDecoder();
447     dec_classification = new ArithmeticDecoder();
448     dec_flags = new ArithmeticDecoder();
449     dec_intensity = new ArithmeticDecoder();
450     dec_scan_angle = new ArithmeticDecoder();
451     dec_user_data = new ArithmeticDecoder();
452     dec_point_source = new ArithmeticDecoder();
453     dec_gps_time = new ArithmeticDecoder();
454   }
455 
456   /* how many bytes do we need to read */
457 
458   U32 num_bytes = num_bytes_channel_returns_XY;
459   if (requested_Z) num_bytes += num_bytes_Z;
460   if (requested_classification) num_bytes += num_bytes_classification;
461   if (requested_flags) num_bytes += num_bytes_flags;
462   if (requested_intensity) num_bytes += num_bytes_intensity;
463   if (requested_scan_angle) num_bytes += num_bytes_scan_angle;
464   if (requested_user_data) num_bytes += num_bytes_user_data;
465   if (requested_point_source) num_bytes += num_bytes_point_source;
466   if (requested_gps_time) num_bytes += num_bytes_gps_time;
467 
468   /* make sure the buffer is sufficiently large */
469 
470   if (num_bytes > num_bytes_allocated)
471   {
472     if (bytes) delete [] bytes;
473     bytes = new U8[num_bytes];
474     if (bytes == 0) return FALSE;
475     num_bytes_allocated = num_bytes;
476   }
477 
478   /* load the requested bytes and init the corresponding instreams and decoders */
479 
480   num_bytes = 0;
481   instream->getBytes(bytes, num_bytes_channel_returns_XY);
482   instream_channel_returns_XY->init(bytes, num_bytes_channel_returns_XY);
483   dec_channel_returns_XY->init(instream_channel_returns_XY);
484   num_bytes += num_bytes_channel_returns_XY;
485 
486   if (requested_Z)
487   {
488     if (num_bytes_Z)
489     {
490       instream->getBytes(&(bytes[num_bytes]), num_bytes_Z);
491       instream_Z->init(&(bytes[num_bytes]), num_bytes_Z);
492       dec_Z->init(instream_Z);
493       num_bytes += num_bytes_Z;
494       changed_Z = TRUE;
495     }
496     else
497     {
498       instream_Z->init(0, 0);
499       changed_Z = FALSE;
500     }
501   }
502   else
503   {
504     if (num_bytes_Z)
505     {
506       instream->skipBytes(num_bytes_Z);
507     }
508     changed_Z = FALSE;
509   }
510 
511   if (requested_classification)
512   {
513     if (num_bytes_classification)
514     {
515       instream->getBytes(&(bytes[num_bytes]), num_bytes_classification);
516       instream_classification->init(&(bytes[num_bytes]), num_bytes_classification);
517       dec_classification->init(instream_classification);
518       num_bytes += num_bytes_classification;
519       changed_classification = TRUE;
520     }
521     else
522     {
523       instream_classification->init(0, 0);
524       changed_classification = FALSE;
525     }
526   }
527   else
528   {
529     if (num_bytes_classification)
530     {
531       instream->skipBytes(num_bytes_classification);
532     }
533     changed_classification = FALSE;
534   }
535 
536   if (requested_flags)
537   {
538     if (num_bytes_flags)
539     {
540       instream->getBytes(&(bytes[num_bytes]), num_bytes_flags);
541       instream_flags->init(&(bytes[num_bytes]), num_bytes_flags);
542       dec_flags->init(instream_flags);
543       num_bytes += num_bytes_flags;
544       changed_flags = TRUE;
545     }
546     else
547     {
548       instream_flags->init(0, 0);
549       changed_flags = FALSE;
550     }
551   }
552   else
553   {
554     if (num_bytes_flags)
555     {
556       instream->skipBytes(num_bytes_flags);
557     }
558     changed_flags = FALSE;
559   }
560 
561   if (requested_intensity)
562   {
563     if (num_bytes_intensity)
564     {
565       instream->getBytes(&(bytes[num_bytes]), num_bytes_intensity);
566       instream_intensity->init(&(bytes[num_bytes]), num_bytes_intensity);
567       dec_intensity->init(instream_intensity);
568       num_bytes += num_bytes_intensity;
569       changed_intensity = TRUE;
570     }
571     else
572     {
573       instream_intensity->init(0, 0);
574       changed_intensity = FALSE;
575     }
576   }
577   else
578   {
579     if (num_bytes_intensity)
580     {
581       instream->skipBytes(num_bytes_intensity);
582     }
583     changed_intensity = FALSE;
584   }
585 
586   if (requested_scan_angle)
587   {
588     if (num_bytes_scan_angle)
589     {
590       instream->getBytes(&(bytes[num_bytes]), num_bytes_scan_angle);
591       instream_scan_angle->init(&(bytes[num_bytes]), num_bytes_scan_angle);
592       dec_scan_angle->init(instream_scan_angle);
593       num_bytes += num_bytes_scan_angle;
594       changed_scan_angle = TRUE;
595     }
596     else
597     {
598       instream_scan_angle->init(0, 0);
599       changed_scan_angle = FALSE;
600     }
601   }
602   else
603   {
604     if (num_bytes_scan_angle)
605     {
606       instream->skipBytes(num_bytes_scan_angle);
607     }
608     changed_scan_angle = FALSE;
609   }
610 
611   if (requested_user_data)
612   {
613     if (num_bytes_user_data)
614     {
615       instream->getBytes(&(bytes[num_bytes]), num_bytes_user_data);
616       instream_user_data->init(&(bytes[num_bytes]), num_bytes_user_data);
617       dec_user_data->init(instream_user_data);
618       num_bytes += num_bytes_user_data;
619       changed_user_data = TRUE;
620     }
621     else
622     {
623       instream_user_data->init(0, 0);
624       changed_user_data = FALSE;
625     }
626   }
627   else
628   {
629     if (num_bytes_user_data)
630     {
631       instream->skipBytes(num_bytes_user_data);
632     }
633     changed_user_data = FALSE;
634   }
635 
636   if (requested_point_source)
637   {
638     if (num_bytes_point_source)
639     {
640       instream->getBytes(&(bytes[num_bytes]), num_bytes_point_source);
641       instream_point_source->init(&(bytes[num_bytes]), num_bytes_point_source);
642       dec_point_source->init(instream_point_source);
643       num_bytes += num_bytes_point_source;
644       changed_point_source = TRUE;
645     }
646     else
647     {
648       instream_point_source->init(0, 0);
649       changed_point_source = FALSE;
650     }
651   }
652   else
653   {
654     if (num_bytes_point_source)
655     {
656       instream->skipBytes(num_bytes_point_source);
657     }
658     changed_point_source = FALSE;
659   }
660 
661   if (requested_gps_time)
662   {
663     if (num_bytes_gps_time)
664     {
665       instream->getBytes(&(bytes[num_bytes]), num_bytes_gps_time);
666       instream_gps_time->init(&(bytes[num_bytes]), num_bytes_gps_time);
667       dec_gps_time->init(instream_gps_time);
668       num_bytes += num_bytes_gps_time;
669       changed_gps_time = TRUE;
670     }
671     else
672     {
673       instream_gps_time->init(0, 0);
674       changed_gps_time = FALSE;
675     }
676   }
677   else
678   {
679     if (num_bytes_gps_time)
680     {
681       instream->skipBytes(num_bytes_gps_time);
682     }
683     changed_gps_time = FALSE;
684   }
685 
686   /* mark the four scanner channel contexts as unused */
687 
688   U32 c;
689   for (c = 0; c < 4; c++)
690   {
691     contexts[c].unused = TRUE;
692   }
693 
694   /* set scanner channel as current context */
695 
696   current_context = ((LASpoint14*)item)->scanner_channel;
697   context = current_context; // the POINT14 reader sets context for all other items
698 
699   /* create and init models and decompressors */
700 
701   createAndInitModelsAndDecompressors(current_context, item);
702 
703   return TRUE;
704 }
705 
read(U8 * item,U32 & context)706 inline void LASreadItemCompressed_POINT14_v3::read(U8* item, U32& context)
707 {
708   // get last
709 
710   U8* last_item = contexts[current_context].last_item;
711 
712   ////////////////////////////////////////
713   // decompress returns_XY layer
714   ////////////////////////////////////////
715 
716   // create single (3) / first (1) / last (2) / intermediate (0) context from last point return
717 
718   I32 lpr = (((LASpoint14*)last_item)->return_number == 1 ? 1 : 0); // first?
719   lpr += (((LASpoint14*)last_item)->return_number >= ((LASpoint14*)last_item)->number_of_returns ? 2 : 0); // last?
720 
721   // add info whether the GPS time changed in the last return to the context
722 
723   lpr += (((LASpoint14*)last_item)->gps_time_change ? 4 : 0);
724 
725   // decompress which values have changed with last point return context
726 
727   I32 changed_values = dec_channel_returns_XY->decodeSymbol(contexts[current_context].m_changed_values[lpr]);
728 
729   // if scanner channel has changed
730 
731   if (changed_values & (1 << 6))
732   {
733     U32 diff = dec_channel_returns_XY->decodeSymbol(contexts[current_context].m_scanner_channel); // curr = last + (sym + 1)
734     U32 scanner_channel = (current_context + diff + 1) % 4;
735     // maybe create and init entropy models and integer compressors
736     if (contexts[scanner_channel].unused)
737     {
738       // create and init entropy models and integer decompressors
739       createAndInitModelsAndDecompressors(scanner_channel, contexts[current_context].last_item);
740     }
741     // switch context to current scanner channel
742     current_context = scanner_channel;
743     context = current_context; // the POINT14 reader sets context for all other items
744 
745     // get last for new context
746     last_item = contexts[current_context].last_item;
747     ((LASpoint14*)last_item)->scanner_channel = scanner_channel;
748   }
749 
750   // determine changed attributes
751 
752   BOOL point_source_change = (changed_values & (1 << 5) ? TRUE : FALSE);
753   BOOL gps_time_change = (changed_values & (1 << 4) ? TRUE : FALSE);
754   BOOL scan_angle_change = (changed_values & (1 << 3) ? TRUE : FALSE);
755 
756   // get last return counts
757 
758   U32 last_n = ((LASpoint14*)last_item)->number_of_returns;
759   U32 last_r = ((LASpoint14*)last_item)->return_number;
760 
761   // if number of returns is different we decompress it
762 
763   U32 n;
764   if (changed_values & (1 << 2))
765   {
766     if (contexts[current_context].m_number_of_returns[last_n] == 0)
767     {
768       contexts[current_context].m_number_of_returns[last_n] = dec_channel_returns_XY->createSymbolModel(16);
769       dec_channel_returns_XY->initSymbolModel(contexts[current_context].m_number_of_returns[last_n]);
770     }
771     n = dec_channel_returns_XY->decodeSymbol(contexts[current_context].m_number_of_returns[last_n]);
772     ((LASpoint14*)last_item)->number_of_returns = n;
773   }
774   else
775   {
776     n = last_n;
777   }
778 
779   // how is the return number different
780 
781   U32 r;
782   if ((changed_values & 3) == 0) // same return number
783   {
784     r = last_r;
785   }
786   else if ((changed_values & 3) == 1) // return number plus 1 mod 16
787   {
788     r = ((last_r + 1) % 16);
789     ((LASpoint14*)last_item)->return_number = r;
790   }
791   else if ((changed_values & 3) == 2) // return number minus 1 mod 16
792   {
793     r = ((last_r + 15) % 16);
794     ((LASpoint14*)last_item)->return_number = r;
795   }
796   else
797   {
798     // the return number difference is bigger than +1 / -1 so we decompress how it is different
799 
800     if (gps_time_change) // if the GPS time has changed
801     {
802       if (contexts[current_context].m_return_number[last_r] == 0)
803       {
804         contexts[current_context].m_return_number[last_r] = dec_channel_returns_XY->createSymbolModel(16);
805         dec_channel_returns_XY->initSymbolModel(contexts[current_context].m_return_number[last_r]);
806       }
807       r = dec_channel_returns_XY->decodeSymbol(contexts[current_context].m_return_number[last_r]);
808     }
809     else // if the GPS time has not changed
810     {
811       I32 sym = dec_channel_returns_XY->decodeSymbol(contexts[current_context].m_return_number_gps_same);
812       r = (last_r + (sym + 2)) % 16;
813     }
814     ((LASpoint14*)last_item)->return_number = r;
815   }
816 
817   // set legacy return counts and number of returns
818 
819   if (n > 7)
820   {
821     if (r > 6)
822     {
823       if (r >= n)
824       {
825         ((LASpoint14*)last_item)->legacy_return_number = 7;
826       }
827       else
828       {
829         ((LASpoint14*)last_item)->legacy_return_number = 6;
830       }
831     }
832     else
833     {
834       ((LASpoint14*)last_item)->legacy_return_number = r;
835     }
836     ((LASpoint14*)last_item)->legacy_number_of_returns = 7;
837   }
838   else
839   {
840     ((LASpoint14*)last_item)->legacy_return_number = r;
841     ((LASpoint14*)last_item)->legacy_number_of_returns = n;
842   }
843 
844   // get return map m and return level l context for current point
845 
846   U32 m = number_return_map_6ctx[n][r];
847   U32 l = number_return_level_8ctx[n][r];
848 
849   // create single (3) / first (1) / last (2) / intermediate (0) return context for current point
850 
851   I32 cpr = (r == 1 ? 2 : 0); // first ?
852   cpr += (r >= n ? 1 : 0); // last ?
853 
854   U32 k_bits;
855   I32 median, diff;
856 
857   // decompress X coordinate
858   median = contexts[current_context].last_X_diff_median5[(m<<1) | gps_time_change].get();
859   diff = contexts[current_context].ic_dX->decompress(median, n==1);
860   ((LASpoint14*)last_item)->X += diff;
861   contexts[current_context].last_X_diff_median5[(m<<1) | gps_time_change].add(diff);
862 
863   // decompress Y coordinate
864   median = contexts[current_context].last_Y_diff_median5[(m<<1) | gps_time_change].get();
865   k_bits = contexts[current_context].ic_dX->getK();
866   diff = contexts[current_context].ic_dY->decompress(median, (n==1) + ( k_bits < 20 ? U32_ZERO_BIT_0(k_bits) : 20 ));
867   ((LASpoint14*)last_item)->Y += diff;
868   contexts[current_context].last_Y_diff_median5[(m<<1) | gps_time_change].add(diff);
869 
870   ////////////////////////////////////////
871   // decompress Z layer (if changed and requested)
872   ////////////////////////////////////////
873 
874   if (changed_Z) // if the Z coordinate should be decompressed and changes within this chunk
875   {
876     k_bits = (contexts[current_context].ic_dX->getK() + contexts[current_context].ic_dY->getK()) / 2;
877     ((LASpoint14*)last_item)->Z = contexts[current_context].ic_Z->decompress(contexts[current_context].last_Z[l], (n==1) + (k_bits < 18 ? U32_ZERO_BIT_0(k_bits) : 18));
878     contexts[current_context].last_Z[l] = ((LASpoint14*)last_item)->Z;
879   }
880 
881   ////////////////////////////////////////
882   // decompress classifications layer (if changed and requested)
883   ////////////////////////////////////////
884 
885   if (changed_classification) // if the classification should be decompressed and changes within this chunk
886   {
887     U32 last_classification = ((LASpoint14*)last_item)->classification;
888     I32 ccc = ((last_classification & 0x1F) << 1) + (cpr == 3 ? 1 : 0);
889     if (contexts[current_context].m_classification[ccc] == 0)
890     {
891       contexts[current_context].m_classification[ccc] = dec_classification->createSymbolModel(256);
892       dec_classification->initSymbolModel(contexts[current_context].m_classification[ccc]);
893     }
894     ((LASpoint14*)last_item)->classification = dec_classification->decodeSymbol(contexts[current_context].m_classification[ccc]);
895 
896     // update the legacy copy
897     if (((LASpoint14*)last_item)->classification < 32)
898     {
899       ((LASpoint14*)last_item)->legacy_classification = ((LASpoint14*)last_item)->classification;
900     }
901     else
902     {
903       ((LASpoint14*)last_item)->legacy_classification = 0;
904     }
905   }
906 
907   ////////////////////////////////////////
908   // decompress flags layer (if changed and requested)
909   ////////////////////////////////////////
910 
911   if (changed_flags) // if the flags should be decompressed and change within this chunk
912   {
913     U32 last_flags = (((LASpoint14*)last_item)->edge_of_flight_line << 5) | (((LASpoint14*)last_item)->scan_direction_flag << 4) | ((LASpoint14*)last_item)->classification_flags;
914     if (contexts[current_context].m_flags[last_flags] == 0)
915     {
916       contexts[current_context].m_flags[last_flags] = dec_flags->createSymbolModel(64);
917       dec_flags->initSymbolModel(contexts[current_context].m_flags[last_flags]);
918     }
919     U32 flags = dec_flags->decodeSymbol(contexts[current_context].m_flags[last_flags]);
920     ((LASpoint14*)last_item)->edge_of_flight_line = !!(flags & (1 << 5));
921     ((LASpoint14*)last_item)->scan_direction_flag = !!(flags & (1 << 4));
922     ((LASpoint14*)last_item)->classification_flags = (flags & 0x0F);
923 
924     // legacy copies
925     ((LASpoint14*)last_item)->legacy_flags = (flags & 0x07);
926   }
927 
928   ////////////////////////////////////////
929   // decompress intensity layer (if changed and requested)
930   ////////////////////////////////////////
931 
932   if (changed_intensity) // if the intensity should be decompressed and changes within this chunk
933   {
934     U16 intensity = contexts[current_context].ic_intensity->decompress(contexts[current_context].last_intensity[(cpr<<1) | gps_time_change], cpr);
935     contexts[current_context].last_intensity[(cpr<<1) | gps_time_change] = intensity;
936     ((LASpoint14*)last_item)->intensity = intensity;
937   }
938 
939   ////////////////////////////////////////
940   // decompress scan_angle layer (if changed and requested)
941   ////////////////////////////////////////
942 
943   if (changed_scan_angle) // if the scan angle should be decompressed and changes within this chunk
944   {
945     if (scan_angle_change) // if the scan angle has actually changed
946     {
947       ((LASpoint14*)last_item)->scan_angle = contexts[current_context].ic_scan_angle->decompress(((LASpoint14*)last_item)->scan_angle, gps_time_change); // if the GPS time has changed
948       ((LASpoint14*)last_item)->legacy_scan_angle_rank = I8_CLAMP(I16_QUANTIZE(0.006f*((LASpoint14*)last_item)->scan_angle));
949     }
950   }
951 
952   ////////////////////////////////////////
953   // decompress user_data layer (if changed and requested)
954   ////////////////////////////////////////
955 
956   if (changed_user_data) // if the user data should be decompressed and changes within this chunk
957   {
958     if (contexts[current_context].m_user_data[((LASpoint14*)last_item)->user_data/4] == 0)
959     {
960       contexts[current_context].m_user_data[((LASpoint14*)last_item)->user_data/4] = dec_user_data->createSymbolModel(256);
961       dec_user_data->initSymbolModel(contexts[current_context].m_user_data[((LASpoint14*)last_item)->user_data/4]);
962     }
963     ((LASpoint14*)last_item)->user_data = dec_user_data->decodeSymbol(contexts[current_context].m_user_data[((LASpoint14*)last_item)->user_data/4]);
964   }
965 
966   ////////////////////////////////////////
967   // decompress point_source layer (if changed and requested)
968   ////////////////////////////////////////
969 
970   if (changed_point_source) // if the point source ID should be decompressed and changes within this chunk
971   {
972     if (point_source_change) // if the point source ID has actually changed
973     {
974       ((LASpoint14*)last_item)->point_source_ID = contexts[current_context].ic_point_source_ID->decompress(((LASpoint14*)last_item)->point_source_ID);
975     }
976   }
977 
978   ////////////////////////////////////////
979   // decompress gps_time layer (if changed and requested)
980   ////////////////////////////////////////
981 
982   if (changed_gps_time) // if the GPS time should be decompressed and changes within this chunk
983   {
984     if (gps_time_change) // if the GPS time has actually changed
985     {
986       read_gps_time();
987       ((LASpoint14*)last_item)->gps_time = contexts[current_context].last_gpstime[contexts[current_context].last].f64;
988     }
989   }
990 
991   // copy the last item
992   memcpy(item, last_item, sizeof(LASpoint14));
993   // remember if the last point had a gps_time_change
994   ((LASpoint14*)last_item)->gps_time_change = gps_time_change;
995 }
996 
read_gps_time()997 void LASreadItemCompressed_POINT14_v3::read_gps_time()
998 {
999   I32 multi;
1000   if (contexts[current_context].last_gpstime_diff[contexts[current_context].last] == 0) // if the last integer difference was zero
1001   {
1002     multi = dec_gps_time->decodeSymbol(contexts[current_context].m_gpstime_0diff);
1003     if (multi == 0) // the difference can be represented with 32 bits
1004     {
1005       contexts[current_context].last_gpstime_diff[contexts[current_context].last] = contexts[current_context].ic_gpstime->decompress(0, 0);
1006       contexts[current_context].last_gpstime[contexts[current_context].last].i64 += contexts[current_context].last_gpstime_diff[contexts[current_context].last];
1007       contexts[current_context].multi_extreme_counter[contexts[current_context].last] = 0;
1008     }
1009     else if (multi == 1) // the difference is huge
1010     {
1011       contexts[current_context].next = (contexts[current_context].next+1)&3;
1012       contexts[current_context].last_gpstime[contexts[current_context].next].u64 = contexts[current_context].ic_gpstime->decompress((I32)(contexts[current_context].last_gpstime[contexts[current_context].last].u64 >> 32), 8);
1013       contexts[current_context].last_gpstime[contexts[current_context].next].u64 = contexts[current_context].last_gpstime[contexts[current_context].next].u64 << 32;
1014       contexts[current_context].last_gpstime[contexts[current_context].next].u64 |= dec_gps_time->readInt();
1015       contexts[current_context].last = contexts[current_context].next;
1016       contexts[current_context].last_gpstime_diff[contexts[current_context].last] = 0;
1017       contexts[current_context].multi_extreme_counter[contexts[current_context].last] = 0;
1018     }
1019     else // we switch to another sequence
1020     {
1021       contexts[current_context].last = (contexts[current_context].last+multi-1)&3;
1022       read_gps_time();
1023     }
1024   }
1025   else
1026   {
1027     multi = dec_gps_time->decodeSymbol(contexts[current_context].m_gpstime_multi);
1028     if (multi == 1)
1029     {
1030       contexts[current_context].last_gpstime[contexts[current_context].last].i64 += contexts[current_context].ic_gpstime->decompress(contexts[current_context].last_gpstime_diff[contexts[current_context].last], 1);;
1031       contexts[current_context].multi_extreme_counter[contexts[current_context].last] = 0;
1032     }
1033     else if (multi < LASZIP_GPSTIME_MULTI_CODE_FULL)
1034     {
1035       I32 gpstime_diff;
1036       if (multi == 0)
1037       {
1038         gpstime_diff = contexts[current_context].ic_gpstime->decompress(0, 7);
1039         contexts[current_context].multi_extreme_counter[contexts[current_context].last]++;
1040         if (contexts[current_context].multi_extreme_counter[contexts[current_context].last] > 3)
1041         {
1042           contexts[current_context].last_gpstime_diff[contexts[current_context].last] = gpstime_diff;
1043           contexts[current_context].multi_extreme_counter[contexts[current_context].last] = 0;
1044         }
1045       }
1046       else if (multi < LASZIP_GPSTIME_MULTI)
1047       {
1048         if (multi < 10)
1049           gpstime_diff = contexts[current_context].ic_gpstime->decompress(multi*contexts[current_context].last_gpstime_diff[contexts[current_context].last], 2);
1050         else
1051           gpstime_diff = contexts[current_context].ic_gpstime->decompress(multi*contexts[current_context].last_gpstime_diff[contexts[current_context].last], 3);
1052       }
1053       else if (multi == LASZIP_GPSTIME_MULTI)
1054       {
1055         gpstime_diff = contexts[current_context].ic_gpstime->decompress(LASZIP_GPSTIME_MULTI*contexts[current_context].last_gpstime_diff[contexts[current_context].last], 4);
1056         contexts[current_context].multi_extreme_counter[contexts[current_context].last]++;
1057         if (contexts[current_context].multi_extreme_counter[contexts[current_context].last] > 3)
1058         {
1059           contexts[current_context].last_gpstime_diff[contexts[current_context].last] = gpstime_diff;
1060           contexts[current_context].multi_extreme_counter[contexts[current_context].last] = 0;
1061         }
1062       }
1063       else
1064       {
1065         multi = LASZIP_GPSTIME_MULTI - multi;
1066         if (multi > LASZIP_GPSTIME_MULTI_MINUS)
1067         {
1068           gpstime_diff = contexts[current_context].ic_gpstime->decompress(multi*contexts[current_context].last_gpstime_diff[contexts[current_context].last], 5);
1069         }
1070         else
1071         {
1072           gpstime_diff = contexts[current_context].ic_gpstime->decompress(LASZIP_GPSTIME_MULTI_MINUS*contexts[current_context].last_gpstime_diff[contexts[current_context].last], 6);
1073           contexts[current_context].multi_extreme_counter[contexts[current_context].last]++;
1074           if (contexts[current_context].multi_extreme_counter[contexts[current_context].last] > 3)
1075           {
1076             contexts[current_context].last_gpstime_diff[contexts[current_context].last] = gpstime_diff;
1077             contexts[current_context].multi_extreme_counter[contexts[current_context].last] = 0;
1078           }
1079         }
1080       }
1081       contexts[current_context].last_gpstime[contexts[current_context].last].i64 += gpstime_diff;
1082     }
1083     else if (multi ==  LASZIP_GPSTIME_MULTI_CODE_FULL)
1084     {
1085       contexts[current_context].next = (contexts[current_context].next+1)&3;
1086       contexts[current_context].last_gpstime[contexts[current_context].next].u64 = contexts[current_context].ic_gpstime->decompress((I32)(contexts[current_context].last_gpstime[contexts[current_context].last].u64 >> 32), 8);
1087       contexts[current_context].last_gpstime[contexts[current_context].next].u64 = contexts[current_context].last_gpstime[contexts[current_context].next].u64 << 32;
1088       contexts[current_context].last_gpstime[contexts[current_context].next].u64 |= dec_gps_time->readInt();
1089       contexts[current_context].last = contexts[current_context].next;
1090       contexts[current_context].last_gpstime_diff[contexts[current_context].last] = 0;
1091       contexts[current_context].multi_extreme_counter[contexts[current_context].last] = 0;
1092     }
1093     else if (multi >=  LASZIP_GPSTIME_MULTI_CODE_FULL)
1094     {
1095       contexts[current_context].last = (contexts[current_context].last+multi-LASZIP_GPSTIME_MULTI_CODE_FULL)&3;
1096       read_gps_time();
1097     }
1098   }
1099 }
1100 
1101 /*
1102 ===============================================================================
1103                        LASreadItemCompressed_RGB14_v3
1104 ===============================================================================
1105 */
1106 
LASreadItemCompressed_RGB14_v3(ArithmeticDecoder * dec,const U32 decompress_selective)1107 LASreadItemCompressed_RGB14_v3::LASreadItemCompressed_RGB14_v3(ArithmeticDecoder* dec, const U32 decompress_selective)
1108 {
1109   /* not used as a decoder. just gives access to instream */
1110 
1111   assert(dec);
1112   this->dec = dec;
1113 
1114   /* zero instreams and decoders */
1115 
1116   instream_RGB = 0;
1117 
1118   dec_RGB = 0;
1119 
1120   /* zero num_bytes and init booleans */
1121 
1122   num_bytes_RGB = 0;
1123 
1124   changed_RGB = FALSE;
1125 
1126   requested_RGB = (decompress_selective & LASZIP_DECOMPRESS_SELECTIVE_RGB ? TRUE : FALSE);
1127 
1128   /* init the bytes buffer to zero */
1129 
1130   bytes = 0;
1131   num_bytes_allocated = 0;
1132 
1133   /* mark the four scanner channel contexts as uninitialized */
1134 
1135   U32 c;
1136   for (c = 0; c < 4; c++)
1137   {
1138     contexts[c].m_byte_used = 0;
1139   }
1140   current_context = 0;
1141 }
1142 
~LASreadItemCompressed_RGB14_v3()1143 LASreadItemCompressed_RGB14_v3::~LASreadItemCompressed_RGB14_v3()
1144 {
1145   /* destroy all initialized scanner channel contexts */
1146 
1147   U32 c;
1148   for (c = 0; c < 4; c++)
1149   {
1150     if (contexts[c].m_byte_used)
1151     {
1152       dec_RGB->destroySymbolModel(contexts[c].m_byte_used);
1153       dec_RGB->destroySymbolModel(contexts[c].m_rgb_diff_0);
1154       dec_RGB->destroySymbolModel(contexts[c].m_rgb_diff_1);
1155       dec_RGB->destroySymbolModel(contexts[c].m_rgb_diff_2);
1156       dec_RGB->destroySymbolModel(contexts[c].m_rgb_diff_3);
1157       dec_RGB->destroySymbolModel(contexts[c].m_rgb_diff_4);
1158       dec_RGB->destroySymbolModel(contexts[c].m_rgb_diff_5);
1159     }
1160   }
1161 
1162   /* destroy all instreams and decoders */
1163 
1164   if (instream_RGB)
1165   {
1166     delete instream_RGB;
1167 
1168     delete dec_RGB;
1169   }
1170 
1171   if (bytes) delete [] bytes;
1172 }
1173 
createAndInitModelsAndDecompressors(U32 context,const U8 * item)1174 inline BOOL LASreadItemCompressed_RGB14_v3::createAndInitModelsAndDecompressors(U32 context, const U8* item)
1175 {
1176   /* should only be called when context is unused */
1177 
1178   assert(contexts[context].unused);
1179 
1180   /* first create all entropy models (if needed) */
1181 
1182   if (contexts[context].m_byte_used == 0)
1183   {
1184     contexts[context].m_byte_used = dec_RGB->createSymbolModel(128);
1185     contexts[context].m_rgb_diff_0 = dec_RGB->createSymbolModel(256);
1186     contexts[context].m_rgb_diff_1 = dec_RGB->createSymbolModel(256);
1187     contexts[context].m_rgb_diff_2 = dec_RGB->createSymbolModel(256);
1188     contexts[context].m_rgb_diff_3 = dec_RGB->createSymbolModel(256);
1189     contexts[context].m_rgb_diff_4 = dec_RGB->createSymbolModel(256);
1190     contexts[context].m_rgb_diff_5 = dec_RGB->createSymbolModel(256);
1191   }
1192 
1193   /* then init entropy models */
1194 
1195   dec_RGB->initSymbolModel(contexts[context].m_byte_used);
1196   dec_RGB->initSymbolModel(contexts[context].m_rgb_diff_0);
1197   dec_RGB->initSymbolModel(contexts[context].m_rgb_diff_1);
1198   dec_RGB->initSymbolModel(contexts[context].m_rgb_diff_2);
1199   dec_RGB->initSymbolModel(contexts[context].m_rgb_diff_3);
1200   dec_RGB->initSymbolModel(contexts[context].m_rgb_diff_4);
1201   dec_RGB->initSymbolModel(contexts[context].m_rgb_diff_5);
1202 
1203   /* init current context from item */
1204 
1205   memcpy(contexts[context].last_item, item, 6);
1206 
1207   contexts[context].unused = FALSE;
1208 
1209   return TRUE;
1210 }
1211 
chunk_sizes()1212 BOOL LASreadItemCompressed_RGB14_v3::chunk_sizes()
1213 {
1214   /* for layered compression 'dec' only hands over the stream */
1215 
1216   ByteStreamIn* instream = dec->getByteStreamIn();
1217 
1218   /* read bytes per layer */
1219 
1220   instream->get32bitsLE(((U8*)&num_bytes_RGB));
1221 
1222   return TRUE;
1223 }
1224 
init(const U8 * item,U32 & context)1225 BOOL LASreadItemCompressed_RGB14_v3::init(const U8* item, U32& context)
1226 {
1227   /* for layered compression 'dec' only hands over the stream */
1228 
1229   ByteStreamIn* instream = dec->getByteStreamIn();
1230 
1231   /* on the first init create instreams and decoders */
1232 
1233   if (instream_RGB == 0)
1234   {
1235     /* create instreams */
1236 
1237     if (IS_LITTLE_ENDIAN())
1238     {
1239       instream_RGB = new ByteStreamInArrayLE();
1240     }
1241     else
1242     {
1243       instream_RGB = new ByteStreamInArrayBE();
1244     }
1245 
1246     /* create decoders */
1247 
1248     dec_RGB = new ArithmeticDecoder();
1249   }
1250 
1251   /* make sure the buffer is sufficiently large */
1252 
1253   if (num_bytes_RGB > num_bytes_allocated)
1254   {
1255     if (bytes) delete [] bytes;
1256     bytes = new U8[num_bytes_RGB];
1257     if (bytes == 0) return FALSE;
1258     num_bytes_allocated = num_bytes_RGB;
1259   }
1260 
1261   /* load the requested bytes and init the corresponding instreams an decoders */
1262 
1263   if (requested_RGB)
1264   {
1265     if (num_bytes_RGB)
1266     {
1267       instream->getBytes(bytes, num_bytes_RGB);
1268       instream_RGB->init(bytes, num_bytes_RGB);
1269       dec_RGB->init(instream_RGB);
1270       changed_RGB = TRUE;
1271     }
1272     else
1273     {
1274       instream_RGB->init(0, 0);
1275       changed_RGB = FALSE;
1276     }
1277   }
1278   else
1279   {
1280     if (num_bytes_RGB)
1281     {
1282       instream->skipBytes(num_bytes_RGB);
1283     }
1284     changed_RGB = FALSE;
1285   }
1286 
1287   /* mark the four scanner channel contexts as unused */
1288 
1289   U32 c;
1290   for (c = 0; c < 4; c++)
1291   {
1292     contexts[c].unused = TRUE;
1293   }
1294 
1295   /* set scanner channel as current context */
1296 
1297   current_context = context; // all other items use context set by POINT14 reader
1298 
1299   /* create and init models and decompressors */
1300 
1301   createAndInitModelsAndDecompressors(current_context, item);
1302 
1303   return TRUE;
1304 }
1305 
read(U8 * item,U32 & context)1306 inline void LASreadItemCompressed_RGB14_v3::read(U8* item, U32& context)
1307 {
1308   // get last
1309 
1310   U16* last_item = contexts[current_context].last_item;
1311 
1312   // check for context switch
1313 
1314   if (current_context != context)
1315   {
1316     current_context = context; // all other items use context set by POINT14 reader
1317     if (contexts[current_context].unused)
1318     {
1319       createAndInitModelsAndDecompressors(current_context, (U8*)last_item);
1320       last_item = contexts[current_context].last_item;
1321     }
1322   }
1323 
1324   // decompress
1325 
1326   if (changed_RGB)
1327   {
1328     U8 corr;
1329     I32 diff = 0;
1330     U32 sym = dec_RGB->decodeSymbol(contexts[current_context].m_byte_used);
1331     if (sym & (1 << 0))
1332     {
1333       corr = dec_RGB->decodeSymbol(contexts[current_context].m_rgb_diff_0);
1334       ((U16*)item)[0] = (U16)U8_FOLD(corr + (last_item[0]&255));
1335     }
1336     else
1337     {
1338       ((U16*)item)[0] = last_item[0]&0xFF;
1339     }
1340     if (sym & (1 << 1))
1341     {
1342       corr = dec_RGB->decodeSymbol(contexts[current_context].m_rgb_diff_1);
1343       ((U16*)item)[0] |= (((U16)U8_FOLD(corr + (last_item[0]>>8))) << 8);
1344     }
1345     else
1346     {
1347       ((U16*)item)[0] |= (last_item[0]&0xFF00);
1348     }
1349     if (sym & (1 << 6))
1350     {
1351       diff = (((U16*)item)[0]&0x00FF) - (last_item[0]&0x00FF);
1352       if (sym & (1 << 2))
1353       {
1354         corr = dec_RGB->decodeSymbol(contexts[current_context].m_rgb_diff_2);
1355         ((U16*)item)[1] = (U16)U8_FOLD(corr + U8_CLAMP(diff+(last_item[1]&255)));
1356       }
1357       else
1358       {
1359         ((U16*)item)[1] = last_item[1]&0xFF;
1360       }
1361       if (sym & (1 << 4))
1362       {
1363         corr = dec_RGB->decodeSymbol(contexts[current_context].m_rgb_diff_4);
1364         diff = (diff + ((((U16*)item)[1]&0x00FF) - (last_item[1]&0x00FF))) / 2;
1365         ((U16*)item)[2] = (U16)U8_FOLD(corr + U8_CLAMP(diff+(last_item[2]&255)));
1366       }
1367       else
1368       {
1369         ((U16*)item)[2] = last_item[2]&0xFF;
1370       }
1371       diff = (((U16*)item)[0]>>8) - (last_item[0]>>8);
1372       if (sym & (1 << 3))
1373       {
1374         corr = dec_RGB->decodeSymbol(contexts[current_context].m_rgb_diff_3);
1375         ((U16*)item)[1] |= (((U16)U8_FOLD(corr + U8_CLAMP(diff+(last_item[1]>>8))))<<8);
1376       }
1377       else
1378       {
1379         ((U16*)item)[1] |= (last_item[1]&0xFF00);
1380       }
1381       if (sym & (1 << 5))
1382       {
1383         corr = dec_RGB->decodeSymbol(contexts[current_context].m_rgb_diff_5);
1384         diff = (diff + ((((U16*)item)[1]>>8) - (last_item[1]>>8))) / 2;
1385         ((U16*)item)[2] |= (((U16)U8_FOLD(corr + U8_CLAMP(diff+(last_item[2]>>8))))<<8);
1386       }
1387       else
1388       {
1389         ((U16*)item)[2] |= (last_item[2]&0xFF00);
1390       }
1391     }
1392     else
1393     {
1394       ((U16*)item)[1] = ((U16*)item)[0];
1395       ((U16*)item)[2] = ((U16*)item)[0];
1396     }
1397     memcpy(last_item, item, 6);
1398   }
1399   else
1400   {
1401     memcpy(item, last_item, 6);
1402   }
1403 }
1404 
1405 /*
1406 ===============================================================================
1407                     LASreadItemCompressed_RGBNIR14_v3
1408 ===============================================================================
1409 */
1410 
LASreadItemCompressed_RGBNIR14_v3(ArithmeticDecoder * dec,const U32 decompress_selective)1411 LASreadItemCompressed_RGBNIR14_v3::LASreadItemCompressed_RGBNIR14_v3(ArithmeticDecoder* dec, const U32 decompress_selective)
1412 {
1413   /* not used as a decoder. just gives access to instream */
1414 
1415   assert(dec);
1416   this->dec = dec;
1417 
1418   /* zero instreams and decoders */
1419 
1420   instream_RGB = 0;
1421   instream_NIR = 0;
1422 
1423   dec_RGB = 0;
1424   dec_NIR = 0;
1425 
1426   /* zero num_bytes and init booleans */
1427 
1428   num_bytes_RGB = 0;
1429   num_bytes_NIR = 0;
1430 
1431   changed_RGB = FALSE;
1432   changed_NIR = FALSE;
1433 
1434   requested_RGB = (decompress_selective & LASZIP_DECOMPRESS_SELECTIVE_RGB ? TRUE : FALSE);
1435   requested_NIR = (decompress_selective & LASZIP_DECOMPRESS_SELECTIVE_NIR ? TRUE : FALSE);
1436 
1437   /* init the bytes buffer to zero */
1438 
1439   bytes = 0;
1440   num_bytes_allocated = 0;
1441 
1442   /* mark the four scanner channel contexts as uninitialized */
1443 
1444   U32 c;
1445   for (c = 0; c < 4; c++)
1446   {
1447     contexts[c].m_rgb_bytes_used = 0;
1448     contexts[c].m_nir_bytes_used = 0;
1449   }
1450   current_context = 0;
1451 }
1452 
~LASreadItemCompressed_RGBNIR14_v3()1453 LASreadItemCompressed_RGBNIR14_v3::~LASreadItemCompressed_RGBNIR14_v3()
1454 {
1455   /* destroy all initialized scanner channel contexts */
1456 
1457   U32 c;
1458   for (c = 0; c < 4; c++)
1459   {
1460     if (contexts[c].m_rgb_bytes_used)
1461     {
1462       dec_RGB->destroySymbolModel(contexts[c].m_rgb_bytes_used);
1463       dec_RGB->destroySymbolModel(contexts[c].m_rgb_diff_0);
1464       dec_RGB->destroySymbolModel(contexts[c].m_rgb_diff_1);
1465       dec_RGB->destroySymbolModel(contexts[c].m_rgb_diff_2);
1466       dec_RGB->destroySymbolModel(contexts[c].m_rgb_diff_3);
1467       dec_RGB->destroySymbolModel(contexts[c].m_rgb_diff_4);
1468       dec_RGB->destroySymbolModel(contexts[c].m_rgb_diff_5);
1469     }
1470 
1471     if (contexts[c].m_nir_bytes_used)
1472     {
1473       dec_NIR->destroySymbolModel(contexts[c].m_nir_bytes_used);
1474       dec_NIR->destroySymbolModel(contexts[c].m_nir_diff_0);
1475       dec_NIR->destroySymbolModel(contexts[c].m_nir_diff_1);
1476     }
1477   }
1478 
1479   /* destroy all instreams and decoders */
1480 
1481   if (instream_RGB)
1482   {
1483     delete instream_RGB;
1484 
1485     delete dec_RGB;
1486   }
1487 
1488   if (instream_NIR)
1489   {
1490     delete instream_NIR;
1491 
1492     delete dec_NIR;
1493   }
1494 
1495   if (bytes) delete [] bytes;
1496 }
1497 
createAndInitModelsAndDecompressors(U32 context,const U8 * item)1498 inline BOOL LASreadItemCompressed_RGBNIR14_v3::createAndInitModelsAndDecompressors(U32 context, const U8* item)
1499 {
1500   /* should only be called when context is unused */
1501 
1502   assert(contexts[context].unused);
1503 
1504   /* first create all entropy models (if needed) */
1505 
1506   if (requested_RGB)
1507   {
1508     if (contexts[context].m_rgb_bytes_used == 0)
1509     {
1510       contexts[context].m_rgb_bytes_used = dec_RGB->createSymbolModel(128);
1511       contexts[context].m_rgb_diff_0 = dec_RGB->createSymbolModel(256);
1512       contexts[context].m_rgb_diff_1 = dec_RGB->createSymbolModel(256);
1513       contexts[context].m_rgb_diff_2 = dec_RGB->createSymbolModel(256);
1514       contexts[context].m_rgb_diff_3 = dec_RGB->createSymbolModel(256);
1515       contexts[context].m_rgb_diff_4 = dec_RGB->createSymbolModel(256);
1516       contexts[context].m_rgb_diff_5 = dec_RGB->createSymbolModel(256);
1517     }
1518 
1519     /* then init entropy models */
1520 
1521     dec_RGB->initSymbolModel(contexts[context].m_rgb_bytes_used);
1522     dec_RGB->initSymbolModel(contexts[context].m_rgb_diff_0);
1523     dec_RGB->initSymbolModel(contexts[context].m_rgb_diff_1);
1524     dec_RGB->initSymbolModel(contexts[context].m_rgb_diff_2);
1525     dec_RGB->initSymbolModel(contexts[context].m_rgb_diff_3);
1526     dec_RGB->initSymbolModel(contexts[context].m_rgb_diff_4);
1527     dec_RGB->initSymbolModel(contexts[context].m_rgb_diff_5);
1528   }
1529 
1530   if (requested_NIR)
1531   {
1532     if (contexts[context].m_nir_bytes_used == 0)
1533     {
1534       contexts[context].m_nir_bytes_used = dec_NIR->createSymbolModel(4);
1535       contexts[context].m_nir_diff_0 = dec_NIR->createSymbolModel(256);
1536       contexts[context].m_nir_diff_1 = dec_NIR->createSymbolModel(256);
1537     }
1538 
1539     /* then init entropy models */
1540 
1541     dec_NIR->initSymbolModel(contexts[context].m_nir_bytes_used);
1542     dec_NIR->initSymbolModel(contexts[context].m_nir_diff_0);
1543     dec_NIR->initSymbolModel(contexts[context].m_nir_diff_1);
1544   }
1545 
1546   /* init current context from item */
1547 
1548   memcpy(contexts[context].last_item, item, 8);
1549 
1550   contexts[context].unused = FALSE;
1551 
1552   return TRUE;
1553 }
1554 
chunk_sizes()1555 BOOL LASreadItemCompressed_RGBNIR14_v3::chunk_sizes()
1556 {
1557   /* for layered compression 'dec' only hands over the stream */
1558 
1559   ByteStreamIn* instream = dec->getByteStreamIn();
1560 
1561   /* read bytes per layer */
1562 
1563   instream->get32bitsLE(((U8*)&num_bytes_RGB));
1564   instream->get32bitsLE(((U8*)&num_bytes_NIR));
1565 
1566   return TRUE;
1567 }
1568 
init(const U8 * item,U32 & context)1569 BOOL LASreadItemCompressed_RGBNIR14_v3::init(const U8* item, U32& context)
1570 {
1571   /* for layered compression 'dec' only hands over the stream */
1572 
1573   ByteStreamIn* instream = dec->getByteStreamIn();
1574 
1575   /* on the first init create instreams and decoders */
1576 
1577   if (instream_RGB == 0)
1578   {
1579     /* create instreams */
1580 
1581     if (IS_LITTLE_ENDIAN())
1582     {
1583       instream_RGB = new ByteStreamInArrayLE();
1584       instream_NIR = new ByteStreamInArrayLE();
1585     }
1586     else
1587     {
1588       instream_RGB = new ByteStreamInArrayBE();
1589       instream_NIR = new ByteStreamInArrayBE();
1590     }
1591 
1592     /* create decoders */
1593 
1594     dec_RGB = new ArithmeticDecoder();
1595     dec_NIR = new ArithmeticDecoder();
1596   }
1597 
1598   /* how many bytes do we need to read */
1599 
1600   U32 num_bytes = 0;
1601   if (requested_RGB) num_bytes += num_bytes_RGB;
1602   if (requested_NIR) num_bytes += num_bytes_NIR;
1603 
1604   /* make sure the buffer is sufficiently large */
1605 
1606   if (num_bytes > num_bytes_allocated)
1607   {
1608     if (bytes) delete [] bytes;
1609     bytes = new U8[num_bytes];
1610     if (bytes == 0) return FALSE;
1611     num_bytes_allocated = num_bytes;
1612   }
1613 
1614   /* load the requested bytes and init the corresponding instreams an decoders */
1615 
1616   num_bytes = 0;
1617 
1618   if (requested_RGB)
1619   {
1620     if (num_bytes_RGB)
1621     {
1622       instream->getBytes(bytes, num_bytes_RGB);
1623       num_bytes += num_bytes_RGB;
1624       instream_RGB->init(bytes, num_bytes_RGB);
1625       dec_RGB->init(instream_RGB);
1626       changed_RGB = TRUE;
1627     }
1628     else
1629     {
1630       instream_RGB->init(0, 0);
1631       changed_RGB = FALSE;
1632     }
1633   }
1634   else
1635   {
1636     if (num_bytes_RGB)
1637     {
1638       instream->skipBytes(num_bytes_RGB);
1639     }
1640     changed_RGB = FALSE;
1641   }
1642 
1643   if (requested_NIR)
1644   {
1645     if (num_bytes_NIR)
1646     {
1647       instream->getBytes(&bytes[num_bytes], num_bytes_NIR);
1648       instream_NIR->init(&bytes[num_bytes], num_bytes_NIR);
1649       dec_NIR->init(instream_NIR);
1650       changed_NIR = TRUE;
1651     }
1652     else
1653     {
1654       instream_NIR->init(0, 0);
1655       changed_NIR = FALSE;
1656     }
1657   }
1658   else
1659   {
1660     if (num_bytes_NIR)
1661     {
1662       instream->skipBytes(num_bytes_NIR);
1663     }
1664     changed_NIR = FALSE;
1665   }
1666 
1667   /* mark the four scanner channel contexts as unused */
1668 
1669   U32 c;
1670   for (c = 0; c < 4; c++)
1671   {
1672     contexts[c].unused = TRUE;
1673   }
1674 
1675   /* set scanner channel as current context */
1676 
1677   current_context = context; // all other items use context set by POINT14 reader
1678 
1679   /* create and init models and decompressors */
1680 
1681   createAndInitModelsAndDecompressors(current_context, item);
1682 
1683   return TRUE;
1684 }
1685 
read(U8 * item,U32 & context)1686 inline void LASreadItemCompressed_RGBNIR14_v3::read(U8* item, U32& context)
1687 {
1688   // get last
1689 
1690   U16* last_item = contexts[current_context].last_item;
1691 
1692   // check for context switch
1693 
1694   if (current_context != context)
1695   {
1696     current_context = context; // all other items use context set by POINT14 reader
1697     if (contexts[current_context].unused)
1698     {
1699       createAndInitModelsAndDecompressors(current_context, (U8*)last_item);
1700       last_item = contexts[current_context].last_item;
1701     }
1702   }
1703 
1704   // decompress
1705 
1706   ////////////////////////////////////////
1707   // decompress RGB layer
1708   ////////////////////////////////////////
1709 
1710   if (changed_RGB)
1711   {
1712     U8 corr;
1713     I32 diff = 0;
1714     U32 sym = dec_RGB->decodeSymbol(contexts[current_context].m_rgb_bytes_used);
1715     if (sym & (1 << 0))
1716     {
1717       corr = dec_RGB->decodeSymbol(contexts[current_context].m_rgb_diff_0);
1718       ((U16*)item)[0] = (U16)U8_FOLD(corr + (last_item[0]&255));
1719     }
1720     else
1721     {
1722       ((U16*)item)[0] = last_item[0]&0xFF;
1723     }
1724     if (sym & (1 << 1))
1725     {
1726       corr = dec_RGB->decodeSymbol(contexts[current_context].m_rgb_diff_1);
1727       ((U16*)item)[0] |= (((U16)U8_FOLD(corr + (last_item[0]>>8))) << 8);
1728     }
1729     else
1730     {
1731       ((U16*)item)[0] |= (last_item[0]&0xFF00);
1732     }
1733     if (sym & (1 << 6))
1734     {
1735       diff = (((U16*)item)[0]&0x00FF) - (last_item[0]&0x00FF);
1736       if (sym & (1 << 2))
1737       {
1738         corr = dec_RGB->decodeSymbol(contexts[current_context].m_rgb_diff_2);
1739         ((U16*)item)[1] = (U16)U8_FOLD(corr + U8_CLAMP(diff+(last_item[1]&255)));
1740       }
1741       else
1742       {
1743         ((U16*)item)[1] = last_item[1]&0xFF;
1744       }
1745       if (sym & (1 << 4))
1746       {
1747         corr = dec_RGB->decodeSymbol(contexts[current_context].m_rgb_diff_4);
1748         diff = (diff + ((((U16*)item)[1]&0x00FF) - (last_item[1]&0x00FF))) / 2;
1749         ((U16*)item)[2] = (U16)U8_FOLD(corr + U8_CLAMP(diff+(last_item[2]&255)));
1750       }
1751       else
1752       {
1753         ((U16*)item)[2] = last_item[2]&0xFF;
1754       }
1755       diff = (((U16*)item)[0]>>8) - (last_item[0]>>8);
1756       if (sym & (1 << 3))
1757       {
1758         corr = dec_RGB->decodeSymbol(contexts[current_context].m_rgb_diff_3);
1759         ((U16*)item)[1] |= (((U16)U8_FOLD(corr + U8_CLAMP(diff+(last_item[1]>>8))))<<8);
1760       }
1761       else
1762       {
1763         ((U16*)item)[1] |= (last_item[1]&0xFF00);
1764       }
1765       if (sym & (1 << 5))
1766       {
1767         corr = dec_RGB->decodeSymbol(contexts[current_context].m_rgb_diff_5);
1768         diff = (diff + ((((U16*)item)[1]>>8) - (last_item[1]>>8))) / 2;
1769         ((U16*)item)[2] |= (((U16)U8_FOLD(corr + U8_CLAMP(diff+(last_item[2]>>8))))<<8);
1770       }
1771       else
1772       {
1773         ((U16*)item)[2] |= (last_item[2]&0xFF00);
1774       }
1775     }
1776     else
1777     {
1778       ((U16*)item)[1] = ((U16*)item)[0];
1779       ((U16*)item)[2] = ((U16*)item)[0];
1780     }
1781     memcpy(last_item, item, 6);
1782   }
1783   else
1784   {
1785     memcpy(item, last_item, 6);
1786   }
1787 
1788   ////////////////////////////////////////
1789   // decompress NIR layer
1790   ////////////////////////////////////////
1791 
1792   if (changed_NIR)
1793   {
1794     U8 corr;
1795     U32 sym = dec_NIR->decodeSymbol(contexts[current_context].m_nir_bytes_used);
1796     if (sym & (1 << 0))
1797     {
1798       corr = dec_NIR->decodeSymbol(contexts[current_context].m_nir_diff_0);
1799       ((U16*)item)[3] = (U16)U8_FOLD(corr + (last_item[3]&255));
1800     }
1801     else
1802     {
1803       ((U16*)item)[3] = last_item[3]&0xFF;
1804     }
1805     if (sym & (1 << 1))
1806     {
1807       corr = dec_NIR->decodeSymbol(contexts[current_context].m_nir_diff_1);
1808       ((U16*)item)[3] |= (((U16)U8_FOLD(corr + (last_item[3]>>8))) << 8);
1809     }
1810     else
1811     {
1812       ((U16*)item)[3] |= (last_item[3]&0xFF00);
1813     }
1814     last_item[3] = ((U16*)item)[3];
1815   }
1816   else
1817   {
1818     ((U16*)item)[3] = last_item[3];
1819   }
1820 }
1821 
1822 /*
1823 ===============================================================================
1824                        LASreadItemCompressed_WAVEPACKET14_v3
1825 ===============================================================================
1826 */
1827 
LASreadItemCompressed_WAVEPACKET14_v3(ArithmeticDecoder * dec,const U32 decompress_selective)1828 LASreadItemCompressed_WAVEPACKET14_v3::LASreadItemCompressed_WAVEPACKET14_v3(ArithmeticDecoder* dec, const U32 decompress_selective)
1829 {
1830   /* not used as a decoder. just gives access to instream */
1831 
1832   assert(dec);
1833   this->dec = dec;
1834 
1835   /* zero instreams and decoders */
1836 
1837   instream_wavepacket = 0;
1838 
1839   dec_wavepacket = 0;
1840 
1841   /* zero num_bytes and init booleans */
1842 
1843   num_bytes_wavepacket = 0;
1844 
1845   changed_wavepacket = FALSE;
1846 
1847   requested_wavepacket = (decompress_selective & LASZIP_DECOMPRESS_SELECTIVE_WAVEPACKET ? TRUE : FALSE);
1848 
1849   /* init the bytes buffer to zero */
1850 
1851   bytes = 0;
1852   num_bytes_allocated = 0;
1853 
1854   /* mark the four scanner channel contexts as uninitialized */
1855 
1856   U32 c;
1857   for (c = 0; c < 4; c++)
1858   {
1859     contexts[c].m_packet_index = 0;
1860   }
1861   current_context = 0;
1862 }
1863 
~LASreadItemCompressed_WAVEPACKET14_v3()1864 LASreadItemCompressed_WAVEPACKET14_v3::~LASreadItemCompressed_WAVEPACKET14_v3()
1865 {
1866   /* destroy all initialized scanner channel contexts */
1867 
1868   U32 c;
1869   for (c = 0; c < 4; c++)
1870   {
1871     if (contexts[c].m_packet_index)
1872     {
1873       dec_wavepacket->destroySymbolModel(contexts[c].m_packet_index);
1874       dec_wavepacket->destroySymbolModel(contexts[c].m_offset_diff[0]);
1875       dec_wavepacket->destroySymbolModel(contexts[c].m_offset_diff[1]);
1876       dec_wavepacket->destroySymbolModel(contexts[c].m_offset_diff[2]);
1877       dec_wavepacket->destroySymbolModel(contexts[c].m_offset_diff[3]);
1878       delete contexts[c].ic_offset_diff;
1879       delete contexts[c].ic_packet_size;
1880       delete contexts[c].ic_return_point;
1881       delete contexts[c].ic_xyz;
1882     }
1883   }
1884 
1885   /* destroy all instreams and decoders */
1886 
1887   if (instream_wavepacket)
1888   {
1889     delete instream_wavepacket;
1890 
1891     delete dec_wavepacket;
1892   }
1893 
1894   if (bytes) delete [] bytes;
1895 }
1896 
createAndInitModelsAndDecompressors(U32 context,const U8 * item)1897 inline BOOL LASreadItemCompressed_WAVEPACKET14_v3::createAndInitModelsAndDecompressors(U32 context, const U8* item)
1898 {
1899   /* should only be called when context is unused */
1900 
1901   assert(contexts[context].unused);
1902 
1903   /* first create all entropy models (if needed) */
1904 
1905   if (requested_wavepacket)
1906   {
1907     if (contexts[context].m_packet_index == 0)
1908     {
1909       contexts[context].m_packet_index = dec_wavepacket->createSymbolModel(256);
1910       contexts[context].m_offset_diff[0] = dec_wavepacket->createSymbolModel(4);
1911       contexts[context].m_offset_diff[1] = dec_wavepacket->createSymbolModel(4);
1912       contexts[context].m_offset_diff[2] = dec_wavepacket->createSymbolModel(4);
1913       contexts[context].m_offset_diff[3] = dec_wavepacket->createSymbolModel(4);
1914       contexts[context].ic_offset_diff = new IntegerCompressor(dec_wavepacket, 32);
1915       contexts[context].ic_packet_size = new IntegerCompressor(dec_wavepacket, 32);
1916       contexts[context].ic_return_point = new IntegerCompressor(dec_wavepacket, 32);
1917       contexts[context].ic_xyz = new IntegerCompressor(dec_wavepacket, 32, 3);
1918     }
1919 
1920     /* then init entropy models */
1921 
1922     dec_wavepacket->initSymbolModel(contexts[context].m_packet_index);
1923     dec_wavepacket->initSymbolModel(contexts[context].m_offset_diff[0]);
1924     dec_wavepacket->initSymbolModel(contexts[context].m_offset_diff[1]);
1925     dec_wavepacket->initSymbolModel(contexts[context].m_offset_diff[2]);
1926     dec_wavepacket->initSymbolModel(contexts[context].m_offset_diff[3]);
1927     contexts[context].ic_offset_diff->initDecompressor();
1928     contexts[context].ic_packet_size->initDecompressor();
1929     contexts[context].ic_return_point->initDecompressor();
1930     contexts[context].ic_xyz->initDecompressor();
1931   }
1932 
1933   /* init current context from item */
1934 
1935   contexts[context].last_diff_32 = 0;
1936   contexts[context].sym_last_offset_diff = 0;
1937   memcpy(contexts[context].last_item, item, 29);
1938 
1939   contexts[context].unused = FALSE;
1940 
1941   return TRUE;
1942 }
1943 
chunk_sizes()1944 BOOL LASreadItemCompressed_WAVEPACKET14_v3::chunk_sizes()
1945 {
1946   /* for layered compression 'dec' only hands over the stream */
1947 
1948   ByteStreamIn* instream = dec->getByteStreamIn();
1949 
1950   /* read bytes per layer */
1951 
1952   instream->get32bitsLE(((U8*)&num_bytes_wavepacket));
1953 
1954   return TRUE;
1955 }
1956 
init(const U8 * item,U32 & context)1957 BOOL LASreadItemCompressed_WAVEPACKET14_v3::init(const U8* item, U32& context)
1958 {
1959   /* for layered compression 'dec' only hands over the stream */
1960 
1961   ByteStreamIn* instream = dec->getByteStreamIn();
1962 
1963   /* on the first init create instreams and decoders */
1964 
1965   if (instream_wavepacket == 0)
1966   {
1967     /* create instreams */
1968 
1969     if (IS_LITTLE_ENDIAN())
1970     {
1971       instream_wavepacket = new ByteStreamInArrayLE();
1972     }
1973     else
1974     {
1975       instream_wavepacket = new ByteStreamInArrayBE();
1976     }
1977 
1978     /* create decoders */
1979 
1980     dec_wavepacket = new ArithmeticDecoder();
1981   }
1982 
1983   /* make sure the buffer is sufficiently large */
1984 
1985   if (num_bytes_wavepacket > num_bytes_allocated)
1986   {
1987     if (bytes) delete [] bytes;
1988     bytes = new U8[num_bytes_wavepacket];
1989     if (bytes == 0) return FALSE;
1990     num_bytes_allocated = num_bytes_wavepacket;
1991   }
1992 
1993   /* load the requested bytes and init the corresponding instreams an decoders */
1994 
1995   if (requested_wavepacket)
1996   {
1997     if (num_bytes_wavepacket)
1998     {
1999       instream->getBytes(bytes, num_bytes_wavepacket);
2000       instream_wavepacket->init(bytes, num_bytes_wavepacket);
2001       dec_wavepacket->init(instream_wavepacket);
2002       changed_wavepacket = TRUE;
2003     }
2004     else
2005     {
2006       instream_wavepacket->init(0, 0);
2007       changed_wavepacket = FALSE;
2008     }
2009   }
2010   else
2011   {
2012     if (num_bytes_wavepacket)
2013     {
2014       instream->skipBytes(num_bytes_wavepacket);
2015     }
2016     changed_wavepacket = FALSE;
2017   }
2018 
2019   /* mark the four scanner channel contexts as unused */
2020 
2021   U32 c;
2022   for (c = 0; c < 4; c++)
2023   {
2024     contexts[c].unused = TRUE;
2025   }
2026 
2027   /* set scanner channel as current context */
2028 
2029   current_context = context; // all other items use context set by POINT14 reader
2030 
2031   /* create and init models and decompressors */
2032 
2033   createAndInitModelsAndDecompressors(current_context, item);
2034 
2035   return TRUE;
2036 }
2037 
read(U8 * item,U32 & context)2038 inline void LASreadItemCompressed_WAVEPACKET14_v3::read(U8* item, U32& context)
2039 {
2040   // get last
2041 
2042   U8* last_item = contexts[current_context].last_item;
2043 
2044   // check for context switch
2045 
2046   if (current_context != context)
2047   {
2048     current_context = context; // all other items use context set by POINT14 reader
2049     if (contexts[current_context].unused)
2050     {
2051       createAndInitModelsAndDecompressors(current_context, last_item);
2052       last_item = contexts[current_context].last_item;
2053     }
2054   }
2055 
2056   // decompress
2057 
2058   if (changed_wavepacket)
2059   {
2060     item[0] = (U8)(dec_wavepacket->decodeSymbol(contexts[current_context].m_packet_index));
2061 
2062     LASwavepacket13 this_item_m;
2063     LASwavepacket13 last_item_m = LASwavepacket13::unpack(last_item+1);
2064 
2065     contexts[current_context].sym_last_offset_diff = dec_wavepacket->decodeSymbol(contexts[current_context].m_offset_diff[contexts[current_context].sym_last_offset_diff]);
2066 
2067     if (contexts[current_context].sym_last_offset_diff == 0)
2068     {
2069       this_item_m.offset = last_item_m.offset;
2070     }
2071     else if (contexts[current_context].sym_last_offset_diff == 1)
2072     {
2073       this_item_m.offset = last_item_m.offset + last_item_m.packet_size;
2074     }
2075     else if (contexts[current_context].sym_last_offset_diff == 2)
2076     {
2077       contexts[current_context].last_diff_32 = contexts[current_context].ic_offset_diff->decompress(contexts[current_context].last_diff_32);
2078       this_item_m.offset = last_item_m.offset + contexts[current_context].last_diff_32;
2079     }
2080     else
2081     {
2082       this_item_m.offset = dec_wavepacket->readInt64();
2083     }
2084 
2085     this_item_m.packet_size = contexts[current_context].ic_packet_size->decompress(last_item_m.packet_size);
2086     this_item_m.return_point.i32 = contexts[current_context].ic_return_point->decompress(last_item_m.return_point.i32);
2087     this_item_m.x.i32 = contexts[current_context].ic_xyz->decompress(last_item_m.x.i32, 0);
2088     this_item_m.y.i32 = contexts[current_context].ic_xyz->decompress(last_item_m.y.i32, 1);
2089     this_item_m.z.i32 = contexts[current_context].ic_xyz->decompress(last_item_m.z.i32, 2);
2090 
2091     this_item_m.pack(item+1);
2092 
2093     memcpy(last_item, item, 29);
2094   }
2095 }
2096 
2097 /*
2098 ===============================================================================
2099                        LASreadItemCompressed_BYTE14_v3
2100 ===============================================================================
2101 */
2102 
LASreadItemCompressed_BYTE14_v3(ArithmeticDecoder * dec,U32 number,const U32 decompress_selective)2103 LASreadItemCompressed_BYTE14_v3::LASreadItemCompressed_BYTE14_v3(ArithmeticDecoder* dec, U32 number, const U32 decompress_selective)
2104 {
2105   /* not used as a decoder. just gives access to instream */
2106 
2107   assert(dec);
2108   this->dec = dec;
2109 
2110   /* must be more than one byte */
2111 
2112   assert(number);
2113   this->number = number;
2114 
2115   /* zero instream and decoder pointer arrays */
2116 
2117   instream_Bytes = 0;
2118 
2119   dec_Bytes = 0;
2120 
2121   /* create and init num_bytes and booleans arrays */
2122 
2123   num_bytes_Bytes = new U32[number];
2124 
2125   changed_Bytes = new BOOL[number];
2126 
2127   requested_Bytes = new BOOL[number];
2128 
2129   U32 i;
2130   for (i = 0; i < number; i++)
2131   {
2132     num_bytes_Bytes[i] = 0;
2133 
2134     changed_Bytes[i] = FALSE;
2135 
2136     if (i > 15) // currently only the first 16 extra bytes can be selectively decompressed
2137     {
2138       requested_Bytes[i] = TRUE;
2139     }
2140     else
2141     {
2142       requested_Bytes[i] = (decompress_selective & (LASZIP_DECOMPRESS_SELECTIVE_BYTE0 << i) ? TRUE : FALSE);
2143     }
2144   }
2145 
2146   /* init the bytes buffer to zero */
2147 
2148   bytes = 0;
2149   num_bytes_allocated = 0;
2150 
2151   /* mark the four scanner channel contexts as uninitialized */
2152 
2153   U32 c;
2154   for (c = 0; c < 4; c++)
2155   {
2156     contexts[c].m_bytes = 0;
2157   }
2158   current_context = 0;
2159 }
2160 
~LASreadItemCompressed_BYTE14_v3()2161 LASreadItemCompressed_BYTE14_v3::~LASreadItemCompressed_BYTE14_v3()
2162 {
2163   /* destroy all initialized scanner channel contexts */
2164 
2165   U32 c, i;
2166   for (c = 0; c < 4; c++)
2167   {
2168     if (contexts[c].m_bytes)
2169     {
2170       for (i = 0; i < number; i++)
2171       {
2172         dec_Bytes[i]->destroySymbolModel(contexts[c].m_bytes[i]);
2173       }
2174       delete [] contexts[c].m_bytes;
2175       delete [] contexts[c].last_item;
2176     }
2177   }
2178 
2179   /* destroy all instream and decoder arrays */
2180 
2181   if (instream_Bytes)
2182   {
2183     for (i = 0; i < number; i++)
2184     {
2185       if (instream_Bytes[i])
2186       {
2187         delete instream_Bytes[i];
2188         delete dec_Bytes[i];
2189       }
2190     }
2191 
2192     delete [] instream_Bytes;
2193     delete [] dec_Bytes;
2194   }
2195 
2196   /* destroy all other arrays */
2197 
2198   if (num_bytes_Bytes) delete [] num_bytes_Bytes;
2199 
2200   if (changed_Bytes) delete [] changed_Bytes;
2201 
2202   if (requested_Bytes) delete [] requested_Bytes;
2203 
2204   if (bytes) delete [] bytes;
2205 }
2206 
createAndInitModelsAndDecompressors(U32 context,const U8 * item)2207 inline BOOL LASreadItemCompressed_BYTE14_v3::createAndInitModelsAndDecompressors(U32 context, const U8* item)
2208 {
2209   U32 i;
2210 
2211   /* should only be called when context is unused */
2212 
2213   assert(contexts[context].unused);
2214 
2215   /* first create all entropy models and last items (if needed) */
2216 
2217   if (contexts[context].m_bytes == 0)
2218   {
2219     contexts[context].m_bytes = new ArithmeticModel*[number];
2220     for (i = 0; i < number; i++)
2221     {
2222       contexts[context].m_bytes[i] = dec_Bytes[i]->createSymbolModel(256);
2223       dec_Bytes[i]->initSymbolModel(contexts[context].m_bytes[i]);
2224     }
2225 
2226     /* create last item */
2227     contexts[context].last_item = new U8[number];
2228   }
2229 
2230   /* then init entropy models */
2231 
2232   for (i = 0; i < number; i++)
2233   {
2234     dec_Bytes[i]->initSymbolModel(contexts[context].m_bytes[i]);
2235   }
2236 
2237   /* init current context from item */
2238 
2239   memcpy(contexts[context].last_item, item, number);
2240 
2241   contexts[context].unused = FALSE;
2242 
2243   return TRUE;
2244 }
2245 
chunk_sizes()2246 BOOL LASreadItemCompressed_BYTE14_v3::chunk_sizes()
2247 {
2248   U32 i;
2249 
2250   /* for layered compression 'dec' only hands over the stream */
2251 
2252   ByteStreamIn* instream = dec->getByteStreamIn();
2253 
2254   for (i = 0; i < number; i++)
2255   {
2256     /* read bytes per layer */
2257 
2258     instream->get32bitsLE(((U8*)&(num_bytes_Bytes[i])));
2259   }
2260 
2261   return TRUE;
2262 }
2263 
init(const U8 * item,U32 & context)2264 BOOL LASreadItemCompressed_BYTE14_v3::init(const U8* item, U32& context)
2265 {
2266   U32 i;
2267 
2268   /* for layered compression 'dec' only hands over the stream */
2269 
2270   ByteStreamIn* instream = dec->getByteStreamIn();
2271 
2272   /* on the first init create instreams and decoders */
2273 
2274   if (instream_Bytes == 0)
2275   {
2276     /* create instream pointer array */
2277 
2278     instream_Bytes = new ByteStreamInArray*[number];
2279 
2280     /* create instreams */
2281 
2282     if (IS_LITTLE_ENDIAN())
2283     {
2284       for (i = 0; i < number; i++)
2285       {
2286         instream_Bytes[i] = new ByteStreamInArrayLE();
2287       }
2288     }
2289     else
2290     {
2291       for (i = 0; i < number; i++)
2292       {
2293         instream_Bytes[i] = new ByteStreamInArrayBE();
2294       }
2295     }
2296 
2297     /* create decoder pointer array */
2298 
2299     dec_Bytes = new ArithmeticDecoder*[number];
2300 
2301     /* create layer decoders */
2302 
2303     for (i = 0; i < number; i++)
2304     {
2305       dec_Bytes[i] = new ArithmeticDecoder();
2306     }
2307   }
2308 
2309   /* how many bytes do we need to read */
2310 
2311   U32 num_bytes = 0;
2312 
2313   for (i = 0; i < number; i++)
2314   {
2315     if (requested_Bytes[i]) num_bytes += num_bytes_Bytes[i];
2316   }
2317 
2318   /* make sure the buffer is sufficiently large */
2319 
2320   if (num_bytes > num_bytes_allocated)
2321   {
2322     if (bytes) delete [] bytes;
2323     bytes = new U8[num_bytes];
2324     if (bytes == 0) return FALSE;
2325     num_bytes_allocated = num_bytes;
2326   }
2327 
2328   /* load the requested bytes and init the corresponding instreams an decoders */
2329 
2330   num_bytes = 0;
2331   for (i = 0; i < number; i++)
2332   {
2333     if (requested_Bytes[i])
2334     {
2335       if (num_bytes_Bytes[i])
2336       {
2337         instream->getBytes(&(bytes[num_bytes]), num_bytes_Bytes[i]);
2338         instream_Bytes[i]->init(&(bytes[num_bytes]), num_bytes_Bytes[i]);
2339         dec_Bytes[i]->init(instream_Bytes[i]);
2340         num_bytes += num_bytes_Bytes[i];
2341         changed_Bytes[i] = TRUE;
2342       }
2343       else
2344       {
2345         dec_Bytes[i]->init(0, 0);
2346         changed_Bytes[i] = FALSE;
2347       }
2348     }
2349     else
2350     {
2351       if (num_bytes_Bytes[i])
2352       {
2353         instream->skipBytes(num_bytes_Bytes[i]);
2354       }
2355       changed_Bytes[i] = FALSE;
2356     }
2357   }
2358 
2359   /* mark the four scanner channel contexts as unused */
2360 
2361   U32 c;
2362   for (c = 0; c < 4; c++)
2363   {
2364     contexts[c].unused = TRUE;
2365   }
2366 
2367   /* set scanner channel as current context */
2368 
2369   current_context = context; // all other items use context set by POINT14 reader
2370 
2371   /* create and init models and decompressors */
2372 
2373   createAndInitModelsAndDecompressors(current_context, item);
2374 
2375   return TRUE;
2376 }
2377 
read(U8 * item,U32 & context)2378 inline void LASreadItemCompressed_BYTE14_v3::read(U8* item, U32& context)
2379 {
2380   // get last
2381 
2382   U8* last_item = contexts[current_context].last_item;
2383 
2384   // check for context switch
2385 
2386   if (current_context != context)
2387   {
2388     current_context = context; // all other items use context set by POINT14 reader
2389     if (contexts[current_context].unused)
2390     {
2391       createAndInitModelsAndDecompressors(current_context, (U8*)last_item);
2392       last_item = contexts[current_context].last_item;
2393     }
2394   }
2395 
2396   // decompress
2397 
2398   U32 i;
2399   for (i = 0; i < number; i++)
2400   {
2401     if (changed_Bytes[i])
2402     {
2403       I32 value = last_item[i] + dec_Bytes[i]->decodeSymbol(contexts[current_context].m_bytes[i]);
2404       item[i] = U8_FOLD(value);
2405       last_item[i] = item[i];
2406     }
2407     else
2408     {
2409       item[i] = last_item[i];
2410     }
2411   }
2412 }
2413