1 /******************************************************************************
2 * Copyright (c) 2014, Howard Butler, hobu.inc@gmail.com
3 *
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following
8 * conditions are met:
9 *
10 *     * Redistributions of source code must retain the above copyright
11 *       notice, this list of conditions and the following disclaimer.
12 *     * Redistributions in binary form must reproduce the above copyright
13 *       notice, this list of conditions and the following disclaimer in
14 *       the documentation and/or other materials provided
15 *       with the distribution.
16 *     * Neither the name of Hobu, Inc. or Flaxen Geo Consulting nor the
17 *       names of its contributors may be used to endorse or promote
18 *       products derived from this software without specific prior
19 *       written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
28 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
32 * OF SUCH DAMAGE.
33 ****************************************************************************/
34 
35 #pragma once
36 
37 #include <stdint.h>
38 #include <string>
39 #include <vector>
40 
41 #include <pdal/Dimension.hpp>
42 #include <pdal/Log.hpp>
43 #include <pdal/SpatialReference.hpp>
44 
45 namespace pdal
46 {
47 
48 class ILeStream;
49 class OLeStream;
50 
51 struct BpfMuellerMatrix
52 {
BpfMuellerMatrixpdal::BpfMuellerMatrix53     BpfMuellerMatrix()
54     {
55         static const double vals[] = {1.0, 0.0, 0.0, 0.0,
56                          0.0, 1.0, 0.0, 0.0,
57                          0.0, 0.0, 1.0, 0.0,
58                          0.0, 0.0, 0.0, 1.0};
59         memcpy(m_vals, vals, sizeof(vals));
60     }
61 
62     double m_vals[16];
63 
dumppdal::BpfMuellerMatrix64     void dump()
65     {
66         for (size_t i = 0; i < 4; ++i)
67             std::cerr << m_vals[i] << '\t';
68         std::cerr << "\n";
69         for (size_t i = 4; i < 8; ++i)
70             std::cerr << m_vals[i] << '\t';
71         std::cerr << "\n";
72         for (size_t i = 8; i < 12; ++i)
73             std::cerr << m_vals[i] << '\t';
74         std::cerr << "\n";
75         for (size_t i = 12; i < 16; ++i)
76             std::cerr << m_vals[i] << '\t';
77         std::cerr << "\n\n";
78 
79     }
80 
applypdal::BpfMuellerMatrix81     void apply(double& x, double& y, double& z)
82     {
83         double w = x * m_vals[12] + y * m_vals[13] + z * m_vals[14] +
84             m_vals[15];
85 
86         x = (x * m_vals[0] + y * m_vals[1] + z * m_vals[2] + m_vals[3]) / w;
87         y = (x * m_vals[4] + y * m_vals[5] + z * m_vals[6] + m_vals[7]) / w;
88         z = (x * m_vals[8] + y * m_vals[9] + z * m_vals[10] + m_vals[11]) / w;
89     }
90 };
91 ILeStream& operator >> (ILeStream& stream, BpfMuellerMatrix& m);
92 OLeStream& operator << (OLeStream& stream, BpfMuellerMatrix& m);
93 
94 enum class BpfFormat
95 {
96     DimMajor,
97     PointMajor,
98     ByteMajor
99 };
100 
101 std::istream& operator >> (std::istream& in, BpfFormat& format);
102 std::ostream& operator << (std::ostream& in, const BpfFormat& format);
103 
104 enum class BpfCoordType
105 {
106     Cartesian,
107     UTM,
108     TCR,
109     ENU
110 };
111 
112 enum class BpfCompression
113 {
114     None,
115     QuickLZ,
116     FastLZ,
117     Zlib
118 };
119 
120 struct BpfDimension
121 {
BpfDimensionpdal::BpfDimension122     BpfDimension() : m_offset(0.0),
123         m_min((std::numeric_limits<double>::max)()),
124         m_max(std::numeric_limits<double>::lowest()),
125         m_id(Dimension::Id::Unknown)
126     {}
127 
128     double m_offset;
129     double m_min;
130     double m_max;
131     std::string m_label;
132     Dimension::Id m_id;
133 
134     static bool read(ILeStream& stream, std::vector<BpfDimension>& dims,
135         size_t start);
136     static bool write(OLeStream& stream, std::vector<BpfDimension>& dims);
137 };
138 typedef std::vector<BpfDimension> BpfDimensionList;
139 
140 struct BpfHeader
141 {
142     struct error : std::runtime_error
143     {
errorpdal::BpfHeader::error144         error(const std::string& err) : std::runtime_error(err)
145         {}
146     };
147 
BpfHeaderpdal::BpfHeader148     BpfHeader() : m_version(0), m_len(176), m_numDim(0),
149         m_compression(Utils::toNative(BpfCompression::None)), m_numPts(0),
150         m_coordType(Utils::toNative(BpfCoordType::Cartesian)), m_coordId(0),
151         m_spacing(0.0), m_startTime(0.0), m_endTime(0.0)
152     {}
153 
154     int32_t m_version;
155     std::string m_ver;
156     int32_t m_len;
157     int32_t m_numDim;
158     BpfFormat m_pointFormat;
159     uint8_t m_compression;
160     int32_t m_numPts;
161     int32_t m_coordType;
162     int32_t m_coordId;
163     float m_spacing;
164     BpfMuellerMatrix m_xform;
165     double m_startTime;
166     double m_endTime;
167     std::vector<BpfDimension> m_staticDims;
168     LogPtr m_log;
169 
setLogpdal::BpfHeader170     PDAL_DLL void setLog(const LogPtr& log)
171          { m_log = log; }
172     PDAL_DLL bool read(ILeStream& stream);
173     bool write(OLeStream& stream);
174     bool readV3(ILeStream& stream);
175     bool readV1(ILeStream& stream);
176     bool trySetSpatialReference(const pdal::SpatialReference&);
177     PDAL_DLL bool readDimensions(ILeStream& stream,
178         std::vector<BpfDimension>& dims, bool fixNames);
179     void writeDimensions(OLeStream& stream, std::vector<BpfDimension>& dims);
180     void dump();
181 };
182 
183 struct BpfUlemHeader
184 {
185     uint32_t m_numFrames;
186     uint16_t m_year;
187     uint8_t m_month;
188     uint8_t m_day;
189     uint16_t m_lidarMode;
190     uint16_t m_wavelen;  // In nm.
191     uint16_t m_pulseFreq;  // In Hz.
192     uint16_t m_focalWidth;
193     uint16_t m_focalHeight;
194     float m_pixelPitchWidth;
195     float m_pixelPitchHeight;
196     std::string m_classCode;
197 
198     bool read(ILeStream& stream);
199 };
200 
201 struct BpfUlemFrame
202 {
203     int32_t m_num;
204     double m_roll; //x
205     double m_pitch; //y
206     double m_heading; //z
207     BpfMuellerMatrix m_xform;
208     int16_t m_shortEncoder;
209     int16_t m_longEncoder;
210 
211     bool read(ILeStream& stream);
212 };
213 
214 struct BpfUlemFile
215 {
216     uint32_t m_len;
217     std::string m_filename;
218     std::vector<char> m_buf;
219     std::string m_filespec;
220 
BpfUlemFilepdal::BpfUlemFile221     BpfUlemFile() : m_len(0)
222     {}
223 
BpfUlemFilepdal::BpfUlemFile224     BpfUlemFile(uint32_t len, const std::string& filename,
225             const std::string& filespec) :
226         m_len(len), m_filename(filename), m_filespec(filespec)
227     {}
228 
229     bool read(ILeStream& stream);
230     bool write(OLeStream& stream);
231 };
232 
233 struct BpfPolarStokesParam
234 {
235     float m_x;
236     float m_y;
237     float m_z;
238     float m_a;
239 
240     bool read(ILeStream& stream);
241 };
242 
243 struct BpfPolarHeader
244 {
245     uint32_t m_numFrames;
246     uint16_t m_fpaId;
247     uint32_t m_numXmit;
248     uint32_t m_numRcv;
249     std::vector<BpfPolarStokesParam> m_xmitStates;
250     std::vector<BpfMuellerMatrix> m_psaSettings;
251 
252     bool read(ILeStream& stream);
253 };
254 
255 struct BpfPolarFrame
256 {
257 public:
258     uint32_t m_num;
259     int16_t m_stokesIdx;
260     float m_stokesParam[4];
261     float m_stokesOutParam[4];
262     BpfMuellerMatrix m_xform;
263     int16_t m_truncation;
264 
265     bool read(ILeStream& stream);
266 };
267 
268 } //namespace pdal
269