[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