extzstd 0.2 → 0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. checksums.yaml +4 -4
  2. data/HISTORY.ja.md +13 -0
  3. data/README.md +17 -14
  4. data/contrib/zstd/{NEWS → CHANGELOG} +115 -2
  5. data/contrib/zstd/CODE_OF_CONDUCT.md +5 -0
  6. data/contrib/zstd/Makefile +99 -53
  7. data/contrib/zstd/README.md +59 -39
  8. data/contrib/zstd/TESTING.md +1 -1
  9. data/contrib/zstd/appveyor.yml +17 -6
  10. data/contrib/zstd/lib/BUCK +29 -2
  11. data/contrib/zstd/lib/Makefile +118 -21
  12. data/contrib/zstd/lib/README.md +84 -44
  13. data/contrib/zstd/lib/common/bitstream.h +17 -33
  14. data/contrib/zstd/lib/common/compiler.h +62 -8
  15. data/contrib/zstd/lib/common/cpu.h +215 -0
  16. data/contrib/zstd/lib/common/debug.c +44 -0
  17. data/contrib/zstd/lib/common/debug.h +134 -0
  18. data/contrib/zstd/lib/common/entropy_common.c +16 -1
  19. data/contrib/zstd/lib/common/error_private.c +7 -0
  20. data/contrib/zstd/lib/common/fse.h +48 -44
  21. data/contrib/zstd/lib/common/fse_decompress.c +3 -3
  22. data/contrib/zstd/lib/common/huf.h +169 -113
  23. data/contrib/zstd/lib/common/mem.h +20 -2
  24. data/contrib/zstd/lib/common/pool.c +135 -49
  25. data/contrib/zstd/lib/common/pool.h +40 -21
  26. data/contrib/zstd/lib/common/threading.c +2 -2
  27. data/contrib/zstd/lib/common/threading.h +12 -12
  28. data/contrib/zstd/lib/common/xxhash.c +3 -2
  29. data/contrib/zstd/lib/common/zstd_common.c +3 -6
  30. data/contrib/zstd/lib/common/zstd_errors.h +17 -7
  31. data/contrib/zstd/lib/common/zstd_internal.h +76 -48
  32. data/contrib/zstd/lib/compress/fse_compress.c +89 -209
  33. data/contrib/zstd/lib/compress/hist.c +203 -0
  34. data/contrib/zstd/lib/compress/hist.h +95 -0
  35. data/contrib/zstd/lib/compress/huf_compress.c +188 -80
  36. data/contrib/zstd/lib/compress/zstd_compress.c +2500 -1203
  37. data/contrib/zstd/lib/compress/zstd_compress_internal.h +463 -62
  38. data/contrib/zstd/lib/compress/zstd_double_fast.c +321 -131
  39. data/contrib/zstd/lib/compress/zstd_double_fast.h +13 -4
  40. data/contrib/zstd/lib/compress/zstd_fast.c +335 -108
  41. data/contrib/zstd/lib/compress/zstd_fast.h +12 -6
  42. data/contrib/zstd/lib/compress/zstd_lazy.c +654 -313
  43. data/contrib/zstd/lib/compress/zstd_lazy.h +44 -16
  44. data/contrib/zstd/lib/compress/zstd_ldm.c +310 -420
  45. data/contrib/zstd/lib/compress/zstd_ldm.h +63 -26
  46. data/contrib/zstd/lib/compress/zstd_opt.c +773 -325
  47. data/contrib/zstd/lib/compress/zstd_opt.h +31 -5
  48. data/contrib/zstd/lib/compress/zstdmt_compress.c +1468 -518
  49. data/contrib/zstd/lib/compress/zstdmt_compress.h +96 -45
  50. data/contrib/zstd/lib/decompress/huf_decompress.c +518 -282
  51. data/contrib/zstd/lib/decompress/zstd_ddict.c +240 -0
  52. data/contrib/zstd/lib/decompress/zstd_ddict.h +44 -0
  53. data/contrib/zstd/lib/decompress/zstd_decompress.c +613 -1513
  54. data/contrib/zstd/lib/decompress/zstd_decompress_block.c +1311 -0
  55. data/contrib/zstd/lib/decompress/zstd_decompress_block.h +59 -0
  56. data/contrib/zstd/lib/decompress/zstd_decompress_internal.h +175 -0
  57. data/contrib/zstd/lib/dictBuilder/cover.c +194 -113
  58. data/contrib/zstd/lib/dictBuilder/cover.h +112 -0
  59. data/contrib/zstd/lib/dictBuilder/divsufsort.c +3 -3
  60. data/contrib/zstd/lib/dictBuilder/fastcover.c +740 -0
  61. data/contrib/zstd/lib/dictBuilder/zdict.c +142 -106
  62. data/contrib/zstd/lib/dictBuilder/zdict.h +115 -49
  63. data/contrib/zstd/lib/legacy/zstd_legacy.h +44 -12
  64. data/contrib/zstd/lib/legacy/zstd_v01.c +41 -10
  65. data/contrib/zstd/lib/legacy/zstd_v01.h +12 -7
  66. data/contrib/zstd/lib/legacy/zstd_v02.c +37 -12
  67. data/contrib/zstd/lib/legacy/zstd_v02.h +12 -7
  68. data/contrib/zstd/lib/legacy/zstd_v03.c +38 -12
  69. data/contrib/zstd/lib/legacy/zstd_v03.h +12 -7
  70. data/contrib/zstd/lib/legacy/zstd_v04.c +55 -174
  71. data/contrib/zstd/lib/legacy/zstd_v04.h +12 -7
  72. data/contrib/zstd/lib/legacy/zstd_v05.c +59 -31
  73. data/contrib/zstd/lib/legacy/zstd_v05.h +12 -7
  74. data/contrib/zstd/lib/legacy/zstd_v06.c +48 -20
  75. data/contrib/zstd/lib/legacy/zstd_v06.h +10 -5
  76. data/contrib/zstd/lib/legacy/zstd_v07.c +62 -29
  77. data/contrib/zstd/lib/legacy/zstd_v07.h +10 -5
  78. data/contrib/zstd/lib/zstd.h +1346 -832
  79. data/ext/extzstd.c +27 -19
  80. data/ext/extzstd_stream.c +20 -4
  81. data/ext/zstd_compress.c +1 -0
  82. data/ext/zstd_decompress.c +4 -0
  83. data/ext/zstd_dictbuilder.c +4 -0
  84. data/ext/zstd_dictbuilder_fastcover.c +5 -0
  85. data/lib/extzstd.rb +52 -220
  86. data/lib/extzstd/version.rb +1 -1
  87. metadata +21 -7
  88. data/contrib/zstd/circle.yml +0 -63
@@ -0,0 +1,203 @@
1
+ /* ******************************************************************
2
+ hist : Histogram functions
3
+ part of Finite State Entropy project
4
+ Copyright (C) 2013-present, Yann Collet.
5
+
6
+ BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
7
+
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions are
10
+ met:
11
+
12
+ * Redistributions of source code must retain the above copyright
13
+ notice, this list of conditions and the following disclaimer.
14
+ * Redistributions in binary form must reproduce the above
15
+ copyright notice, this list of conditions and the following disclaimer
16
+ in the documentation and/or other materials provided with the
17
+ distribution.
18
+
19
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
+
31
+ You can contact the author at :
32
+ - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy
33
+ - Public forum : https://groups.google.com/forum/#!forum/lz4c
34
+ ****************************************************************** */
35
+
36
+ /* --- dependencies --- */
37
+ #include "mem.h" /* U32, BYTE, etc. */
38
+ #include "debug.h" /* assert, DEBUGLOG */
39
+ #include "error_private.h" /* ERROR */
40
+ #include "hist.h"
41
+
42
+
43
+ /* --- Error management --- */
44
+ unsigned HIST_isError(size_t code) { return ERR_isError(code); }
45
+
46
+ /*-**************************************************************
47
+ * Histogram functions
48
+ ****************************************************************/
49
+ unsigned HIST_count_simple(unsigned* count, unsigned* maxSymbolValuePtr,
50
+ const void* src, size_t srcSize)
51
+ {
52
+ const BYTE* ip = (const BYTE*)src;
53
+ const BYTE* const end = ip + srcSize;
54
+ unsigned maxSymbolValue = *maxSymbolValuePtr;
55
+ unsigned largestCount=0;
56
+
57
+ memset(count, 0, (maxSymbolValue+1) * sizeof(*count));
58
+ if (srcSize==0) { *maxSymbolValuePtr = 0; return 0; }
59
+
60
+ while (ip<end) {
61
+ assert(*ip <= maxSymbolValue);
62
+ count[*ip++]++;
63
+ }
64
+
65
+ while (!count[maxSymbolValue]) maxSymbolValue--;
66
+ *maxSymbolValuePtr = maxSymbolValue;
67
+
68
+ { U32 s;
69
+ for (s=0; s<=maxSymbolValue; s++)
70
+ if (count[s] > largestCount) largestCount = count[s];
71
+ }
72
+
73
+ return largestCount;
74
+ }
75
+
76
+ typedef enum { trustInput, checkMaxSymbolValue } HIST_checkInput_e;
77
+
78
+ /* HIST_count_parallel_wksp() :
79
+ * store histogram into 4 intermediate tables, recombined at the end.
80
+ * this design makes better use of OoO cpus,
81
+ * and is noticeably faster when some values are heavily repeated.
82
+ * But it needs some additional workspace for intermediate tables.
83
+ * `workSpace` size must be a table of size >= HIST_WKSP_SIZE_U32.
84
+ * @return : largest histogram frequency,
85
+ * or an error code (notably when histogram would be larger than *maxSymbolValuePtr). */
86
+ static size_t HIST_count_parallel_wksp(
87
+ unsigned* count, unsigned* maxSymbolValuePtr,
88
+ const void* source, size_t sourceSize,
89
+ HIST_checkInput_e check,
90
+ U32* const workSpace)
91
+ {
92
+ const BYTE* ip = (const BYTE*)source;
93
+ const BYTE* const iend = ip+sourceSize;
94
+ unsigned maxSymbolValue = *maxSymbolValuePtr;
95
+ unsigned max=0;
96
+ U32* const Counting1 = workSpace;
97
+ U32* const Counting2 = Counting1 + 256;
98
+ U32* const Counting3 = Counting2 + 256;
99
+ U32* const Counting4 = Counting3 + 256;
100
+
101
+ memset(workSpace, 0, 4*256*sizeof(unsigned));
102
+
103
+ /* safety checks */
104
+ if (!sourceSize) {
105
+ memset(count, 0, maxSymbolValue + 1);
106
+ *maxSymbolValuePtr = 0;
107
+ return 0;
108
+ }
109
+ if (!maxSymbolValue) maxSymbolValue = 255; /* 0 == default */
110
+
111
+ /* by stripes of 16 bytes */
112
+ { U32 cached = MEM_read32(ip); ip += 4;
113
+ while (ip < iend-15) {
114
+ U32 c = cached; cached = MEM_read32(ip); ip += 4;
115
+ Counting1[(BYTE) c ]++;
116
+ Counting2[(BYTE)(c>>8) ]++;
117
+ Counting3[(BYTE)(c>>16)]++;
118
+ Counting4[ c>>24 ]++;
119
+ c = cached; cached = MEM_read32(ip); ip += 4;
120
+ Counting1[(BYTE) c ]++;
121
+ Counting2[(BYTE)(c>>8) ]++;
122
+ Counting3[(BYTE)(c>>16)]++;
123
+ Counting4[ c>>24 ]++;
124
+ c = cached; cached = MEM_read32(ip); ip += 4;
125
+ Counting1[(BYTE) c ]++;
126
+ Counting2[(BYTE)(c>>8) ]++;
127
+ Counting3[(BYTE)(c>>16)]++;
128
+ Counting4[ c>>24 ]++;
129
+ c = cached; cached = MEM_read32(ip); ip += 4;
130
+ Counting1[(BYTE) c ]++;
131
+ Counting2[(BYTE)(c>>8) ]++;
132
+ Counting3[(BYTE)(c>>16)]++;
133
+ Counting4[ c>>24 ]++;
134
+ }
135
+ ip-=4;
136
+ }
137
+
138
+ /* finish last symbols */
139
+ while (ip<iend) Counting1[*ip++]++;
140
+
141
+ if (check) { /* verify stats will fit into destination table */
142
+ U32 s; for (s=255; s>maxSymbolValue; s--) {
143
+ Counting1[s] += Counting2[s] + Counting3[s] + Counting4[s];
144
+ if (Counting1[s]) return ERROR(maxSymbolValue_tooSmall);
145
+ } }
146
+
147
+ { U32 s;
148
+ if (maxSymbolValue > 255) maxSymbolValue = 255;
149
+ for (s=0; s<=maxSymbolValue; s++) {
150
+ count[s] = Counting1[s] + Counting2[s] + Counting3[s] + Counting4[s];
151
+ if (count[s] > max) max = count[s];
152
+ } }
153
+
154
+ while (!count[maxSymbolValue]) maxSymbolValue--;
155
+ *maxSymbolValuePtr = maxSymbolValue;
156
+ return (size_t)max;
157
+ }
158
+
159
+ /* HIST_countFast_wksp() :
160
+ * Same as HIST_countFast(), but using an externally provided scratch buffer.
161
+ * `workSpace` is a writable buffer which must be 4-bytes aligned,
162
+ * `workSpaceSize` must be >= HIST_WKSP_SIZE
163
+ */
164
+ size_t HIST_countFast_wksp(unsigned* count, unsigned* maxSymbolValuePtr,
165
+ const void* source, size_t sourceSize,
166
+ void* workSpace, size_t workSpaceSize)
167
+ {
168
+ if (sourceSize < 1500) /* heuristic threshold */
169
+ return HIST_count_simple(count, maxSymbolValuePtr, source, sourceSize);
170
+ if ((size_t)workSpace & 3) return ERROR(GENERIC); /* must be aligned on 4-bytes boundaries */
171
+ if (workSpaceSize < HIST_WKSP_SIZE) return ERROR(workSpace_tooSmall);
172
+ return HIST_count_parallel_wksp(count, maxSymbolValuePtr, source, sourceSize, trustInput, (U32*)workSpace);
173
+ }
174
+
175
+ /* fast variant (unsafe : won't check if src contains values beyond count[] limit) */
176
+ size_t HIST_countFast(unsigned* count, unsigned* maxSymbolValuePtr,
177
+ const void* source, size_t sourceSize)
178
+ {
179
+ unsigned tmpCounters[HIST_WKSP_SIZE_U32];
180
+ return HIST_countFast_wksp(count, maxSymbolValuePtr, source, sourceSize, tmpCounters, sizeof(tmpCounters));
181
+ }
182
+
183
+ /* HIST_count_wksp() :
184
+ * Same as HIST_count(), but using an externally provided scratch buffer.
185
+ * `workSpace` size must be table of >= HIST_WKSP_SIZE_U32 unsigned */
186
+ size_t HIST_count_wksp(unsigned* count, unsigned* maxSymbolValuePtr,
187
+ const void* source, size_t sourceSize,
188
+ void* workSpace, size_t workSpaceSize)
189
+ {
190
+ if ((size_t)workSpace & 3) return ERROR(GENERIC); /* must be aligned on 4-bytes boundaries */
191
+ if (workSpaceSize < HIST_WKSP_SIZE) return ERROR(workSpace_tooSmall);
192
+ if (*maxSymbolValuePtr < 255)
193
+ return HIST_count_parallel_wksp(count, maxSymbolValuePtr, source, sourceSize, checkMaxSymbolValue, (U32*)workSpace);
194
+ *maxSymbolValuePtr = 255;
195
+ return HIST_countFast_wksp(count, maxSymbolValuePtr, source, sourceSize, workSpace, workSpaceSize);
196
+ }
197
+
198
+ size_t HIST_count(unsigned* count, unsigned* maxSymbolValuePtr,
199
+ const void* src, size_t srcSize)
200
+ {
201
+ unsigned tmpCounters[HIST_WKSP_SIZE_U32];
202
+ return HIST_count_wksp(count, maxSymbolValuePtr, src, srcSize, tmpCounters, sizeof(tmpCounters));
203
+ }
@@ -0,0 +1,95 @@
1
+ /* ******************************************************************
2
+ hist : Histogram functions
3
+ part of Finite State Entropy project
4
+ Copyright (C) 2013-present, Yann Collet.
5
+
6
+ BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
7
+
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions are
10
+ met:
11
+
12
+ * Redistributions of source code must retain the above copyright
13
+ notice, this list of conditions and the following disclaimer.
14
+ * Redistributions in binary form must reproduce the above
15
+ copyright notice, this list of conditions and the following disclaimer
16
+ in the documentation and/or other materials provided with the
17
+ distribution.
18
+
19
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
+
31
+ You can contact the author at :
32
+ - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy
33
+ - Public forum : https://groups.google.com/forum/#!forum/lz4c
34
+ ****************************************************************** */
35
+
36
+ /* --- dependencies --- */
37
+ #include <stddef.h> /* size_t */
38
+
39
+
40
+ /* --- simple histogram functions --- */
41
+
42
+ /*! HIST_count():
43
+ * Provides the precise count of each byte within a table 'count'.
44
+ * 'count' is a table of unsigned int, of minimum size (*maxSymbolValuePtr+1).
45
+ * Updates *maxSymbolValuePtr with actual largest symbol value detected.
46
+ * @return : count of the most frequent symbol (which isn't identified).
47
+ * or an error code, which can be tested using HIST_isError().
48
+ * note : if return == srcSize, there is only one symbol.
49
+ */
50
+ size_t HIST_count(unsigned* count, unsigned* maxSymbolValuePtr,
51
+ const void* src, size_t srcSize);
52
+
53
+ unsigned HIST_isError(size_t code); /**< tells if a return value is an error code */
54
+
55
+
56
+ /* --- advanced histogram functions --- */
57
+
58
+ #define HIST_WKSP_SIZE_U32 1024
59
+ #define HIST_WKSP_SIZE (HIST_WKSP_SIZE_U32 * sizeof(unsigned))
60
+ /** HIST_count_wksp() :
61
+ * Same as HIST_count(), but using an externally provided scratch buffer.
62
+ * Benefit is this function will use very little stack space.
63
+ * `workSpace` is a writable buffer which must be 4-bytes aligned,
64
+ * `workSpaceSize` must be >= HIST_WKSP_SIZE
65
+ */
66
+ size_t HIST_count_wksp(unsigned* count, unsigned* maxSymbolValuePtr,
67
+ const void* src, size_t srcSize,
68
+ void* workSpace, size_t workSpaceSize);
69
+
70
+ /** HIST_countFast() :
71
+ * same as HIST_count(), but blindly trusts that all byte values within src are <= *maxSymbolValuePtr.
72
+ * This function is unsafe, and will segfault if any value within `src` is `> *maxSymbolValuePtr`
73
+ */
74
+ size_t HIST_countFast(unsigned* count, unsigned* maxSymbolValuePtr,
75
+ const void* src, size_t srcSize);
76
+
77
+ /** HIST_countFast_wksp() :
78
+ * Same as HIST_countFast(), but using an externally provided scratch buffer.
79
+ * `workSpace` is a writable buffer which must be 4-bytes aligned,
80
+ * `workSpaceSize` must be >= HIST_WKSP_SIZE
81
+ */
82
+ size_t HIST_countFast_wksp(unsigned* count, unsigned* maxSymbolValuePtr,
83
+ const void* src, size_t srcSize,
84
+ void* workSpace, size_t workSpaceSize);
85
+
86
+ /*! HIST_count_simple() :
87
+ * Same as HIST_countFast(), this function is unsafe,
88
+ * and will segfault if any value within `src` is `> *maxSymbolValuePtr`.
89
+ * It is also a bit slower for large inputs.
90
+ * However, it does not need any additional memory (not even on stack).
91
+ * @return : count of the most frequent symbol.
92
+ * Note this function doesn't produce any error (i.e. it must succeed).
93
+ */
94
+ unsigned HIST_count_simple(unsigned* count, unsigned* maxSymbolValuePtr,
95
+ const void* src, size_t srcSize);
@@ -45,7 +45,9 @@
45
45
  ****************************************************************/
46
46
  #include <string.h> /* memcpy, memset */
47
47
  #include <stdio.h> /* printf (debug) */
48
+ #include "compiler.h"
48
49
  #include "bitstream.h"
50
+ #include "hist.h"
49
51
  #define FSE_STATIC_LINKING_ONLY /* FSE_optimalTableLog_internal */
50
52
  #include "fse.h" /* header compression */
51
53
  #define HUF_STATIC_LINKING_ONLY
@@ -57,7 +59,7 @@
57
59
  * Error Management
58
60
  ****************************************************************/
59
61
  #define HUF_isError ERR_isError
60
- #define HUF_STATIC_ASSERT(c) { enum { HUF_static_assert = 1/(int)(!!(c)) }; } /* use only *after* variable declarations */
62
+ #define HUF_STATIC_ASSERT(c) DEBUG_STATIC_ASSERT(c) /* use only *after* variable declarations */
61
63
  #define CHECK_V_F(e, f) size_t const e = f; if (ERR_isError(e)) return e
62
64
  #define CHECK_F(f) { CHECK_V_F(_var_err__, f); }
63
65
 
@@ -80,28 +82,28 @@ unsigned HUF_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxS
80
82
  * Note : all elements within weightTable are supposed to be <= HUF_TABLELOG_MAX.
81
83
  */
82
84
  #define MAX_FSE_TABLELOG_FOR_HUFF_HEADER 6
83
- size_t HUF_compressWeights (void* dst, size_t dstSize, const void* weightTable, size_t wtSize)
85
+ static size_t HUF_compressWeights (void* dst, size_t dstSize, const void* weightTable, size_t wtSize)
84
86
  {
85
87
  BYTE* const ostart = (BYTE*) dst;
86
88
  BYTE* op = ostart;
87
89
  BYTE* const oend = ostart + dstSize;
88
90
 
89
- U32 maxSymbolValue = HUF_TABLELOG_MAX;
91
+ unsigned maxSymbolValue = HUF_TABLELOG_MAX;
90
92
  U32 tableLog = MAX_FSE_TABLELOG_FOR_HUFF_HEADER;
91
93
 
92
94
  FSE_CTable CTable[FSE_CTABLE_SIZE_U32(MAX_FSE_TABLELOG_FOR_HUFF_HEADER, HUF_TABLELOG_MAX)];
93
95
  BYTE scratchBuffer[1<<MAX_FSE_TABLELOG_FOR_HUFF_HEADER];
94
96
 
95
- U32 count[HUF_TABLELOG_MAX+1];
97
+ unsigned count[HUF_TABLELOG_MAX+1];
96
98
  S16 norm[HUF_TABLELOG_MAX+1];
97
99
 
98
100
  /* init conditions */
99
101
  if (wtSize <= 1) return 0; /* Not compressible */
100
102
 
101
103
  /* Scan input and build symbol stats */
102
- { CHECK_V_F(maxCount, FSE_count_simple(count, &maxSymbolValue, weightTable, wtSize) );
104
+ { unsigned const maxCount = HIST_count_simple(count, &maxSymbolValue, weightTable, wtSize); /* never fails */
103
105
  if (maxCount == wtSize) return 1; /* only a single symbol in src : rle */
104
- if (maxCount == 1) return 0; /* each symbol present maximum once => not compressible */
106
+ if (maxCount == 1) return 0; /* each symbol present maximum once => not compressible */
105
107
  }
106
108
 
107
109
  tableLog = FSE_optimalTableLog(tableLog, wtSize, maxSymbolValue);
@@ -132,7 +134,7 @@ struct HUF_CElt_s {
132
134
  `CTable` : Huffman tree to save, using huf representation.
133
135
  @return : size of saved CTable */
134
136
  size_t HUF_writeCTable (void* dst, size_t maxDstSize,
135
- const HUF_CElt* CTable, U32 maxSymbolValue, U32 huffLog)
137
+ const HUF_CElt* CTable, unsigned maxSymbolValue, unsigned huffLog)
136
138
  {
137
139
  BYTE bitsToWeight[HUF_TABLELOG_MAX + 1]; /* precomputed conversion table */
138
140
  BYTE huffWeight[HUF_SYMBOLVALUE_MAX];
@@ -167,7 +169,7 @@ size_t HUF_writeCTable (void* dst, size_t maxDstSize,
167
169
  }
168
170
 
169
171
 
170
- size_t HUF_readCTable (HUF_CElt* CTable, U32* maxSymbolValuePtr, const void* src, size_t srcSize)
172
+ size_t HUF_readCTable (HUF_CElt* CTable, unsigned* maxSymbolValuePtr, const void* src, size_t srcSize)
171
173
  {
172
174
  BYTE huffWeight[HUF_SYMBOLVALUE_MAX + 1]; /* init not required, even though some static analyzer may complain */
173
175
  U32 rankVal[HUF_TABLELOG_ABSOLUTEMAX + 1]; /* large enough for values from 0 to 16 */
@@ -215,6 +217,13 @@ size_t HUF_readCTable (HUF_CElt* CTable, U32* maxSymbolValuePtr, const void* src
215
217
  return readSize;
216
218
  }
217
219
 
220
+ U32 HUF_getNbBits(const void* symbolTable, U32 symbolValue)
221
+ {
222
+ const HUF_CElt* table = (const HUF_CElt*)symbolTable;
223
+ assert(symbolValue <= HUF_SYMBOLVALUE_MAX);
224
+ return table[symbolValue].nbBits;
225
+ }
226
+
218
227
 
219
228
  typedef struct nodeElt_s {
220
229
  U32 count;
@@ -306,7 +315,7 @@ typedef struct {
306
315
  U32 current;
307
316
  } rankPos;
308
317
 
309
- static void HUF_sort(nodeElt* huffNode, const U32* count, U32 maxSymbolValue)
318
+ static void HUF_sort(nodeElt* huffNode, const unsigned* count, U32 maxSymbolValue)
310
319
  {
311
320
  rankPos rank[32];
312
321
  U32 n;
@@ -322,7 +331,10 @@ static void HUF_sort(nodeElt* huffNode, const U32* count, U32 maxSymbolValue)
322
331
  U32 const c = count[n];
323
332
  U32 const r = BIT_highbit32(c+1) + 1;
324
333
  U32 pos = rank[r].current++;
325
- while ((pos > rank[r].base) && (c > huffNode[pos-1].count)) huffNode[pos]=huffNode[pos-1], pos--;
334
+ while ((pos > rank[r].base) && (c > huffNode[pos-1].count)) {
335
+ huffNode[pos] = huffNode[pos-1];
336
+ pos--;
337
+ }
326
338
  huffNode[pos].count = c;
327
339
  huffNode[pos].byte = (BYTE)n;
328
340
  }
@@ -331,11 +343,11 @@ static void HUF_sort(nodeElt* huffNode, const U32* count, U32 maxSymbolValue)
331
343
 
332
344
  /** HUF_buildCTable_wksp() :
333
345
  * Same as HUF_buildCTable(), but using externally allocated scratch buffer.
334
- * `workSpace` must be aligned on 4-bytes boundaries, and be at least as large as a table of 1024 unsigned.
346
+ * `workSpace` must be aligned on 4-bytes boundaries, and be at least as large as a table of HUF_CTABLE_WORKSPACE_SIZE_U32 unsigned.
335
347
  */
336
348
  #define STARTNODE (HUF_SYMBOLVALUE_MAX+1)
337
- typedef nodeElt huffNodeTable[2*HUF_SYMBOLVALUE_MAX+1 +1];
338
- size_t HUF_buildCTable_wksp (HUF_CElt* tree, const U32* count, U32 maxSymbolValue, U32 maxNbBits, void* workSpace, size_t wkspSize)
349
+ typedef nodeElt huffNodeTable[HUF_CTABLE_WORKSPACE_SIZE_U32];
350
+ size_t HUF_buildCTable_wksp (HUF_CElt* tree, const unsigned* count, U32 maxSymbolValue, U32 maxNbBits, void* workSpace, size_t wkspSize)
339
351
  {
340
352
  nodeElt* const huffNode0 = (nodeElt*)workSpace;
341
353
  nodeElt* const huffNode = huffNode0+1;
@@ -345,9 +357,10 @@ size_t HUF_buildCTable_wksp (HUF_CElt* tree, const U32* count, U32 maxSymbolValu
345
357
  U32 nodeRoot;
346
358
 
347
359
  /* safety checks */
348
- if (wkspSize < sizeof(huffNodeTable)) return ERROR(GENERIC); /* workSpace is not large enough */
360
+ if (((size_t)workSpace & 3) != 0) return ERROR(GENERIC); /* must be aligned on 4-bytes boundaries */
361
+ if (wkspSize < sizeof(huffNodeTable)) return ERROR(workSpace_tooSmall);
349
362
  if (maxNbBits == 0) maxNbBits = HUF_TABLELOG_DEFAULT;
350
- if (maxSymbolValue > HUF_SYMBOLVALUE_MAX) return ERROR(GENERIC);
363
+ if (maxSymbolValue > HUF_SYMBOLVALUE_MAX) return ERROR(maxSymbolValue_tooLarge);
351
364
  memset(huffNode0, 0, sizeof(huffNodeTable));
352
365
 
353
366
  /* sort, decreasing order */
@@ -405,9 +418,10 @@ size_t HUF_buildCTable_wksp (HUF_CElt* tree, const U32* count, U32 maxSymbolValu
405
418
  }
406
419
 
407
420
  /** HUF_buildCTable() :
421
+ * @return : maxNbBits
408
422
  * Note : count is used before tree is written, so they can safely overlap
409
423
  */
410
- size_t HUF_buildCTable (HUF_CElt* tree, const U32* count, U32 maxSymbolValue, U32 maxNbBits)
424
+ size_t HUF_buildCTable (HUF_CElt* tree, const unsigned* count, unsigned maxSymbolValue, unsigned maxNbBits)
411
425
  {
412
426
  huffNodeTable nodeTable;
413
427
  return HUF_buildCTable_wksp(tree, count, maxSymbolValue, maxNbBits, nodeTable, sizeof(nodeTable));
@@ -432,13 +446,14 @@ static int HUF_validateCTable(const HUF_CElt* CTable, const unsigned* count, uns
432
446
  return !bad;
433
447
  }
434
448
 
435
- static void HUF_encodeSymbol(BIT_CStream_t* bitCPtr, U32 symbol, const HUF_CElt* CTable)
449
+ size_t HUF_compressBound(size_t size) { return HUF_COMPRESSBOUND(size); }
450
+
451
+ FORCE_INLINE_TEMPLATE void
452
+ HUF_encodeSymbol(BIT_CStream_t* bitCPtr, U32 symbol, const HUF_CElt* CTable)
436
453
  {
437
454
  BIT_addBitsFast(bitCPtr, CTable[symbol].val, CTable[symbol].nbBits);
438
455
  }
439
456
 
440
- size_t HUF_compressBound(size_t size) { return HUF_COMPRESSBOUND(size); }
441
-
442
457
  #define HUF_FLUSHBITS(s) BIT_flushBits(s)
443
458
 
444
459
  #define HUF_FLUSHBITS_1(stream) \
@@ -447,7 +462,10 @@ size_t HUF_compressBound(size_t size) { return HUF_COMPRESSBOUND(size); }
447
462
  #define HUF_FLUSHBITS_2(stream) \
448
463
  if (sizeof((stream)->bitContainer)*8 < HUF_TABLELOG_MAX*4+7) HUF_FLUSHBITS(stream)
449
464
 
450
- size_t HUF_compress1X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable)
465
+ FORCE_INLINE_TEMPLATE size_t
466
+ HUF_compress1X_usingCTable_internal_body(void* dst, size_t dstSize,
467
+ const void* src, size_t srcSize,
468
+ const HUF_CElt* CTable)
451
469
  {
452
470
  const BYTE* ip = (const BYTE*) src;
453
471
  BYTE* const ostart = (BYTE*)dst;
@@ -491,8 +509,58 @@ size_t HUF_compress1X_usingCTable(void* dst, size_t dstSize, const void* src, si
491
509
  return BIT_closeCStream(&bitC);
492
510
  }
493
511
 
512
+ #if DYNAMIC_BMI2
494
513
 
495
- size_t HUF_compress4X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable)
514
+ static TARGET_ATTRIBUTE("bmi2") size_t
515
+ HUF_compress1X_usingCTable_internal_bmi2(void* dst, size_t dstSize,
516
+ const void* src, size_t srcSize,
517
+ const HUF_CElt* CTable)
518
+ {
519
+ return HUF_compress1X_usingCTable_internal_body(dst, dstSize, src, srcSize, CTable);
520
+ }
521
+
522
+ static size_t
523
+ HUF_compress1X_usingCTable_internal_default(void* dst, size_t dstSize,
524
+ const void* src, size_t srcSize,
525
+ const HUF_CElt* CTable)
526
+ {
527
+ return HUF_compress1X_usingCTable_internal_body(dst, dstSize, src, srcSize, CTable);
528
+ }
529
+
530
+ static size_t
531
+ HUF_compress1X_usingCTable_internal(void* dst, size_t dstSize,
532
+ const void* src, size_t srcSize,
533
+ const HUF_CElt* CTable, const int bmi2)
534
+ {
535
+ if (bmi2) {
536
+ return HUF_compress1X_usingCTable_internal_bmi2(dst, dstSize, src, srcSize, CTable);
537
+ }
538
+ return HUF_compress1X_usingCTable_internal_default(dst, dstSize, src, srcSize, CTable);
539
+ }
540
+
541
+ #else
542
+
543
+ static size_t
544
+ HUF_compress1X_usingCTable_internal(void* dst, size_t dstSize,
545
+ const void* src, size_t srcSize,
546
+ const HUF_CElt* CTable, const int bmi2)
547
+ {
548
+ (void)bmi2;
549
+ return HUF_compress1X_usingCTable_internal_body(dst, dstSize, src, srcSize, CTable);
550
+ }
551
+
552
+ #endif
553
+
554
+ size_t HUF_compress1X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable)
555
+ {
556
+ return HUF_compress1X_usingCTable_internal(dst, dstSize, src, srcSize, CTable, /* bmi2 */ 0);
557
+ }
558
+
559
+
560
+ static size_t
561
+ HUF_compress4X_usingCTable_internal(void* dst, size_t dstSize,
562
+ const void* src, size_t srcSize,
563
+ const HUF_CElt* CTable, int bmi2)
496
564
  {
497
565
  size_t const segmentSize = (srcSize+3)/4; /* first 3 segments */
498
566
  const BYTE* ip = (const BYTE*) src;
@@ -505,28 +573,31 @@ size_t HUF_compress4X_usingCTable(void* dst, size_t dstSize, const void* src, si
505
573
  if (srcSize < 12) return 0; /* no saving possible : too small input */
506
574
  op += 6; /* jumpTable */
507
575
 
508
- { CHECK_V_F(cSize, HUF_compress1X_usingCTable(op, oend-op, ip, segmentSize, CTable) );
576
+ { CHECK_V_F(cSize, HUF_compress1X_usingCTable_internal(op, oend-op, ip, segmentSize, CTable, bmi2) );
509
577
  if (cSize==0) return 0;
578
+ assert(cSize <= 65535);
510
579
  MEM_writeLE16(ostart, (U16)cSize);
511
580
  op += cSize;
512
581
  }
513
582
 
514
583
  ip += segmentSize;
515
- { CHECK_V_F(cSize, HUF_compress1X_usingCTable(op, oend-op, ip, segmentSize, CTable) );
584
+ { CHECK_V_F(cSize, HUF_compress1X_usingCTable_internal(op, oend-op, ip, segmentSize, CTable, bmi2) );
516
585
  if (cSize==0) return 0;
586
+ assert(cSize <= 65535);
517
587
  MEM_writeLE16(ostart+2, (U16)cSize);
518
588
  op += cSize;
519
589
  }
520
590
 
521
591
  ip += segmentSize;
522
- { CHECK_V_F(cSize, HUF_compress1X_usingCTable(op, oend-op, ip, segmentSize, CTable) );
592
+ { CHECK_V_F(cSize, HUF_compress1X_usingCTable_internal(op, oend-op, ip, segmentSize, CTable, bmi2) );
523
593
  if (cSize==0) return 0;
594
+ assert(cSize <= 65535);
524
595
  MEM_writeLE16(ostart+4, (U16)cSize);
525
596
  op += cSize;
526
597
  }
527
598
 
528
599
  ip += segmentSize;
529
- { CHECK_V_F(cSize, HUF_compress1X_usingCTable(op, oend-op, ip, iend-ip, CTable) );
600
+ { CHECK_V_F(cSize, HUF_compress1X_usingCTable_internal(op, oend-op, ip, iend-ip, CTable, bmi2) );
530
601
  if (cSize==0) return 0;
531
602
  op += cSize;
532
603
  }
@@ -534,15 +605,21 @@ size_t HUF_compress4X_usingCTable(void* dst, size_t dstSize, const void* src, si
534
605
  return op-ostart;
535
606
  }
536
607
 
608
+ size_t HUF_compress4X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable)
609
+ {
610
+ return HUF_compress4X_usingCTable_internal(dst, dstSize, src, srcSize, CTable, /* bmi2 */ 0);
611
+ }
612
+
613
+ typedef enum { HUF_singleStream, HUF_fourStreams } HUF_nbStreams_e;
537
614
 
538
615
  static size_t HUF_compressCTable_internal(
539
616
  BYTE* const ostart, BYTE* op, BYTE* const oend,
540
617
  const void* src, size_t srcSize,
541
- unsigned singleStream, const HUF_CElt* CTable)
618
+ HUF_nbStreams_e nbStreams, const HUF_CElt* CTable, const int bmi2)
542
619
  {
543
- size_t const cSize = singleStream ?
544
- HUF_compress1X_usingCTable(op, oend - op, src, srcSize, CTable) :
545
- HUF_compress4X_usingCTable(op, oend - op, src, srcSize, CTable);
620
+ size_t const cSize = (nbStreams==HUF_singleStream) ?
621
+ HUF_compress1X_usingCTable_internal(op, oend - op, src, srcSize, CTable, bmi2) :
622
+ HUF_compress4X_usingCTable_internal(op, oend - op, src, srcSize, CTable, bmi2);
546
623
  if (HUF_isError(cSize)) { return cSize; }
547
624
  if (cSize==0) { return 0; } /* uncompressible */
548
625
  op += cSize;
@@ -551,86 +628,99 @@ static size_t HUF_compressCTable_internal(
551
628
  return op-ostart;
552
629
  }
553
630
 
631
+ typedef struct {
632
+ unsigned count[HUF_SYMBOLVALUE_MAX + 1];
633
+ HUF_CElt CTable[HUF_SYMBOLVALUE_MAX + 1];
634
+ huffNodeTable nodeTable;
635
+ } HUF_compress_tables_t;
554
636
 
555
- /* `workSpace` must a table of at least 1024 unsigned */
556
- static size_t HUF_compress_internal (
557
- void* dst, size_t dstSize,
558
- const void* src, size_t srcSize,
559
- unsigned maxSymbolValue, unsigned huffLog,
560
- unsigned singleStream,
561
- void* workSpace, size_t wkspSize,
562
- HUF_CElt* oldHufTable, HUF_repeat* repeat, int preferRepeat)
637
+ /* HUF_compress_internal() :
638
+ * `workSpace` must a table of at least HUF_WORKSPACE_SIZE_U32 unsigned */
639
+ static size_t
640
+ HUF_compress_internal (void* dst, size_t dstSize,
641
+ const void* src, size_t srcSize,
642
+ unsigned maxSymbolValue, unsigned huffLog,
643
+ HUF_nbStreams_e nbStreams,
644
+ void* workSpace, size_t wkspSize,
645
+ HUF_CElt* oldHufTable, HUF_repeat* repeat, int preferRepeat,
646
+ const int bmi2)
563
647
  {
648
+ HUF_compress_tables_t* const table = (HUF_compress_tables_t*)workSpace;
564
649
  BYTE* const ostart = (BYTE*)dst;
565
650
  BYTE* const oend = ostart + dstSize;
566
651
  BYTE* op = ostart;
567
652
 
568
- U32* count;
569
- size_t const countSize = sizeof(U32) * (HUF_SYMBOLVALUE_MAX + 1);
570
- HUF_CElt* CTable;
571
- size_t const CTableSize = sizeof(HUF_CElt) * (HUF_SYMBOLVALUE_MAX + 1);
572
-
573
653
  /* checks & inits */
574
- if (wkspSize < sizeof(huffNodeTable) + countSize + CTableSize) return ERROR(GENERIC);
575
- if (!srcSize) return 0; /* Uncompressed (note : 1 means rle, so first byte must be correct) */
576
- if (!dstSize) return 0; /* cannot fit within dst budget */
654
+ if (((size_t)workSpace & 3) != 0) return ERROR(GENERIC); /* must be aligned on 4-bytes boundaries */
655
+ if (wkspSize < HUF_WORKSPACE_SIZE) return ERROR(workSpace_tooSmall);
656
+ if (!srcSize) return 0; /* Uncompressed */
657
+ if (!dstSize) return 0; /* cannot fit anything within dst budget */
577
658
  if (srcSize > HUF_BLOCKSIZE_MAX) return ERROR(srcSize_wrong); /* current block size limit */
578
659
  if (huffLog > HUF_TABLELOG_MAX) return ERROR(tableLog_tooLarge);
660
+ if (maxSymbolValue > HUF_SYMBOLVALUE_MAX) return ERROR(maxSymbolValue_tooLarge);
579
661
  if (!maxSymbolValue) maxSymbolValue = HUF_SYMBOLVALUE_MAX;
580
662
  if (!huffLog) huffLog = HUF_TABLELOG_DEFAULT;
581
663
 
582
- count = (U32*)workSpace;
583
- workSpace = (BYTE*)workSpace + countSize;
584
- wkspSize -= countSize;
585
- CTable = (HUF_CElt*)workSpace;
586
- workSpace = (BYTE*)workSpace + CTableSize;
587
- wkspSize -= CTableSize;
588
-
589
- /* Heuristic : If we don't need to check the validity of the old table use the old table for small inputs */
664
+ /* Heuristic : If old table is valid, use it for small inputs */
590
665
  if (preferRepeat && repeat && *repeat == HUF_repeat_valid) {
591
- return HUF_compressCTable_internal(ostart, op, oend, src, srcSize, singleStream, oldHufTable);
666
+ return HUF_compressCTable_internal(ostart, op, oend,
667
+ src, srcSize,
668
+ nbStreams, oldHufTable, bmi2);
592
669
  }
593
670
 
594
671
  /* Scan input and build symbol stats */
595
- { CHECK_V_F(largest, FSE_count_wksp (count, &maxSymbolValue, (const BYTE*)src, srcSize, (U32*)workSpace) );
672
+ { CHECK_V_F(largest, HIST_count_wksp (table->count, &maxSymbolValue, (const BYTE*)src, srcSize, workSpace, wkspSize) );
596
673
  if (largest == srcSize) { *ostart = ((const BYTE*)src)[0]; return 1; } /* single symbol, rle */
597
- if (largest <= (srcSize >> 7)+1) return 0; /* Fast heuristic : not compressible enough */
674
+ if (largest <= (srcSize >> 7)+4) return 0; /* heuristic : probably not compressible enough */
598
675
  }
599
676
 
600
677
  /* Check validity of previous table */
601
- if (repeat && *repeat == HUF_repeat_check && !HUF_validateCTable(oldHufTable, count, maxSymbolValue)) {
678
+ if ( repeat
679
+ && *repeat == HUF_repeat_check
680
+ && !HUF_validateCTable(oldHufTable, table->count, maxSymbolValue)) {
602
681
  *repeat = HUF_repeat_none;
603
682
  }
604
683
  /* Heuristic : use existing table for small inputs */
605
684
  if (preferRepeat && repeat && *repeat != HUF_repeat_none) {
606
- return HUF_compressCTable_internal(ostart, op, oend, src, srcSize, singleStream, oldHufTable);
685
+ return HUF_compressCTable_internal(ostart, op, oend,
686
+ src, srcSize,
687
+ nbStreams, oldHufTable, bmi2);
607
688
  }
608
689
 
609
690
  /* Build Huffman Tree */
610
691
  huffLog = HUF_optimalTableLog(huffLog, srcSize, maxSymbolValue);
611
- { CHECK_V_F(maxBits, HUF_buildCTable_wksp (CTable, count, maxSymbolValue, huffLog, workSpace, wkspSize) );
692
+ { size_t const maxBits = HUF_buildCTable_wksp(table->CTable, table->count,
693
+ maxSymbolValue, huffLog,
694
+ table->nodeTable, sizeof(table->nodeTable));
695
+ CHECK_F(maxBits);
612
696
  huffLog = (U32)maxBits;
613
- /* Zero the unused symbols so we can check it for validity */
614
- memset(CTable + maxSymbolValue + 1, 0, CTableSize - (maxSymbolValue + 1) * sizeof(HUF_CElt));
697
+ /* Zero unused symbols in CTable, so we can check it for validity */
698
+ memset(table->CTable + (maxSymbolValue + 1), 0,
699
+ sizeof(table->CTable) - ((maxSymbolValue + 1) * sizeof(HUF_CElt)));
615
700
  }
616
701
 
617
702
  /* Write table description header */
618
- { CHECK_V_F(hSize, HUF_writeCTable (op, dstSize, CTable, maxSymbolValue, huffLog) );
619
- /* Check if using the previous table will be beneficial */
703
+ { CHECK_V_F(hSize, HUF_writeCTable (op, dstSize, table->CTable, maxSymbolValue, huffLog) );
704
+ /* Check if using previous huffman table is beneficial */
620
705
  if (repeat && *repeat != HUF_repeat_none) {
621
- size_t const oldSize = HUF_estimateCompressedSize(oldHufTable, count, maxSymbolValue);
622
- size_t const newSize = HUF_estimateCompressedSize(CTable, count, maxSymbolValue);
706
+ size_t const oldSize = HUF_estimateCompressedSize(oldHufTable, table->count, maxSymbolValue);
707
+ size_t const newSize = HUF_estimateCompressedSize(table->CTable, table->count, maxSymbolValue);
623
708
  if (oldSize <= hSize + newSize || hSize + 12 >= srcSize) {
624
- return HUF_compressCTable_internal(ostart, op, oend, src, srcSize, singleStream, oldHufTable);
625
- }
626
- }
627
- /* Use the new table */
709
+ return HUF_compressCTable_internal(ostart, op, oend,
710
+ src, srcSize,
711
+ nbStreams, oldHufTable, bmi2);
712
+ } }
713
+
714
+ /* Use the new huffman table */
628
715
  if (hSize + 12ul >= srcSize) { return 0; }
629
716
  op += hSize;
630
717
  if (repeat) { *repeat = HUF_repeat_none; }
631
- if (oldHufTable) { memcpy(oldHufTable, CTable, CTableSize); } /* Save the new table */
718
+ if (oldHufTable)
719
+ memcpy(oldHufTable, table->CTable, sizeof(table->CTable)); /* Save new table */
632
720
  }
633
- return HUF_compressCTable_internal(ostart, op, oend, src, srcSize, singleStream, CTable);
721
+ return HUF_compressCTable_internal(ostart, op, oend,
722
+ src, srcSize,
723
+ nbStreams, table->CTable, bmi2);
634
724
  }
635
725
 
636
726
 
@@ -639,52 +729,70 @@ size_t HUF_compress1X_wksp (void* dst, size_t dstSize,
639
729
  unsigned maxSymbolValue, unsigned huffLog,
640
730
  void* workSpace, size_t wkspSize)
641
731
  {
642
- return HUF_compress_internal(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, 1 /* single stream */, workSpace, wkspSize, NULL, NULL, 0);
732
+ return HUF_compress_internal(dst, dstSize, src, srcSize,
733
+ maxSymbolValue, huffLog, HUF_singleStream,
734
+ workSpace, wkspSize,
735
+ NULL, NULL, 0, 0 /*bmi2*/);
643
736
  }
644
737
 
645
738
  size_t HUF_compress1X_repeat (void* dst, size_t dstSize,
646
739
  const void* src, size_t srcSize,
647
740
  unsigned maxSymbolValue, unsigned huffLog,
648
741
  void* workSpace, size_t wkspSize,
649
- HUF_CElt* hufTable, HUF_repeat* repeat, int preferRepeat)
742
+ HUF_CElt* hufTable, HUF_repeat* repeat, int preferRepeat, int bmi2)
650
743
  {
651
- return HUF_compress_internal(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, 1 /* single stream */, workSpace, wkspSize, hufTable, repeat, preferRepeat);
744
+ return HUF_compress_internal(dst, dstSize, src, srcSize,
745
+ maxSymbolValue, huffLog, HUF_singleStream,
746
+ workSpace, wkspSize, hufTable,
747
+ repeat, preferRepeat, bmi2);
652
748
  }
653
749
 
654
750
  size_t HUF_compress1X (void* dst, size_t dstSize,
655
751
  const void* src, size_t srcSize,
656
752
  unsigned maxSymbolValue, unsigned huffLog)
657
753
  {
658
- unsigned workSpace[1024];
754
+ unsigned workSpace[HUF_WORKSPACE_SIZE_U32];
659
755
  return HUF_compress1X_wksp(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, workSpace, sizeof(workSpace));
660
756
  }
661
757
 
758
+ /* HUF_compress4X_repeat():
759
+ * compress input using 4 streams.
760
+ * provide workspace to generate compression tables */
662
761
  size_t HUF_compress4X_wksp (void* dst, size_t dstSize,
663
762
  const void* src, size_t srcSize,
664
763
  unsigned maxSymbolValue, unsigned huffLog,
665
764
  void* workSpace, size_t wkspSize)
666
765
  {
667
- return HUF_compress_internal(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, 0 /* 4 streams */, workSpace, wkspSize, NULL, NULL, 0);
766
+ return HUF_compress_internal(dst, dstSize, src, srcSize,
767
+ maxSymbolValue, huffLog, HUF_fourStreams,
768
+ workSpace, wkspSize,
769
+ NULL, NULL, 0, 0 /*bmi2*/);
668
770
  }
669
771
 
772
+ /* HUF_compress4X_repeat():
773
+ * compress input using 4 streams.
774
+ * re-use an existing huffman compression table */
670
775
  size_t HUF_compress4X_repeat (void* dst, size_t dstSize,
671
776
  const void* src, size_t srcSize,
672
777
  unsigned maxSymbolValue, unsigned huffLog,
673
778
  void* workSpace, size_t wkspSize,
674
- HUF_CElt* hufTable, HUF_repeat* repeat, int preferRepeat)
779
+ HUF_CElt* hufTable, HUF_repeat* repeat, int preferRepeat, int bmi2)
675
780
  {
676
- return HUF_compress_internal(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, 0 /* 4 streams */, workSpace, wkspSize, hufTable, repeat, preferRepeat);
781
+ return HUF_compress_internal(dst, dstSize, src, srcSize,
782
+ maxSymbolValue, huffLog, HUF_fourStreams,
783
+ workSpace, wkspSize,
784
+ hufTable, repeat, preferRepeat, bmi2);
677
785
  }
678
786
 
679
787
  size_t HUF_compress2 (void* dst, size_t dstSize,
680
788
  const void* src, size_t srcSize,
681
789
  unsigned maxSymbolValue, unsigned huffLog)
682
790
  {
683
- unsigned workSpace[1024];
791
+ unsigned workSpace[HUF_WORKSPACE_SIZE_U32];
684
792
  return HUF_compress4X_wksp(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, workSpace, sizeof(workSpace));
685
793
  }
686
794
 
687
795
  size_t HUF_compress (void* dst, size_t maxDstSize, const void* src, size_t srcSize)
688
796
  {
689
- return HUF_compress2(dst, maxDstSize, src, (U32)srcSize, 255, HUF_TABLELOG_DEFAULT);
797
+ return HUF_compress2(dst, maxDstSize, src, srcSize, 255, HUF_TABLELOG_DEFAULT);
690
798
  }