diff options
Diffstat (limited to 'lzo/examples/lzopack.c')
-rw-r--r-- | lzo/examples/lzopack.c | 645 |
1 files changed, 0 insertions, 645 deletions
diff --git a/lzo/examples/lzopack.c b/lzo/examples/lzopack.c deleted file mode 100644 index e4e745df..00000000 --- a/lzo/examples/lzopack.c +++ /dev/null @@ -1,645 +0,0 @@ -/* lzopack.c -- LZO example program: a simple file packer - - This file is part of the LZO real-time data compression library. - - Copyright (C) 2011 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 2010 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 2009 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 2005 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 2004 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 2003 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer - Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer - All Rights Reserved. - - The LZO library is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of - the License, or (at your option) any later version. - - The LZO library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with the LZO library; see the file COPYING. - If not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - - Markus F.X.J. Oberhumer - <markus@oberhumer.com> - http://www.oberhumer.com/opensource/lzo/ - */ - - -/************************************************************************* -// NOTE: this is an example program, so do not use to backup your data. -// -// This program lacks things like sophisticated file handling but is -// pretty complete regarding compression - it should provide a good -// starting point for adaption for your applications. -// -// Please study LZO.FAQ and simple.c first. -**************************************************************************/ - -#include "lzo/lzoconf.h" -#include "lzo/lzo1x.h" - -/* portability layer */ -static const char *progname = NULL; -#define WANT_LZO_MALLOC 1 -#define WANT_LZO_FREAD 1 -#define WANT_LZO_WILDARGV 1 -#define WANT_XMALLOC 1 -#include "examples/portab.h" - - -static unsigned long total_in = 0; -static unsigned long total_out = 0; -static lzo_bool opt_debug = 0; - -/* magic file header for lzopack-compressed files */ -static const unsigned char magic[7] = - { 0x00, 0xe9, 0x4c, 0x5a, 0x4f, 0xff, 0x1a }; - - -/************************************************************************* -// file IO -**************************************************************************/ - -lzo_uint xread(FILE *fp, lzo_voidp buf, lzo_uint len, lzo_bool allow_eof) -{ - lzo_uint l; - - l = (lzo_uint) lzo_fread(fp, buf, len); - if (l > len) - { - fprintf(stderr, "\nsomething's wrong with your C library !!!\n"); - exit(1); - } - if (l != len && !allow_eof) - { - fprintf(stderr, "\nread error - premature end of file\n"); - exit(1); - } - total_in += (unsigned long) l; - return l; -} - -lzo_uint xwrite(FILE *fp, const lzo_voidp buf, lzo_uint len) -{ - if (fp != NULL && lzo_fwrite(fp, buf, len) != len) - { - fprintf(stderr, "\nwrite error (disk full ?)\n"); - exit(1); - } - total_out += (unsigned long) len; - return len; -} - - -int xgetc(FILE *fp) -{ - unsigned char c; - xread(fp, (lzo_voidp) &c, 1, 0); - return c; -} - -void xputc(FILE *fp, int c) -{ - unsigned char cc = (unsigned char) (c & 0xff); - xwrite(fp, (const lzo_voidp) &cc, 1); -} - -/* read and write portable 32-bit integers */ - -lzo_uint32 xread32(FILE *fp) -{ - unsigned char b[4]; - lzo_uint32 v; - - xread(fp, b, 4, 0); - v = (lzo_uint32) b[3] << 0; - v |= (lzo_uint32) b[2] << 8; - v |= (lzo_uint32) b[1] << 16; - v |= (lzo_uint32) b[0] << 24; - return v; -} - -void xwrite32(FILE *fp, lzo_xint v) -{ - unsigned char b[4]; - - b[3] = (unsigned char) ((v >> 0) & 0xff); - b[2] = (unsigned char) ((v >> 8) & 0xff); - b[1] = (unsigned char) ((v >> 16) & 0xff); - b[0] = (unsigned char) ((v >> 24) & 0xff); - xwrite(fp, b, 4); -} - - -/************************************************************************* -// compress -// -// possible improvement: we could use overlapping compression to -// save some memory - see overlap.c. This would require some minor -// changes in the decompression code as well, because if a block -// turns out to be incompressible we would still have to store it in its -// "compressed" (i.e. then slightly enlarged) form because the original -// (uncompressed) data would have been lost during the overlapping -// compression. -**************************************************************************/ - -int do_compress(FILE *fi, FILE *fo, int compression_level, lzo_uint block_size) -{ - int r = 0; - lzo_bytep in = NULL; - lzo_bytep out = NULL; - lzo_voidp wrkmem = NULL; - lzo_uint in_len; - lzo_uint out_len; - lzo_uint32 wrk_len = 0; - lzo_uint32 flags = 1; /* do compute a checksum */ - int method = 1; /* compression method: LZO1X */ - lzo_uint32 checksum; - - total_in = total_out = 0; - -/* - * Step 1: write magic header, flags & block size, init checksum - */ - xwrite(fo, magic, sizeof(magic)); - xwrite32(fo, flags); - xputc(fo, method); /* compression method */ - xputc(fo, compression_level); /* compression level */ - xwrite32(fo, block_size); - checksum = lzo_adler32(0, NULL, 0); - -/* - * Step 2: allocate compression buffers and work-memory - */ - in = (lzo_bytep) xmalloc(block_size); - out = (lzo_bytep) xmalloc(block_size + block_size / 16 + 64 + 3); - if (compression_level == 9) - wrk_len = LZO1X_999_MEM_COMPRESS; - else - wrk_len = LZO1X_1_MEM_COMPRESS; - wrkmem = (lzo_voidp) xmalloc(wrk_len); - if (in == NULL || out == NULL || wrkmem == NULL) - { - printf("%s: out of memory\n", progname); - r = 1; - goto err; - } - -/* - * Step 3: process blocks - */ - for (;;) - { - /* read block */ - in_len = xread(fi, in, block_size, 1); - if (in_len == 0) - break; - - /* update checksum */ - if (flags & 1) - checksum = lzo_adler32(checksum, in, in_len); - - /* clear wrkmem (not needed, only for debug/benchmark purposes) */ - if (opt_debug) - lzo_memset(wrkmem, 0xff, wrk_len); - - /* compress block */ - if (compression_level == 9) - r = lzo1x_999_compress(in, in_len, out, &out_len, wrkmem); - else - r = lzo1x_1_compress(in, in_len, out, &out_len, wrkmem); - if (r != LZO_E_OK || out_len > in_len + in_len / 16 + 64 + 3) - { - /* this should NEVER happen */ - printf("internal error - compression failed: %d\n", r); - r = 2; - goto err; - } - - /* write uncompressed block size */ - xwrite32(fo, in_len); - - if (out_len < in_len) - { - /* write compressed block */ - xwrite32(fo, out_len); - xwrite(fo, out, out_len); - } - else - { - /* not compressible - write uncompressed block */ - xwrite32(fo, in_len); - xwrite(fo, in, in_len); - } - } - - /* write EOF marker */ - xwrite32(fo, 0); - - /* write checksum */ - if (flags & 1) - xwrite32(fo, checksum); - - r = 0; -err: - lzo_free(wrkmem); - lzo_free(out); - lzo_free(in); - return r; -} - - -/************************************************************************* -// decompress / test -// -// We are using overlapping (in-place) decompression to save some -// memory - see overlap.c. -**************************************************************************/ - -int do_decompress(FILE *fi, FILE *fo) -{ - int r = 0; - lzo_bytep buf = NULL; - lzo_uint buf_len; - unsigned char m [ sizeof(magic) ]; - lzo_uint32 flags; - int method; - int compression_level; - lzo_uint block_size; - lzo_uint32 checksum; - - total_in = total_out = 0; - -/* - * Step 1: check magic header, read flags & block size, init checksum - */ - if (xread(fi, m, sizeof(magic),1) != sizeof(magic) || - memcmp(m, magic, sizeof(magic)) != 0) - { - printf("%s: header error - this file is not compressed by lzopack\n", progname); - r = 1; - goto err; - } - flags = xread32(fi); - method = xgetc(fi); - compression_level = xgetc(fi); - if (method != 1) - { - printf("%s: header error - invalid method %d (level %d)\n", - progname, method, compression_level); - r = 2; - goto err; - } - block_size = xread32(fi); - if (block_size < 1024 || block_size > 8*1024*1024L) - { - printf("%s: header error - invalid block size %ld\n", - progname, (long) block_size); - r = 3; - goto err; - } - checksum = lzo_adler32(0,NULL,0); - -/* - * Step 2: allocate buffer for in-place decompression - */ - buf_len = block_size + block_size / 16 + 64 + 3; - buf = (lzo_bytep) xmalloc(buf_len); - if (buf == NULL) - { - printf("%s: out of memory\n", progname); - r = 4; - goto err; - } - -/* - * Step 3: process blocks - */ - for (;;) - { - lzo_bytep in; - lzo_bytep out; - lzo_uint in_len; - lzo_uint out_len; - - /* read uncompressed size */ - out_len = xread32(fi); - - /* exit if last block (EOF marker) */ - if (out_len == 0) - break; - - /* read compressed size */ - in_len = xread32(fi); - - /* sanity check of the size values */ - if (in_len > block_size || out_len > block_size || - in_len == 0 || in_len > out_len) - { - printf("%s: block size error - data corrupted\n", progname); - r = 5; - goto err; - } - - /* place compressed block at the top of the buffer */ - in = buf + buf_len - in_len; - out = buf; - - /* read compressed block data */ - xread(fi, in, in_len, 0); - - if (in_len < out_len) - { - /* decompress - use safe decompressor as data might be corrupted - * during a file transfer */ - lzo_uint new_len = out_len; - - r = lzo1x_decompress_safe(in, in_len, out, &new_len, NULL); - if (r != LZO_E_OK || new_len != out_len) - { - printf("%s: compressed data violation\n", progname); - r = 6; - goto err; - } - /* write decompressed block */ - xwrite(fo, out, out_len); - /* update checksum */ - if (flags & 1) - checksum = lzo_adler32(checksum, out, out_len); - } - else - { - /* write original (incompressible) block */ - xwrite(fo, in, in_len); - /* update checksum */ - if (flags & 1) - checksum = lzo_adler32(checksum, in, in_len); - } - } - - /* read and verify checksum */ - if (flags & 1) - { - lzo_uint32 c = xread32(fi); - if (c != checksum) - { - printf("%s: checksum error - data corrupted\n", progname); - r = 7; - goto err; - } - } - - r = 0; -err: - lzo_free(buf); - return r; -} - - -/************************************************************************* -// -**************************************************************************/ - -static void usage(void) -{ - printf("usage: %s [-9] input-file output-file (compress)\n", progname); - printf("usage: %s -d input-file output-file (decompress)\n", progname); - printf("usage: %s -t input-file... (test)\n", progname); - exit(1); -} - - -/* open input file */ -static FILE *xopen_fi(const char *name) -{ - FILE *fp; - - fp = fopen(name, "rb"); - if (fp == NULL) - { - printf("%s: cannot open input file %s\n", progname, name); - exit(1); - } -#if defined(HAVE_STAT) && defined(S_ISREG) - { - struct stat st; - int is_regular = 1; - if (stat(name, &st) != 0 || !S_ISREG(st.st_mode)) - is_regular = 0; - if (!is_regular) - { - printf("%s: %s is not a regular file\n", progname, name); - fclose(fp); fp = NULL; - exit(1); - } - } -#endif - return fp; -} - - -/* open output file */ -static FILE *xopen_fo(const char *name) -{ - FILE *fp; - -#if 0 - /* this is an example program, so make sure we don't overwrite a file */ - fp = fopen(name, "rb"); - if (fp != NULL) - { - printf("%s: file %s already exists -- not overwritten\n", progname, name); - fclose(fp); fp = NULL; - exit(1); - } -#endif - fp = fopen(name, "wb"); - if (fp == NULL) - { - printf("%s: cannot open output file %s\n", progname, name); - exit(1); - } - return fp; -} - - -/* close file */ -static void xclose(FILE *fp) -{ - if (fp) - { - int err; - err = ferror(fp); - if (fclose(fp) != 0) - err = 1; - if (err) - { - printf("%s: error while closing file\n", progname); - exit(1); - } - } -} - - -/************************************************************************* -// -**************************************************************************/ - -int __lzo_cdecl_main main(int argc, char *argv[]) -{ - int i = 1; - int r = 0; - FILE *fi = NULL; - FILE *fo = NULL; - const char *in_name = NULL; - const char *out_name = NULL; - unsigned opt_decompress = 0; - unsigned opt_test = 0; - int opt_compression_level = 1; - lzo_uint opt_block_size; - const char *s; - - lzo_wildargv(&argc, &argv); - - progname = argv[0]; - for (s = progname; *s; s++) - if ((*s == '/' || *s == '\\') && s[1]) - progname = s + 1; - - printf("\nLZO real-time data compression library (v%s, %s).\n", - lzo_version_string(), lzo_version_date()); - printf("Copyright (C) 1996-2011 Markus Franz Xaver Johannes Oberhumer\nAll Rights Reserved.\n\n"); - -#if 0 - printf( -"*** DISCLAIMER ***\n" -" This is an example program, do not use to backup your data !\n" -" Get LZOP if you're interested into a full-featured packer.\n" -" See http://www.oberhumer.com/opensource/lzop/\n" -"\n"); -#endif - - -/* - * Step 1: initialize the LZO library - */ - if (lzo_init() != LZO_E_OK) - { - printf("internal error - lzo_init() failed !!!\n"); - printf("(this usually indicates a compiler bug - try recompiling\nwithout optimizations, and enable '-DLZO_DEBUG' for diagnostics)\n"); - exit(1); - } - - -/* - * Step 2: setup memory - */ - opt_block_size = 256 * 1024L; - -#if defined(ACC_MM_AHSHIFT) - /* reduce memory requirements for ancient 16-bit DOS 640kB real-mode */ - if (ACC_MM_AHSHIFT != 3) - opt_block_size = 16 * 1024L; -#endif - - -/* - * Step 3: get options - */ - - while (i < argc && argv[i][0] == '-') - { - if (strcmp(argv[i],"-d") == 0) - opt_decompress = 1; - else if (strcmp(argv[i],"-t") == 0) - opt_test = 1; - else if (strcmp(argv[i],"-9") == 0) - opt_compression_level = 9; - else if (argv[i][1] == 'b' && argv[i][2]) - { - long b = atol(&argv[i][2]); - if (b >= 1024L && b <= 8*1024*1024L) - opt_block_size = (lzo_uint) b; - else - { - printf("%s: invalid block_size in option '%s'.\n", progname, argv[i]); - usage(); - } - } - else if (strcmp(argv[i],"--debug") == 0) - opt_debug += 1; - else - usage(); - i++; - } - if (opt_test && i >= argc) - usage(); - if (!opt_test && i + 2 != argc) - usage(); - - -/* - * Step 4: process file(s) - */ - - if (opt_test) - { - while (i < argc && r == 0) - { - in_name = argv[i++]; - fi = xopen_fi(in_name); - r = do_decompress(fi, NULL); - if (r == 0) - printf("%s: %s tested ok (%lu -> %lu bytes)\n", - progname, in_name, total_in, total_out); - xclose(fi); fi = NULL; - } - } - else if (opt_decompress) - { - in_name = argv[i++]; - out_name = argv[i++]; - fi = xopen_fi(in_name); - fo = xopen_fo(out_name); - r = do_decompress(fi, fo); - if (r == 0) - printf("%s: decompressed %lu into %lu bytes\n", - progname, total_in, total_out); - } - else /* compress */ - { - in_name = argv[i++]; - out_name = argv[i++]; - fi = xopen_fi(in_name); - fo = xopen_fo(out_name); - r = do_compress(fi, fo, opt_compression_level, opt_block_size); - if (r == 0) - printf("%s: compressed %lu into %lu bytes\n", - progname, total_in, total_out); - } - - xclose(fi); fi = NULL; - xclose(fo); fo = NULL; - return r; -} - -/* -vi:ts=4:et -*/ - |