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 #include <stdio.h> // printf 12*3117ece4Schristos #include <stdlib.h> // free 13*3117ece4Schristos #include <zstd.h> // presumes zstd library is installed 14*3117ece4Schristos #include "common.h" // Helper functions, CHECK(), and CHECK_ZSTD() 15*3117ece4Schristos 16*3117ece4Schristos static void decompress(const char* fname) 17*3117ece4Schristos { 18*3117ece4Schristos size_t cSize; 19*3117ece4Schristos void* const cBuff = mallocAndLoadFile_orDie(fname, &cSize); 20*3117ece4Schristos /* Read the content size from the frame header. For simplicity we require 21*3117ece4Schristos * that it is always present. By default, zstd will write the content size 22*3117ece4Schristos * in the header when it is known. If you can't guarantee that the frame 23*3117ece4Schristos * content size is always written into the header, either use streaming 24*3117ece4Schristos * decompression, or ZSTD_decompressBound(). 25*3117ece4Schristos */ 26*3117ece4Schristos unsigned long long const rSize = ZSTD_getFrameContentSize(cBuff, cSize); 27*3117ece4Schristos CHECK(rSize != ZSTD_CONTENTSIZE_ERROR, "%s: not compressed by zstd!", fname); 28*3117ece4Schristos CHECK(rSize != ZSTD_CONTENTSIZE_UNKNOWN, "%s: original size unknown!", fname); 29*3117ece4Schristos 30*3117ece4Schristos void* const rBuff = malloc_orDie((size_t)rSize); 31*3117ece4Schristos 32*3117ece4Schristos /* Decompress. 33*3117ece4Schristos * If you are doing many decompressions, you may want to reuse the context 34*3117ece4Schristos * and use ZSTD_decompressDCtx(). If you want to set advanced parameters, 35*3117ece4Schristos * use ZSTD_DCtx_setParameter(). 36*3117ece4Schristos */ 37*3117ece4Schristos size_t const dSize = ZSTD_decompress(rBuff, rSize, cBuff, cSize); 38*3117ece4Schristos CHECK_ZSTD(dSize); 39*3117ece4Schristos /* When zstd knows the content size, it will error if it doesn't match. */ 40*3117ece4Schristos CHECK(dSize == rSize, "Impossible because zstd will check this condition!"); 41*3117ece4Schristos 42*3117ece4Schristos /* success */ 43*3117ece4Schristos printf("%25s : %6u -> %7u \n", fname, (unsigned)cSize, (unsigned)rSize); 44*3117ece4Schristos 45*3117ece4Schristos free(rBuff); 46*3117ece4Schristos free(cBuff); 47*3117ece4Schristos } 48*3117ece4Schristos 49*3117ece4Schristos int main(int argc, const char** argv) 50*3117ece4Schristos { 51*3117ece4Schristos const char* const exeName = argv[0]; 52*3117ece4Schristos 53*3117ece4Schristos if (argc!=2) { 54*3117ece4Schristos printf("wrong arguments\n"); 55*3117ece4Schristos printf("usage:\n"); 56*3117ece4Schristos printf("%s FILE\n", exeName); 57*3117ece4Schristos return 1; 58*3117ece4Schristos } 59*3117ece4Schristos 60*3117ece4Schristos decompress(argv[1]); 61*3117ece4Schristos 62*3117ece4Schristos printf("%s correctly decoded (in memory). \n", argv[1]); 63*3117ece4Schristos 64*3117ece4Schristos return 0; 65*3117ece4Schristos } 66