extzstd 0.2 → 0.3

Sign up to get free protection for your applications and to get access to all the features.
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
  }