Mercurial > repos > rliterman > csp2
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 |