1eb7fbc25SPierre Schweitzer /*
2*06042735SVincent Franchomme * Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
3eb7fbc25SPierre Schweitzer * All rights reserved.
4eb7fbc25SPierre Schweitzer *
5eb7fbc25SPierre Schweitzer * This source code is licensed under both the BSD-style license (found in the
6eb7fbc25SPierre Schweitzer * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7eb7fbc25SPierre Schweitzer * in the COPYING file in the root directory of this source tree).
8eb7fbc25SPierre Schweitzer * You may select, at your option, one of the above-listed licenses.
9eb7fbc25SPierre Schweitzer */
10eb7fbc25SPierre Schweitzer
11eb7fbc25SPierre Schweitzer #ifndef ZSTD_CCOMMON_H_MODULE
12eb7fbc25SPierre Schweitzer #define ZSTD_CCOMMON_H_MODULE
13eb7fbc25SPierre Schweitzer
14eb7fbc25SPierre Schweitzer /* this module contains definitions which must be identical
15eb7fbc25SPierre Schweitzer * across compression, decompression and dictBuilder.
16eb7fbc25SPierre Schweitzer * It also contains a few functions useful to at least 2 of them
17eb7fbc25SPierre Schweitzer * and which benefit from being inlined */
18eb7fbc25SPierre Schweitzer
19eb7fbc25SPierre Schweitzer /*-*************************************
20eb7fbc25SPierre Schweitzer * Dependencies
21eb7fbc25SPierre Schweitzer ***************************************/
22*06042735SVincent Franchomme #ifdef __aarch64__
23*06042735SVincent Franchomme #include <arm_neon.h>
24*06042735SVincent Franchomme #endif
25eb7fbc25SPierre Schweitzer #include "compiler.h"
26eb7fbc25SPierre Schweitzer #include "mem.h"
27eb7fbc25SPierre Schweitzer #include "debug.h" /* assert, DEBUGLOG, RAWLOG, g_debuglevel */
28eb7fbc25SPierre Schweitzer #include "error_private.h"
29eb7fbc25SPierre Schweitzer #define ZSTD_STATIC_LINKING_ONLY
30eb7fbc25SPierre Schweitzer #include "zstd.h"
31eb7fbc25SPierre Schweitzer #define FSE_STATIC_LINKING_ONLY
32eb7fbc25SPierre Schweitzer #include "fse.h"
33eb7fbc25SPierre Schweitzer #define HUF_STATIC_LINKING_ONLY
34eb7fbc25SPierre Schweitzer #include "huf.h"
35eb7fbc25SPierre Schweitzer #ifndef XXH_STATIC_LINKING_ONLY
36eb7fbc25SPierre Schweitzer # define XXH_STATIC_LINKING_ONLY /* XXH64_state_t */
37eb7fbc25SPierre Schweitzer #endif
38194ea909SVictor Perevertkin #include "../xxhash.h" /* XXH_reset, update, digest */
39eb7fbc25SPierre Schweitzer
40eb7fbc25SPierre Schweitzer #if defined (__cplusplus)
41eb7fbc25SPierre Schweitzer extern "C" {
42eb7fbc25SPierre Schweitzer #endif
43eb7fbc25SPierre Schweitzer
44eb7fbc25SPierre Schweitzer /* ---- static assert (debug) --- */
45eb7fbc25SPierre Schweitzer #define ZSTD_STATIC_ASSERT(c) DEBUG_STATIC_ASSERT(c)
46*06042735SVincent Franchomme #define ZSTD_isError ERR_isError /* for inlining */
47*06042735SVincent Franchomme #define FSE_isError ERR_isError
48*06042735SVincent Franchomme #define HUF_isError ERR_isError
49eb7fbc25SPierre Schweitzer
50eb7fbc25SPierre Schweitzer
51eb7fbc25SPierre Schweitzer /*-*************************************
52eb7fbc25SPierre Schweitzer * shared macros
53eb7fbc25SPierre Schweitzer ***************************************/
54eb7fbc25SPierre Schweitzer #undef MIN
55eb7fbc25SPierre Schweitzer #undef MAX
56eb7fbc25SPierre Schweitzer #define MIN(a,b) ((a)<(b) ? (a) : (b))
57eb7fbc25SPierre Schweitzer #define MAX(a,b) ((a)>(b) ? (a) : (b))
58*06042735SVincent Franchomme
59*06042735SVincent Franchomme /**
60*06042735SVincent Franchomme * Ignore: this is an internal helper.
61*06042735SVincent Franchomme *
62*06042735SVincent Franchomme * This is a helper function to help force C99-correctness during compilation.
63*06042735SVincent Franchomme * Under strict compilation modes, variadic macro arguments can't be empty.
64*06042735SVincent Franchomme * However, variadic function arguments can be. Using a function therefore lets
65*06042735SVincent Franchomme * us statically check that at least one (string) argument was passed,
66*06042735SVincent Franchomme * independent of the compilation flags.
67*06042735SVincent Franchomme */
68*06042735SVincent Franchomme static INLINE_KEYWORD UNUSED_ATTR
_force_has_format_string(const char * format,...)69*06042735SVincent Franchomme void _force_has_format_string(const char *format, ...) {
70*06042735SVincent Franchomme (void)format;
71*06042735SVincent Franchomme }
72*06042735SVincent Franchomme
73*06042735SVincent Franchomme /**
74*06042735SVincent Franchomme * Ignore: this is an internal helper.
75*06042735SVincent Franchomme *
76*06042735SVincent Franchomme * We want to force this function invocation to be syntactically correct, but
77*06042735SVincent Franchomme * we don't want to force runtime evaluation of its arguments.
78*06042735SVincent Franchomme */
79*06042735SVincent Franchomme #define _FORCE_HAS_FORMAT_STRING(...) \
80*06042735SVincent Franchomme if (0) { \
81*06042735SVincent Franchomme _force_has_format_string(__VA_ARGS__); \
82*06042735SVincent Franchomme }
83*06042735SVincent Franchomme
84*06042735SVincent Franchomme /**
85*06042735SVincent Franchomme * Return the specified error if the condition evaluates to true.
86*06042735SVincent Franchomme *
87*06042735SVincent Franchomme * In debug modes, prints additional information.
88*06042735SVincent Franchomme * In order to do that (particularly, printing the conditional that failed),
89*06042735SVincent Franchomme * this can't just wrap RETURN_ERROR().
90*06042735SVincent Franchomme */
91*06042735SVincent Franchomme #define RETURN_ERROR_IF(cond, err, ...) \
92*06042735SVincent Franchomme if (cond) { \
93*06042735SVincent Franchomme RAWLOG(3, "%s:%d: ERROR!: check %s failed, returning %s", \
94*06042735SVincent Franchomme __FILE__, __LINE__, ZSTD_QUOTE(cond), ZSTD_QUOTE(ERROR(err))); \
95*06042735SVincent Franchomme _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \
96*06042735SVincent Franchomme RAWLOG(3, ": " __VA_ARGS__); \
97*06042735SVincent Franchomme RAWLOG(3, "\n"); \
98*06042735SVincent Franchomme return ERROR(err); \
99*06042735SVincent Franchomme }
100*06042735SVincent Franchomme
101*06042735SVincent Franchomme /**
102*06042735SVincent Franchomme * Unconditionally return the specified error.
103*06042735SVincent Franchomme *
104*06042735SVincent Franchomme * In debug modes, prints additional information.
105*06042735SVincent Franchomme */
106*06042735SVincent Franchomme #define RETURN_ERROR(err, ...) \
107*06042735SVincent Franchomme do { \
108*06042735SVincent Franchomme RAWLOG(3, "%s:%d: ERROR!: unconditional check failed, returning %s", \
109*06042735SVincent Franchomme __FILE__, __LINE__, ZSTD_QUOTE(ERROR(err))); \
110*06042735SVincent Franchomme _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \
111*06042735SVincent Franchomme RAWLOG(3, ": " __VA_ARGS__); \
112*06042735SVincent Franchomme RAWLOG(3, "\n"); \
113*06042735SVincent Franchomme return ERROR(err); \
114*06042735SVincent Franchomme } while(0);
115*06042735SVincent Franchomme
116*06042735SVincent Franchomme /**
117*06042735SVincent Franchomme * If the provided expression evaluates to an error code, returns that error code.
118*06042735SVincent Franchomme *
119*06042735SVincent Franchomme * In debug modes, prints additional information.
120*06042735SVincent Franchomme */
121*06042735SVincent Franchomme #define FORWARD_IF_ERROR(err, ...) \
122*06042735SVincent Franchomme do { \
123*06042735SVincent Franchomme size_t const err_code = (err); \
124*06042735SVincent Franchomme if (ERR_isError(err_code)) { \
125*06042735SVincent Franchomme RAWLOG(3, "%s:%d: ERROR!: forwarding error in %s: %s", \
126*06042735SVincent Franchomme __FILE__, __LINE__, ZSTD_QUOTE(err), ERR_getErrorName(err_code)); \
127*06042735SVincent Franchomme _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \
128*06042735SVincent Franchomme RAWLOG(3, ": " __VA_ARGS__); \
129*06042735SVincent Franchomme RAWLOG(3, "\n"); \
130*06042735SVincent Franchomme return err_code; \
131*06042735SVincent Franchomme } \
132*06042735SVincent Franchomme } while(0);
133eb7fbc25SPierre Schweitzer
134eb7fbc25SPierre Schweitzer
135eb7fbc25SPierre Schweitzer /*-*************************************
136eb7fbc25SPierre Schweitzer * Common constants
137eb7fbc25SPierre Schweitzer ***************************************/
138eb7fbc25SPierre Schweitzer #define ZSTD_OPT_NUM (1<<12)
139eb7fbc25SPierre Schweitzer
140eb7fbc25SPierre Schweitzer #define ZSTD_REP_NUM 3 /* number of repcodes */
141eb7fbc25SPierre Schweitzer #define ZSTD_REP_MOVE (ZSTD_REP_NUM-1)
142eb7fbc25SPierre Schweitzer static const U32 repStartValue[ZSTD_REP_NUM] = { 1, 4, 8 };
143eb7fbc25SPierre Schweitzer
144eb7fbc25SPierre Schweitzer #define KB *(1 <<10)
145eb7fbc25SPierre Schweitzer #define MB *(1 <<20)
146eb7fbc25SPierre Schweitzer #define GB *(1U<<30)
147eb7fbc25SPierre Schweitzer
148eb7fbc25SPierre Schweitzer #define BIT7 128
149eb7fbc25SPierre Schweitzer #define BIT6 64
150eb7fbc25SPierre Schweitzer #define BIT5 32
151eb7fbc25SPierre Schweitzer #define BIT4 16
152eb7fbc25SPierre Schweitzer #define BIT1 2
153eb7fbc25SPierre Schweitzer #define BIT0 1
154eb7fbc25SPierre Schweitzer
155eb7fbc25SPierre Schweitzer #define ZSTD_WINDOWLOG_ABSOLUTEMIN 10
156eb7fbc25SPierre Schweitzer static const size_t ZSTD_fcs_fieldSize[4] = { 0, 2, 4, 8 };
157eb7fbc25SPierre Schweitzer static const size_t ZSTD_did_fieldSize[4] = { 0, 1, 2, 4 };
158eb7fbc25SPierre Schweitzer
159eb7fbc25SPierre Schweitzer #define ZSTD_FRAMEIDSIZE 4 /* magic number size */
160eb7fbc25SPierre Schweitzer
161eb7fbc25SPierre Schweitzer #define ZSTD_BLOCKHEADERSIZE 3 /* C standard doesn't allow `static const` variable to be init using another `static const` variable */
162eb7fbc25SPierre Schweitzer static const size_t ZSTD_blockHeaderSize = ZSTD_BLOCKHEADERSIZE;
163eb7fbc25SPierre Schweitzer typedef enum { bt_raw, bt_rle, bt_compressed, bt_reserved } blockType_e;
164eb7fbc25SPierre Schweitzer
165*06042735SVincent Franchomme #define ZSTD_FRAMECHECKSUMSIZE 4
166*06042735SVincent Franchomme
167eb7fbc25SPierre Schweitzer #define MIN_SEQUENCES_SIZE 1 /* nbSeq==0 */
168eb7fbc25SPierre Schweitzer #define MIN_CBLOCK_SIZE (1 /*litCSize*/ + 1 /* RLE or RAW */ + MIN_SEQUENCES_SIZE /* nbSeq==0 */) /* for a non-null block */
169eb7fbc25SPierre Schweitzer
170eb7fbc25SPierre Schweitzer #define HufLog 12
171eb7fbc25SPierre Schweitzer typedef enum { set_basic, set_rle, set_compressed, set_repeat } symbolEncodingType_e;
172eb7fbc25SPierre Schweitzer
173eb7fbc25SPierre Schweitzer #define LONGNBSEQ 0x7F00
174eb7fbc25SPierre Schweitzer
175eb7fbc25SPierre Schweitzer #define MINMATCH 3
176eb7fbc25SPierre Schweitzer
177eb7fbc25SPierre Schweitzer #define Litbits 8
178eb7fbc25SPierre Schweitzer #define MaxLit ((1<<Litbits) - 1)
179eb7fbc25SPierre Schweitzer #define MaxML 52
180eb7fbc25SPierre Schweitzer #define MaxLL 35
181eb7fbc25SPierre Schweitzer #define DefaultMaxOff 28
182eb7fbc25SPierre Schweitzer #define MaxOff 31
183eb7fbc25SPierre Schweitzer #define MaxSeq MAX(MaxLL, MaxML) /* Assumption : MaxOff < MaxLL,MaxML */
184eb7fbc25SPierre Schweitzer #define MLFSELog 9
185eb7fbc25SPierre Schweitzer #define LLFSELog 9
186eb7fbc25SPierre Schweitzer #define OffFSELog 8
187eb7fbc25SPierre Schweitzer #define MaxFSELog MAX(MAX(MLFSELog, LLFSELog), OffFSELog)
188eb7fbc25SPierre Schweitzer
189eb7fbc25SPierre Schweitzer static const U32 LL_bits[MaxLL+1] = { 0, 0, 0, 0, 0, 0, 0, 0,
190eb7fbc25SPierre Schweitzer 0, 0, 0, 0, 0, 0, 0, 0,
191eb7fbc25SPierre Schweitzer 1, 1, 1, 1, 2, 2, 3, 3,
192eb7fbc25SPierre Schweitzer 4, 6, 7, 8, 9,10,11,12,
193eb7fbc25SPierre Schweitzer 13,14,15,16 };
194eb7fbc25SPierre Schweitzer static const S16 LL_defaultNorm[MaxLL+1] = { 4, 3, 2, 2, 2, 2, 2, 2,
195eb7fbc25SPierre Schweitzer 2, 2, 2, 2, 2, 1, 1, 1,
196eb7fbc25SPierre Schweitzer 2, 2, 2, 2, 2, 2, 2, 2,
197eb7fbc25SPierre Schweitzer 2, 3, 2, 1, 1, 1, 1, 1,
198eb7fbc25SPierre Schweitzer -1,-1,-1,-1 };
199eb7fbc25SPierre Schweitzer #define LL_DEFAULTNORMLOG 6 /* for static allocation */
200eb7fbc25SPierre Schweitzer static const U32 LL_defaultNormLog = LL_DEFAULTNORMLOG;
201eb7fbc25SPierre Schweitzer
202eb7fbc25SPierre Schweitzer static const U32 ML_bits[MaxML+1] = { 0, 0, 0, 0, 0, 0, 0, 0,
203eb7fbc25SPierre Schweitzer 0, 0, 0, 0, 0, 0, 0, 0,
204eb7fbc25SPierre Schweitzer 0, 0, 0, 0, 0, 0, 0, 0,
205eb7fbc25SPierre Schweitzer 0, 0, 0, 0, 0, 0, 0, 0,
206eb7fbc25SPierre Schweitzer 1, 1, 1, 1, 2, 2, 3, 3,
207eb7fbc25SPierre Schweitzer 4, 4, 5, 7, 8, 9,10,11,
208eb7fbc25SPierre Schweitzer 12,13,14,15,16 };
209eb7fbc25SPierre Schweitzer static const S16 ML_defaultNorm[MaxML+1] = { 1, 4, 3, 2, 2, 2, 2, 2,
210eb7fbc25SPierre Schweitzer 2, 1, 1, 1, 1, 1, 1, 1,
211eb7fbc25SPierre Schweitzer 1, 1, 1, 1, 1, 1, 1, 1,
212eb7fbc25SPierre Schweitzer 1, 1, 1, 1, 1, 1, 1, 1,
213eb7fbc25SPierre Schweitzer 1, 1, 1, 1, 1, 1, 1, 1,
214eb7fbc25SPierre Schweitzer 1, 1, 1, 1, 1, 1,-1,-1,
215eb7fbc25SPierre Schweitzer -1,-1,-1,-1,-1 };
216eb7fbc25SPierre Schweitzer #define ML_DEFAULTNORMLOG 6 /* for static allocation */
217eb7fbc25SPierre Schweitzer static const U32 ML_defaultNormLog = ML_DEFAULTNORMLOG;
218eb7fbc25SPierre Schweitzer
219eb7fbc25SPierre Schweitzer static const S16 OF_defaultNorm[DefaultMaxOff+1] = { 1, 1, 1, 1, 1, 1, 2, 2,
220eb7fbc25SPierre Schweitzer 2, 1, 1, 1, 1, 1, 1, 1,
221eb7fbc25SPierre Schweitzer 1, 1, 1, 1, 1, 1, 1, 1,
222eb7fbc25SPierre Schweitzer -1,-1,-1,-1,-1 };
223eb7fbc25SPierre Schweitzer #define OF_DEFAULTNORMLOG 5 /* for static allocation */
224eb7fbc25SPierre Schweitzer static const U32 OF_defaultNormLog = OF_DEFAULTNORMLOG;
225eb7fbc25SPierre Schweitzer
226eb7fbc25SPierre Schweitzer
227eb7fbc25SPierre Schweitzer /*-*******************************************
228eb7fbc25SPierre Schweitzer * Shared functions to include for inlining
229eb7fbc25SPierre Schweitzer *********************************************/
ZSTD_copy8(void * dst,const void * src)230*06042735SVincent Franchomme static void ZSTD_copy8(void* dst, const void* src) {
231*06042735SVincent Franchomme #ifdef __aarch64__
232*06042735SVincent Franchomme vst1_u8((uint8_t*)dst, vld1_u8((const uint8_t*)src));
233*06042735SVincent Franchomme #else
234*06042735SVincent Franchomme memcpy(dst, src, 8);
235*06042735SVincent Franchomme #endif
236*06042735SVincent Franchomme }
237*06042735SVincent Franchomme
238eb7fbc25SPierre Schweitzer #define COPY8(d,s) { ZSTD_copy8(d,s); d+=8; s+=8; }
ZSTD_copy16(void * dst,const void * src)239*06042735SVincent Franchomme static void ZSTD_copy16(void* dst, const void* src) {
240*06042735SVincent Franchomme #ifdef __aarch64__
241*06042735SVincent Franchomme vst1q_u8((uint8_t*)dst, vld1q_u8((const uint8_t*)src));
242*06042735SVincent Franchomme #else
243*06042735SVincent Franchomme memcpy(dst, src, 16);
244*06042735SVincent Franchomme #endif
245*06042735SVincent Franchomme }
246*06042735SVincent Franchomme #define COPY16(d,s) { ZSTD_copy16(d,s); d+=16; s+=16; }
247*06042735SVincent Franchomme
248*06042735SVincent Franchomme #define WILDCOPY_OVERLENGTH 32
249*06042735SVincent Franchomme #define WILDCOPY_VECLEN 16
250*06042735SVincent Franchomme
251*06042735SVincent Franchomme typedef enum {
252*06042735SVincent Franchomme ZSTD_no_overlap,
253*06042735SVincent Franchomme ZSTD_overlap_src_before_dst
254*06042735SVincent Franchomme /* ZSTD_overlap_dst_before_src, */
255*06042735SVincent Franchomme } ZSTD_overlap_e;
256eb7fbc25SPierre Schweitzer
257eb7fbc25SPierre Schweitzer /*! ZSTD_wildcopy() :
258*06042735SVincent Franchomme * Custom version of memcpy(), can over read/write up to WILDCOPY_OVERLENGTH bytes (if length==0)
259*06042735SVincent Franchomme * @param ovtype controls the overlap detection
260*06042735SVincent Franchomme * - ZSTD_no_overlap: The source and destination are guaranteed to be at least WILDCOPY_VECLEN bytes apart.
261*06042735SVincent Franchomme * - ZSTD_overlap_src_before_dst: The src and dst may overlap, but they MUST be at least 8 bytes apart.
262*06042735SVincent Franchomme * The src buffer must be before the dst buffer.
263*06042735SVincent Franchomme */
264*06042735SVincent Franchomme MEM_STATIC FORCE_INLINE_ATTR
ZSTD_wildcopy(void * dst,const void * src,ptrdiff_t length,ZSTD_overlap_e const ovtype)265*06042735SVincent Franchomme void ZSTD_wildcopy(void* dst, const void* src, ptrdiff_t length, ZSTD_overlap_e const ovtype)
266eb7fbc25SPierre Schweitzer {
267*06042735SVincent Franchomme ptrdiff_t diff = (BYTE*)dst - (const BYTE*)src;
268eb7fbc25SPierre Schweitzer const BYTE* ip = (const BYTE*)src;
269eb7fbc25SPierre Schweitzer BYTE* op = (BYTE*)dst;
270eb7fbc25SPierre Schweitzer BYTE* const oend = op + length;
271*06042735SVincent Franchomme
272*06042735SVincent Franchomme assert(diff >= 8 || (ovtype == ZSTD_no_overlap && diff <= -WILDCOPY_VECLEN));
273*06042735SVincent Franchomme
274*06042735SVincent Franchomme if (ovtype == ZSTD_overlap_src_before_dst && diff < WILDCOPY_VECLEN) {
275*06042735SVincent Franchomme /* Handle short offset copies. */
276*06042735SVincent Franchomme do {
277eb7fbc25SPierre Schweitzer COPY8(op, ip)
278*06042735SVincent Franchomme } while (op < oend);
279*06042735SVincent Franchomme } else {
280*06042735SVincent Franchomme assert(diff >= WILDCOPY_VECLEN || diff <= -WILDCOPY_VECLEN);
281*06042735SVincent Franchomme /* Separate out the first COPY16() call because the copy length is
282*06042735SVincent Franchomme * almost certain to be short, so the branches have different
283*06042735SVincent Franchomme * probabilities. Since it is almost certain to be short, only do
284*06042735SVincent Franchomme * one COPY16() in the first call. Then, do two calls per loop since
285*06042735SVincent Franchomme * at that point it is more likely to have a high trip count.
286*06042735SVincent Franchomme */
287*06042735SVincent Franchomme #ifndef __aarch64__
288*06042735SVincent Franchomme do {
289*06042735SVincent Franchomme COPY16(op, ip);
290*06042735SVincent Franchomme }
291eb7fbc25SPierre Schweitzer while (op < oend);
292*06042735SVincent Franchomme #else
293*06042735SVincent Franchomme COPY16(op, ip);
294*06042735SVincent Franchomme if (op >= oend) return;
295*06042735SVincent Franchomme do {
296*06042735SVincent Franchomme COPY16(op, ip);
297*06042735SVincent Franchomme COPY16(op, ip);
298*06042735SVincent Franchomme }
299*06042735SVincent Franchomme while (op < oend);
300*06042735SVincent Franchomme #endif
301*06042735SVincent Franchomme }
302eb7fbc25SPierre Schweitzer }
303eb7fbc25SPierre Schweitzer
ZSTD_limitCopy(void * dst,size_t dstCapacity,const void * src,size_t srcSize)304*06042735SVincent Franchomme MEM_STATIC size_t ZSTD_limitCopy(void* dst, size_t dstCapacity, const void* src, size_t srcSize)
305eb7fbc25SPierre Schweitzer {
306*06042735SVincent Franchomme size_t const length = MIN(dstCapacity, srcSize);
307*06042735SVincent Franchomme if (length > 0) {
308*06042735SVincent Franchomme memcpy(dst, src, length);
309eb7fbc25SPierre Schweitzer }
310*06042735SVincent Franchomme return length;
311*06042735SVincent Franchomme }
312*06042735SVincent Franchomme
313*06042735SVincent Franchomme /* define "workspace is too large" as this number of times larger than needed */
314*06042735SVincent Franchomme #define ZSTD_WORKSPACETOOLARGE_FACTOR 3
315*06042735SVincent Franchomme
316*06042735SVincent Franchomme /* when workspace is continuously too large
317*06042735SVincent Franchomme * during at least this number of times,
318*06042735SVincent Franchomme * context's memory usage is considered wasteful,
319*06042735SVincent Franchomme * because it's sized to handle a worst case scenario which rarely happens.
320*06042735SVincent Franchomme * In which case, resize it down to free some memory */
321*06042735SVincent Franchomme #define ZSTD_WORKSPACETOOLARGE_MAXDURATION 128
322eb7fbc25SPierre Schweitzer
323eb7fbc25SPierre Schweitzer
324eb7fbc25SPierre Schweitzer /*-*******************************************
325eb7fbc25SPierre Schweitzer * Private declarations
326eb7fbc25SPierre Schweitzer *********************************************/
327eb7fbc25SPierre Schweitzer typedef struct seqDef_s {
328eb7fbc25SPierre Schweitzer U32 offset;
329eb7fbc25SPierre Schweitzer U16 litLength;
330eb7fbc25SPierre Schweitzer U16 matchLength;
331eb7fbc25SPierre Schweitzer } seqDef;
332eb7fbc25SPierre Schweitzer
333eb7fbc25SPierre Schweitzer typedef struct {
334eb7fbc25SPierre Schweitzer seqDef* sequencesStart;
335eb7fbc25SPierre Schweitzer seqDef* sequences;
336eb7fbc25SPierre Schweitzer BYTE* litStart;
337eb7fbc25SPierre Schweitzer BYTE* lit;
338eb7fbc25SPierre Schweitzer BYTE* llCode;
339eb7fbc25SPierre Schweitzer BYTE* mlCode;
340eb7fbc25SPierre Schweitzer BYTE* ofCode;
341eb7fbc25SPierre Schweitzer size_t maxNbSeq;
342eb7fbc25SPierre Schweitzer size_t maxNbLit;
343eb7fbc25SPierre Schweitzer U32 longLengthID; /* 0 == no longLength; 1 == Lit.longLength; 2 == Match.longLength; */
344eb7fbc25SPierre Schweitzer U32 longLengthPos;
345eb7fbc25SPierre Schweitzer } seqStore_t;
346eb7fbc25SPierre Schweitzer
347*06042735SVincent Franchomme typedef struct {
348*06042735SVincent Franchomme U32 litLength;
349*06042735SVincent Franchomme U32 matchLength;
350*06042735SVincent Franchomme } ZSTD_sequenceLength;
351*06042735SVincent Franchomme
352*06042735SVincent Franchomme /**
353*06042735SVincent Franchomme * Returns the ZSTD_sequenceLength for the given sequences. It handles the decoding of long sequences
354*06042735SVincent Franchomme * indicated by longLengthPos and longLengthID, and adds MINMATCH back to matchLength.
355*06042735SVincent Franchomme */
ZSTD_getSequenceLength(seqStore_t const * seqStore,seqDef const * seq)356*06042735SVincent Franchomme MEM_STATIC ZSTD_sequenceLength ZSTD_getSequenceLength(seqStore_t const* seqStore, seqDef const* seq)
357*06042735SVincent Franchomme {
358*06042735SVincent Franchomme ZSTD_sequenceLength seqLen;
359*06042735SVincent Franchomme seqLen.litLength = seq->litLength;
360*06042735SVincent Franchomme seqLen.matchLength = seq->matchLength + MINMATCH;
361*06042735SVincent Franchomme if (seqStore->longLengthPos == (U32)(seq - seqStore->sequencesStart)) {
362*06042735SVincent Franchomme if (seqStore->longLengthID == 1) {
363*06042735SVincent Franchomme seqLen.litLength += 0xFFFF;
364*06042735SVincent Franchomme }
365*06042735SVincent Franchomme if (seqStore->longLengthID == 2) {
366*06042735SVincent Franchomme seqLen.matchLength += 0xFFFF;
367*06042735SVincent Franchomme }
368*06042735SVincent Franchomme }
369*06042735SVincent Franchomme return seqLen;
370*06042735SVincent Franchomme }
371*06042735SVincent Franchomme
372*06042735SVincent Franchomme /**
373*06042735SVincent Franchomme * Contains the compressed frame size and an upper-bound for the decompressed frame size.
374*06042735SVincent Franchomme * Note: before using `compressedSize`, check for errors using ZSTD_isError().
375*06042735SVincent Franchomme * similarly, before using `decompressedBound`, check for errors using:
376*06042735SVincent Franchomme * `decompressedBound != ZSTD_CONTENTSIZE_ERROR`
377*06042735SVincent Franchomme */
378*06042735SVincent Franchomme typedef struct {
379*06042735SVincent Franchomme size_t compressedSize;
380*06042735SVincent Franchomme unsigned long long decompressedBound;
381*06042735SVincent Franchomme } ZSTD_frameSizeInfo; /* decompress & legacy */
382*06042735SVincent Franchomme
383eb7fbc25SPierre Schweitzer const seqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx); /* compress & dictBuilder */
384eb7fbc25SPierre Schweitzer void ZSTD_seqToCodes(const seqStore_t* seqStorePtr); /* compress, dictBuilder, decodeCorpus (shouldn't get its definition from here) */
385eb7fbc25SPierre Schweitzer
386eb7fbc25SPierre Schweitzer /* custom memory allocation functions */
387eb7fbc25SPierre Schweitzer void* ZSTD_malloc(size_t size, ZSTD_customMem customMem);
388eb7fbc25SPierre Schweitzer void* ZSTD_calloc(size_t size, ZSTD_customMem customMem);
389eb7fbc25SPierre Schweitzer void ZSTD_free(void* ptr, ZSTD_customMem customMem);
390eb7fbc25SPierre Schweitzer
391eb7fbc25SPierre Schweitzer
ZSTD_highbit32(U32 val)392eb7fbc25SPierre Schweitzer MEM_STATIC U32 ZSTD_highbit32(U32 val) /* compress, dictBuilder, decodeCorpus */
393eb7fbc25SPierre Schweitzer {
394eb7fbc25SPierre Schweitzer assert(val != 0);
395eb7fbc25SPierre Schweitzer {
396eb7fbc25SPierre Schweitzer # if defined(_MSC_VER) /* Visual */
397eb7fbc25SPierre Schweitzer unsigned long r=0;
398*06042735SVincent Franchomme return _BitScanReverse(&r, val) ? (unsigned)r : 0;
399eb7fbc25SPierre Schweitzer # elif defined(__GNUC__) && (__GNUC__ >= 3) /* GCC Intrinsic */
400*06042735SVincent Franchomme return __builtin_clz (val) ^ 31;
401*06042735SVincent Franchomme # elif defined(__ICCARM__) /* IAR Intrinsic */
402*06042735SVincent Franchomme return 31 - __CLZ(val);
403eb7fbc25SPierre Schweitzer # else /* Software version */
404eb7fbc25SPierre Schweitzer 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 };
405eb7fbc25SPierre Schweitzer U32 v = val;
406eb7fbc25SPierre Schweitzer v |= v >> 1;
407eb7fbc25SPierre Schweitzer v |= v >> 2;
408eb7fbc25SPierre Schweitzer v |= v >> 4;
409eb7fbc25SPierre Schweitzer v |= v >> 8;
410eb7fbc25SPierre Schweitzer v |= v >> 16;
411eb7fbc25SPierre Schweitzer return DeBruijnClz[(v * 0x07C4ACDDU) >> 27];
412eb7fbc25SPierre Schweitzer # endif
413eb7fbc25SPierre Schweitzer }
414eb7fbc25SPierre Schweitzer }
415eb7fbc25SPierre Schweitzer
416eb7fbc25SPierre Schweitzer
417eb7fbc25SPierre Schweitzer /* ZSTD_invalidateRepCodes() :
418eb7fbc25SPierre Schweitzer * ensures next compression will not use repcodes from previous block.
419eb7fbc25SPierre Schweitzer * Note : only works with regular variant;
420eb7fbc25SPierre Schweitzer * do not use with extDict variant ! */
421eb7fbc25SPierre Schweitzer void ZSTD_invalidateRepCodes(ZSTD_CCtx* cctx); /* zstdmt, adaptive_compression (shouldn't get this definition from here) */
422eb7fbc25SPierre Schweitzer
423eb7fbc25SPierre Schweitzer
424eb7fbc25SPierre Schweitzer typedef struct {
425eb7fbc25SPierre Schweitzer blockType_e blockType;
426eb7fbc25SPierre Schweitzer U32 lastBlock;
427eb7fbc25SPierre Schweitzer U32 origSize;
428*06042735SVincent Franchomme } blockProperties_t; /* declared here for decompress and fullbench */
429eb7fbc25SPierre Schweitzer
430eb7fbc25SPierre Schweitzer /*! ZSTD_getcBlockSize() :
431eb7fbc25SPierre Schweitzer * Provides the size of compressed block from block header `src` */
432eb7fbc25SPierre Schweitzer /* Used by: decompress, fullbench (does not get its definition from here) */
433eb7fbc25SPierre Schweitzer size_t ZSTD_getcBlockSize(const void* src, size_t srcSize,
434eb7fbc25SPierre Schweitzer blockProperties_t* bpPtr);
435eb7fbc25SPierre Schweitzer
436*06042735SVincent Franchomme /*! ZSTD_decodeSeqHeaders() :
437*06042735SVincent Franchomme * decode sequence header from src */
438*06042735SVincent Franchomme /* Used by: decompress, fullbench (does not get its definition from here) */
439*06042735SVincent Franchomme size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr,
440*06042735SVincent Franchomme const void* src, size_t srcSize);
441*06042735SVincent Franchomme
442*06042735SVincent Franchomme
443eb7fbc25SPierre Schweitzer #if defined (__cplusplus)
444eb7fbc25SPierre Schweitzer }
445eb7fbc25SPierre Schweitzer #endif
446eb7fbc25SPierre Schweitzer
447eb7fbc25SPierre Schweitzer #endif /* ZSTD_CCOMMON_H_MODULE */
448