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