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