[Liblas-commits] laszip: one last optimization to compress 1.5 percent better

liblas-commits at liblas.org liblas-commits at liblas.org
Thu Dec 23 20:24:37 EST 2010


details:   http://hg.liblas.orglaszip/rev/e815143ce051
changeset: 89:e815143ce051
user:      isenburg
date:      Thu Dec 23 17:24:25 2010 -0800
description:
one last optimization to compress 1.5 percent better

diffstat:

 src/lasreaditemcompressed_v1.cpp  |  111 +++++++++++++++++++------------
 src/lasreaditemcompressed_v1.hpp  |   14 +-
 src/laswriteitemcompressed_v1.cpp |  134 ++++++++++++++++++++++++++++---------
 src/laswriteitemcompressed_v1.hpp |   14 +-
 4 files changed, 181 insertions(+), 92 deletions(-)

diffs (truncated from 463 to 300 lines):

diff -r 113c76a6708b -r e815143ce051 src/lasreaditemcompressed_v1.cpp
--- a/src/lasreaditemcompressed_v1.cpp	Thu Dec 23 10:11:19 2010 -0800
+++ b/src/lasreaditemcompressed_v1.cpp	Thu Dec 23 17:24:25 2010 -0800
@@ -57,60 +57,67 @@
 
 struct LASpoint10
 {
-  int x;
-  int y;
-  int z;
-  unsigned short intensity;
-  unsigned char return_number : 3;
-  unsigned char number_of_returns_of_given_pulse : 3;
-  unsigned char scan_direction_flag : 1;
-  unsigned char edge_of_flight_line : 1;
-  unsigned char classification;
-  char scan_angle_rank;
-  unsigned char user_data;
-  unsigned short point_source_ID;
+  I32 x;
+  I32 y;
+  I32 z;
+  U16 intensity;
+  U8 return_number : 3;
+  U8 number_of_returns_of_given_pulse : 3;
+  U8 scan_direction_flag : 1;
+  U8 edge_of_flight_line : 1;
+  U8 classification;
+  I8 scan_angle_rank;
+  U8 user_data;
+  U16 point_source_ID;
 };
 
 LASreadItemCompressed_POINT10_v1::LASreadItemCompressed_POINT10_v1(EntropyDecoder* dec)
 {
+  U32 i;
+
   /* set decoder */
   assert(dec);
   this->dec = dec;
 
   /* create models and integer compressors */
   ic_dx = new IntegerCompressor(dec, 32);  // 32 bits, 1 context
-	ic_dy = new IntegerCompressor(dec, 32, 33); // 32 bits, 33 contexts
-	ic_z = new IntegerCompressor(dec, 32, 33);  // 32 bits, 33 contexts
+	ic_dy = new IntegerCompressor(dec, 32, 20); // 32 bits, 20 contexts
+	ic_z = new IntegerCompressor(dec, 32, 20);  // 32 bits, 20 contexts
+	ic_intensity = new IntegerCompressor(dec, 16);
+	ic_scan_angle_rank = new IntegerCompressor(dec, 8, 2);
+	ic_point_source_ID = new IntegerCompressor(dec, 16);
 	m_changed_values = dec->createSymbolModel(64);
-	ic_intensity = new IntegerCompressor(dec, 16);
-	m_bit_byte = dec->createSymbolModel(256);
-  m_classification = dec->createSymbolModel(256);
-	ic_scan_angle_rank = new IntegerCompressor(dec, 8, 2);
-	m_user_data = dec->createSymbolModel(256);
-	ic_point_source_ID = new IntegerCompressor(dec, 16);
-
-  /* create last item */
-  last_item = new U8[20];
+  for (i = 0; i < 256; i++)
+  {
+    m_bit_byte[i] = 0;
+    m_classification[i] = 0;
+    m_user_data[i] = 0;
+  }
 }
 
 LASreadItemCompressed_POINT10_v1::~LASreadItemCompressed_POINT10_v1()
 {
+  U32 i;
+
   delete ic_dx;
   delete ic_dy;
   delete ic_z;
+  delete ic_intensity;
+  delete ic_scan_angle_rank;
+  delete ic_point_source_ID;
   dec->destroySymbolModel(m_changed_values);
-  delete ic_intensity;
-  dec->destroySymbolModel(m_bit_byte);
-  dec->destroySymbolModel(m_classification);
-  delete ic_scan_angle_rank;
-  dec->destroySymbolModel(m_user_data);
-  delete ic_point_source_ID;
-  delete [] last_item;
+  for (i = 0; i < 256; i++)
+  {
+    if (m_bit_byte[i]) dec->destroySymbolModel(m_bit_byte[i]);
+    if (m_classification[i]) dec->destroySymbolModel(m_classification[i]);
+    if (m_user_data[i]) dec->destroySymbolModel(m_user_data[i]);
+  }
 }
-
 
 BOOL LASreadItemCompressed_POINT10_v1::init(const U8* item)
 {
+  U32 i;
+
   /* init state */
 	last_x_diff[0] = last_x_diff[1] = last_x_diff[2] = 0;
 	last_y_diff[0] = last_y_diff[1] = last_y_diff[2] = 0;
@@ -120,13 +127,16 @@
   ic_dx->initDecompressor();
   ic_dy->initDecompressor();
   ic_z->initDecompressor();
+  ic_intensity->initDecompressor();
+  ic_scan_angle_rank->initDecompressor();
+  ic_point_source_ID->initDecompressor();
   dec->initSymbolModel(m_changed_values);
-  ic_intensity->initDecompressor();
-  dec->initSymbolModel(m_bit_byte);
-  dec->initSymbolModel(m_classification);
-  ic_scan_angle_rank->initDecompressor();
-  dec->initSymbolModel(m_user_data);
-  ic_point_source_ID->initDecompressor();
+  for (i = 0; i < 256; i++)
+  {
+    if (m_bit_byte[i]) dec->initSymbolModel(m_bit_byte[i]);
+    if (m_classification[i]) dec->initSymbolModel(m_classification[i]);
+    if (m_user_data[i]) dec->initSymbolModel(m_user_data[i]);
+  }
 
   /* init last item */
   memcpy(last_item, item, 20);
@@ -185,10 +195,10 @@
   ((LASpoint10*)item)->x += x_diff;
   // we use the number k of bits corrector bits to switch contexts
   U32 k_bits = ic_dx->getK();
-  I32 y_diff = ic_dy->decompress(median_y, k_bits);
+  I32 y_diff = ic_dy->decompress(median_y, (k_bits < 19 ? k_bits : 19));
   ((LASpoint10*)item)->y += y_diff;
   k_bits = (k_bits + ic_dy->getK())/2;
-  ((LASpoint10*)item)->z = ic_z->decompress(((LASpoint10*)last_item)->z, k_bits);
+  ((LASpoint10*)item)->z = ic_z->decompress(((LASpoint10*)last_item)->z, (k_bits < 19 ? k_bits : 19));
 
 	// decompress which other values have changed
 	I32 changed_values = dec->decodeSymbol(m_changed_values);
@@ -204,25 +214,40 @@
 		// decompress the edge_of_flight_line, scan_direction_flag, ... if it has changed
 		if (changed_values & 16)
 		{
-			item[14] = dec->decodeSymbol(m_bit_byte);
+      if (m_bit_byte[last_item[14]] == 0)
+      {
+        m_bit_byte[last_item[14]] = dec->createSymbolModel(256);
+        dec->initSymbolModel(m_bit_byte[last_item[14]]);
+      }
+			item[14] = dec->decodeSymbol(m_bit_byte[last_item[14]]);
 		}
 
 		// decompress the classification ... if it has changed
 		if (changed_values & 8)
 		{
-			((LASpoint10*)item)->classification = dec->decodeSymbol(m_classification);
+      if (m_classification[last_item[15]] == 0)
+      {
+        m_classification[last_item[15]] = dec->createSymbolModel(256);
+        dec->initSymbolModel(m_classification[last_item[15]]);
+      }
+			item[15] = dec->decodeSymbol(m_classification[last_item[15]]);
 		}
 		
 		// decompress the scan_angle_rank ... if it has changed
 		if (changed_values & 4)
 		{
-			((LASpoint10*)item)->scan_angle_rank = ic_scan_angle_rank->decompress(((LASpoint10*)last_item)->scan_angle_rank, k_bits < 3);
+			((I8*)item)[16] = ic_scan_angle_rank->decompress(((I8*)last_item)[16], k_bits < 3);
 		}
 
 		// decompress the user_data ... if it has changed
 		if (changed_values & 2)
 		{
-			((LASpoint10*)item)->user_data = dec->decodeSymbol(m_user_data);
+      if (m_user_data[last_item[17]] == 0)
+      {
+        m_user_data[last_item[17]] = dec->createSymbolModel(256);
+        dec->initSymbolModel(m_user_data[last_item[17]]);
+      }
+			item[17] = dec->decodeSymbol(m_user_data[last_item[17]]);
 		}
 
 		// decompress the point_source_ID ... if it has changed
diff -r 113c76a6708b -r e815143ce051 src/lasreaditemcompressed_v1.hpp
--- a/src/lasreaditemcompressed_v1.hpp	Thu Dec 23 10:11:19 2010 -0800
+++ b/src/lasreaditemcompressed_v1.hpp	Thu Dec 23 17:24:25 2010 -0800
@@ -63,7 +63,7 @@
 
 private:
   EntropyDecoder* dec;
-  U8* last_item;
+  U8 last_item[20];
 
   I32 last_x_diff[3];
   I32 last_y_diff[3];
@@ -71,13 +71,13 @@
   IntegerCompressor* ic_dx;
   IntegerCompressor* ic_dy;
   IntegerCompressor* ic_z;
+  IntegerCompressor* ic_intensity;
+  IntegerCompressor* ic_scan_angle_rank;
+  IntegerCompressor* ic_point_source_ID;
   EntropyModel* m_changed_values;
-  IntegerCompressor* ic_intensity;
-  EntropyModel* m_bit_byte;
-  EntropyModel* m_classification;
-  IntegerCompressor* ic_scan_angle_rank;
-  EntropyModel* m_user_data;
-  IntegerCompressor* ic_point_source_ID;
+  EntropyModel* m_bit_byte[256];
+  EntropyModel* m_classification[256];
+  EntropyModel* m_user_data[256];
 };
 
 class LASreadItemCompressed_GPSTIME11_v1 : public LASreadItemCompressed
diff -r 113c76a6708b -r e815143ce051 src/laswriteitemcompressed_v1.cpp
--- a/src/laswriteitemcompressed_v1.cpp	Thu Dec 23 10:11:19 2010 -0800
+++ b/src/laswriteitemcompressed_v1.cpp	Thu Dec 23 17:24:25 2010 -0800
@@ -73,43 +73,51 @@
 
 LASwriteItemCompressed_POINT10_v1::LASwriteItemCompressed_POINT10_v1(EntropyEncoder* enc)
 {
+  U32 i;
+
   /* set encoder */
   assert(enc);
   this->enc = enc;
 
   /* create models and integer compressors */
   ic_dx = new IntegerCompressor(enc, 32);  // 32 bits, 1 context
-	ic_dy = new IntegerCompressor(enc, 32, 33); // 32 bits, 33 contexts
-	ic_z = new IntegerCompressor(enc, 32, 33);  // 32 bits, 33 contexts
+	ic_dy = new IntegerCompressor(enc, 32, 20); // 32 bits, 20 contexts
+	ic_z = new IntegerCompressor(enc, 32, 20);  // 32 bits, 20 contexts
+	ic_intensity = new IntegerCompressor(enc, 16);
+	ic_scan_angle_rank = new IntegerCompressor(enc, 8, 2);
+	ic_point_source_ID = new IntegerCompressor(enc, 16);
 	m_changed_values = enc->createSymbolModel(64);
-	ic_intensity = new IntegerCompressor(enc, 16);
-	m_bit_byte = enc->createSymbolModel(256);
-  m_classification = enc->createSymbolModel(256);
-	ic_scan_angle_rank = new IntegerCompressor(enc, 8, 2);
-	m_user_data = enc->createSymbolModel(256);
-	ic_point_source_ID = new IntegerCompressor(enc, 16);
-
-  /* create last item */
-  last_item = new U8[20];
+  for (i = 0; i < 256; i++)
+  {
+    m_bit_byte[i] = 0;
+    m_classification[i] = 0;
+    m_user_data[i] = 0;
+  }
 }
 
 LASwriteItemCompressed_POINT10_v1::~LASwriteItemCompressed_POINT10_v1()
 {
+  U32 i;
+
   delete ic_dx;
   delete ic_dy;
   delete ic_z;
+  delete ic_intensity;
+  delete ic_scan_angle_rank;
+  delete ic_point_source_ID;
   enc->destroySymbolModel(m_changed_values);
-  delete ic_intensity;
-  enc->destroySymbolModel(m_bit_byte);
-  enc->destroySymbolModel(m_classification);
-  delete ic_scan_angle_rank;
-  enc->destroySymbolModel(m_user_data);
-  delete ic_point_source_ID;
-  delete [] last_item;
+  for (i = 0; i < 256; i++)
+  {
+    if (m_bit_byte[i]) enc->destroySymbolModel(m_bit_byte[i]);
+    if (m_classification[i]) enc->destroySymbolModel(m_classification[i]);
+    if (m_user_data[i]) enc->destroySymbolModel(m_user_data[i]);
+  }
 }
 
 BOOL LASwriteItemCompressed_POINT10_v1::init(const U8* item)
 {
+  U32 i;
+
   /* init state */
 	last_x_diff[0] = last_x_diff[1] = last_x_diff[2] = 0;
 	last_y_diff[0] = last_y_diff[1] = last_y_diff[2] = 0;
@@ -119,13 +127,16 @@
   ic_dx->initCompressor();
   ic_dy->initCompressor();
   ic_z->initCompressor();
+  ic_intensity->initCompressor();
+  ic_scan_angle_rank->initCompressor();
+  ic_point_source_ID->initCompressor();
   enc->initSymbolModel(m_changed_values);
-  ic_intensity->initCompressor();
-  enc->initSymbolModel(m_bit_byte);
-  enc->initSymbolModel(m_classification);
-  ic_scan_angle_rank->initCompressor();


More information about the Liblas-commits mailing list