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) 38 extern "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 more 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 */ 66 LZ4LIB_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 */ 79 LZ4LIB_API int LZ4_sizeofStateHC(void); 80 LZ4LIB_API int LZ4_compress_HC_extStateHC(void* state, const char* src, char* dst, int srcSize, int maxDstSize, int compressionLevel); 81 82 83 /*-************************************ 84 * Streaming Compression 85 * Bufferless synchronous API 86 **************************************/ 87 typedef union LZ4_streamHC_u LZ4_streamHC_t; /* incomplete type (defined later) */ 88 89 /*! LZ4_createStreamHC() and LZ4_freeStreamHC() : 90 * These functions create and release memory for LZ4 HC streaming state. 91 * Newly created states are automatically initialized. 92 * Existing states can be re-used several times, using LZ4_resetStreamHC(). 93 * These methods are API and ABI stable, they can be used in combination with a DLL. 94 */ 95 LZ4LIB_API LZ4_streamHC_t* LZ4_createStreamHC(void); 96 LZ4LIB_API int LZ4_freeStreamHC (LZ4_streamHC_t* streamHCPtr); 97 98 LZ4LIB_API void LZ4_resetStreamHC (LZ4_streamHC_t* streamHCPtr, int compressionLevel); 99 LZ4LIB_API int LZ4_loadDictHC (LZ4_streamHC_t* streamHCPtr, const char* dictionary, int dictSize); 100 101 LZ4LIB_API int LZ4_compress_HC_continue (LZ4_streamHC_t* streamHCPtr, const char* src, char* dst, int srcSize, int maxDstSize); 102 103 LZ4LIB_API int LZ4_saveDictHC (LZ4_streamHC_t* streamHCPtr, char* safeBuffer, int maxDictSize); 104 105 /* 106 These functions compress data in successive blocks of any size, using previous blocks as dictionary. 107 One key assumption is that previous blocks (up to 64 KB) remain read-accessible while compressing next blocks. 108 There is an exception for ring buffers, which can be smaller than 64 KB. 109 Ring buffers scenario is automatically detected and handled by LZ4_compress_HC_continue(). 110 111 Before starting compression, state must be properly initialized, using LZ4_resetStreamHC(). 112 A first "fictional block" can then be designated as initial dictionary, using LZ4_loadDictHC() (Optional). 113 114 Then, use LZ4_compress_HC_continue() to compress each successive block. 115 Previous memory blocks (including initial dictionary when present) must remain accessible and unmodified during compression. 116 'dst' buffer should be sized to handle worst case scenarios (see LZ4_compressBound()), to ensure operation success. 117 Because in case of failure, the API does not guarantee context recovery, and context will have to be reset. 118 If `dst` buffer budget cannot be >= LZ4_compressBound(), consider using LZ4_compress_HC_continue_destSize() instead. 119 120 If, for any reason, previous data block can't be preserved unmodified in memory for next compression block, 121 you can save it to a more stable memory space, using LZ4_saveDictHC(). 122 Return value of LZ4_saveDictHC() is the size of dictionary effectively saved into 'safeBuffer'. 123 */ 124 125 126 127 128 /*^********************************************** 129 * !!!!!! STATIC LINKING ONLY !!!!!! 130 ***********************************************/ 131 132 /*-****************************************************************** 133 * PRIVATE DEFINITIONS : 134 * Do not use these definitions directly. 135 * They are merely exposed to allow static allocation of `LZ4_streamHC_t`. 136 * Declare an `LZ4_streamHC_t` directly, rather than any type below. 137 * Even then, only do so in the context of static linking, as definitions may change between versions. 138 ********************************************************************/ 139 140 #define LZ4HC_DICTIONARY_LOGSIZE 16 141 #define LZ4HC_MAXD (1<<LZ4HC_DICTIONARY_LOGSIZE) 142 #define LZ4HC_MAXD_MASK (LZ4HC_MAXD - 1) 143 144 #define LZ4HC_HASH_LOG 15 145 #define LZ4HC_HASHTABLESIZE (1 << LZ4HC_HASH_LOG) 146 #define LZ4HC_HASH_MASK (LZ4HC_HASHTABLESIZE - 1) 147 148 149 #if defined(__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) 150 #include <stdint.h> 151 152 typedef struct LZ4HC_CCtx_internal LZ4HC_CCtx_internal; 153 struct LZ4HC_CCtx_internal 154 { 155 uint32_t hashTable[LZ4HC_HASHTABLESIZE]; 156 uint16_t chainTable[LZ4HC_MAXD]; 157 const uint8_t* end; /* next block here to continue on current prefix */ 158 const uint8_t* base; /* All index relative to this position */ 159 const uint8_t* dictBase; /* alternate base for extDict */ 160 uint32_t dictLimit; /* below that point, need extDict */ 161 uint32_t lowLimit; /* below that point, no more dict */ 162 uint32_t nextToUpdate; /* index from which to continue dictionary update */ 163 short compressionLevel; 164 int8_t favorDecSpeed; /* favor decompression speed if this flag set, 165 otherwise, favor compression ratio */ 166 int8_t dirty; /* stream has to be fully reset if this flag is set */ 167 const LZ4HC_CCtx_internal* dictCtx; 168 }; 169 170 #else 171 172 typedef struct LZ4HC_CCtx_internal LZ4HC_CCtx_internal; 173 struct LZ4HC_CCtx_internal 174 { 175 unsigned int hashTable[LZ4HC_HASHTABLESIZE]; 176 unsigned short chainTable[LZ4HC_MAXD]; 177 const unsigned char* end; /* next block here to continue on current prefix */ 178 const unsigned char* base; /* All index relative to this position */ 179 const unsigned char* dictBase; /* alternate base for extDict */ 180 unsigned int dictLimit; /* below that point, need extDict */ 181 unsigned int lowLimit; /* below that point, no more dict */ 182 unsigned int nextToUpdate; /* index from which to continue dictionary update */ 183 short compressionLevel; 184 char favorDecSpeed; /* favor decompression speed if this flag set, 185 otherwise, favor compression ratio */ 186 char dirty; /* stream has to be fully reset if this flag is set */ 187 const LZ4HC_CCtx_internal* dictCtx; 188 }; 189 190 #endif 191 192 193 /* do not use these definitions directly. 194 * allocate an LZ4_streamHC_t instead. */ 195 #define LZ4_STREAMHCSIZE (4*LZ4HC_HASHTABLESIZE + 2*LZ4HC_MAXD + 56 + ((sizeof(void*)==16) ? 56 : 0) /* AS400*/ ) /* 262200 or 262256*/ 196 #define LZ4_STREAMHCSIZE_SIZET (LZ4_STREAMHCSIZE / sizeof(size_t)) 197 union LZ4_streamHC_u { 198 size_t table[LZ4_STREAMHCSIZE_SIZET]; 199 LZ4HC_CCtx_internal internal_donotuse; 200 }; /* previously typedef'd to LZ4_streamHC_t */ 201 /* LZ4_streamHC_t : 202 * This structure allows static allocation of LZ4 HC streaming state. 203 * State must be initialized using LZ4_resetStreamHC() before first use. 204 * 205 * Static allocation shall only be used in combination with static linking. 206 * When invoking LZ4 from a DLL, use create/free functions instead, which are API and ABI stable. 207 */ 208 209 210 /*-************************************ 211 * Deprecated Functions 212 **************************************/ 213 /* see lz4.h LZ4_DISABLE_DEPRECATE_WARNINGS to turn off deprecation warnings */ 214 215 /* deprecated compression functions */ 216 LZ4_DEPRECATED("use LZ4_compress_HC() instead") LZ4LIB_API int LZ4_compressHC (const char* source, char* dest, int inputSize); 217 LZ4_DEPRECATED("use LZ4_compress_HC() instead") LZ4LIB_API int LZ4_compressHC_limitedOutput (const char* source, char* dest, int inputSize, int maxOutputSize); 218 LZ4_DEPRECATED("use LZ4_compress_HC() instead") LZ4LIB_API int LZ4_compressHC2 (const char* source, char* dest, int inputSize, int compressionLevel); 219 LZ4_DEPRECATED("use LZ4_compress_HC() instead") LZ4LIB_API int LZ4_compressHC2_limitedOutput (const char* source, char* dest, int inputSize, int maxOutputSize, int compressionLevel); 220 LZ4_DEPRECATED("use LZ4_compress_HC_extStateHC() instead") LZ4LIB_API int LZ4_compressHC_withStateHC (void* state, const char* source, char* dest, int inputSize); 221 LZ4_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); 222 LZ4_DEPRECATED("use LZ4_compress_HC_extStateHC() instead") LZ4LIB_API int LZ4_compressHC2_withStateHC (void* state, const char* source, char* dest, int inputSize, int compressionLevel); 223 LZ4_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); 224 LZ4_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); 225 LZ4_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); 226 227 /* Obsolete streaming functions; degraded functionality; do not use! 228 * 229 * In order to perform streaming compression, these functions depended on data 230 * that is no longer tracked in the state. They have been preserved as well as 231 * possible: using them will still produce a correct output. However, use of 232 * LZ4_slideInputBufferHC() will truncate the history of the stream, rather 233 * than preserve a window-sized chunk of history. 234 */ 235 LZ4_DEPRECATED("use LZ4_createStreamHC() instead") LZ4LIB_API void* LZ4_createHC (const char* inputBuffer); 236 LZ4_DEPRECATED("use LZ4_saveDictHC() instead") LZ4LIB_API char* LZ4_slideInputBufferHC (void* LZ4HC_Data); 237 LZ4_DEPRECATED("use LZ4_freeStreamHC() instead") LZ4LIB_API int LZ4_freeHC (void* LZ4HC_Data); 238 LZ4_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); 239 LZ4_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); 240 LZ4_DEPRECATED("use LZ4_createStreamHC() instead") LZ4LIB_API int LZ4_sizeofStreamStateHC(void); 241 LZ4_DEPRECATED("use LZ4_resetStreamHC() instead") LZ4LIB_API int LZ4_resetStreamStateHC(void* state, char* inputBuffer); 242 243 244 #if defined (__cplusplus) 245 } 246 #endif 247 248 #endif /* LZ4_HC_H_19834876238432 */ 249 250 251 /*-************************************************** 252 * !!!!! STATIC LINKING ONLY !!!!! 253 * Following definitions are considered experimental. 254 * They should not be linked from DLL, 255 * as there is no guarantee of API stability yet. 256 * Prototypes will be promoted to "stable" status 257 * after successfull usage in real-life scenarios. 258 ***************************************************/ 259 #ifdef LZ4_HC_STATIC_LINKING_ONLY /* protection macro */ 260 #ifndef LZ4_HC_SLO_098092834 261 #define LZ4_HC_SLO_098092834 262 263 #if defined (__cplusplus) 264 extern "C" { 265 #endif 266 267 /*! LZ4_compress_HC_destSize() : v1.8.0 (experimental) 268 * Will try to compress as much data from `src` as possible 269 * that can fit into `targetDstSize` budget. 270 * Result is provided in 2 parts : 271 * @return : the number of bytes written into 'dst' 272 * or 0 if compression fails. 273 * `srcSizePtr` : value will be updated to indicate how much bytes were read from `src` 274 */ 275 LZ4LIB_STATIC_API int LZ4_compress_HC_destSize( 276 void* LZ4HC_Data, 277 const char* src, char* dst, 278 int* srcSizePtr, int targetDstSize, 279 int compressionLevel); 280 281 /*! LZ4_compress_HC_continue_destSize() : v1.8.0 (experimental) 282 * Similar as LZ4_compress_HC_continue(), 283 * but will read a variable nb of bytes from `src` 284 * to fit into `targetDstSize` budget. 285 * Result is provided in 2 parts : 286 * @return : the number of bytes written into 'dst' 287 * or 0 if compression fails. 288 * `srcSizePtr` : value will be updated to indicate how much bytes were read from `src`. 289 */ 290 LZ4LIB_STATIC_API int LZ4_compress_HC_continue_destSize( 291 LZ4_streamHC_t* LZ4_streamHCPtr, 292 const char* src, char* dst, 293 int* srcSizePtr, int targetDstSize); 294 295 /*! LZ4_setCompressionLevel() : v1.8.0 (experimental) 296 * It's possible to change compression level between 2 invocations of LZ4_compress_HC_continue*() 297 */ 298 LZ4LIB_STATIC_API void LZ4_setCompressionLevel( 299 LZ4_streamHC_t* LZ4_streamHCPtr, int compressionLevel); 300 301 /*! LZ4_favorDecompressionSpeed() : v1.8.2 (experimental) 302 * Parser will select decisions favoring decompression over compression ratio. 303 * Only work at highest compression settings (level >= LZ4HC_CLEVEL_OPT_MIN) 304 */ 305 LZ4LIB_STATIC_API void LZ4_favorDecompressionSpeed( 306 LZ4_streamHC_t* LZ4_streamHCPtr, int favor); 307 308 /*! LZ4_resetStreamHC_fast() : 309 * When an LZ4_streamHC_t is known to be in a internally coherent state, 310 * it can often be prepared for a new compression with almost no work, only 311 * sometimes falling back to the full, expensive reset that is always required 312 * when the stream is in an indeterminate state (i.e., the reset performed by 313 * LZ4_resetStreamHC()). 314 * 315 * LZ4_streamHCs are guaranteed to be in a valid state when: 316 * - returned from LZ4_createStreamHC() 317 * - reset by LZ4_resetStreamHC() 318 * - memset(stream, 0, sizeof(LZ4_streamHC_t)) 319 * - the stream was in a valid state and was reset by LZ4_resetStreamHC_fast() 320 * - the stream was in a valid state and was then used in any compression call 321 * that returned success 322 * - the stream was in an indeterminate state and was used in a compression 323 * call that fully reset the state (LZ4_compress_HC_extStateHC()) and that 324 * returned success 325 * 326 * Note: 327 * A stream that was last used in a compression call that returned an error 328 * may be passed to this function. However, it will be fully reset, which will 329 * clear any existing history and settings from the context. 330 */ 331 LZ4LIB_STATIC_API void LZ4_resetStreamHC_fast( 332 LZ4_streamHC_t* LZ4_streamHCPtr, int compressionLevel); 333 334 /*! LZ4_compress_HC_extStateHC_fastReset() : 335 * A variant of LZ4_compress_HC_extStateHC(). 336 * 337 * Using this variant avoids an expensive initialization step. It is only safe 338 * to call if the state buffer is known to be correctly initialized already 339 * (see above comment on LZ4_resetStreamHC_fast() for a definition of 340 * "correctly initialized"). From a high level, the difference is that this 341 * function initializes the provided state with a call to 342 * LZ4_resetStreamHC_fast() while LZ4_compress_HC_extStateHC() starts with a 343 * call to LZ4_resetStreamHC(). 344 */ 345 LZ4LIB_STATIC_API int LZ4_compress_HC_extStateHC_fastReset ( 346 void* state, 347 const char* src, char* dst, 348 int srcSize, int dstCapacity, 349 int compressionLevel); 350 351 /*! LZ4_attach_HC_dictionary() : 352 * This is an experimental API that allows for the efficient use of a 353 * static dictionary many times. 354 * 355 * Rather than re-loading the dictionary buffer into a working context before 356 * each compression, or copying a pre-loaded dictionary's LZ4_streamHC_t into a 357 * working LZ4_streamHC_t, this function introduces a no-copy setup mechanism, 358 * in which the working stream references the dictionary stream in-place. 359 * 360 * Several assumptions are made about the state of the dictionary stream. 361 * Currently, only streams which have been prepared by LZ4_loadDictHC() should 362 * be expected to work. 363 * 364 * Alternatively, the provided dictionary stream pointer may be NULL, in which 365 * case any existing dictionary stream is unset. 366 * 367 * A dictionary should only be attached to a stream without any history (i.e., 368 * a stream that has just been reset). 369 * 370 * The dictionary will remain attached to the working stream only for the 371 * current stream session. Calls to LZ4_resetStreamHC(_fast) will remove the 372 * dictionary context association from the working stream. The dictionary 373 * stream (and source buffer) must remain in-place / accessible / unchanged 374 * through the lifetime of the stream session. 375 */ 376 LZ4LIB_STATIC_API void LZ4_attach_HC_dictionary( 377 LZ4_streamHC_t *working_stream, 378 const LZ4_streamHC_t *dictionary_stream); 379 380 #if defined (__cplusplus) 381 } 382 #endif 383 384 #endif /* LZ4_HC_SLO_098092834 */ 385 #endif /* LZ4_HC_STATIC_LINKING_ONLY */ 386