1 | #include "mupdf/fitz.h" |
2 | |
3 | #include <zlib.h> |
4 | |
5 | /* |
6 | Compression and other filtering outputs. |
7 | |
8 | These outputs write encoded data to another output. Create a filter |
9 | output with the destination, write to the filter, then close and drop |
10 | it when you're done. These can also be chained together, for example to |
11 | write ASCII Hex encoded, Deflate compressed, and RC4 encrypted data to |
12 | a buffer output. |
13 | |
14 | Output streams don't use reference counting, so make sure to close all |
15 | of the filters in the reverse order of creation so that data is flushed |
16 | properly. |
17 | */ |
18 | |
19 | struct ahx |
20 | { |
21 | fz_output *chain; |
22 | int column; |
23 | }; |
24 | |
25 | static void ahx_write(fz_context *ctx, void *opaque, const void *data, size_t n) |
26 | { |
27 | static const char tohex[16] = "0123456789ABCDEF" ; |
28 | struct ahx *state = opaque; |
29 | const unsigned char *p = data; |
30 | while (n-- > 0) |
31 | { |
32 | int c = *p++; |
33 | fz_write_byte(ctx, state->chain, tohex[(c>>4) & 15]); |
34 | fz_write_byte(ctx, state->chain, tohex[(c) & 15]); |
35 | state->column += 2; |
36 | if (state->column == 64) |
37 | { |
38 | fz_write_byte(ctx, state->chain, '\n'); |
39 | state->column = 0; |
40 | } |
41 | } |
42 | } |
43 | |
44 | static void ahx_close(fz_context *ctx, void *opaque) |
45 | { |
46 | struct ahx *state = opaque; |
47 | fz_write_byte(ctx, state->chain, '>'); |
48 | } |
49 | |
50 | static void ahx_drop(fz_context *ctx, void *opaque) |
51 | { |
52 | struct ahx *state = opaque; |
53 | fz_free(ctx, state); |
54 | } |
55 | |
56 | fz_output * |
57 | fz_new_asciihex_output(fz_context *ctx, fz_output *chain) |
58 | { |
59 | struct ahx *state = fz_malloc_struct(ctx, struct ahx); |
60 | state->chain = chain; |
61 | state->column = 0; |
62 | return fz_new_output(ctx, 512, state, ahx_write, ahx_close, ahx_drop); |
63 | } |
64 | |
65 | struct a85 |
66 | { |
67 | fz_output *chain; |
68 | int column; |
69 | unsigned int word, n; |
70 | }; |
71 | |
72 | static void a85_flush(fz_context *ctx, struct a85 *state) |
73 | { |
74 | unsigned int v1, v2, v3, v4, v5; |
75 | |
76 | v5 = state->word; |
77 | v4 = v5 / 85; |
78 | v3 = v4 / 85; |
79 | v2 = v3 / 85; |
80 | v1 = v2 / 85; |
81 | |
82 | if (state->column >= 70) |
83 | { |
84 | fz_write_byte(ctx, state->chain, '\n'); |
85 | state->column = 0; |
86 | } |
87 | |
88 | if (state->n == 4) |
89 | { |
90 | if (state->word == 0) |
91 | { |
92 | fz_write_byte(ctx, state->chain, 'z'); |
93 | state->column += 1; |
94 | } |
95 | else |
96 | { |
97 | fz_write_byte(ctx, state->chain, (v1 % 85) + '!'); |
98 | fz_write_byte(ctx, state->chain, (v2 % 85) + '!'); |
99 | fz_write_byte(ctx, state->chain, (v3 % 85) + '!'); |
100 | fz_write_byte(ctx, state->chain, (v4 % 85) + '!'); |
101 | fz_write_byte(ctx, state->chain, (v5 % 85) + '!'); |
102 | state->column += 5; |
103 | } |
104 | } |
105 | else if (state->n == 3) |
106 | { |
107 | fz_write_byte(ctx, state->chain, (v2 % 85) + '!'); |
108 | fz_write_byte(ctx, state->chain, (v3 % 85) + '!'); |
109 | fz_write_byte(ctx, state->chain, (v4 % 85) + '!'); |
110 | fz_write_byte(ctx, state->chain, (v5 % 85) + '!'); |
111 | state->column += 4; |
112 | } |
113 | else if (state->n == 2) |
114 | { |
115 | fz_write_byte(ctx, state->chain, (v3 % 85) + '!'); |
116 | fz_write_byte(ctx, state->chain, (v4 % 85) + '!'); |
117 | fz_write_byte(ctx, state->chain, (v5 % 85) + '!'); |
118 | state->column += 3; |
119 | } |
120 | else if (state->n == 1) |
121 | { |
122 | fz_write_byte(ctx, state->chain, (v4 % 85) + '!'); |
123 | fz_write_byte(ctx, state->chain, (v5 % 85) + '!'); |
124 | state->column += 2; |
125 | } |
126 | |
127 | state->word = 0; |
128 | state->n = 0; |
129 | } |
130 | |
131 | static void a85_write(fz_context *ctx, void *opaque, const void *data, size_t n) |
132 | { |
133 | struct a85 *state = opaque; |
134 | const unsigned char *p = data; |
135 | while (n-- > 0) |
136 | { |
137 | unsigned int c = *p++; |
138 | if (state->n == 4) |
139 | a85_flush(ctx, state); |
140 | state->word = (state->word << 8) | c; |
141 | state->n++; |
142 | } |
143 | } |
144 | |
145 | static void a85_close(fz_context *ctx, void *opaque) |
146 | { |
147 | struct a85 *state = opaque; |
148 | a85_flush(ctx, state); |
149 | fz_write_byte(ctx, state->chain, '~'); |
150 | fz_write_byte(ctx, state->chain, '>'); |
151 | } |
152 | |
153 | static void a85_drop(fz_context *ctx, void *opaque) |
154 | { |
155 | struct a85 *state = opaque; |
156 | fz_free(ctx, state); |
157 | } |
158 | |
159 | fz_output * |
160 | fz_new_ascii85_output(fz_context *ctx, fz_output *chain) |
161 | { |
162 | struct a85 *state = fz_malloc_struct(ctx, struct a85); |
163 | state->chain = chain; |
164 | state->column = 0; |
165 | state->word = 0; |
166 | state->n = 0; |
167 | return fz_new_output(ctx, 512, state, a85_write, a85_close, a85_drop); |
168 | } |
169 | |
170 | struct rle |
171 | { |
172 | fz_output *chain; |
173 | int state; |
174 | int run; |
175 | unsigned char buf[128]; |
176 | }; |
177 | |
178 | enum { ZERO, ONE, DIFF, SAME }; |
179 | |
180 | static void rle_flush_same(fz_context *ctx, struct rle *enc) |
181 | { |
182 | fz_write_byte(ctx, enc->chain, 257 - enc->run); |
183 | fz_write_byte(ctx, enc->chain, enc->buf[0]); |
184 | } |
185 | |
186 | static void rle_flush_diff(fz_context *ctx, struct rle *enc) |
187 | { |
188 | fz_write_byte(ctx, enc->chain, enc->run - 1); |
189 | fz_write_data(ctx, enc->chain, enc->buf, enc->run); |
190 | } |
191 | |
192 | static void rle_write(fz_context *ctx, void *opaque, const void *data, size_t n) |
193 | { |
194 | struct rle *enc = opaque; |
195 | const unsigned char *p = data; |
196 | while (n-- > 0) |
197 | { |
198 | int c = *p++; |
199 | switch (enc->state) |
200 | { |
201 | case ZERO: |
202 | enc->state = ONE; |
203 | enc->run = 1; |
204 | enc->buf[0] = c; |
205 | break; |
206 | |
207 | case ONE: |
208 | enc->state = DIFF; |
209 | enc->run = 2; |
210 | enc->buf[1] = c; |
211 | break; |
212 | |
213 | case DIFF: |
214 | /* Max run length */ |
215 | if (enc->run == 128) |
216 | { |
217 | rle_flush_diff(ctx, enc); |
218 | enc->state = ONE; |
219 | enc->run = 1; |
220 | enc->buf[0] = c; |
221 | } |
222 | /* Run of three same */ |
223 | else if ((enc->run >= 2) && (c == enc->buf[enc->run-1]) && (c == enc->buf[enc->run-2])) |
224 | { |
225 | if (enc->run >= 3) { |
226 | enc->run -= 2; /* skip last two in previous run */ |
227 | rle_flush_diff(ctx, enc); |
228 | } |
229 | enc->state = SAME; |
230 | enc->run = 3; |
231 | enc->buf[0] = c; |
232 | } |
233 | else |
234 | { |
235 | enc->buf[enc->run] = c; |
236 | enc->run++; |
237 | } |
238 | break; |
239 | |
240 | case SAME: |
241 | if ((enc->run == 128) || (c != enc->buf[0])) |
242 | { |
243 | rle_flush_same(ctx, enc); |
244 | enc->state = ONE; |
245 | enc->run = 1; |
246 | enc->buf[0] = c; |
247 | } |
248 | else |
249 | { |
250 | enc->run++; |
251 | } |
252 | } |
253 | } |
254 | } |
255 | |
256 | static void rle_close(fz_context *ctx, void *opaque) |
257 | { |
258 | struct rle *enc = opaque; |
259 | switch (enc->state) |
260 | { |
261 | case ZERO: break; |
262 | case ONE: rle_flush_diff(ctx, enc); break; |
263 | case DIFF: rle_flush_diff(ctx, enc); break; |
264 | case SAME: rle_flush_same(ctx, enc); break; |
265 | } |
266 | fz_write_byte(ctx, enc->chain, 128); |
267 | } |
268 | |
269 | static void rle_drop(fz_context *ctx, void *opaque) |
270 | { |
271 | struct rle *enc = opaque; |
272 | fz_free(ctx, enc); |
273 | } |
274 | |
275 | fz_output * |
276 | fz_new_rle_output(fz_context *ctx, fz_output *chain) |
277 | { |
278 | struct rle *enc = fz_malloc_struct(ctx, struct rle); |
279 | enc->chain = chain; |
280 | enc->state = ZERO; |
281 | enc->run = 0; |
282 | return fz_new_output(ctx, 4096, enc, rle_write, rle_close, rle_drop); |
283 | } |
284 | |
285 | struct arc4 |
286 | { |
287 | fz_output *chain; |
288 | fz_arc4 arc4; |
289 | }; |
290 | |
291 | static void arc4_write(fz_context *ctx, void *opaque, const void *data, size_t n) |
292 | { |
293 | struct arc4 *state = opaque; |
294 | const unsigned char *p = data; |
295 | unsigned char buffer[256]; |
296 | while (n > 0) |
297 | { |
298 | size_t x = (n > sizeof buffer) ? sizeof buffer : n; |
299 | fz_arc4_encrypt(&state->arc4, buffer, p, x); |
300 | fz_write_data(ctx, state->chain, buffer, x); |
301 | p += x; |
302 | n -= x; |
303 | } |
304 | } |
305 | |
306 | static void arc4_drop(fz_context *ctx, void *opaque) |
307 | { |
308 | fz_free(ctx, opaque); |
309 | } |
310 | |
311 | fz_output * |
312 | fz_new_arc4_output(fz_context *ctx, fz_output *chain, unsigned char *key, size_t keylen) |
313 | { |
314 | struct arc4 *state = fz_malloc_struct(ctx, struct arc4); |
315 | state->chain = chain; |
316 | fz_arc4_init(&state->arc4, key, keylen); |
317 | return fz_new_output(ctx, 256, state, arc4_write, NULL, arc4_drop); |
318 | } |
319 | |
320 | struct deflate |
321 | { |
322 | fz_output *chain; |
323 | z_stream z; |
324 | }; |
325 | |
326 | static void deflate_write(fz_context *ctx, void *opaque, const void *data, size_t n) |
327 | { |
328 | struct deflate *state = opaque; |
329 | unsigned char buffer[32 << 10]; |
330 | int err; |
331 | |
332 | state->z.next_in = (Bytef*)data; |
333 | state->z.avail_in = n; |
334 | do |
335 | { |
336 | state->z.next_out = buffer; |
337 | state->z.avail_out = sizeof buffer; |
338 | err = deflate(&state->z, Z_NO_FLUSH); |
339 | if (err != Z_OK) |
340 | fz_throw(ctx, FZ_ERROR_GENERIC, "zlib compression failed: %d" , err); |
341 | if (state->z.avail_out > 0) |
342 | fz_write_data(ctx, state->chain, state->z.next_out, state->z.avail_out); |
343 | } while (state->z.avail_out > 0); |
344 | } |
345 | |
346 | static void deflate_close(fz_context *ctx, void *opaque) |
347 | { |
348 | struct deflate *state = opaque; |
349 | unsigned char buffer[32 << 10]; |
350 | int err; |
351 | |
352 | state->z.next_in = NULL; |
353 | state->z.avail_in = 0; |
354 | do |
355 | { |
356 | state->z.next_out = buffer; |
357 | state->z.avail_out = sizeof buffer; |
358 | err = deflate(&state->z, Z_FINISH); |
359 | if (state->z.avail_out > 0) |
360 | fz_write_data(ctx, state->chain, state->z.next_out, state->z.avail_out); |
361 | } while (err == Z_OK); |
362 | |
363 | if (err != Z_STREAM_END) |
364 | fz_throw(ctx, FZ_ERROR_GENERIC, "zlib compression failed: %d" , err); |
365 | } |
366 | |
367 | static void deflate_drop(fz_context *ctx, void *opaque) |
368 | { |
369 | struct deflate *state = opaque; |
370 | (void)deflateEnd(&state->z); |
371 | fz_free(ctx, state); |
372 | } |
373 | |
374 | fz_output * |
375 | fz_new_deflate_output(fz_context *ctx, fz_output *chain, int effort, int raw) |
376 | { |
377 | int err; |
378 | |
379 | struct deflate *state = fz_malloc_struct(ctx, struct deflate); |
380 | state->chain = chain; |
381 | state->z.opaque = ctx; |
382 | state->z.zalloc = fz_zlib_alloc; |
383 | state->z.zfree = fz_zlib_free; |
384 | err = deflateInit2(&state->z, effort, Z_DEFLATED, raw ? -15 : 15, 8, Z_DEFAULT_STRATEGY); |
385 | if (err != Z_OK) |
386 | { |
387 | (void)deflateEnd(&state->z); |
388 | fz_free(ctx, state); |
389 | fz_throw(ctx, FZ_ERROR_GENERIC, "zlib deflateInit2 failed: %d" , err); |
390 | } |
391 | return fz_new_output(ctx, 8192, state, deflate_write, deflate_close, deflate_drop); |
392 | } |
393 | |