Lerc_c_api.h 22 KB

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