123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- /*
- * Copyright (c) Yann Collet, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed under both the BSD-style license (found in the
- * LICENSE file in the root directory of this source tree) and the GPLv2 (found
- * in the COPYING file in the root directory of this source tree).
- * You may select, at your option, one of the above-listed licenses.
- */
- /* The objective of this example is to show of to compress multiple successive files
- * while preserving memory management.
- * All structures and buffers will be created only once,
- * and shared across all compression operations */
- #include <stdio.h> // printf
- #include <stdlib.h> // free
- #include <string.h> // memset, strcat
- #include <zstd.h> // presumes zstd library is installed
- #include "common.h" // Helper functions, CHECK(), and CHECK_ZSTD()
- typedef struct {
- void* buffIn;
- void* buffOut;
- size_t buffInSize;
- size_t buffOutSize;
- ZSTD_CCtx* cctx;
- } resources;
- static resources createResources_orDie(int cLevel)
- {
- resources ress;
- ress.buffInSize = ZSTD_CStreamInSize(); /* can always read one full block */
- ress.buffOutSize= ZSTD_CStreamOutSize(); /* can always flush a full block */
- ress.buffIn = malloc_orDie(ress.buffInSize);
- ress.buffOut= malloc_orDie(ress.buffOutSize);
- ress.cctx = ZSTD_createCCtx();
- CHECK(ress.cctx != NULL, "ZSTD_createCCtx() failed!");
- /* Set any compression parameters you want here.
- * They will persist for every compression operation.
- * Here we set the compression level, and enable the checksum.
- */
- CHECK_ZSTD( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_c_compressionLevel, cLevel) );
- CHECK_ZSTD( ZSTD_CCtx_setParameter(ress.cctx, ZSTD_c_checksumFlag, 1) );
- return ress;
- }
- static void freeResources(resources ress)
- {
- ZSTD_freeCCtx(ress.cctx);
- free(ress.buffIn);
- free(ress.buffOut);
- }
- static void compressFile_orDie(resources ress, const char* fname, const char* outName)
- {
- // Open the input and output files.
- FILE* const fin = fopen_orDie(fname, "rb");
- FILE* const fout = fopen_orDie(outName, "wb");
- /* Reset the context to a clean state to start a new compression operation.
- * The parameters are sticky, so we keep the compression level and extra
- * parameters that we set in createResources_orDie().
- */
- CHECK_ZSTD( ZSTD_CCtx_reset(ress.cctx, ZSTD_reset_session_only) );
- size_t const toRead = ress.buffInSize;
- size_t read;
- while ( (read = fread_orDie(ress.buffIn, toRead, fin)) ) {
- /* This loop is the same as streaming_compression.c.
- * See that file for detailed comments.
- */
- int const lastChunk = (read < toRead);
- ZSTD_EndDirective const mode = lastChunk ? ZSTD_e_end : ZSTD_e_continue;
- ZSTD_inBuffer input = { ress.buffIn, read, 0 };
- int finished;
- do {
- ZSTD_outBuffer output = { ress.buffOut, ress.buffOutSize, 0 };
- size_t const remaining = ZSTD_compressStream2(ress.cctx, &output, &input, mode);
- CHECK_ZSTD(remaining);
- fwrite_orDie(ress.buffOut, output.pos, fout);
- finished = lastChunk ? (remaining == 0) : (input.pos == input.size);
- } while (!finished);
- CHECK(input.pos == input.size,
- "Impossible: zstd only returns 0 when the input is completely consumed!");
- }
- fclose_orDie(fout);
- fclose_orDie(fin);
- }
- int main(int argc, const char** argv)
- {
- const char* const exeName = argv[0];
- if (argc<2) {
- printf("wrong arguments\n");
- printf("usage:\n");
- printf("%s FILE(s)\n", exeName);
- return 1;
- }
- int const cLevel = 7;
- resources const ress = createResources_orDie(cLevel);
- void* ofnBuffer = NULL;
- size_t ofnbSize = 0;
- int argNb;
- for (argNb = 1; argNb < argc; argNb++) {
- const char* const ifn = argv[argNb];
- size_t const ifnSize = strlen(ifn);
- size_t const ofnSize = ifnSize + 5;
- if (ofnbSize <= ofnSize) {
- ofnbSize = ofnSize + 16;
- free(ofnBuffer);
- ofnBuffer = malloc_orDie(ofnbSize);
- }
- memset(ofnBuffer, 0, ofnSize);
- strcat(ofnBuffer, ifn);
- strcat(ofnBuffer, ".zst");
- compressFile_orDie(ress, ifn, ofnBuffer);
- }
- freeResources(ress);
- free(ofnBuffer);
- printf("compressed %i files \n", argc-1);
- return 0;
- }
|