extzstd 0.0.3.CONCEPT → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (138) hide show
  1. checksums.yaml +5 -5
  2. data/HISTORY.ja.md +39 -0
  3. data/LICENSE +6 -6
  4. data/README.md +26 -45
  5. data/contrib/zstd/CHANGELOG +555 -0
  6. data/contrib/zstd/CODE_OF_CONDUCT.md +5 -0
  7. data/contrib/zstd/CONTRIBUTING.md +392 -0
  8. data/contrib/zstd/COPYING +339 -0
  9. data/contrib/zstd/LICENSE +13 -9
  10. data/contrib/zstd/Makefile +414 -0
  11. data/contrib/zstd/README.md +170 -45
  12. data/contrib/zstd/TESTING.md +44 -0
  13. data/contrib/zstd/appveyor.yml +289 -0
  14. data/contrib/zstd/lib/BUCK +234 -0
  15. data/contrib/zstd/lib/Makefile +354 -0
  16. data/contrib/zstd/lib/README.md +179 -0
  17. data/contrib/zstd/{common → lib/common}/bitstream.h +170 -130
  18. data/contrib/zstd/lib/common/compiler.h +175 -0
  19. data/contrib/zstd/lib/common/cpu.h +215 -0
  20. data/contrib/zstd/lib/common/debug.c +24 -0
  21. data/contrib/zstd/lib/common/debug.h +114 -0
  22. data/contrib/zstd/{common → lib/common}/entropy_common.c +79 -94
  23. data/contrib/zstd/lib/common/error_private.c +55 -0
  24. data/contrib/zstd/lib/common/error_private.h +80 -0
  25. data/contrib/zstd/{common → lib/common}/fse.h +153 -93
  26. data/contrib/zstd/{common → lib/common}/fse_decompress.c +37 -82
  27. data/contrib/zstd/lib/common/huf.h +340 -0
  28. data/contrib/zstd/{common → lib/common}/mem.h +154 -78
  29. data/contrib/zstd/lib/common/pool.c +344 -0
  30. data/contrib/zstd/lib/common/pool.h +84 -0
  31. data/contrib/zstd/lib/common/threading.c +121 -0
  32. data/contrib/zstd/lib/common/threading.h +155 -0
  33. data/contrib/zstd/{common → lib/common}/xxhash.c +85 -75
  34. data/contrib/zstd/{common → lib/common}/xxhash.h +85 -73
  35. data/contrib/zstd/lib/common/zstd_common.c +83 -0
  36. data/contrib/zstd/lib/common/zstd_errors.h +94 -0
  37. data/contrib/zstd/lib/common/zstd_internal.h +447 -0
  38. data/contrib/zstd/{compress → lib/compress}/fse_compress.c +194 -303
  39. data/contrib/zstd/lib/compress/hist.c +183 -0
  40. data/contrib/zstd/lib/compress/hist.h +75 -0
  41. data/contrib/zstd/lib/compress/huf_compress.c +798 -0
  42. data/contrib/zstd/lib/compress/zstd_compress.c +4278 -0
  43. data/contrib/zstd/lib/compress/zstd_compress_internal.h +1125 -0
  44. data/contrib/zstd/lib/compress/zstd_compress_literals.c +158 -0
  45. data/contrib/zstd/lib/compress/zstd_compress_literals.h +29 -0
  46. data/contrib/zstd/lib/compress/zstd_compress_sequences.c +419 -0
  47. data/contrib/zstd/lib/compress/zstd_compress_sequences.h +54 -0
  48. data/contrib/zstd/lib/compress/zstd_compress_superblock.c +845 -0
  49. data/contrib/zstd/lib/compress/zstd_compress_superblock.h +32 -0
  50. data/contrib/zstd/lib/compress/zstd_cwksp.h +525 -0
  51. data/contrib/zstd/lib/compress/zstd_double_fast.c +521 -0
  52. data/contrib/zstd/lib/compress/zstd_double_fast.h +38 -0
  53. data/contrib/zstd/lib/compress/zstd_fast.c +496 -0
  54. data/contrib/zstd/lib/compress/zstd_fast.h +37 -0
  55. data/contrib/zstd/lib/compress/zstd_lazy.c +1138 -0
  56. data/contrib/zstd/lib/compress/zstd_lazy.h +67 -0
  57. data/contrib/zstd/lib/compress/zstd_ldm.c +619 -0
  58. data/contrib/zstd/lib/compress/zstd_ldm.h +110 -0
  59. data/contrib/zstd/lib/compress/zstd_opt.c +1200 -0
  60. data/contrib/zstd/lib/compress/zstd_opt.h +56 -0
  61. data/contrib/zstd/lib/compress/zstdmt_compress.c +2143 -0
  62. data/contrib/zstd/lib/compress/zstdmt_compress.h +192 -0
  63. data/contrib/zstd/lib/decompress/huf_decompress.c +1248 -0
  64. data/contrib/zstd/lib/decompress/zstd_ddict.c +244 -0
  65. data/contrib/zstd/lib/decompress/zstd_ddict.h +44 -0
  66. data/contrib/zstd/lib/decompress/zstd_decompress.c +1885 -0
  67. data/contrib/zstd/lib/decompress/zstd_decompress_block.c +1432 -0
  68. data/contrib/zstd/lib/decompress/zstd_decompress_block.h +59 -0
  69. data/contrib/zstd/lib/decompress/zstd_decompress_internal.h +189 -0
  70. data/contrib/zstd/{common → lib/deprecated}/zbuff.h +86 -69
  71. data/contrib/zstd/lib/deprecated/zbuff_common.c +26 -0
  72. data/contrib/zstd/lib/deprecated/zbuff_compress.c +147 -0
  73. data/contrib/zstd/lib/deprecated/zbuff_decompress.c +75 -0
  74. data/contrib/zstd/lib/dictBuilder/cover.c +1236 -0
  75. data/contrib/zstd/lib/dictBuilder/cover.h +157 -0
  76. data/contrib/zstd/{dictBuilder → lib/dictBuilder}/divsufsort.c +3 -3
  77. data/contrib/zstd/{dictBuilder → lib/dictBuilder}/divsufsort.h +5 -5
  78. data/contrib/zstd/lib/dictBuilder/fastcover.c +757 -0
  79. data/contrib/zstd/{dictBuilder → lib/dictBuilder}/zdict.c +437 -347
  80. data/contrib/zstd/lib/dictBuilder/zdict.h +305 -0
  81. data/contrib/zstd/lib/legacy/zstd_legacy.h +415 -0
  82. data/contrib/zstd/{legacy → lib/legacy}/zstd_v01.c +272 -292
  83. data/contrib/zstd/{legacy → lib/legacy}/zstd_v01.h +26 -32
  84. data/contrib/zstd/{legacy → lib/legacy}/zstd_v02.c +162 -392
  85. data/contrib/zstd/{legacy → lib/legacy}/zstd_v02.h +26 -32
  86. data/contrib/zstd/{legacy → lib/legacy}/zstd_v03.c +162 -391
  87. data/contrib/zstd/{legacy → lib/legacy}/zstd_v03.h +27 -33
  88. data/contrib/zstd/{legacy → lib/legacy}/zstd_v04.c +195 -604
  89. data/contrib/zstd/{legacy → lib/legacy}/zstd_v04.h +26 -32
  90. data/contrib/zstd/{legacy → lib/legacy}/zstd_v05.c +300 -575
  91. data/contrib/zstd/{legacy → lib/legacy}/zstd_v05.h +22 -31
  92. data/contrib/zstd/{legacy → lib/legacy}/zstd_v06.c +165 -592
  93. data/contrib/zstd/{legacy → lib/legacy}/zstd_v06.h +54 -67
  94. data/contrib/zstd/lib/legacy/zstd_v07.c +4541 -0
  95. data/contrib/zstd/lib/legacy/zstd_v07.h +187 -0
  96. data/contrib/zstd/lib/libzstd.pc.in +15 -0
  97. data/contrib/zstd/lib/zstd.h +2090 -0
  98. data/ext/depend +2 -0
  99. data/ext/extconf.rb +18 -5
  100. data/ext/extzstd.c +296 -214
  101. data/ext/extzstd.h +81 -36
  102. data/ext/extzstd_nogvls.h +0 -117
  103. data/ext/extzstd_stream.c +622 -0
  104. data/ext/libzstd_conf.h +8 -0
  105. data/ext/zstd_common.c +11 -0
  106. data/ext/zstd_compress.c +15 -0
  107. data/ext/zstd_decompress.c +6 -0
  108. data/ext/zstd_dictbuilder.c +10 -0
  109. data/ext/zstd_dictbuilder_fastcover.c +3 -0
  110. data/ext/zstd_legacy_v01.c +3 -1
  111. data/ext/zstd_legacy_v02.c +3 -1
  112. data/ext/zstd_legacy_v03.c +3 -1
  113. data/ext/zstd_legacy_v04.c +3 -1
  114. data/ext/zstd_legacy_v05.c +3 -1
  115. data/ext/zstd_legacy_v06.c +3 -1
  116. data/ext/zstd_legacy_v07.c +3 -0
  117. data/gemstub.rb +27 -21
  118. data/lib/extzstd.rb +82 -161
  119. data/lib/extzstd/version.rb +1 -1
  120. data/test/test_basic.rb +19 -6
  121. metadata +127 -59
  122. data/contrib/zstd/common/error_private.h +0 -125
  123. data/contrib/zstd/common/error_public.h +0 -77
  124. data/contrib/zstd/common/huf.h +0 -228
  125. data/contrib/zstd/common/zstd.h +0 -475
  126. data/contrib/zstd/common/zstd_common.c +0 -91
  127. data/contrib/zstd/common/zstd_internal.h +0 -238
  128. data/contrib/zstd/compress/huf_compress.c +0 -577
  129. data/contrib/zstd/compress/zbuff_compress.c +0 -327
  130. data/contrib/zstd/compress/zstd_compress.c +0 -3074
  131. data/contrib/zstd/compress/zstd_opt.h +0 -1046
  132. data/contrib/zstd/decompress/huf_decompress.c +0 -894
  133. data/contrib/zstd/decompress/zbuff_decompress.c +0 -294
  134. data/contrib/zstd/decompress/zstd_decompress.c +0 -1362
  135. data/contrib/zstd/dictBuilder/zdict.h +0 -113
  136. data/contrib/zstd/legacy/zstd_legacy.h +0 -140
  137. data/ext/extzstd_buffered.c +0 -265
  138. data/ext/zstd_amalgam.c +0 -18
@@ -0,0 +1,447 @@
1
+ /*
2
+ * Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
3
+ * All rights reserved.
4
+ *
5
+ * This source code is licensed under both the BSD-style license (found in the
6
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7
+ * in the COPYING file in the root directory of this source tree).
8
+ * You may select, at your option, one of the above-listed licenses.
9
+ */
10
+
11
+ #ifndef ZSTD_CCOMMON_H_MODULE
12
+ #define ZSTD_CCOMMON_H_MODULE
13
+
14
+ /* this module contains definitions which must be identical
15
+ * across compression, decompression and dictBuilder.
16
+ * It also contains a few functions useful to at least 2 of them
17
+ * and which benefit from being inlined */
18
+
19
+ /*-*************************************
20
+ * Dependencies
21
+ ***************************************/
22
+ #ifdef __aarch64__
23
+ #include <arm_neon.h>
24
+ #endif
25
+ #include "compiler.h"
26
+ #include "mem.h"
27
+ #include "debug.h" /* assert, DEBUGLOG, RAWLOG, g_debuglevel */
28
+ #include "error_private.h"
29
+ #define ZSTD_STATIC_LINKING_ONLY
30
+ #include "../zstd.h"
31
+ #define FSE_STATIC_LINKING_ONLY
32
+ #include "fse.h"
33
+ #define HUF_STATIC_LINKING_ONLY
34
+ #include "huf.h"
35
+ #ifndef XXH_STATIC_LINKING_ONLY
36
+ # define XXH_STATIC_LINKING_ONLY /* XXH64_state_t */
37
+ #endif
38
+ #include "xxhash.h" /* XXH_reset, update, digest */
39
+
40
+ #if defined (__cplusplus)
41
+ extern "C" {
42
+ #endif
43
+
44
+ /* ---- static assert (debug) --- */
45
+ #define ZSTD_STATIC_ASSERT(c) DEBUG_STATIC_ASSERT(c)
46
+ #define ZSTD_isError ERR_isError /* for inlining */
47
+ #define FSE_isError ERR_isError
48
+ #define HUF_isError ERR_isError
49
+
50
+
51
+ /*-*************************************
52
+ * shared macros
53
+ ***************************************/
54
+ #undef MIN
55
+ #undef MAX
56
+ #define MIN(a,b) ((a)<(b) ? (a) : (b))
57
+ #define MAX(a,b) ((a)>(b) ? (a) : (b))
58
+
59
+ /**
60
+ * Ignore: this is an internal helper.
61
+ *
62
+ * This is a helper function to help force C99-correctness during compilation.
63
+ * Under strict compilation modes, variadic macro arguments can't be empty.
64
+ * However, variadic function arguments can be. Using a function therefore lets
65
+ * us statically check that at least one (string) argument was passed,
66
+ * independent of the compilation flags.
67
+ */
68
+ static INLINE_KEYWORD UNUSED_ATTR
69
+ void _force_has_format_string(const char *format, ...) {
70
+ (void)format;
71
+ }
72
+
73
+ /**
74
+ * Ignore: this is an internal helper.
75
+ *
76
+ * We want to force this function invocation to be syntactically correct, but
77
+ * we don't want to force runtime evaluation of its arguments.
78
+ */
79
+ #define _FORCE_HAS_FORMAT_STRING(...) \
80
+ if (0) { \
81
+ _force_has_format_string(__VA_ARGS__); \
82
+ }
83
+
84
+ /**
85
+ * Return the specified error if the condition evaluates to true.
86
+ *
87
+ * In debug modes, prints additional information.
88
+ * In order to do that (particularly, printing the conditional that failed),
89
+ * this can't just wrap RETURN_ERROR().
90
+ */
91
+ #define RETURN_ERROR_IF(cond, err, ...) \
92
+ if (cond) { \
93
+ RAWLOG(3, "%s:%d: ERROR!: check %s failed, returning %s", \
94
+ __FILE__, __LINE__, ZSTD_QUOTE(cond), ZSTD_QUOTE(ERROR(err))); \
95
+ _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \
96
+ RAWLOG(3, ": " __VA_ARGS__); \
97
+ RAWLOG(3, "\n"); \
98
+ return ERROR(err); \
99
+ }
100
+
101
+ /**
102
+ * Unconditionally return the specified error.
103
+ *
104
+ * In debug modes, prints additional information.
105
+ */
106
+ #define RETURN_ERROR(err, ...) \
107
+ do { \
108
+ RAWLOG(3, "%s:%d: ERROR!: unconditional check failed, returning %s", \
109
+ __FILE__, __LINE__, ZSTD_QUOTE(ERROR(err))); \
110
+ _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \
111
+ RAWLOG(3, ": " __VA_ARGS__); \
112
+ RAWLOG(3, "\n"); \
113
+ return ERROR(err); \
114
+ } while(0);
115
+
116
+ /**
117
+ * If the provided expression evaluates to an error code, returns that error code.
118
+ *
119
+ * In debug modes, prints additional information.
120
+ */
121
+ #define FORWARD_IF_ERROR(err, ...) \
122
+ do { \
123
+ size_t const err_code = (err); \
124
+ if (ERR_isError(err_code)) { \
125
+ RAWLOG(3, "%s:%d: ERROR!: forwarding error in %s: %s", \
126
+ __FILE__, __LINE__, ZSTD_QUOTE(err), ERR_getErrorName(err_code)); \
127
+ _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \
128
+ RAWLOG(3, ": " __VA_ARGS__); \
129
+ RAWLOG(3, "\n"); \
130
+ return err_code; \
131
+ } \
132
+ } while(0);
133
+
134
+
135
+ /*-*************************************
136
+ * Common constants
137
+ ***************************************/
138
+ #define ZSTD_OPT_NUM (1<<12)
139
+
140
+ #define ZSTD_REP_NUM 3 /* number of repcodes */
141
+ #define ZSTD_REP_MOVE (ZSTD_REP_NUM-1)
142
+ static const U32 repStartValue[ZSTD_REP_NUM] = { 1, 4, 8 };
143
+
144
+ #define KB *(1 <<10)
145
+ #define MB *(1 <<20)
146
+ #define GB *(1U<<30)
147
+
148
+ #define BIT7 128
149
+ #define BIT6 64
150
+ #define BIT5 32
151
+ #define BIT4 16
152
+ #define BIT1 2
153
+ #define BIT0 1
154
+
155
+ #define ZSTD_WINDOWLOG_ABSOLUTEMIN 10
156
+ static const size_t ZSTD_fcs_fieldSize[4] = { 0, 2, 4, 8 };
157
+ static const size_t ZSTD_did_fieldSize[4] = { 0, 1, 2, 4 };
158
+
159
+ #define ZSTD_FRAMEIDSIZE 4 /* magic number size */
160
+
161
+ #define ZSTD_BLOCKHEADERSIZE 3 /* C standard doesn't allow `static const` variable to be init using another `static const` variable */
162
+ static const size_t ZSTD_blockHeaderSize = ZSTD_BLOCKHEADERSIZE;
163
+ typedef enum { bt_raw, bt_rle, bt_compressed, bt_reserved } blockType_e;
164
+
165
+ #define ZSTD_FRAMECHECKSUMSIZE 4
166
+
167
+ #define MIN_SEQUENCES_SIZE 1 /* nbSeq==0 */
168
+ #define MIN_CBLOCK_SIZE (1 /*litCSize*/ + 1 /* RLE or RAW */ + MIN_SEQUENCES_SIZE /* nbSeq==0 */) /* for a non-null block */
169
+
170
+ #define HufLog 12
171
+ typedef enum { set_basic, set_rle, set_compressed, set_repeat } symbolEncodingType_e;
172
+
173
+ #define LONGNBSEQ 0x7F00
174
+
175
+ #define MINMATCH 3
176
+
177
+ #define Litbits 8
178
+ #define MaxLit ((1<<Litbits) - 1)
179
+ #define MaxML 52
180
+ #define MaxLL 35
181
+ #define DefaultMaxOff 28
182
+ #define MaxOff 31
183
+ #define MaxSeq MAX(MaxLL, MaxML) /* Assumption : MaxOff < MaxLL,MaxML */
184
+ #define MLFSELog 9
185
+ #define LLFSELog 9
186
+ #define OffFSELog 8
187
+ #define MaxFSELog MAX(MAX(MLFSELog, LLFSELog), OffFSELog)
188
+
189
+ static const U32 LL_bits[MaxLL+1] = { 0, 0, 0, 0, 0, 0, 0, 0,
190
+ 0, 0, 0, 0, 0, 0, 0, 0,
191
+ 1, 1, 1, 1, 2, 2, 3, 3,
192
+ 4, 6, 7, 8, 9,10,11,12,
193
+ 13,14,15,16 };
194
+ static const S16 LL_defaultNorm[MaxLL+1] = { 4, 3, 2, 2, 2, 2, 2, 2,
195
+ 2, 2, 2, 2, 2, 1, 1, 1,
196
+ 2, 2, 2, 2, 2, 2, 2, 2,
197
+ 2, 3, 2, 1, 1, 1, 1, 1,
198
+ -1,-1,-1,-1 };
199
+ #define LL_DEFAULTNORMLOG 6 /* for static allocation */
200
+ static const U32 LL_defaultNormLog = LL_DEFAULTNORMLOG;
201
+
202
+ static const U32 ML_bits[MaxML+1] = { 0, 0, 0, 0, 0, 0, 0, 0,
203
+ 0, 0, 0, 0, 0, 0, 0, 0,
204
+ 0, 0, 0, 0, 0, 0, 0, 0,
205
+ 0, 0, 0, 0, 0, 0, 0, 0,
206
+ 1, 1, 1, 1, 2, 2, 3, 3,
207
+ 4, 4, 5, 7, 8, 9,10,11,
208
+ 12,13,14,15,16 };
209
+ static const S16 ML_defaultNorm[MaxML+1] = { 1, 4, 3, 2, 2, 2, 2, 2,
210
+ 2, 1, 1, 1, 1, 1, 1, 1,
211
+ 1, 1, 1, 1, 1, 1, 1, 1,
212
+ 1, 1, 1, 1, 1, 1, 1, 1,
213
+ 1, 1, 1, 1, 1, 1, 1, 1,
214
+ 1, 1, 1, 1, 1, 1,-1,-1,
215
+ -1,-1,-1,-1,-1 };
216
+ #define ML_DEFAULTNORMLOG 6 /* for static allocation */
217
+ static const U32 ML_defaultNormLog = ML_DEFAULTNORMLOG;
218
+
219
+ static const S16 OF_defaultNorm[DefaultMaxOff+1] = { 1, 1, 1, 1, 1, 1, 2, 2,
220
+ 2, 1, 1, 1, 1, 1, 1, 1,
221
+ 1, 1, 1, 1, 1, 1, 1, 1,
222
+ -1,-1,-1,-1,-1 };
223
+ #define OF_DEFAULTNORMLOG 5 /* for static allocation */
224
+ static const U32 OF_defaultNormLog = OF_DEFAULTNORMLOG;
225
+
226
+
227
+ /*-*******************************************
228
+ * Shared functions to include for inlining
229
+ *********************************************/
230
+ static void ZSTD_copy8(void* dst, const void* src) {
231
+ #ifdef __aarch64__
232
+ vst1_u8((uint8_t*)dst, vld1_u8((const uint8_t*)src));
233
+ #else
234
+ memcpy(dst, src, 8);
235
+ #endif
236
+ }
237
+
238
+ #define COPY8(d,s) { ZSTD_copy8(d,s); d+=8; s+=8; }
239
+ static void ZSTD_copy16(void* dst, const void* src) {
240
+ #ifdef __aarch64__
241
+ vst1q_u8((uint8_t*)dst, vld1q_u8((const uint8_t*)src));
242
+ #else
243
+ memcpy(dst, src, 16);
244
+ #endif
245
+ }
246
+ #define COPY16(d,s) { ZSTD_copy16(d,s); d+=16; s+=16; }
247
+
248
+ #define WILDCOPY_OVERLENGTH 32
249
+ #define WILDCOPY_VECLEN 16
250
+
251
+ typedef enum {
252
+ ZSTD_no_overlap,
253
+ ZSTD_overlap_src_before_dst
254
+ /* ZSTD_overlap_dst_before_src, */
255
+ } ZSTD_overlap_e;
256
+
257
+ /*! ZSTD_wildcopy() :
258
+ * Custom version of memcpy(), can over read/write up to WILDCOPY_OVERLENGTH bytes (if length==0)
259
+ * @param ovtype controls the overlap detection
260
+ * - ZSTD_no_overlap: The source and destination are guaranteed to be at least WILDCOPY_VECLEN bytes apart.
261
+ * - ZSTD_overlap_src_before_dst: The src and dst may overlap, but they MUST be at least 8 bytes apart.
262
+ * The src buffer must be before the dst buffer.
263
+ */
264
+ MEM_STATIC FORCE_INLINE_ATTR
265
+ void ZSTD_wildcopy(void* dst, const void* src, ptrdiff_t length, ZSTD_overlap_e const ovtype)
266
+ {
267
+ ptrdiff_t diff = (BYTE*)dst - (const BYTE*)src;
268
+ const BYTE* ip = (const BYTE*)src;
269
+ BYTE* op = (BYTE*)dst;
270
+ BYTE* const oend = op + length;
271
+
272
+ assert(diff >= 8 || (ovtype == ZSTD_no_overlap && diff <= -WILDCOPY_VECLEN));
273
+
274
+ if (ovtype == ZSTD_overlap_src_before_dst && diff < WILDCOPY_VECLEN) {
275
+ /* Handle short offset copies. */
276
+ do {
277
+ COPY8(op, ip)
278
+ } while (op < oend);
279
+ } else {
280
+ assert(diff >= WILDCOPY_VECLEN || diff <= -WILDCOPY_VECLEN);
281
+ /* Separate out the first COPY16() call because the copy length is
282
+ * almost certain to be short, so the branches have different
283
+ * probabilities. Since it is almost certain to be short, only do
284
+ * one COPY16() in the first call. Then, do two calls per loop since
285
+ * at that point it is more likely to have a high trip count.
286
+ */
287
+ #ifndef __aarch64__
288
+ do {
289
+ COPY16(op, ip);
290
+ }
291
+ while (op < oend);
292
+ #else
293
+ COPY16(op, ip);
294
+ if (op >= oend) return;
295
+ do {
296
+ COPY16(op, ip);
297
+ COPY16(op, ip);
298
+ }
299
+ while (op < oend);
300
+ #endif
301
+ }
302
+ }
303
+
304
+ MEM_STATIC size_t ZSTD_limitCopy(void* dst, size_t dstCapacity, const void* src, size_t srcSize)
305
+ {
306
+ size_t const length = MIN(dstCapacity, srcSize);
307
+ if (length > 0) {
308
+ memcpy(dst, src, length);
309
+ }
310
+ return length;
311
+ }
312
+
313
+ /* define "workspace is too large" as this number of times larger than needed */
314
+ #define ZSTD_WORKSPACETOOLARGE_FACTOR 3
315
+
316
+ /* when workspace is continuously too large
317
+ * during at least this number of times,
318
+ * context's memory usage is considered wasteful,
319
+ * because it's sized to handle a worst case scenario which rarely happens.
320
+ * In which case, resize it down to free some memory */
321
+ #define ZSTD_WORKSPACETOOLARGE_MAXDURATION 128
322
+
323
+
324
+ /*-*******************************************
325
+ * Private declarations
326
+ *********************************************/
327
+ typedef struct seqDef_s {
328
+ U32 offset;
329
+ U16 litLength;
330
+ U16 matchLength;
331
+ } seqDef;
332
+
333
+ typedef struct {
334
+ seqDef* sequencesStart;
335
+ seqDef* sequences;
336
+ BYTE* litStart;
337
+ BYTE* lit;
338
+ BYTE* llCode;
339
+ BYTE* mlCode;
340
+ BYTE* ofCode;
341
+ size_t maxNbSeq;
342
+ size_t maxNbLit;
343
+ U32 longLengthID; /* 0 == no longLength; 1 == Lit.longLength; 2 == Match.longLength; */
344
+ U32 longLengthPos;
345
+ } seqStore_t;
346
+
347
+ typedef struct {
348
+ U32 litLength;
349
+ U32 matchLength;
350
+ } ZSTD_sequenceLength;
351
+
352
+ /**
353
+ * Returns the ZSTD_sequenceLength for the given sequences. It handles the decoding of long sequences
354
+ * indicated by longLengthPos and longLengthID, and adds MINMATCH back to matchLength.
355
+ */
356
+ MEM_STATIC ZSTD_sequenceLength ZSTD_getSequenceLength(seqStore_t const* seqStore, seqDef const* seq)
357
+ {
358
+ ZSTD_sequenceLength seqLen;
359
+ seqLen.litLength = seq->litLength;
360
+ seqLen.matchLength = seq->matchLength + MINMATCH;
361
+ if (seqStore->longLengthPos == (U32)(seq - seqStore->sequencesStart)) {
362
+ if (seqStore->longLengthID == 1) {
363
+ seqLen.litLength += 0xFFFF;
364
+ }
365
+ if (seqStore->longLengthID == 2) {
366
+ seqLen.matchLength += 0xFFFF;
367
+ }
368
+ }
369
+ return seqLen;
370
+ }
371
+
372
+ /**
373
+ * Contains the compressed frame size and an upper-bound for the decompressed frame size.
374
+ * Note: before using `compressedSize`, check for errors using ZSTD_isError().
375
+ * similarly, before using `decompressedBound`, check for errors using:
376
+ * `decompressedBound != ZSTD_CONTENTSIZE_ERROR`
377
+ */
378
+ typedef struct {
379
+ size_t compressedSize;
380
+ unsigned long long decompressedBound;
381
+ } ZSTD_frameSizeInfo; /* decompress & legacy */
382
+
383
+ const seqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx); /* compress & dictBuilder */
384
+ void ZSTD_seqToCodes(const seqStore_t* seqStorePtr); /* compress, dictBuilder, decodeCorpus (shouldn't get its definition from here) */
385
+
386
+ /* custom memory allocation functions */
387
+ void* ZSTD_malloc(size_t size, ZSTD_customMem customMem);
388
+ void* ZSTD_calloc(size_t size, ZSTD_customMem customMem);
389
+ void ZSTD_free(void* ptr, ZSTD_customMem customMem);
390
+
391
+
392
+ MEM_STATIC U32 ZSTD_highbit32(U32 val) /* compress, dictBuilder, decodeCorpus */
393
+ {
394
+ assert(val != 0);
395
+ {
396
+ # if defined(_MSC_VER) /* Visual */
397
+ unsigned long r=0;
398
+ return _BitScanReverse(&r, val) ? (unsigned)r : 0;
399
+ # elif defined(__GNUC__) && (__GNUC__ >= 3) /* GCC Intrinsic */
400
+ return __builtin_clz (val) ^ 31;
401
+ # elif defined(__ICCARM__) /* IAR Intrinsic */
402
+ return 31 - __CLZ(val);
403
+ # else /* Software version */
404
+ static const U32 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 };
405
+ U32 v = val;
406
+ v |= v >> 1;
407
+ v |= v >> 2;
408
+ v |= v >> 4;
409
+ v |= v >> 8;
410
+ v |= v >> 16;
411
+ return DeBruijnClz[(v * 0x07C4ACDDU) >> 27];
412
+ # endif
413
+ }
414
+ }
415
+
416
+
417
+ /* ZSTD_invalidateRepCodes() :
418
+ * ensures next compression will not use repcodes from previous block.
419
+ * Note : only works with regular variant;
420
+ * do not use with extDict variant ! */
421
+ void ZSTD_invalidateRepCodes(ZSTD_CCtx* cctx); /* zstdmt, adaptive_compression (shouldn't get this definition from here) */
422
+
423
+
424
+ typedef struct {
425
+ blockType_e blockType;
426
+ U32 lastBlock;
427
+ U32 origSize;
428
+ } blockProperties_t; /* declared here for decompress and fullbench */
429
+
430
+ /*! ZSTD_getcBlockSize() :
431
+ * Provides the size of compressed block from block header `src` */
432
+ /* Used by: decompress, fullbench (does not get its definition from here) */
433
+ size_t ZSTD_getcBlockSize(const void* src, size_t srcSize,
434
+ blockProperties_t* bpPtr);
435
+
436
+ /*! ZSTD_decodeSeqHeaders() :
437
+ * decode sequence header from src */
438
+ /* Used by: decompress, fullbench (does not get its definition from here) */
439
+ size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr,
440
+ const void* src, size_t srcSize);
441
+
442
+
443
+ #if defined (__cplusplus)
444
+ }
445
+ #endif
446
+
447
+ #endif /* ZSTD_CCOMMON_H_MODULE */
@@ -1,76 +1,36 @@
1
1
  /* ******************************************************************
2
- FSE : Finite State Entropy encoder
3
- Copyright (C) 2013-2015, Yann Collet.
4
-
5
- BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
6
-
7
- Redistribution and use in source and binary forms, with or without
8
- modification, are permitted provided that the following conditions are
9
- met:
10
-
11
- * Redistributions of source code must retain the above copyright
12
- notice, this list of conditions and the following disclaimer.
13
- * Redistributions in binary form must reproduce the above
14
- copyright notice, this list of conditions and the following disclaimer
15
- in the documentation and/or other materials provided with the
16
- distribution.
17
-
18
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22
- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
-
30
- You can contact the author at :
31
- - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy
32
- - Public forum : https://groups.google.com/forum/#!forum/lz4c
2
+ * FSE : Finite State Entropy encoder
3
+ * Copyright (c) 2013-2020, Yann Collet, Facebook, Inc.
4
+ *
5
+ * You can contact the author at :
6
+ * - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy
7
+ * - Public forum : https://groups.google.com/forum/#!forum/lz4c
8
+ *
9
+ * This source code is licensed under both the BSD-style license (found in the
10
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
11
+ * in the COPYING file in the root directory of this source tree).
12
+ * You may select, at your option, one of the above-listed licenses.
33
13
  ****************************************************************** */
34
14
 
35
- /* **************************************************************
36
- * Compiler specifics
37
- ****************************************************************/
38
- #ifdef _MSC_VER /* Visual Studio */
39
- # define FORCE_INLINE static __forceinline
40
- # include <intrin.h> /* For Visual 2005 */
41
- # pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
42
- # pragma warning(disable : 4214) /* disable: C4214: non-int bitfields */
43
- #else
44
- # ifdef __GNUC__
45
- # define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
46
- # define FORCE_INLINE static inline __attribute__((always_inline))
47
- # else
48
- # define FORCE_INLINE static inline
49
- # endif
50
- #endif
51
-
52
-
53
15
  /* **************************************************************
54
16
  * Includes
55
17
  ****************************************************************/
56
18
  #include <stdlib.h> /* malloc, free, qsort */
57
19
  #include <string.h> /* memcpy, memset */
58
- #include <stdio.h> /* printf (debug) */
59
- #include "bitstream.h"
20
+ #include "../common/compiler.h"
21
+ #include "../common/mem.h" /* U32, U16, etc. */
22
+ #include "../common/debug.h" /* assert, DEBUGLOG */
23
+ #include "hist.h" /* HIST_count_wksp */
24
+ #include "../common/bitstream.h"
60
25
  #define FSE_STATIC_LINKING_ONLY
61
- #include "fse.h"
26
+ #include "../common/fse.h"
27
+ #include "../common/error_private.h"
62
28
 
63
29
 
64
30
  /* **************************************************************
65
31
  * Error Management
66
32
  ****************************************************************/
67
- #define FSE_STATIC_ASSERT(c) { enum { FSE_static_assert = 1/(int)(!!(c)) }; } /* use only *after* variable declarations */
68
-
69
-
70
- /* **************************************************************
71
- * Complex types
72
- ****************************************************************/
73
- typedef U32 CTable_max_t[FSE_CTABLE_SIZE_U32(FSE_MAX_TABLELOG, FSE_MAX_SYMBOL_VALUE)];
33
+ #define FSE_isError ERR_isError
74
34
 
75
35
 
76
36
  /* **************************************************************
@@ -97,7 +57,15 @@ typedef U32 CTable_max_t[FSE_CTABLE_SIZE_U32(FSE_MAX_TABLELOG, FSE_MAX_SYMBOL_VA
97
57
 
98
58
 
99
59
  /* Function templates */
100
- size_t FSE_buildCTable(FSE_CTable* ct, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog)
60
+
61
+ /* FSE_buildCTable_wksp() :
62
+ * Same as FSE_buildCTable(), but using an externally allocated scratch buffer (`workSpace`).
63
+ * wkspSize should be sized to handle worst case situation, which is `1<<max_tableLog * sizeof(FSE_FUNCTION_TYPE)`
64
+ * workSpace must also be properly aligned with FSE_FUNCTION_TYPE requirements
65
+ */
66
+ size_t FSE_buildCTable_wksp(FSE_CTable* ct,
67
+ const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog,
68
+ void* workSpace, size_t wkspSize)
101
69
  {
102
70
  U32 const tableSize = 1 << tableLog;
103
71
  U32 const tableMask = tableSize - 1;
@@ -108,20 +76,26 @@ size_t FSE_buildCTable(FSE_CTable* ct, const short* normalizedCounter, unsigned
108
76
  U32 const step = FSE_TABLESTEP(tableSize);
109
77
  U32 cumul[FSE_MAX_SYMBOL_VALUE+2];
110
78
 
111
- FSE_FUNCTION_TYPE tableSymbol[FSE_MAX_TABLESIZE]; /* memset() is not necessary, even if static analyzer complain about it */
79
+ FSE_FUNCTION_TYPE* const tableSymbol = (FSE_FUNCTION_TYPE*)workSpace;
112
80
  U32 highThreshold = tableSize-1;
113
81
 
114
82
  /* CTable header */
83
+ if (((size_t)1 << tableLog) * sizeof(FSE_FUNCTION_TYPE) > wkspSize) return ERROR(tableLog_tooLarge);
115
84
  tableU16[-2] = (U16) tableLog;
116
85
  tableU16[-1] = (U16) maxSymbolValue;
86
+ assert(tableLog < 16); /* required for threshold strategy to work */
117
87
 
118
88
  /* For explanations on how to distribute symbol values over the table :
119
- * http://fastcompression.blogspot.fr/2014/02/fse-distributing-symbol-values.html */
89
+ * http://fastcompression.blogspot.fr/2014/02/fse-distributing-symbol-values.html */
90
+
91
+ #ifdef __clang_analyzer__
92
+ memset(tableSymbol, 0, sizeof(*tableSymbol) * tableSize); /* useless initialization, just to keep scan-build happy */
93
+ #endif
120
94
 
121
95
  /* symbol start positions */
122
96
  { U32 u;
123
97
  cumul[0] = 0;
124
- for (u=1; u<=maxSymbolValue+1; u++) {
98
+ for (u=1; u <= maxSymbolValue+1; u++) {
125
99
  if (normalizedCounter[u-1]==-1) { /* Low proba symbol */
126
100
  cumul[u] = cumul[u-1] + 1;
127
101
  tableSymbol[highThreshold--] = (FSE_FUNCTION_TYPE)(u-1);
@@ -135,14 +109,16 @@ size_t FSE_buildCTable(FSE_CTable* ct, const short* normalizedCounter, unsigned
135
109
  { U32 position = 0;
136
110
  U32 symbol;
137
111
  for (symbol=0; symbol<=maxSymbolValue; symbol++) {
138
- int nbOccurences;
139
- for (nbOccurences=0; nbOccurences<normalizedCounter[symbol]; nbOccurences++) {
112
+ int nbOccurrences;
113
+ int const freq = normalizedCounter[symbol];
114
+ for (nbOccurrences=0; nbOccurrences<freq; nbOccurrences++) {
140
115
  tableSymbol[position] = (FSE_FUNCTION_TYPE)symbol;
141
116
  position = (position + step) & tableMask;
142
- while (position > highThreshold) position = (position + step) & tableMask; /* Low proba area */
117
+ while (position > highThreshold)
118
+ position = (position + step) & tableMask; /* Low proba area */
143
119
  } }
144
120
 
145
- if (position!=0) return ERROR(GENERIC); /* Must have gone through all positions */
121
+ assert(position==0); /* Must have initialized all positions */
146
122
  }
147
123
 
148
124
  /* Build table */
@@ -157,7 +133,10 @@ size_t FSE_buildCTable(FSE_CTable* ct, const short* normalizedCounter, unsigned
157
133
  for (s=0; s<=maxSymbolValue; s++) {
158
134
  switch (normalizedCounter[s])
159
135
  {
160
- case 0: break;
136
+ case 0:
137
+ /* filling nonetheless, for compatibility with FSE_getMaxNbBits() */
138
+ symbolTT[s].deltaNbBits = ((tableLog+1) << 16) - (1<<tableLog);
139
+ break;
161
140
 
162
141
  case -1:
163
142
  case 1:
@@ -174,27 +153,46 @@ size_t FSE_buildCTable(FSE_CTable* ct, const short* normalizedCounter, unsigned
174
153
  total += normalizedCounter[s];
175
154
  } } } }
176
155
 
156
+ #if 0 /* debug : symbol costs */
157
+ DEBUGLOG(5, "\n --- table statistics : ");
158
+ { U32 symbol;
159
+ for (symbol=0; symbol<=maxSymbolValue; symbol++) {
160
+ DEBUGLOG(5, "%3u: w=%3i, maxBits=%u, fracBits=%.2f",
161
+ symbol, normalizedCounter[symbol],
162
+ FSE_getMaxNbBits(symbolTT, symbol),
163
+ (double)FSE_bitCost(symbolTT, tableLog, symbol, 8) / 256);
164
+ }
165
+ }
166
+ #endif
167
+
177
168
  return 0;
178
169
  }
179
170
 
180
171
 
172
+ size_t FSE_buildCTable(FSE_CTable* ct, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog)
173
+ {
174
+ FSE_FUNCTION_TYPE tableSymbol[FSE_MAX_TABLESIZE]; /* memset() is not necessary, even if static analyzer complain about it */
175
+ return FSE_buildCTable_wksp(ct, normalizedCounter, maxSymbolValue, tableLog, tableSymbol, sizeof(tableSymbol));
176
+ }
177
+
178
+
181
179
 
182
180
  #ifndef FSE_COMMONDEFS_ONLY
183
181
 
182
+
184
183
  /*-**************************************************************
185
- * FSE NCount encoding-decoding
184
+ * FSE NCount encoding
186
185
  ****************************************************************/
187
186
  size_t FSE_NCountWriteBound(unsigned maxSymbolValue, unsigned tableLog)
188
187
  {
189
- size_t maxHeaderSize = (((maxSymbolValue+1) * tableLog) >> 3) + 3;
188
+ size_t const maxHeaderSize = (((maxSymbolValue+1) * tableLog) >> 3) + 3;
190
189
  return maxSymbolValue ? maxHeaderSize : FSE_NCOUNTBOUND; /* maxSymbolValue==0 ? use default */
191
190
  }
192
191
 
193
- static short FSE_abs(short a) { return a<0 ? -a : a; }
194
-
195
- static size_t FSE_writeNCount_generic (void* header, size_t headerBufferSize,
196
- const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog,
197
- unsigned writeIsSafe)
192
+ static size_t
193
+ FSE_writeNCount_generic (void* header, size_t headerBufferSize,
194
+ const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog,
195
+ unsigned writeIsSafe)
198
196
  {
199
197
  BYTE* const ostart = (BYTE*) header;
200
198
  BYTE* out = ostart;
@@ -203,13 +201,12 @@ static size_t FSE_writeNCount_generic (void* header, size_t headerBufferSize,
203
201
  const int tableSize = 1 << tableLog;
204
202
  int remaining;
205
203
  int threshold;
206
- U32 bitStream;
207
- int bitCount;
208
- unsigned charnum = 0;
209
- int previous0 = 0;
204
+ U32 bitStream = 0;
205
+ int bitCount = 0;
206
+ unsigned symbol = 0;
207
+ unsigned const alphabetSize = maxSymbolValue + 1;
208
+ int previousIs0 = 0;
210
209
 
211
- bitStream = 0;
212
- bitCount = 0;
213
210
  /* Table Size */
214
211
  bitStream += (tableLog-FSE_MIN_TABLELOG) << bitCount;
215
212
  bitCount += 4;
@@ -219,48 +216,53 @@ static size_t FSE_writeNCount_generic (void* header, size_t headerBufferSize,
219
216
  threshold = tableSize;
220
217
  nbBits = tableLog+1;
221
218
 
222
- while (remaining>1) { /* stops at 1 */
223
- if (previous0) {
224
- unsigned start = charnum;
225
- while (!normalizedCounter[charnum]) charnum++;
226
- while (charnum >= start+24) {
219
+ while ((symbol < alphabetSize) && (remaining>1)) { /* stops at 1 */
220
+ if (previousIs0) {
221
+ unsigned start = symbol;
222
+ while ((symbol < alphabetSize) && !normalizedCounter[symbol]) symbol++;
223
+ if (symbol == alphabetSize) break; /* incorrect distribution */
224
+ while (symbol >= start+24) {
227
225
  start+=24;
228
226
  bitStream += 0xFFFFU << bitCount;
229
- if ((!writeIsSafe) && (out > oend-2)) return ERROR(dstSize_tooSmall); /* Buffer overflow */
227
+ if ((!writeIsSafe) && (out > oend-2))
228
+ return ERROR(dstSize_tooSmall); /* Buffer overflow */
230
229
  out[0] = (BYTE) bitStream;
231
230
  out[1] = (BYTE)(bitStream>>8);
232
231
  out+=2;
233
232
  bitStream>>=16;
234
233
  }
235
- while (charnum >= start+3) {
234
+ while (symbol >= start+3) {
236
235
  start+=3;
237
236
  bitStream += 3 << bitCount;
238
237
  bitCount += 2;
239
238
  }
240
- bitStream += (charnum-start) << bitCount;
239
+ bitStream += (symbol-start) << bitCount;
241
240
  bitCount += 2;
242
241
  if (bitCount>16) {
243
- if ((!writeIsSafe) && (out > oend - 2)) return ERROR(dstSize_tooSmall); /* Buffer overflow */
242
+ if ((!writeIsSafe) && (out > oend - 2))
243
+ return ERROR(dstSize_tooSmall); /* Buffer overflow */
244
244
  out[0] = (BYTE)bitStream;
245
245
  out[1] = (BYTE)(bitStream>>8);
246
246
  out += 2;
247
247
  bitStream >>= 16;
248
248
  bitCount -= 16;
249
249
  } }
250
- { short count = normalizedCounter[charnum++];
251
- const short max = (short)((2*threshold-1)-remaining);
252
- remaining -= FSE_abs(count);
253
- if (remaining<1) return ERROR(GENERIC);
250
+ { int count = normalizedCounter[symbol++];
251
+ int const max = (2*threshold-1) - remaining;
252
+ remaining -= count < 0 ? -count : count;
254
253
  count++; /* +1 for extra accuracy */
255
- if (count>=threshold) count += max; /* [0..max[ [max..threshold[ (...) [threshold+max 2*threshold[ */
254
+ if (count>=threshold)
255
+ count += max; /* [0..max[ [max..threshold[ (...) [threshold+max 2*threshold[ */
256
256
  bitStream += count << bitCount;
257
257
  bitCount += nbBits;
258
258
  bitCount -= (count<max);
259
- previous0 = (count==1);
260
- while (remaining<threshold) nbBits--, threshold>>=1;
259
+ previousIs0 = (count==1);
260
+ if (remaining<1) return ERROR(GENERIC);
261
+ while (remaining<threshold) { nbBits--; threshold>>=1; }
261
262
  }
262
263
  if (bitCount>16) {
263
- if ((!writeIsSafe) && (out > oend - 2)) return ERROR(dstSize_tooSmall); /* Buffer overflow */
264
+ if ((!writeIsSafe) && (out > oend - 2))
265
+ return ERROR(dstSize_tooSmall); /* Buffer overflow */
264
266
  out[0] = (BYTE)bitStream;
265
267
  out[1] = (BYTE)(bitStream>>8);
266
268
  out += 2;
@@ -268,172 +270,37 @@ static size_t FSE_writeNCount_generic (void* header, size_t headerBufferSize,
268
270
  bitCount -= 16;
269
271
  } }
270
272
 
273
+ if (remaining != 1)
274
+ return ERROR(GENERIC); /* incorrect normalized distribution */
275
+ assert(symbol <= alphabetSize);
276
+
271
277
  /* flush remaining bitStream */
272
- if ((!writeIsSafe) && (out > oend - 2)) return ERROR(dstSize_tooSmall); /* Buffer overflow */
278
+ if ((!writeIsSafe) && (out > oend - 2))
279
+ return ERROR(dstSize_tooSmall); /* Buffer overflow */
273
280
  out[0] = (BYTE)bitStream;
274
281
  out[1] = (BYTE)(bitStream>>8);
275
282
  out+= (bitCount+7) /8;
276
283
 
277
- if (charnum > maxSymbolValue + 1) return ERROR(GENERIC);
278
-
279
284
  return (out-ostart);
280
285
  }
281
286
 
282
287
 
283
- size_t FSE_writeNCount (void* buffer, size_t bufferSize, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog)
288
+ size_t FSE_writeNCount (void* buffer, size_t bufferSize,
289
+ const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog)
284
290
  {
285
- if (tableLog > FSE_MAX_TABLELOG) return ERROR(GENERIC); /* Unsupported */
291
+ if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge); /* Unsupported */
286
292
  if (tableLog < FSE_MIN_TABLELOG) return ERROR(GENERIC); /* Unsupported */
287
293
 
288
294
  if (bufferSize < FSE_NCountWriteBound(maxSymbolValue, tableLog))
289
295
  return FSE_writeNCount_generic(buffer, bufferSize, normalizedCounter, maxSymbolValue, tableLog, 0);
290
296
 
291
- return FSE_writeNCount_generic(buffer, bufferSize, normalizedCounter, maxSymbolValue, tableLog, 1);
292
- }
293
-
294
-
295
-
296
- /*-**************************************************************
297
- * Counting histogram
298
- ****************************************************************/
299
- /*! FSE_count_simple
300
- This function just counts byte values within `src`,
301
- and store the histogram into table `count`.
302
- This function is unsafe : it doesn't check that all values within `src` can fit into `count`.
303
- For this reason, prefer using a table `count` with 256 elements.
304
- @return : count of most numerous element
305
- */
306
- static size_t FSE_count_simple(unsigned* count, unsigned* maxSymbolValuePtr,
307
- const void* src, size_t srcSize)
308
- {
309
- const BYTE* ip = (const BYTE*)src;
310
- const BYTE* const end = ip + srcSize;
311
- unsigned maxSymbolValue = *maxSymbolValuePtr;
312
- unsigned max=0;
313
-
314
-
315
- memset(count, 0, (maxSymbolValue+1)*sizeof(*count));
316
- if (srcSize==0) { *maxSymbolValuePtr = 0; return 0; }
317
-
318
- while (ip<end) count[*ip++]++;
319
-
320
- while (!count[maxSymbolValue]) maxSymbolValue--;
321
- *maxSymbolValuePtr = maxSymbolValue;
322
-
323
- { U32 s; for (s=0; s<=maxSymbolValue; s++) if (count[s] > max) max = count[s]; }
324
-
325
- return (size_t)max;
326
- }
327
-
328
-
329
- static size_t FSE_count_parallel(unsigned* count, unsigned* maxSymbolValuePtr,
330
- const void* source, size_t sourceSize,
331
- unsigned checkMax)
332
- {
333
- const BYTE* ip = (const BYTE*)source;
334
- const BYTE* const iend = ip+sourceSize;
335
- unsigned maxSymbolValue = *maxSymbolValuePtr;
336
- unsigned max=0;
337
-
338
-
339
- U32 Counting1[256] = { 0 };
340
- U32 Counting2[256] = { 0 };
341
- U32 Counting3[256] = { 0 };
342
- U32 Counting4[256] = { 0 };
343
-
344
- /* safety checks */
345
- if (!sourceSize) {
346
- memset(count, 0, maxSymbolValue + 1);
347
- *maxSymbolValuePtr = 0;
348
- return 0;
349
- }
350
- if (!maxSymbolValue) maxSymbolValue = 255; /* 0 == default */
351
-
352
- /* by stripes of 16 bytes */
353
- { U32 cached = MEM_read32(ip); ip += 4;
354
- while (ip < iend-15) {
355
- U32 c = cached; cached = MEM_read32(ip); ip += 4;
356
- Counting1[(BYTE) c ]++;
357
- Counting2[(BYTE)(c>>8) ]++;
358
- Counting3[(BYTE)(c>>16)]++;
359
- Counting4[ c>>24 ]++;
360
- c = cached; cached = MEM_read32(ip); ip += 4;
361
- Counting1[(BYTE) c ]++;
362
- Counting2[(BYTE)(c>>8) ]++;
363
- Counting3[(BYTE)(c>>16)]++;
364
- Counting4[ c>>24 ]++;
365
- c = cached; cached = MEM_read32(ip); ip += 4;
366
- Counting1[(BYTE) c ]++;
367
- Counting2[(BYTE)(c>>8) ]++;
368
- Counting3[(BYTE)(c>>16)]++;
369
- Counting4[ c>>24 ]++;
370
- c = cached; cached = MEM_read32(ip); ip += 4;
371
- Counting1[(BYTE) c ]++;
372
- Counting2[(BYTE)(c>>8) ]++;
373
- Counting3[(BYTE)(c>>16)]++;
374
- Counting4[ c>>24 ]++;
375
- }
376
- ip-=4;
377
- }
378
-
379
- /* finish last symbols */
380
- while (ip<iend) Counting1[*ip++]++;
381
-
382
- if (checkMax) { /* verify stats will fit into destination table */
383
- U32 s; for (s=255; s>maxSymbolValue; s--) {
384
- Counting1[s] += Counting2[s] + Counting3[s] + Counting4[s];
385
- if (Counting1[s]) return ERROR(maxSymbolValue_tooSmall);
386
- } }
387
-
388
- { U32 s; for (s=0; s<=maxSymbolValue; s++) {
389
- count[s] = Counting1[s] + Counting2[s] + Counting3[s] + Counting4[s];
390
- if (count[s] > max) max = count[s];
391
- }}
392
-
393
- while (!count[maxSymbolValue]) maxSymbolValue--;
394
- *maxSymbolValuePtr = maxSymbolValue;
395
- return (size_t)max;
396
- }
397
-
398
- /* fast variant (unsafe : won't check if src contains values beyond count[] limit) */
399
- size_t FSE_countFast(unsigned* count, unsigned* maxSymbolValuePtr,
400
- const void* source, size_t sourceSize)
401
- {
402
- if (sourceSize < 1500) return FSE_count_simple(count, maxSymbolValuePtr, source, sourceSize);
403
- return FSE_count_parallel(count, maxSymbolValuePtr, source, sourceSize, 0);
297
+ return FSE_writeNCount_generic(buffer, bufferSize, normalizedCounter, maxSymbolValue, tableLog, 1 /* write in buffer is safe */);
404
298
  }
405
299
 
406
- size_t FSE_count(unsigned* count, unsigned* maxSymbolValuePtr,
407
- const void* source, size_t sourceSize)
408
- {
409
- if (*maxSymbolValuePtr <255)
410
- return FSE_count_parallel(count, maxSymbolValuePtr, source, sourceSize, 1);
411
- *maxSymbolValuePtr = 255;
412
- return FSE_countFast(count, maxSymbolValuePtr, source, sourceSize);
413
- }
414
-
415
-
416
300
 
417
301
  /*-**************************************************************
418
302
  * FSE Compression Code
419
303
  ****************************************************************/
420
- /*! FSE_sizeof_CTable() :
421
- FSE_CTable is a variable size structure which contains :
422
- `U16 tableLog;`
423
- `U16 maxSymbolValue;`
424
- `U16 nextStateNumber[1 << tableLog];` // This size is variable
425
- `FSE_symbolCompressionTransform symbolTT[maxSymbolValue+1];` // This size is variable
426
- Allocation is manual (C standard does not support variable-size structures).
427
- */
428
-
429
- size_t FSE_sizeof_CTable (unsigned maxSymbolValue, unsigned tableLog)
430
- {
431
- size_t size;
432
- FSE_STATIC_ASSERT((size_t)FSE_CTABLE_SIZE_U32(FSE_MAX_TABLELOG, FSE_MAX_SYMBOL_VALUE)*4 >= sizeof(CTable_max_t)); /* A compilation error here means FSE_CTABLE_SIZE_U32 is not large enough */
433
- if (tableLog > FSE_MAX_TABLELOG) return ERROR(GENERIC);
434
- size = FSE_CTABLE_SIZE_U32 (tableLog, maxSymbolValue) * sizeof(U32);
435
- return size;
436
- }
437
304
 
438
305
  FSE_CTable* FSE_createCTable (unsigned maxSymbolValue, unsigned tableLog)
439
306
  {
@@ -448,20 +315,22 @@ void FSE_freeCTable (FSE_CTable* ct) { free(ct); }
448
315
  /* provides the minimum logSize to safely represent a distribution */
449
316
  static unsigned FSE_minTableLog(size_t srcSize, unsigned maxSymbolValue)
450
317
  {
451
- U32 minBitsSrc = BIT_highbit32((U32)(srcSize - 1)) + 1;
452
- U32 minBitsSymbols = BIT_highbit32(maxSymbolValue) + 2;
453
- U32 minBits = minBitsSrc < minBitsSymbols ? minBitsSrc : minBitsSymbols;
454
- return minBits;
318
+ U32 minBitsSrc = BIT_highbit32((U32)(srcSize)) + 1;
319
+ U32 minBitsSymbols = BIT_highbit32(maxSymbolValue) + 2;
320
+ U32 minBits = minBitsSrc < minBitsSymbols ? minBitsSrc : minBitsSymbols;
321
+ assert(srcSize > 1); /* Not supported, RLE should be used instead */
322
+ return minBits;
455
323
  }
456
324
 
457
325
  unsigned FSE_optimalTableLog_internal(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue, unsigned minus)
458
326
  {
459
- U32 maxBitsSrc = BIT_highbit32((U32)(srcSize - 1)) - minus;
327
+ U32 maxBitsSrc = BIT_highbit32((U32)(srcSize - 1)) - minus;
460
328
  U32 tableLog = maxTableLog;
461
- U32 minBits = FSE_minTableLog(srcSize, maxSymbolValue);
329
+ U32 minBits = FSE_minTableLog(srcSize, maxSymbolValue);
330
+ assert(srcSize > 1); /* Not supported, RLE should be used instead */
462
331
  if (tableLog==0) tableLog = FSE_DEFAULT_TABLELOG;
463
- if (maxBitsSrc < tableLog) tableLog = maxBitsSrc; /* Accuracy can be reduced */
464
- if (minBits > tableLog) tableLog = minBits; /* Need a minimum to safely represent all symbol values */
332
+ if (maxBitsSrc < tableLog) tableLog = maxBitsSrc; /* Accuracy can be reduced */
333
+ if (minBits > tableLog) tableLog = minBits; /* Need a minimum to safely represent all symbol values */
465
334
  if (tableLog < FSE_MIN_TABLELOG) tableLog = FSE_MIN_TABLELOG;
466
335
  if (tableLog > FSE_MAX_TABLELOG) tableLog = FSE_MAX_TABLELOG;
467
336
  return tableLog;
@@ -478,12 +347,13 @@ unsigned FSE_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxS
478
347
 
479
348
  static size_t FSE_normalizeM2(short* norm, U32 tableLog, const unsigned* count, size_t total, U32 maxSymbolValue)
480
349
  {
350
+ short const NOT_YET_ASSIGNED = -2;
481
351
  U32 s;
482
352
  U32 distributed = 0;
483
353
  U32 ToDistribute;
484
354
 
485
355
  /* Init */
486
- U32 lowThreshold = (U32)(total >> tableLog);
356
+ U32 const lowThreshold = (U32)(total >> tableLog);
487
357
  U32 lowOne = (U32)((total * 3) >> (tableLog + 1));
488
358
 
489
359
  for (s=0; s<=maxSymbolValue; s++) {
@@ -503,15 +373,19 @@ static size_t FSE_normalizeM2(short* norm, U32 tableLog, const unsigned* count,
503
373
  total -= count[s];
504
374
  continue;
505
375
  }
506
- norm[s]=-2;
376
+
377
+ norm[s]=NOT_YET_ASSIGNED;
507
378
  }
508
379
  ToDistribute = (1 << tableLog) - distributed;
509
380
 
381
+ if (ToDistribute == 0)
382
+ return 0;
383
+
510
384
  if ((total / ToDistribute) > lowOne) {
511
385
  /* risk of rounding to zero */
512
386
  lowOne = (U32)((total * 3) / (ToDistribute * 2));
513
387
  for (s=0; s<=maxSymbolValue; s++) {
514
- if ((norm[s] == -2) && (count[s] <= lowOne)) {
388
+ if ((norm[s] == NOT_YET_ASSIGNED) && (count[s] <= lowOne)) {
515
389
  norm[s] = 1;
516
390
  distributed++;
517
391
  total -= count[s];
@@ -526,22 +400,28 @@ static size_t FSE_normalizeM2(short* norm, U32 tableLog, const unsigned* count,
526
400
  find max, then give all remaining points to max */
527
401
  U32 maxV = 0, maxC = 0;
528
402
  for (s=0; s<=maxSymbolValue; s++)
529
- if (count[s] > maxC) maxV=s, maxC=count[s];
403
+ if (count[s] > maxC) { maxV=s; maxC=count[s]; }
530
404
  norm[maxV] += (short)ToDistribute;
531
405
  return 0;
532
406
  }
533
407
 
534
- {
535
- U64 const vStepLog = 62 - tableLog;
408
+ if (total == 0) {
409
+ /* all of the symbols were low enough for the lowOne or lowThreshold */
410
+ for (s=0; ToDistribute > 0; s = (s+1)%(maxSymbolValue+1))
411
+ if (norm[s] > 0) { ToDistribute--; norm[s]++; }
412
+ return 0;
413
+ }
414
+
415
+ { U64 const vStepLog = 62 - tableLog;
536
416
  U64 const mid = (1ULL << (vStepLog-1)) - 1;
537
417
  U64 const rStep = ((((U64)1<<vStepLog) * ToDistribute) + mid) / total; /* scale on remaining */
538
418
  U64 tmpTotal = mid;
539
419
  for (s=0; s<=maxSymbolValue; s++) {
540
- if (norm[s]==-2) {
541
- U64 end = tmpTotal + (count[s] * rStep);
542
- U32 sStart = (U32)(tmpTotal >> vStepLog);
543
- U32 sEnd = (U32)(end >> vStepLog);
544
- U32 weight = sEnd - sStart;
420
+ if (norm[s]==NOT_YET_ASSIGNED) {
421
+ U64 const end = tmpTotal + (count[s] * rStep);
422
+ U32 const sStart = (U32)(tmpTotal >> vStepLog);
423
+ U32 const sEnd = (U32)(end >> vStepLog);
424
+ U32 const weight = sEnd - sStart;
545
425
  if (weight < 1)
546
426
  return ERROR(GENERIC);
547
427
  norm[s] = (short)weight;
@@ -562,8 +442,7 @@ size_t FSE_normalizeCount (short* normalizedCounter, unsigned tableLog,
562
442
  if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge); /* Unsupported size */
563
443
  if (tableLog < FSE_minTableLog(total, maxSymbolValue)) return ERROR(GENERIC); /* Too small tableLog, compression potentially impossible */
564
444
 
565
- { U32 const rtbTable[] = { 0, 473195, 504333, 520860, 550000, 700000, 750000, 830000 };
566
-
445
+ { static U32 const rtbTable[] = { 0, 473195, 504333, 520860, 550000, 700000, 750000, 830000 };
567
446
  U64 const scale = 62 - tableLog;
568
447
  U64 const step = ((U64)1<<62) / total; /* <== here, one division ! */
569
448
  U64 const vStep = 1ULL<<(scale-20);
@@ -585,13 +464,13 @@ size_t FSE_normalizeCount (short* normalizedCounter, unsigned tableLog,
585
464
  U64 restToBeat = vStep * rtbTable[proba];
586
465
  proba += (count[s]*step) - ((U64)proba<<scale) > restToBeat;
587
466
  }
588
- if (proba > largestP) largestP=proba, largest=s;
467
+ if (proba > largestP) { largestP=proba; largest=s; }
589
468
  normalizedCounter[s] = proba;
590
469
  stillToDistribute -= proba;
591
470
  } }
592
471
  if (-stillToDistribute >= (normalizedCounter[largest] >> 1)) {
593
472
  /* corner case, need another normalization method */
594
- size_t errorCode = FSE_normalizeM2(normalizedCounter, tableLog, count, total, maxSymbolValue);
473
+ size_t const errorCode = FSE_normalizeM2(normalizedCounter, tableLog, count, total, maxSymbolValue);
595
474
  if (FSE_isError(errorCode)) return errorCode;
596
475
  }
597
476
  else normalizedCounter[largest] += (short)stillToDistribute;
@@ -602,11 +481,11 @@ size_t FSE_normalizeCount (short* normalizedCounter, unsigned tableLog,
602
481
  U32 s;
603
482
  U32 nTotal = 0;
604
483
  for (s=0; s<=maxSymbolValue; s++)
605
- printf("%3i: %4i \n", s, normalizedCounter[s]);
484
+ RAWLOG(2, "%3i: %4i \n", s, normalizedCounter[s]);
606
485
  for (s=0; s<=maxSymbolValue; s++)
607
486
  nTotal += abs(normalizedCounter[s]);
608
487
  if (nTotal != (1U<<tableLog))
609
- printf("Warning !!! Total == %u != %u !!!", nTotal, 1U<<tableLog);
488
+ RAWLOG(2, "Warning !!! Total == %u != %u !!!", nTotal, 1U<<tableLog);
610
489
  getchar();
611
490
  }
612
491
  #endif
@@ -640,17 +519,15 @@ size_t FSE_buildCTable_raw (FSE_CTable* ct, unsigned nbBits)
640
519
 
641
520
  /* Build Symbol Transformation Table */
642
521
  { const U32 deltaNbBits = (nbBits << 16) - (1 << nbBits);
643
-
644
522
  for (s=0; s<=maxSymbolValue; s++) {
645
523
  symbolTT[s].deltaNbBits = deltaNbBits;
646
524
  symbolTT[s].deltaFindState = s-1;
647
525
  } }
648
526
 
649
-
650
527
  return 0;
651
528
  }
652
529
 
653
- /* fake FSE_CTable, for rle (100% always same symbol) input */
530
+ /* fake FSE_CTable, for rle input (always same symbol) */
654
531
  size_t FSE_buildCTable_rle (FSE_CTable* ct, BYTE symbolValue)
655
532
  {
656
533
  void* ptr = ct;
@@ -682,14 +559,13 @@ static size_t FSE_compress_usingCTable_generic (void* dst, size_t dstSize,
682
559
  const BYTE* const iend = istart + srcSize;
683
560
  const BYTE* ip=iend;
684
561
 
685
-
686
562
  BIT_CStream_t bitC;
687
563
  FSE_CState_t CState1, CState2;
688
564
 
689
565
  /* init */
690
566
  if (srcSize <= 2) return 0;
691
- { size_t const errorCode = BIT_initCStream(&bitC, dst, dstSize);
692
- if (FSE_isError(errorCode)) return 0; }
567
+ { size_t const initError = BIT_initCStream(&bitC, dst, dstSize);
568
+ if (FSE_isError(initError)) return 0; /* not enough space available to write a bitstream */ }
693
569
 
694
570
  #define FSE_FLUSHBITS(s) (fast ? BIT_flushBitsFast(s) : BIT_flushBits(s))
695
571
 
@@ -712,7 +588,7 @@ static size_t FSE_compress_usingCTable_generic (void* dst, size_t dstSize,
712
588
  }
713
589
 
714
590
  /* 2 or 4 encoding per loop */
715
- for ( ; ip>istart ; ) {
591
+ while ( ip>istart ) {
716
592
 
717
593
  FSE_encodeSymbol(&bitC, &CState2, *--ip);
718
594
 
@@ -738,7 +614,7 @@ size_t FSE_compress_usingCTable (void* dst, size_t dstSize,
738
614
  const void* src, size_t srcSize,
739
615
  const FSE_CTable* ct)
740
616
  {
741
- const unsigned fast = (dstSize >= FSE_BLOCKBOUND(srcSize));
617
+ unsigned const fast = (dstSize >= FSE_BLOCKBOUND(srcSize));
742
618
 
743
619
  if (fast)
744
620
  return FSE_compress_usingCTable_generic(dst, dstSize, src, srcSize, ct, 1);
@@ -749,58 +625,73 @@ size_t FSE_compress_usingCTable (void* dst, size_t dstSize,
749
625
 
750
626
  size_t FSE_compressBound(size_t size) { return FSE_COMPRESSBOUND(size); }
751
627
 
752
- size_t FSE_compress2 (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog)
628
+ /* FSE_compress_wksp() :
629
+ * Same as FSE_compress2(), but using an externally allocated scratch buffer (`workSpace`).
630
+ * `wkspSize` size must be `(1<<tableLog)`.
631
+ */
632
+ size_t FSE_compress_wksp (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize)
753
633
  {
754
- const BYTE* const istart = (const BYTE*) src;
755
- const BYTE* ip = istart;
756
-
757
634
  BYTE* const ostart = (BYTE*) dst;
758
635
  BYTE* op = ostart;
759
636
  BYTE* const oend = ostart + dstSize;
760
637
 
761
- U32 count[FSE_MAX_SYMBOL_VALUE+1];
638
+ unsigned count[FSE_MAX_SYMBOL_VALUE+1];
762
639
  S16 norm[FSE_MAX_SYMBOL_VALUE+1];
763
- CTable_max_t ct;
764
- size_t errorCode;
640
+ FSE_CTable* CTable = (FSE_CTable*)workSpace;
641
+ size_t const CTableSize = FSE_CTABLE_SIZE_U32(tableLog, maxSymbolValue);
642
+ void* scratchBuffer = (void*)(CTable + CTableSize);
643
+ size_t const scratchBufferSize = wkspSize - (CTableSize * sizeof(FSE_CTable));
765
644
 
766
645
  /* init conditions */
767
- if (srcSize <= 1) return 0; /* Uncompressible */
646
+ if (wkspSize < FSE_WKSP_SIZE_U32(tableLog, maxSymbolValue)) return ERROR(tableLog_tooLarge);
647
+ if (srcSize <= 1) return 0; /* Not compressible */
768
648
  if (!maxSymbolValue) maxSymbolValue = FSE_MAX_SYMBOL_VALUE;
769
649
  if (!tableLog) tableLog = FSE_DEFAULT_TABLELOG;
770
650
 
771
651
  /* Scan input and build symbol stats */
772
- errorCode = FSE_count (count, &maxSymbolValue, ip, srcSize);
773
- if (FSE_isError(errorCode)) return errorCode;
774
- if (errorCode == srcSize) return 1;
775
- if (errorCode == 1) return 0; /* each symbol only present once */
776
- if (errorCode < (srcSize >> 7)) return 0; /* Heuristic : not compressible enough */
652
+ { CHECK_V_F(maxCount, HIST_count_wksp(count, &maxSymbolValue, src, srcSize, scratchBuffer, scratchBufferSize) );
653
+ if (maxCount == srcSize) return 1; /* only a single symbol in src : rle */
654
+ if (maxCount == 1) return 0; /* each symbol present maximum once => not compressible */
655
+ if (maxCount < (srcSize >> 7)) return 0; /* Heuristic : not compressible enough */
656
+ }
777
657
 
778
658
  tableLog = FSE_optimalTableLog(tableLog, srcSize, maxSymbolValue);
779
- errorCode = FSE_normalizeCount (norm, tableLog, count, srcSize, maxSymbolValue);
780
- if (FSE_isError(errorCode)) return errorCode;
659
+ CHECK_F( FSE_normalizeCount(norm, tableLog, count, srcSize, maxSymbolValue) );
781
660
 
782
661
  /* Write table description header */
783
- errorCode = FSE_writeNCount (op, oend-op, norm, maxSymbolValue, tableLog);
784
- if (FSE_isError(errorCode)) return errorCode;
785
- op += errorCode;
662
+ { CHECK_V_F(nc_err, FSE_writeNCount(op, oend-op, norm, maxSymbolValue, tableLog) );
663
+ op += nc_err;
664
+ }
786
665
 
787
666
  /* Compress */
788
- errorCode = FSE_buildCTable (ct, norm, maxSymbolValue, tableLog);
789
- if (FSE_isError(errorCode)) return errorCode;
790
- errorCode = FSE_compress_usingCTable(op, oend - op, ip, srcSize, ct);
791
- if (errorCode == 0) return 0; /* not enough space for compressed data */
792
- op += errorCode;
667
+ CHECK_F( FSE_buildCTable_wksp(CTable, norm, maxSymbolValue, tableLog, scratchBuffer, scratchBufferSize) );
668
+ { CHECK_V_F(cSize, FSE_compress_usingCTable(op, oend - op, src, srcSize, CTable) );
669
+ if (cSize == 0) return 0; /* not enough space for compressed data */
670
+ op += cSize;
671
+ }
793
672
 
794
673
  /* check compressibility */
795
- if ( (size_t)(op-ostart) >= srcSize-1 )
796
- return 0;
674
+ if ( (size_t)(op-ostart) >= srcSize-1 ) return 0;
797
675
 
798
676
  return op-ostart;
799
677
  }
800
678
 
801
- size_t FSE_compress (void* dst, size_t dstSize, const void* src, size_t srcSize)
679
+ typedef struct {
680
+ FSE_CTable CTable_max[FSE_CTABLE_SIZE_U32(FSE_MAX_TABLELOG, FSE_MAX_SYMBOL_VALUE)];
681
+ BYTE scratchBuffer[1 << FSE_MAX_TABLELOG];
682
+ } fseWkspMax_t;
683
+
684
+ size_t FSE_compress2 (void* dst, size_t dstCapacity, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog)
685
+ {
686
+ fseWkspMax_t scratchBuffer;
687
+ DEBUG_STATIC_ASSERT(sizeof(scratchBuffer) >= FSE_WKSP_SIZE_U32(FSE_MAX_TABLELOG, FSE_MAX_SYMBOL_VALUE)); /* compilation failures here means scratchBuffer is not large enough */
688
+ if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge);
689
+ return FSE_compress_wksp(dst, dstCapacity, src, srcSize, maxSymbolValue, tableLog, &scratchBuffer, sizeof(scratchBuffer));
690
+ }
691
+
692
+ size_t FSE_compress (void* dst, size_t dstCapacity, const void* src, size_t srcSize)
802
693
  {
803
- return FSE_compress2(dst, dstSize, src, (U32)srcSize, FSE_MAX_SYMBOL_VALUE, FSE_DEFAULT_TABLELOG);
694
+ return FSE_compress2(dst, dstCapacity, src, srcSize, FSE_MAX_SYMBOL_VALUE, FSE_DEFAULT_TABLELOG);
804
695
  }
805
696
 
806
697