1 /*
2 ===============================================================================
3 
4   FILE:  decompressor.hpp
5 
6   CONTENTS:
7     Integer decompressor
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 
32 #ifndef __decompressor_hpp__
33 #define __decompressor_hpp__
34 
35 #include "model.hpp"
36 
37 #include <vector>
38 #include <memory>
39 #include <cassert>
40 
41 namespace laszip {
42 	namespace decompressors {
43 		struct integer {
integerlaszip::decompressors::integer44 			integer(U32 bits = 16, U32 contexts = 1, U32 bits_high = 8, U32 range = 0):
45 				bits(bits), contexts(contexts), bits_high(bits_high), range(range) {
46 				if (range) { // the corrector's significant bits and range
47 					corr_bits = 0;
48 					corr_range = range;
49 					while (range)
50 					{
51 						range = range >> 1;
52 						corr_bits++;
53 					}
54 					if (corr_range == (1u << (corr_bits-1)))
55 					{
56 						corr_bits--;
57 					}
58 					// the corrector must fall into this interval
59 					corr_min = -((I32)(corr_range/2));
60 					corr_max = corr_min + corr_range - 1;
61 				}
62 				else if (bits && bits < 32) {
63 					corr_bits = bits;
64 					corr_range = 1u << bits;
65 					// the corrector must fall into this interval
66 					corr_min = -((I32)(corr_range/2));
67 					corr_max = corr_min + corr_range - 1;
68 				}
69 				else {
70 					corr_bits = 32;
71 					corr_range = 0;
72 					// the corrector must fall into this interval
73 					corr_min = I32_MIN;
74 					corr_max = I32_MAX;
75 				}
76 
77 				k = 0;
78 			}
79 
initlaszip::decompressors::integer80 			void init() {
81 				using laszip::models::arithmetic;
82 				using laszip::models::arithmetic_bit;
83 
84 				U32 i;
85 
86 				// maybe create the models
87 				if (mBits.empty()) {
88 					for (i = 0; i < contexts; i++)
89 						mBits.push_back(arithmetic(corr_bits+1));
90 
91 #ifndef COMPRESS_ONLY_K
92 					// mcorrector0 is already initialized
93 					for (i = 1; i <= corr_bits; i++) {
94 						U32 v = i <= bits_high ? 1 << i : 1 << bits_high;
95 						mCorrector.push_back(arithmetic(v));
96 					}
97 #endif
98 				}
99 			}
100 
101 			template<
102 				typename TDecoder
103 			>
decompresslaszip::decompressors::integer104 			I32 decompress(TDecoder& dec, I32 pred, U32 context) {
105 				I32 real = pred + readCorrector(dec, mBits[context]);
106 				if (real < 0) real += corr_range;
107 				else if ((U32)(real) >= corr_range) real -= corr_range;
108 
109 				return real;
110 			}
111 
getKlaszip::decompressors::integer112 			inline unsigned int getK() const { return k; }
113 
114 			template<
115 				typename TDecoder,
116 				typename TEntroyModel
117 			>
readCorrectorlaszip::decompressors::integer118 			I32 readCorrector(TDecoder& dec, TEntroyModel& mBits) {
119 				I32 c;
120 
121 				// decode within which interval the corrector is falling
122 
123 				k = dec.decodeSymbol(mBits);
124 
125 				// decode the exact location of the corrector within the interval
126 
127 #ifdef COMPRESS_ONLY_K
128 				if (k) // then c is either smaller than 0 or bigger than 1
129 				{
130 					if (k < 32)
131 					{
132 						c = dec.readBits(k);
133 
134 						if (c >= (1<<(k-1))) // if c is in the interval [ 2^(k-1)  ...  + 2^k - 1 ]
135 						{
136 							// so we translate c back into the interval [ 2^(k-1) + 1  ...  2^k ] by adding 1
137 							c += 1;
138 						}
139 						else // otherwise c is in the interval [ 0 ...  + 2^(k-1) - 1 ]
140 						{
141 							// so we translate c back into the interval [ - (2^k - 1)  ...  - (2^(k-1)) ] by subtracting (2^k - 1)
142 							c -= ((1<<k) - 1);
143 						}
144 					}
145 					else
146 					{
147 						c = corr_min;
148 					}
149 				}
150 				else // then c is either 0 or 1
151 				{
152 					c = dec.readBit();
153 				}
154 #else // COMPRESS_ONLY_K
155 				if (k) // then c is either smaller than 0 or bigger than 1
156 				{
157 					if (k < 32)
158 					{
159 						if (k <= bits_high) // for small k we can do this in one step
160 						{
161 							// decompress c with the range coder
162 							c = dec.decodeSymbol(mCorrector[k-1]);
163 						}
164 						else
165 						{
166 							// for larger k we need to do this in two steps
167 							int k1 = k-bits_high;
168 							// decompress higher bits with table
169 							c = dec.decodeSymbol(mCorrector[k-1]);
170 							// read lower bits raw
171 							int c1 = dec.readBits(k1);
172 							// put the corrector back together
173 							c = (c << k1) | c1;
174 						}
175 						// translate c back into its correct interval
176 						if (c >= (1<<(k-1))) // if c is in the interval [ 2^(k-1)  ...  + 2^k - 1 ]
177 						{
178 							// so we translate c back into the interval [ 2^(k-1) + 1  ...  2^k ] by adding 1
179 							c += 1;
180 						}
181 						else // otherwise c is in the interval [ 0 ...  + 2^(k-1) - 1 ]
182 						{
183 							// so we translate c back into the interval [ - (2^k - 1)  ...  - (2^(k-1)) ] by subtracting (2^k - 1)
184 							c -= ((1<<k) - 1);
185 						}
186 					}
187 					else
188 					{
189 						c = corr_min;
190 					}
191 				}
192 				else // then c is either 0 or 1
193 				{
194 					c = dec.decodeBit(mCorrector0);
195 				}
196 #endif // COMPRESS_ONLY_K
197 
198 				return c;
199 			}
200 
201 			U32 k;
202 
203 			U32 bits;
204 
205 			U32 contexts;
206 			U32 bits_high;
207 			U32 range;
208 
209 			U32 corr_bits;
210 			U32 corr_range;
211 			I32 corr_min;
212 			I32 corr_max;
213 
214 
215 			std::vector<laszip::models::arithmetic> mBits;
216 
217 			laszip::models::arithmetic_bit mCorrector0;
218 			std::vector<laszip::models::arithmetic> mCorrector;
219 		};
220 	}
221 }
222 
223 #endif // __decompressor_hpp__
224