1 /*
2 ===============================================================================
3 
4   FILE:  field_point14.hpp
5 
6   CONTENTS:
7 
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 namespace lazperf
32 {
33 namespace detail
34 {
35 
36 class Point14Base
37 {
38 protected:
39     Point14Base();
40 
41     struct ChannelCtx
42     {
43         int ctx_num_;  //ABELL - For debug.
44         std::vector<models::arithmetic> changed_values_model_;
45         models::arithmetic scanner_channel_model_;
46         models::arithmetic rn_gps_same_model_;
47         std::vector<models::arithmetic> nr_model_;
48         std::vector<models::arithmetic> rn_model_;
49         std::vector<models::arithmetic> class_model_;
50         std::vector<models::arithmetic> flag_model_;
51         std::vector<models::arithmetic> user_data_model_;
52 
53         models::arithmetic gpstime_multi_model_;
54         models::arithmetic gpstime_0diff_model_;
55 
56         compressors::integer dx_compr_;
57         compressors::integer dy_compr_;
58         compressors::integer z_compr_;
59         compressors::integer intensity_compr_;
60         compressors::integer scan_angle_compr_;
61         compressors::integer point_source_id_compr_;
62         compressors::integer gpstime_compr_;
63 
64         decompressors::integer dx_decomp_;
65         decompressors::integer dy_decomp_;
66         decompressors::integer z_decomp_;
67         decompressors::integer intensity_decomp_;
68         decompressors::integer scan_angle_decomp_;
69         decompressors::integer point_source_id_decomp_;
70         decompressors::integer gpstime_decomp_;
71 
72         bool have_last_;
73         las::point14 last_;
74         std::array<uint16_t, 8> last_intensity_;
75         std::array<int32_t, 8> last_z_;
76         std::array<utils::streaming_median<int>, 12> last_x_diff_median5_;
77         std::array<utils::streaming_median<int>, 12> last_y_diff_median5_;
78         uint32_t last_gps_seq_;
79         uint32_t next_gps_seq_;
80         std::array<double, 4> last_gpstime_;
81         std::array<int32_t, 4> last_gpstime_diff_;
82         std::array<int32_t, 4> multi_extreme_counter_;
83         bool gps_time_change_;
84 
ChannelCtxlazperf::detail::Point14Base::ChannelCtx85         ChannelCtx() : changed_values_model_(8, models::arithmetic(128)),
86             scanner_channel_model_(3), rn_gps_same_model_(13),
87             nr_model_(16, models::arithmetic(16)), rn_model_(16, models::arithmetic(16)),
88             class_model_(64, models::arithmetic(256)), flag_model_(64, models::arithmetic(64)),
89             user_data_model_(64, models::arithmetic(256)), gpstime_multi_model_(515),
90             gpstime_0diff_model_(5),
91             dx_compr_(32, 2), dy_compr_(32, 22), z_compr_(32, 20), intensity_compr_(16, 4),
92             scan_angle_compr_(16, 2), point_source_id_compr_(16), gpstime_compr_(32, 9),
93             dx_decomp_(32, 2), dy_decomp_(32, 22), z_decomp_(32, 20), intensity_decomp_(16, 4),
94             scan_angle_decomp_(16, 2), point_source_id_decomp_(16), gpstime_decomp_(32, 9),
95             have_last_{false}, last_gps_seq_{0}, next_gps_seq_{0},
96             last_gpstime_{}, last_gpstime_diff_{}, multi_extreme_counter_{},
97             gps_time_change_{}
98         {
99             //ABELL - Move the init into the ctor, I think.
100             // Also, the encoder should be passed to the ctor.
101             dx_compr_.init();
102             dy_compr_.init();
103             z_compr_.init();
104             intensity_compr_.init();
105             scan_angle_compr_.init();
106             point_source_id_compr_.init();
107             gpstime_compr_.init();
108 
109             dx_decomp_.init();
110             dy_decomp_.init();
111             z_decomp_.init();
112             intensity_decomp_.init();
113             scan_angle_decomp_.init();
114             point_source_id_decomp_.init();
115             gpstime_decomp_.init();
116 
117             for (auto& xd : last_x_diff_median5_)
118                 xd.init();
119             for (auto& yd : last_y_diff_median5_)
120                 yd.init();
121         }
122     };  // ChannelCtx
123 
124     std::array<ChannelCtx, 4> chan_ctxs_;
125     int last_channel_;
126 };
127 
128 class Point14Compressor : public Point14Base
129 {
130 public:
Point14Compressor(OutCbStream & stream)131     Point14Compressor(OutCbStream& stream) : stream_(stream)
132     {}
133 
134     void writeSizes();
135     void writeData();
136     const char *compress(const char *buf, int& sc);
137 
138 private:
139     void encodeGpsTime(const las::point14& point, ChannelCtx& c);
140 
141     OutCbStream& stream_;
142     encoders::arithmetic<MemoryStream> xy_enc_ = true;
143     encoders::arithmetic<MemoryStream> z_enc_ = true;
144     encoders::arithmetic<MemoryStream> class_enc_ = false;
145     encoders::arithmetic<MemoryStream> flags_enc_ = false;
146     encoders::arithmetic<MemoryStream> intensity_enc_ = false;
147     encoders::arithmetic<MemoryStream> scan_angle_enc_ = false;
148     encoders::arithmetic<MemoryStream> user_data_enc_ = false;
149     encoders::arithmetic<MemoryStream> point_source_id_enc_ = false;
150     encoders::arithmetic<MemoryStream> gpstime_enc_ = false;
151 };
152 
153 class Point14Decompressor : public Point14Base
154 {
155 public:
Point14Decompressor(InCbStream & stream)156     Point14Decompressor(InCbStream& stream) : stream_(stream)
157     {}
158 
159     void dumpSums();
160     void readSizes();
161     void readData();
162     char *decompress(char *buf, int& sc);
163 
164 private:
165     void decodeGpsTime(ChannelCtx& c);
166 
167     InCbStream stream_;
168     decoders::arithmetic<MemoryStream> xy_dec_;
169     decoders::arithmetic<MemoryStream> z_dec_;
170     decoders::arithmetic<MemoryStream> class_dec_;
171     decoders::arithmetic<MemoryStream> flags_dec_;
172     decoders::arithmetic<MemoryStream> intensity_dec_;
173     decoders::arithmetic<MemoryStream> scan_angle_dec_;
174     decoders::arithmetic<MemoryStream> user_data_dec_;
175     decoders::arithmetic<MemoryStream> point_source_id_dec_;
176     decoders::arithmetic<MemoryStream> gpstime_dec_;
177     std::vector<uint32_t> sizes_;
178     utils::Summer sumChange;
179     utils::Summer sumReturn;
180     utils::Summer sumX;
181     utils::Summer sumY;
182     utils::Summer sumZ;
183     utils::Summer sumClass;
184     utils::Summer sumFlags;
185     utils::Summer sumIntensity;
186     utils::Summer sumScanAngle;
187     utils::Summer sumUserData;
188     utils::Summer sumPointSourceId;
189     utils::Summer sumGpsTime;
190 };
191 
192 } // namespace detail
193 } // namespace lazperf
194