[Liblas-commits] laszip: allows variable-sized chunking with explicit zipper.chun...

liblas-commits at liblas.org liblas-commits at liblas.org
Mon May 9 16:02:10 EDT 2011


details:   http://hg.liblas.orglaszip/rev/89966fbc7885
changeset: 224:89966fbc7885
user:      isenburg
date:      Mon May 09 13:03:25 2011 -0700
description:
allows variable-sized chunking with explicit zipper.chunk() call when chunk_size == 0
Subject: laszip: allows variable-sized chunking with explicit zipper.chunk() call when chunk_size == 0

details:   http://hg.liblas.orglaszip/rev/18dca0c2b4cc
changeset: 225:18dca0c2b4cc
user:      isenburg
date:      Mon May 09 13:04:25 2011 -0700
description:
allows variable-sized chunking with explicit zipper.chunk() call when chunk_size == 0

diffstat:

 include/laszip/laszip.hpp    |   6 ++-
 include/laszip/laszipper.hpp |   4 ++-
 src/lasreadpoint.cpp         |  61 ++++++++++++++++++++++++++++++++++++++-----
 src/lasreadpoint.hpp         |   4 ++
 src/laswritepoint.cpp        |  31 ++++++++++++++++++++-
 src/laswritepoint.hpp        |   3 ++
 src/laszipper.cpp            |   5 +++
 7 files changed, 101 insertions(+), 13 deletions(-)

diffs (truncated from 341 to 300 lines):

diff -r 3fc5cbb8490e -r 18dca0c2b4cc include/laszip/laszip.hpp
--- a/include/laszip/laszip.hpp	Fri May 06 05:53:12 2011 -0700
+++ b/include/laszip/laszip.hpp	Mon May 09 13:04:25 2011 -0700
@@ -14,7 +14,7 @@
   
   COPYRIGHT:
 
-    (c) 2010-2011, Martin Isenburg, LASSO - tools to catch reality
+    (c) 2007-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
@@ -25,7 +25,9 @@
   
   CHANGE HISTORY:
   
-    20 March 2011 -- incrementing LASZIP_VERSION to 2.0 for improved compression
+    8 May 2011 -- added an option for variable chunking via chunk()
+    23 April 2011 -- changed interface for simplicity and chunking support
+    20 March 2011 -- incrementing LASZIP_VERSION to 1.2 for improved compression
     10 January 2011 -- licensing change for LGPL release and liblas integration
     12 December 2010 -- refactored from lasdefinitions after movies with silke
   
diff -r 3fc5cbb8490e -r 18dca0c2b4cc include/laszip/laszipper.hpp
--- a/include/laszip/laszipper.hpp	Fri May 06 05:53:12 2011 -0700
+++ b/include/laszip/laszipper.hpp	Mon May 09 13:04:25 2011 -0700
@@ -24,7 +24,8 @@
   
   CHANGE HISTORY:
   
-    23 April 2011 -- changed interface for easier future compressor support
+    8 May 2011 -- added an option for variable chunking via chunk()
+    23 April 2011 -- changed interface for simplicity and chunking support
     10 January 2011 -- licensing change for LGPL release and liblas integration
     12 December 2010 -- created from LASwriter/LASreader after Howard got pushy (-;
   
@@ -55,6 +56,7 @@
   unsigned int open(FILE* outfile);
   unsigned int open(ostream& outstream);
   bool write(const unsigned char* const * point);
+  bool chunk();
   unsigned int close();
 
   LASzipper();
diff -r 3fc5cbb8490e -r 18dca0c2b4cc src/lasreadpoint.cpp
--- a/src/lasreadpoint.cpp	Fri May 06 05:53:12 2011 -0700
+++ b/src/lasreadpoint.cpp	Mon May 09 13:04:25 2011 -0700
@@ -50,7 +50,9 @@
   // used for chunking
   chunk_size = U32_MAX;
   chunk_count = 0;
+  current_chunk = 0;
   number_chunks = 0;
+  chunk_totals = 0;
   chunk_starts = 0;
   // used for seeking
   seek_point = 0;
@@ -85,6 +87,9 @@
   readers = 0;
   num_readers = num_items;
 
+  // disable chunking
+  chunk_size = U32_MAX;
+
   // always create the raw readers
   readers_raw = new LASreadItem*[num_readers];
   for (i = 0; i < num_readers; i++)
@@ -186,7 +191,7 @@
     }
     if (laszip->compressor == LASZIP_COMPRESSOR_POINTWISE_CHUNKED)
     {
-      chunk_size = laszip->chunk_size;
+      if (laszip->chunk_size) chunk_size = laszip->chunk_size;
       number_chunks = U32_MAX;
     }
   }
@@ -198,12 +203,14 @@
   if (!instream) return FALSE;
   this->instream = instream;
 
+  // if chunking is enabled
   if (number_chunks == U32_MAX)
   {
     if (!read_chunk_table())
     {
       return FALSE;
     }
+    current_chunk = 0;
   }
 
   point_start = instream->position();
@@ -232,17 +239,27 @@
   U32 delta = 0;
   if (dec)
   {
-    if (number_chunks)
+    if (chunk_starts)
     {
-      U32 current_chunk = current/chunk_size;
-      U32 target_chunk = target/chunk_size;
+      U32 target_chunk;
+      if (chunk_totals)
+      {
+        target_chunk = search_chunk_table(target, 0, number_chunks);
+        chunk_size = chunk_totals[target_chunk+1]-chunk_totals[target_chunk];
+        delta = target - chunk_totals[target_chunk];
+      }
+      else
+      {
+        target_chunk = target/chunk_size;
+        delta = target%chunk_size;
+      }
       if (current_chunk != target_chunk || current > target)
       {
         dec->done();
-        instream->seek(chunk_starts[target_chunk]);
+        current_chunk = target_chunk;
+        instream->seek(chunk_starts[current_chunk]);
         init(instream);
         chunk_count = 0;
-        delta = target%chunk_size;
       }
       else
       {
@@ -282,6 +299,11 @@
 
   if (chunk_count == chunk_size)
   {
+    current_chunk++;
+    if (chunk_totals)
+    {
+      chunk_size = chunk_totals[current_chunk+1]-chunk_totals[current_chunk];
+    }
     dec->done();
     init(instream);
     chunk_count = 0;
@@ -353,12 +375,25 @@
   {
     return FALSE;
   }
+  if (chunk_totals) delete [] chunk_totals;
+  chunk_totals = 0;
   if (chunk_starts) delete [] chunk_starts;
-  chunk_starts = new long[number_chunks];
+  chunk_starts = 0;
+  if (chunk_size == U32_MAX) chunk_totals = new U32[number_chunks+1];
+  chunk_starts = new long[number_chunks+1];
+  if (chunk_size == U32_MAX) chunk_totals[0] = 0;
   chunk_starts[0] = chunks_start;
   U32 i;
-  for (i = 1; i < number_chunks; i++)
+  for (i = 1; i <= number_chunks; i++)
   {
+    if (chunk_size == U32_MAX)
+    {
+      if (!instream->get32bitsLE((U8*)&chunk_totals[i]))
+      {
+        return FALSE;
+      }
+      chunk_totals[i] += chunk_totals[i-1];
+    }
     if (!instream->get32bitsLE((U8*)&chunk_starts[i]))
     {
       return FALSE;
@@ -369,6 +404,16 @@
   return TRUE;
 }
 
+U32 LASreadPoint::search_chunk_table(const U32 index, const U32 lower, const U32 upper)
+{
+  if (lower + 1 == upper) return lower;
+  U32 mid = (lower+upper)/2;
+  if (index >= chunk_totals[mid])
+    return search_chunk_table(index, mid, upper);
+  else
+    return search_chunk_table(index, lower, mid);
+}
+
 LASreadPoint::~LASreadPoint()
 {
   U32 i;
diff -r 3fc5cbb8490e -r 18dca0c2b4cc src/lasreadpoint.hpp
--- a/src/lasreadpoint.hpp	Fri May 06 05:53:12 2011 -0700
+++ b/src/lasreadpoint.hpp	Mon May 09 13:04:25 2011 -0700
@@ -24,6 +24,7 @@
   
   CHANGE HISTORY:
   
+    25 April 2011 -- added chunked laszip for random access decompression
     10 January 2011 -- licensing change for LGPL release and liblas integration
     7 December 2010 -- adapted from LASpointReader for better code modularity
     3 December 2010 -- updated to (somewhat) support LAS format 1.3
@@ -66,9 +67,12 @@
   // used for chunking
   U32 chunk_size;
   U32 chunk_count;
+  U32 current_chunk;
   U32 number_chunks;
   long* chunk_starts;
+  U32* chunk_totals;
   BOOL read_chunk_table();
+  U32 search_chunk_table(const U32 index, const U32 lower, const U32 upper);
   // used for seeking
   U32 point_start;
   U32 point_size;
diff -r 3fc5cbb8490e -r 18dca0c2b4cc src/laswritepoint.cpp
--- a/src/laswritepoint.cpp	Fri May 06 05:53:12 2011 -0700
+++ b/src/laswritepoint.cpp	Mon May 09 13:04:25 2011 -0700
@@ -52,8 +52,10 @@
   chunk_count = 0;
   number_chunks = 0;
   alloced_chunks = 0;
+  chunk_sizes = 0;
   chunk_bytes = 0;
   chunk_table_start_position = 0;
+  chunk_start_position = 0;
 }
 
 BOOL LASwritePoint::setup(const U32 num_items, const LASitem* items, LASzip* laszip)
@@ -195,7 +197,7 @@
     }
     if (laszip->compressor == LASZIP_COMPRESSOR_POINTWISE_CHUNKED)
     {
-      chunk_size = laszip->chunk_size;
+      if (laszip->chunk_size) chunk_size = laszip->chunk_size;
       chunk_count = 0;
       number_chunks = U32_MAX;
     }
@@ -208,6 +210,7 @@
   if (!outstream) return FALSE;
   this->outstream = outstream;
 
+  // if chunking is enabled
   if (number_chunks == U32_MAX)
   {
     number_chunks = 0;
@@ -273,13 +276,26 @@
   }
   return TRUE;
 }
+
+BOOL LASwritePoint::chunk()
+{
+  if (chunk_start_position == 0 || chunk_size != U32_MAX)
+  {
+    return FALSE;
+  }
+  enc->done();
+  add_chunk_to_table();
+  init(outstream);
+  chunk_count = 0;
+  return TRUE;
+}
 
 BOOL LASwritePoint::done()
 {
   if (writers == writers_compressed)
   {
     enc->done();
-    if (chunk_size != U32_MAX)
+    if (chunk_start_position)
     {
       if (chunk_count) add_chunk_to_table();
       return write_chunk_table();
@@ -295,16 +311,20 @@
     if (chunk_bytes == 0)
     {
       alloced_chunks = 1024;
+      if (chunk_size == U32_MAX) chunk_sizes = (U32*)malloc(sizeof(U32)*alloced_chunks); 
       chunk_bytes = (U32*)malloc(sizeof(U32)*alloced_chunks); 
     }
     else
     {
       alloced_chunks *= 2;
+      if (chunk_size == U32_MAX) chunk_sizes = (U32*)realloc(chunk_sizes, sizeof(U32)*alloced_chunks); 
       chunk_bytes = (U32*)realloc(chunk_bytes, sizeof(U32)*alloced_chunks); 
     }
+    if (chunk_size == U32_MAX && chunk_sizes == 0) return FALSE;
     if (chunk_bytes == 0) return FALSE;
   }
   I64 position = outstream->position();
+  if (chunk_size == U32_MAX) chunk_sizes[number_chunks] = chunk_count;
   chunk_bytes[number_chunks] = (U32)(position - chunk_start_position);
   chunk_start_position = position;
   number_chunks++;
@@ -336,6 +356,13 @@
   }
   for (i = 0; i < number_chunks; i++)
   {
+    if (chunk_size == U32_MAX) 
+    {
+      if (!outstream->put32bitsLE((U8*)&chunk_sizes[i]))
+      {
+        return FALSE;
+      }
+    }
     if (!outstream->put32bitsLE((U8*)&chunk_bytes[i]))
     {
       return FALSE;
diff -r 3fc5cbb8490e -r 18dca0c2b4cc src/laswritepoint.hpp


More information about the Liblas-commits mailing list