1 /* 2 * Copyright (c) 2016-present, Yann Collet, Facebook, Inc. 3 * All rights reserved. 4 * 5 * This source code is licensed under both the BSD-style license (found in the 6 * LICENSE file in the root directory of this source tree) and the GPLv2 (found 7 * in the COPYING file in the root directory of this source tree). 8 * You may select, at your option, one of the above-listed licenses. 9 */ 10 11 12 /*- Dependencies -*/ 13 #include "zstd_v05.h" 14 #include "error_private.h" 15 16 17 /* ****************************************************************** 18 mem.h 19 low-level memory access routines 20 Copyright (C) 2013-2015, Yann Collet. 21 22 BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) 23 24 Redistribution and use in source and binary forms, with or without 25 modification, are permitted provided that the following conditions are 26 met: 27 28 * Redistributions of source code must retain the above copyright 29 notice, this list of conditions and the following disclaimer. 30 * Redistributions in binary form must reproduce the above 31 copyright notice, this list of conditions and the following disclaimer 32 in the documentation and/or other materials provided with the 33 distribution. 34 35 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 36 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 37 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 38 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 39 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 40 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 41 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 42 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 43 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 44 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 45 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 46 47 You can contact the author at : 48 - FSEv05 source repository : https://github.com/Cyan4973/FiniteStateEntropy 49 - Public forum : https://groups.google.com/forum/#!forum/lz4c 50 ****************************************************************** */ 51 #ifndef MEM_H_MODULE 52 #define MEM_H_MODULE 53 54 #if defined (__cplusplus) 55 extern "C" { 56 #endif 57 58 /*-**************************************** 59 * Dependencies 60 ******************************************/ 61 #include <stddef.h> /* size_t, ptrdiff_t */ 62 #include <string.h> /* memcpy */ 63 64 65 /*-**************************************** 66 * Compiler specifics 67 ******************************************/ 68 #if defined(__GNUC__) 69 # define MEM_STATIC static __attribute__((unused)) 70 #elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) 71 # define MEM_STATIC static inline 72 #elif defined(_MSC_VER) 73 # define MEM_STATIC static __inline 74 #else 75 # define MEM_STATIC static /* this version may generate warnings for unused static functions; disable the relevant warning */ 76 #endif 77 78 79 /*-************************************************************** 80 * Basic Types 81 *****************************************************************/ 82 #if defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) 83 # include <stdint.h> 84 typedef uint8_t BYTE; 85 typedef uint16_t U16; 86 typedef int16_t S16; 87 typedef uint32_t U32; 88 typedef int32_t S32; 89 typedef uint64_t U64; 90 typedef int64_t S64; 91 #else 92 typedef unsigned char BYTE; 93 typedef unsigned short U16; 94 typedef signed short S16; 95 typedef unsigned int U32; 96 typedef signed int S32; 97 typedef unsigned long long U64; 98 typedef signed long long S64; 99 #endif 100 101 102 /*-************************************************************** 103 * Memory I/O 104 *****************************************************************/ 105 /* MEM_FORCE_MEMORY_ACCESS : 106 * By default, access to unaligned memory is controlled by `memcpy()`, which is safe and portable. 107 * Unfortunately, on some target/compiler combinations, the generated assembly is sub-optimal. 108 * The below switch allow to select different access method for improved performance. 109 * Method 0 (default) : use `memcpy()`. Safe and portable. 110 * Method 1 : `__packed` statement. It depends on compiler extension (ie, not portable). 111 * This method is safe if your compiler supports it, and *generally* as fast or faster than `memcpy`. 112 * Method 2 : direct access. This method is portable but violate C standard. 113 * It can generate buggy code on targets depending on alignment. 114 * In some circumstances, it's the only known way to get the most performance (ie GCC + ARMv6) 115 * See http://fastcompression.blogspot.fr/2015/08/accessing-unaligned-memory.html for details. 116 * Prefer these methods in priority order (0 > 1 > 2) 117 */ 118 #ifndef MEM_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */ 119 # if defined(__GNUC__) && ( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) ) 120 # define MEM_FORCE_MEMORY_ACCESS 2 121 # elif (defined(__INTEL_COMPILER) && !defined(WIN32)) || \ 122 (defined(__GNUC__) && ( defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__) )) 123 # define MEM_FORCE_MEMORY_ACCESS 1 124 # endif 125 #endif 126 127 MEM_STATIC unsigned MEM_32bits(void) { return sizeof(void*)==4; } 128 MEM_STATIC unsigned MEM_64bits(void) { return sizeof(void*)==8; } 129 130 MEM_STATIC unsigned MEM_isLittleEndian(void) 131 { 132 const union { U32 u; BYTE c[4]; } one = { 1 }; /* don't use static : performance detrimental */ 133 return one.c[0]; 134 } 135 136 #if defined(MEM_FORCE_MEMORY_ACCESS) && (MEM_FORCE_MEMORY_ACCESS==2) 137 138 /* violates C standard, by lying on structure alignment. 139 Only use if no other choice to achieve best performance on target platform */ 140 MEM_STATIC U16 MEM_read16(const void* memPtr) { return *(const U16*) memPtr; } 141 MEM_STATIC U32 MEM_read32(const void* memPtr) { return *(const U32*) memPtr; } 142 MEM_STATIC U64 MEM_read64(const void* memPtr) { return *(const U64*) memPtr; } 143 144 MEM_STATIC void MEM_write16(void* memPtr, U16 value) { *(U16*)memPtr = value; } 145 MEM_STATIC void MEM_write32(void* memPtr, U32 value) { *(U32*)memPtr = value; } 146 MEM_STATIC void MEM_write64(void* memPtr, U64 value) { *(U64*)memPtr = value; } 147 148 #elif defined(MEM_FORCE_MEMORY_ACCESS) && (MEM_FORCE_MEMORY_ACCESS==1) 149 150 /* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */ 151 /* currently only defined for gcc and icc */ 152 typedef union { U16 u16; U32 u32; U64 u64; size_t st; } __attribute__((packed)) unalign; 153 154 MEM_STATIC U16 MEM_read16(const void* ptr) { return ((const unalign*)ptr)->u16; } 155 MEM_STATIC U32 MEM_read32(const void* ptr) { return ((const unalign*)ptr)->u32; } 156 MEM_STATIC U64 MEM_read64(const void* ptr) { return ((const unalign*)ptr)->u64; } 157 158 MEM_STATIC void MEM_write16(void* memPtr, U16 value) { ((unalign*)memPtr)->u16 = value; } 159 MEM_STATIC void MEM_write32(void* memPtr, U32 value) { ((unalign*)memPtr)->u32 = value; } 160 MEM_STATIC void MEM_write64(void* memPtr, U64 value) { ((unalign*)memPtr)->u64 = value; } 161 162 #else 163 164 /* default method, safe and standard. 165 can sometimes prove slower */ 166 167 MEM_STATIC U16 MEM_read16(const void* memPtr) 168 { 169 U16 val; memcpy(&val, memPtr, sizeof(val)); return val; 170 } 171 172 MEM_STATIC U32 MEM_read32(const void* memPtr) 173 { 174 U32 val; memcpy(&val, memPtr, sizeof(val)); return val; 175 } 176 177 MEM_STATIC U64 MEM_read64(const void* memPtr) 178 { 179 U64 val; memcpy(&val, memPtr, sizeof(val)); return val; 180 } 181 182 MEM_STATIC void MEM_write16(void* memPtr, U16 value) 183 { 184 memcpy(memPtr, &value, sizeof(value)); 185 } 186 187 MEM_STATIC void MEM_write32(void* memPtr, U32 value) 188 { 189 memcpy(memPtr, &value, sizeof(value)); 190 } 191 192 MEM_STATIC void MEM_write64(void* memPtr, U64 value) 193 { 194 memcpy(memPtr, &value, sizeof(value)); 195 } 196 197 #endif /* MEM_FORCE_MEMORY_ACCESS */ 198 199 200 MEM_STATIC U16 MEM_readLE16(const void* memPtr) 201 { 202 if (MEM_isLittleEndian()) 203 return MEM_read16(memPtr); 204 else { 205 const BYTE* p = (const BYTE*)memPtr; 206 return (U16)(p[0] + (p[1]<<8)); 207 } 208 } 209 210 MEM_STATIC void MEM_writeLE16(void* memPtr, U16 val) 211 { 212 if (MEM_isLittleEndian()) { 213 MEM_write16(memPtr, val); 214 } else { 215 BYTE* p = (BYTE*)memPtr; 216 p[0] = (BYTE)val; 217 p[1] = (BYTE)(val>>8); 218 } 219 } 220 221 MEM_STATIC U32 MEM_readLE32(const void* memPtr) 222 { 223 if (MEM_isLittleEndian()) 224 return MEM_read32(memPtr); 225 else { 226 const BYTE* p = (const BYTE*)memPtr; 227 return (U32)((U32)p[0] + ((U32)p[1]<<8) + ((U32)p[2]<<16) + ((U32)p[3]<<24)); 228 } 229 } 230 231 232 MEM_STATIC U64 MEM_readLE64(const void* memPtr) 233 { 234 if (MEM_isLittleEndian()) 235 return MEM_read64(memPtr); 236 else { 237 const BYTE* p = (const BYTE*)memPtr; 238 return (U64)((U64)p[0] + ((U64)p[1]<<8) + ((U64)p[2]<<16) + ((U64)p[3]<<24) 239 + ((U64)p[4]<<32) + ((U64)p[5]<<40) + ((U64)p[6]<<48) + ((U64)p[7]<<56)); 240 } 241 } 242 243 244 MEM_STATIC size_t MEM_readLEST(const void* memPtr) 245 { 246 if (MEM_32bits()) 247 return (size_t)MEM_readLE32(memPtr); 248 else 249 return (size_t)MEM_readLE64(memPtr); 250 } 251 252 253 #if defined (__cplusplus) 254 } 255 #endif 256 257 #endif /* MEM_H_MODULE */ 258 259 /* 260 zstd - standard compression library 261 Header File for static linking only 262 Copyright (C) 2014-2016, Yann Collet. 263 264 BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) 265 266 Redistribution and use in source and binary forms, with or without 267 modification, are permitted provided that the following conditions are 268 met: 269 * Redistributions of source code must retain the above copyright 270 notice, this list of conditions and the following disclaimer. 271 * Redistributions in binary form must reproduce the above 272 copyright notice, this list of conditions and the following disclaimer 273 in the documentation and/or other materials provided with the 274 distribution. 275 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 276 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 277 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 278 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 279 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 280 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 281 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 282 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 283 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 284 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 285 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 286 287 You can contact the author at : 288 - zstd homepage : http://www.zstd.net 289 */ 290 #ifndef ZSTD_STATIC_H 291 #define ZSTD_STATIC_H 292 293 /* The prototypes defined within this file are considered experimental. 294 * They should not be used in the context DLL as they may change in the future. 295 * Prefer static linking if you need them, to control breaking version changes issues. 296 */ 297 298 #if defined (__cplusplus) 299 extern "C" { 300 #endif 301 302 303 304 /*-************************************* 305 * Types 306 ***************************************/ 307 #define ZSTDv05_WINDOWLOG_ABSOLUTEMIN 11 308 309 310 /*-************************************* 311 * Advanced functions 312 ***************************************/ 313 /*- Advanced Decompression functions -*/ 314 315 /*! ZSTDv05_decompress_usingPreparedDCtx() : 316 * Same as ZSTDv05_decompress_usingDict, but using a reference context `preparedDCtx`, where dictionary has been loaded. 317 * It avoids reloading the dictionary each time. 318 * `preparedDCtx` must have been properly initialized using ZSTDv05_decompressBegin_usingDict(). 319 * Requires 2 contexts : 1 for reference, which will not be modified, and 1 to run the decompression operation */ 320 size_t ZSTDv05_decompress_usingPreparedDCtx( 321 ZSTDv05_DCtx* dctx, const ZSTDv05_DCtx* preparedDCtx, 322 void* dst, size_t dstCapacity, 323 const void* src, size_t srcSize); 324 325 326 /* ************************************** 327 * Streaming functions (direct mode) 328 ****************************************/ 329 size_t ZSTDv05_decompressBegin(ZSTDv05_DCtx* dctx); 330 331 /* 332 Streaming decompression, direct mode (bufferless) 333 334 A ZSTDv05_DCtx object is required to track streaming operations. 335 Use ZSTDv05_createDCtx() / ZSTDv05_freeDCtx() to manage it. 336 A ZSTDv05_DCtx object can be re-used multiple times. 337 338 First typical operation is to retrieve frame parameters, using ZSTDv05_getFrameParams(). 339 This operation is independent, and just needs enough input data to properly decode the frame header. 340 Objective is to retrieve *params.windowlog, to know minimum amount of memory required during decoding. 341 Result : 0 when successful, it means the ZSTDv05_parameters structure has been filled. 342 >0 : means there is not enough data into src. Provides the expected size to successfully decode header. 343 errorCode, which can be tested using ZSTDv05_isError() 344 345 Start decompression, with ZSTDv05_decompressBegin() or ZSTDv05_decompressBegin_usingDict() 346 Alternatively, you can copy a prepared context, using ZSTDv05_copyDCtx() 347 348 Then use ZSTDv05_nextSrcSizeToDecompress() and ZSTDv05_decompressContinue() alternatively. 349 ZSTDv05_nextSrcSizeToDecompress() tells how much bytes to provide as 'srcSize' to ZSTDv05_decompressContinue(). 350 ZSTDv05_decompressContinue() requires this exact amount of bytes, or it will fail. 351 ZSTDv05_decompressContinue() needs previous data blocks during decompression, up to (1 << windowlog). 352 They should preferably be located contiguously, prior to current block. Alternatively, a round buffer is also possible. 353 354 @result of ZSTDv05_decompressContinue() is the number of bytes regenerated within 'dst'. 355 It can be zero, which is not an error; it just means ZSTDv05_decompressContinue() has decoded some header. 356 357 A frame is fully decoded when ZSTDv05_nextSrcSizeToDecompress() returns zero. 358 Context can then be reset to start a new decompression. 359 */ 360 361 362 /* ************************************** 363 * Block functions 364 ****************************************/ 365 /*! Block functions produce and decode raw zstd blocks, without frame metadata. 366 User will have to take in charge required information to regenerate data, such as block sizes. 367 368 A few rules to respect : 369 - Uncompressed block size must be <= 128 KB 370 - Compressing or decompressing requires a context structure 371 + Use ZSTDv05_createCCtx() and ZSTDv05_createDCtx() 372 - It is necessary to init context before starting 373 + compression : ZSTDv05_compressBegin() 374 + decompression : ZSTDv05_decompressBegin() 375 + variants _usingDict() are also allowed 376 + copyCCtx() and copyDCtx() work too 377 - When a block is considered not compressible enough, ZSTDv05_compressBlock() result will be zero. 378 In which case, nothing is produced into `dst`. 379 + User must test for such outcome and deal directly with uncompressed data 380 + ZSTDv05_decompressBlock() doesn't accept uncompressed data as input !! 381 */ 382 383 size_t ZSTDv05_decompressBlock(ZSTDv05_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize); 384 385 386 387 388 #if defined (__cplusplus) 389 } 390 #endif 391 392 #endif /* ZSTDv05_STATIC_H */ 393 394 395 /* 396 zstd_internal - common functions to include 397 Header File for include 398 Copyright (C) 2014-2016, Yann Collet. 399 400 BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) 401 402 Redistribution and use in source and binary forms, with or without 403 modification, are permitted provided that the following conditions are 404 met: 405 * Redistributions of source code must retain the above copyright 406 notice, this list of conditions and the following disclaimer. 407 * Redistributions in binary form must reproduce the above 408 copyright notice, this list of conditions and the following disclaimer 409 in the documentation and/or other materials provided with the 410 distribution. 411 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 412 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 413 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 414 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 415 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 416 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 417 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 418 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 419 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 420 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 421 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 422 423 You can contact the author at : 424 - zstd source repository : https://github.com/Cyan4973/zstd 425 */ 426 #ifndef ZSTD_CCOMMON_H_MODULE 427 #define ZSTD_CCOMMON_H_MODULE 428 429 430 431 /*-************************************* 432 * Common macros 433 ***************************************/ 434 #define MIN(a,b) ((a)<(b) ? (a) : (b)) 435 #define MAX(a,b) ((a)>(b) ? (a) : (b)) 436 437 438 /*-************************************* 439 * Common constants 440 ***************************************/ 441 #define ZSTDv05_DICT_MAGIC 0xEC30A435 442 443 #define KB *(1 <<10) 444 #define MB *(1 <<20) 445 #define GB *(1U<<30) 446 447 #define BLOCKSIZE (128 KB) /* define, for static allocation */ 448 449 static const size_t ZSTDv05_blockHeaderSize = 3; 450 static const size_t ZSTDv05_frameHeaderSize_min = 5; 451 #define ZSTDv05_frameHeaderSize_max 5 /* define, for static allocation */ 452 453 #define BITv057 128 454 #define BITv056 64 455 #define BITv055 32 456 #define BITv054 16 457 #define BITv051 2 458 #define BITv050 1 459 460 #define IS_HUFv05 0 461 #define IS_PCH 1 462 #define IS_RAW 2 463 #define IS_RLE 3 464 465 #define MINMATCH 4 466 #define REPCODE_STARTVALUE 1 467 468 #define Litbits 8 469 #define MLbits 7 470 #define LLbits 6 471 #define Offbits 5 472 #define MaxLit ((1<<Litbits) - 1) 473 #define MaxML ((1<<MLbits) - 1) 474 #define MaxLL ((1<<LLbits) - 1) 475 #define MaxOff ((1<<Offbits)- 1) 476 #define MLFSEv05Log 10 477 #define LLFSEv05Log 10 478 #define OffFSEv05Log 9 479 #define MaxSeq MAX(MaxLL, MaxML) 480 481 #define FSEv05_ENCODING_RAW 0 482 #define FSEv05_ENCODING_RLE 1 483 #define FSEv05_ENCODING_STATIC 2 484 #define FSEv05_ENCODING_DYNAMIC 3 485 486 487 #define HufLog 12 488 489 #define MIN_SEQUENCES_SIZE 1 /* nbSeq==0 */ 490 #define MIN_CBLOCK_SIZE (1 /*litCSize*/ + 1 /* RLE or RAW */ + MIN_SEQUENCES_SIZE /* nbSeq==0 */) /* for a non-null block */ 491 492 #define WILDCOPY_OVERLENGTH 8 493 494 typedef enum { bt_compressed, bt_raw, bt_rle, bt_end } blockType_t; 495 496 497 /*-******************************************* 498 * Shared functions to include for inlining 499 *********************************************/ 500 static void ZSTDv05_copy8(void* dst, const void* src) { memcpy(dst, src, 8); } 501 502 #define COPY8(d,s) { ZSTDv05_copy8(d,s); d+=8; s+=8; } 503 504 /*! ZSTDv05_wildcopy() : 505 * custom version of memcpy(), can copy up to 7 bytes too many (8 bytes if length==0) */ 506 MEM_STATIC void ZSTDv05_wildcopy(void* dst, const void* src, ptrdiff_t length) 507 { 508 const BYTE* ip = (const BYTE*)src; 509 BYTE* op = (BYTE*)dst; 510 BYTE* const oend = op + length; 511 do 512 COPY8(op, ip) 513 while (op < oend); 514 } 515 516 517 /*-******************************************* 518 * Private interfaces 519 *********************************************/ 520 typedef struct { 521 void* buffer; 522 U32* offsetStart; 523 U32* offset; 524 BYTE* offCodeStart; 525 BYTE* offCode; 526 BYTE* litStart; 527 BYTE* lit; 528 BYTE* litLengthStart; 529 BYTE* litLength; 530 BYTE* matchLengthStart; 531 BYTE* matchLength; 532 BYTE* dumpsStart; 533 BYTE* dumps; 534 /* opt */ 535 U32* matchLengthFreq; 536 U32* litLengthFreq; 537 U32* litFreq; 538 U32* offCodeFreq; 539 U32 matchLengthSum; 540 U32 litLengthSum; 541 U32 litSum; 542 U32 offCodeSum; 543 } seqStore_t; 544 545 546 547 #endif /* ZSTDv05_CCOMMON_H_MODULE */ 548 /* ****************************************************************** 549 FSEv05 : Finite State Entropy coder 550 header file 551 Copyright (C) 2013-2015, Yann Collet. 552 553 BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) 554 555 Redistribution and use in source and binary forms, with or without 556 modification, are permitted provided that the following conditions are 557 met: 558 559 * Redistributions of source code must retain the above copyright 560 notice, this list of conditions and the following disclaimer. 561 * Redistributions in binary form must reproduce the above 562 copyright notice, this list of conditions and the following disclaimer 563 in the documentation and/or other materials provided with the 564 distribution. 565 566 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 567 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 568 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 569 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 570 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 571 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 572 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 573 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 574 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 575 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 576 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 577 578 You can contact the author at : 579 - Source repository : https://github.com/Cyan4973/FiniteStateEntropy 580 - Public forum : https://groups.google.com/forum/#!forum/lz4c 581 ****************************************************************** */ 582 #ifndef FSEv05_H 583 #define FSEv05_H 584 585 #if defined (__cplusplus) 586 extern "C" { 587 #endif 588 589 590 /* ***************************************** 591 * Includes 592 ******************************************/ 593 #include <stddef.h> /* size_t, ptrdiff_t */ 594 595 596 /*-**************************************** 597 * FSEv05 simple functions 598 ******************************************/ 599 size_t FSEv05_decompress(void* dst, size_t maxDstSize, 600 const void* cSrc, size_t cSrcSize); 601 /*! 602 FSEv05_decompress(): 603 Decompress FSEv05 data from buffer 'cSrc', of size 'cSrcSize', 604 into already allocated destination buffer 'dst', of size 'maxDstSize'. 605 return : size of regenerated data (<= maxDstSize) 606 or an error code, which can be tested using FSEv05_isError() 607 608 ** Important ** : FSEv05_decompress() doesn't decompress non-compressible nor RLE data !!! 609 Why ? : making this distinction requires a header. 610 Header management is intentionally delegated to the user layer, which can better manage special cases. 611 */ 612 613 614 /* ***************************************** 615 * Tool functions 616 ******************************************/ 617 /* Error Management */ 618 unsigned FSEv05_isError(size_t code); /* tells if a return value is an error code */ 619 const char* FSEv05_getErrorName(size_t code); /* provides error code string (useful for debugging) */ 620 621 622 623 624 /* ***************************************** 625 * FSEv05 detailed API 626 ******************************************/ 627 /* *** DECOMPRESSION *** */ 628 629 /*! 630 FSEv05_readNCount(): 631 Read compactly saved 'normalizedCounter' from 'rBuffer'. 632 return : size read from 'rBuffer' 633 or an errorCode, which can be tested using FSEv05_isError() 634 maxSymbolValuePtr[0] and tableLogPtr[0] will also be updated with their respective values */ 635 size_t FSEv05_readNCount (short* normalizedCounter, unsigned* maxSymbolValuePtr, unsigned* tableLogPtr, const void* rBuffer, size_t rBuffSize); 636 637 /*! 638 Constructor and Destructor of type FSEv05_DTable 639 Note that its size depends on 'tableLog' */ 640 typedef unsigned FSEv05_DTable; /* don't allocate that. It's just a way to be more restrictive than void* */ 641 FSEv05_DTable* FSEv05_createDTable(unsigned tableLog); 642 void FSEv05_freeDTable(FSEv05_DTable* dt); 643 644 /*! 645 FSEv05_buildDTable(): 646 Builds 'dt', which must be already allocated, using FSEv05_createDTable() 647 @return : 0, 648 or an errorCode, which can be tested using FSEv05_isError() */ 649 size_t FSEv05_buildDTable (FSEv05_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog); 650 651 /*! 652 FSEv05_decompress_usingDTable(): 653 Decompress compressed source @cSrc of size @cSrcSize using `dt` 654 into `dst` which must be already allocated. 655 @return : size of regenerated data (necessarily <= @dstCapacity) 656 or an errorCode, which can be tested using FSEv05_isError() */ 657 size_t FSEv05_decompress_usingDTable(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, const FSEv05_DTable* dt); 658 659 660 661 #if defined (__cplusplus) 662 } 663 #endif 664 665 #endif /* FSEv05_H */ 666 /* ****************************************************************** 667 bitstream 668 Part of FSEv05 library 669 header file (to include) 670 Copyright (C) 2013-2016, Yann Collet. 671 672 BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) 673 674 Redistribution and use in source and binary forms, with or without 675 modification, are permitted provided that the following conditions are 676 met: 677 678 * Redistributions of source code must retain the above copyright 679 notice, this list of conditions and the following disclaimer. 680 * Redistributions in binary form must reproduce the above 681 copyright notice, this list of conditions and the following disclaimer 682 in the documentation and/or other materials provided with the 683 distribution. 684 685 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 686 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 687 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 688 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 689 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 690 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 691 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 692 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 693 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 694 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 695 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 696 697 You can contact the author at : 698 - Source repository : https://github.com/Cyan4973/FiniteStateEntropy 699 ****************************************************************** */ 700 #ifndef BITv05STREAM_H_MODULE 701 #define BITv05STREAM_H_MODULE 702 703 #if defined (__cplusplus) 704 extern "C" { 705 #endif 706 707 708 /* 709 * This API consists of small unitary functions, which highly benefit from being inlined. 710 * Since link-time-optimization is not available for all compilers, 711 * these functions are defined into a .h to be included. 712 */ 713 714 715 716 /*-******************************************** 717 * bitStream decoding API (read backward) 718 **********************************************/ 719 typedef struct 720 { 721 size_t bitContainer; 722 unsigned bitsConsumed; 723 const char* ptr; 724 const char* start; 725 } BITv05_DStream_t; 726 727 typedef enum { BITv05_DStream_unfinished = 0, 728 BITv05_DStream_endOfBuffer = 1, 729 BITv05_DStream_completed = 2, 730 BITv05_DStream_overflow = 3 } BITv05_DStream_status; /* result of BITv05_reloadDStream() */ 731 /* 1,2,4,8 would be better for bitmap combinations, but slows down performance a bit ... :( */ 732 733 MEM_STATIC size_t BITv05_initDStream(BITv05_DStream_t* bitD, const void* srcBuffer, size_t srcSize); 734 MEM_STATIC size_t BITv05_readBits(BITv05_DStream_t* bitD, unsigned nbBits); 735 MEM_STATIC BITv05_DStream_status BITv05_reloadDStream(BITv05_DStream_t* bitD); 736 MEM_STATIC unsigned BITv05_endOfDStream(const BITv05_DStream_t* bitD); 737 738 739 /*-**************************************** 740 * unsafe API 741 ******************************************/ 742 MEM_STATIC size_t BITv05_readBitsFast(BITv05_DStream_t* bitD, unsigned nbBits); 743 /* faster, but works only if nbBits >= 1 */ 744 745 746 747 /*-************************************************************** 748 * Helper functions 749 ****************************************************************/ 750 MEM_STATIC unsigned BITv05_highbit32 (U32 val) 751 { 752 # if defined(_MSC_VER) /* Visual */ 753 unsigned long r=0; 754 _BitScanReverse ( &r, val ); 755 return (unsigned) r; 756 # elif defined(__GNUC__) && (__GNUC__ >= 3) /* Use GCC Intrinsic */ 757 return 31 - __builtin_clz (val); 758 # else /* Software version */ 759 static const unsigned DeBruijnClz[32] = { 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 }; 760 U32 v = val; 761 unsigned r; 762 v |= v >> 1; 763 v |= v >> 2; 764 v |= v >> 4; 765 v |= v >> 8; 766 v |= v >> 16; 767 r = DeBruijnClz[ (U32) (v * 0x07C4ACDDU) >> 27]; 768 return r; 769 # endif 770 } 771 772 773 774 /*-******************************************************** 775 * bitStream decoding 776 **********************************************************/ 777 /*!BITv05_initDStream 778 * Initialize a BITv05_DStream_t. 779 * @bitD : a pointer to an already allocated BITv05_DStream_t structure 780 * @srcBuffer must point at the beginning of a bitStream 781 * @srcSize must be the exact size of the bitStream 782 * @result : size of stream (== srcSize) or an errorCode if a problem is detected 783 */ 784 MEM_STATIC size_t BITv05_initDStream(BITv05_DStream_t* bitD, const void* srcBuffer, size_t srcSize) 785 { 786 if (srcSize < 1) { memset(bitD, 0, sizeof(*bitD)); return ERROR(srcSize_wrong); } 787 788 if (srcSize >= sizeof(size_t)) { /* normal case */ 789 U32 contain32; 790 bitD->start = (const char*)srcBuffer; 791 bitD->ptr = (const char*)srcBuffer + srcSize - sizeof(size_t); 792 bitD->bitContainer = MEM_readLEST(bitD->ptr); 793 contain32 = ((const BYTE*)srcBuffer)[srcSize-1]; 794 if (contain32 == 0) return ERROR(GENERIC); /* endMark not present */ 795 bitD->bitsConsumed = 8 - BITv05_highbit32(contain32); 796 } else { 797 U32 contain32; 798 bitD->start = (const char*)srcBuffer; 799 bitD->ptr = bitD->start; 800 bitD->bitContainer = *(const BYTE*)(bitD->start); 801 switch(srcSize) 802 { 803 case 7: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[6]) << (sizeof(size_t)*8 - 16);/* fall-through */ 804 case 6: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[5]) << (sizeof(size_t)*8 - 24);/* fall-through */ 805 case 5: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[4]) << (sizeof(size_t)*8 - 32);/* fall-through */ 806 case 4: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[3]) << 24; /* fall-through */ 807 case 3: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[2]) << 16; /* fall-through */ 808 case 2: bitD->bitContainer += (size_t)(((const BYTE*)(bitD->start))[1]) << 8; /* fall-through */ 809 default: break; 810 } 811 contain32 = ((const BYTE*)srcBuffer)[srcSize-1]; 812 if (contain32 == 0) return ERROR(GENERIC); /* endMark not present */ 813 bitD->bitsConsumed = 8 - BITv05_highbit32(contain32); 814 bitD->bitsConsumed += (U32)(sizeof(size_t) - srcSize)*8; 815 } 816 817 return srcSize; 818 } 819 820 MEM_STATIC size_t BITv05_lookBits(BITv05_DStream_t* bitD, U32 nbBits) 821 { 822 const U32 bitMask = sizeof(bitD->bitContainer)*8 - 1; 823 return ((bitD->bitContainer << (bitD->bitsConsumed & bitMask)) >> 1) >> ((bitMask-nbBits) & bitMask); 824 } 825 826 /*! BITv05_lookBitsFast : 827 * unsafe version; only works only if nbBits >= 1 */ 828 MEM_STATIC size_t BITv05_lookBitsFast(BITv05_DStream_t* bitD, U32 nbBits) 829 { 830 const U32 bitMask = sizeof(bitD->bitContainer)*8 - 1; 831 return (bitD->bitContainer << (bitD->bitsConsumed & bitMask)) >> (((bitMask+1)-nbBits) & bitMask); 832 } 833 834 MEM_STATIC void BITv05_skipBits(BITv05_DStream_t* bitD, U32 nbBits) 835 { 836 bitD->bitsConsumed += nbBits; 837 } 838 839 MEM_STATIC size_t BITv05_readBits(BITv05_DStream_t* bitD, U32 nbBits) 840 { 841 size_t value = BITv05_lookBits(bitD, nbBits); 842 BITv05_skipBits(bitD, nbBits); 843 return value; 844 } 845 846 /*!BITv05_readBitsFast : 847 * unsafe version; only works only if nbBits >= 1 */ 848 MEM_STATIC size_t BITv05_readBitsFast(BITv05_DStream_t* bitD, U32 nbBits) 849 { 850 size_t value = BITv05_lookBitsFast(bitD, nbBits); 851 BITv05_skipBits(bitD, nbBits); 852 return value; 853 } 854 855 MEM_STATIC BITv05_DStream_status BITv05_reloadDStream(BITv05_DStream_t* bitD) 856 { 857 if (bitD->bitsConsumed > (sizeof(bitD->bitContainer)*8)) /* should never happen */ 858 return BITv05_DStream_overflow; 859 860 if (bitD->ptr >= bitD->start + sizeof(bitD->bitContainer)) { 861 bitD->ptr -= bitD->bitsConsumed >> 3; 862 bitD->bitsConsumed &= 7; 863 bitD->bitContainer = MEM_readLEST(bitD->ptr); 864 return BITv05_DStream_unfinished; 865 } 866 if (bitD->ptr == bitD->start) { 867 if (bitD->bitsConsumed < sizeof(bitD->bitContainer)*8) return BITv05_DStream_endOfBuffer; 868 return BITv05_DStream_completed; 869 } 870 { 871 U32 nbBytes = bitD->bitsConsumed >> 3; 872 BITv05_DStream_status result = BITv05_DStream_unfinished; 873 if (bitD->ptr - nbBytes < bitD->start) { 874 nbBytes = (U32)(bitD->ptr - bitD->start); /* ptr > start */ 875 result = BITv05_DStream_endOfBuffer; 876 } 877 bitD->ptr -= nbBytes; 878 bitD->bitsConsumed -= nbBytes*8; 879 bitD->bitContainer = MEM_readLEST(bitD->ptr); /* reminder : srcSize > sizeof(bitD) */ 880 return result; 881 } 882 } 883 884 /*! BITv05_endOfDStream 885 * @return Tells if DStream has reached its exact end 886 */ 887 MEM_STATIC unsigned BITv05_endOfDStream(const BITv05_DStream_t* DStream) 888 { 889 return ((DStream->ptr == DStream->start) && (DStream->bitsConsumed == sizeof(DStream->bitContainer)*8)); 890 } 891 892 #if defined (__cplusplus) 893 } 894 #endif 895 896 #endif /* BITv05STREAM_H_MODULE */ 897 /* ****************************************************************** 898 FSEv05 : Finite State Entropy coder 899 header file for static linking (only) 900 Copyright (C) 2013-2015, Yann Collet 901 902 BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) 903 904 Redistribution and use in source and binary forms, with or without 905 modification, are permitted provided that the following conditions are 906 met: 907 908 * Redistributions of source code must retain the above copyright 909 notice, this list of conditions and the following disclaimer. 910 * Redistributions in binary form must reproduce the above 911 copyright notice, this list of conditions and the following disclaimer 912 in the documentation and/or other materials provided with the 913 distribution. 914 915 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 916 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 917 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 918 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 919 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 920 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 921 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 922 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 923 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 924 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 925 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 926 927 You can contact the author at : 928 - Source repository : https://github.com/Cyan4973/FiniteStateEntropy 929 - Public forum : https://groups.google.com/forum/#!forum/lz4c 930 ****************************************************************** */ 931 #ifndef FSEv05_STATIC_H 932 #define FSEv05_STATIC_H 933 934 #if defined (__cplusplus) 935 extern "C" { 936 #endif 937 938 939 940 /* ***************************************** 941 * Static allocation 942 *******************************************/ 943 /* It is possible to statically allocate FSEv05 CTable/DTable as a table of unsigned using below macros */ 944 #define FSEv05_DTABLE_SIZE_U32(maxTableLog) (1 + (1<<maxTableLog)) 945 946 947 /* ***************************************** 948 * FSEv05 advanced API 949 *******************************************/ 950 size_t FSEv05_buildDTable_raw (FSEv05_DTable* dt, unsigned nbBits); 951 /* build a fake FSEv05_DTable, designed to read an uncompressed bitstream where each symbol uses nbBits */ 952 953 size_t FSEv05_buildDTable_rle (FSEv05_DTable* dt, unsigned char symbolValue); 954 /* build a fake FSEv05_DTable, designed to always generate the same symbolValue */ 955 956 957 958 /* ***************************************** 959 * FSEv05 symbol decompression API 960 *******************************************/ 961 typedef struct 962 { 963 size_t state; 964 const void* table; /* precise table may vary, depending on U16 */ 965 } FSEv05_DState_t; 966 967 968 static void FSEv05_initDState(FSEv05_DState_t* DStatePtr, BITv05_DStream_t* bitD, const FSEv05_DTable* dt); 969 970 static unsigned char FSEv05_decodeSymbol(FSEv05_DState_t* DStatePtr, BITv05_DStream_t* bitD); 971 972 static unsigned FSEv05_endOfDState(const FSEv05_DState_t* DStatePtr); 973 974 975 976 /* ***************************************** 977 * FSEv05 unsafe API 978 *******************************************/ 979 static unsigned char FSEv05_decodeSymbolFast(FSEv05_DState_t* DStatePtr, BITv05_DStream_t* bitD); 980 /* faster, but works only if nbBits is always >= 1 (otherwise, result will be corrupted) */ 981 982 983 /* ***************************************** 984 * Implementation of inlined functions 985 *******************************************/ 986 /* decompression */ 987 988 typedef struct { 989 U16 tableLog; 990 U16 fastMode; 991 } FSEv05_DTableHeader; /* sizeof U32 */ 992 993 typedef struct 994 { 995 unsigned short newState; 996 unsigned char symbol; 997 unsigned char nbBits; 998 } FSEv05_decode_t; /* size == U32 */ 999 1000 MEM_STATIC void FSEv05_initDState(FSEv05_DState_t* DStatePtr, BITv05_DStream_t* bitD, const FSEv05_DTable* dt) 1001 { 1002 const void* ptr = dt; 1003 const FSEv05_DTableHeader* const DTableH = (const FSEv05_DTableHeader*)ptr; 1004 DStatePtr->state = BITv05_readBits(bitD, DTableH->tableLog); 1005 BITv05_reloadDStream(bitD); 1006 DStatePtr->table = dt + 1; 1007 } 1008 1009 MEM_STATIC BYTE FSEv05_peakSymbol(FSEv05_DState_t* DStatePtr) 1010 { 1011 const FSEv05_decode_t DInfo = ((const FSEv05_decode_t*)(DStatePtr->table))[DStatePtr->state]; 1012 return DInfo.symbol; 1013 } 1014 1015 MEM_STATIC BYTE FSEv05_decodeSymbol(FSEv05_DState_t* DStatePtr, BITv05_DStream_t* bitD) 1016 { 1017 const FSEv05_decode_t DInfo = ((const FSEv05_decode_t*)(DStatePtr->table))[DStatePtr->state]; 1018 const U32 nbBits = DInfo.nbBits; 1019 BYTE symbol = DInfo.symbol; 1020 size_t lowBits = BITv05_readBits(bitD, nbBits); 1021 1022 DStatePtr->state = DInfo.newState + lowBits; 1023 return symbol; 1024 } 1025 1026 MEM_STATIC BYTE FSEv05_decodeSymbolFast(FSEv05_DState_t* DStatePtr, BITv05_DStream_t* bitD) 1027 { 1028 const FSEv05_decode_t DInfo = ((const FSEv05_decode_t*)(DStatePtr->table))[DStatePtr->state]; 1029 const U32 nbBits = DInfo.nbBits; 1030 BYTE symbol = DInfo.symbol; 1031 size_t lowBits = BITv05_readBitsFast(bitD, nbBits); 1032 1033 DStatePtr->state = DInfo.newState + lowBits; 1034 return symbol; 1035 } 1036 1037 MEM_STATIC unsigned FSEv05_endOfDState(const FSEv05_DState_t* DStatePtr) 1038 { 1039 return DStatePtr->state == 0; 1040 } 1041 1042 1043 #if defined (__cplusplus) 1044 } 1045 #endif 1046 1047 #endif /* FSEv05_STATIC_H */ 1048 /* ****************************************************************** 1049 FSEv05 : Finite State Entropy coder 1050 Copyright (C) 2013-2015, Yann Collet. 1051 1052 BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) 1053 1054 Redistribution and use in source and binary forms, with or without 1055 modification, are permitted provided that the following conditions are 1056 met: 1057 1058 * Redistributions of source code must retain the above copyright 1059 notice, this list of conditions and the following disclaimer. 1060 * Redistributions in binary form must reproduce the above 1061 copyright notice, this list of conditions and the following disclaimer 1062 in the documentation and/or other materials provided with the 1063 distribution. 1064 1065 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1066 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1067 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1068 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 1069 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 1070 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 1071 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 1072 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 1073 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 1074 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 1075 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1076 1077 You can contact the author at : 1078 - FSEv05 source repository : https://github.com/Cyan4973/FiniteStateEntropy 1079 - Public forum : https://groups.google.com/forum/#!forum/lz4c 1080 ****************************************************************** */ 1081 1082 #ifndef FSEv05_COMMONDEFS_ONLY 1083 1084 /* ************************************************************** 1085 * Tuning parameters 1086 ****************************************************************/ 1087 /*!MEMORY_USAGE : 1088 * Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; etc.) 1089 * Increasing memory usage improves compression ratio 1090 * Reduced memory usage can improve speed, due to cache effect 1091 * Recommended max value is 14, for 16KB, which nicely fits into Intel x86 L1 cache */ 1092 #define FSEv05_MAX_MEMORY_USAGE 14 1093 #define FSEv05_DEFAULT_MEMORY_USAGE 13 1094 1095 /*!FSEv05_MAX_SYMBOL_VALUE : 1096 * Maximum symbol value authorized. 1097 * Required for proper stack allocation */ 1098 #define FSEv05_MAX_SYMBOL_VALUE 255 1099 1100 1101 /* ************************************************************** 1102 * template functions type & suffix 1103 ****************************************************************/ 1104 #define FSEv05_FUNCTION_TYPE BYTE 1105 #define FSEv05_FUNCTION_EXTENSION 1106 #define FSEv05_DECODE_TYPE FSEv05_decode_t 1107 1108 1109 #endif /* !FSEv05_COMMONDEFS_ONLY */ 1110 1111 /* ************************************************************** 1112 * Compiler specifics 1113 ****************************************************************/ 1114 #ifdef _MSC_VER /* Visual Studio */ 1115 # define FORCE_INLINE static __forceinline 1116 # include <intrin.h> /* For Visual 2005 */ 1117 # pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */ 1118 # pragma warning(disable : 4214) /* disable: C4214: non-int bitfields */ 1119 #else 1120 # if defined (__cplusplus) || defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */ 1121 # ifdef __GNUC__ 1122 # define FORCE_INLINE static inline __attribute__((always_inline)) 1123 # else 1124 # define FORCE_INLINE static inline 1125 # endif 1126 # else 1127 # define FORCE_INLINE static 1128 # endif /* __STDC_VERSION__ */ 1129 #endif 1130 1131 1132 /* ************************************************************** 1133 * Includes 1134 ****************************************************************/ 1135 #include <stdlib.h> /* malloc, free, qsort */ 1136 #include <string.h> /* memcpy, memset */ 1137 #include <stdio.h> /* printf (debug) */ 1138 1139 1140 1141 /* *************************************************************** 1142 * Constants 1143 *****************************************************************/ 1144 #define FSEv05_MAX_TABLELOG (FSEv05_MAX_MEMORY_USAGE-2) 1145 #define FSEv05_MAX_TABLESIZE (1U<<FSEv05_MAX_TABLELOG) 1146 #define FSEv05_MAXTABLESIZE_MASK (FSEv05_MAX_TABLESIZE-1) 1147 #define FSEv05_DEFAULT_TABLELOG (FSEv05_DEFAULT_MEMORY_USAGE-2) 1148 #define FSEv05_MIN_TABLELOG 5 1149 1150 #define FSEv05_TABLELOG_ABSOLUTE_MAX 15 1151 #if FSEv05_MAX_TABLELOG > FSEv05_TABLELOG_ABSOLUTE_MAX 1152 #error "FSEv05_MAX_TABLELOG > FSEv05_TABLELOG_ABSOLUTE_MAX is not supported" 1153 #endif 1154 1155 1156 /* ************************************************************** 1157 * Error Management 1158 ****************************************************************/ 1159 #define FSEv05_STATIC_ASSERT(c) { enum { FSEv05_static_assert = 1/(int)(!!(c)) }; } /* use only *after* variable declarations */ 1160 1161 1162 /* ************************************************************** 1163 * Complex types 1164 ****************************************************************/ 1165 typedef U32 DTable_max_t[FSEv05_DTABLE_SIZE_U32(FSEv05_MAX_TABLELOG)]; 1166 1167 1168 /* ************************************************************** 1169 * Templates 1170 ****************************************************************/ 1171 /* 1172 designed to be included 1173 for type-specific functions (template emulation in C) 1174 Objective is to write these functions only once, for improved maintenance 1175 */ 1176 1177 /* safety checks */ 1178 #ifndef FSEv05_FUNCTION_EXTENSION 1179 # error "FSEv05_FUNCTION_EXTENSION must be defined" 1180 #endif 1181 #ifndef FSEv05_FUNCTION_TYPE 1182 # error "FSEv05_FUNCTION_TYPE must be defined" 1183 #endif 1184 1185 /* Function names */ 1186 #define FSEv05_CAT(X,Y) X##Y 1187 #define FSEv05_FUNCTION_NAME(X,Y) FSEv05_CAT(X,Y) 1188 #define FSEv05_TYPE_NAME(X,Y) FSEv05_CAT(X,Y) 1189 1190 1191 /* Function templates */ 1192 static U32 FSEv05_tableStep(U32 tableSize) { return (tableSize>>1) + (tableSize>>3) + 3; } 1193 1194 1195 1196 FSEv05_DTable* FSEv05_createDTable (unsigned tableLog) 1197 { 1198 if (tableLog > FSEv05_TABLELOG_ABSOLUTE_MAX) tableLog = FSEv05_TABLELOG_ABSOLUTE_MAX; 1199 return (FSEv05_DTable*)malloc( FSEv05_DTABLE_SIZE_U32(tableLog) * sizeof (U32) ); 1200 } 1201 1202 void FSEv05_freeDTable (FSEv05_DTable* dt) 1203 { 1204 free(dt); 1205 } 1206 1207 size_t FSEv05_buildDTable(FSEv05_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog) 1208 { 1209 FSEv05_DTableHeader DTableH; 1210 void* const tdPtr = dt+1; /* because dt is unsigned, 32-bits aligned on 32-bits */ 1211 FSEv05_DECODE_TYPE* const tableDecode = (FSEv05_DECODE_TYPE*) (tdPtr); 1212 const U32 tableSize = 1 << tableLog; 1213 const U32 tableMask = tableSize-1; 1214 const U32 step = FSEv05_tableStep(tableSize); 1215 U16 symbolNext[FSEv05_MAX_SYMBOL_VALUE+1]; 1216 U32 position = 0; 1217 U32 highThreshold = tableSize-1; 1218 const S16 largeLimit= (S16)(1 << (tableLog-1)); 1219 U32 noLarge = 1; 1220 U32 s; 1221 1222 /* Sanity Checks */ 1223 if (maxSymbolValue > FSEv05_MAX_SYMBOL_VALUE) return ERROR(maxSymbolValue_tooLarge); 1224 if (tableLog > FSEv05_MAX_TABLELOG) return ERROR(tableLog_tooLarge); 1225 1226 /* Init, lay down lowprob symbols */ 1227 DTableH.tableLog = (U16)tableLog; 1228 for (s=0; s<=maxSymbolValue; s++) { 1229 if (normalizedCounter[s]==-1) { 1230 tableDecode[highThreshold--].symbol = (FSEv05_FUNCTION_TYPE)s; 1231 symbolNext[s] = 1; 1232 } else { 1233 if (normalizedCounter[s] >= largeLimit) noLarge=0; 1234 symbolNext[s] = normalizedCounter[s]; 1235 } } 1236 1237 /* Spread symbols */ 1238 for (s=0; s<=maxSymbolValue; s++) { 1239 int i; 1240 for (i=0; i<normalizedCounter[s]; i++) { 1241 tableDecode[position].symbol = (FSEv05_FUNCTION_TYPE)s; 1242 position = (position + step) & tableMask; 1243 while (position > highThreshold) position = (position + step) & tableMask; /* lowprob area */ 1244 } } 1245 1246 if (position!=0) return ERROR(GENERIC); /* position must reach all cells once, otherwise normalizedCounter is incorrect */ 1247 1248 /* Build Decoding table */ 1249 { 1250 U32 i; 1251 for (i=0; i<tableSize; i++) { 1252 FSEv05_FUNCTION_TYPE symbol = (FSEv05_FUNCTION_TYPE)(tableDecode[i].symbol); 1253 U16 nextState = symbolNext[symbol]++; 1254 tableDecode[i].nbBits = (BYTE) (tableLog - BITv05_highbit32 ((U32)nextState) ); 1255 tableDecode[i].newState = (U16) ( (nextState << tableDecode[i].nbBits) - tableSize); 1256 } } 1257 1258 DTableH.fastMode = (U16)noLarge; 1259 memcpy(dt, &DTableH, sizeof(DTableH)); 1260 return 0; 1261 } 1262 1263 1264 #ifndef FSEv05_COMMONDEFS_ONLY 1265 /*-**************************************** 1266 * FSEv05 helper functions 1267 ******************************************/ 1268 unsigned FSEv05_isError(size_t code) { return ERR_isError(code); } 1269 1270 const char* FSEv05_getErrorName(size_t code) { return ERR_getErrorName(code); } 1271 1272 1273 /*-************************************************************** 1274 * FSEv05 NCount encoding-decoding 1275 ****************************************************************/ 1276 static short FSEv05_abs(short a) { return a<0 ? -a : a; } 1277 1278 1279 size_t FSEv05_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr, 1280 const void* headerBuffer, size_t hbSize) 1281 { 1282 const BYTE* const istart = (const BYTE*) headerBuffer; 1283 const BYTE* const iend = istart + hbSize; 1284 const BYTE* ip = istart; 1285 int nbBits; 1286 int remaining; 1287 int threshold; 1288 U32 bitStream; 1289 int bitCount; 1290 unsigned charnum = 0; 1291 int previous0 = 0; 1292 1293 if (hbSize < 4) return ERROR(srcSize_wrong); 1294 bitStream = MEM_readLE32(ip); 1295 nbBits = (bitStream & 0xF) + FSEv05_MIN_TABLELOG; /* extract tableLog */ 1296 if (nbBits > FSEv05_TABLELOG_ABSOLUTE_MAX) return ERROR(tableLog_tooLarge); 1297 bitStream >>= 4; 1298 bitCount = 4; 1299 *tableLogPtr = nbBits; 1300 remaining = (1<<nbBits)+1; 1301 threshold = 1<<nbBits; 1302 nbBits++; 1303 1304 while ((remaining>1) && (charnum<=*maxSVPtr)) { 1305 if (previous0) { 1306 unsigned n0 = charnum; 1307 while ((bitStream & 0xFFFF) == 0xFFFF) { 1308 n0+=24; 1309 if (ip < iend-5) { 1310 ip+=2; 1311 bitStream = MEM_readLE32(ip) >> bitCount; 1312 } else { 1313 bitStream >>= 16; 1314 bitCount+=16; 1315 } } 1316 while ((bitStream & 3) == 3) { 1317 n0+=3; 1318 bitStream>>=2; 1319 bitCount+=2; 1320 } 1321 n0 += bitStream & 3; 1322 bitCount += 2; 1323 if (n0 > *maxSVPtr) return ERROR(maxSymbolValue_tooSmall); 1324 while (charnum < n0) normalizedCounter[charnum++] = 0; 1325 if ((ip <= iend-7) || (ip + (bitCount>>3) <= iend-4)) { 1326 ip += bitCount>>3; 1327 bitCount &= 7; 1328 bitStream = MEM_readLE32(ip) >> bitCount; 1329 } 1330 else 1331 bitStream >>= 2; 1332 } 1333 { 1334 const short max = (short)((2*threshold-1)-remaining); 1335 short count; 1336 1337 if ((bitStream & (threshold-1)) < (U32)max) { 1338 count = (short)(bitStream & (threshold-1)); 1339 bitCount += nbBits-1; 1340 } else { 1341 count = (short)(bitStream & (2*threshold-1)); 1342 if (count >= threshold) count -= max; 1343 bitCount += nbBits; 1344 } 1345 1346 count--; /* extra accuracy */ 1347 remaining -= FSEv05_abs(count); 1348 normalizedCounter[charnum++] = count; 1349 previous0 = !count; 1350 while (remaining < threshold) { 1351 nbBits--; 1352 threshold >>= 1; 1353 } 1354 1355 if ((ip <= iend-7) || (ip + (bitCount>>3) <= iend-4)) { 1356 ip += bitCount>>3; 1357 bitCount &= 7; 1358 } else { 1359 bitCount -= (int)(8 * (iend - 4 - ip)); 1360 ip = iend - 4; 1361 } 1362 bitStream = MEM_readLE32(ip) >> (bitCount & 31); 1363 } } 1364 if (remaining != 1) return ERROR(GENERIC); 1365 *maxSVPtr = charnum-1; 1366 1367 ip += (bitCount+7)>>3; 1368 if ((size_t)(ip-istart) > hbSize) return ERROR(srcSize_wrong); 1369 return ip-istart; 1370 } 1371 1372 1373 1374 /*-******************************************************* 1375 * Decompression (Byte symbols) 1376 *********************************************************/ 1377 size_t FSEv05_buildDTable_rle (FSEv05_DTable* dt, BYTE symbolValue) 1378 { 1379 void* ptr = dt; 1380 FSEv05_DTableHeader* const DTableH = (FSEv05_DTableHeader*)ptr; 1381 void* dPtr = dt + 1; 1382 FSEv05_decode_t* const cell = (FSEv05_decode_t*)dPtr; 1383 1384 DTableH->tableLog = 0; 1385 DTableH->fastMode = 0; 1386 1387 cell->newState = 0; 1388 cell->symbol = symbolValue; 1389 cell->nbBits = 0; 1390 1391 return 0; 1392 } 1393 1394 1395 size_t FSEv05_buildDTable_raw (FSEv05_DTable* dt, unsigned nbBits) 1396 { 1397 void* ptr = dt; 1398 FSEv05_DTableHeader* const DTableH = (FSEv05_DTableHeader*)ptr; 1399 void* dPtr = dt + 1; 1400 FSEv05_decode_t* const dinfo = (FSEv05_decode_t*)dPtr; 1401 const unsigned tableSize = 1 << nbBits; 1402 const unsigned tableMask = tableSize - 1; 1403 const unsigned maxSymbolValue = tableMask; 1404 unsigned s; 1405 1406 /* Sanity checks */ 1407 if (nbBits < 1) return ERROR(GENERIC); /* min size */ 1408 1409 /* Build Decoding Table */ 1410 DTableH->tableLog = (U16)nbBits; 1411 DTableH->fastMode = 1; 1412 for (s=0; s<=maxSymbolValue; s++) { 1413 dinfo[s].newState = 0; 1414 dinfo[s].symbol = (BYTE)s; 1415 dinfo[s].nbBits = (BYTE)nbBits; 1416 } 1417 1418 return 0; 1419 } 1420 1421 FORCE_INLINE size_t FSEv05_decompress_usingDTable_generic( 1422 void* dst, size_t maxDstSize, 1423 const void* cSrc, size_t cSrcSize, 1424 const FSEv05_DTable* dt, const unsigned fast) 1425 { 1426 BYTE* const ostart = (BYTE*) dst; 1427 BYTE* op = ostart; 1428 BYTE* const omax = op + maxDstSize; 1429 BYTE* const olimit = omax-3; 1430 1431 BITv05_DStream_t bitD; 1432 FSEv05_DState_t state1; 1433 FSEv05_DState_t state2; 1434 size_t errorCode; 1435 1436 /* Init */ 1437 errorCode = BITv05_initDStream(&bitD, cSrc, cSrcSize); /* replaced last arg by maxCompressed Size */ 1438 if (FSEv05_isError(errorCode)) return errorCode; 1439 1440 FSEv05_initDState(&state1, &bitD, dt); 1441 FSEv05_initDState(&state2, &bitD, dt); 1442 1443 #define FSEv05_GETSYMBOL(statePtr) fast ? FSEv05_decodeSymbolFast(statePtr, &bitD) : FSEv05_decodeSymbol(statePtr, &bitD) 1444 1445 /* 4 symbols per loop */ 1446 for ( ; (BITv05_reloadDStream(&bitD)==BITv05_DStream_unfinished) && (op<olimit) ; op+=4) { 1447 op[0] = FSEv05_GETSYMBOL(&state1); 1448 1449 if (FSEv05_MAX_TABLELOG*2+7 > sizeof(bitD.bitContainer)*8) /* This test must be static */ 1450 BITv05_reloadDStream(&bitD); 1451 1452 op[1] = FSEv05_GETSYMBOL(&state2); 1453 1454 if (FSEv05_MAX_TABLELOG*4+7 > sizeof(bitD.bitContainer)*8) /* This test must be static */ 1455 { if (BITv05_reloadDStream(&bitD) > BITv05_DStream_unfinished) { op+=2; break; } } 1456 1457 op[2] = FSEv05_GETSYMBOL(&state1); 1458 1459 if (FSEv05_MAX_TABLELOG*2+7 > sizeof(bitD.bitContainer)*8) /* This test must be static */ 1460 BITv05_reloadDStream(&bitD); 1461 1462 op[3] = FSEv05_GETSYMBOL(&state2); 1463 } 1464 1465 /* tail */ 1466 /* note : BITv05_reloadDStream(&bitD) >= FSEv05_DStream_partiallyFilled; Ends at exactly BITv05_DStream_completed */ 1467 while (1) { 1468 if ( (BITv05_reloadDStream(&bitD)>BITv05_DStream_completed) || (op==omax) || (BITv05_endOfDStream(&bitD) && (fast || FSEv05_endOfDState(&state1))) ) 1469 break; 1470 1471 *op++ = FSEv05_GETSYMBOL(&state1); 1472 1473 if ( (BITv05_reloadDStream(&bitD)>BITv05_DStream_completed) || (op==omax) || (BITv05_endOfDStream(&bitD) && (fast || FSEv05_endOfDState(&state2))) ) 1474 break; 1475 1476 *op++ = FSEv05_GETSYMBOL(&state2); 1477 } 1478 1479 /* end ? */ 1480 if (BITv05_endOfDStream(&bitD) && FSEv05_endOfDState(&state1) && FSEv05_endOfDState(&state2)) 1481 return op-ostart; 1482 1483 if (op==omax) return ERROR(dstSize_tooSmall); /* dst buffer is full, but cSrc unfinished */ 1484 1485 return ERROR(corruption_detected); 1486 } 1487 1488 1489 size_t FSEv05_decompress_usingDTable(void* dst, size_t originalSize, 1490 const void* cSrc, size_t cSrcSize, 1491 const FSEv05_DTable* dt) 1492 { 1493 const void* ptr = dt; 1494 const FSEv05_DTableHeader* DTableH = (const FSEv05_DTableHeader*)ptr; 1495 const U32 fastMode = DTableH->fastMode; 1496 1497 /* select fast mode (static) */ 1498 if (fastMode) return FSEv05_decompress_usingDTable_generic(dst, originalSize, cSrc, cSrcSize, dt, 1); 1499 return FSEv05_decompress_usingDTable_generic(dst, originalSize, cSrc, cSrcSize, dt, 0); 1500 } 1501 1502 1503 size_t FSEv05_decompress(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize) 1504 { 1505 const BYTE* const istart = (const BYTE*)cSrc; 1506 const BYTE* ip = istart; 1507 short counting[FSEv05_MAX_SYMBOL_VALUE+1]; 1508 DTable_max_t dt; /* Static analyzer seems unable to understand this table will be properly initialized later */ 1509 unsigned tableLog; 1510 unsigned maxSymbolValue = FSEv05_MAX_SYMBOL_VALUE; 1511 size_t errorCode; 1512 1513 if (cSrcSize<2) return ERROR(srcSize_wrong); /* too small input size */ 1514 1515 /* normal FSEv05 decoding mode */ 1516 errorCode = FSEv05_readNCount (counting, &maxSymbolValue, &tableLog, istart, cSrcSize); 1517 if (FSEv05_isError(errorCode)) return errorCode; 1518 if (errorCode >= cSrcSize) return ERROR(srcSize_wrong); /* too small input size */ 1519 ip += errorCode; 1520 cSrcSize -= errorCode; 1521 1522 errorCode = FSEv05_buildDTable (dt, counting, maxSymbolValue, tableLog); 1523 if (FSEv05_isError(errorCode)) return errorCode; 1524 1525 /* always return, even if it is an error code */ 1526 return FSEv05_decompress_usingDTable (dst, maxDstSize, ip, cSrcSize, dt); 1527 } 1528 1529 1530 1531 #endif /* FSEv05_COMMONDEFS_ONLY */ 1532 /* ****************************************************************** 1533 Huff0 : Huffman coder, part of New Generation Entropy library 1534 header file 1535 Copyright (C) 2013-2016, Yann Collet. 1536 1537 BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) 1538 1539 Redistribution and use in source and binary forms, with or without 1540 modification, are permitted provided that the following conditions are 1541 met: 1542 1543 * Redistributions of source code must retain the above copyright 1544 notice, this list of conditions and the following disclaimer. 1545 * Redistributions in binary form must reproduce the above 1546 copyright notice, this list of conditions and the following disclaimer 1547 in the documentation and/or other materials provided with the 1548 distribution. 1549 1550 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1551 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1552 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1553 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 1554 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 1555 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 1556 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 1557 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 1558 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 1559 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 1560 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1561 1562 You can contact the author at : 1563 - Source repository : https://github.com/Cyan4973/FiniteStateEntropy 1564 ****************************************************************** */ 1565 #ifndef HUFF0_H 1566 #define HUFF0_H 1567 1568 #if defined (__cplusplus) 1569 extern "C" { 1570 #endif 1571 1572 1573 1574 /* **************************************** 1575 * Huff0 simple functions 1576 ******************************************/ 1577 size_t HUFv05_decompress(void* dst, size_t dstSize, 1578 const void* cSrc, size_t cSrcSize); 1579 /*! 1580 HUFv05_decompress(): 1581 Decompress Huff0 data from buffer 'cSrc', of size 'cSrcSize', 1582 into already allocated destination buffer 'dst', of size 'dstSize'. 1583 @dstSize : must be the **exact** size of original (uncompressed) data. 1584 Note : in contrast with FSEv05, HUFv05_decompress can regenerate 1585 RLE (cSrcSize==1) and uncompressed (cSrcSize==dstSize) data, 1586 because it knows size to regenerate. 1587 @return : size of regenerated data (== dstSize) 1588 or an error code, which can be tested using HUFv05_isError() 1589 */ 1590 1591 1592 /* **************************************** 1593 * Tool functions 1594 ******************************************/ 1595 /* Error Management */ 1596 unsigned HUFv05_isError(size_t code); /* tells if a return value is an error code */ 1597 const char* HUFv05_getErrorName(size_t code); /* provides error code string (useful for debugging) */ 1598 1599 1600 #if defined (__cplusplus) 1601 } 1602 #endif 1603 1604 #endif /* HUF0_H */ 1605 /* ****************************************************************** 1606 Huff0 : Huffman codec, part of New Generation Entropy library 1607 header file, for static linking only 1608 Copyright (C) 2013-2016, Yann Collet 1609 1610 BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) 1611 1612 Redistribution and use in source and binary forms, with or without 1613 modification, are permitted provided that the following conditions are 1614 met: 1615 1616 * Redistributions of source code must retain the above copyright 1617 notice, this list of conditions and the following disclaimer. 1618 * Redistributions in binary form must reproduce the above 1619 copyright notice, this list of conditions and the following disclaimer 1620 in the documentation and/or other materials provided with the 1621 distribution. 1622 1623 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1624 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1625 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1626 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 1627 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 1628 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 1629 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 1630 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 1631 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 1632 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 1633 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1634 1635 You can contact the author at : 1636 - Source repository : https://github.com/Cyan4973/FiniteStateEntropy 1637 ****************************************************************** */ 1638 #ifndef HUF0_STATIC_H 1639 #define HUF0_STATIC_H 1640 1641 #if defined (__cplusplus) 1642 extern "C" { 1643 #endif 1644 1645 1646 1647 /* **************************************** 1648 * Static allocation 1649 ******************************************/ 1650 /* static allocation of Huff0's DTable */ 1651 #define HUFv05_DTABLE_SIZE(maxTableLog) (1 + (1<<maxTableLog)) 1652 #define HUFv05_CREATE_STATIC_DTABLEX2(DTable, maxTableLog) \ 1653 unsigned short DTable[HUFv05_DTABLE_SIZE(maxTableLog)] = { maxTableLog } 1654 #define HUFv05_CREATE_STATIC_DTABLEX4(DTable, maxTableLog) \ 1655 unsigned int DTable[HUFv05_DTABLE_SIZE(maxTableLog)] = { maxTableLog } 1656 #define HUFv05_CREATE_STATIC_DTABLEX6(DTable, maxTableLog) \ 1657 unsigned int DTable[HUFv05_DTABLE_SIZE(maxTableLog) * 3 / 2] = { maxTableLog } 1658 1659 1660 /* **************************************** 1661 * Advanced decompression functions 1662 ******************************************/ 1663 size_t HUFv05_decompress4X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* single-symbol decoder */ 1664 size_t HUFv05_decompress4X4 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* double-symbols decoder */ 1665 1666 1667 /* **************************************** 1668 * Huff0 detailed API 1669 ******************************************/ 1670 /*! 1671 HUFv05_decompress() does the following: 1672 1. select the decompression algorithm (X2, X4, X6) based on pre-computed heuristics 1673 2. build Huffman table from save, using HUFv05_readDTableXn() 1674 3. decode 1 or 4 segments in parallel using HUFv05_decompressSXn_usingDTable 1675 */ 1676 size_t HUFv05_readDTableX2 (unsigned short* DTable, const void* src, size_t srcSize); 1677 size_t HUFv05_readDTableX4 (unsigned* DTable, const void* src, size_t srcSize); 1678 1679 size_t HUFv05_decompress4X2_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const unsigned short* DTable); 1680 size_t HUFv05_decompress4X4_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const unsigned* DTable); 1681 1682 1683 /* single stream variants */ 1684 1685 size_t HUFv05_decompress1X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* single-symbol decoder */ 1686 size_t HUFv05_decompress1X4 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* double-symbol decoder */ 1687 1688 size_t HUFv05_decompress1X2_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const unsigned short* DTable); 1689 size_t HUFv05_decompress1X4_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const unsigned* DTable); 1690 1691 1692 1693 #if defined (__cplusplus) 1694 } 1695 #endif 1696 1697 #endif /* HUF0_STATIC_H */ 1698 /* ****************************************************************** 1699 Huff0 : Huffman coder, part of New Generation Entropy library 1700 Copyright (C) 2013-2015, Yann Collet. 1701 1702 BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) 1703 1704 Redistribution and use in source and binary forms, with or without 1705 modification, are permitted provided that the following conditions are 1706 met: 1707 1708 * Redistributions of source code must retain the above copyright 1709 notice, this list of conditions and the following disclaimer. 1710 * Redistributions in binary form must reproduce the above 1711 copyright notice, this list of conditions and the following disclaimer 1712 in the documentation and/or other materials provided with the 1713 distribution. 1714 1715 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1716 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1717 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1718 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 1719 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 1720 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 1721 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 1722 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 1723 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 1724 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 1725 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1726 1727 You can contact the author at : 1728 - FSEv05+Huff0 source repository : https://github.com/Cyan4973/FiniteStateEntropy 1729 - Public forum : https://groups.google.com/forum/#!forum/lz4c 1730 ****************************************************************** */ 1731 1732 /* ************************************************************** 1733 * Compiler specifics 1734 ****************************************************************/ 1735 #if defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) 1736 /* inline is defined */ 1737 #elif defined(_MSC_VER) 1738 # define inline __inline 1739 #else 1740 # define inline /* disable inline */ 1741 #endif 1742 1743 1744 #ifdef _MSC_VER /* Visual Studio */ 1745 # pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */ 1746 #endif 1747 1748 1749 /* ************************************************************** 1750 * Includes 1751 ****************************************************************/ 1752 #include <stdlib.h> /* malloc, free, qsort */ 1753 #include <string.h> /* memcpy, memset */ 1754 #include <stdio.h> /* printf (debug) */ 1755 1756 1757 /* ************************************************************** 1758 * Constants 1759 ****************************************************************/ 1760 #define HUFv05_ABSOLUTEMAX_TABLELOG 16 /* absolute limit of HUFv05_MAX_TABLELOG. Beyond that value, code does not work */ 1761 #define HUFv05_MAX_TABLELOG 12 /* max configured tableLog (for static allocation); can be modified up to HUFv05_ABSOLUTEMAX_TABLELOG */ 1762 #define HUFv05_DEFAULT_TABLELOG HUFv05_MAX_TABLELOG /* tableLog by default, when not specified */ 1763 #define HUFv05_MAX_SYMBOL_VALUE 255 1764 #if (HUFv05_MAX_TABLELOG > HUFv05_ABSOLUTEMAX_TABLELOG) 1765 # error "HUFv05_MAX_TABLELOG is too large !" 1766 #endif 1767 1768 1769 /* ************************************************************** 1770 * Error Management 1771 ****************************************************************/ 1772 unsigned HUFv05_isError(size_t code) { return ERR_isError(code); } 1773 const char* HUFv05_getErrorName(size_t code) { return ERR_getErrorName(code); } 1774 #define HUFv05_STATIC_ASSERT(c) { enum { HUFv05_static_assert = 1/(int)(!!(c)) }; } /* use only *after* variable declarations */ 1775 1776 1777 /* ******************************************************* 1778 * Huff0 : Huffman block decompression 1779 *********************************************************/ 1780 typedef struct { BYTE byte; BYTE nbBits; } HUFv05_DEltX2; /* single-symbol decoding */ 1781 1782 typedef struct { U16 sequence; BYTE nbBits; BYTE length; } HUFv05_DEltX4; /* double-symbols decoding */ 1783 1784 typedef struct { BYTE symbol; BYTE weight; } sortedSymbol_t; 1785 1786 /*! HUFv05_readStats 1787 Read compact Huffman tree, saved by HUFv05_writeCTable 1788 @huffWeight : destination buffer 1789 @return : size read from `src` 1790 */ 1791 static size_t HUFv05_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats, 1792 U32* nbSymbolsPtr, U32* tableLogPtr, 1793 const void* src, size_t srcSize) 1794 { 1795 U32 weightTotal; 1796 U32 tableLog; 1797 const BYTE* ip = (const BYTE*) src; 1798 size_t iSize; 1799 size_t oSize; 1800 U32 n; 1801 1802 if (!srcSize) return ERROR(srcSize_wrong); 1803 iSize = ip[0]; 1804 //memset(huffWeight, 0, hwSize); /* is not necessary, even though some analyzer complain ... */ 1805 1806 if (iSize >= 128) { /* special header */ 1807 if (iSize >= (242)) { /* RLE */ 1808 static int l[14] = { 1, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64, 127, 128 }; 1809 oSize = l[iSize-242]; 1810 memset(huffWeight, 1, hwSize); 1811 iSize = 0; 1812 } 1813 else { /* Incompressible */ 1814 oSize = iSize - 127; 1815 iSize = ((oSize+1)/2); 1816 if (iSize+1 > srcSize) return ERROR(srcSize_wrong); 1817 if (oSize >= hwSize) return ERROR(corruption_detected); 1818 ip += 1; 1819 for (n=0; n<oSize; n+=2) { 1820 huffWeight[n] = ip[n/2] >> 4; 1821 huffWeight[n+1] = ip[n/2] & 15; 1822 } } } 1823 else { /* header compressed with FSEv05 (normal case) */ 1824 if (iSize+1 > srcSize) return ERROR(srcSize_wrong); 1825 oSize = FSEv05_decompress(huffWeight, hwSize-1, ip+1, iSize); /* max (hwSize-1) values decoded, as last one is implied */ 1826 if (FSEv05_isError(oSize)) return oSize; 1827 } 1828 1829 /* collect weight stats */ 1830 memset(rankStats, 0, (HUFv05_ABSOLUTEMAX_TABLELOG + 1) * sizeof(U32)); 1831 weightTotal = 0; 1832 for (n=0; n<oSize; n++) { 1833 if (huffWeight[n] >= HUFv05_ABSOLUTEMAX_TABLELOG) return ERROR(corruption_detected); 1834 rankStats[huffWeight[n]]++; 1835 weightTotal += (1 << huffWeight[n]) >> 1; 1836 } 1837 if (weightTotal == 0) return ERROR(corruption_detected); 1838 1839 /* get last non-null symbol weight (implied, total must be 2^n) */ 1840 tableLog = BITv05_highbit32(weightTotal) + 1; 1841 if (tableLog > HUFv05_ABSOLUTEMAX_TABLELOG) return ERROR(corruption_detected); 1842 { /* determine last weight */ 1843 U32 total = 1 << tableLog; 1844 U32 rest = total - weightTotal; 1845 U32 verif = 1 << BITv05_highbit32(rest); 1846 U32 lastWeight = BITv05_highbit32(rest) + 1; 1847 if (verif != rest) return ERROR(corruption_detected); /* last value must be a clean power of 2 */ 1848 huffWeight[oSize] = (BYTE)lastWeight; 1849 rankStats[lastWeight]++; 1850 } 1851 1852 /* check tree construction validity */ 1853 if ((rankStats[1] < 2) || (rankStats[1] & 1)) return ERROR(corruption_detected); /* by construction : at least 2 elts of rank 1, must be even */ 1854 1855 /* results */ 1856 *nbSymbolsPtr = (U32)(oSize+1); 1857 *tableLogPtr = tableLog; 1858 return iSize+1; 1859 } 1860 1861 1862 /*-***************************/ 1863 /* single-symbol decoding */ 1864 /*-***************************/ 1865 1866 size_t HUFv05_readDTableX2 (U16* DTable, const void* src, size_t srcSize) 1867 { 1868 BYTE huffWeight[HUFv05_MAX_SYMBOL_VALUE + 1]; 1869 U32 rankVal[HUFv05_ABSOLUTEMAX_TABLELOG + 1]; /* large enough for values from 0 to 16 */ 1870 U32 tableLog = 0; 1871 size_t iSize; 1872 U32 nbSymbols = 0; 1873 U32 n; 1874 U32 nextRankStart; 1875 void* const dtPtr = DTable + 1; 1876 HUFv05_DEltX2* const dt = (HUFv05_DEltX2*)dtPtr; 1877 1878 HUFv05_STATIC_ASSERT(sizeof(HUFv05_DEltX2) == sizeof(U16)); /* if compilation fails here, assertion is false */ 1879 //memset(huffWeight, 0, sizeof(huffWeight)); /* is not necessary, even though some analyzer complain ... */ 1880 1881 iSize = HUFv05_readStats(huffWeight, HUFv05_MAX_SYMBOL_VALUE + 1, rankVal, &nbSymbols, &tableLog, src, srcSize); 1882 if (HUFv05_isError(iSize)) return iSize; 1883 1884 /* check result */ 1885 if (tableLog > DTable[0]) return ERROR(tableLog_tooLarge); /* DTable is too small */ 1886 DTable[0] = (U16)tableLog; /* maybe should separate sizeof allocated DTable, from used size of DTable, in case of re-use */ 1887 1888 /* Prepare ranks */ 1889 nextRankStart = 0; 1890 for (n=1; n<=tableLog; n++) { 1891 U32 current = nextRankStart; 1892 nextRankStart += (rankVal[n] << (n-1)); 1893 rankVal[n] = current; 1894 } 1895 1896 /* fill DTable */ 1897 for (n=0; n<nbSymbols; n++) { 1898 const U32 w = huffWeight[n]; 1899 const U32 length = (1 << w) >> 1; 1900 U32 i; 1901 HUFv05_DEltX2 D; 1902 D.byte = (BYTE)n; D.nbBits = (BYTE)(tableLog + 1 - w); 1903 for (i = rankVal[w]; i < rankVal[w] + length; i++) 1904 dt[i] = D; 1905 rankVal[w] += length; 1906 } 1907 1908 return iSize; 1909 } 1910 1911 static BYTE HUFv05_decodeSymbolX2(BITv05_DStream_t* Dstream, const HUFv05_DEltX2* dt, const U32 dtLog) 1912 { 1913 const size_t val = BITv05_lookBitsFast(Dstream, dtLog); /* note : dtLog >= 1 */ 1914 const BYTE c = dt[val].byte; 1915 BITv05_skipBits(Dstream, dt[val].nbBits); 1916 return c; 1917 } 1918 1919 #define HUFv05_DECODE_SYMBOLX2_0(ptr, DStreamPtr) \ 1920 *ptr++ = HUFv05_decodeSymbolX2(DStreamPtr, dt, dtLog) 1921 1922 #define HUFv05_DECODE_SYMBOLX2_1(ptr, DStreamPtr) \ 1923 if (MEM_64bits() || (HUFv05_MAX_TABLELOG<=12)) \ 1924 HUFv05_DECODE_SYMBOLX2_0(ptr, DStreamPtr) 1925 1926 #define HUFv05_DECODE_SYMBOLX2_2(ptr, DStreamPtr) \ 1927 if (MEM_64bits()) \ 1928 HUFv05_DECODE_SYMBOLX2_0(ptr, DStreamPtr) 1929 1930 static inline size_t HUFv05_decodeStreamX2(BYTE* p, BITv05_DStream_t* const bitDPtr, BYTE* const pEnd, const HUFv05_DEltX2* const dt, const U32 dtLog) 1931 { 1932 BYTE* const pStart = p; 1933 1934 /* up to 4 symbols at a time */ 1935 while ((BITv05_reloadDStream(bitDPtr) == BITv05_DStream_unfinished) && (p <= pEnd-4)) { 1936 HUFv05_DECODE_SYMBOLX2_2(p, bitDPtr); 1937 HUFv05_DECODE_SYMBOLX2_1(p, bitDPtr); 1938 HUFv05_DECODE_SYMBOLX2_2(p, bitDPtr); 1939 HUFv05_DECODE_SYMBOLX2_0(p, bitDPtr); 1940 } 1941 1942 /* closer to the end */ 1943 while ((BITv05_reloadDStream(bitDPtr) == BITv05_DStream_unfinished) && (p < pEnd)) 1944 HUFv05_DECODE_SYMBOLX2_0(p, bitDPtr); 1945 1946 /* no more data to retrieve from bitstream, hence no need to reload */ 1947 while (p < pEnd) 1948 HUFv05_DECODE_SYMBOLX2_0(p, bitDPtr); 1949 1950 return pEnd-pStart; 1951 } 1952 1953 size_t HUFv05_decompress1X2_usingDTable( 1954 void* dst, size_t dstSize, 1955 const void* cSrc, size_t cSrcSize, 1956 const U16* DTable) 1957 { 1958 BYTE* op = (BYTE*)dst; 1959 BYTE* const oend = op + dstSize; 1960 const U32 dtLog = DTable[0]; 1961 const void* dtPtr = DTable; 1962 const HUFv05_DEltX2* const dt = ((const HUFv05_DEltX2*)dtPtr)+1; 1963 BITv05_DStream_t bitD; 1964 1965 if (dstSize <= cSrcSize) return ERROR(dstSize_tooSmall); 1966 { size_t const errorCode = BITv05_initDStream(&bitD, cSrc, cSrcSize); 1967 if (HUFv05_isError(errorCode)) return errorCode; } 1968 1969 HUFv05_decodeStreamX2(op, &bitD, oend, dt, dtLog); 1970 1971 /* check */ 1972 if (!BITv05_endOfDStream(&bitD)) return ERROR(corruption_detected); 1973 1974 return dstSize; 1975 } 1976 1977 size_t HUFv05_decompress1X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) 1978 { 1979 HUFv05_CREATE_STATIC_DTABLEX2(DTable, HUFv05_MAX_TABLELOG); 1980 const BYTE* ip = (const BYTE*) cSrc; 1981 size_t errorCode; 1982 1983 errorCode = HUFv05_readDTableX2 (DTable, cSrc, cSrcSize); 1984 if (HUFv05_isError(errorCode)) return errorCode; 1985 if (errorCode >= cSrcSize) return ERROR(srcSize_wrong); 1986 ip += errorCode; 1987 cSrcSize -= errorCode; 1988 1989 return HUFv05_decompress1X2_usingDTable (dst, dstSize, ip, cSrcSize, DTable); 1990 } 1991 1992 1993 size_t HUFv05_decompress4X2_usingDTable( 1994 void* dst, size_t dstSize, 1995 const void* cSrc, size_t cSrcSize, 1996 const U16* DTable) 1997 { 1998 const BYTE* const istart = (const BYTE*) cSrc; 1999 BYTE* const ostart = (BYTE*) dst; 2000 BYTE* const oend = ostart + dstSize; 2001 const void* const dtPtr = DTable; 2002 const HUFv05_DEltX2* const dt = ((const HUFv05_DEltX2*)dtPtr) +1; 2003 const U32 dtLog = DTable[0]; 2004 size_t errorCode; 2005 2006 /* Init */ 2007 BITv05_DStream_t bitD1; 2008 BITv05_DStream_t bitD2; 2009 BITv05_DStream_t bitD3; 2010 BITv05_DStream_t bitD4; 2011 const size_t length1 = MEM_readLE16(istart); 2012 const size_t length2 = MEM_readLE16(istart+2); 2013 const size_t length3 = MEM_readLE16(istart+4); 2014 size_t length4; 2015 const BYTE* const istart1 = istart + 6; /* jumpTable */ 2016 const BYTE* const istart2 = istart1 + length1; 2017 const BYTE* const istart3 = istart2 + length2; 2018 const BYTE* const istart4 = istart3 + length3; 2019 const size_t segmentSize = (dstSize+3) / 4; 2020 BYTE* const opStart2 = ostart + segmentSize; 2021 BYTE* const opStart3 = opStart2 + segmentSize; 2022 BYTE* const opStart4 = opStart3 + segmentSize; 2023 BYTE* op1 = ostart; 2024 BYTE* op2 = opStart2; 2025 BYTE* op3 = opStart3; 2026 BYTE* op4 = opStart4; 2027 U32 endSignal; 2028 2029 /* Check */ 2030 if (cSrcSize < 10) return ERROR(corruption_detected); /* strict minimum : jump table + 1 byte per stream */ 2031 2032 length4 = cSrcSize - (length1 + length2 + length3 + 6); 2033 if (length4 > cSrcSize) return ERROR(corruption_detected); /* overflow */ 2034 errorCode = BITv05_initDStream(&bitD1, istart1, length1); 2035 if (HUFv05_isError(errorCode)) return errorCode; 2036 errorCode = BITv05_initDStream(&bitD2, istart2, length2); 2037 if (HUFv05_isError(errorCode)) return errorCode; 2038 errorCode = BITv05_initDStream(&bitD3, istart3, length3); 2039 if (HUFv05_isError(errorCode)) return errorCode; 2040 errorCode = BITv05_initDStream(&bitD4, istart4, length4); 2041 if (HUFv05_isError(errorCode)) return errorCode; 2042 2043 /* 16-32 symbols per loop (4-8 symbols per stream) */ 2044 endSignal = BITv05_reloadDStream(&bitD1) | BITv05_reloadDStream(&bitD2) | BITv05_reloadDStream(&bitD3) | BITv05_reloadDStream(&bitD4); 2045 for ( ; (endSignal==BITv05_DStream_unfinished) && (op4<(oend-7)) ; ) { 2046 HUFv05_DECODE_SYMBOLX2_2(op1, &bitD1); 2047 HUFv05_DECODE_SYMBOLX2_2(op2, &bitD2); 2048 HUFv05_DECODE_SYMBOLX2_2(op3, &bitD3); 2049 HUFv05_DECODE_SYMBOLX2_2(op4, &bitD4); 2050 HUFv05_DECODE_SYMBOLX2_1(op1, &bitD1); 2051 HUFv05_DECODE_SYMBOLX2_1(op2, &bitD2); 2052 HUFv05_DECODE_SYMBOLX2_1(op3, &bitD3); 2053 HUFv05_DECODE_SYMBOLX2_1(op4, &bitD4); 2054 HUFv05_DECODE_SYMBOLX2_2(op1, &bitD1); 2055 HUFv05_DECODE_SYMBOLX2_2(op2, &bitD2); 2056 HUFv05_DECODE_SYMBOLX2_2(op3, &bitD3); 2057 HUFv05_DECODE_SYMBOLX2_2(op4, &bitD4); 2058 HUFv05_DECODE_SYMBOLX2_0(op1, &bitD1); 2059 HUFv05_DECODE_SYMBOLX2_0(op2, &bitD2); 2060 HUFv05_DECODE_SYMBOLX2_0(op3, &bitD3); 2061 HUFv05_DECODE_SYMBOLX2_0(op4, &bitD4); 2062 endSignal = BITv05_reloadDStream(&bitD1) | BITv05_reloadDStream(&bitD2) | BITv05_reloadDStream(&bitD3) | BITv05_reloadDStream(&bitD4); 2063 } 2064 2065 /* check corruption */ 2066 if (op1 > opStart2) return ERROR(corruption_detected); 2067 if (op2 > opStart3) return ERROR(corruption_detected); 2068 if (op3 > opStart4) return ERROR(corruption_detected); 2069 /* note : op4 supposed already verified within main loop */ 2070 2071 /* finish bitStreams one by one */ 2072 HUFv05_decodeStreamX2(op1, &bitD1, opStart2, dt, dtLog); 2073 HUFv05_decodeStreamX2(op2, &bitD2, opStart3, dt, dtLog); 2074 HUFv05_decodeStreamX2(op3, &bitD3, opStart4, dt, dtLog); 2075 HUFv05_decodeStreamX2(op4, &bitD4, oend, dt, dtLog); 2076 2077 /* check */ 2078 endSignal = BITv05_endOfDStream(&bitD1) & BITv05_endOfDStream(&bitD2) & BITv05_endOfDStream(&bitD3) & BITv05_endOfDStream(&bitD4); 2079 if (!endSignal) return ERROR(corruption_detected); 2080 2081 /* decoded size */ 2082 return dstSize; 2083 } 2084 2085 2086 size_t HUFv05_decompress4X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) 2087 { 2088 HUFv05_CREATE_STATIC_DTABLEX2(DTable, HUFv05_MAX_TABLELOG); 2089 const BYTE* ip = (const BYTE*) cSrc; 2090 size_t errorCode; 2091 2092 errorCode = HUFv05_readDTableX2 (DTable, cSrc, cSrcSize); 2093 if (HUFv05_isError(errorCode)) return errorCode; 2094 if (errorCode >= cSrcSize) return ERROR(srcSize_wrong); 2095 ip += errorCode; 2096 cSrcSize -= errorCode; 2097 2098 return HUFv05_decompress4X2_usingDTable (dst, dstSize, ip, cSrcSize, DTable); 2099 } 2100 2101 2102 /* *************************/ 2103 /* double-symbols decoding */ 2104 /* *************************/ 2105 2106 static void HUFv05_fillDTableX4Level2(HUFv05_DEltX4* DTable, U32 sizeLog, const U32 consumed, 2107 const U32* rankValOrigin, const int minWeight, 2108 const sortedSymbol_t* sortedSymbols, const U32 sortedListSize, 2109 U32 nbBitsBaseline, U16 baseSeq) 2110 { 2111 HUFv05_DEltX4 DElt; 2112 U32 rankVal[HUFv05_ABSOLUTEMAX_TABLELOG + 1]; 2113 U32 s; 2114 2115 /* get pre-calculated rankVal */ 2116 memcpy(rankVal, rankValOrigin, sizeof(rankVal)); 2117 2118 /* fill skipped values */ 2119 if (minWeight>1) { 2120 U32 i, skipSize = rankVal[minWeight]; 2121 MEM_writeLE16(&(DElt.sequence), baseSeq); 2122 DElt.nbBits = (BYTE)(consumed); 2123 DElt.length = 1; 2124 for (i = 0; i < skipSize; i++) 2125 DTable[i] = DElt; 2126 } 2127 2128 /* fill DTable */ 2129 for (s=0; s<sortedListSize; s++) { /* note : sortedSymbols already skipped */ 2130 const U32 symbol = sortedSymbols[s].symbol; 2131 const U32 weight = sortedSymbols[s].weight; 2132 const U32 nbBits = nbBitsBaseline - weight; 2133 const U32 length = 1 << (sizeLog-nbBits); 2134 const U32 start = rankVal[weight]; 2135 U32 i = start; 2136 const U32 end = start + length; 2137 2138 MEM_writeLE16(&(DElt.sequence), (U16)(baseSeq + (symbol << 8))); 2139 DElt.nbBits = (BYTE)(nbBits + consumed); 2140 DElt.length = 2; 2141 do { DTable[i++] = DElt; } while (i<end); /* since length >= 1 */ 2142 2143 rankVal[weight] += length; 2144 } 2145 } 2146 2147 typedef U32 rankVal_t[HUFv05_ABSOLUTEMAX_TABLELOG][HUFv05_ABSOLUTEMAX_TABLELOG + 1]; 2148 2149 static void HUFv05_fillDTableX4(HUFv05_DEltX4* DTable, const U32 targetLog, 2150 const sortedSymbol_t* sortedList, const U32 sortedListSize, 2151 const U32* rankStart, rankVal_t rankValOrigin, const U32 maxWeight, 2152 const U32 nbBitsBaseline) 2153 { 2154 U32 rankVal[HUFv05_ABSOLUTEMAX_TABLELOG + 1]; 2155 const int scaleLog = nbBitsBaseline - targetLog; /* note : targetLog >= srcLog, hence scaleLog <= 1 */ 2156 const U32 minBits = nbBitsBaseline - maxWeight; 2157 U32 s; 2158 2159 memcpy(rankVal, rankValOrigin, sizeof(rankVal)); 2160 2161 /* fill DTable */ 2162 for (s=0; s<sortedListSize; s++) { 2163 const U16 symbol = sortedList[s].symbol; 2164 const U32 weight = sortedList[s].weight; 2165 const U32 nbBits = nbBitsBaseline - weight; 2166 const U32 start = rankVal[weight]; 2167 const U32 length = 1 << (targetLog-nbBits); 2168 2169 if (targetLog-nbBits >= minBits) { /* enough room for a second symbol */ 2170 U32 sortedRank; 2171 int minWeight = nbBits + scaleLog; 2172 if (minWeight < 1) minWeight = 1; 2173 sortedRank = rankStart[minWeight]; 2174 HUFv05_fillDTableX4Level2(DTable+start, targetLog-nbBits, nbBits, 2175 rankValOrigin[nbBits], minWeight, 2176 sortedList+sortedRank, sortedListSize-sortedRank, 2177 nbBitsBaseline, symbol); 2178 } else { 2179 U32 i; 2180 const U32 end = start + length; 2181 HUFv05_DEltX4 DElt; 2182 2183 MEM_writeLE16(&(DElt.sequence), symbol); 2184 DElt.nbBits = (BYTE)(nbBits); 2185 DElt.length = 1; 2186 for (i = start; i < end; i++) 2187 DTable[i] = DElt; 2188 } 2189 rankVal[weight] += length; 2190 } 2191 } 2192 2193 size_t HUFv05_readDTableX4 (U32* DTable, const void* src, size_t srcSize) 2194 { 2195 BYTE weightList[HUFv05_MAX_SYMBOL_VALUE + 1]; 2196 sortedSymbol_t sortedSymbol[HUFv05_MAX_SYMBOL_VALUE + 1]; 2197 U32 rankStats[HUFv05_ABSOLUTEMAX_TABLELOG + 1] = { 0 }; 2198 U32 rankStart0[HUFv05_ABSOLUTEMAX_TABLELOG + 2] = { 0 }; 2199 U32* const rankStart = rankStart0+1; 2200 rankVal_t rankVal; 2201 U32 tableLog, maxW, sizeOfSort, nbSymbols; 2202 const U32 memLog = DTable[0]; 2203 size_t iSize; 2204 void* dtPtr = DTable; 2205 HUFv05_DEltX4* const dt = ((HUFv05_DEltX4*)dtPtr) + 1; 2206 2207 HUFv05_STATIC_ASSERT(sizeof(HUFv05_DEltX4) == sizeof(U32)); /* if compilation fails here, assertion is false */ 2208 if (memLog > HUFv05_ABSOLUTEMAX_TABLELOG) return ERROR(tableLog_tooLarge); 2209 //memset(weightList, 0, sizeof(weightList)); /* is not necessary, even though some analyzer complain ... */ 2210 2211 iSize = HUFv05_readStats(weightList, HUFv05_MAX_SYMBOL_VALUE + 1, rankStats, &nbSymbols, &tableLog, src, srcSize); 2212 if (HUFv05_isError(iSize)) return iSize; 2213 2214 /* check result */ 2215 if (tableLog > memLog) return ERROR(tableLog_tooLarge); /* DTable can't fit code depth */ 2216 2217 /* find maxWeight */ 2218 for (maxW = tableLog; rankStats[maxW]==0; maxW--) {} /* necessarily finds a solution before 0 */ 2219 2220 /* Get start index of each weight */ 2221 { 2222 U32 w, nextRankStart = 0; 2223 for (w=1; w<=maxW; w++) { 2224 U32 current = nextRankStart; 2225 nextRankStart += rankStats[w]; 2226 rankStart[w] = current; 2227 } 2228 rankStart[0] = nextRankStart; /* put all 0w symbols at the end of sorted list*/ 2229 sizeOfSort = nextRankStart; 2230 } 2231 2232 /* sort symbols by weight */ 2233 { 2234 U32 s; 2235 for (s=0; s<nbSymbols; s++) { 2236 U32 w = weightList[s]; 2237 U32 r = rankStart[w]++; 2238 sortedSymbol[r].symbol = (BYTE)s; 2239 sortedSymbol[r].weight = (BYTE)w; 2240 } 2241 rankStart[0] = 0; /* forget 0w symbols; this is beginning of weight(1) */ 2242 } 2243 2244 /* Build rankVal */ 2245 { 2246 const U32 minBits = tableLog+1 - maxW; 2247 U32 nextRankVal = 0; 2248 U32 w, consumed; 2249 const int rescale = (memLog-tableLog) - 1; /* tableLog <= memLog */ 2250 U32* rankVal0 = rankVal[0]; 2251 for (w=1; w<=maxW; w++) { 2252 U32 current = nextRankVal; 2253 nextRankVal += rankStats[w] << (w+rescale); 2254 rankVal0[w] = current; 2255 } 2256 for (consumed = minBits; consumed <= memLog - minBits; consumed++) { 2257 U32* rankValPtr = rankVal[consumed]; 2258 for (w = 1; w <= maxW; w++) { 2259 rankValPtr[w] = rankVal0[w] >> consumed; 2260 } } } 2261 2262 HUFv05_fillDTableX4(dt, memLog, 2263 sortedSymbol, sizeOfSort, 2264 rankStart0, rankVal, maxW, 2265 tableLog+1); 2266 2267 return iSize; 2268 } 2269 2270 2271 static U32 HUFv05_decodeSymbolX4(void* op, BITv05_DStream_t* DStream, const HUFv05_DEltX4* dt, const U32 dtLog) 2272 { 2273 const size_t val = BITv05_lookBitsFast(DStream, dtLog); /* note : dtLog >= 1 */ 2274 memcpy(op, dt+val, 2); 2275 BITv05_skipBits(DStream, dt[val].nbBits); 2276 return dt[val].length; 2277 } 2278 2279 static U32 HUFv05_decodeLastSymbolX4(void* op, BITv05_DStream_t* DStream, const HUFv05_DEltX4* dt, const U32 dtLog) 2280 { 2281 const size_t val = BITv05_lookBitsFast(DStream, dtLog); /* note : dtLog >= 1 */ 2282 memcpy(op, dt+val, 1); 2283 if (dt[val].length==1) BITv05_skipBits(DStream, dt[val].nbBits); 2284 else { 2285 if (DStream->bitsConsumed < (sizeof(DStream->bitContainer)*8)) { 2286 BITv05_skipBits(DStream, dt[val].nbBits); 2287 if (DStream->bitsConsumed > (sizeof(DStream->bitContainer)*8)) 2288 DStream->bitsConsumed = (sizeof(DStream->bitContainer)*8); /* ugly hack; works only because it's the last symbol. Note : can't easily extract nbBits from just this symbol */ 2289 } } 2290 return 1; 2291 } 2292 2293 2294 #define HUFv05_DECODE_SYMBOLX4_0(ptr, DStreamPtr) \ 2295 ptr += HUFv05_decodeSymbolX4(ptr, DStreamPtr, dt, dtLog) 2296 2297 #define HUFv05_DECODE_SYMBOLX4_1(ptr, DStreamPtr) \ 2298 if (MEM_64bits() || (HUFv05_MAX_TABLELOG<=12)) \ 2299 ptr += HUFv05_decodeSymbolX4(ptr, DStreamPtr, dt, dtLog) 2300 2301 #define HUFv05_DECODE_SYMBOLX4_2(ptr, DStreamPtr) \ 2302 if (MEM_64bits()) \ 2303 ptr += HUFv05_decodeSymbolX4(ptr, DStreamPtr, dt, dtLog) 2304 2305 static inline size_t HUFv05_decodeStreamX4(BYTE* p, BITv05_DStream_t* bitDPtr, BYTE* const pEnd, const HUFv05_DEltX4* const dt, const U32 dtLog) 2306 { 2307 BYTE* const pStart = p; 2308 2309 /* up to 8 symbols at a time */ 2310 while ((BITv05_reloadDStream(bitDPtr) == BITv05_DStream_unfinished) && (p < pEnd-7)) { 2311 HUFv05_DECODE_SYMBOLX4_2(p, bitDPtr); 2312 HUFv05_DECODE_SYMBOLX4_1(p, bitDPtr); 2313 HUFv05_DECODE_SYMBOLX4_2(p, bitDPtr); 2314 HUFv05_DECODE_SYMBOLX4_0(p, bitDPtr); 2315 } 2316 2317 /* closer to the end */ 2318 while ((BITv05_reloadDStream(bitDPtr) == BITv05_DStream_unfinished) && (p <= pEnd-2)) 2319 HUFv05_DECODE_SYMBOLX4_0(p, bitDPtr); 2320 2321 while (p <= pEnd-2) 2322 HUFv05_DECODE_SYMBOLX4_0(p, bitDPtr); /* no need to reload : reached the end of DStream */ 2323 2324 if (p < pEnd) 2325 p += HUFv05_decodeLastSymbolX4(p, bitDPtr, dt, dtLog); 2326 2327 return p-pStart; 2328 } 2329 2330 2331 size_t HUFv05_decompress1X4_usingDTable( 2332 void* dst, size_t dstSize, 2333 const void* cSrc, size_t cSrcSize, 2334 const U32* DTable) 2335 { 2336 const BYTE* const istart = (const BYTE*) cSrc; 2337 BYTE* const ostart = (BYTE*) dst; 2338 BYTE* const oend = ostart + dstSize; 2339 2340 const U32 dtLog = DTable[0]; 2341 const void* const dtPtr = DTable; 2342 const HUFv05_DEltX4* const dt = ((const HUFv05_DEltX4*)dtPtr) +1; 2343 size_t errorCode; 2344 2345 /* Init */ 2346 BITv05_DStream_t bitD; 2347 errorCode = BITv05_initDStream(&bitD, istart, cSrcSize); 2348 if (HUFv05_isError(errorCode)) return errorCode; 2349 2350 /* finish bitStreams one by one */ 2351 HUFv05_decodeStreamX4(ostart, &bitD, oend, dt, dtLog); 2352 2353 /* check */ 2354 if (!BITv05_endOfDStream(&bitD)) return ERROR(corruption_detected); 2355 2356 /* decoded size */ 2357 return dstSize; 2358 } 2359 2360 size_t HUFv05_decompress1X4 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) 2361 { 2362 HUFv05_CREATE_STATIC_DTABLEX4(DTable, HUFv05_MAX_TABLELOG); 2363 const BYTE* ip = (const BYTE*) cSrc; 2364 2365 size_t hSize = HUFv05_readDTableX4 (DTable, cSrc, cSrcSize); 2366 if (HUFv05_isError(hSize)) return hSize; 2367 if (hSize >= cSrcSize) return ERROR(srcSize_wrong); 2368 ip += hSize; 2369 cSrcSize -= hSize; 2370 2371 return HUFv05_decompress1X4_usingDTable (dst, dstSize, ip, cSrcSize, DTable); 2372 } 2373 2374 size_t HUFv05_decompress4X4_usingDTable( 2375 void* dst, size_t dstSize, 2376 const void* cSrc, size_t cSrcSize, 2377 const U32* DTable) 2378 { 2379 if (cSrcSize < 10) return ERROR(corruption_detected); /* strict minimum : jump table + 1 byte per stream */ 2380 2381 { 2382 const BYTE* const istart = (const BYTE*) cSrc; 2383 BYTE* const ostart = (BYTE*) dst; 2384 BYTE* const oend = ostart + dstSize; 2385 const void* const dtPtr = DTable; 2386 const HUFv05_DEltX4* const dt = ((const HUFv05_DEltX4*)dtPtr) +1; 2387 const U32 dtLog = DTable[0]; 2388 size_t errorCode; 2389 2390 /* Init */ 2391 BITv05_DStream_t bitD1; 2392 BITv05_DStream_t bitD2; 2393 BITv05_DStream_t bitD3; 2394 BITv05_DStream_t bitD4; 2395 const size_t length1 = MEM_readLE16(istart); 2396 const size_t length2 = MEM_readLE16(istart+2); 2397 const size_t length3 = MEM_readLE16(istart+4); 2398 size_t length4; 2399 const BYTE* const istart1 = istart + 6; /* jumpTable */ 2400 const BYTE* const istart2 = istart1 + length1; 2401 const BYTE* const istart3 = istart2 + length2; 2402 const BYTE* const istart4 = istart3 + length3; 2403 const size_t segmentSize = (dstSize+3) / 4; 2404 BYTE* const opStart2 = ostart + segmentSize; 2405 BYTE* const opStart3 = opStart2 + segmentSize; 2406 BYTE* const opStart4 = opStart3 + segmentSize; 2407 BYTE* op1 = ostart; 2408 BYTE* op2 = opStart2; 2409 BYTE* op3 = opStart3; 2410 BYTE* op4 = opStart4; 2411 U32 endSignal; 2412 2413 length4 = cSrcSize - (length1 + length2 + length3 + 6); 2414 if (length4 > cSrcSize) return ERROR(corruption_detected); /* overflow */ 2415 errorCode = BITv05_initDStream(&bitD1, istart1, length1); 2416 if (HUFv05_isError(errorCode)) return errorCode; 2417 errorCode = BITv05_initDStream(&bitD2, istart2, length2); 2418 if (HUFv05_isError(errorCode)) return errorCode; 2419 errorCode = BITv05_initDStream(&bitD3, istart3, length3); 2420 if (HUFv05_isError(errorCode)) return errorCode; 2421 errorCode = BITv05_initDStream(&bitD4, istart4, length4); 2422 if (HUFv05_isError(errorCode)) return errorCode; 2423 2424 /* 16-32 symbols per loop (4-8 symbols per stream) */ 2425 endSignal = BITv05_reloadDStream(&bitD1) | BITv05_reloadDStream(&bitD2) | BITv05_reloadDStream(&bitD3) | BITv05_reloadDStream(&bitD4); 2426 for ( ; (endSignal==BITv05_DStream_unfinished) && (op4<(oend-7)) ; ) { 2427 HUFv05_DECODE_SYMBOLX4_2(op1, &bitD1); 2428 HUFv05_DECODE_SYMBOLX4_2(op2, &bitD2); 2429 HUFv05_DECODE_SYMBOLX4_2(op3, &bitD3); 2430 HUFv05_DECODE_SYMBOLX4_2(op4, &bitD4); 2431 HUFv05_DECODE_SYMBOLX4_1(op1, &bitD1); 2432 HUFv05_DECODE_SYMBOLX4_1(op2, &bitD2); 2433 HUFv05_DECODE_SYMBOLX4_1(op3, &bitD3); 2434 HUFv05_DECODE_SYMBOLX4_1(op4, &bitD4); 2435 HUFv05_DECODE_SYMBOLX4_2(op1, &bitD1); 2436 HUFv05_DECODE_SYMBOLX4_2(op2, &bitD2); 2437 HUFv05_DECODE_SYMBOLX4_2(op3, &bitD3); 2438 HUFv05_DECODE_SYMBOLX4_2(op4, &bitD4); 2439 HUFv05_DECODE_SYMBOLX4_0(op1, &bitD1); 2440 HUFv05_DECODE_SYMBOLX4_0(op2, &bitD2); 2441 HUFv05_DECODE_SYMBOLX4_0(op3, &bitD3); 2442 HUFv05_DECODE_SYMBOLX4_0(op4, &bitD4); 2443 2444 endSignal = BITv05_reloadDStream(&bitD1) | BITv05_reloadDStream(&bitD2) | BITv05_reloadDStream(&bitD3) | BITv05_reloadDStream(&bitD4); 2445 } 2446 2447 /* check corruption */ 2448 if (op1 > opStart2) return ERROR(corruption_detected); 2449 if (op2 > opStart3) return ERROR(corruption_detected); 2450 if (op3 > opStart4) return ERROR(corruption_detected); 2451 /* note : op4 supposed already verified within main loop */ 2452 2453 /* finish bitStreams one by one */ 2454 HUFv05_decodeStreamX4(op1, &bitD1, opStart2, dt, dtLog); 2455 HUFv05_decodeStreamX4(op2, &bitD2, opStart3, dt, dtLog); 2456 HUFv05_decodeStreamX4(op3, &bitD3, opStart4, dt, dtLog); 2457 HUFv05_decodeStreamX4(op4, &bitD4, oend, dt, dtLog); 2458 2459 /* check */ 2460 endSignal = BITv05_endOfDStream(&bitD1) & BITv05_endOfDStream(&bitD2) & BITv05_endOfDStream(&bitD3) & BITv05_endOfDStream(&bitD4); 2461 if (!endSignal) return ERROR(corruption_detected); 2462 2463 /* decoded size */ 2464 return dstSize; 2465 } 2466 } 2467 2468 2469 size_t HUFv05_decompress4X4 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) 2470 { 2471 HUFv05_CREATE_STATIC_DTABLEX4(DTable, HUFv05_MAX_TABLELOG); 2472 const BYTE* ip = (const BYTE*) cSrc; 2473 2474 size_t hSize = HUFv05_readDTableX4 (DTable, cSrc, cSrcSize); 2475 if (HUFv05_isError(hSize)) return hSize; 2476 if (hSize >= cSrcSize) return ERROR(srcSize_wrong); 2477 ip += hSize; 2478 cSrcSize -= hSize; 2479 2480 return HUFv05_decompress4X4_usingDTable (dst, dstSize, ip, cSrcSize, DTable); 2481 } 2482 2483 2484 /* ********************************/ 2485 /* Generic decompression selector */ 2486 /* ********************************/ 2487 2488 typedef struct { U32 tableTime; U32 decode256Time; } algo_time_t; 2489 static const algo_time_t algoTime[16 /* Quantization */][3 /* single, double, quad */] = 2490 { 2491 /* single, double, quad */ 2492 {{0,0}, {1,1}, {2,2}}, /* Q==0 : impossible */ 2493 {{0,0}, {1,1}, {2,2}}, /* Q==1 : impossible */ 2494 {{ 38,130}, {1313, 74}, {2151, 38}}, /* Q == 2 : 12-18% */ 2495 {{ 448,128}, {1353, 74}, {2238, 41}}, /* Q == 3 : 18-25% */ 2496 {{ 556,128}, {1353, 74}, {2238, 47}}, /* Q == 4 : 25-32% */ 2497 {{ 714,128}, {1418, 74}, {2436, 53}}, /* Q == 5 : 32-38% */ 2498 {{ 883,128}, {1437, 74}, {2464, 61}}, /* Q == 6 : 38-44% */ 2499 {{ 897,128}, {1515, 75}, {2622, 68}}, /* Q == 7 : 44-50% */ 2500 {{ 926,128}, {1613, 75}, {2730, 75}}, /* Q == 8 : 50-56% */ 2501 {{ 947,128}, {1729, 77}, {3359, 77}}, /* Q == 9 : 56-62% */ 2502 {{1107,128}, {2083, 81}, {4006, 84}}, /* Q ==10 : 62-69% */ 2503 {{1177,128}, {2379, 87}, {4785, 88}}, /* Q ==11 : 69-75% */ 2504 {{1242,128}, {2415, 93}, {5155, 84}}, /* Q ==12 : 75-81% */ 2505 {{1349,128}, {2644,106}, {5260,106}}, /* Q ==13 : 81-87% */ 2506 {{1455,128}, {2422,124}, {4174,124}}, /* Q ==14 : 87-93% */ 2507 {{ 722,128}, {1891,145}, {1936,146}}, /* Q ==15 : 93-99% */ 2508 }; 2509 2510 typedef size_t (*decompressionAlgo)(void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); 2511 2512 size_t HUFv05_decompress (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize) 2513 { 2514 static const decompressionAlgo decompress[3] = { HUFv05_decompress4X2, HUFv05_decompress4X4, NULL }; 2515 /* estimate decompression time */ 2516 U32 Q; 2517 const U32 D256 = (U32)(dstSize >> 8); 2518 U32 Dtime[3]; 2519 U32 algoNb = 0; 2520 int n; 2521 2522 /* validation checks */ 2523 if (dstSize == 0) return ERROR(dstSize_tooSmall); 2524 if (cSrcSize >= dstSize) return ERROR(corruption_detected); /* invalid, or not compressed, but not compressed already dealt with */ 2525 if (cSrcSize == 1) { memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; } /* RLE */ 2526 2527 /* decoder timing evaluation */ 2528 Q = (U32)(cSrcSize * 16 / dstSize); /* Q < 16 since dstSize > cSrcSize */ 2529 for (n=0; n<3; n++) 2530 Dtime[n] = algoTime[Q][n].tableTime + (algoTime[Q][n].decode256Time * D256); 2531 2532 Dtime[1] += Dtime[1] >> 4; Dtime[2] += Dtime[2] >> 3; /* advantage to algorithms using less memory, for cache eviction */ 2533 2534 if (Dtime[1] < Dtime[0]) algoNb = 1; 2535 2536 return decompress[algoNb](dst, dstSize, cSrc, cSrcSize); 2537 2538 //return HUFv05_decompress4X2(dst, dstSize, cSrc, cSrcSize); /* multi-streams single-symbol decoding */ 2539 //return HUFv05_decompress4X4(dst, dstSize, cSrc, cSrcSize); /* multi-streams double-symbols decoding */ 2540 //return HUFv05_decompress4X6(dst, dstSize, cSrc, cSrcSize); /* multi-streams quad-symbols decoding */ 2541 } 2542 /* 2543 zstd - standard compression library 2544 Copyright (C) 2014-2016, Yann Collet. 2545 2546 BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) 2547 2548 Redistribution and use in source and binary forms, with or without 2549 modification, are permitted provided that the following conditions are 2550 met: 2551 * Redistributions of source code must retain the above copyright 2552 notice, this list of conditions and the following disclaimer. 2553 * Redistributions in binary form must reproduce the above 2554 copyright notice, this list of conditions and the following disclaimer 2555 in the documentation and/or other materials provided with the 2556 distribution. 2557 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2558 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2559 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2560 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2561 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2562 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2563 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2564 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2565 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2566 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2567 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2568 2569 You can contact the author at : 2570 - zstd source repository : https://github.com/Cyan4973/zstd 2571 */ 2572 2573 /* *************************************************************** 2574 * Tuning parameters 2575 *****************************************************************/ 2576 /*! 2577 * HEAPMODE : 2578 * Select how default decompression function ZSTDv05_decompress() will allocate memory, 2579 * in memory stack (0), or in memory heap (1, requires malloc()) 2580 */ 2581 #ifndef ZSTDv05_HEAPMODE 2582 # define ZSTDv05_HEAPMODE 1 2583 #endif 2584 2585 2586 /*-******************************************************* 2587 * Dependencies 2588 *********************************************************/ 2589 #include <stdlib.h> /* calloc */ 2590 #include <string.h> /* memcpy, memmove */ 2591 #include <stdio.h> /* debug only : printf */ 2592 2593 2594 /*-******************************************************* 2595 * Compiler specifics 2596 *********************************************************/ 2597 #ifdef _MSC_VER /* Visual Studio */ 2598 # include <intrin.h> /* For Visual 2005 */ 2599 # pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */ 2600 # pragma warning(disable : 4324) /* disable: C4324: padded structure */ 2601 #endif 2602 2603 2604 /*-************************************* 2605 * Local types 2606 ***************************************/ 2607 typedef struct 2608 { 2609 blockType_t blockType; 2610 U32 origSize; 2611 } blockProperties_t; 2612 2613 2614 /* ******************************************************* 2615 * Memory operations 2616 **********************************************************/ 2617 static void ZSTDv05_copy4(void* dst, const void* src) { memcpy(dst, src, 4); } 2618 2619 2620 /* ************************************* 2621 * Error Management 2622 ***************************************/ 2623 /*! ZSTDv05_isError() : 2624 * tells if a return value is an error code */ 2625 unsigned ZSTDv05_isError(size_t code) { return ERR_isError(code); } 2626 2627 2628 /*! ZSTDv05_getErrorName() : 2629 * provides error code string (useful for debugging) */ 2630 const char* ZSTDv05_getErrorName(size_t code) { return ERR_getErrorName(code); } 2631 2632 2633 /* ************************************************************* 2634 * Context management 2635 ***************************************************************/ 2636 typedef enum { ZSTDv05ds_getFrameHeaderSize, ZSTDv05ds_decodeFrameHeader, 2637 ZSTDv05ds_decodeBlockHeader, ZSTDv05ds_decompressBlock } ZSTDv05_dStage; 2638 2639 struct ZSTDv05_DCtx_s 2640 { 2641 FSEv05_DTable LLTable[FSEv05_DTABLE_SIZE_U32(LLFSEv05Log)]; 2642 FSEv05_DTable OffTable[FSEv05_DTABLE_SIZE_U32(OffFSEv05Log)]; 2643 FSEv05_DTable MLTable[FSEv05_DTABLE_SIZE_U32(MLFSEv05Log)]; 2644 unsigned hufTableX4[HUFv05_DTABLE_SIZE(HufLog)]; 2645 const void* previousDstEnd; 2646 const void* base; 2647 const void* vBase; 2648 const void* dictEnd; 2649 size_t expected; 2650 size_t headerSize; 2651 ZSTDv05_parameters params; 2652 blockType_t bType; /* used in ZSTDv05_decompressContinue(), to transfer blockType between header decoding and block decoding stages */ 2653 ZSTDv05_dStage stage; 2654 U32 flagStaticTables; 2655 const BYTE* litPtr; 2656 size_t litSize; 2657 BYTE litBuffer[BLOCKSIZE + WILDCOPY_OVERLENGTH]; 2658 BYTE headerBuffer[ZSTDv05_frameHeaderSize_max]; 2659 }; /* typedef'd to ZSTDv05_DCtx within "zstd_static.h" */ 2660 2661 size_t ZSTDv05_sizeofDCtx (void) { return sizeof(ZSTDv05_DCtx); } 2662 2663 size_t ZSTDv05_decompressBegin(ZSTDv05_DCtx* dctx) 2664 { 2665 dctx->expected = ZSTDv05_frameHeaderSize_min; 2666 dctx->stage = ZSTDv05ds_getFrameHeaderSize; 2667 dctx->previousDstEnd = NULL; 2668 dctx->base = NULL; 2669 dctx->vBase = NULL; 2670 dctx->dictEnd = NULL; 2671 dctx->hufTableX4[0] = HufLog; 2672 dctx->flagStaticTables = 0; 2673 return 0; 2674 } 2675 2676 ZSTDv05_DCtx* ZSTDv05_createDCtx(void) 2677 { 2678 ZSTDv05_DCtx* dctx = (ZSTDv05_DCtx*)malloc(sizeof(ZSTDv05_DCtx)); 2679 if (dctx==NULL) return NULL; 2680 ZSTDv05_decompressBegin(dctx); 2681 return dctx; 2682 } 2683 2684 size_t ZSTDv05_freeDCtx(ZSTDv05_DCtx* dctx) 2685 { 2686 free(dctx); 2687 return 0; /* reserved as a potential error code in the future */ 2688 } 2689 2690 void ZSTDv05_copyDCtx(ZSTDv05_DCtx* dstDCtx, const ZSTDv05_DCtx* srcDCtx) 2691 { 2692 memcpy(dstDCtx, srcDCtx, 2693 sizeof(ZSTDv05_DCtx) - (BLOCKSIZE+WILDCOPY_OVERLENGTH + ZSTDv05_frameHeaderSize_max)); /* no need to copy workspace */ 2694 } 2695 2696 2697 /* ************************************************************* 2698 * Decompression section 2699 ***************************************************************/ 2700 2701 /* Frame format description 2702 Frame Header - [ Block Header - Block ] - Frame End 2703 1) Frame Header 2704 - 4 bytes - Magic Number : ZSTDv05_MAGICNUMBER (defined within zstd_internal.h) 2705 - 1 byte - Window Descriptor 2706 2) Block Header 2707 - 3 bytes, starting with a 2-bits descriptor 2708 Uncompressed, Compressed, Frame End, unused 2709 3) Block 2710 See Block Format Description 2711 4) Frame End 2712 - 3 bytes, compatible with Block Header 2713 */ 2714 2715 /* Block format description 2716 2717 Block = Literal Section - Sequences Section 2718 Prerequisite : size of (compressed) block, maximum size of regenerated data 2719 2720 1) Literal Section 2721 2722 1.1) Header : 1-5 bytes 2723 flags: 2 bits 2724 00 compressed by Huff0 2725 01 unused 2726 10 is Raw (uncompressed) 2727 11 is Rle 2728 Note : using 01 => Huff0 with precomputed table ? 2729 Note : delta map ? => compressed ? 2730 2731 1.1.1) Huff0-compressed literal block : 3-5 bytes 2732 srcSize < 1 KB => 3 bytes (2-2-10-10) => single stream 2733 srcSize < 1 KB => 3 bytes (2-2-10-10) 2734 srcSize < 16KB => 4 bytes (2-2-14-14) 2735 else => 5 bytes (2-2-18-18) 2736 big endian convention 2737 2738 1.1.2) Raw (uncompressed) literal block header : 1-3 bytes 2739 size : 5 bits: (IS_RAW<<6) + (0<<4) + size 2740 12 bits: (IS_RAW<<6) + (2<<4) + (size>>8) 2741 size&255 2742 20 bits: (IS_RAW<<6) + (3<<4) + (size>>16) 2743 size>>8&255 2744 size&255 2745 2746 1.1.3) Rle (repeated single byte) literal block header : 1-3 bytes 2747 size : 5 bits: (IS_RLE<<6) + (0<<4) + size 2748 12 bits: (IS_RLE<<6) + (2<<4) + (size>>8) 2749 size&255 2750 20 bits: (IS_RLE<<6) + (3<<4) + (size>>16) 2751 size>>8&255 2752 size&255 2753 2754 1.1.4) Huff0-compressed literal block, using precomputed CTables : 3-5 bytes 2755 srcSize < 1 KB => 3 bytes (2-2-10-10) => single stream 2756 srcSize < 1 KB => 3 bytes (2-2-10-10) 2757 srcSize < 16KB => 4 bytes (2-2-14-14) 2758 else => 5 bytes (2-2-18-18) 2759 big endian convention 2760 2761 1- CTable available (stored into workspace ?) 2762 2- Small input (fast heuristic ? Full comparison ? depend on clevel ?) 2763 2764 2765 1.2) Literal block content 2766 2767 1.2.1) Huff0 block, using sizes from header 2768 See Huff0 format 2769 2770 1.2.2) Huff0 block, using prepared table 2771 2772 1.2.3) Raw content 2773 2774 1.2.4) single byte 2775 2776 2777 2) Sequences section 2778 TO DO 2779 */ 2780 2781 2782 /** ZSTDv05_decodeFrameHeader_Part1() : 2783 * decode the 1st part of the Frame Header, which tells Frame Header size. 2784 * srcSize must be == ZSTDv05_frameHeaderSize_min. 2785 * @return : the full size of the Frame Header */ 2786 static size_t ZSTDv05_decodeFrameHeader_Part1(ZSTDv05_DCtx* zc, const void* src, size_t srcSize) 2787 { 2788 U32 magicNumber; 2789 if (srcSize != ZSTDv05_frameHeaderSize_min) 2790 return ERROR(srcSize_wrong); 2791 magicNumber = MEM_readLE32(src); 2792 if (magicNumber != ZSTDv05_MAGICNUMBER) return ERROR(prefix_unknown); 2793 zc->headerSize = ZSTDv05_frameHeaderSize_min; 2794 return zc->headerSize; 2795 } 2796 2797 2798 size_t ZSTDv05_getFrameParams(ZSTDv05_parameters* params, const void* src, size_t srcSize) 2799 { 2800 U32 magicNumber; 2801 if (srcSize < ZSTDv05_frameHeaderSize_min) return ZSTDv05_frameHeaderSize_max; 2802 magicNumber = MEM_readLE32(src); 2803 if (magicNumber != ZSTDv05_MAGICNUMBER) return ERROR(prefix_unknown); 2804 memset(params, 0, sizeof(*params)); 2805 params->windowLog = (((const BYTE*)src)[4] & 15) + ZSTDv05_WINDOWLOG_ABSOLUTEMIN; 2806 if ((((const BYTE*)src)[4] >> 4) != 0) return ERROR(frameParameter_unsupported); /* reserved bits */ 2807 return 0; 2808 } 2809 2810 /** ZSTDv05_decodeFrameHeader_Part2() : 2811 * decode the full Frame Header. 2812 * srcSize must be the size provided by ZSTDv05_decodeFrameHeader_Part1(). 2813 * @return : 0, or an error code, which can be tested using ZSTDv05_isError() */ 2814 static size_t ZSTDv05_decodeFrameHeader_Part2(ZSTDv05_DCtx* zc, const void* src, size_t srcSize) 2815 { 2816 size_t result; 2817 if (srcSize != zc->headerSize) 2818 return ERROR(srcSize_wrong); 2819 result = ZSTDv05_getFrameParams(&(zc->params), src, srcSize); 2820 if ((MEM_32bits()) && (zc->params.windowLog > 25)) return ERROR(frameParameter_unsupported); 2821 return result; 2822 } 2823 2824 2825 size_t ZSTDv05_getcBlockSize(const void* src, size_t srcSize, blockProperties_t* bpPtr) 2826 { 2827 const BYTE* const in = (const BYTE* const)src; 2828 BYTE headerFlags; 2829 U32 cSize; 2830 2831 if (srcSize < 3) 2832 return ERROR(srcSize_wrong); 2833 2834 headerFlags = *in; 2835 cSize = in[2] + (in[1]<<8) + ((in[0] & 7)<<16); 2836 2837 bpPtr->blockType = (blockType_t)(headerFlags >> 6); 2838 bpPtr->origSize = (bpPtr->blockType == bt_rle) ? cSize : 0; 2839 2840 if (bpPtr->blockType == bt_end) return 0; 2841 if (bpPtr->blockType == bt_rle) return 1; 2842 return cSize; 2843 } 2844 2845 2846 static size_t ZSTDv05_copyRawBlock(void* dst, size_t maxDstSize, const void* src, size_t srcSize) 2847 { 2848 if (srcSize > maxDstSize) return ERROR(dstSize_tooSmall); 2849 memcpy(dst, src, srcSize); 2850 return srcSize; 2851 } 2852 2853 2854 /*! ZSTDv05_decodeLiteralsBlock() : 2855 @return : nb of bytes read from src (< srcSize ) */ 2856 size_t ZSTDv05_decodeLiteralsBlock(ZSTDv05_DCtx* dctx, 2857 const void* src, size_t srcSize) /* note : srcSize < BLOCKSIZE */ 2858 { 2859 const BYTE* const istart = (const BYTE*) src; 2860 2861 /* any compressed block with literals segment must be at least this size */ 2862 if (srcSize < MIN_CBLOCK_SIZE) return ERROR(corruption_detected); 2863 2864 switch(istart[0]>> 6) 2865 { 2866 case IS_HUFv05: 2867 { 2868 size_t litSize, litCSize, singleStream=0; 2869 U32 lhSize = ((istart[0]) >> 4) & 3; 2870 if (srcSize < 5) return ERROR(corruption_detected); /* srcSize >= MIN_CBLOCK_SIZE == 3; here we need up to 5 for case 3 */ 2871 switch(lhSize) 2872 { 2873 case 0: case 1: default: /* note : default is impossible, since lhSize into [0..3] */ 2874 /* 2 - 2 - 10 - 10 */ 2875 lhSize=3; 2876 singleStream = istart[0] & 16; 2877 litSize = ((istart[0] & 15) << 6) + (istart[1] >> 2); 2878 litCSize = ((istart[1] & 3) << 8) + istart[2]; 2879 break; 2880 case 2: 2881 /* 2 - 2 - 14 - 14 */ 2882 lhSize=4; 2883 litSize = ((istart[0] & 15) << 10) + (istart[1] << 2) + (istart[2] >> 6); 2884 litCSize = ((istart[2] & 63) << 8) + istart[3]; 2885 break; 2886 case 3: 2887 /* 2 - 2 - 18 - 18 */ 2888 lhSize=5; 2889 litSize = ((istart[0] & 15) << 14) + (istart[1] << 6) + (istart[2] >> 2); 2890 litCSize = ((istart[2] & 3) << 16) + (istart[3] << 8) + istart[4]; 2891 break; 2892 } 2893 if (litSize > BLOCKSIZE) return ERROR(corruption_detected); 2894 if (litCSize + lhSize > srcSize) return ERROR(corruption_detected); 2895 2896 if (HUFv05_isError(singleStream ? 2897 HUFv05_decompress1X2(dctx->litBuffer, litSize, istart+lhSize, litCSize) : 2898 HUFv05_decompress (dctx->litBuffer, litSize, istart+lhSize, litCSize) )) 2899 return ERROR(corruption_detected); 2900 2901 dctx->litPtr = dctx->litBuffer; 2902 dctx->litSize = litSize; 2903 memset(dctx->litBuffer + dctx->litSize, 0, WILDCOPY_OVERLENGTH); 2904 return litCSize + lhSize; 2905 } 2906 case IS_PCH: 2907 { 2908 size_t errorCode; 2909 size_t litSize, litCSize; 2910 U32 lhSize = ((istart[0]) >> 4) & 3; 2911 if (lhSize != 1) /* only case supported for now : small litSize, single stream */ 2912 return ERROR(corruption_detected); 2913 if (!dctx->flagStaticTables) 2914 return ERROR(dictionary_corrupted); 2915 2916 /* 2 - 2 - 10 - 10 */ 2917 lhSize=3; 2918 litSize = ((istart[0] & 15) << 6) + (istart[1] >> 2); 2919 litCSize = ((istart[1] & 3) << 8) + istart[2]; 2920 if (litCSize + lhSize > srcSize) return ERROR(corruption_detected); 2921 2922 errorCode = HUFv05_decompress1X4_usingDTable(dctx->litBuffer, litSize, istart+lhSize, litCSize, dctx->hufTableX4); 2923 if (HUFv05_isError(errorCode)) return ERROR(corruption_detected); 2924 2925 dctx->litPtr = dctx->litBuffer; 2926 dctx->litSize = litSize; 2927 memset(dctx->litBuffer + dctx->litSize, 0, WILDCOPY_OVERLENGTH); 2928 return litCSize + lhSize; 2929 } 2930 case IS_RAW: 2931 { 2932 size_t litSize; 2933 U32 lhSize = ((istart[0]) >> 4) & 3; 2934 switch(lhSize) 2935 { 2936 case 0: case 1: default: /* note : default is impossible, since lhSize into [0..3] */ 2937 lhSize=1; 2938 litSize = istart[0] & 31; 2939 break; 2940 case 2: 2941 litSize = ((istart[0] & 15) << 8) + istart[1]; 2942 break; 2943 case 3: 2944 litSize = ((istart[0] & 15) << 16) + (istart[1] << 8) + istart[2]; 2945 break; 2946 } 2947 2948 if (lhSize+litSize+WILDCOPY_OVERLENGTH > srcSize) { /* risk reading beyond src buffer with wildcopy */ 2949 if (litSize+lhSize > srcSize) return ERROR(corruption_detected); 2950 memcpy(dctx->litBuffer, istart+lhSize, litSize); 2951 dctx->litPtr = dctx->litBuffer; 2952 dctx->litSize = litSize; 2953 memset(dctx->litBuffer + dctx->litSize, 0, WILDCOPY_OVERLENGTH); 2954 return lhSize+litSize; 2955 } 2956 /* direct reference into compressed stream */ 2957 dctx->litPtr = istart+lhSize; 2958 dctx->litSize = litSize; 2959 return lhSize+litSize; 2960 } 2961 case IS_RLE: 2962 { 2963 size_t litSize; 2964 U32 lhSize = ((istart[0]) >> 4) & 3; 2965 switch(lhSize) 2966 { 2967 case 0: case 1: default: /* note : default is impossible, since lhSize into [0..3] */ 2968 lhSize = 1; 2969 litSize = istart[0] & 31; 2970 break; 2971 case 2: 2972 litSize = ((istart[0] & 15) << 8) + istart[1]; 2973 break; 2974 case 3: 2975 litSize = ((istart[0] & 15) << 16) + (istart[1] << 8) + istart[2]; 2976 if (srcSize<4) return ERROR(corruption_detected); /* srcSize >= MIN_CBLOCK_SIZE == 3; here we need lhSize+1 = 4 */ 2977 break; 2978 } 2979 if (litSize > BLOCKSIZE) return ERROR(corruption_detected); 2980 memset(dctx->litBuffer, istart[lhSize], litSize + WILDCOPY_OVERLENGTH); 2981 dctx->litPtr = dctx->litBuffer; 2982 dctx->litSize = litSize; 2983 return lhSize+1; 2984 } 2985 default: 2986 return ERROR(corruption_detected); /* impossible */ 2987 } 2988 } 2989 2990 2991 size_t ZSTDv05_decodeSeqHeaders(int* nbSeq, const BYTE** dumpsPtr, size_t* dumpsLengthPtr, 2992 FSEv05_DTable* DTableLL, FSEv05_DTable* DTableML, FSEv05_DTable* DTableOffb, 2993 const void* src, size_t srcSize, U32 flagStaticTable) 2994 { 2995 const BYTE* const istart = (const BYTE* const)src; 2996 const BYTE* ip = istart; 2997 const BYTE* const iend = istart + srcSize; 2998 U32 LLtype, Offtype, MLtype; 2999 U32 LLlog, Offlog, MLlog; 3000 size_t dumpsLength; 3001 3002 /* check */ 3003 if (srcSize < MIN_SEQUENCES_SIZE) 3004 return ERROR(srcSize_wrong); 3005 3006 /* SeqHead */ 3007 *nbSeq = *ip++; 3008 if (*nbSeq==0) return 1; 3009 if (*nbSeq >= 128) { 3010 if (ip >= iend) return ERROR(srcSize_wrong); 3011 *nbSeq = ((nbSeq[0]-128)<<8) + *ip++; 3012 } 3013 3014 if (ip >= iend) return ERROR(srcSize_wrong); 3015 LLtype = *ip >> 6; 3016 Offtype = (*ip >> 4) & 3; 3017 MLtype = (*ip >> 2) & 3; 3018 if (*ip & 2) { 3019 if (ip+3 > iend) return ERROR(srcSize_wrong); 3020 dumpsLength = ip[2]; 3021 dumpsLength += ip[1] << 8; 3022 ip += 3; 3023 } else { 3024 if (ip+2 > iend) return ERROR(srcSize_wrong); 3025 dumpsLength = ip[1]; 3026 dumpsLength += (ip[0] & 1) << 8; 3027 ip += 2; 3028 } 3029 *dumpsPtr = ip; 3030 ip += dumpsLength; 3031 *dumpsLengthPtr = dumpsLength; 3032 3033 /* check */ 3034 if (ip > iend-3) return ERROR(srcSize_wrong); /* min : all 3 are "raw", hence no header, but at least xxLog bits per type */ 3035 3036 /* sequences */ 3037 { 3038 S16 norm[MaxML+1]; /* assumption : MaxML >= MaxLL >= MaxOff */ 3039 size_t headerSize; 3040 3041 /* Build DTables */ 3042 switch(LLtype) 3043 { 3044 case FSEv05_ENCODING_RLE : 3045 LLlog = 0; 3046 FSEv05_buildDTable_rle(DTableLL, *ip++); 3047 break; 3048 case FSEv05_ENCODING_RAW : 3049 LLlog = LLbits; 3050 FSEv05_buildDTable_raw(DTableLL, LLbits); 3051 break; 3052 case FSEv05_ENCODING_STATIC: 3053 if (!flagStaticTable) return ERROR(corruption_detected); 3054 break; 3055 case FSEv05_ENCODING_DYNAMIC : 3056 default : /* impossible */ 3057 { U32 max = MaxLL; 3058 headerSize = FSEv05_readNCount(norm, &max, &LLlog, ip, iend-ip); 3059 if (FSEv05_isError(headerSize)) return ERROR(GENERIC); 3060 if (LLlog > LLFSEv05Log) return ERROR(corruption_detected); 3061 ip += headerSize; 3062 FSEv05_buildDTable(DTableLL, norm, max, LLlog); 3063 } } 3064 3065 switch(Offtype) 3066 { 3067 case FSEv05_ENCODING_RLE : 3068 Offlog = 0; 3069 if (ip > iend-2) return ERROR(srcSize_wrong); /* min : "raw", hence no header, but at least xxLog bits */ 3070 FSEv05_buildDTable_rle(DTableOffb, *ip++ & MaxOff); /* if *ip > MaxOff, data is corrupted */ 3071 break; 3072 case FSEv05_ENCODING_RAW : 3073 Offlog = Offbits; 3074 FSEv05_buildDTable_raw(DTableOffb, Offbits); 3075 break; 3076 case FSEv05_ENCODING_STATIC: 3077 if (!flagStaticTable) return ERROR(corruption_detected); 3078 break; 3079 case FSEv05_ENCODING_DYNAMIC : 3080 default : /* impossible */ 3081 { U32 max = MaxOff; 3082 headerSize = FSEv05_readNCount(norm, &max, &Offlog, ip, iend-ip); 3083 if (FSEv05_isError(headerSize)) return ERROR(GENERIC); 3084 if (Offlog > OffFSEv05Log) return ERROR(corruption_detected); 3085 ip += headerSize; 3086 FSEv05_buildDTable(DTableOffb, norm, max, Offlog); 3087 } } 3088 3089 switch(MLtype) 3090 { 3091 case FSEv05_ENCODING_RLE : 3092 MLlog = 0; 3093 if (ip > iend-2) return ERROR(srcSize_wrong); /* min : "raw", hence no header, but at least xxLog bits */ 3094 FSEv05_buildDTable_rle(DTableML, *ip++); 3095 break; 3096 case FSEv05_ENCODING_RAW : 3097 MLlog = MLbits; 3098 FSEv05_buildDTable_raw(DTableML, MLbits); 3099 break; 3100 case FSEv05_ENCODING_STATIC: 3101 if (!flagStaticTable) return ERROR(corruption_detected); 3102 break; 3103 case FSEv05_ENCODING_DYNAMIC : 3104 default : /* impossible */ 3105 { U32 max = MaxML; 3106 headerSize = FSEv05_readNCount(norm, &max, &MLlog, ip, iend-ip); 3107 if (FSEv05_isError(headerSize)) return ERROR(GENERIC); 3108 if (MLlog > MLFSEv05Log) return ERROR(corruption_detected); 3109 ip += headerSize; 3110 FSEv05_buildDTable(DTableML, norm, max, MLlog); 3111 } } } 3112 3113 return ip-istart; 3114 } 3115 3116 3117 typedef struct { 3118 size_t litLength; 3119 size_t matchLength; 3120 size_t offset; 3121 } seq_t; 3122 3123 typedef struct { 3124 BITv05_DStream_t DStream; 3125 FSEv05_DState_t stateLL; 3126 FSEv05_DState_t stateOffb; 3127 FSEv05_DState_t stateML; 3128 size_t prevOffset; 3129 const BYTE* dumps; 3130 const BYTE* dumpsEnd; 3131 } seqState_t; 3132 3133 3134 3135 static void ZSTDv05_decodeSequence(seq_t* seq, seqState_t* seqState) 3136 { 3137 size_t litLength; 3138 size_t prevOffset; 3139 size_t offset; 3140 size_t matchLength; 3141 const BYTE* dumps = seqState->dumps; 3142 const BYTE* const de = seqState->dumpsEnd; 3143 3144 /* Literal length */ 3145 litLength = FSEv05_peakSymbol(&(seqState->stateLL)); 3146 prevOffset = litLength ? seq->offset : seqState->prevOffset; 3147 if (litLength == MaxLL) { 3148 U32 add = *dumps++; 3149 if (add < 255) litLength += add; 3150 else { 3151 litLength = MEM_readLE32(dumps) & 0xFFFFFF; /* no risk : dumps is always followed by seq tables > 1 byte */ 3152 if (litLength&1) litLength>>=1, dumps += 3; 3153 else litLength = (U16)(litLength)>>1, dumps += 2; 3154 } 3155 if (dumps > de) { litLength = MaxLL+255; } /* late correction, to avoid using uninitialized memory */ 3156 if (dumps >= de) { dumps = de-1; } /* late correction, to avoid read overflow (data is now corrupted anyway) */ 3157 } 3158 3159 /* Offset */ 3160 { 3161 static const U32 offsetPrefix[MaxOff+1] = { 3162 1 /*fake*/, 1, 2, 4, 8, 16, 32, 64, 128, 256, 3163 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 3164 524288, 1048576, 2097152, 4194304, 8388608, 16777216, 33554432, /*fake*/ 1, 1, 1, 1, 1 }; 3165 U32 offsetCode = FSEv05_peakSymbol(&(seqState->stateOffb)); /* <= maxOff, by table construction */ 3166 U32 nbBits = offsetCode - 1; 3167 if (offsetCode==0) nbBits = 0; /* cmove */ 3168 offset = offsetPrefix[offsetCode] + BITv05_readBits(&(seqState->DStream), nbBits); 3169 if (MEM_32bits()) BITv05_reloadDStream(&(seqState->DStream)); 3170 if (offsetCode==0) offset = prevOffset; /* repcode, cmove */ 3171 if (offsetCode | !litLength) seqState->prevOffset = seq->offset; /* cmove */ 3172 FSEv05_decodeSymbol(&(seqState->stateOffb), &(seqState->DStream)); /* update */ 3173 } 3174 3175 /* Literal length update */ 3176 FSEv05_decodeSymbol(&(seqState->stateLL), &(seqState->DStream)); /* update */ 3177 if (MEM_32bits()) BITv05_reloadDStream(&(seqState->DStream)); 3178 3179 /* MatchLength */ 3180 matchLength = FSEv05_decodeSymbol(&(seqState->stateML), &(seqState->DStream)); 3181 if (matchLength == MaxML) { 3182 U32 add = *dumps++; 3183 if (add < 255) matchLength += add; 3184 else { 3185 matchLength = MEM_readLE32(dumps) & 0xFFFFFF; /* no pb : dumps is always followed by seq tables > 1 byte */ 3186 if (matchLength&1) matchLength>>=1, dumps += 3; 3187 else matchLength = (U16)(matchLength)>>1, dumps += 2; 3188 } 3189 if (dumps > de) { matchLength = MaxML+255; } /* late correction, to avoid using uninitialized memory */ 3190 if (dumps >= de) { dumps = de-1; } /* late correction, to avoid read overflow (data is now corrupted anyway) */ 3191 } 3192 matchLength += MINMATCH; 3193 3194 /* save result */ 3195 seq->litLength = litLength; 3196 seq->offset = offset; 3197 seq->matchLength = matchLength; 3198 seqState->dumps = dumps; 3199 3200 #if 0 /* debug */ 3201 { 3202 static U64 totalDecoded = 0; 3203 printf("pos %6u : %3u literals & match %3u bytes at distance %6u \n", 3204 (U32)(totalDecoded), (U32)litLength, (U32)matchLength, (U32)offset); 3205 totalDecoded += litLength + matchLength; 3206 } 3207 #endif 3208 } 3209 3210 3211 static size_t ZSTDv05_execSequence(BYTE* op, 3212 BYTE* const oend, seq_t sequence, 3213 const BYTE** litPtr, const BYTE* const litLimit, 3214 const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd) 3215 { 3216 static const int dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 }; /* added */ 3217 static const int dec64table[] = { 8, 8, 8, 7, 8, 9,10,11 }; /* substracted */ 3218 BYTE* const oLitEnd = op + sequence.litLength; 3219 const size_t sequenceLength = sequence.litLength + sequence.matchLength; 3220 BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */ 3221 BYTE* const oend_8 = oend-8; 3222 const BYTE* const litEnd = *litPtr + sequence.litLength; 3223 const BYTE* match = oLitEnd - sequence.offset; 3224 3225 /* check */ 3226 if (oLitEnd > oend_8) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of 8 from oend */ 3227 if (oMatchEnd > oend) return ERROR(dstSize_tooSmall); /* overwrite beyond dst buffer */ 3228 if (litEnd > litLimit) return ERROR(corruption_detected); /* risk read beyond lit buffer */ 3229 3230 /* copy Literals */ 3231 ZSTDv05_wildcopy(op, *litPtr, sequence.litLength); /* note : oLitEnd <= oend-8 : no risk of overwrite beyond oend */ 3232 op = oLitEnd; 3233 *litPtr = litEnd; /* update for next sequence */ 3234 3235 /* copy Match */ 3236 if (sequence.offset > (size_t)(oLitEnd - base)) { 3237 /* offset beyond prefix */ 3238 if (sequence.offset > (size_t)(oLitEnd - vBase)) 3239 return ERROR(corruption_detected); 3240 match = dictEnd - (base-match); 3241 if (match + sequence.matchLength <= dictEnd) { 3242 memmove(oLitEnd, match, sequence.matchLength); 3243 return sequenceLength; 3244 } 3245 /* span extDict & currentPrefixSegment */ 3246 { 3247 size_t length1 = dictEnd - match; 3248 memmove(oLitEnd, match, length1); 3249 op = oLitEnd + length1; 3250 sequence.matchLength -= length1; 3251 match = base; 3252 if (op > oend_8 || sequence.matchLength < MINMATCH) { 3253 while (op < oMatchEnd) *op++ = *match++; 3254 return sequenceLength; 3255 } 3256 } } 3257 /* Requirement: op <= oend_8 */ 3258 3259 /* match within prefix */ 3260 if (sequence.offset < 8) { 3261 /* close range match, overlap */ 3262 const int sub2 = dec64table[sequence.offset]; 3263 op[0] = match[0]; 3264 op[1] = match[1]; 3265 op[2] = match[2]; 3266 op[3] = match[3]; 3267 match += dec32table[sequence.offset]; 3268 ZSTDv05_copy4(op+4, match); 3269 match -= sub2; 3270 } else { 3271 ZSTDv05_copy8(op, match); 3272 } 3273 op += 8; match += 8; 3274 3275 if (oMatchEnd > oend-(16-MINMATCH)) { 3276 if (op < oend_8) { 3277 ZSTDv05_wildcopy(op, match, oend_8 - op); 3278 match += oend_8 - op; 3279 op = oend_8; 3280 } 3281 while (op < oMatchEnd) 3282 *op++ = *match++; 3283 } else { 3284 ZSTDv05_wildcopy(op, match, (ptrdiff_t)sequence.matchLength-8); /* works even if matchLength < 8 */ 3285 } 3286 return sequenceLength; 3287 } 3288 3289 3290 static size_t ZSTDv05_decompressSequences( 3291 ZSTDv05_DCtx* dctx, 3292 void* dst, size_t maxDstSize, 3293 const void* seqStart, size_t seqSize) 3294 { 3295 const BYTE* ip = (const BYTE*)seqStart; 3296 const BYTE* const iend = ip + seqSize; 3297 BYTE* const ostart = (BYTE* const)dst; 3298 BYTE* op = ostart; 3299 BYTE* const oend = ostart + maxDstSize; 3300 size_t errorCode, dumpsLength; 3301 const BYTE* litPtr = dctx->litPtr; 3302 const BYTE* const litEnd = litPtr + dctx->litSize; 3303 int nbSeq; 3304 const BYTE* dumps; 3305 U32* DTableLL = dctx->LLTable; 3306 U32* DTableML = dctx->MLTable; 3307 U32* DTableOffb = dctx->OffTable; 3308 const BYTE* const base = (const BYTE*) (dctx->base); 3309 const BYTE* const vBase = (const BYTE*) (dctx->vBase); 3310 const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd); 3311 3312 /* Build Decoding Tables */ 3313 errorCode = ZSTDv05_decodeSeqHeaders(&nbSeq, &dumps, &dumpsLength, 3314 DTableLL, DTableML, DTableOffb, 3315 ip, seqSize, dctx->flagStaticTables); 3316 if (ZSTDv05_isError(errorCode)) return errorCode; 3317 ip += errorCode; 3318 3319 /* Regen sequences */ 3320 if (nbSeq) { 3321 seq_t sequence; 3322 seqState_t seqState; 3323 3324 memset(&sequence, 0, sizeof(sequence)); 3325 sequence.offset = REPCODE_STARTVALUE; 3326 seqState.dumps = dumps; 3327 seqState.dumpsEnd = dumps + dumpsLength; 3328 seqState.prevOffset = REPCODE_STARTVALUE; 3329 errorCode = BITv05_initDStream(&(seqState.DStream), ip, iend-ip); 3330 if (ERR_isError(errorCode)) return ERROR(corruption_detected); 3331 FSEv05_initDState(&(seqState.stateLL), &(seqState.DStream), DTableLL); 3332 FSEv05_initDState(&(seqState.stateOffb), &(seqState.DStream), DTableOffb); 3333 FSEv05_initDState(&(seqState.stateML), &(seqState.DStream), DTableML); 3334 3335 for ( ; (BITv05_reloadDStream(&(seqState.DStream)) <= BITv05_DStream_completed) && nbSeq ; ) { 3336 size_t oneSeqSize; 3337 nbSeq--; 3338 ZSTDv05_decodeSequence(&sequence, &seqState); 3339 oneSeqSize = ZSTDv05_execSequence(op, oend, sequence, &litPtr, litEnd, base, vBase, dictEnd); 3340 if (ZSTDv05_isError(oneSeqSize)) return oneSeqSize; 3341 op += oneSeqSize; 3342 } 3343 3344 /* check if reached exact end */ 3345 if (nbSeq) return ERROR(corruption_detected); 3346 } 3347 3348 /* last literal segment */ 3349 { 3350 size_t lastLLSize = litEnd - litPtr; 3351 if (litPtr > litEnd) return ERROR(corruption_detected); /* too many literals already used */ 3352 if (op+lastLLSize > oend) return ERROR(dstSize_tooSmall); 3353 memcpy(op, litPtr, lastLLSize); 3354 op += lastLLSize; 3355 } 3356 3357 return op-ostart; 3358 } 3359 3360 3361 static void ZSTDv05_checkContinuity(ZSTDv05_DCtx* dctx, const void* dst) 3362 { 3363 if (dst != dctx->previousDstEnd) { /* not contiguous */ 3364 dctx->dictEnd = dctx->previousDstEnd; 3365 dctx->vBase = (const char*)dst - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->base)); 3366 dctx->base = dst; 3367 dctx->previousDstEnd = dst; 3368 } 3369 } 3370 3371 3372 static size_t ZSTDv05_decompressBlock_internal(ZSTDv05_DCtx* dctx, 3373 void* dst, size_t dstCapacity, 3374 const void* src, size_t srcSize) 3375 { /* blockType == blockCompressed */ 3376 const BYTE* ip = (const BYTE*)src; 3377 size_t litCSize; 3378 3379 if (srcSize >= BLOCKSIZE) return ERROR(srcSize_wrong); 3380 3381 /* Decode literals sub-block */ 3382 litCSize = ZSTDv05_decodeLiteralsBlock(dctx, src, srcSize); 3383 if (ZSTDv05_isError(litCSize)) return litCSize; 3384 ip += litCSize; 3385 srcSize -= litCSize; 3386 3387 return ZSTDv05_decompressSequences(dctx, dst, dstCapacity, ip, srcSize); 3388 } 3389 3390 3391 size_t ZSTDv05_decompressBlock(ZSTDv05_DCtx* dctx, 3392 void* dst, size_t dstCapacity, 3393 const void* src, size_t srcSize) 3394 { 3395 ZSTDv05_checkContinuity(dctx, dst); 3396 return ZSTDv05_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize); 3397 } 3398 3399 3400 /*! ZSTDv05_decompress_continueDCtx 3401 * dctx must have been properly initialized */ 3402 static size_t ZSTDv05_decompress_continueDCtx(ZSTDv05_DCtx* dctx, 3403 void* dst, size_t maxDstSize, 3404 const void* src, size_t srcSize) 3405 { 3406 const BYTE* ip = (const BYTE*)src; 3407 const BYTE* iend = ip + srcSize; 3408 BYTE* const ostart = (BYTE* const)dst; 3409 BYTE* op = ostart; 3410 BYTE* const oend = ostart + maxDstSize; 3411 size_t remainingSize = srcSize; 3412 blockProperties_t blockProperties; 3413 3414 /* Frame Header */ 3415 { 3416 size_t frameHeaderSize; 3417 if (srcSize < ZSTDv05_frameHeaderSize_min+ZSTDv05_blockHeaderSize) return ERROR(srcSize_wrong); 3418 frameHeaderSize = ZSTDv05_decodeFrameHeader_Part1(dctx, src, ZSTDv05_frameHeaderSize_min); 3419 if (ZSTDv05_isError(frameHeaderSize)) return frameHeaderSize; 3420 if (srcSize < frameHeaderSize+ZSTDv05_blockHeaderSize) return ERROR(srcSize_wrong); 3421 ip += frameHeaderSize; remainingSize -= frameHeaderSize; 3422 frameHeaderSize = ZSTDv05_decodeFrameHeader_Part2(dctx, src, frameHeaderSize); 3423 if (ZSTDv05_isError(frameHeaderSize)) return frameHeaderSize; 3424 } 3425 3426 /* Loop on each block */ 3427 while (1) 3428 { 3429 size_t decodedSize=0; 3430 size_t cBlockSize = ZSTDv05_getcBlockSize(ip, iend-ip, &blockProperties); 3431 if (ZSTDv05_isError(cBlockSize)) return cBlockSize; 3432 3433 ip += ZSTDv05_blockHeaderSize; 3434 remainingSize -= ZSTDv05_blockHeaderSize; 3435 if (cBlockSize > remainingSize) return ERROR(srcSize_wrong); 3436 3437 switch(blockProperties.blockType) 3438 { 3439 case bt_compressed: 3440 decodedSize = ZSTDv05_decompressBlock_internal(dctx, op, oend-op, ip, cBlockSize); 3441 break; 3442 case bt_raw : 3443 decodedSize = ZSTDv05_copyRawBlock(op, oend-op, ip, cBlockSize); 3444 break; 3445 case bt_rle : 3446 return ERROR(GENERIC); /* not yet supported */ 3447 break; 3448 case bt_end : 3449 /* end of frame */ 3450 if (remainingSize) return ERROR(srcSize_wrong); 3451 break; 3452 default: 3453 return ERROR(GENERIC); /* impossible */ 3454 } 3455 if (cBlockSize == 0) break; /* bt_end */ 3456 3457 if (ZSTDv05_isError(decodedSize)) return decodedSize; 3458 op += decodedSize; 3459 ip += cBlockSize; 3460 remainingSize -= cBlockSize; 3461 } 3462 3463 return op-ostart; 3464 } 3465 3466 3467 size_t ZSTDv05_decompress_usingPreparedDCtx(ZSTDv05_DCtx* dctx, const ZSTDv05_DCtx* refDCtx, 3468 void* dst, size_t maxDstSize, 3469 const void* src, size_t srcSize) 3470 { 3471 ZSTDv05_copyDCtx(dctx, refDCtx); 3472 ZSTDv05_checkContinuity(dctx, dst); 3473 return ZSTDv05_decompress_continueDCtx(dctx, dst, maxDstSize, src, srcSize); 3474 } 3475 3476 3477 size_t ZSTDv05_decompress_usingDict(ZSTDv05_DCtx* dctx, 3478 void* dst, size_t maxDstSize, 3479 const void* src, size_t srcSize, 3480 const void* dict, size_t dictSize) 3481 { 3482 ZSTDv05_decompressBegin_usingDict(dctx, dict, dictSize); 3483 ZSTDv05_checkContinuity(dctx, dst); 3484 return ZSTDv05_decompress_continueDCtx(dctx, dst, maxDstSize, src, srcSize); 3485 } 3486 3487 3488 size_t ZSTDv05_decompressDCtx(ZSTDv05_DCtx* dctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize) 3489 { 3490 return ZSTDv05_decompress_usingDict(dctx, dst, maxDstSize, src, srcSize, NULL, 0); 3491 } 3492 3493 size_t ZSTDv05_decompress(void* dst, size_t maxDstSize, const void* src, size_t srcSize) 3494 { 3495 #if defined(ZSTDv05_HEAPMODE) && (ZSTDv05_HEAPMODE==1) 3496 size_t regenSize; 3497 ZSTDv05_DCtx* dctx = ZSTDv05_createDCtx(); 3498 if (dctx==NULL) return ERROR(memory_allocation); 3499 regenSize = ZSTDv05_decompressDCtx(dctx, dst, maxDstSize, src, srcSize); 3500 ZSTDv05_freeDCtx(dctx); 3501 return regenSize; 3502 #else 3503 ZSTDv05_DCtx dctx; 3504 return ZSTDv05_decompressDCtx(&dctx, dst, maxDstSize, src, srcSize); 3505 #endif 3506 } 3507 3508 size_t ZSTDv05_findFrameCompressedSize(const void *src, size_t srcSize) 3509 { 3510 const BYTE* ip = (const BYTE*)src; 3511 size_t remainingSize = srcSize; 3512 blockProperties_t blockProperties; 3513 3514 /* Frame Header */ 3515 if (srcSize < ZSTDv05_frameHeaderSize_min) return ERROR(srcSize_wrong); 3516 if (MEM_readLE32(src) != ZSTDv05_MAGICNUMBER) return ERROR(prefix_unknown); 3517 ip += ZSTDv05_frameHeaderSize_min; remainingSize -= ZSTDv05_frameHeaderSize_min; 3518 3519 /* Loop on each block */ 3520 while (1) 3521 { 3522 size_t cBlockSize = ZSTDv05_getcBlockSize(ip, remainingSize, &blockProperties); 3523 if (ZSTDv05_isError(cBlockSize)) return cBlockSize; 3524 3525 ip += ZSTDv05_blockHeaderSize; 3526 remainingSize -= ZSTDv05_blockHeaderSize; 3527 if (cBlockSize > remainingSize) return ERROR(srcSize_wrong); 3528 3529 if (cBlockSize == 0) break; /* bt_end */ 3530 3531 ip += cBlockSize; 3532 remainingSize -= cBlockSize; 3533 } 3534 3535 return ip - (const BYTE*)src; 3536 } 3537 3538 /* ****************************** 3539 * Streaming Decompression API 3540 ********************************/ 3541 size_t ZSTDv05_nextSrcSizeToDecompress(ZSTDv05_DCtx* dctx) 3542 { 3543 return dctx->expected; 3544 } 3545 3546 size_t ZSTDv05_decompressContinue(ZSTDv05_DCtx* dctx, void* dst, size_t maxDstSize, const void* src, size_t srcSize) 3547 { 3548 /* Sanity check */ 3549 if (srcSize != dctx->expected) return ERROR(srcSize_wrong); 3550 ZSTDv05_checkContinuity(dctx, dst); 3551 3552 /* Decompress : frame header; part 1 */ 3553 switch (dctx->stage) 3554 { 3555 case ZSTDv05ds_getFrameHeaderSize : 3556 /* get frame header size */ 3557 if (srcSize != ZSTDv05_frameHeaderSize_min) return ERROR(srcSize_wrong); /* impossible */ 3558 dctx->headerSize = ZSTDv05_decodeFrameHeader_Part1(dctx, src, ZSTDv05_frameHeaderSize_min); 3559 if (ZSTDv05_isError(dctx->headerSize)) return dctx->headerSize; 3560 memcpy(dctx->headerBuffer, src, ZSTDv05_frameHeaderSize_min); 3561 if (dctx->headerSize > ZSTDv05_frameHeaderSize_min) return ERROR(GENERIC); /* should never happen */ 3562 dctx->expected = 0; /* not necessary to copy more */ 3563 /* fallthrough */ 3564 case ZSTDv05ds_decodeFrameHeader: 3565 /* get frame header */ 3566 { size_t const result = ZSTDv05_decodeFrameHeader_Part2(dctx, dctx->headerBuffer, dctx->headerSize); 3567 if (ZSTDv05_isError(result)) return result; 3568 dctx->expected = ZSTDv05_blockHeaderSize; 3569 dctx->stage = ZSTDv05ds_decodeBlockHeader; 3570 return 0; 3571 } 3572 case ZSTDv05ds_decodeBlockHeader: 3573 { 3574 /* Decode block header */ 3575 blockProperties_t bp; 3576 size_t blockSize = ZSTDv05_getcBlockSize(src, ZSTDv05_blockHeaderSize, &bp); 3577 if (ZSTDv05_isError(blockSize)) return blockSize; 3578 if (bp.blockType == bt_end) { 3579 dctx->expected = 0; 3580 dctx->stage = ZSTDv05ds_getFrameHeaderSize; 3581 } 3582 else { 3583 dctx->expected = blockSize; 3584 dctx->bType = bp.blockType; 3585 dctx->stage = ZSTDv05ds_decompressBlock; 3586 } 3587 return 0; 3588 } 3589 case ZSTDv05ds_decompressBlock: 3590 { 3591 /* Decompress : block content */ 3592 size_t rSize; 3593 switch(dctx->bType) 3594 { 3595 case bt_compressed: 3596 rSize = ZSTDv05_decompressBlock_internal(dctx, dst, maxDstSize, src, srcSize); 3597 break; 3598 case bt_raw : 3599 rSize = ZSTDv05_copyRawBlock(dst, maxDstSize, src, srcSize); 3600 break; 3601 case bt_rle : 3602 return ERROR(GENERIC); /* not yet handled */ 3603 break; 3604 case bt_end : /* should never happen (filtered at phase 1) */ 3605 rSize = 0; 3606 break; 3607 default: 3608 return ERROR(GENERIC); /* impossible */ 3609 } 3610 dctx->stage = ZSTDv05ds_decodeBlockHeader; 3611 dctx->expected = ZSTDv05_blockHeaderSize; 3612 dctx->previousDstEnd = (char*)dst + rSize; 3613 return rSize; 3614 } 3615 default: 3616 return ERROR(GENERIC); /* impossible */ 3617 } 3618 } 3619 3620 3621 static void ZSTDv05_refDictContent(ZSTDv05_DCtx* dctx, const void* dict, size_t dictSize) 3622 { 3623 dctx->dictEnd = dctx->previousDstEnd; 3624 dctx->vBase = (const char*)dict - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->base)); 3625 dctx->base = dict; 3626 dctx->previousDstEnd = (const char*)dict + dictSize; 3627 } 3628 3629 static size_t ZSTDv05_loadEntropy(ZSTDv05_DCtx* dctx, const void* dict, size_t dictSize) 3630 { 3631 size_t hSize, offcodeHeaderSize, matchlengthHeaderSize, errorCode, litlengthHeaderSize; 3632 short offcodeNCount[MaxOff+1]; 3633 U32 offcodeMaxValue=MaxOff, offcodeLog; 3634 short matchlengthNCount[MaxML+1]; 3635 unsigned matchlengthMaxValue = MaxML, matchlengthLog; 3636 short litlengthNCount[MaxLL+1]; 3637 unsigned litlengthMaxValue = MaxLL, litlengthLog; 3638 3639 hSize = HUFv05_readDTableX4(dctx->hufTableX4, dict, dictSize); 3640 if (HUFv05_isError(hSize)) return ERROR(dictionary_corrupted); 3641 dict = (const char*)dict + hSize; 3642 dictSize -= hSize; 3643 3644 offcodeHeaderSize = FSEv05_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dict, dictSize); 3645 if (FSEv05_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted); 3646 if (offcodeLog > OffFSEv05Log) return ERROR(dictionary_corrupted); 3647 errorCode = FSEv05_buildDTable(dctx->OffTable, offcodeNCount, offcodeMaxValue, offcodeLog); 3648 if (FSEv05_isError(errorCode)) return ERROR(dictionary_corrupted); 3649 dict = (const char*)dict + offcodeHeaderSize; 3650 dictSize -= offcodeHeaderSize; 3651 3652 matchlengthHeaderSize = FSEv05_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dict, dictSize); 3653 if (FSEv05_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted); 3654 if (matchlengthLog > MLFSEv05Log) return ERROR(dictionary_corrupted); 3655 errorCode = FSEv05_buildDTable(dctx->MLTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog); 3656 if (FSEv05_isError(errorCode)) return ERROR(dictionary_corrupted); 3657 dict = (const char*)dict + matchlengthHeaderSize; 3658 dictSize -= matchlengthHeaderSize; 3659 3660 litlengthHeaderSize = FSEv05_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dict, dictSize); 3661 if (litlengthLog > LLFSEv05Log) return ERROR(dictionary_corrupted); 3662 if (FSEv05_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted); 3663 errorCode = FSEv05_buildDTable(dctx->LLTable, litlengthNCount, litlengthMaxValue, litlengthLog); 3664 if (FSEv05_isError(errorCode)) return ERROR(dictionary_corrupted); 3665 3666 dctx->flagStaticTables = 1; 3667 return hSize + offcodeHeaderSize + matchlengthHeaderSize + litlengthHeaderSize; 3668 } 3669 3670 static size_t ZSTDv05_decompress_insertDictionary(ZSTDv05_DCtx* dctx, const void* dict, size_t dictSize) 3671 { 3672 size_t eSize; 3673 U32 magic = MEM_readLE32(dict); 3674 if (magic != ZSTDv05_DICT_MAGIC) { 3675 /* pure content mode */ 3676 ZSTDv05_refDictContent(dctx, dict, dictSize); 3677 return 0; 3678 } 3679 /* load entropy tables */ 3680 dict = (const char*)dict + 4; 3681 dictSize -= 4; 3682 eSize = ZSTDv05_loadEntropy(dctx, dict, dictSize); 3683 if (ZSTDv05_isError(eSize)) return ERROR(dictionary_corrupted); 3684 3685 /* reference dictionary content */ 3686 dict = (const char*)dict + eSize; 3687 dictSize -= eSize; 3688 ZSTDv05_refDictContent(dctx, dict, dictSize); 3689 3690 return 0; 3691 } 3692 3693 3694 size_t ZSTDv05_decompressBegin_usingDict(ZSTDv05_DCtx* dctx, const void* dict, size_t dictSize) 3695 { 3696 size_t errorCode; 3697 errorCode = ZSTDv05_decompressBegin(dctx); 3698 if (ZSTDv05_isError(errorCode)) return errorCode; 3699 3700 if (dict && dictSize) { 3701 errorCode = ZSTDv05_decompress_insertDictionary(dctx, dict, dictSize); 3702 if (ZSTDv05_isError(errorCode)) return ERROR(dictionary_corrupted); 3703 } 3704 3705 return 0; 3706 } 3707 3708 /* 3709 Buffered version of Zstd compression library 3710 Copyright (C) 2015-2016, Yann Collet. 3711 3712 BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) 3713 3714 Redistribution and use in source and binary forms, with or without 3715 modification, are permitted provided that the following conditions are 3716 met: 3717 * Redistributions of source code must retain the above copyright 3718 notice, this list of conditions and the following disclaimer. 3719 * Redistributions in binary form must reproduce the above 3720 copyright notice, this list of conditions and the following disclaimer 3721 in the documentation and/or other materials provided with the 3722 distribution. 3723 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 3724 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3725 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 3726 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3727 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3728 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3729 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3730 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3731 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3732 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3733 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3734 3735 You can contact the author at : 3736 - zstd source repository : https://github.com/Cyan4973/zstd 3737 - ztsd public forum : https://groups.google.com/forum/#!forum/lz4c 3738 */ 3739 3740 /* The objects defined into this file should be considered experimental. 3741 * They are not labelled stable, as their prototype may change in the future. 3742 * You can use them for tests, provide feedback, or if you can endure risk of future changes. 3743 */ 3744 3745 3746 3747 /* ************************************* 3748 * Constants 3749 ***************************************/ 3750 static size_t ZBUFFv05_blockHeaderSize = 3; 3751 3752 3753 3754 /* *** Compression *** */ 3755 3756 static size_t ZBUFFv05_limitCopy(void* dst, size_t maxDstSize, const void* src, size_t srcSize) 3757 { 3758 size_t length = MIN(maxDstSize, srcSize); 3759 memcpy(dst, src, length); 3760 return length; 3761 } 3762 3763 3764 3765 3766 /** ************************************************ 3767 * Streaming decompression 3768 * 3769 * A ZBUFFv05_DCtx object is required to track streaming operation. 3770 * Use ZBUFFv05_createDCtx() and ZBUFFv05_freeDCtx() to create/release resources. 3771 * Use ZBUFFv05_decompressInit() to start a new decompression operation. 3772 * ZBUFFv05_DCtx objects can be reused multiple times. 3773 * 3774 * Use ZBUFFv05_decompressContinue() repetitively to consume your input. 3775 * *srcSizePtr and *maxDstSizePtr can be any size. 3776 * The function will report how many bytes were read or written by modifying *srcSizePtr and *maxDstSizePtr. 3777 * Note that it may not consume the entire input, in which case it's up to the caller to call again the function with remaining input. 3778 * The content of dst will be overwritten (up to *maxDstSizePtr) at each function call, so save its content if it matters or change dst . 3779 * return : a hint to preferred nb of bytes to use as input for next function call (it's only a hint, to improve latency) 3780 * or 0 when a frame is completely decoded 3781 * or an error code, which can be tested using ZBUFFv05_isError(). 3782 * 3783 * Hint : recommended buffer sizes (not compulsory) 3784 * output : 128 KB block size is the internal unit, it ensures it's always possible to write a full block when it's decoded. 3785 * input : just follow indications from ZBUFFv05_decompressContinue() to minimize latency. It should always be <= 128 KB + 3 . 3786 * **************************************************/ 3787 3788 typedef enum { ZBUFFv05ds_init, ZBUFFv05ds_readHeader, ZBUFFv05ds_loadHeader, ZBUFFv05ds_decodeHeader, 3789 ZBUFFv05ds_read, ZBUFFv05ds_load, ZBUFFv05ds_flush } ZBUFFv05_dStage; 3790 3791 /* *** Resource management *** */ 3792 3793 #define ZSTDv05_frameHeaderSize_max 5 /* too magical, should come from reference */ 3794 struct ZBUFFv05_DCtx_s { 3795 ZSTDv05_DCtx* zc; 3796 ZSTDv05_parameters params; 3797 char* inBuff; 3798 size_t inBuffSize; 3799 size_t inPos; 3800 char* outBuff; 3801 size_t outBuffSize; 3802 size_t outStart; 3803 size_t outEnd; 3804 size_t hPos; 3805 ZBUFFv05_dStage stage; 3806 unsigned char headerBuffer[ZSTDv05_frameHeaderSize_max]; 3807 }; /* typedef'd to ZBUFFv05_DCtx within "zstd_buffered.h" */ 3808 3809 3810 ZBUFFv05_DCtx* ZBUFFv05_createDCtx(void) 3811 { 3812 ZBUFFv05_DCtx* zbc = (ZBUFFv05_DCtx*)malloc(sizeof(ZBUFFv05_DCtx)); 3813 if (zbc==NULL) return NULL; 3814 memset(zbc, 0, sizeof(*zbc)); 3815 zbc->zc = ZSTDv05_createDCtx(); 3816 zbc->stage = ZBUFFv05ds_init; 3817 return zbc; 3818 } 3819 3820 size_t ZBUFFv05_freeDCtx(ZBUFFv05_DCtx* zbc) 3821 { 3822 if (zbc==NULL) return 0; /* support free on null */ 3823 ZSTDv05_freeDCtx(zbc->zc); 3824 free(zbc->inBuff); 3825 free(zbc->outBuff); 3826 free(zbc); 3827 return 0; 3828 } 3829 3830 3831 /* *** Initialization *** */ 3832 3833 size_t ZBUFFv05_decompressInitDictionary(ZBUFFv05_DCtx* zbc, const void* dict, size_t dictSize) 3834 { 3835 zbc->stage = ZBUFFv05ds_readHeader; 3836 zbc->hPos = zbc->inPos = zbc->outStart = zbc->outEnd = 0; 3837 return ZSTDv05_decompressBegin_usingDict(zbc->zc, dict, dictSize); 3838 } 3839 3840 size_t ZBUFFv05_decompressInit(ZBUFFv05_DCtx* zbc) 3841 { 3842 return ZBUFFv05_decompressInitDictionary(zbc, NULL, 0); 3843 } 3844 3845 3846 /* *** Decompression *** */ 3847 3848 size_t ZBUFFv05_decompressContinue(ZBUFFv05_DCtx* zbc, void* dst, size_t* maxDstSizePtr, const void* src, size_t* srcSizePtr) 3849 { 3850 const char* const istart = (const char*)src; 3851 const char* ip = istart; 3852 const char* const iend = istart + *srcSizePtr; 3853 char* const ostart = (char*)dst; 3854 char* op = ostart; 3855 char* const oend = ostart + *maxDstSizePtr; 3856 U32 notDone = 1; 3857 3858 while (notDone) { 3859 switch(zbc->stage) 3860 { 3861 case ZBUFFv05ds_init : 3862 return ERROR(init_missing); 3863 3864 case ZBUFFv05ds_readHeader : 3865 /* read header from src */ 3866 { 3867 size_t headerSize = ZSTDv05_getFrameParams(&(zbc->params), src, *srcSizePtr); 3868 if (ZSTDv05_isError(headerSize)) return headerSize; 3869 if (headerSize) { 3870 /* not enough input to decode header : tell how many bytes would be necessary */ 3871 memcpy(zbc->headerBuffer+zbc->hPos, src, *srcSizePtr); 3872 zbc->hPos += *srcSizePtr; 3873 *maxDstSizePtr = 0; 3874 zbc->stage = ZBUFFv05ds_loadHeader; 3875 return headerSize - zbc->hPos; 3876 } 3877 zbc->stage = ZBUFFv05ds_decodeHeader; 3878 break; 3879 } 3880 /* fall-through */ 3881 case ZBUFFv05ds_loadHeader: 3882 /* complete header from src */ 3883 { 3884 size_t headerSize = ZBUFFv05_limitCopy( 3885 zbc->headerBuffer + zbc->hPos, ZSTDv05_frameHeaderSize_max - zbc->hPos, 3886 src, *srcSizePtr); 3887 zbc->hPos += headerSize; 3888 ip += headerSize; 3889 headerSize = ZSTDv05_getFrameParams(&(zbc->params), zbc->headerBuffer, zbc->hPos); 3890 if (ZSTDv05_isError(headerSize)) return headerSize; 3891 if (headerSize) { 3892 /* not enough input to decode header : tell how many bytes would be necessary */ 3893 *maxDstSizePtr = 0; 3894 return headerSize - zbc->hPos; 3895 } 3896 // zbc->stage = ZBUFFv05ds_decodeHeader; break; /* useless : stage follows */ 3897 } 3898 /* fall-through */ 3899 case ZBUFFv05ds_decodeHeader: 3900 /* apply header to create / resize buffers */ 3901 { 3902 size_t neededOutSize = (size_t)1 << zbc->params.windowLog; 3903 size_t neededInSize = BLOCKSIZE; /* a block is never > BLOCKSIZE */ 3904 if (zbc->inBuffSize < neededInSize) { 3905 free(zbc->inBuff); 3906 zbc->inBuffSize = neededInSize; 3907 zbc->inBuff = (char*)malloc(neededInSize); 3908 if (zbc->inBuff == NULL) return ERROR(memory_allocation); 3909 } 3910 if (zbc->outBuffSize < neededOutSize) { 3911 free(zbc->outBuff); 3912 zbc->outBuffSize = neededOutSize; 3913 zbc->outBuff = (char*)malloc(neededOutSize); 3914 if (zbc->outBuff == NULL) return ERROR(memory_allocation); 3915 } } 3916 if (zbc->hPos) { 3917 /* some data already loaded into headerBuffer : transfer into inBuff */ 3918 memcpy(zbc->inBuff, zbc->headerBuffer, zbc->hPos); 3919 zbc->inPos = zbc->hPos; 3920 zbc->hPos = 0; 3921 zbc->stage = ZBUFFv05ds_load; 3922 break; 3923 } 3924 zbc->stage = ZBUFFv05ds_read; 3925 /* fall-through */ 3926 case ZBUFFv05ds_read: 3927 { 3928 size_t neededInSize = ZSTDv05_nextSrcSizeToDecompress(zbc->zc); 3929 if (neededInSize==0) { /* end of frame */ 3930 zbc->stage = ZBUFFv05ds_init; 3931 notDone = 0; 3932 break; 3933 } 3934 if ((size_t)(iend-ip) >= neededInSize) { 3935 /* directly decode from src */ 3936 size_t decodedSize = ZSTDv05_decompressContinue(zbc->zc, 3937 zbc->outBuff + zbc->outStart, zbc->outBuffSize - zbc->outStart, 3938 ip, neededInSize); 3939 if (ZSTDv05_isError(decodedSize)) return decodedSize; 3940 ip += neededInSize; 3941 if (!decodedSize) break; /* this was just a header */ 3942 zbc->outEnd = zbc->outStart + decodedSize; 3943 zbc->stage = ZBUFFv05ds_flush; 3944 break; 3945 } 3946 if (ip==iend) { notDone = 0; break; } /* no more input */ 3947 zbc->stage = ZBUFFv05ds_load; 3948 } 3949 /* fall-through */ 3950 case ZBUFFv05ds_load: 3951 { 3952 size_t neededInSize = ZSTDv05_nextSrcSizeToDecompress(zbc->zc); 3953 size_t toLoad = neededInSize - zbc->inPos; /* should always be <= remaining space within inBuff */ 3954 size_t loadedSize; 3955 if (toLoad > zbc->inBuffSize - zbc->inPos) return ERROR(corruption_detected); /* should never happen */ 3956 loadedSize = ZBUFFv05_limitCopy(zbc->inBuff + zbc->inPos, toLoad, ip, iend-ip); 3957 ip += loadedSize; 3958 zbc->inPos += loadedSize; 3959 if (loadedSize < toLoad) { notDone = 0; break; } /* not enough input, wait for more */ 3960 { 3961 size_t decodedSize = ZSTDv05_decompressContinue(zbc->zc, 3962 zbc->outBuff + zbc->outStart, zbc->outBuffSize - zbc->outStart, 3963 zbc->inBuff, neededInSize); 3964 if (ZSTDv05_isError(decodedSize)) return decodedSize; 3965 zbc->inPos = 0; /* input is consumed */ 3966 if (!decodedSize) { zbc->stage = ZBUFFv05ds_read; break; } /* this was just a header */ 3967 zbc->outEnd = zbc->outStart + decodedSize; 3968 zbc->stage = ZBUFFv05ds_flush; 3969 // break; /* ZBUFFv05ds_flush follows */ 3970 } 3971 } 3972 /* fall-through */ 3973 case ZBUFFv05ds_flush: 3974 { 3975 size_t toFlushSize = zbc->outEnd - zbc->outStart; 3976 size_t flushedSize = ZBUFFv05_limitCopy(op, oend-op, zbc->outBuff + zbc->outStart, toFlushSize); 3977 op += flushedSize; 3978 zbc->outStart += flushedSize; 3979 if (flushedSize == toFlushSize) { 3980 zbc->stage = ZBUFFv05ds_read; 3981 if (zbc->outStart + BLOCKSIZE > zbc->outBuffSize) 3982 zbc->outStart = zbc->outEnd = 0; 3983 break; 3984 } 3985 /* cannot flush everything */ 3986 notDone = 0; 3987 break; 3988 } 3989 default: return ERROR(GENERIC); /* impossible */ 3990 } } 3991 3992 *srcSizePtr = ip-istart; 3993 *maxDstSizePtr = op-ostart; 3994 3995 { size_t nextSrcSizeHint = ZSTDv05_nextSrcSizeToDecompress(zbc->zc); 3996 if (nextSrcSizeHint > ZBUFFv05_blockHeaderSize) nextSrcSizeHint+= ZBUFFv05_blockHeaderSize; /* get next block header too */ 3997 nextSrcSizeHint -= zbc->inPos; /* already loaded*/ 3998 return nextSrcSizeHint; 3999 } 4000 } 4001 4002 4003 4004 /* ************************************* 4005 * Tool functions 4006 ***************************************/ 4007 unsigned ZBUFFv05_isError(size_t errorCode) { return ERR_isError(errorCode); } 4008 const char* ZBUFFv05_getErrorName(size_t errorCode) { return ERR_getErrorName(errorCode); } 4009 4010 size_t ZBUFFv05_recommendedDInSize(void) { return BLOCKSIZE + ZBUFFv05_blockHeaderSize /* block header size*/ ; } 4011 size_t ZBUFFv05_recommendedDOutSize(void) { return BLOCKSIZE; } 4012