1*3117ece4Schristos /* 2*3117ece4Schristos * Copyright (c) Meta Platforms, Inc. and affiliates. 3*3117ece4Schristos * All rights reserved. 4*3117ece4Schristos * 5*3117ece4Schristos * This source code is licensed under both the BSD-style license (found in the 6*3117ece4Schristos * LICENSE file in the root directory of this source tree) and the GPLv2 (found 7*3117ece4Schristos * in the COPYING file in the root directory of this source tree). 8*3117ece4Schristos * You may select, at your option, one of the above-listed licenses. 9*3117ece4Schristos */ 10*3117ece4Schristos 11*3117ece4Schristos 12*3117ece4Schristos 13*3117ece4Schristos /* ************************************* 14*3117ece4Schristos * Dependencies 15*3117ece4Schristos ***************************************/ 16*3117ece4Schristos #define ZBUFF_STATIC_LINKING_ONLY 17*3117ece4Schristos #include "zbuff.h" 18*3117ece4Schristos #include "../common/error_private.h" 19*3117ece4Schristos 20*3117ece4Schristos 21*3117ece4Schristos /*-*********************************************************** 22*3117ece4Schristos * Streaming compression 23*3117ece4Schristos * 24*3117ece4Schristos * A ZBUFF_CCtx object is required to track streaming operation. 25*3117ece4Schristos * Use ZBUFF_createCCtx() and ZBUFF_freeCCtx() to create/release resources. 26*3117ece4Schristos * Use ZBUFF_compressInit() to start a new compression operation. 27*3117ece4Schristos * ZBUFF_CCtx objects can be reused multiple times. 28*3117ece4Schristos * 29*3117ece4Schristos * Use ZBUFF_compressContinue() repetitively to consume your input. 30*3117ece4Schristos * *srcSizePtr and *dstCapacityPtr can be any size. 31*3117ece4Schristos * The function will report how many bytes were read or written by modifying *srcSizePtr and *dstCapacityPtr. 32*3117ece4Schristos * Note that it may not consume the entire input, in which case it's up to the caller to call again the function with remaining input. 33*3117ece4Schristos * The content of dst will be overwritten (up to *dstCapacityPtr) at each function call, so save its content if it matters or change dst . 34*3117ece4Schristos * @return : a hint to preferred nb of bytes to use as input for next function call (it's only a hint, to improve latency) 35*3117ece4Schristos * or an error code, which can be tested using ZBUFF_isError(). 36*3117ece4Schristos * 37*3117ece4Schristos * ZBUFF_compressFlush() can be used to instruct ZBUFF to compress and output whatever remains within its buffer. 38*3117ece4Schristos * Note that it will not output more than *dstCapacityPtr. 39*3117ece4Schristos * Therefore, some content might still be left into its internal buffer if dst buffer is too small. 40*3117ece4Schristos * @return : nb of bytes still present into internal buffer (0 if it's empty) 41*3117ece4Schristos * or an error code, which can be tested using ZBUFF_isError(). 42*3117ece4Schristos * 43*3117ece4Schristos * ZBUFF_compressEnd() instructs to finish a frame. 44*3117ece4Schristos * It will perform a flush and write frame epilogue. 45*3117ece4Schristos * Similar to ZBUFF_compressFlush(), it may not be able to output the entire internal buffer content if *dstCapacityPtr is too small. 46*3117ece4Schristos * @return : nb of bytes still present into internal buffer (0 if it's empty) 47*3117ece4Schristos * or an error code, which can be tested using ZBUFF_isError(). 48*3117ece4Schristos * 49*3117ece4Schristos * Hint : recommended buffer sizes (not compulsory) 50*3117ece4Schristos * input : ZSTD_BLOCKSIZE_MAX (128 KB), internal unit size, it improves latency to use this value. 51*3117ece4Schristos * output : ZSTD_compressBound(ZSTD_BLOCKSIZE_MAX) + ZSTD_blockHeaderSize + ZBUFF_endFrameSize : ensures it's always possible to write/flush/end a full block at best speed. 52*3117ece4Schristos * ***********************************************************/ 53*3117ece4Schristos 54*3117ece4Schristos ZBUFF_CCtx* ZBUFF_createCCtx(void) 55*3117ece4Schristos { 56*3117ece4Schristos return ZSTD_createCStream(); 57*3117ece4Schristos } 58*3117ece4Schristos 59*3117ece4Schristos ZBUFF_CCtx* ZBUFF_createCCtx_advanced(ZSTD_customMem customMem) 60*3117ece4Schristos { 61*3117ece4Schristos return ZSTD_createCStream_advanced(customMem); 62*3117ece4Schristos } 63*3117ece4Schristos 64*3117ece4Schristos size_t ZBUFF_freeCCtx(ZBUFF_CCtx* zbc) 65*3117ece4Schristos { 66*3117ece4Schristos return ZSTD_freeCStream(zbc); 67*3117ece4Schristos } 68*3117ece4Schristos 69*3117ece4Schristos 70*3117ece4Schristos /* ====== Initialization ====== */ 71*3117ece4Schristos 72*3117ece4Schristos size_t ZBUFF_compressInit_advanced(ZBUFF_CCtx* zbc, 73*3117ece4Schristos const void* dict, size_t dictSize, 74*3117ece4Schristos ZSTD_parameters params, unsigned long long pledgedSrcSize) 75*3117ece4Schristos { 76*3117ece4Schristos if (pledgedSrcSize==0) pledgedSrcSize = ZSTD_CONTENTSIZE_UNKNOWN; /* preserve "0 == unknown" behavior */ 77*3117ece4Schristos FORWARD_IF_ERROR(ZSTD_CCtx_reset(zbc, ZSTD_reset_session_only), ""); 78*3117ece4Schristos FORWARD_IF_ERROR(ZSTD_CCtx_setPledgedSrcSize(zbc, pledgedSrcSize), ""); 79*3117ece4Schristos 80*3117ece4Schristos FORWARD_IF_ERROR(ZSTD_checkCParams(params.cParams), ""); 81*3117ece4Schristos FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(zbc, ZSTD_c_windowLog, params.cParams.windowLog), ""); 82*3117ece4Schristos FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(zbc, ZSTD_c_hashLog, params.cParams.hashLog), ""); 83*3117ece4Schristos FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(zbc, ZSTD_c_chainLog, params.cParams.chainLog), ""); 84*3117ece4Schristos FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(zbc, ZSTD_c_searchLog, params.cParams.searchLog), ""); 85*3117ece4Schristos FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(zbc, ZSTD_c_minMatch, params.cParams.minMatch), ""); 86*3117ece4Schristos FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(zbc, ZSTD_c_targetLength, params.cParams.targetLength), ""); 87*3117ece4Schristos FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(zbc, ZSTD_c_strategy, params.cParams.strategy), ""); 88*3117ece4Schristos 89*3117ece4Schristos FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(zbc, ZSTD_c_contentSizeFlag, params.fParams.contentSizeFlag), ""); 90*3117ece4Schristos FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(zbc, ZSTD_c_checksumFlag, params.fParams.checksumFlag), ""); 91*3117ece4Schristos FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(zbc, ZSTD_c_dictIDFlag, params.fParams.noDictIDFlag), ""); 92*3117ece4Schristos 93*3117ece4Schristos FORWARD_IF_ERROR(ZSTD_CCtx_loadDictionary(zbc, dict, dictSize), ""); 94*3117ece4Schristos return 0; 95*3117ece4Schristos } 96*3117ece4Schristos 97*3117ece4Schristos size_t ZBUFF_compressInitDictionary(ZBUFF_CCtx* zbc, const void* dict, size_t dictSize, int compressionLevel) 98*3117ece4Schristos { 99*3117ece4Schristos FORWARD_IF_ERROR(ZSTD_CCtx_reset(zbc, ZSTD_reset_session_only), ""); 100*3117ece4Schristos FORWARD_IF_ERROR(ZSTD_CCtx_setParameter(zbc, ZSTD_c_compressionLevel, compressionLevel), ""); 101*3117ece4Schristos FORWARD_IF_ERROR(ZSTD_CCtx_loadDictionary(zbc, dict, dictSize), ""); 102*3117ece4Schristos return 0; 103*3117ece4Schristos } 104*3117ece4Schristos 105*3117ece4Schristos size_t ZBUFF_compressInit(ZBUFF_CCtx* zbc, int compressionLevel) 106*3117ece4Schristos { 107*3117ece4Schristos return ZSTD_initCStream(zbc, compressionLevel); 108*3117ece4Schristos } 109*3117ece4Schristos 110*3117ece4Schristos /* ====== Compression ====== */ 111*3117ece4Schristos 112*3117ece4Schristos 113*3117ece4Schristos size_t ZBUFF_compressContinue(ZBUFF_CCtx* zbc, 114*3117ece4Schristos void* dst, size_t* dstCapacityPtr, 115*3117ece4Schristos const void* src, size_t* srcSizePtr) 116*3117ece4Schristos { 117*3117ece4Schristos size_t result; 118*3117ece4Schristos ZSTD_outBuffer outBuff; 119*3117ece4Schristos ZSTD_inBuffer inBuff; 120*3117ece4Schristos outBuff.dst = dst; 121*3117ece4Schristos outBuff.pos = 0; 122*3117ece4Schristos outBuff.size = *dstCapacityPtr; 123*3117ece4Schristos inBuff.src = src; 124*3117ece4Schristos inBuff.pos = 0; 125*3117ece4Schristos inBuff.size = *srcSizePtr; 126*3117ece4Schristos result = ZSTD_compressStream(zbc, &outBuff, &inBuff); 127*3117ece4Schristos *dstCapacityPtr = outBuff.pos; 128*3117ece4Schristos *srcSizePtr = inBuff.pos; 129*3117ece4Schristos return result; 130*3117ece4Schristos } 131*3117ece4Schristos 132*3117ece4Schristos 133*3117ece4Schristos 134*3117ece4Schristos /* ====== Finalize ====== */ 135*3117ece4Schristos 136*3117ece4Schristos size_t ZBUFF_compressFlush(ZBUFF_CCtx* zbc, void* dst, size_t* dstCapacityPtr) 137*3117ece4Schristos { 138*3117ece4Schristos size_t result; 139*3117ece4Schristos ZSTD_outBuffer outBuff; 140*3117ece4Schristos outBuff.dst = dst; 141*3117ece4Schristos outBuff.pos = 0; 142*3117ece4Schristos outBuff.size = *dstCapacityPtr; 143*3117ece4Schristos result = ZSTD_flushStream(zbc, &outBuff); 144*3117ece4Schristos *dstCapacityPtr = outBuff.pos; 145*3117ece4Schristos return result; 146*3117ece4Schristos } 147*3117ece4Schristos 148*3117ece4Schristos 149*3117ece4Schristos size_t ZBUFF_compressEnd(ZBUFF_CCtx* zbc, void* dst, size_t* dstCapacityPtr) 150*3117ece4Schristos { 151*3117ece4Schristos size_t result; 152*3117ece4Schristos ZSTD_outBuffer outBuff; 153*3117ece4Schristos outBuff.dst = dst; 154*3117ece4Schristos outBuff.pos = 0; 155*3117ece4Schristos outBuff.size = *dstCapacityPtr; 156*3117ece4Schristos result = ZSTD_endStream(zbc, &outBuff); 157*3117ece4Schristos *dstCapacityPtr = outBuff.pos; 158*3117ece4Schristos return result; 159*3117ece4Schristos } 160*3117ece4Schristos 161*3117ece4Schristos 162*3117ece4Schristos 163*3117ece4Schristos /* ************************************* 164*3117ece4Schristos * Tool functions 165*3117ece4Schristos ***************************************/ 166*3117ece4Schristos size_t ZBUFF_recommendedCInSize(void) { return ZSTD_CStreamInSize(); } 167*3117ece4Schristos size_t ZBUFF_recommendedCOutSize(void) { return ZSTD_CStreamOutSize(); } 168