1 /* 2 LZ4 - Fast LZ compression algorithm 3 Copyright (C) 2011-2020, Yann Collet. 4 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 homepage : http://www.lz4.org 32 - LZ4 source repository : https://github.com/lz4/lz4 33 */ 34 35 #include "../../lv_conf_internal.h" 36 #if LV_USE_LZ4_INTERNAL 37 38 /*-************************************ 39 * Tuning parameters 40 **************************************/ 41 /* 42 * LZ4_HEAPMODE : 43 * Select how stateless compression functions like `LZ4_compress_default()` 44 * allocate memory for their hash table, 45 * in memory stack (0:default, fastest), or in memory heap (1:requires malloc()). 46 */ 47 #ifndef LZ4_HEAPMODE 48 # define LZ4_HEAPMODE 0 49 #endif 50 51 /* 52 * LZ4_ACCELERATION_DEFAULT : 53 * Select "acceleration" for LZ4_compress_fast() when parameter value <= 0 54 */ 55 #define LZ4_ACCELERATION_DEFAULT 1 56 /* 57 * LZ4_ACCELERATION_MAX : 58 * Any "acceleration" value higher than this threshold 59 * get treated as LZ4_ACCELERATION_MAX instead (fix #876) 60 */ 61 #define LZ4_ACCELERATION_MAX 65537 62 63 64 /*-************************************ 65 * CPU Feature Detection 66 **************************************/ 67 /* LZ4_FORCE_MEMORY_ACCESS 68 * By default, access to unaligned memory is controlled by `memcpy()`, which is safe and portable. 69 * Unfortunately, on some target/compiler combinations, the generated assembly is sub-optimal. 70 * The below switch allow to select different access method for improved performance. 71 * Method 0 (default) : use `memcpy()`. Safe and portable. 72 * Method 1 : `__packed` statement. It depends on compiler extension (ie, not portable). 73 * This method is safe if your compiler supports it, and *generally* as fast or faster than `memcpy`. 74 * Method 2 : direct access. This method is portable but violate C standard. 75 * It can generate buggy code on targets which assembly generation depends on alignment. 76 * But in some circumstances, it's the only known way to get the most performance (ie GCC + ARMv6) 77 * See https://fastcompression.blogspot.fr/2015/08/accessing-unaligned-memory.html for details. 78 * Prefer these methods in priority order (0 > 1 > 2) 79 */ 80 #ifndef LZ4_FORCE_MEMORY_ACCESS /* can be defined externally */ 81 # if defined(__GNUC__) && \ 82 ( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) \ 83 || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) ) 84 # define LZ4_FORCE_MEMORY_ACCESS 2 85 # elif (defined(__INTEL_COMPILER) && !defined(_WIN32)) || defined(__GNUC__) || defined(_MSC_VER) 86 # define LZ4_FORCE_MEMORY_ACCESS 1 87 # endif 88 #endif 89 90 /* 91 * LZ4_FORCE_SW_BITCOUNT 92 * Define this parameter if your target system or compiler does not support hardware bit count 93 */ 94 #if defined(_MSC_VER) && defined(_WIN32_WCE) /* Visual Studio for WinCE doesn't support Hardware bit count */ 95 # undef LZ4_FORCE_SW_BITCOUNT /* avoid double def */ 96 # define LZ4_FORCE_SW_BITCOUNT 97 #endif 98 99 100 101 /*-************************************ 102 * Dependency 103 **************************************/ 104 /* 105 * LZ4_SRC_INCLUDED: 106 * Amalgamation flag, whether lz4.c is included 107 */ 108 #ifndef LZ4_SRC_INCLUDED 109 # define LZ4_SRC_INCLUDED 1 110 #endif 111 112 #ifndef LZ4_STATIC_LINKING_ONLY 113 #define LZ4_STATIC_LINKING_ONLY 114 #endif 115 116 #ifndef LZ4_DISABLE_DEPRECATE_WARNINGS 117 #define LZ4_DISABLE_DEPRECATE_WARNINGS /* due to LZ4_decompress_safe_withPrefix64k */ 118 #endif 119 120 #define LZ4_STATIC_LINKING_ONLY /* LZ4_DISTANCE_MAX */ 121 #include "lz4.h" 122 /* see also "memory routines" below */ 123 124 125 /*-************************************ 126 * Compiler Options 127 **************************************/ 128 #if defined(_MSC_VER) && (_MSC_VER >= 1400) /* Visual Studio 2005+ */ 129 # include <intrin.h> /* only present in VS2005+ */ 130 # pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */ 131 # pragma warning(disable : 6237) /* disable: C6237: conditional expression is always 0 */ 132 #endif /* _MSC_VER */ 133 134 #ifndef LZ4_FORCE_INLINE 135 # ifdef _MSC_VER /* Visual Studio */ 136 # define LZ4_FORCE_INLINE static __forceinline 137 # else 138 # if defined (__cplusplus) || defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */ 139 # ifdef __GNUC__ 140 # define LZ4_FORCE_INLINE static inline __attribute__((always_inline)) 141 # else 142 # define LZ4_FORCE_INLINE static inline 143 # endif 144 # else 145 # define LZ4_FORCE_INLINE static 146 # endif /* __STDC_VERSION__ */ 147 # endif /* _MSC_VER */ 148 #endif /* LZ4_FORCE_INLINE */ 149 150 /* LZ4_FORCE_O2 and LZ4_FORCE_INLINE 151 * gcc on ppc64le generates an unrolled SIMDized loop for LZ4_wildCopy8, 152 * together with a simple 8-byte copy loop as a fall-back path. 153 * However, this optimization hurts the decompression speed by >30%, 154 * because the execution does not go to the optimized loop 155 * for typical compressible data, and all of the preamble checks 156 * before going to the fall-back path become useless overhead. 157 * This optimization happens only with the -O3 flag, and -O2 generates 158 * a simple 8-byte copy loop. 159 * With gcc on ppc64le, all of the LZ4_decompress_* and LZ4_wildCopy8 160 * functions are annotated with __attribute__((optimize("O2"))), 161 * and also LZ4_wildCopy8 is forcibly inlined, so that the O2 attribute 162 * of LZ4_wildCopy8 does not affect the compression speed. 163 */ 164 #if defined(__PPC64__) && defined(__LITTLE_ENDIAN__) && defined(__GNUC__) && !defined(__clang__) 165 # define LZ4_FORCE_O2 __attribute__((optimize("O2"))) 166 # undef LZ4_FORCE_INLINE 167 # define LZ4_FORCE_INLINE static __inline __attribute__((optimize("O2"),always_inline)) 168 #else 169 # define LZ4_FORCE_O2 170 #endif 171 172 #if (defined(__GNUC__) && (__GNUC__ >= 3)) || (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 800)) || defined(__clang__) 173 # define expect(expr,value) (__builtin_expect ((expr),(value)) ) 174 #else 175 # define expect(expr,value) (expr) 176 #endif 177 178 #ifndef likely 179 #define likely(expr) expect((expr) != 0, 1) 180 #endif 181 #ifndef unlikely 182 #define unlikely(expr) expect((expr) != 0, 0) 183 #endif 184 185 /* Should the alignment test prove unreliable, for some reason, 186 * it can be disabled by setting LZ4_ALIGN_TEST to 0 */ 187 #ifndef LZ4_ALIGN_TEST /* can be externally provided */ 188 # define LZ4_ALIGN_TEST 1 189 #endif 190 191 192 /*-************************************ 193 * Memory routines 194 **************************************/ 195 196 /*! LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION : 197 * Disable relatively high-level LZ4/HC functions that use dynamic memory 198 * allocation functions (malloc(), calloc(), free()). 199 * 200 * Note that this is a compile-time switch. And since it disables 201 * public/stable LZ4 v1 API functions, we don't recommend using this 202 * symbol to generate a library for distribution. 203 * 204 * The following public functions are removed when this symbol is defined. 205 * - lz4 : LZ4_createStream, LZ4_freeStream, 206 * LZ4_createStreamDecode, LZ4_freeStreamDecode, LZ4_create (deprecated) 207 * - lz4hc : LZ4_createStreamHC, LZ4_freeStreamHC, 208 * LZ4_createHC (deprecated), LZ4_freeHC (deprecated) 209 * - lz4frame, lz4file : All LZ4F_* functions 210 */ 211 #if defined(LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION) 212 # define ALLOC(s) lz4_error_memory_allocation_is_disabled 213 # define ALLOC_AND_ZERO(s) lz4_error_memory_allocation_is_disabled 214 # define FREEMEM(p) lz4_error_memory_allocation_is_disabled 215 #elif defined(LZ4_USER_MEMORY_FUNCTIONS) 216 /* memory management functions can be customized by user project. 217 * Below functions must exist somewhere in the Project 218 * and be available at link time */ 219 void* LZ4_malloc(size_t s); 220 void* LZ4_calloc(size_t n, size_t s); 221 void LZ4_free(void* p); 222 # define ALLOC(s) LZ4_malloc(s) 223 # define ALLOC_AND_ZERO(s) LZ4_calloc(1,s) 224 # define FREEMEM(p) LZ4_free(p) 225 #else 226 # include <stdlib.h> /* malloc, calloc, free */ 227 # define ALLOC(s) malloc(s) 228 # define ALLOC_AND_ZERO(s) calloc(1,s) 229 # define FREEMEM(p) free(p) 230 #endif 231 232 #if ! LZ4_FREESTANDING 233 # include <string.h> /* memset, memcpy */ 234 #endif 235 #if !defined(LZ4_memset) 236 # define LZ4_memset(p,v,s) memset((p),(v),(s)) 237 #endif 238 #define MEM_INIT(p,v,s) LZ4_memset((p),(v),(s)) 239 240 241 /*-************************************ 242 * Common Constants 243 **************************************/ 244 #define MINMATCH 4 245 246 #define WILDCOPYLENGTH 8 247 #define LASTLITERALS 5 /* see ../doc/lz4_Block_format.md#parsing-restrictions */ 248 #define MFLIMIT 12 /* see ../doc/lz4_Block_format.md#parsing-restrictions */ 249 #define MATCH_SAFEGUARD_DISTANCE ((2*WILDCOPYLENGTH) - MINMATCH) /* ensure it's possible to write 2 x wildcopyLength without overflowing output buffer */ 250 #define FASTLOOP_SAFE_DISTANCE 64 251 static const int LZ4_minLength = (MFLIMIT+1); 252 253 #define KB *(1 <<10) 254 #define MB *(1 <<20) 255 #define GB *(1U<<30) 256 257 #define LZ4_DISTANCE_ABSOLUTE_MAX 65535 258 #if (LZ4_DISTANCE_MAX > LZ4_DISTANCE_ABSOLUTE_MAX) /* max supported by LZ4 format */ 259 # error "LZ4_DISTANCE_MAX is too big : must be <= 65535" 260 #endif 261 262 #define ML_BITS 4 263 #define ML_MASK ((1U<<ML_BITS)-1) 264 #define RUN_BITS (8-ML_BITS) 265 #define RUN_MASK ((1U<<RUN_BITS)-1) 266 267 268 /*-************************************ 269 * Error detection 270 **************************************/ 271 #if defined(LZ4_DEBUG) && (LZ4_DEBUG>=1) 272 # include <assert.h> 273 #else 274 # ifndef assert 275 # define assert(condition) ((void)0) 276 # endif 277 #endif 278 279 #define LZ4_STATIC_ASSERT(c) { enum { LZ4_static_assert = 1/(int)(!!(c)) }; } /* use after variable declarations */ 280 281 #if defined(LZ4_DEBUG) && (LZ4_DEBUG>=2) 282 # include <stdio.h> 283 static int g_debuglog_enable = 1; 284 # define DEBUGLOG(l, ...) { \ 285 if ((g_debuglog_enable) && (l<=LZ4_DEBUG)) { \ 286 fprintf(stderr, __FILE__ " %i: ", __LINE__); \ 287 fprintf(stderr, __VA_ARGS__); \ 288 fprintf(stderr, " \n"); \ 289 } } 290 #else 291 # define DEBUGLOG(l, ...) {} /* disabled */ 292 #endif 293 LZ4_isAligned(const void * ptr,size_t alignment)294 static int LZ4_isAligned(const void* ptr, size_t alignment) 295 { 296 return ((size_t)ptr & (alignment -1)) == 0; 297 } 298 299 300 /*-************************************ 301 * Types 302 **************************************/ 303 #include <limits.h> 304 #if defined(__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) 305 # include <stdint.h> 306 typedef uint8_t BYTE; 307 typedef uint16_t U16; 308 typedef uint32_t U32; 309 typedef int32_t S32; 310 typedef uint64_t U64; 311 typedef uintptr_t uptrval; 312 #else 313 # if UINT_MAX != 4294967295UL 314 # error "LZ4 code (when not C++ or C99) assumes that sizeof(int) == 4" 315 # endif 316 typedef unsigned char BYTE; 317 typedef unsigned short U16; 318 typedef unsigned int U32; 319 typedef signed int S32; 320 typedef unsigned long long U64; 321 typedef size_t uptrval; /* generally true, except OpenVMS-64 */ 322 #endif 323 324 #if defined(__x86_64__) 325 typedef U64 reg_t; /* 64-bits in x32 mode */ 326 #else 327 typedef size_t reg_t; /* 32-bits in x32 mode */ 328 #endif 329 330 typedef enum { 331 notLimited = 0, 332 limitedOutput = 1, 333 fillOutput = 2 334 } limitedOutput_directive; 335 336 337 /*-************************************ 338 * Reading and writing into memory 339 **************************************/ 340 341 /** 342 * LZ4 relies on memcpy with a constant size being inlined. In freestanding 343 * environments, the compiler can't assume the implementation of memcpy() is 344 * standard compliant, so it can't apply its specialized memcpy() inlining 345 * logic. When possible, use __builtin_memcpy() to tell the compiler to analyze 346 * memcpy() as if it were standard compliant, so it can inline it in freestanding 347 * environments. This is needed when decompressing the Linux Kernel, for example. 348 */ 349 #if !defined(LZ4_memcpy) 350 # if defined(__GNUC__) && (__GNUC__ >= 4) 351 # define LZ4_memcpy(dst, src, size) __builtin_memcpy(dst, src, size) 352 # else 353 # define LZ4_memcpy(dst, src, size) memcpy(dst, src, size) 354 # endif 355 #endif 356 357 #if !defined(LZ4_memmove) 358 # if defined(__GNUC__) && (__GNUC__ >= 4) 359 # define LZ4_memmove __builtin_memmove 360 # else 361 # define LZ4_memmove memmove 362 # endif 363 #endif 364 LZ4_isLittleEndian(void)365 static unsigned LZ4_isLittleEndian(void) 366 { 367 const union { U32 u; BYTE c[4]; } one = { 1 }; /* don't use static : performance detrimental */ 368 return one.c[0]; 369 } 370 371 #if defined(__GNUC__) || defined(__INTEL_COMPILER) 372 #define LZ4_PACK( __Declaration__ ) __Declaration__ __attribute__((__packed__)) 373 #elif defined(_MSC_VER) 374 #define LZ4_PACK( __Declaration__ ) __pragma( pack(push, 1) ) __Declaration__ __pragma( pack(pop)) 375 #endif 376 377 #if defined(LZ4_FORCE_MEMORY_ACCESS) && (LZ4_FORCE_MEMORY_ACCESS==2) 378 /* lie to the compiler about data alignment; use with caution */ 379 LZ4_read16(const void * memPtr)380 static U16 LZ4_read16(const void* memPtr) { return *(const U16*) memPtr; } LZ4_read32(const void * memPtr)381 static U32 LZ4_read32(const void* memPtr) { return *(const U32*) memPtr; } LZ4_read_ARCH(const void * memPtr)382 static reg_t LZ4_read_ARCH(const void* memPtr) { return *(const reg_t*) memPtr; } 383 LZ4_write16(void * memPtr,U16 value)384 static void LZ4_write16(void* memPtr, U16 value) { *(U16*)memPtr = value; } LZ4_write32(void * memPtr,U32 value)385 static void LZ4_write32(void* memPtr, U32 value) { *(U32*)memPtr = value; } 386 387 #elif defined(LZ4_FORCE_MEMORY_ACCESS) && (LZ4_FORCE_MEMORY_ACCESS==1) 388 389 /* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */ 390 /* currently only defined for gcc and icc */ 391 LZ4_PACK(typedef struct { U16 u16; }) LZ4_unalign16; 392 LZ4_PACK(typedef struct { U32 u32; }) LZ4_unalign32; 393 LZ4_PACK(typedef struct { reg_t uArch; }) LZ4_unalignST; 394 LZ4_read16(const void * ptr)395 static U16 LZ4_read16(const void* ptr) { return ((const LZ4_unalign16*)ptr)->u16; } LZ4_read32(const void * ptr)396 static U32 LZ4_read32(const void* ptr) { return ((const LZ4_unalign32*)ptr)->u32; } LZ4_read_ARCH(const void * ptr)397 static reg_t LZ4_read_ARCH(const void* ptr) { return ((const LZ4_unalignST*)ptr)->uArch; } 398 LZ4_write16(void * memPtr,U16 value)399 static void LZ4_write16(void* memPtr, U16 value) { ((LZ4_unalign16*)memPtr)->u16 = value; } LZ4_write32(void * memPtr,U32 value)400 static void LZ4_write32(void* memPtr, U32 value) { ((LZ4_unalign32*)memPtr)->u32 = value; } 401 402 #else /* safe and portable access using memcpy() */ 403 LZ4_read16(const void * memPtr)404 static U16 LZ4_read16(const void* memPtr) 405 { 406 U16 val; LZ4_memcpy(&val, memPtr, sizeof(val)); return val; 407 } 408 LZ4_read32(const void * memPtr)409 static U32 LZ4_read32(const void* memPtr) 410 { 411 U32 val; LZ4_memcpy(&val, memPtr, sizeof(val)); return val; 412 } 413 LZ4_read_ARCH(const void * memPtr)414 static reg_t LZ4_read_ARCH(const void* memPtr) 415 { 416 reg_t val; LZ4_memcpy(&val, memPtr, sizeof(val)); return val; 417 } 418 LZ4_write16(void * memPtr,U16 value)419 static void LZ4_write16(void* memPtr, U16 value) 420 { 421 LZ4_memcpy(memPtr, &value, sizeof(value)); 422 } 423 LZ4_write32(void * memPtr,U32 value)424 static void LZ4_write32(void* memPtr, U32 value) 425 { 426 LZ4_memcpy(memPtr, &value, sizeof(value)); 427 } 428 429 #endif /* LZ4_FORCE_MEMORY_ACCESS */ 430 431 LZ4_readLE16(const void * memPtr)432 static U16 LZ4_readLE16(const void* memPtr) 433 { 434 if (LZ4_isLittleEndian()) { 435 return LZ4_read16(memPtr); 436 } else { 437 const BYTE* p = (const BYTE*)memPtr; 438 return (U16)((U16)p[0] + (p[1]<<8)); 439 } 440 } 441 LZ4_writeLE16(void * memPtr,U16 value)442 static void LZ4_writeLE16(void* memPtr, U16 value) 443 { 444 if (LZ4_isLittleEndian()) { 445 LZ4_write16(memPtr, value); 446 } else { 447 BYTE* p = (BYTE*)memPtr; 448 p[0] = (BYTE) value; 449 p[1] = (BYTE)(value>>8); 450 } 451 } 452 453 /* customized variant of memcpy, which can overwrite up to 8 bytes beyond dstEnd */ 454 LZ4_FORCE_INLINE LZ4_wildCopy8(void * dstPtr,const void * srcPtr,void * dstEnd)455 void LZ4_wildCopy8(void* dstPtr, const void* srcPtr, void* dstEnd) 456 { 457 BYTE* d = (BYTE*)dstPtr; 458 const BYTE* s = (const BYTE*)srcPtr; 459 BYTE* const e = (BYTE*)dstEnd; 460 461 do { LZ4_memcpy(d,s,8); d+=8; s+=8; } while (d<e); 462 } 463 464 static const unsigned inc32table[8] = {0, 1, 2, 1, 0, 4, 4, 4}; 465 static const int dec64table[8] = {0, 0, 0, -1, -4, 1, 2, 3}; 466 467 468 #ifndef LZ4_FAST_DEC_LOOP 469 # if defined __i386__ || defined _M_IX86 || defined __x86_64__ || defined _M_X64 470 # define LZ4_FAST_DEC_LOOP 1 471 # elif defined(__aarch64__) && defined(__APPLE__) 472 # define LZ4_FAST_DEC_LOOP 1 473 # elif defined(__aarch64__) && !defined(__clang__) 474 /* On non-Apple aarch64, we disable this optimization for clang because 475 * on certain mobile chipsets, performance is reduced with clang. For 476 * more information refer to https://github.com/lz4/lz4/pull/707 */ 477 # define LZ4_FAST_DEC_LOOP 1 478 # else 479 # define LZ4_FAST_DEC_LOOP 0 480 # endif 481 #endif 482 483 #if LZ4_FAST_DEC_LOOP 484 485 LZ4_FORCE_INLINE void LZ4_memcpy_using_offset_base(BYTE * dstPtr,const BYTE * srcPtr,BYTE * dstEnd,const size_t offset)486 LZ4_memcpy_using_offset_base(BYTE* dstPtr, const BYTE* srcPtr, BYTE* dstEnd, const size_t offset) 487 { 488 assert(srcPtr + offset == dstPtr); 489 if (offset < 8) { 490 LZ4_write32(dstPtr, 0); /* silence an msan warning when offset==0 */ 491 dstPtr[0] = srcPtr[0]; 492 dstPtr[1] = srcPtr[1]; 493 dstPtr[2] = srcPtr[2]; 494 dstPtr[3] = srcPtr[3]; 495 srcPtr += inc32table[offset]; 496 LZ4_memcpy(dstPtr+4, srcPtr, 4); 497 srcPtr -= dec64table[offset]; 498 dstPtr += 8; 499 } else { 500 LZ4_memcpy(dstPtr, srcPtr, 8); 501 dstPtr += 8; 502 srcPtr += 8; 503 } 504 505 LZ4_wildCopy8(dstPtr, srcPtr, dstEnd); 506 } 507 508 /* customized variant of memcpy, which can overwrite up to 32 bytes beyond dstEnd 509 * this version copies two times 16 bytes (instead of one time 32 bytes) 510 * because it must be compatible with offsets >= 16. */ 511 LZ4_FORCE_INLINE void LZ4_wildCopy32(void * dstPtr,const void * srcPtr,void * dstEnd)512 LZ4_wildCopy32(void* dstPtr, const void* srcPtr, void* dstEnd) 513 { 514 BYTE* d = (BYTE*)dstPtr; 515 const BYTE* s = (const BYTE*)srcPtr; 516 BYTE* const e = (BYTE*)dstEnd; 517 518 do { LZ4_memcpy(d,s,16); LZ4_memcpy(d+16,s+16,16); d+=32; s+=32; } while (d<e); 519 } 520 521 /* LZ4_memcpy_using_offset() presumes : 522 * - dstEnd >= dstPtr + MINMATCH 523 * - there is at least 8 bytes available to write after dstEnd */ 524 LZ4_FORCE_INLINE void LZ4_memcpy_using_offset(BYTE * dstPtr,const BYTE * srcPtr,BYTE * dstEnd,const size_t offset)525 LZ4_memcpy_using_offset(BYTE* dstPtr, const BYTE* srcPtr, BYTE* dstEnd, const size_t offset) 526 { 527 BYTE v[8]; 528 529 assert(dstEnd >= dstPtr + MINMATCH); 530 531 switch(offset) { 532 case 1: 533 MEM_INIT(v, *srcPtr, 8); 534 break; 535 case 2: 536 LZ4_memcpy(v, srcPtr, 2); 537 LZ4_memcpy(&v[2], srcPtr, 2); 538 #if defined(_MSC_VER) && (_MSC_VER <= 1937) /* MSVC 2022 ver 17.7 or earlier */ 539 # pragma warning(push) 540 # pragma warning(disable : 6385) /* warning C6385: Reading invalid data from 'v'. */ 541 #endif 542 LZ4_memcpy(&v[4], v, 4); 543 #if defined(_MSC_VER) && (_MSC_VER <= 1937) /* MSVC 2022 ver 17.7 or earlier */ 544 # pragma warning(pop) 545 #endif 546 break; 547 case 4: 548 LZ4_memcpy(v, srcPtr, 4); 549 LZ4_memcpy(&v[4], srcPtr, 4); 550 break; 551 default: 552 LZ4_memcpy_using_offset_base(dstPtr, srcPtr, dstEnd, offset); 553 return; 554 } 555 556 LZ4_memcpy(dstPtr, v, 8); 557 dstPtr += 8; 558 while (dstPtr < dstEnd) { 559 LZ4_memcpy(dstPtr, v, 8); 560 dstPtr += 8; 561 } 562 } 563 #endif 564 565 566 /*-************************************ 567 * Common functions 568 **************************************/ LZ4_NbCommonBytes(reg_t val)569 static unsigned LZ4_NbCommonBytes (reg_t val) 570 { 571 assert(val != 0); 572 if (LZ4_isLittleEndian()) { 573 if (sizeof(val) == 8) { 574 # if defined(_MSC_VER) && (_MSC_VER >= 1800) && (defined(_M_AMD64) && !defined(_M_ARM64EC)) && !defined(LZ4_FORCE_SW_BITCOUNT) 575 /*-************************************************************************************************* 576 * ARM64EC is a Microsoft-designed ARM64 ABI compatible with AMD64 applications on ARM64 Windows 11. 577 * The ARM64EC ABI does not support AVX/AVX2/AVX512 instructions, nor their relevant intrinsics 578 * including _tzcnt_u64. Therefore, we need to neuter the _tzcnt_u64 code path for ARM64EC. 579 ****************************************************************************************************/ 580 # if defined(__clang__) && (__clang_major__ < 10) 581 /* Avoid undefined clang-cl intrinsics issue. 582 * See https://github.com/lz4/lz4/pull/1017 for details. */ 583 return (unsigned)__builtin_ia32_tzcnt_u64(val) >> 3; 584 # else 585 /* x64 CPUS without BMI support interpret `TZCNT` as `REP BSF` */ 586 return (unsigned)_tzcnt_u64(val) >> 3; 587 # endif 588 # elif defined(_MSC_VER) && defined(_WIN64) && !defined(LZ4_FORCE_SW_BITCOUNT) 589 unsigned long r = 0; 590 _BitScanForward64(&r, (U64)val); 591 return (unsigned)r >> 3; 592 # elif (defined(__clang__) || (defined(__GNUC__) && ((__GNUC__ > 3) || \ 593 ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 4))))) && \ 594 !defined(LZ4_FORCE_SW_BITCOUNT) 595 return (unsigned)__builtin_ctzll((U64)val) >> 3; 596 # else 597 const U64 m = 0x0101010101010101ULL; 598 val ^= val - 1; 599 return (unsigned)(((U64)((val & (m - 1)) * m)) >> 56); 600 # endif 601 } else /* 32 bits */ { 602 # if defined(_MSC_VER) && (_MSC_VER >= 1400) && !defined(LZ4_FORCE_SW_BITCOUNT) 603 unsigned long r; 604 _BitScanForward(&r, (U32)val); 605 return (unsigned)r >> 3; 606 # elif (defined(__clang__) || (defined(__GNUC__) && ((__GNUC__ > 3) || \ 607 ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 4))))) && \ 608 !defined(__TINYC__) && !defined(LZ4_FORCE_SW_BITCOUNT) 609 return (unsigned)__builtin_ctz((U32)val) >> 3; 610 # else 611 const U32 m = 0x01010101; 612 return (unsigned)((((val - 1) ^ val) & (m - 1)) * m) >> 24; 613 # endif 614 } 615 } else /* Big Endian CPU */ { 616 if (sizeof(val)==8) { 617 # if (defined(__clang__) || (defined(__GNUC__) && ((__GNUC__ > 3) || \ 618 ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 4))))) && \ 619 !defined(__TINYC__) && !defined(LZ4_FORCE_SW_BITCOUNT) 620 return (unsigned)__builtin_clzll((U64)val) >> 3; 621 # else 622 #if 1 623 /* this method is probably faster, 624 * but adds a 128 bytes lookup table */ 625 static const unsigned char ctz7_tab[128] = { 626 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 627 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 628 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 629 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 630 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 631 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 632 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 633 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 634 }; 635 U64 const mask = 0x0101010101010101ULL; 636 U64 const t = (((val >> 8) - mask) | val) & mask; 637 return ctz7_tab[(t * 0x0080402010080402ULL) >> 57]; 638 #else 639 /* this method doesn't consume memory space like the previous one, 640 * but it contains several branches, 641 * that may end up slowing execution */ 642 static const U32 by32 = sizeof(val)*4; /* 32 on 64 bits (goal), 16 on 32 bits. 643 Just to avoid some static analyzer complaining about shift by 32 on 32-bits target. 644 Note that this code path is never triggered in 32-bits mode. */ 645 unsigned r; 646 if (!(val>>by32)) { r=4; } else { r=0; val>>=by32; } 647 if (!(val>>16)) { r+=2; val>>=8; } else { val>>=24; } 648 r += (!val); 649 return r; 650 #endif 651 # endif 652 } else /* 32 bits */ { 653 # if (defined(__clang__) || (defined(__GNUC__) && ((__GNUC__ > 3) || \ 654 ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 4))))) && \ 655 !defined(LZ4_FORCE_SW_BITCOUNT) 656 return (unsigned)__builtin_clz((U32)val) >> 3; 657 # else 658 val >>= 8; 659 val = ((((val + 0x00FFFF00) | 0x00FFFFFF) + val) | 660 (val + 0x00FF0000)) >> 24; 661 return (unsigned)val ^ 3; 662 # endif 663 } 664 } 665 } 666 667 668 #define STEPSIZE sizeof(reg_t) 669 LZ4_FORCE_INLINE LZ4_count(const BYTE * pIn,const BYTE * pMatch,const BYTE * pInLimit)670 unsigned LZ4_count(const BYTE* pIn, const BYTE* pMatch, const BYTE* pInLimit) 671 { 672 const BYTE* const pStart = pIn; 673 674 if (likely(pIn < pInLimit-(STEPSIZE-1))) { 675 reg_t const diff = LZ4_read_ARCH(pMatch) ^ LZ4_read_ARCH(pIn); 676 if (!diff) { 677 pIn+=STEPSIZE; pMatch+=STEPSIZE; 678 } else { 679 return LZ4_NbCommonBytes(diff); 680 } } 681 682 while (likely(pIn < pInLimit-(STEPSIZE-1))) { 683 reg_t const diff = LZ4_read_ARCH(pMatch) ^ LZ4_read_ARCH(pIn); 684 if (!diff) { pIn+=STEPSIZE; pMatch+=STEPSIZE; continue; } 685 pIn += LZ4_NbCommonBytes(diff); 686 return (unsigned)(pIn - pStart); 687 } 688 689 if ((STEPSIZE==8) && (pIn<(pInLimit-3)) && (LZ4_read32(pMatch) == LZ4_read32(pIn))) { pIn+=4; pMatch+=4; } 690 if ((pIn<(pInLimit-1)) && (LZ4_read16(pMatch) == LZ4_read16(pIn))) { pIn+=2; pMatch+=2; } 691 if ((pIn<pInLimit) && (*pMatch == *pIn)) pIn++; 692 return (unsigned)(pIn - pStart); 693 } 694 695 696 #ifndef LZ4_COMMONDEFS_ONLY 697 /*-************************************ 698 * Local Constants 699 **************************************/ 700 static const int LZ4_64Klimit = ((64 KB) + (MFLIMIT-1)); 701 static const U32 LZ4_skipTrigger = 6; /* Increase this value ==> compression run slower on incompressible data */ 702 703 704 /*-************************************ 705 * Local Structures and types 706 **************************************/ 707 typedef enum { clearedTable = 0, byPtr, byU32, byU16 } tableType_t; 708 709 /** 710 * This enum distinguishes several different modes of accessing previous 711 * content in the stream. 712 * 713 * - noDict : There is no preceding content. 714 * - withPrefix64k : Table entries up to ctx->dictSize before the current blob 715 * blob being compressed are valid and refer to the preceding 716 * content (of length ctx->dictSize), which is available 717 * contiguously preceding in memory the content currently 718 * being compressed. 719 * - usingExtDict : Like withPrefix64k, but the preceding content is somewhere 720 * else in memory, starting at ctx->dictionary with length 721 * ctx->dictSize. 722 * - usingDictCtx : Everything concerning the preceding content is 723 * in a separate context, pointed to by ctx->dictCtx. 724 * ctx->dictionary, ctx->dictSize, and table entries 725 * in the current context that refer to positions 726 * preceding the beginning of the current compression are 727 * ignored. Instead, ctx->dictCtx->dictionary and ctx->dictCtx 728 * ->dictSize describe the location and size of the preceding 729 * content, and matches are found by looking in the ctx 730 * ->dictCtx->hashTable. 731 */ 732 typedef enum { noDict = 0, withPrefix64k, usingExtDict, usingDictCtx } dict_directive; 733 typedef enum { noDictIssue = 0, dictSmall } dictIssue_directive; 734 735 736 /*-************************************ 737 * Local Utils 738 **************************************/ LZ4_versionNumber(void)739 int LZ4_versionNumber (void) { return LZ4_VERSION_NUMBER; } LZ4_versionString(void)740 const char* LZ4_versionString(void) { return LZ4_VERSION_STRING; } LZ4_compressBound(int isize)741 int LZ4_compressBound(int isize) { return LZ4_COMPRESSBOUND(isize); } LZ4_sizeofState(void)742 int LZ4_sizeofState(void) { return sizeof(LZ4_stream_t); } 743 744 745 /*-**************************************** 746 * Internal Definitions, used only in Tests 747 *******************************************/ 748 #if defined (__cplusplus) 749 extern "C" { 750 #endif 751 752 int LZ4_compress_forceExtDict (LZ4_stream_t* LZ4_dict, const char* source, char* dest, int srcSize); 753 754 int LZ4_decompress_safe_forceExtDict(const char* source, char* dest, 755 int compressedSize, int maxOutputSize, 756 const void* dictStart, size_t dictSize); 757 int LZ4_decompress_safe_partial_forceExtDict(const char* source, char* dest, 758 int compressedSize, int targetOutputSize, int dstCapacity, 759 const void* dictStart, size_t dictSize); 760 #if defined (__cplusplus) 761 } 762 #endif 763 764 /*-****************************** 765 * Compression functions 766 ********************************/ LZ4_hash4(U32 sequence,tableType_t const tableType)767 LZ4_FORCE_INLINE U32 LZ4_hash4(U32 sequence, tableType_t const tableType) 768 { 769 if (tableType == byU16) 770 return ((sequence * 2654435761U) >> ((MINMATCH*8)-(LZ4_HASHLOG+1))); 771 else 772 return ((sequence * 2654435761U) >> ((MINMATCH*8)-LZ4_HASHLOG)); 773 } 774 LZ4_hash5(U64 sequence,tableType_t const tableType)775 LZ4_FORCE_INLINE U32 LZ4_hash5(U64 sequence, tableType_t const tableType) 776 { 777 const U32 hashLog = (tableType == byU16) ? LZ4_HASHLOG+1 : LZ4_HASHLOG; 778 if (LZ4_isLittleEndian()) { 779 const U64 prime5bytes = 889523592379ULL; 780 return (U32)(((sequence << 24) * prime5bytes) >> (64 - hashLog)); 781 } else { 782 const U64 prime8bytes = 11400714785074694791ULL; 783 return (U32)(((sequence >> 24) * prime8bytes) >> (64 - hashLog)); 784 } 785 } 786 LZ4_hashPosition(const void * const p,tableType_t const tableType)787 LZ4_FORCE_INLINE U32 LZ4_hashPosition(const void* const p, tableType_t const tableType) 788 { 789 if ((sizeof(reg_t)==8) && (tableType != byU16)) return LZ4_hash5(LZ4_read_ARCH(p), tableType); 790 return LZ4_hash4(LZ4_read32(p), tableType); 791 } 792 LZ4_clearHash(U32 h,void * tableBase,tableType_t const tableType)793 LZ4_FORCE_INLINE void LZ4_clearHash(U32 h, void* tableBase, tableType_t const tableType) 794 { 795 switch (tableType) 796 { 797 default: /* fallthrough */ 798 case clearedTable: { /* illegal! */ assert(0); return; } 799 case byPtr: { const BYTE** hashTable = (const BYTE**)tableBase; hashTable[h] = NULL; return; } 800 case byU32: { U32* hashTable = (U32*) tableBase; hashTable[h] = 0; return; } 801 case byU16: { U16* hashTable = (U16*) tableBase; hashTable[h] = 0; return; } 802 } 803 } 804 LZ4_putIndexOnHash(U32 idx,U32 h,void * tableBase,tableType_t const tableType)805 LZ4_FORCE_INLINE void LZ4_putIndexOnHash(U32 idx, U32 h, void* tableBase, tableType_t const tableType) 806 { 807 switch (tableType) 808 { 809 default: /* fallthrough */ 810 case clearedTable: /* fallthrough */ 811 case byPtr: { /* illegal! */ assert(0); return; } 812 case byU32: { U32* hashTable = (U32*) tableBase; hashTable[h] = idx; return; } 813 case byU16: { U16* hashTable = (U16*) tableBase; assert(idx < 65536); hashTable[h] = (U16)idx; return; } 814 } 815 } 816 817 /* LZ4_putPosition*() : only used in byPtr mode */ LZ4_putPositionOnHash(const BYTE * p,U32 h,void * tableBase,tableType_t const tableType)818 LZ4_FORCE_INLINE void LZ4_putPositionOnHash(const BYTE* p, U32 h, 819 void* tableBase, tableType_t const tableType) 820 { 821 const BYTE** const hashTable = (const BYTE**)tableBase; 822 assert(tableType == byPtr); (void)tableType; 823 hashTable[h] = p; 824 } 825 LZ4_putPosition(const BYTE * p,void * tableBase,tableType_t tableType)826 LZ4_FORCE_INLINE void LZ4_putPosition(const BYTE* p, void* tableBase, tableType_t tableType) 827 { 828 U32 const h = LZ4_hashPosition(p, tableType); 829 LZ4_putPositionOnHash(p, h, tableBase, tableType); 830 } 831 832 /* LZ4_getIndexOnHash() : 833 * Index of match position registered in hash table. 834 * hash position must be calculated by using base+index, or dictBase+index. 835 * Assumption 1 : only valid if tableType == byU32 or byU16. 836 * Assumption 2 : h is presumed valid (within limits of hash table) 837 */ LZ4_getIndexOnHash(U32 h,const void * tableBase,tableType_t tableType)838 LZ4_FORCE_INLINE U32 LZ4_getIndexOnHash(U32 h, const void* tableBase, tableType_t tableType) 839 { 840 LZ4_STATIC_ASSERT(LZ4_MEMORY_USAGE > 2); 841 if (tableType == byU32) { 842 const U32* const hashTable = (const U32*) tableBase; 843 assert(h < (1U << (LZ4_MEMORY_USAGE-2))); 844 return hashTable[h]; 845 } 846 if (tableType == byU16) { 847 const U16* const hashTable = (const U16*) tableBase; 848 assert(h < (1U << (LZ4_MEMORY_USAGE-1))); 849 return hashTable[h]; 850 } 851 assert(0); return 0; /* forbidden case */ 852 } 853 LZ4_getPositionOnHash(U32 h,const void * tableBase,tableType_t tableType)854 static const BYTE* LZ4_getPositionOnHash(U32 h, const void* tableBase, tableType_t tableType) 855 { 856 assert(tableType == byPtr); (void)tableType; 857 { const BYTE* const* hashTable = (const BYTE* const*) tableBase; return hashTable[h]; } 858 } 859 860 LZ4_FORCE_INLINE const BYTE* LZ4_getPosition(const BYTE * p,const void * tableBase,tableType_t tableType)861 LZ4_getPosition(const BYTE* p, 862 const void* tableBase, tableType_t tableType) 863 { 864 U32 const h = LZ4_hashPosition(p, tableType); 865 return LZ4_getPositionOnHash(h, tableBase, tableType); 866 } 867 868 LZ4_FORCE_INLINE void LZ4_prepareTable(LZ4_stream_t_internal * const cctx,const int inputSize,const tableType_t tableType)869 LZ4_prepareTable(LZ4_stream_t_internal* const cctx, 870 const int inputSize, 871 const tableType_t tableType) { 872 /* If the table hasn't been used, it's guaranteed to be zeroed out, and is 873 * therefore safe to use no matter what mode we're in. Otherwise, we figure 874 * out if it's safe to leave as is or whether it needs to be reset. 875 */ 876 if ((tableType_t)cctx->tableType != clearedTable) { 877 assert(inputSize >= 0); 878 if ((tableType_t)cctx->tableType != tableType 879 || ((tableType == byU16) && cctx->currentOffset + (unsigned)inputSize >= 0xFFFFU) 880 || ((tableType == byU32) && cctx->currentOffset > 1 GB) 881 || tableType == byPtr 882 || inputSize >= 4 KB) 883 { 884 DEBUGLOG(4, "LZ4_prepareTable: Resetting table in %p", cctx); 885 MEM_INIT(cctx->hashTable, 0, LZ4_HASHTABLESIZE); 886 cctx->currentOffset = 0; 887 cctx->tableType = (U32)clearedTable; 888 } else { 889 DEBUGLOG(4, "LZ4_prepareTable: Re-use hash table (no reset)"); 890 } 891 } 892 893 /* Adding a gap, so all previous entries are > LZ4_DISTANCE_MAX back, 894 * is faster than compressing without a gap. 895 * However, compressing with currentOffset == 0 is faster still, 896 * so we preserve that case. 897 */ 898 if (cctx->currentOffset != 0 && tableType == byU32) { 899 DEBUGLOG(5, "LZ4_prepareTable: adding 64KB to currentOffset"); 900 cctx->currentOffset += 64 KB; 901 } 902 903 /* Finally, clear history */ 904 cctx->dictCtx = NULL; 905 cctx->dictionary = NULL; 906 cctx->dictSize = 0; 907 } 908 909 /** LZ4_compress_generic_validated() : 910 * inlined, to ensure branches are decided at compilation time. 911 * The following conditions are presumed already validated: 912 * - source != NULL 913 * - inputSize > 0 914 */ LZ4_compress_generic_validated(LZ4_stream_t_internal * const cctx,const char * const source,char * const dest,const int inputSize,int * inputConsumed,const int maxOutputSize,const limitedOutput_directive outputDirective,const tableType_t tableType,const dict_directive dictDirective,const dictIssue_directive dictIssue,const int acceleration)915 LZ4_FORCE_INLINE int LZ4_compress_generic_validated( 916 LZ4_stream_t_internal* const cctx, 917 const char* const source, 918 char* const dest, 919 const int inputSize, 920 int* inputConsumed, /* only written when outputDirective == fillOutput */ 921 const int maxOutputSize, 922 const limitedOutput_directive outputDirective, 923 const tableType_t tableType, 924 const dict_directive dictDirective, 925 const dictIssue_directive dictIssue, 926 const int acceleration) 927 { 928 int result; 929 const BYTE* ip = (const BYTE*)source; 930 931 U32 const startIndex = cctx->currentOffset; 932 const BYTE* base = (const BYTE*)source - startIndex; 933 const BYTE* lowLimit; 934 935 const LZ4_stream_t_internal* dictCtx = (const LZ4_stream_t_internal*) cctx->dictCtx; 936 const BYTE* const dictionary = 937 dictDirective == usingDictCtx ? dictCtx->dictionary : cctx->dictionary; 938 const U32 dictSize = 939 dictDirective == usingDictCtx ? dictCtx->dictSize : cctx->dictSize; 940 const U32 dictDelta = 941 (dictDirective == usingDictCtx) ? startIndex - dictCtx->currentOffset : 0; /* make indexes in dictCtx comparable with indexes in current context */ 942 943 int const maybe_extMem = (dictDirective == usingExtDict) || (dictDirective == usingDictCtx); 944 U32 const prefixIdxLimit = startIndex - dictSize; /* used when dictDirective == dictSmall */ 945 const BYTE* const dictEnd = dictionary ? dictionary + dictSize : dictionary; 946 const BYTE* anchor = (const BYTE*) source; 947 const BYTE* const iend = ip + inputSize; 948 const BYTE* const mflimitPlusOne = iend - MFLIMIT + 1; 949 const BYTE* const matchlimit = iend - LASTLITERALS; 950 951 /* the dictCtx currentOffset is indexed on the start of the dictionary, 952 * while a dictionary in the current context precedes the currentOffset */ 953 const BYTE* dictBase = (dictionary == NULL) ? NULL : 954 (dictDirective == usingDictCtx) ? 955 dictionary + dictSize - dictCtx->currentOffset : 956 dictionary + dictSize - startIndex; 957 958 BYTE* op = (BYTE*) dest; 959 BYTE* const olimit = op + maxOutputSize; 960 961 U32 offset = 0; 962 U32 forwardH; 963 964 DEBUGLOG(5, "LZ4_compress_generic_validated: srcSize=%i, tableType=%u", inputSize, tableType); 965 assert(ip != NULL); 966 if (tableType == byU16) assert(inputSize<LZ4_64Klimit); /* Size too large (not within 64K limit) */ 967 if (tableType == byPtr) assert(dictDirective==noDict); /* only supported use case with byPtr */ 968 /* If init conditions are not met, we don't have to mark stream 969 * as having dirty context, since no action was taken yet */ 970 if (outputDirective == fillOutput && maxOutputSize < 1) { return 0; } /* Impossible to store anything */ 971 assert(acceleration >= 1); 972 973 lowLimit = (const BYTE*)source - (dictDirective == withPrefix64k ? dictSize : 0); 974 975 /* Update context state */ 976 if (dictDirective == usingDictCtx) { 977 /* Subsequent linked blocks can't use the dictionary. */ 978 /* Instead, they use the block we just compressed. */ 979 cctx->dictCtx = NULL; 980 cctx->dictSize = (U32)inputSize; 981 } else { 982 cctx->dictSize += (U32)inputSize; 983 } 984 cctx->currentOffset += (U32)inputSize; 985 cctx->tableType = (U32)tableType; 986 987 if (inputSize<LZ4_minLength) goto _last_literals; /* Input too small, no compression (all literals) */ 988 989 /* First Byte */ 990 { U32 const h = LZ4_hashPosition(ip, tableType); 991 if (tableType == byPtr) { 992 LZ4_putPositionOnHash(ip, h, cctx->hashTable, byPtr); 993 } else { 994 LZ4_putIndexOnHash(startIndex, h, cctx->hashTable, tableType); 995 } } 996 ip++; forwardH = LZ4_hashPosition(ip, tableType); 997 998 /* Main Loop */ 999 for ( ; ; ) { 1000 const BYTE* match; 1001 BYTE* token; 1002 const BYTE* filledIp; 1003 1004 /* Find a match */ 1005 if (tableType == byPtr) { 1006 const BYTE* forwardIp = ip; 1007 int step = 1; 1008 int searchMatchNb = acceleration << LZ4_skipTrigger; 1009 do { 1010 U32 const h = forwardH; 1011 ip = forwardIp; 1012 forwardIp += step; 1013 step = (searchMatchNb++ >> LZ4_skipTrigger); 1014 1015 if (unlikely(forwardIp > mflimitPlusOne)) goto _last_literals; 1016 assert(ip < mflimitPlusOne); 1017 1018 match = LZ4_getPositionOnHash(h, cctx->hashTable, tableType); 1019 forwardH = LZ4_hashPosition(forwardIp, tableType); 1020 LZ4_putPositionOnHash(ip, h, cctx->hashTable, tableType); 1021 1022 } while ( (match+LZ4_DISTANCE_MAX < ip) 1023 || (LZ4_read32(match) != LZ4_read32(ip)) ); 1024 1025 } else { /* byU32, byU16 */ 1026 1027 const BYTE* forwardIp = ip; 1028 int step = 1; 1029 int searchMatchNb = acceleration << LZ4_skipTrigger; 1030 do { 1031 U32 const h = forwardH; 1032 U32 const current = (U32)(forwardIp - base); 1033 U32 matchIndex = LZ4_getIndexOnHash(h, cctx->hashTable, tableType); 1034 assert(matchIndex <= current); 1035 assert(forwardIp - base < (ptrdiff_t)(2 GB - 1)); 1036 ip = forwardIp; 1037 forwardIp += step; 1038 step = (searchMatchNb++ >> LZ4_skipTrigger); 1039 1040 if (unlikely(forwardIp > mflimitPlusOne)) goto _last_literals; 1041 assert(ip < mflimitPlusOne); 1042 1043 if (dictDirective == usingDictCtx) { 1044 if (matchIndex < startIndex) { 1045 /* there was no match, try the dictionary */ 1046 assert(tableType == byU32); 1047 matchIndex = LZ4_getIndexOnHash(h, dictCtx->hashTable, byU32); 1048 match = dictBase + matchIndex; 1049 matchIndex += dictDelta; /* make dictCtx index comparable with current context */ 1050 lowLimit = dictionary; 1051 } else { 1052 match = base + matchIndex; 1053 lowLimit = (const BYTE*)source; 1054 } 1055 } else if (dictDirective == usingExtDict) { 1056 if (matchIndex < startIndex) { 1057 DEBUGLOG(7, "extDict candidate: matchIndex=%5u < startIndex=%5u", matchIndex, startIndex); 1058 assert(startIndex - matchIndex >= MINMATCH); 1059 assert(dictBase); 1060 match = dictBase + matchIndex; 1061 lowLimit = dictionary; 1062 } else { 1063 match = base + matchIndex; 1064 lowLimit = (const BYTE*)source; 1065 } 1066 } else { /* single continuous memory segment */ 1067 match = base + matchIndex; 1068 } 1069 forwardH = LZ4_hashPosition(forwardIp, tableType); 1070 LZ4_putIndexOnHash(current, h, cctx->hashTable, tableType); 1071 1072 DEBUGLOG(7, "candidate at pos=%u (offset=%u \n", matchIndex, current - matchIndex); 1073 if ((dictIssue == dictSmall) && (matchIndex < prefixIdxLimit)) { continue; } /* match outside of valid area */ 1074 assert(matchIndex < current); 1075 if ( ((tableType != byU16) || (LZ4_DISTANCE_MAX < LZ4_DISTANCE_ABSOLUTE_MAX)) 1076 && (matchIndex+LZ4_DISTANCE_MAX < current)) { 1077 continue; 1078 } /* too far */ 1079 assert((current - matchIndex) <= LZ4_DISTANCE_MAX); /* match now expected within distance */ 1080 1081 if (LZ4_read32(match) == LZ4_read32(ip)) { 1082 if (maybe_extMem) offset = current - matchIndex; 1083 break; /* match found */ 1084 } 1085 1086 } while(1); 1087 } 1088 1089 /* Catch up */ 1090 filledIp = ip; 1091 assert(ip > anchor); /* this is always true as ip has been advanced before entering the main loop */ 1092 if ((match > lowLimit) && unlikely(ip[-1] == match[-1])) { 1093 do { ip--; match--; } while (((ip > anchor) & (match > lowLimit)) && (unlikely(ip[-1] == match[-1]))); 1094 } 1095 1096 /* Encode Literals */ 1097 { unsigned const litLength = (unsigned)(ip - anchor); 1098 token = op++; 1099 if ((outputDirective == limitedOutput) && /* Check output buffer overflow */ 1100 (unlikely(op + litLength + (2 + 1 + LASTLITERALS) + (litLength/255) > olimit)) ) { 1101 return 0; /* cannot compress within `dst` budget. Stored indexes in hash table are nonetheless fine */ 1102 } 1103 if ((outputDirective == fillOutput) && 1104 (unlikely(op + (litLength+240)/255 /* litlen */ + litLength /* literals */ + 2 /* offset */ + 1 /* token */ + MFLIMIT - MINMATCH /* min last literals so last match is <= end - MFLIMIT */ > olimit))) { 1105 op--; 1106 goto _last_literals; 1107 } 1108 if (litLength >= RUN_MASK) { 1109 int len = (int)(litLength - RUN_MASK); 1110 *token = (RUN_MASK<<ML_BITS); 1111 for(; len >= 255 ; len-=255) *op++ = 255; 1112 *op++ = (BYTE)len; 1113 } 1114 else *token = (BYTE)(litLength<<ML_BITS); 1115 1116 /* Copy Literals */ 1117 LZ4_wildCopy8(op, anchor, op+litLength); 1118 op+=litLength; 1119 DEBUGLOG(6, "seq.start:%i, literals=%u, match.start:%i", 1120 (int)(anchor-(const BYTE*)source), litLength, (int)(ip-(const BYTE*)source)); 1121 } 1122 1123 _next_match: 1124 /* at this stage, the following variables must be correctly set : 1125 * - ip : at start of LZ operation 1126 * - match : at start of previous pattern occurrence; can be within current prefix, or within extDict 1127 * - offset : if maybe_ext_memSegment==1 (constant) 1128 * - lowLimit : must be == dictionary to mean "match is within extDict"; must be == source otherwise 1129 * - token and *token : position to write 4-bits for match length; higher 4-bits for literal length supposed already written 1130 */ 1131 1132 if ((outputDirective == fillOutput) && 1133 (op + 2 /* offset */ + 1 /* token */ + MFLIMIT - MINMATCH /* min last literals so last match is <= end - MFLIMIT */ > olimit)) { 1134 /* the match was too close to the end, rewind and go to last literals */ 1135 op = token; 1136 goto _last_literals; 1137 } 1138 1139 /* Encode Offset */ 1140 if (maybe_extMem) { /* static test */ 1141 DEBUGLOG(6, " with offset=%u (ext if > %i)", offset, (int)(ip - (const BYTE*)source)); 1142 assert(offset <= LZ4_DISTANCE_MAX && offset > 0); 1143 LZ4_writeLE16(op, (U16)offset); op+=2; 1144 } else { 1145 DEBUGLOG(6, " with offset=%u (same segment)", (U32)(ip - match)); 1146 assert(ip-match <= LZ4_DISTANCE_MAX); 1147 LZ4_writeLE16(op, (U16)(ip - match)); op+=2; 1148 } 1149 1150 /* Encode MatchLength */ 1151 { unsigned matchCode; 1152 1153 if ( (dictDirective==usingExtDict || dictDirective==usingDictCtx) 1154 && (lowLimit==dictionary) /* match within extDict */ ) { 1155 const BYTE* limit = ip + (dictEnd-match); 1156 assert(dictEnd > match); 1157 if (limit > matchlimit) limit = matchlimit; 1158 matchCode = LZ4_count(ip+MINMATCH, match+MINMATCH, limit); 1159 ip += (size_t)matchCode + MINMATCH; 1160 if (ip==limit) { 1161 unsigned const more = LZ4_count(limit, (const BYTE*)source, matchlimit); 1162 matchCode += more; 1163 ip += more; 1164 } 1165 DEBUGLOG(6, " with matchLength=%u starting in extDict", matchCode+MINMATCH); 1166 } else { 1167 matchCode = LZ4_count(ip+MINMATCH, match+MINMATCH, matchlimit); 1168 ip += (size_t)matchCode + MINMATCH; 1169 DEBUGLOG(6, " with matchLength=%u", matchCode+MINMATCH); 1170 } 1171 1172 if ((outputDirective) && /* Check output buffer overflow */ 1173 (unlikely(op + (1 + LASTLITERALS) + (matchCode+240)/255 > olimit)) ) { 1174 if (outputDirective == fillOutput) { 1175 /* Match description too long : reduce it */ 1176 U32 newMatchCode = 15 /* in token */ - 1 /* to avoid needing a zero byte */ + ((U32)(olimit - op) - 1 - LASTLITERALS) * 255; 1177 ip -= matchCode - newMatchCode; 1178 assert(newMatchCode < matchCode); 1179 matchCode = newMatchCode; 1180 if (unlikely(ip <= filledIp)) { 1181 /* We have already filled up to filledIp so if ip ends up less than filledIp 1182 * we have positions in the hash table beyond the current position. This is 1183 * a problem if we reuse the hash table. So we have to remove these positions 1184 * from the hash table. 1185 */ 1186 const BYTE* ptr; 1187 DEBUGLOG(5, "Clearing %u positions", (U32)(filledIp - ip)); 1188 for (ptr = ip; ptr <= filledIp; ++ptr) { 1189 U32 const h = LZ4_hashPosition(ptr, tableType); 1190 LZ4_clearHash(h, cctx->hashTable, tableType); 1191 } 1192 } 1193 } else { 1194 assert(outputDirective == limitedOutput); 1195 return 0; /* cannot compress within `dst` budget. Stored indexes in hash table are nonetheless fine */ 1196 } 1197 } 1198 if (matchCode >= ML_MASK) { 1199 *token += ML_MASK; 1200 matchCode -= ML_MASK; 1201 LZ4_write32(op, 0xFFFFFFFF); 1202 while (matchCode >= 4*255) { 1203 op+=4; 1204 LZ4_write32(op, 0xFFFFFFFF); 1205 matchCode -= 4*255; 1206 } 1207 op += matchCode / 255; 1208 *op++ = (BYTE)(matchCode % 255); 1209 } else 1210 *token += (BYTE)(matchCode); 1211 } 1212 /* Ensure we have enough space for the last literals. */ 1213 assert(!(outputDirective == fillOutput && op + 1 + LASTLITERALS > olimit)); 1214 1215 anchor = ip; 1216 1217 /* Test end of chunk */ 1218 if (ip >= mflimitPlusOne) break; 1219 1220 /* Fill table */ 1221 { U32 const h = LZ4_hashPosition(ip-2, tableType); 1222 if (tableType == byPtr) { 1223 LZ4_putPositionOnHash(ip-2, h, cctx->hashTable, byPtr); 1224 } else { 1225 U32 const idx = (U32)((ip-2) - base); 1226 LZ4_putIndexOnHash(idx, h, cctx->hashTable, tableType); 1227 } } 1228 1229 /* Test next position */ 1230 if (tableType == byPtr) { 1231 1232 match = LZ4_getPosition(ip, cctx->hashTable, tableType); 1233 LZ4_putPosition(ip, cctx->hashTable, tableType); 1234 if ( (match+LZ4_DISTANCE_MAX >= ip) 1235 && (LZ4_read32(match) == LZ4_read32(ip)) ) 1236 { token=op++; *token=0; goto _next_match; } 1237 1238 } else { /* byU32, byU16 */ 1239 1240 U32 const h = LZ4_hashPosition(ip, tableType); 1241 U32 const current = (U32)(ip-base); 1242 U32 matchIndex = LZ4_getIndexOnHash(h, cctx->hashTable, tableType); 1243 assert(matchIndex < current); 1244 if (dictDirective == usingDictCtx) { 1245 if (matchIndex < startIndex) { 1246 /* there was no match, try the dictionary */ 1247 assert(tableType == byU32); 1248 matchIndex = LZ4_getIndexOnHash(h, dictCtx->hashTable, byU32); 1249 match = dictBase + matchIndex; 1250 lowLimit = dictionary; /* required for match length counter */ 1251 matchIndex += dictDelta; 1252 } else { 1253 match = base + matchIndex; 1254 lowLimit = (const BYTE*)source; /* required for match length counter */ 1255 } 1256 } else if (dictDirective==usingExtDict) { 1257 if (matchIndex < startIndex) { 1258 assert(dictBase); 1259 match = dictBase + matchIndex; 1260 lowLimit = dictionary; /* required for match length counter */ 1261 } else { 1262 match = base + matchIndex; 1263 lowLimit = (const BYTE*)source; /* required for match length counter */ 1264 } 1265 } else { /* single memory segment */ 1266 match = base + matchIndex; 1267 } 1268 LZ4_putIndexOnHash(current, h, cctx->hashTable, tableType); 1269 assert(matchIndex < current); 1270 if ( ((dictIssue==dictSmall) ? (matchIndex >= prefixIdxLimit) : 1) 1271 && (((tableType==byU16) && (LZ4_DISTANCE_MAX == LZ4_DISTANCE_ABSOLUTE_MAX)) ? 1 : (matchIndex+LZ4_DISTANCE_MAX >= current)) 1272 && (LZ4_read32(match) == LZ4_read32(ip)) ) { 1273 token=op++; 1274 *token=0; 1275 if (maybe_extMem) offset = current - matchIndex; 1276 DEBUGLOG(6, "seq.start:%i, literals=%u, match.start:%i", 1277 (int)(anchor-(const BYTE*)source), 0, (int)(ip-(const BYTE*)source)); 1278 goto _next_match; 1279 } 1280 } 1281 1282 /* Prepare next loop */ 1283 forwardH = LZ4_hashPosition(++ip, tableType); 1284 1285 } 1286 1287 _last_literals: 1288 /* Encode Last Literals */ 1289 { size_t lastRun = (size_t)(iend - anchor); 1290 if ( (outputDirective) && /* Check output buffer overflow */ 1291 (op + lastRun + 1 + ((lastRun+255-RUN_MASK)/255) > olimit)) { 1292 if (outputDirective == fillOutput) { 1293 /* adapt lastRun to fill 'dst' */ 1294 assert(olimit >= op); 1295 lastRun = (size_t)(olimit-op) - 1/*token*/; 1296 lastRun -= (lastRun + 256 - RUN_MASK) / 256; /*additional length tokens*/ 1297 } else { 1298 assert(outputDirective == limitedOutput); 1299 return 0; /* cannot compress within `dst` budget. Stored indexes in hash table are nonetheless fine */ 1300 } 1301 } 1302 DEBUGLOG(6, "Final literal run : %i literals", (int)lastRun); 1303 if (lastRun >= RUN_MASK) { 1304 size_t accumulator = lastRun - RUN_MASK; 1305 *op++ = RUN_MASK << ML_BITS; 1306 for(; accumulator >= 255 ; accumulator-=255) *op++ = 255; 1307 *op++ = (BYTE) accumulator; 1308 } else { 1309 *op++ = (BYTE)(lastRun<<ML_BITS); 1310 } 1311 LZ4_memcpy(op, anchor, lastRun); 1312 ip = anchor + lastRun; 1313 op += lastRun; 1314 } 1315 1316 if (outputDirective == fillOutput) { 1317 *inputConsumed = (int) (((const char*)ip)-source); 1318 } 1319 result = (int)(((char*)op) - dest); 1320 assert(result > 0); 1321 DEBUGLOG(5, "LZ4_compress_generic: compressed %i bytes into %i bytes", inputSize, result); 1322 return result; 1323 } 1324 1325 /** LZ4_compress_generic() : 1326 * inlined, to ensure branches are decided at compilation time; 1327 * takes care of src == (NULL, 0) 1328 * and forward the rest to LZ4_compress_generic_validated */ LZ4_compress_generic(LZ4_stream_t_internal * const cctx,const char * const src,char * const dst,const int srcSize,int * inputConsumed,const int dstCapacity,const limitedOutput_directive outputDirective,const tableType_t tableType,const dict_directive dictDirective,const dictIssue_directive dictIssue,const int acceleration)1329 LZ4_FORCE_INLINE int LZ4_compress_generic( 1330 LZ4_stream_t_internal* const cctx, 1331 const char* const src, 1332 char* const dst, 1333 const int srcSize, 1334 int *inputConsumed, /* only written when outputDirective == fillOutput */ 1335 const int dstCapacity, 1336 const limitedOutput_directive outputDirective, 1337 const tableType_t tableType, 1338 const dict_directive dictDirective, 1339 const dictIssue_directive dictIssue, 1340 const int acceleration) 1341 { 1342 DEBUGLOG(5, "LZ4_compress_generic: srcSize=%i, dstCapacity=%i", 1343 srcSize, dstCapacity); 1344 1345 if ((U32)srcSize > (U32)LZ4_MAX_INPUT_SIZE) { return 0; } /* Unsupported srcSize, too large (or negative) */ 1346 if (srcSize == 0) { /* src == NULL supported if srcSize == 0 */ 1347 if (outputDirective != notLimited && dstCapacity <= 0) return 0; /* no output, can't write anything */ 1348 DEBUGLOG(5, "Generating an empty block"); 1349 assert(outputDirective == notLimited || dstCapacity >= 1); 1350 assert(dst != NULL); 1351 dst[0] = 0; 1352 if (outputDirective == fillOutput) { 1353 assert (inputConsumed != NULL); 1354 *inputConsumed = 0; 1355 } 1356 return 1; 1357 } 1358 assert(src != NULL); 1359 1360 return LZ4_compress_generic_validated(cctx, src, dst, srcSize, 1361 inputConsumed, /* only written into if outputDirective == fillOutput */ 1362 dstCapacity, outputDirective, 1363 tableType, dictDirective, dictIssue, acceleration); 1364 } 1365 1366 LZ4_compress_fast_extState(void * state,const char * source,char * dest,int inputSize,int maxOutputSize,int acceleration)1367 int LZ4_compress_fast_extState(void* state, const char* source, char* dest, int inputSize, int maxOutputSize, int acceleration) 1368 { 1369 LZ4_stream_t_internal* const ctx = & LZ4_initStream(state, sizeof(LZ4_stream_t)) -> internal_donotuse; 1370 assert(ctx != NULL); 1371 if (acceleration < 1) acceleration = LZ4_ACCELERATION_DEFAULT; 1372 if (acceleration > LZ4_ACCELERATION_MAX) acceleration = LZ4_ACCELERATION_MAX; 1373 if (maxOutputSize >= LZ4_compressBound(inputSize)) { 1374 if (inputSize < LZ4_64Klimit) { 1375 return LZ4_compress_generic(ctx, source, dest, inputSize, NULL, 0, notLimited, byU16, noDict, noDictIssue, acceleration); 1376 } else { 1377 const tableType_t tableType = ((sizeof(void*)==4) && ((uptrval)source > LZ4_DISTANCE_MAX)) ? byPtr : byU32; 1378 return LZ4_compress_generic(ctx, source, dest, inputSize, NULL, 0, notLimited, tableType, noDict, noDictIssue, acceleration); 1379 } 1380 } else { 1381 if (inputSize < LZ4_64Klimit) { 1382 return LZ4_compress_generic(ctx, source, dest, inputSize, NULL, maxOutputSize, limitedOutput, byU16, noDict, noDictIssue, acceleration); 1383 } else { 1384 const tableType_t tableType = ((sizeof(void*)==4) && ((uptrval)source > LZ4_DISTANCE_MAX)) ? byPtr : byU32; 1385 return LZ4_compress_generic(ctx, source, dest, inputSize, NULL, maxOutputSize, limitedOutput, tableType, noDict, noDictIssue, acceleration); 1386 } 1387 } 1388 } 1389 1390 /** 1391 * LZ4_compress_fast_extState_fastReset() : 1392 * A variant of LZ4_compress_fast_extState(). 1393 * 1394 * Using this variant avoids an expensive initialization step. It is only safe 1395 * to call if the state buffer is known to be correctly initialized already 1396 * (see comment in lz4.h on LZ4_resetStream_fast() for a definition of 1397 * "correctly initialized"). 1398 */ LZ4_compress_fast_extState_fastReset(void * state,const char * src,char * dst,int srcSize,int dstCapacity,int acceleration)1399 int LZ4_compress_fast_extState_fastReset(void* state, const char* src, char* dst, int srcSize, int dstCapacity, int acceleration) 1400 { 1401 LZ4_stream_t_internal* const ctx = &((LZ4_stream_t*)state)->internal_donotuse; 1402 if (acceleration < 1) acceleration = LZ4_ACCELERATION_DEFAULT; 1403 if (acceleration > LZ4_ACCELERATION_MAX) acceleration = LZ4_ACCELERATION_MAX; 1404 assert(ctx != NULL); 1405 1406 if (dstCapacity >= LZ4_compressBound(srcSize)) { 1407 if (srcSize < LZ4_64Klimit) { 1408 const tableType_t tableType = byU16; 1409 LZ4_prepareTable(ctx, srcSize, tableType); 1410 if (ctx->currentOffset) { 1411 return LZ4_compress_generic(ctx, src, dst, srcSize, NULL, 0, notLimited, tableType, noDict, dictSmall, acceleration); 1412 } else { 1413 return LZ4_compress_generic(ctx, src, dst, srcSize, NULL, 0, notLimited, tableType, noDict, noDictIssue, acceleration); 1414 } 1415 } else { 1416 const tableType_t tableType = ((sizeof(void*)==4) && ((uptrval)src > LZ4_DISTANCE_MAX)) ? byPtr : byU32; 1417 LZ4_prepareTable(ctx, srcSize, tableType); 1418 return LZ4_compress_generic(ctx, src, dst, srcSize, NULL, 0, notLimited, tableType, noDict, noDictIssue, acceleration); 1419 } 1420 } else { 1421 if (srcSize < LZ4_64Klimit) { 1422 const tableType_t tableType = byU16; 1423 LZ4_prepareTable(ctx, srcSize, tableType); 1424 if (ctx->currentOffset) { 1425 return LZ4_compress_generic(ctx, src, dst, srcSize, NULL, dstCapacity, limitedOutput, tableType, noDict, dictSmall, acceleration); 1426 } else { 1427 return LZ4_compress_generic(ctx, src, dst, srcSize, NULL, dstCapacity, limitedOutput, tableType, noDict, noDictIssue, acceleration); 1428 } 1429 } else { 1430 const tableType_t tableType = ((sizeof(void*)==4) && ((uptrval)src > LZ4_DISTANCE_MAX)) ? byPtr : byU32; 1431 LZ4_prepareTable(ctx, srcSize, tableType); 1432 return LZ4_compress_generic(ctx, src, dst, srcSize, NULL, dstCapacity, limitedOutput, tableType, noDict, noDictIssue, acceleration); 1433 } 1434 } 1435 } 1436 1437 LZ4_compress_fast(const char * src,char * dest,int srcSize,int dstCapacity,int acceleration)1438 int LZ4_compress_fast(const char* src, char* dest, int srcSize, int dstCapacity, int acceleration) 1439 { 1440 int result; 1441 #if (LZ4_HEAPMODE) 1442 LZ4_stream_t* const ctxPtr = (LZ4_stream_t*)ALLOC(sizeof(LZ4_stream_t)); /* malloc-calloc always properly aligned */ 1443 if (ctxPtr == NULL) return 0; 1444 #else 1445 LZ4_stream_t ctx; 1446 LZ4_stream_t* const ctxPtr = &ctx; 1447 #endif 1448 result = LZ4_compress_fast_extState(ctxPtr, src, dest, srcSize, dstCapacity, acceleration); 1449 1450 #if (LZ4_HEAPMODE) 1451 FREEMEM(ctxPtr); 1452 #endif 1453 return result; 1454 } 1455 1456 LZ4_compress_default(const char * src,char * dst,int srcSize,int dstCapacity)1457 int LZ4_compress_default(const char* src, char* dst, int srcSize, int dstCapacity) 1458 { 1459 return LZ4_compress_fast(src, dst, srcSize, dstCapacity, 1); 1460 } 1461 1462 1463 /* Note!: This function leaves the stream in an unclean/broken state! 1464 * It is not safe to subsequently use the same state with a _fastReset() or 1465 * _continue() call without resetting it. */ LZ4_compress_destSize_extState(LZ4_stream_t * state,const char * src,char * dst,int * srcSizePtr,int targetDstSize)1466 static int LZ4_compress_destSize_extState (LZ4_stream_t* state, const char* src, char* dst, int* srcSizePtr, int targetDstSize) 1467 { 1468 void* const s = LZ4_initStream(state, sizeof (*state)); 1469 assert(s != NULL); (void)s; 1470 1471 if (targetDstSize >= LZ4_compressBound(*srcSizePtr)) { /* compression success is guaranteed */ 1472 return LZ4_compress_fast_extState(state, src, dst, *srcSizePtr, targetDstSize, 1); 1473 } else { 1474 if (*srcSizePtr < LZ4_64Klimit) { 1475 return LZ4_compress_generic(&state->internal_donotuse, src, dst, *srcSizePtr, srcSizePtr, targetDstSize, fillOutput, byU16, noDict, noDictIssue, 1); 1476 } else { 1477 tableType_t const addrMode = ((sizeof(void*)==4) && ((uptrval)src > LZ4_DISTANCE_MAX)) ? byPtr : byU32; 1478 return LZ4_compress_generic(&state->internal_donotuse, src, dst, *srcSizePtr, srcSizePtr, targetDstSize, fillOutput, addrMode, noDict, noDictIssue, 1); 1479 } } 1480 } 1481 1482 LZ4_compress_destSize(const char * src,char * dst,int * srcSizePtr,int targetDstSize)1483 int LZ4_compress_destSize(const char* src, char* dst, int* srcSizePtr, int targetDstSize) 1484 { 1485 #if (LZ4_HEAPMODE) 1486 LZ4_stream_t* const ctx = (LZ4_stream_t*)ALLOC(sizeof(LZ4_stream_t)); /* malloc-calloc always properly aligned */ 1487 if (ctx == NULL) return 0; 1488 #else 1489 LZ4_stream_t ctxBody; 1490 LZ4_stream_t* const ctx = &ctxBody; 1491 #endif 1492 1493 int result = LZ4_compress_destSize_extState(ctx, src, dst, srcSizePtr, targetDstSize); 1494 1495 #if (LZ4_HEAPMODE) 1496 FREEMEM(ctx); 1497 #endif 1498 return result; 1499 } 1500 1501 1502 1503 /*-****************************** 1504 * Streaming functions 1505 ********************************/ 1506 1507 #if !defined(LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION) LZ4_createStream(void)1508 LZ4_stream_t* LZ4_createStream(void) 1509 { 1510 LZ4_stream_t* const lz4s = (LZ4_stream_t*)ALLOC(sizeof(LZ4_stream_t)); 1511 LZ4_STATIC_ASSERT(sizeof(LZ4_stream_t) >= sizeof(LZ4_stream_t_internal)); 1512 DEBUGLOG(4, "LZ4_createStream %p", lz4s); 1513 if (lz4s == NULL) return NULL; 1514 LZ4_initStream(lz4s, sizeof(*lz4s)); 1515 return lz4s; 1516 } 1517 #endif 1518 LZ4_stream_t_alignment(void)1519 static size_t LZ4_stream_t_alignment(void) 1520 { 1521 #if LZ4_ALIGN_TEST 1522 typedef struct { char c; LZ4_stream_t t; } t_a; 1523 return sizeof(t_a) - sizeof(LZ4_stream_t); 1524 #else 1525 return 1; /* effectively disabled */ 1526 #endif 1527 } 1528 LZ4_initStream(void * buffer,size_t size)1529 LZ4_stream_t* LZ4_initStream (void* buffer, size_t size) 1530 { 1531 DEBUGLOG(5, "LZ4_initStream"); 1532 if (buffer == NULL) { return NULL; } 1533 if (size < sizeof(LZ4_stream_t)) { return NULL; } 1534 if (!LZ4_isAligned(buffer, LZ4_stream_t_alignment())) return NULL; 1535 MEM_INIT(buffer, 0, sizeof(LZ4_stream_t_internal)); 1536 return (LZ4_stream_t*)buffer; 1537 } 1538 1539 /* resetStream is now deprecated, 1540 * prefer initStream() which is more general */ LZ4_resetStream(LZ4_stream_t * LZ4_stream)1541 void LZ4_resetStream (LZ4_stream_t* LZ4_stream) 1542 { 1543 DEBUGLOG(5, "LZ4_resetStream (ctx:%p)", LZ4_stream); 1544 MEM_INIT(LZ4_stream, 0, sizeof(LZ4_stream_t_internal)); 1545 } 1546 LZ4_resetStream_fast(LZ4_stream_t * ctx)1547 void LZ4_resetStream_fast(LZ4_stream_t* ctx) { 1548 LZ4_prepareTable(&(ctx->internal_donotuse), 0, byU32); 1549 } 1550 1551 #if !defined(LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION) LZ4_freeStream(LZ4_stream_t * LZ4_stream)1552 int LZ4_freeStream (LZ4_stream_t* LZ4_stream) 1553 { 1554 if (!LZ4_stream) return 0; /* support free on NULL */ 1555 DEBUGLOG(5, "LZ4_freeStream %p", LZ4_stream); 1556 FREEMEM(LZ4_stream); 1557 return (0); 1558 } 1559 #endif 1560 1561 1562 #define HASH_UNIT sizeof(reg_t) LZ4_loadDict(LZ4_stream_t * LZ4_dict,const char * dictionary,int dictSize)1563 int LZ4_loadDict (LZ4_stream_t* LZ4_dict, const char* dictionary, int dictSize) 1564 { 1565 LZ4_stream_t_internal* const dict = &LZ4_dict->internal_donotuse; 1566 const tableType_t tableType = byU32; 1567 const BYTE* p = (const BYTE*)dictionary; 1568 const BYTE* const dictEnd = p + dictSize; 1569 U32 idx32; 1570 1571 DEBUGLOG(4, "LZ4_loadDict (%i bytes from %p into %p)", dictSize, dictionary, LZ4_dict); 1572 1573 /* It's necessary to reset the context, 1574 * and not just continue it with prepareTable() 1575 * to avoid any risk of generating overflowing matchIndex 1576 * when compressing using this dictionary */ 1577 LZ4_resetStream(LZ4_dict); 1578 1579 /* We always increment the offset by 64 KB, since, if the dict is longer, 1580 * we truncate it to the last 64k, and if it's shorter, we still want to 1581 * advance by a whole window length so we can provide the guarantee that 1582 * there are only valid offsets in the window, which allows an optimization 1583 * in LZ4_compress_fast_continue() where it uses noDictIssue even when the 1584 * dictionary isn't a full 64k. */ 1585 dict->currentOffset += 64 KB; 1586 1587 if (dictSize < (int)HASH_UNIT) { 1588 return 0; 1589 } 1590 1591 if ((dictEnd - p) > 64 KB) p = dictEnd - 64 KB; 1592 dict->dictionary = p; 1593 dict->dictSize = (U32)(dictEnd - p); 1594 dict->tableType = (U32)tableType; 1595 idx32 = dict->currentOffset - dict->dictSize; 1596 1597 while (p <= dictEnd-HASH_UNIT) { 1598 U32 const h = LZ4_hashPosition(p, tableType); 1599 LZ4_putIndexOnHash(idx32, h, dict->hashTable, tableType); 1600 p+=3; idx32+=3; 1601 } 1602 1603 return (int)dict->dictSize; 1604 } 1605 LZ4_attach_dictionary(LZ4_stream_t * workingStream,const LZ4_stream_t * dictionaryStream)1606 void LZ4_attach_dictionary(LZ4_stream_t* workingStream, const LZ4_stream_t* dictionaryStream) 1607 { 1608 const LZ4_stream_t_internal* dictCtx = (dictionaryStream == NULL) ? NULL : 1609 &(dictionaryStream->internal_donotuse); 1610 1611 DEBUGLOG(4, "LZ4_attach_dictionary (%p, %p, size %u)", 1612 workingStream, dictionaryStream, 1613 dictCtx != NULL ? dictCtx->dictSize : 0); 1614 1615 if (dictCtx != NULL) { 1616 /* If the current offset is zero, we will never look in the 1617 * external dictionary context, since there is no value a table 1618 * entry can take that indicate a miss. In that case, we need 1619 * to bump the offset to something non-zero. 1620 */ 1621 if (workingStream->internal_donotuse.currentOffset == 0) { 1622 workingStream->internal_donotuse.currentOffset = 64 KB; 1623 } 1624 1625 /* Don't actually attach an empty dictionary. 1626 */ 1627 if (dictCtx->dictSize == 0) { 1628 dictCtx = NULL; 1629 } 1630 } 1631 workingStream->internal_donotuse.dictCtx = dictCtx; 1632 } 1633 1634 LZ4_renormDictT(LZ4_stream_t_internal * LZ4_dict,int nextSize)1635 static void LZ4_renormDictT(LZ4_stream_t_internal* LZ4_dict, int nextSize) 1636 { 1637 assert(nextSize >= 0); 1638 if (LZ4_dict->currentOffset + (unsigned)nextSize > 0x80000000) { /* potential ptrdiff_t overflow (32-bits mode) */ 1639 /* rescale hash table */ 1640 U32 const delta = LZ4_dict->currentOffset - 64 KB; 1641 const BYTE* dictEnd = LZ4_dict->dictionary + LZ4_dict->dictSize; 1642 int i; 1643 DEBUGLOG(4, "LZ4_renormDictT"); 1644 for (i=0; i<LZ4_HASH_SIZE_U32; i++) { 1645 if (LZ4_dict->hashTable[i] < delta) LZ4_dict->hashTable[i]=0; 1646 else LZ4_dict->hashTable[i] -= delta; 1647 } 1648 LZ4_dict->currentOffset = 64 KB; 1649 if (LZ4_dict->dictSize > 64 KB) LZ4_dict->dictSize = 64 KB; 1650 LZ4_dict->dictionary = dictEnd - LZ4_dict->dictSize; 1651 } 1652 } 1653 1654 LZ4_compress_fast_continue(LZ4_stream_t * LZ4_stream,const char * source,char * dest,int inputSize,int maxOutputSize,int acceleration)1655 int LZ4_compress_fast_continue (LZ4_stream_t* LZ4_stream, 1656 const char* source, char* dest, 1657 int inputSize, int maxOutputSize, 1658 int acceleration) 1659 { 1660 const tableType_t tableType = byU32; 1661 LZ4_stream_t_internal* const streamPtr = &LZ4_stream->internal_donotuse; 1662 const char* dictEnd = streamPtr->dictSize ? (const char*)streamPtr->dictionary + streamPtr->dictSize : NULL; 1663 1664 DEBUGLOG(5, "LZ4_compress_fast_continue (inputSize=%i, dictSize=%u)", inputSize, streamPtr->dictSize); 1665 1666 LZ4_renormDictT(streamPtr, inputSize); /* fix index overflow */ 1667 if (acceleration < 1) acceleration = LZ4_ACCELERATION_DEFAULT; 1668 if (acceleration > LZ4_ACCELERATION_MAX) acceleration = LZ4_ACCELERATION_MAX; 1669 1670 /* invalidate tiny dictionaries */ 1671 if ( (streamPtr->dictSize < 4) /* tiny dictionary : not enough for a hash */ 1672 && (dictEnd != source) /* prefix mode */ 1673 && (inputSize > 0) /* tolerance : don't lose history, in case next invocation would use prefix mode */ 1674 && (streamPtr->dictCtx == NULL) /* usingDictCtx */ 1675 ) { 1676 DEBUGLOG(5, "LZ4_compress_fast_continue: dictSize(%u) at addr:%p is too small", streamPtr->dictSize, streamPtr->dictionary); 1677 /* remove dictionary existence from history, to employ faster prefix mode */ 1678 streamPtr->dictSize = 0; 1679 streamPtr->dictionary = (const BYTE*)source; 1680 dictEnd = source; 1681 } 1682 1683 /* Check overlapping input/dictionary space */ 1684 { const char* const sourceEnd = source + inputSize; 1685 if ((sourceEnd > (const char*)streamPtr->dictionary) && (sourceEnd < dictEnd)) { 1686 streamPtr->dictSize = (U32)(dictEnd - sourceEnd); 1687 if (streamPtr->dictSize > 64 KB) streamPtr->dictSize = 64 KB; 1688 if (streamPtr->dictSize < 4) streamPtr->dictSize = 0; 1689 streamPtr->dictionary = (const BYTE*)dictEnd - streamPtr->dictSize; 1690 } 1691 } 1692 1693 /* prefix mode : source data follows dictionary */ 1694 if (dictEnd == source) { 1695 if ((streamPtr->dictSize < 64 KB) && (streamPtr->dictSize < streamPtr->currentOffset)) 1696 return LZ4_compress_generic(streamPtr, source, dest, inputSize, NULL, maxOutputSize, limitedOutput, tableType, withPrefix64k, dictSmall, acceleration); 1697 else 1698 return LZ4_compress_generic(streamPtr, source, dest, inputSize, NULL, maxOutputSize, limitedOutput, tableType, withPrefix64k, noDictIssue, acceleration); 1699 } 1700 1701 /* external dictionary mode */ 1702 { int result; 1703 if (streamPtr->dictCtx) { 1704 /* We depend here on the fact that dictCtx'es (produced by 1705 * LZ4_loadDict) guarantee that their tables contain no references 1706 * to offsets between dictCtx->currentOffset - 64 KB and 1707 * dictCtx->currentOffset - dictCtx->dictSize. This makes it safe 1708 * to use noDictIssue even when the dict isn't a full 64 KB. 1709 */ 1710 if (inputSize > 4 KB) { 1711 /* For compressing large blobs, it is faster to pay the setup 1712 * cost to copy the dictionary's tables into the active context, 1713 * so that the compression loop is only looking into one table. 1714 */ 1715 LZ4_memcpy(streamPtr, streamPtr->dictCtx, sizeof(*streamPtr)); 1716 result = LZ4_compress_generic(streamPtr, source, dest, inputSize, NULL, maxOutputSize, limitedOutput, tableType, usingExtDict, noDictIssue, acceleration); 1717 } else { 1718 result = LZ4_compress_generic(streamPtr, source, dest, inputSize, NULL, maxOutputSize, limitedOutput, tableType, usingDictCtx, noDictIssue, acceleration); 1719 } 1720 } else { /* small data <= 4 KB */ 1721 if ((streamPtr->dictSize < 64 KB) && (streamPtr->dictSize < streamPtr->currentOffset)) { 1722 result = LZ4_compress_generic(streamPtr, source, dest, inputSize, NULL, maxOutputSize, limitedOutput, tableType, usingExtDict, dictSmall, acceleration); 1723 } else { 1724 result = LZ4_compress_generic(streamPtr, source, dest, inputSize, NULL, maxOutputSize, limitedOutput, tableType, usingExtDict, noDictIssue, acceleration); 1725 } 1726 } 1727 streamPtr->dictionary = (const BYTE*)source; 1728 streamPtr->dictSize = (U32)inputSize; 1729 return result; 1730 } 1731 } 1732 1733 1734 /* Hidden debug function, to force-test external dictionary mode */ LZ4_compress_forceExtDict(LZ4_stream_t * LZ4_dict,const char * source,char * dest,int srcSize)1735 int LZ4_compress_forceExtDict (LZ4_stream_t* LZ4_dict, const char* source, char* dest, int srcSize) 1736 { 1737 LZ4_stream_t_internal* const streamPtr = &LZ4_dict->internal_donotuse; 1738 int result; 1739 1740 LZ4_renormDictT(streamPtr, srcSize); 1741 1742 if ((streamPtr->dictSize < 64 KB) && (streamPtr->dictSize < streamPtr->currentOffset)) { 1743 result = LZ4_compress_generic(streamPtr, source, dest, srcSize, NULL, 0, notLimited, byU32, usingExtDict, dictSmall, 1); 1744 } else { 1745 result = LZ4_compress_generic(streamPtr, source, dest, srcSize, NULL, 0, notLimited, byU32, usingExtDict, noDictIssue, 1); 1746 } 1747 1748 streamPtr->dictionary = (const BYTE*)source; 1749 streamPtr->dictSize = (U32)srcSize; 1750 1751 return result; 1752 } 1753 1754 1755 /*! LZ4_saveDict() : 1756 * If previously compressed data block is not guaranteed to remain available at its memory location, 1757 * save it into a safer place (char* safeBuffer). 1758 * Note : no need to call LZ4_loadDict() afterwards, dictionary is immediately usable, 1759 * one can therefore call LZ4_compress_fast_continue() right after. 1760 * @return : saved dictionary size in bytes (necessarily <= dictSize), or 0 if error. 1761 */ LZ4_saveDict(LZ4_stream_t * LZ4_dict,char * safeBuffer,int dictSize)1762 int LZ4_saveDict (LZ4_stream_t* LZ4_dict, char* safeBuffer, int dictSize) 1763 { 1764 LZ4_stream_t_internal* const dict = &LZ4_dict->internal_donotuse; 1765 1766 DEBUGLOG(5, "LZ4_saveDict : dictSize=%i, safeBuffer=%p", dictSize, safeBuffer); 1767 1768 if ((U32)dictSize > 64 KB) { dictSize = 64 KB; } /* useless to define a dictionary > 64 KB */ 1769 if ((U32)dictSize > dict->dictSize) { dictSize = (int)dict->dictSize; } 1770 1771 if (safeBuffer == NULL) assert(dictSize == 0); 1772 if (dictSize > 0) { 1773 const BYTE* const previousDictEnd = dict->dictionary + dict->dictSize; 1774 assert(dict->dictionary); 1775 LZ4_memmove(safeBuffer, previousDictEnd - dictSize, (size_t)dictSize); 1776 } 1777 1778 dict->dictionary = (const BYTE*)safeBuffer; 1779 dict->dictSize = (U32)dictSize; 1780 1781 return dictSize; 1782 } 1783 1784 1785 1786 /*-******************************* 1787 * Decompression functions 1788 ********************************/ 1789 1790 typedef enum { decode_full_block = 0, partial_decode = 1 } earlyEnd_directive; 1791 1792 #undef MIN 1793 #define MIN(a,b) ( (a) < (b) ? (a) : (b) ) 1794 1795 1796 /* variant for decompress_unsafe() 1797 * does not know end of input 1798 * presumes input is well formed 1799 * note : will consume at least one byte */ read_long_length_no_check(const BYTE ** pp)1800 static size_t read_long_length_no_check(const BYTE** pp) 1801 { 1802 size_t b, l = 0; 1803 do { b = **pp; (*pp)++; l += b; } while (b==255); 1804 DEBUGLOG(6, "read_long_length_no_check: +length=%zu using %zu input bytes", l, l/255 + 1) 1805 return l; 1806 } 1807 1808 /* core decoder variant for LZ4_decompress_fast*() 1809 * for legacy support only : these entry points are deprecated. 1810 * - Presumes input is correctly formed (no defense vs malformed inputs) 1811 * - Does not know input size (presume input buffer is "large enough") 1812 * - Decompress a full block (only) 1813 * @return : nb of bytes read from input. 1814 * Note : this variant is not optimized for speed, just for maintenance. 1815 * the goal is to remove support of decompress_fast*() variants by v2.0 1816 **/ 1817 LZ4_FORCE_INLINE int LZ4_decompress_unsafe_generic(const BYTE * const istart,BYTE * const ostart,int decompressedSize,size_t prefixSize,const BYTE * const dictStart,const size_t dictSize)1818 LZ4_decompress_unsafe_generic( 1819 const BYTE* const istart, 1820 BYTE* const ostart, 1821 int decompressedSize, 1822 1823 size_t prefixSize, 1824 const BYTE* const dictStart, /* only if dict==usingExtDict */ 1825 const size_t dictSize /* note: =0 if dictStart==NULL */ 1826 ) 1827 { 1828 const BYTE* ip = istart; 1829 BYTE* op = (BYTE*)ostart; 1830 BYTE* const oend = ostart + decompressedSize; 1831 const BYTE* const prefixStart = ostart - prefixSize; 1832 1833 DEBUGLOG(5, "LZ4_decompress_unsafe_generic"); 1834 if (dictStart == NULL) assert(dictSize == 0); 1835 1836 while (1) { 1837 /* start new sequence */ 1838 unsigned token = *ip++; 1839 1840 /* literals */ 1841 { size_t ll = token >> ML_BITS; 1842 if (ll==15) { 1843 /* long literal length */ 1844 ll += read_long_length_no_check(&ip); 1845 } 1846 if ((size_t)(oend-op) < ll) return -1; /* output buffer overflow */ 1847 LZ4_memmove(op, ip, ll); /* support in-place decompression */ 1848 op += ll; 1849 ip += ll; 1850 if ((size_t)(oend-op) < MFLIMIT) { 1851 if (op==oend) break; /* end of block */ 1852 DEBUGLOG(5, "invalid: literals end at distance %zi from end of block", oend-op); 1853 /* incorrect end of block : 1854 * last match must start at least MFLIMIT==12 bytes before end of output block */ 1855 return -1; 1856 } } 1857 1858 /* match */ 1859 { size_t ml = token & 15; 1860 size_t const offset = LZ4_readLE16(ip); 1861 ip+=2; 1862 1863 if (ml==15) { 1864 /* long literal length */ 1865 ml += read_long_length_no_check(&ip); 1866 } 1867 ml += MINMATCH; 1868 1869 if ((size_t)(oend-op) < ml) return -1; /* output buffer overflow */ 1870 1871 { const BYTE* match = op - offset; 1872 1873 /* out of range */ 1874 if (offset > (size_t)(op - prefixStart) + dictSize) { 1875 DEBUGLOG(6, "offset out of range"); 1876 return -1; 1877 } 1878 1879 /* check special case : extDict */ 1880 if (offset > (size_t)(op - prefixStart)) { 1881 /* extDict scenario */ 1882 const BYTE* const dictEnd = dictStart + dictSize; 1883 const BYTE* extMatch = dictEnd - (offset - (size_t)(op-prefixStart)); 1884 size_t const extml = (size_t)(dictEnd - extMatch); 1885 if (extml > ml) { 1886 /* match entirely within extDict */ 1887 LZ4_memmove(op, extMatch, ml); 1888 op += ml; 1889 ml = 0; 1890 } else { 1891 /* match split between extDict & prefix */ 1892 LZ4_memmove(op, extMatch, extml); 1893 op += extml; 1894 ml -= extml; 1895 } 1896 match = prefixStart; 1897 } 1898 1899 /* match copy - slow variant, supporting overlap copy */ 1900 { size_t u; 1901 for (u=0; u<ml; u++) { 1902 op[u] = match[u]; 1903 } } } 1904 op += ml; 1905 if ((size_t)(oend-op) < LASTLITERALS) { 1906 DEBUGLOG(5, "invalid: match ends at distance %zi from end of block", oend-op); 1907 /* incorrect end of block : 1908 * last match must stop at least LASTLITERALS==5 bytes before end of output block */ 1909 return -1; 1910 } 1911 } /* match */ 1912 } /* main loop */ 1913 return (int)(ip - istart); 1914 } 1915 1916 1917 /* Read the variable-length literal or match length. 1918 * 1919 * @ip : input pointer 1920 * @ilimit : position after which if length is not decoded, the input is necessarily corrupted. 1921 * @initial_check - check ip >= ipmax before start of loop. Returns initial_error if so. 1922 * @error (output) - error code. Must be set to 0 before call. 1923 **/ 1924 typedef size_t Rvl_t; 1925 static const Rvl_t rvl_error = (Rvl_t)(-1); 1926 LZ4_FORCE_INLINE Rvl_t read_variable_length(const BYTE ** ip,const BYTE * ilimit,int initial_check)1927 read_variable_length(const BYTE** ip, const BYTE* ilimit, 1928 int initial_check) 1929 { 1930 Rvl_t s, length = 0; 1931 assert(ip != NULL); 1932 assert(*ip != NULL); 1933 assert(ilimit != NULL); 1934 if (initial_check && unlikely((*ip) >= ilimit)) { /* read limit reached */ 1935 return rvl_error; 1936 } 1937 do { 1938 s = **ip; 1939 (*ip)++; 1940 length += s; 1941 if (unlikely((*ip) > ilimit)) { /* read limit reached */ 1942 return rvl_error; 1943 } 1944 /* accumulator overflow detection (32-bit mode only) */ 1945 if ((sizeof(length)<8) && unlikely(length > ((Rvl_t)(-1)/2)) ) { 1946 return rvl_error; 1947 } 1948 } while (s==255); 1949 1950 return length; 1951 } 1952 1953 /*! LZ4_decompress_generic() : 1954 * This generic decompression function covers all use cases. 1955 * It shall be instantiated several times, using different sets of directives. 1956 * Note that it is important for performance that this function really get inlined, 1957 * in order to remove useless branches during compilation optimization. 1958 */ 1959 LZ4_FORCE_INLINE int LZ4_decompress_generic(const char * const src,char * const dst,int srcSize,int outputSize,earlyEnd_directive partialDecoding,dict_directive dict,const BYTE * const lowPrefix,const BYTE * const dictStart,const size_t dictSize)1960 LZ4_decompress_generic( 1961 const char* const src, 1962 char* const dst, 1963 int srcSize, 1964 int outputSize, /* If endOnInput==endOnInputSize, this value is `dstCapacity` */ 1965 1966 earlyEnd_directive partialDecoding, /* full, partial */ 1967 dict_directive dict, /* noDict, withPrefix64k, usingExtDict */ 1968 const BYTE* const lowPrefix, /* always <= dst, == dst when no prefix */ 1969 const BYTE* const dictStart, /* only if dict==usingExtDict */ 1970 const size_t dictSize /* note : = 0 if noDict */ 1971 ) 1972 { 1973 if ((src == NULL) || (outputSize < 0)) { return -1; } 1974 1975 { const BYTE* ip = (const BYTE*) src; 1976 const BYTE* const iend = ip + srcSize; 1977 1978 BYTE* op = (BYTE*) dst; 1979 BYTE* const oend = op + outputSize; 1980 BYTE* cpy; 1981 1982 const BYTE* const dictEnd = (dictStart == NULL) ? NULL : dictStart + dictSize; 1983 1984 const int checkOffset = (dictSize < (int)(64 KB)); 1985 1986 1987 /* Set up the "end" pointers for the shortcut. */ 1988 const BYTE* const shortiend = iend - 14 /*maxLL*/ - 2 /*offset*/; 1989 const BYTE* const shortoend = oend - 14 /*maxLL*/ - 18 /*maxML*/; 1990 1991 const BYTE* match; 1992 size_t offset; 1993 unsigned token; 1994 size_t length; 1995 1996 1997 DEBUGLOG(5, "LZ4_decompress_generic (srcSize:%i, dstSize:%i)", srcSize, outputSize); 1998 1999 /* Special cases */ 2000 assert(lowPrefix <= op); 2001 if (unlikely(outputSize==0)) { 2002 /* Empty output buffer */ 2003 if (partialDecoding) return 0; 2004 return ((srcSize==1) && (*ip==0)) ? 0 : -1; 2005 } 2006 if (unlikely(srcSize==0)) { return -1; } 2007 2008 /* LZ4_FAST_DEC_LOOP: 2009 * designed for modern OoO performance cpus, 2010 * where copying reliably 32-bytes is preferable to an unpredictable branch. 2011 * note : fast loop may show a regression for some client arm chips. */ 2012 #if LZ4_FAST_DEC_LOOP 2013 if ((oend - op) < FASTLOOP_SAFE_DISTANCE) { 2014 DEBUGLOG(6, "skip fast decode loop"); 2015 goto safe_decode; 2016 } 2017 2018 /* Fast loop : decode sequences as long as output < oend-FASTLOOP_SAFE_DISTANCE */ 2019 DEBUGLOG(6, "using fast decode loop"); 2020 while (1) { 2021 /* Main fastloop assertion: We can always wildcopy FASTLOOP_SAFE_DISTANCE */ 2022 assert(oend - op >= FASTLOOP_SAFE_DISTANCE); 2023 assert(ip < iend); 2024 token = *ip++; 2025 length = token >> ML_BITS; /* literal length */ 2026 2027 /* decode literal length */ 2028 if (length == RUN_MASK) { 2029 size_t const addl = read_variable_length(&ip, iend-RUN_MASK, 1); 2030 if (addl == rvl_error) { 2031 DEBUGLOG(6, "error reading long literal length"); 2032 goto _output_error; 2033 } 2034 length += addl; 2035 if (unlikely((uptrval)(op)+length<(uptrval)(op))) { goto _output_error; } /* overflow detection */ 2036 if (unlikely((uptrval)(ip)+length<(uptrval)(ip))) { goto _output_error; } /* overflow detection */ 2037 2038 /* copy literals */ 2039 LZ4_STATIC_ASSERT(MFLIMIT >= WILDCOPYLENGTH); 2040 if ((op+length>oend-32) || (ip+length>iend-32)) { goto safe_literal_copy; } 2041 LZ4_wildCopy32(op, ip, op+length); 2042 ip += length; op += length; 2043 } else if (ip <= iend-(16 + 1/*max lit + offset + nextToken*/)) { 2044 /* We don't need to check oend, since we check it once for each loop below */ 2045 DEBUGLOG(7, "copy %u bytes in a 16-bytes stripe", (unsigned)length); 2046 /* Literals can only be <= 14, but hope compilers optimize better when copy by a register size */ 2047 LZ4_memcpy(op, ip, 16); 2048 ip += length; op += length; 2049 } else { 2050 goto safe_literal_copy; 2051 } 2052 2053 /* get offset */ 2054 offset = LZ4_readLE16(ip); ip+=2; 2055 DEBUGLOG(6, " offset = %zu", offset); 2056 match = op - offset; 2057 assert(match <= op); /* overflow check */ 2058 2059 /* get matchlength */ 2060 length = token & ML_MASK; 2061 2062 if (length == ML_MASK) { 2063 size_t const addl = read_variable_length(&ip, iend - LASTLITERALS + 1, 0); 2064 if (addl == rvl_error) { 2065 DEBUGLOG(6, "error reading long match length"); 2066 goto _output_error; 2067 } 2068 length += addl; 2069 length += MINMATCH; 2070 if (unlikely((uptrval)(op)+length<(uptrval)op)) { goto _output_error; } /* overflow detection */ 2071 if (op + length >= oend - FASTLOOP_SAFE_DISTANCE) { 2072 goto safe_match_copy; 2073 } 2074 } else { 2075 length += MINMATCH; 2076 if (op + length >= oend - FASTLOOP_SAFE_DISTANCE) { 2077 goto safe_match_copy; 2078 } 2079 2080 /* Fastpath check: skip LZ4_wildCopy32 when true */ 2081 if ((dict == withPrefix64k) || (match >= lowPrefix)) { 2082 if (offset >= 8) { 2083 assert(match >= lowPrefix); 2084 assert(match <= op); 2085 assert(op + 18 <= oend); 2086 2087 LZ4_memcpy(op, match, 8); 2088 LZ4_memcpy(op+8, match+8, 8); 2089 LZ4_memcpy(op+16, match+16, 2); 2090 op += length; 2091 continue; 2092 } } } 2093 2094 if ( checkOffset && (unlikely(match + dictSize < lowPrefix)) ) { 2095 DEBUGLOG(6, "Error : pos=%zi, offset=%zi => outside buffers", op-lowPrefix, op-match); 2096 goto _output_error; 2097 } 2098 /* match starting within external dictionary */ 2099 if ((dict==usingExtDict) && (match < lowPrefix)) { 2100 assert(dictEnd != NULL); 2101 if (unlikely(op+length > oend-LASTLITERALS)) { 2102 if (partialDecoding) { 2103 DEBUGLOG(7, "partialDecoding: dictionary match, close to dstEnd"); 2104 length = MIN(length, (size_t)(oend-op)); 2105 } else { 2106 DEBUGLOG(6, "end-of-block condition violated") 2107 goto _output_error; 2108 } } 2109 2110 if (length <= (size_t)(lowPrefix-match)) { 2111 /* match fits entirely within external dictionary : just copy */ 2112 LZ4_memmove(op, dictEnd - (lowPrefix-match), length); 2113 op += length; 2114 } else { 2115 /* match stretches into both external dictionary and current block */ 2116 size_t const copySize = (size_t)(lowPrefix - match); 2117 size_t const restSize = length - copySize; 2118 LZ4_memcpy(op, dictEnd - copySize, copySize); 2119 op += copySize; 2120 if (restSize > (size_t)(op - lowPrefix)) { /* overlap copy */ 2121 BYTE* const endOfMatch = op + restSize; 2122 const BYTE* copyFrom = lowPrefix; 2123 while (op < endOfMatch) { *op++ = *copyFrom++; } 2124 } else { 2125 LZ4_memcpy(op, lowPrefix, restSize); 2126 op += restSize; 2127 } } 2128 continue; 2129 } 2130 2131 /* copy match within block */ 2132 cpy = op + length; 2133 2134 assert((op <= oend) && (oend-op >= 32)); 2135 if (unlikely(offset<16)) { 2136 LZ4_memcpy_using_offset(op, match, cpy, offset); 2137 } else { 2138 LZ4_wildCopy32(op, match, cpy); 2139 } 2140 2141 op = cpy; /* wildcopy correction */ 2142 } 2143 safe_decode: 2144 #endif 2145 2146 /* Main Loop : decode remaining sequences where output < FASTLOOP_SAFE_DISTANCE */ 2147 DEBUGLOG(6, "using safe decode loop"); 2148 while (1) { 2149 assert(ip < iend); 2150 token = *ip++; 2151 length = token >> ML_BITS; /* literal length */ 2152 2153 /* A two-stage shortcut for the most common case: 2154 * 1) If the literal length is 0..14, and there is enough space, 2155 * enter the shortcut and copy 16 bytes on behalf of the literals 2156 * (in the fast mode, only 8 bytes can be safely copied this way). 2157 * 2) Further if the match length is 4..18, copy 18 bytes in a similar 2158 * manner; but we ensure that there's enough space in the output for 2159 * those 18 bytes earlier, upon entering the shortcut (in other words, 2160 * there is a combined check for both stages). 2161 */ 2162 if ( (length != RUN_MASK) 2163 /* strictly "less than" on input, to re-enter the loop with at least one byte */ 2164 && likely((ip < shortiend) & (op <= shortoend)) ) { 2165 /* Copy the literals */ 2166 LZ4_memcpy(op, ip, 16); 2167 op += length; ip += length; 2168 2169 /* The second stage: prepare for match copying, decode full info. 2170 * If it doesn't work out, the info won't be wasted. */ 2171 length = token & ML_MASK; /* match length */ 2172 offset = LZ4_readLE16(ip); ip += 2; 2173 match = op - offset; 2174 assert(match <= op); /* check overflow */ 2175 2176 /* Do not deal with overlapping matches. */ 2177 if ( (length != ML_MASK) 2178 && (offset >= 8) 2179 && (dict==withPrefix64k || match >= lowPrefix) ) { 2180 /* Copy the match. */ 2181 LZ4_memcpy(op + 0, match + 0, 8); 2182 LZ4_memcpy(op + 8, match + 8, 8); 2183 LZ4_memcpy(op +16, match +16, 2); 2184 op += length + MINMATCH; 2185 /* Both stages worked, load the next token. */ 2186 continue; 2187 } 2188 2189 /* The second stage didn't work out, but the info is ready. 2190 * Propel it right to the point of match copying. */ 2191 goto _copy_match; 2192 } 2193 2194 /* decode literal length */ 2195 if (length == RUN_MASK) { 2196 size_t const addl = read_variable_length(&ip, iend-RUN_MASK, 1); 2197 if (addl == rvl_error) { goto _output_error; } 2198 length += addl; 2199 if (unlikely((uptrval)(op)+length<(uptrval)(op))) { goto _output_error; } /* overflow detection */ 2200 if (unlikely((uptrval)(ip)+length<(uptrval)(ip))) { goto _output_error; } /* overflow detection */ 2201 } 2202 2203 #if LZ4_FAST_DEC_LOOP 2204 safe_literal_copy: 2205 #endif 2206 /* copy literals */ 2207 cpy = op+length; 2208 2209 LZ4_STATIC_ASSERT(MFLIMIT >= WILDCOPYLENGTH); 2210 if ((cpy>oend-MFLIMIT) || (ip+length>iend-(2+1+LASTLITERALS))) { 2211 /* We've either hit the input parsing restriction or the output parsing restriction. 2212 * In the normal scenario, decoding a full block, it must be the last sequence, 2213 * otherwise it's an error (invalid input or dimensions). 2214 * In partialDecoding scenario, it's necessary to ensure there is no buffer overflow. 2215 */ 2216 if (partialDecoding) { 2217 /* Since we are partial decoding we may be in this block because of the output parsing 2218 * restriction, which is not valid since the output buffer is allowed to be undersized. 2219 */ 2220 DEBUGLOG(7, "partialDecoding: copying literals, close to input or output end") 2221 DEBUGLOG(7, "partialDecoding: literal length = %u", (unsigned)length); 2222 DEBUGLOG(7, "partialDecoding: remaining space in dstBuffer : %i", (int)(oend - op)); 2223 DEBUGLOG(7, "partialDecoding: remaining space in srcBuffer : %i", (int)(iend - ip)); 2224 /* Finishing in the middle of a literals segment, 2225 * due to lack of input. 2226 */ 2227 if (ip+length > iend) { 2228 length = (size_t)(iend-ip); 2229 cpy = op + length; 2230 } 2231 /* Finishing in the middle of a literals segment, 2232 * due to lack of output space. 2233 */ 2234 if (cpy > oend) { 2235 cpy = oend; 2236 assert(op<=oend); 2237 length = (size_t)(oend-op); 2238 } 2239 } else { 2240 /* We must be on the last sequence (or invalid) because of the parsing limitations 2241 * so check that we exactly consume the input and don't overrun the output buffer. 2242 */ 2243 if ((ip+length != iend) || (cpy > oend)) { 2244 DEBUGLOG(6, "should have been last run of literals") 2245 DEBUGLOG(6, "ip(%p) + length(%i) = %p != iend (%p)", ip, (int)length, ip+length, iend); 2246 DEBUGLOG(6, "or cpy(%p) > oend(%p)", cpy, oend); 2247 goto _output_error; 2248 } 2249 } 2250 LZ4_memmove(op, ip, length); /* supports overlapping memory regions, for in-place decompression scenarios */ 2251 ip += length; 2252 op += length; 2253 /* Necessarily EOF when !partialDecoding. 2254 * When partialDecoding, it is EOF if we've either 2255 * filled the output buffer or 2256 * can't proceed with reading an offset for following match. 2257 */ 2258 if (!partialDecoding || (cpy == oend) || (ip >= (iend-2))) { 2259 break; 2260 } 2261 } else { 2262 LZ4_wildCopy8(op, ip, cpy); /* can overwrite up to 8 bytes beyond cpy */ 2263 ip += length; op = cpy; 2264 } 2265 2266 /* get offset */ 2267 offset = LZ4_readLE16(ip); ip+=2; 2268 match = op - offset; 2269 2270 /* get matchlength */ 2271 length = token & ML_MASK; 2272 2273 _copy_match: 2274 if (length == ML_MASK) { 2275 size_t const addl = read_variable_length(&ip, iend - LASTLITERALS + 1, 0); 2276 if (addl == rvl_error) { goto _output_error; } 2277 length += addl; 2278 if (unlikely((uptrval)(op)+length<(uptrval)op)) goto _output_error; /* overflow detection */ 2279 } 2280 length += MINMATCH; 2281 2282 #if LZ4_FAST_DEC_LOOP 2283 safe_match_copy: 2284 #endif 2285 if ((checkOffset) && (unlikely(match + dictSize < lowPrefix))) goto _output_error; /* Error : offset outside buffers */ 2286 /* match starting within external dictionary */ 2287 if ((dict==usingExtDict) && (match < lowPrefix)) { 2288 assert(dictEnd != NULL); 2289 if (unlikely(op+length > oend-LASTLITERALS)) { 2290 if (partialDecoding) length = MIN(length, (size_t)(oend-op)); 2291 else goto _output_error; /* doesn't respect parsing restriction */ 2292 } 2293 2294 if (length <= (size_t)(lowPrefix-match)) { 2295 /* match fits entirely within external dictionary : just copy */ 2296 LZ4_memmove(op, dictEnd - (lowPrefix-match), length); 2297 op += length; 2298 } else { 2299 /* match stretches into both external dictionary and current block */ 2300 size_t const copySize = (size_t)(lowPrefix - match); 2301 size_t const restSize = length - copySize; 2302 LZ4_memcpy(op, dictEnd - copySize, copySize); 2303 op += copySize; 2304 if (restSize > (size_t)(op - lowPrefix)) { /* overlap copy */ 2305 BYTE* const endOfMatch = op + restSize; 2306 const BYTE* copyFrom = lowPrefix; 2307 while (op < endOfMatch) *op++ = *copyFrom++; 2308 } else { 2309 LZ4_memcpy(op, lowPrefix, restSize); 2310 op += restSize; 2311 } } 2312 continue; 2313 } 2314 assert(match >= lowPrefix); 2315 2316 /* copy match within block */ 2317 cpy = op + length; 2318 2319 /* partialDecoding : may end anywhere within the block */ 2320 assert(op<=oend); 2321 if (partialDecoding && (cpy > oend-MATCH_SAFEGUARD_DISTANCE)) { 2322 size_t const mlen = MIN(length, (size_t)(oend-op)); 2323 const BYTE* const matchEnd = match + mlen; 2324 BYTE* const copyEnd = op + mlen; 2325 if (matchEnd > op) { /* overlap copy */ 2326 while (op < copyEnd) { *op++ = *match++; } 2327 } else { 2328 LZ4_memcpy(op, match, mlen); 2329 } 2330 op = copyEnd; 2331 if (op == oend) { break; } 2332 continue; 2333 } 2334 2335 if (unlikely(offset<8)) { 2336 LZ4_write32(op, 0); /* silence msan warning when offset==0 */ 2337 op[0] = match[0]; 2338 op[1] = match[1]; 2339 op[2] = match[2]; 2340 op[3] = match[3]; 2341 match += inc32table[offset]; 2342 LZ4_memcpy(op+4, match, 4); 2343 match -= dec64table[offset]; 2344 } else { 2345 LZ4_memcpy(op, match, 8); 2346 match += 8; 2347 } 2348 op += 8; 2349 2350 if (unlikely(cpy > oend-MATCH_SAFEGUARD_DISTANCE)) { 2351 BYTE* const oCopyLimit = oend - (WILDCOPYLENGTH-1); 2352 if (cpy > oend-LASTLITERALS) { goto _output_error; } /* Error : last LASTLITERALS bytes must be literals (uncompressed) */ 2353 if (op < oCopyLimit) { 2354 LZ4_wildCopy8(op, match, oCopyLimit); 2355 match += oCopyLimit - op; 2356 op = oCopyLimit; 2357 } 2358 while (op < cpy) { *op++ = *match++; } 2359 } else { 2360 LZ4_memcpy(op, match, 8); 2361 if (length > 16) { LZ4_wildCopy8(op+8, match+8, cpy); } 2362 } 2363 op = cpy; /* wildcopy correction */ 2364 } 2365 2366 /* end of decoding */ 2367 DEBUGLOG(5, "decoded %i bytes", (int) (((char*)op)-dst)); 2368 return (int) (((char*)op)-dst); /* Nb of output bytes decoded */ 2369 2370 /* Overflow error detected */ 2371 _output_error: 2372 return (int) (-(((const char*)ip)-src))-1; 2373 } 2374 } 2375 2376 2377 /*===== Instantiate the API decoding functions. =====*/ 2378 2379 LZ4_FORCE_O2 LZ4_decompress_safe(const char * source,char * dest,int compressedSize,int maxDecompressedSize)2380 int LZ4_decompress_safe(const char* source, char* dest, int compressedSize, int maxDecompressedSize) 2381 { 2382 return LZ4_decompress_generic(source, dest, compressedSize, maxDecompressedSize, 2383 decode_full_block, noDict, 2384 (BYTE*)dest, NULL, 0); 2385 } 2386 2387 LZ4_FORCE_O2 LZ4_decompress_safe_partial(const char * src,char * dst,int compressedSize,int targetOutputSize,int dstCapacity)2388 int LZ4_decompress_safe_partial(const char* src, char* dst, int compressedSize, int targetOutputSize, int dstCapacity) 2389 { 2390 dstCapacity = MIN(targetOutputSize, dstCapacity); 2391 return LZ4_decompress_generic(src, dst, compressedSize, dstCapacity, 2392 partial_decode, 2393 noDict, (BYTE*)dst, NULL, 0); 2394 } 2395 2396 LZ4_FORCE_O2 LZ4_decompress_fast(const char * source,char * dest,int originalSize)2397 int LZ4_decompress_fast(const char* source, char* dest, int originalSize) 2398 { 2399 DEBUGLOG(5, "LZ4_decompress_fast"); 2400 return LZ4_decompress_unsafe_generic( 2401 (const BYTE*)source, (BYTE*)dest, originalSize, 2402 0, NULL, 0); 2403 } 2404 2405 /*===== Instantiate a few more decoding cases, used more than once. =====*/ 2406 2407 LZ4_FORCE_O2 /* Exported, an obsolete API function. */ LZ4_decompress_safe_withPrefix64k(const char * source,char * dest,int compressedSize,int maxOutputSize)2408 int LZ4_decompress_safe_withPrefix64k(const char* source, char* dest, int compressedSize, int maxOutputSize) 2409 { 2410 return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, 2411 decode_full_block, withPrefix64k, 2412 (BYTE*)dest - 64 KB, NULL, 0); 2413 } 2414 2415 LZ4_FORCE_O2 LZ4_decompress_safe_partial_withPrefix64k(const char * source,char * dest,int compressedSize,int targetOutputSize,int dstCapacity)2416 static int LZ4_decompress_safe_partial_withPrefix64k(const char* source, char* dest, int compressedSize, int targetOutputSize, int dstCapacity) 2417 { 2418 dstCapacity = MIN(targetOutputSize, dstCapacity); 2419 return LZ4_decompress_generic(source, dest, compressedSize, dstCapacity, 2420 partial_decode, withPrefix64k, 2421 (BYTE*)dest - 64 KB, NULL, 0); 2422 } 2423 2424 /* Another obsolete API function, paired with the previous one. */ LZ4_decompress_fast_withPrefix64k(const char * source,char * dest,int originalSize)2425 int LZ4_decompress_fast_withPrefix64k(const char* source, char* dest, int originalSize) 2426 { 2427 return LZ4_decompress_unsafe_generic( 2428 (const BYTE*)source, (BYTE*)dest, originalSize, 2429 64 KB, NULL, 0); 2430 } 2431 2432 LZ4_FORCE_O2 LZ4_decompress_safe_withSmallPrefix(const char * source,char * dest,int compressedSize,int maxOutputSize,size_t prefixSize)2433 static int LZ4_decompress_safe_withSmallPrefix(const char* source, char* dest, int compressedSize, int maxOutputSize, 2434 size_t prefixSize) 2435 { 2436 return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, 2437 decode_full_block, noDict, 2438 (BYTE*)dest-prefixSize, NULL, 0); 2439 } 2440 2441 LZ4_FORCE_O2 LZ4_decompress_safe_partial_withSmallPrefix(const char * source,char * dest,int compressedSize,int targetOutputSize,int dstCapacity,size_t prefixSize)2442 static int LZ4_decompress_safe_partial_withSmallPrefix(const char* source, char* dest, int compressedSize, int targetOutputSize, int dstCapacity, 2443 size_t prefixSize) 2444 { 2445 dstCapacity = MIN(targetOutputSize, dstCapacity); 2446 return LZ4_decompress_generic(source, dest, compressedSize, dstCapacity, 2447 partial_decode, noDict, 2448 (BYTE*)dest-prefixSize, NULL, 0); 2449 } 2450 2451 LZ4_FORCE_O2 LZ4_decompress_safe_forceExtDict(const char * source,char * dest,int compressedSize,int maxOutputSize,const void * dictStart,size_t dictSize)2452 int LZ4_decompress_safe_forceExtDict(const char* source, char* dest, 2453 int compressedSize, int maxOutputSize, 2454 const void* dictStart, size_t dictSize) 2455 { 2456 DEBUGLOG(5, "LZ4_decompress_safe_forceExtDict"); 2457 return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, 2458 decode_full_block, usingExtDict, 2459 (BYTE*)dest, (const BYTE*)dictStart, dictSize); 2460 } 2461 2462 LZ4_FORCE_O2 LZ4_decompress_safe_partial_forceExtDict(const char * source,char * dest,int compressedSize,int targetOutputSize,int dstCapacity,const void * dictStart,size_t dictSize)2463 int LZ4_decompress_safe_partial_forceExtDict(const char* source, char* dest, 2464 int compressedSize, int targetOutputSize, int dstCapacity, 2465 const void* dictStart, size_t dictSize) 2466 { 2467 dstCapacity = MIN(targetOutputSize, dstCapacity); 2468 return LZ4_decompress_generic(source, dest, compressedSize, dstCapacity, 2469 partial_decode, usingExtDict, 2470 (BYTE*)dest, (const BYTE*)dictStart, dictSize); 2471 } 2472 2473 LZ4_FORCE_O2 LZ4_decompress_fast_extDict(const char * source,char * dest,int originalSize,const void * dictStart,size_t dictSize)2474 static int LZ4_decompress_fast_extDict(const char* source, char* dest, int originalSize, 2475 const void* dictStart, size_t dictSize) 2476 { 2477 return LZ4_decompress_unsafe_generic( 2478 (const BYTE*)source, (BYTE*)dest, originalSize, 2479 0, (const BYTE*)dictStart, dictSize); 2480 } 2481 2482 /* The "double dictionary" mode, for use with e.g. ring buffers: the first part 2483 * of the dictionary is passed as prefix, and the second via dictStart + dictSize. 2484 * These routines are used only once, in LZ4_decompress_*_continue(). 2485 */ 2486 LZ4_FORCE_INLINE LZ4_decompress_safe_doubleDict(const char * source,char * dest,int compressedSize,int maxOutputSize,size_t prefixSize,const void * dictStart,size_t dictSize)2487 int LZ4_decompress_safe_doubleDict(const char* source, char* dest, int compressedSize, int maxOutputSize, 2488 size_t prefixSize, const void* dictStart, size_t dictSize) 2489 { 2490 return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, 2491 decode_full_block, usingExtDict, 2492 (BYTE*)dest-prefixSize, (const BYTE*)dictStart, dictSize); 2493 } 2494 2495 /*===== streaming decompression functions =====*/ 2496 2497 #if !defined(LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION) LZ4_createStreamDecode(void)2498 LZ4_streamDecode_t* LZ4_createStreamDecode(void) 2499 { 2500 LZ4_STATIC_ASSERT(sizeof(LZ4_streamDecode_t) >= sizeof(LZ4_streamDecode_t_internal)); 2501 return (LZ4_streamDecode_t*) ALLOC_AND_ZERO(sizeof(LZ4_streamDecode_t)); 2502 } 2503 LZ4_freeStreamDecode(LZ4_streamDecode_t * LZ4_stream)2504 int LZ4_freeStreamDecode (LZ4_streamDecode_t* LZ4_stream) 2505 { 2506 if (LZ4_stream == NULL) { return 0; } /* support free on NULL */ 2507 FREEMEM(LZ4_stream); 2508 return 0; 2509 } 2510 #endif 2511 2512 /*! LZ4_setStreamDecode() : 2513 * Use this function to instruct where to find the dictionary. 2514 * This function is not necessary if previous data is still available where it was decoded. 2515 * Loading a size of 0 is allowed (same effect as no dictionary). 2516 * @return : 1 if OK, 0 if error 2517 */ LZ4_setStreamDecode(LZ4_streamDecode_t * LZ4_streamDecode,const char * dictionary,int dictSize)2518 int LZ4_setStreamDecode (LZ4_streamDecode_t* LZ4_streamDecode, const char* dictionary, int dictSize) 2519 { 2520 LZ4_streamDecode_t_internal* lz4sd = &LZ4_streamDecode->internal_donotuse; 2521 lz4sd->prefixSize = (size_t)dictSize; 2522 if (dictSize) { 2523 assert(dictionary != NULL); 2524 lz4sd->prefixEnd = (const BYTE*) dictionary + dictSize; 2525 } else { 2526 lz4sd->prefixEnd = (const BYTE*) dictionary; 2527 } 2528 lz4sd->externalDict = NULL; 2529 lz4sd->extDictSize = 0; 2530 return 1; 2531 } 2532 2533 /*! LZ4_decoderRingBufferSize() : 2534 * when setting a ring buffer for streaming decompression (optional scenario), 2535 * provides the minimum size of this ring buffer 2536 * to be compatible with any source respecting maxBlockSize condition. 2537 * Note : in a ring buffer scenario, 2538 * blocks are presumed decompressed next to each other. 2539 * When not enough space remains for next block (remainingSize < maxBlockSize), 2540 * decoding resumes from beginning of ring buffer. 2541 * @return : minimum ring buffer size, 2542 * or 0 if there is an error (invalid maxBlockSize). 2543 */ LZ4_decoderRingBufferSize(int maxBlockSize)2544 int LZ4_decoderRingBufferSize(int maxBlockSize) 2545 { 2546 if (maxBlockSize < 0) return 0; 2547 if (maxBlockSize > LZ4_MAX_INPUT_SIZE) return 0; 2548 if (maxBlockSize < 16) maxBlockSize = 16; 2549 return LZ4_DECODER_RING_BUFFER_SIZE(maxBlockSize); 2550 } 2551 2552 /* 2553 *_continue() : 2554 These decoding functions allow decompression of multiple blocks in "streaming" mode. 2555 Previously decoded blocks must still be available at the memory position where they were decoded. 2556 If it's not possible, save the relevant part of decoded data into a safe buffer, 2557 and indicate where it stands using LZ4_setStreamDecode() 2558 */ 2559 LZ4_FORCE_O2 LZ4_decompress_safe_continue(LZ4_streamDecode_t * LZ4_streamDecode,const char * source,char * dest,int compressedSize,int maxOutputSize)2560 int LZ4_decompress_safe_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int compressedSize, int maxOutputSize) 2561 { 2562 LZ4_streamDecode_t_internal* lz4sd = &LZ4_streamDecode->internal_donotuse; 2563 int result; 2564 2565 if (lz4sd->prefixSize == 0) { 2566 /* The first call, no dictionary yet. */ 2567 assert(lz4sd->extDictSize == 0); 2568 result = LZ4_decompress_safe(source, dest, compressedSize, maxOutputSize); 2569 if (result <= 0) return result; 2570 lz4sd->prefixSize = (size_t)result; 2571 lz4sd->prefixEnd = (BYTE*)dest + result; 2572 } else if (lz4sd->prefixEnd == (BYTE*)dest) { 2573 /* They're rolling the current segment. */ 2574 if (lz4sd->prefixSize >= 64 KB - 1) 2575 result = LZ4_decompress_safe_withPrefix64k(source, dest, compressedSize, maxOutputSize); 2576 else if (lz4sd->extDictSize == 0) 2577 result = LZ4_decompress_safe_withSmallPrefix(source, dest, compressedSize, maxOutputSize, 2578 lz4sd->prefixSize); 2579 else 2580 result = LZ4_decompress_safe_doubleDict(source, dest, compressedSize, maxOutputSize, 2581 lz4sd->prefixSize, lz4sd->externalDict, lz4sd->extDictSize); 2582 if (result <= 0) return result; 2583 lz4sd->prefixSize += (size_t)result; 2584 lz4sd->prefixEnd += result; 2585 } else { 2586 /* The buffer wraps around, or they're switching to another buffer. */ 2587 lz4sd->extDictSize = lz4sd->prefixSize; 2588 lz4sd->externalDict = lz4sd->prefixEnd - lz4sd->extDictSize; 2589 result = LZ4_decompress_safe_forceExtDict(source, dest, compressedSize, maxOutputSize, 2590 lz4sd->externalDict, lz4sd->extDictSize); 2591 if (result <= 0) return result; 2592 lz4sd->prefixSize = (size_t)result; 2593 lz4sd->prefixEnd = (BYTE*)dest + result; 2594 } 2595 2596 return result; 2597 } 2598 2599 LZ4_FORCE_O2 int LZ4_decompress_fast_continue(LZ4_streamDecode_t * LZ4_streamDecode,const char * source,char * dest,int originalSize)2600 LZ4_decompress_fast_continue (LZ4_streamDecode_t* LZ4_streamDecode, 2601 const char* source, char* dest, int originalSize) 2602 { 2603 LZ4_streamDecode_t_internal* const lz4sd = 2604 (assert(LZ4_streamDecode!=NULL), &LZ4_streamDecode->internal_donotuse); 2605 int result; 2606 2607 DEBUGLOG(5, "LZ4_decompress_fast_continue (toDecodeSize=%i)", originalSize); 2608 assert(originalSize >= 0); 2609 2610 if (lz4sd->prefixSize == 0) { 2611 DEBUGLOG(5, "first invocation : no prefix nor extDict"); 2612 assert(lz4sd->extDictSize == 0); 2613 result = LZ4_decompress_fast(source, dest, originalSize); 2614 if (result <= 0) return result; 2615 lz4sd->prefixSize = (size_t)originalSize; 2616 lz4sd->prefixEnd = (BYTE*)dest + originalSize; 2617 } else if (lz4sd->prefixEnd == (BYTE*)dest) { 2618 DEBUGLOG(5, "continue using existing prefix"); 2619 result = LZ4_decompress_unsafe_generic( 2620 (const BYTE*)source, (BYTE*)dest, originalSize, 2621 lz4sd->prefixSize, 2622 lz4sd->externalDict, lz4sd->extDictSize); 2623 if (result <= 0) return result; 2624 lz4sd->prefixSize += (size_t)originalSize; 2625 lz4sd->prefixEnd += originalSize; 2626 } else { 2627 DEBUGLOG(5, "prefix becomes extDict"); 2628 lz4sd->extDictSize = lz4sd->prefixSize; 2629 lz4sd->externalDict = lz4sd->prefixEnd - lz4sd->extDictSize; 2630 result = LZ4_decompress_fast_extDict(source, dest, originalSize, 2631 lz4sd->externalDict, lz4sd->extDictSize); 2632 if (result <= 0) return result; 2633 lz4sd->prefixSize = (size_t)originalSize; 2634 lz4sd->prefixEnd = (BYTE*)dest + originalSize; 2635 } 2636 2637 return result; 2638 } 2639 2640 2641 /* 2642 Advanced decoding functions : 2643 *_usingDict() : 2644 These decoding functions work the same as "_continue" ones, 2645 the dictionary must be explicitly provided within parameters 2646 */ 2647 LZ4_decompress_safe_usingDict(const char * source,char * dest,int compressedSize,int maxOutputSize,const char * dictStart,int dictSize)2648 int LZ4_decompress_safe_usingDict(const char* source, char* dest, int compressedSize, int maxOutputSize, const char* dictStart, int dictSize) 2649 { 2650 if (dictSize==0) 2651 return LZ4_decompress_safe(source, dest, compressedSize, maxOutputSize); 2652 if (dictStart+dictSize == dest) { 2653 if (dictSize >= 64 KB - 1) { 2654 return LZ4_decompress_safe_withPrefix64k(source, dest, compressedSize, maxOutputSize); 2655 } 2656 assert(dictSize >= 0); 2657 return LZ4_decompress_safe_withSmallPrefix(source, dest, compressedSize, maxOutputSize, (size_t)dictSize); 2658 } 2659 assert(dictSize >= 0); 2660 return LZ4_decompress_safe_forceExtDict(source, dest, compressedSize, maxOutputSize, dictStart, (size_t)dictSize); 2661 } 2662 LZ4_decompress_safe_partial_usingDict(const char * source,char * dest,int compressedSize,int targetOutputSize,int dstCapacity,const char * dictStart,int dictSize)2663 int LZ4_decompress_safe_partial_usingDict(const char* source, char* dest, int compressedSize, int targetOutputSize, int dstCapacity, const char* dictStart, int dictSize) 2664 { 2665 if (dictSize==0) 2666 return LZ4_decompress_safe_partial(source, dest, compressedSize, targetOutputSize, dstCapacity); 2667 if (dictStart+dictSize == dest) { 2668 if (dictSize >= 64 KB - 1) { 2669 return LZ4_decompress_safe_partial_withPrefix64k(source, dest, compressedSize, targetOutputSize, dstCapacity); 2670 } 2671 assert(dictSize >= 0); 2672 return LZ4_decompress_safe_partial_withSmallPrefix(source, dest, compressedSize, targetOutputSize, dstCapacity, (size_t)dictSize); 2673 } 2674 assert(dictSize >= 0); 2675 return LZ4_decompress_safe_partial_forceExtDict(source, dest, compressedSize, targetOutputSize, dstCapacity, dictStart, (size_t)dictSize); 2676 } 2677 LZ4_decompress_fast_usingDict(const char * source,char * dest,int originalSize,const char * dictStart,int dictSize)2678 int LZ4_decompress_fast_usingDict(const char* source, char* dest, int originalSize, const char* dictStart, int dictSize) 2679 { 2680 if (dictSize==0 || dictStart+dictSize == dest) 2681 return LZ4_decompress_unsafe_generic( 2682 (const BYTE*)source, (BYTE*)dest, originalSize, 2683 (size_t)dictSize, NULL, 0); 2684 assert(dictSize >= 0); 2685 return LZ4_decompress_fast_extDict(source, dest, originalSize, dictStart, (size_t)dictSize); 2686 } 2687 2688 2689 /*=************************************************* 2690 * Obsolete Functions 2691 ***************************************************/ 2692 /* obsolete compression functions */ LZ4_compress_limitedOutput(const char * source,char * dest,int inputSize,int maxOutputSize)2693 int LZ4_compress_limitedOutput(const char* source, char* dest, int inputSize, int maxOutputSize) 2694 { 2695 return LZ4_compress_default(source, dest, inputSize, maxOutputSize); 2696 } LZ4_compress(const char * src,char * dest,int srcSize)2697 int LZ4_compress(const char* src, char* dest, int srcSize) 2698 { 2699 return LZ4_compress_default(src, dest, srcSize, LZ4_compressBound(srcSize)); 2700 } LZ4_compress_limitedOutput_withState(void * state,const char * src,char * dst,int srcSize,int dstSize)2701 int LZ4_compress_limitedOutput_withState (void* state, const char* src, char* dst, int srcSize, int dstSize) 2702 { 2703 return LZ4_compress_fast_extState(state, src, dst, srcSize, dstSize, 1); 2704 } LZ4_compress_withState(void * state,const char * src,char * dst,int srcSize)2705 int LZ4_compress_withState (void* state, const char* src, char* dst, int srcSize) 2706 { 2707 return LZ4_compress_fast_extState(state, src, dst, srcSize, LZ4_compressBound(srcSize), 1); 2708 } LZ4_compress_limitedOutput_continue(LZ4_stream_t * LZ4_stream,const char * src,char * dst,int srcSize,int dstCapacity)2709 int LZ4_compress_limitedOutput_continue (LZ4_stream_t* LZ4_stream, const char* src, char* dst, int srcSize, int dstCapacity) 2710 { 2711 return LZ4_compress_fast_continue(LZ4_stream, src, dst, srcSize, dstCapacity, 1); 2712 } LZ4_compress_continue(LZ4_stream_t * LZ4_stream,const char * source,char * dest,int inputSize)2713 int LZ4_compress_continue (LZ4_stream_t* LZ4_stream, const char* source, char* dest, int inputSize) 2714 { 2715 return LZ4_compress_fast_continue(LZ4_stream, source, dest, inputSize, LZ4_compressBound(inputSize), 1); 2716 } 2717 2718 /* 2719 These decompression functions are deprecated and should no longer be used. 2720 They are only provided here for compatibility with older user programs. 2721 - LZ4_uncompress is totally equivalent to LZ4_decompress_fast 2722 - LZ4_uncompress_unknownOutputSize is totally equivalent to LZ4_decompress_safe 2723 */ LZ4_uncompress(const char * source,char * dest,int outputSize)2724 int LZ4_uncompress (const char* source, char* dest, int outputSize) 2725 { 2726 return LZ4_decompress_fast(source, dest, outputSize); 2727 } LZ4_uncompress_unknownOutputSize(const char * source,char * dest,int isize,int maxOutputSize)2728 int LZ4_uncompress_unknownOutputSize (const char* source, char* dest, int isize, int maxOutputSize) 2729 { 2730 return LZ4_decompress_safe(source, dest, isize, maxOutputSize); 2731 } 2732 2733 /* Obsolete Streaming functions */ 2734 LZ4_sizeofStreamState(void)2735 int LZ4_sizeofStreamState(void) { return sizeof(LZ4_stream_t); } 2736 LZ4_resetStreamState(void * state,char * inputBuffer)2737 int LZ4_resetStreamState(void* state, char* inputBuffer) 2738 { 2739 (void)inputBuffer; 2740 LZ4_resetStream((LZ4_stream_t*)state); 2741 return 0; 2742 } 2743 2744 #if !defined(LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION) LZ4_create(char * inputBuffer)2745 void* LZ4_create (char* inputBuffer) 2746 { 2747 (void)inputBuffer; 2748 return LZ4_createStream(); 2749 } 2750 #endif 2751 LZ4_slideInputBuffer(void * state)2752 char* LZ4_slideInputBuffer (void* state) 2753 { 2754 /* avoid const char * -> char * conversion warning */ 2755 return (char *)(uptrval)((LZ4_stream_t*)state)->internal_donotuse.dictionary; 2756 } 2757 2758 #endif /* LZ4_COMMONDEFS_ONLY */ 2759 2760 #endif /* LV_USE_LZ4_INTERNAL */ 2761 2762