blob: 73fc7705b94c09051a118cd7f98d67c427e03aa1 [file] [log] [blame]
Yann Collet32fb4072017-08-18 16:52:05 -07001/*
Yann Collet4ded9e52016-08-30 10:04:33 -07002 * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
3 * All rights reserved.
4 *
Yann Collet32fb4072017-08-18 16:52:05 -07005 * 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).
Yann Collet3128e032017-09-08 00:09:23 -07008 * You may select, at your option, one of the above-listed licenses.
Yann Collet4ded9e52016-08-30 10:04:33 -07009 */
Yann Collet2acb5d32015-10-29 16:49:43 +010010
Yann Collet2acb5d32015-10-29 16:49:43 +010011#ifndef ZSTD_CCOMMON_H_MODULE
12#define ZSTD_CCOMMON_H_MODULE
13
Yann Collet8b6aecf2017-11-07 15:27:06 -080014/* 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 */
Yann Collet5c956d52016-09-06 15:05:19 +020018
Yann Collet7d360282016-02-12 00:07:30 +010019/*-*************************************
Yann Collet953ce722016-02-04 15:28:14 +010020* Dependencies
Yann Collet2acb5d32015-10-29 16:49:43 +010021***************************************/
Nick Terrell565e9252017-08-14 17:20:50 -070022#include "compiler.h"
Yann Collet2acb5d32015-10-29 16:49:43 +010023#include "mem.h"
Yann Colletfa41bcc2018-06-13 14:59:26 -040024#include "debug.h" /* assert, DEBUGLOG, RAWLOG, g_debuglevel */
Yann Collet977f1f32016-01-21 15:38:47 +010025#include "error_private.h"
Yann Colletd3b7f8d2016-06-04 19:47:02 +020026#define ZSTD_STATIC_LINKING_ONLY
27#include "zstd.h"
Nick Terrellde0414b2017-07-12 19:08:24 -070028#define FSE_STATIC_LINKING_ONLY
29#include "fse.h"
30#define HUF_STATIC_LINKING_ONLY
31#include "huf.h"
Yann Collet4bcc69b2017-03-01 11:33:25 -080032#ifndef XXH_STATIC_LINKING_ONLY
Yann Collet58e8d792017-06-02 18:20:48 -070033# define XXH_STATIC_LINKING_ONLY /* XXH64_state_t */
Yann Collet4bcc69b2017-03-01 11:33:25 -080034#endif
Yann Collet58e8d792017-06-02 18:20:48 -070035#include "xxhash.h" /* XXH_reset, update, digest */
36
37
Nick Terrellde6c6bc2017-08-24 18:09:50 -070038#if defined (__cplusplus)
39extern "C" {
40#endif
41
Yann Colletfa41bcc2018-06-13 14:59:26 -040042/* ---- static assert (debug) --- */
43#define ZSTD_STATIC_ASSERT(c) DEBUG_STATIC_ASSERT(c)
Yann Colletccd2d422018-10-23 17:25:49 -070044#define ZSTD_isError ERR_isError /* for inlining */
45#define FSE_isError ERR_isError
46#define HUF_isError ERR_isError
Yann Collet2acb5d32015-10-29 16:49:43 +010047
48
Yann Collet7d360282016-02-12 00:07:30 +010049/*-*************************************
Yann Collet3e21ec52016-09-06 15:36:19 +020050* shared macros
Yann Collet14983e72015-11-11 21:38:21 +010051***************************************/
Yann Collet4f818182017-04-17 17:57:35 -070052#undef MIN
53#undef MAX
Yann Colletbe2010e2015-10-31 12:57:14 +010054#define MIN(a,b) ((a)<(b) ? (a) : (b))
Yann Collet14983e72015-11-11 21:38:21 +010055#define MAX(a,b) ((a)>(b) ? (a) : (b))
Yann Collet3e21ec52016-09-06 15:36:19 +020056#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 +020057#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 +010058
W. Felix Handte54fa31f2018-12-05 16:23:18 -080059#define RETURN_ERROR_IF(cond, err, ...) \
60 if (cond) { \
61 RAWLOG(3, "%s:%d: check %s failed, returning %s", __FILE__, __LINE__, ZSTD_QUOTE(cond), ZSTD_QUOTE(ERROR(err))); \
62 RAWLOG(3, ": " __VA_ARGS__); \
63 RAWLOG(3, "\n"); \
64 return ERROR(err); \
65 }
66
Yann Collet2acb5d32015-10-29 16:49:43 +010067
Yann Collet7d360282016-02-12 00:07:30 +010068/*-*************************************
Yann Collet14983e72015-11-11 21:38:21 +010069* Common constants
70***************************************/
inikep87d4f3d2016-03-02 15:56:24 +010071#define ZSTD_OPT_NUM (1<<12)
Yann Collet88fcd292015-11-25 14:42:45 +010072
inikep5f49eba2016-08-10 15:01:53 +020073#define ZSTD_REP_NUM 3 /* number of repcodes */
inikep5f49eba2016-08-10 15:01:53 +020074#define ZSTD_REP_MOVE (ZSTD_REP_NUM-1)
Yann Collet4266c0a2016-06-14 01:49:25 +020075static const U32 repStartValue[ZSTD_REP_NUM] = { 1, 4, 8 };
Yann Collet14983e72015-11-11 21:38:21 +010076
77#define KB *(1 <<10)
78#define MB *(1 <<20)
79#define GB *(1U<<30)
Yann Collet2acb5d32015-10-29 16:49:43 +010080
Yann Collet14983e72015-11-11 21:38:21 +010081#define BIT7 128
82#define BIT6 64
83#define BIT5 32
84#define BIT4 16
85#define BIT1 2
86#define BIT0 1
87
Yann Collet673f0d72016-06-06 00:26:38 +020088#define ZSTD_WINDOWLOG_ABSOLUTEMIN 10
89static const size_t ZSTD_fcs_fieldSize[4] = { 0, 2, 4, 8 };
Yann Colletc46fb922016-05-29 05:01:04 +020090static const size_t ZSTD_did_fieldSize[4] = { 0, 1, 2, 4 };
Yann Collet37f3d1b2016-03-19 15:11:42 +010091
Yann Collet6e66bbf2018-08-14 12:56:21 -070092#define ZSTD_FRAMEIDSIZE 4 /* magic number size */
Yann Colletb8d4a382017-09-25 15:25:07 -070093
Yann Collet49bb0042016-06-04 20:17:38 +020094#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 +010095static const size_t ZSTD_blockHeaderSize = ZSTD_BLOCKHEADERSIZE;
Yann Colletc991cc12016-07-28 00:55:43 +020096typedef enum { bt_raw, bt_rle, bt_compressed, bt_reserved } blockType_e;
Yann Collet37f3d1b2016-03-19 15:11:42 +010097
98#define MIN_SEQUENCES_SIZE 1 /* nbSeq==0 */
99#define MIN_CBLOCK_SIZE (1 /*litCSize*/ + 1 /* RLE or RAW */ + MIN_SEQUENCES_SIZE /* nbSeq==0 */) /* for a non-null block */
100
101#define HufLog 12
Yann Colletf8e7b532016-07-23 16:31:49 +0200102typedef enum { set_basic, set_rle, set_compressed, set_repeat } symbolEncodingType_e;
Yann Collet14983e72015-11-11 21:38:21 +0100103
Yann Collet37f3d1b2016-03-19 15:11:42 +0100104#define LONGNBSEQ 0x7F00
105
inikep7bc19b62016-04-06 09:46:01 +0200106#define MINMATCH 3
Yann Collet14983e72015-11-11 21:38:21 +0100107
inikep3bfcfc72016-02-03 18:47:30 +0100108#define Litbits 8
inikep70b05452016-02-03 22:56:55 +0100109#define MaxLit ((1<<Litbits) - 1)
Yann Collet95424402018-02-09 04:25:15 -0800110#define MaxML 52
111#define MaxLL 35
Nick Terrellbbe77212017-09-18 16:54:53 -0700112#define DefaultMaxOff 28
Yann Collet95424402018-02-09 04:25:15 -0800113#define MaxOff 31
Yann Collet4db09ef2016-03-18 22:23:49 +0100114#define MaxSeq MAX(MaxLL, MaxML) /* Assumption : MaxOff < MaxLL,MaxML */
Yann Colletbe391432016-03-22 23:19:28 +0100115#define MLFSELog 9
Yann Colletd64f4352016-03-21 00:07:42 +0100116#define LLFSELog 9
Yann Collet646693e2016-03-24 02:31:27 +0100117#define OffFSELog 8
Yann Collet95424402018-02-09 04:25:15 -0800118#define MaxFSELog MAX(MAX(MLFSELog, LLFSELog), OffFSELog)
inikepf3c65032016-03-04 20:04:25 +0100119
Yann Collet4191efa2017-11-08 11:05:32 -0800120static const U32 LL_bits[MaxLL+1] = { 0, 0, 0, 0, 0, 0, 0, 0,
121 0, 0, 0, 0, 0, 0, 0, 0,
122 1, 1, 1, 1, 2, 2, 3, 3,
123 4, 6, 7, 8, 9,10,11,12,
Yann Colletb0aec172016-03-21 13:24:16 +0100124 13,14,15,16 };
Yann Collet4191efa2017-11-08 11:05:32 -0800125static const S16 LL_defaultNorm[MaxLL+1] = { 4, 3, 2, 2, 2, 2, 2, 2,
126 2, 2, 2, 2, 2, 1, 1, 1,
127 2, 2, 2, 2, 2, 2, 2, 2,
128 2, 3, 2, 1, 1, 1, 1, 1,
Yann Collet48537162016-04-07 15:24:29 +0200129 -1,-1,-1,-1 };
Yann Collet51f4d562016-09-22 15:57:28 +0200130#define LL_DEFAULTNORMLOG 6 /* for static allocation */
131static const U32 LL_defaultNormLog = LL_DEFAULTNORMLOG;
Yann Colletb0aec172016-03-21 13:24:16 +0100132
Yann Collet4191efa2017-11-08 11:05:32 -0800133static const U32 ML_bits[MaxML+1] = { 0, 0, 0, 0, 0, 0, 0, 0,
134 0, 0, 0, 0, 0, 0, 0, 0,
135 0, 0, 0, 0, 0, 0, 0, 0,
136 0, 0, 0, 0, 0, 0, 0, 0,
137 1, 1, 1, 1, 2, 2, 3, 3,
138 4, 4, 5, 7, 8, 9,10,11,
Yann Collet48537162016-04-07 15:24:29 +0200139 12,13,14,15,16 };
Yann Collet4191efa2017-11-08 11:05:32 -0800140static const S16 ML_defaultNorm[MaxML+1] = { 1, 4, 3, 2, 2, 2, 2, 2,
141 2, 1, 1, 1, 1, 1, 1, 1,
142 1, 1, 1, 1, 1, 1, 1, 1,
143 1, 1, 1, 1, 1, 1, 1, 1,
144 1, 1, 1, 1, 1, 1, 1, 1,
145 1, 1, 1, 1, 1, 1,-1,-1,
Yann Collet48537162016-04-07 15:24:29 +0200146 -1,-1,-1,-1,-1 };
Yann Collet51f4d562016-09-22 15:57:28 +0200147#define ML_DEFAULTNORMLOG 6 /* for static allocation */
148static const U32 ML_defaultNormLog = ML_DEFAULTNORMLOG;
Yann Colletfadda6c2016-03-22 12:14:26 +0100149
Yann Collet4191efa2017-11-08 11:05:32 -0800150static const S16 OF_defaultNorm[DefaultMaxOff+1] = { 1, 1, 1, 1, 1, 1, 2, 2,
151 2, 1, 1, 1, 1, 1, 1, 1,
152 1, 1, 1, 1, 1, 1, 1, 1,
153 -1,-1,-1,-1,-1 };
Yann Collet51f4d562016-09-22 15:57:28 +0200154#define OF_DEFAULTNORMLOG 5 /* for static allocation */
155static const U32 OF_defaultNormLog = OF_DEFAULTNORMLOG;
Yann Collet48537162016-04-07 15:24:29 +0200156
Yann Collet2acb5d32015-10-29 16:49:43 +0100157
Yann Colletfb810d62016-01-28 00:18:06 +0100158/*-*******************************************
Yann Collet14983e72015-11-11 21:38:21 +0100159* Shared functions to include for inlining
Yann Colletfb810d62016-01-28 00:18:06 +0100160*********************************************/
Yann Collet2acb5d32015-10-29 16:49:43 +0100161static void ZSTD_copy8(void* dst, const void* src) { memcpy(dst, src, 8); }
Yann Collet2acb5d32015-10-29 16:49:43 +0100162#define COPY8(d,s) { ZSTD_copy8(d,s); d+=8; s+=8; }
163
Yann Collet953ce722016-02-04 15:28:14 +0100164/*! ZSTD_wildcopy() :
Yann Colletcdade552017-11-17 11:40:08 -0800165 * custom version of memcpy(), can overwrite up to WILDCOPY_OVERLENGTH bytes (if length==0) */
Yann Collet37f3d1b2016-03-19 15:11:42 +0100166#define WILDCOPY_OVERLENGTH 8
Nick Terrell064a1432016-12-12 19:01:23 -0800167MEM_STATIC void ZSTD_wildcopy(void* dst, const void* src, ptrdiff_t length)
Yann Collet2acb5d32015-10-29 16:49:43 +0100168{
169 const BYTE* ip = (const BYTE*)src;
170 BYTE* op = (BYTE*)dst;
171 BYTE* const oend = op + length;
Yann Collet50c5cdb2015-11-04 20:35:33 +0100172 do
173 COPY8(op, ip)
174 while (op < oend);
Yann Collet2acb5d32015-10-29 16:49:43 +0100175}
176
Yann Collet280f9a82016-08-08 00:44:00 +0200177MEM_STATIC void ZSTD_wildcopy_e(void* dst, const void* src, void* dstEnd) /* should be faster for decoding, but strangely, not verified on all platform */
178{
179 const BYTE* ip = (const BYTE*)src;
180 BYTE* op = (BYTE*)dst;
181 BYTE* const oend = (BYTE*)dstEnd;
182 do
183 COPY8(op, ip)
184 while (op < oend);
185}
186
Yann Collet7d360282016-02-12 00:07:30 +0100187
188/*-*******************************************
Yann Collet8b6aecf2017-11-07 15:27:06 -0800189* Private declarations
Yann Collet7d360282016-02-12 00:07:30 +0100190*********************************************/
Yann Colleted57d852016-07-29 21:22:17 +0200191typedef struct seqDef_s {
192 U32 offset;
193 U16 litLength;
194 U16 matchLength;
195} seqDef;
196
inikep87d4f3d2016-03-02 15:56:24 +0100197typedef struct {
Yann Colletc0ce4f12016-07-30 00:55:13 +0200198 seqDef* sequencesStart;
Yann Colleted57d852016-07-29 21:22:17 +0200199 seqDef* sequences;
Yann Collet7d360282016-02-12 00:07:30 +0100200 BYTE* litStart;
201 BYTE* lit;
Yann Colleted57d852016-07-29 21:22:17 +0200202 BYTE* llCode;
203 BYTE* mlCode;
204 BYTE* ofCode;
Nick Terrell924944e2018-08-21 14:20:02 -0700205 size_t maxNbSeq;
Nick Terrell5e580de2018-08-28 13:24:44 -0700206 size_t maxNbLit;
Yann Collet5d393572016-04-07 17:19:00 +0200207 U32 longLengthID; /* 0 == no longLength; 1 == Lit.longLength; 2 == Match.longLength; */
208 U32 longLengthPos;
Nick Terrell7a28b9e2017-07-17 15:29:11 -0700209} seqStore_t;
210
Yann Collet8b6aecf2017-11-07 15:27:06 -0800211const seqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx); /* compress & dictBuilder */
212void ZSTD_seqToCodes(const seqStore_t* seqStorePtr); /* compress, dictBuilder, decodeCorpus (shouldn't get its definition from here) */
Yann Collet2acb5d32015-10-29 16:49:43 +0100213
inikepc4807f42016-06-02 15:11:39 +0200214/* custom memory allocation functions */
Yann Collet23b6e052016-08-28 21:05:43 -0700215void* ZSTD_malloc(size_t size, ZSTD_customMem customMem);
Yann Collet44e45e82017-05-30 16:12:06 -0700216void* ZSTD_calloc(size_t size, ZSTD_customMem customMem);
Yann Collet23b6e052016-08-28 21:05:43 -0700217void ZSTD_free(void* ptr, ZSTD_customMem customMem);
218
inikep2a746092016-06-03 14:53:51 +0200219
Yann Collet8b6aecf2017-11-07 15:27:06 -0800220MEM_STATIC U32 ZSTD_highbit32(U32 val) /* compress, dictBuilder, decodeCorpus */
Yann Colletc154d9d2016-07-27 14:37:00 +0200221{
Stella Laue50ed1f2017-08-22 11:55:42 -0700222 assert(val != 0);
223 {
Yann Colletc154d9d2016-07-27 14:37:00 +0200224# if defined(_MSC_VER) /* Visual */
Stella Laue50ed1f2017-08-22 11:55:42 -0700225 unsigned long r=0;
226 _BitScanReverse(&r, val);
227 return (unsigned)r;
Yann Colletc154d9d2016-07-27 14:37:00 +0200228# elif defined(__GNUC__) && (__GNUC__ >= 3) /* GCC Intrinsic */
Stella Laue50ed1f2017-08-22 11:55:42 -0700229 return 31 - __builtin_clz(val);
Yann Colletc154d9d2016-07-27 14:37:00 +0200230# else /* Software version */
Yann Collet0a0a2122017-11-28 14:07:03 -0800231 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 };
Stella Laue50ed1f2017-08-22 11:55:42 -0700232 U32 v = val;
Stella Laue50ed1f2017-08-22 11:55:42 -0700233 v |= v >> 1;
234 v |= v >> 2;
235 v |= v >> 4;
236 v |= v >> 8;
237 v |= v >> 16;
Yann Collet0a0a2122017-11-28 14:07:03 -0800238 return DeBruijnClz[(v * 0x07C4ACDDU) >> 27];
Yann Colletc154d9d2016-07-27 14:37:00 +0200239# endif
Stella Laue50ed1f2017-08-22 11:55:42 -0700240 }
Yann Colletc154d9d2016-07-27 14:37:00 +0200241}
242
243
Yann Collet32dfae62017-01-19 10:32:55 -0800244/* ZSTD_invalidateRepCodes() :
245 * ensures next compression will not use repcodes from previous block.
246 * Note : only works with regular variant;
247 * do not use with extDict variant ! */
Yann Collet8b6aecf2017-11-07 15:27:06 -0800248void ZSTD_invalidateRepCodes(ZSTD_CCtx* cctx); /* zstdmt, adaptive_compression (shouldn't get this definition from here) */
Yann Collet32dfae62017-01-19 10:32:55 -0800249
250
Yann Colletf04deff2017-07-06 01:42:46 -0700251typedef struct {
252 blockType_e blockType;
253 U32 lastBlock;
254 U32 origSize;
Yann Collet2b491402018-10-25 16:28:41 -0700255} blockProperties_t; /* declared here for decompress and fullbench */
Yann Colletf04deff2017-07-06 01:42:46 -0700256
257/*! ZSTD_getcBlockSize() :
Yann Collet4191efa2017-11-08 11:05:32 -0800258 * Provides the size of compressed block from block header `src` */
259/* Used by: decompress, fullbench (does not get its definition from here) */
Yann Colletf04deff2017-07-06 01:42:46 -0700260size_t ZSTD_getcBlockSize(const void* src, size_t srcSize,
261 blockProperties_t* bpPtr);
262
Yann Collet2b491402018-10-25 16:28:41 -0700263/*! ZSTD_decodeSeqHeaders() :
264 * decode sequence header from src */
265/* Used by: decompress, fullbench (does not get its definition from here) */
266size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr,
267 const void* src, size_t srcSize);
268
269
Nick Terrellde6c6bc2017-08-24 18:09:50 -0700270#if defined (__cplusplus)
271}
272#endif
Yann Colletf04deff2017-07-06 01:42:46 -0700273
Yann Collet2acb5d32015-10-29 16:49:43 +0100274#endif /* ZSTD_CCOMMON_H_MODULE */