blob: 3bc7e55a0a97aa7e9dfb8ef7eb0fd76d7dfb374f [file] [log] [blame]
Yann Collet32fb4072017-08-18 16:52:05 -07001/*
Nick Terrellac58c8d2020-03-26 15:19:05 -07002 * Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
Yann Collet4ded9e52016-08-30 10:04:33 -07003 * 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***************************************/
caoyzh7f75f052020-03-28 00:11:50 +080022#ifdef __aarch64__
23#include <arm_neon.h>
24#endif
Nick Terrell565e9252017-08-14 17:20:50 -070025#include "compiler.h"
Yann Collet2acb5d32015-10-29 16:49:43 +010026#include "mem.h"
Yann Colletfa41bcc2018-06-13 14:59:26 -040027#include "debug.h" /* assert, DEBUGLOG, RAWLOG, g_debuglevel */
Yann Collet977f1f32016-01-21 15:38:47 +010028#include "error_private.h"
Yann Colletd3b7f8d2016-06-04 19:47:02 +020029#define ZSTD_STATIC_LINKING_ONLY
W. Felix Handte60288272020-05-01 16:07:57 -040030#include "../zstd.h"
Nick Terrellde0414b2017-07-12 19:08:24 -070031#define FSE_STATIC_LINKING_ONLY
32#include "fse.h"
33#define HUF_STATIC_LINKING_ONLY
34#include "huf.h"
Yann Collet4bcc69b2017-03-01 11:33:25 -080035#ifndef XXH_STATIC_LINKING_ONLY
Yann Collet58e8d792017-06-02 18:20:48 -070036# define XXH_STATIC_LINKING_ONLY /* XXH64_state_t */
Yann Collet4bcc69b2017-03-01 11:33:25 -080037#endif
Yann Collet58e8d792017-06-02 18:20:48 -070038#include "xxhash.h" /* XXH_reset, update, digest */
39
Nick Terrellde6c6bc2017-08-24 18:09:50 -070040#if defined (__cplusplus)
41extern "C" {
42#endif
43
Yann Colletfa41bcc2018-06-13 14:59:26 -040044/* ---- static assert (debug) --- */
45#define ZSTD_STATIC_ASSERT(c) DEBUG_STATIC_ASSERT(c)
Yann Colletccd2d422018-10-23 17:25:49 -070046#define ZSTD_isError ERR_isError /* for inlining */
47#define FSE_isError ERR_isError
48#define HUF_isError ERR_isError
Yann Collet2acb5d32015-10-29 16:49:43 +010049
50
Yann Collet7d360282016-02-12 00:07:30 +010051/*-*************************************
Yann Collet3e21ec52016-09-06 15:36:19 +020052* shared macros
Yann Collet14983e72015-11-11 21:38:21 +010053***************************************/
Yann Collet4f818182017-04-17 17:57:35 -070054#undef MIN
55#undef MAX
Yann Colletbe2010e2015-10-31 12:57:14 +010056#define MIN(a,b) ((a)<(b) ? (a) : (b))
Yann Collet14983e72015-11-11 21:38:21 +010057#define MAX(a,b) ((a)>(b) ? (a) : (b))
W. Felix Handte7ebd8972019-01-28 17:16:32 -050058
W. Felix Handtebaa4e2e2020-04-30 17:07:49 -040059/**
60 * Ignore: this is an internal helper.
61 *
62 * This is a helper function to help force C99-correctness during compilation.
63 * Under strict compilation modes, variadic macro arguments can't be empty.
64 * However, variadic function arguments can be. Using a function therefore lets
65 * us statically check that at least one (string) argument was passed,
66 * independent of the compilation flags.
67 */
W. Felix Handte37648592020-04-30 17:43:20 -040068static INLINE_KEYWORD UNUSED_ATTR
69void _force_has_format_string(const char *format, ...) {
W. Felix Handte450542d2020-04-30 13:09:14 -040070 (void)format;
71}
72
W. Felix Handtea3538bb2019-01-28 12:34:08 -050073/**
W. Felix Handtebaa4e2e2020-04-30 17:07:49 -040074 * Ignore: this is an internal helper.
75 *
76 * We want to force this function invocation to be syntactically correct, but
77 * we don't want to force runtime evaluation of its arguments.
78 */
79#define _FORCE_HAS_FORMAT_STRING(...) \
80 if (0) { \
81 _force_has_format_string(__VA_ARGS__); \
82 }
83
84/**
W. Felix Handtea3538bb2019-01-28 12:34:08 -050085 * Return the specified error if the condition evaluates to true.
86 *
Yann Collet0b0b83e2019-08-03 16:43:34 +020087 * In debug modes, prints additional information.
88 * In order to do that (particularly, printing the conditional that failed),
89 * this can't just wrap RETURN_ERROR().
W. Felix Handtea3538bb2019-01-28 12:34:08 -050090 */
W. Felix Handte54fa31f2018-12-05 16:23:18 -080091#define RETURN_ERROR_IF(cond, err, ...) \
92 if (cond) { \
W. Felix Handte450542d2020-04-30 13:09:14 -040093 RAWLOG(3, "%s:%d: ERROR!: check %s failed, returning %s", \
94 __FILE__, __LINE__, ZSTD_QUOTE(cond), ZSTD_QUOTE(ERROR(err))); \
W. Felix Handtebaa4e2e2020-04-30 17:07:49 -040095 _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \
W. Felix Handte450542d2020-04-30 13:09:14 -040096 RAWLOG(3, ": " __VA_ARGS__); \
W. Felix Handte54fa31f2018-12-05 16:23:18 -080097 RAWLOG(3, "\n"); \
98 return ERROR(err); \
99 }
100
W. Felix Handtea3538bb2019-01-28 12:34:08 -0500101/**
102 * Unconditionally return the specified error.
103 *
104 * In debug modes, prints additional information.
105 */
106#define RETURN_ERROR(err, ...) \
107 do { \
W. Felix Handte450542d2020-04-30 13:09:14 -0400108 RAWLOG(3, "%s:%d: ERROR!: unconditional check failed, returning %s", \
109 __FILE__, __LINE__, ZSTD_QUOTE(ERROR(err))); \
W. Felix Handtebaa4e2e2020-04-30 17:07:49 -0400110 _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \
W. Felix Handte450542d2020-04-30 13:09:14 -0400111 RAWLOG(3, ": " __VA_ARGS__); \
W. Felix Handtea3538bb2019-01-28 12:34:08 -0500112 RAWLOG(3, "\n"); \
113 return ERROR(err); \
114 } while(0);
115
116/**
117 * If the provided expression evaluates to an error code, returns that error code.
118 *
119 * In debug modes, prints additional information.
120 */
W. Felix Handte501eb252019-01-29 12:56:07 -0500121#define FORWARD_IF_ERROR(err, ...) \
W. Felix Handtea3538bb2019-01-28 12:34:08 -0500122 do { \
123 size_t const err_code = (err); \
124 if (ERR_isError(err_code)) { \
W. Felix Handte450542d2020-04-30 13:09:14 -0400125 RAWLOG(3, "%s:%d: ERROR!: forwarding error in %s: %s", \
126 __FILE__, __LINE__, ZSTD_QUOTE(err), ERR_getErrorName(err_code)); \
W. Felix Handtebaa4e2e2020-04-30 17:07:49 -0400127 _FORCE_HAS_FORMAT_STRING(__VA_ARGS__); \
W. Felix Handte450542d2020-04-30 13:09:14 -0400128 RAWLOG(3, ": " __VA_ARGS__); \
W. Felix Handtea3538bb2019-01-28 12:34:08 -0500129 RAWLOG(3, "\n"); \
130 return err_code; \
131 } \
132 } while(0);
133
Yann Collet2acb5d32015-10-29 16:49:43 +0100134
Yann Collet7d360282016-02-12 00:07:30 +0100135/*-*************************************
Yann Collet14983e72015-11-11 21:38:21 +0100136* Common constants
137***************************************/
inikep87d4f3d2016-03-02 15:56:24 +0100138#define ZSTD_OPT_NUM (1<<12)
Yann Collet88fcd292015-11-25 14:42:45 +0100139
inikep5f49eba2016-08-10 15:01:53 +0200140#define ZSTD_REP_NUM 3 /* number of repcodes */
inikep5f49eba2016-08-10 15:01:53 +0200141#define ZSTD_REP_MOVE (ZSTD_REP_NUM-1)
Yann Collet4266c0a2016-06-14 01:49:25 +0200142static const U32 repStartValue[ZSTD_REP_NUM] = { 1, 4, 8 };
Yann Collet14983e72015-11-11 21:38:21 +0100143
144#define KB *(1 <<10)
145#define MB *(1 <<20)
146#define GB *(1U<<30)
Yann Collet2acb5d32015-10-29 16:49:43 +0100147
Yann Collet14983e72015-11-11 21:38:21 +0100148#define BIT7 128
149#define BIT6 64
150#define BIT5 32
151#define BIT4 16
152#define BIT1 2
153#define BIT0 1
154
Yann Collet673f0d72016-06-06 00:26:38 +0200155#define ZSTD_WINDOWLOG_ABSOLUTEMIN 10
156static const size_t ZSTD_fcs_fieldSize[4] = { 0, 2, 4, 8 };
Yann Colletc46fb922016-05-29 05:01:04 +0200157static const size_t ZSTD_did_fieldSize[4] = { 0, 1, 2, 4 };
Yann Collet37f3d1b2016-03-19 15:11:42 +0100158
Yann Collet6e66bbf2018-08-14 12:56:21 -0700159#define ZSTD_FRAMEIDSIZE 4 /* magic number size */
Yann Colletb8d4a382017-09-25 15:25:07 -0700160
Yann Collet49bb0042016-06-04 20:17:38 +0200161#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 +0100162static const size_t ZSTD_blockHeaderSize = ZSTD_BLOCKHEADERSIZE;
Yann Colletc991cc12016-07-28 00:55:43 +0200163typedef enum { bt_raw, bt_rle, bt_compressed, bt_reserved } blockType_e;
Yann Collet37f3d1b2016-03-19 15:11:42 +0100164
Bimba Shresthab1f53b12020-01-03 16:53:51 -0800165#define ZSTD_FRAMECHECKSUMSIZE 4
166
Yann Collet37f3d1b2016-03-19 15:11:42 +0100167#define MIN_SEQUENCES_SIZE 1 /* nbSeq==0 */
168#define MIN_CBLOCK_SIZE (1 /*litCSize*/ + 1 /* RLE or RAW */ + MIN_SEQUENCES_SIZE /* nbSeq==0 */) /* for a non-null block */
169
170#define HufLog 12
Yann Colletf8e7b532016-07-23 16:31:49 +0200171typedef enum { set_basic, set_rle, set_compressed, set_repeat } symbolEncodingType_e;
Yann Collet14983e72015-11-11 21:38:21 +0100172
Yann Collet37f3d1b2016-03-19 15:11:42 +0100173#define LONGNBSEQ 0x7F00
174
inikep7bc19b62016-04-06 09:46:01 +0200175#define MINMATCH 3
Yann Collet14983e72015-11-11 21:38:21 +0100176
inikep3bfcfc72016-02-03 18:47:30 +0100177#define Litbits 8
inikep70b05452016-02-03 22:56:55 +0100178#define MaxLit ((1<<Litbits) - 1)
Yann Collet95424402018-02-09 04:25:15 -0800179#define MaxML 52
180#define MaxLL 35
Nick Terrellbbe77212017-09-18 16:54:53 -0700181#define DefaultMaxOff 28
Yann Collet95424402018-02-09 04:25:15 -0800182#define MaxOff 31
Yann Collet4db09ef2016-03-18 22:23:49 +0100183#define MaxSeq MAX(MaxLL, MaxML) /* Assumption : MaxOff < MaxLL,MaxML */
Yann Colletbe391432016-03-22 23:19:28 +0100184#define MLFSELog 9
Yann Colletd64f4352016-03-21 00:07:42 +0100185#define LLFSELog 9
Yann Collet646693e2016-03-24 02:31:27 +0100186#define OffFSELog 8
Yann Collet95424402018-02-09 04:25:15 -0800187#define MaxFSELog MAX(MAX(MLFSELog, LLFSELog), OffFSELog)
inikepf3c65032016-03-04 20:04:25 +0100188
Yann Collet4191efa2017-11-08 11:05:32 -0800189static const U32 LL_bits[MaxLL+1] = { 0, 0, 0, 0, 0, 0, 0, 0,
190 0, 0, 0, 0, 0, 0, 0, 0,
191 1, 1, 1, 1, 2, 2, 3, 3,
192 4, 6, 7, 8, 9,10,11,12,
Yann Colletb0aec172016-03-21 13:24:16 +0100193 13,14,15,16 };
Yann Collet4191efa2017-11-08 11:05:32 -0800194static const S16 LL_defaultNorm[MaxLL+1] = { 4, 3, 2, 2, 2, 2, 2, 2,
195 2, 2, 2, 2, 2, 1, 1, 1,
196 2, 2, 2, 2, 2, 2, 2, 2,
197 2, 3, 2, 1, 1, 1, 1, 1,
Yann Collet48537162016-04-07 15:24:29 +0200198 -1,-1,-1,-1 };
Yann Collet51f4d562016-09-22 15:57:28 +0200199#define LL_DEFAULTNORMLOG 6 /* for static allocation */
200static const U32 LL_defaultNormLog = LL_DEFAULTNORMLOG;
Yann Colletb0aec172016-03-21 13:24:16 +0100201
Yann Collet4191efa2017-11-08 11:05:32 -0800202static const U32 ML_bits[MaxML+1] = { 0, 0, 0, 0, 0, 0, 0, 0,
203 0, 0, 0, 0, 0, 0, 0, 0,
204 0, 0, 0, 0, 0, 0, 0, 0,
205 0, 0, 0, 0, 0, 0, 0, 0,
206 1, 1, 1, 1, 2, 2, 3, 3,
207 4, 4, 5, 7, 8, 9,10,11,
Yann Collet48537162016-04-07 15:24:29 +0200208 12,13,14,15,16 };
Yann Collet4191efa2017-11-08 11:05:32 -0800209static const S16 ML_defaultNorm[MaxML+1] = { 1, 4, 3, 2, 2, 2, 2, 2,
210 2, 1, 1, 1, 1, 1, 1, 1,
211 1, 1, 1, 1, 1, 1, 1, 1,
212 1, 1, 1, 1, 1, 1, 1, 1,
213 1, 1, 1, 1, 1, 1, 1, 1,
214 1, 1, 1, 1, 1, 1,-1,-1,
Yann Collet48537162016-04-07 15:24:29 +0200215 -1,-1,-1,-1,-1 };
Yann Collet51f4d562016-09-22 15:57:28 +0200216#define ML_DEFAULTNORMLOG 6 /* for static allocation */
217static const U32 ML_defaultNormLog = ML_DEFAULTNORMLOG;
Yann Colletfadda6c2016-03-22 12:14:26 +0100218
Yann Collet4191efa2017-11-08 11:05:32 -0800219static const S16 OF_defaultNorm[DefaultMaxOff+1] = { 1, 1, 1, 1, 1, 1, 2, 2,
220 2, 1, 1, 1, 1, 1, 1, 1,
221 1, 1, 1, 1, 1, 1, 1, 1,
222 -1,-1,-1,-1,-1 };
Yann Collet51f4d562016-09-22 15:57:28 +0200223#define OF_DEFAULTNORMLOG 5 /* for static allocation */
224static const U32 OF_defaultNormLog = OF_DEFAULTNORMLOG;
Yann Collet48537162016-04-07 15:24:29 +0200225
Yann Collet2acb5d32015-10-29 16:49:43 +0100226
Yann Colletfb810d62016-01-28 00:18:06 +0100227/*-*******************************************
Yann Collet14983e72015-11-11 21:38:21 +0100228* Shared functions to include for inlining
Yann Colletfb810d62016-01-28 00:18:06 +0100229*********************************************/
caoyzhb2e56f72020-03-16 11:07:31 +0800230static void ZSTD_copy8(void* dst, const void* src) {
231#ifdef __aarch64__
232 vst1_u8((uint8_t*)dst, vld1_u8((const uint8_t*)src));
233#else
234 memcpy(dst, src, 8);
235#endif
236}
mgrice812e8f22019-07-11 15:31:07 -0700237
Yann Collet2acb5d32015-10-29 16:49:43 +0100238#define COPY8(d,s) { ZSTD_copy8(d,s); d+=8; s+=8; }
caoyzhb2e56f72020-03-16 11:07:31 +0800239static void ZSTD_copy16(void* dst, const void* src) {
240#ifdef __aarch64__
241 vst1q_u8((uint8_t*)dst, vld1q_u8((const uint8_t*)src));
242#else
243 memcpy(dst, src, 16);
244#endif
245}
mgrice812e8f22019-07-11 15:31:07 -0700246#define COPY16(d,s) { ZSTD_copy16(d,s); d+=16; s+=16; }
247
Nick Terrellcdad7fa2019-09-20 00:52:15 -0700248#define WILDCOPY_OVERLENGTH 32
Nick Terrellefd37a62019-09-19 13:25:03 -0700249#define WILDCOPY_VECLEN 16
mgrice812e8f22019-07-11 15:31:07 -0700250
251typedef enum {
252 ZSTD_no_overlap,
Yann Colletcb18fff2019-09-24 17:50:58 -0700253 ZSTD_overlap_src_before_dst
mgrice812e8f22019-07-11 15:31:07 -0700254 /* ZSTD_overlap_dst_before_src, */
255} ZSTD_overlap_e;
Yann Collet2acb5d32015-10-29 16:49:43 +0100256
Yann Collet953ce722016-02-04 15:28:14 +0100257/*! ZSTD_wildcopy() :
Nick Terrellefd37a62019-09-19 13:25:03 -0700258 * Custom version of memcpy(), can over read/write up to WILDCOPY_OVERLENGTH bytes (if length==0)
259 * @param ovtype controls the overlap detection
260 * - ZSTD_no_overlap: The source and destination are guaranteed to be at least WILDCOPY_VECLEN bytes apart.
261 * - ZSTD_overlap_src_before_dst: The src and dst may overlap, but they MUST be at least 8 bytes apart.
262 * The src buffer must be before the dst buffer.
263 */
Nick Terrelle32e3e82020-01-28 20:37:04 -0800264MEM_STATIC FORCE_INLINE_ATTR
Nick Terrell44c65da2019-09-20 12:23:25 -0700265void ZSTD_wildcopy(void* dst, const void* src, ptrdiff_t length, ZSTD_overlap_e const ovtype)
Yann Collet2acb5d32015-10-29 16:49:43 +0100266{
mgrice812e8f22019-07-11 15:31:07 -0700267 ptrdiff_t diff = (BYTE*)dst - (const BYTE*)src;
Yann Collet2acb5d32015-10-29 16:49:43 +0100268 const BYTE* ip = (const BYTE*)src;
269 BYTE* op = (BYTE*)dst;
270 BYTE* const oend = op + length;
mgrice812e8f22019-07-11 15:31:07 -0700271
Nick Terrellefd37a62019-09-19 13:25:03 -0700272 assert(diff >= 8 || (ovtype == ZSTD_no_overlap && diff <= -WILDCOPY_VECLEN));
mgriceb8305992019-08-27 14:49:23 -0700273
Nick Terrellefd37a62019-09-19 13:25:03 -0700274 if (ovtype == ZSTD_overlap_src_before_dst && diff < WILDCOPY_VECLEN) {
275 /* Handle short offset copies. */
mgriceb8305992019-08-27 14:49:23 -0700276 do {
Nick Terrellefd37a62019-09-19 13:25:03 -0700277 COPY8(op, ip)
278 } while (op < oend);
279 } else {
280 assert(diff >= WILDCOPY_VECLEN || diff <= -WILDCOPY_VECLEN);
Nick Terrelle32e3e82020-01-28 20:37:04 -0800281 /* Separate out the first COPY16() call because the copy length is
Nick Terrellefd37a62019-09-19 13:25:03 -0700282 * almost certain to be short, so the branches have different
Nick Terrelle32e3e82020-01-28 20:37:04 -0800283 * probabilities. Since it is almost certain to be short, only do
caoyzh9e802ed2020-04-02 23:08:13 +0800284 * one COPY16() in the first call. Then, do two calls per loop since
285 * at that point it is more likely to have a high trip count.
Nick Terrellefd37a62019-09-19 13:25:03 -0700286 */
caoyzhb2e56f72020-03-16 11:07:31 +0800287#ifndef __aarch64__
caoyzh969ba4f2020-04-14 21:33:25 +0800288 do {
289 COPY16(op, ip);
290 }
291 while (op < oend);
292#else
Nick Terrellefd37a62019-09-19 13:25:03 -0700293 COPY16(op, ip);
Nick Terrellefd37a62019-09-19 13:25:03 -0700294 if (op >= oend) return;
295 do {
296 COPY16(op, ip);
Nick Terrellcdad7fa2019-09-20 00:52:15 -0700297 COPY16(op, ip);
mgriceb8305992019-08-27 14:49:23 -0700298 }
299 while (op < oend);
caoyzh969ba4f2020-04-14 21:33:25 +0800300#endif
mgrice812e8f22019-07-11 15:31:07 -0700301 }
302}
303
Carl Woffendenedd9a072020-04-07 11:02:06 +0200304MEM_STATIC size_t ZSTD_limitCopy(void* dst, size_t dstCapacity, const void* src, size_t srcSize)
305{
306 size_t const length = MIN(dstCapacity, srcSize);
307 if (length > 0) {
308 memcpy(dst, src, length);
309 }
310 return length;
311}
Yann Collet7d360282016-02-12 00:07:30 +0100312
Bimba Shrestha01548662020-04-03 14:26:15 -0700313/* define "workspace is too large" as this number of times larger than needed */
314#define ZSTD_WORKSPACETOOLARGE_FACTOR 3
315
316/* when workspace is continuously too large
317 * during at least this number of times,
318 * context's memory usage is considered wasteful,
319 * because it's sized to handle a worst case scenario which rarely happens.
320 * In which case, resize it down to free some memory */
321#define ZSTD_WORKSPACETOOLARGE_MAXDURATION 128
322
Yann Collet7d360282016-02-12 00:07:30 +0100323
324/*-*******************************************
Yann Collet8b6aecf2017-11-07 15:27:06 -0800325* Private declarations
Yann Collet7d360282016-02-12 00:07:30 +0100326*********************************************/
Yann Colleted57d852016-07-29 21:22:17 +0200327typedef struct seqDef_s {
328 U32 offset;
329 U16 litLength;
330 U16 matchLength;
331} seqDef;
332
inikep87d4f3d2016-03-02 15:56:24 +0100333typedef struct {
Yann Colletc0ce4f12016-07-30 00:55:13 +0200334 seqDef* sequencesStart;
Yann Colleted57d852016-07-29 21:22:17 +0200335 seqDef* sequences;
Yann Collet7d360282016-02-12 00:07:30 +0100336 BYTE* litStart;
337 BYTE* lit;
Yann Colleted57d852016-07-29 21:22:17 +0200338 BYTE* llCode;
339 BYTE* mlCode;
340 BYTE* ofCode;
Nick Terrell924944e2018-08-21 14:20:02 -0700341 size_t maxNbSeq;
Nick Terrell5e580de2018-08-28 13:24:44 -0700342 size_t maxNbLit;
Yann Collet5d393572016-04-07 17:19:00 +0200343 U32 longLengthID; /* 0 == no longLength; 1 == Lit.longLength; 2 == Match.longLength; */
344 U32 longLengthPos;
Nick Terrell7a28b9e2017-07-17 15:29:11 -0700345} seqStore_t;
346
Nick Terrelle103d7b2020-05-01 16:11:47 -0700347typedef struct {
348 U32 litLength;
349 U32 matchLength;
350} ZSTD_sequenceLength;
351
352/**
353 * Returns the ZSTD_sequenceLength for the given sequences. It handles the decoding of long sequences
354 * indicated by longLengthPos and longLengthID, and adds MINMATCH back to matchLength.
355 */
356MEM_STATIC ZSTD_sequenceLength ZSTD_getSequenceLength(seqStore_t const* seqStore, seqDef const* seq)
357{
358 ZSTD_sequenceLength seqLen;
359 seqLen.litLength = seq->litLength;
360 seqLen.matchLength = seq->matchLength + MINMATCH;
361 if (seqStore->longLengthPos == (U32)(seq - seqStore->sequencesStart)) {
362 if (seqStore->longLengthID == 1) {
363 seqLen.litLength += 0xFFFF;
364 }
365 if (seqStore->longLengthID == 2) {
366 seqLen.matchLength += 0xFFFF;
367 }
368 }
369 return seqLen;
370}
371
shakeelrao19b75b62019-03-15 18:04:19 -0700372/**
373 * Contains the compressed frame size and an upper-bound for the decompressed frame size.
shakeelrao0033bb42019-03-17 17:41:27 -0700374 * Note: before using `compressedSize`, check for errors using ZSTD_isError().
375 * similarly, before using `decompressedBound`, check for errors using:
376 * `decompressedBound != ZSTD_CONTENTSIZE_ERROR`
shakeelrao19b75b62019-03-15 18:04:19 -0700377 */
378typedef struct {
379 size_t compressedSize;
380 unsigned long long decompressedBound;
shakeelrao0033bb42019-03-17 17:41:27 -0700381} ZSTD_frameSizeInfo; /* decompress & legacy */
shakeelrao19b75b62019-03-15 18:04:19 -0700382
Yann Collet8b6aecf2017-11-07 15:27:06 -0800383const seqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx); /* compress & dictBuilder */
384void ZSTD_seqToCodes(const seqStore_t* seqStorePtr); /* compress, dictBuilder, decodeCorpus (shouldn't get its definition from here) */
Yann Collet2acb5d32015-10-29 16:49:43 +0100385
inikepc4807f42016-06-02 15:11:39 +0200386/* custom memory allocation functions */
Yann Collet23b6e052016-08-28 21:05:43 -0700387void* ZSTD_malloc(size_t size, ZSTD_customMem customMem);
Yann Collet44e45e82017-05-30 16:12:06 -0700388void* ZSTD_calloc(size_t size, ZSTD_customMem customMem);
Yann Collet23b6e052016-08-28 21:05:43 -0700389void ZSTD_free(void* ptr, ZSTD_customMem customMem);
390
inikep2a746092016-06-03 14:53:51 +0200391
Yann Collet8b6aecf2017-11-07 15:27:06 -0800392MEM_STATIC U32 ZSTD_highbit32(U32 val) /* compress, dictBuilder, decodeCorpus */
Yann Colletc154d9d2016-07-27 14:37:00 +0200393{
Stella Laue50ed1f2017-08-22 11:55:42 -0700394 assert(val != 0);
395 {
Yann Colletc154d9d2016-07-27 14:37:00 +0200396# if defined(_MSC_VER) /* Visual */
Stella Laue50ed1f2017-08-22 11:55:42 -0700397 unsigned long r=0;
Bimba Shresthadba3abc2020-03-05 12:20:59 -0800398 return _BitScanReverse(&r, val) ? (unsigned)r : 0;
Yann Colletc154d9d2016-07-27 14:37:00 +0200399# elif defined(__GNUC__) && (__GNUC__ >= 3) /* GCC Intrinsic */
Dávid Bolvanský1ab1a402019-09-23 21:32:56 +0200400 return __builtin_clz (val) ^ 31;
Joseph Chen3855bc42019-07-29 15:20:37 +0800401# elif defined(__ICCARM__) /* IAR Intrinsic */
402 return 31 - __CLZ(val);
Yann Colletc154d9d2016-07-27 14:37:00 +0200403# else /* Software version */
Yann Collet0a0a2122017-11-28 14:07:03 -0800404 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 -0700405 U32 v = val;
Stella Laue50ed1f2017-08-22 11:55:42 -0700406 v |= v >> 1;
407 v |= v >> 2;
408 v |= v >> 4;
409 v |= v >> 8;
410 v |= v >> 16;
Yann Collet0a0a2122017-11-28 14:07:03 -0800411 return DeBruijnClz[(v * 0x07C4ACDDU) >> 27];
Yann Colletc154d9d2016-07-27 14:37:00 +0200412# endif
Stella Laue50ed1f2017-08-22 11:55:42 -0700413 }
Yann Colletc154d9d2016-07-27 14:37:00 +0200414}
415
416
Yann Collet32dfae62017-01-19 10:32:55 -0800417/* ZSTD_invalidateRepCodes() :
418 * ensures next compression will not use repcodes from previous block.
419 * Note : only works with regular variant;
420 * do not use with extDict variant ! */
Yann Collet8b6aecf2017-11-07 15:27:06 -0800421void ZSTD_invalidateRepCodes(ZSTD_CCtx* cctx); /* zstdmt, adaptive_compression (shouldn't get this definition from here) */
Yann Collet32dfae62017-01-19 10:32:55 -0800422
423
Yann Colletf04deff2017-07-06 01:42:46 -0700424typedef struct {
425 blockType_e blockType;
426 U32 lastBlock;
427 U32 origSize;
Yann Collet2b491402018-10-25 16:28:41 -0700428} blockProperties_t; /* declared here for decompress and fullbench */
Yann Colletf04deff2017-07-06 01:42:46 -0700429
430/*! ZSTD_getcBlockSize() :
Yann Collet4191efa2017-11-08 11:05:32 -0800431 * Provides the size of compressed block from block header `src` */
432/* Used by: decompress, fullbench (does not get its definition from here) */
Yann Colletf04deff2017-07-06 01:42:46 -0700433size_t ZSTD_getcBlockSize(const void* src, size_t srcSize,
434 blockProperties_t* bpPtr);
435
Yann Collet2b491402018-10-25 16:28:41 -0700436/*! ZSTD_decodeSeqHeaders() :
437 * decode sequence header from src */
438/* Used by: decompress, fullbench (does not get its definition from here) */
439size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr,
440 const void* src, size_t srcSize);
441
442
Nick Terrellde6c6bc2017-08-24 18:09:50 -0700443#if defined (__cplusplus)
444}
445#endif
Yann Colletf04deff2017-07-06 01:42:46 -0700446
Yann Collet2acb5d32015-10-29 16:49:43 +0100447#endif /* ZSTD_CCOMMON_H_MODULE */