ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/liblzf/lzf.c
Revision: 1.2
Committed: Sun Nov 17 11:39:26 2002 UTC (21 years, 6 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.1: +1 -1 lines
Log Message:
*** empty log message ***

File Contents

# Content
1 /*
2 * Copyright (c) 2000-2002 Marc Alexander Lehmann <pcg@goof.com>
3 *
4 * Redistribution and use in source and binary forms, with or without modifica-
5 * tion, are permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright notice,
8 * this list of conditions and the following disclaimer.
9 *
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
19 * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
20 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
21 * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
25 * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
26 * OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include "config.h"
30
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <assert.h>
34
35 #include <unistd.h>
36 #include <getopt.h>
37
38 #include "lzf.h"
39
40 static void
41 usage (int ec)
42 {
43 fprintf (stderr, "\n"
44 "lzf, a very leightweight compression/decompression filter\n"
45 "written by Marc Lehmann <pcg@goof.com> You can find more info at\n"
46 "http://liblzv.plan9.de/\n"
47 "\n"
48 "USAGE: lzf -c [-b blocksize] | -d\n"
49 " -c compress\n"
50 " -d decompress\n"
51 " -b specify the blocksize (default 64k-1)\n"
52 "\n"
53 );
54
55 exit (ec);
56 }
57
58 /*
59 * Anatomy: an lzf file consists of any number of blocks in the following format:
60 *
61 * "ZV\0" 2-byte-usize <uncompressed data>
62 * "ZV\1" 2-byte-csize 2-byte-usize <compressed data>
63 * "ZV\2" 4-byte-crc32-0xdebb20e3 (NYI)
64 *
65 */
66
67 static void compress (unsigned int blocksize)
68 {
69 ssize_t us;
70 unsigned int cs;
71 u8 buff1[64*1024];
72 u8 buff2[64*1024];
73 u8 header[3+2+2];
74
75 header[0] = 'Z';
76 header[1] = 'V';
77
78 for(;;) {
79 us = fread (buff1, 1, blocksize, stdin);
80
81 if (us < blocksize)
82 {
83 if (us == 0)
84 break;
85 else if (!feof (stdin))
86 {
87 perror ("compress");
88 exit (1);
89 }
90 }
91
92 cs = lzf_compress (buff1, us, buff2, us - 4);
93
94 if (cs)
95 {
96 header[2] = 1;
97 header[3] = cs >> 8;
98 header[4] = cs & 0xff;
99 header[5] = us >> 8;
100 header[6] = us & 0xff;
101
102 fwrite (header, 3+2+2, 1, stdout);
103 fwrite (buff2, cs, 1, stdout);
104 }
105 else
106 {
107 header[2] = 0;
108 header[3] = us >> 8;
109 header[4] = us & 0xff;
110
111 fwrite (header, 3+2, 1, stdout);
112 fwrite (buff1, us, 1, stdout);
113 }
114 } while (!feof (stdin));
115 }
116
117 static void decompress (void)
118 {
119 ssize_t us;
120 unsigned int cs;
121 u8 buff1[64*1024];
122 u8 buff2[64*1024];
123 u8 header[3+2+2];
124
125 for(;;) {
126 if (fread (header, 3+2, 1, stdin) != 1)
127 {
128 if (feof (stdin))
129 break;
130 else
131 {
132 perror ("decompress");
133 exit (1);
134 }
135 }
136
137 if (header[0] != 'Z' || header[1] != 'V')
138 {
139 fprintf (stderr, "decompress: invalid stream - no magic number found\n");
140 exit (1);
141 }
142
143 cs = (header[3] << 8) | header[4];
144
145 if (header[2] == 1)
146 {
147 if (fread (header+3+2, 2, 1, stdin) != 1)
148 {
149 perror ("decompress");
150 exit (1);
151 }
152
153 us = (header[5] << 8) | header[6];
154
155 if (fread (buff1, cs, 1, stdin) != 1)
156 {
157 perror ("decompress");
158 exit (1);
159 }
160
161 if (lzf_decompress (buff1, cs, buff2, us) != us)
162 {
163 fprintf (stderr, "decompress: invalid stream - data corrupted\n");
164 exit (1);
165 }
166
167 fwrite (buff2, us, 1, stdout);
168 }
169 else if (header[2] == 0)
170 {
171 if (fread (buff2, cs, 1, stdin) != 1)
172 {
173 perror ("decompress");
174 exit (1);
175 }
176
177 fwrite (buff2, cs, 1, stdout);
178 }
179 else
180 {
181 fprintf (stderr, "decompress: invalid stream - unknown block type\n");
182 exit (1);
183 }
184 }
185 }
186
187 int
188 main (int argc, char *argv[])
189 {
190 int c;
191 unsigned int blocksize = 64*1024-1;
192 enum { m_compress, m_decompress } mode = m_compress;
193
194 while ((c = getopt (argc, argv, "cdb:h")) != -1)
195 switch (c)
196 {
197 case 'c':
198 mode = m_compress;
199 break;
200
201 case 'd':
202 mode = m_decompress;
203 break;
204
205 case 'b':
206 blocksize = atol (optarg);
207 break;
208
209 case 'h':
210 usage (0);
211
212 case ':':
213 fprintf (stderr, "required argument missing, use -h\n");
214 exit (1);
215
216 case '?':
217 fprintf (stderr, "unknown option, use -h\n");
218 exit (1);
219
220 default:
221 usage (1);
222 }
223
224 if (mode == m_compress)
225 compress (blocksize);
226 else if (mode == m_decompress)
227 decompress ();
228 else
229 abort ();
230
231 return 0;
232 }