1/* dict.c -- example program: how to use preset dictionaries 2 3 This file is part of the LZO real-time data compression library. 4 5 Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer 6 Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer 7 Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer 8 Copyright (C) 2005 Markus Franz Xaver Johannes Oberhumer 9 Copyright (C) 2004 Markus Franz Xaver Johannes Oberhumer 10 Copyright (C) 2003 Markus Franz Xaver Johannes Oberhumer 11 Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer 12 Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer 13 Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer 14 Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer 15 Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer 16 Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer 17 Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer 18 All Rights Reserved. 19 20 The LZO library is free software; you can redistribute it and/or 21 modify it under the terms of the GNU General Public License as 22 published by the Free Software Foundation; either version 2 of 23 the License, or (at your option) any later version. 24 25 The LZO library is distributed in the hope that it will be useful, 26 but WITHOUT ANY WARRANTY; without even the implied warranty of 27 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 28 GNU General Public License for more details. 29 30 You should have received a copy of the GNU General Public License 31 along with the LZO library; see the file COPYING. 32 If not, write to the Free Software Foundation, Inc., 33 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 34 35 Markus F.X.J. Oberhumer 36 <markus@oberhumer.com> 37 http://www.oberhumer.com/opensource/lzo/ 38 */ 39 40 41/************************************************************************* 42// This program shows how to use preset dictionaries. 43// 44// Please study LZO.FAQ and simple.c first. 45**************************************************************************/ 46 47#include "lzo/lzoconf.h" 48#include "lzo/lzo1x.h" 49 50/* portability layer */ 51#define WANT_LZO_MALLOC 1 52#define WANT_LZO_FREAD 1 53#define WANT_LZO_WILDARGV 1 54#include "examples/portab.h" 55 56 57static const char *progname = NULL; 58 59#define DICT_LEN 0xbfff 60static lzo_bytep dict; 61static lzo_uint dict_len = 0; 62static lzo_uint32 dict_adler32; 63 64 65/************************************************************************* 66// 67**************************************************************************/ 68 69static lzo_uint total_n = 0; 70static lzo_uint total_c_len = 0; 71static lzo_uint total_d_len = 0; 72 73static void print_file ( const char *name, lzo_uint d_len, lzo_uint c_len ) 74{ 75 double perc; 76 77 perc = (d_len > 0) ? c_len * 100.0 / d_len : 0; 78 printf(" | %-30s %9ld -> %9ld %7.2f%% |\n", 79 name, (long) d_len, (long) c_len, perc); 80 81 total_n++; 82 total_c_len += c_len; 83 total_d_len += d_len; 84} 85 86 87/************************************************************************* 88// 89**************************************************************************/ 90 91int do_file ( const char *in_name, int level ) 92{ 93 int r; 94 lzo_bytep in; 95 lzo_bytep out; 96 lzo_bytep newb; 97 lzo_bytep wrkmem; 98 lzo_uint in_len; 99 lzo_uint out_len; 100 lzo_uint new_len; 101 long l; 102 FILE *f; 103 104/* 105 * Step 1: open the input file 106 */ 107 f = fopen(in_name,"rb"); 108 if (f == 0) 109 { 110 printf("%s: cannot open file %s\n", progname, in_name); 111 return 0; /* no error */ 112 } 113 fseek(f,0,SEEK_END); 114 l = ftell(f); 115 fseek(f,0,SEEK_SET); 116 if (l <= 0) 117 { 118 printf("%s: %s: empty file -- skipping\n", progname, in_name); 119 fclose(f); 120 return 0; 121 } 122 in_len = (lzo_uint) l; 123 124/* 125 * Step 2: allocate compression buffers and read the file 126 */ 127 in = (lzo_bytep) lzo_malloc(in_len); 128 out = (lzo_bytep) lzo_malloc(in_len + in_len / 16 + 64 + 3); 129 newb = (lzo_bytep) lzo_malloc(in_len); 130 wrkmem = (lzo_bytep) lzo_malloc(LZO1X_999_MEM_COMPRESS); 131 if (in == NULL || out == NULL || newb == NULL || wrkmem == NULL) 132 { 133 printf("%s: out of memory\n", progname); 134 exit(1); 135 } 136 in_len = (lzo_uint) lzo_fread(f,in,in_len); 137 fclose(f); 138 139/* 140 * Step 3: compress from `in' to `out' with LZO1X-999 141 */ 142 r = lzo1x_999_compress_level(in,in_len,out,&out_len,wrkmem, 143 dict, dict_len, 0, level); 144 if (r != LZO_E_OK) 145 { 146 /* this should NEVER happen */ 147 printf("internal error - compression failed: %d\n", r); 148 return 1; 149 } 150 151 print_file(in_name,in_len,out_len); 152 153/* 154 * Step 4: decompress again, now going from `out' to `newb' 155 */ 156 new_len = in_len; 157 r = lzo1x_decompress_dict_safe(out,out_len,newb,&new_len,NULL,dict,dict_len); 158 if (r != LZO_E_OK) 159 { 160 /* this should NEVER happen */ 161 printf("internal error - decompression failed: %d\n", r); 162 return 1; 163 } 164 165/* 166 * Step 5: verify decompression 167 */ 168 if (new_len != in_len || lzo_memcmp(in,newb,in_len) != 0) 169 { 170 /* this should NEVER happen */ 171 printf("internal error - decompression data error\n"); 172 return 1; 173 } 174 175 /* free buffers in reverse order to help malloc() */ 176 lzo_free(wrkmem); 177 lzo_free(newb); 178 lzo_free(out); 179 lzo_free(in); 180 return 0; 181} 182 183 184/************************************************************************* 185// 186**************************************************************************/ 187 188int __lzo_cdecl_main main(int argc, char *argv[]) 189{ 190 int i = 1; 191 int r; 192 const char *dict_name; 193 FILE *f; 194 time_t t_total; 195 int level = 7; 196 197 lzo_wildargv(&argc, &argv); 198 199 printf("\nLZO real-time data compression library (v%s, %s).\n", 200 lzo_version_string(), lzo_version_date()); 201 printf("Copyright (C) 1996-2008 Markus Franz Xaver Johannes Oberhumer\nAll Rights Reserved.\n\n"); 202 203 progname = argv[0]; 204 205 if (i < argc && argv[i][0] == '-' && isdigit(argv[i][1])) 206 level = atoi(&argv[i++][1]); 207 208 if (i + 1 >= argc || level < 1 || level > 9) 209 { 210 printf("usage: %s [-level] [ dictionary-file | -n ] file...\n", progname); 211 exit(1); 212 } 213 printf("Compression level is LZO1X-999/%d\n", level); 214 215/* 216 * Step 1: initialize the LZO library 217 */ 218 if (lzo_init() != LZO_E_OK) 219 { 220 printf("internal error - lzo_init() failed !!!\n"); 221 printf("(this usually indicates a compiler bug - try recompiling\nwithout optimizations, and enable `-DLZO_DEBUG' for diagnostics)\n"); 222 exit(1); 223 } 224 225/* 226 * Step 2: prepare the dictionary 227 */ 228 dict = (lzo_bytep) lzo_malloc(DICT_LEN); 229 if (dict == NULL) 230 { 231 printf("%s: out of memory\n", progname); 232 exit(1); 233 } 234 dict_name = argv[i++]; 235 if (strcmp(dict_name,"-n") == 0) 236 { 237 dict_name = "empty"; 238 dict_len = 0; 239 } 240 else 241 { 242 f = fopen(dict_name,"rb"); 243 if (!f) 244 { 245 printf("%s: cannot open dictionary file %s\n", progname, dict_name); 246 exit(1); 247 } 248 dict_len = (lzo_uint) lzo_fread(f,dict,DICT_LEN); 249 fclose(f); 250 } 251 252 dict_adler32 = lzo_adler32(0,NULL,0); 253 dict_adler32 = lzo_adler32(dict_adler32,dict,dict_len); 254 printf("Using dictionary '%s', %ld bytes, ID 0x%08lx.\n", 255 dict_name, (long) dict_len, (long) dict_adler32); 256 257/* 258 * Step 3: process files 259 */ 260 t_total = time(NULL); 261 for (r = 0; r == 0 && i < argc; i++) 262 r = do_file(argv[i], level); 263 t_total = time(NULL) - t_total; 264 265 lzo_free(dict); 266 267 if (total_n > 1) 268 print_file("***TOTALS***",total_d_len,total_c_len); 269 270 printf("Dictionary compression test %s, execution time %lu seconds.\n", 271 r == 0 ? "passed" : "FAILED", (unsigned long) t_total); 272 return r; 273} 274 275/* 276vi:ts=4:et 277*/ 278 279