zstdlib 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES.md +5 -0
  3. data/ext/zstdlib/extconf.rb +1 -1
  4. data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.2}/lib/common/bitstream.h +0 -0
  5. data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.2}/lib/common/compiler.h +7 -0
  6. data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.2}/lib/common/cpu.h +0 -0
  7. data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.2}/lib/common/debug.c +0 -0
  8. data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.2}/lib/common/debug.h +0 -0
  9. data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.2}/lib/common/entropy_common.c +0 -0
  10. data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.2}/lib/common/error_private.c +0 -0
  11. data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.2}/lib/common/error_private.h +0 -0
  12. data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.2}/lib/common/fse.h +0 -0
  13. data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.2}/lib/common/fse_decompress.c +0 -0
  14. data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.2}/lib/common/huf.h +0 -0
  15. data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.2}/lib/common/mem.h +0 -0
  16. data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.2}/lib/common/pool.c +0 -0
  17. data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.2}/lib/common/pool.h +0 -0
  18. data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.2}/lib/common/threading.c +0 -0
  19. data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.2}/lib/common/threading.h +0 -0
  20. data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.2}/lib/common/xxhash.c +0 -0
  21. data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.2}/lib/common/xxhash.h +0 -0
  22. data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.2}/lib/common/zstd_common.c +0 -0
  23. data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.2}/lib/common/zstd_errors.h +0 -0
  24. data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.2}/lib/common/zstd_internal.h +58 -6
  25. data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.2}/lib/compress/fse_compress.c +0 -0
  26. data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.2}/lib/compress/hist.c +0 -0
  27. data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.2}/lib/compress/hist.h +0 -0
  28. data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.2}/lib/compress/huf_compress.c +0 -0
  29. data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.2}/lib/compress/zstd_compress.c +178 -691
  30. data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.2}/lib/compress/zstd_compress_internal.h +98 -30
  31. data/ext/zstdlib/zstd-1.4.2/lib/compress/zstd_compress_literals.c +149 -0
  32. data/ext/zstdlib/zstd-1.4.2/lib/compress/zstd_compress_literals.h +29 -0
  33. data/ext/zstdlib/zstd-1.4.2/lib/compress/zstd_compress_sequences.c +415 -0
  34. data/ext/zstdlib/zstd-1.4.2/lib/compress/zstd_compress_sequences.h +47 -0
  35. data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.2}/lib/compress/zstd_double_fast.c +56 -36
  36. data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.2}/lib/compress/zstd_double_fast.h +0 -0
  37. data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.2}/lib/compress/zstd_fast.c +35 -14
  38. data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.2}/lib/compress/zstd_fast.h +0 -0
  39. data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.2}/lib/compress/zstd_lazy.c +10 -5
  40. data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.2}/lib/compress/zstd_lazy.h +0 -0
  41. data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.2}/lib/compress/zstd_ldm.c +1 -1
  42. data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.2}/lib/compress/zstd_ldm.h +0 -0
  43. data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.2}/lib/compress/zstd_opt.c +45 -32
  44. data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.2}/lib/compress/zstd_opt.h +0 -0
  45. data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.2}/lib/compress/zstdmt_compress.c +18 -7
  46. data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.2}/lib/compress/zstdmt_compress.h +1 -0
  47. data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.2}/lib/decompress/huf_decompress.c +0 -0
  48. data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.2}/lib/decompress/zstd_ddict.c +0 -0
  49. data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.2}/lib/decompress/zstd_ddict.h +0 -0
  50. data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.2}/lib/decompress/zstd_decompress.c +14 -9
  51. data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.2}/lib/decompress/zstd_decompress_block.c +20 -9
  52. data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.2}/lib/decompress/zstd_decompress_block.h +0 -0
  53. data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.2}/lib/decompress/zstd_decompress_internal.h +0 -0
  54. data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.2}/lib/zstd.h +53 -21
  55. data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.2}/zlibWrapper/gzclose.c +0 -0
  56. data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.2}/zlibWrapper/gzcompatibility.h +0 -0
  57. data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.2}/zlibWrapper/gzguts.h +0 -0
  58. data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.2}/zlibWrapper/gzlib.c +0 -0
  59. data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.2}/zlibWrapper/gzread.c +0 -0
  60. data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.2}/zlibWrapper/gzwrite.c +0 -0
  61. data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.2}/zlibWrapper/zstd_zlibwrapper.c +0 -0
  62. data/ext/zstdlib/{zstd-1.4.0 → zstd-1.4.2}/zlibWrapper/zstd_zlibwrapper.h +0 -0
  63. metadata +62 -59
@@ -33,13 +33,13 @@ extern "C" {
33
33
  ***************************************/
34
34
  #define kSearchStrength 8
35
35
  #define HASH_READ_SIZE 8
36
- #define ZSTD_DUBT_UNSORTED_MARK 1 /* For btlazy2 strategy, index 1 now means "unsorted".
36
+ #define ZSTD_DUBT_UNSORTED_MARK 1 /* For btlazy2 strategy, index ZSTD_DUBT_UNSORTED_MARK==1 means "unsorted".
37
37
  It could be confused for a real successor at index "1", if sorted as larger than its predecessor.
38
38
  It's not a big deal though : candidate will just be sorted again.
39
39
  Additionally, candidate position 1 will be lost.
40
40
  But candidate 1 cannot hide a large tree of candidates, so it's a minimal loss.
41
- The benefit is that ZSTD_DUBT_UNSORTED_MARK cannot be mishandled after table re-use with a different strategy
42
- Constant required by ZSTD_compressBlock_btlazy2() and ZSTD_reduceTable_internal() */
41
+ The benefit is that ZSTD_DUBT_UNSORTED_MARK cannot be mishandled after table re-use with a different strategy.
42
+ This constant is required by ZSTD_compressBlock_btlazy2() and ZSTD_reduceTable_internal() */
43
43
 
44
44
 
45
45
  /*-*************************************
@@ -128,21 +128,20 @@ typedef struct {
128
128
  BYTE const* base; /* All regular indexes relative to this position */
129
129
  BYTE const* dictBase; /* extDict indexes relative to this position */
130
130
  U32 dictLimit; /* below that point, need extDict */
131
- U32 lowLimit; /* below that point, no more data */
131
+ U32 lowLimit; /* below that point, no more valid data */
132
132
  } ZSTD_window_t;
133
133
 
134
134
  typedef struct ZSTD_matchState_t ZSTD_matchState_t;
135
135
  struct ZSTD_matchState_t {
136
136
  ZSTD_window_t window; /* State for window round buffer management */
137
- U32 loadedDictEnd; /* index of end of dictionary */
137
+ U32 loadedDictEnd; /* index of end of dictionary, within context's referential. When dict referential is copied into active context (i.e. not attached), effectively same value as dictSize, since referential starts from zero */
138
138
  U32 nextToUpdate; /* index from which to continue table update */
139
- U32 nextToUpdate3; /* index from which to continue table update */
140
139
  U32 hashLog3; /* dispatch table : larger == faster, more memory */
141
140
  U32* hashTable;
142
141
  U32* hashTable3;
143
142
  U32* chainTable;
144
143
  optState_t opt; /* optimal parser state */
145
- const ZSTD_matchState_t * dictMatchState;
144
+ const ZSTD_matchState_t* dictMatchState;
146
145
  ZSTD_compressionParameters cParams;
147
146
  };
148
147
 
@@ -195,6 +194,9 @@ struct ZSTD_CCtx_params_s {
195
194
  int compressionLevel;
196
195
  int forceWindow; /* force back-references to respect limit of
197
196
  * 1<<wLog, even for dictionary */
197
+ size_t targetCBlockSize; /* Tries to fit compressed block size to be around targetCBlockSize.
198
+ * No target when targetCBlockSize == 0.
199
+ * There is no guarantee on compressed block size */
198
200
 
199
201
  ZSTD_dictAttachPref_e attachDictPref;
200
202
  ZSTD_literalCompressionMode_e literalCompressionMode;
@@ -305,6 +307,30 @@ MEM_STATIC U32 ZSTD_MLcode(U32 mlBase)
305
307
  return (mlBase > 127) ? ZSTD_highbit32(mlBase) + ML_deltaCode : ML_Code[mlBase];
306
308
  }
307
309
 
310
+ /* ZSTD_cParam_withinBounds:
311
+ * @return 1 if value is within cParam bounds,
312
+ * 0 otherwise */
313
+ MEM_STATIC int ZSTD_cParam_withinBounds(ZSTD_cParameter cParam, int value)
314
+ {
315
+ ZSTD_bounds const bounds = ZSTD_cParam_getBounds(cParam);
316
+ if (ZSTD_isError(bounds.error)) return 0;
317
+ if (value < bounds.lowerBound) return 0;
318
+ if (value > bounds.upperBound) return 0;
319
+ return 1;
320
+ }
321
+
322
+ /* ZSTD_minGain() :
323
+ * minimum compression required
324
+ * to generate a compress block or a compressed literals section.
325
+ * note : use same formula for both situations */
326
+ MEM_STATIC size_t ZSTD_minGain(size_t srcSize, ZSTD_strategy strat)
327
+ {
328
+ U32 const minlog = (strat>=ZSTD_btultra) ? (U32)(strat) - 1 : 6;
329
+ ZSTD_STATIC_ASSERT(ZSTD_btultra == 8);
330
+ assert(ZSTD_cParam_withinBounds(ZSTD_c_strategy, strat));
331
+ return (srcSize >> minlog) + 2;
332
+ }
333
+
308
334
  /*! ZSTD_storeSeq() :
309
335
  * Store a sequence (literal length, literals, offset code and match length code) into seqStore_t.
310
336
  * `offsetCode` : distance to match + 3 (values 1-3 are repCodes).
@@ -324,7 +350,7 @@ MEM_STATIC void ZSTD_storeSeq(seqStore_t* seqStorePtr, size_t litLength, const v
324
350
  /* copy Literals */
325
351
  assert(seqStorePtr->maxNbLit <= 128 KB);
326
352
  assert(seqStorePtr->lit + litLength <= seqStorePtr->litStart + seqStorePtr->maxNbLit);
327
- ZSTD_wildcopy(seqStorePtr->lit, literals, litLength);
353
+ ZSTD_wildcopy(seqStorePtr->lit, literals, litLength, ZSTD_no_overlap);
328
354
  seqStorePtr->lit += litLength;
329
355
 
330
356
  /* literal Length */
@@ -564,6 +590,9 @@ MEM_STATIC U64 ZSTD_rollingHash_rotate(U64 hash, BYTE toRemove, BYTE toAdd, U64
564
590
  /*-*************************************
565
591
  * Round buffer management
566
592
  ***************************************/
593
+ #if (ZSTD_WINDOWLOG_MAX_64 > 31)
594
+ # error "ZSTD_WINDOWLOG_MAX is too large : would overflow ZSTD_CURRENT_MAX"
595
+ #endif
567
596
  /* Max current allowed */
568
597
  #define ZSTD_CURRENT_MAX ((3U << 29) + (1U << ZSTD_WINDOWLOG_MAX))
569
598
  /* Maximum chunk size before overflow correction needs to be called again */
@@ -675,31 +704,49 @@ MEM_STATIC U32 ZSTD_window_correctOverflow(ZSTD_window_t* window, U32 cycleLog,
675
704
  * Updates lowLimit so that:
676
705
  * (srcEnd - base) - lowLimit == maxDist + loadedDictEnd
677
706
  *
678
- * This allows a simple check that index >= lowLimit to see if index is valid.
679
- * This must be called before a block compression call, with srcEnd as the block
680
- * source end.
707
+ * It ensures index is valid as long as index >= lowLimit.
708
+ * This must be called before a block compression call.
681
709
  *
682
- * If loadedDictEndPtr is not NULL, we set it to zero once we update lowLimit.
683
- * This is because dictionaries are allowed to be referenced as long as the last
684
- * byte of the dictionary is in the window, but once they are out of range,
685
- * they cannot be referenced. If loadedDictEndPtr is NULL, we use
686
- * loadedDictEnd == 0.
710
+ * loadedDictEnd is only defined if a dictionary is in use for current compression.
711
+ * As the name implies, loadedDictEnd represents the index at end of dictionary.
712
+ * The value lies within context's referential, it can be directly compared to blockEndIdx.
687
713
  *
688
- * In normal dict mode, the dict is between lowLimit and dictLimit. In
689
- * dictMatchState mode, lowLimit and dictLimit are the same, and the dictionary
690
- * is below them. forceWindow and dictMatchState are therefore incompatible.
714
+ * If loadedDictEndPtr is NULL, no dictionary is in use, and we use loadedDictEnd == 0.
715
+ * If loadedDictEndPtr is not NULL, we set it to zero after updating lowLimit.
716
+ * This is because dictionaries are allowed to be referenced fully
717
+ * as long as the last byte of the dictionary is in the window.
718
+ * Once input has progressed beyond window size, dictionary cannot be referenced anymore.
719
+ *
720
+ * In normal dict mode, the dictionary lies between lowLimit and dictLimit.
721
+ * In dictMatchState mode, lowLimit and dictLimit are the same,
722
+ * and the dictionary is below them.
723
+ * forceWindow and dictMatchState are therefore incompatible.
691
724
  */
692
725
  MEM_STATIC void
693
726
  ZSTD_window_enforceMaxDist(ZSTD_window_t* window,
694
- void const* srcEnd,
695
- U32 maxDist,
696
- U32* loadedDictEndPtr,
727
+ const void* blockEnd,
728
+ U32 maxDist,
729
+ U32* loadedDictEndPtr,
697
730
  const ZSTD_matchState_t** dictMatchStatePtr)
698
731
  {
699
- U32 const blockEndIdx = (U32)((BYTE const*)srcEnd - window->base);
700
- U32 loadedDictEnd = (loadedDictEndPtr != NULL) ? *loadedDictEndPtr : 0;
701
- DEBUGLOG(5, "ZSTD_window_enforceMaxDist: blockEndIdx=%u, maxDist=%u",
702
- (unsigned)blockEndIdx, (unsigned)maxDist);
732
+ U32 const blockEndIdx = (U32)((BYTE const*)blockEnd - window->base);
733
+ U32 const loadedDictEnd = (loadedDictEndPtr != NULL) ? *loadedDictEndPtr : 0;
734
+ DEBUGLOG(5, "ZSTD_window_enforceMaxDist: blockEndIdx=%u, maxDist=%u, loadedDictEnd=%u",
735
+ (unsigned)blockEndIdx, (unsigned)maxDist, (unsigned)loadedDictEnd);
736
+
737
+ /* - When there is no dictionary : loadedDictEnd == 0.
738
+ In which case, the test (blockEndIdx > maxDist) is merely to avoid
739
+ overflowing next operation `newLowLimit = blockEndIdx - maxDist`.
740
+ - When there is a standard dictionary :
741
+ Index referential is copied from the dictionary,
742
+ which means it starts from 0.
743
+ In which case, loadedDictEnd == dictSize,
744
+ and it makes sense to compare `blockEndIdx > maxDist + dictSize`
745
+ since `blockEndIdx` also starts from zero.
746
+ - When there is an attached dictionary :
747
+ loadedDictEnd is expressed within the referential of the context,
748
+ so it can be directly compared against blockEndIdx.
749
+ */
703
750
  if (blockEndIdx > maxDist + loadedDictEnd) {
704
751
  U32 const newLowLimit = blockEndIdx - maxDist;
705
752
  if (window->lowLimit < newLowLimit) window->lowLimit = newLowLimit;
@@ -708,10 +755,31 @@ ZSTD_window_enforceMaxDist(ZSTD_window_t* window,
708
755
  (unsigned)window->dictLimit, (unsigned)window->lowLimit);
709
756
  window->dictLimit = window->lowLimit;
710
757
  }
711
- if (loadedDictEndPtr)
712
- *loadedDictEndPtr = 0;
713
- if (dictMatchStatePtr)
714
- *dictMatchStatePtr = NULL;
758
+ /* On reaching window size, dictionaries are invalidated */
759
+ if (loadedDictEndPtr) *loadedDictEndPtr = 0;
760
+ if (dictMatchStatePtr) *dictMatchStatePtr = NULL;
761
+ }
762
+ }
763
+
764
+ /* Similar to ZSTD_window_enforceMaxDist(),
765
+ * but only invalidates dictionary
766
+ * when input progresses beyond window size. */
767
+ MEM_STATIC void
768
+ ZSTD_checkDictValidity(ZSTD_window_t* window,
769
+ const void* blockEnd,
770
+ U32 maxDist,
771
+ U32* loadedDictEndPtr,
772
+ const ZSTD_matchState_t** dictMatchStatePtr)
773
+ {
774
+ U32 const blockEndIdx = (U32)((BYTE const*)blockEnd - window->base);
775
+ U32 const loadedDictEnd = (loadedDictEndPtr != NULL) ? *loadedDictEndPtr : 0;
776
+ DEBUGLOG(5, "ZSTD_checkDictValidity: blockEndIdx=%u, maxDist=%u, loadedDictEnd=%u",
777
+ (unsigned)blockEndIdx, (unsigned)maxDist, (unsigned)loadedDictEnd);
778
+
779
+ if (loadedDictEnd && (blockEndIdx > maxDist + loadedDictEnd)) {
780
+ /* On reaching window size, dictionaries are invalidated */
781
+ if (loadedDictEndPtr) *loadedDictEndPtr = 0;
782
+ if (dictMatchStatePtr) *dictMatchStatePtr = NULL;
715
783
  }
716
784
  }
717
785
 
@@ -0,0 +1,149 @@
1
+ /*
2
+ * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
3
+ * All rights reserved.
4
+ *
5
+ * This source code is licensed under both the BSD-style license (found in the
6
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7
+ * in the COPYING file in the root directory of this source tree).
8
+ * You may select, at your option, one of the above-listed licenses.
9
+ */
10
+
11
+ /*-*************************************
12
+ * Dependencies
13
+ ***************************************/
14
+ #include "zstd_compress_literals.h"
15
+
16
+ size_t ZSTD_noCompressLiterals (void* dst, size_t dstCapacity, const void* src, size_t srcSize)
17
+ {
18
+ BYTE* const ostart = (BYTE* const)dst;
19
+ U32 const flSize = 1 + (srcSize>31) + (srcSize>4095);
20
+
21
+ RETURN_ERROR_IF(srcSize + flSize > dstCapacity, dstSize_tooSmall);
22
+
23
+ switch(flSize)
24
+ {
25
+ case 1: /* 2 - 1 - 5 */
26
+ ostart[0] = (BYTE)((U32)set_basic + (srcSize<<3));
27
+ break;
28
+ case 2: /* 2 - 2 - 12 */
29
+ MEM_writeLE16(ostart, (U16)((U32)set_basic + (1<<2) + (srcSize<<4)));
30
+ break;
31
+ case 3: /* 2 - 2 - 20 */
32
+ MEM_writeLE32(ostart, (U32)((U32)set_basic + (3<<2) + (srcSize<<4)));
33
+ break;
34
+ default: /* not necessary : flSize is {1,2,3} */
35
+ assert(0);
36
+ }
37
+
38
+ memcpy(ostart + flSize, src, srcSize);
39
+ return srcSize + flSize;
40
+ }
41
+
42
+ size_t ZSTD_compressRleLiteralsBlock (void* dst, size_t dstCapacity, const void* src, size_t srcSize)
43
+ {
44
+ BYTE* const ostart = (BYTE* const)dst;
45
+ U32 const flSize = 1 + (srcSize>31) + (srcSize>4095);
46
+
47
+ (void)dstCapacity; /* dstCapacity already guaranteed to be >=4, hence large enough */
48
+
49
+ switch(flSize)
50
+ {
51
+ case 1: /* 2 - 1 - 5 */
52
+ ostart[0] = (BYTE)((U32)set_rle + (srcSize<<3));
53
+ break;
54
+ case 2: /* 2 - 2 - 12 */
55
+ MEM_writeLE16(ostart, (U16)((U32)set_rle + (1<<2) + (srcSize<<4)));
56
+ break;
57
+ case 3: /* 2 - 2 - 20 */
58
+ MEM_writeLE32(ostart, (U32)((U32)set_rle + (3<<2) + (srcSize<<4)));
59
+ break;
60
+ default: /* not necessary : flSize is {1,2,3} */
61
+ assert(0);
62
+ }
63
+
64
+ ostart[flSize] = *(const BYTE*)src;
65
+ return flSize+1;
66
+ }
67
+
68
+ size_t ZSTD_compressLiterals (ZSTD_hufCTables_t const* prevHuf,
69
+ ZSTD_hufCTables_t* nextHuf,
70
+ ZSTD_strategy strategy, int disableLiteralCompression,
71
+ void* dst, size_t dstCapacity,
72
+ const void* src, size_t srcSize,
73
+ void* workspace, size_t wkspSize,
74
+ const int bmi2)
75
+ {
76
+ size_t const minGain = ZSTD_minGain(srcSize, strategy);
77
+ size_t const lhSize = 3 + (srcSize >= 1 KB) + (srcSize >= 16 KB);
78
+ BYTE* const ostart = (BYTE*)dst;
79
+ U32 singleStream = srcSize < 256;
80
+ symbolEncodingType_e hType = set_compressed;
81
+ size_t cLitSize;
82
+
83
+ DEBUGLOG(5,"ZSTD_compressLiterals (disableLiteralCompression=%i)",
84
+ disableLiteralCompression);
85
+
86
+ /* Prepare nextEntropy assuming reusing the existing table */
87
+ memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
88
+
89
+ if (disableLiteralCompression)
90
+ return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
91
+
92
+ /* small ? don't even attempt compression (speed opt) */
93
+ # define COMPRESS_LITERALS_SIZE_MIN 63
94
+ { size_t const minLitSize = (prevHuf->repeatMode == HUF_repeat_valid) ? 6 : COMPRESS_LITERALS_SIZE_MIN;
95
+ if (srcSize <= minLitSize) return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
96
+ }
97
+
98
+ RETURN_ERROR_IF(dstCapacity < lhSize+1, dstSize_tooSmall, "not enough space for compression");
99
+ { HUF_repeat repeat = prevHuf->repeatMode;
100
+ int const preferRepeat = strategy < ZSTD_lazy ? srcSize <= 1024 : 0;
101
+ if (repeat == HUF_repeat_valid && lhSize == 3) singleStream = 1;
102
+ cLitSize = singleStream ? HUF_compress1X_repeat(ostart+lhSize, dstCapacity-lhSize, src, srcSize, 255, 11,
103
+ workspace, wkspSize, (HUF_CElt*)nextHuf->CTable, &repeat, preferRepeat, bmi2)
104
+ : HUF_compress4X_repeat(ostart+lhSize, dstCapacity-lhSize, src, srcSize, 255, 11,
105
+ workspace, wkspSize, (HUF_CElt*)nextHuf->CTable, &repeat, preferRepeat, bmi2);
106
+ if (repeat != HUF_repeat_none) {
107
+ /* reused the existing table */
108
+ hType = set_repeat;
109
+ }
110
+ }
111
+
112
+ if ((cLitSize==0) | (cLitSize >= srcSize - minGain) | ERR_isError(cLitSize)) {
113
+ memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
114
+ return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
115
+ }
116
+ if (cLitSize==1) {
117
+ memcpy(nextHuf, prevHuf, sizeof(*prevHuf));
118
+ return ZSTD_compressRleLiteralsBlock(dst, dstCapacity, src, srcSize);
119
+ }
120
+
121
+ if (hType == set_compressed) {
122
+ /* using a newly constructed table */
123
+ nextHuf->repeatMode = HUF_repeat_check;
124
+ }
125
+
126
+ /* Build header */
127
+ switch(lhSize)
128
+ {
129
+ case 3: /* 2 - 2 - 10 - 10 */
130
+ { U32 const lhc = hType + ((!singleStream) << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<14);
131
+ MEM_writeLE24(ostart, lhc);
132
+ break;
133
+ }
134
+ case 4: /* 2 - 2 - 14 - 14 */
135
+ { U32 const lhc = hType + (2 << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<18);
136
+ MEM_writeLE32(ostart, lhc);
137
+ break;
138
+ }
139
+ case 5: /* 2 - 2 - 18 - 18 */
140
+ { U32 const lhc = hType + (3 << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<22);
141
+ MEM_writeLE32(ostart, lhc);
142
+ ostart[4] = (BYTE)(cLitSize >> 10);
143
+ break;
144
+ }
145
+ default: /* not possible : lhSize is {3,4,5} */
146
+ assert(0);
147
+ }
148
+ return lhSize+cLitSize;
149
+ }
@@ -0,0 +1,29 @@
1
+ /*
2
+ * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
3
+ * All rights reserved.
4
+ *
5
+ * This source code is licensed under both the BSD-style license (found in the
6
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7
+ * in the COPYING file in the root directory of this source tree).
8
+ * You may select, at your option, one of the above-listed licenses.
9
+ */
10
+
11
+ #ifndef ZSTD_COMPRESS_LITERALS_H
12
+ #define ZSTD_COMPRESS_LITERALS_H
13
+
14
+ #include "zstd_compress_internal.h" /* ZSTD_hufCTables_t, ZSTD_minGain() */
15
+
16
+
17
+ size_t ZSTD_noCompressLiterals (void* dst, size_t dstCapacity, const void* src, size_t srcSize);
18
+
19
+ size_t ZSTD_compressRleLiteralsBlock (void* dst, size_t dstCapacity, const void* src, size_t srcSize);
20
+
21
+ size_t ZSTD_compressLiterals (ZSTD_hufCTables_t const* prevHuf,
22
+ ZSTD_hufCTables_t* nextHuf,
23
+ ZSTD_strategy strategy, int disableLiteralCompression,
24
+ void* dst, size_t dstCapacity,
25
+ const void* src, size_t srcSize,
26
+ void* workspace, size_t wkspSize,
27
+ const int bmi2);
28
+
29
+ #endif /* ZSTD_COMPRESS_LITERALS_H */
@@ -0,0 +1,415 @@
1
+ /*
2
+ * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
3
+ * All rights reserved.
4
+ *
5
+ * This source code is licensed under both the BSD-style license (found in the
6
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7
+ * in the COPYING file in the root directory of this source tree).
8
+ * You may select, at your option, one of the above-listed licenses.
9
+ */
10
+
11
+ /*-*************************************
12
+ * Dependencies
13
+ ***************************************/
14
+ #include "zstd_compress_sequences.h"
15
+
16
+ /**
17
+ * -log2(x / 256) lookup table for x in [0, 256).
18
+ * If x == 0: Return 0
19
+ * Else: Return floor(-log2(x / 256) * 256)
20
+ */
21
+ static unsigned const kInverseProbabilityLog256[256] = {
22
+ 0, 2048, 1792, 1642, 1536, 1453, 1386, 1329, 1280, 1236, 1197, 1162,
23
+ 1130, 1100, 1073, 1047, 1024, 1001, 980, 960, 941, 923, 906, 889,
24
+ 874, 859, 844, 830, 817, 804, 791, 779, 768, 756, 745, 734,
25
+ 724, 714, 704, 694, 685, 676, 667, 658, 650, 642, 633, 626,
26
+ 618, 610, 603, 595, 588, 581, 574, 567, 561, 554, 548, 542,
27
+ 535, 529, 523, 517, 512, 506, 500, 495, 489, 484, 478, 473,
28
+ 468, 463, 458, 453, 448, 443, 438, 434, 429, 424, 420, 415,
29
+ 411, 407, 402, 398, 394, 390, 386, 382, 377, 373, 370, 366,
30
+ 362, 358, 354, 350, 347, 343, 339, 336, 332, 329, 325, 322,
31
+ 318, 315, 311, 308, 305, 302, 298, 295, 292, 289, 286, 282,
32
+ 279, 276, 273, 270, 267, 264, 261, 258, 256, 253, 250, 247,
33
+ 244, 241, 239, 236, 233, 230, 228, 225, 222, 220, 217, 215,
34
+ 212, 209, 207, 204, 202, 199, 197, 194, 192, 190, 187, 185,
35
+ 182, 180, 178, 175, 173, 171, 168, 166, 164, 162, 159, 157,
36
+ 155, 153, 151, 149, 146, 144, 142, 140, 138, 136, 134, 132,
37
+ 130, 128, 126, 123, 121, 119, 117, 115, 114, 112, 110, 108,
38
+ 106, 104, 102, 100, 98, 96, 94, 93, 91, 89, 87, 85,
39
+ 83, 82, 80, 78, 76, 74, 73, 71, 69, 67, 66, 64,
40
+ 62, 61, 59, 57, 55, 54, 52, 50, 49, 47, 46, 44,
41
+ 42, 41, 39, 37, 36, 34, 33, 31, 30, 28, 26, 25,
42
+ 23, 22, 20, 19, 17, 16, 14, 13, 11, 10, 8, 7,
43
+ 5, 4, 2, 1,
44
+ };
45
+
46
+ static unsigned ZSTD_getFSEMaxSymbolValue(FSE_CTable const* ctable) {
47
+ void const* ptr = ctable;
48
+ U16 const* u16ptr = (U16 const*)ptr;
49
+ U32 const maxSymbolValue = MEM_read16(u16ptr + 1);
50
+ return maxSymbolValue;
51
+ }
52
+
53
+ /**
54
+ * Returns the cost in bytes of encoding the normalized count header.
55
+ * Returns an error if any of the helper functions return an error.
56
+ */
57
+ static size_t ZSTD_NCountCost(unsigned const* count, unsigned const max,
58
+ size_t const nbSeq, unsigned const FSELog)
59
+ {
60
+ BYTE wksp[FSE_NCOUNTBOUND];
61
+ S16 norm[MaxSeq + 1];
62
+ const U32 tableLog = FSE_optimalTableLog(FSELog, nbSeq, max);
63
+ FORWARD_IF_ERROR(FSE_normalizeCount(norm, tableLog, count, nbSeq, max));
64
+ return FSE_writeNCount(wksp, sizeof(wksp), norm, max, tableLog);
65
+ }
66
+
67
+ /**
68
+ * Returns the cost in bits of encoding the distribution described by count
69
+ * using the entropy bound.
70
+ */
71
+ static size_t ZSTD_entropyCost(unsigned const* count, unsigned const max, size_t const total)
72
+ {
73
+ unsigned cost = 0;
74
+ unsigned s;
75
+ for (s = 0; s <= max; ++s) {
76
+ unsigned norm = (unsigned)((256 * count[s]) / total);
77
+ if (count[s] != 0 && norm == 0)
78
+ norm = 1;
79
+ assert(count[s] < total);
80
+ cost += count[s] * kInverseProbabilityLog256[norm];
81
+ }
82
+ return cost >> 8;
83
+ }
84
+
85
+ /**
86
+ * Returns the cost in bits of encoding the distribution in count using ctable.
87
+ * Returns an error if ctable cannot represent all the symbols in count.
88
+ */
89
+ static size_t ZSTD_fseBitCost(
90
+ FSE_CTable const* ctable,
91
+ unsigned const* count,
92
+ unsigned const max)
93
+ {
94
+ unsigned const kAccuracyLog = 8;
95
+ size_t cost = 0;
96
+ unsigned s;
97
+ FSE_CState_t cstate;
98
+ FSE_initCState(&cstate, ctable);
99
+ RETURN_ERROR_IF(ZSTD_getFSEMaxSymbolValue(ctable) < max, GENERIC,
100
+ "Repeat FSE_CTable has maxSymbolValue %u < %u",
101
+ ZSTD_getFSEMaxSymbolValue(ctable), max);
102
+ for (s = 0; s <= max; ++s) {
103
+ unsigned const tableLog = cstate.stateLog;
104
+ unsigned const badCost = (tableLog + 1) << kAccuracyLog;
105
+ unsigned const bitCost = FSE_bitCost(cstate.symbolTT, tableLog, s, kAccuracyLog);
106
+ if (count[s] == 0)
107
+ continue;
108
+ RETURN_ERROR_IF(bitCost >= badCost, GENERIC,
109
+ "Repeat FSE_CTable has Prob[%u] == 0", s);
110
+ cost += count[s] * bitCost;
111
+ }
112
+ return cost >> kAccuracyLog;
113
+ }
114
+
115
+ /**
116
+ * Returns the cost in bits of encoding the distribution in count using the
117
+ * table described by norm. The max symbol support by norm is assumed >= max.
118
+ * norm must be valid for every symbol with non-zero probability in count.
119
+ */
120
+ static size_t ZSTD_crossEntropyCost(short const* norm, unsigned accuracyLog,
121
+ unsigned const* count, unsigned const max)
122
+ {
123
+ unsigned const shift = 8 - accuracyLog;
124
+ size_t cost = 0;
125
+ unsigned s;
126
+ assert(accuracyLog <= 8);
127
+ for (s = 0; s <= max; ++s) {
128
+ unsigned const normAcc = norm[s] != -1 ? norm[s] : 1;
129
+ unsigned const norm256 = normAcc << shift;
130
+ assert(norm256 > 0);
131
+ assert(norm256 < 256);
132
+ cost += count[s] * kInverseProbabilityLog256[norm256];
133
+ }
134
+ return cost >> 8;
135
+ }
136
+
137
+ symbolEncodingType_e
138
+ ZSTD_selectEncodingType(
139
+ FSE_repeat* repeatMode, unsigned const* count, unsigned const max,
140
+ size_t const mostFrequent, size_t nbSeq, unsigned const FSELog,
141
+ FSE_CTable const* prevCTable,
142
+ short const* defaultNorm, U32 defaultNormLog,
143
+ ZSTD_defaultPolicy_e const isDefaultAllowed,
144
+ ZSTD_strategy const strategy)
145
+ {
146
+ ZSTD_STATIC_ASSERT(ZSTD_defaultDisallowed == 0 && ZSTD_defaultAllowed != 0);
147
+ if (mostFrequent == nbSeq) {
148
+ *repeatMode = FSE_repeat_none;
149
+ if (isDefaultAllowed && nbSeq <= 2) {
150
+ /* Prefer set_basic over set_rle when there are 2 or less symbols,
151
+ * since RLE uses 1 byte, but set_basic uses 5-6 bits per symbol.
152
+ * If basic encoding isn't possible, always choose RLE.
153
+ */
154
+ DEBUGLOG(5, "Selected set_basic");
155
+ return set_basic;
156
+ }
157
+ DEBUGLOG(5, "Selected set_rle");
158
+ return set_rle;
159
+ }
160
+ if (strategy < ZSTD_lazy) {
161
+ if (isDefaultAllowed) {
162
+ size_t const staticFse_nbSeq_max = 1000;
163
+ size_t const mult = 10 - strategy;
164
+ size_t const baseLog = 3;
165
+ size_t const dynamicFse_nbSeq_min = (((size_t)1 << defaultNormLog) * mult) >> baseLog; /* 28-36 for offset, 56-72 for lengths */
166
+ assert(defaultNormLog >= 5 && defaultNormLog <= 6); /* xx_DEFAULTNORMLOG */
167
+ assert(mult <= 9 && mult >= 7);
168
+ if ( (*repeatMode == FSE_repeat_valid)
169
+ && (nbSeq < staticFse_nbSeq_max) ) {
170
+ DEBUGLOG(5, "Selected set_repeat");
171
+ return set_repeat;
172
+ }
173
+ if ( (nbSeq < dynamicFse_nbSeq_min)
174
+ || (mostFrequent < (nbSeq >> (defaultNormLog-1))) ) {
175
+ DEBUGLOG(5, "Selected set_basic");
176
+ /* The format allows default tables to be repeated, but it isn't useful.
177
+ * When using simple heuristics to select encoding type, we don't want
178
+ * to confuse these tables with dictionaries. When running more careful
179
+ * analysis, we don't need to waste time checking both repeating tables
180
+ * and default tables.
181
+ */
182
+ *repeatMode = FSE_repeat_none;
183
+ return set_basic;
184
+ }
185
+ }
186
+ } else {
187
+ size_t const basicCost = isDefaultAllowed ? ZSTD_crossEntropyCost(defaultNorm, defaultNormLog, count, max) : ERROR(GENERIC);
188
+ size_t const repeatCost = *repeatMode != FSE_repeat_none ? ZSTD_fseBitCost(prevCTable, count, max) : ERROR(GENERIC);
189
+ size_t const NCountCost = ZSTD_NCountCost(count, max, nbSeq, FSELog);
190
+ size_t const compressedCost = (NCountCost << 3) + ZSTD_entropyCost(count, max, nbSeq);
191
+
192
+ if (isDefaultAllowed) {
193
+ assert(!ZSTD_isError(basicCost));
194
+ assert(!(*repeatMode == FSE_repeat_valid && ZSTD_isError(repeatCost)));
195
+ }
196
+ assert(!ZSTD_isError(NCountCost));
197
+ assert(compressedCost < ERROR(maxCode));
198
+ DEBUGLOG(5, "Estimated bit costs: basic=%u\trepeat=%u\tcompressed=%u",
199
+ (unsigned)basicCost, (unsigned)repeatCost, (unsigned)compressedCost);
200
+ if (basicCost <= repeatCost && basicCost <= compressedCost) {
201
+ DEBUGLOG(5, "Selected set_basic");
202
+ assert(isDefaultAllowed);
203
+ *repeatMode = FSE_repeat_none;
204
+ return set_basic;
205
+ }
206
+ if (repeatCost <= compressedCost) {
207
+ DEBUGLOG(5, "Selected set_repeat");
208
+ assert(!ZSTD_isError(repeatCost));
209
+ return set_repeat;
210
+ }
211
+ assert(compressedCost < basicCost && compressedCost < repeatCost);
212
+ }
213
+ DEBUGLOG(5, "Selected set_compressed");
214
+ *repeatMode = FSE_repeat_check;
215
+ return set_compressed;
216
+ }
217
+
218
+ size_t
219
+ ZSTD_buildCTable(void* dst, size_t dstCapacity,
220
+ FSE_CTable* nextCTable, U32 FSELog, symbolEncodingType_e type,
221
+ unsigned* count, U32 max,
222
+ const BYTE* codeTable, size_t nbSeq,
223
+ const S16* defaultNorm, U32 defaultNormLog, U32 defaultMax,
224
+ const FSE_CTable* prevCTable, size_t prevCTableSize,
225
+ void* workspace, size_t workspaceSize)
226
+ {
227
+ BYTE* op = (BYTE*)dst;
228
+ const BYTE* const oend = op + dstCapacity;
229
+ DEBUGLOG(6, "ZSTD_buildCTable (dstCapacity=%u)", (unsigned)dstCapacity);
230
+
231
+ switch (type) {
232
+ case set_rle:
233
+ FORWARD_IF_ERROR(FSE_buildCTable_rle(nextCTable, (BYTE)max));
234
+ RETURN_ERROR_IF(dstCapacity==0, dstSize_tooSmall);
235
+ *op = codeTable[0];
236
+ return 1;
237
+ case set_repeat:
238
+ memcpy(nextCTable, prevCTable, prevCTableSize);
239
+ return 0;
240
+ case set_basic:
241
+ FORWARD_IF_ERROR(FSE_buildCTable_wksp(nextCTable, defaultNorm, defaultMax, defaultNormLog, workspace, workspaceSize)); /* note : could be pre-calculated */
242
+ return 0;
243
+ case set_compressed: {
244
+ S16 norm[MaxSeq + 1];
245
+ size_t nbSeq_1 = nbSeq;
246
+ const U32 tableLog = FSE_optimalTableLog(FSELog, nbSeq, max);
247
+ if (count[codeTable[nbSeq-1]] > 1) {
248
+ count[codeTable[nbSeq-1]]--;
249
+ nbSeq_1--;
250
+ }
251
+ assert(nbSeq_1 > 1);
252
+ FORWARD_IF_ERROR(FSE_normalizeCount(norm, tableLog, count, nbSeq_1, max));
253
+ { size_t const NCountSize = FSE_writeNCount(op, oend - op, norm, max, tableLog); /* overflow protected */
254
+ FORWARD_IF_ERROR(NCountSize);
255
+ FORWARD_IF_ERROR(FSE_buildCTable_wksp(nextCTable, norm, max, tableLog, workspace, workspaceSize));
256
+ return NCountSize;
257
+ }
258
+ }
259
+ default: assert(0); RETURN_ERROR(GENERIC);
260
+ }
261
+ }
262
+
263
+ FORCE_INLINE_TEMPLATE size_t
264
+ ZSTD_encodeSequences_body(
265
+ void* dst, size_t dstCapacity,
266
+ FSE_CTable const* CTable_MatchLength, BYTE const* mlCodeTable,
267
+ FSE_CTable const* CTable_OffsetBits, BYTE const* ofCodeTable,
268
+ FSE_CTable const* CTable_LitLength, BYTE const* llCodeTable,
269
+ seqDef const* sequences, size_t nbSeq, int longOffsets)
270
+ {
271
+ BIT_CStream_t blockStream;
272
+ FSE_CState_t stateMatchLength;
273
+ FSE_CState_t stateOffsetBits;
274
+ FSE_CState_t stateLitLength;
275
+
276
+ RETURN_ERROR_IF(
277
+ ERR_isError(BIT_initCStream(&blockStream, dst, dstCapacity)),
278
+ dstSize_tooSmall, "not enough space remaining");
279
+ DEBUGLOG(6, "available space for bitstream : %i (dstCapacity=%u)",
280
+ (int)(blockStream.endPtr - blockStream.startPtr),
281
+ (unsigned)dstCapacity);
282
+
283
+ /* first symbols */
284
+ FSE_initCState2(&stateMatchLength, CTable_MatchLength, mlCodeTable[nbSeq-1]);
285
+ FSE_initCState2(&stateOffsetBits, CTable_OffsetBits, ofCodeTable[nbSeq-1]);
286
+ FSE_initCState2(&stateLitLength, CTable_LitLength, llCodeTable[nbSeq-1]);
287
+ BIT_addBits(&blockStream, sequences[nbSeq-1].litLength, LL_bits[llCodeTable[nbSeq-1]]);
288
+ if (MEM_32bits()) BIT_flushBits(&blockStream);
289
+ BIT_addBits(&blockStream, sequences[nbSeq-1].matchLength, ML_bits[mlCodeTable[nbSeq-1]]);
290
+ if (MEM_32bits()) BIT_flushBits(&blockStream);
291
+ if (longOffsets) {
292
+ U32 const ofBits = ofCodeTable[nbSeq-1];
293
+ int const extraBits = ofBits - MIN(ofBits, STREAM_ACCUMULATOR_MIN-1);
294
+ if (extraBits) {
295
+ BIT_addBits(&blockStream, sequences[nbSeq-1].offset, extraBits);
296
+ BIT_flushBits(&blockStream);
297
+ }
298
+ BIT_addBits(&blockStream, sequences[nbSeq-1].offset >> extraBits,
299
+ ofBits - extraBits);
300
+ } else {
301
+ BIT_addBits(&blockStream, sequences[nbSeq-1].offset, ofCodeTable[nbSeq-1]);
302
+ }
303
+ BIT_flushBits(&blockStream);
304
+
305
+ { size_t n;
306
+ for (n=nbSeq-2 ; n<nbSeq ; n--) { /* intentional underflow */
307
+ BYTE const llCode = llCodeTable[n];
308
+ BYTE const ofCode = ofCodeTable[n];
309
+ BYTE const mlCode = mlCodeTable[n];
310
+ U32 const llBits = LL_bits[llCode];
311
+ U32 const ofBits = ofCode;
312
+ U32 const mlBits = ML_bits[mlCode];
313
+ DEBUGLOG(6, "encoding: litlen:%2u - matchlen:%2u - offCode:%7u",
314
+ (unsigned)sequences[n].litLength,
315
+ (unsigned)sequences[n].matchLength + MINMATCH,
316
+ (unsigned)sequences[n].offset);
317
+ /* 32b*/ /* 64b*/
318
+ /* (7)*/ /* (7)*/
319
+ FSE_encodeSymbol(&blockStream, &stateOffsetBits, ofCode); /* 15 */ /* 15 */
320
+ FSE_encodeSymbol(&blockStream, &stateMatchLength, mlCode); /* 24 */ /* 24 */
321
+ if (MEM_32bits()) BIT_flushBits(&blockStream); /* (7)*/
322
+ FSE_encodeSymbol(&blockStream, &stateLitLength, llCode); /* 16 */ /* 33 */
323
+ if (MEM_32bits() || (ofBits+mlBits+llBits >= 64-7-(LLFSELog+MLFSELog+OffFSELog)))
324
+ BIT_flushBits(&blockStream); /* (7)*/
325
+ BIT_addBits(&blockStream, sequences[n].litLength, llBits);
326
+ if (MEM_32bits() && ((llBits+mlBits)>24)) BIT_flushBits(&blockStream);
327
+ BIT_addBits(&blockStream, sequences[n].matchLength, mlBits);
328
+ if (MEM_32bits() || (ofBits+mlBits+llBits > 56)) BIT_flushBits(&blockStream);
329
+ if (longOffsets) {
330
+ int const extraBits = ofBits - MIN(ofBits, STREAM_ACCUMULATOR_MIN-1);
331
+ if (extraBits) {
332
+ BIT_addBits(&blockStream, sequences[n].offset, extraBits);
333
+ BIT_flushBits(&blockStream); /* (7)*/
334
+ }
335
+ BIT_addBits(&blockStream, sequences[n].offset >> extraBits,
336
+ ofBits - extraBits); /* 31 */
337
+ } else {
338
+ BIT_addBits(&blockStream, sequences[n].offset, ofBits); /* 31 */
339
+ }
340
+ BIT_flushBits(&blockStream); /* (7)*/
341
+ DEBUGLOG(7, "remaining space : %i", (int)(blockStream.endPtr - blockStream.ptr));
342
+ } }
343
+
344
+ DEBUGLOG(6, "ZSTD_encodeSequences: flushing ML state with %u bits", stateMatchLength.stateLog);
345
+ FSE_flushCState(&blockStream, &stateMatchLength);
346
+ DEBUGLOG(6, "ZSTD_encodeSequences: flushing Off state with %u bits", stateOffsetBits.stateLog);
347
+ FSE_flushCState(&blockStream, &stateOffsetBits);
348
+ DEBUGLOG(6, "ZSTD_encodeSequences: flushing LL state with %u bits", stateLitLength.stateLog);
349
+ FSE_flushCState(&blockStream, &stateLitLength);
350
+
351
+ { size_t const streamSize = BIT_closeCStream(&blockStream);
352
+ RETURN_ERROR_IF(streamSize==0, dstSize_tooSmall, "not enough space");
353
+ return streamSize;
354
+ }
355
+ }
356
+
357
+ static size_t
358
+ ZSTD_encodeSequences_default(
359
+ void* dst, size_t dstCapacity,
360
+ FSE_CTable const* CTable_MatchLength, BYTE const* mlCodeTable,
361
+ FSE_CTable const* CTable_OffsetBits, BYTE const* ofCodeTable,
362
+ FSE_CTable const* CTable_LitLength, BYTE const* llCodeTable,
363
+ seqDef const* sequences, size_t nbSeq, int longOffsets)
364
+ {
365
+ return ZSTD_encodeSequences_body(dst, dstCapacity,
366
+ CTable_MatchLength, mlCodeTable,
367
+ CTable_OffsetBits, ofCodeTable,
368
+ CTable_LitLength, llCodeTable,
369
+ sequences, nbSeq, longOffsets);
370
+ }
371
+
372
+
373
+ #if DYNAMIC_BMI2
374
+
375
+ static TARGET_ATTRIBUTE("bmi2") size_t
376
+ ZSTD_encodeSequences_bmi2(
377
+ void* dst, size_t dstCapacity,
378
+ FSE_CTable const* CTable_MatchLength, BYTE const* mlCodeTable,
379
+ FSE_CTable const* CTable_OffsetBits, BYTE const* ofCodeTable,
380
+ FSE_CTable const* CTable_LitLength, BYTE const* llCodeTable,
381
+ seqDef const* sequences, size_t nbSeq, int longOffsets)
382
+ {
383
+ return ZSTD_encodeSequences_body(dst, dstCapacity,
384
+ CTable_MatchLength, mlCodeTable,
385
+ CTable_OffsetBits, ofCodeTable,
386
+ CTable_LitLength, llCodeTable,
387
+ sequences, nbSeq, longOffsets);
388
+ }
389
+
390
+ #endif
391
+
392
+ size_t ZSTD_encodeSequences(
393
+ void* dst, size_t dstCapacity,
394
+ FSE_CTable const* CTable_MatchLength, BYTE const* mlCodeTable,
395
+ FSE_CTable const* CTable_OffsetBits, BYTE const* ofCodeTable,
396
+ FSE_CTable const* CTable_LitLength, BYTE const* llCodeTable,
397
+ seqDef const* sequences, size_t nbSeq, int longOffsets, int bmi2)
398
+ {
399
+ DEBUGLOG(5, "ZSTD_encodeSequences: dstCapacity = %u", (unsigned)dstCapacity);
400
+ #if DYNAMIC_BMI2
401
+ if (bmi2) {
402
+ return ZSTD_encodeSequences_bmi2(dst, dstCapacity,
403
+ CTable_MatchLength, mlCodeTable,
404
+ CTable_OffsetBits, ofCodeTable,
405
+ CTable_LitLength, llCodeTable,
406
+ sequences, nbSeq, longOffsets);
407
+ }
408
+ #endif
409
+ (void)bmi2;
410
+ return ZSTD_encodeSequences_default(dst, dstCapacity,
411
+ CTable_MatchLength, mlCodeTable,
412
+ CTable_OffsetBits, ofCodeTable,
413
+ CTable_LitLength, llCodeTable,
414
+ sequences, nbSeq, longOffsets);
415
+ }