fz_stream * fz_open_image_decomp_stream_from_buffer(fz_context *ctx, fz_compressed_buffer *buffer, int *l2factor) { fz_stream *chain = fz_open_buffer(ctx, buffer->buffer); return fz_open_image_decomp_stream(ctx, chain, &buffer->params, l2factor); }
fz_stream * fz_open_compressed_buffer(fz_context *ctx, fz_compressed_buffer *buffer) { int factor = 1; return fz_open_image_decomp_stream(ctx, buffer, &factor); }
/* * Create a filter given a name and param dictionary. */ static fz_stream * build_filter(fz_context *ctx, fz_stream *chain, pdf_document *doc, pdf_obj *f, pdf_obj *p, int num, int gen, fz_compression_params *params) { fz_compression_params local_params; if (params == NULL) params = &local_params; build_compression_params(ctx, f, p, params); /* If we were using params we were passed in, and we successfully * recognised the image type, we can use the existing filter and * shortstop here. */ if (params != &local_params && params->type != FZ_IMAGE_RAW) return chain; if (params->type != FZ_IMAGE_RAW) return fz_open_image_decomp_stream(ctx, chain, params, NULL); if (pdf_name_eq(ctx, f, PDF_NAME_ASCIIHexDecode) || pdf_name_eq(ctx, f, PDF_NAME_AHx)) return fz_open_ahxd(ctx, chain); else if (pdf_name_eq(ctx, f, PDF_NAME_ASCII85Decode) || pdf_name_eq(ctx, f, PDF_NAME_A85)) return fz_open_a85d(ctx, chain); else if (pdf_name_eq(ctx, f, PDF_NAME_JBIG2Decode)) { fz_jbig2_globals *globals = NULL; pdf_obj *obj = pdf_dict_get(ctx, p, PDF_NAME_JBIG2Globals); if (pdf_is_indirect(ctx, obj)) globals = pdf_load_jbig2_globals(ctx, doc, obj); /* fz_open_jbig2d takes possession of globals */ return fz_open_jbig2d(ctx, chain, globals); } else if (pdf_name_eq(ctx, f, PDF_NAME_JPXDecode)) return chain; /* JPX decoding is special cased in the image loading code */ else if (pdf_name_eq(ctx, f, PDF_NAME_Crypt)) { pdf_obj *name; if (!doc->crypt) { fz_warn(ctx, "crypt filter in unencrypted document"); return chain; } name = pdf_dict_get(ctx, p, PDF_NAME_Name); if (pdf_is_name(ctx, name)) return pdf_open_crypt_with_filter(ctx, chain, doc->crypt, name, num, gen); return chain; } fz_warn(ctx, "unknown filter name (%s)", pdf_to_name(ctx, f)); return chain; }
static fz_pixmap * pdf_image_get_pixmap(fz_context *ctx, fz_image *image_, int w, int h) { pdf_image *image = (pdf_image *)image_; fz_pixmap *tile; fz_stream *stm; int l2factor; pdf_image_key key; int native_l2factor; int indexed; /* Check for 'simple' images which are just pixmaps */ if (image->buffer == NULL) { tile = image->tile; if (!tile) return NULL; return fz_keep_pixmap(ctx, tile); /* That's all we can give you! */ } /* Ensure our expectations for tile size are reasonable */ if (w > image->base.w) w = image->base.w; if (h > image->base.h) h = image->base.h; /* What is our ideal factor? */ if (w == 0 || h == 0) l2factor = 0; else for (l2factor=0; image->base.w>>(l2factor+1) >= w && image->base.h>>(l2factor+1) >= h && l2factor < 8; l2factor++); /* Can we find any suitable tiles in the cache? */ key.refs = 1; key.image = &image->base; key.l2factor = l2factor; do { tile = fz_find_item(ctx, fz_free_pixmap_imp, &key, &pdf_image_store_type); if (tile) return tile; key.l2factor--; } while (key.l2factor >= 0); /* We need to make a new one. */ native_l2factor = l2factor; stm = fz_open_image_decomp_stream(ctx, image->buffer, &native_l2factor); indexed = fz_colorspace_is_indexed(image->base.colorspace); return decomp_image_from_stream(ctx, stm, image, 0, indexed, l2factor, native_l2factor, 1); }
void pdf_load_compressed_inline_image(fz_context *ctx, pdf_document *doc, pdf_obj *dict, int length, fz_stream *stm, int indexed, fz_image *image) { fz_compressed_buffer *bc = fz_malloc_struct(ctx, fz_compressed_buffer); fz_try(ctx) { int dummy_l2factor = 0; bc->buffer = fz_new_buffer(ctx, 1024); stm = pdf_open_inline_stream(ctx, doc, dict, length, stm, &bc->params); stm = fz_open_leecher(ctx, stm, bc->buffer); stm = fz_open_image_decomp_stream(ctx, stm, &bc->params, &dummy_l2factor); image->tile = fz_decomp_image_from_stream(ctx, stm, image, indexed, 0, 0); } fz_catch(ctx) { fz_drop_compressed_buffer(ctx, bc); fz_rethrow(ctx); } image->buffer = bc; }
fz_pixmap * fz_image_get_pixmap(fz_context *ctx, fz_image *image, int w, int h) { fz_pixmap *tile; fz_stream *stm; int l2factor; fz_image_key key; int native_l2factor; int indexed; fz_image_key *keyp; /* Check for 'simple' images which are just pixmaps */ if (image->buffer == NULL) { tile = image->tile; if (!tile) return NULL; return fz_keep_pixmap(ctx, tile); /* That's all we can give you! */ } /* Ensure our expectations for tile size are reasonable */ if (w > image->w) w = image->w; if (h > image->h) h = image->h; /* What is our ideal factor? */ if (w == 0 || h == 0) l2factor = 0; else for (l2factor=0; image->w>>(l2factor+1) >= w && image->h>>(l2factor+1) >= h && l2factor < 8; l2factor++); /* Can we find any suitable tiles in the cache? */ key.refs = 1; key.image = image; key.l2factor = l2factor; do { tile = fz_find_item(ctx, fz_free_pixmap_imp, &key, &fz_image_store_type); if (tile) return tile; key.l2factor--; } while (key.l2factor >= 0); /* We need to make a new one. */ /* First check for ones that we can't decode using streams */ switch (image->buffer->params.type) { case FZ_IMAGE_PNG: tile = fz_load_png(ctx, image->buffer->buffer->data, image->buffer->buffer->len); break; case FZ_IMAGE_TIFF: tile = fz_load_tiff(ctx, image->buffer->buffer->data, image->buffer->buffer->len); break; default: native_l2factor = l2factor; stm = fz_open_image_decomp_stream(ctx, image->buffer, &native_l2factor); indexed = fz_colorspace_is_indexed(image->colorspace); tile = fz_decomp_image_from_stream(ctx, stm, image, 0, indexed, l2factor, native_l2factor); break; } /* Now we try to cache the pixmap. Any failure here will just result * in us not caching. */ fz_var(keyp); fz_try(ctx) { fz_pixmap *existing_tile; keyp = fz_malloc_struct(ctx, fz_image_key); keyp->refs = 1; keyp->image = fz_keep_image(ctx, image); keyp->l2factor = l2factor; existing_tile = fz_store_item(ctx, keyp, tile, fz_pixmap_size(ctx, tile), &fz_image_store_type); if (existing_tile) { /* We already have a tile. This must have been produced by a * racing thread. We'll throw away ours and use that one. */ fz_drop_pixmap(ctx, tile); tile = existing_tile; } } fz_always(ctx) { fz_drop_image_key(ctx, keyp); } fz_catch(ctx) { /* Do nothing */ } return tile; }