comparison CSP2/CSP2_env/env-d9b9114564458d9d-741b3de822f2aaca6c6caa4325c4afce/include/Lerc_c_api.h @ 69:33d812a61356

planemo upload commit 2e9511a184a1ca667c7be0c6321a36dc4e3d116d
author jpayne
date Tue, 18 Mar 2025 17:55:14 -0400
parents
children
comparison
equal deleted inserted replaced
67:0e9998148a16 69:33d812a61356
1 /*
2 Copyright 2016 - 2022 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 LERC_API_INCLUDE_GUARD
25 #define LERC_API_INCLUDE_GUARD
26
27 //#define USE_EMSCRIPTEN // to build a wasm Lerc decoder, install emscripten first
28
29 #ifdef USE_EMSCRIPTEN
30 #include <emscripten/emscripten.h>
31 #endif
32
33 #ifdef __cplusplus
34 extern "C" {
35 #endif
36
37 /* LERC version numbers and related macros added in 3.0.0 */
38
39 #define LERC_VERSION_MAJOR 4
40 #define LERC_VERSION_MINOR 0
41 #define LERC_VERSION_PATCH 0
42
43 /* Macro to compute a LERC version number from its components */
44 #define LERC_COMPUTE_VERSION(maj,min,patch) ((maj)*10000+(min)*100+(patch))
45
46 /* Current LERC version from the above version numbers */
47 #define LERC_VERSION_NUMBER \
48 LERC_COMPUTE_VERSION(LERC_VERSION_MAJOR, LERC_VERSION_MINOR, LERC_VERSION_PATCH)
49
50 /* Macro that returns true if the current LERC version is at least the version specified by (maj,min,patch) */
51 #define LERC_AT_LEAST_VERSION(maj,min,patch) \
52 (LERC_VERSION_NUMBER >= LERC_COMPUTE_VERSION(maj,min,patch))
53
54 #if defined _WIN32 || defined __CYGWIN__
55 # if defined(LERC_STATIC)
56 # define LERCDLL_API
57 # elif defined(LERC_EXPORTS)
58 # define LERCDLL_API __declspec(dllexport)
59 # else
60 # define LERCDLL_API __declspec(dllimport)
61 # endif
62 #elif __GNUC__ >= 4
63 #define LERCDLL_API __attribute__((visibility("default")))
64 #else
65 #define LERCDLL_API
66 #endif
67
68 //! C-API for LERC library
69
70
71 //! Added in version 4.0:
72 //!
73 //! - 1) better support 3D and 4D data, allow for lossy encoding even if a noData value is used
74 //! - 2) better lossless compression for float and double (pass maxZError = 0)
75 //! - 3) allow to pass integer > 32 bit as double (Lerc detects it is all integer and uses that)
76 //! - 4) renamed nDim to nDepth (without changing the function signatures)
77 //!
78 //! More on 1). In version 3.0, for 2D images, the 2D valid / invalid byte masks represent invalid pixels.
79 //! For more than 1 band, different masks per band can be used. No change to that.
80 //! For nDepth > 1, or an array of values per pixel, there is the special case of a mix of valid and invalid values
81 //! at the same pixel. The 2D mask cannot cover this case.
82 //! We have added 4 new functions to version 4.0 to cover this case, see below. If you don't encounter this
83 //! "mixed case", you can continue using the same API functions as in version 3.0.
84 //! If you should encounter a Lerc blob that has this mix, both the regular lerc_decode() and
85 //! lerc_getDataRanges() functions will fail with "ErrCode::HasNoData".
86 //! In that case, you need to call the new lerc_decode_4D() function.
87 //!
88 //! More on 2). Better lossless compression for float and double is enabled for all API functions.
89 //! For 1) and 3) you have to call the new "..._4D()" functions, see further below.
90
91
92 typedef unsigned int lerc_status;
93
94 //! All output buffers must have been allocated by the caller.
95
96 //! Compute the buffer size in bytes required to hold the compressed input tile. Optional.
97 //! You can call lerc_encode(...) directly as long as the output buffer is big enough.
98
99 //! Order of raw input data is top left corner to lower right corner, row by row. This for each band.
100 //! Data type is { char = 0, uchar = 1, short = 2, ushort = 3, int = 4, uint = 5, float = 6, double = 7 }, see Lerc_types.h .
101 //! maxZErr is the max compression error per pixel allowed.
102
103 //! The image or mask of valid pixels is optional. Nullptr means all pixels are valid.
104 //! If not all pixels are valid, set invalid pixel bytes to 0, valid pixel bytes to 1.
105 //! Size of the valid / invalid pixel image is (nCols * nRows * nMasks).
106
107 LERCDLL_API
108 lerc_status lerc_computeCompressedSize(
109 const void* pData, // raw image data, row by row, band by band
110 unsigned int dataType, // char = 0, uchar = 1, short = 2, ushort = 3, int = 4, uint = 5, float = 6, double = 7
111 int nDepth, // number of values per pixel (e.g., 3 for RGB, data is stored as [RGB, RGB, ...])
112 int nCols, // number of columns
113 int nRows, // number of rows
114 int nBands, // number of bands (e.g., 3 for [RRRR ..., GGGG ..., BBBB ...])
115 int nMasks, // 0 - all valid, 1 - same mask for all bands, nBands - masks can differ between bands
116 const unsigned char* pValidBytes, // nullptr if all pixels are valid; otherwise 1 byte per pixel (1 = valid, 0 = invalid)
117 double maxZErr, // max coding error per pixel, defines the precision
118 unsigned int* numBytes); // size of outgoing Lerc blob
119
120 //! Encode the input data into a compressed Lerc blob.
121
122 LERCDLL_API
123 lerc_status lerc_encode(
124 const void* pData, // raw image data, row by row, band by band
125 unsigned int dataType, // char = 0, uchar = 1, short = 2, ushort = 3, int = 4, uint = 5, float = 6, double = 7
126 int nDepth, // number of values per pixel (e.g., 3 for RGB, data is stored as [RGB, RGB, ...])
127 int nCols, // number of columns
128 int nRows, // number of rows
129 int nBands, // number of bands (e.g., 3 for [RRRR ..., GGGG ..., BBBB ...])
130 int nMasks, // 0 - all valid, 1 - same mask for all bands, nBands - masks can differ between bands
131 const unsigned char* pValidBytes, // nullptr if all pixels are valid; otherwise 1 byte per pixel (1 = valid, 0 = invalid)
132 double maxZErr, // max coding error per pixel, defines the precision
133 unsigned char* pOutBuffer, // buffer to write to, function fails if buffer too small
134 unsigned int outBufferSize, // size of output buffer
135 unsigned int* nBytesWritten); // number of bytes written to output buffer
136
137
138 //! Use the 2 functions below to encode to an older codec version
139
140 LERCDLL_API
141 lerc_status lerc_computeCompressedSizeForVersion(
142 const void* pData, // raw image data, row by row, band by band
143 int codecVersion, // [2 .. 6] for [v2.2 .. v2.6], or -1 for latest codec v2.6
144 unsigned int dataType, // char = 0, uchar = 1, short = 2, ushort = 3, int = 4, uint = 5, float = 6, double = 7
145 int nDepth, // number of values per pixel (e.g., 3 for RGB, data is stored as [RGB, RGB, ...])
146 int nCols, // number of columns
147 int nRows, // number of rows
148 int nBands, // number of bands (e.g., 3 for [RRRR ..., GGGG ..., BBBB ...])
149 int nMasks, // 0 - all valid, 1 - same mask for all bands, nBands - masks can differ between bands
150 const unsigned char* pValidBytes, // nullptr if all pixels are valid; otherwise 1 byte per pixel (1 = valid, 0 = invalid)
151 double maxZErr, // max coding error per pixel, defines the precision
152 unsigned int* numBytes); // size of outgoing Lerc blob
153
154 LERCDLL_API
155 lerc_status lerc_encodeForVersion(
156 const void* pData, // raw image data, row by row, band by band
157 int codecVersion, // [2 .. 6] for [v2.2 .. v2.6], or -1 for latest codec v2.6
158 unsigned int dataType, // char = 0, uchar = 1, short = 2, ushort = 3, int = 4, uint = 5, float = 6, double = 7
159 int nDepth, // number of values per pixel (e.g., 3 for RGB, data is stored as [RGB, RGB, ...])
160 int nCols, // number of columns
161 int nRows, // number of rows
162 int nBands, // number of bands (e.g., 3 for [RRRR ..., GGGG ..., BBBB ...])
163 int nMasks, // 0 - all valid, 1 - same mask for all bands, nBands - masks can differ between bands
164 const unsigned char* pValidBytes, // nullptr if all pixels are valid; otherwise 1 byte per pixel (1 = valid, 0 = invalid)
165 double maxZErr, // max coding error per pixel, defines the precision
166 unsigned char* pOutBuffer, // buffer to write to, function fails if buffer too small
167 unsigned int outBufferSize, // size of output buffer
168 unsigned int* nBytesWritten); // number of bytes written to output buffer
169
170
171 //! Call this to get info about the compressed Lerc blob. Optional.
172 //! Info returned in infoArray is
173 //! { version, dataType, nDepth, nCols, nRows, nBands, nValidPixels, blobSize, nMasks, nDepth, nUsesNoDataValue }, see Lerc_types.h .
174 //! Info returned in dataRangeArray is { zMin, zMax, maxZErrorUsed }, see Lerc_types.h .
175 //! If nDepth > 1 or nBands > 1 the data range [zMin, zMax] is over all values.
176
177 // Remark on function signature. The arrays to be filled may grow in future versions. In order not to break
178 // existing code, the function fills these arrays only up to their allocated size.
179
180 // Remark on param blobSize. Usually it is known, either the file size of the blob written to disk,
181 // or the size of the blob transmitted. It should be passed accurately for 2 reasons:
182 // _ function finds out how many single band Lerc blobs are concatenated, if any
183 // _ function checks for truncated file or blob
184 // It is OK to pass blobSize too large as long as there is no other (valid) Lerc blob following next.
185 // If in doubt, check the code in Lerc::GetLercInfo(...) for the exact logic.
186
187 LERCDLL_API
188 #ifdef USE_EMSCRIPTEN
189 EMSCRIPTEN_KEEPALIVE
190 #endif
191 lerc_status lerc_getBlobInfo(
192 const unsigned char* pLercBlob, // Lerc blob to decode
193 unsigned int blobSize, // blob size in bytes
194 unsigned int* infoArray, // info array with all info needed to allocate the outgoing arrays for calling decode
195 double* dataRangeArray, // quick access to overall data range [zMin, zMax] without having to decode the data
196 int infoArraySize, // number of elements of infoArray
197 int dataRangeArraySize); // number of elements of dataRangeArray
198
199 //! Call this to quickly get the data ranges [min, max] per dimension and band without having to decode the pixels. Optional.
200 //! The 2 output data arrays must have been allocated to the same size (nDepth * nBands).
201 //! The output data array's layout is an image with nDepth columns and nBands rows.
202
203 LERCDLL_API
204 #ifdef USE_EMSCRIPTEN
205 EMSCRIPTEN_KEEPALIVE
206 #endif
207 lerc_status lerc_getDataRanges(
208 const unsigned char* pLercBlob, // Lerc blob to decode
209 unsigned int blobSize, // blob size in bytes
210 int nDepth, // number of values per pixel (e.g., 3 for RGB, data is stored as [RGB, RGB, ...])
211 int nBands, // number of bands (e.g., 3 for [RRRR ..., GGGG ..., BBBB ...])
212 double* pMins, // outgoing minima per dimension and band
213 double* pMaxs); // outgoing maxima per dimension and band
214
215 //! Decode the compressed Lerc blob into a raw data array.
216 //! The data array must have been allocated to size (nDepth * nCols * nRows * nBands * sizeof(dataType)).
217 //! The valid pixels array, if not all pixels valid, must have been allocated to size (nCols * nRows * nMasks).
218
219 LERCDLL_API
220 #ifdef USE_EMSCRIPTEN
221 EMSCRIPTEN_KEEPALIVE
222 #endif
223 lerc_status lerc_decode(
224 const unsigned char* pLercBlob, // Lerc blob to decode
225 unsigned int blobSize, // blob size in bytes
226 int nMasks, // 0, 1, or nBands; return as many masks in the next array
227 unsigned char* pValidBytes, // gets filled if not nullptr, even if all valid
228 int nDepth, // number of values per pixel (e.g., 3 for RGB, data is stored as [RGB, RGB, ...])
229 int nCols, // number of columns
230 int nRows, // number of rows
231 int nBands, // number of bands (e.g., 3 for [RRRR ..., GGGG ..., BBBB ...])
232 unsigned int dataType, // char = 0, uchar = 1, short = 2, ushort = 3, int = 4, uint = 5, float = 6, double = 7
233 void* pData); // outgoing data array
234
235 //! Same as above, but decode into double array independent of compressed data type.
236 //! Wasteful in memory, but convenient if a caller from Python or C# does not want to deal with
237 //! data type conversion, templating, or casting.
238 //! Should this api be extended to new data types that don't fit into a double such as int64,
239 //! then this function will fail for such compressed data types.
240
241 LERCDLL_API
242 lerc_status lerc_decodeToDouble(
243 const unsigned char* pLercBlob, // Lerc blob to decode
244 unsigned int blobSize, // blob size in bytes
245 int nMasks, // 0, 1, or nBands; return as many masks in the next array
246 unsigned char* pValidBytes, // gets filled if not nullptr, even if all valid
247 int nDepth, // number of values per pixel (e.g., 3 for RGB, data is stored as [RGB, RGB, ...])
248 int nCols, // number of columns
249 int nRows, // number of rows
250 int nBands, // number of bands (e.g., 3 for [RRRR ..., GGGG ..., BBBB ...])
251 double* pData); // outgoing data array
252
253
254 //! Added in version 4.0:
255 //!
256 //! The 4 functions below are new. The main purpose (and difference to the functions above) is to support, for 3D and 4D data,
257 //! the special case of a mix of valid and invalid values at the same pixel.
258 //!
259 //! Main idea: Lerc has the property that for each 8x8 pixel block the minimum value is always encoded lossless in the block header.
260 //! To enable lossy encoding in the presence of noData values, the original noData value is mapped below the range of the valid values,
261 //! if possible. If not possible, it switches to lossless. On decode, that temporary noData value gets mapped back to the original
262 //! noData value.
263 //!
264 //! To minimize the occurence of noData values (and for better compression), Lerc tries to move noData values to the byte mask
265 //! wherever possible (e.g., all values at some pixel are invalid). So for a given band the noData values may disappear and get
266 //! all moved to the byte mask. Decode only returns a noData value if it is really used. In that case the caller needs to filter
267 //! the decoded arrays using both the byte mask returned and the noData value returned.
268 //!
269 //! In addition to the noData support, the new functions can also take integer values > 32 bit (but < 53 bit) as a double array,
270 //! and if all integer, use that for compression.
271 //!
272 //! If floating point data contains NaN, Lerc tries to move it to the byte mask or replace it by a passed noData value.
273 //! Note, if not all NaN values can be moved to the mask (mixed case), and no noData value was passed, Lerc will fail.
274 //! It would be wrong to invent a noData value on the tile level.
275
276
277 //! Encode functions:
278 //!
279 //! If you don't use a noData value, are fine with the byte masks, just pass nullptr for the last 2 arguments.
280 //!
281 //! If you do have noData values at pixels that are marked as valid pixels by the byte mask,
282 //! pass 2 arrays of size nBands each, one value per band.
283 //! In pUsesNoData array, for each band, pass 1 for noData value is used, 0 if not.
284 //! In noDataValues array, for each band, pass the noData value if there is one.
285
286 LERCDLL_API
287 lerc_status lerc_computeCompressedSize_4D(
288 const void* pData, // raw image data, row by row, band by band
289 unsigned int dataType, // char = 0, uchar = 1, short = 2, ushort = 3, int = 4, uint = 5, float = 6, double = 7
290 int nDepth, // number of values per pixel (e.g., 3 for RGB, data is stored as [RGB, RGB, ...])
291 int nCols, // number of columns
292 int nRows, // number of rows
293 int nBands, // number of bands (e.g., 3 for [RRRR ..., GGGG ..., BBBB ...])
294 int nMasks, // 0 - all valid, 1 - same mask for all bands, nBands - masks can differ between bands
295 const unsigned char* pValidBytes, // nullptr if all pixels are valid; otherwise 1 byte per pixel (1 = valid, 0 = invalid)
296 double maxZErr, // max coding error per pixel, defines the precision
297 unsigned int* numBytes, // size of outgoing Lerc blob
298 const unsigned char* pUsesNoData, // if there are invalid values not marked by the mask, pass an array of size nBands, 1 - uses noData, 0 - not
299 const double* noDataValues); // same, pass an array of size nBands with noData value per band, or pass nullptr
300
301 LERCDLL_API
302 lerc_status lerc_encode_4D(
303 const void* pData, // raw image data, row by row, band by band
304 unsigned int dataType, // char = 0, uchar = 1, short = 2, ushort = 3, int = 4, uint = 5, float = 6, double = 7
305 int nDepth, // number of values per pixel (e.g., 3 for RGB, data is stored as [RGB, RGB, ...])
306 int nCols, // number of columns
307 int nRows, // number of rows
308 int nBands, // number of bands (e.g., 3 for [RRRR ..., GGGG ..., BBBB ...])
309 int nMasks, // 0 - all valid, 1 - same mask for all bands, nBands - masks can differ between bands
310 const unsigned char* pValidBytes, // nullptr if all pixels are valid; otherwise 1 byte per pixel (1 = valid, 0 = invalid)
311 double maxZErr, // max coding error per pixel, defines the precision
312 unsigned char* pOutBuffer, // buffer to write to, function fails if buffer too small
313 unsigned int outBufferSize, // size of output buffer
314 unsigned int* nBytesWritten, // number of bytes written to output buffer
315 const unsigned char* pUsesNoData, // if there are invalid values not marked by the mask, pass an array of size nBands, 1 - uses noData, 0 - not
316 const double* noDataValues); // same, pass an array of size nBands with noData value per band, or pass nullptr
317
318
319 //! Decode functions:
320 //!
321 //! Same as for regular decode, first call lerc_getBlobInfo() to get all info needed from the blob header.
322 //! Check the property (InfoArray::nUsesNoDataValue) to check if there is any noData value used.
323 //!
324 //! If not, just pass nullptr for the last 2 arguments.
325 //!
326 //! If yes, pass 2 arrays of size nBands each, one value per band.
327 //! In pUsesNoData array, for each band, 1 means a noData value is used, 0 means not.
328 //! In noDataValues array, for each band, it has the noData value if there is one.
329 //! This is the same noData value as passed for encode.
330
331 LERCDLL_API
332 #ifdef USE_EMSCRIPTEN
333 EMSCRIPTEN_KEEPALIVE
334 #endif
335 lerc_status lerc_decode_4D(
336 const unsigned char* pLercBlob, // Lerc blob to decode
337 unsigned int blobSize, // blob size in bytes
338 int nMasks, // 0, 1, or nBands; return as many masks in the next array
339 unsigned char* pValidBytes, // gets filled if not nullptr, even if all valid
340 int nDepth, // number of values per pixel (e.g., 3 for RGB, data is stored as [RGB, RGB, ...])
341 int nCols, // number of columns
342 int nRows, // number of rows
343 int nBands, // number of bands (e.g., 3 for [RRRR ..., GGGG ..., BBBB ...])
344 unsigned int dataType, // char = 0, uchar = 1, short = 2, ushort = 3, int = 4, uint = 5, float = 6, double = 7
345 void* pData, // outgoing data array
346 unsigned char* pUsesNoData, // pass an array of size nBands, 1 - band uses noData, 0 - not
347 double* noDataValues); // same, pass an array of size nBands to get the noData value per band, if any
348
349 LERCDLL_API
350 lerc_status lerc_decodeToDouble_4D(
351 const unsigned char* pLercBlob, // Lerc blob to decode
352 unsigned int blobSize, // blob size in bytes
353 int nMasks, // 0, 1, or nBands; return as many masks in the next array
354 unsigned char* pValidBytes, // gets filled if not nullptr, even if all valid
355 int nDepth, // number of values per pixel (e.g., 3 for RGB, data is stored as [RGB, RGB, ...])
356 int nCols, // number of columns
357 int nRows, // number of rows
358 int nBands, // number of bands (e.g., 3 for [RRRR ..., GGGG ..., BBBB ...])
359 double* pData, // outgoing data array
360 unsigned char* pUsesNoData, // pass an array of size nBands, 1 - band uses noData, 0 - not
361 double* noDataValues); // same, pass an array of size nBands to get the noData value per band, if any
362
363
364 #ifdef __cplusplus
365 }
366 #endif
367
368 #endif // LERC_API_INCLUDE_GUARD