/* * Build a filter for reading raw stream data. * This is a null filter to constrain reading to the * stream length, followed by a decryption filter. */ static fz_stream * pdf_open_raw_filter(fz_stream *chain, pdf_document *xref, pdf_obj *stmobj, int num, int gen) { int hascrypt; int len; fz_context *ctx = chain->ctx; /* don't close chain when we close this filter */ fz_keep_stream(chain); len = pdf_to_int(pdf_dict_gets(stmobj, "Length")); chain = fz_open_null(chain, len); fz_try(ctx) { hascrypt = pdf_stream_has_crypt(ctx, stmobj); if (xref->crypt && !hascrypt) chain = pdf_open_crypt(chain, xref->crypt, num, gen); } fz_catch(ctx) { fz_close(chain); fz_rethrow(ctx); } return chain; }
/* * Build a filter for reading raw stream data. * This is a null filter to constrain reading to the stream length (and to * allow for other people accessing the file), followed by a decryption * filter. * * orig_num and orig_gen are used purely to seed the encryption. */ static fz_stream * pdf_open_raw_filter(fz_context *ctx, fz_stream *chain, pdf_document *doc, pdf_obj *stmobj, int num, int orig_num, int orig_gen, int offset) { int hascrypt; int len; if (num > 0 && num < pdf_xref_len(ctx, doc)) { pdf_xref_entry *entry = pdf_get_xref_entry(ctx, doc, num); if (entry->stm_buf) return fz_open_buffer(ctx, entry->stm_buf); } /* don't close chain when we close this filter */ fz_keep_stream(ctx, chain); len = pdf_to_int(ctx, pdf_dict_get(ctx, stmobj, PDF_NAME_Length)); chain = fz_open_null(ctx, chain, len, offset); hascrypt = pdf_stream_has_crypt(ctx, stmobj); if (doc->crypt && !hascrypt) chain = pdf_open_crypt(ctx, chain, doc->crypt, orig_num, orig_gen); return chain; }
int xps_open_stream(xps_context **ctxp, fz_stream *file) { xps_context *ctx; int code; ctx = fz_malloc(file->ctx, sizeof(xps_context)); memset(ctx, 0, sizeof(xps_context)); ctx->ctx = file->ctx; ctx->file = fz_keep_stream(file); code = xps_find_and_read_zip_dir(ctx); if (code < 0) { xps_free_context(ctx); return fz_error_note(file->ctx, code, "cannot read zip central directory"); } code = xps_read_page_list(ctx); if (code) { xps_free_context(ctx); return fz_error_note(file->ctx, code, "cannot read page list"); } *ctxp = ctx; return fz_okay; }
/* * Build a filter for reading raw stream data. * This is a null filter to constrain reading to the stream length (and to * allow for other people accessing the file), followed by a decryption * filter. * * orig_num and orig_gen are used purely to seed the encryption. */ static fz_stream * pdf_open_raw_filter(fz_context *ctx, fz_stream *chain, pdf_document *doc, pdf_obj *stmobj, int num, int *orig_num, int *orig_gen, fz_off_t offset) { pdf_xref_entry *x = NULL; int hascrypt; int len; if (num > 0 && num < pdf_xref_len(ctx, doc)) { x = pdf_get_xref_entry(ctx, doc, num); *orig_num = x->num; *orig_gen = x->gen; if (x->stm_buf) return fz_open_buffer(ctx, x->stm_buf); } else { /* We only end up here when called from pdf_open_stream_with_offset to parse new format XRef sections. */ /* New style XRef sections must have generation number 0. */ *orig_num = num; *orig_gen = 0; } /* don't close chain when we close this filter */ fz_keep_stream(ctx, chain); len = pdf_to_int(ctx, pdf_dict_get(ctx, stmobj, PDF_NAME_Length)); chain = fz_open_null(ctx, chain, len, offset); hascrypt = pdf_stream_has_crypt(ctx, stmobj); if (doc->crypt && !hascrypt) chain = pdf_open_crypt(ctx, chain, doc->crypt, *orig_num, *orig_gen); return chain; }
fz_stream * fz_open_leecher(fz_context *ctx, fz_stream *chain, fz_buffer *buffer) { fz_leech *state = fz_malloc_struct(ctx, fz_leech); state->chain = fz_keep_stream(ctx, chain); state->buffer = fz_keep_buffer(ctx, buffer); return fz_new_stream(ctx, state, next_leech, close_leech); }
fz_archive * fz_new_archive_of_size(fz_context *ctx, fz_stream *file, int size) { fz_archive *arch; arch = Memento_label(fz_calloc(ctx, 1, size), "fz_archive"); arch->file = fz_keep_stream(ctx, file); return arch; }
pdfout_parser * pdfout_parser_outline_wysiwyg_new (fz_context *ctx, fz_stream *stm) { parser *result = fz_malloc_struct (ctx, parser); result->super.drop = parser_drop; result->super.parse = parser_parse; result->stream = fz_keep_stream (ctx, stm); return &result->super; }
/* cf. http://code.google.com/p/sumatrapdf/issues/detail?id=1333 */ static fz_pixmap * decomp_image_banded(fz_context *ctx, fz_stream *stm, fz_image *image, int indexed, int l2factor, int native_l2factor) { fz_pixmap *tile = NULL, *part = NULL; int w = (image->w + (1 << l2factor) - 1) >> l2factor; int h = (image->h + (1 << l2factor) - 1) >> l2factor; int part_h, orig_h = image->h; int band = 1 << fz_maxi(8, l2factor); fz_var(tile); fz_var(part); fz_try(ctx) { fz_colorspace *cs = image->colorspace; if (indexed) cs = *(fz_colorspace **)cs->data; // cf. struct indexed in res_colorspace.c tile = fz_new_pixmap(ctx, cs, w, h); tile->interpolate = image->interpolate; tile->has_alpha = 0; /* SumatraPDF: allow optimizing non-alpha pixmaps */ /* decompress the image in bands of 256 lines */ for (part_h = h; part_h > 0; part_h -= band >> l2factor) { image->h = part_h > band >> l2factor ? band : ((orig_h - 1) % band) + 1; part = fz_decomp_image_from_stream(ctx, fz_keep_stream(stm), image, -1 - indexed, l2factor, native_l2factor); memcpy(tile->samples + (h - part_h) * tile->w * tile->n, part->samples, part->h * part->w * part->n); tile->has_alpha |= part->has_alpha; /* SumatraPDF: allow optimizing non-alpha pixmaps */ fz_drop_pixmap(ctx, part); part = NULL; } /* cf. http://bugs.ghostscript.com/show_bug.cgi?id=693517 */ if (image->usecolorkey && image->mask) fz_unblend_masked_tile(ctx, tile, image); } fz_always(ctx) { image->h = orig_h; fz_close(stm); } fz_catch(ctx) { fz_drop_pixmap(ctx, part); fz_drop_pixmap(ctx, tile); fz_rethrow(ctx); } return tile; }
/* * Build a filter for reading raw stream data. * This is a null filter to constrain reading to the * stream length, followed by a decryption filter. */ static fz_stream * pdf_open_raw_filter(fz_stream *chain, pdf_xref *xref, fz_obj *stmobj, int num, int gen) { int hascrypt; int len; /* don't close chain when we close this filter */ fz_keep_stream(chain); len = fz_to_int(fz_dict_gets(stmobj, "Length")); chain = fz_open_null(chain, len); hascrypt = pdf_stream_has_crypt(stmobj); if (xref->crypt && !hascrypt) chain = pdf_open_crypt(chain, xref->crypt, num, gen); return chain; }
/* * Construct a filter to decode a stream, without * constraining to stream length, and without decryption. */ fz_stream * pdf_open_inline_stream(pdf_document *xref, pdf_obj *stmobj, int length, fz_stream *chain, pdf_image_params *imparams) { pdf_obj *filters; pdf_obj *params; filters = pdf_dict_getsa(stmobj, "Filter", "F"); params = pdf_dict_getsa(stmobj, "DecodeParms", "DP"); /* don't close chain when we close this filter */ fz_keep_stream(chain); if (pdf_is_name(filters)) return build_filter(chain, xref, filters, params, 0, 0, imparams); if (pdf_array_len(filters) > 0) return build_filter_chain(chain, xref, filters, params, 0, 0, imparams); return fz_open_null(chain, length); }
/* * Construct a filter to decode a stream, without * constraining to stream length, and without decryption. */ fz_stream * pdf_open_inline_stream(fz_stream *chain, pdf_xref *xref, fz_obj *stmobj, int length) { fz_obj *filters; fz_obj *params; filters = fz_dict_getsa(stmobj, "Filter", "F"); params = fz_dict_getsa(stmobj, "DecodeParms", "DP"); /* don't close chain when we close this filter */ fz_keep_stream(chain); if (fz_is_name(filters)) return build_filter(chain, xref, filters, params, 0, 0); if (fz_array_len(filters) > 0) return build_filter_chain(chain, xref, filters, params, 0, 0); return fz_open_null(chain, length); }
/* * Construct a filter to decode a stream, without * constraining to stream length, and without decryption. */ fz_stream * pdf_open_inline_stream(fz_context *ctx, pdf_document *doc, pdf_obj *stmobj, int length, fz_stream *chain, fz_compression_params *imparams) { pdf_obj *filters; pdf_obj *params; filters = pdf_dict_geta(ctx, stmobj, PDF_NAME_Filter, PDF_NAME_F); params = pdf_dict_geta(ctx, stmobj, PDF_NAME_DecodeParms, PDF_NAME_DP); /* don't close chain when we close this filter */ fz_keep_stream(ctx, chain); if (pdf_is_name(ctx, filters)) return build_filter(ctx, chain, doc, filters, params, 0, 0, imparams); if (pdf_array_len(ctx, filters) > 0) return build_filter_chain(ctx, chain, doc, filters, params, 0, 0, imparams); if (imparams) imparams->type = FZ_IMAGE_RAW; return fz_open_null(ctx, chain, length, fz_tell(ctx, chain)); }
fz_stream * fz_open_sgilog16(fz_context *ctx, fz_stream *chain, int w) { fz_sgilog16 *state = fz_malloc_struct(ctx, fz_sgilog16); fz_try(ctx) { state->run = 0; state->n = 0; state->c = 0; state->w = w; state->temp = fz_malloc(ctx, w * sizeof(uint16_t)); state->chain = fz_keep_stream(ctx, chain); } fz_catch(ctx) { fz_free(ctx, state->temp); fz_free(ctx, state); fz_rethrow(ctx); } return fz_new_stream(ctx, state, next_sgilog16, close_sgilog16); }
fz_stream * fz_open_copy(fz_stream *chain) { return fz_keep_stream(chain); }
static fz_pixmap * decomp_image_banded(fz_context *ctx, fz_stream *stm, pdf_image *image, int indexed, int l2factor, int native_l2factor, int cache) { fz_pixmap *tile = NULL, *part = NULL; int w = (image->base.w + (1 << l2factor) - 1) >> l2factor; int h = (image->base.h + (1 << l2factor) - 1) >> l2factor; int part_h, orig_h = image->base.h; int band = 1 << fz_maxi(8, l2factor); fz_var(tile); fz_var(part); fz_try(ctx) { tile = fz_new_pixmap(ctx, image->base.colorspace, w, h); tile->interpolate = image->interpolate; tile->has_alpha = 0; /* SumatraPDF: allow optimizing non-alpha pixmaps */ /* decompress the image in bands of 256 lines */ for (part_h = h; part_h > 0; part_h -= band >> l2factor) { image->base.h = part_h > band >> l2factor ? band : (orig_h - 1) % band + 1; part = decomp_image_from_stream(ctx, fz_keep_stream(stm), image, -1, indexed, l2factor, native_l2factor, 0); memcpy(tile->samples + (h - part_h) * tile->w * tile->n, part->samples, part->h * part->w * part->n); tile->has_alpha |= part->has_alpha; /* SumatraPDF: allow optimizing non-alpha pixmaps */ fz_drop_pixmap(ctx, part); part = NULL; } /* cf. http://bugs.ghostscript.com/show_bug.cgi?id=693517 */ if (image->usecolorkey && image->base.mask) pdf_unblend_masked_tile(ctx, tile, image); } fz_always(ctx) { image->base.h = orig_h; fz_close(stm); } fz_catch(ctx) { fz_drop_pixmap(ctx, part); fz_drop_pixmap(ctx, tile); fz_rethrow(ctx); } if (cache) { pdf_image_key *key = NULL; fz_var(key); fz_try(ctx) { key = fz_malloc_struct(ctx, pdf_image_key); key->refs = 1; key->image = fz_keep_image(ctx, &image->base); key->l2factor = l2factor; fz_store_item(ctx, key, tile, fz_pixmap_size(ctx, tile), &pdf_image_store_type); } fz_always(ctx) { pdf_drop_image_key(ctx, key); } fz_catch(ctx) { } } return tile; }
fz_error pdf_open_xref_with_stream(pdf_xref **xrefp, fz_stream *file, char *password) { pdf_xref *xref; fz_error error; fz_obj *encrypt, *id; fz_obj *dict, *obj; int i, repaired = 0; /* install pdf specific callback */ fz_resolve_indirect = pdf_resolve_indirect; xref = fz_malloc(sizeof(pdf_xref)); memset(xref, 0, sizeof(pdf_xref)); xref->file = fz_keep_stream(file); error = pdf_load_xref(xref, xref->scratch, sizeof xref->scratch); if (error) { fz_catch(error, "trying to repair"); if (xref->table) { fz_free(xref->table); xref->table = NULL; xref->len = 0; } if (xref->trailer) { fz_drop_obj(xref->trailer); xref->trailer = NULL; } error = pdf_repair_xref(xref, xref->scratch, sizeof xref->scratch); if (error) { pdf_free_xref(xref); return fz_rethrow(error, "cannot repair document"); } repaired = 1; } encrypt = fz_dict_gets(xref->trailer, "Encrypt"); id = fz_dict_gets(xref->trailer, "ID"); if (fz_is_dict(encrypt)) { error = pdf_new_crypt(&xref->crypt, encrypt, id); if (error) { pdf_free_xref(xref); return fz_rethrow(error, "cannot decrypt document"); } } if (pdf_needs_password(xref)) { /* Only care if we have a password */ if (password) { int okay = pdf_authenticate_password(xref, password); if (!okay) { pdf_free_xref(xref); return fz_throw("invalid password"); } } } if (repaired) { int hasroot, hasinfo; error = pdf_repair_obj_stms(xref); if (error) { pdf_free_xref(xref); return fz_rethrow(error, "cannot repair document"); } hasroot = fz_dict_gets(xref->trailer, "Root") != NULL; hasinfo = fz_dict_gets(xref->trailer, "Info") != NULL; for (i = 1; i < xref->len; i++) { if (xref->table[i].type == 0 || xref->table[i].type == 'f') continue; error = pdf_load_object(&dict, xref, i, 0); if (error) { fz_catch(error, "ignoring broken object (%d 0 R)", i); continue; } if (!hasroot) { obj = fz_dict_gets(dict, "Type"); if (fz_is_name(obj) && !strcmp(fz_to_name(obj), "Catalog")) { obj = fz_new_indirect(i, 0, xref); fz_dict_puts(xref->trailer, "Root", obj); fz_drop_obj(obj); } } if (!hasinfo) { if (fz_dict_gets(dict, "Creator") || fz_dict_gets(dict, "Producer")) { obj = fz_new_indirect(i, 0, xref); fz_dict_puts(xref->trailer, "Info", obj); fz_drop_obj(obj); } } fz_drop_obj(dict); } } error = pdf_read_ocg(xref); if (error) { pdf_free_xref(xref); return fz_rethrow(error, "Broken Optional Content"); } *xrefp = xref; return fz_okay; }