extzstd 0.1 → 0.1.1
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.
- checksums.yaml +4 -4
- data/HISTORY.ja +5 -0
- data/README.md +5 -5
- data/contrib/zstd/CONTRIBUTING.md +42 -0
- data/contrib/zstd/LICENSE-examples +11 -0
- data/contrib/zstd/Makefile +315 -0
- data/contrib/zstd/NEWS +261 -0
- data/contrib/zstd/PATENTS +33 -0
- data/contrib/zstd/README.md +121 -41
- data/contrib/zstd/TESTING.md +44 -0
- data/contrib/zstd/appveyor.yml +178 -0
- data/contrib/zstd/circle.yml +75 -0
- data/contrib/zstd/lib/BUCK +186 -0
- data/contrib/zstd/lib/Makefile +163 -0
- data/contrib/zstd/lib/README.md +77 -0
- data/contrib/zstd/{common → lib/common}/bitstream.h +7 -4
- data/contrib/zstd/{common → lib/common}/entropy_common.c +19 -23
- data/contrib/zstd/{common → lib/common}/error_private.c +0 -0
- data/contrib/zstd/{common → lib/common}/error_private.h +0 -0
- data/contrib/zstd/{common → lib/common}/fse.h +94 -34
- data/contrib/zstd/{common → lib/common}/fse_decompress.c +18 -19
- data/contrib/zstd/{common → lib/common}/huf.h +52 -20
- data/contrib/zstd/{common → lib/common}/mem.h +17 -13
- data/contrib/zstd/lib/common/pool.c +194 -0
- data/contrib/zstd/lib/common/pool.h +56 -0
- data/contrib/zstd/lib/common/threading.c +80 -0
- data/contrib/zstd/lib/common/threading.h +104 -0
- data/contrib/zstd/{common → lib/common}/xxhash.c +3 -1
- data/contrib/zstd/{common → lib/common}/xxhash.h +11 -15
- data/contrib/zstd/{common → lib/common}/zstd_common.c +1 -11
- data/contrib/zstd/{common → lib/common}/zstd_errors.h +16 -2
- data/contrib/zstd/{common → lib/common}/zstd_internal.h +17 -1
- data/contrib/zstd/{compress → lib/compress}/fse_compress.c +138 -91
- data/contrib/zstd/{compress → lib/compress}/huf_compress.c +218 -67
- data/contrib/zstd/{compress → lib/compress}/zstd_compress.c +231 -108
- data/contrib/zstd/{compress → lib/compress}/zstd_opt.h +44 -25
- data/contrib/zstd/lib/compress/zstdmt_compress.c +739 -0
- data/contrib/zstd/lib/compress/zstdmt_compress.h +78 -0
- data/contrib/zstd/{decompress → lib/decompress}/huf_decompress.c +28 -23
- data/contrib/zstd/{decompress → lib/decompress}/zstd_decompress.c +814 -176
- data/contrib/zstd/{common → lib/deprecated}/zbuff.h +60 -39
- data/contrib/zstd/lib/deprecated/zbuff_common.c +26 -0
- data/contrib/zstd/lib/deprecated/zbuff_compress.c +145 -0
- data/contrib/zstd/lib/deprecated/zbuff_decompress.c +74 -0
- data/contrib/zstd/lib/dictBuilder/cover.c +1029 -0
- data/contrib/zstd/{dictBuilder → lib/dictBuilder}/divsufsort.c +0 -0
- data/contrib/zstd/{dictBuilder → lib/dictBuilder}/divsufsort.h +0 -0
- data/contrib/zstd/{dictBuilder → lib/dictBuilder}/zdict.c +68 -18
- data/contrib/zstd/lib/dictBuilder/zdict.h +201 -0
- data/contrib/zstd/{legacy → lib/legacy}/zstd_legacy.h +122 -7
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v01.c +34 -3
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v01.h +8 -0
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v02.c +45 -12
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v02.h +8 -0
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v03.c +45 -12
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v03.h +8 -0
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v04.c +56 -33
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v04.h +8 -0
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v05.c +45 -18
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v05.h +7 -0
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v06.c +43 -16
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v06.h +7 -0
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v07.c +57 -23
- data/contrib/zstd/{legacy → lib/legacy}/zstd_v07.h +8 -0
- data/contrib/zstd/lib/libzstd.pc.in +14 -0
- data/contrib/zstd/{zstd.h → lib/zstd.h} +206 -71
- data/ext/depend +2 -0
- data/ext/extconf.rb +4 -4
- data/ext/extzstd.c +1 -1
- data/ext/zstd_common.c +5 -5
- data/ext/zstd_compress.c +3 -3
- data/ext/zstd_decompress.c +2 -2
- data/ext/zstd_dictbuilder.c +2 -2
- data/ext/zstd_legacy_v01.c +1 -1
- data/ext/zstd_legacy_v02.c +1 -1
- data/ext/zstd_legacy_v03.c +1 -1
- data/ext/zstd_legacy_v04.c +1 -1
- data/ext/zstd_legacy_v05.c +1 -1
- data/ext/zstd_legacy_v06.c +1 -1
- data/ext/zstd_legacy_v07.c +1 -1
- data/gemstub.rb +9 -5
- data/lib/extzstd/version.rb +1 -1
- metadata +73 -51
- data/contrib/zstd/compress/zbuff_compress.c +0 -319
- data/contrib/zstd/decompress/zbuff_decompress.c +0 -252
- data/contrib/zstd/dictBuilder/zdict.h +0 -111
|
@@ -13,8 +13,6 @@
|
|
|
13
13
|
***************************************/
|
|
14
14
|
#include <string.h> /* memset */
|
|
15
15
|
#include "mem.h"
|
|
16
|
-
#define XXH_STATIC_LINKING_ONLY /* XXH64_state_t */
|
|
17
|
-
#include "xxhash.h" /* XXH_reset, update, digest */
|
|
18
16
|
#define FSE_STATIC_LINKING_ONLY /* FSE_encodeSymbol */
|
|
19
17
|
#include "fse.h"
|
|
20
18
|
#define HUF_STATIC_LINKING_ONLY
|
|
@@ -33,6 +31,7 @@ typedef enum { ZSTDcs_created=0, ZSTDcs_init, ZSTDcs_ongoing, ZSTDcs_ending } ZS
|
|
|
33
31
|
/*-*************************************
|
|
34
32
|
* Helper functions
|
|
35
33
|
***************************************/
|
|
34
|
+
#define ZSTD_STATIC_ASSERT(c) { enum { ZSTD_static_assert = 1/(int)(!!(c)) }; }
|
|
36
35
|
size_t ZSTD_compressBound(size_t srcSize) { return FSE_compressBound(srcSize) + 12; }
|
|
37
36
|
|
|
38
37
|
|
|
@@ -50,8 +49,7 @@ static void ZSTD_resetSeqStore(seqStore_t* ssPtr)
|
|
|
50
49
|
/*-*************************************
|
|
51
50
|
* Context memory management
|
|
52
51
|
***************************************/
|
|
53
|
-
struct ZSTD_CCtx_s
|
|
54
|
-
{
|
|
52
|
+
struct ZSTD_CCtx_s {
|
|
55
53
|
const BYTE* nextSrc; /* next block here to continue on current prefix */
|
|
56
54
|
const BYTE* base; /* All regular indexes relative to this position */
|
|
57
55
|
const BYTE* dictBase; /* extDict indexes relative to this position */
|
|
@@ -60,10 +58,12 @@ struct ZSTD_CCtx_s
|
|
|
60
58
|
U32 nextToUpdate; /* index from which to continue dictionary update */
|
|
61
59
|
U32 nextToUpdate3; /* index from which to continue dictionary update */
|
|
62
60
|
U32 hashLog3; /* dispatch table : larger == faster, more memory */
|
|
63
|
-
U32 loadedDictEnd;
|
|
61
|
+
U32 loadedDictEnd; /* index of end of dictionary */
|
|
62
|
+
U32 forceWindow; /* force back-references to respect limit of 1<<wLog, even for dictionary */
|
|
63
|
+
U32 forceRawDict; /* Force loading dictionary in "content-only" mode (no header analysis) */
|
|
64
64
|
ZSTD_compressionStage_e stage;
|
|
65
65
|
U32 rep[ZSTD_REP_NUM];
|
|
66
|
-
U32
|
|
66
|
+
U32 repToConfirm[ZSTD_REP_NUM];
|
|
67
67
|
U32 dictID;
|
|
68
68
|
ZSTD_parameters params;
|
|
69
69
|
void* workSpace;
|
|
@@ -79,9 +79,11 @@ struct ZSTD_CCtx_s
|
|
|
79
79
|
U32* chainTable;
|
|
80
80
|
HUF_CElt* hufTable;
|
|
81
81
|
U32 flagStaticTables;
|
|
82
|
+
HUF_repeat flagStaticHufTable;
|
|
82
83
|
FSE_CTable offcodeCTable [FSE_CTABLE_SIZE_U32(OffFSELog, MaxOff)];
|
|
83
84
|
FSE_CTable matchlengthCTable[FSE_CTABLE_SIZE_U32(MLFSELog, MaxML)];
|
|
84
85
|
FSE_CTable litlengthCTable [FSE_CTABLE_SIZE_U32(LLFSELog, MaxLL)];
|
|
86
|
+
unsigned tmpCounters[HUF_WORKSPACE_SIZE_U32];
|
|
85
87
|
};
|
|
86
88
|
|
|
87
89
|
ZSTD_CCtx* ZSTD_createCCtx(void)
|
|
@@ -99,7 +101,7 @@ ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem)
|
|
|
99
101
|
cctx = (ZSTD_CCtx*) ZSTD_malloc(sizeof(ZSTD_CCtx), customMem);
|
|
100
102
|
if (!cctx) return NULL;
|
|
101
103
|
memset(cctx, 0, sizeof(ZSTD_CCtx));
|
|
102
|
-
|
|
104
|
+
cctx->customMem = customMem;
|
|
103
105
|
return cctx;
|
|
104
106
|
}
|
|
105
107
|
|
|
@@ -117,6 +119,16 @@ size_t ZSTD_sizeof_CCtx(const ZSTD_CCtx* cctx)
|
|
|
117
119
|
return sizeof(*cctx) + cctx->workSpaceSize;
|
|
118
120
|
}
|
|
119
121
|
|
|
122
|
+
size_t ZSTD_setCCtxParameter(ZSTD_CCtx* cctx, ZSTD_CCtxParameter param, unsigned value)
|
|
123
|
+
{
|
|
124
|
+
switch(param)
|
|
125
|
+
{
|
|
126
|
+
case ZSTD_p_forceWindow : cctx->forceWindow = value>0; cctx->loadedDictEnd = 0; return 0;
|
|
127
|
+
case ZSTD_p_forceRawDict : cctx->forceRawDict = value>0; return 0;
|
|
128
|
+
default: return ERROR(parameter_unknown);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
120
132
|
const seqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx) /* hidden interface */
|
|
121
133
|
{
|
|
122
134
|
return &(ctx->seqStore);
|
|
@@ -147,6 +159,14 @@ size_t ZSTD_checkCParams(ZSTD_compressionParameters cParams)
|
|
|
147
159
|
}
|
|
148
160
|
|
|
149
161
|
|
|
162
|
+
/** ZSTD_cycleLog() :
|
|
163
|
+
* condition for correct operation : hashLog > 1 */
|
|
164
|
+
static U32 ZSTD_cycleLog(U32 hashLog, ZSTD_strategy strat)
|
|
165
|
+
{
|
|
166
|
+
U32 const btScale = ((U32)strat >= (U32)ZSTD_btlazy2);
|
|
167
|
+
return hashLog - btScale;
|
|
168
|
+
}
|
|
169
|
+
|
|
150
170
|
/** ZSTD_adjustCParams() :
|
|
151
171
|
optimize `cPar` for a given input (`srcSize` and `dictSize`).
|
|
152
172
|
mostly downsizing to reduce memory consumption and initialization.
|
|
@@ -165,9 +185,9 @@ ZSTD_compressionParameters ZSTD_adjustCParams(ZSTD_compressionParameters cPar, u
|
|
|
165
185
|
if (cPar.windowLog > srcLog) cPar.windowLog = srcLog;
|
|
166
186
|
} }
|
|
167
187
|
if (cPar.hashLog > cPar.windowLog) cPar.hashLog = cPar.windowLog;
|
|
168
|
-
{ U32 const
|
|
169
|
-
|
|
170
|
-
|
|
188
|
+
{ U32 const cycleLog = ZSTD_cycleLog(cPar.chainLog, cPar.strategy);
|
|
189
|
+
if (cycleLog > cPar.windowLog) cPar.chainLog -= (cycleLog - cPar.windowLog);
|
|
190
|
+
}
|
|
171
191
|
|
|
172
192
|
if (cPar.windowLog < ZSTD_WINDOWLOG_ABSOLUTEMIN) cPar.windowLog = ZSTD_WINDOWLOG_ABSOLUTEMIN; /* required for frame header */
|
|
173
193
|
|
|
@@ -227,14 +247,17 @@ static size_t ZSTD_continueCCtx(ZSTD_CCtx* cctx, ZSTD_parameters params, U64 fra
|
|
|
227
247
|
typedef enum { ZSTDcrp_continue, ZSTDcrp_noMemset, ZSTDcrp_fullReset } ZSTD_compResetPolicy_e;
|
|
228
248
|
|
|
229
249
|
/*! ZSTD_resetCCtx_advanced() :
|
|
230
|
-
note :
|
|
250
|
+
note : `params` must be validated */
|
|
231
251
|
static size_t ZSTD_resetCCtx_advanced (ZSTD_CCtx* zc,
|
|
232
252
|
ZSTD_parameters params, U64 frameContentSize,
|
|
233
253
|
ZSTD_compResetPolicy_e const crp)
|
|
234
254
|
{
|
|
235
255
|
if (crp == ZSTDcrp_continue)
|
|
236
|
-
if (ZSTD_equivalentParams(params, zc->params))
|
|
256
|
+
if (ZSTD_equivalentParams(params, zc->params)) {
|
|
257
|
+
zc->flagStaticTables = 0;
|
|
258
|
+
zc->flagStaticHufTable = HUF_repeat_none;
|
|
237
259
|
return ZSTD_continueCCtx(zc, params, frameContentSize);
|
|
260
|
+
}
|
|
238
261
|
|
|
239
262
|
{ size_t const blockSize = MIN(ZSTD_BLOCKSIZE_ABSOLUTEMAX, (size_t)1 << params.cParams.windowLog);
|
|
240
263
|
U32 const divider = (params.cParams.searchLength==3) ? 3 : 4;
|
|
@@ -268,6 +291,7 @@ static size_t ZSTD_resetCCtx_advanced (ZSTD_CCtx* zc,
|
|
|
268
291
|
ptr = zc->hashTable3 + h3Size;
|
|
269
292
|
zc->hufTable = (HUF_CElt*)ptr;
|
|
270
293
|
zc->flagStaticTables = 0;
|
|
294
|
+
zc->flagStaticHufTable = HUF_repeat_none;
|
|
271
295
|
ptr = ((U32*)ptr) + 256; /* note : HUF_CElt* is incomplete type, size is simulated using U32 */
|
|
272
296
|
|
|
273
297
|
zc->nextToUpdate = 1;
|
|
@@ -308,6 +332,14 @@ static size_t ZSTD_resetCCtx_advanced (ZSTD_CCtx* zc,
|
|
|
308
332
|
}
|
|
309
333
|
}
|
|
310
334
|
|
|
335
|
+
/* ZSTD_invalidateRepCodes() :
|
|
336
|
+
* ensures next compression will not use repcodes from previous block.
|
|
337
|
+
* Note : only works with regular variant;
|
|
338
|
+
* do not use with extDict variant ! */
|
|
339
|
+
void ZSTD_invalidateRepCodes(ZSTD_CCtx* cctx) {
|
|
340
|
+
int i;
|
|
341
|
+
for (i=0; i<ZSTD_REP_NUM; i++) cctx->rep[i] = 0;
|
|
342
|
+
}
|
|
311
343
|
|
|
312
344
|
/*! ZSTD_copyCCtx() :
|
|
313
345
|
* Duplicate an existing context `srcCCtx` into another one `dstCCtx`.
|
|
@@ -317,8 +349,12 @@ size_t ZSTD_copyCCtx(ZSTD_CCtx* dstCCtx, const ZSTD_CCtx* srcCCtx, unsigned long
|
|
|
317
349
|
{
|
|
318
350
|
if (srcCCtx->stage!=ZSTDcs_init) return ERROR(stage_wrong);
|
|
319
351
|
|
|
352
|
+
|
|
320
353
|
memcpy(&dstCCtx->customMem, &srcCCtx->customMem, sizeof(ZSTD_customMem));
|
|
321
|
-
|
|
354
|
+
{ ZSTD_parameters params = srcCCtx->params;
|
|
355
|
+
params.fParams.contentSizeFlag = (pledgedSrcSize > 0);
|
|
356
|
+
ZSTD_resetCCtx_advanced(dstCCtx, params, pledgedSrcSize, ZSTDcrp_noMemset);
|
|
357
|
+
}
|
|
322
358
|
|
|
323
359
|
/* copy tables */
|
|
324
360
|
{ size_t const chainSize = (srcCCtx->params.cParams.strategy == ZSTD_fast) ? 0 : (1 << srcCCtx->params.cParams.chainLog);
|
|
@@ -341,12 +377,15 @@ size_t ZSTD_copyCCtx(ZSTD_CCtx* dstCCtx, const ZSTD_CCtx* srcCCtx, unsigned long
|
|
|
341
377
|
|
|
342
378
|
/* copy entropy tables */
|
|
343
379
|
dstCCtx->flagStaticTables = srcCCtx->flagStaticTables;
|
|
380
|
+
dstCCtx->flagStaticHufTable = srcCCtx->flagStaticHufTable;
|
|
344
381
|
if (srcCCtx->flagStaticTables) {
|
|
345
|
-
memcpy(dstCCtx->hufTable, srcCCtx->hufTable, 256*4);
|
|
346
382
|
memcpy(dstCCtx->litlengthCTable, srcCCtx->litlengthCTable, sizeof(dstCCtx->litlengthCTable));
|
|
347
383
|
memcpy(dstCCtx->matchlengthCTable, srcCCtx->matchlengthCTable, sizeof(dstCCtx->matchlengthCTable));
|
|
348
384
|
memcpy(dstCCtx->offcodeCTable, srcCCtx->offcodeCTable, sizeof(dstCCtx->offcodeCTable));
|
|
349
385
|
}
|
|
386
|
+
if (srcCCtx->flagStaticHufTable) {
|
|
387
|
+
memcpy(dstCCtx->hufTable, srcCCtx->hufTable, 256*4);
|
|
388
|
+
}
|
|
350
389
|
|
|
351
390
|
return 0;
|
|
352
391
|
}
|
|
@@ -460,24 +499,28 @@ static size_t ZSTD_compressLiterals (ZSTD_CCtx* zc,
|
|
|
460
499
|
|
|
461
500
|
/* small ? don't even attempt compression (speed opt) */
|
|
462
501
|
# define LITERAL_NOENTROPY 63
|
|
463
|
-
{ size_t const minLitSize = zc->
|
|
502
|
+
{ size_t const minLitSize = zc->flagStaticHufTable == HUF_repeat_valid ? 6 : LITERAL_NOENTROPY;
|
|
464
503
|
if (srcSize <= minLitSize) return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
|
|
465
504
|
}
|
|
466
505
|
|
|
467
506
|
if (dstCapacity < lhSize+1) return ERROR(dstSize_tooSmall); /* not enough space for compression */
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
singleStream = 1;
|
|
471
|
-
cLitSize =
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
507
|
+
{ HUF_repeat repeat = zc->flagStaticHufTable;
|
|
508
|
+
int const preferRepeat = zc->params.cParams.strategy < ZSTD_lazy ? srcSize <= 1024 : 0;
|
|
509
|
+
if (repeat == HUF_repeat_valid && lhSize == 3) singleStream = 1;
|
|
510
|
+
cLitSize = singleStream ? HUF_compress1X_repeat(ostart+lhSize, dstCapacity-lhSize, src, srcSize, 255, 11, zc->tmpCounters, sizeof(zc->tmpCounters), zc->hufTable, &repeat, preferRepeat)
|
|
511
|
+
: HUF_compress4X_repeat(ostart+lhSize, dstCapacity-lhSize, src, srcSize, 255, 11, zc->tmpCounters, sizeof(zc->tmpCounters), zc->hufTable, &repeat, preferRepeat);
|
|
512
|
+
if (repeat != HUF_repeat_none) { hType = set_repeat; } /* reused the existing table */
|
|
513
|
+
else { zc->flagStaticHufTable = HUF_repeat_check; } /* now have a table to reuse */
|
|
475
514
|
}
|
|
476
515
|
|
|
477
|
-
if ((cLitSize==0) | (cLitSize >= srcSize - minGain))
|
|
516
|
+
if ((cLitSize==0) | (cLitSize >= srcSize - minGain)) {
|
|
517
|
+
zc->flagStaticHufTable = HUF_repeat_none;
|
|
478
518
|
return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
|
|
479
|
-
|
|
519
|
+
}
|
|
520
|
+
if (cLitSize==1) {
|
|
521
|
+
zc->flagStaticHufTable = HUF_repeat_none;
|
|
480
522
|
return ZSTD_compressRleLiteralsBlock(dst, dstCapacity, src, srcSize);
|
|
523
|
+
}
|
|
481
524
|
|
|
482
525
|
/* Build header */
|
|
483
526
|
switch(lhSize)
|
|
@@ -545,11 +588,11 @@ void ZSTD_seqToCodes(const seqStore_t* seqStorePtr)
|
|
|
545
588
|
mlCodeTable[seqStorePtr->longLengthPos] = MaxML;
|
|
546
589
|
}
|
|
547
590
|
|
|
548
|
-
|
|
549
|
-
size_t ZSTD_compressSequences(ZSTD_CCtx* zc,
|
|
591
|
+
MEM_STATIC size_t ZSTD_compressSequences (ZSTD_CCtx* zc,
|
|
550
592
|
void* dst, size_t dstCapacity,
|
|
551
593
|
size_t srcSize)
|
|
552
594
|
{
|
|
595
|
+
const int longOffsets = zc->params.cParams.windowLog > STREAM_ACCUMULATOR_MIN;
|
|
553
596
|
const seqStore_t* seqStorePtr = &(zc->seqStore);
|
|
554
597
|
U32 count[MaxSeq+1];
|
|
555
598
|
S16 norm[MaxSeq+1];
|
|
@@ -566,6 +609,7 @@ size_t ZSTD_compressSequences(ZSTD_CCtx* zc,
|
|
|
566
609
|
BYTE* op = ostart;
|
|
567
610
|
size_t const nbSeq = seqStorePtr->sequences - seqStorePtr->sequencesStart;
|
|
568
611
|
BYTE* seqHead;
|
|
612
|
+
BYTE scratchBuffer[1<<MAX(MLFSELog,LLFSELog)];
|
|
569
613
|
|
|
570
614
|
/* Compress literals */
|
|
571
615
|
{ const BYTE* const literals = seqStorePtr->litStart;
|
|
@@ -593,7 +637,7 @@ size_t ZSTD_compressSequences(ZSTD_CCtx* zc,
|
|
|
593
637
|
|
|
594
638
|
/* CTable for Literal Lengths */
|
|
595
639
|
{ U32 max = MaxLL;
|
|
596
|
-
size_t const mostFrequent =
|
|
640
|
+
size_t const mostFrequent = FSE_countFast_wksp(count, &max, llCodeTable, nbSeq, zc->tmpCounters);
|
|
597
641
|
if ((mostFrequent == nbSeq) && (nbSeq > 2)) {
|
|
598
642
|
*op++ = llCodeTable[0];
|
|
599
643
|
FSE_buildCTable_rle(CTable_LitLength, (BYTE)max);
|
|
@@ -601,7 +645,7 @@ size_t ZSTD_compressSequences(ZSTD_CCtx* zc,
|
|
|
601
645
|
} else if ((zc->flagStaticTables) && (nbSeq < MAX_SEQ_FOR_STATIC_FSE)) {
|
|
602
646
|
LLtype = set_repeat;
|
|
603
647
|
} else if ((nbSeq < MIN_SEQ_FOR_DYNAMIC_FSE) || (mostFrequent < (nbSeq >> (LL_defaultNormLog-1)))) {
|
|
604
|
-
|
|
648
|
+
FSE_buildCTable_wksp(CTable_LitLength, LL_defaultNorm, MaxLL, LL_defaultNormLog, scratchBuffer, sizeof(scratchBuffer));
|
|
605
649
|
LLtype = set_basic;
|
|
606
650
|
} else {
|
|
607
651
|
size_t nbSeq_1 = nbSeq;
|
|
@@ -611,13 +655,13 @@ size_t ZSTD_compressSequences(ZSTD_CCtx* zc,
|
|
|
611
655
|
{ size_t const NCountSize = FSE_writeNCount(op, oend-op, norm, max, tableLog); /* overflow protected */
|
|
612
656
|
if (FSE_isError(NCountSize)) return ERROR(GENERIC);
|
|
613
657
|
op += NCountSize; }
|
|
614
|
-
|
|
658
|
+
FSE_buildCTable_wksp(CTable_LitLength, norm, max, tableLog, scratchBuffer, sizeof(scratchBuffer));
|
|
615
659
|
LLtype = set_compressed;
|
|
616
660
|
} }
|
|
617
661
|
|
|
618
662
|
/* CTable for Offsets */
|
|
619
663
|
{ U32 max = MaxOff;
|
|
620
|
-
size_t const mostFrequent =
|
|
664
|
+
size_t const mostFrequent = FSE_countFast_wksp(count, &max, ofCodeTable, nbSeq, zc->tmpCounters);
|
|
621
665
|
if ((mostFrequent == nbSeq) && (nbSeq > 2)) {
|
|
622
666
|
*op++ = ofCodeTable[0];
|
|
623
667
|
FSE_buildCTable_rle(CTable_OffsetBits, (BYTE)max);
|
|
@@ -625,7 +669,7 @@ size_t ZSTD_compressSequences(ZSTD_CCtx* zc,
|
|
|
625
669
|
} else if ((zc->flagStaticTables) && (nbSeq < MAX_SEQ_FOR_STATIC_FSE)) {
|
|
626
670
|
Offtype = set_repeat;
|
|
627
671
|
} else if ((nbSeq < MIN_SEQ_FOR_DYNAMIC_FSE) || (mostFrequent < (nbSeq >> (OF_defaultNormLog-1)))) {
|
|
628
|
-
|
|
672
|
+
FSE_buildCTable_wksp(CTable_OffsetBits, OF_defaultNorm, MaxOff, OF_defaultNormLog, scratchBuffer, sizeof(scratchBuffer));
|
|
629
673
|
Offtype = set_basic;
|
|
630
674
|
} else {
|
|
631
675
|
size_t nbSeq_1 = nbSeq;
|
|
@@ -635,13 +679,13 @@ size_t ZSTD_compressSequences(ZSTD_CCtx* zc,
|
|
|
635
679
|
{ size_t const NCountSize = FSE_writeNCount(op, oend-op, norm, max, tableLog); /* overflow protected */
|
|
636
680
|
if (FSE_isError(NCountSize)) return ERROR(GENERIC);
|
|
637
681
|
op += NCountSize; }
|
|
638
|
-
|
|
682
|
+
FSE_buildCTable_wksp(CTable_OffsetBits, norm, max, tableLog, scratchBuffer, sizeof(scratchBuffer));
|
|
639
683
|
Offtype = set_compressed;
|
|
640
684
|
} }
|
|
641
685
|
|
|
642
686
|
/* CTable for MatchLengths */
|
|
643
687
|
{ U32 max = MaxML;
|
|
644
|
-
size_t const mostFrequent =
|
|
688
|
+
size_t const mostFrequent = FSE_countFast_wksp(count, &max, mlCodeTable, nbSeq, zc->tmpCounters);
|
|
645
689
|
if ((mostFrequent == nbSeq) && (nbSeq > 2)) {
|
|
646
690
|
*op++ = *mlCodeTable;
|
|
647
691
|
FSE_buildCTable_rle(CTable_MatchLength, (BYTE)max);
|
|
@@ -649,7 +693,7 @@ size_t ZSTD_compressSequences(ZSTD_CCtx* zc,
|
|
|
649
693
|
} else if ((zc->flagStaticTables) && (nbSeq < MAX_SEQ_FOR_STATIC_FSE)) {
|
|
650
694
|
MLtype = set_repeat;
|
|
651
695
|
} else if ((nbSeq < MIN_SEQ_FOR_DYNAMIC_FSE) || (mostFrequent < (nbSeq >> (ML_defaultNormLog-1)))) {
|
|
652
|
-
|
|
696
|
+
FSE_buildCTable_wksp(CTable_MatchLength, ML_defaultNorm, MaxML, ML_defaultNormLog, scratchBuffer, sizeof(scratchBuffer));
|
|
653
697
|
MLtype = set_basic;
|
|
654
698
|
} else {
|
|
655
699
|
size_t nbSeq_1 = nbSeq;
|
|
@@ -659,7 +703,7 @@ size_t ZSTD_compressSequences(ZSTD_CCtx* zc,
|
|
|
659
703
|
{ size_t const NCountSize = FSE_writeNCount(op, oend-op, norm, max, tableLog); /* overflow protected */
|
|
660
704
|
if (FSE_isError(NCountSize)) return ERROR(GENERIC);
|
|
661
705
|
op += NCountSize; }
|
|
662
|
-
|
|
706
|
+
FSE_buildCTable_wksp(CTable_MatchLength, norm, max, tableLog, scratchBuffer, sizeof(scratchBuffer));
|
|
663
707
|
MLtype = set_compressed;
|
|
664
708
|
} }
|
|
665
709
|
|
|
@@ -682,7 +726,18 @@ size_t ZSTD_compressSequences(ZSTD_CCtx* zc,
|
|
|
682
726
|
if (MEM_32bits()) BIT_flushBits(&blockStream);
|
|
683
727
|
BIT_addBits(&blockStream, sequences[nbSeq-1].matchLength, ML_bits[mlCodeTable[nbSeq-1]]);
|
|
684
728
|
if (MEM_32bits()) BIT_flushBits(&blockStream);
|
|
685
|
-
|
|
729
|
+
if (longOffsets) {
|
|
730
|
+
U32 const ofBits = ofCodeTable[nbSeq-1];
|
|
731
|
+
int const extraBits = ofBits - MIN(ofBits, STREAM_ACCUMULATOR_MIN-1);
|
|
732
|
+
if (extraBits) {
|
|
733
|
+
BIT_addBits(&blockStream, sequences[nbSeq-1].offset, extraBits);
|
|
734
|
+
BIT_flushBits(&blockStream);
|
|
735
|
+
}
|
|
736
|
+
BIT_addBits(&blockStream, sequences[nbSeq-1].offset >> extraBits,
|
|
737
|
+
ofBits - extraBits);
|
|
738
|
+
} else {
|
|
739
|
+
BIT_addBits(&blockStream, sequences[nbSeq-1].offset, ofCodeTable[nbSeq-1]);
|
|
740
|
+
}
|
|
686
741
|
BIT_flushBits(&blockStream);
|
|
687
742
|
|
|
688
743
|
{ size_t n;
|
|
@@ -704,7 +759,17 @@ size_t ZSTD_compressSequences(ZSTD_CCtx* zc,
|
|
|
704
759
|
if (MEM_32bits() && ((llBits+mlBits)>24)) BIT_flushBits(&blockStream);
|
|
705
760
|
BIT_addBits(&blockStream, sequences[n].matchLength, mlBits);
|
|
706
761
|
if (MEM_32bits()) BIT_flushBits(&blockStream); /* (7)*/
|
|
707
|
-
|
|
762
|
+
if (longOffsets) {
|
|
763
|
+
int const extraBits = ofBits - MIN(ofBits, STREAM_ACCUMULATOR_MIN-1);
|
|
764
|
+
if (extraBits) {
|
|
765
|
+
BIT_addBits(&blockStream, sequences[n].offset, extraBits);
|
|
766
|
+
BIT_flushBits(&blockStream); /* (7)*/
|
|
767
|
+
}
|
|
768
|
+
BIT_addBits(&blockStream, sequences[n].offset >> extraBits,
|
|
769
|
+
ofBits - extraBits); /* 31 */
|
|
770
|
+
} else {
|
|
771
|
+
BIT_addBits(&blockStream, sequences[n].offset, ofBits); /* 31 */
|
|
772
|
+
}
|
|
708
773
|
BIT_flushBits(&blockStream); /* (7)*/
|
|
709
774
|
} }
|
|
710
775
|
|
|
@@ -719,16 +784,25 @@ size_t ZSTD_compressSequences(ZSTD_CCtx* zc,
|
|
|
719
784
|
|
|
720
785
|
/* check compressibility */
|
|
721
786
|
_check_compressibility:
|
|
722
|
-
{
|
|
723
|
-
|
|
724
|
-
|
|
787
|
+
{ size_t const minGain = ZSTD_minGain(srcSize);
|
|
788
|
+
size_t const maxCSize = srcSize - minGain;
|
|
789
|
+
if ((size_t)(op-ostart) >= maxCSize) {
|
|
790
|
+
zc->flagStaticHufTable = HUF_repeat_none;
|
|
791
|
+
return 0;
|
|
792
|
+
} }
|
|
725
793
|
|
|
726
794
|
/* confirm repcodes */
|
|
727
|
-
{ int i; for (i=0; i<ZSTD_REP_NUM; i++) zc->rep[i] = zc->
|
|
795
|
+
{ int i; for (i=0; i<ZSTD_REP_NUM; i++) zc->rep[i] = zc->repToConfirm[i]; }
|
|
728
796
|
|
|
729
797
|
return op - ostart;
|
|
730
798
|
}
|
|
731
799
|
|
|
800
|
+
#if 0 /* for debug */
|
|
801
|
+
# define STORESEQ_DEBUG
|
|
802
|
+
#include <stdio.h> /* fprintf */
|
|
803
|
+
U32 g_startDebug = 0;
|
|
804
|
+
const BYTE* g_start = NULL;
|
|
805
|
+
#endif
|
|
732
806
|
|
|
733
807
|
/*! ZSTD_storeSeq() :
|
|
734
808
|
Store a sequence (literal length, literals, offset code and match length code) into seqStore_t.
|
|
@@ -737,13 +811,14 @@ _check_compressibility:
|
|
|
737
811
|
*/
|
|
738
812
|
MEM_STATIC void ZSTD_storeSeq(seqStore_t* seqStorePtr, size_t litLength, const void* literals, U32 offsetCode, size_t matchCode)
|
|
739
813
|
{
|
|
740
|
-
#
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
814
|
+
#ifdef STORESEQ_DEBUG
|
|
815
|
+
if (g_startDebug) {
|
|
816
|
+
const U32 pos = (U32)((const BYTE*)literals - g_start);
|
|
817
|
+
if (g_start==NULL) g_start = (const BYTE*)literals;
|
|
818
|
+
if ((pos > 1895000) && (pos < 1895300))
|
|
819
|
+
fprintf(stderr, "Cpos %6u :%5u literals & match %3u bytes at distance %6u \n",
|
|
820
|
+
pos, (U32)litLength, (U32)matchCode+MINMATCH, (U32)offsetCode);
|
|
821
|
+
}
|
|
747
822
|
#endif
|
|
748
823
|
/* copy Literals */
|
|
749
824
|
ZSTD_wildcopy(seqStorePtr->lit, literals, litLength);
|
|
@@ -993,8 +1068,8 @@ void ZSTD_compressBlock_fast_generic(ZSTD_CCtx* cctx,
|
|
|
993
1068
|
} } }
|
|
994
1069
|
|
|
995
1070
|
/* save reps for next block */
|
|
996
|
-
cctx->
|
|
997
|
-
cctx->
|
|
1071
|
+
cctx->repToConfirm[0] = offset_1 ? offset_1 : offsetSaved;
|
|
1072
|
+
cctx->repToConfirm[1] = offset_2 ? offset_2 : offsetSaved;
|
|
998
1073
|
|
|
999
1074
|
/* Last Literals */
|
|
1000
1075
|
{ size_t const lastLLSize = iend - anchor;
|
|
@@ -1108,7 +1183,7 @@ static void ZSTD_compressBlock_fast_extDict_generic(ZSTD_CCtx* ctx,
|
|
|
1108
1183
|
} } }
|
|
1109
1184
|
|
|
1110
1185
|
/* save reps for next block */
|
|
1111
|
-
ctx->
|
|
1186
|
+
ctx->repToConfirm[0] = offset_1; ctx->repToConfirm[1] = offset_2;
|
|
1112
1187
|
|
|
1113
1188
|
/* Last Literals */
|
|
1114
1189
|
{ size_t const lastLLSize = iend - anchor;
|
|
@@ -1262,8 +1337,8 @@ void ZSTD_compressBlock_doubleFast_generic(ZSTD_CCtx* cctx,
|
|
|
1262
1337
|
} } }
|
|
1263
1338
|
|
|
1264
1339
|
/* save reps for next block */
|
|
1265
|
-
cctx->
|
|
1266
|
-
cctx->
|
|
1340
|
+
cctx->repToConfirm[0] = offset_1 ? offset_1 : offsetSaved;
|
|
1341
|
+
cctx->repToConfirm[1] = offset_2 ? offset_2 : offsetSaved;
|
|
1267
1342
|
|
|
1268
1343
|
/* Last Literals */
|
|
1269
1344
|
{ size_t const lastLLSize = iend - anchor;
|
|
@@ -1412,7 +1487,7 @@ static void ZSTD_compressBlock_doubleFast_extDict_generic(ZSTD_CCtx* ctx,
|
|
|
1412
1487
|
} } }
|
|
1413
1488
|
|
|
1414
1489
|
/* save reps for next block */
|
|
1415
|
-
ctx->
|
|
1490
|
+
ctx->repToConfirm[0] = offset_1; ctx->repToConfirm[1] = offset_2;
|
|
1416
1491
|
|
|
1417
1492
|
/* Last Literals */
|
|
1418
1493
|
{ size_t const lastLLSize = iend - anchor;
|
|
@@ -1482,8 +1557,9 @@ static U32 ZSTD_insertBt1(ZSTD_CCtx* zc, const BYTE* const ip, const U32 mls, co
|
|
|
1482
1557
|
hashTable[h] = current; /* Update Hash Table */
|
|
1483
1558
|
|
|
1484
1559
|
while (nbCompares-- && (matchIndex > windowLow)) {
|
|
1485
|
-
U32* nextPtr = bt + 2*(matchIndex & btMask);
|
|
1560
|
+
U32* const nextPtr = bt + 2*(matchIndex & btMask);
|
|
1486
1561
|
size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */
|
|
1562
|
+
|
|
1487
1563
|
#ifdef ZSTD_C_PREDICT /* note : can create issues when hlog small <= 11 */
|
|
1488
1564
|
const U32* predictPtr = bt + 2*((matchIndex-1) & btMask); /* written this way, as bt is a roll buffer */
|
|
1489
1565
|
if (matchIndex == predictedSmall) {
|
|
@@ -1579,7 +1655,7 @@ static size_t ZSTD_insertBtAndFindBestMatch (
|
|
|
1579
1655
|
hashTable[h] = current; /* Update Hash Table */
|
|
1580
1656
|
|
|
1581
1657
|
while (nbCompares-- && (matchIndex > windowLow)) {
|
|
1582
|
-
U32* nextPtr = bt + 2*(matchIndex & btMask);
|
|
1658
|
+
U32* const nextPtr = bt + 2*(matchIndex & btMask);
|
|
1583
1659
|
size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */
|
|
1584
1660
|
const BYTE* match;
|
|
1585
1661
|
|
|
@@ -1711,7 +1787,7 @@ static size_t ZSTD_BtFindBestMatch_selectMLS_extDict (
|
|
|
1711
1787
|
#define NEXT_IN_CHAIN(d, mask) chainTable[(d) & mask]
|
|
1712
1788
|
|
|
1713
1789
|
/* Update chains up to ip (excluded)
|
|
1714
|
-
Assumption : always within prefix (
|
|
1790
|
+
Assumption : always within prefix (i.e. not within extDict) */
|
|
1715
1791
|
FORCE_INLINE
|
|
1716
1792
|
U32 ZSTD_insertAndFindFirstIndex (ZSTD_CCtx* zc, const BYTE* ip, U32 mls)
|
|
1717
1793
|
{
|
|
@@ -1943,8 +2019,8 @@ _storeSequence:
|
|
|
1943
2019
|
} }
|
|
1944
2020
|
|
|
1945
2021
|
/* Save reps for next block */
|
|
1946
|
-
ctx->
|
|
1947
|
-
ctx->
|
|
2022
|
+
ctx->repToConfirm[0] = offset_1 ? offset_1 : savedOffset;
|
|
2023
|
+
ctx->repToConfirm[1] = offset_2 ? offset_2 : savedOffset;
|
|
1948
2024
|
|
|
1949
2025
|
/* Last Literals */
|
|
1950
2026
|
{ size_t const lastLLSize = iend - anchor;
|
|
@@ -2138,7 +2214,7 @@ _storeSequence:
|
|
|
2138
2214
|
} }
|
|
2139
2215
|
|
|
2140
2216
|
/* Save reps for next block */
|
|
2141
|
-
ctx->
|
|
2217
|
+
ctx->repToConfirm[0] = offset_1; ctx->repToConfirm[1] = offset_2;
|
|
2142
2218
|
|
|
2143
2219
|
/* Last Literals */
|
|
2144
2220
|
{ size_t const lastLLSize = iend - anchor;
|
|
@@ -2271,16 +2347,16 @@ static size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
|
|
|
2271
2347
|
if (remaining < blockSize) blockSize = remaining;
|
|
2272
2348
|
|
|
2273
2349
|
/* preemptive overflow correction */
|
|
2274
|
-
if (cctx->lowLimit > (
|
|
2275
|
-
U32 const
|
|
2276
|
-
U32 const
|
|
2277
|
-
U32 const
|
|
2278
|
-
U32 const
|
|
2279
|
-
|
|
2350
|
+
if (cctx->lowLimit > (3U<<29)) {
|
|
2351
|
+
U32 const cycleMask = (1 << ZSTD_cycleLog(cctx->params.cParams.hashLog, cctx->params.cParams.strategy)) - 1;
|
|
2352
|
+
U32 const current = (U32)(ip - cctx->base);
|
|
2353
|
+
U32 const newCurrent = (current & cycleMask) + (1 << cctx->params.cParams.windowLog);
|
|
2354
|
+
U32 const correction = current - newCurrent;
|
|
2355
|
+
ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX_64 <= 30);
|
|
2280
2356
|
ZSTD_reduceIndex(cctx, correction);
|
|
2281
2357
|
cctx->base += correction;
|
|
2282
2358
|
cctx->dictBase += correction;
|
|
2283
|
-
cctx->lowLimit
|
|
2359
|
+
cctx->lowLimit -= correction;
|
|
2284
2360
|
cctx->dictLimit -= correction;
|
|
2285
2361
|
if (cctx->nextToUpdate < correction) cctx->nextToUpdate = 0;
|
|
2286
2362
|
else cctx->nextToUpdate -= correction;
|
|
@@ -2325,7 +2401,7 @@ static size_t ZSTD_writeFrameHeader(void* dst, size_t dstCapacity,
|
|
|
2325
2401
|
U32 const dictIDSizeCode = (dictID>0) + (dictID>=256) + (dictID>=65536); /* 0-3 */
|
|
2326
2402
|
U32 const checksumFlag = params.fParams.checksumFlag>0;
|
|
2327
2403
|
U32 const windowSize = 1U << params.cParams.windowLog;
|
|
2328
|
-
U32 const singleSegment = params.fParams.contentSizeFlag && (windowSize
|
|
2404
|
+
U32 const singleSegment = params.fParams.contentSizeFlag && (windowSize >= pledgedSrcSize);
|
|
2329
2405
|
BYTE const windowLogByte = (BYTE)((params.cParams.windowLog - ZSTD_WINDOWLOG_ABSOLUTEMIN) << 3);
|
|
2330
2406
|
U32 const fcsCode = params.fParams.contentSizeFlag ?
|
|
2331
2407
|
(pledgedSrcSize>=256) + (pledgedSrcSize>=65536+256) + (pledgedSrcSize>=0xFFFFFFFFU) : /* 0-3 */
|
|
@@ -2397,12 +2473,14 @@ static size_t ZSTD_compressContinue_internal (ZSTD_CCtx* cctx,
|
|
|
2397
2473
|
|
|
2398
2474
|
cctx->nextSrc = ip + srcSize;
|
|
2399
2475
|
|
|
2400
|
-
|
|
2476
|
+
if (srcSize) {
|
|
2477
|
+
size_t const cSize = frame ?
|
|
2401
2478
|
ZSTD_compress_generic (cctx, dst, dstCapacity, src, srcSize, lastFrameChunk) :
|
|
2402
2479
|
ZSTD_compressBlock_internal (cctx, dst, dstCapacity, src, srcSize);
|
|
2403
2480
|
if (ZSTD_isError(cSize)) return cSize;
|
|
2404
2481
|
return cSize + fhSize;
|
|
2405
|
-
}
|
|
2482
|
+
} else
|
|
2483
|
+
return fhSize;
|
|
2406
2484
|
}
|
|
2407
2485
|
|
|
2408
2486
|
|
|
@@ -2438,7 +2516,7 @@ static size_t ZSTD_loadDictionaryContent(ZSTD_CCtx* zc, const void* src, size_t
|
|
|
2438
2516
|
zc->dictBase = zc->base;
|
|
2439
2517
|
zc->base += ip - zc->nextSrc;
|
|
2440
2518
|
zc->nextToUpdate = zc->dictLimit;
|
|
2441
|
-
zc->loadedDictEnd = (U32)(iend - zc->base);
|
|
2519
|
+
zc->loadedDictEnd = zc->forceWindow ? 0 : (U32)(iend - zc->base);
|
|
2442
2520
|
|
|
2443
2521
|
zc->nextSrc = iend;
|
|
2444
2522
|
if (srcSize <= HASH_READ_SIZE) return 0;
|
|
@@ -2469,7 +2547,7 @@ static size_t ZSTD_loadDictionaryContent(ZSTD_CCtx* zc, const void* src, size_t
|
|
|
2469
2547
|
return ERROR(GENERIC); /* strategy doesn't exist; impossible */
|
|
2470
2548
|
}
|
|
2471
2549
|
|
|
2472
|
-
zc->nextToUpdate = zc->
|
|
2550
|
+
zc->nextToUpdate = (U32)(iend - zc->base);
|
|
2473
2551
|
return 0;
|
|
2474
2552
|
}
|
|
2475
2553
|
|
|
@@ -2506,6 +2584,7 @@ static size_t ZSTD_loadDictEntropyStats(ZSTD_CCtx* cctx, const void* dict, size_
|
|
|
2506
2584
|
const BYTE* const dictEnd = dictPtr + dictSize;
|
|
2507
2585
|
short offcodeNCount[MaxOff+1];
|
|
2508
2586
|
unsigned offcodeMaxValue = MaxOff;
|
|
2587
|
+
BYTE scratchBuffer[1<<MAX(MLFSELog,LLFSELog)];
|
|
2509
2588
|
|
|
2510
2589
|
{ size_t const hufHeaderSize = HUF_readCTable(cctx->hufTable, 255, dict, dictSize);
|
|
2511
2590
|
if (HUF_isError(hufHeaderSize)) return ERROR(dictionary_corrupted);
|
|
@@ -2517,7 +2596,7 @@ static size_t ZSTD_loadDictEntropyStats(ZSTD_CCtx* cctx, const void* dict, size_
|
|
|
2517
2596
|
if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted);
|
|
2518
2597
|
if (offcodeLog > OffFSELog) return ERROR(dictionary_corrupted);
|
|
2519
2598
|
/* Defer checking offcodeMaxValue because we need to know the size of the dictionary content */
|
|
2520
|
-
CHECK_E (
|
|
2599
|
+
CHECK_E (FSE_buildCTable_wksp(cctx->offcodeCTable, offcodeNCount, offcodeMaxValue, offcodeLog, scratchBuffer, sizeof(scratchBuffer)), dictionary_corrupted);
|
|
2521
2600
|
dictPtr += offcodeHeaderSize;
|
|
2522
2601
|
}
|
|
2523
2602
|
|
|
@@ -2528,7 +2607,7 @@ static size_t ZSTD_loadDictEntropyStats(ZSTD_CCtx* cctx, const void* dict, size_
|
|
|
2528
2607
|
if (matchlengthLog > MLFSELog) return ERROR(dictionary_corrupted);
|
|
2529
2608
|
/* Every match length code must have non-zero probability */
|
|
2530
2609
|
CHECK_F (ZSTD_checkDictNCount(matchlengthNCount, matchlengthMaxValue, MaxML));
|
|
2531
|
-
CHECK_E (
|
|
2610
|
+
CHECK_E (FSE_buildCTable_wksp(cctx->matchlengthCTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog, scratchBuffer, sizeof(scratchBuffer)), dictionary_corrupted);
|
|
2532
2611
|
dictPtr += matchlengthHeaderSize;
|
|
2533
2612
|
}
|
|
2534
2613
|
|
|
@@ -2539,14 +2618,14 @@ static size_t ZSTD_loadDictEntropyStats(ZSTD_CCtx* cctx, const void* dict, size_
|
|
|
2539
2618
|
if (litlengthLog > LLFSELog) return ERROR(dictionary_corrupted);
|
|
2540
2619
|
/* Every literal length code must have non-zero probability */
|
|
2541
2620
|
CHECK_F (ZSTD_checkDictNCount(litlengthNCount, litlengthMaxValue, MaxLL));
|
|
2542
|
-
CHECK_E(
|
|
2621
|
+
CHECK_E(FSE_buildCTable_wksp(cctx->litlengthCTable, litlengthNCount, litlengthMaxValue, litlengthLog, scratchBuffer, sizeof(scratchBuffer)), dictionary_corrupted);
|
|
2543
2622
|
dictPtr += litlengthHeaderSize;
|
|
2544
2623
|
}
|
|
2545
2624
|
|
|
2546
2625
|
if (dictPtr+12 > dictEnd) return ERROR(dictionary_corrupted);
|
|
2547
|
-
cctx->rep[0] = MEM_readLE32(dictPtr+0); if (cctx->rep[0] >= dictSize) return ERROR(dictionary_corrupted);
|
|
2548
|
-
cctx->rep[1] = MEM_readLE32(dictPtr+4); if (cctx->rep[1] >= dictSize) return ERROR(dictionary_corrupted);
|
|
2549
|
-
cctx->rep[2] = MEM_readLE32(dictPtr+8); if (cctx->rep[2] >= dictSize) return ERROR(dictionary_corrupted);
|
|
2626
|
+
cctx->rep[0] = MEM_readLE32(dictPtr+0); if (cctx->rep[0] == 0 || cctx->rep[0] >= dictSize) return ERROR(dictionary_corrupted);
|
|
2627
|
+
cctx->rep[1] = MEM_readLE32(dictPtr+4); if (cctx->rep[1] == 0 || cctx->rep[1] >= dictSize) return ERROR(dictionary_corrupted);
|
|
2628
|
+
cctx->rep[2] = MEM_readLE32(dictPtr+8); if (cctx->rep[2] == 0 || cctx->rep[2] >= dictSize) return ERROR(dictionary_corrupted);
|
|
2550
2629
|
dictPtr += 12;
|
|
2551
2630
|
|
|
2552
2631
|
{ U32 offcodeMax = MaxOff;
|
|
@@ -2560,6 +2639,7 @@ static size_t ZSTD_loadDictEntropyStats(ZSTD_CCtx* cctx, const void* dict, size_
|
|
|
2560
2639
|
}
|
|
2561
2640
|
|
|
2562
2641
|
cctx->flagStaticTables = 1;
|
|
2642
|
+
cctx->flagStaticHufTable = HUF_repeat_valid;
|
|
2563
2643
|
return dictPtr - (const BYTE*)dict;
|
|
2564
2644
|
}
|
|
2565
2645
|
|
|
@@ -2569,8 +2649,9 @@ static size_t ZSTD_compress_insertDictionary(ZSTD_CCtx* zc, const void* dict, si
|
|
|
2569
2649
|
{
|
|
2570
2650
|
if ((dict==NULL) || (dictSize<=8)) return 0;
|
|
2571
2651
|
|
|
2572
|
-
/*
|
|
2573
|
-
if (MEM_readLE32(dict) != ZSTD_DICT_MAGIC)
|
|
2652
|
+
/* dict as pure content */
|
|
2653
|
+
if ((MEM_readLE32(dict) != ZSTD_DICT_MAGIC) || (zc->forceRawDict))
|
|
2654
|
+
return ZSTD_loadDictionaryContent(zc, dict, dictSize);
|
|
2574
2655
|
zc->dictID = zc->params.fParams.noDictIDFlag ? 0 : MEM_readLE32((const char*)dict+4);
|
|
2575
2656
|
|
|
2576
2657
|
/* known magic number : dict is parsed for entropy stats and content */
|
|
@@ -2581,7 +2662,6 @@ static size_t ZSTD_compress_insertDictionary(ZSTD_CCtx* zc, const void* dict, si
|
|
|
2581
2662
|
}
|
|
2582
2663
|
}
|
|
2583
2664
|
|
|
2584
|
-
|
|
2585
2665
|
/*! ZSTD_compressBegin_internal() :
|
|
2586
2666
|
* @return : 0, or an error code */
|
|
2587
2667
|
static size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx,
|
|
@@ -2613,9 +2693,9 @@ size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t di
|
|
|
2613
2693
|
}
|
|
2614
2694
|
|
|
2615
2695
|
|
|
2616
|
-
size_t ZSTD_compressBegin(ZSTD_CCtx*
|
|
2696
|
+
size_t ZSTD_compressBegin(ZSTD_CCtx* cctx, int compressionLevel)
|
|
2617
2697
|
{
|
|
2618
|
-
return ZSTD_compressBegin_usingDict(
|
|
2698
|
+
return ZSTD_compressBegin_usingDict(cctx, NULL, 0, compressionLevel);
|
|
2619
2699
|
}
|
|
2620
2700
|
|
|
2621
2701
|
|
|
@@ -2695,7 +2775,7 @@ size_t ZSTD_compress_advanced (ZSTD_CCtx* ctx,
|
|
|
2695
2775
|
|
|
2696
2776
|
size_t ZSTD_compress_usingDict(ZSTD_CCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize, const void* dict, size_t dictSize, int compressionLevel)
|
|
2697
2777
|
{
|
|
2698
|
-
ZSTD_parameters params = ZSTD_getParams(compressionLevel, srcSize, dictSize);
|
|
2778
|
+
ZSTD_parameters params = ZSTD_getParams(compressionLevel, srcSize, dict ? dictSize : 0);
|
|
2699
2779
|
params.fParams.contentSizeFlag = 1;
|
|
2700
2780
|
return ZSTD_compress_internal(ctx, dst, dstCapacity, src, srcSize, dict, dictSize, params);
|
|
2701
2781
|
}
|
|
@@ -2720,7 +2800,8 @@ size_t ZSTD_compress(void* dst, size_t dstCapacity, const void* src, size_t srcS
|
|
|
2720
2800
|
/* ===== Dictionary API ===== */
|
|
2721
2801
|
|
|
2722
2802
|
struct ZSTD_CDict_s {
|
|
2723
|
-
void*
|
|
2803
|
+
void* dictBuffer;
|
|
2804
|
+
const void* dictContent;
|
|
2724
2805
|
size_t dictContentSize;
|
|
2725
2806
|
ZSTD_CCtx* refContext;
|
|
2726
2807
|
}; /* typedef'd tp ZSTD_CDict within "zstd.h" */
|
|
@@ -2728,39 +2809,45 @@ struct ZSTD_CDict_s {
|
|
|
2728
2809
|
size_t ZSTD_sizeof_CDict(const ZSTD_CDict* cdict)
|
|
2729
2810
|
{
|
|
2730
2811
|
if (cdict==NULL) return 0; /* support sizeof on NULL */
|
|
2731
|
-
return ZSTD_sizeof_CCtx(cdict->refContext) + cdict->dictContentSize;
|
|
2812
|
+
return ZSTD_sizeof_CCtx(cdict->refContext) + (cdict->dictBuffer ? cdict->dictContentSize : 0) + sizeof(*cdict);
|
|
2732
2813
|
}
|
|
2733
2814
|
|
|
2734
|
-
ZSTD_CDict* ZSTD_createCDict_advanced(const void*
|
|
2815
|
+
ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize, unsigned byReference,
|
|
2816
|
+
ZSTD_parameters params, ZSTD_customMem customMem)
|
|
2735
2817
|
{
|
|
2736
2818
|
if (!customMem.customAlloc && !customMem.customFree) customMem = defaultCustomMem;
|
|
2737
2819
|
if (!customMem.customAlloc || !customMem.customFree) return NULL;
|
|
2738
2820
|
|
|
2739
2821
|
{ ZSTD_CDict* const cdict = (ZSTD_CDict*) ZSTD_malloc(sizeof(ZSTD_CDict), customMem);
|
|
2740
|
-
void* const dictContent = ZSTD_malloc(dictSize, customMem);
|
|
2741
2822
|
ZSTD_CCtx* const cctx = ZSTD_createCCtx_advanced(customMem);
|
|
2742
2823
|
|
|
2743
|
-
if (!
|
|
2744
|
-
ZSTD_free(dictContent, customMem);
|
|
2824
|
+
if (!cdict || !cctx) {
|
|
2745
2825
|
ZSTD_free(cdict, customMem);
|
|
2746
|
-
|
|
2826
|
+
ZSTD_freeCCtx(cctx);
|
|
2747
2827
|
return NULL;
|
|
2748
2828
|
}
|
|
2749
2829
|
|
|
2750
|
-
if (dictSize) {
|
|
2751
|
-
|
|
2830
|
+
if ((byReference) || (!dictBuffer) || (!dictSize)) {
|
|
2831
|
+
cdict->dictBuffer = NULL;
|
|
2832
|
+
cdict->dictContent = dictBuffer;
|
|
2833
|
+
} else {
|
|
2834
|
+
void* const internalBuffer = ZSTD_malloc(dictSize, customMem);
|
|
2835
|
+
if (!internalBuffer) { ZSTD_free(cctx, customMem); ZSTD_free(cdict, customMem); return NULL; }
|
|
2836
|
+
memcpy(internalBuffer, dictBuffer, dictSize);
|
|
2837
|
+
cdict->dictBuffer = internalBuffer;
|
|
2838
|
+
cdict->dictContent = internalBuffer;
|
|
2752
2839
|
}
|
|
2753
|
-
|
|
2840
|
+
|
|
2841
|
+
{ size_t const errorCode = ZSTD_compressBegin_advanced(cctx, cdict->dictContent, dictSize, params, 0);
|
|
2754
2842
|
if (ZSTD_isError(errorCode)) {
|
|
2755
|
-
ZSTD_free(
|
|
2843
|
+
ZSTD_free(cdict->dictBuffer, customMem);
|
|
2756
2844
|
ZSTD_free(cdict, customMem);
|
|
2757
|
-
|
|
2845
|
+
ZSTD_freeCCtx(cctx);
|
|
2758
2846
|
return NULL;
|
|
2759
2847
|
} }
|
|
2760
2848
|
|
|
2761
|
-
cdict->dictContent = dictContent;
|
|
2762
|
-
cdict->dictContentSize = dictSize;
|
|
2763
2849
|
cdict->refContext = cctx;
|
|
2850
|
+
cdict->dictContentSize = dictSize;
|
|
2764
2851
|
return cdict;
|
|
2765
2852
|
}
|
|
2766
2853
|
}
|
|
@@ -2770,7 +2857,15 @@ ZSTD_CDict* ZSTD_createCDict(const void* dict, size_t dictSize, int compressionL
|
|
|
2770
2857
|
ZSTD_customMem const allocator = { NULL, NULL, NULL };
|
|
2771
2858
|
ZSTD_parameters params = ZSTD_getParams(compressionLevel, 0, dictSize);
|
|
2772
2859
|
params.fParams.contentSizeFlag = 1;
|
|
2773
|
-
return ZSTD_createCDict_advanced(dict, dictSize, params, allocator);
|
|
2860
|
+
return ZSTD_createCDict_advanced(dict, dictSize, 0, params, allocator);
|
|
2861
|
+
}
|
|
2862
|
+
|
|
2863
|
+
ZSTD_CDict* ZSTD_createCDict_byReference(const void* dict, size_t dictSize, int compressionLevel)
|
|
2864
|
+
{
|
|
2865
|
+
ZSTD_customMem const allocator = { NULL, NULL, NULL };
|
|
2866
|
+
ZSTD_parameters params = ZSTD_getParams(compressionLevel, 0, dictSize);
|
|
2867
|
+
params.fParams.contentSizeFlag = 1;
|
|
2868
|
+
return ZSTD_createCDict_advanced(dict, dictSize, 1, params, allocator);
|
|
2774
2869
|
}
|
|
2775
2870
|
|
|
2776
2871
|
size_t ZSTD_freeCDict(ZSTD_CDict* cdict)
|
|
@@ -2778,7 +2873,7 @@ size_t ZSTD_freeCDict(ZSTD_CDict* cdict)
|
|
|
2778
2873
|
if (cdict==NULL) return 0; /* support free on NULL */
|
|
2779
2874
|
{ ZSTD_customMem const cMem = cdict->refContext->customMem;
|
|
2780
2875
|
ZSTD_freeCCtx(cdict->refContext);
|
|
2781
|
-
ZSTD_free(cdict->
|
|
2876
|
+
ZSTD_free(cdict->dictBuffer, cMem);
|
|
2782
2877
|
ZSTD_free(cdict, cMem);
|
|
2783
2878
|
return 0;
|
|
2784
2879
|
}
|
|
@@ -2788,10 +2883,14 @@ static ZSTD_parameters ZSTD_getParamsFromCDict(const ZSTD_CDict* cdict) {
|
|
|
2788
2883
|
return ZSTD_getParamsFromCCtx(cdict->refContext);
|
|
2789
2884
|
}
|
|
2790
2885
|
|
|
2791
|
-
size_t ZSTD_compressBegin_usingCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict,
|
|
2886
|
+
size_t ZSTD_compressBegin_usingCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict, unsigned long long pledgedSrcSize)
|
|
2792
2887
|
{
|
|
2793
2888
|
if (cdict->dictContentSize) CHECK_F(ZSTD_copyCCtx(cctx, cdict->refContext, pledgedSrcSize))
|
|
2794
|
-
else
|
|
2889
|
+
else {
|
|
2890
|
+
ZSTD_parameters params = cdict->refContext->params;
|
|
2891
|
+
params.fParams.contentSizeFlag = (pledgedSrcSize > 0);
|
|
2892
|
+
CHECK_F(ZSTD_compressBegin_advanced(cctx, NULL, 0, params, pledgedSrcSize));
|
|
2893
|
+
}
|
|
2795
2894
|
return 0;
|
|
2796
2895
|
}
|
|
2797
2896
|
|
|
@@ -2839,6 +2938,8 @@ struct ZSTD_CStream_s {
|
|
|
2839
2938
|
ZSTD_cStreamStage stage;
|
|
2840
2939
|
U32 checksum;
|
|
2841
2940
|
U32 frameEnded;
|
|
2941
|
+
U64 pledgedSrcSize;
|
|
2942
|
+
U64 inputProcessed;
|
|
2842
2943
|
ZSTD_parameters params;
|
|
2843
2944
|
ZSTD_customMem customMem;
|
|
2844
2945
|
}; /* typedef'd to ZSTD_CStream within "zstd.h" */
|
|
@@ -2883,9 +2984,9 @@ size_t ZSTD_freeCStream(ZSTD_CStream* zcs)
|
|
|
2883
2984
|
size_t ZSTD_CStreamInSize(void) { return ZSTD_BLOCKSIZE_ABSOLUTEMAX; }
|
|
2884
2985
|
size_t ZSTD_CStreamOutSize(void) { return ZSTD_compressBound(ZSTD_BLOCKSIZE_ABSOLUTEMAX) + ZSTD_blockHeaderSize + 4 /* 32-bits hash */ ; }
|
|
2885
2986
|
|
|
2886
|
-
size_t
|
|
2987
|
+
static size_t ZSTD_resetCStream_internal(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize)
|
|
2887
2988
|
{
|
|
2888
|
-
if (zcs->inBuffSize==0) return ERROR(stage_wrong); /* zcs has not been init at least once */
|
|
2989
|
+
if (zcs->inBuffSize==0) return ERROR(stage_wrong); /* zcs has not been init at least once => can't reset */
|
|
2889
2990
|
|
|
2890
2991
|
if (zcs->cdict) CHECK_F(ZSTD_compressBegin_usingCDict(zcs->cctx, zcs->cdict, pledgedSrcSize))
|
|
2891
2992
|
else CHECK_F(ZSTD_compressBegin_advanced(zcs->cctx, NULL, 0, zcs->params, pledgedSrcSize));
|
|
@@ -2896,9 +2997,19 @@ size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize)
|
|
|
2896
2997
|
zcs->outBuffContentSize = zcs->outBuffFlushedSize = 0;
|
|
2897
2998
|
zcs->stage = zcss_load;
|
|
2898
2999
|
zcs->frameEnded = 0;
|
|
3000
|
+
zcs->pledgedSrcSize = pledgedSrcSize;
|
|
3001
|
+
zcs->inputProcessed = 0;
|
|
2899
3002
|
return 0; /* ready to go */
|
|
2900
3003
|
}
|
|
2901
3004
|
|
|
3005
|
+
size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize)
|
|
3006
|
+
{
|
|
3007
|
+
|
|
3008
|
+
zcs->params.fParams.contentSizeFlag = (pledgedSrcSize > 0);
|
|
3009
|
+
|
|
3010
|
+
return ZSTD_resetCStream_internal(zcs, pledgedSrcSize);
|
|
3011
|
+
}
|
|
3012
|
+
|
|
2902
3013
|
size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs,
|
|
2903
3014
|
const void* dict, size_t dictSize,
|
|
2904
3015
|
ZSTD_parameters params, unsigned long long pledgedSrcSize)
|
|
@@ -2920,9 +3031,9 @@ size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs,
|
|
|
2920
3031
|
if (zcs->outBuff == NULL) return ERROR(memory_allocation);
|
|
2921
3032
|
}
|
|
2922
3033
|
|
|
2923
|
-
if (dict) {
|
|
3034
|
+
if (dict && dictSize >= 8) {
|
|
2924
3035
|
ZSTD_freeCDict(zcs->cdictLocal);
|
|
2925
|
-
zcs->cdictLocal = ZSTD_createCDict_advanced(dict, dictSize, params, zcs->customMem);
|
|
3036
|
+
zcs->cdictLocal = ZSTD_createCDict_advanced(dict, dictSize, 0, params, zcs->customMem);
|
|
2926
3037
|
if (zcs->cdictLocal == NULL) return ERROR(memory_allocation);
|
|
2927
3038
|
zcs->cdict = zcs->cdictLocal;
|
|
2928
3039
|
} else zcs->cdict = NULL;
|
|
@@ -2930,7 +3041,7 @@ size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs,
|
|
|
2930
3041
|
zcs->checksum = params.fParams.checksumFlag > 0;
|
|
2931
3042
|
zcs->params = params;
|
|
2932
3043
|
|
|
2933
|
-
return
|
|
3044
|
+
return ZSTD_resetCStream_internal(zcs, pledgedSrcSize);
|
|
2934
3045
|
}
|
|
2935
3046
|
|
|
2936
3047
|
/* note : cdict must outlive compression session */
|
|
@@ -2939,6 +3050,7 @@ size_t ZSTD_initCStream_usingCDict(ZSTD_CStream* zcs, const ZSTD_CDict* cdict)
|
|
|
2939
3050
|
ZSTD_parameters const params = ZSTD_getParamsFromCDict(cdict);
|
|
2940
3051
|
size_t const initError = ZSTD_initCStream_advanced(zcs, NULL, 0, params, 0);
|
|
2941
3052
|
zcs->cdict = cdict;
|
|
3053
|
+
zcs->cctx->dictID = params.fParams.noDictIDFlag ? 0 : cdict->refContext->dictID;
|
|
2942
3054
|
return initError;
|
|
2943
3055
|
}
|
|
2944
3056
|
|
|
@@ -2948,6 +3060,13 @@ size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t di
|
|
|
2948
3060
|
return ZSTD_initCStream_advanced(zcs, dict, dictSize, params, 0);
|
|
2949
3061
|
}
|
|
2950
3062
|
|
|
3063
|
+
size_t ZSTD_initCStream_srcSize(ZSTD_CStream* zcs, int compressionLevel, unsigned long long pledgedSrcSize)
|
|
3064
|
+
{
|
|
3065
|
+
ZSTD_parameters params = ZSTD_getParams(compressionLevel, pledgedSrcSize, 0);
|
|
3066
|
+
if (pledgedSrcSize) params.fParams.contentSizeFlag = 1;
|
|
3067
|
+
return ZSTD_initCStream_advanced(zcs, NULL, 0, params, pledgedSrcSize);
|
|
3068
|
+
}
|
|
3069
|
+
|
|
2951
3070
|
size_t ZSTD_initCStream(ZSTD_CStream* zcs, int compressionLevel)
|
|
2952
3071
|
{
|
|
2953
3072
|
return ZSTD_initCStream_usingDict(zcs, NULL, 0, compressionLevel);
|
|
@@ -2956,7 +3075,7 @@ size_t ZSTD_initCStream(ZSTD_CStream* zcs, int compressionLevel)
|
|
|
2956
3075
|
size_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs)
|
|
2957
3076
|
{
|
|
2958
3077
|
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;
|
|
3078
|
+
return sizeof(*zcs) + ZSTD_sizeof_CCtx(zcs->cctx) + ZSTD_sizeof_CDict(zcs->cdictLocal) + zcs->outBuffSize + zcs->inBuffSize;
|
|
2960
3079
|
}
|
|
2961
3080
|
|
|
2962
3081
|
/*====== Compression ======*/
|
|
@@ -3044,6 +3163,7 @@ static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
|
|
|
3044
3163
|
|
|
3045
3164
|
*srcSizePtr = ip - istart;
|
|
3046
3165
|
*dstCapacityPtr = op - ostart;
|
|
3166
|
+
zcs->inputProcessed += *srcSizePtr;
|
|
3047
3167
|
if (zcs->frameEnded) return 0;
|
|
3048
3168
|
{ size_t hintInSize = zcs->inBuffTarget - zcs->inBuffPos;
|
|
3049
3169
|
if (hintInSize==0) hintInSize = zcs->blockSize;
|
|
@@ -3088,6 +3208,9 @@ size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output)
|
|
|
3088
3208
|
BYTE* const oend = (BYTE*)(output->dst) + output->size;
|
|
3089
3209
|
BYTE* op = ostart;
|
|
3090
3210
|
|
|
3211
|
+
if ((zcs->pledgedSrcSize) && (zcs->inputProcessed != zcs->pledgedSrcSize))
|
|
3212
|
+
return ERROR(srcSize_wrong); /* pledgedSrcSize not respected */
|
|
3213
|
+
|
|
3091
3214
|
if (zcs->stage != zcss_final) {
|
|
3092
3215
|
/* flush whatever remains */
|
|
3093
3216
|
size_t srcSize = 0;
|