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

planemo upload commit 2e9511a184a1ca667c7be0c6321a36dc4e3d116d
author jpayne
date Tue, 18 Mar 2025 17:55:14 -0400
parents
children
rev   line source
jpayne@69 1 /*
jpayne@69 2 * libdeflate.h - public header for libdeflate
jpayne@69 3 */
jpayne@69 4
jpayne@69 5 #ifndef LIBDEFLATE_H
jpayne@69 6 #define LIBDEFLATE_H
jpayne@69 7
jpayne@69 8 #include <stddef.h>
jpayne@69 9 #include <stdint.h>
jpayne@69 10
jpayne@69 11 #ifdef __cplusplus
jpayne@69 12 extern "C" {
jpayne@69 13 #endif
jpayne@69 14
jpayne@69 15 #define LIBDEFLATE_VERSION_MAJOR 1
jpayne@69 16 #define LIBDEFLATE_VERSION_MINOR 17
jpayne@69 17 #define LIBDEFLATE_VERSION_STRING "1.17"
jpayne@69 18
jpayne@69 19 /*
jpayne@69 20 * Users of libdeflate.dll on Windows can define LIBDEFLATE_DLL to cause
jpayne@69 21 * __declspec(dllimport) to be used. This should be done when it's easy to do.
jpayne@69 22 * Otherwise it's fine to skip it, since it is a very minor performance
jpayne@69 23 * optimization that is irrelevant for most use cases of libdeflate.
jpayne@69 24 */
jpayne@69 25 #ifndef LIBDEFLATEAPI
jpayne@69 26 # if defined(LIBDEFLATE_DLL) && (defined(_WIN32) || defined(__CYGWIN__))
jpayne@69 27 # define LIBDEFLATEAPI __declspec(dllimport)
jpayne@69 28 # else
jpayne@69 29 # define LIBDEFLATEAPI
jpayne@69 30 # endif
jpayne@69 31 #endif
jpayne@69 32
jpayne@69 33 /* ========================================================================== */
jpayne@69 34 /* Compression */
jpayne@69 35 /* ========================================================================== */
jpayne@69 36
jpayne@69 37 struct libdeflate_compressor;
jpayne@69 38
jpayne@69 39 /*
jpayne@69 40 * libdeflate_alloc_compressor() allocates a new compressor that supports
jpayne@69 41 * DEFLATE, zlib, and gzip compression. 'compression_level' is the compression
jpayne@69 42 * level on a zlib-like scale but with a higher maximum value (1 = fastest, 6 =
jpayne@69 43 * medium/default, 9 = slow, 12 = slowest). Level 0 is also supported and means
jpayne@69 44 * "no compression", specifically "create a valid stream, but only emit
jpayne@69 45 * uncompressed blocks" (this will expand the data slightly).
jpayne@69 46 *
jpayne@69 47 * The return value is a pointer to the new compressor, or NULL if out of memory
jpayne@69 48 * or if the compression level is invalid (i.e. outside the range [0, 12]).
jpayne@69 49 *
jpayne@69 50 * Note: for compression, the sliding window size is defined at compilation time
jpayne@69 51 * to 32768, the largest size permissible in the DEFLATE format. It cannot be
jpayne@69 52 * changed at runtime.
jpayne@69 53 *
jpayne@69 54 * A single compressor is not safe to use by multiple threads concurrently.
jpayne@69 55 * However, different threads may use different compressors concurrently.
jpayne@69 56 */
jpayne@69 57 LIBDEFLATEAPI struct libdeflate_compressor *
jpayne@69 58 libdeflate_alloc_compressor(int compression_level);
jpayne@69 59
jpayne@69 60 /*
jpayne@69 61 * libdeflate_deflate_compress() performs raw DEFLATE compression on a buffer of
jpayne@69 62 * data. It attempts to compress 'in_nbytes' bytes of data located at 'in' and
jpayne@69 63 * write the result to 'out', which has space for 'out_nbytes_avail' bytes. The
jpayne@69 64 * return value is the compressed size in bytes, or 0 if the data could not be
jpayne@69 65 * compressed to 'out_nbytes_avail' bytes or fewer (but see note below).
jpayne@69 66 *
jpayne@69 67 * If compression is successful, then the output data is guaranteed to be a
jpayne@69 68 * valid DEFLATE stream that decompresses to the input data. No other
jpayne@69 69 * guarantees are made about the output data. Notably, different versions of
jpayne@69 70 * libdeflate can produce different compressed data for the same uncompressed
jpayne@69 71 * data, even at the same compression level. Do ***NOT*** do things like
jpayne@69 72 * writing tests that compare compressed data to a golden output, as this can
jpayne@69 73 * break when libdeflate is updated. (This property isn't specific to
jpayne@69 74 * libdeflate; the same is true for zlib and other compression libraries too.)
jpayne@69 75 *
jpayne@69 76 * Note: due to a performance optimization, libdeflate_deflate_compress()
jpayne@69 77 * currently needs a small amount of slack space at the end of the output
jpayne@69 78 * buffer. As a result, it can't actually report compressed sizes very close to
jpayne@69 79 * 'out_nbytes_avail'. This doesn't matter in real-world use cases, and
jpayne@69 80 * libdeflate_deflate_compress_bound() already includes the slack space.
jpayne@69 81 * However, it does mean that testing code that redundantly compresses data
jpayne@69 82 * using an exact-sized output buffer won't work as might be expected:
jpayne@69 83 *
jpayne@69 84 * out_nbytes = libdeflate_deflate_compress(c, in, in_nbytes, out,
jpayne@69 85 * libdeflate_deflate_compress_bound(in_nbytes));
jpayne@69 86 * // The following assertion will fail.
jpayne@69 87 * assert(libdeflate_deflate_compress(c, in, in_nbytes, out, out_nbytes) != 0);
jpayne@69 88 *
jpayne@69 89 * To avoid this, either don't write tests like the above, or make sure to
jpayne@69 90 * include at least 9 bytes of slack space in 'out_nbytes_avail'.
jpayne@69 91 */
jpayne@69 92 LIBDEFLATEAPI size_t
jpayne@69 93 libdeflate_deflate_compress(struct libdeflate_compressor *compressor,
jpayne@69 94 const void *in, size_t in_nbytes,
jpayne@69 95 void *out, size_t out_nbytes_avail);
jpayne@69 96
jpayne@69 97 /*
jpayne@69 98 * libdeflate_deflate_compress_bound() returns a worst-case upper bound on the
jpayne@69 99 * number of bytes of compressed data that may be produced by compressing any
jpayne@69 100 * buffer of length less than or equal to 'in_nbytes' using
jpayne@69 101 * libdeflate_deflate_compress() with the specified compressor. This bound will
jpayne@69 102 * necessarily be a number greater than or equal to 'in_nbytes'. It may be an
jpayne@69 103 * overestimate of the true upper bound. The return value is guaranteed to be
jpayne@69 104 * the same for all invocations with the same compressor and same 'in_nbytes'.
jpayne@69 105 *
jpayne@69 106 * As a special case, 'compressor' may be NULL. This causes the bound to be
jpayne@69 107 * taken across *any* libdeflate_compressor that could ever be allocated with
jpayne@69 108 * this build of the library, with any options.
jpayne@69 109 *
jpayne@69 110 * Note that this function is not necessary in many applications. With
jpayne@69 111 * block-based compression, it is usually preferable to separately store the
jpayne@69 112 * uncompressed size of each block and to store any blocks that did not compress
jpayne@69 113 * to less than their original size uncompressed. In that scenario, there is no
jpayne@69 114 * need to know the worst-case compressed size, since the maximum number of
jpayne@69 115 * bytes of compressed data that may be used would always be one less than the
jpayne@69 116 * input length. You can just pass a buffer of that size to
jpayne@69 117 * libdeflate_deflate_compress() and store the data uncompressed if
jpayne@69 118 * libdeflate_deflate_compress() returns 0, indicating that the compressed data
jpayne@69 119 * did not fit into the provided output buffer.
jpayne@69 120 */
jpayne@69 121 LIBDEFLATEAPI size_t
jpayne@69 122 libdeflate_deflate_compress_bound(struct libdeflate_compressor *compressor,
jpayne@69 123 size_t in_nbytes);
jpayne@69 124
jpayne@69 125 /*
jpayne@69 126 * Like libdeflate_deflate_compress(), but uses the zlib wrapper format instead
jpayne@69 127 * of raw DEFLATE.
jpayne@69 128 */
jpayne@69 129 LIBDEFLATEAPI size_t
jpayne@69 130 libdeflate_zlib_compress(struct libdeflate_compressor *compressor,
jpayne@69 131 const void *in, size_t in_nbytes,
jpayne@69 132 void *out, size_t out_nbytes_avail);
jpayne@69 133
jpayne@69 134 /*
jpayne@69 135 * Like libdeflate_deflate_compress_bound(), but assumes the data will be
jpayne@69 136 * compressed with libdeflate_zlib_compress() rather than with
jpayne@69 137 * libdeflate_deflate_compress().
jpayne@69 138 */
jpayne@69 139 LIBDEFLATEAPI size_t
jpayne@69 140 libdeflate_zlib_compress_bound(struct libdeflate_compressor *compressor,
jpayne@69 141 size_t in_nbytes);
jpayne@69 142
jpayne@69 143 /*
jpayne@69 144 * Like libdeflate_deflate_compress(), but uses the gzip wrapper format instead
jpayne@69 145 * of raw DEFLATE.
jpayne@69 146 */
jpayne@69 147 LIBDEFLATEAPI size_t
jpayne@69 148 libdeflate_gzip_compress(struct libdeflate_compressor *compressor,
jpayne@69 149 const void *in, size_t in_nbytes,
jpayne@69 150 void *out, size_t out_nbytes_avail);
jpayne@69 151
jpayne@69 152 /*
jpayne@69 153 * Like libdeflate_deflate_compress_bound(), but assumes the data will be
jpayne@69 154 * compressed with libdeflate_gzip_compress() rather than with
jpayne@69 155 * libdeflate_deflate_compress().
jpayne@69 156 */
jpayne@69 157 LIBDEFLATEAPI size_t
jpayne@69 158 libdeflate_gzip_compress_bound(struct libdeflate_compressor *compressor,
jpayne@69 159 size_t in_nbytes);
jpayne@69 160
jpayne@69 161 /*
jpayne@69 162 * libdeflate_free_compressor() frees a compressor that was allocated with
jpayne@69 163 * libdeflate_alloc_compressor(). If a NULL pointer is passed in, no action is
jpayne@69 164 * taken.
jpayne@69 165 */
jpayne@69 166 LIBDEFLATEAPI void
jpayne@69 167 libdeflate_free_compressor(struct libdeflate_compressor *compressor);
jpayne@69 168
jpayne@69 169 /* ========================================================================== */
jpayne@69 170 /* Decompression */
jpayne@69 171 /* ========================================================================== */
jpayne@69 172
jpayne@69 173 struct libdeflate_decompressor;
jpayne@69 174
jpayne@69 175 /*
jpayne@69 176 * libdeflate_alloc_decompressor() allocates a new decompressor that can be used
jpayne@69 177 * for DEFLATE, zlib, and gzip decompression. The return value is a pointer to
jpayne@69 178 * the new decompressor, or NULL if out of memory.
jpayne@69 179 *
jpayne@69 180 * This function takes no parameters, and the returned decompressor is valid for
jpayne@69 181 * decompressing data that was compressed at any compression level and with any
jpayne@69 182 * sliding window size.
jpayne@69 183 *
jpayne@69 184 * A single decompressor is not safe to use by multiple threads concurrently.
jpayne@69 185 * However, different threads may use different decompressors concurrently.
jpayne@69 186 */
jpayne@69 187 LIBDEFLATEAPI struct libdeflate_decompressor *
jpayne@69 188 libdeflate_alloc_decompressor(void);
jpayne@69 189
jpayne@69 190 /*
jpayne@69 191 * Result of a call to libdeflate_deflate_decompress(),
jpayne@69 192 * libdeflate_zlib_decompress(), or libdeflate_gzip_decompress().
jpayne@69 193 */
jpayne@69 194 enum libdeflate_result {
jpayne@69 195 /* Decompression was successful. */
jpayne@69 196 LIBDEFLATE_SUCCESS = 0,
jpayne@69 197
jpayne@69 198 /* Decompression failed because the compressed data was invalid,
jpayne@69 199 * corrupt, or otherwise unsupported. */
jpayne@69 200 LIBDEFLATE_BAD_DATA = 1,
jpayne@69 201
jpayne@69 202 /* A NULL 'actual_out_nbytes_ret' was provided, but the data would have
jpayne@69 203 * decompressed to fewer than 'out_nbytes_avail' bytes. */
jpayne@69 204 LIBDEFLATE_SHORT_OUTPUT = 2,
jpayne@69 205
jpayne@69 206 /* The data would have decompressed to more than 'out_nbytes_avail'
jpayne@69 207 * bytes. */
jpayne@69 208 LIBDEFLATE_INSUFFICIENT_SPACE = 3,
jpayne@69 209 };
jpayne@69 210
jpayne@69 211 /*
jpayne@69 212 * libdeflate_deflate_decompress() decompresses a DEFLATE stream from the buffer
jpayne@69 213 * 'in' with compressed size up to 'in_nbytes' bytes. The uncompressed data is
jpayne@69 214 * written to 'out', a buffer with size 'out_nbytes_avail' bytes. If
jpayne@69 215 * decompression succeeds, then 0 (LIBDEFLATE_SUCCESS) is returned. Otherwise,
jpayne@69 216 * a nonzero result code such as LIBDEFLATE_BAD_DATA is returned, and the
jpayne@69 217 * contents of the output buffer are undefined.
jpayne@69 218 *
jpayne@69 219 * Decompression stops at the end of the DEFLATE stream (as indicated by the
jpayne@69 220 * BFINAL flag), even if it is actually shorter than 'in_nbytes' bytes.
jpayne@69 221 *
jpayne@69 222 * libdeflate_deflate_decompress() can be used in cases where the actual
jpayne@69 223 * uncompressed size is known (recommended) or unknown (not recommended):
jpayne@69 224 *
jpayne@69 225 * - If the actual uncompressed size is known, then pass the actual
jpayne@69 226 * uncompressed size as 'out_nbytes_avail' and pass NULL for
jpayne@69 227 * 'actual_out_nbytes_ret'. This makes libdeflate_deflate_decompress() fail
jpayne@69 228 * with LIBDEFLATE_SHORT_OUTPUT if the data decompressed to fewer than the
jpayne@69 229 * specified number of bytes.
jpayne@69 230 *
jpayne@69 231 * - If the actual uncompressed size is unknown, then provide a non-NULL
jpayne@69 232 * 'actual_out_nbytes_ret' and provide a buffer with some size
jpayne@69 233 * 'out_nbytes_avail' that you think is large enough to hold all the
jpayne@69 234 * uncompressed data. In this case, if the data decompresses to less than
jpayne@69 235 * or equal to 'out_nbytes_avail' bytes, then
jpayne@69 236 * libdeflate_deflate_decompress() will write the actual uncompressed size
jpayne@69 237 * to *actual_out_nbytes_ret and return 0 (LIBDEFLATE_SUCCESS). Otherwise,
jpayne@69 238 * it will return LIBDEFLATE_INSUFFICIENT_SPACE if the provided buffer was
jpayne@69 239 * not large enough but no other problems were encountered, or another
jpayne@69 240 * nonzero result code if decompression failed for another reason.
jpayne@69 241 */
jpayne@69 242 LIBDEFLATEAPI enum libdeflate_result
jpayne@69 243 libdeflate_deflate_decompress(struct libdeflate_decompressor *decompressor,
jpayne@69 244 const void *in, size_t in_nbytes,
jpayne@69 245 void *out, size_t out_nbytes_avail,
jpayne@69 246 size_t *actual_out_nbytes_ret);
jpayne@69 247
jpayne@69 248 /*
jpayne@69 249 * Like libdeflate_deflate_decompress(), but adds the 'actual_in_nbytes_ret'
jpayne@69 250 * argument. If decompression succeeds and 'actual_in_nbytes_ret' is not NULL,
jpayne@69 251 * then the actual compressed size of the DEFLATE stream (aligned to the next
jpayne@69 252 * byte boundary) is written to *actual_in_nbytes_ret.
jpayne@69 253 */
jpayne@69 254 LIBDEFLATEAPI enum libdeflate_result
jpayne@69 255 libdeflate_deflate_decompress_ex(struct libdeflate_decompressor *decompressor,
jpayne@69 256 const void *in, size_t in_nbytes,
jpayne@69 257 void *out, size_t out_nbytes_avail,
jpayne@69 258 size_t *actual_in_nbytes_ret,
jpayne@69 259 size_t *actual_out_nbytes_ret);
jpayne@69 260
jpayne@69 261 /*
jpayne@69 262 * Like libdeflate_deflate_decompress(), but assumes the zlib wrapper format
jpayne@69 263 * instead of raw DEFLATE.
jpayne@69 264 *
jpayne@69 265 * Decompression will stop at the end of the zlib stream, even if it is shorter
jpayne@69 266 * than 'in_nbytes'. If you need to know exactly where the zlib stream ended,
jpayne@69 267 * use libdeflate_zlib_decompress_ex().
jpayne@69 268 */
jpayne@69 269 LIBDEFLATEAPI enum libdeflate_result
jpayne@69 270 libdeflate_zlib_decompress(struct libdeflate_decompressor *decompressor,
jpayne@69 271 const void *in, size_t in_nbytes,
jpayne@69 272 void *out, size_t out_nbytes_avail,
jpayne@69 273 size_t *actual_out_nbytes_ret);
jpayne@69 274
jpayne@69 275 /*
jpayne@69 276 * Like libdeflate_zlib_decompress(), but adds the 'actual_in_nbytes_ret'
jpayne@69 277 * argument. If 'actual_in_nbytes_ret' is not NULL and the decompression
jpayne@69 278 * succeeds (indicating that the first zlib-compressed stream in the input
jpayne@69 279 * buffer was decompressed), then the actual number of input bytes consumed is
jpayne@69 280 * written to *actual_in_nbytes_ret.
jpayne@69 281 */
jpayne@69 282 LIBDEFLATEAPI enum libdeflate_result
jpayne@69 283 libdeflate_zlib_decompress_ex(struct libdeflate_decompressor *decompressor,
jpayne@69 284 const void *in, size_t in_nbytes,
jpayne@69 285 void *out, size_t out_nbytes_avail,
jpayne@69 286 size_t *actual_in_nbytes_ret,
jpayne@69 287 size_t *actual_out_nbytes_ret);
jpayne@69 288
jpayne@69 289 /*
jpayne@69 290 * Like libdeflate_deflate_decompress(), but assumes the gzip wrapper format
jpayne@69 291 * instead of raw DEFLATE.
jpayne@69 292 *
jpayne@69 293 * If multiple gzip-compressed members are concatenated, then only the first
jpayne@69 294 * will be decompressed. Use libdeflate_gzip_decompress_ex() if you need
jpayne@69 295 * multi-member support.
jpayne@69 296 */
jpayne@69 297 LIBDEFLATEAPI enum libdeflate_result
jpayne@69 298 libdeflate_gzip_decompress(struct libdeflate_decompressor *decompressor,
jpayne@69 299 const void *in, size_t in_nbytes,
jpayne@69 300 void *out, size_t out_nbytes_avail,
jpayne@69 301 size_t *actual_out_nbytes_ret);
jpayne@69 302
jpayne@69 303 /*
jpayne@69 304 * Like libdeflate_gzip_decompress(), but adds the 'actual_in_nbytes_ret'
jpayne@69 305 * argument. If 'actual_in_nbytes_ret' is not NULL and the decompression
jpayne@69 306 * succeeds (indicating that the first gzip-compressed member in the input
jpayne@69 307 * buffer was decompressed), then the actual number of input bytes consumed is
jpayne@69 308 * written to *actual_in_nbytes_ret.
jpayne@69 309 */
jpayne@69 310 LIBDEFLATEAPI enum libdeflate_result
jpayne@69 311 libdeflate_gzip_decompress_ex(struct libdeflate_decompressor *decompressor,
jpayne@69 312 const void *in, size_t in_nbytes,
jpayne@69 313 void *out, size_t out_nbytes_avail,
jpayne@69 314 size_t *actual_in_nbytes_ret,
jpayne@69 315 size_t *actual_out_nbytes_ret);
jpayne@69 316
jpayne@69 317 /*
jpayne@69 318 * libdeflate_free_decompressor() frees a decompressor that was allocated with
jpayne@69 319 * libdeflate_alloc_decompressor(). If a NULL pointer is passed in, no action
jpayne@69 320 * is taken.
jpayne@69 321 */
jpayne@69 322 LIBDEFLATEAPI void
jpayne@69 323 libdeflate_free_decompressor(struct libdeflate_decompressor *decompressor);
jpayne@69 324
jpayne@69 325 /* ========================================================================== */
jpayne@69 326 /* Checksums */
jpayne@69 327 /* ========================================================================== */
jpayne@69 328
jpayne@69 329 /*
jpayne@69 330 * libdeflate_adler32() updates a running Adler-32 checksum with 'len' bytes of
jpayne@69 331 * data and returns the updated checksum. When starting a new checksum, the
jpayne@69 332 * required initial value for 'adler' is 1. This value is also returned when
jpayne@69 333 * 'buffer' is specified as NULL.
jpayne@69 334 */
jpayne@69 335 LIBDEFLATEAPI uint32_t
jpayne@69 336 libdeflate_adler32(uint32_t adler, const void *buffer, size_t len);
jpayne@69 337
jpayne@69 338
jpayne@69 339 /*
jpayne@69 340 * libdeflate_crc32() updates a running CRC-32 checksum with 'len' bytes of data
jpayne@69 341 * and returns the updated checksum. When starting a new checksum, the required
jpayne@69 342 * initial value for 'crc' is 0. This value is also returned when 'buffer' is
jpayne@69 343 * specified as NULL.
jpayne@69 344 */
jpayne@69 345 LIBDEFLATEAPI uint32_t
jpayne@69 346 libdeflate_crc32(uint32_t crc, const void *buffer, size_t len);
jpayne@69 347
jpayne@69 348 /* ========================================================================== */
jpayne@69 349 /* Custom memory allocator */
jpayne@69 350 /* ========================================================================== */
jpayne@69 351
jpayne@69 352 /*
jpayne@69 353 * Install a custom memory allocator which libdeflate will use for all memory
jpayne@69 354 * allocations. 'malloc_func' is a function that must behave like malloc(), and
jpayne@69 355 * 'free_func' is a function that must behave like free().
jpayne@69 356 *
jpayne@69 357 * There must not be any libdeflate_compressor or libdeflate_decompressor
jpayne@69 358 * structures in existence when calling this function.
jpayne@69 359 */
jpayne@69 360 LIBDEFLATEAPI void
jpayne@69 361 libdeflate_set_memory_allocator(void *(*malloc_func)(size_t),
jpayne@69 362 void (*free_func)(void *));
jpayne@69 363
jpayne@69 364 #ifdef __cplusplus
jpayne@69 365 }
jpayne@69 366 #endif
jpayne@69 367
jpayne@69 368 #endif /* LIBDEFLATE_H */