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