1*2b9c00cbSConrad Meyer /* 2*2b9c00cbSConrad Meyer * Copyright (c) 2016-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 #include <stdio.h> // printf 12*2b9c00cbSConrad Meyer #include <stdlib.h> // free 13*2b9c00cbSConrad Meyer #include <string.h> // memcpy, strlen 14*2b9c00cbSConrad Meyer #include <zstd.h> // presumes zstd library is installed 15*2b9c00cbSConrad Meyer #include "common.h" // Helper functions, CHECK(), and CHECK_ZSTD() 16*2b9c00cbSConrad Meyer 17*2b9c00cbSConrad Meyer typedef struct { 18*2b9c00cbSConrad Meyer void* fBuffer; 19*2b9c00cbSConrad Meyer void* cBuffer; 20*2b9c00cbSConrad Meyer size_t fBufferSize; 21*2b9c00cbSConrad Meyer size_t cBufferSize; 22*2b9c00cbSConrad Meyer ZSTD_CCtx* cctx; 23*2b9c00cbSConrad Meyer } resources; 24*2b9c00cbSConrad Meyer 25*2b9c00cbSConrad Meyer /* 26*2b9c00cbSConrad Meyer * allocate memory for buffers big enough to compress all files 27*2b9c00cbSConrad Meyer * as well as memory for output file name (ofn) 28*2b9c00cbSConrad Meyer */ 29*2b9c00cbSConrad Meyer static resources createResources_orDie(int argc, const char** argv, char **ofn, size_t* ofnBufferLen) 30*2b9c00cbSConrad Meyer { 31*2b9c00cbSConrad Meyer size_t maxFilenameLength=0; 32*2b9c00cbSConrad Meyer size_t maxFileSize = 0; 33*2b9c00cbSConrad Meyer 34*2b9c00cbSConrad Meyer int argNb; 35*2b9c00cbSConrad Meyer for (argNb = 1; argNb < argc; argNb++) { 36*2b9c00cbSConrad Meyer const char* const filename = argv[argNb]; 37*2b9c00cbSConrad Meyer size_t const filenameLength = strlen(filename); 38*2b9c00cbSConrad Meyer size_t const fileSize = fsize_orDie(filename); 39*2b9c00cbSConrad Meyer 40*2b9c00cbSConrad Meyer if (filenameLength > maxFilenameLength) maxFilenameLength = filenameLength; 41*2b9c00cbSConrad Meyer if (fileSize > maxFileSize) maxFileSize = fileSize; 42*2b9c00cbSConrad Meyer } 43*2b9c00cbSConrad Meyer 44*2b9c00cbSConrad Meyer resources ress; 45*2b9c00cbSConrad Meyer ress.fBufferSize = maxFileSize; 46*2b9c00cbSConrad Meyer ress.cBufferSize = ZSTD_compressBound(maxFileSize); 47*2b9c00cbSConrad Meyer 48*2b9c00cbSConrad Meyer *ofnBufferLen = maxFilenameLength + 5; 49*2b9c00cbSConrad Meyer *ofn = (char*)malloc_orDie(*ofnBufferLen); 50*2b9c00cbSConrad Meyer ress.fBuffer = malloc_orDie(ress.fBufferSize); 51*2b9c00cbSConrad Meyer ress.cBuffer = malloc_orDie(ress.cBufferSize); 52*2b9c00cbSConrad Meyer ress.cctx = ZSTD_createCCtx(); 53*2b9c00cbSConrad Meyer CHECK(ress.cctx != NULL, "ZSTD_createCCtx() failed!"); 54*2b9c00cbSConrad Meyer return ress; 55*2b9c00cbSConrad Meyer } 56*2b9c00cbSConrad Meyer 57*2b9c00cbSConrad Meyer static void freeResources(resources ress, char *outFilename) 58*2b9c00cbSConrad Meyer { 59*2b9c00cbSConrad Meyer free(ress.fBuffer); 60*2b9c00cbSConrad Meyer free(ress.cBuffer); 61*2b9c00cbSConrad Meyer ZSTD_freeCCtx(ress.cctx); /* never fails */ 62*2b9c00cbSConrad Meyer free(outFilename); 63*2b9c00cbSConrad Meyer } 64*2b9c00cbSConrad Meyer 65*2b9c00cbSConrad Meyer /* compress with pre-allocated context (ZSTD_CCtx) and input/output buffers*/ 66*2b9c00cbSConrad Meyer static void compressFile_orDie(resources ress, const char* fname, const char* oname) 67*2b9c00cbSConrad Meyer { 68*2b9c00cbSConrad Meyer size_t fSize = loadFile_orDie(fname, ress.fBuffer, ress.fBufferSize); 69*2b9c00cbSConrad Meyer 70*2b9c00cbSConrad Meyer /* Compress using the context. 71*2b9c00cbSConrad Meyer * If you need more control over parameters, use the advanced API: 72*2b9c00cbSConrad Meyer * ZSTD_CCtx_setParameter(), and ZSTD_compress2(). 73*2b9c00cbSConrad Meyer */ 74*2b9c00cbSConrad Meyer size_t const cSize = ZSTD_compressCCtx(ress.cctx, ress.cBuffer, ress.cBufferSize, ress.fBuffer, fSize, 1); 75*2b9c00cbSConrad Meyer CHECK_ZSTD(cSize); 76*2b9c00cbSConrad Meyer 77*2b9c00cbSConrad Meyer saveFile_orDie(oname, ress.cBuffer, cSize); 78*2b9c00cbSConrad Meyer 79*2b9c00cbSConrad Meyer /* success */ 80*2b9c00cbSConrad Meyer printf("%25s : %6u -> %7u - %s \n", fname, (unsigned)fSize, (unsigned)cSize, oname); 81*2b9c00cbSConrad Meyer } 82*2b9c00cbSConrad Meyer 83*2b9c00cbSConrad Meyer int main(int argc, const char** argv) 84*2b9c00cbSConrad Meyer { 85*2b9c00cbSConrad Meyer const char* const exeName = argv[0]; 86*2b9c00cbSConrad Meyer 87*2b9c00cbSConrad Meyer if (argc<2) { 88*2b9c00cbSConrad Meyer printf("wrong arguments\n"); 89*2b9c00cbSConrad Meyer printf("usage:\n"); 90*2b9c00cbSConrad Meyer printf("%s FILE(s)\n", exeName); 91*2b9c00cbSConrad Meyer return 1; 92*2b9c00cbSConrad Meyer } 93*2b9c00cbSConrad Meyer 94*2b9c00cbSConrad Meyer /* memory allocation for outFilename and resources */ 95*2b9c00cbSConrad Meyer char* outFilename; 96*2b9c00cbSConrad Meyer size_t outFilenameBufferLen; 97*2b9c00cbSConrad Meyer resources const ress = createResources_orDie(argc, argv, &outFilename, &outFilenameBufferLen); 98*2b9c00cbSConrad Meyer 99*2b9c00cbSConrad Meyer /* compress files with shared context, input and output buffers */ 100*2b9c00cbSConrad Meyer int argNb; 101*2b9c00cbSConrad Meyer for (argNb = 1; argNb < argc; argNb++) { 102*2b9c00cbSConrad Meyer const char* const inFilename = argv[argNb]; 103*2b9c00cbSConrad Meyer size_t const inFilenameLen = strlen(inFilename); 104*2b9c00cbSConrad Meyer CHECK(inFilenameLen + 5 <= outFilenameBufferLen, "File name too long!"); 105*2b9c00cbSConrad Meyer memcpy(outFilename, inFilename, inFilenameLen); 106*2b9c00cbSConrad Meyer memcpy(outFilename+inFilenameLen, ".zst", 5); 107*2b9c00cbSConrad Meyer compressFile_orDie(ress, inFilename, outFilename); 108*2b9c00cbSConrad Meyer } 109*2b9c00cbSConrad Meyer 110*2b9c00cbSConrad Meyer /* free memory */ 111*2b9c00cbSConrad Meyer freeResources(ress,outFilename); 112*2b9c00cbSConrad Meyer 113*2b9c00cbSConrad Meyer printf("compressed %i files \n", argc-1); 114*2b9c00cbSConrad Meyer 115*2b9c00cbSConrad Meyer return 0; 116*2b9c00cbSConrad Meyer } 117