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); } }
/** 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)); }
/** 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)); }
/** 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)); }
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); }
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; } } } }