zstd-ruby 1.1.4.0 → 1.2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (31) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -1
  3. data/README.md +1 -1
  4. data/ext/zstdruby/libzstd/Makefile +11 -1
  5. data/ext/zstdruby/libzstd/README.md +8 -0
  6. data/ext/zstdruby/libzstd/common/bitstream.h +56 -27
  7. data/ext/zstdruby/libzstd/common/error_private.c +2 -1
  8. data/ext/zstdruby/libzstd/common/fse.h +7 -3
  9. data/ext/zstdruby/libzstd/common/huf.h +42 -19
  10. data/ext/zstdruby/libzstd/common/mem.h +2 -3
  11. data/ext/zstdruby/libzstd/common/zstd_errors.h +1 -0
  12. data/ext/zstdruby/libzstd/common/zstd_internal.h +3 -2
  13. data/ext/zstdruby/libzstd/compress/fse_compress.c +10 -10
  14. data/ext/zstdruby/libzstd/compress/zstd_compress.c +455 -244
  15. data/ext/zstdruby/libzstd/compress/zstd_opt.h +6 -4
  16. data/ext/zstdruby/libzstd/compress/zstdmt_compress.c +40 -28
  17. data/ext/zstdruby/libzstd/decompress/zstd_decompress.c +115 -219
  18. data/ext/zstdruby/libzstd/dictBuilder/cover.c +34 -13
  19. data/ext/zstdruby/libzstd/dictBuilder/zdict.c +65 -43
  20. data/ext/zstdruby/libzstd/dictBuilder/zdict.h +7 -7
  21. data/ext/zstdruby/libzstd/dll/example/README.md +5 -5
  22. data/ext/zstdruby/libzstd/dll/example/build_package.bat +1 -0
  23. data/ext/zstdruby/libzstd/legacy/zstd_v01.c +1 -1
  24. data/ext/zstdruby/libzstd/legacy/zstd_v02.c +21 -21
  25. data/ext/zstdruby/libzstd/legacy/zstd_v03.c +20 -20
  26. data/ext/zstdruby/libzstd/legacy/zstd_v04.c +4 -4
  27. data/ext/zstdruby/libzstd/legacy/zstd_v05.c +2 -2
  28. data/ext/zstdruby/libzstd/legacy/zstd_v06.c +2 -2
  29. data/ext/zstdruby/libzstd/zstd.h +88 -68
  30. data/lib/zstd-ruby/version.rb +1 -1
  31. metadata +3 -3
@@ -175,10 +175,10 @@ MEM_STATIC void ZSTD_updatePrice(seqStore_t* seqStorePtr, U32 litLength, const B
175
175
  }
176
176
 
177
177
  /* match offset */
178
- { BYTE const offCode = (BYTE)ZSTD_highbit32(offset+1);
179
- seqStorePtr->offCodeSum++;
180
- seqStorePtr->offCodeFreq[offCode]++;
181
- }
178
+ { BYTE const offCode = (BYTE)ZSTD_highbit32(offset+1);
179
+ seqStorePtr->offCodeSum++;
180
+ seqStorePtr->offCodeFreq[offCode]++;
181
+ }
182
182
 
183
183
  /* match Length */
184
184
  { const BYTE ML_deltaCode = 36;
@@ -360,6 +360,7 @@ static U32 ZSTD_BtGetAllMatches_selectMLS (
360
360
  default :
361
361
  case 4 : return ZSTD_BtGetAllMatches(zc, ip, iHighLimit, maxNbAttempts, 4, matches, minMatchLen);
362
362
  case 5 : return ZSTD_BtGetAllMatches(zc, ip, iHighLimit, maxNbAttempts, 5, matches, minMatchLen);
363
+ case 7 :
363
364
  case 6 : return ZSTD_BtGetAllMatches(zc, ip, iHighLimit, maxNbAttempts, 6, matches, minMatchLen);
364
365
  }
365
366
  }
@@ -387,6 +388,7 @@ static U32 ZSTD_BtGetAllMatches_selectMLS_extDict (
387
388
  default :
388
389
  case 4 : return ZSTD_BtGetAllMatches_extDict(zc, ip, iHighLimit, maxNbAttempts, 4, matches, minMatchLen);
389
390
  case 5 : return ZSTD_BtGetAllMatches_extDict(zc, ip, iHighLimit, maxNbAttempts, 5, matches, minMatchLen);
391
+ case 7 :
390
392
  case 6 : return ZSTD_BtGetAllMatches_extDict(zc, ip, iHighLimit, maxNbAttempts, 6, matches, minMatchLen);
391
393
  }
392
394
  }
@@ -33,7 +33,7 @@
33
33
  # include <stdio.h>
34
34
  # include <unistd.h>
35
35
  # include <sys/times.h>
36
- static unsigned g_debugLevel = 3;
36
+ static unsigned g_debugLevel = 5;
37
37
  # define DEBUGLOGRAW(l, ...) if (l<=g_debugLevel) { fprintf(stderr, __VA_ARGS__); }
38
38
  # define DEBUGLOG(l, ...) if (l<=g_debugLevel) { fprintf(stderr, __FILE__ ": "); fprintf(stderr, __VA_ARGS__); fprintf(stderr, " \n"); }
39
39
 
@@ -44,26 +44,26 @@
44
44
  DEBUGLOGRAW(l, " \n"); \
45
45
  }
46
46
 
47
- static unsigned long long GetCurrentClockTimeMicroseconds()
47
+ static unsigned long long GetCurrentClockTimeMicroseconds(void)
48
48
  {
49
49
  static clock_t _ticksPerSecond = 0;
50
50
  if (_ticksPerSecond <= 0) _ticksPerSecond = sysconf(_SC_CLK_TCK);
51
51
 
52
- struct tms junk; clock_t newTicks = (clock_t) times(&junk);
53
- return ((((unsigned long long)newTicks)*(1000000))/_ticksPerSecond);
52
+ { struct tms junk; clock_t newTicks = (clock_t) times(&junk);
53
+ return ((((unsigned long long)newTicks)*(1000000))/_ticksPerSecond); }
54
54
  }
55
55
 
56
56
  #define MUTEX_WAIT_TIME_DLEVEL 5
57
57
  #define PTHREAD_MUTEX_LOCK(mutex) \
58
58
  if (g_debugLevel>=MUTEX_WAIT_TIME_DLEVEL) { \
59
- unsigned long long beforeTime = GetCurrentClockTimeMicroseconds(); \
60
- pthread_mutex_lock(mutex); \
61
- unsigned long long afterTime = GetCurrentClockTimeMicroseconds(); \
62
- unsigned long long elapsedTime = (afterTime-beforeTime); \
63
- if (elapsedTime > 1000) { /* or whatever threshold you like; I'm using 1 millisecond here */ \
64
- DEBUGLOG(MUTEX_WAIT_TIME_DLEVEL, "Thread took %llu microseconds to acquire mutex %s \n", \
59
+ unsigned long long const beforeTime = GetCurrentClockTimeMicroseconds(); \
60
+ pthread_mutex_lock(mutex); \
61
+ { unsigned long long const afterTime = GetCurrentClockTimeMicroseconds(); \
62
+ unsigned long long const elapsedTime = (afterTime-beforeTime); \
63
+ if (elapsedTime > 1000) { /* or whatever threshold you like; I'm using 1 millisecond here */ \
64
+ DEBUGLOG(MUTEX_WAIT_TIME_DLEVEL, "Thread took %llu microseconds to acquire mutex %s \n", \
65
65
  elapsedTime, #mutex); \
66
- } \
66
+ } } \
67
67
  } else pthread_mutex_lock(mutex);
68
68
 
69
69
  #else
@@ -228,17 +228,19 @@ void ZSTDMT_compressChunk(void* jobDescription)
228
228
  ZSTDMT_jobDescription* const job = (ZSTDMT_jobDescription*)jobDescription;
229
229
  const void* const src = (const char*)job->srcStart + job->dictSize;
230
230
  buffer_t const dstBuff = job->dstBuff;
231
- DEBUGLOG(3, "job (first:%u) (last:%u) : dictSize %u, srcSize %u", job->firstChunk, job->lastChunk, (U32)job->dictSize, (U32)job->srcSize);
231
+ DEBUGLOG(3, "job (first:%u) (last:%u) : dictSize %u, srcSize %u",
232
+ job->firstChunk, job->lastChunk, (U32)job->dictSize, (U32)job->srcSize);
232
233
  if (job->cdict) { /* should only happen for first segment */
233
- size_t const initError = ZSTD_compressBegin_usingCDict(job->cctx, job->cdict, job->fullFrameSize);
234
+ size_t const initError = ZSTD_compressBegin_usingCDict_advanced(job->cctx, job->cdict, job->params.fParams, job->fullFrameSize);
234
235
  if (job->cdict) DEBUGLOG(3, "using CDict ");
235
236
  if (ZSTD_isError(initError)) { job->cSize = initError; goto _endJob; }
236
237
  } else { /* srcStart points at reloaded section */
237
- size_t const dictModeError = ZSTD_setCCtxParameter(job->cctx, ZSTD_p_forceRawDict, 1); /* Force loading dictionary in "content-only" mode (no header analysis) */
238
- size_t const initError = ZSTD_compressBegin_advanced(job->cctx, job->srcStart, job->dictSize, job->params, 0);
239
- if (ZSTD_isError(initError) || ZSTD_isError(dictModeError)) { job->cSize = initError; goto _endJob; }
240
- ZSTD_setCCtxParameter(job->cctx, ZSTD_p_forceWindow, 1);
241
- }
238
+ if (!job->firstChunk) job->params.fParams.contentSizeFlag = 0; /* ensure no srcSize control */
239
+ { size_t const dictModeError = ZSTD_setCCtxParameter(job->cctx, ZSTD_p_forceRawDict, 1); /* Force loading dictionary in "content-only" mode (no header analysis) */
240
+ size_t const initError = ZSTD_compressBegin_advanced(job->cctx, job->srcStart, job->dictSize, job->params, job->fullFrameSize);
241
+ if (ZSTD_isError(initError) || ZSTD_isError(dictModeError)) { job->cSize = initError; goto _endJob; }
242
+ ZSTD_setCCtxParameter(job->cctx, ZSTD_p_forceWindow, 1);
243
+ } }
242
244
  if (!job->firstChunk) { /* flush and overwrite frame header when it's not first segment */
243
245
  size_t const hSize = ZSTD_compressContinue(job->cctx, dstBuff.start, dstBuff.size, src, 0);
244
246
  if (ZSTD_isError(hSize)) { job->cSize = hSize; goto _endJob; }
@@ -250,7 +252,9 @@ void ZSTDMT_compressChunk(void* jobDescription)
250
252
  job->cSize = (job->lastChunk) ?
251
253
  ZSTD_compressEnd (job->cctx, dstBuff.start, dstBuff.size, src, job->srcSize) :
252
254
  ZSTD_compressContinue(job->cctx, dstBuff.start, dstBuff.size, src, job->srcSize);
253
- DEBUGLOG(3, "compressed %u bytes into %u bytes (first:%u) (last:%u)", (unsigned)job->srcSize, (unsigned)job->cSize, job->firstChunk, job->lastChunk);
255
+ DEBUGLOG(3, "compressed %u bytes into %u bytes (first:%u) (last:%u)",
256
+ (unsigned)job->srcSize, (unsigned)job->cSize, job->firstChunk, job->lastChunk);
257
+ DEBUGLOG(5, "dstBuff.size : %u ; => %s", (U32)dstBuff.size, ZSTD_getErrorName(job->cSize));
254
258
 
255
259
  _endJob:
256
260
  PTHREAD_MUTEX_LOCK(job->jobCompleted_mutex);
@@ -388,14 +392,17 @@ size_t ZSTDMT_compressCCtx(ZSTDMT_CCtx* mtctx,
388
392
  int compressionLevel)
389
393
  {
390
394
  ZSTD_parameters params = ZSTD_getParams(compressionLevel, srcSize, 0);
395
+ U32 const overlapLog = (compressionLevel >= ZSTD_maxCLevel()) ? 0 : 3;
396
+ size_t const overlapSize = (size_t)1 << (params.cParams.windowLog - overlapLog);
391
397
  size_t const chunkTargetSize = (size_t)1 << (params.cParams.windowLog + 2);
392
- unsigned const nbChunksMax = (unsigned)(srcSize / chunkTargetSize) + (srcSize < chunkTargetSize) /* min 1 */;
398
+ unsigned const nbChunksMax = (unsigned)(srcSize / chunkTargetSize) + 1;
393
399
  unsigned nbChunks = MIN(nbChunksMax, mtctx->nbThreads);
394
400
  size_t const proposedChunkSize = (srcSize + (nbChunks-1)) / nbChunks;
395
401
  size_t const avgChunkSize = ((proposedChunkSize & 0x1FFFF) < 0xFFFF) ? proposedChunkSize + 0xFFFF : proposedChunkSize; /* avoid too small last block */
396
402
  size_t remainingSrcSize = srcSize;
397
403
  const char* const srcStart = (const char*)src;
398
- size_t frameStartPos = 0;
404
+ unsigned const compressWithinDst = (dstCapacity >= ZSTD_compressBound(srcSize)) ? nbChunks : (unsigned)(dstCapacity / ZSTD_compressBound(avgChunkSize)); /* presumes avgChunkSize >= 256 KB, which should be the case */
405
+ size_t frameStartPos = 0, dstBufferPos = 0;
399
406
 
400
407
  DEBUGLOG(3, "windowLog : %2u => chunkTargetSize : %u bytes ", params.cParams.windowLog, (U32)chunkTargetSize);
401
408
  DEBUGLOG(2, "nbChunks : %2u (chunkSize : %u bytes) ", nbChunks, (U32)avgChunkSize);
@@ -409,10 +416,11 @@ size_t ZSTDMT_compressCCtx(ZSTDMT_CCtx* mtctx,
409
416
  { unsigned u;
410
417
  for (u=0; u<nbChunks; u++) {
411
418
  size_t const chunkSize = MIN(remainingSrcSize, avgChunkSize);
412
- size_t const dstBufferCapacity = u ? ZSTD_compressBound(chunkSize) : dstCapacity;
413
- buffer_t const dstAsBuffer = { dst, dstCapacity };
414
- buffer_t const dstBuffer = u ? ZSTDMT_getBuffer(mtctx->buffPool, dstBufferCapacity) : dstAsBuffer;
419
+ size_t const dstBufferCapacity = ZSTD_compressBound(chunkSize);
420
+ buffer_t const dstAsBuffer = { (char*)dst + dstBufferPos, dstBufferCapacity };
421
+ buffer_t const dstBuffer = u < compressWithinDst ? dstAsBuffer : ZSTDMT_getBuffer(mtctx->buffPool, dstBufferCapacity);
415
422
  ZSTD_CCtx* const cctx = ZSTDMT_getCCtx(mtctx->cctxPool);
423
+ size_t dictSize = u ? overlapSize : 0;
416
424
 
417
425
  if ((cctx==NULL) || (dstBuffer.start==NULL)) {
418
426
  mtctx->jobs[u].cSize = ERROR(memory_allocation); /* job result */
@@ -421,7 +429,8 @@ size_t ZSTDMT_compressCCtx(ZSTDMT_CCtx* mtctx,
421
429
  break; /* let's wait for previous jobs to complete, but don't start new ones */
422
430
  }
423
431
 
424
- mtctx->jobs[u].srcStart = srcStart + frameStartPos;
432
+ mtctx->jobs[u].srcStart = srcStart + frameStartPos - dictSize;
433
+ mtctx->jobs[u].dictSize = dictSize;
425
434
  mtctx->jobs[u].srcSize = chunkSize;
426
435
  mtctx->jobs[u].fullFrameSize = srcSize;
427
436
  mtctx->jobs[u].params = params;
@@ -438,6 +447,7 @@ size_t ZSTDMT_compressCCtx(ZSTDMT_CCtx* mtctx,
438
447
  POOL_add(mtctx->factory, ZSTDMT_compressChunk, &mtctx->jobs[u]);
439
448
 
440
449
  frameStartPos += chunkSize;
450
+ dstBufferPos += dstBufferCapacity;
441
451
  remainingSrcSize -= chunkSize;
442
452
  } }
443
453
  /* note : since nbChunks <= nbThreads, all jobs should be running immediately in parallel */
@@ -461,8 +471,10 @@ size_t ZSTDMT_compressCCtx(ZSTDMT_CCtx* mtctx,
461
471
  if (ZSTD_isError(cSize)) error = cSize;
462
472
  if ((!error) && (dstPos + cSize > dstCapacity)) error = ERROR(dstSize_tooSmall);
463
473
  if (chunkID) { /* note : chunk 0 is already written directly into dst */
464
- if (!error) memcpy((char*)dst + dstPos, mtctx->jobs[chunkID].dstBuff.start, cSize);
465
- ZSTDMT_releaseBuffer(mtctx->buffPool, mtctx->jobs[chunkID].dstBuff);
474
+ if (!error)
475
+ memmove((char*)dst + dstPos, mtctx->jobs[chunkID].dstBuff.start, cSize); /* may overlap if chunk decompressed within dst */
476
+ if (chunkID >= compressWithinDst) /* otherwise, it decompresses within dst */
477
+ ZSTDMT_releaseBuffer(mtctx->buffPool, mtctx->jobs[chunkID].dstBuff);
466
478
  mtctx->jobs[chunkID].dstBuff = g_nullBuffer;
467
479
  }
468
480
  dstPos += cSize ;
@@ -509,7 +521,7 @@ static size_t ZSTDMT_initCStream_internal(ZSTDMT_CCtx* zcs,
509
521
  if (updateDict) {
510
522
  ZSTD_freeCDict(zcs->cdict); zcs->cdict = NULL;
511
523
  if (dict && dictSize) {
512
- zcs->cdict = ZSTD_createCDict_advanced(dict, dictSize, 0, params, cmem);
524
+ zcs->cdict = ZSTD_createCDict_advanced(dict, dictSize, 0, params.cParams, cmem);
513
525
  if (zcs->cdict == NULL) return ERROR(memory_allocation);
514
526
  } }
515
527
  zcs->frameContentSize = pledgedSrcSize;
@@ -177,30 +177,6 @@ void ZSTD_copyDCtx(ZSTD_DCtx* dstDCtx, const ZSTD_DCtx* srcDCtx)
177
177
  memcpy(dstDCtx, srcDCtx, sizeof(ZSTD_DCtx) - workSpaceSize); /* no need to copy workspace */
178
178
  }
179
179
 
180
- #if 0
181
- /* deprecated */
182
- static void ZSTD_refDCtx(ZSTD_DCtx* dstDCtx, const ZSTD_DCtx* srcDCtx)
183
- {
184
- ZSTD_decompressBegin(dstDCtx); /* init */
185
- if (srcDCtx) { /* support refDCtx on NULL */
186
- dstDCtx->dictEnd = srcDCtx->dictEnd;
187
- dstDCtx->vBase = srcDCtx->vBase;
188
- dstDCtx->base = srcDCtx->base;
189
- dstDCtx->previousDstEnd = srcDCtx->previousDstEnd;
190
- dstDCtx->dictID = srcDCtx->dictID;
191
- dstDCtx->litEntropy = srcDCtx->litEntropy;
192
- dstDCtx->fseEntropy = srcDCtx->fseEntropy;
193
- dstDCtx->LLTptr = srcDCtx->entropy.LLTable;
194
- dstDCtx->MLTptr = srcDCtx->entropy.MLTable;
195
- dstDCtx->OFTptr = srcDCtx->entropy.OFTable;
196
- dstDCtx->HUFptr = srcDCtx->entropy.hufTable;
197
- dstDCtx->entropy.rep[0] = srcDCtx->entropy.rep[0];
198
- dstDCtx->entropy.rep[1] = srcDCtx->entropy.rep[1];
199
- dstDCtx->entropy.rep[2] = srcDCtx->entropy.rep[2];
200
- }
201
- }
202
- #endif
203
-
204
180
  static void ZSTD_refDDict(ZSTD_DCtx* dstDCtx, const ZSTD_DDict* ddict);
205
181
 
206
182
 
@@ -431,7 +407,8 @@ typedef struct
431
407
 
432
408
  /*! ZSTD_getcBlockSize() :
433
409
  * Provides the size of compressed block from block header `src` */
434
- size_t ZSTD_getcBlockSize(const void* src, size_t srcSize, blockProperties_t* bpPtr)
410
+ size_t ZSTD_getcBlockSize(const void* src, size_t srcSize,
411
+ blockProperties_t* bpPtr)
435
412
  {
436
413
  if (srcSize < ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
437
414
  { U32 const cBlockHeader = MEM_readLE24(src);
@@ -446,7 +423,8 @@ size_t ZSTD_getcBlockSize(const void* src, size_t srcSize, blockProperties_t* bp
446
423
  }
447
424
 
448
425
 
449
- static size_t ZSTD_copyRawBlock(void* dst, size_t dstCapacity, const void* src, size_t srcSize)
426
+ static size_t ZSTD_copyRawBlock(void* dst, size_t dstCapacity,
427
+ const void* src, size_t srcSize)
450
428
  {
451
429
  if (srcSize > dstCapacity) return ERROR(dstSize_tooSmall);
452
430
  memcpy(dst, src, srcSize);
@@ -454,7 +432,9 @@ static size_t ZSTD_copyRawBlock(void* dst, size_t dstCapacity, const void* src,
454
432
  }
455
433
 
456
434
 
457
- static size_t ZSTD_setRleBlock(void* dst, size_t dstCapacity, const void* src, size_t srcSize, size_t regenSize)
435
+ static size_t ZSTD_setRleBlock(void* dst, size_t dstCapacity,
436
+ const void* src, size_t srcSize,
437
+ size_t regenSize)
458
438
  {
459
439
  if (srcSize != 1) return ERROR(srcSize_wrong);
460
440
  if (regenSize > dstCapacity) return ERROR(dstSize_tooSmall);
@@ -595,176 +575,70 @@ typedef union {
595
575
  U32 alignedBy4;
596
576
  } FSE_decode_t4;
597
577
 
578
+ /* Default FSE distribution table for Literal Lengths */
598
579
  static const FSE_decode_t4 LL_defaultDTable[(1<<LL_DEFAULTNORMLOG)+1] = {
599
580
  { { LL_DEFAULTNORMLOG, 1, 1 } }, /* header : tableLog, fastMode, fastMode */
600
- { { 0, 0, 4 } }, /* 0 : base, symbol, bits */
601
- { { 16, 0, 4 } },
602
- { { 32, 1, 5 } },
603
- { { 0, 3, 5 } },
604
- { { 0, 4, 5 } },
605
- { { 0, 6, 5 } },
606
- { { 0, 7, 5 } },
607
- { { 0, 9, 5 } },
608
- { { 0, 10, 5 } },
609
- { { 0, 12, 5 } },
610
- { { 0, 14, 6 } },
611
- { { 0, 16, 5 } },
612
- { { 0, 18, 5 } },
613
- { { 0, 19, 5 } },
614
- { { 0, 21, 5 } },
615
- { { 0, 22, 5 } },
616
- { { 0, 24, 5 } },
617
- { { 32, 25, 5 } },
618
- { { 0, 26, 5 } },
619
- { { 0, 27, 6 } },
620
- { { 0, 29, 6 } },
621
- { { 0, 31, 6 } },
622
- { { 32, 0, 4 } },
623
- { { 0, 1, 4 } },
624
- { { 0, 2, 5 } },
625
- { { 32, 4, 5 } },
626
- { { 0, 5, 5 } },
627
- { { 32, 7, 5 } },
628
- { { 0, 8, 5 } },
629
- { { 32, 10, 5 } },
630
- { { 0, 11, 5 } },
631
- { { 0, 13, 6 } },
632
- { { 32, 16, 5 } },
633
- { { 0, 17, 5 } },
634
- { { 32, 19, 5 } },
635
- { { 0, 20, 5 } },
636
- { { 32, 22, 5 } },
637
- { { 0, 23, 5 } },
638
- { { 0, 25, 4 } },
639
- { { 16, 25, 4 } },
640
- { { 32, 26, 5 } },
641
- { { 0, 28, 6 } },
642
- { { 0, 30, 6 } },
643
- { { 48, 0, 4 } },
644
- { { 16, 1, 4 } },
645
- { { 32, 2, 5 } },
646
- { { 32, 3, 5 } },
647
- { { 32, 5, 5 } },
648
- { { 32, 6, 5 } },
649
- { { 32, 8, 5 } },
650
- { { 32, 9, 5 } },
651
- { { 32, 11, 5 } },
652
- { { 32, 12, 5 } },
653
- { { 0, 15, 6 } },
654
- { { 32, 17, 5 } },
655
- { { 32, 18, 5 } },
656
- { { 32, 20, 5 } },
657
- { { 32, 21, 5 } },
658
- { { 32, 23, 5 } },
659
- { { 32, 24, 5 } },
660
- { { 0, 35, 6 } },
661
- { { 0, 34, 6 } },
662
- { { 0, 33, 6 } },
663
- { { 0, 32, 6 } },
581
+ /* base, symbol, bits */
582
+ { { 0, 0, 4 } }, { { 16, 0, 4 } }, { { 32, 1, 5 } }, { { 0, 3, 5 } },
583
+ { { 0, 4, 5 } }, { { 0, 6, 5 } }, { { 0, 7, 5 } }, { { 0, 9, 5 } },
584
+ { { 0, 10, 5 } }, { { 0, 12, 5 } }, { { 0, 14, 6 } }, { { 0, 16, 5 } },
585
+ { { 0, 18, 5 } }, { { 0, 19, 5 } }, { { 0, 21, 5 } }, { { 0, 22, 5 } },
586
+ { { 0, 24, 5 } }, { { 32, 25, 5 } }, { { 0, 26, 5 } }, { { 0, 27, 6 } },
587
+ { { 0, 29, 6 } }, { { 0, 31, 6 } }, { { 32, 0, 4 } }, { { 0, 1, 4 } },
588
+ { { 0, 2, 5 } }, { { 32, 4, 5 } }, { { 0, 5, 5 } }, { { 32, 7, 5 } },
589
+ { { 0, 8, 5 } }, { { 32, 10, 5 } }, { { 0, 11, 5 } }, { { 0, 13, 6 } },
590
+ { { 32, 16, 5 } }, { { 0, 17, 5 } }, { { 32, 19, 5 } }, { { 0, 20, 5 } },
591
+ { { 32, 22, 5 } }, { { 0, 23, 5 } }, { { 0, 25, 4 } }, { { 16, 25, 4 } },
592
+ { { 32, 26, 5 } }, { { 0, 28, 6 } }, { { 0, 30, 6 } }, { { 48, 0, 4 } },
593
+ { { 16, 1, 4 } }, { { 32, 2, 5 } }, { { 32, 3, 5 } }, { { 32, 5, 5 } },
594
+ { { 32, 6, 5 } }, { { 32, 8, 5 } }, { { 32, 9, 5 } }, { { 32, 11, 5 } },
595
+ { { 32, 12, 5 } }, { { 0, 15, 6 } }, { { 32, 17, 5 } }, { { 32, 18, 5 } },
596
+ { { 32, 20, 5 } }, { { 32, 21, 5 } }, { { 32, 23, 5 } }, { { 32, 24, 5 } },
597
+ { { 0, 35, 6 } }, { { 0, 34, 6 } }, { { 0, 33, 6 } }, { { 0, 32, 6 } },
664
598
  }; /* LL_defaultDTable */
665
599
 
600
+ /* Default FSE distribution table for Match Lengths */
666
601
  static const FSE_decode_t4 ML_defaultDTable[(1<<ML_DEFAULTNORMLOG)+1] = {
667
602
  { { ML_DEFAULTNORMLOG, 1, 1 } }, /* header : tableLog, fastMode, fastMode */
668
- { { 0, 0, 6 } }, /* 0 : base, symbol, bits */
669
- { { 0, 1, 4 } },
670
- { { 32, 2, 5 } },
671
- { { 0, 3, 5 } },
672
- { { 0, 5, 5 } },
673
- { { 0, 6, 5 } },
674
- { { 0, 8, 5 } },
675
- { { 0, 10, 6 } },
676
- { { 0, 13, 6 } },
677
- { { 0, 16, 6 } },
678
- { { 0, 19, 6 } },
679
- { { 0, 22, 6 } },
680
- { { 0, 25, 6 } },
681
- { { 0, 28, 6 } },
682
- { { 0, 31, 6 } },
683
- { { 0, 33, 6 } },
684
- { { 0, 35, 6 } },
685
- { { 0, 37, 6 } },
686
- { { 0, 39, 6 } },
687
- { { 0, 41, 6 } },
688
- { { 0, 43, 6 } },
689
- { { 0, 45, 6 } },
690
- { { 16, 1, 4 } },
691
- { { 0, 2, 4 } },
692
- { { 32, 3, 5 } },
693
- { { 0, 4, 5 } },
694
- { { 32, 6, 5 } },
695
- { { 0, 7, 5 } },
696
- { { 0, 9, 6 } },
697
- { { 0, 12, 6 } },
698
- { { 0, 15, 6 } },
699
- { { 0, 18, 6 } },
700
- { { 0, 21, 6 } },
701
- { { 0, 24, 6 } },
702
- { { 0, 27, 6 } },
703
- { { 0, 30, 6 } },
704
- { { 0, 32, 6 } },
705
- { { 0, 34, 6 } },
706
- { { 0, 36, 6 } },
707
- { { 0, 38, 6 } },
708
- { { 0, 40, 6 } },
709
- { { 0, 42, 6 } },
710
- { { 0, 44, 6 } },
711
- { { 32, 1, 4 } },
712
- { { 48, 1, 4 } },
713
- { { 16, 2, 4 } },
714
- { { 32, 4, 5 } },
715
- { { 32, 5, 5 } },
716
- { { 32, 7, 5 } },
717
- { { 32, 8, 5 } },
718
- { { 0, 11, 6 } },
719
- { { 0, 14, 6 } },
720
- { { 0, 17, 6 } },
721
- { { 0, 20, 6 } },
722
- { { 0, 23, 6 } },
723
- { { 0, 26, 6 } },
724
- { { 0, 29, 6 } },
725
- { { 0, 52, 6 } },
726
- { { 0, 51, 6 } },
727
- { { 0, 50, 6 } },
728
- { { 0, 49, 6 } },
729
- { { 0, 48, 6 } },
730
- { { 0, 47, 6 } },
731
- { { 0, 46, 6 } },
603
+ /* base, symbol, bits */
604
+ { { 0, 0, 6 } }, { { 0, 1, 4 } }, { { 32, 2, 5 } }, { { 0, 3, 5 } },
605
+ { { 0, 5, 5 } }, { { 0, 6, 5 } }, { { 0, 8, 5 } }, { { 0, 10, 6 } },
606
+ { { 0, 13, 6 } }, { { 0, 16, 6 } }, { { 0, 19, 6 } }, { { 0, 22, 6 } },
607
+ { { 0, 25, 6 } }, { { 0, 28, 6 } }, { { 0, 31, 6 } }, { { 0, 33, 6 } },
608
+ { { 0, 35, 6 } }, { { 0, 37, 6 } }, { { 0, 39, 6 } }, { { 0, 41, 6 } },
609
+ { { 0, 43, 6 } }, { { 0, 45, 6 } }, { { 16, 1, 4 } }, { { 0, 2, 4 } },
610
+ { { 32, 3, 5 } }, { { 0, 4, 5 } }, { { 32, 6, 5 } }, { { 0, 7, 5 } },
611
+ { { 0, 9, 6 } }, { { 0, 12, 6 } }, { { 0, 15, 6 } }, { { 0, 18, 6 } },
612
+ { { 0, 21, 6 } }, { { 0, 24, 6 } }, { { 0, 27, 6 } }, { { 0, 30, 6 } },
613
+ { { 0, 32, 6 } }, { { 0, 34, 6 } }, { { 0, 36, 6 } }, { { 0, 38, 6 } },
614
+ { { 0, 40, 6 } }, { { 0, 42, 6 } }, { { 0, 44, 6 } }, { { 32, 1, 4 } },
615
+ { { 48, 1, 4 } }, { { 16, 2, 4 } }, { { 32, 4, 5 } }, { { 32, 5, 5 } },
616
+ { { 32, 7, 5 } }, { { 32, 8, 5 } }, { { 0, 11, 6 } }, { { 0, 14, 6 } },
617
+ { { 0, 17, 6 } }, { { 0, 20, 6 } }, { { 0, 23, 6 } }, { { 0, 26, 6 } },
618
+ { { 0, 29, 6 } }, { { 0, 52, 6 } }, { { 0, 51, 6 } }, { { 0, 50, 6 } },
619
+ { { 0, 49, 6 } }, { { 0, 48, 6 } }, { { 0, 47, 6 } }, { { 0, 46, 6 } },
732
620
  }; /* ML_defaultDTable */
733
621
 
622
+ /* Default FSE distribution table for Offset Codes */
734
623
  static const FSE_decode_t4 OF_defaultDTable[(1<<OF_DEFAULTNORMLOG)+1] = {
735
624
  { { OF_DEFAULTNORMLOG, 1, 1 } }, /* header : tableLog, fastMode, fastMode */
736
- { { 0, 0, 5 } }, /* 0 : base, symbol, bits */
737
- { { 0, 6, 4 } },
738
- { { 0, 9, 5 } },
739
- { { 0, 15, 5 } },
740
- { { 0, 21, 5 } },
741
- { { 0, 3, 5 } },
742
- { { 0, 7, 4 } },
743
- { { 0, 12, 5 } },
744
- { { 0, 18, 5 } },
745
- { { 0, 23, 5 } },
746
- { { 0, 5, 5 } },
747
- { { 0, 8, 4 } },
748
- { { 0, 14, 5 } },
749
- { { 0, 20, 5 } },
750
- { { 0, 2, 5 } },
751
- { { 16, 7, 4 } },
752
- { { 0, 11, 5 } },
753
- { { 0, 17, 5 } },
754
- { { 0, 22, 5 } },
755
- { { 0, 4, 5 } },
756
- { { 16, 8, 4 } },
757
- { { 0, 13, 5 } },
758
- { { 0, 19, 5 } },
759
- { { 0, 1, 5 } },
760
- { { 16, 6, 4 } },
761
- { { 0, 10, 5 } },
762
- { { 0, 16, 5 } },
763
- { { 0, 28, 5 } },
764
- { { 0, 27, 5 } },
765
- { { 0, 26, 5 } },
766
- { { 0, 25, 5 } },
767
- { { 0, 24, 5 } },
625
+ /* base, symbol, bits */
626
+ { { 0, 0, 5 } }, { { 0, 6, 4 } },
627
+ { { 0, 9, 5 } }, { { 0, 15, 5 } },
628
+ { { 0, 21, 5 } }, { { 0, 3, 5 } },
629
+ { { 0, 7, 4 } }, { { 0, 12, 5 } },
630
+ { { 0, 18, 5 } }, { { 0, 23, 5 } },
631
+ { { 0, 5, 5 } }, { { 0, 8, 4 } },
632
+ { { 0, 14, 5 } }, { { 0, 20, 5 } },
633
+ { { 0, 2, 5 } }, { { 16, 7, 4 } },
634
+ { { 0, 11, 5 } }, { { 0, 17, 5 } },
635
+ { { 0, 22, 5 } }, { { 0, 4, 5 } },
636
+ { { 16, 8, 4 } }, { { 0, 13, 5 } },
637
+ { { 0, 19, 5 } }, { { 0, 1, 5 } },
638
+ { { 16, 6, 4 } }, { { 0, 10, 5 } },
639
+ { { 0, 16, 5 } }, { { 0, 28, 5 } },
640
+ { { 0, 27, 5 } }, { { 0, 26, 5 } },
641
+ { { 0, 25, 5 } }, { { 0, 24, 5 } },
768
642
  }; /* OF_defaultDTable */
769
643
 
770
644
  /*! ZSTD_buildSeqTable() :
@@ -927,8 +801,6 @@ size_t ZSTD_execSequenceLast7(BYTE* op,
927
801
  }
928
802
 
929
803
 
930
-
931
-
932
804
  static seq_t ZSTD_decodeSequence(seqState_t* seqState)
933
805
  {
934
806
  seq_t seq;
@@ -943,21 +815,26 @@ static seq_t ZSTD_decodeSequence(seqState_t* seqState)
943
815
  U32 const totalBits = llBits+mlBits+ofBits;
944
816
 
945
817
  static const U32 LL_base[MaxLL+1] = {
946
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
947
- 16, 18, 20, 22, 24, 28, 32, 40, 48, 64, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000,
818
+ 0, 1, 2, 3, 4, 5, 6, 7,
819
+ 8, 9, 10, 11, 12, 13, 14, 15,
820
+ 16, 18, 20, 22, 24, 28, 32, 40,
821
+ 48, 64, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000,
948
822
  0x2000, 0x4000, 0x8000, 0x10000 };
949
823
 
950
824
  static const U32 ML_base[MaxML+1] = {
951
- 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
952
- 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
953
- 35, 37, 39, 41, 43, 47, 51, 59, 67, 83, 99, 0x83, 0x103, 0x203, 0x403, 0x803,
825
+ 3, 4, 5, 6, 7, 8, 9, 10,
826
+ 11, 12, 13, 14, 15, 16, 17, 18,
827
+ 19, 20, 21, 22, 23, 24, 25, 26,
828
+ 27, 28, 29, 30, 31, 32, 33, 34,
829
+ 35, 37, 39, 41, 43, 47, 51, 59,
830
+ 67, 83, 99, 0x83, 0x103, 0x203, 0x403, 0x803,
954
831
  0x1003, 0x2003, 0x4003, 0x8003, 0x10003 };
955
832
 
956
833
  static const U32 OF_base[MaxOff+1] = {
957
- 0, 1, 1, 5, 0xD, 0x1D, 0x3D, 0x7D,
958
- 0xFD, 0x1FD, 0x3FD, 0x7FD, 0xFFD, 0x1FFD, 0x3FFD, 0x7FFD,
959
- 0xFFFD, 0x1FFFD, 0x3FFFD, 0x7FFFD, 0xFFFFD, 0x1FFFFD, 0x3FFFFD, 0x7FFFFD,
960
- 0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD };
834
+ 0, 1, 1, 5, 0xD, 0x1D, 0x3D, 0x7D,
835
+ 0xFD, 0x1FD, 0x3FD, 0x7FD, 0xFFD, 0x1FFD, 0x3FFD, 0x7FFD,
836
+ 0xFFFD, 0x1FFFD, 0x3FFFD, 0x7FFFD, 0xFFFFD, 0x1FFFFD, 0x3FFFFD, 0x7FFFFD,
837
+ 0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD };
961
838
 
962
839
  /* sequence */
963
840
  { size_t offset;
@@ -1031,7 +908,7 @@ size_t ZSTD_execSequence(BYTE* op,
1031
908
 
1032
909
  /* copy Match */
1033
910
  if (sequence.offset > (size_t)(oLitEnd - base)) {
1034
- /* offset beyond prefix */
911
+ /* offset beyond prefix -> go into extDict */
1035
912
  if (sequence.offset > (size_t)(oLitEnd - vBase)) return ERROR(corruption_detected);
1036
913
  match = dictEnd + (match - base);
1037
914
  if (match + sequence.matchLength <= dictEnd) {
@@ -1156,21 +1033,26 @@ FORCE_INLINE seq_t ZSTD_decodeSequenceLong_generic(seqState_t* seqState, int con
1156
1033
  U32 const totalBits = llBits+mlBits+ofBits;
1157
1034
 
1158
1035
  static const U32 LL_base[MaxLL+1] = {
1159
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
1160
- 16, 18, 20, 22, 24, 28, 32, 40, 48, 64, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000,
1036
+ 0, 1, 2, 3, 4, 5, 6, 7,
1037
+ 8, 9, 10, 11, 12, 13, 14, 15,
1038
+ 16, 18, 20, 22, 24, 28, 32, 40,
1039
+ 48, 64, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000,
1161
1040
  0x2000, 0x4000, 0x8000, 0x10000 };
1162
1041
 
1163
1042
  static const U32 ML_base[MaxML+1] = {
1164
- 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
1165
- 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
1166
- 35, 37, 39, 41, 43, 47, 51, 59, 67, 83, 99, 0x83, 0x103, 0x203, 0x403, 0x803,
1043
+ 3, 4, 5, 6, 7, 8, 9, 10,
1044
+ 11, 12, 13, 14, 15, 16, 17, 18,
1045
+ 19, 20, 21, 22, 23, 24, 25, 26,
1046
+ 27, 28, 29, 30, 31, 32, 33, 34,
1047
+ 35, 37, 39, 41, 43, 47, 51, 59,
1048
+ 67, 83, 99, 0x83, 0x103, 0x203, 0x403, 0x803,
1167
1049
  0x1003, 0x2003, 0x4003, 0x8003, 0x10003 };
1168
1050
 
1169
1051
  static const U32 OF_base[MaxOff+1] = {
1170
- 0, 1, 1, 5, 0xD, 0x1D, 0x3D, 0x7D,
1171
- 0xFD, 0x1FD, 0x3FD, 0x7FD, 0xFFD, 0x1FFD, 0x3FFD, 0x7FFD,
1172
- 0xFFFD, 0x1FFFD, 0x3FFFD, 0x7FFFD, 0xFFFFD, 0x1FFFFD, 0x3FFFFD, 0x7FFFFD,
1173
- 0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD };
1052
+ 0, 1, 1, 5, 0xD, 0x1D, 0x3D, 0x7D,
1053
+ 0xFD, 0x1FD, 0x3FD, 0x7FD, 0xFFD, 0x1FFD, 0x3FFD, 0x7FFD,
1054
+ 0xFFFD, 0x1FFFD, 0x3FFFD, 0x7FFFD, 0xFFFFD, 0x1FFFFD, 0x3FFFFD, 0x7FFFFD,
1055
+ 0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD };
1174
1056
 
1175
1057
  /* sequence */
1176
1058
  { size_t offset;
@@ -1476,7 +1358,7 @@ size_t ZSTD_findFrameCompressedSize(const void *src, size_t srcSize)
1476
1358
  if (ZSTD_isLegacy(src, srcSize)) return ZSTD_findFrameCompressedSizeLegacy(src, srcSize);
1477
1359
  #endif
1478
1360
  if (srcSize >= ZSTD_skippableHeaderSize &&
1479
- (MEM_readLE32(src) & 0xFFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) {
1361
+ (MEM_readLE32(src) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) {
1480
1362
  return ZSTD_skippableHeaderSize + MEM_readLE32((const BYTE*)src + 4);
1481
1363
  } else {
1482
1364
  const BYTE* ip = (const BYTE*)src;
@@ -2115,15 +1997,18 @@ unsigned ZSTD_getDictID_fromDDict(const ZSTD_DDict* ddict)
2115
1997
  }
2116
1998
 
2117
1999
  /*! ZSTD_getDictID_fromFrame() :
2118
- * Provides the dictID required to decompressed the frame stored within `src`.
2000
+ * Provides the dictID required to decompresse frame stored within `src`.
2119
2001
  * If @return == 0, the dictID could not be decoded.
2120
2002
  * This could for one of the following reasons :
2121
- * - The frame does not require a dictionary to be decoded (most common case).
2122
- * - The frame was built with dictID intentionally removed. Whatever dictionary is necessary is a hidden information.
2003
+ * - The frame does not require a dictionary (most common case).
2004
+ * - The frame was built with dictID intentionally removed.
2005
+ * Needed dictionary is a hidden information.
2123
2006
  * Note : this use case also happens when using a non-conformant dictionary.
2124
- * - `srcSize` is too small, and as a result, the frame header could not be decoded (only possible if `srcSize < ZSTD_FRAMEHEADERSIZE_MAX`).
2007
+ * - `srcSize` is too small, and as a result, frame header could not be decoded.
2008
+ * Note : possible if `srcSize < ZSTD_FRAMEHEADERSIZE_MAX`.
2125
2009
  * - This is not a Zstandard frame.
2126
- * When identifying the exact failure cause, it's possible to used ZSTD_getFrameParams(), which will provide a more precise error code. */
2010
+ * When identifying the exact failure cause, it's possible to use
2011
+ * ZSTD_getFrameParams(), which will provide a more precise error code. */
2127
2012
  unsigned ZSTD_getDictID_fromFrame(const void* src, size_t srcSize)
2128
2013
  {
2129
2014
  ZSTD_frameParams zfp = { 0 , 0 , 0 , 0 };
@@ -2209,9 +2094,13 @@ size_t ZSTD_freeDStream(ZSTD_DStream* zds)
2209
2094
  if (zds==NULL) return 0; /* support free on null */
2210
2095
  { ZSTD_customMem const cMem = zds->customMem;
2211
2096
  ZSTD_freeDCtx(zds->dctx);
2097
+ zds->dctx = NULL;
2212
2098
  ZSTD_freeDDict(zds->ddictLocal);
2099
+ zds->ddictLocal = NULL;
2213
2100
  ZSTD_free(zds->inBuff, cMem);
2101
+ zds->inBuff = NULL;
2214
2102
  ZSTD_free(zds->outBuff, cMem);
2103
+ zds->outBuff = NULL;
2215
2104
  #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1)
2216
2105
  if (zds->legacyContext)
2217
2106
  ZSTD_freeLegacyStreamContext(zds->legacyContext, zds->previousLegacyVersion);
@@ -2247,7 +2136,9 @@ size_t ZSTD_initDStream(ZSTD_DStream* zds)
2247
2136
  return ZSTD_initDStream_usingDict(zds, NULL, 0);
2248
2137
  }
2249
2138
 
2250
- size_t ZSTD_initDStream_usingDDict(ZSTD_DStream* zds, const ZSTD_DDict* ddict) /**< note : ddict will just be referenced, and must outlive decompression session */
2139
+ /* ZSTD_initDStream_usingDDict() :
2140
+ * ddict will just be referenced, and must outlive decompression session */
2141
+ size_t ZSTD_initDStream_usingDDict(ZSTD_DStream* zds, const ZSTD_DDict* ddict)
2251
2142
  {
2252
2143
  size_t const initResult = ZSTD_initDStream(zds);
2253
2144
  zds->ddict = ddict;
@@ -2277,8 +2168,11 @@ size_t ZSTD_setDStreamParameter(ZSTD_DStream* zds,
2277
2168
 
2278
2169
  size_t ZSTD_sizeof_DStream(const ZSTD_DStream* zds)
2279
2170
  {
2280
- if (zds==NULL) return 0; /* support sizeof on NULL */
2281
- return sizeof(*zds) + ZSTD_sizeof_DCtx(zds->dctx) + ZSTD_sizeof_DDict(zds->ddictLocal) + zds->inBuffSize + zds->outBuffSize;
2171
+ if (zds==NULL) return 0; /* support sizeof NULL */
2172
+ return sizeof(*zds)
2173
+ + ZSTD_sizeof_DCtx(zds->dctx)
2174
+ + ZSTD_sizeof_DDict(zds->ddictLocal)
2175
+ + zds->inBuffSize + zds->outBuffSize;
2282
2176
  }
2283
2177
 
2284
2178
 
@@ -2376,15 +2270,17 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
2376
2270
  zds->blockSize = blockSize;
2377
2271
  if (zds->inBuffSize < blockSize) {
2378
2272
  ZSTD_free(zds->inBuff, zds->customMem);
2379
- zds->inBuffSize = blockSize;
2273
+ zds->inBuffSize = 0;
2380
2274
  zds->inBuff = (char*)ZSTD_malloc(blockSize, zds->customMem);
2381
2275
  if (zds->inBuff == NULL) return ERROR(memory_allocation);
2276
+ zds->inBuffSize = blockSize;
2382
2277
  }
2383
2278
  if (zds->outBuffSize < neededOutSize) {
2384
2279
  ZSTD_free(zds->outBuff, zds->customMem);
2385
- zds->outBuffSize = neededOutSize;
2280
+ zds->outBuffSize = 0;
2386
2281
  zds->outBuff = (char*)ZSTD_malloc(neededOutSize, zds->customMem);
2387
2282
  if (zds->outBuff == NULL) return ERROR(memory_allocation);
2283
+ zds->outBuffSize = neededOutSize;
2388
2284
  } }
2389
2285
  zds->stage = zdss_read;
2390
2286
  /* pass-through */