1*2b9c00cbSConrad Meyer /* 2*2b9c00cbSConrad Meyer * Copyright (c) 2017-present, Yann Collet, Facebook, Inc. 3*2b9c00cbSConrad Meyer * All rights reserved. 4*2b9c00cbSConrad Meyer * 5*2b9c00cbSConrad Meyer * This source code is licensed under both the BSD-style license (found in the 6*2b9c00cbSConrad Meyer * LICENSE file in the root directory of this source tree) and the GPLv2 (found 7*2b9c00cbSConrad Meyer * in the COPYING file in the root directory of this source tree). 8*2b9c00cbSConrad Meyer * You may select, at your option, one of the above-listed licenses. 9*2b9c00cbSConrad Meyer */ 10*2b9c00cbSConrad Meyer 11*2b9c00cbSConrad Meyer 12*2b9c00cbSConrad Meyer /*=== Tuning parameter ===*/ 13*2b9c00cbSConrad Meyer #ifndef MAX_TESTED_LEVEL 14*2b9c00cbSConrad Meyer #define MAX_TESTED_LEVEL 12 15*2b9c00cbSConrad Meyer #endif 16*2b9c00cbSConrad Meyer 17*2b9c00cbSConrad Meyer 18*2b9c00cbSConrad Meyer /*=== Dependencies ===*/ 19*2b9c00cbSConrad Meyer #include <stdio.h> // printf 20*2b9c00cbSConrad Meyer #define ZSTD_STATIC_LINKING_ONLY 21*2b9c00cbSConrad Meyer #include <zstd.h> // presumes zstd library is installed 22*2b9c00cbSConrad Meyer #include "common.h" // Helper functions, CHECK(), and CHECK_ZSTD() 23*2b9c00cbSConrad Meyer 24*2b9c00cbSConrad Meyer 25*2b9c00cbSConrad Meyer /*=== functions ===*/ 26*2b9c00cbSConrad Meyer 27*2b9c00cbSConrad Meyer /*! readU32FromChar() : 28*2b9c00cbSConrad Meyer @return : unsigned integer value read from input in `char` format 29*2b9c00cbSConrad Meyer allows and interprets K, KB, KiB, M, MB and MiB suffix. 30*2b9c00cbSConrad Meyer Will also modify `*stringPtr`, advancing it to position where it stopped reading. 31*2b9c00cbSConrad Meyer Note : function result can overflow if digit string > MAX_UINT */ 32*2b9c00cbSConrad Meyer static unsigned readU32FromChar(const char** stringPtr) 33*2b9c00cbSConrad Meyer { 34*2b9c00cbSConrad Meyer unsigned result = 0; 35*2b9c00cbSConrad Meyer while ((**stringPtr >='0') && (**stringPtr <='9')) 36*2b9c00cbSConrad Meyer result *= 10, result += **stringPtr - '0', (*stringPtr)++ ; 37*2b9c00cbSConrad Meyer if ((**stringPtr=='K') || (**stringPtr=='M')) { 38*2b9c00cbSConrad Meyer result <<= 10; 39*2b9c00cbSConrad Meyer if (**stringPtr=='M') result <<= 10; 40*2b9c00cbSConrad Meyer (*stringPtr)++ ; 41*2b9c00cbSConrad Meyer if (**stringPtr=='i') (*stringPtr)++; 42*2b9c00cbSConrad Meyer if (**stringPtr=='B') (*stringPtr)++; 43*2b9c00cbSConrad Meyer } 44*2b9c00cbSConrad Meyer return result; 45*2b9c00cbSConrad Meyer } 46*2b9c00cbSConrad Meyer 47*2b9c00cbSConrad Meyer 48*2b9c00cbSConrad Meyer int main(int argc, char const *argv[]) { 49*2b9c00cbSConrad Meyer 50*2b9c00cbSConrad Meyer printf("\n Zstandard (v%s) memory usage for streaming : \n\n", ZSTD_versionString()); 51*2b9c00cbSConrad Meyer 52*2b9c00cbSConrad Meyer unsigned wLog = 0; 53*2b9c00cbSConrad Meyer if (argc > 1) { 54*2b9c00cbSConrad Meyer const char* valStr = argv[1]; 55*2b9c00cbSConrad Meyer wLog = readU32FromChar(&valStr); 56*2b9c00cbSConrad Meyer } 57*2b9c00cbSConrad Meyer 58*2b9c00cbSConrad Meyer int compressionLevel; 59*2b9c00cbSConrad Meyer for (compressionLevel = 1; compressionLevel <= MAX_TESTED_LEVEL; compressionLevel++) { 60*2b9c00cbSConrad Meyer #define INPUT_SIZE 5 61*2b9c00cbSConrad Meyer #define COMPRESSED_SIZE 128 62*2b9c00cbSConrad Meyer char const dataToCompress[INPUT_SIZE] = "abcde"; 63*2b9c00cbSConrad Meyer char compressedData[COMPRESSED_SIZE]; 64*2b9c00cbSConrad Meyer char decompressedData[INPUT_SIZE]; 65*2b9c00cbSConrad Meyer /* the ZSTD_CCtx_params structure is a way to save parameters and use 66*2b9c00cbSConrad Meyer * them across multiple contexts. We use them here so we can call the 67*2b9c00cbSConrad Meyer * function ZSTD_estimateCStreamSize_usingCCtxParams(). 68*2b9c00cbSConrad Meyer */ 69*2b9c00cbSConrad Meyer ZSTD_CCtx_params* const cctxParams = ZSTD_createCCtxParams(); 70*2b9c00cbSConrad Meyer CHECK(cctxParams != NULL, "ZSTD_createCCtxParams() failed!"); 71*2b9c00cbSConrad Meyer 72*2b9c00cbSConrad Meyer /* Set the compression level. */ 73*2b9c00cbSConrad Meyer CHECK_ZSTD( ZSTD_CCtxParams_setParameter(cctxParams, ZSTD_c_compressionLevel, compressionLevel) ); 74*2b9c00cbSConrad Meyer /* Set the window log. 75*2b9c00cbSConrad Meyer * The value 0 means use the default window log, which is equivalent to 76*2b9c00cbSConrad Meyer * not setting it. 77*2b9c00cbSConrad Meyer */ 78*2b9c00cbSConrad Meyer CHECK_ZSTD( ZSTD_CCtxParams_setParameter(cctxParams, ZSTD_c_windowLog, wLog) ); 79*2b9c00cbSConrad Meyer 80*2b9c00cbSConrad Meyer /* Force the compressor to allocate the maximum memory size for a given 81*2b9c00cbSConrad Meyer * level by not providing the pledged source size, or calling 82*2b9c00cbSConrad Meyer * ZSTD_compressStream2() with ZSTD_e_end. 83*2b9c00cbSConrad Meyer */ 84*2b9c00cbSConrad Meyer ZSTD_CCtx* const cctx = ZSTD_createCCtx(); 85*2b9c00cbSConrad Meyer CHECK(cctx != NULL, "ZSTD_createCCtx() failed!"); 86*2b9c00cbSConrad Meyer CHECK_ZSTD( ZSTD_CCtx_setParametersUsingCCtxParams(cctx, cctxParams) ); 87*2b9c00cbSConrad Meyer size_t compressedSize; 88*2b9c00cbSConrad Meyer { 89*2b9c00cbSConrad Meyer ZSTD_inBuffer inBuff = { dataToCompress, sizeof(dataToCompress), 0 }; 90*2b9c00cbSConrad Meyer ZSTD_outBuffer outBuff = { compressedData, sizeof(compressedData), 0 }; 91*2b9c00cbSConrad Meyer CHECK_ZSTD( ZSTD_compressStream(cctx, &outBuff, &inBuff) ); 92*2b9c00cbSConrad Meyer size_t const remaining = ZSTD_endStream(cctx, &outBuff); 93*2b9c00cbSConrad Meyer CHECK_ZSTD(remaining); 94*2b9c00cbSConrad Meyer CHECK(remaining == 0, "Frame not flushed!"); 95*2b9c00cbSConrad Meyer compressedSize = outBuff.pos; 96*2b9c00cbSConrad Meyer } 97*2b9c00cbSConrad Meyer 98*2b9c00cbSConrad Meyer ZSTD_DCtx* const dctx = ZSTD_createDCtx(); 99*2b9c00cbSConrad Meyer CHECK(dctx != NULL, "ZSTD_createDCtx() failed!"); 100*2b9c00cbSConrad Meyer /* Set the maximum allowed window log. 101*2b9c00cbSConrad Meyer * The value 0 means use the default window log, which is equivalent to 102*2b9c00cbSConrad Meyer * not setting it. 103*2b9c00cbSConrad Meyer */ 104*2b9c00cbSConrad Meyer CHECK_ZSTD( ZSTD_DCtx_setParameter(dctx, ZSTD_d_windowLogMax, wLog) ); 105*2b9c00cbSConrad Meyer /* forces decompressor to use maximum memory size, since the 106*2b9c00cbSConrad Meyer * decompressed size is not stored in the frame header. 107*2b9c00cbSConrad Meyer */ 108*2b9c00cbSConrad Meyer { ZSTD_inBuffer inBuff = { compressedData, compressedSize, 0 }; 109*2b9c00cbSConrad Meyer ZSTD_outBuffer outBuff = { decompressedData, sizeof(decompressedData), 0 }; 110*2b9c00cbSConrad Meyer size_t const remaining = ZSTD_decompressStream(dctx, &outBuff, &inBuff); 111*2b9c00cbSConrad Meyer CHECK_ZSTD(remaining); 112*2b9c00cbSConrad Meyer CHECK(remaining == 0, "Frame not complete!"); 113*2b9c00cbSConrad Meyer CHECK(outBuff.pos == sizeof(dataToCompress), "Bad decompression!"); 114*2b9c00cbSConrad Meyer } 115*2b9c00cbSConrad Meyer 116*2b9c00cbSConrad Meyer size_t const cstreamSize = ZSTD_sizeof_CStream(cctx); 117*2b9c00cbSConrad Meyer size_t const cstreamEstimatedSize = ZSTD_estimateCStreamSize_usingCCtxParams(cctxParams); 118*2b9c00cbSConrad Meyer size_t const dstreamSize = ZSTD_sizeof_DStream(dctx); 119*2b9c00cbSConrad Meyer size_t const dstreamEstimatedSize = ZSTD_estimateDStreamSize_fromFrame(compressedData, compressedSize); 120*2b9c00cbSConrad Meyer 121*2b9c00cbSConrad Meyer CHECK(cstreamSize <= cstreamEstimatedSize, "Compression mem (%u) > estimated (%u)", 122*2b9c00cbSConrad Meyer (unsigned)cstreamSize, (unsigned)cstreamEstimatedSize); 123*2b9c00cbSConrad Meyer CHECK(dstreamSize <= dstreamEstimatedSize, "Decompression mem (%u) > estimated (%u)", 124*2b9c00cbSConrad Meyer (unsigned)dstreamSize, (unsigned)dstreamEstimatedSize); 125*2b9c00cbSConrad Meyer 126*2b9c00cbSConrad Meyer printf("Level %2i : Compression Mem = %5u KB (estimated : %5u KB) ; Decompression Mem = %4u KB (estimated : %5u KB)\n", 127*2b9c00cbSConrad Meyer compressionLevel, 128*2b9c00cbSConrad Meyer (unsigned)(cstreamSize>>10), (unsigned)(cstreamEstimatedSize>>10), 129*2b9c00cbSConrad Meyer (unsigned)(dstreamSize>>10), (unsigned)(dstreamEstimatedSize>>10)); 130*2b9c00cbSConrad Meyer 131*2b9c00cbSConrad Meyer ZSTD_freeDCtx(dctx); 132*2b9c00cbSConrad Meyer ZSTD_freeCCtx(cctx); 133*2b9c00cbSConrad Meyer ZSTD_freeCCtxParams(cctxParams); 134*2b9c00cbSConrad Meyer if (wLog) break; /* single test */ 135*2b9c00cbSConrad Meyer } 136*2b9c00cbSConrad Meyer return 0; 137*2b9c00cbSConrad Meyer } 138