1 /*
2 ===============================================================================
3 
4   FILE:  io.hpp
5 
6   CONTENTS:
7     LAZ io
8 
9   PROGRAMMERS:
10 
11     martin.isenburg@rapidlasso.com  -  http://rapidlasso.com
12     uday.karan@gmail.com - Hobu, Inc.
13 
14   COPYRIGHT:
15 
16     (c) 2007-2014, martin isenburg, rapidlasso - tools to catch reality
17     (c) 2014, Uday Verma, Hobu, Inc.
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 ===============================================================================
29 */
30 
31 #pragma once
32 
33 #include <cstdint>
34 #include <fstream>
35 
36 #include "las.hpp"
37 #include "streams.hpp"
38 #include "vlr.hpp"
39 #include "charbuf.hpp"
40 
41 #pragma once
42 
43 namespace lazperf
44 {
45 namespace io
46 {
47 const uint32_t DefaultChunkSize = 50000;
48 
49 #pragma pack(push, 1)
50 struct vector3
51 {
vector3lazperf::io::vector352     vector3() : x(0), y(0), z(0)
53     {}
54 
vector3lazperf::io::vector355     vector3(double x, double y, double z) : x(x), y(y), z(z)
56     {}
57 
58     double x;
59     double y;
60     double z;
61 };
62 
63 struct header
64 {
65     char magic[4] { 'L', 'A', 'S', 'F' };
66     uint16_t file_source_id {};
67     uint16_t global_encoding {};
68     char guid[16] {};
69 
70     struct {
71         uint8_t major {1};
72         uint8_t minor {3};
73     } version;
74 
75     char system_identifier[32] {};
76     char generating_software[32] {};
77 
78     struct {
79         uint16_t day {};
80         uint16_t year {};
81     } creation;
82 
83     uint16_t header_size {};
84     uint32_t point_offset {};
85     uint32_t vlr_count {};
86 
87     uint8_t point_format_id {};
88     uint16_t point_record_length {};
89 
90     uint32_t point_count {};
91     uint32_t points_by_return[5] {};
92 
93     vector3 scale;
94     vector3 offset;
95     vector3 minimum;
96     vector3 maximum;
97 
98     int ebCount() const;
99 };
100 
101 struct header14 : public header
102 {
103     uint64_t wave_offset {0};
104     uint64_t evlr_offset {0};
105     uint32_t elvr_count {0};
106     uint64_t point_count_14 {0};
107     uint64_t points_by_return_14[15] {};
108 };
109 #pragma pack(pop)
110 } // namespace io
111 
112 #define FRIEND_TEST(test_case_name, test_name) \
113     friend class test_case_name##_##test_name##_Test
114 
115 namespace reader
116 {
117 
118 class basic_file
119 {
120     FRIEND_TEST(io_tests, parses_laszip_vlr_correctly);
121     struct Private;
122 
123 protected:
124     basic_file();
125     ~basic_file();
126 
127     void open(std::istream& in);
128 
129 public:
130     size_t pointCount() const;
131     const io::header& header() const;
132     void readPoint(char *out);
133 
134 private:
135     // The file object is not copyable or copy constructible
136     basic_file(const basic_file&) = delete;
137     basic_file& operator = (const basic_file&) = delete;
138 
139     std::unique_ptr<Private> p_;
140 };
141 
142 class mem_file : public basic_file
143 {
144     struct Private;
145 
146 public:
147     mem_file(char *buf, size_t count);
148     ~mem_file();
149 
150 private:
151     std::unique_ptr<Private> p_;
152 };
153 
154 class generic_file : public basic_file
155 {
156 public:
157     generic_file(std::istream& in);
158 };
159 
160 class named_file : public basic_file
161 {
162     struct Private;
163 
164 public:
165     named_file(const std::string& filename);
166     ~named_file();
167 
168 private:
169     std::unique_ptr<Private> p_;
170 };
171 
172 } // namespace reader
173 
174 
175 namespace writer
176 {
177 
178 class basic_file
179 {
180 protected:
181     struct Private;
182 
183     basic_file();
184     virtual ~basic_file();
185 
186 public:
187     void open(std::ostream& out, const io::header& h, uint32_t chunk_size);
188     void writePoint(const char *p);
189     void close();
190     virtual bool compressed() const;
191 
192 protected:
193     std::unique_ptr<Private> p_;
194 };
195 
196 class named_file : public basic_file
197 {
198     struct Private;
199 
200 public:
201     struct config
202     {
203     public:
204         io::vector3 scale;
205         io::vector3 offset;
206         unsigned int chunk_size;
207         int pdrf;
208         int minor_version;
209         int extra_bytes;
210 
211         explicit config();
212         config(const io::vector3& scale, const io::vector3& offset,
213             unsigned int chunksize = io::DefaultChunkSize);
214         config(const io::header& header);
215 
216         io::header to_header() const;
217     };
218 
219     named_file(const std::string& filename, const config& c);
220     virtual ~named_file();
221 
222     void close();
223 
224     std::unique_ptr<Private> p_;
225 };
226 
227 } // namespace writer
228 } // namespace lazperf
229 
230