blob: 1621bca61adacf906bc781a79759ee81f7c52630 [file] [log] [blame]
Yann Collet4ded9e52016-08-30 10:04:33 -07001/**
2 * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
3 * All rights reserved.
4 *
5 * This source code is licensed under the BSD-style license found in the
6 * LICENSE file in the root directory of this source tree. An additional grant
7 * of patent rights can be found in the PATENTS file in the same directory.
8 */
Yann Collet2acb5d32015-10-29 16:49:43 +01009
Yann Collet2acb5d32015-10-29 16:49:43 +010010#ifndef ZSTD_CCOMMON_H_MODULE
11#define ZSTD_CCOMMON_H_MODULE
12
Yann Collet5c956d52016-09-06 15:05:19 +020013/*-*******************************************************
14* Compiler specifics
15*********************************************************/
16#ifdef _MSC_VER /* Visual Studio */
17# define FORCE_INLINE static __forceinline
18# include <intrin.h> /* For Visual 2005 */
Yann Collet5c956d52016-09-06 15:05:19 +020019# pragma warning(disable : 4100) /* disable: C4100: unreferenced formal parameter */
Yann Collet69a54d12017-04-27 01:10:36 -070020# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
Yann Collet9a691e02017-05-31 01:17:44 -070021# pragma warning(disable : 4204) /* disable: C4204: non-constant aggregate initializer */
Yann Collet69a54d12017-04-27 01:10:36 -070022# pragma warning(disable : 4324) /* disable: C4324: padded structure */
Yann Collet5c956d52016-09-06 15:05:19 +020023#else
24# if defined (__cplusplus) || defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */
25# ifdef __GNUC__
26# define FORCE_INLINE static inline __attribute__((always_inline))
27# else
28# define FORCE_INLINE static inline
29# endif
30# else
31# define FORCE_INLINE static
32# endif /* __STDC_VERSION__ */
33#endif
34
Nick Terrelleb7873a2016-10-21 16:55:26 -070035#ifdef _MSC_VER
36# define FORCE_NOINLINE static __declspec(noinline)
37#else
38# ifdef __GNUC__
39# define FORCE_NOINLINE static __attribute__((__noinline__))
40# else
41# define FORCE_NOINLINE static
42# endif
43#endif
44
Yann Collet5c956d52016-09-06 15:05:19 +020045
Yann Collet7d360282016-02-12 00:07:30 +010046/*-*************************************
Yann Collet953ce722016-02-04 15:28:14 +010047* Dependencies
Yann Collet2acb5d32015-10-29 16:49:43 +010048***************************************/
49#include "mem.h"
Yann Collet977f1f32016-01-21 15:38:47 +010050#include "error_private.h"
Yann Colletd3b7f8d2016-06-04 19:47:02 +020051#define ZSTD_STATIC_LINKING_ONLY
52#include "zstd.h"
Nick Terrellde0414b2017-07-12 19:08:24 -070053#define FSE_STATIC_LINKING_ONLY
54#include "fse.h"
55#define HUF_STATIC_LINKING_ONLY
56#include "huf.h"
Yann Collet4bcc69b2017-03-01 11:33:25 -080057#ifndef XXH_STATIC_LINKING_ONLY
Yann Collet58e8d792017-06-02 18:20:48 -070058# define XXH_STATIC_LINKING_ONLY /* XXH64_state_t */
Yann Collet4bcc69b2017-03-01 11:33:25 -080059#endif
Yann Collet58e8d792017-06-02 18:20:48 -070060#include "xxhash.h" /* XXH_reset, update, digest */
61
62
63/*-*************************************
64* Debug
65***************************************/
66#if defined(ZSTD_DEBUG) && (ZSTD_DEBUG>=1)
67# include <assert.h>
68#else
69# ifndef assert
70# define assert(condition) ((void)0)
71# endif
72#endif
73
74#define ZSTD_STATIC_ASSERT(c) { enum { ZSTD_static_assert = 1/(int)(!!(c)) }; }
75
76#if defined(ZSTD_DEBUG) && (ZSTD_DEBUG>=2)
77# include <stdio.h>
Yann Collet33a66392017-06-28 11:09:43 -070078/* recommended values for ZSTD_DEBUG display levels :
Yann Colleta3d99262017-06-29 14:44:49 -070079 * 1 : no display, enables assert() only
Yann Collet33a66392017-06-28 11:09:43 -070080 * 2 : reserved for currently active debugging path
81 * 3 : events once per object lifetime (CCtx, CDict)
82 * 4 : events once per frame
83 * 5 : events once per block
84 * 6 : events once per sequence (*very* verbose) */
85# define DEBUGLOG(l, ...) { \
86 if (l<=ZSTD_DEBUG) { \
87 fprintf(stderr, __FILE__ ": "); \
88 fprintf(stderr, __VA_ARGS__); \
89 fprintf(stderr, " \n"); \
Yann Collet58e8d792017-06-02 18:20:48 -070090 } }
91#else
92# define DEBUGLOG(l, ...) {} /* disabled */
93#endif
Yann Collet2acb5d32015-10-29 16:49:43 +010094
95
Yann Collet7d360282016-02-12 00:07:30 +010096/*-*************************************
Yann Collet3e21ec52016-09-06 15:36:19 +020097* shared macros
Yann Collet14983e72015-11-11 21:38:21 +010098***************************************/
Yann Collet4f818182017-04-17 17:57:35 -070099#undef MIN
100#undef MAX
Yann Colletbe2010e2015-10-31 12:57:14 +0100101#define MIN(a,b) ((a)<(b) ? (a) : (b))
Yann Collet14983e72015-11-11 21:38:21 +0100102#define MAX(a,b) ((a)>(b) ? (a) : (b))
Yann Collet3e21ec52016-09-06 15:36:19 +0200103#define CHECK_F(f) { size_t const errcod = f; if (ERR_isError(errcod)) return errcod; } /* check and Forward error code */
Yann Collet95d07d72016-09-06 16:38:51 +0200104#define CHECK_E(f, e) { size_t const errcod = f; if (ERR_isError(errcod)) return ERROR(e); } /* check and send Error code */
Yann Collet2acb5d32015-10-29 16:49:43 +0100105
106
Yann Collet7d360282016-02-12 00:07:30 +0100107/*-*************************************
Yann Collet14983e72015-11-11 21:38:21 +0100108* Common constants
109***************************************/
inikep87d4f3d2016-03-02 15:56:24 +0100110#define ZSTD_OPT_NUM (1<<12)
Yann Collet88fcd292015-11-25 14:42:45 +0100111
inikep5f49eba2016-08-10 15:01:53 +0200112#define ZSTD_REP_NUM 3 /* number of repcodes */
113#define ZSTD_REP_CHECK (ZSTD_REP_NUM) /* number of repcodes to check by the optimal parser */
114#define ZSTD_REP_MOVE (ZSTD_REP_NUM-1)
115#define ZSTD_REP_MOVE_OPT (ZSTD_REP_NUM)
Yann Collet4266c0a2016-06-14 01:49:25 +0200116static const U32 repStartValue[ZSTD_REP_NUM] = { 1, 4, 8 };
Yann Collet14983e72015-11-11 21:38:21 +0100117
118#define KB *(1 <<10)
119#define MB *(1 <<20)
120#define GB *(1U<<30)
Yann Collet2acb5d32015-10-29 16:49:43 +0100121
Yann Collet14983e72015-11-11 21:38:21 +0100122#define BIT7 128
123#define BIT6 64
124#define BIT5 32
125#define BIT4 16
126#define BIT1 2
127#define BIT0 1
128
Yann Collet673f0d72016-06-06 00:26:38 +0200129#define ZSTD_WINDOWLOG_ABSOLUTEMIN 10
130static const size_t ZSTD_fcs_fieldSize[4] = { 0, 2, 4, 8 };
Yann Colletc46fb922016-05-29 05:01:04 +0200131static const size_t ZSTD_did_fieldSize[4] = { 0, 1, 2, 4 };
Yann Collet37f3d1b2016-03-19 15:11:42 +0100132
Yann Collet49bb0042016-06-04 20:17:38 +0200133#define ZSTD_BLOCKHEADERSIZE 3 /* C standard doesn't allow `static const` variable to be init using another `static const` variable */
Yann Collet37f3d1b2016-03-19 15:11:42 +0100134static const size_t ZSTD_blockHeaderSize = ZSTD_BLOCKHEADERSIZE;
Yann Colletc991cc12016-07-28 00:55:43 +0200135typedef enum { bt_raw, bt_rle, bt_compressed, bt_reserved } blockType_e;
Yann Collet37f3d1b2016-03-19 15:11:42 +0100136
137#define MIN_SEQUENCES_SIZE 1 /* nbSeq==0 */
138#define MIN_CBLOCK_SIZE (1 /*litCSize*/ + 1 /* RLE or RAW */ + MIN_SEQUENCES_SIZE /* nbSeq==0 */) /* for a non-null block */
139
140#define HufLog 12
Yann Colletf8e7b532016-07-23 16:31:49 +0200141typedef enum { set_basic, set_rle, set_compressed, set_repeat } symbolEncodingType_e;
Yann Collet14983e72015-11-11 21:38:21 +0100142
Yann Collet37f3d1b2016-03-19 15:11:42 +0100143#define LONGNBSEQ 0x7F00
144
inikep7bc19b62016-04-06 09:46:01 +0200145#define MINMATCH 3
Yann Collet14983e72015-11-11 21:38:21 +0100146
inikep3bfcfc72016-02-03 18:47:30 +0100147#define Litbits 8
inikep70b05452016-02-03 22:56:55 +0100148#define MaxLit ((1<<Litbits) - 1)
Yann Colletfadda6c2016-03-22 12:14:26 +0100149#define MaxML 52
Yann Colletb0aec172016-03-21 13:24:16 +0100150#define MaxLL 35
Yann Collet48537162016-04-07 15:24:29 +0200151#define MaxOff 28
Yann Collet4db09ef2016-03-18 22:23:49 +0100152#define MaxSeq MAX(MaxLL, MaxML) /* Assumption : MaxOff < MaxLL,MaxML */
Yann Colletbe391432016-03-22 23:19:28 +0100153#define MLFSELog 9
Yann Colletd64f4352016-03-21 00:07:42 +0100154#define LLFSELog 9
Yann Collet646693e2016-03-24 02:31:27 +0100155#define OffFSELog 8
inikepf3c65032016-03-04 20:04:25 +0100156
Yann Colletb0aec172016-03-21 13:24:16 +0100157static const U32 LL_bits[MaxLL+1] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
158 1, 1, 1, 1, 2, 2, 3, 3, 4, 6, 7, 8, 9,10,11,12,
159 13,14,15,16 };
Yann Collet48537162016-04-07 15:24:29 +0200160static const S16 LL_defaultNorm[MaxLL+1] = { 4, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1,
161 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 1, 1, 1, 1, 1,
162 -1,-1,-1,-1 };
Yann Collet51f4d562016-09-22 15:57:28 +0200163#define LL_DEFAULTNORMLOG 6 /* for static allocation */
164static const U32 LL_defaultNormLog = LL_DEFAULTNORMLOG;
Yann Colletb0aec172016-03-21 13:24:16 +0100165
Yann Colletfadda6c2016-03-22 12:14:26 +0100166static const U32 ML_bits[MaxML+1] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
167 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
168 1, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 7, 8, 9,10,11,
Yann Collet48537162016-04-07 15:24:29 +0200169 12,13,14,15,16 };
170static const S16 ML_defaultNorm[MaxML+1] = { 1, 4, 3, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1,
Yann Colletfadda6c2016-03-22 12:14:26 +0100171 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
Yann Collet48537162016-04-07 15:24:29 +0200172 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,-1,-1,
173 -1,-1,-1,-1,-1 };
Yann Collet51f4d562016-09-22 15:57:28 +0200174#define ML_DEFAULTNORMLOG 6 /* for static allocation */
175static const U32 ML_defaultNormLog = ML_DEFAULTNORMLOG;
Yann Colletfadda6c2016-03-22 12:14:26 +0100176
Yann Collet48537162016-04-07 15:24:29 +0200177static const S16 OF_defaultNorm[MaxOff+1] = { 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1,
178 1, 1, 1, 1, 1, 1, 1, 1,-1,-1,-1,-1,-1 };
Yann Collet51f4d562016-09-22 15:57:28 +0200179#define OF_DEFAULTNORMLOG 5 /* for static allocation */
180static const U32 OF_defaultNormLog = OF_DEFAULTNORMLOG;
Yann Collet48537162016-04-07 15:24:29 +0200181
Yann Collet2acb5d32015-10-29 16:49:43 +0100182
Yann Colletfb810d62016-01-28 00:18:06 +0100183/*-*******************************************
Yann Collet14983e72015-11-11 21:38:21 +0100184* Shared functions to include for inlining
Yann Colletfb810d62016-01-28 00:18:06 +0100185*********************************************/
Yann Collet2acb5d32015-10-29 16:49:43 +0100186static void ZSTD_copy8(void* dst, const void* src) { memcpy(dst, src, 8); }
Yann Collet2acb5d32015-10-29 16:49:43 +0100187#define COPY8(d,s) { ZSTD_copy8(d,s); d+=8; s+=8; }
188
Yann Collet953ce722016-02-04 15:28:14 +0100189/*! ZSTD_wildcopy() :
190* custom version of memcpy(), can copy up to 7 bytes too many (8 bytes if length==0) */
Yann Collet37f3d1b2016-03-19 15:11:42 +0100191#define WILDCOPY_OVERLENGTH 8
Nick Terrell064a1432016-12-12 19:01:23 -0800192MEM_STATIC void ZSTD_wildcopy(void* dst, const void* src, ptrdiff_t length)
Yann Collet2acb5d32015-10-29 16:49:43 +0100193{
194 const BYTE* ip = (const BYTE*)src;
195 BYTE* op = (BYTE*)dst;
196 BYTE* const oend = op + length;
Yann Collet50c5cdb2015-11-04 20:35:33 +0100197 do
198 COPY8(op, ip)
199 while (op < oend);
Yann Collet2acb5d32015-10-29 16:49:43 +0100200}
201
Yann Collet280f9a82016-08-08 00:44:00 +0200202MEM_STATIC void ZSTD_wildcopy_e(void* dst, const void* src, void* dstEnd) /* should be faster for decoding, but strangely, not verified on all platform */
203{
204 const BYTE* ip = (const BYTE*)src;
205 BYTE* op = (BYTE*)dst;
206 BYTE* const oend = (BYTE*)dstEnd;
207 do
208 COPY8(op, ip)
209 while (op < oend);
210}
211
Yann Collet7d360282016-02-12 00:07:30 +0100212
213/*-*******************************************
214* Private interfaces
215*********************************************/
inikep35b891c2016-05-20 19:42:20 +0200216typedef struct ZSTD_stats_s ZSTD_stats_t;
217
Yann Colleted57d852016-07-29 21:22:17 +0200218typedef struct seqDef_s {
219 U32 offset;
220 U16 litLength;
221 U16 matchLength;
222} seqDef;
223
224
inikep87d4f3d2016-03-02 15:56:24 +0100225typedef struct {
Yann Colletc0ce4f12016-07-30 00:55:13 +0200226 seqDef* sequencesStart;
Yann Colleted57d852016-07-29 21:22:17 +0200227 seqDef* sequences;
Yann Collet7d360282016-02-12 00:07:30 +0100228 BYTE* litStart;
229 BYTE* lit;
Yann Colleted57d852016-07-29 21:22:17 +0200230 BYTE* llCode;
231 BYTE* mlCode;
232 BYTE* ofCode;
Yann Collet5d393572016-04-07 17:19:00 +0200233 U32 longLengthID; /* 0 == no longLength; 1 == Lit.longLength; 2 == Match.longLength; */
234 U32 longLengthPos;
Nick Terrelle1982302017-07-17 12:27:24 -0700235 U32 rep[ZSTD_REP_NUM];
236 U32 repToConfirm[ZSTD_REP_NUM];
Nick Terrell7a28b9e2017-07-17 15:29:11 -0700237} seqStore_t;
238
239typedef struct {
240 U32 off;
241 U32 len;
242} ZSTD_match_t;
243
244typedef struct {
245 U32 price;
246 U32 off;
247 U32 mlen;
248 U32 litlen;
249 U32 rep[ZSTD_REP_NUM];
250} ZSTD_optimal_t;
251
252typedef struct {
Yann Collet7d360282016-02-12 00:07:30 +0100253 U32* litFreq;
Nick Terrell7a28b9e2017-07-17 15:29:11 -0700254 U32* litLengthFreq;
255 U32* matchLengthFreq;
Yann Collet7d360282016-02-12 00:07:30 +0100256 U32* offCodeFreq;
Nick Terrell7a28b9e2017-07-17 15:29:11 -0700257 ZSTD_match_t* matchTable;
258 ZSTD_optimal_t* priceTable;
259
Yann Collet7d360282016-02-12 00:07:30 +0100260 U32 matchLengthSum;
inikepe0010e92016-02-23 16:25:04 +0100261 U32 matchSum;
Yann Collet7d360282016-02-12 00:07:30 +0100262 U32 litLengthSum;
263 U32 litSum;
264 U32 offCodeSum;
inikepb5a519f2016-03-09 15:45:01 +0100265 U32 log2matchLengthSum;
266 U32 log2matchSum;
267 U32 log2litLengthSum;
268 U32 log2litSum;
269 U32 log2offCodeSum;
270 U32 factor;
Przemyslaw Skibinski9ca65af2016-11-23 17:22:54 +0100271 U32 staticPrices;
inikepf7d210b2016-04-11 16:35:13 +0200272 U32 cachedPrice;
273 U32 cachedLitLength;
274 const BYTE* cachedLiterals;
Nick Terrell7a28b9e2017-07-17 15:29:11 -0700275} optState_t;
Yann Collet7d360282016-02-12 00:07:30 +0100276
Nick Terrellde0414b2017-07-12 19:08:24 -0700277typedef struct {
Nick Terrellde0414b2017-07-12 19:08:24 -0700278 U32 hufCTable[HUF_CTABLE_SIZE_U32(255)];
Nick Terrellde0414b2017-07-12 19:08:24 -0700279 FSE_CTable offcodeCTable[FSE_CTABLE_SIZE_U32(OffFSELog, MaxOff)];
280 FSE_CTable matchlengthCTable[FSE_CTABLE_SIZE_U32(MLFSELog, MaxML)];
281 FSE_CTable litlengthCTable[FSE_CTABLE_SIZE_U32(LLFSELog, MaxLL)];
282 U32 workspace[HUF_WORKSPACE_SIZE_U32];
Nick Terrell830ef412017-07-13 12:45:39 -0700283 HUF_repeat hufCTable_repeatMode;
284 FSE_repeat offcode_repeatMode;
285 FSE_repeat matchlength_repeatMode;
286 FSE_repeat litlength_repeatMode;
Nick Terrellde0414b2017-07-12 19:08:24 -0700287} ZSTD_entropyCTables_t;
288
Yann Colletb44be742016-03-26 20:52:14 +0100289const seqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx);
Yann Colleted57d852016-07-29 21:22:17 +0200290void ZSTD_seqToCodes(const seqStore_t* seqStorePtr);
Yann Collet2acb5d32015-10-29 16:49:43 +0100291
inikepc4807f42016-06-02 15:11:39 +0200292/* custom memory allocation functions */
Yann Collet23b6e052016-08-28 21:05:43 -0700293void* ZSTD_malloc(size_t size, ZSTD_customMem customMem);
Yann Collet44e45e82017-05-30 16:12:06 -0700294void* ZSTD_calloc(size_t size, ZSTD_customMem customMem);
Yann Collet23b6e052016-08-28 21:05:43 -0700295void ZSTD_free(void* ptr, ZSTD_customMem customMem);
296
inikep2a746092016-06-03 14:53:51 +0200297
Yann Colletc154d9d2016-07-27 14:37:00 +0200298/*====== common function ======*/
299
300MEM_STATIC U32 ZSTD_highbit32(U32 val)
301{
302# if defined(_MSC_VER) /* Visual */
303 unsigned long r=0;
304 _BitScanReverse(&r, val);
305 return (unsigned)r;
306# elif defined(__GNUC__) && (__GNUC__ >= 3) /* GCC Intrinsic */
307 return 31 - __builtin_clz(val);
308# else /* Software version */
309 static const int DeBruijnClz[32] = { 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 };
310 U32 v = val;
311 int r;
312 v |= v >> 1;
313 v |= v >> 2;
314 v |= v >> 4;
315 v |= v >> 8;
316 v |= v >> 16;
317 r = DeBruijnClz[(U32)(v * 0x07C4ACDDU) >> 27];
318 return r;
319# endif
320}
321
322
Yann Collet32dfae62017-01-19 10:32:55 -0800323/* hidden functions */
324
325/* ZSTD_invalidateRepCodes() :
326 * ensures next compression will not use repcodes from previous block.
327 * Note : only works with regular variant;
328 * do not use with extDict variant ! */
329void ZSTD_invalidateRepCodes(ZSTD_CCtx* cctx);
330
331
Yann Collet8c910d22017-06-03 01:15:02 -0700332/*! ZSTD_initCStream_internal() :
333 * Private use only. Init streaming operation.
334 * expects params to be valid.
335 * must receive dict, or cdict, or none, but not both.
336 * @return : 0, or an error code */
337size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs,
cyan49738bcbf422017-06-04 23:52:00 -0700338 const void* dict, size_t dictSize,
339 const ZSTD_CDict* cdict,
340 ZSTD_parameters params, unsigned long long pledgedSrcSize);
Yann Collet8c910d22017-06-03 01:15:02 -0700341
Yann Collet5a773612017-07-03 15:21:24 -0700342/*! ZSTD_compressStream_generic() :
Yann Colletd5c046c2017-06-30 14:51:01 -0700343 * Private use only. To be called from zstdmt_compress.c in single-thread mode. */
344size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
345 ZSTD_outBuffer* output,
346 ZSTD_inBuffer* input,
347 ZSTD_EndDirective const flushMode);
Yann Collet8c910d22017-06-03 01:15:02 -0700348
349/*! ZSTD_getParamsFromCDict() :
350 * as the name implies */
351ZSTD_parameters ZSTD_getParamsFromCDict(const ZSTD_CDict* cdict);
352
353
Yann Colletf04deff2017-07-06 01:42:46 -0700354typedef struct {
355 blockType_e blockType;
356 U32 lastBlock;
357 U32 origSize;
358} blockProperties_t;
359
360/*! ZSTD_getcBlockSize() :
361* Provides the size of compressed block from block header `src` */
362size_t ZSTD_getcBlockSize(const void* src, size_t srcSize,
363 blockProperties_t* bpPtr);
364
365
Yann Collet2acb5d32015-10-29 16:49:43 +0100366#endif /* ZSTD_CCOMMON_H_MODULE */