Rev 4680 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4680 | right-hear | 1 | #include "fitz.h" |
2 | |||
3 | #include |
||
4 | |||
5 | typedef struct fz_flate_s fz_flate; |
||
6 | |||
7 | struct fz_flate_s |
||
8 | { |
||
9 | fz_stream *chain; |
||
10 | z_stream z; |
||
11 | }; |
||
12 | |||
13 | static void *zalloc(void *opaque, unsigned int items, unsigned int size) |
||
14 | { |
||
15 | return fz_calloc(items, size); |
||
16 | } |
||
17 | |||
18 | static void zfree(void *opaque, void *ptr) |
||
19 | { |
||
20 | fz_free(ptr); |
||
21 | } |
||
22 | |||
23 | static int |
||
24 | read_flated(fz_stream *stm, unsigned char *outbuf, int outlen) |
||
25 | { |
||
26 | fz_flate *state = stm->state; |
||
27 | fz_stream *chain = state->chain; |
||
28 | z_streamp zp = &state->z; |
||
29 | int code; |
||
30 | |||
31 | zp->next_out = outbuf; |
||
32 | zp->avail_out = outlen; |
||
33 | |||
34 | while (zp->avail_out > 0) |
||
35 | { |
||
36 | if (chain->rp == chain->wp) |
||
37 | fz_fill_buffer(chain); |
||
38 | |||
39 | zp->next_in = chain->rp; |
||
40 | zp->avail_in = chain->wp - chain->rp; |
||
41 | |||
42 | code = inflate(zp, Z_SYNC_FLUSH); |
||
43 | |||
44 | chain->rp = chain->wp - zp->avail_in; |
||
45 | |||
46 | if (code == Z_STREAM_END) |
||
47 | { |
||
48 | return outlen - zp->avail_out; |
||
49 | } |
||
50 | else if (code == Z_BUF_ERROR) |
||
51 | { |
||
52 | fz_warn("premature end of data in flate filter"); |
||
53 | return outlen - zp->avail_out; |
||
54 | } |
||
55 | else if (code == Z_DATA_ERROR && zp->avail_in == 0) |
||
56 | { |
||
57 | fz_warn("ignoring zlib error: %s", zp->msg); |
||
58 | return outlen - zp->avail_out; |
||
59 | } |
||
60 | else if (code != Z_OK) |
||
61 | { |
||
62 | return fz_throw("zlib error: %s", zp->msg); |
||
63 | } |
||
64 | } |
||
65 | |||
66 | return outlen - zp->avail_out; |
||
67 | } |
||
68 | |||
69 | static void |
||
70 | close_flated(fz_stream *stm) |
||
71 | { |
||
72 | fz_flate *state = stm->state; |
||
73 | int code; |
||
74 | |||
75 | code = inflateEnd(&state->z); |
||
76 | if (code != Z_OK) |
||
77 | fz_warn("zlib error: inflateEnd: %s", state->z.msg); |
||
78 | |||
79 | fz_close(state->chain); |
||
80 | fz_free(state); |
||
81 | } |
||
82 | |||
83 | fz_stream * |
||
84 | fz_open_flated(fz_stream *chain) |
||
85 | { |
||
86 | fz_flate *state; |
||
87 | int code; |
||
88 | |||
89 | state = fz_malloc(sizeof(fz_flate)); |
||
90 | state->chain = chain; |
||
91 | |||
92 | state->z.zalloc = zalloc; |
||
93 | state->z.zfree = zfree; |
||
94 | state->z.opaque = NULL; |
||
95 | state->z.next_in = NULL; |
||
96 | state->z.avail_in = 0; |
||
97 | |||
98 | code = inflateInit(&state->z); |
||
99 | if (code != Z_OK) |
||
100 | fz_warn("zlib error: inflateInit: %s", state->z.msg); |
||
101 | |||
102 | return fz_new_stream(state, read_flated, close_flated); |
||
103 | } |