[Liblas-commits] laszip: added pack and unpack of VLRs

liblas-commits at liblas.org liblas-commits at liblas.org
Thu May 5 20:05:49 EDT 2011


details:   http://hg.liblas.orglaszip/rev/7be77f426cc4
changeset: 219:7be77f426cc4
user:      isenburg
date:      Thu May 05 17:04:55 2011 -0700
description:
added pack and unpack of VLRs
Subject: laszip: added pack and unpack of VLRs

details:   http://hg.liblas.orglaszip/rev/ec411de55d58
changeset: 220:ec411de55d58
user:      isenburg
date:      Thu May 05 17:05:14 2011 -0700
description:
added pack and unpack of VLRs
Subject: laszip: example with packing/unpacking of VLR

details:   http://hg.liblas.orglaszip/rev/9b6736a2d308
changeset: 221:9b6736a2d308
user:      isenburg
date:      Thu May 05 17:05:48 2011 -0700
description:
example with packing/unpacking of VLR

diffstat:

 include/laszip/laszip.hpp |   25 +-
 src/laszip.cpp            |  324 +++++++++++++++++++++++++++++++++------------
 tools/laszippertest.cpp   |   19 +-
 3 files changed, 265 insertions(+), 103 deletions(-)

diffs (truncated from 508 to 300 lines):

diff -r adeb854f4738 -r 9b6736a2d308 include/laszip/laszip.hpp
--- a/include/laszip/laszip.hpp	Mon Apr 25 16:31:25 2011 -0700
+++ b/include/laszip/laszip.hpp	Thu May 05 17:05:48 2011 -0700
@@ -62,21 +62,15 @@
 {
 public:
   enum Type { BYTE = 0, SHORT, INT, LONG, FLOAT, DOUBLE, POINT10, GPSTIME11, RGB12, WAVEPACKET13 } type;
+  unsigned short size;
+  unsigned short version;
 
   // number parameter only used when setting to BYTE
   void set(LASitem::Type t, unsigned short number=1);
-
   bool is_type(LASitem::Type t) const;
-  bool supported_type() const;
-  bool supported_size() const;
-  bool supported_version() const;
   bool supported() const;
 
   const char* get_name() const;
-
-public:
-  unsigned short size;
-  unsigned short version;
 };
 
 class LASZIP_DLL LASzip
@@ -86,24 +80,31 @@
   LASzip();
   ~LASzip();
 
-  bool setup(const unsigned int num_items, const LASitem* items, const unsigned short compressor=LASZIP_COMPRESSOR_DEFAULT);
+  // pack to and unpack from VLR
+  unsigned char* bytes;
+  bool unpack(const unsigned char* bytes, const int num);
+  bool pack(unsigned char*& bytes, int& num);
+
+  // setup
+  bool setup(const unsigned char point_type, const unsigned short point_size, const unsigned short compressor=LASZIP_COMPRESSOR_DEFAULT);
+  bool setup(const unsigned short num_items, const LASitem* items, const unsigned short compressor=LASZIP_COMPRESSOR_DEFAULT);
   void set_chunk_size(const unsigned int chunk_size);
   void request_version(const unsigned int requested_version);
 
-  // to be stored in LASzip VLR
+  // stored in LASzip VLR data section
   unsigned short compressor;
   unsigned short coder;
   unsigned char version_major;
   unsigned char version_minor;
   unsigned short version_revision;
   unsigned int options;
-  unsigned int num_items;
   unsigned int chunk_size; 
   SIGNED_INT64 num_points;  /* not mandatory ... -1 if unknown */
   SIGNED_INT64 num_bytes;   /* not mandatory ... -1 if unknown */
+  unsigned short num_items;
   LASitem* items;
 
-  // not to be stored
+  // not stored LASzip VLR data section
   unsigned short requested_version;
 };
 
diff -r adeb854f4738 -r 9b6736a2d308 src/laszip.cpp
--- a/src/laszip.cpp	Mon Apr 25 16:31:25 2011 -0700
+++ b/src/laszip.cpp	Thu May 05 17:05:48 2011 -0700
@@ -29,6 +29,8 @@
 ===============================================================================
 */
 #include "laszip.hpp"
+#include "mydefs.hpp"
+#include <assert.h>
 
 LASzip::LASzip()
 {
@@ -44,11 +46,238 @@
   num_bytes = -1;
   items = 0;
   requested_version = 0;
+  bytes = 0;
 }
 
-bool LASzip::setup(const unsigned int num_items, const LASitem* items, const unsigned short compressor)
+LASzip::~LASzip()
 {
-  unsigned int i;
+  if (items) delete [] items;
+  if (bytes) delete [] bytes;
+}
+
+// unpack from VLR data
+bool LASzip::unpack(const U8* bytes, const I32 num)
+{
+  if (num < 34) return false; // too few bytes
+  if (((num - 34) % 6) != 0) return false; // wrong number bytes
+  if (((num - 34) / 6) == 0) return false; // too few items
+  num_items = (num - 34) / 6;
+  if (items) delete [] items;
+  items = new LASitem[num_items];
+
+  // the data of the LASzip VLR
+  //     U16  compressor         2 bytes 
+  //     U16  coder              2 bytes 
+  //     U8   version_major      1 byte 
+  //     U8   version_minor      1 byte
+  //     U16  version_revision   2 bytes
+  //     U32  options            4 bytes 
+  //     U32  chunk_size         4 bytes
+  //     I64  num_points         8 bytes
+  //     I64  num_bytes          8 bytes
+  //     U16  num_items          2 bytes
+  //        U16 type                2 bytes * num_items
+  //        U16 size                2 bytes * num_items
+  //        U16 version             2 bytes * num_items
+  // which totals 34+6*num_items
+
+  U16 i;
+  const U8* b = bytes;
+  compressor = *((U16*)b);
+  b += 2;
+  coder = *((U16*)b);
+  b += 2;
+  version_major = *((U8*)b);
+  b += 1;
+  version_minor = *((U8*)b);
+  b += 1;
+  version_revision = *((U16*)b);
+  b += 2;
+  options = *((U32*)b);
+  b += 4;
+  chunk_size = *((U32*)b);
+  b += 4;
+  num_points = *((I64*)b);
+  b += 8;
+  num_bytes = *((I64*)b);
+  b += 8;
+  num_items = *((U16*)b);
+  b += 2;
+  for (i = 0; i < num_items; i++)
+  {
+    items[i].type = (LASitem::Type)*((U16*)b);
+    b += 2;
+    items[i].size = *((U16*)b);
+    b += 2;
+    items[i].version = *((U16*)b);
+    b += 2;
+  }
+  assert((bytes + num) == b);
+  for (i = 0; i < num_items; i++)
+  {
+    if (!items[i].supported()) return false;
+  }
+  return true;
+}
+
+// pack to VLR data
+bool LASzip::pack(U8*& bytes, I32& num)
+{
+  num = 34 + 6*num_items;
+  if (this->bytes) delete [] this->bytes;
+  this->bytes = bytes = new U8[num];
+
+  // the data of the LASzip VLR
+  //     U16  compressor         2 bytes 
+  //     U16  coder              2 bytes 
+  //     U8   version_major      1 byte 
+  //     U8   version_minor      1 byte
+  //     U16  version_revision   2 bytes
+  //     U32  options            4 bytes 
+  //     U32  chunk_size         4 bytes
+  //     I64  num_points         8 bytes
+  //     I64  num_bytes          8 bytes
+  //     U16  num_items          2 bytes
+  //        U16 type                2 bytes * num_items
+  //        U16 size                2 bytes * num_items
+  //        U16 version             2 bytes * num_items
+  // which totals 34+6*num_items
+
+  U16 i;
+  U8* b = bytes;
+  *((U16*)b) = compressor;
+  b += 2;
+  *((U16*)b) = coder;
+  b += 2;
+  *((U8*)b) = version_major;
+  b += 1;
+  *((U8*)b) = version_minor;
+  b += 1;
+  *((U16*)b) = version_revision;
+  b += 2;
+  *((U32*)b) = options;
+  b += 4;
+  *((U32*)b) = chunk_size;
+  b += 4;
+  *((I64*)b) = num_points;
+  b += 8;
+  *((I64*)b) = num_bytes;
+  b += 8;
+  *((U16*)b) = num_items;
+  b += 2;
+  for (i = 0; i < num_items; i++)
+  {
+    *((U16*)b) = (U16)items[i].type;
+    b += 2;
+    *((U16*)b) = items[i].size;
+    b += 2;
+    *((U16*)b) = items[i].version;
+    b += 2;
+  }
+  assert((bytes + num) == b);
+  for (i = 0; i < num_items; i++)
+  {
+    if (!items[i].supported()) return false;
+  }
+  return true;
+}
+
+bool LASzip::setup(const U8 point_type, const U16 point_size, const U16 compressor)
+{
+  if (compressor > LASZIP_COMPRESSOR_POINTWISE_CHUNKED) return false;
+
+  // switch over the point types we know
+
+  BOOL have_gps_time = FALSE;
+  BOOL have_rgb = FALSE;
+  BOOL have_wavepacket = FALSE;
+  I32 extra_bytes_number = 0;
+
+  switch (point_type)
+  {
+  case 0:
+    extra_bytes_number = (I32)point_size - 20;
+    break;
+  case 1:
+    have_gps_time = TRUE;
+    extra_bytes_number = (I32)point_size - 28;
+    break;
+  case 2:
+    have_rgb = TRUE;
+    extra_bytes_number = (I32)point_size - 26;
+    break;
+  case 3:
+    have_gps_time = TRUE;
+    have_rgb = TRUE;
+    extra_bytes_number = (I32)point_size - 34;
+    break;
+  case 4:
+    have_gps_time = TRUE;
+    have_wavepacket = TRUE;
+    extra_bytes_number = (I32)point_size - 57;
+    break;
+  case 5:
+    have_gps_time = TRUE;
+    have_rgb = TRUE;
+    have_wavepacket = TRUE;
+    extra_bytes_number = (I32)point_size - 63;
+    break;
+  default:
+    return false;
+  }
+
+  if (extra_bytes_number < 0) return false;
+
+  // create item description
+
+  if (items) delete [] items;
+  num_items = 1 + !!(have_gps_time) + !!(have_rgb) + !!(have_wavepacket) + !!(extra_bytes_number);
+  items = new LASitem[num_items];
+
+  U16 i = 1;
+  items[0].type = LASitem::POINT10;
+  items[0].size = 20;
+  items[0].version = 0;
+  if (have_gps_time)
+  {
+    items[i].type = LASitem::GPSTIME11;
+    items[i].size = 8;
+    items[i].version = 0;
+    i++;
+  }
+  if (have_rgb)
+  {
+    items[i].type = LASitem::RGB12;
+    items[i].size = 6;
+    items[i].version = 0;
+    i++;
+  }
+  if (have_wavepacket)
+  {
+    items[i].type = LASitem::WAVEPACKET13;
+    items[i].size = 29;
+    items[i].version = 0;
+    i++;
+  }
+  if (extra_bytes_number)
+  {
+    items[i].type = LASitem::BYTE;
+    items[i].size = extra_bytes_number;
+    items[i].version = 0;
+    i++;


More information about the Liblas-commits mailing list