1 /* 2 * Copyright (c) 2016-2020, Yann Collet, Facebook, Inc. 3 * All rights reserved. 4 * 5 * This source code is licensed under both the BSD-style license (found in the 6 * LICENSE file in the root directory of this source tree) and the GPLv2 (found 7 * in the COPYING file in the root directory of this source tree). 8 * You may select, at your option, one of the above-listed licenses. 9 */ 10 11 #include <stdio.h> // printf 12 #include <stdlib.h> // free 13 #include <zstd.h> // presumes zstd library is installed 14 #include "common.h" // Helper functions, CHECK(), and CHECK_ZSTD() 15 16 static void decompress(const char* fname) 17 { 18 size_t cSize; 19 void* const cBuff = mallocAndLoadFile_orDie(fname, &cSize); 20 /* Read the content size from the frame header. For simplicity we require 21 * that it is always present. By default, zstd will write the content size 22 * in the header when it is known. If you can't guarantee that the frame 23 * content size is always written into the header, either use streaming 24 * decompression, or ZSTD_decompressBound(). 25 */ 26 unsigned long long const rSize = ZSTD_getFrameContentSize(cBuff, cSize); 27 CHECK(rSize != ZSTD_CONTENTSIZE_ERROR, "%s: not compressed by zstd!", fname); 28 CHECK(rSize != ZSTD_CONTENTSIZE_UNKNOWN, "%s: original size unknown!", fname); 29 30 void* const rBuff = malloc_orDie((size_t)rSize); 31 32 /* Decompress. 33 * If you are doing many decompressions, you may want to reuse the context 34 * and use ZSTD_decompressDCtx(). If you want to set advanced parameters, 35 * use ZSTD_DCtx_setParameter(). 36 */ 37 size_t const dSize = ZSTD_decompress(rBuff, rSize, cBuff, cSize); 38 CHECK_ZSTD(dSize); 39 /* When zstd knows the content size, it will error if it doesn't match. */ 40 CHECK(dSize == rSize, "Impossible because zstd will check this condition!"); 41 42 /* success */ 43 printf("%25s : %6u -> %7u \n", fname, (unsigned)cSize, (unsigned)rSize); 44 45 free(rBuff); 46 free(cBuff); 47 } 48 49 int main(int argc, const char** argv) 50 { 51 const char* const exeName = argv[0]; 52 53 if (argc!=2) { 54 printf("wrong arguments\n"); 55 printf("usage:\n"); 56 printf("%s FILE\n", exeName); 57 return 1; 58 } 59 60 decompress(argv[1]); 61 62 printf("%s correctly decoded (in memory). \n", argv[1]); 63 64 return 0; 65 } 66