root/morphix/trunk/cloop/advancecomp-1.9_create_compressed_fs/compress.cc

Revision 2, 8.3 kB (checked in by nextime, 2 years ago)

Initial import, branching from morphix svn

Line 
1 /*
2  * This file is part of the Advance project.
3  *
4  * Copyright (C) 2002 Andrea Mazzoleni
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  */
20
21 #include "portable.h"
22
23 #include "compress.h"
24
25 #include <cassert>
26
27 // -------------------------------------------------------------------------
28 // compression/decompression
29
30 bool decompress_deflate_zlib(const unsigned char* in_data, unsigned in_size, unsigned char* out_data, unsigned out_size) {
31
32         z_stream stream;
33         stream.next_in = const_cast<unsigned char*>(in_data);
34         stream.avail_in = in_size;
35         stream.next_out = out_data;
36         stream.avail_out = out_size;
37         stream.zalloc = (alloc_func)Z_NULL;
38         stream.zfree = (free_func)Z_NULL;
39         stream.opaque = Z_NULL;
40
41         /* !! ZLIB UNDOCUMENTED FEATURE !! (used in gzio.c module )
42          * windowBits is passed < 0 to tell that there is no zlib header.
43          * Note that in this case inflate *requires* an extra "dummy" byte
44          * after the compressed stream in order to complete decompression and
45          * return Z_STREAM_END.
46          */
47         /* The zlib code effectively READ the dummy byte,
48          * this imply that the pointer MUST point to a valid data region.
49          * The dummy byte is not always needed, only if inflate return Z_OK
50          * instead of Z_STREAM_END.
51          */
52
53         if (inflateInit2(&stream,-15) != Z_OK) {
54                 return false;
55         }
56
57         int err = inflate(&stream, Z_SYNC_FLUSH);
58
59         if (err == Z_OK) {
60                 /* dummy byte */
61                 unsigned char dummy = 0;
62                 stream.next_in = &dummy;
63                 stream.avail_in = 1;
64
65                 err = inflate(&stream, Z_SYNC_FLUSH);
66         }
67
68         if (err != Z_STREAM_END || stream.total_in != in_size || stream.total_out != out_size) {
69                 inflateEnd(&stream);
70                 return false;
71         }
72
73         if (inflateEnd(&stream) != Z_OK) {
74                 return false;
75         }
76
77         return true;
78 }
79
80 bool compress_deflate_zlib(const unsigned char* in_data, unsigned in_size, unsigned char* out_data, unsigned& out_size, int compression_level, int strategy, int mem_level) {
81         z_stream stream;
82
83         stream.next_in = const_cast<unsigned char*>(in_data);
84         stream.avail_in = in_size;
85         stream.next_out = out_data;
86         stream.avail_out = out_size;
87         stream.zalloc = Z_NULL;
88         stream.zfree = Z_NULL;
89         stream.opaque = Z_NULL;
90
91         int compression_window;
92         unsigned required_window = in_size;
93
94         // don't use the 8 bit window due a bug in the zlib 1.1.3 and previous
95         if (required_window <= 512) compression_window = 9;
96         else if (required_window <= 1024) compression_window = 10;
97         else if (required_window <= 2048) compression_window = 11;
98         else if (required_window <= 4096) compression_window = 12;
99         else if (required_window <= 8192) compression_window = 13;
100         else if (required_window <= 16384) compression_window = 14;
101         else compression_window = 15;
102
103         if (compression_window > MAX_WBITS)
104                 compression_window = MAX_WBITS;
105
106         /* windowBits is passed < 0 to suppress the zlib header */
107         if (deflateInit2(&stream, compression_level, Z_DEFLATED, -compression_window, mem_level, strategy) != Z_OK) {
108                 return false;
109         }
110
111         if (deflate(&stream, Z_FINISH) != Z_STREAM_END) {
112                 deflateEnd(&stream);
113                 return false;
114         }
115
116         out_size = stream.total_out;
117
118         deflateEnd(&stream);
119
120         return true;
121 }
122
123 bool decompress_rfc1950_zlib(const unsigned char* in_data, unsigned in_size, unsigned char* out_data, unsigned out_size)
124 {
125         unsigned long size = out_size;
126
127         if (uncompress(out_data, &size, in_data, in_size) != Z_OK)
128                 return false;
129
130         if (size != out_size)
131                 return false;
132
133         return true;
134 }
135
136 bool compress_rfc1950_zlib(const unsigned char* in_data, unsigned in_size, unsigned char* out_data, unsigned& out_size, int compression_level, int strategy, int mem_level)
137 {
138         z_stream stream;
139
140         stream.next_in = const_cast<unsigned char*>(in_data);
141         stream.avail_in = in_size;
142         stream.next_out = out_data;
143         stream.avail_out = out_size;
144         stream.zalloc = Z_NULL;
145         stream.zfree = Z_NULL;
146         stream.opaque = Z_NULL;
147
148         int compression_window;
149         unsigned required_window = in_size;
150
151         // don't use the 8 bit window due a bug in the zlib 1.1.3 and previous
152         if (required_window <= 512) compression_window = 9;
153         else if (required_window <= 1024) compression_window = 10;
154         else if (required_window <= 2048) compression_window = 11;
155         else if (required_window <= 4096) compression_window = 12;
156         else if (required_window <= 8192) compression_window = 13;
157         else if (required_window <= 16384) compression_window = 14;
158         else compression_window = 15;
159
160         if (compression_window > MAX_WBITS)
161                 compression_window = MAX_WBITS;
162
163         if (deflateInit2(&stream, compression_level, Z_DEFLATED, compression_window, mem_level, strategy) != Z_OK) {
164                 return false;
165         }
166
167         if (deflate(&stream, Z_FINISH) != Z_STREAM_END) {
168                 deflateEnd(&stream);
169                 return false;
170         }
171
172         out_size = stream.total_out;
173
174         deflateEnd(&stream);
175
176         return true;
177 }
178
179 #ifdef USE_BZIP2
180 bool compress_bzip2(const unsigned char* in_data, unsigned in_size, unsigned char* out_data, unsigned& out_size, int blocksize, int workfactor) {
181         return BZ2_bzBuffToBuffCompress(out_data,&out_size,const_cast<unsigned char*>(in_data),in_size,blocksize,0,workfactor) == BZ_OK;
182 }
183
184 bool decompress_bzip2(const unsigned char* in_data, unsigned in_size, unsigned char* out_data, unsigned out_size) {
185         unsigned size = out_size;
186
187         if (BZ2_bzBuffToBuffDecompress(out_data,&size,const_cast<unsigned char*>(in_data),in_size,0,0)!=BZ_OK)
188                 return false;
189
190         if (size != out_size)
191                 return false;
192
193         return true;
194 }
195 #endif
196
197 bool compress_zlib(shrink_t level, unsigned char* out_data, unsigned& out_size, const unsigned char* in_data, unsigned in_size) {
198 #if defined(USE_7Z)
199         if (level == shrink_normal || level == shrink_extra || level == shrink_extreme) {
200                 unsigned sz_passes;
201                 unsigned sz_fastbytes;
202
203                 switch (level) {
204                 case shrink_normal :
205                         sz_passes = 1;
206                         sz_fastbytes = 64;
207                         break;
208                 case shrink_extra :
209                         sz_passes = 3;
210                         sz_fastbytes = 128;
211                         break;
212                 case shrink_extreme :
213                         sz_passes = 5;
214                         sz_fastbytes = 255;
215                         break;
216                 default:
217                         assert(0);
218                 }
219
220                 if (!compress_rfc1950_7z(in_data,in_size,out_data,out_size,sz_passes,sz_fastbytes)) {
221                         return false;
222                 }
223
224                 return true;
225         }
226 #endif
227
228         int libz_level = Z_BEST_COMPRESSION;
229
230         switch (level) {
231         case shrink_none :
232                 libz_level = Z_NO_COMPRESSION;
233                 break;
234         case shrink_fast :
235                 libz_level = Z_DEFAULT_COMPRESSION;
236                 break;
237         case shrink_normal :
238                 libz_level = Z_DEFAULT_COMPRESSION;
239                 break;
240         case shrink_extra :
241                 libz_level = Z_BEST_COMPRESSION;
242                 break;
243         case shrink_extreme :
244                 libz_level = Z_BEST_COMPRESSION;
245                 break;
246         }
247
248         if (!compress_rfc1950_zlib(in_data,in_size,out_data,out_size,libz_level,Z_DEFAULT_STRATEGY,MAX_MEM_LEVEL)) {
249                 return false;
250         }
251
252         return true;
253 }
254
255 bool compress_deflate(shrink_t level, unsigned char* out_data, unsigned& out_size, const unsigned char* in_data, unsigned in_size) {
256 #if defined(USE_7Z)
257         if (level == shrink_normal || level == shrink_extra || level == shrink_extreme) {
258                 unsigned sz_passes;
259                 unsigned sz_fastbytes;
260
261                 switch (level) {
262                 case shrink_normal :
263                         sz_passes = 1;
264                         sz_fastbytes = 64;
265                         break;
266                 case shrink_extra :
267                         sz_passes = 3;
268                         sz_fastbytes = 128;
269                         break;
270                 case shrink_extreme :
271                         sz_passes = 5;
272                         sz_fastbytes = 255;
273                         break;
274                 default:
275                         assert(0);
276                 }
277
278                 if (!compress_deflate_7z(in_data,in_size,out_data,out_size,sz_passes,sz_fastbytes)) {
279                         return false;
280                 }
281
282                 return true;
283         }
284 #endif
285
286         int libz_level = Z_BEST_COMPRESSION;
287
288         switch (level) {
289         case shrink_none :
290                 libz_level = Z_NO_COMPRESSION;
291                 break;
292         case shrink_fast :
293                 libz_level = Z_DEFAULT_COMPRESSION;
294                 break;
295         case shrink_normal :
296                 libz_level = Z_DEFAULT_COMPRESSION;
297                 break;
298         case shrink_extra :
299                 libz_level = Z_BEST_COMPRESSION;
300                 break;
301         case shrink_extreme :
302                 libz_level = Z_BEST_COMPRESSION;
303                 break;
304         }
305
306         if (!compress_deflate_zlib(in_data,in_size,out_data,out_size,libz_level,Z_DEFAULT_STRATEGY,MAX_MEM_LEVEL)) {
307                 return false;
308         }
309
310         return true;
311 }
312
313 unsigned oversize_deflate(unsigned size) {
314         return size * 11 / 10 + 12;
315 }
316
317 unsigned oversize_zlib(unsigned size) {
318         return oversize_deflate(size) + 10;
319 }
320
Note: See TracBrowser for help on using the browser.