1 /* overlap.c -- example program: overlapping (de)compression
3 This file is part of the LZO real-time data compression library.
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
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.
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.
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.
38 Markus F.X.J. Oberhumer
39 <markus@oberhumer.com>
40 http://www.oberhumer.com/opensource/lzo/
44 /*************************************************************************
45 // This program shows how to do overlapping compression and
46 // in-place decompression.
48 // Please study LZO.FAQ and simple.c first.
49 **************************************************************************/
51 #include "lzo/lzoconf.h"
52 #include "lzo/lzo1x.h"
54 /* portability layer */
55 static const char *progname
= NULL
;
56 #define WANT_LZO_MALLOC 1
57 #define WANT_LZO_FREAD 1
58 #define WANT_LZO_WILDARGV 1
59 #define WANT_XMALLOC 1
60 #include "examples/portab.h"
63 /* Overhead (in bytes) for the in-place decompression buffer.
64 * Most files need only 16 !
65 * (try 'overlap -16 file' or even 'overlap -8 file')
67 * Worst case (for files that are compressible by only a few bytes)
68 * is 'in_len / 16 + 64 + 3'. See step 5a) below.
70 * For overlapping compression '0xbfff + in_len / 16 + 64 + 3' bytes
71 * will be needed. See step 4a) below.
74 static lzo_uint opt_overhead
= 0; /* assume worst case */
77 #if 0 && defined(LZO_USE_ASM)
78 /* just for testing */
80 # define lzo1x_decompress lzo1x_decompress_asm_fast
84 static unsigned long total_files
= 0;
85 static unsigned long total_in
= 0;
88 /*************************************************************************
90 **************************************************************************/
92 int do_file ( const char *in_name
)
98 lzo_voidp wrkmem
= NULL
;
101 lzo_uint in_len
; /* uncompressed length */
103 lzo_bytep out
= NULL
;
104 lzo_uint out_len
; /* compressed length */
106 lzo_bytep overlap
= NULL
;
110 lzo_uint new_len
= 0;
113 * Step 1: open the input file
115 fp
= fopen(in_name
, "rb");
118 printf("%s: %s: cannot open file\n", progname
, in_name
);
121 fseek(fp
, 0, SEEK_END
);
123 fseek(fp
, 0, SEEK_SET
);
126 printf("%s: %s: empty file -- skipping\n", progname
, in_name
);
129 in_len
= (lzo_uint
) l
;
132 * Step 2: allocate compression buffers and read the file
134 in
= (lzo_bytep
) xmalloc(in_len
);
135 out
= (lzo_bytep
) xmalloc(in_len
+ in_len
/ 16 + 64 + 3);
136 wrkmem
= (lzo_voidp
) xmalloc(LZO1X_1_MEM_COMPRESS
);
137 in_len
= (lzo_uint
) lzo_fread(fp
, in
, in_len
);
138 fclose(fp
); fp
= NULL
;
139 printf("%s: %s: read %lu bytes\n", progname
, in_name
, (unsigned long) in_len
);
142 total_in
+= (unsigned long) in_len
;
145 * Step 3: compress from 'in' to 'out' with LZO1X-1
147 r
= lzo1x_1_compress(in
,in_len
,out
,&out_len
,wrkmem
);
148 if (r
!= LZO_E_OK
|| out_len
> in_len
+ in_len
/ 16 + 64 + 3)
150 /* this should NEVER happen */
151 printf("internal error - compression failed: %d\n", r
);
154 printf("%-26s %8lu -> %8lu\n", "LZO1X-1:", (unsigned long) in_len
, (unsigned long) out_len
);
157 /***** Step 4: overlapping compression *****/
160 * Step 4a: allocate the 'overlap' buffer for overlapping compression
162 overhead
= in_len
> 0xbfff ? 0xbfff : in_len
;
163 overhead
+= in_len
/ 16 + 64 + 3;
164 overlap
= (lzo_bytep
) xmalloc(in_len
+ overhead
);
167 * Step 4b: prepare data in 'overlap' buffer.
168 * copy uncompressed data at the top of the overlap buffer
170 /*** offset = in_len + overhead - in_len; ***/
172 lzo_memcpy(overlap
+ offset
, in
, in_len
);
175 * Step 4c: do an in-place compression within the 'overlap' buffer
177 r
= lzo1x_1_compress(overlap
+offset
,in_len
,overlap
,&new_len
,wrkmem
);
180 /* this should NEVER happen */
181 printf("overlapping compression failed: %d\n", r
);
186 * Step 4d: verify overlapping compression
188 if (new_len
!= out_len
|| lzo_memcmp(out
,overlap
,out_len
) != 0)
190 /* As compression is non-deterministic there can be a difference
191 * in the representation of the compressed data (but this usually
192 * happens very seldom). So we have to verify the overlapping
193 * compression by doing a temporary decompression.
195 lzo_uint ll
= in_len
;
196 lzo_bytep tmp
= (lzo_bytep
) xmalloc(ll
);
197 r
= lzo1x_decompress_safe(overlap
, new_len
, tmp
, &ll
, NULL
);
198 if (r
!= LZO_E_OK
|| ll
!= in_len
|| lzo_memcmp(in
, tmp
, ll
) != 0)
200 /* this should NEVER happen */
201 printf("overlapping compression data error\n");
207 printf("overlapping compression: %8lu -> %8lu overhead: %7lu\n",
208 (unsigned long) in_len
, (unsigned long) new_len
, (unsigned long) overhead
);
209 lzo_free(overlap
); overlap
= NULL
;
212 /***** Step 5: overlapping decompression *****/
215 * Step 5a: allocate the 'overlap' buffer for in-place decompression
217 if (opt_overhead
== 0 || out_len
>= in_len
)
218 overhead
= in_len
/ 16 + 64 + 3;
220 overhead
= opt_overhead
;
221 overlap
= (lzo_bytep
) xmalloc(in_len
+ overhead
);
224 * Step 5b: prepare data in 'overlap' buffer.
225 * copy compressed data at the top of the overlap buffer
227 offset
= in_len
+ overhead
- out_len
;
228 lzo_memcpy(overlap
+ offset
, out
, out_len
);
231 * Step 5c: do an in-place decompression within the 'overlap' buffer
234 r
= lzo1x_decompress(overlap
+offset
,out_len
,overlap
,&new_len
,NULL
);
237 /* this may happen if overhead is too small */
238 printf("overlapping decompression failed: %d - increase 'opt_overhead'\n", r
);
243 * Step 5d: verify decompression
245 if (new_len
!= in_len
|| lzo_memcmp(in
,overlap
,in_len
) != 0)
247 /* this may happen if overhead is too small */
248 printf("overlapping decompression data error - increase 'opt_overhead'\n");
251 printf("overlapping decompression: %8lu -> %8lu overhead: %7lu\n",
252 (unsigned long) out_len
, (unsigned long) new_len
, (unsigned long) overhead
);
253 lzo_free(overlap
); overlap
= NULL
;
267 /*************************************************************************
269 **************************************************************************/
271 int __lzo_cdecl_main
main(int argc
, char *argv
[])
276 lzo_wildargv(&argc
, &argv
);
278 printf("\nLZO real-time data compression library (v%s, %s).\n",
279 lzo_version_string(), lzo_version_date());
280 printf("Copyright (C) 1996-2011 Markus Franz Xaver Johannes Oberhumer\nAll Rights Reserved.\n\n");
283 if (i
< argc
&& argv
[i
][0] == '-')
284 opt_overhead
= atoi(&argv
[i
++][1]);
286 if (opt_overhead
!= 0 && opt_overhead
< 8)
288 printf("%s: invalid overhead value %ld\n", progname
, (long)opt_overhead
);
294 printf("usage: %s [-overhead_in_bytes] file..\n", progname
);
299 * Step 1: initialize the LZO library
301 if (lzo_init() != LZO_E_OK
)
303 printf("internal error - lzo_init() failed !!!\n");
304 printf("(this usually indicates a compiler bug - try recompiling\nwithout optimizations, and enable '-DLZO_DEBUG' for diagnostics)\n");
309 * Step 2: process files
311 for (r
= 0; r
== 0 && i
< argc
; i
++)
312 r
= do_file(argv
[i
]);
314 printf("\nDone. Successfully processed %lu bytes in %lu files.\n",
315 total_in
, total_files
);