Пример #1
0
        /** ZSTD_compressSubBlock_literal() :
         *  Compresses literals section for a sub-block.
         *  When we have to write the Huffman table we will sometimes choose a header
         *  size larger than necessary. This is because we have to pick the header size
         *  before we know the table size + compressed size, so we have a bound on the
         *  table size. If we guessed incorrectly, we fall back to uncompressed literals.
         *
         *  We write the header when writeEntropy=1 and set entropyWritten=1 when we succeeded
         *  in writing the header, otherwise it is set to 0.
         *
         *  hufMetadata->hType has literals block type info.
         *      If it is set_basic, all sub-blocks literals section will be Raw_Literals_Block.
         *      If it is set_rle, all sub-blocks literals section will be RLE_Literals_Block.
         *      If it is set_compressed, first sub-block's literals section will be Compressed_Literals_Block
         *      If it is set_compressed, first sub-block's literals section will be Treeless_Literals_Block
         *      and the following sub-blocks' literals sections will be Treeless_Literals_Block.
         *  @return : compressed size of literals section of a sub-block
         *            Or 0 if it unable to compress.
         *            Or error code */
        private static nuint ZSTD_compressSubBlock_literal(HUF_CElt_s *hufTable, ZSTD_hufCTablesMetadata_t *hufMetadata, byte *literals, nuint litSize, void *dst, nuint dstSize, int bmi2, int writeEntropy, int *entropyWritten)
        {
            nuint header               = (nuint)(writeEntropy != 0 ? 200 : 0);
            nuint lhSize               = (nuint)(3 + ((litSize >= ((uint)(1 * (1 << 10)) - header)) ? 1 : 0) + ((litSize >= ((uint)(16 * (1 << 10)) - header)) ? 1 : 0));
            byte *ostart               = (byte *)(dst);
            byte *oend                 = ostart + dstSize;
            byte *op                   = ostart + lhSize;
            uint  singleStream         = ((lhSize == 3) ? 1U : 0U);
            symbolEncodingType_e hType = writeEntropy != 0 ? hufMetadata->hType : symbolEncodingType_e.set_repeat;
            nuint cLitSize             = 0;

            *entropyWritten = 0;
            if (litSize == 0 || hufMetadata->hType == symbolEncodingType_e.set_basic)
            {
                return(ZSTD_noCompressLiterals(dst, dstSize, (void *)literals, litSize));
            }
            else if (hufMetadata->hType == symbolEncodingType_e.set_rle)
            {
                return(ZSTD_compressRleLiteralsBlock(dst, dstSize, (void *)literals, litSize));
            }

            assert(litSize > 0);
            assert(hufMetadata->hType == symbolEncodingType_e.set_compressed || hufMetadata->hType == symbolEncodingType_e.set_repeat);
            if (writeEntropy != 0 && hufMetadata->hType == symbolEncodingType_e.set_compressed)
            {
                memcpy((void *)(op), (void *)(hufMetadata->hufDesBuffer), (hufMetadata->hufDesSize));
                op       += hufMetadata->hufDesSize;
                cLitSize += hufMetadata->hufDesSize;
            }


            {
                nuint cSize = singleStream != 0 ? HUF_compress1X_usingCTable((void *)op, (nuint)(oend - op), (void *)literals, litSize, hufTable) : HUF_compress4X_usingCTable((void *)op, (nuint)(oend - op), (void *)literals, litSize, hufTable);

                op       += cSize;
                cLitSize += cSize;
                if (cSize == 0 || (ERR_isError(cSize)) != 0)
                {
                    return(0);
                }

                if (writeEntropy == 0 && cLitSize >= litSize)
                {
                    return(ZSTD_noCompressLiterals(dst, dstSize, (void *)literals, litSize));
                }

                if (lhSize < (nuint)(3 + ((cLitSize >= (uint)(1 * (1 << 10))) ? 1 : 0) + ((cLitSize >= (uint)(16 * (1 << 10))) ? 1 : 0)))
                {
                    assert(cLitSize > litSize);
                    return(ZSTD_noCompressLiterals(dst, dstSize, (void *)literals, litSize));
                }
            }

            switch (lhSize)
            {
            case 3:
            {
                uint lhc = (uint)(hType + ((singleStream == 0 ? 1 : 0) << 2)) + ((uint)(litSize) << 4) + ((uint)(cLitSize) << 14);

                MEM_writeLE24((void *)ostart, lhc);
                break;
            }

            case 4:
            {
                uint lhc = (uint)(hType + (2 << 2)) + ((uint)(litSize) << 4) + ((uint)(cLitSize) << 18);

                MEM_writeLE32((void *)ostart, lhc);
                break;
            }

            case 5:
            {
                uint lhc = (uint)(hType + (3 << 2)) + ((uint)(litSize) << 4) + ((uint)(cLitSize) << 22);

                MEM_writeLE32((void *)ostart, lhc);
                ostart[4] = (byte)(cLitSize >> 10);
                break;
            }

            default:
            {
                assert(0 != 0);
            }
            break;
            }

            *entropyWritten = 1;
            return((nuint)(op - ostart));
        }
Пример #2
0
        private static nuint ZSTD_estimateSubBlockSize_literal(byte *literals, nuint litSize, ZSTD_hufCTables_t *huf, ZSTD_hufCTablesMetadata_t *hufMetadata, void *workspace, nuint wkspSize, int writeEntropy)
        {
            uint *countWksp                = (uint *)(workspace);
            uint  maxSymbolValue           = 255;
            nuint literalSectionHeaderSize = 3;

            if (hufMetadata->hType == symbolEncodingType_e.set_basic)
            {
                return(litSize);
            }
            else if (hufMetadata->hType == symbolEncodingType_e.set_rle)
            {
                return(1);
            }
            else if (hufMetadata->hType == symbolEncodingType_e.set_compressed || hufMetadata->hType == symbolEncodingType_e.set_repeat)
            {
                nuint largest = HIST_count_wksp(countWksp, &maxSymbolValue, (void *)(byte *)(literals), litSize, workspace, wkspSize);

                if ((ERR_isError(largest)) != 0)
                {
                    return(litSize);
                }


                {
                    nuint cLitSizeEstimate = HUF_estimateCompressedSize((HUF_CElt_s *)(huf->CTable), countWksp, maxSymbolValue);

                    if (writeEntropy != 0)
                    {
                        cLitSizeEstimate += hufMetadata->hufDesSize;
                    }

                    return(cLitSizeEstimate + literalSectionHeaderSize);
                }
            }

            assert(0 != 0);
            return(0);
        }
Пример #3
0
        /** ZSTD_buildSuperBlockEntropy_literal() :
         *  Builds entropy for the super-block literals.
         *  Stores literals block type (raw, rle, compressed, repeat) and
         *  huffman description table to hufMetadata.
         *  @return : size of huffman description table or error code */
        private static nuint ZSTD_buildSuperBlockEntropy_literal(void *src, nuint srcSize, ZSTD_hufCTables_t *prevHuf, ZSTD_hufCTables_t *nextHuf, ZSTD_hufCTablesMetadata_t *hufMetadata, int disableLiteralsCompression, void *workspace, nuint wkspSize)
        {
            byte *     wkspStart      = (byte *)(workspace);
            byte *     wkspEnd        = wkspStart + wkspSize;
            byte *     countWkspStart = wkspStart;
            uint *     countWksp      = (uint *)(workspace);
            nuint      countWkspSize  = (uint)((255 + 1)) * (nuint)(4);
            byte *     nodeWksp       = countWkspStart + countWkspSize;
            nuint      nodeWkspSize   = (nuint)(wkspEnd - nodeWksp);
            uint       maxSymbolValue = 255;
            uint       huffLog        = 11;
            HUF_repeat repeat         = prevHuf->repeatMode;

            memcpy((void *)(nextHuf), (void *)(prevHuf), ((nuint)(sizeof(ZSTD_hufCTables_t))));
            if (disableLiteralsCompression != 0)
            {
                hufMetadata->hType = symbolEncodingType_e.set_basic;
                return(0);
            }


            {
                nuint minLitSize = (nuint)((prevHuf->repeatMode == HUF_repeat.HUF_repeat_valid) ? 6 : 63);

                if (srcSize <= minLitSize)
                {
                    hufMetadata->hType = symbolEncodingType_e.set_basic;
                    return(0);
                }
            }


            {
                nuint largest = HIST_count_wksp(countWksp, &maxSymbolValue, (void *)(byte *)(src), srcSize, workspace, wkspSize);


                {
                    nuint err_code = (largest);

                    if ((ERR_isError(err_code)) != 0)
                    {
                        return(err_code);
                    }
                }

                if (largest == srcSize)
                {
                    hufMetadata->hType = symbolEncodingType_e.set_rle;
                    return(0);
                }

                if (largest <= (srcSize >> 7) + 4)
                {
                    hufMetadata->hType = symbolEncodingType_e.set_basic;
                    return(0);
                }
            }

            if (repeat == HUF_repeat.HUF_repeat_check && (HUF_validateCTable((HUF_CElt_s *)(prevHuf->CTable), countWksp, maxSymbolValue)) == 0)
            {
                repeat = HUF_repeat.HUF_repeat_none;
            }

            memset((void *)(nextHuf->CTable), (0), ((nuint)(sizeof(HUF_CElt_s) * 256)));
            huffLog = HUF_optimalTableLog(huffLog, srcSize, maxSymbolValue);

            {
                nuint maxBits = HUF_buildCTable_wksp((HUF_CElt_s *)(nextHuf->CTable), countWksp, maxSymbolValue, huffLog, (void *)nodeWksp, nodeWkspSize);


                {
                    nuint err_code = (maxBits);

                    if ((ERR_isError(err_code)) != 0)
                    {
                        return(err_code);
                    }
                }

                huffLog = (uint)(maxBits);

                {
                    nuint newCSize = HUF_estimateCompressedSize((HUF_CElt_s *)(nextHuf->CTable), countWksp, maxSymbolValue);
                    nuint hSize    = HUF_writeCTable((void *)hufMetadata->hufDesBuffer, (nuint)(128), (HUF_CElt_s *)(nextHuf->CTable), maxSymbolValue, huffLog);

                    if (repeat != HUF_repeat.HUF_repeat_none)
                    {
                        nuint oldCSize = HUF_estimateCompressedSize((HUF_CElt_s *)(prevHuf->CTable), countWksp, maxSymbolValue);

                        if (oldCSize < srcSize && (oldCSize <= hSize + newCSize || hSize + 12 >= srcSize))
                        {
                            memcpy((void *)(nextHuf), (void *)(prevHuf), ((nuint)(sizeof(ZSTD_hufCTables_t))));
                            hufMetadata->hType = symbolEncodingType_e.set_repeat;
                            return(0);
                        }
                    }

                    if (newCSize + hSize >= srcSize)
                    {
                        memcpy((void *)(nextHuf), (void *)(prevHuf), ((nuint)(sizeof(ZSTD_hufCTables_t))));
                        hufMetadata->hType = symbolEncodingType_e.set_basic;
                        return(0);
                    }

                    hufMetadata->hType  = symbolEncodingType_e.set_compressed;
                    nextHuf->repeatMode = HUF_repeat.HUF_repeat_check;
                    return(hSize);
                }
            }
        }