Line data Source code
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 : #pragma once
25 :
26 : #include <cstring>
27 : #include <vector>
28 : #include "Lerc_types.h"
29 : #include "BitMask.h"
30 : #include "Lerc2.h"
31 :
32 : NAMESPACE_LERC_START
33 :
34 : #ifdef HAVE_LERC1_DECODE
35 : class CntZImage;
36 : #endif
37 :
38 : class Lerc
39 : {
40 : public:
41 : Lerc() {}
42 : ~Lerc() {}
43 :
44 : // data types supported by Lerc
45 : enum DataType { DT_Char, DT_Byte, DT_Short, DT_UShort, DT_Int, DT_UInt, DT_Float, DT_Double, DT_Undefined };
46 :
47 : // all functions are provided in 2 flavors
48 : // - using void pointers to the image data, can be called on a Lerc lib or dll
49 : // - data templated, can be called if compiled together
50 :
51 :
52 : // Encode
53 :
54 : // if more than 1 band, the outgoing Lerc blob has the single band Lerc blobs concatenated;
55 : // or, if you have multiple values per pixel and stored as [RGB, RGB, ... ], then set nDim accordingly (e.g., 3)
56 :
57 : // computes the number of bytes needed to allocate the buffer, accurate to the byte;
58 : // does not encode the image data, but uses statistics and formulas to compute the buffer size needed;
59 : // this function is optional, you can also use a buffer large enough to call Encode() directly,
60 : // or, if encoding a batch of same width / height tiles, call this function once, double the buffer size, and
61 : // then just call Encode() on all tiles;
62 :
63 : static ErrCode ComputeCompressedSize(
64 : const void* pData, // raw image data, row by row, band by band
65 : int version, // 2 = v2.2, 3 = v2.3, 4 = v2.4
66 : DataType dt, // data type, char to double
67 : int nDim, // number of values per pixel
68 : int nCols, // number of cols
69 : int nRows, // number of rows
70 : int nBands, // number of bands
71 : const BitMask* pBitMask, // 0 if all pixels are valid
72 : double maxZErr, // max coding error per pixel, defines the precision
73 : unsigned int& numBytesNeeded); // size of outgoing Lerc blob
74 :
75 : // encodes or compresses the image data into the buffer
76 :
77 : static ErrCode Encode(
78 : const void* pData, // raw image data, row by row, band by band
79 : int version, // 2 = v2.2, 3 = v2.3, 4 = v2.4
80 : DataType dt, // data type, char to double
81 : int nDim, // number of values per pixel
82 : int nCols, // number of cols
83 : int nRows, // number of rows
84 : int nBands, // number of bands
85 : const BitMask* pBitMask, // 0 if all pixels are valid
86 : double maxZErr, // max coding error per pixel, defines the precision
87 : Byte* pBuffer, // buffer to write to, function fails if buffer too small
88 : unsigned int numBytesBuffer, // buffer size
89 : unsigned int& numBytesWritten); // num bytes written to buffer
90 :
91 :
92 : // Decode
93 :
94 : struct LercInfo
95 : {
96 : int version, // Lerc version number (0 for old Lerc1, 1 to 4 for Lerc 2.1 to 2.4)
97 : nDim, // number of values per pixel
98 : nCols, // number of columns
99 : nRows, // number of rows
100 : numValidPixel, // number of valid pixels
101 : nBands, // number of bands
102 : blobSize; // total blob size in bytes
103 : DataType dt; // data type (float only for old Lerc1)
104 : double zMin, // min pixel value, over all data values
105 : zMax, // max pixel value, over all data values
106 : maxZError; // maxZError used for encoding
107 :
108 531 : void RawInit() { memset(this, 0, sizeof(struct LercInfo)); }
109 : };
110 :
111 : // again, this function is optional;
112 : // call it on a Lerc blob to get the above struct returned, from this the data arrays
113 : // can be constructed before calling Decode();
114 : // same as above, for a batch of Lerc blobs of the same kind, you can call this function on
115 : // the first blob, get the info, and on the other Lerc blobs just call Decode();
116 : // this function is very fast on (newer) Lerc2 blobs as it only reads the blob headers;
117 :
118 : // Remark on param numBytesBlob. Usually it is known, either the file size of the blob written to disk,
119 : // or the size of the blob transmitted. It should be accurate for 2 reasons:
120 : // _ function finds out how many single band Lerc blobs are concatenated
121 : // _ function checks for truncated file or blob
122 : // It is OK to pass numBytesBlob too large as long as there is no other (valid) Lerc blob following next.
123 : // If in doubt, check the code in Lerc::GetLercInfo(...) for the exact logic.
124 :
125 : static ErrCode GetLercInfo(const Byte* pLercBlob, // Lerc blob to decode
126 : unsigned int numBytesBlob, // size of Lerc blob in bytes
127 : struct LercInfo& lercInfo);
128 :
129 : // setup outgoing arrays accordingly, then call Decode()
130 :
131 : static ErrCode Decode(
132 : const Byte* pLercBlob, // Lerc blob to decode
133 : unsigned int numBytesBlob, // size of Lerc blob in bytes
134 : BitMask* pBitMask, // gets filled if not 0, even if all valid
135 : int nDim, // number of values per pixel
136 : int nCols, // number of cols
137 : int nRows, // number of rows
138 : int nBands, // number of bands
139 : DataType dt, // data type of outgoing array
140 : void* pData); // outgoing data bands
141 :
142 :
143 : static ErrCode ConvertToDouble(
144 : const void* pDataIn, // pixel data of image tile of data type dt (< double)
145 : DataType dt, // data type of input data
146 : size_t nDataValues, // total number of data values (nDim * nCols * nRows * nBands)
147 : double* pDataOut); // pixel data converted to double
148 :
149 :
150 : // same as functions above, but data templated instead of using void pointers
151 :
152 : template<class T> static ErrCode ComputeCompressedSizeTempl(
153 : const T* pData, // raw image data, row by row, band by
154 : int version, // 2 = v2.2, 3 = v2.3, 4 = v2.4
155 : int nDim, // number of values per pixel
156 : int nCols, // number of cols
157 : int nRows, // number of rows
158 : int nBands, // number of bands
159 : const BitMask* pBitMask, // 0 means all pixels are valid
160 : double maxZErr, // max coding error per pixel, defines the precision
161 : unsigned int& numBytes); // size of outgoing Lerc blob
162 :
163 : template<class T> static ErrCode EncodeTempl(
164 : const T* pData, // raw image data, row by row, band by band
165 : int version, // 2 = v2.2, 3 = v2.3, 4 = v2.4
166 : int nDim, // number of values per pixel
167 : int nCols, // number of cols
168 : int nRows, // number of rows
169 : int nBands, // number of bands
170 : const BitMask* pBitMask, // 0 means all pixels are valid
171 : double maxZErr, // max coding error per pixel, defines the precision
172 : Byte* pBuffer, // buffer to write to, function will fail if buffer too small
173 : unsigned int numBytesBuffer, // buffer size
174 : unsigned int& numBytesWritten); // num bytes written to buffer
175 :
176 : template<class T> static ErrCode DecodeTempl(
177 : T* pData, // outgoing data bands
178 : const Byte* pLercBlob, // Lerc blob to decode
179 : unsigned int numBytesBlob, // size of Lerc blob in bytes
180 : int nDim, // number of values per pixel
181 : int nCols, // number of cols
182 : int nRows, // number of rows
183 : int nBands, // number of bands
184 : BitMask* pBitMask); // gets filled if not 0, even if all valid
185 :
186 : private:
187 : #ifdef HAVE_LERC1_DECODE
188 : template<class T> static bool Convert(const CntZImage& zImg, T* arr, BitMask* pBitMask);
189 : #endif
190 : template<class T> static ErrCode ConvertToDoubleTempl(const T* pDataIn, size_t nDataValues, double* pDataOut);
191 :
192 : template<class T> static ErrCode CheckForNaN(const T* arr, int nDim, int nCols, int nRows, const BitMask* pBitMask);
193 : };
194 : NAMESPACE_LERC_END
|