示例#1
0
        private static nuint ZSTD_seqDecompressedSize(seqStore_t *seqStore, seqDef_s *sequences, nuint nbSeq, nuint litSize, int lastSequence)
        {
            seqDef_s *sstart         = sequences;
            seqDef_s *send           = sequences + nbSeq;
            seqDef_s *sp             = sstart;
            nuint     matchLengthSum = 0;
            nuint     litLengthSum   = 0;

            while (send - sp > 0)
            {
                ZSTD_sequenceLength seqLen = ZSTD_getSequenceLength(seqStore, sp);

                litLengthSum   += seqLen.litLength;
                matchLengthSum += seqLen.matchLength;
                sp++;
            }

            assert(litLengthSum <= litSize);
            if (lastSequence == 0)
            {
                assert(litLengthSum == litSize);
            }

            return(matchLengthSum + litSize);
        }
        public static nuint ZSTD_encodeSequences(void *dst, nuint dstCapacity, uint *CTable_MatchLength, byte *mlCodeTable, uint *CTable_OffsetBits, byte *ofCodeTable, uint *CTable_LitLength, byte *llCodeTable, seqDef_s *sequences, nuint nbSeq, int longOffsets, int bmi2)
        {
            if (bmi2 != 0)
            {
                return(ZSTD_encodeSequences_bmi2(dst, dstCapacity, CTable_MatchLength, mlCodeTable, CTable_OffsetBits, ofCodeTable, CTable_LitLength, llCodeTable, sequences, nbSeq, longOffsets));
            }

            return(ZSTD_encodeSequences_default(dst, dstCapacity, CTable_MatchLength, mlCodeTable, CTable_OffsetBits, ofCodeTable, CTable_LitLength, llCodeTable, sequences, nbSeq, longOffsets));
        }
 private static nuint ZSTD_encodeSequences_bmi2(void *dst, nuint dstCapacity, uint *CTable_MatchLength, byte *mlCodeTable, uint *CTable_OffsetBits, byte *ofCodeTable, uint *CTable_LitLength, byte *llCodeTable, seqDef_s *sequences, nuint nbSeq, int longOffsets)
 {
     return(ZSTD_encodeSequences_body(dst, dstCapacity, CTable_MatchLength, mlCodeTable, CTable_OffsetBits, ofCodeTable, CTable_LitLength, llCodeTable, sequences, nbSeq, longOffsets));
 }
        private static nuint ZSTD_encodeSequences_body(void *dst, nuint dstCapacity, uint *CTable_MatchLength, byte *mlCodeTable, uint *CTable_OffsetBits, byte *ofCodeTable, uint *CTable_LitLength, byte *llCodeTable, seqDef_s *sequences, nuint nbSeq, int longOffsets)
        {
            BIT_CStream_t blockStream;
            FSE_CState_t  stateMatchLength;
            FSE_CState_t  stateOffsetBits;
            FSE_CState_t  stateLitLength;

            if ((ERR_isError(BIT_initCStream(&blockStream, dst, dstCapacity))) != 0)
            {
                return(unchecked ((nuint)(-(int)ZSTD_ErrorCode.ZSTD_error_dstSize_tooSmall)));
            }

            FSE_initCState2(&stateMatchLength, CTable_MatchLength, mlCodeTable[nbSeq - 1]);
            FSE_initCState2(&stateOffsetBits, CTable_OffsetBits, ofCodeTable[nbSeq - 1]);
            FSE_initCState2(&stateLitLength, CTable_LitLength, llCodeTable[nbSeq - 1]);
            BIT_addBits(&blockStream, sequences[nbSeq - 1].litLength, LL_bits[llCodeTable[nbSeq - 1]]);
            if (MEM_32bits)
            {
                BIT_flushBits(&blockStream);
            }

            BIT_addBits(&blockStream, sequences[nbSeq - 1].matchLength, ML_bits[mlCodeTable[nbSeq - 1]]);
            if (MEM_32bits)
            {
                BIT_flushBits(&blockStream);
            }

            if (longOffsets != 0)
            {
                uint ofBits    = ofCodeTable[nbSeq - 1];
                uint extraBits = ofBits - ((ofBits) < (((uint)(MEM_32bits ? 25 : 57)) - 1) ? (ofBits) : (((uint)(MEM_32bits ? 25 : 57)) - 1));

                if (extraBits != 0)
                {
                    BIT_addBits(&blockStream, sequences[nbSeq - 1].offset, extraBits);
                    BIT_flushBits(&blockStream);
                }

                BIT_addBits(&blockStream, sequences[nbSeq - 1].offset >> (int)extraBits, ofBits - extraBits);
            }
            else
            {
                BIT_addBits(&blockStream, sequences[nbSeq - 1].offset, ofCodeTable[nbSeq - 1]);
            }

            BIT_flushBits(&blockStream);

            {
                nuint n;

                for (n = nbSeq - 2; n < nbSeq; n--)
                {
                    byte llCode = llCodeTable[n];
                    byte ofCode = ofCodeTable[n];
                    byte mlCode = mlCodeTable[n];
                    uint llBits = LL_bits[llCode];
                    uint ofBits = ofCode;
                    uint mlBits = ML_bits[mlCode];

                    FSE_encodeSymbol(&blockStream, &stateOffsetBits, ofCode);
                    FSE_encodeSymbol(&blockStream, &stateMatchLength, mlCode);
                    if (MEM_32bits)
                    {
                        BIT_flushBits(&blockStream);
                    }

                    FSE_encodeSymbol(&blockStream, &stateLitLength, llCode);
                    if (MEM_32bits || (ofBits + mlBits + llBits >= (uint)(64 - 7 - (9 + 9 + 8))))
                    {
                        BIT_flushBits(&blockStream);
                    }

                    BIT_addBits(&blockStream, sequences[n].litLength, llBits);
                    if (MEM_32bits && ((llBits + mlBits) > 24))
                    {
                        BIT_flushBits(&blockStream);
                    }

                    BIT_addBits(&blockStream, sequences[n].matchLength, mlBits);
                    if (MEM_32bits || (ofBits + mlBits + llBits > 56))
                    {
                        BIT_flushBits(&blockStream);
                    }

                    if (longOffsets != 0)
                    {
                        uint extraBits = ofBits - ((ofBits) < (((uint)(MEM_32bits ? 25 : 57)) - 1) ? (ofBits) : (((uint)(MEM_32bits ? 25 : 57)) - 1));

                        if (extraBits != 0)
                        {
                            BIT_addBits(&blockStream, sequences[n].offset, extraBits);
                            BIT_flushBits(&blockStream);
                        }

                        BIT_addBits(&blockStream, sequences[n].offset >> (int)extraBits, ofBits - extraBits);
                    }
                    else
                    {
                        BIT_addBits(&blockStream, sequences[n].offset, ofBits);
                    }

                    BIT_flushBits(&blockStream);
                }
            }

            FSE_flushCState(&blockStream, &stateMatchLength);
            FSE_flushCState(&blockStream, &stateOffsetBits);
            FSE_flushCState(&blockStream, &stateLitLength);

            {
                nuint streamSize = BIT_closeCStream(&blockStream);

                if (streamSize == 0)
                {
                    return(unchecked ((nuint)(-(int)ZSTD_ErrorCode.ZSTD_error_dstSize_tooSmall)));
                }

                return(streamSize);
            }
        }
示例#5
0
        /** ZSTD_compressSubBlock_multi() :
         *  Breaks super-block into multiple sub-blocks and compresses them.
         *  Entropy will be written to the first block.
         *  The following blocks will use repeat mode to compress.
         *  All sub-blocks are compressed blocks (no raw or rle blocks).
         *  @return : compressed size of the super block (which is multiple ZSTD blocks)
         *            Or 0 if it failed to compress. */
        private static nuint ZSTD_compressSubBlock_multi(seqStore_t *seqStorePtr, ZSTD_compressedBlockState_t *prevCBlock, ZSTD_compressedBlockState_t *nextCBlock, ZSTD_entropyCTablesMetadata_t *entropyMetadata, ZSTD_CCtx_params_s *cctxParams, void *dst, nuint dstCapacity, void *src, nuint srcSize, int bmi2, uint lastBlock, void *workspace, nuint wkspSize)
        {
            seqDef_s *sstart = seqStorePtr->sequencesStart;
            seqDef_s *send = seqStorePtr->sequences;
            seqDef_s *sp = sstart;
            byte *    lstart = seqStorePtr->litStart;
            byte *    lend = seqStorePtr->lit;
            byte *    lp = lstart;
            byte *    ip = (byte *)(src);
            byte *    iend = ip + srcSize;
            byte *    ostart = (byte *)(dst);
            byte *    oend = ostart + dstCapacity;
            byte *    op = ostart;
            byte *    llCodePtr = seqStorePtr->llCode;
            byte *    mlCodePtr = seqStorePtr->mlCode;
            byte *    ofCodePtr = seqStorePtr->ofCode;
            nuint     targetCBlockSize = cctxParams->targetCBlockSize;
            nuint     litSize, seqCount;
            int       writeLitEntropy = ((entropyMetadata->hufMetadata.hType == symbolEncodingType_e.set_compressed) ? 1 : 0);
            int       writeSeqEntropy = 1;
            int       lastSequence    = 0;

            litSize  = 0;
            seqCount = 0;
            do
            {
                nuint cBlockSizeEstimate = 0;

                if (sstart == send)
                {
                    lastSequence = 1;
                }
                else
                {
                    seqDef_s *sequence = sp + seqCount;

                    lastSequence = ((sequence == send - 1) ? 1 : 0);
                    litSize     += ZSTD_getSequenceLength(seqStorePtr, sequence).litLength;
                    seqCount++;
                }

                if (lastSequence != 0)
                {
                    assert(lp <= lend);
                    assert(litSize <= (nuint)(lend - lp));
                    litSize = (nuint)(lend - lp);
                }

                cBlockSizeEstimate = ZSTD_estimateSubBlockSize(lp, litSize, ofCodePtr, llCodePtr, mlCodePtr, seqCount, &nextCBlock->entropy, entropyMetadata, workspace, wkspSize, writeLitEntropy, writeSeqEntropy);
                if (cBlockSizeEstimate > targetCBlockSize || lastSequence != 0)
                {
                    int   litEntropyWritten = 0;
                    int   seqEntropyWritten = 0;
                    nuint decompressedSize  = ZSTD_seqDecompressedSize(seqStorePtr, sp, seqCount, litSize, lastSequence);
                    nuint cSize             = ZSTD_compressSubBlock(&nextCBlock->entropy, entropyMetadata, sp, seqCount, lp, litSize, llCodePtr, mlCodePtr, ofCodePtr, cctxParams, (void *)op, (nuint)(oend - op), bmi2, writeLitEntropy, writeSeqEntropy, &litEntropyWritten, &seqEntropyWritten, ((lastBlock != 0 && lastSequence != 0) ? 1U : 0U));


                    {
                        nuint err_code = (cSize);

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

                    if (cSize > 0 && cSize < decompressedSize)
                    {
                        assert(ip + decompressedSize <= iend);
                        ip        += decompressedSize;
                        sp        += seqCount;
                        lp        += litSize;
                        op        += cSize;
                        llCodePtr += seqCount;
                        mlCodePtr += seqCount;
                        ofCodePtr += seqCount;
                        litSize    = 0;
                        seqCount   = 0;
                        if (litEntropyWritten != 0)
                        {
                            writeLitEntropy = 0;
                        }

                        if (seqEntropyWritten != 0)
                        {
                            writeSeqEntropy = 0;
                        }
                    }
                }
            }while (lastSequence == 0);

            if (writeLitEntropy != 0)
            {
                memcpy((void *)(&nextCBlock->entropy.huf), (void *)(&prevCBlock->entropy.huf), ((nuint)(sizeof(ZSTD_hufCTables_t))));
            }

            if (writeSeqEntropy != 0 && (ZSTD_needSequenceEntropyTables(&entropyMetadata->fseMetadata)) != 0)
            {
                return(0);
            }

            if (ip < iend)
            {
                nuint cSize = ZSTD_noCompressBlock((void *)op, (nuint)(oend - op), (void *)ip, (nuint)(iend - ip), lastBlock);


                {
                    nuint err_code = (cSize);

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

                assert(cSize != 0);
                op += cSize;
                if (sp < send)
                {
                    seqDef_s * seq;
                    repcodes_s rep;

                    memcpy((void *)(&rep), (void *)(prevCBlock->rep), ((nuint)(sizeof(repcodes_s))));
                    for (seq = sstart; seq < sp; ++seq)
                    {
                        rep = ZSTD_updateRep(rep.rep, seq->offset - 1, ((ZSTD_getSequenceLength(seqStorePtr, seq).litLength == 0) ? 1U : 0U));
                    }

                    memcpy((void *)(nextCBlock->rep), (void *)(&rep), ((nuint)(sizeof(repcodes_s))));
                }
            }

            return((nuint)(op - ostart));
        }
示例#6
0
        /** ZSTD_compressSubBlock() :
         *  Compresses a single sub-block.
         *  @return : compressed size of the sub-block
         *            Or 0 if it failed to compress. */
        private static nuint ZSTD_compressSubBlock(ZSTD_entropyCTables_t *entropy, ZSTD_entropyCTablesMetadata_t *entropyMetadata, seqDef_s *sequences, nuint nbSeq, byte *literals, nuint litSize, byte *llCode, byte *mlCode, byte *ofCode, ZSTD_CCtx_params_s *cctxParams, void *dst, nuint dstCapacity, int bmi2, int writeLitEntropy, int writeSeqEntropy, int *litEntropyWritten, int *seqEntropyWritten, uint lastBlock)
        {
            byte *ostart = (byte *)(dst);
            byte *oend   = ostart + dstCapacity;
            byte *op     = ostart + ZSTD_blockHeaderSize;


            {
                nuint cLitSize = ZSTD_compressSubBlock_literal((HUF_CElt_s *)(entropy->huf.CTable), &entropyMetadata->hufMetadata, literals, litSize, (void *)op, (nuint)(oend - op), bmi2, writeLitEntropy, litEntropyWritten);


                {
                    nuint err_code = (cLitSize);

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

                if (cLitSize == 0)
                {
                    return(0);
                }

                op += cLitSize;
            }


            {
                nuint cSeqSize = ZSTD_compressSubBlock_sequences(&entropy->fse, &entropyMetadata->fseMetadata, sequences, nbSeq, llCode, mlCode, ofCode, cctxParams, (void *)op, (nuint)(oend - op), bmi2, writeSeqEntropy, seqEntropyWritten);


                {
                    nuint err_code = (cSeqSize);

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

                if (cSeqSize == 0)
                {
                    return(0);
                }

                op += cSeqSize;
            }


            {
                nuint cSize          = (nuint)((ulong)((op - ostart)) - ZSTD_blockHeaderSize);
                uint  cBlockHeader24 = lastBlock + (((uint)(blockType_e.bt_compressed)) << 1) + (uint)(cSize << 3);

                MEM_writeLE24((void *)ostart, cBlockHeader24);
            }

            return((nuint)(op - ostart));
        }
示例#7
0
        /** ZSTD_compressSubBlock_sequences() :
         *  Compresses sequences section for a sub-block.
         *  fseMetadata->llType, fseMetadata->ofType, and fseMetadata->mlType have
         *  symbol compression modes for the super-block.
         *  The first successfully compressed block will have these in its header.
         *  We set entropyWritten=1 when we succeed in compressing the sequences.
         *  The following sub-blocks will always have repeat mode.
         *  @return : compressed size of sequences section of a sub-block
         *            Or 0 if it is unable to compress
         *            Or error code. */
        private static nuint ZSTD_compressSubBlock_sequences(ZSTD_fseCTables_t *fseTables, ZSTD_fseCTablesMetadata_t *fseMetadata, seqDef_s *sequences, nuint nbSeq, byte *llCode, byte *mlCode, byte *ofCode, ZSTD_CCtx_params_s *cctxParams, void *dst, nuint dstCapacity, int bmi2, int writeEntropy, int *entropyWritten)
        {
            int   longOffsets = ((cctxParams->cParams.windowLog > ((uint)(MEM_32bits ? 25 : 57))) ? 1 : 0);
            byte *ostart      = (byte *)(dst);
            byte *oend        = ostart + dstCapacity;
            byte *op          = ostart;
            byte *seqHead;

            *entropyWritten = 0;
            if ((oend - op) < 3 + 1)
            {
                return(unchecked ((nuint)(-(int)ZSTD_ErrorCode.ZSTD_error_dstSize_tooSmall)));
            }

            if (nbSeq < 0x7F)
            {
                *op++ = (byte)(nbSeq);
            }
            else if (nbSeq < 0x7F00)
            {
                op[0] = (byte)((nbSeq >> 8) + 0x80); op[1] = (byte)(nbSeq); op += 2;
            }
            else
            {
                op[0] = 0xFF; MEM_writeLE16((void *)(op + 1), (ushort)(nbSeq - 0x7F00)); op += 3;
            }

            if (nbSeq == 0)
            {
                return((nuint)(op - ostart));
            }

            seqHead = op++;
            if (writeEntropy != 0)
            {
                uint LLtype  = (uint)fseMetadata->llType;
                uint Offtype = (uint)fseMetadata->ofType;
                uint MLtype  = (uint)fseMetadata->mlType;

                *seqHead = (byte)((LLtype << 6) + (Offtype << 4) + (MLtype << 2));
                memcpy((void *)(op), (void *)(fseMetadata->fseTablesBuffer), (fseMetadata->fseTablesSize));
                op += fseMetadata->fseTablesSize;
            }
            else
            {
                uint repeat = (uint)symbolEncodingType_e.set_repeat;

                *seqHead = (byte)((repeat << 6) + (repeat << 4) + (repeat << 2));
            }


            {
                nuint bitstreamSize = ZSTD_encodeSequences((void *)op, (nuint)(oend - op), (uint *)fseTables->matchlengthCTable, mlCode, (uint *)fseTables->offcodeCTable, ofCode, (uint *)fseTables->litlengthCTable, llCode, sequences, nbSeq, longOffsets, bmi2);


                {
                    nuint err_code = (bitstreamSize);

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

                op += bitstreamSize;
                if (writeEntropy != 0 && fseMetadata->lastCountSize != 0 && fseMetadata->lastCountSize + bitstreamSize < 4)
                {
                    assert(fseMetadata->lastCountSize + bitstreamSize == 3);
                    return(0);
                }
            }

            if (op - seqHead < 4)
            {
                return(0);
            }

            *entropyWritten = 1;
            return((nuint)(op - ostart));
        }
示例#8
0
        private static ZSTD_sequenceLength ZSTD_getSequenceLength(seqStore_t *seqStore, seqDef_s *seq)
        {
            ZSTD_sequenceLength seqLen;

            seqLen.litLength   = seq->litLength;
            seqLen.matchLength = (uint)(seq->matchLength + 3);
            if (seqStore->longLengthPos == (uint)(seq - seqStore->sequencesStart))
            {
                if (seqStore->longLengthID == 1)
                {
                    seqLen.litLength += 0xFFFF;
                }

                if (seqStore->longLengthID == 2)
                {
                    seqLen.matchLength += 0xFFFF;
                }
            }

            return(seqLen);
        }
示例#9
0
        private static void ZDICT_countEStats(EStats_ress_t esr, ZSTD_parameters * @params, uint *countLit, uint *offsetcodeCount, uint *matchlengthCount, uint *litlengthCount, uint *repOffsets, void *src, nuint srcSize, uint notificationLevel)
        {
            nuint blockSizeMax = (nuint)((((1 << 17)) < (1 << (int)@params->cParams.windowLog) ? ((1 << 17)) : (1 << (int)@params->cParams.windowLog)));
            nuint cSize;

            if (srcSize > blockSizeMax)
            {
                srcSize = blockSizeMax;
            }


            {
                nuint errorCode = ZSTD_compressBegin_usingCDict(esr.zc, esr.dict);

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

            cSize = ZSTD_compressBlock(esr.zc, esr.workPlace, (nuint)((1 << 17)), src, srcSize);
            if ((ERR_isError(cSize)) != 0)
            {
                return;
            }

            if (cSize != 0)
            {
                seqStore_t *seqStorePtr = ZSTD_getSeqStore(esr.zc);


                {
                    byte *bytePtr;

                    for (bytePtr = seqStorePtr->litStart; bytePtr < seqStorePtr->lit; bytePtr++)
                    {
                        countLit[*bytePtr]++;
                    }
                }


                {
                    uint nbSeq = (uint)(seqStorePtr->sequences - seqStorePtr->sequencesStart);

                    ZSTD_seqToCodes(seqStorePtr);

                    {
                        byte *codePtr = seqStorePtr->ofCode;
                        uint  u;

                        for (u = 0; u < nbSeq; u++)
                        {
                            offsetcodeCount[codePtr[u]]++;
                        }
                    }


                    {
                        byte *codePtr = seqStorePtr->mlCode;
                        uint  u;

                        for (u = 0; u < nbSeq; u++)
                        {
                            matchlengthCount[codePtr[u]]++;
                        }
                    }


                    {
                        byte *codePtr = seqStorePtr->llCode;
                        uint  u;

                        for (u = 0; u < nbSeq; u++)
                        {
                            litlengthCount[codePtr[u]]++;
                        }
                    }

                    if (nbSeq >= 2)
                    {
                        seqDef_s *seq     = seqStorePtr->sequencesStart;
                        uint      offset1 = seq[0].offset - 3;
                        uint      offset2 = seq[1].offset - 3;

                        if (offset1 >= 1024)
                        {
                            offset1 = 0;
                        }

                        if (offset2 >= 1024)
                        {
                            offset2 = 0;
                        }

                        repOffsets[offset1] += 3;
                        repOffsets[offset2] += 1;
                    }
                }
            }
        }