From 417b4381dda4b88a1e382f821c8964cf8954307e Mon Sep 17 00:00:00 2001 From: David Monniaux Date: Tue, 29 Jan 2019 22:31:50 +0100 Subject: https://github.com/pfalcon/uzlib --- test/monniaux/uzlib/examples/tgunzip/tgunzip.c | 167 +++++++++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 test/monniaux/uzlib/examples/tgunzip/tgunzip.c (limited to 'test/monniaux/uzlib/examples/tgunzip/tgunzip.c') diff --git a/test/monniaux/uzlib/examples/tgunzip/tgunzip.c b/test/monniaux/uzlib/examples/tgunzip/tgunzip.c new file mode 100644 index 00000000..dcf15eca --- /dev/null +++ b/test/monniaux/uzlib/examples/tgunzip/tgunzip.c @@ -0,0 +1,167 @@ +/* + * tgunzip - gzip decompressor example + * + * Copyright (c) 2003 by Joergen Ibsen / Jibz + * All Rights Reserved + * + * http://www.ibsensoftware.com/ + * + * Copyright (c) 2014-2016 by Paul Sokolovsky + * + * This software is provided 'as-is', without any express + * or implied warranty. In no event will the authors be + * held liable for any damages arising from the use of + * this software. + * + * Permission is granted to anyone to use this software + * for any purpose, including commercial applications, + * and to alter it and redistribute it freely, subject to + * the following restrictions: + * + * 1. The origin of this software must not be + * misrepresented; you must not claim that you + * wrote the original software. If you use this + * software in a product, an acknowledgment in + * the product documentation would be appreciated + * but is not required. + * + * 2. Altered source versions must be plainly marked + * as such, and must not be misrepresented as + * being the original software. + * + * 3. This notice may not be removed or altered from + * any source distribution. + */ + +#include +#include + +#include "uzlib.h" + +/* produce decompressed output in chunks of this size */ +/* defauly is to decompress byte by byte; can be any other length */ +#define OUT_CHUNK_SIZE 1 + +void exit_error(const char *what) +{ + printf("ERROR: %s\n", what); + exit(1); +} + +int main(int argc, char *argv[]) +{ + FILE *fin, *fout; + unsigned int len, dlen, outlen; + const unsigned char *source; + unsigned char *dest; + int res; + + printf("tgunzip - example from the tiny inflate library (www.ibsensoftware.com)\n\n"); + + if (argc < 3) + { + printf( + "Syntax: tgunzip \n\n" + "Both input and output are kept in memory, so do not use this on huge files.\n"); + + return 1; + } + + uzlib_init(); + + /* -- open files -- */ + + if ((fin = fopen(argv[1], "rb")) == NULL) exit_error("source file"); + + if ((fout = fopen(argv[2], "wb")) == NULL) exit_error("destination file"); + + /* -- read source -- */ + + fseek(fin, 0, SEEK_END); + + len = ftell(fin); + + fseek(fin, 0, SEEK_SET); + + source = (unsigned char *)malloc(len); + + if (source == NULL) exit_error("memory"); + + if (fread((unsigned char*)source, 1, len, fin) != len) exit_error("read"); + + fclose(fin); + + if (len < 4) exit_error("file too small"); + + /* -- get decompressed length -- */ + + dlen = source[len - 1]; + dlen = 256*dlen + source[len - 2]; + dlen = 256*dlen + source[len - 3]; + dlen = 256*dlen + source[len - 4]; + + outlen = dlen; + + /* there can be mismatch between length in the trailer and actual + data stream; to avoid buffer overruns on overlong streams, reserve + one extra byte */ + dlen++; + + dest = (unsigned char *)malloc(dlen); + + if (dest == NULL) exit_error("memory"); + + /* -- decompress data -- */ + + struct uzlib_uncomp d; +// uzlib_uncompress_init(&d, malloc(32768), 32768); + uzlib_uncompress_init(&d, NULL, 0); + + /* all 3 fields below must be initialized by user */ + d.source = source; + d.source_limit = source + len - 4; + d.source_read_cb = NULL; + + res = uzlib_gzip_parse_header(&d); + if (res != TINF_OK) { + printf("Error parsing header: %d\n", res); + exit(1); + } + + d.dest_start = d.dest = dest; + + while (dlen) { + unsigned int chunk_len = dlen < OUT_CHUNK_SIZE ? dlen : OUT_CHUNK_SIZE; + d.dest_limit = d.dest + chunk_len; + res = uzlib_uncompress_chksum(&d); + dlen -= chunk_len; + if (res != TINF_OK) { + break; + } + } + + if (res != TINF_DONE) { + printf("Error during decompression: %d\n", res); + exit(-res); + } + + printf("decompressed %lu bytes\n", d.dest - dest); + +#if 0 + if (d.dest - dest != gz.dlen) { + printf("Invalid decompressed length: %lu vs %u\n", d.dest - dest, gz.dlen); + } + + if (tinf_crc32(dest, gz.dlen) != gz.crc32) { + printf("Invalid decompressed crc32\n"); + } +#endif + + /* -- write output -- */ + + fwrite(dest, 1, outlen, fout); + + fclose(fout); + + return 0; +} -- cgit