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

# User Rev Content
1 root 1.1 /*
2 root 1.2 * Copyright (c) 2000-2002 Marc Alexander Lehmann <pcg@goof.com>
3 root 1.1 *
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     }