static fz_display_node * fz_new_display_node(fz_display_command cmd, fz_matrix ctm, fz_colorspace *colorspace, float *color, float alpha) { fz_display_node *node; int i; node = fz_malloc(sizeof(fz_display_node)); node->cmd = cmd; node->next = NULL; node->rect = fz_empty_rect; node->item.path = NULL; node->stroke = NULL; node->flag = 0; node->ctm = ctm; if (colorspace) { node->colorspace = fz_keep_colorspace(colorspace); if (color) { for (i = 0; i < node->colorspace->n; i++) node->color[i] = color[i]; } } else { node->colorspace = NULL; } node->alpha = alpha; return node; }
static void fz_text_fill_image_mask(fz_context *ctx, fz_device *dev, fz_image *img, const fz_matrix *ctm, fz_colorspace *cspace, float *color, float alpha) { fz_text_device *tdev = (fz_text_device*)dev; fz_text_page *page = tdev->page; fz_image_block *block; /* If the alpha is less than 50% then it's probably a watermark or * effect or something. Skip it */ if (alpha < 0.5) return; /* New block */ if (page->len == page->cap) { int newcap = (page->cap ? page->cap*2 : 4); page->blocks = fz_resize_array(ctx, page->blocks, newcap, sizeof(*page->blocks)); page->cap = newcap; } block = fz_malloc_struct(ctx, fz_image_block); page->blocks[page->len].type = FZ_PAGE_BLOCK_IMAGE; page->blocks[page->len].u.image = block; block->image = fz_keep_image(ctx, img); block->cspace = fz_keep_colorspace(ctx, cspace); if (cspace) memcpy(block->colors, color, sizeof(block->colors[0])*cspace->n); block->mat = *ctm; block->bbox.x0 = 0; block->bbox.y0 = 0; block->bbox.x1 = 1; block->bbox.y1 = 1; fz_transform_rect(&block->bbox, ctm); page->len++; }
static fz_display_node * fz_new_display_node(fz_context *ctx, fz_display_command cmd, const fz_matrix *ctm, fz_colorspace *colorspace, float *color, float alpha) { fz_display_node *node; int i; node = fz_malloc_struct(ctx, fz_display_node); node->cmd = cmd; node->next = NULL; node->rect = fz_empty_rect; node->item.path = NULL; node->stroke = NULL; node->flag = (cmd == FZ_CMD_BEGIN_TILE ? fz_gen_id(ctx) : 0); node->ctm = *ctm; if (colorspace) { node->colorspace = fz_keep_colorspace(ctx, colorspace); if (color) { for (i = 0; i < node->colorspace->n; i++) node->color[i] = color[i]; } } else { node->colorspace = NULL; } node->alpha = alpha; return node; }
fz_image * fz_new_image_from_pixmap(fz_context *ctx, fz_pixmap *pixmap, fz_image *mask) { fz_image *image; assert(mask == NULL || mask->mask == NULL); fz_try(ctx) { image = fz_malloc_struct(ctx, fz_image); FZ_INIT_STORABLE(image, 1, fz_free_image); image->w = pixmap->w; image->h = pixmap->h; image->n = pixmap->n; image->colorspace = fz_keep_colorspace(ctx, pixmap->colorspace); image->bpc = 8; image->buffer = NULL; image->get_pixmap = fz_image_get_pixmap; image->xres = pixmap->xres; image->yres = pixmap->yres; image->tile = pixmap; image->mask = mask; } fz_catch(ctx) { fz_drop_pixmap(ctx, pixmap); fz_drop_image(ctx, mask); fz_rethrow(ctx); } return image; }
void fz_set_device_lab(fz_context *ctx, fz_colorspace *cs) { fz_lock(ctx, FZ_LOCK_ALLOC); fz_drop_colorspace(ctx, ctx->colorspace->lab); ctx->colorspace->lab = fz_keep_colorspace(ctx, cs); fz_unlock(ctx, FZ_LOCK_ALLOC); }
void fz_load_jxr_info(fz_context *ctx, const unsigned char *data, size_t size, int *wp, int *hp, int *xresp, int *yresp, fz_colorspace **cspacep) { struct info info = { 0 }; jxr_read_image(ctx, data, size, &info, 1); *cspacep = fz_keep_colorspace(ctx, info.cspace); /* info.cspace is a borrowed device colorspace */ *wp = info.width; *hp = info.height; *xresp = info.xres; *yresp = info.yres; }
void fz_load_gif_info(fz_context *ctx, const unsigned char *p, size_t total, int *wp, int *hp, int *xresp, int *yresp, fz_colorspace **cspacep) { struct info gif; gif_read_image(ctx, &gif, p, total, 1); *cspacep = fz_keep_colorspace(ctx, fz_device_rgb(ctx)); *wp = gif.width; *hp = gif.height; *xresp = gif.xres; *yresp = gif.yres; }
fz_pixmap * fz_new_pixmap_with_data(fz_context *ctx, fz_colorspace *colorspace, int w, int h, unsigned char *samples) { fz_pixmap *pix; pix = fz_malloc_struct(ctx, fz_pixmap); FZ_INIT_STORABLE(pix, 1, fz_free_pixmap_imp); pix->x = 0; pix->y = 0; pix->w = w; pix->h = h; pix->interpolate = 1; pix->xres = 96; pix->yres = 96; pix->colorspace = NULL; pix->n = 1; pix->has_alpha = 1; /* SumatraPDF: allow optimizing non-alpha pixmaps */ pix->single_bit = 0; /* SumatraPDF: allow optimizing 1-bit pixmaps */ if (colorspace) { pix->colorspace = fz_keep_colorspace(ctx, colorspace); pix->n = 1 + colorspace->n; } pix->samples = samples; if (samples) { pix->free_samples = 0; } else { fz_try(ctx) { if (pix->w + pix->n - 1 > INT_MAX / pix->n) fz_throw(ctx, "overly wide image"); pix->samples = fz_malloc_array(ctx, pix->h, pix->w * pix->n); } fz_catch(ctx) { if (colorspace) fz_drop_colorspace(ctx, colorspace); fz_free(ctx, pix); fz_rethrow(ctx); } pix->free_samples = 1; } return pix; }
fz_error pdf_load_colorspace(fz_colorspace **csp, pdf_xref *xref, fz_obj *obj) { fz_error error; if ((*csp = pdf_find_item(xref->store, fz_drop_colorspace, obj))) { fz_keep_colorspace(*csp); return fz_okay; } error = pdf_load_colorspace_imp(csp, xref, obj); if (error) return fz_rethrow(error, "cannot load colorspace (%d %d R)", fz_to_num(obj), fz_to_gen(obj)); pdf_store_item(xref->store, fz_keep_colorspace, fz_drop_colorspace, obj, *csp); return fz_okay; }
static void pdf_load_jpx(pdf_document *xref, pdf_obj *dict, pdf_image *image, int forcemask) { fz_buffer *buf = NULL; fz_colorspace *colorspace = NULL; fz_pixmap *img = NULL; pdf_obj *obj; fz_context *ctx = xref->ctx; int indexed = 0; fz_var(img); fz_var(buf); fz_var(colorspace); buf = pdf_load_stream(xref, pdf_to_num(dict), pdf_to_gen(dict)); /* FIXME: We can't handle decode arrays for indexed images currently */ fz_try(ctx) { obj = pdf_dict_gets(dict, "ColorSpace"); if (obj) { colorspace = pdf_load_colorspace(xref, obj); indexed = !strcmp(colorspace->name, "Indexed"); } img = fz_load_jpx(ctx, buf->data, buf->len, colorspace, indexed); if (img && colorspace == NULL) colorspace = fz_keep_colorspace(ctx, img->colorspace); fz_drop_buffer(ctx, buf); buf = NULL; obj = pdf_dict_getsa(dict, "SMask", "Mask"); if (pdf_is_dict(obj)) { if (forcemask) fz_warn(ctx, "Ignoring recursive JPX soft mask"); else image->base.mask = (fz_image *)pdf_load_image_imp(xref, NULL, obj, NULL, 1); } obj = pdf_dict_getsa(dict, "Decode", "D"); if (obj && !indexed) { float decode[FZ_MAX_COLORS * 2]; int i; for (i = 0; i < img->n * 2; i++) decode[i] = pdf_to_real(pdf_array_get(obj, i)); fz_decode_tile(img, decode); } } fz_catch(ctx) { if (colorspace) fz_drop_colorspace(ctx, colorspace); fz_drop_buffer(ctx, buf); fz_drop_pixmap(ctx, img); fz_rethrow(ctx); } FZ_INIT_STORABLE(&image->base, 1, pdf_free_image); image->base.get_pixmap = pdf_image_get_pixmap; image->base.w = img->w; image->base.h = img->h; image->base.bpc = 8; image->base.colorspace = colorspace; image->buffer = NULL; image->tile = img; image->n = img->n; image->interpolate = 0; image->imagemask = 0; image->usecolorkey = 0; }
static void pdf_run_page_contents_with_usage(fz_context *ctx, pdf_document *doc, pdf_page *page, fz_device *dev, const fz_matrix *ctm, const char *usage, fz_cookie *cookie) { fz_matrix local_ctm, page_ctm; pdf_obj *resources; pdf_obj *contents; fz_rect mediabox; pdf_processor *proc = NULL; fz_default_colorspaces *default_cs; fz_var(proc); default_cs = pdf_load_default_colorspaces(ctx, doc, page); if (default_cs) fz_set_default_colorspaces(ctx, dev, default_cs); fz_try(ctx) { pdf_page_transform(ctx, page, &mediabox, &page_ctm); fz_concat(&local_ctm, &page_ctm, ctm); resources = pdf_page_resources(ctx, page); contents = pdf_page_contents(ctx, page); if (page->transparency) { fz_colorspace *colorspace = NULL; pdf_obj *group = pdf_page_group(ctx, page); if (group) { pdf_obj *cs = pdf_dict_get(ctx, group, PDF_NAME_CS); if (cs) { fz_try(ctx) colorspace = pdf_load_colorspace(ctx, cs); fz_catch(ctx) colorspace = NULL; } } else colorspace = fz_keep_colorspace(ctx, fz_default_output_intent(ctx, default_cs)); fz_begin_group(ctx, dev, fz_transform_rect(&mediabox, &local_ctm), colorspace, 1, 0, 0, 1); fz_drop_colorspace(ctx, colorspace); } proc = pdf_new_run_processor(ctx, dev, &local_ctm, usage, NULL, 0); pdf_process_contents(ctx, proc, doc, resources, contents, cookie); pdf_close_processor(ctx, proc); } fz_always(ctx) { fz_drop_default_colorspaces(ctx, default_cs); pdf_drop_processor(ctx, proc); } fz_catch(ctx) fz_rethrow(ctx); if (page->transparency) fz_end_group(ctx, dev); }
static fz_image * pdf_load_jpx(pdf_document *xref, pdf_obj *dict, int forcemask) { fz_buffer *buf = NULL; fz_colorspace *colorspace = NULL; fz_pixmap *img = NULL; pdf_obj *obj; fz_context *ctx = xref->ctx; int indexed = 0; fz_image *mask = NULL; fz_var(img); fz_var(buf); fz_var(colorspace); fz_var(mask); buf = pdf_load_stream(xref, pdf_to_num(dict), pdf_to_gen(dict)); /* FIXME: We can't handle decode arrays for indexed images currently */ fz_try(ctx) { obj = pdf_dict_gets(dict, "ColorSpace"); if (obj) { colorspace = pdf_load_colorspace(xref, obj); indexed = !strcmp(colorspace->name, "Indexed"); } img = fz_load_jpx(ctx, buf->data, buf->len, colorspace, indexed); if (img && colorspace == NULL) colorspace = fz_keep_colorspace(ctx, img->colorspace); fz_drop_buffer(ctx, buf); buf = NULL; obj = pdf_dict_getsa(dict, "SMask", "Mask"); if (pdf_is_dict(obj)) { if (forcemask) fz_warn(ctx, "Ignoring recursive JPX soft mask"); else mask = pdf_load_image_imp(xref, NULL, obj, NULL, 1); } obj = pdf_dict_getsa(dict, "Decode", "D"); if (obj && !indexed) { float decode[FZ_MAX_COLORS * 2]; int i; for (i = 0; i < img->n * 2; i++) decode[i] = pdf_to_real(pdf_array_get(obj, i)); fz_decode_tile(img, decode); } } fz_catch(ctx) { if (colorspace) fz_drop_colorspace(ctx, colorspace); fz_drop_buffer(ctx, buf); fz_drop_pixmap(ctx, img); fz_rethrow(ctx); } return fz_new_image_from_pixmap(ctx, img, mask); }