extzstd 0.0.2.CONCEPT-x86-mingw32 → 0.0.3.CONCEPT-x86-mingw32

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