Intial commit
[profile/ivi/w3m.git] / inflate.c
1 /* $Id: inflate.c,v 1.7 2002/01/31 18:28:24 ukai Exp $ */
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 }