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