1 /*
2 ===============================================================================
3 
4   FILE:  laszip.hpp
5 
6   CONTENTS:
7 
8     Contains LASitem and LASchunk structs as well as the IDs of the currently
9     supported entropy coding scheme
10 
11   PROGRAMMERS:
12 
13     martin.isenburg@rapidlasso.com  -  http://rapidlasso.com
14 
15   COPYRIGHT:
16 
17     (c) 2007-2019, martin isenburg, rapidlasso - fast tools to catch reality
18 
19     This is free software; you can redistribute and/or modify it under the
20     terms of the GNU Lesser General Licence as published by the Free Software
21     Foundation. See the COPYING file for more information.
22 
23     This software is distributed WITHOUT ANY WARRANTY and without even the
24     implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
25 
26   CHANGE HISTORY:
27 
28     20 March 2019 -- upped to 3.3 r1 for consistent legacy and extended class check
29     21 February 2019 -- bug fix when writing 4294967295+ points uncompressed to LAS
30     28 December 2018 -- fix for v4 decompression of WavePacket part of PRDF 9 and 10
31     27 December 2018 -- upped to 3.2 r9 for bug fix in multi-channel NIR decompression
32      7 November 2018 -- upped to 3.2 r8 for identical legacy and extended flags check
33     20 October 2018 -- upped to 3.2 r7 for rare bug in LASinterval::merge_intervals()
34      5 October 2018 -- upped to 3.2 r6 for corrected 'is_empty' return value
35     28 September 2018 -- upped to 3.2 r5 for fix in extended classification writing
36      9 February 2018 -- minor version increment as it can read v4 compressed items
37     28 December 2017 -- fix incorrect 'context switch' reported by Wanwannodao
38     23 August 2017 -- minor version increment for C++ stream-based read/write API
39     28 May 2017 -- support for "LAS 1.4 selective decompression" added into DLL API
40      8 April 2017 -- new check for whether point size and total size of items match
41     30 March 2017 -- support for "native LAS 1.4 extension" added into main branch
42      7 January 2017 -- set reserved VLR field from 0xAABB to 0x0 in DLL
43      7 January 2017 -- consistent compatibility mode scan angle quantization in DLL
44      7 January 2017 -- compatibility mode *decompression* fix for waveforms in DLL
45     25 February 2016 -- depreciating old libLAS laszipper/lasunzipper binding
46     29 July 2013 -- reorganized to create an easy-to-use LASzip DLL
47      5 December 2011 -- learns the chunk table if it is missing (e.g. truncated LAZ)
48      6 October 2011 -- large file support, ability to read with missing chunk table
49     23 June 2011 -- turned on LASzip version 2.0 compressor with chunking
50      8 May 2011 -- added an option for variable chunking via chunk()
51     23 April 2011 -- changed interface for simplicity and chunking support
52     20 March 2011 -- incrementing LASZIP_VERSION to 1.2 for improved compression
53     10 January 2011 -- licensing change for LGPL release and liblas integration
54     12 December 2010 -- refactored from lasdefinitions after movies with silke
55 
56 ===============================================================================
57 */
58 #ifndef LASZIP_HPP
59 #define LASZIP_HPP
60 
61 #if defined(_MSC_VER) && (_MSC_VER < 1300)
62 #define LZ_WIN32_VC6
63 typedef __int64   SIGNED_INT64;
64 #else
65 typedef long long SIGNED_INT64;
66 #endif
67 
68 #if defined(_MSC_VER) && (_MSC_FULL_VER >= 150000000)
69 #define LASCopyString _strdup
70 #else
71 #define LASCopyString strdup
72 #endif
73 
74 #define LASZIP_VERSION_MAJOR                3
75 #define LASZIP_VERSION_MINOR                4
76 #define LASZIP_VERSION_REVISION             3
77 #define LASZIP_VERSION_BUILD_DATE      191111
78 
79 #define LASZIP_COMPRESSOR_NONE              0
80 #define LASZIP_COMPRESSOR_POINTWISE         1
81 #define LASZIP_COMPRESSOR_POINTWISE_CHUNKED 2
82 #define LASZIP_COMPRESSOR_LAYERED_CHUNKED   3
83 #define LASZIP_COMPRESSOR_TOTAL_NUMBER_OF   4
84 
85 #define LASZIP_COMPRESSOR_CHUNKED LASZIP_COMPRESSOR_POINTWISE_CHUNKED
86 #define LASZIP_COMPRESSOR_NOT_CHUNKED LASZIP_COMPRESSOR_POINTWISE
87 
88 #define LASZIP_COMPRESSOR_DEFAULT LASZIP_COMPRESSOR_CHUNKED
89 
90 #define LASZIP_CODER_ARITHMETIC             0
91 #define LASZIP_CODER_TOTAL_NUMBER_OF        1
92 
93 #define LASZIP_CHUNK_SIZE_DEFAULT           50000
94 
95 class LASitem
96 {
97 public:
98   enum Type { BYTE = 0, SHORT, INT, LONG, FLOAT, DOUBLE, POINT10, GPSTIME11, RGB12, WAVEPACKET13, POINT14, RGB14, RGBNIR14, WAVEPACKET14, BYTE14 } type;
99   unsigned short size;
100   unsigned short version;
101   bool is_type(LASitem::Type t) const;
102   const char* get_name() const;
103 };
104 
105 class LASzip
106 {
107 public:
108 
109   // supported version control
110   bool check_compressor(const unsigned short compressor);
111   bool check_coder(const unsigned short coder);
112   bool check_item(const LASitem* item);
113   bool check_items(const unsigned short num_items, const LASitem* items, const unsigned short point_size=0);
114   bool check(const unsigned short point_size=0);
115 
116   // go back and forth between item array and point type & size
117   bool setup(unsigned short* num_items, LASitem** items, const unsigned char point_type, const unsigned short point_size, const unsigned short compressor=LASZIP_COMPRESSOR_NONE);
118   bool is_standard(const unsigned short num_items, const LASitem* items, unsigned char* point_type=0, unsigned short* record_length=0);
119   bool is_standard(unsigned char* point_type=0, unsigned short* record_length=0);
120 
121   // pack to and unpack from VLR
122   unsigned char* bytes;
123   bool unpack(const unsigned char* bytes, const int num);
124   bool pack(unsigned char*& bytes, int& num);
125 
126   // setup
127   bool request_compatibility_mode(const unsigned short requested_compatibility_mode=0); // 0 = none, 1 = LAS 1.4 compatibility mode
128   bool setup(const unsigned char point_type, const unsigned short point_size, const unsigned short compressor=LASZIP_COMPRESSOR_DEFAULT);
129   bool setup(const unsigned short num_items, const LASitem* items, const unsigned short compressor);
130   bool set_chunk_size(const unsigned int chunk_size);             /* for compressor only */
131   bool request_version(const unsigned short requested_version);   /* for compressor only */
132 
133   // in case a function returns false this string describes the problem
134   const char* get_error() const;
135 
136   // stored in LASzip VLR data section
137   unsigned short compressor;
138   unsigned short coder;
139   unsigned char version_major;
140   unsigned char version_minor;
141   unsigned short version_revision;
142   unsigned int options;
143   unsigned int chunk_size;
144   SIGNED_INT64 number_of_special_evlrs; /* must be -1 if unused */
145   SIGNED_INT64 offset_to_special_evlrs; /* must be -1 if unused */
146   unsigned short num_items;
147   LASitem* items;
148 
149   LASzip();
150   ~LASzip();
151 
152 private:
153   bool return_error(const char* err);
154   char* error_string;
155 };
156 
157 #endif
158