em_inflate.c

Fast, small, in-memory inflate (zlib, deflate and gzip decompression)
git clone git://git.finwo.net/lib/em_inflate.c
Log | Files | Refs | README | LICENSE

main.c (3049B)


      1 /*
      2  * main.c - example of using em_inflate to decompress a gzip file
      3  *
      4  * Copyright (C) 2019 Emmanuel Marty
      5  *
      6  * This software is provided 'as-is', without any express or implied
      7  * warranty.  In no event will the authors be held liable for any damages
      8  * arising from the use of this software.
      9  *
     10  * Permission is granted to anyone to use this software for any purpose,
     11  * including commercial applications, and to alter it and redistribute it
     12  * freely, subject to the following restrictions:
     13  *
     14  * 1. The origin of this software must not be misrepresented; you must not
     15  *    claim that you wrote the original software. If you use this software
     16  *    in a product, an acknowledgment in the product documentation would be
     17  *    appreciated but is not required.
     18  * 2. Altered source versions must be plainly marked as such, and must not be
     19  *    misrepresented as being the original software.
     20  * 3. This notice may not be removed or altered from any source distribution.
     21  */
     22 
     23 #include <stdio.h>
     24 #include <stdlib.h>
     25 #include <string.h>
     26 #include <memory.h>
     27 
     28 #include "tidwall/buf.h"
     29 
     30 #include "em_inflate.h"
     31 
     32 int main(int argc, char **argv) {
     33    unsigned char *pCompressedData;
     34    size_t nCompressedDataSize;
     35    FILE *f;
     36 
     37    if (argc != 3) {
     38       fprintf(stderr, "usage: %s [infile.gz] [outfile]\n", argv[0]);
     39       return 100;
     40    }
     41 
     42    /* Load compressed file in memory all at once */
     43 
     44    f = fopen(argv[1], "rb");
     45    if (!f) {
     46       fprintf(stderr, "error opening '%s' for reading\n", argv[1]);
     47       return 100;
     48    }
     49 
     50    fseek(f, 0, SEEK_END);
     51    nCompressedDataSize = (size_t)ftell(f);
     52    fseek(f, 0, SEEK_SET);
     53 
     54    pCompressedData = (unsigned char*)malloc(nCompressedDataSize);
     55    if (!pCompressedData) {
     56       fclose(f);
     57       fprintf(stderr, "out of memory, %zu bytes needed\n", nCompressedDataSize);
     58       return 100;
     59    }
     60 
     61    memset(pCompressedData, 0, nCompressedDataSize);
     62    if (fread(pCompressedData, 1, nCompressedDataSize, f) != nCompressedDataSize) {
     63       free(pCompressedData);
     64       fclose(f);
     65       fprintf(stderr, "I/O error reading '%s'\n", argv[1]);
     66       return 100;
     67    }
     68 
     69    fclose(f);
     70    f = NULL;
     71 
     72    /* Decompress */
     73 
     74    struct buf *inflated = em_inflate(&(struct buf){
     75       .data = (void*)pCompressedData,
     76       .len  = nCompressedDataSize,
     77    });
     78 
     79    if (!inflated) {
     80       fprintf(stderr, "Error inflating data\n");
     81       return 100;
     82    }
     83 
     84    fprintf(stdout, "decompressed %zu bytes\n", inflated->len);
     85 
     86    /* Write decompressed file out all at once */
     87 
     88    f = fopen(argv[2], "wb");
     89    if (!f) {
     90       buf_clear(inflated);
     91       free(inflated);
     92       free(pCompressedData);
     93       fprintf(stderr, "error opening '%s' for writing\n", argv[1]);
     94       return 100;
     95    }
     96 
     97    if (fwrite(inflated->data, 1, inflated->len, f) != inflated->len) {
     98       fclose(f);
     99       buf_clear(inflated);
    100       free(inflated);
    101       free(pCompressedData);
    102       fprintf(stderr, "I/O error writing '%s'\n", argv[1]);
    103       return 100;
    104    }
    105 
    106    fclose(f);
    107    buf_clear(inflated);
    108    free(inflated);
    109    free(pCompressedData);
    110 
    111    return 0;
    112 }