1/*
2 LZ4 HC - High Compression Mode of LZ4
3 Header File
4 Copyright (C) 2011-2017, Yann Collet.
5 BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
6
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are
9 met:
10
11 * Redistributions of source code must retain the above copyright
12 notice, this list of conditions and the following disclaimer.
13 * Redistributions in binary form must reproduce the above
14 copyright notice, this list of conditions and the following disclaimer
15 in the documentation and/or other materials provided with the
16 distribution.
17
18 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30 You can contact the author at :
31 - LZ4 source repository : https://github.com/lz4/lz4
32 - LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c
33*/
34#ifndef LZ4_HC_H_19834876238432
35#define LZ4_HC_H_19834876238432
36
37#if defined (__cplusplus)
38extern "C" {
39#endif
40
41/* --- Dependency --- */
42/* note : lz4hc requires lz4.h/lz4.c for compilation */
43#include "lz4.h" /* stddef, LZ4LIB_API, LZ4_DEPRECATED */
44
45
46/* --- Useful constants --- */
47#define LZ4HC_CLEVEL_MIN 3
48#define LZ4HC_CLEVEL_DEFAULT 9
49#define LZ4HC_CLEVEL_OPT_MIN 10
50#define LZ4HC_CLEVEL_MAX 12
51
52
53/*-************************************
54 * Block Compression
55 **************************************/
56/*! LZ4_compress_HC() :
57 * Compress data from `src` into `dst`, using the powerful but slower "HC" algorithm.
58 * `dst` must be already allocated.
59 * Compression is guaranteed to succeed if `dstCapacity >= LZ4_compressBound(srcSize)` (see "lz4.h")
60 * Max supported `srcSize` value is LZ4_MAX_INPUT_SIZE (see "lz4.h")
61 * `compressionLevel` : any value between 1 and LZ4HC_CLEVEL_MAX will work.
62 * Values > LZ4HC_CLEVEL_MAX behave the same as LZ4HC_CLEVEL_MAX.
63 * @return : the number of bytes written into 'dst'
64 * or 0 if compression fails.
65 */
66LZ4LIB_API int LZ4_compress_HC (const char* src, char* dst, int srcSize, int dstCapacity, int compressionLevel);
67
68
69/* Note :
70 * Decompression functions are provided within "lz4.h" (BSD license)
71 */
72
73
74/*! LZ4_compress_HC_extStateHC() :
75 * Same as LZ4_compress_HC(), but using an externally allocated memory segment for `state`.
76 * `state` size is provided by LZ4_sizeofStateHC().
77 * Memory segment must be aligned on 8-bytes boundaries (which a normal malloc() should do properly).
78 */
79LZ4LIB_API int LZ4_sizeofStateHC(void);
80LZ4LIB_API int LZ4_compress_HC_extStateHC(void* stateHC, const char* src, char* dst, int srcSize, int maxDstSize, int compressionLevel);
81
82
83/*! LZ4_compress_HC_destSize() : v1.9.0+
84 * Will compress as much data as possible from `src`
85 * to fit into `targetDstSize` budget.
86 * Result is provided in 2 parts :
87 * @return : the number of bytes written into 'dst' (necessarily <= targetDstSize)
88 * or 0 if compression fails.
89 * `srcSizePtr` : on success, *srcSizePtr is updated to indicate how much bytes were read from `src`
90 */
91LZ4LIB_API int LZ4_compress_HC_destSize(void* stateHC,
92 const char* src, char* dst,
93 int* srcSizePtr, int targetDstSize,
94 int compressionLevel);
95
96
97/*-************************************
98 * Streaming Compression
99 * Bufferless synchronous API
100 **************************************/
101 typedef union LZ4_streamHC_u LZ4_streamHC_t; /* incomplete type (defined later) */
102
103/*! LZ4_createStreamHC() and LZ4_freeStreamHC() :
104 * These functions create and release memory for LZ4 HC streaming state.
105 * Newly created states are automatically initialized.
106 * A same state can be used multiple times consecutively,
107 * starting with LZ4_resetStreamHC_fast() to start a new stream of blocks.
108 */
109LZ4LIB_API LZ4_streamHC_t* LZ4_createStreamHC(void);
110LZ4LIB_API int LZ4_freeStreamHC (LZ4_streamHC_t* streamHCPtr);
111
112/*
113 These functions compress data in successive blocks of any size,
114 using previous blocks as dictionary, to improve compression ratio.
115 One key assumption is that previous blocks (up to 64 KB) remain read-accessible while compressing next blocks.
116 There is an exception for ring buffers, which can be smaller than 64 KB.
117 Ring-buffer scenario is automatically detected and handled within LZ4_compress_HC_continue().
118
119 Before starting compression, state must be allocated and properly initialized.
120 LZ4_createStreamHC() does both, though compression level is set to LZ4HC_CLEVEL_DEFAULT.
121
122 Selecting the compression level can be done with LZ4_resetStreamHC_fast() (starts a new stream)
123 or LZ4_setCompressionLevel() (anytime, between blocks in the same stream) (experimental).
124 LZ4_resetStreamHC_fast() only works on states which have been properly initialized at least once,
125 which is automatically the case when state is created using LZ4_createStreamHC().
126
127 After reset, a first "fictional block" can be designated as initial dictionary,
128 using LZ4_loadDictHC() (Optional).
129
130 Invoke LZ4_compress_HC_continue() to compress each successive block.
131 The number of blocks is unlimited.
132 Previous input blocks, including initial dictionary when present,
133 must remain accessible and unmodified during compression.
134
135 It's allowed to update compression level anytime between blocks,
136 using LZ4_setCompressionLevel() (experimental).
137
138 'dst' buffer should be sized to handle worst case scenarios
139 (see LZ4_compressBound(), it ensures compression success).
140 In case of failure, the API does not guarantee recovery,
141 so the state _must_ be reset.
142 To ensure compression success
143 whenever `dst` buffer size cannot be made >= LZ4_compressBound(),
144 consider using LZ4_compress_HC_continue_destSize().
145
146 Whenever previous input blocks can't be preserved unmodified in-place during compression of next blocks,
147 it's possible to copy the last blocks into a more stable memory space, using LZ4_saveDictHC().
148 Return value of LZ4_saveDictHC() is the size of dictionary effectively saved into 'safeBuffer' (<= 64 KB)
149
150 After completing a streaming compression,
151 it's possible to start a new stream of blocks, using the same LZ4_streamHC_t state,
152 just by resetting it, using LZ4_resetStreamHC_fast().
153*/
154
155LZ4LIB_API void LZ4_resetStreamHC_fast(LZ4_streamHC_t* streamHCPtr, int compressionLevel); /* v1.9.0+ */
156LZ4LIB_API int LZ4_loadDictHC (LZ4_streamHC_t* streamHCPtr, const char* dictionary, int dictSize);
157
158LZ4LIB_API int LZ4_compress_HC_continue (LZ4_streamHC_t* streamHCPtr,
159 const char* src, char* dst,
160 int srcSize, int maxDstSize);
161
162/*! LZ4_compress_HC_continue_destSize() : v1.9.0+
163 * Similar to LZ4_compress_HC_continue(),
164 * but will read as much data as possible from `src`
165 * to fit into `targetDstSize` budget.
166 * Result is provided into 2 parts :
167 * @return : the number of bytes written into 'dst' (necessarily <= targetDstSize)
168 * or 0 if compression fails.
169 * `srcSizePtr` : on success, *srcSizePtr will be updated to indicate how much bytes were read from `src`.
170 * Note that this function may not consume the entire input.
171 */
172LZ4LIB_API int LZ4_compress_HC_continue_destSize(LZ4_streamHC_t* LZ4_streamHCPtr,
173 const char* src, char* dst,
174 int* srcSizePtr, int targetDstSize);
175
176LZ4LIB_API int LZ4_saveDictHC (LZ4_streamHC_t* streamHCPtr, char* safeBuffer, int maxDictSize);
177
178
179
180/*^**********************************************
181 * !!!!!! STATIC LINKING ONLY !!!!!!
182 ***********************************************/
183
184/*-******************************************************************
185 * PRIVATE DEFINITIONS :
186 * Do not use these definitions directly.
187 * They are merely exposed to allow static allocation of `LZ4_streamHC_t`.
188 * Declare an `LZ4_streamHC_t` directly, rather than any type below.
189 * Even then, only do so in the context of static linking, as definitions may change between versions.
190 ********************************************************************/
191
192#define LZ4HC_DICTIONARY_LOGSIZE 16
193#define LZ4HC_MAXD (1<<LZ4HC_DICTIONARY_LOGSIZE)
194#define LZ4HC_MAXD_MASK (LZ4HC_MAXD - 1)
195
196#define LZ4HC_HASH_LOG 15
197#define LZ4HC_HASHTABLESIZE (1 << LZ4HC_HASH_LOG)
198#define LZ4HC_HASH_MASK (LZ4HC_HASHTABLESIZE - 1)
199
200
201#if defined(__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
202#include <stdint.h>
203
204typedef struct LZ4HC_CCtx_internal LZ4HC_CCtx_internal;
205struct LZ4HC_CCtx_internal
206{
207 uint32_t hashTable[LZ4HC_HASHTABLESIZE];
208 uint16_t chainTable[LZ4HC_MAXD];
209 const uint8_t* end; /* next block here to continue on current prefix */
210 const uint8_t* base; /* All index relative to this position */
211 const uint8_t* dictBase; /* alternate base for extDict */
212 uint32_t dictLimit; /* below that point, need extDict */
213 uint32_t lowLimit; /* below that point, no more dict */
214 uint32_t nextToUpdate; /* index from which to continue dictionary update */
215 short compressionLevel;
216 int8_t favorDecSpeed; /* favor decompression speed if this flag set,
217 otherwise, favor compression ratio */
218 int8_t dirty; /* stream has to be fully reset if this flag is set */
219 const LZ4HC_CCtx_internal* dictCtx;
220};
221
222#else
223
224typedef struct LZ4HC_CCtx_internal LZ4HC_CCtx_internal;
225struct LZ4HC_CCtx_internal
226{
227 unsigned int hashTable[LZ4HC_HASHTABLESIZE];
228 unsigned short chainTable[LZ4HC_MAXD];
229 const unsigned char* end; /* next block here to continue on current prefix */
230 const unsigned char* base; /* All index relative to this position */
231 const unsigned char* dictBase; /* alternate base for extDict */
232 unsigned int dictLimit; /* below that point, need extDict */
233 unsigned int lowLimit; /* below that point, no more dict */
234 unsigned int nextToUpdate; /* index from which to continue dictionary update */
235 short compressionLevel;
236 char favorDecSpeed; /* favor decompression speed if this flag set,
237 otherwise, favor compression ratio */
238 char dirty; /* stream has to be fully reset if this flag is set */
239 const LZ4HC_CCtx_internal* dictCtx;
240};
241
242#endif
243
244
245/* Do not use these definitions directly !
246 * Declare or allocate an LZ4_streamHC_t instead.
247 */
248#define LZ4_STREAMHCSIZE (4*LZ4HC_HASHTABLESIZE + 2*LZ4HC_MAXD + 56 + ((sizeof(void*)==16) ? 56 : 0) /* AS400*/ ) /* 262200 or 262256*/
249#define LZ4_STREAMHCSIZE_SIZET (LZ4_STREAMHCSIZE / sizeof(size_t))
250union LZ4_streamHC_u {
251 size_t table[LZ4_STREAMHCSIZE_SIZET];
252 LZ4HC_CCtx_internal internal_donotuse;
253}; /* previously typedef'd to LZ4_streamHC_t */
254
255/* LZ4_streamHC_t :
256 * This structure allows static allocation of LZ4 HC streaming state.
257 * This can be used to allocate statically, on state, or as part of a larger structure.
258 *
259 * Such state **must** be initialized using LZ4_initStreamHC() before first use.
260 *
261 * Note that invoking LZ4_initStreamHC() is not required when
262 * the state was created using LZ4_createStreamHC() (which is recommended).
263 * Using the normal builder, a newly created state is automatically initialized.
264 *
265 * Static allocation shall only be used in combination with static linking.
266 */
267
268/* LZ4_initStreamHC() : v1.9.0+
269 * Required before first use of a statically allocated LZ4_streamHC_t.
270 * Before v1.9.0 : use LZ4_resetStreamHC() instead
271 */
272LZ4LIB_API LZ4_streamHC_t* LZ4_initStreamHC (void* buffer, size_t size);
273
274
275/*-************************************
276* Deprecated Functions
277**************************************/
278/* see lz4.h LZ4_DISABLE_DEPRECATE_WARNINGS to turn off deprecation warnings */
279
280/* deprecated compression functions */
281LZ4_DEPRECATED("use LZ4_compress_HC() instead") LZ4LIB_API int LZ4_compressHC (const char* source, char* dest, int inputSize);
282LZ4_DEPRECATED("use LZ4_compress_HC() instead") LZ4LIB_API int LZ4_compressHC_limitedOutput (const char* source, char* dest, int inputSize, int maxOutputSize);
283LZ4_DEPRECATED("use LZ4_compress_HC() instead") LZ4LIB_API int LZ4_compressHC2 (const char* source, char* dest, int inputSize, int compressionLevel);
284LZ4_DEPRECATED("use LZ4_compress_HC() instead") LZ4LIB_API int LZ4_compressHC2_limitedOutput(const char* source, char* dest, int inputSize, int maxOutputSize, int compressionLevel);
285LZ4_DEPRECATED("use LZ4_compress_HC_extStateHC() instead") LZ4LIB_API int LZ4_compressHC_withStateHC (void* state, const char* source, char* dest, int inputSize);
286LZ4_DEPRECATED("use LZ4_compress_HC_extStateHC() instead") LZ4LIB_API int LZ4_compressHC_limitedOutput_withStateHC (void* state, const char* source, char* dest, int inputSize, int maxOutputSize);
287LZ4_DEPRECATED("use LZ4_compress_HC_extStateHC() instead") LZ4LIB_API int LZ4_compressHC2_withStateHC (void* state, const char* source, char* dest, int inputSize, int compressionLevel);
288LZ4_DEPRECATED("use LZ4_compress_HC_extStateHC() instead") LZ4LIB_API int LZ4_compressHC2_limitedOutput_withStateHC(void* state, const char* source, char* dest, int inputSize, int maxOutputSize, int compressionLevel);
289LZ4_DEPRECATED("use LZ4_compress_HC_continue() instead") LZ4LIB_API int LZ4_compressHC_continue (LZ4_streamHC_t* LZ4_streamHCPtr, const char* source, char* dest, int inputSize);
290LZ4_DEPRECATED("use LZ4_compress_HC_continue() instead") LZ4LIB_API int LZ4_compressHC_limitedOutput_continue (LZ4_streamHC_t* LZ4_streamHCPtr, const char* source, char* dest, int inputSize, int maxOutputSize);
291
292/* Obsolete streaming functions; degraded functionality; do not use!
293 *
294 * In order to perform streaming compression, these functions depended on data
295 * that is no longer tracked in the state. They have been preserved as well as
296 * possible: using them will still produce a correct output. However, use of
297 * LZ4_slideInputBufferHC() will truncate the history of the stream, rather
298 * than preserve a window-sized chunk of history.
299 */
300LZ4_DEPRECATED("use LZ4_createStreamHC() instead") LZ4LIB_API void* LZ4_createHC (const char* inputBuffer);
301LZ4_DEPRECATED("use LZ4_saveDictHC() instead") LZ4LIB_API char* LZ4_slideInputBufferHC (void* LZ4HC_Data);
302LZ4_DEPRECATED("use LZ4_freeStreamHC() instead") LZ4LIB_API int LZ4_freeHC (void* LZ4HC_Data);
303LZ4_DEPRECATED("use LZ4_compress_HC_continue() instead") LZ4LIB_API int LZ4_compressHC2_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize, int compressionLevel);
304LZ4_DEPRECATED("use LZ4_compress_HC_continue() instead") LZ4LIB_API int LZ4_compressHC2_limitedOutput_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize, int maxOutputSize, int compressionLevel);
305LZ4_DEPRECATED("use LZ4_createStreamHC() instead") LZ4LIB_API int LZ4_sizeofStreamStateHC(void);
306LZ4_DEPRECATED("use LZ4_initStreamHC() instead") LZ4LIB_API int LZ4_resetStreamStateHC(void* state, char* inputBuffer);
307
308
309/* LZ4_resetStreamHC() is now replaced by LZ4_initStreamHC().
310 * The intention is to emphasize the difference with LZ4_resetStreamHC_fast(),
311 * which is now the recommended function to start a new stream of blocks,
312 * but cannot be used to initialize a memory segment containing arbitrary garbage data.
313 *
314 * It is recommended to switch to LZ4_initStreamHC().
315 * LZ4_resetStreamHC() will generate deprecation warnings in a future version.
316 */
317LZ4LIB_API void LZ4_resetStreamHC (LZ4_streamHC_t* streamHCPtr, int compressionLevel);
318
319
320#if defined (__cplusplus)
321}
322#endif
323
324#endif /* LZ4_HC_H_19834876238432 */
325
326
327/*-**************************************************
328 * !!!!! STATIC LINKING ONLY !!!!!
329 * Following definitions are considered experimental.
330 * They should not be linked from DLL,
331 * as there is no guarantee of API stability yet.
332 * Prototypes will be promoted to "stable" status
333 * after successfull usage in real-life scenarios.
334 ***************************************************/
335#ifdef LZ4_HC_STATIC_LINKING_ONLY /* protection macro */
336#ifndef LZ4_HC_SLO_098092834
337#define LZ4_HC_SLO_098092834
338
339#define LZ4_STATIC_LINKING_ONLY /* LZ4LIB_STATIC_API */
340#include "lz4.h"
341
342#if defined (__cplusplus)
343extern "C" {
344#endif
345
346/*! LZ4_setCompressionLevel() : v1.8.0+ (experimental)
347 * It's possible to change compression level
348 * between successive invocations of LZ4_compress_HC_continue*()
349 * for dynamic adaptation.
350 */
351LZ4LIB_STATIC_API void LZ4_setCompressionLevel(
352 LZ4_streamHC_t* LZ4_streamHCPtr, int compressionLevel);
353
354/*! LZ4_favorDecompressionSpeed() : v1.8.2+ (experimental)
355 * Opt. Parser will favor decompression speed over compression ratio.
356 * Only applicable to levels >= LZ4HC_CLEVEL_OPT_MIN.
357 */
358LZ4LIB_STATIC_API void LZ4_favorDecompressionSpeed(
359 LZ4_streamHC_t* LZ4_streamHCPtr, int favor);
360
361/*! LZ4_resetStreamHC_fast() : v1.9.0+
362 * When an LZ4_streamHC_t is known to be in a internally coherent state,
363 * it can often be prepared for a new compression with almost no work, only
364 * sometimes falling back to the full, expensive reset that is always required
365 * when the stream is in an indeterminate state (i.e., the reset performed by
366 * LZ4_resetStreamHC()).
367 *
368 * LZ4_streamHCs are guaranteed to be in a valid state when:
369 * - returned from LZ4_createStreamHC()
370 * - reset by LZ4_resetStreamHC()
371 * - memset(stream, 0, sizeof(LZ4_streamHC_t))
372 * - the stream was in a valid state and was reset by LZ4_resetStreamHC_fast()
373 * - the stream was in a valid state and was then used in any compression call
374 * that returned success
375 * - the stream was in an indeterminate state and was used in a compression
376 * call that fully reset the state (LZ4_compress_HC_extStateHC()) and that
377 * returned success
378 *
379 * Note:
380 * A stream that was last used in a compression call that returned an error
381 * may be passed to this function. However, it will be fully reset, which will
382 * clear any existing history and settings from the context.
383 */
384LZ4LIB_STATIC_API void LZ4_resetStreamHC_fast(
385 LZ4_streamHC_t* LZ4_streamHCPtr, int compressionLevel);
386
387/*! LZ4_compress_HC_extStateHC_fastReset() :
388 * A variant of LZ4_compress_HC_extStateHC().
389 *
390 * Using this variant avoids an expensive initialization step. It is only safe
391 * to call if the state buffer is known to be correctly initialized already
392 * (see above comment on LZ4_resetStreamHC_fast() for a definition of
393 * "correctly initialized"). From a high level, the difference is that this
394 * function initializes the provided state with a call to
395 * LZ4_resetStreamHC_fast() while LZ4_compress_HC_extStateHC() starts with a
396 * call to LZ4_resetStreamHC().
397 */
398LZ4LIB_STATIC_API int LZ4_compress_HC_extStateHC_fastReset (
399 void* state,
400 const char* src, char* dst,
401 int srcSize, int dstCapacity,
402 int compressionLevel);
403
404/*! LZ4_attach_HC_dictionary() :
405 * This is an experimental API that allows for the efficient use of a
406 * static dictionary many times.
407 *
408 * Rather than re-loading the dictionary buffer into a working context before
409 * each compression, or copying a pre-loaded dictionary's LZ4_streamHC_t into a
410 * working LZ4_streamHC_t, this function introduces a no-copy setup mechanism,
411 * in which the working stream references the dictionary stream in-place.
412 *
413 * Several assumptions are made about the state of the dictionary stream.
414 * Currently, only streams which have been prepared by LZ4_loadDictHC() should
415 * be expected to work.
416 *
417 * Alternatively, the provided dictionary stream pointer may be NULL, in which
418 * case any existing dictionary stream is unset.
419 *
420 * A dictionary should only be attached to a stream without any history (i.e.,
421 * a stream that has just been reset).
422 *
423 * The dictionary will remain attached to the working stream only for the
424 * current stream session. Calls to LZ4_resetStreamHC(_fast) will remove the
425 * dictionary context association from the working stream. The dictionary
426 * stream (and source buffer) must remain in-place / accessible / unchanged
427 * through the lifetime of the stream session.
428 */
429LZ4LIB_STATIC_API void LZ4_attach_HC_dictionary(
430 LZ4_streamHC_t *working_stream,
431 const LZ4_streamHC_t *dictionary_stream);
432
433#if defined (__cplusplus)
434}
435#endif
436
437#endif /* LZ4_HC_SLO_098092834 */
438#endif /* LZ4_HC_STATIC_LINKING_ONLY */
439