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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) 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/2.1/extzstd.so +0 -0
  59. data/lib/2.2/extzstd.so +0 -0
  60. data/lib/2.3/extzstd.so +0 -0
  61. data/lib/extzstd/version.rb +1 -1
  62. data/lib/extzstd.rb +77 -43
  63. data/test/test_basic.rb +11 -6
  64. metadata +23 -11
  65. data/contrib/zstd/common/error_public.h +0 -77
  66. data/contrib/zstd/common/zstd.h +0 -475
  67. data/ext/extzstd_buffered.c +0 -265
  68. data/ext/zstd_amalgam.c +0 -18
  69. data/lib/2.0/extzstd.so +0 -0
@@ -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