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