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
19struct ahx
20{
21 fz_output *chain;
22 int column;
23};
24
25static 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
44static void ahx_close(fz_context *ctx, void *opaque)
45{
46 struct ahx *state = opaque;
47 fz_write_byte(ctx, state->chain, '>');
48}
49
50static void ahx_drop(fz_context *ctx, void *opaque)
51{
52 struct ahx *state = opaque;
53 fz_free(ctx, state);
54}
55
56fz_output *
57fz_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
65struct a85
66{
67 fz_output *chain;
68 int column;
69 unsigned int word, n;
70};
71
72static 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
131static 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
145static 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
153static void a85_drop(fz_context *ctx, void *opaque)
154{
155 struct a85 *state = opaque;
156 fz_free(ctx, state);
157}
158
159fz_output *
160fz_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
170struct rle
171{
172 fz_output *chain;
173 int state;
174 int run;
175 unsigned char buf[128];
176};
177
178enum { ZERO, ONE, DIFF, SAME };
179
180static 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
186static 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
192static 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
256static 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
269static void rle_drop(fz_context *ctx, void *opaque)
270{
271 struct rle *enc = opaque;
272 fz_free(ctx, enc);
273}
274
275fz_output *
276fz_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
285struct arc4
286{
287 fz_output *chain;
288 fz_arc4 arc4;
289};
290
291static 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
306static void arc4_drop(fz_context *ctx, void *opaque)
307{
308 fz_free(ctx, opaque);
309}
310
311fz_output *
312fz_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
320struct deflate
321{
322 fz_output *chain;
323 z_stream z;
324};
325
326static 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
346static 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
367static 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
374fz_output *
375fz_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