inflate.c (1902B)
1 /* $Id$ */ 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <zlib.h> 5 6 #undef BUFSIZE 7 #define BUFSIZE 4096 8 9 static char dummy_head[1 + 1] = { 10 0x8 + 0x7 * 0x10, 11 (((0x8 + 0x7 * 0x10) * 0x100 + 30) / 31 * 31) & 0xFF, 12 }; 13 14 int 15 main(int argc, char **argv) 16 { 17 z_stream s; 18 FILE *f; 19 char inbuf[BUFSIZE], outbuf[BUFSIZE]; 20 int status, flush, retry = 0, len = 0; 21 22 if (argc > 1) { 23 f = fopen(argv[1], "rb"); 24 if (!f) { 25 fprintf(stderr, "%s: cannot open %s\n", argv[0], argv[1]); 26 exit(1); 27 } 28 } 29 else 30 f = stdin; 31 32 s.zalloc = Z_NULL; 33 s.zfree = Z_NULL; 34 s.opaque = Z_NULL; 35 status = inflateInit(&s); 36 if (status != Z_OK) { 37 fprintf(stderr, "%s: inflateInit() %s\n", argv[0], zError(status)); 38 exit(1); 39 } 40 s.avail_in = 0; 41 s.next_out = (Bytef *) outbuf; 42 s.avail_out = sizeof(outbuf); 43 flush = Z_NO_FLUSH; 44 while (1) { 45 if (s.avail_in == 0) { 46 s.next_in = (Bytef *) inbuf; 47 len = s.avail_in = fread(inbuf, 1, sizeof(inbuf), f); 48 } 49 status = inflate(&s, flush); 50 if (status == Z_STREAM_END || status == Z_BUF_ERROR) { 51 if (sizeof(outbuf) - s.avail_out) 52 fwrite(outbuf, 1, sizeof(outbuf) - s.avail_out, stdout); 53 break; 54 } 55 if (status == Z_DATA_ERROR && !retry++) { 56 status = inflateReset(&s); 57 if (status != Z_OK) { 58 fprintf(stderr, "%s: inflateReset() %s\n", argv[0], 59 zError(status)); 60 exit(1); 61 } 62 s.next_in = (Bytef *) dummy_head; 63 s.avail_in = sizeof(dummy_head); 64 status = inflate(&s, flush); 65 s.next_in = (Bytef *) inbuf; 66 s.avail_in = len; 67 continue; 68 } 69 if (status != Z_OK) { 70 fprintf(stderr, "%s: inflate() %s\n", argv[0], zError(status)); 71 exit(1); 72 } 73 if (s.avail_out == 0) { 74 fwrite(outbuf, 1, sizeof(outbuf), stdout); 75 s.next_out = (Bytef *) outbuf; 76 s.avail_out = sizeof(outbuf); 77 } 78 retry = 1; 79 } 80 inflateEnd(&s); 81 fclose(f); 82 return 0; 83 }