/src/gdal/third_party/LercLib/Lerc2.h
Line | Count | Source |
1 | | /* |
2 | | Copyright 2015 Esri |
3 | | |
4 | | Licensed under the Apache License, Version 2.0 (the "License"); |
5 | | you may not use this file except in compliance with the License. |
6 | | You may obtain a copy of the License at |
7 | | |
8 | | http://www.apache.org/licenses/LICENSE-2.0 |
9 | | |
10 | | Unless required by applicable law or agreed to in writing, software |
11 | | distributed under the License is distributed on an "AS IS" BASIS, |
12 | | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 | | See the License for the specific language governing permissions and |
14 | | limitations under the License. |
15 | | |
16 | | A local copy of the license and additional notices are located with the |
17 | | source distribution at: |
18 | | |
19 | | http://github.com/Esri/lerc/ |
20 | | |
21 | | Contributors: Thomas Maurer |
22 | | */ |
23 | | |
24 | | #ifndef LERC2_H |
25 | | #define LERC2_H |
26 | | |
27 | | #include <algorithm> |
28 | | #include <cfloat> |
29 | | #include <cmath> |
30 | | #include <limits> |
31 | | #include <string> |
32 | | #include <typeinfo> |
33 | | #include "Defines.h" |
34 | | #include "BitMask.h" |
35 | | #include "BitStuffer2.h" |
36 | | #include "Huffman.h" |
37 | | #include "RLE.h" |
38 | | |
39 | | NAMESPACE_LERC_START |
40 | | |
41 | | /** Lerc2 v1 |
42 | | * |
43 | | * -- allow for lossless compression of all common data types |
44 | | * -- avoid data type conversions and copies |
45 | | * -- optimized compression for segmented rasters (10-15x lossless) |
46 | | * -- micro block is 8x8 fixed, only gets doubled to 16x16 if bit rate < 1 bpp |
47 | | * -- cnt is replaced by bit mask |
48 | | * -- Lerc blob header has data range [min, max] |
49 | | * -- harden consistency checks to detect if the byte blob has been tampered with |
50 | | * -- drop support for big endian, this is legacy now |
51 | | * |
52 | | * Lerc2 v2 |
53 | | * |
54 | | * -- add Huffman coding for better lossless compression of 8 bit data types Char, Byte |
55 | | * |
56 | | * Lerc2 v3 |
57 | | * |
58 | | * -- add checksum for the entire byte blob, for more rigorous detection of compressed data corruption |
59 | | * -- for the main bit stuffing routine, use an extra uint buffer for guaranteed memory alignment |
60 | | * -- this also allows dropping the NumExtraBytesToAllocate functions |
61 | | * |
62 | | * Lerc2 v4 |
63 | | * |
64 | | * -- allow array per pixel, nDim values per pixel. Such as RGB, complex number, or larger arrays per pixel |
65 | | * -- extend Huffman coding for 8 bit data types from delta only to trying both delta and orig |
66 | | * -- for integer data types, allow to drop bit planes containing only random noise |
67 | | * |
68 | | */ |
69 | | |
70 | | class Lerc2 |
71 | | { |
72 | | public: |
73 | | Lerc2(); |
74 | | Lerc2(int nDim, int nCols, int nRows, const Byte* pMaskBits = nullptr); // valid / invalid bits as byte array |
75 | 39.4k | ~Lerc2() {} |
76 | | |
77 | | bool SetEncoderToOldVersion(int version); // call this to encode compatible to an old decoder |
78 | | |
79 | | bool Set(int nDim, int nCols, int nRows, const Byte* pMaskBits = nullptr); |
80 | | |
81 | | template<class T> |
82 | | unsigned int ComputeNumBytesNeededToWrite(const T* arr, double maxZError, bool encodeMask); |
83 | | |
84 | | //static unsigned int MinNumBytesNeededToReadHeader(); |
85 | | |
86 | | /// dst buffer already allocated; byte ptr is moved like a file pointer |
87 | | template<class T> |
88 | | bool Encode(const T* arr, Byte** ppByte); |
89 | | |
90 | | // data types supported by Lerc2 |
91 | | enum DataType {DT_Char = 0, DT_Byte, DT_Short, DT_UShort, DT_Int, DT_UInt, DT_Float, DT_Double, DT_Undefined}; |
92 | | |
93 | | struct HeaderInfo |
94 | | { |
95 | | int version; |
96 | | unsigned int checksum; |
97 | | int nRows, |
98 | | nCols, |
99 | | nDim, |
100 | | numValidPixel, |
101 | | microBlockSize, |
102 | | blobSize; |
103 | | |
104 | | DataType dt; |
105 | | |
106 | | double maxZError, |
107 | | zMin, // if nDim > 1, this is the overall range |
108 | | zMax; |
109 | | |
110 | 208k | void RawInit() { memset(this, 0, sizeof(struct HeaderInfo)); } |
111 | | |
112 | 23.3k | bool TryHuffman() const { return version > 1 && (dt == DT_Byte || dt == DT_Char) && maxZError == 0.5; } |
113 | | }; |
114 | | |
115 | | static bool GetHeaderInfo(const Byte* pByte, size_t nBytesRemaining, struct HeaderInfo& headerInfo); |
116 | | |
117 | | /// dst buffer already allocated; byte ptr is moved like a file pointer |
118 | | template<class T> |
119 | | bool Decode(const Byte** ppByte, size_t& nBytesRemaining, T* arr, Byte* pMaskBits = nullptr); // if mask ptr is not 0, mask bits are returned (even if all valid or same as previous) |
120 | | |
121 | | private: |
122 | | static const int kCurrVersion = 4; // 2: added Huffman coding to 8 bit types DT_Char, DT_Byte; |
123 | | // 3: changed the bit stuffing to using a uint aligned buffer, |
124 | | // added Fletcher32 checksum |
125 | | // 4: allow nDim values per pixel |
126 | | |
127 | | enum ImageEncodeMode { IEM_Tiling = 0, IEM_DeltaHuffman, IEM_Huffman }; |
128 | | enum BlockEncodeMode { BEM_RawBinary = 0, BEM_BitStuffSimple, BEM_BitStuffLUT }; |
129 | | |
130 | | int m_microBlockSize, |
131 | | m_maxValToQuantize; |
132 | | BitMask m_bitMask; |
133 | | HeaderInfo m_headerInfo; |
134 | | BitStuffer2 m_bitStuffer2; |
135 | | bool m_encodeMask, |
136 | | m_writeDataOneSweep; |
137 | | ImageEncodeMode m_imageEncodeMode; |
138 | | |
139 | | std::vector<double> m_zMinVec, m_zMaxVec; |
140 | | std::vector<std::pair<unsigned short, unsigned int> > m_huffmanCodes; // <= 256 codes, 1.5 kB |
141 | | |
142 | | private: |
143 | 202k | static std::string FileKey() { return "Lerc2 "; } |
144 | 169k | static bool IsLittleEndianSystem() { int n = 1; return (1 == *((Byte*)&n)) && (4 == sizeof(int)); } |
145 | | void Init(); |
146 | | |
147 | | static unsigned int ComputeNumBytesHeaderToWrite(const struct HeaderInfo& hd); |
148 | | static bool WriteHeader(Byte** ppByte, const struct HeaderInfo& hd); |
149 | | static bool ReadHeader(const Byte** ppByte, size_t& nBytesRemaining, struct HeaderInfo& hd); |
150 | | |
151 | | bool WriteMask(Byte** ppByte) const; |
152 | | bool ReadMask(const Byte** ppByte, size_t& nBytesRemaining); |
153 | | |
154 | | bool DoChecksOnEncode(Byte* pBlobBegin, Byte* pBlobEnd) const; |
155 | | static unsigned int ComputeChecksumFletcher32(const Byte* pByte, int len); |
156 | | |
157 | | static void AddUIntToCounts(int* pCounts, unsigned int val, int nBits); |
158 | | static void AddIntToCounts(int* pCounts, int val, int nBits); |
159 | | |
160 | | template<class T> |
161 | | bool TryBitPlaneCompression(const T* data, double eps, double& newMaxZError) const; |
162 | | |
163 | | template<class T> |
164 | | bool WriteDataOneSweep(const T* data, Byte** ppByte) const; |
165 | | |
166 | | template<class T> |
167 | | bool ReadDataOneSweep(const Byte** ppByte, size_t& nBytesRemaining, T* data) const; |
168 | | |
169 | | template<class T> |
170 | | bool WriteTiles(const T* data, Byte** ppByte, int& numBytes, std::vector<double>& zMinVec, std::vector<double>& zMaxVec) const; |
171 | | |
172 | | template<class T> |
173 | | bool ReadTiles(const Byte** ppByte, size_t& nBytesRemaining, T* data) const; |
174 | | |
175 | | template<class T> |
176 | | bool GetValidDataAndStats(const T* data, int i0, int i1, int j0, int j1, int iDim, |
177 | | T* dataBuf, T& zMinA, T& zMaxA, int& numValidPixel, bool& tryLutA) const; |
178 | | |
179 | | static double ComputeMaxVal(double zMin, double zMax, double maxZError); |
180 | | |
181 | | template<class T> |
182 | | bool NeedToQuantize(int numValidPixel, T zMin, T zMax) const; |
183 | | |
184 | | template<class T> |
185 | | bool Quantize(const T* dataBuf, int num, T zMin, std::vector<unsigned int>& quantVec) const; |
186 | | |
187 | | template<class T> |
188 | | int NumBytesTile(int numValidPixel, T zMin, T zMax, bool tryLut, BlockEncodeMode& blockEncodeMode, |
189 | | const std::vector<std::pair<unsigned int, unsigned int> >& sortedQuantVec) const; |
190 | | |
191 | | template<class T> |
192 | | bool WriteTile(const T* dataBuf, int num, Byte** ppByte, int& numBytesWritten, int j0, T zMin, T zMax, |
193 | | const std::vector<unsigned int>& quantVec, BlockEncodeMode blockEncodeMode, |
194 | | const std::vector<std::pair<unsigned int, unsigned int> >& sortedQuantVec) const; |
195 | | |
196 | | template<class T> |
197 | | bool ReadTile(const Byte** ppByte, size_t& nBytesRemaining, T* data, int i0, int i1, int j0, int j1, int iDim, |
198 | | std::vector<unsigned int>& bufferVec) const; |
199 | | |
200 | | template<class T> |
201 | | int TypeCode(T z, DataType& dtUsed) const; |
202 | | |
203 | | DataType GetDataTypeUsed(int typeCode) const; |
204 | | |
205 | | static DataType ValidateDataType(int dt); |
206 | | |
207 | | static bool WriteVariableDataType(Byte** ppByte, double z, DataType dtUsed); |
208 | | |
209 | | static double ReadVariableDataType(const Byte** ppByte, DataType dtUsed); |
210 | | |
211 | | template<class T> DataType GetDataType(T z) const; |
212 | | |
213 | | static unsigned int GetMaxValToQuantize(DataType dt); |
214 | | |
215 | | static unsigned int GetDataTypeSize(DataType dt); |
216 | | |
217 | | static void SortQuantArray(const std::vector<unsigned int>& quantVec, |
218 | | std::vector<std::pair<unsigned int, unsigned int> >& sortedQuantVec); |
219 | | |
220 | | template<class T> |
221 | | void ComputeHuffmanCodes(const T* data, int& numBytes, ImageEncodeMode& imageEncodeMode, |
222 | | std::vector<std::pair<unsigned short, unsigned int> >& codes) const; |
223 | | |
224 | | template<class T> |
225 | | void ComputeHistoForHuffman(const T* data, std::vector<int>& histo, std::vector<int>& deltaHisto) const; |
226 | | |
227 | | template<class T> |
228 | | bool EncodeHuffman(const T* data, Byte** ppByte) const; |
229 | | |
230 | | template<class T> |
231 | | bool DecodeHuffman(const Byte** ppByte, size_t& nBytesRemaining, T* data) const; |
232 | | |
233 | | template<class T> |
234 | | bool WriteMinMaxRanges(const T* data, Byte** ppByte) const; |
235 | | |
236 | | template<class T> |
237 | | bool ReadMinMaxRanges(const Byte** ppByte, size_t& nBytesRemaining, const T* data); |
238 | | |
239 | | bool CheckMinMaxRanges(bool& minMaxEqual) const; |
240 | | |
241 | | template<class T> |
242 | | bool FillConstImage(T* data) const; |
243 | | }; |
244 | | |
245 | | // -------------------------------------------------------------------------- ; |
246 | | // -------------------------------------------------------------------------- ; |
247 | | |
248 | | template<class T> |
249 | | unsigned int Lerc2::ComputeNumBytesNeededToWrite(const T* arr, double maxZError, bool encodeMask) |
250 | 0 | { |
251 | 0 | if (!arr || !IsLittleEndianSystem()) |
252 | 0 | return 0; |
253 | | |
254 | | // header |
255 | 0 | unsigned int nBytesHeaderMask = ComputeNumBytesHeaderToWrite(m_headerInfo); |
256 | | |
257 | | // valid / invalid mask |
258 | 0 | int numValid = m_headerInfo.numValidPixel; |
259 | 0 | int numTotal = m_headerInfo.nCols * m_headerInfo.nRows; |
260 | |
|
261 | 0 | bool needMask = numValid > 0 && numValid < numTotal; |
262 | |
|
263 | 0 | m_encodeMask = encodeMask; |
264 | |
|
265 | 0 | nBytesHeaderMask += 1 * sizeof(int); // the mask encode numBytes |
266 | |
|
267 | 0 | if (needMask && encodeMask) |
268 | 0 | { |
269 | 0 | RLE rle; |
270 | 0 | size_t n = rle.computeNumBytesRLE((const Byte*)m_bitMask.Bits(), m_bitMask.Size()); |
271 | 0 | nBytesHeaderMask += (unsigned int)n; |
272 | 0 | } |
273 | |
|
274 | 0 | m_headerInfo.dt = GetDataType(arr[0]); |
275 | |
|
276 | 0 | if (m_headerInfo.dt == DT_Undefined) |
277 | 0 | return 0; |
278 | | |
279 | 0 | if (maxZError == 777) // cheat code |
280 | 0 | maxZError = -0.01; |
281 | |
|
282 | 0 | if (m_headerInfo.dt < DT_Float) // integer types |
283 | 0 | { |
284 | | // interpret a negative maxZError as bit plane epsilon; dflt = 0.01; |
285 | 0 | if (maxZError < 0 && (!TryBitPlaneCompression(arr, -maxZError, maxZError))) |
286 | 0 | maxZError = 0; |
287 | |
|
288 | 0 | maxZError = std::max(0.5, floor(maxZError)); |
289 | 0 | } |
290 | 0 | else if (maxZError < 0) // don't allow bit plane compression for float or double yet |
291 | 0 | return 0; |
292 | | |
293 | 0 | m_headerInfo.maxZError = maxZError; |
294 | 0 | m_headerInfo.zMin = 0; |
295 | 0 | m_headerInfo.zMax = 0; |
296 | 0 | m_headerInfo.microBlockSize = m_microBlockSize; |
297 | 0 | m_headerInfo.blobSize = nBytesHeaderMask; |
298 | |
|
299 | 0 | if (numValid == 0) |
300 | 0 | return nBytesHeaderMask; |
301 | | |
302 | 0 | m_maxValToQuantize = GetMaxValToQuantize(m_headerInfo.dt); |
303 | |
|
304 | 0 | Byte* ptr = nullptr; // only emulate the writing and just count the bytes needed |
305 | 0 | int nBytesTiling = 0; |
306 | |
|
307 | 0 | if (!WriteTiles(arr, &ptr, nBytesTiling, m_zMinVec, m_zMaxVec)) // also fills the min max ranges |
308 | 0 | return 0; |
309 | | |
310 | 0 | m_headerInfo.zMin = *std::min_element(m_zMinVec.begin(), m_zMinVec.end()); |
311 | 0 | m_headerInfo.zMax = *std::max_element(m_zMaxVec.begin(), m_zMaxVec.end()); |
312 | |
|
313 | 0 | if (m_headerInfo.zMin == m_headerInfo.zMax) // image is const |
314 | 0 | return nBytesHeaderMask; |
315 | | |
316 | 0 | int nDim = m_headerInfo.nDim; |
317 | |
|
318 | 0 | if (m_headerInfo.version >= 4) |
319 | 0 | { |
320 | | // add the min max ranges behind the mask and before the main data; |
321 | | // so we do not write it if no valid pixel or all same value const |
322 | 0 | m_headerInfo.blobSize += 2 * nDim * sizeof(T); |
323 | |
|
324 | 0 | bool minMaxEqual = false; |
325 | 0 | if (!CheckMinMaxRanges(minMaxEqual)) |
326 | 0 | return 0; |
327 | | |
328 | 0 | if (minMaxEqual) |
329 | 0 | return m_headerInfo.blobSize; // all nDim bands are const |
330 | 0 | } |
331 | | |
332 | | // data |
333 | 0 | m_imageEncodeMode = IEM_Tiling; |
334 | 0 | int nBytesData = nBytesTiling; |
335 | 0 | int nBytesHuffman = 0; |
336 | |
|
337 | 0 | if (m_headerInfo.TryHuffman()) |
338 | 0 | { |
339 | 0 | ImageEncodeMode huffmanEncMode; |
340 | 0 | ComputeHuffmanCodes(arr, nBytesHuffman, huffmanEncMode, m_huffmanCodes); // save Huffman codes for later use |
341 | |
|
342 | 0 | if (!m_huffmanCodes.empty() && nBytesHuffman < nBytesTiling) |
343 | 0 | { |
344 | 0 | m_imageEncodeMode = huffmanEncMode; |
345 | 0 | nBytesData = nBytesHuffman; |
346 | 0 | } |
347 | 0 | else |
348 | 0 | m_huffmanCodes.resize(0); |
349 | 0 | } |
350 | |
|
351 | 0 | m_writeDataOneSweep = false; |
352 | 0 | int nBytesDataOneSweep = (int)(numValid * nDim * sizeof(T)); |
353 | |
|
354 | 0 | { |
355 | | // try with double block size to reduce block header overhead, if |
356 | 0 | if ( (nBytesTiling * 8 < numTotal * nDim * 2) // resulting bit rate < x (2 bpp) |
357 | 0 | && (nBytesTiling < 4 * nBytesDataOneSweep) // bit stuffing is effective |
358 | 0 | && (nBytesHuffman == 0 || nBytesTiling < 2 * nBytesHuffman) ) // not much worse than huffman (otherwise huffman wins anyway) |
359 | 0 | { |
360 | 0 | m_headerInfo.microBlockSize = m_microBlockSize * 2; |
361 | |
|
362 | 0 | std::vector<double> zMinVec, zMaxVec; |
363 | 0 | int nBytes2 = 0; |
364 | 0 | if (!WriteTiles(arr, &ptr, nBytes2, zMinVec, zMaxVec)) // no huffman in here anymore |
365 | 0 | return 0; |
366 | | |
367 | 0 | if (nBytes2 <= nBytesData) |
368 | 0 | { |
369 | 0 | nBytesData = nBytes2; |
370 | 0 | m_imageEncodeMode = IEM_Tiling; |
371 | 0 | m_huffmanCodes.resize(0); |
372 | 0 | } |
373 | 0 | else |
374 | 0 | { |
375 | 0 | m_headerInfo.microBlockSize = m_microBlockSize; // reset to orig |
376 | 0 | } |
377 | 0 | } |
378 | 0 | } |
379 | | |
380 | 0 | if (m_headerInfo.TryHuffman()) |
381 | 0 | nBytesData += 1; // flag for image encode mode |
382 | |
|
383 | 0 | if (nBytesDataOneSweep <= nBytesData) |
384 | 0 | { |
385 | 0 | m_writeDataOneSweep = true; // fallback: write data binary uncompressed in one sweep |
386 | 0 | m_headerInfo.blobSize += 1 + nBytesDataOneSweep; // header, mask, min max ranges, flag, data one sweep |
387 | 0 | } |
388 | 0 | else |
389 | 0 | { |
390 | 0 | m_writeDataOneSweep = false; |
391 | 0 | m_headerInfo.blobSize += 1 + nBytesData; // header, mask, min max ranges, flag(s), data |
392 | 0 | } |
393 | |
|
394 | 0 | return m_headerInfo.blobSize; |
395 | 0 | } Unexecuted instantiation: unsigned int GDAL_LercNS::Lerc2::ComputeNumBytesNeededToWrite<signed char>(signed char const*, double, bool) Unexecuted instantiation: unsigned int GDAL_LercNS::Lerc2::ComputeNumBytesNeededToWrite<unsigned char>(unsigned char const*, double, bool) Unexecuted instantiation: unsigned int GDAL_LercNS::Lerc2::ComputeNumBytesNeededToWrite<short>(short const*, double, bool) Unexecuted instantiation: unsigned int GDAL_LercNS::Lerc2::ComputeNumBytesNeededToWrite<unsigned short>(unsigned short const*, double, bool) Unexecuted instantiation: unsigned int GDAL_LercNS::Lerc2::ComputeNumBytesNeededToWrite<int>(int const*, double, bool) Unexecuted instantiation: unsigned int GDAL_LercNS::Lerc2::ComputeNumBytesNeededToWrite<unsigned int>(unsigned int const*, double, bool) Unexecuted instantiation: unsigned int GDAL_LercNS::Lerc2::ComputeNumBytesNeededToWrite<float>(float const*, double, bool) Unexecuted instantiation: unsigned int GDAL_LercNS::Lerc2::ComputeNumBytesNeededToWrite<double>(double const*, double, bool) |
396 | | |
397 | | // -------------------------------------------------------------------------- ; |
398 | | |
399 | | template<class T> |
400 | | bool Lerc2::Encode(const T* arr, Byte** ppByte) |
401 | 0 | { |
402 | 0 | if (!arr || !ppByte || !IsLittleEndianSystem()) |
403 | 0 | return false; |
404 | | |
405 | 0 | Byte* ptrBlob = *ppByte; // keep a ptr to the start of the blob |
406 | |
|
407 | 0 | if (!WriteHeader(ppByte, m_headerInfo)) |
408 | 0 | return false; |
409 | | |
410 | 0 | if (!WriteMask(ppByte)) |
411 | 0 | return false; |
412 | | |
413 | 0 | if (m_headerInfo.numValidPixel == 0 || m_headerInfo.zMin == m_headerInfo.zMax) |
414 | 0 | { |
415 | 0 | return DoChecksOnEncode(ptrBlob, *ppByte); |
416 | 0 | } |
417 | | |
418 | 0 | if (m_headerInfo.version >= 4) |
419 | 0 | { |
420 | 0 | if (!WriteMinMaxRanges(arr, ppByte)) |
421 | 0 | return false; |
422 | | |
423 | 0 | bool minMaxEqual = false; |
424 | 0 | if (!CheckMinMaxRanges(minMaxEqual)) |
425 | 0 | return false; |
426 | | |
427 | 0 | if (minMaxEqual) |
428 | 0 | return DoChecksOnEncode(ptrBlob, *ppByte); |
429 | 0 | } |
430 | | |
431 | 0 | **ppByte = m_writeDataOneSweep ? 1 : 0; // write flag |
432 | 0 | (*ppByte)++; |
433 | |
|
434 | 0 | if (!m_writeDataOneSweep) |
435 | 0 | { |
436 | 0 | if (m_headerInfo.TryHuffman()) |
437 | 0 | { |
438 | 0 | **ppByte = (Byte)m_imageEncodeMode; // Huffman or tiling encode mode |
439 | 0 | (*ppByte)++; |
440 | |
|
441 | 0 | if (!m_huffmanCodes.empty()) // Huffman, no tiling |
442 | 0 | { |
443 | 0 | if (m_imageEncodeMode != IEM_DeltaHuffman && m_imageEncodeMode != IEM_Huffman) |
444 | 0 | return false; |
445 | | |
446 | 0 | if (!EncodeHuffman(arr, ppByte)) // data bit stuffed |
447 | 0 | return false; |
448 | | |
449 | 0 | return DoChecksOnEncode(ptrBlob, *ppByte); |
450 | 0 | } |
451 | 0 | } |
452 | | |
453 | 0 | int numBytes = 0; |
454 | 0 | std::vector<double> zMinVec, zMaxVec; |
455 | 0 | if (!WriteTiles(arr, ppByte, numBytes, zMinVec, zMaxVec)) |
456 | 0 | return false; |
457 | 0 | } |
458 | 0 | else |
459 | 0 | { |
460 | 0 | if (!WriteDataOneSweep(arr, ppByte)) |
461 | 0 | return false; |
462 | 0 | } |
463 | | |
464 | 0 | return DoChecksOnEncode(ptrBlob, *ppByte); |
465 | 0 | } Unexecuted instantiation: bool GDAL_LercNS::Lerc2::Encode<signed char>(signed char const*, unsigned char**) Unexecuted instantiation: bool GDAL_LercNS::Lerc2::Encode<unsigned char>(unsigned char const*, unsigned char**) Unexecuted instantiation: bool GDAL_LercNS::Lerc2::Encode<short>(short const*, unsigned char**) Unexecuted instantiation: bool GDAL_LercNS::Lerc2::Encode<unsigned short>(unsigned short const*, unsigned char**) Unexecuted instantiation: bool GDAL_LercNS::Lerc2::Encode<int>(int const*, unsigned char**) Unexecuted instantiation: bool GDAL_LercNS::Lerc2::Encode<unsigned int>(unsigned int const*, unsigned char**) Unexecuted instantiation: bool GDAL_LercNS::Lerc2::Encode<float>(float const*, unsigned char**) Unexecuted instantiation: bool GDAL_LercNS::Lerc2::Encode<double>(double const*, unsigned char**) |
466 | | |
467 | | // -------------------------------------------------------------------------- ; |
468 | | |
469 | | template<class T> |
470 | | bool Lerc2::Decode(const Byte** ppByte, size_t& nBytesRemaining, T* arr, Byte* pMaskBits) |
471 | 39.0k | { |
472 | 39.0k | if (!arr || !ppByte || !IsLittleEndianSystem()) |
473 | 0 | return false; |
474 | | |
475 | 39.0k | const Byte* ptrBlob = *ppByte; // keep a ptr to the start of the blob |
476 | 39.0k | size_t nBytesRemaining00 = nBytesRemaining; |
477 | | |
478 | 39.0k | if (!ReadHeader(ppByte, nBytesRemaining, m_headerInfo)) |
479 | 0 | return false; |
480 | | |
481 | 39.0k | if (nBytesRemaining00 < (size_t)m_headerInfo.blobSize) |
482 | 0 | return false; |
483 | | |
484 | 39.0k | if (m_headerInfo.version >= 3) |
485 | 33.6k | { |
486 | 33.6k | int nBytes = (int)(FileKey().length() + sizeof(int) + sizeof(unsigned int)); // start right after the checksum entry |
487 | 33.6k | if (m_headerInfo.blobSize < nBytes) |
488 | 203 | return false; |
489 | 33.4k | unsigned int checksum = ComputeChecksumFletcher32(ptrBlob + nBytes, m_headerInfo.blobSize - nBytes); |
490 | 33.4k | #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION |
491 | | // For fuzzing, ignore checksum verification |
492 | 33.4k | (void)checksum; |
493 | | #else |
494 | | if (checksum != m_headerInfo.checksum) |
495 | | return false; |
496 | | #endif |
497 | 33.4k | } |
498 | | |
499 | 38.8k | if (!ReadMask(ppByte, nBytesRemaining)) |
500 | 6.60k | return false; |
501 | | |
502 | 32.2k | if (pMaskBits) // return proper mask bits even if they were not stored |
503 | 3.32k | memcpy(pMaskBits, m_bitMask.Bits(), m_bitMask.Size()); |
504 | | |
505 | 32.2k | memset(arr, 0, m_headerInfo.nCols * m_headerInfo.nRows * m_headerInfo.nDim * sizeof(T)); |
506 | | |
507 | 32.2k | if (m_headerInfo.numValidPixel == 0) |
508 | 263 | return true; |
509 | | |
510 | 31.9k | if (m_headerInfo.zMin == m_headerInfo.zMax) // image is const |
511 | 1.24k | { |
512 | 1.24k | if (!FillConstImage(arr)) |
513 | 0 | return false; |
514 | | |
515 | 1.24k | return true; |
516 | 1.24k | } |
517 | | |
518 | 30.7k | if (m_headerInfo.version >= 4) |
519 | 25.3k | { |
520 | 25.3k | if (!ReadMinMaxRanges(ppByte, nBytesRemaining, arr)) |
521 | 1.08k | return false; |
522 | | |
523 | 24.2k | bool minMaxEqual = false; |
524 | 24.2k | if (!CheckMinMaxRanges(minMaxEqual)) |
525 | 0 | return false; |
526 | | |
527 | 24.2k | if (minMaxEqual) // if all bands are const, fill outgoing and done |
528 | 502 | { |
529 | 502 | if (!FillConstImage(arr)) |
530 | 0 | return false; |
531 | | |
532 | 502 | return true; // done |
533 | 502 | } |
534 | 24.2k | } |
535 | | |
536 | 29.1k | if (nBytesRemaining < 1) |
537 | 242 | return false; |
538 | | |
539 | 28.8k | Byte readDataOneSweep = **ppByte; // read flag |
540 | 28.8k | (*ppByte)++; |
541 | 28.8k | nBytesRemaining--; |
542 | | |
543 | 28.8k | if (!readDataOneSweep) |
544 | 23.3k | { |
545 | 23.3k | if (m_headerInfo.TryHuffman()) |
546 | 10.8k | { |
547 | 10.8k | if (nBytesRemaining < 1) |
548 | 11 | return false; |
549 | | |
550 | 10.8k | Byte flag = **ppByte; // read flag Huffman / Lerc2 |
551 | 10.8k | (*ppByte)++; |
552 | 10.8k | nBytesRemaining--; |
553 | | |
554 | 10.8k | if (flag > 2 || (m_headerInfo.version < 4 && flag > 1)) |
555 | 133 | return false; |
556 | | |
557 | 10.7k | m_imageEncodeMode = (ImageEncodeMode)flag; |
558 | | |
559 | 10.7k | if (m_imageEncodeMode == IEM_DeltaHuffman || m_imageEncodeMode == IEM_Huffman) |
560 | 9.92k | { |
561 | 9.92k | if (!DecodeHuffman(ppByte, nBytesRemaining, arr)) |
562 | 9.28k | return false; |
563 | | |
564 | 633 | return true; // done. |
565 | 9.92k | } |
566 | 10.7k | } |
567 | | |
568 | 13.3k | if (!ReadTiles(ppByte, nBytesRemaining, arr)) |
569 | 12.6k | return false; |
570 | 13.3k | } |
571 | 5.49k | else |
572 | 5.49k | { |
573 | 5.49k | if (!ReadDataOneSweep(ppByte, nBytesRemaining, arr)) |
574 | 3.14k | return false; |
575 | 5.49k | } |
576 | | |
577 | 2.98k | return true; |
578 | 28.8k | } bool GDAL_LercNS::Lerc2::Decode<signed char>(unsigned char const**, unsigned long&, signed char*, unsigned char*) Line | Count | Source | 471 | 4.79k | { | 472 | 4.79k | if (!arr || !ppByte || !IsLittleEndianSystem()) | 473 | 0 | return false; | 474 | | | 475 | 4.79k | const Byte* ptrBlob = *ppByte; // keep a ptr to the start of the blob | 476 | 4.79k | size_t nBytesRemaining00 = nBytesRemaining; | 477 | | | 478 | 4.79k | if (!ReadHeader(ppByte, nBytesRemaining, m_headerInfo)) | 479 | 0 | return false; | 480 | | | 481 | 4.79k | if (nBytesRemaining00 < (size_t)m_headerInfo.blobSize) | 482 | 0 | return false; | 483 | | | 484 | 4.79k | if (m_headerInfo.version >= 3) | 485 | 3.79k | { | 486 | 3.79k | int nBytes = (int)(FileKey().length() + sizeof(int) + sizeof(unsigned int)); // start right after the checksum entry | 487 | 3.79k | if (m_headerInfo.blobSize < nBytes) | 488 | 0 | return false; | 489 | 3.79k | unsigned int checksum = ComputeChecksumFletcher32(ptrBlob + nBytes, m_headerInfo.blobSize - nBytes); | 490 | 3.79k | #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION | 491 | | // For fuzzing, ignore checksum verification | 492 | 3.79k | (void)checksum; | 493 | | #else | 494 | | if (checksum != m_headerInfo.checksum) | 495 | | return false; | 496 | | #endif | 497 | 3.79k | } | 498 | | | 499 | 4.79k | if (!ReadMask(ppByte, nBytesRemaining)) | 500 | 101 | return false; | 501 | | | 502 | 4.69k | if (pMaskBits) // return proper mask bits even if they were not stored | 503 | 0 | memcpy(pMaskBits, m_bitMask.Bits(), m_bitMask.Size()); | 504 | | | 505 | 4.69k | memset(arr, 0, m_headerInfo.nCols * m_headerInfo.nRows * m_headerInfo.nDim * sizeof(T)); | 506 | | | 507 | 4.69k | if (m_headerInfo.numValidPixel == 0) | 508 | 24 | return true; | 509 | | | 510 | 4.66k | if (m_headerInfo.zMin == m_headerInfo.zMax) // image is const | 511 | 359 | { | 512 | 359 | if (!FillConstImage(arr)) | 513 | 0 | return false; | 514 | | | 515 | 359 | return true; | 516 | 359 | } | 517 | | | 518 | 4.30k | if (m_headerInfo.version >= 4) | 519 | 3.63k | { | 520 | 3.63k | if (!ReadMinMaxRanges(ppByte, nBytesRemaining, arr)) | 521 | 0 | return false; | 522 | | | 523 | 3.63k | bool minMaxEqual = false; | 524 | 3.63k | if (!CheckMinMaxRanges(minMaxEqual)) | 525 | 0 | return false; | 526 | | | 527 | 3.63k | if (minMaxEqual) // if all bands are const, fill outgoing and done | 528 | 72 | { | 529 | 72 | if (!FillConstImage(arr)) | 530 | 0 | return false; | 531 | | | 532 | 72 | return true; // done | 533 | 72 | } | 534 | 3.63k | } | 535 | | | 536 | 4.23k | if (nBytesRemaining < 1) | 537 | 0 | return false; | 538 | | | 539 | 4.23k | Byte readDataOneSweep = **ppByte; // read flag | 540 | 4.23k | (*ppByte)++; | 541 | 4.23k | nBytesRemaining--; | 542 | | | 543 | 4.23k | if (!readDataOneSweep) | 544 | 3.64k | { | 545 | 3.64k | if (m_headerInfo.TryHuffman()) | 546 | 2.47k | { | 547 | 2.47k | if (nBytesRemaining < 1) | 548 | 0 | return false; | 549 | | | 550 | 2.47k | Byte flag = **ppByte; // read flag Huffman / Lerc2 | 551 | 2.47k | (*ppByte)++; | 552 | 2.47k | nBytesRemaining--; | 553 | | | 554 | 2.47k | if (flag > 2 || (m_headerInfo.version < 4 && flag > 1)) | 555 | 26 | return false; | 556 | | | 557 | 2.45k | m_imageEncodeMode = (ImageEncodeMode)flag; | 558 | | | 559 | 2.45k | if (m_imageEncodeMode == IEM_DeltaHuffman || m_imageEncodeMode == IEM_Huffman) | 560 | 2.42k | { | 561 | 2.42k | if (!DecodeHuffman(ppByte, nBytesRemaining, arr)) | 562 | 2.33k | return false; | 563 | | | 564 | 84 | return true; // done. | 565 | 2.42k | } | 566 | 2.45k | } | 567 | | | 568 | 1.19k | if (!ReadTiles(ppByte, nBytesRemaining, arr)) | 569 | 1.17k | return false; | 570 | 1.19k | } | 571 | 594 | else | 572 | 594 | { | 573 | 594 | if (!ReadDataOneSweep(ppByte, nBytesRemaining, arr)) | 574 | 42 | return false; | 575 | 594 | } | 576 | | | 577 | 575 | return true; | 578 | 4.23k | } |
bool GDAL_LercNS::Lerc2::Decode<unsigned char>(unsigned char const**, unsigned long&, unsigned char*, unsigned char*) Line | Count | Source | 471 | 16.4k | { | 472 | 16.4k | if (!arr || !ppByte || !IsLittleEndianSystem()) | 473 | 0 | return false; | 474 | | | 475 | 16.4k | const Byte* ptrBlob = *ppByte; // keep a ptr to the start of the blob | 476 | 16.4k | size_t nBytesRemaining00 = nBytesRemaining; | 477 | | | 478 | 16.4k | if (!ReadHeader(ppByte, nBytesRemaining, m_headerInfo)) | 479 | 0 | return false; | 480 | | | 481 | 16.4k | if (nBytesRemaining00 < (size_t)m_headerInfo.blobSize) | 482 | 0 | return false; | 483 | | | 484 | 16.4k | if (m_headerInfo.version >= 3) | 485 | 13.1k | { | 486 | 13.1k | int nBytes = (int)(FileKey().length() + sizeof(int) + sizeof(unsigned int)); // start right after the checksum entry | 487 | 13.1k | if (m_headerInfo.blobSize < nBytes) | 488 | 28 | return false; | 489 | 13.1k | unsigned int checksum = ComputeChecksumFletcher32(ptrBlob + nBytes, m_headerInfo.blobSize - nBytes); | 490 | 13.1k | #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION | 491 | | // For fuzzing, ignore checksum verification | 492 | 13.1k | (void)checksum; | 493 | | #else | 494 | | if (checksum != m_headerInfo.checksum) | 495 | | return false; | 496 | | #endif | 497 | 13.1k | } | 498 | | | 499 | 16.3k | if (!ReadMask(ppByte, nBytesRemaining)) | 500 | 837 | return false; | 501 | | | 502 | 15.5k | if (pMaskBits) // return proper mask bits even if they were not stored | 503 | 3.32k | memcpy(pMaskBits, m_bitMask.Bits(), m_bitMask.Size()); | 504 | | | 505 | 15.5k | memset(arr, 0, m_headerInfo.nCols * m_headerInfo.nRows * m_headerInfo.nDim * sizeof(T)); | 506 | | | 507 | 15.5k | if (m_headerInfo.numValidPixel == 0) | 508 | 146 | return true; | 509 | | | 510 | 15.4k | if (m_headerInfo.zMin == m_headerInfo.zMax) // image is const | 511 | 608 | { | 512 | 608 | if (!FillConstImage(arr)) | 513 | 0 | return false; | 514 | | | 515 | 608 | return true; | 516 | 608 | } | 517 | | | 518 | 14.7k | if (m_headerInfo.version >= 4) | 519 | 12.2k | { | 520 | 12.2k | if (!ReadMinMaxRanges(ppByte, nBytesRemaining, arr)) | 521 | 221 | return false; | 522 | | | 523 | 12.0k | bool minMaxEqual = false; | 524 | 12.0k | if (!CheckMinMaxRanges(minMaxEqual)) | 525 | 0 | return false; | 526 | | | 527 | 12.0k | if (minMaxEqual) // if all bands are const, fill outgoing and done | 528 | 151 | { | 529 | 151 | if (!FillConstImage(arr)) | 530 | 0 | return false; | 531 | | | 532 | 151 | return true; // done | 533 | 151 | } | 534 | 12.0k | } | 535 | | | 536 | 14.4k | if (nBytesRemaining < 1) | 537 | 67 | return false; | 538 | | | 539 | 14.3k | Byte readDataOneSweep = **ppByte; // read flag | 540 | 14.3k | (*ppByte)++; | 541 | 14.3k | nBytesRemaining--; | 542 | | | 543 | 14.3k | if (!readDataOneSweep) | 544 | 10.8k | { | 545 | 10.8k | if (m_headerInfo.TryHuffman()) | 546 | 8.38k | { | 547 | 8.38k | if (nBytesRemaining < 1) | 548 | 11 | return false; | 549 | | | 550 | 8.37k | Byte flag = **ppByte; // read flag Huffman / Lerc2 | 551 | 8.37k | (*ppByte)++; | 552 | 8.37k | nBytesRemaining--; | 553 | | | 554 | 8.37k | if (flag > 2 || (m_headerInfo.version < 4 && flag > 1)) | 555 | 107 | return false; | 556 | | | 557 | 8.26k | m_imageEncodeMode = (ImageEncodeMode)flag; | 558 | | | 559 | 8.26k | if (m_imageEncodeMode == IEM_DeltaHuffman || m_imageEncodeMode == IEM_Huffman) | 560 | 7.49k | { | 561 | 7.49k | if (!DecodeHuffman(ppByte, nBytesRemaining, arr)) | 562 | 6.95k | return false; | 563 | | | 564 | 549 | return true; // done. | 565 | 7.49k | } | 566 | 8.26k | } | 567 | | | 568 | 3.21k | if (!ReadTiles(ppByte, nBytesRemaining, arr)) | 569 | 2.72k | return false; | 570 | 3.21k | } | 571 | 3.52k | else | 572 | 3.52k | { | 573 | 3.52k | if (!ReadDataOneSweep(ppByte, nBytesRemaining, arr)) | 574 | 2.03k | return false; | 575 | 3.52k | } | 576 | | | 577 | 1.98k | return true; | 578 | 14.3k | } |
bool GDAL_LercNS::Lerc2::Decode<short>(unsigned char const**, unsigned long&, short*, unsigned char*) Line | Count | Source | 471 | 2.60k | { | 472 | 2.60k | if (!arr || !ppByte || !IsLittleEndianSystem()) | 473 | 0 | return false; | 474 | | | 475 | 2.60k | const Byte* ptrBlob = *ppByte; // keep a ptr to the start of the blob | 476 | 2.60k | size_t nBytesRemaining00 = nBytesRemaining; | 477 | | | 478 | 2.60k | if (!ReadHeader(ppByte, nBytesRemaining, m_headerInfo)) | 479 | 0 | return false; | 480 | | | 481 | 2.60k | if (nBytesRemaining00 < (size_t)m_headerInfo.blobSize) | 482 | 0 | return false; | 483 | | | 484 | 2.60k | if (m_headerInfo.version >= 3) | 485 | 2.55k | { | 486 | 2.55k | int nBytes = (int)(FileKey().length() + sizeof(int) + sizeof(unsigned int)); // start right after the checksum entry | 487 | 2.55k | if (m_headerInfo.blobSize < nBytes) | 488 | 30 | return false; | 489 | 2.52k | unsigned int checksum = ComputeChecksumFletcher32(ptrBlob + nBytes, m_headerInfo.blobSize - nBytes); | 490 | 2.52k | #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION | 491 | | // For fuzzing, ignore checksum verification | 492 | 2.52k | (void)checksum; | 493 | | #else | 494 | | if (checksum != m_headerInfo.checksum) | 495 | | return false; | 496 | | #endif | 497 | 2.52k | } | 498 | | | 499 | 2.57k | if (!ReadMask(ppByte, nBytesRemaining)) | 500 | 328 | return false; | 501 | | | 502 | 2.25k | if (pMaskBits) // return proper mask bits even if they were not stored | 503 | 0 | memcpy(pMaskBits, m_bitMask.Bits(), m_bitMask.Size()); | 504 | | | 505 | 2.25k | memset(arr, 0, m_headerInfo.nCols * m_headerInfo.nRows * m_headerInfo.nDim * sizeof(T)); | 506 | | | 507 | 2.25k | if (m_headerInfo.numValidPixel == 0) | 508 | 32 | return true; | 509 | | | 510 | 2.21k | if (m_headerInfo.zMin == m_headerInfo.zMax) // image is const | 511 | 60 | { | 512 | 60 | if (!FillConstImage(arr)) | 513 | 0 | return false; | 514 | | | 515 | 60 | return true; | 516 | 60 | } | 517 | | | 518 | 2.15k | if (m_headerInfo.version >= 4) | 519 | 2.09k | { | 520 | 2.09k | if (!ReadMinMaxRanges(ppByte, nBytesRemaining, arr)) | 521 | 148 | return false; | 522 | | | 523 | 1.95k | bool minMaxEqual = false; | 524 | 1.95k | if (!CheckMinMaxRanges(minMaxEqual)) | 525 | 0 | return false; | 526 | | | 527 | 1.95k | if (minMaxEqual) // if all bands are const, fill outgoing and done | 528 | 81 | { | 529 | 81 | if (!FillConstImage(arr)) | 530 | 0 | return false; | 531 | | | 532 | 81 | return true; // done | 533 | 81 | } | 534 | 1.95k | } | 535 | | | 536 | 1.92k | if (nBytesRemaining < 1) | 537 | 22 | return false; | 538 | | | 539 | 1.90k | Byte readDataOneSweep = **ppByte; // read flag | 540 | 1.90k | (*ppByte)++; | 541 | 1.90k | nBytesRemaining--; | 542 | | | 543 | 1.90k | if (!readDataOneSweep) | 544 | 1.80k | { | 545 | 1.80k | if (m_headerInfo.TryHuffman()) | 546 | 0 | { | 547 | 0 | if (nBytesRemaining < 1) | 548 | 0 | return false; | 549 | | | 550 | 0 | Byte flag = **ppByte; // read flag Huffman / Lerc2 | 551 | 0 | (*ppByte)++; | 552 | 0 | nBytesRemaining--; | 553 | |
| 554 | 0 | if (flag > 2 || (m_headerInfo.version < 4 && flag > 1)) | 555 | 0 | return false; | 556 | | | 557 | 0 | m_imageEncodeMode = (ImageEncodeMode)flag; | 558 | |
| 559 | 0 | if (m_imageEncodeMode == IEM_DeltaHuffman || m_imageEncodeMode == IEM_Huffman) | 560 | 0 | { | 561 | 0 | if (!DecodeHuffman(ppByte, nBytesRemaining, arr)) | 562 | 0 | return false; | 563 | | | 564 | 0 | return true; // done. | 565 | 0 | } | 566 | 0 | } | 567 | | | 568 | 1.80k | if (!ReadTiles(ppByte, nBytesRemaining, arr)) | 569 | 1.75k | return false; | 570 | 1.80k | } | 571 | 101 | else | 572 | 101 | { | 573 | 101 | if (!ReadDataOneSweep(ppByte, nBytesRemaining, arr)) | 574 | 72 | return false; | 575 | 101 | } | 576 | | | 577 | 85 | return true; | 578 | 1.90k | } |
bool GDAL_LercNS::Lerc2::Decode<unsigned short>(unsigned char const**, unsigned long&, unsigned short*, unsigned char*) Line | Count | Source | 471 | 8.43k | { | 472 | 8.43k | if (!arr || !ppByte || !IsLittleEndianSystem()) | 473 | 0 | return false; | 474 | | | 475 | 8.43k | const Byte* ptrBlob = *ppByte; // keep a ptr to the start of the blob | 476 | 8.43k | size_t nBytesRemaining00 = nBytesRemaining; | 477 | | | 478 | 8.43k | if (!ReadHeader(ppByte, nBytesRemaining, m_headerInfo)) | 479 | 0 | return false; | 480 | | | 481 | 8.43k | if (nBytesRemaining00 < (size_t)m_headerInfo.blobSize) | 482 | 0 | return false; | 483 | | | 484 | 8.43k | if (m_headerInfo.version >= 3) | 485 | 8.38k | { | 486 | 8.38k | int nBytes = (int)(FileKey().length() + sizeof(int) + sizeof(unsigned int)); // start right after the checksum entry | 487 | 8.38k | if (m_headerInfo.blobSize < nBytes) | 488 | 32 | return false; | 489 | 8.35k | unsigned int checksum = ComputeChecksumFletcher32(ptrBlob + nBytes, m_headerInfo.blobSize - nBytes); | 490 | 8.35k | #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION | 491 | | // For fuzzing, ignore checksum verification | 492 | 8.35k | (void)checksum; | 493 | | #else | 494 | | if (checksum != m_headerInfo.checksum) | 495 | | return false; | 496 | | #endif | 497 | 8.35k | } | 498 | | | 499 | 8.40k | if (!ReadMask(ppByte, nBytesRemaining)) | 500 | 4.87k | return false; | 501 | | | 502 | 3.52k | if (pMaskBits) // return proper mask bits even if they were not stored | 503 | 0 | memcpy(pMaskBits, m_bitMask.Bits(), m_bitMask.Size()); | 504 | | | 505 | 3.52k | memset(arr, 0, m_headerInfo.nCols * m_headerInfo.nRows * m_headerInfo.nDim * sizeof(T)); | 506 | | | 507 | 3.52k | if (m_headerInfo.numValidPixel == 0) | 508 | 32 | return true; | 509 | | | 510 | 3.49k | if (m_headerInfo.zMin == m_headerInfo.zMax) // image is const | 511 | 39 | { | 512 | 39 | if (!FillConstImage(arr)) | 513 | 0 | return false; | 514 | | | 515 | 39 | return true; | 516 | 39 | } | 517 | | | 518 | 3.45k | if (m_headerInfo.version >= 4) | 519 | 2.31k | { | 520 | 2.31k | if (!ReadMinMaxRanges(ppByte, nBytesRemaining, arr)) | 521 | 141 | return false; | 522 | | | 523 | 2.16k | bool minMaxEqual = false; | 524 | 2.16k | if (!CheckMinMaxRanges(minMaxEqual)) | 525 | 0 | return false; | 526 | | | 527 | 2.16k | if (minMaxEqual) // if all bands are const, fill outgoing and done | 528 | 119 | { | 529 | 119 | if (!FillConstImage(arr)) | 530 | 0 | return false; | 531 | | | 532 | 119 | return true; // done | 533 | 119 | } | 534 | 2.16k | } | 535 | | | 536 | 3.19k | if (nBytesRemaining < 1) | 537 | 37 | return false; | 538 | | | 539 | 3.16k | Byte readDataOneSweep = **ppByte; // read flag | 540 | 3.16k | (*ppByte)++; | 541 | 3.16k | nBytesRemaining--; | 542 | | | 543 | 3.16k | if (!readDataOneSweep) | 544 | 2.73k | { | 545 | 2.73k | if (m_headerInfo.TryHuffman()) | 546 | 0 | { | 547 | 0 | if (nBytesRemaining < 1) | 548 | 0 | return false; | 549 | | | 550 | 0 | Byte flag = **ppByte; // read flag Huffman / Lerc2 | 551 | 0 | (*ppByte)++; | 552 | 0 | nBytesRemaining--; | 553 | |
| 554 | 0 | if (flag > 2 || (m_headerInfo.version < 4 && flag > 1)) | 555 | 0 | return false; | 556 | | | 557 | 0 | m_imageEncodeMode = (ImageEncodeMode)flag; | 558 | |
| 559 | 0 | if (m_imageEncodeMode == IEM_DeltaHuffman || m_imageEncodeMode == IEM_Huffman) | 560 | 0 | { | 561 | 0 | if (!DecodeHuffman(ppByte, nBytesRemaining, arr)) | 562 | 0 | return false; | 563 | | | 564 | 0 | return true; // done. | 565 | 0 | } | 566 | 0 | } | 567 | | | 568 | 2.73k | if (!ReadTiles(ppByte, nBytesRemaining, arr)) | 569 | 2.67k | return false; | 570 | 2.73k | } | 571 | 427 | else | 572 | 427 | { | 573 | 427 | if (!ReadDataOneSweep(ppByte, nBytesRemaining, arr)) | 574 | 360 | return false; | 575 | 427 | } | 576 | | | 577 | 122 | return true; | 578 | 3.16k | } |
bool GDAL_LercNS::Lerc2::Decode<int>(unsigned char const**, unsigned long&, int*, unsigned char*) Line | Count | Source | 471 | 1.58k | { | 472 | 1.58k | if (!arr || !ppByte || !IsLittleEndianSystem()) | 473 | 0 | return false; | 474 | | | 475 | 1.58k | const Byte* ptrBlob = *ppByte; // keep a ptr to the start of the blob | 476 | 1.58k | size_t nBytesRemaining00 = nBytesRemaining; | 477 | | | 478 | 1.58k | if (!ReadHeader(ppByte, nBytesRemaining, m_headerInfo)) | 479 | 0 | return false; | 480 | | | 481 | 1.58k | if (nBytesRemaining00 < (size_t)m_headerInfo.blobSize) | 482 | 0 | return false; | 483 | | | 484 | 1.58k | if (m_headerInfo.version >= 3) | 485 | 1.48k | { | 486 | 1.48k | int nBytes = (int)(FileKey().length() + sizeof(int) + sizeof(unsigned int)); // start right after the checksum entry | 487 | 1.48k | if (m_headerInfo.blobSize < nBytes) | 488 | 32 | return false; | 489 | 1.45k | unsigned int checksum = ComputeChecksumFletcher32(ptrBlob + nBytes, m_headerInfo.blobSize - nBytes); | 490 | 1.45k | #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION | 491 | | // For fuzzing, ignore checksum verification | 492 | 1.45k | (void)checksum; | 493 | | #else | 494 | | if (checksum != m_headerInfo.checksum) | 495 | | return false; | 496 | | #endif | 497 | 1.45k | } | 498 | | | 499 | 1.54k | if (!ReadMask(ppByte, nBytesRemaining)) | 500 | 170 | return false; | 501 | | | 502 | 1.37k | if (pMaskBits) // return proper mask bits even if they were not stored | 503 | 0 | memcpy(pMaskBits, m_bitMask.Bits(), m_bitMask.Size()); | 504 | | | 505 | 1.37k | memset(arr, 0, m_headerInfo.nCols * m_headerInfo.nRows * m_headerInfo.nDim * sizeof(T)); | 506 | | | 507 | 1.37k | if (m_headerInfo.numValidPixel == 0) | 508 | 5 | return true; | 509 | | | 510 | 1.37k | if (m_headerInfo.zMin == m_headerInfo.zMax) // image is const | 511 | 28 | { | 512 | 28 | if (!FillConstImage(arr)) | 513 | 0 | return false; | 514 | | | 515 | 28 | return true; | 516 | 28 | } | 517 | | | 518 | 1.34k | if (m_headerInfo.version >= 4) | 519 | 1.25k | { | 520 | 1.25k | if (!ReadMinMaxRanges(ppByte, nBytesRemaining, arr)) | 521 | 211 | return false; | 522 | | | 523 | 1.03k | bool minMaxEqual = false; | 524 | 1.03k | if (!CheckMinMaxRanges(minMaxEqual)) | 525 | 0 | return false; | 526 | | | 527 | 1.03k | if (minMaxEqual) // if all bands are const, fill outgoing and done | 528 | 23 | { | 529 | 23 | if (!FillConstImage(arr)) | 530 | 0 | return false; | 531 | | | 532 | 23 | return true; // done | 533 | 23 | } | 534 | 1.03k | } | 535 | | | 536 | 1.11k | if (nBytesRemaining < 1) | 537 | 22 | return false; | 538 | | | 539 | 1.08k | Byte readDataOneSweep = **ppByte; // read flag | 540 | 1.08k | (*ppByte)++; | 541 | 1.08k | nBytesRemaining--; | 542 | | | 543 | 1.08k | if (!readDataOneSweep) | 544 | 979 | { | 545 | 979 | if (m_headerInfo.TryHuffman()) | 546 | 0 | { | 547 | 0 | if (nBytesRemaining < 1) | 548 | 0 | return false; | 549 | | | 550 | 0 | Byte flag = **ppByte; // read flag Huffman / Lerc2 | 551 | 0 | (*ppByte)++; | 552 | 0 | nBytesRemaining--; | 553 | |
| 554 | 0 | if (flag > 2 || (m_headerInfo.version < 4 && flag > 1)) | 555 | 0 | return false; | 556 | | | 557 | 0 | m_imageEncodeMode = (ImageEncodeMode)flag; | 558 | |
| 559 | 0 | if (m_imageEncodeMode == IEM_DeltaHuffman || m_imageEncodeMode == IEM_Huffman) | 560 | 0 | { | 561 | 0 | if (!DecodeHuffman(ppByte, nBytesRemaining, arr)) | 562 | 0 | return false; | 563 | | | 564 | 0 | return true; // done. | 565 | 0 | } | 566 | 0 | } | 567 | | | 568 | 979 | if (!ReadTiles(ppByte, nBytesRemaining, arr)) | 569 | 977 | return false; | 570 | 979 | } | 571 | 110 | else | 572 | 110 | { | 573 | 110 | if (!ReadDataOneSweep(ppByte, nBytesRemaining, arr)) | 574 | 88 | return false; | 575 | 110 | } | 576 | | | 577 | 24 | return true; | 578 | 1.08k | } |
bool GDAL_LercNS::Lerc2::Decode<unsigned int>(unsigned char const**, unsigned long&, unsigned int*, unsigned char*) Line | Count | Source | 471 | 3.25k | { | 472 | 3.25k | if (!arr || !ppByte || !IsLittleEndianSystem()) | 473 | 0 | return false; | 474 | | | 475 | 3.25k | const Byte* ptrBlob = *ppByte; // keep a ptr to the start of the blob | 476 | 3.25k | size_t nBytesRemaining00 = nBytesRemaining; | 477 | | | 478 | 3.25k | if (!ReadHeader(ppByte, nBytesRemaining, m_headerInfo)) | 479 | 0 | return false; | 480 | | | 481 | 3.25k | if (nBytesRemaining00 < (size_t)m_headerInfo.blobSize) | 482 | 0 | return false; | 483 | | | 484 | 3.25k | if (m_headerInfo.version >= 3) | 485 | 2.41k | { | 486 | 2.41k | int nBytes = (int)(FileKey().length() + sizeof(int) + sizeof(unsigned int)); // start right after the checksum entry | 487 | 2.41k | if (m_headerInfo.blobSize < nBytes) | 488 | 31 | return false; | 489 | 2.38k | unsigned int checksum = ComputeChecksumFletcher32(ptrBlob + nBytes, m_headerInfo.blobSize - nBytes); | 490 | 2.38k | #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION | 491 | | // For fuzzing, ignore checksum verification | 492 | 2.38k | (void)checksum; | 493 | | #else | 494 | | if (checksum != m_headerInfo.checksum) | 495 | | return false; | 496 | | #endif | 497 | 2.38k | } | 498 | | | 499 | 3.22k | if (!ReadMask(ppByte, nBytesRemaining)) | 500 | 144 | return false; | 501 | | | 502 | 3.08k | if (pMaskBits) // return proper mask bits even if they were not stored | 503 | 0 | memcpy(pMaskBits, m_bitMask.Bits(), m_bitMask.Size()); | 504 | | | 505 | 3.08k | memset(arr, 0, m_headerInfo.nCols * m_headerInfo.nRows * m_headerInfo.nDim * sizeof(T)); | 506 | | | 507 | 3.08k | if (m_headerInfo.numValidPixel == 0) | 508 | 22 | return true; | 509 | | | 510 | 3.05k | if (m_headerInfo.zMin == m_headerInfo.zMax) // image is const | 511 | 99 | { | 512 | 99 | if (!FillConstImage(arr)) | 513 | 0 | return false; | 514 | | | 515 | 99 | return true; | 516 | 99 | } | 517 | | | 518 | 2.95k | if (m_headerInfo.version >= 4) | 519 | 2.23k | { | 520 | 2.23k | if (!ReadMinMaxRanges(ppByte, nBytesRemaining, arr)) | 521 | 91 | return false; | 522 | | | 523 | 2.14k | bool minMaxEqual = false; | 524 | 2.14k | if (!CheckMinMaxRanges(minMaxEqual)) | 525 | 0 | return false; | 526 | | | 527 | 2.14k | if (minMaxEqual) // if all bands are const, fill outgoing and done | 528 | 21 | { | 529 | 21 | if (!FillConstImage(arr)) | 530 | 0 | return false; | 531 | | | 532 | 21 | return true; // done | 533 | 21 | } | 534 | 2.14k | } | 535 | | | 536 | 2.84k | if (nBytesRemaining < 1) | 537 | 34 | return false; | 538 | | | 539 | 2.81k | Byte readDataOneSweep = **ppByte; // read flag | 540 | 2.81k | (*ppByte)++; | 541 | 2.81k | nBytesRemaining--; | 542 | | | 543 | 2.81k | if (!readDataOneSweep) | 544 | 2.24k | { | 545 | 2.24k | if (m_headerInfo.TryHuffman()) | 546 | 0 | { | 547 | 0 | if (nBytesRemaining < 1) | 548 | 0 | return false; | 549 | | | 550 | 0 | Byte flag = **ppByte; // read flag Huffman / Lerc2 | 551 | 0 | (*ppByte)++; | 552 | 0 | nBytesRemaining--; | 553 | |
| 554 | 0 | if (flag > 2 || (m_headerInfo.version < 4 && flag > 1)) | 555 | 0 | return false; | 556 | | | 557 | 0 | m_imageEncodeMode = (ImageEncodeMode)flag; | 558 | |
| 559 | 0 | if (m_imageEncodeMode == IEM_DeltaHuffman || m_imageEncodeMode == IEM_Huffman) | 560 | 0 | { | 561 | 0 | if (!DecodeHuffman(ppByte, nBytesRemaining, arr)) | 562 | 0 | return false; | 563 | | | 564 | 0 | return true; // done. | 565 | 0 | } | 566 | 0 | } | 567 | | | 568 | 2.24k | if (!ReadTiles(ppByte, nBytesRemaining, arr)) | 569 | 2.23k | return false; | 570 | 2.24k | } | 571 | 570 | else | 572 | 570 | { | 573 | 570 | if (!ReadDataOneSweep(ppByte, nBytesRemaining, arr)) | 574 | 446 | return false; | 575 | 570 | } | 576 | | | 577 | 133 | return true; | 578 | 2.81k | } |
bool GDAL_LercNS::Lerc2::Decode<float>(unsigned char const**, unsigned long&, float*, unsigned char*) Line | Count | Source | 471 | 967 | { | 472 | 967 | if (!arr || !ppByte || !IsLittleEndianSystem()) | 473 | 0 | return false; | 474 | | | 475 | 967 | const Byte* ptrBlob = *ppByte; // keep a ptr to the start of the blob | 476 | 967 | size_t nBytesRemaining00 = nBytesRemaining; | 477 | | | 478 | 967 | if (!ReadHeader(ppByte, nBytesRemaining, m_headerInfo)) | 479 | 0 | return false; | 480 | | | 481 | 967 | if (nBytesRemaining00 < (size_t)m_headerInfo.blobSize) | 482 | 0 | return false; | 483 | | | 484 | 967 | if (m_headerInfo.version >= 3) | 485 | 873 | { | 486 | 873 | int nBytes = (int)(FileKey().length() + sizeof(int) + sizeof(unsigned int)); // start right after the checksum entry | 487 | 873 | if (m_headerInfo.blobSize < nBytes) | 488 | 29 | return false; | 489 | 844 | unsigned int checksum = ComputeChecksumFletcher32(ptrBlob + nBytes, m_headerInfo.blobSize - nBytes); | 490 | 844 | #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION | 491 | | // For fuzzing, ignore checksum verification | 492 | 844 | (void)checksum; | 493 | | #else | 494 | | if (checksum != m_headerInfo.checksum) | 495 | | return false; | 496 | | #endif | 497 | 844 | } | 498 | | | 499 | 938 | if (!ReadMask(ppByte, nBytesRemaining)) | 500 | 80 | return false; | 501 | | | 502 | 858 | if (pMaskBits) // return proper mask bits even if they were not stored | 503 | 0 | memcpy(pMaskBits, m_bitMask.Bits(), m_bitMask.Size()); | 504 | | | 505 | 858 | memset(arr, 0, m_headerInfo.nCols * m_headerInfo.nRows * m_headerInfo.nDim * sizeof(T)); | 506 | | | 507 | 858 | if (m_headerInfo.numValidPixel == 0) | 508 | 1 | return true; | 509 | | | 510 | 857 | if (m_headerInfo.zMin == m_headerInfo.zMax) // image is const | 511 | 22 | { | 512 | 22 | if (!FillConstImage(arr)) | 513 | 0 | return false; | 514 | | | 515 | 22 | return true; | 516 | 22 | } | 517 | | | 518 | 835 | if (m_headerInfo.version >= 4) | 519 | 755 | { | 520 | 755 | if (!ReadMinMaxRanges(ppByte, nBytesRemaining, arr)) | 521 | 120 | return false; | 522 | | | 523 | 635 | bool minMaxEqual = false; | 524 | 635 | if (!CheckMinMaxRanges(minMaxEqual)) | 525 | 0 | return false; | 526 | | | 527 | 635 | if (minMaxEqual) // if all bands are const, fill outgoing and done | 528 | 19 | { | 529 | 19 | if (!FillConstImage(arr)) | 530 | 0 | return false; | 531 | | | 532 | 19 | return true; // done | 533 | 19 | } | 534 | 635 | } | 535 | | | 536 | 696 | if (nBytesRemaining < 1) | 537 | 34 | return false; | 538 | | | 539 | 662 | Byte readDataOneSweep = **ppByte; // read flag | 540 | 662 | (*ppByte)++; | 541 | 662 | nBytesRemaining--; | 542 | | | 543 | 662 | if (!readDataOneSweep) | 544 | 588 | { | 545 | 588 | if (m_headerInfo.TryHuffman()) | 546 | 0 | { | 547 | 0 | if (nBytesRemaining < 1) | 548 | 0 | return false; | 549 | | | 550 | 0 | Byte flag = **ppByte; // read flag Huffman / Lerc2 | 551 | 0 | (*ppByte)++; | 552 | 0 | nBytesRemaining--; | 553 | |
| 554 | 0 | if (flag > 2 || (m_headerInfo.version < 4 && flag > 1)) | 555 | 0 | return false; | 556 | | | 557 | 0 | m_imageEncodeMode = (ImageEncodeMode)flag; | 558 | |
| 559 | 0 | if (m_imageEncodeMode == IEM_DeltaHuffman || m_imageEncodeMode == IEM_Huffman) | 560 | 0 | { | 561 | 0 | if (!DecodeHuffman(ppByte, nBytesRemaining, arr)) | 562 | 0 | return false; | 563 | | | 564 | 0 | return true; // done. | 565 | 0 | } | 566 | 0 | } | 567 | | | 568 | 588 | if (!ReadTiles(ppByte, nBytesRemaining, arr)) | 569 | 585 | return false; | 570 | 588 | } | 571 | 74 | else | 572 | 74 | { | 573 | 74 | if (!ReadDataOneSweep(ppByte, nBytesRemaining, arr)) | 574 | 46 | return false; | 575 | 74 | } | 576 | | | 577 | 31 | return true; | 578 | 662 | } |
bool GDAL_LercNS::Lerc2::Decode<double>(unsigned char const**, unsigned long&, double*, unsigned char*) Line | Count | Source | 471 | 986 | { | 472 | 986 | if (!arr || !ppByte || !IsLittleEndianSystem()) | 473 | 0 | return false; | 474 | | | 475 | 986 | const Byte* ptrBlob = *ppByte; // keep a ptr to the start of the blob | 476 | 986 | size_t nBytesRemaining00 = nBytesRemaining; | 477 | | | 478 | 986 | if (!ReadHeader(ppByte, nBytesRemaining, m_headerInfo)) | 479 | 0 | return false; | 480 | | | 481 | 986 | if (nBytesRemaining00 < (size_t)m_headerInfo.blobSize) | 482 | 0 | return false; | 483 | | | 484 | 986 | if (m_headerInfo.version >= 3) | 485 | 930 | { | 486 | 930 | int nBytes = (int)(FileKey().length() + sizeof(int) + sizeof(unsigned int)); // start right after the checksum entry | 487 | 930 | if (m_headerInfo.blobSize < nBytes) | 488 | 21 | return false; | 489 | 909 | unsigned int checksum = ComputeChecksumFletcher32(ptrBlob + nBytes, m_headerInfo.blobSize - nBytes); | 490 | 909 | #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION | 491 | | // For fuzzing, ignore checksum verification | 492 | 909 | (void)checksum; | 493 | | #else | 494 | | if (checksum != m_headerInfo.checksum) | 495 | | return false; | 496 | | #endif | 497 | 909 | } | 498 | | | 499 | 965 | if (!ReadMask(ppByte, nBytesRemaining)) | 500 | 77 | return false; | 501 | | | 502 | 888 | if (pMaskBits) // return proper mask bits even if they were not stored | 503 | 0 | memcpy(pMaskBits, m_bitMask.Bits(), m_bitMask.Size()); | 504 | | | 505 | 888 | memset(arr, 0, m_headerInfo.nCols * m_headerInfo.nRows * m_headerInfo.nDim * sizeof(T)); | 506 | | | 507 | 888 | if (m_headerInfo.numValidPixel == 0) | 508 | 1 | return true; | 509 | | | 510 | 887 | if (m_headerInfo.zMin == m_headerInfo.zMax) // image is const | 511 | 30 | { | 512 | 30 | if (!FillConstImage(arr)) | 513 | 0 | return false; | 514 | | | 515 | 30 | return true; | 516 | 30 | } | 517 | | | 518 | 857 | if (m_headerInfo.version >= 4) | 519 | 812 | { | 520 | 812 | if (!ReadMinMaxRanges(ppByte, nBytesRemaining, arr)) | 521 | 157 | return false; | 522 | | | 523 | 655 | bool minMaxEqual = false; | 524 | 655 | if (!CheckMinMaxRanges(minMaxEqual)) | 525 | 0 | return false; | 526 | | | 527 | 655 | if (minMaxEqual) // if all bands are const, fill outgoing and done | 528 | 16 | { | 529 | 16 | if (!FillConstImage(arr)) | 530 | 0 | return false; | 531 | | | 532 | 16 | return true; // done | 533 | 16 | } | 534 | 655 | } | 535 | | | 536 | 684 | if (nBytesRemaining < 1) | 537 | 26 | return false; | 538 | | | 539 | 658 | Byte readDataOneSweep = **ppByte; // read flag | 540 | 658 | (*ppByte)++; | 541 | 658 | nBytesRemaining--; | 542 | | | 543 | 658 | if (!readDataOneSweep) | 544 | 572 | { | 545 | 572 | if (m_headerInfo.TryHuffman()) | 546 | 0 | { | 547 | 0 | if (nBytesRemaining < 1) | 548 | 0 | return false; | 549 | | | 550 | 0 | Byte flag = **ppByte; // read flag Huffman / Lerc2 | 551 | 0 | (*ppByte)++; | 552 | 0 | nBytesRemaining--; | 553 | |
| 554 | 0 | if (flag > 2 || (m_headerInfo.version < 4 && flag > 1)) | 555 | 0 | return false; | 556 | | | 557 | 0 | m_imageEncodeMode = (ImageEncodeMode)flag; | 558 | |
| 559 | 0 | if (m_imageEncodeMode == IEM_DeltaHuffman || m_imageEncodeMode == IEM_Huffman) | 560 | 0 | { | 561 | 0 | if (!DecodeHuffman(ppByte, nBytesRemaining, arr)) | 562 | 0 | return false; | 563 | | | 564 | 0 | return true; // done. | 565 | 0 | } | 566 | 0 | } | 567 | | | 568 | 572 | if (!ReadTiles(ppByte, nBytesRemaining, arr)) | 569 | 565 | return false; | 570 | 572 | } | 571 | 86 | else | 572 | 86 | { | 573 | 86 | if (!ReadDataOneSweep(ppByte, nBytesRemaining, arr)) | 574 | 61 | return false; | 575 | 86 | } | 576 | | | 577 | 32 | return true; | 578 | 658 | } |
|
579 | | |
580 | | // -------------------------------------------------------------------------- ; |
581 | | // -------------------------------------------------------------------------- ; |
582 | | |
583 | | inline |
584 | | void Lerc2::AddUIntToCounts(int* pCounts, unsigned int val, int nBits) |
585 | 0 | { |
586 | 0 | pCounts[0] += val & 1; |
587 | 0 | for (int i = 1; i < nBits; i++) |
588 | 0 | pCounts[i] += (val >>= 1) & 1; |
589 | 0 | } |
590 | | |
591 | | // -------------------------------------------------------------------------- ; |
592 | | |
593 | | inline |
594 | | void Lerc2::AddIntToCounts(int* pCounts, int val, int nBits) |
595 | 0 | { |
596 | 0 | pCounts[0] += val & 1; |
597 | 0 | for (int i = 1; i < nBits; i++) |
598 | 0 | pCounts[i] += (val >>= 1) & 1; |
599 | 0 | } |
600 | | |
601 | | // -------------------------------------------------------------------------- ; |
602 | | |
603 | | // for the theory and math, see |
604 | | // https://pdfs.semanticscholar.org/d064/2e2ad1a4c3b445b0d795770f604a5d9e269c.pdf |
605 | | |
606 | | template<class T> |
607 | | bool Lerc2::TryBitPlaneCompression(const T* data, double eps, double& newMaxZError) const |
608 | 0 | { |
609 | 0 | newMaxZError = 0; // lossless is the obvious fallback |
610 | |
|
611 | 0 | if (!data || eps <= 0) |
612 | 0 | return false; |
613 | | |
614 | 0 | const HeaderInfo& hd = m_headerInfo; |
615 | 0 | const int nDim = hd.nDim; |
616 | 0 | const int maxShift = 8 * GetDataTypeSize(hd.dt); |
617 | 0 | const int minCnt = 5000; |
618 | |
|
619 | 0 | if (hd.numValidPixel < minCnt) // not enough data for good stats |
620 | 0 | return false; |
621 | | |
622 | 0 | std::vector<int> cntDiffVec(nDim * maxShift, 0); |
623 | 0 | int cnt = 0; |
624 | |
|
625 | 0 | if (nDim == 1 && hd.numValidPixel == hd.nCols * hd.nRows) // special but common case |
626 | 0 | { |
627 | 0 | if (hd.dt == DT_Byte || hd.dt == DT_UShort || hd.dt == DT_UInt) // unsigned int |
628 | 0 | { |
629 | 0 | for (int i = 0; i < hd.nRows - 1; i++) |
630 | 0 | for (int k = i * hd.nCols, j = 0; j < hd.nCols - 1; j++, k++) |
631 | 0 | { |
632 | 0 | unsigned int c = ((unsigned int)data[k]) ^ ((unsigned int)data[k + 1]); |
633 | 0 | AddUIntToCounts(&cntDiffVec[0], c, maxShift); |
634 | 0 | cnt++; |
635 | 0 | c = ((unsigned int)data[k]) ^ ((unsigned int)data[k + hd.nCols]); |
636 | 0 | AddUIntToCounts(&cntDiffVec[0], c, maxShift); |
637 | 0 | cnt++; |
638 | 0 | } |
639 | 0 | } |
640 | 0 | else if (hd.dt == DT_Char || hd.dt == DT_Short || hd.dt == DT_Int) // signed int |
641 | 0 | { |
642 | 0 | for (int i = 0; i < hd.nRows - 1; i++) |
643 | 0 | for (int k = i * hd.nCols, j = 0; j < hd.nCols - 1; j++, k++) |
644 | 0 | { |
645 | 0 | int c = ((int)data[k]) ^ ((int)data[k + 1]); |
646 | 0 | AddIntToCounts(&cntDiffVec[0], c, maxShift); |
647 | 0 | cnt++; |
648 | 0 | c = ((int)data[k]) ^ ((int)data[k + hd.nCols]); |
649 | 0 | AddIntToCounts(&cntDiffVec[0], c, maxShift); |
650 | 0 | cnt++; |
651 | 0 | } |
652 | 0 | } |
653 | 0 | else |
654 | 0 | return false; // unsupported data type |
655 | 0 | } |
656 | | |
657 | 0 | else // general case: nDim > 1 or not all pixel valid |
658 | 0 | { |
659 | 0 | if (hd.dt == DT_Byte || hd.dt == DT_UShort || hd.dt == DT_UInt) // unsigned int |
660 | 0 | { |
661 | 0 | for (int k = 0, m0 = 0, i = 0; i < hd.nRows; i++) |
662 | 0 | for (int j = 0; j < hd.nCols; j++, k++, m0 += nDim) |
663 | 0 | if (m_bitMask.IsValid(k)) |
664 | 0 | { |
665 | 0 | if (j < hd.nCols - 1 && m_bitMask.IsValid(k + 1)) // hori |
666 | 0 | { |
667 | 0 | for (int s0 = 0, iDim = 0; iDim < nDim; iDim++, s0 += maxShift) |
668 | 0 | { |
669 | 0 | unsigned int c = ((unsigned int)data[m0 + iDim]) ^ ((unsigned int)data[m0 + iDim + nDim]); |
670 | 0 | AddUIntToCounts(&cntDiffVec[s0], c, maxShift); |
671 | 0 | } |
672 | 0 | cnt++; |
673 | 0 | } |
674 | 0 | if (i < hd.nRows - 1 && m_bitMask.IsValid(k + hd.nCols)) // vert |
675 | 0 | { |
676 | 0 | for (int s0 = 0, iDim = 0; iDim < nDim; iDim++, s0 += maxShift) |
677 | 0 | { |
678 | 0 | unsigned int c = ((unsigned int)data[m0 + iDim]) ^ ((unsigned int)data[m0 + iDim + nDim * hd.nCols]); |
679 | 0 | AddUIntToCounts(&cntDiffVec[s0], c, maxShift); |
680 | 0 | } |
681 | 0 | cnt++; |
682 | 0 | } |
683 | 0 | } |
684 | 0 | } |
685 | 0 | else if (hd.dt == DT_Char || hd.dt == DT_Short || hd.dt == DT_Int) // signed int |
686 | 0 | { |
687 | 0 | for (int k = 0, m0 = 0, i = 0; i < hd.nRows; i++) |
688 | 0 | for (int j = 0; j < hd.nCols; j++, k++, m0 += nDim) |
689 | 0 | if (m_bitMask.IsValid(k)) |
690 | 0 | { |
691 | 0 | if (j < hd.nCols - 1 && m_bitMask.IsValid(k + 1)) // hori |
692 | 0 | { |
693 | 0 | for (int s0 = 0, iDim = 0; iDim < nDim; iDim++, s0 += maxShift) |
694 | 0 | { |
695 | 0 | int c = ((int)data[m0 + iDim]) ^ ((int)data[m0 + iDim + nDim]); |
696 | 0 | AddIntToCounts(&cntDiffVec[s0], c, maxShift); |
697 | 0 | } |
698 | 0 | cnt++; |
699 | 0 | } |
700 | 0 | if (i < hd.nRows - 1 && m_bitMask.IsValid(k + hd.nCols)) // vert |
701 | 0 | { |
702 | 0 | for (int s0 = 0, iDim = 0; iDim < nDim; iDim++, s0 += maxShift) |
703 | 0 | { |
704 | 0 | int c = ((int)data[m0 + iDim]) ^ ((int)data[m0 + iDim + nDim * hd.nCols]); |
705 | 0 | AddIntToCounts(&cntDiffVec[s0], c, maxShift); |
706 | 0 | } |
707 | 0 | cnt++; |
708 | 0 | } |
709 | 0 | } |
710 | 0 | } |
711 | 0 | else |
712 | 0 | return false; // unsupported data type |
713 | 0 | } |
714 | | |
715 | 0 | if (cnt < minCnt) // not enough data for good stats |
716 | 0 | return false; |
717 | | |
718 | 0 | int nCutFound = 0, lastPlaneKept = 0; |
719 | 0 | const bool printAll = false; |
720 | |
|
721 | 0 | for (int s = maxShift - 1; s >= 0; s--) |
722 | 0 | { |
723 | 0 | if (printAll) printf("bit plane %2d: ", s); |
724 | 0 | bool bCrit = true; |
725 | |
|
726 | 0 | for (int iDim = 0; iDim < nDim; iDim++) |
727 | 0 | { |
728 | 0 | double x = cntDiffVec[iDim * maxShift + s]; |
729 | 0 | double n = cnt; |
730 | 0 | double m = x / n; |
731 | | //double stdDev = sqrt(x * x / n - m * m) / n; |
732 | | |
733 | | //printf(" %.4f +- %.4f ", (float)(2 * m), (float)(2 * stdDev)); |
734 | 0 | if (printAll) printf(" %.4f ", (float)(2 * m)); |
735 | |
|
736 | 0 | if (fabs(1 - 2 * m) >= eps) |
737 | 0 | bCrit = false; |
738 | 0 | } |
739 | 0 | if (printAll) printf("\n"); |
740 | |
|
741 | 0 | if (bCrit && nCutFound < 2) |
742 | 0 | { |
743 | 0 | if (nCutFound == 0) |
744 | 0 | lastPlaneKept = s; |
745 | |
|
746 | 0 | if (nCutFound == 1 && s < lastPlaneKept - 1) |
747 | 0 | { |
748 | 0 | lastPlaneKept = s; |
749 | 0 | nCutFound = 0; |
750 | 0 | if (printAll) printf(" reset "); |
751 | 0 | } |
752 | |
|
753 | 0 | nCutFound++; |
754 | 0 | if (printAll && nCutFound == 1) printf("\n"); |
755 | 0 | } |
756 | 0 | } |
757 | |
|
758 | 0 | lastPlaneKept = std::max(0, lastPlaneKept); |
759 | 0 | if (printAll) printf("%d \n", lastPlaneKept); |
760 | |
|
761 | 0 | newMaxZError = (1 << lastPlaneKept) >> 1; // turn lastPlaneKept into new maxZError |
762 | |
|
763 | 0 | return true; |
764 | 0 | } Unexecuted instantiation: bool GDAL_LercNS::Lerc2::TryBitPlaneCompression<signed char>(signed char const*, double, double&) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::TryBitPlaneCompression<unsigned char>(unsigned char const*, double, double&) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::TryBitPlaneCompression<short>(short const*, double, double&) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::TryBitPlaneCompression<unsigned short>(unsigned short const*, double, double&) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::TryBitPlaneCompression<int>(int const*, double, double&) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::TryBitPlaneCompression<unsigned int>(unsigned int const*, double, double&) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::TryBitPlaneCompression<float>(float const*, double, double&) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::TryBitPlaneCompression<double>(double const*, double, double&) const |
765 | | |
766 | | // -------------------------------------------------------------------------- ; |
767 | | |
768 | | template<class T> |
769 | | bool Lerc2::WriteDataOneSweep(const T* data, Byte** ppByte) const |
770 | 0 | { |
771 | 0 | if (!data || !ppByte) |
772 | 0 | return false; |
773 | | |
774 | 0 | Byte* ptr = (*ppByte); |
775 | 0 | const HeaderInfo& hd = m_headerInfo; |
776 | 0 | int nDim = hd.nDim; |
777 | 0 | int len = nDim * sizeof(T); |
778 | |
|
779 | 0 | for (int k = 0, m0 = 0, i = 0; i < hd.nRows; i++) |
780 | 0 | for (int j = 0; j < hd.nCols; j++, k++, m0 += nDim) |
781 | 0 | if (m_bitMask.IsValid(k)) |
782 | 0 | { |
783 | 0 | memcpy(ptr, &data[m0], len); |
784 | 0 | ptr += len; |
785 | 0 | } |
786 | |
|
787 | 0 | (*ppByte) = ptr; |
788 | 0 | return true; |
789 | 0 | } Unexecuted instantiation: bool GDAL_LercNS::Lerc2::WriteDataOneSweep<signed char>(signed char const*, unsigned char**) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::WriteDataOneSweep<unsigned char>(unsigned char const*, unsigned char**) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::WriteDataOneSweep<short>(short const*, unsigned char**) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::WriteDataOneSweep<unsigned short>(unsigned short const*, unsigned char**) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::WriteDataOneSweep<int>(int const*, unsigned char**) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::WriteDataOneSweep<unsigned int>(unsigned int const*, unsigned char**) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::WriteDataOneSweep<float>(float const*, unsigned char**) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::WriteDataOneSweep<double>(double const*, unsigned char**) const |
790 | | |
791 | | // -------------------------------------------------------------------------- ; |
792 | | |
793 | | template<class T> |
794 | | bool Lerc2::ReadDataOneSweep(const Byte** ppByte, size_t& nBytesRemaining, T* data) const |
795 | 5.49k | { |
796 | 5.49k | if (!data || !ppByte || !(*ppByte)) |
797 | 0 | return false; |
798 | | |
799 | 5.49k | const Byte* ptr = (*ppByte); |
800 | 5.49k | const HeaderInfo& hd = m_headerInfo; |
801 | 5.49k | int nDim = hd.nDim; |
802 | 5.49k | int len = nDim * sizeof(T); |
803 | | |
804 | 5.49k | size_t nValidPix = (size_t)m_bitMask.CountValidBits(); |
805 | | |
806 | 5.49k | if (nBytesRemaining < nValidPix * len) |
807 | 3.14k | return false; |
808 | | |
809 | 2.95M | for (int k = 0, m0 = 0, i = 0; i < hd.nRows; i++) |
810 | 27.2M | for (int j = 0; j < hd.nCols; j++, k++, m0 += nDim) |
811 | 24.2M | if (m_bitMask.IsValid(k)) |
812 | 415k | { |
813 | 415k | memcpy(&data[m0], ptr, len); |
814 | 415k | ptr += len; |
815 | 415k | } |
816 | | |
817 | 2.34k | (*ppByte) = ptr; |
818 | 2.34k | nBytesRemaining -= nValidPix * len; |
819 | | |
820 | 2.34k | return true; |
821 | 5.49k | } bool GDAL_LercNS::Lerc2::ReadDataOneSweep<signed char>(unsigned char const**, unsigned long&, signed char*) const Line | Count | Source | 795 | 594 | { | 796 | 594 | if (!data || !ppByte || !(*ppByte)) | 797 | 0 | return false; | 798 | | | 799 | 594 | const Byte* ptr = (*ppByte); | 800 | 594 | const HeaderInfo& hd = m_headerInfo; | 801 | 594 | int nDim = hd.nDim; | 802 | 594 | int len = nDim * sizeof(T); | 803 | | | 804 | 594 | size_t nValidPix = (size_t)m_bitMask.CountValidBits(); | 805 | | | 806 | 594 | if (nBytesRemaining < nValidPix * len) | 807 | 42 | return false; | 808 | | | 809 | 2.05k | for (int k = 0, m0 = 0, i = 0; i < hd.nRows; i++) | 810 | 83.2k | for (int j = 0; j < hd.nCols; j++, k++, m0 += nDim) | 811 | 81.7k | if (m_bitMask.IsValid(k)) | 812 | 17.2k | { | 813 | 17.2k | memcpy(&data[m0], ptr, len); | 814 | 17.2k | ptr += len; | 815 | 17.2k | } | 816 | | | 817 | 552 | (*ppByte) = ptr; | 818 | 552 | nBytesRemaining -= nValidPix * len; | 819 | | | 820 | 552 | return true; | 821 | 594 | } |
bool GDAL_LercNS::Lerc2::ReadDataOneSweep<unsigned char>(unsigned char const**, unsigned long&, unsigned char*) const Line | Count | Source | 795 | 3.52k | { | 796 | 3.52k | if (!data || !ppByte || !(*ppByte)) | 797 | 0 | return false; | 798 | | | 799 | 3.52k | const Byte* ptr = (*ppByte); | 800 | 3.52k | const HeaderInfo& hd = m_headerInfo; | 801 | 3.52k | int nDim = hd.nDim; | 802 | 3.52k | int len = nDim * sizeof(T); | 803 | | | 804 | 3.52k | size_t nValidPix = (size_t)m_bitMask.CountValidBits(); | 805 | | | 806 | 3.52k | if (nBytesRemaining < nValidPix * len) | 807 | 2.03k | return false; | 808 | | | 809 | 1.57M | for (int k = 0, m0 = 0, i = 0; i < hd.nRows; i++) | 810 | 20.1M | for (int j = 0; j < hd.nCols; j++, k++, m0 += nDim) | 811 | 18.5M | if (m_bitMask.IsValid(k)) | 812 | 107k | { | 813 | 107k | memcpy(&data[m0], ptr, len); | 814 | 107k | ptr += len; | 815 | 107k | } | 816 | | | 817 | 1.49k | (*ppByte) = ptr; | 818 | 1.49k | nBytesRemaining -= nValidPix * len; | 819 | | | 820 | 1.49k | return true; | 821 | 3.52k | } |
bool GDAL_LercNS::Lerc2::ReadDataOneSweep<short>(unsigned char const**, unsigned long&, short*) const Line | Count | Source | 795 | 101 | { | 796 | 101 | if (!data || !ppByte || !(*ppByte)) | 797 | 0 | return false; | 798 | | | 799 | 101 | const Byte* ptr = (*ppByte); | 800 | 101 | const HeaderInfo& hd = m_headerInfo; | 801 | 101 | int nDim = hd.nDim; | 802 | 101 | int len = nDim * sizeof(T); | 803 | | | 804 | 101 | size_t nValidPix = (size_t)m_bitMask.CountValidBits(); | 805 | | | 806 | 101 | if (nBytesRemaining < nValidPix * len) | 807 | 72 | return false; | 808 | | | 809 | 9.82k | for (int k = 0, m0 = 0, i = 0; i < hd.nRows; i++) | 810 | 32.6k | for (int j = 0; j < hd.nCols; j++, k++, m0 += nDim) | 811 | 22.8k | if (m_bitMask.IsValid(k)) | 812 | 8.24k | { | 813 | 8.24k | memcpy(&data[m0], ptr, len); | 814 | 8.24k | ptr += len; | 815 | 8.24k | } | 816 | | | 817 | 29 | (*ppByte) = ptr; | 818 | 29 | nBytesRemaining -= nValidPix * len; | 819 | | | 820 | 29 | return true; | 821 | 101 | } |
bool GDAL_LercNS::Lerc2::ReadDataOneSweep<unsigned short>(unsigned char const**, unsigned long&, unsigned short*) const Line | Count | Source | 795 | 427 | { | 796 | 427 | if (!data || !ppByte || !(*ppByte)) | 797 | 0 | return false; | 798 | | | 799 | 427 | const Byte* ptr = (*ppByte); | 800 | 427 | const HeaderInfo& hd = m_headerInfo; | 801 | 427 | int nDim = hd.nDim; | 802 | 427 | int len = nDim * sizeof(T); | 803 | | | 804 | 427 | size_t nValidPix = (size_t)m_bitMask.CountValidBits(); | 805 | | | 806 | 427 | if (nBytesRemaining < nValidPix * len) | 807 | 360 | return false; | 808 | | | 809 | 1.37k | for (int k = 0, m0 = 0, i = 0; i < hd.nRows; i++) | 810 | 1.46M | for (int j = 0; j < hd.nCols; j++, k++, m0 += nDim) | 811 | 1.46M | if (m_bitMask.IsValid(k)) | 812 | 227k | { | 813 | 227k | memcpy(&data[m0], ptr, len); | 814 | 227k | ptr += len; | 815 | 227k | } | 816 | | | 817 | 67 | (*ppByte) = ptr; | 818 | 67 | nBytesRemaining -= nValidPix * len; | 819 | | | 820 | 67 | return true; | 821 | 427 | } |
bool GDAL_LercNS::Lerc2::ReadDataOneSweep<int>(unsigned char const**, unsigned long&, int*) const Line | Count | Source | 795 | 110 | { | 796 | 110 | if (!data || !ppByte || !(*ppByte)) | 797 | 0 | return false; | 798 | | | 799 | 110 | const Byte* ptr = (*ppByte); | 800 | 110 | const HeaderInfo& hd = m_headerInfo; | 801 | 110 | int nDim = hd.nDim; | 802 | 110 | int len = nDim * sizeof(T); | 803 | | | 804 | 110 | size_t nValidPix = (size_t)m_bitMask.CountValidBits(); | 805 | | | 806 | 110 | if (nBytesRemaining < nValidPix * len) | 807 | 88 | return false; | 808 | | | 809 | 1.16k | for (int k = 0, m0 = 0, i = 0; i < hd.nRows; i++) | 810 | 6.40k | for (int j = 0; j < hd.nCols; j++, k++, m0 += nDim) | 811 | 5.26k | if (m_bitMask.IsValid(k)) | 812 | 1.86k | { | 813 | 1.86k | memcpy(&data[m0], ptr, len); | 814 | 1.86k | ptr += len; | 815 | 1.86k | } | 816 | | | 817 | 22 | (*ppByte) = ptr; | 818 | 22 | nBytesRemaining -= nValidPix * len; | 819 | | | 820 | 22 | return true; | 821 | 110 | } |
bool GDAL_LercNS::Lerc2::ReadDataOneSweep<unsigned int>(unsigned char const**, unsigned long&, unsigned int*) const Line | Count | Source | 795 | 570 | { | 796 | 570 | if (!data || !ppByte || !(*ppByte)) | 797 | 0 | return false; | 798 | | | 799 | 570 | const Byte* ptr = (*ppByte); | 800 | 570 | const HeaderInfo& hd = m_headerInfo; | 801 | 570 | int nDim = hd.nDim; | 802 | 570 | int len = nDim * sizeof(T); | 803 | | | 804 | 570 | size_t nValidPix = (size_t)m_bitMask.CountValidBits(); | 805 | | | 806 | 570 | if (nBytesRemaining < nValidPix * len) | 807 | 446 | return false; | 808 | | | 809 | 1.31M | for (int k = 0, m0 = 0, i = 0; i < hd.nRows; i++) | 810 | 5.26M | for (int j = 0; j < hd.nCols; j++, k++, m0 += nDim) | 811 | 3.94M | if (m_bitMask.IsValid(k)) | 812 | 4.22k | { | 813 | 4.22k | memcpy(&data[m0], ptr, len); | 814 | 4.22k | ptr += len; | 815 | 4.22k | } | 816 | | | 817 | 124 | (*ppByte) = ptr; | 818 | 124 | nBytesRemaining -= nValidPix * len; | 819 | | | 820 | 124 | return true; | 821 | 570 | } |
bool GDAL_LercNS::Lerc2::ReadDataOneSweep<float>(unsigned char const**, unsigned long&, float*) const Line | Count | Source | 795 | 74 | { | 796 | 74 | if (!data || !ppByte || !(*ppByte)) | 797 | 0 | return false; | 798 | | | 799 | 74 | const Byte* ptr = (*ppByte); | 800 | 74 | const HeaderInfo& hd = m_headerInfo; | 801 | 74 | int nDim = hd.nDim; | 802 | 74 | int len = nDim * sizeof(T); | 803 | | | 804 | 74 | size_t nValidPix = (size_t)m_bitMask.CountValidBits(); | 805 | | | 806 | 74 | if (nBytesRemaining < nValidPix * len) | 807 | 46 | return false; | 808 | | | 809 | 47.4k | for (int k = 0, m0 = 0, i = 0; i < hd.nRows; i++) | 810 | 146k | for (int j = 0; j < hd.nCols; j++, k++, m0 += nDim) | 811 | 99.1k | if (m_bitMask.IsValid(k)) | 812 | 33.2k | { | 813 | 33.2k | memcpy(&data[m0], ptr, len); | 814 | 33.2k | ptr += len; | 815 | 33.2k | } | 816 | | | 817 | 28 | (*ppByte) = ptr; | 818 | 28 | nBytesRemaining -= nValidPix * len; | 819 | | | 820 | 28 | return true; | 821 | 74 | } |
bool GDAL_LercNS::Lerc2::ReadDataOneSweep<double>(unsigned char const**, unsigned long&, double*) const Line | Count | Source | 795 | 86 | { | 796 | 86 | if (!data || !ppByte || !(*ppByte)) | 797 | 0 | return false; | 798 | | | 799 | 86 | const Byte* ptr = (*ppByte); | 800 | 86 | const HeaderInfo& hd = m_headerInfo; | 801 | 86 | int nDim = hd.nDim; | 802 | 86 | int len = nDim * sizeof(T); | 803 | | | 804 | 86 | size_t nValidPix = (size_t)m_bitMask.CountValidBits(); | 805 | | | 806 | 86 | if (nBytesRemaining < nValidPix * len) | 807 | 61 | return false; | 808 | | | 809 | 1.81k | for (int k = 0, m0 = 0, i = 0; i < hd.nRows; i++) | 810 | 45.4k | for (int j = 0; j < hd.nCols; j++, k++, m0 += nDim) | 811 | 43.7k | if (m_bitMask.IsValid(k)) | 812 | 15.3k | { | 813 | 15.3k | memcpy(&data[m0], ptr, len); | 814 | 15.3k | ptr += len; | 815 | 15.3k | } | 816 | | | 817 | 25 | (*ppByte) = ptr; | 818 | 25 | nBytesRemaining -= nValidPix * len; | 819 | | | 820 | 25 | return true; | 821 | 86 | } |
|
822 | | |
823 | | // -------------------------------------------------------------------------- ; |
824 | | |
825 | | template<class T> |
826 | | bool Lerc2::WriteTiles(const T* data, Byte** ppByte, int& numBytes, std::vector<double>& zMinVec, std::vector<double>& zMaxVec) const |
827 | 0 | { |
828 | 0 | if (!data || !ppByte) |
829 | 0 | return false; |
830 | | |
831 | 0 | numBytes = 0; |
832 | 0 | int numBytesLerc = 0; |
833 | |
|
834 | 0 | std::vector<unsigned int> quantVec; |
835 | 0 | std::vector<std::pair<unsigned int, unsigned int> > sortedQuantVec; |
836 | |
|
837 | 0 | const HeaderInfo& hd = m_headerInfo; |
838 | 0 | int mbSize = hd.microBlockSize; |
839 | 0 | int nDim = hd.nDim; |
840 | |
|
841 | 0 | std::vector<T> dataVec(mbSize * mbSize, 0); |
842 | 0 | T* dataBuf = &dataVec[0]; |
843 | |
|
844 | 0 | zMinVec.assign(nDim, DBL_MAX); |
845 | 0 | zMaxVec.assign(nDim, -DBL_MAX); |
846 | |
|
847 | 0 | int numTilesVert = (hd.nRows + mbSize - 1) / mbSize; |
848 | 0 | int numTilesHori = (hd.nCols + mbSize - 1) / mbSize; |
849 | |
|
850 | 0 | for (int iTile = 0; iTile < numTilesVert; iTile++) |
851 | 0 | { |
852 | 0 | int tileH = mbSize; |
853 | 0 | int i0 = iTile * tileH; |
854 | 0 | if (iTile == numTilesVert - 1) |
855 | 0 | tileH = hd.nRows - i0; |
856 | |
|
857 | 0 | for (int jTile = 0; jTile < numTilesHori; jTile++) |
858 | 0 | { |
859 | 0 | int tileW = mbSize; |
860 | 0 | int j0 = jTile * tileW; |
861 | 0 | if (jTile == numTilesHori - 1) |
862 | 0 | tileW = hd.nCols - j0; |
863 | |
|
864 | 0 | for (int iDim = 0; iDim < nDim; iDim++) |
865 | 0 | { |
866 | 0 | T zMin = 0, zMax = 0; |
867 | 0 | int numValidPixel = 0; |
868 | 0 | bool tryLut = false; |
869 | |
|
870 | 0 | if (!GetValidDataAndStats(data, i0, i0 + tileH, j0, j0 + tileW, iDim, dataBuf, zMin, zMax, numValidPixel, tryLut)) |
871 | 0 | return false; |
872 | | |
873 | 0 | if (numValidPixel > 0) |
874 | 0 | { |
875 | 0 | zMinVec[iDim] = (std::min)(zMinVec[iDim], (double)zMin); |
876 | 0 | zMaxVec[iDim] = (std::max)(zMaxVec[iDim], (double)zMax); |
877 | 0 | } |
878 | | |
879 | | //tryLut = false; |
880 | | |
881 | | // if needed, quantize the data here once |
882 | 0 | if ((*ppByte || tryLut) && NeedToQuantize(numValidPixel, zMin, zMax)) |
883 | 0 | { |
884 | 0 | if (!Quantize(dataBuf, numValidPixel, zMin, quantVec)) |
885 | 0 | return false; |
886 | | |
887 | 0 | if (tryLut) |
888 | 0 | SortQuantArray(quantVec, sortedQuantVec); |
889 | 0 | } |
890 | | |
891 | 0 | BlockEncodeMode blockEncodeMode; |
892 | 0 | int numBytesNeeded = NumBytesTile(numValidPixel, zMin, zMax, tryLut, blockEncodeMode, sortedQuantVec); |
893 | 0 | numBytesLerc += numBytesNeeded; |
894 | |
|
895 | 0 | if (*ppByte) |
896 | 0 | { |
897 | 0 | int numBytesWritten = 0; |
898 | |
|
899 | 0 | if (!WriteTile(dataBuf, numValidPixel, ppByte, numBytesWritten, j0, zMin, zMax, quantVec, blockEncodeMode, sortedQuantVec)) |
900 | 0 | return false; |
901 | | |
902 | 0 | if (numBytesWritten != numBytesNeeded) |
903 | 0 | return false; |
904 | 0 | } |
905 | 0 | } |
906 | 0 | } |
907 | 0 | } |
908 | | |
909 | 0 | numBytes += numBytesLerc; |
910 | 0 | return true; |
911 | 0 | } Unexecuted instantiation: bool GDAL_LercNS::Lerc2::WriteTiles<signed char>(signed char const*, unsigned char**, int&, std::__1::vector<double, std::__1::allocator<double> >&, std::__1::vector<double, std::__1::allocator<double> >&) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::WriteTiles<unsigned char>(unsigned char const*, unsigned char**, int&, std::__1::vector<double, std::__1::allocator<double> >&, std::__1::vector<double, std::__1::allocator<double> >&) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::WriteTiles<short>(short const*, unsigned char**, int&, std::__1::vector<double, std::__1::allocator<double> >&, std::__1::vector<double, std::__1::allocator<double> >&) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::WriteTiles<unsigned short>(unsigned short const*, unsigned char**, int&, std::__1::vector<double, std::__1::allocator<double> >&, std::__1::vector<double, std::__1::allocator<double> >&) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::WriteTiles<int>(int const*, unsigned char**, int&, std::__1::vector<double, std::__1::allocator<double> >&, std::__1::vector<double, std::__1::allocator<double> >&) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::WriteTiles<unsigned int>(unsigned int const*, unsigned char**, int&, std::__1::vector<double, std::__1::allocator<double> >&, std::__1::vector<double, std::__1::allocator<double> >&) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::WriteTiles<float>(float const*, unsigned char**, int&, std::__1::vector<double, std::__1::allocator<double> >&, std::__1::vector<double, std::__1::allocator<double> >&) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::WriteTiles<double>(double const*, unsigned char**, int&, std::__1::vector<double, std::__1::allocator<double> >&, std::__1::vector<double, std::__1::allocator<double> >&) const |
912 | | |
913 | | // -------------------------------------------------------------------------- ; |
914 | | |
915 | | template<class T> |
916 | | bool Lerc2::ReadTiles(const Byte** ppByte, size_t& nBytesRemaining, T* data) const |
917 | 13.3k | { |
918 | 13.3k | if (!data || !ppByte || !(*ppByte)) |
919 | 0 | return false; |
920 | | |
921 | 13.3k | std::vector<unsigned int> bufferVec; |
922 | | |
923 | 13.3k | const HeaderInfo& hd = m_headerInfo; |
924 | 13.3k | int mbSize = hd.microBlockSize; |
925 | 13.3k | int nDim = hd.nDim; |
926 | | |
927 | 13.3k | if (mbSize > 32) // fail gracefully in case of corrupted blob for old version <= 2 which had no checksum |
928 | 522 | return false; |
929 | | |
930 | 12.8k | if( mbSize <= 0 || hd.nRows < 0 || hd.nCols < 0 || |
931 | 12.8k | hd.nRows > std::numeric_limits<int>::max() - (mbSize - 1) || |
932 | 12.8k | hd.nCols > std::numeric_limits<int>::max() - (mbSize - 1) ) |
933 | 0 | { |
934 | 0 | return false; |
935 | 0 | } |
936 | 12.8k | int numTilesVert = (hd.nRows + mbSize - 1) / mbSize; |
937 | 12.8k | int numTilesHori = (hd.nCols + mbSize - 1) / mbSize; |
938 | | |
939 | 206k | for (int iTile = 0; iTile < numTilesVert; iTile++) |
940 | 206k | { |
941 | 206k | int tileH = mbSize; |
942 | 206k | int i0 = iTile * tileH; |
943 | 206k | if (iTile == numTilesVert - 1) |
944 | 2.95k | tileH = hd.nRows - i0; |
945 | | |
946 | 538k | for (int jTile = 0; jTile < numTilesHori; jTile++) |
947 | 344k | { |
948 | 344k | int tileW = mbSize; |
949 | 344k | int j0 = jTile * tileW; |
950 | 344k | if (jTile == numTilesHori - 1) |
951 | 198k | tileW = hd.nCols - j0; |
952 | | |
953 | 752k | for (int iDim = 0; iDim < nDim; iDim++) |
954 | 419k | { |
955 | 419k | if (!ReadTile(ppByte, nBytesRemaining, data, i0, i0 + tileH, j0, j0 + tileW, iDim, bufferVec)) |
956 | 12.1k | return false; |
957 | 419k | } |
958 | 344k | } |
959 | 206k | } |
960 | | |
961 | 643 | return true; |
962 | 12.8k | } bool GDAL_LercNS::Lerc2::ReadTiles<signed char>(unsigned char const**, unsigned long&, signed char*) const Line | Count | Source | 917 | 1.19k | { | 918 | 1.19k | if (!data || !ppByte || !(*ppByte)) | 919 | 0 | return false; | 920 | | | 921 | 1.19k | std::vector<unsigned int> bufferVec; | 922 | | | 923 | 1.19k | const HeaderInfo& hd = m_headerInfo; | 924 | 1.19k | int mbSize = hd.microBlockSize; | 925 | 1.19k | int nDim = hd.nDim; | 926 | | | 927 | 1.19k | if (mbSize > 32) // fail gracefully in case of corrupted blob for old version <= 2 which had no checksum | 928 | 55 | return false; | 929 | | | 930 | 1.14k | if( mbSize <= 0 || hd.nRows < 0 || hd.nCols < 0 || | 931 | 1.14k | hd.nRows > std::numeric_limits<int>::max() - (mbSize - 1) || | 932 | 1.14k | hd.nCols > std::numeric_limits<int>::max() - (mbSize - 1) ) | 933 | 0 | { | 934 | 0 | return false; | 935 | 0 | } | 936 | 1.14k | int numTilesVert = (hd.nRows + mbSize - 1) / mbSize; | 937 | 1.14k | int numTilesHori = (hd.nCols + mbSize - 1) / mbSize; | 938 | | | 939 | 1.24k | for (int iTile = 0; iTile < numTilesVert; iTile++) | 940 | 1.22k | { | 941 | 1.22k | int tileH = mbSize; | 942 | 1.22k | int i0 = iTile * tileH; | 943 | 1.22k | if (iTile == numTilesVert - 1) | 944 | 286 | tileH = hd.nRows - i0; | 945 | | | 946 | 2.11k | for (int jTile = 0; jTile < numTilesHori; jTile++) | 947 | 2.00k | { | 948 | 2.00k | int tileW = mbSize; | 949 | 2.00k | int j0 = jTile * tileW; | 950 | 2.00k | if (jTile == numTilesHori - 1) | 951 | 267 | tileW = hd.nCols - j0; | 952 | | | 953 | 16.1k | for (int iDim = 0; iDim < nDim; iDim++) | 954 | 15.2k | { | 955 | 15.2k | if (!ReadTile(ppByte, nBytesRemaining, data, i0, i0 + tileH, j0, j0 + tileW, iDim, bufferVec)) | 956 | 1.11k | return false; | 957 | 15.2k | } | 958 | 2.00k | } | 959 | 1.22k | } | 960 | | | 961 | 23 | return true; | 962 | 1.14k | } |
bool GDAL_LercNS::Lerc2::ReadTiles<unsigned char>(unsigned char const**, unsigned long&, unsigned char*) const Line | Count | Source | 917 | 3.21k | { | 918 | 3.21k | if (!data || !ppByte || !(*ppByte)) | 919 | 0 | return false; | 920 | | | 921 | 3.21k | std::vector<unsigned int> bufferVec; | 922 | | | 923 | 3.21k | const HeaderInfo& hd = m_headerInfo; | 924 | 3.21k | int mbSize = hd.microBlockSize; | 925 | 3.21k | int nDim = hd.nDim; | 926 | | | 927 | 3.21k | if (mbSize > 32) // fail gracefully in case of corrupted blob for old version <= 2 which had no checksum | 928 | 166 | return false; | 929 | | | 930 | 3.04k | if( mbSize <= 0 || hd.nRows < 0 || hd.nCols < 0 || | 931 | 3.04k | hd.nRows > std::numeric_limits<int>::max() - (mbSize - 1) || | 932 | 3.04k | hd.nCols > std::numeric_limits<int>::max() - (mbSize - 1) ) | 933 | 0 | { | 934 | 0 | return false; | 935 | 0 | } | 936 | 3.04k | int numTilesVert = (hd.nRows + mbSize - 1) / mbSize; | 937 | 3.04k | int numTilesHori = (hd.nCols + mbSize - 1) / mbSize; | 938 | | | 939 | 28.0k | for (int iTile = 0; iTile < numTilesVert; iTile++) | 940 | 27.5k | { | 941 | 27.5k | int tileH = mbSize; | 942 | 27.5k | int i0 = iTile * tileH; | 943 | 27.5k | if (iTile == numTilesVert - 1) | 944 | 909 | tileH = hd.nRows - i0; | 945 | | | 946 | 59.8k | for (int jTile = 0; jTile < numTilesHori; jTile++) | 947 | 34.8k | { | 948 | 34.8k | int tileW = mbSize; | 949 | 34.8k | int j0 = jTile * tileW; | 950 | 34.8k | if (jTile == numTilesHori - 1) | 951 | 25.9k | tileW = hd.nCols - j0; | 952 | | | 953 | 87.0k | for (int iDim = 0; iDim < nDim; iDim++) | 954 | 54.7k | { | 955 | 54.7k | if (!ReadTile(ppByte, nBytesRemaining, data, i0, i0 + tileH, j0, j0 + tileW, iDim, bufferVec)) | 956 | 2.55k | return false; | 957 | 54.7k | } | 958 | 34.8k | } | 959 | 27.5k | } | 960 | | | 961 | 488 | return true; | 962 | 3.04k | } |
bool GDAL_LercNS::Lerc2::ReadTiles<short>(unsigned char const**, unsigned long&, short*) const Line | Count | Source | 917 | 1.80k | { | 918 | 1.80k | if (!data || !ppByte || !(*ppByte)) | 919 | 0 | return false; | 920 | | | 921 | 1.80k | std::vector<unsigned int> bufferVec; | 922 | | | 923 | 1.80k | const HeaderInfo& hd = m_headerInfo; | 924 | 1.80k | int mbSize = hd.microBlockSize; | 925 | 1.80k | int nDim = hd.nDim; | 926 | | | 927 | 1.80k | if (mbSize > 32) // fail gracefully in case of corrupted blob for old version <= 2 which had no checksum | 928 | 60 | return false; | 929 | | | 930 | 1.74k | if( mbSize <= 0 || hd.nRows < 0 || hd.nCols < 0 || | 931 | 1.74k | hd.nRows > std::numeric_limits<int>::max() - (mbSize - 1) || | 932 | 1.74k | hd.nCols > std::numeric_limits<int>::max() - (mbSize - 1) ) | 933 | 0 | { | 934 | 0 | return false; | 935 | 0 | } | 936 | 1.74k | int numTilesVert = (hd.nRows + mbSize - 1) / mbSize; | 937 | 1.74k | int numTilesHori = (hd.nCols + mbSize - 1) / mbSize; | 938 | | | 939 | 45.8k | for (int iTile = 0; iTile < numTilesVert; iTile++) | 940 | 45.7k | { | 941 | 45.7k | int tileH = mbSize; | 942 | 45.7k | int i0 = iTile * tileH; | 943 | 45.7k | if (iTile == numTilesVert - 1) | 944 | 212 | tileH = hd.nRows - i0; | 945 | | | 946 | 95.9k | for (int jTile = 0; jTile < numTilesHori; jTile++) | 947 | 51.8k | { | 948 | 51.8k | int tileW = mbSize; | 949 | 51.8k | int j0 = jTile * tileW; | 950 | 51.8k | if (jTile == numTilesHori - 1) | 951 | 44.8k | tileW = hd.nCols - j0; | 952 | | | 953 | 112k | for (int iDim = 0; iDim < nDim; iDim++) | 954 | 62.1k | { | 955 | 62.1k | if (!ReadTile(ppByte, nBytesRemaining, data, i0, i0 + tileH, j0, j0 + tileW, iDim, bufferVec)) | 956 | 1.69k | return false; | 957 | 62.1k | } | 958 | 51.8k | } | 959 | 45.7k | } | 960 | | | 961 | 56 | return true; | 962 | 1.74k | } |
bool GDAL_LercNS::Lerc2::ReadTiles<unsigned short>(unsigned char const**, unsigned long&, unsigned short*) const Line | Count | Source | 917 | 2.73k | { | 918 | 2.73k | if (!data || !ppByte || !(*ppByte)) | 919 | 0 | return false; | 920 | | | 921 | 2.73k | std::vector<unsigned int> bufferVec; | 922 | | | 923 | 2.73k | const HeaderInfo& hd = m_headerInfo; | 924 | 2.73k | int mbSize = hd.microBlockSize; | 925 | 2.73k | int nDim = hd.nDim; | 926 | | | 927 | 2.73k | if (mbSize > 32) // fail gracefully in case of corrupted blob for old version <= 2 which had no checksum | 928 | 77 | return false; | 929 | | | 930 | 2.65k | if( mbSize <= 0 || hd.nRows < 0 || hd.nCols < 0 || | 931 | 2.65k | hd.nRows > std::numeric_limits<int>::max() - (mbSize - 1) || | 932 | 2.65k | hd.nCols > std::numeric_limits<int>::max() - (mbSize - 1) ) | 933 | 0 | { | 934 | 0 | return false; | 935 | 0 | } | 936 | 2.65k | int numTilesVert = (hd.nRows + mbSize - 1) / mbSize; | 937 | 2.65k | int numTilesHori = (hd.nCols + mbSize - 1) / mbSize; | 938 | | | 939 | 3.78k | for (int iTile = 0; iTile < numTilesVert; iTile++) | 940 | 3.73k | { | 941 | 3.73k | int tileH = mbSize; | 942 | 3.73k | int i0 = iTile * tileH; | 943 | 3.73k | if (iTile == numTilesVert - 1) | 944 | 345 | tileH = hd.nRows - i0; | 945 | | | 946 | 5.66k | for (int jTile = 0; jTile < numTilesHori; jTile++) | 947 | 4.53k | { | 948 | 4.53k | int tileW = mbSize; | 949 | 4.53k | int j0 = jTile * tileW; | 950 | 4.53k | if (jTile == numTilesHori - 1) | 951 | 1.79k | tileW = hd.nCols - j0; | 952 | | | 953 | 14.9k | for (int iDim = 0; iDim < nDim; iDim++) | 954 | 13.0k | { | 955 | 13.0k | if (!ReadTile(ppByte, nBytesRemaining, data, i0, i0 + tileH, j0, j0 + tileW, iDim, bufferVec)) | 956 | 2.60k | return false; | 957 | 13.0k | } | 958 | 4.53k | } | 959 | 3.73k | } | 960 | | | 961 | 55 | return true; | 962 | 2.65k | } |
bool GDAL_LercNS::Lerc2::ReadTiles<int>(unsigned char const**, unsigned long&, int*) const Line | Count | Source | 917 | 979 | { | 918 | 979 | if (!data || !ppByte || !(*ppByte)) | 919 | 0 | return false; | 920 | | | 921 | 979 | std::vector<unsigned int> bufferVec; | 922 | | | 923 | 979 | const HeaderInfo& hd = m_headerInfo; | 924 | 979 | int mbSize = hd.microBlockSize; | 925 | 979 | int nDim = hd.nDim; | 926 | | | 927 | 979 | if (mbSize > 32) // fail gracefully in case of corrupted blob for old version <= 2 which had no checksum | 928 | 51 | return false; | 929 | | | 930 | 928 | if( mbSize <= 0 || hd.nRows < 0 || hd.nCols < 0 || | 931 | 928 | hd.nRows > std::numeric_limits<int>::max() - (mbSize - 1) || | 932 | 928 | hd.nCols > std::numeric_limits<int>::max() - (mbSize - 1) ) | 933 | 0 | { | 934 | 0 | return false; | 935 | 0 | } | 936 | 928 | int numTilesVert = (hd.nRows + mbSize - 1) / mbSize; | 937 | 928 | int numTilesHori = (hd.nCols + mbSize - 1) / mbSize; | 938 | | | 939 | 2.26k | for (int iTile = 0; iTile < numTilesVert; iTile++) | 940 | 2.26k | { | 941 | 2.26k | int tileH = mbSize; | 942 | 2.26k | int i0 = iTile * tileH; | 943 | 2.26k | if (iTile == numTilesVert - 1) | 944 | 159 | tileH = hd.nRows - i0; | 945 | | | 946 | 4.44k | for (int jTile = 0; jTile < numTilesHori; jTile++) | 947 | 3.10k | { | 948 | 3.10k | int tileW = mbSize; | 949 | 3.10k | int j0 = jTile * tileW; | 950 | 3.10k | if (jTile == numTilesHori - 1) | 951 | 1.77k | tileW = hd.nCols - j0; | 952 | | | 953 | 9.54k | for (int iDim = 0; iDim < nDim; iDim++) | 954 | 7.36k | { | 955 | 7.36k | if (!ReadTile(ppByte, nBytesRemaining, data, i0, i0 + tileH, j0, j0 + tileW, iDim, bufferVec)) | 956 | 926 | return false; | 957 | 7.36k | } | 958 | 3.10k | } | 959 | 2.26k | } | 960 | | | 961 | 2 | return true; | 962 | 928 | } |
bool GDAL_LercNS::Lerc2::ReadTiles<unsigned int>(unsigned char const**, unsigned long&, unsigned int*) const Line | Count | Source | 917 | 2.24k | { | 918 | 2.24k | if (!data || !ppByte || !(*ppByte)) | 919 | 0 | return false; | 920 | | | 921 | 2.24k | std::vector<unsigned int> bufferVec; | 922 | | | 923 | 2.24k | const HeaderInfo& hd = m_headerInfo; | 924 | 2.24k | int mbSize = hd.microBlockSize; | 925 | 2.24k | int nDim = hd.nDim; | 926 | | | 927 | 2.24k | if (mbSize > 32) // fail gracefully in case of corrupted blob for old version <= 2 which had no checksum | 928 | 56 | return false; | 929 | | | 930 | 2.18k | if( mbSize <= 0 || hd.nRows < 0 || hd.nCols < 0 || | 931 | 2.18k | hd.nRows > std::numeric_limits<int>::max() - (mbSize - 1) || | 932 | 2.18k | hd.nCols > std::numeric_limits<int>::max() - (mbSize - 1) ) | 933 | 0 | { | 934 | 0 | return false; | 935 | 0 | } | 936 | 2.18k | int numTilesVert = (hd.nRows + mbSize - 1) / mbSize; | 937 | 2.18k | int numTilesHori = (hd.nCols + mbSize - 1) / mbSize; | 938 | | | 939 | 122k | for (int iTile = 0; iTile < numTilesVert; iTile++) | 940 | 122k | { | 941 | 122k | int tileH = mbSize; | 942 | 122k | int i0 = iTile * tileH; | 943 | 122k | if (iTile == numTilesVert - 1) | 944 | 625 | tileH = hd.nRows - i0; | 945 | | | 946 | 365k | for (int jTile = 0; jTile < numTilesHori; jTile++) | 947 | 244k | { | 948 | 244k | int tileW = mbSize; | 949 | 244k | int j0 = jTile * tileW; | 950 | 244k | if (jTile == numTilesHori - 1) | 951 | 121k | tileW = hd.nCols - j0; | 952 | | | 953 | 497k | for (int iDim = 0; iDim < nDim; iDim++) | 954 | 255k | { | 955 | 255k | if (!ReadTile(ppByte, nBytesRemaining, data, i0, i0 + tileH, j0, j0 + tileW, iDim, bufferVec)) | 956 | 2.17k | return false; | 957 | 255k | } | 958 | 244k | } | 959 | 122k | } | 960 | | | 961 | 9 | return true; | 962 | 2.18k | } |
bool GDAL_LercNS::Lerc2::ReadTiles<float>(unsigned char const**, unsigned long&, float*) const Line | Count | Source | 917 | 588 | { | 918 | 588 | if (!data || !ppByte || !(*ppByte)) | 919 | 0 | return false; | 920 | | | 921 | 588 | std::vector<unsigned int> bufferVec; | 922 | | | 923 | 588 | const HeaderInfo& hd = m_headerInfo; | 924 | 588 | int mbSize = hd.microBlockSize; | 925 | 588 | int nDim = hd.nDim; | 926 | | | 927 | 588 | if (mbSize > 32) // fail gracefully in case of corrupted blob for old version <= 2 which had no checksum | 928 | 17 | return false; | 929 | | | 930 | 571 | if( mbSize <= 0 || hd.nRows < 0 || hd.nCols < 0 || | 931 | 571 | hd.nRows > std::numeric_limits<int>::max() - (mbSize - 1) || | 932 | 571 | hd.nCols > std::numeric_limits<int>::max() - (mbSize - 1) ) | 933 | 0 | { | 934 | 0 | return false; | 935 | 0 | } | 936 | 571 | int numTilesVert = (hd.nRows + mbSize - 1) / mbSize; | 937 | 571 | int numTilesHori = (hd.nCols + mbSize - 1) / mbSize; | 938 | | | 939 | 1.64k | for (int iTile = 0; iTile < numTilesVert; iTile++) | 940 | 1.63k | { | 941 | 1.63k | int tileH = mbSize; | 942 | 1.63k | int i0 = iTile * tileH; | 943 | 1.63k | if (iTile == numTilesVert - 1) | 944 | 122 | tileH = hd.nRows - i0; | 945 | | | 946 | 3.48k | for (int jTile = 0; jTile < numTilesHori; jTile++) | 947 | 2.41k | { | 948 | 2.41k | int tileW = mbSize; | 949 | 2.41k | int j0 = jTile * tileW; | 950 | 2.41k | if (jTile == numTilesHori - 1) | 951 | 1.37k | tileW = hd.nCols - j0; | 952 | | | 953 | 9.09k | for (int iDim = 0; iDim < nDim; iDim++) | 954 | 7.25k | { | 955 | 7.25k | if (!ReadTile(ppByte, nBytesRemaining, data, i0, i0 + tileH, j0, j0 + tileW, iDim, bufferVec)) | 956 | 568 | return false; | 957 | 7.25k | } | 958 | 2.41k | } | 959 | 1.63k | } | 960 | | | 961 | 3 | return true; | 962 | 571 | } |
bool GDAL_LercNS::Lerc2::ReadTiles<double>(unsigned char const**, unsigned long&, double*) const Line | Count | Source | 917 | 572 | { | 918 | 572 | if (!data || !ppByte || !(*ppByte)) | 919 | 0 | return false; | 920 | | | 921 | 572 | std::vector<unsigned int> bufferVec; | 922 | | | 923 | 572 | const HeaderInfo& hd = m_headerInfo; | 924 | 572 | int mbSize = hd.microBlockSize; | 925 | 572 | int nDim = hd.nDim; | 926 | | | 927 | 572 | if (mbSize > 32) // fail gracefully in case of corrupted blob for old version <= 2 which had no checksum | 928 | 40 | return false; | 929 | | | 930 | 532 | if( mbSize <= 0 || hd.nRows < 0 || hd.nCols < 0 || | 931 | 532 | hd.nRows > std::numeric_limits<int>::max() - (mbSize - 1) || | 932 | 532 | hd.nCols > std::numeric_limits<int>::max() - (mbSize - 1) ) | 933 | 0 | { | 934 | 0 | return false; | 935 | 0 | } | 936 | 532 | int numTilesVert = (hd.nRows + mbSize - 1) / mbSize; | 937 | 532 | int numTilesHori = (hd.nCols + mbSize - 1) / mbSize; | 938 | | | 939 | 1.03k | for (int iTile = 0; iTile < numTilesVert; iTile++) | 940 | 1.02k | { | 941 | 1.02k | int tileH = mbSize; | 942 | 1.02k | int i0 = iTile * tileH; | 943 | 1.02k | if (iTile == numTilesVert - 1) | 944 | 294 | tileH = hd.nRows - i0; | 945 | | | 946 | 1.70k | for (int jTile = 0; jTile < numTilesHori; jTile++) | 947 | 1.20k | { | 948 | 1.20k | int tileW = mbSize; | 949 | 1.20k | int j0 = jTile * tileW; | 950 | 1.20k | if (jTile == numTilesHori - 1) | 951 | 854 | tileW = hd.nCols - j0; | 952 | | | 953 | 5.22k | for (int iDim = 0; iDim < nDim; iDim++) | 954 | 4.54k | { | 955 | 4.54k | if (!ReadTile(ppByte, nBytesRemaining, data, i0, i0 + tileH, j0, j0 + tileW, iDim, bufferVec)) | 956 | 525 | return false; | 957 | 4.54k | } | 958 | 1.20k | } | 959 | 1.02k | } | 960 | | | 961 | 7 | return true; | 962 | 532 | } |
|
963 | | |
964 | | // -------------------------------------------------------------------------- ; |
965 | | |
966 | | template<class T> |
967 | | bool Lerc2::GetValidDataAndStats(const T* data, int i0, int i1, int j0, int j1, int iDim, |
968 | | T* dataBuf, T& zMin, T& zMax, int& numValidPixel, bool& tryLut) const |
969 | 0 | { |
970 | 0 | const HeaderInfo& hd = m_headerInfo; |
971 | |
|
972 | 0 | if (!data || i0 < 0 || j0 < 0 || i1 > hd.nRows || j1 > hd.nCols || iDim < 0 || iDim > hd.nDim || !dataBuf) |
973 | 0 | return false; |
974 | | |
975 | 0 | zMin = 0; |
976 | 0 | zMax = 0; |
977 | 0 | tryLut = false; |
978 | |
|
979 | 0 | T prevVal = 0; |
980 | 0 | int cnt = 0, cntSameVal = 0; |
981 | 0 | int nDim = hd.nDim; |
982 | |
|
983 | 0 | if (hd.numValidPixel == hd.nCols * hd.nRows) // all valid, no mask |
984 | 0 | { |
985 | 0 | for (int i = i0; i < i1; i++) |
986 | 0 | { |
987 | 0 | int k = i * hd.nCols + j0; |
988 | 0 | int m = k * nDim + iDim; |
989 | |
|
990 | 0 | for (int j = j0; j < j1; j++, k++, m += nDim) |
991 | 0 | { |
992 | 0 | T val = data[m]; |
993 | 0 | dataBuf[cnt] = val; |
994 | |
|
995 | 0 | if (cnt > 0) |
996 | 0 | { |
997 | 0 | if (val < zMin) |
998 | 0 | zMin = val; |
999 | 0 | else if (val > zMax) |
1000 | 0 | zMax = val; |
1001 | |
|
1002 | 0 | if (val == prevVal) |
1003 | 0 | cntSameVal++; |
1004 | 0 | } |
1005 | 0 | else |
1006 | 0 | zMin = zMax = val; // init |
1007 | |
|
1008 | 0 | prevVal = val; |
1009 | 0 | cnt++; |
1010 | 0 | } |
1011 | 0 | } |
1012 | 0 | } |
1013 | 0 | else // not all valid, use mask |
1014 | 0 | { |
1015 | 0 | for (int i = i0; i < i1; i++) |
1016 | 0 | { |
1017 | 0 | int k = i * hd.nCols + j0; |
1018 | 0 | int m = k * nDim + iDim; |
1019 | |
|
1020 | 0 | for (int j = j0; j < j1; j++, k++, m += nDim) |
1021 | 0 | if (m_bitMask.IsValid(k)) |
1022 | 0 | { |
1023 | 0 | T val = data[m]; |
1024 | 0 | dataBuf[cnt] = val; |
1025 | |
|
1026 | 0 | if (cnt > 0) |
1027 | 0 | { |
1028 | 0 | if (val < zMin) |
1029 | 0 | zMin = val; |
1030 | 0 | else if (val > zMax) |
1031 | 0 | zMax = val; |
1032 | |
|
1033 | 0 | if (val == prevVal) |
1034 | 0 | cntSameVal++; |
1035 | 0 | } |
1036 | 0 | else |
1037 | 0 | zMin = zMax = val; // init |
1038 | |
|
1039 | 0 | prevVal = val; |
1040 | 0 | cnt++; |
1041 | 0 | } |
1042 | 0 | } |
1043 | 0 | } |
1044 | |
|
1045 | 0 | if (cnt > 4) |
1046 | 0 | tryLut = (zMax > zMin + hd.maxZError) && (2 * cntSameVal > cnt); |
1047 | |
|
1048 | 0 | numValidPixel = cnt; |
1049 | 0 | return true; |
1050 | 0 | } Unexecuted instantiation: bool GDAL_LercNS::Lerc2::GetValidDataAndStats<signed char>(signed char const*, int, int, int, int, int, signed char*, signed char&, signed char&, int&, bool&) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::GetValidDataAndStats<unsigned char>(unsigned char const*, int, int, int, int, int, unsigned char*, unsigned char&, unsigned char&, int&, bool&) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::GetValidDataAndStats<short>(short const*, int, int, int, int, int, short*, short&, short&, int&, bool&) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::GetValidDataAndStats<unsigned short>(unsigned short const*, int, int, int, int, int, unsigned short*, unsigned short&, unsigned short&, int&, bool&) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::GetValidDataAndStats<int>(int const*, int, int, int, int, int, int*, int&, int&, int&, bool&) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::GetValidDataAndStats<unsigned int>(unsigned int const*, int, int, int, int, int, unsigned int*, unsigned int&, unsigned int&, int&, bool&) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::GetValidDataAndStats<float>(float const*, int, int, int, int, int, float*, float&, float&, int&, bool&) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::GetValidDataAndStats<double>(double const*, int, int, int, int, int, double*, double&, double&, int&, bool&) const |
1051 | | |
1052 | | // -------------------------------------------------------------------------- ; |
1053 | | |
1054 | | inline double Lerc2::ComputeMaxVal(double zMin, double zMax, double maxZError) |
1055 | 0 | { |
1056 | 0 | double fac = 1 / (2 * maxZError); // must match the code in Decode(), don't touch it |
1057 | 0 | return (zMax - zMin) * fac; |
1058 | 0 | } |
1059 | | |
1060 | | // -------------------------------------------------------------------------- ; |
1061 | | |
1062 | | template<class T> |
1063 | | bool Lerc2::NeedToQuantize(int numValidPixel, T zMin, T zMax) const |
1064 | 0 | { |
1065 | 0 | if (numValidPixel == 0 || m_headerInfo.maxZError == 0) |
1066 | 0 | return false; |
1067 | | |
1068 | 0 | double maxVal = ComputeMaxVal(zMin, zMax, m_headerInfo.maxZError); |
1069 | 0 | return !(maxVal > m_maxValToQuantize || (unsigned int)(maxVal + 0.5) == 0); |
1070 | 0 | } Unexecuted instantiation: bool GDAL_LercNS::Lerc2::NeedToQuantize<signed char>(int, signed char, signed char) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::NeedToQuantize<unsigned char>(int, unsigned char, unsigned char) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::NeedToQuantize<short>(int, short, short) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::NeedToQuantize<unsigned short>(int, unsigned short, unsigned short) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::NeedToQuantize<int>(int, int, int) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::NeedToQuantize<unsigned int>(int, unsigned int, unsigned int) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::NeedToQuantize<float>(int, float, float) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::NeedToQuantize<double>(int, double, double) const |
1071 | | |
1072 | | // -------------------------------------------------------------------------- ; |
1073 | | |
1074 | | template<class T> |
1075 | | bool Lerc2::Quantize(const T* dataBuf, int num, T zMin, std::vector<unsigned int>& quantVec) const |
1076 | 0 | { |
1077 | 0 | quantVec.resize(num); |
1078 | |
|
1079 | 0 | if (m_headerInfo.dt < DT_Float && m_headerInfo.maxZError == 0.5) // int lossless |
1080 | 0 | { |
1081 | 0 | for (int i = 0; i < num; i++) |
1082 | 0 | quantVec[i] = (unsigned int)(dataBuf[i] - zMin); // ok, as char, short get promoted to int by C++ integral promotion rule |
1083 | 0 | } |
1084 | 0 | else // float and/or lossy |
1085 | 0 | { |
1086 | 0 | double scale = 1 / (2 * m_headerInfo.maxZError); |
1087 | 0 | double zMinDbl = (double)zMin; |
1088 | |
|
1089 | 0 | for (int i = 0; i < num; i++) |
1090 | 0 | quantVec[i] = (unsigned int)(((double)dataBuf[i] - zMinDbl) * scale + 0.5); // ok, consistent with ComputeMaxVal(...) |
1091 | | //quantVec[i] = (unsigned int)((dataBuf[i] - zMin) * scale + 0.5); // bad, not consistent with ComputeMaxVal(...) |
1092 | 0 | } |
1093 | |
|
1094 | 0 | return true; |
1095 | 0 | } Unexecuted instantiation: bool GDAL_LercNS::Lerc2::Quantize<signed char>(signed char const*, int, signed char, std::__1::vector<unsigned int, std::__1::allocator<unsigned int> >&) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::Quantize<unsigned char>(unsigned char const*, int, unsigned char, std::__1::vector<unsigned int, std::__1::allocator<unsigned int> >&) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::Quantize<short>(short const*, int, short, std::__1::vector<unsigned int, std::__1::allocator<unsigned int> >&) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::Quantize<unsigned short>(unsigned short const*, int, unsigned short, std::__1::vector<unsigned int, std::__1::allocator<unsigned int> >&) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::Quantize<int>(int const*, int, int, std::__1::vector<unsigned int, std::__1::allocator<unsigned int> >&) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::Quantize<unsigned int>(unsigned int const*, int, unsigned int, std::__1::vector<unsigned int, std::__1::allocator<unsigned int> >&) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::Quantize<float>(float const*, int, float, std::__1::vector<unsigned int, std::__1::allocator<unsigned int> >&) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::Quantize<double>(double const*, int, double, std::__1::vector<unsigned int, std::__1::allocator<unsigned int> >&) const |
1096 | | |
1097 | | // -------------------------------------------------------------------------- ; |
1098 | | |
1099 | | template<class T> |
1100 | | int Lerc2::NumBytesTile(int numValidPixel, T zMin, T zMax, bool tryLut, BlockEncodeMode& blockEncodeMode, |
1101 | | const std::vector<std::pair<unsigned int, unsigned int> >& sortedQuantVec) const |
1102 | 0 | { |
1103 | 0 | blockEncodeMode = BEM_RawBinary; |
1104 | |
|
1105 | 0 | if (numValidPixel == 0 || (zMin == 0 && zMax == 0)) |
1106 | 0 | return 1; |
1107 | | |
1108 | 0 | double maxVal = 0, maxZError = m_headerInfo.maxZError; |
1109 | 0 | int nBytesRaw = (int)(1 + numValidPixel * sizeof(T)); |
1110 | |
|
1111 | 0 | if ((maxZError == 0 && zMax > zMin) |
1112 | 0 | || (maxZError > 0 && (maxVal = ComputeMaxVal(zMin, zMax, maxZError)) > m_maxValToQuantize)) |
1113 | 0 | { |
1114 | 0 | return nBytesRaw; |
1115 | 0 | } |
1116 | 0 | else |
1117 | 0 | { |
1118 | 0 | DataType dtUsed; |
1119 | 0 | TypeCode(zMin, dtUsed); |
1120 | 0 | int nBytes = 1 + GetDataTypeSize(dtUsed); |
1121 | |
|
1122 | 0 | unsigned int maxElem = (unsigned int)(maxVal + 0.5); |
1123 | 0 | if (maxElem > 0) |
1124 | 0 | { |
1125 | 0 | nBytes += (!tryLut) ? m_bitStuffer2.ComputeNumBytesNeededSimple(numValidPixel, maxElem) |
1126 | 0 | : m_bitStuffer2.ComputeNumBytesNeededLut(sortedQuantVec, tryLut); |
1127 | 0 | } |
1128 | |
|
1129 | 0 | if (nBytes < nBytesRaw) |
1130 | 0 | blockEncodeMode = (!tryLut || maxElem == 0) ? BEM_BitStuffSimple : BEM_BitStuffLUT; |
1131 | 0 | else |
1132 | 0 | nBytes = nBytesRaw; |
1133 | |
|
1134 | 0 | return nBytes; |
1135 | 0 | } |
1136 | 0 | } Unexecuted instantiation: int GDAL_LercNS::Lerc2::NumBytesTile<signed char>(int, signed char, signed char, bool, GDAL_LercNS::Lerc2::BlockEncodeMode&, std::__1::vector<std::__1::pair<unsigned int, unsigned int>, std::__1::allocator<std::__1::pair<unsigned int, unsigned int> > > const&) const Unexecuted instantiation: int GDAL_LercNS::Lerc2::NumBytesTile<unsigned char>(int, unsigned char, unsigned char, bool, GDAL_LercNS::Lerc2::BlockEncodeMode&, std::__1::vector<std::__1::pair<unsigned int, unsigned int>, std::__1::allocator<std::__1::pair<unsigned int, unsigned int> > > const&) const Unexecuted instantiation: int GDAL_LercNS::Lerc2::NumBytesTile<short>(int, short, short, bool, GDAL_LercNS::Lerc2::BlockEncodeMode&, std::__1::vector<std::__1::pair<unsigned int, unsigned int>, std::__1::allocator<std::__1::pair<unsigned int, unsigned int> > > const&) const Unexecuted instantiation: int GDAL_LercNS::Lerc2::NumBytesTile<unsigned short>(int, unsigned short, unsigned short, bool, GDAL_LercNS::Lerc2::BlockEncodeMode&, std::__1::vector<std::__1::pair<unsigned int, unsigned int>, std::__1::allocator<std::__1::pair<unsigned int, unsigned int> > > const&) const Unexecuted instantiation: int GDAL_LercNS::Lerc2::NumBytesTile<int>(int, int, int, bool, GDAL_LercNS::Lerc2::BlockEncodeMode&, std::__1::vector<std::__1::pair<unsigned int, unsigned int>, std::__1::allocator<std::__1::pair<unsigned int, unsigned int> > > const&) const Unexecuted instantiation: int GDAL_LercNS::Lerc2::NumBytesTile<unsigned int>(int, unsigned int, unsigned int, bool, GDAL_LercNS::Lerc2::BlockEncodeMode&, std::__1::vector<std::__1::pair<unsigned int, unsigned int>, std::__1::allocator<std::__1::pair<unsigned int, unsigned int> > > const&) const Unexecuted instantiation: int GDAL_LercNS::Lerc2::NumBytesTile<float>(int, float, float, bool, GDAL_LercNS::Lerc2::BlockEncodeMode&, std::__1::vector<std::__1::pair<unsigned int, unsigned int>, std::__1::allocator<std::__1::pair<unsigned int, unsigned int> > > const&) const Unexecuted instantiation: int GDAL_LercNS::Lerc2::NumBytesTile<double>(int, double, double, bool, GDAL_LercNS::Lerc2::BlockEncodeMode&, std::__1::vector<std::__1::pair<unsigned int, unsigned int>, std::__1::allocator<std::__1::pair<unsigned int, unsigned int> > > const&) const |
1137 | | |
1138 | | // -------------------------------------------------------------------------- ; |
1139 | | |
1140 | | template<class T> |
1141 | | bool Lerc2::WriteTile(const T* dataBuf, int num, Byte** ppByte, int& numBytesWritten, int j0, T zMin, T zMax, |
1142 | | const std::vector<unsigned int>& quantVec, BlockEncodeMode blockEncodeMode, |
1143 | | const std::vector<std::pair<unsigned int, unsigned int> >& sortedQuantVec) const |
1144 | 0 | { |
1145 | 0 | Byte* ptr = *ppByte; |
1146 | 0 | Byte comprFlag = ((j0 >> 3) & 15) << 2; // use bits 2345 for integrity check |
1147 | |
|
1148 | 0 | if (num == 0 || (zMin == 0 && zMax == 0)) // special cases |
1149 | 0 | { |
1150 | 0 | *ptr++ = comprFlag | 2; // set compression flag to 2 to mark tile as constant 0 |
1151 | 0 | numBytesWritten = 1; |
1152 | 0 | *ppByte = ptr; |
1153 | 0 | return true; |
1154 | 0 | } |
1155 | | |
1156 | 0 | if (blockEncodeMode == BEM_RawBinary) |
1157 | 0 | { |
1158 | 0 | *ptr++ = comprFlag | 0; // write z's binary uncompressed |
1159 | |
|
1160 | 0 | memcpy(ptr, dataBuf, num * sizeof(T)); |
1161 | 0 | ptr += num * sizeof(T); |
1162 | 0 | } |
1163 | 0 | else |
1164 | 0 | { |
1165 | 0 | double maxVal = (m_headerInfo.maxZError > 0) ? ComputeMaxVal(zMin, zMax, m_headerInfo.maxZError) : 0; |
1166 | | |
1167 | | // write z's as int arr bit stuffed |
1168 | 0 | unsigned int maxElem = (unsigned int)(maxVal + 0.5); |
1169 | 0 | if (maxElem == 0) |
1170 | 0 | comprFlag |= 3; // set compression flag to 3 to mark tile as constant zMin |
1171 | 0 | else |
1172 | 0 | comprFlag |= 1; // use bit stuffing |
1173 | |
|
1174 | 0 | DataType dtUsed; |
1175 | 0 | int bits67 = TypeCode(zMin, dtUsed); |
1176 | 0 | comprFlag |= bits67 << 6; |
1177 | |
|
1178 | 0 | *ptr++ = comprFlag; |
1179 | |
|
1180 | 0 | if (!WriteVariableDataType(&ptr, (double)zMin, dtUsed)) |
1181 | 0 | return false; |
1182 | | |
1183 | 0 | if (maxElem > 0) |
1184 | 0 | { |
1185 | 0 | if ((int)quantVec.size() != num) |
1186 | 0 | return false; |
1187 | | |
1188 | 0 | if (blockEncodeMode == BEM_BitStuffSimple) |
1189 | 0 | { |
1190 | 0 | if (!m_bitStuffer2.EncodeSimple(&ptr, quantVec, m_headerInfo.version)) |
1191 | 0 | return false; |
1192 | 0 | } |
1193 | 0 | else if (blockEncodeMode == BEM_BitStuffLUT) |
1194 | 0 | { |
1195 | 0 | if (!m_bitStuffer2.EncodeLut(&ptr, sortedQuantVec, m_headerInfo.version)) |
1196 | 0 | return false; |
1197 | 0 | } |
1198 | 0 | else |
1199 | 0 | return false; |
1200 | 0 | } |
1201 | 0 | } |
1202 | | |
1203 | 0 | numBytesWritten = (int)(ptr - *ppByte); |
1204 | 0 | *ppByte = ptr; |
1205 | 0 | return true; |
1206 | 0 | } Unexecuted instantiation: bool GDAL_LercNS::Lerc2::WriteTile<signed char>(signed char const*, int, unsigned char**, int&, int, signed char, signed char, std::__1::vector<unsigned int, std::__1::allocator<unsigned int> > const&, GDAL_LercNS::Lerc2::BlockEncodeMode, std::__1::vector<std::__1::pair<unsigned int, unsigned int>, std::__1::allocator<std::__1::pair<unsigned int, unsigned int> > > const&) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::WriteTile<unsigned char>(unsigned char const*, int, unsigned char**, int&, int, unsigned char, unsigned char, std::__1::vector<unsigned int, std::__1::allocator<unsigned int> > const&, GDAL_LercNS::Lerc2::BlockEncodeMode, std::__1::vector<std::__1::pair<unsigned int, unsigned int>, std::__1::allocator<std::__1::pair<unsigned int, unsigned int> > > const&) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::WriteTile<short>(short const*, int, unsigned char**, int&, int, short, short, std::__1::vector<unsigned int, std::__1::allocator<unsigned int> > const&, GDAL_LercNS::Lerc2::BlockEncodeMode, std::__1::vector<std::__1::pair<unsigned int, unsigned int>, std::__1::allocator<std::__1::pair<unsigned int, unsigned int> > > const&) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::WriteTile<unsigned short>(unsigned short const*, int, unsigned char**, int&, int, unsigned short, unsigned short, std::__1::vector<unsigned int, std::__1::allocator<unsigned int> > const&, GDAL_LercNS::Lerc2::BlockEncodeMode, std::__1::vector<std::__1::pair<unsigned int, unsigned int>, std::__1::allocator<std::__1::pair<unsigned int, unsigned int> > > const&) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::WriteTile<int>(int const*, int, unsigned char**, int&, int, int, int, std::__1::vector<unsigned int, std::__1::allocator<unsigned int> > const&, GDAL_LercNS::Lerc2::BlockEncodeMode, std::__1::vector<std::__1::pair<unsigned int, unsigned int>, std::__1::allocator<std::__1::pair<unsigned int, unsigned int> > > const&) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::WriteTile<unsigned int>(unsigned int const*, int, unsigned char**, int&, int, unsigned int, unsigned int, std::__1::vector<unsigned int, std::__1::allocator<unsigned int> > const&, GDAL_LercNS::Lerc2::BlockEncodeMode, std::__1::vector<std::__1::pair<unsigned int, unsigned int>, std::__1::allocator<std::__1::pair<unsigned int, unsigned int> > > const&) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::WriteTile<float>(float const*, int, unsigned char**, int&, int, float, float, std::__1::vector<unsigned int, std::__1::allocator<unsigned int> > const&, GDAL_LercNS::Lerc2::BlockEncodeMode, std::__1::vector<std::__1::pair<unsigned int, unsigned int>, std::__1::allocator<std::__1::pair<unsigned int, unsigned int> > > const&) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::WriteTile<double>(double const*, int, unsigned char**, int&, int, double, double, std::__1::vector<unsigned int, std::__1::allocator<unsigned int> > const&, GDAL_LercNS::Lerc2::BlockEncodeMode, std::__1::vector<std::__1::pair<unsigned int, unsigned int>, std::__1::allocator<std::__1::pair<unsigned int, unsigned int> > > const&) const |
1207 | | |
1208 | | // -------------------------------------------------------------------------- ; |
1209 | | |
1210 | | template<class T> |
1211 | | bool Lerc2::ReadTile(const Byte** ppByte, size_t& nBytesRemainingInOut, T* data, int i0, int i1, int j0, int j1, int iDim, |
1212 | | std::vector<unsigned int>& bufferVec) const |
1213 | 419k | { |
1214 | 419k | const Byte* ptr = *ppByte; |
1215 | 419k | size_t nBytesRemaining = nBytesRemainingInOut; |
1216 | | |
1217 | 419k | if (nBytesRemaining < 1) |
1218 | 584 | return false; |
1219 | | |
1220 | 419k | Byte comprFlag = *ptr++; |
1221 | 419k | nBytesRemaining--; |
1222 | | |
1223 | 419k | int bits67 = comprFlag >> 6; |
1224 | 419k | int testCode = (comprFlag >> 2) & 15; // use bits 2345 for integrity check |
1225 | 419k | if (testCode != ((j0 >> 3) & 15)) |
1226 | 6.69k | return false; |
1227 | | |
1228 | 412k | const HeaderInfo& hd = m_headerInfo; |
1229 | 412k | int nCols = hd.nCols; |
1230 | 412k | int nDim = hd.nDim; |
1231 | | |
1232 | 412k | comprFlag &= 3; |
1233 | | |
1234 | 412k | if (comprFlag == 2) // entire tile is constant 0 (all the valid pixels) |
1235 | 28.2k | { |
1236 | 141k | for (int i = i0; i < i1; i++) |
1237 | 113k | { |
1238 | 113k | int k = i * nCols + j0; |
1239 | 113k | int m = k * nDim + iDim; |
1240 | | |
1241 | 1.20M | for (int j = j0; j < j1; j++, k++, m += nDim) |
1242 | 1.09M | if (m_bitMask.IsValid(k)) |
1243 | 885k | data[m] = 0; |
1244 | 113k | } |
1245 | | |
1246 | 28.2k | *ppByte = ptr; |
1247 | 28.2k | nBytesRemainingInOut = nBytesRemaining; |
1248 | 28.2k | return true; |
1249 | 28.2k | } |
1250 | | |
1251 | 384k | else if (comprFlag == 0) // read z's binary uncompressed |
1252 | 351k | { |
1253 | 351k | const T* srcPtr = (const T*)ptr; |
1254 | 351k | int cnt = 0; |
1255 | | |
1256 | 1.68M | for (int i = i0; i < i1; i++) |
1257 | 1.33M | { |
1258 | 1.33M | int k = i * nCols + j0; |
1259 | 1.33M | int m = k * nDim + iDim; |
1260 | | |
1261 | 6.56M | for (int j = j0; j < j1; j++, k++, m += nDim) |
1262 | 5.23M | if (m_bitMask.IsValid(k)) |
1263 | 502k | { |
1264 | 502k | if (nBytesRemaining < sizeof(T)) |
1265 | 769 | return false; |
1266 | | |
1267 | 502k | data[m] = *srcPtr++; |
1268 | 502k | nBytesRemaining -= sizeof(T); |
1269 | | |
1270 | 502k | cnt++; |
1271 | 502k | } |
1272 | 1.33M | } |
1273 | | |
1274 | 350k | ptr += cnt * sizeof(T); |
1275 | 350k | } |
1276 | 32.4k | else |
1277 | 32.4k | { |
1278 | | // read z's as int arr bit stuffed |
1279 | 32.4k | DataType dtUsed = GetDataTypeUsed(bits67); |
1280 | 32.4k | if( dtUsed == DT_Undefined ) |
1281 | 158 | return false; |
1282 | 32.2k | size_t n = GetDataTypeSize(dtUsed); |
1283 | 32.2k | if (nBytesRemaining < n) |
1284 | 262 | return false; |
1285 | | |
1286 | 32.0k | double offset = ReadVariableDataType(&ptr, dtUsed); |
1287 | 32.0k | nBytesRemaining -= n; |
1288 | | |
1289 | 32.0k | if (comprFlag == 3) // entire tile is constant zMin (all the valid pixels) |
1290 | 16.7k | { |
1291 | 133k | for (int i = i0; i < i1; i++) |
1292 | 116k | { |
1293 | 116k | int k = i * nCols + j0; |
1294 | 116k | int m = k * nDim + iDim; |
1295 | | |
1296 | 984k | for (int j = j0; j < j1; j++, k++, m += nDim) |
1297 | 868k | if (m_bitMask.IsValid(k)) |
1298 | 168k | data[m] = (T)offset; |
1299 | 116k | } |
1300 | 16.7k | } |
1301 | 15.2k | else |
1302 | 15.2k | { |
1303 | 15.2k | size_t maxElementCount = (i1 - i0) * (j1 - j0); |
1304 | 15.2k | if (!m_bitStuffer2.Decode(&ptr, nBytesRemaining, bufferVec, maxElementCount, hd.version)) |
1305 | 2.81k | return false; |
1306 | | |
1307 | 12.4k | double invScale = 2 * hd.maxZError; // for int types this is int |
1308 | 12.4k | double zMax = (hd.version >= 4 && nDim > 1) ? m_zMaxVec[iDim] : hd.zMax; |
1309 | 12.4k | const unsigned int* srcPtr = bufferVec.data(); |
1310 | | |
1311 | 12.4k | if (bufferVec.size() == maxElementCount) // all valid |
1312 | 5.27k | { |
1313 | 42.6k | for (int i = i0; i < i1; i++) |
1314 | 37.3k | { |
1315 | 37.3k | int k = i * nCols + j0; |
1316 | 37.3k | int m = k * nDim + iDim; |
1317 | | |
1318 | 366k | for (int j = j0; j < j1; j++, k++, m += nDim) |
1319 | 329k | { |
1320 | 329k | double z = offset + *srcPtr++ * invScale; |
1321 | 329k | data[m] = (T)std::min(z, zMax); // make sure we stay in the orig range |
1322 | 329k | } |
1323 | 37.3k | } |
1324 | 5.27k | } |
1325 | 7.15k | else // not all valid |
1326 | 7.15k | { |
1327 | | #ifndef GDAL_COMPILATION |
1328 | | if (hd.version > 2) |
1329 | | { |
1330 | | for (int i = i0; i < i1; i++) |
1331 | | { |
1332 | | int k = i * nCols + j0; |
1333 | | int m = k * nDim + iDim; |
1334 | | |
1335 | | for (int j = j0; j < j1; j++, k++, m += nDim) |
1336 | | if (m_bitMask.IsValid(k)) |
1337 | | { |
1338 | | double z = offset + *srcPtr++ * invScale; |
1339 | | data[m] = (T)std::min(z, zMax); // make sure we stay in the orig range |
1340 | | } |
1341 | | } |
1342 | | } |
1343 | | else // fail gracefully in case of corrupted blob for old version <= 2 which had no checksum |
1344 | | #endif |
1345 | 7.15k | { |
1346 | 7.15k | size_t bufferVecIdx = 0; |
1347 | | |
1348 | 85.2k | for (int i = i0; i < i1; i++) |
1349 | 78.9k | { |
1350 | 78.9k | int k = i * nCols + j0; |
1351 | 78.9k | int m = k * nDim + iDim; |
1352 | | |
1353 | 777k | for (int j = j0; j < j1; j++, k++, m += nDim) |
1354 | 699k | if (m_bitMask.IsValid(k)) |
1355 | 88.9k | { |
1356 | 88.9k | if (bufferVecIdx == bufferVec.size()) // fail gracefully in case of corrupted blob for old version <= 2 which had no checksum |
1357 | 881 | return false; |
1358 | | |
1359 | 88.0k | double z = offset + bufferVec[bufferVecIdx] * invScale; |
1360 | 88.0k | bufferVecIdx++; |
1361 | 88.0k | data[m] = (T)std::min(z, zMax); // make sure we stay in the orig range |
1362 | 88.0k | } |
1363 | 78.9k | } |
1364 | 7.15k | } |
1365 | 7.15k | } |
1366 | 12.4k | } |
1367 | 32.0k | } |
1368 | | |
1369 | 379k | *ppByte = ptr; |
1370 | 379k | nBytesRemainingInOut = nBytesRemaining; |
1371 | 379k | return true; |
1372 | 412k | } bool GDAL_LercNS::Lerc2::ReadTile<signed char>(unsigned char const**, unsigned long&, signed char*, int, int, int, int, int, std::__1::vector<unsigned int, std::__1::allocator<unsigned int> >&) const Line | Count | Source | 1213 | 15.2k | { | 1214 | 15.2k | const Byte* ptr = *ppByte; | 1215 | 15.2k | size_t nBytesRemaining = nBytesRemainingInOut; | 1216 | | | 1217 | 15.2k | if (nBytesRemaining < 1) | 1218 | 21 | return false; | 1219 | | | 1220 | 15.2k | Byte comprFlag = *ptr++; | 1221 | 15.2k | nBytesRemaining--; | 1222 | | | 1223 | 15.2k | int bits67 = comprFlag >> 6; | 1224 | 15.2k | int testCode = (comprFlag >> 2) & 15; // use bits 2345 for integrity check | 1225 | 15.2k | if (testCode != ((j0 >> 3) & 15)) | 1226 | 696 | return false; | 1227 | | | 1228 | 14.5k | const HeaderInfo& hd = m_headerInfo; | 1229 | 14.5k | int nCols = hd.nCols; | 1230 | 14.5k | int nDim = hd.nDim; | 1231 | | | 1232 | 14.5k | comprFlag &= 3; | 1233 | | | 1234 | 14.5k | if (comprFlag == 2) // entire tile is constant 0 (all the valid pixels) | 1235 | 4.43k | { | 1236 | 12.8k | for (int i = i0; i < i1; i++) | 1237 | 8.45k | { | 1238 | 8.45k | int k = i * nCols + j0; | 1239 | 8.45k | int m = k * nDim + iDim; | 1240 | | | 1241 | 48.5k | for (int j = j0; j < j1; j++, k++, m += nDim) | 1242 | 40.1k | if (m_bitMask.IsValid(k)) | 1243 | 17.1k | data[m] = 0; | 1244 | 8.45k | } | 1245 | | | 1246 | 4.43k | *ppByte = ptr; | 1247 | 4.43k | nBytesRemainingInOut = nBytesRemaining; | 1248 | 4.43k | return true; | 1249 | 4.43k | } | 1250 | | | 1251 | 10.1k | else if (comprFlag == 0) // read z's binary uncompressed | 1252 | 8.77k | { | 1253 | 8.77k | const T* srcPtr = (const T*)ptr; | 1254 | 8.77k | int cnt = 0; | 1255 | | | 1256 | 30.8k | for (int i = i0; i < i1; i++) | 1257 | 22.0k | { | 1258 | 22.0k | int k = i * nCols + j0; | 1259 | 22.0k | int m = k * nDim + iDim; | 1260 | | | 1261 | 166k | for (int j = j0; j < j1; j++, k++, m += nDim) | 1262 | 144k | if (m_bitMask.IsValid(k)) | 1263 | 65.1k | { | 1264 | 65.1k | if (nBytesRemaining < sizeof(T)) | 1265 | 54 | return false; | 1266 | | | 1267 | 65.1k | data[m] = *srcPtr++; | 1268 | 65.1k | nBytesRemaining -= sizeof(T); | 1269 | | | 1270 | 65.1k | cnt++; | 1271 | 65.1k | } | 1272 | 22.0k | } | 1273 | | | 1274 | 8.71k | ptr += cnt * sizeof(T); | 1275 | 8.71k | } | 1276 | 1.32k | else | 1277 | 1.32k | { | 1278 | | // read z's as int arr bit stuffed | 1279 | 1.32k | DataType dtUsed = GetDataTypeUsed(bits67); | 1280 | 1.32k | if( dtUsed == DT_Undefined ) | 1281 | 0 | return false; | 1282 | 1.32k | size_t n = GetDataTypeSize(dtUsed); | 1283 | 1.32k | if (nBytesRemaining < n) | 1284 | 0 | return false; | 1285 | | | 1286 | 1.32k | double offset = ReadVariableDataType(&ptr, dtUsed); | 1287 | 1.32k | nBytesRemaining -= n; | 1288 | | | 1289 | 1.32k | if (comprFlag == 3) // entire tile is constant zMin (all the valid pixels) | 1290 | 735 | { | 1291 | 3.60k | for (int i = i0; i < i1; i++) | 1292 | 2.87k | { | 1293 | 2.87k | int k = i * nCols + j0; | 1294 | 2.87k | int m = k * nDim + iDim; | 1295 | | | 1296 | 21.8k | for (int j = j0; j < j1; j++, k++, m += nDim) | 1297 | 18.9k | if (m_bitMask.IsValid(k)) | 1298 | 15.9k | data[m] = (T)offset; | 1299 | 2.87k | } | 1300 | 735 | } | 1301 | 593 | else | 1302 | 593 | { | 1303 | 593 | size_t maxElementCount = (i1 - i0) * (j1 - j0); | 1304 | 593 | if (!m_bitStuffer2.Decode(&ptr, nBytesRemaining, bufferVec, maxElementCount, hd.version)) | 1305 | 194 | return false; | 1306 | | | 1307 | 399 | double invScale = 2 * hd.maxZError; // for int types this is int | 1308 | 399 | double zMax = (hd.version >= 4 && nDim > 1) ? m_zMaxVec[iDim] : hd.zMax; | 1309 | 399 | const unsigned int* srcPtr = bufferVec.data(); | 1310 | | | 1311 | 399 | if (bufferVec.size() == maxElementCount) // all valid | 1312 | 95 | { | 1313 | 889 | for (int i = i0; i < i1; i++) | 1314 | 794 | { | 1315 | 794 | int k = i * nCols + j0; | 1316 | 794 | int m = k * nDim + iDim; | 1317 | | | 1318 | 12.7k | for (int j = j0; j < j1; j++, k++, m += nDim) | 1319 | 11.9k | { | 1320 | 11.9k | double z = offset + *srcPtr++ * invScale; | 1321 | 11.9k | data[m] = (T)std::min(z, zMax); // make sure we stay in the orig range | 1322 | 11.9k | } | 1323 | 794 | } | 1324 | 95 | } | 1325 | 304 | else // not all valid | 1326 | 304 | { | 1327 | | #ifndef GDAL_COMPILATION | 1328 | | if (hd.version > 2) | 1329 | | { | 1330 | | for (int i = i0; i < i1; i++) | 1331 | | { | 1332 | | int k = i * nCols + j0; | 1333 | | int m = k * nDim + iDim; | 1334 | | | 1335 | | for (int j = j0; j < j1; j++, k++, m += nDim) | 1336 | | if (m_bitMask.IsValid(k)) | 1337 | | { | 1338 | | double z = offset + *srcPtr++ * invScale; | 1339 | | data[m] = (T)std::min(z, zMax); // make sure we stay in the orig range | 1340 | | } | 1341 | | } | 1342 | | } | 1343 | | else // fail gracefully in case of corrupted blob for old version <= 2 which had no checksum | 1344 | | #endif | 1345 | 304 | { | 1346 | 304 | size_t bufferVecIdx = 0; | 1347 | | | 1348 | 1.79k | for (int i = i0; i < i1; i++) | 1349 | 1.64k | { | 1350 | 1.64k | int k = i * nCols + j0; | 1351 | 1.64k | int m = k * nDim + iDim; | 1352 | | | 1353 | 22.1k | for (int j = j0; j < j1; j++, k++, m += nDim) | 1354 | 20.6k | if (m_bitMask.IsValid(k)) | 1355 | 7.93k | { | 1356 | 7.93k | if (bufferVecIdx == bufferVec.size()) // fail gracefully in case of corrupted blob for old version <= 2 which had no checksum | 1357 | 152 | return false; | 1358 | | | 1359 | 7.78k | double z = offset + bufferVec[bufferVecIdx] * invScale; | 1360 | 7.78k | bufferVecIdx++; | 1361 | 7.78k | data[m] = (T)std::min(z, zMax); // make sure we stay in the orig range | 1362 | 7.78k | } | 1363 | 1.64k | } | 1364 | 304 | } | 1365 | 304 | } | 1366 | 399 | } | 1367 | 1.32k | } | 1368 | | | 1369 | 9.70k | *ppByte = ptr; | 1370 | 9.70k | nBytesRemainingInOut = nBytesRemaining; | 1371 | 9.70k | return true; | 1372 | 14.5k | } |
bool GDAL_LercNS::Lerc2::ReadTile<unsigned char>(unsigned char const**, unsigned long&, unsigned char*, int, int, int, int, int, std::__1::vector<unsigned int, std::__1::allocator<unsigned int> >&) const Line | Count | Source | 1213 | 54.7k | { | 1214 | 54.7k | const Byte* ptr = *ppByte; | 1215 | 54.7k | size_t nBytesRemaining = nBytesRemainingInOut; | 1216 | | | 1217 | 54.7k | if (nBytesRemaining < 1) | 1218 | 108 | return false; | 1219 | | | 1220 | 54.6k | Byte comprFlag = *ptr++; | 1221 | 54.6k | nBytesRemaining--; | 1222 | | | 1223 | 54.6k | int bits67 = comprFlag >> 6; | 1224 | 54.6k | int testCode = (comprFlag >> 2) & 15; // use bits 2345 for integrity check | 1225 | 54.6k | if (testCode != ((j0 >> 3) & 15)) | 1226 | 1.49k | return false; | 1227 | | | 1228 | 53.1k | const HeaderInfo& hd = m_headerInfo; | 1229 | 53.1k | int nCols = hd.nCols; | 1230 | 53.1k | int nDim = hd.nDim; | 1231 | | | 1232 | 53.1k | comprFlag &= 3; | 1233 | | | 1234 | 53.1k | if (comprFlag == 2) // entire tile is constant 0 (all the valid pixels) | 1235 | 10.9k | { | 1236 | 80.0k | for (int i = i0; i < i1; i++) | 1237 | 69.1k | { | 1238 | 69.1k | int k = i * nCols + j0; | 1239 | 69.1k | int m = k * nDim + iDim; | 1240 | | | 1241 | 911k | for (int j = j0; j < j1; j++, k++, m += nDim) | 1242 | 842k | if (m_bitMask.IsValid(k)) | 1243 | 821k | data[m] = 0; | 1244 | 69.1k | } | 1245 | | | 1246 | 10.9k | *ppByte = ptr; | 1247 | 10.9k | nBytesRemainingInOut = nBytesRemaining; | 1248 | 10.9k | return true; | 1249 | 10.9k | } | 1250 | | | 1251 | 42.2k | else if (comprFlag == 0) // read z's binary uncompressed | 1252 | 27.3k | { | 1253 | 27.3k | const T* srcPtr = (const T*)ptr; | 1254 | 27.3k | int cnt = 0; | 1255 | | | 1256 | 309k | for (int i = i0; i < i1; i++) | 1257 | 282k | { | 1258 | 282k | int k = i * nCols + j0; | 1259 | 282k | int m = k * nDim + iDim; | 1260 | | | 1261 | 2.44M | for (int j = j0; j < j1; j++, k++, m += nDim) | 1262 | 2.15M | if (m_bitMask.IsValid(k)) | 1263 | 293k | { | 1264 | 293k | if (nBytesRemaining < sizeof(T)) | 1265 | 63 | return false; | 1266 | | | 1267 | 293k | data[m] = *srcPtr++; | 1268 | 293k | nBytesRemaining -= sizeof(T); | 1269 | | | 1270 | 293k | cnt++; | 1271 | 293k | } | 1272 | 282k | } | 1273 | | | 1274 | 27.2k | ptr += cnt * sizeof(T); | 1275 | 27.2k | } | 1276 | 14.9k | else | 1277 | 14.9k | { | 1278 | | // read z's as int arr bit stuffed | 1279 | 14.9k | DataType dtUsed = GetDataTypeUsed(bits67); | 1280 | 14.9k | if( dtUsed == DT_Undefined ) | 1281 | 11 | return false; | 1282 | 14.9k | size_t n = GetDataTypeSize(dtUsed); | 1283 | 14.9k | if (nBytesRemaining < n) | 1284 | 37 | return false; | 1285 | | | 1286 | 14.9k | double offset = ReadVariableDataType(&ptr, dtUsed); | 1287 | 14.9k | nBytesRemaining -= n; | 1288 | | | 1289 | 14.9k | if (comprFlag == 3) // entire tile is constant zMin (all the valid pixels) | 1290 | 6.08k | { | 1291 | 93.0k | for (int i = i0; i < i1; i++) | 1292 | 86.9k | { | 1293 | 86.9k | int k = i * nCols + j0; | 1294 | 86.9k | int m = k * nDim + iDim; | 1295 | | | 1296 | 771k | for (int j = j0; j < j1; j++, k++, m += nDim) | 1297 | 684k | if (m_bitMask.IsValid(k)) | 1298 | 118k | data[m] = (T)offset; | 1299 | 86.9k | } | 1300 | 6.08k | } | 1301 | 8.85k | else | 1302 | 8.85k | { | 1303 | 8.85k | size_t maxElementCount = (i1 - i0) * (j1 - j0); | 1304 | 8.85k | if (!m_bitStuffer2.Decode(&ptr, nBytesRemaining, bufferVec, maxElementCount, hd.version)) | 1305 | 643 | return false; | 1306 | | | 1307 | 8.20k | double invScale = 2 * hd.maxZError; // for int types this is int | 1308 | 8.20k | double zMax = (hd.version >= 4 && nDim > 1) ? m_zMaxVec[iDim] : hd.zMax; | 1309 | 8.20k | const unsigned int* srcPtr = bufferVec.data(); | 1310 | | | 1311 | 8.20k | if (bufferVec.size() == maxElementCount) // all valid | 1312 | 3.77k | { | 1313 | 32.9k | for (int i = i0; i < i1; i++) | 1314 | 29.1k | { | 1315 | 29.1k | int k = i * nCols + j0; | 1316 | 29.1k | int m = k * nDim + iDim; | 1317 | | | 1318 | 261k | for (int j = j0; j < j1; j++, k++, m += nDim) | 1319 | 232k | { | 1320 | 232k | double z = offset + *srcPtr++ * invScale; | 1321 | 232k | data[m] = (T)std::min(z, zMax); // make sure we stay in the orig range | 1322 | 232k | } | 1323 | 29.1k | } | 1324 | 3.77k | } | 1325 | 4.43k | else // not all valid | 1326 | 4.43k | { | 1327 | | #ifndef GDAL_COMPILATION | 1328 | | if (hd.version > 2) | 1329 | | { | 1330 | | for (int i = i0; i < i1; i++) | 1331 | | { | 1332 | | int k = i * nCols + j0; | 1333 | | int m = k * nDim + iDim; | 1334 | | | 1335 | | for (int j = j0; j < j1; j++, k++, m += nDim) | 1336 | | if (m_bitMask.IsValid(k)) | 1337 | | { | 1338 | | double z = offset + *srcPtr++ * invScale; | 1339 | | data[m] = (T)std::min(z, zMax); // make sure we stay in the orig range | 1340 | | } | 1341 | | } | 1342 | | } | 1343 | | else // fail gracefully in case of corrupted blob for old version <= 2 which had no checksum | 1344 | | #endif | 1345 | 4.43k | { | 1346 | 4.43k | size_t bufferVecIdx = 0; | 1347 | | | 1348 | 70.5k | for (int i = i0; i < i1; i++) | 1349 | 66.3k | { | 1350 | 66.3k | int k = i * nCols + j0; | 1351 | 66.3k | int m = k * nDim + iDim; | 1352 | | | 1353 | 611k | for (int j = j0; j < j1; j++, k++, m += nDim) | 1354 | 544k | if (m_bitMask.IsValid(k)) | 1355 | 55.3k | { | 1356 | 55.3k | if (bufferVecIdx == bufferVec.size()) // fail gracefully in case of corrupted blob for old version <= 2 which had no checksum | 1357 | 202 | return false; | 1358 | | | 1359 | 55.1k | double z = offset + bufferVec[bufferVecIdx] * invScale; | 1360 | 55.1k | bufferVecIdx++; | 1361 | 55.1k | data[m] = (T)std::min(z, zMax); // make sure we stay in the orig range | 1362 | 55.1k | } | 1363 | 66.3k | } | 1364 | 4.43k | } | 1365 | 4.43k | } | 1366 | 8.20k | } | 1367 | 14.9k | } | 1368 | | | 1369 | 41.3k | *ppByte = ptr; | 1370 | 41.3k | nBytesRemainingInOut = nBytesRemaining; | 1371 | 41.3k | return true; | 1372 | 53.1k | } |
bool GDAL_LercNS::Lerc2::ReadTile<short>(unsigned char const**, unsigned long&, short*, int, int, int, int, int, std::__1::vector<unsigned int, std::__1::allocator<unsigned int> >&) const Line | Count | Source | 1213 | 62.1k | { | 1214 | 62.1k | const Byte* ptr = *ppByte; | 1215 | 62.1k | size_t nBytesRemaining = nBytesRemainingInOut; | 1216 | | | 1217 | 62.1k | if (nBytesRemaining < 1) | 1218 | 88 | return false; | 1219 | | | 1220 | 62.0k | Byte comprFlag = *ptr++; | 1221 | 62.0k | nBytesRemaining--; | 1222 | | | 1223 | 62.0k | int bits67 = comprFlag >> 6; | 1224 | 62.0k | int testCode = (comprFlag >> 2) & 15; // use bits 2345 for integrity check | 1225 | 62.0k | if (testCode != ((j0 >> 3) & 15)) | 1226 | 1.08k | return false; | 1227 | | | 1228 | 60.9k | const HeaderInfo& hd = m_headerInfo; | 1229 | 60.9k | int nCols = hd.nCols; | 1230 | 60.9k | int nDim = hd.nDim; | 1231 | | | 1232 | 60.9k | comprFlag &= 3; | 1233 | | | 1234 | 60.9k | if (comprFlag == 2) // entire tile is constant 0 (all the valid pixels) | 1235 | 3.48k | { | 1236 | 11.2k | for (int i = i0; i < i1; i++) | 1237 | 7.78k | { | 1238 | 7.78k | int k = i * nCols + j0; | 1239 | 7.78k | int m = k * nDim + iDim; | 1240 | | | 1241 | 37.6k | for (int j = j0; j < j1; j++, k++, m += nDim) | 1242 | 29.9k | if (m_bitMask.IsValid(k)) | 1243 | 10.1k | data[m] = 0; | 1244 | 7.78k | } | 1245 | | | 1246 | 3.48k | *ppByte = ptr; | 1247 | 3.48k | nBytesRemainingInOut = nBytesRemaining; | 1248 | 3.48k | return true; | 1249 | 3.48k | } | 1250 | | | 1251 | 57.5k | else if (comprFlag == 0) // read z's binary uncompressed | 1252 | 54.9k | { | 1253 | 54.9k | const T* srcPtr = (const T*)ptr; | 1254 | 54.9k | int cnt = 0; | 1255 | | | 1256 | 548k | for (int i = i0; i < i1; i++) | 1257 | 494k | { | 1258 | 494k | int k = i * nCols + j0; | 1259 | 494k | int m = k * nDim + iDim; | 1260 | | | 1261 | 2.50M | for (int j = j0; j < j1; j++, k++, m += nDim) | 1262 | 2.01M | if (m_bitMask.IsValid(k)) | 1263 | 35.4k | { | 1264 | 35.4k | if (nBytesRemaining < sizeof(T)) | 1265 | 105 | return false; | 1266 | | | 1267 | 35.3k | data[m] = *srcPtr++; | 1268 | 35.3k | nBytesRemaining -= sizeof(T); | 1269 | | | 1270 | 35.3k | cnt++; | 1271 | 35.3k | } | 1272 | 494k | } | 1273 | | | 1274 | 54.8k | ptr += cnt * sizeof(T); | 1275 | 54.8k | } | 1276 | 2.55k | else | 1277 | 2.55k | { | 1278 | | // read z's as int arr bit stuffed | 1279 | 2.55k | DataType dtUsed = GetDataTypeUsed(bits67); | 1280 | 2.55k | if( dtUsed == DT_Undefined ) | 1281 | 39 | return false; | 1282 | 2.51k | size_t n = GetDataTypeSize(dtUsed); | 1283 | 2.51k | if (nBytesRemaining < n) | 1284 | 32 | return false; | 1285 | | | 1286 | 2.48k | double offset = ReadVariableDataType(&ptr, dtUsed); | 1287 | 2.48k | nBytesRemaining -= n; | 1288 | | | 1289 | 2.48k | if (comprFlag == 3) // entire tile is constant zMin (all the valid pixels) | 1290 | 1.00k | { | 1291 | 4.70k | for (int i = i0; i < i1; i++) | 1292 | 3.69k | { | 1293 | 3.69k | int k = i * nCols + j0; | 1294 | 3.69k | int m = k * nDim + iDim; | 1295 | | | 1296 | 31.4k | for (int j = j0; j < j1; j++, k++, m += nDim) | 1297 | 27.7k | if (m_bitMask.IsValid(k)) | 1298 | 7.25k | data[m] = (T)offset; | 1299 | 3.69k | } | 1300 | 1.00k | } | 1301 | 1.48k | else | 1302 | 1.48k | { | 1303 | 1.48k | size_t maxElementCount = (i1 - i0) * (j1 - j0); | 1304 | 1.48k | if (!m_bitStuffer2.Decode(&ptr, nBytesRemaining, bufferVec, maxElementCount, hd.version)) | 1305 | 223 | return false; | 1306 | | | 1307 | 1.25k | double invScale = 2 * hd.maxZError; // for int types this is int | 1308 | 1.25k | double zMax = (hd.version >= 4 && nDim > 1) ? m_zMaxVec[iDim] : hd.zMax; | 1309 | 1.25k | const unsigned int* srcPtr = bufferVec.data(); | 1310 | | | 1311 | 1.25k | if (bufferVec.size() == maxElementCount) // all valid | 1312 | 587 | { | 1313 | 2.64k | for (int i = i0; i < i1; i++) | 1314 | 2.05k | { | 1315 | 2.05k | int k = i * nCols + j0; | 1316 | 2.05k | int m = k * nDim + iDim; | 1317 | | | 1318 | 17.3k | for (int j = j0; j < j1; j++, k++, m += nDim) | 1319 | 15.3k | { | 1320 | 15.3k | double z = offset + *srcPtr++ * invScale; | 1321 | 15.3k | data[m] = (T)std::min(z, zMax); // make sure we stay in the orig range | 1322 | 15.3k | } | 1323 | 2.05k | } | 1324 | 587 | } | 1325 | 670 | else // not all valid | 1326 | 670 | { | 1327 | | #ifndef GDAL_COMPILATION | 1328 | | if (hd.version > 2) | 1329 | | { | 1330 | | for (int i = i0; i < i1; i++) | 1331 | | { | 1332 | | int k = i * nCols + j0; | 1333 | | int m = k * nDim + iDim; | 1334 | | | 1335 | | for (int j = j0; j < j1; j++, k++, m += nDim) | 1336 | | if (m_bitMask.IsValid(k)) | 1337 | | { | 1338 | | double z = offset + *srcPtr++ * invScale; | 1339 | | data[m] = (T)std::min(z, zMax); // make sure we stay in the orig range | 1340 | | } | 1341 | | } | 1342 | | } | 1343 | | else // fail gracefully in case of corrupted blob for old version <= 2 which had no checksum | 1344 | | #endif | 1345 | 670 | { | 1346 | 670 | size_t bufferVecIdx = 0; | 1347 | | | 1348 | 4.38k | for (int i = i0; i < i1; i++) | 1349 | 3.84k | { | 1350 | 3.84k | int k = i * nCols + j0; | 1351 | 3.84k | int m = k * nDim + iDim; | 1352 | | | 1353 | 45.8k | for (int j = j0; j < j1; j++, k++, m += nDim) | 1354 | 42.0k | if (m_bitMask.IsValid(k)) | 1355 | 10.5k | { | 1356 | 10.5k | if (bufferVecIdx == bufferVec.size()) // fail gracefully in case of corrupted blob for old version <= 2 which had no checksum | 1357 | 122 | return false; | 1358 | | | 1359 | 10.4k | double z = offset + bufferVec[bufferVecIdx] * invScale; | 1360 | 10.4k | bufferVecIdx++; | 1361 | 10.4k | data[m] = (T)std::min(z, zMax); // make sure we stay in the orig range | 1362 | 10.4k | } | 1363 | 3.84k | } | 1364 | 670 | } | 1365 | 670 | } | 1366 | 1.25k | } | 1367 | 2.48k | } | 1368 | | | 1369 | 56.9k | *ppByte = ptr; | 1370 | 56.9k | nBytesRemainingInOut = nBytesRemaining; | 1371 | 56.9k | return true; | 1372 | 60.9k | } |
bool GDAL_LercNS::Lerc2::ReadTile<unsigned short>(unsigned char const**, unsigned long&, unsigned short*, int, int, int, int, int, std::__1::vector<unsigned int, std::__1::allocator<unsigned int> >&) const Line | Count | Source | 1213 | 13.0k | { | 1214 | 13.0k | const Byte* ptr = *ppByte; | 1215 | 13.0k | size_t nBytesRemaining = nBytesRemainingInOut; | 1216 | | | 1217 | 13.0k | if (nBytesRemaining < 1) | 1218 | 90 | return false; | 1219 | | | 1220 | 12.9k | Byte comprFlag = *ptr++; | 1221 | 12.9k | nBytesRemaining--; | 1222 | | | 1223 | 12.9k | int bits67 = comprFlag >> 6; | 1224 | 12.9k | int testCode = (comprFlag >> 2) & 15; // use bits 2345 for integrity check | 1225 | 12.9k | if (testCode != ((j0 >> 3) & 15)) | 1226 | 938 | return false; | 1227 | | | 1228 | 11.9k | const HeaderInfo& hd = m_headerInfo; | 1229 | 11.9k | int nCols = hd.nCols; | 1230 | 11.9k | int nDim = hd.nDim; | 1231 | | | 1232 | 11.9k | comprFlag &= 3; | 1233 | | | 1234 | 11.9k | if (comprFlag == 2) // entire tile is constant 0 (all the valid pixels) | 1235 | 2.76k | { | 1236 | 8.89k | for (int i = i0; i < i1; i++) | 1237 | 6.12k | { | 1238 | 6.12k | int k = i * nCols + j0; | 1239 | 6.12k | int m = k * nDim + iDim; | 1240 | | | 1241 | 31.7k | for (int j = j0; j < j1; j++, k++, m += nDim) | 1242 | 25.6k | if (m_bitMask.IsValid(k)) | 1243 | 10.3k | data[m] = 0; | 1244 | 6.12k | } | 1245 | | | 1246 | 2.76k | *ppByte = ptr; | 1247 | 2.76k | nBytesRemainingInOut = nBytesRemaining; | 1248 | 2.76k | return true; | 1249 | 2.76k | } | 1250 | | | 1251 | 9.21k | else if (comprFlag == 0) // read z's binary uncompressed | 1252 | 5.99k | { | 1253 | 5.99k | const T* srcPtr = (const T*)ptr; | 1254 | 5.99k | int cnt = 0; | 1255 | | | 1256 | 20.2k | for (int i = i0; i < i1; i++) | 1257 | 14.4k | { | 1258 | 14.4k | int k = i * nCols + j0; | 1259 | 14.4k | int m = k * nDim + iDim; | 1260 | | | 1261 | 61.2k | for (int j = j0; j < j1; j++, k++, m += nDim) | 1262 | 46.9k | if (m_bitMask.IsValid(k)) | 1263 | 15.8k | { | 1264 | 15.8k | if (nBytesRemaining < sizeof(T)) | 1265 | 102 | return false; | 1266 | | | 1267 | 15.7k | data[m] = *srcPtr++; | 1268 | 15.7k | nBytesRemaining -= sizeof(T); | 1269 | | | 1270 | 15.7k | cnt++; | 1271 | 15.7k | } | 1272 | 14.4k | } | 1273 | | | 1274 | 5.89k | ptr += cnt * sizeof(T); | 1275 | 5.89k | } | 1276 | 3.21k | else | 1277 | 3.21k | { | 1278 | | // read z's as int arr bit stuffed | 1279 | 3.21k | DataType dtUsed = GetDataTypeUsed(bits67); | 1280 | 3.21k | if( dtUsed == DT_Undefined ) | 1281 | 64 | return false; | 1282 | 3.15k | size_t n = GetDataTypeSize(dtUsed); | 1283 | 3.15k | if (nBytesRemaining < n) | 1284 | 26 | return false; | 1285 | | | 1286 | 3.12k | double offset = ReadVariableDataType(&ptr, dtUsed); | 1287 | 3.12k | nBytesRemaining -= n; | 1288 | | | 1289 | 3.12k | if (comprFlag == 3) // entire tile is constant zMin (all the valid pixels) | 1290 | 1.29k | { | 1291 | 4.64k | for (int i = i0; i < i1; i++) | 1292 | 3.34k | { | 1293 | 3.34k | int k = i * nCols + j0; | 1294 | 3.34k | int m = k * nDim + iDim; | 1295 | | | 1296 | 21.7k | for (int j = j0; j < j1; j++, k++, m += nDim) | 1297 | 18.3k | if (m_bitMask.IsValid(k)) | 1298 | 5.19k | data[m] = (T)offset; | 1299 | 3.34k | } | 1300 | 1.29k | } | 1301 | 1.83k | else | 1302 | 1.83k | { | 1303 | 1.83k | size_t maxElementCount = (i1 - i0) * (j1 - j0); | 1304 | 1.83k | if (!m_bitStuffer2.Decode(&ptr, nBytesRemaining, bufferVec, maxElementCount, hd.version)) | 1305 | 1.17k | return false; | 1306 | | | 1307 | 655 | double invScale = 2 * hd.maxZError; // for int types this is int | 1308 | 655 | double zMax = (hd.version >= 4 && nDim > 1) ? m_zMaxVec[iDim] : hd.zMax; | 1309 | 655 | const unsigned int* srcPtr = bufferVec.data(); | 1310 | | | 1311 | 655 | if (bufferVec.size() == maxElementCount) // all valid | 1312 | 224 | { | 1313 | 1.08k | for (int i = i0; i < i1; i++) | 1314 | 863 | { | 1315 | 863 | int k = i * nCols + j0; | 1316 | 863 | int m = k * nDim + iDim; | 1317 | | | 1318 | 6.87k | for (int j = j0; j < j1; j++, k++, m += nDim) | 1319 | 6.01k | { | 1320 | 6.01k | double z = offset + *srcPtr++ * invScale; | 1321 | 6.01k | data[m] = (T)std::min(z, zMax); // make sure we stay in the orig range | 1322 | 6.01k | } | 1323 | 863 | } | 1324 | 224 | } | 1325 | 431 | else // not all valid | 1326 | 431 | { | 1327 | | #ifndef GDAL_COMPILATION | 1328 | | if (hd.version > 2) | 1329 | | { | 1330 | | for (int i = i0; i < i1; i++) | 1331 | | { | 1332 | | int k = i * nCols + j0; | 1333 | | int m = k * nDim + iDim; | 1334 | | | 1335 | | for (int j = j0; j < j1; j++, k++, m += nDim) | 1336 | | if (m_bitMask.IsValid(k)) | 1337 | | { | 1338 | | double z = offset + *srcPtr++ * invScale; | 1339 | | data[m] = (T)std::min(z, zMax); // make sure we stay in the orig range | 1340 | | } | 1341 | | } | 1342 | | } | 1343 | | else // fail gracefully in case of corrupted blob for old version <= 2 which had no checksum | 1344 | | #endif | 1345 | 431 | { | 1346 | 431 | size_t bufferVecIdx = 0; | 1347 | | | 1348 | 1.71k | for (int i = i0; i < i1; i++) | 1349 | 1.48k | { | 1350 | 1.48k | int k = i * nCols + j0; | 1351 | 1.48k | int m = k * nDim + iDim; | 1352 | | | 1353 | 18.8k | for (int j = j0; j < j1; j++, k++, m += nDim) | 1354 | 17.5k | if (m_bitMask.IsValid(k)) | 1355 | 3.52k | { | 1356 | 3.52k | if (bufferVecIdx == bufferVec.size()) // fail gracefully in case of corrupted blob for old version <= 2 which had no checksum | 1357 | 203 | return false; | 1358 | | | 1359 | 3.32k | double z = offset + bufferVec[bufferVecIdx] * invScale; | 1360 | 3.32k | bufferVecIdx++; | 1361 | 3.32k | data[m] = (T)std::min(z, zMax); // make sure we stay in the orig range | 1362 | 3.32k | } | 1363 | 1.48k | } | 1364 | 431 | } | 1365 | 431 | } | 1366 | 655 | } | 1367 | 3.12k | } | 1368 | | | 1369 | 7.64k | *ppByte = ptr; | 1370 | 7.64k | nBytesRemainingInOut = nBytesRemaining; | 1371 | 7.64k | return true; | 1372 | 11.9k | } |
bool GDAL_LercNS::Lerc2::ReadTile<int>(unsigned char const**, unsigned long&, int*, int, int, int, int, int, std::__1::vector<unsigned int, std::__1::allocator<unsigned int> >&) const Line | Count | Source | 1213 | 7.36k | { | 1214 | 7.36k | const Byte* ptr = *ppByte; | 1215 | 7.36k | size_t nBytesRemaining = nBytesRemainingInOut; | 1216 | | | 1217 | 7.36k | if (nBytesRemaining < 1) | 1218 | 61 | return false; | 1219 | | | 1220 | 7.30k | Byte comprFlag = *ptr++; | 1221 | 7.30k | nBytesRemaining--; | 1222 | | | 1223 | 7.30k | int bits67 = comprFlag >> 6; | 1224 | 7.30k | int testCode = (comprFlag >> 2) & 15; // use bits 2345 for integrity check | 1225 | 7.30k | if (testCode != ((j0 >> 3) & 15)) | 1226 | 521 | return false; | 1227 | | | 1228 | 6.78k | const HeaderInfo& hd = m_headerInfo; | 1229 | 6.78k | int nCols = hd.nCols; | 1230 | 6.78k | int nDim = hd.nDim; | 1231 | | | 1232 | 6.78k | comprFlag &= 3; | 1233 | | | 1234 | 6.78k | if (comprFlag == 2) // entire tile is constant 0 (all the valid pixels) | 1235 | 1.58k | { | 1236 | 9.28k | for (int i = i0; i < i1; i++) | 1237 | 7.69k | { | 1238 | 7.69k | int k = i * nCols + j0; | 1239 | 7.69k | int m = k * nDim + iDim; | 1240 | | | 1241 | 36.0k | for (int j = j0; j < j1; j++, k++, m += nDim) | 1242 | 28.3k | if (m_bitMask.IsValid(k)) | 1243 | 9.80k | data[m] = 0; | 1244 | 7.69k | } | 1245 | | | 1246 | 1.58k | *ppByte = ptr; | 1247 | 1.58k | nBytesRemainingInOut = nBytesRemaining; | 1248 | 1.58k | return true; | 1249 | 1.58k | } | 1250 | | | 1251 | 5.19k | else if (comprFlag == 0) // read z's binary uncompressed | 1252 | 3.39k | { | 1253 | 3.39k | const T* srcPtr = (const T*)ptr; | 1254 | 3.39k | int cnt = 0; | 1255 | | | 1256 | 11.9k | for (int i = i0; i < i1; i++) | 1257 | 8.64k | { | 1258 | 8.64k | int k = i * nCols + j0; | 1259 | 8.64k | int m = k * nDim + iDim; | 1260 | | | 1261 | 37.5k | for (int j = j0; j < j1; j++, k++, m += nDim) | 1262 | 29.0k | if (m_bitMask.IsValid(k)) | 1263 | 7.80k | { | 1264 | 7.80k | if (nBytesRemaining < sizeof(T)) | 1265 | 125 | return false; | 1266 | | | 1267 | 7.67k | data[m] = *srcPtr++; | 1268 | 7.67k | nBytesRemaining -= sizeof(T); | 1269 | | | 1270 | 7.67k | cnt++; | 1271 | 7.67k | } | 1272 | 8.64k | } | 1273 | | | 1274 | 3.26k | ptr += cnt * sizeof(T); | 1275 | 3.26k | } | 1276 | 1.80k | else | 1277 | 1.80k | { | 1278 | | // read z's as int arr bit stuffed | 1279 | 1.80k | DataType dtUsed = GetDataTypeUsed(bits67); | 1280 | 1.80k | if( dtUsed == DT_Undefined ) | 1281 | 0 | return false; | 1282 | 1.80k | size_t n = GetDataTypeSize(dtUsed); | 1283 | 1.80k | if (nBytesRemaining < n) | 1284 | 30 | return false; | 1285 | | | 1286 | 1.77k | double offset = ReadVariableDataType(&ptr, dtUsed); | 1287 | 1.77k | nBytesRemaining -= n; | 1288 | | | 1289 | 1.77k | if (comprFlag == 3) // entire tile is constant zMin (all the valid pixels) | 1290 | 1.23k | { | 1291 | 8.11k | for (int i = i0; i < i1; i++) | 1292 | 6.88k | { | 1293 | 6.88k | int k = i * nCols + j0; | 1294 | 6.88k | int m = k * nDim + iDim; | 1295 | | | 1296 | 36.4k | for (int j = j0; j < j1; j++, k++, m += nDim) | 1297 | 29.6k | if (m_bitMask.IsValid(k)) | 1298 | 8.37k | data[m] = (T)offset; | 1299 | 6.88k | } | 1300 | 1.23k | } | 1301 | 544 | else | 1302 | 544 | { | 1303 | 544 | size_t maxElementCount = (i1 - i0) * (j1 - j0); | 1304 | 544 | if (!m_bitStuffer2.Decode(&ptr, nBytesRemaining, bufferVec, maxElementCount, hd.version)) | 1305 | 143 | return false; | 1306 | | | 1307 | 401 | double invScale = 2 * hd.maxZError; // for int types this is int | 1308 | 401 | double zMax = (hd.version >= 4 && nDim > 1) ? m_zMaxVec[iDim] : hd.zMax; | 1309 | 401 | const unsigned int* srcPtr = bufferVec.data(); | 1310 | | | 1311 | 401 | if (bufferVec.size() == maxElementCount) // all valid | 1312 | 139 | { | 1313 | 1.92k | for (int i = i0; i < i1; i++) | 1314 | 1.78k | { | 1315 | 1.78k | int k = i * nCols + j0; | 1316 | 1.78k | int m = k * nDim + iDim; | 1317 | | | 1318 | 29.5k | for (int j = j0; j < j1; j++, k++, m += nDim) | 1319 | 27.7k | { | 1320 | 27.7k | double z = offset + *srcPtr++ * invScale; | 1321 | 27.7k | data[m] = (T)std::min(z, zMax); // make sure we stay in the orig range | 1322 | 27.7k | } | 1323 | 1.78k | } | 1324 | 139 | } | 1325 | 262 | else // not all valid | 1326 | 262 | { | 1327 | | #ifndef GDAL_COMPILATION | 1328 | | if (hd.version > 2) | 1329 | | { | 1330 | | for (int i = i0; i < i1; i++) | 1331 | | { | 1332 | | int k = i * nCols + j0; | 1333 | | int m = k * nDim + iDim; | 1334 | | | 1335 | | for (int j = j0; j < j1; j++, k++, m += nDim) | 1336 | | if (m_bitMask.IsValid(k)) | 1337 | | { | 1338 | | double z = offset + *srcPtr++ * invScale; | 1339 | | data[m] = (T)std::min(z, zMax); // make sure we stay in the orig range | 1340 | | } | 1341 | | } | 1342 | | } | 1343 | | else // fail gracefully in case of corrupted blob for old version <= 2 which had no checksum | 1344 | | #endif | 1345 | 262 | { | 1346 | 262 | size_t bufferVecIdx = 0; | 1347 | | | 1348 | 1.80k | for (int i = i0; i < i1; i++) | 1349 | 1.58k | { | 1350 | 1.58k | int k = i * nCols + j0; | 1351 | 1.58k | int m = k * nDim + iDim; | 1352 | | | 1353 | 23.8k | for (int j = j0; j < j1; j++, k++, m += nDim) | 1354 | 22.3k | if (m_bitMask.IsValid(k)) | 1355 | 5.12k | { | 1356 | 5.12k | if (bufferVecIdx == bufferVec.size()) // fail gracefully in case of corrupted blob for old version <= 2 which had no checksum | 1357 | 46 | return false; | 1358 | | | 1359 | 5.08k | double z = offset + bufferVec[bufferVecIdx] * invScale; | 1360 | 5.08k | bufferVecIdx++; | 1361 | 5.08k | data[m] = (T)std::min(z, zMax); // make sure we stay in the orig range | 1362 | 5.08k | } | 1363 | 1.58k | } | 1364 | 262 | } | 1365 | 262 | } | 1366 | 401 | } | 1367 | 1.77k | } | 1368 | | | 1369 | 4.85k | *ppByte = ptr; | 1370 | 4.85k | nBytesRemainingInOut = nBytesRemaining; | 1371 | 4.85k | return true; | 1372 | 6.78k | } |
bool GDAL_LercNS::Lerc2::ReadTile<unsigned int>(unsigned char const**, unsigned long&, unsigned int*, int, int, int, int, int, std::__1::vector<unsigned int, std::__1::allocator<unsigned int> >&) const Line | Count | Source | 1213 | 255k | { | 1214 | 255k | const Byte* ptr = *ppByte; | 1215 | 255k | size_t nBytesRemaining = nBytesRemainingInOut; | 1216 | | | 1217 | 255k | if (nBytesRemaining < 1) | 1218 | 126 | return false; | 1219 | | | 1220 | 255k | Byte comprFlag = *ptr++; | 1221 | 255k | nBytesRemaining--; | 1222 | | | 1223 | 255k | int bits67 = comprFlag >> 6; | 1224 | 255k | int testCode = (comprFlag >> 2) & 15; // use bits 2345 for integrity check | 1225 | 255k | if (testCode != ((j0 >> 3) & 15)) | 1226 | 1.41k | return false; | 1227 | | | 1228 | 253k | const HeaderInfo& hd = m_headerInfo; | 1229 | 253k | int nCols = hd.nCols; | 1230 | 253k | int nDim = hd.nDim; | 1231 | | | 1232 | 253k | comprFlag &= 3; | 1233 | | | 1234 | 253k | if (comprFlag == 2) // entire tile is constant 0 (all the valid pixels) | 1235 | 2.70k | { | 1236 | 11.5k | for (int i = i0; i < i1; i++) | 1237 | 8.86k | { | 1238 | 8.86k | int k = i * nCols + j0; | 1239 | 8.86k | int m = k * nDim + iDim; | 1240 | | | 1241 | 127k | for (int j = j0; j < j1; j++, k++, m += nDim) | 1242 | 118k | if (m_bitMask.IsValid(k)) | 1243 | 12.8k | data[m] = 0; | 1244 | 8.86k | } | 1245 | | | 1246 | 2.70k | *ppByte = ptr; | 1247 | 2.70k | nBytesRemainingInOut = nBytesRemaining; | 1248 | 2.70k | return true; | 1249 | 2.70k | } | 1250 | | | 1251 | 250k | else if (comprFlag == 0) // read z's binary uncompressed | 1252 | 246k | { | 1253 | 246k | const T* srcPtr = (const T*)ptr; | 1254 | 246k | int cnt = 0; | 1255 | | | 1256 | 738k | for (int i = i0; i < i1; i++) | 1257 | 492k | { | 1258 | 492k | int k = i * nCols + j0; | 1259 | 492k | int m = k * nDim + iDim; | 1260 | | | 1261 | 1.25M | for (int j = j0; j < j1; j++, k++, m += nDim) | 1262 | 766k | if (m_bitMask.IsValid(k)) | 1263 | 61.6k | { | 1264 | 61.6k | if (nBytesRemaining < sizeof(T)) | 1265 | 148 | return false; | 1266 | | | 1267 | 61.5k | data[m] = *srcPtr++; | 1268 | 61.5k | nBytesRemaining -= sizeof(T); | 1269 | | | 1270 | 61.5k | cnt++; | 1271 | 61.5k | } | 1272 | 492k | } | 1273 | | | 1274 | 246k | ptr += cnt * sizeof(T); | 1275 | 246k | } | 1276 | 4.73k | else | 1277 | 4.73k | { | 1278 | | // read z's as int arr bit stuffed | 1279 | 4.73k | DataType dtUsed = GetDataTypeUsed(bits67); | 1280 | 4.73k | if( dtUsed == DT_Undefined ) | 1281 | 44 | return false; | 1282 | 4.69k | size_t n = GetDataTypeSize(dtUsed); | 1283 | 4.69k | if (nBytesRemaining < n) | 1284 | 82 | return false; | 1285 | | | 1286 | 4.60k | double offset = ReadVariableDataType(&ptr, dtUsed); | 1287 | 4.60k | nBytesRemaining -= n; | 1288 | | | 1289 | 4.60k | if (comprFlag == 3) // entire tile is constant zMin (all the valid pixels) | 1290 | 3.24k | { | 1291 | 11.3k | for (int i = i0; i < i1; i++) | 1292 | 8.13k | { | 1293 | 8.13k | int k = i * nCols + j0; | 1294 | 8.13k | int m = k * nDim + iDim; | 1295 | | | 1296 | 89.6k | for (int j = j0; j < j1; j++, k++, m += nDim) | 1297 | 81.5k | if (m_bitMask.IsValid(k)) | 1298 | 9.91k | data[m] = (T)offset; | 1299 | 8.13k | } | 1300 | 3.24k | } | 1301 | 1.36k | else | 1302 | 1.36k | { | 1303 | 1.36k | size_t maxElementCount = (i1 - i0) * (j1 - j0); | 1304 | 1.36k | if (!m_bitStuffer2.Decode(&ptr, nBytesRemaining, bufferVec, maxElementCount, hd.version)) | 1305 | 282 | return false; | 1306 | | | 1307 | 1.08k | double invScale = 2 * hd.maxZError; // for int types this is int | 1308 | 1.08k | double zMax = (hd.version >= 4 && nDim > 1) ? m_zMaxVec[iDim] : hd.zMax; | 1309 | 1.08k | const unsigned int* srcPtr = bufferVec.data(); | 1310 | | | 1311 | 1.08k | if (bufferVec.size() == maxElementCount) // all valid | 1312 | 358 | { | 1313 | 2.86k | for (int i = i0; i < i1; i++) | 1314 | 2.50k | { | 1315 | 2.50k | int k = i * nCols + j0; | 1316 | 2.50k | int m = k * nDim + iDim; | 1317 | | | 1318 | 38.2k | for (int j = j0; j < j1; j++, k++, m += nDim) | 1319 | 35.7k | { | 1320 | 35.7k | double z = offset + *srcPtr++ * invScale; | 1321 | 35.7k | data[m] = (T)std::min(z, zMax); // make sure we stay in the orig range | 1322 | 35.7k | } | 1323 | 2.50k | } | 1324 | 358 | } | 1325 | 726 | else // not all valid | 1326 | 726 | { | 1327 | | #ifndef GDAL_COMPILATION | 1328 | | if (hd.version > 2) | 1329 | | { | 1330 | | for (int i = i0; i < i1; i++) | 1331 | | { | 1332 | | int k = i * nCols + j0; | 1333 | | int m = k * nDim + iDim; | 1334 | | | 1335 | | for (int j = j0; j < j1; j++, k++, m += nDim) | 1336 | | if (m_bitMask.IsValid(k)) | 1337 | | { | 1338 | | double z = offset + *srcPtr++ * invScale; | 1339 | | data[m] = (T)std::min(z, zMax); // make sure we stay in the orig range | 1340 | | } | 1341 | | } | 1342 | | } | 1343 | | else // fail gracefully in case of corrupted blob for old version <= 2 which had no checksum | 1344 | | #endif | 1345 | 726 | { | 1346 | 726 | size_t bufferVecIdx = 0; | 1347 | | | 1348 | 3.98k | for (int i = i0; i < i1; i++) | 1349 | 3.34k | { | 1350 | 3.34k | int k = i * nCols + j0; | 1351 | 3.34k | int m = k * nDim + iDim; | 1352 | | | 1353 | 53.0k | for (int j = j0; j < j1; j++, k++, m += nDim) | 1354 | 49.8k | if (m_bitMask.IsValid(k)) | 1355 | 5.81k | { | 1356 | 5.81k | if (bufferVecIdx == bufferVec.size()) // fail gracefully in case of corrupted blob for old version <= 2 which had no checksum | 1357 | 84 | return false; | 1358 | | | 1359 | 5.72k | double z = offset + bufferVec[bufferVecIdx] * invScale; | 1360 | 5.72k | bufferVecIdx++; | 1361 | 5.72k | data[m] = (T)std::min(z, zMax); // make sure we stay in the orig range | 1362 | 5.72k | } | 1363 | 3.34k | } | 1364 | 726 | } | 1365 | 726 | } | 1366 | 1.08k | } | 1367 | 4.60k | } | 1368 | | | 1369 | 250k | *ppByte = ptr; | 1370 | 250k | nBytesRemainingInOut = nBytesRemaining; | 1371 | 250k | return true; | 1372 | 253k | } |
bool GDAL_LercNS::Lerc2::ReadTile<float>(unsigned char const**, unsigned long&, float*, int, int, int, int, int, std::__1::vector<unsigned int, std::__1::allocator<unsigned int> >&) const Line | Count | Source | 1213 | 7.25k | { | 1214 | 7.25k | const Byte* ptr = *ppByte; | 1215 | 7.25k | size_t nBytesRemaining = nBytesRemainingInOut; | 1216 | | | 1217 | 7.25k | if (nBytesRemaining < 1) | 1218 | 34 | return false; | 1219 | | | 1220 | 7.21k | Byte comprFlag = *ptr++; | 1221 | 7.21k | nBytesRemaining--; | 1222 | | | 1223 | 7.21k | int bits67 = comprFlag >> 6; | 1224 | 7.21k | int testCode = (comprFlag >> 2) & 15; // use bits 2345 for integrity check | 1225 | 7.21k | if (testCode != ((j0 >> 3) & 15)) | 1226 | 309 | return false; | 1227 | | | 1228 | 6.90k | const HeaderInfo& hd = m_headerInfo; | 1229 | 6.90k | int nCols = hd.nCols; | 1230 | 6.90k | int nDim = hd.nDim; | 1231 | | | 1232 | 6.90k | comprFlag &= 3; | 1233 | | | 1234 | 6.90k | if (comprFlag == 2) // entire tile is constant 0 (all the valid pixels) | 1235 | 1.21k | { | 1236 | 3.64k | for (int i = i0; i < i1; i++) | 1237 | 2.42k | { | 1238 | 2.42k | int k = i * nCols + j0; | 1239 | 2.42k | int m = k * nDim + iDim; | 1240 | | | 1241 | 6.97k | for (int j = j0; j < j1; j++, k++, m += nDim) | 1242 | 4.54k | if (m_bitMask.IsValid(k)) | 1243 | 1.38k | data[m] = 0; | 1244 | 2.42k | } | 1245 | | | 1246 | 1.21k | *ppByte = ptr; | 1247 | 1.21k | nBytesRemainingInOut = nBytesRemaining; | 1248 | 1.21k | return true; | 1249 | 1.21k | } | 1250 | | | 1251 | 5.69k | else if (comprFlag == 0) // read z's binary uncompressed | 1252 | 2.75k | { | 1253 | 2.75k | const T* srcPtr = (const T*)ptr; | 1254 | 2.75k | int cnt = 0; | 1255 | | | 1256 | 9.05k | for (int i = i0; i < i1; i++) | 1257 | 6.37k | { | 1258 | 6.37k | int k = i * nCols + j0; | 1259 | 6.37k | int m = k * nDim + iDim; | 1260 | | | 1261 | 40.1k | for (int j = j0; j < j1; j++, k++, m += nDim) | 1262 | 33.8k | if (m_bitMask.IsValid(k)) | 1263 | 20.1k | { | 1264 | 20.1k | if (nBytesRemaining < sizeof(T)) | 1265 | 78 | return false; | 1266 | | | 1267 | 20.1k | data[m] = *srcPtr++; | 1268 | 20.1k | nBytesRemaining -= sizeof(T); | 1269 | | | 1270 | 20.1k | cnt++; | 1271 | 20.1k | } | 1272 | 6.37k | } | 1273 | | | 1274 | 2.68k | ptr += cnt * sizeof(T); | 1275 | 2.68k | } | 1276 | 2.93k | else | 1277 | 2.93k | { | 1278 | | // read z's as int arr bit stuffed | 1279 | 2.93k | DataType dtUsed = GetDataTypeUsed(bits67); | 1280 | 2.93k | if( dtUsed == DT_Undefined ) | 1281 | 0 | return false; | 1282 | 2.93k | size_t n = GetDataTypeSize(dtUsed); | 1283 | 2.93k | if (nBytesRemaining < n) | 1284 | 14 | return false; | 1285 | | | 1286 | 2.91k | double offset = ReadVariableDataType(&ptr, dtUsed); | 1287 | 2.91k | nBytesRemaining -= n; | 1288 | | | 1289 | 2.91k | if (comprFlag == 3) // entire tile is constant zMin (all the valid pixels) | 1290 | 2.45k | { | 1291 | 5.78k | for (int i = i0; i < i1; i++) | 1292 | 3.33k | { | 1293 | 3.33k | int k = i * nCols + j0; | 1294 | 3.33k | int m = k * nDim + iDim; | 1295 | | | 1296 | 9.16k | for (int j = j0; j < j1; j++, k++, m += nDim) | 1297 | 5.83k | if (m_bitMask.IsValid(k)) | 1298 | 2.39k | data[m] = (T)offset; | 1299 | 3.33k | } | 1300 | 2.45k | } | 1301 | 463 | else | 1302 | 463 | { | 1303 | 463 | size_t maxElementCount = (i1 - i0) * (j1 - j0); | 1304 | 463 | if (!m_bitStuffer2.Decode(&ptr, nBytesRemaining, bufferVec, maxElementCount, hd.version)) | 1305 | 100 | return false; | 1306 | | | 1307 | 363 | double invScale = 2 * hd.maxZError; // for int types this is int | 1308 | 363 | double zMax = (hd.version >= 4 && nDim > 1) ? m_zMaxVec[iDim] : hd.zMax; | 1309 | 363 | const unsigned int* srcPtr = bufferVec.data(); | 1310 | | | 1311 | 363 | if (bufferVec.size() == maxElementCount) // all valid | 1312 | 97 | { | 1313 | 291 | for (int i = i0; i < i1; i++) | 1314 | 194 | { | 1315 | 194 | int k = i * nCols + j0; | 1316 | 194 | int m = k * nDim + iDim; | 1317 | | | 1318 | 580 | for (int j = j0; j < j1; j++, k++, m += nDim) | 1319 | 386 | { | 1320 | 386 | double z = offset + *srcPtr++ * invScale; | 1321 | 386 | data[m] = (T)std::min(z, zMax); // make sure we stay in the orig range | 1322 | 386 | } | 1323 | 194 | } | 1324 | 97 | } | 1325 | 266 | else // not all valid | 1326 | 266 | { | 1327 | | #ifndef GDAL_COMPILATION | 1328 | | if (hd.version > 2) | 1329 | | { | 1330 | | for (int i = i0; i < i1; i++) | 1331 | | { | 1332 | | int k = i * nCols + j0; | 1333 | | int m = k * nDim + iDim; | 1334 | | | 1335 | | for (int j = j0; j < j1; j++, k++, m += nDim) | 1336 | | if (m_bitMask.IsValid(k)) | 1337 | | { | 1338 | | double z = offset + *srcPtr++ * invScale; | 1339 | | data[m] = (T)std::min(z, zMax); // make sure we stay in the orig range | 1340 | | } | 1341 | | } | 1342 | | } | 1343 | | else // fail gracefully in case of corrupted blob for old version <= 2 which had no checksum | 1344 | | #endif | 1345 | 266 | { | 1346 | 266 | size_t bufferVecIdx = 0; | 1347 | | | 1348 | 766 | for (int i = i0; i < i1; i++) | 1349 | 533 | { | 1350 | 533 | int k = i * nCols + j0; | 1351 | 533 | int m = k * nDim + iDim; | 1352 | | | 1353 | 1.84k | for (int j = j0; j < j1; j++, k++, m += nDim) | 1354 | 1.34k | if (m_bitMask.IsValid(k)) | 1355 | 462 | { | 1356 | 462 | if (bufferVecIdx == bufferVec.size()) // fail gracefully in case of corrupted blob for old version <= 2 which had no checksum | 1357 | 33 | return false; | 1358 | | | 1359 | 429 | double z = offset + bufferVec[bufferVecIdx] * invScale; | 1360 | 429 | bufferVecIdx++; | 1361 | 429 | data[m] = (T)std::min(z, zMax); // make sure we stay in the orig range | 1362 | 429 | } | 1363 | 533 | } | 1364 | 266 | } | 1365 | 266 | } | 1366 | 363 | } | 1367 | 2.91k | } | 1368 | | | 1369 | 5.46k | *ppByte = ptr; | 1370 | 5.46k | nBytesRemainingInOut = nBytesRemaining; | 1371 | 5.46k | return true; | 1372 | 6.90k | } |
bool GDAL_LercNS::Lerc2::ReadTile<double>(unsigned char const**, unsigned long&, double*, int, int, int, int, int, std::__1::vector<unsigned int, std::__1::allocator<unsigned int> >&) const Line | Count | Source | 1213 | 4.54k | { | 1214 | 4.54k | const Byte* ptr = *ppByte; | 1215 | 4.54k | size_t nBytesRemaining = nBytesRemainingInOut; | 1216 | | | 1217 | 4.54k | if (nBytesRemaining < 1) | 1218 | 56 | return false; | 1219 | | | 1220 | 4.48k | Byte comprFlag = *ptr++; | 1221 | 4.48k | nBytesRemaining--; | 1222 | | | 1223 | 4.48k | int bits67 = comprFlag >> 6; | 1224 | 4.48k | int testCode = (comprFlag >> 2) & 15; // use bits 2345 for integrity check | 1225 | 4.48k | if (testCode != ((j0 >> 3) & 15)) | 1226 | 248 | return false; | 1227 | | | 1228 | 4.23k | const HeaderInfo& hd = m_headerInfo; | 1229 | 4.23k | int nCols = hd.nCols; | 1230 | 4.23k | int nDim = hd.nDim; | 1231 | | | 1232 | 4.23k | comprFlag &= 3; | 1233 | | | 1234 | 4.23k | if (comprFlag == 2) // entire tile is constant 0 (all the valid pixels) | 1235 | 1.18k | { | 1236 | 4.01k | for (int i = i0; i < i1; i++) | 1237 | 2.82k | { | 1238 | 2.82k | int k = i * nCols + j0; | 1239 | 2.82k | int m = k * nDim + iDim; | 1240 | | | 1241 | 8.79k | for (int j = j0; j < j1; j++, k++, m += nDim) | 1242 | 5.96k | if (m_bitMask.IsValid(k)) | 1243 | 2.23k | data[m] = 0; | 1244 | 2.82k | } | 1245 | | | 1246 | 1.18k | *ppByte = ptr; | 1247 | 1.18k | nBytesRemainingInOut = nBytesRemaining; | 1248 | 1.18k | return true; | 1249 | 1.18k | } | 1250 | | | 1251 | 3.05k | else if (comprFlag == 0) // read z's binary uncompressed | 1252 | 2.19k | { | 1253 | 2.19k | const T* srcPtr = (const T*)ptr; | 1254 | 2.19k | int cnt = 0; | 1255 | | | 1256 | 16.0k | for (int i = i0; i < i1; i++) | 1257 | 13.9k | { | 1258 | 13.9k | int k = i * nCols + j0; | 1259 | 13.9k | int m = k * nDim + iDim; | 1260 | | | 1261 | 55.3k | for (int j = j0; j < j1; j++, k++, m += nDim) | 1262 | 41.5k | if (m_bitMask.IsValid(k)) | 1263 | 2.89k | { | 1264 | 2.89k | if (nBytesRemaining < sizeof(T)) | 1265 | 94 | return false; | 1266 | | | 1267 | 2.80k | data[m] = *srcPtr++; | 1268 | 2.80k | nBytesRemaining -= sizeof(T); | 1269 | | | 1270 | 2.80k | cnt++; | 1271 | 2.80k | } | 1272 | 13.9k | } | 1273 | | | 1274 | 2.09k | ptr += cnt * sizeof(T); | 1275 | 2.09k | } | 1276 | 858 | else | 1277 | 858 | { | 1278 | | // read z's as int arr bit stuffed | 1279 | 858 | DataType dtUsed = GetDataTypeUsed(bits67); | 1280 | 858 | if( dtUsed == DT_Undefined ) | 1281 | 0 | return false; | 1282 | 858 | size_t n = GetDataTypeSize(dtUsed); | 1283 | 858 | if (nBytesRemaining < n) | 1284 | 41 | return false; | 1285 | | | 1286 | 817 | double offset = ReadVariableDataType(&ptr, dtUsed); | 1287 | 817 | nBytesRemaining -= n; | 1288 | | | 1289 | 817 | if (comprFlag == 3) // entire tile is constant zMin (all the valid pixels) | 1290 | 710 | { | 1291 | 1.72k | for (int i = i0; i < i1; i++) | 1292 | 1.01k | { | 1293 | 1.01k | int k = i * nCols + j0; | 1294 | 1.01k | int m = k * nDim + iDim; | 1295 | | | 1296 | 3.13k | for (int j = j0; j < j1; j++, k++, m += nDim) | 1297 | 2.11k | if (m_bitMask.IsValid(k)) | 1298 | 961 | data[m] = (T)offset; | 1299 | 1.01k | } | 1300 | 710 | } | 1301 | 107 | else | 1302 | 107 | { | 1303 | 107 | size_t maxElementCount = (i1 - i0) * (j1 - j0); | 1304 | 107 | if (!m_bitStuffer2.Decode(&ptr, nBytesRemaining, bufferVec, maxElementCount, hd.version)) | 1305 | 47 | return false; | 1306 | | | 1307 | 60 | double invScale = 2 * hd.maxZError; // for int types this is int | 1308 | 60 | double zMax = (hd.version >= 4 && nDim > 1) ? m_zMaxVec[iDim] : hd.zMax; | 1309 | 60 | const unsigned int* srcPtr = bufferVec.data(); | 1310 | | | 1311 | 60 | if (bufferVec.size() == maxElementCount) // all valid | 1312 | 0 | { | 1313 | 0 | for (int i = i0; i < i1; i++) | 1314 | 0 | { | 1315 | 0 | int k = i * nCols + j0; | 1316 | 0 | int m = k * nDim + iDim; | 1317 | |
| 1318 | 0 | for (int j = j0; j < j1; j++, k++, m += nDim) | 1319 | 0 | { | 1320 | 0 | double z = offset + *srcPtr++ * invScale; | 1321 | 0 | data[m] = (T)std::min(z, zMax); // make sure we stay in the orig range | 1322 | 0 | } | 1323 | 0 | } | 1324 | 0 | } | 1325 | 60 | else // not all valid | 1326 | 60 | { | 1327 | | #ifndef GDAL_COMPILATION | 1328 | | if (hd.version > 2) | 1329 | | { | 1330 | | for (int i = i0; i < i1; i++) | 1331 | | { | 1332 | | int k = i * nCols + j0; | 1333 | | int m = k * nDim + iDim; | 1334 | | | 1335 | | for (int j = j0; j < j1; j++, k++, m += nDim) | 1336 | | if (m_bitMask.IsValid(k)) | 1337 | | { | 1338 | | double z = offset + *srcPtr++ * invScale; | 1339 | | data[m] = (T)std::min(z, zMax); // make sure we stay in the orig range | 1340 | | } | 1341 | | } | 1342 | | } | 1343 | | else // fail gracefully in case of corrupted blob for old version <= 2 which had no checksum | 1344 | | #endif | 1345 | 60 | { | 1346 | 60 | size_t bufferVecIdx = 0; | 1347 | | | 1348 | 211 | for (int i = i0; i < i1; i++) | 1349 | 190 | { | 1350 | 190 | int k = i * nCols + j0; | 1351 | 190 | int m = k * nDim + iDim; | 1352 | | | 1353 | 1.23k | for (int j = j0; j < j1; j++, k++, m += nDim) | 1354 | 1.08k | if (m_bitMask.IsValid(k)) | 1355 | 160 | { | 1356 | 160 | if (bufferVecIdx == bufferVec.size()) // fail gracefully in case of corrupted blob for old version <= 2 which had no checksum | 1357 | 39 | return false; | 1358 | | | 1359 | 121 | double z = offset + bufferVec[bufferVecIdx] * invScale; | 1360 | 121 | bufferVecIdx++; | 1361 | 121 | data[m] = (T)std::min(z, zMax); // make sure we stay in the orig range | 1362 | 121 | } | 1363 | 190 | } | 1364 | 60 | } | 1365 | 60 | } | 1366 | 60 | } | 1367 | 817 | } | 1368 | | | 1369 | 2.82k | *ppByte = ptr; | 1370 | 2.82k | nBytesRemainingInOut = nBytesRemaining; | 1371 | 2.82k | return true; | 1372 | 4.23k | } |
|
1373 | | |
1374 | | // -------------------------------------------------------------------------- ; |
1375 | | |
1376 | | template<class T> |
1377 | | int Lerc2::TypeCode(T z, DataType& dtUsed) const |
1378 | 0 | { |
1379 | 0 | Byte b = (Byte)z; |
1380 | 0 | DataType dt = m_headerInfo.dt; |
1381 | 0 | switch (dt) |
1382 | 0 | { |
1383 | 0 | case DT_Short: |
1384 | 0 | { |
1385 | 0 | signed char c = (signed char)z; |
1386 | 0 | int tc = (T)c == z ? 2 : (T)b == z ? 1 : 0; |
1387 | 0 | dtUsed = (DataType)(dt - tc); |
1388 | 0 | return tc; |
1389 | 0 | } |
1390 | 0 | case DT_UShort: |
1391 | 0 | { |
1392 | 0 | int tc = (T)b == z ? 1 : 0; |
1393 | 0 | dtUsed = (DataType)(dt - 2 * tc); |
1394 | 0 | return tc; |
1395 | 0 | } |
1396 | 0 | case DT_Int: |
1397 | 0 | { |
1398 | 0 | short s = (short)z; |
1399 | 0 | unsigned short us = (unsigned short)z; |
1400 | 0 | int tc = (T)b == z ? 3 : (T)s == z ? 2 : (T)us == z ? 1 : 0; |
1401 | 0 | dtUsed = (DataType)(dt - tc); |
1402 | 0 | return tc; |
1403 | 0 | } |
1404 | 0 | case DT_UInt: |
1405 | 0 | { |
1406 | 0 | unsigned short us = (unsigned short)z; |
1407 | 0 | int tc = (T)b == z ? 2 : (T)us == z ? 1 : 0; |
1408 | 0 | dtUsed = (DataType)(dt - 2 * tc); |
1409 | 0 | return tc; |
1410 | 0 | } |
1411 | 0 | case DT_Float: |
1412 | 0 | { |
1413 | 0 | short s = (short)z; |
1414 | 0 | int tc = (T)b == z ? 2 : (T)s == z ? 1 : 0; |
1415 | 0 | dtUsed = tc == 0 ? dt : (tc == 1 ? DT_Short : DT_Byte); |
1416 | 0 | return tc; |
1417 | 0 | } |
1418 | 0 | case DT_Double: |
1419 | 0 | { |
1420 | 0 | short s = (short)z; |
1421 | 0 | int l = (int)z; |
1422 | 0 | float f = (float)z; |
1423 | 0 | int tc = (T)s == z ? 3 : (T)l == z ? 2 : (T)f == z ? 1 : 0; |
1424 | 0 | dtUsed = tc == 0 ? dt : (DataType)(dt - 2 * tc + 1); |
1425 | 0 | return tc; |
1426 | 0 | } |
1427 | 0 | default: |
1428 | 0 | { |
1429 | 0 | dtUsed = dt; |
1430 | 0 | return 0; |
1431 | 0 | } |
1432 | 0 | } |
1433 | 0 | } Unexecuted instantiation: int GDAL_LercNS::Lerc2::TypeCode<signed char>(signed char, GDAL_LercNS::Lerc2::DataType&) const Unexecuted instantiation: int GDAL_LercNS::Lerc2::TypeCode<unsigned char>(unsigned char, GDAL_LercNS::Lerc2::DataType&) const Unexecuted instantiation: int GDAL_LercNS::Lerc2::TypeCode<short>(short, GDAL_LercNS::Lerc2::DataType&) const Unexecuted instantiation: int GDAL_LercNS::Lerc2::TypeCode<unsigned short>(unsigned short, GDAL_LercNS::Lerc2::DataType&) const Unexecuted instantiation: int GDAL_LercNS::Lerc2::TypeCode<int>(int, GDAL_LercNS::Lerc2::DataType&) const Unexecuted instantiation: int GDAL_LercNS::Lerc2::TypeCode<unsigned int>(unsigned int, GDAL_LercNS::Lerc2::DataType&) const Unexecuted instantiation: int GDAL_LercNS::Lerc2::TypeCode<float>(float, GDAL_LercNS::Lerc2::DataType&) const Unexecuted instantiation: int GDAL_LercNS::Lerc2::TypeCode<double>(double, GDAL_LercNS::Lerc2::DataType&) const |
1434 | | |
1435 | | // -------------------------------------------------------------------------- ; |
1436 | | |
1437 | | inline Lerc2::DataType Lerc2::ValidateDataType(int dt) |
1438 | 13.0k | { |
1439 | 13.0k | if( dt >= DT_Char && dt <= DT_Double ) |
1440 | 12.8k | return static_cast<DataType>(dt); |
1441 | 147 | return DT_Undefined; |
1442 | 13.0k | } |
1443 | | |
1444 | | // -------------------------------------------------------------------------- ; |
1445 | | |
1446 | | inline |
1447 | | Lerc2::DataType Lerc2::GetDataTypeUsed(int tc) const |
1448 | 32.4k | { |
1449 | 32.4k | DataType dt = m_headerInfo.dt; |
1450 | 32.4k | switch (dt) |
1451 | 32.4k | { |
1452 | 2.55k | case DT_Short: |
1453 | 4.36k | case DT_Int: return ValidateDataType(dt - tc); |
1454 | 3.21k | case DT_UShort: |
1455 | 7.95k | case DT_UInt: return ValidateDataType(dt - 2 * tc); |
1456 | 2.93k | case DT_Float: return tc == 0 ? dt : (tc == 1 ? DT_Short : DT_Byte); |
1457 | 858 | case DT_Double: return tc == 0 ? dt : ValidateDataType(dt - 2 * tc + 1); |
1458 | 16.3k | default: |
1459 | 16.3k | return dt; |
1460 | 32.4k | } |
1461 | 32.4k | } |
1462 | | |
1463 | | // -------------------------------------------------------------------------- ; |
1464 | | |
1465 | | inline |
1466 | | bool Lerc2::WriteVariableDataType(Byte** ppByte, double z, DataType dtUsed) |
1467 | 0 | { |
1468 | 0 | Byte* ptr = *ppByte; |
1469 | |
|
1470 | 0 | switch (dtUsed) |
1471 | 0 | { |
1472 | 0 | case DT_Char: |
1473 | 0 | { |
1474 | 0 | *((signed char*)ptr) = (signed char)z; |
1475 | 0 | ptr++; |
1476 | 0 | break; |
1477 | 0 | } |
1478 | 0 | case DT_Byte: |
1479 | 0 | { |
1480 | 0 | *((Byte*)ptr) = (Byte)z; |
1481 | 0 | ptr++; |
1482 | 0 | break; |
1483 | 0 | } |
1484 | 0 | case DT_Short: |
1485 | 0 | { |
1486 | 0 | short s = (short)z; |
1487 | 0 | memcpy(ptr, &s, sizeof(short)); |
1488 | 0 | ptr += 2; |
1489 | 0 | break; |
1490 | 0 | } |
1491 | 0 | case DT_UShort: |
1492 | 0 | { |
1493 | 0 | unsigned short us = (unsigned short)z; |
1494 | 0 | memcpy(ptr, &us, sizeof(unsigned short)); |
1495 | 0 | ptr += 2; |
1496 | 0 | break; |
1497 | 0 | } |
1498 | 0 | case DT_Int: |
1499 | 0 | { |
1500 | 0 | int i = (int)z; |
1501 | 0 | memcpy(ptr, &i, sizeof(int)); |
1502 | 0 | ptr += 4; |
1503 | 0 | break; |
1504 | 0 | } |
1505 | 0 | case DT_UInt: |
1506 | 0 | { |
1507 | 0 | unsigned int n = (unsigned int)z; |
1508 | 0 | memcpy(ptr, &n, sizeof(unsigned int)); |
1509 | 0 | ptr += 4; |
1510 | 0 | break; |
1511 | 0 | } |
1512 | 0 | case DT_Float: |
1513 | 0 | { |
1514 | 0 | float f = (float)z; |
1515 | 0 | memcpy(ptr, &f, sizeof(float)); |
1516 | 0 | ptr += 4; |
1517 | 0 | break; |
1518 | 0 | } |
1519 | 0 | case DT_Double: |
1520 | 0 | { |
1521 | 0 | memcpy(ptr, &z, sizeof(double)); |
1522 | 0 | ptr += 8; |
1523 | 0 | break; |
1524 | 0 | } |
1525 | | |
1526 | 0 | default: |
1527 | 0 | return false; |
1528 | 0 | } |
1529 | | |
1530 | 0 | *ppByte = ptr; |
1531 | 0 | return true; |
1532 | 0 | } |
1533 | | |
1534 | | // -------------------------------------------------------------------------- ; |
1535 | | |
1536 | | inline |
1537 | | double Lerc2::ReadVariableDataType(const Byte** ppByte, DataType dtUsed) |
1538 | 32.0k | { |
1539 | 32.0k | const Byte* ptr = *ppByte; |
1540 | | |
1541 | 32.0k | switch (dtUsed) |
1542 | 32.0k | { |
1543 | 11.1k | case DT_Char: |
1544 | 11.1k | { |
1545 | 11.1k | signed char c = *((signed char*)ptr); |
1546 | 11.1k | *ppByte = ptr + 1; |
1547 | 11.1k | return c; |
1548 | 0 | } |
1549 | 11.8k | case DT_Byte: |
1550 | 11.8k | { |
1551 | 11.8k | Byte b = *((Byte*)ptr); |
1552 | 11.8k | *ppByte = ptr + 1; |
1553 | 11.8k | return b; |
1554 | 0 | } |
1555 | 1.57k | case DT_Short: |
1556 | 1.57k | { |
1557 | 1.57k | short s; |
1558 | 1.57k | memcpy(&s, ptr, sizeof(short)); |
1559 | 1.57k | *ppByte = ptr + 2; |
1560 | 1.57k | return s; |
1561 | 0 | } |
1562 | 3.62k | case DT_UShort: |
1563 | 3.62k | { |
1564 | 3.62k | unsigned short us; |
1565 | 3.62k | memcpy(&us, ptr, sizeof(unsigned short)); |
1566 | 3.62k | *ppByte = ptr + 2; |
1567 | 3.62k | return us; |
1568 | 0 | } |
1569 | 1.14k | case DT_Int: |
1570 | 1.14k | { |
1571 | 1.14k | int i; |
1572 | 1.14k | memcpy(&i, ptr, sizeof(int)); |
1573 | 1.14k | *ppByte = ptr + 4; |
1574 | 1.14k | return i; |
1575 | 0 | } |
1576 | 2.09k | case DT_UInt: |
1577 | 2.09k | { |
1578 | 2.09k | unsigned int n; |
1579 | 2.09k | memcpy(&n, ptr, sizeof(unsigned int)); |
1580 | 2.09k | *ppByte = ptr + 4; |
1581 | 2.09k | return n; |
1582 | 0 | } |
1583 | 482 | case DT_Float: |
1584 | 482 | { |
1585 | 482 | float f; |
1586 | 482 | memcpy(&f, ptr, sizeof(float)); |
1587 | 482 | *ppByte = ptr + 4; |
1588 | 482 | return f; |
1589 | 0 | } |
1590 | 137 | case DT_Double: |
1591 | 137 | { |
1592 | 137 | double d; |
1593 | 137 | memcpy(&d, ptr, sizeof(double)); |
1594 | 137 | *ppByte = ptr + 8; |
1595 | 137 | return d; |
1596 | 0 | } |
1597 | 0 | default: |
1598 | 0 | return 0; |
1599 | 32.0k | } |
1600 | 32.0k | } |
1601 | | |
1602 | | // -------------------------------------------------------------------------- ; |
1603 | | |
1604 | | template<class T> |
1605 | | Lerc2::DataType Lerc2::GetDataType(T z) const |
1606 | 0 | { |
1607 | 0 | const std::type_info& ti = typeid(z); |
1608 | |
|
1609 | 0 | if (ti == typeid(signed char)) return DT_Char; |
1610 | 0 | else if (ti == typeid(Byte)) return DT_Byte; |
1611 | 0 | else if (ti == typeid(short)) return DT_Short; |
1612 | 0 | else if (ti == typeid(unsigned short)) return DT_UShort; |
1613 | 0 | else if (ti == typeid(int ) && sizeof(int ) == 4) return DT_Int; |
1614 | 0 | else if (ti == typeid(long) && sizeof(long) == 4) return DT_Int; |
1615 | 0 | else if (ti == typeid(unsigned int ) && sizeof(unsigned int ) == 4) return DT_UInt; |
1616 | 0 | else if (ti == typeid(unsigned long) && sizeof(unsigned long) == 4) return DT_UInt; |
1617 | 0 | else if (ti == typeid(float)) return DT_Float; |
1618 | 0 | else if (ti == typeid(double)) return DT_Double; |
1619 | 0 | else |
1620 | 0 | return DT_Undefined; |
1621 | 0 | } Unexecuted instantiation: GDAL_LercNS::Lerc2::DataType GDAL_LercNS::Lerc2::GetDataType<signed char>(signed char) const Unexecuted instantiation: GDAL_LercNS::Lerc2::DataType GDAL_LercNS::Lerc2::GetDataType<unsigned char>(unsigned char) const Unexecuted instantiation: GDAL_LercNS::Lerc2::DataType GDAL_LercNS::Lerc2::GetDataType<short>(short) const Unexecuted instantiation: GDAL_LercNS::Lerc2::DataType GDAL_LercNS::Lerc2::GetDataType<unsigned short>(unsigned short) const Unexecuted instantiation: GDAL_LercNS::Lerc2::DataType GDAL_LercNS::Lerc2::GetDataType<int>(int) const Unexecuted instantiation: GDAL_LercNS::Lerc2::DataType GDAL_LercNS::Lerc2::GetDataType<unsigned int>(unsigned int) const Unexecuted instantiation: GDAL_LercNS::Lerc2::DataType GDAL_LercNS::Lerc2::GetDataType<float>(float) const Unexecuted instantiation: GDAL_LercNS::Lerc2::DataType GDAL_LercNS::Lerc2::GetDataType<double>(double) const |
1622 | | |
1623 | | // -------------------------------------------------------------------------- ; |
1624 | | |
1625 | | inline |
1626 | | unsigned int Lerc2::GetMaxValToQuantize(DataType dt) |
1627 | 0 | { |
1628 | 0 | switch (dt) |
1629 | 0 | { |
1630 | 0 | case DT_Char: |
1631 | 0 | case DT_Byte: //return (1 << 7) - 1; // disabled: allow LUT mode for 8 bit segmented |
1632 | 0 | case DT_Short: |
1633 | 0 | case DT_UShort: return (1 << 15) - 1; |
1634 | | |
1635 | 0 | case DT_Int: |
1636 | 0 | case DT_UInt: |
1637 | 0 | case DT_Float: |
1638 | 0 | case DT_Double: return (1 << 30) - 1; |
1639 | | |
1640 | 0 | default: |
1641 | 0 | return 0; |
1642 | 0 | } |
1643 | 0 | } |
1644 | | |
1645 | | // -------------------------------------------------------------------------- ; |
1646 | | |
1647 | | inline |
1648 | | unsigned int Lerc2::GetDataTypeSize(DataType dt) |
1649 | 32.2k | { |
1650 | 32.2k | switch (dt) |
1651 | 32.2k | { |
1652 | 11.1k | case DT_Char: |
1653 | 23.0k | case DT_Byte: return 1; |
1654 | 1.61k | case DT_Short: |
1655 | 5.28k | case DT_UShort: return 2; |
1656 | 1.15k | case DT_Int: |
1657 | 3.30k | case DT_UInt: |
1658 | 3.83k | case DT_Float: return 4; |
1659 | 141 | case DT_Double: return 8; |
1660 | | |
1661 | 0 | default: |
1662 | 0 | return 0; |
1663 | 32.2k | } |
1664 | 32.2k | } |
1665 | | |
1666 | | // -------------------------------------------------------------------------- ; |
1667 | | |
1668 | | template<class T> |
1669 | | void Lerc2::ComputeHuffmanCodes(const T* data, int& numBytes, ImageEncodeMode& imageEncodeMode, std::vector<std::pair<unsigned short, unsigned int> >& codes) const |
1670 | 0 | { |
1671 | 0 | std::vector<int> histo, deltaHisto; |
1672 | 0 | ComputeHistoForHuffman(data, histo, deltaHisto); |
1673 | |
|
1674 | 0 | int nBytes0 = 0, nBytes1 = 0; |
1675 | 0 | double avgBpp0 = 0, avgBpp1 = 0; |
1676 | 0 | Huffman huffman0, huffman1; |
1677 | |
|
1678 | 0 | if (m_headerInfo.version >= 4) |
1679 | 0 | { |
1680 | 0 | if (!huffman0.ComputeCodes(histo) || !huffman0.ComputeCompressedSize(histo, nBytes0, avgBpp0)) |
1681 | 0 | nBytes0 = 0; |
1682 | 0 | } |
1683 | |
|
1684 | 0 | if (!huffman1.ComputeCodes(deltaHisto) || !huffman1.ComputeCompressedSize(deltaHisto, nBytes1, avgBpp1)) |
1685 | 0 | nBytes1 = 0; |
1686 | |
|
1687 | 0 | if (nBytes0 > 0 && nBytes1 > 0) // regular case, pick the better of the two |
1688 | 0 | { |
1689 | 0 | imageEncodeMode = (nBytes0 <= nBytes1) ? IEM_Huffman : IEM_DeltaHuffman; |
1690 | 0 | codes = (nBytes0 <= nBytes1) ? huffman0.GetCodes() : huffman1.GetCodes(); |
1691 | 0 | numBytes = (std::min)(nBytes0, nBytes1); |
1692 | 0 | } |
1693 | 0 | else if (nBytes0 == 0 && nBytes1 == 0) // rare case huffman cannot handle, fall back to tiling |
1694 | 0 | { |
1695 | 0 | imageEncodeMode = IEM_Tiling; |
1696 | 0 | codes.resize(0); |
1697 | 0 | numBytes = 0; |
1698 | 0 | } |
1699 | 0 | else // rare also, pick the valid one, the other is 0 |
1700 | 0 | { |
1701 | 0 | imageEncodeMode = (nBytes0 > nBytes1) ? IEM_Huffman : IEM_DeltaHuffman; |
1702 | 0 | codes = (nBytes0 > nBytes1) ? huffman0.GetCodes() : huffman1.GetCodes(); |
1703 | 0 | numBytes = (std::max)(nBytes0, nBytes1); |
1704 | 0 | } |
1705 | 0 | } Unexecuted instantiation: void GDAL_LercNS::Lerc2::ComputeHuffmanCodes<signed char>(signed char const*, int&, GDAL_LercNS::Lerc2::ImageEncodeMode&, std::__1::vector<std::__1::pair<unsigned short, unsigned int>, std::__1::allocator<std::__1::pair<unsigned short, unsigned int> > >&) const Unexecuted instantiation: void GDAL_LercNS::Lerc2::ComputeHuffmanCodes<unsigned char>(unsigned char const*, int&, GDAL_LercNS::Lerc2::ImageEncodeMode&, std::__1::vector<std::__1::pair<unsigned short, unsigned int>, std::__1::allocator<std::__1::pair<unsigned short, unsigned int> > >&) const Unexecuted instantiation: void GDAL_LercNS::Lerc2::ComputeHuffmanCodes<short>(short const*, int&, GDAL_LercNS::Lerc2::ImageEncodeMode&, std::__1::vector<std::__1::pair<unsigned short, unsigned int>, std::__1::allocator<std::__1::pair<unsigned short, unsigned int> > >&) const Unexecuted instantiation: void GDAL_LercNS::Lerc2::ComputeHuffmanCodes<unsigned short>(unsigned short const*, int&, GDAL_LercNS::Lerc2::ImageEncodeMode&, std::__1::vector<std::__1::pair<unsigned short, unsigned int>, std::__1::allocator<std::__1::pair<unsigned short, unsigned int> > >&) const Unexecuted instantiation: void GDAL_LercNS::Lerc2::ComputeHuffmanCodes<int>(int const*, int&, GDAL_LercNS::Lerc2::ImageEncodeMode&, std::__1::vector<std::__1::pair<unsigned short, unsigned int>, std::__1::allocator<std::__1::pair<unsigned short, unsigned int> > >&) const Unexecuted instantiation: void GDAL_LercNS::Lerc2::ComputeHuffmanCodes<unsigned int>(unsigned int const*, int&, GDAL_LercNS::Lerc2::ImageEncodeMode&, std::__1::vector<std::__1::pair<unsigned short, unsigned int>, std::__1::allocator<std::__1::pair<unsigned short, unsigned int> > >&) const Unexecuted instantiation: void GDAL_LercNS::Lerc2::ComputeHuffmanCodes<float>(float const*, int&, GDAL_LercNS::Lerc2::ImageEncodeMode&, std::__1::vector<std::__1::pair<unsigned short, unsigned int>, std::__1::allocator<std::__1::pair<unsigned short, unsigned int> > >&) const Unexecuted instantiation: void GDAL_LercNS::Lerc2::ComputeHuffmanCodes<double>(double const*, int&, GDAL_LercNS::Lerc2::ImageEncodeMode&, std::__1::vector<std::__1::pair<unsigned short, unsigned int>, std::__1::allocator<std::__1::pair<unsigned short, unsigned int> > >&) const |
1706 | | |
1707 | | // -------------------------------------------------------------------------- ; |
1708 | | |
1709 | | template<class T> |
1710 | | void Lerc2::ComputeHistoForHuffman(const T* data, std::vector<int>& histo, std::vector<int>& deltaHisto) const |
1711 | 0 | { |
1712 | 0 | histo.resize(256); |
1713 | 0 | deltaHisto.resize(256); |
1714 | |
|
1715 | 0 | memset(&histo[0], 0, histo.size() * sizeof(int)); |
1716 | 0 | memset(&deltaHisto[0], 0, deltaHisto.size() * sizeof(int)); |
1717 | |
|
1718 | 0 | int offset = (m_headerInfo.dt == DT_Char) ? 128 : 0; |
1719 | 0 | int height = m_headerInfo.nRows; |
1720 | 0 | int width = m_headerInfo.nCols; |
1721 | 0 | int nDim = m_headerInfo.nDim; |
1722 | |
|
1723 | 0 | if (m_headerInfo.numValidPixel == width * height) // all valid |
1724 | 0 | { |
1725 | 0 | for (int iDim = 0; iDim < nDim; iDim++) |
1726 | 0 | { |
1727 | 0 | T prevVal = 0; |
1728 | 0 | for (int m = iDim, i = 0; i < height; i++) |
1729 | 0 | for (int j = 0; j < width; j++, m += nDim) |
1730 | 0 | { |
1731 | 0 | T val = data[m]; |
1732 | 0 | T delta = val; |
1733 | |
|
1734 | 0 | if (j > 0) |
1735 | 0 | delta -= prevVal; // use overflow |
1736 | 0 | else if (i > 0) |
1737 | 0 | delta -= data[m - width * nDim]; |
1738 | 0 | else |
1739 | 0 | delta -= prevVal; |
1740 | |
|
1741 | 0 | prevVal = val; |
1742 | |
|
1743 | 0 | histo[offset + (int)val]++; |
1744 | 0 | deltaHisto[offset + (int)delta]++; |
1745 | 0 | } |
1746 | 0 | } |
1747 | 0 | } |
1748 | 0 | else // not all valid |
1749 | 0 | { |
1750 | 0 | for (int iDim = 0; iDim < nDim; iDim++) |
1751 | 0 | { |
1752 | 0 | T prevVal = 0; |
1753 | 0 | for (int k = 0, m = iDim, i = 0; i < height; i++) |
1754 | 0 | for (int j = 0; j < width; j++, k++, m += nDim) |
1755 | 0 | if (m_bitMask.IsValid(k)) |
1756 | 0 | { |
1757 | 0 | T val = data[m]; |
1758 | 0 | T delta = val; |
1759 | |
|
1760 | 0 | if (j > 0 && m_bitMask.IsValid(k - 1)) |
1761 | 0 | { |
1762 | 0 | delta -= prevVal; // use overflow |
1763 | 0 | } |
1764 | 0 | else if (i > 0 && m_bitMask.IsValid(k - width)) |
1765 | 0 | { |
1766 | 0 | delta -= data[m - width * nDim]; |
1767 | 0 | } |
1768 | 0 | else |
1769 | 0 | delta -= prevVal; |
1770 | |
|
1771 | 0 | prevVal = val; |
1772 | |
|
1773 | 0 | histo[offset + (int)val]++; |
1774 | 0 | deltaHisto[offset + (int)delta]++; |
1775 | 0 | } |
1776 | 0 | } |
1777 | 0 | } |
1778 | 0 | } Unexecuted instantiation: void GDAL_LercNS::Lerc2::ComputeHistoForHuffman<signed char>(signed char const*, std::__1::vector<int, std::__1::allocator<int> >&, std::__1::vector<int, std::__1::allocator<int> >&) const Unexecuted instantiation: void GDAL_LercNS::Lerc2::ComputeHistoForHuffman<unsigned char>(unsigned char const*, std::__1::vector<int, std::__1::allocator<int> >&, std::__1::vector<int, std::__1::allocator<int> >&) const Unexecuted instantiation: void GDAL_LercNS::Lerc2::ComputeHistoForHuffman<short>(short const*, std::__1::vector<int, std::__1::allocator<int> >&, std::__1::vector<int, std::__1::allocator<int> >&) const Unexecuted instantiation: void GDAL_LercNS::Lerc2::ComputeHistoForHuffman<unsigned short>(unsigned short const*, std::__1::vector<int, std::__1::allocator<int> >&, std::__1::vector<int, std::__1::allocator<int> >&) const Unexecuted instantiation: void GDAL_LercNS::Lerc2::ComputeHistoForHuffman<int>(int const*, std::__1::vector<int, std::__1::allocator<int> >&, std::__1::vector<int, std::__1::allocator<int> >&) const Unexecuted instantiation: void GDAL_LercNS::Lerc2::ComputeHistoForHuffman<unsigned int>(unsigned int const*, std::__1::vector<int, std::__1::allocator<int> >&, std::__1::vector<int, std::__1::allocator<int> >&) const Unexecuted instantiation: void GDAL_LercNS::Lerc2::ComputeHistoForHuffman<float>(float const*, std::__1::vector<int, std::__1::allocator<int> >&, std::__1::vector<int, std::__1::allocator<int> >&) const Unexecuted instantiation: void GDAL_LercNS::Lerc2::ComputeHistoForHuffman<double>(double const*, std::__1::vector<int, std::__1::allocator<int> >&, std::__1::vector<int, std::__1::allocator<int> >&) const |
1779 | | |
1780 | | // -------------------------------------------------------------------------- ; |
1781 | | |
1782 | | template<class T> |
1783 | | bool Lerc2::EncodeHuffman(const T* data, Byte** ppByte) const |
1784 | 0 | { |
1785 | 0 | if (!data || !ppByte) |
1786 | 0 | return false; |
1787 | | |
1788 | 0 | Huffman huffman; |
1789 | 0 | if (!huffman.SetCodes(m_huffmanCodes) || !huffman.WriteCodeTable(ppByte, m_headerInfo.version)) // header and code table |
1790 | 0 | return false; |
1791 | | |
1792 | 0 | int offset = (m_headerInfo.dt == DT_Char) ? 128 : 0; |
1793 | 0 | int height = m_headerInfo.nRows; |
1794 | 0 | int width = m_headerInfo.nCols; |
1795 | 0 | int nDim = m_headerInfo.nDim; |
1796 | |
|
1797 | 0 | unsigned int* arr = (unsigned int*)(*ppByte); |
1798 | 0 | unsigned int* dstPtr = arr; |
1799 | 0 | int bitPos = 0; |
1800 | |
|
1801 | 0 | if (m_imageEncodeMode == IEM_DeltaHuffman) |
1802 | 0 | { |
1803 | 0 | for (int iDim = 0; iDim < nDim; iDim++) |
1804 | 0 | { |
1805 | 0 | T prevVal = 0; |
1806 | 0 | for (int k = 0, m = iDim, i = 0; i < height; i++) |
1807 | 0 | for (int j = 0; j < width; j++, k++, m += nDim) |
1808 | 0 | if (m_bitMask.IsValid(k)) |
1809 | 0 | { |
1810 | 0 | T val = data[m]; |
1811 | 0 | T delta = val; |
1812 | |
|
1813 | 0 | if (j > 0 && m_bitMask.IsValid(k - 1)) |
1814 | 0 | { |
1815 | 0 | delta -= prevVal; // use overflow |
1816 | 0 | } |
1817 | 0 | else if (i > 0 && m_bitMask.IsValid(k - width)) |
1818 | 0 | { |
1819 | 0 | delta -= data[m - width * nDim]; |
1820 | 0 | } |
1821 | 0 | else |
1822 | 0 | delta -= prevVal; |
1823 | |
|
1824 | 0 | prevVal = val; |
1825 | | |
1826 | | // bit stuff the huffman code for this delta |
1827 | 0 | int kBin = offset + (int)delta; |
1828 | 0 | int len = m_huffmanCodes[kBin].first; |
1829 | 0 | if (len <= 0) |
1830 | 0 | return false; |
1831 | | |
1832 | 0 | unsigned int code = m_huffmanCodes[kBin].second; |
1833 | |
|
1834 | 0 | if (32 - bitPos >= len) |
1835 | 0 | { |
1836 | 0 | if (bitPos == 0) |
1837 | 0 | *dstPtr = 0; |
1838 | |
|
1839 | 0 | *dstPtr |= code << (32 - bitPos - len); |
1840 | 0 | bitPos += len; |
1841 | 0 | if (bitPos == 32) |
1842 | 0 | { |
1843 | 0 | bitPos = 0; |
1844 | 0 | dstPtr++; |
1845 | 0 | } |
1846 | 0 | } |
1847 | 0 | else |
1848 | 0 | { |
1849 | 0 | bitPos += len - 32; |
1850 | 0 | *dstPtr++ |= code >> bitPos; |
1851 | 0 | *dstPtr = code << (32 - bitPos); |
1852 | 0 | } |
1853 | 0 | } |
1854 | 0 | } |
1855 | 0 | } |
1856 | | |
1857 | 0 | else if (m_imageEncodeMode == IEM_Huffman) |
1858 | 0 | { |
1859 | 0 | for (int k = 0, m0 = 0, i = 0; i < height; i++) |
1860 | 0 | for (int j = 0; j < width; j++, k++, m0 += nDim) |
1861 | 0 | if (m_bitMask.IsValid(k)) |
1862 | 0 | for (int m = 0; m < nDim; m++) |
1863 | 0 | { |
1864 | 0 | T val = data[m0 + m]; |
1865 | | |
1866 | | // bit stuff the huffman code for this val |
1867 | 0 | int kBin = offset + (int)val; |
1868 | 0 | int len = m_huffmanCodes[kBin].first; |
1869 | 0 | if (len <= 0) |
1870 | 0 | return false; |
1871 | | |
1872 | 0 | unsigned int code = m_huffmanCodes[kBin].second; |
1873 | |
|
1874 | 0 | if (32 - bitPos >= len) |
1875 | 0 | { |
1876 | 0 | if (bitPos == 0) |
1877 | 0 | *dstPtr = 0; |
1878 | |
|
1879 | 0 | *dstPtr |= code << (32 - bitPos - len); |
1880 | 0 | bitPos += len; |
1881 | 0 | if (bitPos == 32) |
1882 | 0 | { |
1883 | 0 | bitPos = 0; |
1884 | 0 | dstPtr++; |
1885 | 0 | } |
1886 | 0 | } |
1887 | 0 | else |
1888 | 0 | { |
1889 | 0 | bitPos += len - 32; |
1890 | 0 | *dstPtr++ |= code >> bitPos; |
1891 | 0 | *dstPtr = code << (32 - bitPos); |
1892 | 0 | } |
1893 | 0 | } |
1894 | 0 | } |
1895 | | |
1896 | 0 | else |
1897 | 0 | return false; |
1898 | | |
1899 | 0 | size_t numUInts = dstPtr - arr + (bitPos > 0 ? 1 : 0) + 1; // add one more as the decode LUT can read ahead |
1900 | 0 | *ppByte += numUInts * sizeof(unsigned int); |
1901 | 0 | return true; |
1902 | 0 | } Unexecuted instantiation: bool GDAL_LercNS::Lerc2::EncodeHuffman<signed char>(signed char const*, unsigned char**) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::EncodeHuffman<unsigned char>(unsigned char const*, unsigned char**) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::EncodeHuffman<short>(short const*, unsigned char**) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::EncodeHuffman<unsigned short>(unsigned short const*, unsigned char**) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::EncodeHuffman<int>(int const*, unsigned char**) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::EncodeHuffman<unsigned int>(unsigned int const*, unsigned char**) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::EncodeHuffman<float>(float const*, unsigned char**) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::EncodeHuffman<double>(double const*, unsigned char**) const |
1903 | | |
1904 | | // -------------------------------------------------------------------------- ; |
1905 | | |
1906 | | template<class T> |
1907 | | bool Lerc2::DecodeHuffman(const Byte** ppByte, size_t& nBytesRemainingInOut, T* data) const |
1908 | 9.92k | { |
1909 | 9.92k | if (!data || !ppByte || !(*ppByte)) |
1910 | 0 | return false; |
1911 | | |
1912 | 9.92k | Huffman huffman; |
1913 | 9.92k | if (!huffman.ReadCodeTable(ppByte, nBytesRemainingInOut, m_headerInfo.version)) // header and code table |
1914 | 2.25k | return false; |
1915 | | |
1916 | 7.66k | int numBitsLUT = 0; |
1917 | 7.66k | if (!huffman.BuildTreeFromCodes(numBitsLUT)) |
1918 | 168 | return false; |
1919 | | |
1920 | 7.49k | int offset = (m_headerInfo.dt == DT_Char) ? 128 : 0; |
1921 | 7.49k | int height = m_headerInfo.nRows; |
1922 | 7.49k | int width = m_headerInfo.nCols; |
1923 | 7.49k | int nDim = m_headerInfo.nDim; |
1924 | | |
1925 | 7.49k | const unsigned int* arr = (const unsigned int*)(*ppByte); |
1926 | 7.49k | const unsigned int* srcPtr = arr; |
1927 | 7.49k | int bitPos = 0; |
1928 | 7.49k | size_t nBytesRemaining = nBytesRemainingInOut; |
1929 | | |
1930 | 7.49k | if (m_headerInfo.numValidPixel == width * height) // all valid |
1931 | 3.41k | { |
1932 | 3.41k | if (m_imageEncodeMode == IEM_DeltaHuffman) |
1933 | 1.61k | { |
1934 | 6.96k | for (int iDim = 0; iDim < nDim; iDim++) |
1935 | 6.84k | { |
1936 | 6.84k | T prevVal = 0; |
1937 | 57.8k | for (int m = iDim, i = 0; i < height; i++) |
1938 | 1.09M | for (int j = 0; j < width; j++, m += nDim) |
1939 | 1.04M | { |
1940 | 1.04M | int val = 0; |
1941 | 1.04M | if (nBytesRemaining >= 4 * sizeof(unsigned int)) |
1942 | 1.01M | { |
1943 | 1.01M | if (!huffman.DecodeOneValue_NoOverrunCheck(&srcPtr, nBytesRemaining, bitPos, numBitsLUT, val)) |
1944 | 404 | return false; |
1945 | 1.01M | } |
1946 | 28.1k | else |
1947 | 28.1k | { |
1948 | 28.1k | if (!huffman.DecodeOneValue(&srcPtr, nBytesRemaining, bitPos, numBitsLUT, val)) |
1949 | 1.09k | return false; |
1950 | 28.1k | } |
1951 | | |
1952 | 1.04M | T delta = (T)(val - offset); |
1953 | | |
1954 | 1.04M | if (j > 0) |
1955 | 990k | delta += prevVal; // use overflow |
1956 | 52.1k | else if (i > 0) |
1957 | 45.4k | delta += data[m - width * nDim]; |
1958 | 6.71k | else |
1959 | 6.71k | delta += prevVal; |
1960 | | |
1961 | 1.04M | data[m] = delta; |
1962 | 1.04M | prevVal = delta; |
1963 | 1.04M | } |
1964 | 6.84k | } |
1965 | 1.61k | } |
1966 | | |
1967 | 1.79k | else if (m_imageEncodeMode == IEM_Huffman) |
1968 | 1.79k | { |
1969 | 8.43k | for (int k = 0, m0 = 0, i = 0; i < height; i++) |
1970 | 115k | for (int j = 0; j < width; j++, k++, m0 += nDim) |
1971 | 3.57M | for (int m = 0; m < nDim; m++) |
1972 | 3.47M | { |
1973 | 3.47M | int val = 0; |
1974 | 3.47M | if (nBytesRemaining >= 4 * sizeof(unsigned int)) |
1975 | 3.43M | { |
1976 | 3.43M | if (!huffman.DecodeOneValue_NoOverrunCheck(&srcPtr, nBytesRemaining, bitPos, numBitsLUT, val)) |
1977 | 440 | return false; |
1978 | 3.43M | } |
1979 | 30.8k | else |
1980 | 30.8k | { |
1981 | 30.8k | if (!huffman.DecodeOneValue(&srcPtr, nBytesRemaining, bitPos, numBitsLUT, val)) |
1982 | 1.23k | return false; |
1983 | 30.8k | } |
1984 | | |
1985 | 3.46M | data[m0 + m] = (T)(val - offset); |
1986 | 3.46M | } |
1987 | 1.79k | } |
1988 | | |
1989 | 0 | else |
1990 | 0 | return false; |
1991 | 3.41k | } |
1992 | | |
1993 | 4.08k | else // not all valid |
1994 | 4.08k | { |
1995 | 4.08k | if (m_imageEncodeMode == IEM_DeltaHuffman) |
1996 | 1.96k | { |
1997 | 5.44k | for (int iDim = 0; iDim < nDim; iDim++) |
1998 | 5.25k | { |
1999 | 5.25k | T prevVal = 0; |
2000 | 486k | for (int k = 0, m = iDim, i = 0; i < height; i++) |
2001 | 33.1M | for (int j = 0; j < width; j++, k++, m += nDim) |
2002 | 32.6M | if (m_bitMask.IsValid(k)) |
2003 | 485k | { |
2004 | 485k | int val = 0; |
2005 | 485k | if (nBytesRemaining >= 4 * sizeof(unsigned int)) |
2006 | 454k | { |
2007 | 454k | if (!huffman.DecodeOneValue_NoOverrunCheck(&srcPtr, nBytesRemaining, bitPos, numBitsLUT, val)) |
2008 | 535 | return false; |
2009 | 454k | } |
2010 | 30.3k | else |
2011 | 30.3k | { |
2012 | 30.3k | if (!huffman.DecodeOneValue(&srcPtr, nBytesRemaining, bitPos, numBitsLUT, val)) |
2013 | 1.23k | return false; |
2014 | 30.3k | } |
2015 | | |
2016 | 483k | T delta = (T)(val - offset); |
2017 | | |
2018 | 483k | if (j > 0 && m_bitMask.IsValid(k - 1)) |
2019 | 265k | { |
2020 | 265k | delta += prevVal; // use overflow |
2021 | 265k | } |
2022 | 217k | else if (i > 0 && m_bitMask.IsValid(k - width)) |
2023 | 52.1k | { |
2024 | 52.1k | delta += data[m - width * nDim]; |
2025 | 52.1k | } |
2026 | 165k | else |
2027 | 165k | delta += prevVal; |
2028 | | |
2029 | 483k | data[m] = delta; |
2030 | 483k | prevVal = delta; |
2031 | 483k | } |
2032 | 5.25k | } |
2033 | 1.96k | } |
2034 | | |
2035 | 2.12k | else if (m_imageEncodeMode == IEM_Huffman) |
2036 | 2.12k | { |
2037 | 14.0k | for (int k = 0, m0 = 0, i = 0; i < height; i++) |
2038 | 340k | for (int j = 0; j < width; j++, k++, m0 += nDim) |
2039 | 328k | if (m_bitMask.IsValid(k)) |
2040 | 12.2M | for (int m = 0; m < nDim; m++) |
2041 | 12.1M | { |
2042 | 12.1M | int val = 0; |
2043 | 12.1M | if (nBytesRemaining >= 4 * sizeof(unsigned int)) |
2044 | 12.1M | { |
2045 | 12.1M | if (!huffman.DecodeOneValue_NoOverrunCheck(&srcPtr, nBytesRemaining, bitPos, numBitsLUT, val)) |
2046 | 567 | return false; |
2047 | 12.1M | } |
2048 | 36.3k | else |
2049 | 36.3k | { |
2050 | 36.3k | if (!huffman.DecodeOneValue(&srcPtr, nBytesRemaining, bitPos, numBitsLUT, val)) |
2051 | 1.29k | return false; |
2052 | 36.3k | } |
2053 | | |
2054 | 12.1M | data[m0 + m] = (T)(val - offset); |
2055 | 12.1M | } |
2056 | 2.12k | } |
2057 | | |
2058 | 0 | else |
2059 | 0 | return false; |
2060 | 4.08k | } |
2061 | | |
2062 | 692 | size_t numUInts = srcPtr - arr + (bitPos > 0 ? 1 : 0) + 1; // add one more as the decode LUT can read ahead |
2063 | 692 | size_t len = numUInts * sizeof(unsigned int); |
2064 | | |
2065 | 692 | if (nBytesRemainingInOut < len) |
2066 | 59 | return false; |
2067 | | |
2068 | 633 | *ppByte += len; |
2069 | 633 | nBytesRemainingInOut -= len; |
2070 | 633 | return true; |
2071 | 692 | } bool GDAL_LercNS::Lerc2::DecodeHuffman<signed char>(unsigned char const**, unsigned long&, signed char*) const Line | Count | Source | 1908 | 2.42k | { | 1909 | 2.42k | if (!data || !ppByte || !(*ppByte)) | 1910 | 0 | return false; | 1911 | | | 1912 | 2.42k | Huffman huffman; | 1913 | 2.42k | if (!huffman.ReadCodeTable(ppByte, nBytesRemainingInOut, m_headerInfo.version)) // header and code table | 1914 | 453 | return false; | 1915 | | | 1916 | 1.96k | int numBitsLUT = 0; | 1917 | 1.96k | if (!huffman.BuildTreeFromCodes(numBitsLUT)) | 1918 | 47 | return false; | 1919 | | | 1920 | 1.92k | int offset = (m_headerInfo.dt == DT_Char) ? 128 : 0; | 1921 | 1.92k | int height = m_headerInfo.nRows; | 1922 | 1.92k | int width = m_headerInfo.nCols; | 1923 | 1.92k | int nDim = m_headerInfo.nDim; | 1924 | | | 1925 | 1.92k | const unsigned int* arr = (const unsigned int*)(*ppByte); | 1926 | 1.92k | const unsigned int* srcPtr = arr; | 1927 | 1.92k | int bitPos = 0; | 1928 | 1.92k | size_t nBytesRemaining = nBytesRemainingInOut; | 1929 | | | 1930 | 1.92k | if (m_headerInfo.numValidPixel == width * height) // all valid | 1931 | 874 | { | 1932 | 874 | if (m_imageEncodeMode == IEM_DeltaHuffman) | 1933 | 440 | { | 1934 | 469 | for (int iDim = 0; iDim < nDim; iDim++) | 1935 | 460 | { | 1936 | 460 | T prevVal = 0; | 1937 | 1.88k | for (int m = iDim, i = 0; i < height; i++) | 1938 | 33.4k | for (int j = 0; j < width; j++, m += nDim) | 1939 | 32.0k | { | 1940 | 32.0k | int val = 0; | 1941 | 32.0k | if (nBytesRemaining >= 4 * sizeof(unsigned int)) | 1942 | 24.3k | { | 1943 | 24.3k | if (!huffman.DecodeOneValue_NoOverrunCheck(&srcPtr, nBytesRemaining, bitPos, numBitsLUT, val)) | 1944 | 118 | return false; | 1945 | 24.3k | } | 1946 | 7.71k | else | 1947 | 7.71k | { | 1948 | 7.71k | if (!huffman.DecodeOneValue(&srcPtr, nBytesRemaining, bitPos, numBitsLUT, val)) | 1949 | 313 | return false; | 1950 | 7.71k | } | 1951 | | | 1952 | 31.6k | T delta = (T)(val - offset); | 1953 | | | 1954 | 31.6k | if (j > 0) | 1955 | 29.8k | delta += prevVal; // use overflow | 1956 | 1.79k | else if (i > 0) | 1957 | 1.36k | delta += data[m - width * nDim]; | 1958 | 428 | else | 1959 | 428 | delta += prevVal; | 1960 | | | 1961 | 31.6k | data[m] = delta; | 1962 | 31.6k | prevVal = delta; | 1963 | 31.6k | } | 1964 | 460 | } | 1965 | 440 | } | 1966 | | | 1967 | 434 | else if (m_imageEncodeMode == IEM_Huffman) | 1968 | 434 | { | 1969 | 762 | for (int k = 0, m0 = 0, i = 0; i < height; i++) | 1970 | 8.08k | for (int j = 0; j < width; j++, k++, m0 += nDim) | 1971 | 30.5k | for (int m = 0; m < nDim; m++) | 1972 | 23.1k | { | 1973 | 23.1k | int val = 0; | 1974 | 23.1k | if (nBytesRemaining >= 4 * sizeof(unsigned int)) | 1975 | 16.7k | { | 1976 | 16.7k | if (!huffman.DecodeOneValue_NoOverrunCheck(&srcPtr, nBytesRemaining, bitPos, numBitsLUT, val)) | 1977 | 115 | return false; | 1978 | 16.7k | } | 1979 | 6.41k | else | 1980 | 6.41k | { | 1981 | 6.41k | if (!huffman.DecodeOneValue(&srcPtr, nBytesRemaining, bitPos, numBitsLUT, val)) | 1982 | 314 | return false; | 1983 | 6.41k | } | 1984 | | | 1985 | 22.7k | data[m0 + m] = (T)(val - offset); | 1986 | 22.7k | } | 1987 | 434 | } | 1988 | | | 1989 | 0 | else | 1990 | 0 | return false; | 1991 | 874 | } | 1992 | | | 1993 | 1.04k | else // not all valid | 1994 | 1.04k | { | 1995 | 1.04k | if (m_imageEncodeMode == IEM_DeltaHuffman) | 1996 | 522 | { | 1997 | 1.07k | for (int iDim = 0; iDim < nDim; iDim++) | 1998 | 1.03k | { | 1999 | 1.03k | T prevVal = 0; | 2000 | 13.9k | for (int k = 0, m = iDim, i = 0; i < height; i++) | 2001 | 275k | for (int j = 0; j < width; j++, k++, m += nDim) | 2002 | 262k | if (m_bitMask.IsValid(k)) | 2003 | 28.4k | { | 2004 | 28.4k | int val = 0; | 2005 | 28.4k | if (nBytesRemaining >= 4 * sizeof(unsigned int)) | 2006 | 18.4k | { | 2007 | 18.4k | if (!huffman.DecodeOneValue_NoOverrunCheck(&srcPtr, nBytesRemaining, bitPos, numBitsLUT, val)) | 2008 | 124 | return false; | 2009 | 18.4k | } | 2010 | 10.0k | else | 2011 | 10.0k | { | 2012 | 10.0k | if (!huffman.DecodeOneValue(&srcPtr, nBytesRemaining, bitPos, numBitsLUT, val)) | 2013 | 360 | return false; | 2014 | 10.0k | } | 2015 | | | 2016 | 27.9k | T delta = (T)(val - offset); | 2017 | | | 2018 | 27.9k | if (j > 0 && m_bitMask.IsValid(k - 1)) | 2019 | 11.4k | { | 2020 | 11.4k | delta += prevVal; // use overflow | 2021 | 11.4k | } | 2022 | 16.5k | else if (i > 0 && m_bitMask.IsValid(k - width)) | 2023 | 4.58k | { | 2024 | 4.58k | delta += data[m - width * nDim]; | 2025 | 4.58k | } | 2026 | 11.9k | else | 2027 | 11.9k | delta += prevVal; | 2028 | | | 2029 | 27.9k | data[m] = delta; | 2030 | 27.9k | prevVal = delta; | 2031 | 27.9k | } | 2032 | 1.03k | } | 2033 | 522 | } | 2034 | | | 2035 | 525 | else if (m_imageEncodeMode == IEM_Huffman) | 2036 | 525 | { | 2037 | 2.13k | for (int k = 0, m0 = 0, i = 0; i < height; i++) | 2038 | 36.1k | for (int j = 0; j < width; j++, k++, m0 += nDim) | 2039 | 34.5k | if (m_bitMask.IsValid(k)) | 2040 | 27.8k | for (int m = 0; m < nDim; m++) | 2041 | 23.3k | { | 2042 | 23.3k | int val = 0; | 2043 | 23.3k | if (nBytesRemaining >= 4 * sizeof(unsigned int)) | 2044 | 13.0k | { | 2045 | 13.0k | if (!huffman.DecodeOneValue_NoOverrunCheck(&srcPtr, nBytesRemaining, bitPos, numBitsLUT, val)) | 2046 | 115 | return false; | 2047 | 13.0k | } | 2048 | 10.3k | else | 2049 | 10.3k | { | 2050 | 10.3k | if (!huffman.DecodeOneValue(&srcPtr, nBytesRemaining, bitPos, numBitsLUT, val)) | 2051 | 371 | return false; | 2052 | 10.3k | } | 2053 | | | 2054 | 22.8k | data[m0 + m] = (T)(val - offset); | 2055 | 22.8k | } | 2056 | 525 | } | 2057 | | | 2058 | 0 | else | 2059 | 0 | return false; | 2060 | 1.04k | } | 2061 | | | 2062 | 91 | size_t numUInts = srcPtr - arr + (bitPos > 0 ? 1 : 0) + 1; // add one more as the decode LUT can read ahead | 2063 | 91 | size_t len = numUInts * sizeof(unsigned int); | 2064 | | | 2065 | 91 | if (nBytesRemainingInOut < len) | 2066 | 7 | return false; | 2067 | | | 2068 | 84 | *ppByte += len; | 2069 | 84 | nBytesRemainingInOut -= len; | 2070 | 84 | return true; | 2071 | 91 | } |
bool GDAL_LercNS::Lerc2::DecodeHuffman<unsigned char>(unsigned char const**, unsigned long&, unsigned char*) const Line | Count | Source | 1908 | 7.49k | { | 1909 | 7.49k | if (!data || !ppByte || !(*ppByte)) | 1910 | 0 | return false; | 1911 | | | 1912 | 7.49k | Huffman huffman; | 1913 | 7.49k | if (!huffman.ReadCodeTable(ppByte, nBytesRemainingInOut, m_headerInfo.version)) // header and code table | 1914 | 1.80k | return false; | 1915 | | | 1916 | 5.69k | int numBitsLUT = 0; | 1917 | 5.69k | if (!huffman.BuildTreeFromCodes(numBitsLUT)) | 1918 | 121 | return false; | 1919 | | | 1920 | 5.57k | int offset = (m_headerInfo.dt == DT_Char) ? 128 : 0; | 1921 | 5.57k | int height = m_headerInfo.nRows; | 1922 | 5.57k | int width = m_headerInfo.nCols; | 1923 | 5.57k | int nDim = m_headerInfo.nDim; | 1924 | | | 1925 | 5.57k | const unsigned int* arr = (const unsigned int*)(*ppByte); | 1926 | 5.57k | const unsigned int* srcPtr = arr; | 1927 | 5.57k | int bitPos = 0; | 1928 | 5.57k | size_t nBytesRemaining = nBytesRemainingInOut; | 1929 | | | 1930 | 5.57k | if (m_headerInfo.numValidPixel == width * height) // all valid | 1931 | 2.53k | { | 1932 | 2.53k | if (m_imageEncodeMode == IEM_DeltaHuffman) | 1933 | 1.17k | { | 1934 | 6.49k | for (int iDim = 0; iDim < nDim; iDim++) | 1935 | 6.38k | { | 1936 | 6.38k | T prevVal = 0; | 1937 | 55.9k | for (int m = iDim, i = 0; i < height; i++) | 1938 | 1.06M | for (int j = 0; j < width; j++, m += nDim) | 1939 | 1.01M | { | 1940 | 1.01M | int val = 0; | 1941 | 1.01M | if (nBytesRemaining >= 4 * sizeof(unsigned int)) | 1942 | 991k | { | 1943 | 991k | if (!huffman.DecodeOneValue_NoOverrunCheck(&srcPtr, nBytesRemaining, bitPos, numBitsLUT, val)) | 1944 | 286 | return false; | 1945 | 991k | } | 1946 | 20.4k | else | 1947 | 20.4k | { | 1948 | 20.4k | if (!huffman.DecodeOneValue(&srcPtr, nBytesRemaining, bitPos, numBitsLUT, val)) | 1949 | 783 | return false; | 1950 | 20.4k | } | 1951 | | | 1952 | 1.01M | T delta = (T)(val - offset); | 1953 | | | 1954 | 1.01M | if (j > 0) | 1955 | 960k | delta += prevVal; // use overflow | 1956 | 50.3k | else if (i > 0) | 1957 | 44.0k | delta += data[m - width * nDim]; | 1958 | 6.29k | else | 1959 | 6.29k | delta += prevVal; | 1960 | | | 1961 | 1.01M | data[m] = delta; | 1962 | 1.01M | prevVal = delta; | 1963 | 1.01M | } | 1964 | 6.38k | } | 1965 | 1.17k | } | 1966 | | | 1967 | 1.36k | else if (m_imageEncodeMode == IEM_Huffman) | 1968 | 1.36k | { | 1969 | 7.67k | for (int k = 0, m0 = 0, i = 0; i < height; i++) | 1970 | 107k | for (int j = 0; j < width; j++, k++, m0 += nDim) | 1971 | 3.54M | for (int m = 0; m < nDim; m++) | 1972 | 3.44M | { | 1973 | 3.44M | int val = 0; | 1974 | 3.44M | if (nBytesRemaining >= 4 * sizeof(unsigned int)) | 1975 | 3.42M | { | 1976 | 3.42M | if (!huffman.DecodeOneValue_NoOverrunCheck(&srcPtr, nBytesRemaining, bitPos, numBitsLUT, val)) | 1977 | 325 | return false; | 1978 | 3.42M | } | 1979 | 24.4k | else | 1980 | 24.4k | { | 1981 | 24.4k | if (!huffman.DecodeOneValue(&srcPtr, nBytesRemaining, bitPos, numBitsLUT, val)) | 1982 | 924 | return false; | 1983 | 24.4k | } | 1984 | | | 1985 | 3.44M | data[m0 + m] = (T)(val - offset); | 1986 | 3.44M | } | 1987 | 1.36k | } | 1988 | | | 1989 | 0 | else | 1990 | 0 | return false; | 1991 | 2.53k | } | 1992 | | | 1993 | 3.04k | else // not all valid | 1994 | 3.04k | { | 1995 | 3.04k | if (m_imageEncodeMode == IEM_DeltaHuffman) | 1996 | 1.44k | { | 1997 | 4.37k | for (int iDim = 0; iDim < nDim; iDim++) | 1998 | 4.21k | { | 1999 | 4.21k | T prevVal = 0; | 2000 | 472k | for (int k = 0, m = iDim, i = 0; i < height; i++) | 2001 | 32.8M | for (int j = 0; j < width; j++, k++, m += nDim) | 2002 | 32.4M | if (m_bitMask.IsValid(k)) | 2003 | 456k | { | 2004 | 456k | int val = 0; | 2005 | 456k | if (nBytesRemaining >= 4 * sizeof(unsigned int)) | 2006 | 436k | { | 2007 | 436k | if (!huffman.DecodeOneValue_NoOverrunCheck(&srcPtr, nBytesRemaining, bitPos, numBitsLUT, val)) | 2008 | 411 | return false; | 2009 | 436k | } | 2010 | 20.3k | else | 2011 | 20.3k | { | 2012 | 20.3k | if (!huffman.DecodeOneValue(&srcPtr, nBytesRemaining, bitPos, numBitsLUT, val)) | 2013 | 872 | return false; | 2014 | 20.3k | } | 2015 | | | 2016 | 455k | T delta = (T)(val - offset); | 2017 | | | 2018 | 455k | if (j > 0 && m_bitMask.IsValid(k - 1)) | 2019 | 254k | { | 2020 | 254k | delta += prevVal; // use overflow | 2021 | 254k | } | 2022 | 201k | else if (i > 0 && m_bitMask.IsValid(k - width)) | 2023 | 47.5k | { | 2024 | 47.5k | delta += data[m - width * nDim]; | 2025 | 47.5k | } | 2026 | 153k | else | 2027 | 153k | delta += prevVal; | 2028 | | | 2029 | 455k | data[m] = delta; | 2030 | 455k | prevVal = delta; | 2031 | 455k | } | 2032 | 4.21k | } | 2033 | 1.44k | } | 2034 | | | 2035 | 1.60k | else if (m_imageEncodeMode == IEM_Huffman) | 2036 | 1.60k | { | 2037 | 11.9k | for (int k = 0, m0 = 0, i = 0; i < height; i++) | 2038 | 303k | for (int j = 0; j < width; j++, k++, m0 += nDim) | 2039 | 293k | if (m_bitMask.IsValid(k)) | 2040 | 12.2M | for (int m = 0; m < nDim; m++) | 2041 | 12.1M | { | 2042 | 12.1M | int val = 0; | 2043 | 12.1M | if (nBytesRemaining >= 4 * sizeof(unsigned int)) | 2044 | 12.1M | { | 2045 | 12.1M | if (!huffman.DecodeOneValue_NoOverrunCheck(&srcPtr, nBytesRemaining, bitPos, numBitsLUT, val)) | 2046 | 452 | return false; | 2047 | 12.1M | } | 2048 | 26.0k | else | 2049 | 26.0k | { | 2050 | 26.0k | if (!huffman.DecodeOneValue(&srcPtr, nBytesRemaining, bitPos, numBitsLUT, val)) | 2051 | 924 | return false; | 2052 | 26.0k | } | 2053 | | | 2054 | 12.1M | data[m0 + m] = (T)(val - offset); | 2055 | 12.1M | } | 2056 | 1.60k | } | 2057 | | | 2058 | 0 | else | 2059 | 0 | return false; | 2060 | 3.04k | } | 2061 | | | 2062 | 601 | size_t numUInts = srcPtr - arr + (bitPos > 0 ? 1 : 0) + 1; // add one more as the decode LUT can read ahead | 2063 | 601 | size_t len = numUInts * sizeof(unsigned int); | 2064 | | | 2065 | 601 | if (nBytesRemainingInOut < len) | 2066 | 52 | return false; | 2067 | | | 2068 | 549 | *ppByte += len; | 2069 | 549 | nBytesRemainingInOut -= len; | 2070 | 549 | return true; | 2071 | 601 | } |
Unexecuted instantiation: bool GDAL_LercNS::Lerc2::DecodeHuffman<short>(unsigned char const**, unsigned long&, short*) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::DecodeHuffman<unsigned short>(unsigned char const**, unsigned long&, unsigned short*) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::DecodeHuffman<int>(unsigned char const**, unsigned long&, int*) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::DecodeHuffman<unsigned int>(unsigned char const**, unsigned long&, unsigned int*) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::DecodeHuffman<float>(unsigned char const**, unsigned long&, float*) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::DecodeHuffman<double>(unsigned char const**, unsigned long&, double*) const |
2072 | | |
2073 | | // -------------------------------------------------------------------------- ; |
2074 | | |
2075 | | template<class T> |
2076 | | bool Lerc2::WriteMinMaxRanges(const T* /*data*/, Byte** ppByte) const |
2077 | 0 | { |
2078 | 0 | if (!ppByte || !(*ppByte)) |
2079 | 0 | return false; |
2080 | | |
2081 | | //printf("write min / max = %f %f\n", m_zMinVec[0], m_zMaxVec[0]); |
2082 | | |
2083 | 0 | int nDim = m_headerInfo.nDim; |
2084 | 0 | if (/* nDim < 2 || */ (int)m_zMinVec.size() != nDim || (int)m_zMaxVec.size() != nDim) |
2085 | 0 | return false; |
2086 | | |
2087 | 0 | std::vector<T> zVec(nDim); |
2088 | 0 | size_t len = nDim * sizeof(T); |
2089 | |
|
2090 | 0 | for (int i = 0; i < nDim; i++) |
2091 | 0 | zVec[i] = (T)m_zMinVec[i]; |
2092 | |
|
2093 | 0 | memcpy(*ppByte, &zVec[0], len); |
2094 | 0 | (*ppByte) += len; |
2095 | |
|
2096 | 0 | for (int i = 0; i < nDim; i++) |
2097 | 0 | zVec[i] = (T)m_zMaxVec[i]; |
2098 | |
|
2099 | 0 | memcpy(*ppByte, &zVec[0], len); |
2100 | 0 | (*ppByte) += len; |
2101 | |
|
2102 | 0 | return true; |
2103 | 0 | } Unexecuted instantiation: bool GDAL_LercNS::Lerc2::WriteMinMaxRanges<signed char>(signed char const*, unsigned char**) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::WriteMinMaxRanges<unsigned char>(unsigned char const*, unsigned char**) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::WriteMinMaxRanges<short>(short const*, unsigned char**) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::WriteMinMaxRanges<unsigned short>(unsigned short const*, unsigned char**) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::WriteMinMaxRanges<int>(int const*, unsigned char**) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::WriteMinMaxRanges<unsigned int>(unsigned int const*, unsigned char**) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::WriteMinMaxRanges<float>(float const*, unsigned char**) const Unexecuted instantiation: bool GDAL_LercNS::Lerc2::WriteMinMaxRanges<double>(double const*, unsigned char**) const |
2104 | | |
2105 | | // -------------------------------------------------------------------------- ; |
2106 | | |
2107 | | template<class T> |
2108 | | bool Lerc2::ReadMinMaxRanges(const Byte** ppByte, size_t& nBytesRemaining, const T* /*data*/) |
2109 | 25.3k | { |
2110 | 25.3k | if (!ppByte || !(*ppByte)) |
2111 | 0 | return false; |
2112 | | |
2113 | 25.3k | int nDim = m_headerInfo.nDim; |
2114 | | |
2115 | 25.3k | m_zMinVec.resize(nDim); |
2116 | 25.3k | m_zMaxVec.resize(nDim); |
2117 | | |
2118 | 25.3k | std::vector<T> zVec(nDim); |
2119 | 25.3k | size_t len = nDim * sizeof(T); |
2120 | | |
2121 | 25.3k | if (nBytesRemaining < len || !memcpy(&zVec[0], *ppByte, len)) |
2122 | 667 | return false; |
2123 | | |
2124 | 24.6k | (*ppByte) += len; |
2125 | 24.6k | nBytesRemaining -= len; |
2126 | | |
2127 | 817k | for (int i = 0; i < nDim; i++) |
2128 | 793k | m_zMinVec[i] = zVec[i]; |
2129 | | |
2130 | 24.6k | if (nBytesRemaining < len || !memcpy(&zVec[0], *ppByte, len)) |
2131 | 422 | return false; |
2132 | | |
2133 | 24.2k | (*ppByte) += len; |
2134 | 24.2k | nBytesRemaining -= len; |
2135 | | |
2136 | 785k | for (int i = 0; i < nDim; i++) |
2137 | 761k | m_zMaxVec[i] = zVec[i]; |
2138 | | |
2139 | | //printf("read min / max = %f %f\n", m_zMinVec[0], m_zMaxVec[0]); |
2140 | | |
2141 | 24.2k | return true; |
2142 | 24.6k | } bool GDAL_LercNS::Lerc2::ReadMinMaxRanges<signed char>(unsigned char const**, unsigned long&, signed char const*) Line | Count | Source | 2109 | 3.63k | { | 2110 | 3.63k | if (!ppByte || !(*ppByte)) | 2111 | 0 | return false; | 2112 | | | 2113 | 3.63k | int nDim = m_headerInfo.nDim; | 2114 | | | 2115 | 3.63k | m_zMinVec.resize(nDim); | 2116 | 3.63k | m_zMaxVec.resize(nDim); | 2117 | | | 2118 | 3.63k | std::vector<T> zVec(nDim); | 2119 | 3.63k | size_t len = nDim * sizeof(T); | 2120 | | | 2121 | 3.63k | if (nBytesRemaining < len || !memcpy(&zVec[0], *ppByte, len)) | 2122 | 0 | return false; | 2123 | | | 2124 | 3.63k | (*ppByte) += len; | 2125 | 3.63k | nBytesRemaining -= len; | 2126 | | | 2127 | 177k | for (int i = 0; i < nDim; i++) | 2128 | 174k | m_zMinVec[i] = zVec[i]; | 2129 | | | 2130 | 3.63k | if (nBytesRemaining < len || !memcpy(&zVec[0], *ppByte, len)) | 2131 | 0 | return false; | 2132 | | | 2133 | 3.63k | (*ppByte) += len; | 2134 | 3.63k | nBytesRemaining -= len; | 2135 | | | 2136 | 177k | for (int i = 0; i < nDim; i++) | 2137 | 174k | m_zMaxVec[i] = zVec[i]; | 2138 | | | 2139 | | //printf("read min / max = %f %f\n", m_zMinVec[0], m_zMaxVec[0]); | 2140 | | | 2141 | 3.63k | return true; | 2142 | 3.63k | } |
bool GDAL_LercNS::Lerc2::ReadMinMaxRanges<unsigned char>(unsigned char const**, unsigned long&, unsigned char const*) Line | Count | Source | 2109 | 12.2k | { | 2110 | 12.2k | if (!ppByte || !(*ppByte)) | 2111 | 0 | return false; | 2112 | | | 2113 | 12.2k | int nDim = m_headerInfo.nDim; | 2114 | | | 2115 | 12.2k | m_zMinVec.resize(nDim); | 2116 | 12.2k | m_zMaxVec.resize(nDim); | 2117 | | | 2118 | 12.2k | std::vector<T> zVec(nDim); | 2119 | 12.2k | size_t len = nDim * sizeof(T); | 2120 | | | 2121 | 12.2k | if (nBytesRemaining < len || !memcpy(&zVec[0], *ppByte, len)) | 2122 | 140 | return false; | 2123 | | | 2124 | 12.1k | (*ppByte) += len; | 2125 | 12.1k | nBytesRemaining -= len; | 2126 | | | 2127 | 510k | for (int i = 0; i < nDim; i++) | 2128 | 498k | m_zMinVec[i] = zVec[i]; | 2129 | | | 2130 | 12.1k | if (nBytesRemaining < len || !memcpy(&zVec[0], *ppByte, len)) | 2131 | 81 | return false; | 2132 | | | 2133 | 12.0k | (*ppByte) += len; | 2134 | 12.0k | nBytesRemaining -= len; | 2135 | | | 2136 | 504k | for (int i = 0; i < nDim; i++) | 2137 | 492k | m_zMaxVec[i] = zVec[i]; | 2138 | | | 2139 | | //printf("read min / max = %f %f\n", m_zMinVec[0], m_zMaxVec[0]); | 2140 | | | 2141 | 12.0k | return true; | 2142 | 12.1k | } |
bool GDAL_LercNS::Lerc2::ReadMinMaxRanges<short>(unsigned char const**, unsigned long&, short const*) Line | Count | Source | 2109 | 2.09k | { | 2110 | 2.09k | if (!ppByte || !(*ppByte)) | 2111 | 0 | return false; | 2112 | | | 2113 | 2.09k | int nDim = m_headerInfo.nDim; | 2114 | | | 2115 | 2.09k | m_zMinVec.resize(nDim); | 2116 | 2.09k | m_zMaxVec.resize(nDim); | 2117 | | | 2118 | 2.09k | std::vector<T> zVec(nDim); | 2119 | 2.09k | size_t len = nDim * sizeof(T); | 2120 | | | 2121 | 2.09k | if (nBytesRemaining < len || !memcpy(&zVec[0], *ppByte, len)) | 2122 | 103 | return false; | 2123 | | | 2124 | 1.99k | (*ppByte) += len; | 2125 | 1.99k | nBytesRemaining -= len; | 2126 | | | 2127 | 21.0k | for (int i = 0; i < nDim; i++) | 2128 | 19.0k | m_zMinVec[i] = zVec[i]; | 2129 | | | 2130 | 1.99k | if (nBytesRemaining < len || !memcpy(&zVec[0], *ppByte, len)) | 2131 | 45 | return false; | 2132 | | | 2133 | 1.95k | (*ppByte) += len; | 2134 | 1.95k | nBytesRemaining -= len; | 2135 | | | 2136 | 20.4k | for (int i = 0; i < nDim; i++) | 2137 | 18.5k | m_zMaxVec[i] = zVec[i]; | 2138 | | | 2139 | | //printf("read min / max = %f %f\n", m_zMinVec[0], m_zMaxVec[0]); | 2140 | | | 2141 | 1.95k | return true; | 2142 | 1.99k | } |
bool GDAL_LercNS::Lerc2::ReadMinMaxRanges<unsigned short>(unsigned char const**, unsigned long&, unsigned short const*) Line | Count | Source | 2109 | 2.31k | { | 2110 | 2.31k | if (!ppByte || !(*ppByte)) | 2111 | 0 | return false; | 2112 | | | 2113 | 2.31k | int nDim = m_headerInfo.nDim; | 2114 | | | 2115 | 2.31k | m_zMinVec.resize(nDim); | 2116 | 2.31k | m_zMaxVec.resize(nDim); | 2117 | | | 2118 | 2.31k | std::vector<T> zVec(nDim); | 2119 | 2.31k | size_t len = nDim * sizeof(T); | 2120 | | | 2121 | 2.31k | if (nBytesRemaining < len || !memcpy(&zVec[0], *ppByte, len)) | 2122 | 96 | return false; | 2123 | | | 2124 | 2.21k | (*ppByte) += len; | 2125 | 2.21k | nBytesRemaining -= len; | 2126 | | | 2127 | 20.4k | for (int i = 0; i < nDim; i++) | 2128 | 18.2k | m_zMinVec[i] = zVec[i]; | 2129 | | | 2130 | 2.21k | if (nBytesRemaining < len || !memcpy(&zVec[0], *ppByte, len)) | 2131 | 45 | return false; | 2132 | | | 2133 | 2.16k | (*ppByte) += len; | 2134 | 2.16k | nBytesRemaining -= len; | 2135 | | | 2136 | 19.9k | for (int i = 0; i < nDim; i++) | 2137 | 17.7k | m_zMaxVec[i] = zVec[i]; | 2138 | | | 2139 | | //printf("read min / max = %f %f\n", m_zMinVec[0], m_zMaxVec[0]); | 2140 | | | 2141 | 2.16k | return true; | 2142 | 2.21k | } |
bool GDAL_LercNS::Lerc2::ReadMinMaxRanges<int>(unsigned char const**, unsigned long&, int const*) Line | Count | Source | 2109 | 1.25k | { | 2110 | 1.25k | if (!ppByte || !(*ppByte)) | 2111 | 0 | return false; | 2112 | | | 2113 | 1.25k | int nDim = m_headerInfo.nDim; | 2114 | | | 2115 | 1.25k | m_zMinVec.resize(nDim); | 2116 | 1.25k | m_zMaxVec.resize(nDim); | 2117 | | | 2118 | 1.25k | std::vector<T> zVec(nDim); | 2119 | 1.25k | size_t len = nDim * sizeof(T); | 2120 | | | 2121 | 1.25k | if (nBytesRemaining < len || !memcpy(&zVec[0], *ppByte, len)) | 2122 | 95 | return false; | 2123 | | | 2124 | 1.15k | (*ppByte) += len; | 2125 | 1.15k | nBytesRemaining -= len; | 2126 | | | 2127 | 10.9k | for (int i = 0; i < nDim; i++) | 2128 | 9.77k | m_zMinVec[i] = zVec[i]; | 2129 | | | 2130 | 1.15k | if (nBytesRemaining < len || !memcpy(&zVec[0], *ppByte, len)) | 2131 | 116 | return false; | 2132 | | | 2133 | 1.03k | (*ppByte) += len; | 2134 | 1.03k | nBytesRemaining -= len; | 2135 | | | 2136 | 9.53k | for (int i = 0; i < nDim; i++) | 2137 | 8.49k | m_zMaxVec[i] = zVec[i]; | 2138 | | | 2139 | | //printf("read min / max = %f %f\n", m_zMinVec[0], m_zMaxVec[0]); | 2140 | | | 2141 | 1.03k | return true; | 2142 | 1.15k | } |
bool GDAL_LercNS::Lerc2::ReadMinMaxRanges<unsigned int>(unsigned char const**, unsigned long&, unsigned int const*) Line | Count | Source | 2109 | 2.23k | { | 2110 | 2.23k | if (!ppByte || !(*ppByte)) | 2111 | 0 | return false; | 2112 | | | 2113 | 2.23k | int nDim = m_headerInfo.nDim; | 2114 | | | 2115 | 2.23k | m_zMinVec.resize(nDim); | 2116 | 2.23k | m_zMaxVec.resize(nDim); | 2117 | | | 2118 | 2.23k | std::vector<T> zVec(nDim); | 2119 | 2.23k | size_t len = nDim * sizeof(T); | 2120 | | | 2121 | 2.23k | if (nBytesRemaining < len || !memcpy(&zVec[0], *ppByte, len)) | 2122 | 52 | return false; | 2123 | | | 2124 | 2.18k | (*ppByte) += len; | 2125 | 2.18k | nBytesRemaining -= len; | 2126 | | | 2127 | 16.8k | for (int i = 0; i < nDim; i++) | 2128 | 14.6k | m_zMinVec[i] = zVec[i]; | 2129 | | | 2130 | 2.18k | if (nBytesRemaining < len || !memcpy(&zVec[0], *ppByte, len)) | 2131 | 39 | return false; | 2132 | | | 2133 | 2.14k | (*ppByte) += len; | 2134 | 2.14k | nBytesRemaining -= len; | 2135 | | | 2136 | 16.4k | for (int i = 0; i < nDim; i++) | 2137 | 14.3k | m_zMaxVec[i] = zVec[i]; | 2138 | | | 2139 | | //printf("read min / max = %f %f\n", m_zMinVec[0], m_zMaxVec[0]); | 2140 | | | 2141 | 2.14k | return true; | 2142 | 2.18k | } |
bool GDAL_LercNS::Lerc2::ReadMinMaxRanges<float>(unsigned char const**, unsigned long&, float const*) Line | Count | Source | 2109 | 755 | { | 2110 | 755 | if (!ppByte || !(*ppByte)) | 2111 | 0 | return false; | 2112 | | | 2113 | 755 | int nDim = m_headerInfo.nDim; | 2114 | | | 2115 | 755 | m_zMinVec.resize(nDim); | 2116 | 755 | m_zMaxVec.resize(nDim); | 2117 | | | 2118 | 755 | std::vector<T> zVec(nDim); | 2119 | 755 | size_t len = nDim * sizeof(T); | 2120 | | | 2121 | 755 | if (nBytesRemaining < len || !memcpy(&zVec[0], *ppByte, len)) | 2122 | 84 | return false; | 2123 | | | 2124 | 671 | (*ppByte) += len; | 2125 | 671 | nBytesRemaining -= len; | 2126 | | | 2127 | 9.10k | for (int i = 0; i < nDim; i++) | 2128 | 8.43k | m_zMinVec[i] = zVec[i]; | 2129 | | | 2130 | 671 | if (nBytesRemaining < len || !memcpy(&zVec[0], *ppByte, len)) | 2131 | 36 | return false; | 2132 | | | 2133 | 635 | (*ppByte) += len; | 2134 | 635 | nBytesRemaining -= len; | 2135 | | | 2136 | 8.28k | for (int i = 0; i < nDim; i++) | 2137 | 7.65k | m_zMaxVec[i] = zVec[i]; | 2138 | | | 2139 | | //printf("read min / max = %f %f\n", m_zMinVec[0], m_zMaxVec[0]); | 2140 | | | 2141 | 635 | return true; | 2142 | 671 | } |
bool GDAL_LercNS::Lerc2::ReadMinMaxRanges<double>(unsigned char const**, unsigned long&, double const*) Line | Count | Source | 2109 | 812 | { | 2110 | 812 | if (!ppByte || !(*ppByte)) | 2111 | 0 | return false; | 2112 | | | 2113 | 812 | int nDim = m_headerInfo.nDim; | 2114 | | | 2115 | 812 | m_zMinVec.resize(nDim); | 2116 | 812 | m_zMaxVec.resize(nDim); | 2117 | | | 2118 | 812 | std::vector<T> zVec(nDim); | 2119 | 812 | size_t len = nDim * sizeof(T); | 2120 | | | 2121 | 812 | if (nBytesRemaining < len || !memcpy(&zVec[0], *ppByte, len)) | 2122 | 97 | return false; | 2123 | | | 2124 | 715 | (*ppByte) += len; | 2125 | 715 | nBytesRemaining -= len; | 2126 | | | 2127 | 51.0k | for (int i = 0; i < nDim; i++) | 2128 | 50.3k | m_zMinVec[i] = zVec[i]; | 2129 | | | 2130 | 715 | if (nBytesRemaining < len || !memcpy(&zVec[0], *ppByte, len)) | 2131 | 60 | return false; | 2132 | | | 2133 | 655 | (*ppByte) += len; | 2134 | 655 | nBytesRemaining -= len; | 2135 | | | 2136 | 28.8k | for (int i = 0; i < nDim; i++) | 2137 | 28.2k | m_zMaxVec[i] = zVec[i]; | 2138 | | | 2139 | | //printf("read min / max = %f %f\n", m_zMinVec[0], m_zMaxVec[0]); | 2140 | | | 2141 | 655 | return true; | 2142 | 715 | } |
|
2143 | | |
2144 | | // -------------------------------------------------------------------------- ; |
2145 | | |
2146 | | inline |
2147 | | bool Lerc2::CheckMinMaxRanges(bool& minMaxEqual) const |
2148 | 24.2k | { |
2149 | 24.2k | int nDim = m_headerInfo.nDim; |
2150 | 24.2k | if ((int)m_zMinVec.size() != nDim || (int)m_zMaxVec.size() != nDim) |
2151 | 0 | return false; |
2152 | | |
2153 | 24.2k | minMaxEqual = (0 == memcmp(&m_zMinVec[0], &m_zMaxVec[0], nDim * sizeof(m_zMinVec[0]))); |
2154 | 24.2k | return true; |
2155 | 24.2k | } |
2156 | | |
2157 | | // -------------------------------------------------------------------------- ; |
2158 | | |
2159 | | template<class T> |
2160 | | bool Lerc2::FillConstImage(T* data) const |
2161 | 1.74k | { |
2162 | 1.74k | if (!data) |
2163 | 0 | return false; |
2164 | | |
2165 | 1.74k | const HeaderInfo& hd = m_headerInfo; |
2166 | 1.74k | int nCols = hd.nCols; |
2167 | 1.74k | int nRows = hd.nRows; |
2168 | 1.74k | int nDim = hd.nDim; |
2169 | 1.74k | T z0 = (T)hd.zMin; |
2170 | | |
2171 | 1.74k | if (nDim == 1) |
2172 | 1.36k | { |
2173 | 19.2M | for (int k = 0, i = 0; i < nRows; i++) |
2174 | 99.1M | for (int j = 0; j < nCols; j++, k++) |
2175 | 79.8M | if (m_bitMask.IsValid(k)) |
2176 | 4.49M | data[k] = z0; |
2177 | 1.36k | } |
2178 | 387 | else |
2179 | 387 | { |
2180 | 387 | std::vector<T> zBufVec(nDim, z0); |
2181 | | |
2182 | 387 | if (hd.zMin != hd.zMax) |
2183 | 236 | { |
2184 | 236 | if ((int)m_zMinVec.size() != nDim) |
2185 | 0 | return false; |
2186 | | |
2187 | 1.60k | for (int m = 0; m < nDim; m++) |
2188 | 1.36k | zBufVec[m] = (T)m_zMinVec[m]; |
2189 | 236 | } |
2190 | | |
2191 | 387 | int len = nDim * sizeof(T); |
2192 | 1.67M | for (int k = 0, m = 0, i = 0; i < nRows; i++) |
2193 | 16.9M | for (int j = 0; j < nCols; j++, k++, m += nDim) |
2194 | 15.3M | if (m_bitMask.IsValid(k)) |
2195 | 1.40M | memcpy(&data[m], &zBufVec[0], len); |
2196 | 387 | } |
2197 | | |
2198 | 1.74k | return true; |
2199 | 1.74k | } bool GDAL_LercNS::Lerc2::FillConstImage<signed char>(signed char*) const Line | Count | Source | 2161 | 431 | { | 2162 | 431 | if (!data) | 2163 | 0 | return false; | 2164 | | | 2165 | 431 | const HeaderInfo& hd = m_headerInfo; | 2166 | 431 | int nCols = hd.nCols; | 2167 | 431 | int nRows = hd.nRows; | 2168 | 431 | int nDim = hd.nDim; | 2169 | 431 | T z0 = (T)hd.zMin; | 2170 | | | 2171 | 431 | if (nDim == 1) | 2172 | 409 | { | 2173 | 3.03k | for (int k = 0, i = 0; i < nRows; i++) | 2174 | 253k | for (int j = 0; j < nCols; j++, k++) | 2175 | 251k | if (m_bitMask.IsValid(k)) | 2176 | 37.9k | data[k] = z0; | 2177 | 409 | } | 2178 | 22 | else | 2179 | 22 | { | 2180 | 22 | std::vector<T> zBufVec(nDim, z0); | 2181 | | | 2182 | 22 | if (hd.zMin != hd.zMax) | 2183 | 12 | { | 2184 | 12 | if ((int)m_zMinVec.size() != nDim) | 2185 | 0 | return false; | 2186 | | | 2187 | 168 | for (int m = 0; m < nDim; m++) | 2188 | 156 | zBufVec[m] = (T)m_zMinVec[m]; | 2189 | 12 | } | 2190 | | | 2191 | 22 | int len = nDim * sizeof(T); | 2192 | 31.0k | for (int k = 0, m = 0, i = 0; i < nRows; i++) | 2193 | 651k | for (int j = 0; j < nCols; j++, k++, m += nDim) | 2194 | 620k | if (m_bitMask.IsValid(k)) | 2195 | 83.4k | memcpy(&data[m], &zBufVec[0], len); | 2196 | 22 | } | 2197 | | | 2198 | 431 | return true; | 2199 | 431 | } |
bool GDAL_LercNS::Lerc2::FillConstImage<unsigned char>(unsigned char*) const Line | Count | Source | 2161 | 759 | { | 2162 | 759 | if (!data) | 2163 | 0 | return false; | 2164 | | | 2165 | 759 | const HeaderInfo& hd = m_headerInfo; | 2166 | 759 | int nCols = hd.nCols; | 2167 | 759 | int nRows = hd.nRows; | 2168 | 759 | int nDim = hd.nDim; | 2169 | 759 | T z0 = (T)hd.zMin; | 2170 | | | 2171 | 759 | if (nDim == 1) | 2172 | 632 | { | 2173 | 10.3M | for (int k = 0, i = 0; i < nRows; i++) | 2174 | 49.7M | for (int j = 0; j < nCols; j++, k++) | 2175 | 39.4M | if (m_bitMask.IsValid(k)) | 2176 | 1.46M | data[k] = z0; | 2177 | 632 | } | 2178 | 127 | else | 2179 | 127 | { | 2180 | 127 | std::vector<T> zBufVec(nDim, z0); | 2181 | | | 2182 | 127 | if (hd.zMin != hd.zMax) | 2183 | 79 | { | 2184 | 79 | if ((int)m_zMinVec.size() != nDim) | 2185 | 0 | return false; | 2186 | | | 2187 | 631 | for (int m = 0; m < nDim; m++) | 2188 | 552 | zBufVec[m] = (T)m_zMinVec[m]; | 2189 | 79 | } | 2190 | | | 2191 | 127 | int len = nDim * sizeof(T); | 2192 | 532k | for (int k = 0, m = 0, i = 0; i < nRows; i++) | 2193 | 5.29M | for (int j = 0; j < nCols; j++, k++, m += nDim) | 2194 | 4.76M | if (m_bitMask.IsValid(k)) | 2195 | 404k | memcpy(&data[m], &zBufVec[0], len); | 2196 | 127 | } | 2197 | | | 2198 | 759 | return true; | 2199 | 759 | } |
bool GDAL_LercNS::Lerc2::FillConstImage<short>(short*) const Line | Count | Source | 2161 | 141 | { | 2162 | 141 | if (!data) | 2163 | 0 | return false; | 2164 | | | 2165 | 141 | const HeaderInfo& hd = m_headerInfo; | 2166 | 141 | int nCols = hd.nCols; | 2167 | 141 | int nRows = hd.nRows; | 2168 | 141 | int nDim = hd.nDim; | 2169 | 141 | T z0 = (T)hd.zMin; | 2170 | | | 2171 | 141 | if (nDim == 1) | 2172 | 101 | { | 2173 | 2.65M | for (int k = 0, i = 0; i < nRows; i++) | 2174 | 13.0M | for (int j = 0; j < nCols; j++, k++) | 2175 | 10.3M | if (m_bitMask.IsValid(k)) | 2176 | 1.69M | data[k] = z0; | 2177 | 101 | } | 2178 | 40 | else | 2179 | 40 | { | 2180 | 40 | std::vector<T> zBufVec(nDim, z0); | 2181 | | | 2182 | 40 | if (hd.zMin != hd.zMax) | 2183 | 20 | { | 2184 | 20 | if ((int)m_zMinVec.size() != nDim) | 2185 | 0 | return false; | 2186 | | | 2187 | 184 | for (int m = 0; m < nDim; m++) | 2188 | 164 | zBufVec[m] = (T)m_zMinVec[m]; | 2189 | 20 | } | 2190 | | | 2191 | 40 | int len = nDim * sizeof(T); | 2192 | 138k | for (int k = 0, m = 0, i = 0; i < nRows; i++) | 2193 | 3.89M | for (int j = 0; j < nCols; j++, k++, m += nDim) | 2194 | 3.75M | if (m_bitMask.IsValid(k)) | 2195 | 426k | memcpy(&data[m], &zBufVec[0], len); | 2196 | 40 | } | 2197 | | | 2198 | 141 | return true; | 2199 | 141 | } |
bool GDAL_LercNS::Lerc2::FillConstImage<unsigned short>(unsigned short*) const Line | Count | Source | 2161 | 158 | { | 2162 | 158 | if (!data) | 2163 | 0 | return false; | 2164 | | | 2165 | 158 | const HeaderInfo& hd = m_headerInfo; | 2166 | 158 | int nCols = hd.nCols; | 2167 | 158 | int nRows = hd.nRows; | 2168 | 158 | int nDim = hd.nDim; | 2169 | 158 | T z0 = (T)hd.zMin; | 2170 | | | 2171 | 158 | if (nDim == 1) | 2172 | 75 | { | 2173 | 1.28M | for (int k = 0, i = 0; i < nRows; i++) | 2174 | 9.47M | for (int j = 0; j < nCols; j++, k++) | 2175 | 8.18M | if (m_bitMask.IsValid(k)) | 2176 | 309k | data[k] = z0; | 2177 | 75 | } | 2178 | 83 | else | 2179 | 83 | { | 2180 | 83 | std::vector<T> zBufVec(nDim, z0); | 2181 | | | 2182 | 83 | if (hd.zMin != hd.zMax) | 2183 | 74 | { | 2184 | 74 | if ((int)m_zMinVec.size() != nDim) | 2185 | 0 | return false; | 2186 | | | 2187 | 317 | for (int m = 0; m < nDim; m++) | 2188 | 243 | zBufVec[m] = (T)m_zMinVec[m]; | 2189 | 74 | } | 2190 | | | 2191 | 83 | int len = nDim * sizeof(T); | 2192 | 173k | for (int k = 0, m = 0, i = 0; i < nRows; i++) | 2193 | 2.32M | for (int j = 0; j < nCols; j++, k++, m += nDim) | 2194 | 2.15M | if (m_bitMask.IsValid(k)) | 2195 | 189k | memcpy(&data[m], &zBufVec[0], len); | 2196 | 83 | } | 2197 | | | 2198 | 158 | return true; | 2199 | 158 | } |
bool GDAL_LercNS::Lerc2::FillConstImage<int>(int*) const Line | Count | Source | 2161 | 51 | { | 2162 | 51 | if (!data) | 2163 | 0 | return false; | 2164 | | | 2165 | 51 | const HeaderInfo& hd = m_headerInfo; | 2166 | 51 | int nCols = hd.nCols; | 2167 | 51 | int nRows = hd.nRows; | 2168 | 51 | int nDim = hd.nDim; | 2169 | 51 | T z0 = (T)hd.zMin; | 2170 | | | 2171 | 51 | if (nDim == 1) | 2172 | 21 | { | 2173 | 2.06M | for (int k = 0, i = 0; i < nRows; i++) | 2174 | 13.4M | for (int j = 0; j < nCols; j++, k++) | 2175 | 11.3M | if (m_bitMask.IsValid(k)) | 2176 | 100k | data[k] = z0; | 2177 | 21 | } | 2178 | 30 | else | 2179 | 30 | { | 2180 | 30 | std::vector<T> zBufVec(nDim, z0); | 2181 | | | 2182 | 30 | if (hd.zMin != hd.zMax) | 2183 | 15 | { | 2184 | 15 | if ((int)m_zMinVec.size() != nDim) | 2185 | 0 | return false; | 2186 | | | 2187 | 101 | for (int m = 0; m < nDim; m++) | 2188 | 86 | zBufVec[m] = (T)m_zMinVec[m]; | 2189 | 15 | } | 2190 | | | 2191 | 30 | int len = nDim * sizeof(T); | 2192 | 116k | for (int k = 0, m = 0, i = 0; i < nRows; i++) | 2193 | 1.18M | for (int j = 0; j < nCols; j++, k++, m += nDim) | 2194 | 1.07M | if (m_bitMask.IsValid(k)) | 2195 | 47.1k | memcpy(&data[m], &zBufVec[0], len); | 2196 | 30 | } | 2197 | | | 2198 | 51 | return true; | 2199 | 51 | } |
bool GDAL_LercNS::Lerc2::FillConstImage<unsigned int>(unsigned int*) const Line | Count | Source | 2161 | 120 | { | 2162 | 120 | if (!data) | 2163 | 0 | return false; | 2164 | | | 2165 | 120 | const HeaderInfo& hd = m_headerInfo; | 2166 | 120 | int nCols = hd.nCols; | 2167 | 120 | int nRows = hd.nRows; | 2168 | 120 | int nDim = hd.nDim; | 2169 | 120 | T z0 = (T)hd.zMin; | 2170 | | | 2171 | 120 | if (nDim == 1) | 2172 | 87 | { | 2173 | 826k | for (int k = 0, i = 0; i < nRows; i++) | 2174 | 3.72M | for (int j = 0; j < nCols; j++, k++) | 2175 | 2.90M | if (m_bitMask.IsValid(k)) | 2176 | 200k | data[k] = z0; | 2177 | 87 | } | 2178 | 33 | else | 2179 | 33 | { | 2180 | 33 | std::vector<T> zBufVec(nDim, z0); | 2181 | | | 2182 | 33 | if (hd.zMin != hd.zMax) | 2183 | 17 | { | 2184 | 17 | if ((int)m_zMinVec.size() != nDim) | 2185 | 0 | return false; | 2186 | | | 2187 | 105 | for (int m = 0; m < nDim; m++) | 2188 | 88 | zBufVec[m] = (T)m_zMinVec[m]; | 2189 | 17 | } | 2190 | | | 2191 | 33 | int len = nDim * sizeof(T); | 2192 | 308k | for (int k = 0, m = 0, i = 0; i < nRows; i++) | 2193 | 1.67M | for (int j = 0; j < nCols; j++, k++, m += nDim) | 2194 | 1.36M | if (m_bitMask.IsValid(k)) | 2195 | 125k | memcpy(&data[m], &zBufVec[0], len); | 2196 | 33 | } | 2197 | | | 2198 | 120 | return true; | 2199 | 120 | } |
bool GDAL_LercNS::Lerc2::FillConstImage<float>(float*) const Line | Count | Source | 2161 | 41 | { | 2162 | 41 | if (!data) | 2163 | 0 | return false; | 2164 | | | 2165 | 41 | const HeaderInfo& hd = m_headerInfo; | 2166 | 41 | int nCols = hd.nCols; | 2167 | 41 | int nRows = hd.nRows; | 2168 | 41 | int nDim = hd.nDim; | 2169 | 41 | T z0 = (T)hd.zMin; | 2170 | | | 2171 | 41 | if (nDim == 1) | 2172 | 17 | { | 2173 | 1.17M | for (int k = 0, i = 0; i < nRows; i++) | 2174 | 6.18M | for (int j = 0; j < nCols; j++, k++) | 2175 | 5.01M | if (m_bitMask.IsValid(k)) | 2176 | 335k | data[k] = z0; | 2177 | 17 | } | 2178 | 24 | else | 2179 | 24 | { | 2180 | 24 | std::vector<T> zBufVec(nDim, z0); | 2181 | | | 2182 | 24 | if (hd.zMin != hd.zMax) | 2183 | 9 | { | 2184 | 9 | if ((int)m_zMinVec.size() != nDim) | 2185 | 0 | return false; | 2186 | | | 2187 | 46 | for (int m = 0; m < nDim; m++) | 2188 | 37 | zBufVec[m] = (T)m_zMinVec[m]; | 2189 | 9 | } | 2190 | | | 2191 | 24 | int len = nDim * sizeof(T); | 2192 | 141k | for (int k = 0, m = 0, i = 0; i < nRows; i++) | 2193 | 1.12M | for (int j = 0; j < nCols; j++, k++, m += nDim) | 2194 | 980k | if (m_bitMask.IsValid(k)) | 2195 | 87.5k | memcpy(&data[m], &zBufVec[0], len); | 2196 | 24 | } | 2197 | | | 2198 | 41 | return true; | 2199 | 41 | } |
bool GDAL_LercNS::Lerc2::FillConstImage<double>(double*) const Line | Count | Source | 2161 | 46 | { | 2162 | 46 | if (!data) | 2163 | 0 | return false; | 2164 | | | 2165 | 46 | const HeaderInfo& hd = m_headerInfo; | 2166 | 46 | int nCols = hd.nCols; | 2167 | 46 | int nRows = hd.nRows; | 2168 | 46 | int nDim = hd.nDim; | 2169 | 46 | T z0 = (T)hd.zMin; | 2170 | | | 2171 | 46 | if (nDim == 1) | 2172 | 18 | { | 2173 | 923k | for (int k = 0, i = 0; i < nRows; i++) | 2174 | 3.27M | for (int j = 0; j < nCols; j++, k++) | 2175 | 2.35M | if (m_bitMask.IsValid(k)) | 2176 | 359k | data[k] = z0; | 2177 | 18 | } | 2178 | 28 | else | 2179 | 28 | { | 2180 | 28 | std::vector<T> zBufVec(nDim, z0); | 2181 | | | 2182 | 28 | if (hd.zMin != hd.zMax) | 2183 | 10 | { | 2184 | 10 | if ((int)m_zMinVec.size() != nDim) | 2185 | 0 | return false; | 2186 | | | 2187 | 51 | for (int m = 0; m < nDim; m++) | 2188 | 41 | zBufVec[m] = (T)m_zMinVec[m]; | 2189 | 10 | } | 2190 | | | 2191 | 28 | int len = nDim * sizeof(T); | 2192 | 231k | for (int k = 0, m = 0, i = 0; i < nRows; i++) | 2193 | 828k | for (int j = 0; j < nCols; j++, k++, m += nDim) | 2194 | 596k | if (m_bitMask.IsValid(k)) | 2195 | 37.4k | memcpy(&data[m], &zBufVec[0], len); | 2196 | 28 | } | 2197 | | | 2198 | 46 | return true; | 2199 | 46 | } |
|
2200 | | |
2201 | | // -------------------------------------------------------------------------- ; |
2202 | | |
2203 | | NAMESPACE_LERC_END |
2204 | | #endif |