Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
7640 views
1
#include "mupdf/fitz.h"
2
3
#include <zlib.h>
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
unsigned char buffer[4096];
12
};
13
14
static void *zalloc(void *opaque, unsigned int items, unsigned int size)
15
{
16
return fz_malloc_array_no_throw(opaque, items, size);
17
}
18
19
static void zfree(void *opaque, void *ptr)
20
{
21
fz_free(opaque, ptr);
22
}
23
24
static int
25
next_flated(fz_context *ctx, fz_stream *stm, int required)
26
{
27
fz_flate *state = stm->state;
28
fz_stream *chain = state->chain;
29
z_streamp zp = &state->z;
30
int code;
31
unsigned char *outbuf = state->buffer;
32
int outlen = sizeof(state->buffer);
33
34
if (stm->eof)
35
return EOF;
36
37
zp->next_out = outbuf;
38
zp->avail_out = outlen;
39
40
while (zp->avail_out > 0)
41
{
42
zp->avail_in = fz_available(ctx, chain, 1);
43
zp->next_in = chain->rp;
44
45
code = inflate(zp, Z_SYNC_FLUSH);
46
47
chain->rp = chain->wp - zp->avail_in;
48
49
if (code == Z_STREAM_END)
50
{
51
break;
52
}
53
else if (code == Z_BUF_ERROR)
54
{
55
fz_warn(ctx, "premature end of data in flate filter");
56
break;
57
}
58
else if (code == Z_DATA_ERROR && zp->avail_in == 0)
59
{
60
fz_warn(ctx, "ignoring zlib error: %s", zp->msg);
61
break;
62
}
63
else if (code == Z_DATA_ERROR && !strcmp(zp->msg, "incorrect data check"))
64
{
65
fz_warn(ctx, "ignoring zlib error: %s", zp->msg);
66
chain->rp = chain->wp;
67
break;
68
}
69
else if (code != Z_OK)
70
{
71
fz_throw(ctx, FZ_ERROR_GENERIC, "zlib error: %s", zp->msg);
72
}
73
}
74
75
stm->rp = state->buffer;
76
stm->wp = state->buffer + outlen - zp->avail_out;
77
stm->pos += outlen - zp->avail_out;
78
if (stm->rp == stm->wp)
79
{
80
stm->eof = 1;
81
return EOF;
82
}
83
return *stm->rp++;
84
}
85
86
static void
87
close_flated(fz_context *ctx, void *state_)
88
{
89
fz_flate *state = (fz_flate *)state_;
90
int code;
91
92
code = inflateEnd(&state->z);
93
if (code != Z_OK)
94
fz_warn(ctx, "zlib error: inflateEnd: %s", state->z.msg);
95
96
fz_drop_stream(ctx, state->chain);
97
fz_free(ctx, state);
98
}
99
100
fz_stream *
101
fz_open_flated(fz_context *ctx, fz_stream *chain, int window_bits)
102
{
103
fz_flate *state = NULL;
104
int code = Z_OK;
105
106
fz_var(code);
107
fz_var(state);
108
109
fz_try(ctx)
110
{
111
state = fz_malloc_struct(ctx, fz_flate);
112
state->chain = chain;
113
114
state->z.zalloc = zalloc;
115
state->z.zfree = zfree;
116
state->z.opaque = ctx;
117
state->z.next_in = NULL;
118
state->z.avail_in = 0;
119
120
code = inflateInit2(&state->z, window_bits);
121
if (code != Z_OK)
122
fz_throw(ctx, FZ_ERROR_GENERIC, "zlib error: inflateInit: %s", state->z.msg);
123
}
124
fz_catch(ctx)
125
{
126
if (state && code == Z_OK)
127
inflateEnd(&state->z);
128
fz_free(ctx, state);
129
fz_drop_stream(ctx, chain);
130
fz_rethrow(ctx);
131
}
132
return fz_new_stream(ctx, state, next_flated, close_flated);
133
}
134
135