[Liblas-commits] laszip: adding laszip version 2.0

liblas-commits at liblas.org liblas-commits at liblas.org
Tue Mar 22 09:05:41 EDT 2011


details:   http://hg.liblas.orglaszip/rev/b56e6d3ad22f
changeset: 186:b56e6d3ad22f
user:      isenburg
date:      Mon Mar 21 04:20:11 2011 -0700
description:
adding laszip version 2.0

diffstat:

 src/lasreaditemcompressed_v2.cpp  |  567 +++++++++++++++++++++++++++++++++++
 src/lasreaditemcompressed_v2.hpp  |  136 ++++++++
 src/laswriteitemcompressed_v2.cpp |  601 ++++++++++++++++++++++++++++++++++++++
 src/laswriteitemcompressed_v2.hpp |  136 ++++++++
 src/laszip_common_v2.hpp          |  186 +++++++++++
 5 files changed, 1626 insertions(+), 0 deletions(-)

diffs (truncated from 1646 to 300 lines):

diff -r b187957e98ef -r b56e6d3ad22f src/lasreaditemcompressed_v2.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lasreaditemcompressed_v2.cpp	Mon Mar 21 04:20:11 2011 -0700
@@ -0,0 +1,567 @@
+/*
+===============================================================================
+
+  FILE:  lasreaditemcompressed_v2.cpp
+  
+  CONTENTS:
+  
+    see corresponding header file
+  
+  PROGRAMMERS:
+
+    martin.isenburg at gmail.com
+
+  COPYRIGHT:
+
+    (c) 2011, Martin Isenburg, LASSO - tools to catch reality
+
+    This is free software; you can redistribute and/or modify it under the
+    terms of the GNU Lesser General Licence as published by the Free Software
+    Foundation. See the COPYING file for more information.
+
+    This software is distributed WITHOUT ANY WARRANTY and without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  
+  CHANGE HISTORY:
+  
+    see corresponding header file
+  
+===============================================================================
+*/
+
+#include "lasreaditemcompressed_v2.hpp"
+
+#include <assert.h>
+#include <string.h>
+
+struct LASpoint10
+{
+  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_v2::LASreadItemCompressed_POINT10_v2(EntropyDecoder* dec)
+{
+  U32 i;
+
+  /* set decoder */
+  assert(dec);
+  this->dec = dec;
+
+  /* create models and integer compressors */
+  m_changed_values = dec->createSymbolModel(64);
+  ic_intensity = new IntegerCompressor(dec, 16, 4);
+  m_scan_angle_rank[0] = dec->createSymbolModel(256);
+  m_scan_angle_rank[1] = dec->createSymbolModel(256);
+  ic_point_source_ID = new IntegerCompressor(dec, 16);
+  for (i = 0; i < 256; i++)
+  {
+    m_bit_byte[i] = 0;
+    m_classification[i] = 0;
+    m_user_data[i] = 0;
+  }
+  ic_dx = new IntegerCompressor(dec, 32, 2);  // 32 bits, 2 context
+  ic_dy = new IntegerCompressor(dec, 32, 22); // 32 bits, 22 contexts
+  ic_z = new IntegerCompressor(dec, 32, 20);  // 32 bits, 20 contexts
+}
+
+LASreadItemCompressed_POINT10_v2::~LASreadItemCompressed_POINT10_v2()
+{
+  U32 i;
+
+  dec->destroySymbolModel(m_changed_values);
+  delete ic_intensity;
+  dec->destroySymbolModel(m_scan_angle_rank[0]);
+  dec->destroySymbolModel(m_scan_angle_rank[1]);
+  delete ic_point_source_ID;
+  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]);
+  }
+  delete ic_dx;
+  delete ic_dy;
+  delete ic_z;
+}
+
+BOOL LASreadItemCompressed_POINT10_v2::init(const U8* item)
+{
+  U32 i;
+
+  /* init state */
+  for (i=0; i < 16; i++)
+  {
+    last_x_diff_median5[i].init();
+    last_y_diff_median5[i].init();
+    last_intensity[i] = 0;
+    last_height[i/2] = 0;
+  }
+
+  /* init models and integer compressors */
+  dec->initSymbolModel(m_changed_values);
+  ic_intensity->initDecompressor();
+  dec->initSymbolModel(m_scan_angle_rank[0]);
+  dec->initSymbolModel(m_scan_angle_rank[1]);
+  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]);
+  }
+  ic_dx->initDecompressor();
+  ic_dy->initDecompressor();
+  ic_z->initDecompressor();
+
+  /* init last item */
+  memcpy(last_item, item, 20);
+
+  return TRUE;
+}
+
+inline BOOL LASreadItemCompressed_POINT10_v2::read(U8* item)
+{
+  U32 r, n, m, l;
+  U32 k_bits;
+  I32 median, diff;
+
+  // decompress which other values have changed
+  I32 changed_values = dec->decodeSymbol(m_changed_values);
+
+  if (changed_values)
+  {
+    // decompress the edge_of_flight_line, scan_direction_flag, ... if it has changed
+    if (changed_values & 32)
+    {
+      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]]);
+      }
+      last_item[14] = (U8)dec->decodeSymbol(m_bit_byte[last_item[14]]);
+    }
+
+    r = ((LASpoint10*)last_item)->return_number;
+    n = ((LASpoint10*)last_item)->number_of_returns_of_given_pulse;
+    m = number_return_map[n][r];
+    l = number_return_level[n][r];
+
+    // decompress the intensity if it has changed
+    if (changed_values & 16)
+    {
+      ((LASpoint10*)last_item)->intensity = (U16)ic_intensity->decompress(last_intensity[m], (m < 3 ? m : 3));
+      last_intensity[m] = ((LASpoint10*)last_item)->intensity;
+    }
+    else
+    {
+      ((LASpoint10*)last_item)->intensity = last_intensity[m];
+    }
+
+    // decompress the classification ... if it has changed
+    if (changed_values & 8)
+    {
+      if (m_classification[last_item[15]] == 0)
+      {
+        m_classification[last_item[15]] = dec->createSymbolModel(256);
+        dec->initSymbolModel(m_classification[last_item[15]]);
+      }
+      last_item[15] = (U8)dec->decodeSymbol(m_classification[last_item[15]]);
+    }
+    
+    // decompress the scan_angle_rank ... if it has changed
+    if (changed_values & 4)
+    {
+      I32 val = dec->decodeSymbol(m_scan_angle_rank[((LASpoint10*)last_item)->scan_direction_flag]);
+      last_item[16] = U8_FOLD(val + last_item[16]);
+    }
+
+    // decompress the user_data ... if it has changed
+    if (changed_values & 2)
+    {
+      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]]);
+      }
+      last_item[17] = (U8)dec->decodeSymbol(m_user_data[last_item[17]]);
+    }
+
+    // decompress the point_source_ID ... if it has changed
+    if (changed_values & 1)
+    {
+      ((LASpoint10*)last_item)->point_source_ID = (U16)ic_point_source_ID->decompress(((LASpoint10*)last_item)->point_source_ID);
+    }
+  }
+  else
+  {
+    r = ((LASpoint10*)last_item)->return_number;
+    n = ((LASpoint10*)last_item)->number_of_returns_of_given_pulse;
+    m = number_return_map[n][r];
+    l = number_return_level[n][r];
+  }
+
+  // decompress x coordinate
+  median = last_x_diff_median5[m].get();
+  diff = ic_dx->decompress(median, n==1);
+  ((LASpoint10*)last_item)->x += diff;
+  last_x_diff_median5[m].add(diff);
+
+  // decompress y coordinate
+  median = last_y_diff_median5[m].get();
+  k_bits = ic_dx->getK();
+  diff = ic_dy->decompress(median, (n==1) + ( k_bits < 20 ? U32_ZERO_BIT_0(k_bits) : 20 ));
+  ((LASpoint10*)last_item)->y += diff;
+  last_y_diff_median5[m].add(diff);
+
+  // decompress z coordinate
+  k_bits = (ic_dx->getK() + ic_dy->getK()) / 2;
+  ((LASpoint10*)last_item)->z = ic_z->decompress(last_height[l], (n==1) + (k_bits < 18 ? U32_ZERO_BIT_0(k_bits) : 18));
+  last_height[l] = ((LASpoint10*)last_item)->z;
+
+  // copy the last point
+  memcpy(item, last_item, 20);
+  return TRUE;
+}
+
+/*
+===============================================================================
+                       LASreadItemCompressed_GPSTIME11_v2
+===============================================================================
+*/
+
+#define LASZIP_GPSTIME_MULTI 512
+#define LASZIP_GPSTIME_MULTI_1024 (LASZIP_GPSTIME_MULTI + 0)
+#define LASZIP_GPSTIME_MULTI_2048 (LASZIP_GPSTIME_MULTI + 1)
+#define LASZIP_GPSTIME_MULTI_4096 (LASZIP_GPSTIME_MULTI + 2)
+#define LASZIP_GPSTIME_MULTI_MINUS_11000 (LASZIP_GPSTIME_MULTI + 3)
+#define LASZIP_GPSTIME_MULTI_MINUS_5500 (LASZIP_GPSTIME_MULTI + 4)
+#define LASZIP_GPSTIME_MULTI_MINUS_550 (LASZIP_GPSTIME_MULTI + 5)
+#define LASZIP_GPSTIME_MULTI_MINUS_55 (LASZIP_GPSTIME_MULTI + 6)
+#define LASZIP_GPSTIME_MULTI_MINUS_5 (LASZIP_GPSTIME_MULTI + 7)
+#define LASZIP_GPSTIME_MULTI_UNCHANGED (LASZIP_GPSTIME_MULTI + 8)
+#define LASZIP_GPSTIME_MULTI_DOUBLE (LASZIP_GPSTIME_MULTI + 9)
+
+#define LASZIP_GPSTIME_MULTI_TOTAL (LASZIP_GPSTIME_MULTI + 10) 
+
+LASreadItemCompressed_GPSTIME11_v2::LASreadItemCompressed_GPSTIME11_v2(EntropyDecoder* dec)
+{
+  /* set decoder */
+  assert(dec);
+  this->dec = dec;
+  /* create entropy models and integer compressors */
+  m_gpstime_multi = dec->createSymbolModel(LASZIP_GPSTIME_MULTI_TOTAL);
+  m_gpstime_0diff = dec->createSymbolModel(3);
+  ic_gpstime = new IntegerCompressor(dec, 32, 7); // 32 bits, 7 contexts
+}
+
+LASreadItemCompressed_GPSTIME11_v2::~LASreadItemCompressed_GPSTIME11_v2()
+{
+  dec->destroySymbolModel(m_gpstime_multi);
+  dec->destroySymbolModel(m_gpstime_0diff);
+  delete ic_gpstime;
+}
+
+BOOL LASreadItemCompressed_GPSTIME11_v2::init(const U8* item)
+{
+  /* init state */
+  last_gpstime_diff = 0;
+  multi_extreme_counter = 0;
+
+  /* init models and integer compressors */
+  dec->initSymbolModel(m_gpstime_multi);
+  dec->initSymbolModel(m_gpstime_0diff);
+  ic_gpstime->initDecompressor();
+
+  /* init last item */
+  last_gpstime.u64 = *((U64*)item);
+  return TRUE;
+}
+
+inline BOOL LASreadItemCompressed_GPSTIME11_v2::read(U8* item)
+{
+  I32 multi;
+  if (last_gpstime_diff == 0) // if the last integer difference was zero
+  {
+    multi = dec->decodeSymbol(m_gpstime_0diff);


More information about the Liblas-commits mailing list