1 /* precomp.c -- example program: how to generate pre-compressed data
3 This file is part of the LZO real-time data compression library.
5 Copyright (C) 1996-2014 Markus Franz Xaver Johannes Oberhumer
8 The LZO library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2 of
11 the License, or (at your option) any later version.
13 The LZO library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with the LZO library; see the file COPYING.
20 If not, write to the Free Software Foundation, Inc.,
21 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23 Markus F.X.J. Oberhumer
24 <markus@oberhumer.com>
25 http://www.oberhumer.com/opensource/lzo/
29 /*************************************************************************
30 // This program shows how to generate pre-compressed data.
32 // Please study LZO.FAQ and simple.c first.
34 // We will be trying both LZO1X-999 and LZO1Y-999 and choose
35 // the algorithm that achieves the best compression ratio.
36 **************************************************************************/
38 #include "lzo/lzoconf.h"
39 #include "lzo/lzo1x.h"
40 #include "lzo/lzo1y.h"
48 /* portability layer */
49 static const char *progname
= NULL
;
50 #define WANT_LZO_MALLOC 1
51 #define WANT_LZO_FREAD 1
52 #define WANT_LZO_WILDARGV 1
53 #define WANT_XMALLOC 1
54 #include "examples/portab.h"
57 /*************************************************************************
59 **************************************************************************/
61 int __lzo_cdecl_main
main(int argc
, char *argv
[])
76 int best_compress
= -1;
79 lzo_uint32_t uncompressed_checksum
;
80 lzo_uint32_t compressed_checksum
;
83 const char *in_name
= NULL
;
84 const char *out_name
= NULL
;
88 lzo_wildargv(&argc
, &argv
);
90 printf("\nLZO real-time data compression library (v%s, %s).\n",
91 lzo_version_string(), lzo_version_date());
92 printf("Copyright (C) 1996-2014 Markus Franz Xaver Johannes Oberhumer\nAll Rights Reserved.\n\n");
95 if (argc
< 2 || argc
> 3)
97 printf("usage: %s file [output-file]\n", progname
);
101 if (argc
> 2) out_name
= argv
[2];
104 * Step 1: initialize the LZO library
106 if (lzo_init() != LZO_E_OK
)
108 printf("internal error - lzo_init() failed !!!\n");
109 printf("(this usually indicates a compiler bug - try recompiling\nwithout optimizations, and enable '-DLZO_DEBUG' for diagnostics)\n");
114 * Step 2: allocate the work-memory
118 wrkmem_size
= (LZO1X_999_MEM_COMPRESS
> wrkmem_size
) ? LZO1X_999_MEM_COMPRESS
: wrkmem_size
;
121 wrkmem_size
= (LZO1Y_999_MEM_COMPRESS
> wrkmem_size
) ? LZO1Y_999_MEM_COMPRESS
: wrkmem_size
;
123 wrkmem
= (lzo_voidp
) xmalloc(wrkmem_size
);
126 printf("%s: out of memory\n", progname
);
131 * Step 3: open the input file
133 fp
= fopen(in_name
,"rb");
136 printf("%s: cannot open file %s\n", progname
, in_name
);
139 fseek(fp
, 0, SEEK_END
);
141 fseek(fp
, 0, SEEK_SET
);
144 printf("%s: %s: empty file\n", progname
, in_name
);
145 fclose(fp
); fp
= NULL
;
148 in_len
= (lzo_uint
) l
;
149 out_bufsize
= in_len
+ in_len
/ 16 + 64 + 3;
153 * Step 4: allocate compression buffers and read the file
155 in
= (lzo_bytep
) xmalloc(in_len
);
156 out
= (lzo_bytep
) xmalloc(out_bufsize
);
157 if (in
== NULL
|| out
== NULL
)
159 printf("%s: out of memory\n", progname
);
162 in_len
= (lzo_uint
) lzo_fread(fp
, in
, in_len
);
163 printf("%s: loaded file %s: %ld bytes\n", progname
, in_name
, (long) in_len
);
164 fclose(fp
); fp
= NULL
;
167 * Step 5: compute a checksum of the uncompressed data
169 uncompressed_checksum
= lzo_adler32(0,NULL
,0);
170 uncompressed_checksum
= lzo_adler32(uncompressed_checksum
,in
,in_len
);
173 * Step 6a: compress from 'in' to 'out' with LZO1X-999
176 out_len
= out_bufsize
;
177 r
= lzo1x_999_compress(in
,in_len
,out
,&out_len
,wrkmem
);
180 /* this should NEVER happen */
181 printf("internal error - compression failed: %d\n", r
);
184 printf("LZO1X-999: %8lu -> %8lu\n", (unsigned long) in_len
, (unsigned long) out_len
);
185 if (out_len
< best_len
)
188 best_compress
= 1; /* LZO1X-999 */
190 #endif /* USE_LZO1X */
193 * Step 6b: compress from 'in' to 'out' with LZO1Y-999
196 out_len
= out_bufsize
;
197 r
= lzo1y_999_compress(in
,in_len
,out
,&out_len
,wrkmem
);
200 /* this should NEVER happen */
201 printf("internal error - compression failed: %d\n", r
);
204 printf("LZO1Y-999: %8lu -> %8lu\n", (unsigned long) in_len
, (unsigned long) out_len
);
205 if (out_len
< best_len
)
208 best_compress
= 2; /* LZO1Y-999 */
210 #endif /* USE_LZO1Y */
213 * Step 7: check if compressible
215 if (best_len
>= in_len
)
217 printf("This file contains incompressible data.\n");
222 * Step 8: compress data again using the best compressor found
224 out_len
= out_bufsize
;
225 if (best_compress
== 1)
226 r
= lzo1x_999_compress(in
,in_len
,out
,&out_len
,wrkmem
);
227 else if (best_compress
== 2)
228 r
= lzo1y_999_compress(in
,in_len
,out
,&out_len
,wrkmem
);
231 assert(r
== LZO_E_OK
);
232 assert(out_len
== best_len
);
235 * Step 9: optimize compressed data (compressed data is in 'out' buffer)
238 /* Optimization does not require any data in the buffer that will
239 * hold the uncompressed data. To prove this, we clear the buffer.
241 lzo_memset(in
,0,in_len
);
247 if (best_compress
== 1)
248 r
= lzo1x_optimize(out
,out_len
,in
,&orig_len
,NULL
);
251 if (best_compress
== 2)
252 r
= lzo1y_optimize(out
,out_len
,in
,&orig_len
,NULL
);
254 if (r
!= LZO_E_OK
|| orig_len
!= in_len
)
256 /* this should NEVER happen */
257 printf("internal error - optimization failed: %d\n", r
);
262 * Step 10: compute a checksum of the compressed data
264 compressed_checksum
= lzo_adler32(0,NULL
,0);
265 compressed_checksum
= lzo_adler32(compressed_checksum
,out
,out_len
);
268 * Step 11: write compressed data to a file
270 printf("%s: %s: %ld -> %ld, checksum 0x%08lx 0x%08lx\n",
271 progname
, in_name
, (long) in_len
, (long) out_len
,
272 (long) uncompressed_checksum
, (long) compressed_checksum
);
274 if (out_name
&& out_name
[0])
276 printf("%s: writing to file %s\n", progname
, out_name
);
277 fp
= fopen(out_name
,"wb");
280 printf("%s: cannot open output file %s\n", progname
, out_name
);
283 if (lzo_fwrite(fp
, out
, out_len
) != out_len
|| fclose(fp
) != 0)
285 printf("%s: write error !!\n", progname
);
291 * Step 12: verify decompression
294 lzo_memset(in
,0,in_len
); /* paranoia - clear output buffer */
298 if (best_compress
== 1)
299 r
= lzo1x_decompress_safe(out
,out_len
,in
,&orig_len
,NULL
);
302 if (best_compress
== 2)
303 r
= lzo1y_decompress_safe(out
,out_len
,in
,&orig_len
,NULL
);
305 if (r
!= LZO_E_OK
|| orig_len
!= in_len
)
307 /* this should NEVER happen */
308 printf("internal error - decompression failed: %d\n", r
);
311 if (uncompressed_checksum
!= lzo_adler32(lzo_adler32(0,NULL
,0),in
,in_len
))
313 /* this should NEVER happen */
314 printf("internal error - decompression data error\n");
317 /* Now you could also verify decompression under similar conditions as in
318 * your application, e.g. overlapping assembler decompression etc.
330 /* vim:set ts=4 sw=4 et: */