extzstd 0.0.3.CONCEPT → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (138) hide show
  1. checksums.yaml +5 -5
  2. data/HISTORY.ja.md +39 -0
  3. data/LICENSE +6 -6
  4. data/README.md +26 -45
  5. data/contrib/zstd/CHANGELOG +555 -0
  6. data/contrib/zstd/CODE_OF_CONDUCT.md +5 -0
  7. data/contrib/zstd/CONTRIBUTING.md +392 -0
  8. data/contrib/zstd/COPYING +339 -0
  9. data/contrib/zstd/LICENSE +13 -9
  10. data/contrib/zstd/Makefile +414 -0
  11. data/contrib/zstd/README.md +170 -45
  12. data/contrib/zstd/TESTING.md +44 -0
  13. data/contrib/zstd/appveyor.yml +289 -0
  14. data/contrib/zstd/lib/BUCK +234 -0
  15. data/contrib/zstd/lib/Makefile +354 -0
  16. data/contrib/zstd/lib/README.md +179 -0
  17. data/contrib/zstd/{common → lib/common}/bitstream.h +170 -130
  18. data/contrib/zstd/lib/common/compiler.h +175 -0
  19. data/contrib/zstd/lib/common/cpu.h +215 -0
  20. data/contrib/zstd/lib/common/debug.c +24 -0
  21. data/contrib/zstd/lib/common/debug.h +114 -0
  22. data/contrib/zstd/{common → lib/common}/entropy_common.c +79 -94
  23. data/contrib/zstd/lib/common/error_private.c +55 -0
  24. data/contrib/zstd/lib/common/error_private.h +80 -0
  25. data/contrib/zstd/{common → lib/common}/fse.h +153 -93
  26. data/contrib/zstd/{common → lib/common}/fse_decompress.c +37 -82
  27. data/contrib/zstd/lib/common/huf.h +340 -0
  28. data/contrib/zstd/{common → lib/common}/mem.h +154 -78
  29. data/contrib/zstd/lib/common/pool.c +344 -0
  30. data/contrib/zstd/lib/common/pool.h +84 -0
  31. data/contrib/zstd/lib/common/threading.c +121 -0
  32. data/contrib/zstd/lib/common/threading.h +155 -0
  33. data/contrib/zstd/{common → lib/common}/xxhash.c +85 -75
  34. data/contrib/zstd/{common → lib/common}/xxhash.h +85 -73
  35. data/contrib/zstd/lib/common/zstd_common.c +83 -0
  36. data/contrib/zstd/lib/common/zstd_errors.h +94 -0
  37. data/contrib/zstd/lib/common/zstd_internal.h +447 -0
  38. data/contrib/zstd/{compress → lib/compress}/fse_compress.c +194 -303
  39. data/contrib/zstd/lib/compress/hist.c +183 -0
  40. data/contrib/zstd/lib/compress/hist.h +75 -0
  41. data/contrib/zstd/lib/compress/huf_compress.c +798 -0
  42. data/contrib/zstd/lib/compress/zstd_compress.c +4278 -0
  43. data/contrib/zstd/lib/compress/zstd_compress_internal.h +1125 -0
  44. data/contrib/zstd/lib/compress/zstd_compress_literals.c +158 -0
  45. data/contrib/zstd/lib/compress/zstd_compress_literals.h +29 -0
  46. data/contrib/zstd/lib/compress/zstd_compress_sequences.c +419 -0
  47. data/contrib/zstd/lib/compress/zstd_compress_sequences.h +54 -0
  48. data/contrib/zstd/lib/compress/zstd_compress_superblock.c +845 -0
  49. data/contrib/zstd/lib/compress/zstd_compress_superblock.h +32 -0
  50. data/contrib/zstd/lib/compress/zstd_cwksp.h +525 -0
  51. data/contrib/zstd/lib/compress/zstd_double_fast.c +521 -0
  52. data/contrib/zstd/lib/compress/zstd_double_fast.h +38 -0
  53. data/contrib/zstd/lib/compress/zstd_fast.c +496 -0
  54. data/contrib/zstd/lib/compress/zstd_fast.h +37 -0
  55. data/contrib/zstd/lib/compress/zstd_lazy.c +1138 -0
  56. data/contrib/zstd/lib/compress/zstd_lazy.h +67 -0
  57. data/contrib/zstd/lib/compress/zstd_ldm.c +619 -0
  58. data/contrib/zstd/lib/compress/zstd_ldm.h +110 -0
  59. data/contrib/zstd/lib/compress/zstd_opt.c +1200 -0
  60. data/contrib/zstd/lib/compress/zstd_opt.h +56 -0
  61. data/contrib/zstd/lib/compress/zstdmt_compress.c +2143 -0
  62. data/contrib/zstd/lib/compress/zstdmt_compress.h +192 -0
  63. data/contrib/zstd/lib/decompress/huf_decompress.c +1248 -0
  64. data/contrib/zstd/lib/decompress/zstd_ddict.c +244 -0
  65. data/contrib/zstd/lib/decompress/zstd_ddict.h +44 -0
  66. data/contrib/zstd/lib/decompress/zstd_decompress.c +1885 -0
  67. data/contrib/zstd/lib/decompress/zstd_decompress_block.c +1432 -0
  68. data/contrib/zstd/lib/decompress/zstd_decompress_block.h +59 -0
  69. data/contrib/zstd/lib/decompress/zstd_decompress_internal.h +189 -0
  70. data/contrib/zstd/{common → lib/deprecated}/zbuff.h +86 -69
  71. data/contrib/zstd/lib/deprecated/zbuff_common.c +26 -0
  72. data/contrib/zstd/lib/deprecated/zbuff_compress.c +147 -0
  73. data/contrib/zstd/lib/deprecated/zbuff_decompress.c +75 -0
  74. data/contrib/zstd/lib/dictBuilder/cover.c +1236 -0
  75. data/contrib/zstd/lib/dictBuilder/cover.h +157 -0
  76. data/contrib/zstd/{dictBuilder → lib/dictBuilder}/divsufsort.c +3 -3
  77. data/contrib/zstd/{dictBuilder → lib/dictBuilder}/divsufsort.h +5 -5
  78. data/contrib/zstd/lib/dictBuilder/fastcover.c +757 -0
  79. data/contrib/zstd/{dictBuilder → lib/dictBuilder}/zdict.c +437 -347
  80. data/contrib/zstd/lib/dictBuilder/zdict.h +305 -0
  81. data/contrib/zstd/lib/legacy/zstd_legacy.h +415 -0
  82. data/contrib/zstd/{legacy → lib/legacy}/zstd_v01.c +272 -292
  83. data/contrib/zstd/{legacy → lib/legacy}/zstd_v01.h +26 -32
  84. data/contrib/zstd/{legacy → lib/legacy}/zstd_v02.c +162 -392
  85. data/contrib/zstd/{legacy → lib/legacy}/zstd_v02.h +26 -32
  86. data/contrib/zstd/{legacy → lib/legacy}/zstd_v03.c +162 -391
  87. data/contrib/zstd/{legacy → lib/legacy}/zstd_v03.h +27 -33
  88. data/contrib/zstd/{legacy → lib/legacy}/zstd_v04.c +195 -604
  89. data/contrib/zstd/{legacy → lib/legacy}/zstd_v04.h +26 -32
  90. data/contrib/zstd/{legacy → lib/legacy}/zstd_v05.c +300 -575
  91. data/contrib/zstd/{legacy → lib/legacy}/zstd_v05.h +22 -31
  92. data/contrib/zstd/{legacy → lib/legacy}/zstd_v06.c +165 -592
  93. data/contrib/zstd/{legacy → lib/legacy}/zstd_v06.h +54 -67
  94. data/contrib/zstd/lib/legacy/zstd_v07.c +4541 -0
  95. data/contrib/zstd/lib/legacy/zstd_v07.h +187 -0
  96. data/contrib/zstd/lib/libzstd.pc.in +15 -0
  97. data/contrib/zstd/lib/zstd.h +2090 -0
  98. data/ext/depend +2 -0
  99. data/ext/extconf.rb +18 -5
  100. data/ext/extzstd.c +296 -214
  101. data/ext/extzstd.h +81 -36
  102. data/ext/extzstd_nogvls.h +0 -117
  103. data/ext/extzstd_stream.c +622 -0
  104. data/ext/libzstd_conf.h +8 -0
  105. data/ext/zstd_common.c +11 -0
  106. data/ext/zstd_compress.c +15 -0
  107. data/ext/zstd_decompress.c +6 -0
  108. data/ext/zstd_dictbuilder.c +10 -0
  109. data/ext/zstd_dictbuilder_fastcover.c +3 -0
  110. data/ext/zstd_legacy_v01.c +3 -1
  111. data/ext/zstd_legacy_v02.c +3 -1
  112. data/ext/zstd_legacy_v03.c +3 -1
  113. data/ext/zstd_legacy_v04.c +3 -1
  114. data/ext/zstd_legacy_v05.c +3 -1
  115. data/ext/zstd_legacy_v06.c +3 -1
  116. data/ext/zstd_legacy_v07.c +3 -0
  117. data/gemstub.rb +27 -21
  118. data/lib/extzstd.rb +82 -161
  119. data/lib/extzstd/version.rb +1 -1
  120. data/test/test_basic.rb +19 -6
  121. metadata +127 -59
  122. data/contrib/zstd/common/error_private.h +0 -125
  123. data/contrib/zstd/common/error_public.h +0 -77
  124. data/contrib/zstd/common/huf.h +0 -228
  125. data/contrib/zstd/common/zstd.h +0 -475
  126. data/contrib/zstd/common/zstd_common.c +0 -91
  127. data/contrib/zstd/common/zstd_internal.h +0 -238
  128. data/contrib/zstd/compress/huf_compress.c +0 -577
  129. data/contrib/zstd/compress/zbuff_compress.c +0 -327
  130. data/contrib/zstd/compress/zstd_compress.c +0 -3074
  131. data/contrib/zstd/compress/zstd_opt.h +0 -1046
  132. data/contrib/zstd/decompress/huf_decompress.c +0 -894
  133. data/contrib/zstd/decompress/zbuff_decompress.c +0 -294
  134. data/contrib/zstd/decompress/zstd_decompress.c +0 -1362
  135. data/contrib/zstd/dictBuilder/zdict.h +0 -113
  136. data/contrib/zstd/legacy/zstd_legacy.h +0 -140
  137. data/ext/extzstd_buffered.c +0 -265
  138. data/ext/zstd_amalgam.c +0 -18
@@ -1,327 +0,0 @@
1
- /*
2
- Buffered version of Zstd compression library
3
- Copyright (C) 2015-2016, Yann Collet.
4
-
5
- BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
6
-
7
- Redistribution and use in source and binary forms, with or without
8
- modification, are permitted provided that the following conditions are
9
- met:
10
- * Redistributions of source code must retain the above copyright
11
- notice, this list of conditions and the following disclaimer.
12
- * Redistributions in binary form must reproduce the above
13
- copyright notice, this list of conditions and the following disclaimer
14
- in the documentation and/or other materials provided with the
15
- distribution.
16
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20
- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
-
28
- You can contact the author at :
29
- - zstd homepage : http://www.zstd.net/
30
- */
31
-
32
-
33
- /* *************************************
34
- * Dependencies
35
- ***************************************/
36
- #include <stdlib.h>
37
- #include "error_private.h"
38
- #include "zstd_internal.h" /* MIN, ZSTD_BLOCKHEADERSIZE, defaultCustomMem */
39
- #define ZBUFF_STATIC_LINKING_ONLY
40
- #include "zbuff.h"
41
-
42
-
43
- /* *************************************
44
- * Constants
45
- ***************************************/
46
- static size_t const ZBUFF_endFrameSize = ZSTD_BLOCKHEADERSIZE;
47
-
48
-
49
- /*_**************************************************
50
- * Streaming compression
51
- *
52
- * A ZBUFF_CCtx object is required to track streaming operation.
53
- * Use ZBUFF_createCCtx() and ZBUFF_freeCCtx() to create/release resources.
54
- * Use ZBUFF_compressInit() to start a new compression operation.
55
- * ZBUFF_CCtx objects can be reused multiple times.
56
- *
57
- * Use ZBUFF_compressContinue() repetitively to consume your input.
58
- * *srcSizePtr and *dstCapacityPtr can be any size.
59
- * The function will report how many bytes were read or written by modifying *srcSizePtr and *dstCapacityPtr.
60
- * Note that it may not consume the entire input, in which case it's up to the caller to call again the function with remaining input.
61
- * The content of dst will be overwritten (up to *dstCapacityPtr) at each function call, so save its content if it matters or change dst .
62
- * @return : a hint to preferred nb of bytes to use as input for next function call (it's only a hint, to improve latency)
63
- * or an error code, which can be tested using ZBUFF_isError().
64
- *
65
- * ZBUFF_compressFlush() can be used to instruct ZBUFF to compress and output whatever remains within its buffer.
66
- * Note that it will not output more than *dstCapacityPtr.
67
- * Therefore, some content might still be left into its internal buffer if dst buffer is too small.
68
- * @return : nb of bytes still present into internal buffer (0 if it's empty)
69
- * or an error code, which can be tested using ZBUFF_isError().
70
- *
71
- * ZBUFF_compressEnd() instructs to finish a frame.
72
- * It will perform a flush and write frame epilogue.
73
- * Similar to ZBUFF_compressFlush(), it may not be able to output the entire internal buffer content if *dstCapacityPtr is too small.
74
- * @return : nb of bytes still present into internal buffer (0 if it's empty)
75
- * or an error code, which can be tested using ZBUFF_isError().
76
- *
77
- * Hint : recommended buffer sizes (not compulsory)
78
- * input : ZSTD_BLOCKSIZE_MAX (128 KB), internal unit size, it improves latency to use this value.
79
- * output : ZSTD_compressBound(ZSTD_BLOCKSIZE_MAX) + ZSTD_blockHeaderSize + ZBUFF_endFrameSize : ensures it's always possible to write/flush/end a full block at best speed.
80
- * **************************************************/
81
-
82
- typedef enum { ZBUFFcs_init, ZBUFFcs_load, ZBUFFcs_flush, ZBUFFcs_final } ZBUFF_cStage;
83
-
84
- /* *** Resources *** */
85
- struct ZBUFF_CCtx_s {
86
- ZSTD_CCtx* zc;
87
- char* inBuff;
88
- size_t inBuffSize;
89
- size_t inToCompress;
90
- size_t inBuffPos;
91
- size_t inBuffTarget;
92
- size_t blockSize;
93
- char* outBuff;
94
- size_t outBuffSize;
95
- size_t outBuffContentSize;
96
- size_t outBuffFlushedSize;
97
- ZBUFF_cStage stage;
98
- ZSTD_customMem customMem;
99
- }; /* typedef'd tp ZBUFF_CCtx within "zstd_buffered.h" */
100
-
101
- ZBUFF_CCtx* ZBUFF_createCCtx(void)
102
- {
103
- return ZBUFF_createCCtx_advanced(defaultCustomMem);
104
- }
105
-
106
- ZBUFF_CCtx* ZBUFF_createCCtx_advanced(ZSTD_customMem customMem)
107
- {
108
- ZBUFF_CCtx* zbc;
109
-
110
- if (!customMem.customAlloc && !customMem.customFree)
111
- customMem = defaultCustomMem;
112
-
113
- if (!customMem.customAlloc || !customMem.customFree)
114
- return NULL;
115
-
116
- zbc = (ZBUFF_CCtx*)customMem.customAlloc(customMem.opaque, sizeof(ZBUFF_CCtx));
117
- if (zbc==NULL) return NULL;
118
- memset(zbc, 0, sizeof(ZBUFF_CCtx));
119
- memcpy(&zbc->customMem, &customMem, sizeof(ZSTD_customMem));
120
- zbc->zc = ZSTD_createCCtx_advanced(customMem);
121
- if (zbc->zc == NULL) { ZBUFF_freeCCtx(zbc); return NULL; }
122
- return zbc;
123
- }
124
-
125
- size_t ZBUFF_freeCCtx(ZBUFF_CCtx* zbc)
126
- {
127
- if (zbc==NULL) return 0; /* support free on NULL */
128
- ZSTD_freeCCtx(zbc->zc);
129
- if (zbc->inBuff) zbc->customMem.customFree(zbc->customMem.opaque, zbc->inBuff);
130
- if (zbc->outBuff) zbc->customMem.customFree(zbc->customMem.opaque, zbc->outBuff);
131
- zbc->customMem.customFree(zbc->customMem.opaque, zbc);
132
- return 0;
133
- }
134
-
135
-
136
- /* *** Initialization *** */
137
-
138
- size_t ZBUFF_compressInit_advanced(ZBUFF_CCtx* zbc,
139
- const void* dict, size_t dictSize,
140
- ZSTD_parameters params, unsigned long long pledgedSrcSize)
141
- {
142
- /* allocate buffers */
143
- { size_t const neededInBuffSize = (size_t)1 << params.cParams.windowLog;
144
- if (zbc->inBuffSize < neededInBuffSize) {
145
- zbc->inBuffSize = neededInBuffSize;
146
- zbc->customMem.customFree(zbc->customMem.opaque, zbc->inBuff); /* should not be necessary */
147
- zbc->inBuff = (char*)zbc->customMem.customAlloc(zbc->customMem.opaque, neededInBuffSize);
148
- if (zbc->inBuff == NULL) return ERROR(memory_allocation);
149
- }
150
- zbc->blockSize = MIN(ZSTD_BLOCKSIZE_MAX, neededInBuffSize);
151
- }
152
- if (zbc->outBuffSize < ZSTD_compressBound(zbc->blockSize)+1) {
153
- zbc->outBuffSize = ZSTD_compressBound(zbc->blockSize)+1;
154
- zbc->customMem.customFree(zbc->customMem.opaque, zbc->outBuff); /* should not be necessary */
155
- zbc->outBuff = (char*)zbc->customMem.customAlloc(zbc->customMem.opaque, zbc->outBuffSize);
156
- if (zbc->outBuff == NULL) return ERROR(memory_allocation);
157
- }
158
-
159
- { size_t const errorCode = ZSTD_compressBegin_advanced(zbc->zc, dict, dictSize, params, pledgedSrcSize);
160
- if (ZSTD_isError(errorCode)) return errorCode; }
161
-
162
- zbc->inToCompress = 0;
163
- zbc->inBuffPos = 0;
164
- zbc->inBuffTarget = zbc->blockSize;
165
- zbc->outBuffContentSize = zbc->outBuffFlushedSize = 0;
166
- zbc->stage = ZBUFFcs_load;
167
- return 0; /* ready to go */
168
- }
169
-
170
-
171
- size_t ZBUFF_compressInitDictionary(ZBUFF_CCtx* zbc, const void* dict, size_t dictSize, int compressionLevel)
172
- {
173
- ZSTD_parameters const params = ZSTD_getParams(compressionLevel, 0, dictSize);
174
- return ZBUFF_compressInit_advanced(zbc, dict, dictSize, params, 0);
175
- }
176
-
177
- size_t ZBUFF_compressInit(ZBUFF_CCtx* zbc, int compressionLevel)
178
- {
179
- return ZBUFF_compressInitDictionary(zbc, NULL, 0, compressionLevel);
180
- }
181
-
182
-
183
- /* internal util function */
184
- MEM_STATIC size_t ZBUFF_limitCopy(void* dst, size_t dstCapacity, const void* src, size_t srcSize)
185
- {
186
- size_t const length = MIN(dstCapacity, srcSize);
187
- memcpy(dst, src, length);
188
- return length;
189
- }
190
-
191
-
192
- /* *** Compression *** */
193
-
194
- static size_t ZBUFF_compressContinue_generic(ZBUFF_CCtx* zbc,
195
- void* dst, size_t* dstCapacityPtr,
196
- const void* src, size_t* srcSizePtr,
197
- int flush)
198
- {
199
- U32 notDone = 1;
200
- const char* const istart = (const char*)src;
201
- const char* const iend = istart + *srcSizePtr;
202
- const char* ip = istart;
203
- char* const ostart = (char*)dst;
204
- char* const oend = ostart + *dstCapacityPtr;
205
- char* op = ostart;
206
-
207
- while (notDone) {
208
- switch(zbc->stage)
209
- {
210
- case ZBUFFcs_init: return ERROR(init_missing); /* call ZBUFF_compressInit() first ! */
211
-
212
- case ZBUFFcs_load:
213
- /* complete inBuffer */
214
- { size_t const toLoad = zbc->inBuffTarget - zbc->inBuffPos;
215
- size_t const loaded = ZBUFF_limitCopy(zbc->inBuff + zbc->inBuffPos, toLoad, ip, iend-ip);
216
- zbc->inBuffPos += loaded;
217
- ip += loaded;
218
- if ( (zbc->inBuffPos==zbc->inToCompress) || (!flush && (toLoad != loaded)) ) {
219
- notDone = 0; break; /* not enough input to get a full block : stop there, wait for more */
220
- } }
221
- /* compress current block (note : this stage cannot be stopped in the middle) */
222
- { void* cDst;
223
- size_t cSize;
224
- size_t const iSize = zbc->inBuffPos - zbc->inToCompress;
225
- size_t oSize = oend-op;
226
- if (oSize >= ZSTD_compressBound(iSize))
227
- cDst = op; /* compress directly into output buffer (avoid flush stage) */
228
- else
229
- cDst = zbc->outBuff, oSize = zbc->outBuffSize;
230
- cSize = ZSTD_compressContinue(zbc->zc, cDst, oSize, zbc->inBuff + zbc->inToCompress, iSize);
231
- if (ZSTD_isError(cSize)) return cSize;
232
- /* prepare next block */
233
- zbc->inBuffTarget = zbc->inBuffPos + zbc->blockSize;
234
- if (zbc->inBuffTarget > zbc->inBuffSize)
235
- zbc->inBuffPos = 0, zbc->inBuffTarget = zbc->blockSize; /* note : inBuffSize >= blockSize */
236
- zbc->inToCompress = zbc->inBuffPos;
237
- if (cDst == op) { op += cSize; break; } /* no need to flush */
238
- zbc->outBuffContentSize = cSize;
239
- zbc->outBuffFlushedSize = 0;
240
- zbc->stage = ZBUFFcs_flush; /* continue to flush stage */
241
- }
242
-
243
- case ZBUFFcs_flush:
244
- { size_t const toFlush = zbc->outBuffContentSize - zbc->outBuffFlushedSize;
245
- size_t const flushed = ZBUFF_limitCopy(op, oend-op, zbc->outBuff + zbc->outBuffFlushedSize, toFlush);
246
- op += flushed;
247
- zbc->outBuffFlushedSize += flushed;
248
- if (toFlush!=flushed) { notDone = 0; break; } /* dst too small to store flushed data : stop there */
249
- zbc->outBuffContentSize = zbc->outBuffFlushedSize = 0;
250
- zbc->stage = ZBUFFcs_load;
251
- break;
252
- }
253
-
254
- case ZBUFFcs_final:
255
- notDone = 0; /* do nothing */
256
- break;
257
-
258
- default:
259
- return ERROR(GENERIC); /* impossible */
260
- }
261
- }
262
-
263
- *srcSizePtr = ip - istart;
264
- *dstCapacityPtr = op - ostart;
265
- { size_t hintInSize = zbc->inBuffTarget - zbc->inBuffPos;
266
- if (hintInSize==0) hintInSize = zbc->blockSize;
267
- return hintInSize;
268
- }
269
- }
270
-
271
- size_t ZBUFF_compressContinue(ZBUFF_CCtx* zbc,
272
- void* dst, size_t* dstCapacityPtr,
273
- const void* src, size_t* srcSizePtr)
274
- {
275
- return ZBUFF_compressContinue_generic(zbc, dst, dstCapacityPtr, src, srcSizePtr, 0);
276
- }
277
-
278
-
279
-
280
- /* *** Finalize *** */
281
-
282
- size_t ZBUFF_compressFlush(ZBUFF_CCtx* zbc, void* dst, size_t* dstCapacityPtr)
283
- {
284
- size_t srcSize = 0;
285
- ZBUFF_compressContinue_generic(zbc, dst, dstCapacityPtr, &srcSize, &srcSize, 1); /* use a valid src address instead of NULL */
286
- return zbc->outBuffContentSize - zbc->outBuffFlushedSize;
287
- }
288
-
289
-
290
- size_t ZBUFF_compressEnd(ZBUFF_CCtx* zbc, void* dst, size_t* dstCapacityPtr)
291
- {
292
- BYTE* const ostart = (BYTE*)dst;
293
- BYTE* const oend = ostart + *dstCapacityPtr;
294
- BYTE* op = ostart;
295
-
296
- if (zbc->stage != ZBUFFcs_final) {
297
- /* flush whatever remains */
298
- size_t outSize = *dstCapacityPtr;
299
- size_t const remainingToFlush = ZBUFF_compressFlush(zbc, dst, &outSize);
300
- op += outSize;
301
- if (remainingToFlush) {
302
- *dstCapacityPtr = op-ostart;
303
- return remainingToFlush + ZBUFF_endFrameSize;
304
- }
305
- /* create epilogue */
306
- zbc->stage = ZBUFFcs_final;
307
- zbc->outBuffContentSize = ZSTD_compressEnd(zbc->zc, zbc->outBuff, zbc->outBuffSize); /* epilogue into outBuff */
308
- }
309
-
310
- /* flush epilogue */
311
- { size_t const toFlush = zbc->outBuffContentSize - zbc->outBuffFlushedSize;
312
- size_t const flushed = ZBUFF_limitCopy(op, oend-op, zbc->outBuff + zbc->outBuffFlushedSize, toFlush);
313
- op += flushed;
314
- zbc->outBuffFlushedSize += flushed;
315
- *dstCapacityPtr = op-ostart;
316
- if (toFlush==flushed) zbc->stage = ZBUFFcs_init; /* end reached */
317
- return toFlush - flushed;
318
- }
319
- }
320
-
321
-
322
-
323
- /* *************************************
324
- * Tool functions
325
- ***************************************/
326
- size_t ZBUFF_recommendedCInSize(void) { return ZSTD_BLOCKSIZE_MAX; }
327
- size_t ZBUFF_recommendedCOutSize(void) { return ZSTD_compressBound(ZSTD_BLOCKSIZE_MAX) + ZSTD_blockHeaderSize + ZBUFF_endFrameSize; }
@@ -1,3074 +0,0 @@
1
- /*
2
- ZSTD HC - High Compression Mode of Zstandard
3
- Copyright (C) 2015-2016, Yann Collet.
4
-
5
- BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
6
-
7
- Redistribution and use in source and binary forms, with or without
8
- modification, are permitted provided that the following conditions are
9
- met:
10
-
11
- * Redistributions of source code must retain the above copyright
12
- notice, this list of conditions and the following disclaimer.
13
- * Redistributions in binary form must reproduce the above
14
- copyright notice, this list of conditions and the following disclaimer
15
- in the documentation and/or other materials provided with the
16
- distribution.
17
-
18
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22
- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
-
30
- You can contact the author at :
31
- - Zstd source repository : https://www.zstd.net
32
- */
33
-
34
-
35
- /* *******************************************************
36
- * Compiler specifics
37
- *********************************************************/
38
- #ifdef _MSC_VER /* Visual Studio */
39
- # define FORCE_INLINE static __forceinline
40
- # include <intrin.h> /* For Visual 2005 */
41
- # pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
42
- #else
43
- # ifdef __GNUC__
44
- # define FORCE_INLINE static inline __attribute__((always_inline))
45
- # else
46
- # define FORCE_INLINE static inline
47
- # endif
48
- #endif
49
-
50
-
51
- /*-*************************************
52
- * Dependencies
53
- ***************************************/
54
- #include <string.h> /* memset */
55
- #include "mem.h"
56
- #define XXH_STATIC_LINKING_ONLY /* XXH64_state_t */
57
- #include "xxhash.h" /* XXH_reset, update, digest */
58
- #define FSE_STATIC_LINKING_ONLY
59
- #include "fse.h"
60
- #define HUF_STATIC_LINKING_ONLY
61
- #include "huf.h"
62
- #include "zstd_internal.h" /* includes zstd.h */
63
-
64
-
65
- /*-*************************************
66
- * Constants
67
- ***************************************/
68
- static const U32 g_searchStrength = 8; /* control skip over incompressible data */
69
-
70
-
71
- /*-*************************************
72
- * Helper functions
73
- ***************************************/
74
- size_t ZSTD_compressBound(size_t srcSize) { return FSE_compressBound(srcSize) + 12; }
75
-
76
- static U32 ZSTD_highbit32(U32 val)
77
- {
78
- # if defined(_MSC_VER) /* Visual */
79
- unsigned long r=0;
80
- _BitScanReverse(&r, val);
81
- return (unsigned)r;
82
- # elif defined(__GNUC__) && (__GNUC__ >= 3) /* GCC Intrinsic */
83
- return 31 - __builtin_clz(val);
84
- # else /* Software version */
85
- static const int DeBruijnClz[32] = { 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 };
86
- U32 v = val;
87
- int r;
88
- v |= v >> 1;
89
- v |= v >> 2;
90
- v |= v >> 4;
91
- v |= v >> 8;
92
- v |= v >> 16;
93
- r = DeBruijnClz[(U32)(v * 0x07C4ACDDU) >> 27];
94
- return r;
95
- # endif
96
- }
97
-
98
- /*-*************************************
99
- * Sequence storage
100
- ***************************************/
101
- static void ZSTD_resetSeqStore(seqStore_t* ssPtr)
102
- {
103
- ssPtr->offset = ssPtr->offsetStart;
104
- ssPtr->lit = ssPtr->litStart;
105
- ssPtr->litLength = ssPtr->litLengthStart;
106
- ssPtr->matchLength = ssPtr->matchLengthStart;
107
- ssPtr->longLengthID = 0;
108
- }
109
-
110
-
111
- /*-*************************************
112
- * Context memory management
113
- ***************************************/
114
- struct ZSTD_CCtx_s
115
- {
116
- const BYTE* nextSrc; /* next block here to continue on current prefix */
117
- const BYTE* base; /* All regular indexes relative to this position */
118
- const BYTE* dictBase; /* extDict indexes relative to this position */
119
- U32 dictLimit; /* below that point, need extDict */
120
- U32 lowLimit; /* below that point, no more data */
121
- U32 nextToUpdate; /* index from which to continue dictionary update */
122
- U32 nextToUpdate3; /* index from which to continue dictionary update */
123
- U32 hashLog3; /* dispatch table : larger == faster, more memory */
124
- U32 loadedDictEnd;
125
- U32 stage; /* 0: created; 1: init,dictLoad; 2:started */
126
- U32 rep[ZSTD_REP_NUM];
127
- U32 savedRep[ZSTD_REP_NUM];
128
- U32 dictID;
129
- ZSTD_parameters params;
130
- void* workSpace;
131
- size_t workSpaceSize;
132
- size_t blockSize;
133
- U64 frameContentSize;
134
- XXH64_state_t xxhState;
135
- ZSTD_customMem customMem;
136
-
137
- seqStore_t seqStore; /* sequences storage ptrs */
138
- U32* hashTable;
139
- U32* hashTable3;
140
- U32* chainTable;
141
- HUF_CElt* hufTable;
142
- U32 flagStaticTables;
143
- FSE_CTable offcodeCTable [FSE_CTABLE_SIZE_U32(OffFSELog, MaxOff)];
144
- FSE_CTable matchlengthCTable [FSE_CTABLE_SIZE_U32(MLFSELog, MaxML)];
145
- FSE_CTable litlengthCTable [FSE_CTABLE_SIZE_U32(LLFSELog, MaxLL)];
146
- };
147
-
148
- ZSTD_CCtx* ZSTD_createCCtx(void)
149
- {
150
- return ZSTD_createCCtx_advanced(defaultCustomMem);
151
- }
152
-
153
- ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem)
154
- {
155
- ZSTD_CCtx* cctx;
156
-
157
- if (!customMem.customAlloc && !customMem.customFree)
158
- customMem = defaultCustomMem;
159
-
160
- if (!customMem.customAlloc || !customMem.customFree)
161
- return NULL;
162
-
163
- cctx = (ZSTD_CCtx*) customMem.customAlloc(customMem.opaque, sizeof(ZSTD_CCtx));
164
- if (!cctx) return NULL;
165
- memset(cctx, 0, sizeof(ZSTD_CCtx));
166
- memcpy(&(cctx->customMem), &customMem, sizeof(ZSTD_customMem));
167
- return cctx;
168
- }
169
-
170
- size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx)
171
- {
172
- if (cctx==NULL) return 0; /* support free on NULL */
173
- if (cctx->workSpace) cctx->customMem.customFree(cctx->customMem.opaque, cctx->workSpace);
174
- cctx->customMem.customFree(cctx->customMem.opaque, cctx);
175
- return 0; /* reserved as a potential error code in the future */
176
- }
177
-
178
- size_t ZSTD_sizeofCCtx(const ZSTD_CCtx* cctx)
179
- {
180
- return sizeof(*cctx) + cctx->workSpaceSize;
181
- }
182
-
183
- const seqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx) /* hidden interface */
184
- {
185
- return &(ctx->seqStore);
186
- }
187
-
188
-
189
- #define CLAMP(val,min,max) { if (val<min) val=min; else if (val>max) val=max; }
190
- #define CLAMPCHECK(val,min,max) { if ((val<min) || (val>max)) return ERROR(compressionParameter_unsupported); }
191
-
192
- /** ZSTD_checkParams() :
193
- ensure param values remain within authorized range.
194
- @return : 0, or an error code if one value is beyond authorized range */
195
- size_t ZSTD_checkCParams(ZSTD_compressionParameters cParams)
196
- {
197
- CLAMPCHECK(cParams.windowLog, ZSTD_WINDOWLOG_MIN, ZSTD_WINDOWLOG_MAX);
198
- CLAMPCHECK(cParams.chainLog, ZSTD_CHAINLOG_MIN, ZSTD_CHAINLOG_MAX);
199
- CLAMPCHECK(cParams.hashLog, ZSTD_HASHLOG_MIN, ZSTD_HASHLOG_MAX);
200
- CLAMPCHECK(cParams.searchLog, ZSTD_SEARCHLOG_MIN, ZSTD_SEARCHLOG_MAX);
201
- { U32 const searchLengthMin = (cParams.strategy == ZSTD_fast || cParams.strategy == ZSTD_greedy) ? ZSTD_SEARCHLENGTH_MIN+1 : ZSTD_SEARCHLENGTH_MIN;
202
- U32 const searchLengthMax = (cParams.strategy == ZSTD_fast) ? ZSTD_SEARCHLENGTH_MAX : ZSTD_SEARCHLENGTH_MAX-1;
203
- CLAMPCHECK(cParams.searchLength, searchLengthMin, searchLengthMax); }
204
- CLAMPCHECK(cParams.targetLength, ZSTD_TARGETLENGTH_MIN, ZSTD_TARGETLENGTH_MAX);
205
- if ((U32)(cParams.strategy) > (U32)ZSTD_btopt) return ERROR(compressionParameter_unsupported);
206
- return 0;
207
- }
208
-
209
-
210
- /** ZSTD_checkCParams_advanced() :
211
- temporary work-around, while the compressor compatibility remains limited regarding windowLog < 18 */
212
- size_t ZSTD_checkCParams_advanced(ZSTD_compressionParameters cParams, U64 srcSize)
213
- {
214
- if (srcSize > (1ULL << ZSTD_WINDOWLOG_MIN)) return ZSTD_checkCParams(cParams);
215
- if (cParams.windowLog < ZSTD_WINDOWLOG_ABSOLUTEMIN) return ERROR(compressionParameter_unsupported);
216
- if (srcSize <= (1ULL << cParams.windowLog)) cParams.windowLog = ZSTD_WINDOWLOG_MIN; /* fake value - temporary work around */
217
- if (srcSize <= (1ULL << cParams.chainLog)) cParams.chainLog = ZSTD_CHAINLOG_MIN; /* fake value - temporary work around */
218
- if ((srcSize <= (1ULL << cParams.hashLog)) && ((U32)cParams.strategy < (U32)ZSTD_btlazy2)) cParams.hashLog = ZSTD_HASHLOG_MIN; /* fake value - temporary work around */
219
- return ZSTD_checkCParams(cParams);
220
- }
221
-
222
-
223
- /** ZSTD_adjustCParams() :
224
- optimize cPar for a given input (`srcSize` and `dictSize`).
225
- mostly downsizing to reduce memory consumption and initialization.
226
- Both `srcSize` and `dictSize` are optional (use 0 if unknown),
227
- but if both are 0, no optimization can be done.
228
- Note : cPar is considered validated at this stage. Use ZSTD_checkParams() to ensure that. */
229
- ZSTD_compressionParameters ZSTD_adjustCParams(ZSTD_compressionParameters cPar, unsigned long long srcSize, size_t dictSize)
230
- {
231
- if (srcSize+dictSize == 0) return cPar; /* no size information available : no adjustment */
232
-
233
- /* resize params, to use less memory when necessary */
234
- { U32 const minSrcSize = (srcSize==0) ? 500 : 0;
235
- U64 const rSize = srcSize + dictSize + minSrcSize;
236
- if (rSize < ((U64)1<<ZSTD_WINDOWLOG_MAX)) {
237
- U32 const srcLog = ZSTD_highbit32((U32)(rSize)-1) + 1;
238
- if (cPar.windowLog > srcLog) cPar.windowLog = srcLog;
239
- } }
240
- if (cPar.hashLog > cPar.windowLog) cPar.hashLog = cPar.windowLog;
241
- { U32 const btPlus = (cPar.strategy == ZSTD_btlazy2) || (cPar.strategy == ZSTD_btopt);
242
- U32 const maxChainLog = cPar.windowLog+btPlus;
243
- if (cPar.chainLog > maxChainLog) cPar.chainLog = maxChainLog; } /* <= ZSTD_CHAINLOG_MAX */
244
-
245
- if (cPar.windowLog < ZSTD_WINDOWLOG_ABSOLUTEMIN) cPar.windowLog = ZSTD_WINDOWLOG_ABSOLUTEMIN; /* required for frame header */
246
- if ((cPar.hashLog < ZSTD_HASHLOG_MIN) && ( (U32)cPar.strategy >= (U32)ZSTD_btlazy2)) cPar.hashLog = ZSTD_HASHLOG_MIN; /* required to ensure collision resistance in bt */
247
-
248
- return cPar;
249
- }
250
-
251
-
252
- size_t ZSTD_estimateCCtxSize(ZSTD_compressionParameters cParams)
253
- {
254
- const size_t blockSize = MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << cParams.windowLog);
255
- const U32 divider = (cParams.searchLength==3) ? 3 : 4;
256
- const size_t maxNbSeq = blockSize / divider;
257
- const size_t tokenSpace = blockSize + 11*maxNbSeq;
258
-
259
- const size_t chainSize = (cParams.strategy == ZSTD_fast) ? 0 : (1 << cParams.chainLog);
260
- const size_t hSize = ((size_t)1) << cParams.hashLog;
261
- const U32 hashLog3 = (cParams.searchLength>3) ? 0 : MIN(ZSTD_HASHLOG3_MAX, cParams.windowLog);
262
- const size_t h3Size = ((size_t)1) << hashLog3;
263
- const size_t tableSpace = (chainSize + hSize + h3Size) * sizeof(U32);
264
-
265
- size_t const optSpace = ((MaxML+1) + (MaxLL+1) + (MaxOff+1) + (1<<Litbits))*sizeof(U32)
266
- + (ZSTD_OPT_NUM+1)*(sizeof(ZSTD_match_t) + sizeof(ZSTD_optimal_t));
267
- size_t const neededSpace = tableSpace + (256*sizeof(U32)) /* huffTable */ + tokenSpace
268
- + ((cParams.strategy == ZSTD_btopt) ? optSpace : 0);
269
-
270
- return sizeof(ZSTD_CCtx) + neededSpace;
271
- }
272
-
273
- /*! ZSTD_resetCCtx_advanced() :
274
- note : 'params' is expected to be validated */
275
- static size_t ZSTD_resetCCtx_advanced (ZSTD_CCtx* zc,
276
- ZSTD_parameters params, U64 frameContentSize,
277
- U32 reset)
278
- { /* note : params considered validated here */
279
- const size_t blockSize = MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << params.cParams.windowLog);
280
- const U32 divider = (params.cParams.searchLength==3) ? 3 : 4;
281
- const size_t maxNbSeq = blockSize / divider;
282
- const size_t tokenSpace = blockSize + 11*maxNbSeq;
283
- const size_t chainSize = (params.cParams.strategy == ZSTD_fast) ? 0 : (1 << params.cParams.chainLog);
284
- const size_t hSize = ((size_t)1) << params.cParams.hashLog;
285
- const U32 hashLog3 = (params.cParams.searchLength>3) ? 0 : MIN(ZSTD_HASHLOG3_MAX, params.cParams.windowLog);
286
- const size_t h3Size = ((size_t)1) << hashLog3;
287
- const size_t tableSpace = (chainSize + hSize + h3Size) * sizeof(U32);
288
-
289
- /* Check if workSpace is large enough, alloc a new one if needed */
290
- { size_t const optSpace = ((MaxML+1) + (MaxLL+1) + (MaxOff+1) + (1<<Litbits))*sizeof(U32)
291
- + (ZSTD_OPT_NUM+1)*(sizeof(ZSTD_match_t) + sizeof(ZSTD_optimal_t));
292
- size_t const neededSpace = tableSpace + (256*sizeof(U32)) /* huffTable */ + tokenSpace
293
- + ((params.cParams.strategy == ZSTD_btopt) ? optSpace : 0);
294
- if (zc->workSpaceSize < neededSpace) {
295
- zc->customMem.customFree(zc->customMem.opaque, zc->workSpace);
296
- zc->workSpace = zc->customMem.customAlloc(zc->customMem.opaque, neededSpace);
297
- if (zc->workSpace == NULL) return ERROR(memory_allocation);
298
- zc->workSpaceSize = neededSpace;
299
- } }
300
-
301
- if (reset) memset(zc->workSpace, 0, tableSpace ); /* reset only tables */
302
- XXH64_reset(&zc->xxhState, 0);
303
- zc->hashLog3 = hashLog3;
304
- zc->hashTable = (U32*)(zc->workSpace);
305
- zc->chainTable = zc->hashTable + hSize;
306
- zc->hashTable3 = zc->chainTable + chainSize;
307
- zc->seqStore.buffer = zc->hashTable3 + h3Size;
308
- zc->hufTable = (HUF_CElt*)zc->seqStore.buffer;
309
- zc->flagStaticTables = 0;
310
- zc->seqStore.buffer = ((U32*)(zc->seqStore.buffer)) + 256; /* note : HUF_CElt* is incomplete type, size is simulated using U32 */
311
-
312
- zc->nextToUpdate = 1;
313
- zc->nextSrc = NULL;
314
- zc->base = NULL;
315
- zc->dictBase = NULL;
316
- zc->dictLimit = 0;
317
- zc->lowLimit = 0;
318
- zc->params = params;
319
- zc->blockSize = blockSize;
320
- zc->frameContentSize = frameContentSize;
321
- { int i; for (i=0; i<ZSTD_REP_NUM; i++) zc->rep[i] = repStartValue[i]; }
322
-
323
- if (params.cParams.strategy == ZSTD_btopt) {
324
- zc->seqStore.litFreq = (U32*)(zc->seqStore.buffer);
325
- zc->seqStore.litLengthFreq = zc->seqStore.litFreq + (1<<Litbits);
326
- zc->seqStore.matchLengthFreq = zc->seqStore.litLengthFreq + (MaxLL+1);
327
- zc->seqStore.offCodeFreq = zc->seqStore.matchLengthFreq + (MaxML+1);
328
- zc->seqStore.buffer = zc->seqStore.offCodeFreq + (MaxOff+1);
329
- zc->seqStore.matchTable = (ZSTD_match_t*)zc->seqStore.buffer;
330
- zc->seqStore.buffer = zc->seqStore.matchTable + ZSTD_OPT_NUM+1;
331
- zc->seqStore.priceTable = (ZSTD_optimal_t*)zc->seqStore.buffer;
332
- zc->seqStore.buffer = zc->seqStore.priceTable + ZSTD_OPT_NUM+1;
333
- zc->seqStore.litLengthSum = 0;
334
- }
335
- zc->seqStore.offsetStart = (U32*)(zc->seqStore.buffer);
336
- zc->seqStore.buffer = zc->seqStore.offsetStart + maxNbSeq;
337
- zc->seqStore.litLengthStart = (U16*)zc->seqStore.buffer;
338
- zc->seqStore.matchLengthStart = zc->seqStore.litLengthStart + maxNbSeq;
339
- zc->seqStore.llCodeStart = (BYTE*) (zc->seqStore.matchLengthStart + maxNbSeq);
340
- zc->seqStore.mlCodeStart = zc->seqStore.llCodeStart + maxNbSeq;
341
- zc->seqStore.offCodeStart = zc->seqStore.mlCodeStart + maxNbSeq;
342
- zc->seqStore.litStart = zc->seqStore.offCodeStart + maxNbSeq;
343
-
344
- zc->stage = 1;
345
- zc->dictID = 0;
346
- zc->loadedDictEnd = 0;
347
-
348
- return 0;
349
- }
350
-
351
-
352
- /*! ZSTD_copyCCtx() :
353
- * Duplicate an existing context `srcCCtx` into another one `dstCCtx`.
354
- * Only works during stage 1 (i.e. after creation, but before first call to ZSTD_compressContinue()).
355
- * @return : 0, or an error code */
356
- size_t ZSTD_copyCCtx(ZSTD_CCtx* dstCCtx, const ZSTD_CCtx* srcCCtx)
357
- {
358
- if (srcCCtx->stage!=1) return ERROR(stage_wrong);
359
-
360
- memcpy(&dstCCtx->customMem, &srcCCtx->customMem, sizeof(ZSTD_customMem));
361
- ZSTD_resetCCtx_advanced(dstCCtx, srcCCtx->params, srcCCtx->frameContentSize, 0);
362
- dstCCtx->params.fParams.contentSizeFlag = 0; /* content size different from the one set during srcCCtx init */
363
-
364
- /* copy tables */
365
- { const size_t chainSize = (srcCCtx->params.cParams.strategy == ZSTD_fast) ? 0 : (1 << srcCCtx->params.cParams.chainLog);
366
- const size_t hSize = ((size_t)1) << srcCCtx->params.cParams.hashLog;
367
- const size_t h3Size = (size_t)1 << srcCCtx->hashLog3;
368
- const size_t tableSpace = (chainSize + hSize + h3Size) * sizeof(U32);
369
- memcpy(dstCCtx->workSpace, srcCCtx->workSpace, tableSpace);
370
- }
371
-
372
- /* copy dictionary offsets */
373
- dstCCtx->nextToUpdate = srcCCtx->nextToUpdate;
374
- dstCCtx->nextToUpdate3= srcCCtx->nextToUpdate3;
375
- dstCCtx->nextSrc = srcCCtx->nextSrc;
376
- dstCCtx->base = srcCCtx->base;
377
- dstCCtx->dictBase = srcCCtx->dictBase;
378
- dstCCtx->dictLimit = srcCCtx->dictLimit;
379
- dstCCtx->lowLimit = srcCCtx->lowLimit;
380
- dstCCtx->loadedDictEnd= srcCCtx->loadedDictEnd;
381
- dstCCtx->dictID = srcCCtx->dictID;
382
-
383
- /* copy entropy tables */
384
- dstCCtx->flagStaticTables = srcCCtx->flagStaticTables;
385
- if (srcCCtx->flagStaticTables) {
386
- memcpy(dstCCtx->hufTable, srcCCtx->hufTable, 256*4);
387
- memcpy(dstCCtx->litlengthCTable, srcCCtx->litlengthCTable, sizeof(dstCCtx->litlengthCTable));
388
- memcpy(dstCCtx->matchlengthCTable, srcCCtx->matchlengthCTable, sizeof(dstCCtx->matchlengthCTable));
389
- memcpy(dstCCtx->offcodeCTable, srcCCtx->offcodeCTable, sizeof(dstCCtx->offcodeCTable));
390
- }
391
-
392
- return 0;
393
- }
394
-
395
-
396
- /*! ZSTD_reduceTable() :
397
- * reduce table indexes by `reducerValue` */
398
- static void ZSTD_reduceTable (U32* const table, U32 const size, U32 const reducerValue)
399
- {
400
- U32 u;
401
- for (u=0 ; u < size ; u++) {
402
- if (table[u] < reducerValue) table[u] = 0;
403
- else table[u] -= reducerValue;
404
- }
405
- }
406
-
407
- /*! ZSTD_reduceIndex() :
408
- * rescale all indexes to avoid future overflow (indexes are U32) */
409
- static void ZSTD_reduceIndex (ZSTD_CCtx* zc, const U32 reducerValue)
410
- {
411
- { const U32 hSize = 1 << zc->params.cParams.hashLog;
412
- ZSTD_reduceTable(zc->hashTable, hSize, reducerValue); }
413
-
414
- { const U32 chainSize = (zc->params.cParams.strategy == ZSTD_fast) ? 0 : (1 << zc->params.cParams.chainLog);
415
- ZSTD_reduceTable(zc->chainTable, chainSize, reducerValue); }
416
-
417
- { const U32 h3Size = (zc->hashLog3) ? 1 << zc->hashLog3 : 0;
418
- ZSTD_reduceTable(zc->hashTable3, h3Size, reducerValue); }
419
- }
420
-
421
-
422
- /*-*******************************************************
423
- * Block entropic compression
424
- *********************************************************/
425
-
426
- /* Frame format description
427
- Frame Header - [ Block Header - Block ] - Frame End
428
- 1) Frame Header
429
- - 4 bytes : Magic Number : ZSTD_MAGICNUMBER (defined within zstd_static.h)
430
- - 1 byte : Frame Header Descriptor
431
- - 1-13 bytes : Optional fields
432
- 2) Block Header
433
- - 3 bytes, starting with a 2-bits descriptor
434
- Uncompressed, Compressed, Frame End, unused
435
- 3) Block
436
- See Block Format Description
437
- 4) Frame End
438
- - 3 bytes, compatible with Block Header
439
- */
440
-
441
-
442
- /* Frame header :
443
-
444
- 1 byte - FrameHeaderDescription :
445
- bit 0-1 : dictID (0, 1, 2 or 4 bytes)
446
- bit 2-4 : reserved (must be zero)
447
- bit 5 : SkippedWindowLog (if 1, WindowLog byte is not present)
448
- bit 6-7 : FrameContentFieldsize (0, 2, 4, or 8)
449
- if (SkippedWindowLog && !FrameContentFieldsize) FrameContentFieldsize=1;
450
-
451
- Optional : WindowLog (0 or 1 byte)
452
- bit 0-2 : octal Fractional (1/8th)
453
- bit 3-7 : Power of 2, with 0 = 1 KB (up to 2 TB)
454
-
455
- Optional : content size (0, 1, 2, 4 or 8 bytes)
456
- 0 : unknown
457
- 1 : 0-255 bytes
458
- 2 : 256 - 65535+256
459
- 8 : up to 16 exa
460
-
461
- Optional : dictID (0, 1, 2 or 4 bytes)
462
- Automatic adaptation
463
- 0 : no dictID
464
- 1 : 1 - 255
465
- 2 : 256 - 65535
466
- 4 : all other values
467
- */
468
-
469
-
470
- /* Block format description
471
-
472
- Block = Literals Section - Sequences Section
473
- Prerequisite : size of (compressed) block, maximum size of regenerated data
474
-
475
- 1) Literal Section
476
-
477
- 1.1) Header : 1-5 bytes
478
- flags: 2 bits
479
- 00 compressed by Huff0
480
- 01 repeat
481
- 10 is Raw (uncompressed)
482
- 11 is Rle
483
- Note : using 01 => Huff0 with precomputed table ?
484
- Note : delta map ? => compressed ?
485
-
486
- 1.1.1) Huff0-compressed literal block : 3-5 bytes
487
- srcSize < 1 KB => 3 bytes (2-2-10-10) => single stream
488
- srcSize < 1 KB => 3 bytes (2-2-10-10)
489
- srcSize < 16KB => 4 bytes (2-2-14-14)
490
- else => 5 bytes (2-2-18-18)
491
- big endian convention
492
-
493
- 1.1.2) Raw (uncompressed) literal block header : 1-3 bytes
494
- size : 5 bits: (IS_RAW<<6) + (0<<4) + size
495
- 12 bits: (IS_RAW<<6) + (2<<4) + (size>>8)
496
- size&255
497
- 20 bits: (IS_RAW<<6) + (3<<4) + (size>>16)
498
- size>>8&255
499
- size&255
500
-
501
- 1.1.3) Rle (repeated single byte) literal block header : 1-3 bytes
502
- size : 5 bits: (IS_RLE<<6) + (0<<4) + size
503
- 12 bits: (IS_RLE<<6) + (2<<4) + (size>>8)
504
- size&255
505
- 20 bits: (IS_RLE<<6) + (3<<4) + (size>>16)
506
- size>>8&255
507
- size&255
508
-
509
- 1.1.4) Huff0-compressed literal block, using precomputed CTables : 3-5 bytes
510
- srcSize < 1 KB => 3 bytes (2-2-10-10) => single stream
511
- srcSize < 1 KB => 3 bytes (2-2-10-10)
512
- srcSize < 16KB => 4 bytes (2-2-14-14)
513
- else => 5 bytes (2-2-18-18)
514
- big endian convention
515
-
516
- 1- CTable available (stored into workspace)
517
- 2- Small input (fast heuristic ? Full comparison ? depend on clevel ?)
518
-
519
-
520
- 1.2) Literal block content
521
-
522
- 1.2.1) Huff0 block, using sizes from header
523
- See Huff0 format
524
-
525
- 1.2.2) Huff0 block, using prepared table
526
-
527
- 1.2.3) Raw content
528
-
529
- 1.2.4) single byte
530
-
531
-
532
- 2) Sequences section
533
-
534
- - Nb Sequences : 2 bytes, little endian
535
- - Control Token : 1 byte (see below)
536
- - Dumps Length : 1 or 2 bytes (depending on control token)
537
- - Dumps : as stated by dumps length
538
- - Literal Lengths FSE table (as needed depending on encoding method)
539
- - Offset Codes FSE table (as needed depending on encoding method)
540
- - Match Lengths FSE table (as needed depending on encoding method)
541
-
542
- 2.1) Control Token
543
- 8 bits, divided as :
544
- 0-1 : dumpsLength
545
- 2-3 : MatchLength, FSE encoding method
546
- 4-5 : Offset Codes, FSE encoding method
547
- 6-7 : Literal Lengths, FSE encoding method
548
-
549
- FSE encoding method :
550
- FSE_ENCODING_RAW : uncompressed; no header
551
- FSE_ENCODING_RLE : single repeated value; header 1 byte
552
- FSE_ENCODING_STATIC : use prepared table; no header
553
- FSE_ENCODING_DYNAMIC : read NCount
554
- */
555
-
556
- size_t ZSTD_noCompressBlock (void* dst, size_t dstCapacity, const void* src, size_t srcSize)
557
- {
558
- BYTE* const ostart = (BYTE* const)dst;
559
-
560
- if (srcSize + ZSTD_blockHeaderSize > dstCapacity) return ERROR(dstSize_tooSmall);
561
- memcpy(ostart + ZSTD_blockHeaderSize, src, srcSize);
562
-
563
- /* Build header */
564
- ostart[0] = (BYTE)(srcSize>>16);
565
- ostart[1] = (BYTE)(srcSize>>8);
566
- ostart[2] = (BYTE) srcSize;
567
- ostart[0] += (BYTE)(bt_raw<<6); /* is a raw (uncompressed) block */
568
-
569
- return ZSTD_blockHeaderSize+srcSize;
570
- }
571
-
572
-
573
- static size_t ZSTD_noCompressLiterals (void* dst, size_t dstCapacity, const void* src, size_t srcSize)
574
- {
575
- BYTE* const ostart = (BYTE* const)dst;
576
- U32 const flSize = 1 + (srcSize>31) + (srcSize>4095);
577
-
578
- if (srcSize + flSize > dstCapacity) return ERROR(dstSize_tooSmall);
579
-
580
- switch(flSize)
581
- {
582
- case 1: /* 2 - 1 - 5 */
583
- ostart[0] = (BYTE)((lbt_raw<<6) + (0<<5) + srcSize);
584
- break;
585
- case 2: /* 2 - 2 - 12 */
586
- ostart[0] = (BYTE)((lbt_raw<<6) + (2<<4) + (srcSize >> 8));
587
- ostart[1] = (BYTE)srcSize;
588
- break;
589
- default: /*note : should not be necessary : flSize is within {1,2,3} */
590
- case 3: /* 2 - 2 - 20 */
591
- ostart[0] = (BYTE)((lbt_raw<<6) + (3<<4) + (srcSize >> 16));
592
- ostart[1] = (BYTE)(srcSize>>8);
593
- ostart[2] = (BYTE)srcSize;
594
- break;
595
- }
596
-
597
- memcpy(ostart + flSize, src, srcSize);
598
- return srcSize + flSize;
599
- }
600
-
601
- static size_t ZSTD_compressRleLiteralsBlock (void* dst, size_t dstCapacity, const void* src, size_t srcSize)
602
- {
603
- BYTE* const ostart = (BYTE* const)dst;
604
- U32 const flSize = 1 + (srcSize>31) + (srcSize>4095);
605
-
606
- (void)dstCapacity; /* dstCapacity guaranteed to be >=4, hence large enough */
607
-
608
- switch(flSize)
609
- {
610
- case 1: /* 2 - 1 - 5 */
611
- ostart[0] = (BYTE)((lbt_rle<<6) + (0<<5) + srcSize);
612
- break;
613
- case 2: /* 2 - 2 - 12 */
614
- ostart[0] = (BYTE)((lbt_rle<<6) + (2<<4) + (srcSize >> 8));
615
- ostart[1] = (BYTE)srcSize;
616
- break;
617
- default: /*note : should not be necessary : flSize is necessarily within {1,2,3} */
618
- case 3: /* 2 - 2 - 20 */
619
- ostart[0] = (BYTE)((lbt_rle<<6) + (3<<4) + (srcSize >> 16));
620
- ostart[1] = (BYTE)(srcSize>>8);
621
- ostart[2] = (BYTE)srcSize;
622
- break;
623
- }
624
-
625
- ostart[flSize] = *(const BYTE*)src;
626
- return flSize+1;
627
- }
628
-
629
-
630
- static size_t ZSTD_minGain(size_t srcSize) { return (srcSize >> 6) + 2; }
631
-
632
- static size_t ZSTD_compressLiterals (ZSTD_CCtx* zc,
633
- void* dst, size_t dstCapacity,
634
- const void* src, size_t srcSize)
635
- {
636
- size_t const minGain = ZSTD_minGain(srcSize);
637
- size_t const lhSize = 3 + (srcSize >= 1 KB) + (srcSize >= 16 KB);
638
- BYTE* const ostart = (BYTE*)dst;
639
- U32 singleStream = srcSize < 256;
640
- litBlockType_t hType = lbt_huffman;
641
- size_t cLitSize;
642
-
643
-
644
- /* small ? don't even attempt compression (speed opt) */
645
- # define LITERAL_NOENTROPY 63
646
- { size_t const minLitSize = zc->flagStaticTables ? 6 : LITERAL_NOENTROPY;
647
- if (srcSize <= minLitSize) return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
648
- }
649
-
650
- if (dstCapacity < lhSize+1) return ERROR(dstSize_tooSmall); /* not enough space for compression */
651
- if (zc->flagStaticTables && (lhSize==3)) {
652
- hType = lbt_repeat;
653
- singleStream = 1;
654
- cLitSize = HUF_compress1X_usingCTable(ostart+lhSize, dstCapacity-lhSize, src, srcSize, zc->hufTable);
655
- } else {
656
- cLitSize = singleStream ? HUF_compress1X(ostart+lhSize, dstCapacity-lhSize, src, srcSize, 255, 11)
657
- : HUF_compress2 (ostart+lhSize, dstCapacity-lhSize, src, srcSize, 255, 11);
658
- }
659
-
660
- if ((cLitSize==0) | (cLitSize >= srcSize - minGain))
661
- return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
662
- if (cLitSize==1)
663
- return ZSTD_compressRleLiteralsBlock(dst, dstCapacity, src, srcSize);
664
-
665
- /* Build header */
666
- switch(lhSize)
667
- {
668
- case 3: /* 2 - 2 - 10 - 10 */
669
- ostart[0] = (BYTE)((srcSize>>6) + (singleStream << 4) + (hType<<6));
670
- ostart[1] = (BYTE)((srcSize<<2) + (cLitSize>>8));
671
- ostart[2] = (BYTE)(cLitSize);
672
- break;
673
- case 4: /* 2 - 2 - 14 - 14 */
674
- ostart[0] = (BYTE)((srcSize>>10) + (2<<4) + (hType<<6));
675
- ostart[1] = (BYTE)(srcSize>> 2);
676
- ostart[2] = (BYTE)((srcSize<<6) + (cLitSize>>8));
677
- ostart[3] = (BYTE)(cLitSize);
678
- break;
679
- default: /* should not be necessary, lhSize is only {3,4,5} */
680
- case 5: /* 2 - 2 - 18 - 18 */
681
- ostart[0] = (BYTE)((srcSize>>14) + (3<<4) + (hType<<6));
682
- ostart[1] = (BYTE)(srcSize>>6);
683
- ostart[2] = (BYTE)((srcSize<<2) + (cLitSize>>16));
684
- ostart[3] = (BYTE)(cLitSize>>8);
685
- ostart[4] = (BYTE)(cLitSize);
686
- break;
687
- }
688
- return lhSize+cLitSize;
689
- }
690
-
691
-
692
- void ZSTD_seqToCodes(const seqStore_t* seqStorePtr, size_t const nbSeq)
693
- {
694
- /* LL codes */
695
- { static const BYTE LL_Code[64] = { 0, 1, 2, 3, 4, 5, 6, 7,
696
- 8, 9, 10, 11, 12, 13, 14, 15,
697
- 16, 16, 17, 17, 18, 18, 19, 19,
698
- 20, 20, 20, 20, 21, 21, 21, 21,
699
- 22, 22, 22, 22, 22, 22, 22, 22,
700
- 23, 23, 23, 23, 23, 23, 23, 23,
701
- 24, 24, 24, 24, 24, 24, 24, 24,
702
- 24, 24, 24, 24, 24, 24, 24, 24 };
703
- const BYTE LL_deltaCode = 19;
704
- const U16* const llTable = seqStorePtr->litLengthStart;
705
- BYTE* const llCodeTable = seqStorePtr->llCodeStart;
706
- size_t u;
707
- for (u=0; u<nbSeq; u++) {
708
- U32 const ll = llTable[u];
709
- llCodeTable[u] = (ll>63) ? (BYTE)ZSTD_highbit32(ll) + LL_deltaCode : LL_Code[ll];
710
- }
711
- if (seqStorePtr->longLengthID==1)
712
- llCodeTable[seqStorePtr->longLengthPos] = MaxLL;
713
- }
714
-
715
- /* Offset codes */
716
- { const U32* const offsetTable = seqStorePtr->offsetStart;
717
- BYTE* const ofCodeTable = seqStorePtr->offCodeStart;
718
- size_t u;
719
- for (u=0; u<nbSeq; u++) ofCodeTable[u] = (BYTE)ZSTD_highbit32(offsetTable[u]);
720
- }
721
-
722
- /* ML codes */
723
- { static const BYTE ML_Code[128] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
724
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
725
- 32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 36, 36, 37, 37, 37, 37,
726
- 38, 38, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 39, 39,
727
- 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
728
- 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
729
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
730
- 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42 };
731
- const BYTE ML_deltaCode = 36;
732
- const U16* const mlTable = seqStorePtr->matchLengthStart;
733
- BYTE* const mlCodeTable = seqStorePtr->mlCodeStart;
734
- size_t u;
735
- for (u=0; u<nbSeq; u++) {
736
- U32 const ml = mlTable[u];
737
- mlCodeTable[u] = (ml>127) ? (BYTE)ZSTD_highbit32(ml) + ML_deltaCode : ML_Code[ml];
738
- }
739
- if (seqStorePtr->longLengthID==2)
740
- mlCodeTable[seqStorePtr->longLengthPos] = MaxML;
741
- }
742
- }
743
-
744
-
745
- size_t ZSTD_compressSequences(ZSTD_CCtx* zc,
746
- void* dst, size_t dstCapacity,
747
- size_t srcSize)
748
- {
749
- const seqStore_t* seqStorePtr = &(zc->seqStore);
750
- U32 count[MaxSeq+1];
751
- S16 norm[MaxSeq+1];
752
- FSE_CTable* CTable_LitLength = zc->litlengthCTable;
753
- FSE_CTable* CTable_OffsetBits = zc->offcodeCTable;
754
- FSE_CTable* CTable_MatchLength = zc->matchlengthCTable;
755
- U32 LLtype, Offtype, MLtype; /* compressed, raw or rle */
756
- U16* const llTable = seqStorePtr->litLengthStart;
757
- U16* const mlTable = seqStorePtr->matchLengthStart;
758
- const U32* const offsetTable = seqStorePtr->offsetStart;
759
- const U32* const offsetTableEnd = seqStorePtr->offset;
760
- BYTE* const ofCodeTable = seqStorePtr->offCodeStart;
761
- BYTE* const llCodeTable = seqStorePtr->llCodeStart;
762
- BYTE* const mlCodeTable = seqStorePtr->mlCodeStart;
763
- BYTE* const ostart = (BYTE*)dst;
764
- BYTE* const oend = ostart + dstCapacity;
765
- BYTE* op = ostart;
766
- size_t const nbSeq = offsetTableEnd - offsetTable;
767
- BYTE* seqHead;
768
-
769
- /* Compress literals */
770
- { const BYTE* const literals = seqStorePtr->litStart;
771
- size_t const litSize = seqStorePtr->lit - literals;
772
- size_t const cSize = ZSTD_compressLiterals(zc, op, dstCapacity, literals, litSize);
773
- if (ZSTD_isError(cSize)) return cSize;
774
- op += cSize;
775
- }
776
-
777
- /* Sequences Header */
778
- if ((oend-op) < 3 /*max nbSeq Size*/ + 1 /*seqHead */) return ERROR(dstSize_tooSmall);
779
- if (nbSeq < 0x7F) *op++ = (BYTE)nbSeq;
780
- else if (nbSeq < LONGNBSEQ) op[0] = (BYTE)((nbSeq>>8) + 0x80), op[1] = (BYTE)nbSeq, op+=2;
781
- else op[0]=0xFF, MEM_writeLE16(op+1, (U16)(nbSeq - LONGNBSEQ)), op+=3;
782
- if (nbSeq==0) goto _check_compressibility;
783
-
784
- /* seqHead : flags for FSE encoding type */
785
- seqHead = op++;
786
-
787
- #define MIN_SEQ_FOR_DYNAMIC_FSE 64
788
- #define MAX_SEQ_FOR_STATIC_FSE 1000
789
-
790
- /* convert length/distances into codes */
791
- ZSTD_seqToCodes(seqStorePtr, nbSeq);
792
-
793
- /* CTable for Literal Lengths */
794
- { U32 max = MaxLL;
795
- size_t const mostFrequent = FSE_countFast(count, &max, llCodeTable, nbSeq);
796
- if ((mostFrequent == nbSeq) && (nbSeq > 2)) {
797
- *op++ = llCodeTable[0];
798
- FSE_buildCTable_rle(CTable_LitLength, (BYTE)max);
799
- LLtype = FSE_ENCODING_RLE;
800
- } else if ((zc->flagStaticTables) && (nbSeq < MAX_SEQ_FOR_STATIC_FSE)) {
801
- LLtype = FSE_ENCODING_STATIC;
802
- } else if ((nbSeq < MIN_SEQ_FOR_DYNAMIC_FSE) || (mostFrequent < (nbSeq >> (LL_defaultNormLog-1)))) {
803
- FSE_buildCTable(CTable_LitLength, LL_defaultNorm, MaxLL, LL_defaultNormLog);
804
- LLtype = FSE_ENCODING_RAW;
805
- } else {
806
- size_t nbSeq_1 = nbSeq;
807
- const U32 tableLog = FSE_optimalTableLog(LLFSELog, nbSeq, max);
808
- if (count[llCodeTable[nbSeq-1]]>1) { count[llCodeTable[nbSeq-1]]--; nbSeq_1--; }
809
- FSE_normalizeCount(norm, tableLog, count, nbSeq_1, max);
810
- { size_t const NCountSize = FSE_writeNCount(op, oend-op, norm, max, tableLog); /* overflow protected */
811
- if (FSE_isError(NCountSize)) return ERROR(GENERIC);
812
- op += NCountSize; }
813
- FSE_buildCTable(CTable_LitLength, norm, max, tableLog);
814
- LLtype = FSE_ENCODING_DYNAMIC;
815
- } }
816
-
817
- /* CTable for Offsets */
818
- { U32 max = MaxOff;
819
- size_t const mostFrequent = FSE_countFast(count, &max, ofCodeTable, nbSeq);
820
- if ((mostFrequent == nbSeq) && (nbSeq > 2)) {
821
- *op++ = ofCodeTable[0];
822
- FSE_buildCTable_rle(CTable_OffsetBits, (BYTE)max);
823
- Offtype = FSE_ENCODING_RLE;
824
- } else if ((zc->flagStaticTables) && (nbSeq < MAX_SEQ_FOR_STATIC_FSE)) {
825
- Offtype = FSE_ENCODING_STATIC;
826
- } else if ((nbSeq < MIN_SEQ_FOR_DYNAMIC_FSE) || (mostFrequent < (nbSeq >> (OF_defaultNormLog-1)))) {
827
- FSE_buildCTable(CTable_OffsetBits, OF_defaultNorm, MaxOff, OF_defaultNormLog);
828
- Offtype = FSE_ENCODING_RAW;
829
- } else {
830
- size_t nbSeq_1 = nbSeq;
831
- const U32 tableLog = FSE_optimalTableLog(OffFSELog, nbSeq, max);
832
- if (count[ofCodeTable[nbSeq-1]]>1) { count[ofCodeTable[nbSeq-1]]--; nbSeq_1--; }
833
- FSE_normalizeCount(norm, tableLog, count, nbSeq_1, max);
834
- { size_t const NCountSize = FSE_writeNCount(op, oend-op, norm, max, tableLog); /* overflow protected */
835
- if (FSE_isError(NCountSize)) return ERROR(GENERIC);
836
- op += NCountSize; }
837
- FSE_buildCTable(CTable_OffsetBits, norm, max, tableLog);
838
- Offtype = FSE_ENCODING_DYNAMIC;
839
- } }
840
-
841
- /* CTable for MatchLengths */
842
- { U32 max = MaxML;
843
- size_t const mostFrequent = FSE_countFast(count, &max, mlCodeTable, nbSeq);
844
- if ((mostFrequent == nbSeq) && (nbSeq > 2)) {
845
- *op++ = *mlCodeTable;
846
- FSE_buildCTable_rle(CTable_MatchLength, (BYTE)max);
847
- MLtype = FSE_ENCODING_RLE;
848
- } else if ((zc->flagStaticTables) && (nbSeq < MAX_SEQ_FOR_STATIC_FSE)) {
849
- MLtype = FSE_ENCODING_STATIC;
850
- } else if ((nbSeq < MIN_SEQ_FOR_DYNAMIC_FSE) || (mostFrequent < (nbSeq >> (ML_defaultNormLog-1)))) {
851
- FSE_buildCTable(CTable_MatchLength, ML_defaultNorm, MaxML, ML_defaultNormLog);
852
- MLtype = FSE_ENCODING_RAW;
853
- } else {
854
- size_t nbSeq_1 = nbSeq;
855
- const U32 tableLog = FSE_optimalTableLog(MLFSELog, nbSeq, max);
856
- if (count[mlCodeTable[nbSeq-1]]>1) { count[mlCodeTable[nbSeq-1]]--; nbSeq_1--; }
857
- FSE_normalizeCount(norm, tableLog, count, nbSeq_1, max);
858
- { size_t const NCountSize = FSE_writeNCount(op, oend-op, norm, max, tableLog); /* overflow protected */
859
- if (FSE_isError(NCountSize)) return ERROR(GENERIC);
860
- op += NCountSize; }
861
- FSE_buildCTable(CTable_MatchLength, norm, max, tableLog);
862
- MLtype = FSE_ENCODING_DYNAMIC;
863
- } }
864
-
865
- *seqHead = (BYTE)((LLtype<<6) + (Offtype<<4) + (MLtype<<2));
866
- zc->flagStaticTables = 0;
867
-
868
- /* Encoding Sequences */
869
- { BIT_CStream_t blockStream;
870
- FSE_CState_t stateMatchLength;
871
- FSE_CState_t stateOffsetBits;
872
- FSE_CState_t stateLitLength;
873
-
874
- { size_t const errorCode = BIT_initCStream(&blockStream, op, oend-op);
875
- if (ERR_isError(errorCode)) return ERROR(dstSize_tooSmall); } /* not enough space remaining */
876
-
877
- /* first symbols */
878
- FSE_initCState2(&stateMatchLength, CTable_MatchLength, mlCodeTable[nbSeq-1]);
879
- FSE_initCState2(&stateOffsetBits, CTable_OffsetBits, ofCodeTable[nbSeq-1]);
880
- FSE_initCState2(&stateLitLength, CTable_LitLength, llCodeTable[nbSeq-1]);
881
- BIT_addBits(&blockStream, llTable[nbSeq-1], LL_bits[llCodeTable[nbSeq-1]]);
882
- if (MEM_32bits()) BIT_flushBits(&blockStream);
883
- BIT_addBits(&blockStream, mlTable[nbSeq-1], ML_bits[mlCodeTable[nbSeq-1]]);
884
- if (MEM_32bits()) BIT_flushBits(&blockStream);
885
- BIT_addBits(&blockStream, offsetTable[nbSeq-1], ofCodeTable[nbSeq-1]);
886
- BIT_flushBits(&blockStream);
887
-
888
- { size_t n;
889
- for (n=nbSeq-2 ; n<nbSeq ; n--) { /* intentional underflow */
890
- const BYTE ofCode = ofCodeTable[n];
891
- const BYTE mlCode = mlCodeTable[n];
892
- const BYTE llCode = llCodeTable[n];
893
- const U32 llBits = LL_bits[llCode];
894
- const U32 mlBits = ML_bits[mlCode];
895
- const U32 ofBits = ofCode; /* 32b*/ /* 64b*/
896
- /* (7)*/ /* (7)*/
897
- FSE_encodeSymbol(&blockStream, &stateOffsetBits, ofCode); /* 15 */ /* 15 */
898
- FSE_encodeSymbol(&blockStream, &stateMatchLength, mlCode); /* 24 */ /* 24 */
899
- if (MEM_32bits()) BIT_flushBits(&blockStream); /* (7)*/
900
- FSE_encodeSymbol(&blockStream, &stateLitLength, llCode); /* 16 */ /* 33 */
901
- if (MEM_32bits() || (ofBits+mlBits+llBits >= 64-7-(LLFSELog+MLFSELog+OffFSELog)))
902
- BIT_flushBits(&blockStream); /* (7)*/
903
- BIT_addBits(&blockStream, llTable[n], llBits);
904
- if (MEM_32bits() && ((llBits+mlBits)>24)) BIT_flushBits(&blockStream);
905
- BIT_addBits(&blockStream, mlTable[n], mlBits);
906
- if (MEM_32bits()) BIT_flushBits(&blockStream); /* (7)*/
907
- BIT_addBits(&blockStream, offsetTable[n], ofBits); /* 31 */
908
- BIT_flushBits(&blockStream); /* (7)*/
909
- } }
910
-
911
- FSE_flushCState(&blockStream, &stateMatchLength);
912
- FSE_flushCState(&blockStream, &stateOffsetBits);
913
- FSE_flushCState(&blockStream, &stateLitLength);
914
-
915
- { size_t const streamSize = BIT_closeCStream(&blockStream);
916
- if (streamSize==0) return ERROR(dstSize_tooSmall); /* not enough space */
917
- op += streamSize;
918
- } }
919
-
920
- /* check compressibility */
921
- _check_compressibility:
922
- { size_t const minGain = ZSTD_minGain(srcSize);
923
- size_t const maxCSize = srcSize - minGain;
924
- if ((size_t)(op-ostart) >= maxCSize) return 0; }
925
-
926
- /* confirm repcodes */
927
- { int i; for (i=0; i<ZSTD_REP_NUM; i++) zc->rep[i] = zc->savedRep[i]; }
928
-
929
- return op - ostart;
930
- }
931
-
932
-
933
- /*! ZSTD_storeSeq() :
934
- Store a sequence (literal length, literals, offset code and match length code) into seqStore_t.
935
- `offsetCode` : distance to match, or 0 == repCode.
936
- `matchCode` : matchLength - MINMATCH
937
- */
938
- MEM_STATIC void ZSTD_storeSeq(seqStore_t* seqStorePtr, size_t litLength, const void* literals, U32 offsetCode, size_t matchCode)
939
- {
940
- #if 0 /* for debug */
941
- static const BYTE* g_start = NULL;
942
- const U32 pos = (U32)(literals - g_start);
943
- if (g_start==NULL) g_start = literals;
944
- //if ((pos > 1) && (pos < 50000))
945
- printf("Cpos %6u :%5u literals & match %3u bytes at distance %6u \n",
946
- pos, (U32)litLength, (U32)matchCode+MINMATCH, (U32)offsetCode);
947
- #endif
948
- ZSTD_statsUpdatePrices(&seqStorePtr->stats, litLength, (const BYTE*)literals, offsetCode, matchCode); /* debug only */
949
-
950
- /* copy Literals */
951
- ZSTD_wildcopy(seqStorePtr->lit, literals, litLength);
952
- seqStorePtr->lit += litLength;
953
-
954
- /* literal Length */
955
- if (litLength>0xFFFF) { seqStorePtr->longLengthID = 1; seqStorePtr->longLengthPos = (U32)(seqStorePtr->litLength - seqStorePtr->litLengthStart); }
956
- *seqStorePtr->litLength++ = (U16)litLength;
957
-
958
- /* match offset */
959
- *(seqStorePtr->offset++) = offsetCode + 1;
960
-
961
- /* match Length */
962
- if (matchCode>0xFFFF) { seqStorePtr->longLengthID = 2; seqStorePtr->longLengthPos = (U32)(seqStorePtr->matchLength - seqStorePtr->matchLengthStart); }
963
- *seqStorePtr->matchLength++ = (U16)matchCode;
964
- }
965
-
966
-
967
- /*-*************************************
968
- * Match length counter
969
- ***************************************/
970
- static unsigned ZSTD_NbCommonBytes (register size_t val)
971
- {
972
- if (MEM_isLittleEndian()) {
973
- if (MEM_64bits()) {
974
- # if defined(_MSC_VER) && defined(_WIN64)
975
- unsigned long r = 0;
976
- _BitScanForward64( &r, (U64)val );
977
- return (unsigned)(r>>3);
978
- # elif defined(__GNUC__) && (__GNUC__ >= 3)
979
- return (__builtin_ctzll((U64)val) >> 3);
980
- # else
981
- static const int DeBruijnBytePos[64] = { 0, 0, 0, 0, 0, 1, 1, 2, 0, 3, 1, 3, 1, 4, 2, 7, 0, 2, 3, 6, 1, 5, 3, 5, 1, 3, 4, 4, 2, 5, 6, 7, 7, 0, 1, 2, 3, 3, 4, 6, 2, 6, 5, 5, 3, 4, 5, 6, 7, 1, 2, 4, 6, 4, 4, 5, 7, 2, 6, 5, 7, 6, 7, 7 };
982
- return DeBruijnBytePos[((U64)((val & -(long long)val) * 0x0218A392CDABBD3FULL)) >> 58];
983
- # endif
984
- } else { /* 32 bits */
985
- # if defined(_MSC_VER)
986
- unsigned long r=0;
987
- _BitScanForward( &r, (U32)val );
988
- return (unsigned)(r>>3);
989
- # elif defined(__GNUC__) && (__GNUC__ >= 3)
990
- return (__builtin_ctz((U32)val) >> 3);
991
- # else
992
- static const int DeBruijnBytePos[32] = { 0, 0, 3, 0, 3, 1, 3, 0, 3, 2, 2, 1, 3, 2, 0, 1, 3, 3, 1, 2, 2, 2, 2, 0, 3, 1, 2, 0, 1, 0, 1, 1 };
993
- return DeBruijnBytePos[((U32)((val & -(S32)val) * 0x077CB531U)) >> 27];
994
- # endif
995
- }
996
- } else { /* Big Endian CPU */
997
- if (MEM_64bits()) {
998
- # if defined(_MSC_VER) && defined(_WIN64)
999
- unsigned long r = 0;
1000
- _BitScanReverse64( &r, val );
1001
- return (unsigned)(r>>3);
1002
- # elif defined(__GNUC__) && (__GNUC__ >= 3)
1003
- return (__builtin_clzll(val) >> 3);
1004
- # else
1005
- unsigned r;
1006
- const unsigned n32 = sizeof(size_t)*4; /* calculate this way due to compiler complaining in 32-bits mode */
1007
- if (!(val>>n32)) { r=4; } else { r=0; val>>=n32; }
1008
- if (!(val>>16)) { r+=2; val>>=8; } else { val>>=24; }
1009
- r += (!val);
1010
- return r;
1011
- # endif
1012
- } else { /* 32 bits */
1013
- # if defined(_MSC_VER)
1014
- unsigned long r = 0;
1015
- _BitScanReverse( &r, (unsigned long)val );
1016
- return (unsigned)(r>>3);
1017
- # elif defined(__GNUC__) && (__GNUC__ >= 3)
1018
- return (__builtin_clz((U32)val) >> 3);
1019
- # else
1020
- unsigned r;
1021
- if (!(val>>16)) { r=2; val>>=8; } else { r=0; val>>=24; }
1022
- r += (!val);
1023
- return r;
1024
- # endif
1025
- } }
1026
- }
1027
-
1028
-
1029
- static size_t ZSTD_count(const BYTE* pIn, const BYTE* pMatch, const BYTE* const pInLimit)
1030
- {
1031
- const BYTE* const pStart = pIn;
1032
- const BYTE* const pInLoopLimit = pInLimit - (sizeof(size_t)-1);
1033
-
1034
- while (pIn < pInLoopLimit) {
1035
- size_t const diff = MEM_readST(pMatch) ^ MEM_readST(pIn);
1036
- if (!diff) { pIn+=sizeof(size_t); pMatch+=sizeof(size_t); continue; }
1037
- pIn += ZSTD_NbCommonBytes(diff);
1038
- return (size_t)(pIn - pStart);
1039
- }
1040
- if (MEM_64bits()) if ((pIn<(pInLimit-3)) && (MEM_read32(pMatch) == MEM_read32(pIn))) { pIn+=4; pMatch+=4; }
1041
- if ((pIn<(pInLimit-1)) && (MEM_read16(pMatch) == MEM_read16(pIn))) { pIn+=2; pMatch+=2; }
1042
- if ((pIn<pInLimit) && (*pMatch == *pIn)) pIn++;
1043
- return (size_t)(pIn - pStart);
1044
- }
1045
-
1046
- /** ZSTD_count_2segments() :
1047
- * can count match length with `ip` & `match` in 2 different segments.
1048
- * convention : on reaching mEnd, match count continue starting from iStart
1049
- */
1050
- static size_t ZSTD_count_2segments(const BYTE* ip, const BYTE* match, const BYTE* iEnd, const BYTE* mEnd, const BYTE* iStart)
1051
- {
1052
- const BYTE* const vEnd = MIN( ip + (mEnd - match), iEnd);
1053
- size_t matchLength = ZSTD_count(ip, match, vEnd);
1054
- if (match + matchLength == mEnd)
1055
- matchLength += ZSTD_count(ip+matchLength, iStart, iEnd);
1056
- return matchLength;
1057
- }
1058
-
1059
-
1060
- /*-*************************************
1061
- * Hashes
1062
- ***************************************/
1063
- static const U32 prime3bytes = 506832829U;
1064
- static U32 ZSTD_hash3(U32 u, U32 h) { return ((u << (32-24)) * prime3bytes) >> (32-h) ; }
1065
- MEM_STATIC size_t ZSTD_hash3Ptr(const void* ptr, U32 h) { return ZSTD_hash3(MEM_readLE32(ptr), h); } /* only in zstd_opt.h */
1066
-
1067
- static const U32 prime4bytes = 2654435761U;
1068
- static U32 ZSTD_hash4(U32 u, U32 h) { return (u * prime4bytes) >> (32-h) ; }
1069
- static size_t ZSTD_hash4Ptr(const void* ptr, U32 h) { return ZSTD_hash4(MEM_read32(ptr), h); }
1070
-
1071
- static const U64 prime5bytes = 889523592379ULL;
1072
- static size_t ZSTD_hash5(U64 u, U32 h) { return (size_t)(((u << (64-40)) * prime5bytes) >> (64-h)) ; }
1073
- static size_t ZSTD_hash5Ptr(const void* p, U32 h) { return ZSTD_hash5(MEM_readLE64(p), h); }
1074
-
1075
- static const U64 prime6bytes = 227718039650203ULL;
1076
- static size_t ZSTD_hash6(U64 u, U32 h) { return (size_t)(((u << (64-48)) * prime6bytes) >> (64-h)) ; }
1077
- static size_t ZSTD_hash6Ptr(const void* p, U32 h) { return ZSTD_hash6(MEM_readLE64(p), h); }
1078
-
1079
- static const U64 prime7bytes = 58295818150454627ULL;
1080
- static size_t ZSTD_hash7(U64 u, U32 h) { return (size_t)(((u << (64-56)) * prime7bytes) >> (64-h)) ; }
1081
- static size_t ZSTD_hash7Ptr(const void* p, U32 h) { return ZSTD_hash7(MEM_readLE64(p), h); }
1082
-
1083
- //static const U64 prime8bytes = 58295818150454627ULL;
1084
- static const U64 prime8bytes = 0xCF1BBCDCB7A56463ULL;
1085
- static size_t ZSTD_hash8(U64 u, U32 h) { return (size_t)(((u) * prime8bytes) >> (64-h)) ; }
1086
- static size_t ZSTD_hash8Ptr(const void* p, U32 h) { return ZSTD_hash8(MEM_readLE64(p), h); }
1087
-
1088
- static size_t ZSTD_hashPtr(const void* p, U32 hBits, U32 mls)
1089
- {
1090
- switch(mls)
1091
- {
1092
- default:
1093
- case 4: return ZSTD_hash4Ptr(p, hBits);
1094
- case 5: return ZSTD_hash5Ptr(p, hBits);
1095
- case 6: return ZSTD_hash6Ptr(p, hBits);
1096
- case 7: return ZSTD_hash7Ptr(p, hBits);
1097
- case 8: return ZSTD_hash8Ptr(p, hBits);
1098
- }
1099
- }
1100
-
1101
-
1102
- /*-*************************************
1103
- * Fast Scan
1104
- ***************************************/
1105
- static void ZSTD_fillHashTable (ZSTD_CCtx* zc, const void* end, const U32 mls)
1106
- {
1107
- U32* const hashTable = zc->hashTable;
1108
- const U32 hBits = zc->params.cParams.hashLog;
1109
- const BYTE* const base = zc->base;
1110
- const BYTE* ip = base + zc->nextToUpdate;
1111
- const BYTE* const iend = ((const BYTE*)end) - 8;
1112
- const size_t fastHashFillStep = 3;
1113
-
1114
- while(ip <= iend) {
1115
- hashTable[ZSTD_hashPtr(ip, hBits, mls)] = (U32)(ip - base);
1116
- ip += fastHashFillStep;
1117
- }
1118
- }
1119
-
1120
-
1121
- FORCE_INLINE
1122
- void ZSTD_compressBlock_fast_generic(ZSTD_CCtx* cctx,
1123
- const void* src, size_t srcSize,
1124
- const U32 mls)
1125
- {
1126
- U32* const hashTable = cctx->hashTable;
1127
- const U32 hBits = cctx->params.cParams.hashLog;
1128
- seqStore_t* seqStorePtr = &(cctx->seqStore);
1129
- const BYTE* const base = cctx->base;
1130
- const BYTE* const istart = (const BYTE*)src;
1131
- const BYTE* ip = istart;
1132
- const BYTE* anchor = istart;
1133
- const U32 lowestIndex = cctx->dictLimit;
1134
- const BYTE* const lowest = base + lowestIndex;
1135
- const BYTE* const iend = istart + srcSize;
1136
- const BYTE* const ilimit = iend - 8;
1137
- U32 offset_1=cctx->rep[0], offset_2=cctx->rep[1];
1138
- U32 offsetSaved = 0;
1139
-
1140
- /* init */
1141
- ip += (ip==lowest);
1142
- { U32 const maxRep = (U32)(ip-lowest);
1143
- if (offset_2 > maxRep) offsetSaved = offset_2, offset_2 = 0;
1144
- if (offset_1 > maxRep) offsetSaved = offset_1, offset_1 = 0;
1145
- }
1146
-
1147
- /* Main Search Loop */
1148
- while (ip < ilimit) { /* < instead of <=, because repcode check at (ip+1) */
1149
- size_t mLength;
1150
- size_t const h = ZSTD_hashPtr(ip, hBits, mls);
1151
- U32 const current = (U32)(ip-base);
1152
- U32 const matchIndex = hashTable[h];
1153
- const BYTE* match = base + matchIndex;
1154
- hashTable[h] = current; /* update hash table */
1155
-
1156
- if ((offset_1 > 0) & (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1))) { /* note : by construction, offset_1 <= current */
1157
- mLength = ZSTD_count(ip+1+4, ip+1+4-offset_1, iend) + 4;
1158
- ip++;
1159
- ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, 0, mLength-MINMATCH);
1160
- } else {
1161
- U32 offset;
1162
- if ( (matchIndex <= lowestIndex) || (MEM_read32(match) != MEM_read32(ip)) ) {
1163
- ip += ((ip-anchor) >> g_searchStrength) + 1;
1164
- continue;
1165
- }
1166
- mLength = ZSTD_count(ip+4, match+4, iend) + 4;
1167
- offset = (U32)(ip-match);
1168
- while (((ip>anchor) & (match>lowest)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
1169
- offset_2 = offset_1;
1170
- offset_1 = offset;
1171
-
1172
- ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
1173
- }
1174
-
1175
- /* match found */
1176
- ip += mLength;
1177
- anchor = ip;
1178
-
1179
- if (ip <= ilimit) {
1180
- /* Fill Table */
1181
- hashTable[ZSTD_hashPtr(base+current+2, hBits, mls)] = current+2; /* here because current+2 could be > iend-8 */
1182
- hashTable[ZSTD_hashPtr(ip-2, hBits, mls)] = (U32)(ip-2-base);
1183
- /* check immediate repcode */
1184
- while ( (ip <= ilimit)
1185
- && ( (offset_2>0)
1186
- & (MEM_read32(ip) == MEM_read32(ip - offset_2)) )) {
1187
- /* store sequence */
1188
- size_t const rLength = ZSTD_count(ip+4, ip+4-offset_2, iend) + 4;
1189
- { U32 const tmpOff = offset_2; offset_2 = offset_1; offset_1 = tmpOff; } /* swap offset_2 <=> offset_1 */
1190
- hashTable[ZSTD_hashPtr(ip, hBits, mls)] = (U32)(ip-base);
1191
- ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, rLength-MINMATCH);
1192
- ip += rLength;
1193
- anchor = ip;
1194
- continue; /* faster when present ... (?) */
1195
- } } }
1196
-
1197
- /* save reps for next block */
1198
- cctx->savedRep[0] = offset_1 ? offset_1 : offsetSaved;
1199
- cctx->savedRep[1] = offset_2 ? offset_2 : offsetSaved;
1200
-
1201
- /* Last Literals */
1202
- { size_t const lastLLSize = iend - anchor;
1203
- memcpy(seqStorePtr->lit, anchor, lastLLSize);
1204
- seqStorePtr->lit += lastLLSize;
1205
- }
1206
- }
1207
-
1208
-
1209
- static void ZSTD_compressBlock_fast(ZSTD_CCtx* ctx,
1210
- const void* src, size_t srcSize)
1211
- {
1212
- const U32 mls = ctx->params.cParams.searchLength;
1213
- switch(mls)
1214
- {
1215
- default:
1216
- case 4 :
1217
- ZSTD_compressBlock_fast_generic(ctx, src, srcSize, 4); return;
1218
- case 5 :
1219
- ZSTD_compressBlock_fast_generic(ctx, src, srcSize, 5); return;
1220
- case 6 :
1221
- ZSTD_compressBlock_fast_generic(ctx, src, srcSize, 6); return;
1222
- case 7 :
1223
- ZSTD_compressBlock_fast_generic(ctx, src, srcSize, 7); return;
1224
- }
1225
- }
1226
-
1227
-
1228
- static void ZSTD_compressBlock_fast_extDict_generic(ZSTD_CCtx* ctx,
1229
- const void* src, size_t srcSize,
1230
- const U32 mls)
1231
- {
1232
- U32* hashTable = ctx->hashTable;
1233
- const U32 hBits = ctx->params.cParams.hashLog;
1234
- seqStore_t* seqStorePtr = &(ctx->seqStore);
1235
- const BYTE* const base = ctx->base;
1236
- const BYTE* const dictBase = ctx->dictBase;
1237
- const BYTE* const istart = (const BYTE*)src;
1238
- const BYTE* ip = istart;
1239
- const BYTE* anchor = istart;
1240
- const U32 lowestIndex = ctx->lowLimit;
1241
- const BYTE* const dictStart = dictBase + lowestIndex;
1242
- const U32 dictLimit = ctx->dictLimit;
1243
- const BYTE* const lowPrefixPtr = base + dictLimit;
1244
- const BYTE* const dictEnd = dictBase + dictLimit;
1245
- const BYTE* const iend = istart + srcSize;
1246
- const BYTE* const ilimit = iend - 8;
1247
- U32 offset_1=ctx->rep[0], offset_2=ctx->rep[1];
1248
-
1249
- /* Search Loop */
1250
- while (ip < ilimit) { /* < instead of <=, because (ip+1) */
1251
- const size_t h = ZSTD_hashPtr(ip, hBits, mls);
1252
- const U32 matchIndex = hashTable[h];
1253
- const BYTE* matchBase = matchIndex < dictLimit ? dictBase : base;
1254
- const BYTE* match = matchBase + matchIndex;
1255
- const U32 current = (U32)(ip-base);
1256
- const U32 repIndex = current + 1 - offset_1; /* offset_1 expected <= current +1 */
1257
- const BYTE* repBase = repIndex < dictLimit ? dictBase : base;
1258
- const BYTE* repMatch = repBase + repIndex;
1259
- size_t mLength;
1260
- hashTable[h] = current; /* update hash table */
1261
-
1262
- if ( (((U32)((dictLimit-1) - repIndex) >= 3) /* intentional underflow */ & (repIndex > lowestIndex))
1263
- && (MEM_read32(repMatch) == MEM_read32(ip+1)) ) {
1264
- const BYTE* repMatchEnd = repIndex < dictLimit ? dictEnd : iend;
1265
- mLength = ZSTD_count_2segments(ip+1+EQUAL_READ32, repMatch+EQUAL_READ32, iend, repMatchEnd, lowPrefixPtr) + EQUAL_READ32;
1266
- ip++;
1267
- ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, 0, mLength-MINMATCH);
1268
- } else {
1269
- if ( (matchIndex < lowestIndex) ||
1270
- (MEM_read32(match) != MEM_read32(ip)) ) {
1271
- ip += ((ip-anchor) >> g_searchStrength) + 1;
1272
- continue;
1273
- }
1274
- { const BYTE* matchEnd = matchIndex < dictLimit ? dictEnd : iend;
1275
- const BYTE* lowMatchPtr = matchIndex < dictLimit ? dictStart : lowPrefixPtr;
1276
- U32 offset;
1277
- mLength = ZSTD_count_2segments(ip+EQUAL_READ32, match+EQUAL_READ32, iend, matchEnd, lowPrefixPtr) + EQUAL_READ32;
1278
- while (((ip>anchor) & (match>lowMatchPtr)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
1279
- offset = current - matchIndex;
1280
- offset_2 = offset_1;
1281
- offset_1 = offset;
1282
- ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
1283
- } }
1284
-
1285
- /* found a match : store it */
1286
- ip += mLength;
1287
- anchor = ip;
1288
-
1289
- if (ip <= ilimit) {
1290
- /* Fill Table */
1291
- hashTable[ZSTD_hashPtr(base+current+2, hBits, mls)] = current+2;
1292
- hashTable[ZSTD_hashPtr(ip-2, hBits, mls)] = (U32)(ip-2-base);
1293
- /* check immediate repcode */
1294
- while (ip <= ilimit) {
1295
- U32 const current2 = (U32)(ip-base);
1296
- U32 const repIndex2 = current2 - offset_2;
1297
- const BYTE* repMatch2 = repIndex2 < dictLimit ? dictBase + repIndex2 : base + repIndex2;
1298
- if ( (((U32)((dictLimit-1) - repIndex2) >= 3) & (repIndex2 > lowestIndex)) /* intentional overflow */
1299
- && (MEM_read32(repMatch2) == MEM_read32(ip)) ) {
1300
- const BYTE* const repEnd2 = repIndex2 < dictLimit ? dictEnd : iend;
1301
- size_t repLength2 = ZSTD_count_2segments(ip+EQUAL_READ32, repMatch2+EQUAL_READ32, iend, repEnd2, lowPrefixPtr) + EQUAL_READ32;
1302
- U32 tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset; /* swap offset_2 <=> offset_1 */
1303
- ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, repLength2-MINMATCH);
1304
- hashTable[ZSTD_hashPtr(ip, hBits, mls)] = current2;
1305
- ip += repLength2;
1306
- anchor = ip;
1307
- continue;
1308
- }
1309
- break;
1310
- } } }
1311
-
1312
- /* save reps for next block */
1313
- ctx->savedRep[0] = offset_1; ctx->savedRep[1] = offset_2;
1314
-
1315
- /* Last Literals */
1316
- { size_t const lastLLSize = iend - anchor;
1317
- memcpy(seqStorePtr->lit, anchor, lastLLSize);
1318
- seqStorePtr->lit += lastLLSize;
1319
- }
1320
- }
1321
-
1322
-
1323
- static void ZSTD_compressBlock_fast_extDict(ZSTD_CCtx* ctx,
1324
- const void* src, size_t srcSize)
1325
- {
1326
- const U32 mls = ctx->params.cParams.searchLength;
1327
- switch(mls)
1328
- {
1329
- default:
1330
- case 4 :
1331
- ZSTD_compressBlock_fast_extDict_generic(ctx, src, srcSize, 4); return;
1332
- case 5 :
1333
- ZSTD_compressBlock_fast_extDict_generic(ctx, src, srcSize, 5); return;
1334
- case 6 :
1335
- ZSTD_compressBlock_fast_extDict_generic(ctx, src, srcSize, 6); return;
1336
- case 7 :
1337
- ZSTD_compressBlock_fast_extDict_generic(ctx, src, srcSize, 7); return;
1338
- }
1339
- }
1340
-
1341
-
1342
- /*-*************************************
1343
- * Double Fast
1344
- ***************************************/
1345
- static void ZSTD_fillDoubleHashTable (ZSTD_CCtx* cctx, const void* end, const U32 mls)
1346
- {
1347
- U32* const hashLarge = cctx->hashTable;
1348
- const U32 hBitsL = cctx->params.cParams.hashLog;
1349
- U32* const hashSmall = cctx->chainTable;
1350
- const U32 hBitsS = cctx->params.cParams.chainLog;
1351
- const BYTE* const base = cctx->base;
1352
- const BYTE* ip = base + cctx->nextToUpdate;
1353
- const BYTE* const iend = ((const BYTE*)end) - 8;
1354
- const size_t fastHashFillStep = 3;
1355
-
1356
- while(ip <= iend) {
1357
- hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = (U32)(ip - base);
1358
- hashLarge[ZSTD_hashPtr(ip, hBitsL, 8)] = (U32)(ip - base);
1359
- ip += fastHashFillStep;
1360
- }
1361
- }
1362
-
1363
-
1364
- FORCE_INLINE
1365
- void ZSTD_compressBlock_doubleFast_generic(ZSTD_CCtx* cctx,
1366
- const void* src, size_t srcSize,
1367
- const U32 mls)
1368
- {
1369
- U32* const hashLong = cctx->hashTable;
1370
- const U32 hBitsL = cctx->params.cParams.hashLog;
1371
- U32* const hashSmall = cctx->chainTable;
1372
- const U32 hBitsS = cctx->params.cParams.chainLog;
1373
- seqStore_t* seqStorePtr = &(cctx->seqStore);
1374
- const BYTE* const base = cctx->base;
1375
- const BYTE* const istart = (const BYTE*)src;
1376
- const BYTE* ip = istart;
1377
- const BYTE* anchor = istart;
1378
- const U32 lowestIndex = cctx->dictLimit;
1379
- const BYTE* const lowest = base + lowestIndex;
1380
- const BYTE* const iend = istart + srcSize;
1381
- const BYTE* const ilimit = iend - 8;
1382
- U32 offset_1=cctx->rep[0], offset_2=cctx->rep[1];
1383
- U32 offsetSaved = 0;
1384
-
1385
- /* init */
1386
- ip += (ip==lowest);
1387
- { U32 const maxRep = (U32)(ip-lowest);
1388
- if (offset_2 > maxRep) offsetSaved = offset_2, offset_2 = 0;
1389
- if (offset_1 > maxRep) offsetSaved = offset_1, offset_1 = 0;
1390
- }
1391
-
1392
- /* Main Search Loop */
1393
- while (ip < ilimit) { /* < instead of <=, because repcode check at (ip+1) */
1394
- size_t mLength;
1395
- size_t const h2 = ZSTD_hashPtr(ip, hBitsL, 8);
1396
- size_t const h = ZSTD_hashPtr(ip, hBitsS, mls);
1397
- U32 const current = (U32)(ip-base);
1398
- U32 const matchIndexL = hashLong[h2];
1399
- U32 const matchIndexS = hashSmall[h];
1400
- const BYTE* matchLong = base + matchIndexL;
1401
- const BYTE* match = base + matchIndexS;
1402
- hashLong[h2] = hashSmall[h] = current; /* update hash tables */
1403
-
1404
- if ((offset_1 > 0) & (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1))) { /* note : by construction, offset_1 <= current */
1405
- mLength = ZSTD_count(ip+1+4, ip+1+4-offset_1, iend) + 4;
1406
- ip++;
1407
- ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, 0, mLength-MINMATCH);
1408
- } else {
1409
- U32 offset;
1410
- if ( (matchIndexL > lowestIndex) && (MEM_read64(matchLong) == MEM_read64(ip)) ) {
1411
- mLength = ZSTD_count(ip+8, matchLong+8, iend) + 8;
1412
- offset = (U32)(ip-matchLong);
1413
- while (((ip>anchor) & (matchLong>lowest)) && (ip[-1] == matchLong[-1])) { ip--; matchLong--; mLength++; } /* catch up */
1414
- } else if ( (matchIndexS > lowestIndex) && (MEM_read32(match) == MEM_read32(ip)) ) {
1415
- mLength = ZSTD_count(ip+4, match+4, iend) + 4;
1416
- offset = (U32)(ip-match);
1417
- while (((ip>anchor) & (match>lowest)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
1418
- } else {
1419
- ip += ((ip-anchor) >> g_searchStrength) + 1;
1420
- continue;
1421
- }
1422
-
1423
- offset_2 = offset_1;
1424
- offset_1 = offset;
1425
-
1426
- ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
1427
- }
1428
-
1429
- /* match found */
1430
- ip += mLength;
1431
- anchor = ip;
1432
-
1433
- if (ip <= ilimit) {
1434
- /* Fill Table */
1435
- hashLong[ZSTD_hashPtr(base+current+2, hBitsL, 8)] =
1436
- hashSmall[ZSTD_hashPtr(base+current+2, hBitsS, mls)] = current+2; /* here because current+2 could be > iend-8 */
1437
- hashLong[ZSTD_hashPtr(ip-2, hBitsL, 8)] =
1438
- hashSmall[ZSTD_hashPtr(ip-2, hBitsS, mls)] = (U32)(ip-2-base);
1439
-
1440
- /* check immediate repcode */
1441
- while ( (ip <= ilimit)
1442
- && ( (offset_2>0)
1443
- & (MEM_read32(ip) == MEM_read32(ip - offset_2)) )) {
1444
- /* store sequence */
1445
- size_t const rLength = ZSTD_count(ip+4, ip+4-offset_2, iend) + 4;
1446
- { U32 const tmpOff = offset_2; offset_2 = offset_1; offset_1 = tmpOff; } /* swap offset_2 <=> offset_1 */
1447
- hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = (U32)(ip-base);
1448
- hashLong[ZSTD_hashPtr(ip, hBitsL, 8)] = (U32)(ip-base);
1449
- ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, rLength-MINMATCH);
1450
- ip += rLength;
1451
- anchor = ip;
1452
- continue; /* faster when present ... (?) */
1453
- } } }
1454
-
1455
- /* save reps for next block */
1456
- cctx->savedRep[0] = offset_1 ? offset_1 : offsetSaved;
1457
- cctx->savedRep[1] = offset_2 ? offset_2 : offsetSaved;
1458
-
1459
- /* Last Literals */
1460
- { size_t const lastLLSize = iend - anchor;
1461
- memcpy(seqStorePtr->lit, anchor, lastLLSize);
1462
- seqStorePtr->lit += lastLLSize;
1463
- }
1464
- }
1465
-
1466
-
1467
- static void ZSTD_compressBlock_doubleFast(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
1468
- {
1469
- const U32 mls = ctx->params.cParams.searchLength;
1470
- switch(mls)
1471
- {
1472
- default:
1473
- case 4 :
1474
- ZSTD_compressBlock_doubleFast_generic(ctx, src, srcSize, 4); return;
1475
- case 5 :
1476
- ZSTD_compressBlock_doubleFast_generic(ctx, src, srcSize, 5); return;
1477
- case 6 :
1478
- ZSTD_compressBlock_doubleFast_generic(ctx, src, srcSize, 6); return;
1479
- case 7 :
1480
- ZSTD_compressBlock_doubleFast_generic(ctx, src, srcSize, 7); return;
1481
- }
1482
- }
1483
-
1484
-
1485
- static void ZSTD_compressBlock_doubleFast_extDict_generic(ZSTD_CCtx* ctx,
1486
- const void* src, size_t srcSize,
1487
- const U32 mls)
1488
- {
1489
- U32* const hashLong = ctx->hashTable;
1490
- const U32 hBitsL = ctx->params.cParams.hashLog;
1491
- U32* const hashSmall = ctx->chainTable;
1492
- const U32 hBitsS = ctx->params.cParams.chainLog;
1493
- seqStore_t* seqStorePtr = &(ctx->seqStore);
1494
- const BYTE* const base = ctx->base;
1495
- const BYTE* const dictBase = ctx->dictBase;
1496
- const BYTE* const istart = (const BYTE*)src;
1497
- const BYTE* ip = istart;
1498
- const BYTE* anchor = istart;
1499
- const U32 lowestIndex = ctx->lowLimit;
1500
- const BYTE* const dictStart = dictBase + lowestIndex;
1501
- const U32 dictLimit = ctx->dictLimit;
1502
- const BYTE* const lowPrefixPtr = base + dictLimit;
1503
- const BYTE* const dictEnd = dictBase + dictLimit;
1504
- const BYTE* const iend = istart + srcSize;
1505
- const BYTE* const ilimit = iend - 8;
1506
- U32 offset_1=ctx->rep[0], offset_2=ctx->rep[1];
1507
-
1508
- /* Search Loop */
1509
- while (ip < ilimit) { /* < instead of <=, because (ip+1) */
1510
- const size_t hSmall = ZSTD_hashPtr(ip, hBitsS, mls);
1511
- const U32 matchIndex = hashSmall[hSmall];
1512
- const BYTE* matchBase = matchIndex < dictLimit ? dictBase : base;
1513
- const BYTE* match = matchBase + matchIndex;
1514
-
1515
- const size_t hLong = ZSTD_hashPtr(ip, hBitsL, 8);
1516
- const U32 matchLongIndex = hashLong[hLong];
1517
- const BYTE* matchLongBase = matchLongIndex < dictLimit ? dictBase : base;
1518
- const BYTE* matchLong = matchLongBase + matchLongIndex;
1519
-
1520
- const U32 current = (U32)(ip-base);
1521
- const U32 repIndex = current + 1 - offset_1; /* offset_1 expected <= current +1 */
1522
- const BYTE* repBase = repIndex < dictLimit ? dictBase : base;
1523
- const BYTE* repMatch = repBase + repIndex;
1524
- size_t mLength;
1525
- hashSmall[hSmall] = hashLong[hLong] = current; /* update hash table */
1526
-
1527
- if ( (((U32)((dictLimit-1) - repIndex) >= 3) /* intentional underflow */ & (repIndex > lowestIndex))
1528
- && (MEM_read32(repMatch) == MEM_read32(ip+1)) ) {
1529
- const BYTE* repMatchEnd = repIndex < dictLimit ? dictEnd : iend;
1530
- mLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repMatchEnd, lowPrefixPtr) + 4;
1531
- ip++;
1532
- ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, 0, mLength-MINMATCH);
1533
- } else {
1534
- if ((matchLongIndex > lowestIndex) && (MEM_read64(matchLong) == MEM_read64(ip))) {
1535
- const BYTE* matchEnd = matchLongIndex < dictLimit ? dictEnd : iend;
1536
- const BYTE* lowMatchPtr = matchLongIndex < dictLimit ? dictStart : lowPrefixPtr;
1537
- U32 offset;
1538
- mLength = ZSTD_count_2segments(ip+8, matchLong+8, iend, matchEnd, lowPrefixPtr) + 8;
1539
- offset = current - matchLongIndex;
1540
- while (((ip>anchor) & (matchLong>lowMatchPtr)) && (ip[-1] == matchLong[-1])) { ip--; matchLong--; mLength++; } /* catch up */
1541
- offset_2 = offset_1;
1542
- offset_1 = offset;
1543
- ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
1544
- } else if ((matchIndex > lowestIndex) && (MEM_read32(match) == MEM_read32(ip))) {
1545
- const BYTE* matchEnd = matchIndex < dictLimit ? dictEnd : iend;
1546
- const BYTE* lowMatchPtr = matchIndex < dictLimit ? dictStart : lowPrefixPtr;
1547
- U32 offset;
1548
- mLength = ZSTD_count_2segments(ip+4, match+4, iend, matchEnd, lowPrefixPtr) + 4;
1549
- while (((ip>anchor) & (match>lowMatchPtr)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
1550
- offset = current - matchIndex;
1551
- offset_2 = offset_1;
1552
- offset_1 = offset;
1553
- ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
1554
- } else {
1555
- ip += ((ip-anchor) >> g_searchStrength) + 1;
1556
- continue;
1557
- } }
1558
-
1559
- /* found a match : store it */
1560
- ip += mLength;
1561
- anchor = ip;
1562
-
1563
- if (ip <= ilimit) {
1564
- /* Fill Table */
1565
- hashSmall[ZSTD_hashPtr(base+current+2, hBitsS, mls)] = current+2;
1566
- hashLong[ZSTD_hashPtr(base+current+2, hBitsL, 8)] = current+2;
1567
- hashSmall[ZSTD_hashPtr(ip-2, hBitsS, mls)] = (U32)(ip-2-base);
1568
- hashLong[ZSTD_hashPtr(ip-2, hBitsL, 8)] = (U32)(ip-2-base);
1569
- /* check immediate repcode */
1570
- while (ip <= ilimit) {
1571
- U32 const current2 = (U32)(ip-base);
1572
- U32 const repIndex2 = current2 - offset_2;
1573
- const BYTE* repMatch2 = repIndex2 < dictLimit ? dictBase + repIndex2 : base + repIndex2;
1574
- if ( (((U32)((dictLimit-1) - repIndex2) >= 3) & (repIndex2 > lowestIndex)) /* intentional overflow */
1575
- && (MEM_read32(repMatch2) == MEM_read32(ip)) ) {
1576
- const BYTE* const repEnd2 = repIndex2 < dictLimit ? dictEnd : iend;
1577
- size_t const repLength2 = ZSTD_count_2segments(ip+EQUAL_READ32, repMatch2+EQUAL_READ32, iend, repEnd2, lowPrefixPtr) + EQUAL_READ32;
1578
- U32 tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset; /* swap offset_2 <=> offset_1 */
1579
- ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, repLength2-MINMATCH);
1580
- hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = current2;
1581
- hashLong[ZSTD_hashPtr(ip, hBitsL, 8)] = current2;
1582
- ip += repLength2;
1583
- anchor = ip;
1584
- continue;
1585
- }
1586
- break;
1587
- } } }
1588
-
1589
- /* save reps for next block */
1590
- ctx->savedRep[0] = offset_1; ctx->savedRep[1] = offset_2;
1591
-
1592
- /* Last Literals */
1593
- { size_t const lastLLSize = iend - anchor;
1594
- memcpy(seqStorePtr->lit, anchor, lastLLSize);
1595
- seqStorePtr->lit += lastLLSize;
1596
- }
1597
- }
1598
-
1599
-
1600
- static void ZSTD_compressBlock_doubleFast_extDict(ZSTD_CCtx* ctx,
1601
- const void* src, size_t srcSize)
1602
- {
1603
- const U32 mls = ctx->params.cParams.searchLength;
1604
- switch(mls)
1605
- {
1606
- default:
1607
- case 4 :
1608
- ZSTD_compressBlock_doubleFast_extDict_generic(ctx, src, srcSize, 4); return;
1609
- case 5 :
1610
- ZSTD_compressBlock_doubleFast_extDict_generic(ctx, src, srcSize, 5); return;
1611
- case 6 :
1612
- ZSTD_compressBlock_doubleFast_extDict_generic(ctx, src, srcSize, 6); return;
1613
- case 7 :
1614
- ZSTD_compressBlock_doubleFast_extDict_generic(ctx, src, srcSize, 7); return;
1615
- }
1616
- }
1617
-
1618
-
1619
- /*-*************************************
1620
- * Binary Tree search
1621
- ***************************************/
1622
- /** ZSTD_insertBt1() : add one or multiple positions to tree.
1623
- * ip : assumed <= iend-8 .
1624
- * @return : nb of positions added */
1625
- static U32 ZSTD_insertBt1(ZSTD_CCtx* zc, const BYTE* const ip, const U32 mls, const BYTE* const iend, U32 nbCompares,
1626
- U32 extDict)
1627
- {
1628
- U32* const hashTable = zc->hashTable;
1629
- const U32 hashLog = zc->params.cParams.hashLog;
1630
- const size_t h = ZSTD_hashPtr(ip, hashLog, mls);
1631
- U32* const bt = zc->chainTable;
1632
- const U32 btLog = zc->params.cParams.chainLog - 1;
1633
- const U32 btMask= (1 << btLog) - 1;
1634
- U32 matchIndex = hashTable[h];
1635
- size_t commonLengthSmaller=0, commonLengthLarger=0;
1636
- const BYTE* const base = zc->base;
1637
- const BYTE* const dictBase = zc->dictBase;
1638
- const U32 dictLimit = zc->dictLimit;
1639
- const BYTE* const dictEnd = dictBase + dictLimit;
1640
- const BYTE* const prefixStart = base + dictLimit;
1641
- const BYTE* match = base + matchIndex;
1642
- const U32 current = (U32)(ip-base);
1643
- const U32 btLow = btMask >= current ? 0 : current - btMask;
1644
- U32* smallerPtr = bt + 2*(current&btMask);
1645
- U32* largerPtr = smallerPtr + 1;
1646
- U32 dummy32; /* to be nullified at the end */
1647
- const U32 windowLow = zc->lowLimit;
1648
- U32 matchEndIdx = current+8;
1649
- size_t bestLength = 8;
1650
- #ifdef ZSTD_C_PREDICT
1651
- U32 predictedSmall = *(bt + 2*((current-1)&btMask) + 0);
1652
- U32 predictedLarge = *(bt + 2*((current-1)&btMask) + 1);
1653
- predictedSmall += (predictedSmall>0);
1654
- predictedLarge += (predictedLarge>0);
1655
- #endif /* ZSTD_C_PREDICT */
1656
-
1657
- hashTable[h] = current; /* Update Hash Table */
1658
-
1659
- while (nbCompares-- && (matchIndex > windowLow)) {
1660
- U32* nextPtr = bt + 2*(matchIndex & btMask);
1661
- size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */
1662
- #ifdef ZSTD_C_PREDICT /* note : can create issues when hlog small <= 11 */
1663
- const U32* predictPtr = bt + 2*((matchIndex-1) & btMask); /* written this way, as bt is a roll buffer */
1664
- if (matchIndex == predictedSmall) {
1665
- /* no need to check length, result known */
1666
- *smallerPtr = matchIndex;
1667
- if (matchIndex <= btLow) { smallerPtr=&dummy32; break; } /* beyond tree size, stop the search */
1668
- smallerPtr = nextPtr+1; /* new "smaller" => larger of match */
1669
- matchIndex = nextPtr[1]; /* new matchIndex larger than previous (closer to current) */
1670
- predictedSmall = predictPtr[1] + (predictPtr[1]>0);
1671
- continue;
1672
- }
1673
- if (matchIndex == predictedLarge) {
1674
- *largerPtr = matchIndex;
1675
- if (matchIndex <= btLow) { largerPtr=&dummy32; break; } /* beyond tree size, stop the search */
1676
- largerPtr = nextPtr;
1677
- matchIndex = nextPtr[0];
1678
- predictedLarge = predictPtr[0] + (predictPtr[0]>0);
1679
- continue;
1680
- }
1681
- #endif
1682
- if ((!extDict) || (matchIndex+matchLength >= dictLimit)) {
1683
- match = base + matchIndex;
1684
- if (match[matchLength] == ip[matchLength])
1685
- matchLength += ZSTD_count(ip+matchLength+1, match+matchLength+1, iend) +1;
1686
- } else {
1687
- match = dictBase + matchIndex;
1688
- matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iend, dictEnd, prefixStart);
1689
- if (matchIndex+matchLength >= dictLimit)
1690
- match = base + matchIndex; /* to prepare for next usage of match[matchLength] */
1691
- }
1692
-
1693
- if (matchLength > bestLength) {
1694
- bestLength = matchLength;
1695
- if (matchLength > matchEndIdx - matchIndex)
1696
- matchEndIdx = matchIndex + (U32)matchLength;
1697
- }
1698
-
1699
- if (ip+matchLength == iend) /* equal : no way to know if inf or sup */
1700
- break; /* drop , to guarantee consistency ; miss a bit of compression, but other solutions can corrupt the tree */
1701
-
1702
- if (match[matchLength] < ip[matchLength]) { /* necessarily within correct buffer */
1703
- /* match is smaller than current */
1704
- *smallerPtr = matchIndex; /* update smaller idx */
1705
- commonLengthSmaller = matchLength; /* all smaller will now have at least this guaranteed common length */
1706
- if (matchIndex <= btLow) { smallerPtr=&dummy32; break; } /* beyond tree size, stop the search */
1707
- smallerPtr = nextPtr+1; /* new "smaller" => larger of match */
1708
- matchIndex = nextPtr[1]; /* new matchIndex larger than previous (closer to current) */
1709
- } else {
1710
- /* match is larger than current */
1711
- *largerPtr = matchIndex;
1712
- commonLengthLarger = matchLength;
1713
- if (matchIndex <= btLow) { largerPtr=&dummy32; break; } /* beyond tree size, stop the search */
1714
- largerPtr = nextPtr;
1715
- matchIndex = nextPtr[0];
1716
- } }
1717
-
1718
- *smallerPtr = *largerPtr = 0;
1719
- if (bestLength > 384) return MIN(192, (U32)(bestLength - 384)); /* speed optimization */
1720
- if (matchEndIdx > current + 8) return matchEndIdx - current - 8;
1721
- return 1;
1722
- }
1723
-
1724
-
1725
- static size_t ZSTD_insertBtAndFindBestMatch (
1726
- ZSTD_CCtx* zc,
1727
- const BYTE* const ip, const BYTE* const iend,
1728
- size_t* offsetPtr,
1729
- U32 nbCompares, const U32 mls,
1730
- U32 extDict)
1731
- {
1732
- U32* const hashTable = zc->hashTable;
1733
- const U32 hashLog = zc->params.cParams.hashLog;
1734
- const size_t h = ZSTD_hashPtr(ip, hashLog, mls);
1735
- U32* const bt = zc->chainTable;
1736
- const U32 btLog = zc->params.cParams.chainLog - 1;
1737
- const U32 btMask= (1 << btLog) - 1;
1738
- U32 matchIndex = hashTable[h];
1739
- size_t commonLengthSmaller=0, commonLengthLarger=0;
1740
- const BYTE* const base = zc->base;
1741
- const BYTE* const dictBase = zc->dictBase;
1742
- const U32 dictLimit = zc->dictLimit;
1743
- const BYTE* const dictEnd = dictBase + dictLimit;
1744
- const BYTE* const prefixStart = base + dictLimit;
1745
- const U32 current = (U32)(ip-base);
1746
- const U32 btLow = btMask >= current ? 0 : current - btMask;
1747
- const U32 windowLow = zc->lowLimit;
1748
- U32* smallerPtr = bt + 2*(current&btMask);
1749
- U32* largerPtr = bt + 2*(current&btMask) + 1;
1750
- U32 matchEndIdx = current+8;
1751
- U32 dummy32; /* to be nullified at the end */
1752
- size_t bestLength = 0;
1753
-
1754
- hashTable[h] = current; /* Update Hash Table */
1755
-
1756
- while (nbCompares-- && (matchIndex > windowLow)) {
1757
- U32* nextPtr = bt + 2*(matchIndex & btMask);
1758
- size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */
1759
- const BYTE* match;
1760
-
1761
- if ((!extDict) || (matchIndex+matchLength >= dictLimit)) {
1762
- match = base + matchIndex;
1763
- if (match[matchLength] == ip[matchLength])
1764
- matchLength += ZSTD_count(ip+matchLength+1, match+matchLength+1, iend) +1;
1765
- } else {
1766
- match = dictBase + matchIndex;
1767
- matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iend, dictEnd, prefixStart);
1768
- if (matchIndex+matchLength >= dictLimit)
1769
- match = base + matchIndex; /* to prepare for next usage of match[matchLength] */
1770
- }
1771
-
1772
- if (matchLength > bestLength) {
1773
- if (matchLength > matchEndIdx - matchIndex)
1774
- matchEndIdx = matchIndex + (U32)matchLength;
1775
- if ( (4*(int)(matchLength-bestLength)) > (int)(ZSTD_highbit32(current-matchIndex+1) - ZSTD_highbit32((U32)offsetPtr[0]+1)) )
1776
- bestLength = matchLength, *offsetPtr = ZSTD_REP_MOVE + current - matchIndex;
1777
- if (ip+matchLength == iend) /* equal : no way to know if inf or sup */
1778
- break; /* drop, to guarantee consistency (miss a little bit of compression) */
1779
- }
1780
-
1781
- if (match[matchLength] < ip[matchLength]) {
1782
- /* match is smaller than current */
1783
- *smallerPtr = matchIndex; /* update smaller idx */
1784
- commonLengthSmaller = matchLength; /* all smaller will now have at least this guaranteed common length */
1785
- if (matchIndex <= btLow) { smallerPtr=&dummy32; break; } /* beyond tree size, stop the search */
1786
- smallerPtr = nextPtr+1; /* new "smaller" => larger of match */
1787
- matchIndex = nextPtr[1]; /* new matchIndex larger than previous (closer to current) */
1788
- } else {
1789
- /* match is larger than current */
1790
- *largerPtr = matchIndex;
1791
- commonLengthLarger = matchLength;
1792
- if (matchIndex <= btLow) { largerPtr=&dummy32; break; } /* beyond tree size, stop the search */
1793
- largerPtr = nextPtr;
1794
- matchIndex = nextPtr[0];
1795
- } }
1796
-
1797
- *smallerPtr = *largerPtr = 0;
1798
-
1799
- zc->nextToUpdate = (matchEndIdx > current + 8) ? matchEndIdx - 8 : current+1;
1800
- return bestLength;
1801
- }
1802
-
1803
-
1804
- static void ZSTD_updateTree(ZSTD_CCtx* zc, const BYTE* const ip, const BYTE* const iend, const U32 nbCompares, const U32 mls)
1805
- {
1806
- const BYTE* const base = zc->base;
1807
- const U32 target = (U32)(ip - base);
1808
- U32 idx = zc->nextToUpdate;
1809
-
1810
- while(idx < target)
1811
- idx += ZSTD_insertBt1(zc, base+idx, mls, iend, nbCompares, 0);
1812
- }
1813
-
1814
- /** ZSTD_BtFindBestMatch() : Tree updater, providing best match */
1815
- static size_t ZSTD_BtFindBestMatch (
1816
- ZSTD_CCtx* zc,
1817
- const BYTE* const ip, const BYTE* const iLimit,
1818
- size_t* offsetPtr,
1819
- const U32 maxNbAttempts, const U32 mls)
1820
- {
1821
- if (ip < zc->base + zc->nextToUpdate) return 0; /* skipped area */
1822
- ZSTD_updateTree(zc, ip, iLimit, maxNbAttempts, mls);
1823
- return ZSTD_insertBtAndFindBestMatch(zc, ip, iLimit, offsetPtr, maxNbAttempts, mls, 0);
1824
- }
1825
-
1826
-
1827
- static size_t ZSTD_BtFindBestMatch_selectMLS (
1828
- ZSTD_CCtx* zc, /* Index table will be updated */
1829
- const BYTE* ip, const BYTE* const iLimit,
1830
- size_t* offsetPtr,
1831
- const U32 maxNbAttempts, const U32 matchLengthSearch)
1832
- {
1833
- switch(matchLengthSearch)
1834
- {
1835
- default :
1836
- case 4 : return ZSTD_BtFindBestMatch(zc, ip, iLimit, offsetPtr, maxNbAttempts, 4);
1837
- case 5 : return ZSTD_BtFindBestMatch(zc, ip, iLimit, offsetPtr, maxNbAttempts, 5);
1838
- case 6 : return ZSTD_BtFindBestMatch(zc, ip, iLimit, offsetPtr, maxNbAttempts, 6);
1839
- }
1840
- }
1841
-
1842
-
1843
- static void ZSTD_updateTree_extDict(ZSTD_CCtx* zc, const BYTE* const ip, const BYTE* const iend, const U32 nbCompares, const U32 mls)
1844
- {
1845
- const BYTE* const base = zc->base;
1846
- const U32 target = (U32)(ip - base);
1847
- U32 idx = zc->nextToUpdate;
1848
-
1849
- while (idx < target) idx += ZSTD_insertBt1(zc, base+idx, mls, iend, nbCompares, 1);
1850
- }
1851
-
1852
-
1853
- /** Tree updater, providing best match */
1854
- static size_t ZSTD_BtFindBestMatch_extDict (
1855
- ZSTD_CCtx* zc,
1856
- const BYTE* const ip, const BYTE* const iLimit,
1857
- size_t* offsetPtr,
1858
- const U32 maxNbAttempts, const U32 mls)
1859
- {
1860
- if (ip < zc->base + zc->nextToUpdate) return 0; /* skipped area */
1861
- ZSTD_updateTree_extDict(zc, ip, iLimit, maxNbAttempts, mls);
1862
- return ZSTD_insertBtAndFindBestMatch(zc, ip, iLimit, offsetPtr, maxNbAttempts, mls, 1);
1863
- }
1864
-
1865
-
1866
- static size_t ZSTD_BtFindBestMatch_selectMLS_extDict (
1867
- ZSTD_CCtx* zc, /* Index table will be updated */
1868
- const BYTE* ip, const BYTE* const iLimit,
1869
- size_t* offsetPtr,
1870
- const U32 maxNbAttempts, const U32 matchLengthSearch)
1871
- {
1872
- switch(matchLengthSearch)
1873
- {
1874
- default :
1875
- case 4 : return ZSTD_BtFindBestMatch_extDict(zc, ip, iLimit, offsetPtr, maxNbAttempts, 4);
1876
- case 5 : return ZSTD_BtFindBestMatch_extDict(zc, ip, iLimit, offsetPtr, maxNbAttempts, 5);
1877
- case 6 : return ZSTD_BtFindBestMatch_extDict(zc, ip, iLimit, offsetPtr, maxNbAttempts, 6);
1878
- }
1879
- }
1880
-
1881
-
1882
-
1883
- /* ***********************
1884
- * Hash Chain
1885
- *************************/
1886
-
1887
- #define NEXT_IN_CHAIN(d, mask) chainTable[(d) & mask]
1888
-
1889
-
1890
- /* Update chains up to ip (excluded)
1891
- Assumption : always within prefix (ie. not within extDict) */
1892
- FORCE_INLINE
1893
- U32 ZSTD_insertAndFindFirstIndex (ZSTD_CCtx* zc, const BYTE* ip, U32 mls)
1894
- {
1895
- U32* const hashTable = zc->hashTable;
1896
- const U32 hashLog = zc->params.cParams.hashLog;
1897
- U32* const chainTable = zc->chainTable;
1898
- const U32 chainMask = (1 << zc->params.cParams.chainLog) - 1;
1899
- const BYTE* const base = zc->base;
1900
- const U32 target = (U32)(ip - base);
1901
- U32 idx = zc->nextToUpdate;
1902
-
1903
- while(idx < target) { /* catch up */
1904
- size_t const h = ZSTD_hashPtr(base+idx, hashLog, mls);
1905
- NEXT_IN_CHAIN(idx, chainMask) = hashTable[h];
1906
- hashTable[h] = idx;
1907
- idx++;
1908
- }
1909
-
1910
- zc->nextToUpdate = target;
1911
- return hashTable[ZSTD_hashPtr(ip, hashLog, mls)];
1912
- }
1913
-
1914
-
1915
-
1916
- FORCE_INLINE /* inlining is important to hardwire a hot branch (template emulation) */
1917
- size_t ZSTD_HcFindBestMatch_generic (
1918
- ZSTD_CCtx* zc, /* Index table will be updated */
1919
- const BYTE* const ip, const BYTE* const iLimit,
1920
- size_t* offsetPtr,
1921
- const U32 maxNbAttempts, const U32 mls, const U32 extDict)
1922
- {
1923
- U32* const chainTable = zc->chainTable;
1924
- const U32 chainSize = (1 << zc->params.cParams.chainLog);
1925
- const U32 chainMask = chainSize-1;
1926
- const BYTE* const base = zc->base;
1927
- const BYTE* const dictBase = zc->dictBase;
1928
- const U32 dictLimit = zc->dictLimit;
1929
- const BYTE* const prefixStart = base + dictLimit;
1930
- const BYTE* const dictEnd = dictBase + dictLimit;
1931
- const U32 lowLimit = zc->lowLimit;
1932
- const U32 current = (U32)(ip-base);
1933
- const U32 minChain = current > chainSize ? current - chainSize : 0;
1934
- int nbAttempts=maxNbAttempts;
1935
- size_t ml=EQUAL_READ32-1;
1936
-
1937
- /* HC4 match finder */
1938
- U32 matchIndex = ZSTD_insertAndFindFirstIndex (zc, ip, mls);
1939
-
1940
- for ( ; (matchIndex>lowLimit) & (nbAttempts>0) ; nbAttempts--) {
1941
- const BYTE* match;
1942
- size_t currentMl=0;
1943
- if ((!extDict) || matchIndex >= dictLimit) {
1944
- match = base + matchIndex;
1945
- if (match[ml] == ip[ml]) /* potentially better */
1946
- currentMl = ZSTD_count(ip, match, iLimit);
1947
- } else {
1948
- match = dictBase + matchIndex;
1949
- if (MEM_read32(match) == MEM_read32(ip)) /* assumption : matchIndex <= dictLimit-4 (by table construction) */
1950
- currentMl = ZSTD_count_2segments(ip+EQUAL_READ32, match+EQUAL_READ32, iLimit, dictEnd, prefixStart) + EQUAL_READ32;
1951
- }
1952
-
1953
- /* save best solution */
1954
- if (currentMl > ml) { ml = currentMl; *offsetPtr = current - matchIndex + ZSTD_REP_MOVE; if (ip+currentMl == iLimit) break; /* best possible, and avoid read overflow*/ }
1955
-
1956
- if (matchIndex <= minChain) break;
1957
- matchIndex = NEXT_IN_CHAIN(matchIndex, chainMask);
1958
- }
1959
-
1960
- return ml;
1961
- }
1962
-
1963
-
1964
- FORCE_INLINE size_t ZSTD_HcFindBestMatch_selectMLS (
1965
- ZSTD_CCtx* zc,
1966
- const BYTE* ip, const BYTE* const iLimit,
1967
- size_t* offsetPtr,
1968
- const U32 maxNbAttempts, const U32 matchLengthSearch)
1969
- {
1970
- switch(matchLengthSearch)
1971
- {
1972
- default :
1973
- case 4 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 4, 0);
1974
- case 5 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 5, 0);
1975
- case 6 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 6, 0);
1976
- }
1977
- }
1978
-
1979
-
1980
- FORCE_INLINE size_t ZSTD_HcFindBestMatch_extDict_selectMLS (
1981
- ZSTD_CCtx* zc,
1982
- const BYTE* ip, const BYTE* const iLimit,
1983
- size_t* offsetPtr,
1984
- const U32 maxNbAttempts, const U32 matchLengthSearch)
1985
- {
1986
- switch(matchLengthSearch)
1987
- {
1988
- default :
1989
- case 4 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 4, 1);
1990
- case 5 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 5, 1);
1991
- case 6 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 6, 1);
1992
- }
1993
- }
1994
-
1995
-
1996
- /* *******************************
1997
- * Common parser - lazy strategy
1998
- *********************************/
1999
- FORCE_INLINE
2000
- void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx,
2001
- const void* src, size_t srcSize,
2002
- const U32 searchMethod, const U32 depth)
2003
- {
2004
- seqStore_t* seqStorePtr = &(ctx->seqStore);
2005
- const BYTE* const istart = (const BYTE*)src;
2006
- const BYTE* ip = istart;
2007
- const BYTE* anchor = istart;
2008
- const BYTE* const iend = istart + srcSize;
2009
- const BYTE* const ilimit = iend - 8;
2010
- const BYTE* const base = ctx->base + ctx->dictLimit;
2011
-
2012
- U32 const maxSearches = 1 << ctx->params.cParams.searchLog;
2013
- U32 const mls = ctx->params.cParams.searchLength;
2014
-
2015
- typedef size_t (*searchMax_f)(ZSTD_CCtx* zc, const BYTE* ip, const BYTE* iLimit,
2016
- size_t* offsetPtr,
2017
- U32 maxNbAttempts, U32 matchLengthSearch);
2018
- searchMax_f const searchMax = searchMethod ? ZSTD_BtFindBestMatch_selectMLS : ZSTD_HcFindBestMatch_selectMLS;
2019
- U32 offset_1 = ctx->rep[0], offset_2 = ctx->rep[1], savedOffset=0;
2020
-
2021
- /* init */
2022
- ip += (ip==base);
2023
- ctx->nextToUpdate3 = ctx->nextToUpdate;
2024
- { U32 const maxRep = (U32)(ip-base);
2025
- if (offset_2 > maxRep) savedOffset = offset_2, offset_2 = 0;
2026
- if (offset_1 > maxRep) savedOffset = offset_1, offset_1 = 0;
2027
- }
2028
-
2029
- /* Match Loop */
2030
- while (ip < ilimit) {
2031
- size_t matchLength=0;
2032
- size_t offset=0;
2033
- const BYTE* start=ip+1;
2034
-
2035
- /* check repCode */
2036
- if ((offset_1>0) & (MEM_read32(ip+1) == MEM_read32(ip+1 - offset_1))) {
2037
- /* repcode : we take it */
2038
- matchLength = ZSTD_count(ip+1+EQUAL_READ32, ip+1+EQUAL_READ32-offset_1, iend) + EQUAL_READ32;
2039
- if (depth==0) goto _storeSequence;
2040
- }
2041
-
2042
- /* first search (depth 0) */
2043
- { size_t offsetFound = 99999999;
2044
- size_t const ml2 = searchMax(ctx, ip, iend, &offsetFound, maxSearches, mls);
2045
- if (ml2 > matchLength)
2046
- matchLength = ml2, start = ip, offset=offsetFound;
2047
- }
2048
-
2049
- if (matchLength < EQUAL_READ32) {
2050
- ip += ((ip-anchor) >> g_searchStrength) + 1; /* jump faster over incompressible sections */
2051
- continue;
2052
- }
2053
-
2054
- /* let's try to find a better solution */
2055
- if (depth>=1)
2056
- while (ip<ilimit) {
2057
- ip ++;
2058
- if ((offset) && ((offset_1>0) & (MEM_read32(ip) == MEM_read32(ip - offset_1)))) {
2059
- size_t const mlRep = ZSTD_count(ip+EQUAL_READ32, ip+EQUAL_READ32-offset_1, iend) + EQUAL_READ32;
2060
- int const gain2 = (int)(mlRep * 3);
2061
- int const gain1 = (int)(matchLength*3 - ZSTD_highbit32((U32)offset+1) + 1);
2062
- if ((mlRep >= EQUAL_READ32) && (gain2 > gain1))
2063
- matchLength = mlRep, offset = 0, start = ip;
2064
- }
2065
- { size_t offset2=99999999;
2066
- size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
2067
- int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)offset2+1)); /* raw approx */
2068
- int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 4);
2069
- if ((ml2 >= EQUAL_READ32) && (gain2 > gain1)) {
2070
- matchLength = ml2, offset = offset2, start = ip;
2071
- continue; /* search a better one */
2072
- } }
2073
-
2074
- /* let's find an even better one */
2075
- if ((depth==2) && (ip<ilimit)) {
2076
- ip ++;
2077
- if ((offset) && ((offset_1>0) & (MEM_read32(ip) == MEM_read32(ip - offset_1)))) {
2078
- size_t const ml2 = ZSTD_count(ip+EQUAL_READ32, ip+EQUAL_READ32-offset_1, iend) + EQUAL_READ32;
2079
- int const gain2 = (int)(ml2 * 4);
2080
- int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 1);
2081
- if ((ml2 >= EQUAL_READ32) && (gain2 > gain1))
2082
- matchLength = ml2, offset = 0, start = ip;
2083
- }
2084
- { size_t offset2=99999999;
2085
- size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
2086
- int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)offset2+1)); /* raw approx */
2087
- int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 7);
2088
- if ((ml2 >= EQUAL_READ32) && (gain2 > gain1)) {
2089
- matchLength = ml2, offset = offset2, start = ip;
2090
- continue;
2091
- } } }
2092
- break; /* nothing found : store previous solution */
2093
- }
2094
-
2095
- /* catch up */
2096
- if (offset) {
2097
- while ((start>anchor) && (start>base+offset-ZSTD_REP_MOVE) && (start[-1] == start[-1-offset+ZSTD_REP_MOVE])) /* only search for offset within prefix */
2098
- { start--; matchLength++; }
2099
- offset_2 = offset_1; offset_1 = (U32)(offset - ZSTD_REP_MOVE);
2100
- }
2101
-
2102
- /* store sequence */
2103
- _storeSequence:
2104
- { size_t const litLength = start - anchor;
2105
- ZSTD_storeSeq(seqStorePtr, litLength, anchor, (U32)offset, matchLength-MINMATCH);
2106
- anchor = ip = start + matchLength;
2107
- }
2108
-
2109
- /* check immediate repcode */
2110
- while ( (ip <= ilimit)
2111
- && ((offset_2>0)
2112
- & (MEM_read32(ip) == MEM_read32(ip - offset_2)) )) {
2113
- /* store sequence */
2114
- matchLength = ZSTD_count(ip+EQUAL_READ32, ip+EQUAL_READ32-offset_2, iend) + EQUAL_READ32;
2115
- offset = offset_2; offset_2 = offset_1; offset_1 = (U32)offset; /* swap repcodes */
2116
- ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, matchLength-MINMATCH);
2117
- ip += matchLength;
2118
- anchor = ip;
2119
- continue; /* faster when present ... (?) */
2120
- } }
2121
-
2122
- /* Save reps for next block */
2123
- ctx->savedRep[0] = offset_1 ? offset_1 : savedOffset;
2124
- ctx->savedRep[1] = offset_2 ? offset_2 : savedOffset;
2125
-
2126
- /* Last Literals */
2127
- { size_t const lastLLSize = iend - anchor;
2128
- memcpy(seqStorePtr->lit, anchor, lastLLSize);
2129
- seqStorePtr->lit += lastLLSize;
2130
- ZSTD_statsUpdatePrices(&seqStorePtr->stats, lastLLSize, anchor, 0, 0);
2131
- }
2132
- }
2133
-
2134
-
2135
- static void ZSTD_compressBlock_btlazy2(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
2136
- {
2137
- ZSTD_compressBlock_lazy_generic(ctx, src, srcSize, 1, 2);
2138
- }
2139
-
2140
- static void ZSTD_compressBlock_lazy2(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
2141
- {
2142
- ZSTD_compressBlock_lazy_generic(ctx, src, srcSize, 0, 2);
2143
- }
2144
-
2145
- static void ZSTD_compressBlock_lazy(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
2146
- {
2147
- ZSTD_compressBlock_lazy_generic(ctx, src, srcSize, 0, 1);
2148
- }
2149
-
2150
- static void ZSTD_compressBlock_greedy(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
2151
- {
2152
- ZSTD_compressBlock_lazy_generic(ctx, src, srcSize, 0, 0);
2153
- }
2154
-
2155
-
2156
- FORCE_INLINE
2157
- void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx,
2158
- const void* src, size_t srcSize,
2159
- const U32 searchMethod, const U32 depth)
2160
- {
2161
- seqStore_t* seqStorePtr = &(ctx->seqStore);
2162
- const BYTE* const istart = (const BYTE*)src;
2163
- const BYTE* ip = istart;
2164
- const BYTE* anchor = istart;
2165
- const BYTE* const iend = istart + srcSize;
2166
- const BYTE* const ilimit = iend - 8;
2167
- const BYTE* const base = ctx->base;
2168
- const U32 dictLimit = ctx->dictLimit;
2169
- const U32 lowestIndex = ctx->lowLimit;
2170
- const BYTE* const prefixStart = base + dictLimit;
2171
- const BYTE* const dictBase = ctx->dictBase;
2172
- const BYTE* const dictEnd = dictBase + dictLimit;
2173
- const BYTE* const dictStart = dictBase + ctx->lowLimit;
2174
-
2175
- const U32 maxSearches = 1 << ctx->params.cParams.searchLog;
2176
- const U32 mls = ctx->params.cParams.searchLength;
2177
-
2178
- typedef size_t (*searchMax_f)(ZSTD_CCtx* zc, const BYTE* ip, const BYTE* iLimit,
2179
- size_t* offsetPtr,
2180
- U32 maxNbAttempts, U32 matchLengthSearch);
2181
- searchMax_f searchMax = searchMethod ? ZSTD_BtFindBestMatch_selectMLS_extDict : ZSTD_HcFindBestMatch_extDict_selectMLS;
2182
-
2183
- U32 offset_1 = ctx->rep[0], offset_2 = ctx->rep[1];
2184
-
2185
- /* init */
2186
- ctx->nextToUpdate3 = ctx->nextToUpdate;
2187
- ip += (ip == prefixStart);
2188
-
2189
- /* Match Loop */
2190
- while (ip < ilimit) {
2191
- size_t matchLength=0;
2192
- size_t offset=0;
2193
- const BYTE* start=ip+1;
2194
- U32 current = (U32)(ip-base);
2195
-
2196
- /* check repCode */
2197
- { const U32 repIndex = (U32)(current+1 - offset_1);
2198
- const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
2199
- const BYTE* const repMatch = repBase + repIndex;
2200
- if (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex > lowestIndex)) /* intentional overflow */
2201
- if (MEM_read32(ip+1) == MEM_read32(repMatch)) {
2202
- /* repcode detected we should take it */
2203
- const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
2204
- matchLength = ZSTD_count_2segments(ip+1+EQUAL_READ32, repMatch+EQUAL_READ32, iend, repEnd, prefixStart) + EQUAL_READ32;
2205
- if (depth==0) goto _storeSequence;
2206
- } }
2207
-
2208
- /* first search (depth 0) */
2209
- { size_t offsetFound = 99999999;
2210
- size_t const ml2 = searchMax(ctx, ip, iend, &offsetFound, maxSearches, mls);
2211
- if (ml2 > matchLength)
2212
- matchLength = ml2, start = ip, offset=offsetFound;
2213
- }
2214
-
2215
- if (matchLength < EQUAL_READ32) {
2216
- ip += ((ip-anchor) >> g_searchStrength) + 1; /* jump faster over incompressible sections */
2217
- continue;
2218
- }
2219
-
2220
- /* let's try to find a better solution */
2221
- if (depth>=1)
2222
- while (ip<ilimit) {
2223
- ip ++;
2224
- current++;
2225
- /* check repCode */
2226
- if (offset) {
2227
- const U32 repIndex = (U32)(current - offset_1);
2228
- const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
2229
- const BYTE* const repMatch = repBase + repIndex;
2230
- if (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex > lowestIndex)) /* intentional overflow */
2231
- if (MEM_read32(ip) == MEM_read32(repMatch)) {
2232
- /* repcode detected */
2233
- const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
2234
- size_t const repLength = ZSTD_count_2segments(ip+EQUAL_READ32, repMatch+EQUAL_READ32, iend, repEnd, prefixStart) + EQUAL_READ32;
2235
- int const gain2 = (int)(repLength * 3);
2236
- int const gain1 = (int)(matchLength*3 - ZSTD_highbit32((U32)offset+1) + 1);
2237
- if ((repLength >= EQUAL_READ32) && (gain2 > gain1))
2238
- matchLength = repLength, offset = 0, start = ip;
2239
- } }
2240
-
2241
- /* search match, depth 1 */
2242
- { size_t offset2=99999999;
2243
- size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
2244
- int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)offset2+1)); /* raw approx */
2245
- int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 4);
2246
- if ((ml2 >= EQUAL_READ32) && (gain2 > gain1)) {
2247
- matchLength = ml2, offset = offset2, start = ip;
2248
- continue; /* search a better one */
2249
- } }
2250
-
2251
- /* let's find an even better one */
2252
- if ((depth==2) && (ip<ilimit)) {
2253
- ip ++;
2254
- current++;
2255
- /* check repCode */
2256
- if (offset) {
2257
- const U32 repIndex = (U32)(current - offset_1);
2258
- const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
2259
- const BYTE* const repMatch = repBase + repIndex;
2260
- if (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex > lowestIndex)) /* intentional overflow */
2261
- if (MEM_read32(ip) == MEM_read32(repMatch)) {
2262
- /* repcode detected */
2263
- const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
2264
- size_t repLength = ZSTD_count_2segments(ip+EQUAL_READ32, repMatch+EQUAL_READ32, iend, repEnd, prefixStart) + EQUAL_READ32;
2265
- int gain2 = (int)(repLength * 4);
2266
- int gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 1);
2267
- if ((repLength >= EQUAL_READ32) && (gain2 > gain1))
2268
- matchLength = repLength, offset = 0, start = ip;
2269
- } }
2270
-
2271
- /* search match, depth 2 */
2272
- { size_t offset2=99999999;
2273
- size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
2274
- int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)offset2+1)); /* raw approx */
2275
- int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 7);
2276
- if ((ml2 >= EQUAL_READ32) && (gain2 > gain1)) {
2277
- matchLength = ml2, offset = offset2, start = ip;
2278
- continue;
2279
- } } }
2280
- break; /* nothing found : store previous solution */
2281
- }
2282
-
2283
- /* catch up */
2284
- if (offset) {
2285
- U32 const matchIndex = (U32)((start-base) - (offset - ZSTD_REP_MOVE));
2286
- const BYTE* match = (matchIndex < dictLimit) ? dictBase + matchIndex : base + matchIndex;
2287
- const BYTE* const mStart = (matchIndex < dictLimit) ? dictStart : prefixStart;
2288
- while ((start>anchor) && (match>mStart) && (start[-1] == match[-1])) { start--; match--; matchLength++; } /* catch up */
2289
- offset_2 = offset_1; offset_1 = (U32)(offset - ZSTD_REP_MOVE);
2290
- }
2291
-
2292
- /* store sequence */
2293
- _storeSequence:
2294
- { size_t const litLength = start - anchor;
2295
- ZSTD_storeSeq(seqStorePtr, litLength, anchor, (U32)offset, matchLength-MINMATCH);
2296
- anchor = ip = start + matchLength;
2297
- }
2298
-
2299
- /* check immediate repcode */
2300
- while (ip <= ilimit) {
2301
- const U32 repIndex = (U32)((ip-base) - offset_2);
2302
- const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
2303
- const BYTE* const repMatch = repBase + repIndex;
2304
- if (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex > lowestIndex)) /* intentional overflow */
2305
- if (MEM_read32(ip) == MEM_read32(repMatch)) {
2306
- /* repcode detected we should take it */
2307
- const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
2308
- matchLength = ZSTD_count_2segments(ip+EQUAL_READ32, repMatch+EQUAL_READ32, iend, repEnd, prefixStart) + EQUAL_READ32;
2309
- offset = offset_2; offset_2 = offset_1; offset_1 = (U32)offset; /* swap offset history */
2310
- ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, matchLength-MINMATCH);
2311
- ip += matchLength;
2312
- anchor = ip;
2313
- continue; /* faster when present ... (?) */
2314
- }
2315
- break;
2316
- } }
2317
-
2318
- /* Save reps for next block */
2319
- ctx->savedRep[0] = offset_1; ctx->savedRep[1] = offset_2;
2320
-
2321
- /* Last Literals */
2322
- { size_t const lastLLSize = iend - anchor;
2323
- memcpy(seqStorePtr->lit, anchor, lastLLSize);
2324
- seqStorePtr->lit += lastLLSize;
2325
- }
2326
- }
2327
-
2328
-
2329
- void ZSTD_compressBlock_greedy_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
2330
- {
2331
- ZSTD_compressBlock_lazy_extDict_generic(ctx, src, srcSize, 0, 0);
2332
- }
2333
-
2334
- static void ZSTD_compressBlock_lazy_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
2335
- {
2336
- ZSTD_compressBlock_lazy_extDict_generic(ctx, src, srcSize, 0, 1);
2337
- }
2338
-
2339
- static void ZSTD_compressBlock_lazy2_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
2340
- {
2341
- ZSTD_compressBlock_lazy_extDict_generic(ctx, src, srcSize, 0, 2);
2342
- }
2343
-
2344
- static void ZSTD_compressBlock_btlazy2_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
2345
- {
2346
- ZSTD_compressBlock_lazy_extDict_generic(ctx, src, srcSize, 1, 2);
2347
- }
2348
-
2349
-
2350
- /* The optimal parser */
2351
- #include "zstd_opt.h"
2352
-
2353
- static void ZSTD_compressBlock_btopt(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
2354
- {
2355
- #ifdef ZSTD_OPT_H_91842398743
2356
- ZSTD_compressBlock_opt_generic(ctx, src, srcSize);
2357
- #else
2358
- (void)ctx; (void)src; (void)srcSize;
2359
- return;
2360
- #endif
2361
- }
2362
-
2363
- static void ZSTD_compressBlock_btopt_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
2364
- {
2365
- #ifdef ZSTD_OPT_H_91842398743
2366
- ZSTD_compressBlock_opt_extDict_generic(ctx, src, srcSize);
2367
- #else
2368
- (void)ctx; (void)src; (void)srcSize;
2369
- return;
2370
- #endif
2371
- }
2372
-
2373
-
2374
- typedef void (*ZSTD_blockCompressor) (ZSTD_CCtx* ctx, const void* src, size_t srcSize);
2375
-
2376
- static ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, int extDict)
2377
- {
2378
- static const ZSTD_blockCompressor blockCompressor[2][7] = {
2379
- { ZSTD_compressBlock_fast, ZSTD_compressBlock_doubleFast, ZSTD_compressBlock_greedy, ZSTD_compressBlock_lazy, ZSTD_compressBlock_lazy2, ZSTD_compressBlock_btlazy2, ZSTD_compressBlock_btopt },
2380
- { ZSTD_compressBlock_fast_extDict, ZSTD_compressBlock_doubleFast_extDict, ZSTD_compressBlock_greedy_extDict, ZSTD_compressBlock_lazy_extDict,ZSTD_compressBlock_lazy2_extDict, ZSTD_compressBlock_btlazy2_extDict, ZSTD_compressBlock_btopt_extDict }
2381
- };
2382
-
2383
- return blockCompressor[extDict][(U32)strat];
2384
- }
2385
-
2386
-
2387
- static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc, void* dst, size_t dstCapacity, const void* src, size_t srcSize)
2388
- {
2389
- ZSTD_blockCompressor const blockCompressor = ZSTD_selectBlockCompressor(zc->params.cParams.strategy, zc->lowLimit < zc->dictLimit);
2390
- if (srcSize < MIN_CBLOCK_SIZE+ZSTD_blockHeaderSize+1) return 0; /* don't even attempt compression below a certain srcSize */
2391
- ZSTD_resetSeqStore(&(zc->seqStore));
2392
- blockCompressor(zc, src, srcSize);
2393
- return ZSTD_compressSequences(zc, dst, dstCapacity, srcSize);
2394
- }
2395
-
2396
-
2397
-
2398
-
2399
- static size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
2400
- void* dst, size_t dstCapacity,
2401
- const void* src, size_t srcSize)
2402
- {
2403
- size_t blockSize = cctx->blockSize;
2404
- size_t remaining = srcSize;
2405
- const BYTE* ip = (const BYTE*)src;
2406
- BYTE* const ostart = (BYTE*)dst;
2407
- BYTE* op = ostart;
2408
- const U32 maxDist = 1 << cctx->params.cParams.windowLog;
2409
- ZSTD_stats_t* stats = &cctx->seqStore.stats;
2410
- ZSTD_statsInit(stats); /* debug only */
2411
-
2412
- if (cctx->params.fParams.checksumFlag)
2413
- XXH64_update(&cctx->xxhState, src, srcSize);
2414
-
2415
- while (remaining) {
2416
- size_t cSize;
2417
- ZSTD_statsResetFreqs(stats); /* debug only */
2418
-
2419
- if (dstCapacity < ZSTD_blockHeaderSize + MIN_CBLOCK_SIZE) return ERROR(dstSize_tooSmall); /* not enough space to store compressed block */
2420
- if (remaining < blockSize) blockSize = remaining;
2421
-
2422
- if ((U32)(ip+blockSize - cctx->base) > cctx->loadedDictEnd + maxDist) {
2423
- /* enforce maxDist */
2424
- U32 const newLowLimit = (U32)(ip+blockSize - cctx->base) - maxDist;
2425
- if (cctx->lowLimit < newLowLimit) cctx->lowLimit = newLowLimit;
2426
- if (cctx->dictLimit < cctx->lowLimit) cctx->dictLimit = cctx->lowLimit;
2427
- }
2428
-
2429
- cSize = ZSTD_compressBlock_internal(cctx, op+ZSTD_blockHeaderSize, dstCapacity-ZSTD_blockHeaderSize, ip, blockSize);
2430
- if (ZSTD_isError(cSize)) return cSize;
2431
-
2432
- if (cSize == 0) { /* block is not compressible */
2433
- cSize = ZSTD_noCompressBlock(op, dstCapacity, ip, blockSize);
2434
- if (ZSTD_isError(cSize)) return cSize;
2435
- } else {
2436
- op[0] = (BYTE)(cSize>>16);
2437
- op[1] = (BYTE)(cSize>>8);
2438
- op[2] = (BYTE)cSize;
2439
- op[0] += (BYTE)(bt_compressed << 6); /* is a compressed block */
2440
- cSize += 3;
2441
- }
2442
-
2443
- remaining -= blockSize;
2444
- dstCapacity -= cSize;
2445
- ip += blockSize;
2446
- op += cSize;
2447
- }
2448
-
2449
- ZSTD_statsPrint(stats, cctx->params.cParams.searchLength);
2450
- return op-ostart;
2451
- }
2452
-
2453
-
2454
- static size_t ZSTD_writeFrameHeader(void* dst, size_t dstCapacity,
2455
- ZSTD_parameters params, U64 pledgedSrcSize, U32 dictID)
2456
- { BYTE* const op = (BYTE*)dst;
2457
- U32 const dictIDSizeCode = (dictID>0) + (dictID>=256) + (dictID>=65536); /* 0-3 */
2458
- U32 const checksumFlag = params.fParams.checksumFlag>0;
2459
- U32 const windowSize = 1U << params.cParams.windowLog;
2460
- U32 const directModeFlag = params.fParams.contentSizeFlag && (windowSize > (pledgedSrcSize-1));
2461
- BYTE const windowLogByte = (BYTE)((params.cParams.windowLog - ZSTD_WINDOWLOG_ABSOLUTEMIN) << 3);
2462
- U32 const fcsCode = params.fParams.contentSizeFlag ?
2463
- (pledgedSrcSize>=256) + (pledgedSrcSize>=65536+256) + (pledgedSrcSize>=0xFFFFFFFFU) : /* 0-3 */
2464
- 0;
2465
- BYTE const frameHeaderDecriptionByte = (BYTE)(dictIDSizeCode + (checksumFlag<<2) + (directModeFlag<<5) + (fcsCode<<6) );
2466
- size_t pos;
2467
-
2468
- if (dstCapacity < ZSTD_frameHeaderSize_max) return ERROR(dstSize_tooSmall);
2469
-
2470
- MEM_writeLE32(dst, ZSTD_MAGICNUMBER);
2471
- op[4] = frameHeaderDecriptionByte; pos=5;
2472
- if (!directModeFlag) op[pos++] = windowLogByte;
2473
- switch(dictIDSizeCode)
2474
- {
2475
- default: /* impossible */
2476
- case 0 : break;
2477
- case 1 : op[pos] = (BYTE)(dictID); pos++; break;
2478
- case 2 : MEM_writeLE16(op+pos, (U16)(dictID)); pos+=2; break;
2479
- case 3 : MEM_writeLE32(op+pos, dictID); pos+=4; break;
2480
- }
2481
- switch(fcsCode)
2482
- {
2483
- default: /* impossible */
2484
- case 0 : if (directModeFlag) op[pos++] = (BYTE)(pledgedSrcSize); break;
2485
- case 1 : MEM_writeLE16(op+pos, (U16)(pledgedSrcSize-256)); pos+=2; break;
2486
- case 2 : MEM_writeLE32(op+pos, (U32)(pledgedSrcSize)); pos+=4; break;
2487
- case 3 : MEM_writeLE64(op+pos, (U64)(pledgedSrcSize)); pos+=8; break;
2488
- }
2489
- return pos;
2490
- }
2491
-
2492
-
2493
- static size_t ZSTD_compressContinue_internal (ZSTD_CCtx* zc,
2494
- void* dst, size_t dstCapacity,
2495
- const void* src, size_t srcSize,
2496
- U32 frame)
2497
- {
2498
- const BYTE* const ip = (const BYTE*) src;
2499
- size_t fhSize = 0;
2500
-
2501
- if (zc->stage==0) return ERROR(stage_wrong);
2502
- if (frame && (zc->stage==1)) { /* copy saved header */
2503
- fhSize = ZSTD_writeFrameHeader(dst, dstCapacity, zc->params, zc->frameContentSize, zc->dictID);
2504
- if (ZSTD_isError(fhSize)) return fhSize;
2505
- dstCapacity -= fhSize;
2506
- dst = (char*)dst + fhSize;
2507
- zc->stage = 2;
2508
- }
2509
-
2510
- /* Check if blocks follow each other */
2511
- if (src != zc->nextSrc) {
2512
- /* not contiguous */
2513
- size_t const delta = zc->nextSrc - ip;
2514
- zc->lowLimit = zc->dictLimit;
2515
- zc->dictLimit = (U32)(zc->nextSrc - zc->base);
2516
- zc->dictBase = zc->base;
2517
- zc->base -= delta;
2518
- zc->nextToUpdate = zc->dictLimit;
2519
- if (zc->dictLimit - zc->lowLimit < 8) zc->lowLimit = zc->dictLimit; /* too small extDict */
2520
- }
2521
-
2522
- /* preemptive overflow correction */
2523
- if (zc->lowLimit > (1<<30)) {
2524
- U32 const btplus = (zc->params.cParams.strategy == ZSTD_btlazy2) | (zc->params.cParams.strategy == ZSTD_btopt);
2525
- U32 const chainMask = (1 << (zc->params.cParams.chainLog - btplus)) - 1;
2526
- U32 const newLowLimit = zc->lowLimit & chainMask; /* preserve position % chainSize */
2527
- U32 const correction = zc->lowLimit - newLowLimit;
2528
- ZSTD_reduceIndex(zc, correction);
2529
- zc->base += correction;
2530
- zc->dictBase += correction;
2531
- zc->lowLimit = newLowLimit;
2532
- zc->dictLimit -= correction;
2533
- if (zc->nextToUpdate < correction) zc->nextToUpdate = 0;
2534
- else zc->nextToUpdate -= correction;
2535
- }
2536
-
2537
- /* if input and dictionary overlap : reduce dictionary (presumed modified by input) */
2538
- if ((ip+srcSize > zc->dictBase + zc->lowLimit) && (ip < zc->dictBase + zc->dictLimit)) {
2539
- zc->lowLimit = (U32)(ip + srcSize - zc->dictBase);
2540
- if (zc->lowLimit > zc->dictLimit) zc->lowLimit = zc->dictLimit;
2541
- }
2542
-
2543
- zc->nextSrc = ip + srcSize;
2544
- { size_t const cSize = frame ?
2545
- ZSTD_compress_generic (zc, dst, dstCapacity, src, srcSize) :
2546
- ZSTD_compressBlock_internal (zc, dst, dstCapacity, src, srcSize);
2547
- if (ZSTD_isError(cSize)) return cSize;
2548
- return cSize + fhSize;
2549
- }
2550
- }
2551
-
2552
-
2553
- size_t ZSTD_compressContinue (ZSTD_CCtx* zc,
2554
- void* dst, size_t dstCapacity,
2555
- const void* src, size_t srcSize)
2556
- {
2557
- return ZSTD_compressContinue_internal(zc, dst, dstCapacity, src, srcSize, 1);
2558
- }
2559
-
2560
-
2561
- size_t ZSTD_compressBlock(ZSTD_CCtx* zc, void* dst, size_t dstCapacity, const void* src, size_t srcSize)
2562
- {
2563
- size_t const blockSizeMax = MIN (ZSTD_BLOCKSIZE_MAX, 1 << zc->params.cParams.windowLog);
2564
- if (srcSize > blockSizeMax) return ERROR(srcSize_wrong);
2565
- ZSTD_LOG_BLOCK("%p: ZSTD_compressBlock searchLength=%d\n", zc->base, zc->params.cParams.searchLength);
2566
- return ZSTD_compressContinue_internal(zc, dst, dstCapacity, src, srcSize, 0);
2567
- }
2568
-
2569
-
2570
- static size_t ZSTD_loadDictionaryContent(ZSTD_CCtx* zc, const void* src, size_t srcSize)
2571
- {
2572
- const BYTE* const ip = (const BYTE*) src;
2573
- const BYTE* const iend = ip + srcSize;
2574
-
2575
- /* input becomes current prefix */
2576
- zc->lowLimit = zc->dictLimit;
2577
- zc->dictLimit = (U32)(zc->nextSrc - zc->base);
2578
- zc->dictBase = zc->base;
2579
- zc->base += ip - zc->nextSrc;
2580
- zc->nextToUpdate = zc->dictLimit;
2581
- zc->loadedDictEnd = (U32)(iend - zc->base);
2582
-
2583
- zc->nextSrc = iend;
2584
- if (srcSize <= 8) return 0;
2585
-
2586
- switch(zc->params.cParams.strategy)
2587
- {
2588
- case ZSTD_fast:
2589
- ZSTD_fillHashTable (zc, iend, zc->params.cParams.searchLength);
2590
- break;
2591
-
2592
- case ZSTD_dfast:
2593
- ZSTD_fillDoubleHashTable (zc, iend, zc->params.cParams.searchLength);
2594
- break;
2595
-
2596
- case ZSTD_greedy:
2597
- case ZSTD_lazy:
2598
- case ZSTD_lazy2:
2599
- ZSTD_insertAndFindFirstIndex (zc, iend-8, zc->params.cParams.searchLength);
2600
- break;
2601
-
2602
- case ZSTD_btlazy2:
2603
- case ZSTD_btopt:
2604
- ZSTD_updateTree(zc, iend-8, iend, 1 << zc->params.cParams.searchLog, zc->params.cParams.searchLength);
2605
- break;
2606
-
2607
- default:
2608
- return ERROR(GENERIC); /* strategy doesn't exist; impossible */
2609
- }
2610
-
2611
- zc->nextToUpdate = zc->loadedDictEnd;
2612
- return 0;
2613
- }
2614
-
2615
-
2616
- /* Dictionary format :
2617
- Magic == ZSTD_DICT_MAGIC (4 bytes)
2618
- HUF_writeCTable(256)
2619
- FSE_writeNCount(ml)
2620
- FSE_writeNCount(off)
2621
- FSE_writeNCount(ll)
2622
- RepOffsets
2623
- Dictionary content
2624
- */
2625
- /*! ZSTD_loadDictEntropyStats() :
2626
- @return : size read from dictionary
2627
- note : magic number supposed already checked */
2628
- static size_t ZSTD_loadDictEntropyStats(ZSTD_CCtx* cctx, const void* dict, size_t dictSize)
2629
- {
2630
- const BYTE* dictPtr = (const BYTE*)dict;
2631
- const BYTE* const dictEnd = dictPtr + dictSize;
2632
-
2633
- { size_t const hufHeaderSize = HUF_readCTable(cctx->hufTable, 255, dict, dictSize);
2634
- if (HUF_isError(hufHeaderSize)) return ERROR(dictionary_corrupted);
2635
- dictPtr += hufHeaderSize;
2636
- }
2637
-
2638
- { short offcodeNCount[MaxOff+1];
2639
- unsigned offcodeMaxValue = MaxOff, offcodeLog = OffFSELog;
2640
- size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, dictEnd-dictPtr);
2641
- if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted);
2642
- { size_t const errorCode = FSE_buildCTable(cctx->offcodeCTable, offcodeNCount, offcodeMaxValue, offcodeLog);
2643
- if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted); }
2644
- dictPtr += offcodeHeaderSize;
2645
- }
2646
-
2647
- { short matchlengthNCount[MaxML+1];
2648
- unsigned matchlengthMaxValue = MaxML, matchlengthLog = MLFSELog;
2649
- size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, dictEnd-dictPtr);
2650
- if (FSE_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted);
2651
- { size_t const errorCode = FSE_buildCTable(cctx->matchlengthCTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog);
2652
- if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted); }
2653
- dictPtr += matchlengthHeaderSize;
2654
- }
2655
-
2656
- { short litlengthNCount[MaxLL+1];
2657
- unsigned litlengthMaxValue = MaxLL, litlengthLog = LLFSELog;
2658
- size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, dictEnd-dictPtr);
2659
- if (FSE_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted);
2660
- { size_t const errorCode = FSE_buildCTable(cctx->litlengthCTable, litlengthNCount, litlengthMaxValue, litlengthLog);
2661
- if (FSE_isError(errorCode)) return ERROR(dictionary_corrupted); }
2662
- dictPtr += litlengthHeaderSize;
2663
- }
2664
-
2665
- if (dictPtr+12 > dictEnd) return ERROR(dictionary_corrupted);
2666
- cctx->rep[0] = MEM_readLE32(dictPtr+0); if (cctx->rep[0] >= dictSize) return ERROR(dictionary_corrupted);
2667
- cctx->rep[1] = MEM_readLE32(dictPtr+4); if (cctx->rep[1] >= dictSize) return ERROR(dictionary_corrupted);
2668
- cctx->rep[2] = MEM_readLE32(dictPtr+8); if (cctx->rep[2] >= dictSize) return ERROR(dictionary_corrupted);
2669
- dictPtr += 12;
2670
-
2671
- cctx->flagStaticTables = 1;
2672
- return dictPtr - (const BYTE*)dict;
2673
- }
2674
-
2675
- /** ZSTD_compress_insertDictionary() :
2676
- * @return : 0, or an error code */
2677
- static size_t ZSTD_compress_insertDictionary(ZSTD_CCtx* zc, const void* dict, size_t dictSize)
2678
- {
2679
- if ((dict==NULL) || (dictSize<=8)) return 0;
2680
-
2681
- /* default : dict is pure content */
2682
- if (MEM_readLE32(dict) != ZSTD_DICT_MAGIC) return ZSTD_loadDictionaryContent(zc, dict, dictSize);
2683
- zc->dictID = zc->params.fParams.noDictIDFlag ? 0 : MEM_readLE32((const char*)dict+4);
2684
-
2685
- /* known magic number : dict is parsed for entropy stats and content */
2686
- { size_t const eSize = ZSTD_loadDictEntropyStats(zc, (const char*)dict+8 /* skip dictHeader */, dictSize-8) + 8;
2687
- if (ZSTD_isError(eSize)) return eSize;
2688
- return ZSTD_loadDictionaryContent(zc, (const char*)dict+eSize, dictSize-eSize);
2689
- }
2690
- }
2691
-
2692
-
2693
- /*! ZSTD_compressBegin_internal() :
2694
- * @return : 0, or an error code */
2695
- static size_t ZSTD_compressBegin_internal(ZSTD_CCtx* zc,
2696
- const void* dict, size_t dictSize,
2697
- ZSTD_parameters params, U64 pledgedSrcSize)
2698
- {
2699
- size_t const resetError = ZSTD_resetCCtx_advanced(zc, params, pledgedSrcSize, 1);
2700
- if (ZSTD_isError(resetError)) return resetError;
2701
-
2702
- return ZSTD_compress_insertDictionary(zc, dict, dictSize);
2703
- }
2704
-
2705
-
2706
- /*! ZSTD_compressBegin_advanced() :
2707
- * @return : 0, or an error code */
2708
- size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx,
2709
- const void* dict, size_t dictSize,
2710
- ZSTD_parameters params, unsigned long long pledgedSrcSize)
2711
- {
2712
- /* compression parameters verification and optimization */
2713
- { size_t const errorCode = ZSTD_checkCParams_advanced(params.cParams, pledgedSrcSize);
2714
- if (ZSTD_isError(errorCode)) return errorCode; }
2715
-
2716
- return ZSTD_compressBegin_internal(cctx, dict, dictSize, params, pledgedSrcSize);
2717
- }
2718
-
2719
-
2720
- size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel)
2721
- {
2722
- ZSTD_parameters const params = ZSTD_getParams(compressionLevel, 0, dictSize);
2723
- ZSTD_LOG_BLOCK("%p: ZSTD_compressBegin_usingDict compressionLevel=%d\n", cctx->base, compressionLevel);
2724
- return ZSTD_compressBegin_internal(cctx, dict, dictSize, params, 0);
2725
- }
2726
-
2727
-
2728
- size_t ZSTD_compressBegin(ZSTD_CCtx* zc, int compressionLevel)
2729
- {
2730
- ZSTD_LOG_BLOCK("%p: ZSTD_compressBegin compressionLevel=%d\n", zc->base, compressionLevel);
2731
- return ZSTD_compressBegin_usingDict(zc, NULL, 0, compressionLevel);
2732
- }
2733
-
2734
-
2735
- /*! ZSTD_compressEnd() :
2736
- * Write frame epilogue.
2737
- * @return : nb of bytes written into dst (or an error code) */
2738
- size_t ZSTD_compressEnd(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity)
2739
- {
2740
- BYTE* op = (BYTE*)dst;
2741
- size_t fhSize = 0;
2742
-
2743
- /* not even init ! */
2744
- if (cctx->stage==0) return ERROR(stage_wrong);
2745
-
2746
- /* special case : empty frame */
2747
- if (cctx->stage==1) {
2748
- fhSize = ZSTD_writeFrameHeader(dst, dstCapacity, cctx->params, 0, 0);
2749
- if (ZSTD_isError(fhSize)) return fhSize;
2750
- dstCapacity -= fhSize;
2751
- op += fhSize;
2752
- cctx->stage = 2;
2753
- }
2754
-
2755
- /* frame epilogue */
2756
- if (dstCapacity < 3) return ERROR(dstSize_tooSmall);
2757
- { U32 const checksum = cctx->params.fParams.checksumFlag ?
2758
- (U32)((XXH64_digest(&cctx->xxhState) >> 11) & ((1<<22)-1)) :
2759
- 0;
2760
- op[0] = (BYTE)((bt_end<<6) + (checksum>>16));
2761
- op[1] = (BYTE)(checksum>>8);
2762
- op[2] = (BYTE)checksum;
2763
- }
2764
-
2765
- cctx->stage = 0; /* return to "created but not init" status */
2766
- return 3+fhSize;
2767
- }
2768
-
2769
-
2770
- /*! ZSTD_compress_usingPreparedCCtx() :
2771
- * Same as ZSTD_compress_usingDict, but using a reference context `preparedCCtx`, where dictionary has been loaded.
2772
- * It avoids reloading the dictionary each time.
2773
- * `preparedCCtx` must have been properly initialized using ZSTD_compressBegin_usingDict() or ZSTD_compressBegin_advanced().
2774
- * Requires 2 contexts : 1 for reference (preparedCCtx) which will not be modified, and 1 to run the compression operation (cctx) */
2775
- static size_t ZSTD_compress_usingPreparedCCtx(ZSTD_CCtx* cctx, const ZSTD_CCtx* preparedCCtx,
2776
- void* dst, size_t dstCapacity,
2777
- const void* src, size_t srcSize)
2778
- {
2779
- { size_t const errorCode = ZSTD_copyCCtx(cctx, preparedCCtx);
2780
- if (ZSTD_isError(errorCode)) return errorCode;
2781
- }
2782
- { size_t const cSize = ZSTD_compressContinue(cctx, dst, dstCapacity, src, srcSize);
2783
- if (ZSTD_isError(cSize)) return cSize;
2784
-
2785
- { size_t const endSize = ZSTD_compressEnd(cctx, (char*)dst+cSize, dstCapacity-cSize);
2786
- if (ZSTD_isError(endSize)) return endSize;
2787
- return cSize + endSize;
2788
- } }
2789
- }
2790
-
2791
-
2792
- static size_t ZSTD_compress_internal (ZSTD_CCtx* ctx,
2793
- void* dst, size_t dstCapacity,
2794
- const void* src, size_t srcSize,
2795
- const void* dict,size_t dictSize,
2796
- ZSTD_parameters params)
2797
- {
2798
- BYTE* const ostart = (BYTE*)dst;
2799
- BYTE* op = ostart;
2800
-
2801
- /* Init */
2802
- { size_t const errorCode = ZSTD_compressBegin_internal(ctx, dict, dictSize, params, srcSize);
2803
- if(ZSTD_isError(errorCode)) return errorCode; }
2804
-
2805
- /* body (compression) */
2806
- { size_t const oSize = ZSTD_compressContinue (ctx, op, dstCapacity, src, srcSize);
2807
- if(ZSTD_isError(oSize)) return oSize;
2808
- op += oSize;
2809
- dstCapacity -= oSize; }
2810
-
2811
- /* Close frame */
2812
- { size_t const oSize = ZSTD_compressEnd(ctx, op, dstCapacity);
2813
- if(ZSTD_isError(oSize)) return oSize;
2814
- op += oSize; }
2815
-
2816
- return (op - ostart);
2817
- }
2818
-
2819
- size_t ZSTD_compress_advanced (ZSTD_CCtx* ctx,
2820
- void* dst, size_t dstCapacity,
2821
- const void* src, size_t srcSize,
2822
- const void* dict,size_t dictSize,
2823
- ZSTD_parameters params)
2824
- {
2825
- size_t const errorCode = ZSTD_checkCParams_advanced(params.cParams, srcSize);
2826
- if (ZSTD_isError(errorCode)) return errorCode;
2827
- return ZSTD_compress_internal(ctx, dst, dstCapacity, src, srcSize, dict, dictSize, params);
2828
- }
2829
-
2830
- size_t ZSTD_compress_usingDict(ZSTD_CCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize, const void* dict, size_t dictSize, int compressionLevel)
2831
- {
2832
- ZSTD_parameters params = ZSTD_getParams(compressionLevel, srcSize, dictSize);
2833
- params.fParams.contentSizeFlag = 1;
2834
- ZSTD_LOG_BLOCK("%p: ZSTD_compress_usingDict srcSize=%d dictSize=%d compressionLevel=%d\n", ctx->base, (int)srcSize, (int)dictSize, compressionLevel);
2835
- return ZSTD_compress_internal(ctx, dst, dstCapacity, src, srcSize, dict, dictSize, params);
2836
- }
2837
-
2838
- size_t ZSTD_compressCCtx (ZSTD_CCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize, int compressionLevel)
2839
- {
2840
- ZSTD_LOG_BLOCK("%p: ZSTD_compressCCtx srcSize=%d compressionLevel=%d\n", ctx->base, (int)srcSize, compressionLevel);
2841
- return ZSTD_compress_usingDict(ctx, dst, dstCapacity, src, srcSize, NULL, 0, compressionLevel);
2842
- }
2843
-
2844
- size_t ZSTD_compress(void* dst, size_t dstCapacity, const void* src, size_t srcSize, int compressionLevel)
2845
- {
2846
- size_t result;
2847
- ZSTD_CCtx ctxBody;
2848
- memset(&ctxBody, 0, sizeof(ctxBody));
2849
- memcpy(&ctxBody.customMem, &defaultCustomMem, sizeof(ZSTD_customMem));
2850
- result = ZSTD_compressCCtx(&ctxBody, dst, dstCapacity, src, srcSize, compressionLevel);
2851
- ctxBody.customMem.customFree(ctxBody.customMem.opaque, ctxBody.workSpace); /* can't free ctxBody, since it's on stack; just free heap content */
2852
- return result;
2853
- }
2854
-
2855
-
2856
- /* ===== Dictionary API ===== */
2857
-
2858
- struct ZSTD_CDict_s {
2859
- void* dictContent;
2860
- size_t dictContentSize;
2861
- ZSTD_CCtx* refContext;
2862
- }; /* typedef'd tp ZSTD_CDict within zstd.h */
2863
-
2864
- ZSTD_CDict* ZSTD_createCDict_advanced(const void* dict, size_t dictSize, ZSTD_parameters params, ZSTD_customMem customMem)
2865
- {
2866
- if (!customMem.customAlloc && !customMem.customFree)
2867
- customMem = defaultCustomMem;
2868
-
2869
- if (!customMem.customAlloc || !customMem.customFree) /* can't have 1/2 custom alloc/free as NULL */
2870
- return NULL;
2871
-
2872
- { ZSTD_CDict* const cdict = (ZSTD_CDict*) customMem.customAlloc(customMem.opaque, sizeof(*cdict));
2873
- void* const dictContent = customMem.customAlloc(customMem.opaque, dictSize);
2874
- ZSTD_CCtx* const cctx = ZSTD_createCCtx_advanced(customMem);
2875
-
2876
- if (!dictContent || !cdict || !cctx) {
2877
- customMem.customFree(customMem.opaque, dictContent);
2878
- customMem.customFree(customMem.opaque, cdict);
2879
- customMem.customFree(customMem.opaque, cctx);
2880
- return NULL;
2881
- }
2882
-
2883
- memcpy(dictContent, dict, dictSize);
2884
- { size_t const errorCode = ZSTD_compressBegin_advanced(cctx, dictContent, dictSize, params, 0);
2885
- if (ZSTD_isError(errorCode)) {
2886
- customMem.customFree(customMem.opaque, dictContent);
2887
- customMem.customFree(customMem.opaque, cdict);
2888
- customMem.customFree(customMem.opaque, cctx);
2889
- return NULL;
2890
- } }
2891
-
2892
- cdict->dictContent = dictContent;
2893
- cdict->dictContentSize = dictSize;
2894
- cdict->refContext = cctx;
2895
- return cdict;
2896
- }
2897
- }
2898
-
2899
- ZSTD_CDict* ZSTD_createCDict(const void* dict, size_t dictSize, int compressionLevel)
2900
- {
2901
- ZSTD_customMem const allocator = { NULL, NULL, NULL };
2902
- ZSTD_parameters params;
2903
- memset(&params, 0, sizeof(params));
2904
- params.cParams = ZSTD_getCParams(compressionLevel, 0, dictSize);
2905
- params.fParams.contentSizeFlag = 1;
2906
- return ZSTD_createCDict_advanced(dict, dictSize, params, allocator);
2907
- }
2908
-
2909
- size_t ZSTD_freeCDict(ZSTD_CDict* cdict)
2910
- {
2911
- ZSTD_freeFunction const cFree = cdict->refContext->customMem.customFree;
2912
- void* const opaque = cdict->refContext->customMem.opaque;
2913
- ZSTD_freeCCtx(cdict->refContext);
2914
- cFree(opaque, cdict->dictContent);
2915
- cFree(opaque, cdict);
2916
- return 0;
2917
- }
2918
-
2919
- ZSTDLIB_API size_t ZSTD_compress_usingCDict(ZSTD_CCtx* cctx,
2920
- void* dst, size_t dstCapacity,
2921
- const void* src, size_t srcSize,
2922
- const ZSTD_CDict* cdict)
2923
- {
2924
- return ZSTD_compress_usingPreparedCCtx(cctx, cdict->refContext,
2925
- dst, dstCapacity,
2926
- src, srcSize);
2927
- }
2928
-
2929
-
2930
-
2931
- /*-===== Pre-defined compression levels =====-*/
2932
-
2933
- #define ZSTD_DEFAULT_CLEVEL 1
2934
- #define ZSTD_MAX_CLEVEL 22
2935
- unsigned ZSTD_maxCLevel(void) { return ZSTD_MAX_CLEVEL; }
2936
-
2937
- static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEVEL+1] = {
2938
- { /* "default" */
2939
- /* W, C, H, S, L, TL, strat */
2940
- { 18, 12, 12, 1, 7, 16, ZSTD_fast }, /* level 0 - not used */
2941
- { 19, 13, 14, 1, 7, 16, ZSTD_fast }, /* level 1 */
2942
- { 19, 15, 16, 1, 6, 16, ZSTD_fast }, /* level 2 */
2943
- { 20, 16, 18, 1, 5, 16, ZSTD_dfast }, /* level 3 */
2944
- { 20, 13, 17, 2, 5, 16, ZSTD_greedy }, /* level 4.*/
2945
- { 20, 15, 18, 3, 5, 16, ZSTD_greedy }, /* level 5 */
2946
- { 21, 16, 19, 2, 5, 16, ZSTD_lazy }, /* level 6 */
2947
- { 21, 17, 20, 3, 5, 16, ZSTD_lazy }, /* level 7 */
2948
- { 21, 18, 20, 3, 5, 16, ZSTD_lazy2 }, /* level 8.*/
2949
- { 21, 20, 20, 3, 5, 16, ZSTD_lazy2 }, /* level 9 */
2950
- { 21, 19, 21, 4, 5, 16, ZSTD_lazy2 }, /* level 10 */
2951
- { 22, 20, 22, 4, 5, 16, ZSTD_lazy2 }, /* level 11 */
2952
- { 22, 20, 22, 5, 5, 16, ZSTD_lazy2 }, /* level 12 */
2953
- { 22, 21, 22, 5, 5, 16, ZSTD_lazy2 }, /* level 13 */
2954
- { 22, 21, 22, 6, 5, 16, ZSTD_lazy2 }, /* level 14 */
2955
- { 22, 21, 21, 5, 5, 16, ZSTD_btlazy2 }, /* level 15 */
2956
- { 23, 22, 22, 5, 5, 16, ZSTD_btlazy2 }, /* level 16 */
2957
- { 23, 23, 22, 5, 5, 16, ZSTD_btlazy2 }, /* level 17.*/
2958
- { 23, 23, 22, 6, 5, 24, ZSTD_btopt }, /* level 18.*/
2959
- { 23, 23, 22, 6, 3, 48, ZSTD_btopt }, /* level 19.*/
2960
- { 25, 26, 23, 7, 3, 64, ZSTD_btopt }, /* level 20.*/
2961
- { 26, 26, 23, 7, 3,256, ZSTD_btopt }, /* level 21.*/
2962
- { 27, 27, 25, 9, 3,512, ZSTD_btopt }, /* level 22.*/
2963
- },
2964
- { /* for srcSize <= 256 KB */
2965
- /* W, C, H, S, L, T, strat */
2966
- { 18, 12, 12, 1, 7, 4, ZSTD_fast }, /* level 0 - not used */
2967
- { 18, 13, 14, 1, 6, 4, ZSTD_fast }, /* level 1 */
2968
- { 18, 15, 17, 1, 5, 4, ZSTD_fast }, /* level 2 */
2969
- { 18, 13, 15, 1, 5, 4, ZSTD_greedy }, /* level 3.*/
2970
- { 18, 15, 17, 1, 5, 4, ZSTD_greedy }, /* level 4.*/
2971
- { 18, 16, 17, 4, 5, 4, ZSTD_greedy }, /* level 5 */
2972
- { 18, 17, 17, 5, 5, 4, ZSTD_greedy }, /* level 6 */
2973
- { 18, 17, 17, 4, 4, 4, ZSTD_lazy }, /* level 7 */
2974
- { 18, 17, 17, 4, 4, 4, ZSTD_lazy2 }, /* level 8 */
2975
- { 18, 17, 17, 5, 4, 4, ZSTD_lazy2 }, /* level 9 */
2976
- { 18, 17, 17, 6, 4, 4, ZSTD_lazy2 }, /* level 10 */
2977
- { 18, 18, 17, 6, 4, 4, ZSTD_lazy2 }, /* level 11.*/
2978
- { 18, 18, 17, 7, 4, 4, ZSTD_lazy2 }, /* level 12.*/
2979
- { 18, 19, 17, 7, 4, 4, ZSTD_btlazy2 }, /* level 13 */
2980
- { 18, 18, 18, 4, 4, 16, ZSTD_btopt }, /* level 14.*/
2981
- { 18, 18, 18, 8, 4, 24, ZSTD_btopt }, /* level 15.*/
2982
- { 18, 19, 18, 8, 3, 48, ZSTD_btopt }, /* level 16.*/
2983
- { 18, 19, 18, 8, 3, 96, ZSTD_btopt }, /* level 17.*/
2984
- { 18, 19, 18, 9, 3,128, ZSTD_btopt }, /* level 18.*/
2985
- { 18, 19, 18, 10, 3,256, ZSTD_btopt }, /* level 19.*/
2986
- { 18, 19, 18, 11, 3,512, ZSTD_btopt }, /* level 20.*/
2987
- { 18, 19, 18, 12, 3,512, ZSTD_btopt }, /* level 21.*/
2988
- { 18, 19, 18, 13, 3,512, ZSTD_btopt }, /* level 22.*/
2989
- },
2990
- { /* for srcSize <= 128 KB */
2991
- /* W, C, H, S, L, T, strat */
2992
- { 17, 12, 12, 1, 7, 4, ZSTD_fast }, /* level 0 - not used */
2993
- { 17, 12, 13, 1, 6, 4, ZSTD_fast }, /* level 1 */
2994
- { 17, 13, 16, 1, 5, 4, ZSTD_fast }, /* level 2 */
2995
- { 17, 13, 14, 2, 5, 4, ZSTD_greedy }, /* level 3 */
2996
- { 17, 13, 15, 3, 4, 4, ZSTD_greedy }, /* level 4 */
2997
- { 17, 15, 17, 4, 4, 4, ZSTD_greedy }, /* level 5 */
2998
- { 17, 16, 17, 3, 4, 4, ZSTD_lazy }, /* level 6 */
2999
- { 17, 15, 17, 4, 4, 4, ZSTD_lazy2 }, /* level 7 */
3000
- { 17, 17, 17, 4, 4, 4, ZSTD_lazy2 }, /* level 8 */
3001
- { 17, 17, 17, 5, 4, 4, ZSTD_lazy2 }, /* level 9 */
3002
- { 17, 17, 17, 6, 4, 4, ZSTD_lazy2 }, /* level 10 */
3003
- { 17, 17, 17, 7, 4, 4, ZSTD_lazy2 }, /* level 11 */
3004
- { 17, 17, 17, 8, 4, 4, ZSTD_lazy2 }, /* level 12 */
3005
- { 17, 18, 17, 6, 4, 4, ZSTD_btlazy2 }, /* level 13.*/
3006
- { 17, 17, 17, 7, 3, 8, ZSTD_btopt }, /* level 14.*/
3007
- { 17, 17, 17, 7, 3, 16, ZSTD_btopt }, /* level 15.*/
3008
- { 17, 18, 17, 7, 3, 32, ZSTD_btopt }, /* level 16.*/
3009
- { 17, 18, 17, 7, 3, 64, ZSTD_btopt }, /* level 17.*/
3010
- { 17, 18, 17, 7, 3,256, ZSTD_btopt }, /* level 18.*/
3011
- { 17, 18, 17, 8, 3,256, ZSTD_btopt }, /* level 19.*/
3012
- { 17, 18, 17, 9, 3,256, ZSTD_btopt }, /* level 20.*/
3013
- { 17, 18, 17, 10, 3,256, ZSTD_btopt }, /* level 21.*/
3014
- { 17, 18, 17, 11, 3,256, ZSTD_btopt }, /* level 22.*/
3015
- },
3016
- { /* for srcSize <= 16 KB */
3017
- /* W, C, H, S, L, T, strat */
3018
- { 14, 12, 12, 1, 7, 6, ZSTD_fast }, /* level 0 - not used */
3019
- { 14, 14, 14, 1, 7, 6, ZSTD_fast }, /* level 1 */
3020
- { 14, 14, 14, 1, 4, 6, ZSTD_fast }, /* level 2 */
3021
- { 14, 14, 14, 1, 4, 6, ZSTD_dfast }, /* level 3.*/
3022
- { 14, 14, 14, 4, 4, 6, ZSTD_greedy }, /* level 4.*/
3023
- { 14, 14, 14, 3, 4, 6, ZSTD_lazy }, /* level 5.*/
3024
- { 14, 14, 14, 4, 4, 6, ZSTD_lazy2 }, /* level 6 */
3025
- { 14, 14, 14, 5, 4, 6, ZSTD_lazy2 }, /* level 7 */
3026
- { 14, 14, 14, 6, 4, 6, ZSTD_lazy2 }, /* level 8.*/
3027
- { 14, 15, 14, 6, 4, 6, ZSTD_btlazy2 }, /* level 9.*/
3028
- { 14, 15, 14, 3, 3, 6, ZSTD_btopt }, /* level 10.*/
3029
- { 14, 15, 14, 6, 3, 8, ZSTD_btopt }, /* level 11.*/
3030
- { 14, 15, 14, 6, 3, 16, ZSTD_btopt }, /* level 12.*/
3031
- { 14, 15, 14, 6, 3, 24, ZSTD_btopt }, /* level 13.*/
3032
- { 14, 15, 15, 6, 3, 48, ZSTD_btopt }, /* level 14.*/
3033
- { 14, 15, 15, 6, 3, 64, ZSTD_btopt }, /* level 15.*/
3034
- { 14, 15, 15, 6, 3, 96, ZSTD_btopt }, /* level 16.*/
3035
- { 14, 15, 15, 6, 3,128, ZSTD_btopt }, /* level 17.*/
3036
- { 14, 15, 15, 6, 3,256, ZSTD_btopt }, /* level 18.*/
3037
- { 14, 15, 15, 7, 3,256, ZSTD_btopt }, /* level 19.*/
3038
- { 14, 15, 15, 8, 3,256, ZSTD_btopt }, /* level 20.*/
3039
- { 14, 15, 15, 9, 3,256, ZSTD_btopt }, /* level 21.*/
3040
- { 14, 15, 15, 10, 3,256, ZSTD_btopt }, /* level 22.*/
3041
- },
3042
- };
3043
-
3044
- /*! ZSTD_getCParams() :
3045
- * @return ZSTD_compressionParameters structure for a selected compression level, `srcSize` and `dictSize`.
3046
- * Size values are optional, provide 0 if not known or unused */
3047
- ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long long srcSize, size_t dictSize)
3048
- {
3049
- ZSTD_compressionParameters cp;
3050
- size_t const addedSize = srcSize ? 0 : 500;
3051
- U64 const rSize = srcSize+dictSize ? srcSize+dictSize+addedSize : (U64)-1;
3052
- U32 const tableID = (rSize <= 256 KB) + (rSize <= 128 KB) + (rSize <= 16 KB); /* intentional underflow for srcSizeHint == 0 */
3053
- if (compressionLevel <= 0) compressionLevel = ZSTD_DEFAULT_CLEVEL; /* 0 == default; no negative compressionLevel yet */
3054
- if (compressionLevel > ZSTD_MAX_CLEVEL) compressionLevel = ZSTD_MAX_CLEVEL;
3055
- cp = ZSTD_defaultCParameters[tableID][compressionLevel];
3056
- if (MEM_32bits()) { /* auto-correction, for 32-bits mode */
3057
- if (cp.windowLog > ZSTD_WINDOWLOG_MAX) cp.windowLog = ZSTD_WINDOWLOG_MAX;
3058
- if (cp.chainLog > ZSTD_CHAINLOG_MAX) cp.chainLog = ZSTD_CHAINLOG_MAX;
3059
- if (cp.hashLog > ZSTD_HASHLOG_MAX) cp.hashLog = ZSTD_HASHLOG_MAX;
3060
- }
3061
- cp = ZSTD_adjustCParams(cp, srcSize, dictSize);
3062
- return cp;
3063
- }
3064
-
3065
- /*! ZSTD_getParams() :
3066
- * same as ZSTD_getCParams(), but @return a `ZSTD_parameters` object (instead of `ZSTD_compressionParameters`).
3067
- * All fields of `ZSTD_frameParameters` are set to default (0) */
3068
- ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long srcSize, size_t dictSize) {
3069
- ZSTD_parameters params;
3070
- ZSTD_compressionParameters const cParams = ZSTD_getCParams(compressionLevel, srcSize, dictSize);
3071
- memset(&params, 0, sizeof(params));
3072
- params.cParams = cParams;
3073
- return params;
3074
- }