static void fz_decode_tiff_lzw(fz_context *ctx, struct tiff *tiff, fz_stream *chain, unsigned char *wp, int wlen) { fz_stream *stm = fz_open_lzwd(ctx, chain, 1); fz_read(ctx, stm, wp, wlen); fz_drop_stream(ctx, stm); }
static void fz_decode_tiff_lzw(struct tiff *tiff, fz_stream *chain, unsigned char *wp, int wlen) { fz_stream *stm = fz_open_lzwd(chain, 1); fz_read(stm, wp, wlen); fz_close(stm); }
static int xps_decode_tiff_lzw(struct tiff *tiff, fz_stream *chain, byte *wp, int wlen) { fz_stream *stm = fz_open_lzwd(chain, NULL); int n = fz_read(stm, wp, wlen); fz_close(stm); if (n < 0) return fz_error_note(chain->ctx, n, "cannot read lzw strip"); return fz_okay; }
fz_stream * fz_open_image_decomp_stream(fz_context *ctx, fz_compressed_buffer *buffer, int *factor) { fz_stream *chain = fz_open_buffer(ctx, buffer->buffer); fz_compression_params *params = &buffer->params; switch (params->type) { case FZ_IMAGE_FAX: *factor = 1; return fz_open_faxd(chain, params->u.fax.k, params->u.fax.end_of_line, params->u.fax.encoded_byte_align, params->u.fax.columns, params->u.fax.rows, params->u.fax.end_of_block, params->u.fax.black_is_1); case FZ_IMAGE_JPEG: if (*factor > 8) *factor = 8; return fz_open_resized_dctd(chain, params->u.jpeg.color_transform, *factor); case FZ_IMAGE_RLD: *factor = 1; return fz_open_rld(chain); case FZ_IMAGE_FLATE: *factor = 1; chain = fz_open_flated(chain); if (params->u.flate.predictor > 1) chain = fz_open_predict(chain, params->u.flate.predictor, params->u.flate.columns, params->u.flate.colors, params->u.flate.bpc); return chain; case FZ_IMAGE_LZW: *factor = 1; chain = fz_open_lzwd(chain, params->u.lzw.early_change); if (params->u.lzw.predictor > 1) chain = fz_open_predict(chain, params->u.lzw.predictor, params->u.lzw.columns, params->u.lzw.colors, params->u.lzw.bpc); return chain; default: *factor = 1; break; } return chain; }
fz_stream * fz_open_image_decomp_stream(fz_context *ctx, fz_stream *chain, fz_compression_params *params, int *l2factor) { int our_l2factor = 0; switch (params->type) { case FZ_IMAGE_FAX: return fz_open_faxd(ctx, chain, params->u.fax.k, params->u.fax.end_of_line, params->u.fax.encoded_byte_align, params->u.fax.columns, params->u.fax.rows, params->u.fax.end_of_block, params->u.fax.black_is_1); case FZ_IMAGE_JPEG: if (l2factor) { our_l2factor = *l2factor; if (our_l2factor > 3) our_l2factor = 3; *l2factor -= our_l2factor; } return fz_open_dctd(ctx, chain, params->u.jpeg.color_transform, our_l2factor, NULL); case FZ_IMAGE_RLD: return fz_open_rld(ctx, chain); case FZ_IMAGE_FLATE: chain = fz_open_flated(ctx, chain, 15); if (params->u.flate.predictor > 1) chain = fz_open_predict(ctx, chain, params->u.flate.predictor, params->u.flate.columns, params->u.flate.colors, params->u.flate.bpc); return chain; case FZ_IMAGE_LZW: chain = fz_open_lzwd(ctx, chain, params->u.lzw.early_change); if (params->u.lzw.predictor > 1) chain = fz_open_predict(ctx, chain, params->u.lzw.predictor, params->u.lzw.columns, params->u.lzw.colors, params->u.lzw.bpc); return chain; default: break; } return chain; }
fz_stream * pdf_open_image_decomp_stream(fz_context *ctx, fz_buffer *buffer, pdf_image_params *params, int *factor) { fz_stream *chain = fz_open_buffer(ctx, buffer); switch (params->type) { case PDF_IMAGE_FAX: *factor = 1; return fz_open_faxd(chain, params->u.fax.k, params->u.fax.eol, params->u.fax.eba, params->u.fax.columns, params->u.fax.rows, params->u.fax.eob, params->u.fax.bi1); case PDF_IMAGE_JPEG: if (*factor > 8) *factor = 8; return fz_open_resized_dctd(chain, params->u.jpeg.ct, *factor); case PDF_IMAGE_RLD: *factor = 1; return fz_open_rld(chain); case PDF_IMAGE_FLATE: *factor = 1; chain = fz_open_flated(chain); if (params->u.flate.predictor > 1) chain = fz_open_predict(chain, params->u.flate.predictor, params->u.flate.columns, params->u.flate.colors, params->u.flate.bpc); return chain; case PDF_IMAGE_LZW: *factor = 1; chain = fz_open_lzwd(chain, params->u.lzw.ec); if (params->u.lzw.predictor > 1) chain = fz_open_predict(chain, params->u.lzw.predictor, params->u.lzw.columns, params->u.lzw.colors, params->u.lzw.bpc); return chain; default: *factor = 1; break; } return chain; }
/* * Create a filter given a name and param dictionary. */ static fz_stream * build_filter(fz_stream *chain, pdf_document * xref, pdf_obj * f, pdf_obj * p, int num, int gen, pdf_image_params *params) { fz_context *ctx = chain->ctx; char *s = pdf_to_name(f); int predictor = pdf_to_int(pdf_dict_gets(p, "Predictor")); int columns = pdf_to_int(pdf_dict_gets(p, "Columns")); int colors = pdf_to_int(pdf_dict_gets(p, "Colors")); int bpc = pdf_to_int(pdf_dict_gets(p, "BitsPerComponent")); if (predictor == 0) predictor = 1; if (columns == 0) columns = 1; if (colors == 0) colors = 1; if (bpc == 0) bpc = 8; if (!strcmp(s, "ASCIIHexDecode") || !strcmp(s, "AHx")) return fz_open_ahxd(chain); else if (!strcmp(s, "ASCII85Decode") || !strcmp(s, "A85")) return fz_open_a85d(chain); else if (!strcmp(s, "CCITTFaxDecode") || !strcmp(s, "CCF")) { pdf_obj *k = pdf_dict_gets(p, "K"); pdf_obj *eol = pdf_dict_gets(p, "EndOfLine"); pdf_obj *eba = pdf_dict_gets(p, "EncodedByteAlign"); pdf_obj *columns = pdf_dict_gets(p, "Columns"); pdf_obj *rows = pdf_dict_gets(p, "Rows"); pdf_obj *eob = pdf_dict_gets(p, "EndOfBlock"); pdf_obj *bi1 = pdf_dict_gets(p, "BlackIs1"); if (params) { /* We will shortstop here */ params->type = PDF_IMAGE_FAX; params->u.fax.k = (k ? pdf_to_int(k) : 0); params->u.fax.eol = (eol ? pdf_to_bool(eol) : 0); params->u.fax.eba = (eba ? pdf_to_bool(eba) : 0); params->u.fax.columns = (columns ? pdf_to_int(columns) : 1728); params->u.fax.rows = (rows ? pdf_to_int(rows) : 0); params->u.fax.eob = (eob ? pdf_to_bool(eob) : 1); params->u.fax.bi1 = (bi1 ? pdf_to_bool(bi1) : 0); return chain; } return fz_open_faxd(chain, k ? pdf_to_int(k) : 0, eol ? pdf_to_bool(eol) : 0, eba ? pdf_to_bool(eba) : 0, columns ? pdf_to_int(columns) : 1728, rows ? pdf_to_int(rows) : 0, eob ? pdf_to_bool(eob) : 1, bi1 ? pdf_to_bool(bi1) : 0); } else if (!strcmp(s, "DCTDecode") || !strcmp(s, "DCT")) { pdf_obj *ct = pdf_dict_gets(p, "ColorTransform"); if (params) { /* We will shortstop here */ params->type = PDF_IMAGE_JPEG; params->u.jpeg.ct = (ct ? pdf_to_int(ct) : -1); return chain; } return fz_open_dctd(chain, ct ? pdf_to_int(ct) : -1); } else if (!strcmp(s, "RunLengthDecode") || !strcmp(s, "RL")) { if (params) { /* We will shortstop here */ params->type = PDF_IMAGE_RLD; return chain; } return fz_open_rld(chain); } else if (!strcmp(s, "FlateDecode") || !strcmp(s, "Fl")) { if (params) { /* We will shortstop here */ params->type = PDF_IMAGE_FLATE; params->u.flate.predictor = predictor; params->u.flate.columns = columns; params->u.flate.colors = colors; params->u.flate.bpc = bpc; return chain; } chain = fz_open_flated(chain); if (predictor > 1) chain = fz_open_predict(chain, predictor, columns, colors, bpc); return chain; } else if (!strcmp(s, "LZWDecode") || !strcmp(s, "LZW")) { pdf_obj *ec = pdf_dict_gets(p, "EarlyChange"); if (params) { /* We will shortstop here */ params->type = PDF_IMAGE_LZW; params->u.lzw.predictor = predictor; params->u.lzw.columns = columns; params->u.lzw.colors = colors; params->u.lzw.bpc = bpc; params->u.lzw.ec = (ec ? pdf_to_int(ec) : 1); return chain; } chain = fz_open_lzwd(chain, ec ? pdf_to_int(ec) : 1); if (predictor > 1) chain = fz_open_predict(chain, predictor, columns, colors, bpc); return chain; } else if (!strcmp(s, "JBIG2Decode")) { fz_buffer *globals = NULL; pdf_obj *obj = pdf_dict_gets(p, "JBIG2Globals"); if (obj) globals = pdf_load_stream(xref, pdf_to_num(obj), pdf_to_gen(obj)); /* fz_open_jbig2d takes possession of globals */ return fz_open_jbig2d(chain, globals); } else if (!strcmp(s, "JPXDecode")) return chain; /* JPX decoding is special cased in the image loading code */ else if (!strcmp(s, "Crypt")) { pdf_obj *name; if (!xref->crypt) { fz_warn(ctx, "crypt filter in unencrypted document"); return chain; } name = pdf_dict_gets(p, "Name"); if (pdf_is_name(name)) return pdf_open_crypt_with_filter(chain, xref->crypt, pdf_to_name(name), num, gen); return chain; } fz_warn(ctx, "unknown filter name (%s)", s); return chain; }
static unsigned char * gif_read_tbid(fz_context *ctx, struct info *info, unsigned char *dest, unsigned char *p, unsigned char *end) { fz_stream *stm, *lzwstm = NULL; unsigned int mincodesize, y; fz_buffer *compressed = NULL, *uncompressed = NULL; const unsigned char *ct; unsigned char *sp; if (end - p < 1) fz_throw(ctx, FZ_ERROR_GENERIC, "premature end in table based image data in gif image"); mincodesize = *p; fz_var(compressed); fz_var(lzwstm); fz_var(uncompressed); fz_try(ctx) { compressed = fz_new_buffer(ctx, 0); p = gif_read_subblocks(ctx, info, p + 1, end, compressed); stm = fz_open_buffer(ctx, compressed); lzwstm = fz_open_lzwd(ctx, stm, 0, mincodesize + 1, 1, 0); uncompressed = fz_read_all(ctx, lzwstm, info->width * info->height); sp = uncompressed->data; if (info->has_lct) ct = info->lct; else if (info->has_gct) ct = info->gct; else ct = dct; if (info->image_interlaced) { for (y = 0; y < info->image_height; y += 8, sp += info->image_width) gif_read_line(ctx, info, dest, ct, y, sp); for (y = 4; y < info->image_height; y += 8, sp += info->image_width) gif_read_line(ctx, info, dest, ct, y, sp); for (y = 2; y < info->image_height; y += 4, sp += info->image_width) gif_read_line(ctx, info, dest, ct, y, sp); for (y = 1; y < info->image_height; y += 2, sp += info->image_width) gif_read_line(ctx, info, dest, ct, y, sp); } else for (y = 0; y < info->image_height; y++, sp += info->image_width) gif_read_line(ctx, info, dest, ct, y, sp); } fz_always(ctx) { fz_drop_buffer(ctx, uncompressed); fz_drop_buffer(ctx, compressed); fz_drop_stream(ctx, lzwstm); } fz_catch(ctx) { fz_rethrow(ctx); } return p; }
static const unsigned char * gif_read_tbid(fz_context *ctx, struct info *info, unsigned char *dest, const unsigned char *p, const unsigned char *end) { fz_stream *stm, *lzwstm = NULL; unsigned int mincodesize, y; fz_buffer *compressed = NULL, *uncompressed = NULL; const unsigned char *ct; unsigned char *sp; int ct_entries; if (end - p < 1) fz_throw(ctx, FZ_ERROR_GENERIC, "premature end in table based image data in gif image"); mincodesize = *p; /* if there is no overlap, avoid pasting image data, just consume it */ if (info->image_top >= info->height || info->image_left >= info->width) { p = gif_read_subblocks(ctx, info, p + 1, end, NULL); return p; } fz_var(compressed); fz_var(lzwstm); fz_var(uncompressed); fz_try(ctx) { compressed = fz_new_buffer(ctx, 0); p = gif_read_subblocks(ctx, info, p + 1, end, compressed); stm = fz_open_buffer(ctx, compressed); lzwstm = fz_open_lzwd(ctx, stm, 0, mincodesize + 1, 1, 1); uncompressed = fz_read_all(ctx, lzwstm, 0); if (uncompressed->len < info->image_width * info->image_height) fz_throw(ctx, FZ_ERROR_GENERIC, "premature end in compressed table based image data in gif image"); if (info->has_lct) { ct = info->lct; ct_entries = info->lct_entries; } else if (info->has_gct) { ct = info->gct; ct_entries = info->gct_entries; } else { ct = dct; ct_entries = 256; } sp = uncompressed->data; if (info->image_interlaced) { for (y = 0; y < info->image_height; y += 8, sp += info->image_width) gif_read_line(ctx, info, dest, ct_entries, ct, y, sp); for (y = 4; y < info->image_height; y += 8, sp += info->image_width) gif_read_line(ctx, info, dest, ct_entries, ct, y, sp); for (y = 2; y < info->image_height; y += 4, sp += info->image_width) gif_read_line(ctx, info, dest, ct_entries, ct, y, sp); for (y = 1; y < info->image_height; y += 2, sp += info->image_width) gif_read_line(ctx, info, dest, ct_entries, ct, y, sp); } else for (y = 0; y < info->image_height; y++, sp += info->image_width) gif_read_line(ctx, info, dest, ct_entries, ct, y, sp); } fz_always(ctx) { fz_drop_buffer(ctx, uncompressed); fz_drop_buffer(ctx, compressed); fz_drop_stream(ctx, lzwstm); } fz_catch(ctx) { fz_rethrow(ctx); } return p; }
/* * Create a filter given a name and param dictionary. */ static fz_stream * build_filter(fz_stream *chain, pdf_xref * xref, fz_obj * f, fz_obj * p, int num, int gen) { fz_error error; char *s; s = fz_to_name(f); if (!strcmp(s, "ASCIIHexDecode") || !strcmp(s, "AHx")) return fz_open_ahxd(chain); else if (!strcmp(s, "ASCII85Decode") || !strcmp(s, "A85")) return fz_open_a85d(chain); else if (!strcmp(s, "CCITTFaxDecode") || !strcmp(s, "CCF")) return fz_open_faxd(chain, p); else if (!strcmp(s, "DCTDecode") || !strcmp(s, "DCT")) return fz_open_dctd(chain, p); else if (!strcmp(s, "RunLengthDecode") || !strcmp(s, "RL")) return fz_open_rld(chain); else if (!strcmp(s, "FlateDecode") || !strcmp(s, "Fl")) { fz_obj *obj = fz_dict_gets(p, "Predictor"); if (fz_to_int(obj) > 1) return fz_open_predict(fz_open_flated(chain), p); return fz_open_flated(chain); } else if (!strcmp(s, "LZWDecode") || !strcmp(s, "LZW")) { fz_obj *obj = fz_dict_gets(p, "Predictor"); if (fz_to_int(obj) > 1) return fz_open_predict(fz_open_lzwd(chain, p), p); return fz_open_lzwd(chain, p); } else if (!strcmp(s, "JBIG2Decode")) { fz_obj *obj = fz_dict_gets(p, "JBIG2Globals"); if (obj) { fz_buffer *globals; error = pdf_load_stream(&globals, xref, fz_to_num(obj), fz_to_gen(obj)); if (error) fz_catch(error, "cannot load jbig2 global segments"); chain = fz_open_jbig2d(chain, globals); fz_drop_buffer(globals); return chain; } return fz_open_jbig2d(chain, NULL); } else if (!strcmp(s, "JPXDecode")) return chain; /* JPX decoding is special cased in the image loading code */ else if (!strcmp(s, "Crypt")) { fz_obj *name; if (!xref->crypt) { fz_warn("crypt filter in unencrypted document"); return chain; } name = fz_dict_gets(p, "Name"); if (fz_is_name(name)) return pdf_open_crypt_with_filter(chain, xref->crypt, fz_to_name(name), num, gen); return chain; } fz_warn("unknown filter name (%s)", s); return chain; }