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