~ubuntu-branches/debian/stretch/uswsusp/stretch

« back to all changes in this revision

Viewing changes to lzf/lzf.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthew Garrett
  • Date: 2006-08-11 09:42:59 UTC
  • Revision ID: james.westby@ubuntu.com-20060811094259-xbpx53fo39c0xl8y
Tags: 0.1
Initial Release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 2000-2005 Marc Alexander Lehmann <schmorp@schmorp.de>
 
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
 * Alternatively, the contents of this file may be used under the terms of
 
29
 * the GNU General Public License version 2 (the "GPL"), in which case the
 
30
 * provisions of the GPL are applicable instead of the above. If you wish to
 
31
 * allow the use of your version of this file only under the terms of the
 
32
 * GPL and not to allow others to use your version of this file under the
 
33
 * BSD license, indicate your decision by deleting the provisions above and
 
34
 * replace them with the notice and other provisions required by the GPL. If
 
35
 * you do not delete the provisions above, a recipient may use your version
 
36
 * of this file under either the BSD or the GPL.
 
37
 */
 
38
 
 
39
#include <stdio.h>
 
40
#include <stdlib.h>
 
41
#include <string.h>
 
42
#include <assert.h>
 
43
 
 
44
#include <unistd.h>
 
45
#include <getopt.h>
 
46
 
 
47
#include "lzf.h"
 
48
 
 
49
typedef unsigned char u8;
 
50
 
 
51
static void
 
52
usage (int ec)
 
53
{
 
54
  fprintf (stderr, "\n"
 
55
           "lzf, a very lightweight compression/decompression filter\n"
 
56
           "written by Marc Lehmann <schmorp@schmorp.de> You can find more info at\n"
 
57
           "http://liblzf.plan9.de/\n"
 
58
           "\n"
 
59
           "USAGE: lzf -c [-b blocksize] | -d\n"
 
60
           "          -c  compress\n"
 
61
           "          -d  decompress\n"
 
62
           "          -b  specify the blocksize (default 64k-1)\n"
 
63
           "\n"
 
64
    );
 
65
 
 
66
  exit (ec);
 
67
}
 
68
 
 
69
/*
 
70
 * Anatomy: an lzf file consists of any number of blocks in the following format:
 
71
 *
 
72
 * "ZV\0" 2-byte-usize <uncompressed data>
 
73
 * "ZV\1" 2-byte-csize 2-byte-usize <compressed data>
 
74
 * "ZV\2" 4-byte-crc32-0xdebb20e3 (NYI)
 
75
 * 
 
76
 */
 
77
 
 
78
static void compress (unsigned int blocksize)
 
79
{
 
80
  ssize_t us;
 
81
  unsigned int cs;
 
82
  u8 buff1[64*1024];
 
83
  u8 buff2[64*1024];
 
84
  u8 header[3+2+2];
 
85
 
 
86
  header[0] = 'Z';
 
87
  header[1] = 'V';
 
88
 
 
89
  for(;;) {
 
90
    us = fread (buff1, 1, blocksize, stdin);
 
91
 
 
92
    if (us < blocksize)
 
93
      {
 
94
        if (us == 0)
 
95
          break;
 
96
        else if (!feof (stdin))
 
97
          {
 
98
            perror ("compress");
 
99
            exit (1);
 
100
          }
 
101
      }
 
102
 
 
103
    cs = lzf_compress (buff1, us, buff2, us - 4);
 
104
 
 
105
    if (cs)
 
106
      {
 
107
        header[2] = 1;
 
108
        header[3] = cs >> 8;
 
109
        header[4] = cs & 0xff;
 
110
        header[5] = us >> 8;
 
111
        header[6] = us & 0xff;
 
112
 
 
113
        fwrite (header, 3+2+2, 1, stdout);
 
114
        fwrite (buff2, cs, 1, stdout);
 
115
      }
 
116
    else
 
117
      {
 
118
        header[2] = 0;
 
119
        header[3] = us >> 8;
 
120
        header[4] = us & 0xff;
 
121
 
 
122
        fwrite (header, 3+2, 1, stdout);
 
123
        fwrite (buff1, us, 1, stdout);
 
124
      }
 
125
  } while (!feof (stdin));
 
126
}
 
127
 
 
128
static void decompress (void)
 
129
{
 
130
  ssize_t us;
 
131
  unsigned int cs;
 
132
  u8 buff1[64*1024];
 
133
  u8 buff2[64*1024];
 
134
  u8 header[3+2+2];
 
135
 
 
136
  for(;;) {
 
137
    if (fread (header, 3+2, 1, stdin) != 1)
 
138
      {
 
139
        if (feof (stdin))
 
140
          break;
 
141
        else
 
142
          {
 
143
            perror ("decompress");
 
144
            exit (1);
 
145
          }
 
146
      }
 
147
 
 
148
    if (header[0] != 'Z' || header[1] != 'V')
 
149
      {
 
150
        fprintf (stderr, "decompress: invalid stream - no magic number found\n");
 
151
        exit (1);
 
152
      }
 
153
 
 
154
    cs = (header[3] << 8) | header[4];
 
155
 
 
156
    if (header[2] == 1)
 
157
      {
 
158
        if (fread (header+3+2, 2, 1, stdin) != 1)
 
159
          {
 
160
            perror ("decompress");
 
161
            exit (1);
 
162
          }
 
163
 
 
164
        us = (header[5] << 8) | header[6];
 
165
 
 
166
        if (fread (buff1, cs, 1, stdin) != 1)
 
167
          {
 
168
            perror ("decompress");
 
169
            exit (1);
 
170
          }
 
171
 
 
172
        if (lzf_decompress (buff1, cs, buff2, us) != us)
 
173
          {
 
174
            fprintf (stderr, "decompress: invalid stream - data corrupted\n");
 
175
            exit (1);
 
176
          }
 
177
 
 
178
        fwrite (buff2, us, 1, stdout);
 
179
      }
 
180
    else if (header[2] == 0)
 
181
      {
 
182
        if (fread (buff2, cs, 1, stdin) != 1)
 
183
          {
 
184
            perror ("decompress");
 
185
            exit (1);
 
186
          }
 
187
 
 
188
        fwrite (buff2, cs, 1, stdout);
 
189
      }
 
190
    else
 
191
      {
 
192
        fprintf (stderr, "decompress: invalid stream - unknown block type\n");
 
193
        exit (1);
 
194
      }
 
195
  }
 
196
}
 
197
 
 
198
int
 
199
main (int argc, char *argv[])
 
200
{
 
201
  int c;
 
202
  unsigned int blocksize = 64*1024-1;
 
203
  enum { m_compress, m_decompress } mode = m_compress;
 
204
 
 
205
  if (!strcmp (argv[0] + strlen (argv[0] - 5), "unlzf"))
 
206
    mode = m_decompress;
 
207
 
 
208
  while ((c = getopt (argc, argv, "cdb:h")) != -1)
 
209
    switch (c)
 
210
      {
 
211
      case 'c':
 
212
        mode = m_compress;
 
213
        break;
 
214
 
 
215
      case 'd':
 
216
        mode = m_decompress;
 
217
        break;
 
218
 
 
219
      case 'b':
 
220
        blocksize = atol (optarg);
 
221
        break;
 
222
 
 
223
      case 'h':
 
224
        usage (0);
 
225
 
 
226
      case ':':
 
227
        fprintf (stderr, "required argument missing, use -h\n");
 
228
        exit (1);
 
229
 
 
230
      case '?':
 
231
        fprintf (stderr, "unknown option, use -h\n");
 
232
        exit (1);
 
233
 
 
234
      default:
 
235
        usage (1);
 
236
      }
 
237
 
 
238
  if (mode == m_compress)
 
239
    compress (blocksize);
 
240
  else if (mode == m_decompress)
 
241
    decompress ();
 
242
  else
 
243
    abort ();
 
244
 
 
245
  return 0;
 
246
}