/[pkg-mixmaster]/trunk/Mix/Src/compress.c
ViewVC logotype

Contents of /trunk/Mix/Src/compress.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 934 - (hide annotations) (download)
Sat Jun 24 13:40:39 2006 UTC (6 years, 10 months ago) by rabbi
File MIME type: text/plain
File size: 4746 byte(s)
Updated copyright dates.
1 rabbi 934 /* Mixmaster version 3.0 -- (C) 1999 - 2006 Anonymizer Inc. and others.
2 rabbi 1
3     Mixmaster may be redistributed and modified under certain conditions.
4     This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
5     ANY KIND, either express or implied. See the file COPYRIGHT for
6     details.
7    
8     Buffer compression (interface to zlib)
9 weasel 647 $Id$ */
10 rabbi 1
11    
12     #include "mix3.h"
13     #include <stdio.h>
14     #include <assert.h>
15    
16     static byte gz_magic[2] =
17     {0x1f, 0x8b}; /* gzip magic header */
18    
19     /* gzip flag byte */
20     #define ASCII_FLAG 0x01
21     #define HEAD_CRC 0x02
22     #define EXTRA_FIELD 0x04
23     #define ORIG_NAME 0x08
24     #define COMMENT 0x10
25     #define RESERVED 0xE0
26     #define Z_DEFLATED 8
27    
28     #ifdef USE_ZLIB
29     #include "zlib.h"
30    
31     int buf_unzip(BUFFER *in, int type)
32     {
33     BUFFER *out;
34     z_stream s;
35     long outstart;
36     int err;
37     int ret = 0;
38    
39     out = buf_new();
40    
41     s.zalloc = (alloc_func) 0;
42     s.zfree = (free_func) 0;
43     s.opaque = (voidpf) 0;
44    
45     s.next_in = in->data + in->ptr;
46     s.avail_in = in->length + 1 - in->ptr; /* terminating 0 byte as "dummy" */
47     s.next_out = NULL;
48    
49     if (type == 1)
50     err = inflateInit(&s); /* zlib */
51     else
52     err = inflateInit2(&s, -MAX_WBITS);
53     if (err != Z_OK) {
54     ret = -1;
55     goto end;
56     }
57     outstart = 0;
58     buf_append(out, NULL, in->length * 15 / 10);
59    
60     for (;;) {
61     s.next_out = out->data + s.total_out + outstart;
62     s.avail_out = out->length - outstart - s.total_out;
63     err = inflate(&s, Z_PARTIAL_FLUSH);
64     out->length -= s.avail_out;
65     if (err != Z_OK)
66     break;
67     buf_append(out, NULL, BUFSIZE);
68     }
69     if (err != Z_STREAM_END)
70     errlog(WARNING, "Decompression error %d\n", err);
71    
72     err = inflateEnd(&s);
73     if (err != Z_OK)
74     ret = -1;
75     end:
76     if (ret != 0)
77     switch (err) {
78     case Z_STREAM_ERROR:
79     errlog(ERRORMSG, "Decompression error Z_STREAM_ERROR.\n", err);
80     break;
81     case Z_MEM_ERROR:
82     errlog(ERRORMSG, "Decompression error Z_MEM_ERROR.\n", err);
83     break;
84     case Z_BUF_ERROR:
85     errlog(ERRORMSG, "Decompression error Z_BUF_ERROR.\n", err);
86     break;
87     case Z_VERSION_ERROR:
88     errlog(ERRORMSG, "Decompression error Z_VERSION_ERROR.\n", err);
89     break;
90     default:
91     errlog(ERRORMSG, "Decompression error %d.\n", err);
92     }
93     buf_move(in, out);
94     buf_free(out);
95     return (ret);
96     }
97    
98     int buf_zip(BUFFER *out, BUFFER *in, int bits)
99     {
100     z_stream s;
101     long outstart;
102     int err = -1;
103    
104     assert(in != out);
105    
106     s.zalloc = (alloc_func) 0;
107     s.zfree = (free_func) 0;
108     s.opaque = (voidpf) 0;
109     s.next_in = NULL;
110    
111     if (bits == 0)
112     bits = MAX_WBITS;
113    
114     if (deflateInit2(&s, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -bits, 8, 0) != Z_OK)
115     goto end;
116    
117     outstart = out->length;
118 weaselp 600 /* 12 is overhead, 1.01 is maximum expansion, and 1 is there to force a round-up */
119 weaselp 599 buf_append(out, NULL, (int)13+in->length*1.01); /* fit it in one chunk */
120 rabbi 1
121     s.next_in = in->data;
122     s.avail_in = in->length;
123    
124     for (;;) {
125     s.next_out = out->data + s.total_out + outstart;
126     s.avail_out = out->length - outstart - s.total_out;
127     err = deflate(&s, Z_FINISH);
128     out->length -= s.avail_out;
129     if (err != Z_OK)
130     break;
131 weaselp 599 errlog(ERRORMSG, "Compressed data did not fit in one chunk.\n");
132 rabbi 1 buf_append(out, NULL, BUFSIZE);
133     }
134     if (deflateEnd(&s) != Z_OK || err != Z_STREAM_END)
135     err = -1;
136     else
137     err = 0;
138     end:
139     if (err != 0)
140     errlog(ERRORMSG, "Compression error.\n");
141     return (err);
142     }
143    
144 rabbi 262 #else /* end of USE_ZLIB */
145 rabbi 1 int buf_zip(BUFFER *out, BUFFER *in, int bits)
146     {
147     return (-1);
148     }
149    
150     int buf_unzip(BUFFER *b, int type)
151     {
152     errlog(ERRORMSG, "Can't uncompress: no zlib\n");
153     return (-1);
154     }
155 rabbi 262 #endif /* else not USE_ZLIB */
156 rabbi 1
157     int compressed(BUFFER *b)
158     {
159     return (b->length >= 10 && b->data[0] == gz_magic[0] &&
160     b->data[1] == gz_magic[1]);
161     }
162    
163     int buf_uncompress(BUFFER *in)
164     {
165     int type;
166     int err = -1;
167     unsigned int len;
168    
169     if (!compressed(in))
170     return (0);
171     type = in->data[3];
172     if (in->data[2] != Z_DEFLATED || (type & RESERVED) == 0) {
173     in->ptr = 10;
174     if ((type & EXTRA_FIELD) != 0) {
175     len = buf_geti(in);
176     in->ptr += len;
177     }
178     if ((type & ORIG_NAME) != 0)
179     while (buf_getc(in) > 0) ;
180     if ((type & COMMENT) != 0)
181     while (buf_getc(in) > 0) ;
182     if ((type & HEAD_CRC) != 0)
183     buf_geti(in);
184     err = buf_unzip(in, 0);
185     }
186     return (err);
187     }
188    
189     int buf_compress(BUFFER *in)
190     {
191     BUFFER *out;
192     int err;
193    
194     if (compressed(in))
195     return (0);
196    
197     out = buf_new();
198     buf_appendc(out, gz_magic[0]);
199     buf_appendc(out, gz_magic[1]);
200     buf_appendc(out, Z_DEFLATED);
201     buf_appendc(out, 0); /* flags */
202     buf_appendl(out, 0); /* time */
203     buf_appendc(out, 0); /* xflags */
204     buf_appendc(out, 3); /* Unix */
205     err = buf_zip(out, in, 0);
206     if (err == 0)
207     buf_move(in, out);
208     buf_free(out);
209     return (err);
210     }

Properties

Name Value
svn:keywords Id

  ViewVC Help
Powered by ViewVC 1.1.5