1 /*
2 ===============================================================================
3
4 FILE: field_byte14.cpp
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 #include "../las.hpp"
32
33 namespace lazperf
34 {
35 namespace detail
36 {
37
Byte14Base(size_t count)38 Byte14Base::Byte14Base(size_t count) : count_(count), last_channel_(-1),
39 chan_ctxs_ { count_, count_, count_, count_ }
40 {}
41
count() const42 size_t Byte14Base::count() const
43 {
44 return count_;
45 }
46
47 // COMPRESSOR
48
Byte14Compressor(OutCbStream & stream,size_t count)49 Byte14Compressor::Byte14Compressor(OutCbStream& stream, size_t count) :
50 Byte14Base(count), stream_(stream), valid_(count_),
51 byte_enc_(count, encoders::arithmetic<MemoryStream>(true))
52 {}
53
writeSizes()54 void Byte14Compressor::writeSizes()
55 {
56 for (size_t i = 0; i < count_; ++i)
57 {
58 if (valid_[i])
59 {
60 byte_enc_[i].done();
61 stream_ << byte_enc_[i].num_encoded();
62 }
63 else
64 stream_ << (uint32_t)0;
65 }
66 }
67
writeData()68 void Byte14Compressor::writeData()
69 {
70 int32_t total = 0;
71 for (size_t i = 0; i < count_; ++i)
72 {
73 if (valid_[i])
74 {
75 stream_.putBytes(byte_enc_[i].encoded_bytes(), byte_enc_[i].num_encoded());
76 total += utils::sum(byte_enc_[i].encoded_bytes(), byte_enc_[i].num_encoded());
77 }
78 }
79 LAZDEBUG(std::cerr << "BYTE : " << total << "\n");
80 }
81
compress(const char * buf,int & sc)82 const char *Byte14Compressor::compress(const char *buf, int& sc)
83 {
84 // don't have the first data yet, just push it to our
85 // have last stuff and move on
86 if (last_channel_ == -1)
87 {
88 ChannelCtx& c = chan_ctxs_[sc];
89 stream_.putBytes((const unsigned char *)buf, count_);
90 c.last_.assign(buf, buf + count_);
91 c.have_last_ = true;
92 last_channel_ = sc;
93 return buf + count_;
94 }
95 ChannelCtx& c = chan_ctxs_[sc];
96 las::byte14 *pLastBytes = &chan_ctxs_[last_channel_].last_;
97 if (!c.have_last_)
98 {
99 c.have_last_ = true;
100 c.last_ = *pLastBytes;
101 pLastBytes = &c.last_;
102 }
103 // This mess is because of the broken-ness of the handling for last in v3, where
104 // 'last_point' only gets updated on the first context switch in the LASzip code.
105 las::byte14& lastBytes = *pLastBytes;
106
107 for (size_t i = 0; i < count_; ++i, ++buf)
108 {
109 int32_t diff = *(const uint8_t *)buf - lastBytes[i];
110 byte_enc_[i].encodeSymbol(c.byte_model_[i], (uint8_t)diff);
111 if (diff)
112 {
113 valid_[i] = true;
114 lastBytes[i] = *buf;
115 }
116 }
117
118 last_channel_ = sc;
119 return buf + count_;
120 }
121
122 // DECOMPRESSOR
123
Byte14Decompressor(InCbStream & stream,size_t count)124 Byte14Decompressor::Byte14Decompressor(InCbStream& stream, size_t count) : Byte14Base(count),
125 stream_(stream), byte_cnt_(count_), byte_dec_(count_, decoders::arithmetic<MemoryStream>())
126 {}
127
readSizes()128 void Byte14Decompressor::readSizes()
129 {
130 for (size_t i = 0; i < count_; ++i)
131 stream_ >> byte_cnt_[i];
132 }
133
readData()134 void Byte14Decompressor::readData()
135 {
136 for (size_t i = 0; i < count_; ++i)
137 byte_dec_[i].initStream(stream_, byte_cnt_[i]);
138 }
139
dumpSums()140 void Byte14Decompressor::dumpSums()
141 {
142 std::cout << "BYTE : " << sumByte.value() << "\n";
143 }
144
decompress(char * buf,int & sc)145 char *Byte14Decompressor::decompress(char *buf, int& sc)
146 {
147 if (last_channel_ == -1)
148 {
149 ChannelCtx& c = chan_ctxs_[sc];
150 stream_.getBytes((unsigned char *)buf, count_);
151 c.last_.assign(buf, buf + count_);
152 c.have_last_ = true;
153 last_channel_ = sc;
154 return buf + count_;
155 }
156
157 ChannelCtx& c = chan_ctxs_[sc];
158 las::byte14 *pLastByte = &chan_ctxs_[last_channel_].last_;
159 if (sc != last_channel_)
160 {
161 last_channel_ = sc;
162 if (!c.have_last_)
163 {
164 c.have_last_ = true;
165 c.last_ = *pLastByte;
166 pLastByte = &chan_ctxs_[last_channel_].last_;
167 }
168 }
169 las::byte14& lastByte = *pLastByte;
170
171 for (size_t i = 0; i < count_; ++i, buf++)
172 {
173 if (byte_cnt_[i])
174 {
175 *buf = lastByte[i] + byte_dec_[i].decodeSymbol(c.byte_model_[i]);
176 lastByte[i] = *buf;
177 }
178 else
179 *buf = lastByte[i];
180 }
181 LAZDEBUG(sumByte.add(lastByte.data(), count_));
182
183 return buf;
184 }
185
186 } // namespace detail
187 } // namespace lazperf
188