162306a36Sopenharmony_ci/*
262306a36Sopenharmony_ci * Copyright (c) Yann Collet, Facebook, Inc.
362306a36Sopenharmony_ci * All rights reserved.
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * This source code is licensed under both the BSD-style license (found in the
662306a36Sopenharmony_ci * LICENSE file in the root directory of this source tree) and the GPLv2 (found
762306a36Sopenharmony_ci * in the COPYING file in the root directory of this source tree).
862306a36Sopenharmony_ci * You may select, at your option, one of the above-listed licenses.
962306a36Sopenharmony_ci */
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci/* zstd_decompress_internal:
1362306a36Sopenharmony_ci * objects and definitions shared within lib/decompress modules */
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci #ifndef ZSTD_DECOMPRESS_INTERNAL_H
1662306a36Sopenharmony_ci #define ZSTD_DECOMPRESS_INTERNAL_H
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci/*-*******************************************************
2062306a36Sopenharmony_ci *  Dependencies
2162306a36Sopenharmony_ci *********************************************************/
2262306a36Sopenharmony_ci#include "../common/mem.h"             /* BYTE, U16, U32 */
2362306a36Sopenharmony_ci#include "../common/zstd_internal.h"   /* constants : MaxLL, MaxML, MaxOff, LLFSELog, etc. */
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci/*-*******************************************************
2862306a36Sopenharmony_ci *  Constants
2962306a36Sopenharmony_ci *********************************************************/
3062306a36Sopenharmony_cistatic UNUSED_ATTR const U32 LL_base[MaxLL+1] = {
3162306a36Sopenharmony_ci                 0,    1,    2,     3,     4,     5,     6,      7,
3262306a36Sopenharmony_ci                 8,    9,   10,    11,    12,    13,    14,     15,
3362306a36Sopenharmony_ci                16,   18,   20,    22,    24,    28,    32,     40,
3462306a36Sopenharmony_ci                48,   64, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000,
3562306a36Sopenharmony_ci                0x2000, 0x4000, 0x8000, 0x10000 };
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_cistatic UNUSED_ATTR const U32 OF_base[MaxOff+1] = {
3862306a36Sopenharmony_ci                 0,        1,       1,       5,     0xD,     0x1D,     0x3D,     0x7D,
3962306a36Sopenharmony_ci                 0xFD,   0x1FD,   0x3FD,   0x7FD,   0xFFD,   0x1FFD,   0x3FFD,   0x7FFD,
4062306a36Sopenharmony_ci                 0xFFFD, 0x1FFFD, 0x3FFFD, 0x7FFFD, 0xFFFFD, 0x1FFFFD, 0x3FFFFD, 0x7FFFFD,
4162306a36Sopenharmony_ci                 0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD, 0x1FFFFFFD, 0x3FFFFFFD, 0x7FFFFFFD };
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_cistatic UNUSED_ATTR const U8 OF_bits[MaxOff+1] = {
4462306a36Sopenharmony_ci                     0,  1,  2,  3,  4,  5,  6,  7,
4562306a36Sopenharmony_ci                     8,  9, 10, 11, 12, 13, 14, 15,
4662306a36Sopenharmony_ci                    16, 17, 18, 19, 20, 21, 22, 23,
4762306a36Sopenharmony_ci                    24, 25, 26, 27, 28, 29, 30, 31 };
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_cistatic UNUSED_ATTR const U32 ML_base[MaxML+1] = {
5062306a36Sopenharmony_ci                     3,  4,  5,    6,     7,     8,     9,    10,
5162306a36Sopenharmony_ci                    11, 12, 13,   14,    15,    16,    17,    18,
5262306a36Sopenharmony_ci                    19, 20, 21,   22,    23,    24,    25,    26,
5362306a36Sopenharmony_ci                    27, 28, 29,   30,    31,    32,    33,    34,
5462306a36Sopenharmony_ci                    35, 37, 39,   41,    43,    47,    51,    59,
5562306a36Sopenharmony_ci                    67, 83, 99, 0x83, 0x103, 0x203, 0x403, 0x803,
5662306a36Sopenharmony_ci                    0x1003, 0x2003, 0x4003, 0x8003, 0x10003 };
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_ci/*-*******************************************************
6062306a36Sopenharmony_ci *  Decompression types
6162306a36Sopenharmony_ci *********************************************************/
6262306a36Sopenharmony_ci typedef struct {
6362306a36Sopenharmony_ci     U32 fastMode;
6462306a36Sopenharmony_ci     U32 tableLog;
6562306a36Sopenharmony_ci } ZSTD_seqSymbol_header;
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_ci typedef struct {
6862306a36Sopenharmony_ci     U16  nextState;
6962306a36Sopenharmony_ci     BYTE nbAdditionalBits;
7062306a36Sopenharmony_ci     BYTE nbBits;
7162306a36Sopenharmony_ci     U32  baseValue;
7262306a36Sopenharmony_ci } ZSTD_seqSymbol;
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_ci #define SEQSYMBOL_TABLE_SIZE(log)   (1 + (1 << (log)))
7562306a36Sopenharmony_ci
7662306a36Sopenharmony_ci#define ZSTD_BUILD_FSE_TABLE_WKSP_SIZE (sizeof(S16) * (MaxSeq + 1) + (1u << MaxFSELog) + sizeof(U64))
7762306a36Sopenharmony_ci#define ZSTD_BUILD_FSE_TABLE_WKSP_SIZE_U32 ((ZSTD_BUILD_FSE_TABLE_WKSP_SIZE + sizeof(U32) - 1) / sizeof(U32))
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_citypedef struct {
8062306a36Sopenharmony_ci    ZSTD_seqSymbol LLTable[SEQSYMBOL_TABLE_SIZE(LLFSELog)];    /* Note : Space reserved for FSE Tables */
8162306a36Sopenharmony_ci    ZSTD_seqSymbol OFTable[SEQSYMBOL_TABLE_SIZE(OffFSELog)];   /* is also used as temporary workspace while building hufTable during DDict creation */
8262306a36Sopenharmony_ci    ZSTD_seqSymbol MLTable[SEQSYMBOL_TABLE_SIZE(MLFSELog)];    /* and therefore must be at least HUF_DECOMPRESS_WORKSPACE_SIZE large */
8362306a36Sopenharmony_ci    HUF_DTable hufTable[HUF_DTABLE_SIZE(HufLog)];  /* can accommodate HUF_decompress4X */
8462306a36Sopenharmony_ci    U32 rep[ZSTD_REP_NUM];
8562306a36Sopenharmony_ci    U32 workspace[ZSTD_BUILD_FSE_TABLE_WKSP_SIZE_U32];
8662306a36Sopenharmony_ci} ZSTD_entropyDTables_t;
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_citypedef enum { ZSTDds_getFrameHeaderSize, ZSTDds_decodeFrameHeader,
8962306a36Sopenharmony_ci               ZSTDds_decodeBlockHeader, ZSTDds_decompressBlock,
9062306a36Sopenharmony_ci               ZSTDds_decompressLastBlock, ZSTDds_checkChecksum,
9162306a36Sopenharmony_ci               ZSTDds_decodeSkippableHeader, ZSTDds_skipFrame } ZSTD_dStage;
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_citypedef enum { zdss_init=0, zdss_loadHeader,
9462306a36Sopenharmony_ci               zdss_read, zdss_load, zdss_flush } ZSTD_dStreamStage;
9562306a36Sopenharmony_ci
9662306a36Sopenharmony_citypedef enum {
9762306a36Sopenharmony_ci    ZSTD_use_indefinitely = -1,  /* Use the dictionary indefinitely */
9862306a36Sopenharmony_ci    ZSTD_dont_use = 0,           /* Do not use the dictionary (if one exists free it) */
9962306a36Sopenharmony_ci    ZSTD_use_once = 1            /* Use the dictionary once and set to ZSTD_dont_use */
10062306a36Sopenharmony_ci} ZSTD_dictUses_e;
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_ci/* Hashset for storing references to multiple ZSTD_DDict within ZSTD_DCtx */
10362306a36Sopenharmony_citypedef struct {
10462306a36Sopenharmony_ci    const ZSTD_DDict** ddictPtrTable;
10562306a36Sopenharmony_ci    size_t ddictPtrTableSize;
10662306a36Sopenharmony_ci    size_t ddictPtrCount;
10762306a36Sopenharmony_ci} ZSTD_DDictHashSet;
10862306a36Sopenharmony_ci
10962306a36Sopenharmony_ci#ifndef ZSTD_DECODER_INTERNAL_BUFFER
11062306a36Sopenharmony_ci#  define ZSTD_DECODER_INTERNAL_BUFFER  (1 << 16)
11162306a36Sopenharmony_ci#endif
11262306a36Sopenharmony_ci
11362306a36Sopenharmony_ci#define ZSTD_LBMIN 64
11462306a36Sopenharmony_ci#define ZSTD_LBMAX (128 << 10)
11562306a36Sopenharmony_ci
11662306a36Sopenharmony_ci/* extra buffer, compensates when dst is not large enough to store litBuffer */
11762306a36Sopenharmony_ci#define ZSTD_LITBUFFEREXTRASIZE  BOUNDED(ZSTD_LBMIN, ZSTD_DECODER_INTERNAL_BUFFER, ZSTD_LBMAX)
11862306a36Sopenharmony_ci
11962306a36Sopenharmony_citypedef enum {
12062306a36Sopenharmony_ci    ZSTD_not_in_dst = 0,  /* Stored entirely within litExtraBuffer */
12162306a36Sopenharmony_ci    ZSTD_in_dst = 1,           /* Stored entirely within dst (in memory after current output write) */
12262306a36Sopenharmony_ci    ZSTD_split = 2            /* Split between litExtraBuffer and dst */
12362306a36Sopenharmony_ci} ZSTD_litLocation_e;
12462306a36Sopenharmony_ci
12562306a36Sopenharmony_cistruct ZSTD_DCtx_s
12662306a36Sopenharmony_ci{
12762306a36Sopenharmony_ci    const ZSTD_seqSymbol* LLTptr;
12862306a36Sopenharmony_ci    const ZSTD_seqSymbol* MLTptr;
12962306a36Sopenharmony_ci    const ZSTD_seqSymbol* OFTptr;
13062306a36Sopenharmony_ci    const HUF_DTable* HUFptr;
13162306a36Sopenharmony_ci    ZSTD_entropyDTables_t entropy;
13262306a36Sopenharmony_ci    U32 workspace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32];   /* space needed when building huffman tables */
13362306a36Sopenharmony_ci    const void* previousDstEnd;   /* detect continuity */
13462306a36Sopenharmony_ci    const void* prefixStart;      /* start of current segment */
13562306a36Sopenharmony_ci    const void* virtualStart;     /* virtual start of previous segment if it was just before current one */
13662306a36Sopenharmony_ci    const void* dictEnd;          /* end of previous segment */
13762306a36Sopenharmony_ci    size_t expected;
13862306a36Sopenharmony_ci    ZSTD_frameHeader fParams;
13962306a36Sopenharmony_ci    U64 processedCSize;
14062306a36Sopenharmony_ci    U64 decodedSize;
14162306a36Sopenharmony_ci    blockType_e bType;            /* used in ZSTD_decompressContinue(), store blockType between block header decoding and block decompression stages */
14262306a36Sopenharmony_ci    ZSTD_dStage stage;
14362306a36Sopenharmony_ci    U32 litEntropy;
14462306a36Sopenharmony_ci    U32 fseEntropy;
14562306a36Sopenharmony_ci    struct xxh64_state xxhState;
14662306a36Sopenharmony_ci    size_t headerSize;
14762306a36Sopenharmony_ci    ZSTD_format_e format;
14862306a36Sopenharmony_ci    ZSTD_forceIgnoreChecksum_e forceIgnoreChecksum;   /* User specified: if == 1, will ignore checksums in compressed frame. Default == 0 */
14962306a36Sopenharmony_ci    U32 validateChecksum;         /* if == 1, will validate checksum. Is == 1 if (fParams.checksumFlag == 1) and (forceIgnoreChecksum == 0). */
15062306a36Sopenharmony_ci    const BYTE* litPtr;
15162306a36Sopenharmony_ci    ZSTD_customMem customMem;
15262306a36Sopenharmony_ci    size_t litSize;
15362306a36Sopenharmony_ci    size_t rleSize;
15462306a36Sopenharmony_ci    size_t staticSize;
15562306a36Sopenharmony_ci#if DYNAMIC_BMI2 != 0
15662306a36Sopenharmony_ci    int bmi2;                     /* == 1 if the CPU supports BMI2 and 0 otherwise. CPU support is determined dynamically once per context lifetime. */
15762306a36Sopenharmony_ci#endif
15862306a36Sopenharmony_ci
15962306a36Sopenharmony_ci    /* dictionary */
16062306a36Sopenharmony_ci    ZSTD_DDict* ddictLocal;
16162306a36Sopenharmony_ci    const ZSTD_DDict* ddict;     /* set by ZSTD_initDStream_usingDDict(), or ZSTD_DCtx_refDDict() */
16262306a36Sopenharmony_ci    U32 dictID;
16362306a36Sopenharmony_ci    int ddictIsCold;             /* if == 1 : dictionary is "new" for working context, and presumed "cold" (not in cpu cache) */
16462306a36Sopenharmony_ci    ZSTD_dictUses_e dictUses;
16562306a36Sopenharmony_ci    ZSTD_DDictHashSet* ddictSet;                    /* Hash set for multiple ddicts */
16662306a36Sopenharmony_ci    ZSTD_refMultipleDDicts_e refMultipleDDicts;     /* User specified: if == 1, will allow references to multiple DDicts. Default == 0 (disabled) */
16762306a36Sopenharmony_ci
16862306a36Sopenharmony_ci    /* streaming */
16962306a36Sopenharmony_ci    ZSTD_dStreamStage streamStage;
17062306a36Sopenharmony_ci    char*  inBuff;
17162306a36Sopenharmony_ci    size_t inBuffSize;
17262306a36Sopenharmony_ci    size_t inPos;
17362306a36Sopenharmony_ci    size_t maxWindowSize;
17462306a36Sopenharmony_ci    char*  outBuff;
17562306a36Sopenharmony_ci    size_t outBuffSize;
17662306a36Sopenharmony_ci    size_t outStart;
17762306a36Sopenharmony_ci    size_t outEnd;
17862306a36Sopenharmony_ci    size_t lhSize;
17962306a36Sopenharmony_ci    U32 hostageByte;
18062306a36Sopenharmony_ci    int noForwardProgress;
18162306a36Sopenharmony_ci    ZSTD_bufferMode_e outBufferMode;
18262306a36Sopenharmony_ci    ZSTD_outBuffer expectedOutBuffer;
18362306a36Sopenharmony_ci
18462306a36Sopenharmony_ci    /* workspace */
18562306a36Sopenharmony_ci    BYTE* litBuffer;
18662306a36Sopenharmony_ci    const BYTE* litBufferEnd;
18762306a36Sopenharmony_ci    ZSTD_litLocation_e litBufferLocation;
18862306a36Sopenharmony_ci    BYTE litExtraBuffer[ZSTD_LITBUFFEREXTRASIZE + WILDCOPY_OVERLENGTH]; /* literal buffer can be split between storage within dst and within this scratch buffer */
18962306a36Sopenharmony_ci    BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX];
19062306a36Sopenharmony_ci
19162306a36Sopenharmony_ci    size_t oversizedDuration;
19262306a36Sopenharmony_ci
19362306a36Sopenharmony_ci#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
19462306a36Sopenharmony_ci    void const* dictContentBeginForFuzzing;
19562306a36Sopenharmony_ci    void const* dictContentEndForFuzzing;
19662306a36Sopenharmony_ci#endif
19762306a36Sopenharmony_ci
19862306a36Sopenharmony_ci    /* Tracing */
19962306a36Sopenharmony_ci};  /* typedef'd to ZSTD_DCtx within "zstd.h" */
20062306a36Sopenharmony_ci
20162306a36Sopenharmony_ciMEM_STATIC int ZSTD_DCtx_get_bmi2(const struct ZSTD_DCtx_s *dctx) {
20262306a36Sopenharmony_ci#if DYNAMIC_BMI2 != 0
20362306a36Sopenharmony_ci	return dctx->bmi2;
20462306a36Sopenharmony_ci#else
20562306a36Sopenharmony_ci    (void)dctx;
20662306a36Sopenharmony_ci	return 0;
20762306a36Sopenharmony_ci#endif
20862306a36Sopenharmony_ci}
20962306a36Sopenharmony_ci
21062306a36Sopenharmony_ci/*-*******************************************************
21162306a36Sopenharmony_ci *  Shared internal functions
21262306a36Sopenharmony_ci *********************************************************/
21362306a36Sopenharmony_ci
21462306a36Sopenharmony_ci/*! ZSTD_loadDEntropy() :
21562306a36Sopenharmony_ci *  dict : must point at beginning of a valid zstd dictionary.
21662306a36Sopenharmony_ci * @return : size of dictionary header (size of magic number + dict ID + entropy tables) */
21762306a36Sopenharmony_cisize_t ZSTD_loadDEntropy(ZSTD_entropyDTables_t* entropy,
21862306a36Sopenharmony_ci                   const void* const dict, size_t const dictSize);
21962306a36Sopenharmony_ci
22062306a36Sopenharmony_ci/*! ZSTD_checkContinuity() :
22162306a36Sopenharmony_ci *  check if next `dst` follows previous position, where decompression ended.
22262306a36Sopenharmony_ci *  If yes, do nothing (continue on current segment).
22362306a36Sopenharmony_ci *  If not, classify previous segment as "external dictionary", and start a new segment.
22462306a36Sopenharmony_ci *  This function cannot fail. */
22562306a36Sopenharmony_civoid ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst, size_t dstSize);
22662306a36Sopenharmony_ci
22762306a36Sopenharmony_ci
22862306a36Sopenharmony_ci#endif /* ZSTD_DECOMPRESS_INTERNAL_H */
229