/* * 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; }
fz_buffer * pdf_load_raw_renumbered_stream(fz_context *ctx, pdf_document *doc, int num, int gen, int orig_num, int orig_gen) { fz_stream *stm; pdf_obj *dict; int len; fz_buffer *buf; 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_keep_buffer(ctx, entry->stm_buf); } dict = pdf_load_object(ctx, doc, num, gen); len = pdf_to_int(ctx, pdf_dict_get(ctx, dict, PDF_NAME_Length)); pdf_drop_obj(ctx, dict); stm = pdf_open_raw_renumbered_stream(ctx, doc, num, gen, orig_num, orig_gen); buf = fz_read_all(ctx, stm, len); fz_drop_stream(ctx, stm); return buf; }
/* * 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; }
static fz_buffer * pdf_load_image_stream(fz_context *ctx, pdf_document *doc, int num, int gen, int orig_num, int orig_gen, fz_compression_params *params, int *truncated) { fz_stream *stm = NULL; pdf_obj *dict, *obj; int i, len, n; fz_buffer *buf; fz_var(buf); if (num > 0 && num < pdf_xref_len(ctx, doc)) { pdf_xref_entry *entry = pdf_get_xref_entry(ctx, doc, num); /* Return ref to existing buffer, but only if uncompressed, * or shortstoppable */ if (can_reuse_buffer(ctx, entry, params)) return fz_keep_buffer(ctx, entry->stm_buf); } dict = pdf_load_object(ctx, doc, num, gen); len = pdf_to_int(ctx, pdf_dict_get(ctx, dict, PDF_NAME_Length)); obj = pdf_dict_get(ctx, dict, PDF_NAME_Filter); len = pdf_guess_filter_length(len, pdf_to_name(ctx, obj)); n = pdf_array_len(ctx, obj); for (i = 0; i < n; i++) len = pdf_guess_filter_length(len, pdf_to_name(ctx, pdf_array_get(ctx, obj, i))); pdf_drop_obj(ctx, dict); stm = pdf_open_image_stream(ctx, doc, num, gen, orig_num, orig_gen, params); fz_try(ctx) { if (truncated) buf = fz_read_best(ctx, stm, len, truncated); else buf = fz_read_all(ctx, stm, len); } fz_always(ctx) { fz_drop_stream(ctx, stm); } fz_catch(ctx) { fz_rethrow_message(ctx, "cannot read raw stream (%d %d R)", num, gen); } return buf; }