| 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 | |