/** 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_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)); }
private static nuint ZSTD_estimateSubBlockSize(byte *literals, nuint litSize, byte *ofCodeTable, byte *llCodeTable, byte *mlCodeTable, nuint nbSeq, ZSTD_entropyCTables_t *entropy, ZSTD_entropyCTablesMetadata_t *entropyMetadata, void *workspace, nuint wkspSize, int writeLitEntropy, int writeSeqEntropy) { nuint cSizeEstimate = 0; cSizeEstimate += ZSTD_estimateSubBlockSize_literal(literals, litSize, &entropy->huf, &entropyMetadata->hufMetadata, workspace, wkspSize, writeLitEntropy); cSizeEstimate += ZSTD_estimateSubBlockSize_sequences(ofCodeTable, llCodeTable, mlCodeTable, nbSeq, &entropy->fse, &entropyMetadata->fseMetadata, workspace, wkspSize, writeSeqEntropy); return(cSizeEstimate + ZSTD_blockHeaderSize); }
/** ZSTD_buildSuperBlockEntropy() : * Builds entropy for the super-block. * @return : 0 on success or error code */ private static nuint ZSTD_buildSuperBlockEntropy(seqStore_t *seqStorePtr, ZSTD_entropyCTables_t *prevEntropy, ZSTD_entropyCTables_t *nextEntropy, ZSTD_CCtx_params_s *cctxParams, ZSTD_entropyCTablesMetadata_t *entropyMetadata, void *workspace, nuint wkspSize) { nuint litSize = (nuint)(seqStorePtr->lit - seqStorePtr->litStart); entropyMetadata->hufMetadata.hufDesSize = ZSTD_buildSuperBlockEntropy_literal((void *)seqStorePtr->litStart, litSize, &prevEntropy->huf, &nextEntropy->huf, &entropyMetadata->hufMetadata, ZSTD_disableLiteralsCompression(cctxParams), workspace, wkspSize); { nuint err_code = (entropyMetadata->hufMetadata.hufDesSize); if ((ERR_isError(err_code)) != 0) { return(err_code); } } entropyMetadata->fseMetadata.fseTablesSize = ZSTD_buildSuperBlockEntropy_sequences(seqStorePtr, &prevEntropy->fse, &nextEntropy->fse, cctxParams, &entropyMetadata->fseMetadata, workspace, wkspSize); { nuint err_code = (entropyMetadata->fseMetadata.fseTablesSize); if ((ERR_isError(err_code)) != 0) { return(err_code); } } return(0); }