zstd-ruby 1.5.2.0 → 1.5.2.1

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