1 /* $Id: compress.c 119 2004-10-05 20:38:42Z oyvind $
4 Revision 1.1 2004/10/05 20:31:35 oyvind
5 * added GCC to repository
7 Revision 1.2 2000/12/14 18:45:35 ghazi
10 * compress.c: Include stdlib.h and compress.h.
12 (report_str_error): Make static.
13 (ez_inflate_str): Delete unused variable. Add parens in if-stmt.
14 (hrd_inflate_str): Likewise.
16 * compress.h (init_compression, end_compression, init_inflation,
17 end_inflation): Prototype void arguments.
19 * dostime.c (rcsid): Delete.
21 * jargrep.c: Include ctype.h, stdlib.h, zlib.h and compress.h.
22 Make functions static. Cast ctype function argument to `unsigned
23 char'. Add parens in if-stmts. Constify.
24 (Usage): Change into a macro.
25 (jargrep): Remove unused parameter.
27 * jartool.c: Constify. Add parens in if-stmts. Align
28 signed/unsigned char pointers in functions calls using casts.
30 (list_jar): Fix printf format specifier.
31 (usage): Chop long string into bits. Reformat.
33 * pushback.c (rcsid): Delete.
35 Revision 1.1 2000/12/09 03:08:23 apbianco
36 2000-12-08 Alexandre Petit-Bianco <apbianco@cygnus.com>
40 Revision 1.7 2000/09/13 14:02:02 cory
41 Reformatted some of the code to more closly match the layout of the orriginal
44 Revision 1.6 2000/09/12 22:29:36 cory
45 Jargrep now seems to do what I want it to do. Performs properly on Linux x86,
46 will test some other platforms later.
48 Revision 1.1.1.1 1999/12/06 03:09:16 toast
53 Revision 1.7 1999/05/10 08:50:05 burnsbr
54 *** empty log message ***
56 Revision 1.6 1999/05/10 08:38:44 burnsbr
57 *** empty log message ***
59 Revision 1.5 1999/05/10 08:30:29 burnsbr
62 Revision 1.4 1999/04/27 10:03:33 burnsbr
63 added configure support
65 Revision 1.3 1999/04/26 02:35:32 burnsbr
66 compression now works.. yahoo
68 Revision 1.2 1999/04/23 12:01:59 burnsbr
71 Revision 1.1 1999/04/23 11:58:25 burnsbr
78 compress.c - code for handling deflation
79 Copyright (C) 1999 Bryan Burns
81 This program is free software; you can redistribute it and/or
82 modify it under the terms of the GNU General Public License
83 as published by the Free Software Foundation; either version 2
84 of the License, or (at your option) any later version.
86 This program is distributed in the hope that it will be useful,
87 but WITHOUT ANY WARRANTY; without even the implied warranty of
88 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
89 GNU General Public License for more details.
91 You should have received a copy of the GNU General Public License
92 along with this program; if not, write to the Free Software
93 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
110 #include <sys/types.h>
113 #include "pushback.h"
114 #include "compress.h"
120 void init_compression(){
122 memset(&zs
, 0, sizeof(z_stream
));
128 /* Why -MAX_WBITS? zlib has an undocumented feature, where if the windowbits
129 parameter is negative, it omits the zlib header, which seems to kill
130 any other zip/unzip program. This caused me SO much pain.. */
131 if(deflateInit2(&zs
, Z_DEFAULT_COMPRESSION
, Z_DEFLATED
, -MAX_WBITS
,
132 9, Z_DEFAULT_STRATEGY
) != Z_OK
){
134 fprintf(stderr
, "Error initializing deflation!\n");
139 int compress_file(int in_fd
, int out_fd
, struct zipentry
*ze
){
141 Bytef out_buff
[RDSZ
];
142 unsigned int rdamt
, wramt
;
143 unsigned long tr
= 0;
149 zs
.next_in
= in_buff
;
151 zs
.next_out
= out_buff
;
152 zs
.avail_out
= (uInt
)RDSZ
;
154 ze
->crc
= crc32(0L, Z_NULL
, 0);
158 /* If deflate is out of input, fill the input buffer for it */
159 if(zs
.avail_in
== 0 && zs
.avail_out
> 0){
160 if((rtval
= read(in_fd
, in_buff
, RDSZ
)) == 0)
170 /* compute the CRC while we're at it */
171 ze
->crc
= crc32(ze
->crc
, in_buff
, rdamt
);
173 /* update the total amount read sofar */
176 zs
.next_in
= in_buff
;
180 /* deflate the data */
181 if(deflate(&zs
, 0) != Z_OK
){
182 fprintf(stderr
, "Error deflating! %s:%d\n", __FILE__
, __LINE__
);
186 /* If the output buffer is full, dump it to disk */
187 if(zs
.avail_out
== 0){
189 if(write(out_fd
, out_buff
, RDSZ
) != RDSZ
){
194 /* clear the output buffer */
195 zs
.next_out
= out_buff
;
196 zs
.avail_out
= (uInt
)RDSZ
;
201 /* If we have any data waiting in the buffer after we're done with the file
203 if(zs
.avail_out
< RDSZ
){
205 wramt
= RDSZ
- zs
.avail_out
;
207 if(write(out_fd
, out_buff
, wramt
) != (int)wramt
){
211 /* clear the output buffer */
212 zs
.next_out
= out_buff
;
213 zs
.avail_out
= (uInt
)RDSZ
;
217 /* finish deflation. This purges zlib's internal data buffers */
218 while(deflate(&zs
, Z_FINISH
) == Z_OK
){
219 wramt
= RDSZ
- zs
.avail_out
;
221 if(write(out_fd
, out_buff
, wramt
) != (int)wramt
){
226 zs
.next_out
= out_buff
;
227 zs
.avail_out
= (uInt
)RDSZ
;
230 /* If there's any data left in the buffer, write it out */
231 if(zs
.avail_out
!= RDSZ
){
232 wramt
= RDSZ
- zs
.avail_out
;
234 if(write(out_fd
, out_buff
, wramt
) != (int)wramt
){
240 /* update fastjar's entry information */
241 ze
->usize
= (ub4
)zs
.total_in
;
242 ze
->csize
= (ub4
)zs
.total_out
;
244 /* Reset the deflation for the next time around */
245 if(deflateReset(&zs
) != Z_OK
){
246 fprintf(stderr
, "Error resetting deflation\n");
253 void end_compression(){
256 /* Oddly enough, zlib always returns Z_DATA_ERROR if you specify no
257 zlib header. Go fig. */
258 if((rtval
= deflateEnd(&zs
)) != Z_OK
&& rtval
!= Z_DATA_ERROR
){
259 fprintf(stderr
, "Error calling deflateEnd\n");
260 fprintf(stderr
, "error: (%d) %s\n", rtval
, zs
.msg
);
266 void init_inflation(){
268 memset(&zs
, 0, sizeof(z_stream
));
274 if(inflateInit2(&zs
, -15) != Z_OK
){
275 fprintf(stderr
, "Error initializing deflation!\n");
281 int inflate_file(pb_file
*pbf
, int out_fd
, struct zipentry
*ze
){
283 Bytef out_buff
[RDSZ
];
290 crc
= crc32(crc
, NULL
, 0); /* initialize crc */
292 /* loop until we've consumed all the compressed data */
295 if(zs
.avail_in
== 0){
296 if((rdamt
= pb_read(pbf
, in_buff
, RDSZ
)) == 0)
298 else if((int)rdamt
< 0){
304 printf("%d bytes read\n", rdamt
);
307 zs
.next_in
= in_buff
;
311 zs
.next_out
= out_buff
;
314 if((rtval
= inflate(&zs
, 0)) != Z_OK
){
315 if(rtval
== Z_STREAM_END
){
317 printf("end of stream\n");
319 if(zs
.avail_out
!= RDSZ
){
320 crc
= crc32(crc
, out_buff
, (RDSZ
- zs
.avail_out
));
323 if(write(out_fd
, out_buff
, (RDSZ
- zs
.avail_out
)) !=
324 (int)(RDSZ
- zs
.avail_out
)){
332 fprintf(stderr
, "Error inflating file! (%d)\n", rtval
);
336 if(zs
.avail_out
!= RDSZ
){
337 crc
= crc32(crc
, out_buff
, (RDSZ
- zs
.avail_out
));
340 if(write(out_fd
, out_buff
, (RDSZ
- zs
.avail_out
)) !=
341 (int)(RDSZ
- zs
.avail_out
)){
345 zs
.next_out
= out_buff
;
351 printf("done inflating\n");
355 printf("%d bytes left over\n", zs
.avail_in
);
359 printf("CRC is %x\n", crc
);
364 pb_push(pbf
, zs
.next_in
, zs
.avail_in
);
366 ze
->usize
= zs
.total_out
;
373 Function name: report_str_error
374 args: val Error code returned from zlib.
375 purpose: Put out an error message corresponding to error code returned from zlib.
376 Be suitably cryptic seeing I don't really know exactly what these errors mean.
379 static void report_str_error(int val
) {
384 fprintf(stderr
, "Need a dictionary?\n");
387 fprintf(stderr
, "Z_DATA_ERROR\n");
390 fprintf(stderr
, "Z_STREAM_ERROR\n");
393 fprintf(stderr
, "Z_MEM_ERROR\n");
396 fprintf(stderr
, "Z_BUF_ERROR\n");
401 fprintf(stderr
, "Unknown behavior from inflate\n");
407 Function name: ez_inflate_str
408 args: pbf Pointer to pushback handle for file.
409 csize Compressed size of embedded file.
410 usize Uncompressed size of embedded file.
411 purpose: Read in and decompress the contents of an embedded file and store it in a
413 returns: Byte array of uncompressed embedded file.
416 static Bytef
*ez_inflate_str(pb_file
*pbf
, ub4 csize
, ub4 usize
) {
421 if((zs
.next_in
= in_buff
= (Bytef
*) malloc(csize
))) {
422 if((zs
.next_out
= out_buff
= (Bytef
*) malloc(usize
+ 1))) {
423 if((rdamt
= pb_read(pbf
, zs
.next_in
, csize
)) == csize
) {
425 zs
.avail_out
= usize
;
426 report_str_error(inflate(&zs
, 0));
429 out_buff
[usize
] = '\0';
432 fprintf(stderr
, "Read failed on input file.\n");
433 fprintf(stderr
, "Tried to read %u but read %u instead.\n", csize
, rdamt
);
440 fprintf(stderr
, "Malloc of out_buff failed.\n");
441 fprintf(stderr
, "Error: %s\n", strerror(errno
));
447 fprintf(stderr
, "Malloc of in_buff failed.\n");
448 fprintf(stderr
, "Error: %s\n", strerror(errno
));
456 Function name: hrd_inflate_str
457 args: pbf Pointer to pushback handle for file.
458 csize Pointer to compressed size of embedded file.
459 usize Pointer to uncompressed size of embedded file.
460 purpose: Read and decompress an embedded file into a string. Set csize and usize
461 accordingly. This function does the reading for us in the case there is not size
462 information in the header for the embedded file.
463 returns: Byte array of the contents of the embedded file.
466 static Bytef
*hrd_inflate_str(pb_file
*pbf
, ub4
*csize
, ub4
*usize
) {
477 while(zret
!= Z_STREAM_END
&& (rdamt
= pb_read(pbf
, in_buff
, RDSZ
)))
481 zs
.next_in
= in_buff
;
483 if((tmp
= (Bytef
*) realloc(out_buff
, (RDSZ
* i
) + 1))) {
485 zs
.next_out
= &(out_buff
[(RDSZ
* (i
- 1)) - zs
.avail_out
]);
486 zs
.avail_out
+= RDSZ
;
490 fprintf(stderr
, "Realloc of out_buff failed.\n");
491 fprintf(stderr
, "Error: %s\n", strerror(errno
));
494 } while((zret
= inflate(&zs
, 0)) == Z_OK
);
495 report_str_error(zret
);
497 pb_push(pbf
, zs
.next_in
, zs
.avail_in
);
499 out_buff
[(RDSZ
* (i
- 1)) - zs
.avail_out
] = '\0';
500 *usize
= zs
.total_out
;
501 *csize
= zs
.total_in
;
509 Function name: inflate_string
510 args: pbf Pointer to pushback handle for file.
511 csize Pointer to compressed size of embedded file. May be 0 if not set.
512 usize Pointer to uncompressed size of embedded file. May be 0 if not set.
513 purpose: Decide the easiest (in computer terms) methos of decompressing this embedded
515 returns: Pointer to a string containing the decompressed contents of the embedded file.
516 If csize and usize are not set set them to correct numbers.
519 Bytef
*inflate_string(pb_file
*pbf
, ub4
*csize
, ub4
*usize
) {
522 if(*csize
&& *usize
) ret_buf
= ez_inflate_str(pbf
, *csize
, *usize
);
523 else ret_buf
= hrd_inflate_str(pbf
, csize
, usize
);