authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-11-15 20:21:50-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-12-06 12:15:04-07:00
logd1b3409df1804ff3182596ca41e2e2424c0918e7
tree906214ea90105f87d10695750f9c89af08121fcd
parent39fd77bc163f0d7fc7408cbb4e48f960b4739448

add zstd v1.5.2

only the decompression files

34 files changed, 21147 insertions(+), 0 deletions(-)

stage1/zstd/LICENSE created+30
......@@ -0,0 +1,30 @@
1BSD License
2
3For Zstandard software
4
5Copyright (c) 2016-present, Facebook, Inc. All rights reserved.
6
7Redistribution and use in source and binary forms, with or without modification,
8are permitted provided that the following conditions are met:
9
10 * Redistributions of source code must retain the above copyright notice, this
11 list of conditions and the following disclaimer.
12
13 * Redistributions in binary form must reproduce the above copyright notice,
14 this list of conditions and the following disclaimer in the documentation
15 and/or other materials provided with the distribution.
16
17 * Neither the name Facebook nor the names of its contributors may be used to
18 endorse or promote products derived from this software without specific
19 prior written permission.
20
21THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
22ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
25ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
28ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
stage1/zstd/lib/common/bitstream.h created+478
......@@ -0,0 +1,478 @@
1/* ******************************************************************
2 * bitstream
3 * Part of FSE library
4 * Copyright (c) Yann Collet, Facebook, Inc.
5 *
6 * You can contact the author at :
7 * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
8 *
9 * This source code is licensed under both the BSD-style license (found in the
10 * LICENSE file in the root directory of this source tree) and the GPLv2 (found
11 * in the COPYING file in the root directory of this source tree).
12 * You may select, at your option, one of the above-listed licenses.
13****************************************************************** */
14#ifndef BITSTREAM_H_MODULE
15#define BITSTREAM_H_MODULE
16
17#if defined (__cplusplus)
18extern "C" {
19#endif
20/*
21* This API consists of small unitary functions, which must be inlined for best performance.
22* Since link-time-optimization is not available for all compilers,
23* these functions are defined into a .h to be included.
24*/
25
26/*-****************************************
27* Dependencies
28******************************************/
29#include "mem.h" /* unaligned access routines */
30#include "compiler.h" /* UNLIKELY() */
31#include "debug.h" /* assert(), DEBUGLOG(), RAWLOG() */
32#include "error_private.h" /* error codes and messages */
33
34
35/*=========================================
36* Target specific
37=========================================*/
38#ifndef ZSTD_NO_INTRINSICS
39# if defined(__BMI__) && defined(__GNUC__)
40# include <immintrin.h> /* support for bextr (experimental) */
41# elif defined(__ICCARM__)
42# include <intrinsics.h>
43# endif
44#endif
45
46#define STREAM_ACCUMULATOR_MIN_32 25
47#define STREAM_ACCUMULATOR_MIN_64 57
48#define STREAM_ACCUMULATOR_MIN ((U32)(MEM_32bits() ? STREAM_ACCUMULATOR_MIN_32 : STREAM_ACCUMULATOR_MIN_64))
49
50
51/*-******************************************
52* bitStream encoding API (write forward)
53********************************************/
54/* bitStream can mix input from multiple sources.
55 * A critical property of these streams is that they encode and decode in **reverse** direction.
56 * So the first bit sequence you add will be the last to be read, like a LIFO stack.
57 */
58typedef struct {
59 size_t bitContainer;
60 unsigned bitPos;
61 char* startPtr;
62 char* ptr;
63 char* endPtr;
64} BIT_CStream_t;
65
66MEM_STATIC size_t BIT_initCStream(BIT_CStream_t* bitC, void* dstBuffer, size_t dstCapacity);
67MEM_STATIC void BIT_addBits(BIT_CStream_t* bitC, size_t value, unsigned nbBits);
68MEM_STATIC void BIT_flushBits(BIT_CStream_t* bitC);
69MEM_STATIC size_t BIT_closeCStream(BIT_CStream_t* bitC);
70
71/* Start with initCStream, providing the size of buffer to write into.
72* bitStream will never write outside of this buffer.
73* `dstCapacity` must be >= sizeof(bitD->bitContainer), otherwise @return will be an error code.
74*
75* bits are first added to a local register.
76* Local register is size_t, hence 64-bits on 64-bits systems, or 32-bits on 32-bits systems.
77* Writing data into memory is an explicit operation, performed by the flushBits function.
78* Hence keep track how many bits are potentially stored into local register to avoid register overflow.
79* After a flushBits, a maximum of 7 bits might still be stored into local register.
80*
81* Avoid storing elements of more than 24 bits if you want compatibility with 32-bits bitstream readers.
82*
83* Last operation is to close the bitStream.
84* The function returns the final size of CStream in bytes.
85* If data couldn't fit into `dstBuffer`, it will return a 0 ( == not storable)
86*/
87
88
89/*-********************************************
90* bitStream decoding API (read backward)
91**********************************************/
92typedef struct {
93 size_t bitContainer;
94 unsigned bitsConsumed;
95 const char* ptr;
96 const char* start;
97 const char* limitPtr;
98} BIT_DStream_t;
99
100typedef enum { BIT_DStream_unfinished = 0,
101 BIT_DStream_endOfBuffer = 1,
102 BIT_DStream_completed = 2,
103 BIT_DStream_overflow = 3 } BIT_DStream_status; /* result of BIT_reloadDStream() */
104 /* 1,2,4,8 would be better for bitmap combinations, but slows down performance a bit ... :( */
105
106MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, size_t srcSize);
107MEM_STATIC size_t BIT_readBits(BIT_DStream_t* bitD, unsigned nbBits);
108MEM_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD);
109MEM_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t* bitD);
110
111
112/* Start by invoking BIT_initDStream().
113* A chunk of the bitStream is then stored into a local register.
114* Local register size is 64-bits on 64-bits systems, 32-bits on 32-bits systems (size_t).
115* You can then retrieve bitFields stored into the local register, **in reverse order**.
116* Local register is explicitly reloaded from memory by the BIT_reloadDStream() method.
117* A reload guarantee a minimum of ((8*sizeof(bitD->bitContainer))-7) bits when its result is BIT_DStream_unfinished.
118* Otherwise, it can be less than that, so proceed accordingly.
119* Checking if DStream has reached its end can be performed with BIT_endOfDStream().
120*/
121
122
123/*-****************************************
124* unsafe API
125******************************************/
126MEM_STATIC void BIT_addBitsFast(BIT_CStream_t* bitC, size_t value, unsigned nbBits);
127/* faster, but works only if value is "clean", meaning all high bits above nbBits are 0 */
128
129MEM_STATIC void BIT_flushBitsFast(BIT_CStream_t* bitC);
130/* unsafe version; does not check buffer overflow */
131
132MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, unsigned nbBits);
133/* faster, but works only if nbBits >= 1 */
134
135
136
137/*-**************************************************************
138* Internal functions
139****************************************************************/
140MEM_STATIC unsigned BIT_highbit32 (U32 val)
141{
142 assert(val != 0);
143 {
144# if defined(_MSC_VER) /* Visual */
145# if STATIC_BMI2 == 1
146 return _lzcnt_u32(val) ^ 31;
147# else
148 if (val != 0) {
149 unsigned long r;
150 _BitScanReverse(&r, val);
151 return (unsigned)r;
152 } else {
153 /* Should not reach this code path */
154 __assume(0);
155 }
156# endif
157# elif defined(__GNUC__) && (__GNUC__ >= 3) /* Use GCC Intrinsic */
158 return __builtin_clz (val) ^ 31;
159# elif defined(__ICCARM__) /* IAR Intrinsic */
160 return 31 - __CLZ(val);
161# else /* Software version */
162 static const unsigned DeBruijnClz[32] = { 0, 9, 1, 10, 13, 21, 2, 29,
163 11, 14, 16, 18, 22, 25, 3, 30,
164 8, 12, 20, 28, 15, 17, 24, 7,
165 19, 27, 23, 6, 26, 5, 4, 31 };
166 U32 v = val;
167 v |= v >> 1;
168 v |= v >> 2;
169 v |= v >> 4;
170 v |= v >> 8;
171 v |= v >> 16;
172 return DeBruijnClz[ (U32) (v * 0x07C4ACDDU) >> 27];
173# endif
174 }
175}
176
177/*===== Local Constants =====*/
178static const unsigned BIT_mask[] = {
179 0, 1, 3, 7, 0xF, 0x1F,
180 0x3F, 0x7F, 0xFF, 0x1FF, 0x3FF, 0x7FF,
181 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF, 0x1FFFF,
182 0x3FFFF, 0x7FFFF, 0xFFFFF, 0x1FFFFF, 0x3FFFFF, 0x7FFFFF,
183 0xFFFFFF, 0x1FFFFFF, 0x3FFFFFF, 0x7FFFFFF, 0xFFFFFFF, 0x1FFFFFFF,
184 0x3FFFFFFF, 0x7FFFFFFF}; /* up to 31 bits */
185#define BIT_MASK_SIZE (sizeof(BIT_mask) / sizeof(BIT_mask[0]))
186
187/*-**************************************************************
188* bitStream encoding
189****************************************************************/
190/*! BIT_initCStream() :
191 * `dstCapacity` must be > sizeof(size_t)
192 * @return : 0 if success,
193 * otherwise an error code (can be tested using ERR_isError()) */
194MEM_STATIC size_t BIT_initCStream(BIT_CStream_t* bitC,
195 void* startPtr, size_t dstCapacity)
196{
197 bitC->bitContainer = 0;
198 bitC->bitPos = 0;
199 bitC->startPtr = (char*)startPtr;
200 bitC->ptr = bitC->startPtr;
201 bitC->endPtr = bitC->startPtr + dstCapacity - sizeof(bitC->bitContainer);
202 if (dstCapacity <= sizeof(bitC->bitContainer)) return ERROR(dstSize_tooSmall);
203 return 0;
204}
205
206/*! BIT_addBits() :
207 * can add up to 31 bits into `bitC`.
208 * Note : does not check for register overflow ! */
209MEM_STATIC void BIT_addBits(BIT_CStream_t* bitC,
210 size_t value, unsigned nbBits)
211{
212 DEBUG_STATIC_ASSERT(BIT_MASK_SIZE == 32);
213 assert(nbBits < BIT_MASK_SIZE);
214 assert(nbBits + bitC->bitPos < sizeof(bitC->bitContainer) * 8);
215 bitC->bitContainer |= (value & BIT_mask[nbBits]) << bitC->bitPos;
216 bitC->bitPos += nbBits;
217}
218
219/*! BIT_addBitsFast() :
220 * works only if `value` is _clean_,
221 * meaning all high bits above nbBits are 0 */
222MEM_STATIC void BIT_addBitsFast(BIT_CStream_t* bitC,
223 size_t value, unsigned nbBits)
224{
225 assert((value>>nbBits) == 0);
226 assert(nbBits + bitC->bitPos < sizeof(bitC->bitContainer) * 8);
227 bitC->bitContainer |= value << bitC->bitPos;
228 bitC->bitPos += nbBits;
229}
230
231/*! BIT_flushBitsFast() :
232 * assumption : bitContainer has not overflowed
233 * unsafe version; does not check buffer overflow */
234MEM_STATIC void BIT_flushBitsFast(BIT_CStream_t* bitC)
235{
236 size_t const nbBytes = bitC->bitPos >> 3;
237 assert(bitC->bitPos < sizeof(bitC->bitContainer) * 8);
238 assert(bitC->ptr <= bitC->endPtr);
239 MEM_writeLEST(bitC->ptr, bitC->bitContainer);
240 bitC->ptr += nbBytes;
241 bitC->bitPos &= 7;
242 bitC->bitContainer >>= nbBytes*8;
243}
244
245/*! BIT_flushBits() :
246 * assumption : bitContainer has not overflowed
247 * safe version; check for buffer overflow, and prevents it.
248 * note : does not signal buffer overflow.
249 * overflow will be revealed later on using BIT_closeCStream() */
250MEM_STATIC void BIT_flushBits(BIT_CStream_t* bitC)
251{
252 size_t const nbBytes = bitC->bitPos >> 3;
253 assert(bitC->bitPos < sizeof(bitC->bitContainer) * 8);
254 assert(bitC->ptr <= bitC->endPtr);
255 MEM_writeLEST(bitC->ptr, bitC->bitContainer);
256 bitC->ptr += nbBytes;
257 if (bitC->ptr > bitC->endPtr) bitC->ptr = bitC->endPtr;
258 bitC->bitPos &= 7;
259 bitC->bitContainer >>= nbBytes*8;
260}
261
262/*! BIT_closeCStream() :
263 * @return : size of CStream, in bytes,
264 * or 0 if it could not fit into dstBuffer */
265MEM_STATIC size_t BIT_closeCStream(BIT_CStream_t* bitC)
266{
267 BIT_addBitsFast(bitC, 1, 1); /* endMark */
268 BIT_flushBits(bitC);
269 if (bitC->ptr >= bitC->endPtr) return 0; /* overflow detected */
270 return (bitC->ptr - bitC->startPtr) + (bitC->bitPos > 0);
271}
272
273
274/*-********************************************************
275* bitStream decoding
276**********************************************************/
277/*! BIT_initDStream() :
278 * Initialize a BIT_DStream_t.
279 * `bitD` : a pointer to an already allocated BIT_DStream_t structure.
280 * `srcSize` must be the *exact* size of the bitStream, in bytes.
281 * @return : size of stream (== srcSize), or an errorCode if a problem is detected
282 */
283MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, size_t srcSize)
284{
285 if (srcSize < 1) { ZSTD_memset(bitD, 0, sizeof(*bitD)); return ERROR(srcSize_wrong); }
286
287 bitD->start = (const char*)srcBuffer;
288 bitD->limitPtr = bitD->start + sizeof(bitD->bitContainer);
289
290 if (srcSize >= sizeof(bitD->bitContainer)) { /* normal case */
291 bitD->ptr = (const char*)srcBuffer + srcSize - sizeof(bitD->bitContainer);
292 bitD->bitContainer = MEM_readLEST(bitD->ptr);
293 { BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1];
294 bitD->bitsConsumed = lastByte ? 8 - BIT_highbit32(lastByte) : 0; /* ensures bitsConsumed is always set */
295 if (lastByte == 0) return ERROR(GENERIC); /* endMark not present */ }
296 } else {
297 bitD->ptr = bitD->start;
298 bitD->bitContainer = *(const BYTE*)(bitD->start);
299 switch(srcSize)
300 {
301 case 7: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[6]) << (sizeof(bitD->bitContainer)*8 - 16);
302 ZSTD_FALLTHROUGH;
303
304 case 6: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[5]) << (sizeof(bitD->bitContainer)*8 - 24);
305 ZSTD_FALLTHROUGH;
306
307 case 5: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[4]) << (sizeof(bitD->bitContainer)*8 - 32);
308 ZSTD_FALLTHROUGH;
309
310 case 4: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[3]) << 24;
311 ZSTD_FALLTHROUGH;
312
313 case 3: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[2]) << 16;
314 ZSTD_FALLTHROUGH;
315
316 case 2: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[1]) << 8;
317 ZSTD_FALLTHROUGH;
318
319 default: break;
320 }
321 { BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1];
322 bitD->bitsConsumed = lastByte ? 8 - BIT_highbit32(lastByte) : 0;
323 if (lastByte == 0) return ERROR(corruption_detected); /* endMark not present */
324 }
325 bitD->bitsConsumed += (U32)(sizeof(bitD->bitContainer) - srcSize)*8;
326 }
327
328 return srcSize;
329}
330
331MEM_STATIC FORCE_INLINE_ATTR size_t BIT_getUpperBits(size_t bitContainer, U32 const start)
332{
333 return bitContainer >> start;
334}
335
336MEM_STATIC FORCE_INLINE_ATTR size_t BIT_getMiddleBits(size_t bitContainer, U32 const start, U32 const nbBits)
337{
338 U32 const regMask = sizeof(bitContainer)*8 - 1;
339 /* if start > regMask, bitstream is corrupted, and result is undefined */
340 assert(nbBits < BIT_MASK_SIZE);
341 /* x86 transform & ((1 << nbBits) - 1) to bzhi instruction, it is better
342 * than accessing memory. When bmi2 instruction is not present, we consider
343 * such cpus old (pre-Haswell, 2013) and their performance is not of that
344 * importance.
345 */
346#if defined(__x86_64__) || defined(_M_X86)
347 return (bitContainer >> (start & regMask)) & ((((U64)1) << nbBits) - 1);
348#else
349 return (bitContainer >> (start & regMask)) & BIT_mask[nbBits];
350#endif
351}
352
353MEM_STATIC FORCE_INLINE_ATTR size_t BIT_getLowerBits(size_t bitContainer, U32 const nbBits)
354{
355#if defined(STATIC_BMI2) && STATIC_BMI2 == 1
356 return _bzhi_u64(bitContainer, nbBits);
357#else
358 assert(nbBits < BIT_MASK_SIZE);
359 return bitContainer & BIT_mask[nbBits];
360#endif
361}
362
363/*! BIT_lookBits() :
364 * Provides next n bits from local register.
365 * local register is not modified.
366 * On 32-bits, maxNbBits==24.
367 * On 64-bits, maxNbBits==56.
368 * @return : value extracted */
369MEM_STATIC FORCE_INLINE_ATTR size_t BIT_lookBits(const BIT_DStream_t* bitD, U32 nbBits)
370{
371 /* arbitrate between double-shift and shift+mask */
372#if 1
373 /* if bitD->bitsConsumed + nbBits > sizeof(bitD->bitContainer)*8,
374 * bitstream is likely corrupted, and result is undefined */
375 return BIT_getMiddleBits(bitD->bitContainer, (sizeof(bitD->bitContainer)*8) - bitD->bitsConsumed - nbBits, nbBits);
376#else
377 /* this code path is slower on my os-x laptop */
378 U32 const regMask = sizeof(bitD->bitContainer)*8 - 1;
379 return ((bitD->bitContainer << (bitD->bitsConsumed & regMask)) >> 1) >> ((regMask-nbBits) & regMask);
380#endif
381}
382
383/*! BIT_lookBitsFast() :
384 * unsafe version; only works if nbBits >= 1 */
385MEM_STATIC size_t BIT_lookBitsFast(const BIT_DStream_t* bitD, U32 nbBits)
386{
387 U32 const regMask = sizeof(bitD->bitContainer)*8 - 1;
388 assert(nbBits >= 1);
389 return (bitD->bitContainer << (bitD->bitsConsumed & regMask)) >> (((regMask+1)-nbBits) & regMask);
390}
391
392MEM_STATIC FORCE_INLINE_ATTR void BIT_skipBits(BIT_DStream_t* bitD, U32 nbBits)
393{
394 bitD->bitsConsumed += nbBits;
395}
396
397/*! BIT_readBits() :
398 * Read (consume) next n bits from local register and update.
399 * Pay attention to not read more than nbBits contained into local register.
400 * @return : extracted value. */
401MEM_STATIC FORCE_INLINE_ATTR size_t BIT_readBits(BIT_DStream_t* bitD, unsigned nbBits)
402{
403 size_t const value = BIT_lookBits(bitD, nbBits);
404 BIT_skipBits(bitD, nbBits);
405 return value;
406}
407
408/*! BIT_readBitsFast() :
409 * unsafe version; only works only if nbBits >= 1 */
410MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, unsigned nbBits)
411{
412 size_t const value = BIT_lookBitsFast(bitD, nbBits);
413 assert(nbBits >= 1);
414 BIT_skipBits(bitD, nbBits);
415 return value;
416}
417
418/*! BIT_reloadDStreamFast() :
419 * Similar to BIT_reloadDStream(), but with two differences:
420 * 1. bitsConsumed <= sizeof(bitD->bitContainer)*8 must hold!
421 * 2. Returns BIT_DStream_overflow when bitD->ptr < bitD->limitPtr, at this
422 * point you must use BIT_reloadDStream() to reload.
423 */
424MEM_STATIC BIT_DStream_status BIT_reloadDStreamFast(BIT_DStream_t* bitD)
425{
426 if (UNLIKELY(bitD->ptr < bitD->limitPtr))
427 return BIT_DStream_overflow;
428 assert(bitD->bitsConsumed <= sizeof(bitD->bitContainer)*8);
429 bitD->ptr -= bitD->bitsConsumed >> 3;
430 bitD->bitsConsumed &= 7;
431 bitD->bitContainer = MEM_readLEST(bitD->ptr);
432 return BIT_DStream_unfinished;
433}
434
435/*! BIT_reloadDStream() :
436 * Refill `bitD` from buffer previously set in BIT_initDStream() .
437 * This function is safe, it guarantees it will not read beyond src buffer.
438 * @return : status of `BIT_DStream_t` internal register.
439 * when status == BIT_DStream_unfinished, internal register is filled with at least 25 or 57 bits */
440MEM_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD)
441{
442 if (bitD->bitsConsumed > (sizeof(bitD->bitContainer)*8)) /* overflow detected, like end of stream */
443 return BIT_DStream_overflow;
444
445 if (bitD->ptr >= bitD->limitPtr) {
446 return BIT_reloadDStreamFast(bitD);
447 }
448 if (bitD->ptr == bitD->start) {
449 if (bitD->bitsConsumed < sizeof(bitD->bitContainer)*8) return BIT_DStream_endOfBuffer;
450 return BIT_DStream_completed;
451 }
452 /* start < ptr < limitPtr */
453 { U32 nbBytes = bitD->bitsConsumed >> 3;
454 BIT_DStream_status result = BIT_DStream_unfinished;
455 if (bitD->ptr - nbBytes < bitD->start) {
456 nbBytes = (U32)(bitD->ptr - bitD->start); /* ptr > start */
457 result = BIT_DStream_endOfBuffer;
458 }
459 bitD->ptr -= nbBytes;
460 bitD->bitsConsumed -= nbBytes*8;
461 bitD->bitContainer = MEM_readLEST(bitD->ptr); /* reminder : srcSize > sizeof(bitD->bitContainer), otherwise bitD->ptr == bitD->start */
462 return result;
463 }
464}
465
466/*! BIT_endOfDStream() :
467 * @return : 1 if DStream has _exactly_ reached its end (all bits consumed).
468 */
469MEM_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t* DStream)
470{
471 return ((DStream->ptr == DStream->start) && (DStream->bitsConsumed == sizeof(DStream->bitContainer)*8));
472}
473
474#if defined (__cplusplus)
475}
476#endif
477
478#endif /* BITSTREAM_H_MODULE */
stage1/zstd/lib/common/compiler.h created+335
......@@ -0,0 +1,335 @@
1/*
2 * Copyright (c) Yann Collet, Facebook, Inc.
3 * All rights reserved.
4 *
5 * This source code is licensed under both the BSD-style license (found in the
6 * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7 * in the COPYING file in the root directory of this source tree).
8 * You may select, at your option, one of the above-listed licenses.
9 */
10
11#ifndef ZSTD_COMPILER_H
12#define ZSTD_COMPILER_H
13
14#include "portability_macros.h"
15
16/*-*******************************************************
17* Compiler specifics
18*********************************************************/
19/* force inlining */
20
21#if !defined(ZSTD_NO_INLINE)
22#if (defined(__GNUC__) && !defined(__STRICT_ANSI__)) || defined(__cplusplus) || defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */
23# define INLINE_KEYWORD inline
24#else
25# define INLINE_KEYWORD
26#endif
27
28#if defined(__GNUC__) || defined(__ICCARM__)
29# define FORCE_INLINE_ATTR __attribute__((always_inline))
30#elif defined(_MSC_VER)
31# define FORCE_INLINE_ATTR __forceinline
32#else
33# define FORCE_INLINE_ATTR
34#endif
35
36#else
37
38#define INLINE_KEYWORD
39#define FORCE_INLINE_ATTR
40
41#endif
42
43/**
44 On MSVC qsort requires that functions passed into it use the __cdecl calling conversion(CC).
45 This explicitly marks such functions as __cdecl so that the code will still compile
46 if a CC other than __cdecl has been made the default.
47*/
48#if defined(_MSC_VER)
49# define WIN_CDECL __cdecl
50#else
51# define WIN_CDECL
52#endif
53
54/**
55 * FORCE_INLINE_TEMPLATE is used to define C "templates", which take constant
56 * parameters. They must be inlined for the compiler to eliminate the constant
57 * branches.
58 */
59#define FORCE_INLINE_TEMPLATE static INLINE_KEYWORD FORCE_INLINE_ATTR
60/**
61 * HINT_INLINE is used to help the compiler generate better code. It is *not*
62 * used for "templates", so it can be tweaked based on the compilers
63 * performance.
64 *
65 * gcc-4.8 and gcc-4.9 have been shown to benefit from leaving off the
66 * always_inline attribute.
67 *
68 * clang up to 5.0.0 (trunk) benefit tremendously from the always_inline
69 * attribute.
70 */
71#if !defined(__clang__) && defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 8 && __GNUC__ < 5
72# define HINT_INLINE static INLINE_KEYWORD
73#else
74# define HINT_INLINE static INLINE_KEYWORD FORCE_INLINE_ATTR
75#endif
76
77/* UNUSED_ATTR tells the compiler it is okay if the function is unused. */
78#if defined(__GNUC__)
79# define UNUSED_ATTR __attribute__((unused))
80#else
81# define UNUSED_ATTR
82#endif
83
84/* force no inlining */
85#ifdef _MSC_VER
86# define FORCE_NOINLINE static __declspec(noinline)
87#else
88# if defined(__GNUC__) || defined(__ICCARM__)
89# define FORCE_NOINLINE static __attribute__((__noinline__))
90# else
91# define FORCE_NOINLINE static
92# endif
93#endif
94
95
96/* target attribute */
97#if defined(__GNUC__) || defined(__ICCARM__)
98# define TARGET_ATTRIBUTE(target) __attribute__((__target__(target)))
99#else
100# define TARGET_ATTRIBUTE(target)
101#endif
102
103/* Target attribute for BMI2 dynamic dispatch.
104 * Enable lzcnt, bmi, and bmi2.
105 * We test for bmi1 & bmi2. lzcnt is included in bmi1.
106 */
107#define BMI2_TARGET_ATTRIBUTE TARGET_ATTRIBUTE("lzcnt,bmi,bmi2")
108
109/* prefetch
110 * can be disabled, by declaring NO_PREFETCH build macro */
111#if defined(NO_PREFETCH)
112# define PREFETCH_L1(ptr) (void)(ptr) /* disabled */
113# define PREFETCH_L2(ptr) (void)(ptr) /* disabled */
114#else
115# if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_I86)) /* _mm_prefetch() is not defined outside of x86/x64 */
116# include <mmintrin.h> /* https://msdn.microsoft.com/fr-fr/library/84szxsww(v=vs.90).aspx */
117# define PREFETCH_L1(ptr) _mm_prefetch((const char*)(ptr), _MM_HINT_T0)
118# define PREFETCH_L2(ptr) _mm_prefetch((const char*)(ptr), _MM_HINT_T1)
119# elif defined(__GNUC__) && ( (__GNUC__ >= 4) || ( (__GNUC__ == 3) && (__GNUC_MINOR__ >= 1) ) )
120# define PREFETCH_L1(ptr) __builtin_prefetch((ptr), 0 /* rw==read */, 3 /* locality */)
121# define PREFETCH_L2(ptr) __builtin_prefetch((ptr), 0 /* rw==read */, 2 /* locality */)
122# elif defined(__aarch64__)
123# define PREFETCH_L1(ptr) __asm__ __volatile__("prfm pldl1keep, %0" ::"Q"(*(ptr)))
124# define PREFETCH_L2(ptr) __asm__ __volatile__("prfm pldl2keep, %0" ::"Q"(*(ptr)))
125# else
126# define PREFETCH_L1(ptr) (void)(ptr) /* disabled */
127# define PREFETCH_L2(ptr) (void)(ptr) /* disabled */
128# endif
129#endif /* NO_PREFETCH */
130
131#define CACHELINE_SIZE 64
132
133#define PREFETCH_AREA(p, s) { \
134 const char* const _ptr = (const char*)(p); \
135 size_t const _size = (size_t)(s); \
136 size_t _pos; \
137 for (_pos=0; _pos<_size; _pos+=CACHELINE_SIZE) { \
138 PREFETCH_L2(_ptr + _pos); \
139 } \
140}
141
142/* vectorization
143 * older GCC (pre gcc-4.3 picked as the cutoff) uses a different syntax,
144 * and some compilers, like Intel ICC and MCST LCC, do not support it at all. */
145#if !defined(__INTEL_COMPILER) && !defined(__clang__) && defined(__GNUC__) && !defined(__LCC__)
146# if (__GNUC__ == 4 && __GNUC_MINOR__ > 3) || (__GNUC__ >= 5)
147# define DONT_VECTORIZE __attribute__((optimize("no-tree-vectorize")))
148# else
149# define DONT_VECTORIZE _Pragma("GCC optimize(\"no-tree-vectorize\")")
150# endif
151#else
152# define DONT_VECTORIZE
153#endif
154
155/* Tell the compiler that a branch is likely or unlikely.
156 * Only use these macros if it causes the compiler to generate better code.
157 * If you can remove a LIKELY/UNLIKELY annotation without speed changes in gcc
158 * and clang, please do.
159 */
160#if defined(__GNUC__)
161#define LIKELY(x) (__builtin_expect((x), 1))
162#define UNLIKELY(x) (__builtin_expect((x), 0))
163#else
164#define LIKELY(x) (x)
165#define UNLIKELY(x) (x)
166#endif
167
168/* disable warnings */
169#ifdef _MSC_VER /* Visual Studio */
170# include <intrin.h> /* For Visual 2005 */
171# pragma warning(disable : 4100) /* disable: C4100: unreferenced formal parameter */
172# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
173# pragma warning(disable : 4204) /* disable: C4204: non-constant aggregate initializer */
174# pragma warning(disable : 4214) /* disable: C4214: non-int bitfields */
175# pragma warning(disable : 4324) /* disable: C4324: padded structure */
176#endif
177
178/*Like DYNAMIC_BMI2 but for compile time determination of BMI2 support*/
179#ifndef STATIC_BMI2
180# if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_I86))
181# ifdef __AVX2__ //MSVC does not have a BMI2 specific flag, but every CPU that supports AVX2 also supports BMI2
182# define STATIC_BMI2 1
183# endif
184# endif
185#endif
186
187#ifndef STATIC_BMI2
188 #define STATIC_BMI2 0
189#endif
190
191/* compile time determination of SIMD support */
192#if !defined(ZSTD_NO_INTRINSICS)
193# if defined(__SSE2__) || defined(_M_AMD64) || (defined (_M_IX86) && defined(_M_IX86_FP) && (_M_IX86_FP >= 2))
194# define ZSTD_ARCH_X86_SSE2
195# endif
196# if defined(__ARM_NEON) || defined(_M_ARM64)
197# define ZSTD_ARCH_ARM_NEON
198# endif
199#
200# if defined(ZSTD_ARCH_X86_SSE2)
201# include <emmintrin.h>
202# elif defined(ZSTD_ARCH_ARM_NEON)
203# include <arm_neon.h>
204# endif
205#endif
206
207/* C-language Attributes are added in C23. */
208#if defined(__STDC_VERSION__) && (__STDC_VERSION__ > 201710L) && defined(__has_c_attribute)
209# define ZSTD_HAS_C_ATTRIBUTE(x) __has_c_attribute(x)
210#else
211# define ZSTD_HAS_C_ATTRIBUTE(x) 0
212#endif
213
214/* Only use C++ attributes in C++. Some compilers report support for C++
215 * attributes when compiling with C.
216 */
217#if defined(__cplusplus) && defined(__has_cpp_attribute)
218# define ZSTD_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)
219#else
220# define ZSTD_HAS_CPP_ATTRIBUTE(x) 0
221#endif
222
223/* Define ZSTD_FALLTHROUGH macro for annotating switch case with the 'fallthrough' attribute.
224 * - C23: https://en.cppreference.com/w/c/language/attributes/fallthrough
225 * - CPP17: https://en.cppreference.com/w/cpp/language/attributes/fallthrough
226 * - Else: __attribute__((__fallthrough__))
227 */
228#ifndef ZSTD_FALLTHROUGH
229# if ZSTD_HAS_C_ATTRIBUTE(fallthrough)
230# define ZSTD_FALLTHROUGH [[fallthrough]]
231# elif ZSTD_HAS_CPP_ATTRIBUTE(fallthrough)
232# define ZSTD_FALLTHROUGH [[fallthrough]]
233# elif __has_attribute(__fallthrough__)
234/* Leading semicolon is to satisfy gcc-11 with -pedantic. Without the semicolon
235 * gcc complains about: a label can only be part of a statement and a declaration is not a statement.
236 */
237# define ZSTD_FALLTHROUGH ; __attribute__((__fallthrough__))
238# else
239# define ZSTD_FALLTHROUGH
240# endif
241#endif
242
243/*-**************************************************************
244* Alignment check
245*****************************************************************/
246
247/* this test was initially positioned in mem.h,
248 * but this file is removed (or replaced) for linux kernel
249 * so it's now hosted in compiler.h,
250 * which remains valid for both user & kernel spaces.
251 */
252
253#ifndef ZSTD_ALIGNOF
254# if defined(__GNUC__) || defined(_MSC_VER)
255/* covers gcc, clang & MSVC */
256/* note : this section must come first, before C11,
257 * due to a limitation in the kernel source generator */
258# define ZSTD_ALIGNOF(T) __alignof(T)
259
260# elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)
261/* C11 support */
262# include <stdalign.h>
263# define ZSTD_ALIGNOF(T) alignof(T)
264
265# else
266/* No known support for alignof() - imperfect backup */
267# define ZSTD_ALIGNOF(T) (sizeof(void*) < sizeof(T) ? sizeof(void*) : sizeof(T))
268
269# endif
270#endif /* ZSTD_ALIGNOF */
271
272/*-**************************************************************
273* Sanitizer
274*****************************************************************/
275
276#if ZSTD_MEMORY_SANITIZER
277/* Not all platforms that support msan provide sanitizers/msan_interface.h.
278 * We therefore declare the functions we need ourselves, rather than trying to
279 * include the header file... */
280#include <stddef.h> /* size_t */
281#define ZSTD_DEPS_NEED_STDINT
282#include "zstd_deps.h" /* intptr_t */
283
284/* Make memory region fully initialized (without changing its contents). */
285void __msan_unpoison(const volatile void *a, size_t size);
286
287/* Make memory region fully uninitialized (without changing its contents).
288 This is a legacy interface that does not update origin information. Use
289 __msan_allocated_memory() instead. */
290void __msan_poison(const volatile void *a, size_t size);
291
292/* Returns the offset of the first (at least partially) poisoned byte in the
293 memory range, or -1 if the whole range is good. */
294intptr_t __msan_test_shadow(const volatile void *x, size_t size);
295#endif
296
297#if ZSTD_ADDRESS_SANITIZER
298/* Not all platforms that support asan provide sanitizers/asan_interface.h.
299 * We therefore declare the functions we need ourselves, rather than trying to
300 * include the header file... */
301#include <stddef.h> /* size_t */
302
303/**
304 * Marks a memory region (<c>[addr, addr+size)</c>) as unaddressable.
305 *
306 * This memory must be previously allocated by your program. Instrumented
307 * code is forbidden from accessing addresses in this region until it is
308 * unpoisoned. This function is not guaranteed to poison the entire region -
309 * it could poison only a subregion of <c>[addr, addr+size)</c> due to ASan
310 * alignment restrictions.
311 *
312 * \note This function is not thread-safe because no two threads can poison or
313 * unpoison memory in the same memory region simultaneously.
314 *
315 * \param addr Start of memory region.
316 * \param size Size of memory region. */
317void __asan_poison_memory_region(void const volatile *addr, size_t size);
318
319/**
320 * Marks a memory region (<c>[addr, addr+size)</c>) as addressable.
321 *
322 * This memory must be previously allocated by your program. Accessing
323 * addresses in this region is allowed until this region is poisoned again.
324 * This function could unpoison a super-region of <c>[addr, addr+size)</c> due
325 * to ASan alignment restrictions.
326 *
327 * \note This function is not thread-safe because no two threads can
328 * poison or unpoison memory in the same memory region simultaneously.
329 *
330 * \param addr Start of memory region.
331 * \param size Size of memory region. */
332void __asan_unpoison_memory_region(void const volatile *addr, size_t size);
333#endif
334
335#endif /* ZSTD_COMPILER_H */
stage1/zstd/lib/common/cpu.h created+213
......@@ -0,0 +1,213 @@
1/*
2 * Copyright (c) Facebook, Inc.
3 * All rights reserved.
4 *
5 * This source code is licensed under both the BSD-style license (found in the
6 * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7 * in the COPYING file in the root directory of this source tree).
8 * You may select, at your option, one of the above-listed licenses.
9 */
10
11#ifndef ZSTD_COMMON_CPU_H
12#define ZSTD_COMMON_CPU_H
13
14/**
15 * Implementation taken from folly/CpuId.h
16 * https://github.com/facebook/folly/blob/master/folly/CpuId.h
17 */
18
19#include "mem.h"
20
21#ifdef _MSC_VER
22#include <intrin.h>
23#endif
24
25typedef struct {
26 U32 f1c;
27 U32 f1d;
28 U32 f7b;
29 U32 f7c;
30} ZSTD_cpuid_t;
31
32MEM_STATIC ZSTD_cpuid_t ZSTD_cpuid(void) {
33 U32 f1c = 0;
34 U32 f1d = 0;
35 U32 f7b = 0;
36 U32 f7c = 0;
37#if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_IX86))
38 int reg[4];
39 __cpuid((int*)reg, 0);
40 {
41 int const n = reg[0];
42 if (n >= 1) {
43 __cpuid((int*)reg, 1);
44 f1c = (U32)reg[2];
45 f1d = (U32)reg[3];
46 }
47 if (n >= 7) {
48 __cpuidex((int*)reg, 7, 0);
49 f7b = (U32)reg[1];
50 f7c = (U32)reg[2];
51 }
52 }
53#elif defined(__i386__) && defined(__PIC__) && !defined(__clang__) && defined(__GNUC__)
54 /* The following block like the normal cpuid branch below, but gcc
55 * reserves ebx for use of its pic register so we must specially
56 * handle the save and restore to avoid clobbering the register
57 */
58 U32 n;
59 __asm__(
60 "pushl %%ebx\n\t"
61 "cpuid\n\t"
62 "popl %%ebx\n\t"
63 : "=a"(n)
64 : "a"(0)
65 : "ecx", "edx");
66 if (n >= 1) {
67 U32 f1a;
68 __asm__(
69 "pushl %%ebx\n\t"
70 "cpuid\n\t"
71 "popl %%ebx\n\t"
72 : "=a"(f1a), "=c"(f1c), "=d"(f1d)
73 : "a"(1));
74 }
75 if (n >= 7) {
76 __asm__(
77 "pushl %%ebx\n\t"
78 "cpuid\n\t"
79 "movl %%ebx, %%eax\n\t"
80 "popl %%ebx"
81 : "=a"(f7b), "=c"(f7c)
82 : "a"(7), "c"(0)
83 : "edx");
84 }
85#elif defined(__x86_64__) || defined(_M_X64) || defined(__i386__)
86 U32 n;
87 __asm__("cpuid" : "=a"(n) : "a"(0) : "ebx", "ecx", "edx");
88 if (n >= 1) {
89 U32 f1a;
90 __asm__("cpuid" : "=a"(f1a), "=c"(f1c), "=d"(f1d) : "a"(1) : "ebx");
91 }
92 if (n >= 7) {
93 U32 f7a;
94 __asm__("cpuid"
95 : "=a"(f7a), "=b"(f7b), "=c"(f7c)
96 : "a"(7), "c"(0)
97 : "edx");
98 }
99#endif
100 {
101 ZSTD_cpuid_t cpuid;
102 cpuid.f1c = f1c;
103 cpuid.f1d = f1d;
104 cpuid.f7b = f7b;
105 cpuid.f7c = f7c;
106 return cpuid;
107 }
108}
109
110#define X(name, r, bit) \
111 MEM_STATIC int ZSTD_cpuid_##name(ZSTD_cpuid_t const cpuid) { \
112 return ((cpuid.r) & (1U << bit)) != 0; \
113 }
114
115/* cpuid(1): Processor Info and Feature Bits. */
116#define C(name, bit) X(name, f1c, bit)
117 C(sse3, 0)
118 C(pclmuldq, 1)
119 C(dtes64, 2)
120 C(monitor, 3)
121 C(dscpl, 4)
122 C(vmx, 5)
123 C(smx, 6)
124 C(eist, 7)
125 C(tm2, 8)
126 C(ssse3, 9)
127 C(cnxtid, 10)
128 C(fma, 12)
129 C(cx16, 13)
130 C(xtpr, 14)
131 C(pdcm, 15)
132 C(pcid, 17)
133 C(dca, 18)
134 C(sse41, 19)
135 C(sse42, 20)
136 C(x2apic, 21)
137 C(movbe, 22)
138 C(popcnt, 23)
139 C(tscdeadline, 24)
140 C(aes, 25)
141 C(xsave, 26)
142 C(osxsave, 27)
143 C(avx, 28)
144 C(f16c, 29)
145 C(rdrand, 30)
146#undef C
147#define D(name, bit) X(name, f1d, bit)
148 D(fpu, 0)
149 D(vme, 1)
150 D(de, 2)
151 D(pse, 3)
152 D(tsc, 4)
153 D(msr, 5)
154 D(pae, 6)
155 D(mce, 7)
156 D(cx8, 8)
157 D(apic, 9)
158 D(sep, 11)
159 D(mtrr, 12)
160 D(pge, 13)
161 D(mca, 14)
162 D(cmov, 15)
163 D(pat, 16)
164 D(pse36, 17)
165 D(psn, 18)
166 D(clfsh, 19)
167 D(ds, 21)
168 D(acpi, 22)
169 D(mmx, 23)
170 D(fxsr, 24)
171 D(sse, 25)
172 D(sse2, 26)
173 D(ss, 27)
174 D(htt, 28)
175 D(tm, 29)
176 D(pbe, 31)
177#undef D
178
179/* cpuid(7): Extended Features. */
180#define B(name, bit) X(name, f7b, bit)
181 B(bmi1, 3)
182 B(hle, 4)
183 B(avx2, 5)
184 B(smep, 7)
185 B(bmi2, 8)
186 B(erms, 9)
187 B(invpcid, 10)
188 B(rtm, 11)
189 B(mpx, 14)
190 B(avx512f, 16)
191 B(avx512dq, 17)
192 B(rdseed, 18)
193 B(adx, 19)
194 B(smap, 20)
195 B(avx512ifma, 21)
196 B(pcommit, 22)
197 B(clflushopt, 23)
198 B(clwb, 24)
199 B(avx512pf, 26)
200 B(avx512er, 27)
201 B(avx512cd, 28)
202 B(sha, 29)
203 B(avx512bw, 30)
204 B(avx512vl, 31)
205#undef B
206#define C(name, bit) X(name, f7c, bit)
207 C(prefetchwt1, 0)
208 C(avx512vbmi, 1)
209#undef C
210
211#undef X
212
213#endif /* ZSTD_COMMON_CPU_H */
stage1/zstd/lib/common/debug.c created+24
......@@ -0,0 +1,24 @@
1/* ******************************************************************
2 * debug
3 * Part of FSE library
4 * Copyright (c) Yann Collet, Facebook, Inc.
5 *
6 * You can contact the author at :
7 * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
8 *
9 * This source code is licensed under both the BSD-style license (found in the
10 * LICENSE file in the root directory of this source tree) and the GPLv2 (found
11 * in the COPYING file in the root directory of this source tree).
12 * You may select, at your option, one of the above-listed licenses.
13****************************************************************** */
14
15
16/*
17 * This module only hosts one global variable
18 * which can be used to dynamically influence the verbosity of traces,
19 * such as DEBUGLOG and RAWLOG
20 */
21
22#include "debug.h"
23
24int g_debuglevel = DEBUGLEVEL;
stage1/zstd/lib/common/debug.h created+107
......@@ -0,0 +1,107 @@
1/* ******************************************************************
2 * debug
3 * Part of FSE library
4 * Copyright (c) Yann Collet, Facebook, Inc.
5 *
6 * You can contact the author at :
7 * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
8 *
9 * This source code is licensed under both the BSD-style license (found in the
10 * LICENSE file in the root directory of this source tree) and the GPLv2 (found
11 * in the COPYING file in the root directory of this source tree).
12 * You may select, at your option, one of the above-listed licenses.
13****************************************************************** */
14
15
16/*
17 * The purpose of this header is to enable debug functions.
18 * They regroup assert(), DEBUGLOG() and RAWLOG() for run-time,
19 * and DEBUG_STATIC_ASSERT() for compile-time.
20 *
21 * By default, DEBUGLEVEL==0, which means run-time debug is disabled.
22 *
23 * Level 1 enables assert() only.
24 * Starting level 2, traces can be generated and pushed to stderr.
25 * The higher the level, the more verbose the traces.
26 *
27 * It's possible to dynamically adjust level using variable g_debug_level,
28 * which is only declared if DEBUGLEVEL>=2,
29 * and is a global variable, not multi-thread protected (use with care)
30 */
31
32#ifndef DEBUG_H_12987983217
33#define DEBUG_H_12987983217
34
35#if defined (__cplusplus)
36extern "C" {
37#endif
38
39
40/* static assert is triggered at compile time, leaving no runtime artefact.
41 * static assert only works with compile-time constants.
42 * Also, this variant can only be used inside a function. */
43#define DEBUG_STATIC_ASSERT(c) (void)sizeof(char[(c) ? 1 : -1])
44
45
46/* DEBUGLEVEL is expected to be defined externally,
47 * typically through compiler command line.
48 * Value must be a number. */
49#ifndef DEBUGLEVEL
50# define DEBUGLEVEL 0
51#endif
52
53
54/* recommended values for DEBUGLEVEL :
55 * 0 : release mode, no debug, all run-time checks disabled
56 * 1 : enables assert() only, no display
57 * 2 : reserved, for currently active debug path
58 * 3 : events once per object lifetime (CCtx, CDict, etc.)
59 * 4 : events once per frame
60 * 5 : events once per block
61 * 6 : events once per sequence (verbose)
62 * 7+: events at every position (*very* verbose)
63 *
64 * It's generally inconvenient to output traces > 5.
65 * In which case, it's possible to selectively trigger high verbosity levels
66 * by modifying g_debug_level.
67 */
68
69#if (DEBUGLEVEL>=1)
70# define ZSTD_DEPS_NEED_ASSERT
71# include "zstd_deps.h"
72#else
73# ifndef assert /* assert may be already defined, due to prior #include <assert.h> */
74# define assert(condition) ((void)0) /* disable assert (default) */
75# endif
76#endif
77
78#if (DEBUGLEVEL>=2)
79# define ZSTD_DEPS_NEED_IO
80# include "zstd_deps.h"
81extern int g_debuglevel; /* the variable is only declared,
82 it actually lives in debug.c,
83 and is shared by the whole process.
84 It's not thread-safe.
85 It's useful when enabling very verbose levels
86 on selective conditions (such as position in src) */
87
88# define RAWLOG(l, ...) { \
89 if (l<=g_debuglevel) { \
90 ZSTD_DEBUG_PRINT(__VA_ARGS__); \
91 } }
92# define DEBUGLOG(l, ...) { \
93 if (l<=g_debuglevel) { \
94 ZSTD_DEBUG_PRINT(__FILE__ ": " __VA_ARGS__); \
95 ZSTD_DEBUG_PRINT(" \n"); \
96 } }
97#else
98# define RAWLOG(l, ...) {} /* disabled */
99# define DEBUGLOG(l, ...) {} /* disabled */
100#endif
101
102
103#if defined (__cplusplus)
104}
105#endif
106
107#endif /* DEBUG_H_12987983217 */
stage1/zstd/lib/common/entropy_common.c created+368
......@@ -0,0 +1,368 @@
1/* ******************************************************************
2 * Common functions of New Generation Entropy library
3 * Copyright (c) Yann Collet, Facebook, Inc.
4 *
5 * You can contact the author at :
6 * - FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy
7 * - Public forum : https://groups.google.com/forum/#!forum/lz4c
8 *
9 * This source code is licensed under both the BSD-style license (found in the
10 * LICENSE file in the root directory of this source tree) and the GPLv2 (found
11 * in the COPYING file in the root directory of this source tree).
12 * You may select, at your option, one of the above-listed licenses.
13****************************************************************** */
14
15/* *************************************
16* Dependencies
17***************************************/
18#include "mem.h"
19#include "error_private.h" /* ERR_*, ERROR */
20#define FSE_STATIC_LINKING_ONLY /* FSE_MIN_TABLELOG */
21#include "fse.h"
22#define HUF_STATIC_LINKING_ONLY /* HUF_TABLELOG_ABSOLUTEMAX */
23#include "huf.h"
24
25
26/*=== Version ===*/
27unsigned FSE_versionNumber(void) { return FSE_VERSION_NUMBER; }
28
29
30/*=== Error Management ===*/
31unsigned FSE_isError(size_t code) { return ERR_isError(code); }
32const char* FSE_getErrorName(size_t code) { return ERR_getErrorName(code); }
33
34unsigned HUF_isError(size_t code) { return ERR_isError(code); }
35const char* HUF_getErrorName(size_t code) { return ERR_getErrorName(code); }
36
37
38/*-**************************************************************
39* FSE NCount encoding-decoding
40****************************************************************/
41static U32 FSE_ctz(U32 val)
42{
43 assert(val != 0);
44 {
45# if defined(_MSC_VER) /* Visual */
46 if (val != 0) {
47 unsigned long r;
48 _BitScanForward(&r, val);
49 return (unsigned)r;
50 } else {
51 /* Should not reach this code path */
52 __assume(0);
53 }
54# elif defined(__GNUC__) && (__GNUC__ >= 3) /* GCC Intrinsic */
55 return __builtin_ctz(val);
56# elif defined(__ICCARM__) /* IAR Intrinsic */
57 return __CTZ(val);
58# else /* Software version */
59 U32 count = 0;
60 while ((val & 1) == 0) {
61 val >>= 1;
62 ++count;
63 }
64 return count;
65# endif
66 }
67}
68
69FORCE_INLINE_TEMPLATE
70size_t FSE_readNCount_body(short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr,
71 const void* headerBuffer, size_t hbSize)
72{
73 const BYTE* const istart = (const BYTE*) headerBuffer;
74 const BYTE* const iend = istart + hbSize;
75 const BYTE* ip = istart;
76 int nbBits;
77 int remaining;
78 int threshold;
79 U32 bitStream;
80 int bitCount;
81 unsigned charnum = 0;
82 unsigned const maxSV1 = *maxSVPtr + 1;
83 int previous0 = 0;
84
85 if (hbSize < 8) {
86 /* This function only works when hbSize >= 8 */
87 char buffer[8] = {0};
88 ZSTD_memcpy(buffer, headerBuffer, hbSize);
89 { size_t const countSize = FSE_readNCount(normalizedCounter, maxSVPtr, tableLogPtr,
90 buffer, sizeof(buffer));
91 if (FSE_isError(countSize)) return countSize;
92 if (countSize > hbSize) return ERROR(corruption_detected);
93 return countSize;
94 } }
95 assert(hbSize >= 8);
96
97 /* init */
98 ZSTD_memset(normalizedCounter, 0, (*maxSVPtr+1) * sizeof(normalizedCounter[0])); /* all symbols not present in NCount have a frequency of 0 */
99 bitStream = MEM_readLE32(ip);
100 nbBits = (bitStream & 0xF) + FSE_MIN_TABLELOG; /* extract tableLog */
101 if (nbBits > FSE_TABLELOG_ABSOLUTE_MAX) return ERROR(tableLog_tooLarge);
102 bitStream >>= 4;
103 bitCount = 4;
104 *tableLogPtr = nbBits;
105 remaining = (1<<nbBits)+1;
106 threshold = 1<<nbBits;
107 nbBits++;
108
109 for (;;) {
110 if (previous0) {
111 /* Count the number of repeats. Each time the
112 * 2-bit repeat code is 0b11 there is another
113 * repeat.
114 * Avoid UB by setting the high bit to 1.
115 */
116 int repeats = FSE_ctz(~bitStream | 0x80000000) >> 1;
117 while (repeats >= 12) {
118 charnum += 3 * 12;
119 if (LIKELY(ip <= iend-7)) {
120 ip += 3;
121 } else {
122 bitCount -= (int)(8 * (iend - 7 - ip));
123 bitCount &= 31;
124 ip = iend - 4;
125 }
126 bitStream = MEM_readLE32(ip) >> bitCount;
127 repeats = FSE_ctz(~bitStream | 0x80000000) >> 1;
128 }
129 charnum += 3 * repeats;
130 bitStream >>= 2 * repeats;
131 bitCount += 2 * repeats;
132
133 /* Add the final repeat which isn't 0b11. */
134 assert((bitStream & 3) < 3);
135 charnum += bitStream & 3;
136 bitCount += 2;
137
138 /* This is an error, but break and return an error
139 * at the end, because returning out of a loop makes
140 * it harder for the compiler to optimize.
141 */
142 if (charnum >= maxSV1) break;
143
144 /* We don't need to set the normalized count to 0
145 * because we already memset the whole buffer to 0.
146 */
147
148 if (LIKELY(ip <= iend-7) || (ip + (bitCount>>3) <= iend-4)) {
149 assert((bitCount >> 3) <= 3); /* For first condition to work */
150 ip += bitCount>>3;
151 bitCount &= 7;
152 } else {
153 bitCount -= (int)(8 * (iend - 4 - ip));
154 bitCount &= 31;
155 ip = iend - 4;
156 }
157 bitStream = MEM_readLE32(ip) >> bitCount;
158 }
159 {
160 int const max = (2*threshold-1) - remaining;
161 int count;
162
163 if ((bitStream & (threshold-1)) < (U32)max) {
164 count = bitStream & (threshold-1);
165 bitCount += nbBits-1;
166 } else {
167 count = bitStream & (2*threshold-1);
168 if (count >= threshold) count -= max;
169 bitCount += nbBits;
170 }
171
172 count--; /* extra accuracy */
173 /* When it matters (small blocks), this is a
174 * predictable branch, because we don't use -1.
175 */
176 if (count >= 0) {
177 remaining -= count;
178 } else {
179 assert(count == -1);
180 remaining += count;
181 }
182 normalizedCounter[charnum++] = (short)count;
183 previous0 = !count;
184
185 assert(threshold > 1);
186 if (remaining < threshold) {
187 /* This branch can be folded into the
188 * threshold update condition because we
189 * know that threshold > 1.
190 */
191 if (remaining <= 1) break;
192 nbBits = BIT_highbit32(remaining) + 1;
193 threshold = 1 << (nbBits - 1);
194 }
195 if (charnum >= maxSV1) break;
196
197 if (LIKELY(ip <= iend-7) || (ip + (bitCount>>3) <= iend-4)) {
198 ip += bitCount>>3;
199 bitCount &= 7;
200 } else {
201 bitCount -= (int)(8 * (iend - 4 - ip));
202 bitCount &= 31;
203 ip = iend - 4;
204 }
205 bitStream = MEM_readLE32(ip) >> bitCount;
206 } }
207 if (remaining != 1) return ERROR(corruption_detected);
208 /* Only possible when there are too many zeros. */
209 if (charnum > maxSV1) return ERROR(maxSymbolValue_tooSmall);
210 if (bitCount > 32) return ERROR(corruption_detected);
211 *maxSVPtr = charnum-1;
212
213 ip += (bitCount+7)>>3;
214 return ip-istart;
215}
216
217/* Avoids the FORCE_INLINE of the _body() function. */
218static size_t FSE_readNCount_body_default(
219 short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr,
220 const void* headerBuffer, size_t hbSize)
221{
222 return FSE_readNCount_body(normalizedCounter, maxSVPtr, tableLogPtr, headerBuffer, hbSize);
223}
224
225#if DYNAMIC_BMI2
226BMI2_TARGET_ATTRIBUTE static size_t FSE_readNCount_body_bmi2(
227 short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr,
228 const void* headerBuffer, size_t hbSize)
229{
230 return FSE_readNCount_body(normalizedCounter, maxSVPtr, tableLogPtr, headerBuffer, hbSize);
231}
232#endif
233
234size_t FSE_readNCount_bmi2(
235 short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr,
236 const void* headerBuffer, size_t hbSize, int bmi2)
237{
238#if DYNAMIC_BMI2
239 if (bmi2) {
240 return FSE_readNCount_body_bmi2(normalizedCounter, maxSVPtr, tableLogPtr, headerBuffer, hbSize);
241 }
242#endif
243 (void)bmi2;
244 return FSE_readNCount_body_default(normalizedCounter, maxSVPtr, tableLogPtr, headerBuffer, hbSize);
245}
246
247size_t FSE_readNCount(
248 short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr,
249 const void* headerBuffer, size_t hbSize)
250{
251 return FSE_readNCount_bmi2(normalizedCounter, maxSVPtr, tableLogPtr, headerBuffer, hbSize, /* bmi2 */ 0);
252}
253
254
255/*! HUF_readStats() :
256 Read compact Huffman tree, saved by HUF_writeCTable().
257 `huffWeight` is destination buffer.
258 `rankStats` is assumed to be a table of at least HUF_TABLELOG_MAX U32.
259 @return : size read from `src` , or an error Code .
260 Note : Needed by HUF_readCTable() and HUF_readDTableX?() .
261*/
262size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats,
263 U32* nbSymbolsPtr, U32* tableLogPtr,
264 const void* src, size_t srcSize)
265{
266 U32 wksp[HUF_READ_STATS_WORKSPACE_SIZE_U32];
267 return HUF_readStats_wksp(huffWeight, hwSize, rankStats, nbSymbolsPtr, tableLogPtr, src, srcSize, wksp, sizeof(wksp), /* bmi2 */ 0);
268}
269
270FORCE_INLINE_TEMPLATE size_t
271HUF_readStats_body(BYTE* huffWeight, size_t hwSize, U32* rankStats,
272 U32* nbSymbolsPtr, U32* tableLogPtr,
273 const void* src, size_t srcSize,
274 void* workSpace, size_t wkspSize,
275 int bmi2)
276{
277 U32 weightTotal;
278 const BYTE* ip = (const BYTE*) src;
279 size_t iSize;
280 size_t oSize;
281
282 if (!srcSize) return ERROR(srcSize_wrong);
283 iSize = ip[0];
284 /* ZSTD_memset(huffWeight, 0, hwSize); *//* is not necessary, even though some analyzer complain ... */
285
286 if (iSize >= 128) { /* special header */
287 oSize = iSize - 127;
288 iSize = ((oSize+1)/2);
289 if (iSize+1 > srcSize) return ERROR(srcSize_wrong);
290 if (oSize >= hwSize) return ERROR(corruption_detected);
291 ip += 1;
292 { U32 n;
293 for (n=0; n<oSize; n+=2) {
294 huffWeight[n] = ip[n/2] >> 4;
295 huffWeight[n+1] = ip[n/2] & 15;
296 } } }
297 else { /* header compressed with FSE (normal case) */
298 if (iSize+1 > srcSize) return ERROR(srcSize_wrong);
299 /* max (hwSize-1) values decoded, as last one is implied */
300 oSize = FSE_decompress_wksp_bmi2(huffWeight, hwSize-1, ip+1, iSize, 6, workSpace, wkspSize, bmi2);
301 if (FSE_isError(oSize)) return oSize;
302 }
303
304 /* collect weight stats */
305 ZSTD_memset(rankStats, 0, (HUF_TABLELOG_MAX + 1) * sizeof(U32));
306 weightTotal = 0;
307 { U32 n; for (n=0; n<oSize; n++) {
308 if (huffWeight[n] > HUF_TABLELOG_MAX) return ERROR(corruption_detected);
309 rankStats[huffWeight[n]]++;
310 weightTotal += (1 << huffWeight[n]) >> 1;
311 } }
312 if (weightTotal == 0) return ERROR(corruption_detected);
313
314 /* get last non-null symbol weight (implied, total must be 2^n) */
315 { U32 const tableLog = BIT_highbit32(weightTotal) + 1;
316 if (tableLog > HUF_TABLELOG_MAX) return ERROR(corruption_detected);
317 *tableLogPtr = tableLog;
318 /* determine last weight */
319 { U32 const total = 1 << tableLog;
320 U32 const rest = total - weightTotal;
321 U32 const verif = 1 << BIT_highbit32(rest);
322 U32 const lastWeight = BIT_highbit32(rest) + 1;
323 if (verif != rest) return ERROR(corruption_detected); /* last value must be a clean power of 2 */
324 huffWeight[oSize] = (BYTE)lastWeight;
325 rankStats[lastWeight]++;
326 } }
327
328 /* check tree construction validity */
329 if ((rankStats[1] < 2) || (rankStats[1] & 1)) return ERROR(corruption_detected); /* by construction : at least 2 elts of rank 1, must be even */
330
331 /* results */
332 *nbSymbolsPtr = (U32)(oSize+1);
333 return iSize+1;
334}
335
336/* Avoids the FORCE_INLINE of the _body() function. */
337static size_t HUF_readStats_body_default(BYTE* huffWeight, size_t hwSize, U32* rankStats,
338 U32* nbSymbolsPtr, U32* tableLogPtr,
339 const void* src, size_t srcSize,
340 void* workSpace, size_t wkspSize)
341{
342 return HUF_readStats_body(huffWeight, hwSize, rankStats, nbSymbolsPtr, tableLogPtr, src, srcSize, workSpace, wkspSize, 0);
343}
344
345#if DYNAMIC_BMI2
346static BMI2_TARGET_ATTRIBUTE size_t HUF_readStats_body_bmi2(BYTE* huffWeight, size_t hwSize, U32* rankStats,
347 U32* nbSymbolsPtr, U32* tableLogPtr,
348 const void* src, size_t srcSize,
349 void* workSpace, size_t wkspSize)
350{
351 return HUF_readStats_body(huffWeight, hwSize, rankStats, nbSymbolsPtr, tableLogPtr, src, srcSize, workSpace, wkspSize, 1);
352}
353#endif
354
355size_t HUF_readStats_wksp(BYTE* huffWeight, size_t hwSize, U32* rankStats,
356 U32* nbSymbolsPtr, U32* tableLogPtr,
357 const void* src, size_t srcSize,
358 void* workSpace, size_t wkspSize,
359 int bmi2)
360{
361#if DYNAMIC_BMI2
362 if (bmi2) {
363 return HUF_readStats_body_bmi2(huffWeight, hwSize, rankStats, nbSymbolsPtr, tableLogPtr, src, srcSize, workSpace, wkspSize);
364 }
365#endif
366 (void)bmi2;
367 return HUF_readStats_body_default(huffWeight, hwSize, rankStats, nbSymbolsPtr, tableLogPtr, src, srcSize, workSpace, wkspSize);
368}
stage1/zstd/lib/common/error_private.c created+56
......@@ -0,0 +1,56 @@
1/*
2 * Copyright (c) Yann Collet, Facebook, Inc.
3 * All rights reserved.
4 *
5 * This source code is licensed under both the BSD-style license (found in the
6 * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7 * in the COPYING file in the root directory of this source tree).
8 * You may select, at your option, one of the above-listed licenses.
9 */
10
11/* The purpose of this file is to have a single list of error strings embedded in binary */
12
13#include "error_private.h"
14
15const char* ERR_getErrorString(ERR_enum code)
16{
17#ifdef ZSTD_STRIP_ERROR_STRINGS
18 (void)code;
19 return "Error strings stripped";
20#else
21 static const char* const notErrorCode = "Unspecified error code";
22 switch( code )
23 {
24 case PREFIX(no_error): return "No error detected";
25 case PREFIX(GENERIC): return "Error (generic)";
26 case PREFIX(prefix_unknown): return "Unknown frame descriptor";
27 case PREFIX(version_unsupported): return "Version not supported";
28 case PREFIX(frameParameter_unsupported): return "Unsupported frame parameter";
29 case PREFIX(frameParameter_windowTooLarge): return "Frame requires too much memory for decoding";
30 case PREFIX(corruption_detected): return "Corrupted block detected";
31 case PREFIX(checksum_wrong): return "Restored data doesn't match checksum";
32 case PREFIX(parameter_unsupported): return "Unsupported parameter";
33 case PREFIX(parameter_outOfBound): return "Parameter is out of bound";
34 case PREFIX(init_missing): return "Context should be init first";
35 case PREFIX(memory_allocation): return "Allocation error : not enough memory";
36 case PREFIX(workSpace_tooSmall): return "workSpace buffer is not large enough";
37 case PREFIX(stage_wrong): return "Operation not authorized at current processing stage";
38 case PREFIX(tableLog_tooLarge): return "tableLog requires too much memory : unsupported";
39 case PREFIX(maxSymbolValue_tooLarge): return "Unsupported max Symbol Value : too large";
40 case PREFIX(maxSymbolValue_tooSmall): return "Specified maxSymbolValue is too small";
41 case PREFIX(dictionary_corrupted): return "Dictionary is corrupted";
42 case PREFIX(dictionary_wrong): return "Dictionary mismatch";
43 case PREFIX(dictionaryCreation_failed): return "Cannot create Dictionary from provided samples";
44 case PREFIX(dstSize_tooSmall): return "Destination buffer is too small";
45 case PREFIX(srcSize_wrong): return "Src size is incorrect";
46 case PREFIX(dstBuffer_null): return "Operation on NULL destination buffer";
47 /* following error codes are not stable and may be removed or changed in a future version */
48 case PREFIX(frameIndex_tooLarge): return "Frame index is too large";
49 case PREFIX(seekableIO): return "An I/O error occurred when reading/seeking";
50 case PREFIX(dstBuffer_wrong): return "Destination buffer is wrong";
51 case PREFIX(srcBuffer_wrong): return "Source buffer is wrong";
52 case PREFIX(maxCode):
53 default: return notErrorCode;
54 }
55#endif
56}
stage1/zstd/lib/common/error_private.h created+159
......@@ -0,0 +1,159 @@
1/*
2 * Copyright (c) Yann Collet, Facebook, Inc.
3 * All rights reserved.
4 *
5 * This source code is licensed under both the BSD-style license (found in the
6 * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7 * in the COPYING file in the root directory of this source tree).
8 * You may select, at your option, one of the above-listed licenses.
9 */
10
11/* Note : this module is expected to remain private, do not expose it */
12
13#ifndef ERROR_H_MODULE
14#define ERROR_H_MODULE
15
16#if defined (__cplusplus)
17extern "C" {
18#endif
19
20
21/* ****************************************
22* Dependencies
23******************************************/
24#include "../zstd_errors.h" /* enum list */
25#include "compiler.h"
26#include "debug.h"
27#include "zstd_deps.h" /* size_t */
28
29
30/* ****************************************
31* Compiler-specific
32******************************************/
33#if defined(__GNUC__)
34# define ERR_STATIC static __attribute__((unused))
35#elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
36# define ERR_STATIC static inline
37#elif defined(_MSC_VER)
38# define ERR_STATIC static __inline
39#else
40# define ERR_STATIC static /* this version may generate warnings for unused static functions; disable the relevant warning */
41#endif
42
43
44/*-****************************************
45* Customization (error_public.h)
46******************************************/
47typedef ZSTD_ErrorCode ERR_enum;
48#define PREFIX(name) ZSTD_error_##name
49
50
51/*-****************************************
52* Error codes handling
53******************************************/
54#undef ERROR /* already defined on Visual Studio */
55#define ERROR(name) ZSTD_ERROR(name)
56#define ZSTD_ERROR(name) ((size_t)-PREFIX(name))
57
58ERR_STATIC unsigned ERR_isError(size_t code) { return (code > ERROR(maxCode)); }
59
60ERR_STATIC ERR_enum ERR_getErrorCode(size_t code) { if (!ERR_isError(code)) return (ERR_enum)0; return (ERR_enum) (0-code); }
61
62/* check and forward error code */
63#define CHECK_V_F(e, f) size_t const e = f; if (ERR_isError(e)) return e
64#define CHECK_F(f) { CHECK_V_F(_var_err__, f); }
65
66
67/*-****************************************
68* Error Strings
69******************************************/
70
71const char* ERR_getErrorString(ERR_enum code); /* error_private.c */
72
73ERR_STATIC const char* ERR_getErrorName(size_t code)
74{
75 return ERR_getErrorString(ERR_getErrorCode(code));
76}
77
78/**
79 * Ignore: this is an internal helper.
80 *
81 * This is a helper function to help force C99-correctness during compilation.
82 * Under strict compilation modes, variadic macro arguments can't be empty.
83 * However, variadic function arguments can be. Using a function therefore lets
84 * us statically check that at least one (string) argument was passed,
85 * independent of the compilation flags.
86 */
87static INLINE_KEYWORD UNUSED_ATTR
88void _force_has_format_string(const char *format, ...) {
89 (void)format;
90}
91
92/**
93 * Ignore: this is an internal helper.
94 *
95 * We want to force this function invocation to be syntactically correct, but
96 * we don't want to force runtime evaluation of its arguments.
97 */
98#define _FORCE_HAS_FORMAT_STRING(...) \
99 if (0) { \
100 _force_has_format_string(__VA_ARGS__); \
101 }
102
103#define ERR_QUOTE(str) #str
104
105/**
106 * Return the specified error if the condition evaluates to true.
107 *
108 * In debug modes, prints additional information.
109 * In order to do that (particularly, printing the conditional that failed),
110 * this can't just wrap RETURN_ERROR().
111 */
112#define RETURN_ERROR_IF(cond, err, ...) \
113 if (cond) { \
114 RAWLOG(3, "%s:%d: ERROR!: check %s failed, returning %s", \
115 __FILE__, __LINE__, ERR_QUOTE(cond), ERR_QUOTE(ERROR(err))); \
116 _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \
117 RAWLOG(3, ": " __VA_ARGS__); \
118 RAWLOG(3, "\n"); \
119 return ERROR(err); \
120 }
121
122/**
123 * Unconditionally return the specified error.
124 *
125 * In debug modes, prints additional information.
126 */
127#define RETURN_ERROR(err, ...) \
128 do { \
129 RAWLOG(3, "%s:%d: ERROR!: unconditional check failed, returning %s", \
130 __FILE__, __LINE__, ERR_QUOTE(ERROR(err))); \
131 _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \
132 RAWLOG(3, ": " __VA_ARGS__); \
133 RAWLOG(3, "\n"); \
134 return ERROR(err); \
135 } while(0);
136
137/**
138 * If the provided expression evaluates to an error code, returns that error code.
139 *
140 * In debug modes, prints additional information.
141 */
142#define FORWARD_IF_ERROR(err, ...) \
143 do { \
144 size_t const err_code = (err); \
145 if (ERR_isError(err_code)) { \
146 RAWLOG(3, "%s:%d: ERROR!: forwarding error in %s: %s", \
147 __FILE__, __LINE__, ERR_QUOTE(err), ERR_getErrorName(err_code)); \
148 _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \
149 RAWLOG(3, ": " __VA_ARGS__); \
150 RAWLOG(3, "\n"); \
151 return err_code; \
152 } \
153 } while(0);
154
155#if defined (__cplusplus)
156}
157#endif
158
159#endif /* ERROR_H_MODULE */
stage1/zstd/lib/common/fse.h created+717
......@@ -0,0 +1,717 @@
1/* ******************************************************************
2 * FSE : Finite State Entropy codec
3 * Public Prototypes declaration
4 * Copyright (c) Yann Collet, Facebook, Inc.
5 *
6 * You can contact the author at :
7 * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
8 *
9 * This source code is licensed under both the BSD-style license (found in the
10 * LICENSE file in the root directory of this source tree) and the GPLv2 (found
11 * in the COPYING file in the root directory of this source tree).
12 * You may select, at your option, one of the above-listed licenses.
13****************************************************************** */
14
15#if defined (__cplusplus)
16extern "C" {
17#endif
18
19#ifndef FSE_H
20#define FSE_H
21
22
23/*-*****************************************
24* Dependencies
25******************************************/
26#include "zstd_deps.h" /* size_t, ptrdiff_t */
27
28
29/*-*****************************************
30* FSE_PUBLIC_API : control library symbols visibility
31******************************************/
32#if defined(FSE_DLL_EXPORT) && (FSE_DLL_EXPORT==1) && defined(__GNUC__) && (__GNUC__ >= 4)
33# define FSE_PUBLIC_API __attribute__ ((visibility ("default")))
34#elif defined(FSE_DLL_EXPORT) && (FSE_DLL_EXPORT==1) /* Visual expected */
35# define FSE_PUBLIC_API __declspec(dllexport)
36#elif defined(FSE_DLL_IMPORT) && (FSE_DLL_IMPORT==1)
37# define FSE_PUBLIC_API __declspec(dllimport) /* It isn't required but allows to generate better code, saving a function pointer load from the IAT and an indirect jump.*/
38#else
39# define FSE_PUBLIC_API
40#endif
41
42/*------ Version ------*/
43#define FSE_VERSION_MAJOR 0
44#define FSE_VERSION_MINOR 9
45#define FSE_VERSION_RELEASE 0
46
47#define FSE_LIB_VERSION FSE_VERSION_MAJOR.FSE_VERSION_MINOR.FSE_VERSION_RELEASE
48#define FSE_QUOTE(str) #str
49#define FSE_EXPAND_AND_QUOTE(str) FSE_QUOTE(str)
50#define FSE_VERSION_STRING FSE_EXPAND_AND_QUOTE(FSE_LIB_VERSION)
51
52#define FSE_VERSION_NUMBER (FSE_VERSION_MAJOR *100*100 + FSE_VERSION_MINOR *100 + FSE_VERSION_RELEASE)
53FSE_PUBLIC_API unsigned FSE_versionNumber(void); /**< library version number; to be used when checking dll version */
54
55
56/*-****************************************
57* FSE simple functions
58******************************************/
59/*! FSE_compress() :
60 Compress content of buffer 'src', of size 'srcSize', into destination buffer 'dst'.
61 'dst' buffer must be already allocated. Compression runs faster is dstCapacity >= FSE_compressBound(srcSize).
62 @return : size of compressed data (<= dstCapacity).
63 Special values : if return == 0, srcData is not compressible => Nothing is stored within dst !!!
64 if return == 1, srcData is a single byte symbol * srcSize times. Use RLE compression instead.
65 if FSE_isError(return), compression failed (more details using FSE_getErrorName())
66*/
67FSE_PUBLIC_API size_t FSE_compress(void* dst, size_t dstCapacity,
68 const void* src, size_t srcSize);
69
70/*! FSE_decompress():
71 Decompress FSE data from buffer 'cSrc', of size 'cSrcSize',
72 into already allocated destination buffer 'dst', of size 'dstCapacity'.
73 @return : size of regenerated data (<= maxDstSize),
74 or an error code, which can be tested using FSE_isError() .
75
76 ** Important ** : FSE_decompress() does not decompress non-compressible nor RLE data !!!
77 Why ? : making this distinction requires a header.
78 Header management is intentionally delegated to the user layer, which can better manage special cases.
79*/
80FSE_PUBLIC_API size_t FSE_decompress(void* dst, size_t dstCapacity,
81 const void* cSrc, size_t cSrcSize);
82
83
84/*-*****************************************
85* Tool functions
86******************************************/
87FSE_PUBLIC_API size_t FSE_compressBound(size_t size); /* maximum compressed size */
88
89/* Error Management */
90FSE_PUBLIC_API unsigned FSE_isError(size_t code); /* tells if a return value is an error code */
91FSE_PUBLIC_API const char* FSE_getErrorName(size_t code); /* provides error code string (useful for debugging) */
92
93
94/*-*****************************************
95* FSE advanced functions
96******************************************/
97/*! FSE_compress2() :
98 Same as FSE_compress(), but allows the selection of 'maxSymbolValue' and 'tableLog'
99 Both parameters can be defined as '0' to mean : use default value
100 @return : size of compressed data
101 Special values : if return == 0, srcData is not compressible => Nothing is stored within cSrc !!!
102 if return == 1, srcData is a single byte symbol * srcSize times. Use RLE compression.
103 if FSE_isError(return), it's an error code.
104*/
105FSE_PUBLIC_API size_t FSE_compress2 (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog);
106
107
108/*-*****************************************
109* FSE detailed API
110******************************************/
111/*!
112FSE_compress() does the following:
1131. count symbol occurrence from source[] into table count[] (see hist.h)
1142. normalize counters so that sum(count[]) == Power_of_2 (2^tableLog)
1153. save normalized counters to memory buffer using writeNCount()
1164. build encoding table 'CTable' from normalized counters
1175. encode the data stream using encoding table 'CTable'
118
119FSE_decompress() does the following:
1201. read normalized counters with readNCount()
1212. build decoding table 'DTable' from normalized counters
1223. decode the data stream using decoding table 'DTable'
123
124The following API allows targeting specific sub-functions for advanced tasks.
125For example, it's possible to compress several blocks using the same 'CTable',
126or to save and provide normalized distribution using external method.
127*/
128
129/* *** COMPRESSION *** */
130
131/*! FSE_optimalTableLog():
132 dynamically downsize 'tableLog' when conditions are met.
133 It saves CPU time, by using smaller tables, while preserving or even improving compression ratio.
134 @return : recommended tableLog (necessarily <= 'maxTableLog') */
135FSE_PUBLIC_API unsigned FSE_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue);
136
137/*! FSE_normalizeCount():
138 normalize counts so that sum(count[]) == Power_of_2 (2^tableLog)
139 'normalizedCounter' is a table of short, of minimum size (maxSymbolValue+1).
140 useLowProbCount is a boolean parameter which trades off compressed size for
141 faster header decoding. When it is set to 1, the compressed data will be slightly
142 smaller. And when it is set to 0, FSE_readNCount() and FSE_buildDTable() will be
143 faster. If you are compressing a small amount of data (< 2 KB) then useLowProbCount=0
144 is a good default, since header deserialization makes a big speed difference.
145 Otherwise, useLowProbCount=1 is a good default, since the speed difference is small.
146 @return : tableLog,
147 or an errorCode, which can be tested using FSE_isError() */
148FSE_PUBLIC_API size_t FSE_normalizeCount(short* normalizedCounter, unsigned tableLog,
149 const unsigned* count, size_t srcSize, unsigned maxSymbolValue, unsigned useLowProbCount);
150
151/*! FSE_NCountWriteBound():
152 Provides the maximum possible size of an FSE normalized table, given 'maxSymbolValue' and 'tableLog'.
153 Typically useful for allocation purpose. */
154FSE_PUBLIC_API size_t FSE_NCountWriteBound(unsigned maxSymbolValue, unsigned tableLog);
155
156/*! FSE_writeNCount():
157 Compactly save 'normalizedCounter' into 'buffer'.
158 @return : size of the compressed table,
159 or an errorCode, which can be tested using FSE_isError(). */
160FSE_PUBLIC_API size_t FSE_writeNCount (void* buffer, size_t bufferSize,
161 const short* normalizedCounter,
162 unsigned maxSymbolValue, unsigned tableLog);
163
164/*! Constructor and Destructor of FSE_CTable.
165 Note that FSE_CTable size depends on 'tableLog' and 'maxSymbolValue' */
166typedef unsigned FSE_CTable; /* don't allocate that. It's only meant to be more restrictive than void* */
167FSE_PUBLIC_API FSE_CTable* FSE_createCTable (unsigned maxSymbolValue, unsigned tableLog);
168FSE_PUBLIC_API void FSE_freeCTable (FSE_CTable* ct);
169
170/*! FSE_buildCTable():
171 Builds `ct`, which must be already allocated, using FSE_createCTable().
172 @return : 0, or an errorCode, which can be tested using FSE_isError() */
173FSE_PUBLIC_API size_t FSE_buildCTable(FSE_CTable* ct, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog);
174
175/*! FSE_compress_usingCTable():
176 Compress `src` using `ct` into `dst` which must be already allocated.
177 @return : size of compressed data (<= `dstCapacity`),
178 or 0 if compressed data could not fit into `dst`,
179 or an errorCode, which can be tested using FSE_isError() */
180FSE_PUBLIC_API size_t FSE_compress_usingCTable (void* dst, size_t dstCapacity, const void* src, size_t srcSize, const FSE_CTable* ct);
181
182/*!
183Tutorial :
184----------
185The first step is to count all symbols. FSE_count() does this job very fast.
186Result will be saved into 'count', a table of unsigned int, which must be already allocated, and have 'maxSymbolValuePtr[0]+1' cells.
187'src' is a table of bytes of size 'srcSize'. All values within 'src' MUST be <= maxSymbolValuePtr[0]
188maxSymbolValuePtr[0] will be updated, with its real value (necessarily <= original value)
189FSE_count() will return the number of occurrence of the most frequent symbol.
190This can be used to know if there is a single symbol within 'src', and to quickly evaluate its compressibility.
191If there is an error, the function will return an ErrorCode (which can be tested using FSE_isError()).
192
193The next step is to normalize the frequencies.
194FSE_normalizeCount() will ensure that sum of frequencies is == 2 ^'tableLog'.
195It also guarantees a minimum of 1 to any Symbol with frequency >= 1.
196You can use 'tableLog'==0 to mean "use default tableLog value".
197If you are unsure of which tableLog value to use, you can ask FSE_optimalTableLog(),
198which will provide the optimal valid tableLog given sourceSize, maxSymbolValue, and a user-defined maximum (0 means "default").
199
200The result of FSE_normalizeCount() will be saved into a table,
201called 'normalizedCounter', which is a table of signed short.
202'normalizedCounter' must be already allocated, and have at least 'maxSymbolValue+1' cells.
203The return value is tableLog if everything proceeded as expected.
204It is 0 if there is a single symbol within distribution.
205If there is an error (ex: invalid tableLog value), the function will return an ErrorCode (which can be tested using FSE_isError()).
206
207'normalizedCounter' can be saved in a compact manner to a memory area using FSE_writeNCount().
208'buffer' must be already allocated.
209For guaranteed success, buffer size must be at least FSE_headerBound().
210The result of the function is the number of bytes written into 'buffer'.
211If there is an error, the function will return an ErrorCode (which can be tested using FSE_isError(); ex : buffer size too small).
212
213'normalizedCounter' can then be used to create the compression table 'CTable'.
214The space required by 'CTable' must be already allocated, using FSE_createCTable().
215You can then use FSE_buildCTable() to fill 'CTable'.
216If there is an error, both functions will return an ErrorCode (which can be tested using FSE_isError()).
217
218'CTable' can then be used to compress 'src', with FSE_compress_usingCTable().
219Similar to FSE_count(), the convention is that 'src' is assumed to be a table of char of size 'srcSize'
220The function returns the size of compressed data (without header), necessarily <= `dstCapacity`.
221If it returns '0', compressed data could not fit into 'dst'.
222If there is an error, the function will return an ErrorCode (which can be tested using FSE_isError()).
223*/
224
225
226/* *** DECOMPRESSION *** */
227
228/*! FSE_readNCount():
229 Read compactly saved 'normalizedCounter' from 'rBuffer'.
230 @return : size read from 'rBuffer',
231 or an errorCode, which can be tested using FSE_isError().
232 maxSymbolValuePtr[0] and tableLogPtr[0] will also be updated with their respective values */
233FSE_PUBLIC_API size_t FSE_readNCount (short* normalizedCounter,
234 unsigned* maxSymbolValuePtr, unsigned* tableLogPtr,
235 const void* rBuffer, size_t rBuffSize);
236
237/*! FSE_readNCount_bmi2():
238 * Same as FSE_readNCount() but pass bmi2=1 when your CPU supports BMI2 and 0 otherwise.
239 */
240FSE_PUBLIC_API size_t FSE_readNCount_bmi2(short* normalizedCounter,
241 unsigned* maxSymbolValuePtr, unsigned* tableLogPtr,
242 const void* rBuffer, size_t rBuffSize, int bmi2);
243
244/*! Constructor and Destructor of FSE_DTable.
245 Note that its size depends on 'tableLog' */
246typedef unsigned FSE_DTable; /* don't allocate that. It's just a way to be more restrictive than void* */
247FSE_PUBLIC_API FSE_DTable* FSE_createDTable(unsigned tableLog);
248FSE_PUBLIC_API void FSE_freeDTable(FSE_DTable* dt);
249
250/*! FSE_buildDTable():
251 Builds 'dt', which must be already allocated, using FSE_createDTable().
252 return : 0, or an errorCode, which can be tested using FSE_isError() */
253FSE_PUBLIC_API size_t FSE_buildDTable (FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog);
254
255/*! FSE_decompress_usingDTable():
256 Decompress compressed source `cSrc` of size `cSrcSize` using `dt`
257 into `dst` which must be already allocated.
258 @return : size of regenerated data (necessarily <= `dstCapacity`),
259 or an errorCode, which can be tested using FSE_isError() */
260FSE_PUBLIC_API size_t FSE_decompress_usingDTable(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, const FSE_DTable* dt);
261
262/*!
263Tutorial :
264----------
265(Note : these functions only decompress FSE-compressed blocks.
266 If block is uncompressed, use memcpy() instead
267 If block is a single repeated byte, use memset() instead )
268
269The first step is to obtain the normalized frequencies of symbols.
270This can be performed by FSE_readNCount() if it was saved using FSE_writeNCount().
271'normalizedCounter' must be already allocated, and have at least 'maxSymbolValuePtr[0]+1' cells of signed short.
272In practice, that means it's necessary to know 'maxSymbolValue' beforehand,
273or size the table to handle worst case situations (typically 256).
274FSE_readNCount() will provide 'tableLog' and 'maxSymbolValue'.
275The result of FSE_readNCount() is the number of bytes read from 'rBuffer'.
276Note that 'rBufferSize' must be at least 4 bytes, even if useful information is less than that.
277If there is an error, the function will return an error code, which can be tested using FSE_isError().
278
279The next step is to build the decompression tables 'FSE_DTable' from 'normalizedCounter'.
280This is performed by the function FSE_buildDTable().
281The space required by 'FSE_DTable' must be already allocated using FSE_createDTable().
282If there is an error, the function will return an error code, which can be tested using FSE_isError().
283
284`FSE_DTable` can then be used to decompress `cSrc`, with FSE_decompress_usingDTable().
285`cSrcSize` must be strictly correct, otherwise decompression will fail.
286FSE_decompress_usingDTable() result will tell how many bytes were regenerated (<=`dstCapacity`).
287If there is an error, the function will return an error code, which can be tested using FSE_isError(). (ex: dst buffer too small)
288*/
289
290#endif /* FSE_H */
291
292#if defined(FSE_STATIC_LINKING_ONLY) && !defined(FSE_H_FSE_STATIC_LINKING_ONLY)
293#define FSE_H_FSE_STATIC_LINKING_ONLY
294
295/* *** Dependency *** */
296#include "bitstream.h"
297
298
299/* *****************************************
300* Static allocation
301*******************************************/
302/* FSE buffer bounds */
303#define FSE_NCOUNTBOUND 512
304#define FSE_BLOCKBOUND(size) ((size) + ((size)>>7) + 4 /* fse states */ + sizeof(size_t) /* bitContainer */)
305#define FSE_COMPRESSBOUND(size) (FSE_NCOUNTBOUND + FSE_BLOCKBOUND(size)) /* Macro version, useful for static allocation */
306
307/* It is possible to statically allocate FSE CTable/DTable as a table of FSE_CTable/FSE_DTable using below macros */
308#define FSE_CTABLE_SIZE_U32(maxTableLog, maxSymbolValue) (1 + (1<<((maxTableLog)-1)) + (((maxSymbolValue)+1)*2))
309#define FSE_DTABLE_SIZE_U32(maxTableLog) (1 + (1<<(maxTableLog)))
310
311/* or use the size to malloc() space directly. Pay attention to alignment restrictions though */
312#define FSE_CTABLE_SIZE(maxTableLog, maxSymbolValue) (FSE_CTABLE_SIZE_U32(maxTableLog, maxSymbolValue) * sizeof(FSE_CTable))
313#define FSE_DTABLE_SIZE(maxTableLog) (FSE_DTABLE_SIZE_U32(maxTableLog) * sizeof(FSE_DTable))
314
315
316/* *****************************************
317 * FSE advanced API
318 ***************************************** */
319
320unsigned FSE_optimalTableLog_internal(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue, unsigned minus);
321/**< same as FSE_optimalTableLog(), which used `minus==2` */
322
323/* FSE_compress_wksp() :
324 * Same as FSE_compress2(), but using an externally allocated scratch buffer (`workSpace`).
325 * FSE_COMPRESS_WKSP_SIZE_U32() provides the minimum size required for `workSpace` as a table of FSE_CTable.
326 */
327#define FSE_COMPRESS_WKSP_SIZE_U32(maxTableLog, maxSymbolValue) ( FSE_CTABLE_SIZE_U32(maxTableLog, maxSymbolValue) + ((maxTableLog > 12) ? (1 << (maxTableLog - 2)) : 1024) )
328size_t FSE_compress_wksp (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize);
329
330size_t FSE_buildCTable_raw (FSE_CTable* ct, unsigned nbBits);
331/**< build a fake FSE_CTable, designed for a flat distribution, where each symbol uses nbBits */
332
333size_t FSE_buildCTable_rle (FSE_CTable* ct, unsigned char symbolValue);
334/**< build a fake FSE_CTable, designed to compress always the same symbolValue */
335
336/* FSE_buildCTable_wksp() :
337 * Same as FSE_buildCTable(), but using an externally allocated scratch buffer (`workSpace`).
338 * `wkspSize` must be >= `FSE_BUILD_CTABLE_WORKSPACE_SIZE_U32(maxSymbolValue, tableLog)` of `unsigned`.
339 * See FSE_buildCTable_wksp() for breakdown of workspace usage.
340 */
341#define FSE_BUILD_CTABLE_WORKSPACE_SIZE_U32(maxSymbolValue, tableLog) (((maxSymbolValue + 2) + (1ull << (tableLog)))/2 + sizeof(U64)/sizeof(U32) /* additional 8 bytes for potential table overwrite */)
342#define FSE_BUILD_CTABLE_WORKSPACE_SIZE(maxSymbolValue, tableLog) (sizeof(unsigned) * FSE_BUILD_CTABLE_WORKSPACE_SIZE_U32(maxSymbolValue, tableLog))
343size_t FSE_buildCTable_wksp(FSE_CTable* ct, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize);
344
345#define FSE_BUILD_DTABLE_WKSP_SIZE(maxTableLog, maxSymbolValue) (sizeof(short) * (maxSymbolValue + 1) + (1ULL << maxTableLog) + 8)
346#define FSE_BUILD_DTABLE_WKSP_SIZE_U32(maxTableLog, maxSymbolValue) ((FSE_BUILD_DTABLE_WKSP_SIZE(maxTableLog, maxSymbolValue) + sizeof(unsigned) - 1) / sizeof(unsigned))
347FSE_PUBLIC_API size_t FSE_buildDTable_wksp(FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize);
348/**< Same as FSE_buildDTable(), using an externally allocated `workspace` produced with `FSE_BUILD_DTABLE_WKSP_SIZE_U32(maxSymbolValue)` */
349
350size_t FSE_buildDTable_raw (FSE_DTable* dt, unsigned nbBits);
351/**< build a fake FSE_DTable, designed to read a flat distribution where each symbol uses nbBits */
352
353size_t FSE_buildDTable_rle (FSE_DTable* dt, unsigned char symbolValue);
354/**< build a fake FSE_DTable, designed to always generate the same symbolValue */
355
356#define FSE_DECOMPRESS_WKSP_SIZE_U32(maxTableLog, maxSymbolValue) (FSE_DTABLE_SIZE_U32(maxTableLog) + FSE_BUILD_DTABLE_WKSP_SIZE_U32(maxTableLog, maxSymbolValue) + (FSE_MAX_SYMBOL_VALUE + 1) / 2 + 1)
357#define FSE_DECOMPRESS_WKSP_SIZE(maxTableLog, maxSymbolValue) (FSE_DECOMPRESS_WKSP_SIZE_U32(maxTableLog, maxSymbolValue) * sizeof(unsigned))
358size_t FSE_decompress_wksp(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, unsigned maxLog, void* workSpace, size_t wkspSize);
359/**< same as FSE_decompress(), using an externally allocated `workSpace` produced with `FSE_DECOMPRESS_WKSP_SIZE_U32(maxLog, maxSymbolValue)` */
360
361size_t FSE_decompress_wksp_bmi2(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, unsigned maxLog, void* workSpace, size_t wkspSize, int bmi2);
362/**< Same as FSE_decompress_wksp() but with dynamic BMI2 support. Pass 1 if your CPU supports BMI2 or 0 if it doesn't. */
363
364typedef enum {
365 FSE_repeat_none, /**< Cannot use the previous table */
366 FSE_repeat_check, /**< Can use the previous table but it must be checked */
367 FSE_repeat_valid /**< Can use the previous table and it is assumed to be valid */
368 } FSE_repeat;
369
370/* *****************************************
371* FSE symbol compression API
372*******************************************/
373/*!
374 This API consists of small unitary functions, which highly benefit from being inlined.
375 Hence their body are included in next section.
376*/
377typedef struct {
378 ptrdiff_t value;
379 const void* stateTable;
380 const void* symbolTT;
381 unsigned stateLog;
382} FSE_CState_t;
383
384static void FSE_initCState(FSE_CState_t* CStatePtr, const FSE_CTable* ct);
385
386static void FSE_encodeSymbol(BIT_CStream_t* bitC, FSE_CState_t* CStatePtr, unsigned symbol);
387
388static void FSE_flushCState(BIT_CStream_t* bitC, const FSE_CState_t* CStatePtr);
389
390/**<
391These functions are inner components of FSE_compress_usingCTable().
392They allow the creation of custom streams, mixing multiple tables and bit sources.
393
394A key property to keep in mind is that encoding and decoding are done **in reverse direction**.
395So the first symbol you will encode is the last you will decode, like a LIFO stack.
396
397You will need a few variables to track your CStream. They are :
398
399FSE_CTable ct; // Provided by FSE_buildCTable()
400BIT_CStream_t bitStream; // bitStream tracking structure
401FSE_CState_t state; // State tracking structure (can have several)
402
403
404The first thing to do is to init bitStream and state.
405 size_t errorCode = BIT_initCStream(&bitStream, dstBuffer, maxDstSize);
406 FSE_initCState(&state, ct);
407
408Note that BIT_initCStream() can produce an error code, so its result should be tested, using FSE_isError();
409You can then encode your input data, byte after byte.
410FSE_encodeSymbol() outputs a maximum of 'tableLog' bits at a time.
411Remember decoding will be done in reverse direction.
412 FSE_encodeByte(&bitStream, &state, symbol);
413
414At any time, you can also add any bit sequence.
415Note : maximum allowed nbBits is 25, for compatibility with 32-bits decoders
416 BIT_addBits(&bitStream, bitField, nbBits);
417
418The above methods don't commit data to memory, they just store it into local register, for speed.
419Local register size is 64-bits on 64-bits systems, 32-bits on 32-bits systems (size_t).
420Writing data to memory is a manual operation, performed by the flushBits function.
421 BIT_flushBits(&bitStream);
422
423Your last FSE encoding operation shall be to flush your last state value(s).
424 FSE_flushState(&bitStream, &state);
425
426Finally, you must close the bitStream.
427The function returns the size of CStream in bytes.
428If data couldn't fit into dstBuffer, it will return a 0 ( == not compressible)
429If there is an error, it returns an errorCode (which can be tested using FSE_isError()).
430 size_t size = BIT_closeCStream(&bitStream);
431*/
432
433
434/* *****************************************
435* FSE symbol decompression API
436*******************************************/
437typedef struct {
438 size_t state;
439 const void* table; /* precise table may vary, depending on U16 */
440} FSE_DState_t;
441
442
443static void FSE_initDState(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD, const FSE_DTable* dt);
444
445static unsigned char FSE_decodeSymbol(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD);
446
447static unsigned FSE_endOfDState(const FSE_DState_t* DStatePtr);
448
449/**<
450Let's now decompose FSE_decompress_usingDTable() into its unitary components.
451You will decode FSE-encoded symbols from the bitStream,
452and also any other bitFields you put in, **in reverse order**.
453
454You will need a few variables to track your bitStream. They are :
455
456BIT_DStream_t DStream; // Stream context
457FSE_DState_t DState; // State context. Multiple ones are possible
458FSE_DTable* DTablePtr; // Decoding table, provided by FSE_buildDTable()
459
460The first thing to do is to init the bitStream.
461 errorCode = BIT_initDStream(&DStream, srcBuffer, srcSize);
462
463You should then retrieve your initial state(s)
464(in reverse flushing order if you have several ones) :
465 errorCode = FSE_initDState(&DState, &DStream, DTablePtr);
466
467You can then decode your data, symbol after symbol.
468For information the maximum number of bits read by FSE_decodeSymbol() is 'tableLog'.
469Keep in mind that symbols are decoded in reverse order, like a LIFO stack (last in, first out).
470 unsigned char symbol = FSE_decodeSymbol(&DState, &DStream);
471
472You can retrieve any bitfield you eventually stored into the bitStream (in reverse order)
473Note : maximum allowed nbBits is 25, for 32-bits compatibility
474 size_t bitField = BIT_readBits(&DStream, nbBits);
475
476All above operations only read from local register (which size depends on size_t).
477Refueling the register from memory is manually performed by the reload method.
478 endSignal = FSE_reloadDStream(&DStream);
479
480BIT_reloadDStream() result tells if there is still some more data to read from DStream.
481BIT_DStream_unfinished : there is still some data left into the DStream.
482BIT_DStream_endOfBuffer : Dstream reached end of buffer. Its container may no longer be completely filled.
483BIT_DStream_completed : Dstream reached its exact end, corresponding in general to decompression completed.
484BIT_DStream_tooFar : Dstream went too far. Decompression result is corrupted.
485
486When reaching end of buffer (BIT_DStream_endOfBuffer), progress slowly, notably if you decode multiple symbols per loop,
487to properly detect the exact end of stream.
488After each decoded symbol, check if DStream is fully consumed using this simple test :
489 BIT_reloadDStream(&DStream) >= BIT_DStream_completed
490
491When it's done, verify decompression is fully completed, by checking both DStream and the relevant states.
492Checking if DStream has reached its end is performed by :
493 BIT_endOfDStream(&DStream);
494Check also the states. There might be some symbols left there, if some high probability ones (>50%) are possible.
495 FSE_endOfDState(&DState);
496*/
497
498
499/* *****************************************
500* FSE unsafe API
501*******************************************/
502static unsigned char FSE_decodeSymbolFast(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD);
503/* faster, but works only if nbBits is always >= 1 (otherwise, result will be corrupted) */
504
505
506/* *****************************************
507* Implementation of inlined functions
508*******************************************/
509typedef struct {
510 int deltaFindState;
511 U32 deltaNbBits;
512} FSE_symbolCompressionTransform; /* total 8 bytes */
513
514MEM_STATIC void FSE_initCState(FSE_CState_t* statePtr, const FSE_CTable* ct)
515{
516 const void* ptr = ct;
517 const U16* u16ptr = (const U16*) ptr;
518 const U32 tableLog = MEM_read16(ptr);
519 statePtr->value = (ptrdiff_t)1<<tableLog;
520 statePtr->stateTable = u16ptr+2;
521 statePtr->symbolTT = ct + 1 + (tableLog ? (1<<(tableLog-1)) : 1);
522 statePtr->stateLog = tableLog;
523}
524
525
526/*! FSE_initCState2() :
527* Same as FSE_initCState(), but the first symbol to include (which will be the last to be read)
528* uses the smallest state value possible, saving the cost of this symbol */
529MEM_STATIC void FSE_initCState2(FSE_CState_t* statePtr, const FSE_CTable* ct, U32 symbol)
530{
531 FSE_initCState(statePtr, ct);
532 { const FSE_symbolCompressionTransform symbolTT = ((const FSE_symbolCompressionTransform*)(statePtr->symbolTT))[symbol];
533 const U16* stateTable = (const U16*)(statePtr->stateTable);
534 U32 nbBitsOut = (U32)((symbolTT.deltaNbBits + (1<<15)) >> 16);
535 statePtr->value = (nbBitsOut << 16) - symbolTT.deltaNbBits;
536 statePtr->value = stateTable[(statePtr->value >> nbBitsOut) + symbolTT.deltaFindState];
537 }
538}
539
540MEM_STATIC void FSE_encodeSymbol(BIT_CStream_t* bitC, FSE_CState_t* statePtr, unsigned symbol)
541{
542 FSE_symbolCompressionTransform const symbolTT = ((const FSE_symbolCompressionTransform*)(statePtr->symbolTT))[symbol];
543 const U16* const stateTable = (const U16*)(statePtr->stateTable);
544 U32 const nbBitsOut = (U32)((statePtr->value + symbolTT.deltaNbBits) >> 16);
545 BIT_addBits(bitC, statePtr->value, nbBitsOut);
546 statePtr->value = stateTable[ (statePtr->value >> nbBitsOut) + symbolTT.deltaFindState];
547}
548
549MEM_STATIC void FSE_flushCState(BIT_CStream_t* bitC, const FSE_CState_t* statePtr)
550{
551 BIT_addBits(bitC, statePtr->value, statePtr->stateLog);
552 BIT_flushBits(bitC);
553}
554
555
556/* FSE_getMaxNbBits() :
557 * Approximate maximum cost of a symbol, in bits.
558 * Fractional get rounded up (i.e : a symbol with a normalized frequency of 3 gives the same result as a frequency of 2)
559 * note 1 : assume symbolValue is valid (<= maxSymbolValue)
560 * note 2 : if freq[symbolValue]==0, @return a fake cost of tableLog+1 bits */
561MEM_STATIC U32 FSE_getMaxNbBits(const void* symbolTTPtr, U32 symbolValue)
562{
563 const FSE_symbolCompressionTransform* symbolTT = (const FSE_symbolCompressionTransform*) symbolTTPtr;
564 return (symbolTT[symbolValue].deltaNbBits + ((1<<16)-1)) >> 16;
565}
566
567/* FSE_bitCost() :
568 * Approximate symbol cost, as fractional value, using fixed-point format (accuracyLog fractional bits)
569 * note 1 : assume symbolValue is valid (<= maxSymbolValue)
570 * note 2 : if freq[symbolValue]==0, @return a fake cost of tableLog+1 bits */
571MEM_STATIC U32 FSE_bitCost(const void* symbolTTPtr, U32 tableLog, U32 symbolValue, U32 accuracyLog)
572{
573 const FSE_symbolCompressionTransform* symbolTT = (const FSE_symbolCompressionTransform*) symbolTTPtr;
574 U32 const minNbBits = symbolTT[symbolValue].deltaNbBits >> 16;
575 U32 const threshold = (minNbBits+1) << 16;
576 assert(tableLog < 16);
577 assert(accuracyLog < 31-tableLog); /* ensure enough room for renormalization double shift */
578 { U32 const tableSize = 1 << tableLog;
579 U32 const deltaFromThreshold = threshold - (symbolTT[symbolValue].deltaNbBits + tableSize);
580 U32 const normalizedDeltaFromThreshold = (deltaFromThreshold << accuracyLog) >> tableLog; /* linear interpolation (very approximate) */
581 U32 const bitMultiplier = 1 << accuracyLog;
582 assert(symbolTT[symbolValue].deltaNbBits + tableSize <= threshold);
583 assert(normalizedDeltaFromThreshold <= bitMultiplier);
584 return (minNbBits+1)*bitMultiplier - normalizedDeltaFromThreshold;
585 }
586}
587
588
589/* ====== Decompression ====== */
590
591typedef struct {
592 U16 tableLog;
593 U16 fastMode;
594} FSE_DTableHeader; /* sizeof U32 */
595
596typedef struct
597{
598 unsigned short newState;
599 unsigned char symbol;
600 unsigned char nbBits;
601} FSE_decode_t; /* size == U32 */
602
603MEM_STATIC void FSE_initDState(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD, const FSE_DTable* dt)
604{
605 const void* ptr = dt;
606 const FSE_DTableHeader* const DTableH = (const FSE_DTableHeader*)ptr;
607 DStatePtr->state = BIT_readBits(bitD, DTableH->tableLog);
608 BIT_reloadDStream(bitD);
609 DStatePtr->table = dt + 1;
610}
611
612MEM_STATIC BYTE FSE_peekSymbol(const FSE_DState_t* DStatePtr)
613{
614 FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state];
615 return DInfo.symbol;
616}
617
618MEM_STATIC void FSE_updateState(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD)
619{
620 FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state];
621 U32 const nbBits = DInfo.nbBits;
622 size_t const lowBits = BIT_readBits(bitD, nbBits);
623 DStatePtr->state = DInfo.newState + lowBits;
624}
625
626MEM_STATIC BYTE FSE_decodeSymbol(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD)
627{
628 FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state];
629 U32 const nbBits = DInfo.nbBits;
630 BYTE const symbol = DInfo.symbol;
631 size_t const lowBits = BIT_readBits(bitD, nbBits);
632
633 DStatePtr->state = DInfo.newState + lowBits;
634 return symbol;
635}
636
637/*! FSE_decodeSymbolFast() :
638 unsafe, only works if no symbol has a probability > 50% */
639MEM_STATIC BYTE FSE_decodeSymbolFast(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD)
640{
641 FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state];
642 U32 const nbBits = DInfo.nbBits;
643 BYTE const symbol = DInfo.symbol;
644 size_t const lowBits = BIT_readBitsFast(bitD, nbBits);
645
646 DStatePtr->state = DInfo.newState + lowBits;
647 return symbol;
648}
649
650MEM_STATIC unsigned FSE_endOfDState(const FSE_DState_t* DStatePtr)
651{
652 return DStatePtr->state == 0;
653}
654
655
656
657#ifndef FSE_COMMONDEFS_ONLY
658
659/* **************************************************************
660* Tuning parameters
661****************************************************************/
662/*!MEMORY_USAGE :
663* Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; etc.)
664* Increasing memory usage improves compression ratio
665* Reduced memory usage can improve speed, due to cache effect
666* Recommended max value is 14, for 16KB, which nicely fits into Intel x86 L1 cache */
667#ifndef FSE_MAX_MEMORY_USAGE
668# define FSE_MAX_MEMORY_USAGE 14
669#endif
670#ifndef FSE_DEFAULT_MEMORY_USAGE
671# define FSE_DEFAULT_MEMORY_USAGE 13
672#endif
673#if (FSE_DEFAULT_MEMORY_USAGE > FSE_MAX_MEMORY_USAGE)
674# error "FSE_DEFAULT_MEMORY_USAGE must be <= FSE_MAX_MEMORY_USAGE"
675#endif
676
677/*!FSE_MAX_SYMBOL_VALUE :
678* Maximum symbol value authorized.
679* Required for proper stack allocation */
680#ifndef FSE_MAX_SYMBOL_VALUE
681# define FSE_MAX_SYMBOL_VALUE 255
682#endif
683
684/* **************************************************************
685* template functions type & suffix
686****************************************************************/
687#define FSE_FUNCTION_TYPE BYTE
688#define FSE_FUNCTION_EXTENSION
689#define FSE_DECODE_TYPE FSE_decode_t
690
691
692#endif /* !FSE_COMMONDEFS_ONLY */
693
694
695/* ***************************************************************
696* Constants
697*****************************************************************/
698#define FSE_MAX_TABLELOG (FSE_MAX_MEMORY_USAGE-2)
699#define FSE_MAX_TABLESIZE (1U<<FSE_MAX_TABLELOG)
700#define FSE_MAXTABLESIZE_MASK (FSE_MAX_TABLESIZE-1)
701#define FSE_DEFAULT_TABLELOG (FSE_DEFAULT_MEMORY_USAGE-2)
702#define FSE_MIN_TABLELOG 5
703
704#define FSE_TABLELOG_ABSOLUTE_MAX 15
705#if FSE_MAX_TABLELOG > FSE_TABLELOG_ABSOLUTE_MAX
706# error "FSE_MAX_TABLELOG > FSE_TABLELOG_ABSOLUTE_MAX is not supported"
707#endif
708
709#define FSE_TABLESTEP(tableSize) (((tableSize)>>1) + ((tableSize)>>3) + 3)
710
711
712#endif /* FSE_STATIC_LINKING_ONLY */
713
714
715#if defined (__cplusplus)
716}
717#endif
stage1/zstd/lib/common/fse_decompress.c created+403
......@@ -0,0 +1,403 @@
1/* ******************************************************************
2 * FSE : Finite State Entropy decoder
3 * Copyright (c) Yann Collet, Facebook, Inc.
4 *
5 * You can contact the author at :
6 * - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy
7 * - Public forum : https://groups.google.com/forum/#!forum/lz4c
8 *
9 * This source code is licensed under both the BSD-style license (found in the
10 * LICENSE file in the root directory of this source tree) and the GPLv2 (found
11 * in the COPYING file in the root directory of this source tree).
12 * You may select, at your option, one of the above-listed licenses.
13****************************************************************** */
14
15
16/* **************************************************************
17* Includes
18****************************************************************/
19#include "debug.h" /* assert */
20#include "bitstream.h"
21#include "compiler.h"
22#define FSE_STATIC_LINKING_ONLY
23#include "fse.h"
24#include "error_private.h"
25#define ZSTD_DEPS_NEED_MALLOC
26#include "zstd_deps.h"
27
28
29/* **************************************************************
30* Error Management
31****************************************************************/
32#define FSE_isError ERR_isError
33#define FSE_STATIC_ASSERT(c) DEBUG_STATIC_ASSERT(c) /* use only *after* variable declarations */
34
35
36/* **************************************************************
37* Templates
38****************************************************************/
39/*
40 designed to be included
41 for type-specific functions (template emulation in C)
42 Objective is to write these functions only once, for improved maintenance
43*/
44
45/* safety checks */
46#ifndef FSE_FUNCTION_EXTENSION
47# error "FSE_FUNCTION_EXTENSION must be defined"
48#endif
49#ifndef FSE_FUNCTION_TYPE
50# error "FSE_FUNCTION_TYPE must be defined"
51#endif
52
53/* Function names */
54#define FSE_CAT(X,Y) X##Y
55#define FSE_FUNCTION_NAME(X,Y) FSE_CAT(X,Y)
56#define FSE_TYPE_NAME(X,Y) FSE_CAT(X,Y)
57
58
59/* Function templates */
60FSE_DTable* FSE_createDTable (unsigned tableLog)
61{
62 if (tableLog > FSE_TABLELOG_ABSOLUTE_MAX) tableLog = FSE_TABLELOG_ABSOLUTE_MAX;
63 return (FSE_DTable*)ZSTD_malloc( FSE_DTABLE_SIZE_U32(tableLog) * sizeof (U32) );
64}
65
66void FSE_freeDTable (FSE_DTable* dt)
67{
68 ZSTD_free(dt);
69}
70
71static size_t FSE_buildDTable_internal(FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize)
72{
73 void* const tdPtr = dt+1; /* because *dt is unsigned, 32-bits aligned on 32-bits */
74 FSE_DECODE_TYPE* const tableDecode = (FSE_DECODE_TYPE*) (tdPtr);
75 U16* symbolNext = (U16*)workSpace;
76 BYTE* spread = (BYTE*)(symbolNext + maxSymbolValue + 1);
77
78 U32 const maxSV1 = maxSymbolValue + 1;
79 U32 const tableSize = 1 << tableLog;
80 U32 highThreshold = tableSize-1;
81
82 /* Sanity Checks */
83 if (FSE_BUILD_DTABLE_WKSP_SIZE(tableLog, maxSymbolValue) > wkspSize) return ERROR(maxSymbolValue_tooLarge);
84 if (maxSymbolValue > FSE_MAX_SYMBOL_VALUE) return ERROR(maxSymbolValue_tooLarge);
85 if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge);
86
87 /* Init, lay down lowprob symbols */
88 { FSE_DTableHeader DTableH;
89 DTableH.tableLog = (U16)tableLog;
90 DTableH.fastMode = 1;
91 { S16 const largeLimit= (S16)(1 << (tableLog-1));
92 U32 s;
93 for (s=0; s<maxSV1; s++) {
94 if (normalizedCounter[s]==-1) {
95 tableDecode[highThreshold--].symbol = (FSE_FUNCTION_TYPE)s;
96 symbolNext[s] = 1;
97 } else {
98 if (normalizedCounter[s] >= largeLimit) DTableH.fastMode=0;
99 symbolNext[s] = normalizedCounter[s];
100 } } }
101 ZSTD_memcpy(dt, &DTableH, sizeof(DTableH));
102 }
103
104 /* Spread symbols */
105 if (highThreshold == tableSize - 1) {
106 size_t const tableMask = tableSize-1;
107 size_t const step = FSE_TABLESTEP(tableSize);
108 /* First lay down the symbols in order.
109 * We use a uint64_t to lay down 8 bytes at a time. This reduces branch
110 * misses since small blocks generally have small table logs, so nearly
111 * all symbols have counts <= 8. We ensure we have 8 bytes at the end of
112 * our buffer to handle the over-write.
113 */
114 {
115 U64 const add = 0x0101010101010101ull;
116 size_t pos = 0;
117 U64 sv = 0;
118 U32 s;
119 for (s=0; s<maxSV1; ++s, sv += add) {
120 int i;
121 int const n = normalizedCounter[s];
122 MEM_write64(spread + pos, sv);
123 for (i = 8; i < n; i += 8) {
124 MEM_write64(spread + pos + i, sv);
125 }
126 pos += n;
127 }
128 }
129 /* Now we spread those positions across the table.
130 * The benefit of doing it in two stages is that we avoid the the
131 * variable size inner loop, which caused lots of branch misses.
132 * Now we can run through all the positions without any branch misses.
133 * We unroll the loop twice, since that is what emperically worked best.
134 */
135 {
136 size_t position = 0;
137 size_t s;
138 size_t const unroll = 2;
139 assert(tableSize % unroll == 0); /* FSE_MIN_TABLELOG is 5 */
140 for (s = 0; s < (size_t)tableSize; s += unroll) {
141 size_t u;
142 for (u = 0; u < unroll; ++u) {
143 size_t const uPosition = (position + (u * step)) & tableMask;
144 tableDecode[uPosition].symbol = spread[s + u];
145 }
146 position = (position + (unroll * step)) & tableMask;
147 }
148 assert(position == 0);
149 }
150 } else {
151 U32 const tableMask = tableSize-1;
152 U32 const step = FSE_TABLESTEP(tableSize);
153 U32 s, position = 0;
154 for (s=0; s<maxSV1; s++) {
155 int i;
156 for (i=0; i<normalizedCounter[s]; i++) {
157 tableDecode[position].symbol = (FSE_FUNCTION_TYPE)s;
158 position = (position + step) & tableMask;
159 while (position > highThreshold) position = (position + step) & tableMask; /* lowprob area */
160 } }
161 if (position!=0) return ERROR(GENERIC); /* position must reach all cells once, otherwise normalizedCounter is incorrect */
162 }
163
164 /* Build Decoding table */
165 { U32 u;
166 for (u=0; u<tableSize; u++) {
167 FSE_FUNCTION_TYPE const symbol = (FSE_FUNCTION_TYPE)(tableDecode[u].symbol);
168 U32 const nextState = symbolNext[symbol]++;
169 tableDecode[u].nbBits = (BYTE) (tableLog - BIT_highbit32(nextState) );
170 tableDecode[u].newState = (U16) ( (nextState << tableDecode[u].nbBits) - tableSize);
171 } }
172
173 return 0;
174}
175
176size_t FSE_buildDTable_wksp(FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize)
177{
178 return FSE_buildDTable_internal(dt, normalizedCounter, maxSymbolValue, tableLog, workSpace, wkspSize);
179}
180
181
182#ifndef FSE_COMMONDEFS_ONLY
183
184/*-*******************************************************
185* Decompression (Byte symbols)
186*********************************************************/
187size_t FSE_buildDTable_rle (FSE_DTable* dt, BYTE symbolValue)
188{
189 void* ptr = dt;
190 FSE_DTableHeader* const DTableH = (FSE_DTableHeader*)ptr;
191 void* dPtr = dt + 1;
192 FSE_decode_t* const cell = (FSE_decode_t*)dPtr;
193
194 DTableH->tableLog = 0;
195 DTableH->fastMode = 0;
196
197 cell->newState = 0;
198 cell->symbol = symbolValue;
199 cell->nbBits = 0;
200
201 return 0;
202}
203
204
205size_t FSE_buildDTable_raw (FSE_DTable* dt, unsigned nbBits)
206{
207 void* ptr = dt;
208 FSE_DTableHeader* const DTableH = (FSE_DTableHeader*)ptr;
209 void* dPtr = dt + 1;
210 FSE_decode_t* const dinfo = (FSE_decode_t*)dPtr;
211 const unsigned tableSize = 1 << nbBits;
212 const unsigned tableMask = tableSize - 1;
213 const unsigned maxSV1 = tableMask+1;
214 unsigned s;
215
216 /* Sanity checks */
217 if (nbBits < 1) return ERROR(GENERIC); /* min size */
218
219 /* Build Decoding Table */
220 DTableH->tableLog = (U16)nbBits;
221 DTableH->fastMode = 1;
222 for (s=0; s<maxSV1; s++) {
223 dinfo[s].newState = 0;
224 dinfo[s].symbol = (BYTE)s;
225 dinfo[s].nbBits = (BYTE)nbBits;
226 }
227
228 return 0;
229}
230
231FORCE_INLINE_TEMPLATE size_t FSE_decompress_usingDTable_generic(
232 void* dst, size_t maxDstSize,
233 const void* cSrc, size_t cSrcSize,
234 const FSE_DTable* dt, const unsigned fast)
235{
236 BYTE* const ostart = (BYTE*) dst;
237 BYTE* op = ostart;
238 BYTE* const omax = op + maxDstSize;
239 BYTE* const olimit = omax-3;
240
241 BIT_DStream_t bitD;
242 FSE_DState_t state1;
243 FSE_DState_t state2;
244
245 /* Init */
246 CHECK_F(BIT_initDStream(&bitD, cSrc, cSrcSize));
247
248 FSE_initDState(&state1, &bitD, dt);
249 FSE_initDState(&state2, &bitD, dt);
250
251#define FSE_GETSYMBOL(statePtr) fast ? FSE_decodeSymbolFast(statePtr, &bitD) : FSE_decodeSymbol(statePtr, &bitD)
252
253 /* 4 symbols per loop */
254 for ( ; (BIT_reloadDStream(&bitD)==BIT_DStream_unfinished) & (op<olimit) ; op+=4) {
255 op[0] = FSE_GETSYMBOL(&state1);
256
257 if (FSE_MAX_TABLELOG*2+7 > sizeof(bitD.bitContainer)*8) /* This test must be static */
258 BIT_reloadDStream(&bitD);
259
260 op[1] = FSE_GETSYMBOL(&state2);
261
262 if (FSE_MAX_TABLELOG*4+7 > sizeof(bitD.bitContainer)*8) /* This test must be static */
263 { if (BIT_reloadDStream(&bitD) > BIT_DStream_unfinished) { op+=2; break; } }
264
265 op[2] = FSE_GETSYMBOL(&state1);
266
267 if (FSE_MAX_TABLELOG*2+7 > sizeof(bitD.bitContainer)*8) /* This test must be static */
268 BIT_reloadDStream(&bitD);
269
270 op[3] = FSE_GETSYMBOL(&state2);
271 }
272
273 /* tail */
274 /* note : BIT_reloadDStream(&bitD) >= FSE_DStream_partiallyFilled; Ends at exactly BIT_DStream_completed */
275 while (1) {
276 if (op>(omax-2)) return ERROR(dstSize_tooSmall);
277 *op++ = FSE_GETSYMBOL(&state1);
278 if (BIT_reloadDStream(&bitD)==BIT_DStream_overflow) {
279 *op++ = FSE_GETSYMBOL(&state2);
280 break;
281 }
282
283 if (op>(omax-2)) return ERROR(dstSize_tooSmall);
284 *op++ = FSE_GETSYMBOL(&state2);
285 if (BIT_reloadDStream(&bitD)==BIT_DStream_overflow) {
286 *op++ = FSE_GETSYMBOL(&state1);
287 break;
288 } }
289
290 return op-ostart;
291}
292
293
294size_t FSE_decompress_usingDTable(void* dst, size_t originalSize,
295 const void* cSrc, size_t cSrcSize,
296 const FSE_DTable* dt)
297{
298 const void* ptr = dt;
299 const FSE_DTableHeader* DTableH = (const FSE_DTableHeader*)ptr;
300 const U32 fastMode = DTableH->fastMode;
301
302 /* select fast mode (static) */
303 if (fastMode) return FSE_decompress_usingDTable_generic(dst, originalSize, cSrc, cSrcSize, dt, 1);
304 return FSE_decompress_usingDTable_generic(dst, originalSize, cSrc, cSrcSize, dt, 0);
305}
306
307
308size_t FSE_decompress_wksp(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, unsigned maxLog, void* workSpace, size_t wkspSize)
309{
310 return FSE_decompress_wksp_bmi2(dst, dstCapacity, cSrc, cSrcSize, maxLog, workSpace, wkspSize, /* bmi2 */ 0);
311}
312
313typedef struct {
314 short ncount[FSE_MAX_SYMBOL_VALUE + 1];
315 FSE_DTable dtable[1]; /* Dynamically sized */
316} FSE_DecompressWksp;
317
318
319FORCE_INLINE_TEMPLATE size_t FSE_decompress_wksp_body(
320 void* dst, size_t dstCapacity,
321 const void* cSrc, size_t cSrcSize,
322 unsigned maxLog, void* workSpace, size_t wkspSize,
323 int bmi2)
324{
325 const BYTE* const istart = (const BYTE*)cSrc;
326 const BYTE* ip = istart;
327 unsigned tableLog;
328 unsigned maxSymbolValue = FSE_MAX_SYMBOL_VALUE;
329 FSE_DecompressWksp* const wksp = (FSE_DecompressWksp*)workSpace;
330
331 DEBUG_STATIC_ASSERT((FSE_MAX_SYMBOL_VALUE + 1) % 2 == 0);
332 if (wkspSize < sizeof(*wksp)) return ERROR(GENERIC);
333
334 /* normal FSE decoding mode */
335 {
336 size_t const NCountLength = FSE_readNCount_bmi2(wksp->ncount, &maxSymbolValue, &tableLog, istart, cSrcSize, bmi2);
337 if (FSE_isError(NCountLength)) return NCountLength;
338 if (tableLog > maxLog) return ERROR(tableLog_tooLarge);
339 assert(NCountLength <= cSrcSize);
340 ip += NCountLength;
341 cSrcSize -= NCountLength;
342 }
343
344 if (FSE_DECOMPRESS_WKSP_SIZE(tableLog, maxSymbolValue) > wkspSize) return ERROR(tableLog_tooLarge);
345 workSpace = wksp->dtable + FSE_DTABLE_SIZE_U32(tableLog);
346 wkspSize -= sizeof(*wksp) + FSE_DTABLE_SIZE(tableLog);
347
348 CHECK_F( FSE_buildDTable_internal(wksp->dtable, wksp->ncount, maxSymbolValue, tableLog, workSpace, wkspSize) );
349
350 {
351 const void* ptr = wksp->dtable;
352 const FSE_DTableHeader* DTableH = (const FSE_DTableHeader*)ptr;
353 const U32 fastMode = DTableH->fastMode;
354
355 /* select fast mode (static) */
356 if (fastMode) return FSE_decompress_usingDTable_generic(dst, dstCapacity, ip, cSrcSize, wksp->dtable, 1);
357 return FSE_decompress_usingDTable_generic(dst, dstCapacity, ip, cSrcSize, wksp->dtable, 0);
358 }
359}
360
361/* Avoids the FORCE_INLINE of the _body() function. */
362static size_t FSE_decompress_wksp_body_default(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, unsigned maxLog, void* workSpace, size_t wkspSize)
363{
364 return FSE_decompress_wksp_body(dst, dstCapacity, cSrc, cSrcSize, maxLog, workSpace, wkspSize, 0);
365}
366
367#if DYNAMIC_BMI2
368BMI2_TARGET_ATTRIBUTE static size_t FSE_decompress_wksp_body_bmi2(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, unsigned maxLog, void* workSpace, size_t wkspSize)
369{
370 return FSE_decompress_wksp_body(dst, dstCapacity, cSrc, cSrcSize, maxLog, workSpace, wkspSize, 1);
371}
372#endif
373
374size_t FSE_decompress_wksp_bmi2(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, unsigned maxLog, void* workSpace, size_t wkspSize, int bmi2)
375{
376#if DYNAMIC_BMI2
377 if (bmi2) {
378 return FSE_decompress_wksp_body_bmi2(dst, dstCapacity, cSrc, cSrcSize, maxLog, workSpace, wkspSize);
379 }
380#endif
381 (void)bmi2;
382 return FSE_decompress_wksp_body_default(dst, dstCapacity, cSrc, cSrcSize, maxLog, workSpace, wkspSize);
383}
384
385
386typedef FSE_DTable DTable_max_t[FSE_DTABLE_SIZE_U32(FSE_MAX_TABLELOG)];
387
388#ifndef ZSTD_NO_UNUSED_FUNCTIONS
389size_t FSE_buildDTable(FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog) {
390 U32 wksp[FSE_BUILD_DTABLE_WKSP_SIZE_U32(FSE_TABLELOG_ABSOLUTE_MAX, FSE_MAX_SYMBOL_VALUE)];
391 return FSE_buildDTable_wksp(dt, normalizedCounter, maxSymbolValue, tableLog, wksp, sizeof(wksp));
392}
393
394size_t FSE_decompress(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize)
395{
396 /* Static analyzer seems unable to understand this table will be properly initialized later */
397 U32 wksp[FSE_DECOMPRESS_WKSP_SIZE_U32(FSE_MAX_TABLELOG, FSE_MAX_SYMBOL_VALUE)];
398 return FSE_decompress_wksp(dst, dstCapacity, cSrc, cSrcSize, FSE_MAX_TABLELOG, wksp, sizeof(wksp));
399}
400#endif
401
402
403#endif /* FSE_COMMONDEFS_ONLY */
stage1/zstd/lib/common/huf.h created+364
......@@ -0,0 +1,364 @@
1/* ******************************************************************
2 * huff0 huffman codec,
3 * part of Finite State Entropy library
4 * Copyright (c) Yann Collet, Facebook, Inc.
5 *
6 * You can contact the author at :
7 * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
8 *
9 * This source code is licensed under both the BSD-style license (found in the
10 * LICENSE file in the root directory of this source tree) and the GPLv2 (found
11 * in the COPYING file in the root directory of this source tree).
12 * You may select, at your option, one of the above-listed licenses.
13****************************************************************** */
14
15#if defined (__cplusplus)
16extern "C" {
17#endif
18
19#ifndef HUF_H_298734234
20#define HUF_H_298734234
21
22/* *** Dependencies *** */
23#include "zstd_deps.h" /* size_t */
24
25
26/* *** library symbols visibility *** */
27/* Note : when linking with -fvisibility=hidden on gcc, or by default on Visual,
28 * HUF symbols remain "private" (internal symbols for library only).
29 * Set macro FSE_DLL_EXPORT to 1 if you want HUF symbols visible on DLL interface */
30#if defined(FSE_DLL_EXPORT) && (FSE_DLL_EXPORT==1) && defined(__GNUC__) && (__GNUC__ >= 4)
31# define HUF_PUBLIC_API __attribute__ ((visibility ("default")))
32#elif defined(FSE_DLL_EXPORT) && (FSE_DLL_EXPORT==1) /* Visual expected */
33# define HUF_PUBLIC_API __declspec(dllexport)
34#elif defined(FSE_DLL_IMPORT) && (FSE_DLL_IMPORT==1)
35# define HUF_PUBLIC_API __declspec(dllimport) /* not required, just to generate faster code (saves a function pointer load from IAT and an indirect jump) */
36#else
37# define HUF_PUBLIC_API
38#endif
39
40
41/* ========================== */
42/* *** simple functions *** */
43/* ========================== */
44
45/** HUF_compress() :
46 * Compress content from buffer 'src', of size 'srcSize', into buffer 'dst'.
47 * 'dst' buffer must be already allocated.
48 * Compression runs faster if `dstCapacity` >= HUF_compressBound(srcSize).
49 * `srcSize` must be <= `HUF_BLOCKSIZE_MAX` == 128 KB.
50 * @return : size of compressed data (<= `dstCapacity`).
51 * Special values : if return == 0, srcData is not compressible => Nothing is stored within dst !!!
52 * if HUF_isError(return), compression failed (more details using HUF_getErrorName())
53 */
54HUF_PUBLIC_API size_t HUF_compress(void* dst, size_t dstCapacity,
55 const void* src, size_t srcSize);
56
57/** HUF_decompress() :
58 * Decompress HUF data from buffer 'cSrc', of size 'cSrcSize',
59 * into already allocated buffer 'dst', of minimum size 'dstSize'.
60 * `originalSize` : **must** be the ***exact*** size of original (uncompressed) data.
61 * Note : in contrast with FSE, HUF_decompress can regenerate
62 * RLE (cSrcSize==1) and uncompressed (cSrcSize==dstSize) data,
63 * because it knows size to regenerate (originalSize).
64 * @return : size of regenerated data (== originalSize),
65 * or an error code, which can be tested using HUF_isError()
66 */
67HUF_PUBLIC_API size_t HUF_decompress(void* dst, size_t originalSize,
68 const void* cSrc, size_t cSrcSize);
69
70
71/* *** Tool functions *** */
72#define HUF_BLOCKSIZE_MAX (128 * 1024) /**< maximum input size for a single block compressed with HUF_compress */
73HUF_PUBLIC_API size_t HUF_compressBound(size_t size); /**< maximum compressed size (worst case) */
74
75/* Error Management */
76HUF_PUBLIC_API unsigned HUF_isError(size_t code); /**< tells if a return value is an error code */
77HUF_PUBLIC_API const char* HUF_getErrorName(size_t code); /**< provides error code string (useful for debugging) */
78
79
80/* *** Advanced function *** */
81
82/** HUF_compress2() :
83 * Same as HUF_compress(), but offers control over `maxSymbolValue` and `tableLog`.
84 * `maxSymbolValue` must be <= HUF_SYMBOLVALUE_MAX .
85 * `tableLog` must be `<= HUF_TABLELOG_MAX` . */
86HUF_PUBLIC_API size_t HUF_compress2 (void* dst, size_t dstCapacity,
87 const void* src, size_t srcSize,
88 unsigned maxSymbolValue, unsigned tableLog);
89
90/** HUF_compress4X_wksp() :
91 * Same as HUF_compress2(), but uses externally allocated `workSpace`.
92 * `workspace` must be at least as large as HUF_WORKSPACE_SIZE */
93#define HUF_WORKSPACE_SIZE ((8 << 10) + 512 /* sorting scratch space */)
94#define HUF_WORKSPACE_SIZE_U64 (HUF_WORKSPACE_SIZE / sizeof(U64))
95HUF_PUBLIC_API size_t HUF_compress4X_wksp (void* dst, size_t dstCapacity,
96 const void* src, size_t srcSize,
97 unsigned maxSymbolValue, unsigned tableLog,
98 void* workSpace, size_t wkspSize);
99
100#endif /* HUF_H_298734234 */
101
102/* ******************************************************************
103 * WARNING !!
104 * The following section contains advanced and experimental definitions
105 * which shall never be used in the context of a dynamic library,
106 * because they are not guaranteed to remain stable in the future.
107 * Only consider them in association with static linking.
108 * *****************************************************************/
109#if defined(HUF_STATIC_LINKING_ONLY) && !defined(HUF_H_HUF_STATIC_LINKING_ONLY)
110#define HUF_H_HUF_STATIC_LINKING_ONLY
111
112/* *** Dependencies *** */
113#include "mem.h" /* U32 */
114#define FSE_STATIC_LINKING_ONLY
115#include "fse.h"
116
117
118/* *** Constants *** */
119#define HUF_TABLELOG_MAX 12 /* max runtime value of tableLog (due to static allocation); can be modified up to HUF_TABLELOG_ABSOLUTEMAX */
120#define HUF_TABLELOG_DEFAULT 11 /* default tableLog value when none specified */
121#define HUF_SYMBOLVALUE_MAX 255
122
123#define HUF_TABLELOG_ABSOLUTEMAX 12 /* absolute limit of HUF_MAX_TABLELOG. Beyond that value, code does not work */
124#if (HUF_TABLELOG_MAX > HUF_TABLELOG_ABSOLUTEMAX)
125# error "HUF_TABLELOG_MAX is too large !"
126#endif
127
128
129/* ****************************************
130* Static allocation
131******************************************/
132/* HUF buffer bounds */
133#define HUF_CTABLEBOUND 129
134#define HUF_BLOCKBOUND(size) (size + (size>>8) + 8) /* only true when incompressible is pre-filtered with fast heuristic */
135#define HUF_COMPRESSBOUND(size) (HUF_CTABLEBOUND + HUF_BLOCKBOUND(size)) /* Macro version, useful for static allocation */
136
137/* static allocation of HUF's Compression Table */
138/* this is a private definition, just exposed for allocation and strict aliasing purpose. never EVER access its members directly */
139typedef size_t HUF_CElt; /* consider it an incomplete type */
140#define HUF_CTABLE_SIZE_ST(maxSymbolValue) ((maxSymbolValue)+2) /* Use tables of size_t, for proper alignment */
141#define HUF_CTABLE_SIZE(maxSymbolValue) (HUF_CTABLE_SIZE_ST(maxSymbolValue) * sizeof(size_t))
142#define HUF_CREATE_STATIC_CTABLE(name, maxSymbolValue) \
143 HUF_CElt name[HUF_CTABLE_SIZE_ST(maxSymbolValue)] /* no final ; */
144
145/* static allocation of HUF's DTable */
146typedef U32 HUF_DTable;
147#define HUF_DTABLE_SIZE(maxTableLog) (1 + (1<<(maxTableLog)))
148#define HUF_CREATE_STATIC_DTABLEX1(DTable, maxTableLog) \
149 HUF_DTable DTable[HUF_DTABLE_SIZE((maxTableLog)-1)] = { ((U32)((maxTableLog)-1) * 0x01000001) }
150#define HUF_CREATE_STATIC_DTABLEX2(DTable, maxTableLog) \
151 HUF_DTable DTable[HUF_DTABLE_SIZE(maxTableLog)] = { ((U32)(maxTableLog) * 0x01000001) }
152
153
154/* ****************************************
155* Advanced decompression functions
156******************************************/
157size_t HUF_decompress4X1 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< single-symbol decoder */
158#ifndef HUF_FORCE_DECOMPRESS_X1
159size_t HUF_decompress4X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< double-symbols decoder */
160#endif
161
162size_t HUF_decompress4X_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< decodes RLE and uncompressed */
163size_t HUF_decompress4X_hufOnly(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< considers RLE and uncompressed as errors */
164size_t HUF_decompress4X_hufOnly_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize); /**< considers RLE and uncompressed as errors */
165size_t HUF_decompress4X1_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< single-symbol decoder */
166size_t HUF_decompress4X1_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize); /**< single-symbol decoder */
167#ifndef HUF_FORCE_DECOMPRESS_X1
168size_t HUF_decompress4X2_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< double-symbols decoder */
169size_t HUF_decompress4X2_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize); /**< double-symbols decoder */
170#endif
171
172
173/* ****************************************
174 * HUF detailed API
175 * ****************************************/
176
177/*! HUF_compress() does the following:
178 * 1. count symbol occurrence from source[] into table count[] using FSE_count() (exposed within "fse.h")
179 * 2. (optional) refine tableLog using HUF_optimalTableLog()
180 * 3. build Huffman table from count using HUF_buildCTable()
181 * 4. save Huffman table to memory buffer using HUF_writeCTable()
182 * 5. encode the data stream using HUF_compress4X_usingCTable()
183 *
184 * The following API allows targeting specific sub-functions for advanced tasks.
185 * For example, it's possible to compress several blocks using the same 'CTable',
186 * or to save and regenerate 'CTable' using external methods.
187 */
188unsigned HUF_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue);
189size_t HUF_buildCTable (HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue, unsigned maxNbBits); /* @return : maxNbBits; CTable and count can overlap. In which case, CTable will overwrite count content */
190size_t HUF_writeCTable (void* dst, size_t maxDstSize, const HUF_CElt* CTable, unsigned maxSymbolValue, unsigned huffLog);
191size_t HUF_writeCTable_wksp(void* dst, size_t maxDstSize, const HUF_CElt* CTable, unsigned maxSymbolValue, unsigned huffLog, void* workspace, size_t workspaceSize);
192size_t HUF_compress4X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable);
193size_t HUF_compress4X_usingCTable_bmi2(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable, int bmi2);
194size_t HUF_estimateCompressedSize(const HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue);
195int HUF_validateCTable(const HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue);
196
197typedef enum {
198 HUF_repeat_none, /**< Cannot use the previous table */
199 HUF_repeat_check, /**< Can use the previous table but it must be checked. Note : The previous table must have been constructed by HUF_compress{1, 4}X_repeat */
200 HUF_repeat_valid /**< Can use the previous table and it is assumed to be valid */
201 } HUF_repeat;
202/** HUF_compress4X_repeat() :
203 * Same as HUF_compress4X_wksp(), but considers using hufTable if *repeat != HUF_repeat_none.
204 * If it uses hufTable it does not modify hufTable or repeat.
205 * If it doesn't, it sets *repeat = HUF_repeat_none, and it sets hufTable to the table used.
206 * If preferRepeat then the old table will always be used if valid.
207 * If suspectUncompressible then some sampling checks will be run to potentially skip huffman coding */
208size_t HUF_compress4X_repeat(void* dst, size_t dstSize,
209 const void* src, size_t srcSize,
210 unsigned maxSymbolValue, unsigned tableLog,
211 void* workSpace, size_t wkspSize, /**< `workSpace` must be aligned on 4-bytes boundaries, `wkspSize` must be >= HUF_WORKSPACE_SIZE */
212 HUF_CElt* hufTable, HUF_repeat* repeat, int preferRepeat, int bmi2, unsigned suspectUncompressible);
213
214/** HUF_buildCTable_wksp() :
215 * Same as HUF_buildCTable(), but using externally allocated scratch buffer.
216 * `workSpace` must be aligned on 4-bytes boundaries, and its size must be >= HUF_CTABLE_WORKSPACE_SIZE.
217 */
218#define HUF_CTABLE_WORKSPACE_SIZE_U32 (2*HUF_SYMBOLVALUE_MAX +1 +1)
219#define HUF_CTABLE_WORKSPACE_SIZE (HUF_CTABLE_WORKSPACE_SIZE_U32 * sizeof(unsigned))
220size_t HUF_buildCTable_wksp (HUF_CElt* tree,
221 const unsigned* count, U32 maxSymbolValue, U32 maxNbBits,
222 void* workSpace, size_t wkspSize);
223
224/*! HUF_readStats() :
225 * Read compact Huffman tree, saved by HUF_writeCTable().
226 * `huffWeight` is destination buffer.
227 * @return : size read from `src` , or an error Code .
228 * Note : Needed by HUF_readCTable() and HUF_readDTableXn() . */
229size_t HUF_readStats(BYTE* huffWeight, size_t hwSize,
230 U32* rankStats, U32* nbSymbolsPtr, U32* tableLogPtr,
231 const void* src, size_t srcSize);
232
233/*! HUF_readStats_wksp() :
234 * Same as HUF_readStats() but takes an external workspace which must be
235 * 4-byte aligned and its size must be >= HUF_READ_STATS_WORKSPACE_SIZE.
236 * If the CPU has BMI2 support, pass bmi2=1, otherwise pass bmi2=0.
237 */
238#define HUF_READ_STATS_WORKSPACE_SIZE_U32 FSE_DECOMPRESS_WKSP_SIZE_U32(6, HUF_TABLELOG_MAX-1)
239#define HUF_READ_STATS_WORKSPACE_SIZE (HUF_READ_STATS_WORKSPACE_SIZE_U32 * sizeof(unsigned))
240size_t HUF_readStats_wksp(BYTE* huffWeight, size_t hwSize,
241 U32* rankStats, U32* nbSymbolsPtr, U32* tableLogPtr,
242 const void* src, size_t srcSize,
243 void* workspace, size_t wkspSize,
244 int bmi2);
245
246/** HUF_readCTable() :
247 * Loading a CTable saved with HUF_writeCTable() */
248size_t HUF_readCTable (HUF_CElt* CTable, unsigned* maxSymbolValuePtr, const void* src, size_t srcSize, unsigned *hasZeroWeights);
249
250/** HUF_getNbBitsFromCTable() :
251 * Read nbBits from CTable symbolTable, for symbol `symbolValue` presumed <= HUF_SYMBOLVALUE_MAX
252 * Note 1 : is not inlined, as HUF_CElt definition is private */
253U32 HUF_getNbBitsFromCTable(const HUF_CElt* symbolTable, U32 symbolValue);
254
255/*
256 * HUF_decompress() does the following:
257 * 1. select the decompression algorithm (X1, X2) based on pre-computed heuristics
258 * 2. build Huffman table from save, using HUF_readDTableX?()
259 * 3. decode 1 or 4 segments in parallel using HUF_decompress?X?_usingDTable()
260 */
261
262/** HUF_selectDecoder() :
263 * Tells which decoder is likely to decode faster,
264 * based on a set of pre-computed metrics.
265 * @return : 0==HUF_decompress4X1, 1==HUF_decompress4X2 .
266 * Assumption : 0 < dstSize <= 128 KB */
267U32 HUF_selectDecoder (size_t dstSize, size_t cSrcSize);
268
269/**
270 * The minimum workspace size for the `workSpace` used in
271 * HUF_readDTableX1_wksp() and HUF_readDTableX2_wksp().
272 *
273 * The space used depends on HUF_TABLELOG_MAX, ranging from ~1500 bytes when
274 * HUF_TABLE_LOG_MAX=12 to ~1850 bytes when HUF_TABLE_LOG_MAX=15.
275 * Buffer overflow errors may potentially occur if code modifications result in
276 * a required workspace size greater than that specified in the following
277 * macro.
278 */
279#define HUF_DECOMPRESS_WORKSPACE_SIZE ((2 << 10) + (1 << 9))
280#define HUF_DECOMPRESS_WORKSPACE_SIZE_U32 (HUF_DECOMPRESS_WORKSPACE_SIZE / sizeof(U32))
281
282#ifndef HUF_FORCE_DECOMPRESS_X2
283size_t HUF_readDTableX1 (HUF_DTable* DTable, const void* src, size_t srcSize);
284size_t HUF_readDTableX1_wksp (HUF_DTable* DTable, const void* src, size_t srcSize, void* workSpace, size_t wkspSize);
285#endif
286#ifndef HUF_FORCE_DECOMPRESS_X1
287size_t HUF_readDTableX2 (HUF_DTable* DTable, const void* src, size_t srcSize);
288size_t HUF_readDTableX2_wksp (HUF_DTable* DTable, const void* src, size_t srcSize, void* workSpace, size_t wkspSize);
289#endif
290
291size_t HUF_decompress4X_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable);
292#ifndef HUF_FORCE_DECOMPRESS_X2
293size_t HUF_decompress4X1_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable);
294#endif
295#ifndef HUF_FORCE_DECOMPRESS_X1
296size_t HUF_decompress4X2_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable);
297#endif
298
299
300/* ====================== */
301/* single stream variants */
302/* ====================== */
303
304size_t HUF_compress1X (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog);
305size_t HUF_compress1X_wksp (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize); /**< `workSpace` must be a table of at least HUF_WORKSPACE_SIZE_U64 U64 */
306size_t HUF_compress1X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable);
307size_t HUF_compress1X_usingCTable_bmi2(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable, int bmi2);
308/** HUF_compress1X_repeat() :
309 * Same as HUF_compress1X_wksp(), but considers using hufTable if *repeat != HUF_repeat_none.
310 * If it uses hufTable it does not modify hufTable or repeat.
311 * If it doesn't, it sets *repeat = HUF_repeat_none, and it sets hufTable to the table used.
312 * If preferRepeat then the old table will always be used if valid.
313 * If suspectUncompressible then some sampling checks will be run to potentially skip huffman coding */
314size_t HUF_compress1X_repeat(void* dst, size_t dstSize,
315 const void* src, size_t srcSize,
316 unsigned maxSymbolValue, unsigned tableLog,
317 void* workSpace, size_t wkspSize, /**< `workSpace` must be aligned on 4-bytes boundaries, `wkspSize` must be >= HUF_WORKSPACE_SIZE */
318 HUF_CElt* hufTable, HUF_repeat* repeat, int preferRepeat, int bmi2, unsigned suspectUncompressible);
319
320size_t HUF_decompress1X1 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* single-symbol decoder */
321#ifndef HUF_FORCE_DECOMPRESS_X1
322size_t HUF_decompress1X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* double-symbol decoder */
323#endif
324
325size_t HUF_decompress1X_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);
326size_t HUF_decompress1X_DCtx_wksp (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize);
327#ifndef HUF_FORCE_DECOMPRESS_X2
328size_t HUF_decompress1X1_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< single-symbol decoder */
329size_t HUF_decompress1X1_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize); /**< single-symbol decoder */
330#endif
331#ifndef HUF_FORCE_DECOMPRESS_X1
332size_t HUF_decompress1X2_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< double-symbols decoder */
333size_t HUF_decompress1X2_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize); /**< double-symbols decoder */
334#endif
335
336size_t HUF_decompress1X_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable); /**< automatic selection of sing or double symbol decoder, based on DTable */
337#ifndef HUF_FORCE_DECOMPRESS_X2
338size_t HUF_decompress1X1_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable);
339#endif
340#ifndef HUF_FORCE_DECOMPRESS_X1
341size_t HUF_decompress1X2_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable);
342#endif
343
344/* BMI2 variants.
345 * If the CPU has BMI2 support, pass bmi2=1, otherwise pass bmi2=0.
346 */
347size_t HUF_decompress1X_usingDTable_bmi2(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable, int bmi2);
348#ifndef HUF_FORCE_DECOMPRESS_X2
349size_t HUF_decompress1X1_DCtx_wksp_bmi2(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int bmi2);
350#endif
351size_t HUF_decompress4X_usingDTable_bmi2(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable, int bmi2);
352size_t HUF_decompress4X_hufOnly_wksp_bmi2(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int bmi2);
353#ifndef HUF_FORCE_DECOMPRESS_X2
354size_t HUF_readDTableX1_wksp_bmi2(HUF_DTable* DTable, const void* src, size_t srcSize, void* workSpace, size_t wkspSize, int bmi2);
355#endif
356#ifndef HUF_FORCE_DECOMPRESS_X1
357size_t HUF_readDTableX2_wksp_bmi2(HUF_DTable* DTable, const void* src, size_t srcSize, void* workSpace, size_t wkspSize, int bmi2);
358#endif
359
360#endif /* HUF_STATIC_LINKING_ONLY */
361
362#if defined (__cplusplus)
363}
364#endif
stage1/zstd/lib/common/mem.h created+442
......@@ -0,0 +1,442 @@
1/*
2 * Copyright (c) Yann Collet, Facebook, Inc.
3 * All rights reserved.
4 *
5 * This source code is licensed under both the BSD-style license (found in the
6 * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7 * in the COPYING file in the root directory of this source tree).
8 * You may select, at your option, one of the above-listed licenses.
9 */
10
11#ifndef MEM_H_MODULE
12#define MEM_H_MODULE
13
14#if defined (__cplusplus)
15extern "C" {
16#endif
17
18/*-****************************************
19* Dependencies
20******************************************/
21#include <stddef.h> /* size_t, ptrdiff_t */
22#include "compiler.h" /* __has_builtin */
23#include "debug.h" /* DEBUG_STATIC_ASSERT */
24#include "zstd_deps.h" /* ZSTD_memcpy */
25
26
27/*-****************************************
28* Compiler specifics
29******************************************/
30#if defined(_MSC_VER) /* Visual Studio */
31# include <stdlib.h> /* _byteswap_ulong */
32# include <intrin.h> /* _byteswap_* */
33#endif
34#if defined(__GNUC__)
35# define MEM_STATIC static __inline __attribute__((unused))
36#elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
37# define MEM_STATIC static inline
38#elif defined(_MSC_VER)
39# define MEM_STATIC static __inline
40#else
41# define MEM_STATIC static /* this version may generate warnings for unused static functions; disable the relevant warning */
42#endif
43
44/*-**************************************************************
45* Basic Types
46*****************************************************************/
47#if !defined (__VMS) && (defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) )
48# if defined(_AIX)
49# include <inttypes.h>
50# else
51# include <stdint.h> /* intptr_t */
52# endif
53 typedef uint8_t BYTE;
54 typedef uint8_t U8;
55 typedef int8_t S8;
56 typedef uint16_t U16;
57 typedef int16_t S16;
58 typedef uint32_t U32;
59 typedef int32_t S32;
60 typedef uint64_t U64;
61 typedef int64_t S64;
62#else
63# include <limits.h>
64#if CHAR_BIT != 8
65# error "this implementation requires char to be exactly 8-bit type"
66#endif
67 typedef unsigned char BYTE;
68 typedef unsigned char U8;
69 typedef signed char S8;
70#if USHRT_MAX != 65535
71# error "this implementation requires short to be exactly 16-bit type"
72#endif
73 typedef unsigned short U16;
74 typedef signed short S16;
75#if UINT_MAX != 4294967295
76# error "this implementation requires int to be exactly 32-bit type"
77#endif
78 typedef unsigned int U32;
79 typedef signed int S32;
80/* note : there are no limits defined for long long type in C90.
81 * limits exist in C99, however, in such case, <stdint.h> is preferred */
82 typedef unsigned long long U64;
83 typedef signed long long S64;
84#endif
85
86
87/*-**************************************************************
88* Memory I/O API
89*****************************************************************/
90/*=== Static platform detection ===*/
91MEM_STATIC unsigned MEM_32bits(void);
92MEM_STATIC unsigned MEM_64bits(void);
93MEM_STATIC unsigned MEM_isLittleEndian(void);
94
95/*=== Native unaligned read/write ===*/
96MEM_STATIC U16 MEM_read16(const void* memPtr);
97MEM_STATIC U32 MEM_read32(const void* memPtr);
98MEM_STATIC U64 MEM_read64(const void* memPtr);
99MEM_STATIC size_t MEM_readST(const void* memPtr);
100
101MEM_STATIC void MEM_write16(void* memPtr, U16 value);
102MEM_STATIC void MEM_write32(void* memPtr, U32 value);
103MEM_STATIC void MEM_write64(void* memPtr, U64 value);
104
105/*=== Little endian unaligned read/write ===*/
106MEM_STATIC U16 MEM_readLE16(const void* memPtr);
107MEM_STATIC U32 MEM_readLE24(const void* memPtr);
108MEM_STATIC U32 MEM_readLE32(const void* memPtr);
109MEM_STATIC U64 MEM_readLE64(const void* memPtr);
110MEM_STATIC size_t MEM_readLEST(const void* memPtr);
111
112MEM_STATIC void MEM_writeLE16(void* memPtr, U16 val);
113MEM_STATIC void MEM_writeLE24(void* memPtr, U32 val);
114MEM_STATIC void MEM_writeLE32(void* memPtr, U32 val32);
115MEM_STATIC void MEM_writeLE64(void* memPtr, U64 val64);
116MEM_STATIC void MEM_writeLEST(void* memPtr, size_t val);
117
118/*=== Big endian unaligned read/write ===*/
119MEM_STATIC U32 MEM_readBE32(const void* memPtr);
120MEM_STATIC U64 MEM_readBE64(const void* memPtr);
121MEM_STATIC size_t MEM_readBEST(const void* memPtr);
122
123MEM_STATIC void MEM_writeBE32(void* memPtr, U32 val32);
124MEM_STATIC void MEM_writeBE64(void* memPtr, U64 val64);
125MEM_STATIC void MEM_writeBEST(void* memPtr, size_t val);
126
127/*=== Byteswap ===*/
128MEM_STATIC U32 MEM_swap32(U32 in);
129MEM_STATIC U64 MEM_swap64(U64 in);
130MEM_STATIC size_t MEM_swapST(size_t in);
131
132
133/*-**************************************************************
134* Memory I/O Implementation
135*****************************************************************/
136/* MEM_FORCE_MEMORY_ACCESS :
137 * By default, access to unaligned memory is controlled by `memcpy()`, which is safe and portable.
138 * Unfortunately, on some target/compiler combinations, the generated assembly is sub-optimal.
139 * The below switch allow to select different access method for improved performance.
140 * Method 0 (default) : use `memcpy()`. Safe and portable.
141 * Method 1 : `__packed` statement. It depends on compiler extension (i.e., not portable).
142 * This method is safe if your compiler supports it, and *generally* as fast or faster than `memcpy`.
143 * Method 2 : direct access. This method is portable but violate C standard.
144 * It can generate buggy code on targets depending on alignment.
145 * In some circumstances, it's the only known way to get the most performance (i.e. GCC + ARMv6)
146 * See http://fastcompression.blogspot.fr/2015/08/accessing-unaligned-memory.html for details.
147 * Prefer these methods in priority order (0 > 1 > 2)
148 */
149#ifndef MEM_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */
150# if defined(__INTEL_COMPILER) || defined(__GNUC__) || defined(__ICCARM__)
151# define MEM_FORCE_MEMORY_ACCESS 1
152# endif
153#endif
154
155MEM_STATIC unsigned MEM_32bits(void) { return sizeof(size_t)==4; }
156MEM_STATIC unsigned MEM_64bits(void) { return sizeof(size_t)==8; }
157
158MEM_STATIC unsigned MEM_isLittleEndian(void)
159{
160#if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
161 return 1;
162#elif defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
163 return 0;
164#elif defined(__clang__) && __LITTLE_ENDIAN__
165 return 1;
166#elif defined(__clang__) && __BIG_ENDIAN__
167 return 0;
168#elif defined(_MSC_VER) && (_M_AMD64 || _M_IX86)
169 return 1;
170#elif defined(__DMC__) && defined(_M_IX86)
171 return 1;
172#else
173 const union { U32 u; BYTE c[4]; } one = { 1 }; /* don't use static : performance detrimental */
174 return one.c[0];
175#endif
176}
177
178#if defined(MEM_FORCE_MEMORY_ACCESS) && (MEM_FORCE_MEMORY_ACCESS==2)
179
180/* violates C standard, by lying on structure alignment.
181Only use if no other choice to achieve best performance on target platform */
182MEM_STATIC U16 MEM_read16(const void* memPtr) { return *(const U16*) memPtr; }
183MEM_STATIC U32 MEM_read32(const void* memPtr) { return *(const U32*) memPtr; }
184MEM_STATIC U64 MEM_read64(const void* memPtr) { return *(const U64*) memPtr; }
185MEM_STATIC size_t MEM_readST(const void* memPtr) { return *(const size_t*) memPtr; }
186
187MEM_STATIC void MEM_write16(void* memPtr, U16 value) { *(U16*)memPtr = value; }
188MEM_STATIC void MEM_write32(void* memPtr, U32 value) { *(U32*)memPtr = value; }
189MEM_STATIC void MEM_write64(void* memPtr, U64 value) { *(U64*)memPtr = value; }
190
191#elif defined(MEM_FORCE_MEMORY_ACCESS) && (MEM_FORCE_MEMORY_ACCESS==1)
192
193/* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */
194/* currently only defined for gcc and icc */
195#if defined(_MSC_VER) || (defined(__INTEL_COMPILER) && defined(WIN32))
196 __pragma( pack(push, 1) )
197 typedef struct { U16 v; } unalign16;
198 typedef struct { U32 v; } unalign32;
199 typedef struct { U64 v; } unalign64;
200 typedef struct { size_t v; } unalignArch;
201 __pragma( pack(pop) )
202#else
203 typedef struct { U16 v; } __attribute__((packed)) unalign16;
204 typedef struct { U32 v; } __attribute__((packed)) unalign32;
205 typedef struct { U64 v; } __attribute__((packed)) unalign64;
206 typedef struct { size_t v; } __attribute__((packed)) unalignArch;
207#endif
208
209MEM_STATIC U16 MEM_read16(const void* ptr) { return ((const unalign16*)ptr)->v; }
210MEM_STATIC U32 MEM_read32(const void* ptr) { return ((const unalign32*)ptr)->v; }
211MEM_STATIC U64 MEM_read64(const void* ptr) { return ((const unalign64*)ptr)->v; }
212MEM_STATIC size_t MEM_readST(const void* ptr) { return ((const unalignArch*)ptr)->v; }
213
214MEM_STATIC void MEM_write16(void* memPtr, U16 value) { ((unalign16*)memPtr)->v = value; }
215MEM_STATIC void MEM_write32(void* memPtr, U32 value) { ((unalign32*)memPtr)->v = value; }
216MEM_STATIC void MEM_write64(void* memPtr, U64 value) { ((unalign64*)memPtr)->v = value; }
217
218#else
219
220/* default method, safe and standard.
221 can sometimes prove slower */
222
223MEM_STATIC U16 MEM_read16(const void* memPtr)
224{
225 U16 val; ZSTD_memcpy(&val, memPtr, sizeof(val)); return val;
226}
227
228MEM_STATIC U32 MEM_read32(const void* memPtr)
229{
230 U32 val; ZSTD_memcpy(&val, memPtr, sizeof(val)); return val;
231}
232
233MEM_STATIC U64 MEM_read64(const void* memPtr)
234{
235 U64 val; ZSTD_memcpy(&val, memPtr, sizeof(val)); return val;
236}
237
238MEM_STATIC size_t MEM_readST(const void* memPtr)
239{
240 size_t val; ZSTD_memcpy(&val, memPtr, sizeof(val)); return val;
241}
242
243MEM_STATIC void MEM_write16(void* memPtr, U16 value)
244{
245 ZSTD_memcpy(memPtr, &value, sizeof(value));
246}
247
248MEM_STATIC void MEM_write32(void* memPtr, U32 value)
249{
250 ZSTD_memcpy(memPtr, &value, sizeof(value));
251}
252
253MEM_STATIC void MEM_write64(void* memPtr, U64 value)
254{
255 ZSTD_memcpy(memPtr, &value, sizeof(value));
256}
257
258#endif /* MEM_FORCE_MEMORY_ACCESS */
259
260MEM_STATIC U32 MEM_swap32(U32 in)
261{
262#if defined(_MSC_VER) /* Visual Studio */
263 return _byteswap_ulong(in);
264#elif (defined (__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 403)) \
265 || (defined(__clang__) && __has_builtin(__builtin_bswap32))
266 return __builtin_bswap32(in);
267#else
268 return ((in << 24) & 0xff000000 ) |
269 ((in << 8) & 0x00ff0000 ) |
270 ((in >> 8) & 0x0000ff00 ) |
271 ((in >> 24) & 0x000000ff );
272#endif
273}
274
275MEM_STATIC U64 MEM_swap64(U64 in)
276{
277#if defined(_MSC_VER) /* Visual Studio */
278 return _byteswap_uint64(in);
279#elif (defined (__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 403)) \
280 || (defined(__clang__) && __has_builtin(__builtin_bswap64))
281 return __builtin_bswap64(in);
282#else
283 return ((in << 56) & 0xff00000000000000ULL) |
284 ((in << 40) & 0x00ff000000000000ULL) |
285 ((in << 24) & 0x0000ff0000000000ULL) |
286 ((in << 8) & 0x000000ff00000000ULL) |
287 ((in >> 8) & 0x00000000ff000000ULL) |
288 ((in >> 24) & 0x0000000000ff0000ULL) |
289 ((in >> 40) & 0x000000000000ff00ULL) |
290 ((in >> 56) & 0x00000000000000ffULL);
291#endif
292}
293
294MEM_STATIC size_t MEM_swapST(size_t in)
295{
296 if (MEM_32bits())
297 return (size_t)MEM_swap32((U32)in);
298 else
299 return (size_t)MEM_swap64((U64)in);
300}
301
302/*=== Little endian r/w ===*/
303
304MEM_STATIC U16 MEM_readLE16(const void* memPtr)
305{
306 if (MEM_isLittleEndian())
307 return MEM_read16(memPtr);
308 else {
309 const BYTE* p = (const BYTE*)memPtr;
310 return (U16)(p[0] + (p[1]<<8));
311 }
312}
313
314MEM_STATIC void MEM_writeLE16(void* memPtr, U16 val)
315{
316 if (MEM_isLittleEndian()) {
317 MEM_write16(memPtr, val);
318 } else {
319 BYTE* p = (BYTE*)memPtr;
320 p[0] = (BYTE)val;
321 p[1] = (BYTE)(val>>8);
322 }
323}
324
325MEM_STATIC U32 MEM_readLE24(const void* memPtr)
326{
327 return (U32)MEM_readLE16(memPtr) + ((U32)(((const BYTE*)memPtr)[2]) << 16);
328}
329
330MEM_STATIC void MEM_writeLE24(void* memPtr, U32 val)
331{
332 MEM_writeLE16(memPtr, (U16)val);
333 ((BYTE*)memPtr)[2] = (BYTE)(val>>16);
334}
335
336MEM_STATIC U32 MEM_readLE32(const void* memPtr)
337{
338 if (MEM_isLittleEndian())
339 return MEM_read32(memPtr);
340 else
341 return MEM_swap32(MEM_read32(memPtr));
342}
343
344MEM_STATIC void MEM_writeLE32(void* memPtr, U32 val32)
345{
346 if (MEM_isLittleEndian())
347 MEM_write32(memPtr, val32);
348 else
349 MEM_write32(memPtr, MEM_swap32(val32));
350}
351
352MEM_STATIC U64 MEM_readLE64(const void* memPtr)
353{
354 if (MEM_isLittleEndian())
355 return MEM_read64(memPtr);
356 else
357 return MEM_swap64(MEM_read64(memPtr));
358}
359
360MEM_STATIC void MEM_writeLE64(void* memPtr, U64 val64)
361{
362 if (MEM_isLittleEndian())
363 MEM_write64(memPtr, val64);
364 else
365 MEM_write64(memPtr, MEM_swap64(val64));
366}
367
368MEM_STATIC size_t MEM_readLEST(const void* memPtr)
369{
370 if (MEM_32bits())
371 return (size_t)MEM_readLE32(memPtr);
372 else
373 return (size_t)MEM_readLE64(memPtr);
374}
375
376MEM_STATIC void MEM_writeLEST(void* memPtr, size_t val)
377{
378 if (MEM_32bits())
379 MEM_writeLE32(memPtr, (U32)val);
380 else
381 MEM_writeLE64(memPtr, (U64)val);
382}
383
384/*=== Big endian r/w ===*/
385
386MEM_STATIC U32 MEM_readBE32(const void* memPtr)
387{
388 if (MEM_isLittleEndian())
389 return MEM_swap32(MEM_read32(memPtr));
390 else
391 return MEM_read32(memPtr);
392}
393
394MEM_STATIC void MEM_writeBE32(void* memPtr, U32 val32)
395{
396 if (MEM_isLittleEndian())
397 MEM_write32(memPtr, MEM_swap32(val32));
398 else
399 MEM_write32(memPtr, val32);
400}
401
402MEM_STATIC U64 MEM_readBE64(const void* memPtr)
403{
404 if (MEM_isLittleEndian())
405 return MEM_swap64(MEM_read64(memPtr));
406 else
407 return MEM_read64(memPtr);
408}
409
410MEM_STATIC void MEM_writeBE64(void* memPtr, U64 val64)
411{
412 if (MEM_isLittleEndian())
413 MEM_write64(memPtr, MEM_swap64(val64));
414 else
415 MEM_write64(memPtr, val64);
416}
417
418MEM_STATIC size_t MEM_readBEST(const void* memPtr)
419{
420 if (MEM_32bits())
421 return (size_t)MEM_readBE32(memPtr);
422 else
423 return (size_t)MEM_readBE64(memPtr);
424}
425
426MEM_STATIC void MEM_writeBEST(void* memPtr, size_t val)
427{
428 if (MEM_32bits())
429 MEM_writeBE32(memPtr, (U32)val);
430 else
431 MEM_writeBE64(memPtr, (U64)val);
432}
433
434/* code only tested on 32 and 64 bits systems */
435MEM_STATIC void MEM_check(void) { DEBUG_STATIC_ASSERT((sizeof(size_t)==4) || (sizeof(size_t)==8)); }
436
437
438#if defined (__cplusplus)
439}
440#endif
441
442#endif /* MEM_H_MODULE */
stage1/zstd/lib/common/pool.c created+355
......@@ -0,0 +1,355 @@
1/*
2 * Copyright (c) Yann Collet, Facebook, Inc.
3 * All rights reserved.
4 *
5 * This source code is licensed under both the BSD-style license (found in the
6 * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7 * in the COPYING file in the root directory of this source tree).
8 * You may select, at your option, one of the above-listed licenses.
9 */
10
11
12/* ====== Dependencies ======= */
13#include "zstd_deps.h" /* size_t */
14#include "debug.h" /* assert */
15#include "zstd_internal.h" /* ZSTD_customMalloc, ZSTD_customFree */
16#include "pool.h"
17
18/* ====== Compiler specifics ====== */
19#if defined(_MSC_VER)
20# pragma warning(disable : 4204) /* disable: C4204: non-constant aggregate initializer */
21#endif
22
23
24#ifdef ZSTD_MULTITHREAD
25
26#include "threading.h" /* pthread adaptation */
27
28/* A job is a function and an opaque argument */
29typedef struct POOL_job_s {
30 POOL_function function;
31 void *opaque;
32} POOL_job;
33
34struct POOL_ctx_s {
35 ZSTD_customMem customMem;
36 /* Keep track of the threads */
37 ZSTD_pthread_t* threads;
38 size_t threadCapacity;
39 size_t threadLimit;
40
41 /* The queue is a circular buffer */
42 POOL_job *queue;
43 size_t queueHead;
44 size_t queueTail;
45 size_t queueSize;
46
47 /* The number of threads working on jobs */
48 size_t numThreadsBusy;
49 /* Indicates if the queue is empty */
50 int queueEmpty;
51
52 /* The mutex protects the queue */
53 ZSTD_pthread_mutex_t queueMutex;
54 /* Condition variable for pushers to wait on when the queue is full */
55 ZSTD_pthread_cond_t queuePushCond;
56 /* Condition variables for poppers to wait on when the queue is empty */
57 ZSTD_pthread_cond_t queuePopCond;
58 /* Indicates if the queue is shutting down */
59 int shutdown;
60};
61
62/* POOL_thread() :
63 * Work thread for the thread pool.
64 * Waits for jobs and executes them.
65 * @returns : NULL on failure else non-null.
66 */
67static void* POOL_thread(void* opaque) {
68 POOL_ctx* const ctx = (POOL_ctx*)opaque;
69 if (!ctx) { return NULL; }
70 for (;;) {
71 /* Lock the mutex and wait for a non-empty queue or until shutdown */
72 ZSTD_pthread_mutex_lock(&ctx->queueMutex);
73
74 while ( ctx->queueEmpty
75 || (ctx->numThreadsBusy >= ctx->threadLimit) ) {
76 if (ctx->shutdown) {
77 /* even if !queueEmpty, (possible if numThreadsBusy >= threadLimit),
78 * a few threads will be shutdown while !queueEmpty,
79 * but enough threads will remain active to finish the queue */
80 ZSTD_pthread_mutex_unlock(&ctx->queueMutex);
81 return opaque;
82 }
83 ZSTD_pthread_cond_wait(&ctx->queuePopCond, &ctx->queueMutex);
84 }
85 /* Pop a job off the queue */
86 { POOL_job const job = ctx->queue[ctx->queueHead];
87 ctx->queueHead = (ctx->queueHead + 1) % ctx->queueSize;
88 ctx->numThreadsBusy++;
89 ctx->queueEmpty = (ctx->queueHead == ctx->queueTail);
90 /* Unlock the mutex, signal a pusher, and run the job */
91 ZSTD_pthread_cond_signal(&ctx->queuePushCond);
92 ZSTD_pthread_mutex_unlock(&ctx->queueMutex);
93
94 job.function(job.opaque);
95
96 /* If the intended queue size was 0, signal after finishing job */
97 ZSTD_pthread_mutex_lock(&ctx->queueMutex);
98 ctx->numThreadsBusy--;
99 if (ctx->queueSize == 1) {
100 ZSTD_pthread_cond_signal(&ctx->queuePushCond);
101 }
102 ZSTD_pthread_mutex_unlock(&ctx->queueMutex);
103 }
104 } /* for (;;) */
105 assert(0); /* Unreachable */
106}
107
108/* ZSTD_createThreadPool() : public access point */
109POOL_ctx* ZSTD_createThreadPool(size_t numThreads) {
110 return POOL_create (numThreads, 0);
111}
112
113POOL_ctx* POOL_create(size_t numThreads, size_t queueSize) {
114 return POOL_create_advanced(numThreads, queueSize, ZSTD_defaultCMem);
115}
116
117POOL_ctx* POOL_create_advanced(size_t numThreads, size_t queueSize,
118 ZSTD_customMem customMem)
119{
120 POOL_ctx* ctx;
121 /* Check parameters */
122 if (!numThreads) { return NULL; }
123 /* Allocate the context and zero initialize */
124 ctx = (POOL_ctx*)ZSTD_customCalloc(sizeof(POOL_ctx), customMem);
125 if (!ctx) { return NULL; }
126 /* Initialize the job queue.
127 * It needs one extra space since one space is wasted to differentiate
128 * empty and full queues.
129 */
130 ctx->queueSize = queueSize + 1;
131 ctx->queue = (POOL_job*)ZSTD_customMalloc(ctx->queueSize * sizeof(POOL_job), customMem);
132 ctx->queueHead = 0;
133 ctx->queueTail = 0;
134 ctx->numThreadsBusy = 0;
135 ctx->queueEmpty = 1;
136 {
137 int error = 0;
138 error |= ZSTD_pthread_mutex_init(&ctx->queueMutex, NULL);
139 error |= ZSTD_pthread_cond_init(&ctx->queuePushCond, NULL);
140 error |= ZSTD_pthread_cond_init(&ctx->queuePopCond, NULL);
141 if (error) { POOL_free(ctx); return NULL; }
142 }
143 ctx->shutdown = 0;
144 /* Allocate space for the thread handles */
145 ctx->threads = (ZSTD_pthread_t*)ZSTD_customMalloc(numThreads * sizeof(ZSTD_pthread_t), customMem);
146 ctx->threadCapacity = 0;
147 ctx->customMem = customMem;
148 /* Check for errors */
149 if (!ctx->threads || !ctx->queue) { POOL_free(ctx); return NULL; }
150 /* Initialize the threads */
151 { size_t i;
152 for (i = 0; i < numThreads; ++i) {
153 if (ZSTD_pthread_create(&ctx->threads[i], NULL, &POOL_thread, ctx)) {
154 ctx->threadCapacity = i;
155 POOL_free(ctx);
156 return NULL;
157 } }
158 ctx->threadCapacity = numThreads;
159 ctx->threadLimit = numThreads;
160 }
161 return ctx;
162}
163
164/*! POOL_join() :
165 Shutdown the queue, wake any sleeping threads, and join all of the threads.
166*/
167static void POOL_join(POOL_ctx* ctx) {
168 /* Shut down the queue */
169 ZSTD_pthread_mutex_lock(&ctx->queueMutex);
170 ctx->shutdown = 1;
171 ZSTD_pthread_mutex_unlock(&ctx->queueMutex);
172 /* Wake up sleeping threads */
173 ZSTD_pthread_cond_broadcast(&ctx->queuePushCond);
174 ZSTD_pthread_cond_broadcast(&ctx->queuePopCond);
175 /* Join all of the threads */
176 { size_t i;
177 for (i = 0; i < ctx->threadCapacity; ++i) {
178 ZSTD_pthread_join(ctx->threads[i], NULL); /* note : could fail */
179 } }
180}
181
182void POOL_free(POOL_ctx *ctx) {
183 if (!ctx) { return; }
184 POOL_join(ctx);
185 ZSTD_pthread_mutex_destroy(&ctx->queueMutex);
186 ZSTD_pthread_cond_destroy(&ctx->queuePushCond);
187 ZSTD_pthread_cond_destroy(&ctx->queuePopCond);
188 ZSTD_customFree(ctx->queue, ctx->customMem);
189 ZSTD_customFree(ctx->threads, ctx->customMem);
190 ZSTD_customFree(ctx, ctx->customMem);
191}
192
193void ZSTD_freeThreadPool (ZSTD_threadPool* pool) {
194 POOL_free (pool);
195}
196
197size_t POOL_sizeof(const POOL_ctx* ctx) {
198 if (ctx==NULL) return 0; /* supports sizeof NULL */
199 return sizeof(*ctx)
200 + ctx->queueSize * sizeof(POOL_job)
201 + ctx->threadCapacity * sizeof(ZSTD_pthread_t);
202}
203
204
205/* @return : 0 on success, 1 on error */
206static int POOL_resize_internal(POOL_ctx* ctx, size_t numThreads)
207{
208 if (numThreads <= ctx->threadCapacity) {
209 if (!numThreads) return 1;
210 ctx->threadLimit = numThreads;
211 return 0;
212 }
213 /* numThreads > threadCapacity */
214 { ZSTD_pthread_t* const threadPool = (ZSTD_pthread_t*)ZSTD_customMalloc(numThreads * sizeof(ZSTD_pthread_t), ctx->customMem);
215 if (!threadPool) return 1;
216 /* replace existing thread pool */
217 ZSTD_memcpy(threadPool, ctx->threads, ctx->threadCapacity * sizeof(*threadPool));
218 ZSTD_customFree(ctx->threads, ctx->customMem);
219 ctx->threads = threadPool;
220 /* Initialize additional threads */
221 { size_t threadId;
222 for (threadId = ctx->threadCapacity; threadId < numThreads; ++threadId) {
223 if (ZSTD_pthread_create(&threadPool[threadId], NULL, &POOL_thread, ctx)) {
224 ctx->threadCapacity = threadId;
225 return 1;
226 } }
227 } }
228 /* successfully expanded */
229 ctx->threadCapacity = numThreads;
230 ctx->threadLimit = numThreads;
231 return 0;
232}
233
234/* @return : 0 on success, 1 on error */
235int POOL_resize(POOL_ctx* ctx, size_t numThreads)
236{
237 int result;
238 if (ctx==NULL) return 1;
239 ZSTD_pthread_mutex_lock(&ctx->queueMutex);
240 result = POOL_resize_internal(ctx, numThreads);
241 ZSTD_pthread_cond_broadcast(&ctx->queuePopCond);
242 ZSTD_pthread_mutex_unlock(&ctx->queueMutex);
243 return result;
244}
245
246/**
247 * Returns 1 if the queue is full and 0 otherwise.
248 *
249 * When queueSize is 1 (pool was created with an intended queueSize of 0),
250 * then a queue is empty if there is a thread free _and_ no job is waiting.
251 */
252static int isQueueFull(POOL_ctx const* ctx) {
253 if (ctx->queueSize > 1) {
254 return ctx->queueHead == ((ctx->queueTail + 1) % ctx->queueSize);
255 } else {
256 return (ctx->numThreadsBusy == ctx->threadLimit) ||
257 !ctx->queueEmpty;
258 }
259}
260
261
262static void
263POOL_add_internal(POOL_ctx* ctx, POOL_function function, void *opaque)
264{
265 POOL_job const job = {function, opaque};
266 assert(ctx != NULL);
267 if (ctx->shutdown) return;
268
269 ctx->queueEmpty = 0;
270 ctx->queue[ctx->queueTail] = job;
271 ctx->queueTail = (ctx->queueTail + 1) % ctx->queueSize;
272 ZSTD_pthread_cond_signal(&ctx->queuePopCond);
273}
274
275void POOL_add(POOL_ctx* ctx, POOL_function function, void* opaque)
276{
277 assert(ctx != NULL);
278 ZSTD_pthread_mutex_lock(&ctx->queueMutex);
279 /* Wait until there is space in the queue for the new job */
280 while (isQueueFull(ctx) && (!ctx->shutdown)) {
281 ZSTD_pthread_cond_wait(&ctx->queuePushCond, &ctx->queueMutex);
282 }
283 POOL_add_internal(ctx, function, opaque);
284 ZSTD_pthread_mutex_unlock(&ctx->queueMutex);
285}
286
287
288int POOL_tryAdd(POOL_ctx* ctx, POOL_function function, void* opaque)
289{
290 assert(ctx != NULL);
291 ZSTD_pthread_mutex_lock(&ctx->queueMutex);
292 if (isQueueFull(ctx)) {
293 ZSTD_pthread_mutex_unlock(&ctx->queueMutex);
294 return 0;
295 }
296 POOL_add_internal(ctx, function, opaque);
297 ZSTD_pthread_mutex_unlock(&ctx->queueMutex);
298 return 1;
299}
300
301
302#else /* ZSTD_MULTITHREAD not defined */
303
304/* ========================== */
305/* No multi-threading support */
306/* ========================== */
307
308
309/* We don't need any data, but if it is empty, malloc() might return NULL. */
310struct POOL_ctx_s {
311 int dummy;
312};
313static POOL_ctx g_poolCtx;
314
315POOL_ctx* POOL_create(size_t numThreads, size_t queueSize) {
316 return POOL_create_advanced(numThreads, queueSize, ZSTD_defaultCMem);
317}
318
319POOL_ctx*
320POOL_create_advanced(size_t numThreads, size_t queueSize, ZSTD_customMem customMem)
321{
322 (void)numThreads;
323 (void)queueSize;
324 (void)customMem;
325 return &g_poolCtx;
326}
327
328void POOL_free(POOL_ctx* ctx) {
329 assert(!ctx || ctx == &g_poolCtx);
330 (void)ctx;
331}
332
333int POOL_resize(POOL_ctx* ctx, size_t numThreads) {
334 (void)ctx; (void)numThreads;
335 return 0;
336}
337
338void POOL_add(POOL_ctx* ctx, POOL_function function, void* opaque) {
339 (void)ctx;
340 function(opaque);
341}
342
343int POOL_tryAdd(POOL_ctx* ctx, POOL_function function, void* opaque) {
344 (void)ctx;
345 function(opaque);
346 return 1;
347}
348
349size_t POOL_sizeof(const POOL_ctx* ctx) {
350 if (ctx==NULL) return 0; /* supports sizeof NULL */
351 assert(ctx == &g_poolCtx);
352 return sizeof(*ctx);
353}
354
355#endif /* ZSTD_MULTITHREAD */
stage1/zstd/lib/common/pool.h created+84
......@@ -0,0 +1,84 @@
1/*
2 * Copyright (c) Yann Collet, Facebook, Inc.
3 * All rights reserved.
4 *
5 * This source code is licensed under both the BSD-style license (found in the
6 * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7 * in the COPYING file in the root directory of this source tree).
8 * You may select, at your option, one of the above-listed licenses.
9 */
10
11#ifndef POOL_H
12#define POOL_H
13
14#if defined (__cplusplus)
15extern "C" {
16#endif
17
18
19#include "zstd_deps.h"
20#define ZSTD_STATIC_LINKING_ONLY /* ZSTD_customMem */
21#include "../zstd.h"
22
23typedef struct POOL_ctx_s POOL_ctx;
24
25/*! POOL_create() :
26 * Create a thread pool with at most `numThreads` threads.
27 * `numThreads` must be at least 1.
28 * The maximum number of queued jobs before blocking is `queueSize`.
29 * @return : POOL_ctx pointer on success, else NULL.
30*/
31POOL_ctx* POOL_create(size_t numThreads, size_t queueSize);
32
33POOL_ctx* POOL_create_advanced(size_t numThreads, size_t queueSize,
34 ZSTD_customMem customMem);
35
36/*! POOL_free() :
37 * Free a thread pool returned by POOL_create().
38 */
39void POOL_free(POOL_ctx* ctx);
40
41/*! POOL_resize() :
42 * Expands or shrinks pool's number of threads.
43 * This is more efficient than releasing + creating a new context,
44 * since it tries to preserve and re-use existing threads.
45 * `numThreads` must be at least 1.
46 * @return : 0 when resize was successful,
47 * !0 (typically 1) if there is an error.
48 * note : only numThreads can be resized, queueSize remains unchanged.
49 */
50int POOL_resize(POOL_ctx* ctx, size_t numThreads);
51
52/*! POOL_sizeof() :
53 * @return threadpool memory usage
54 * note : compatible with NULL (returns 0 in this case)
55 */
56size_t POOL_sizeof(const POOL_ctx* ctx);
57
58/*! POOL_function :
59 * The function type that can be added to a thread pool.
60 */
61typedef void (*POOL_function)(void*);
62
63/*! POOL_add() :
64 * Add the job `function(opaque)` to the thread pool. `ctx` must be valid.
65 * Possibly blocks until there is room in the queue.
66 * Note : The function may be executed asynchronously,
67 * therefore, `opaque` must live until function has been completed.
68 */
69void POOL_add(POOL_ctx* ctx, POOL_function function, void* opaque);
70
71
72/*! POOL_tryAdd() :
73 * Add the job `function(opaque)` to thread pool _if_ a queue slot is available.
74 * Returns immediately even if not (does not block).
75 * @return : 1 if successful, 0 if not.
76 */
77int POOL_tryAdd(POOL_ctx* ctx, POOL_function function, void* opaque);
78
79
80#if defined (__cplusplus)
81}
82#endif
83
84#endif
stage1/zstd/lib/common/portability_macros.h created+137
......@@ -0,0 +1,137 @@
1/*
2 * Copyright (c) Facebook, Inc.
3 * All rights reserved.
4 *
5 * This source code is licensed under both the BSD-style license (found in the
6 * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7 * in the COPYING file in the root directory of this source tree).
8 * You may select, at your option, one of the above-listed licenses.
9 */
10
11#ifndef ZSTD_PORTABILITY_MACROS_H
12#define ZSTD_PORTABILITY_MACROS_H
13
14/**
15 * This header file contains macro defintions to support portability.
16 * This header is shared between C and ASM code, so it MUST only
17 * contain macro definitions. It MUST not contain any C code.
18 *
19 * This header ONLY defines macros to detect platforms/feature support.
20 *
21 */
22
23
24/* compat. with non-clang compilers */
25#ifndef __has_attribute
26 #define __has_attribute(x) 0
27#endif
28
29/* compat. with non-clang compilers */
30#ifndef __has_builtin
31# define __has_builtin(x) 0
32#endif
33
34/* compat. with non-clang compilers */
35#ifndef __has_feature
36# define __has_feature(x) 0
37#endif
38
39/* detects whether we are being compiled under msan */
40#ifndef ZSTD_MEMORY_SANITIZER
41# if __has_feature(memory_sanitizer)
42# define ZSTD_MEMORY_SANITIZER 1
43# else
44# define ZSTD_MEMORY_SANITIZER 0
45# endif
46#endif
47
48/* detects whether we are being compiled under asan */
49#ifndef ZSTD_ADDRESS_SANITIZER
50# if __has_feature(address_sanitizer)
51# define ZSTD_ADDRESS_SANITIZER 1
52# elif defined(__SANITIZE_ADDRESS__)
53# define ZSTD_ADDRESS_SANITIZER 1
54# else
55# define ZSTD_ADDRESS_SANITIZER 0
56# endif
57#endif
58
59/* detects whether we are being compiled under dfsan */
60#ifndef ZSTD_DATAFLOW_SANITIZER
61# if __has_feature(dataflow_sanitizer)
62# define ZSTD_DATAFLOW_SANITIZER 1
63# else
64# define ZSTD_DATAFLOW_SANITIZER 0
65# endif
66#endif
67
68/* Mark the internal assembly functions as hidden */
69#ifdef __ELF__
70# define ZSTD_HIDE_ASM_FUNCTION(func) .hidden func
71#else
72# define ZSTD_HIDE_ASM_FUNCTION(func)
73#endif
74
75/* Enable runtime BMI2 dispatch based on the CPU.
76 * Enabled for clang & gcc >=4.8 on x86 when BMI2 isn't enabled by default.
77 */
78#ifndef DYNAMIC_BMI2
79 #if ((defined(__clang__) && __has_attribute(__target__)) \
80 || (defined(__GNUC__) \
81 && (__GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)))) \
82 && (defined(__x86_64__) || defined(_M_X64)) \
83 && !defined(__BMI2__)
84 # define DYNAMIC_BMI2 1
85 #else
86 # define DYNAMIC_BMI2 0
87 #endif
88#endif
89
90/**
91 * Only enable assembly for GNUC comptabile compilers,
92 * because other platforms may not support GAS assembly syntax.
93 *
94 * Only enable assembly for Linux / MacOS, other platforms may
95 * work, but they haven't been tested. This could likely be
96 * extended to BSD systems.
97 *
98 * Disable assembly when MSAN is enabled, because MSAN requires
99 * 100% of code to be instrumented to work.
100 */
101#if defined(__GNUC__)
102# if defined(__linux__) || defined(__linux) || defined(__APPLE__)
103# if ZSTD_MEMORY_SANITIZER
104# define ZSTD_ASM_SUPPORTED 0
105# elif ZSTD_DATAFLOW_SANITIZER
106# define ZSTD_ASM_SUPPORTED 0
107# else
108# define ZSTD_ASM_SUPPORTED 1
109# endif
110# else
111# define ZSTD_ASM_SUPPORTED 0
112# endif
113#else
114# define ZSTD_ASM_SUPPORTED 0
115#endif
116
117/**
118 * Determines whether we should enable assembly for x86-64
119 * with BMI2.
120 *
121 * Enable if all of the following conditions hold:
122 * - ASM hasn't been explicitly disabled by defining ZSTD_DISABLE_ASM
123 * - Assembly is supported
124 * - We are compiling for x86-64 and either:
125 * - DYNAMIC_BMI2 is enabled
126 * - BMI2 is supported at compile time
127 */
128#if !defined(ZSTD_DISABLE_ASM) && \
129 ZSTD_ASM_SUPPORTED && \
130 defined(__x86_64__) && \
131 (DYNAMIC_BMI2 || defined(__BMI2__))
132# define ZSTD_ENABLE_ASM_X86_64_BMI2 1
133#else
134# define ZSTD_ENABLE_ASM_X86_64_BMI2 0
135#endif
136
137#endif /* ZSTD_PORTABILITY_MACROS_H */
stage1/zstd/lib/common/threading.c created+122
......@@ -0,0 +1,122 @@
1/**
2 * Copyright (c) 2016 Tino Reichardt
3 * All rights reserved.
4 *
5 * You can contact the author at:
6 * - zstdmt source repository: https://github.com/mcmilk/zstdmt
7 *
8 * This source code is licensed under both the BSD-style license (found in the
9 * LICENSE file in the root directory of this source tree) and the GPLv2 (found
10 * in the COPYING file in the root directory of this source tree).
11 * You may select, at your option, one of the above-listed licenses.
12 */
13
14/**
15 * This file will hold wrapper for systems, which do not support pthreads
16 */
17
18#include "threading.h"
19
20/* create fake symbol to avoid empty translation unit warning */
21int g_ZSTD_threading_useless_symbol;
22
23#if defined(ZSTD_MULTITHREAD) && defined(_WIN32)
24
25/**
26 * Windows minimalist Pthread Wrapper, based on :
27 * http://www.cse.wustl.edu/~schmidt/win32-cv-1.html
28 */
29
30
31/* === Dependencies === */
32#include <process.h>
33#include <errno.h>
34
35
36/* === Implementation === */
37
38static unsigned __stdcall worker(void *arg)
39{
40 ZSTD_pthread_t* const thread = (ZSTD_pthread_t*) arg;
41 thread->arg = thread->start_routine(thread->arg);
42 return 0;
43}
44
45int ZSTD_pthread_create(ZSTD_pthread_t* thread, const void* unused,
46 void* (*start_routine) (void*), void* arg)
47{
48 (void)unused;
49 thread->arg = arg;
50 thread->start_routine = start_routine;
51 thread->handle = (HANDLE) _beginthreadex(NULL, 0, worker, thread, 0, NULL);
52
53 if (!thread->handle)
54 return errno;
55 else
56 return 0;
57}
58
59int ZSTD_pthread_join(ZSTD_pthread_t thread, void **value_ptr)
60{
61 DWORD result;
62
63 if (!thread.handle) return 0;
64
65 result = WaitForSingleObject(thread.handle, INFINITE);
66 switch (result) {
67 case WAIT_OBJECT_0:
68 if (value_ptr) *value_ptr = thread.arg;
69 return 0;
70 case WAIT_ABANDONED:
71 return EINVAL;
72 default:
73 return GetLastError();
74 }
75}
76
77#endif /* ZSTD_MULTITHREAD */
78
79#if defined(ZSTD_MULTITHREAD) && DEBUGLEVEL >= 1 && !defined(_WIN32)
80
81#define ZSTD_DEPS_NEED_MALLOC
82#include "zstd_deps.h"
83
84int ZSTD_pthread_mutex_init(ZSTD_pthread_mutex_t* mutex, pthread_mutexattr_t const* attr)
85{
86 *mutex = (pthread_mutex_t*)ZSTD_malloc(sizeof(pthread_mutex_t));
87 if (!*mutex)
88 return 1;
89 return pthread_mutex_init(*mutex, attr);
90}
91
92int ZSTD_pthread_mutex_destroy(ZSTD_pthread_mutex_t* mutex)
93{
94 if (!*mutex)
95 return 0;
96 {
97 int const ret = pthread_mutex_destroy(*mutex);
98 ZSTD_free(*mutex);
99 return ret;
100 }
101}
102
103int ZSTD_pthread_cond_init(ZSTD_pthread_cond_t* cond, pthread_condattr_t const* attr)
104{
105 *cond = (pthread_cond_t*)ZSTD_malloc(sizeof(pthread_cond_t));
106 if (!*cond)
107 return 1;
108 return pthread_cond_init(*cond, attr);
109}
110
111int ZSTD_pthread_cond_destroy(ZSTD_pthread_cond_t* cond)
112{
113 if (!*cond)
114 return 0;
115 {
116 int const ret = pthread_cond_destroy(*cond);
117 ZSTD_free(*cond);
118 return ret;
119 }
120}
121
122#endif
stage1/zstd/lib/common/threading.h created+155
......@@ -0,0 +1,155 @@
1/**
2 * Copyright (c) 2016 Tino Reichardt
3 * All rights reserved.
4 *
5 * You can contact the author at:
6 * - zstdmt source repository: https://github.com/mcmilk/zstdmt
7 *
8 * This source code is licensed under both the BSD-style license (found in the
9 * LICENSE file in the root directory of this source tree) and the GPLv2 (found
10 * in the COPYING file in the root directory of this source tree).
11 * You may select, at your option, one of the above-listed licenses.
12 */
13
14#ifndef THREADING_H_938743
15#define THREADING_H_938743
16
17#include "debug.h"
18
19#if defined (__cplusplus)
20extern "C" {
21#endif
22
23#if defined(ZSTD_MULTITHREAD) && defined(_WIN32)
24
25/**
26 * Windows minimalist Pthread Wrapper, based on :
27 * http://www.cse.wustl.edu/~schmidt/win32-cv-1.html
28 */
29#ifdef WINVER
30# undef WINVER
31#endif
32#define WINVER 0x0600
33
34#ifdef _WIN32_WINNT
35# undef _WIN32_WINNT
36#endif
37#define _WIN32_WINNT 0x0600
38
39#ifndef WIN32_LEAN_AND_MEAN
40# define WIN32_LEAN_AND_MEAN
41#endif
42
43#undef ERROR /* reported already defined on VS 2015 (Rich Geldreich) */
44#include <windows.h>
45#undef ERROR
46#define ERROR(name) ZSTD_ERROR(name)
47
48
49/* mutex */
50#define ZSTD_pthread_mutex_t CRITICAL_SECTION
51#define ZSTD_pthread_mutex_init(a, b) ((void)(b), InitializeCriticalSection((a)), 0)
52#define ZSTD_pthread_mutex_destroy(a) DeleteCriticalSection((a))
53#define ZSTD_pthread_mutex_lock(a) EnterCriticalSection((a))
54#define ZSTD_pthread_mutex_unlock(a) LeaveCriticalSection((a))
55
56/* condition variable */
57#define ZSTD_pthread_cond_t CONDITION_VARIABLE
58#define ZSTD_pthread_cond_init(a, b) ((void)(b), InitializeConditionVariable((a)), 0)
59#define ZSTD_pthread_cond_destroy(a) ((void)(a))
60#define ZSTD_pthread_cond_wait(a, b) SleepConditionVariableCS((a), (b), INFINITE)
61#define ZSTD_pthread_cond_signal(a) WakeConditionVariable((a))
62#define ZSTD_pthread_cond_broadcast(a) WakeAllConditionVariable((a))
63
64/* ZSTD_pthread_create() and ZSTD_pthread_join() */
65typedef struct {
66 HANDLE handle;
67 void* (*start_routine)(void*);
68 void* arg;
69} ZSTD_pthread_t;
70
71int ZSTD_pthread_create(ZSTD_pthread_t* thread, const void* unused,
72 void* (*start_routine) (void*), void* arg);
73
74int ZSTD_pthread_join(ZSTD_pthread_t thread, void** value_ptr);
75
76/**
77 * add here more wrappers as required
78 */
79
80
81#elif defined(ZSTD_MULTITHREAD) /* posix assumed ; need a better detection method */
82/* === POSIX Systems === */
83# include <pthread.h>
84
85#if DEBUGLEVEL < 1
86
87#define ZSTD_pthread_mutex_t pthread_mutex_t
88#define ZSTD_pthread_mutex_init(a, b) pthread_mutex_init((a), (b))
89#define ZSTD_pthread_mutex_destroy(a) pthread_mutex_destroy((a))
90#define ZSTD_pthread_mutex_lock(a) pthread_mutex_lock((a))
91#define ZSTD_pthread_mutex_unlock(a) pthread_mutex_unlock((a))
92
93#define ZSTD_pthread_cond_t pthread_cond_t
94#define ZSTD_pthread_cond_init(a, b) pthread_cond_init((a), (b))
95#define ZSTD_pthread_cond_destroy(a) pthread_cond_destroy((a))
96#define ZSTD_pthread_cond_wait(a, b) pthread_cond_wait((a), (b))
97#define ZSTD_pthread_cond_signal(a) pthread_cond_signal((a))
98#define ZSTD_pthread_cond_broadcast(a) pthread_cond_broadcast((a))
99
100#define ZSTD_pthread_t pthread_t
101#define ZSTD_pthread_create(a, b, c, d) pthread_create((a), (b), (c), (d))
102#define ZSTD_pthread_join(a, b) pthread_join((a),(b))
103
104#else /* DEBUGLEVEL >= 1 */
105
106/* Debug implementation of threading.
107 * In this implementation we use pointers for mutexes and condition variables.
108 * This way, if we forget to init/destroy them the program will crash or ASAN
109 * will report leaks.
110 */
111
112#define ZSTD_pthread_mutex_t pthread_mutex_t*
113int ZSTD_pthread_mutex_init(ZSTD_pthread_mutex_t* mutex, pthread_mutexattr_t const* attr);
114int ZSTD_pthread_mutex_destroy(ZSTD_pthread_mutex_t* mutex);
115#define ZSTD_pthread_mutex_lock(a) pthread_mutex_lock(*(a))
116#define ZSTD_pthread_mutex_unlock(a) pthread_mutex_unlock(*(a))
117
118#define ZSTD_pthread_cond_t pthread_cond_t*
119int ZSTD_pthread_cond_init(ZSTD_pthread_cond_t* cond, pthread_condattr_t const* attr);
120int ZSTD_pthread_cond_destroy(ZSTD_pthread_cond_t* cond);
121#define ZSTD_pthread_cond_wait(a, b) pthread_cond_wait(*(a), *(b))
122#define ZSTD_pthread_cond_signal(a) pthread_cond_signal(*(a))
123#define ZSTD_pthread_cond_broadcast(a) pthread_cond_broadcast(*(a))
124
125#define ZSTD_pthread_t pthread_t
126#define ZSTD_pthread_create(a, b, c, d) pthread_create((a), (b), (c), (d))
127#define ZSTD_pthread_join(a, b) pthread_join((a),(b))
128
129#endif
130
131#else /* ZSTD_MULTITHREAD not defined */
132/* No multithreading support */
133
134typedef int ZSTD_pthread_mutex_t;
135#define ZSTD_pthread_mutex_init(a, b) ((void)(a), (void)(b), 0)
136#define ZSTD_pthread_mutex_destroy(a) ((void)(a))
137#define ZSTD_pthread_mutex_lock(a) ((void)(a))
138#define ZSTD_pthread_mutex_unlock(a) ((void)(a))
139
140typedef int ZSTD_pthread_cond_t;
141#define ZSTD_pthread_cond_init(a, b) ((void)(a), (void)(b), 0)
142#define ZSTD_pthread_cond_destroy(a) ((void)(a))
143#define ZSTD_pthread_cond_wait(a, b) ((void)(a), (void)(b))
144#define ZSTD_pthread_cond_signal(a) ((void)(a))
145#define ZSTD_pthread_cond_broadcast(a) ((void)(a))
146
147/* do not use ZSTD_pthread_t */
148
149#endif /* ZSTD_MULTITHREAD */
150
151#if defined (__cplusplus)
152}
153#endif
154
155#endif /* THREADING_H_938743 */
stage1/zstd/lib/common/xxhash.c created+24
......@@ -0,0 +1,24 @@
1/*
2 * xxHash - Fast Hash algorithm
3 * Copyright (c) Yann Collet, Facebook, Inc.
4 *
5 * You can contact the author at :
6 * - xxHash homepage: http://www.xxhash.com
7 * - xxHash source repository : https://github.com/Cyan4973/xxHash
8 *
9 * This source code is licensed under both the BSD-style license (found in the
10 * LICENSE file in the root directory of this source tree) and the GPLv2 (found
11 * in the COPYING file in the root directory of this source tree).
12 * You may select, at your option, one of the above-listed licenses.
13*/
14
15
16
17/*
18 * xxhash.c instantiates functions defined in xxhash.h
19 */
20
21#define XXH_STATIC_LINKING_ONLY /* access advanced declarations */
22#define XXH_IMPLEMENTATION /* access definitions */
23
24#include "xxhash.h"
stage1/zstd/lib/common/xxhash.h created+5686
......@@ -0,0 +1,5686 @@
1/*
2 * xxHash - Fast Hash algorithm
3 * Copyright (c) Yann Collet, Facebook, Inc.
4 *
5 * You can contact the author at :
6 * - xxHash homepage: http://www.xxhash.com
7 * - xxHash source repository : https://github.com/Cyan4973/xxHash
8 *
9 * This source code is licensed under both the BSD-style license (found in the
10 * LICENSE file in the root directory of this source tree) and the GPLv2 (found
11 * in the COPYING file in the root directory of this source tree).
12 * You may select, at your option, one of the above-listed licenses.
13*/
14
15
16#ifndef XXH_NO_XXH3
17# define XXH_NO_XXH3
18#endif
19
20#ifndef XXH_NAMESPACE
21# define XXH_NAMESPACE ZSTD_
22#endif
23
24/*!
25 * @mainpage xxHash
26 *
27 * @file xxhash.h
28 * xxHash prototypes and implementation
29 */
30/* TODO: update */
31/* Notice extracted from xxHash homepage:
32
33xxHash is an extremely fast hash algorithm, running at RAM speed limits.
34It also successfully passes all tests from the SMHasher suite.
35
36Comparison (single thread, Windows Seven 32 bits, using SMHasher on a Core 2 Duo @3GHz)
37
38Name Speed Q.Score Author
39xxHash 5.4 GB/s 10
40CrapWow 3.2 GB/s 2 Andrew
41MurmurHash 3a 2.7 GB/s 10 Austin Appleby
42SpookyHash 2.0 GB/s 10 Bob Jenkins
43SBox 1.4 GB/s 9 Bret Mulvey
44Lookup3 1.2 GB/s 9 Bob Jenkins
45SuperFastHash 1.2 GB/s 1 Paul Hsieh
46CityHash64 1.05 GB/s 10 Pike & Alakuijala
47FNV 0.55 GB/s 5 Fowler, Noll, Vo
48CRC32 0.43 GB/s 9
49MD5-32 0.33 GB/s 10 Ronald L. Rivest
50SHA1-32 0.28 GB/s 10
51
52Q.Score is a measure of quality of the hash function.
53It depends on successfully passing SMHasher test set.
5410 is a perfect score.
55
56Note: SMHasher's CRC32 implementation is not the fastest one.
57Other speed-oriented implementations can be faster,
58especially in combination with PCLMUL instruction:
59https://fastcompression.blogspot.com/2019/03/presenting-xxh3.html?showComment=1552696407071#c3490092340461170735
60
61A 64-bit version, named XXH64, is available since r35.
62It offers much better speed, but for 64-bit applications only.
63Name Speed on 64 bits Speed on 32 bits
64XXH64 13.8 GB/s 1.9 GB/s
65XXH32 6.8 GB/s 6.0 GB/s
66*/
67
68#if defined (__cplusplus)
69extern "C" {
70#endif
71
72/* ****************************
73 * INLINE mode
74 ******************************/
75/*!
76 * XXH_INLINE_ALL (and XXH_PRIVATE_API)
77 * Use these build macros to inline xxhash into the target unit.
78 * Inlining improves performance on small inputs, especially when the length is
79 * expressed as a compile-time constant:
80 *
81 * https://fastcompression.blogspot.com/2018/03/xxhash-for-small-keys-impressive-power.html
82 *
83 * It also keeps xxHash symbols private to the unit, so they are not exported.
84 *
85 * Usage:
86 * #define XXH_INLINE_ALL
87 * #include "xxhash.h"
88 *
89 * Do not compile and link xxhash.o as a separate object, as it is not useful.
90 */
91#if (defined(XXH_INLINE_ALL) || defined(XXH_PRIVATE_API)) \
92 && !defined(XXH_INLINE_ALL_31684351384)
93 /* this section should be traversed only once */
94# define XXH_INLINE_ALL_31684351384
95 /* give access to the advanced API, required to compile implementations */
96# undef XXH_STATIC_LINKING_ONLY /* avoid macro redef */
97# define XXH_STATIC_LINKING_ONLY
98 /* make all functions private */
99# undef XXH_PUBLIC_API
100# if defined(__GNUC__)
101# define XXH_PUBLIC_API static __inline __attribute__((unused))
102# elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
103# define XXH_PUBLIC_API static inline
104# elif defined(_MSC_VER)
105# define XXH_PUBLIC_API static __inline
106# else
107 /* note: this version may generate warnings for unused static functions */
108# define XXH_PUBLIC_API static
109# endif
110
111 /*
112 * This part deals with the special case where a unit wants to inline xxHash,
113 * but "xxhash.h" has previously been included without XXH_INLINE_ALL,
114 * such as part of some previously included *.h header file.
115 * Without further action, the new include would just be ignored,
116 * and functions would effectively _not_ be inlined (silent failure).
117 * The following macros solve this situation by prefixing all inlined names,
118 * avoiding naming collision with previous inclusions.
119 */
120 /* Before that, we unconditionally #undef all symbols,
121 * in case they were already defined with XXH_NAMESPACE.
122 * They will then be redefined for XXH_INLINE_ALL
123 */
124# undef XXH_versionNumber
125 /* XXH32 */
126# undef XXH32
127# undef XXH32_createState
128# undef XXH32_freeState
129# undef XXH32_reset
130# undef XXH32_update
131# undef XXH32_digest
132# undef XXH32_copyState
133# undef XXH32_canonicalFromHash
134# undef XXH32_hashFromCanonical
135 /* XXH64 */
136# undef XXH64
137# undef XXH64_createState
138# undef XXH64_freeState
139# undef XXH64_reset
140# undef XXH64_update
141# undef XXH64_digest
142# undef XXH64_copyState
143# undef XXH64_canonicalFromHash
144# undef XXH64_hashFromCanonical
145 /* XXH3_64bits */
146# undef XXH3_64bits
147# undef XXH3_64bits_withSecret
148# undef XXH3_64bits_withSeed
149# undef XXH3_64bits_withSecretandSeed
150# undef XXH3_createState
151# undef XXH3_freeState
152# undef XXH3_copyState
153# undef XXH3_64bits_reset
154# undef XXH3_64bits_reset_withSeed
155# undef XXH3_64bits_reset_withSecret
156# undef XXH3_64bits_update
157# undef XXH3_64bits_digest
158# undef XXH3_generateSecret
159 /* XXH3_128bits */
160# undef XXH128
161# undef XXH3_128bits
162# undef XXH3_128bits_withSeed
163# undef XXH3_128bits_withSecret
164# undef XXH3_128bits_reset
165# undef XXH3_128bits_reset_withSeed
166# undef XXH3_128bits_reset_withSecret
167# undef XXH3_128bits_reset_withSecretandSeed
168# undef XXH3_128bits_update
169# undef XXH3_128bits_digest
170# undef XXH128_isEqual
171# undef XXH128_cmp
172# undef XXH128_canonicalFromHash
173# undef XXH128_hashFromCanonical
174 /* Finally, free the namespace itself */
175# undef XXH_NAMESPACE
176
177 /* employ the namespace for XXH_INLINE_ALL */
178# define XXH_NAMESPACE XXH_INLINE_
179 /*
180 * Some identifiers (enums, type names) are not symbols,
181 * but they must nonetheless be renamed to avoid redeclaration.
182 * Alternative solution: do not redeclare them.
183 * However, this requires some #ifdefs, and has a more dispersed impact.
184 * Meanwhile, renaming can be achieved in a single place.
185 */
186# define XXH_IPREF(Id) XXH_NAMESPACE ## Id
187# define XXH_OK XXH_IPREF(XXH_OK)
188# define XXH_ERROR XXH_IPREF(XXH_ERROR)
189# define XXH_errorcode XXH_IPREF(XXH_errorcode)
190# define XXH32_canonical_t XXH_IPREF(XXH32_canonical_t)
191# define XXH64_canonical_t XXH_IPREF(XXH64_canonical_t)
192# define XXH128_canonical_t XXH_IPREF(XXH128_canonical_t)
193# define XXH32_state_s XXH_IPREF(XXH32_state_s)
194# define XXH32_state_t XXH_IPREF(XXH32_state_t)
195# define XXH64_state_s XXH_IPREF(XXH64_state_s)
196# define XXH64_state_t XXH_IPREF(XXH64_state_t)
197# define XXH3_state_s XXH_IPREF(XXH3_state_s)
198# define XXH3_state_t XXH_IPREF(XXH3_state_t)
199# define XXH128_hash_t XXH_IPREF(XXH128_hash_t)
200 /* Ensure the header is parsed again, even if it was previously included */
201# undef XXHASH_H_5627135585666179
202# undef XXHASH_H_STATIC_13879238742
203#endif /* XXH_INLINE_ALL || XXH_PRIVATE_API */
204
205
206
207/* ****************************************************************
208 * Stable API
209 *****************************************************************/
210#ifndef XXHASH_H_5627135585666179
211#define XXHASH_H_5627135585666179 1
212
213
214/*!
215 * @defgroup public Public API
216 * Contains details on the public xxHash functions.
217 * @{
218 */
219/* specific declaration modes for Windows */
220#if !defined(XXH_INLINE_ALL) && !defined(XXH_PRIVATE_API)
221# if defined(WIN32) && defined(_MSC_VER) && (defined(XXH_IMPORT) || defined(XXH_EXPORT))
222# ifdef XXH_EXPORT
223# define XXH_PUBLIC_API __declspec(dllexport)
224# elif XXH_IMPORT
225# define XXH_PUBLIC_API __declspec(dllimport)
226# endif
227# else
228# define XXH_PUBLIC_API /* do nothing */
229# endif
230#endif
231
232#ifdef XXH_DOXYGEN
233/*!
234 * @brief Emulate a namespace by transparently prefixing all symbols.
235 *
236 * If you want to include _and expose_ xxHash functions from within your own
237 * library, but also want to avoid symbol collisions with other libraries which
238 * may also include xxHash, you can use XXH_NAMESPACE to automatically prefix
239 * any public symbol from xxhash library with the value of XXH_NAMESPACE
240 * (therefore, avoid empty or numeric values).
241 *
242 * Note that no change is required within the calling program as long as it
243 * includes `xxhash.h`: Regular symbol names will be automatically translated
244 * by this header.
245 */
246# define XXH_NAMESPACE /* YOUR NAME HERE */
247# undef XXH_NAMESPACE
248#endif
249
250#ifdef XXH_NAMESPACE
251# define XXH_CAT(A,B) A##B
252# define XXH_NAME2(A,B) XXH_CAT(A,B)
253# define XXH_versionNumber XXH_NAME2(XXH_NAMESPACE, XXH_versionNumber)
254/* XXH32 */
255# define XXH32 XXH_NAME2(XXH_NAMESPACE, XXH32)
256# define XXH32_createState XXH_NAME2(XXH_NAMESPACE, XXH32_createState)
257# define XXH32_freeState XXH_NAME2(XXH_NAMESPACE, XXH32_freeState)
258# define XXH32_reset XXH_NAME2(XXH_NAMESPACE, XXH32_reset)
259# define XXH32_update XXH_NAME2(XXH_NAMESPACE, XXH32_update)
260# define XXH32_digest XXH_NAME2(XXH_NAMESPACE, XXH32_digest)
261# define XXH32_copyState XXH_NAME2(XXH_NAMESPACE, XXH32_copyState)
262# define XXH32_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH32_canonicalFromHash)
263# define XXH32_hashFromCanonical XXH_NAME2(XXH_NAMESPACE, XXH32_hashFromCanonical)
264/* XXH64 */
265# define XXH64 XXH_NAME2(XXH_NAMESPACE, XXH64)
266# define XXH64_createState XXH_NAME2(XXH_NAMESPACE, XXH64_createState)
267# define XXH64_freeState XXH_NAME2(XXH_NAMESPACE, XXH64_freeState)
268# define XXH64_reset XXH_NAME2(XXH_NAMESPACE, XXH64_reset)
269# define XXH64_update XXH_NAME2(XXH_NAMESPACE, XXH64_update)
270# define XXH64_digest XXH_NAME2(XXH_NAMESPACE, XXH64_digest)
271# define XXH64_copyState XXH_NAME2(XXH_NAMESPACE, XXH64_copyState)
272# define XXH64_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH64_canonicalFromHash)
273# define XXH64_hashFromCanonical XXH_NAME2(XXH_NAMESPACE, XXH64_hashFromCanonical)
274/* XXH3_64bits */
275# define XXH3_64bits XXH_NAME2(XXH_NAMESPACE, XXH3_64bits)
276# define XXH3_64bits_withSecret XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_withSecret)
277# define XXH3_64bits_withSeed XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_withSeed)
278# define XXH3_64bits_withSecretandSeed XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_withSecretandSeed)
279# define XXH3_createState XXH_NAME2(XXH_NAMESPACE, XXH3_createState)
280# define XXH3_freeState XXH_NAME2(XXH_NAMESPACE, XXH3_freeState)
281# define XXH3_copyState XXH_NAME2(XXH_NAMESPACE, XXH3_copyState)
282# define XXH3_64bits_reset XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_reset)
283# define XXH3_64bits_reset_withSeed XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_reset_withSeed)
284# define XXH3_64bits_reset_withSecret XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_reset_withSecret)
285# define XXH3_64bits_reset_withSecretandSeed XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_reset_withSecretandSeed)
286# define XXH3_64bits_update XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_update)
287# define XXH3_64bits_digest XXH_NAME2(XXH_NAMESPACE, XXH3_64bits_digest)
288# define XXH3_generateSecret XXH_NAME2(XXH_NAMESPACE, XXH3_generateSecret)
289# define XXH3_generateSecret_fromSeed XXH_NAME2(XXH_NAMESPACE, XXH3_generateSecret_fromSeed)
290/* XXH3_128bits */
291# define XXH128 XXH_NAME2(XXH_NAMESPACE, XXH128)
292# define XXH3_128bits XXH_NAME2(XXH_NAMESPACE, XXH3_128bits)
293# define XXH3_128bits_withSeed XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_withSeed)
294# define XXH3_128bits_withSecret XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_withSecret)
295# define XXH3_128bits_withSecretandSeed XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_withSecretandSeed)
296# define XXH3_128bits_reset XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_reset)
297# define XXH3_128bits_reset_withSeed XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_reset_withSeed)
298# define XXH3_128bits_reset_withSecret XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_reset_withSecret)
299# define XXH3_128bits_reset_withSecretandSeed XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_reset_withSecretandSeed)
300# define XXH3_128bits_update XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_update)
301# define XXH3_128bits_digest XXH_NAME2(XXH_NAMESPACE, XXH3_128bits_digest)
302# define XXH128_isEqual XXH_NAME2(XXH_NAMESPACE, XXH128_isEqual)
303# define XXH128_cmp XXH_NAME2(XXH_NAMESPACE, XXH128_cmp)
304# define XXH128_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH128_canonicalFromHash)
305# define XXH128_hashFromCanonical XXH_NAME2(XXH_NAMESPACE, XXH128_hashFromCanonical)
306#endif
307
308
309/* *************************************
310* Version
311***************************************/
312#define XXH_VERSION_MAJOR 0
313#define XXH_VERSION_MINOR 8
314#define XXH_VERSION_RELEASE 1
315#define XXH_VERSION_NUMBER (XXH_VERSION_MAJOR *100*100 + XXH_VERSION_MINOR *100 + XXH_VERSION_RELEASE)
316
317/*!
318 * @brief Obtains the xxHash version.
319 *
320 * This is mostly useful when xxHash is compiled as a shared library,
321 * since the returned value comes from the library, as opposed to header file.
322 *
323 * @return `XXH_VERSION_NUMBER` of the invoked library.
324 */
325XXH_PUBLIC_API unsigned XXH_versionNumber (void);
326
327
328/* ****************************
329* Common basic types
330******************************/
331#include <stddef.h> /* size_t */
332typedef enum { XXH_OK=0, XXH_ERROR } XXH_errorcode;
333
334
335/*-**********************************************************************
336* 32-bit hash
337************************************************************************/
338#if defined(XXH_DOXYGEN) /* Don't show <stdint.h> include */
339/*!
340 * @brief An unsigned 32-bit integer.
341 *
342 * Not necessarily defined to `uint32_t` but functionally equivalent.
343 */
344typedef uint32_t XXH32_hash_t;
345
346#elif !defined (__VMS) \
347 && (defined (__cplusplus) \
348 || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) )
349# include <stdint.h>
350 typedef uint32_t XXH32_hash_t;
351
352#else
353# include <limits.h>
354# if UINT_MAX == 0xFFFFFFFFUL
355 typedef unsigned int XXH32_hash_t;
356# else
357# if ULONG_MAX == 0xFFFFFFFFUL
358 typedef unsigned long XXH32_hash_t;
359# else
360# error "unsupported platform: need a 32-bit type"
361# endif
362# endif
363#endif
364
365/*!
366 * @}
367 *
368 * @defgroup xxh32_family XXH32 family
369 * @ingroup public
370 * Contains functions used in the classic 32-bit xxHash algorithm.
371 *
372 * @note
373 * XXH32 is useful for older platforms, with no or poor 64-bit performance.
374 * Note that @ref xxh3_family provides competitive speed
375 * for both 32-bit and 64-bit systems, and offers true 64/128 bit hash results.
376 *
377 * @see @ref xxh64_family, @ref xxh3_family : Other xxHash families
378 * @see @ref xxh32_impl for implementation details
379 * @{
380 */
381
382/*!
383 * @brief Calculates the 32-bit hash of @p input using xxHash32.
384 *
385 * Speed on Core 2 Duo @ 3 GHz (single thread, SMHasher benchmark): 5.4 GB/s
386 *
387 * @param input The block of data to be hashed, at least @p length bytes in size.
388 * @param length The length of @p input, in bytes.
389 * @param seed The 32-bit seed to alter the hash's output predictably.
390 *
391 * @pre
392 * The memory between @p input and @p input + @p length must be valid,
393 * readable, contiguous memory. However, if @p length is `0`, @p input may be
394 * `NULL`. In C++, this also must be *TriviallyCopyable*.
395 *
396 * @return The calculated 32-bit hash value.
397 *
398 * @see
399 * XXH64(), XXH3_64bits_withSeed(), XXH3_128bits_withSeed(), XXH128():
400 * Direct equivalents for the other variants of xxHash.
401 * @see
402 * XXH32_createState(), XXH32_update(), XXH32_digest(): Streaming version.
403 */
404XXH_PUBLIC_API XXH32_hash_t XXH32 (const void* input, size_t length, XXH32_hash_t seed);
405
406/*!
407 * Streaming functions generate the xxHash value from an incremental input.
408 * This method is slower than single-call functions, due to state management.
409 * For small inputs, prefer `XXH32()` and `XXH64()`, which are better optimized.
410 *
411 * An XXH state must first be allocated using `XXH*_createState()`.
412 *
413 * Start a new hash by initializing the state with a seed using `XXH*_reset()`.
414 *
415 * Then, feed the hash state by calling `XXH*_update()` as many times as necessary.
416 *
417 * The function returns an error code, with 0 meaning OK, and any other value
418 * meaning there is an error.
419 *
420 * Finally, a hash value can be produced anytime, by using `XXH*_digest()`.
421 * This function returns the nn-bits hash as an int or long long.
422 *
423 * It's still possible to continue inserting input into the hash state after a
424 * digest, and generate new hash values later on by invoking `XXH*_digest()`.
425 *
426 * When done, release the state using `XXH*_freeState()`.
427 *
428 * Example code for incrementally hashing a file:
429 * @code{.c}
430 * #include <stdio.h>
431 * #include <xxhash.h>
432 * #define BUFFER_SIZE 256
433 *
434 * // Note: XXH64 and XXH3 use the same interface.
435 * XXH32_hash_t
436 * hashFile(FILE* stream)
437 * {
438 * XXH32_state_t* state;
439 * unsigned char buf[BUFFER_SIZE];
440 * size_t amt;
441 * XXH32_hash_t hash;
442 *
443 * state = XXH32_createState(); // Create a state
444 * assert(state != NULL); // Error check here
445 * XXH32_reset(state, 0xbaad5eed); // Reset state with our seed
446 * while ((amt = fread(buf, 1, sizeof(buf), stream)) != 0) {
447 * XXH32_update(state, buf, amt); // Hash the file in chunks
448 * }
449 * hash = XXH32_digest(state); // Finalize the hash
450 * XXH32_freeState(state); // Clean up
451 * return hash;
452 * }
453 * @endcode
454 */
455
456/*!
457 * @typedef struct XXH32_state_s XXH32_state_t
458 * @brief The opaque state struct for the XXH32 streaming API.
459 *
460 * @see XXH32_state_s for details.
461 */
462typedef struct XXH32_state_s XXH32_state_t;
463
464/*!
465 * @brief Allocates an @ref XXH32_state_t.
466 *
467 * Must be freed with XXH32_freeState().
468 * @return An allocated XXH32_state_t on success, `NULL` on failure.
469 */
470XXH_PUBLIC_API XXH32_state_t* XXH32_createState(void);
471/*!
472 * @brief Frees an @ref XXH32_state_t.
473 *
474 * Must be allocated with XXH32_createState().
475 * @param statePtr A pointer to an @ref XXH32_state_t allocated with @ref XXH32_createState().
476 * @return XXH_OK.
477 */
478XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr);
479/*!
480 * @brief Copies one @ref XXH32_state_t to another.
481 *
482 * @param dst_state The state to copy to.
483 * @param src_state The state to copy from.
484 * @pre
485 * @p dst_state and @p src_state must not be `NULL` and must not overlap.
486 */
487XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* dst_state, const XXH32_state_t* src_state);
488
489/*!
490 * @brief Resets an @ref XXH32_state_t to begin a new hash.
491 *
492 * This function resets and seeds a state. Call it before @ref XXH32_update().
493 *
494 * @param statePtr The state struct to reset.
495 * @param seed The 32-bit seed to alter the hash result predictably.
496 *
497 * @pre
498 * @p statePtr must not be `NULL`.
499 *
500 * @return @ref XXH_OK on success, @ref XXH_ERROR on failure.
501 */
502XXH_PUBLIC_API XXH_errorcode XXH32_reset (XXH32_state_t* statePtr, XXH32_hash_t seed);
503
504/*!
505 * @brief Consumes a block of @p input to an @ref XXH32_state_t.
506 *
507 * Call this to incrementally consume blocks of data.
508 *
509 * @param statePtr The state struct to update.
510 * @param input The block of data to be hashed, at least @p length bytes in size.
511 * @param length The length of @p input, in bytes.
512 *
513 * @pre
514 * @p statePtr must not be `NULL`.
515 * @pre
516 * The memory between @p input and @p input + @p length must be valid,
517 * readable, contiguous memory. However, if @p length is `0`, @p input may be
518 * `NULL`. In C++, this also must be *TriviallyCopyable*.
519 *
520 * @return @ref XXH_OK on success, @ref XXH_ERROR on failure.
521 */
522XXH_PUBLIC_API XXH_errorcode XXH32_update (XXH32_state_t* statePtr, const void* input, size_t length);
523
524/*!
525 * @brief Returns the calculated hash value from an @ref XXH32_state_t.
526 *
527 * @note
528 * Calling XXH32_digest() will not affect @p statePtr, so you can update,
529 * digest, and update again.
530 *
531 * @param statePtr The state struct to calculate the hash from.
532 *
533 * @pre
534 * @p statePtr must not be `NULL`.
535 *
536 * @return The calculated xxHash32 value from that state.
537 */
538XXH_PUBLIC_API XXH32_hash_t XXH32_digest (const XXH32_state_t* statePtr);
539
540/******* Canonical representation *******/
541
542/*
543 * The default return values from XXH functions are unsigned 32 and 64 bit
544 * integers.
545 * This the simplest and fastest format for further post-processing.
546 *
547 * However, this leaves open the question of what is the order on the byte level,
548 * since little and big endian conventions will store the same number differently.
549 *
550 * The canonical representation settles this issue by mandating big-endian
551 * convention, the same convention as human-readable numbers (large digits first).
552 *
553 * When writing hash values to storage, sending them over a network, or printing
554 * them, it's highly recommended to use the canonical representation to ensure
555 * portability across a wider range of systems, present and future.
556 *
557 * The following functions allow transformation of hash values to and from
558 * canonical format.
559 */
560
561/*!
562 * @brief Canonical (big endian) representation of @ref XXH32_hash_t.
563 */
564typedef struct {
565 unsigned char digest[4]; /*!< Hash bytes, big endian */
566} XXH32_canonical_t;
567
568/*!
569 * @brief Converts an @ref XXH32_hash_t to a big endian @ref XXH32_canonical_t.
570 *
571 * @param dst The @ref XXH32_canonical_t pointer to be stored to.
572 * @param hash The @ref XXH32_hash_t to be converted.
573 *
574 * @pre
575 * @p dst must not be `NULL`.
576 */
577XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash);
578
579/*!
580 * @brief Converts an @ref XXH32_canonical_t to a native @ref XXH32_hash_t.
581 *
582 * @param src The @ref XXH32_canonical_t to convert.
583 *
584 * @pre
585 * @p src must not be `NULL`.
586 *
587 * @return The converted hash.
588 */
589XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src);
590
591
592#ifdef __has_attribute
593# define XXH_HAS_ATTRIBUTE(x) __has_attribute(x)
594#else
595# define XXH_HAS_ATTRIBUTE(x) 0
596#endif
597
598/* C-language Attributes are added in C23. */
599#if defined(__STDC_VERSION__) && (__STDC_VERSION__ > 201710L) && defined(__has_c_attribute)
600# define XXH_HAS_C_ATTRIBUTE(x) __has_c_attribute(x)
601#else
602# define XXH_HAS_C_ATTRIBUTE(x) 0
603#endif
604
605#if defined(__cplusplus) && defined(__has_cpp_attribute)
606# define XXH_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)
607#else
608# define XXH_HAS_CPP_ATTRIBUTE(x) 0
609#endif
610
611/*
612Define XXH_FALLTHROUGH macro for annotating switch case with the 'fallthrough' attribute
613introduced in CPP17 and C23.
614CPP17 : https://en.cppreference.com/w/cpp/language/attributes/fallthrough
615C23 : https://en.cppreference.com/w/c/language/attributes/fallthrough
616*/
617#if XXH_HAS_C_ATTRIBUTE(x)
618# define XXH_FALLTHROUGH [[fallthrough]]
619#elif XXH_HAS_CPP_ATTRIBUTE(x)
620# define XXH_FALLTHROUGH [[fallthrough]]
621#elif XXH_HAS_ATTRIBUTE(__fallthrough__)
622# define XXH_FALLTHROUGH __attribute__ ((fallthrough))
623#else
624# define XXH_FALLTHROUGH
625#endif
626
627/*!
628 * @}
629 * @ingroup public
630 * @{
631 */
632
633#ifndef XXH_NO_LONG_LONG
634/*-**********************************************************************
635* 64-bit hash
636************************************************************************/
637#if defined(XXH_DOXYGEN) /* don't include <stdint.h> */
638/*!
639 * @brief An unsigned 64-bit integer.
640 *
641 * Not necessarily defined to `uint64_t` but functionally equivalent.
642 */
643typedef uint64_t XXH64_hash_t;
644#elif !defined (__VMS) \
645 && (defined (__cplusplus) \
646 || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) )
647# include <stdint.h>
648 typedef uint64_t XXH64_hash_t;
649#else
650# include <limits.h>
651# if defined(__LP64__) && ULONG_MAX == 0xFFFFFFFFFFFFFFFFULL
652 /* LP64 ABI says uint64_t is unsigned long */
653 typedef unsigned long XXH64_hash_t;
654# else
655 /* the following type must have a width of 64-bit */
656 typedef unsigned long long XXH64_hash_t;
657# endif
658#endif
659
660/*!
661 * @}
662 *
663 * @defgroup xxh64_family XXH64 family
664 * @ingroup public
665 * @{
666 * Contains functions used in the classic 64-bit xxHash algorithm.
667 *
668 * @note
669 * XXH3 provides competitive speed for both 32-bit and 64-bit systems,
670 * and offers true 64/128 bit hash results.
671 * It provides better speed for systems with vector processing capabilities.
672 */
673
674
675/*!
676 * @brief Calculates the 64-bit hash of @p input using xxHash64.
677 *
678 * This function usually runs faster on 64-bit systems, but slower on 32-bit
679 * systems (see benchmark).
680 *
681 * @param input The block of data to be hashed, at least @p length bytes in size.
682 * @param length The length of @p input, in bytes.
683 * @param seed The 64-bit seed to alter the hash's output predictably.
684 *
685 * @pre
686 * The memory between @p input and @p input + @p length must be valid,
687 * readable, contiguous memory. However, if @p length is `0`, @p input may be
688 * `NULL`. In C++, this also must be *TriviallyCopyable*.
689 *
690 * @return The calculated 64-bit hash.
691 *
692 * @see
693 * XXH32(), XXH3_64bits_withSeed(), XXH3_128bits_withSeed(), XXH128():
694 * Direct equivalents for the other variants of xxHash.
695 * @see
696 * XXH64_createState(), XXH64_update(), XXH64_digest(): Streaming version.
697 */
698XXH_PUBLIC_API XXH64_hash_t XXH64(const void* input, size_t length, XXH64_hash_t seed);
699
700/******* Streaming *******/
701/*!
702 * @brief The opaque state struct for the XXH64 streaming API.
703 *
704 * @see XXH64_state_s for details.
705 */
706typedef struct XXH64_state_s XXH64_state_t; /* incomplete type */
707XXH_PUBLIC_API XXH64_state_t* XXH64_createState(void);
708XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr);
709XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t* dst_state, const XXH64_state_t* src_state);
710
711XXH_PUBLIC_API XXH_errorcode XXH64_reset (XXH64_state_t* statePtr, XXH64_hash_t seed);
712XXH_PUBLIC_API XXH_errorcode XXH64_update (XXH64_state_t* statePtr, const void* input, size_t length);
713XXH_PUBLIC_API XXH64_hash_t XXH64_digest (const XXH64_state_t* statePtr);
714
715/******* Canonical representation *******/
716typedef struct { unsigned char digest[sizeof(XXH64_hash_t)]; } XXH64_canonical_t;
717XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash);
718XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src);
719
720#ifndef XXH_NO_XXH3
721/*!
722 * @}
723 * ************************************************************************
724 * @defgroup xxh3_family XXH3 family
725 * @ingroup public
726 * @{
727 *
728 * XXH3 is a more recent hash algorithm featuring:
729 * - Improved speed for both small and large inputs
730 * - True 64-bit and 128-bit outputs
731 * - SIMD acceleration
732 * - Improved 32-bit viability
733 *
734 * Speed analysis methodology is explained here:
735 *
736 * https://fastcompression.blogspot.com/2019/03/presenting-xxh3.html
737 *
738 * Compared to XXH64, expect XXH3 to run approximately
739 * ~2x faster on large inputs and >3x faster on small ones,
740 * exact differences vary depending on platform.
741 *
742 * XXH3's speed benefits greatly from SIMD and 64-bit arithmetic,
743 * but does not require it.
744 * Any 32-bit and 64-bit targets that can run XXH32 smoothly
745 * can run XXH3 at competitive speeds, even without vector support.
746 * Further details are explained in the implementation.
747 *
748 * Optimized implementations are provided for AVX512, AVX2, SSE2, NEON, POWER8,
749 * ZVector and scalar targets. This can be controlled via the XXH_VECTOR macro.
750 *
751 * XXH3 implementation is portable:
752 * it has a generic C90 formulation that can be compiled on any platform,
753 * all implementations generage exactly the same hash value on all platforms.
754 * Starting from v0.8.0, it's also labelled "stable", meaning that
755 * any future version will also generate the same hash value.
756 *
757 * XXH3 offers 2 variants, _64bits and _128bits.
758 *
759 * When only 64 bits are needed, prefer invoking the _64bits variant, as it
760 * reduces the amount of mixing, resulting in faster speed on small inputs.
761 * It's also generally simpler to manipulate a scalar return type than a struct.
762 *
763 * The API supports one-shot hashing, streaming mode, and custom secrets.
764 */
765
766/*-**********************************************************************
767* XXH3 64-bit variant
768************************************************************************/
769
770/* XXH3_64bits():
771 * default 64-bit variant, using default secret and default seed of 0.
772 * It's the fastest variant. */
773XXH_PUBLIC_API XXH64_hash_t XXH3_64bits(const void* data, size_t len);
774
775/*
776 * XXH3_64bits_withSeed():
777 * This variant generates a custom secret on the fly
778 * based on default secret altered using the `seed` value.
779 * While this operation is decently fast, note that it's not completely free.
780 * Note: seed==0 produces the same results as XXH3_64bits().
781 */
782XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_withSeed(const void* data, size_t len, XXH64_hash_t seed);
783
784/*!
785 * The bare minimum size for a custom secret.
786 *
787 * @see
788 * XXH3_64bits_withSecret(), XXH3_64bits_reset_withSecret(),
789 * XXH3_128bits_withSecret(), XXH3_128bits_reset_withSecret().
790 */
791#define XXH3_SECRET_SIZE_MIN 136
792
793/*
794 * XXH3_64bits_withSecret():
795 * It's possible to provide any blob of bytes as a "secret" to generate the hash.
796 * This makes it more difficult for an external actor to prepare an intentional collision.
797 * The main condition is that secretSize *must* be large enough (>= XXH3_SECRET_SIZE_MIN).
798 * However, the quality of the secret impacts the dispersion of the hash algorithm.
799 * Therefore, the secret _must_ look like a bunch of random bytes.
800 * Avoid "trivial" or structured data such as repeated sequences or a text document.
801 * Whenever in doubt about the "randomness" of the blob of bytes,
802 * consider employing "XXH3_generateSecret()" instead (see below).
803 * It will generate a proper high entropy secret derived from the blob of bytes.
804 * Another advantage of using XXH3_generateSecret() is that
805 * it guarantees that all bits within the initial blob of bytes
806 * will impact every bit of the output.
807 * This is not necessarily the case when using the blob of bytes directly
808 * because, when hashing _small_ inputs, only a portion of the secret is employed.
809 */
810XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_withSecret(const void* data, size_t len, const void* secret, size_t secretSize);
811
812
813/******* Streaming *******/
814/*
815 * Streaming requires state maintenance.
816 * This operation costs memory and CPU.
817 * As a consequence, streaming is slower than one-shot hashing.
818 * For better performance, prefer one-shot functions whenever applicable.
819 */
820
821/*!
822 * @brief The state struct for the XXH3 streaming API.
823 *
824 * @see XXH3_state_s for details.
825 */
826typedef struct XXH3_state_s XXH3_state_t;
827XXH_PUBLIC_API XXH3_state_t* XXH3_createState(void);
828XXH_PUBLIC_API XXH_errorcode XXH3_freeState(XXH3_state_t* statePtr);
829XXH_PUBLIC_API void XXH3_copyState(XXH3_state_t* dst_state, const XXH3_state_t* src_state);
830
831/*
832 * XXH3_64bits_reset():
833 * Initialize with default parameters.
834 * digest will be equivalent to `XXH3_64bits()`.
835 */
836XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset(XXH3_state_t* statePtr);
837/*
838 * XXH3_64bits_reset_withSeed():
839 * Generate a custom secret from `seed`, and store it into `statePtr`.
840 * digest will be equivalent to `XXH3_64bits_withSeed()`.
841 */
842XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSeed(XXH3_state_t* statePtr, XXH64_hash_t seed);
843/*
844 * XXH3_64bits_reset_withSecret():
845 * `secret` is referenced, it _must outlive_ the hash streaming session.
846 * Similar to one-shot API, `secretSize` must be >= `XXH3_SECRET_SIZE_MIN`,
847 * and the quality of produced hash values depends on secret's entropy
848 * (secret's content should look like a bunch of random bytes).
849 * When in doubt about the randomness of a candidate `secret`,
850 * consider employing `XXH3_generateSecret()` instead (see below).
851 */
852XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSecret(XXH3_state_t* statePtr, const void* secret, size_t secretSize);
853
854XXH_PUBLIC_API XXH_errorcode XXH3_64bits_update (XXH3_state_t* statePtr, const void* input, size_t length);
855XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_digest (const XXH3_state_t* statePtr);
856
857/* note : canonical representation of XXH3 is the same as XXH64
858 * since they both produce XXH64_hash_t values */
859
860
861/*-**********************************************************************
862* XXH3 128-bit variant
863************************************************************************/
864
865/*!
866 * @brief The return value from 128-bit hashes.
867 *
868 * Stored in little endian order, although the fields themselves are in native
869 * endianness.
870 */
871typedef struct {
872 XXH64_hash_t low64; /*!< `value & 0xFFFFFFFFFFFFFFFF` */
873 XXH64_hash_t high64; /*!< `value >> 64` */
874} XXH128_hash_t;
875
876XXH_PUBLIC_API XXH128_hash_t XXH3_128bits(const void* data, size_t len);
877XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_withSeed(const void* data, size_t len, XXH64_hash_t seed);
878XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_withSecret(const void* data, size_t len, const void* secret, size_t secretSize);
879
880/******* Streaming *******/
881/*
882 * Streaming requires state maintenance.
883 * This operation costs memory and CPU.
884 * As a consequence, streaming is slower than one-shot hashing.
885 * For better performance, prefer one-shot functions whenever applicable.
886 *
887 * XXH3_128bits uses the same XXH3_state_t as XXH3_64bits().
888 * Use already declared XXH3_createState() and XXH3_freeState().
889 *
890 * All reset and streaming functions have same meaning as their 64-bit counterpart.
891 */
892
893XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset(XXH3_state_t* statePtr);
894XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSeed(XXH3_state_t* statePtr, XXH64_hash_t seed);
895XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSecret(XXH3_state_t* statePtr, const void* secret, size_t secretSize);
896
897XXH_PUBLIC_API XXH_errorcode XXH3_128bits_update (XXH3_state_t* statePtr, const void* input, size_t length);
898XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_digest (const XXH3_state_t* statePtr);
899
900/* Following helper functions make it possible to compare XXH128_hast_t values.
901 * Since XXH128_hash_t is a structure, this capability is not offered by the language.
902 * Note: For better performance, these functions can be inlined using XXH_INLINE_ALL */
903
904/*!
905 * XXH128_isEqual():
906 * Return: 1 if `h1` and `h2` are equal, 0 if they are not.
907 */
908XXH_PUBLIC_API int XXH128_isEqual(XXH128_hash_t h1, XXH128_hash_t h2);
909
910/*!
911 * XXH128_cmp():
912 *
913 * This comparator is compatible with stdlib's `qsort()`/`bsearch()`.
914 *
915 * return: >0 if *h128_1 > *h128_2
916 * =0 if *h128_1 == *h128_2
917 * <0 if *h128_1 < *h128_2
918 */
919XXH_PUBLIC_API int XXH128_cmp(const void* h128_1, const void* h128_2);
920
921
922/******* Canonical representation *******/
923typedef struct { unsigned char digest[sizeof(XXH128_hash_t)]; } XXH128_canonical_t;
924XXH_PUBLIC_API void XXH128_canonicalFromHash(XXH128_canonical_t* dst, XXH128_hash_t hash);
925XXH_PUBLIC_API XXH128_hash_t XXH128_hashFromCanonical(const XXH128_canonical_t* src);
926
927
928#endif /* !XXH_NO_XXH3 */
929#endif /* XXH_NO_LONG_LONG */
930
931/*!
932 * @}
933 */
934#endif /* XXHASH_H_5627135585666179 */
935
936
937
938#if defined(XXH_STATIC_LINKING_ONLY) && !defined(XXHASH_H_STATIC_13879238742)
939#define XXHASH_H_STATIC_13879238742
940/* ****************************************************************************
941 * This section contains declarations which are not guaranteed to remain stable.
942 * They may change in future versions, becoming incompatible with a different
943 * version of the library.
944 * These declarations should only be used with static linking.
945 * Never use them in association with dynamic linking!
946 ***************************************************************************** */
947
948/*
949 * These definitions are only present to allow static allocation
950 * of XXH states, on stack or in a struct, for example.
951 * Never **ever** access their members directly.
952 */
953
954/*!
955 * @internal
956 * @brief Structure for XXH32 streaming API.
957 *
958 * @note This is only defined when @ref XXH_STATIC_LINKING_ONLY,
959 * @ref XXH_INLINE_ALL, or @ref XXH_IMPLEMENTATION is defined. Otherwise it is
960 * an opaque type. This allows fields to safely be changed.
961 *
962 * Typedef'd to @ref XXH32_state_t.
963 * Do not access the members of this struct directly.
964 * @see XXH64_state_s, XXH3_state_s
965 */
966struct XXH32_state_s {
967 XXH32_hash_t total_len_32; /*!< Total length hashed, modulo 2^32 */
968 XXH32_hash_t large_len; /*!< Whether the hash is >= 16 (handles @ref total_len_32 overflow) */
969 XXH32_hash_t v[4]; /*!< Accumulator lanes */
970 XXH32_hash_t mem32[4]; /*!< Internal buffer for partial reads. Treated as unsigned char[16]. */
971 XXH32_hash_t memsize; /*!< Amount of data in @ref mem32 */
972 XXH32_hash_t reserved; /*!< Reserved field. Do not read nor write to it. */
973}; /* typedef'd to XXH32_state_t */
974
975
976#ifndef XXH_NO_LONG_LONG /* defined when there is no 64-bit support */
977
978/*!
979 * @internal
980 * @brief Structure for XXH64 streaming API.
981 *
982 * @note This is only defined when @ref XXH_STATIC_LINKING_ONLY,
983 * @ref XXH_INLINE_ALL, or @ref XXH_IMPLEMENTATION is defined. Otherwise it is
984 * an opaque type. This allows fields to safely be changed.
985 *
986 * Typedef'd to @ref XXH64_state_t.
987 * Do not access the members of this struct directly.
988 * @see XXH32_state_s, XXH3_state_s
989 */
990struct XXH64_state_s {
991 XXH64_hash_t total_len; /*!< Total length hashed. This is always 64-bit. */
992 XXH64_hash_t v[4]; /*!< Accumulator lanes */
993 XXH64_hash_t mem64[4]; /*!< Internal buffer for partial reads. Treated as unsigned char[32]. */
994 XXH32_hash_t memsize; /*!< Amount of data in @ref mem64 */
995 XXH32_hash_t reserved32; /*!< Reserved field, needed for padding anyways*/
996 XXH64_hash_t reserved64; /*!< Reserved field. Do not read or write to it. */
997}; /* typedef'd to XXH64_state_t */
998
999
1000#ifndef XXH_NO_XXH3
1001
1002#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) /* >= C11 */
1003# include <stdalign.h>
1004# define XXH_ALIGN(n) alignas(n)
1005#elif defined(__cplusplus) && (__cplusplus >= 201103L) /* >= C++11 */
1006/* In C++ alignas() is a keyword */
1007# define XXH_ALIGN(n) alignas(n)
1008#elif defined(__GNUC__)
1009# define XXH_ALIGN(n) __attribute__ ((aligned(n)))
1010#elif defined(_MSC_VER)
1011# define XXH_ALIGN(n) __declspec(align(n))
1012#else
1013# define XXH_ALIGN(n) /* disabled */
1014#endif
1015
1016/* Old GCC versions only accept the attribute after the type in structures. */
1017#if !(defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) /* C11+ */ \
1018 && ! (defined(__cplusplus) && (__cplusplus >= 201103L)) /* >= C++11 */ \
1019 && defined(__GNUC__)
1020# define XXH_ALIGN_MEMBER(align, type) type XXH_ALIGN(align)
1021#else
1022# define XXH_ALIGN_MEMBER(align, type) XXH_ALIGN(align) type
1023#endif
1024
1025/*!
1026 * @brief The size of the internal XXH3 buffer.
1027 *
1028 * This is the optimal update size for incremental hashing.
1029 *
1030 * @see XXH3_64b_update(), XXH3_128b_update().
1031 */
1032#define XXH3_INTERNALBUFFER_SIZE 256
1033
1034/*!
1035 * @brief Default size of the secret buffer (and @ref XXH3_kSecret).
1036 *
1037 * This is the size used in @ref XXH3_kSecret and the seeded functions.
1038 *
1039 * Not to be confused with @ref XXH3_SECRET_SIZE_MIN.
1040 */
1041#define XXH3_SECRET_DEFAULT_SIZE 192
1042
1043/*!
1044 * @internal
1045 * @brief Structure for XXH3 streaming API.
1046 *
1047 * @note This is only defined when @ref XXH_STATIC_LINKING_ONLY,
1048 * @ref XXH_INLINE_ALL, or @ref XXH_IMPLEMENTATION is defined.
1049 * Otherwise it is an opaque type.
1050 * Never use this definition in combination with dynamic library.
1051 * This allows fields to safely be changed in the future.
1052 *
1053 * @note ** This structure has a strict alignment requirement of 64 bytes!! **
1054 * Do not allocate this with `malloc()` or `new`,
1055 * it will not be sufficiently aligned.
1056 * Use @ref XXH3_createState() and @ref XXH3_freeState(), or stack allocation.
1057 *
1058 * Typedef'd to @ref XXH3_state_t.
1059 * Do never access the members of this struct directly.
1060 *
1061 * @see XXH3_INITSTATE() for stack initialization.
1062 * @see XXH3_createState(), XXH3_freeState().
1063 * @see XXH32_state_s, XXH64_state_s
1064 */
1065struct XXH3_state_s {
1066 XXH_ALIGN_MEMBER(64, XXH64_hash_t acc[8]);
1067 /*!< The 8 accumulators. Similar to `vN` in @ref XXH32_state_s::v1 and @ref XXH64_state_s */
1068 XXH_ALIGN_MEMBER(64, unsigned char customSecret[XXH3_SECRET_DEFAULT_SIZE]);
1069 /*!< Used to store a custom secret generated from a seed. */
1070 XXH_ALIGN_MEMBER(64, unsigned char buffer[XXH3_INTERNALBUFFER_SIZE]);
1071 /*!< The internal buffer. @see XXH32_state_s::mem32 */
1072 XXH32_hash_t bufferedSize;
1073 /*!< The amount of memory in @ref buffer, @see XXH32_state_s::memsize */
1074 XXH32_hash_t useSeed;
1075 /*!< Reserved field. Needed for padding on 64-bit. */
1076 size_t nbStripesSoFar;
1077 /*!< Number or stripes processed. */
1078 XXH64_hash_t totalLen;
1079 /*!< Total length hashed. 64-bit even on 32-bit targets. */
1080 size_t nbStripesPerBlock;
1081 /*!< Number of stripes per block. */
1082 size_t secretLimit;
1083 /*!< Size of @ref customSecret or @ref extSecret */
1084 XXH64_hash_t seed;
1085 /*!< Seed for _withSeed variants. Must be zero otherwise, @see XXH3_INITSTATE() */
1086 XXH64_hash_t reserved64;
1087 /*!< Reserved field. */
1088 const unsigned char* extSecret;
1089 /*!< Reference to an external secret for the _withSecret variants, NULL
1090 * for other variants. */
1091 /* note: there may be some padding at the end due to alignment on 64 bytes */
1092}; /* typedef'd to XXH3_state_t */
1093
1094#undef XXH_ALIGN_MEMBER
1095
1096/*!
1097 * @brief Initializes a stack-allocated `XXH3_state_s`.
1098 *
1099 * When the @ref XXH3_state_t structure is merely emplaced on stack,
1100 * it should be initialized with XXH3_INITSTATE() or a memset()
1101 * in case its first reset uses XXH3_NNbits_reset_withSeed().
1102 * This init can be omitted if the first reset uses default or _withSecret mode.
1103 * This operation isn't necessary when the state is created with XXH3_createState().
1104 * Note that this doesn't prepare the state for a streaming operation,
1105 * it's still necessary to use XXH3_NNbits_reset*() afterwards.
1106 */
1107#define XXH3_INITSTATE(XXH3_state_ptr) { (XXH3_state_ptr)->seed = 0; }
1108
1109
1110/* XXH128() :
1111 * simple alias to pre-selected XXH3_128bits variant
1112 */
1113XXH_PUBLIC_API XXH128_hash_t XXH128(const void* data, size_t len, XXH64_hash_t seed);
1114
1115
1116/* === Experimental API === */
1117/* Symbols defined below must be considered tied to a specific library version. */
1118
1119/*
1120 * XXH3_generateSecret():
1121 *
1122 * Derive a high-entropy secret from any user-defined content, named customSeed.
1123 * The generated secret can be used in combination with `*_withSecret()` functions.
1124 * The `_withSecret()` variants are useful to provide a higher level of protection than 64-bit seed,
1125 * as it becomes much more difficult for an external actor to guess how to impact the calculation logic.
1126 *
1127 * The function accepts as input a custom seed of any length and any content,
1128 * and derives from it a high-entropy secret of length @secretSize
1129 * into an already allocated buffer @secretBuffer.
1130 * @secretSize must be >= XXH3_SECRET_SIZE_MIN
1131 *
1132 * The generated secret can then be used with any `*_withSecret()` variant.
1133 * Functions `XXH3_128bits_withSecret()`, `XXH3_64bits_withSecret()`,
1134 * `XXH3_128bits_reset_withSecret()` and `XXH3_64bits_reset_withSecret()`
1135 * are part of this list. They all accept a `secret` parameter
1136 * which must be large enough for implementation reasons (>= XXH3_SECRET_SIZE_MIN)
1137 * _and_ feature very high entropy (consist of random-looking bytes).
1138 * These conditions can be a high bar to meet, so
1139 * XXH3_generateSecret() can be employed to ensure proper quality.
1140 *
1141 * customSeed can be anything. It can have any size, even small ones,
1142 * and its content can be anything, even "poor entropy" sources such as a bunch of zeroes.
1143 * The resulting `secret` will nonetheless provide all required qualities.
1144 *
1145 * When customSeedSize > 0, supplying NULL as customSeed is undefined behavior.
1146 */
1147XXH_PUBLIC_API XXH_errorcode XXH3_generateSecret(void* secretBuffer, size_t secretSize, const void* customSeed, size_t customSeedSize);
1148
1149
1150/*
1151 * XXH3_generateSecret_fromSeed():
1152 *
1153 * Generate the same secret as the _withSeed() variants.
1154 *
1155 * The resulting secret has a length of XXH3_SECRET_DEFAULT_SIZE (necessarily).
1156 * @secretBuffer must be already allocated, of size at least XXH3_SECRET_DEFAULT_SIZE bytes.
1157 *
1158 * The generated secret can be used in combination with
1159 *`*_withSecret()` and `_withSecretandSeed()` variants.
1160 * This generator is notably useful in combination with `_withSecretandSeed()`,
1161 * as a way to emulate a faster `_withSeed()` variant.
1162 */
1163XXH_PUBLIC_API void XXH3_generateSecret_fromSeed(void* secretBuffer, XXH64_hash_t seed);
1164
1165/*
1166 * *_withSecretandSeed() :
1167 * These variants generate hash values using either
1168 * @seed for "short" keys (< XXH3_MIDSIZE_MAX = 240 bytes)
1169 * or @secret for "large" keys (>= XXH3_MIDSIZE_MAX).
1170 *
1171 * This generally benefits speed, compared to `_withSeed()` or `_withSecret()`.
1172 * `_withSeed()` has to generate the secret on the fly for "large" keys.
1173 * It's fast, but can be perceptible for "not so large" keys (< 1 KB).
1174 * `_withSecret()` has to generate the masks on the fly for "small" keys,
1175 * which requires more instructions than _withSeed() variants.
1176 * Therefore, _withSecretandSeed variant combines the best of both worlds.
1177 *
1178 * When @secret has been generated by XXH3_generateSecret_fromSeed(),
1179 * this variant produces *exactly* the same results as `_withSeed()` variant,
1180 * hence offering only a pure speed benefit on "large" input,
1181 * by skipping the need to regenerate the secret for every large input.
1182 *
1183 * Another usage scenario is to hash the secret to a 64-bit hash value,
1184 * for example with XXH3_64bits(), which then becomes the seed,
1185 * and then employ both the seed and the secret in _withSecretandSeed().
1186 * On top of speed, an added benefit is that each bit in the secret
1187 * has a 50% chance to swap each bit in the output,
1188 * via its impact to the seed.
1189 * This is not guaranteed when using the secret directly in "small data" scenarios,
1190 * because only portions of the secret are employed for small data.
1191 */
1192XXH_PUBLIC_API XXH64_hash_t
1193XXH3_64bits_withSecretandSeed(const void* data, size_t len,
1194 const void* secret, size_t secretSize,
1195 XXH64_hash_t seed);
1196
1197XXH_PUBLIC_API XXH128_hash_t
1198XXH3_128bits_withSecretandSeed(const void* data, size_t len,
1199 const void* secret, size_t secretSize,
1200 XXH64_hash_t seed64);
1201
1202XXH_PUBLIC_API XXH_errorcode
1203XXH3_64bits_reset_withSecretandSeed(XXH3_state_t* statePtr,
1204 const void* secret, size_t secretSize,
1205 XXH64_hash_t seed64);
1206
1207XXH_PUBLIC_API XXH_errorcode
1208XXH3_128bits_reset_withSecretandSeed(XXH3_state_t* statePtr,
1209 const void* secret, size_t secretSize,
1210 XXH64_hash_t seed64);
1211
1212
1213#endif /* XXH_NO_XXH3 */
1214#endif /* XXH_NO_LONG_LONG */
1215#if defined(XXH_INLINE_ALL) || defined(XXH_PRIVATE_API)
1216# define XXH_IMPLEMENTATION
1217#endif
1218
1219#endif /* defined(XXH_STATIC_LINKING_ONLY) && !defined(XXHASH_H_STATIC_13879238742) */
1220
1221
1222/* ======================================================================== */
1223/* ======================================================================== */
1224/* ======================================================================== */
1225
1226
1227/*-**********************************************************************
1228 * xxHash implementation
1229 *-**********************************************************************
1230 * xxHash's implementation used to be hosted inside xxhash.c.
1231 *
1232 * However, inlining requires implementation to be visible to the compiler,
1233 * hence be included alongside the header.
1234 * Previously, implementation was hosted inside xxhash.c,
1235 * which was then #included when inlining was activated.
1236 * This construction created issues with a few build and install systems,
1237 * as it required xxhash.c to be stored in /include directory.
1238 *
1239 * xxHash implementation is now directly integrated within xxhash.h.
1240 * As a consequence, xxhash.c is no longer needed in /include.
1241 *
1242 * xxhash.c is still available and is still useful.
1243 * In a "normal" setup, when xxhash is not inlined,
1244 * xxhash.h only exposes the prototypes and public symbols,
1245 * while xxhash.c can be built into an object file xxhash.o
1246 * which can then be linked into the final binary.
1247 ************************************************************************/
1248
1249#if ( defined(XXH_INLINE_ALL) || defined(XXH_PRIVATE_API) \
1250 || defined(XXH_IMPLEMENTATION) ) && !defined(XXH_IMPLEM_13a8737387)
1251# define XXH_IMPLEM_13a8737387
1252
1253/* *************************************
1254* Tuning parameters
1255***************************************/
1256
1257/*!
1258 * @defgroup tuning Tuning parameters
1259 * @{
1260 *
1261 * Various macros to control xxHash's behavior.
1262 */
1263#ifdef XXH_DOXYGEN
1264/*!
1265 * @brief Define this to disable 64-bit code.
1266 *
1267 * Useful if only using the @ref xxh32_family and you have a strict C90 compiler.
1268 */
1269# define XXH_NO_LONG_LONG
1270# undef XXH_NO_LONG_LONG /* don't actually */
1271/*!
1272 * @brief Controls how unaligned memory is accessed.
1273 *
1274 * By default, access to unaligned memory is controlled by `memcpy()`, which is
1275 * safe and portable.
1276 *
1277 * Unfortunately, on some target/compiler combinations, the generated assembly
1278 * is sub-optimal.
1279 *
1280 * The below switch allow selection of a different access method
1281 * in the search for improved performance.
1282 *
1283 * @par Possible options:
1284 *
1285 * - `XXH_FORCE_MEMORY_ACCESS=0` (default): `memcpy`
1286 * @par
1287 * Use `memcpy()`. Safe and portable. Note that most modern compilers will
1288 * eliminate the function call and treat it as an unaligned access.
1289 *
1290 * - `XXH_FORCE_MEMORY_ACCESS=1`: `__attribute__((packed))`
1291 * @par
1292 * Depends on compiler extensions and is therefore not portable.
1293 * This method is safe _if_ your compiler supports it,
1294 * and *generally* as fast or faster than `memcpy`.
1295 *
1296 * - `XXH_FORCE_MEMORY_ACCESS=2`: Direct cast
1297 * @par
1298 * Casts directly and dereferences. This method doesn't depend on the
1299 * compiler, but it violates the C standard as it directly dereferences an
1300 * unaligned pointer. It can generate buggy code on targets which do not
1301 * support unaligned memory accesses, but in some circumstances, it's the
1302 * only known way to get the most performance.
1303 *
1304 * - `XXH_FORCE_MEMORY_ACCESS=3`: Byteshift
1305 * @par
1306 * Also portable. This can generate the best code on old compilers which don't
1307 * inline small `memcpy()` calls, and it might also be faster on big-endian
1308 * systems which lack a native byteswap instruction. However, some compilers
1309 * will emit literal byteshifts even if the target supports unaligned access.
1310 * .
1311 *
1312 * @warning
1313 * Methods 1 and 2 rely on implementation-defined behavior. Use these with
1314 * care, as what works on one compiler/platform/optimization level may cause
1315 * another to read garbage data or even crash.
1316 *
1317 * See http://fastcompression.blogspot.com/2015/08/accessing-unaligned-memory.html for details.
1318 *
1319 * Prefer these methods in priority order (0 > 3 > 1 > 2)
1320 */
1321# define XXH_FORCE_MEMORY_ACCESS 0
1322
1323/*!
1324 * @def XXH_FORCE_ALIGN_CHECK
1325 * @brief If defined to non-zero, adds a special path for aligned inputs (XXH32()
1326 * and XXH64() only).
1327 *
1328 * This is an important performance trick for architectures without decent
1329 * unaligned memory access performance.
1330 *
1331 * It checks for input alignment, and when conditions are met, uses a "fast
1332 * path" employing direct 32-bit/64-bit reads, resulting in _dramatically
1333 * faster_ read speed.
1334 *
1335 * The check costs one initial branch per hash, which is generally negligible,
1336 * but not zero.
1337 *
1338 * Moreover, it's not useful to generate an additional code path if memory
1339 * access uses the same instruction for both aligned and unaligned
1340 * addresses (e.g. x86 and aarch64).
1341 *
1342 * In these cases, the alignment check can be removed by setting this macro to 0.
1343 * Then the code will always use unaligned memory access.
1344 * Align check is automatically disabled on x86, x64 & arm64,
1345 * which are platforms known to offer good unaligned memory accesses performance.
1346 *
1347 * This option does not affect XXH3 (only XXH32 and XXH64).
1348 */
1349# define XXH_FORCE_ALIGN_CHECK 0
1350
1351/*!
1352 * @def XXH_NO_INLINE_HINTS
1353 * @brief When non-zero, sets all functions to `static`.
1354 *
1355 * By default, xxHash tries to force the compiler to inline almost all internal
1356 * functions.
1357 *
1358 * This can usually improve performance due to reduced jumping and improved
1359 * constant folding, but significantly increases the size of the binary which
1360 * might not be favorable.
1361 *
1362 * Additionally, sometimes the forced inlining can be detrimental to performance,
1363 * depending on the architecture.
1364 *
1365 * XXH_NO_INLINE_HINTS marks all internal functions as static, giving the
1366 * compiler full control on whether to inline or not.
1367 *
1368 * When not optimizing (-O0), optimizing for size (-Os, -Oz), or using
1369 * -fno-inline with GCC or Clang, this will automatically be defined.
1370 */
1371# define XXH_NO_INLINE_HINTS 0
1372
1373/*!
1374 * @def XXH32_ENDJMP
1375 * @brief Whether to use a jump for `XXH32_finalize`.
1376 *
1377 * For performance, `XXH32_finalize` uses multiple branches in the finalizer.
1378 * This is generally preferable for performance,
1379 * but depending on exact architecture, a jmp may be preferable.
1380 *
1381 * This setting is only possibly making a difference for very small inputs.
1382 */
1383# define XXH32_ENDJMP 0
1384
1385/*!
1386 * @internal
1387 * @brief Redefines old internal names.
1388 *
1389 * For compatibility with code that uses xxHash's internals before the names
1390 * were changed to improve namespacing. There is no other reason to use this.
1391 */
1392# define XXH_OLD_NAMES
1393# undef XXH_OLD_NAMES /* don't actually use, it is ugly. */
1394#endif /* XXH_DOXYGEN */
1395/*!
1396 * @}
1397 */
1398
1399#ifndef XXH_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */
1400 /* prefer __packed__ structures (method 1) for gcc on armv7+ and mips */
1401# if !defined(__clang__) && \
1402( \
1403 (defined(__INTEL_COMPILER) && !defined(_WIN32)) || \
1404 ( \
1405 defined(__GNUC__) && ( \
1406 (defined(__ARM_ARCH) && __ARM_ARCH >= 7) || \
1407 ( \
1408 defined(__mips__) && \
1409 (__mips <= 5 || __mips_isa_rev < 6) && \
1410 (!defined(__mips16) || defined(__mips_mips16e2)) \
1411 ) \
1412 ) \
1413 ) \
1414)
1415# define XXH_FORCE_MEMORY_ACCESS 1
1416# endif
1417#endif
1418
1419#ifndef XXH_FORCE_ALIGN_CHECK /* can be defined externally */
1420# if defined(__i386) || defined(__x86_64__) || defined(__aarch64__) \
1421 || defined(_M_IX86) || defined(_M_X64) || defined(_M_ARM64) /* visual */
1422# define XXH_FORCE_ALIGN_CHECK 0
1423# else
1424# define XXH_FORCE_ALIGN_CHECK 1
1425# endif
1426#endif
1427
1428#ifndef XXH_NO_INLINE_HINTS
1429# if defined(__OPTIMIZE_SIZE__) /* -Os, -Oz */ \
1430 || defined(__NO_INLINE__) /* -O0, -fno-inline */
1431# define XXH_NO_INLINE_HINTS 1
1432# else
1433# define XXH_NO_INLINE_HINTS 0
1434# endif
1435#endif
1436
1437#ifndef XXH32_ENDJMP
1438/* generally preferable for performance */
1439# define XXH32_ENDJMP 0
1440#endif
1441
1442/*!
1443 * @defgroup impl Implementation
1444 * @{
1445 */
1446
1447
1448/* *************************************
1449* Includes & Memory related functions
1450***************************************/
1451/* Modify the local functions below should you wish to use some other memory routines */
1452/* for ZSTD_malloc(), ZSTD_free() */
1453#define ZSTD_DEPS_NEED_MALLOC
1454#include "zstd_deps.h" /* size_t, ZSTD_malloc, ZSTD_free, ZSTD_memcpy */
1455static void* XXH_malloc(size_t s) { return ZSTD_malloc(s); }
1456static void XXH_free (void* p) { ZSTD_free(p); }
1457static void* XXH_memcpy(void* dest, const void* src, size_t size) { return ZSTD_memcpy(dest,src,size); }
1458
1459
1460/* *************************************
1461* Compiler Specific Options
1462***************************************/
1463#ifdef _MSC_VER /* Visual Studio warning fix */
1464# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
1465#endif
1466
1467#if XXH_NO_INLINE_HINTS /* disable inlining hints */
1468# if defined(__GNUC__) || defined(__clang__)
1469# define XXH_FORCE_INLINE static __attribute__((unused))
1470# else
1471# define XXH_FORCE_INLINE static
1472# endif
1473# define XXH_NO_INLINE static
1474/* enable inlining hints */
1475#elif defined(__GNUC__) || defined(__clang__)
1476# define XXH_FORCE_INLINE static __inline__ __attribute__((always_inline, unused))
1477# define XXH_NO_INLINE static __attribute__((noinline))
1478#elif defined(_MSC_VER) /* Visual Studio */
1479# define XXH_FORCE_INLINE static __forceinline
1480# define XXH_NO_INLINE static __declspec(noinline)
1481#elif defined (__cplusplus) \
1482 || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) /* C99 */
1483# define XXH_FORCE_INLINE static inline
1484# define XXH_NO_INLINE static
1485#else
1486# define XXH_FORCE_INLINE static
1487# define XXH_NO_INLINE static
1488#endif
1489
1490
1491
1492/* *************************************
1493* Debug
1494***************************************/
1495/*!
1496 * @ingroup tuning
1497 * @def XXH_DEBUGLEVEL
1498 * @brief Sets the debugging level.
1499 *
1500 * XXH_DEBUGLEVEL is expected to be defined externally, typically via the
1501 * compiler's command line options. The value must be a number.
1502 */
1503#ifndef XXH_DEBUGLEVEL
1504# ifdef DEBUGLEVEL /* backwards compat */
1505# define XXH_DEBUGLEVEL DEBUGLEVEL
1506# else
1507# define XXH_DEBUGLEVEL 0
1508# endif
1509#endif
1510
1511#if (XXH_DEBUGLEVEL>=1)
1512# include <assert.h> /* note: can still be disabled with NDEBUG */
1513# define XXH_ASSERT(c) assert(c)
1514#else
1515# define XXH_ASSERT(c) ((void)0)
1516#endif
1517
1518/* note: use after variable declarations */
1519#ifndef XXH_STATIC_ASSERT
1520# if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) /* C11 */
1521# include <assert.h>
1522# define XXH_STATIC_ASSERT_WITH_MESSAGE(c,m) do { static_assert((c),m); } while(0)
1523# elif defined(__cplusplus) && (__cplusplus >= 201103L) /* C++11 */
1524# define XXH_STATIC_ASSERT_WITH_MESSAGE(c,m) do { static_assert((c),m); } while(0)
1525# else
1526# define XXH_STATIC_ASSERT_WITH_MESSAGE(c,m) do { struct xxh_sa { char x[(c) ? 1 : -1]; }; } while(0)
1527# endif
1528# define XXH_STATIC_ASSERT(c) XXH_STATIC_ASSERT_WITH_MESSAGE((c),#c)
1529#endif
1530
1531/*!
1532 * @internal
1533 * @def XXH_COMPILER_GUARD(var)
1534 * @brief Used to prevent unwanted optimizations for @p var.
1535 *
1536 * It uses an empty GCC inline assembly statement with a register constraint
1537 * which forces @p var into a general purpose register (eg eax, ebx, ecx
1538 * on x86) and marks it as modified.
1539 *
1540 * This is used in a few places to avoid unwanted autovectorization (e.g.
1541 * XXH32_round()). All vectorization we want is explicit via intrinsics,
1542 * and _usually_ isn't wanted elsewhere.
1543 *
1544 * We also use it to prevent unwanted constant folding for AArch64 in
1545 * XXH3_initCustomSecret_scalar().
1546 */
1547#if defined(__GNUC__) || defined(__clang__)
1548# define XXH_COMPILER_GUARD(var) __asm__ __volatile__("" : "+r" (var))
1549#else
1550# define XXH_COMPILER_GUARD(var) ((void)0)
1551#endif
1552
1553/* *************************************
1554* Basic Types
1555***************************************/
1556#if !defined (__VMS) \
1557 && (defined (__cplusplus) \
1558 || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) )
1559# include <stdint.h>
1560 typedef uint8_t xxh_u8;
1561#else
1562 typedef unsigned char xxh_u8;
1563#endif
1564typedef XXH32_hash_t xxh_u32;
1565
1566#ifdef XXH_OLD_NAMES
1567# define BYTE xxh_u8
1568# define U8 xxh_u8
1569# define U32 xxh_u32
1570#endif
1571
1572/* *** Memory access *** */
1573
1574/*!
1575 * @internal
1576 * @fn xxh_u32 XXH_read32(const void* ptr)
1577 * @brief Reads an unaligned 32-bit integer from @p ptr in native endianness.
1578 *
1579 * Affected by @ref XXH_FORCE_MEMORY_ACCESS.
1580 *
1581 * @param ptr The pointer to read from.
1582 * @return The 32-bit native endian integer from the bytes at @p ptr.
1583 */
1584
1585/*!
1586 * @internal
1587 * @fn xxh_u32 XXH_readLE32(const void* ptr)
1588 * @brief Reads an unaligned 32-bit little endian integer from @p ptr.
1589 *
1590 * Affected by @ref XXH_FORCE_MEMORY_ACCESS.
1591 *
1592 * @param ptr The pointer to read from.
1593 * @return The 32-bit little endian integer from the bytes at @p ptr.
1594 */
1595
1596/*!
1597 * @internal
1598 * @fn xxh_u32 XXH_readBE32(const void* ptr)
1599 * @brief Reads an unaligned 32-bit big endian integer from @p ptr.
1600 *
1601 * Affected by @ref XXH_FORCE_MEMORY_ACCESS.
1602 *
1603 * @param ptr The pointer to read from.
1604 * @return The 32-bit big endian integer from the bytes at @p ptr.
1605 */
1606
1607/*!
1608 * @internal
1609 * @fn xxh_u32 XXH_readLE32_align(const void* ptr, XXH_alignment align)
1610 * @brief Like @ref XXH_readLE32(), but has an option for aligned reads.
1611 *
1612 * Affected by @ref XXH_FORCE_MEMORY_ACCESS.
1613 * Note that when @ref XXH_FORCE_ALIGN_CHECK == 0, the @p align parameter is
1614 * always @ref XXH_alignment::XXH_unaligned.
1615 *
1616 * @param ptr The pointer to read from.
1617 * @param align Whether @p ptr is aligned.
1618 * @pre
1619 * If @p align == @ref XXH_alignment::XXH_aligned, @p ptr must be 4 byte
1620 * aligned.
1621 * @return The 32-bit little endian integer from the bytes at @p ptr.
1622 */
1623
1624#if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==3))
1625/*
1626 * Manual byteshift. Best for old compilers which don't inline memcpy.
1627 * We actually directly use XXH_readLE32 and XXH_readBE32.
1628 */
1629#elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==2))
1630
1631/*
1632 * Force direct memory access. Only works on CPU which support unaligned memory
1633 * access in hardware.
1634 */
1635static xxh_u32 XXH_read32(const void* memPtr) { return *(const xxh_u32*) memPtr; }
1636
1637#elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==1))
1638
1639/*
1640 * __pack instructions are safer but compiler specific, hence potentially
1641 * problematic for some compilers.
1642 *
1643 * Currently only defined for GCC and ICC.
1644 */
1645#ifdef XXH_OLD_NAMES
1646typedef union { xxh_u32 u32; } __attribute__((packed)) unalign;
1647#endif
1648static xxh_u32 XXH_read32(const void* ptr)
1649{
1650 typedef union { xxh_u32 u32; } __attribute__((packed)) xxh_unalign;
1651 return ((const xxh_unalign*)ptr)->u32;
1652}
1653
1654#else
1655
1656/*
1657 * Portable and safe solution. Generally efficient.
1658 * see: http://fastcompression.blogspot.com/2015/08/accessing-unaligned-memory.html
1659 */
1660static xxh_u32 XXH_read32(const void* memPtr)
1661{
1662 xxh_u32 val;
1663 XXH_memcpy(&val, memPtr, sizeof(val));
1664 return val;
1665}
1666
1667#endif /* XXH_FORCE_DIRECT_MEMORY_ACCESS */
1668
1669
1670/* *** Endianness *** */
1671
1672/*!
1673 * @ingroup tuning
1674 * @def XXH_CPU_LITTLE_ENDIAN
1675 * @brief Whether the target is little endian.
1676 *
1677 * Defined to 1 if the target is little endian, or 0 if it is big endian.
1678 * It can be defined externally, for example on the compiler command line.
1679 *
1680 * If it is not defined,
1681 * a runtime check (which is usually constant folded) is used instead.
1682 *
1683 * @note
1684 * This is not necessarily defined to an integer constant.
1685 *
1686 * @see XXH_isLittleEndian() for the runtime check.
1687 */
1688#ifndef XXH_CPU_LITTLE_ENDIAN
1689/*
1690 * Try to detect endianness automatically, to avoid the nonstandard behavior
1691 * in `XXH_isLittleEndian()`
1692 */
1693# if defined(_WIN32) /* Windows is always little endian */ \
1694 || defined(__LITTLE_ENDIAN__) \
1695 || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
1696# define XXH_CPU_LITTLE_ENDIAN 1
1697# elif defined(__BIG_ENDIAN__) \
1698 || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
1699# define XXH_CPU_LITTLE_ENDIAN 0
1700# else
1701/*!
1702 * @internal
1703 * @brief Runtime check for @ref XXH_CPU_LITTLE_ENDIAN.
1704 *
1705 * Most compilers will constant fold this.
1706 */
1707static int XXH_isLittleEndian(void)
1708{
1709 /*
1710 * Portable and well-defined behavior.
1711 * Don't use static: it is detrimental to performance.
1712 */
1713 const union { xxh_u32 u; xxh_u8 c[4]; } one = { 1 };
1714 return one.c[0];
1715}
1716# define XXH_CPU_LITTLE_ENDIAN XXH_isLittleEndian()
1717# endif
1718#endif
1719
1720
1721
1722
1723/* ****************************************
1724* Compiler-specific Functions and Macros
1725******************************************/
1726#define XXH_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
1727
1728#ifdef __has_builtin
1729# define XXH_HAS_BUILTIN(x) __has_builtin(x)
1730#else
1731# define XXH_HAS_BUILTIN(x) 0
1732#endif
1733
1734/*!
1735 * @internal
1736 * @def XXH_rotl32(x,r)
1737 * @brief 32-bit rotate left.
1738 *
1739 * @param x The 32-bit integer to be rotated.
1740 * @param r The number of bits to rotate.
1741 * @pre
1742 * @p r > 0 && @p r < 32
1743 * @note
1744 * @p x and @p r may be evaluated multiple times.
1745 * @return The rotated result.
1746 */
1747#if !defined(NO_CLANG_BUILTIN) && XXH_HAS_BUILTIN(__builtin_rotateleft32) \
1748 && XXH_HAS_BUILTIN(__builtin_rotateleft64)
1749# define XXH_rotl32 __builtin_rotateleft32
1750# define XXH_rotl64 __builtin_rotateleft64
1751/* Note: although _rotl exists for minGW (GCC under windows), performance seems poor */
1752#elif defined(_MSC_VER)
1753# define XXH_rotl32(x,r) _rotl(x,r)
1754# define XXH_rotl64(x,r) _rotl64(x,r)
1755#else
1756# define XXH_rotl32(x,r) (((x) << (r)) | ((x) >> (32 - (r))))
1757# define XXH_rotl64(x,r) (((x) << (r)) | ((x) >> (64 - (r))))
1758#endif
1759
1760/*!
1761 * @internal
1762 * @fn xxh_u32 XXH_swap32(xxh_u32 x)
1763 * @brief A 32-bit byteswap.
1764 *
1765 * @param x The 32-bit integer to byteswap.
1766 * @return @p x, byteswapped.
1767 */
1768#if defined(_MSC_VER) /* Visual Studio */
1769# define XXH_swap32 _byteswap_ulong
1770#elif XXH_GCC_VERSION >= 403
1771# define XXH_swap32 __builtin_bswap32
1772#else
1773static xxh_u32 XXH_swap32 (xxh_u32 x)
1774{
1775 return ((x << 24) & 0xff000000 ) |
1776 ((x << 8) & 0x00ff0000 ) |
1777 ((x >> 8) & 0x0000ff00 ) |
1778 ((x >> 24) & 0x000000ff );
1779}
1780#endif
1781
1782
1783/* ***************************
1784* Memory reads
1785*****************************/
1786
1787/*!
1788 * @internal
1789 * @brief Enum to indicate whether a pointer is aligned.
1790 */
1791typedef enum {
1792 XXH_aligned, /*!< Aligned */
1793 XXH_unaligned /*!< Possibly unaligned */
1794} XXH_alignment;
1795
1796/*
1797 * XXH_FORCE_MEMORY_ACCESS==3 is an endian-independent byteshift load.
1798 *
1799 * This is ideal for older compilers which don't inline memcpy.
1800 */
1801#if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==3))
1802
1803XXH_FORCE_INLINE xxh_u32 XXH_readLE32(const void* memPtr)
1804{
1805 const xxh_u8* bytePtr = (const xxh_u8 *)memPtr;
1806 return bytePtr[0]
1807 | ((xxh_u32)bytePtr[1] << 8)
1808 | ((xxh_u32)bytePtr[2] << 16)
1809 | ((xxh_u32)bytePtr[3] << 24);
1810}
1811
1812XXH_FORCE_INLINE xxh_u32 XXH_readBE32(const void* memPtr)
1813{
1814 const xxh_u8* bytePtr = (const xxh_u8 *)memPtr;
1815 return bytePtr[3]
1816 | ((xxh_u32)bytePtr[2] << 8)
1817 | ((xxh_u32)bytePtr[1] << 16)
1818 | ((xxh_u32)bytePtr[0] << 24);
1819}
1820
1821#else
1822XXH_FORCE_INLINE xxh_u32 XXH_readLE32(const void* ptr)
1823{
1824 return XXH_CPU_LITTLE_ENDIAN ? XXH_read32(ptr) : XXH_swap32(XXH_read32(ptr));
1825}
1826
1827static xxh_u32 XXH_readBE32(const void* ptr)
1828{
1829 return XXH_CPU_LITTLE_ENDIAN ? XXH_swap32(XXH_read32(ptr)) : XXH_read32(ptr);
1830}
1831#endif
1832
1833XXH_FORCE_INLINE xxh_u32
1834XXH_readLE32_align(const void* ptr, XXH_alignment align)
1835{
1836 if (align==XXH_unaligned) {
1837 return XXH_readLE32(ptr);
1838 } else {
1839 return XXH_CPU_LITTLE_ENDIAN ? *(const xxh_u32*)ptr : XXH_swap32(*(const xxh_u32*)ptr);
1840 }
1841}
1842
1843
1844/* *************************************
1845* Misc
1846***************************************/
1847/*! @ingroup public */
1848XXH_PUBLIC_API unsigned XXH_versionNumber (void) { return XXH_VERSION_NUMBER; }
1849
1850
1851/* *******************************************************************
1852* 32-bit hash functions
1853*********************************************************************/
1854/*!
1855 * @}
1856 * @defgroup xxh32_impl XXH32 implementation
1857 * @ingroup impl
1858 * @{
1859 */
1860 /* #define instead of static const, to be used as initializers */
1861#define XXH_PRIME32_1 0x9E3779B1U /*!< 0b10011110001101110111100110110001 */
1862#define XXH_PRIME32_2 0x85EBCA77U /*!< 0b10000101111010111100101001110111 */
1863#define XXH_PRIME32_3 0xC2B2AE3DU /*!< 0b11000010101100101010111000111101 */
1864#define XXH_PRIME32_4 0x27D4EB2FU /*!< 0b00100111110101001110101100101111 */
1865#define XXH_PRIME32_5 0x165667B1U /*!< 0b00010110010101100110011110110001 */
1866
1867#ifdef XXH_OLD_NAMES
1868# define PRIME32_1 XXH_PRIME32_1
1869# define PRIME32_2 XXH_PRIME32_2
1870# define PRIME32_3 XXH_PRIME32_3
1871# define PRIME32_4 XXH_PRIME32_4
1872# define PRIME32_5 XXH_PRIME32_5
1873#endif
1874
1875/*!
1876 * @internal
1877 * @brief Normal stripe processing routine.
1878 *
1879 * This shuffles the bits so that any bit from @p input impacts several bits in
1880 * @p acc.
1881 *
1882 * @param acc The accumulator lane.
1883 * @param input The stripe of input to mix.
1884 * @return The mixed accumulator lane.
1885 */
1886static xxh_u32 XXH32_round(xxh_u32 acc, xxh_u32 input)
1887{
1888 acc += input * XXH_PRIME32_2;
1889 acc = XXH_rotl32(acc, 13);
1890 acc *= XXH_PRIME32_1;
1891#if (defined(__SSE4_1__) || defined(__aarch64__)) && !defined(XXH_ENABLE_AUTOVECTORIZE)
1892 /*
1893 * UGLY HACK:
1894 * A compiler fence is the only thing that prevents GCC and Clang from
1895 * autovectorizing the XXH32 loop (pragmas and attributes don't work for some
1896 * reason) without globally disabling SSE4.1.
1897 *
1898 * The reason we want to avoid vectorization is because despite working on
1899 * 4 integers at a time, there are multiple factors slowing XXH32 down on
1900 * SSE4:
1901 * - There's a ridiculous amount of lag from pmulld (10 cycles of latency on
1902 * newer chips!) making it slightly slower to multiply four integers at
1903 * once compared to four integers independently. Even when pmulld was
1904 * fastest, Sandy/Ivy Bridge, it is still not worth it to go into SSE
1905 * just to multiply unless doing a long operation.
1906 *
1907 * - Four instructions are required to rotate,
1908 * movqda tmp, v // not required with VEX encoding
1909 * pslld tmp, 13 // tmp <<= 13
1910 * psrld v, 19 // x >>= 19
1911 * por v, tmp // x |= tmp
1912 * compared to one for scalar:
1913 * roll v, 13 // reliably fast across the board
1914 * shldl v, v, 13 // Sandy Bridge and later prefer this for some reason
1915 *
1916 * - Instruction level parallelism is actually more beneficial here because
1917 * the SIMD actually serializes this operation: While v1 is rotating, v2
1918 * can load data, while v3 can multiply. SSE forces them to operate
1919 * together.
1920 *
1921 * This is also enabled on AArch64, as Clang autovectorizes it incorrectly
1922 * and it is pointless writing a NEON implementation that is basically the
1923 * same speed as scalar for XXH32.
1924 */
1925 XXH_COMPILER_GUARD(acc);
1926#endif
1927 return acc;
1928}
1929
1930/*!
1931 * @internal
1932 * @brief Mixes all bits to finalize the hash.
1933 *
1934 * The final mix ensures that all input bits have a chance to impact any bit in
1935 * the output digest, resulting in an unbiased distribution.
1936 *
1937 * @param h32 The hash to avalanche.
1938 * @return The avalanched hash.
1939 */
1940static xxh_u32 XXH32_avalanche(xxh_u32 h32)
1941{
1942 h32 ^= h32 >> 15;
1943 h32 *= XXH_PRIME32_2;
1944 h32 ^= h32 >> 13;
1945 h32 *= XXH_PRIME32_3;
1946 h32 ^= h32 >> 16;
1947 return(h32);
1948}
1949
1950#define XXH_get32bits(p) XXH_readLE32_align(p, align)
1951
1952/*!
1953 * @internal
1954 * @brief Processes the last 0-15 bytes of @p ptr.
1955 *
1956 * There may be up to 15 bytes remaining to consume from the input.
1957 * This final stage will digest them to ensure that all input bytes are present
1958 * in the final mix.
1959 *
1960 * @param h32 The hash to finalize.
1961 * @param ptr The pointer to the remaining input.
1962 * @param len The remaining length, modulo 16.
1963 * @param align Whether @p ptr is aligned.
1964 * @return The finalized hash.
1965 */
1966static xxh_u32
1967XXH32_finalize(xxh_u32 h32, const xxh_u8* ptr, size_t len, XXH_alignment align)
1968{
1969#define XXH_PROCESS1 do { \
1970 h32 += (*ptr++) * XXH_PRIME32_5; \
1971 h32 = XXH_rotl32(h32, 11) * XXH_PRIME32_1; \
1972} while (0)
1973
1974#define XXH_PROCESS4 do { \
1975 h32 += XXH_get32bits(ptr) * XXH_PRIME32_3; \
1976 ptr += 4; \
1977 h32 = XXH_rotl32(h32, 17) * XXH_PRIME32_4; \
1978} while (0)
1979
1980 if (ptr==NULL) XXH_ASSERT(len == 0);
1981
1982 /* Compact rerolled version; generally faster */
1983 if (!XXH32_ENDJMP) {
1984 len &= 15;
1985 while (len >= 4) {
1986 XXH_PROCESS4;
1987 len -= 4;
1988 }
1989 while (len > 0) {
1990 XXH_PROCESS1;
1991 --len;
1992 }
1993 return XXH32_avalanche(h32);
1994 } else {
1995 switch(len&15) /* or switch(bEnd - p) */ {
1996 case 12: XXH_PROCESS4;
1997 XXH_FALLTHROUGH;
1998 case 8: XXH_PROCESS4;
1999 XXH_FALLTHROUGH;
2000 case 4: XXH_PROCESS4;
2001 return XXH32_avalanche(h32);
2002
2003 case 13: XXH_PROCESS4;
2004 XXH_FALLTHROUGH;
2005 case 9: XXH_PROCESS4;
2006 XXH_FALLTHROUGH;
2007 case 5: XXH_PROCESS4;
2008 XXH_PROCESS1;
2009 return XXH32_avalanche(h32);
2010
2011 case 14: XXH_PROCESS4;
2012 XXH_FALLTHROUGH;
2013 case 10: XXH_PROCESS4;
2014 XXH_FALLTHROUGH;
2015 case 6: XXH_PROCESS4;
2016 XXH_PROCESS1;
2017 XXH_PROCESS1;
2018 return XXH32_avalanche(h32);
2019
2020 case 15: XXH_PROCESS4;
2021 XXH_FALLTHROUGH;
2022 case 11: XXH_PROCESS4;
2023 XXH_FALLTHROUGH;
2024 case 7: XXH_PROCESS4;
2025 XXH_FALLTHROUGH;
2026 case 3: XXH_PROCESS1;
2027 XXH_FALLTHROUGH;
2028 case 2: XXH_PROCESS1;
2029 XXH_FALLTHROUGH;
2030 case 1: XXH_PROCESS1;
2031 XXH_FALLTHROUGH;
2032 case 0: return XXH32_avalanche(h32);
2033 }
2034 XXH_ASSERT(0);
2035 return h32; /* reaching this point is deemed impossible */
2036 }
2037}
2038
2039#ifdef XXH_OLD_NAMES
2040# define PROCESS1 XXH_PROCESS1
2041# define PROCESS4 XXH_PROCESS4
2042#else
2043# undef XXH_PROCESS1
2044# undef XXH_PROCESS4
2045#endif
2046
2047/*!
2048 * @internal
2049 * @brief The implementation for @ref XXH32().
2050 *
2051 * @param input , len , seed Directly passed from @ref XXH32().
2052 * @param align Whether @p input is aligned.
2053 * @return The calculated hash.
2054 */
2055XXH_FORCE_INLINE xxh_u32
2056XXH32_endian_align(const xxh_u8* input, size_t len, xxh_u32 seed, XXH_alignment align)
2057{
2058 xxh_u32 h32;
2059
2060 if (input==NULL) XXH_ASSERT(len == 0);
2061
2062 if (len>=16) {
2063 const xxh_u8* const bEnd = input + len;
2064 const xxh_u8* const limit = bEnd - 15;
2065 xxh_u32 v1 = seed + XXH_PRIME32_1 + XXH_PRIME32_2;
2066 xxh_u32 v2 = seed + XXH_PRIME32_2;
2067 xxh_u32 v3 = seed + 0;
2068 xxh_u32 v4 = seed - XXH_PRIME32_1;
2069
2070 do {
2071 v1 = XXH32_round(v1, XXH_get32bits(input)); input += 4;
2072 v2 = XXH32_round(v2, XXH_get32bits(input)); input += 4;
2073 v3 = XXH32_round(v3, XXH_get32bits(input)); input += 4;
2074 v4 = XXH32_round(v4, XXH_get32bits(input)); input += 4;
2075 } while (input < limit);
2076
2077 h32 = XXH_rotl32(v1, 1) + XXH_rotl32(v2, 7)
2078 + XXH_rotl32(v3, 12) + XXH_rotl32(v4, 18);
2079 } else {
2080 h32 = seed + XXH_PRIME32_5;
2081 }
2082
2083 h32 += (xxh_u32)len;
2084
2085 return XXH32_finalize(h32, input, len&15, align);
2086}
2087
2088/*! @ingroup xxh32_family */
2089XXH_PUBLIC_API XXH32_hash_t XXH32 (const void* input, size_t len, XXH32_hash_t seed)
2090{
2091#if 0
2092 /* Simple version, good for code maintenance, but unfortunately slow for small inputs */
2093 XXH32_state_t state;
2094 XXH32_reset(&state, seed);
2095 XXH32_update(&state, (const xxh_u8*)input, len);
2096 return XXH32_digest(&state);
2097#else
2098 if (XXH_FORCE_ALIGN_CHECK) {
2099 if ((((size_t)input) & 3) == 0) { /* Input is 4-bytes aligned, leverage the speed benefit */
2100 return XXH32_endian_align((const xxh_u8*)input, len, seed, XXH_aligned);
2101 } }
2102
2103 return XXH32_endian_align((const xxh_u8*)input, len, seed, XXH_unaligned);
2104#endif
2105}
2106
2107
2108
2109/******* Hash streaming *******/
2110/*!
2111 * @ingroup xxh32_family
2112 */
2113XXH_PUBLIC_API XXH32_state_t* XXH32_createState(void)
2114{
2115 return (XXH32_state_t*)XXH_malloc(sizeof(XXH32_state_t));
2116}
2117/*! @ingroup xxh32_family */
2118XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr)
2119{
2120 XXH_free(statePtr);
2121 return XXH_OK;
2122}
2123
2124/*! @ingroup xxh32_family */
2125XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* dstState, const XXH32_state_t* srcState)
2126{
2127 XXH_memcpy(dstState, srcState, sizeof(*dstState));
2128}
2129
2130/*! @ingroup xxh32_family */
2131XXH_PUBLIC_API XXH_errorcode XXH32_reset(XXH32_state_t* statePtr, XXH32_hash_t seed)
2132{
2133 XXH_ASSERT(statePtr != NULL);
2134 memset(statePtr, 0, sizeof(*statePtr));
2135 statePtr->v[0] = seed + XXH_PRIME32_1 + XXH_PRIME32_2;
2136 statePtr->v[1] = seed + XXH_PRIME32_2;
2137 statePtr->v[2] = seed + 0;
2138 statePtr->v[3] = seed - XXH_PRIME32_1;
2139 return XXH_OK;
2140}
2141
2142
2143/*! @ingroup xxh32_family */
2144XXH_PUBLIC_API XXH_errorcode
2145XXH32_update(XXH32_state_t* state, const void* input, size_t len)
2146{
2147 if (input==NULL) {
2148 XXH_ASSERT(len == 0);
2149 return XXH_OK;
2150 }
2151
2152 { const xxh_u8* p = (const xxh_u8*)input;
2153 const xxh_u8* const bEnd = p + len;
2154
2155 state->total_len_32 += (XXH32_hash_t)len;
2156 state->large_len |= (XXH32_hash_t)((len>=16) | (state->total_len_32>=16));
2157
2158 if (state->memsize + len < 16) { /* fill in tmp buffer */
2159 XXH_memcpy((xxh_u8*)(state->mem32) + state->memsize, input, len);
2160 state->memsize += (XXH32_hash_t)len;
2161 return XXH_OK;
2162 }
2163
2164 if (state->memsize) { /* some data left from previous update */
2165 XXH_memcpy((xxh_u8*)(state->mem32) + state->memsize, input, 16-state->memsize);
2166 { const xxh_u32* p32 = state->mem32;
2167 state->v[0] = XXH32_round(state->v[0], XXH_readLE32(p32)); p32++;
2168 state->v[1] = XXH32_round(state->v[1], XXH_readLE32(p32)); p32++;
2169 state->v[2] = XXH32_round(state->v[2], XXH_readLE32(p32)); p32++;
2170 state->v[3] = XXH32_round(state->v[3], XXH_readLE32(p32));
2171 }
2172 p += 16-state->memsize;
2173 state->memsize = 0;
2174 }
2175
2176 if (p <= bEnd-16) {
2177 const xxh_u8* const limit = bEnd - 16;
2178
2179 do {
2180 state->v[0] = XXH32_round(state->v[0], XXH_readLE32(p)); p+=4;
2181 state->v[1] = XXH32_round(state->v[1], XXH_readLE32(p)); p+=4;
2182 state->v[2] = XXH32_round(state->v[2], XXH_readLE32(p)); p+=4;
2183 state->v[3] = XXH32_round(state->v[3], XXH_readLE32(p)); p+=4;
2184 } while (p<=limit);
2185
2186 }
2187
2188 if (p < bEnd) {
2189 XXH_memcpy(state->mem32, p, (size_t)(bEnd-p));
2190 state->memsize = (unsigned)(bEnd-p);
2191 }
2192 }
2193
2194 return XXH_OK;
2195}
2196
2197
2198/*! @ingroup xxh32_family */
2199XXH_PUBLIC_API XXH32_hash_t XXH32_digest(const XXH32_state_t* state)
2200{
2201 xxh_u32 h32;
2202
2203 if (state->large_len) {
2204 h32 = XXH_rotl32(state->v[0], 1)
2205 + XXH_rotl32(state->v[1], 7)
2206 + XXH_rotl32(state->v[2], 12)
2207 + XXH_rotl32(state->v[3], 18);
2208 } else {
2209 h32 = state->v[2] /* == seed */ + XXH_PRIME32_5;
2210 }
2211
2212 h32 += state->total_len_32;
2213
2214 return XXH32_finalize(h32, (const xxh_u8*)state->mem32, state->memsize, XXH_aligned);
2215}
2216
2217
2218/******* Canonical representation *******/
2219
2220/*!
2221 * @ingroup xxh32_family
2222 * The default return values from XXH functions are unsigned 32 and 64 bit
2223 * integers.
2224 *
2225 * The canonical representation uses big endian convention, the same convention
2226 * as human-readable numbers (large digits first).
2227 *
2228 * This way, hash values can be written into a file or buffer, remaining
2229 * comparable across different systems.
2230 *
2231 * The following functions allow transformation of hash values to and from their
2232 * canonical format.
2233 */
2234XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash)
2235{
2236 /* XXH_STATIC_ASSERT(sizeof(XXH32_canonical_t) == sizeof(XXH32_hash_t)); */
2237 if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap32(hash);
2238 XXH_memcpy(dst, &hash, sizeof(*dst));
2239}
2240/*! @ingroup xxh32_family */
2241XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src)
2242{
2243 return XXH_readBE32(src);
2244}
2245
2246
2247#ifndef XXH_NO_LONG_LONG
2248
2249/* *******************************************************************
2250* 64-bit hash functions
2251*********************************************************************/
2252/*!
2253 * @}
2254 * @ingroup impl
2255 * @{
2256 */
2257/******* Memory access *******/
2258
2259typedef XXH64_hash_t xxh_u64;
2260
2261#ifdef XXH_OLD_NAMES
2262# define U64 xxh_u64
2263#endif
2264
2265#if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==3))
2266/*
2267 * Manual byteshift. Best for old compilers which don't inline memcpy.
2268 * We actually directly use XXH_readLE64 and XXH_readBE64.
2269 */
2270#elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==2))
2271
2272/* Force direct memory access. Only works on CPU which support unaligned memory access in hardware */
2273static xxh_u64 XXH_read64(const void* memPtr)
2274{
2275 return *(const xxh_u64*) memPtr;
2276}
2277
2278#elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==1))
2279
2280/*
2281 * __pack instructions are safer, but compiler specific, hence potentially
2282 * problematic for some compilers.
2283 *
2284 * Currently only defined for GCC and ICC.
2285 */
2286#ifdef XXH_OLD_NAMES
2287typedef union { xxh_u32 u32; xxh_u64 u64; } __attribute__((packed)) unalign64;
2288#endif
2289static xxh_u64 XXH_read64(const void* ptr)
2290{
2291 typedef union { xxh_u32 u32; xxh_u64 u64; } __attribute__((packed)) xxh_unalign64;
2292 return ((const xxh_unalign64*)ptr)->u64;
2293}
2294
2295#else
2296
2297/*
2298 * Portable and safe solution. Generally efficient.
2299 * see: http://fastcompression.blogspot.com/2015/08/accessing-unaligned-memory.html
2300 */
2301static xxh_u64 XXH_read64(const void* memPtr)
2302{
2303 xxh_u64 val;
2304 XXH_memcpy(&val, memPtr, sizeof(val));
2305 return val;
2306}
2307
2308#endif /* XXH_FORCE_DIRECT_MEMORY_ACCESS */
2309
2310#if defined(_MSC_VER) /* Visual Studio */
2311# define XXH_swap64 _byteswap_uint64
2312#elif XXH_GCC_VERSION >= 403
2313# define XXH_swap64 __builtin_bswap64
2314#else
2315static xxh_u64 XXH_swap64(xxh_u64 x)
2316{
2317 return ((x << 56) & 0xff00000000000000ULL) |
2318 ((x << 40) & 0x00ff000000000000ULL) |
2319 ((x << 24) & 0x0000ff0000000000ULL) |
2320 ((x << 8) & 0x000000ff00000000ULL) |
2321 ((x >> 8) & 0x00000000ff000000ULL) |
2322 ((x >> 24) & 0x0000000000ff0000ULL) |
2323 ((x >> 40) & 0x000000000000ff00ULL) |
2324 ((x >> 56) & 0x00000000000000ffULL);
2325}
2326#endif
2327
2328
2329/* XXH_FORCE_MEMORY_ACCESS==3 is an endian-independent byteshift load. */
2330#if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==3))
2331
2332XXH_FORCE_INLINE xxh_u64 XXH_readLE64(const void* memPtr)
2333{
2334 const xxh_u8* bytePtr = (const xxh_u8 *)memPtr;
2335 return bytePtr[0]
2336 | ((xxh_u64)bytePtr[1] << 8)
2337 | ((xxh_u64)bytePtr[2] << 16)
2338 | ((xxh_u64)bytePtr[3] << 24)
2339 | ((xxh_u64)bytePtr[4] << 32)
2340 | ((xxh_u64)bytePtr[5] << 40)
2341 | ((xxh_u64)bytePtr[6] << 48)
2342 | ((xxh_u64)bytePtr[7] << 56);
2343}
2344
2345XXH_FORCE_INLINE xxh_u64 XXH_readBE64(const void* memPtr)
2346{
2347 const xxh_u8* bytePtr = (const xxh_u8 *)memPtr;
2348 return bytePtr[7]
2349 | ((xxh_u64)bytePtr[6] << 8)
2350 | ((xxh_u64)bytePtr[5] << 16)
2351 | ((xxh_u64)bytePtr[4] << 24)
2352 | ((xxh_u64)bytePtr[3] << 32)
2353 | ((xxh_u64)bytePtr[2] << 40)
2354 | ((xxh_u64)bytePtr[1] << 48)
2355 | ((xxh_u64)bytePtr[0] << 56);
2356}
2357
2358#else
2359XXH_FORCE_INLINE xxh_u64 XXH_readLE64(const void* ptr)
2360{
2361 return XXH_CPU_LITTLE_ENDIAN ? XXH_read64(ptr) : XXH_swap64(XXH_read64(ptr));
2362}
2363
2364static xxh_u64 XXH_readBE64(const void* ptr)
2365{
2366 return XXH_CPU_LITTLE_ENDIAN ? XXH_swap64(XXH_read64(ptr)) : XXH_read64(ptr);
2367}
2368#endif
2369
2370XXH_FORCE_INLINE xxh_u64
2371XXH_readLE64_align(const void* ptr, XXH_alignment align)
2372{
2373 if (align==XXH_unaligned)
2374 return XXH_readLE64(ptr);
2375 else
2376 return XXH_CPU_LITTLE_ENDIAN ? *(const xxh_u64*)ptr : XXH_swap64(*(const xxh_u64*)ptr);
2377}
2378
2379
2380/******* xxh64 *******/
2381/*!
2382 * @}
2383 * @defgroup xxh64_impl XXH64 implementation
2384 * @ingroup impl
2385 * @{
2386 */
2387/* #define rather that static const, to be used as initializers */
2388#define XXH_PRIME64_1 0x9E3779B185EBCA87ULL /*!< 0b1001111000110111011110011011000110000101111010111100101010000111 */
2389#define XXH_PRIME64_2 0xC2B2AE3D27D4EB4FULL /*!< 0b1100001010110010101011100011110100100111110101001110101101001111 */
2390#define XXH_PRIME64_3 0x165667B19E3779F9ULL /*!< 0b0001011001010110011001111011000110011110001101110111100111111001 */
2391#define XXH_PRIME64_4 0x85EBCA77C2B2AE63ULL /*!< 0b1000010111101011110010100111011111000010101100101010111001100011 */
2392#define XXH_PRIME64_5 0x27D4EB2F165667C5ULL /*!< 0b0010011111010100111010110010111100010110010101100110011111000101 */
2393
2394#ifdef XXH_OLD_NAMES
2395# define PRIME64_1 XXH_PRIME64_1
2396# define PRIME64_2 XXH_PRIME64_2
2397# define PRIME64_3 XXH_PRIME64_3
2398# define PRIME64_4 XXH_PRIME64_4
2399# define PRIME64_5 XXH_PRIME64_5
2400#endif
2401
2402static xxh_u64 XXH64_round(xxh_u64 acc, xxh_u64 input)
2403{
2404 acc += input * XXH_PRIME64_2;
2405 acc = XXH_rotl64(acc, 31);
2406 acc *= XXH_PRIME64_1;
2407 return acc;
2408}
2409
2410static xxh_u64 XXH64_mergeRound(xxh_u64 acc, xxh_u64 val)
2411{
2412 val = XXH64_round(0, val);
2413 acc ^= val;
2414 acc = acc * XXH_PRIME64_1 + XXH_PRIME64_4;
2415 return acc;
2416}
2417
2418static xxh_u64 XXH64_avalanche(xxh_u64 h64)
2419{
2420 h64 ^= h64 >> 33;
2421 h64 *= XXH_PRIME64_2;
2422 h64 ^= h64 >> 29;
2423 h64 *= XXH_PRIME64_3;
2424 h64 ^= h64 >> 32;
2425 return h64;
2426}
2427
2428
2429#define XXH_get64bits(p) XXH_readLE64_align(p, align)
2430
2431static xxh_u64
2432XXH64_finalize(xxh_u64 h64, const xxh_u8* ptr, size_t len, XXH_alignment align)
2433{
2434 if (ptr==NULL) XXH_ASSERT(len == 0);
2435 len &= 31;
2436 while (len >= 8) {
2437 xxh_u64 const k1 = XXH64_round(0, XXH_get64bits(ptr));
2438 ptr += 8;
2439 h64 ^= k1;
2440 h64 = XXH_rotl64(h64,27) * XXH_PRIME64_1 + XXH_PRIME64_4;
2441 len -= 8;
2442 }
2443 if (len >= 4) {
2444 h64 ^= (xxh_u64)(XXH_get32bits(ptr)) * XXH_PRIME64_1;
2445 ptr += 4;
2446 h64 = XXH_rotl64(h64, 23) * XXH_PRIME64_2 + XXH_PRIME64_3;
2447 len -= 4;
2448 }
2449 while (len > 0) {
2450 h64 ^= (*ptr++) * XXH_PRIME64_5;
2451 h64 = XXH_rotl64(h64, 11) * XXH_PRIME64_1;
2452 --len;
2453 }
2454 return XXH64_avalanche(h64);
2455}
2456
2457#ifdef XXH_OLD_NAMES
2458# define PROCESS1_64 XXH_PROCESS1_64
2459# define PROCESS4_64 XXH_PROCESS4_64
2460# define PROCESS8_64 XXH_PROCESS8_64
2461#else
2462# undef XXH_PROCESS1_64
2463# undef XXH_PROCESS4_64
2464# undef XXH_PROCESS8_64
2465#endif
2466
2467XXH_FORCE_INLINE xxh_u64
2468XXH64_endian_align(const xxh_u8* input, size_t len, xxh_u64 seed, XXH_alignment align)
2469{
2470 xxh_u64 h64;
2471 if (input==NULL) XXH_ASSERT(len == 0);
2472
2473 if (len>=32) {
2474 const xxh_u8* const bEnd = input + len;
2475 const xxh_u8* const limit = bEnd - 31;
2476 xxh_u64 v1 = seed + XXH_PRIME64_1 + XXH_PRIME64_2;
2477 xxh_u64 v2 = seed + XXH_PRIME64_2;
2478 xxh_u64 v3 = seed + 0;
2479 xxh_u64 v4 = seed - XXH_PRIME64_1;
2480
2481 do {
2482 v1 = XXH64_round(v1, XXH_get64bits(input)); input+=8;
2483 v2 = XXH64_round(v2, XXH_get64bits(input)); input+=8;
2484 v3 = XXH64_round(v3, XXH_get64bits(input)); input+=8;
2485 v4 = XXH64_round(v4, XXH_get64bits(input)); input+=8;
2486 } while (input<limit);
2487
2488 h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18);
2489 h64 = XXH64_mergeRound(h64, v1);
2490 h64 = XXH64_mergeRound(h64, v2);
2491 h64 = XXH64_mergeRound(h64, v3);
2492 h64 = XXH64_mergeRound(h64, v4);
2493
2494 } else {
2495 h64 = seed + XXH_PRIME64_5;
2496 }
2497
2498 h64 += (xxh_u64) len;
2499
2500 return XXH64_finalize(h64, input, len, align);
2501}
2502
2503
2504/*! @ingroup xxh64_family */
2505XXH_PUBLIC_API XXH64_hash_t XXH64 (const void* input, size_t len, XXH64_hash_t seed)
2506{
2507#if 0
2508 /* Simple version, good for code maintenance, but unfortunately slow for small inputs */
2509 XXH64_state_t state;
2510 XXH64_reset(&state, seed);
2511 XXH64_update(&state, (const xxh_u8*)input, len);
2512 return XXH64_digest(&state);
2513#else
2514 if (XXH_FORCE_ALIGN_CHECK) {
2515 if ((((size_t)input) & 7)==0) { /* Input is aligned, let's leverage the speed advantage */
2516 return XXH64_endian_align((const xxh_u8*)input, len, seed, XXH_aligned);
2517 } }
2518
2519 return XXH64_endian_align((const xxh_u8*)input, len, seed, XXH_unaligned);
2520
2521#endif
2522}
2523
2524/******* Hash Streaming *******/
2525
2526/*! @ingroup xxh64_family*/
2527XXH_PUBLIC_API XXH64_state_t* XXH64_createState(void)
2528{
2529 return (XXH64_state_t*)XXH_malloc(sizeof(XXH64_state_t));
2530}
2531/*! @ingroup xxh64_family */
2532XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr)
2533{
2534 XXH_free(statePtr);
2535 return XXH_OK;
2536}
2537
2538/*! @ingroup xxh64_family */
2539XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t* dstState, const XXH64_state_t* srcState)
2540{
2541 XXH_memcpy(dstState, srcState, sizeof(*dstState));
2542}
2543
2544/*! @ingroup xxh64_family */
2545XXH_PUBLIC_API XXH_errorcode XXH64_reset(XXH64_state_t* statePtr, XXH64_hash_t seed)
2546{
2547 XXH_ASSERT(statePtr != NULL);
2548 memset(statePtr, 0, sizeof(*statePtr));
2549 statePtr->v[0] = seed + XXH_PRIME64_1 + XXH_PRIME64_2;
2550 statePtr->v[1] = seed + XXH_PRIME64_2;
2551 statePtr->v[2] = seed + 0;
2552 statePtr->v[3] = seed - XXH_PRIME64_1;
2553 return XXH_OK;
2554}
2555
2556/*! @ingroup xxh64_family */
2557XXH_PUBLIC_API XXH_errorcode
2558XXH64_update (XXH64_state_t* state, const void* input, size_t len)
2559{
2560 if (input==NULL) {
2561 XXH_ASSERT(len == 0);
2562 return XXH_OK;
2563 }
2564
2565 { const xxh_u8* p = (const xxh_u8*)input;
2566 const xxh_u8* const bEnd = p + len;
2567
2568 state->total_len += len;
2569
2570 if (state->memsize + len < 32) { /* fill in tmp buffer */
2571 XXH_memcpy(((xxh_u8*)state->mem64) + state->memsize, input, len);
2572 state->memsize += (xxh_u32)len;
2573 return XXH_OK;
2574 }
2575
2576 if (state->memsize) { /* tmp buffer is full */
2577 XXH_memcpy(((xxh_u8*)state->mem64) + state->memsize, input, 32-state->memsize);
2578 state->v[0] = XXH64_round(state->v[0], XXH_readLE64(state->mem64+0));
2579 state->v[1] = XXH64_round(state->v[1], XXH_readLE64(state->mem64+1));
2580 state->v[2] = XXH64_round(state->v[2], XXH_readLE64(state->mem64+2));
2581 state->v[3] = XXH64_round(state->v[3], XXH_readLE64(state->mem64+3));
2582 p += 32 - state->memsize;
2583 state->memsize = 0;
2584 }
2585
2586 if (p+32 <= bEnd) {
2587 const xxh_u8* const limit = bEnd - 32;
2588
2589 do {
2590 state->v[0] = XXH64_round(state->v[0], XXH_readLE64(p)); p+=8;
2591 state->v[1] = XXH64_round(state->v[1], XXH_readLE64(p)); p+=8;
2592 state->v[2] = XXH64_round(state->v[2], XXH_readLE64(p)); p+=8;
2593 state->v[3] = XXH64_round(state->v[3], XXH_readLE64(p)); p+=8;
2594 } while (p<=limit);
2595
2596 }
2597
2598 if (p < bEnd) {
2599 XXH_memcpy(state->mem64, p, (size_t)(bEnd-p));
2600 state->memsize = (unsigned)(bEnd-p);
2601 }
2602 }
2603
2604 return XXH_OK;
2605}
2606
2607
2608/*! @ingroup xxh64_family */
2609XXH_PUBLIC_API XXH64_hash_t XXH64_digest(const XXH64_state_t* state)
2610{
2611 xxh_u64 h64;
2612
2613 if (state->total_len >= 32) {
2614 h64 = XXH_rotl64(state->v[0], 1) + XXH_rotl64(state->v[1], 7) + XXH_rotl64(state->v[2], 12) + XXH_rotl64(state->v[3], 18);
2615 h64 = XXH64_mergeRound(h64, state->v[0]);
2616 h64 = XXH64_mergeRound(h64, state->v[1]);
2617 h64 = XXH64_mergeRound(h64, state->v[2]);
2618 h64 = XXH64_mergeRound(h64, state->v[3]);
2619 } else {
2620 h64 = state->v[2] /*seed*/ + XXH_PRIME64_5;
2621 }
2622
2623 h64 += (xxh_u64) state->total_len;
2624
2625 return XXH64_finalize(h64, (const xxh_u8*)state->mem64, (size_t)state->total_len, XXH_aligned);
2626}
2627
2628
2629/******* Canonical representation *******/
2630
2631/*! @ingroup xxh64_family */
2632XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash)
2633{
2634 /* XXH_STATIC_ASSERT(sizeof(XXH64_canonical_t) == sizeof(XXH64_hash_t)); */
2635 if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap64(hash);
2636 XXH_memcpy(dst, &hash, sizeof(*dst));
2637}
2638
2639/*! @ingroup xxh64_family */
2640XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src)
2641{
2642 return XXH_readBE64(src);
2643}
2644
2645#ifndef XXH_NO_XXH3
2646
2647/* *********************************************************************
2648* XXH3
2649* New generation hash designed for speed on small keys and vectorization
2650************************************************************************ */
2651/*!
2652 * @}
2653 * @defgroup xxh3_impl XXH3 implementation
2654 * @ingroup impl
2655 * @{
2656 */
2657
2658/* === Compiler specifics === */
2659
2660#if ((defined(sun) || defined(__sun)) && __cplusplus) /* Solaris includes __STDC_VERSION__ with C++. Tested with GCC 5.5 */
2661# define XXH_RESTRICT /* disable */
2662#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* >= C99 */
2663# define XXH_RESTRICT restrict
2664#else
2665/* Note: it might be useful to define __restrict or __restrict__ for some C++ compilers */
2666# define XXH_RESTRICT /* disable */
2667#endif
2668
2669#if (defined(__GNUC__) && (__GNUC__ >= 3)) \
2670 || (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 800)) \
2671 || defined(__clang__)
2672# define XXH_likely(x) __builtin_expect(x, 1)
2673# define XXH_unlikely(x) __builtin_expect(x, 0)
2674#else
2675# define XXH_likely(x) (x)
2676# define XXH_unlikely(x) (x)
2677#endif
2678
2679#if defined(__GNUC__) || defined(__clang__)
2680# if defined(__ARM_NEON__) || defined(__ARM_NEON) \
2681 || defined(__aarch64__) || defined(_M_ARM) \
2682 || defined(_M_ARM64) || defined(_M_ARM64EC)
2683# define inline __inline__ /* circumvent a clang bug */
2684# include <arm_neon.h>
2685# undef inline
2686# elif defined(__AVX2__)
2687# include <immintrin.h>
2688# elif defined(__SSE2__)
2689# include <emmintrin.h>
2690# endif
2691#endif
2692
2693#if defined(_MSC_VER)
2694# include <intrin.h>
2695#endif
2696
2697/*
2698 * One goal of XXH3 is to make it fast on both 32-bit and 64-bit, while
2699 * remaining a true 64-bit/128-bit hash function.
2700 *
2701 * This is done by prioritizing a subset of 64-bit operations that can be
2702 * emulated without too many steps on the average 32-bit machine.
2703 *
2704 * For example, these two lines seem similar, and run equally fast on 64-bit:
2705 *
2706 * xxh_u64 x;
2707 * x ^= (x >> 47); // good
2708 * x ^= (x >> 13); // bad
2709 *
2710 * However, to a 32-bit machine, there is a major difference.
2711 *
2712 * x ^= (x >> 47) looks like this:
2713 *
2714 * x.lo ^= (x.hi >> (47 - 32));
2715 *
2716 * while x ^= (x >> 13) looks like this:
2717 *
2718 * // note: funnel shifts are not usually cheap.
2719 * x.lo ^= (x.lo >> 13) | (x.hi << (32 - 13));
2720 * x.hi ^= (x.hi >> 13);
2721 *
2722 * The first one is significantly faster than the second, simply because the
2723 * shift is larger than 32. This means:
2724 * - All the bits we need are in the upper 32 bits, so we can ignore the lower
2725 * 32 bits in the shift.
2726 * - The shift result will always fit in the lower 32 bits, and therefore,
2727 * we can ignore the upper 32 bits in the xor.
2728 *
2729 * Thanks to this optimization, XXH3 only requires these features to be efficient:
2730 *
2731 * - Usable unaligned access
2732 * - A 32-bit or 64-bit ALU
2733 * - If 32-bit, a decent ADC instruction
2734 * - A 32 or 64-bit multiply with a 64-bit result
2735 * - For the 128-bit variant, a decent byteswap helps short inputs.
2736 *
2737 * The first two are already required by XXH32, and almost all 32-bit and 64-bit
2738 * platforms which can run XXH32 can run XXH3 efficiently.
2739 *
2740 * Thumb-1, the classic 16-bit only subset of ARM's instruction set, is one
2741 * notable exception.
2742 *
2743 * First of all, Thumb-1 lacks support for the UMULL instruction which
2744 * performs the important long multiply. This means numerous __aeabi_lmul
2745 * calls.
2746 *
2747 * Second of all, the 8 functional registers are just not enough.
2748 * Setup for __aeabi_lmul, byteshift loads, pointers, and all arithmetic need
2749 * Lo registers, and this shuffling results in thousands more MOVs than A32.
2750 *
2751 * A32 and T32 don't have this limitation. They can access all 14 registers,
2752 * do a 32->64 multiply with UMULL, and the flexible operand allowing free
2753 * shifts is helpful, too.
2754 *
2755 * Therefore, we do a quick sanity check.
2756 *
2757 * If compiling Thumb-1 for a target which supports ARM instructions, we will
2758 * emit a warning, as it is not a "sane" platform to compile for.
2759 *
2760 * Usually, if this happens, it is because of an accident and you probably need
2761 * to specify -march, as you likely meant to compile for a newer architecture.
2762 *
2763 * Credit: large sections of the vectorial and asm source code paths
2764 * have been contributed by @easyaspi314
2765 */
2766#if defined(__thumb__) && !defined(__thumb2__) && defined(__ARM_ARCH_ISA_ARM)
2767# warning "XXH3 is highly inefficient without ARM or Thumb-2."
2768#endif
2769
2770/* ==========================================
2771 * Vectorization detection
2772 * ========================================== */
2773
2774#ifdef XXH_DOXYGEN
2775/*!
2776 * @ingroup tuning
2777 * @brief Overrides the vectorization implementation chosen for XXH3.
2778 *
2779 * Can be defined to 0 to disable SIMD or any of the values mentioned in
2780 * @ref XXH_VECTOR_TYPE.
2781 *
2782 * If this is not defined, it uses predefined macros to determine the best
2783 * implementation.
2784 */
2785# define XXH_VECTOR XXH_SCALAR
2786/*!
2787 * @ingroup tuning
2788 * @brief Possible values for @ref XXH_VECTOR.
2789 *
2790 * Note that these are actually implemented as macros.
2791 *
2792 * If this is not defined, it is detected automatically.
2793 * @ref XXH_X86DISPATCH overrides this.
2794 */
2795enum XXH_VECTOR_TYPE /* fake enum */ {
2796 XXH_SCALAR = 0, /*!< Portable scalar version */
2797 XXH_SSE2 = 1, /*!<
2798 * SSE2 for Pentium 4, Opteron, all x86_64.
2799 *
2800 * @note SSE2 is also guaranteed on Windows 10, macOS, and
2801 * Android x86.
2802 */
2803 XXH_AVX2 = 2, /*!< AVX2 for Haswell and Bulldozer */
2804 XXH_AVX512 = 3, /*!< AVX512 for Skylake and Icelake */
2805 XXH_NEON = 4, /*!< NEON for most ARMv7-A and all AArch64 */
2806 XXH_VSX = 5, /*!< VSX and ZVector for POWER8/z13 (64-bit) */
2807};
2808/*!
2809 * @ingroup tuning
2810 * @brief Selects the minimum alignment for XXH3's accumulators.
2811 *
2812 * When using SIMD, this should match the alignment reqired for said vector
2813 * type, so, for example, 32 for AVX2.
2814 *
2815 * Default: Auto detected.
2816 */
2817# define XXH_ACC_ALIGN 8
2818#endif
2819
2820/* Actual definition */
2821#ifndef XXH_DOXYGEN
2822# define XXH_SCALAR 0
2823# define XXH_SSE2 1
2824# define XXH_AVX2 2
2825# define XXH_AVX512 3
2826# define XXH_NEON 4
2827# define XXH_VSX 5
2828#endif
2829
2830#ifndef XXH_VECTOR /* can be defined on command line */
2831# if ( \
2832 defined(__ARM_NEON__) || defined(__ARM_NEON) /* gcc */ \
2833 || defined(_M_ARM) || defined(_M_ARM64) || defined(_M_ARM64EC) /* msvc */ \
2834 ) && ( \
2835 defined(_WIN32) || defined(__LITTLE_ENDIAN__) /* little endian only */ \
2836 || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) \
2837 )
2838# define XXH_VECTOR XXH_NEON
2839# elif defined(__AVX512F__)
2840# define XXH_VECTOR XXH_AVX512
2841# elif defined(__AVX2__)
2842# define XXH_VECTOR XXH_AVX2
2843# elif defined(__SSE2__) || defined(_M_AMD64) || defined(_M_X64) || (defined(_M_IX86_FP) && (_M_IX86_FP == 2))
2844# define XXH_VECTOR XXH_SSE2
2845# elif (defined(__PPC64__) && defined(__POWER8_VECTOR__)) \
2846 || (defined(__s390x__) && defined(__VEC__)) \
2847 && defined(__GNUC__) /* TODO: IBM XL */
2848# define XXH_VECTOR XXH_VSX
2849# else
2850# define XXH_VECTOR XXH_SCALAR
2851# endif
2852#endif
2853
2854/*
2855 * Controls the alignment of the accumulator,
2856 * for compatibility with aligned vector loads, which are usually faster.
2857 */
2858#ifndef XXH_ACC_ALIGN
2859# if defined(XXH_X86DISPATCH)
2860# define XXH_ACC_ALIGN 64 /* for compatibility with avx512 */
2861# elif XXH_VECTOR == XXH_SCALAR /* scalar */
2862# define XXH_ACC_ALIGN 8
2863# elif XXH_VECTOR == XXH_SSE2 /* sse2 */
2864# define XXH_ACC_ALIGN 16
2865# elif XXH_VECTOR == XXH_AVX2 /* avx2 */
2866# define XXH_ACC_ALIGN 32
2867# elif XXH_VECTOR == XXH_NEON /* neon */
2868# define XXH_ACC_ALIGN 16
2869# elif XXH_VECTOR == XXH_VSX /* vsx */
2870# define XXH_ACC_ALIGN 16
2871# elif XXH_VECTOR == XXH_AVX512 /* avx512 */
2872# define XXH_ACC_ALIGN 64
2873# endif
2874#endif
2875
2876#if defined(XXH_X86DISPATCH) || XXH_VECTOR == XXH_SSE2 \
2877 || XXH_VECTOR == XXH_AVX2 || XXH_VECTOR == XXH_AVX512
2878# define XXH_SEC_ALIGN XXH_ACC_ALIGN
2879#else
2880# define XXH_SEC_ALIGN 8
2881#endif
2882
2883/*
2884 * UGLY HACK:
2885 * GCC usually generates the best code with -O3 for xxHash.
2886 *
2887 * However, when targeting AVX2, it is overzealous in its unrolling resulting
2888 * in code roughly 3/4 the speed of Clang.
2889 *
2890 * There are other issues, such as GCC splitting _mm256_loadu_si256 into
2891 * _mm_loadu_si128 + _mm256_inserti128_si256. This is an optimization which
2892 * only applies to Sandy and Ivy Bridge... which don't even support AVX2.
2893 *
2894 * That is why when compiling the AVX2 version, it is recommended to use either
2895 * -O2 -mavx2 -march=haswell
2896 * or
2897 * -O2 -mavx2 -mno-avx256-split-unaligned-load
2898 * for decent performance, or to use Clang instead.
2899 *
2900 * Fortunately, we can control the first one with a pragma that forces GCC into
2901 * -O2, but the other one we can't control without "failed to inline always
2902 * inline function due to target mismatch" warnings.
2903 */
2904#if XXH_VECTOR == XXH_AVX2 /* AVX2 */ \
2905 && defined(__GNUC__) && !defined(__clang__) /* GCC, not Clang */ \
2906 && defined(__OPTIMIZE__) && !defined(__OPTIMIZE_SIZE__) /* respect -O0 and -Os */
2907# pragma GCC push_options
2908# pragma GCC optimize("-O2")
2909#endif
2910
2911
2912#if XXH_VECTOR == XXH_NEON
2913/*
2914 * NEON's setup for vmlal_u32 is a little more complicated than it is on
2915 * SSE2, AVX2, and VSX.
2916 *
2917 * While PMULUDQ and VMULEUW both perform a mask, VMLAL.U32 performs an upcast.
2918 *
2919 * To do the same operation, the 128-bit 'Q' register needs to be split into
2920 * two 64-bit 'D' registers, performing this operation::
2921 *
2922 * [ a | b ]
2923 * | '---------. .--------' |
2924 * | x |
2925 * | .---------' '--------. |
2926 * [ a & 0xFFFFFFFF | b & 0xFFFFFFFF ],[ a >> 32 | b >> 32 ]
2927 *
2928 * Due to significant changes in aarch64, the fastest method for aarch64 is
2929 * completely different than the fastest method for ARMv7-A.
2930 *
2931 * ARMv7-A treats D registers as unions overlaying Q registers, so modifying
2932 * D11 will modify the high half of Q5. This is similar to how modifying AH
2933 * will only affect bits 8-15 of AX on x86.
2934 *
2935 * VZIP takes two registers, and puts even lanes in one register and odd lanes
2936 * in the other.
2937 *
2938 * On ARMv7-A, this strangely modifies both parameters in place instead of
2939 * taking the usual 3-operand form.
2940 *
2941 * Therefore, if we want to do this, we can simply use a D-form VZIP.32 on the
2942 * lower and upper halves of the Q register to end up with the high and low
2943 * halves where we want - all in one instruction.
2944 *
2945 * vzip.32 d10, d11 @ d10 = { d10[0], d11[0] }; d11 = { d10[1], d11[1] }
2946 *
2947 * Unfortunately we need inline assembly for this: Instructions modifying two
2948 * registers at once is not possible in GCC or Clang's IR, and they have to
2949 * create a copy.
2950 *
2951 * aarch64 requires a different approach.
2952 *
2953 * In order to make it easier to write a decent compiler for aarch64, many
2954 * quirks were removed, such as conditional execution.
2955 *
2956 * NEON was also affected by this.
2957 *
2958 * aarch64 cannot access the high bits of a Q-form register, and writes to a
2959 * D-form register zero the high bits, similar to how writes to W-form scalar
2960 * registers (or DWORD registers on x86_64) work.
2961 *
2962 * The formerly free vget_high intrinsics now require a vext (with a few
2963 * exceptions)
2964 *
2965 * Additionally, VZIP was replaced by ZIP1 and ZIP2, which are the equivalent
2966 * of PUNPCKL* and PUNPCKH* in SSE, respectively, in order to only modify one
2967 * operand.
2968 *
2969 * The equivalent of the VZIP.32 on the lower and upper halves would be this
2970 * mess:
2971 *
2972 * ext v2.4s, v0.4s, v0.4s, #2 // v2 = { v0[2], v0[3], v0[0], v0[1] }
2973 * zip1 v1.2s, v0.2s, v2.2s // v1 = { v0[0], v2[0] }
2974 * zip2 v0.2s, v0.2s, v1.2s // v0 = { v0[1], v2[1] }
2975 *
2976 * Instead, we use a literal downcast, vmovn_u64 (XTN), and vshrn_n_u64 (SHRN):
2977 *
2978 * shrn v1.2s, v0.2d, #32 // v1 = (uint32x2_t)(v0 >> 32);
2979 * xtn v0.2s, v0.2d // v0 = (uint32x2_t)(v0 & 0xFFFFFFFF);
2980 *
2981 * This is available on ARMv7-A, but is less efficient than a single VZIP.32.
2982 */
2983
2984/*!
2985 * Function-like macro:
2986 * void XXH_SPLIT_IN_PLACE(uint64x2_t &in, uint32x2_t &outLo, uint32x2_t &outHi)
2987 * {
2988 * outLo = (uint32x2_t)(in & 0xFFFFFFFF);
2989 * outHi = (uint32x2_t)(in >> 32);
2990 * in = UNDEFINED;
2991 * }
2992 */
2993# if !defined(XXH_NO_VZIP_HACK) /* define to disable */ \
2994 && (defined(__GNUC__) || defined(__clang__)) \
2995 && (defined(__arm__) || defined(__thumb__) || defined(_M_ARM))
2996# define XXH_SPLIT_IN_PLACE(in, outLo, outHi) \
2997 do { \
2998 /* Undocumented GCC/Clang operand modifier: %e0 = lower D half, %f0 = upper D half */ \
2999 /* https://github.com/gcc-mirror/gcc/blob/38cf91e5/gcc/config/arm/arm.c#L22486 */ \
3000 /* https://github.com/llvm-mirror/llvm/blob/2c4ca683/lib/Target/ARM/ARMAsmPrinter.cpp#L399 */ \
3001 __asm__("vzip.32 %e0, %f0" : "+w" (in)); \
3002 (outLo) = vget_low_u32 (vreinterpretq_u32_u64(in)); \
3003 (outHi) = vget_high_u32(vreinterpretq_u32_u64(in)); \
3004 } while (0)
3005# else
3006# define XXH_SPLIT_IN_PLACE(in, outLo, outHi) \
3007 do { \
3008 (outLo) = vmovn_u64 (in); \
3009 (outHi) = vshrn_n_u64 ((in), 32); \
3010 } while (0)
3011# endif
3012
3013/*!
3014 * @ingroup tuning
3015 * @brief Controls the NEON to scalar ratio for XXH3
3016 *
3017 * On AArch64 when not optimizing for size, XXH3 will run 6 lanes using NEON and
3018 * 2 lanes on scalar by default.
3019 *
3020 * This can be set to 2, 4, 6, or 8. ARMv7 will default to all 8 NEON lanes, as the
3021 * emulated 64-bit arithmetic is too slow.
3022 *
3023 * Modern ARM CPUs are _very_ sensitive to how their pipelines are used.
3024 *
3025 * For example, the Cortex-A73 can dispatch 3 micro-ops per cycle, but it can't
3026 * have more than 2 NEON (F0/F1) micro-ops. If you are only using NEON instructions,
3027 * you are only using 2/3 of the CPU bandwidth.
3028 *
3029 * This is even more noticable on the more advanced cores like the A76 which
3030 * can dispatch 8 micro-ops per cycle, but still only 2 NEON micro-ops at once.
3031 *
3032 * Therefore, @ref XXH3_NEON_LANES lanes will be processed using NEON, and the
3033 * remaining lanes will use scalar instructions. This improves the bandwidth
3034 * and also gives the integer pipelines something to do besides twiddling loop
3035 * counters and pointers.
3036 *
3037 * This change benefits CPUs with large micro-op buffers without negatively affecting
3038 * other CPUs:
3039 *
3040 * | Chipset | Dispatch type | NEON only | 6:2 hybrid | Diff. |
3041 * |:----------------------|:--------------------|----------:|-----------:|------:|
3042 * | Snapdragon 730 (A76) | 2 NEON/8 micro-ops | 8.8 GB/s | 10.1 GB/s | ~16% |
3043 * | Snapdragon 835 (A73) | 2 NEON/3 micro-ops | 5.1 GB/s | 5.3 GB/s | ~5% |
3044 * | Marvell PXA1928 (A53) | In-order dual-issue | 1.9 GB/s | 1.9 GB/s | 0% |
3045 *
3046 * It also seems to fix some bad codegen on GCC, making it almost as fast as clang.
3047 *
3048 * @see XXH3_accumulate_512_neon()
3049 */
3050# ifndef XXH3_NEON_LANES
3051# if (defined(__aarch64__) || defined(__arm64__) || defined(_M_ARM64) || defined(_M_ARM64EC)) \
3052 && !defined(__OPTIMIZE_SIZE__)
3053# define XXH3_NEON_LANES 6
3054# else
3055# define XXH3_NEON_LANES XXH_ACC_NB
3056# endif
3057# endif
3058#endif /* XXH_VECTOR == XXH_NEON */
3059
3060/*
3061 * VSX and Z Vector helpers.
3062 *
3063 * This is very messy, and any pull requests to clean this up are welcome.
3064 *
3065 * There are a lot of problems with supporting VSX and s390x, due to
3066 * inconsistent intrinsics, spotty coverage, and multiple endiannesses.
3067 */
3068#if XXH_VECTOR == XXH_VSX
3069# if defined(__s390x__)
3070# include <s390intrin.h>
3071# else
3072/* gcc's altivec.h can have the unwanted consequence to unconditionally
3073 * #define bool, vector, and pixel keywords,
3074 * with bad consequences for programs already using these keywords for other purposes.
3075 * The paragraph defining these macros is skipped when __APPLE_ALTIVEC__ is defined.
3076 * __APPLE_ALTIVEC__ is _generally_ defined automatically by the compiler,
3077 * but it seems that, in some cases, it isn't.
3078 * Force the build macro to be defined, so that keywords are not altered.
3079 */
3080# if defined(__GNUC__) && !defined(__APPLE_ALTIVEC__)
3081# define __APPLE_ALTIVEC__
3082# endif
3083# include <altivec.h>
3084# endif
3085
3086typedef __vector unsigned long long xxh_u64x2;
3087typedef __vector unsigned char xxh_u8x16;
3088typedef __vector unsigned xxh_u32x4;
3089
3090# ifndef XXH_VSX_BE
3091# if defined(__BIG_ENDIAN__) \
3092 || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
3093# define XXH_VSX_BE 1
3094# elif defined(__VEC_ELEMENT_REG_ORDER__) && __VEC_ELEMENT_REG_ORDER__ == __ORDER_BIG_ENDIAN__
3095# warning "-maltivec=be is not recommended. Please use native endianness."
3096# define XXH_VSX_BE 1
3097# else
3098# define XXH_VSX_BE 0
3099# endif
3100# endif /* !defined(XXH_VSX_BE) */
3101
3102# if XXH_VSX_BE
3103# if defined(__POWER9_VECTOR__) || (defined(__clang__) && defined(__s390x__))
3104# define XXH_vec_revb vec_revb
3105# else
3106/*!
3107 * A polyfill for POWER9's vec_revb().
3108 */
3109XXH_FORCE_INLINE xxh_u64x2 XXH_vec_revb(xxh_u64x2 val)
3110{
3111 xxh_u8x16 const vByteSwap = { 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
3112 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08 };
3113 return vec_perm(val, val, vByteSwap);
3114}
3115# endif
3116# endif /* XXH_VSX_BE */
3117
3118/*!
3119 * Performs an unaligned vector load and byte swaps it on big endian.
3120 */
3121XXH_FORCE_INLINE xxh_u64x2 XXH_vec_loadu(const void *ptr)
3122{
3123 xxh_u64x2 ret;
3124 XXH_memcpy(&ret, ptr, sizeof(xxh_u64x2));
3125# if XXH_VSX_BE
3126 ret = XXH_vec_revb(ret);
3127# endif
3128 return ret;
3129}
3130
3131/*
3132 * vec_mulo and vec_mule are very problematic intrinsics on PowerPC
3133 *
3134 * These intrinsics weren't added until GCC 8, despite existing for a while,
3135 * and they are endian dependent. Also, their meaning swap depending on version.
3136 * */
3137# if defined(__s390x__)
3138 /* s390x is always big endian, no issue on this platform */
3139# define XXH_vec_mulo vec_mulo
3140# define XXH_vec_mule vec_mule
3141# elif defined(__clang__) && XXH_HAS_BUILTIN(__builtin_altivec_vmuleuw)
3142/* Clang has a better way to control this, we can just use the builtin which doesn't swap. */
3143# define XXH_vec_mulo __builtin_altivec_vmulouw
3144# define XXH_vec_mule __builtin_altivec_vmuleuw
3145# else
3146/* gcc needs inline assembly */
3147/* Adapted from https://github.com/google/highwayhash/blob/master/highwayhash/hh_vsx.h. */
3148XXH_FORCE_INLINE xxh_u64x2 XXH_vec_mulo(xxh_u32x4 a, xxh_u32x4 b)
3149{
3150 xxh_u64x2 result;
3151 __asm__("vmulouw %0, %1, %2" : "=v" (result) : "v" (a), "v" (b));
3152 return result;
3153}
3154XXH_FORCE_INLINE xxh_u64x2 XXH_vec_mule(xxh_u32x4 a, xxh_u32x4 b)
3155{
3156 xxh_u64x2 result;
3157 __asm__("vmuleuw %0, %1, %2" : "=v" (result) : "v" (a), "v" (b));
3158 return result;
3159}
3160# endif /* XXH_vec_mulo, XXH_vec_mule */
3161#endif /* XXH_VECTOR == XXH_VSX */
3162
3163
3164/* prefetch
3165 * can be disabled, by declaring XXH_NO_PREFETCH build macro */
3166#if defined(XXH_NO_PREFETCH)
3167# define XXH_PREFETCH(ptr) (void)(ptr) /* disabled */
3168#else
3169# if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_IX86)) /* _mm_prefetch() not defined outside of x86/x64 */
3170# include <mmintrin.h> /* https://msdn.microsoft.com/fr-fr/library/84szxsww(v=vs.90).aspx */
3171# define XXH_PREFETCH(ptr) _mm_prefetch((const char*)(ptr), _MM_HINT_T0)
3172# elif defined(__GNUC__) && ( (__GNUC__ >= 4) || ( (__GNUC__ == 3) && (__GNUC_MINOR__ >= 1) ) )
3173# define XXH_PREFETCH(ptr) __builtin_prefetch((ptr), 0 /* rw==read */, 3 /* locality */)
3174# else
3175# define XXH_PREFETCH(ptr) (void)(ptr) /* disabled */
3176# endif
3177#endif /* XXH_NO_PREFETCH */
3178
3179
3180/* ==========================================
3181 * XXH3 default settings
3182 * ========================================== */
3183
3184#define XXH_SECRET_DEFAULT_SIZE 192 /* minimum XXH3_SECRET_SIZE_MIN */
3185
3186#if (XXH_SECRET_DEFAULT_SIZE < XXH3_SECRET_SIZE_MIN)
3187# error "default keyset is not large enough"
3188#endif
3189
3190/*! Pseudorandom secret taken directly from FARSH. */
3191XXH_ALIGN(64) static const xxh_u8 XXH3_kSecret[XXH_SECRET_DEFAULT_SIZE] = {
3192 0xb8, 0xfe, 0x6c, 0x39, 0x23, 0xa4, 0x4b, 0xbe, 0x7c, 0x01, 0x81, 0x2c, 0xf7, 0x21, 0xad, 0x1c,
3193 0xde, 0xd4, 0x6d, 0xe9, 0x83, 0x90, 0x97, 0xdb, 0x72, 0x40, 0xa4, 0xa4, 0xb7, 0xb3, 0x67, 0x1f,
3194 0xcb, 0x79, 0xe6, 0x4e, 0xcc, 0xc0, 0xe5, 0x78, 0x82, 0x5a, 0xd0, 0x7d, 0xcc, 0xff, 0x72, 0x21,
3195 0xb8, 0x08, 0x46, 0x74, 0xf7, 0x43, 0x24, 0x8e, 0xe0, 0x35, 0x90, 0xe6, 0x81, 0x3a, 0x26, 0x4c,
3196 0x3c, 0x28, 0x52, 0xbb, 0x91, 0xc3, 0x00, 0xcb, 0x88, 0xd0, 0x65, 0x8b, 0x1b, 0x53, 0x2e, 0xa3,
3197 0x71, 0x64, 0x48, 0x97, 0xa2, 0x0d, 0xf9, 0x4e, 0x38, 0x19, 0xef, 0x46, 0xa9, 0xde, 0xac, 0xd8,
3198 0xa8, 0xfa, 0x76, 0x3f, 0xe3, 0x9c, 0x34, 0x3f, 0xf9, 0xdc, 0xbb, 0xc7, 0xc7, 0x0b, 0x4f, 0x1d,
3199 0x8a, 0x51, 0xe0, 0x4b, 0xcd, 0xb4, 0x59, 0x31, 0xc8, 0x9f, 0x7e, 0xc9, 0xd9, 0x78, 0x73, 0x64,
3200 0xea, 0xc5, 0xac, 0x83, 0x34, 0xd3, 0xeb, 0xc3, 0xc5, 0x81, 0xa0, 0xff, 0xfa, 0x13, 0x63, 0xeb,
3201 0x17, 0x0d, 0xdd, 0x51, 0xb7, 0xf0, 0xda, 0x49, 0xd3, 0x16, 0x55, 0x26, 0x29, 0xd4, 0x68, 0x9e,
3202 0x2b, 0x16, 0xbe, 0x58, 0x7d, 0x47, 0xa1, 0xfc, 0x8f, 0xf8, 0xb8, 0xd1, 0x7a, 0xd0, 0x31, 0xce,
3203 0x45, 0xcb, 0x3a, 0x8f, 0x95, 0x16, 0x04, 0x28, 0xaf, 0xd7, 0xfb, 0xca, 0xbb, 0x4b, 0x40, 0x7e,
3204};
3205
3206
3207#ifdef XXH_OLD_NAMES
3208# define kSecret XXH3_kSecret
3209#endif
3210
3211#ifdef XXH_DOXYGEN
3212/*!
3213 * @brief Calculates a 32-bit to 64-bit long multiply.
3214 *
3215 * Implemented as a macro.
3216 *
3217 * Wraps `__emulu` on MSVC x86 because it tends to call `__allmul` when it doesn't
3218 * need to (but it shouldn't need to anyways, it is about 7 instructions to do
3219 * a 64x64 multiply...). Since we know that this will _always_ emit `MULL`, we
3220 * use that instead of the normal method.
3221 *
3222 * If you are compiling for platforms like Thumb-1 and don't have a better option,
3223 * you may also want to write your own long multiply routine here.
3224 *
3225 * @param x, y Numbers to be multiplied
3226 * @return 64-bit product of the low 32 bits of @p x and @p y.
3227 */
3228XXH_FORCE_INLINE xxh_u64
3229XXH_mult32to64(xxh_u64 x, xxh_u64 y)
3230{
3231 return (x & 0xFFFFFFFF) * (y & 0xFFFFFFFF);
3232}
3233#elif defined(_MSC_VER) && defined(_M_IX86)
3234# define XXH_mult32to64(x, y) __emulu((unsigned)(x), (unsigned)(y))
3235#else
3236/*
3237 * Downcast + upcast is usually better than masking on older compilers like
3238 * GCC 4.2 (especially 32-bit ones), all without affecting newer compilers.
3239 *
3240 * The other method, (x & 0xFFFFFFFF) * (y & 0xFFFFFFFF), will AND both operands
3241 * and perform a full 64x64 multiply -- entirely redundant on 32-bit.
3242 */
3243# define XXH_mult32to64(x, y) ((xxh_u64)(xxh_u32)(x) * (xxh_u64)(xxh_u32)(y))
3244#endif
3245
3246/*!
3247 * @brief Calculates a 64->128-bit long multiply.
3248 *
3249 * Uses `__uint128_t` and `_umul128` if available, otherwise uses a scalar
3250 * version.
3251 *
3252 * @param lhs , rhs The 64-bit integers to be multiplied
3253 * @return The 128-bit result represented in an @ref XXH128_hash_t.
3254 */
3255static XXH128_hash_t
3256XXH_mult64to128(xxh_u64 lhs, xxh_u64 rhs)
3257{
3258 /*
3259 * GCC/Clang __uint128_t method.
3260 *
3261 * On most 64-bit targets, GCC and Clang define a __uint128_t type.
3262 * This is usually the best way as it usually uses a native long 64-bit
3263 * multiply, such as MULQ on x86_64 or MUL + UMULH on aarch64.
3264 *
3265 * Usually.
3266 *
3267 * Despite being a 32-bit platform, Clang (and emscripten) define this type
3268 * despite not having the arithmetic for it. This results in a laggy
3269 * compiler builtin call which calculates a full 128-bit multiply.
3270 * In that case it is best to use the portable one.
3271 * https://github.com/Cyan4973/xxHash/issues/211#issuecomment-515575677
3272 */
3273#if (defined(__GNUC__) || defined(__clang__)) && !defined(__wasm__) \
3274 && defined(__SIZEOF_INT128__) \
3275 || (defined(_INTEGRAL_MAX_BITS) && _INTEGRAL_MAX_BITS >= 128)
3276
3277 __uint128_t const product = (__uint128_t)lhs * (__uint128_t)rhs;
3278 XXH128_hash_t r128;
3279 r128.low64 = (xxh_u64)(product);
3280 r128.high64 = (xxh_u64)(product >> 64);
3281 return r128;
3282
3283 /*
3284 * MSVC for x64's _umul128 method.
3285 *
3286 * xxh_u64 _umul128(xxh_u64 Multiplier, xxh_u64 Multiplicand, xxh_u64 *HighProduct);
3287 *
3288 * This compiles to single operand MUL on x64.
3289 */
3290#elif (defined(_M_X64) || defined(_M_IA64)) && !defined(_M_ARM64EC)
3291
3292#ifndef _MSC_VER
3293# pragma intrinsic(_umul128)
3294#endif
3295 xxh_u64 product_high;
3296 xxh_u64 const product_low = _umul128(lhs, rhs, &product_high);
3297 XXH128_hash_t r128;
3298 r128.low64 = product_low;
3299 r128.high64 = product_high;
3300 return r128;
3301
3302 /*
3303 * MSVC for ARM64's __umulh method.
3304 *
3305 * This compiles to the same MUL + UMULH as GCC/Clang's __uint128_t method.
3306 */
3307#elif defined(_M_ARM64) || defined(_M_ARM64EC)
3308
3309#ifndef _MSC_VER
3310# pragma intrinsic(__umulh)
3311#endif
3312 XXH128_hash_t r128;
3313 r128.low64 = lhs * rhs;
3314 r128.high64 = __umulh(lhs, rhs);
3315 return r128;
3316
3317#else
3318 /*
3319 * Portable scalar method. Optimized for 32-bit and 64-bit ALUs.
3320 *
3321 * This is a fast and simple grade school multiply, which is shown below
3322 * with base 10 arithmetic instead of base 0x100000000.
3323 *
3324 * 9 3 // D2 lhs = 93
3325 * x 7 5 // D2 rhs = 75
3326 * ----------
3327 * 1 5 // D2 lo_lo = (93 % 10) * (75 % 10) = 15
3328 * 4 5 | // D2 hi_lo = (93 / 10) * (75 % 10) = 45
3329 * 2 1 | // D2 lo_hi = (93 % 10) * (75 / 10) = 21
3330 * + 6 3 | | // D2 hi_hi = (93 / 10) * (75 / 10) = 63
3331 * ---------
3332 * 2 7 | // D2 cross = (15 / 10) + (45 % 10) + 21 = 27
3333 * + 6 7 | | // D2 upper = (27 / 10) + (45 / 10) + 63 = 67
3334 * ---------
3335 * 6 9 7 5 // D4 res = (27 * 10) + (15 % 10) + (67 * 100) = 6975
3336 *
3337 * The reasons for adding the products like this are:
3338 * 1. It avoids manual carry tracking. Just like how
3339 * (9 * 9) + 9 + 9 = 99, the same applies with this for UINT64_MAX.
3340 * This avoids a lot of complexity.
3341 *
3342 * 2. It hints for, and on Clang, compiles to, the powerful UMAAL
3343 * instruction available in ARM's Digital Signal Processing extension
3344 * in 32-bit ARMv6 and later, which is shown below:
3345 *
3346 * void UMAAL(xxh_u32 *RdLo, xxh_u32 *RdHi, xxh_u32 Rn, xxh_u32 Rm)
3347 * {
3348 * xxh_u64 product = (xxh_u64)*RdLo * (xxh_u64)*RdHi + Rn + Rm;
3349 * *RdLo = (xxh_u32)(product & 0xFFFFFFFF);
3350 * *RdHi = (xxh_u32)(product >> 32);
3351 * }
3352 *
3353 * This instruction was designed for efficient long multiplication, and
3354 * allows this to be calculated in only 4 instructions at speeds
3355 * comparable to some 64-bit ALUs.
3356 *
3357 * 3. It isn't terrible on other platforms. Usually this will be a couple
3358 * of 32-bit ADD/ADCs.
3359 */
3360
3361 /* First calculate all of the cross products. */
3362 xxh_u64 const lo_lo = XXH_mult32to64(lhs & 0xFFFFFFFF, rhs & 0xFFFFFFFF);
3363 xxh_u64 const hi_lo = XXH_mult32to64(lhs >> 32, rhs & 0xFFFFFFFF);
3364 xxh_u64 const lo_hi = XXH_mult32to64(lhs & 0xFFFFFFFF, rhs >> 32);
3365 xxh_u64 const hi_hi = XXH_mult32to64(lhs >> 32, rhs >> 32);
3366
3367 /* Now add the products together. These will never overflow. */
3368 xxh_u64 const cross = (lo_lo >> 32) + (hi_lo & 0xFFFFFFFF) + lo_hi;
3369 xxh_u64 const upper = (hi_lo >> 32) + (cross >> 32) + hi_hi;
3370 xxh_u64 const lower = (cross << 32) | (lo_lo & 0xFFFFFFFF);
3371
3372 XXH128_hash_t r128;
3373 r128.low64 = lower;
3374 r128.high64 = upper;
3375 return r128;
3376#endif
3377}
3378
3379/*!
3380 * @brief Calculates a 64-bit to 128-bit multiply, then XOR folds it.
3381 *
3382 * The reason for the separate function is to prevent passing too many structs
3383 * around by value. This will hopefully inline the multiply, but we don't force it.
3384 *
3385 * @param lhs , rhs The 64-bit integers to multiply
3386 * @return The low 64 bits of the product XOR'd by the high 64 bits.
3387 * @see XXH_mult64to128()
3388 */
3389static xxh_u64
3390XXH3_mul128_fold64(xxh_u64 lhs, xxh_u64 rhs)
3391{
3392 XXH128_hash_t product = XXH_mult64to128(lhs, rhs);
3393 return product.low64 ^ product.high64;
3394}
3395
3396/*! Seems to produce slightly better code on GCC for some reason. */
3397XXH_FORCE_INLINE xxh_u64 XXH_xorshift64(xxh_u64 v64, int shift)
3398{
3399 XXH_ASSERT(0 <= shift && shift < 64);
3400 return v64 ^ (v64 >> shift);
3401}
3402
3403/*
3404 * This is a fast avalanche stage,
3405 * suitable when input bits are already partially mixed
3406 */
3407static XXH64_hash_t XXH3_avalanche(xxh_u64 h64)
3408{
3409 h64 = XXH_xorshift64(h64, 37);
3410 h64 *= 0x165667919E3779F9ULL;
3411 h64 = XXH_xorshift64(h64, 32);
3412 return h64;
3413}
3414
3415/*
3416 * This is a stronger avalanche,
3417 * inspired by Pelle Evensen's rrmxmx
3418 * preferable when input has not been previously mixed
3419 */
3420static XXH64_hash_t XXH3_rrmxmx(xxh_u64 h64, xxh_u64 len)
3421{
3422 /* this mix is inspired by Pelle Evensen's rrmxmx */
3423 h64 ^= XXH_rotl64(h64, 49) ^ XXH_rotl64(h64, 24);
3424 h64 *= 0x9FB21C651E98DF25ULL;
3425 h64 ^= (h64 >> 35) + len ;
3426 h64 *= 0x9FB21C651E98DF25ULL;
3427 return XXH_xorshift64(h64, 28);
3428}
3429
3430
3431/* ==========================================
3432 * Short keys
3433 * ==========================================
3434 * One of the shortcomings of XXH32 and XXH64 was that their performance was
3435 * sub-optimal on short lengths. It used an iterative algorithm which strongly
3436 * favored lengths that were a multiple of 4 or 8.
3437 *
3438 * Instead of iterating over individual inputs, we use a set of single shot
3439 * functions which piece together a range of lengths and operate in constant time.
3440 *
3441 * Additionally, the number of multiplies has been significantly reduced. This
3442 * reduces latency, especially when emulating 64-bit multiplies on 32-bit.
3443 *
3444 * Depending on the platform, this may or may not be faster than XXH32, but it
3445 * is almost guaranteed to be faster than XXH64.
3446 */
3447
3448/*
3449 * At very short lengths, there isn't enough input to fully hide secrets, or use
3450 * the entire secret.
3451 *
3452 * There is also only a limited amount of mixing we can do before significantly
3453 * impacting performance.
3454 *
3455 * Therefore, we use different sections of the secret and always mix two secret
3456 * samples with an XOR. This should have no effect on performance on the
3457 * seedless or withSeed variants because everything _should_ be constant folded
3458 * by modern compilers.
3459 *
3460 * The XOR mixing hides individual parts of the secret and increases entropy.
3461 *
3462 * This adds an extra layer of strength for custom secrets.
3463 */
3464XXH_FORCE_INLINE XXH64_hash_t
3465XXH3_len_1to3_64b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed)
3466{
3467 XXH_ASSERT(input != NULL);
3468 XXH_ASSERT(1 <= len && len <= 3);
3469 XXH_ASSERT(secret != NULL);
3470 /*
3471 * len = 1: combined = { input[0], 0x01, input[0], input[0] }
3472 * len = 2: combined = { input[1], 0x02, input[0], input[1] }
3473 * len = 3: combined = { input[2], 0x03, input[0], input[1] }
3474 */
3475 { xxh_u8 const c1 = input[0];
3476 xxh_u8 const c2 = input[len >> 1];
3477 xxh_u8 const c3 = input[len - 1];
3478 xxh_u32 const combined = ((xxh_u32)c1 << 16) | ((xxh_u32)c2 << 24)
3479 | ((xxh_u32)c3 << 0) | ((xxh_u32)len << 8);
3480 xxh_u64 const bitflip = (XXH_readLE32(secret) ^ XXH_readLE32(secret+4)) + seed;
3481 xxh_u64 const keyed = (xxh_u64)combined ^ bitflip;
3482 return XXH64_avalanche(keyed);
3483 }
3484}
3485
3486XXH_FORCE_INLINE XXH64_hash_t
3487XXH3_len_4to8_64b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed)
3488{
3489 XXH_ASSERT(input != NULL);
3490 XXH_ASSERT(secret != NULL);
3491 XXH_ASSERT(4 <= len && len <= 8);
3492 seed ^= (xxh_u64)XXH_swap32((xxh_u32)seed) << 32;
3493 { xxh_u32 const input1 = XXH_readLE32(input);
3494 xxh_u32 const input2 = XXH_readLE32(input + len - 4);
3495 xxh_u64 const bitflip = (XXH_readLE64(secret+8) ^ XXH_readLE64(secret+16)) - seed;
3496 xxh_u64 const input64 = input2 + (((xxh_u64)input1) << 32);
3497 xxh_u64 const keyed = input64 ^ bitflip;
3498 return XXH3_rrmxmx(keyed, len);
3499 }
3500}
3501
3502XXH_FORCE_INLINE XXH64_hash_t
3503XXH3_len_9to16_64b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed)
3504{
3505 XXH_ASSERT(input != NULL);
3506 XXH_ASSERT(secret != NULL);
3507 XXH_ASSERT(9 <= len && len <= 16);
3508 { xxh_u64 const bitflip1 = (XXH_readLE64(secret+24) ^ XXH_readLE64(secret+32)) + seed;
3509 xxh_u64 const bitflip2 = (XXH_readLE64(secret+40) ^ XXH_readLE64(secret+48)) - seed;
3510 xxh_u64 const input_lo = XXH_readLE64(input) ^ bitflip1;
3511 xxh_u64 const input_hi = XXH_readLE64(input + len - 8) ^ bitflip2;
3512 xxh_u64 const acc = len
3513 + XXH_swap64(input_lo) + input_hi
3514 + XXH3_mul128_fold64(input_lo, input_hi);
3515 return XXH3_avalanche(acc);
3516 }
3517}
3518
3519XXH_FORCE_INLINE XXH64_hash_t
3520XXH3_len_0to16_64b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed)
3521{
3522 XXH_ASSERT(len <= 16);
3523 { if (XXH_likely(len > 8)) return XXH3_len_9to16_64b(input, len, secret, seed);
3524 if (XXH_likely(len >= 4)) return XXH3_len_4to8_64b(input, len, secret, seed);
3525 if (len) return XXH3_len_1to3_64b(input, len, secret, seed);
3526 return XXH64_avalanche(seed ^ (XXH_readLE64(secret+56) ^ XXH_readLE64(secret+64)));
3527 }
3528}
3529
3530/*
3531 * DISCLAIMER: There are known *seed-dependent* multicollisions here due to
3532 * multiplication by zero, affecting hashes of lengths 17 to 240.
3533 *
3534 * However, they are very unlikely.
3535 *
3536 * Keep this in mind when using the unseeded XXH3_64bits() variant: As with all
3537 * unseeded non-cryptographic hashes, it does not attempt to defend itself
3538 * against specially crafted inputs, only random inputs.
3539 *
3540 * Compared to classic UMAC where a 1 in 2^31 chance of 4 consecutive bytes
3541 * cancelling out the secret is taken an arbitrary number of times (addressed
3542 * in XXH3_accumulate_512), this collision is very unlikely with random inputs
3543 * and/or proper seeding:
3544 *
3545 * This only has a 1 in 2^63 chance of 8 consecutive bytes cancelling out, in a
3546 * function that is only called up to 16 times per hash with up to 240 bytes of
3547 * input.
3548 *
3549 * This is not too bad for a non-cryptographic hash function, especially with
3550 * only 64 bit outputs.
3551 *
3552 * The 128-bit variant (which trades some speed for strength) is NOT affected
3553 * by this, although it is always a good idea to use a proper seed if you care
3554 * about strength.
3555 */
3556XXH_FORCE_INLINE xxh_u64 XXH3_mix16B(const xxh_u8* XXH_RESTRICT input,
3557 const xxh_u8* XXH_RESTRICT secret, xxh_u64 seed64)
3558{
3559#if defined(__GNUC__) && !defined(__clang__) /* GCC, not Clang */ \
3560 && defined(__i386__) && defined(__SSE2__) /* x86 + SSE2 */ \
3561 && !defined(XXH_ENABLE_AUTOVECTORIZE) /* Define to disable like XXH32 hack */
3562 /*
3563 * UGLY HACK:
3564 * GCC for x86 tends to autovectorize the 128-bit multiply, resulting in
3565 * slower code.
3566 *
3567 * By forcing seed64 into a register, we disrupt the cost model and
3568 * cause it to scalarize. See `XXH32_round()`
3569 *
3570 * FIXME: Clang's output is still _much_ faster -- On an AMD Ryzen 3600,
3571 * XXH3_64bits @ len=240 runs at 4.6 GB/s with Clang 9, but 3.3 GB/s on
3572 * GCC 9.2, despite both emitting scalar code.
3573 *
3574 * GCC generates much better scalar code than Clang for the rest of XXH3,
3575 * which is why finding a more optimal codepath is an interest.
3576 */
3577 XXH_COMPILER_GUARD(seed64);
3578#endif
3579 { xxh_u64 const input_lo = XXH_readLE64(input);
3580 xxh_u64 const input_hi = XXH_readLE64(input+8);
3581 return XXH3_mul128_fold64(
3582 input_lo ^ (XXH_readLE64(secret) + seed64),
3583 input_hi ^ (XXH_readLE64(secret+8) - seed64)
3584 );
3585 }
3586}
3587
3588/* For mid range keys, XXH3 uses a Mum-hash variant. */
3589XXH_FORCE_INLINE XXH64_hash_t
3590XXH3_len_17to128_64b(const xxh_u8* XXH_RESTRICT input, size_t len,
3591 const xxh_u8* XXH_RESTRICT secret, size_t secretSize,
3592 XXH64_hash_t seed)
3593{
3594 XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN); (void)secretSize;
3595 XXH_ASSERT(16 < len && len <= 128);
3596
3597 { xxh_u64 acc = len * XXH_PRIME64_1;
3598 if (len > 32) {
3599 if (len > 64) {
3600 if (len > 96) {
3601 acc += XXH3_mix16B(input+48, secret+96, seed);
3602 acc += XXH3_mix16B(input+len-64, secret+112, seed);
3603 }
3604 acc += XXH3_mix16B(input+32, secret+64, seed);
3605 acc += XXH3_mix16B(input+len-48, secret+80, seed);
3606 }
3607 acc += XXH3_mix16B(input+16, secret+32, seed);
3608 acc += XXH3_mix16B(input+len-32, secret+48, seed);
3609 }
3610 acc += XXH3_mix16B(input+0, secret+0, seed);
3611 acc += XXH3_mix16B(input+len-16, secret+16, seed);
3612
3613 return XXH3_avalanche(acc);
3614 }
3615}
3616
3617#define XXH3_MIDSIZE_MAX 240
3618
3619XXH_NO_INLINE XXH64_hash_t
3620XXH3_len_129to240_64b(const xxh_u8* XXH_RESTRICT input, size_t len,
3621 const xxh_u8* XXH_RESTRICT secret, size_t secretSize,
3622 XXH64_hash_t seed)
3623{
3624 XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN); (void)secretSize;
3625 XXH_ASSERT(128 < len && len <= XXH3_MIDSIZE_MAX);
3626
3627 #define XXH3_MIDSIZE_STARTOFFSET 3
3628 #define XXH3_MIDSIZE_LASTOFFSET 17
3629
3630 { xxh_u64 acc = len * XXH_PRIME64_1;
3631 int const nbRounds = (int)len / 16;
3632 int i;
3633 for (i=0; i<8; i++) {
3634 acc += XXH3_mix16B(input+(16*i), secret+(16*i), seed);
3635 }
3636 acc = XXH3_avalanche(acc);
3637 XXH_ASSERT(nbRounds >= 8);
3638#if defined(__clang__) /* Clang */ \
3639 && (defined(__ARM_NEON) || defined(__ARM_NEON__)) /* NEON */ \
3640 && !defined(XXH_ENABLE_AUTOVECTORIZE) /* Define to disable */
3641 /*
3642 * UGLY HACK:
3643 * Clang for ARMv7-A tries to vectorize this loop, similar to GCC x86.
3644 * In everywhere else, it uses scalar code.
3645 *
3646 * For 64->128-bit multiplies, even if the NEON was 100% optimal, it
3647 * would still be slower than UMAAL (see XXH_mult64to128).
3648 *
3649 * Unfortunately, Clang doesn't handle the long multiplies properly and
3650 * converts them to the nonexistent "vmulq_u64" intrinsic, which is then
3651 * scalarized into an ugly mess of VMOV.32 instructions.
3652 *
3653 * This mess is difficult to avoid without turning autovectorization
3654 * off completely, but they are usually relatively minor and/or not
3655 * worth it to fix.
3656 *
3657 * This loop is the easiest to fix, as unlike XXH32, this pragma
3658 * _actually works_ because it is a loop vectorization instead of an
3659 * SLP vectorization.
3660 */
3661 #pragma clang loop vectorize(disable)
3662#endif
3663 for (i=8 ; i < nbRounds; i++) {
3664 acc += XXH3_mix16B(input+(16*i), secret+(16*(i-8)) + XXH3_MIDSIZE_STARTOFFSET, seed);
3665 }
3666 /* last bytes */
3667 acc += XXH3_mix16B(input + len - 16, secret + XXH3_SECRET_SIZE_MIN - XXH3_MIDSIZE_LASTOFFSET, seed);
3668 return XXH3_avalanche(acc);
3669 }
3670}
3671
3672
3673/* ======= Long Keys ======= */
3674
3675#define XXH_STRIPE_LEN 64
3676#define XXH_SECRET_CONSUME_RATE 8 /* nb of secret bytes consumed at each accumulation */
3677#define XXH_ACC_NB (XXH_STRIPE_LEN / sizeof(xxh_u64))
3678
3679#ifdef XXH_OLD_NAMES
3680# define STRIPE_LEN XXH_STRIPE_LEN
3681# define ACC_NB XXH_ACC_NB
3682#endif
3683
3684XXH_FORCE_INLINE void XXH_writeLE64(void* dst, xxh_u64 v64)
3685{
3686 if (!XXH_CPU_LITTLE_ENDIAN) v64 = XXH_swap64(v64);
3687 XXH_memcpy(dst, &v64, sizeof(v64));
3688}
3689
3690/* Several intrinsic functions below are supposed to accept __int64 as argument,
3691 * as documented in https://software.intel.com/sites/landingpage/IntrinsicsGuide/ .
3692 * However, several environments do not define __int64 type,
3693 * requiring a workaround.
3694 */
3695#if !defined (__VMS) \
3696 && (defined (__cplusplus) \
3697 || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) )
3698 typedef int64_t xxh_i64;
3699#else
3700 /* the following type must have a width of 64-bit */
3701 typedef long long xxh_i64;
3702#endif
3703
3704
3705/*
3706 * XXH3_accumulate_512 is the tightest loop for long inputs, and it is the most optimized.
3707 *
3708 * It is a hardened version of UMAC, based off of FARSH's implementation.
3709 *
3710 * This was chosen because it adapts quite well to 32-bit, 64-bit, and SIMD
3711 * implementations, and it is ridiculously fast.
3712 *
3713 * We harden it by mixing the original input to the accumulators as well as the product.
3714 *
3715 * This means that in the (relatively likely) case of a multiply by zero, the
3716 * original input is preserved.
3717 *
3718 * On 128-bit inputs, we swap 64-bit pairs when we add the input to improve
3719 * cross-pollination, as otherwise the upper and lower halves would be
3720 * essentially independent.
3721 *
3722 * This doesn't matter on 64-bit hashes since they all get merged together in
3723 * the end, so we skip the extra step.
3724 *
3725 * Both XXH3_64bits and XXH3_128bits use this subroutine.
3726 */
3727
3728#if (XXH_VECTOR == XXH_AVX512) \
3729 || (defined(XXH_DISPATCH_AVX512) && XXH_DISPATCH_AVX512 != 0)
3730
3731#ifndef XXH_TARGET_AVX512
3732# define XXH_TARGET_AVX512 /* disable attribute target */
3733#endif
3734
3735XXH_FORCE_INLINE XXH_TARGET_AVX512 void
3736XXH3_accumulate_512_avx512(void* XXH_RESTRICT acc,
3737 const void* XXH_RESTRICT input,
3738 const void* XXH_RESTRICT secret)
3739{
3740 __m512i* const xacc = (__m512i *) acc;
3741 XXH_ASSERT((((size_t)acc) & 63) == 0);
3742 XXH_STATIC_ASSERT(XXH_STRIPE_LEN == sizeof(__m512i));
3743
3744 {
3745 /* data_vec = input[0]; */
3746 __m512i const data_vec = _mm512_loadu_si512 (input);
3747 /* key_vec = secret[0]; */
3748 __m512i const key_vec = _mm512_loadu_si512 (secret);
3749 /* data_key = data_vec ^ key_vec; */
3750 __m512i const data_key = _mm512_xor_si512 (data_vec, key_vec);
3751 /* data_key_lo = data_key >> 32; */
3752 __m512i const data_key_lo = _mm512_shuffle_epi32 (data_key, (_MM_PERM_ENUM)_MM_SHUFFLE(0, 3, 0, 1));
3753 /* product = (data_key & 0xffffffff) * (data_key_lo & 0xffffffff); */
3754 __m512i const product = _mm512_mul_epu32 (data_key, data_key_lo);
3755 /* xacc[0] += swap(data_vec); */
3756 __m512i const data_swap = _mm512_shuffle_epi32(data_vec, (_MM_PERM_ENUM)_MM_SHUFFLE(1, 0, 3, 2));
3757 __m512i const sum = _mm512_add_epi64(*xacc, data_swap);
3758 /* xacc[0] += product; */
3759 *xacc = _mm512_add_epi64(product, sum);
3760 }
3761}
3762
3763/*
3764 * XXH3_scrambleAcc: Scrambles the accumulators to improve mixing.
3765 *
3766 * Multiplication isn't perfect, as explained by Google in HighwayHash:
3767 *
3768 * // Multiplication mixes/scrambles bytes 0-7 of the 64-bit result to
3769 * // varying degrees. In descending order of goodness, bytes
3770 * // 3 4 2 5 1 6 0 7 have quality 228 224 164 160 100 96 36 32.
3771 * // As expected, the upper and lower bytes are much worse.
3772 *
3773 * Source: https://github.com/google/highwayhash/blob/0aaf66b/highwayhash/hh_avx2.h#L291
3774 *
3775 * Since our algorithm uses a pseudorandom secret to add some variance into the
3776 * mix, we don't need to (or want to) mix as often or as much as HighwayHash does.
3777 *
3778 * This isn't as tight as XXH3_accumulate, but still written in SIMD to avoid
3779 * extraction.
3780 *
3781 * Both XXH3_64bits and XXH3_128bits use this subroutine.
3782 */
3783
3784XXH_FORCE_INLINE XXH_TARGET_AVX512 void
3785XXH3_scrambleAcc_avx512(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret)
3786{
3787 XXH_ASSERT((((size_t)acc) & 63) == 0);
3788 XXH_STATIC_ASSERT(XXH_STRIPE_LEN == sizeof(__m512i));
3789 { __m512i* const xacc = (__m512i*) acc;
3790 const __m512i prime32 = _mm512_set1_epi32((int)XXH_PRIME32_1);
3791
3792 /* xacc[0] ^= (xacc[0] >> 47) */
3793 __m512i const acc_vec = *xacc;
3794 __m512i const shifted = _mm512_srli_epi64 (acc_vec, 47);
3795 __m512i const data_vec = _mm512_xor_si512 (acc_vec, shifted);
3796 /* xacc[0] ^= secret; */
3797 __m512i const key_vec = _mm512_loadu_si512 (secret);
3798 __m512i const data_key = _mm512_xor_si512 (data_vec, key_vec);
3799
3800 /* xacc[0] *= XXH_PRIME32_1; */
3801 __m512i const data_key_hi = _mm512_shuffle_epi32 (data_key, (_MM_PERM_ENUM)_MM_SHUFFLE(0, 3, 0, 1));
3802 __m512i const prod_lo = _mm512_mul_epu32 (data_key, prime32);
3803 __m512i const prod_hi = _mm512_mul_epu32 (data_key_hi, prime32);
3804 *xacc = _mm512_add_epi64(prod_lo, _mm512_slli_epi64(prod_hi, 32));
3805 }
3806}
3807
3808XXH_FORCE_INLINE XXH_TARGET_AVX512 void
3809XXH3_initCustomSecret_avx512(void* XXH_RESTRICT customSecret, xxh_u64 seed64)
3810{
3811 XXH_STATIC_ASSERT((XXH_SECRET_DEFAULT_SIZE & 63) == 0);
3812 XXH_STATIC_ASSERT(XXH_SEC_ALIGN == 64);
3813 XXH_ASSERT(((size_t)customSecret & 63) == 0);
3814 (void)(&XXH_writeLE64);
3815 { int const nbRounds = XXH_SECRET_DEFAULT_SIZE / sizeof(__m512i);
3816 __m512i const seed = _mm512_mask_set1_epi64(_mm512_set1_epi64((xxh_i64)seed64), 0xAA, (xxh_i64)(0U - seed64));
3817
3818 const __m512i* const src = (const __m512i*) ((const void*) XXH3_kSecret);
3819 __m512i* const dest = ( __m512i*) customSecret;
3820 int i;
3821 XXH_ASSERT(((size_t)src & 63) == 0); /* control alignment */
3822 XXH_ASSERT(((size_t)dest & 63) == 0);
3823 for (i=0; i < nbRounds; ++i) {
3824 /* GCC has a bug, _mm512_stream_load_si512 accepts 'void*', not 'void const*',
3825 * this will warn "discards 'const' qualifier". */
3826 union {
3827 const __m512i* cp;
3828 void* p;
3829 } remote_const_void;
3830 remote_const_void.cp = src + i;
3831 dest[i] = _mm512_add_epi64(_mm512_stream_load_si512(remote_const_void.p), seed);
3832 } }
3833}
3834
3835#endif
3836
3837#if (XXH_VECTOR == XXH_AVX2) \
3838 || (defined(XXH_DISPATCH_AVX2) && XXH_DISPATCH_AVX2 != 0)
3839
3840#ifndef XXH_TARGET_AVX2
3841# define XXH_TARGET_AVX2 /* disable attribute target */
3842#endif
3843
3844XXH_FORCE_INLINE XXH_TARGET_AVX2 void
3845XXH3_accumulate_512_avx2( void* XXH_RESTRICT acc,
3846 const void* XXH_RESTRICT input,
3847 const void* XXH_RESTRICT secret)
3848{
3849 XXH_ASSERT((((size_t)acc) & 31) == 0);
3850 { __m256i* const xacc = (__m256i *) acc;
3851 /* Unaligned. This is mainly for pointer arithmetic, and because
3852 * _mm256_loadu_si256 requires a const __m256i * pointer for some reason. */
3853 const __m256i* const xinput = (const __m256i *) input;
3854 /* Unaligned. This is mainly for pointer arithmetic, and because
3855 * _mm256_loadu_si256 requires a const __m256i * pointer for some reason. */
3856 const __m256i* const xsecret = (const __m256i *) secret;
3857
3858 size_t i;
3859 for (i=0; i < XXH_STRIPE_LEN/sizeof(__m256i); i++) {
3860 /* data_vec = xinput[i]; */
3861 __m256i const data_vec = _mm256_loadu_si256 (xinput+i);
3862 /* key_vec = xsecret[i]; */
3863 __m256i const key_vec = _mm256_loadu_si256 (xsecret+i);
3864 /* data_key = data_vec ^ key_vec; */
3865 __m256i const data_key = _mm256_xor_si256 (data_vec, key_vec);
3866 /* data_key_lo = data_key >> 32; */
3867 __m256i const data_key_lo = _mm256_shuffle_epi32 (data_key, _MM_SHUFFLE(0, 3, 0, 1));
3868 /* product = (data_key & 0xffffffff) * (data_key_lo & 0xffffffff); */
3869 __m256i const product = _mm256_mul_epu32 (data_key, data_key_lo);
3870 /* xacc[i] += swap(data_vec); */
3871 __m256i const data_swap = _mm256_shuffle_epi32(data_vec, _MM_SHUFFLE(1, 0, 3, 2));
3872 __m256i const sum = _mm256_add_epi64(xacc[i], data_swap);
3873 /* xacc[i] += product; */
3874 xacc[i] = _mm256_add_epi64(product, sum);
3875 } }
3876}
3877
3878XXH_FORCE_INLINE XXH_TARGET_AVX2 void
3879XXH3_scrambleAcc_avx2(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret)
3880{
3881 XXH_ASSERT((((size_t)acc) & 31) == 0);
3882 { __m256i* const xacc = (__m256i*) acc;
3883 /* Unaligned. This is mainly for pointer arithmetic, and because
3884 * _mm256_loadu_si256 requires a const __m256i * pointer for some reason. */
3885 const __m256i* const xsecret = (const __m256i *) secret;
3886 const __m256i prime32 = _mm256_set1_epi32((int)XXH_PRIME32_1);
3887
3888 size_t i;
3889 for (i=0; i < XXH_STRIPE_LEN/sizeof(__m256i); i++) {
3890 /* xacc[i] ^= (xacc[i] >> 47) */
3891 __m256i const acc_vec = xacc[i];
3892 __m256i const shifted = _mm256_srli_epi64 (acc_vec, 47);
3893 __m256i const data_vec = _mm256_xor_si256 (acc_vec, shifted);
3894 /* xacc[i] ^= xsecret; */
3895 __m256i const key_vec = _mm256_loadu_si256 (xsecret+i);
3896 __m256i const data_key = _mm256_xor_si256 (data_vec, key_vec);
3897
3898 /* xacc[i] *= XXH_PRIME32_1; */
3899 __m256i const data_key_hi = _mm256_shuffle_epi32 (data_key, _MM_SHUFFLE(0, 3, 0, 1));
3900 __m256i const prod_lo = _mm256_mul_epu32 (data_key, prime32);
3901 __m256i const prod_hi = _mm256_mul_epu32 (data_key_hi, prime32);
3902 xacc[i] = _mm256_add_epi64(prod_lo, _mm256_slli_epi64(prod_hi, 32));
3903 }
3904 }
3905}
3906
3907XXH_FORCE_INLINE XXH_TARGET_AVX2 void XXH3_initCustomSecret_avx2(void* XXH_RESTRICT customSecret, xxh_u64 seed64)
3908{
3909 XXH_STATIC_ASSERT((XXH_SECRET_DEFAULT_SIZE & 31) == 0);
3910 XXH_STATIC_ASSERT((XXH_SECRET_DEFAULT_SIZE / sizeof(__m256i)) == 6);
3911 XXH_STATIC_ASSERT(XXH_SEC_ALIGN <= 64);
3912 (void)(&XXH_writeLE64);
3913 XXH_PREFETCH(customSecret);
3914 { __m256i const seed = _mm256_set_epi64x((xxh_i64)(0U - seed64), (xxh_i64)seed64, (xxh_i64)(0U - seed64), (xxh_i64)seed64);
3915
3916 const __m256i* const src = (const __m256i*) ((const void*) XXH3_kSecret);
3917 __m256i* dest = ( __m256i*) customSecret;
3918
3919# if defined(__GNUC__) || defined(__clang__)
3920 /*
3921 * On GCC & Clang, marking 'dest' as modified will cause the compiler:
3922 * - do not extract the secret from sse registers in the internal loop
3923 * - use less common registers, and avoid pushing these reg into stack
3924 */
3925 XXH_COMPILER_GUARD(dest);
3926# endif
3927 XXH_ASSERT(((size_t)src & 31) == 0); /* control alignment */
3928 XXH_ASSERT(((size_t)dest & 31) == 0);
3929
3930 /* GCC -O2 need unroll loop manually */
3931 dest[0] = _mm256_add_epi64(_mm256_stream_load_si256(src+0), seed);
3932 dest[1] = _mm256_add_epi64(_mm256_stream_load_si256(src+1), seed);
3933 dest[2] = _mm256_add_epi64(_mm256_stream_load_si256(src+2), seed);
3934 dest[3] = _mm256_add_epi64(_mm256_stream_load_si256(src+3), seed);
3935 dest[4] = _mm256_add_epi64(_mm256_stream_load_si256(src+4), seed);
3936 dest[5] = _mm256_add_epi64(_mm256_stream_load_si256(src+5), seed);
3937 }
3938}
3939
3940#endif
3941
3942/* x86dispatch always generates SSE2 */
3943#if (XXH_VECTOR == XXH_SSE2) || defined(XXH_X86DISPATCH)
3944
3945#ifndef XXH_TARGET_SSE2
3946# define XXH_TARGET_SSE2 /* disable attribute target */
3947#endif
3948
3949XXH_FORCE_INLINE XXH_TARGET_SSE2 void
3950XXH3_accumulate_512_sse2( void* XXH_RESTRICT acc,
3951 const void* XXH_RESTRICT input,
3952 const void* XXH_RESTRICT secret)
3953{
3954 /* SSE2 is just a half-scale version of the AVX2 version. */
3955 XXH_ASSERT((((size_t)acc) & 15) == 0);
3956 { __m128i* const xacc = (__m128i *) acc;
3957 /* Unaligned. This is mainly for pointer arithmetic, and because
3958 * _mm_loadu_si128 requires a const __m128i * pointer for some reason. */
3959 const __m128i* const xinput = (const __m128i *) input;
3960 /* Unaligned. This is mainly for pointer arithmetic, and because
3961 * _mm_loadu_si128 requires a const __m128i * pointer for some reason. */
3962 const __m128i* const xsecret = (const __m128i *) secret;
3963
3964 size_t i;
3965 for (i=0; i < XXH_STRIPE_LEN/sizeof(__m128i); i++) {
3966 /* data_vec = xinput[i]; */
3967 __m128i const data_vec = _mm_loadu_si128 (xinput+i);
3968 /* key_vec = xsecret[i]; */
3969 __m128i const key_vec = _mm_loadu_si128 (xsecret+i);
3970 /* data_key = data_vec ^ key_vec; */
3971 __m128i const data_key = _mm_xor_si128 (data_vec, key_vec);
3972 /* data_key_lo = data_key >> 32; */
3973 __m128i const data_key_lo = _mm_shuffle_epi32 (data_key, _MM_SHUFFLE(0, 3, 0, 1));
3974 /* product = (data_key & 0xffffffff) * (data_key_lo & 0xffffffff); */
3975 __m128i const product = _mm_mul_epu32 (data_key, data_key_lo);
3976 /* xacc[i] += swap(data_vec); */
3977 __m128i const data_swap = _mm_shuffle_epi32(data_vec, _MM_SHUFFLE(1,0,3,2));
3978 __m128i const sum = _mm_add_epi64(xacc[i], data_swap);
3979 /* xacc[i] += product; */
3980 xacc[i] = _mm_add_epi64(product, sum);
3981 } }
3982}
3983
3984XXH_FORCE_INLINE XXH_TARGET_SSE2 void
3985XXH3_scrambleAcc_sse2(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret)
3986{
3987 XXH_ASSERT((((size_t)acc) & 15) == 0);
3988 { __m128i* const xacc = (__m128i*) acc;
3989 /* Unaligned. This is mainly for pointer arithmetic, and because
3990 * _mm_loadu_si128 requires a const __m128i * pointer for some reason. */
3991 const __m128i* const xsecret = (const __m128i *) secret;
3992 const __m128i prime32 = _mm_set1_epi32((int)XXH_PRIME32_1);
3993
3994 size_t i;
3995 for (i=0; i < XXH_STRIPE_LEN/sizeof(__m128i); i++) {
3996 /* xacc[i] ^= (xacc[i] >> 47) */
3997 __m128i const acc_vec = xacc[i];
3998 __m128i const shifted = _mm_srli_epi64 (acc_vec, 47);
3999 __m128i const data_vec = _mm_xor_si128 (acc_vec, shifted);
4000 /* xacc[i] ^= xsecret[i]; */
4001 __m128i const key_vec = _mm_loadu_si128 (xsecret+i);
4002 __m128i const data_key = _mm_xor_si128 (data_vec, key_vec);
4003
4004 /* xacc[i] *= XXH_PRIME32_1; */
4005 __m128i const data_key_hi = _mm_shuffle_epi32 (data_key, _MM_SHUFFLE(0, 3, 0, 1));
4006 __m128i const prod_lo = _mm_mul_epu32 (data_key, prime32);
4007 __m128i const prod_hi = _mm_mul_epu32 (data_key_hi, prime32);
4008 xacc[i] = _mm_add_epi64(prod_lo, _mm_slli_epi64(prod_hi, 32));
4009 }
4010 }
4011}
4012
4013XXH_FORCE_INLINE XXH_TARGET_SSE2 void XXH3_initCustomSecret_sse2(void* XXH_RESTRICT customSecret, xxh_u64 seed64)
4014{
4015 XXH_STATIC_ASSERT((XXH_SECRET_DEFAULT_SIZE & 15) == 0);
4016 (void)(&XXH_writeLE64);
4017 { int const nbRounds = XXH_SECRET_DEFAULT_SIZE / sizeof(__m128i);
4018
4019# if defined(_MSC_VER) && defined(_M_IX86) && _MSC_VER < 1900
4020 /* MSVC 32bit mode does not support _mm_set_epi64x before 2015 */
4021 XXH_ALIGN(16) const xxh_i64 seed64x2[2] = { (xxh_i64)seed64, (xxh_i64)(0U - seed64) };
4022 __m128i const seed = _mm_load_si128((__m128i const*)seed64x2);
4023# else
4024 __m128i const seed = _mm_set_epi64x((xxh_i64)(0U - seed64), (xxh_i64)seed64);
4025# endif
4026 int i;
4027
4028 const void* const src16 = XXH3_kSecret;
4029 __m128i* dst16 = (__m128i*) customSecret;
4030# if defined(__GNUC__) || defined(__clang__)
4031 /*
4032 * On GCC & Clang, marking 'dest' as modified will cause the compiler:
4033 * - do not extract the secret from sse registers in the internal loop
4034 * - use less common registers, and avoid pushing these reg into stack
4035 */
4036 XXH_COMPILER_GUARD(dst16);
4037# endif
4038 XXH_ASSERT(((size_t)src16 & 15) == 0); /* control alignment */
4039 XXH_ASSERT(((size_t)dst16 & 15) == 0);
4040
4041 for (i=0; i < nbRounds; ++i) {
4042 dst16[i] = _mm_add_epi64(_mm_load_si128((const __m128i *)src16+i), seed);
4043 } }
4044}
4045
4046#endif
4047
4048#if (XXH_VECTOR == XXH_NEON)
4049
4050/* forward declarations for the scalar routines */
4051XXH_FORCE_INLINE void
4052XXH3_scalarRound(void* XXH_RESTRICT acc, void const* XXH_RESTRICT input,
4053 void const* XXH_RESTRICT secret, size_t lane);
4054
4055XXH_FORCE_INLINE void
4056XXH3_scalarScrambleRound(void* XXH_RESTRICT acc,
4057 void const* XXH_RESTRICT secret, size_t lane);
4058
4059/*!
4060 * @internal
4061 * @brief The bulk processing loop for NEON.
4062 *
4063 * The NEON code path is actually partially scalar when running on AArch64. This
4064 * is to optimize the pipelining and can have up to 15% speedup depending on the
4065 * CPU, and it also mitigates some GCC codegen issues.
4066 *
4067 * @see XXH3_NEON_LANES for configuring this and details about this optimization.
4068 */
4069XXH_FORCE_INLINE void
4070XXH3_accumulate_512_neon( void* XXH_RESTRICT acc,
4071 const void* XXH_RESTRICT input,
4072 const void* XXH_RESTRICT secret)
4073{
4074 XXH_ASSERT((((size_t)acc) & 15) == 0);
4075 XXH_STATIC_ASSERT(XXH3_NEON_LANES > 0 && XXH3_NEON_LANES <= XXH_ACC_NB && XXH3_NEON_LANES % 2 == 0);
4076 {
4077 uint64x2_t* const xacc = (uint64x2_t *) acc;
4078 /* We don't use a uint32x4_t pointer because it causes bus errors on ARMv7. */
4079 uint8_t const* const xinput = (const uint8_t *) input;
4080 uint8_t const* const xsecret = (const uint8_t *) secret;
4081
4082 size_t i;
4083 /* NEON for the first few lanes (these loops are normally interleaved) */
4084 for (i=0; i < XXH3_NEON_LANES / 2; i++) {
4085 /* data_vec = xinput[i]; */
4086 uint8x16_t data_vec = vld1q_u8(xinput + (i * 16));
4087 /* key_vec = xsecret[i]; */
4088 uint8x16_t key_vec = vld1q_u8(xsecret + (i * 16));
4089 uint64x2_t data_key;
4090 uint32x2_t data_key_lo, data_key_hi;
4091 /* xacc[i] += swap(data_vec); */
4092 uint64x2_t const data64 = vreinterpretq_u64_u8(data_vec);
4093 uint64x2_t const swapped = vextq_u64(data64, data64, 1);
4094 xacc[i] = vaddq_u64 (xacc[i], swapped);
4095 /* data_key = data_vec ^ key_vec; */
4096 data_key = vreinterpretq_u64_u8(veorq_u8(data_vec, key_vec));
4097 /* data_key_lo = (uint32x2_t) (data_key & 0xFFFFFFFF);
4098 * data_key_hi = (uint32x2_t) (data_key >> 32);
4099 * data_key = UNDEFINED; */
4100 XXH_SPLIT_IN_PLACE(data_key, data_key_lo, data_key_hi);
4101 /* xacc[i] += (uint64x2_t) data_key_lo * (uint64x2_t) data_key_hi; */
4102 xacc[i] = vmlal_u32 (xacc[i], data_key_lo, data_key_hi);
4103
4104 }
4105 /* Scalar for the remainder. This may be a zero iteration loop. */
4106 for (i = XXH3_NEON_LANES; i < XXH_ACC_NB; i++) {
4107 XXH3_scalarRound(acc, input, secret, i);
4108 }
4109 }
4110}
4111
4112XXH_FORCE_INLINE void
4113XXH3_scrambleAcc_neon(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret)
4114{
4115 XXH_ASSERT((((size_t)acc) & 15) == 0);
4116
4117 { uint64x2_t* xacc = (uint64x2_t*) acc;
4118 uint8_t const* xsecret = (uint8_t const*) secret;
4119 uint32x2_t prime = vdup_n_u32 (XXH_PRIME32_1);
4120
4121 size_t i;
4122 /* NEON for the first few lanes (these loops are normally interleaved) */
4123 for (i=0; i < XXH3_NEON_LANES / 2; i++) {
4124 /* xacc[i] ^= (xacc[i] >> 47); */
4125 uint64x2_t acc_vec = xacc[i];
4126 uint64x2_t shifted = vshrq_n_u64 (acc_vec, 47);
4127 uint64x2_t data_vec = veorq_u64 (acc_vec, shifted);
4128
4129 /* xacc[i] ^= xsecret[i]; */
4130 uint8x16_t key_vec = vld1q_u8 (xsecret + (i * 16));
4131 uint64x2_t data_key = veorq_u64 (data_vec, vreinterpretq_u64_u8(key_vec));
4132
4133 /* xacc[i] *= XXH_PRIME32_1 */
4134 uint32x2_t data_key_lo, data_key_hi;
4135 /* data_key_lo = (uint32x2_t) (xacc[i] & 0xFFFFFFFF);
4136 * data_key_hi = (uint32x2_t) (xacc[i] >> 32);
4137 * xacc[i] = UNDEFINED; */
4138 XXH_SPLIT_IN_PLACE(data_key, data_key_lo, data_key_hi);
4139 { /*
4140 * prod_hi = (data_key >> 32) * XXH_PRIME32_1;
4141 *
4142 * Avoid vmul_u32 + vshll_n_u32 since Clang 6 and 7 will
4143 * incorrectly "optimize" this:
4144 * tmp = vmul_u32(vmovn_u64(a), vmovn_u64(b));
4145 * shifted = vshll_n_u32(tmp, 32);
4146 * to this:
4147 * tmp = "vmulq_u64"(a, b); // no such thing!
4148 * shifted = vshlq_n_u64(tmp, 32);
4149 *
4150 * However, unlike SSE, Clang lacks a 64-bit multiply routine
4151 * for NEON, and it scalarizes two 64-bit multiplies instead.
4152 *
4153 * vmull_u32 has the same timing as vmul_u32, and it avoids
4154 * this bug completely.
4155 * See https://bugs.llvm.org/show_bug.cgi?id=39967
4156 */
4157 uint64x2_t prod_hi = vmull_u32 (data_key_hi, prime);
4158 /* xacc[i] = prod_hi << 32; */
4159 xacc[i] = vshlq_n_u64(prod_hi, 32);
4160 /* xacc[i] += (prod_hi & 0xFFFFFFFF) * XXH_PRIME32_1; */
4161 xacc[i] = vmlal_u32(xacc[i], data_key_lo, prime);
4162 }
4163 }
4164 /* Scalar for the remainder. This may be a zero iteration loop. */
4165 for (i = XXH3_NEON_LANES; i < XXH_ACC_NB; i++) {
4166 XXH3_scalarScrambleRound(acc, secret, i);
4167 }
4168 }
4169}
4170
4171#endif
4172
4173#if (XXH_VECTOR == XXH_VSX)
4174
4175XXH_FORCE_INLINE void
4176XXH3_accumulate_512_vsx( void* XXH_RESTRICT acc,
4177 const void* XXH_RESTRICT input,
4178 const void* XXH_RESTRICT secret)
4179{
4180 /* presumed aligned */
4181 unsigned int* const xacc = (unsigned int*) acc;
4182 xxh_u64x2 const* const xinput = (xxh_u64x2 const*) input; /* no alignment restriction */
4183 xxh_u64x2 const* const xsecret = (xxh_u64x2 const*) secret; /* no alignment restriction */
4184 xxh_u64x2 const v32 = { 32, 32 };
4185 size_t i;
4186 for (i = 0; i < XXH_STRIPE_LEN / sizeof(xxh_u64x2); i++) {
4187 /* data_vec = xinput[i]; */
4188 xxh_u64x2 const data_vec = XXH_vec_loadu(xinput + i);
4189 /* key_vec = xsecret[i]; */
4190 xxh_u64x2 const key_vec = XXH_vec_loadu(xsecret + i);
4191 xxh_u64x2 const data_key = data_vec ^ key_vec;
4192 /* shuffled = (data_key << 32) | (data_key >> 32); */
4193 xxh_u32x4 const shuffled = (xxh_u32x4)vec_rl(data_key, v32);
4194 /* product = ((xxh_u64x2)data_key & 0xFFFFFFFF) * ((xxh_u64x2)shuffled & 0xFFFFFFFF); */
4195 xxh_u64x2 const product = XXH_vec_mulo((xxh_u32x4)data_key, shuffled);
4196 /* acc_vec = xacc[i]; */
4197 xxh_u64x2 acc_vec = (xxh_u64x2)vec_xl(0, xacc + 4 * i);
4198 acc_vec += product;
4199
4200 /* swap high and low halves */
4201#ifdef __s390x__
4202 acc_vec += vec_permi(data_vec, data_vec, 2);
4203#else
4204 acc_vec += vec_xxpermdi(data_vec, data_vec, 2);
4205#endif
4206 /* xacc[i] = acc_vec; */
4207 vec_xst((xxh_u32x4)acc_vec, 0, xacc + 4 * i);
4208 }
4209}
4210
4211XXH_FORCE_INLINE void
4212XXH3_scrambleAcc_vsx(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret)
4213{
4214 XXH_ASSERT((((size_t)acc) & 15) == 0);
4215
4216 { xxh_u64x2* const xacc = (xxh_u64x2*) acc;
4217 const xxh_u64x2* const xsecret = (const xxh_u64x2*) secret;
4218 /* constants */
4219 xxh_u64x2 const v32 = { 32, 32 };
4220 xxh_u64x2 const v47 = { 47, 47 };
4221 xxh_u32x4 const prime = { XXH_PRIME32_1, XXH_PRIME32_1, XXH_PRIME32_1, XXH_PRIME32_1 };
4222 size_t i;
4223 for (i = 0; i < XXH_STRIPE_LEN / sizeof(xxh_u64x2); i++) {
4224 /* xacc[i] ^= (xacc[i] >> 47); */
4225 xxh_u64x2 const acc_vec = xacc[i];
4226 xxh_u64x2 const data_vec = acc_vec ^ (acc_vec >> v47);
4227
4228 /* xacc[i] ^= xsecret[i]; */
4229 xxh_u64x2 const key_vec = XXH_vec_loadu(xsecret + i);
4230 xxh_u64x2 const data_key = data_vec ^ key_vec;
4231
4232 /* xacc[i] *= XXH_PRIME32_1 */
4233 /* prod_lo = ((xxh_u64x2)data_key & 0xFFFFFFFF) * ((xxh_u64x2)prime & 0xFFFFFFFF); */
4234 xxh_u64x2 const prod_even = XXH_vec_mule((xxh_u32x4)data_key, prime);
4235 /* prod_hi = ((xxh_u64x2)data_key >> 32) * ((xxh_u64x2)prime >> 32); */
4236 xxh_u64x2 const prod_odd = XXH_vec_mulo((xxh_u32x4)data_key, prime);
4237 xacc[i] = prod_odd + (prod_even << v32);
4238 } }
4239}
4240
4241#endif
4242
4243/* scalar variants - universal */
4244
4245/*!
4246 * @internal
4247 * @brief Scalar round for @ref XXH3_accumulate_512_scalar().
4248 *
4249 * This is extracted to its own function because the NEON path uses a combination
4250 * of NEON and scalar.
4251 */
4252XXH_FORCE_INLINE void
4253XXH3_scalarRound(void* XXH_RESTRICT acc,
4254 void const* XXH_RESTRICT input,
4255 void const* XXH_RESTRICT secret,
4256 size_t lane)
4257{
4258 xxh_u64* xacc = (xxh_u64*) acc;
4259 xxh_u8 const* xinput = (xxh_u8 const*) input;
4260 xxh_u8 const* xsecret = (xxh_u8 const*) secret;
4261 XXH_ASSERT(lane < XXH_ACC_NB);
4262 XXH_ASSERT(((size_t)acc & (XXH_ACC_ALIGN-1)) == 0);
4263 {
4264 xxh_u64 const data_val = XXH_readLE64(xinput + lane * 8);
4265 xxh_u64 const data_key = data_val ^ XXH_readLE64(xsecret + lane * 8);
4266 xacc[lane ^ 1] += data_val; /* swap adjacent lanes */
4267 xacc[lane] += XXH_mult32to64(data_key & 0xFFFFFFFF, data_key >> 32);
4268 }
4269}
4270
4271/*!
4272 * @internal
4273 * @brief Processes a 64 byte block of data using the scalar path.
4274 */
4275XXH_FORCE_INLINE void
4276XXH3_accumulate_512_scalar(void* XXH_RESTRICT acc,
4277 const void* XXH_RESTRICT input,
4278 const void* XXH_RESTRICT secret)
4279{
4280 size_t i;
4281 for (i=0; i < XXH_ACC_NB; i++) {
4282 XXH3_scalarRound(acc, input, secret, i);
4283 }
4284}
4285
4286/*!
4287 * @internal
4288 * @brief Scalar scramble step for @ref XXH3_scrambleAcc_scalar().
4289 *
4290 * This is extracted to its own function because the NEON path uses a combination
4291 * of NEON and scalar.
4292 */
4293XXH_FORCE_INLINE void
4294XXH3_scalarScrambleRound(void* XXH_RESTRICT acc,
4295 void const* XXH_RESTRICT secret,
4296 size_t lane)
4297{
4298 xxh_u64* const xacc = (xxh_u64*) acc; /* presumed aligned */
4299 const xxh_u8* const xsecret = (const xxh_u8*) secret; /* no alignment restriction */
4300 XXH_ASSERT((((size_t)acc) & (XXH_ACC_ALIGN-1)) == 0);
4301 XXH_ASSERT(lane < XXH_ACC_NB);
4302 {
4303 xxh_u64 const key64 = XXH_readLE64(xsecret + lane * 8);
4304 xxh_u64 acc64 = xacc[lane];
4305 acc64 = XXH_xorshift64(acc64, 47);
4306 acc64 ^= key64;
4307 acc64 *= XXH_PRIME32_1;
4308 xacc[lane] = acc64;
4309 }
4310}
4311
4312/*!
4313 * @internal
4314 * @brief Scrambles the accumulators after a large chunk has been read
4315 */
4316XXH_FORCE_INLINE void
4317XXH3_scrambleAcc_scalar(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret)
4318{
4319 size_t i;
4320 for (i=0; i < XXH_ACC_NB; i++) {
4321 XXH3_scalarScrambleRound(acc, secret, i);
4322 }
4323}
4324
4325XXH_FORCE_INLINE void
4326XXH3_initCustomSecret_scalar(void* XXH_RESTRICT customSecret, xxh_u64 seed64)
4327{
4328 /*
4329 * We need a separate pointer for the hack below,
4330 * which requires a non-const pointer.
4331 * Any decent compiler will optimize this out otherwise.
4332 */
4333 const xxh_u8* kSecretPtr = XXH3_kSecret;
4334 XXH_STATIC_ASSERT((XXH_SECRET_DEFAULT_SIZE & 15) == 0);
4335
4336#if defined(__clang__) && defined(__aarch64__)
4337 /*
4338 * UGLY HACK:
4339 * Clang generates a bunch of MOV/MOVK pairs for aarch64, and they are
4340 * placed sequentially, in order, at the top of the unrolled loop.
4341 *
4342 * While MOVK is great for generating constants (2 cycles for a 64-bit
4343 * constant compared to 4 cycles for LDR), it fights for bandwidth with
4344 * the arithmetic instructions.
4345 *
4346 * I L S
4347 * MOVK
4348 * MOVK
4349 * MOVK
4350 * MOVK
4351 * ADD
4352 * SUB STR
4353 * STR
4354 * By forcing loads from memory (as the asm line causes Clang to assume
4355 * that XXH3_kSecretPtr has been changed), the pipelines are used more
4356 * efficiently:
4357 * I L S
4358 * LDR
4359 * ADD LDR
4360 * SUB STR
4361 * STR
4362 *
4363 * See XXH3_NEON_LANES for details on the pipsline.
4364 *
4365 * XXH3_64bits_withSeed, len == 256, Snapdragon 835
4366 * without hack: 2654.4 MB/s
4367 * with hack: 3202.9 MB/s
4368 */
4369 XXH_COMPILER_GUARD(kSecretPtr);
4370#endif
4371 /*
4372 * Note: in debug mode, this overrides the asm optimization
4373 * and Clang will emit MOVK chains again.
4374 */
4375 XXH_ASSERT(kSecretPtr == XXH3_kSecret);
4376
4377 { int const nbRounds = XXH_SECRET_DEFAULT_SIZE / 16;
4378 int i;
4379 for (i=0; i < nbRounds; i++) {
4380 /*
4381 * The asm hack causes Clang to assume that kSecretPtr aliases with
4382 * customSecret, and on aarch64, this prevented LDP from merging two
4383 * loads together for free. Putting the loads together before the stores
4384 * properly generates LDP.
4385 */
4386 xxh_u64 lo = XXH_readLE64(kSecretPtr + 16*i) + seed64;
4387 xxh_u64 hi = XXH_readLE64(kSecretPtr + 16*i + 8) - seed64;
4388 XXH_writeLE64((xxh_u8*)customSecret + 16*i, lo);
4389 XXH_writeLE64((xxh_u8*)customSecret + 16*i + 8, hi);
4390 } }
4391}
4392
4393
4394typedef void (*XXH3_f_accumulate_512)(void* XXH_RESTRICT, const void*, const void*);
4395typedef void (*XXH3_f_scrambleAcc)(void* XXH_RESTRICT, const void*);
4396typedef void (*XXH3_f_initCustomSecret)(void* XXH_RESTRICT, xxh_u64);
4397
4398
4399#if (XXH_VECTOR == XXH_AVX512)
4400
4401#define XXH3_accumulate_512 XXH3_accumulate_512_avx512
4402#define XXH3_scrambleAcc XXH3_scrambleAcc_avx512
4403#define XXH3_initCustomSecret XXH3_initCustomSecret_avx512
4404
4405#elif (XXH_VECTOR == XXH_AVX2)
4406
4407#define XXH3_accumulate_512 XXH3_accumulate_512_avx2
4408#define XXH3_scrambleAcc XXH3_scrambleAcc_avx2
4409#define XXH3_initCustomSecret XXH3_initCustomSecret_avx2
4410
4411#elif (XXH_VECTOR == XXH_SSE2)
4412
4413#define XXH3_accumulate_512 XXH3_accumulate_512_sse2
4414#define XXH3_scrambleAcc XXH3_scrambleAcc_sse2
4415#define XXH3_initCustomSecret XXH3_initCustomSecret_sse2
4416
4417#elif (XXH_VECTOR == XXH_NEON)
4418
4419#define XXH3_accumulate_512 XXH3_accumulate_512_neon
4420#define XXH3_scrambleAcc XXH3_scrambleAcc_neon
4421#define XXH3_initCustomSecret XXH3_initCustomSecret_scalar
4422
4423#elif (XXH_VECTOR == XXH_VSX)
4424
4425#define XXH3_accumulate_512 XXH3_accumulate_512_vsx
4426#define XXH3_scrambleAcc XXH3_scrambleAcc_vsx
4427#define XXH3_initCustomSecret XXH3_initCustomSecret_scalar
4428
4429#else /* scalar */
4430
4431#define XXH3_accumulate_512 XXH3_accumulate_512_scalar
4432#define XXH3_scrambleAcc XXH3_scrambleAcc_scalar
4433#define XXH3_initCustomSecret XXH3_initCustomSecret_scalar
4434
4435#endif
4436
4437
4438
4439#ifndef XXH_PREFETCH_DIST
4440# ifdef __clang__
4441# define XXH_PREFETCH_DIST 320
4442# else
4443# if (XXH_VECTOR == XXH_AVX512)
4444# define XXH_PREFETCH_DIST 512
4445# else
4446# define XXH_PREFETCH_DIST 384
4447# endif
4448# endif /* __clang__ */
4449#endif /* XXH_PREFETCH_DIST */
4450
4451/*
4452 * XXH3_accumulate()
4453 * Loops over XXH3_accumulate_512().
4454 * Assumption: nbStripes will not overflow the secret size
4455 */
4456XXH_FORCE_INLINE void
4457XXH3_accumulate( xxh_u64* XXH_RESTRICT acc,
4458 const xxh_u8* XXH_RESTRICT input,
4459 const xxh_u8* XXH_RESTRICT secret,
4460 size_t nbStripes,
4461 XXH3_f_accumulate_512 f_acc512)
4462{
4463 size_t n;
4464 for (n = 0; n < nbStripes; n++ ) {
4465 const xxh_u8* const in = input + n*XXH_STRIPE_LEN;
4466 XXH_PREFETCH(in + XXH_PREFETCH_DIST);
4467 f_acc512(acc,
4468 in,
4469 secret + n*XXH_SECRET_CONSUME_RATE);
4470 }
4471}
4472
4473XXH_FORCE_INLINE void
4474XXH3_hashLong_internal_loop(xxh_u64* XXH_RESTRICT acc,
4475 const xxh_u8* XXH_RESTRICT input, size_t len,
4476 const xxh_u8* XXH_RESTRICT secret, size_t secretSize,
4477 XXH3_f_accumulate_512 f_acc512,
4478 XXH3_f_scrambleAcc f_scramble)
4479{
4480 size_t const nbStripesPerBlock = (secretSize - XXH_STRIPE_LEN) / XXH_SECRET_CONSUME_RATE;
4481 size_t const block_len = XXH_STRIPE_LEN * nbStripesPerBlock;
4482 size_t const nb_blocks = (len - 1) / block_len;
4483
4484 size_t n;
4485
4486 XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN);
4487
4488 for (n = 0; n < nb_blocks; n++) {
4489 XXH3_accumulate(acc, input + n*block_len, secret, nbStripesPerBlock, f_acc512);
4490 f_scramble(acc, secret + secretSize - XXH_STRIPE_LEN);
4491 }
4492
4493 /* last partial block */
4494 XXH_ASSERT(len > XXH_STRIPE_LEN);
4495 { size_t const nbStripes = ((len - 1) - (block_len * nb_blocks)) / XXH_STRIPE_LEN;
4496 XXH_ASSERT(nbStripes <= (secretSize / XXH_SECRET_CONSUME_RATE));
4497 XXH3_accumulate(acc, input + nb_blocks*block_len, secret, nbStripes, f_acc512);
4498
4499 /* last stripe */
4500 { const xxh_u8* const p = input + len - XXH_STRIPE_LEN;
4501#define XXH_SECRET_LASTACC_START 7 /* not aligned on 8, last secret is different from acc & scrambler */
4502 f_acc512(acc, p, secret + secretSize - XXH_STRIPE_LEN - XXH_SECRET_LASTACC_START);
4503 } }
4504}
4505
4506XXH_FORCE_INLINE xxh_u64
4507XXH3_mix2Accs(const xxh_u64* XXH_RESTRICT acc, const xxh_u8* XXH_RESTRICT secret)
4508{
4509 return XXH3_mul128_fold64(
4510 acc[0] ^ XXH_readLE64(secret),
4511 acc[1] ^ XXH_readLE64(secret+8) );
4512}
4513
4514static XXH64_hash_t
4515XXH3_mergeAccs(const xxh_u64* XXH_RESTRICT acc, const xxh_u8* XXH_RESTRICT secret, xxh_u64 start)
4516{
4517 xxh_u64 result64 = start;
4518 size_t i = 0;
4519
4520 for (i = 0; i < 4; i++) {
4521 result64 += XXH3_mix2Accs(acc+2*i, secret + 16*i);
4522#if defined(__clang__) /* Clang */ \
4523 && (defined(__arm__) || defined(__thumb__)) /* ARMv7 */ \
4524 && (defined(__ARM_NEON) || defined(__ARM_NEON__)) /* NEON */ \
4525 && !defined(XXH_ENABLE_AUTOVECTORIZE) /* Define to disable */
4526 /*
4527 * UGLY HACK:
4528 * Prevent autovectorization on Clang ARMv7-a. Exact same problem as
4529 * the one in XXH3_len_129to240_64b. Speeds up shorter keys > 240b.
4530 * XXH3_64bits, len == 256, Snapdragon 835:
4531 * without hack: 2063.7 MB/s
4532 * with hack: 2560.7 MB/s
4533 */
4534 XXH_COMPILER_GUARD(result64);
4535#endif
4536 }
4537
4538 return XXH3_avalanche(result64);
4539}
4540
4541#define XXH3_INIT_ACC { XXH_PRIME32_3, XXH_PRIME64_1, XXH_PRIME64_2, XXH_PRIME64_3, \
4542 XXH_PRIME64_4, XXH_PRIME32_2, XXH_PRIME64_5, XXH_PRIME32_1 }
4543
4544XXH_FORCE_INLINE XXH64_hash_t
4545XXH3_hashLong_64b_internal(const void* XXH_RESTRICT input, size_t len,
4546 const void* XXH_RESTRICT secret, size_t secretSize,
4547 XXH3_f_accumulate_512 f_acc512,
4548 XXH3_f_scrambleAcc f_scramble)
4549{
4550 XXH_ALIGN(XXH_ACC_ALIGN) xxh_u64 acc[XXH_ACC_NB] = XXH3_INIT_ACC;
4551
4552 XXH3_hashLong_internal_loop(acc, (const xxh_u8*)input, len, (const xxh_u8*)secret, secretSize, f_acc512, f_scramble);
4553
4554 /* converge into final hash */
4555 XXH_STATIC_ASSERT(sizeof(acc) == 64);
4556 /* do not align on 8, so that the secret is different from the accumulator */
4557#define XXH_SECRET_MERGEACCS_START 11
4558 XXH_ASSERT(secretSize >= sizeof(acc) + XXH_SECRET_MERGEACCS_START);
4559 return XXH3_mergeAccs(acc, (const xxh_u8*)secret + XXH_SECRET_MERGEACCS_START, (xxh_u64)len * XXH_PRIME64_1);
4560}
4561
4562/*
4563 * It's important for performance to transmit secret's size (when it's static)
4564 * so that the compiler can properly optimize the vectorized loop.
4565 * This makes a big performance difference for "medium" keys (<1 KB) when using AVX instruction set.
4566 */
4567XXH_FORCE_INLINE XXH64_hash_t
4568XXH3_hashLong_64b_withSecret(const void* XXH_RESTRICT input, size_t len,
4569 XXH64_hash_t seed64, const xxh_u8* XXH_RESTRICT secret, size_t secretLen)
4570{
4571 (void)seed64;
4572 return XXH3_hashLong_64b_internal(input, len, secret, secretLen, XXH3_accumulate_512, XXH3_scrambleAcc);
4573}
4574
4575/*
4576 * It's preferable for performance that XXH3_hashLong is not inlined,
4577 * as it results in a smaller function for small data, easier to the instruction cache.
4578 * Note that inside this no_inline function, we do inline the internal loop,
4579 * and provide a statically defined secret size to allow optimization of vector loop.
4580 */
4581XXH_NO_INLINE XXH64_hash_t
4582XXH3_hashLong_64b_default(const void* XXH_RESTRICT input, size_t len,
4583 XXH64_hash_t seed64, const xxh_u8* XXH_RESTRICT secret, size_t secretLen)
4584{
4585 (void)seed64; (void)secret; (void)secretLen;
4586 return XXH3_hashLong_64b_internal(input, len, XXH3_kSecret, sizeof(XXH3_kSecret), XXH3_accumulate_512, XXH3_scrambleAcc);
4587}
4588
4589/*
4590 * XXH3_hashLong_64b_withSeed():
4591 * Generate a custom key based on alteration of default XXH3_kSecret with the seed,
4592 * and then use this key for long mode hashing.
4593 *
4594 * This operation is decently fast but nonetheless costs a little bit of time.
4595 * Try to avoid it whenever possible (typically when seed==0).
4596 *
4597 * It's important for performance that XXH3_hashLong is not inlined. Not sure
4598 * why (uop cache maybe?), but the difference is large and easily measurable.
4599 */
4600XXH_FORCE_INLINE XXH64_hash_t
4601XXH3_hashLong_64b_withSeed_internal(const void* input, size_t len,
4602 XXH64_hash_t seed,
4603 XXH3_f_accumulate_512 f_acc512,
4604 XXH3_f_scrambleAcc f_scramble,
4605 XXH3_f_initCustomSecret f_initSec)
4606{
4607 if (seed == 0)
4608 return XXH3_hashLong_64b_internal(input, len,
4609 XXH3_kSecret, sizeof(XXH3_kSecret),
4610 f_acc512, f_scramble);
4611 { XXH_ALIGN(XXH_SEC_ALIGN) xxh_u8 secret[XXH_SECRET_DEFAULT_SIZE];
4612 f_initSec(secret, seed);
4613 return XXH3_hashLong_64b_internal(input, len, secret, sizeof(secret),
4614 f_acc512, f_scramble);
4615 }
4616}
4617
4618/*
4619 * It's important for performance that XXH3_hashLong is not inlined.
4620 */
4621XXH_NO_INLINE XXH64_hash_t
4622XXH3_hashLong_64b_withSeed(const void* input, size_t len,
4623 XXH64_hash_t seed, const xxh_u8* secret, size_t secretLen)
4624{
4625 (void)secret; (void)secretLen;
4626 return XXH3_hashLong_64b_withSeed_internal(input, len, seed,
4627 XXH3_accumulate_512, XXH3_scrambleAcc, XXH3_initCustomSecret);
4628}
4629
4630
4631typedef XXH64_hash_t (*XXH3_hashLong64_f)(const void* XXH_RESTRICT, size_t,
4632 XXH64_hash_t, const xxh_u8* XXH_RESTRICT, size_t);
4633
4634XXH_FORCE_INLINE XXH64_hash_t
4635XXH3_64bits_internal(const void* XXH_RESTRICT input, size_t len,
4636 XXH64_hash_t seed64, const void* XXH_RESTRICT secret, size_t secretLen,
4637 XXH3_hashLong64_f f_hashLong)
4638{
4639 XXH_ASSERT(secretLen >= XXH3_SECRET_SIZE_MIN);
4640 /*
4641 * If an action is to be taken if `secretLen` condition is not respected,
4642 * it should be done here.
4643 * For now, it's a contract pre-condition.
4644 * Adding a check and a branch here would cost performance at every hash.
4645 * Also, note that function signature doesn't offer room to return an error.
4646 */
4647 if (len <= 16)
4648 return XXH3_len_0to16_64b((const xxh_u8*)input, len, (const xxh_u8*)secret, seed64);
4649 if (len <= 128)
4650 return XXH3_len_17to128_64b((const xxh_u8*)input, len, (const xxh_u8*)secret, secretLen, seed64);
4651 if (len <= XXH3_MIDSIZE_MAX)
4652 return XXH3_len_129to240_64b((const xxh_u8*)input, len, (const xxh_u8*)secret, secretLen, seed64);
4653 return f_hashLong(input, len, seed64, (const xxh_u8*)secret, secretLen);
4654}
4655
4656
4657/* === Public entry point === */
4658
4659/*! @ingroup xxh3_family */
4660XXH_PUBLIC_API XXH64_hash_t XXH3_64bits(const void* input, size_t len)
4661{
4662 return XXH3_64bits_internal(input, len, 0, XXH3_kSecret, sizeof(XXH3_kSecret), XXH3_hashLong_64b_default);
4663}
4664
4665/*! @ingroup xxh3_family */
4666XXH_PUBLIC_API XXH64_hash_t
4667XXH3_64bits_withSecret(const void* input, size_t len, const void* secret, size_t secretSize)
4668{
4669 return XXH3_64bits_internal(input, len, 0, secret, secretSize, XXH3_hashLong_64b_withSecret);
4670}
4671
4672/*! @ingroup xxh3_family */
4673XXH_PUBLIC_API XXH64_hash_t
4674XXH3_64bits_withSeed(const void* input, size_t len, XXH64_hash_t seed)
4675{
4676 return XXH3_64bits_internal(input, len, seed, XXH3_kSecret, sizeof(XXH3_kSecret), XXH3_hashLong_64b_withSeed);
4677}
4678
4679XXH_PUBLIC_API XXH64_hash_t
4680XXH3_64bits_withSecretandSeed(const void* input, size_t len, const void* secret, size_t secretSize, XXH64_hash_t seed)
4681{
4682 if (len <= XXH3_MIDSIZE_MAX)
4683 return XXH3_64bits_internal(input, len, seed, XXH3_kSecret, sizeof(XXH3_kSecret), NULL);
4684 return XXH3_hashLong_64b_withSecret(input, len, seed, (const xxh_u8*)secret, secretSize);
4685}
4686
4687
4688/* === XXH3 streaming === */
4689
4690/*
4691 * Malloc's a pointer that is always aligned to align.
4692 *
4693 * This must be freed with `XXH_alignedFree()`.
4694 *
4695 * malloc typically guarantees 16 byte alignment on 64-bit systems and 8 byte
4696 * alignment on 32-bit. This isn't enough for the 32 byte aligned loads in AVX2
4697 * or on 32-bit, the 16 byte aligned loads in SSE2 and NEON.
4698 *
4699 * This underalignment previously caused a rather obvious crash which went
4700 * completely unnoticed due to XXH3_createState() not actually being tested.
4701 * Credit to RedSpah for noticing this bug.
4702 *
4703 * The alignment is done manually: Functions like posix_memalign or _mm_malloc
4704 * are avoided: To maintain portability, we would have to write a fallback
4705 * like this anyways, and besides, testing for the existence of library
4706 * functions without relying on external build tools is impossible.
4707 *
4708 * The method is simple: Overallocate, manually align, and store the offset
4709 * to the original behind the returned pointer.
4710 *
4711 * Align must be a power of 2 and 8 <= align <= 128.
4712 */
4713static void* XXH_alignedMalloc(size_t s, size_t align)
4714{
4715 XXH_ASSERT(align <= 128 && align >= 8); /* range check */
4716 XXH_ASSERT((align & (align-1)) == 0); /* power of 2 */
4717 XXH_ASSERT(s != 0 && s < (s + align)); /* empty/overflow */
4718 { /* Overallocate to make room for manual realignment and an offset byte */
4719 xxh_u8* base = (xxh_u8*)XXH_malloc(s + align);
4720 if (base != NULL) {
4721 /*
4722 * Get the offset needed to align this pointer.
4723 *
4724 * Even if the returned pointer is aligned, there will always be
4725 * at least one byte to store the offset to the original pointer.
4726 */
4727 size_t offset = align - ((size_t)base & (align - 1)); /* base % align */
4728 /* Add the offset for the now-aligned pointer */
4729 xxh_u8* ptr = base + offset;
4730
4731 XXH_ASSERT((size_t)ptr % align == 0);
4732
4733 /* Store the offset immediately before the returned pointer. */
4734 ptr[-1] = (xxh_u8)offset;
4735 return ptr;
4736 }
4737 return NULL;
4738 }
4739}
4740/*
4741 * Frees an aligned pointer allocated by XXH_alignedMalloc(). Don't pass
4742 * normal malloc'd pointers, XXH_alignedMalloc has a specific data layout.
4743 */
4744static void XXH_alignedFree(void* p)
4745{
4746 if (p != NULL) {
4747 xxh_u8* ptr = (xxh_u8*)p;
4748 /* Get the offset byte we added in XXH_malloc. */
4749 xxh_u8 offset = ptr[-1];
4750 /* Free the original malloc'd pointer */
4751 xxh_u8* base = ptr - offset;
4752 XXH_free(base);
4753 }
4754}
4755/*! @ingroup xxh3_family */
4756XXH_PUBLIC_API XXH3_state_t* XXH3_createState(void)
4757{
4758 XXH3_state_t* const state = (XXH3_state_t*)XXH_alignedMalloc(sizeof(XXH3_state_t), 64);
4759 if (state==NULL) return NULL;
4760 XXH3_INITSTATE(state);
4761 return state;
4762}
4763
4764/*! @ingroup xxh3_family */
4765XXH_PUBLIC_API XXH_errorcode XXH3_freeState(XXH3_state_t* statePtr)
4766{
4767 XXH_alignedFree(statePtr);
4768 return XXH_OK;
4769}
4770
4771/*! @ingroup xxh3_family */
4772XXH_PUBLIC_API void
4773XXH3_copyState(XXH3_state_t* dst_state, const XXH3_state_t* src_state)
4774{
4775 XXH_memcpy(dst_state, src_state, sizeof(*dst_state));
4776}
4777
4778static void
4779XXH3_reset_internal(XXH3_state_t* statePtr,
4780 XXH64_hash_t seed,
4781 const void* secret, size_t secretSize)
4782{
4783 size_t const initStart = offsetof(XXH3_state_t, bufferedSize);
4784 size_t const initLength = offsetof(XXH3_state_t, nbStripesPerBlock) - initStart;
4785 XXH_ASSERT(offsetof(XXH3_state_t, nbStripesPerBlock) > initStart);
4786 XXH_ASSERT(statePtr != NULL);
4787 /* set members from bufferedSize to nbStripesPerBlock (excluded) to 0 */
4788 memset((char*)statePtr + initStart, 0, initLength);
4789 statePtr->acc[0] = XXH_PRIME32_3;
4790 statePtr->acc[1] = XXH_PRIME64_1;
4791 statePtr->acc[2] = XXH_PRIME64_2;
4792 statePtr->acc[3] = XXH_PRIME64_3;
4793 statePtr->acc[4] = XXH_PRIME64_4;
4794 statePtr->acc[5] = XXH_PRIME32_2;
4795 statePtr->acc[6] = XXH_PRIME64_5;
4796 statePtr->acc[7] = XXH_PRIME32_1;
4797 statePtr->seed = seed;
4798 statePtr->useSeed = (seed != 0);
4799 statePtr->extSecret = (const unsigned char*)secret;
4800 XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN);
4801 statePtr->secretLimit = secretSize - XXH_STRIPE_LEN;
4802 statePtr->nbStripesPerBlock = statePtr->secretLimit / XXH_SECRET_CONSUME_RATE;
4803}
4804
4805/*! @ingroup xxh3_family */
4806XXH_PUBLIC_API XXH_errorcode
4807XXH3_64bits_reset(XXH3_state_t* statePtr)
4808{
4809 if (statePtr == NULL) return XXH_ERROR;
4810 XXH3_reset_internal(statePtr, 0, XXH3_kSecret, XXH_SECRET_DEFAULT_SIZE);
4811 return XXH_OK;
4812}
4813
4814/*! @ingroup xxh3_family */
4815XXH_PUBLIC_API XXH_errorcode
4816XXH3_64bits_reset_withSecret(XXH3_state_t* statePtr, const void* secret, size_t secretSize)
4817{
4818 if (statePtr == NULL) return XXH_ERROR;
4819 XXH3_reset_internal(statePtr, 0, secret, secretSize);
4820 if (secret == NULL) return XXH_ERROR;
4821 if (secretSize < XXH3_SECRET_SIZE_MIN) return XXH_ERROR;
4822 return XXH_OK;
4823}
4824
4825/*! @ingroup xxh3_family */
4826XXH_PUBLIC_API XXH_errorcode
4827XXH3_64bits_reset_withSeed(XXH3_state_t* statePtr, XXH64_hash_t seed)
4828{
4829 if (statePtr == NULL) return XXH_ERROR;
4830 if (seed==0) return XXH3_64bits_reset(statePtr);
4831 if ((seed != statePtr->seed) || (statePtr->extSecret != NULL))
4832 XXH3_initCustomSecret(statePtr->customSecret, seed);
4833 XXH3_reset_internal(statePtr, seed, NULL, XXH_SECRET_DEFAULT_SIZE);
4834 return XXH_OK;
4835}
4836
4837/*! @ingroup xxh3_family */
4838XXH_PUBLIC_API XXH_errorcode
4839XXH3_64bits_reset_withSecretandSeed(XXH3_state_t* statePtr, const void* secret, size_t secretSize, XXH64_hash_t seed64)
4840{
4841 if (statePtr == NULL) return XXH_ERROR;
4842 if (secret == NULL) return XXH_ERROR;
4843 if (secretSize < XXH3_SECRET_SIZE_MIN) return XXH_ERROR;
4844 XXH3_reset_internal(statePtr, seed64, secret, secretSize);
4845 statePtr->useSeed = 1; /* always, even if seed64==0 */
4846 return XXH_OK;
4847}
4848
4849/* Note : when XXH3_consumeStripes() is invoked,
4850 * there must be a guarantee that at least one more byte must be consumed from input
4851 * so that the function can blindly consume all stripes using the "normal" secret segment */
4852XXH_FORCE_INLINE void
4853XXH3_consumeStripes(xxh_u64* XXH_RESTRICT acc,
4854 size_t* XXH_RESTRICT nbStripesSoFarPtr, size_t nbStripesPerBlock,
4855 const xxh_u8* XXH_RESTRICT input, size_t nbStripes,
4856 const xxh_u8* XXH_RESTRICT secret, size_t secretLimit,
4857 XXH3_f_accumulate_512 f_acc512,
4858 XXH3_f_scrambleAcc f_scramble)
4859{
4860 XXH_ASSERT(nbStripes <= nbStripesPerBlock); /* can handle max 1 scramble per invocation */
4861 XXH_ASSERT(*nbStripesSoFarPtr < nbStripesPerBlock);
4862 if (nbStripesPerBlock - *nbStripesSoFarPtr <= nbStripes) {
4863 /* need a scrambling operation */
4864 size_t const nbStripesToEndofBlock = nbStripesPerBlock - *nbStripesSoFarPtr;
4865 size_t const nbStripesAfterBlock = nbStripes - nbStripesToEndofBlock;
4866 XXH3_accumulate(acc, input, secret + nbStripesSoFarPtr[0] * XXH_SECRET_CONSUME_RATE, nbStripesToEndofBlock, f_acc512);
4867 f_scramble(acc, secret + secretLimit);
4868 XXH3_accumulate(acc, input + nbStripesToEndofBlock * XXH_STRIPE_LEN, secret, nbStripesAfterBlock, f_acc512);
4869 *nbStripesSoFarPtr = nbStripesAfterBlock;
4870 } else {
4871 XXH3_accumulate(acc, input, secret + nbStripesSoFarPtr[0] * XXH_SECRET_CONSUME_RATE, nbStripes, f_acc512);
4872 *nbStripesSoFarPtr += nbStripes;
4873 }
4874}
4875
4876#ifndef XXH3_STREAM_USE_STACK
4877# ifndef __clang__ /* clang doesn't need additional stack space */
4878# define XXH3_STREAM_USE_STACK 1
4879# endif
4880#endif
4881/*
4882 * Both XXH3_64bits_update and XXH3_128bits_update use this routine.
4883 */
4884XXH_FORCE_INLINE XXH_errorcode
4885XXH3_update(XXH3_state_t* XXH_RESTRICT const state,
4886 const xxh_u8* XXH_RESTRICT input, size_t len,
4887 XXH3_f_accumulate_512 f_acc512,
4888 XXH3_f_scrambleAcc f_scramble)
4889{
4890 if (input==NULL) {
4891 XXH_ASSERT(len == 0);
4892 return XXH_OK;
4893 }
4894
4895 XXH_ASSERT(state != NULL);
4896 { const xxh_u8* const bEnd = input + len;
4897 const unsigned char* const secret = (state->extSecret == NULL) ? state->customSecret : state->extSecret;
4898#if defined(XXH3_STREAM_USE_STACK) && XXH3_STREAM_USE_STACK >= 1
4899 /* For some reason, gcc and MSVC seem to suffer greatly
4900 * when operating accumulators directly into state.
4901 * Operating into stack space seems to enable proper optimization.
4902 * clang, on the other hand, doesn't seem to need this trick */
4903 XXH_ALIGN(XXH_ACC_ALIGN) xxh_u64 acc[8]; memcpy(acc, state->acc, sizeof(acc));
4904#else
4905 xxh_u64* XXH_RESTRICT const acc = state->acc;
4906#endif
4907 state->totalLen += len;
4908 XXH_ASSERT(state->bufferedSize <= XXH3_INTERNALBUFFER_SIZE);
4909
4910 /* small input : just fill in tmp buffer */
4911 if (state->bufferedSize + len <= XXH3_INTERNALBUFFER_SIZE) {
4912 XXH_memcpy(state->buffer + state->bufferedSize, input, len);
4913 state->bufferedSize += (XXH32_hash_t)len;
4914 return XXH_OK;
4915 }
4916
4917 /* total input is now > XXH3_INTERNALBUFFER_SIZE */
4918 #define XXH3_INTERNALBUFFER_STRIPES (XXH3_INTERNALBUFFER_SIZE / XXH_STRIPE_LEN)
4919 XXH_STATIC_ASSERT(XXH3_INTERNALBUFFER_SIZE % XXH_STRIPE_LEN == 0); /* clean multiple */
4920
4921 /*
4922 * Internal buffer is partially filled (always, except at beginning)
4923 * Complete it, then consume it.
4924 */
4925 if (state->bufferedSize) {
4926 size_t const loadSize = XXH3_INTERNALBUFFER_SIZE - state->bufferedSize;
4927 XXH_memcpy(state->buffer + state->bufferedSize, input, loadSize);
4928 input += loadSize;
4929 XXH3_consumeStripes(acc,
4930 &state->nbStripesSoFar, state->nbStripesPerBlock,
4931 state->buffer, XXH3_INTERNALBUFFER_STRIPES,
4932 secret, state->secretLimit,
4933 f_acc512, f_scramble);
4934 state->bufferedSize = 0;
4935 }
4936 XXH_ASSERT(input < bEnd);
4937
4938 /* large input to consume : ingest per full block */
4939 if ((size_t)(bEnd - input) > state->nbStripesPerBlock * XXH_STRIPE_LEN) {
4940 size_t nbStripes = (size_t)(bEnd - 1 - input) / XXH_STRIPE_LEN;
4941 XXH_ASSERT(state->nbStripesPerBlock >= state->nbStripesSoFar);
4942 /* join to current block's end */
4943 { size_t const nbStripesToEnd = state->nbStripesPerBlock - state->nbStripesSoFar;
4944 XXH_ASSERT(nbStripesToEnd <= nbStripes);
4945 XXH3_accumulate(acc, input, secret + state->nbStripesSoFar * XXH_SECRET_CONSUME_RATE, nbStripesToEnd, f_acc512);
4946 f_scramble(acc, secret + state->secretLimit);
4947 state->nbStripesSoFar = 0;
4948 input += nbStripesToEnd * XXH_STRIPE_LEN;
4949 nbStripes -= nbStripesToEnd;
4950 }
4951 /* consume per entire blocks */
4952 while(nbStripes >= state->nbStripesPerBlock) {
4953 XXH3_accumulate(acc, input, secret, state->nbStripesPerBlock, f_acc512);
4954 f_scramble(acc, secret + state->secretLimit);
4955 input += state->nbStripesPerBlock * XXH_STRIPE_LEN;
4956 nbStripes -= state->nbStripesPerBlock;
4957 }
4958 /* consume last partial block */
4959 XXH3_accumulate(acc, input, secret, nbStripes, f_acc512);
4960 input += nbStripes * XXH_STRIPE_LEN;
4961 XXH_ASSERT(input < bEnd); /* at least some bytes left */
4962 state->nbStripesSoFar = nbStripes;
4963 /* buffer predecessor of last partial stripe */
4964 XXH_memcpy(state->buffer + sizeof(state->buffer) - XXH_STRIPE_LEN, input - XXH_STRIPE_LEN, XXH_STRIPE_LEN);
4965 XXH_ASSERT(bEnd - input <= XXH_STRIPE_LEN);
4966 } else {
4967 /* content to consume <= block size */
4968 /* Consume input by a multiple of internal buffer size */
4969 if (bEnd - input > XXH3_INTERNALBUFFER_SIZE) {
4970 const xxh_u8* const limit = bEnd - XXH3_INTERNALBUFFER_SIZE;
4971 do {
4972 XXH3_consumeStripes(acc,
4973 &state->nbStripesSoFar, state->nbStripesPerBlock,
4974 input, XXH3_INTERNALBUFFER_STRIPES,
4975 secret, state->secretLimit,
4976 f_acc512, f_scramble);
4977 input += XXH3_INTERNALBUFFER_SIZE;
4978 } while (input<limit);
4979 /* buffer predecessor of last partial stripe */
4980 XXH_memcpy(state->buffer + sizeof(state->buffer) - XXH_STRIPE_LEN, input - XXH_STRIPE_LEN, XXH_STRIPE_LEN);
4981 }
4982 }
4983
4984 /* Some remaining input (always) : buffer it */
4985 XXH_ASSERT(input < bEnd);
4986 XXH_ASSERT(bEnd - input <= XXH3_INTERNALBUFFER_SIZE);
4987 XXH_ASSERT(state->bufferedSize == 0);
4988 XXH_memcpy(state->buffer, input, (size_t)(bEnd-input));
4989 state->bufferedSize = (XXH32_hash_t)(bEnd-input);
4990#if defined(XXH3_STREAM_USE_STACK) && XXH3_STREAM_USE_STACK >= 1
4991 /* save stack accumulators into state */
4992 memcpy(state->acc, acc, sizeof(acc));
4993#endif
4994 }
4995
4996 return XXH_OK;
4997}
4998
4999/*! @ingroup xxh3_family */
5000XXH_PUBLIC_API XXH_errorcode
5001XXH3_64bits_update(XXH3_state_t* state, const void* input, size_t len)
5002{
5003 return XXH3_update(state, (const xxh_u8*)input, len,
5004 XXH3_accumulate_512, XXH3_scrambleAcc);
5005}
5006
5007
5008XXH_FORCE_INLINE void
5009XXH3_digest_long (XXH64_hash_t* acc,
5010 const XXH3_state_t* state,
5011 const unsigned char* secret)
5012{
5013 /*
5014 * Digest on a local copy. This way, the state remains unaltered, and it can
5015 * continue ingesting more input afterwards.
5016 */
5017 XXH_memcpy(acc, state->acc, sizeof(state->acc));
5018 if (state->bufferedSize >= XXH_STRIPE_LEN) {
5019 size_t const nbStripes = (state->bufferedSize - 1) / XXH_STRIPE_LEN;
5020 size_t nbStripesSoFar = state->nbStripesSoFar;
5021 XXH3_consumeStripes(acc,
5022 &nbStripesSoFar, state->nbStripesPerBlock,
5023 state->buffer, nbStripes,
5024 secret, state->secretLimit,
5025 XXH3_accumulate_512, XXH3_scrambleAcc);
5026 /* last stripe */
5027 XXH3_accumulate_512(acc,
5028 state->buffer + state->bufferedSize - XXH_STRIPE_LEN,
5029 secret + state->secretLimit - XXH_SECRET_LASTACC_START);
5030 } else { /* bufferedSize < XXH_STRIPE_LEN */
5031 xxh_u8 lastStripe[XXH_STRIPE_LEN];
5032 size_t const catchupSize = XXH_STRIPE_LEN - state->bufferedSize;
5033 XXH_ASSERT(state->bufferedSize > 0); /* there is always some input buffered */
5034 XXH_memcpy(lastStripe, state->buffer + sizeof(state->buffer) - catchupSize, catchupSize);
5035 XXH_memcpy(lastStripe + catchupSize, state->buffer, state->bufferedSize);
5036 XXH3_accumulate_512(acc,
5037 lastStripe,
5038 secret + state->secretLimit - XXH_SECRET_LASTACC_START);
5039 }
5040}
5041
5042/*! @ingroup xxh3_family */
5043XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_digest (const XXH3_state_t* state)
5044{
5045 const unsigned char* const secret = (state->extSecret == NULL) ? state->customSecret : state->extSecret;
5046 if (state->totalLen > XXH3_MIDSIZE_MAX) {
5047 XXH_ALIGN(XXH_ACC_ALIGN) XXH64_hash_t acc[XXH_ACC_NB];
5048 XXH3_digest_long(acc, state, secret);
5049 return XXH3_mergeAccs(acc,
5050 secret + XXH_SECRET_MERGEACCS_START,
5051 (xxh_u64)state->totalLen * XXH_PRIME64_1);
5052 }
5053 /* totalLen <= XXH3_MIDSIZE_MAX: digesting a short input */
5054 if (state->useSeed)
5055 return XXH3_64bits_withSeed(state->buffer, (size_t)state->totalLen, state->seed);
5056 return XXH3_64bits_withSecret(state->buffer, (size_t)(state->totalLen),
5057 secret, state->secretLimit + XXH_STRIPE_LEN);
5058}
5059
5060
5061
5062/* ==========================================
5063 * XXH3 128 bits (a.k.a XXH128)
5064 * ==========================================
5065 * XXH3's 128-bit variant has better mixing and strength than the 64-bit variant,
5066 * even without counting the significantly larger output size.
5067 *
5068 * For example, extra steps are taken to avoid the seed-dependent collisions
5069 * in 17-240 byte inputs (See XXH3_mix16B and XXH128_mix32B).
5070 *
5071 * This strength naturally comes at the cost of some speed, especially on short
5072 * lengths. Note that longer hashes are about as fast as the 64-bit version
5073 * due to it using only a slight modification of the 64-bit loop.
5074 *
5075 * XXH128 is also more oriented towards 64-bit machines. It is still extremely
5076 * fast for a _128-bit_ hash on 32-bit (it usually clears XXH64).
5077 */
5078
5079XXH_FORCE_INLINE XXH128_hash_t
5080XXH3_len_1to3_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed)
5081{
5082 /* A doubled version of 1to3_64b with different constants. */
5083 XXH_ASSERT(input != NULL);
5084 XXH_ASSERT(1 <= len && len <= 3);
5085 XXH_ASSERT(secret != NULL);
5086 /*
5087 * len = 1: combinedl = { input[0], 0x01, input[0], input[0] }
5088 * len = 2: combinedl = { input[1], 0x02, input[0], input[1] }
5089 * len = 3: combinedl = { input[2], 0x03, input[0], input[1] }
5090 */
5091 { xxh_u8 const c1 = input[0];
5092 xxh_u8 const c2 = input[len >> 1];
5093 xxh_u8 const c3 = input[len - 1];
5094 xxh_u32 const combinedl = ((xxh_u32)c1 <<16) | ((xxh_u32)c2 << 24)
5095 | ((xxh_u32)c3 << 0) | ((xxh_u32)len << 8);
5096 xxh_u32 const combinedh = XXH_rotl32(XXH_swap32(combinedl), 13);
5097 xxh_u64 const bitflipl = (XXH_readLE32(secret) ^ XXH_readLE32(secret+4)) + seed;
5098 xxh_u64 const bitfliph = (XXH_readLE32(secret+8) ^ XXH_readLE32(secret+12)) - seed;
5099 xxh_u64 const keyed_lo = (xxh_u64)combinedl ^ bitflipl;
5100 xxh_u64 const keyed_hi = (xxh_u64)combinedh ^ bitfliph;
5101 XXH128_hash_t h128;
5102 h128.low64 = XXH64_avalanche(keyed_lo);
5103 h128.high64 = XXH64_avalanche(keyed_hi);
5104 return h128;
5105 }
5106}
5107
5108XXH_FORCE_INLINE XXH128_hash_t
5109XXH3_len_4to8_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed)
5110{
5111 XXH_ASSERT(input != NULL);
5112 XXH_ASSERT(secret != NULL);
5113 XXH_ASSERT(4 <= len && len <= 8);
5114 seed ^= (xxh_u64)XXH_swap32((xxh_u32)seed) << 32;
5115 { xxh_u32 const input_lo = XXH_readLE32(input);
5116 xxh_u32 const input_hi = XXH_readLE32(input + len - 4);
5117 xxh_u64 const input_64 = input_lo + ((xxh_u64)input_hi << 32);
5118 xxh_u64 const bitflip = (XXH_readLE64(secret+16) ^ XXH_readLE64(secret+24)) + seed;
5119 xxh_u64 const keyed = input_64 ^ bitflip;
5120
5121 /* Shift len to the left to ensure it is even, this avoids even multiplies. */
5122 XXH128_hash_t m128 = XXH_mult64to128(keyed, XXH_PRIME64_1 + (len << 2));
5123
5124 m128.high64 += (m128.low64 << 1);
5125 m128.low64 ^= (m128.high64 >> 3);
5126
5127 m128.low64 = XXH_xorshift64(m128.low64, 35);
5128 m128.low64 *= 0x9FB21C651E98DF25ULL;
5129 m128.low64 = XXH_xorshift64(m128.low64, 28);
5130 m128.high64 = XXH3_avalanche(m128.high64);
5131 return m128;
5132 }
5133}
5134
5135XXH_FORCE_INLINE XXH128_hash_t
5136XXH3_len_9to16_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed)
5137{
5138 XXH_ASSERT(input != NULL);
5139 XXH_ASSERT(secret != NULL);
5140 XXH_ASSERT(9 <= len && len <= 16);
5141 { xxh_u64 const bitflipl = (XXH_readLE64(secret+32) ^ XXH_readLE64(secret+40)) - seed;
5142 xxh_u64 const bitfliph = (XXH_readLE64(secret+48) ^ XXH_readLE64(secret+56)) + seed;
5143 xxh_u64 const input_lo = XXH_readLE64(input);
5144 xxh_u64 input_hi = XXH_readLE64(input + len - 8);
5145 XXH128_hash_t m128 = XXH_mult64to128(input_lo ^ input_hi ^ bitflipl, XXH_PRIME64_1);
5146 /*
5147 * Put len in the middle of m128 to ensure that the length gets mixed to
5148 * both the low and high bits in the 128x64 multiply below.
5149 */
5150 m128.low64 += (xxh_u64)(len - 1) << 54;
5151 input_hi ^= bitfliph;
5152 /*
5153 * Add the high 32 bits of input_hi to the high 32 bits of m128, then
5154 * add the long product of the low 32 bits of input_hi and XXH_PRIME32_2 to
5155 * the high 64 bits of m128.
5156 *
5157 * The best approach to this operation is different on 32-bit and 64-bit.
5158 */
5159 if (sizeof(void *) < sizeof(xxh_u64)) { /* 32-bit */
5160 /*
5161 * 32-bit optimized version, which is more readable.
5162 *
5163 * On 32-bit, it removes an ADC and delays a dependency between the two
5164 * halves of m128.high64, but it generates an extra mask on 64-bit.
5165 */
5166 m128.high64 += (input_hi & 0xFFFFFFFF00000000ULL) + XXH_mult32to64((xxh_u32)input_hi, XXH_PRIME32_2);
5167 } else {
5168 /*
5169 * 64-bit optimized (albeit more confusing) version.
5170 *
5171 * Uses some properties of addition and multiplication to remove the mask:
5172 *
5173 * Let:
5174 * a = input_hi.lo = (input_hi & 0x00000000FFFFFFFF)
5175 * b = input_hi.hi = (input_hi & 0xFFFFFFFF00000000)
5176 * c = XXH_PRIME32_2
5177 *
5178 * a + (b * c)
5179 * Inverse Property: x + y - x == y
5180 * a + (b * (1 + c - 1))
5181 * Distributive Property: x * (y + z) == (x * y) + (x * z)
5182 * a + (b * 1) + (b * (c - 1))
5183 * Identity Property: x * 1 == x
5184 * a + b + (b * (c - 1))
5185 *
5186 * Substitute a, b, and c:
5187 * input_hi.hi + input_hi.lo + ((xxh_u64)input_hi.lo * (XXH_PRIME32_2 - 1))
5188 *
5189 * Since input_hi.hi + input_hi.lo == input_hi, we get this:
5190 * input_hi + ((xxh_u64)input_hi.lo * (XXH_PRIME32_2 - 1))
5191 */
5192 m128.high64 += input_hi + XXH_mult32to64((xxh_u32)input_hi, XXH_PRIME32_2 - 1);
5193 }
5194 /* m128 ^= XXH_swap64(m128 >> 64); */
5195 m128.low64 ^= XXH_swap64(m128.high64);
5196
5197 { /* 128x64 multiply: h128 = m128 * XXH_PRIME64_2; */
5198 XXH128_hash_t h128 = XXH_mult64to128(m128.low64, XXH_PRIME64_2);
5199 h128.high64 += m128.high64 * XXH_PRIME64_2;
5200
5201 h128.low64 = XXH3_avalanche(h128.low64);
5202 h128.high64 = XXH3_avalanche(h128.high64);
5203 return h128;
5204 } }
5205}
5206
5207/*
5208 * Assumption: `secret` size is >= XXH3_SECRET_SIZE_MIN
5209 */
5210XXH_FORCE_INLINE XXH128_hash_t
5211XXH3_len_0to16_128b(const xxh_u8* input, size_t len, const xxh_u8* secret, XXH64_hash_t seed)
5212{
5213 XXH_ASSERT(len <= 16);
5214 { if (len > 8) return XXH3_len_9to16_128b(input, len, secret, seed);
5215 if (len >= 4) return XXH3_len_4to8_128b(input, len, secret, seed);
5216 if (len) return XXH3_len_1to3_128b(input, len, secret, seed);
5217 { XXH128_hash_t h128;
5218 xxh_u64 const bitflipl = XXH_readLE64(secret+64) ^ XXH_readLE64(secret+72);
5219 xxh_u64 const bitfliph = XXH_readLE64(secret+80) ^ XXH_readLE64(secret+88);
5220 h128.low64 = XXH64_avalanche(seed ^ bitflipl);
5221 h128.high64 = XXH64_avalanche( seed ^ bitfliph);
5222 return h128;
5223 } }
5224}
5225
5226/*
5227 * A bit slower than XXH3_mix16B, but handles multiply by zero better.
5228 */
5229XXH_FORCE_INLINE XXH128_hash_t
5230XXH128_mix32B(XXH128_hash_t acc, const xxh_u8* input_1, const xxh_u8* input_2,
5231 const xxh_u8* secret, XXH64_hash_t seed)
5232{
5233 acc.low64 += XXH3_mix16B (input_1, secret+0, seed);
5234 acc.low64 ^= XXH_readLE64(input_2) + XXH_readLE64(input_2 + 8);
5235 acc.high64 += XXH3_mix16B (input_2, secret+16, seed);
5236 acc.high64 ^= XXH_readLE64(input_1) + XXH_readLE64(input_1 + 8);
5237 return acc;
5238}
5239
5240
5241XXH_FORCE_INLINE XXH128_hash_t
5242XXH3_len_17to128_128b(const xxh_u8* XXH_RESTRICT input, size_t len,
5243 const xxh_u8* XXH_RESTRICT secret, size_t secretSize,
5244 XXH64_hash_t seed)
5245{
5246 XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN); (void)secretSize;
5247 XXH_ASSERT(16 < len && len <= 128);
5248
5249 { XXH128_hash_t acc;
5250 acc.low64 = len * XXH_PRIME64_1;
5251 acc.high64 = 0;
5252 if (len > 32) {
5253 if (len > 64) {
5254 if (len > 96) {
5255 acc = XXH128_mix32B(acc, input+48, input+len-64, secret+96, seed);
5256 }
5257 acc = XXH128_mix32B(acc, input+32, input+len-48, secret+64, seed);
5258 }
5259 acc = XXH128_mix32B(acc, input+16, input+len-32, secret+32, seed);
5260 }
5261 acc = XXH128_mix32B(acc, input, input+len-16, secret, seed);
5262 { XXH128_hash_t h128;
5263 h128.low64 = acc.low64 + acc.high64;
5264 h128.high64 = (acc.low64 * XXH_PRIME64_1)
5265 + (acc.high64 * XXH_PRIME64_4)
5266 + ((len - seed) * XXH_PRIME64_2);
5267 h128.low64 = XXH3_avalanche(h128.low64);
5268 h128.high64 = (XXH64_hash_t)0 - XXH3_avalanche(h128.high64);
5269 return h128;
5270 }
5271 }
5272}
5273
5274XXH_NO_INLINE XXH128_hash_t
5275XXH3_len_129to240_128b(const xxh_u8* XXH_RESTRICT input, size_t len,
5276 const xxh_u8* XXH_RESTRICT secret, size_t secretSize,
5277 XXH64_hash_t seed)
5278{
5279 XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN); (void)secretSize;
5280 XXH_ASSERT(128 < len && len <= XXH3_MIDSIZE_MAX);
5281
5282 { XXH128_hash_t acc;
5283 int const nbRounds = (int)len / 32;
5284 int i;
5285 acc.low64 = len * XXH_PRIME64_1;
5286 acc.high64 = 0;
5287 for (i=0; i<4; i++) {
5288 acc = XXH128_mix32B(acc,
5289 input + (32 * i),
5290 input + (32 * i) + 16,
5291 secret + (32 * i),
5292 seed);
5293 }
5294 acc.low64 = XXH3_avalanche(acc.low64);
5295 acc.high64 = XXH3_avalanche(acc.high64);
5296 XXH_ASSERT(nbRounds >= 4);
5297 for (i=4 ; i < nbRounds; i++) {
5298 acc = XXH128_mix32B(acc,
5299 input + (32 * i),
5300 input + (32 * i) + 16,
5301 secret + XXH3_MIDSIZE_STARTOFFSET + (32 * (i - 4)),
5302 seed);
5303 }
5304 /* last bytes */
5305 acc = XXH128_mix32B(acc,
5306 input + len - 16,
5307 input + len - 32,
5308 secret + XXH3_SECRET_SIZE_MIN - XXH3_MIDSIZE_LASTOFFSET - 16,
5309 0ULL - seed);
5310
5311 { XXH128_hash_t h128;
5312 h128.low64 = acc.low64 + acc.high64;
5313 h128.high64 = (acc.low64 * XXH_PRIME64_1)
5314 + (acc.high64 * XXH_PRIME64_4)
5315 + ((len - seed) * XXH_PRIME64_2);
5316 h128.low64 = XXH3_avalanche(h128.low64);
5317 h128.high64 = (XXH64_hash_t)0 - XXH3_avalanche(h128.high64);
5318 return h128;
5319 }
5320 }
5321}
5322
5323XXH_FORCE_INLINE XXH128_hash_t
5324XXH3_hashLong_128b_internal(const void* XXH_RESTRICT input, size_t len,
5325 const xxh_u8* XXH_RESTRICT secret, size_t secretSize,
5326 XXH3_f_accumulate_512 f_acc512,
5327 XXH3_f_scrambleAcc f_scramble)
5328{
5329 XXH_ALIGN(XXH_ACC_ALIGN) xxh_u64 acc[XXH_ACC_NB] = XXH3_INIT_ACC;
5330
5331 XXH3_hashLong_internal_loop(acc, (const xxh_u8*)input, len, secret, secretSize, f_acc512, f_scramble);
5332
5333 /* converge into final hash */
5334 XXH_STATIC_ASSERT(sizeof(acc) == 64);
5335 XXH_ASSERT(secretSize >= sizeof(acc) + XXH_SECRET_MERGEACCS_START);
5336 { XXH128_hash_t h128;
5337 h128.low64 = XXH3_mergeAccs(acc,
5338 secret + XXH_SECRET_MERGEACCS_START,
5339 (xxh_u64)len * XXH_PRIME64_1);
5340 h128.high64 = XXH3_mergeAccs(acc,
5341 secret + secretSize
5342 - sizeof(acc) - XXH_SECRET_MERGEACCS_START,
5343 ~((xxh_u64)len * XXH_PRIME64_2));
5344 return h128;
5345 }
5346}
5347
5348/*
5349 * It's important for performance that XXH3_hashLong is not inlined.
5350 */
5351XXH_NO_INLINE XXH128_hash_t
5352XXH3_hashLong_128b_default(const void* XXH_RESTRICT input, size_t len,
5353 XXH64_hash_t seed64,
5354 const void* XXH_RESTRICT secret, size_t secretLen)
5355{
5356 (void)seed64; (void)secret; (void)secretLen;
5357 return XXH3_hashLong_128b_internal(input, len, XXH3_kSecret, sizeof(XXH3_kSecret),
5358 XXH3_accumulate_512, XXH3_scrambleAcc);
5359}
5360
5361/*
5362 * It's important for performance to pass @secretLen (when it's static)
5363 * to the compiler, so that it can properly optimize the vectorized loop.
5364 */
5365XXH_FORCE_INLINE XXH128_hash_t
5366XXH3_hashLong_128b_withSecret(const void* XXH_RESTRICT input, size_t len,
5367 XXH64_hash_t seed64,
5368 const void* XXH_RESTRICT secret, size_t secretLen)
5369{
5370 (void)seed64;
5371 return XXH3_hashLong_128b_internal(input, len, (const xxh_u8*)secret, secretLen,
5372 XXH3_accumulate_512, XXH3_scrambleAcc);
5373}
5374
5375XXH_FORCE_INLINE XXH128_hash_t
5376XXH3_hashLong_128b_withSeed_internal(const void* XXH_RESTRICT input, size_t len,
5377 XXH64_hash_t seed64,
5378 XXH3_f_accumulate_512 f_acc512,
5379 XXH3_f_scrambleAcc f_scramble,
5380 XXH3_f_initCustomSecret f_initSec)
5381{
5382 if (seed64 == 0)
5383 return XXH3_hashLong_128b_internal(input, len,
5384 XXH3_kSecret, sizeof(XXH3_kSecret),
5385 f_acc512, f_scramble);
5386 { XXH_ALIGN(XXH_SEC_ALIGN) xxh_u8 secret[XXH_SECRET_DEFAULT_SIZE];
5387 f_initSec(secret, seed64);
5388 return XXH3_hashLong_128b_internal(input, len, (const xxh_u8*)secret, sizeof(secret),
5389 f_acc512, f_scramble);
5390 }
5391}
5392
5393/*
5394 * It's important for performance that XXH3_hashLong is not inlined.
5395 */
5396XXH_NO_INLINE XXH128_hash_t
5397XXH3_hashLong_128b_withSeed(const void* input, size_t len,
5398 XXH64_hash_t seed64, const void* XXH_RESTRICT secret, size_t secretLen)
5399{
5400 (void)secret; (void)secretLen;
5401 return XXH3_hashLong_128b_withSeed_internal(input, len, seed64,
5402 XXH3_accumulate_512, XXH3_scrambleAcc, XXH3_initCustomSecret);
5403}
5404
5405typedef XXH128_hash_t (*XXH3_hashLong128_f)(const void* XXH_RESTRICT, size_t,
5406 XXH64_hash_t, const void* XXH_RESTRICT, size_t);
5407
5408XXH_FORCE_INLINE XXH128_hash_t
5409XXH3_128bits_internal(const void* input, size_t len,
5410 XXH64_hash_t seed64, const void* XXH_RESTRICT secret, size_t secretLen,
5411 XXH3_hashLong128_f f_hl128)
5412{
5413 XXH_ASSERT(secretLen >= XXH3_SECRET_SIZE_MIN);
5414 /*
5415 * If an action is to be taken if `secret` conditions are not respected,
5416 * it should be done here.
5417 * For now, it's a contract pre-condition.
5418 * Adding a check and a branch here would cost performance at every hash.
5419 */
5420 if (len <= 16)
5421 return XXH3_len_0to16_128b((const xxh_u8*)input, len, (const xxh_u8*)secret, seed64);
5422 if (len <= 128)
5423 return XXH3_len_17to128_128b((const xxh_u8*)input, len, (const xxh_u8*)secret, secretLen, seed64);
5424 if (len <= XXH3_MIDSIZE_MAX)
5425 return XXH3_len_129to240_128b((const xxh_u8*)input, len, (const xxh_u8*)secret, secretLen, seed64);
5426 return f_hl128(input, len, seed64, secret, secretLen);
5427}
5428
5429
5430/* === Public XXH128 API === */
5431
5432/*! @ingroup xxh3_family */
5433XXH_PUBLIC_API XXH128_hash_t XXH3_128bits(const void* input, size_t len)
5434{
5435 return XXH3_128bits_internal(input, len, 0,
5436 XXH3_kSecret, sizeof(XXH3_kSecret),
5437 XXH3_hashLong_128b_default);
5438}
5439
5440/*! @ingroup xxh3_family */
5441XXH_PUBLIC_API XXH128_hash_t
5442XXH3_128bits_withSecret(const void* input, size_t len, const void* secret, size_t secretSize)
5443{
5444 return XXH3_128bits_internal(input, len, 0,
5445 (const xxh_u8*)secret, secretSize,
5446 XXH3_hashLong_128b_withSecret);
5447}
5448
5449/*! @ingroup xxh3_family */
5450XXH_PUBLIC_API XXH128_hash_t
5451XXH3_128bits_withSeed(const void* input, size_t len, XXH64_hash_t seed)
5452{
5453 return XXH3_128bits_internal(input, len, seed,
5454 XXH3_kSecret, sizeof(XXH3_kSecret),
5455 XXH3_hashLong_128b_withSeed);
5456}
5457
5458/*! @ingroup xxh3_family */
5459XXH_PUBLIC_API XXH128_hash_t
5460XXH3_128bits_withSecretandSeed(const void* input, size_t len, const void* secret, size_t secretSize, XXH64_hash_t seed)
5461{
5462 if (len <= XXH3_MIDSIZE_MAX)
5463 return XXH3_128bits_internal(input, len, seed, XXH3_kSecret, sizeof(XXH3_kSecret), NULL);
5464 return XXH3_hashLong_128b_withSecret(input, len, seed, secret, secretSize);
5465}
5466
5467/*! @ingroup xxh3_family */
5468XXH_PUBLIC_API XXH128_hash_t
5469XXH128(const void* input, size_t len, XXH64_hash_t seed)
5470{
5471 return XXH3_128bits_withSeed(input, len, seed);
5472}
5473
5474
5475/* === XXH3 128-bit streaming === */
5476
5477/*
5478 * All initialization and update functions are identical to 64-bit streaming variant.
5479 * The only difference is the finalization routine.
5480 */
5481
5482/*! @ingroup xxh3_family */
5483XXH_PUBLIC_API XXH_errorcode
5484XXH3_128bits_reset(XXH3_state_t* statePtr)
5485{
5486 return XXH3_64bits_reset(statePtr);
5487}
5488
5489/*! @ingroup xxh3_family */
5490XXH_PUBLIC_API XXH_errorcode
5491XXH3_128bits_reset_withSecret(XXH3_state_t* statePtr, const void* secret, size_t secretSize)
5492{
5493 return XXH3_64bits_reset_withSecret(statePtr, secret, secretSize);
5494}
5495
5496/*! @ingroup xxh3_family */
5497XXH_PUBLIC_API XXH_errorcode
5498XXH3_128bits_reset_withSeed(XXH3_state_t* statePtr, XXH64_hash_t seed)
5499{
5500 return XXH3_64bits_reset_withSeed(statePtr, seed);
5501}
5502
5503/*! @ingroup xxh3_family */
5504XXH_PUBLIC_API XXH_errorcode
5505XXH3_128bits_reset_withSecretandSeed(XXH3_state_t* statePtr, const void* secret, size_t secretSize, XXH64_hash_t seed)
5506{
5507 return XXH3_64bits_reset_withSecretandSeed(statePtr, secret, secretSize, seed);
5508}
5509
5510/*! @ingroup xxh3_family */
5511XXH_PUBLIC_API XXH_errorcode
5512XXH3_128bits_update(XXH3_state_t* state, const void* input, size_t len)
5513{
5514 return XXH3_update(state, (const xxh_u8*)input, len,
5515 XXH3_accumulate_512, XXH3_scrambleAcc);
5516}
5517
5518/*! @ingroup xxh3_family */
5519XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_digest (const XXH3_state_t* state)
5520{
5521 const unsigned char* const secret = (state->extSecret == NULL) ? state->customSecret : state->extSecret;
5522 if (state->totalLen > XXH3_MIDSIZE_MAX) {
5523 XXH_ALIGN(XXH_ACC_ALIGN) XXH64_hash_t acc[XXH_ACC_NB];
5524 XXH3_digest_long(acc, state, secret);
5525 XXH_ASSERT(state->secretLimit + XXH_STRIPE_LEN >= sizeof(acc) + XXH_SECRET_MERGEACCS_START);
5526 { XXH128_hash_t h128;
5527 h128.low64 = XXH3_mergeAccs(acc,
5528 secret + XXH_SECRET_MERGEACCS_START,
5529 (xxh_u64)state->totalLen * XXH_PRIME64_1);
5530 h128.high64 = XXH3_mergeAccs(acc,
5531 secret + state->secretLimit + XXH_STRIPE_LEN
5532 - sizeof(acc) - XXH_SECRET_MERGEACCS_START,
5533 ~((xxh_u64)state->totalLen * XXH_PRIME64_2));
5534 return h128;
5535 }
5536 }
5537 /* len <= XXH3_MIDSIZE_MAX : short code */
5538 if (state->seed)
5539 return XXH3_128bits_withSeed(state->buffer, (size_t)state->totalLen, state->seed);
5540 return XXH3_128bits_withSecret(state->buffer, (size_t)(state->totalLen),
5541 secret, state->secretLimit + XXH_STRIPE_LEN);
5542}
5543
5544/* 128-bit utility functions */
5545
5546#include <string.h> /* memcmp, memcpy */
5547
5548/* return : 1 is equal, 0 if different */
5549/*! @ingroup xxh3_family */
5550XXH_PUBLIC_API int XXH128_isEqual(XXH128_hash_t h1, XXH128_hash_t h2)
5551{
5552 /* note : XXH128_hash_t is compact, it has no padding byte */
5553 return !(memcmp(&h1, &h2, sizeof(h1)));
5554}
5555
5556/* This prototype is compatible with stdlib's qsort().
5557 * return : >0 if *h128_1 > *h128_2
5558 * <0 if *h128_1 < *h128_2
5559 * =0 if *h128_1 == *h128_2 */
5560/*! @ingroup xxh3_family */
5561XXH_PUBLIC_API int XXH128_cmp(const void* h128_1, const void* h128_2)
5562{
5563 XXH128_hash_t const h1 = *(const XXH128_hash_t*)h128_1;
5564 XXH128_hash_t const h2 = *(const XXH128_hash_t*)h128_2;
5565 int const hcmp = (h1.high64 > h2.high64) - (h2.high64 > h1.high64);
5566 /* note : bets that, in most cases, hash values are different */
5567 if (hcmp) return hcmp;
5568 return (h1.low64 > h2.low64) - (h2.low64 > h1.low64);
5569}
5570
5571
5572/*====== Canonical representation ======*/
5573/*! @ingroup xxh3_family */
5574XXH_PUBLIC_API void
5575XXH128_canonicalFromHash(XXH128_canonical_t* dst, XXH128_hash_t hash)
5576{
5577 XXH_STATIC_ASSERT(sizeof(XXH128_canonical_t) == sizeof(XXH128_hash_t));
5578 if (XXH_CPU_LITTLE_ENDIAN) {
5579 hash.high64 = XXH_swap64(hash.high64);
5580 hash.low64 = XXH_swap64(hash.low64);
5581 }
5582 XXH_memcpy(dst, &hash.high64, sizeof(hash.high64));
5583 XXH_memcpy((char*)dst + sizeof(hash.high64), &hash.low64, sizeof(hash.low64));
5584}
5585
5586/*! @ingroup xxh3_family */
5587XXH_PUBLIC_API XXH128_hash_t
5588XXH128_hashFromCanonical(const XXH128_canonical_t* src)
5589{
5590 XXH128_hash_t h;
5591 h.high64 = XXH_readBE64(src);
5592 h.low64 = XXH_readBE64(src->digest + 8);
5593 return h;
5594}
5595
5596
5597
5598/* ==========================================
5599 * Secret generators
5600 * ==========================================
5601 */
5602#define XXH_MIN(x, y) (((x) > (y)) ? (y) : (x))
5603
5604XXH_FORCE_INLINE void XXH3_combine16(void* dst, XXH128_hash_t h128)
5605{
5606 XXH_writeLE64( dst, XXH_readLE64(dst) ^ h128.low64 );
5607 XXH_writeLE64( (char*)dst+8, XXH_readLE64((char*)dst+8) ^ h128.high64 );
5608}
5609
5610/*! @ingroup xxh3_family */
5611XXH_PUBLIC_API XXH_errorcode
5612XXH3_generateSecret(void* secretBuffer, size_t secretSize, const void* customSeed, size_t customSeedSize)
5613{
5614#if (XXH_DEBUGLEVEL >= 1)
5615 XXH_ASSERT(secretBuffer != NULL);
5616 XXH_ASSERT(secretSize >= XXH3_SECRET_SIZE_MIN);
5617#else
5618 /* production mode, assert() are disabled */
5619 if (secretBuffer == NULL) return XXH_ERROR;
5620 if (secretSize < XXH3_SECRET_SIZE_MIN) return XXH_ERROR;
5621#endif
5622
5623 if (customSeedSize == 0) {
5624 customSeed = XXH3_kSecret;
5625 customSeedSize = XXH_SECRET_DEFAULT_SIZE;
5626 }
5627#if (XXH_DEBUGLEVEL >= 1)
5628 XXH_ASSERT(customSeed != NULL);
5629#else
5630 if (customSeed == NULL) return XXH_ERROR;
5631#endif
5632
5633 /* Fill secretBuffer with a copy of customSeed - repeat as needed */
5634 { size_t pos = 0;
5635 while (pos < secretSize) {
5636 size_t const toCopy = XXH_MIN((secretSize - pos), customSeedSize);
5637 memcpy((char*)secretBuffer + pos, customSeed, toCopy);
5638 pos += toCopy;
5639 } }
5640
5641 { size_t const nbSeg16 = secretSize / 16;
5642 size_t n;
5643 XXH128_canonical_t scrambler;
5644 XXH128_canonicalFromHash(&scrambler, XXH128(customSeed, customSeedSize, 0));
5645 for (n=0; n<nbSeg16; n++) {
5646 XXH128_hash_t const h128 = XXH128(&scrambler, sizeof(scrambler), n);
5647 XXH3_combine16((char*)secretBuffer + n*16, h128);
5648 }
5649 /* last segment */
5650 XXH3_combine16((char*)secretBuffer + secretSize - 16, XXH128_hashFromCanonical(&scrambler));
5651 }
5652 return XXH_OK;
5653}
5654
5655/*! @ingroup xxh3_family */
5656XXH_PUBLIC_API void
5657XXH3_generateSecret_fromSeed(void* secretBuffer, XXH64_hash_t seed)
5658{
5659 XXH_ALIGN(XXH_SEC_ALIGN) xxh_u8 secret[XXH_SECRET_DEFAULT_SIZE];
5660 XXH3_initCustomSecret(secret, seed);
5661 XXH_ASSERT(secretBuffer != NULL);
5662 memcpy(secretBuffer, secret, XXH_SECRET_DEFAULT_SIZE);
5663}
5664
5665
5666
5667/* Pop our optimization override from above */
5668#if XXH_VECTOR == XXH_AVX2 /* AVX2 */ \
5669 && defined(__GNUC__) && !defined(__clang__) /* GCC, not Clang */ \
5670 && defined(__OPTIMIZE__) && !defined(__OPTIMIZE_SIZE__) /* respect -O0 and -Os */
5671# pragma GCC pop_options
5672#endif
5673
5674#endif /* XXH_NO_LONG_LONG */
5675
5676#endif /* XXH_NO_XXH3 */
5677
5678/*!
5679 * @}
5680 */
5681#endif /* XXH_IMPLEMENTATION */
5682
5683
5684#if defined (__cplusplus)
5685}
5686#endif
stage1/zstd/lib/common/zstd_common.c created+83
......@@ -0,0 +1,83 @@
1/*
2 * Copyright (c) Yann Collet, Facebook, Inc.
3 * All rights reserved.
4 *
5 * This source code is licensed under both the BSD-style license (found in the
6 * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7 * in the COPYING file in the root directory of this source tree).
8 * You may select, at your option, one of the above-listed licenses.
9 */
10
11
12
13/*-*************************************
14* Dependencies
15***************************************/
16#define ZSTD_DEPS_NEED_MALLOC
17#include "zstd_deps.h" /* ZSTD_malloc, ZSTD_calloc, ZSTD_free, ZSTD_memset */
18#include "error_private.h"
19#include "zstd_internal.h"
20
21
22/*-****************************************
23* Version
24******************************************/
25unsigned ZSTD_versionNumber(void) { return ZSTD_VERSION_NUMBER; }
26
27const char* ZSTD_versionString(void) { return ZSTD_VERSION_STRING; }
28
29
30/*-****************************************
31* ZSTD Error Management
32******************************************/
33#undef ZSTD_isError /* defined within zstd_internal.h */
34/*! ZSTD_isError() :
35 * tells if a return value is an error code
36 * symbol is required for external callers */
37unsigned ZSTD_isError(size_t code) { return ERR_isError(code); }
38
39/*! ZSTD_getErrorName() :
40 * provides error code string from function result (useful for debugging) */
41const char* ZSTD_getErrorName(size_t code) { return ERR_getErrorName(code); }
42
43/*! ZSTD_getError() :
44 * convert a `size_t` function result into a proper ZSTD_errorCode enum */
45ZSTD_ErrorCode ZSTD_getErrorCode(size_t code) { return ERR_getErrorCode(code); }
46
47/*! ZSTD_getErrorString() :
48 * provides error code string from enum */
49const char* ZSTD_getErrorString(ZSTD_ErrorCode code) { return ERR_getErrorString(code); }
50
51
52
53/*=**************************************************************
54* Custom allocator
55****************************************************************/
56void* ZSTD_customMalloc(size_t size, ZSTD_customMem customMem)
57{
58 if (customMem.customAlloc)
59 return customMem.customAlloc(customMem.opaque, size);
60 return ZSTD_malloc(size);
61}
62
63void* ZSTD_customCalloc(size_t size, ZSTD_customMem customMem)
64{
65 if (customMem.customAlloc) {
66 /* calloc implemented as malloc+memset;
67 * not as efficient as calloc, but next best guess for custom malloc */
68 void* const ptr = customMem.customAlloc(customMem.opaque, size);
69 ZSTD_memset(ptr, 0, size);
70 return ptr;
71 }
72 return ZSTD_calloc(1, size);
73}
74
75void ZSTD_customFree(void* ptr, ZSTD_customMem customMem)
76{
77 if (ptr!=NULL) {
78 if (customMem.customFree)
79 customMem.customFree(customMem.opaque, ptr);
80 else
81 ZSTD_free(ptr);
82 }
83}
stage1/zstd/lib/common/zstd_deps.h created+111
......@@ -0,0 +1,111 @@
1/*
2 * Copyright (c) Facebook, Inc.
3 * All rights reserved.
4 *
5 * This source code is licensed under both the BSD-style license (found in the
6 * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7 * in the COPYING file in the root directory of this source tree).
8 * You may select, at your option, one of the above-listed licenses.
9 */
10
11/* This file provides common libc dependencies that zstd requires.
12 * The purpose is to allow replacing this file with a custom implementation
13 * to compile zstd without libc support.
14 */
15
16/* Need:
17 * NULL
18 * INT_MAX
19 * UINT_MAX
20 * ZSTD_memcpy()
21 * ZSTD_memset()
22 * ZSTD_memmove()
23 */
24#ifndef ZSTD_DEPS_COMMON
25#define ZSTD_DEPS_COMMON
26
27#include <limits.h>
28#include <stddef.h>
29#include <string.h>
30
31#if defined(__GNUC__) && __GNUC__ >= 4
32# define ZSTD_memcpy(d,s,l) __builtin_memcpy((d),(s),(l))
33# define ZSTD_memmove(d,s,l) __builtin_memmove((d),(s),(l))
34# define ZSTD_memset(p,v,l) __builtin_memset((p),(v),(l))
35#else
36# define ZSTD_memcpy(d,s,l) memcpy((d),(s),(l))
37# define ZSTD_memmove(d,s,l) memmove((d),(s),(l))
38# define ZSTD_memset(p,v,l) memset((p),(v),(l))
39#endif
40
41#endif /* ZSTD_DEPS_COMMON */
42
43/* Need:
44 * ZSTD_malloc()
45 * ZSTD_free()
46 * ZSTD_calloc()
47 */
48#ifdef ZSTD_DEPS_NEED_MALLOC
49#ifndef ZSTD_DEPS_MALLOC
50#define ZSTD_DEPS_MALLOC
51
52#include <stdlib.h>
53
54#define ZSTD_malloc(s) malloc(s)
55#define ZSTD_calloc(n,s) calloc((n), (s))
56#define ZSTD_free(p) free((p))
57
58#endif /* ZSTD_DEPS_MALLOC */
59#endif /* ZSTD_DEPS_NEED_MALLOC */
60
61/*
62 * Provides 64-bit math support.
63 * Need:
64 * U64 ZSTD_div64(U64 dividend, U32 divisor)
65 */
66#ifdef ZSTD_DEPS_NEED_MATH64
67#ifndef ZSTD_DEPS_MATH64
68#define ZSTD_DEPS_MATH64
69
70#define ZSTD_div64(dividend, divisor) ((dividend) / (divisor))
71
72#endif /* ZSTD_DEPS_MATH64 */
73#endif /* ZSTD_DEPS_NEED_MATH64 */
74
75/* Need:
76 * assert()
77 */
78#ifdef ZSTD_DEPS_NEED_ASSERT
79#ifndef ZSTD_DEPS_ASSERT
80#define ZSTD_DEPS_ASSERT
81
82#include <assert.h>
83
84#endif /* ZSTD_DEPS_ASSERT */
85#endif /* ZSTD_DEPS_NEED_ASSERT */
86
87/* Need:
88 * ZSTD_DEBUG_PRINT()
89 */
90#ifdef ZSTD_DEPS_NEED_IO
91#ifndef ZSTD_DEPS_IO
92#define ZSTD_DEPS_IO
93
94#include <stdio.h>
95#define ZSTD_DEBUG_PRINT(...) fprintf(stderr, __VA_ARGS__)
96
97#endif /* ZSTD_DEPS_IO */
98#endif /* ZSTD_DEPS_NEED_IO */
99
100/* Only requested when <stdint.h> is known to be present.
101 * Need:
102 * intptr_t
103 */
104#ifdef ZSTD_DEPS_NEED_STDINT
105#ifndef ZSTD_DEPS_STDINT
106#define ZSTD_DEPS_STDINT
107
108#include <stdint.h>
109
110#endif /* ZSTD_DEPS_STDINT */
111#endif /* ZSTD_DEPS_NEED_STDINT */
stage1/zstd/lib/common/zstd_internal.h created+493
......@@ -0,0 +1,493 @@
1/*
2 * Copyright (c) Yann Collet, Facebook, Inc.
3 * All rights reserved.
4 *
5 * This source code is licensed under both the BSD-style license (found in the
6 * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7 * in the COPYING file in the root directory of this source tree).
8 * You may select, at your option, one of the above-listed licenses.
9 */
10
11#ifndef ZSTD_CCOMMON_H_MODULE
12#define ZSTD_CCOMMON_H_MODULE
13
14/* this module contains definitions which must be identical
15 * across compression, decompression and dictBuilder.
16 * It also contains a few functions useful to at least 2 of them
17 * and which benefit from being inlined */
18
19/*-*************************************
20* Dependencies
21***************************************/
22#include "compiler.h"
23#include "cpu.h"
24#include "mem.h"
25#include "debug.h" /* assert, DEBUGLOG, RAWLOG, g_debuglevel */
26#include "error_private.h"
27#define ZSTD_STATIC_LINKING_ONLY
28#include "../zstd.h"
29#define FSE_STATIC_LINKING_ONLY
30#include "fse.h"
31#define HUF_STATIC_LINKING_ONLY
32#include "huf.h"
33#ifndef XXH_STATIC_LINKING_ONLY
34# define XXH_STATIC_LINKING_ONLY /* XXH64_state_t */
35#endif
36#include "xxhash.h" /* XXH_reset, update, digest */
37#ifndef ZSTD_NO_TRACE
38# include "zstd_trace.h"
39#else
40# define ZSTD_TRACE 0
41#endif
42
43#if defined (__cplusplus)
44extern "C" {
45#endif
46
47/* ---- static assert (debug) --- */
48#define ZSTD_STATIC_ASSERT(c) DEBUG_STATIC_ASSERT(c)
49#define ZSTD_isError ERR_isError /* for inlining */
50#define FSE_isError ERR_isError
51#define HUF_isError ERR_isError
52
53
54/*-*************************************
55* shared macros
56***************************************/
57#undef MIN
58#undef MAX
59#define MIN(a,b) ((a)<(b) ? (a) : (b))
60#define MAX(a,b) ((a)>(b) ? (a) : (b))
61#define BOUNDED(min,val,max) (MAX(min,MIN(val,max)))
62
63
64/*-*************************************
65* Common constants
66***************************************/
67#define ZSTD_OPT_NUM (1<<12)
68
69#define ZSTD_REP_NUM 3 /* number of repcodes */
70static UNUSED_ATTR const U32 repStartValue[ZSTD_REP_NUM] = { 1, 4, 8 };
71
72#define KB *(1 <<10)
73#define MB *(1 <<20)
74#define GB *(1U<<30)
75
76#define BIT7 128
77#define BIT6 64
78#define BIT5 32
79#define BIT4 16
80#define BIT1 2
81#define BIT0 1
82
83#define ZSTD_WINDOWLOG_ABSOLUTEMIN 10
84static UNUSED_ATTR const size_t ZSTD_fcs_fieldSize[4] = { 0, 2, 4, 8 };
85static UNUSED_ATTR const size_t ZSTD_did_fieldSize[4] = { 0, 1, 2, 4 };
86
87#define ZSTD_FRAMEIDSIZE 4 /* magic number size */
88
89#define ZSTD_BLOCKHEADERSIZE 3 /* C standard doesn't allow `static const` variable to be init using another `static const` variable */
90static UNUSED_ATTR const size_t ZSTD_blockHeaderSize = ZSTD_BLOCKHEADERSIZE;
91typedef enum { bt_raw, bt_rle, bt_compressed, bt_reserved } blockType_e;
92
93#define ZSTD_FRAMECHECKSUMSIZE 4
94
95#define MIN_SEQUENCES_SIZE 1 /* nbSeq==0 */
96#define MIN_CBLOCK_SIZE (1 /*litCSize*/ + 1 /* RLE or RAW */ + MIN_SEQUENCES_SIZE /* nbSeq==0 */) /* for a non-null block */
97
98#define HufLog 12
99typedef enum { set_basic, set_rle, set_compressed, set_repeat } symbolEncodingType_e;
100
101#define LONGNBSEQ 0x7F00
102
103#define MINMATCH 3
104
105#define Litbits 8
106#define MaxLit ((1<<Litbits) - 1)
107#define MaxML 52
108#define MaxLL 35
109#define DefaultMaxOff 28
110#define MaxOff 31
111#define MaxSeq MAX(MaxLL, MaxML) /* Assumption : MaxOff < MaxLL,MaxML */
112#define MLFSELog 9
113#define LLFSELog 9
114#define OffFSELog 8
115#define MaxFSELog MAX(MAX(MLFSELog, LLFSELog), OffFSELog)
116
117#define ZSTD_MAX_HUF_HEADER_SIZE 128 /* header + <= 127 byte tree description */
118/* Each table cannot take more than #symbols * FSELog bits */
119#define ZSTD_MAX_FSE_HEADERS_SIZE (((MaxML + 1) * MLFSELog + (MaxLL + 1) * LLFSELog + (MaxOff + 1) * OffFSELog + 7) / 8)
120
121static UNUSED_ATTR const U8 LL_bits[MaxLL+1] = {
122 0, 0, 0, 0, 0, 0, 0, 0,
123 0, 0, 0, 0, 0, 0, 0, 0,
124 1, 1, 1, 1, 2, 2, 3, 3,
125 4, 6, 7, 8, 9,10,11,12,
126 13,14,15,16
127};
128static UNUSED_ATTR const S16 LL_defaultNorm[MaxLL+1] = {
129 4, 3, 2, 2, 2, 2, 2, 2,
130 2, 2, 2, 2, 2, 1, 1, 1,
131 2, 2, 2, 2, 2, 2, 2, 2,
132 2, 3, 2, 1, 1, 1, 1, 1,
133 -1,-1,-1,-1
134};
135#define LL_DEFAULTNORMLOG 6 /* for static allocation */
136static UNUSED_ATTR const U32 LL_defaultNormLog = LL_DEFAULTNORMLOG;
137
138static UNUSED_ATTR const U8 ML_bits[MaxML+1] = {
139 0, 0, 0, 0, 0, 0, 0, 0,
140 0, 0, 0, 0, 0, 0, 0, 0,
141 0, 0, 0, 0, 0, 0, 0, 0,
142 0, 0, 0, 0, 0, 0, 0, 0,
143 1, 1, 1, 1, 2, 2, 3, 3,
144 4, 4, 5, 7, 8, 9,10,11,
145 12,13,14,15,16
146};
147static UNUSED_ATTR const S16 ML_defaultNorm[MaxML+1] = {
148 1, 4, 3, 2, 2, 2, 2, 2,
149 2, 1, 1, 1, 1, 1, 1, 1,
150 1, 1, 1, 1, 1, 1, 1, 1,
151 1, 1, 1, 1, 1, 1, 1, 1,
152 1, 1, 1, 1, 1, 1, 1, 1,
153 1, 1, 1, 1, 1, 1,-1,-1,
154 -1,-1,-1,-1,-1
155};
156#define ML_DEFAULTNORMLOG 6 /* for static allocation */
157static UNUSED_ATTR const U32 ML_defaultNormLog = ML_DEFAULTNORMLOG;
158
159static UNUSED_ATTR const S16 OF_defaultNorm[DefaultMaxOff+1] = {
160 1, 1, 1, 1, 1, 1, 2, 2,
161 2, 1, 1, 1, 1, 1, 1, 1,
162 1, 1, 1, 1, 1, 1, 1, 1,
163 -1,-1,-1,-1,-1
164};
165#define OF_DEFAULTNORMLOG 5 /* for static allocation */
166static UNUSED_ATTR const U32 OF_defaultNormLog = OF_DEFAULTNORMLOG;
167
168
169/*-*******************************************
170* Shared functions to include for inlining
171*********************************************/
172static void ZSTD_copy8(void* dst, const void* src) {
173#if defined(ZSTD_ARCH_ARM_NEON)
174 vst1_u8((uint8_t*)dst, vld1_u8((const uint8_t*)src));
175#else
176 ZSTD_memcpy(dst, src, 8);
177#endif
178}
179#define COPY8(d,s) { ZSTD_copy8(d,s); d+=8; s+=8; }
180
181/* Need to use memmove here since the literal buffer can now be located within
182 the dst buffer. In circumstances where the op "catches up" to where the
183 literal buffer is, there can be partial overlaps in this call on the final
184 copy if the literal is being shifted by less than 16 bytes. */
185static void ZSTD_copy16(void* dst, const void* src) {
186#if defined(ZSTD_ARCH_ARM_NEON)
187 vst1q_u8((uint8_t*)dst, vld1q_u8((const uint8_t*)src));
188#elif defined(ZSTD_ARCH_X86_SSE2)
189 _mm_storeu_si128((__m128i*)dst, _mm_loadu_si128((const __m128i*)src));
190#elif defined(__clang__)
191 ZSTD_memmove(dst, src, 16);
192#else
193 /* ZSTD_memmove is not inlined properly by gcc */
194 BYTE copy16_buf[16];
195 ZSTD_memcpy(copy16_buf, src, 16);
196 ZSTD_memcpy(dst, copy16_buf, 16);
197#endif
198}
199#define COPY16(d,s) { ZSTD_copy16(d,s); d+=16; s+=16; }
200
201#define WILDCOPY_OVERLENGTH 32
202#define WILDCOPY_VECLEN 16
203
204typedef enum {
205 ZSTD_no_overlap,
206 ZSTD_overlap_src_before_dst
207 /* ZSTD_overlap_dst_before_src, */
208} ZSTD_overlap_e;
209
210/*! ZSTD_wildcopy() :
211 * Custom version of ZSTD_memcpy(), can over read/write up to WILDCOPY_OVERLENGTH bytes (if length==0)
212 * @param ovtype controls the overlap detection
213 * - ZSTD_no_overlap: The source and destination are guaranteed to be at least WILDCOPY_VECLEN bytes apart.
214 * - ZSTD_overlap_src_before_dst: The src and dst may overlap, but they MUST be at least 8 bytes apart.
215 * The src buffer must be before the dst buffer.
216 */
217MEM_STATIC FORCE_INLINE_ATTR
218void ZSTD_wildcopy(void* dst, const void* src, ptrdiff_t length, ZSTD_overlap_e const ovtype)
219{
220 ptrdiff_t diff = (BYTE*)dst - (const BYTE*)src;
221 const BYTE* ip = (const BYTE*)src;
222 BYTE* op = (BYTE*)dst;
223 BYTE* const oend = op + length;
224
225 if (ovtype == ZSTD_overlap_src_before_dst && diff < WILDCOPY_VECLEN) {
226 /* Handle short offset copies. */
227 do {
228 COPY8(op, ip)
229 } while (op < oend);
230 } else {
231 assert(diff >= WILDCOPY_VECLEN || diff <= -WILDCOPY_VECLEN);
232 /* Separate out the first COPY16() call because the copy length is
233 * almost certain to be short, so the branches have different
234 * probabilities. Since it is almost certain to be short, only do
235 * one COPY16() in the first call. Then, do two calls per loop since
236 * at that point it is more likely to have a high trip count.
237 */
238#ifdef __aarch64__
239 do {
240 COPY16(op, ip);
241 }
242 while (op < oend);
243#else
244 ZSTD_copy16(op, ip);
245 if (16 >= length) return;
246 op += 16;
247 ip += 16;
248 do {
249 COPY16(op, ip);
250 COPY16(op, ip);
251 }
252 while (op < oend);
253#endif
254 }
255}
256
257MEM_STATIC size_t ZSTD_limitCopy(void* dst, size_t dstCapacity, const void* src, size_t srcSize)
258{
259 size_t const length = MIN(dstCapacity, srcSize);
260 if (length > 0) {
261 ZSTD_memcpy(dst, src, length);
262 }
263 return length;
264}
265
266/* define "workspace is too large" as this number of times larger than needed */
267#define ZSTD_WORKSPACETOOLARGE_FACTOR 3
268
269/* when workspace is continuously too large
270 * during at least this number of times,
271 * context's memory usage is considered wasteful,
272 * because it's sized to handle a worst case scenario which rarely happens.
273 * In which case, resize it down to free some memory */
274#define ZSTD_WORKSPACETOOLARGE_MAXDURATION 128
275
276/* Controls whether the input/output buffer is buffered or stable. */
277typedef enum {
278 ZSTD_bm_buffered = 0, /* Buffer the input/output */
279 ZSTD_bm_stable = 1 /* ZSTD_inBuffer/ZSTD_outBuffer is stable */
280} ZSTD_bufferMode_e;
281
282
283/*-*******************************************
284* Private declarations
285*********************************************/
286typedef struct seqDef_s {
287 U32 offBase; /* offBase == Offset + ZSTD_REP_NUM, or repcode 1,2,3 */
288 U16 litLength;
289 U16 mlBase; /* mlBase == matchLength - MINMATCH */
290} seqDef;
291
292/* Controls whether seqStore has a single "long" litLength or matchLength. See seqStore_t. */
293typedef enum {
294 ZSTD_llt_none = 0, /* no longLengthType */
295 ZSTD_llt_literalLength = 1, /* represents a long literal */
296 ZSTD_llt_matchLength = 2 /* represents a long match */
297} ZSTD_longLengthType_e;
298
299typedef struct {
300 seqDef* sequencesStart;
301 seqDef* sequences; /* ptr to end of sequences */
302 BYTE* litStart;
303 BYTE* lit; /* ptr to end of literals */
304 BYTE* llCode;
305 BYTE* mlCode;
306 BYTE* ofCode;
307 size_t maxNbSeq;
308 size_t maxNbLit;
309
310 /* longLengthPos and longLengthType to allow us to represent either a single litLength or matchLength
311 * in the seqStore that has a value larger than U16 (if it exists). To do so, we increment
312 * the existing value of the litLength or matchLength by 0x10000.
313 */
314 ZSTD_longLengthType_e longLengthType;
315 U32 longLengthPos; /* Index of the sequence to apply long length modification to */
316} seqStore_t;
317
318typedef struct {
319 U32 litLength;
320 U32 matchLength;
321} ZSTD_sequenceLength;
322
323/**
324 * Returns the ZSTD_sequenceLength for the given sequences. It handles the decoding of long sequences
325 * indicated by longLengthPos and longLengthType, and adds MINMATCH back to matchLength.
326 */
327MEM_STATIC ZSTD_sequenceLength ZSTD_getSequenceLength(seqStore_t const* seqStore, seqDef const* seq)
328{
329 ZSTD_sequenceLength seqLen;
330 seqLen.litLength = seq->litLength;
331 seqLen.matchLength = seq->mlBase + MINMATCH;
332 if (seqStore->longLengthPos == (U32)(seq - seqStore->sequencesStart)) {
333 if (seqStore->longLengthType == ZSTD_llt_literalLength) {
334 seqLen.litLength += 0xFFFF;
335 }
336 if (seqStore->longLengthType == ZSTD_llt_matchLength) {
337 seqLen.matchLength += 0xFFFF;
338 }
339 }
340 return seqLen;
341}
342
343/**
344 * Contains the compressed frame size and an upper-bound for the decompressed frame size.
345 * Note: before using `compressedSize`, check for errors using ZSTD_isError().
346 * similarly, before using `decompressedBound`, check for errors using:
347 * `decompressedBound != ZSTD_CONTENTSIZE_ERROR`
348 */
349typedef struct {
350 size_t compressedSize;
351 unsigned long long decompressedBound;
352} ZSTD_frameSizeInfo; /* decompress & legacy */
353
354const seqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx); /* compress & dictBuilder */
355void ZSTD_seqToCodes(const seqStore_t* seqStorePtr); /* compress, dictBuilder, decodeCorpus (shouldn't get its definition from here) */
356
357/* custom memory allocation functions */
358void* ZSTD_customMalloc(size_t size, ZSTD_customMem customMem);
359void* ZSTD_customCalloc(size_t size, ZSTD_customMem customMem);
360void ZSTD_customFree(void* ptr, ZSTD_customMem customMem);
361
362
363MEM_STATIC U32 ZSTD_highbit32(U32 val) /* compress, dictBuilder, decodeCorpus */
364{
365 assert(val != 0);
366 {
367# if defined(_MSC_VER) /* Visual */
368# if STATIC_BMI2 == 1
369 return _lzcnt_u32(val)^31;
370# else
371 if (val != 0) {
372 unsigned long r;
373 _BitScanReverse(&r, val);
374 return (unsigned)r;
375 } else {
376 /* Should not reach this code path */
377 __assume(0);
378 }
379# endif
380# elif defined(__GNUC__) && (__GNUC__ >= 3) /* GCC Intrinsic */
381 return __builtin_clz (val) ^ 31;
382# elif defined(__ICCARM__) /* IAR Intrinsic */
383 return 31 - __CLZ(val);
384# else /* Software version */
385 static const U32 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 };
386 U32 v = val;
387 v |= v >> 1;
388 v |= v >> 2;
389 v |= v >> 4;
390 v |= v >> 8;
391 v |= v >> 16;
392 return DeBruijnClz[(v * 0x07C4ACDDU) >> 27];
393# endif
394 }
395}
396
397/**
398 * Counts the number of trailing zeros of a `size_t`.
399 * Most compilers should support CTZ as a builtin. A backup
400 * implementation is provided if the builtin isn't supported, but
401 * it may not be terribly efficient.
402 */
403MEM_STATIC unsigned ZSTD_countTrailingZeros(size_t val)
404{
405 if (MEM_64bits()) {
406# if defined(_MSC_VER) && defined(_WIN64)
407# if STATIC_BMI2
408 return _tzcnt_u64(val);
409# else
410 if (val != 0) {
411 unsigned long r;
412 _BitScanForward64(&r, (U64)val);
413 return (unsigned)r;
414 } else {
415 /* Should not reach this code path */
416 __assume(0);
417 }
418# endif
419# elif defined(__GNUC__) && (__GNUC__ >= 4)
420 return __builtin_ctzll((U64)val);
421# else
422 static const int DeBruijnBytePos[64] = { 0, 1, 2, 7, 3, 13, 8, 19,
423 4, 25, 14, 28, 9, 34, 20, 56,
424 5, 17, 26, 54, 15, 41, 29, 43,
425 10, 31, 38, 35, 21, 45, 49, 57,
426 63, 6, 12, 18, 24, 27, 33, 55,
427 16, 53, 40, 42, 30, 37, 44, 48,
428 62, 11, 23, 32, 52, 39, 36, 47,
429 61, 22, 51, 46, 60, 50, 59, 58 };
430 return DeBruijnBytePos[((U64)((val & -(long long)val) * 0x0218A392CDABBD3FULL)) >> 58];
431# endif
432 } else { /* 32 bits */
433# if defined(_MSC_VER)
434 if (val != 0) {
435 unsigned long r;
436 _BitScanForward(&r, (U32)val);
437 return (unsigned)r;
438 } else {
439 /* Should not reach this code path */
440 __assume(0);
441 }
442# elif defined(__GNUC__) && (__GNUC__ >= 3)
443 return __builtin_ctz((U32)val);
444# else
445 static const int DeBruijnBytePos[32] = { 0, 1, 28, 2, 29, 14, 24, 3,
446 30, 22, 20, 15, 25, 17, 4, 8,
447 31, 27, 13, 23, 21, 19, 16, 7,
448 26, 12, 18, 6, 11, 5, 10, 9 };
449 return DeBruijnBytePos[((U32)((val & -(S32)val) * 0x077CB531U)) >> 27];
450# endif
451 }
452}
453
454
455/* ZSTD_invalidateRepCodes() :
456 * ensures next compression will not use repcodes from previous block.
457 * Note : only works with regular variant;
458 * do not use with extDict variant ! */
459void ZSTD_invalidateRepCodes(ZSTD_CCtx* cctx); /* zstdmt, adaptive_compression (shouldn't get this definition from here) */
460
461
462typedef struct {
463 blockType_e blockType;
464 U32 lastBlock;
465 U32 origSize;
466} blockProperties_t; /* declared here for decompress and fullbench */
467
468/*! ZSTD_getcBlockSize() :
469 * Provides the size of compressed block from block header `src` */
470/* Used by: decompress, fullbench (does not get its definition from here) */
471size_t ZSTD_getcBlockSize(const void* src, size_t srcSize,
472 blockProperties_t* bpPtr);
473
474/*! ZSTD_decodeSeqHeaders() :
475 * decode sequence header from src */
476/* Used by: decompress, fullbench (does not get its definition from here) */
477size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr,
478 const void* src, size_t srcSize);
479
480/**
481 * @returns true iff the CPU supports dynamic BMI2 dispatch.
482 */
483MEM_STATIC int ZSTD_cpuSupportsBmi2(void)
484{
485 ZSTD_cpuid_t cpuid = ZSTD_cpuid();
486 return ZSTD_cpuid_bmi1(cpuid) && ZSTD_cpuid_bmi2(cpuid);
487}
488
489#if defined (__cplusplus)
490}
491#endif
492
493#endif /* ZSTD_CCOMMON_H_MODULE */
stage1/zstd/lib/common/zstd_trace.h created+163
......@@ -0,0 +1,163 @@
1/*
2 * Copyright (c) Facebook, Inc.
3 * All rights reserved.
4 *
5 * This source code is licensed under both the BSD-style license (found in the
6 * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7 * in the COPYING file in the root directory of this source tree).
8 * You may select, at your option, one of the above-listed licenses.
9 */
10
11#ifndef ZSTD_TRACE_H
12#define ZSTD_TRACE_H
13
14#if defined (__cplusplus)
15extern "C" {
16#endif
17
18#include <stddef.h>
19
20/* weak symbol support
21 * For now, enable conservatively:
22 * - Only GNUC
23 * - Only ELF
24 * - Only x86-64 and i386
25 * Also, explicitly disable on platforms known not to work so they aren't
26 * forgotten in the future.
27 */
28#if !defined(ZSTD_HAVE_WEAK_SYMBOLS) && \
29 defined(__GNUC__) && defined(__ELF__) && \
30 (defined(__x86_64__) || defined(_M_X64) || defined(__i386__) || defined(_M_IX86)) && \
31 !defined(__APPLE__) && !defined(_WIN32) && !defined(__MINGW32__) && \
32 !defined(__CYGWIN__) && !defined(_AIX)
33# define ZSTD_HAVE_WEAK_SYMBOLS 1
34#else
35# define ZSTD_HAVE_WEAK_SYMBOLS 0
36#endif
37#if ZSTD_HAVE_WEAK_SYMBOLS
38# define ZSTD_WEAK_ATTR __attribute__((__weak__))
39#else
40# define ZSTD_WEAK_ATTR
41#endif
42
43/* Only enable tracing when weak symbols are available. */
44#ifndef ZSTD_TRACE
45# define ZSTD_TRACE ZSTD_HAVE_WEAK_SYMBOLS
46#endif
47
48#if ZSTD_TRACE
49
50struct ZSTD_CCtx_s;
51struct ZSTD_DCtx_s;
52struct ZSTD_CCtx_params_s;
53
54typedef struct {
55 /**
56 * ZSTD_VERSION_NUMBER
57 *
58 * This is guaranteed to be the first member of ZSTD_trace.
59 * Otherwise, this struct is not stable between versions. If
60 * the version number does not match your expectation, you
61 * should not interpret the rest of the struct.
62 */
63 unsigned version;
64 /**
65 * Non-zero if streaming (de)compression is used.
66 */
67 unsigned streaming;
68 /**
69 * The dictionary ID.
70 */
71 unsigned dictionaryID;
72 /**
73 * Is the dictionary cold?
74 * Only set on decompression.
75 */
76 unsigned dictionaryIsCold;
77 /**
78 * The dictionary size or zero if no dictionary.
79 */
80 size_t dictionarySize;
81 /**
82 * The uncompressed size of the data.
83 */
84 size_t uncompressedSize;
85 /**
86 * The compressed size of the data.
87 */
88 size_t compressedSize;
89 /**
90 * The fully resolved CCtx parameters (NULL on decompression).
91 */
92 struct ZSTD_CCtx_params_s const* params;
93 /**
94 * The ZSTD_CCtx pointer (NULL on decompression).
95 */
96 struct ZSTD_CCtx_s const* cctx;
97 /**
98 * The ZSTD_DCtx pointer (NULL on compression).
99 */
100 struct ZSTD_DCtx_s const* dctx;
101} ZSTD_Trace;
102
103/**
104 * A tracing context. It must be 0 when tracing is disabled.
105 * Otherwise, any non-zero value returned by a tracing begin()
106 * function is presented to any subsequent calls to end().
107 *
108 * Any non-zero value is treated as tracing is enabled and not
109 * interpreted by the library.
110 *
111 * Two possible uses are:
112 * * A timestamp for when the begin() function was called.
113 * * A unique key identifying the (de)compression, like the
114 * address of the [dc]ctx pointer if you need to track
115 * more information than just a timestamp.
116 */
117typedef unsigned long long ZSTD_TraceCtx;
118
119/**
120 * Trace the beginning of a compression call.
121 * @param cctx The dctx pointer for the compression.
122 * It can be used as a key to map begin() to end().
123 * @returns Non-zero if tracing is enabled. The return value is
124 * passed to ZSTD_trace_compress_end().
125 */
126ZSTD_WEAK_ATTR ZSTD_TraceCtx ZSTD_trace_compress_begin(
127 struct ZSTD_CCtx_s const* cctx);
128
129/**
130 * Trace the end of a compression call.
131 * @param ctx The return value of ZSTD_trace_compress_begin().
132 * @param trace The zstd tracing info.
133 */
134ZSTD_WEAK_ATTR void ZSTD_trace_compress_end(
135 ZSTD_TraceCtx ctx,
136 ZSTD_Trace const* trace);
137
138/**
139 * Trace the beginning of a decompression call.
140 * @param dctx The dctx pointer for the decompression.
141 * It can be used as a key to map begin() to end().
142 * @returns Non-zero if tracing is enabled. The return value is
143 * passed to ZSTD_trace_compress_end().
144 */
145ZSTD_WEAK_ATTR ZSTD_TraceCtx ZSTD_trace_decompress_begin(
146 struct ZSTD_DCtx_s const* dctx);
147
148/**
149 * Trace the end of a decompression call.
150 * @param ctx The return value of ZSTD_trace_decompress_begin().
151 * @param trace The zstd tracing info.
152 */
153ZSTD_WEAK_ATTR void ZSTD_trace_decompress_end(
154 ZSTD_TraceCtx ctx,
155 ZSTD_Trace const* trace);
156
157#endif /* ZSTD_TRACE */
158
159#if defined (__cplusplus)
160}
161#endif
162
163#endif /* ZSTD_TRACE_H */
stage1/zstd/lib/decompress/huf_decompress.c created+1889
......@@ -0,0 +1,1889 @@
1/* ******************************************************************
2 * huff0 huffman decoder,
3 * part of Finite State Entropy library
4 * Copyright (c) Yann Collet, Facebook, Inc.
5 *
6 * You can contact the author at :
7 * - FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy
8 *
9 * This source code is licensed under both the BSD-style license (found in the
10 * LICENSE file in the root directory of this source tree) and the GPLv2 (found
11 * in the COPYING file in the root directory of this source tree).
12 * You may select, at your option, one of the above-listed licenses.
13****************************************************************** */
14
15/* **************************************************************
16* Dependencies
17****************************************************************/
18#include "../common/zstd_deps.h" /* ZSTD_memcpy, ZSTD_memset */
19#include "../common/compiler.h"
20#include "../common/bitstream.h" /* BIT_* */
21#include "../common/fse.h" /* to compress headers */
22#define HUF_STATIC_LINKING_ONLY
23#include "../common/huf.h"
24#include "../common/error_private.h"
25#include "../common/zstd_internal.h"
26
27/* **************************************************************
28* Constants
29****************************************************************/
30
31#define HUF_DECODER_FAST_TABLELOG 11
32
33/* **************************************************************
34* Macros
35****************************************************************/
36
37/* These two optional macros force the use one way or another of the two
38 * Huffman decompression implementations. You can't force in both directions
39 * at the same time.
40 */
41#if defined(HUF_FORCE_DECOMPRESS_X1) && \
42 defined(HUF_FORCE_DECOMPRESS_X2)
43#error "Cannot force the use of the X1 and X2 decoders at the same time!"
44#endif
45
46#if ZSTD_ENABLE_ASM_X86_64_BMI2 && DYNAMIC_BMI2
47# define HUF_ASM_X86_64_BMI2_ATTRS BMI2_TARGET_ATTRIBUTE
48#else
49# define HUF_ASM_X86_64_BMI2_ATTRS
50#endif
51
52#ifdef __cplusplus
53# define HUF_EXTERN_C extern "C"
54#else
55# define HUF_EXTERN_C
56#endif
57#define HUF_ASM_DECL HUF_EXTERN_C
58
59#if DYNAMIC_BMI2 || (ZSTD_ENABLE_ASM_X86_64_BMI2 && defined(__BMI2__))
60# define HUF_NEED_BMI2_FUNCTION 1
61#else
62# define HUF_NEED_BMI2_FUNCTION 0
63#endif
64
65#if !(ZSTD_ENABLE_ASM_X86_64_BMI2 && defined(__BMI2__))
66# define HUF_NEED_DEFAULT_FUNCTION 1
67#else
68# define HUF_NEED_DEFAULT_FUNCTION 0
69#endif
70
71/* **************************************************************
72* Error Management
73****************************************************************/
74#define HUF_isError ERR_isError
75
76
77/* **************************************************************
78* Byte alignment for workSpace management
79****************************************************************/
80#define HUF_ALIGN(x, a) HUF_ALIGN_MASK((x), (a) - 1)
81#define HUF_ALIGN_MASK(x, mask) (((x) + (mask)) & ~(mask))
82
83
84/* **************************************************************
85* BMI2 Variant Wrappers
86****************************************************************/
87#if DYNAMIC_BMI2
88
89#define HUF_DGEN(fn) \
90 \
91 static size_t fn##_default( \
92 void* dst, size_t dstSize, \
93 const void* cSrc, size_t cSrcSize, \
94 const HUF_DTable* DTable) \
95 { \
96 return fn##_body(dst, dstSize, cSrc, cSrcSize, DTable); \
97 } \
98 \
99 static BMI2_TARGET_ATTRIBUTE size_t fn##_bmi2( \
100 void* dst, size_t dstSize, \
101 const void* cSrc, size_t cSrcSize, \
102 const HUF_DTable* DTable) \
103 { \
104 return fn##_body(dst, dstSize, cSrc, cSrcSize, DTable); \
105 } \
106 \
107 static size_t fn(void* dst, size_t dstSize, void const* cSrc, \
108 size_t cSrcSize, HUF_DTable const* DTable, int bmi2) \
109 { \
110 if (bmi2) { \
111 return fn##_bmi2(dst, dstSize, cSrc, cSrcSize, DTable); \
112 } \
113 return fn##_default(dst, dstSize, cSrc, cSrcSize, DTable); \
114 }
115
116#else
117
118#define HUF_DGEN(fn) \
119 static size_t fn(void* dst, size_t dstSize, void const* cSrc, \
120 size_t cSrcSize, HUF_DTable const* DTable, int bmi2) \
121 { \
122 (void)bmi2; \
123 return fn##_body(dst, dstSize, cSrc, cSrcSize, DTable); \
124 }
125
126#endif
127
128
129/*-***************************/
130/* generic DTableDesc */
131/*-***************************/
132typedef struct { BYTE maxTableLog; BYTE tableType; BYTE tableLog; BYTE reserved; } DTableDesc;
133
134static DTableDesc HUF_getDTableDesc(const HUF_DTable* table)
135{
136 DTableDesc dtd;
137 ZSTD_memcpy(&dtd, table, sizeof(dtd));
138 return dtd;
139}
140
141#if ZSTD_ENABLE_ASM_X86_64_BMI2
142
143static size_t HUF_initDStream(BYTE const* ip) {
144 BYTE const lastByte = ip[7];
145 size_t const bitsConsumed = lastByte ? 8 - BIT_highbit32(lastByte) : 0;
146 size_t const value = MEM_readLEST(ip) | 1;
147 assert(bitsConsumed <= 8);
148 return value << bitsConsumed;
149}
150typedef struct {
151 BYTE const* ip[4];
152 BYTE* op[4];
153 U64 bits[4];
154 void const* dt;
155 BYTE const* ilimit;
156 BYTE* oend;
157 BYTE const* iend[4];
158} HUF_DecompressAsmArgs;
159
160/**
161 * Initializes args for the asm decoding loop.
162 * @returns 0 on success
163 * 1 if the fallback implementation should be used.
164 * Or an error code on failure.
165 */
166static size_t HUF_DecompressAsmArgs_init(HUF_DecompressAsmArgs* args, void* dst, size_t dstSize, void const* src, size_t srcSize, const HUF_DTable* DTable)
167{
168 void const* dt = DTable + 1;
169 U32 const dtLog = HUF_getDTableDesc(DTable).tableLog;
170
171 const BYTE* const ilimit = (const BYTE*)src + 6 + 8;
172
173 BYTE* const oend = (BYTE*)dst + dstSize;
174
175 /* The following condition is false on x32 platform,
176 * but HUF_asm is not compatible with this ABI */
177 if (!(MEM_isLittleEndian() && !MEM_32bits())) return 1;
178
179 /* strict minimum : jump table + 1 byte per stream */
180 if (srcSize < 10)
181 return ERROR(corruption_detected);
182
183 /* Must have at least 8 bytes per stream because we don't handle initializing smaller bit containers.
184 * If table log is not correct at this point, fallback to the old decoder.
185 * On small inputs we don't have enough data to trigger the fast loop, so use the old decoder.
186 */
187 if (dtLog != HUF_DECODER_FAST_TABLELOG)
188 return 1;
189
190 /* Read the jump table. */
191 {
192 const BYTE* const istart = (const BYTE*)src;
193 size_t const length1 = MEM_readLE16(istart);
194 size_t const length2 = MEM_readLE16(istart+2);
195 size_t const length3 = MEM_readLE16(istart+4);
196 size_t const length4 = srcSize - (length1 + length2 + length3 + 6);
197 args->iend[0] = istart + 6; /* jumpTable */
198 args->iend[1] = args->iend[0] + length1;
199 args->iend[2] = args->iend[1] + length2;
200 args->iend[3] = args->iend[2] + length3;
201
202 /* HUF_initDStream() requires this, and this small of an input
203 * won't benefit from the ASM loop anyways.
204 * length1 must be >= 16 so that ip[0] >= ilimit before the loop
205 * starts.
206 */
207 if (length1 < 16 || length2 < 8 || length3 < 8 || length4 < 8)
208 return 1;
209 if (length4 > srcSize) return ERROR(corruption_detected); /* overflow */
210 }
211 /* ip[] contains the position that is currently loaded into bits[]. */
212 args->ip[0] = args->iend[1] - sizeof(U64);
213 args->ip[1] = args->iend[2] - sizeof(U64);
214 args->ip[2] = args->iend[3] - sizeof(U64);
215 args->ip[3] = (BYTE const*)src + srcSize - sizeof(U64);
216
217 /* op[] contains the output pointers. */
218 args->op[0] = (BYTE*)dst;
219 args->op[1] = args->op[0] + (dstSize+3)/4;
220 args->op[2] = args->op[1] + (dstSize+3)/4;
221 args->op[3] = args->op[2] + (dstSize+3)/4;
222
223 /* No point to call the ASM loop for tiny outputs. */
224 if (args->op[3] >= oend)
225 return 1;
226
227 /* bits[] is the bit container.
228 * It is read from the MSB down to the LSB.
229 * It is shifted left as it is read, and zeros are
230 * shifted in. After the lowest valid bit a 1 is
231 * set, so that CountTrailingZeros(bits[]) can be used
232 * to count how many bits we've consumed.
233 */
234 args->bits[0] = HUF_initDStream(args->ip[0]);
235 args->bits[1] = HUF_initDStream(args->ip[1]);
236 args->bits[2] = HUF_initDStream(args->ip[2]);
237 args->bits[3] = HUF_initDStream(args->ip[3]);
238
239 /* If ip[] >= ilimit, it is guaranteed to be safe to
240 * reload bits[]. It may be beyond its section, but is
241 * guaranteed to be valid (>= istart).
242 */
243 args->ilimit = ilimit;
244
245 args->oend = oend;
246 args->dt = dt;
247
248 return 0;
249}
250
251static size_t HUF_initRemainingDStream(BIT_DStream_t* bit, HUF_DecompressAsmArgs const* args, int stream, BYTE* segmentEnd)
252{
253 /* Validate that we haven't overwritten. */
254 if (args->op[stream] > segmentEnd)
255 return ERROR(corruption_detected);
256 /* Validate that we haven't read beyond iend[].
257 * Note that ip[] may be < iend[] because the MSB is
258 * the next bit to read, and we may have consumed 100%
259 * of the stream, so down to iend[i] - 8 is valid.
260 */
261 if (args->ip[stream] < args->iend[stream] - 8)
262 return ERROR(corruption_detected);
263
264 /* Construct the BIT_DStream_t. */
265 bit->bitContainer = MEM_readLE64(args->ip[stream]);
266 bit->bitsConsumed = ZSTD_countTrailingZeros((size_t)args->bits[stream]);
267 bit->start = (const char*)args->iend[0];
268 bit->limitPtr = bit->start + sizeof(size_t);
269 bit->ptr = (const char*)args->ip[stream];
270
271 return 0;
272}
273#endif
274
275
276#ifndef HUF_FORCE_DECOMPRESS_X2
277
278/*-***************************/
279/* single-symbol decoding */
280/*-***************************/
281typedef struct { BYTE nbBits; BYTE byte; } HUF_DEltX1; /* single-symbol decoding */
282
283/**
284 * Packs 4 HUF_DEltX1 structs into a U64. This is used to lay down 4 entries at
285 * a time.
286 */
287static U64 HUF_DEltX1_set4(BYTE symbol, BYTE nbBits) {
288 U64 D4;
289 if (MEM_isLittleEndian()) {
290 D4 = (symbol << 8) + nbBits;
291 } else {
292 D4 = symbol + (nbBits << 8);
293 }
294 D4 *= 0x0001000100010001ULL;
295 return D4;
296}
297
298/**
299 * Increase the tableLog to targetTableLog and rescales the stats.
300 * If tableLog > targetTableLog this is a no-op.
301 * @returns New tableLog
302 */
303static U32 HUF_rescaleStats(BYTE* huffWeight, U32* rankVal, U32 nbSymbols, U32 tableLog, U32 targetTableLog)
304{
305 if (tableLog > targetTableLog)
306 return tableLog;
307 if (tableLog < targetTableLog) {
308 U32 const scale = targetTableLog - tableLog;
309 U32 s;
310 /* Increase the weight for all non-zero probability symbols by scale. */
311 for (s = 0; s < nbSymbols; ++s) {
312 huffWeight[s] += (BYTE)((huffWeight[s] == 0) ? 0 : scale);
313 }
314 /* Update rankVal to reflect the new weights.
315 * All weights except 0 get moved to weight + scale.
316 * Weights [1, scale] are empty.
317 */
318 for (s = targetTableLog; s > scale; --s) {
319 rankVal[s] = rankVal[s - scale];
320 }
321 for (s = scale; s > 0; --s) {
322 rankVal[s] = 0;
323 }
324 }
325 return targetTableLog;
326}
327
328typedef struct {
329 U32 rankVal[HUF_TABLELOG_ABSOLUTEMAX + 1];
330 U32 rankStart[HUF_TABLELOG_ABSOLUTEMAX + 1];
331 U32 statsWksp[HUF_READ_STATS_WORKSPACE_SIZE_U32];
332 BYTE symbols[HUF_SYMBOLVALUE_MAX + 1];
333 BYTE huffWeight[HUF_SYMBOLVALUE_MAX + 1];
334} HUF_ReadDTableX1_Workspace;
335
336
337size_t HUF_readDTableX1_wksp(HUF_DTable* DTable, const void* src, size_t srcSize, void* workSpace, size_t wkspSize)
338{
339 return HUF_readDTableX1_wksp_bmi2(DTable, src, srcSize, workSpace, wkspSize, /* bmi2 */ 0);
340}
341
342size_t HUF_readDTableX1_wksp_bmi2(HUF_DTable* DTable, const void* src, size_t srcSize, void* workSpace, size_t wkspSize, int bmi2)
343{
344 U32 tableLog = 0;
345 U32 nbSymbols = 0;
346 size_t iSize;
347 void* const dtPtr = DTable + 1;
348 HUF_DEltX1* const dt = (HUF_DEltX1*)dtPtr;
349 HUF_ReadDTableX1_Workspace* wksp = (HUF_ReadDTableX1_Workspace*)workSpace;
350
351 DEBUG_STATIC_ASSERT(HUF_DECOMPRESS_WORKSPACE_SIZE >= sizeof(*wksp));
352 if (sizeof(*wksp) > wkspSize) return ERROR(tableLog_tooLarge);
353
354 DEBUG_STATIC_ASSERT(sizeof(DTableDesc) == sizeof(HUF_DTable));
355 /* ZSTD_memset(huffWeight, 0, sizeof(huffWeight)); */ /* is not necessary, even though some analyzer complain ... */
356
357 iSize = HUF_readStats_wksp(wksp->huffWeight, HUF_SYMBOLVALUE_MAX + 1, wksp->rankVal, &nbSymbols, &tableLog, src, srcSize, wksp->statsWksp, sizeof(wksp->statsWksp), bmi2);
358 if (HUF_isError(iSize)) return iSize;
359
360
361 /* Table header */
362 { DTableDesc dtd = HUF_getDTableDesc(DTable);
363 U32 const maxTableLog = dtd.maxTableLog + 1;
364 U32 const targetTableLog = MIN(maxTableLog, HUF_DECODER_FAST_TABLELOG);
365 tableLog = HUF_rescaleStats(wksp->huffWeight, wksp->rankVal, nbSymbols, tableLog, targetTableLog);
366 if (tableLog > (U32)(dtd.maxTableLog+1)) return ERROR(tableLog_tooLarge); /* DTable too small, Huffman tree cannot fit in */
367 dtd.tableType = 0;
368 dtd.tableLog = (BYTE)tableLog;
369 ZSTD_memcpy(DTable, &dtd, sizeof(dtd));
370 }
371
372 /* Compute symbols and rankStart given rankVal:
373 *
374 * rankVal already contains the number of values of each weight.
375 *
376 * symbols contains the symbols ordered by weight. First are the rankVal[0]
377 * weight 0 symbols, followed by the rankVal[1] weight 1 symbols, and so on.
378 * symbols[0] is filled (but unused) to avoid a branch.
379 *
380 * rankStart contains the offset where each rank belongs in the DTable.
381 * rankStart[0] is not filled because there are no entries in the table for
382 * weight 0.
383 */
384 {
385 int n;
386 int nextRankStart = 0;
387 int const unroll = 4;
388 int const nLimit = (int)nbSymbols - unroll + 1;
389 for (n=0; n<(int)tableLog+1; n++) {
390 U32 const curr = nextRankStart;
391 nextRankStart += wksp->rankVal[n];
392 wksp->rankStart[n] = curr;
393 }
394 for (n=0; n < nLimit; n += unroll) {
395 int u;
396 for (u=0; u < unroll; ++u) {
397 size_t const w = wksp->huffWeight[n+u];
398 wksp->symbols[wksp->rankStart[w]++] = (BYTE)(n+u);
399 }
400 }
401 for (; n < (int)nbSymbols; ++n) {
402 size_t const w = wksp->huffWeight[n];
403 wksp->symbols[wksp->rankStart[w]++] = (BYTE)n;
404 }
405 }
406
407 /* fill DTable
408 * We fill all entries of each weight in order.
409 * That way length is a constant for each iteration of the outer loop.
410 * We can switch based on the length to a different inner loop which is
411 * optimized for that particular case.
412 */
413 {
414 U32 w;
415 int symbol=wksp->rankVal[0];
416 int rankStart=0;
417 for (w=1; w<tableLog+1; ++w) {
418 int const symbolCount = wksp->rankVal[w];
419 int const length = (1 << w) >> 1;
420 int uStart = rankStart;
421 BYTE const nbBits = (BYTE)(tableLog + 1 - w);
422 int s;
423 int u;
424 switch (length) {
425 case 1:
426 for (s=0; s<symbolCount; ++s) {
427 HUF_DEltX1 D;
428 D.byte = wksp->symbols[symbol + s];
429 D.nbBits = nbBits;
430 dt[uStart] = D;
431 uStart += 1;
432 }
433 break;
434 case 2:
435 for (s=0; s<symbolCount; ++s) {
436 HUF_DEltX1 D;
437 D.byte = wksp->symbols[symbol + s];
438 D.nbBits = nbBits;
439 dt[uStart+0] = D;
440 dt[uStart+1] = D;
441 uStart += 2;
442 }
443 break;
444 case 4:
445 for (s=0; s<symbolCount; ++s) {
446 U64 const D4 = HUF_DEltX1_set4(wksp->symbols[symbol + s], nbBits);
447 MEM_write64(dt + uStart, D4);
448 uStart += 4;
449 }
450 break;
451 case 8:
452 for (s=0; s<symbolCount; ++s) {
453 U64 const D4 = HUF_DEltX1_set4(wksp->symbols[symbol + s], nbBits);
454 MEM_write64(dt + uStart, D4);
455 MEM_write64(dt + uStart + 4, D4);
456 uStart += 8;
457 }
458 break;
459 default:
460 for (s=0; s<symbolCount; ++s) {
461 U64 const D4 = HUF_DEltX1_set4(wksp->symbols[symbol + s], nbBits);
462 for (u=0; u < length; u += 16) {
463 MEM_write64(dt + uStart + u + 0, D4);
464 MEM_write64(dt + uStart + u + 4, D4);
465 MEM_write64(dt + uStart + u + 8, D4);
466 MEM_write64(dt + uStart + u + 12, D4);
467 }
468 assert(u == length);
469 uStart += length;
470 }
471 break;
472 }
473 symbol += symbolCount;
474 rankStart += symbolCount * length;
475 }
476 }
477 return iSize;
478}
479
480FORCE_INLINE_TEMPLATE BYTE
481HUF_decodeSymbolX1(BIT_DStream_t* Dstream, const HUF_DEltX1* dt, const U32 dtLog)
482{
483 size_t const val = BIT_lookBitsFast(Dstream, dtLog); /* note : dtLog >= 1 */
484 BYTE const c = dt[val].byte;
485 BIT_skipBits(Dstream, dt[val].nbBits);
486 return c;
487}
488
489#define HUF_DECODE_SYMBOLX1_0(ptr, DStreamPtr) \
490 *ptr++ = HUF_decodeSymbolX1(DStreamPtr, dt, dtLog)
491
492#define HUF_DECODE_SYMBOLX1_1(ptr, DStreamPtr) \
493 if (MEM_64bits() || (HUF_TABLELOG_MAX<=12)) \
494 HUF_DECODE_SYMBOLX1_0(ptr, DStreamPtr)
495
496#define HUF_DECODE_SYMBOLX1_2(ptr, DStreamPtr) \
497 if (MEM_64bits()) \
498 HUF_DECODE_SYMBOLX1_0(ptr, DStreamPtr)
499
500HINT_INLINE size_t
501HUF_decodeStreamX1(BYTE* p, BIT_DStream_t* const bitDPtr, BYTE* const pEnd, const HUF_DEltX1* const dt, const U32 dtLog)
502{
503 BYTE* const pStart = p;
504
505 /* up to 4 symbols at a time */
506 if ((pEnd - p) > 3) {
507 while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p < pEnd-3)) {
508 HUF_DECODE_SYMBOLX1_2(p, bitDPtr);
509 HUF_DECODE_SYMBOLX1_1(p, bitDPtr);
510 HUF_DECODE_SYMBOLX1_2(p, bitDPtr);
511 HUF_DECODE_SYMBOLX1_0(p, bitDPtr);
512 }
513 } else {
514 BIT_reloadDStream(bitDPtr);
515 }
516
517 /* [0-3] symbols remaining */
518 if (MEM_32bits())
519 while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p < pEnd))
520 HUF_DECODE_SYMBOLX1_0(p, bitDPtr);
521
522 /* no more data to retrieve from bitstream, no need to reload */
523 while (p < pEnd)
524 HUF_DECODE_SYMBOLX1_0(p, bitDPtr);
525
526 return pEnd-pStart;
527}
528
529FORCE_INLINE_TEMPLATE size_t
530HUF_decompress1X1_usingDTable_internal_body(
531 void* dst, size_t dstSize,
532 const void* cSrc, size_t cSrcSize,
533 const HUF_DTable* DTable)
534{
535 BYTE* op = (BYTE*)dst;
536 BYTE* const oend = op + dstSize;
537 const void* dtPtr = DTable + 1;
538 const HUF_DEltX1* const dt = (const HUF_DEltX1*)dtPtr;
539 BIT_DStream_t bitD;
540 DTableDesc const dtd = HUF_getDTableDesc(DTable);
541 U32 const dtLog = dtd.tableLog;
542
543 CHECK_F( BIT_initDStream(&bitD, cSrc, cSrcSize) );
544
545 HUF_decodeStreamX1(op, &bitD, oend, dt, dtLog);
546
547 if (!BIT_endOfDStream(&bitD)) return ERROR(corruption_detected);
548
549 return dstSize;
550}
551
552FORCE_INLINE_TEMPLATE size_t
553HUF_decompress4X1_usingDTable_internal_body(
554 void* dst, size_t dstSize,
555 const void* cSrc, size_t cSrcSize,
556 const HUF_DTable* DTable)
557{
558 /* Check */
559 if (cSrcSize < 10) return ERROR(corruption_detected); /* strict minimum : jump table + 1 byte per stream */
560
561 { const BYTE* const istart = (const BYTE*) cSrc;
562 BYTE* const ostart = (BYTE*) dst;
563 BYTE* const oend = ostart + dstSize;
564 BYTE* const olimit = oend - 3;
565 const void* const dtPtr = DTable + 1;
566 const HUF_DEltX1* const dt = (const HUF_DEltX1*)dtPtr;
567
568 /* Init */
569 BIT_DStream_t bitD1;
570 BIT_DStream_t bitD2;
571 BIT_DStream_t bitD3;
572 BIT_DStream_t bitD4;
573 size_t const length1 = MEM_readLE16(istart);
574 size_t const length2 = MEM_readLE16(istart+2);
575 size_t const length3 = MEM_readLE16(istart+4);
576 size_t const length4 = cSrcSize - (length1 + length2 + length3 + 6);
577 const BYTE* const istart1 = istart + 6; /* jumpTable */
578 const BYTE* const istart2 = istart1 + length1;
579 const BYTE* const istart3 = istart2 + length2;
580 const BYTE* const istart4 = istart3 + length3;
581 const size_t segmentSize = (dstSize+3) / 4;
582 BYTE* const opStart2 = ostart + segmentSize;
583 BYTE* const opStart3 = opStart2 + segmentSize;
584 BYTE* const opStart4 = opStart3 + segmentSize;
585 BYTE* op1 = ostart;
586 BYTE* op2 = opStart2;
587 BYTE* op3 = opStart3;
588 BYTE* op4 = opStart4;
589 DTableDesc const dtd = HUF_getDTableDesc(DTable);
590 U32 const dtLog = dtd.tableLog;
591 U32 endSignal = 1;
592
593 if (length4 > cSrcSize) return ERROR(corruption_detected); /* overflow */
594 if (opStart4 > oend) return ERROR(corruption_detected); /* overflow */
595 CHECK_F( BIT_initDStream(&bitD1, istart1, length1) );
596 CHECK_F( BIT_initDStream(&bitD2, istart2, length2) );
597 CHECK_F( BIT_initDStream(&bitD3, istart3, length3) );
598 CHECK_F( BIT_initDStream(&bitD4, istart4, length4) );
599
600 /* up to 16 symbols per loop (4 symbols per stream) in 64-bit mode */
601 if ((size_t)(oend - op4) >= sizeof(size_t)) {
602 for ( ; (endSignal) & (op4 < olimit) ; ) {
603 HUF_DECODE_SYMBOLX1_2(op1, &bitD1);
604 HUF_DECODE_SYMBOLX1_2(op2, &bitD2);
605 HUF_DECODE_SYMBOLX1_2(op3, &bitD3);
606 HUF_DECODE_SYMBOLX1_2(op4, &bitD4);
607 HUF_DECODE_SYMBOLX1_1(op1, &bitD1);
608 HUF_DECODE_SYMBOLX1_1(op2, &bitD2);
609 HUF_DECODE_SYMBOLX1_1(op3, &bitD3);
610 HUF_DECODE_SYMBOLX1_1(op4, &bitD4);
611 HUF_DECODE_SYMBOLX1_2(op1, &bitD1);
612 HUF_DECODE_SYMBOLX1_2(op2, &bitD2);
613 HUF_DECODE_SYMBOLX1_2(op3, &bitD3);
614 HUF_DECODE_SYMBOLX1_2(op4, &bitD4);
615 HUF_DECODE_SYMBOLX1_0(op1, &bitD1);
616 HUF_DECODE_SYMBOLX1_0(op2, &bitD2);
617 HUF_DECODE_SYMBOLX1_0(op3, &bitD3);
618 HUF_DECODE_SYMBOLX1_0(op4, &bitD4);
619 endSignal &= BIT_reloadDStreamFast(&bitD1) == BIT_DStream_unfinished;
620 endSignal &= BIT_reloadDStreamFast(&bitD2) == BIT_DStream_unfinished;
621 endSignal &= BIT_reloadDStreamFast(&bitD3) == BIT_DStream_unfinished;
622 endSignal &= BIT_reloadDStreamFast(&bitD4) == BIT_DStream_unfinished;
623 }
624 }
625
626 /* check corruption */
627 /* note : should not be necessary : op# advance in lock step, and we control op4.
628 * but curiously, binary generated by gcc 7.2 & 7.3 with -mbmi2 runs faster when >=1 test is present */
629 if (op1 > opStart2) return ERROR(corruption_detected);
630 if (op2 > opStart3) return ERROR(corruption_detected);
631 if (op3 > opStart4) return ERROR(corruption_detected);
632 /* note : op4 supposed already verified within main loop */
633
634 /* finish bitStreams one by one */
635 HUF_decodeStreamX1(op1, &bitD1, opStart2, dt, dtLog);
636 HUF_decodeStreamX1(op2, &bitD2, opStart3, dt, dtLog);
637 HUF_decodeStreamX1(op3, &bitD3, opStart4, dt, dtLog);
638 HUF_decodeStreamX1(op4, &bitD4, oend, dt, dtLog);
639
640 /* check */
641 { U32 const endCheck = BIT_endOfDStream(&bitD1) & BIT_endOfDStream(&bitD2) & BIT_endOfDStream(&bitD3) & BIT_endOfDStream(&bitD4);
642 if (!endCheck) return ERROR(corruption_detected); }
643
644 /* decoded size */
645 return dstSize;
646 }
647}
648
649#if HUF_NEED_BMI2_FUNCTION
650static BMI2_TARGET_ATTRIBUTE
651size_t HUF_decompress4X1_usingDTable_internal_bmi2(void* dst, size_t dstSize, void const* cSrc,
652 size_t cSrcSize, HUF_DTable const* DTable) {
653 return HUF_decompress4X1_usingDTable_internal_body(dst, dstSize, cSrc, cSrcSize, DTable);
654}
655#endif
656
657#if HUF_NEED_DEFAULT_FUNCTION
658static
659size_t HUF_decompress4X1_usingDTable_internal_default(void* dst, size_t dstSize, void const* cSrc,
660 size_t cSrcSize, HUF_DTable const* DTable) {
661 return HUF_decompress4X1_usingDTable_internal_body(dst, dstSize, cSrc, cSrcSize, DTable);
662}
663#endif
664
665#if ZSTD_ENABLE_ASM_X86_64_BMI2
666
667HUF_ASM_DECL void HUF_decompress4X1_usingDTable_internal_bmi2_asm_loop(HUF_DecompressAsmArgs* args) ZSTDLIB_HIDDEN;
668
669static HUF_ASM_X86_64_BMI2_ATTRS
670size_t
671HUF_decompress4X1_usingDTable_internal_bmi2_asm(
672 void* dst, size_t dstSize,
673 const void* cSrc, size_t cSrcSize,
674 const HUF_DTable* DTable)
675{
676 void const* dt = DTable + 1;
677 const BYTE* const iend = (const BYTE*)cSrc + 6;
678 BYTE* const oend = (BYTE*)dst + dstSize;
679 HUF_DecompressAsmArgs args;
680 {
681 size_t const ret = HUF_DecompressAsmArgs_init(&args, dst, dstSize, cSrc, cSrcSize, DTable);
682 FORWARD_IF_ERROR(ret, "Failed to init asm args");
683 if (ret != 0)
684 return HUF_decompress4X1_usingDTable_internal_bmi2(dst, dstSize, cSrc, cSrcSize, DTable);
685 }
686
687 assert(args.ip[0] >= args.ilimit);
688 HUF_decompress4X1_usingDTable_internal_bmi2_asm_loop(&args);
689
690 /* Our loop guarantees that ip[] >= ilimit and that we haven't
691 * overwritten any op[].
692 */
693 assert(args.ip[0] >= iend);
694 assert(args.ip[1] >= iend);
695 assert(args.ip[2] >= iend);
696 assert(args.ip[3] >= iend);
697 assert(args.op[3] <= oend);
698 (void)iend;
699
700 /* finish bit streams one by one. */
701 {
702 size_t const segmentSize = (dstSize+3) / 4;
703 BYTE* segmentEnd = (BYTE*)dst;
704 int i;
705 for (i = 0; i < 4; ++i) {
706 BIT_DStream_t bit;
707 if (segmentSize <= (size_t)(oend - segmentEnd))
708 segmentEnd += segmentSize;
709 else
710 segmentEnd = oend;
711 FORWARD_IF_ERROR(HUF_initRemainingDStream(&bit, &args, i, segmentEnd), "corruption");
712 /* Decompress and validate that we've produced exactly the expected length. */
713 args.op[i] += HUF_decodeStreamX1(args.op[i], &bit, segmentEnd, (HUF_DEltX1 const*)dt, HUF_DECODER_FAST_TABLELOG);
714 if (args.op[i] != segmentEnd) return ERROR(corruption_detected);
715 }
716 }
717
718 /* decoded size */
719 return dstSize;
720}
721#endif /* ZSTD_ENABLE_ASM_X86_64_BMI2 */
722
723typedef size_t (*HUF_decompress_usingDTable_t)(void *dst, size_t dstSize,
724 const void *cSrc,
725 size_t cSrcSize,
726 const HUF_DTable *DTable);
727
728HUF_DGEN(HUF_decompress1X1_usingDTable_internal)
729
730static size_t HUF_decompress4X1_usingDTable_internal(void* dst, size_t dstSize, void const* cSrc,
731 size_t cSrcSize, HUF_DTable const* DTable, int bmi2)
732{
733#if DYNAMIC_BMI2
734 if (bmi2) {
735# if ZSTD_ENABLE_ASM_X86_64_BMI2
736 return HUF_decompress4X1_usingDTable_internal_bmi2_asm(dst, dstSize, cSrc, cSrcSize, DTable);
737# else
738 return HUF_decompress4X1_usingDTable_internal_bmi2(dst, dstSize, cSrc, cSrcSize, DTable);
739# endif
740 }
741#else
742 (void)bmi2;
743#endif
744
745#if ZSTD_ENABLE_ASM_X86_64_BMI2 && defined(__BMI2__)
746 return HUF_decompress4X1_usingDTable_internal_bmi2_asm(dst, dstSize, cSrc, cSrcSize, DTable);
747#else
748 return HUF_decompress4X1_usingDTable_internal_default(dst, dstSize, cSrc, cSrcSize, DTable);
749#endif
750}
751
752
753size_t HUF_decompress1X1_usingDTable(
754 void* dst, size_t dstSize,
755 const void* cSrc, size_t cSrcSize,
756 const HUF_DTable* DTable)
757{
758 DTableDesc dtd = HUF_getDTableDesc(DTable);
759 if (dtd.tableType != 0) return ERROR(GENERIC);
760 return HUF_decompress1X1_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable, /* bmi2 */ 0);
761}
762
763size_t HUF_decompress1X1_DCtx_wksp(HUF_DTable* DCtx, void* dst, size_t dstSize,
764 const void* cSrc, size_t cSrcSize,
765 void* workSpace, size_t wkspSize)
766{
767 const BYTE* ip = (const BYTE*) cSrc;
768
769 size_t const hSize = HUF_readDTableX1_wksp(DCtx, cSrc, cSrcSize, workSpace, wkspSize);
770 if (HUF_isError(hSize)) return hSize;
771 if (hSize >= cSrcSize) return ERROR(srcSize_wrong);
772 ip += hSize; cSrcSize -= hSize;
773
774 return HUF_decompress1X1_usingDTable_internal(dst, dstSize, ip, cSrcSize, DCtx, /* bmi2 */ 0);
775}
776
777
778size_t HUF_decompress4X1_usingDTable(
779 void* dst, size_t dstSize,
780 const void* cSrc, size_t cSrcSize,
781 const HUF_DTable* DTable)
782{
783 DTableDesc dtd = HUF_getDTableDesc(DTable);
784 if (dtd.tableType != 0) return ERROR(GENERIC);
785 return HUF_decompress4X1_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable, /* bmi2 */ 0);
786}
787
788static size_t HUF_decompress4X1_DCtx_wksp_bmi2(HUF_DTable* dctx, void* dst, size_t dstSize,
789 const void* cSrc, size_t cSrcSize,
790 void* workSpace, size_t wkspSize, int bmi2)
791{
792 const BYTE* ip = (const BYTE*) cSrc;
793
794 size_t const hSize = HUF_readDTableX1_wksp_bmi2(dctx, cSrc, cSrcSize, workSpace, wkspSize, bmi2);
795 if (HUF_isError(hSize)) return hSize;
796 if (hSize >= cSrcSize) return ERROR(srcSize_wrong);
797 ip += hSize; cSrcSize -= hSize;
798
799 return HUF_decompress4X1_usingDTable_internal(dst, dstSize, ip, cSrcSize, dctx, bmi2);
800}
801
802size_t HUF_decompress4X1_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize,
803 const void* cSrc, size_t cSrcSize,
804 void* workSpace, size_t wkspSize)
805{
806 return HUF_decompress4X1_DCtx_wksp_bmi2(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize, 0);
807}
808
809
810#endif /* HUF_FORCE_DECOMPRESS_X2 */
811
812
813#ifndef HUF_FORCE_DECOMPRESS_X1
814
815/* *************************/
816/* double-symbols decoding */
817/* *************************/
818
819typedef struct { U16 sequence; BYTE nbBits; BYTE length; } HUF_DEltX2; /* double-symbols decoding */
820typedef struct { BYTE symbol; } sortedSymbol_t;
821typedef U32 rankValCol_t[HUF_TABLELOG_MAX + 1];
822typedef rankValCol_t rankVal_t[HUF_TABLELOG_MAX];
823
824/**
825 * Constructs a HUF_DEltX2 in a U32.
826 */
827static U32 HUF_buildDEltX2U32(U32 symbol, U32 nbBits, U32 baseSeq, int level)
828{
829 U32 seq;
830 DEBUG_STATIC_ASSERT(offsetof(HUF_DEltX2, sequence) == 0);
831 DEBUG_STATIC_ASSERT(offsetof(HUF_DEltX2, nbBits) == 2);
832 DEBUG_STATIC_ASSERT(offsetof(HUF_DEltX2, length) == 3);
833 DEBUG_STATIC_ASSERT(sizeof(HUF_DEltX2) == sizeof(U32));
834 if (MEM_isLittleEndian()) {
835 seq = level == 1 ? symbol : (baseSeq + (symbol << 8));
836 return seq + (nbBits << 16) + ((U32)level << 24);
837 } else {
838 seq = level == 1 ? (symbol << 8) : ((baseSeq << 8) + symbol);
839 return (seq << 16) + (nbBits << 8) + (U32)level;
840 }
841}
842
843/**
844 * Constructs a HUF_DEltX2.
845 */
846static HUF_DEltX2 HUF_buildDEltX2(U32 symbol, U32 nbBits, U32 baseSeq, int level)
847{
848 HUF_DEltX2 DElt;
849 U32 const val = HUF_buildDEltX2U32(symbol, nbBits, baseSeq, level);
850 DEBUG_STATIC_ASSERT(sizeof(DElt) == sizeof(val));
851 ZSTD_memcpy(&DElt, &val, sizeof(val));
852 return DElt;
853}
854
855/**
856 * Constructs 2 HUF_DEltX2s and packs them into a U64.
857 */
858static U64 HUF_buildDEltX2U64(U32 symbol, U32 nbBits, U16 baseSeq, int level)
859{
860 U32 DElt = HUF_buildDEltX2U32(symbol, nbBits, baseSeq, level);
861 return (U64)DElt + ((U64)DElt << 32);
862}
863
864/**
865 * Fills the DTable rank with all the symbols from [begin, end) that are each
866 * nbBits long.
867 *
868 * @param DTableRank The start of the rank in the DTable.
869 * @param begin The first symbol to fill (inclusive).
870 * @param end The last symbol to fill (exclusive).
871 * @param nbBits Each symbol is nbBits long.
872 * @param tableLog The table log.
873 * @param baseSeq If level == 1 { 0 } else { the first level symbol }
874 * @param level The level in the table. Must be 1 or 2.
875 */
876static void HUF_fillDTableX2ForWeight(
877 HUF_DEltX2* DTableRank,
878 sortedSymbol_t const* begin, sortedSymbol_t const* end,
879 U32 nbBits, U32 tableLog,
880 U16 baseSeq, int const level)
881{
882 U32 const length = 1U << ((tableLog - nbBits) & 0x1F /* quiet static-analyzer */);
883 const sortedSymbol_t* ptr;
884 assert(level >= 1 && level <= 2);
885 switch (length) {
886 case 1:
887 for (ptr = begin; ptr != end; ++ptr) {
888 HUF_DEltX2 const DElt = HUF_buildDEltX2(ptr->symbol, nbBits, baseSeq, level);
889 *DTableRank++ = DElt;
890 }
891 break;
892 case 2:
893 for (ptr = begin; ptr != end; ++ptr) {
894 HUF_DEltX2 const DElt = HUF_buildDEltX2(ptr->symbol, nbBits, baseSeq, level);
895 DTableRank[0] = DElt;
896 DTableRank[1] = DElt;
897 DTableRank += 2;
898 }
899 break;
900 case 4:
901 for (ptr = begin; ptr != end; ++ptr) {
902 U64 const DEltX2 = HUF_buildDEltX2U64(ptr->symbol, nbBits, baseSeq, level);
903 ZSTD_memcpy(DTableRank + 0, &DEltX2, sizeof(DEltX2));
904 ZSTD_memcpy(DTableRank + 2, &DEltX2, sizeof(DEltX2));
905 DTableRank += 4;
906 }
907 break;
908 case 8:
909 for (ptr = begin; ptr != end; ++ptr) {
910 U64 const DEltX2 = HUF_buildDEltX2U64(ptr->symbol, nbBits, baseSeq, level);
911 ZSTD_memcpy(DTableRank + 0, &DEltX2, sizeof(DEltX2));
912 ZSTD_memcpy(DTableRank + 2, &DEltX2, sizeof(DEltX2));
913 ZSTD_memcpy(DTableRank + 4, &DEltX2, sizeof(DEltX2));
914 ZSTD_memcpy(DTableRank + 6, &DEltX2, sizeof(DEltX2));
915 DTableRank += 8;
916 }
917 break;
918 default:
919 for (ptr = begin; ptr != end; ++ptr) {
920 U64 const DEltX2 = HUF_buildDEltX2U64(ptr->symbol, nbBits, baseSeq, level);
921 HUF_DEltX2* const DTableRankEnd = DTableRank + length;
922 for (; DTableRank != DTableRankEnd; DTableRank += 8) {
923 ZSTD_memcpy(DTableRank + 0, &DEltX2, sizeof(DEltX2));
924 ZSTD_memcpy(DTableRank + 2, &DEltX2, sizeof(DEltX2));
925 ZSTD_memcpy(DTableRank + 4, &DEltX2, sizeof(DEltX2));
926 ZSTD_memcpy(DTableRank + 6, &DEltX2, sizeof(DEltX2));
927 }
928 }
929 break;
930 }
931}
932
933/* HUF_fillDTableX2Level2() :
934 * `rankValOrigin` must be a table of at least (HUF_TABLELOG_MAX + 1) U32 */
935static void HUF_fillDTableX2Level2(HUF_DEltX2* DTable, U32 targetLog, const U32 consumedBits,
936 const U32* rankVal, const int minWeight, const int maxWeight1,
937 const sortedSymbol_t* sortedSymbols, U32 const* rankStart,
938 U32 nbBitsBaseline, U16 baseSeq)
939{
940 /* Fill skipped values (all positions up to rankVal[minWeight]).
941 * These are positions only get a single symbol because the combined weight
942 * is too large.
943 */
944 if (minWeight>1) {
945 U32 const length = 1U << ((targetLog - consumedBits) & 0x1F /* quiet static-analyzer */);
946 U64 const DEltX2 = HUF_buildDEltX2U64(baseSeq, consumedBits, /* baseSeq */ 0, /* level */ 1);
947 int const skipSize = rankVal[minWeight];
948 assert(length > 1);
949 assert((U32)skipSize < length);
950 switch (length) {
951 case 2:
952 assert(skipSize == 1);
953 ZSTD_memcpy(DTable, &DEltX2, sizeof(DEltX2));
954 break;
955 case 4:
956 assert(skipSize <= 4);
957 ZSTD_memcpy(DTable + 0, &DEltX2, sizeof(DEltX2));
958 ZSTD_memcpy(DTable + 2, &DEltX2, sizeof(DEltX2));
959 break;
960 default:
961 {
962 int i;
963 for (i = 0; i < skipSize; i += 8) {
964 ZSTD_memcpy(DTable + i + 0, &DEltX2, sizeof(DEltX2));
965 ZSTD_memcpy(DTable + i + 2, &DEltX2, sizeof(DEltX2));
966 ZSTD_memcpy(DTable + i + 4, &DEltX2, sizeof(DEltX2));
967 ZSTD_memcpy(DTable + i + 6, &DEltX2, sizeof(DEltX2));
968 }
969 }
970 }
971 }
972
973 /* Fill each of the second level symbols by weight. */
974 {
975 int w;
976 for (w = minWeight; w < maxWeight1; ++w) {
977 int const begin = rankStart[w];
978 int const end = rankStart[w+1];
979 U32 const nbBits = nbBitsBaseline - w;
980 U32 const totalBits = nbBits + consumedBits;
981 HUF_fillDTableX2ForWeight(
982 DTable + rankVal[w],
983 sortedSymbols + begin, sortedSymbols + end,
984 totalBits, targetLog,
985 baseSeq, /* level */ 2);
986 }
987 }
988}
989
990static void HUF_fillDTableX2(HUF_DEltX2* DTable, const U32 targetLog,
991 const sortedSymbol_t* sortedList,
992 const U32* rankStart, rankVal_t rankValOrigin, const U32 maxWeight,
993 const U32 nbBitsBaseline)
994{
995 U32* const rankVal = rankValOrigin[0];
996 const int scaleLog = nbBitsBaseline - targetLog; /* note : targetLog >= srcLog, hence scaleLog <= 1 */
997 const U32 minBits = nbBitsBaseline - maxWeight;
998 int w;
999 int const wEnd = (int)maxWeight + 1;
1000
1001 /* Fill DTable in order of weight. */
1002 for (w = 1; w < wEnd; ++w) {
1003 int const begin = (int)rankStart[w];
1004 int const end = (int)rankStart[w+1];
1005 U32 const nbBits = nbBitsBaseline - w;
1006
1007 if (targetLog-nbBits >= minBits) {
1008 /* Enough room for a second symbol. */
1009 int start = rankVal[w];
1010 U32 const length = 1U << ((targetLog - nbBits) & 0x1F /* quiet static-analyzer */);
1011 int minWeight = nbBits + scaleLog;
1012 int s;
1013 if (minWeight < 1) minWeight = 1;
1014 /* Fill the DTable for every symbol of weight w.
1015 * These symbols get at least 1 second symbol.
1016 */
1017 for (s = begin; s != end; ++s) {
1018 HUF_fillDTableX2Level2(
1019 DTable + start, targetLog, nbBits,
1020 rankValOrigin[nbBits], minWeight, wEnd,
1021 sortedList, rankStart,
1022 nbBitsBaseline, sortedList[s].symbol);
1023 start += length;
1024 }
1025 } else {
1026 /* Only a single symbol. */
1027 HUF_fillDTableX2ForWeight(
1028 DTable + rankVal[w],
1029 sortedList + begin, sortedList + end,
1030 nbBits, targetLog,
1031 /* baseSeq */ 0, /* level */ 1);
1032 }
1033 }
1034}
1035
1036typedef struct {
1037 rankValCol_t rankVal[HUF_TABLELOG_MAX];
1038 U32 rankStats[HUF_TABLELOG_MAX + 1];
1039 U32 rankStart0[HUF_TABLELOG_MAX + 3];
1040 sortedSymbol_t sortedSymbol[HUF_SYMBOLVALUE_MAX + 1];
1041 BYTE weightList[HUF_SYMBOLVALUE_MAX + 1];
1042 U32 calleeWksp[HUF_READ_STATS_WORKSPACE_SIZE_U32];
1043} HUF_ReadDTableX2_Workspace;
1044
1045size_t HUF_readDTableX2_wksp(HUF_DTable* DTable,
1046 const void* src, size_t srcSize,
1047 void* workSpace, size_t wkspSize)
1048{
1049 return HUF_readDTableX2_wksp_bmi2(DTable, src, srcSize, workSpace, wkspSize, /* bmi2 */ 0);
1050}
1051
1052size_t HUF_readDTableX2_wksp_bmi2(HUF_DTable* DTable,
1053 const void* src, size_t srcSize,
1054 void* workSpace, size_t wkspSize, int bmi2)
1055{
1056 U32 tableLog, maxW, nbSymbols;
1057 DTableDesc dtd = HUF_getDTableDesc(DTable);
1058 U32 maxTableLog = dtd.maxTableLog;
1059 size_t iSize;
1060 void* dtPtr = DTable+1; /* force compiler to avoid strict-aliasing */
1061 HUF_DEltX2* const dt = (HUF_DEltX2*)dtPtr;
1062 U32 *rankStart;
1063
1064 HUF_ReadDTableX2_Workspace* const wksp = (HUF_ReadDTableX2_Workspace*)workSpace;
1065
1066 if (sizeof(*wksp) > wkspSize) return ERROR(GENERIC);
1067
1068 rankStart = wksp->rankStart0 + 1;
1069 ZSTD_memset(wksp->rankStats, 0, sizeof(wksp->rankStats));
1070 ZSTD_memset(wksp->rankStart0, 0, sizeof(wksp->rankStart0));
1071
1072 DEBUG_STATIC_ASSERT(sizeof(HUF_DEltX2) == sizeof(HUF_DTable)); /* if compiler fails here, assertion is wrong */
1073 if (maxTableLog > HUF_TABLELOG_MAX) return ERROR(tableLog_tooLarge);
1074 /* ZSTD_memset(weightList, 0, sizeof(weightList)); */ /* is not necessary, even though some analyzer complain ... */
1075
1076 iSize = HUF_readStats_wksp(wksp->weightList, HUF_SYMBOLVALUE_MAX + 1, wksp->rankStats, &nbSymbols, &tableLog, src, srcSize, wksp->calleeWksp, sizeof(wksp->calleeWksp), bmi2);
1077 if (HUF_isError(iSize)) return iSize;
1078
1079 /* check result */
1080 if (tableLog > maxTableLog) return ERROR(tableLog_tooLarge); /* DTable can't fit code depth */
1081 if (tableLog <= HUF_DECODER_FAST_TABLELOG && maxTableLog > HUF_DECODER_FAST_TABLELOG) maxTableLog = HUF_DECODER_FAST_TABLELOG;
1082
1083 /* find maxWeight */
1084 for (maxW = tableLog; wksp->rankStats[maxW]==0; maxW--) {} /* necessarily finds a solution before 0 */
1085
1086 /* Get start index of each weight */
1087 { U32 w, nextRankStart = 0;
1088 for (w=1; w<maxW+1; w++) {
1089 U32 curr = nextRankStart;
1090 nextRankStart += wksp->rankStats[w];
1091 rankStart[w] = curr;
1092 }
1093 rankStart[0] = nextRankStart; /* put all 0w symbols at the end of sorted list*/
1094 rankStart[maxW+1] = nextRankStart;
1095 }
1096
1097 /* sort symbols by weight */
1098 { U32 s;
1099 for (s=0; s<nbSymbols; s++) {
1100 U32 const w = wksp->weightList[s];
1101 U32 const r = rankStart[w]++;
1102 wksp->sortedSymbol[r].symbol = (BYTE)s;
1103 }
1104 rankStart[0] = 0; /* forget 0w symbols; this is beginning of weight(1) */
1105 }
1106
1107 /* Build rankVal */
1108 { U32* const rankVal0 = wksp->rankVal[0];
1109 { int const rescale = (maxTableLog-tableLog) - 1; /* tableLog <= maxTableLog */
1110 U32 nextRankVal = 0;
1111 U32 w;
1112 for (w=1; w<maxW+1; w++) {
1113 U32 curr = nextRankVal;
1114 nextRankVal += wksp->rankStats[w] << (w+rescale);
1115 rankVal0[w] = curr;
1116 } }
1117 { U32 const minBits = tableLog+1 - maxW;
1118 U32 consumed;
1119 for (consumed = minBits; consumed < maxTableLog - minBits + 1; consumed++) {
1120 U32* const rankValPtr = wksp->rankVal[consumed];
1121 U32 w;
1122 for (w = 1; w < maxW+1; w++) {
1123 rankValPtr[w] = rankVal0[w] >> consumed;
1124 } } } }
1125
1126 HUF_fillDTableX2(dt, maxTableLog,
1127 wksp->sortedSymbol,
1128 wksp->rankStart0, wksp->rankVal, maxW,
1129 tableLog+1);
1130
1131 dtd.tableLog = (BYTE)maxTableLog;
1132 dtd.tableType = 1;
1133 ZSTD_memcpy(DTable, &dtd, sizeof(dtd));
1134 return iSize;
1135}
1136
1137
1138FORCE_INLINE_TEMPLATE U32
1139HUF_decodeSymbolX2(void* op, BIT_DStream_t* DStream, const HUF_DEltX2* dt, const U32 dtLog)
1140{
1141 size_t const val = BIT_lookBitsFast(DStream, dtLog); /* note : dtLog >= 1 */
1142 ZSTD_memcpy(op, &dt[val].sequence, 2);
1143 BIT_skipBits(DStream, dt[val].nbBits);
1144 return dt[val].length;
1145}
1146
1147FORCE_INLINE_TEMPLATE U32
1148HUF_decodeLastSymbolX2(void* op, BIT_DStream_t* DStream, const HUF_DEltX2* dt, const U32 dtLog)
1149{
1150 size_t const val = BIT_lookBitsFast(DStream, dtLog); /* note : dtLog >= 1 */
1151 ZSTD_memcpy(op, &dt[val].sequence, 1);
1152 if (dt[val].length==1) {
1153 BIT_skipBits(DStream, dt[val].nbBits);
1154 } else {
1155 if (DStream->bitsConsumed < (sizeof(DStream->bitContainer)*8)) {
1156 BIT_skipBits(DStream, dt[val].nbBits);
1157 if (DStream->bitsConsumed > (sizeof(DStream->bitContainer)*8))
1158 /* ugly hack; works only because it's the last symbol. Note : can't easily extract nbBits from just this symbol */
1159 DStream->bitsConsumed = (sizeof(DStream->bitContainer)*8);
1160 }
1161 }
1162 return 1;
1163}
1164
1165#define HUF_DECODE_SYMBOLX2_0(ptr, DStreamPtr) \
1166 ptr += HUF_decodeSymbolX2(ptr, DStreamPtr, dt, dtLog)
1167
1168#define HUF_DECODE_SYMBOLX2_1(ptr, DStreamPtr) \
1169 if (MEM_64bits() || (HUF_TABLELOG_MAX<=12)) \
1170 ptr += HUF_decodeSymbolX2(ptr, DStreamPtr, dt, dtLog)
1171
1172#define HUF_DECODE_SYMBOLX2_2(ptr, DStreamPtr) \
1173 if (MEM_64bits()) \
1174 ptr += HUF_decodeSymbolX2(ptr, DStreamPtr, dt, dtLog)
1175
1176HINT_INLINE size_t
1177HUF_decodeStreamX2(BYTE* p, BIT_DStream_t* bitDPtr, BYTE* const pEnd,
1178 const HUF_DEltX2* const dt, const U32 dtLog)
1179{
1180 BYTE* const pStart = p;
1181
1182 /* up to 8 symbols at a time */
1183 if ((size_t)(pEnd - p) >= sizeof(bitDPtr->bitContainer)) {
1184 if (dtLog <= 11 && MEM_64bits()) {
1185 /* up to 10 symbols at a time */
1186 while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p < pEnd-9)) {
1187 HUF_DECODE_SYMBOLX2_0(p, bitDPtr);
1188 HUF_DECODE_SYMBOLX2_0(p, bitDPtr);
1189 HUF_DECODE_SYMBOLX2_0(p, bitDPtr);
1190 HUF_DECODE_SYMBOLX2_0(p, bitDPtr);
1191 HUF_DECODE_SYMBOLX2_0(p, bitDPtr);
1192 }
1193 } else {
1194 /* up to 8 symbols at a time */
1195 while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p < pEnd-(sizeof(bitDPtr->bitContainer)-1))) {
1196 HUF_DECODE_SYMBOLX2_2(p, bitDPtr);
1197 HUF_DECODE_SYMBOLX2_1(p, bitDPtr);
1198 HUF_DECODE_SYMBOLX2_2(p, bitDPtr);
1199 HUF_DECODE_SYMBOLX2_0(p, bitDPtr);
1200 }
1201 }
1202 } else {
1203 BIT_reloadDStream(bitDPtr);
1204 }
1205
1206 /* closer to end : up to 2 symbols at a time */
1207 if ((size_t)(pEnd - p) >= 2) {
1208 while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p <= pEnd-2))
1209 HUF_DECODE_SYMBOLX2_0(p, bitDPtr);
1210
1211 while (p <= pEnd-2)
1212 HUF_DECODE_SYMBOLX2_0(p, bitDPtr); /* no need to reload : reached the end of DStream */
1213 }
1214
1215 if (p < pEnd)
1216 p += HUF_decodeLastSymbolX2(p, bitDPtr, dt, dtLog);
1217
1218 return p-pStart;
1219}
1220
1221FORCE_INLINE_TEMPLATE size_t
1222HUF_decompress1X2_usingDTable_internal_body(
1223 void* dst, size_t dstSize,
1224 const void* cSrc, size_t cSrcSize,
1225 const HUF_DTable* DTable)
1226{
1227 BIT_DStream_t bitD;
1228
1229 /* Init */
1230 CHECK_F( BIT_initDStream(&bitD, cSrc, cSrcSize) );
1231
1232 /* decode */
1233 { BYTE* const ostart = (BYTE*) dst;
1234 BYTE* const oend = ostart + dstSize;
1235 const void* const dtPtr = DTable+1; /* force compiler to not use strict-aliasing */
1236 const HUF_DEltX2* const dt = (const HUF_DEltX2*)dtPtr;
1237 DTableDesc const dtd = HUF_getDTableDesc(DTable);
1238 HUF_decodeStreamX2(ostart, &bitD, oend, dt, dtd.tableLog);
1239 }
1240
1241 /* check */
1242 if (!BIT_endOfDStream(&bitD)) return ERROR(corruption_detected);
1243
1244 /* decoded size */
1245 return dstSize;
1246}
1247FORCE_INLINE_TEMPLATE size_t
1248HUF_decompress4X2_usingDTable_internal_body(
1249 void* dst, size_t dstSize,
1250 const void* cSrc, size_t cSrcSize,
1251 const HUF_DTable* DTable)
1252{
1253 if (cSrcSize < 10) return ERROR(corruption_detected); /* strict minimum : jump table + 1 byte per stream */
1254
1255 { const BYTE* const istart = (const BYTE*) cSrc;
1256 BYTE* const ostart = (BYTE*) dst;
1257 BYTE* const oend = ostart + dstSize;
1258 BYTE* const olimit = oend - (sizeof(size_t)-1);
1259 const void* const dtPtr = DTable+1;
1260 const HUF_DEltX2* const dt = (const HUF_DEltX2*)dtPtr;
1261
1262 /* Init */
1263 BIT_DStream_t bitD1;
1264 BIT_DStream_t bitD2;
1265 BIT_DStream_t bitD3;
1266 BIT_DStream_t bitD4;
1267 size_t const length1 = MEM_readLE16(istart);
1268 size_t const length2 = MEM_readLE16(istart+2);
1269 size_t const length3 = MEM_readLE16(istart+4);
1270 size_t const length4 = cSrcSize - (length1 + length2 + length3 + 6);
1271 const BYTE* const istart1 = istart + 6; /* jumpTable */
1272 const BYTE* const istart2 = istart1 + length1;
1273 const BYTE* const istart3 = istart2 + length2;
1274 const BYTE* const istart4 = istart3 + length3;
1275 size_t const segmentSize = (dstSize+3) / 4;
1276 BYTE* const opStart2 = ostart + segmentSize;
1277 BYTE* const opStart3 = opStart2 + segmentSize;
1278 BYTE* const opStart4 = opStart3 + segmentSize;
1279 BYTE* op1 = ostart;
1280 BYTE* op2 = opStart2;
1281 BYTE* op3 = opStart3;
1282 BYTE* op4 = opStart4;
1283 U32 endSignal = 1;
1284 DTableDesc const dtd = HUF_getDTableDesc(DTable);
1285 U32 const dtLog = dtd.tableLog;
1286
1287 if (length4 > cSrcSize) return ERROR(corruption_detected); /* overflow */
1288 if (opStart4 > oend) return ERROR(corruption_detected); /* overflow */
1289 CHECK_F( BIT_initDStream(&bitD1, istart1, length1) );
1290 CHECK_F( BIT_initDStream(&bitD2, istart2, length2) );
1291 CHECK_F( BIT_initDStream(&bitD3, istart3, length3) );
1292 CHECK_F( BIT_initDStream(&bitD4, istart4, length4) );
1293
1294 /* 16-32 symbols per loop (4-8 symbols per stream) */
1295 if ((size_t)(oend - op4) >= sizeof(size_t)) {
1296 for ( ; (endSignal) & (op4 < olimit); ) {
1297#if defined(__clang__) && (defined(__x86_64__) || defined(__i386__))
1298 HUF_DECODE_SYMBOLX2_2(op1, &bitD1);
1299 HUF_DECODE_SYMBOLX2_1(op1, &bitD1);
1300 HUF_DECODE_SYMBOLX2_2(op1, &bitD1);
1301 HUF_DECODE_SYMBOLX2_0(op1, &bitD1);
1302 HUF_DECODE_SYMBOLX2_2(op2, &bitD2);
1303 HUF_DECODE_SYMBOLX2_1(op2, &bitD2);
1304 HUF_DECODE_SYMBOLX2_2(op2, &bitD2);
1305 HUF_DECODE_SYMBOLX2_0(op2, &bitD2);
1306 endSignal &= BIT_reloadDStreamFast(&bitD1) == BIT_DStream_unfinished;
1307 endSignal &= BIT_reloadDStreamFast(&bitD2) == BIT_DStream_unfinished;
1308 HUF_DECODE_SYMBOLX2_2(op3, &bitD3);
1309 HUF_DECODE_SYMBOLX2_1(op3, &bitD3);
1310 HUF_DECODE_SYMBOLX2_2(op3, &bitD3);
1311 HUF_DECODE_SYMBOLX2_0(op3, &bitD3);
1312 HUF_DECODE_SYMBOLX2_2(op4, &bitD4);
1313 HUF_DECODE_SYMBOLX2_1(op4, &bitD4);
1314 HUF_DECODE_SYMBOLX2_2(op4, &bitD4);
1315 HUF_DECODE_SYMBOLX2_0(op4, &bitD4);
1316 endSignal &= BIT_reloadDStreamFast(&bitD3) == BIT_DStream_unfinished;
1317 endSignal &= BIT_reloadDStreamFast(&bitD4) == BIT_DStream_unfinished;
1318#else
1319 HUF_DECODE_SYMBOLX2_2(op1, &bitD1);
1320 HUF_DECODE_SYMBOLX2_2(op2, &bitD2);
1321 HUF_DECODE_SYMBOLX2_2(op3, &bitD3);
1322 HUF_DECODE_SYMBOLX2_2(op4, &bitD4);
1323 HUF_DECODE_SYMBOLX2_1(op1, &bitD1);
1324 HUF_DECODE_SYMBOLX2_1(op2, &bitD2);
1325 HUF_DECODE_SYMBOLX2_1(op3, &bitD3);
1326 HUF_DECODE_SYMBOLX2_1(op4, &bitD4);
1327 HUF_DECODE_SYMBOLX2_2(op1, &bitD1);
1328 HUF_DECODE_SYMBOLX2_2(op2, &bitD2);
1329 HUF_DECODE_SYMBOLX2_2(op3, &bitD3);
1330 HUF_DECODE_SYMBOLX2_2(op4, &bitD4);
1331 HUF_DECODE_SYMBOLX2_0(op1, &bitD1);
1332 HUF_DECODE_SYMBOLX2_0(op2, &bitD2);
1333 HUF_DECODE_SYMBOLX2_0(op3, &bitD3);
1334 HUF_DECODE_SYMBOLX2_0(op4, &bitD4);
1335 endSignal = (U32)LIKELY((U32)
1336 (BIT_reloadDStreamFast(&bitD1) == BIT_DStream_unfinished)
1337 & (BIT_reloadDStreamFast(&bitD2) == BIT_DStream_unfinished)
1338 & (BIT_reloadDStreamFast(&bitD3) == BIT_DStream_unfinished)
1339 & (BIT_reloadDStreamFast(&bitD4) == BIT_DStream_unfinished));
1340#endif
1341 }
1342 }
1343
1344 /* check corruption */
1345 if (op1 > opStart2) return ERROR(corruption_detected);
1346 if (op2 > opStart3) return ERROR(corruption_detected);
1347 if (op3 > opStart4) return ERROR(corruption_detected);
1348 /* note : op4 already verified within main loop */
1349
1350 /* finish bitStreams one by one */
1351 HUF_decodeStreamX2(op1, &bitD1, opStart2, dt, dtLog);
1352 HUF_decodeStreamX2(op2, &bitD2, opStart3, dt, dtLog);
1353 HUF_decodeStreamX2(op3, &bitD3, opStart4, dt, dtLog);
1354 HUF_decodeStreamX2(op4, &bitD4, oend, dt, dtLog);
1355
1356 /* check */
1357 { U32 const endCheck = BIT_endOfDStream(&bitD1) & BIT_endOfDStream(&bitD2) & BIT_endOfDStream(&bitD3) & BIT_endOfDStream(&bitD4);
1358 if (!endCheck) return ERROR(corruption_detected); }
1359
1360 /* decoded size */
1361 return dstSize;
1362 }
1363}
1364
1365#if HUF_NEED_BMI2_FUNCTION
1366static BMI2_TARGET_ATTRIBUTE
1367size_t HUF_decompress4X2_usingDTable_internal_bmi2(void* dst, size_t dstSize, void const* cSrc,
1368 size_t cSrcSize, HUF_DTable const* DTable) {
1369 return HUF_decompress4X2_usingDTable_internal_body(dst, dstSize, cSrc, cSrcSize, DTable);
1370}
1371#endif
1372
1373#if HUF_NEED_DEFAULT_FUNCTION
1374static
1375size_t HUF_decompress4X2_usingDTable_internal_default(void* dst, size_t dstSize, void const* cSrc,
1376 size_t cSrcSize, HUF_DTable const* DTable) {
1377 return HUF_decompress4X2_usingDTable_internal_body(dst, dstSize, cSrc, cSrcSize, DTable);
1378}
1379#endif
1380
1381#if ZSTD_ENABLE_ASM_X86_64_BMI2
1382
1383HUF_ASM_DECL void HUF_decompress4X2_usingDTable_internal_bmi2_asm_loop(HUF_DecompressAsmArgs* args) ZSTDLIB_HIDDEN;
1384
1385static HUF_ASM_X86_64_BMI2_ATTRS size_t
1386HUF_decompress4X2_usingDTable_internal_bmi2_asm(
1387 void* dst, size_t dstSize,
1388 const void* cSrc, size_t cSrcSize,
1389 const HUF_DTable* DTable) {
1390 void const* dt = DTable + 1;
1391 const BYTE* const iend = (const BYTE*)cSrc + 6;
1392 BYTE* const oend = (BYTE*)dst + dstSize;
1393 HUF_DecompressAsmArgs args;
1394 {
1395 size_t const ret = HUF_DecompressAsmArgs_init(&args, dst, dstSize, cSrc, cSrcSize, DTable);
1396 FORWARD_IF_ERROR(ret, "Failed to init asm args");
1397 if (ret != 0)
1398 return HUF_decompress4X2_usingDTable_internal_bmi2(dst, dstSize, cSrc, cSrcSize, DTable);
1399 }
1400
1401 assert(args.ip[0] >= args.ilimit);
1402 HUF_decompress4X2_usingDTable_internal_bmi2_asm_loop(&args);
1403
1404 /* note : op4 already verified within main loop */
1405 assert(args.ip[0] >= iend);
1406 assert(args.ip[1] >= iend);
1407 assert(args.ip[2] >= iend);
1408 assert(args.ip[3] >= iend);
1409 assert(args.op[3] <= oend);
1410 (void)iend;
1411
1412 /* finish bitStreams one by one */
1413 {
1414 size_t const segmentSize = (dstSize+3) / 4;
1415 BYTE* segmentEnd = (BYTE*)dst;
1416 int i;
1417 for (i = 0; i < 4; ++i) {
1418 BIT_DStream_t bit;
1419 if (segmentSize <= (size_t)(oend - segmentEnd))
1420 segmentEnd += segmentSize;
1421 else
1422 segmentEnd = oend;
1423 FORWARD_IF_ERROR(HUF_initRemainingDStream(&bit, &args, i, segmentEnd), "corruption");
1424 args.op[i] += HUF_decodeStreamX2(args.op[i], &bit, segmentEnd, (HUF_DEltX2 const*)dt, HUF_DECODER_FAST_TABLELOG);
1425 if (args.op[i] != segmentEnd)
1426 return ERROR(corruption_detected);
1427 }
1428 }
1429
1430 /* decoded size */
1431 return dstSize;
1432}
1433#endif /* ZSTD_ENABLE_ASM_X86_64_BMI2 */
1434
1435static size_t HUF_decompress4X2_usingDTable_internal(void* dst, size_t dstSize, void const* cSrc,
1436 size_t cSrcSize, HUF_DTable const* DTable, int bmi2)
1437{
1438#if DYNAMIC_BMI2
1439 if (bmi2) {
1440# if ZSTD_ENABLE_ASM_X86_64_BMI2
1441 return HUF_decompress4X2_usingDTable_internal_bmi2_asm(dst, dstSize, cSrc, cSrcSize, DTable);
1442# else
1443 return HUF_decompress4X2_usingDTable_internal_bmi2(dst, dstSize, cSrc, cSrcSize, DTable);
1444# endif
1445 }
1446#else
1447 (void)bmi2;
1448#endif
1449
1450#if ZSTD_ENABLE_ASM_X86_64_BMI2 && defined(__BMI2__)
1451 return HUF_decompress4X2_usingDTable_internal_bmi2_asm(dst, dstSize, cSrc, cSrcSize, DTable);
1452#else
1453 return HUF_decompress4X2_usingDTable_internal_default(dst, dstSize, cSrc, cSrcSize, DTable);
1454#endif
1455}
1456
1457HUF_DGEN(HUF_decompress1X2_usingDTable_internal)
1458
1459size_t HUF_decompress1X2_usingDTable(
1460 void* dst, size_t dstSize,
1461 const void* cSrc, size_t cSrcSize,
1462 const HUF_DTable* DTable)
1463{
1464 DTableDesc dtd = HUF_getDTableDesc(DTable);
1465 if (dtd.tableType != 1) return ERROR(GENERIC);
1466 return HUF_decompress1X2_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable, /* bmi2 */ 0);
1467}
1468
1469size_t HUF_decompress1X2_DCtx_wksp(HUF_DTable* DCtx, void* dst, size_t dstSize,
1470 const void* cSrc, size_t cSrcSize,
1471 void* workSpace, size_t wkspSize)
1472{
1473 const BYTE* ip = (const BYTE*) cSrc;
1474
1475 size_t const hSize = HUF_readDTableX2_wksp(DCtx, cSrc, cSrcSize,
1476 workSpace, wkspSize);
1477 if (HUF_isError(hSize)) return hSize;
1478 if (hSize >= cSrcSize) return ERROR(srcSize_wrong);
1479 ip += hSize; cSrcSize -= hSize;
1480
1481 return HUF_decompress1X2_usingDTable_internal(dst, dstSize, ip, cSrcSize, DCtx, /* bmi2 */ 0);
1482}
1483
1484
1485size_t HUF_decompress4X2_usingDTable(
1486 void* dst, size_t dstSize,
1487 const void* cSrc, size_t cSrcSize,
1488 const HUF_DTable* DTable)
1489{
1490 DTableDesc dtd = HUF_getDTableDesc(DTable);
1491 if (dtd.tableType != 1) return ERROR(GENERIC);
1492 return HUF_decompress4X2_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable, /* bmi2 */ 0);
1493}
1494
1495static size_t HUF_decompress4X2_DCtx_wksp_bmi2(HUF_DTable* dctx, void* dst, size_t dstSize,
1496 const void* cSrc, size_t cSrcSize,
1497 void* workSpace, size_t wkspSize, int bmi2)
1498{
1499 const BYTE* ip = (const BYTE*) cSrc;
1500
1501 size_t hSize = HUF_readDTableX2_wksp(dctx, cSrc, cSrcSize,
1502 workSpace, wkspSize);
1503 if (HUF_isError(hSize)) return hSize;
1504 if (hSize >= cSrcSize) return ERROR(srcSize_wrong);
1505 ip += hSize; cSrcSize -= hSize;
1506
1507 return HUF_decompress4X2_usingDTable_internal(dst, dstSize, ip, cSrcSize, dctx, bmi2);
1508}
1509
1510size_t HUF_decompress4X2_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize,
1511 const void* cSrc, size_t cSrcSize,
1512 void* workSpace, size_t wkspSize)
1513{
1514 return HUF_decompress4X2_DCtx_wksp_bmi2(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize, /* bmi2 */ 0);
1515}
1516
1517
1518#endif /* HUF_FORCE_DECOMPRESS_X1 */
1519
1520
1521/* ***********************************/
1522/* Universal decompression selectors */
1523/* ***********************************/
1524
1525size_t HUF_decompress1X_usingDTable(void* dst, size_t maxDstSize,
1526 const void* cSrc, size_t cSrcSize,
1527 const HUF_DTable* DTable)
1528{
1529 DTableDesc const dtd = HUF_getDTableDesc(DTable);
1530#if defined(HUF_FORCE_DECOMPRESS_X1)
1531 (void)dtd;
1532 assert(dtd.tableType == 0);
1533 return HUF_decompress1X1_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, /* bmi2 */ 0);
1534#elif defined(HUF_FORCE_DECOMPRESS_X2)
1535 (void)dtd;
1536 assert(dtd.tableType == 1);
1537 return HUF_decompress1X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, /* bmi2 */ 0);
1538#else
1539 return dtd.tableType ? HUF_decompress1X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, /* bmi2 */ 0) :
1540 HUF_decompress1X1_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, /* bmi2 */ 0);
1541#endif
1542}
1543
1544size_t HUF_decompress4X_usingDTable(void* dst, size_t maxDstSize,
1545 const void* cSrc, size_t cSrcSize,
1546 const HUF_DTable* DTable)
1547{
1548 DTableDesc const dtd = HUF_getDTableDesc(DTable);
1549#if defined(HUF_FORCE_DECOMPRESS_X1)
1550 (void)dtd;
1551 assert(dtd.tableType == 0);
1552 return HUF_decompress4X1_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, /* bmi2 */ 0);
1553#elif defined(HUF_FORCE_DECOMPRESS_X2)
1554 (void)dtd;
1555 assert(dtd.tableType == 1);
1556 return HUF_decompress4X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, /* bmi2 */ 0);
1557#else
1558 return dtd.tableType ? HUF_decompress4X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, /* bmi2 */ 0) :
1559 HUF_decompress4X1_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, /* bmi2 */ 0);
1560#endif
1561}
1562
1563
1564#if !defined(HUF_FORCE_DECOMPRESS_X1) && !defined(HUF_FORCE_DECOMPRESS_X2)
1565typedef struct { U32 tableTime; U32 decode256Time; } algo_time_t;
1566static const algo_time_t algoTime[16 /* Quantization */][2 /* single, double */] =
1567{
1568 /* single, double, quad */
1569 {{0,0}, {1,1}}, /* Q==0 : impossible */
1570 {{0,0}, {1,1}}, /* Q==1 : impossible */
1571 {{ 150,216}, { 381,119}}, /* Q == 2 : 12-18% */
1572 {{ 170,205}, { 514,112}}, /* Q == 3 : 18-25% */
1573 {{ 177,199}, { 539,110}}, /* Q == 4 : 25-32% */
1574 {{ 197,194}, { 644,107}}, /* Q == 5 : 32-38% */
1575 {{ 221,192}, { 735,107}}, /* Q == 6 : 38-44% */
1576 {{ 256,189}, { 881,106}}, /* Q == 7 : 44-50% */
1577 {{ 359,188}, {1167,109}}, /* Q == 8 : 50-56% */
1578 {{ 582,187}, {1570,114}}, /* Q == 9 : 56-62% */
1579 {{ 688,187}, {1712,122}}, /* Q ==10 : 62-69% */
1580 {{ 825,186}, {1965,136}}, /* Q ==11 : 69-75% */
1581 {{ 976,185}, {2131,150}}, /* Q ==12 : 75-81% */
1582 {{1180,186}, {2070,175}}, /* Q ==13 : 81-87% */
1583 {{1377,185}, {1731,202}}, /* Q ==14 : 87-93% */
1584 {{1412,185}, {1695,202}}, /* Q ==15 : 93-99% */
1585};
1586#endif
1587
1588/** HUF_selectDecoder() :
1589 * Tells which decoder is likely to decode faster,
1590 * based on a set of pre-computed metrics.
1591 * @return : 0==HUF_decompress4X1, 1==HUF_decompress4X2 .
1592 * Assumption : 0 < dstSize <= 128 KB */
1593U32 HUF_selectDecoder (size_t dstSize, size_t cSrcSize)
1594{
1595 assert(dstSize > 0);
1596 assert(dstSize <= 128*1024);
1597#if defined(HUF_FORCE_DECOMPRESS_X1)
1598 (void)dstSize;
1599 (void)cSrcSize;
1600 return 0;
1601#elif defined(HUF_FORCE_DECOMPRESS_X2)
1602 (void)dstSize;
1603 (void)cSrcSize;
1604 return 1;
1605#else
1606 /* decoder timing evaluation */
1607 { U32 const Q = (cSrcSize >= dstSize) ? 15 : (U32)(cSrcSize * 16 / dstSize); /* Q < 16 */
1608 U32 const D256 = (U32)(dstSize >> 8);
1609 U32 const DTime0 = algoTime[Q][0].tableTime + (algoTime[Q][0].decode256Time * D256);
1610 U32 DTime1 = algoTime[Q][1].tableTime + (algoTime[Q][1].decode256Time * D256);
1611 DTime1 += DTime1 >> 5; /* small advantage to algorithm using less memory, to reduce cache eviction */
1612 return DTime1 < DTime0;
1613 }
1614#endif
1615}
1616
1617
1618size_t HUF_decompress4X_hufOnly_wksp(HUF_DTable* dctx, void* dst,
1619 size_t dstSize, const void* cSrc,
1620 size_t cSrcSize, void* workSpace,
1621 size_t wkspSize)
1622{
1623 /* validation checks */
1624 if (dstSize == 0) return ERROR(dstSize_tooSmall);
1625 if (cSrcSize == 0) return ERROR(corruption_detected);
1626
1627 { U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);
1628#if defined(HUF_FORCE_DECOMPRESS_X1)
1629 (void)algoNb;
1630 assert(algoNb == 0);
1631 return HUF_decompress4X1_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize);
1632#elif defined(HUF_FORCE_DECOMPRESS_X2)
1633 (void)algoNb;
1634 assert(algoNb == 1);
1635 return HUF_decompress4X2_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize);
1636#else
1637 return algoNb ? HUF_decompress4X2_DCtx_wksp(dctx, dst, dstSize, cSrc,
1638 cSrcSize, workSpace, wkspSize):
1639 HUF_decompress4X1_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize);
1640#endif
1641 }
1642}
1643
1644size_t HUF_decompress1X_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize,
1645 const void* cSrc, size_t cSrcSize,
1646 void* workSpace, size_t wkspSize)
1647{
1648 /* validation checks */
1649 if (dstSize == 0) return ERROR(dstSize_tooSmall);
1650 if (cSrcSize > dstSize) return ERROR(corruption_detected); /* invalid */
1651 if (cSrcSize == dstSize) { ZSTD_memcpy(dst, cSrc, dstSize); return dstSize; } /* not compressed */
1652 if (cSrcSize == 1) { ZSTD_memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; } /* RLE */
1653
1654 { U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);
1655#if defined(HUF_FORCE_DECOMPRESS_X1)
1656 (void)algoNb;
1657 assert(algoNb == 0);
1658 return HUF_decompress1X1_DCtx_wksp(dctx, dst, dstSize, cSrc,
1659 cSrcSize, workSpace, wkspSize);
1660#elif defined(HUF_FORCE_DECOMPRESS_X2)
1661 (void)algoNb;
1662 assert(algoNb == 1);
1663 return HUF_decompress1X2_DCtx_wksp(dctx, dst, dstSize, cSrc,
1664 cSrcSize, workSpace, wkspSize);
1665#else
1666 return algoNb ? HUF_decompress1X2_DCtx_wksp(dctx, dst, dstSize, cSrc,
1667 cSrcSize, workSpace, wkspSize):
1668 HUF_decompress1X1_DCtx_wksp(dctx, dst, dstSize, cSrc,
1669 cSrcSize, workSpace, wkspSize);
1670#endif
1671 }
1672}
1673
1674
1675size_t HUF_decompress1X_usingDTable_bmi2(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable, int bmi2)
1676{
1677 DTableDesc const dtd = HUF_getDTableDesc(DTable);
1678#if defined(HUF_FORCE_DECOMPRESS_X1)
1679 (void)dtd;
1680 assert(dtd.tableType == 0);
1681 return HUF_decompress1X1_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, bmi2);
1682#elif defined(HUF_FORCE_DECOMPRESS_X2)
1683 (void)dtd;
1684 assert(dtd.tableType == 1);
1685 return HUF_decompress1X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, bmi2);
1686#else
1687 return dtd.tableType ? HUF_decompress1X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, bmi2) :
1688 HUF_decompress1X1_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, bmi2);
1689#endif
1690}
1691
1692#ifndef HUF_FORCE_DECOMPRESS_X2
1693size_t HUF_decompress1X1_DCtx_wksp_bmi2(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int bmi2)
1694{
1695 const BYTE* ip = (const BYTE*) cSrc;
1696
1697 size_t const hSize = HUF_readDTableX1_wksp_bmi2(dctx, cSrc, cSrcSize, workSpace, wkspSize, bmi2);
1698 if (HUF_isError(hSize)) return hSize;
1699 if (hSize >= cSrcSize) return ERROR(srcSize_wrong);
1700 ip += hSize; cSrcSize -= hSize;
1701
1702 return HUF_decompress1X1_usingDTable_internal(dst, dstSize, ip, cSrcSize, dctx, bmi2);
1703}
1704#endif
1705
1706size_t HUF_decompress4X_usingDTable_bmi2(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable, int bmi2)
1707{
1708 DTableDesc const dtd = HUF_getDTableDesc(DTable);
1709#if defined(HUF_FORCE_DECOMPRESS_X1)
1710 (void)dtd;
1711 assert(dtd.tableType == 0);
1712 return HUF_decompress4X1_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, bmi2);
1713#elif defined(HUF_FORCE_DECOMPRESS_X2)
1714 (void)dtd;
1715 assert(dtd.tableType == 1);
1716 return HUF_decompress4X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, bmi2);
1717#else
1718 return dtd.tableType ? HUF_decompress4X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, bmi2) :
1719 HUF_decompress4X1_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, bmi2);
1720#endif
1721}
1722
1723size_t HUF_decompress4X_hufOnly_wksp_bmi2(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int bmi2)
1724{
1725 /* validation checks */
1726 if (dstSize == 0) return ERROR(dstSize_tooSmall);
1727 if (cSrcSize == 0) return ERROR(corruption_detected);
1728
1729 { U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);
1730#if defined(HUF_FORCE_DECOMPRESS_X1)
1731 (void)algoNb;
1732 assert(algoNb == 0);
1733 return HUF_decompress4X1_DCtx_wksp_bmi2(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize, bmi2);
1734#elif defined(HUF_FORCE_DECOMPRESS_X2)
1735 (void)algoNb;
1736 assert(algoNb == 1);
1737 return HUF_decompress4X2_DCtx_wksp_bmi2(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize, bmi2);
1738#else
1739 return algoNb ? HUF_decompress4X2_DCtx_wksp_bmi2(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize, bmi2) :
1740 HUF_decompress4X1_DCtx_wksp_bmi2(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize, bmi2);
1741#endif
1742 }
1743}
1744
1745#ifndef ZSTD_NO_UNUSED_FUNCTIONS
1746#ifndef HUF_FORCE_DECOMPRESS_X2
1747size_t HUF_readDTableX1(HUF_DTable* DTable, const void* src, size_t srcSize)
1748{
1749 U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32];
1750 return HUF_readDTableX1_wksp(DTable, src, srcSize,
1751 workSpace, sizeof(workSpace));
1752}
1753
1754size_t HUF_decompress1X1_DCtx(HUF_DTable* DCtx, void* dst, size_t dstSize,
1755 const void* cSrc, size_t cSrcSize)
1756{
1757 U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32];
1758 return HUF_decompress1X1_DCtx_wksp(DCtx, dst, dstSize, cSrc, cSrcSize,
1759 workSpace, sizeof(workSpace));
1760}
1761
1762size_t HUF_decompress1X1 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
1763{
1764 HUF_CREATE_STATIC_DTABLEX1(DTable, HUF_TABLELOG_MAX);
1765 return HUF_decompress1X1_DCtx (DTable, dst, dstSize, cSrc, cSrcSize);
1766}
1767#endif
1768
1769#ifndef HUF_FORCE_DECOMPRESS_X1
1770size_t HUF_readDTableX2(HUF_DTable* DTable, const void* src, size_t srcSize)
1771{
1772 U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32];
1773 return HUF_readDTableX2_wksp(DTable, src, srcSize,
1774 workSpace, sizeof(workSpace));
1775}
1776
1777size_t HUF_decompress1X2_DCtx(HUF_DTable* DCtx, void* dst, size_t dstSize,
1778 const void* cSrc, size_t cSrcSize)
1779{
1780 U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32];
1781 return HUF_decompress1X2_DCtx_wksp(DCtx, dst, dstSize, cSrc, cSrcSize,
1782 workSpace, sizeof(workSpace));
1783}
1784
1785size_t HUF_decompress1X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
1786{
1787 HUF_CREATE_STATIC_DTABLEX2(DTable, HUF_TABLELOG_MAX);
1788 return HUF_decompress1X2_DCtx(DTable, dst, dstSize, cSrc, cSrcSize);
1789}
1790#endif
1791
1792#ifndef HUF_FORCE_DECOMPRESS_X2
1793size_t HUF_decompress4X1_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
1794{
1795 U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32];
1796 return HUF_decompress4X1_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize,
1797 workSpace, sizeof(workSpace));
1798}
1799size_t HUF_decompress4X1 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
1800{
1801 HUF_CREATE_STATIC_DTABLEX1(DTable, HUF_TABLELOG_MAX);
1802 return HUF_decompress4X1_DCtx(DTable, dst, dstSize, cSrc, cSrcSize);
1803}
1804#endif
1805
1806#ifndef HUF_FORCE_DECOMPRESS_X1
1807size_t HUF_decompress4X2_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize,
1808 const void* cSrc, size_t cSrcSize)
1809{
1810 U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32];
1811 return HUF_decompress4X2_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize,
1812 workSpace, sizeof(workSpace));
1813}
1814
1815size_t HUF_decompress4X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
1816{
1817 HUF_CREATE_STATIC_DTABLEX2(DTable, HUF_TABLELOG_MAX);
1818 return HUF_decompress4X2_DCtx(DTable, dst, dstSize, cSrc, cSrcSize);
1819}
1820#endif
1821
1822typedef size_t (*decompressionAlgo)(void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);
1823
1824size_t HUF_decompress (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
1825{
1826#if !defined(HUF_FORCE_DECOMPRESS_X1) && !defined(HUF_FORCE_DECOMPRESS_X2)
1827 static const decompressionAlgo decompress[2] = { HUF_decompress4X1, HUF_decompress4X2 };
1828#endif
1829
1830 /* validation checks */
1831 if (dstSize == 0) return ERROR(dstSize_tooSmall);
1832 if (cSrcSize > dstSize) return ERROR(corruption_detected); /* invalid */
1833 if (cSrcSize == dstSize) { ZSTD_memcpy(dst, cSrc, dstSize); return dstSize; } /* not compressed */
1834 if (cSrcSize == 1) { ZSTD_memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; } /* RLE */
1835
1836 { U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);
1837#if defined(HUF_FORCE_DECOMPRESS_X1)
1838 (void)algoNb;
1839 assert(algoNb == 0);
1840 return HUF_decompress4X1(dst, dstSize, cSrc, cSrcSize);
1841#elif defined(HUF_FORCE_DECOMPRESS_X2)
1842 (void)algoNb;
1843 assert(algoNb == 1);
1844 return HUF_decompress4X2(dst, dstSize, cSrc, cSrcSize);
1845#else
1846 return decompress[algoNb](dst, dstSize, cSrc, cSrcSize);
1847#endif
1848 }
1849}
1850
1851size_t HUF_decompress4X_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
1852{
1853 /* validation checks */
1854 if (dstSize == 0) return ERROR(dstSize_tooSmall);
1855 if (cSrcSize > dstSize) return ERROR(corruption_detected); /* invalid */
1856 if (cSrcSize == dstSize) { ZSTD_memcpy(dst, cSrc, dstSize); return dstSize; } /* not compressed */
1857 if (cSrcSize == 1) { ZSTD_memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; } /* RLE */
1858
1859 { U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);
1860#if defined(HUF_FORCE_DECOMPRESS_X1)
1861 (void)algoNb;
1862 assert(algoNb == 0);
1863 return HUF_decompress4X1_DCtx(dctx, dst, dstSize, cSrc, cSrcSize);
1864#elif defined(HUF_FORCE_DECOMPRESS_X2)
1865 (void)algoNb;
1866 assert(algoNb == 1);
1867 return HUF_decompress4X2_DCtx(dctx, dst, dstSize, cSrc, cSrcSize);
1868#else
1869 return algoNb ? HUF_decompress4X2_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) :
1870 HUF_decompress4X1_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) ;
1871#endif
1872 }
1873}
1874
1875size_t HUF_decompress4X_hufOnly(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
1876{
1877 U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32];
1878 return HUF_decompress4X_hufOnly_wksp(dctx, dst, dstSize, cSrc, cSrcSize,
1879 workSpace, sizeof(workSpace));
1880}
1881
1882size_t HUF_decompress1X_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize,
1883 const void* cSrc, size_t cSrcSize)
1884{
1885 U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32];
1886 return HUF_decompress1X_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize,
1887 workSpace, sizeof(workSpace));
1888}
1889#endif
stage1/zstd/lib/decompress/huf_decompress_amd64.S created+585
......@@ -0,0 +1,585 @@
1/*
2 * Copyright (c) Facebook, Inc.
3 * All rights reserved.
4 *
5 * This source code is licensed under both the BSD-style license (found in the
6 * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7 * in the COPYING file in the root directory of this source tree).
8 * You may select, at your option, one of the above-listed licenses.
9 */
10
11#include "../common/portability_macros.h"
12
13/* Stack marking
14 * ref: https://wiki.gentoo.org/wiki/Hardened/GNU_stack_quickstart
15 */
16#if defined(__ELF__) && defined(__GNUC__)
17.section .note.GNU-stack,"",%progbits
18#endif
19
20#if ZSTD_ENABLE_ASM_X86_64_BMI2
21
22/* Calling convention:
23 *
24 * %rdi contains the first argument: HUF_DecompressAsmArgs*.
25 * %rbp isn't maintained (no frame pointer).
26 * %rsp contains the stack pointer that grows down.
27 * No red-zone is assumed, only addresses >= %rsp are used.
28 * All register contents are preserved.
29 *
30 * TODO: Support Windows calling convention.
31 */
32
33ZSTD_HIDE_ASM_FUNCTION(HUF_decompress4X1_usingDTable_internal_bmi2_asm_loop)
34ZSTD_HIDE_ASM_FUNCTION(HUF_decompress4X2_usingDTable_internal_bmi2_asm_loop)
35ZSTD_HIDE_ASM_FUNCTION(_HUF_decompress4X2_usingDTable_internal_bmi2_asm_loop)
36ZSTD_HIDE_ASM_FUNCTION(_HUF_decompress4X1_usingDTable_internal_bmi2_asm_loop)
37.global HUF_decompress4X1_usingDTable_internal_bmi2_asm_loop
38.global HUF_decompress4X2_usingDTable_internal_bmi2_asm_loop
39.global _HUF_decompress4X1_usingDTable_internal_bmi2_asm_loop
40.global _HUF_decompress4X2_usingDTable_internal_bmi2_asm_loop
41.text
42
43/* Sets up register mappings for clarity.
44 * op[], bits[], dtable & ip[0] each get their own register.
45 * ip[1,2,3] & olimit alias var[].
46 * %rax is a scratch register.
47 */
48
49#define op0 rsi
50#define op1 rbx
51#define op2 rcx
52#define op3 rdi
53
54#define ip0 r8
55#define ip1 r9
56#define ip2 r10
57#define ip3 r11
58
59#define bits0 rbp
60#define bits1 rdx
61#define bits2 r12
62#define bits3 r13
63#define dtable r14
64#define olimit r15
65
66/* var[] aliases ip[1,2,3] & olimit
67 * ip[1,2,3] are saved every iteration.
68 * olimit is only used in compute_olimit.
69 */
70#define var0 r15
71#define var1 r9
72#define var2 r10
73#define var3 r11
74
75/* 32-bit var registers */
76#define vard0 r15d
77#define vard1 r9d
78#define vard2 r10d
79#define vard3 r11d
80
81/* Calls X(N) for each stream 0, 1, 2, 3. */
82#define FOR_EACH_STREAM(X) \
83 X(0); \
84 X(1); \
85 X(2); \
86 X(3)
87
88/* Calls X(N, idx) for each stream 0, 1, 2, 3. */
89#define FOR_EACH_STREAM_WITH_INDEX(X, idx) \
90 X(0, idx); \
91 X(1, idx); \
92 X(2, idx); \
93 X(3, idx)
94
95/* Define both _HUF_* & HUF_* symbols because MacOS
96 * C symbols are prefixed with '_' & Linux symbols aren't.
97 */
98_HUF_decompress4X1_usingDTable_internal_bmi2_asm_loop:
99HUF_decompress4X1_usingDTable_internal_bmi2_asm_loop:
100 /* Save all registers - even if they are callee saved for simplicity. */
101 push %rax
102 push %rbx
103 push %rcx
104 push %rdx
105 push %rbp
106 push %rsi
107 push %rdi
108 push %r8
109 push %r9
110 push %r10
111 push %r11
112 push %r12
113 push %r13
114 push %r14
115 push %r15
116
117 /* Read HUF_DecompressAsmArgs* args from %rax */
118 movq %rdi, %rax
119 movq 0(%rax), %ip0
120 movq 8(%rax), %ip1
121 movq 16(%rax), %ip2
122 movq 24(%rax), %ip3
123 movq 32(%rax), %op0
124 movq 40(%rax), %op1
125 movq 48(%rax), %op2
126 movq 56(%rax), %op3
127 movq 64(%rax), %bits0
128 movq 72(%rax), %bits1
129 movq 80(%rax), %bits2
130 movq 88(%rax), %bits3
131 movq 96(%rax), %dtable
132 push %rax /* argument */
133 push 104(%rax) /* ilimit */
134 push 112(%rax) /* oend */
135 push %olimit /* olimit space */
136
137 subq $24, %rsp
138
139.L_4X1_compute_olimit:
140 /* Computes how many iterations we can do safely
141 * %r15, %rax may be clobbered
142 * rbx, rdx must be saved
143 * op3 & ip0 mustn't be clobbered
144 */
145 movq %rbx, 0(%rsp)
146 movq %rdx, 8(%rsp)
147
148 movq 32(%rsp), %rax /* rax = oend */
149 subq %op3, %rax /* rax = oend - op3 */
150
151 /* r15 = (oend - op3) / 5 */
152 movabsq $-3689348814741910323, %rdx
153 mulq %rdx
154 movq %rdx, %r15
155 shrq $2, %r15
156
157 movq %ip0, %rax /* rax = ip0 */
158 movq 40(%rsp), %rdx /* rdx = ilimit */
159 subq %rdx, %rax /* rax = ip0 - ilimit */
160 movq %rax, %rbx /* rbx = ip0 - ilimit */
161
162 /* rdx = (ip0 - ilimit) / 7 */
163 movabsq $2635249153387078803, %rdx
164 mulq %rdx
165 subq %rdx, %rbx
166 shrq %rbx
167 addq %rbx, %rdx
168 shrq $2, %rdx
169
170 /* r15 = min(%rdx, %r15) */
171 cmpq %rdx, %r15
172 cmova %rdx, %r15
173
174 /* r15 = r15 * 5 */
175 leaq (%r15, %r15, 4), %r15
176
177 /* olimit = op3 + r15 */
178 addq %op3, %olimit
179
180 movq 8(%rsp), %rdx
181 movq 0(%rsp), %rbx
182
183 /* If (op3 + 20 > olimit) */
184 movq %op3, %rax /* rax = op3 */
185 addq $20, %rax /* rax = op3 + 20 */
186 cmpq %rax, %olimit /* op3 + 20 > olimit */
187 jb .L_4X1_exit
188
189 /* If (ip1 < ip0) go to exit */
190 cmpq %ip0, %ip1
191 jb .L_4X1_exit
192
193 /* If (ip2 < ip1) go to exit */
194 cmpq %ip1, %ip2
195 jb .L_4X1_exit
196
197 /* If (ip3 < ip2) go to exit */
198 cmpq %ip2, %ip3
199 jb .L_4X1_exit
200
201/* Reads top 11 bits from bits[n]
202 * Loads dt[bits[n]] into var[n]
203 */
204#define GET_NEXT_DELT(n) \
205 movq $53, %var##n; \
206 shrxq %var##n, %bits##n, %var##n; \
207 movzwl (%dtable,%var##n,2),%vard##n
208
209/* var[n] must contain the DTable entry computed with GET_NEXT_DELT
210 * Moves var[n] to %rax
211 * bits[n] <<= var[n] & 63
212 * op[n][idx] = %rax >> 8
213 * %ah is a way to access bits [8, 16) of %rax
214 */
215#define DECODE_FROM_DELT(n, idx) \
216 movq %var##n, %rax; \
217 shlxq %var##n, %bits##n, %bits##n; \
218 movb %ah, idx(%op##n)
219
220/* Assumes GET_NEXT_DELT has been called.
221 * Calls DECODE_FROM_DELT then GET_NEXT_DELT
222 */
223#define DECODE_AND_GET_NEXT(n, idx) \
224 DECODE_FROM_DELT(n, idx); \
225 GET_NEXT_DELT(n) \
226
227/* // ctz & nbBytes is stored in bits[n]
228 * // nbBits is stored in %rax
229 * ctz = CTZ[bits[n]]
230 * nbBits = ctz & 7
231 * nbBytes = ctz >> 3
232 * op[n] += 5
233 * ip[n] -= nbBytes
234 * // Note: x86-64 is little-endian ==> no bswap
235 * bits[n] = MEM_readST(ip[n]) | 1
236 * bits[n] <<= nbBits
237 */
238#define RELOAD_BITS(n) \
239 bsfq %bits##n, %bits##n; \
240 movq %bits##n, %rax; \
241 andq $7, %rax; \
242 shrq $3, %bits##n; \
243 leaq 5(%op##n), %op##n; \
244 subq %bits##n, %ip##n; \
245 movq (%ip##n), %bits##n; \
246 orq $1, %bits##n; \
247 shlx %rax, %bits##n, %bits##n
248
249 /* Store clobbered variables on the stack */
250 movq %olimit, 24(%rsp)
251 movq %ip1, 0(%rsp)
252 movq %ip2, 8(%rsp)
253 movq %ip3, 16(%rsp)
254
255 /* Call GET_NEXT_DELT for each stream */
256 FOR_EACH_STREAM(GET_NEXT_DELT)
257
258 .p2align 6
259
260.L_4X1_loop_body:
261 /* Decode 5 symbols in each of the 4 streams (20 total)
262 * Must have called GET_NEXT_DELT for each stream
263 */
264 FOR_EACH_STREAM_WITH_INDEX(DECODE_AND_GET_NEXT, 0)
265 FOR_EACH_STREAM_WITH_INDEX(DECODE_AND_GET_NEXT, 1)
266 FOR_EACH_STREAM_WITH_INDEX(DECODE_AND_GET_NEXT, 2)
267 FOR_EACH_STREAM_WITH_INDEX(DECODE_AND_GET_NEXT, 3)
268 FOR_EACH_STREAM_WITH_INDEX(DECODE_FROM_DELT, 4)
269
270 /* Load ip[1,2,3] from stack (var[] aliases them)
271 * ip[] is needed for RELOAD_BITS
272 * Each will be stored back to the stack after RELOAD
273 */
274 movq 0(%rsp), %ip1
275 movq 8(%rsp), %ip2
276 movq 16(%rsp), %ip3
277
278 /* Reload each stream & fetch the next table entry
279 * to prepare for the next iteration
280 */
281 RELOAD_BITS(0)
282 GET_NEXT_DELT(0)
283
284 RELOAD_BITS(1)
285 movq %ip1, 0(%rsp)
286 GET_NEXT_DELT(1)
287
288 RELOAD_BITS(2)
289 movq %ip2, 8(%rsp)
290 GET_NEXT_DELT(2)
291
292 RELOAD_BITS(3)
293 movq %ip3, 16(%rsp)
294 GET_NEXT_DELT(3)
295
296 /* If op3 < olimit: continue the loop */
297 cmp %op3, 24(%rsp)
298 ja .L_4X1_loop_body
299
300 /* Reload ip[1,2,3] from stack */
301 movq 0(%rsp), %ip1
302 movq 8(%rsp), %ip2
303 movq 16(%rsp), %ip3
304
305 /* Re-compute olimit */
306 jmp .L_4X1_compute_olimit
307
308#undef GET_NEXT_DELT
309#undef DECODE_FROM_DELT
310#undef DECODE
311#undef RELOAD_BITS
312.L_4X1_exit:
313 addq $24, %rsp
314
315 /* Restore stack (oend & olimit) */
316 pop %rax /* olimit */
317 pop %rax /* oend */
318 pop %rax /* ilimit */
319 pop %rax /* arg */
320
321 /* Save ip / op / bits */
322 movq %ip0, 0(%rax)
323 movq %ip1, 8(%rax)
324 movq %ip2, 16(%rax)
325 movq %ip3, 24(%rax)
326 movq %op0, 32(%rax)
327 movq %op1, 40(%rax)
328 movq %op2, 48(%rax)
329 movq %op3, 56(%rax)
330 movq %bits0, 64(%rax)
331 movq %bits1, 72(%rax)
332 movq %bits2, 80(%rax)
333 movq %bits3, 88(%rax)
334
335 /* Restore registers */
336 pop %r15
337 pop %r14
338 pop %r13
339 pop %r12
340 pop %r11
341 pop %r10
342 pop %r9
343 pop %r8
344 pop %rdi
345 pop %rsi
346 pop %rbp
347 pop %rdx
348 pop %rcx
349 pop %rbx
350 pop %rax
351 ret
352
353_HUF_decompress4X2_usingDTable_internal_bmi2_asm_loop:
354HUF_decompress4X2_usingDTable_internal_bmi2_asm_loop:
355 /* Save all registers - even if they are callee saved for simplicity. */
356 push %rax
357 push %rbx
358 push %rcx
359 push %rdx
360 push %rbp
361 push %rsi
362 push %rdi
363 push %r8
364 push %r9
365 push %r10
366 push %r11
367 push %r12
368 push %r13
369 push %r14
370 push %r15
371
372 movq %rdi, %rax
373 movq 0(%rax), %ip0
374 movq 8(%rax), %ip1
375 movq 16(%rax), %ip2
376 movq 24(%rax), %ip3
377 movq 32(%rax), %op0
378 movq 40(%rax), %op1
379 movq 48(%rax), %op2
380 movq 56(%rax), %op3
381 movq 64(%rax), %bits0
382 movq 72(%rax), %bits1
383 movq 80(%rax), %bits2
384 movq 88(%rax), %bits3
385 movq 96(%rax), %dtable
386 push %rax /* argument */
387 push %rax /* olimit */
388 push 104(%rax) /* ilimit */
389
390 movq 112(%rax), %rax
391 push %rax /* oend3 */
392
393 movq %op3, %rax
394 push %rax /* oend2 */
395
396 movq %op2, %rax
397 push %rax /* oend1 */
398
399 movq %op1, %rax
400 push %rax /* oend0 */
401
402 /* Scratch space */
403 subq $8, %rsp
404
405.L_4X2_compute_olimit:
406 /* Computes how many iterations we can do safely
407 * %r15, %rax may be clobbered
408 * rdx must be saved
409 * op[1,2,3,4] & ip0 mustn't be clobbered
410 */
411 movq %rdx, 0(%rsp)
412
413 /* We can consume up to 7 input bytes each iteration. */
414 movq %ip0, %rax /* rax = ip0 */
415 movq 40(%rsp), %rdx /* rdx = ilimit */
416 subq %rdx, %rax /* rax = ip0 - ilimit */
417 movq %rax, %r15 /* r15 = ip0 - ilimit */
418
419 /* rdx = rax / 7 */
420 movabsq $2635249153387078803, %rdx
421 mulq %rdx
422 subq %rdx, %r15
423 shrq %r15
424 addq %r15, %rdx
425 shrq $2, %rdx
426
427 /* r15 = (ip0 - ilimit) / 7 */
428 movq %rdx, %r15
429
430 movabsq $-3689348814741910323, %rdx
431 movq 8(%rsp), %rax /* rax = oend0 */
432 subq %op0, %rax /* rax = oend0 - op0 */
433 mulq %rdx
434 shrq $3, %rdx /* rdx = rax / 10 */
435
436 /* r15 = min(%rdx, %r15) */
437 cmpq %rdx, %r15
438 cmova %rdx, %r15
439
440 movabsq $-3689348814741910323, %rdx
441 movq 16(%rsp), %rax /* rax = oend1 */
442 subq %op1, %rax /* rax = oend1 - op1 */
443 mulq %rdx
444 shrq $3, %rdx /* rdx = rax / 10 */
445
446 /* r15 = min(%rdx, %r15) */
447 cmpq %rdx, %r15
448 cmova %rdx, %r15
449
450 movabsq $-3689348814741910323, %rdx
451 movq 24(%rsp), %rax /* rax = oend2 */
452 subq %op2, %rax /* rax = oend2 - op2 */
453 mulq %rdx
454 shrq $3, %rdx /* rdx = rax / 10 */
455
456 /* r15 = min(%rdx, %r15) */
457 cmpq %rdx, %r15
458 cmova %rdx, %r15
459
460 movabsq $-3689348814741910323, %rdx
461 movq 32(%rsp), %rax /* rax = oend3 */
462 subq %op3, %rax /* rax = oend3 - op3 */
463 mulq %rdx
464 shrq $3, %rdx /* rdx = rax / 10 */
465
466 /* r15 = min(%rdx, %r15) */
467 cmpq %rdx, %r15
468 cmova %rdx, %r15
469
470 /* olimit = op3 + 5 * r15 */
471 movq %r15, %rax
472 leaq (%op3, %rax, 4), %olimit
473 addq %rax, %olimit
474
475 movq 0(%rsp), %rdx
476
477 /* If (op3 + 10 > olimit) */
478 movq %op3, %rax /* rax = op3 */
479 addq $10, %rax /* rax = op3 + 10 */
480 cmpq %rax, %olimit /* op3 + 10 > olimit */
481 jb .L_4X2_exit
482
483 /* If (ip1 < ip0) go to exit */
484 cmpq %ip0, %ip1
485 jb .L_4X2_exit
486
487 /* If (ip2 < ip1) go to exit */
488 cmpq %ip1, %ip2
489 jb .L_4X2_exit
490
491 /* If (ip3 < ip2) go to exit */
492 cmpq %ip2, %ip3
493 jb .L_4X2_exit
494
495#define DECODE(n, idx) \
496 movq %bits##n, %rax; \
497 shrq $53, %rax; \
498 movzwl 0(%dtable,%rax,4),%r8d; \
499 movzbl 2(%dtable,%rax,4),%r15d; \
500 movzbl 3(%dtable,%rax,4),%eax; \
501 movw %r8w, (%op##n); \
502 shlxq %r15, %bits##n, %bits##n; \
503 addq %rax, %op##n
504
505#define RELOAD_BITS(n) \
506 bsfq %bits##n, %bits##n; \
507 movq %bits##n, %rax; \
508 shrq $3, %bits##n; \
509 andq $7, %rax; \
510 subq %bits##n, %ip##n; \
511 movq (%ip##n), %bits##n; \
512 orq $1, %bits##n; \
513 shlxq %rax, %bits##n, %bits##n
514
515
516 movq %olimit, 48(%rsp)
517
518 .p2align 6
519
520.L_4X2_loop_body:
521 /* We clobber r8, so store it on the stack */
522 movq %r8, 0(%rsp)
523
524 /* Decode 5 symbols from each of the 4 streams (20 symbols total). */
525 FOR_EACH_STREAM_WITH_INDEX(DECODE, 0)
526 FOR_EACH_STREAM_WITH_INDEX(DECODE, 1)
527 FOR_EACH_STREAM_WITH_INDEX(DECODE, 2)
528 FOR_EACH_STREAM_WITH_INDEX(DECODE, 3)
529 FOR_EACH_STREAM_WITH_INDEX(DECODE, 4)
530
531 /* Reload r8 */
532 movq 0(%rsp), %r8
533
534 FOR_EACH_STREAM(RELOAD_BITS)
535
536 cmp %op3, 48(%rsp)
537 ja .L_4X2_loop_body
538 jmp .L_4X2_compute_olimit
539
540#undef DECODE
541#undef RELOAD_BITS
542.L_4X2_exit:
543 addq $8, %rsp
544 /* Restore stack (oend & olimit) */
545 pop %rax /* oend0 */
546 pop %rax /* oend1 */
547 pop %rax /* oend2 */
548 pop %rax /* oend3 */
549 pop %rax /* ilimit */
550 pop %rax /* olimit */
551 pop %rax /* arg */
552
553 /* Save ip / op / bits */
554 movq %ip0, 0(%rax)
555 movq %ip1, 8(%rax)
556 movq %ip2, 16(%rax)
557 movq %ip3, 24(%rax)
558 movq %op0, 32(%rax)
559 movq %op1, 40(%rax)
560 movq %op2, 48(%rax)
561 movq %op3, 56(%rax)
562 movq %bits0, 64(%rax)
563 movq %bits1, 72(%rax)
564 movq %bits2, 80(%rax)
565 movq %bits3, 88(%rax)
566
567 /* Restore registers */
568 pop %r15
569 pop %r14
570 pop %r13
571 pop %r12
572 pop %r11
573 pop %r10
574 pop %r9
575 pop %r8
576 pop %rdi
577 pop %rsi
578 pop %rbp
579 pop %rdx
580 pop %rcx
581 pop %rbx
582 pop %rax
583 ret
584
585#endif
stage1/zstd/lib/decompress/zstd_ddict.c created+244
......@@ -0,0 +1,244 @@
1/*
2 * Copyright (c) Yann Collet, Facebook, Inc.
3 * All rights reserved.
4 *
5 * This source code is licensed under both the BSD-style license (found in the
6 * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7 * in the COPYING file in the root directory of this source tree).
8 * You may select, at your option, one of the above-listed licenses.
9 */
10
11/* zstd_ddict.c :
12 * concentrates all logic that needs to know the internals of ZSTD_DDict object */
13
14/*-*******************************************************
15* Dependencies
16*********************************************************/
17#include "../common/zstd_deps.h" /* ZSTD_memcpy, ZSTD_memmove, ZSTD_memset */
18#include "../common/cpu.h" /* bmi2 */
19#include "../common/mem.h" /* low level memory routines */
20#define FSE_STATIC_LINKING_ONLY
21#include "../common/fse.h"
22#define HUF_STATIC_LINKING_ONLY
23#include "../common/huf.h"
24#include "zstd_decompress_internal.h"
25#include "zstd_ddict.h"
26
27#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1)
28# include "../legacy/zstd_legacy.h"
29#endif
30
31
32
33/*-*******************************************************
34* Types
35*********************************************************/
36struct ZSTD_DDict_s {
37 void* dictBuffer;
38 const void* dictContent;
39 size_t dictSize;
40 ZSTD_entropyDTables_t entropy;
41 U32 dictID;
42 U32 entropyPresent;
43 ZSTD_customMem cMem;
44}; /* typedef'd to ZSTD_DDict within "zstd.h" */
45
46const void* ZSTD_DDict_dictContent(const ZSTD_DDict* ddict)
47{
48 assert(ddict != NULL);
49 return ddict->dictContent;
50}
51
52size_t ZSTD_DDict_dictSize(const ZSTD_DDict* ddict)
53{
54 assert(ddict != NULL);
55 return ddict->dictSize;
56}
57
58void ZSTD_copyDDictParameters(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict)
59{
60 DEBUGLOG(4, "ZSTD_copyDDictParameters");
61 assert(dctx != NULL);
62 assert(ddict != NULL);
63 dctx->dictID = ddict->dictID;
64 dctx->prefixStart = ddict->dictContent;
65 dctx->virtualStart = ddict->dictContent;
66 dctx->dictEnd = (const BYTE*)ddict->dictContent + ddict->dictSize;
67 dctx->previousDstEnd = dctx->dictEnd;
68#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
69 dctx->dictContentBeginForFuzzing = dctx->prefixStart;
70 dctx->dictContentEndForFuzzing = dctx->previousDstEnd;
71#endif
72 if (ddict->entropyPresent) {
73 dctx->litEntropy = 1;
74 dctx->fseEntropy = 1;
75 dctx->LLTptr = ddict->entropy.LLTable;
76 dctx->MLTptr = ddict->entropy.MLTable;
77 dctx->OFTptr = ddict->entropy.OFTable;
78 dctx->HUFptr = ddict->entropy.hufTable;
79 dctx->entropy.rep[0] = ddict->entropy.rep[0];
80 dctx->entropy.rep[1] = ddict->entropy.rep[1];
81 dctx->entropy.rep[2] = ddict->entropy.rep[2];
82 } else {
83 dctx->litEntropy = 0;
84 dctx->fseEntropy = 0;
85 }
86}
87
88
89static size_t
90ZSTD_loadEntropy_intoDDict(ZSTD_DDict* ddict,
91 ZSTD_dictContentType_e dictContentType)
92{
93 ddict->dictID = 0;
94 ddict->entropyPresent = 0;
95 if (dictContentType == ZSTD_dct_rawContent) return 0;
96
97 if (ddict->dictSize < 8) {
98 if (dictContentType == ZSTD_dct_fullDict)
99 return ERROR(dictionary_corrupted); /* only accept specified dictionaries */
100 return 0; /* pure content mode */
101 }
102 { U32 const magic = MEM_readLE32(ddict->dictContent);
103 if (magic != ZSTD_MAGIC_DICTIONARY) {
104 if (dictContentType == ZSTD_dct_fullDict)
105 return ERROR(dictionary_corrupted); /* only accept specified dictionaries */
106 return 0; /* pure content mode */
107 }
108 }
109 ddict->dictID = MEM_readLE32((const char*)ddict->dictContent + ZSTD_FRAMEIDSIZE);
110
111 /* load entropy tables */
112 RETURN_ERROR_IF(ZSTD_isError(ZSTD_loadDEntropy(
113 &ddict->entropy, ddict->dictContent, ddict->dictSize)),
114 dictionary_corrupted, "");
115 ddict->entropyPresent = 1;
116 return 0;
117}
118
119
120static size_t ZSTD_initDDict_internal(ZSTD_DDict* ddict,
121 const void* dict, size_t dictSize,
122 ZSTD_dictLoadMethod_e dictLoadMethod,
123 ZSTD_dictContentType_e dictContentType)
124{
125 if ((dictLoadMethod == ZSTD_dlm_byRef) || (!dict) || (!dictSize)) {
126 ddict->dictBuffer = NULL;
127 ddict->dictContent = dict;
128 if (!dict) dictSize = 0;
129 } else {
130 void* const internalBuffer = ZSTD_customMalloc(dictSize, ddict->cMem);
131 ddict->dictBuffer = internalBuffer;
132 ddict->dictContent = internalBuffer;
133 if (!internalBuffer) return ERROR(memory_allocation);
134 ZSTD_memcpy(internalBuffer, dict, dictSize);
135 }
136 ddict->dictSize = dictSize;
137 ddict->entropy.hufTable[0] = (HUF_DTable)((HufLog)*0x1000001); /* cover both little and big endian */
138
139 /* parse dictionary content */
140 FORWARD_IF_ERROR( ZSTD_loadEntropy_intoDDict(ddict, dictContentType) , "");
141
142 return 0;
143}
144
145ZSTD_DDict* ZSTD_createDDict_advanced(const void* dict, size_t dictSize,
146 ZSTD_dictLoadMethod_e dictLoadMethod,
147 ZSTD_dictContentType_e dictContentType,
148 ZSTD_customMem customMem)
149{
150 if ((!customMem.customAlloc) ^ (!customMem.customFree)) return NULL;
151
152 { ZSTD_DDict* const ddict = (ZSTD_DDict*) ZSTD_customMalloc(sizeof(ZSTD_DDict), customMem);
153 if (ddict == NULL) return NULL;
154 ddict->cMem = customMem;
155 { size_t const initResult = ZSTD_initDDict_internal(ddict,
156 dict, dictSize,
157 dictLoadMethod, dictContentType);
158 if (ZSTD_isError(initResult)) {
159 ZSTD_freeDDict(ddict);
160 return NULL;
161 } }
162 return ddict;
163 }
164}
165
166/*! ZSTD_createDDict() :
167* Create a digested dictionary, to start decompression without startup delay.
168* `dict` content is copied inside DDict.
169* Consequently, `dict` can be released after `ZSTD_DDict` creation */
170ZSTD_DDict* ZSTD_createDDict(const void* dict, size_t dictSize)
171{
172 ZSTD_customMem const allocator = { NULL, NULL, NULL };
173 return ZSTD_createDDict_advanced(dict, dictSize, ZSTD_dlm_byCopy, ZSTD_dct_auto, allocator);
174}
175
176/*! ZSTD_createDDict_byReference() :
177 * Create a digested dictionary, to start decompression without startup delay.
178 * Dictionary content is simply referenced, it will be accessed during decompression.
179 * Warning : dictBuffer must outlive DDict (DDict must be freed before dictBuffer) */
180ZSTD_DDict* ZSTD_createDDict_byReference(const void* dictBuffer, size_t dictSize)
181{
182 ZSTD_customMem const allocator = { NULL, NULL, NULL };
183 return ZSTD_createDDict_advanced(dictBuffer, dictSize, ZSTD_dlm_byRef, ZSTD_dct_auto, allocator);
184}
185
186
187const ZSTD_DDict* ZSTD_initStaticDDict(
188 void* sBuffer, size_t sBufferSize,
189 const void* dict, size_t dictSize,
190 ZSTD_dictLoadMethod_e dictLoadMethod,
191 ZSTD_dictContentType_e dictContentType)
192{
193 size_t const neededSpace = sizeof(ZSTD_DDict)
194 + (dictLoadMethod == ZSTD_dlm_byRef ? 0 : dictSize);
195 ZSTD_DDict* const ddict = (ZSTD_DDict*)sBuffer;
196 assert(sBuffer != NULL);
197 assert(dict != NULL);
198 if ((size_t)sBuffer & 7) return NULL; /* 8-aligned */
199 if (sBufferSize < neededSpace) return NULL;
200 if (dictLoadMethod == ZSTD_dlm_byCopy) {
201 ZSTD_memcpy(ddict+1, dict, dictSize); /* local copy */
202 dict = ddict+1;
203 }
204 if (ZSTD_isError( ZSTD_initDDict_internal(ddict,
205 dict, dictSize,
206 ZSTD_dlm_byRef, dictContentType) ))
207 return NULL;
208 return ddict;
209}
210
211
212size_t ZSTD_freeDDict(ZSTD_DDict* ddict)
213{
214 if (ddict==NULL) return 0; /* support free on NULL */
215 { ZSTD_customMem const cMem = ddict->cMem;
216 ZSTD_customFree(ddict->dictBuffer, cMem);
217 ZSTD_customFree(ddict, cMem);
218 return 0;
219 }
220}
221
222/*! ZSTD_estimateDDictSize() :
223 * Estimate amount of memory that will be needed to create a dictionary for decompression.
224 * Note : dictionary created by reference using ZSTD_dlm_byRef are smaller */
225size_t ZSTD_estimateDDictSize(size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod)
226{
227 return sizeof(ZSTD_DDict) + (dictLoadMethod == ZSTD_dlm_byRef ? 0 : dictSize);
228}
229
230size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict)
231{
232 if (ddict==NULL) return 0; /* support sizeof on NULL */
233 return sizeof(*ddict) + (ddict->dictBuffer ? ddict->dictSize : 0) ;
234}
235
236/*! ZSTD_getDictID_fromDDict() :
237 * Provides the dictID of the dictionary loaded into `ddict`.
238 * If @return == 0, the dictionary is not conformant to Zstandard specification, or empty.
239 * Non-conformant dictionaries can still be loaded, but as content-only dictionaries. */
240unsigned ZSTD_getDictID_fromDDict(const ZSTD_DDict* ddict)
241{
242 if (ddict==NULL) return 0;
243 return ZSTD_getDictID_fromDict(ddict->dictContent, ddict->dictSize);
244}
stage1/zstd/lib/decompress/zstd_ddict.h created+44
......@@ -0,0 +1,44 @@
1/*
2 * Copyright (c) Yann Collet, Facebook, Inc.
3 * All rights reserved.
4 *
5 * This source code is licensed under both the BSD-style license (found in the
6 * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7 * in the COPYING file in the root directory of this source tree).
8 * You may select, at your option, one of the above-listed licenses.
9 */
10
11
12#ifndef ZSTD_DDICT_H
13#define ZSTD_DDICT_H
14
15/*-*******************************************************
16 * Dependencies
17 *********************************************************/
18#include "../common/zstd_deps.h" /* size_t */
19#include "../zstd.h" /* ZSTD_DDict, and several public functions */
20
21
22/*-*******************************************************
23 * Interface
24 *********************************************************/
25
26/* note: several prototypes are already published in `zstd.h` :
27 * ZSTD_createDDict()
28 * ZSTD_createDDict_byReference()
29 * ZSTD_createDDict_advanced()
30 * ZSTD_freeDDict()
31 * ZSTD_initStaticDDict()
32 * ZSTD_sizeof_DDict()
33 * ZSTD_estimateDDictSize()
34 * ZSTD_getDictID_fromDict()
35 */
36
37const void* ZSTD_DDict_dictContent(const ZSTD_DDict* ddict);
38size_t ZSTD_DDict_dictSize(const ZSTD_DDict* ddict);
39
40void ZSTD_copyDDictParameters(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict);
41
42
43
44#endif /* ZSTD_DDICT_H */
stage1/zstd/lib/decompress/zstd_decompress.c created+2230
......@@ -0,0 +1,2230 @@
1/*
2 * Copyright (c) Yann Collet, Facebook, Inc.
3 * All rights reserved.
4 *
5 * This source code is licensed under both the BSD-style license (found in the
6 * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7 * in the COPYING file in the root directory of this source tree).
8 * You may select, at your option, one of the above-listed licenses.
9 */
10
11
12/* ***************************************************************
13* Tuning parameters
14*****************************************************************/
15/*!
16 * HEAPMODE :
17 * Select how default decompression function ZSTD_decompress() allocates its context,
18 * on stack (0), or into heap (1, default; requires malloc()).
19 * Note that functions with explicit context such as ZSTD_decompressDCtx() are unaffected.
20 */
21#ifndef ZSTD_HEAPMODE
22# define ZSTD_HEAPMODE 1
23#endif
24
25/*!
26* LEGACY_SUPPORT :
27* if set to 1+, ZSTD_decompress() can decode older formats (v0.1+)
28*/
29#ifndef ZSTD_LEGACY_SUPPORT
30# define ZSTD_LEGACY_SUPPORT 0
31#endif
32
33/*!
34 * MAXWINDOWSIZE_DEFAULT :
35 * maximum window size accepted by DStream __by default__.
36 * Frames requiring more memory will be rejected.
37 * It's possible to set a different limit using ZSTD_DCtx_setMaxWindowSize().
38 */
39#ifndef ZSTD_MAXWINDOWSIZE_DEFAULT
40# define ZSTD_MAXWINDOWSIZE_DEFAULT (((U32)1 << ZSTD_WINDOWLOG_LIMIT_DEFAULT) + 1)
41#endif
42
43/*!
44 * NO_FORWARD_PROGRESS_MAX :
45 * maximum allowed nb of calls to ZSTD_decompressStream()
46 * without any forward progress
47 * (defined as: no byte read from input, and no byte flushed to output)
48 * before triggering an error.
49 */
50#ifndef ZSTD_NO_FORWARD_PROGRESS_MAX
51# define ZSTD_NO_FORWARD_PROGRESS_MAX 16
52#endif
53
54
55/*-*******************************************************
56* Dependencies
57*********************************************************/
58#include "../common/zstd_deps.h" /* ZSTD_memcpy, ZSTD_memmove, ZSTD_memset */
59#include "../common/mem.h" /* low level memory routines */
60#define FSE_STATIC_LINKING_ONLY
61#include "../common/fse.h"
62#define HUF_STATIC_LINKING_ONLY
63#include "../common/huf.h"
64#include "../common/xxhash.h" /* XXH64_reset, XXH64_update, XXH64_digest, XXH64 */
65#include "../common/zstd_internal.h" /* blockProperties_t */
66#include "zstd_decompress_internal.h" /* ZSTD_DCtx */
67#include "zstd_ddict.h" /* ZSTD_DDictDictContent */
68#include "zstd_decompress_block.h" /* ZSTD_decompressBlock_internal */
69
70#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1)
71# include "../legacy/zstd_legacy.h"
72#endif
73
74
75
76/*************************************
77 * Multiple DDicts Hashset internals *
78 *************************************/
79
80#define DDICT_HASHSET_MAX_LOAD_FACTOR_COUNT_MULT 4
81#define DDICT_HASHSET_MAX_LOAD_FACTOR_SIZE_MULT 3 /* These two constants represent SIZE_MULT/COUNT_MULT load factor without using a float.
82 * Currently, that means a 0.75 load factor.
83 * So, if count * COUNT_MULT / size * SIZE_MULT != 0, then we've exceeded
84 * the load factor of the ddict hash set.
85 */
86
87#define DDICT_HASHSET_TABLE_BASE_SIZE 64
88#define DDICT_HASHSET_RESIZE_FACTOR 2
89
90/* Hash function to determine starting position of dict insertion within the table
91 * Returns an index between [0, hashSet->ddictPtrTableSize]
92 */
93static size_t ZSTD_DDictHashSet_getIndex(const ZSTD_DDictHashSet* hashSet, U32 dictID) {
94 const U64 hash = XXH64(&dictID, sizeof(U32), 0);
95 /* DDict ptr table size is a multiple of 2, use size - 1 as mask to get index within [0, hashSet->ddictPtrTableSize) */
96 return hash & (hashSet->ddictPtrTableSize - 1);
97}
98
99/* Adds DDict to a hashset without resizing it.
100 * If inserting a DDict with a dictID that already exists in the set, replaces the one in the set.
101 * Returns 0 if successful, or a zstd error code if something went wrong.
102 */
103static size_t ZSTD_DDictHashSet_emplaceDDict(ZSTD_DDictHashSet* hashSet, const ZSTD_DDict* ddict) {
104 const U32 dictID = ZSTD_getDictID_fromDDict(ddict);
105 size_t idx = ZSTD_DDictHashSet_getIndex(hashSet, dictID);
106 const size_t idxRangeMask = hashSet->ddictPtrTableSize - 1;
107 RETURN_ERROR_IF(hashSet->ddictPtrCount == hashSet->ddictPtrTableSize, GENERIC, "Hash set is full!");
108 DEBUGLOG(4, "Hashed index: for dictID: %u is %zu", dictID, idx);
109 while (hashSet->ddictPtrTable[idx] != NULL) {
110 /* Replace existing ddict if inserting ddict with same dictID */
111 if (ZSTD_getDictID_fromDDict(hashSet->ddictPtrTable[idx]) == dictID) {
112 DEBUGLOG(4, "DictID already exists, replacing rather than adding");
113 hashSet->ddictPtrTable[idx] = ddict;
114 return 0;
115 }
116 idx &= idxRangeMask;
117 idx++;
118 }
119 DEBUGLOG(4, "Final idx after probing for dictID %u is: %zu", dictID, idx);
120 hashSet->ddictPtrTable[idx] = ddict;
121 hashSet->ddictPtrCount++;
122 return 0;
123}
124
125/* Expands hash table by factor of DDICT_HASHSET_RESIZE_FACTOR and
126 * rehashes all values, allocates new table, frees old table.
127 * Returns 0 on success, otherwise a zstd error code.
128 */
129static size_t ZSTD_DDictHashSet_expand(ZSTD_DDictHashSet* hashSet, ZSTD_customMem customMem) {
130 size_t newTableSize = hashSet->ddictPtrTableSize * DDICT_HASHSET_RESIZE_FACTOR;
131 const ZSTD_DDict** newTable = (const ZSTD_DDict**)ZSTD_customCalloc(sizeof(ZSTD_DDict*) * newTableSize, customMem);
132 const ZSTD_DDict** oldTable = hashSet->ddictPtrTable;
133 size_t oldTableSize = hashSet->ddictPtrTableSize;
134 size_t i;
135
136 DEBUGLOG(4, "Expanding DDict hash table! Old size: %zu new size: %zu", oldTableSize, newTableSize);
137 RETURN_ERROR_IF(!newTable, memory_allocation, "Expanded hashset allocation failed!");
138 hashSet->ddictPtrTable = newTable;
139 hashSet->ddictPtrTableSize = newTableSize;
140 hashSet->ddictPtrCount = 0;
141 for (i = 0; i < oldTableSize; ++i) {
142 if (oldTable[i] != NULL) {
143 FORWARD_IF_ERROR(ZSTD_DDictHashSet_emplaceDDict(hashSet, oldTable[i]), "");
144 }
145 }
146 ZSTD_customFree((void*)oldTable, customMem);
147 DEBUGLOG(4, "Finished re-hash");
148 return 0;
149}
150
151/* Fetches a DDict with the given dictID
152 * Returns the ZSTD_DDict* with the requested dictID. If it doesn't exist, then returns NULL.
153 */
154static const ZSTD_DDict* ZSTD_DDictHashSet_getDDict(ZSTD_DDictHashSet* hashSet, U32 dictID) {
155 size_t idx = ZSTD_DDictHashSet_getIndex(hashSet, dictID);
156 const size_t idxRangeMask = hashSet->ddictPtrTableSize - 1;
157 DEBUGLOG(4, "Hashed index: for dictID: %u is %zu", dictID, idx);
158 for (;;) {
159 size_t currDictID = ZSTD_getDictID_fromDDict(hashSet->ddictPtrTable[idx]);
160 if (currDictID == dictID || currDictID == 0) {
161 /* currDictID == 0 implies a NULL ddict entry */
162 break;
163 } else {
164 idx &= idxRangeMask; /* Goes to start of table when we reach the end */
165 idx++;
166 }
167 }
168 DEBUGLOG(4, "Final idx after probing for dictID %u is: %zu", dictID, idx);
169 return hashSet->ddictPtrTable[idx];
170}
171
172/* Allocates space for and returns a ddict hash set
173 * The hash set's ZSTD_DDict* table has all values automatically set to NULL to begin with.
174 * Returns NULL if allocation failed.
175 */
176static ZSTD_DDictHashSet* ZSTD_createDDictHashSet(ZSTD_customMem customMem) {
177 ZSTD_DDictHashSet* ret = (ZSTD_DDictHashSet*)ZSTD_customMalloc(sizeof(ZSTD_DDictHashSet), customMem);
178 DEBUGLOG(4, "Allocating new hash set");
179 if (!ret)
180 return NULL;
181 ret->ddictPtrTable = (const ZSTD_DDict**)ZSTD_customCalloc(DDICT_HASHSET_TABLE_BASE_SIZE * sizeof(ZSTD_DDict*), customMem);
182 if (!ret->ddictPtrTable) {
183 ZSTD_customFree(ret, customMem);
184 return NULL;
185 }
186 ret->ddictPtrTableSize = DDICT_HASHSET_TABLE_BASE_SIZE;
187 ret->ddictPtrCount = 0;
188 return ret;
189}
190
191/* Frees the table of ZSTD_DDict* within a hashset, then frees the hashset itself.
192 * Note: The ZSTD_DDict* within the table are NOT freed.
193 */
194static void ZSTD_freeDDictHashSet(ZSTD_DDictHashSet* hashSet, ZSTD_customMem customMem) {
195 DEBUGLOG(4, "Freeing ddict hash set");
196 if (hashSet && hashSet->ddictPtrTable) {
197 ZSTD_customFree((void*)hashSet->ddictPtrTable, customMem);
198 }
199 if (hashSet) {
200 ZSTD_customFree(hashSet, customMem);
201 }
202}
203
204/* Public function: Adds a DDict into the ZSTD_DDictHashSet, possibly triggering a resize of the hash set.
205 * Returns 0 on success, or a ZSTD error.
206 */
207static size_t ZSTD_DDictHashSet_addDDict(ZSTD_DDictHashSet* hashSet, const ZSTD_DDict* ddict, ZSTD_customMem customMem) {
208 DEBUGLOG(4, "Adding dict ID: %u to hashset with - Count: %zu Tablesize: %zu", ZSTD_getDictID_fromDDict(ddict), hashSet->ddictPtrCount, hashSet->ddictPtrTableSize);
209 if (hashSet->ddictPtrCount * DDICT_HASHSET_MAX_LOAD_FACTOR_COUNT_MULT / hashSet->ddictPtrTableSize * DDICT_HASHSET_MAX_LOAD_FACTOR_SIZE_MULT != 0) {
210 FORWARD_IF_ERROR(ZSTD_DDictHashSet_expand(hashSet, customMem), "");
211 }
212 FORWARD_IF_ERROR(ZSTD_DDictHashSet_emplaceDDict(hashSet, ddict), "");
213 return 0;
214}
215
216/*-*************************************************************
217* Context management
218***************************************************************/
219size_t ZSTD_sizeof_DCtx (const ZSTD_DCtx* dctx)
220{
221 if (dctx==NULL) return 0; /* support sizeof NULL */
222 return sizeof(*dctx)
223 + ZSTD_sizeof_DDict(dctx->ddictLocal)
224 + dctx->inBuffSize + dctx->outBuffSize;
225}
226
227size_t ZSTD_estimateDCtxSize(void) { return sizeof(ZSTD_DCtx); }
228
229
230static size_t ZSTD_startingInputLength(ZSTD_format_e format)
231{
232 size_t const startingInputLength = ZSTD_FRAMEHEADERSIZE_PREFIX(format);
233 /* only supports formats ZSTD_f_zstd1 and ZSTD_f_zstd1_magicless */
234 assert( (format == ZSTD_f_zstd1) || (format == ZSTD_f_zstd1_magicless) );
235 return startingInputLength;
236}
237
238static void ZSTD_DCtx_resetParameters(ZSTD_DCtx* dctx)
239{
240 assert(dctx->streamStage == zdss_init);
241 dctx->format = ZSTD_f_zstd1;
242 dctx->maxWindowSize = ZSTD_MAXWINDOWSIZE_DEFAULT;
243 dctx->outBufferMode = ZSTD_bm_buffered;
244 dctx->forceIgnoreChecksum = ZSTD_d_validateChecksum;
245 dctx->refMultipleDDicts = ZSTD_rmd_refSingleDDict;
246}
247
248static void ZSTD_initDCtx_internal(ZSTD_DCtx* dctx)
249{
250 dctx->staticSize = 0;
251 dctx->ddict = NULL;
252 dctx->ddictLocal = NULL;
253 dctx->dictEnd = NULL;
254 dctx->ddictIsCold = 0;
255 dctx->dictUses = ZSTD_dont_use;
256 dctx->inBuff = NULL;
257 dctx->inBuffSize = 0;
258 dctx->outBuffSize = 0;
259 dctx->streamStage = zdss_init;
260#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1)
261 dctx->legacyContext = NULL;
262 dctx->previousLegacyVersion = 0;
263#endif
264 dctx->noForwardProgress = 0;
265 dctx->oversizedDuration = 0;
266#if DYNAMIC_BMI2
267 dctx->bmi2 = ZSTD_cpuSupportsBmi2();
268#endif
269 dctx->ddictSet = NULL;
270 ZSTD_DCtx_resetParameters(dctx);
271#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
272 dctx->dictContentEndForFuzzing = NULL;
273#endif
274}
275
276ZSTD_DCtx* ZSTD_initStaticDCtx(void *workspace, size_t workspaceSize)
277{
278 ZSTD_DCtx* const dctx = (ZSTD_DCtx*) workspace;
279
280 if ((size_t)workspace & 7) return NULL; /* 8-aligned */
281 if (workspaceSize < sizeof(ZSTD_DCtx)) return NULL; /* minimum size */
282
283 ZSTD_initDCtx_internal(dctx);
284 dctx->staticSize = workspaceSize;
285 dctx->inBuff = (char*)(dctx+1);
286 return dctx;
287}
288
289static ZSTD_DCtx* ZSTD_createDCtx_internal(ZSTD_customMem customMem) {
290 if ((!customMem.customAlloc) ^ (!customMem.customFree)) return NULL;
291
292 { ZSTD_DCtx* const dctx = (ZSTD_DCtx*)ZSTD_customMalloc(sizeof(*dctx), customMem);
293 if (!dctx) return NULL;
294 dctx->customMem = customMem;
295 ZSTD_initDCtx_internal(dctx);
296 return dctx;
297 }
298}
299
300ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem)
301{
302 return ZSTD_createDCtx_internal(customMem);
303}
304
305ZSTD_DCtx* ZSTD_createDCtx(void)
306{
307 DEBUGLOG(3, "ZSTD_createDCtx");
308 return ZSTD_createDCtx_internal(ZSTD_defaultCMem);
309}
310
311static void ZSTD_clearDict(ZSTD_DCtx* dctx)
312{
313 ZSTD_freeDDict(dctx->ddictLocal);
314 dctx->ddictLocal = NULL;
315 dctx->ddict = NULL;
316 dctx->dictUses = ZSTD_dont_use;
317}
318
319size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx)
320{
321 if (dctx==NULL) return 0; /* support free on NULL */
322 RETURN_ERROR_IF(dctx->staticSize, memory_allocation, "not compatible with static DCtx");
323 { ZSTD_customMem const cMem = dctx->customMem;
324 ZSTD_clearDict(dctx);
325 ZSTD_customFree(dctx->inBuff, cMem);
326 dctx->inBuff = NULL;
327#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1)
328 if (dctx->legacyContext)
329 ZSTD_freeLegacyStreamContext(dctx->legacyContext, dctx->previousLegacyVersion);
330#endif
331 if (dctx->ddictSet) {
332 ZSTD_freeDDictHashSet(dctx->ddictSet, cMem);
333 dctx->ddictSet = NULL;
334 }
335 ZSTD_customFree(dctx, cMem);
336 return 0;
337 }
338}
339
340/* no longer useful */
341void ZSTD_copyDCtx(ZSTD_DCtx* dstDCtx, const ZSTD_DCtx* srcDCtx)
342{
343 size_t const toCopy = (size_t)((char*)(&dstDCtx->inBuff) - (char*)dstDCtx);
344 ZSTD_memcpy(dstDCtx, srcDCtx, toCopy); /* no need to copy workspace */
345}
346
347/* Given a dctx with a digested frame params, re-selects the correct ZSTD_DDict based on
348 * the requested dict ID from the frame. If there exists a reference to the correct ZSTD_DDict, then
349 * accordingly sets the ddict to be used to decompress the frame.
350 *
351 * If no DDict is found, then no action is taken, and the ZSTD_DCtx::ddict remains as-is.
352 *
353 * ZSTD_d_refMultipleDDicts must be enabled for this function to be called.
354 */
355static void ZSTD_DCtx_selectFrameDDict(ZSTD_DCtx* dctx) {
356 assert(dctx->refMultipleDDicts && dctx->ddictSet);
357 DEBUGLOG(4, "Adjusting DDict based on requested dict ID from frame");
358 if (dctx->ddict) {
359 const ZSTD_DDict* frameDDict = ZSTD_DDictHashSet_getDDict(dctx->ddictSet, dctx->fParams.dictID);
360 if (frameDDict) {
361 DEBUGLOG(4, "DDict found!");
362 ZSTD_clearDict(dctx);
363 dctx->dictID = dctx->fParams.dictID;
364 dctx->ddict = frameDDict;
365 dctx->dictUses = ZSTD_use_indefinitely;
366 }
367 }
368}
369
370
371/*-*************************************************************
372 * Frame header decoding
373 ***************************************************************/
374
375/*! ZSTD_isFrame() :
376 * Tells if the content of `buffer` starts with a valid Frame Identifier.
377 * Note : Frame Identifier is 4 bytes. If `size < 4`, @return will always be 0.
378 * Note 2 : Legacy Frame Identifiers are considered valid only if Legacy Support is enabled.
379 * Note 3 : Skippable Frame Identifiers are considered valid. */
380unsigned ZSTD_isFrame(const void* buffer, size_t size)
381{
382 if (size < ZSTD_FRAMEIDSIZE) return 0;
383 { U32 const magic = MEM_readLE32(buffer);
384 if (magic == ZSTD_MAGICNUMBER) return 1;
385 if ((magic & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) return 1;
386 }
387#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1)
388 if (ZSTD_isLegacy(buffer, size)) return 1;
389#endif
390 return 0;
391}
392
393/*! ZSTD_isSkippableFrame() :
394 * Tells if the content of `buffer` starts with a valid Frame Identifier for a skippable frame.
395 * Note : Frame Identifier is 4 bytes. If `size < 4`, @return will always be 0.
396 */
397unsigned ZSTD_isSkippableFrame(const void* buffer, size_t size)
398{
399 if (size < ZSTD_FRAMEIDSIZE) return 0;
400 { U32 const magic = MEM_readLE32(buffer);
401 if ((magic & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) return 1;
402 }
403 return 0;
404}
405
406/** ZSTD_frameHeaderSize_internal() :
407 * srcSize must be large enough to reach header size fields.
408 * note : only works for formats ZSTD_f_zstd1 and ZSTD_f_zstd1_magicless.
409 * @return : size of the Frame Header
410 * or an error code, which can be tested with ZSTD_isError() */
411static size_t ZSTD_frameHeaderSize_internal(const void* src, size_t srcSize, ZSTD_format_e format)
412{
413 size_t const minInputSize = ZSTD_startingInputLength(format);
414 RETURN_ERROR_IF(srcSize < minInputSize, srcSize_wrong, "");
415
416 { BYTE const fhd = ((const BYTE*)src)[minInputSize-1];
417 U32 const dictID= fhd & 3;
418 U32 const singleSegment = (fhd >> 5) & 1;
419 U32 const fcsId = fhd >> 6;
420 return minInputSize + !singleSegment
421 + ZSTD_did_fieldSize[dictID] + ZSTD_fcs_fieldSize[fcsId]
422 + (singleSegment && !fcsId);
423 }
424}
425
426/** ZSTD_frameHeaderSize() :
427 * srcSize must be >= ZSTD_frameHeaderSize_prefix.
428 * @return : size of the Frame Header,
429 * or an error code (if srcSize is too small) */
430size_t ZSTD_frameHeaderSize(const void* src, size_t srcSize)
431{
432 return ZSTD_frameHeaderSize_internal(src, srcSize, ZSTD_f_zstd1);
433}
434
435
436/** ZSTD_getFrameHeader_advanced() :
437 * decode Frame Header, or require larger `srcSize`.
438 * note : only works for formats ZSTD_f_zstd1 and ZSTD_f_zstd1_magicless
439 * @return : 0, `zfhPtr` is correctly filled,
440 * >0, `srcSize` is too small, value is wanted `srcSize` amount,
441 * or an error code, which can be tested using ZSTD_isError() */
442size_t ZSTD_getFrameHeader_advanced(ZSTD_frameHeader* zfhPtr, const void* src, size_t srcSize, ZSTD_format_e format)
443{
444 const BYTE* ip = (const BYTE*)src;
445 size_t const minInputSize = ZSTD_startingInputLength(format);
446
447 ZSTD_memset(zfhPtr, 0, sizeof(*zfhPtr)); /* not strictly necessary, but static analyzer do not understand that zfhPtr is only going to be read only if return value is zero, since they are 2 different signals */
448 if (srcSize < minInputSize) return minInputSize;
449 RETURN_ERROR_IF(src==NULL, GENERIC, "invalid parameter");
450
451 if ( (format != ZSTD_f_zstd1_magicless)
452 && (MEM_readLE32(src) != ZSTD_MAGICNUMBER) ) {
453 if ((MEM_readLE32(src) & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) {
454 /* skippable frame */
455 if (srcSize < ZSTD_SKIPPABLEHEADERSIZE)
456 return ZSTD_SKIPPABLEHEADERSIZE; /* magic number + frame length */
457 ZSTD_memset(zfhPtr, 0, sizeof(*zfhPtr));
458 zfhPtr->frameContentSize = MEM_readLE32((const char *)src + ZSTD_FRAMEIDSIZE);
459 zfhPtr->frameType = ZSTD_skippableFrame;
460 return 0;
461 }
462 RETURN_ERROR(prefix_unknown, "");
463 }
464
465 /* ensure there is enough `srcSize` to fully read/decode frame header */
466 { size_t const fhsize = ZSTD_frameHeaderSize_internal(src, srcSize, format);
467 if (srcSize < fhsize) return fhsize;
468 zfhPtr->headerSize = (U32)fhsize;
469 }
470
471 { BYTE const fhdByte = ip[minInputSize-1];
472 size_t pos = minInputSize;
473 U32 const dictIDSizeCode = fhdByte&3;
474 U32 const checksumFlag = (fhdByte>>2)&1;
475 U32 const singleSegment = (fhdByte>>5)&1;
476 U32 const fcsID = fhdByte>>6;
477 U64 windowSize = 0;
478 U32 dictID = 0;
479 U64 frameContentSize = ZSTD_CONTENTSIZE_UNKNOWN;
480 RETURN_ERROR_IF((fhdByte & 0x08) != 0, frameParameter_unsupported,
481 "reserved bits, must be zero");
482
483 if (!singleSegment) {
484 BYTE const wlByte = ip[pos++];
485 U32 const windowLog = (wlByte >> 3) + ZSTD_WINDOWLOG_ABSOLUTEMIN;
486 RETURN_ERROR_IF(windowLog > ZSTD_WINDOWLOG_MAX, frameParameter_windowTooLarge, "");
487 windowSize = (1ULL << windowLog);
488 windowSize += (windowSize >> 3) * (wlByte&7);
489 }
490 switch(dictIDSizeCode)
491 {
492 default:
493 assert(0); /* impossible */
494 ZSTD_FALLTHROUGH;
495 case 0 : break;
496 case 1 : dictID = ip[pos]; pos++; break;
497 case 2 : dictID = MEM_readLE16(ip+pos); pos+=2; break;
498 case 3 : dictID = MEM_readLE32(ip+pos); pos+=4; break;
499 }
500 switch(fcsID)
501 {
502 default:
503 assert(0); /* impossible */
504 ZSTD_FALLTHROUGH;
505 case 0 : if (singleSegment) frameContentSize = ip[pos]; break;
506 case 1 : frameContentSize = MEM_readLE16(ip+pos)+256; break;
507 case 2 : frameContentSize = MEM_readLE32(ip+pos); break;
508 case 3 : frameContentSize = MEM_readLE64(ip+pos); break;
509 }
510 if (singleSegment) windowSize = frameContentSize;
511
512 zfhPtr->frameType = ZSTD_frame;
513 zfhPtr->frameContentSize = frameContentSize;
514 zfhPtr->windowSize = windowSize;
515 zfhPtr->blockSizeMax = (unsigned) MIN(windowSize, ZSTD_BLOCKSIZE_MAX);
516 zfhPtr->dictID = dictID;
517 zfhPtr->checksumFlag = checksumFlag;
518 }
519 return 0;
520}
521
522/** ZSTD_getFrameHeader() :
523 * decode Frame Header, or require larger `srcSize`.
524 * note : this function does not consume input, it only reads it.
525 * @return : 0, `zfhPtr` is correctly filled,
526 * >0, `srcSize` is too small, value is wanted `srcSize` amount,
527 * or an error code, which can be tested using ZSTD_isError() */
528size_t ZSTD_getFrameHeader(ZSTD_frameHeader* zfhPtr, const void* src, size_t srcSize)
529{
530 return ZSTD_getFrameHeader_advanced(zfhPtr, src, srcSize, ZSTD_f_zstd1);
531}
532
533/** ZSTD_getFrameContentSize() :
534 * compatible with legacy mode
535 * @return : decompressed size of the single frame pointed to be `src` if known, otherwise
536 * - ZSTD_CONTENTSIZE_UNKNOWN if the size cannot be determined
537 * - ZSTD_CONTENTSIZE_ERROR if an error occurred (e.g. invalid magic number, srcSize too small) */
538unsigned long long ZSTD_getFrameContentSize(const void *src, size_t srcSize)
539{
540#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1)
541 if (ZSTD_isLegacy(src, srcSize)) {
542 unsigned long long const ret = ZSTD_getDecompressedSize_legacy(src, srcSize);
543 return ret == 0 ? ZSTD_CONTENTSIZE_UNKNOWN : ret;
544 }
545#endif
546 { ZSTD_frameHeader zfh;
547 if (ZSTD_getFrameHeader(&zfh, src, srcSize) != 0)
548 return ZSTD_CONTENTSIZE_ERROR;
549 if (zfh.frameType == ZSTD_skippableFrame) {
550 return 0;
551 } else {
552 return zfh.frameContentSize;
553 } }
554}
555
556static size_t readSkippableFrameSize(void const* src, size_t srcSize)
557{
558 size_t const skippableHeaderSize = ZSTD_SKIPPABLEHEADERSIZE;
559 U32 sizeU32;
560
561 RETURN_ERROR_IF(srcSize < ZSTD_SKIPPABLEHEADERSIZE, srcSize_wrong, "");
562
563 sizeU32 = MEM_readLE32((BYTE const*)src + ZSTD_FRAMEIDSIZE);
564 RETURN_ERROR_IF((U32)(sizeU32 + ZSTD_SKIPPABLEHEADERSIZE) < sizeU32,
565 frameParameter_unsupported, "");
566 {
567 size_t const skippableSize = skippableHeaderSize + sizeU32;
568 RETURN_ERROR_IF(skippableSize > srcSize, srcSize_wrong, "");
569 return skippableSize;
570 }
571}
572
573/*! ZSTD_readSkippableFrame() :
574 * Retrieves a zstd skippable frame containing data given by src, and writes it to dst buffer.
575 *
576 * The parameter magicVariant will receive the magicVariant that was supplied when the frame was written,
577 * i.e. magicNumber - ZSTD_MAGIC_SKIPPABLE_START. This can be NULL if the caller is not interested
578 * in the magicVariant.
579 *
580 * Returns an error if destination buffer is not large enough, or if the frame is not skippable.
581 *
582 * @return : number of bytes written or a ZSTD error.
583 */
584ZSTDLIB_API size_t ZSTD_readSkippableFrame(void* dst, size_t dstCapacity, unsigned* magicVariant,
585 const void* src, size_t srcSize)
586{
587 U32 const magicNumber = MEM_readLE32(src);
588 size_t skippableFrameSize = readSkippableFrameSize(src, srcSize);
589 size_t skippableContentSize = skippableFrameSize - ZSTD_SKIPPABLEHEADERSIZE;
590
591 /* check input validity */
592 RETURN_ERROR_IF(!ZSTD_isSkippableFrame(src, srcSize), frameParameter_unsupported, "");
593 RETURN_ERROR_IF(skippableFrameSize < ZSTD_SKIPPABLEHEADERSIZE || skippableFrameSize > srcSize, srcSize_wrong, "");
594 RETURN_ERROR_IF(skippableContentSize > dstCapacity, dstSize_tooSmall, "");
595
596 /* deliver payload */
597 if (skippableContentSize > 0 && dst != NULL)
598 ZSTD_memcpy(dst, (const BYTE *)src + ZSTD_SKIPPABLEHEADERSIZE, skippableContentSize);
599 if (magicVariant != NULL)
600 *magicVariant = magicNumber - ZSTD_MAGIC_SKIPPABLE_START;
601 return skippableContentSize;
602}
603
604/** ZSTD_findDecompressedSize() :
605 * compatible with legacy mode
606 * `srcSize` must be the exact length of some number of ZSTD compressed and/or
607 * skippable frames
608 * @return : decompressed size of the frames contained */
609unsigned long long ZSTD_findDecompressedSize(const void* src, size_t srcSize)
610{
611 unsigned long long totalDstSize = 0;
612
613 while (srcSize >= ZSTD_startingInputLength(ZSTD_f_zstd1)) {
614 U32 const magicNumber = MEM_readLE32(src);
615
616 if ((magicNumber & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) {
617 size_t const skippableSize = readSkippableFrameSize(src, srcSize);
618 if (ZSTD_isError(skippableSize)) {
619 return ZSTD_CONTENTSIZE_ERROR;
620 }
621 assert(skippableSize <= srcSize);
622
623 src = (const BYTE *)src + skippableSize;
624 srcSize -= skippableSize;
625 continue;
626 }
627
628 { unsigned long long const ret = ZSTD_getFrameContentSize(src, srcSize);
629 if (ret >= ZSTD_CONTENTSIZE_ERROR) return ret;
630
631 /* check for overflow */
632 if (totalDstSize + ret < totalDstSize) return ZSTD_CONTENTSIZE_ERROR;
633 totalDstSize += ret;
634 }
635 { size_t const frameSrcSize = ZSTD_findFrameCompressedSize(src, srcSize);
636 if (ZSTD_isError(frameSrcSize)) {
637 return ZSTD_CONTENTSIZE_ERROR;
638 }
639
640 src = (const BYTE *)src + frameSrcSize;
641 srcSize -= frameSrcSize;
642 }
643 } /* while (srcSize >= ZSTD_frameHeaderSize_prefix) */
644
645 if (srcSize) return ZSTD_CONTENTSIZE_ERROR;
646
647 return totalDstSize;
648}
649
650/** ZSTD_getDecompressedSize() :
651 * compatible with legacy mode
652 * @return : decompressed size if known, 0 otherwise
653 note : 0 can mean any of the following :
654 - frame content is empty
655 - decompressed size field is not present in frame header
656 - frame header unknown / not supported
657 - frame header not complete (`srcSize` too small) */
658unsigned long long ZSTD_getDecompressedSize(const void* src, size_t srcSize)
659{
660 unsigned long long const ret = ZSTD_getFrameContentSize(src, srcSize);
661 ZSTD_STATIC_ASSERT(ZSTD_CONTENTSIZE_ERROR < ZSTD_CONTENTSIZE_UNKNOWN);
662 return (ret >= ZSTD_CONTENTSIZE_ERROR) ? 0 : ret;
663}
664
665
666/** ZSTD_decodeFrameHeader() :
667 * `headerSize` must be the size provided by ZSTD_frameHeaderSize().
668 * If multiple DDict references are enabled, also will choose the correct DDict to use.
669 * @return : 0 if success, or an error code, which can be tested using ZSTD_isError() */
670static size_t ZSTD_decodeFrameHeader(ZSTD_DCtx* dctx, const void* src, size_t headerSize)
671{
672 size_t const result = ZSTD_getFrameHeader_advanced(&(dctx->fParams), src, headerSize, dctx->format);
673 if (ZSTD_isError(result)) return result; /* invalid header */
674 RETURN_ERROR_IF(result>0, srcSize_wrong, "headerSize too small");
675
676 /* Reference DDict requested by frame if dctx references multiple ddicts */
677 if (dctx->refMultipleDDicts == ZSTD_rmd_refMultipleDDicts && dctx->ddictSet) {
678 ZSTD_DCtx_selectFrameDDict(dctx);
679 }
680
681#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
682 /* Skip the dictID check in fuzzing mode, because it makes the search
683 * harder.
684 */
685 RETURN_ERROR_IF(dctx->fParams.dictID && (dctx->dictID != dctx->fParams.dictID),
686 dictionary_wrong, "");
687#endif
688 dctx->validateChecksum = (dctx->fParams.checksumFlag && !dctx->forceIgnoreChecksum) ? 1 : 0;
689 if (dctx->validateChecksum) XXH64_reset(&dctx->xxhState, 0);
690 dctx->processedCSize += headerSize;
691 return 0;
692}
693
694static ZSTD_frameSizeInfo ZSTD_errorFrameSizeInfo(size_t ret)
695{
696 ZSTD_frameSizeInfo frameSizeInfo;
697 frameSizeInfo.compressedSize = ret;
698 frameSizeInfo.decompressedBound = ZSTD_CONTENTSIZE_ERROR;
699 return frameSizeInfo;
700}
701
702static ZSTD_frameSizeInfo ZSTD_findFrameSizeInfo(const void* src, size_t srcSize)
703{
704 ZSTD_frameSizeInfo frameSizeInfo;
705 ZSTD_memset(&frameSizeInfo, 0, sizeof(ZSTD_frameSizeInfo));
706
707#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1)
708 if (ZSTD_isLegacy(src, srcSize))
709 return ZSTD_findFrameSizeInfoLegacy(src, srcSize);
710#endif
711
712 if ((srcSize >= ZSTD_SKIPPABLEHEADERSIZE)
713 && (MEM_readLE32(src) & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) {
714 frameSizeInfo.compressedSize = readSkippableFrameSize(src, srcSize);
715 assert(ZSTD_isError(frameSizeInfo.compressedSize) ||
716 frameSizeInfo.compressedSize <= srcSize);
717 return frameSizeInfo;
718 } else {
719 const BYTE* ip = (const BYTE*)src;
720 const BYTE* const ipstart = ip;
721 size_t remainingSize = srcSize;
722 size_t nbBlocks = 0;
723 ZSTD_frameHeader zfh;
724
725 /* Extract Frame Header */
726 { size_t const ret = ZSTD_getFrameHeader(&zfh, src, srcSize);
727 if (ZSTD_isError(ret))
728 return ZSTD_errorFrameSizeInfo(ret);
729 if (ret > 0)
730 return ZSTD_errorFrameSizeInfo(ERROR(srcSize_wrong));
731 }
732
733 ip += zfh.headerSize;
734 remainingSize -= zfh.headerSize;
735
736 /* Iterate over each block */
737 while (1) {
738 blockProperties_t blockProperties;
739 size_t const cBlockSize = ZSTD_getcBlockSize(ip, remainingSize, &blockProperties);
740 if (ZSTD_isError(cBlockSize))
741 return ZSTD_errorFrameSizeInfo(cBlockSize);
742
743 if (ZSTD_blockHeaderSize + cBlockSize > remainingSize)
744 return ZSTD_errorFrameSizeInfo(ERROR(srcSize_wrong));
745
746 ip += ZSTD_blockHeaderSize + cBlockSize;
747 remainingSize -= ZSTD_blockHeaderSize + cBlockSize;
748 nbBlocks++;
749
750 if (blockProperties.lastBlock) break;
751 }
752
753 /* Final frame content checksum */
754 if (zfh.checksumFlag) {
755 if (remainingSize < 4)
756 return ZSTD_errorFrameSizeInfo(ERROR(srcSize_wrong));
757 ip += 4;
758 }
759
760 frameSizeInfo.compressedSize = (size_t)(ip - ipstart);
761 frameSizeInfo.decompressedBound = (zfh.frameContentSize != ZSTD_CONTENTSIZE_UNKNOWN)
762 ? zfh.frameContentSize
763 : nbBlocks * zfh.blockSizeMax;
764 return frameSizeInfo;
765 }
766}
767
768/** ZSTD_findFrameCompressedSize() :
769 * compatible with legacy mode
770 * `src` must point to the start of a ZSTD frame, ZSTD legacy frame, or skippable frame
771 * `srcSize` must be at least as large as the frame contained
772 * @return : the compressed size of the frame starting at `src` */
773size_t ZSTD_findFrameCompressedSize(const void *src, size_t srcSize)
774{
775 ZSTD_frameSizeInfo const frameSizeInfo = ZSTD_findFrameSizeInfo(src, srcSize);
776 return frameSizeInfo.compressedSize;
777}
778
779/** ZSTD_decompressBound() :
780 * compatible with legacy mode
781 * `src` must point to the start of a ZSTD frame or a skippeable frame
782 * `srcSize` must be at least as large as the frame contained
783 * @return : the maximum decompressed size of the compressed source
784 */
785unsigned long long ZSTD_decompressBound(const void* src, size_t srcSize)
786{
787 unsigned long long bound = 0;
788 /* Iterate over each frame */
789 while (srcSize > 0) {
790 ZSTD_frameSizeInfo const frameSizeInfo = ZSTD_findFrameSizeInfo(src, srcSize);
791 size_t const compressedSize = frameSizeInfo.compressedSize;
792 unsigned long long const decompressedBound = frameSizeInfo.decompressedBound;
793 if (ZSTD_isError(compressedSize) || decompressedBound == ZSTD_CONTENTSIZE_ERROR)
794 return ZSTD_CONTENTSIZE_ERROR;
795 assert(srcSize >= compressedSize);
796 src = (const BYTE*)src + compressedSize;
797 srcSize -= compressedSize;
798 bound += decompressedBound;
799 }
800 return bound;
801}
802
803
804/*-*************************************************************
805 * Frame decoding
806 ***************************************************************/
807
808/** ZSTD_insertBlock() :
809 * insert `src` block into `dctx` history. Useful to track uncompressed blocks. */
810size_t ZSTD_insertBlock(ZSTD_DCtx* dctx, const void* blockStart, size_t blockSize)
811{
812 DEBUGLOG(5, "ZSTD_insertBlock: %u bytes", (unsigned)blockSize);
813 ZSTD_checkContinuity(dctx, blockStart, blockSize);
814 dctx->previousDstEnd = (const char*)blockStart + blockSize;
815 return blockSize;
816}
817
818
819static size_t ZSTD_copyRawBlock(void* dst, size_t dstCapacity,
820 const void* src, size_t srcSize)
821{
822 DEBUGLOG(5, "ZSTD_copyRawBlock");
823 RETURN_ERROR_IF(srcSize > dstCapacity, dstSize_tooSmall, "");
824 if (dst == NULL) {
825 if (srcSize == 0) return 0;
826 RETURN_ERROR(dstBuffer_null, "");
827 }
828 ZSTD_memcpy(dst, src, srcSize);
829 return srcSize;
830}
831
832static size_t ZSTD_setRleBlock(void* dst, size_t dstCapacity,
833 BYTE b,
834 size_t regenSize)
835{
836 RETURN_ERROR_IF(regenSize > dstCapacity, dstSize_tooSmall, "");
837 if (dst == NULL) {
838 if (regenSize == 0) return 0;
839 RETURN_ERROR(dstBuffer_null, "");
840 }
841 ZSTD_memset(dst, b, regenSize);
842 return regenSize;
843}
844
845static void ZSTD_DCtx_trace_end(ZSTD_DCtx const* dctx, U64 uncompressedSize, U64 compressedSize, unsigned streaming)
846{
847#if ZSTD_TRACE
848 if (dctx->traceCtx && ZSTD_trace_decompress_end != NULL) {
849 ZSTD_Trace trace;
850 ZSTD_memset(&trace, 0, sizeof(trace));
851 trace.version = ZSTD_VERSION_NUMBER;
852 trace.streaming = streaming;
853 if (dctx->ddict) {
854 trace.dictionaryID = ZSTD_getDictID_fromDDict(dctx->ddict);
855 trace.dictionarySize = ZSTD_DDict_dictSize(dctx->ddict);
856 trace.dictionaryIsCold = dctx->ddictIsCold;
857 }
858 trace.uncompressedSize = (size_t)uncompressedSize;
859 trace.compressedSize = (size_t)compressedSize;
860 trace.dctx = dctx;
861 ZSTD_trace_decompress_end(dctx->traceCtx, &trace);
862 }
863#else
864 (void)dctx;
865 (void)uncompressedSize;
866 (void)compressedSize;
867 (void)streaming;
868#endif
869}
870
871
872/*! ZSTD_decompressFrame() :
873 * @dctx must be properly initialized
874 * will update *srcPtr and *srcSizePtr,
875 * to make *srcPtr progress by one frame. */
876static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
877 void* dst, size_t dstCapacity,
878 const void** srcPtr, size_t *srcSizePtr)
879{
880 const BYTE* const istart = (const BYTE*)(*srcPtr);
881 const BYTE* ip = istart;
882 BYTE* const ostart = (BYTE*)dst;
883 BYTE* const oend = dstCapacity != 0 ? ostart + dstCapacity : ostart;
884 BYTE* op = ostart;
885 size_t remainingSrcSize = *srcSizePtr;
886
887 DEBUGLOG(4, "ZSTD_decompressFrame (srcSize:%i)", (int)*srcSizePtr);
888
889 /* check */
890 RETURN_ERROR_IF(
891 remainingSrcSize < ZSTD_FRAMEHEADERSIZE_MIN(dctx->format)+ZSTD_blockHeaderSize,
892 srcSize_wrong, "");
893
894 /* Frame Header */
895 { size_t const frameHeaderSize = ZSTD_frameHeaderSize_internal(
896 ip, ZSTD_FRAMEHEADERSIZE_PREFIX(dctx->format), dctx->format);
897 if (ZSTD_isError(frameHeaderSize)) return frameHeaderSize;
898 RETURN_ERROR_IF(remainingSrcSize < frameHeaderSize+ZSTD_blockHeaderSize,
899 srcSize_wrong, "");
900 FORWARD_IF_ERROR( ZSTD_decodeFrameHeader(dctx, ip, frameHeaderSize) , "");
901 ip += frameHeaderSize; remainingSrcSize -= frameHeaderSize;
902 }
903
904 /* Loop on each block */
905 while (1) {
906 size_t decodedSize;
907 blockProperties_t blockProperties;
908 size_t const cBlockSize = ZSTD_getcBlockSize(ip, remainingSrcSize, &blockProperties);
909 if (ZSTD_isError(cBlockSize)) return cBlockSize;
910
911 ip += ZSTD_blockHeaderSize;
912 remainingSrcSize -= ZSTD_blockHeaderSize;
913 RETURN_ERROR_IF(cBlockSize > remainingSrcSize, srcSize_wrong, "");
914
915 switch(blockProperties.blockType)
916 {
917 case bt_compressed:
918 decodedSize = ZSTD_decompressBlock_internal(dctx, op, (size_t)(oend-op), ip, cBlockSize, /* frame */ 1, not_streaming);
919 break;
920 case bt_raw :
921 decodedSize = ZSTD_copyRawBlock(op, (size_t)(oend-op), ip, cBlockSize);
922 break;
923 case bt_rle :
924 decodedSize = ZSTD_setRleBlock(op, (size_t)(oend-op), *ip, blockProperties.origSize);
925 break;
926 case bt_reserved :
927 default:
928 RETURN_ERROR(corruption_detected, "invalid block type");
929 }
930
931 if (ZSTD_isError(decodedSize)) return decodedSize;
932 if (dctx->validateChecksum)
933 XXH64_update(&dctx->xxhState, op, decodedSize);
934 if (decodedSize != 0)
935 op += decodedSize;
936 assert(ip != NULL);
937 ip += cBlockSize;
938 remainingSrcSize -= cBlockSize;
939 if (blockProperties.lastBlock) break;
940 }
941
942 if (dctx->fParams.frameContentSize != ZSTD_CONTENTSIZE_UNKNOWN) {
943 RETURN_ERROR_IF((U64)(op-ostart) != dctx->fParams.frameContentSize,
944 corruption_detected, "");
945 }
946 if (dctx->fParams.checksumFlag) { /* Frame content checksum verification */
947 RETURN_ERROR_IF(remainingSrcSize<4, checksum_wrong, "");
948 if (!dctx->forceIgnoreChecksum) {
949 U32 const checkCalc = (U32)XXH64_digest(&dctx->xxhState);
950 U32 checkRead;
951 checkRead = MEM_readLE32(ip);
952 RETURN_ERROR_IF(checkRead != checkCalc, checksum_wrong, "");
953 }
954 ip += 4;
955 remainingSrcSize -= 4;
956 }
957 ZSTD_DCtx_trace_end(dctx, (U64)(op-ostart), (U64)(ip-istart), /* streaming */ 0);
958 /* Allow caller to get size read */
959 *srcPtr = ip;
960 *srcSizePtr = remainingSrcSize;
961 return (size_t)(op-ostart);
962}
963
964static size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx,
965 void* dst, size_t dstCapacity,
966 const void* src, size_t srcSize,
967 const void* dict, size_t dictSize,
968 const ZSTD_DDict* ddict)
969{
970 void* const dststart = dst;
971 int moreThan1Frame = 0;
972
973 DEBUGLOG(5, "ZSTD_decompressMultiFrame");
974 assert(dict==NULL || ddict==NULL); /* either dict or ddict set, not both */
975
976 if (ddict) {
977 dict = ZSTD_DDict_dictContent(ddict);
978 dictSize = ZSTD_DDict_dictSize(ddict);
979 }
980
981 while (srcSize >= ZSTD_startingInputLength(dctx->format)) {
982
983#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1)
984 if (ZSTD_isLegacy(src, srcSize)) {
985 size_t decodedSize;
986 size_t const frameSize = ZSTD_findFrameCompressedSizeLegacy(src, srcSize);
987 if (ZSTD_isError(frameSize)) return frameSize;
988 RETURN_ERROR_IF(dctx->staticSize, memory_allocation,
989 "legacy support is not compatible with static dctx");
990
991 decodedSize = ZSTD_decompressLegacy(dst, dstCapacity, src, frameSize, dict, dictSize);
992 if (ZSTD_isError(decodedSize)) return decodedSize;
993
994 assert(decodedSize <= dstCapacity);
995 dst = (BYTE*)dst + decodedSize;
996 dstCapacity -= decodedSize;
997
998 src = (const BYTE*)src + frameSize;
999 srcSize -= frameSize;
1000
1001 continue;
1002 }
1003#endif
1004
1005 { U32 const magicNumber = MEM_readLE32(src);
1006 DEBUGLOG(4, "reading magic number %08X (expecting %08X)",
1007 (unsigned)magicNumber, ZSTD_MAGICNUMBER);
1008 if ((magicNumber & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) {
1009 size_t const skippableSize = readSkippableFrameSize(src, srcSize);
1010 FORWARD_IF_ERROR(skippableSize, "readSkippableFrameSize failed");
1011 assert(skippableSize <= srcSize);
1012
1013 src = (const BYTE *)src + skippableSize;
1014 srcSize -= skippableSize;
1015 continue;
1016 } }
1017
1018 if (ddict) {
1019 /* we were called from ZSTD_decompress_usingDDict */
1020 FORWARD_IF_ERROR(ZSTD_decompressBegin_usingDDict(dctx, ddict), "");
1021 } else {
1022 /* this will initialize correctly with no dict if dict == NULL, so
1023 * use this in all cases but ddict */
1024 FORWARD_IF_ERROR(ZSTD_decompressBegin_usingDict(dctx, dict, dictSize), "");
1025 }
1026 ZSTD_checkContinuity(dctx, dst, dstCapacity);
1027
1028 { const size_t res = ZSTD_decompressFrame(dctx, dst, dstCapacity,
1029 &src, &srcSize);
1030 RETURN_ERROR_IF(
1031 (ZSTD_getErrorCode(res) == ZSTD_error_prefix_unknown)
1032 && (moreThan1Frame==1),
1033 srcSize_wrong,
1034 "At least one frame successfully completed, "
1035 "but following bytes are garbage: "
1036 "it's more likely to be a srcSize error, "
1037 "specifying more input bytes than size of frame(s). "
1038 "Note: one could be unlucky, it might be a corruption error instead, "
1039 "happening right at the place where we expect zstd magic bytes. "
1040 "But this is _much_ less likely than a srcSize field error.");
1041 if (ZSTD_isError(res)) return res;
1042 assert(res <= dstCapacity);
1043 if (res != 0)
1044 dst = (BYTE*)dst + res;
1045 dstCapacity -= res;
1046 }
1047 moreThan1Frame = 1;
1048 } /* while (srcSize >= ZSTD_frameHeaderSize_prefix) */
1049
1050 RETURN_ERROR_IF(srcSize, srcSize_wrong, "input not entirely consumed");
1051
1052 return (size_t)((BYTE*)dst - (BYTE*)dststart);
1053}
1054
1055size_t ZSTD_decompress_usingDict(ZSTD_DCtx* dctx,
1056 void* dst, size_t dstCapacity,
1057 const void* src, size_t srcSize,
1058 const void* dict, size_t dictSize)
1059{
1060 return ZSTD_decompressMultiFrame(dctx, dst, dstCapacity, src, srcSize, dict, dictSize, NULL);
1061}
1062
1063
1064static ZSTD_DDict const* ZSTD_getDDict(ZSTD_DCtx* dctx)
1065{
1066 switch (dctx->dictUses) {
1067 default:
1068 assert(0 /* Impossible */);
1069 ZSTD_FALLTHROUGH;
1070 case ZSTD_dont_use:
1071 ZSTD_clearDict(dctx);
1072 return NULL;
1073 case ZSTD_use_indefinitely:
1074 return dctx->ddict;
1075 case ZSTD_use_once:
1076 dctx->dictUses = ZSTD_dont_use;
1077 return dctx->ddict;
1078 }
1079}
1080
1081size_t ZSTD_decompressDCtx(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize)
1082{
1083 return ZSTD_decompress_usingDDict(dctx, dst, dstCapacity, src, srcSize, ZSTD_getDDict(dctx));
1084}
1085
1086
1087size_t ZSTD_decompress(void* dst, size_t dstCapacity, const void* src, size_t srcSize)
1088{
1089#if defined(ZSTD_HEAPMODE) && (ZSTD_HEAPMODE>=1)
1090 size_t regenSize;
1091 ZSTD_DCtx* const dctx = ZSTD_createDCtx_internal(ZSTD_defaultCMem);
1092 RETURN_ERROR_IF(dctx==NULL, memory_allocation, "NULL pointer!");
1093 regenSize = ZSTD_decompressDCtx(dctx, dst, dstCapacity, src, srcSize);
1094 ZSTD_freeDCtx(dctx);
1095 return regenSize;
1096#else /* stack mode */
1097 ZSTD_DCtx dctx;
1098 ZSTD_initDCtx_internal(&dctx);
1099 return ZSTD_decompressDCtx(&dctx, dst, dstCapacity, src, srcSize);
1100#endif
1101}
1102
1103
1104/*-**************************************
1105* Advanced Streaming Decompression API
1106* Bufferless and synchronous
1107****************************************/
1108size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx) { return dctx->expected; }
1109
1110/**
1111 * Similar to ZSTD_nextSrcSizeToDecompress(), but when when a block input can be streamed,
1112 * we allow taking a partial block as the input. Currently only raw uncompressed blocks can
1113 * be streamed.
1114 *
1115 * For blocks that can be streamed, this allows us to reduce the latency until we produce
1116 * output, and avoid copying the input.
1117 *
1118 * @param inputSize - The total amount of input that the caller currently has.
1119 */
1120static size_t ZSTD_nextSrcSizeToDecompressWithInputSize(ZSTD_DCtx* dctx, size_t inputSize) {
1121 if (!(dctx->stage == ZSTDds_decompressBlock || dctx->stage == ZSTDds_decompressLastBlock))
1122 return dctx->expected;
1123 if (dctx->bType != bt_raw)
1124 return dctx->expected;
1125 return BOUNDED(1, inputSize, dctx->expected);
1126}
1127
1128ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx) {
1129 switch(dctx->stage)
1130 {
1131 default: /* should not happen */
1132 assert(0);
1133 ZSTD_FALLTHROUGH;
1134 case ZSTDds_getFrameHeaderSize:
1135 ZSTD_FALLTHROUGH;
1136 case ZSTDds_decodeFrameHeader:
1137 return ZSTDnit_frameHeader;
1138 case ZSTDds_decodeBlockHeader:
1139 return ZSTDnit_blockHeader;
1140 case ZSTDds_decompressBlock:
1141 return ZSTDnit_block;
1142 case ZSTDds_decompressLastBlock:
1143 return ZSTDnit_lastBlock;
1144 case ZSTDds_checkChecksum:
1145 return ZSTDnit_checksum;
1146 case ZSTDds_decodeSkippableHeader:
1147 ZSTD_FALLTHROUGH;
1148 case ZSTDds_skipFrame:
1149 return ZSTDnit_skippableFrame;
1150 }
1151}
1152
1153static int ZSTD_isSkipFrame(ZSTD_DCtx* dctx) { return dctx->stage == ZSTDds_skipFrame; }
1154
1155/** ZSTD_decompressContinue() :
1156 * srcSize : must be the exact nb of bytes expected (see ZSTD_nextSrcSizeToDecompress())
1157 * @return : nb of bytes generated into `dst` (necessarily <= `dstCapacity)
1158 * or an error code, which can be tested using ZSTD_isError() */
1159size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize)
1160{
1161 DEBUGLOG(5, "ZSTD_decompressContinue (srcSize:%u)", (unsigned)srcSize);
1162 /* Sanity check */
1163 RETURN_ERROR_IF(srcSize != ZSTD_nextSrcSizeToDecompressWithInputSize(dctx, srcSize), srcSize_wrong, "not allowed");
1164 ZSTD_checkContinuity(dctx, dst, dstCapacity);
1165
1166 dctx->processedCSize += srcSize;
1167
1168 switch (dctx->stage)
1169 {
1170 case ZSTDds_getFrameHeaderSize :
1171 assert(src != NULL);
1172 if (dctx->format == ZSTD_f_zstd1) { /* allows header */
1173 assert(srcSize >= ZSTD_FRAMEIDSIZE); /* to read skippable magic number */
1174 if ((MEM_readLE32(src) & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) { /* skippable frame */
1175 ZSTD_memcpy(dctx->headerBuffer, src, srcSize);
1176 dctx->expected = ZSTD_SKIPPABLEHEADERSIZE - srcSize; /* remaining to load to get full skippable frame header */
1177 dctx->stage = ZSTDds_decodeSkippableHeader;
1178 return 0;
1179 } }
1180 dctx->headerSize = ZSTD_frameHeaderSize_internal(src, srcSize, dctx->format);
1181 if (ZSTD_isError(dctx->headerSize)) return dctx->headerSize;
1182 ZSTD_memcpy(dctx->headerBuffer, src, srcSize);
1183 dctx->expected = dctx->headerSize - srcSize;
1184 dctx->stage = ZSTDds_decodeFrameHeader;
1185 return 0;
1186
1187 case ZSTDds_decodeFrameHeader:
1188 assert(src != NULL);
1189 ZSTD_memcpy(dctx->headerBuffer + (dctx->headerSize - srcSize), src, srcSize);
1190 FORWARD_IF_ERROR(ZSTD_decodeFrameHeader(dctx, dctx->headerBuffer, dctx->headerSize), "");
1191 dctx->expected = ZSTD_blockHeaderSize;
1192 dctx->stage = ZSTDds_decodeBlockHeader;
1193 return 0;
1194
1195 case ZSTDds_decodeBlockHeader:
1196 { blockProperties_t bp;
1197 size_t const cBlockSize = ZSTD_getcBlockSize(src, ZSTD_blockHeaderSize, &bp);
1198 if (ZSTD_isError(cBlockSize)) return cBlockSize;
1199 RETURN_ERROR_IF(cBlockSize > dctx->fParams.blockSizeMax, corruption_detected, "Block Size Exceeds Maximum");
1200 dctx->expected = cBlockSize;
1201 dctx->bType = bp.blockType;
1202 dctx->rleSize = bp.origSize;
1203 if (cBlockSize) {
1204 dctx->stage = bp.lastBlock ? ZSTDds_decompressLastBlock : ZSTDds_decompressBlock;
1205 return 0;
1206 }
1207 /* empty block */
1208 if (bp.lastBlock) {
1209 if (dctx->fParams.checksumFlag) {
1210 dctx->expected = 4;
1211 dctx->stage = ZSTDds_checkChecksum;
1212 } else {
1213 dctx->expected = 0; /* end of frame */
1214 dctx->stage = ZSTDds_getFrameHeaderSize;
1215 }
1216 } else {
1217 dctx->expected = ZSTD_blockHeaderSize; /* jump to next header */
1218 dctx->stage = ZSTDds_decodeBlockHeader;
1219 }
1220 return 0;
1221 }
1222
1223 case ZSTDds_decompressLastBlock:
1224 case ZSTDds_decompressBlock:
1225 DEBUGLOG(5, "ZSTD_decompressContinue: case ZSTDds_decompressBlock");
1226 { size_t rSize;
1227 switch(dctx->bType)
1228 {
1229 case bt_compressed:
1230 DEBUGLOG(5, "ZSTD_decompressContinue: case bt_compressed");
1231 rSize = ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize, /* frame */ 1, is_streaming);
1232 dctx->expected = 0; /* Streaming not supported */
1233 break;
1234 case bt_raw :
1235 assert(srcSize <= dctx->expected);
1236 rSize = ZSTD_copyRawBlock(dst, dstCapacity, src, srcSize);
1237 FORWARD_IF_ERROR(rSize, "ZSTD_copyRawBlock failed");
1238 assert(rSize == srcSize);
1239 dctx->expected -= rSize;
1240 break;
1241 case bt_rle :
1242 rSize = ZSTD_setRleBlock(dst, dstCapacity, *(const BYTE*)src, dctx->rleSize);
1243 dctx->expected = 0; /* Streaming not supported */
1244 break;
1245 case bt_reserved : /* should never happen */
1246 default:
1247 RETURN_ERROR(corruption_detected, "invalid block type");
1248 }
1249 FORWARD_IF_ERROR(rSize, "");
1250 RETURN_ERROR_IF(rSize > dctx->fParams.blockSizeMax, corruption_detected, "Decompressed Block Size Exceeds Maximum");
1251 DEBUGLOG(5, "ZSTD_decompressContinue: decoded size from block : %u", (unsigned)rSize);
1252 dctx->decodedSize += rSize;
1253 if (dctx->validateChecksum) XXH64_update(&dctx->xxhState, dst, rSize);
1254 dctx->previousDstEnd = (char*)dst + rSize;
1255
1256 /* Stay on the same stage until we are finished streaming the block. */
1257 if (dctx->expected > 0) {
1258 return rSize;
1259 }
1260
1261 if (dctx->stage == ZSTDds_decompressLastBlock) { /* end of frame */
1262 DEBUGLOG(4, "ZSTD_decompressContinue: decoded size from frame : %u", (unsigned)dctx->decodedSize);
1263 RETURN_ERROR_IF(
1264 dctx->fParams.frameContentSize != ZSTD_CONTENTSIZE_UNKNOWN
1265 && dctx->decodedSize != dctx->fParams.frameContentSize,
1266 corruption_detected, "");
1267 if (dctx->fParams.checksumFlag) { /* another round for frame checksum */
1268 dctx->expected = 4;
1269 dctx->stage = ZSTDds_checkChecksum;
1270 } else {
1271 ZSTD_DCtx_trace_end(dctx, dctx->decodedSize, dctx->processedCSize, /* streaming */ 1);
1272 dctx->expected = 0; /* ends here */
1273 dctx->stage = ZSTDds_getFrameHeaderSize;
1274 }
1275 } else {
1276 dctx->stage = ZSTDds_decodeBlockHeader;
1277 dctx->expected = ZSTD_blockHeaderSize;
1278 }
1279 return rSize;
1280 }
1281
1282 case ZSTDds_checkChecksum:
1283 assert(srcSize == 4); /* guaranteed by dctx->expected */
1284 {
1285 if (dctx->validateChecksum) {
1286 U32 const h32 = (U32)XXH64_digest(&dctx->xxhState);
1287 U32 const check32 = MEM_readLE32(src);
1288 DEBUGLOG(4, "ZSTD_decompressContinue: checksum : calculated %08X :: %08X read", (unsigned)h32, (unsigned)check32);
1289 RETURN_ERROR_IF(check32 != h32, checksum_wrong, "");
1290 }
1291 ZSTD_DCtx_trace_end(dctx, dctx->decodedSize, dctx->processedCSize, /* streaming */ 1);
1292 dctx->expected = 0;
1293 dctx->stage = ZSTDds_getFrameHeaderSize;
1294 return 0;
1295 }
1296
1297 case ZSTDds_decodeSkippableHeader:
1298 assert(src != NULL);
1299 assert(srcSize <= ZSTD_SKIPPABLEHEADERSIZE);
1300 ZSTD_memcpy(dctx->headerBuffer + (ZSTD_SKIPPABLEHEADERSIZE - srcSize), src, srcSize); /* complete skippable header */
1301 dctx->expected = MEM_readLE32(dctx->headerBuffer + ZSTD_FRAMEIDSIZE); /* note : dctx->expected can grow seriously large, beyond local buffer size */
1302 dctx->stage = ZSTDds_skipFrame;
1303 return 0;
1304
1305 case ZSTDds_skipFrame:
1306 dctx->expected = 0;
1307 dctx->stage = ZSTDds_getFrameHeaderSize;
1308 return 0;
1309
1310 default:
1311 assert(0); /* impossible */
1312 RETURN_ERROR(GENERIC, "impossible to reach"); /* some compiler require default to do something */
1313 }
1314}
1315
1316
1317static size_t ZSTD_refDictContent(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
1318{
1319 dctx->dictEnd = dctx->previousDstEnd;
1320 dctx->virtualStart = (const char*)dict - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->prefixStart));
1321 dctx->prefixStart = dict;
1322 dctx->previousDstEnd = (const char*)dict + dictSize;
1323#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
1324 dctx->dictContentBeginForFuzzing = dctx->prefixStart;
1325 dctx->dictContentEndForFuzzing = dctx->previousDstEnd;
1326#endif
1327 return 0;
1328}
1329
1330/*! ZSTD_loadDEntropy() :
1331 * dict : must point at beginning of a valid zstd dictionary.
1332 * @return : size of entropy tables read */
1333size_t
1334ZSTD_loadDEntropy(ZSTD_entropyDTables_t* entropy,
1335 const void* const dict, size_t const dictSize)
1336{
1337 const BYTE* dictPtr = (const BYTE*)dict;
1338 const BYTE* const dictEnd = dictPtr + dictSize;
1339
1340 RETURN_ERROR_IF(dictSize <= 8, dictionary_corrupted, "dict is too small");
1341 assert(MEM_readLE32(dict) == ZSTD_MAGIC_DICTIONARY); /* dict must be valid */
1342 dictPtr += 8; /* skip header = magic + dictID */
1343
1344 ZSTD_STATIC_ASSERT(offsetof(ZSTD_entropyDTables_t, OFTable) == offsetof(ZSTD_entropyDTables_t, LLTable) + sizeof(entropy->LLTable));
1345 ZSTD_STATIC_ASSERT(offsetof(ZSTD_entropyDTables_t, MLTable) == offsetof(ZSTD_entropyDTables_t, OFTable) + sizeof(entropy->OFTable));
1346 ZSTD_STATIC_ASSERT(sizeof(entropy->LLTable) + sizeof(entropy->OFTable) + sizeof(entropy->MLTable) >= HUF_DECOMPRESS_WORKSPACE_SIZE);
1347 { void* const workspace = &entropy->LLTable; /* use fse tables as temporary workspace; implies fse tables are grouped together */
1348 size_t const workspaceSize = sizeof(entropy->LLTable) + sizeof(entropy->OFTable) + sizeof(entropy->MLTable);
1349#ifdef HUF_FORCE_DECOMPRESS_X1
1350 /* in minimal huffman, we always use X1 variants */
1351 size_t const hSize = HUF_readDTableX1_wksp(entropy->hufTable,
1352 dictPtr, dictEnd - dictPtr,
1353 workspace, workspaceSize);
1354#else
1355 size_t const hSize = HUF_readDTableX2_wksp(entropy->hufTable,
1356 dictPtr, (size_t)(dictEnd - dictPtr),
1357 workspace, workspaceSize);
1358#endif
1359 RETURN_ERROR_IF(HUF_isError(hSize), dictionary_corrupted, "");
1360 dictPtr += hSize;
1361 }
1362
1363 { short offcodeNCount[MaxOff+1];
1364 unsigned offcodeMaxValue = MaxOff, offcodeLog;
1365 size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, (size_t)(dictEnd-dictPtr));
1366 RETURN_ERROR_IF(FSE_isError(offcodeHeaderSize), dictionary_corrupted, "");
1367 RETURN_ERROR_IF(offcodeMaxValue > MaxOff, dictionary_corrupted, "");
1368 RETURN_ERROR_IF(offcodeLog > OffFSELog, dictionary_corrupted, "");
1369 ZSTD_buildFSETable( entropy->OFTable,
1370 offcodeNCount, offcodeMaxValue,
1371 OF_base, OF_bits,
1372 offcodeLog,
1373 entropy->workspace, sizeof(entropy->workspace),
1374 /* bmi2 */0);
1375 dictPtr += offcodeHeaderSize;
1376 }
1377
1378 { short matchlengthNCount[MaxML+1];
1379 unsigned matchlengthMaxValue = MaxML, matchlengthLog;
1380 size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, (size_t)(dictEnd-dictPtr));
1381 RETURN_ERROR_IF(FSE_isError(matchlengthHeaderSize), dictionary_corrupted, "");
1382 RETURN_ERROR_IF(matchlengthMaxValue > MaxML, dictionary_corrupted, "");
1383 RETURN_ERROR_IF(matchlengthLog > MLFSELog, dictionary_corrupted, "");
1384 ZSTD_buildFSETable( entropy->MLTable,
1385 matchlengthNCount, matchlengthMaxValue,
1386 ML_base, ML_bits,
1387 matchlengthLog,
1388 entropy->workspace, sizeof(entropy->workspace),
1389 /* bmi2 */ 0);
1390 dictPtr += matchlengthHeaderSize;
1391 }
1392
1393 { short litlengthNCount[MaxLL+1];
1394 unsigned litlengthMaxValue = MaxLL, litlengthLog;
1395 size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, (size_t)(dictEnd-dictPtr));
1396 RETURN_ERROR_IF(FSE_isError(litlengthHeaderSize), dictionary_corrupted, "");
1397 RETURN_ERROR_IF(litlengthMaxValue > MaxLL, dictionary_corrupted, "");
1398 RETURN_ERROR_IF(litlengthLog > LLFSELog, dictionary_corrupted, "");
1399 ZSTD_buildFSETable( entropy->LLTable,
1400 litlengthNCount, litlengthMaxValue,
1401 LL_base, LL_bits,
1402 litlengthLog,
1403 entropy->workspace, sizeof(entropy->workspace),
1404 /* bmi2 */ 0);
1405 dictPtr += litlengthHeaderSize;
1406 }
1407
1408 RETURN_ERROR_IF(dictPtr+12 > dictEnd, dictionary_corrupted, "");
1409 { int i;
1410 size_t const dictContentSize = (size_t)(dictEnd - (dictPtr+12));
1411 for (i=0; i<3; i++) {
1412 U32 const rep = MEM_readLE32(dictPtr); dictPtr += 4;
1413 RETURN_ERROR_IF(rep==0 || rep > dictContentSize,
1414 dictionary_corrupted, "");
1415 entropy->rep[i] = rep;
1416 } }
1417
1418 return (size_t)(dictPtr - (const BYTE*)dict);
1419}
1420
1421static size_t ZSTD_decompress_insertDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
1422{
1423 if (dictSize < 8) return ZSTD_refDictContent(dctx, dict, dictSize);
1424 { U32 const magic = MEM_readLE32(dict);
1425 if (magic != ZSTD_MAGIC_DICTIONARY) {
1426 return ZSTD_refDictContent(dctx, dict, dictSize); /* pure content mode */
1427 } }
1428 dctx->dictID = MEM_readLE32((const char*)dict + ZSTD_FRAMEIDSIZE);
1429
1430 /* load entropy tables */
1431 { size_t const eSize = ZSTD_loadDEntropy(&dctx->entropy, dict, dictSize);
1432 RETURN_ERROR_IF(ZSTD_isError(eSize), dictionary_corrupted, "");
1433 dict = (const char*)dict + eSize;
1434 dictSize -= eSize;
1435 }
1436 dctx->litEntropy = dctx->fseEntropy = 1;
1437
1438 /* reference dictionary content */
1439 return ZSTD_refDictContent(dctx, dict, dictSize);
1440}
1441
1442size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx)
1443{
1444 assert(dctx != NULL);
1445#if ZSTD_TRACE
1446 dctx->traceCtx = (ZSTD_trace_decompress_begin != NULL) ? ZSTD_trace_decompress_begin(dctx) : 0;
1447#endif
1448 dctx->expected = ZSTD_startingInputLength(dctx->format); /* dctx->format must be properly set */
1449 dctx->stage = ZSTDds_getFrameHeaderSize;
1450 dctx->processedCSize = 0;
1451 dctx->decodedSize = 0;
1452 dctx->previousDstEnd = NULL;
1453 dctx->prefixStart = NULL;
1454 dctx->virtualStart = NULL;
1455 dctx->dictEnd = NULL;
1456 dctx->entropy.hufTable[0] = (HUF_DTable)((HufLog)*0x1000001); /* cover both little and big endian */
1457 dctx->litEntropy = dctx->fseEntropy = 0;
1458 dctx->dictID = 0;
1459 dctx->bType = bt_reserved;
1460 ZSTD_STATIC_ASSERT(sizeof(dctx->entropy.rep) == sizeof(repStartValue));
1461 ZSTD_memcpy(dctx->entropy.rep, repStartValue, sizeof(repStartValue)); /* initial repcodes */
1462 dctx->LLTptr = dctx->entropy.LLTable;
1463 dctx->MLTptr = dctx->entropy.MLTable;
1464 dctx->OFTptr = dctx->entropy.OFTable;
1465 dctx->HUFptr = dctx->entropy.hufTable;
1466 return 0;
1467}
1468
1469size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
1470{
1471 FORWARD_IF_ERROR( ZSTD_decompressBegin(dctx) , "");
1472 if (dict && dictSize)
1473 RETURN_ERROR_IF(
1474 ZSTD_isError(ZSTD_decompress_insertDictionary(dctx, dict, dictSize)),
1475 dictionary_corrupted, "");
1476 return 0;
1477}
1478
1479
1480/* ====== ZSTD_DDict ====== */
1481
1482size_t ZSTD_decompressBegin_usingDDict(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict)
1483{
1484 DEBUGLOG(4, "ZSTD_decompressBegin_usingDDict");
1485 assert(dctx != NULL);
1486 if (ddict) {
1487 const char* const dictStart = (const char*)ZSTD_DDict_dictContent(ddict);
1488 size_t const dictSize = ZSTD_DDict_dictSize(ddict);
1489 const void* const dictEnd = dictStart + dictSize;
1490 dctx->ddictIsCold = (dctx->dictEnd != dictEnd);
1491 DEBUGLOG(4, "DDict is %s",
1492 dctx->ddictIsCold ? "~cold~" : "hot!");
1493 }
1494 FORWARD_IF_ERROR( ZSTD_decompressBegin(dctx) , "");
1495 if (ddict) { /* NULL ddict is equivalent to no dictionary */
1496 ZSTD_copyDDictParameters(dctx, ddict);
1497 }
1498 return 0;
1499}
1500
1501/*! ZSTD_getDictID_fromDict() :
1502 * Provides the dictID stored within dictionary.
1503 * if @return == 0, the dictionary is not conformant with Zstandard specification.
1504 * It can still be loaded, but as a content-only dictionary. */
1505unsigned ZSTD_getDictID_fromDict(const void* dict, size_t dictSize)
1506{
1507 if (dictSize < 8) return 0;
1508 if (MEM_readLE32(dict) != ZSTD_MAGIC_DICTIONARY) return 0;
1509 return MEM_readLE32((const char*)dict + ZSTD_FRAMEIDSIZE);
1510}
1511
1512/*! ZSTD_getDictID_fromFrame() :
1513 * Provides the dictID required to decompress frame stored within `src`.
1514 * If @return == 0, the dictID could not be decoded.
1515 * This could for one of the following reasons :
1516 * - The frame does not require a dictionary (most common case).
1517 * - The frame was built with dictID intentionally removed.
1518 * Needed dictionary is a hidden information.
1519 * Note : this use case also happens when using a non-conformant dictionary.
1520 * - `srcSize` is too small, and as a result, frame header could not be decoded.
1521 * Note : possible if `srcSize < ZSTD_FRAMEHEADERSIZE_MAX`.
1522 * - This is not a Zstandard frame.
1523 * When identifying the exact failure cause, it's possible to use
1524 * ZSTD_getFrameHeader(), which will provide a more precise error code. */
1525unsigned ZSTD_getDictID_fromFrame(const void* src, size_t srcSize)
1526{
1527 ZSTD_frameHeader zfp = { 0, 0, 0, ZSTD_frame, 0, 0, 0 };
1528 size_t const hError = ZSTD_getFrameHeader(&zfp, src, srcSize);
1529 if (ZSTD_isError(hError)) return 0;
1530 return zfp.dictID;
1531}
1532
1533
1534/*! ZSTD_decompress_usingDDict() :
1535* Decompression using a pre-digested Dictionary
1536* Use dictionary without significant overhead. */
1537size_t ZSTD_decompress_usingDDict(ZSTD_DCtx* dctx,
1538 void* dst, size_t dstCapacity,
1539 const void* src, size_t srcSize,
1540 const ZSTD_DDict* ddict)
1541{
1542 /* pass content and size in case legacy frames are encountered */
1543 return ZSTD_decompressMultiFrame(dctx, dst, dstCapacity, src, srcSize,
1544 NULL, 0,
1545 ddict);
1546}
1547
1548
1549/*=====================================
1550* Streaming decompression
1551*====================================*/
1552
1553ZSTD_DStream* ZSTD_createDStream(void)
1554{
1555 DEBUGLOG(3, "ZSTD_createDStream");
1556 return ZSTD_createDCtx_internal(ZSTD_defaultCMem);
1557}
1558
1559ZSTD_DStream* ZSTD_initStaticDStream(void *workspace, size_t workspaceSize)
1560{
1561 return ZSTD_initStaticDCtx(workspace, workspaceSize);
1562}
1563
1564ZSTD_DStream* ZSTD_createDStream_advanced(ZSTD_customMem customMem)
1565{
1566 return ZSTD_createDCtx_internal(customMem);
1567}
1568
1569size_t ZSTD_freeDStream(ZSTD_DStream* zds)
1570{
1571 return ZSTD_freeDCtx(zds);
1572}
1573
1574
1575/* *** Initialization *** */
1576
1577size_t ZSTD_DStreamInSize(void) { return ZSTD_BLOCKSIZE_MAX + ZSTD_blockHeaderSize; }
1578size_t ZSTD_DStreamOutSize(void) { return ZSTD_BLOCKSIZE_MAX; }
1579
1580size_t ZSTD_DCtx_loadDictionary_advanced(ZSTD_DCtx* dctx,
1581 const void* dict, size_t dictSize,
1582 ZSTD_dictLoadMethod_e dictLoadMethod,
1583 ZSTD_dictContentType_e dictContentType)
1584{
1585 RETURN_ERROR_IF(dctx->streamStage != zdss_init, stage_wrong, "");
1586 ZSTD_clearDict(dctx);
1587 if (dict && dictSize != 0) {
1588 dctx->ddictLocal = ZSTD_createDDict_advanced(dict, dictSize, dictLoadMethod, dictContentType, dctx->customMem);
1589 RETURN_ERROR_IF(dctx->ddictLocal == NULL, memory_allocation, "NULL pointer!");
1590 dctx->ddict = dctx->ddictLocal;
1591 dctx->dictUses = ZSTD_use_indefinitely;
1592 }
1593 return 0;
1594}
1595
1596size_t ZSTD_DCtx_loadDictionary_byReference(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
1597{
1598 return ZSTD_DCtx_loadDictionary_advanced(dctx, dict, dictSize, ZSTD_dlm_byRef, ZSTD_dct_auto);
1599}
1600
1601size_t ZSTD_DCtx_loadDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
1602{
1603 return ZSTD_DCtx_loadDictionary_advanced(dctx, dict, dictSize, ZSTD_dlm_byCopy, ZSTD_dct_auto);
1604}
1605
1606size_t ZSTD_DCtx_refPrefix_advanced(ZSTD_DCtx* dctx, const void* prefix, size_t prefixSize, ZSTD_dictContentType_e dictContentType)
1607{
1608 FORWARD_IF_ERROR(ZSTD_DCtx_loadDictionary_advanced(dctx, prefix, prefixSize, ZSTD_dlm_byRef, dictContentType), "");
1609 dctx->dictUses = ZSTD_use_once;
1610 return 0;
1611}
1612
1613size_t ZSTD_DCtx_refPrefix(ZSTD_DCtx* dctx, const void* prefix, size_t prefixSize)
1614{
1615 return ZSTD_DCtx_refPrefix_advanced(dctx, prefix, prefixSize, ZSTD_dct_rawContent);
1616}
1617
1618
1619/* ZSTD_initDStream_usingDict() :
1620 * return : expected size, aka ZSTD_startingInputLength().
1621 * this function cannot fail */
1622size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dict, size_t dictSize)
1623{
1624 DEBUGLOG(4, "ZSTD_initDStream_usingDict");
1625 FORWARD_IF_ERROR( ZSTD_DCtx_reset(zds, ZSTD_reset_session_only) , "");
1626 FORWARD_IF_ERROR( ZSTD_DCtx_loadDictionary(zds, dict, dictSize) , "");
1627 return ZSTD_startingInputLength(zds->format);
1628}
1629
1630/* note : this variant can't fail */
1631size_t ZSTD_initDStream(ZSTD_DStream* zds)
1632{
1633 DEBUGLOG(4, "ZSTD_initDStream");
1634 return ZSTD_initDStream_usingDDict(zds, NULL);
1635}
1636
1637/* ZSTD_initDStream_usingDDict() :
1638 * ddict will just be referenced, and must outlive decompression session
1639 * this function cannot fail */
1640size_t ZSTD_initDStream_usingDDict(ZSTD_DStream* dctx, const ZSTD_DDict* ddict)
1641{
1642 FORWARD_IF_ERROR( ZSTD_DCtx_reset(dctx, ZSTD_reset_session_only) , "");
1643 FORWARD_IF_ERROR( ZSTD_DCtx_refDDict(dctx, ddict) , "");
1644 return ZSTD_startingInputLength(dctx->format);
1645}
1646
1647/* ZSTD_resetDStream() :
1648 * return : expected size, aka ZSTD_startingInputLength().
1649 * this function cannot fail */
1650size_t ZSTD_resetDStream(ZSTD_DStream* dctx)
1651{
1652 FORWARD_IF_ERROR(ZSTD_DCtx_reset(dctx, ZSTD_reset_session_only), "");
1653 return ZSTD_startingInputLength(dctx->format);
1654}
1655
1656
1657size_t ZSTD_DCtx_refDDict(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict)
1658{
1659 RETURN_ERROR_IF(dctx->streamStage != zdss_init, stage_wrong, "");
1660 ZSTD_clearDict(dctx);
1661 if (ddict) {
1662 dctx->ddict = ddict;
1663 dctx->dictUses = ZSTD_use_indefinitely;
1664 if (dctx->refMultipleDDicts == ZSTD_rmd_refMultipleDDicts) {
1665 if (dctx->ddictSet == NULL) {
1666 dctx->ddictSet = ZSTD_createDDictHashSet(dctx->customMem);
1667 if (!dctx->ddictSet) {
1668 RETURN_ERROR(memory_allocation, "Failed to allocate memory for hash set!");
1669 }
1670 }
1671 assert(!dctx->staticSize); /* Impossible: ddictSet cannot have been allocated if static dctx */
1672 FORWARD_IF_ERROR(ZSTD_DDictHashSet_addDDict(dctx->ddictSet, ddict, dctx->customMem), "");
1673 }
1674 }
1675 return 0;
1676}
1677
1678/* ZSTD_DCtx_setMaxWindowSize() :
1679 * note : no direct equivalence in ZSTD_DCtx_setParameter,
1680 * since this version sets windowSize, and the other sets windowLog */
1681size_t ZSTD_DCtx_setMaxWindowSize(ZSTD_DCtx* dctx, size_t maxWindowSize)
1682{
1683 ZSTD_bounds const bounds = ZSTD_dParam_getBounds(ZSTD_d_windowLogMax);
1684 size_t const min = (size_t)1 << bounds.lowerBound;
1685 size_t const max = (size_t)1 << bounds.upperBound;
1686 RETURN_ERROR_IF(dctx->streamStage != zdss_init, stage_wrong, "");
1687 RETURN_ERROR_IF(maxWindowSize < min, parameter_outOfBound, "");
1688 RETURN_ERROR_IF(maxWindowSize > max, parameter_outOfBound, "");
1689 dctx->maxWindowSize = maxWindowSize;
1690 return 0;
1691}
1692
1693size_t ZSTD_DCtx_setFormat(ZSTD_DCtx* dctx, ZSTD_format_e format)
1694{
1695 return ZSTD_DCtx_setParameter(dctx, ZSTD_d_format, (int)format);
1696}
1697
1698ZSTD_bounds ZSTD_dParam_getBounds(ZSTD_dParameter dParam)
1699{
1700 ZSTD_bounds bounds = { 0, 0, 0 };
1701 switch(dParam) {
1702 case ZSTD_d_windowLogMax:
1703 bounds.lowerBound = ZSTD_WINDOWLOG_ABSOLUTEMIN;
1704 bounds.upperBound = ZSTD_WINDOWLOG_MAX;
1705 return bounds;
1706 case ZSTD_d_format:
1707 bounds.lowerBound = (int)ZSTD_f_zstd1;
1708 bounds.upperBound = (int)ZSTD_f_zstd1_magicless;
1709 ZSTD_STATIC_ASSERT(ZSTD_f_zstd1 < ZSTD_f_zstd1_magicless);
1710 return bounds;
1711 case ZSTD_d_stableOutBuffer:
1712 bounds.lowerBound = (int)ZSTD_bm_buffered;
1713 bounds.upperBound = (int)ZSTD_bm_stable;
1714 return bounds;
1715 case ZSTD_d_forceIgnoreChecksum:
1716 bounds.lowerBound = (int)ZSTD_d_validateChecksum;
1717 bounds.upperBound = (int)ZSTD_d_ignoreChecksum;
1718 return bounds;
1719 case ZSTD_d_refMultipleDDicts:
1720 bounds.lowerBound = (int)ZSTD_rmd_refSingleDDict;
1721 bounds.upperBound = (int)ZSTD_rmd_refMultipleDDicts;
1722 return bounds;
1723 default:;
1724 }
1725 bounds.error = ERROR(parameter_unsupported);
1726 return bounds;
1727}
1728
1729/* ZSTD_dParam_withinBounds:
1730 * @return 1 if value is within dParam bounds,
1731 * 0 otherwise */
1732static int ZSTD_dParam_withinBounds(ZSTD_dParameter dParam, int value)
1733{
1734 ZSTD_bounds const bounds = ZSTD_dParam_getBounds(dParam);
1735 if (ZSTD_isError(bounds.error)) return 0;
1736 if (value < bounds.lowerBound) return 0;
1737 if (value > bounds.upperBound) return 0;
1738 return 1;
1739}
1740
1741#define CHECK_DBOUNDS(p,v) { \
1742 RETURN_ERROR_IF(!ZSTD_dParam_withinBounds(p, v), parameter_outOfBound, ""); \
1743}
1744
1745size_t ZSTD_DCtx_getParameter(ZSTD_DCtx* dctx, ZSTD_dParameter param, int* value)
1746{
1747 switch (param) {
1748 case ZSTD_d_windowLogMax:
1749 *value = (int)ZSTD_highbit32((U32)dctx->maxWindowSize);
1750 return 0;
1751 case ZSTD_d_format:
1752 *value = (int)dctx->format;
1753 return 0;
1754 case ZSTD_d_stableOutBuffer:
1755 *value = (int)dctx->outBufferMode;
1756 return 0;
1757 case ZSTD_d_forceIgnoreChecksum:
1758 *value = (int)dctx->forceIgnoreChecksum;
1759 return 0;
1760 case ZSTD_d_refMultipleDDicts:
1761 *value = (int)dctx->refMultipleDDicts;
1762 return 0;
1763 default:;
1764 }
1765 RETURN_ERROR(parameter_unsupported, "");
1766}
1767
1768size_t ZSTD_DCtx_setParameter(ZSTD_DCtx* dctx, ZSTD_dParameter dParam, int value)
1769{
1770 RETURN_ERROR_IF(dctx->streamStage != zdss_init, stage_wrong, "");
1771 switch(dParam) {
1772 case ZSTD_d_windowLogMax:
1773 if (value == 0) value = ZSTD_WINDOWLOG_LIMIT_DEFAULT;
1774 CHECK_DBOUNDS(ZSTD_d_windowLogMax, value);
1775 dctx->maxWindowSize = ((size_t)1) << value;
1776 return 0;
1777 case ZSTD_d_format:
1778 CHECK_DBOUNDS(ZSTD_d_format, value);
1779 dctx->format = (ZSTD_format_e)value;
1780 return 0;
1781 case ZSTD_d_stableOutBuffer:
1782 CHECK_DBOUNDS(ZSTD_d_stableOutBuffer, value);
1783 dctx->outBufferMode = (ZSTD_bufferMode_e)value;
1784 return 0;
1785 case ZSTD_d_forceIgnoreChecksum:
1786 CHECK_DBOUNDS(ZSTD_d_forceIgnoreChecksum, value);
1787 dctx->forceIgnoreChecksum = (ZSTD_forceIgnoreChecksum_e)value;
1788 return 0;
1789 case ZSTD_d_refMultipleDDicts:
1790 CHECK_DBOUNDS(ZSTD_d_refMultipleDDicts, value);
1791 if (dctx->staticSize != 0) {
1792 RETURN_ERROR(parameter_unsupported, "Static dctx does not support multiple DDicts!");
1793 }
1794 dctx->refMultipleDDicts = (ZSTD_refMultipleDDicts_e)value;
1795 return 0;
1796 default:;
1797 }
1798 RETURN_ERROR(parameter_unsupported, "");
1799}
1800
1801size_t ZSTD_DCtx_reset(ZSTD_DCtx* dctx, ZSTD_ResetDirective reset)
1802{
1803 if ( (reset == ZSTD_reset_session_only)
1804 || (reset == ZSTD_reset_session_and_parameters) ) {
1805 dctx->streamStage = zdss_init;
1806 dctx->noForwardProgress = 0;
1807 }
1808 if ( (reset == ZSTD_reset_parameters)
1809 || (reset == ZSTD_reset_session_and_parameters) ) {
1810 RETURN_ERROR_IF(dctx->streamStage != zdss_init, stage_wrong, "");
1811 ZSTD_clearDict(dctx);
1812 ZSTD_DCtx_resetParameters(dctx);
1813 }
1814 return 0;
1815}
1816
1817
1818size_t ZSTD_sizeof_DStream(const ZSTD_DStream* dctx)
1819{
1820 return ZSTD_sizeof_DCtx(dctx);
1821}
1822
1823size_t ZSTD_decodingBufferSize_min(unsigned long long windowSize, unsigned long long frameContentSize)
1824{
1825 size_t const blockSize = (size_t) MIN(windowSize, ZSTD_BLOCKSIZE_MAX);
1826 /* space is needed to store the litbuffer after the output of a given block without stomping the extDict of a previous run, as well as to cover both windows against wildcopy*/
1827 unsigned long long const neededRBSize = windowSize + blockSize + ZSTD_BLOCKSIZE_MAX + (WILDCOPY_OVERLENGTH * 2);
1828 unsigned long long const neededSize = MIN(frameContentSize, neededRBSize);
1829 size_t const minRBSize = (size_t) neededSize;
1830 RETURN_ERROR_IF((unsigned long long)minRBSize != neededSize,
1831 frameParameter_windowTooLarge, "");
1832 return minRBSize;
1833}
1834
1835size_t ZSTD_estimateDStreamSize(size_t windowSize)
1836{
1837 size_t const blockSize = MIN(windowSize, ZSTD_BLOCKSIZE_MAX);
1838 size_t const inBuffSize = blockSize; /* no block can be larger */
1839 size_t const outBuffSize = ZSTD_decodingBufferSize_min(windowSize, ZSTD_CONTENTSIZE_UNKNOWN);
1840 return ZSTD_estimateDCtxSize() + inBuffSize + outBuffSize;
1841}
1842
1843size_t ZSTD_estimateDStreamSize_fromFrame(const void* src, size_t srcSize)
1844{
1845 U32 const windowSizeMax = 1U << ZSTD_WINDOWLOG_MAX; /* note : should be user-selectable, but requires an additional parameter (or a dctx) */
1846 ZSTD_frameHeader zfh;
1847 size_t const err = ZSTD_getFrameHeader(&zfh, src, srcSize);
1848 if (ZSTD_isError(err)) return err;
1849 RETURN_ERROR_IF(err>0, srcSize_wrong, "");
1850 RETURN_ERROR_IF(zfh.windowSize > windowSizeMax,
1851 frameParameter_windowTooLarge, "");
1852 return ZSTD_estimateDStreamSize((size_t)zfh.windowSize);
1853}
1854
1855
1856/* ***** Decompression ***** */
1857
1858static int ZSTD_DCtx_isOverflow(ZSTD_DStream* zds, size_t const neededInBuffSize, size_t const neededOutBuffSize)
1859{
1860 return (zds->inBuffSize + zds->outBuffSize) >= (neededInBuffSize + neededOutBuffSize) * ZSTD_WORKSPACETOOLARGE_FACTOR;
1861}
1862
1863static void ZSTD_DCtx_updateOversizedDuration(ZSTD_DStream* zds, size_t const neededInBuffSize, size_t const neededOutBuffSize)
1864{
1865 if (ZSTD_DCtx_isOverflow(zds, neededInBuffSize, neededOutBuffSize))
1866 zds->oversizedDuration++;
1867 else
1868 zds->oversizedDuration = 0;
1869}
1870
1871static int ZSTD_DCtx_isOversizedTooLong(ZSTD_DStream* zds)
1872{
1873 return zds->oversizedDuration >= ZSTD_WORKSPACETOOLARGE_MAXDURATION;
1874}
1875
1876/* Checks that the output buffer hasn't changed if ZSTD_obm_stable is used. */
1877static size_t ZSTD_checkOutBuffer(ZSTD_DStream const* zds, ZSTD_outBuffer const* output)
1878{
1879 ZSTD_outBuffer const expect = zds->expectedOutBuffer;
1880 /* No requirement when ZSTD_obm_stable is not enabled. */
1881 if (zds->outBufferMode != ZSTD_bm_stable)
1882 return 0;
1883 /* Any buffer is allowed in zdss_init, this must be the same for every other call until
1884 * the context is reset.
1885 */
1886 if (zds->streamStage == zdss_init)
1887 return 0;
1888 /* The buffer must match our expectation exactly. */
1889 if (expect.dst == output->dst && expect.pos == output->pos && expect.size == output->size)
1890 return 0;
1891 RETURN_ERROR(dstBuffer_wrong, "ZSTD_d_stableOutBuffer enabled but output differs!");
1892}
1893
1894/* Calls ZSTD_decompressContinue() with the right parameters for ZSTD_decompressStream()
1895 * and updates the stage and the output buffer state. This call is extracted so it can be
1896 * used both when reading directly from the ZSTD_inBuffer, and in buffered input mode.
1897 * NOTE: You must break after calling this function since the streamStage is modified.
1898 */
1899static size_t ZSTD_decompressContinueStream(
1900 ZSTD_DStream* zds, char** op, char* oend,
1901 void const* src, size_t srcSize) {
1902 int const isSkipFrame = ZSTD_isSkipFrame(zds);
1903 if (zds->outBufferMode == ZSTD_bm_buffered) {
1904 size_t const dstSize = isSkipFrame ? 0 : zds->outBuffSize - zds->outStart;
1905 size_t const decodedSize = ZSTD_decompressContinue(zds,
1906 zds->outBuff + zds->outStart, dstSize, src, srcSize);
1907 FORWARD_IF_ERROR(decodedSize, "");
1908 if (!decodedSize && !isSkipFrame) {
1909 zds->streamStage = zdss_read;
1910 } else {
1911 zds->outEnd = zds->outStart + decodedSize;
1912 zds->streamStage = zdss_flush;
1913 }
1914 } else {
1915 /* Write directly into the output buffer */
1916 size_t const dstSize = isSkipFrame ? 0 : (size_t)(oend - *op);
1917 size_t const decodedSize = ZSTD_decompressContinue(zds, *op, dstSize, src, srcSize);
1918 FORWARD_IF_ERROR(decodedSize, "");
1919 *op += decodedSize;
1920 /* Flushing is not needed. */
1921 zds->streamStage = zdss_read;
1922 assert(*op <= oend);
1923 assert(zds->outBufferMode == ZSTD_bm_stable);
1924 }
1925 return 0;
1926}
1927
1928size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inBuffer* input)
1929{
1930 const char* const src = (const char*)input->src;
1931 const char* const istart = input->pos != 0 ? src + input->pos : src;
1932 const char* const iend = input->size != 0 ? src + input->size : src;
1933 const char* ip = istart;
1934 char* const dst = (char*)output->dst;
1935 char* const ostart = output->pos != 0 ? dst + output->pos : dst;
1936 char* const oend = output->size != 0 ? dst + output->size : dst;
1937 char* op = ostart;
1938 U32 someMoreWork = 1;
1939
1940 DEBUGLOG(5, "ZSTD_decompressStream");
1941 RETURN_ERROR_IF(
1942 input->pos > input->size,
1943 srcSize_wrong,
1944 "forbidden. in: pos: %u vs size: %u",
1945 (U32)input->pos, (U32)input->size);
1946 RETURN_ERROR_IF(
1947 output->pos > output->size,
1948 dstSize_tooSmall,
1949 "forbidden. out: pos: %u vs size: %u",
1950 (U32)output->pos, (U32)output->size);
1951 DEBUGLOG(5, "input size : %u", (U32)(input->size - input->pos));
1952 FORWARD_IF_ERROR(ZSTD_checkOutBuffer(zds, output), "");
1953
1954 while (someMoreWork) {
1955 switch(zds->streamStage)
1956 {
1957 case zdss_init :
1958 DEBUGLOG(5, "stage zdss_init => transparent reset ");
1959 zds->streamStage = zdss_loadHeader;
1960 zds->lhSize = zds->inPos = zds->outStart = zds->outEnd = 0;
1961#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1)
1962 zds->legacyVersion = 0;
1963#endif
1964 zds->hostageByte = 0;
1965 zds->expectedOutBuffer = *output;
1966 ZSTD_FALLTHROUGH;
1967
1968 case zdss_loadHeader :
1969 DEBUGLOG(5, "stage zdss_loadHeader (srcSize : %u)", (U32)(iend - ip));
1970#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1)
1971 if (zds->legacyVersion) {
1972 RETURN_ERROR_IF(zds->staticSize, memory_allocation,
1973 "legacy support is incompatible with static dctx");
1974 { size_t const hint = ZSTD_decompressLegacyStream(zds->legacyContext, zds->legacyVersion, output, input);
1975 if (hint==0) zds->streamStage = zdss_init;
1976 return hint;
1977 } }
1978#endif
1979 { size_t const hSize = ZSTD_getFrameHeader_advanced(&zds->fParams, zds->headerBuffer, zds->lhSize, zds->format);
1980 if (zds->refMultipleDDicts && zds->ddictSet) {
1981 ZSTD_DCtx_selectFrameDDict(zds);
1982 }
1983 DEBUGLOG(5, "header size : %u", (U32)hSize);
1984 if (ZSTD_isError(hSize)) {
1985#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1)
1986 U32 const legacyVersion = ZSTD_isLegacy(istart, iend-istart);
1987 if (legacyVersion) {
1988 ZSTD_DDict const* const ddict = ZSTD_getDDict(zds);
1989 const void* const dict = ddict ? ZSTD_DDict_dictContent(ddict) : NULL;
1990 size_t const dictSize = ddict ? ZSTD_DDict_dictSize(ddict) : 0;
1991 DEBUGLOG(5, "ZSTD_decompressStream: detected legacy version v0.%u", legacyVersion);
1992 RETURN_ERROR_IF(zds->staticSize, memory_allocation,
1993 "legacy support is incompatible with static dctx");
1994 FORWARD_IF_ERROR(ZSTD_initLegacyStream(&zds->legacyContext,
1995 zds->previousLegacyVersion, legacyVersion,
1996 dict, dictSize), "");
1997 zds->legacyVersion = zds->previousLegacyVersion = legacyVersion;
1998 { size_t const hint = ZSTD_decompressLegacyStream(zds->legacyContext, legacyVersion, output, input);
1999 if (hint==0) zds->streamStage = zdss_init; /* or stay in stage zdss_loadHeader */
2000 return hint;
2001 } }
2002#endif
2003 return hSize; /* error */
2004 }
2005 if (hSize != 0) { /* need more input */
2006 size_t const toLoad = hSize - zds->lhSize; /* if hSize!=0, hSize > zds->lhSize */
2007 size_t const remainingInput = (size_t)(iend-ip);
2008 assert(iend >= ip);
2009 if (toLoad > remainingInput) { /* not enough input to load full header */
2010 if (remainingInput > 0) {
2011 ZSTD_memcpy(zds->headerBuffer + zds->lhSize, ip, remainingInput);
2012 zds->lhSize += remainingInput;
2013 }
2014 input->pos = input->size;
2015 return (MAX((size_t)ZSTD_FRAMEHEADERSIZE_MIN(zds->format), hSize) - zds->lhSize) + ZSTD_blockHeaderSize; /* remaining header bytes + next block header */
2016 }
2017 assert(ip != NULL);
2018 ZSTD_memcpy(zds->headerBuffer + zds->lhSize, ip, toLoad); zds->lhSize = hSize; ip += toLoad;
2019 break;
2020 } }
2021
2022 /* check for single-pass mode opportunity */
2023 if (zds->fParams.frameContentSize != ZSTD_CONTENTSIZE_UNKNOWN
2024 && zds->fParams.frameType != ZSTD_skippableFrame
2025 && (U64)(size_t)(oend-op) >= zds->fParams.frameContentSize) {
2026 size_t const cSize = ZSTD_findFrameCompressedSize(istart, (size_t)(iend-istart));
2027 if (cSize <= (size_t)(iend-istart)) {
2028 /* shortcut : using single-pass mode */
2029 size_t const decompressedSize = ZSTD_decompress_usingDDict(zds, op, (size_t)(oend-op), istart, cSize, ZSTD_getDDict(zds));
2030 if (ZSTD_isError(decompressedSize)) return decompressedSize;
2031 DEBUGLOG(4, "shortcut to single-pass ZSTD_decompress_usingDDict()")
2032 ip = istart + cSize;
2033 op += decompressedSize;
2034 zds->expected = 0;
2035 zds->streamStage = zdss_init;
2036 someMoreWork = 0;
2037 break;
2038 } }
2039
2040 /* Check output buffer is large enough for ZSTD_odm_stable. */
2041 if (zds->outBufferMode == ZSTD_bm_stable
2042 && zds->fParams.frameType != ZSTD_skippableFrame
2043 && zds->fParams.frameContentSize != ZSTD_CONTENTSIZE_UNKNOWN
2044 && (U64)(size_t)(oend-op) < zds->fParams.frameContentSize) {
2045 RETURN_ERROR(dstSize_tooSmall, "ZSTD_obm_stable passed but ZSTD_outBuffer is too small");
2046 }
2047
2048 /* Consume header (see ZSTDds_decodeFrameHeader) */
2049 DEBUGLOG(4, "Consume header");
2050 FORWARD_IF_ERROR(ZSTD_decompressBegin_usingDDict(zds, ZSTD_getDDict(zds)), "");
2051
2052 if ((MEM_readLE32(zds->headerBuffer) & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) { /* skippable frame */
2053 zds->expected = MEM_readLE32(zds->headerBuffer + ZSTD_FRAMEIDSIZE);
2054 zds->stage = ZSTDds_skipFrame;
2055 } else {
2056 FORWARD_IF_ERROR(ZSTD_decodeFrameHeader(zds, zds->headerBuffer, zds->lhSize), "");
2057 zds->expected = ZSTD_blockHeaderSize;
2058 zds->stage = ZSTDds_decodeBlockHeader;
2059 }
2060
2061 /* control buffer memory usage */
2062 DEBUGLOG(4, "Control max memory usage (%u KB <= max %u KB)",
2063 (U32)(zds->fParams.windowSize >>10),
2064 (U32)(zds->maxWindowSize >> 10) );
2065 zds->fParams.windowSize = MAX(zds->fParams.windowSize, 1U << ZSTD_WINDOWLOG_ABSOLUTEMIN);
2066 RETURN_ERROR_IF(zds->fParams.windowSize > zds->maxWindowSize,
2067 frameParameter_windowTooLarge, "");
2068
2069 /* Adapt buffer sizes to frame header instructions */
2070 { size_t const neededInBuffSize = MAX(zds->fParams.blockSizeMax, 4 /* frame checksum */);
2071 size_t const neededOutBuffSize = zds->outBufferMode == ZSTD_bm_buffered
2072 ? ZSTD_decodingBufferSize_min(zds->fParams.windowSize, zds->fParams.frameContentSize)
2073 : 0;
2074
2075 ZSTD_DCtx_updateOversizedDuration(zds, neededInBuffSize, neededOutBuffSize);
2076
2077 { int const tooSmall = (zds->inBuffSize < neededInBuffSize) || (zds->outBuffSize < neededOutBuffSize);
2078 int const tooLarge = ZSTD_DCtx_isOversizedTooLong(zds);
2079
2080 if (tooSmall || tooLarge) {
2081 size_t const bufferSize = neededInBuffSize + neededOutBuffSize;
2082 DEBUGLOG(4, "inBuff : from %u to %u",
2083 (U32)zds->inBuffSize, (U32)neededInBuffSize);
2084 DEBUGLOG(4, "outBuff : from %u to %u",
2085 (U32)zds->outBuffSize, (U32)neededOutBuffSize);
2086 if (zds->staticSize) { /* static DCtx */
2087 DEBUGLOG(4, "staticSize : %u", (U32)zds->staticSize);
2088 assert(zds->staticSize >= sizeof(ZSTD_DCtx)); /* controlled at init */
2089 RETURN_ERROR_IF(
2090 bufferSize > zds->staticSize - sizeof(ZSTD_DCtx),
2091 memory_allocation, "");
2092 } else {
2093 ZSTD_customFree(zds->inBuff, zds->customMem);
2094 zds->inBuffSize = 0;
2095 zds->outBuffSize = 0;
2096 zds->inBuff = (char*)ZSTD_customMalloc(bufferSize, zds->customMem);
2097 RETURN_ERROR_IF(zds->inBuff == NULL, memory_allocation, "");
2098 }
2099 zds->inBuffSize = neededInBuffSize;
2100 zds->outBuff = zds->inBuff + zds->inBuffSize;
2101 zds->outBuffSize = neededOutBuffSize;
2102 } } }
2103 zds->streamStage = zdss_read;
2104 ZSTD_FALLTHROUGH;
2105
2106 case zdss_read:
2107 DEBUGLOG(5, "stage zdss_read");
2108 { size_t const neededInSize = ZSTD_nextSrcSizeToDecompressWithInputSize(zds, (size_t)(iend - ip));
2109 DEBUGLOG(5, "neededInSize = %u", (U32)neededInSize);
2110 if (neededInSize==0) { /* end of frame */
2111 zds->streamStage = zdss_init;
2112 someMoreWork = 0;
2113 break;
2114 }
2115 if ((size_t)(iend-ip) >= neededInSize) { /* decode directly from src */
2116 FORWARD_IF_ERROR(ZSTD_decompressContinueStream(zds, &op, oend, ip, neededInSize), "");
2117 ip += neededInSize;
2118 /* Function modifies the stage so we must break */
2119 break;
2120 } }
2121 if (ip==iend) { someMoreWork = 0; break; } /* no more input */
2122 zds->streamStage = zdss_load;
2123 ZSTD_FALLTHROUGH;
2124
2125 case zdss_load:
2126 { size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zds);
2127 size_t const toLoad = neededInSize - zds->inPos;
2128 int const isSkipFrame = ZSTD_isSkipFrame(zds);
2129 size_t loadedSize;
2130 /* At this point we shouldn't be decompressing a block that we can stream. */
2131 assert(neededInSize == ZSTD_nextSrcSizeToDecompressWithInputSize(zds, iend - ip));
2132 if (isSkipFrame) {
2133 loadedSize = MIN(toLoad, (size_t)(iend-ip));
2134 } else {
2135 RETURN_ERROR_IF(toLoad > zds->inBuffSize - zds->inPos,
2136 corruption_detected,
2137 "should never happen");
2138 loadedSize = ZSTD_limitCopy(zds->inBuff + zds->inPos, toLoad, ip, (size_t)(iend-ip));
2139 }
2140 ip += loadedSize;
2141 zds->inPos += loadedSize;
2142 if (loadedSize < toLoad) { someMoreWork = 0; break; } /* not enough input, wait for more */
2143
2144 /* decode loaded input */
2145 zds->inPos = 0; /* input is consumed */
2146 FORWARD_IF_ERROR(ZSTD_decompressContinueStream(zds, &op, oend, zds->inBuff, neededInSize), "");
2147 /* Function modifies the stage so we must break */
2148 break;
2149 }
2150 case zdss_flush:
2151 { size_t const toFlushSize = zds->outEnd - zds->outStart;
2152 size_t const flushedSize = ZSTD_limitCopy(op, (size_t)(oend-op), zds->outBuff + zds->outStart, toFlushSize);
2153 op += flushedSize;
2154 zds->outStart += flushedSize;
2155 if (flushedSize == toFlushSize) { /* flush completed */
2156 zds->streamStage = zdss_read;
2157 if ( (zds->outBuffSize < zds->fParams.frameContentSize)
2158 && (zds->outStart + zds->fParams.blockSizeMax > zds->outBuffSize) ) {
2159 DEBUGLOG(5, "restart filling outBuff from beginning (left:%i, needed:%u)",
2160 (int)(zds->outBuffSize - zds->outStart),
2161 (U32)zds->fParams.blockSizeMax);
2162 zds->outStart = zds->outEnd = 0;
2163 }
2164 break;
2165 } }
2166 /* cannot complete flush */
2167 someMoreWork = 0;
2168 break;
2169
2170 default:
2171 assert(0); /* impossible */
2172 RETURN_ERROR(GENERIC, "impossible to reach"); /* some compiler require default to do something */
2173 } }
2174
2175 /* result */
2176 input->pos = (size_t)(ip - (const char*)(input->src));
2177 output->pos = (size_t)(op - (char*)(output->dst));
2178
2179 /* Update the expected output buffer for ZSTD_obm_stable. */
2180 zds->expectedOutBuffer = *output;
2181
2182 if ((ip==istart) && (op==ostart)) { /* no forward progress */
2183 zds->noForwardProgress ++;
2184 if (zds->noForwardProgress >= ZSTD_NO_FORWARD_PROGRESS_MAX) {
2185 RETURN_ERROR_IF(op==oend, dstSize_tooSmall, "");
2186 RETURN_ERROR_IF(ip==iend, srcSize_wrong, "");
2187 assert(0);
2188 }
2189 } else {
2190 zds->noForwardProgress = 0;
2191 }
2192 { size_t nextSrcSizeHint = ZSTD_nextSrcSizeToDecompress(zds);
2193 if (!nextSrcSizeHint) { /* frame fully decoded */
2194 if (zds->outEnd == zds->outStart) { /* output fully flushed */
2195 if (zds->hostageByte) {
2196 if (input->pos >= input->size) {
2197 /* can't release hostage (not present) */
2198 zds->streamStage = zdss_read;
2199 return 1;
2200 }
2201 input->pos++; /* release hostage */
2202 } /* zds->hostageByte */
2203 return 0;
2204 } /* zds->outEnd == zds->outStart */
2205 if (!zds->hostageByte) { /* output not fully flushed; keep last byte as hostage; will be released when all output is flushed */
2206 input->pos--; /* note : pos > 0, otherwise, impossible to finish reading last block */
2207 zds->hostageByte=1;
2208 }
2209 return 1;
2210 } /* nextSrcSizeHint==0 */
2211 nextSrcSizeHint += ZSTD_blockHeaderSize * (ZSTD_nextInputType(zds) == ZSTDnit_block); /* preload header of next block */
2212 assert(zds->inPos <= nextSrcSizeHint);
2213 nextSrcSizeHint -= zds->inPos; /* part already loaded*/
2214 return nextSrcSizeHint;
2215 }
2216}
2217
2218size_t ZSTD_decompressStream_simpleArgs (
2219 ZSTD_DCtx* dctx,
2220 void* dst, size_t dstCapacity, size_t* dstPos,
2221 const void* src, size_t srcSize, size_t* srcPos)
2222{
2223 ZSTD_outBuffer output = { dst, dstCapacity, *dstPos };
2224 ZSTD_inBuffer input = { src, srcSize, *srcPos };
2225 /* ZSTD_compress_generic() will check validity of dstPos and srcPos */
2226 size_t const cErr = ZSTD_decompressStream(dctx, &output, &input);
2227 *dstPos = output.pos;
2228 *srcPos = input.pos;
2229 return cErr;
2230}
stage1/zstd/lib/decompress/zstd_decompress_block.c created+2072
......@@ -0,0 +1,2072 @@
1/*
2 * Copyright (c) Yann Collet, Facebook, Inc.
3 * All rights reserved.
4 *
5 * This source code is licensed under both the BSD-style license (found in the
6 * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7 * in the COPYING file in the root directory of this source tree).
8 * You may select, at your option, one of the above-listed licenses.
9 */
10
11/* zstd_decompress_block :
12 * this module takes care of decompressing _compressed_ block */
13
14/*-*******************************************************
15* Dependencies
16*********************************************************/
17#include "../common/zstd_deps.h" /* ZSTD_memcpy, ZSTD_memmove, ZSTD_memset */
18#include "../common/compiler.h" /* prefetch */
19#include "../common/cpu.h" /* bmi2 */
20#include "../common/mem.h" /* low level memory routines */
21#define FSE_STATIC_LINKING_ONLY
22#include "../common/fse.h"
23#define HUF_STATIC_LINKING_ONLY
24#include "../common/huf.h"
25#include "../common/zstd_internal.h"
26#include "zstd_decompress_internal.h" /* ZSTD_DCtx */
27#include "zstd_ddict.h" /* ZSTD_DDictDictContent */
28#include "zstd_decompress_block.h"
29
30/*_*******************************************************
31* Macros
32**********************************************************/
33
34/* These two optional macros force the use one way or another of the two
35 * ZSTD_decompressSequences implementations. You can't force in both directions
36 * at the same time.
37 */
38#if defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT) && \
39 defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG)
40#error "Cannot force the use of the short and the long ZSTD_decompressSequences variants!"
41#endif
42
43
44/*_*******************************************************
45* Memory operations
46**********************************************************/
47static void ZSTD_copy4(void* dst, const void* src) { ZSTD_memcpy(dst, src, 4); }
48
49
50/*-*************************************************************
51 * Block decoding
52 ***************************************************************/
53
54/*! ZSTD_getcBlockSize() :
55 * Provides the size of compressed block from block header `src` */
56size_t ZSTD_getcBlockSize(const void* src, size_t srcSize,
57 blockProperties_t* bpPtr)
58{
59 RETURN_ERROR_IF(srcSize < ZSTD_blockHeaderSize, srcSize_wrong, "");
60
61 { U32 const cBlockHeader = MEM_readLE24(src);
62 U32 const cSize = cBlockHeader >> 3;
63 bpPtr->lastBlock = cBlockHeader & 1;
64 bpPtr->blockType = (blockType_e)((cBlockHeader >> 1) & 3);
65 bpPtr->origSize = cSize; /* only useful for RLE */
66 if (bpPtr->blockType == bt_rle) return 1;
67 RETURN_ERROR_IF(bpPtr->blockType == bt_reserved, corruption_detected, "");
68 return cSize;
69 }
70}
71
72/* Allocate buffer for literals, either overlapping current dst, or split between dst and litExtraBuffer, or stored entirely within litExtraBuffer */
73static void ZSTD_allocateLiteralsBuffer(ZSTD_DCtx* dctx, void* const dst, const size_t dstCapacity, const size_t litSize,
74 const streaming_operation streaming, const size_t expectedWriteSize, const unsigned splitImmediately)
75{
76 if (streaming == not_streaming && dstCapacity > ZSTD_BLOCKSIZE_MAX + WILDCOPY_OVERLENGTH + litSize + WILDCOPY_OVERLENGTH)
77 {
78 /* room for litbuffer to fit without read faulting */
79 dctx->litBuffer = (BYTE*)dst + ZSTD_BLOCKSIZE_MAX + WILDCOPY_OVERLENGTH;
80 dctx->litBufferEnd = dctx->litBuffer + litSize;
81 dctx->litBufferLocation = ZSTD_in_dst;
82 }
83 else if (litSize > ZSTD_LITBUFFEREXTRASIZE)
84 {
85 /* won't fit in litExtraBuffer, so it will be split between end of dst and extra buffer */
86 if (splitImmediately) {
87 /* won't fit in litExtraBuffer, so it will be split between end of dst and extra buffer */
88 dctx->litBuffer = (BYTE*)dst + expectedWriteSize - litSize + ZSTD_LITBUFFEREXTRASIZE - WILDCOPY_OVERLENGTH;
89 dctx->litBufferEnd = dctx->litBuffer + litSize - ZSTD_LITBUFFEREXTRASIZE;
90 }
91 else {
92 /* initially this will be stored entirely in dst during huffman decoding, it will partially shifted to litExtraBuffer after */
93 dctx->litBuffer = (BYTE*)dst + expectedWriteSize - litSize;
94 dctx->litBufferEnd = (BYTE*)dst + expectedWriteSize;
95 }
96 dctx->litBufferLocation = ZSTD_split;
97 }
98 else
99 {
100 /* fits entirely within litExtraBuffer, so no split is necessary */
101 dctx->litBuffer = dctx->litExtraBuffer;
102 dctx->litBufferEnd = dctx->litBuffer + litSize;
103 dctx->litBufferLocation = ZSTD_not_in_dst;
104 }
105}
106
107/* Hidden declaration for fullbench */
108size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
109 const void* src, size_t srcSize,
110 void* dst, size_t dstCapacity, const streaming_operation streaming);
111/*! ZSTD_decodeLiteralsBlock() :
112 * Where it is possible to do so without being stomped by the output during decompression, the literals block will be stored
113 * in the dstBuffer. If there is room to do so, it will be stored in full in the excess dst space after where the current
114 * block will be output. Otherwise it will be stored at the end of the current dst blockspace, with a small portion being
115 * stored in dctx->litExtraBuffer to help keep it "ahead" of the current output write.
116 *
117 * @return : nb of bytes read from src (< srcSize )
118 * note : symbol not declared but exposed for fullbench */
119size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
120 const void* src, size_t srcSize, /* note : srcSize < BLOCKSIZE */
121 void* dst, size_t dstCapacity, const streaming_operation streaming)
122{
123 DEBUGLOG(5, "ZSTD_decodeLiteralsBlock");
124 RETURN_ERROR_IF(srcSize < MIN_CBLOCK_SIZE, corruption_detected, "");
125
126 { const BYTE* const istart = (const BYTE*) src;
127 symbolEncodingType_e const litEncType = (symbolEncodingType_e)(istart[0] & 3);
128
129 switch(litEncType)
130 {
131 case set_repeat:
132 DEBUGLOG(5, "set_repeat flag : re-using stats from previous compressed literals block");
133 RETURN_ERROR_IF(dctx->litEntropy==0, dictionary_corrupted, "");
134 ZSTD_FALLTHROUGH;
135
136 case set_compressed:
137 RETURN_ERROR_IF(srcSize < 5, corruption_detected, "srcSize >= MIN_CBLOCK_SIZE == 3; here we need up to 5 for case 3");
138 { size_t lhSize, litSize, litCSize;
139 U32 singleStream=0;
140 U32 const lhlCode = (istart[0] >> 2) & 3;
141 U32 const lhc = MEM_readLE32(istart);
142 size_t hufSuccess;
143 size_t expectedWriteSize = MIN(ZSTD_BLOCKSIZE_MAX, dstCapacity);
144 switch(lhlCode)
145 {
146 case 0: case 1: default: /* note : default is impossible, since lhlCode into [0..3] */
147 /* 2 - 2 - 10 - 10 */
148 singleStream = !lhlCode;
149 lhSize = 3;
150 litSize = (lhc >> 4) & 0x3FF;
151 litCSize = (lhc >> 14) & 0x3FF;
152 break;
153 case 2:
154 /* 2 - 2 - 14 - 14 */
155 lhSize = 4;
156 litSize = (lhc >> 4) & 0x3FFF;
157 litCSize = lhc >> 18;
158 break;
159 case 3:
160 /* 2 - 2 - 18 - 18 */
161 lhSize = 5;
162 litSize = (lhc >> 4) & 0x3FFFF;
163 litCSize = (lhc >> 22) + ((size_t)istart[4] << 10);
164 break;
165 }
166 RETURN_ERROR_IF(litSize > 0 && dst == NULL, dstSize_tooSmall, "NULL not handled");
167 RETURN_ERROR_IF(litSize > ZSTD_BLOCKSIZE_MAX, corruption_detected, "");
168 RETURN_ERROR_IF(litCSize + lhSize > srcSize, corruption_detected, "");
169 RETURN_ERROR_IF(expectedWriteSize < litSize , dstSize_tooSmall, "");
170 ZSTD_allocateLiteralsBuffer(dctx, dst, dstCapacity, litSize, streaming, expectedWriteSize, 0);
171
172 /* prefetch huffman table if cold */
173 if (dctx->ddictIsCold && (litSize > 768 /* heuristic */)) {
174 PREFETCH_AREA(dctx->HUFptr, sizeof(dctx->entropy.hufTable));
175 }
176
177 if (litEncType==set_repeat) {
178 if (singleStream) {
179 hufSuccess = HUF_decompress1X_usingDTable_bmi2(
180 dctx->litBuffer, litSize, istart+lhSize, litCSize,
181 dctx->HUFptr, ZSTD_DCtx_get_bmi2(dctx));
182 } else {
183 hufSuccess = HUF_decompress4X_usingDTable_bmi2(
184 dctx->litBuffer, litSize, istart+lhSize, litCSize,
185 dctx->HUFptr, ZSTD_DCtx_get_bmi2(dctx));
186 }
187 } else {
188 if (singleStream) {
189#if defined(HUF_FORCE_DECOMPRESS_X2)
190 hufSuccess = HUF_decompress1X_DCtx_wksp(
191 dctx->entropy.hufTable, dctx->litBuffer, litSize,
192 istart+lhSize, litCSize, dctx->workspace,
193 sizeof(dctx->workspace));
194#else
195 hufSuccess = HUF_decompress1X1_DCtx_wksp_bmi2(
196 dctx->entropy.hufTable, dctx->litBuffer, litSize,
197 istart+lhSize, litCSize, dctx->workspace,
198 sizeof(dctx->workspace), ZSTD_DCtx_get_bmi2(dctx));
199#endif
200 } else {
201 hufSuccess = HUF_decompress4X_hufOnly_wksp_bmi2(
202 dctx->entropy.hufTable, dctx->litBuffer, litSize,
203 istart+lhSize, litCSize, dctx->workspace,
204 sizeof(dctx->workspace), ZSTD_DCtx_get_bmi2(dctx));
205 }
206 }
207 if (dctx->litBufferLocation == ZSTD_split)
208 {
209 ZSTD_memcpy(dctx->litExtraBuffer, dctx->litBufferEnd - ZSTD_LITBUFFEREXTRASIZE, ZSTD_LITBUFFEREXTRASIZE);
210 ZSTD_memmove(dctx->litBuffer + ZSTD_LITBUFFEREXTRASIZE - WILDCOPY_OVERLENGTH, dctx->litBuffer, litSize - ZSTD_LITBUFFEREXTRASIZE);
211 dctx->litBuffer += ZSTD_LITBUFFEREXTRASIZE - WILDCOPY_OVERLENGTH;
212 dctx->litBufferEnd -= WILDCOPY_OVERLENGTH;
213 }
214
215 RETURN_ERROR_IF(HUF_isError(hufSuccess), corruption_detected, "");
216
217 dctx->litPtr = dctx->litBuffer;
218 dctx->litSize = litSize;
219 dctx->litEntropy = 1;
220 if (litEncType==set_compressed) dctx->HUFptr = dctx->entropy.hufTable;
221 return litCSize + lhSize;
222 }
223
224 case set_basic:
225 { size_t litSize, lhSize;
226 U32 const lhlCode = ((istart[0]) >> 2) & 3;
227 size_t expectedWriteSize = MIN(ZSTD_BLOCKSIZE_MAX, dstCapacity);
228 switch(lhlCode)
229 {
230 case 0: case 2: default: /* note : default is impossible, since lhlCode into [0..3] */
231 lhSize = 1;
232 litSize = istart[0] >> 3;
233 break;
234 case 1:
235 lhSize = 2;
236 litSize = MEM_readLE16(istart) >> 4;
237 break;
238 case 3:
239 lhSize = 3;
240 litSize = MEM_readLE24(istart) >> 4;
241 break;
242 }
243
244 RETURN_ERROR_IF(litSize > 0 && dst == NULL, dstSize_tooSmall, "NULL not handled");
245 RETURN_ERROR_IF(expectedWriteSize < litSize, dstSize_tooSmall, "");
246 ZSTD_allocateLiteralsBuffer(dctx, dst, dstCapacity, litSize, streaming, expectedWriteSize, 1);
247 if (lhSize+litSize+WILDCOPY_OVERLENGTH > srcSize) { /* risk reading beyond src buffer with wildcopy */
248 RETURN_ERROR_IF(litSize+lhSize > srcSize, corruption_detected, "");
249 if (dctx->litBufferLocation == ZSTD_split)
250 {
251 ZSTD_memcpy(dctx->litBuffer, istart + lhSize, litSize - ZSTD_LITBUFFEREXTRASIZE);
252 ZSTD_memcpy(dctx->litExtraBuffer, istart + lhSize + litSize - ZSTD_LITBUFFEREXTRASIZE, ZSTD_LITBUFFEREXTRASIZE);
253 }
254 else
255 {
256 ZSTD_memcpy(dctx->litBuffer, istart + lhSize, litSize);
257 }
258 dctx->litPtr = dctx->litBuffer;
259 dctx->litSize = litSize;
260 return lhSize+litSize;
261 }
262 /* direct reference into compressed stream */
263 dctx->litPtr = istart+lhSize;
264 dctx->litSize = litSize;
265 dctx->litBufferEnd = dctx->litPtr + litSize;
266 dctx->litBufferLocation = ZSTD_not_in_dst;
267 return lhSize+litSize;
268 }
269
270 case set_rle:
271 { U32 const lhlCode = ((istart[0]) >> 2) & 3;
272 size_t litSize, lhSize;
273 size_t expectedWriteSize = MIN(ZSTD_BLOCKSIZE_MAX, dstCapacity);
274 switch(lhlCode)
275 {
276 case 0: case 2: default: /* note : default is impossible, since lhlCode into [0..3] */
277 lhSize = 1;
278 litSize = istart[0] >> 3;
279 break;
280 case 1:
281 lhSize = 2;
282 litSize = MEM_readLE16(istart) >> 4;
283 break;
284 case 3:
285 lhSize = 3;
286 litSize = MEM_readLE24(istart) >> 4;
287 RETURN_ERROR_IF(srcSize<4, corruption_detected, "srcSize >= MIN_CBLOCK_SIZE == 3; here we need lhSize+1 = 4");
288 break;
289 }
290 RETURN_ERROR_IF(litSize > 0 && dst == NULL, dstSize_tooSmall, "NULL not handled");
291 RETURN_ERROR_IF(litSize > ZSTD_BLOCKSIZE_MAX, corruption_detected, "");
292 RETURN_ERROR_IF(expectedWriteSize < litSize, dstSize_tooSmall, "");
293 ZSTD_allocateLiteralsBuffer(dctx, dst, dstCapacity, litSize, streaming, expectedWriteSize, 1);
294 if (dctx->litBufferLocation == ZSTD_split)
295 {
296 ZSTD_memset(dctx->litBuffer, istart[lhSize], litSize - ZSTD_LITBUFFEREXTRASIZE);
297 ZSTD_memset(dctx->litExtraBuffer, istart[lhSize], ZSTD_LITBUFFEREXTRASIZE);
298 }
299 else
300 {
301 ZSTD_memset(dctx->litBuffer, istart[lhSize], litSize);
302 }
303 dctx->litPtr = dctx->litBuffer;
304 dctx->litSize = litSize;
305 return lhSize+1;
306 }
307 default:
308 RETURN_ERROR(corruption_detected, "impossible");
309 }
310 }
311}
312
313/* Default FSE distribution tables.
314 * These are pre-calculated FSE decoding tables using default distributions as defined in specification :
315 * https://github.com/facebook/zstd/blob/release/doc/zstd_compression_format.md#default-distributions
316 * They were generated programmatically with following method :
317 * - start from default distributions, present in /lib/common/zstd_internal.h
318 * - generate tables normally, using ZSTD_buildFSETable()
319 * - printout the content of tables
320 * - pretify output, report below, test with fuzzer to ensure it's correct */
321
322/* Default FSE distribution table for Literal Lengths */
323static const ZSTD_seqSymbol LL_defaultDTable[(1<<LL_DEFAULTNORMLOG)+1] = {
324 { 1, 1, 1, LL_DEFAULTNORMLOG}, /* header : fastMode, tableLog */
325 /* nextState, nbAddBits, nbBits, baseVal */
326 { 0, 0, 4, 0}, { 16, 0, 4, 0},
327 { 32, 0, 5, 1}, { 0, 0, 5, 3},
328 { 0, 0, 5, 4}, { 0, 0, 5, 6},
329 { 0, 0, 5, 7}, { 0, 0, 5, 9},
330 { 0, 0, 5, 10}, { 0, 0, 5, 12},
331 { 0, 0, 6, 14}, { 0, 1, 5, 16},
332 { 0, 1, 5, 20}, { 0, 1, 5, 22},
333 { 0, 2, 5, 28}, { 0, 3, 5, 32},
334 { 0, 4, 5, 48}, { 32, 6, 5, 64},
335 { 0, 7, 5, 128}, { 0, 8, 6, 256},
336 { 0, 10, 6, 1024}, { 0, 12, 6, 4096},
337 { 32, 0, 4, 0}, { 0, 0, 4, 1},
338 { 0, 0, 5, 2}, { 32, 0, 5, 4},
339 { 0, 0, 5, 5}, { 32, 0, 5, 7},
340 { 0, 0, 5, 8}, { 32, 0, 5, 10},
341 { 0, 0, 5, 11}, { 0, 0, 6, 13},
342 { 32, 1, 5, 16}, { 0, 1, 5, 18},
343 { 32, 1, 5, 22}, { 0, 2, 5, 24},
344 { 32, 3, 5, 32}, { 0, 3, 5, 40},
345 { 0, 6, 4, 64}, { 16, 6, 4, 64},
346 { 32, 7, 5, 128}, { 0, 9, 6, 512},
347 { 0, 11, 6, 2048}, { 48, 0, 4, 0},
348 { 16, 0, 4, 1}, { 32, 0, 5, 2},
349 { 32, 0, 5, 3}, { 32, 0, 5, 5},
350 { 32, 0, 5, 6}, { 32, 0, 5, 8},
351 { 32, 0, 5, 9}, { 32, 0, 5, 11},
352 { 32, 0, 5, 12}, { 0, 0, 6, 15},
353 { 32, 1, 5, 18}, { 32, 1, 5, 20},
354 { 32, 2, 5, 24}, { 32, 2, 5, 28},
355 { 32, 3, 5, 40}, { 32, 4, 5, 48},
356 { 0, 16, 6,65536}, { 0, 15, 6,32768},
357 { 0, 14, 6,16384}, { 0, 13, 6, 8192},
358}; /* LL_defaultDTable */
359
360/* Default FSE distribution table for Offset Codes */
361static const ZSTD_seqSymbol OF_defaultDTable[(1<<OF_DEFAULTNORMLOG)+1] = {
362 { 1, 1, 1, OF_DEFAULTNORMLOG}, /* header : fastMode, tableLog */
363 /* nextState, nbAddBits, nbBits, baseVal */
364 { 0, 0, 5, 0}, { 0, 6, 4, 61},
365 { 0, 9, 5, 509}, { 0, 15, 5,32765},
366 { 0, 21, 5,2097149}, { 0, 3, 5, 5},
367 { 0, 7, 4, 125}, { 0, 12, 5, 4093},
368 { 0, 18, 5,262141}, { 0, 23, 5,8388605},
369 { 0, 5, 5, 29}, { 0, 8, 4, 253},
370 { 0, 14, 5,16381}, { 0, 20, 5,1048573},
371 { 0, 2, 5, 1}, { 16, 7, 4, 125},
372 { 0, 11, 5, 2045}, { 0, 17, 5,131069},
373 { 0, 22, 5,4194301}, { 0, 4, 5, 13},
374 { 16, 8, 4, 253}, { 0, 13, 5, 8189},
375 { 0, 19, 5,524285}, { 0, 1, 5, 1},
376 { 16, 6, 4, 61}, { 0, 10, 5, 1021},
377 { 0, 16, 5,65533}, { 0, 28, 5,268435453},
378 { 0, 27, 5,134217725}, { 0, 26, 5,67108861},
379 { 0, 25, 5,33554429}, { 0, 24, 5,16777213},
380}; /* OF_defaultDTable */
381
382
383/* Default FSE distribution table for Match Lengths */
384static const ZSTD_seqSymbol ML_defaultDTable[(1<<ML_DEFAULTNORMLOG)+1] = {
385 { 1, 1, 1, ML_DEFAULTNORMLOG}, /* header : fastMode, tableLog */
386 /* nextState, nbAddBits, nbBits, baseVal */
387 { 0, 0, 6, 3}, { 0, 0, 4, 4},
388 { 32, 0, 5, 5}, { 0, 0, 5, 6},
389 { 0, 0, 5, 8}, { 0, 0, 5, 9},
390 { 0, 0, 5, 11}, { 0, 0, 6, 13},
391 { 0, 0, 6, 16}, { 0, 0, 6, 19},
392 { 0, 0, 6, 22}, { 0, 0, 6, 25},
393 { 0, 0, 6, 28}, { 0, 0, 6, 31},
394 { 0, 0, 6, 34}, { 0, 1, 6, 37},
395 { 0, 1, 6, 41}, { 0, 2, 6, 47},
396 { 0, 3, 6, 59}, { 0, 4, 6, 83},
397 { 0, 7, 6, 131}, { 0, 9, 6, 515},
398 { 16, 0, 4, 4}, { 0, 0, 4, 5},
399 { 32, 0, 5, 6}, { 0, 0, 5, 7},
400 { 32, 0, 5, 9}, { 0, 0, 5, 10},
401 { 0, 0, 6, 12}, { 0, 0, 6, 15},
402 { 0, 0, 6, 18}, { 0, 0, 6, 21},
403 { 0, 0, 6, 24}, { 0, 0, 6, 27},
404 { 0, 0, 6, 30}, { 0, 0, 6, 33},
405 { 0, 1, 6, 35}, { 0, 1, 6, 39},
406 { 0, 2, 6, 43}, { 0, 3, 6, 51},
407 { 0, 4, 6, 67}, { 0, 5, 6, 99},
408 { 0, 8, 6, 259}, { 32, 0, 4, 4},
409 { 48, 0, 4, 4}, { 16, 0, 4, 5},
410 { 32, 0, 5, 7}, { 32, 0, 5, 8},
411 { 32, 0, 5, 10}, { 32, 0, 5, 11},
412 { 0, 0, 6, 14}, { 0, 0, 6, 17},
413 { 0, 0, 6, 20}, { 0, 0, 6, 23},
414 { 0, 0, 6, 26}, { 0, 0, 6, 29},
415 { 0, 0, 6, 32}, { 0, 16, 6,65539},
416 { 0, 15, 6,32771}, { 0, 14, 6,16387},
417 { 0, 13, 6, 8195}, { 0, 12, 6, 4099},
418 { 0, 11, 6, 2051}, { 0, 10, 6, 1027},
419}; /* ML_defaultDTable */
420
421
422static void ZSTD_buildSeqTable_rle(ZSTD_seqSymbol* dt, U32 baseValue, U8 nbAddBits)
423{
424 void* ptr = dt;
425 ZSTD_seqSymbol_header* const DTableH = (ZSTD_seqSymbol_header*)ptr;
426 ZSTD_seqSymbol* const cell = dt + 1;
427
428 DTableH->tableLog = 0;
429 DTableH->fastMode = 0;
430
431 cell->nbBits = 0;
432 cell->nextState = 0;
433 assert(nbAddBits < 255);
434 cell->nbAdditionalBits = nbAddBits;
435 cell->baseValue = baseValue;
436}
437
438
439/* ZSTD_buildFSETable() :
440 * generate FSE decoding table for one symbol (ll, ml or off)
441 * cannot fail if input is valid =>
442 * all inputs are presumed validated at this stage */
443FORCE_INLINE_TEMPLATE
444void ZSTD_buildFSETable_body(ZSTD_seqSymbol* dt,
445 const short* normalizedCounter, unsigned maxSymbolValue,
446 const U32* baseValue, const U8* nbAdditionalBits,
447 unsigned tableLog, void* wksp, size_t wkspSize)
448{
449 ZSTD_seqSymbol* const tableDecode = dt+1;
450 U32 const maxSV1 = maxSymbolValue + 1;
451 U32 const tableSize = 1 << tableLog;
452
453 U16* symbolNext = (U16*)wksp;
454 BYTE* spread = (BYTE*)(symbolNext + MaxSeq + 1);
455 U32 highThreshold = tableSize - 1;
456
457
458 /* Sanity Checks */
459 assert(maxSymbolValue <= MaxSeq);
460 assert(tableLog <= MaxFSELog);
461 assert(wkspSize >= ZSTD_BUILD_FSE_TABLE_WKSP_SIZE);
462 (void)wkspSize;
463 /* Init, lay down lowprob symbols */
464 { ZSTD_seqSymbol_header DTableH;
465 DTableH.tableLog = tableLog;
466 DTableH.fastMode = 1;
467 { S16 const largeLimit= (S16)(1 << (tableLog-1));
468 U32 s;
469 for (s=0; s<maxSV1; s++) {
470 if (normalizedCounter[s]==-1) {
471 tableDecode[highThreshold--].baseValue = s;
472 symbolNext[s] = 1;
473 } else {
474 if (normalizedCounter[s] >= largeLimit) DTableH.fastMode=0;
475 assert(normalizedCounter[s]>=0);
476 symbolNext[s] = (U16)normalizedCounter[s];
477 } } }
478 ZSTD_memcpy(dt, &DTableH, sizeof(DTableH));
479 }
480
481 /* Spread symbols */
482 assert(tableSize <= 512);
483 /* Specialized symbol spreading for the case when there are
484 * no low probability (-1 count) symbols. When compressing
485 * small blocks we avoid low probability symbols to hit this
486 * case, since header decoding speed matters more.
487 */
488 if (highThreshold == tableSize - 1) {
489 size_t const tableMask = tableSize-1;
490 size_t const step = FSE_TABLESTEP(tableSize);
491 /* First lay down the symbols in order.
492 * We use a uint64_t to lay down 8 bytes at a time. This reduces branch
493 * misses since small blocks generally have small table logs, so nearly
494 * all symbols have counts <= 8. We ensure we have 8 bytes at the end of
495 * our buffer to handle the over-write.
496 */
497 {
498 U64 const add = 0x0101010101010101ull;
499 size_t pos = 0;
500 U64 sv = 0;
501 U32 s;
502 for (s=0; s<maxSV1; ++s, sv += add) {
503 int i;
504 int const n = normalizedCounter[s];
505 MEM_write64(spread + pos, sv);
506 for (i = 8; i < n; i += 8) {
507 MEM_write64(spread + pos + i, sv);
508 }
509 pos += n;
510 }
511 }
512 /* Now we spread those positions across the table.
513 * The benefit of doing it in two stages is that we avoid the the
514 * variable size inner loop, which caused lots of branch misses.
515 * Now we can run through all the positions without any branch misses.
516 * We unroll the loop twice, since that is what emperically worked best.
517 */
518 {
519 size_t position = 0;
520 size_t s;
521 size_t const unroll = 2;
522 assert(tableSize % unroll == 0); /* FSE_MIN_TABLELOG is 5 */
523 for (s = 0; s < (size_t)tableSize; s += unroll) {
524 size_t u;
525 for (u = 0; u < unroll; ++u) {
526 size_t const uPosition = (position + (u * step)) & tableMask;
527 tableDecode[uPosition].baseValue = spread[s + u];
528 }
529 position = (position + (unroll * step)) & tableMask;
530 }
531 assert(position == 0);
532 }
533 } else {
534 U32 const tableMask = tableSize-1;
535 U32 const step = FSE_TABLESTEP(tableSize);
536 U32 s, position = 0;
537 for (s=0; s<maxSV1; s++) {
538 int i;
539 int const n = normalizedCounter[s];
540 for (i=0; i<n; i++) {
541 tableDecode[position].baseValue = s;
542 position = (position + step) & tableMask;
543 while (position > highThreshold) position = (position + step) & tableMask; /* lowprob area */
544 } }
545 assert(position == 0); /* position must reach all cells once, otherwise normalizedCounter is incorrect */
546 }
547
548 /* Build Decoding table */
549 {
550 U32 u;
551 for (u=0; u<tableSize; u++) {
552 U32 const symbol = tableDecode[u].baseValue;
553 U32 const nextState = symbolNext[symbol]++;
554 tableDecode[u].nbBits = (BYTE) (tableLog - BIT_highbit32(nextState) );
555 tableDecode[u].nextState = (U16) ( (nextState << tableDecode[u].nbBits) - tableSize);
556 assert(nbAdditionalBits[symbol] < 255);
557 tableDecode[u].nbAdditionalBits = nbAdditionalBits[symbol];
558 tableDecode[u].baseValue = baseValue[symbol];
559 }
560 }
561}
562
563/* Avoids the FORCE_INLINE of the _body() function. */
564static void ZSTD_buildFSETable_body_default(ZSTD_seqSymbol* dt,
565 const short* normalizedCounter, unsigned maxSymbolValue,
566 const U32* baseValue, const U8* nbAdditionalBits,
567 unsigned tableLog, void* wksp, size_t wkspSize)
568{
569 ZSTD_buildFSETable_body(dt, normalizedCounter, maxSymbolValue,
570 baseValue, nbAdditionalBits, tableLog, wksp, wkspSize);
571}
572
573#if DYNAMIC_BMI2
574BMI2_TARGET_ATTRIBUTE static void ZSTD_buildFSETable_body_bmi2(ZSTD_seqSymbol* dt,
575 const short* normalizedCounter, unsigned maxSymbolValue,
576 const U32* baseValue, const U8* nbAdditionalBits,
577 unsigned tableLog, void* wksp, size_t wkspSize)
578{
579 ZSTD_buildFSETable_body(dt, normalizedCounter, maxSymbolValue,
580 baseValue, nbAdditionalBits, tableLog, wksp, wkspSize);
581}
582#endif
583
584void ZSTD_buildFSETable(ZSTD_seqSymbol* dt,
585 const short* normalizedCounter, unsigned maxSymbolValue,
586 const U32* baseValue, const U8* nbAdditionalBits,
587 unsigned tableLog, void* wksp, size_t wkspSize, int bmi2)
588{
589#if DYNAMIC_BMI2
590 if (bmi2) {
591 ZSTD_buildFSETable_body_bmi2(dt, normalizedCounter, maxSymbolValue,
592 baseValue, nbAdditionalBits, tableLog, wksp, wkspSize);
593 return;
594 }
595#endif
596 (void)bmi2;
597 ZSTD_buildFSETable_body_default(dt, normalizedCounter, maxSymbolValue,
598 baseValue, nbAdditionalBits, tableLog, wksp, wkspSize);
599}
600
601
602/*! ZSTD_buildSeqTable() :
603 * @return : nb bytes read from src,
604 * or an error code if it fails */
605static size_t ZSTD_buildSeqTable(ZSTD_seqSymbol* DTableSpace, const ZSTD_seqSymbol** DTablePtr,
606 symbolEncodingType_e type, unsigned max, U32 maxLog,
607 const void* src, size_t srcSize,
608 const U32* baseValue, const U8* nbAdditionalBits,
609 const ZSTD_seqSymbol* defaultTable, U32 flagRepeatTable,
610 int ddictIsCold, int nbSeq, U32* wksp, size_t wkspSize,
611 int bmi2)
612{
613 switch(type)
614 {
615 case set_rle :
616 RETURN_ERROR_IF(!srcSize, srcSize_wrong, "");
617 RETURN_ERROR_IF((*(const BYTE*)src) > max, corruption_detected, "");
618 { U32 const symbol = *(const BYTE*)src;
619 U32 const baseline = baseValue[symbol];
620 U8 const nbBits = nbAdditionalBits[symbol];
621 ZSTD_buildSeqTable_rle(DTableSpace, baseline, nbBits);
622 }
623 *DTablePtr = DTableSpace;
624 return 1;
625 case set_basic :
626 *DTablePtr = defaultTable;
627 return 0;
628 case set_repeat:
629 RETURN_ERROR_IF(!flagRepeatTable, corruption_detected, "");
630 /* prefetch FSE table if used */
631 if (ddictIsCold && (nbSeq > 24 /* heuristic */)) {
632 const void* const pStart = *DTablePtr;
633 size_t const pSize = sizeof(ZSTD_seqSymbol) * (SEQSYMBOL_TABLE_SIZE(maxLog));
634 PREFETCH_AREA(pStart, pSize);
635 }
636 return 0;
637 case set_compressed :
638 { unsigned tableLog;
639 S16 norm[MaxSeq+1];
640 size_t const headerSize = FSE_readNCount(norm, &max, &tableLog, src, srcSize);
641 RETURN_ERROR_IF(FSE_isError(headerSize), corruption_detected, "");
642 RETURN_ERROR_IF(tableLog > maxLog, corruption_detected, "");
643 ZSTD_buildFSETable(DTableSpace, norm, max, baseValue, nbAdditionalBits, tableLog, wksp, wkspSize, bmi2);
644 *DTablePtr = DTableSpace;
645 return headerSize;
646 }
647 default :
648 assert(0);
649 RETURN_ERROR(GENERIC, "impossible");
650 }
651}
652
653size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr,
654 const void* src, size_t srcSize)
655{
656 const BYTE* const istart = (const BYTE*)src;
657 const BYTE* const iend = istart + srcSize;
658 const BYTE* ip = istart;
659 int nbSeq;
660 DEBUGLOG(5, "ZSTD_decodeSeqHeaders");
661
662 /* check */
663 RETURN_ERROR_IF(srcSize < MIN_SEQUENCES_SIZE, srcSize_wrong, "");
664
665 /* SeqHead */
666 nbSeq = *ip++;
667 if (!nbSeq) {
668 *nbSeqPtr=0;
669 RETURN_ERROR_IF(srcSize != 1, srcSize_wrong, "");
670 return 1;
671 }
672 if (nbSeq > 0x7F) {
673 if (nbSeq == 0xFF) {
674 RETURN_ERROR_IF(ip+2 > iend, srcSize_wrong, "");
675 nbSeq = MEM_readLE16(ip) + LONGNBSEQ;
676 ip+=2;
677 } else {
678 RETURN_ERROR_IF(ip >= iend, srcSize_wrong, "");
679 nbSeq = ((nbSeq-0x80)<<8) + *ip++;
680 }
681 }
682 *nbSeqPtr = nbSeq;
683
684 /* FSE table descriptors */
685 RETURN_ERROR_IF(ip+1 > iend, srcSize_wrong, ""); /* minimum possible size: 1 byte for symbol encoding types */
686 { symbolEncodingType_e const LLtype = (symbolEncodingType_e)(*ip >> 6);
687 symbolEncodingType_e const OFtype = (symbolEncodingType_e)((*ip >> 4) & 3);
688 symbolEncodingType_e const MLtype = (symbolEncodingType_e)((*ip >> 2) & 3);
689 ip++;
690
691 /* Build DTables */
692 { size_t const llhSize = ZSTD_buildSeqTable(dctx->entropy.LLTable, &dctx->LLTptr,
693 LLtype, MaxLL, LLFSELog,
694 ip, iend-ip,
695 LL_base, LL_bits,
696 LL_defaultDTable, dctx->fseEntropy,
697 dctx->ddictIsCold, nbSeq,
698 dctx->workspace, sizeof(dctx->workspace),
699 ZSTD_DCtx_get_bmi2(dctx));
700 RETURN_ERROR_IF(ZSTD_isError(llhSize), corruption_detected, "ZSTD_buildSeqTable failed");
701 ip += llhSize;
702 }
703
704 { size_t const ofhSize = ZSTD_buildSeqTable(dctx->entropy.OFTable, &dctx->OFTptr,
705 OFtype, MaxOff, OffFSELog,
706 ip, iend-ip,
707 OF_base, OF_bits,
708 OF_defaultDTable, dctx->fseEntropy,
709 dctx->ddictIsCold, nbSeq,
710 dctx->workspace, sizeof(dctx->workspace),
711 ZSTD_DCtx_get_bmi2(dctx));
712 RETURN_ERROR_IF(ZSTD_isError(ofhSize), corruption_detected, "ZSTD_buildSeqTable failed");
713 ip += ofhSize;
714 }
715
716 { size_t const mlhSize = ZSTD_buildSeqTable(dctx->entropy.MLTable, &dctx->MLTptr,
717 MLtype, MaxML, MLFSELog,
718 ip, iend-ip,
719 ML_base, ML_bits,
720 ML_defaultDTable, dctx->fseEntropy,
721 dctx->ddictIsCold, nbSeq,
722 dctx->workspace, sizeof(dctx->workspace),
723 ZSTD_DCtx_get_bmi2(dctx));
724 RETURN_ERROR_IF(ZSTD_isError(mlhSize), corruption_detected, "ZSTD_buildSeqTable failed");
725 ip += mlhSize;
726 }
727 }
728
729 return ip-istart;
730}
731
732
733typedef struct {
734 size_t litLength;
735 size_t matchLength;
736 size_t offset;
737} seq_t;
738
739typedef struct {
740 size_t state;
741 const ZSTD_seqSymbol* table;
742} ZSTD_fseState;
743
744typedef struct {
745 BIT_DStream_t DStream;
746 ZSTD_fseState stateLL;
747 ZSTD_fseState stateOffb;
748 ZSTD_fseState stateML;
749 size_t prevOffset[ZSTD_REP_NUM];
750} seqState_t;
751
752/*! ZSTD_overlapCopy8() :
753 * Copies 8 bytes from ip to op and updates op and ip where ip <= op.
754 * If the offset is < 8 then the offset is spread to at least 8 bytes.
755 *
756 * Precondition: *ip <= *op
757 * Postcondition: *op - *op >= 8
758 */
759HINT_INLINE void ZSTD_overlapCopy8(BYTE** op, BYTE const** ip, size_t offset) {
760 assert(*ip <= *op);
761 if (offset < 8) {
762 /* close range match, overlap */
763 static const U32 dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 }; /* added */
764 static const int dec64table[] = { 8, 8, 8, 7, 8, 9,10,11 }; /* subtracted */
765 int const sub2 = dec64table[offset];
766 (*op)[0] = (*ip)[0];
767 (*op)[1] = (*ip)[1];
768 (*op)[2] = (*ip)[2];
769 (*op)[3] = (*ip)[3];
770 *ip += dec32table[offset];
771 ZSTD_copy4(*op+4, *ip);
772 *ip -= sub2;
773 } else {
774 ZSTD_copy8(*op, *ip);
775 }
776 *ip += 8;
777 *op += 8;
778 assert(*op - *ip >= 8);
779}
780
781/*! ZSTD_safecopy() :
782 * Specialized version of memcpy() that is allowed to READ up to WILDCOPY_OVERLENGTH past the input buffer
783 * and write up to 16 bytes past oend_w (op >= oend_w is allowed).
784 * This function is only called in the uncommon case where the sequence is near the end of the block. It
785 * should be fast for a single long sequence, but can be slow for several short sequences.
786 *
787 * @param ovtype controls the overlap detection
788 * - ZSTD_no_overlap: The source and destination are guaranteed to be at least WILDCOPY_VECLEN bytes apart.
789 * - ZSTD_overlap_src_before_dst: The src and dst may overlap and may be any distance apart.
790 * The src buffer must be before the dst buffer.
791 */
792static void ZSTD_safecopy(BYTE* op, const BYTE* const oend_w, BYTE const* ip, ptrdiff_t length, ZSTD_overlap_e ovtype) {
793 ptrdiff_t const diff = op - ip;
794 BYTE* const oend = op + length;
795
796 assert((ovtype == ZSTD_no_overlap && (diff <= -8 || diff >= 8 || op >= oend_w)) ||
797 (ovtype == ZSTD_overlap_src_before_dst && diff >= 0));
798
799 if (length < 8) {
800 /* Handle short lengths. */
801 while (op < oend) *op++ = *ip++;
802 return;
803 }
804 if (ovtype == ZSTD_overlap_src_before_dst) {
805 /* Copy 8 bytes and ensure the offset >= 8 when there can be overlap. */
806 assert(length >= 8);
807 ZSTD_overlapCopy8(&op, &ip, diff);
808 length -= 8;
809 assert(op - ip >= 8);
810 assert(op <= oend);
811 }
812
813 if (oend <= oend_w) {
814 /* No risk of overwrite. */
815 ZSTD_wildcopy(op, ip, length, ovtype);
816 return;
817 }
818 if (op <= oend_w) {
819 /* Wildcopy until we get close to the end. */
820 assert(oend > oend_w);
821 ZSTD_wildcopy(op, ip, oend_w - op, ovtype);
822 ip += oend_w - op;
823 op += oend_w - op;
824 }
825 /* Handle the leftovers. */
826 while (op < oend) *op++ = *ip++;
827}
828
829/* ZSTD_safecopyDstBeforeSrc():
830 * This version allows overlap with dst before src, or handles the non-overlap case with dst after src
831 * Kept separate from more common ZSTD_safecopy case to avoid performance impact to the safecopy common case */
832static void ZSTD_safecopyDstBeforeSrc(BYTE* op, BYTE const* ip, ptrdiff_t length) {
833 ptrdiff_t const diff = op - ip;
834 BYTE* const oend = op + length;
835
836 if (length < 8 || diff > -8) {
837 /* Handle short lengths, close overlaps, and dst not before src. */
838 while (op < oend) *op++ = *ip++;
839 return;
840 }
841
842 if (op <= oend - WILDCOPY_OVERLENGTH && diff < -WILDCOPY_VECLEN) {
843 ZSTD_wildcopy(op, ip, oend - WILDCOPY_OVERLENGTH - op, ZSTD_no_overlap);
844 ip += oend - WILDCOPY_OVERLENGTH - op;
845 op += oend - WILDCOPY_OVERLENGTH - op;
846 }
847
848 /* Handle the leftovers. */
849 while (op < oend) *op++ = *ip++;
850}
851
852/* ZSTD_execSequenceEnd():
853 * This version handles cases that are near the end of the output buffer. It requires
854 * more careful checks to make sure there is no overflow. By separating out these hard
855 * and unlikely cases, we can speed up the common cases.
856 *
857 * NOTE: This function needs to be fast for a single long sequence, but doesn't need
858 * to be optimized for many small sequences, since those fall into ZSTD_execSequence().
859 */
860FORCE_NOINLINE
861size_t ZSTD_execSequenceEnd(BYTE* op,
862 BYTE* const oend, seq_t sequence,
863 const BYTE** litPtr, const BYTE* const litLimit,
864 const BYTE* const prefixStart, const BYTE* const virtualStart, const BYTE* const dictEnd)
865{
866 BYTE* const oLitEnd = op + sequence.litLength;
867 size_t const sequenceLength = sequence.litLength + sequence.matchLength;
868 const BYTE* const iLitEnd = *litPtr + sequence.litLength;
869 const BYTE* match = oLitEnd - sequence.offset;
870 BYTE* const oend_w = oend - WILDCOPY_OVERLENGTH;
871
872 /* bounds checks : careful of address space overflow in 32-bit mode */
873 RETURN_ERROR_IF(sequenceLength > (size_t)(oend - op), dstSize_tooSmall, "last match must fit within dstBuffer");
874 RETURN_ERROR_IF(sequence.litLength > (size_t)(litLimit - *litPtr), corruption_detected, "try to read beyond literal buffer");
875 assert(op < op + sequenceLength);
876 assert(oLitEnd < op + sequenceLength);
877
878 /* copy literals */
879 ZSTD_safecopy(op, oend_w, *litPtr, sequence.litLength, ZSTD_no_overlap);
880 op = oLitEnd;
881 *litPtr = iLitEnd;
882
883 /* copy Match */
884 if (sequence.offset > (size_t)(oLitEnd - prefixStart)) {
885 /* offset beyond prefix */
886 RETURN_ERROR_IF(sequence.offset > (size_t)(oLitEnd - virtualStart), corruption_detected, "");
887 match = dictEnd - (prefixStart - match);
888 if (match + sequence.matchLength <= dictEnd) {
889 ZSTD_memmove(oLitEnd, match, sequence.matchLength);
890 return sequenceLength;
891 }
892 /* span extDict & currentPrefixSegment */
893 { size_t const length1 = dictEnd - match;
894 ZSTD_memmove(oLitEnd, match, length1);
895 op = oLitEnd + length1;
896 sequence.matchLength -= length1;
897 match = prefixStart;
898 }
899 }
900 ZSTD_safecopy(op, oend_w, match, sequence.matchLength, ZSTD_overlap_src_before_dst);
901 return sequenceLength;
902}
903
904/* ZSTD_execSequenceEndSplitLitBuffer():
905 * This version is intended to be used during instances where the litBuffer is still split. It is kept separate to avoid performance impact for the good case.
906 */
907FORCE_NOINLINE
908size_t ZSTD_execSequenceEndSplitLitBuffer(BYTE* op,
909 BYTE* const oend, const BYTE* const oend_w, seq_t sequence,
910 const BYTE** litPtr, const BYTE* const litLimit,
911 const BYTE* const prefixStart, const BYTE* const virtualStart, const BYTE* const dictEnd)
912{
913 BYTE* const oLitEnd = op + sequence.litLength;
914 size_t const sequenceLength = sequence.litLength + sequence.matchLength;
915 const BYTE* const iLitEnd = *litPtr + sequence.litLength;
916 const BYTE* match = oLitEnd - sequence.offset;
917
918
919 /* bounds checks : careful of address space overflow in 32-bit mode */
920 RETURN_ERROR_IF(sequenceLength > (size_t)(oend - op), dstSize_tooSmall, "last match must fit within dstBuffer");
921 RETURN_ERROR_IF(sequence.litLength > (size_t)(litLimit - *litPtr), corruption_detected, "try to read beyond literal buffer");
922 assert(op < op + sequenceLength);
923 assert(oLitEnd < op + sequenceLength);
924
925 /* copy literals */
926 RETURN_ERROR_IF(op > *litPtr && op < *litPtr + sequence.litLength, dstSize_tooSmall, "output should not catch up to and overwrite literal buffer");
927 ZSTD_safecopyDstBeforeSrc(op, *litPtr, sequence.litLength);
928 op = oLitEnd;
929 *litPtr = iLitEnd;
930
931 /* copy Match */
932 if (sequence.offset > (size_t)(oLitEnd - prefixStart)) {
933 /* offset beyond prefix */
934 RETURN_ERROR_IF(sequence.offset > (size_t)(oLitEnd - virtualStart), corruption_detected, "");
935 match = dictEnd - (prefixStart - match);
936 if (match + sequence.matchLength <= dictEnd) {
937 ZSTD_memmove(oLitEnd, match, sequence.matchLength);
938 return sequenceLength;
939 }
940 /* span extDict & currentPrefixSegment */
941 { size_t const length1 = dictEnd - match;
942 ZSTD_memmove(oLitEnd, match, length1);
943 op = oLitEnd + length1;
944 sequence.matchLength -= length1;
945 match = prefixStart;
946 }
947 }
948 ZSTD_safecopy(op, oend_w, match, sequence.matchLength, ZSTD_overlap_src_before_dst);
949 return sequenceLength;
950}
951
952HINT_INLINE
953size_t ZSTD_execSequence(BYTE* op,
954 BYTE* const oend, seq_t sequence,
955 const BYTE** litPtr, const BYTE* const litLimit,
956 const BYTE* const prefixStart, const BYTE* const virtualStart, const BYTE* const dictEnd)
957{
958 BYTE* const oLitEnd = op + sequence.litLength;
959 size_t const sequenceLength = sequence.litLength + sequence.matchLength;
960 BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */
961 BYTE* const oend_w = oend - WILDCOPY_OVERLENGTH; /* risk : address space underflow on oend=NULL */
962 const BYTE* const iLitEnd = *litPtr + sequence.litLength;
963 const BYTE* match = oLitEnd - sequence.offset;
964
965 assert(op != NULL /* Precondition */);
966 assert(oend_w < oend /* No underflow */);
967 /* Handle edge cases in a slow path:
968 * - Read beyond end of literals
969 * - Match end is within WILDCOPY_OVERLIMIT of oend
970 * - 32-bit mode and the match length overflows
971 */
972 if (UNLIKELY(
973 iLitEnd > litLimit ||
974 oMatchEnd > oend_w ||
975 (MEM_32bits() && (size_t)(oend - op) < sequenceLength + WILDCOPY_OVERLENGTH)))
976 return ZSTD_execSequenceEnd(op, oend, sequence, litPtr, litLimit, prefixStart, virtualStart, dictEnd);
977
978 /* Assumptions (everything else goes into ZSTD_execSequenceEnd()) */
979 assert(op <= oLitEnd /* No overflow */);
980 assert(oLitEnd < oMatchEnd /* Non-zero match & no overflow */);
981 assert(oMatchEnd <= oend /* No underflow */);
982 assert(iLitEnd <= litLimit /* Literal length is in bounds */);
983 assert(oLitEnd <= oend_w /* Can wildcopy literals */);
984 assert(oMatchEnd <= oend_w /* Can wildcopy matches */);
985
986 /* Copy Literals:
987 * Split out litLength <= 16 since it is nearly always true. +1.6% on gcc-9.
988 * We likely don't need the full 32-byte wildcopy.
989 */
990 assert(WILDCOPY_OVERLENGTH >= 16);
991 ZSTD_copy16(op, (*litPtr));
992 if (UNLIKELY(sequence.litLength > 16)) {
993 ZSTD_wildcopy(op + 16, (*litPtr) + 16, sequence.litLength - 16, ZSTD_no_overlap);
994 }
995 op = oLitEnd;
996 *litPtr = iLitEnd; /* update for next sequence */
997
998 /* Copy Match */
999 if (sequence.offset > (size_t)(oLitEnd - prefixStart)) {
1000 /* offset beyond prefix -> go into extDict */
1001 RETURN_ERROR_IF(UNLIKELY(sequence.offset > (size_t)(oLitEnd - virtualStart)), corruption_detected, "");
1002 match = dictEnd + (match - prefixStart);
1003 if (match + sequence.matchLength <= dictEnd) {
1004 ZSTD_memmove(oLitEnd, match, sequence.matchLength);
1005 return sequenceLength;
1006 }
1007 /* span extDict & currentPrefixSegment */
1008 { size_t const length1 = dictEnd - match;
1009 ZSTD_memmove(oLitEnd, match, length1);
1010 op = oLitEnd + length1;
1011 sequence.matchLength -= length1;
1012 match = prefixStart;
1013 }
1014 }
1015 /* Match within prefix of 1 or more bytes */
1016 assert(op <= oMatchEnd);
1017 assert(oMatchEnd <= oend_w);
1018 assert(match >= prefixStart);
1019 assert(sequence.matchLength >= 1);
1020
1021 /* Nearly all offsets are >= WILDCOPY_VECLEN bytes, which means we can use wildcopy
1022 * without overlap checking.
1023 */
1024 if (LIKELY(sequence.offset >= WILDCOPY_VECLEN)) {
1025 /* We bet on a full wildcopy for matches, since we expect matches to be
1026 * longer than literals (in general). In silesia, ~10% of matches are longer
1027 * than 16 bytes.
1028 */
1029 ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength, ZSTD_no_overlap);
1030 return sequenceLength;
1031 }
1032 assert(sequence.offset < WILDCOPY_VECLEN);
1033
1034 /* Copy 8 bytes and spread the offset to be >= 8. */
1035 ZSTD_overlapCopy8(&op, &match, sequence.offset);
1036
1037 /* If the match length is > 8 bytes, then continue with the wildcopy. */
1038 if (sequence.matchLength > 8) {
1039 assert(op < oMatchEnd);
1040 ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength - 8, ZSTD_overlap_src_before_dst);
1041 }
1042 return sequenceLength;
1043}
1044
1045HINT_INLINE
1046size_t ZSTD_execSequenceSplitLitBuffer(BYTE* op,
1047 BYTE* const oend, const BYTE* const oend_w, seq_t sequence,
1048 const BYTE** litPtr, const BYTE* const litLimit,
1049 const BYTE* const prefixStart, const BYTE* const virtualStart, const BYTE* const dictEnd)
1050{
1051 BYTE* const oLitEnd = op + sequence.litLength;
1052 size_t const sequenceLength = sequence.litLength + sequence.matchLength;
1053 BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */
1054 const BYTE* const iLitEnd = *litPtr + sequence.litLength;
1055 const BYTE* match = oLitEnd - sequence.offset;
1056
1057 assert(op != NULL /* Precondition */);
1058 assert(oend_w < oend /* No underflow */);
1059 /* Handle edge cases in a slow path:
1060 * - Read beyond end of literals
1061 * - Match end is within WILDCOPY_OVERLIMIT of oend
1062 * - 32-bit mode and the match length overflows
1063 */
1064 if (UNLIKELY(
1065 iLitEnd > litLimit ||
1066 oMatchEnd > oend_w ||
1067 (MEM_32bits() && (size_t)(oend - op) < sequenceLength + WILDCOPY_OVERLENGTH)))
1068 return ZSTD_execSequenceEndSplitLitBuffer(op, oend, oend_w, sequence, litPtr, litLimit, prefixStart, virtualStart, dictEnd);
1069
1070 /* Assumptions (everything else goes into ZSTD_execSequenceEnd()) */
1071 assert(op <= oLitEnd /* No overflow */);
1072 assert(oLitEnd < oMatchEnd /* Non-zero match & no overflow */);
1073 assert(oMatchEnd <= oend /* No underflow */);
1074 assert(iLitEnd <= litLimit /* Literal length is in bounds */);
1075 assert(oLitEnd <= oend_w /* Can wildcopy literals */);
1076 assert(oMatchEnd <= oend_w /* Can wildcopy matches */);
1077
1078 /* Copy Literals:
1079 * Split out litLength <= 16 since it is nearly always true. +1.6% on gcc-9.
1080 * We likely don't need the full 32-byte wildcopy.
1081 */
1082 assert(WILDCOPY_OVERLENGTH >= 16);
1083 ZSTD_copy16(op, (*litPtr));
1084 if (UNLIKELY(sequence.litLength > 16)) {
1085 ZSTD_wildcopy(op+16, (*litPtr)+16, sequence.litLength-16, ZSTD_no_overlap);
1086 }
1087 op = oLitEnd;
1088 *litPtr = iLitEnd; /* update for next sequence */
1089
1090 /* Copy Match */
1091 if (sequence.offset > (size_t)(oLitEnd - prefixStart)) {
1092 /* offset beyond prefix -> go into extDict */
1093 RETURN_ERROR_IF(UNLIKELY(sequence.offset > (size_t)(oLitEnd - virtualStart)), corruption_detected, "");
1094 match = dictEnd + (match - prefixStart);
1095 if (match + sequence.matchLength <= dictEnd) {
1096 ZSTD_memmove(oLitEnd, match, sequence.matchLength);
1097 return sequenceLength;
1098 }
1099 /* span extDict & currentPrefixSegment */
1100 { size_t const length1 = dictEnd - match;
1101 ZSTD_memmove(oLitEnd, match, length1);
1102 op = oLitEnd + length1;
1103 sequence.matchLength -= length1;
1104 match = prefixStart;
1105 } }
1106 /* Match within prefix of 1 or more bytes */
1107 assert(op <= oMatchEnd);
1108 assert(oMatchEnd <= oend_w);
1109 assert(match >= prefixStart);
1110 assert(sequence.matchLength >= 1);
1111
1112 /* Nearly all offsets are >= WILDCOPY_VECLEN bytes, which means we can use wildcopy
1113 * without overlap checking.
1114 */
1115 if (LIKELY(sequence.offset >= WILDCOPY_VECLEN)) {
1116 /* We bet on a full wildcopy for matches, since we expect matches to be
1117 * longer than literals (in general). In silesia, ~10% of matches are longer
1118 * than 16 bytes.
1119 */
1120 ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength, ZSTD_no_overlap);
1121 return sequenceLength;
1122 }
1123 assert(sequence.offset < WILDCOPY_VECLEN);
1124
1125 /* Copy 8 bytes and spread the offset to be >= 8. */
1126 ZSTD_overlapCopy8(&op, &match, sequence.offset);
1127
1128 /* If the match length is > 8 bytes, then continue with the wildcopy. */
1129 if (sequence.matchLength > 8) {
1130 assert(op < oMatchEnd);
1131 ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength-8, ZSTD_overlap_src_before_dst);
1132 }
1133 return sequenceLength;
1134}
1135
1136
1137static void
1138ZSTD_initFseState(ZSTD_fseState* DStatePtr, BIT_DStream_t* bitD, const ZSTD_seqSymbol* dt)
1139{
1140 const void* ptr = dt;
1141 const ZSTD_seqSymbol_header* const DTableH = (const ZSTD_seqSymbol_header*)ptr;
1142 DStatePtr->state = BIT_readBits(bitD, DTableH->tableLog);
1143 DEBUGLOG(6, "ZSTD_initFseState : val=%u using %u bits",
1144 (U32)DStatePtr->state, DTableH->tableLog);
1145 BIT_reloadDStream(bitD);
1146 DStatePtr->table = dt + 1;
1147}
1148
1149FORCE_INLINE_TEMPLATE void
1150ZSTD_updateFseStateWithDInfo(ZSTD_fseState* DStatePtr, BIT_DStream_t* bitD, U16 nextState, U32 nbBits)
1151{
1152 size_t const lowBits = BIT_readBits(bitD, nbBits);
1153 DStatePtr->state = nextState + lowBits;
1154}
1155
1156/* We need to add at most (ZSTD_WINDOWLOG_MAX_32 - 1) bits to read the maximum
1157 * offset bits. But we can only read at most (STREAM_ACCUMULATOR_MIN_32 - 1)
1158 * bits before reloading. This value is the maximum number of bytes we read
1159 * after reloading when we are decoding long offsets.
1160 */
1161#define LONG_OFFSETS_MAX_EXTRA_BITS_32 \
1162 (ZSTD_WINDOWLOG_MAX_32 > STREAM_ACCUMULATOR_MIN_32 \
1163 ? ZSTD_WINDOWLOG_MAX_32 - STREAM_ACCUMULATOR_MIN_32 \
1164 : 0)
1165
1166typedef enum { ZSTD_lo_isRegularOffset, ZSTD_lo_isLongOffset=1 } ZSTD_longOffset_e;
1167
1168FORCE_INLINE_TEMPLATE seq_t
1169ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets)
1170{
1171 seq_t seq;
1172 const ZSTD_seqSymbol* const llDInfo = seqState->stateLL.table + seqState->stateLL.state;
1173 const ZSTD_seqSymbol* const mlDInfo = seqState->stateML.table + seqState->stateML.state;
1174 const ZSTD_seqSymbol* const ofDInfo = seqState->stateOffb.table + seqState->stateOffb.state;
1175 seq.matchLength = mlDInfo->baseValue;
1176 seq.litLength = llDInfo->baseValue;
1177 { U32 const ofBase = ofDInfo->baseValue;
1178 BYTE const llBits = llDInfo->nbAdditionalBits;
1179 BYTE const mlBits = mlDInfo->nbAdditionalBits;
1180 BYTE const ofBits = ofDInfo->nbAdditionalBits;
1181 BYTE const totalBits = llBits+mlBits+ofBits;
1182
1183 U16 const llNext = llDInfo->nextState;
1184 U16 const mlNext = mlDInfo->nextState;
1185 U16 const ofNext = ofDInfo->nextState;
1186 U32 const llnbBits = llDInfo->nbBits;
1187 U32 const mlnbBits = mlDInfo->nbBits;
1188 U32 const ofnbBits = ofDInfo->nbBits;
1189 /*
1190 * As gcc has better branch and block analyzers, sometimes it is only
1191 * valuable to mark likelyness for clang, it gives around 3-4% of
1192 * performance.
1193 */
1194
1195 /* sequence */
1196 { size_t offset;
1197 #if defined(__clang__)
1198 if (LIKELY(ofBits > 1)) {
1199 #else
1200 if (ofBits > 1) {
1201 #endif
1202 ZSTD_STATIC_ASSERT(ZSTD_lo_isLongOffset == 1);
1203 ZSTD_STATIC_ASSERT(LONG_OFFSETS_MAX_EXTRA_BITS_32 == 5);
1204 assert(ofBits <= MaxOff);
1205 if (MEM_32bits() && longOffsets && (ofBits >= STREAM_ACCUMULATOR_MIN_32)) {
1206 U32 const extraBits = ofBits - MIN(ofBits, 32 - seqState->DStream.bitsConsumed);
1207 offset = ofBase + (BIT_readBitsFast(&seqState->DStream, ofBits - extraBits) << extraBits);
1208 BIT_reloadDStream(&seqState->DStream);
1209 if (extraBits) offset += BIT_readBitsFast(&seqState->DStream, extraBits);
1210 assert(extraBits <= LONG_OFFSETS_MAX_EXTRA_BITS_32); /* to avoid another reload */
1211 } else {
1212 offset = ofBase + BIT_readBitsFast(&seqState->DStream, ofBits/*>0*/); /* <= (ZSTD_WINDOWLOG_MAX-1) bits */
1213 if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream);
1214 }
1215 seqState->prevOffset[2] = seqState->prevOffset[1];
1216 seqState->prevOffset[1] = seqState->prevOffset[0];
1217 seqState->prevOffset[0] = offset;
1218 } else {
1219 U32 const ll0 = (llDInfo->baseValue == 0);
1220 if (LIKELY((ofBits == 0))) {
1221 offset = seqState->prevOffset[ll0];
1222 seqState->prevOffset[1] = seqState->prevOffset[!ll0];
1223 seqState->prevOffset[0] = offset;
1224 } else {
1225 offset = ofBase + ll0 + BIT_readBitsFast(&seqState->DStream, 1);
1226 { size_t temp = (offset==3) ? seqState->prevOffset[0] - 1 : seqState->prevOffset[offset];
1227 temp += !temp; /* 0 is not valid; input is corrupted; force offset to 1 */
1228 if (offset != 1) seqState->prevOffset[2] = seqState->prevOffset[1];
1229 seqState->prevOffset[1] = seqState->prevOffset[0];
1230 seqState->prevOffset[0] = offset = temp;
1231 } } }
1232 seq.offset = offset;
1233 }
1234
1235 #if defined(__clang__)
1236 if (UNLIKELY(mlBits > 0))
1237 #else
1238 if (mlBits > 0)
1239 #endif
1240 seq.matchLength += BIT_readBitsFast(&seqState->DStream, mlBits/*>0*/);
1241
1242 if (MEM_32bits() && (mlBits+llBits >= STREAM_ACCUMULATOR_MIN_32-LONG_OFFSETS_MAX_EXTRA_BITS_32))
1243 BIT_reloadDStream(&seqState->DStream);
1244 if (MEM_64bits() && UNLIKELY(totalBits >= STREAM_ACCUMULATOR_MIN_64-(LLFSELog+MLFSELog+OffFSELog)))
1245 BIT_reloadDStream(&seqState->DStream);
1246 /* Ensure there are enough bits to read the rest of data in 64-bit mode. */
1247 ZSTD_STATIC_ASSERT(16+LLFSELog+MLFSELog+OffFSELog < STREAM_ACCUMULATOR_MIN_64);
1248
1249 #if defined(__clang__)
1250 if (UNLIKELY(llBits > 0))
1251 #else
1252 if (llBits > 0)
1253 #endif
1254 seq.litLength += BIT_readBitsFast(&seqState->DStream, llBits/*>0*/);
1255
1256 if (MEM_32bits())
1257 BIT_reloadDStream(&seqState->DStream);
1258
1259 DEBUGLOG(6, "seq: litL=%u, matchL=%u, offset=%u",
1260 (U32)seq.litLength, (U32)seq.matchLength, (U32)seq.offset);
1261
1262 ZSTD_updateFseStateWithDInfo(&seqState->stateLL, &seqState->DStream, llNext, llnbBits); /* <= 9 bits */
1263 ZSTD_updateFseStateWithDInfo(&seqState->stateML, &seqState->DStream, mlNext, mlnbBits); /* <= 9 bits */
1264 if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); /* <= 18 bits */
1265 ZSTD_updateFseStateWithDInfo(&seqState->stateOffb, &seqState->DStream, ofNext, ofnbBits); /* <= 8 bits */
1266 }
1267
1268 return seq;
1269}
1270
1271#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
1272MEM_STATIC int ZSTD_dictionaryIsActive(ZSTD_DCtx const* dctx, BYTE const* prefixStart, BYTE const* oLitEnd)
1273{
1274 size_t const windowSize = dctx->fParams.windowSize;
1275 /* No dictionary used. */
1276 if (dctx->dictContentEndForFuzzing == NULL) return 0;
1277 /* Dictionary is our prefix. */
1278 if (prefixStart == dctx->dictContentBeginForFuzzing) return 1;
1279 /* Dictionary is not our ext-dict. */
1280 if (dctx->dictEnd != dctx->dictContentEndForFuzzing) return 0;
1281 /* Dictionary is not within our window size. */
1282 if ((size_t)(oLitEnd - prefixStart) >= windowSize) return 0;
1283 /* Dictionary is active. */
1284 return 1;
1285}
1286
1287MEM_STATIC void ZSTD_assertValidSequence(
1288 ZSTD_DCtx const* dctx,
1289 BYTE const* op, BYTE const* oend,
1290 seq_t const seq,
1291 BYTE const* prefixStart, BYTE const* virtualStart)
1292{
1293#if DEBUGLEVEL >= 1
1294 size_t const windowSize = dctx->fParams.windowSize;
1295 size_t const sequenceSize = seq.litLength + seq.matchLength;
1296 BYTE const* const oLitEnd = op + seq.litLength;
1297 DEBUGLOG(6, "Checking sequence: litL=%u matchL=%u offset=%u",
1298 (U32)seq.litLength, (U32)seq.matchLength, (U32)seq.offset);
1299 assert(op <= oend);
1300 assert((size_t)(oend - op) >= sequenceSize);
1301 assert(sequenceSize <= ZSTD_BLOCKSIZE_MAX);
1302 if (ZSTD_dictionaryIsActive(dctx, prefixStart, oLitEnd)) {
1303 size_t const dictSize = (size_t)((char const*)dctx->dictContentEndForFuzzing - (char const*)dctx->dictContentBeginForFuzzing);
1304 /* Offset must be within the dictionary. */
1305 assert(seq.offset <= (size_t)(oLitEnd - virtualStart));
1306 assert(seq.offset <= windowSize + dictSize);
1307 } else {
1308 /* Offset must be within our window. */
1309 assert(seq.offset <= windowSize);
1310 }
1311#else
1312 (void)dctx, (void)op, (void)oend, (void)seq, (void)prefixStart, (void)virtualStart;
1313#endif
1314}
1315#endif
1316
1317#ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG
1318
1319
1320FORCE_INLINE_TEMPLATE size_t
1321DONT_VECTORIZE
1322ZSTD_decompressSequences_bodySplitLitBuffer( ZSTD_DCtx* dctx,
1323 void* dst, size_t maxDstSize,
1324 const void* seqStart, size_t seqSize, int nbSeq,
1325 const ZSTD_longOffset_e isLongOffset,
1326 const int frame)
1327{
1328 const BYTE* ip = (const BYTE*)seqStart;
1329 const BYTE* const iend = ip + seqSize;
1330 BYTE* const ostart = (BYTE*)dst;
1331 BYTE* const oend = ostart + maxDstSize;
1332 BYTE* op = ostart;
1333 const BYTE* litPtr = dctx->litPtr;
1334 const BYTE* litBufferEnd = dctx->litBufferEnd;
1335 const BYTE* const prefixStart = (const BYTE*) (dctx->prefixStart);
1336 const BYTE* const vBase = (const BYTE*) (dctx->virtualStart);
1337 const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd);
1338 DEBUGLOG(5, "ZSTD_decompressSequences_bodySplitLitBuffer");
1339 (void)frame;
1340
1341 /* Regen sequences */
1342 if (nbSeq) {
1343 seqState_t seqState;
1344 dctx->fseEntropy = 1;
1345 { U32 i; for (i=0; i<ZSTD_REP_NUM; i++) seqState.prevOffset[i] = dctx->entropy.rep[i]; }
1346 RETURN_ERROR_IF(
1347 ERR_isError(BIT_initDStream(&seqState.DStream, ip, iend-ip)),
1348 corruption_detected, "");
1349 ZSTD_initFseState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr);
1350 ZSTD_initFseState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr);
1351 ZSTD_initFseState(&seqState.stateML, &seqState.DStream, dctx->MLTptr);
1352 assert(dst != NULL);
1353
1354 ZSTD_STATIC_ASSERT(
1355 BIT_DStream_unfinished < BIT_DStream_completed &&
1356 BIT_DStream_endOfBuffer < BIT_DStream_completed &&
1357 BIT_DStream_completed < BIT_DStream_overflow);
1358
1359 /* decompress without overrunning litPtr begins */
1360 {
1361 seq_t sequence = ZSTD_decodeSequence(&seqState, isLongOffset);
1362 /* Align the decompression loop to 32 + 16 bytes.
1363 *
1364 * zstd compiled with gcc-9 on an Intel i9-9900k shows 10% decompression
1365 * speed swings based on the alignment of the decompression loop. This
1366 * performance swing is caused by parts of the decompression loop falling
1367 * out of the DSB. The entire decompression loop should fit in the DSB,
1368 * when it can't we get much worse performance. You can measure if you've
1369 * hit the good case or the bad case with this perf command for some
1370 * compressed file test.zst:
1371 *
1372 * perf stat -e cycles -e instructions -e idq.all_dsb_cycles_any_uops \
1373 * -e idq.all_mite_cycles_any_uops -- ./zstd -tq test.zst
1374 *
1375 * If you see most cycles served out of the MITE you've hit the bad case.
1376 * If you see most cycles served out of the DSB you've hit the good case.
1377 * If it is pretty even then you may be in an okay case.
1378 *
1379 * This issue has been reproduced on the following CPUs:
1380 * - Kabylake: Macbook Pro (15-inch, 2019) 2.4 GHz Intel Core i9
1381 * Use Instruments->Counters to get DSB/MITE cycles.
1382 * I never got performance swings, but I was able to
1383 * go from the good case of mostly DSB to half of the
1384 * cycles served from MITE.
1385 * - Coffeelake: Intel i9-9900k
1386 * - Coffeelake: Intel i7-9700k
1387 *
1388 * I haven't been able to reproduce the instability or DSB misses on any
1389 * of the following CPUS:
1390 * - Haswell
1391 * - Broadwell: Intel(R) Xeon(R) CPU E5-2680 v4 @ 2.40GH
1392 * - Skylake
1393 *
1394 * Alignment is done for each of the three major decompression loops:
1395 * - ZSTD_decompressSequences_bodySplitLitBuffer - presplit section of the literal buffer
1396 * - ZSTD_decompressSequences_bodySplitLitBuffer - postsplit section of the literal buffer
1397 * - ZSTD_decompressSequences_body
1398 * Alignment choices are made to minimize large swings on bad cases and influence on performance
1399 * from changes external to this code, rather than to overoptimize on the current commit.
1400 *
1401 * If you are seeing performance stability this script can help test.
1402 * It tests on 4 commits in zstd where I saw performance change.
1403 *
1404 * https://gist.github.com/terrelln/9889fc06a423fd5ca6e99351564473f4
1405 */
1406#if defined(__GNUC__) && defined(__x86_64__)
1407 __asm__(".p2align 6");
1408# if __GNUC__ >= 7
1409 /* good for gcc-7, gcc-9, and gcc-11 */
1410 __asm__("nop");
1411 __asm__(".p2align 5");
1412 __asm__("nop");
1413 __asm__(".p2align 4");
1414# if __GNUC__ == 8 || __GNUC__ == 10
1415 /* good for gcc-8 and gcc-10 */
1416 __asm__("nop");
1417 __asm__(".p2align 3");
1418# endif
1419# endif
1420#endif
1421
1422 /* Handle the initial state where litBuffer is currently split between dst and litExtraBuffer */
1423 for (; litPtr + sequence.litLength <= dctx->litBufferEnd; ) {
1424 size_t const oneSeqSize = ZSTD_execSequenceSplitLitBuffer(op, oend, litPtr + sequence.litLength - WILDCOPY_OVERLENGTH, sequence, &litPtr, litBufferEnd, prefixStart, vBase, dictEnd);
1425#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
1426 assert(!ZSTD_isError(oneSeqSize));
1427 if (frame) ZSTD_assertValidSequence(dctx, op, oend, sequence, prefixStart, vBase);
1428#endif
1429 if (UNLIKELY(ZSTD_isError(oneSeqSize)))
1430 return oneSeqSize;
1431 DEBUGLOG(6, "regenerated sequence size : %u", (U32)oneSeqSize);
1432 op += oneSeqSize;
1433 if (UNLIKELY(!--nbSeq))
1434 break;
1435 BIT_reloadDStream(&(seqState.DStream));
1436 sequence = ZSTD_decodeSequence(&seqState, isLongOffset);
1437 }
1438
1439 /* If there are more sequences, they will need to read literals from litExtraBuffer; copy over the remainder from dst and update litPtr and litEnd */
1440 if (nbSeq > 0) {
1441 const size_t leftoverLit = dctx->litBufferEnd - litPtr;
1442 if (leftoverLit)
1443 {
1444 RETURN_ERROR_IF(leftoverLit > (size_t)(oend - op), dstSize_tooSmall, "remaining lit must fit within dstBuffer");
1445 ZSTD_safecopyDstBeforeSrc(op, litPtr, leftoverLit);
1446 sequence.litLength -= leftoverLit;
1447 op += leftoverLit;
1448 }
1449 litPtr = dctx->litExtraBuffer;
1450 litBufferEnd = dctx->litExtraBuffer + ZSTD_LITBUFFEREXTRASIZE;
1451 dctx->litBufferLocation = ZSTD_not_in_dst;
1452 {
1453 size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litBufferEnd, prefixStart, vBase, dictEnd);
1454#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
1455 assert(!ZSTD_isError(oneSeqSize));
1456 if (frame) ZSTD_assertValidSequence(dctx, op, oend, sequence, prefixStart, vBase);
1457#endif
1458 if (UNLIKELY(ZSTD_isError(oneSeqSize)))
1459 return oneSeqSize;
1460 DEBUGLOG(6, "regenerated sequence size : %u", (U32)oneSeqSize);
1461 op += oneSeqSize;
1462 if (--nbSeq)
1463 BIT_reloadDStream(&(seqState.DStream));
1464 }
1465 }
1466 }
1467
1468 if (nbSeq > 0) /* there is remaining lit from extra buffer */
1469 {
1470
1471#if defined(__GNUC__) && defined(__x86_64__)
1472 __asm__(".p2align 6");
1473 __asm__("nop");
1474# if __GNUC__ != 7
1475 /* worse for gcc-7 better for gcc-8, gcc-9, and gcc-10 and clang */
1476 __asm__(".p2align 4");
1477 __asm__("nop");
1478 __asm__(".p2align 3");
1479# elif __GNUC__ >= 11
1480 __asm__(".p2align 3");
1481# else
1482 __asm__(".p2align 5");
1483 __asm__("nop");
1484 __asm__(".p2align 3");
1485# endif
1486#endif
1487
1488 for (; ; ) {
1489 seq_t const sequence = ZSTD_decodeSequence(&seqState, isLongOffset);
1490 size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litBufferEnd, prefixStart, vBase, dictEnd);
1491#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
1492 assert(!ZSTD_isError(oneSeqSize));
1493 if (frame) ZSTD_assertValidSequence(dctx, op, oend, sequence, prefixStart, vBase);
1494#endif
1495 if (UNLIKELY(ZSTD_isError(oneSeqSize)))
1496 return oneSeqSize;
1497 DEBUGLOG(6, "regenerated sequence size : %u", (U32)oneSeqSize);
1498 op += oneSeqSize;
1499 if (UNLIKELY(!--nbSeq))
1500 break;
1501 BIT_reloadDStream(&(seqState.DStream));
1502 }
1503 }
1504
1505 /* check if reached exact end */
1506 DEBUGLOG(5, "ZSTD_decompressSequences_bodySplitLitBuffer: after decode loop, remaining nbSeq : %i", nbSeq);
1507 RETURN_ERROR_IF(nbSeq, corruption_detected, "");
1508 RETURN_ERROR_IF(BIT_reloadDStream(&seqState.DStream) < BIT_DStream_completed, corruption_detected, "");
1509 /* save reps for next block */
1510 { U32 i; for (i=0; i<ZSTD_REP_NUM; i++) dctx->entropy.rep[i] = (U32)(seqState.prevOffset[i]); }
1511 }
1512
1513 /* last literal segment */
1514 if (dctx->litBufferLocation == ZSTD_split) /* split hasn't been reached yet, first get dst then copy litExtraBuffer */
1515 {
1516 size_t const lastLLSize = litBufferEnd - litPtr;
1517 RETURN_ERROR_IF(lastLLSize > (size_t)(oend - op), dstSize_tooSmall, "");
1518 if (op != NULL) {
1519 ZSTD_memmove(op, litPtr, lastLLSize);
1520 op += lastLLSize;
1521 }
1522 litPtr = dctx->litExtraBuffer;
1523 litBufferEnd = dctx->litExtraBuffer + ZSTD_LITBUFFEREXTRASIZE;
1524 dctx->litBufferLocation = ZSTD_not_in_dst;
1525 }
1526 { size_t const lastLLSize = litBufferEnd - litPtr;
1527 RETURN_ERROR_IF(lastLLSize > (size_t)(oend-op), dstSize_tooSmall, "");
1528 if (op != NULL) {
1529 ZSTD_memcpy(op, litPtr, lastLLSize);
1530 op += lastLLSize;
1531 }
1532 }
1533
1534 return op-ostart;
1535}
1536
1537FORCE_INLINE_TEMPLATE size_t
1538DONT_VECTORIZE
1539ZSTD_decompressSequences_body(ZSTD_DCtx* dctx,
1540 void* dst, size_t maxDstSize,
1541 const void* seqStart, size_t seqSize, int nbSeq,
1542 const ZSTD_longOffset_e isLongOffset,
1543 const int frame)
1544{
1545 const BYTE* ip = (const BYTE*)seqStart;
1546 const BYTE* const iend = ip + seqSize;
1547 BYTE* const ostart = (BYTE*)dst;
1548 BYTE* const oend = dctx->litBufferLocation == ZSTD_not_in_dst ? ostart + maxDstSize : dctx->litBuffer;
1549 BYTE* op = ostart;
1550 const BYTE* litPtr = dctx->litPtr;
1551 const BYTE* const litEnd = litPtr + dctx->litSize;
1552 const BYTE* const prefixStart = (const BYTE*)(dctx->prefixStart);
1553 const BYTE* const vBase = (const BYTE*)(dctx->virtualStart);
1554 const BYTE* const dictEnd = (const BYTE*)(dctx->dictEnd);
1555 DEBUGLOG(5, "ZSTD_decompressSequences_body");
1556 (void)frame;
1557
1558 /* Regen sequences */
1559 if (nbSeq) {
1560 seqState_t seqState;
1561 dctx->fseEntropy = 1;
1562 { U32 i; for (i = 0; i < ZSTD_REP_NUM; i++) seqState.prevOffset[i] = dctx->entropy.rep[i]; }
1563 RETURN_ERROR_IF(
1564 ERR_isError(BIT_initDStream(&seqState.DStream, ip, iend - ip)),
1565 corruption_detected, "");
1566 ZSTD_initFseState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr);
1567 ZSTD_initFseState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr);
1568 ZSTD_initFseState(&seqState.stateML, &seqState.DStream, dctx->MLTptr);
1569 assert(dst != NULL);
1570
1571 ZSTD_STATIC_ASSERT(
1572 BIT_DStream_unfinished < BIT_DStream_completed &&
1573 BIT_DStream_endOfBuffer < BIT_DStream_completed &&
1574 BIT_DStream_completed < BIT_DStream_overflow);
1575
1576#if defined(__GNUC__) && defined(__x86_64__)
1577 __asm__(".p2align 6");
1578 __asm__("nop");
1579# if __GNUC__ >= 7
1580 __asm__(".p2align 5");
1581 __asm__("nop");
1582 __asm__(".p2align 3");
1583# else
1584 __asm__(".p2align 4");
1585 __asm__("nop");
1586 __asm__(".p2align 3");
1587# endif
1588#endif
1589
1590 for ( ; ; ) {
1591 seq_t const sequence = ZSTD_decodeSequence(&seqState, isLongOffset);
1592 size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litEnd, prefixStart, vBase, dictEnd);
1593#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
1594 assert(!ZSTD_isError(oneSeqSize));
1595 if (frame) ZSTD_assertValidSequence(dctx, op, oend, sequence, prefixStart, vBase);
1596#endif
1597 if (UNLIKELY(ZSTD_isError(oneSeqSize)))
1598 return oneSeqSize;
1599 DEBUGLOG(6, "regenerated sequence size : %u", (U32)oneSeqSize);
1600 op += oneSeqSize;
1601 if (UNLIKELY(!--nbSeq))
1602 break;
1603 BIT_reloadDStream(&(seqState.DStream));
1604 }
1605
1606 /* check if reached exact end */
1607 DEBUGLOG(5, "ZSTD_decompressSequences_body: after decode loop, remaining nbSeq : %i", nbSeq);
1608 RETURN_ERROR_IF(nbSeq, corruption_detected, "");
1609 RETURN_ERROR_IF(BIT_reloadDStream(&seqState.DStream) < BIT_DStream_completed, corruption_detected, "");
1610 /* save reps for next block */
1611 { U32 i; for (i=0; i<ZSTD_REP_NUM; i++) dctx->entropy.rep[i] = (U32)(seqState.prevOffset[i]); }
1612 }
1613
1614 /* last literal segment */
1615 { size_t const lastLLSize = litEnd - litPtr;
1616 RETURN_ERROR_IF(lastLLSize > (size_t)(oend-op), dstSize_tooSmall, "");
1617 if (op != NULL) {
1618 ZSTD_memcpy(op, litPtr, lastLLSize);
1619 op += lastLLSize;
1620 }
1621 }
1622
1623 return op-ostart;
1624}
1625
1626static size_t
1627ZSTD_decompressSequences_default(ZSTD_DCtx* dctx,
1628 void* dst, size_t maxDstSize,
1629 const void* seqStart, size_t seqSize, int nbSeq,
1630 const ZSTD_longOffset_e isLongOffset,
1631 const int frame)
1632{
1633 return ZSTD_decompressSequences_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
1634}
1635
1636static size_t
1637ZSTD_decompressSequencesSplitLitBuffer_default(ZSTD_DCtx* dctx,
1638 void* dst, size_t maxDstSize,
1639 const void* seqStart, size_t seqSize, int nbSeq,
1640 const ZSTD_longOffset_e isLongOffset,
1641 const int frame)
1642{
1643 return ZSTD_decompressSequences_bodySplitLitBuffer(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
1644}
1645#endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG */
1646
1647#ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT
1648
1649FORCE_INLINE_TEMPLATE size_t
1650ZSTD_prefetchMatch(size_t prefetchPos, seq_t const sequence,
1651 const BYTE* const prefixStart, const BYTE* const dictEnd)
1652{
1653 prefetchPos += sequence.litLength;
1654 { const BYTE* const matchBase = (sequence.offset > prefetchPos) ? dictEnd : prefixStart;
1655 const BYTE* const match = matchBase + prefetchPos - sequence.offset; /* note : this operation can overflow when seq.offset is really too large, which can only happen when input is corrupted.
1656 * No consequence though : memory address is only used for prefetching, not for dereferencing */
1657 PREFETCH_L1(match); PREFETCH_L1(match+CACHELINE_SIZE); /* note : it's safe to invoke PREFETCH() on any memory address, including invalid ones */
1658 }
1659 return prefetchPos + sequence.matchLength;
1660}
1661
1662/* This decoding function employs prefetching
1663 * to reduce latency impact of cache misses.
1664 * It's generally employed when block contains a significant portion of long-distance matches
1665 * or when coupled with a "cold" dictionary */
1666FORCE_INLINE_TEMPLATE size_t
1667ZSTD_decompressSequencesLong_body(
1668 ZSTD_DCtx* dctx,
1669 void* dst, size_t maxDstSize,
1670 const void* seqStart, size_t seqSize, int nbSeq,
1671 const ZSTD_longOffset_e isLongOffset,
1672 const int frame)
1673{
1674 const BYTE* ip = (const BYTE*)seqStart;
1675 const BYTE* const iend = ip + seqSize;
1676 BYTE* const ostart = (BYTE*)dst;
1677 BYTE* const oend = dctx->litBufferLocation == ZSTD_in_dst ? dctx->litBuffer : ostart + maxDstSize;
1678 BYTE* op = ostart;
1679 const BYTE* litPtr = dctx->litPtr;
1680 const BYTE* litBufferEnd = dctx->litBufferEnd;
1681 const BYTE* const prefixStart = (const BYTE*) (dctx->prefixStart);
1682 const BYTE* const dictStart = (const BYTE*) (dctx->virtualStart);
1683 const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd);
1684 (void)frame;
1685
1686 /* Regen sequences */
1687 if (nbSeq) {
1688#define STORED_SEQS 8
1689#define STORED_SEQS_MASK (STORED_SEQS-1)
1690#define ADVANCED_SEQS STORED_SEQS
1691 seq_t sequences[STORED_SEQS];
1692 int const seqAdvance = MIN(nbSeq, ADVANCED_SEQS);
1693 seqState_t seqState;
1694 int seqNb;
1695 size_t prefetchPos = (size_t)(op-prefixStart); /* track position relative to prefixStart */
1696
1697 dctx->fseEntropy = 1;
1698 { int i; for (i=0; i<ZSTD_REP_NUM; i++) seqState.prevOffset[i] = dctx->entropy.rep[i]; }
1699 assert(dst != NULL);
1700 assert(iend >= ip);
1701 RETURN_ERROR_IF(
1702 ERR_isError(BIT_initDStream(&seqState.DStream, ip, iend-ip)),
1703 corruption_detected, "");
1704 ZSTD_initFseState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr);
1705 ZSTD_initFseState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr);
1706 ZSTD_initFseState(&seqState.stateML, &seqState.DStream, dctx->MLTptr);
1707
1708 /* prepare in advance */
1709 for (seqNb=0; (BIT_reloadDStream(&seqState.DStream) <= BIT_DStream_completed) && (seqNb<seqAdvance); seqNb++) {
1710 seq_t const sequence = ZSTD_decodeSequence(&seqState, isLongOffset);
1711 prefetchPos = ZSTD_prefetchMatch(prefetchPos, sequence, prefixStart, dictEnd);
1712 sequences[seqNb] = sequence;
1713 }
1714 RETURN_ERROR_IF(seqNb<seqAdvance, corruption_detected, "");
1715
1716 /* decompress without stomping litBuffer */
1717 for (; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && (seqNb < nbSeq); seqNb++) {
1718 seq_t sequence = ZSTD_decodeSequence(&seqState, isLongOffset);
1719 size_t oneSeqSize;
1720
1721 if (dctx->litBufferLocation == ZSTD_split && litPtr + sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK].litLength > dctx->litBufferEnd)
1722 {
1723 /* lit buffer is reaching split point, empty out the first buffer and transition to litExtraBuffer */
1724 const size_t leftoverLit = dctx->litBufferEnd - litPtr;
1725 if (leftoverLit)
1726 {
1727 RETURN_ERROR_IF(leftoverLit > (size_t)(oend - op), dstSize_tooSmall, "remaining lit must fit within dstBuffer");
1728 ZSTD_safecopyDstBeforeSrc(op, litPtr, leftoverLit);
1729 sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK].litLength -= leftoverLit;
1730 op += leftoverLit;
1731 }
1732 litPtr = dctx->litExtraBuffer;
1733 litBufferEnd = dctx->litExtraBuffer + ZSTD_LITBUFFEREXTRASIZE;
1734 dctx->litBufferLocation = ZSTD_not_in_dst;
1735 oneSeqSize = ZSTD_execSequence(op, oend, sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK], &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd);
1736#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
1737 assert(!ZSTD_isError(oneSeqSize));
1738 if (frame) ZSTD_assertValidSequence(dctx, op, oend, sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK], prefixStart, dictStart);
1739#endif
1740 if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
1741
1742 prefetchPos = ZSTD_prefetchMatch(prefetchPos, sequence, prefixStart, dictEnd);
1743 sequences[seqNb & STORED_SEQS_MASK] = sequence;
1744 op += oneSeqSize;
1745 }
1746 else
1747 {
1748 /* lit buffer is either wholly contained in first or second split, or not split at all*/
1749 oneSeqSize = dctx->litBufferLocation == ZSTD_split ?
1750 ZSTD_execSequenceSplitLitBuffer(op, oend, litPtr + sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK].litLength - WILDCOPY_OVERLENGTH, sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK], &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd) :
1751 ZSTD_execSequence(op, oend, sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK], &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd);
1752#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
1753 assert(!ZSTD_isError(oneSeqSize));
1754 if (frame) ZSTD_assertValidSequence(dctx, op, oend, sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK], prefixStart, dictStart);
1755#endif
1756 if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
1757
1758 prefetchPos = ZSTD_prefetchMatch(prefetchPos, sequence, prefixStart, dictEnd);
1759 sequences[seqNb & STORED_SEQS_MASK] = sequence;
1760 op += oneSeqSize;
1761 }
1762 }
1763 RETURN_ERROR_IF(seqNb<nbSeq, corruption_detected, "");
1764
1765 /* finish queue */
1766 seqNb -= seqAdvance;
1767 for ( ; seqNb<nbSeq ; seqNb++) {
1768 seq_t *sequence = &(sequences[seqNb&STORED_SEQS_MASK]);
1769 if (dctx->litBufferLocation == ZSTD_split && litPtr + sequence->litLength > dctx->litBufferEnd)
1770 {
1771 const size_t leftoverLit = dctx->litBufferEnd - litPtr;
1772 if (leftoverLit)
1773 {
1774 RETURN_ERROR_IF(leftoverLit > (size_t)(oend - op), dstSize_tooSmall, "remaining lit must fit within dstBuffer");
1775 ZSTD_safecopyDstBeforeSrc(op, litPtr, leftoverLit);
1776 sequence->litLength -= leftoverLit;
1777 op += leftoverLit;
1778 }
1779 litPtr = dctx->litExtraBuffer;
1780 litBufferEnd = dctx->litExtraBuffer + ZSTD_LITBUFFEREXTRASIZE;
1781 dctx->litBufferLocation = ZSTD_not_in_dst;
1782 {
1783 size_t const oneSeqSize = ZSTD_execSequence(op, oend, *sequence, &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd);
1784#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
1785 assert(!ZSTD_isError(oneSeqSize));
1786 if (frame) ZSTD_assertValidSequence(dctx, op, oend, sequences[seqNb&STORED_SEQS_MASK], prefixStart, dictStart);
1787#endif
1788 if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
1789 op += oneSeqSize;
1790 }
1791 }
1792 else
1793 {
1794 size_t const oneSeqSize = dctx->litBufferLocation == ZSTD_split ?
1795 ZSTD_execSequenceSplitLitBuffer(op, oend, litPtr + sequence->litLength - WILDCOPY_OVERLENGTH, *sequence, &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd) :
1796 ZSTD_execSequence(op, oend, *sequence, &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd);
1797#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
1798 assert(!ZSTD_isError(oneSeqSize));
1799 if (frame) ZSTD_assertValidSequence(dctx, op, oend, sequences[seqNb&STORED_SEQS_MASK], prefixStart, dictStart);
1800#endif
1801 if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
1802 op += oneSeqSize;
1803 }
1804 }
1805
1806 /* save reps for next block */
1807 { U32 i; for (i=0; i<ZSTD_REP_NUM; i++) dctx->entropy.rep[i] = (U32)(seqState.prevOffset[i]); }
1808 }
1809
1810 /* last literal segment */
1811 if (dctx->litBufferLocation == ZSTD_split) /* first deplete literal buffer in dst, then copy litExtraBuffer */
1812 {
1813 size_t const lastLLSize = litBufferEnd - litPtr;
1814 RETURN_ERROR_IF(lastLLSize > (size_t)(oend - op), dstSize_tooSmall, "");
1815 if (op != NULL) {
1816 ZSTD_memmove(op, litPtr, lastLLSize);
1817 op += lastLLSize;
1818 }
1819 litPtr = dctx->litExtraBuffer;
1820 litBufferEnd = dctx->litExtraBuffer + ZSTD_LITBUFFEREXTRASIZE;
1821 }
1822 { size_t const lastLLSize = litBufferEnd - litPtr;
1823 RETURN_ERROR_IF(lastLLSize > (size_t)(oend-op), dstSize_tooSmall, "");
1824 if (op != NULL) {
1825 ZSTD_memmove(op, litPtr, lastLLSize);
1826 op += lastLLSize;
1827 }
1828 }
1829
1830 return op-ostart;
1831}
1832
1833static size_t
1834ZSTD_decompressSequencesLong_default(ZSTD_DCtx* dctx,
1835 void* dst, size_t maxDstSize,
1836 const void* seqStart, size_t seqSize, int nbSeq,
1837 const ZSTD_longOffset_e isLongOffset,
1838 const int frame)
1839{
1840 return ZSTD_decompressSequencesLong_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
1841}
1842#endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT */
1843
1844
1845
1846#if DYNAMIC_BMI2
1847
1848#ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG
1849static BMI2_TARGET_ATTRIBUTE size_t
1850DONT_VECTORIZE
1851ZSTD_decompressSequences_bmi2(ZSTD_DCtx* dctx,
1852 void* dst, size_t maxDstSize,
1853 const void* seqStart, size_t seqSize, int nbSeq,
1854 const ZSTD_longOffset_e isLongOffset,
1855 const int frame)
1856{
1857 return ZSTD_decompressSequences_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
1858}
1859static BMI2_TARGET_ATTRIBUTE size_t
1860DONT_VECTORIZE
1861ZSTD_decompressSequencesSplitLitBuffer_bmi2(ZSTD_DCtx* dctx,
1862 void* dst, size_t maxDstSize,
1863 const void* seqStart, size_t seqSize, int nbSeq,
1864 const ZSTD_longOffset_e isLongOffset,
1865 const int frame)
1866{
1867 return ZSTD_decompressSequences_bodySplitLitBuffer(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
1868}
1869#endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG */
1870
1871#ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT
1872static BMI2_TARGET_ATTRIBUTE size_t
1873ZSTD_decompressSequencesLong_bmi2(ZSTD_DCtx* dctx,
1874 void* dst, size_t maxDstSize,
1875 const void* seqStart, size_t seqSize, int nbSeq,
1876 const ZSTD_longOffset_e isLongOffset,
1877 const int frame)
1878{
1879 return ZSTD_decompressSequencesLong_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
1880}
1881#endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT */
1882
1883#endif /* DYNAMIC_BMI2 */
1884
1885typedef size_t (*ZSTD_decompressSequences_t)(
1886 ZSTD_DCtx* dctx,
1887 void* dst, size_t maxDstSize,
1888 const void* seqStart, size_t seqSize, int nbSeq,
1889 const ZSTD_longOffset_e isLongOffset,
1890 const int frame);
1891
1892#ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG
1893static size_t
1894ZSTD_decompressSequences(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize,
1895 const void* seqStart, size_t seqSize, int nbSeq,
1896 const ZSTD_longOffset_e isLongOffset,
1897 const int frame)
1898{
1899 DEBUGLOG(5, "ZSTD_decompressSequences");
1900#if DYNAMIC_BMI2
1901 if (ZSTD_DCtx_get_bmi2(dctx)) {
1902 return ZSTD_decompressSequences_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
1903 }
1904#endif
1905 return ZSTD_decompressSequences_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
1906}
1907static size_t
1908ZSTD_decompressSequencesSplitLitBuffer(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize,
1909 const void* seqStart, size_t seqSize, int nbSeq,
1910 const ZSTD_longOffset_e isLongOffset,
1911 const int frame)
1912{
1913 DEBUGLOG(5, "ZSTD_decompressSequencesSplitLitBuffer");
1914#if DYNAMIC_BMI2
1915 if (ZSTD_DCtx_get_bmi2(dctx)) {
1916 return ZSTD_decompressSequencesSplitLitBuffer_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
1917 }
1918#endif
1919 return ZSTD_decompressSequencesSplitLitBuffer_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
1920}
1921#endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG */
1922
1923
1924#ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT
1925/* ZSTD_decompressSequencesLong() :
1926 * decompression function triggered when a minimum share of offsets is considered "long",
1927 * aka out of cache.
1928 * note : "long" definition seems overloaded here, sometimes meaning "wider than bitstream register", and sometimes meaning "farther than memory cache distance".
1929 * This function will try to mitigate main memory latency through the use of prefetching */
1930static size_t
1931ZSTD_decompressSequencesLong(ZSTD_DCtx* dctx,
1932 void* dst, size_t maxDstSize,
1933 const void* seqStart, size_t seqSize, int nbSeq,
1934 const ZSTD_longOffset_e isLongOffset,
1935 const int frame)
1936{
1937 DEBUGLOG(5, "ZSTD_decompressSequencesLong");
1938#if DYNAMIC_BMI2
1939 if (ZSTD_DCtx_get_bmi2(dctx)) {
1940 return ZSTD_decompressSequencesLong_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
1941 }
1942#endif
1943 return ZSTD_decompressSequencesLong_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
1944}
1945#endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT */
1946
1947
1948
1949#if !defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT) && \
1950 !defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG)
1951/* ZSTD_getLongOffsetsShare() :
1952 * condition : offTable must be valid
1953 * @return : "share" of long offsets (arbitrarily defined as > (1<<23))
1954 * compared to maximum possible of (1<<OffFSELog) */
1955static unsigned
1956ZSTD_getLongOffsetsShare(const ZSTD_seqSymbol* offTable)
1957{
1958 const void* ptr = offTable;
1959 U32 const tableLog = ((const ZSTD_seqSymbol_header*)ptr)[0].tableLog;
1960 const ZSTD_seqSymbol* table = offTable + 1;
1961 U32 const max = 1 << tableLog;
1962 U32 u, total = 0;
1963 DEBUGLOG(5, "ZSTD_getLongOffsetsShare: (tableLog=%u)", tableLog);
1964
1965 assert(max <= (1 << OffFSELog)); /* max not too large */
1966 for (u=0; u<max; u++) {
1967 if (table[u].nbAdditionalBits > 22) total += 1;
1968 }
1969
1970 assert(tableLog <= OffFSELog);
1971 total <<= (OffFSELog - tableLog); /* scale to OffFSELog */
1972
1973 return total;
1974}
1975#endif
1976
1977size_t
1978ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
1979 void* dst, size_t dstCapacity,
1980 const void* src, size_t srcSize, const int frame, const streaming_operation streaming)
1981{ /* blockType == blockCompressed */
1982 const BYTE* ip = (const BYTE*)src;
1983 /* isLongOffset must be true if there are long offsets.
1984 * Offsets are long if they are larger than 2^STREAM_ACCUMULATOR_MIN.
1985 * We don't expect that to be the case in 64-bit mode.
1986 * In block mode, window size is not known, so we have to be conservative.
1987 * (note: but it could be evaluated from current-lowLimit)
1988 */
1989 ZSTD_longOffset_e const isLongOffset = (ZSTD_longOffset_e)(MEM_32bits() && (!frame || (dctx->fParams.windowSize > (1ULL << STREAM_ACCUMULATOR_MIN))));
1990 DEBUGLOG(5, "ZSTD_decompressBlock_internal (size : %u)", (U32)srcSize);
1991
1992 RETURN_ERROR_IF(srcSize >= ZSTD_BLOCKSIZE_MAX, srcSize_wrong, "");
1993
1994 /* Decode literals section */
1995 { size_t const litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize, dst, dstCapacity, streaming);
1996 DEBUGLOG(5, "ZSTD_decodeLiteralsBlock : %u", (U32)litCSize);
1997 if (ZSTD_isError(litCSize)) return litCSize;
1998 ip += litCSize;
1999 srcSize -= litCSize;
2000 }
2001
2002 /* Build Decoding Tables */
2003 {
2004 /* These macros control at build-time which decompressor implementation
2005 * we use. If neither is defined, we do some inspection and dispatch at
2006 * runtime.
2007 */
2008#if !defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT) && \
2009 !defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG)
2010 int usePrefetchDecoder = dctx->ddictIsCold;
2011#endif
2012 int nbSeq;
2013 size_t const seqHSize = ZSTD_decodeSeqHeaders(dctx, &nbSeq, ip, srcSize);
2014 if (ZSTD_isError(seqHSize)) return seqHSize;
2015 ip += seqHSize;
2016 srcSize -= seqHSize;
2017
2018 RETURN_ERROR_IF(dst == NULL && nbSeq > 0, dstSize_tooSmall, "NULL not handled");
2019
2020#if !defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT) && \
2021 !defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG)
2022 if ( !usePrefetchDecoder
2023 && (!frame || (dctx->fParams.windowSize > (1<<24)))
2024 && (nbSeq>ADVANCED_SEQS) ) { /* could probably use a larger nbSeq limit */
2025 U32 const shareLongOffsets = ZSTD_getLongOffsetsShare(dctx->OFTptr);
2026 U32 const minShare = MEM_64bits() ? 7 : 20; /* heuristic values, correspond to 2.73% and 7.81% */
2027 usePrefetchDecoder = (shareLongOffsets >= minShare);
2028 }
2029#endif
2030
2031 dctx->ddictIsCold = 0;
2032
2033#if !defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT) && \
2034 !defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG)
2035 if (usePrefetchDecoder)
2036#endif
2037#ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT
2038 return ZSTD_decompressSequencesLong(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset, frame);
2039#endif
2040
2041#ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG
2042 /* else */
2043 if (dctx->litBufferLocation == ZSTD_split)
2044 return ZSTD_decompressSequencesSplitLitBuffer(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset, frame);
2045 else
2046 return ZSTD_decompressSequences(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset, frame);
2047#endif
2048 }
2049}
2050
2051
2052void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst, size_t dstSize)
2053{
2054 if (dst != dctx->previousDstEnd && dstSize > 0) { /* not contiguous */
2055 dctx->dictEnd = dctx->previousDstEnd;
2056 dctx->virtualStart = (const char*)dst - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->prefixStart));
2057 dctx->prefixStart = dst;
2058 dctx->previousDstEnd = dst;
2059 }
2060}
2061
2062
2063size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx,
2064 void* dst, size_t dstCapacity,
2065 const void* src, size_t srcSize)
2066{
2067 size_t dSize;
2068 ZSTD_checkContinuity(dctx, dst, dstCapacity);
2069 dSize = ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize, /* frame */ 0, not_streaming);
2070 dctx->previousDstEnd = (char*)dst + dSize;
2071 return dSize;
2072}
stage1/zstd/lib/decompress/zstd_decompress_block.h created+68
......@@ -0,0 +1,68 @@
1/*
2 * Copyright (c) Yann Collet, Facebook, Inc.
3 * All rights reserved.
4 *
5 * This source code is licensed under both the BSD-style license (found in the
6 * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7 * in the COPYING file in the root directory of this source tree).
8 * You may select, at your option, one of the above-listed licenses.
9 */
10
11
12#ifndef ZSTD_DEC_BLOCK_H
13#define ZSTD_DEC_BLOCK_H
14
15/*-*******************************************************
16 * Dependencies
17 *********************************************************/
18#include "../common/zstd_deps.h" /* size_t */
19#include "../zstd.h" /* DCtx, and some public functions */
20#include "../common/zstd_internal.h" /* blockProperties_t, and some public functions */
21#include "zstd_decompress_internal.h" /* ZSTD_seqSymbol */
22
23
24/* === Prototypes === */
25
26/* note: prototypes already published within `zstd.h` :
27 * ZSTD_decompressBlock()
28 */
29
30/* note: prototypes already published within `zstd_internal.h` :
31 * ZSTD_getcBlockSize()
32 * ZSTD_decodeSeqHeaders()
33 */
34
35
36 /* Streaming state is used to inform allocation of the literal buffer */
37typedef enum {
38 not_streaming = 0,
39 is_streaming = 1
40} streaming_operation;
41
42/* ZSTD_decompressBlock_internal() :
43 * decompress block, starting at `src`,
44 * into destination buffer `dst`.
45 * @return : decompressed block size,
46 * or an error code (which can be tested using ZSTD_isError())
47 */
48size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
49 void* dst, size_t dstCapacity,
50 const void* src, size_t srcSize, const int frame, const streaming_operation streaming);
51
52/* ZSTD_buildFSETable() :
53 * generate FSE decoding table for one symbol (ll, ml or off)
54 * this function must be called with valid parameters only
55 * (dt is large enough, normalizedCounter distribution total is a power of 2, max is within range, etc.)
56 * in which case it cannot fail.
57 * The workspace must be 4-byte aligned and at least ZSTD_BUILD_FSE_TABLE_WKSP_SIZE bytes, which is
58 * defined in zstd_decompress_internal.h.
59 * Internal use only.
60 */
61void ZSTD_buildFSETable(ZSTD_seqSymbol* dt,
62 const short* normalizedCounter, unsigned maxSymbolValue,
63 const U32* baseValue, const U8* nbAdditionalBits,
64 unsigned tableLog, void* wksp, size_t wkspSize,
65 int bmi2);
66
67
68#endif /* ZSTD_DEC_BLOCK_H */
stage1/zstd/lib/decompress/zstd_decompress_internal.h created+236
......@@ -0,0 +1,236 @@
1/*
2 * Copyright (c) Yann Collet, Facebook, Inc.
3 * All rights reserved.
4 *
5 * This source code is licensed under both the BSD-style license (found in the
6 * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7 * in the COPYING file in the root directory of this source tree).
8 * You may select, at your option, one of the above-listed licenses.
9 */
10
11
12/* zstd_decompress_internal:
13 * objects and definitions shared within lib/decompress modules */
14
15 #ifndef ZSTD_DECOMPRESS_INTERNAL_H
16 #define ZSTD_DECOMPRESS_INTERNAL_H
17
18
19/*-*******************************************************
20 * Dependencies
21 *********************************************************/
22#include "../common/mem.h" /* BYTE, U16, U32 */
23#include "../common/zstd_internal.h" /* constants : MaxLL, MaxML, MaxOff, LLFSELog, etc. */
24
25
26
27/*-*******************************************************
28 * Constants
29 *********************************************************/
30static UNUSED_ATTR const U32 LL_base[MaxLL+1] = {
31 0, 1, 2, 3, 4, 5, 6, 7,
32 8, 9, 10, 11, 12, 13, 14, 15,
33 16, 18, 20, 22, 24, 28, 32, 40,
34 48, 64, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000,
35 0x2000, 0x4000, 0x8000, 0x10000 };
36
37static UNUSED_ATTR const U32 OF_base[MaxOff+1] = {
38 0, 1, 1, 5, 0xD, 0x1D, 0x3D, 0x7D,
39 0xFD, 0x1FD, 0x3FD, 0x7FD, 0xFFD, 0x1FFD, 0x3FFD, 0x7FFD,
40 0xFFFD, 0x1FFFD, 0x3FFFD, 0x7FFFD, 0xFFFFD, 0x1FFFFD, 0x3FFFFD, 0x7FFFFD,
41 0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD, 0x1FFFFFFD, 0x3FFFFFFD, 0x7FFFFFFD };
42
43static UNUSED_ATTR const U8 OF_bits[MaxOff+1] = {
44 0, 1, 2, 3, 4, 5, 6, 7,
45 8, 9, 10, 11, 12, 13, 14, 15,
46 16, 17, 18, 19, 20, 21, 22, 23,
47 24, 25, 26, 27, 28, 29, 30, 31 };
48
49static UNUSED_ATTR const U32 ML_base[MaxML+1] = {
50 3, 4, 5, 6, 7, 8, 9, 10,
51 11, 12, 13, 14, 15, 16, 17, 18,
52 19, 20, 21, 22, 23, 24, 25, 26,
53 27, 28, 29, 30, 31, 32, 33, 34,
54 35, 37, 39, 41, 43, 47, 51, 59,
55 67, 83, 99, 0x83, 0x103, 0x203, 0x403, 0x803,
56 0x1003, 0x2003, 0x4003, 0x8003, 0x10003 };
57
58
59/*-*******************************************************
60 * Decompression types
61 *********************************************************/
62 typedef struct {
63 U32 fastMode;
64 U32 tableLog;
65 } ZSTD_seqSymbol_header;
66
67 typedef struct {
68 U16 nextState;
69 BYTE nbAdditionalBits;
70 BYTE nbBits;
71 U32 baseValue;
72 } ZSTD_seqSymbol;
73
74 #define SEQSYMBOL_TABLE_SIZE(log) (1 + (1 << (log)))
75
76#define ZSTD_BUILD_FSE_TABLE_WKSP_SIZE (sizeof(S16) * (MaxSeq + 1) + (1u << MaxFSELog) + sizeof(U64))
77#define ZSTD_BUILD_FSE_TABLE_WKSP_SIZE_U32 ((ZSTD_BUILD_FSE_TABLE_WKSP_SIZE + sizeof(U32) - 1) / sizeof(U32))
78
79typedef struct {
80 ZSTD_seqSymbol LLTable[SEQSYMBOL_TABLE_SIZE(LLFSELog)]; /* Note : Space reserved for FSE Tables */
81 ZSTD_seqSymbol OFTable[SEQSYMBOL_TABLE_SIZE(OffFSELog)]; /* is also used as temporary workspace while building hufTable during DDict creation */
82 ZSTD_seqSymbol MLTable[SEQSYMBOL_TABLE_SIZE(MLFSELog)]; /* and therefore must be at least HUF_DECOMPRESS_WORKSPACE_SIZE large */
83 HUF_DTable hufTable[HUF_DTABLE_SIZE(HufLog)]; /* can accommodate HUF_decompress4X */
84 U32 rep[ZSTD_REP_NUM];
85 U32 workspace[ZSTD_BUILD_FSE_TABLE_WKSP_SIZE_U32];
86} ZSTD_entropyDTables_t;
87
88typedef enum { ZSTDds_getFrameHeaderSize, ZSTDds_decodeFrameHeader,
89 ZSTDds_decodeBlockHeader, ZSTDds_decompressBlock,
90 ZSTDds_decompressLastBlock, ZSTDds_checkChecksum,
91 ZSTDds_decodeSkippableHeader, ZSTDds_skipFrame } ZSTD_dStage;
92
93typedef enum { zdss_init=0, zdss_loadHeader,
94 zdss_read, zdss_load, zdss_flush } ZSTD_dStreamStage;
95
96typedef enum {
97 ZSTD_use_indefinitely = -1, /* Use the dictionary indefinitely */
98 ZSTD_dont_use = 0, /* Do not use the dictionary (if one exists free it) */
99 ZSTD_use_once = 1 /* Use the dictionary once and set to ZSTD_dont_use */
100} ZSTD_dictUses_e;
101
102/* Hashset for storing references to multiple ZSTD_DDict within ZSTD_DCtx */
103typedef struct {
104 const ZSTD_DDict** ddictPtrTable;
105 size_t ddictPtrTableSize;
106 size_t ddictPtrCount;
107} ZSTD_DDictHashSet;
108
109#ifndef ZSTD_DECODER_INTERNAL_BUFFER
110# define ZSTD_DECODER_INTERNAL_BUFFER (1 << 16)
111#endif
112
113#define ZSTD_LBMIN 64
114#define ZSTD_LBMAX (128 << 10)
115
116/* extra buffer, compensates when dst is not large enough to store litBuffer */
117#define ZSTD_LITBUFFEREXTRASIZE BOUNDED(ZSTD_LBMIN, ZSTD_DECODER_INTERNAL_BUFFER, ZSTD_LBMAX)
118
119typedef enum {
120 ZSTD_not_in_dst = 0, /* Stored entirely within litExtraBuffer */
121 ZSTD_in_dst = 1, /* Stored entirely within dst (in memory after current output write) */
122 ZSTD_split = 2 /* Split between litExtraBuffer and dst */
123} ZSTD_litLocation_e;
124
125struct ZSTD_DCtx_s
126{
127 const ZSTD_seqSymbol* LLTptr;
128 const ZSTD_seqSymbol* MLTptr;
129 const ZSTD_seqSymbol* OFTptr;
130 const HUF_DTable* HUFptr;
131 ZSTD_entropyDTables_t entropy;
132 U32 workspace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32]; /* space needed when building huffman tables */
133 const void* previousDstEnd; /* detect continuity */
134 const void* prefixStart; /* start of current segment */
135 const void* virtualStart; /* virtual start of previous segment if it was just before current one */
136 const void* dictEnd; /* end of previous segment */
137 size_t expected;
138 ZSTD_frameHeader fParams;
139 U64 processedCSize;
140 U64 decodedSize;
141 blockType_e bType; /* used in ZSTD_decompressContinue(), store blockType between block header decoding and block decompression stages */
142 ZSTD_dStage stage;
143 U32 litEntropy;
144 U32 fseEntropy;
145 XXH64_state_t xxhState;
146 size_t headerSize;
147 ZSTD_format_e format;
148 ZSTD_forceIgnoreChecksum_e forceIgnoreChecksum; /* User specified: if == 1, will ignore checksums in compressed frame. Default == 0 */
149 U32 validateChecksum; /* if == 1, will validate checksum. Is == 1 if (fParams.checksumFlag == 1) and (forceIgnoreChecksum == 0). */
150 const BYTE* litPtr;
151 ZSTD_customMem customMem;
152 size_t litSize;
153 size_t rleSize;
154 size_t staticSize;
155#if DYNAMIC_BMI2 != 0
156 int bmi2; /* == 1 if the CPU supports BMI2 and 0 otherwise. CPU support is determined dynamically once per context lifetime. */
157#endif
158
159 /* dictionary */
160 ZSTD_DDict* ddictLocal;
161 const ZSTD_DDict* ddict; /* set by ZSTD_initDStream_usingDDict(), or ZSTD_DCtx_refDDict() */
162 U32 dictID;
163 int ddictIsCold; /* if == 1 : dictionary is "new" for working context, and presumed "cold" (not in cpu cache) */
164 ZSTD_dictUses_e dictUses;
165 ZSTD_DDictHashSet* ddictSet; /* Hash set for multiple ddicts */
166 ZSTD_refMultipleDDicts_e refMultipleDDicts; /* User specified: if == 1, will allow references to multiple DDicts. Default == 0 (disabled) */
167
168 /* streaming */
169 ZSTD_dStreamStage streamStage;
170 char* inBuff;
171 size_t inBuffSize;
172 size_t inPos;
173 size_t maxWindowSize;
174 char* outBuff;
175 size_t outBuffSize;
176 size_t outStart;
177 size_t outEnd;
178 size_t lhSize;
179#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1)
180 void* legacyContext;
181 U32 previousLegacyVersion;
182 U32 legacyVersion;
183#endif
184 U32 hostageByte;
185 int noForwardProgress;
186 ZSTD_bufferMode_e outBufferMode;
187 ZSTD_outBuffer expectedOutBuffer;
188
189 /* workspace */
190 BYTE* litBuffer;
191 const BYTE* litBufferEnd;
192 ZSTD_litLocation_e litBufferLocation;
193 BYTE litExtraBuffer[ZSTD_LITBUFFEREXTRASIZE + WILDCOPY_OVERLENGTH]; /* literal buffer can be split between storage within dst and within this scratch buffer */
194 BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX];
195
196 size_t oversizedDuration;
197
198#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
199 void const* dictContentBeginForFuzzing;
200 void const* dictContentEndForFuzzing;
201#endif
202
203 /* Tracing */
204#if ZSTD_TRACE
205 ZSTD_TraceCtx traceCtx;
206#endif
207}; /* typedef'd to ZSTD_DCtx within "zstd.h" */
208
209MEM_STATIC int ZSTD_DCtx_get_bmi2(const struct ZSTD_DCtx_s *dctx) {
210#if DYNAMIC_BMI2 != 0
211 return dctx->bmi2;
212#else
213 (void)dctx;
214 return 0;
215#endif
216}
217
218/*-*******************************************************
219 * Shared internal functions
220 *********************************************************/
221
222/*! ZSTD_loadDEntropy() :
223 * dict : must point at beginning of a valid zstd dictionary.
224 * @return : size of dictionary header (size of magic number + dict ID + entropy tables) */
225size_t ZSTD_loadDEntropy(ZSTD_entropyDTables_t* entropy,
226 const void* const dict, size_t const dictSize);
227
228/*! ZSTD_checkContinuity() :
229 * check if next `dst` follows previous position, where decompression ended.
230 * If yes, do nothing (continue on current segment).
231 * If not, classify previous segment as "external dictionary", and start a new segment.
232 * This function cannot fail. */
233void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst, size_t dstSize);
234
235
236#endif /* ZSTD_DECOMPRESS_INTERNAL_H */
stage1/zstd/lib/zstd.h created+2575
......@@ -0,0 +1,2575 @@
1/*
2 * Copyright (c) Yann Collet, Facebook, Inc.
3 * All rights reserved.
4 *
5 * This source code is licensed under both the BSD-style license (found in the
6 * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7 * in the COPYING file in the root directory of this source tree).
8 * You may select, at your option, one of the above-listed licenses.
9 */
10#if defined (__cplusplus)
11extern "C" {
12#endif
13
14#ifndef ZSTD_H_235446
15#define ZSTD_H_235446
16
17/* ====== Dependency ======*/
18#include <limits.h> /* INT_MAX */
19#include <stddef.h> /* size_t */
20
21
22/* ===== ZSTDLIB_API : control library symbols visibility ===== */
23#ifndef ZSTDLIB_VISIBLE
24# if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(__MINGW32__)
25# define ZSTDLIB_VISIBLE __attribute__ ((visibility ("default")))
26# define ZSTDLIB_HIDDEN __attribute__ ((visibility ("hidden")))
27# else
28# define ZSTDLIB_VISIBLE
29# define ZSTDLIB_HIDDEN
30# endif
31#endif
32#if defined(ZSTD_DLL_EXPORT) && (ZSTD_DLL_EXPORT==1)
33# define ZSTDLIB_API __declspec(dllexport) ZSTDLIB_VISIBLE
34#elif defined(ZSTD_DLL_IMPORT) && (ZSTD_DLL_IMPORT==1)
35# define ZSTDLIB_API __declspec(dllimport) ZSTDLIB_VISIBLE /* It isn't required but allows to generate better code, saving a function pointer load from the IAT and an indirect jump.*/
36#else
37# define ZSTDLIB_API ZSTDLIB_VISIBLE
38#endif
39
40
41/*******************************************************************************
42 Introduction
43
44 zstd, short for Zstandard, is a fast lossless compression algorithm, targeting
45 real-time compression scenarios at zlib-level and better compression ratios.
46 The zstd compression library provides in-memory compression and decompression
47 functions.
48
49 The library supports regular compression levels from 1 up to ZSTD_maxCLevel(),
50 which is currently 22. Levels >= 20, labeled `--ultra`, should be used with
51 caution, as they require more memory. The library also offers negative
52 compression levels, which extend the range of speed vs. ratio preferences.
53 The lower the level, the faster the speed (at the cost of compression).
54
55 Compression can be done in:
56 - a single step (described as Simple API)
57 - a single step, reusing a context (described as Explicit context)
58 - unbounded multiple steps (described as Streaming compression)
59
60 The compression ratio achievable on small data can be highly improved using
61 a dictionary. Dictionary compression can be performed in:
62 - a single step (described as Simple dictionary API)
63 - a single step, reusing a dictionary (described as Bulk-processing
64 dictionary API)
65
66 Advanced experimental functions can be accessed using
67 `#define ZSTD_STATIC_LINKING_ONLY` before including zstd.h.
68
69 Advanced experimental APIs should never be used with a dynamically-linked
70 library. They are not "stable"; their definitions or signatures may change in
71 the future. Only static linking is allowed.
72*******************************************************************************/
73
74/*------ Version ------*/
75#define ZSTD_VERSION_MAJOR 1
76#define ZSTD_VERSION_MINOR 5
77#define ZSTD_VERSION_RELEASE 2
78#define ZSTD_VERSION_NUMBER (ZSTD_VERSION_MAJOR *100*100 + ZSTD_VERSION_MINOR *100 + ZSTD_VERSION_RELEASE)
79
80/*! ZSTD_versionNumber() :
81 * Return runtime library version, the value is (MAJOR*100*100 + MINOR*100 + RELEASE). */
82ZSTDLIB_API unsigned ZSTD_versionNumber(void);
83
84#define ZSTD_LIB_VERSION ZSTD_VERSION_MAJOR.ZSTD_VERSION_MINOR.ZSTD_VERSION_RELEASE
85#define ZSTD_QUOTE(str) #str
86#define ZSTD_EXPAND_AND_QUOTE(str) ZSTD_QUOTE(str)
87#define ZSTD_VERSION_STRING ZSTD_EXPAND_AND_QUOTE(ZSTD_LIB_VERSION)
88
89/*! ZSTD_versionString() :
90 * Return runtime library version, like "1.4.5". Requires v1.3.0+. */
91ZSTDLIB_API const char* ZSTD_versionString(void);
92
93/* *************************************
94 * Default constant
95 ***************************************/
96#ifndef ZSTD_CLEVEL_DEFAULT
97# define ZSTD_CLEVEL_DEFAULT 3
98#endif
99
100/* *************************************
101 * Constants
102 ***************************************/
103
104/* All magic numbers are supposed read/written to/from files/memory using little-endian convention */
105#define ZSTD_MAGICNUMBER 0xFD2FB528 /* valid since v0.8.0 */
106#define ZSTD_MAGIC_DICTIONARY 0xEC30A437 /* valid since v0.7.0 */
107#define ZSTD_MAGIC_SKIPPABLE_START 0x184D2A50 /* all 16 values, from 0x184D2A50 to 0x184D2A5F, signal the beginning of a skippable frame */
108#define ZSTD_MAGIC_SKIPPABLE_MASK 0xFFFFFFF0
109
110#define ZSTD_BLOCKSIZELOG_MAX 17
111#define ZSTD_BLOCKSIZE_MAX (1<<ZSTD_BLOCKSIZELOG_MAX)
112
113
114/***************************************
115* Simple API
116***************************************/
117/*! ZSTD_compress() :
118 * Compresses `src` content as a single zstd compressed frame into already allocated `dst`.
119 * Hint : compression runs faster if `dstCapacity` >= `ZSTD_compressBound(srcSize)`.
120 * @return : compressed size written into `dst` (<= `dstCapacity),
121 * or an error code if it fails (which can be tested using ZSTD_isError()). */
122ZSTDLIB_API size_t ZSTD_compress( void* dst, size_t dstCapacity,
123 const void* src, size_t srcSize,
124 int compressionLevel);
125
126/*! ZSTD_decompress() :
127 * `compressedSize` : must be the _exact_ size of some number of compressed and/or skippable frames.
128 * `dstCapacity` is an upper bound of originalSize to regenerate.
129 * If user cannot imply a maximum upper bound, it's better to use streaming mode to decompress data.
130 * @return : the number of bytes decompressed into `dst` (<= `dstCapacity`),
131 * or an errorCode if it fails (which can be tested using ZSTD_isError()). */
132ZSTDLIB_API size_t ZSTD_decompress( void* dst, size_t dstCapacity,
133 const void* src, size_t compressedSize);
134
135/*! ZSTD_getFrameContentSize() : requires v1.3.0+
136 * `src` should point to the start of a ZSTD encoded frame.
137 * `srcSize` must be at least as large as the frame header.
138 * hint : any size >= `ZSTD_frameHeaderSize_max` is large enough.
139 * @return : - decompressed size of `src` frame content, if known
140 * - ZSTD_CONTENTSIZE_UNKNOWN if the size cannot be determined
141 * - ZSTD_CONTENTSIZE_ERROR if an error occurred (e.g. invalid magic number, srcSize too small)
142 * note 1 : a 0 return value means the frame is valid but "empty".
143 * note 2 : decompressed size is an optional field, it may not be present, typically in streaming mode.
144 * When `return==ZSTD_CONTENTSIZE_UNKNOWN`, data to decompress could be any size.
145 * In which case, it's necessary to use streaming mode to decompress data.
146 * Optionally, application can rely on some implicit limit,
147 * as ZSTD_decompress() only needs an upper bound of decompressed size.
148 * (For example, data could be necessarily cut into blocks <= 16 KB).
149 * note 3 : decompressed size is always present when compression is completed using single-pass functions,
150 * such as ZSTD_compress(), ZSTD_compressCCtx() ZSTD_compress_usingDict() or ZSTD_compress_usingCDict().
151 * note 4 : decompressed size can be very large (64-bits value),
152 * potentially larger than what local system can handle as a single memory segment.
153 * In which case, it's necessary to use streaming mode to decompress data.
154 * note 5 : If source is untrusted, decompressed size could be wrong or intentionally modified.
155 * Always ensure return value fits within application's authorized limits.
156 * Each application can set its own limits.
157 * note 6 : This function replaces ZSTD_getDecompressedSize() */
158#define ZSTD_CONTENTSIZE_UNKNOWN (0ULL - 1)
159#define ZSTD_CONTENTSIZE_ERROR (0ULL - 2)
160ZSTDLIB_API unsigned long long ZSTD_getFrameContentSize(const void *src, size_t srcSize);
161
162/*! ZSTD_getDecompressedSize() :
163 * NOTE: This function is now obsolete, in favor of ZSTD_getFrameContentSize().
164 * Both functions work the same way, but ZSTD_getDecompressedSize() blends
165 * "empty", "unknown" and "error" results to the same return value (0),
166 * while ZSTD_getFrameContentSize() gives them separate return values.
167 * @return : decompressed size of `src` frame content _if known and not empty_, 0 otherwise. */
168ZSTDLIB_API unsigned long long ZSTD_getDecompressedSize(const void* src, size_t srcSize);
169
170/*! ZSTD_findFrameCompressedSize() : Requires v1.4.0+
171 * `src` should point to the start of a ZSTD frame or skippable frame.
172 * `srcSize` must be >= first frame size
173 * @return : the compressed size of the first frame starting at `src`,
174 * suitable to pass as `srcSize` to `ZSTD_decompress` or similar,
175 * or an error code if input is invalid */
176ZSTDLIB_API size_t ZSTD_findFrameCompressedSize(const void* src, size_t srcSize);
177
178
179/*====== Helper functions ======*/
180#define ZSTD_COMPRESSBOUND(srcSize) ((srcSize) + ((srcSize)>>8) + (((srcSize) < (128<<10)) ? (((128<<10) - (srcSize)) >> 11) /* margin, from 64 to 0 */ : 0)) /* this formula ensures that bound(A) + bound(B) <= bound(A+B) as long as A and B >= 128 KB */
181ZSTDLIB_API size_t ZSTD_compressBound(size_t srcSize); /*!< maximum compressed size in worst case single-pass scenario */
182ZSTDLIB_API unsigned ZSTD_isError(size_t code); /*!< tells if a `size_t` function result is an error code */
183ZSTDLIB_API const char* ZSTD_getErrorName(size_t code); /*!< provides readable string from an error code */
184ZSTDLIB_API int ZSTD_minCLevel(void); /*!< minimum negative compression level allowed, requires v1.4.0+ */
185ZSTDLIB_API int ZSTD_maxCLevel(void); /*!< maximum compression level available */
186ZSTDLIB_API int ZSTD_defaultCLevel(void); /*!< default compression level, specified by ZSTD_CLEVEL_DEFAULT, requires v1.5.0+ */
187
188
189/***************************************
190* Explicit context
191***************************************/
192/*= Compression context
193 * When compressing many times,
194 * it is recommended to allocate a context just once,
195 * and re-use it for each successive compression operation.
196 * This will make workload friendlier for system's memory.
197 * Note : re-using context is just a speed / resource optimization.
198 * It doesn't change the compression ratio, which remains identical.
199 * Note 2 : In multi-threaded environments,
200 * use one different context per thread for parallel execution.
201 */
202typedef struct ZSTD_CCtx_s ZSTD_CCtx;
203ZSTDLIB_API ZSTD_CCtx* ZSTD_createCCtx(void);
204ZSTDLIB_API size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx); /* accept NULL pointer */
205
206/*! ZSTD_compressCCtx() :
207 * Same as ZSTD_compress(), using an explicit ZSTD_CCtx.
208 * Important : in order to behave similarly to `ZSTD_compress()`,
209 * this function compresses at requested compression level,
210 * __ignoring any other parameter__ .
211 * If any advanced parameter was set using the advanced API,
212 * they will all be reset. Only `compressionLevel` remains.
213 */
214ZSTDLIB_API size_t ZSTD_compressCCtx(ZSTD_CCtx* cctx,
215 void* dst, size_t dstCapacity,
216 const void* src, size_t srcSize,
217 int compressionLevel);
218
219/*= Decompression context
220 * When decompressing many times,
221 * it is recommended to allocate a context only once,
222 * and re-use it for each successive compression operation.
223 * This will make workload friendlier for system's memory.
224 * Use one context per thread for parallel execution. */
225typedef struct ZSTD_DCtx_s ZSTD_DCtx;
226ZSTDLIB_API ZSTD_DCtx* ZSTD_createDCtx(void);
227ZSTDLIB_API size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx); /* accept NULL pointer */
228
229/*! ZSTD_decompressDCtx() :
230 * Same as ZSTD_decompress(),
231 * requires an allocated ZSTD_DCtx.
232 * Compatible with sticky parameters.
233 */
234ZSTDLIB_API size_t ZSTD_decompressDCtx(ZSTD_DCtx* dctx,
235 void* dst, size_t dstCapacity,
236 const void* src, size_t srcSize);
237
238
239/*********************************************
240* Advanced compression API (Requires v1.4.0+)
241**********************************************/
242
243/* API design :
244 * Parameters are pushed one by one into an existing context,
245 * using ZSTD_CCtx_set*() functions.
246 * Pushed parameters are sticky : they are valid for next compressed frame, and any subsequent frame.
247 * "sticky" parameters are applicable to `ZSTD_compress2()` and `ZSTD_compressStream*()` !
248 * __They do not apply to "simple" one-shot variants such as ZSTD_compressCCtx()__ .
249 *
250 * It's possible to reset all parameters to "default" using ZSTD_CCtx_reset().
251 *
252 * This API supersedes all other "advanced" API entry points in the experimental section.
253 * In the future, we expect to remove from experimental API entry points which are redundant with this API.
254 */
255
256
257/* Compression strategies, listed from fastest to strongest */
258typedef enum { ZSTD_fast=1,
259 ZSTD_dfast=2,
260 ZSTD_greedy=3,
261 ZSTD_lazy=4,
262 ZSTD_lazy2=5,
263 ZSTD_btlazy2=6,
264 ZSTD_btopt=7,
265 ZSTD_btultra=8,
266 ZSTD_btultra2=9
267 /* note : new strategies _might_ be added in the future.
268 Only the order (from fast to strong) is guaranteed */
269} ZSTD_strategy;
270
271typedef enum {
272
273 /* compression parameters
274 * Note: When compressing with a ZSTD_CDict these parameters are superseded
275 * by the parameters used to construct the ZSTD_CDict.
276 * See ZSTD_CCtx_refCDict() for more info (superseded-by-cdict). */
277 ZSTD_c_compressionLevel=100, /* Set compression parameters according to pre-defined cLevel table.
278 * Note that exact compression parameters are dynamically determined,
279 * depending on both compression level and srcSize (when known).
280 * Default level is ZSTD_CLEVEL_DEFAULT==3.
281 * Special: value 0 means default, which is controlled by ZSTD_CLEVEL_DEFAULT.
282 * Note 1 : it's possible to pass a negative compression level.
283 * Note 2 : setting a level does not automatically set all other compression parameters
284 * to default. Setting this will however eventually dynamically impact the compression
285 * parameters which have not been manually set. The manually set
286 * ones will 'stick'. */
287 /* Advanced compression parameters :
288 * It's possible to pin down compression parameters to some specific values.
289 * In which case, these values are no longer dynamically selected by the compressor */
290 ZSTD_c_windowLog=101, /* Maximum allowed back-reference distance, expressed as power of 2.
291 * This will set a memory budget for streaming decompression,
292 * with larger values requiring more memory
293 * and typically compressing more.
294 * Must be clamped between ZSTD_WINDOWLOG_MIN and ZSTD_WINDOWLOG_MAX.
295 * Special: value 0 means "use default windowLog".
296 * Note: Using a windowLog greater than ZSTD_WINDOWLOG_LIMIT_DEFAULT
297 * requires explicitly allowing such size at streaming decompression stage. */
298 ZSTD_c_hashLog=102, /* Size of the initial probe table, as a power of 2.
299 * Resulting memory usage is (1 << (hashLog+2)).
300 * Must be clamped between ZSTD_HASHLOG_MIN and ZSTD_HASHLOG_MAX.
301 * Larger tables improve compression ratio of strategies <= dFast,
302 * and improve speed of strategies > dFast.
303 * Special: value 0 means "use default hashLog". */
304 ZSTD_c_chainLog=103, /* Size of the multi-probe search table, as a power of 2.
305 * Resulting memory usage is (1 << (chainLog+2)).
306 * Must be clamped between ZSTD_CHAINLOG_MIN and ZSTD_CHAINLOG_MAX.
307 * Larger tables result in better and slower compression.
308 * This parameter is useless for "fast" strategy.
309 * It's still useful when using "dfast" strategy,
310 * in which case it defines a secondary probe table.
311 * Special: value 0 means "use default chainLog". */
312 ZSTD_c_searchLog=104, /* Number of search attempts, as a power of 2.
313 * More attempts result in better and slower compression.
314 * This parameter is useless for "fast" and "dFast" strategies.
315 * Special: value 0 means "use default searchLog". */
316 ZSTD_c_minMatch=105, /* Minimum size of searched matches.
317 * Note that Zstandard can still find matches of smaller size,
318 * it just tweaks its search algorithm to look for this size and larger.
319 * Larger values increase compression and decompression speed, but decrease ratio.
320 * Must be clamped between ZSTD_MINMATCH_MIN and ZSTD_MINMATCH_MAX.
321 * Note that currently, for all strategies < btopt, effective minimum is 4.
322 * , for all strategies > fast, effective maximum is 6.
323 * Special: value 0 means "use default minMatchLength". */
324 ZSTD_c_targetLength=106, /* Impact of this field depends on strategy.
325 * For strategies btopt, btultra & btultra2:
326 * Length of Match considered "good enough" to stop search.
327 * Larger values make compression stronger, and slower.
328 * For strategy fast:
329 * Distance between match sampling.
330 * Larger values make compression faster, and weaker.
331 * Special: value 0 means "use default targetLength". */
332 ZSTD_c_strategy=107, /* See ZSTD_strategy enum definition.
333 * The higher the value of selected strategy, the more complex it is,
334 * resulting in stronger and slower compression.
335 * Special: value 0 means "use default strategy". */
336 /* LDM mode parameters */
337 ZSTD_c_enableLongDistanceMatching=160, /* Enable long distance matching.
338 * This parameter is designed to improve compression ratio
339 * for large inputs, by finding large matches at long distance.
340 * It increases memory usage and window size.
341 * Note: enabling this parameter increases default ZSTD_c_windowLog to 128 MB
342 * except when expressly set to a different value.
343 * Note: will be enabled by default if ZSTD_c_windowLog >= 128 MB and
344 * compression strategy >= ZSTD_btopt (== compression level 16+) */
345 ZSTD_c_ldmHashLog=161, /* Size of the table for long distance matching, as a power of 2.
346 * Larger values increase memory usage and compression ratio,
347 * but decrease compression speed.
348 * Must be clamped between ZSTD_HASHLOG_MIN and ZSTD_HASHLOG_MAX
349 * default: windowlog - 7.
350 * Special: value 0 means "automatically determine hashlog". */
351 ZSTD_c_ldmMinMatch=162, /* Minimum match size for long distance matcher.
352 * Larger/too small values usually decrease compression ratio.
353 * Must be clamped between ZSTD_LDM_MINMATCH_MIN and ZSTD_LDM_MINMATCH_MAX.
354 * Special: value 0 means "use default value" (default: 64). */
355 ZSTD_c_ldmBucketSizeLog=163, /* Log size of each bucket in the LDM hash table for collision resolution.
356 * Larger values improve collision resolution but decrease compression speed.
357 * The maximum value is ZSTD_LDM_BUCKETSIZELOG_MAX.
358 * Special: value 0 means "use default value" (default: 3). */
359 ZSTD_c_ldmHashRateLog=164, /* Frequency of inserting/looking up entries into the LDM hash table.
360 * Must be clamped between 0 and (ZSTD_WINDOWLOG_MAX - ZSTD_HASHLOG_MIN).
361 * Default is MAX(0, (windowLog - ldmHashLog)), optimizing hash table usage.
362 * Larger values improve compression speed.
363 * Deviating far from default value will likely result in a compression ratio decrease.
364 * Special: value 0 means "automatically determine hashRateLog". */
365
366 /* frame parameters */
367 ZSTD_c_contentSizeFlag=200, /* Content size will be written into frame header _whenever known_ (default:1)
368 * Content size must be known at the beginning of compression.
369 * This is automatically the case when using ZSTD_compress2(),
370 * For streaming scenarios, content size must be provided with ZSTD_CCtx_setPledgedSrcSize() */
371 ZSTD_c_checksumFlag=201, /* A 32-bits checksum of content is written at end of frame (default:0) */
372 ZSTD_c_dictIDFlag=202, /* When applicable, dictionary's ID is written into frame header (default:1) */
373
374 /* multi-threading parameters */
375 /* These parameters are only active if multi-threading is enabled (compiled with build macro ZSTD_MULTITHREAD).
376 * Otherwise, trying to set any other value than default (0) will be a no-op and return an error.
377 * In a situation where it's unknown if the linked library supports multi-threading or not,
378 * setting ZSTD_c_nbWorkers to any value >= 1 and consulting the return value provides a quick way to check this property.
379 */
380 ZSTD_c_nbWorkers=400, /* Select how many threads will be spawned to compress in parallel.
381 * When nbWorkers >= 1, triggers asynchronous mode when invoking ZSTD_compressStream*() :
382 * ZSTD_compressStream*() consumes input and flush output if possible, but immediately gives back control to caller,
383 * while compression is performed in parallel, within worker thread(s).
384 * (note : a strong exception to this rule is when first invocation of ZSTD_compressStream2() sets ZSTD_e_end :
385 * in which case, ZSTD_compressStream2() delegates to ZSTD_compress2(), which is always a blocking call).
386 * More workers improve speed, but also increase memory usage.
387 * Default value is `0`, aka "single-threaded mode" : no worker is spawned,
388 * compression is performed inside Caller's thread, and all invocations are blocking */
389 ZSTD_c_jobSize=401, /* Size of a compression job. This value is enforced only when nbWorkers >= 1.
390 * Each compression job is completed in parallel, so this value can indirectly impact the nb of active threads.
391 * 0 means default, which is dynamically determined based on compression parameters.
392 * Job size must be a minimum of overlap size, or ZSTDMT_JOBSIZE_MIN (= 512 KB), whichever is largest.
393 * The minimum size is automatically and transparently enforced. */
394 ZSTD_c_overlapLog=402, /* Control the overlap size, as a fraction of window size.
395 * The overlap size is an amount of data reloaded from previous job at the beginning of a new job.
396 * It helps preserve compression ratio, while each job is compressed in parallel.
397 * This value is enforced only when nbWorkers >= 1.
398 * Larger values increase compression ratio, but decrease speed.
399 * Possible values range from 0 to 9 :
400 * - 0 means "default" : value will be determined by the library, depending on strategy
401 * - 1 means "no overlap"
402 * - 9 means "full overlap", using a full window size.
403 * Each intermediate rank increases/decreases load size by a factor 2 :
404 * 9: full window; 8: w/2; 7: w/4; 6: w/8; 5:w/16; 4: w/32; 3:w/64; 2:w/128; 1:no overlap; 0:default
405 * default value varies between 6 and 9, depending on strategy */
406
407 /* note : additional experimental parameters are also available
408 * within the experimental section of the API.
409 * At the time of this writing, they include :
410 * ZSTD_c_rsyncable
411 * ZSTD_c_format
412 * ZSTD_c_forceMaxWindow
413 * ZSTD_c_forceAttachDict
414 * ZSTD_c_literalCompressionMode
415 * ZSTD_c_targetCBlockSize
416 * ZSTD_c_srcSizeHint
417 * ZSTD_c_enableDedicatedDictSearch
418 * ZSTD_c_stableInBuffer
419 * ZSTD_c_stableOutBuffer
420 * ZSTD_c_blockDelimiters
421 * ZSTD_c_validateSequences
422 * ZSTD_c_useBlockSplitter
423 * ZSTD_c_useRowMatchFinder
424 * Because they are not stable, it's necessary to define ZSTD_STATIC_LINKING_ONLY to access them.
425 * note : never ever use experimentalParam? names directly;
426 * also, the enums values themselves are unstable and can still change.
427 */
428 ZSTD_c_experimentalParam1=500,
429 ZSTD_c_experimentalParam2=10,
430 ZSTD_c_experimentalParam3=1000,
431 ZSTD_c_experimentalParam4=1001,
432 ZSTD_c_experimentalParam5=1002,
433 ZSTD_c_experimentalParam6=1003,
434 ZSTD_c_experimentalParam7=1004,
435 ZSTD_c_experimentalParam8=1005,
436 ZSTD_c_experimentalParam9=1006,
437 ZSTD_c_experimentalParam10=1007,
438 ZSTD_c_experimentalParam11=1008,
439 ZSTD_c_experimentalParam12=1009,
440 ZSTD_c_experimentalParam13=1010,
441 ZSTD_c_experimentalParam14=1011,
442 ZSTD_c_experimentalParam15=1012
443} ZSTD_cParameter;
444
445typedef struct {
446 size_t error;
447 int lowerBound;
448 int upperBound;
449} ZSTD_bounds;
450
451/*! ZSTD_cParam_getBounds() :
452 * All parameters must belong to an interval with lower and upper bounds,
453 * otherwise they will either trigger an error or be automatically clamped.
454 * @return : a structure, ZSTD_bounds, which contains
455 * - an error status field, which must be tested using ZSTD_isError()
456 * - lower and upper bounds, both inclusive
457 */
458ZSTDLIB_API ZSTD_bounds ZSTD_cParam_getBounds(ZSTD_cParameter cParam);
459
460/*! ZSTD_CCtx_setParameter() :
461 * Set one compression parameter, selected by enum ZSTD_cParameter.
462 * All parameters have valid bounds. Bounds can be queried using ZSTD_cParam_getBounds().
463 * Providing a value beyond bound will either clamp it, or trigger an error (depending on parameter).
464 * Setting a parameter is generally only possible during frame initialization (before starting compression).
465 * Exception : when using multi-threading mode (nbWorkers >= 1),
466 * the following parameters can be updated _during_ compression (within same frame):
467 * => compressionLevel, hashLog, chainLog, searchLog, minMatch, targetLength and strategy.
468 * new parameters will be active for next job only (after a flush()).
469 * @return : an error code (which can be tested using ZSTD_isError()).
470 */
471ZSTDLIB_API size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, int value);
472
473/*! ZSTD_CCtx_setPledgedSrcSize() :
474 * Total input data size to be compressed as a single frame.
475 * Value will be written in frame header, unless if explicitly forbidden using ZSTD_c_contentSizeFlag.
476 * This value will also be controlled at end of frame, and trigger an error if not respected.
477 * @result : 0, or an error code (which can be tested with ZSTD_isError()).
478 * Note 1 : pledgedSrcSize==0 actually means zero, aka an empty frame.
479 * In order to mean "unknown content size", pass constant ZSTD_CONTENTSIZE_UNKNOWN.
480 * ZSTD_CONTENTSIZE_UNKNOWN is default value for any new frame.
481 * Note 2 : pledgedSrcSize is only valid once, for the next frame.
482 * It's discarded at the end of the frame, and replaced by ZSTD_CONTENTSIZE_UNKNOWN.
483 * Note 3 : Whenever all input data is provided and consumed in a single round,
484 * for example with ZSTD_compress2(),
485 * or invoking immediately ZSTD_compressStream2(,,,ZSTD_e_end),
486 * this value is automatically overridden by srcSize instead.
487 */
488ZSTDLIB_API size_t ZSTD_CCtx_setPledgedSrcSize(ZSTD_CCtx* cctx, unsigned long long pledgedSrcSize);
489
490typedef enum {
491 ZSTD_reset_session_only = 1,
492 ZSTD_reset_parameters = 2,
493 ZSTD_reset_session_and_parameters = 3
494} ZSTD_ResetDirective;
495
496/*! ZSTD_CCtx_reset() :
497 * There are 2 different things that can be reset, independently or jointly :
498 * - The session : will stop compressing current frame, and make CCtx ready to start a new one.
499 * Useful after an error, or to interrupt any ongoing compression.
500 * Any internal data not yet flushed is cancelled.
501 * Compression parameters and dictionary remain unchanged.
502 * They will be used to compress next frame.
503 * Resetting session never fails.
504 * - The parameters : changes all parameters back to "default".
505 * This removes any reference to any dictionary too.
506 * Parameters can only be changed between 2 sessions (i.e. no compression is currently ongoing)
507 * otherwise the reset fails, and function returns an error value (which can be tested using ZSTD_isError())
508 * - Both : similar to resetting the session, followed by resetting parameters.
509 */
510ZSTDLIB_API size_t ZSTD_CCtx_reset(ZSTD_CCtx* cctx, ZSTD_ResetDirective reset);
511
512/*! ZSTD_compress2() :
513 * Behave the same as ZSTD_compressCCtx(), but compression parameters are set using the advanced API.
514 * ZSTD_compress2() always starts a new frame.
515 * Should cctx hold data from a previously unfinished frame, everything about it is forgotten.
516 * - Compression parameters are pushed into CCtx before starting compression, using ZSTD_CCtx_set*()
517 * - The function is always blocking, returns when compression is completed.
518 * Hint : compression runs faster if `dstCapacity` >= `ZSTD_compressBound(srcSize)`.
519 * @return : compressed size written into `dst` (<= `dstCapacity),
520 * or an error code if it fails (which can be tested using ZSTD_isError()).
521 */
522ZSTDLIB_API size_t ZSTD_compress2( ZSTD_CCtx* cctx,
523 void* dst, size_t dstCapacity,
524 const void* src, size_t srcSize);
525
526
527/***********************************************
528* Advanced decompression API (Requires v1.4.0+)
529************************************************/
530
531/* The advanced API pushes parameters one by one into an existing DCtx context.
532 * Parameters are sticky, and remain valid for all following frames
533 * using the same DCtx context.
534 * It's possible to reset parameters to default values using ZSTD_DCtx_reset().
535 * Note : This API is compatible with existing ZSTD_decompressDCtx() and ZSTD_decompressStream().
536 * Therefore, no new decompression function is necessary.
537 */
538
539typedef enum {
540
541 ZSTD_d_windowLogMax=100, /* Select a size limit (in power of 2) beyond which
542 * the streaming API will refuse to allocate memory buffer
543 * in order to protect the host from unreasonable memory requirements.
544 * This parameter is only useful in streaming mode, since no internal buffer is allocated in single-pass mode.
545 * By default, a decompression context accepts window sizes <= (1 << ZSTD_WINDOWLOG_LIMIT_DEFAULT).
546 * Special: value 0 means "use default maximum windowLog". */
547
548 /* note : additional experimental parameters are also available
549 * within the experimental section of the API.
550 * At the time of this writing, they include :
551 * ZSTD_d_format
552 * ZSTD_d_stableOutBuffer
553 * ZSTD_d_forceIgnoreChecksum
554 * ZSTD_d_refMultipleDDicts
555 * Because they are not stable, it's necessary to define ZSTD_STATIC_LINKING_ONLY to access them.
556 * note : never ever use experimentalParam? names directly
557 */
558 ZSTD_d_experimentalParam1=1000,
559 ZSTD_d_experimentalParam2=1001,
560 ZSTD_d_experimentalParam3=1002,
561 ZSTD_d_experimentalParam4=1003
562
563} ZSTD_dParameter;
564
565/*! ZSTD_dParam_getBounds() :
566 * All parameters must belong to an interval with lower and upper bounds,
567 * otherwise they will either trigger an error or be automatically clamped.
568 * @return : a structure, ZSTD_bounds, which contains
569 * - an error status field, which must be tested using ZSTD_isError()
570 * - both lower and upper bounds, inclusive
571 */
572ZSTDLIB_API ZSTD_bounds ZSTD_dParam_getBounds(ZSTD_dParameter dParam);
573
574/*! ZSTD_DCtx_setParameter() :
575 * Set one compression parameter, selected by enum ZSTD_dParameter.
576 * All parameters have valid bounds. Bounds can be queried using ZSTD_dParam_getBounds().
577 * Providing a value beyond bound will either clamp it, or trigger an error (depending on parameter).
578 * Setting a parameter is only possible during frame initialization (before starting decompression).
579 * @return : 0, or an error code (which can be tested using ZSTD_isError()).
580 */
581ZSTDLIB_API size_t ZSTD_DCtx_setParameter(ZSTD_DCtx* dctx, ZSTD_dParameter param, int value);
582
583/*! ZSTD_DCtx_reset() :
584 * Return a DCtx to clean state.
585 * Session and parameters can be reset jointly or separately.
586 * Parameters can only be reset when no active frame is being decompressed.
587 * @return : 0, or an error code, which can be tested with ZSTD_isError()
588 */
589ZSTDLIB_API size_t ZSTD_DCtx_reset(ZSTD_DCtx* dctx, ZSTD_ResetDirective reset);
590
591
592/****************************
593* Streaming
594****************************/
595
596typedef struct ZSTD_inBuffer_s {
597 const void* src; /**< start of input buffer */
598 size_t size; /**< size of input buffer */
599 size_t pos; /**< position where reading stopped. Will be updated. Necessarily 0 <= pos <= size */
600} ZSTD_inBuffer;
601
602typedef struct ZSTD_outBuffer_s {
603 void* dst; /**< start of output buffer */
604 size_t size; /**< size of output buffer */
605 size_t pos; /**< position where writing stopped. Will be updated. Necessarily 0 <= pos <= size */
606} ZSTD_outBuffer;
607
608
609
610/*-***********************************************************************
611* Streaming compression - HowTo
612*
613* A ZSTD_CStream object is required to track streaming operation.
614* Use ZSTD_createCStream() and ZSTD_freeCStream() to create/release resources.
615* ZSTD_CStream objects can be reused multiple times on consecutive compression operations.
616* It is recommended to re-use ZSTD_CStream since it will play nicer with system's memory, by re-using already allocated memory.
617*
618* For parallel execution, use one separate ZSTD_CStream per thread.
619*
620* note : since v1.3.0, ZSTD_CStream and ZSTD_CCtx are the same thing.
621*
622* Parameters are sticky : when starting a new compression on the same context,
623* it will re-use the same sticky parameters as previous compression session.
624* When in doubt, it's recommended to fully initialize the context before usage.
625* Use ZSTD_CCtx_reset() to reset the context and ZSTD_CCtx_setParameter(),
626* ZSTD_CCtx_setPledgedSrcSize(), or ZSTD_CCtx_loadDictionary() and friends to
627* set more specific parameters, the pledged source size, or load a dictionary.
628*
629* Use ZSTD_compressStream2() with ZSTD_e_continue as many times as necessary to
630* consume input stream. The function will automatically update both `pos`
631* fields within `input` and `output`.
632* Note that the function may not consume the entire input, for example, because
633* the output buffer is already full, in which case `input.pos < input.size`.
634* The caller must check if input has been entirely consumed.
635* If not, the caller must make some room to receive more compressed data,
636* and then present again remaining input data.
637* note: ZSTD_e_continue is guaranteed to make some forward progress when called,
638* but doesn't guarantee maximal forward progress. This is especially relevant
639* when compressing with multiple threads. The call won't block if it can
640* consume some input, but if it can't it will wait for some, but not all,
641* output to be flushed.
642* @return : provides a minimum amount of data remaining to be flushed from internal buffers
643* or an error code, which can be tested using ZSTD_isError().
644*
645* At any moment, it's possible to flush whatever data might remain stuck within internal buffer,
646* using ZSTD_compressStream2() with ZSTD_e_flush. `output->pos` will be updated.
647* Note that, if `output->size` is too small, a single invocation with ZSTD_e_flush might not be enough (return code > 0).
648* In which case, make some room to receive more compressed data, and call again ZSTD_compressStream2() with ZSTD_e_flush.
649* You must continue calling ZSTD_compressStream2() with ZSTD_e_flush until it returns 0, at which point you can change the
650* operation.
651* note: ZSTD_e_flush will flush as much output as possible, meaning when compressing with multiple threads, it will
652* block until the flush is complete or the output buffer is full.
653* @return : 0 if internal buffers are entirely flushed,
654* >0 if some data still present within internal buffer (the value is minimal estimation of remaining size),
655* or an error code, which can be tested using ZSTD_isError().
656*
657* Calling ZSTD_compressStream2() with ZSTD_e_end instructs to finish a frame.
658* It will perform a flush and write frame epilogue.
659* The epilogue is required for decoders to consider a frame completed.
660* flush operation is the same, and follows same rules as calling ZSTD_compressStream2() with ZSTD_e_flush.
661* You must continue calling ZSTD_compressStream2() with ZSTD_e_end until it returns 0, at which point you are free to
662* start a new frame.
663* note: ZSTD_e_end will flush as much output as possible, meaning when compressing with multiple threads, it will
664* block until the flush is complete or the output buffer is full.
665* @return : 0 if frame fully completed and fully flushed,
666* >0 if some data still present within internal buffer (the value is minimal estimation of remaining size),
667* or an error code, which can be tested using ZSTD_isError().
668*
669* *******************************************************************/
670
671typedef ZSTD_CCtx ZSTD_CStream; /**< CCtx and CStream are now effectively same object (>= v1.3.0) */
672 /* Continue to distinguish them for compatibility with older versions <= v1.2.0 */
673/*===== ZSTD_CStream management functions =====*/
674ZSTDLIB_API ZSTD_CStream* ZSTD_createCStream(void);
675ZSTDLIB_API size_t ZSTD_freeCStream(ZSTD_CStream* zcs); /* accept NULL pointer */
676
677/*===== Streaming compression functions =====*/
678typedef enum {
679 ZSTD_e_continue=0, /* collect more data, encoder decides when to output compressed result, for optimal compression ratio */
680 ZSTD_e_flush=1, /* flush any data provided so far,
681 * it creates (at least) one new block, that can be decoded immediately on reception;
682 * frame will continue: any future data can still reference previously compressed data, improving compression.
683 * note : multithreaded compression will block to flush as much output as possible. */
684 ZSTD_e_end=2 /* flush any remaining data _and_ close current frame.
685 * note that frame is only closed after compressed data is fully flushed (return value == 0).
686 * After that point, any additional data starts a new frame.
687 * note : each frame is independent (does not reference any content from previous frame).
688 : note : multithreaded compression will block to flush as much output as possible. */
689} ZSTD_EndDirective;
690
691/*! ZSTD_compressStream2() : Requires v1.4.0+
692 * Behaves about the same as ZSTD_compressStream, with additional control on end directive.
693 * - Compression parameters are pushed into CCtx before starting compression, using ZSTD_CCtx_set*()
694 * - Compression parameters cannot be changed once compression is started (save a list of exceptions in multi-threading mode)
695 * - output->pos must be <= dstCapacity, input->pos must be <= srcSize
696 * - output->pos and input->pos will be updated. They are guaranteed to remain below their respective limit.
697 * - endOp must be a valid directive
698 * - When nbWorkers==0 (default), function is blocking : it completes its job before returning to caller.
699 * - When nbWorkers>=1, function is non-blocking : it copies a portion of input, distributes jobs to internal worker threads, flush to output whatever is available,
700 * and then immediately returns, just indicating that there is some data remaining to be flushed.
701 * The function nonetheless guarantees forward progress : it will return only after it reads or write at least 1+ byte.
702 * - Exception : if the first call requests a ZSTD_e_end directive and provides enough dstCapacity, the function delegates to ZSTD_compress2() which is always blocking.
703 * - @return provides a minimum amount of data remaining to be flushed from internal buffers
704 * or an error code, which can be tested using ZSTD_isError().
705 * if @return != 0, flush is not fully completed, there is still some data left within internal buffers.
706 * This is useful for ZSTD_e_flush, since in this case more flushes are necessary to empty all buffers.
707 * For ZSTD_e_end, @return == 0 when internal buffers are fully flushed and frame is completed.
708 * - after a ZSTD_e_end directive, if internal buffer is not fully flushed (@return != 0),
709 * only ZSTD_e_end or ZSTD_e_flush operations are allowed.
710 * Before starting a new compression job, or changing compression parameters,
711 * it is required to fully flush internal buffers.
712 */
713ZSTDLIB_API size_t ZSTD_compressStream2( ZSTD_CCtx* cctx,
714 ZSTD_outBuffer* output,
715 ZSTD_inBuffer* input,
716 ZSTD_EndDirective endOp);
717
718
719/* These buffer sizes are softly recommended.
720 * They are not required : ZSTD_compressStream*() happily accepts any buffer size, for both input and output.
721 * Respecting the recommended size just makes it a bit easier for ZSTD_compressStream*(),
722 * reducing the amount of memory shuffling and buffering, resulting in minor performance savings.
723 *
724 * However, note that these recommendations are from the perspective of a C caller program.
725 * If the streaming interface is invoked from some other language,
726 * especially managed ones such as Java or Go, through a foreign function interface such as jni or cgo,
727 * a major performance rule is to reduce crossing such interface to an absolute minimum.
728 * It's not rare that performance ends being spent more into the interface, rather than compression itself.
729 * In which cases, prefer using large buffers, as large as practical,
730 * for both input and output, to reduce the nb of roundtrips.
731 */
732ZSTDLIB_API size_t ZSTD_CStreamInSize(void); /**< recommended size for input buffer */
733ZSTDLIB_API size_t ZSTD_CStreamOutSize(void); /**< recommended size for output buffer. Guarantee to successfully flush at least one complete compressed block. */
734
735
736/* *****************************************************************************
737 * This following is a legacy streaming API, available since v1.0+ .
738 * It can be replaced by ZSTD_CCtx_reset() and ZSTD_compressStream2().
739 * It is redundant, but remains fully supported.
740 * Streaming in combination with advanced parameters and dictionary compression
741 * can only be used through the new API.
742 ******************************************************************************/
743
744/*!
745 * Equivalent to:
746 *
747 * ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only);
748 * ZSTD_CCtx_refCDict(zcs, NULL); // clear the dictionary (if any)
749 * ZSTD_CCtx_setParameter(zcs, ZSTD_c_compressionLevel, compressionLevel);
750 */
751ZSTDLIB_API size_t ZSTD_initCStream(ZSTD_CStream* zcs, int compressionLevel);
752/*!
753 * Alternative for ZSTD_compressStream2(zcs, output, input, ZSTD_e_continue).
754 * NOTE: The return value is different. ZSTD_compressStream() returns a hint for
755 * the next read size (if non-zero and not an error). ZSTD_compressStream2()
756 * returns the minimum nb of bytes left to flush (if non-zero and not an error).
757 */
758ZSTDLIB_API size_t ZSTD_compressStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output, ZSTD_inBuffer* input);
759/*! Equivalent to ZSTD_compressStream2(zcs, output, &emptyInput, ZSTD_e_flush). */
760ZSTDLIB_API size_t ZSTD_flushStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output);
761/*! Equivalent to ZSTD_compressStream2(zcs, output, &emptyInput, ZSTD_e_end). */
762ZSTDLIB_API size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output);
763
764
765/*-***************************************************************************
766* Streaming decompression - HowTo
767*
768* A ZSTD_DStream object is required to track streaming operations.
769* Use ZSTD_createDStream() and ZSTD_freeDStream() to create/release resources.
770* ZSTD_DStream objects can be re-used multiple times.
771*
772* Use ZSTD_initDStream() to start a new decompression operation.
773* @return : recommended first input size
774* Alternatively, use advanced API to set specific properties.
775*
776* Use ZSTD_decompressStream() repetitively to consume your input.
777* The function will update both `pos` fields.
778* If `input.pos < input.size`, some input has not been consumed.
779* It's up to the caller to present again remaining data.
780* The function tries to flush all data decoded immediately, respecting output buffer size.
781* If `output.pos < output.size`, decoder has flushed everything it could.
782* But if `output.pos == output.size`, there might be some data left within internal buffers.,
783* In which case, call ZSTD_decompressStream() again to flush whatever remains in the buffer.
784* Note : with no additional input provided, amount of data flushed is necessarily <= ZSTD_BLOCKSIZE_MAX.
785* @return : 0 when a frame is completely decoded and fully flushed,
786* or an error code, which can be tested using ZSTD_isError(),
787* or any other value > 0, which means there is still some decoding or flushing to do to complete current frame :
788* the return value is a suggested next input size (just a hint for better latency)
789* that will never request more than the remaining frame size.
790* *******************************************************************************/
791
792typedef ZSTD_DCtx ZSTD_DStream; /**< DCtx and DStream are now effectively same object (>= v1.3.0) */
793 /* For compatibility with versions <= v1.2.0, prefer differentiating them. */
794/*===== ZSTD_DStream management functions =====*/
795ZSTDLIB_API ZSTD_DStream* ZSTD_createDStream(void);
796ZSTDLIB_API size_t ZSTD_freeDStream(ZSTD_DStream* zds); /* accept NULL pointer */
797
798/*===== Streaming decompression functions =====*/
799
800/* This function is redundant with the advanced API and equivalent to:
801 *
802 * ZSTD_DCtx_reset(zds, ZSTD_reset_session_only);
803 * ZSTD_DCtx_refDDict(zds, NULL);
804 */
805ZSTDLIB_API size_t ZSTD_initDStream(ZSTD_DStream* zds);
806
807ZSTDLIB_API size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inBuffer* input);
808
809ZSTDLIB_API size_t ZSTD_DStreamInSize(void); /*!< recommended size for input buffer */
810ZSTDLIB_API size_t ZSTD_DStreamOutSize(void); /*!< recommended size for output buffer. Guarantee to successfully flush at least one complete block in all circumstances. */
811
812
813/**************************
814* Simple dictionary API
815***************************/
816/*! ZSTD_compress_usingDict() :
817 * Compression at an explicit compression level using a Dictionary.
818 * A dictionary can be any arbitrary data segment (also called a prefix),
819 * or a buffer with specified information (see zdict.h).
820 * Note : This function loads the dictionary, resulting in significant startup delay.
821 * It's intended for a dictionary used only once.
822 * Note 2 : When `dict == NULL || dictSize < 8` no dictionary is used. */
823ZSTDLIB_API size_t ZSTD_compress_usingDict(ZSTD_CCtx* ctx,
824 void* dst, size_t dstCapacity,
825 const void* src, size_t srcSize,
826 const void* dict,size_t dictSize,
827 int compressionLevel);
828
829/*! ZSTD_decompress_usingDict() :
830 * Decompression using a known Dictionary.
831 * Dictionary must be identical to the one used during compression.
832 * Note : This function loads the dictionary, resulting in significant startup delay.
833 * It's intended for a dictionary used only once.
834 * Note : When `dict == NULL || dictSize < 8` no dictionary is used. */
835ZSTDLIB_API size_t ZSTD_decompress_usingDict(ZSTD_DCtx* dctx,
836 void* dst, size_t dstCapacity,
837 const void* src, size_t srcSize,
838 const void* dict,size_t dictSize);
839
840
841/***********************************
842 * Bulk processing dictionary API
843 **********************************/
844typedef struct ZSTD_CDict_s ZSTD_CDict;
845
846/*! ZSTD_createCDict() :
847 * When compressing multiple messages or blocks using the same dictionary,
848 * it's recommended to digest the dictionary only once, since it's a costly operation.
849 * ZSTD_createCDict() will create a state from digesting a dictionary.
850 * The resulting state can be used for future compression operations with very limited startup cost.
851 * ZSTD_CDict can be created once and shared by multiple threads concurrently, since its usage is read-only.
852 * @dictBuffer can be released after ZSTD_CDict creation, because its content is copied within CDict.
853 * Note 1 : Consider experimental function `ZSTD_createCDict_byReference()` if you prefer to not duplicate @dictBuffer content.
854 * Note 2 : A ZSTD_CDict can be created from an empty @dictBuffer,
855 * in which case the only thing that it transports is the @compressionLevel.
856 * This can be useful in a pipeline featuring ZSTD_compress_usingCDict() exclusively,
857 * expecting a ZSTD_CDict parameter with any data, including those without a known dictionary. */
858ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict(const void* dictBuffer, size_t dictSize,
859 int compressionLevel);
860
861/*! ZSTD_freeCDict() :
862 * Function frees memory allocated by ZSTD_createCDict().
863 * If a NULL pointer is passed, no operation is performed. */
864ZSTDLIB_API size_t ZSTD_freeCDict(ZSTD_CDict* CDict);
865
866/*! ZSTD_compress_usingCDict() :
867 * Compression using a digested Dictionary.
868 * Recommended when same dictionary is used multiple times.
869 * Note : compression level is _decided at dictionary creation time_,
870 * and frame parameters are hardcoded (dictID=yes, contentSize=yes, checksum=no) */
871ZSTDLIB_API size_t ZSTD_compress_usingCDict(ZSTD_CCtx* cctx,
872 void* dst, size_t dstCapacity,
873 const void* src, size_t srcSize,
874 const ZSTD_CDict* cdict);
875
876
877typedef struct ZSTD_DDict_s ZSTD_DDict;
878
879/*! ZSTD_createDDict() :
880 * Create a digested dictionary, ready to start decompression operation without startup delay.
881 * dictBuffer can be released after DDict creation, as its content is copied inside DDict. */
882ZSTDLIB_API ZSTD_DDict* ZSTD_createDDict(const void* dictBuffer, size_t dictSize);
883
884/*! ZSTD_freeDDict() :
885 * Function frees memory allocated with ZSTD_createDDict()
886 * If a NULL pointer is passed, no operation is performed. */
887ZSTDLIB_API size_t ZSTD_freeDDict(ZSTD_DDict* ddict);
888
889/*! ZSTD_decompress_usingDDict() :
890 * Decompression using a digested Dictionary.
891 * Recommended when same dictionary is used multiple times. */
892ZSTDLIB_API size_t ZSTD_decompress_usingDDict(ZSTD_DCtx* dctx,
893 void* dst, size_t dstCapacity,
894 const void* src, size_t srcSize,
895 const ZSTD_DDict* ddict);
896
897
898/********************************
899 * Dictionary helper functions
900 *******************************/
901
902/*! ZSTD_getDictID_fromDict() : Requires v1.4.0+
903 * Provides the dictID stored within dictionary.
904 * if @return == 0, the dictionary is not conformant with Zstandard specification.
905 * It can still be loaded, but as a content-only dictionary. */
906ZSTDLIB_API unsigned ZSTD_getDictID_fromDict(const void* dict, size_t dictSize);
907
908/*! ZSTD_getDictID_fromCDict() : Requires v1.5.0+
909 * Provides the dictID of the dictionary loaded into `cdict`.
910 * If @return == 0, the dictionary is not conformant to Zstandard specification, or empty.
911 * Non-conformant dictionaries can still be loaded, but as content-only dictionaries. */
912ZSTDLIB_API unsigned ZSTD_getDictID_fromCDict(const ZSTD_CDict* cdict);
913
914/*! ZSTD_getDictID_fromDDict() : Requires v1.4.0+
915 * Provides the dictID of the dictionary loaded into `ddict`.
916 * If @return == 0, the dictionary is not conformant to Zstandard specification, or empty.
917 * Non-conformant dictionaries can still be loaded, but as content-only dictionaries. */
918ZSTDLIB_API unsigned ZSTD_getDictID_fromDDict(const ZSTD_DDict* ddict);
919
920/*! ZSTD_getDictID_fromFrame() : Requires v1.4.0+
921 * Provides the dictID required to decompressed the frame stored within `src`.
922 * If @return == 0, the dictID could not be decoded.
923 * This could for one of the following reasons :
924 * - The frame does not require a dictionary to be decoded (most common case).
925 * - The frame was built with dictID intentionally removed. Whatever dictionary is necessary is a hidden information.
926 * Note : this use case also happens when using a non-conformant dictionary.
927 * - `srcSize` is too small, and as a result, the frame header could not be decoded (only possible if `srcSize < ZSTD_FRAMEHEADERSIZE_MAX`).
928 * - This is not a Zstandard frame.
929 * When identifying the exact failure cause, it's possible to use ZSTD_getFrameHeader(), which will provide a more precise error code. */
930ZSTDLIB_API unsigned ZSTD_getDictID_fromFrame(const void* src, size_t srcSize);
931
932
933/*******************************************************************************
934 * Advanced dictionary and prefix API (Requires v1.4.0+)
935 *
936 * This API allows dictionaries to be used with ZSTD_compress2(),
937 * ZSTD_compressStream2(), and ZSTD_decompressDCtx(). Dictionaries are sticky, and
938 * only reset with the context is reset with ZSTD_reset_parameters or
939 * ZSTD_reset_session_and_parameters. Prefixes are single-use.
940 ******************************************************************************/
941
942
943/*! ZSTD_CCtx_loadDictionary() : Requires v1.4.0+
944 * Create an internal CDict from `dict` buffer.
945 * Decompression will have to use same dictionary.
946 * @result : 0, or an error code (which can be tested with ZSTD_isError()).
947 * Special: Loading a NULL (or 0-size) dictionary invalidates previous dictionary,
948 * meaning "return to no-dictionary mode".
949 * Note 1 : Dictionary is sticky, it will be used for all future compressed frames.
950 * To return to "no-dictionary" situation, load a NULL dictionary (or reset parameters).
951 * Note 2 : Loading a dictionary involves building tables.
952 * It's also a CPU consuming operation, with non-negligible impact on latency.
953 * Tables are dependent on compression parameters, and for this reason,
954 * compression parameters can no longer be changed after loading a dictionary.
955 * Note 3 :`dict` content will be copied internally.
956 * Use experimental ZSTD_CCtx_loadDictionary_byReference() to reference content instead.
957 * In such a case, dictionary buffer must outlive its users.
958 * Note 4 : Use ZSTD_CCtx_loadDictionary_advanced()
959 * to precisely select how dictionary content must be interpreted. */
960ZSTDLIB_API size_t ZSTD_CCtx_loadDictionary(ZSTD_CCtx* cctx, const void* dict, size_t dictSize);
961
962/*! ZSTD_CCtx_refCDict() : Requires v1.4.0+
963 * Reference a prepared dictionary, to be used for all next compressed frames.
964 * Note that compression parameters are enforced from within CDict,
965 * and supersede any compression parameter previously set within CCtx.
966 * The parameters ignored are labelled as "superseded-by-cdict" in the ZSTD_cParameter enum docs.
967 * The ignored parameters will be used again if the CCtx is returned to no-dictionary mode.
968 * The dictionary will remain valid for future compressed frames using same CCtx.
969 * @result : 0, or an error code (which can be tested with ZSTD_isError()).
970 * Special : Referencing a NULL CDict means "return to no-dictionary mode".
971 * Note 1 : Currently, only one dictionary can be managed.
972 * Referencing a new dictionary effectively "discards" any previous one.
973 * Note 2 : CDict is just referenced, its lifetime must outlive its usage within CCtx. */
974ZSTDLIB_API size_t ZSTD_CCtx_refCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict);
975
976/*! ZSTD_CCtx_refPrefix() : Requires v1.4.0+
977 * Reference a prefix (single-usage dictionary) for next compressed frame.
978 * A prefix is **only used once**. Tables are discarded at end of frame (ZSTD_e_end).
979 * Decompression will need same prefix to properly regenerate data.
980 * Compressing with a prefix is similar in outcome as performing a diff and compressing it,
981 * but performs much faster, especially during decompression (compression speed is tunable with compression level).
982 * @result : 0, or an error code (which can be tested with ZSTD_isError()).
983 * Special: Adding any prefix (including NULL) invalidates any previous prefix or dictionary
984 * Note 1 : Prefix buffer is referenced. It **must** outlive compression.
985 * Its content must remain unmodified during compression.
986 * Note 2 : If the intention is to diff some large src data blob with some prior version of itself,
987 * ensure that the window size is large enough to contain the entire source.
988 * See ZSTD_c_windowLog.
989 * Note 3 : Referencing a prefix involves building tables, which are dependent on compression parameters.
990 * It's a CPU consuming operation, with non-negligible impact on latency.
991 * If there is a need to use the same prefix multiple times, consider loadDictionary instead.
992 * Note 4 : By default, the prefix is interpreted as raw content (ZSTD_dct_rawContent).
993 * Use experimental ZSTD_CCtx_refPrefix_advanced() to alter dictionary interpretation. */
994ZSTDLIB_API size_t ZSTD_CCtx_refPrefix(ZSTD_CCtx* cctx,
995 const void* prefix, size_t prefixSize);
996
997/*! ZSTD_DCtx_loadDictionary() : Requires v1.4.0+
998 * Create an internal DDict from dict buffer,
999 * to be used to decompress next frames.
1000 * The dictionary remains valid for all future frames, until explicitly invalidated.
1001 * @result : 0, or an error code (which can be tested with ZSTD_isError()).
1002 * Special : Adding a NULL (or 0-size) dictionary invalidates any previous dictionary,
1003 * meaning "return to no-dictionary mode".
1004 * Note 1 : Loading a dictionary involves building tables,
1005 * which has a non-negligible impact on CPU usage and latency.
1006 * It's recommended to "load once, use many times", to amortize the cost
1007 * Note 2 :`dict` content will be copied internally, so `dict` can be released after loading.
1008 * Use ZSTD_DCtx_loadDictionary_byReference() to reference dictionary content instead.
1009 * Note 3 : Use ZSTD_DCtx_loadDictionary_advanced() to take control of
1010 * how dictionary content is loaded and interpreted.
1011 */
1012ZSTDLIB_API size_t ZSTD_DCtx_loadDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSize);
1013
1014/*! ZSTD_DCtx_refDDict() : Requires v1.4.0+
1015 * Reference a prepared dictionary, to be used to decompress next frames.
1016 * The dictionary remains active for decompression of future frames using same DCtx.
1017 *
1018 * If called with ZSTD_d_refMultipleDDicts enabled, repeated calls of this function
1019 * will store the DDict references in a table, and the DDict used for decompression
1020 * will be determined at decompression time, as per the dict ID in the frame.
1021 * The memory for the table is allocated on the first call to refDDict, and can be
1022 * freed with ZSTD_freeDCtx().
1023 *
1024 * @result : 0, or an error code (which can be tested with ZSTD_isError()).
1025 * Note 1 : Currently, only one dictionary can be managed.
1026 * Referencing a new dictionary effectively "discards" any previous one.
1027 * Special: referencing a NULL DDict means "return to no-dictionary mode".
1028 * Note 2 : DDict is just referenced, its lifetime must outlive its usage from DCtx.
1029 */
1030ZSTDLIB_API size_t ZSTD_DCtx_refDDict(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict);
1031
1032/*! ZSTD_DCtx_refPrefix() : Requires v1.4.0+
1033 * Reference a prefix (single-usage dictionary) to decompress next frame.
1034 * This is the reverse operation of ZSTD_CCtx_refPrefix(),
1035 * and must use the same prefix as the one used during compression.
1036 * Prefix is **only used once**. Reference is discarded at end of frame.
1037 * End of frame is reached when ZSTD_decompressStream() returns 0.
1038 * @result : 0, or an error code (which can be tested with ZSTD_isError()).
1039 * Note 1 : Adding any prefix (including NULL) invalidates any previously set prefix or dictionary
1040 * Note 2 : Prefix buffer is referenced. It **must** outlive decompression.
1041 * Prefix buffer must remain unmodified up to the end of frame,
1042 * reached when ZSTD_decompressStream() returns 0.
1043 * Note 3 : By default, the prefix is treated as raw content (ZSTD_dct_rawContent).
1044 * Use ZSTD_CCtx_refPrefix_advanced() to alter dictMode (Experimental section)
1045 * Note 4 : Referencing a raw content prefix has almost no cpu nor memory cost.
1046 * A full dictionary is more costly, as it requires building tables.
1047 */
1048ZSTDLIB_API size_t ZSTD_DCtx_refPrefix(ZSTD_DCtx* dctx,
1049 const void* prefix, size_t prefixSize);
1050
1051/* === Memory management === */
1052
1053/*! ZSTD_sizeof_*() : Requires v1.4.0+
1054 * These functions give the _current_ memory usage of selected object.
1055 * Note that object memory usage can evolve (increase or decrease) over time. */
1056ZSTDLIB_API size_t ZSTD_sizeof_CCtx(const ZSTD_CCtx* cctx);
1057ZSTDLIB_API size_t ZSTD_sizeof_DCtx(const ZSTD_DCtx* dctx);
1058ZSTDLIB_API size_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs);
1059ZSTDLIB_API size_t ZSTD_sizeof_DStream(const ZSTD_DStream* zds);
1060ZSTDLIB_API size_t ZSTD_sizeof_CDict(const ZSTD_CDict* cdict);
1061ZSTDLIB_API size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict);
1062
1063#endif /* ZSTD_H_235446 */
1064
1065
1066/* **************************************************************************************
1067 * ADVANCED AND EXPERIMENTAL FUNCTIONS
1068 ****************************************************************************************
1069 * The definitions in the following section are considered experimental.
1070 * They are provided for advanced scenarios.
1071 * They should never be used with a dynamic library, as prototypes may change in the future.
1072 * Use them only in association with static linking.
1073 * ***************************************************************************************/
1074
1075#if defined(ZSTD_STATIC_LINKING_ONLY) && !defined(ZSTD_H_ZSTD_STATIC_LINKING_ONLY)
1076#define ZSTD_H_ZSTD_STATIC_LINKING_ONLY
1077
1078/* This can be overridden externally to hide static symbols. */
1079#ifndef ZSTDLIB_STATIC_API
1080# if defined(ZSTD_DLL_EXPORT) && (ZSTD_DLL_EXPORT==1)
1081# define ZSTDLIB_STATIC_API __declspec(dllexport) ZSTDLIB_VISIBLE
1082# elif defined(ZSTD_DLL_IMPORT) && (ZSTD_DLL_IMPORT==1)
1083# define ZSTDLIB_STATIC_API __declspec(dllimport) ZSTDLIB_VISIBLE
1084# else
1085# define ZSTDLIB_STATIC_API ZSTDLIB_VISIBLE
1086# endif
1087#endif
1088
1089/* Deprecation warnings :
1090 * Should these warnings be a problem, it is generally possible to disable them,
1091 * typically with -Wno-deprecated-declarations for gcc or _CRT_SECURE_NO_WARNINGS in Visual.
1092 * Otherwise, it's also possible to define ZSTD_DISABLE_DEPRECATE_WARNINGS.
1093 */
1094#ifdef ZSTD_DISABLE_DEPRECATE_WARNINGS
1095# define ZSTD_DEPRECATED(message) ZSTDLIB_STATIC_API /* disable deprecation warnings */
1096#else
1097# if defined (__cplusplus) && (__cplusplus >= 201402) /* C++14 or greater */
1098# define ZSTD_DEPRECATED(message) [[deprecated(message)]] ZSTDLIB_STATIC_API
1099# elif (defined(GNUC) && (GNUC > 4 || (GNUC == 4 && GNUC_MINOR >= 5))) || defined(__clang__)
1100# define ZSTD_DEPRECATED(message) ZSTDLIB_STATIC_API __attribute__((deprecated(message)))
1101# elif defined(__GNUC__) && (__GNUC__ >= 3)
1102# define ZSTD_DEPRECATED(message) ZSTDLIB_STATIC_API __attribute__((deprecated))
1103# elif defined(_MSC_VER)
1104# define ZSTD_DEPRECATED(message) ZSTDLIB_STATIC_API __declspec(deprecated(message))
1105# else
1106# pragma message("WARNING: You need to implement ZSTD_DEPRECATED for this compiler")
1107# define ZSTD_DEPRECATED(message) ZSTDLIB_STATIC_API
1108# endif
1109#endif /* ZSTD_DISABLE_DEPRECATE_WARNINGS */
1110
1111/****************************************************************************************
1112 * experimental API (static linking only)
1113 ****************************************************************************************
1114 * The following symbols and constants
1115 * are not planned to join "stable API" status in the near future.
1116 * They can still change in future versions.
1117 * Some of them are planned to remain in the static_only section indefinitely.
1118 * Some of them might be removed in the future (especially when redundant with existing stable functions)
1119 * ***************************************************************************************/
1120
1121#define ZSTD_FRAMEHEADERSIZE_PREFIX(format) ((format) == ZSTD_f_zstd1 ? 5 : 1) /* minimum input size required to query frame header size */
1122#define ZSTD_FRAMEHEADERSIZE_MIN(format) ((format) == ZSTD_f_zstd1 ? 6 : 2)
1123#define ZSTD_FRAMEHEADERSIZE_MAX 18 /* can be useful for static allocation */
1124#define ZSTD_SKIPPABLEHEADERSIZE 8
1125
1126/* compression parameter bounds */
1127#define ZSTD_WINDOWLOG_MAX_32 30
1128#define ZSTD_WINDOWLOG_MAX_64 31
1129#define ZSTD_WINDOWLOG_MAX ((int)(sizeof(size_t) == 4 ? ZSTD_WINDOWLOG_MAX_32 : ZSTD_WINDOWLOG_MAX_64))
1130#define ZSTD_WINDOWLOG_MIN 10
1131#define ZSTD_HASHLOG_MAX ((ZSTD_WINDOWLOG_MAX < 30) ? ZSTD_WINDOWLOG_MAX : 30)
1132#define ZSTD_HASHLOG_MIN 6
1133#define ZSTD_CHAINLOG_MAX_32 29
1134#define ZSTD_CHAINLOG_MAX_64 30
1135#define ZSTD_CHAINLOG_MAX ((int)(sizeof(size_t) == 4 ? ZSTD_CHAINLOG_MAX_32 : ZSTD_CHAINLOG_MAX_64))
1136#define ZSTD_CHAINLOG_MIN ZSTD_HASHLOG_MIN
1137#define ZSTD_SEARCHLOG_MAX (ZSTD_WINDOWLOG_MAX-1)
1138#define ZSTD_SEARCHLOG_MIN 1
1139#define ZSTD_MINMATCH_MAX 7 /* only for ZSTD_fast, other strategies are limited to 6 */
1140#define ZSTD_MINMATCH_MIN 3 /* only for ZSTD_btopt+, faster strategies are limited to 4 */
1141#define ZSTD_TARGETLENGTH_MAX ZSTD_BLOCKSIZE_MAX
1142#define ZSTD_TARGETLENGTH_MIN 0 /* note : comparing this constant to an unsigned results in a tautological test */
1143#define ZSTD_STRATEGY_MIN ZSTD_fast
1144#define ZSTD_STRATEGY_MAX ZSTD_btultra2
1145
1146
1147#define ZSTD_OVERLAPLOG_MIN 0
1148#define ZSTD_OVERLAPLOG_MAX 9
1149
1150#define ZSTD_WINDOWLOG_LIMIT_DEFAULT 27 /* by default, the streaming decoder will refuse any frame
1151 * requiring larger than (1<<ZSTD_WINDOWLOG_LIMIT_DEFAULT) window size,
1152 * to preserve host's memory from unreasonable requirements.
1153 * This limit can be overridden using ZSTD_DCtx_setParameter(,ZSTD_d_windowLogMax,).
1154 * The limit does not apply for one-pass decoders (such as ZSTD_decompress()), since no additional memory is allocated */
1155
1156
1157/* LDM parameter bounds */
1158#define ZSTD_LDM_HASHLOG_MIN ZSTD_HASHLOG_MIN
1159#define ZSTD_LDM_HASHLOG_MAX ZSTD_HASHLOG_MAX
1160#define ZSTD_LDM_MINMATCH_MIN 4
1161#define ZSTD_LDM_MINMATCH_MAX 4096
1162#define ZSTD_LDM_BUCKETSIZELOG_MIN 1
1163#define ZSTD_LDM_BUCKETSIZELOG_MAX 8
1164#define ZSTD_LDM_HASHRATELOG_MIN 0
1165#define ZSTD_LDM_HASHRATELOG_MAX (ZSTD_WINDOWLOG_MAX - ZSTD_HASHLOG_MIN)
1166
1167/* Advanced parameter bounds */
1168#define ZSTD_TARGETCBLOCKSIZE_MIN 64
1169#define ZSTD_TARGETCBLOCKSIZE_MAX ZSTD_BLOCKSIZE_MAX
1170#define ZSTD_SRCSIZEHINT_MIN 0
1171#define ZSTD_SRCSIZEHINT_MAX INT_MAX
1172
1173
1174/* --- Advanced types --- */
1175
1176typedef struct ZSTD_CCtx_params_s ZSTD_CCtx_params;
1177
1178typedef struct {
1179 unsigned int offset; /* The offset of the match. (NOT the same as the offset code)
1180 * If offset == 0 and matchLength == 0, this sequence represents the last
1181 * literals in the block of litLength size.
1182 */
1183
1184 unsigned int litLength; /* Literal length of the sequence. */
1185 unsigned int matchLength; /* Match length of the sequence. */
1186
1187 /* Note: Users of this API may provide a sequence with matchLength == litLength == offset == 0.
1188 * In this case, we will treat the sequence as a marker for a block boundary.
1189 */
1190
1191 unsigned int rep; /* Represents which repeat offset is represented by the field 'offset'.
1192 * Ranges from [0, 3].
1193 *
1194 * Repeat offsets are essentially previous offsets from previous sequences sorted in
1195 * recency order. For more detail, see doc/zstd_compression_format.md
1196 *
1197 * If rep == 0, then 'offset' does not contain a repeat offset.
1198 * If rep > 0:
1199 * If litLength != 0:
1200 * rep == 1 --> offset == repeat_offset_1
1201 * rep == 2 --> offset == repeat_offset_2
1202 * rep == 3 --> offset == repeat_offset_3
1203 * If litLength == 0:
1204 * rep == 1 --> offset == repeat_offset_2
1205 * rep == 2 --> offset == repeat_offset_3
1206 * rep == 3 --> offset == repeat_offset_1 - 1
1207 *
1208 * Note: This field is optional. ZSTD_generateSequences() will calculate the value of
1209 * 'rep', but repeat offsets do not necessarily need to be calculated from an external
1210 * sequence provider's perspective. For example, ZSTD_compressSequences() does not
1211 * use this 'rep' field at all (as of now).
1212 */
1213} ZSTD_Sequence;
1214
1215typedef struct {
1216 unsigned windowLog; /**< largest match distance : larger == more compression, more memory needed during decompression */
1217 unsigned chainLog; /**< fully searched segment : larger == more compression, slower, more memory (useless for fast) */
1218 unsigned hashLog; /**< dispatch table : larger == faster, more memory */
1219 unsigned searchLog; /**< nb of searches : larger == more compression, slower */
1220 unsigned minMatch; /**< match length searched : larger == faster decompression, sometimes less compression */
1221 unsigned targetLength; /**< acceptable match size for optimal parser (only) : larger == more compression, slower */
1222 ZSTD_strategy strategy; /**< see ZSTD_strategy definition above */
1223} ZSTD_compressionParameters;
1224
1225typedef struct {
1226 int contentSizeFlag; /**< 1: content size will be in frame header (when known) */
1227 int checksumFlag; /**< 1: generate a 32-bits checksum using XXH64 algorithm at end of frame, for error detection */
1228 int noDictIDFlag; /**< 1: no dictID will be saved into frame header (dictID is only useful for dictionary compression) */
1229} ZSTD_frameParameters;
1230
1231typedef struct {
1232 ZSTD_compressionParameters cParams;
1233 ZSTD_frameParameters fParams;
1234} ZSTD_parameters;
1235
1236typedef enum {
1237 ZSTD_dct_auto = 0, /* dictionary is "full" when starting with ZSTD_MAGIC_DICTIONARY, otherwise it is "rawContent" */
1238 ZSTD_dct_rawContent = 1, /* ensures dictionary is always loaded as rawContent, even if it starts with ZSTD_MAGIC_DICTIONARY */
1239 ZSTD_dct_fullDict = 2 /* refuses to load a dictionary if it does not respect Zstandard's specification, starting with ZSTD_MAGIC_DICTIONARY */
1240} ZSTD_dictContentType_e;
1241
1242typedef enum {
1243 ZSTD_dlm_byCopy = 0, /**< Copy dictionary content internally */
1244 ZSTD_dlm_byRef = 1 /**< Reference dictionary content -- the dictionary buffer must outlive its users. */
1245} ZSTD_dictLoadMethod_e;
1246
1247typedef enum {
1248 ZSTD_f_zstd1 = 0, /* zstd frame format, specified in zstd_compression_format.md (default) */
1249 ZSTD_f_zstd1_magicless = 1 /* Variant of zstd frame format, without initial 4-bytes magic number.
1250 * Useful to save 4 bytes per generated frame.
1251 * Decoder cannot recognise automatically this format, requiring this instruction. */
1252} ZSTD_format_e;
1253
1254typedef enum {
1255 /* Note: this enum controls ZSTD_d_forceIgnoreChecksum */
1256 ZSTD_d_validateChecksum = 0,
1257 ZSTD_d_ignoreChecksum = 1
1258} ZSTD_forceIgnoreChecksum_e;
1259
1260typedef enum {
1261 /* Note: this enum controls ZSTD_d_refMultipleDDicts */
1262 ZSTD_rmd_refSingleDDict = 0,
1263 ZSTD_rmd_refMultipleDDicts = 1
1264} ZSTD_refMultipleDDicts_e;
1265
1266typedef enum {
1267 /* Note: this enum and the behavior it controls are effectively internal
1268 * implementation details of the compressor. They are expected to continue
1269 * to evolve and should be considered only in the context of extremely
1270 * advanced performance tuning.
1271 *
1272 * Zstd currently supports the use of a CDict in three ways:
1273 *
1274 * - The contents of the CDict can be copied into the working context. This
1275 * means that the compression can search both the dictionary and input
1276 * while operating on a single set of internal tables. This makes
1277 * the compression faster per-byte of input. However, the initial copy of
1278 * the CDict's tables incurs a fixed cost at the beginning of the
1279 * compression. For small compressions (< 8 KB), that copy can dominate
1280 * the cost of the compression.
1281 *
1282 * - The CDict's tables can be used in-place. In this model, compression is
1283 * slower per input byte, because the compressor has to search two sets of
1284 * tables. However, this model incurs no start-up cost (as long as the
1285 * working context's tables can be reused). For small inputs, this can be
1286 * faster than copying the CDict's tables.
1287 *
1288 * - The CDict's tables are not used at all, and instead we use the working
1289 * context alone to reload the dictionary and use params based on the source
1290 * size. See ZSTD_compress_insertDictionary() and ZSTD_compress_usingDict().
1291 * This method is effective when the dictionary sizes are very small relative
1292 * to the input size, and the input size is fairly large to begin with.
1293 *
1294 * Zstd has a simple internal heuristic that selects which strategy to use
1295 * at the beginning of a compression. However, if experimentation shows that
1296 * Zstd is making poor choices, it is possible to override that choice with
1297 * this enum.
1298 */
1299 ZSTD_dictDefaultAttach = 0, /* Use the default heuristic. */
1300 ZSTD_dictForceAttach = 1, /* Never copy the dictionary. */
1301 ZSTD_dictForceCopy = 2, /* Always copy the dictionary. */
1302 ZSTD_dictForceLoad = 3 /* Always reload the dictionary */
1303} ZSTD_dictAttachPref_e;
1304
1305typedef enum {
1306 ZSTD_lcm_auto = 0, /**< Automatically determine the compression mode based on the compression level.
1307 * Negative compression levels will be uncompressed, and positive compression
1308 * levels will be compressed. */
1309 ZSTD_lcm_huffman = 1, /**< Always attempt Huffman compression. Uncompressed literals will still be
1310 * emitted if Huffman compression is not profitable. */
1311 ZSTD_lcm_uncompressed = 2 /**< Always emit uncompressed literals. */
1312} ZSTD_literalCompressionMode_e;
1313
1314typedef enum {
1315 /* Note: This enum controls features which are conditionally beneficial. Zstd typically will make a final
1316 * decision on whether or not to enable the feature (ZSTD_ps_auto), but setting the switch to ZSTD_ps_enable
1317 * or ZSTD_ps_disable allow for a force enable/disable the feature.
1318 */
1319 ZSTD_ps_auto = 0, /* Let the library automatically determine whether the feature shall be enabled */
1320 ZSTD_ps_enable = 1, /* Force-enable the feature */
1321 ZSTD_ps_disable = 2 /* Do not use the feature */
1322} ZSTD_paramSwitch_e;
1323
1324/***************************************
1325* Frame size functions
1326***************************************/
1327
1328/*! ZSTD_findDecompressedSize() :
1329 * `src` should point to the start of a series of ZSTD encoded and/or skippable frames
1330 * `srcSize` must be the _exact_ size of this series
1331 * (i.e. there should be a frame boundary at `src + srcSize`)
1332 * @return : - decompressed size of all data in all successive frames
1333 * - if the decompressed size cannot be determined: ZSTD_CONTENTSIZE_UNKNOWN
1334 * - if an error occurred: ZSTD_CONTENTSIZE_ERROR
1335 *
1336 * note 1 : decompressed size is an optional field, that may not be present, especially in streaming mode.
1337 * When `return==ZSTD_CONTENTSIZE_UNKNOWN`, data to decompress could be any size.
1338 * In which case, it's necessary to use streaming mode to decompress data.
1339 * note 2 : decompressed size is always present when compression is done with ZSTD_compress()
1340 * note 3 : decompressed size can be very large (64-bits value),
1341 * potentially larger than what local system can handle as a single memory segment.
1342 * In which case, it's necessary to use streaming mode to decompress data.
1343 * note 4 : If source is untrusted, decompressed size could be wrong or intentionally modified.
1344 * Always ensure result fits within application's authorized limits.
1345 * Each application can set its own limits.
1346 * note 5 : ZSTD_findDecompressedSize handles multiple frames, and so it must traverse the input to
1347 * read each contained frame header. This is fast as most of the data is skipped,
1348 * however it does mean that all frame data must be present and valid. */
1349ZSTDLIB_STATIC_API unsigned long long ZSTD_findDecompressedSize(const void* src, size_t srcSize);
1350
1351/*! ZSTD_decompressBound() :
1352 * `src` should point to the start of a series of ZSTD encoded and/or skippable frames
1353 * `srcSize` must be the _exact_ size of this series
1354 * (i.e. there should be a frame boundary at `src + srcSize`)
1355 * @return : - upper-bound for the decompressed size of all data in all successive frames
1356 * - if an error occurred: ZSTD_CONTENTSIZE_ERROR
1357 *
1358 * note 1 : an error can occur if `src` contains an invalid or incorrectly formatted frame.
1359 * note 2 : the upper-bound is exact when the decompressed size field is available in every ZSTD encoded frame of `src`.
1360 * in this case, `ZSTD_findDecompressedSize` and `ZSTD_decompressBound` return the same value.
1361 * note 3 : when the decompressed size field isn't available, the upper-bound for that frame is calculated by:
1362 * upper-bound = # blocks * min(128 KB, Window_Size)
1363 */
1364ZSTDLIB_STATIC_API unsigned long long ZSTD_decompressBound(const void* src, size_t srcSize);
1365
1366/*! ZSTD_frameHeaderSize() :
1367 * srcSize must be >= ZSTD_FRAMEHEADERSIZE_PREFIX.
1368 * @return : size of the Frame Header,
1369 * or an error code (if srcSize is too small) */
1370ZSTDLIB_STATIC_API size_t ZSTD_frameHeaderSize(const void* src, size_t srcSize);
1371
1372typedef enum {
1373 ZSTD_sf_noBlockDelimiters = 0, /* Representation of ZSTD_Sequence has no block delimiters, sequences only */
1374 ZSTD_sf_explicitBlockDelimiters = 1 /* Representation of ZSTD_Sequence contains explicit block delimiters */
1375} ZSTD_sequenceFormat_e;
1376
1377/*! ZSTD_generateSequences() :
1378 * Generate sequences using ZSTD_compress2, given a source buffer.
1379 *
1380 * Each block will end with a dummy sequence
1381 * with offset == 0, matchLength == 0, and litLength == length of last literals.
1382 * litLength may be == 0, and if so, then the sequence of (of: 0 ml: 0 ll: 0)
1383 * simply acts as a block delimiter.
1384 *
1385 * zc can be used to insert custom compression params.
1386 * This function invokes ZSTD_compress2
1387 *
1388 * The output of this function can be fed into ZSTD_compressSequences() with CCtx
1389 * setting of ZSTD_c_blockDelimiters as ZSTD_sf_explicitBlockDelimiters
1390 * @return : number of sequences generated
1391 */
1392
1393ZSTDLIB_STATIC_API size_t ZSTD_generateSequences(ZSTD_CCtx* zc, ZSTD_Sequence* outSeqs,
1394 size_t outSeqsSize, const void* src, size_t srcSize);
1395
1396/*! ZSTD_mergeBlockDelimiters() :
1397 * Given an array of ZSTD_Sequence, remove all sequences that represent block delimiters/last literals
1398 * by merging them into into the literals of the next sequence.
1399 *
1400 * As such, the final generated result has no explicit representation of block boundaries,
1401 * and the final last literals segment is not represented in the sequences.
1402 *
1403 * The output of this function can be fed into ZSTD_compressSequences() with CCtx
1404 * setting of ZSTD_c_blockDelimiters as ZSTD_sf_noBlockDelimiters
1405 * @return : number of sequences left after merging
1406 */
1407ZSTDLIB_STATIC_API size_t ZSTD_mergeBlockDelimiters(ZSTD_Sequence* sequences, size_t seqsSize);
1408
1409/*! ZSTD_compressSequences() :
1410 * Compress an array of ZSTD_Sequence, generated from the original source buffer, into dst.
1411 * If a dictionary is included, then the cctx should reference the dict. (see: ZSTD_CCtx_refCDict(), ZSTD_CCtx_loadDictionary(), etc.)
1412 * The entire source is compressed into a single frame.
1413 *
1414 * The compression behavior changes based on cctx params. In particular:
1415 * If ZSTD_c_blockDelimiters == ZSTD_sf_noBlockDelimiters, the array of ZSTD_Sequence is expected to contain
1416 * no block delimiters (defined in ZSTD_Sequence). Block boundaries are roughly determined based on
1417 * the block size derived from the cctx, and sequences may be split. This is the default setting.
1418 *
1419 * If ZSTD_c_blockDelimiters == ZSTD_sf_explicitBlockDelimiters, the array of ZSTD_Sequence is expected to contain
1420 * block delimiters (defined in ZSTD_Sequence). Behavior is undefined if no block delimiters are provided.
1421 *
1422 * If ZSTD_c_validateSequences == 0, this function will blindly accept the sequences provided. Invalid sequences cause undefined
1423 * behavior. If ZSTD_c_validateSequences == 1, then if sequence is invalid (see doc/zstd_compression_format.md for
1424 * specifics regarding offset/matchlength requirements) then the function will bail out and return an error.
1425 *
1426 * In addition to the two adjustable experimental params, there are other important cctx params.
1427 * - ZSTD_c_minMatch MUST be set as less than or equal to the smallest match generated by the match finder. It has a minimum value of ZSTD_MINMATCH_MIN.
1428 * - ZSTD_c_compressionLevel accordingly adjusts the strength of the entropy coder, as it would in typical compression.
1429 * - ZSTD_c_windowLog affects offset validation: this function will return an error at higher debug levels if a provided offset
1430 * is larger than what the spec allows for a given window log and dictionary (if present). See: doc/zstd_compression_format.md
1431 *
1432 * Note: Repcodes are, as of now, always re-calculated within this function, so ZSTD_Sequence::rep is unused.
1433 * Note 2: Once we integrate ability to ingest repcodes, the explicit block delims mode must respect those repcodes exactly,
1434 * and cannot emit an RLE block that disagrees with the repcode history
1435 * @return : final compressed size or a ZSTD error.
1436 */
1437ZSTDLIB_STATIC_API size_t ZSTD_compressSequences(ZSTD_CCtx* const cctx, void* dst, size_t dstSize,
1438 const ZSTD_Sequence* inSeqs, size_t inSeqsSize,
1439 const void* src, size_t srcSize);
1440
1441
1442/*! ZSTD_writeSkippableFrame() :
1443 * Generates a zstd skippable frame containing data given by src, and writes it to dst buffer.
1444 *
1445 * Skippable frames begin with a a 4-byte magic number. There are 16 possible choices of magic number,
1446 * ranging from ZSTD_MAGIC_SKIPPABLE_START to ZSTD_MAGIC_SKIPPABLE_START+15.
1447 * As such, the parameter magicVariant controls the exact skippable frame magic number variant used, so
1448 * the magic number used will be ZSTD_MAGIC_SKIPPABLE_START + magicVariant.
1449 *
1450 * Returns an error if destination buffer is not large enough, if the source size is not representable
1451 * with a 4-byte unsigned int, or if the parameter magicVariant is greater than 15 (and therefore invalid).
1452 *
1453 * @return : number of bytes written or a ZSTD error.
1454 */
1455ZSTDLIB_STATIC_API size_t ZSTD_writeSkippableFrame(void* dst, size_t dstCapacity,
1456 const void* src, size_t srcSize, unsigned magicVariant);
1457
1458/*! ZSTD_readSkippableFrame() :
1459 * Retrieves a zstd skippable frame containing data given by src, and writes it to dst buffer.
1460 *
1461 * The parameter magicVariant will receive the magicVariant that was supplied when the frame was written,
1462 * i.e. magicNumber - ZSTD_MAGIC_SKIPPABLE_START. This can be NULL if the caller is not interested
1463 * in the magicVariant.
1464 *
1465 * Returns an error if destination buffer is not large enough, or if the frame is not skippable.
1466 *
1467 * @return : number of bytes written or a ZSTD error.
1468 */
1469ZSTDLIB_API size_t ZSTD_readSkippableFrame(void* dst, size_t dstCapacity, unsigned* magicVariant,
1470 const void* src, size_t srcSize);
1471
1472/*! ZSTD_isSkippableFrame() :
1473 * Tells if the content of `buffer` starts with a valid Frame Identifier for a skippable frame.
1474 */
1475ZSTDLIB_API unsigned ZSTD_isSkippableFrame(const void* buffer, size_t size);
1476
1477
1478
1479/***************************************
1480* Memory management
1481***************************************/
1482
1483/*! ZSTD_estimate*() :
1484 * These functions make it possible to estimate memory usage
1485 * of a future {D,C}Ctx, before its creation.
1486 *
1487 * ZSTD_estimateCCtxSize() will provide a memory budget large enough
1488 * for any compression level up to selected one.
1489 * Note : Unlike ZSTD_estimateCStreamSize*(), this estimate
1490 * does not include space for a window buffer.
1491 * Therefore, the estimation is only guaranteed for single-shot compressions, not streaming.
1492 * The estimate will assume the input may be arbitrarily large,
1493 * which is the worst case.
1494 *
1495 * When srcSize can be bound by a known and rather "small" value,
1496 * this fact can be used to provide a tighter estimation
1497 * because the CCtx compression context will need less memory.
1498 * This tighter estimation can be provided by more advanced functions
1499 * ZSTD_estimateCCtxSize_usingCParams(), which can be used in tandem with ZSTD_getCParams(),
1500 * and ZSTD_estimateCCtxSize_usingCCtxParams(), which can be used in tandem with ZSTD_CCtxParams_setParameter().
1501 * Both can be used to estimate memory using custom compression parameters and arbitrary srcSize limits.
1502 *
1503 * Note 2 : only single-threaded compression is supported.
1504 * ZSTD_estimateCCtxSize_usingCCtxParams() will return an error code if ZSTD_c_nbWorkers is >= 1.
1505 */
1506ZSTDLIB_STATIC_API size_t ZSTD_estimateCCtxSize(int compressionLevel);
1507ZSTDLIB_STATIC_API size_t ZSTD_estimateCCtxSize_usingCParams(ZSTD_compressionParameters cParams);
1508ZSTDLIB_STATIC_API size_t ZSTD_estimateCCtxSize_usingCCtxParams(const ZSTD_CCtx_params* params);
1509ZSTDLIB_STATIC_API size_t ZSTD_estimateDCtxSize(void);
1510
1511/*! ZSTD_estimateCStreamSize() :
1512 * ZSTD_estimateCStreamSize() will provide a budget large enough for any compression level up to selected one.
1513 * It will also consider src size to be arbitrarily "large", which is worst case.
1514 * If srcSize is known to always be small, ZSTD_estimateCStreamSize_usingCParams() can provide a tighter estimation.
1515 * ZSTD_estimateCStreamSize_usingCParams() can be used in tandem with ZSTD_getCParams() to create cParams from compressionLevel.
1516 * ZSTD_estimateCStreamSize_usingCCtxParams() can be used in tandem with ZSTD_CCtxParams_setParameter(). Only single-threaded compression is supported. This function will return an error code if ZSTD_c_nbWorkers is >= 1.
1517 * Note : CStream size estimation is only correct for single-threaded compression.
1518 * ZSTD_DStream memory budget depends on window Size.
1519 * This information can be passed manually, using ZSTD_estimateDStreamSize,
1520 * or deducted from a valid frame Header, using ZSTD_estimateDStreamSize_fromFrame();
1521 * Note : if streaming is init with function ZSTD_init?Stream_usingDict(),
1522 * an internal ?Dict will be created, which additional size is not estimated here.
1523 * In this case, get total size by adding ZSTD_estimate?DictSize */
1524ZSTDLIB_STATIC_API size_t ZSTD_estimateCStreamSize(int compressionLevel);
1525ZSTDLIB_STATIC_API size_t ZSTD_estimateCStreamSize_usingCParams(ZSTD_compressionParameters cParams);
1526ZSTDLIB_STATIC_API size_t ZSTD_estimateCStreamSize_usingCCtxParams(const ZSTD_CCtx_params* params);
1527ZSTDLIB_STATIC_API size_t ZSTD_estimateDStreamSize(size_t windowSize);
1528ZSTDLIB_STATIC_API size_t ZSTD_estimateDStreamSize_fromFrame(const void* src, size_t srcSize);
1529
1530/*! ZSTD_estimate?DictSize() :
1531 * ZSTD_estimateCDictSize() will bet that src size is relatively "small", and content is copied, like ZSTD_createCDict().
1532 * ZSTD_estimateCDictSize_advanced() makes it possible to control compression parameters precisely, like ZSTD_createCDict_advanced().
1533 * Note : dictionaries created by reference (`ZSTD_dlm_byRef`) are logically smaller.
1534 */
1535ZSTDLIB_STATIC_API size_t ZSTD_estimateCDictSize(size_t dictSize, int compressionLevel);
1536ZSTDLIB_STATIC_API size_t ZSTD_estimateCDictSize_advanced(size_t dictSize, ZSTD_compressionParameters cParams, ZSTD_dictLoadMethod_e dictLoadMethod);
1537ZSTDLIB_STATIC_API size_t ZSTD_estimateDDictSize(size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod);
1538
1539/*! ZSTD_initStatic*() :
1540 * Initialize an object using a pre-allocated fixed-size buffer.
1541 * workspace: The memory area to emplace the object into.
1542 * Provided pointer *must be 8-bytes aligned*.
1543 * Buffer must outlive object.
1544 * workspaceSize: Use ZSTD_estimate*Size() to determine
1545 * how large workspace must be to support target scenario.
1546 * @return : pointer to object (same address as workspace, just different type),
1547 * or NULL if error (size too small, incorrect alignment, etc.)
1548 * Note : zstd will never resize nor malloc() when using a static buffer.
1549 * If the object requires more memory than available,
1550 * zstd will just error out (typically ZSTD_error_memory_allocation).
1551 * Note 2 : there is no corresponding "free" function.
1552 * Since workspace is allocated externally, it must be freed externally too.
1553 * Note 3 : cParams : use ZSTD_getCParams() to convert a compression level
1554 * into its associated cParams.
1555 * Limitation 1 : currently not compatible with internal dictionary creation, triggered by
1556 * ZSTD_CCtx_loadDictionary(), ZSTD_initCStream_usingDict() or ZSTD_initDStream_usingDict().
1557 * Limitation 2 : static cctx currently not compatible with multi-threading.
1558 * Limitation 3 : static dctx is incompatible with legacy support.
1559 */
1560ZSTDLIB_STATIC_API ZSTD_CCtx* ZSTD_initStaticCCtx(void* workspace, size_t workspaceSize);
1561ZSTDLIB_STATIC_API ZSTD_CStream* ZSTD_initStaticCStream(void* workspace, size_t workspaceSize); /**< same as ZSTD_initStaticCCtx() */
1562
1563ZSTDLIB_STATIC_API ZSTD_DCtx* ZSTD_initStaticDCtx(void* workspace, size_t workspaceSize);
1564ZSTDLIB_STATIC_API ZSTD_DStream* ZSTD_initStaticDStream(void* workspace, size_t workspaceSize); /**< same as ZSTD_initStaticDCtx() */
1565
1566ZSTDLIB_STATIC_API const ZSTD_CDict* ZSTD_initStaticCDict(
1567 void* workspace, size_t workspaceSize,
1568 const void* dict, size_t dictSize,
1569 ZSTD_dictLoadMethod_e dictLoadMethod,
1570 ZSTD_dictContentType_e dictContentType,
1571 ZSTD_compressionParameters cParams);
1572
1573ZSTDLIB_STATIC_API const ZSTD_DDict* ZSTD_initStaticDDict(
1574 void* workspace, size_t workspaceSize,
1575 const void* dict, size_t dictSize,
1576 ZSTD_dictLoadMethod_e dictLoadMethod,
1577 ZSTD_dictContentType_e dictContentType);
1578
1579
1580/*! Custom memory allocation :
1581 * These prototypes make it possible to pass your own allocation/free functions.
1582 * ZSTD_customMem is provided at creation time, using ZSTD_create*_advanced() variants listed below.
1583 * All allocation/free operations will be completed using these custom variants instead of regular <stdlib.h> ones.
1584 */
1585typedef void* (*ZSTD_allocFunction) (void* opaque, size_t size);
1586typedef void (*ZSTD_freeFunction) (void* opaque, void* address);
1587typedef struct { ZSTD_allocFunction customAlloc; ZSTD_freeFunction customFree; void* opaque; } ZSTD_customMem;
1588static
1589#ifdef __GNUC__
1590__attribute__((__unused__))
1591#endif
1592ZSTD_customMem const ZSTD_defaultCMem = { NULL, NULL, NULL }; /**< this constant defers to stdlib's functions */
1593
1594ZSTDLIB_STATIC_API ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem);
1595ZSTDLIB_STATIC_API ZSTD_CStream* ZSTD_createCStream_advanced(ZSTD_customMem customMem);
1596ZSTDLIB_STATIC_API ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem);
1597ZSTDLIB_STATIC_API ZSTD_DStream* ZSTD_createDStream_advanced(ZSTD_customMem customMem);
1598
1599ZSTDLIB_STATIC_API ZSTD_CDict* ZSTD_createCDict_advanced(const void* dict, size_t dictSize,
1600 ZSTD_dictLoadMethod_e dictLoadMethod,
1601 ZSTD_dictContentType_e dictContentType,
1602 ZSTD_compressionParameters cParams,
1603 ZSTD_customMem customMem);
1604
1605/*! Thread pool :
1606 * These prototypes make it possible to share a thread pool among multiple compression contexts.
1607 * This can limit resources for applications with multiple threads where each one uses
1608 * a threaded compression mode (via ZSTD_c_nbWorkers parameter).
1609 * ZSTD_createThreadPool creates a new thread pool with a given number of threads.
1610 * Note that the lifetime of such pool must exist while being used.
1611 * ZSTD_CCtx_refThreadPool assigns a thread pool to a context (use NULL argument value
1612 * to use an internal thread pool).
1613 * ZSTD_freeThreadPool frees a thread pool, accepts NULL pointer.
1614 */
1615typedef struct POOL_ctx_s ZSTD_threadPool;
1616ZSTDLIB_STATIC_API ZSTD_threadPool* ZSTD_createThreadPool(size_t numThreads);
1617ZSTDLIB_STATIC_API void ZSTD_freeThreadPool (ZSTD_threadPool* pool); /* accept NULL pointer */
1618ZSTDLIB_STATIC_API size_t ZSTD_CCtx_refThreadPool(ZSTD_CCtx* cctx, ZSTD_threadPool* pool);
1619
1620
1621/*
1622 * This API is temporary and is expected to change or disappear in the future!
1623 */
1624ZSTDLIB_STATIC_API ZSTD_CDict* ZSTD_createCDict_advanced2(
1625 const void* dict, size_t dictSize,
1626 ZSTD_dictLoadMethod_e dictLoadMethod,
1627 ZSTD_dictContentType_e dictContentType,
1628 const ZSTD_CCtx_params* cctxParams,
1629 ZSTD_customMem customMem);
1630
1631ZSTDLIB_STATIC_API ZSTD_DDict* ZSTD_createDDict_advanced(
1632 const void* dict, size_t dictSize,
1633 ZSTD_dictLoadMethod_e dictLoadMethod,
1634 ZSTD_dictContentType_e dictContentType,
1635 ZSTD_customMem customMem);
1636
1637
1638/***************************************
1639* Advanced compression functions
1640***************************************/
1641
1642/*! ZSTD_createCDict_byReference() :
1643 * Create a digested dictionary for compression
1644 * Dictionary content is just referenced, not duplicated.
1645 * As a consequence, `dictBuffer` **must** outlive CDict,
1646 * and its content must remain unmodified throughout the lifetime of CDict.
1647 * note: equivalent to ZSTD_createCDict_advanced(), with dictLoadMethod==ZSTD_dlm_byRef */
1648ZSTDLIB_STATIC_API ZSTD_CDict* ZSTD_createCDict_byReference(const void* dictBuffer, size_t dictSize, int compressionLevel);
1649
1650/*! ZSTD_getCParams() :
1651 * @return ZSTD_compressionParameters structure for a selected compression level and estimated srcSize.
1652 * `estimatedSrcSize` value is optional, select 0 if not known */
1653ZSTDLIB_STATIC_API ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long long estimatedSrcSize, size_t dictSize);
1654
1655/*! ZSTD_getParams() :
1656 * same as ZSTD_getCParams(), but @return a full `ZSTD_parameters` object instead of sub-component `ZSTD_compressionParameters`.
1657 * All fields of `ZSTD_frameParameters` are set to default : contentSize=1, checksum=0, noDictID=0 */
1658ZSTDLIB_STATIC_API ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long estimatedSrcSize, size_t dictSize);
1659
1660/*! ZSTD_checkCParams() :
1661 * Ensure param values remain within authorized range.
1662 * @return 0 on success, or an error code (can be checked with ZSTD_isError()) */
1663ZSTDLIB_STATIC_API size_t ZSTD_checkCParams(ZSTD_compressionParameters params);
1664
1665/*! ZSTD_adjustCParams() :
1666 * optimize params for a given `srcSize` and `dictSize`.
1667 * `srcSize` can be unknown, in which case use ZSTD_CONTENTSIZE_UNKNOWN.
1668 * `dictSize` must be `0` when there is no dictionary.
1669 * cPar can be invalid : all parameters will be clamped within valid range in the @return struct.
1670 * This function never fails (wide contract) */
1671ZSTDLIB_STATIC_API ZSTD_compressionParameters ZSTD_adjustCParams(ZSTD_compressionParameters cPar, unsigned long long srcSize, size_t dictSize);
1672
1673/*! ZSTD_compress_advanced() :
1674 * Note : this function is now DEPRECATED.
1675 * It can be replaced by ZSTD_compress2(), in combination with ZSTD_CCtx_setParameter() and other parameter setters.
1676 * This prototype will generate compilation warnings. */
1677ZSTD_DEPRECATED("use ZSTD_compress2")
1678size_t ZSTD_compress_advanced(ZSTD_CCtx* cctx,
1679 void* dst, size_t dstCapacity,
1680 const void* src, size_t srcSize,
1681 const void* dict,size_t dictSize,
1682 ZSTD_parameters params);
1683
1684/*! ZSTD_compress_usingCDict_advanced() :
1685 * Note : this function is now DEPRECATED.
1686 * It can be replaced by ZSTD_compress2(), in combination with ZSTD_CCtx_loadDictionary() and other parameter setters.
1687 * This prototype will generate compilation warnings. */
1688ZSTD_DEPRECATED("use ZSTD_compress2 with ZSTD_CCtx_loadDictionary")
1689size_t ZSTD_compress_usingCDict_advanced(ZSTD_CCtx* cctx,
1690 void* dst, size_t dstCapacity,
1691 const void* src, size_t srcSize,
1692 const ZSTD_CDict* cdict,
1693 ZSTD_frameParameters fParams);
1694
1695
1696/*! ZSTD_CCtx_loadDictionary_byReference() :
1697 * Same as ZSTD_CCtx_loadDictionary(), but dictionary content is referenced, instead of being copied into CCtx.
1698 * It saves some memory, but also requires that `dict` outlives its usage within `cctx` */
1699ZSTDLIB_STATIC_API size_t ZSTD_CCtx_loadDictionary_byReference(ZSTD_CCtx* cctx, const void* dict, size_t dictSize);
1700
1701/*! ZSTD_CCtx_loadDictionary_advanced() :
1702 * Same as ZSTD_CCtx_loadDictionary(), but gives finer control over
1703 * how to load the dictionary (by copy ? by reference ?)
1704 * and how to interpret it (automatic ? force raw mode ? full mode only ?) */
1705ZSTDLIB_STATIC_API size_t ZSTD_CCtx_loadDictionary_advanced(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod, ZSTD_dictContentType_e dictContentType);
1706
1707/*! ZSTD_CCtx_refPrefix_advanced() :
1708 * Same as ZSTD_CCtx_refPrefix(), but gives finer control over
1709 * how to interpret prefix content (automatic ? force raw mode (default) ? full mode only ?) */
1710ZSTDLIB_STATIC_API size_t ZSTD_CCtx_refPrefix_advanced(ZSTD_CCtx* cctx, const void* prefix, size_t prefixSize, ZSTD_dictContentType_e dictContentType);
1711
1712/* === experimental parameters === */
1713/* these parameters can be used with ZSTD_setParameter()
1714 * they are not guaranteed to remain supported in the future */
1715
1716 /* Enables rsyncable mode,
1717 * which makes compressed files more rsync friendly
1718 * by adding periodic synchronization points to the compressed data.
1719 * The target average block size is ZSTD_c_jobSize / 2.
1720 * It's possible to modify the job size to increase or decrease
1721 * the granularity of the synchronization point.
1722 * Once the jobSize is smaller than the window size,
1723 * it will result in compression ratio degradation.
1724 * NOTE 1: rsyncable mode only works when multithreading is enabled.
1725 * NOTE 2: rsyncable performs poorly in combination with long range mode,
1726 * since it will decrease the effectiveness of synchronization points,
1727 * though mileage may vary.
1728 * NOTE 3: Rsyncable mode limits maximum compression speed to ~400 MB/s.
1729 * If the selected compression level is already running significantly slower,
1730 * the overall speed won't be significantly impacted.
1731 */
1732 #define ZSTD_c_rsyncable ZSTD_c_experimentalParam1
1733
1734/* Select a compression format.
1735 * The value must be of type ZSTD_format_e.
1736 * See ZSTD_format_e enum definition for details */
1737#define ZSTD_c_format ZSTD_c_experimentalParam2
1738
1739/* Force back-reference distances to remain < windowSize,
1740 * even when referencing into Dictionary content (default:0) */
1741#define ZSTD_c_forceMaxWindow ZSTD_c_experimentalParam3
1742
1743/* Controls whether the contents of a CDict
1744 * are used in place, or copied into the working context.
1745 * Accepts values from the ZSTD_dictAttachPref_e enum.
1746 * See the comments on that enum for an explanation of the feature. */
1747#define ZSTD_c_forceAttachDict ZSTD_c_experimentalParam4
1748
1749/* Controlled with ZSTD_paramSwitch_e enum.
1750 * Default is ZSTD_ps_auto.
1751 * Set to ZSTD_ps_disable to never compress literals.
1752 * Set to ZSTD_ps_enable to always compress literals. (Note: uncompressed literals
1753 * may still be emitted if huffman is not beneficial to use.)
1754 *
1755 * By default, in ZSTD_ps_auto, the library will decide at runtime whether to use
1756 * literals compression based on the compression parameters - specifically,
1757 * negative compression levels do not use literal compression.
1758 */
1759#define ZSTD_c_literalCompressionMode ZSTD_c_experimentalParam5
1760
1761/* Tries to fit compressed block size to be around targetCBlockSize.
1762 * No target when targetCBlockSize == 0.
1763 * There is no guarantee on compressed block size (default:0) */
1764#define ZSTD_c_targetCBlockSize ZSTD_c_experimentalParam6
1765
1766/* User's best guess of source size.
1767 * Hint is not valid when srcSizeHint == 0.
1768 * There is no guarantee that hint is close to actual source size,
1769 * but compression ratio may regress significantly if guess considerably underestimates */
1770#define ZSTD_c_srcSizeHint ZSTD_c_experimentalParam7
1771
1772/* Controls whether the new and experimental "dedicated dictionary search
1773 * structure" can be used. This feature is still rough around the edges, be
1774 * prepared for surprising behavior!
1775 *
1776 * How to use it:
1777 *
1778 * When using a CDict, whether to use this feature or not is controlled at
1779 * CDict creation, and it must be set in a CCtxParams set passed into that
1780 * construction (via ZSTD_createCDict_advanced2()). A compression will then
1781 * use the feature or not based on how the CDict was constructed; the value of
1782 * this param, set in the CCtx, will have no effect.
1783 *
1784 * However, when a dictionary buffer is passed into a CCtx, such as via
1785 * ZSTD_CCtx_loadDictionary(), this param can be set on the CCtx to control
1786 * whether the CDict that is created internally can use the feature or not.
1787 *
1788 * What it does:
1789 *
1790 * Normally, the internal data structures of the CDict are analogous to what
1791 * would be stored in a CCtx after compressing the contents of a dictionary.
1792 * To an approximation, a compression using a dictionary can then use those
1793 * data structures to simply continue what is effectively a streaming
1794 * compression where the simulated compression of the dictionary left off.
1795 * Which is to say, the search structures in the CDict are normally the same
1796 * format as in the CCtx.
1797 *
1798 * It is possible to do better, since the CDict is not like a CCtx: the search
1799 * structures are written once during CDict creation, and then are only read
1800 * after that, while the search structures in the CCtx are both read and
1801 * written as the compression goes along. This means we can choose a search
1802 * structure for the dictionary that is read-optimized.
1803 *
1804 * This feature enables the use of that different structure.
1805 *
1806 * Note that some of the members of the ZSTD_compressionParameters struct have
1807 * different semantics and constraints in the dedicated search structure. It is
1808 * highly recommended that you simply set a compression level in the CCtxParams
1809 * you pass into the CDict creation call, and avoid messing with the cParams
1810 * directly.
1811 *
1812 * Effects:
1813 *
1814 * This will only have any effect when the selected ZSTD_strategy
1815 * implementation supports this feature. Currently, that's limited to
1816 * ZSTD_greedy, ZSTD_lazy, and ZSTD_lazy2.
1817 *
1818 * Note that this means that the CDict tables can no longer be copied into the
1819 * CCtx, so the dict attachment mode ZSTD_dictForceCopy will no longer be
1820 * usable. The dictionary can only be attached or reloaded.
1821 *
1822 * In general, you should expect compression to be faster--sometimes very much
1823 * so--and CDict creation to be slightly slower. Eventually, we will probably
1824 * make this mode the default.
1825 */
1826#define ZSTD_c_enableDedicatedDictSearch ZSTD_c_experimentalParam8
1827
1828/* ZSTD_c_stableInBuffer
1829 * Experimental parameter.
1830 * Default is 0 == disabled. Set to 1 to enable.
1831 *
1832 * Tells the compressor that the ZSTD_inBuffer will ALWAYS be the same
1833 * between calls, except for the modifications that zstd makes to pos (the
1834 * caller must not modify pos). This is checked by the compressor, and
1835 * compression will fail if it ever changes. This means the only flush
1836 * mode that makes sense is ZSTD_e_end, so zstd will error if ZSTD_e_end
1837 * is not used. The data in the ZSTD_inBuffer in the range [src, src + pos)
1838 * MUST not be modified during compression or you will get data corruption.
1839 *
1840 * When this flag is enabled zstd won't allocate an input window buffer,
1841 * because the user guarantees it can reference the ZSTD_inBuffer until
1842 * the frame is complete. But, it will still allocate an output buffer
1843 * large enough to fit a block (see ZSTD_c_stableOutBuffer). This will also
1844 * avoid the memcpy() from the input buffer to the input window buffer.
1845 *
1846 * NOTE: ZSTD_compressStream2() will error if ZSTD_e_end is not used.
1847 * That means this flag cannot be used with ZSTD_compressStream().
1848 *
1849 * NOTE: So long as the ZSTD_inBuffer always points to valid memory, using
1850 * this flag is ALWAYS memory safe, and will never access out-of-bounds
1851 * memory. However, compression WILL fail if you violate the preconditions.
1852 *
1853 * WARNING: The data in the ZSTD_inBuffer in the range [dst, dst + pos) MUST
1854 * not be modified during compression or you will get data corruption. This
1855 * is because zstd needs to reference data in the ZSTD_inBuffer to find
1856 * matches. Normally zstd maintains its own window buffer for this purpose,
1857 * but passing this flag tells zstd to use the user provided buffer.
1858 */
1859#define ZSTD_c_stableInBuffer ZSTD_c_experimentalParam9
1860
1861/* ZSTD_c_stableOutBuffer
1862 * Experimental parameter.
1863 * Default is 0 == disabled. Set to 1 to enable.
1864 *
1865 * Tells he compressor that the ZSTD_outBuffer will not be resized between
1866 * calls. Specifically: (out.size - out.pos) will never grow. This gives the
1867 * compressor the freedom to say: If the compressed data doesn't fit in the
1868 * output buffer then return ZSTD_error_dstSizeTooSmall. This allows us to
1869 * always decompress directly into the output buffer, instead of decompressing
1870 * into an internal buffer and copying to the output buffer.
1871 *
1872 * When this flag is enabled zstd won't allocate an output buffer, because
1873 * it can write directly to the ZSTD_outBuffer. It will still allocate the
1874 * input window buffer (see ZSTD_c_stableInBuffer).
1875 *
1876 * Zstd will check that (out.size - out.pos) never grows and return an error
1877 * if it does. While not strictly necessary, this should prevent surprises.
1878 */
1879#define ZSTD_c_stableOutBuffer ZSTD_c_experimentalParam10
1880
1881/* ZSTD_c_blockDelimiters
1882 * Default is 0 == ZSTD_sf_noBlockDelimiters.
1883 *
1884 * For use with sequence compression API: ZSTD_compressSequences().
1885 *
1886 * Designates whether or not the given array of ZSTD_Sequence contains block delimiters
1887 * and last literals, which are defined as sequences with offset == 0 and matchLength == 0.
1888 * See the definition of ZSTD_Sequence for more specifics.
1889 */
1890#define ZSTD_c_blockDelimiters ZSTD_c_experimentalParam11
1891
1892/* ZSTD_c_validateSequences
1893 * Default is 0 == disabled. Set to 1 to enable sequence validation.
1894 *
1895 * For use with sequence compression API: ZSTD_compressSequences().
1896 * Designates whether or not we validate sequences provided to ZSTD_compressSequences()
1897 * during function execution.
1898 *
1899 * Without validation, providing a sequence that does not conform to the zstd spec will cause
1900 * undefined behavior, and may produce a corrupted block.
1901 *
1902 * With validation enabled, a if sequence is invalid (see doc/zstd_compression_format.md for
1903 * specifics regarding offset/matchlength requirements) then the function will bail out and
1904 * return an error.
1905 *
1906 */
1907#define ZSTD_c_validateSequences ZSTD_c_experimentalParam12
1908
1909/* ZSTD_c_useBlockSplitter
1910 * Controlled with ZSTD_paramSwitch_e enum.
1911 * Default is ZSTD_ps_auto.
1912 * Set to ZSTD_ps_disable to never use block splitter.
1913 * Set to ZSTD_ps_enable to always use block splitter.
1914 *
1915 * By default, in ZSTD_ps_auto, the library will decide at runtime whether to use
1916 * block splitting based on the compression parameters.
1917 */
1918#define ZSTD_c_useBlockSplitter ZSTD_c_experimentalParam13
1919
1920/* ZSTD_c_useRowMatchFinder
1921 * Controlled with ZSTD_paramSwitch_e enum.
1922 * Default is ZSTD_ps_auto.
1923 * Set to ZSTD_ps_disable to never use row-based matchfinder.
1924 * Set to ZSTD_ps_enable to force usage of row-based matchfinder.
1925 *
1926 * By default, in ZSTD_ps_auto, the library will decide at runtime whether to use
1927 * the row-based matchfinder based on support for SIMD instructions and the window log.
1928 * Note that this only pertains to compression strategies: greedy, lazy, and lazy2
1929 */
1930#define ZSTD_c_useRowMatchFinder ZSTD_c_experimentalParam14
1931
1932/* ZSTD_c_deterministicRefPrefix
1933 * Default is 0 == disabled. Set to 1 to enable.
1934 *
1935 * Zstd produces different results for prefix compression when the prefix is
1936 * directly adjacent to the data about to be compressed vs. when it isn't.
1937 * This is because zstd detects that the two buffers are contiguous and it can
1938 * use a more efficient match finding algorithm. However, this produces different
1939 * results than when the two buffers are non-contiguous. This flag forces zstd
1940 * to always load the prefix in non-contiguous mode, even if it happens to be
1941 * adjacent to the data, to guarantee determinism.
1942 *
1943 * If you really care about determinism when using a dictionary or prefix,
1944 * like when doing delta compression, you should select this option. It comes
1945 * at a speed penalty of about ~2.5% if the dictionary and data happened to be
1946 * contiguous, and is free if they weren't contiguous. We don't expect that
1947 * intentionally making the dictionary and data contiguous will be worth the
1948 * cost to memcpy() the data.
1949 */
1950#define ZSTD_c_deterministicRefPrefix ZSTD_c_experimentalParam15
1951
1952/*! ZSTD_CCtx_getParameter() :
1953 * Get the requested compression parameter value, selected by enum ZSTD_cParameter,
1954 * and store it into int* value.
1955 * @return : 0, or an error code (which can be tested with ZSTD_isError()).
1956 */
1957ZSTDLIB_STATIC_API size_t ZSTD_CCtx_getParameter(const ZSTD_CCtx* cctx, ZSTD_cParameter param, int* value);
1958
1959
1960/*! ZSTD_CCtx_params :
1961 * Quick howto :
1962 * - ZSTD_createCCtxParams() : Create a ZSTD_CCtx_params structure
1963 * - ZSTD_CCtxParams_setParameter() : Push parameters one by one into
1964 * an existing ZSTD_CCtx_params structure.
1965 * This is similar to
1966 * ZSTD_CCtx_setParameter().
1967 * - ZSTD_CCtx_setParametersUsingCCtxParams() : Apply parameters to
1968 * an existing CCtx.
1969 * These parameters will be applied to
1970 * all subsequent frames.
1971 * - ZSTD_compressStream2() : Do compression using the CCtx.
1972 * - ZSTD_freeCCtxParams() : Free the memory, accept NULL pointer.
1973 *
1974 * This can be used with ZSTD_estimateCCtxSize_advanced_usingCCtxParams()
1975 * for static allocation of CCtx for single-threaded compression.
1976 */
1977ZSTDLIB_STATIC_API ZSTD_CCtx_params* ZSTD_createCCtxParams(void);
1978ZSTDLIB_STATIC_API size_t ZSTD_freeCCtxParams(ZSTD_CCtx_params* params); /* accept NULL pointer */
1979
1980/*! ZSTD_CCtxParams_reset() :
1981 * Reset params to default values.
1982 */
1983ZSTDLIB_STATIC_API size_t ZSTD_CCtxParams_reset(ZSTD_CCtx_params* params);
1984
1985/*! ZSTD_CCtxParams_init() :
1986 * Initializes the compression parameters of cctxParams according to
1987 * compression level. All other parameters are reset to their default values.
1988 */
1989ZSTDLIB_STATIC_API size_t ZSTD_CCtxParams_init(ZSTD_CCtx_params* cctxParams, int compressionLevel);
1990
1991/*! ZSTD_CCtxParams_init_advanced() :
1992 * Initializes the compression and frame parameters of cctxParams according to
1993 * params. All other parameters are reset to their default values.
1994 */
1995ZSTDLIB_STATIC_API size_t ZSTD_CCtxParams_init_advanced(ZSTD_CCtx_params* cctxParams, ZSTD_parameters params);
1996
1997/*! ZSTD_CCtxParams_setParameter() : Requires v1.4.0+
1998 * Similar to ZSTD_CCtx_setParameter.
1999 * Set one compression parameter, selected by enum ZSTD_cParameter.
2000 * Parameters must be applied to a ZSTD_CCtx using
2001 * ZSTD_CCtx_setParametersUsingCCtxParams().
2002 * @result : a code representing success or failure (which can be tested with
2003 * ZSTD_isError()).
2004 */
2005ZSTDLIB_STATIC_API size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* params, ZSTD_cParameter param, int value);
2006
2007/*! ZSTD_CCtxParams_getParameter() :
2008 * Similar to ZSTD_CCtx_getParameter.
2009 * Get the requested value of one compression parameter, selected by enum ZSTD_cParameter.
2010 * @result : 0, or an error code (which can be tested with ZSTD_isError()).
2011 */
2012ZSTDLIB_STATIC_API size_t ZSTD_CCtxParams_getParameter(const ZSTD_CCtx_params* params, ZSTD_cParameter param, int* value);
2013
2014/*! ZSTD_CCtx_setParametersUsingCCtxParams() :
2015 * Apply a set of ZSTD_CCtx_params to the compression context.
2016 * This can be done even after compression is started,
2017 * if nbWorkers==0, this will have no impact until a new compression is started.
2018 * if nbWorkers>=1, new parameters will be picked up at next job,
2019 * with a few restrictions (windowLog, pledgedSrcSize, nbWorkers, jobSize, and overlapLog are not updated).
2020 */
2021ZSTDLIB_STATIC_API size_t ZSTD_CCtx_setParametersUsingCCtxParams(
2022 ZSTD_CCtx* cctx, const ZSTD_CCtx_params* params);
2023
2024/*! ZSTD_compressStream2_simpleArgs() :
2025 * Same as ZSTD_compressStream2(),
2026 * but using only integral types as arguments.
2027 * This variant might be helpful for binders from dynamic languages
2028 * which have troubles handling structures containing memory pointers.
2029 */
2030ZSTDLIB_STATIC_API size_t ZSTD_compressStream2_simpleArgs (
2031 ZSTD_CCtx* cctx,
2032 void* dst, size_t dstCapacity, size_t* dstPos,
2033 const void* src, size_t srcSize, size_t* srcPos,
2034 ZSTD_EndDirective endOp);
2035
2036
2037/***************************************
2038* Advanced decompression functions
2039***************************************/
2040
2041/*! ZSTD_isFrame() :
2042 * Tells if the content of `buffer` starts with a valid Frame Identifier.
2043 * Note : Frame Identifier is 4 bytes. If `size < 4`, @return will always be 0.
2044 * Note 2 : Legacy Frame Identifiers are considered valid only if Legacy Support is enabled.
2045 * Note 3 : Skippable Frame Identifiers are considered valid. */
2046ZSTDLIB_STATIC_API unsigned ZSTD_isFrame(const void* buffer, size_t size);
2047
2048/*! ZSTD_createDDict_byReference() :
2049 * Create a digested dictionary, ready to start decompression operation without startup delay.
2050 * Dictionary content is referenced, and therefore stays in dictBuffer.
2051 * It is important that dictBuffer outlives DDict,
2052 * it must remain read accessible throughout the lifetime of DDict */
2053ZSTDLIB_STATIC_API ZSTD_DDict* ZSTD_createDDict_byReference(const void* dictBuffer, size_t dictSize);
2054
2055/*! ZSTD_DCtx_loadDictionary_byReference() :
2056 * Same as ZSTD_DCtx_loadDictionary(),
2057 * but references `dict` content instead of copying it into `dctx`.
2058 * This saves memory if `dict` remains around.,
2059 * However, it's imperative that `dict` remains accessible (and unmodified) while being used, so it must outlive decompression. */
2060ZSTDLIB_STATIC_API size_t ZSTD_DCtx_loadDictionary_byReference(ZSTD_DCtx* dctx, const void* dict, size_t dictSize);
2061
2062/*! ZSTD_DCtx_loadDictionary_advanced() :
2063 * Same as ZSTD_DCtx_loadDictionary(),
2064 * but gives direct control over
2065 * how to load the dictionary (by copy ? by reference ?)
2066 * and how to interpret it (automatic ? force raw mode ? full mode only ?). */
2067ZSTDLIB_STATIC_API size_t ZSTD_DCtx_loadDictionary_advanced(ZSTD_DCtx* dctx, const void* dict, size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod, ZSTD_dictContentType_e dictContentType);
2068
2069/*! ZSTD_DCtx_refPrefix_advanced() :
2070 * Same as ZSTD_DCtx_refPrefix(), but gives finer control over
2071 * how to interpret prefix content (automatic ? force raw mode (default) ? full mode only ?) */
2072ZSTDLIB_STATIC_API size_t ZSTD_DCtx_refPrefix_advanced(ZSTD_DCtx* dctx, const void* prefix, size_t prefixSize, ZSTD_dictContentType_e dictContentType);
2073
2074/*! ZSTD_DCtx_setMaxWindowSize() :
2075 * Refuses allocating internal buffers for frames requiring a window size larger than provided limit.
2076 * This protects a decoder context from reserving too much memory for itself (potential attack scenario).
2077 * This parameter is only useful in streaming mode, since no internal buffer is allocated in single-pass mode.
2078 * By default, a decompression context accepts all window sizes <= (1 << ZSTD_WINDOWLOG_LIMIT_DEFAULT)
2079 * @return : 0, or an error code (which can be tested using ZSTD_isError()).
2080 */
2081ZSTDLIB_STATIC_API size_t ZSTD_DCtx_setMaxWindowSize(ZSTD_DCtx* dctx, size_t maxWindowSize);
2082
2083/*! ZSTD_DCtx_getParameter() :
2084 * Get the requested decompression parameter value, selected by enum ZSTD_dParameter,
2085 * and store it into int* value.
2086 * @return : 0, or an error code (which can be tested with ZSTD_isError()).
2087 */
2088ZSTDLIB_STATIC_API size_t ZSTD_DCtx_getParameter(ZSTD_DCtx* dctx, ZSTD_dParameter param, int* value);
2089
2090/* ZSTD_d_format
2091 * experimental parameter,
2092 * allowing selection between ZSTD_format_e input compression formats
2093 */
2094#define ZSTD_d_format ZSTD_d_experimentalParam1
2095/* ZSTD_d_stableOutBuffer
2096 * Experimental parameter.
2097 * Default is 0 == disabled. Set to 1 to enable.
2098 *
2099 * Tells the decompressor that the ZSTD_outBuffer will ALWAYS be the same
2100 * between calls, except for the modifications that zstd makes to pos (the
2101 * caller must not modify pos). This is checked by the decompressor, and
2102 * decompression will fail if it ever changes. Therefore the ZSTD_outBuffer
2103 * MUST be large enough to fit the entire decompressed frame. This will be
2104 * checked when the frame content size is known. The data in the ZSTD_outBuffer
2105 * in the range [dst, dst + pos) MUST not be modified during decompression
2106 * or you will get data corruption.
2107 *
2108 * When this flags is enabled zstd won't allocate an output buffer, because
2109 * it can write directly to the ZSTD_outBuffer, but it will still allocate
2110 * an input buffer large enough to fit any compressed block. This will also
2111 * avoid the memcpy() from the internal output buffer to the ZSTD_outBuffer.
2112 * If you need to avoid the input buffer allocation use the buffer-less
2113 * streaming API.
2114 *
2115 * NOTE: So long as the ZSTD_outBuffer always points to valid memory, using
2116 * this flag is ALWAYS memory safe, and will never access out-of-bounds
2117 * memory. However, decompression WILL fail if you violate the preconditions.
2118 *
2119 * WARNING: The data in the ZSTD_outBuffer in the range [dst, dst + pos) MUST
2120 * not be modified during decompression or you will get data corruption. This
2121 * is because zstd needs to reference data in the ZSTD_outBuffer to regenerate
2122 * matches. Normally zstd maintains its own buffer for this purpose, but passing
2123 * this flag tells zstd to use the user provided buffer.
2124 */
2125#define ZSTD_d_stableOutBuffer ZSTD_d_experimentalParam2
2126
2127/* ZSTD_d_forceIgnoreChecksum
2128 * Experimental parameter.
2129 * Default is 0 == disabled. Set to 1 to enable
2130 *
2131 * Tells the decompressor to skip checksum validation during decompression, regardless
2132 * of whether checksumming was specified during compression. This offers some
2133 * slight performance benefits, and may be useful for debugging.
2134 * Param has values of type ZSTD_forceIgnoreChecksum_e
2135 */
2136#define ZSTD_d_forceIgnoreChecksum ZSTD_d_experimentalParam3
2137
2138/* ZSTD_d_refMultipleDDicts
2139 * Experimental parameter.
2140 * Default is 0 == disabled. Set to 1 to enable
2141 *
2142 * If enabled and dctx is allocated on the heap, then additional memory will be allocated
2143 * to store references to multiple ZSTD_DDict. That is, multiple calls of ZSTD_refDDict()
2144 * using a given ZSTD_DCtx, rather than overwriting the previous DDict reference, will instead
2145 * store all references. At decompression time, the appropriate dictID is selected
2146 * from the set of DDicts based on the dictID in the frame.
2147 *
2148 * Usage is simply calling ZSTD_refDDict() on multiple dict buffers.
2149 *
2150 * Param has values of byte ZSTD_refMultipleDDicts_e
2151 *
2152 * WARNING: Enabling this parameter and calling ZSTD_DCtx_refDDict(), will trigger memory
2153 * allocation for the hash table. ZSTD_freeDCtx() also frees this memory.
2154 * Memory is allocated as per ZSTD_DCtx::customMem.
2155 *
2156 * Although this function allocates memory for the table, the user is still responsible for
2157 * memory management of the underlying ZSTD_DDict* themselves.
2158 */
2159#define ZSTD_d_refMultipleDDicts ZSTD_d_experimentalParam4
2160
2161
2162/*! ZSTD_DCtx_setFormat() :
2163 * This function is REDUNDANT. Prefer ZSTD_DCtx_setParameter().
2164 * Instruct the decoder context about what kind of data to decode next.
2165 * This instruction is mandatory to decode data without a fully-formed header,
2166 * such ZSTD_f_zstd1_magicless for example.
2167 * @return : 0, or an error code (which can be tested using ZSTD_isError()). */
2168ZSTD_DEPRECATED("use ZSTD_DCtx_setParameter() instead")
2169size_t ZSTD_DCtx_setFormat(ZSTD_DCtx* dctx, ZSTD_format_e format);
2170
2171/*! ZSTD_decompressStream_simpleArgs() :
2172 * Same as ZSTD_decompressStream(),
2173 * but using only integral types as arguments.
2174 * This can be helpful for binders from dynamic languages
2175 * which have troubles handling structures containing memory pointers.
2176 */
2177ZSTDLIB_STATIC_API size_t ZSTD_decompressStream_simpleArgs (
2178 ZSTD_DCtx* dctx,
2179 void* dst, size_t dstCapacity, size_t* dstPos,
2180 const void* src, size_t srcSize, size_t* srcPos);
2181
2182
2183/********************************************************************
2184* Advanced streaming functions
2185* Warning : most of these functions are now redundant with the Advanced API.
2186* Once Advanced API reaches "stable" status,
2187* redundant functions will be deprecated, and then at some point removed.
2188********************************************************************/
2189
2190/*===== Advanced Streaming compression functions =====*/
2191
2192/*! ZSTD_initCStream_srcSize() :
2193 * This function is DEPRECATED, and equivalent to:
2194 * ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only);
2195 * ZSTD_CCtx_refCDict(zcs, NULL); // clear the dictionary (if any)
2196 * ZSTD_CCtx_setParameter(zcs, ZSTD_c_compressionLevel, compressionLevel);
2197 * ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize);
2198 *
2199 * pledgedSrcSize must be correct. If it is not known at init time, use
2200 * ZSTD_CONTENTSIZE_UNKNOWN. Note that, for compatibility with older programs,
2201 * "0" also disables frame content size field. It may be enabled in the future.
2202 * This prototype will generate compilation warnings.
2203 */
2204ZSTD_DEPRECATED("use ZSTD_CCtx_reset, see zstd.h for detailed instructions")
2205size_t ZSTD_initCStream_srcSize(ZSTD_CStream* zcs,
2206 int compressionLevel,
2207 unsigned long long pledgedSrcSize);
2208
2209/*! ZSTD_initCStream_usingDict() :
2210 * This function is DEPRECATED, and is equivalent to:
2211 * ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only);
2212 * ZSTD_CCtx_setParameter(zcs, ZSTD_c_compressionLevel, compressionLevel);
2213 * ZSTD_CCtx_loadDictionary(zcs, dict, dictSize);
2214 *
2215 * Creates of an internal CDict (incompatible with static CCtx), except if
2216 * dict == NULL or dictSize < 8, in which case no dict is used.
2217 * Note: dict is loaded with ZSTD_dct_auto (treated as a full zstd dictionary if
2218 * it begins with ZSTD_MAGIC_DICTIONARY, else as raw content) and ZSTD_dlm_byCopy.
2219 * This prototype will generate compilation warnings.
2220 */
2221ZSTD_DEPRECATED("use ZSTD_CCtx_reset, see zstd.h for detailed instructions")
2222size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs,
2223 const void* dict, size_t dictSize,
2224 int compressionLevel);
2225
2226/*! ZSTD_initCStream_advanced() :
2227 * This function is DEPRECATED, and is approximately equivalent to:
2228 * ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only);
2229 * // Pseudocode: Set each zstd parameter and leave the rest as-is.
2230 * for ((param, value) : params) {
2231 * ZSTD_CCtx_setParameter(zcs, param, value);
2232 * }
2233 * ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize);
2234 * ZSTD_CCtx_loadDictionary(zcs, dict, dictSize);
2235 *
2236 * dict is loaded with ZSTD_dct_auto and ZSTD_dlm_byCopy.
2237 * pledgedSrcSize must be correct.
2238 * If srcSize is not known at init time, use value ZSTD_CONTENTSIZE_UNKNOWN.
2239 * This prototype will generate compilation warnings.
2240 */
2241ZSTD_DEPRECATED("use ZSTD_CCtx_reset, see zstd.h for detailed instructions")
2242size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs,
2243 const void* dict, size_t dictSize,
2244 ZSTD_parameters params,
2245 unsigned long long pledgedSrcSize);
2246
2247/*! ZSTD_initCStream_usingCDict() :
2248 * This function is DEPRECATED, and equivalent to:
2249 * ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only);
2250 * ZSTD_CCtx_refCDict(zcs, cdict);
2251 *
2252 * note : cdict will just be referenced, and must outlive compression session
2253 * This prototype will generate compilation warnings.
2254 */
2255ZSTD_DEPRECATED("use ZSTD_CCtx_reset and ZSTD_CCtx_refCDict, see zstd.h for detailed instructions")
2256size_t ZSTD_initCStream_usingCDict(ZSTD_CStream* zcs, const ZSTD_CDict* cdict);
2257
2258/*! ZSTD_initCStream_usingCDict_advanced() :
2259 * This function is DEPRECATED, and is approximately equivalent to:
2260 * ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only);
2261 * // Pseudocode: Set each zstd frame parameter and leave the rest as-is.
2262 * for ((fParam, value) : fParams) {
2263 * ZSTD_CCtx_setParameter(zcs, fParam, value);
2264 * }
2265 * ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize);
2266 * ZSTD_CCtx_refCDict(zcs, cdict);
2267 *
2268 * same as ZSTD_initCStream_usingCDict(), with control over frame parameters.
2269 * pledgedSrcSize must be correct. If srcSize is not known at init time, use
2270 * value ZSTD_CONTENTSIZE_UNKNOWN.
2271 * This prototype will generate compilation warnings.
2272 */
2273ZSTD_DEPRECATED("use ZSTD_CCtx_reset and ZSTD_CCtx_refCDict, see zstd.h for detailed instructions")
2274size_t ZSTD_initCStream_usingCDict_advanced(ZSTD_CStream* zcs,
2275 const ZSTD_CDict* cdict,
2276 ZSTD_frameParameters fParams,
2277 unsigned long long pledgedSrcSize);
2278
2279/*! ZSTD_resetCStream() :
2280 * This function is DEPRECATED, and is equivalent to:
2281 * ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only);
2282 * ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize);
2283 * Note: ZSTD_resetCStream() interprets pledgedSrcSize == 0 as ZSTD_CONTENTSIZE_UNKNOWN, but
2284 * ZSTD_CCtx_setPledgedSrcSize() does not do the same, so ZSTD_CONTENTSIZE_UNKNOWN must be
2285 * explicitly specified.
2286 *
2287 * start a new frame, using same parameters from previous frame.
2288 * This is typically useful to skip dictionary loading stage, since it will re-use it in-place.
2289 * Note that zcs must be init at least once before using ZSTD_resetCStream().
2290 * If pledgedSrcSize is not known at reset time, use macro ZSTD_CONTENTSIZE_UNKNOWN.
2291 * If pledgedSrcSize > 0, its value must be correct, as it will be written in header, and controlled at the end.
2292 * For the time being, pledgedSrcSize==0 is interpreted as "srcSize unknown" for compatibility with older programs,
2293 * but it will change to mean "empty" in future version, so use macro ZSTD_CONTENTSIZE_UNKNOWN instead.
2294 * @return : 0, or an error code (which can be tested using ZSTD_isError())
2295 * This prototype will generate compilation warnings.
2296 */
2297ZSTD_DEPRECATED("use ZSTD_CCtx_reset, see zstd.h for detailed instructions")
2298size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize);
2299
2300
2301typedef struct {
2302 unsigned long long ingested; /* nb input bytes read and buffered */
2303 unsigned long long consumed; /* nb input bytes actually compressed */
2304 unsigned long long produced; /* nb of compressed bytes generated and buffered */
2305 unsigned long long flushed; /* nb of compressed bytes flushed : not provided; can be tracked from caller side */
2306 unsigned currentJobID; /* MT only : latest started job nb */
2307 unsigned nbActiveWorkers; /* MT only : nb of workers actively compressing at probe time */
2308} ZSTD_frameProgression;
2309
2310/* ZSTD_getFrameProgression() :
2311 * tells how much data has been ingested (read from input)
2312 * consumed (input actually compressed) and produced (output) for current frame.
2313 * Note : (ingested - consumed) is amount of input data buffered internally, not yet compressed.
2314 * Aggregates progression inside active worker threads.
2315 */
2316ZSTDLIB_STATIC_API ZSTD_frameProgression ZSTD_getFrameProgression(const ZSTD_CCtx* cctx);
2317
2318/*! ZSTD_toFlushNow() :
2319 * Tell how many bytes are ready to be flushed immediately.
2320 * Useful for multithreading scenarios (nbWorkers >= 1).
2321 * Probe the oldest active job, defined as oldest job not yet entirely flushed,
2322 * and check its output buffer.
2323 * @return : amount of data stored in oldest job and ready to be flushed immediately.
2324 * if @return == 0, it means either :
2325 * + there is no active job (could be checked with ZSTD_frameProgression()), or
2326 * + oldest job is still actively compressing data,
2327 * but everything it has produced has also been flushed so far,
2328 * therefore flush speed is limited by production speed of oldest job
2329 * irrespective of the speed of concurrent (and newer) jobs.
2330 */
2331ZSTDLIB_STATIC_API size_t ZSTD_toFlushNow(ZSTD_CCtx* cctx);
2332
2333
2334/*===== Advanced Streaming decompression functions =====*/
2335
2336/*!
2337 * This function is deprecated, and is equivalent to:
2338 *
2339 * ZSTD_DCtx_reset(zds, ZSTD_reset_session_only);
2340 * ZSTD_DCtx_loadDictionary(zds, dict, dictSize);
2341 *
2342 * note: no dictionary will be used if dict == NULL or dictSize < 8
2343 * Note : this prototype will be marked as deprecated and generate compilation warnings on reaching v1.5.x
2344 */
2345ZSTDLIB_STATIC_API size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dict, size_t dictSize);
2346
2347/*!
2348 * This function is deprecated, and is equivalent to:
2349 *
2350 * ZSTD_DCtx_reset(zds, ZSTD_reset_session_only);
2351 * ZSTD_DCtx_refDDict(zds, ddict);
2352 *
2353 * note : ddict is referenced, it must outlive decompression session
2354 * Note : this prototype will be marked as deprecated and generate compilation warnings on reaching v1.5.x
2355 */
2356ZSTDLIB_STATIC_API size_t ZSTD_initDStream_usingDDict(ZSTD_DStream* zds, const ZSTD_DDict* ddict);
2357
2358/*!
2359 * This function is deprecated, and is equivalent to:
2360 *
2361 * ZSTD_DCtx_reset(zds, ZSTD_reset_session_only);
2362 *
2363 * re-use decompression parameters from previous init; saves dictionary loading
2364 * Note : this prototype will be marked as deprecated and generate compilation warnings on reaching v1.5.x
2365 */
2366ZSTDLIB_STATIC_API size_t ZSTD_resetDStream(ZSTD_DStream* zds);
2367
2368
2369/*********************************************************************
2370* Buffer-less and synchronous inner streaming functions
2371*
2372* This is an advanced API, giving full control over buffer management, for users which need direct control over memory.
2373* But it's also a complex one, with several restrictions, documented below.
2374* Prefer normal streaming API for an easier experience.
2375********************************************************************* */
2376
2377/**
2378 Buffer-less streaming compression (synchronous mode)
2379
2380 A ZSTD_CCtx object is required to track streaming operations.
2381 Use ZSTD_createCCtx() / ZSTD_freeCCtx() to manage resource.
2382 ZSTD_CCtx object can be re-used multiple times within successive compression operations.
2383
2384 Start by initializing a context.
2385 Use ZSTD_compressBegin(), or ZSTD_compressBegin_usingDict() for dictionary compression.
2386 It's also possible to duplicate a reference context which has already been initialized, using ZSTD_copyCCtx()
2387
2388 Then, consume your input using ZSTD_compressContinue().
2389 There are some important considerations to keep in mind when using this advanced function :
2390 - ZSTD_compressContinue() has no internal buffer. It uses externally provided buffers only.
2391 - Interface is synchronous : input is consumed entirely and produces 1+ compressed blocks.
2392 - Caller must ensure there is enough space in `dst` to store compressed data under worst case scenario.
2393 Worst case evaluation is provided by ZSTD_compressBound().
2394 ZSTD_compressContinue() doesn't guarantee recover after a failed compression.
2395 - ZSTD_compressContinue() presumes prior input ***is still accessible and unmodified*** (up to maximum distance size, see WindowLog).
2396 It remembers all previous contiguous blocks, plus one separated memory segment (which can itself consists of multiple contiguous blocks)
2397 - ZSTD_compressContinue() detects that prior input has been overwritten when `src` buffer overlaps.
2398 In which case, it will "discard" the relevant memory section from its history.
2399
2400 Finish a frame with ZSTD_compressEnd(), which will write the last block(s) and optional checksum.
2401 It's possible to use srcSize==0, in which case, it will write a final empty block to end the frame.
2402 Without last block mark, frames are considered unfinished (hence corrupted) by compliant decoders.
2403
2404 `ZSTD_CCtx` object can be re-used (ZSTD_compressBegin()) to compress again.
2405*/
2406
2407/*===== Buffer-less streaming compression functions =====*/
2408ZSTDLIB_STATIC_API size_t ZSTD_compressBegin(ZSTD_CCtx* cctx, int compressionLevel);
2409ZSTDLIB_STATIC_API size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel);
2410ZSTDLIB_STATIC_API size_t ZSTD_compressBegin_usingCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict); /**< note: fails if cdict==NULL */
2411ZSTDLIB_STATIC_API size_t ZSTD_copyCCtx(ZSTD_CCtx* cctx, const ZSTD_CCtx* preparedCCtx, unsigned long long pledgedSrcSize); /**< note: if pledgedSrcSize is not known, use ZSTD_CONTENTSIZE_UNKNOWN */
2412
2413ZSTDLIB_STATIC_API size_t ZSTD_compressContinue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
2414ZSTDLIB_STATIC_API size_t ZSTD_compressEnd(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
2415
2416/* The ZSTD_compressBegin_advanced() and ZSTD_compressBegin_usingCDict_advanced() are now DEPRECATED and will generate a compiler warning */
2417ZSTD_DEPRECATED("use advanced API to access custom parameters")
2418size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, ZSTD_parameters params, unsigned long long pledgedSrcSize); /**< pledgedSrcSize : If srcSize is not known at init time, use ZSTD_CONTENTSIZE_UNKNOWN */
2419ZSTD_DEPRECATED("use advanced API to access custom parameters")
2420size_t ZSTD_compressBegin_usingCDict_advanced(ZSTD_CCtx* const cctx, const ZSTD_CDict* const cdict, ZSTD_frameParameters const fParams, unsigned long long const pledgedSrcSize); /* compression parameters are already set within cdict. pledgedSrcSize must be correct. If srcSize is not known, use macro ZSTD_CONTENTSIZE_UNKNOWN */
2421/**
2422 Buffer-less streaming decompression (synchronous mode)
2423
2424 A ZSTD_DCtx object is required to track streaming operations.
2425 Use ZSTD_createDCtx() / ZSTD_freeDCtx() to manage it.
2426 A ZSTD_DCtx object can be re-used multiple times.
2427
2428 First typical operation is to retrieve frame parameters, using ZSTD_getFrameHeader().
2429 Frame header is extracted from the beginning of compressed frame, so providing only the frame's beginning is enough.
2430 Data fragment must be large enough to ensure successful decoding.
2431 `ZSTD_frameHeaderSize_max` bytes is guaranteed to always be large enough.
2432 @result : 0 : successful decoding, the `ZSTD_frameHeader` structure is correctly filled.
2433 >0 : `srcSize` is too small, please provide at least @result bytes on next attempt.
2434 errorCode, which can be tested using ZSTD_isError().
2435
2436 It fills a ZSTD_frameHeader structure with important information to correctly decode the frame,
2437 such as the dictionary ID, content size, or maximum back-reference distance (`windowSize`).
2438 Note that these values could be wrong, either because of data corruption, or because a 3rd party deliberately spoofs false information.
2439 As a consequence, check that values remain within valid application range.
2440 For example, do not allocate memory blindly, check that `windowSize` is within expectation.
2441 Each application can set its own limits, depending on local restrictions.
2442 For extended interoperability, it is recommended to support `windowSize` of at least 8 MB.
2443
2444 ZSTD_decompressContinue() needs previous data blocks during decompression, up to `windowSize` bytes.
2445 ZSTD_decompressContinue() is very sensitive to contiguity,
2446 if 2 blocks don't follow each other, make sure that either the compressor breaks contiguity at the same place,
2447 or that previous contiguous segment is large enough to properly handle maximum back-reference distance.
2448 There are multiple ways to guarantee this condition.
2449
2450 The most memory efficient way is to use a round buffer of sufficient size.
2451 Sufficient size is determined by invoking ZSTD_decodingBufferSize_min(),
2452 which can @return an error code if required value is too large for current system (in 32-bits mode).
2453 In a round buffer methodology, ZSTD_decompressContinue() decompresses each block next to previous one,
2454 up to the moment there is not enough room left in the buffer to guarantee decoding another full block,
2455 which maximum size is provided in `ZSTD_frameHeader` structure, field `blockSizeMax`.
2456 At which point, decoding can resume from the beginning of the buffer.
2457 Note that already decoded data stored in the buffer should be flushed before being overwritten.
2458
2459 There are alternatives possible, for example using two or more buffers of size `windowSize` each, though they consume more memory.
2460
2461 Finally, if you control the compression process, you can also ignore all buffer size rules,
2462 as long as the encoder and decoder progress in "lock-step",
2463 aka use exactly the same buffer sizes, break contiguity at the same place, etc.
2464
2465 Once buffers are setup, start decompression, with ZSTD_decompressBegin().
2466 If decompression requires a dictionary, use ZSTD_decompressBegin_usingDict() or ZSTD_decompressBegin_usingDDict().
2467
2468 Then use ZSTD_nextSrcSizeToDecompress() and ZSTD_decompressContinue() alternatively.
2469 ZSTD_nextSrcSizeToDecompress() tells how many bytes to provide as 'srcSize' to ZSTD_decompressContinue().
2470 ZSTD_decompressContinue() requires this _exact_ amount of bytes, or it will fail.
2471
2472 @result of ZSTD_decompressContinue() is the number of bytes regenerated within 'dst' (necessarily <= dstCapacity).
2473 It can be zero : it just means ZSTD_decompressContinue() has decoded some metadata item.
2474 It can also be an error code, which can be tested with ZSTD_isError().
2475
2476 A frame is fully decoded when ZSTD_nextSrcSizeToDecompress() returns zero.
2477 Context can then be reset to start a new decompression.
2478
2479 Note : it's possible to know if next input to present is a header or a block, using ZSTD_nextInputType().
2480 This information is not required to properly decode a frame.
2481
2482 == Special case : skippable frames ==
2483
2484 Skippable frames allow integration of user-defined data into a flow of concatenated frames.
2485 Skippable frames will be ignored (skipped) by decompressor.
2486 The format of skippable frames is as follows :
2487 a) Skippable frame ID - 4 Bytes, Little endian format, any value from 0x184D2A50 to 0x184D2A5F
2488 b) Frame Size - 4 Bytes, Little endian format, unsigned 32-bits
2489 c) Frame Content - any content (User Data) of length equal to Frame Size
2490 For skippable frames ZSTD_getFrameHeader() returns zfhPtr->frameType==ZSTD_skippableFrame.
2491 For skippable frames ZSTD_decompressContinue() always returns 0 : it only skips the content.
2492*/
2493
2494/*===== Buffer-less streaming decompression functions =====*/
2495typedef enum { ZSTD_frame, ZSTD_skippableFrame } ZSTD_frameType_e;
2496typedef struct {
2497 unsigned long long frameContentSize; /* if == ZSTD_CONTENTSIZE_UNKNOWN, it means this field is not available. 0 means "empty" */
2498 unsigned long long windowSize; /* can be very large, up to <= frameContentSize */
2499 unsigned blockSizeMax;
2500 ZSTD_frameType_e frameType; /* if == ZSTD_skippableFrame, frameContentSize is the size of skippable content */
2501 unsigned headerSize;
2502 unsigned dictID;
2503 unsigned checksumFlag;
2504} ZSTD_frameHeader;
2505
2506/*! ZSTD_getFrameHeader() :
2507 * decode Frame Header, or requires larger `srcSize`.
2508 * @return : 0, `zfhPtr` is correctly filled,
2509 * >0, `srcSize` is too small, value is wanted `srcSize` amount,
2510 * or an error code, which can be tested using ZSTD_isError() */
2511ZSTDLIB_STATIC_API size_t ZSTD_getFrameHeader(ZSTD_frameHeader* zfhPtr, const void* src, size_t srcSize); /**< doesn't consume input */
2512/*! ZSTD_getFrameHeader_advanced() :
2513 * same as ZSTD_getFrameHeader(),
2514 * with added capability to select a format (like ZSTD_f_zstd1_magicless) */
2515ZSTDLIB_STATIC_API size_t ZSTD_getFrameHeader_advanced(ZSTD_frameHeader* zfhPtr, const void* src, size_t srcSize, ZSTD_format_e format);
2516ZSTDLIB_STATIC_API size_t ZSTD_decodingBufferSize_min(unsigned long long windowSize, unsigned long long frameContentSize); /**< when frame content size is not known, pass in frameContentSize == ZSTD_CONTENTSIZE_UNKNOWN */
2517
2518ZSTDLIB_STATIC_API size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx);
2519ZSTDLIB_STATIC_API size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize);
2520ZSTDLIB_STATIC_API size_t ZSTD_decompressBegin_usingDDict(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict);
2521
2522ZSTDLIB_STATIC_API size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx);
2523ZSTDLIB_STATIC_API size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
2524
2525/* misc */
2526ZSTDLIB_STATIC_API void ZSTD_copyDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* preparedDCtx);
2527typedef enum { ZSTDnit_frameHeader, ZSTDnit_blockHeader, ZSTDnit_block, ZSTDnit_lastBlock, ZSTDnit_checksum, ZSTDnit_skippableFrame } ZSTD_nextInputType_e;
2528ZSTDLIB_STATIC_API ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx);
2529
2530
2531
2532
2533/* ============================ */
2534/** Block level API */
2535/* ============================ */
2536
2537/*!
2538 Block functions produce and decode raw zstd blocks, without frame metadata.
2539 Frame metadata cost is typically ~12 bytes, which can be non-negligible for very small blocks (< 100 bytes).
2540 But users will have to take in charge needed metadata to regenerate data, such as compressed and content sizes.
2541
2542 A few rules to respect :
2543 - Compressing and decompressing require a context structure
2544 + Use ZSTD_createCCtx() and ZSTD_createDCtx()
2545 - It is necessary to init context before starting
2546 + compression : any ZSTD_compressBegin*() variant, including with dictionary
2547 + decompression : any ZSTD_decompressBegin*() variant, including with dictionary
2548 + copyCCtx() and copyDCtx() can be used too
2549 - Block size is limited, it must be <= ZSTD_getBlockSize() <= ZSTD_BLOCKSIZE_MAX == 128 KB
2550 + If input is larger than a block size, it's necessary to split input data into multiple blocks
2551 + For inputs larger than a single block, consider using regular ZSTD_compress() instead.
2552 Frame metadata is not that costly, and quickly becomes negligible as source size grows larger than a block.
2553 - When a block is considered not compressible enough, ZSTD_compressBlock() result will be 0 (zero) !
2554 ===> In which case, nothing is produced into `dst` !
2555 + User __must__ test for such outcome and deal directly with uncompressed data
2556 + A block cannot be declared incompressible if ZSTD_compressBlock() return value was != 0.
2557 Doing so would mess up with statistics history, leading to potential data corruption.
2558 + ZSTD_decompressBlock() _doesn't accept uncompressed data as input_ !!
2559 + In case of multiple successive blocks, should some of them be uncompressed,
2560 decoder must be informed of their existence in order to follow proper history.
2561 Use ZSTD_insertBlock() for such a case.
2562*/
2563
2564/*===== Raw zstd block functions =====*/
2565ZSTDLIB_STATIC_API size_t ZSTD_getBlockSize (const ZSTD_CCtx* cctx);
2566ZSTDLIB_STATIC_API size_t ZSTD_compressBlock (ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
2567ZSTDLIB_STATIC_API size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
2568ZSTDLIB_STATIC_API size_t ZSTD_insertBlock (ZSTD_DCtx* dctx, const void* blockStart, size_t blockSize); /**< insert uncompressed block into `dctx` history. Useful for multi-blocks decompression. */
2569
2570
2571#endif /* ZSTD_H_ZSTD_STATIC_LINKING_ONLY */
2572
2573#if defined (__cplusplus)
2574}
2575#endif
stage1/zstd/lib/zstd_errors.h created+95
......@@ -0,0 +1,95 @@
1/*
2 * Copyright (c) Yann Collet, Facebook, Inc.
3 * All rights reserved.
4 *
5 * This source code is licensed under both the BSD-style license (found in the
6 * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7 * in the COPYING file in the root directory of this source tree).
8 * You may select, at your option, one of the above-listed licenses.
9 */
10
11#ifndef ZSTD_ERRORS_H_398273423
12#define ZSTD_ERRORS_H_398273423
13
14#if defined (__cplusplus)
15extern "C" {
16#endif
17
18/*===== dependency =====*/
19#include <stddef.h> /* size_t */
20
21
22/* ===== ZSTDERRORLIB_API : control library symbols visibility ===== */
23#ifndef ZSTDERRORLIB_VISIBILITY
24# if defined(__GNUC__) && (__GNUC__ >= 4)
25# define ZSTDERRORLIB_VISIBILITY __attribute__ ((visibility ("default")))
26# else
27# define ZSTDERRORLIB_VISIBILITY
28# endif
29#endif
30#if defined(ZSTD_DLL_EXPORT) && (ZSTD_DLL_EXPORT==1)
31# define ZSTDERRORLIB_API __declspec(dllexport) ZSTDERRORLIB_VISIBILITY
32#elif defined(ZSTD_DLL_IMPORT) && (ZSTD_DLL_IMPORT==1)
33# define ZSTDERRORLIB_API __declspec(dllimport) ZSTDERRORLIB_VISIBILITY /* It isn't required but allows to generate better code, saving a function pointer load from the IAT and an indirect jump.*/
34#else
35# define ZSTDERRORLIB_API ZSTDERRORLIB_VISIBILITY
36#endif
37
38/*-*********************************************
39 * Error codes list
40 *-*********************************************
41 * Error codes _values_ are pinned down since v1.3.1 only.
42 * Therefore, don't rely on values if you may link to any version < v1.3.1.
43 *
44 * Only values < 100 are considered stable.
45 *
46 * note 1 : this API shall be used with static linking only.
47 * dynamic linking is not yet officially supported.
48 * note 2 : Prefer relying on the enum than on its value whenever possible
49 * This is the only supported way to use the error list < v1.3.1
50 * note 3 : ZSTD_isError() is always correct, whatever the library version.
51 **********************************************/
52typedef enum {
53 ZSTD_error_no_error = 0,
54 ZSTD_error_GENERIC = 1,
55 ZSTD_error_prefix_unknown = 10,
56 ZSTD_error_version_unsupported = 12,
57 ZSTD_error_frameParameter_unsupported = 14,
58 ZSTD_error_frameParameter_windowTooLarge = 16,
59 ZSTD_error_corruption_detected = 20,
60 ZSTD_error_checksum_wrong = 22,
61 ZSTD_error_dictionary_corrupted = 30,
62 ZSTD_error_dictionary_wrong = 32,
63 ZSTD_error_dictionaryCreation_failed = 34,
64 ZSTD_error_parameter_unsupported = 40,
65 ZSTD_error_parameter_outOfBound = 42,
66 ZSTD_error_tableLog_tooLarge = 44,
67 ZSTD_error_maxSymbolValue_tooLarge = 46,
68 ZSTD_error_maxSymbolValue_tooSmall = 48,
69 ZSTD_error_stage_wrong = 60,
70 ZSTD_error_init_missing = 62,
71 ZSTD_error_memory_allocation = 64,
72 ZSTD_error_workSpace_tooSmall= 66,
73 ZSTD_error_dstSize_tooSmall = 70,
74 ZSTD_error_srcSize_wrong = 72,
75 ZSTD_error_dstBuffer_null = 74,
76 /* following error codes are __NOT STABLE__, they can be removed or changed in future versions */
77 ZSTD_error_frameIndex_tooLarge = 100,
78 ZSTD_error_seekableIO = 102,
79 ZSTD_error_dstBuffer_wrong = 104,
80 ZSTD_error_srcBuffer_wrong = 105,
81 ZSTD_error_maxCode = 120 /* never EVER use this value directly, it can change in future versions! Use ZSTD_isError() instead */
82} ZSTD_ErrorCode;
83
84/*! ZSTD_getErrorCode() :
85 convert a `size_t` function result into a `ZSTD_ErrorCode` enum type,
86 which can be used to compare with enum list published above */
87ZSTDERRORLIB_API ZSTD_ErrorCode ZSTD_getErrorCode(size_t functionResult);
88ZSTDERRORLIB_API const char* ZSTD_getErrorString(ZSTD_ErrorCode code); /**< Same as ZSTD_getErrorName, but using a `ZSTD_ErrorCode` enum argument */
89
90
91#if defined (__cplusplus)
92}
93#endif
94
95#endif /* ZSTD_ERRORS_H_398273423 */