extzstd 0.0.3.CONCEPT → 0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/HISTORY.ja +5 -0
  3. data/LICENSE +6 -6
  4. data/README.md +35 -22
  5. data/contrib/zstd/LICENSE +13 -9
  6. data/contrib/zstd/README.md +37 -44
  7. data/contrib/zstd/common/entropy_common.c +33 -39
  8. data/contrib/zstd/common/error_private.c +43 -0
  9. data/contrib/zstd/common/error_private.h +11 -60
  10. data/contrib/zstd/common/fse.h +11 -5
  11. data/contrib/zstd/common/fse_decompress.c +14 -16
  12. data/contrib/zstd/common/huf.h +1 -1
  13. data/contrib/zstd/common/mem.h +36 -43
  14. data/contrib/zstd/common/xxhash.c +31 -18
  15. data/contrib/zstd/common/xxhash.h +71 -35
  16. data/contrib/zstd/common/zbuff.h +29 -35
  17. data/contrib/zstd/common/zstd_common.c +24 -32
  18. data/contrib/zstd/common/zstd_errors.h +60 -0
  19. data/contrib/zstd/common/zstd_internal.h +109 -80
  20. data/contrib/zstd/compress/fse_compress.c +9 -6
  21. data/contrib/zstd/compress/huf_compress.c +30 -74
  22. data/contrib/zstd/compress/zbuff_compress.c +43 -51
  23. data/contrib/zstd/compress/zstd_compress.c +953 -763
  24. data/contrib/zstd/compress/zstd_opt.h +115 -261
  25. data/contrib/zstd/decompress/huf_decompress.c +29 -40
  26. data/contrib/zstd/decompress/zbuff_decompress.c +36 -78
  27. data/contrib/zstd/decompress/zstd_decompress.c +976 -496
  28. data/contrib/zstd/dictBuilder/divsufsort.h +5 -5
  29. data/contrib/zstd/dictBuilder/zdict.c +194 -229
  30. data/contrib/zstd/dictBuilder/zdict.h +66 -68
  31. data/contrib/zstd/legacy/zstd_legacy.h +168 -49
  32. data/contrib/zstd/legacy/zstd_v01.c +95 -178
  33. data/contrib/zstd/legacy/zstd_v01.h +12 -32
  34. data/contrib/zstd/legacy/zstd_v02.c +48 -274
  35. data/contrib/zstd/legacy/zstd_v02.h +12 -32
  36. data/contrib/zstd/legacy/zstd_v03.c +48 -274
  37. data/contrib/zstd/legacy/zstd_v03.h +12 -32
  38. data/contrib/zstd/legacy/zstd_v04.c +63 -320
  39. data/contrib/zstd/legacy/zstd_v04.h +13 -33
  40. data/contrib/zstd/legacy/zstd_v05.c +80 -345
  41. data/contrib/zstd/legacy/zstd_v05.h +9 -31
  42. data/contrib/zstd/legacy/zstd_v06.c +48 -458
  43. data/contrib/zstd/legacy/zstd_v06.h +41 -67
  44. data/contrib/zstd/legacy/zstd_v07.c +4544 -0
  45. data/contrib/zstd/legacy/zstd_v07.h +173 -0
  46. data/contrib/zstd/zstd.h +640 -0
  47. data/ext/extconf.rb +7 -3
  48. data/ext/extzstd.c +263 -106
  49. data/ext/extzstd.h +8 -6
  50. data/ext/extzstd_nogvls.h +0 -117
  51. data/ext/extzstd_stream.c +347 -0
  52. data/ext/zstd_common.c +8 -0
  53. data/ext/zstd_compress.c +6 -0
  54. data/ext/zstd_decompress.c +5 -0
  55. data/ext/zstd_dictbuilder.c +5 -0
  56. data/ext/zstd_legacy_v07.c +1 -0
  57. data/gemstub.rb +18 -16
  58. data/lib/extzstd/version.rb +1 -1
  59. data/lib/extzstd.rb +77 -43
  60. data/test/test_basic.rb +11 -6
  61. metadata +23 -10
  62. data/contrib/zstd/common/error_public.h +0 -77
  63. data/contrib/zstd/common/zstd.h +0 -475
  64. data/ext/extzstd_buffered.c +0 -265
  65. data/ext/zstd_amalgam.c +0 -18
@@ -1,51 +1,11 @@
1
- /*
2
- ZSTD HC - High Compression Mode of Zstandard
3
- Copyright (C) 2015-2016, 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
- - Zstd source repository : https://www.zstd.net
32
- */
33
-
34
-
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
- #else
43
- # ifdef __GNUC__
44
- # define FORCE_INLINE static inline __attribute__((always_inline))
45
- # else
46
- # define FORCE_INLINE static inline
47
- # endif
48
- #endif
1
+ /**
2
+ * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
3
+ * All rights reserved.
4
+ *
5
+ * This source code is licensed under the BSD-style license found in the
6
+ * LICENSE file in the root directory of this source tree. An additional grant
7
+ * of patent rights can be found in the PATENTS file in the same directory.
8
+ */
49
9
 
50
10
 
51
11
  /*-*************************************
@@ -54,8 +14,8 @@
54
14
  #include <string.h> /* memset */
55
15
  #include "mem.h"
56
16
  #define XXH_STATIC_LINKING_ONLY /* XXH64_state_t */
57
- #include "xxhash.h" /* XXH_reset, update, digest */
58
- #define FSE_STATIC_LINKING_ONLY
17
+ #include "xxhash.h" /* XXH_reset, update, digest */
18
+ #define FSE_STATIC_LINKING_ONLY /* FSE_encodeSymbol */
59
19
  #include "fse.h"
60
20
  #define HUF_STATIC_LINKING_ONLY
61
21
  #include "huf.h"
@@ -66,6 +26,8 @@
66
26
  * Constants
67
27
  ***************************************/
68
28
  static const U32 g_searchStrength = 8; /* control skip over incompressible data */
29
+ #define HASH_READ_SIZE 8
30
+ typedef enum { ZSTDcs_created=0, ZSTDcs_init, ZSTDcs_ongoing, ZSTDcs_ending } ZSTD_compressionStage_e;
69
31
 
70
32
 
71
33
  /*-*************************************
@@ -73,37 +35,14 @@ static const U32 g_searchStrength = 8; /* control skip over incompressible dat
73
35
  ***************************************/
74
36
  size_t ZSTD_compressBound(size_t srcSize) { return FSE_compressBound(srcSize) + 12; }
75
37
 
76
- static U32 ZSTD_highbit32(U32 val)
77
- {
78
- # if defined(_MSC_VER) /* Visual */
79
- unsigned long r=0;
80
- _BitScanReverse(&r, val);
81
- return (unsigned)r;
82
- # elif defined(__GNUC__) && (__GNUC__ >= 3) /* GCC Intrinsic */
83
- return 31 - __builtin_clz(val);
84
- # else /* Software version */
85
- 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 };
86
- U32 v = val;
87
- int r;
88
- v |= v >> 1;
89
- v |= v >> 2;
90
- v |= v >> 4;
91
- v |= v >> 8;
92
- v |= v >> 16;
93
- r = DeBruijnClz[(U32)(v * 0x07C4ACDDU) >> 27];
94
- return r;
95
- # endif
96
- }
97
38
 
98
39
  /*-*************************************
99
40
  * Sequence storage
100
41
  ***************************************/
101
42
  static void ZSTD_resetSeqStore(seqStore_t* ssPtr)
102
43
  {
103
- ssPtr->offset = ssPtr->offsetStart;
104
44
  ssPtr->lit = ssPtr->litStart;
105
- ssPtr->litLength = ssPtr->litLengthStart;
106
- ssPtr->matchLength = ssPtr->matchLengthStart;
45
+ ssPtr->sequences = ssPtr->sequencesStart;
107
46
  ssPtr->longLengthID = 0;
108
47
  }
109
48
 
@@ -122,7 +61,7 @@ struct ZSTD_CCtx_s
122
61
  U32 nextToUpdate3; /* index from which to continue dictionary update */
123
62
  U32 hashLog3; /* dispatch table : larger == faster, more memory */
124
63
  U32 loadedDictEnd;
125
- U32 stage; /* 0: created; 1: init,dictLoad; 2:started */
64
+ ZSTD_compressionStage_e stage;
126
65
  U32 rep[ZSTD_REP_NUM];
127
66
  U32 savedRep[ZSTD_REP_NUM];
128
67
  U32 dictID;
@@ -140,9 +79,9 @@ struct ZSTD_CCtx_s
140
79
  U32* chainTable;
141
80
  HUF_CElt* hufTable;
142
81
  U32 flagStaticTables;
143
- FSE_CTable offcodeCTable [FSE_CTABLE_SIZE_U32(OffFSELog, MaxOff)];
144
- FSE_CTable matchlengthCTable [FSE_CTABLE_SIZE_U32(MLFSELog, MaxML)];
145
- FSE_CTable litlengthCTable [FSE_CTABLE_SIZE_U32(LLFSELog, MaxLL)];
82
+ FSE_CTable offcodeCTable [FSE_CTABLE_SIZE_U32(OffFSELog, MaxOff)];
83
+ FSE_CTable matchlengthCTable[FSE_CTABLE_SIZE_U32(MLFSELog, MaxML)];
84
+ FSE_CTable litlengthCTable [FSE_CTABLE_SIZE_U32(LLFSELog, MaxLL)];
146
85
  };
147
86
 
148
87
  ZSTD_CCtx* ZSTD_createCCtx(void)
@@ -154,29 +93,27 @@ ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem)
154
93
  {
155
94
  ZSTD_CCtx* cctx;
156
95
 
157
- if (!customMem.customAlloc && !customMem.customFree)
158
- customMem = defaultCustomMem;
96
+ if (!customMem.customAlloc && !customMem.customFree) customMem = defaultCustomMem;
97
+ if (!customMem.customAlloc || !customMem.customFree) return NULL;
159
98
 
160
- if (!customMem.customAlloc || !customMem.customFree)
161
- return NULL;
162
-
163
- cctx = (ZSTD_CCtx*) customMem.customAlloc(customMem.opaque, sizeof(ZSTD_CCtx));
99
+ cctx = (ZSTD_CCtx*) ZSTD_malloc(sizeof(ZSTD_CCtx), customMem);
164
100
  if (!cctx) return NULL;
165
101
  memset(cctx, 0, sizeof(ZSTD_CCtx));
166
- memcpy(&(cctx->customMem), &customMem, sizeof(ZSTD_customMem));
102
+ memcpy(&(cctx->customMem), &customMem, sizeof(customMem));
167
103
  return cctx;
168
104
  }
169
105
 
170
106
  size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx)
171
107
  {
172
108
  if (cctx==NULL) return 0; /* support free on NULL */
173
- if (cctx->workSpace) cctx->customMem.customFree(cctx->customMem.opaque, cctx->workSpace);
174
- cctx->customMem.customFree(cctx->customMem.opaque, cctx);
109
+ ZSTD_free(cctx->workSpace, cctx->customMem);
110
+ ZSTD_free(cctx, cctx->customMem);
175
111
  return 0; /* reserved as a potential error code in the future */
176
112
  }
177
113
 
178
- size_t ZSTD_sizeofCCtx(const ZSTD_CCtx* cctx)
114
+ size_t ZSTD_sizeof_CCtx(const ZSTD_CCtx* cctx)
179
115
  {
116
+ if (cctx==NULL) return 0; /* support sizeof on NULL */
180
117
  return sizeof(*cctx) + cctx->workSpaceSize;
181
118
  }
182
119
 
@@ -185,43 +122,33 @@ const seqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx) /* hidden interface *
185
122
  return &(ctx->seqStore);
186
123
  }
187
124
 
125
+ static ZSTD_parameters ZSTD_getParamsFromCCtx(const ZSTD_CCtx* cctx)
126
+ {
127
+ return cctx->params;
128
+ }
188
129
 
189
- #define CLAMP(val,min,max) { if (val<min) val=min; else if (val>max) val=max; }
190
- #define CLAMPCHECK(val,min,max) { if ((val<min) || (val>max)) return ERROR(compressionParameter_unsupported); }
191
130
 
192
131
  /** ZSTD_checkParams() :
193
132
  ensure param values remain within authorized range.
194
133
  @return : 0, or an error code if one value is beyond authorized range */
195
134
  size_t ZSTD_checkCParams(ZSTD_compressionParameters cParams)
196
135
  {
136
+ # define CLAMPCHECK(val,min,max) { if ((val<min) | (val>max)) return ERROR(compressionParameter_unsupported); }
197
137
  CLAMPCHECK(cParams.windowLog, ZSTD_WINDOWLOG_MIN, ZSTD_WINDOWLOG_MAX);
198
138
  CLAMPCHECK(cParams.chainLog, ZSTD_CHAINLOG_MIN, ZSTD_CHAINLOG_MAX);
199
139
  CLAMPCHECK(cParams.hashLog, ZSTD_HASHLOG_MIN, ZSTD_HASHLOG_MAX);
200
140
  CLAMPCHECK(cParams.searchLog, ZSTD_SEARCHLOG_MIN, ZSTD_SEARCHLOG_MAX);
201
- { U32 const searchLengthMin = (cParams.strategy == ZSTD_fast || cParams.strategy == ZSTD_greedy) ? ZSTD_SEARCHLENGTH_MIN+1 : ZSTD_SEARCHLENGTH_MIN;
141
+ { U32 const searchLengthMin = ((cParams.strategy == ZSTD_fast) | (cParams.strategy == ZSTD_greedy)) ? ZSTD_SEARCHLENGTH_MIN+1 : ZSTD_SEARCHLENGTH_MIN;
202
142
  U32 const searchLengthMax = (cParams.strategy == ZSTD_fast) ? ZSTD_SEARCHLENGTH_MAX : ZSTD_SEARCHLENGTH_MAX-1;
203
143
  CLAMPCHECK(cParams.searchLength, searchLengthMin, searchLengthMax); }
204
144
  CLAMPCHECK(cParams.targetLength, ZSTD_TARGETLENGTH_MIN, ZSTD_TARGETLENGTH_MAX);
205
- if ((U32)(cParams.strategy) > (U32)ZSTD_btopt) return ERROR(compressionParameter_unsupported);
145
+ if ((U32)(cParams.strategy) > (U32)ZSTD_btopt2) return ERROR(compressionParameter_unsupported);
206
146
  return 0;
207
147
  }
208
148
 
209
149
 
210
- /** ZSTD_checkCParams_advanced() :
211
- temporary work-around, while the compressor compatibility remains limited regarding windowLog < 18 */
212
- size_t ZSTD_checkCParams_advanced(ZSTD_compressionParameters cParams, U64 srcSize)
213
- {
214
- if (srcSize > (1ULL << ZSTD_WINDOWLOG_MIN)) return ZSTD_checkCParams(cParams);
215
- if (cParams.windowLog < ZSTD_WINDOWLOG_ABSOLUTEMIN) return ERROR(compressionParameter_unsupported);
216
- if (srcSize <= (1ULL << cParams.windowLog)) cParams.windowLog = ZSTD_WINDOWLOG_MIN; /* fake value - temporary work around */
217
- if (srcSize <= (1ULL << cParams.chainLog)) cParams.chainLog = ZSTD_CHAINLOG_MIN; /* fake value - temporary work around */
218
- if ((srcSize <= (1ULL << cParams.hashLog)) && ((U32)cParams.strategy < (U32)ZSTD_btlazy2)) cParams.hashLog = ZSTD_HASHLOG_MIN; /* fake value - temporary work around */
219
- return ZSTD_checkCParams(cParams);
220
- }
221
-
222
-
223
150
  /** ZSTD_adjustCParams() :
224
- optimize cPar for a given input (`srcSize` and `dictSize`).
151
+ optimize `cPar` for a given input (`srcSize` and `dictSize`).
225
152
  mostly downsizing to reduce memory consumption and initialization.
226
153
  Both `srcSize` and `dictSize` are optional (use 0 if unknown),
227
154
  but if both are 0, no optimization can be done.
@@ -234,16 +161,15 @@ ZSTD_compressionParameters ZSTD_adjustCParams(ZSTD_compressionParameters cPar, u
234
161
  { U32 const minSrcSize = (srcSize==0) ? 500 : 0;
235
162
  U64 const rSize = srcSize + dictSize + minSrcSize;
236
163
  if (rSize < ((U64)1<<ZSTD_WINDOWLOG_MAX)) {
237
- U32 const srcLog = ZSTD_highbit32((U32)(rSize)-1) + 1;
164
+ U32 const srcLog = MAX(ZSTD_HASHLOG_MIN, ZSTD_highbit32((U32)(rSize)-1) + 1);
238
165
  if (cPar.windowLog > srcLog) cPar.windowLog = srcLog;
239
166
  } }
240
167
  if (cPar.hashLog > cPar.windowLog) cPar.hashLog = cPar.windowLog;
241
- { U32 const btPlus = (cPar.strategy == ZSTD_btlazy2) || (cPar.strategy == ZSTD_btopt);
168
+ { U32 const btPlus = (cPar.strategy == ZSTD_btlazy2) | (cPar.strategy == ZSTD_btopt) | (cPar.strategy == ZSTD_btopt2);
242
169
  U32 const maxChainLog = cPar.windowLog+btPlus;
243
170
  if (cPar.chainLog > maxChainLog) cPar.chainLog = maxChainLog; } /* <= ZSTD_CHAINLOG_MAX */
244
171
 
245
172
  if (cPar.windowLog < ZSTD_WINDOWLOG_ABSOLUTEMIN) cPar.windowLog = ZSTD_WINDOWLOG_ABSOLUTEMIN; /* required for frame header */
246
- if ((cPar.hashLog < ZSTD_HASHLOG_MIN) && ( (U32)cPar.strategy >= (U32)ZSTD_btlazy2)) cPar.hashLog = ZSTD_HASHLOG_MIN; /* required to ensure collision resistance in bt */
247
173
 
248
174
  return cPar;
249
175
  }
@@ -251,121 +177,154 @@ ZSTD_compressionParameters ZSTD_adjustCParams(ZSTD_compressionParameters cPar, u
251
177
 
252
178
  size_t ZSTD_estimateCCtxSize(ZSTD_compressionParameters cParams)
253
179
  {
254
- const size_t blockSize = MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << cParams.windowLog);
255
- const U32 divider = (cParams.searchLength==3) ? 3 : 4;
256
- const size_t maxNbSeq = blockSize / divider;
257
- const size_t tokenSpace = blockSize + 11*maxNbSeq;
180
+ size_t const blockSize = MIN(ZSTD_BLOCKSIZE_ABSOLUTEMAX, (size_t)1 << cParams.windowLog);
181
+ U32 const divider = (cParams.searchLength==3) ? 3 : 4;
182
+ size_t const maxNbSeq = blockSize / divider;
183
+ size_t const tokenSpace = blockSize + 11*maxNbSeq;
258
184
 
259
- const size_t chainSize = (cParams.strategy == ZSTD_fast) ? 0 : (1 << cParams.chainLog);
260
- const size_t hSize = ((size_t)1) << cParams.hashLog;
261
- const U32 hashLog3 = (cParams.searchLength>3) ? 0 : MIN(ZSTD_HASHLOG3_MAX, cParams.windowLog);
262
- const size_t h3Size = ((size_t)1) << hashLog3;
263
- const size_t tableSpace = (chainSize + hSize + h3Size) * sizeof(U32);
185
+ size_t const chainSize = (cParams.strategy == ZSTD_fast) ? 0 : (1 << cParams.chainLog);
186
+ size_t const hSize = ((size_t)1) << cParams.hashLog;
187
+ U32 const hashLog3 = (cParams.searchLength>3) ? 0 : MIN(ZSTD_HASHLOG3_MAX, cParams.windowLog);
188
+ size_t const h3Size = ((size_t)1) << hashLog3;
189
+ size_t const tableSpace = (chainSize + hSize + h3Size) * sizeof(U32);
264
190
 
265
191
  size_t const optSpace = ((MaxML+1) + (MaxLL+1) + (MaxOff+1) + (1<<Litbits))*sizeof(U32)
266
192
  + (ZSTD_OPT_NUM+1)*(sizeof(ZSTD_match_t) + sizeof(ZSTD_optimal_t));
267
193
  size_t const neededSpace = tableSpace + (256*sizeof(U32)) /* huffTable */ + tokenSpace
268
- + ((cParams.strategy == ZSTD_btopt) ? optSpace : 0);
194
+ + (((cParams.strategy == ZSTD_btopt) || (cParams.strategy == ZSTD_btopt2)) ? optSpace : 0);
269
195
 
270
196
  return sizeof(ZSTD_CCtx) + neededSpace;
271
197
  }
272
198
 
199
+
200
+ static U32 ZSTD_equivalentParams(ZSTD_parameters param1, ZSTD_parameters param2)
201
+ {
202
+ return (param1.cParams.hashLog == param2.cParams.hashLog)
203
+ & (param1.cParams.chainLog == param2.cParams.chainLog)
204
+ & (param1.cParams.strategy == param2.cParams.strategy)
205
+ & ((param1.cParams.searchLength==3) == (param2.cParams.searchLength==3));
206
+ }
207
+
208
+ /*! ZSTD_continueCCtx() :
209
+ reuse CCtx without reset (note : requires no dictionary) */
210
+ static size_t ZSTD_continueCCtx(ZSTD_CCtx* cctx, ZSTD_parameters params, U64 frameContentSize)
211
+ {
212
+ U32 const end = (U32)(cctx->nextSrc - cctx->base);
213
+ cctx->params = params;
214
+ cctx->frameContentSize = frameContentSize;
215
+ cctx->lowLimit = end;
216
+ cctx->dictLimit = end;
217
+ cctx->nextToUpdate = end+1;
218
+ cctx->stage = ZSTDcs_init;
219
+ cctx->dictID = 0;
220
+ cctx->loadedDictEnd = 0;
221
+ { int i; for (i=0; i<ZSTD_REP_NUM; i++) cctx->rep[i] = repStartValue[i]; }
222
+ cctx->seqStore.litLengthSum = 0; /* force reset of btopt stats */
223
+ XXH64_reset(&cctx->xxhState, 0);
224
+ return 0;
225
+ }
226
+
227
+ typedef enum { ZSTDcrp_continue, ZSTDcrp_noMemset, ZSTDcrp_fullReset } ZSTD_compResetPolicy_e;
228
+
273
229
  /*! ZSTD_resetCCtx_advanced() :
274
- note : 'params' is expected to be validated */
230
+ note : 'params' must be validated */
275
231
  static size_t ZSTD_resetCCtx_advanced (ZSTD_CCtx* zc,
276
232
  ZSTD_parameters params, U64 frameContentSize,
277
- U32 reset)
278
- { /* note : params considered validated here */
279
- const size_t blockSize = MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << params.cParams.windowLog);
280
- const U32 divider = (params.cParams.searchLength==3) ? 3 : 4;
281
- const size_t maxNbSeq = blockSize / divider;
282
- const size_t tokenSpace = blockSize + 11*maxNbSeq;
283
- const size_t chainSize = (params.cParams.strategy == ZSTD_fast) ? 0 : (1 << params.cParams.chainLog);
284
- const size_t hSize = ((size_t)1) << params.cParams.hashLog;
285
- const U32 hashLog3 = (params.cParams.searchLength>3) ? 0 : MIN(ZSTD_HASHLOG3_MAX, params.cParams.windowLog);
286
- const size_t h3Size = ((size_t)1) << hashLog3;
287
- const size_t tableSpace = (chainSize + hSize + h3Size) * sizeof(U32);
288
-
289
- /* Check if workSpace is large enough, alloc a new one if needed */
290
- { size_t const optSpace = ((MaxML+1) + (MaxLL+1) + (MaxOff+1) + (1<<Litbits))*sizeof(U32)
291
- + (ZSTD_OPT_NUM+1)*(sizeof(ZSTD_match_t) + sizeof(ZSTD_optimal_t));
292
- size_t const neededSpace = tableSpace + (256*sizeof(U32)) /* huffTable */ + tokenSpace
293
- + ((params.cParams.strategy == ZSTD_btopt) ? optSpace : 0);
294
- if (zc->workSpaceSize < neededSpace) {
295
- zc->customMem.customFree(zc->customMem.opaque, zc->workSpace);
296
- zc->workSpace = zc->customMem.customAlloc(zc->customMem.opaque, neededSpace);
297
- if (zc->workSpace == NULL) return ERROR(memory_allocation);
298
- zc->workSpaceSize = neededSpace;
299
- } }
233
+ ZSTD_compResetPolicy_e const crp)
234
+ {
235
+ if (crp == ZSTDcrp_continue)
236
+ if (ZSTD_equivalentParams(params, zc->params))
237
+ return ZSTD_continueCCtx(zc, params, frameContentSize);
238
+
239
+ { size_t const blockSize = MIN(ZSTD_BLOCKSIZE_ABSOLUTEMAX, (size_t)1 << params.cParams.windowLog);
240
+ U32 const divider = (params.cParams.searchLength==3) ? 3 : 4;
241
+ size_t const maxNbSeq = blockSize / divider;
242
+ size_t const tokenSpace = blockSize + 11*maxNbSeq;
243
+ size_t const chainSize = (params.cParams.strategy == ZSTD_fast) ? 0 : (1 << params.cParams.chainLog);
244
+ size_t const hSize = ((size_t)1) << params.cParams.hashLog;
245
+ U32 const hashLog3 = (params.cParams.searchLength>3) ? 0 : MIN(ZSTD_HASHLOG3_MAX, params.cParams.windowLog);
246
+ size_t const h3Size = ((size_t)1) << hashLog3;
247
+ size_t const tableSpace = (chainSize + hSize + h3Size) * sizeof(U32);
248
+ void* ptr;
249
+
250
+ /* Check if workSpace is large enough, alloc a new one if needed */
251
+ { size_t const optSpace = ((MaxML+1) + (MaxLL+1) + (MaxOff+1) + (1<<Litbits))*sizeof(U32)
252
+ + (ZSTD_OPT_NUM+1)*(sizeof(ZSTD_match_t) + sizeof(ZSTD_optimal_t));
253
+ size_t const neededSpace = tableSpace + (256*sizeof(U32)) /* huffTable */ + tokenSpace
254
+ + (((params.cParams.strategy == ZSTD_btopt) || (params.cParams.strategy == ZSTD_btopt2)) ? optSpace : 0);
255
+ if (zc->workSpaceSize < neededSpace) {
256
+ ZSTD_free(zc->workSpace, zc->customMem);
257
+ zc->workSpace = ZSTD_malloc(neededSpace, zc->customMem);
258
+ if (zc->workSpace == NULL) return ERROR(memory_allocation);
259
+ zc->workSpaceSize = neededSpace;
260
+ } }
300
261
 
301
- if (reset) memset(zc->workSpace, 0, tableSpace ); /* reset only tables */
302
- XXH64_reset(&zc->xxhState, 0);
303
- zc->hashLog3 = hashLog3;
304
- zc->hashTable = (U32*)(zc->workSpace);
305
- zc->chainTable = zc->hashTable + hSize;
306
- zc->hashTable3 = zc->chainTable + chainSize;
307
- zc->seqStore.buffer = zc->hashTable3 + h3Size;
308
- zc->hufTable = (HUF_CElt*)zc->seqStore.buffer;
309
- zc->flagStaticTables = 0;
310
- zc->seqStore.buffer = ((U32*)(zc->seqStore.buffer)) + 256; /* note : HUF_CElt* is incomplete type, size is simulated using U32 */
311
-
312
- zc->nextToUpdate = 1;
313
- zc->nextSrc = NULL;
314
- zc->base = NULL;
315
- zc->dictBase = NULL;
316
- zc->dictLimit = 0;
317
- zc->lowLimit = 0;
318
- zc->params = params;
319
- zc->blockSize = blockSize;
320
- zc->frameContentSize = frameContentSize;
321
- { int i; for (i=0; i<ZSTD_REP_NUM; i++) zc->rep[i] = repStartValue[i]; }
322
-
323
- if (params.cParams.strategy == ZSTD_btopt) {
324
- zc->seqStore.litFreq = (U32*)(zc->seqStore.buffer);
325
- zc->seqStore.litLengthFreq = zc->seqStore.litFreq + (1<<Litbits);
326
- zc->seqStore.matchLengthFreq = zc->seqStore.litLengthFreq + (MaxLL+1);
327
- zc->seqStore.offCodeFreq = zc->seqStore.matchLengthFreq + (MaxML+1);
328
- zc->seqStore.buffer = zc->seqStore.offCodeFreq + (MaxOff+1);
329
- zc->seqStore.matchTable = (ZSTD_match_t*)zc->seqStore.buffer;
330
- zc->seqStore.buffer = zc->seqStore.matchTable + ZSTD_OPT_NUM+1;
331
- zc->seqStore.priceTable = (ZSTD_optimal_t*)zc->seqStore.buffer;
332
- zc->seqStore.buffer = zc->seqStore.priceTable + ZSTD_OPT_NUM+1;
333
- zc->seqStore.litLengthSum = 0;
262
+ if (crp!=ZSTDcrp_noMemset) memset(zc->workSpace, 0, tableSpace); /* reset tables only */
263
+ XXH64_reset(&zc->xxhState, 0);
264
+ zc->hashLog3 = hashLog3;
265
+ zc->hashTable = (U32*)(zc->workSpace);
266
+ zc->chainTable = zc->hashTable + hSize;
267
+ zc->hashTable3 = zc->chainTable + chainSize;
268
+ ptr = zc->hashTable3 + h3Size;
269
+ zc->hufTable = (HUF_CElt*)ptr;
270
+ zc->flagStaticTables = 0;
271
+ ptr = ((U32*)ptr) + 256; /* note : HUF_CElt* is incomplete type, size is simulated using U32 */
272
+
273
+ zc->nextToUpdate = 1;
274
+ zc->nextSrc = NULL;
275
+ zc->base = NULL;
276
+ zc->dictBase = NULL;
277
+ zc->dictLimit = 0;
278
+ zc->lowLimit = 0;
279
+ zc->params = params;
280
+ zc->blockSize = blockSize;
281
+ zc->frameContentSize = frameContentSize;
282
+ { int i; for (i=0; i<ZSTD_REP_NUM; i++) zc->rep[i] = repStartValue[i]; }
283
+
284
+ if ((params.cParams.strategy == ZSTD_btopt) || (params.cParams.strategy == ZSTD_btopt2)) {
285
+ zc->seqStore.litFreq = (U32*)ptr;
286
+ zc->seqStore.litLengthFreq = zc->seqStore.litFreq + (1<<Litbits);
287
+ zc->seqStore.matchLengthFreq = zc->seqStore.litLengthFreq + (MaxLL+1);
288
+ zc->seqStore.offCodeFreq = zc->seqStore.matchLengthFreq + (MaxML+1);
289
+ ptr = zc->seqStore.offCodeFreq + (MaxOff+1);
290
+ zc->seqStore.matchTable = (ZSTD_match_t*)ptr;
291
+ ptr = zc->seqStore.matchTable + ZSTD_OPT_NUM+1;
292
+ zc->seqStore.priceTable = (ZSTD_optimal_t*)ptr;
293
+ ptr = zc->seqStore.priceTable + ZSTD_OPT_NUM+1;
294
+ zc->seqStore.litLengthSum = 0;
295
+ }
296
+ zc->seqStore.sequencesStart = (seqDef*)ptr;
297
+ ptr = zc->seqStore.sequencesStart + maxNbSeq;
298
+ zc->seqStore.llCode = (BYTE*) ptr;
299
+ zc->seqStore.mlCode = zc->seqStore.llCode + maxNbSeq;
300
+ zc->seqStore.ofCode = zc->seqStore.mlCode + maxNbSeq;
301
+ zc->seqStore.litStart = zc->seqStore.ofCode + maxNbSeq;
302
+
303
+ zc->stage = ZSTDcs_init;
304
+ zc->dictID = 0;
305
+ zc->loadedDictEnd = 0;
306
+
307
+ return 0;
334
308
  }
335
- zc->seqStore.offsetStart = (U32*)(zc->seqStore.buffer);
336
- zc->seqStore.buffer = zc->seqStore.offsetStart + maxNbSeq;
337
- zc->seqStore.litLengthStart = (U16*)zc->seqStore.buffer;
338
- zc->seqStore.matchLengthStart = zc->seqStore.litLengthStart + maxNbSeq;
339
- zc->seqStore.llCodeStart = (BYTE*) (zc->seqStore.matchLengthStart + maxNbSeq);
340
- zc->seqStore.mlCodeStart = zc->seqStore.llCodeStart + maxNbSeq;
341
- zc->seqStore.offCodeStart = zc->seqStore.mlCodeStart + maxNbSeq;
342
- zc->seqStore.litStart = zc->seqStore.offCodeStart + maxNbSeq;
343
-
344
- zc->stage = 1;
345
- zc->dictID = 0;
346
- zc->loadedDictEnd = 0;
347
-
348
- return 0;
349
309
  }
350
310
 
351
311
 
352
312
  /*! ZSTD_copyCCtx() :
353
313
  * Duplicate an existing context `srcCCtx` into another one `dstCCtx`.
354
- * Only works during stage 1 (i.e. after creation, but before first call to ZSTD_compressContinue()).
314
+ * Only works during stage ZSTDcs_init (i.e. after creation, but before first call to ZSTD_compressContinue()).
355
315
  * @return : 0, or an error code */
356
- size_t ZSTD_copyCCtx(ZSTD_CCtx* dstCCtx, const ZSTD_CCtx* srcCCtx)
316
+ size_t ZSTD_copyCCtx(ZSTD_CCtx* dstCCtx, const ZSTD_CCtx* srcCCtx, unsigned long long pledgedSrcSize)
357
317
  {
358
- if (srcCCtx->stage!=1) return ERROR(stage_wrong);
318
+ if (srcCCtx->stage!=ZSTDcs_init) return ERROR(stage_wrong);
359
319
 
360
320
  memcpy(&dstCCtx->customMem, &srcCCtx->customMem, sizeof(ZSTD_customMem));
361
- ZSTD_resetCCtx_advanced(dstCCtx, srcCCtx->params, srcCCtx->frameContentSize, 0);
362
- dstCCtx->params.fParams.contentSizeFlag = 0; /* content size different from the one set during srcCCtx init */
321
+ ZSTD_resetCCtx_advanced(dstCCtx, srcCCtx->params, pledgedSrcSize, ZSTDcrp_noMemset);
363
322
 
364
323
  /* copy tables */
365
- { const size_t chainSize = (srcCCtx->params.cParams.strategy == ZSTD_fast) ? 0 : (1 << srcCCtx->params.cParams.chainLog);
366
- const size_t hSize = ((size_t)1) << srcCCtx->params.cParams.hashLog;
367
- const size_t h3Size = (size_t)1 << srcCCtx->hashLog3;
368
- const size_t tableSpace = (chainSize + hSize + h3Size) * sizeof(U32);
324
+ { size_t const chainSize = (srcCCtx->params.cParams.strategy == ZSTD_fast) ? 0 : (1 << srcCCtx->params.cParams.chainLog);
325
+ size_t const hSize = ((size_t)1) << srcCCtx->params.cParams.hashLog;
326
+ size_t const h3Size = (size_t)1 << srcCCtx->hashLog3;
327
+ size_t const tableSpace = (chainSize + hSize + h3Size) * sizeof(U32);
369
328
  memcpy(dstCCtx->workSpace, srcCCtx->workSpace, tableSpace);
370
329
  }
371
330
 
@@ -408,13 +367,13 @@ static void ZSTD_reduceTable (U32* const table, U32 const size, U32 const reduce
408
367
  * rescale all indexes to avoid future overflow (indexes are U32) */
409
368
  static void ZSTD_reduceIndex (ZSTD_CCtx* zc, const U32 reducerValue)
410
369
  {
411
- { const U32 hSize = 1 << zc->params.cParams.hashLog;
370
+ { U32 const hSize = 1 << zc->params.cParams.hashLog;
412
371
  ZSTD_reduceTable(zc->hashTable, hSize, reducerValue); }
413
372
 
414
- { const U32 chainSize = (zc->params.cParams.strategy == ZSTD_fast) ? 0 : (1 << zc->params.cParams.chainLog);
373
+ { U32 const chainSize = (zc->params.cParams.strategy == ZSTD_fast) ? 0 : (1 << zc->params.cParams.chainLog);
415
374
  ZSTD_reduceTable(zc->chainTable, chainSize, reducerValue); }
416
375
 
417
- { const U32 h3Size = (zc->hashLog3) ? 1 << zc->hashLog3 : 0;
376
+ { U32 const h3Size = (zc->hashLog3) ? 1 << zc->hashLog3 : 0;
418
377
  ZSTD_reduceTable(zc->hashTable3, h3Size, reducerValue); }
419
378
  }
420
379
 
@@ -423,149 +382,13 @@ static void ZSTD_reduceIndex (ZSTD_CCtx* zc, const U32 reducerValue)
423
382
  * Block entropic compression
424
383
  *********************************************************/
425
384
 
426
- /* Frame format description
427
- Frame Header - [ Block Header - Block ] - Frame End
428
- 1) Frame Header
429
- - 4 bytes : Magic Number : ZSTD_MAGICNUMBER (defined within zstd_static.h)
430
- - 1 byte : Frame Header Descriptor
431
- - 1-13 bytes : Optional fields
432
- 2) Block Header
433
- - 3 bytes, starting with a 2-bits descriptor
434
- Uncompressed, Compressed, Frame End, unused
435
- 3) Block
436
- See Block Format Description
437
- 4) Frame End
438
- - 3 bytes, compatible with Block Header
439
- */
440
-
441
-
442
- /* Frame header :
443
-
444
- 1 byte - FrameHeaderDescription :
445
- bit 0-1 : dictID (0, 1, 2 or 4 bytes)
446
- bit 2-4 : reserved (must be zero)
447
- bit 5 : SkippedWindowLog (if 1, WindowLog byte is not present)
448
- bit 6-7 : FrameContentFieldsize (0, 2, 4, or 8)
449
- if (SkippedWindowLog && !FrameContentFieldsize) FrameContentFieldsize=1;
450
-
451
- Optional : WindowLog (0 or 1 byte)
452
- bit 0-2 : octal Fractional (1/8th)
453
- bit 3-7 : Power of 2, with 0 = 1 KB (up to 2 TB)
454
-
455
- Optional : content size (0, 1, 2, 4 or 8 bytes)
456
- 0 : unknown
457
- 1 : 0-255 bytes
458
- 2 : 256 - 65535+256
459
- 8 : up to 16 exa
460
-
461
- Optional : dictID (0, 1, 2 or 4 bytes)
462
- Automatic adaptation
463
- 0 : no dictID
464
- 1 : 1 - 255
465
- 2 : 256 - 65535
466
- 4 : all other values
467
- */
468
-
469
-
470
- /* Block format description
471
-
472
- Block = Literals Section - Sequences Section
473
- Prerequisite : size of (compressed) block, maximum size of regenerated data
474
-
475
- 1) Literal Section
476
-
477
- 1.1) Header : 1-5 bytes
478
- flags: 2 bits
479
- 00 compressed by Huff0
480
- 01 repeat
481
- 10 is Raw (uncompressed)
482
- 11 is Rle
483
- Note : using 01 => Huff0 with precomputed table ?
484
- Note : delta map ? => compressed ?
485
-
486
- 1.1.1) Huff0-compressed literal block : 3-5 bytes
487
- srcSize < 1 KB => 3 bytes (2-2-10-10) => single stream
488
- srcSize < 1 KB => 3 bytes (2-2-10-10)
489
- srcSize < 16KB => 4 bytes (2-2-14-14)
490
- else => 5 bytes (2-2-18-18)
491
- big endian convention
492
-
493
- 1.1.2) Raw (uncompressed) literal block header : 1-3 bytes
494
- size : 5 bits: (IS_RAW<<6) + (0<<4) + size
495
- 12 bits: (IS_RAW<<6) + (2<<4) + (size>>8)
496
- size&255
497
- 20 bits: (IS_RAW<<6) + (3<<4) + (size>>16)
498
- size>>8&255
499
- size&255
500
-
501
- 1.1.3) Rle (repeated single byte) literal block header : 1-3 bytes
502
- size : 5 bits: (IS_RLE<<6) + (0<<4) + size
503
- 12 bits: (IS_RLE<<6) + (2<<4) + (size>>8)
504
- size&255
505
- 20 bits: (IS_RLE<<6) + (3<<4) + (size>>16)
506
- size>>8&255
507
- size&255
508
-
509
- 1.1.4) Huff0-compressed literal block, using precomputed CTables : 3-5 bytes
510
- srcSize < 1 KB => 3 bytes (2-2-10-10) => single stream
511
- srcSize < 1 KB => 3 bytes (2-2-10-10)
512
- srcSize < 16KB => 4 bytes (2-2-14-14)
513
- else => 5 bytes (2-2-18-18)
514
- big endian convention
515
-
516
- 1- CTable available (stored into workspace)
517
- 2- Small input (fast heuristic ? Full comparison ? depend on clevel ?)
518
-
519
-
520
- 1.2) Literal block content
521
-
522
- 1.2.1) Huff0 block, using sizes from header
523
- See Huff0 format
524
-
525
- 1.2.2) Huff0 block, using prepared table
526
-
527
- 1.2.3) Raw content
528
-
529
- 1.2.4) single byte
530
-
531
-
532
- 2) Sequences section
533
-
534
- - Nb Sequences : 2 bytes, little endian
535
- - Control Token : 1 byte (see below)
536
- - Dumps Length : 1 or 2 bytes (depending on control token)
537
- - Dumps : as stated by dumps length
538
- - Literal Lengths FSE table (as needed depending on encoding method)
539
- - Offset Codes FSE table (as needed depending on encoding method)
540
- - Match Lengths FSE table (as needed depending on encoding method)
541
-
542
- 2.1) Control Token
543
- 8 bits, divided as :
544
- 0-1 : dumpsLength
545
- 2-3 : MatchLength, FSE encoding method
546
- 4-5 : Offset Codes, FSE encoding method
547
- 6-7 : Literal Lengths, FSE encoding method
548
-
549
- FSE encoding method :
550
- FSE_ENCODING_RAW : uncompressed; no header
551
- FSE_ENCODING_RLE : single repeated value; header 1 byte
552
- FSE_ENCODING_STATIC : use prepared table; no header
553
- FSE_ENCODING_DYNAMIC : read NCount
554
- */
385
+ /* See doc/zstd_compression_format.md for detailed format description */
555
386
 
556
387
  size_t ZSTD_noCompressBlock (void* dst, size_t dstCapacity, const void* src, size_t srcSize)
557
388
  {
558
- BYTE* const ostart = (BYTE* const)dst;
559
-
560
389
  if (srcSize + ZSTD_blockHeaderSize > dstCapacity) return ERROR(dstSize_tooSmall);
561
- memcpy(ostart + ZSTD_blockHeaderSize, src, srcSize);
562
-
563
- /* Build header */
564
- ostart[0] = (BYTE)(srcSize>>16);
565
- ostart[1] = (BYTE)(srcSize>>8);
566
- ostart[2] = (BYTE) srcSize;
567
- ostart[0] += (BYTE)(bt_raw<<6); /* is a raw (uncompressed) block */
568
-
390
+ memcpy((BYTE*)dst + ZSTD_blockHeaderSize, src, srcSize);
391
+ MEM_writeLE24(dst, (U32)(srcSize << 2) + (U32)bt_raw);
569
392
  return ZSTD_blockHeaderSize+srcSize;
570
393
  }
571
394
 
@@ -573,24 +396,21 @@ size_t ZSTD_noCompressBlock (void* dst, size_t dstCapacity, const void* src, siz
573
396
  static size_t ZSTD_noCompressLiterals (void* dst, size_t dstCapacity, const void* src, size_t srcSize)
574
397
  {
575
398
  BYTE* const ostart = (BYTE* const)dst;
576
- U32 const flSize = 1 + (srcSize>31) + (srcSize>4095);
399
+ U32 const flSize = 1 + (srcSize>31) + (srcSize>4095);
577
400
 
578
401
  if (srcSize + flSize > dstCapacity) return ERROR(dstSize_tooSmall);
579
402
 
580
403
  switch(flSize)
581
404
  {
582
405
  case 1: /* 2 - 1 - 5 */
583
- ostart[0] = (BYTE)((lbt_raw<<6) + (0<<5) + srcSize);
406
+ ostart[0] = (BYTE)((U32)set_basic + (srcSize<<3));
584
407
  break;
585
408
  case 2: /* 2 - 2 - 12 */
586
- ostart[0] = (BYTE)((lbt_raw<<6) + (2<<4) + (srcSize >> 8));
587
- ostart[1] = (BYTE)srcSize;
409
+ MEM_writeLE16(ostart, (U16)((U32)set_basic + (1<<2) + (srcSize<<4)));
588
410
  break;
589
411
  default: /*note : should not be necessary : flSize is within {1,2,3} */
590
412
  case 3: /* 2 - 2 - 20 */
591
- ostart[0] = (BYTE)((lbt_raw<<6) + (3<<4) + (srcSize >> 16));
592
- ostart[1] = (BYTE)(srcSize>>8);
593
- ostart[2] = (BYTE)srcSize;
413
+ MEM_writeLE32(ostart, (U32)((U32)set_basic + (3<<2) + (srcSize<<4)));
594
414
  break;
595
415
  }
596
416
 
@@ -601,24 +421,21 @@ static size_t ZSTD_noCompressLiterals (void* dst, size_t dstCapacity, const void
601
421
  static size_t ZSTD_compressRleLiteralsBlock (void* dst, size_t dstCapacity, const void* src, size_t srcSize)
602
422
  {
603
423
  BYTE* const ostart = (BYTE* const)dst;
604
- U32 const flSize = 1 + (srcSize>31) + (srcSize>4095);
424
+ U32 const flSize = 1 + (srcSize>31) + (srcSize>4095);
605
425
 
606
- (void)dstCapacity; /* dstCapacity guaranteed to be >=4, hence large enough */
426
+ (void)dstCapacity; /* dstCapacity already guaranteed to be >=4, hence large enough */
607
427
 
608
428
  switch(flSize)
609
429
  {
610
430
  case 1: /* 2 - 1 - 5 */
611
- ostart[0] = (BYTE)((lbt_rle<<6) + (0<<5) + srcSize);
431
+ ostart[0] = (BYTE)((U32)set_rle + (srcSize<<3));
612
432
  break;
613
433
  case 2: /* 2 - 2 - 12 */
614
- ostart[0] = (BYTE)((lbt_rle<<6) + (2<<4) + (srcSize >> 8));
615
- ostart[1] = (BYTE)srcSize;
434
+ MEM_writeLE16(ostart, (U16)((U32)set_rle + (1<<2) + (srcSize<<4)));
616
435
  break;
617
436
  default: /*note : should not be necessary : flSize is necessarily within {1,2,3} */
618
437
  case 3: /* 2 - 2 - 20 */
619
- ostart[0] = (BYTE)((lbt_rle<<6) + (3<<4) + (srcSize >> 16));
620
- ostart[1] = (BYTE)(srcSize>>8);
621
- ostart[2] = (BYTE)srcSize;
438
+ MEM_writeLE32(ostart, (U32)((U32)set_rle + (3<<2) + (srcSize<<4)));
622
439
  break;
623
440
  }
624
441
 
@@ -635,9 +452,9 @@ static size_t ZSTD_compressLiterals (ZSTD_CCtx* zc,
635
452
  {
636
453
  size_t const minGain = ZSTD_minGain(srcSize);
637
454
  size_t const lhSize = 3 + (srcSize >= 1 KB) + (srcSize >= 16 KB);
638
- BYTE* const ostart = (BYTE*)dst;
455
+ BYTE* const ostart = (BYTE*)dst;
639
456
  U32 singleStream = srcSize < 256;
640
- litBlockType_t hType = lbt_huffman;
457
+ symbolEncodingType_e hType = set_compressed;
641
458
  size_t cLitSize;
642
459
 
643
460
 
@@ -649,7 +466,7 @@ static size_t ZSTD_compressLiterals (ZSTD_CCtx* zc,
649
466
 
650
467
  if (dstCapacity < lhSize+1) return ERROR(dstSize_tooSmall); /* not enough space for compression */
651
468
  if (zc->flagStaticTables && (lhSize==3)) {
652
- hType = lbt_repeat;
469
+ hType = set_repeat;
653
470
  singleStream = 1;
654
471
  cLitSize = HUF_compress1X_usingCTable(ostart+lhSize, dstCapacity-lhSize, src, srcSize, zc->hufTable);
655
472
  } else {
@@ -666,79 +483,66 @@ static size_t ZSTD_compressLiterals (ZSTD_CCtx* zc,
666
483
  switch(lhSize)
667
484
  {
668
485
  case 3: /* 2 - 2 - 10 - 10 */
669
- ostart[0] = (BYTE)((srcSize>>6) + (singleStream << 4) + (hType<<6));
670
- ostart[1] = (BYTE)((srcSize<<2) + (cLitSize>>8));
671
- ostart[2] = (BYTE)(cLitSize);
672
- break;
486
+ { U32 const lhc = hType + ((!singleStream) << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<14);
487
+ MEM_writeLE24(ostart, lhc);
488
+ break;
489
+ }
673
490
  case 4: /* 2 - 2 - 14 - 14 */
674
- ostart[0] = (BYTE)((srcSize>>10) + (2<<4) + (hType<<6));
675
- ostart[1] = (BYTE)(srcSize>> 2);
676
- ostart[2] = (BYTE)((srcSize<<6) + (cLitSize>>8));
677
- ostart[3] = (BYTE)(cLitSize);
678
- break;
491
+ { U32 const lhc = hType + (2 << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<18);
492
+ MEM_writeLE32(ostart, lhc);
493
+ break;
494
+ }
679
495
  default: /* should not be necessary, lhSize is only {3,4,5} */
680
496
  case 5: /* 2 - 2 - 18 - 18 */
681
- ostart[0] = (BYTE)((srcSize>>14) + (3<<4) + (hType<<6));
682
- ostart[1] = (BYTE)(srcSize>>6);
683
- ostart[2] = (BYTE)((srcSize<<2) + (cLitSize>>16));
684
- ostart[3] = (BYTE)(cLitSize>>8);
685
- ostart[4] = (BYTE)(cLitSize);
686
- break;
497
+ { U32 const lhc = hType + (3 << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<22);
498
+ MEM_writeLE32(ostart, lhc);
499
+ ostart[4] = (BYTE)(cLitSize >> 10);
500
+ break;
501
+ }
687
502
  }
688
503
  return lhSize+cLitSize;
689
504
  }
690
505
 
691
-
692
- void ZSTD_seqToCodes(const seqStore_t* seqStorePtr, size_t const nbSeq)
693
- {
694
- /* LL codes */
695
- { static const BYTE LL_Code[64] = { 0, 1, 2, 3, 4, 5, 6, 7,
696
- 8, 9, 10, 11, 12, 13, 14, 15,
697
- 16, 16, 17, 17, 18, 18, 19, 19,
698
- 20, 20, 20, 20, 21, 21, 21, 21,
699
- 22, 22, 22, 22, 22, 22, 22, 22,
700
- 23, 23, 23, 23, 23, 23, 23, 23,
701
- 24, 24, 24, 24, 24, 24, 24, 24,
702
- 24, 24, 24, 24, 24, 24, 24, 24 };
703
- const BYTE LL_deltaCode = 19;
704
- const U16* const llTable = seqStorePtr->litLengthStart;
705
- BYTE* const llCodeTable = seqStorePtr->llCodeStart;
706
- size_t u;
707
- for (u=0; u<nbSeq; u++) {
708
- U32 const ll = llTable[u];
709
- llCodeTable[u] = (ll>63) ? (BYTE)ZSTD_highbit32(ll) + LL_deltaCode : LL_Code[ll];
710
- }
711
- if (seqStorePtr->longLengthID==1)
712
- llCodeTable[seqStorePtr->longLengthPos] = MaxLL;
713
- }
714
-
715
- /* Offset codes */
716
- { const U32* const offsetTable = seqStorePtr->offsetStart;
717
- BYTE* const ofCodeTable = seqStorePtr->offCodeStart;
718
- size_t u;
719
- for (u=0; u<nbSeq; u++) ofCodeTable[u] = (BYTE)ZSTD_highbit32(offsetTable[u]);
720
- }
721
-
722
- /* ML codes */
723
- { static const BYTE ML_Code[128] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
724
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
725
- 32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 36, 36, 37, 37, 37, 37,
726
- 38, 38, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 39, 39,
727
- 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
728
- 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
729
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
730
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42 };
731
- const BYTE ML_deltaCode = 36;
732
- const U16* const mlTable = seqStorePtr->matchLengthStart;
733
- BYTE* const mlCodeTable = seqStorePtr->mlCodeStart;
734
- size_t u;
735
- for (u=0; u<nbSeq; u++) {
736
- U32 const ml = mlTable[u];
737
- mlCodeTable[u] = (ml>127) ? (BYTE)ZSTD_highbit32(ml) + ML_deltaCode : ML_Code[ml];
738
- }
739
- if (seqStorePtr->longLengthID==2)
740
- mlCodeTable[seqStorePtr->longLengthPos] = MaxML;
506
+ static const BYTE LL_Code[64] = { 0, 1, 2, 3, 4, 5, 6, 7,
507
+ 8, 9, 10, 11, 12, 13, 14, 15,
508
+ 16, 16, 17, 17, 18, 18, 19, 19,
509
+ 20, 20, 20, 20, 21, 21, 21, 21,
510
+ 22, 22, 22, 22, 22, 22, 22, 22,
511
+ 23, 23, 23, 23, 23, 23, 23, 23,
512
+ 24, 24, 24, 24, 24, 24, 24, 24,
513
+ 24, 24, 24, 24, 24, 24, 24, 24 };
514
+
515
+ static const BYTE ML_Code[128] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
516
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
517
+ 32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 36, 36, 37, 37, 37, 37,
518
+ 38, 38, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 39, 39,
519
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
520
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
521
+ 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
522
+ 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42 };
523
+
524
+
525
+ void ZSTD_seqToCodes(const seqStore_t* seqStorePtr)
526
+ {
527
+ BYTE const LL_deltaCode = 19;
528
+ BYTE const ML_deltaCode = 36;
529
+ const seqDef* const sequences = seqStorePtr->sequencesStart;
530
+ BYTE* const llCodeTable = seqStorePtr->llCode;
531
+ BYTE* const ofCodeTable = seqStorePtr->ofCode;
532
+ BYTE* const mlCodeTable = seqStorePtr->mlCode;
533
+ U32 const nbSeq = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
534
+ U32 u;
535
+ for (u=0; u<nbSeq; u++) {
536
+ U32 const llv = sequences[u].litLength;
537
+ U32 const mlv = sequences[u].matchLength;
538
+ llCodeTable[u] = (llv> 63) ? (BYTE)ZSTD_highbit32(llv) + LL_deltaCode : LL_Code[llv];
539
+ ofCodeTable[u] = (BYTE)ZSTD_highbit32(sequences[u].offset);
540
+ mlCodeTable[u] = (mlv>127) ? (BYTE)ZSTD_highbit32(mlv) + ML_deltaCode : ML_Code[mlv];
741
541
  }
542
+ if (seqStorePtr->longLengthID==1)
543
+ llCodeTable[seqStorePtr->longLengthPos] = MaxLL;
544
+ if (seqStorePtr->longLengthID==2)
545
+ mlCodeTable[seqStorePtr->longLengthPos] = MaxML;
742
546
  }
743
547
 
744
548
 
@@ -753,17 +557,14 @@ size_t ZSTD_compressSequences(ZSTD_CCtx* zc,
753
557
  FSE_CTable* CTable_OffsetBits = zc->offcodeCTable;
754
558
  FSE_CTable* CTable_MatchLength = zc->matchlengthCTable;
755
559
  U32 LLtype, Offtype, MLtype; /* compressed, raw or rle */
756
- U16* const llTable = seqStorePtr->litLengthStart;
757
- U16* const mlTable = seqStorePtr->matchLengthStart;
758
- const U32* const offsetTable = seqStorePtr->offsetStart;
759
- const U32* const offsetTableEnd = seqStorePtr->offset;
760
- BYTE* const ofCodeTable = seqStorePtr->offCodeStart;
761
- BYTE* const llCodeTable = seqStorePtr->llCodeStart;
762
- BYTE* const mlCodeTable = seqStorePtr->mlCodeStart;
560
+ const seqDef* const sequences = seqStorePtr->sequencesStart;
561
+ const BYTE* const ofCodeTable = seqStorePtr->ofCode;
562
+ const BYTE* const llCodeTable = seqStorePtr->llCode;
563
+ const BYTE* const mlCodeTable = seqStorePtr->mlCode;
763
564
  BYTE* const ostart = (BYTE*)dst;
764
565
  BYTE* const oend = ostart + dstCapacity;
765
566
  BYTE* op = ostart;
766
- size_t const nbSeq = offsetTableEnd - offsetTable;
567
+ size_t const nbSeq = seqStorePtr->sequences - seqStorePtr->sequencesStart;
767
568
  BYTE* seqHead;
768
569
 
769
570
  /* Compress literals */
@@ -788,7 +589,7 @@ size_t ZSTD_compressSequences(ZSTD_CCtx* zc,
788
589
  #define MAX_SEQ_FOR_STATIC_FSE 1000
789
590
 
790
591
  /* convert length/distances into codes */
791
- ZSTD_seqToCodes(seqStorePtr, nbSeq);
592
+ ZSTD_seqToCodes(seqStorePtr);
792
593
 
793
594
  /* CTable for Literal Lengths */
794
595
  { U32 max = MaxLL;
@@ -796,12 +597,12 @@ size_t ZSTD_compressSequences(ZSTD_CCtx* zc,
796
597
  if ((mostFrequent == nbSeq) && (nbSeq > 2)) {
797
598
  *op++ = llCodeTable[0];
798
599
  FSE_buildCTable_rle(CTable_LitLength, (BYTE)max);
799
- LLtype = FSE_ENCODING_RLE;
600
+ LLtype = set_rle;
800
601
  } else if ((zc->flagStaticTables) && (nbSeq < MAX_SEQ_FOR_STATIC_FSE)) {
801
- LLtype = FSE_ENCODING_STATIC;
602
+ LLtype = set_repeat;
802
603
  } else if ((nbSeq < MIN_SEQ_FOR_DYNAMIC_FSE) || (mostFrequent < (nbSeq >> (LL_defaultNormLog-1)))) {
803
604
  FSE_buildCTable(CTable_LitLength, LL_defaultNorm, MaxLL, LL_defaultNormLog);
804
- LLtype = FSE_ENCODING_RAW;
605
+ LLtype = set_basic;
805
606
  } else {
806
607
  size_t nbSeq_1 = nbSeq;
807
608
  const U32 tableLog = FSE_optimalTableLog(LLFSELog, nbSeq, max);
@@ -811,7 +612,7 @@ size_t ZSTD_compressSequences(ZSTD_CCtx* zc,
811
612
  if (FSE_isError(NCountSize)) return ERROR(GENERIC);
812
613
  op += NCountSize; }
813
614
  FSE_buildCTable(CTable_LitLength, norm, max, tableLog);
814
- LLtype = FSE_ENCODING_DYNAMIC;
615
+ LLtype = set_compressed;
815
616
  } }
816
617
 
817
618
  /* CTable for Offsets */
@@ -820,12 +621,12 @@ size_t ZSTD_compressSequences(ZSTD_CCtx* zc,
820
621
  if ((mostFrequent == nbSeq) && (nbSeq > 2)) {
821
622
  *op++ = ofCodeTable[0];
822
623
  FSE_buildCTable_rle(CTable_OffsetBits, (BYTE)max);
823
- Offtype = FSE_ENCODING_RLE;
624
+ Offtype = set_rle;
824
625
  } else if ((zc->flagStaticTables) && (nbSeq < MAX_SEQ_FOR_STATIC_FSE)) {
825
- Offtype = FSE_ENCODING_STATIC;
626
+ Offtype = set_repeat;
826
627
  } else if ((nbSeq < MIN_SEQ_FOR_DYNAMIC_FSE) || (mostFrequent < (nbSeq >> (OF_defaultNormLog-1)))) {
827
628
  FSE_buildCTable(CTable_OffsetBits, OF_defaultNorm, MaxOff, OF_defaultNormLog);
828
- Offtype = FSE_ENCODING_RAW;
629
+ Offtype = set_basic;
829
630
  } else {
830
631
  size_t nbSeq_1 = nbSeq;
831
632
  const U32 tableLog = FSE_optimalTableLog(OffFSELog, nbSeq, max);
@@ -835,7 +636,7 @@ size_t ZSTD_compressSequences(ZSTD_CCtx* zc,
835
636
  if (FSE_isError(NCountSize)) return ERROR(GENERIC);
836
637
  op += NCountSize; }
837
638
  FSE_buildCTable(CTable_OffsetBits, norm, max, tableLog);
838
- Offtype = FSE_ENCODING_DYNAMIC;
639
+ Offtype = set_compressed;
839
640
  } }
840
641
 
841
642
  /* CTable for MatchLengths */
@@ -844,12 +645,12 @@ size_t ZSTD_compressSequences(ZSTD_CCtx* zc,
844
645
  if ((mostFrequent == nbSeq) && (nbSeq > 2)) {
845
646
  *op++ = *mlCodeTable;
846
647
  FSE_buildCTable_rle(CTable_MatchLength, (BYTE)max);
847
- MLtype = FSE_ENCODING_RLE;
648
+ MLtype = set_rle;
848
649
  } else if ((zc->flagStaticTables) && (nbSeq < MAX_SEQ_FOR_STATIC_FSE)) {
849
- MLtype = FSE_ENCODING_STATIC;
650
+ MLtype = set_repeat;
850
651
  } else if ((nbSeq < MIN_SEQ_FOR_DYNAMIC_FSE) || (mostFrequent < (nbSeq >> (ML_defaultNormLog-1)))) {
851
652
  FSE_buildCTable(CTable_MatchLength, ML_defaultNorm, MaxML, ML_defaultNormLog);
852
- MLtype = FSE_ENCODING_RAW;
653
+ MLtype = set_basic;
853
654
  } else {
854
655
  size_t nbSeq_1 = nbSeq;
855
656
  const U32 tableLog = FSE_optimalTableLog(MLFSELog, nbSeq, max);
@@ -859,7 +660,7 @@ size_t ZSTD_compressSequences(ZSTD_CCtx* zc,
859
660
  if (FSE_isError(NCountSize)) return ERROR(GENERIC);
860
661
  op += NCountSize; }
861
662
  FSE_buildCTable(CTable_MatchLength, norm, max, tableLog);
862
- MLtype = FSE_ENCODING_DYNAMIC;
663
+ MLtype = set_compressed;
863
664
  } }
864
665
 
865
666
  *seqHead = (BYTE)((LLtype<<6) + (Offtype<<4) + (MLtype<<2));
@@ -871,28 +672,27 @@ size_t ZSTD_compressSequences(ZSTD_CCtx* zc,
871
672
  FSE_CState_t stateOffsetBits;
872
673
  FSE_CState_t stateLitLength;
873
674
 
874
- { size_t const errorCode = BIT_initCStream(&blockStream, op, oend-op);
875
- if (ERR_isError(errorCode)) return ERROR(dstSize_tooSmall); } /* not enough space remaining */
675
+ CHECK_E(BIT_initCStream(&blockStream, op, oend-op), dstSize_tooSmall); /* not enough space remaining */
876
676
 
877
677
  /* first symbols */
878
678
  FSE_initCState2(&stateMatchLength, CTable_MatchLength, mlCodeTable[nbSeq-1]);
879
679
  FSE_initCState2(&stateOffsetBits, CTable_OffsetBits, ofCodeTable[nbSeq-1]);
880
680
  FSE_initCState2(&stateLitLength, CTable_LitLength, llCodeTable[nbSeq-1]);
881
- BIT_addBits(&blockStream, llTable[nbSeq-1], LL_bits[llCodeTable[nbSeq-1]]);
681
+ BIT_addBits(&blockStream, sequences[nbSeq-1].litLength, LL_bits[llCodeTable[nbSeq-1]]);
882
682
  if (MEM_32bits()) BIT_flushBits(&blockStream);
883
- BIT_addBits(&blockStream, mlTable[nbSeq-1], ML_bits[mlCodeTable[nbSeq-1]]);
683
+ BIT_addBits(&blockStream, sequences[nbSeq-1].matchLength, ML_bits[mlCodeTable[nbSeq-1]]);
884
684
  if (MEM_32bits()) BIT_flushBits(&blockStream);
885
- BIT_addBits(&blockStream, offsetTable[nbSeq-1], ofCodeTable[nbSeq-1]);
685
+ BIT_addBits(&blockStream, sequences[nbSeq-1].offset, ofCodeTable[nbSeq-1]);
886
686
  BIT_flushBits(&blockStream);
887
687
 
888
688
  { size_t n;
889
689
  for (n=nbSeq-2 ; n<nbSeq ; n--) { /* intentional underflow */
890
- const BYTE ofCode = ofCodeTable[n];
891
- const BYTE mlCode = mlCodeTable[n];
892
- const BYTE llCode = llCodeTable[n];
893
- const U32 llBits = LL_bits[llCode];
894
- const U32 mlBits = ML_bits[mlCode];
895
- const U32 ofBits = ofCode; /* 32b*/ /* 64b*/
690
+ BYTE const llCode = llCodeTable[n];
691
+ BYTE const ofCode = ofCodeTable[n];
692
+ BYTE const mlCode = mlCodeTable[n];
693
+ U32 const llBits = LL_bits[llCode];
694
+ U32 const ofBits = ofCode; /* 32b*/ /* 64b*/
695
+ U32 const mlBits = ML_bits[mlCode];
896
696
  /* (7)*/ /* (7)*/
897
697
  FSE_encodeSymbol(&blockStream, &stateOffsetBits, ofCode); /* 15 */ /* 15 */
898
698
  FSE_encodeSymbol(&blockStream, &stateMatchLength, mlCode); /* 24 */ /* 24 */
@@ -900,11 +700,11 @@ size_t ZSTD_compressSequences(ZSTD_CCtx* zc,
900
700
  FSE_encodeSymbol(&blockStream, &stateLitLength, llCode); /* 16 */ /* 33 */
901
701
  if (MEM_32bits() || (ofBits+mlBits+llBits >= 64-7-(LLFSELog+MLFSELog+OffFSELog)))
902
702
  BIT_flushBits(&blockStream); /* (7)*/
903
- BIT_addBits(&blockStream, llTable[n], llBits);
703
+ BIT_addBits(&blockStream, sequences[n].litLength, llBits);
904
704
  if (MEM_32bits() && ((llBits+mlBits)>24)) BIT_flushBits(&blockStream);
905
- BIT_addBits(&blockStream, mlTable[n], mlBits);
705
+ BIT_addBits(&blockStream, sequences[n].matchLength, mlBits);
906
706
  if (MEM_32bits()) BIT_flushBits(&blockStream); /* (7)*/
907
- BIT_addBits(&blockStream, offsetTable[n], ofBits); /* 31 */
707
+ BIT_addBits(&blockStream, sequences[n].offset, ofBits); /* 31 */
908
708
  BIT_flushBits(&blockStream); /* (7)*/
909
709
  } }
910
710
 
@@ -945,22 +745,22 @@ MEM_STATIC void ZSTD_storeSeq(seqStore_t* seqStorePtr, size_t litLength, const v
945
745
  printf("Cpos %6u :%5u literals & match %3u bytes at distance %6u \n",
946
746
  pos, (U32)litLength, (U32)matchCode+MINMATCH, (U32)offsetCode);
947
747
  #endif
948
- ZSTD_statsUpdatePrices(&seqStorePtr->stats, litLength, (const BYTE*)literals, offsetCode, matchCode); /* debug only */
949
-
950
748
  /* copy Literals */
951
749
  ZSTD_wildcopy(seqStorePtr->lit, literals, litLength);
952
750
  seqStorePtr->lit += litLength;
953
751
 
954
752
  /* literal Length */
955
- if (litLength>0xFFFF) { seqStorePtr->longLengthID = 1; seqStorePtr->longLengthPos = (U32)(seqStorePtr->litLength - seqStorePtr->litLengthStart); }
956
- *seqStorePtr->litLength++ = (U16)litLength;
753
+ if (litLength>0xFFFF) { seqStorePtr->longLengthID = 1; seqStorePtr->longLengthPos = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart); }
754
+ seqStorePtr->sequences[0].litLength = (U16)litLength;
957
755
 
958
756
  /* match offset */
959
- *(seqStorePtr->offset++) = offsetCode + 1;
757
+ seqStorePtr->sequences[0].offset = offsetCode + 1;
960
758
 
961
759
  /* match Length */
962
- if (matchCode>0xFFFF) { seqStorePtr->longLengthID = 2; seqStorePtr->longLengthPos = (U32)(seqStorePtr->matchLength - seqStorePtr->matchLengthStart); }
963
- *seqStorePtr->matchLength++ = (U16)matchCode;
760
+ if (matchCode>0xFFFF) { seqStorePtr->longLengthID = 2; seqStorePtr->longLengthPos = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart); }
761
+ seqStorePtr->sequences[0].matchLength = (U16)matchCode;
762
+
763
+ seqStorePtr->sequences++;
964
764
  }
965
765
 
966
766
 
@@ -1050,10 +850,9 @@ static size_t ZSTD_count(const BYTE* pIn, const BYTE* pMatch, const BYTE* const
1050
850
  static size_t ZSTD_count_2segments(const BYTE* ip, const BYTE* match, const BYTE* iEnd, const BYTE* mEnd, const BYTE* iStart)
1051
851
  {
1052
852
  const BYTE* const vEnd = MIN( ip + (mEnd - match), iEnd);
1053
- size_t matchLength = ZSTD_count(ip, match, vEnd);
1054
- if (match + matchLength == mEnd)
1055
- matchLength += ZSTD_count(ip+matchLength, iStart, iEnd);
1056
- return matchLength;
853
+ size_t const matchLength = ZSTD_count(ip, match, vEnd);
854
+ if (match + matchLength != mEnd) return matchLength;
855
+ return matchLength + ZSTD_count(ip+matchLength, iStart, iEnd);
1057
856
  }
1058
857
 
1059
858
 
@@ -1080,7 +879,6 @@ static const U64 prime7bytes = 58295818150454627ULL;
1080
879
  static size_t ZSTD_hash7(U64 u, U32 h) { return (size_t)(((u << (64-56)) * prime7bytes) >> (64-h)) ; }
1081
880
  static size_t ZSTD_hash7Ptr(const void* p, U32 h) { return ZSTD_hash7(MEM_readLE64(p), h); }
1082
881
 
1083
- //static const U64 prime8bytes = 58295818150454627ULL;
1084
882
  static const U64 prime8bytes = 0xCF1BBCDCB7A56463ULL;
1085
883
  static size_t ZSTD_hash8(U64 u, U32 h) { return (size_t)(((u) * prime8bytes) >> (64-h)) ; }
1086
884
  static size_t ZSTD_hash8Ptr(const void* p, U32 h) { return ZSTD_hash8(MEM_readLE64(p), h); }
@@ -1105,10 +903,10 @@ static size_t ZSTD_hashPtr(const void* p, U32 hBits, U32 mls)
1105
903
  static void ZSTD_fillHashTable (ZSTD_CCtx* zc, const void* end, const U32 mls)
1106
904
  {
1107
905
  U32* const hashTable = zc->hashTable;
1108
- const U32 hBits = zc->params.cParams.hashLog;
906
+ U32 const hBits = zc->params.cParams.hashLog;
1109
907
  const BYTE* const base = zc->base;
1110
908
  const BYTE* ip = base + zc->nextToUpdate;
1111
- const BYTE* const iend = ((const BYTE*)end) - 8;
909
+ const BYTE* const iend = ((const BYTE*)end) - HASH_READ_SIZE;
1112
910
  const size_t fastHashFillStep = 3;
1113
911
 
1114
912
  while(ip <= iend) {
@@ -1120,20 +918,20 @@ static void ZSTD_fillHashTable (ZSTD_CCtx* zc, const void* end, const U32 mls)
1120
918
 
1121
919
  FORCE_INLINE
1122
920
  void ZSTD_compressBlock_fast_generic(ZSTD_CCtx* cctx,
1123
- const void* src, size_t srcSize,
1124
- const U32 mls)
921
+ const void* src, size_t srcSize,
922
+ const U32 mls)
1125
923
  {
1126
924
  U32* const hashTable = cctx->hashTable;
1127
- const U32 hBits = cctx->params.cParams.hashLog;
925
+ U32 const hBits = cctx->params.cParams.hashLog;
1128
926
  seqStore_t* seqStorePtr = &(cctx->seqStore);
1129
927
  const BYTE* const base = cctx->base;
1130
928
  const BYTE* const istart = (const BYTE*)src;
1131
929
  const BYTE* ip = istart;
1132
930
  const BYTE* anchor = istart;
1133
- const U32 lowestIndex = cctx->dictLimit;
931
+ const U32 lowestIndex = cctx->dictLimit;
1134
932
  const BYTE* const lowest = base + lowestIndex;
1135
933
  const BYTE* const iend = istart + srcSize;
1136
- const BYTE* const ilimit = iend - 8;
934
+ const BYTE* const ilimit = iend - HASH_READ_SIZE;
1137
935
  U32 offset_1=cctx->rep[0], offset_2=cctx->rep[1];
1138
936
  U32 offsetSaved = 0;
1139
937
 
@@ -1153,7 +951,7 @@ void ZSTD_compressBlock_fast_generic(ZSTD_CCtx* cctx,
1153
951
  const BYTE* match = base + matchIndex;
1154
952
  hashTable[h] = current; /* update hash table */
1155
953
 
1156
- if ((offset_1 > 0) & (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1))) { /* note : by construction, offset_1 <= current */
954
+ if ((offset_1 > 0) & (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1))) {
1157
955
  mLength = ZSTD_count(ip+1+4, ip+1+4-offset_1, iend) + 4;
1158
956
  ip++;
1159
957
  ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, 0, mLength-MINMATCH);
@@ -1288,7 +1086,7 @@ static void ZSTD_compressBlock_fast_extDict_generic(ZSTD_CCtx* ctx,
1288
1086
 
1289
1087
  if (ip <= ilimit) {
1290
1088
  /* Fill Table */
1291
- hashTable[ZSTD_hashPtr(base+current+2, hBits, mls)] = current+2;
1089
+ hashTable[ZSTD_hashPtr(base+current+2, hBits, mls)] = current+2;
1292
1090
  hashTable[ZSTD_hashPtr(ip-2, hBits, mls)] = (U32)(ip-2-base);
1293
1091
  /* check immediate repcode */
1294
1092
  while (ip <= ilimit) {
@@ -1323,7 +1121,7 @@ static void ZSTD_compressBlock_fast_extDict_generic(ZSTD_CCtx* ctx,
1323
1121
  static void ZSTD_compressBlock_fast_extDict(ZSTD_CCtx* ctx,
1324
1122
  const void* src, size_t srcSize)
1325
1123
  {
1326
- const U32 mls = ctx->params.cParams.searchLength;
1124
+ U32 const mls = ctx->params.cParams.searchLength;
1327
1125
  switch(mls)
1328
1126
  {
1329
1127
  default:
@@ -1345,12 +1143,12 @@ static void ZSTD_compressBlock_fast_extDict(ZSTD_CCtx* ctx,
1345
1143
  static void ZSTD_fillDoubleHashTable (ZSTD_CCtx* cctx, const void* end, const U32 mls)
1346
1144
  {
1347
1145
  U32* const hashLarge = cctx->hashTable;
1348
- const U32 hBitsL = cctx->params.cParams.hashLog;
1146
+ U32 const hBitsL = cctx->params.cParams.hashLog;
1349
1147
  U32* const hashSmall = cctx->chainTable;
1350
- const U32 hBitsS = cctx->params.cParams.chainLog;
1148
+ U32 const hBitsS = cctx->params.cParams.chainLog;
1351
1149
  const BYTE* const base = cctx->base;
1352
1150
  const BYTE* ip = base + cctx->nextToUpdate;
1353
- const BYTE* const iend = ((const BYTE*)end) - 8;
1151
+ const BYTE* const iend = ((const BYTE*)end) - HASH_READ_SIZE;
1354
1152
  const size_t fastHashFillStep = 3;
1355
1153
 
1356
1154
  while(ip <= iend) {
@@ -1378,7 +1176,7 @@ void ZSTD_compressBlock_doubleFast_generic(ZSTD_CCtx* cctx,
1378
1176
  const U32 lowestIndex = cctx->dictLimit;
1379
1177
  const BYTE* const lowest = base + lowestIndex;
1380
1178
  const BYTE* const iend = istart + srcSize;
1381
- const BYTE* const ilimit = iend - 8;
1179
+ const BYTE* const ilimit = iend - HASH_READ_SIZE;
1382
1180
  U32 offset_1=cctx->rep[0], offset_2=cctx->rep[1];
1383
1181
  U32 offsetSaved = 0;
1384
1182
 
@@ -1412,9 +1210,20 @@ void ZSTD_compressBlock_doubleFast_generic(ZSTD_CCtx* cctx,
1412
1210
  offset = (U32)(ip-matchLong);
1413
1211
  while (((ip>anchor) & (matchLong>lowest)) && (ip[-1] == matchLong[-1])) { ip--; matchLong--; mLength++; } /* catch up */
1414
1212
  } else if ( (matchIndexS > lowestIndex) && (MEM_read32(match) == MEM_read32(ip)) ) {
1415
- mLength = ZSTD_count(ip+4, match+4, iend) + 4;
1416
- offset = (U32)(ip-match);
1417
- while (((ip>anchor) & (match>lowest)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
1213
+ size_t const h3 = ZSTD_hashPtr(ip+1, hBitsL, 8);
1214
+ U32 const matchIndex3 = hashLong[h3];
1215
+ const BYTE* match3 = base + matchIndex3;
1216
+ hashLong[h3] = current + 1;
1217
+ if ( (matchIndex3 > lowestIndex) && (MEM_read64(match3) == MEM_read64(ip+1)) ) {
1218
+ mLength = ZSTD_count(ip+9, match3+8, iend) + 8;
1219
+ ip++;
1220
+ offset = (U32)(ip-match3);
1221
+ while (((ip>anchor) & (match3>lowest)) && (ip[-1] == match3[-1])) { ip--; match3--; mLength++; } /* catch up */
1222
+ } else {
1223
+ mLength = ZSTD_count(ip+4, match+4, iend) + 4;
1224
+ offset = (U32)(ip-match);
1225
+ while (((ip>anchor) & (match>lowest)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
1226
+ }
1418
1227
  } else {
1419
1228
  ip += ((ip-anchor) >> g_searchStrength) + 1;
1420
1229
  continue;
@@ -1487,9 +1296,9 @@ static void ZSTD_compressBlock_doubleFast_extDict_generic(ZSTD_CCtx* ctx,
1487
1296
  const U32 mls)
1488
1297
  {
1489
1298
  U32* const hashLong = ctx->hashTable;
1490
- const U32 hBitsL = ctx->params.cParams.hashLog;
1299
+ U32 const hBitsL = ctx->params.cParams.hashLog;
1491
1300
  U32* const hashSmall = ctx->chainTable;
1492
- const U32 hBitsS = ctx->params.cParams.chainLog;
1301
+ U32 const hBitsS = ctx->params.cParams.chainLog;
1493
1302
  seqStore_t* seqStorePtr = &(ctx->seqStore);
1494
1303
  const BYTE* const base = ctx->base;
1495
1304
  const BYTE* const dictBase = ctx->dictBase;
@@ -1541,16 +1350,32 @@ static void ZSTD_compressBlock_doubleFast_extDict_generic(ZSTD_CCtx* ctx,
1541
1350
  offset_2 = offset_1;
1542
1351
  offset_1 = offset;
1543
1352
  ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
1353
+
1544
1354
  } else if ((matchIndex > lowestIndex) && (MEM_read32(match) == MEM_read32(ip))) {
1545
- const BYTE* matchEnd = matchIndex < dictLimit ? dictEnd : iend;
1546
- const BYTE* lowMatchPtr = matchIndex < dictLimit ? dictStart : lowPrefixPtr;
1355
+ size_t const h3 = ZSTD_hashPtr(ip+1, hBitsL, 8);
1356
+ U32 const matchIndex3 = hashLong[h3];
1357
+ const BYTE* const match3Base = matchIndex3 < dictLimit ? dictBase : base;
1358
+ const BYTE* match3 = match3Base + matchIndex3;
1547
1359
  U32 offset;
1548
- mLength = ZSTD_count_2segments(ip+4, match+4, iend, matchEnd, lowPrefixPtr) + 4;
1549
- while (((ip>anchor) & (match>lowMatchPtr)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
1550
- offset = current - matchIndex;
1360
+ hashLong[h3] = current + 1;
1361
+ if ( (matchIndex3 > lowestIndex) && (MEM_read64(match3) == MEM_read64(ip+1)) ) {
1362
+ const BYTE* matchEnd = matchIndex3 < dictLimit ? dictEnd : iend;
1363
+ const BYTE* lowMatchPtr = matchIndex3 < dictLimit ? dictStart : lowPrefixPtr;
1364
+ mLength = ZSTD_count_2segments(ip+9, match3+8, iend, matchEnd, lowPrefixPtr) + 8;
1365
+ ip++;
1366
+ offset = current+1 - matchIndex3;
1367
+ while (((ip>anchor) & (match3>lowMatchPtr)) && (ip[-1] == match3[-1])) { ip--; match3--; mLength++; } /* catch up */
1368
+ } else {
1369
+ const BYTE* matchEnd = matchIndex < dictLimit ? dictEnd : iend;
1370
+ const BYTE* lowMatchPtr = matchIndex < dictLimit ? dictStart : lowPrefixPtr;
1371
+ mLength = ZSTD_count_2segments(ip+4, match+4, iend, matchEnd, lowPrefixPtr) + 4;
1372
+ offset = current - matchIndex;
1373
+ while (((ip>anchor) & (match>lowMatchPtr)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
1374
+ }
1551
1375
  offset_2 = offset_1;
1552
1376
  offset_1 = offset;
1553
1377
  ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
1378
+
1554
1379
  } else {
1555
1380
  ip += ((ip-anchor) >> g_searchStrength) + 1;
1556
1381
  continue;
@@ -1600,7 +1425,7 @@ static void ZSTD_compressBlock_doubleFast_extDict_generic(ZSTD_CCtx* ctx,
1600
1425
  static void ZSTD_compressBlock_doubleFast_extDict(ZSTD_CCtx* ctx,
1601
1426
  const void* src, size_t srcSize)
1602
1427
  {
1603
- const U32 mls = ctx->params.cParams.searchLength;
1428
+ U32 const mls = ctx->params.cParams.searchLength;
1604
1429
  switch(mls)
1605
1430
  {
1606
1431
  default:
@@ -1625,26 +1450,26 @@ static void ZSTD_compressBlock_doubleFast_extDict(ZSTD_CCtx* ctx,
1625
1450
  static U32 ZSTD_insertBt1(ZSTD_CCtx* zc, const BYTE* const ip, const U32 mls, const BYTE* const iend, U32 nbCompares,
1626
1451
  U32 extDict)
1627
1452
  {
1628
- U32* const hashTable = zc->hashTable;
1629
- const U32 hashLog = zc->params.cParams.hashLog;
1630
- const size_t h = ZSTD_hashPtr(ip, hashLog, mls);
1631
- U32* const bt = zc->chainTable;
1632
- const U32 btLog = zc->params.cParams.chainLog - 1;
1633
- const U32 btMask= (1 << btLog) - 1;
1634
- U32 matchIndex = hashTable[h];
1453
+ U32* const hashTable = zc->hashTable;
1454
+ U32 const hashLog = zc->params.cParams.hashLog;
1455
+ size_t const h = ZSTD_hashPtr(ip, hashLog, mls);
1456
+ U32* const bt = zc->chainTable;
1457
+ U32 const btLog = zc->params.cParams.chainLog - 1;
1458
+ U32 const btMask = (1 << btLog) - 1;
1459
+ U32 matchIndex = hashTable[h];
1635
1460
  size_t commonLengthSmaller=0, commonLengthLarger=0;
1636
1461
  const BYTE* const base = zc->base;
1637
1462
  const BYTE* const dictBase = zc->dictBase;
1638
1463
  const U32 dictLimit = zc->dictLimit;
1639
1464
  const BYTE* const dictEnd = dictBase + dictLimit;
1640
1465
  const BYTE* const prefixStart = base + dictLimit;
1641
- const BYTE* match = base + matchIndex;
1466
+ const BYTE* match;
1642
1467
  const U32 current = (U32)(ip-base);
1643
1468
  const U32 btLow = btMask >= current ? 0 : current - btMask;
1644
1469
  U32* smallerPtr = bt + 2*(current&btMask);
1645
1470
  U32* largerPtr = smallerPtr + 1;
1646
1471
  U32 dummy32; /* to be nullified at the end */
1647
- const U32 windowLow = zc->lowLimit;
1472
+ U32 const windowLow = zc->lowLimit;
1648
1473
  U32 matchEndIdx = current+8;
1649
1474
  size_t bestLength = 8;
1650
1475
  #ifdef ZSTD_C_PREDICT
@@ -1729,12 +1554,12 @@ static size_t ZSTD_insertBtAndFindBestMatch (
1729
1554
  U32 nbCompares, const U32 mls,
1730
1555
  U32 extDict)
1731
1556
  {
1732
- U32* const hashTable = zc->hashTable;
1733
- const U32 hashLog = zc->params.cParams.hashLog;
1734
- const size_t h = ZSTD_hashPtr(ip, hashLog, mls);
1735
- U32* const bt = zc->chainTable;
1736
- const U32 btLog = zc->params.cParams.chainLog - 1;
1737
- const U32 btMask= (1 << btLog) - 1;
1557
+ U32* const hashTable = zc->hashTable;
1558
+ U32 const hashLog = zc->params.cParams.hashLog;
1559
+ size_t const h = ZSTD_hashPtr(ip, hashLog, mls);
1560
+ U32* const bt = zc->chainTable;
1561
+ U32 const btLog = zc->params.cParams.chainLog - 1;
1562
+ U32 const btMask = (1 << btLog) - 1;
1738
1563
  U32 matchIndex = hashTable[h];
1739
1564
  size_t commonLengthSmaller=0, commonLengthLarger=0;
1740
1565
  const BYTE* const base = zc->base;
@@ -1880,13 +1705,11 @@ static size_t ZSTD_BtFindBestMatch_selectMLS_extDict (
1880
1705
 
1881
1706
 
1882
1707
 
1883
- /* ***********************
1708
+ /* *********************************
1884
1709
  * Hash Chain
1885
- *************************/
1886
-
1710
+ ***********************************/
1887
1711
  #define NEXT_IN_CHAIN(d, mask) chainTable[(d) & mask]
1888
1712
 
1889
-
1890
1713
  /* Update chains up to ip (excluded)
1891
1714
  Assumption : always within prefix (ie. not within extDict) */
1892
1715
  FORCE_INLINE
@@ -2127,7 +1950,6 @@ _storeSequence:
2127
1950
  { size_t const lastLLSize = iend - anchor;
2128
1951
  memcpy(seqStorePtr->lit, anchor, lastLLSize);
2129
1952
  seqStorePtr->lit += lastLLSize;
2130
- ZSTD_statsUpdatePrices(&seqStorePtr->stats, lastLLSize, anchor, 0, 0);
2131
1953
  }
2132
1954
  }
2133
1955
 
@@ -2353,7 +2175,17 @@ static void ZSTD_compressBlock_btlazy2_extDict(ZSTD_CCtx* ctx, const void* src,
2353
2175
  static void ZSTD_compressBlock_btopt(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
2354
2176
  {
2355
2177
  #ifdef ZSTD_OPT_H_91842398743
2356
- ZSTD_compressBlock_opt_generic(ctx, src, srcSize);
2178
+ ZSTD_compressBlock_opt_generic(ctx, src, srcSize, 0);
2179
+ #else
2180
+ (void)ctx; (void)src; (void)srcSize;
2181
+ return;
2182
+ #endif
2183
+ }
2184
+
2185
+ static void ZSTD_compressBlock_btopt2(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
2186
+ {
2187
+ #ifdef ZSTD_OPT_H_91842398743
2188
+ ZSTD_compressBlock_opt_generic(ctx, src, srcSize, 1);
2357
2189
  #else
2358
2190
  (void)ctx; (void)src; (void)srcSize;
2359
2191
  return;
@@ -2363,7 +2195,17 @@ static void ZSTD_compressBlock_btopt(ZSTD_CCtx* ctx, const void* src, size_t src
2363
2195
  static void ZSTD_compressBlock_btopt_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
2364
2196
  {
2365
2197
  #ifdef ZSTD_OPT_H_91842398743
2366
- ZSTD_compressBlock_opt_extDict_generic(ctx, src, srcSize);
2198
+ ZSTD_compressBlock_opt_extDict_generic(ctx, src, srcSize, 0);
2199
+ #else
2200
+ (void)ctx; (void)src; (void)srcSize;
2201
+ return;
2202
+ #endif
2203
+ }
2204
+
2205
+ static void ZSTD_compressBlock_btopt2_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
2206
+ {
2207
+ #ifdef ZSTD_OPT_H_91842398743
2208
+ ZSTD_compressBlock_opt_extDict_generic(ctx, src, srcSize, 1);
2367
2209
  #else
2368
2210
  (void)ctx; (void)src; (void)srcSize;
2369
2211
  return;
@@ -2375,9 +2217,9 @@ typedef void (*ZSTD_blockCompressor) (ZSTD_CCtx* ctx, const void* src, size_t sr
2375
2217
 
2376
2218
  static ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, int extDict)
2377
2219
  {
2378
- static const ZSTD_blockCompressor blockCompressor[2][7] = {
2379
- { ZSTD_compressBlock_fast, ZSTD_compressBlock_doubleFast, ZSTD_compressBlock_greedy, ZSTD_compressBlock_lazy, ZSTD_compressBlock_lazy2, ZSTD_compressBlock_btlazy2, ZSTD_compressBlock_btopt },
2380
- { ZSTD_compressBlock_fast_extDict, ZSTD_compressBlock_doubleFast_extDict, ZSTD_compressBlock_greedy_extDict, ZSTD_compressBlock_lazy_extDict,ZSTD_compressBlock_lazy2_extDict, ZSTD_compressBlock_btlazy2_extDict, ZSTD_compressBlock_btopt_extDict }
2220
+ static const ZSTD_blockCompressor blockCompressor[2][8] = {
2221
+ { ZSTD_compressBlock_fast, ZSTD_compressBlock_doubleFast, ZSTD_compressBlock_greedy, ZSTD_compressBlock_lazy, ZSTD_compressBlock_lazy2, ZSTD_compressBlock_btlazy2, ZSTD_compressBlock_btopt, ZSTD_compressBlock_btopt2 },
2222
+ { ZSTD_compressBlock_fast_extDict, ZSTD_compressBlock_doubleFast_extDict, ZSTD_compressBlock_greedy_extDict, ZSTD_compressBlock_lazy_extDict,ZSTD_compressBlock_lazy2_extDict, ZSTD_compressBlock_btlazy2_extDict, ZSTD_compressBlock_btopt_extDict, ZSTD_compressBlock_btopt2_extDict }
2381
2223
  };
2382
2224
 
2383
2225
  return blockCompressor[extDict][(U32)strat];
@@ -2387,38 +2229,63 @@ static ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, int
2387
2229
  static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc, void* dst, size_t dstCapacity, const void* src, size_t srcSize)
2388
2230
  {
2389
2231
  ZSTD_blockCompressor const blockCompressor = ZSTD_selectBlockCompressor(zc->params.cParams.strategy, zc->lowLimit < zc->dictLimit);
2232
+ const BYTE* const base = zc->base;
2233
+ const BYTE* const istart = (const BYTE*)src;
2234
+ const U32 current = (U32)(istart-base);
2390
2235
  if (srcSize < MIN_CBLOCK_SIZE+ZSTD_blockHeaderSize+1) return 0; /* don't even attempt compression below a certain srcSize */
2391
2236
  ZSTD_resetSeqStore(&(zc->seqStore));
2237
+ if (current > zc->nextToUpdate + 384)
2238
+ zc->nextToUpdate = current - MIN(192, (U32)(current - zc->nextToUpdate - 384)); /* update tree not updated after finding very long rep matches */
2392
2239
  blockCompressor(zc, src, srcSize);
2393
2240
  return ZSTD_compressSequences(zc, dst, dstCapacity, srcSize);
2394
2241
  }
2395
2242
 
2396
2243
 
2397
-
2398
-
2244
+ /*! ZSTD_compress_generic() :
2245
+ * Compress a chunk of data into one or multiple blocks.
2246
+ * All blocks will be terminated, all input will be consumed.
2247
+ * Function will issue an error if there is not enough `dstCapacity` to hold the compressed content.
2248
+ * Frame is supposed already started (header already produced)
2249
+ * @return : compressed size, or an error code
2250
+ */
2399
2251
  static size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
2400
2252
  void* dst, size_t dstCapacity,
2401
- const void* src, size_t srcSize)
2253
+ const void* src, size_t srcSize,
2254
+ U32 lastFrameChunk)
2402
2255
  {
2403
2256
  size_t blockSize = cctx->blockSize;
2404
2257
  size_t remaining = srcSize;
2405
2258
  const BYTE* ip = (const BYTE*)src;
2406
2259
  BYTE* const ostart = (BYTE*)dst;
2407
2260
  BYTE* op = ostart;
2408
- const U32 maxDist = 1 << cctx->params.cParams.windowLog;
2409
- ZSTD_stats_t* stats = &cctx->seqStore.stats;
2410
- ZSTD_statsInit(stats); /* debug only */
2261
+ U32 const maxDist = 1 << cctx->params.cParams.windowLog;
2411
2262
 
2412
- if (cctx->params.fParams.checksumFlag)
2263
+ if (cctx->params.fParams.checksumFlag && srcSize)
2413
2264
  XXH64_update(&cctx->xxhState, src, srcSize);
2414
2265
 
2415
2266
  while (remaining) {
2267
+ U32 const lastBlock = lastFrameChunk & (blockSize >= remaining);
2416
2268
  size_t cSize;
2417
- ZSTD_statsResetFreqs(stats); /* debug only */
2418
2269
 
2419
2270
  if (dstCapacity < ZSTD_blockHeaderSize + MIN_CBLOCK_SIZE) return ERROR(dstSize_tooSmall); /* not enough space to store compressed block */
2420
2271
  if (remaining < blockSize) blockSize = remaining;
2421
2272
 
2273
+ /* preemptive overflow correction */
2274
+ if (cctx->lowLimit > (1<<30)) {
2275
+ U32 const btplus = (cctx->params.cParams.strategy == ZSTD_btlazy2) | (cctx->params.cParams.strategy == ZSTD_btopt) | (cctx->params.cParams.strategy == ZSTD_btopt2);
2276
+ U32 const chainMask = (1 << (cctx->params.cParams.chainLog - btplus)) - 1;
2277
+ U32 const supLog = MAX(cctx->params.cParams.chainLog, 17 /* blockSize */);
2278
+ U32 const newLowLimit = (cctx->lowLimit & chainMask) + (1 << supLog); /* preserve position % chainSize, ensure current-repcode doesn't underflow */
2279
+ U32 const correction = cctx->lowLimit - newLowLimit;
2280
+ ZSTD_reduceIndex(cctx, correction);
2281
+ cctx->base += correction;
2282
+ cctx->dictBase += correction;
2283
+ cctx->lowLimit = newLowLimit;
2284
+ cctx->dictLimit -= correction;
2285
+ if (cctx->nextToUpdate < correction) cctx->nextToUpdate = 0;
2286
+ else cctx->nextToUpdate -= correction;
2287
+ }
2288
+
2422
2289
  if ((U32)(ip+blockSize - cctx->base) > cctx->loadedDictEnd + maxDist) {
2423
2290
  /* enforce maxDist */
2424
2291
  U32 const newLowLimit = (U32)(ip+blockSize - cctx->base) - maxDist;
@@ -2430,14 +2297,15 @@ static size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
2430
2297
  if (ZSTD_isError(cSize)) return cSize;
2431
2298
 
2432
2299
  if (cSize == 0) { /* block is not compressible */
2433
- cSize = ZSTD_noCompressBlock(op, dstCapacity, ip, blockSize);
2434
- if (ZSTD_isError(cSize)) return cSize;
2300
+ U32 const cBlockHeader24 = lastBlock + (((U32)bt_raw)<<1) + (U32)(blockSize << 3);
2301
+ if (blockSize + ZSTD_blockHeaderSize > dstCapacity) return ERROR(dstSize_tooSmall);
2302
+ MEM_writeLE32(op, cBlockHeader24); /* no pb, 4th byte will be overwritten */
2303
+ memcpy(op + ZSTD_blockHeaderSize, ip, blockSize);
2304
+ cSize = ZSTD_blockHeaderSize+blockSize;
2435
2305
  } else {
2436
- op[0] = (BYTE)(cSize>>16);
2437
- op[1] = (BYTE)(cSize>>8);
2438
- op[2] = (BYTE)cSize;
2439
- op[0] += (BYTE)(bt_compressed << 6); /* is a compressed block */
2440
- cSize += 3;
2306
+ U32 const cBlockHeader24 = lastBlock + (((U32)bt_compressed)<<1) + (U32)(cSize << 3);
2307
+ MEM_writeLE24(op, cBlockHeader24);
2308
+ cSize += ZSTD_blockHeaderSize;
2441
2309
  }
2442
2310
 
2443
2311
  remaining -= blockSize;
@@ -2446,7 +2314,7 @@ static size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
2446
2314
  op += cSize;
2447
2315
  }
2448
2316
 
2449
- ZSTD_statsPrint(stats, cctx->params.cParams.searchLength);
2317
+ if (lastFrameChunk && (op>ostart)) cctx->stage = ZSTDcs_ending;
2450
2318
  return op-ostart;
2451
2319
  }
2452
2320
 
@@ -2454,34 +2322,34 @@ static size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
2454
2322
  static size_t ZSTD_writeFrameHeader(void* dst, size_t dstCapacity,
2455
2323
  ZSTD_parameters params, U64 pledgedSrcSize, U32 dictID)
2456
2324
  { BYTE* const op = (BYTE*)dst;
2457
- U32 const dictIDSizeCode = (dictID>0) + (dictID>=256) + (dictID>=65536); /* 0-3 */
2458
- U32 const checksumFlag = params.fParams.checksumFlag>0;
2459
- U32 const windowSize = 1U << params.cParams.windowLog;
2460
- U32 const directModeFlag = params.fParams.contentSizeFlag && (windowSize > (pledgedSrcSize-1));
2461
- BYTE const windowLogByte = (BYTE)((params.cParams.windowLog - ZSTD_WINDOWLOG_ABSOLUTEMIN) << 3);
2462
- U32 const fcsCode = params.fParams.contentSizeFlag ?
2325
+ U32 const dictIDSizeCode = (dictID>0) + (dictID>=256) + (dictID>=65536); /* 0-3 */
2326
+ U32 const checksumFlag = params.fParams.checksumFlag>0;
2327
+ U32 const windowSize = 1U << params.cParams.windowLog;
2328
+ U32 const singleSegment = params.fParams.contentSizeFlag && (windowSize > (pledgedSrcSize-1));
2329
+ BYTE const windowLogByte = (BYTE)((params.cParams.windowLog - ZSTD_WINDOWLOG_ABSOLUTEMIN) << 3);
2330
+ U32 const fcsCode = params.fParams.contentSizeFlag ?
2463
2331
  (pledgedSrcSize>=256) + (pledgedSrcSize>=65536+256) + (pledgedSrcSize>=0xFFFFFFFFU) : /* 0-3 */
2464
2332
  0;
2465
- BYTE const frameHeaderDecriptionByte = (BYTE)(dictIDSizeCode + (checksumFlag<<2) + (directModeFlag<<5) + (fcsCode<<6) );
2333
+ BYTE const frameHeaderDecriptionByte = (BYTE)(dictIDSizeCode + (checksumFlag<<2) + (singleSegment<<5) + (fcsCode<<6) );
2466
2334
  size_t pos;
2467
2335
 
2468
2336
  if (dstCapacity < ZSTD_frameHeaderSize_max) return ERROR(dstSize_tooSmall);
2469
2337
 
2470
2338
  MEM_writeLE32(dst, ZSTD_MAGICNUMBER);
2471
2339
  op[4] = frameHeaderDecriptionByte; pos=5;
2472
- if (!directModeFlag) op[pos++] = windowLogByte;
2340
+ if (!singleSegment) op[pos++] = windowLogByte;
2473
2341
  switch(dictIDSizeCode)
2474
2342
  {
2475
2343
  default: /* impossible */
2476
2344
  case 0 : break;
2477
2345
  case 1 : op[pos] = (BYTE)(dictID); pos++; break;
2478
- case 2 : MEM_writeLE16(op+pos, (U16)(dictID)); pos+=2; break;
2346
+ case 2 : MEM_writeLE16(op+pos, (U16)dictID); pos+=2; break;
2479
2347
  case 3 : MEM_writeLE32(op+pos, dictID); pos+=4; break;
2480
2348
  }
2481
2349
  switch(fcsCode)
2482
2350
  {
2483
2351
  default: /* impossible */
2484
- case 0 : if (directModeFlag) op[pos++] = (BYTE)(pledgedSrcSize); break;
2352
+ case 0 : if (singleSegment) op[pos++] = (BYTE)(pledgedSrcSize); break;
2485
2353
  case 1 : MEM_writeLE16(op+pos, (U16)(pledgedSrcSize-256)); pos+=2; break;
2486
2354
  case 2 : MEM_writeLE32(op+pos, (U32)(pledgedSrcSize)); pos+=4; break;
2487
2355
  case 3 : MEM_writeLE64(op+pos, (U64)(pledgedSrcSize)); pos+=8; break;
@@ -2490,80 +2358,72 @@ static size_t ZSTD_writeFrameHeader(void* dst, size_t dstCapacity,
2490
2358
  }
2491
2359
 
2492
2360
 
2493
- static size_t ZSTD_compressContinue_internal (ZSTD_CCtx* zc,
2361
+ static size_t ZSTD_compressContinue_internal (ZSTD_CCtx* cctx,
2494
2362
  void* dst, size_t dstCapacity,
2495
2363
  const void* src, size_t srcSize,
2496
- U32 frame)
2364
+ U32 frame, U32 lastFrameChunk)
2497
2365
  {
2498
2366
  const BYTE* const ip = (const BYTE*) src;
2499
2367
  size_t fhSize = 0;
2500
2368
 
2501
- if (zc->stage==0) return ERROR(stage_wrong);
2502
- if (frame && (zc->stage==1)) { /* copy saved header */
2503
- fhSize = ZSTD_writeFrameHeader(dst, dstCapacity, zc->params, zc->frameContentSize, zc->dictID);
2369
+ if (cctx->stage==ZSTDcs_created) return ERROR(stage_wrong); /* missing init (ZSTD_compressBegin) */
2370
+
2371
+ if (frame && (cctx->stage==ZSTDcs_init)) {
2372
+ fhSize = ZSTD_writeFrameHeader(dst, dstCapacity, cctx->params, cctx->frameContentSize, cctx->dictID);
2504
2373
  if (ZSTD_isError(fhSize)) return fhSize;
2505
2374
  dstCapacity -= fhSize;
2506
2375
  dst = (char*)dst + fhSize;
2507
- zc->stage = 2;
2376
+ cctx->stage = ZSTDcs_ongoing;
2508
2377
  }
2509
2378
 
2510
2379
  /* Check if blocks follow each other */
2511
- if (src != zc->nextSrc) {
2380
+ if (src != cctx->nextSrc) {
2512
2381
  /* not contiguous */
2513
- size_t const delta = zc->nextSrc - ip;
2514
- zc->lowLimit = zc->dictLimit;
2515
- zc->dictLimit = (U32)(zc->nextSrc - zc->base);
2516
- zc->dictBase = zc->base;
2517
- zc->base -= delta;
2518
- zc->nextToUpdate = zc->dictLimit;
2519
- if (zc->dictLimit - zc->lowLimit < 8) zc->lowLimit = zc->dictLimit; /* too small extDict */
2382
+ ptrdiff_t const delta = cctx->nextSrc - ip;
2383
+ cctx->lowLimit = cctx->dictLimit;
2384
+ cctx->dictLimit = (U32)(cctx->nextSrc - cctx->base);
2385
+ cctx->dictBase = cctx->base;
2386
+ cctx->base -= delta;
2387
+ cctx->nextToUpdate = cctx->dictLimit;
2388
+ if (cctx->dictLimit - cctx->lowLimit < HASH_READ_SIZE) cctx->lowLimit = cctx->dictLimit; /* too small extDict */
2520
2389
  }
2521
2390
 
2522
- /* preemptive overflow correction */
2523
- if (zc->lowLimit > (1<<30)) {
2524
- U32 const btplus = (zc->params.cParams.strategy == ZSTD_btlazy2) | (zc->params.cParams.strategy == ZSTD_btopt);
2525
- U32 const chainMask = (1 << (zc->params.cParams.chainLog - btplus)) - 1;
2526
- U32 const newLowLimit = zc->lowLimit & chainMask; /* preserve position % chainSize */
2527
- U32 const correction = zc->lowLimit - newLowLimit;
2528
- ZSTD_reduceIndex(zc, correction);
2529
- zc->base += correction;
2530
- zc->dictBase += correction;
2531
- zc->lowLimit = newLowLimit;
2532
- zc->dictLimit -= correction;
2533
- if (zc->nextToUpdate < correction) zc->nextToUpdate = 0;
2534
- else zc->nextToUpdate -= correction;
2391
+ /* if input and dictionary overlap : reduce dictionary (area presumed modified by input) */
2392
+ if ((ip+srcSize > cctx->dictBase + cctx->lowLimit) & (ip < cctx->dictBase + cctx->dictLimit)) {
2393
+ ptrdiff_t const highInputIdx = (ip + srcSize) - cctx->dictBase;
2394
+ U32 const lowLimitMax = (highInputIdx > (ptrdiff_t)cctx->dictLimit) ? cctx->dictLimit : (U32)highInputIdx;
2395
+ cctx->lowLimit = lowLimitMax;
2535
2396
  }
2536
2397
 
2537
- /* if input and dictionary overlap : reduce dictionary (presumed modified by input) */
2538
- if ((ip+srcSize > zc->dictBase + zc->lowLimit) && (ip < zc->dictBase + zc->dictLimit)) {
2539
- zc->lowLimit = (U32)(ip + srcSize - zc->dictBase);
2540
- if (zc->lowLimit > zc->dictLimit) zc->lowLimit = zc->dictLimit;
2541
- }
2398
+ cctx->nextSrc = ip + srcSize;
2542
2399
 
2543
- zc->nextSrc = ip + srcSize;
2544
2400
  { size_t const cSize = frame ?
2545
- ZSTD_compress_generic (zc, dst, dstCapacity, src, srcSize) :
2546
- ZSTD_compressBlock_internal (zc, dst, dstCapacity, src, srcSize);
2401
+ ZSTD_compress_generic (cctx, dst, dstCapacity, src, srcSize, lastFrameChunk) :
2402
+ ZSTD_compressBlock_internal (cctx, dst, dstCapacity, src, srcSize);
2547
2403
  if (ZSTD_isError(cSize)) return cSize;
2548
2404
  return cSize + fhSize;
2549
2405
  }
2550
2406
  }
2551
2407
 
2552
2408
 
2553
- size_t ZSTD_compressContinue (ZSTD_CCtx* zc,
2409
+ size_t ZSTD_compressContinue (ZSTD_CCtx* cctx,
2554
2410
  void* dst, size_t dstCapacity,
2555
2411
  const void* src, size_t srcSize)
2556
2412
  {
2557
- return ZSTD_compressContinue_internal(zc, dst, dstCapacity, src, srcSize, 1);
2413
+ return ZSTD_compressContinue_internal(cctx, dst, dstCapacity, src, srcSize, 1, 0);
2558
2414
  }
2559
2415
 
2560
2416
 
2561
- size_t ZSTD_compressBlock(ZSTD_CCtx* zc, void* dst, size_t dstCapacity, const void* src, size_t srcSize)
2417
+ size_t ZSTD_getBlockSizeMax(ZSTD_CCtx* cctx)
2562
2418
  {
2563
- size_t const blockSizeMax = MIN (ZSTD_BLOCKSIZE_MAX, 1 << zc->params.cParams.windowLog);
2419
+ return MIN (ZSTD_BLOCKSIZE_ABSOLUTEMAX, 1 << cctx->params.cParams.windowLog);
2420
+ }
2421
+
2422
+ size_t ZSTD_compressBlock(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize)
2423
+ {
2424
+ size_t const blockSizeMax = ZSTD_getBlockSizeMax(cctx);
2564
2425
  if (srcSize > blockSizeMax) return ERROR(srcSize_wrong);
2565
- ZSTD_LOG_BLOCK("%p: ZSTD_compressBlock searchLength=%d\n", zc->base, zc->params.cParams.searchLength);
2566
- return ZSTD_compressContinue_internal(zc, dst, dstCapacity, src, srcSize, 0);
2426
+ return ZSTD_compressContinue_internal(cctx, dst, dstCapacity, src, srcSize, 0, 0);
2567
2427
  }
2568
2428
 
2569
2429
 
@@ -2581,7 +2441,7 @@ static size_t ZSTD_loadDictionaryContent(ZSTD_CCtx* zc, const void* src, size_t
2581
2441
  zc->loadedDictEnd = (U32)(iend - zc->base);
2582
2442
 
2583
2443
  zc->nextSrc = iend;
2584
- if (srcSize <= 8) return 0;
2444
+ if (srcSize <= HASH_READ_SIZE) return 0;
2585
2445
 
2586
2446
  switch(zc->params.cParams.strategy)
2587
2447
  {
@@ -2596,12 +2456,13 @@ static size_t ZSTD_loadDictionaryContent(ZSTD_CCtx* zc, const void* src, size_t
2596
2456
  case ZSTD_greedy:
2597
2457
  case ZSTD_lazy:
2598
2458
  case ZSTD_lazy2:
2599
- ZSTD_insertAndFindFirstIndex (zc, iend-8, zc->params.cParams.searchLength);
2459
+ ZSTD_insertAndFindFirstIndex (zc, iend-HASH_READ_SIZE, zc->params.cParams.searchLength);
2600
2460
  break;
2601
2461
 
2602
2462
  case ZSTD_btlazy2:
2603
2463
  case ZSTD_btopt:
2604
- ZSTD_updateTree(zc, iend-8, iend, 1 << zc->params.cParams.searchLog, zc->params.cParams.searchLength);
2464
+ case ZSTD_btopt2:
2465
+ ZSTD_updateTree(zc, iend-HASH_READ_SIZE, iend, 1 << zc->params.cParams.searchLog, zc->params.cParams.searchLength);
2605
2466
  break;
2606
2467
 
2607
2468
  default:
@@ -2613,14 +2474,28 @@ static size_t ZSTD_loadDictionaryContent(ZSTD_CCtx* zc, const void* src, size_t
2613
2474
  }
2614
2475
 
2615
2476
 
2477
+ /* Dictionaries that assign zero probability to symbols that show up causes problems
2478
+ when FSE encoding. Refuse dictionaries that assign zero probability to symbols
2479
+ that we may encounter during compression.
2480
+ NOTE: This behavior is not standard and could be improved in the future. */
2481
+ static size_t ZSTD_checkDictNCount(short* normalizedCounter, unsigned dictMaxSymbolValue, unsigned maxSymbolValue) {
2482
+ U32 s;
2483
+ if (dictMaxSymbolValue < maxSymbolValue) return ERROR(dictionary_corrupted);
2484
+ for (s = 0; s <= maxSymbolValue; ++s) {
2485
+ if (normalizedCounter[s] == 0) return ERROR(dictionary_corrupted);
2486
+ }
2487
+ return 0;
2488
+ }
2489
+
2490
+
2616
2491
  /* Dictionary format :
2617
- Magic == ZSTD_DICT_MAGIC (4 bytes)
2618
- HUF_writeCTable(256)
2619
- FSE_writeNCount(ml)
2620
- FSE_writeNCount(off)
2621
- FSE_writeNCount(ll)
2622
- RepOffsets
2623
- Dictionary content
2492
+ Magic == ZSTD_DICT_MAGIC (4 bytes)
2493
+ HUF_writeCTable(256)
2494
+ FSE_writeNCount(off)
2495
+ FSE_writeNCount(ml)
2496
+ FSE_writeNCount(ll)
2497
+ RepOffsets
2498
+ Dictionary content
2624
2499
  */
2625
2500
  /*! ZSTD_loadDictEntropyStats() :
2626
2501
  @return : size read from dictionary
@@ -2629,36 +2504,42 @@ static size_t ZSTD_loadDictEntropyStats(ZSTD_CCtx* cctx, const void* dict, size_
2629
2504
  {
2630
2505
  const BYTE* dictPtr = (const BYTE*)dict;
2631
2506
  const BYTE* const dictEnd = dictPtr + dictSize;
2507
+ short offcodeNCount[MaxOff+1];
2508
+ unsigned offcodeMaxValue = MaxOff;
2632
2509
 
2633
2510
  { size_t const hufHeaderSize = HUF_readCTable(cctx->hufTable, 255, dict, dictSize);
2634
2511
  if (HUF_isError(hufHeaderSize)) return ERROR(dictionary_corrupted);
2635
2512
  dictPtr += hufHeaderSize;
2636
2513
  }
2637
2514
 
2638
- { short offcodeNCount[MaxOff+1];
2639
- unsigned offcodeMaxValue = MaxOff, offcodeLog = OffFSELog;
2515
+ { unsigned offcodeLog;
2640
2516
  size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, dictEnd-dictPtr);
2641
2517
  if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted);
2642
- { size_t const errorCode = FSE_buildCTable(cctx->offcodeCTable, offcodeNCount, offcodeMaxValue, offcodeLog);
2643
- if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted); }
2518
+ if (offcodeLog > OffFSELog) return ERROR(dictionary_corrupted);
2519
+ /* Defer checking offcodeMaxValue because we need to know the size of the dictionary content */
2520
+ CHECK_E (FSE_buildCTable(cctx->offcodeCTable, offcodeNCount, offcodeMaxValue, offcodeLog), dictionary_corrupted);
2644
2521
  dictPtr += offcodeHeaderSize;
2645
2522
  }
2646
2523
 
2647
2524
  { short matchlengthNCount[MaxML+1];
2648
- unsigned matchlengthMaxValue = MaxML, matchlengthLog = MLFSELog;
2525
+ unsigned matchlengthMaxValue = MaxML, matchlengthLog;
2649
2526
  size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, dictEnd-dictPtr);
2650
2527
  if (FSE_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted);
2651
- { size_t const errorCode = FSE_buildCTable(cctx->matchlengthCTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog);
2652
- if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted); }
2528
+ if (matchlengthLog > MLFSELog) return ERROR(dictionary_corrupted);
2529
+ /* Every match length code must have non-zero probability */
2530
+ CHECK_F (ZSTD_checkDictNCount(matchlengthNCount, matchlengthMaxValue, MaxML));
2531
+ CHECK_E (FSE_buildCTable(cctx->matchlengthCTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog), dictionary_corrupted);
2653
2532
  dictPtr += matchlengthHeaderSize;
2654
2533
  }
2655
2534
 
2656
2535
  { short litlengthNCount[MaxLL+1];
2657
- unsigned litlengthMaxValue = MaxLL, litlengthLog = LLFSELog;
2536
+ unsigned litlengthMaxValue = MaxLL, litlengthLog;
2658
2537
  size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, dictEnd-dictPtr);
2659
2538
  if (FSE_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted);
2660
- { size_t const errorCode = FSE_buildCTable(cctx->litlengthCTable, litlengthNCount, litlengthMaxValue, litlengthLog);
2661
- if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted); }
2539
+ if (litlengthLog > LLFSELog) return ERROR(dictionary_corrupted);
2540
+ /* Every literal length code must have non-zero probability */
2541
+ CHECK_F (ZSTD_checkDictNCount(litlengthNCount, litlengthMaxValue, MaxLL));
2542
+ CHECK_E(FSE_buildCTable(cctx->litlengthCTable, litlengthNCount, litlengthMaxValue, litlengthLog), dictionary_corrupted);
2662
2543
  dictPtr += litlengthHeaderSize;
2663
2544
  }
2664
2545
 
@@ -2668,6 +2549,16 @@ static size_t ZSTD_loadDictEntropyStats(ZSTD_CCtx* cctx, const void* dict, size_
2668
2549
  cctx->rep[2] = MEM_readLE32(dictPtr+8); if (cctx->rep[2] >= dictSize) return ERROR(dictionary_corrupted);
2669
2550
  dictPtr += 12;
2670
2551
 
2552
+ { U32 offcodeMax = MaxOff;
2553
+ if ((size_t)(dictEnd - dictPtr) <= ((U32)-1) - 128 KB) {
2554
+ U32 const maxOffset = (U32)(dictEnd - dictPtr) + 128 KB; /* The maximum offset that must be supported */
2555
+ /* Calculate minimum offset code required to represent maxOffset */
2556
+ offcodeMax = ZSTD_highbit32(maxOffset);
2557
+ }
2558
+ /* Every possible supported offset <= dictContentSize + 128 KB must be representable */
2559
+ CHECK_F (ZSTD_checkDictNCount(offcodeNCount, offcodeMaxValue, MIN(offcodeMax, MaxOff)));
2560
+ }
2561
+
2671
2562
  cctx->flagStaticTables = 1;
2672
2563
  return dictPtr - (const BYTE*)dict;
2673
2564
  }
@@ -2683,8 +2574,9 @@ static size_t ZSTD_compress_insertDictionary(ZSTD_CCtx* zc, const void* dict, si
2683
2574
  zc->dictID = zc->params.fParams.noDictIDFlag ? 0 : MEM_readLE32((const char*)dict+4);
2684
2575
 
2685
2576
  /* known magic number : dict is parsed for entropy stats and content */
2686
- { size_t const eSize = ZSTD_loadDictEntropyStats(zc, (const char*)dict+8 /* skip dictHeader */, dictSize-8) + 8;
2687
- if (ZSTD_isError(eSize)) return eSize;
2577
+ { size_t const loadError = ZSTD_loadDictEntropyStats(zc, (const char*)dict+8 /* skip dictHeader */, dictSize-8);
2578
+ size_t const eSize = loadError + 8;
2579
+ if (ZSTD_isError(loadError)) return loadError;
2688
2580
  return ZSTD_loadDictionaryContent(zc, (const char*)dict+eSize, dictSize-eSize);
2689
2581
  }
2690
2582
  }
@@ -2692,14 +2584,13 @@ static size_t ZSTD_compress_insertDictionary(ZSTD_CCtx* zc, const void* dict, si
2692
2584
 
2693
2585
  /*! ZSTD_compressBegin_internal() :
2694
2586
  * @return : 0, or an error code */
2695
- static size_t ZSTD_compressBegin_internal(ZSTD_CCtx* zc,
2587
+ static size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx,
2696
2588
  const void* dict, size_t dictSize,
2697
2589
  ZSTD_parameters params, U64 pledgedSrcSize)
2698
2590
  {
2699
- size_t const resetError = ZSTD_resetCCtx_advanced(zc, params, pledgedSrcSize, 1);
2700
- if (ZSTD_isError(resetError)) return resetError;
2701
-
2702
- return ZSTD_compress_insertDictionary(zc, dict, dictSize);
2591
+ ZSTD_compResetPolicy_e const crp = dictSize ? ZSTDcrp_fullReset : ZSTDcrp_continue;
2592
+ CHECK_F(ZSTD_resetCCtx_advanced(cctx, params, pledgedSrcSize, crp));
2593
+ return ZSTD_compress_insertDictionary(cctx, dict, dictSize);
2703
2594
  }
2704
2595
 
2705
2596
 
@@ -2710,9 +2601,7 @@ size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx,
2710
2601
  ZSTD_parameters params, unsigned long long pledgedSrcSize)
2711
2602
  {
2712
2603
  /* compression parameters verification and optimization */
2713
- { size_t const errorCode = ZSTD_checkCParams_advanced(params.cParams, pledgedSrcSize);
2714
- if (ZSTD_isError(errorCode)) return errorCode; }
2715
-
2604
+ CHECK_F(ZSTD_checkCParams(params.cParams));
2716
2605
  return ZSTD_compressBegin_internal(cctx, dict, dictSize, params, pledgedSrcSize);
2717
2606
  }
2718
2607
 
@@ -2720,100 +2609,78 @@ size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx,
2720
2609
  size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel)
2721
2610
  {
2722
2611
  ZSTD_parameters const params = ZSTD_getParams(compressionLevel, 0, dictSize);
2723
- ZSTD_LOG_BLOCK("%p: ZSTD_compressBegin_usingDict compressionLevel=%d\n", cctx->base, compressionLevel);
2724
2612
  return ZSTD_compressBegin_internal(cctx, dict, dictSize, params, 0);
2725
2613
  }
2726
2614
 
2727
2615
 
2728
2616
  size_t ZSTD_compressBegin(ZSTD_CCtx* zc, int compressionLevel)
2729
2617
  {
2730
- ZSTD_LOG_BLOCK("%p: ZSTD_compressBegin compressionLevel=%d\n", zc->base, compressionLevel);
2731
2618
  return ZSTD_compressBegin_usingDict(zc, NULL, 0, compressionLevel);
2732
2619
  }
2733
2620
 
2734
2621
 
2735
- /*! ZSTD_compressEnd() :
2736
- * Write frame epilogue.
2622
+ /*! ZSTD_writeEpilogue() :
2623
+ * Ends a frame.
2737
2624
  * @return : nb of bytes written into dst (or an error code) */
2738
- size_t ZSTD_compressEnd(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity)
2625
+ static size_t ZSTD_writeEpilogue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity)
2739
2626
  {
2740
- BYTE* op = (BYTE*)dst;
2627
+ BYTE* const ostart = (BYTE*)dst;
2628
+ BYTE* op = ostart;
2741
2629
  size_t fhSize = 0;
2742
2630
 
2743
- /* not even init ! */
2744
- if (cctx->stage==0) return ERROR(stage_wrong);
2631
+ if (cctx->stage == ZSTDcs_created) return ERROR(stage_wrong); /* init missing */
2745
2632
 
2746
2633
  /* special case : empty frame */
2747
- if (cctx->stage==1) {
2634
+ if (cctx->stage == ZSTDcs_init) {
2748
2635
  fhSize = ZSTD_writeFrameHeader(dst, dstCapacity, cctx->params, 0, 0);
2749
2636
  if (ZSTD_isError(fhSize)) return fhSize;
2750
2637
  dstCapacity -= fhSize;
2751
2638
  op += fhSize;
2752
- cctx->stage = 2;
2639
+ cctx->stage = ZSTDcs_ongoing;
2640
+ }
2641
+
2642
+ if (cctx->stage != ZSTDcs_ending) {
2643
+ /* write one last empty block, make it the "last" block */
2644
+ U32 const cBlockHeader24 = 1 /* last block */ + (((U32)bt_raw)<<1) + 0;
2645
+ if (dstCapacity<4) return ERROR(dstSize_tooSmall);
2646
+ MEM_writeLE32(op, cBlockHeader24);
2647
+ op += ZSTD_blockHeaderSize;
2648
+ dstCapacity -= ZSTD_blockHeaderSize;
2753
2649
  }
2754
2650
 
2755
- /* frame epilogue */
2756
- if (dstCapacity < 3) return ERROR(dstSize_tooSmall);
2757
- { U32 const checksum = cctx->params.fParams.checksumFlag ?
2758
- (U32)((XXH64_digest(&cctx->xxhState) >> 11) & ((1<<22)-1)) :
2759
- 0;
2760
- op[0] = (BYTE)((bt_end<<6) + (checksum>>16));
2761
- op[1] = (BYTE)(checksum>>8);
2762
- op[2] = (BYTE)checksum;
2651
+ if (cctx->params.fParams.checksumFlag) {
2652
+ U32 const checksum = (U32) XXH64_digest(&cctx->xxhState);
2653
+ if (dstCapacity<4) return ERROR(dstSize_tooSmall);
2654
+ MEM_writeLE32(op, checksum);
2655
+ op += 4;
2763
2656
  }
2764
2657
 
2765
- cctx->stage = 0; /* return to "created but not init" status */
2766
- return 3+fhSize;
2658
+ cctx->stage = ZSTDcs_created; /* return to "created but no init" status */
2659
+ return op-ostart;
2767
2660
  }
2768
2661
 
2769
2662
 
2770
- /*! ZSTD_compress_usingPreparedCCtx() :
2771
- * Same as ZSTD_compress_usingDict, but using a reference context `preparedCCtx`, where dictionary has been loaded.
2772
- * It avoids reloading the dictionary each time.
2773
- * `preparedCCtx` must have been properly initialized using ZSTD_compressBegin_usingDict() or ZSTD_compressBegin_advanced().
2774
- * Requires 2 contexts : 1 for reference (preparedCCtx) which will not be modified, and 1 to run the compression operation (cctx) */
2775
- static size_t ZSTD_compress_usingPreparedCCtx(ZSTD_CCtx* cctx, const ZSTD_CCtx* preparedCCtx,
2776
- void* dst, size_t dstCapacity,
2777
- const void* src, size_t srcSize)
2663
+ size_t ZSTD_compressEnd (ZSTD_CCtx* cctx,
2664
+ void* dst, size_t dstCapacity,
2665
+ const void* src, size_t srcSize)
2778
2666
  {
2779
- { size_t const errorCode = ZSTD_copyCCtx(cctx, preparedCCtx);
2780
- if (ZSTD_isError(errorCode)) return errorCode;
2781
- }
2782
- { size_t const cSize = ZSTD_compressContinue(cctx, dst, dstCapacity, src, srcSize);
2783
- if (ZSTD_isError(cSize)) return cSize;
2784
-
2785
- { size_t const endSize = ZSTD_compressEnd(cctx, (char*)dst+cSize, dstCapacity-cSize);
2786
- if (ZSTD_isError(endSize)) return endSize;
2787
- return cSize + endSize;
2788
- } }
2667
+ size_t endResult;
2668
+ size_t const cSize = ZSTD_compressContinue_internal(cctx, dst, dstCapacity, src, srcSize, 1, 1);
2669
+ if (ZSTD_isError(cSize)) return cSize;
2670
+ endResult = ZSTD_writeEpilogue(cctx, (char*)dst + cSize, dstCapacity-cSize);
2671
+ if (ZSTD_isError(endResult)) return endResult;
2672
+ return cSize + endResult;
2789
2673
  }
2790
2674
 
2791
2675
 
2792
- static size_t ZSTD_compress_internal (ZSTD_CCtx* ctx,
2676
+ static size_t ZSTD_compress_internal (ZSTD_CCtx* cctx,
2793
2677
  void* dst, size_t dstCapacity,
2794
2678
  const void* src, size_t srcSize,
2795
2679
  const void* dict,size_t dictSize,
2796
2680
  ZSTD_parameters params)
2797
2681
  {
2798
- BYTE* const ostart = (BYTE*)dst;
2799
- BYTE* op = ostart;
2800
-
2801
- /* Init */
2802
- { size_t const errorCode = ZSTD_compressBegin_internal(ctx, dict, dictSize, params, srcSize);
2803
- if(ZSTD_isError(errorCode)) return errorCode; }
2804
-
2805
- /* body (compression) */
2806
- { size_t const oSize = ZSTD_compressContinue (ctx, op, dstCapacity, src, srcSize);
2807
- if(ZSTD_isError(oSize)) return oSize;
2808
- op += oSize;
2809
- dstCapacity -= oSize; }
2810
-
2811
- /* Close frame */
2812
- { size_t const oSize = ZSTD_compressEnd(ctx, op, dstCapacity);
2813
- if(ZSTD_isError(oSize)) return oSize;
2814
- op += oSize; }
2815
-
2816
- return (op - ostart);
2682
+ CHECK_F(ZSTD_compressBegin_internal(cctx, dict, dictSize, params, srcSize));
2683
+ return ZSTD_compressEnd(cctx, dst, dstCapacity, src, srcSize);
2817
2684
  }
2818
2685
 
2819
2686
  size_t ZSTD_compress_advanced (ZSTD_CCtx* ctx,
@@ -2822,8 +2689,7 @@ size_t ZSTD_compress_advanced (ZSTD_CCtx* ctx,
2822
2689
  const void* dict,size_t dictSize,
2823
2690
  ZSTD_parameters params)
2824
2691
  {
2825
- size_t const errorCode = ZSTD_checkCParams_advanced(params.cParams, srcSize);
2826
- if (ZSTD_isError(errorCode)) return errorCode;
2692
+ CHECK_F(ZSTD_checkCParams(params.cParams));
2827
2693
  return ZSTD_compress_internal(ctx, dst, dstCapacity, src, srcSize, dict, dictSize, params);
2828
2694
  }
2829
2695
 
@@ -2831,13 +2697,11 @@ size_t ZSTD_compress_usingDict(ZSTD_CCtx* ctx, void* dst, size_t dstCapacity, co
2831
2697
  {
2832
2698
  ZSTD_parameters params = ZSTD_getParams(compressionLevel, srcSize, dictSize);
2833
2699
  params.fParams.contentSizeFlag = 1;
2834
- ZSTD_LOG_BLOCK("%p: ZSTD_compress_usingDict srcSize=%d dictSize=%d compressionLevel=%d\n", ctx->base, (int)srcSize, (int)dictSize, compressionLevel);
2835
2700
  return ZSTD_compress_internal(ctx, dst, dstCapacity, src, srcSize, dict, dictSize, params);
2836
2701
  }
2837
2702
 
2838
2703
  size_t ZSTD_compressCCtx (ZSTD_CCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize, int compressionLevel)
2839
2704
  {
2840
- ZSTD_LOG_BLOCK("%p: ZSTD_compressCCtx srcSize=%d compressionLevel=%d\n", ctx->base, (int)srcSize, compressionLevel);
2841
2705
  return ZSTD_compress_usingDict(ctx, dst, dstCapacity, src, srcSize, NULL, 0, compressionLevel);
2842
2706
  }
2843
2707
 
@@ -2848,7 +2712,7 @@ size_t ZSTD_compress(void* dst, size_t dstCapacity, const void* src, size_t srcS
2848
2712
  memset(&ctxBody, 0, sizeof(ctxBody));
2849
2713
  memcpy(&ctxBody.customMem, &defaultCustomMem, sizeof(ZSTD_customMem));
2850
2714
  result = ZSTD_compressCCtx(&ctxBody, dst, dstCapacity, src, srcSize, compressionLevel);
2851
- ctxBody.customMem.customFree(ctxBody.customMem.opaque, ctxBody.workSpace); /* can't free ctxBody, since it's on stack; just free heap content */
2715
+ ZSTD_free(ctxBody.workSpace, defaultCustomMem); /* can't free ctxBody itself, as it's on stack; free only heap content */
2852
2716
  return result;
2853
2717
  }
2854
2718
 
@@ -2859,33 +2723,38 @@ struct ZSTD_CDict_s {
2859
2723
  void* dictContent;
2860
2724
  size_t dictContentSize;
2861
2725
  ZSTD_CCtx* refContext;
2862
- }; /* typedef'd tp ZSTD_CDict within zstd.h */
2726
+ }; /* typedef'd tp ZSTD_CDict within "zstd.h" */
2863
2727
 
2864
- ZSTD_CDict* ZSTD_createCDict_advanced(const void* dict, size_t dictSize, ZSTD_parameters params, ZSTD_customMem customMem)
2728
+ size_t ZSTD_sizeof_CDict(const ZSTD_CDict* cdict)
2865
2729
  {
2866
- if (!customMem.customAlloc && !customMem.customFree)
2867
- customMem = defaultCustomMem;
2730
+ if (cdict==NULL) return 0; /* support sizeof on NULL */
2731
+ return ZSTD_sizeof_CCtx(cdict->refContext) + cdict->dictContentSize;
2732
+ }
2868
2733
 
2869
- if (!customMem.customAlloc || !customMem.customFree) /* can't have 1/2 custom alloc/free as NULL */
2870
- return NULL;
2734
+ ZSTD_CDict* ZSTD_createCDict_advanced(const void* dict, size_t dictSize, ZSTD_parameters params, ZSTD_customMem customMem)
2735
+ {
2736
+ if (!customMem.customAlloc && !customMem.customFree) customMem = defaultCustomMem;
2737
+ if (!customMem.customAlloc || !customMem.customFree) return NULL;
2871
2738
 
2872
- { ZSTD_CDict* const cdict = (ZSTD_CDict*) customMem.customAlloc(customMem.opaque, sizeof(*cdict));
2873
- void* const dictContent = customMem.customAlloc(customMem.opaque, dictSize);
2739
+ { ZSTD_CDict* const cdict = (ZSTD_CDict*) ZSTD_malloc(sizeof(ZSTD_CDict), customMem);
2740
+ void* const dictContent = ZSTD_malloc(dictSize, customMem);
2874
2741
  ZSTD_CCtx* const cctx = ZSTD_createCCtx_advanced(customMem);
2875
2742
 
2876
2743
  if (!dictContent || !cdict || !cctx) {
2877
- customMem.customFree(customMem.opaque, dictContent);
2878
- customMem.customFree(customMem.opaque, cdict);
2879
- customMem.customFree(customMem.opaque, cctx);
2744
+ ZSTD_free(dictContent, customMem);
2745
+ ZSTD_free(cdict, customMem);
2746
+ ZSTD_free(cctx, customMem);
2880
2747
  return NULL;
2881
2748
  }
2882
2749
 
2883
- memcpy(dictContent, dict, dictSize);
2750
+ if (dictSize) {
2751
+ memcpy(dictContent, dict, dictSize);
2752
+ }
2884
2753
  { size_t const errorCode = ZSTD_compressBegin_advanced(cctx, dictContent, dictSize, params, 0);
2885
2754
  if (ZSTD_isError(errorCode)) {
2886
- customMem.customFree(customMem.opaque, dictContent);
2887
- customMem.customFree(customMem.opaque, cdict);
2888
- customMem.customFree(customMem.opaque, cctx);
2755
+ ZSTD_free(dictContent, customMem);
2756
+ ZSTD_free(cdict, customMem);
2757
+ ZSTD_free(cctx, customMem);
2889
2758
  return NULL;
2890
2759
  } }
2891
2760
 
@@ -2899,31 +2768,352 @@ ZSTD_CDict* ZSTD_createCDict_advanced(const void* dict, size_t dictSize, ZSTD_pa
2899
2768
  ZSTD_CDict* ZSTD_createCDict(const void* dict, size_t dictSize, int compressionLevel)
2900
2769
  {
2901
2770
  ZSTD_customMem const allocator = { NULL, NULL, NULL };
2902
- ZSTD_parameters params;
2903
- memset(&params, 0, sizeof(params));
2904
- params.cParams = ZSTD_getCParams(compressionLevel, 0, dictSize);
2771
+ ZSTD_parameters params = ZSTD_getParams(compressionLevel, 0, dictSize);
2905
2772
  params.fParams.contentSizeFlag = 1;
2906
2773
  return ZSTD_createCDict_advanced(dict, dictSize, params, allocator);
2907
2774
  }
2908
2775
 
2909
2776
  size_t ZSTD_freeCDict(ZSTD_CDict* cdict)
2910
2777
  {
2911
- ZSTD_freeFunction const cFree = cdict->refContext->customMem.customFree;
2912
- void* const opaque = cdict->refContext->customMem.opaque;
2913
- ZSTD_freeCCtx(cdict->refContext);
2914
- cFree(opaque, cdict->dictContent);
2915
- cFree(opaque, cdict);
2778
+ if (cdict==NULL) return 0; /* support free on NULL */
2779
+ { ZSTD_customMem const cMem = cdict->refContext->customMem;
2780
+ ZSTD_freeCCtx(cdict->refContext);
2781
+ ZSTD_free(cdict->dictContent, cMem);
2782
+ ZSTD_free(cdict, cMem);
2783
+ return 0;
2784
+ }
2785
+ }
2786
+
2787
+ static ZSTD_parameters ZSTD_getParamsFromCDict(const ZSTD_CDict* cdict) {
2788
+ return ZSTD_getParamsFromCCtx(cdict->refContext);
2789
+ }
2790
+
2791
+ size_t ZSTD_compressBegin_usingCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict, U64 pledgedSrcSize)
2792
+ {
2793
+ if (cdict->dictContentSize) CHECK_F(ZSTD_copyCCtx(cctx, cdict->refContext, pledgedSrcSize))
2794
+ else CHECK_F(ZSTD_compressBegin_advanced(cctx, NULL, 0, cdict->refContext->params, pledgedSrcSize));
2916
2795
  return 0;
2917
2796
  }
2918
2797
 
2919
- ZSTDLIB_API size_t ZSTD_compress_usingCDict(ZSTD_CCtx* cctx,
2920
- void* dst, size_t dstCapacity,
2921
- const void* src, size_t srcSize,
2922
- const ZSTD_CDict* cdict)
2798
+ /*! ZSTD_compress_usingCDict() :
2799
+ * Compression using a digested Dictionary.
2800
+ * Faster startup than ZSTD_compress_usingDict(), recommended when same dictionary is used multiple times.
2801
+ * Note that compression level is decided during dictionary creation */
2802
+ size_t ZSTD_compress_usingCDict(ZSTD_CCtx* cctx,
2803
+ void* dst, size_t dstCapacity,
2804
+ const void* src, size_t srcSize,
2805
+ const ZSTD_CDict* cdict)
2806
+ {
2807
+ CHECK_F(ZSTD_compressBegin_usingCDict(cctx, cdict, srcSize));
2808
+
2809
+ if (cdict->refContext->params.fParams.contentSizeFlag==1) {
2810
+ cctx->params.fParams.contentSizeFlag = 1;
2811
+ cctx->frameContentSize = srcSize;
2812
+ }
2813
+
2814
+ return ZSTD_compressEnd(cctx, dst, dstCapacity, src, srcSize);
2815
+ }
2816
+
2817
+
2818
+
2819
+ /* ******************************************************************
2820
+ * Streaming
2821
+ ********************************************************************/
2822
+
2823
+ typedef enum { zcss_init, zcss_load, zcss_flush, zcss_final } ZSTD_cStreamStage;
2824
+
2825
+ struct ZSTD_CStream_s {
2826
+ ZSTD_CCtx* cctx;
2827
+ ZSTD_CDict* cdictLocal;
2828
+ const ZSTD_CDict* cdict;
2829
+ char* inBuff;
2830
+ size_t inBuffSize;
2831
+ size_t inToCompress;
2832
+ size_t inBuffPos;
2833
+ size_t inBuffTarget;
2834
+ size_t blockSize;
2835
+ char* outBuff;
2836
+ size_t outBuffSize;
2837
+ size_t outBuffContentSize;
2838
+ size_t outBuffFlushedSize;
2839
+ ZSTD_cStreamStage stage;
2840
+ U32 checksum;
2841
+ U32 frameEnded;
2842
+ ZSTD_parameters params;
2843
+ ZSTD_customMem customMem;
2844
+ }; /* typedef'd to ZSTD_CStream within "zstd.h" */
2845
+
2846
+ ZSTD_CStream* ZSTD_createCStream(void)
2923
2847
  {
2924
- return ZSTD_compress_usingPreparedCCtx(cctx, cdict->refContext,
2925
- dst, dstCapacity,
2926
- src, srcSize);
2848
+ return ZSTD_createCStream_advanced(defaultCustomMem);
2849
+ }
2850
+
2851
+ ZSTD_CStream* ZSTD_createCStream_advanced(ZSTD_customMem customMem)
2852
+ {
2853
+ ZSTD_CStream* zcs;
2854
+
2855
+ if (!customMem.customAlloc && !customMem.customFree) customMem = defaultCustomMem;
2856
+ if (!customMem.customAlloc || !customMem.customFree) return NULL;
2857
+
2858
+ zcs = (ZSTD_CStream*)ZSTD_malloc(sizeof(ZSTD_CStream), customMem);
2859
+ if (zcs==NULL) return NULL;
2860
+ memset(zcs, 0, sizeof(ZSTD_CStream));
2861
+ memcpy(&zcs->customMem, &customMem, sizeof(ZSTD_customMem));
2862
+ zcs->cctx = ZSTD_createCCtx_advanced(customMem);
2863
+ if (zcs->cctx == NULL) { ZSTD_freeCStream(zcs); return NULL; }
2864
+ return zcs;
2865
+ }
2866
+
2867
+ size_t ZSTD_freeCStream(ZSTD_CStream* zcs)
2868
+ {
2869
+ if (zcs==NULL) return 0; /* support free on NULL */
2870
+ { ZSTD_customMem const cMem = zcs->customMem;
2871
+ ZSTD_freeCCtx(zcs->cctx);
2872
+ ZSTD_freeCDict(zcs->cdictLocal);
2873
+ ZSTD_free(zcs->inBuff, cMem);
2874
+ ZSTD_free(zcs->outBuff, cMem);
2875
+ ZSTD_free(zcs, cMem);
2876
+ return 0;
2877
+ }
2878
+ }
2879
+
2880
+
2881
+ /*====== Initialization ======*/
2882
+
2883
+ size_t ZSTD_CStreamInSize(void) { return ZSTD_BLOCKSIZE_ABSOLUTEMAX; }
2884
+ size_t ZSTD_CStreamOutSize(void) { return ZSTD_compressBound(ZSTD_BLOCKSIZE_ABSOLUTEMAX) + ZSTD_blockHeaderSize + 4 /* 32-bits hash */ ; }
2885
+
2886
+ size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize)
2887
+ {
2888
+ if (zcs->inBuffSize==0) return ERROR(stage_wrong); /* zcs has not been init at least once */
2889
+
2890
+ if (zcs->cdict) CHECK_F(ZSTD_compressBegin_usingCDict(zcs->cctx, zcs->cdict, pledgedSrcSize))
2891
+ else CHECK_F(ZSTD_compressBegin_advanced(zcs->cctx, NULL, 0, zcs->params, pledgedSrcSize));
2892
+
2893
+ zcs->inToCompress = 0;
2894
+ zcs->inBuffPos = 0;
2895
+ zcs->inBuffTarget = zcs->blockSize;
2896
+ zcs->outBuffContentSize = zcs->outBuffFlushedSize = 0;
2897
+ zcs->stage = zcss_load;
2898
+ zcs->frameEnded = 0;
2899
+ return 0; /* ready to go */
2900
+ }
2901
+
2902
+ size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs,
2903
+ const void* dict, size_t dictSize,
2904
+ ZSTD_parameters params, unsigned long long pledgedSrcSize)
2905
+ {
2906
+ /* allocate buffers */
2907
+ { size_t const neededInBuffSize = (size_t)1 << params.cParams.windowLog;
2908
+ if (zcs->inBuffSize < neededInBuffSize) {
2909
+ zcs->inBuffSize = neededInBuffSize;
2910
+ ZSTD_free(zcs->inBuff, zcs->customMem);
2911
+ zcs->inBuff = (char*) ZSTD_malloc(neededInBuffSize, zcs->customMem);
2912
+ if (zcs->inBuff == NULL) return ERROR(memory_allocation);
2913
+ }
2914
+ zcs->blockSize = MIN(ZSTD_BLOCKSIZE_ABSOLUTEMAX, neededInBuffSize);
2915
+ }
2916
+ if (zcs->outBuffSize < ZSTD_compressBound(zcs->blockSize)+1) {
2917
+ zcs->outBuffSize = ZSTD_compressBound(zcs->blockSize)+1;
2918
+ ZSTD_free(zcs->outBuff, zcs->customMem);
2919
+ zcs->outBuff = (char*) ZSTD_malloc(zcs->outBuffSize, zcs->customMem);
2920
+ if (zcs->outBuff == NULL) return ERROR(memory_allocation);
2921
+ }
2922
+
2923
+ if (dict) {
2924
+ ZSTD_freeCDict(zcs->cdictLocal);
2925
+ zcs->cdictLocal = ZSTD_createCDict_advanced(dict, dictSize, params, zcs->customMem);
2926
+ if (zcs->cdictLocal == NULL) return ERROR(memory_allocation);
2927
+ zcs->cdict = zcs->cdictLocal;
2928
+ } else zcs->cdict = NULL;
2929
+
2930
+ zcs->checksum = params.fParams.checksumFlag > 0;
2931
+ zcs->params = params;
2932
+
2933
+ return ZSTD_resetCStream(zcs, pledgedSrcSize);
2934
+ }
2935
+
2936
+ /* note : cdict must outlive compression session */
2937
+ size_t ZSTD_initCStream_usingCDict(ZSTD_CStream* zcs, const ZSTD_CDict* cdict)
2938
+ {
2939
+ ZSTD_parameters const params = ZSTD_getParamsFromCDict(cdict);
2940
+ size_t const initError = ZSTD_initCStream_advanced(zcs, NULL, 0, params, 0);
2941
+ zcs->cdict = cdict;
2942
+ return initError;
2943
+ }
2944
+
2945
+ size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel)
2946
+ {
2947
+ ZSTD_parameters const params = ZSTD_getParams(compressionLevel, 0, dictSize);
2948
+ return ZSTD_initCStream_advanced(zcs, dict, dictSize, params, 0);
2949
+ }
2950
+
2951
+ size_t ZSTD_initCStream(ZSTD_CStream* zcs, int compressionLevel)
2952
+ {
2953
+ return ZSTD_initCStream_usingDict(zcs, NULL, 0, compressionLevel);
2954
+ }
2955
+
2956
+ size_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs)
2957
+ {
2958
+ if (zcs==NULL) return 0; /* support sizeof on NULL */
2959
+ return sizeof(zcs) + ZSTD_sizeof_CCtx(zcs->cctx) + ZSTD_sizeof_CDict(zcs->cdictLocal) + zcs->outBuffSize + zcs->inBuffSize;
2960
+ }
2961
+
2962
+ /*====== Compression ======*/
2963
+
2964
+ typedef enum { zsf_gather, zsf_flush, zsf_end } ZSTD_flush_e;
2965
+
2966
+ MEM_STATIC size_t ZSTD_limitCopy(void* dst, size_t dstCapacity, const void* src, size_t srcSize)
2967
+ {
2968
+ size_t const length = MIN(dstCapacity, srcSize);
2969
+ memcpy(dst, src, length);
2970
+ return length;
2971
+ }
2972
+
2973
+ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
2974
+ void* dst, size_t* dstCapacityPtr,
2975
+ const void* src, size_t* srcSizePtr,
2976
+ ZSTD_flush_e const flush)
2977
+ {
2978
+ U32 someMoreWork = 1;
2979
+ const char* const istart = (const char*)src;
2980
+ const char* const iend = istart + *srcSizePtr;
2981
+ const char* ip = istart;
2982
+ char* const ostart = (char*)dst;
2983
+ char* const oend = ostart + *dstCapacityPtr;
2984
+ char* op = ostart;
2985
+
2986
+ while (someMoreWork) {
2987
+ switch(zcs->stage)
2988
+ {
2989
+ case zcss_init: return ERROR(init_missing); /* call ZBUFF_compressInit() first ! */
2990
+
2991
+ case zcss_load:
2992
+ /* complete inBuffer */
2993
+ { size_t const toLoad = zcs->inBuffTarget - zcs->inBuffPos;
2994
+ size_t const loaded = ZSTD_limitCopy(zcs->inBuff + zcs->inBuffPos, toLoad, ip, iend-ip);
2995
+ zcs->inBuffPos += loaded;
2996
+ ip += loaded;
2997
+ if ( (zcs->inBuffPos==zcs->inToCompress) || (!flush && (toLoad != loaded)) ) {
2998
+ someMoreWork = 0; break; /* not enough input to get a full block : stop there, wait for more */
2999
+ } }
3000
+ /* compress current block (note : this stage cannot be stopped in the middle) */
3001
+ { void* cDst;
3002
+ size_t cSize;
3003
+ size_t const iSize = zcs->inBuffPos - zcs->inToCompress;
3004
+ size_t oSize = oend-op;
3005
+ if (oSize >= ZSTD_compressBound(iSize))
3006
+ cDst = op; /* compress directly into output buffer (avoid flush stage) */
3007
+ else
3008
+ cDst = zcs->outBuff, oSize = zcs->outBuffSize;
3009
+ cSize = (flush == zsf_end) ?
3010
+ ZSTD_compressEnd(zcs->cctx, cDst, oSize, zcs->inBuff + zcs->inToCompress, iSize) :
3011
+ ZSTD_compressContinue(zcs->cctx, cDst, oSize, zcs->inBuff + zcs->inToCompress, iSize);
3012
+ if (ZSTD_isError(cSize)) return cSize;
3013
+ if (flush == zsf_end) zcs->frameEnded = 1;
3014
+ /* prepare next block */
3015
+ zcs->inBuffTarget = zcs->inBuffPos + zcs->blockSize;
3016
+ if (zcs->inBuffTarget > zcs->inBuffSize)
3017
+ zcs->inBuffPos = 0, zcs->inBuffTarget = zcs->blockSize; /* note : inBuffSize >= blockSize */
3018
+ zcs->inToCompress = zcs->inBuffPos;
3019
+ if (cDst == op) { op += cSize; break; } /* no need to flush */
3020
+ zcs->outBuffContentSize = cSize;
3021
+ zcs->outBuffFlushedSize = 0;
3022
+ zcs->stage = zcss_flush; /* pass-through to flush stage */
3023
+ }
3024
+
3025
+ case zcss_flush:
3026
+ { size_t const toFlush = zcs->outBuffContentSize - zcs->outBuffFlushedSize;
3027
+ size_t const flushed = ZSTD_limitCopy(op, oend-op, zcs->outBuff + zcs->outBuffFlushedSize, toFlush);
3028
+ op += flushed;
3029
+ zcs->outBuffFlushedSize += flushed;
3030
+ if (toFlush!=flushed) { someMoreWork = 0; break; } /* dst too small to store flushed data : stop there */
3031
+ zcs->outBuffContentSize = zcs->outBuffFlushedSize = 0;
3032
+ zcs->stage = zcss_load;
3033
+ break;
3034
+ }
3035
+
3036
+ case zcss_final:
3037
+ someMoreWork = 0; /* do nothing */
3038
+ break;
3039
+
3040
+ default:
3041
+ return ERROR(GENERIC); /* impossible */
3042
+ }
3043
+ }
3044
+
3045
+ *srcSizePtr = ip - istart;
3046
+ *dstCapacityPtr = op - ostart;
3047
+ if (zcs->frameEnded) return 0;
3048
+ { size_t hintInSize = zcs->inBuffTarget - zcs->inBuffPos;
3049
+ if (hintInSize==0) hintInSize = zcs->blockSize;
3050
+ return hintInSize;
3051
+ }
3052
+ }
3053
+
3054
+ size_t ZSTD_compressStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output, ZSTD_inBuffer* input)
3055
+ {
3056
+ size_t sizeRead = input->size - input->pos;
3057
+ size_t sizeWritten = output->size - output->pos;
3058
+ size_t const result = ZSTD_compressStream_generic(zcs,
3059
+ (char*)(output->dst) + output->pos, &sizeWritten,
3060
+ (const char*)(input->src) + input->pos, &sizeRead, zsf_gather);
3061
+ input->pos += sizeRead;
3062
+ output->pos += sizeWritten;
3063
+ return result;
3064
+ }
3065
+
3066
+
3067
+ /*====== Finalize ======*/
3068
+
3069
+ /*! ZSTD_flushStream() :
3070
+ * @return : amount of data remaining to flush */
3071
+ size_t ZSTD_flushStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output)
3072
+ {
3073
+ size_t srcSize = 0;
3074
+ size_t sizeWritten = output->size - output->pos;
3075
+ size_t const result = ZSTD_compressStream_generic(zcs,
3076
+ (char*)(output->dst) + output->pos, &sizeWritten,
3077
+ &srcSize, &srcSize, /* use a valid src address instead of NULL */
3078
+ zsf_flush);
3079
+ output->pos += sizeWritten;
3080
+ if (ZSTD_isError(result)) return result;
3081
+ return zcs->outBuffContentSize - zcs->outBuffFlushedSize; /* remaining to flush */
3082
+ }
3083
+
3084
+
3085
+ size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output)
3086
+ {
3087
+ BYTE* const ostart = (BYTE*)(output->dst) + output->pos;
3088
+ BYTE* const oend = (BYTE*)(output->dst) + output->size;
3089
+ BYTE* op = ostart;
3090
+
3091
+ if (zcs->stage != zcss_final) {
3092
+ /* flush whatever remains */
3093
+ size_t srcSize = 0;
3094
+ size_t sizeWritten = output->size - output->pos;
3095
+ size_t const notEnded = ZSTD_compressStream_generic(zcs, ostart, &sizeWritten, &srcSize, &srcSize, zsf_end); /* use a valid src address instead of NULL */
3096
+ size_t const remainingToFlush = zcs->outBuffContentSize - zcs->outBuffFlushedSize;
3097
+ op += sizeWritten;
3098
+ if (remainingToFlush) {
3099
+ output->pos += sizeWritten;
3100
+ return remainingToFlush + ZSTD_BLOCKHEADERSIZE /* final empty block */ + (zcs->checksum * 4);
3101
+ }
3102
+ /* create epilogue */
3103
+ zcs->stage = zcss_final;
3104
+ zcs->outBuffContentSize = !notEnded ? 0 :
3105
+ ZSTD_compressEnd(zcs->cctx, zcs->outBuff, zcs->outBuffSize, NULL, 0); /* write epilogue, including final empty block, into outBuff */
3106
+ }
3107
+
3108
+ /* flush epilogue */
3109
+ { size_t const toFlush = zcs->outBuffContentSize - zcs->outBuffFlushedSize;
3110
+ size_t const flushed = ZSTD_limitCopy(op, oend-op, zcs->outBuff + zcs->outBuffFlushedSize, toFlush);
3111
+ op += flushed;
3112
+ zcs->outBuffFlushedSize += flushed;
3113
+ output->pos += op-ostart;
3114
+ if (toFlush==flushed) zcs->stage = zcss_init; /* end reached */
3115
+ return toFlush - flushed;
3116
+ }
2927
3117
  }
2928
3118
 
2929
3119
 
@@ -2932,20 +3122,20 @@ ZSTDLIB_API size_t ZSTD_compress_usingCDict(ZSTD_CCtx* cctx,
2932
3122
 
2933
3123
  #define ZSTD_DEFAULT_CLEVEL 1
2934
3124
  #define ZSTD_MAX_CLEVEL 22
2935
- unsigned ZSTD_maxCLevel(void) { return ZSTD_MAX_CLEVEL; }
3125
+ int ZSTD_maxCLevel(void) { return ZSTD_MAX_CLEVEL; }
2936
3126
 
2937
3127
  static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEVEL+1] = {
2938
3128
  { /* "default" */
2939
3129
  /* W, C, H, S, L, TL, strat */
2940
- { 18, 12, 12, 1, 7, 16, ZSTD_fast }, /* level 0 - not used */
3130
+ { 18, 12, 12, 1, 7, 16, ZSTD_fast }, /* level 0 - never used */
2941
3131
  { 19, 13, 14, 1, 7, 16, ZSTD_fast }, /* level 1 */
2942
3132
  { 19, 15, 16, 1, 6, 16, ZSTD_fast }, /* level 2 */
2943
- { 20, 16, 18, 1, 5, 16, ZSTD_dfast }, /* level 3 */
2944
- { 20, 13, 17, 2, 5, 16, ZSTD_greedy }, /* level 4.*/
3133
+ { 20, 16, 17, 1, 5, 16, ZSTD_dfast }, /* level 3.*/
3134
+ { 20, 18, 18, 1, 5, 16, ZSTD_dfast }, /* level 4.*/
2945
3135
  { 20, 15, 18, 3, 5, 16, ZSTD_greedy }, /* level 5 */
2946
3136
  { 21, 16, 19, 2, 5, 16, ZSTD_lazy }, /* level 6 */
2947
3137
  { 21, 17, 20, 3, 5, 16, ZSTD_lazy }, /* level 7 */
2948
- { 21, 18, 20, 3, 5, 16, ZSTD_lazy2 }, /* level 8.*/
3138
+ { 21, 18, 20, 3, 5, 16, ZSTD_lazy2 }, /* level 8 */
2949
3139
  { 21, 20, 20, 3, 5, 16, ZSTD_lazy2 }, /* level 9 */
2950
3140
  { 21, 19, 21, 4, 5, 16, ZSTD_lazy2 }, /* level 10 */
2951
3141
  { 22, 20, 22, 4, 5, 16, ZSTD_lazy2 }, /* level 11 */
@@ -2954,69 +3144,69 @@ static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEV
2954
3144
  { 22, 21, 22, 6, 5, 16, ZSTD_lazy2 }, /* level 14 */
2955
3145
  { 22, 21, 21, 5, 5, 16, ZSTD_btlazy2 }, /* level 15 */
2956
3146
  { 23, 22, 22, 5, 5, 16, ZSTD_btlazy2 }, /* level 16 */
2957
- { 23, 23, 22, 5, 5, 16, ZSTD_btlazy2 }, /* level 17.*/
2958
- { 23, 23, 22, 6, 5, 24, ZSTD_btopt }, /* level 18.*/
2959
- { 23, 23, 22, 6, 3, 48, ZSTD_btopt }, /* level 19.*/
2960
- { 25, 26, 23, 7, 3, 64, ZSTD_btopt }, /* level 20.*/
2961
- { 26, 26, 23, 7, 3,256, ZSTD_btopt }, /* level 21.*/
2962
- { 27, 27, 25, 9, 3,512, ZSTD_btopt }, /* level 22.*/
3147
+ { 23, 21, 22, 4, 5, 24, ZSTD_btopt }, /* level 17 */
3148
+ { 23, 23, 22, 6, 5, 32, ZSTD_btopt }, /* level 18 */
3149
+ { 23, 23, 22, 6, 3, 48, ZSTD_btopt }, /* level 19 */
3150
+ { 25, 25, 23, 7, 3, 64, ZSTD_btopt2 }, /* level 20 */
3151
+ { 26, 26, 23, 7, 3,256, ZSTD_btopt2 }, /* level 21 */
3152
+ { 27, 27, 25, 9, 3,512, ZSTD_btopt2 }, /* level 22 */
2963
3153
  },
2964
3154
  { /* for srcSize <= 256 KB */
2965
3155
  /* W, C, H, S, L, T, strat */
2966
- { 18, 12, 12, 1, 7, 4, ZSTD_fast }, /* level 0 - not used */
2967
- { 18, 13, 14, 1, 6, 4, ZSTD_fast }, /* level 1 */
2968
- { 18, 15, 17, 1, 5, 4, ZSTD_fast }, /* level 2 */
2969
- { 18, 13, 15, 1, 5, 4, ZSTD_greedy }, /* level 3.*/
2970
- { 18, 15, 17, 1, 5, 4, ZSTD_greedy }, /* level 4.*/
2971
- { 18, 16, 17, 4, 5, 4, ZSTD_greedy }, /* level 5 */
2972
- { 18, 17, 17, 5, 5, 4, ZSTD_greedy }, /* level 6 */
2973
- { 18, 17, 17, 4, 4, 4, ZSTD_lazy }, /* level 7 */
2974
- { 18, 17, 17, 4, 4, 4, ZSTD_lazy2 }, /* level 8 */
2975
- { 18, 17, 17, 5, 4, 4, ZSTD_lazy2 }, /* level 9 */
2976
- { 18, 17, 17, 6, 4, 4, ZSTD_lazy2 }, /* level 10 */
2977
- { 18, 18, 17, 6, 4, 4, ZSTD_lazy2 }, /* level 11.*/
2978
- { 18, 18, 17, 7, 4, 4, ZSTD_lazy2 }, /* level 12.*/
2979
- { 18, 19, 17, 7, 4, 4, ZSTD_btlazy2 }, /* level 13 */
3156
+ { 0, 0, 0, 0, 0, 0, ZSTD_fast }, /* level 0 - not used */
3157
+ { 18, 13, 14, 1, 6, 8, ZSTD_fast }, /* level 1 */
3158
+ { 18, 14, 13, 1, 5, 8, ZSTD_dfast }, /* level 2 */
3159
+ { 18, 16, 15, 1, 5, 8, ZSTD_dfast }, /* level 3 */
3160
+ { 18, 15, 17, 1, 5, 8, ZSTD_greedy }, /* level 4.*/
3161
+ { 18, 16, 17, 4, 5, 8, ZSTD_greedy }, /* level 5.*/
3162
+ { 18, 16, 17, 3, 5, 8, ZSTD_lazy }, /* level 6.*/
3163
+ { 18, 17, 17, 4, 4, 8, ZSTD_lazy }, /* level 7 */
3164
+ { 18, 17, 17, 4, 4, 8, ZSTD_lazy2 }, /* level 8 */
3165
+ { 18, 17, 17, 5, 4, 8, ZSTD_lazy2 }, /* level 9 */
3166
+ { 18, 17, 17, 6, 4, 8, ZSTD_lazy2 }, /* level 10 */
3167
+ { 18, 18, 17, 6, 4, 8, ZSTD_lazy2 }, /* level 11.*/
3168
+ { 18, 18, 17, 7, 4, 8, ZSTD_lazy2 }, /* level 12.*/
3169
+ { 18, 19, 17, 6, 4, 8, ZSTD_btlazy2 }, /* level 13 */
2980
3170
  { 18, 18, 18, 4, 4, 16, ZSTD_btopt }, /* level 14.*/
2981
- { 18, 18, 18, 8, 4, 24, ZSTD_btopt }, /* level 15.*/
2982
- { 18, 19, 18, 8, 3, 48, ZSTD_btopt }, /* level 16.*/
2983
- { 18, 19, 18, 8, 3, 96, ZSTD_btopt }, /* level 17.*/
3171
+ { 18, 18, 18, 4, 3, 16, ZSTD_btopt }, /* level 15.*/
3172
+ { 18, 19, 18, 6, 3, 32, ZSTD_btopt }, /* level 16.*/
3173
+ { 18, 19, 18, 8, 3, 64, ZSTD_btopt }, /* level 17.*/
2984
3174
  { 18, 19, 18, 9, 3,128, ZSTD_btopt }, /* level 18.*/
2985
3175
  { 18, 19, 18, 10, 3,256, ZSTD_btopt }, /* level 19.*/
2986
- { 18, 19, 18, 11, 3,512, ZSTD_btopt }, /* level 20.*/
2987
- { 18, 19, 18, 12, 3,512, ZSTD_btopt }, /* level 21.*/
2988
- { 18, 19, 18, 13, 3,512, ZSTD_btopt }, /* level 22.*/
3176
+ { 18, 19, 18, 11, 3,512, ZSTD_btopt2 }, /* level 20.*/
3177
+ { 18, 19, 18, 12, 3,512, ZSTD_btopt2 }, /* level 21.*/
3178
+ { 18, 19, 18, 13, 3,512, ZSTD_btopt2 }, /* level 22.*/
2989
3179
  },
2990
3180
  { /* for srcSize <= 128 KB */
2991
3181
  /* W, C, H, S, L, T, strat */
2992
- { 17, 12, 12, 1, 7, 4, ZSTD_fast }, /* level 0 - not used */
2993
- { 17, 12, 13, 1, 6, 4, ZSTD_fast }, /* level 1 */
2994
- { 17, 13, 16, 1, 5, 4, ZSTD_fast }, /* level 2 */
2995
- { 17, 13, 14, 2, 5, 4, ZSTD_greedy }, /* level 3 */
2996
- { 17, 13, 15, 3, 4, 4, ZSTD_greedy }, /* level 4 */
2997
- { 17, 15, 17, 4, 4, 4, ZSTD_greedy }, /* level 5 */
2998
- { 17, 16, 17, 3, 4, 4, ZSTD_lazy }, /* level 6 */
2999
- { 17, 15, 17, 4, 4, 4, ZSTD_lazy2 }, /* level 7 */
3000
- { 17, 17, 17, 4, 4, 4, ZSTD_lazy2 }, /* level 8 */
3001
- { 17, 17, 17, 5, 4, 4, ZSTD_lazy2 }, /* level 9 */
3002
- { 17, 17, 17, 6, 4, 4, ZSTD_lazy2 }, /* level 10 */
3003
- { 17, 17, 17, 7, 4, 4, ZSTD_lazy2 }, /* level 11 */
3004
- { 17, 17, 17, 8, 4, 4, ZSTD_lazy2 }, /* level 12 */
3005
- { 17, 18, 17, 6, 4, 4, ZSTD_btlazy2 }, /* level 13.*/
3182
+ { 17, 12, 12, 1, 7, 8, ZSTD_fast }, /* level 0 - not used */
3183
+ { 17, 12, 13, 1, 6, 8, ZSTD_fast }, /* level 1 */
3184
+ { 17, 13, 16, 1, 5, 8, ZSTD_fast }, /* level 2 */
3185
+ { 17, 16, 16, 2, 5, 8, ZSTD_dfast }, /* level 3 */
3186
+ { 17, 13, 15, 3, 4, 8, ZSTD_greedy }, /* level 4 */
3187
+ { 17, 15, 17, 4, 4, 8, ZSTD_greedy }, /* level 5 */
3188
+ { 17, 16, 17, 3, 4, 8, ZSTD_lazy }, /* level 6 */
3189
+ { 17, 15, 17, 4, 4, 8, ZSTD_lazy2 }, /* level 7 */
3190
+ { 17, 17, 17, 4, 4, 8, ZSTD_lazy2 }, /* level 8 */
3191
+ { 17, 17, 17, 5, 4, 8, ZSTD_lazy2 }, /* level 9 */
3192
+ { 17, 17, 17, 6, 4, 8, ZSTD_lazy2 }, /* level 10 */
3193
+ { 17, 17, 17, 7, 4, 8, ZSTD_lazy2 }, /* level 11 */
3194
+ { 17, 17, 17, 8, 4, 8, ZSTD_lazy2 }, /* level 12 */
3195
+ { 17, 18, 17, 6, 4, 8, ZSTD_btlazy2 }, /* level 13.*/
3006
3196
  { 17, 17, 17, 7, 3, 8, ZSTD_btopt }, /* level 14.*/
3007
3197
  { 17, 17, 17, 7, 3, 16, ZSTD_btopt }, /* level 15.*/
3008
3198
  { 17, 18, 17, 7, 3, 32, ZSTD_btopt }, /* level 16.*/
3009
3199
  { 17, 18, 17, 7, 3, 64, ZSTD_btopt }, /* level 17.*/
3010
3200
  { 17, 18, 17, 7, 3,256, ZSTD_btopt }, /* level 18.*/
3011
3201
  { 17, 18, 17, 8, 3,256, ZSTD_btopt }, /* level 19.*/
3012
- { 17, 18, 17, 9, 3,256, ZSTD_btopt }, /* level 20.*/
3013
- { 17, 18, 17, 10, 3,256, ZSTD_btopt }, /* level 21.*/
3014
- { 17, 18, 17, 11, 3,256, ZSTD_btopt }, /* level 22.*/
3202
+ { 17, 18, 17, 9, 3,256, ZSTD_btopt2 }, /* level 20.*/
3203
+ { 17, 18, 17, 10, 3,256, ZSTD_btopt2 }, /* level 21.*/
3204
+ { 17, 18, 17, 11, 3,512, ZSTD_btopt2 }, /* level 22.*/
3015
3205
  },
3016
3206
  { /* for srcSize <= 16 KB */
3017
3207
  /* W, C, H, S, L, T, strat */
3018
3208
  { 14, 12, 12, 1, 7, 6, ZSTD_fast }, /* level 0 - not used */
3019
- { 14, 14, 14, 1, 7, 6, ZSTD_fast }, /* level 1 */
3209
+ { 14, 14, 14, 1, 6, 6, ZSTD_fast }, /* level 1 */
3020
3210
  { 14, 14, 14, 1, 4, 6, ZSTD_fast }, /* level 2 */
3021
3211
  { 14, 14, 14, 1, 4, 6, ZSTD_dfast }, /* level 3.*/
3022
3212
  { 14, 14, 14, 4, 4, 6, ZSTD_greedy }, /* level 4.*/
@@ -3035,9 +3225,9 @@ static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEV
3035
3225
  { 14, 15, 15, 6, 3,128, ZSTD_btopt }, /* level 17.*/
3036
3226
  { 14, 15, 15, 6, 3,256, ZSTD_btopt }, /* level 18.*/
3037
3227
  { 14, 15, 15, 7, 3,256, ZSTD_btopt }, /* level 19.*/
3038
- { 14, 15, 15, 8, 3,256, ZSTD_btopt }, /* level 20.*/
3039
- { 14, 15, 15, 9, 3,256, ZSTD_btopt }, /* level 21.*/
3040
- { 14, 15, 15, 10, 3,256, ZSTD_btopt }, /* level 22.*/
3228
+ { 14, 15, 15, 8, 3,256, ZSTD_btopt2 }, /* level 20.*/
3229
+ { 14, 15, 15, 9, 3,256, ZSTD_btopt2 }, /* level 21.*/
3230
+ { 14, 15, 15, 10, 3,256, ZSTD_btopt2 }, /* level 22.*/
3041
3231
  },
3042
3232
  };
3043
3233