2210 lines · 99.1 KB · C
RawDownload
// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause/* * Copyright (c) Meta Platforms, Inc. and affiliates. * All rights reserved. * * This source code is licensed under both the BSD-style license (found in the * LICENSE file in the root directory of this source tree) and the GPLv2 (found * in the COPYING file in the root directory of this source tree). * You may select, at your option, one of the above-listed licenses. */ /* zstd_decompress_block : * this module takes care of decompressing _compressed_ block */ /*-********************************************************  Dependencies*********************************************************/#include "../common/zstd_deps.h"   /* ZSTD_memcpy, ZSTD_memmove, ZSTD_memset */#include "../common/compiler.h"    /* prefetch */#include "../common/cpu.h"         /* bmi2 */#include "../common/mem.h"         /* low level memory routines */#define FSE_STATIC_LINKING_ONLY#include "../common/fse.h"#include "../common/huf.h"#include "../common/zstd_internal.h"#include "zstd_decompress_internal.h"   /* ZSTD_DCtx */#include "zstd_ddict.h"  /* ZSTD_DDictDictContent */#include "zstd_decompress_block.h"#include "../common/bits.h"  /* ZSTD_highbit32 */ /*_********************************************************  Macros**********************************************************/ /* These two optional macros force the use one way or another of the two * ZSTD_decompressSequences implementations. You can't force in both directions * at the same time. */#if defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT) && \    defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG)#error "Cannot force the use of the short and the long ZSTD_decompressSequences variants!"#endif  /*_********************************************************  Memory operations**********************************************************/static void ZSTD_copy4(void* dst, const void* src) { ZSTD_memcpy(dst, src, 4); }  /*-************************************************************* *   Block decoding ***************************************************************/ static size_t ZSTD_blockSizeMax(ZSTD_DCtx const* dctx){    size_t const blockSizeMax = dctx->isFrameDecompression ? dctx->fParams.blockSizeMax : ZSTD_BLOCKSIZE_MAX;    assert(blockSizeMax <= ZSTD_BLOCKSIZE_MAX);    return blockSizeMax;} /*! ZSTD_getcBlockSize() : *  Provides the size of compressed block from block header `src` */size_t ZSTD_getcBlockSize(const void* src, size_t srcSize,                          blockProperties_t* bpPtr){    RETURN_ERROR_IF(srcSize < ZSTD_blockHeaderSize, srcSize_wrong, "");     {   U32 const cBlockHeader = MEM_readLE24(src);        U32 const cSize = cBlockHeader >> 3;        bpPtr->lastBlock = cBlockHeader & 1;        bpPtr->blockType = (blockType_e)((cBlockHeader >> 1) & 3);        bpPtr->origSize = cSize;   /* only useful for RLE */        if (bpPtr->blockType == bt_rle) return 1;        RETURN_ERROR_IF(bpPtr->blockType == bt_reserved, corruption_detected, "");        return cSize;    }} /* Allocate buffer for literals, either overlapping current dst, or split between dst and litExtraBuffer, or stored entirely within litExtraBuffer */static void ZSTD_allocateLiteralsBuffer(ZSTD_DCtx* dctx, void* const dst, const size_t dstCapacity, const size_t litSize,    const streaming_operation streaming, const size_t expectedWriteSize, const unsigned splitImmediately){    size_t const blockSizeMax = ZSTD_blockSizeMax(dctx);    assert(litSize <= blockSizeMax);    assert(dctx->isFrameDecompression || streaming == not_streaming);    assert(expectedWriteSize <= blockSizeMax);    if (streaming == not_streaming && dstCapacity > blockSizeMax + WILDCOPY_OVERLENGTH + litSize + WILDCOPY_OVERLENGTH) {        /* If we aren't streaming, we can just put the literals after the output         * of the current block. We don't need to worry about overwriting the         * extDict of our window, because it doesn't exist.         * So if we have space after the end of the block, just put it there.         */        dctx->litBuffer = (BYTE*)dst + blockSizeMax + WILDCOPY_OVERLENGTH;        dctx->litBufferEnd = dctx->litBuffer + litSize;        dctx->litBufferLocation = ZSTD_in_dst;    } else if (litSize <= ZSTD_LITBUFFEREXTRASIZE) {        /* Literals fit entirely within the extra buffer, put them there to avoid         * having to split the literals.         */        dctx->litBuffer = dctx->litExtraBuffer;        dctx->litBufferEnd = dctx->litBuffer + litSize;        dctx->litBufferLocation = ZSTD_not_in_dst;    } else {        assert(blockSizeMax > ZSTD_LITBUFFEREXTRASIZE);        /* Literals must be split between the output block and the extra lit         * buffer. We fill the extra lit buffer with the tail of the literals,         * and put the rest of the literals at the end of the block, with         * WILDCOPY_OVERLENGTH of buffer room to allow for overreads.         * This MUST not write more than our maxBlockSize beyond dst, because in         * streaming mode, that could overwrite part of our extDict window.         */        if (splitImmediately) {            /* won't fit in litExtraBuffer, so it will be split between end of dst and extra buffer */            dctx->litBuffer = (BYTE*)dst + expectedWriteSize - litSize + ZSTD_LITBUFFEREXTRASIZE - WILDCOPY_OVERLENGTH;            dctx->litBufferEnd = dctx->litBuffer + litSize - ZSTD_LITBUFFEREXTRASIZE;        } else {            /* initially this will be stored entirely in dst during huffman decoding, it will partially be shifted to litExtraBuffer after */            dctx->litBuffer = (BYTE*)dst + expectedWriteSize - litSize;            dctx->litBufferEnd = (BYTE*)dst + expectedWriteSize;        }        dctx->litBufferLocation = ZSTD_split;        assert(dctx->litBufferEnd <= (BYTE*)dst + expectedWriteSize);    }} /*! ZSTD_decodeLiteralsBlock() : * Where it is possible to do so without being stomped by the output during decompression, the literals block will be stored * in the dstBuffer.  If there is room to do so, it will be stored in full in the excess dst space after where the current * block will be output.  Otherwise it will be stored at the end of the current dst blockspace, with a small portion being * stored in dctx->litExtraBuffer to help keep it "ahead" of the current output write. * * @return : nb of bytes read from src (< srcSize ) *  note : symbol not declared but exposed for fullbench */static size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,                          const void* src, size_t srcSize,   /* note : srcSize < BLOCKSIZE */                          void* dst, size_t dstCapacity, const streaming_operation streaming){    DEBUGLOG(5, "ZSTD_decodeLiteralsBlock");    RETURN_ERROR_IF(srcSize < MIN_CBLOCK_SIZE, corruption_detected, "");     {   const BYTE* const istart = (const BYTE*) src;        SymbolEncodingType_e const litEncType = (SymbolEncodingType_e)(istart[0] & 3);        size_t const blockSizeMax = ZSTD_blockSizeMax(dctx);         switch(litEncType)        {        case set_repeat:            DEBUGLOG(5, "set_repeat flag : re-using stats from previous compressed literals block");            RETURN_ERROR_IF(dctx->litEntropy==0, dictionary_corrupted, "");            ZSTD_FALLTHROUGH;         case set_compressed:            RETURN_ERROR_IF(srcSize < 5, corruption_detected, "srcSize >= MIN_CBLOCK_SIZE == 2; here we need up to 5 for case 3");            {   size_t lhSize, litSize, litCSize;                U32 singleStream=0;                U32 const lhlCode = (istart[0] >> 2) & 3;                U32 const lhc = MEM_readLE32(istart);                size_t hufSuccess;                size_t expectedWriteSize = MIN(blockSizeMax, dstCapacity);                int const flags = 0                    | (ZSTD_DCtx_get_bmi2(dctx) ? HUF_flags_bmi2 : 0)                    | (dctx->disableHufAsm ? HUF_flags_disableAsm : 0);                switch(lhlCode)                {                case 0: case 1: default:   /* note : default is impossible, since lhlCode into [0..3] */                    /* 2 - 2 - 10 - 10 */                    singleStream = !lhlCode;                    lhSize = 3;                    litSize  = (lhc >> 4) & 0x3FF;                    litCSize = (lhc >> 14) & 0x3FF;                    break;                case 2:                    /* 2 - 2 - 14 - 14 */                    lhSize = 4;                    litSize  = (lhc >> 4) & 0x3FFF;                    litCSize = lhc >> 18;                    break;                case 3:                    /* 2 - 2 - 18 - 18 */                    lhSize = 5;                    litSize  = (lhc >> 4) & 0x3FFFF;                    litCSize = (lhc >> 22) + ((size_t)istart[4] << 10);                    break;                }                RETURN_ERROR_IF(litSize > 0 && dst == NULL, dstSize_tooSmall, "NULL not handled");                RETURN_ERROR_IF(litSize > blockSizeMax, corruption_detected, "");                if (!singleStream)                    RETURN_ERROR_IF(litSize < MIN_LITERALS_FOR_4_STREAMS, literals_headerWrong,                        "Not enough literals (%zu) for the 4-streams mode (min %u)",                        litSize, MIN_LITERALS_FOR_4_STREAMS);                RETURN_ERROR_IF(litCSize + lhSize > srcSize, corruption_detected, "");                RETURN_ERROR_IF(expectedWriteSize < litSize , dstSize_tooSmall, "");                ZSTD_allocateLiteralsBuffer(dctx, dst, dstCapacity, litSize, streaming, expectedWriteSize, 0);                 /* prefetch huffman table if cold */                if (dctx->ddictIsCold && (litSize > 768 /* heuristic */)) {                    PREFETCH_AREA(dctx->HUFptr, sizeof(dctx->entropy.hufTable));                }                 if (litEncType==set_repeat) {                    if (singleStream) {                        hufSuccess = HUF_decompress1X_usingDTable(                            dctx->litBuffer, litSize, istart+lhSize, litCSize,                            dctx->HUFptr, flags);                    } else {                        assert(litSize >= MIN_LITERALS_FOR_4_STREAMS);                        hufSuccess = HUF_decompress4X_usingDTable(                            dctx->litBuffer, litSize, istart+lhSize, litCSize,                            dctx->HUFptr, flags);                    }                } else {                    if (singleStream) {#if defined(HUF_FORCE_DECOMPRESS_X2)                        hufSuccess = HUF_decompress1X_DCtx_wksp(                            dctx->entropy.hufTable, dctx->litBuffer, litSize,                            istart+lhSize, litCSize, dctx->workspace,                            sizeof(dctx->workspace), flags);#else                        hufSuccess = HUF_decompress1X1_DCtx_wksp(                            dctx->entropy.hufTable, dctx->litBuffer, litSize,                            istart+lhSize, litCSize, dctx->workspace,                            sizeof(dctx->workspace), flags);#endif                    } else {                        hufSuccess = HUF_decompress4X_hufOnly_wksp(                            dctx->entropy.hufTable, dctx->litBuffer, litSize,                            istart+lhSize, litCSize, dctx->workspace,                            sizeof(dctx->workspace), flags);                    }                }                if (dctx->litBufferLocation == ZSTD_split)                {                    assert(litSize > ZSTD_LITBUFFEREXTRASIZE);                    ZSTD_memcpy(dctx->litExtraBuffer, dctx->litBufferEnd - ZSTD_LITBUFFEREXTRASIZE, ZSTD_LITBUFFEREXTRASIZE);                    ZSTD_memmove(dctx->litBuffer + ZSTD_LITBUFFEREXTRASIZE - WILDCOPY_OVERLENGTH, dctx->litBuffer, litSize - ZSTD_LITBUFFEREXTRASIZE);                    dctx->litBuffer += ZSTD_LITBUFFEREXTRASIZE - WILDCOPY_OVERLENGTH;                    dctx->litBufferEnd -= WILDCOPY_OVERLENGTH;                    assert(dctx->litBufferEnd <= (BYTE*)dst + blockSizeMax);                }                 RETURN_ERROR_IF(HUF_isError(hufSuccess), corruption_detected, "");                 dctx->litPtr = dctx->litBuffer;                dctx->litSize = litSize;                dctx->litEntropy = 1;                if (litEncType==set_compressed) dctx->HUFptr = dctx->entropy.hufTable;                return litCSize + lhSize;            }         case set_basic:            {   size_t litSize, lhSize;                U32 const lhlCode = ((istart[0]) >> 2) & 3;                size_t expectedWriteSize = MIN(blockSizeMax, dstCapacity);                switch(lhlCode)                {                case 0: case 2: default:   /* note : default is impossible, since lhlCode into [0..3] */                    lhSize = 1;                    litSize = istart[0] >> 3;                    break;                case 1:                    lhSize = 2;                    litSize = MEM_readLE16(istart) >> 4;                    break;                case 3:                    lhSize = 3;                    RETURN_ERROR_IF(srcSize<3, corruption_detected, "srcSize >= MIN_CBLOCK_SIZE == 2; here we need lhSize = 3");                    litSize = MEM_readLE24(istart) >> 4;                    break;                }                 RETURN_ERROR_IF(litSize > 0 && dst == NULL, dstSize_tooSmall, "NULL not handled");                RETURN_ERROR_IF(litSize > blockSizeMax, corruption_detected, "");                RETURN_ERROR_IF(expectedWriteSize < litSize, dstSize_tooSmall, "");                ZSTD_allocateLiteralsBuffer(dctx, dst, dstCapacity, litSize, streaming, expectedWriteSize, 1);                if (lhSize+litSize+WILDCOPY_OVERLENGTH > srcSize) {  /* risk reading beyond src buffer with wildcopy */                    RETURN_ERROR_IF(litSize+lhSize > srcSize, corruption_detected, "");                    if (dctx->litBufferLocation == ZSTD_split)                    {                        ZSTD_memcpy(dctx->litBuffer, istart + lhSize, litSize - ZSTD_LITBUFFEREXTRASIZE);                        ZSTD_memcpy(dctx->litExtraBuffer, istart + lhSize + litSize - ZSTD_LITBUFFEREXTRASIZE, ZSTD_LITBUFFEREXTRASIZE);                    }                    else                    {                        ZSTD_memcpy(dctx->litBuffer, istart + lhSize, litSize);                    }                    dctx->litPtr = dctx->litBuffer;                    dctx->litSize = litSize;                    return lhSize+litSize;                }                /* direct reference into compressed stream */                dctx->litPtr = istart+lhSize;                dctx->litSize = litSize;                dctx->litBufferEnd = dctx->litPtr + litSize;                dctx->litBufferLocation = ZSTD_not_in_dst;                return lhSize+litSize;            }         case set_rle:            {   U32 const lhlCode = ((istart[0]) >> 2) & 3;                size_t litSize, lhSize;                size_t expectedWriteSize = MIN(blockSizeMax, dstCapacity);                switch(lhlCode)                {                case 0: case 2: default:   /* note : default is impossible, since lhlCode into [0..3] */                    lhSize = 1;                    litSize = istart[0] >> 3;                    break;                case 1:                    lhSize = 2;                    RETURN_ERROR_IF(srcSize<3, corruption_detected, "srcSize >= MIN_CBLOCK_SIZE == 2; here we need lhSize+1 = 3");                    litSize = MEM_readLE16(istart) >> 4;                    break;                case 3:                    lhSize = 3;                    RETURN_ERROR_IF(srcSize<4, corruption_detected, "srcSize >= MIN_CBLOCK_SIZE == 2; here we need lhSize+1 = 4");                    litSize = MEM_readLE24(istart) >> 4;                    break;                }                RETURN_ERROR_IF(litSize > 0 && dst == NULL, dstSize_tooSmall, "NULL not handled");                RETURN_ERROR_IF(litSize > blockSizeMax, corruption_detected, "");                RETURN_ERROR_IF(expectedWriteSize < litSize, dstSize_tooSmall, "");                ZSTD_allocateLiteralsBuffer(dctx, dst, dstCapacity, litSize, streaming, expectedWriteSize, 1);                if (dctx->litBufferLocation == ZSTD_split)                {                    ZSTD_memset(dctx->litBuffer, istart[lhSize], litSize - ZSTD_LITBUFFEREXTRASIZE);                    ZSTD_memset(dctx->litExtraBuffer, istart[lhSize], ZSTD_LITBUFFEREXTRASIZE);                }                else                {                    ZSTD_memset(dctx->litBuffer, istart[lhSize], litSize);                }                dctx->litPtr = dctx->litBuffer;                dctx->litSize = litSize;                return lhSize+1;            }        default:            RETURN_ERROR(corruption_detected, "impossible");        }    }} /* Hidden declaration for fullbench */size_t ZSTD_decodeLiteralsBlock_wrapper(ZSTD_DCtx* dctx,                          const void* src, size_t srcSize,                          void* dst, size_t dstCapacity);size_t ZSTD_decodeLiteralsBlock_wrapper(ZSTD_DCtx* dctx,                          const void* src, size_t srcSize,                          void* dst, size_t dstCapacity){    dctx->isFrameDecompression = 0;    return ZSTD_decodeLiteralsBlock(dctx, src, srcSize, dst, dstCapacity, not_streaming);} /* Default FSE distribution tables. * These are pre-calculated FSE decoding tables using default distributions as defined in specification : * https://github.com/facebook/zstd/blob/release/doc/zstd_compression_format.md#default-distributions * They were generated programmatically with following method : * - start from default distributions, present in /lib/common/zstd_internal.h * - generate tables normally, using ZSTD_buildFSETable() * - printout the content of tables * - prettify output, report below, test with fuzzer to ensure it's correct */ /* Default FSE distribution table for Literal Lengths */static const ZSTD_seqSymbol LL_defaultDTable[(1<<LL_DEFAULTNORMLOG)+1] = {     {  1,  1,  1, LL_DEFAULTNORMLOG},  /* header : fastMode, tableLog */     /* nextState, nbAddBits, nbBits, baseVal */     {  0,  0,  4,    0},  { 16,  0,  4,    0},     { 32,  0,  5,    1},  {  0,  0,  5,    3},     {  0,  0,  5,    4},  {  0,  0,  5,    6},     {  0,  0,  5,    7},  {  0,  0,  5,    9},     {  0,  0,  5,   10},  {  0,  0,  5,   12},     {  0,  0,  6,   14},  {  0,  1,  5,   16},     {  0,  1,  5,   20},  {  0,  1,  5,   22},     {  0,  2,  5,   28},  {  0,  3,  5,   32},     {  0,  4,  5,   48},  { 32,  6,  5,   64},     {  0,  7,  5,  128},  {  0,  8,  6,  256},     {  0, 10,  6, 1024},  {  0, 12,  6, 4096},     { 32,  0,  4,    0},  {  0,  0,  4,    1},     {  0,  0,  5,    2},  { 32,  0,  5,    4},     {  0,  0,  5,    5},  { 32,  0,  5,    7},     {  0,  0,  5,    8},  { 32,  0,  5,   10},     {  0,  0,  5,   11},  {  0,  0,  6,   13},     { 32,  1,  5,   16},  {  0,  1,  5,   18},     { 32,  1,  5,   22},  {  0,  2,  5,   24},     { 32,  3,  5,   32},  {  0,  3,  5,   40},     {  0,  6,  4,   64},  { 16,  6,  4,   64},     { 32,  7,  5,  128},  {  0,  9,  6,  512},     {  0, 11,  6, 2048},  { 48,  0,  4,    0},     { 16,  0,  4,    1},  { 32,  0,  5,    2},     { 32,  0,  5,    3},  { 32,  0,  5,    5},     { 32,  0,  5,    6},  { 32,  0,  5,    8},     { 32,  0,  5,    9},  { 32,  0,  5,   11},     { 32,  0,  5,   12},  {  0,  0,  6,   15},     { 32,  1,  5,   18},  { 32,  1,  5,   20},     { 32,  2,  5,   24},  { 32,  2,  5,   28},     { 32,  3,  5,   40},  { 32,  4,  5,   48},     {  0, 16,  6,65536},  {  0, 15,  6,32768},     {  0, 14,  6,16384},  {  0, 13,  6, 8192},};   /* LL_defaultDTable */ /* Default FSE distribution table for Offset Codes */static const ZSTD_seqSymbol OF_defaultDTable[(1<<OF_DEFAULTNORMLOG)+1] = {    {  1,  1,  1, OF_DEFAULTNORMLOG},  /* header : fastMode, tableLog */    /* nextState, nbAddBits, nbBits, baseVal */    {  0,  0,  5,    0},     {  0,  6,  4,   61},    {  0,  9,  5,  509},     {  0, 15,  5,32765},    {  0, 21,  5,2097149},   {  0,  3,  5,    5},    {  0,  7,  4,  125},     {  0, 12,  5, 4093},    {  0, 18,  5,262141},    {  0, 23,  5,8388605},    {  0,  5,  5,   29},     {  0,  8,  4,  253},    {  0, 14,  5,16381},     {  0, 20,  5,1048573},    {  0,  2,  5,    1},     { 16,  7,  4,  125},    {  0, 11,  5, 2045},     {  0, 17,  5,131069},    {  0, 22,  5,4194301},   {  0,  4,  5,   13},    { 16,  8,  4,  253},     {  0, 13,  5, 8189},    {  0, 19,  5,524285},    {  0,  1,  5,    1},    { 16,  6,  4,   61},     {  0, 10,  5, 1021},    {  0, 16,  5,65533},     {  0, 28,  5,268435453},    {  0, 27,  5,134217725}, {  0, 26,  5,67108861},    {  0, 25,  5,33554429},  {  0, 24,  5,16777213},};   /* OF_defaultDTable */  /* Default FSE distribution table for Match Lengths */static const ZSTD_seqSymbol ML_defaultDTable[(1<<ML_DEFAULTNORMLOG)+1] = {    {  1,  1,  1, ML_DEFAULTNORMLOG},  /* header : fastMode, tableLog */    /* nextState, nbAddBits, nbBits, baseVal */    {  0,  0,  6,    3},  {  0,  0,  4,    4},    { 32,  0,  5,    5},  {  0,  0,  5,    6},    {  0,  0,  5,    8},  {  0,  0,  5,    9},    {  0,  0,  5,   11},  {  0,  0,  6,   13},    {  0,  0,  6,   16},  {  0,  0,  6,   19},    {  0,  0,  6,   22},  {  0,  0,  6,   25},    {  0,  0,  6,   28},  {  0,  0,  6,   31},    {  0,  0,  6,   34},  {  0,  1,  6,   37},    {  0,  1,  6,   41},  {  0,  2,  6,   47},    {  0,  3,  6,   59},  {  0,  4,  6,   83},    {  0,  7,  6,  131},  {  0,  9,  6,  515},    { 16,  0,  4,    4},  {  0,  0,  4,    5},    { 32,  0,  5,    6},  {  0,  0,  5,    7},    { 32,  0,  5,    9},  {  0,  0,  5,   10},    {  0,  0,  6,   12},  {  0,  0,  6,   15},    {  0,  0,  6,   18},  {  0,  0,  6,   21},    {  0,  0,  6,   24},  {  0,  0,  6,   27},    {  0,  0,  6,   30},  {  0,  0,  6,   33},    {  0,  1,  6,   35},  {  0,  1,  6,   39},    {  0,  2,  6,   43},  {  0,  3,  6,   51},    {  0,  4,  6,   67},  {  0,  5,  6,   99},    {  0,  8,  6,  259},  { 32,  0,  4,    4},    { 48,  0,  4,    4},  { 16,  0,  4,    5},    { 32,  0,  5,    7},  { 32,  0,  5,    8},    { 32,  0,  5,   10},  { 32,  0,  5,   11},    {  0,  0,  6,   14},  {  0,  0,  6,   17},    {  0,  0,  6,   20},  {  0,  0,  6,   23},    {  0,  0,  6,   26},  {  0,  0,  6,   29},    {  0,  0,  6,   32},  {  0, 16,  6,65539},    {  0, 15,  6,32771},  {  0, 14,  6,16387},    {  0, 13,  6, 8195},  {  0, 12,  6, 4099},    {  0, 11,  6, 2051},  {  0, 10,  6, 1027},};   /* ML_defaultDTable */  static void ZSTD_buildSeqTable_rle(ZSTD_seqSymbol* dt, U32 baseValue, U8 nbAddBits){    void* ptr = dt;    ZSTD_seqSymbol_header* const DTableH = (ZSTD_seqSymbol_header*)ptr;    ZSTD_seqSymbol* const cell = dt + 1;     DTableH->tableLog = 0;    DTableH->fastMode = 0;     cell->nbBits = 0;    cell->nextState = 0;    assert(nbAddBits < 255);    cell->nbAdditionalBits = nbAddBits;    cell->baseValue = baseValue;}  /* ZSTD_buildFSETable() : * generate FSE decoding table for one symbol (ll, ml or off) * cannot fail if input is valid => * all inputs are presumed validated at this stage */FORCE_INLINE_TEMPLATEvoid ZSTD_buildFSETable_body(ZSTD_seqSymbol* dt,            const short* normalizedCounter, unsigned maxSymbolValue,            const U32* baseValue, const U8* nbAdditionalBits,            unsigned tableLog, void* wksp, size_t wkspSize){    ZSTD_seqSymbol* const tableDecode = dt+1;    U32 const maxSV1 = maxSymbolValue + 1;    U32 const tableSize = 1 << tableLog;     U16* symbolNext = (U16*)wksp;    BYTE* spread = (BYTE*)(symbolNext + MaxSeq + 1);    U32 highThreshold = tableSize - 1;      /* Sanity Checks */

Lines 1–500 of 2210.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t