Exemplo n.º 1
0
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++;
}
Exemplo n.º 2
0
static void add_flow_image(fz_context *ctx, fz_pool *pool, fz_html *top, fz_css_style *style, fz_image *img)
{
    fz_html_flow *flow;
    add_flow_glue(ctx, pool, top, style, "", 0);
    flow = add_flow(ctx, pool, top, style, FLOW_IMAGE);
    flow->content.image = fz_keep_image(ctx, img);
    add_flow_glue(ctx, pool, top, style, "", 0);
}
Exemplo n.º 3
0
static void
fz_list_fill_image(fz_device *dev, fz_image *image, fz_matrix ctm, float alpha)
{
	fz_display_node *node;
	node = fz_new_display_node(dev->ctx, FZ_CMD_FILL_IMAGE, ctm, NULL, NULL, alpha);
	node->rect = fz_transform_rect(ctm, fz_unit_rect);
	node->item.image = fz_keep_image(dev->ctx, image);
	fz_append_display_node(dev->user, node);
}
Exemplo n.º 4
0
static void
fz_list_fill_image_mask(fz_device *dev, fz_image *image, const fz_matrix *ctm,
	fz_colorspace *colorspace, float *color, float alpha)
{
	fz_display_node *node;
	node = fz_new_display_node(dev->ctx, FZ_CMD_FILL_IMAGE_MASK, ctm, colorspace, color, alpha);
	node->rect = fz_unit_rect;
	fz_transform_rect(&node->rect, ctm);
	node->item.image = fz_keep_image(dev->ctx, image);
	fz_append_display_node(dev->user, node);
}
Exemplo n.º 5
0
static void
fz_list_clip_image_mask(fz_device *dev, fz_image *image, fz_rect *rect, fz_matrix ctm)
{
	fz_display_node *node;
	node = fz_new_display_node(dev->ctx, FZ_CMD_CLIP_IMAGE_MASK, ctm, NULL, NULL, 0);
	node->rect = fz_transform_rect(ctm, fz_unit_rect);
	if (rect)
		node->rect = fz_intersect_rect(node->rect, *rect);
	node->item.image = fz_keep_image(dev->ctx, image);
	fz_append_display_node(dev->user, node);
}
Exemplo n.º 6
0
static img_document *
img_new_document(fz_context *ctx, fz_image *image)
{
	img_document *doc = fz_new_document(ctx, sizeof *doc);

	doc->super.close = (fz_document_close_fn *)img_close_document;
	doc->super.count_pages = (fz_document_count_pages_fn *)img_count_pages;
	doc->super.load_page = (fz_document_load_page_fn *)img_load_page;
	doc->super.lookup_metadata = (fz_document_lookup_metadata_fn *)img_lookup_metadata;

	doc->image = fz_keep_image(ctx, image);

	return doc;
}
Exemplo n.º 7
0
static img_page *
img_load_page(fz_context *ctx, img_document *doc, int number)
{
	img_page *page;

	if (number != 0)
		return NULL;

	page = fz_new_page(ctx, sizeof *page);

	page->super.bound_page = (fz_page_bound_page_fn *)img_bound_page;
	page->super.run_page_contents = (fz_page_run_page_contents_fn *)img_run_page;
	page->super.drop_page_imp = (fz_page_drop_page_imp_fn *)img_drop_page_imp;

	page->image = fz_keep_image(ctx, doc->image);

	return page;
}
Exemplo n.º 8
0
static tiff_page *
tiff_load_page(fz_context *ctx, tiff_document *doc, int number)
{
	fz_pixmap *pixmap = NULL;
	fz_image *image = NULL;
	tiff_page *page = NULL;

	if (number < 0 || number >= doc->page_count)
		return NULL;

	fz_var(pixmap);
	fz_var(image);
	fz_var(page);

	fz_try(ctx)
	{
		size_t len;
		unsigned char *data;
		len = fz_buffer_storage(ctx, doc->buffer, &data);
		pixmap = fz_load_tiff_subimage(ctx, data, len, number);
		image = fz_new_image_from_pixmap(ctx, pixmap, NULL);

		page = fz_new_page(ctx, sizeof *page);
		page->super.bound_page = (fz_page_bound_page_fn *)tiff_bound_page;
		page->super.run_page_contents = (fz_page_run_page_contents_fn *)tiff_run_page;
		page->super.drop_page = (fz_page_drop_page_fn *)tiff_drop_page;
		page->image = fz_keep_image(ctx, image);
	}
	fz_always(ctx)
	{
		fz_drop_image(ctx, image);
		fz_drop_pixmap(ctx, pixmap);
	}
	fz_catch(ctx)
	{
		fz_free(ctx, page);
		fz_rethrow(ctx);
	}

	return page;
}
Exemplo n.º 9
0
static fz_pixmap *
decomp_image_from_stream(fz_context *ctx, fz_stream *stm, pdf_image *image, int in_line, int indexed, int l2factor, int native_l2factor, int cache)
{
	fz_pixmap *tile = NULL;
	fz_pixmap *existing_tile;
	int stride, len, i;
	unsigned char *samples = NULL;
	int f = 1<<native_l2factor;
	int w = (image->base.w + f-1) >> native_l2factor;
	int h = (image->base.h + f-1) >> native_l2factor;
	pdf_image_key *key = NULL;

	fz_var(tile);
	fz_var(samples);
	fz_var(key);

	fz_try(ctx)
	{
		tile = fz_new_pixmap(ctx, image->base.colorspace, w, h);
		tile->interpolate = image->interpolate;

		stride = (w * image->n * image->base.bpc + 7) / 8;

		samples = fz_malloc_array(ctx, h, stride);

		len = fz_read(stm, samples, h * stride);
		if (len < 0)
		{
			fz_throw(ctx, "cannot read image data");
		}

		/* Make sure we read the EOF marker (for inline images only) */
		if (in_line)
		{
			unsigned char tbuf[512];
			fz_try(ctx)
			{
				int tlen = fz_read(stm, tbuf, sizeof tbuf);
				if (tlen > 0)
					fz_warn(ctx, "ignoring garbage at end of image");
			}
			fz_catch(ctx)
			{
				fz_warn(ctx, "ignoring error at end of image");
			}
		}

		/* Pad truncated images */
		if (len < stride * h)
		{
			fz_warn(ctx, "padding truncated image");
			memset(samples + len, 0, stride * h - len);
		}

		/* Invert 1-bit image masks */
		if (image->imagemask)
		{
			/* 0=opaque and 1=transparent so we need to invert */
			unsigned char *p = samples;
			len = h * stride;
			for (i = 0; i < len; i++)
				p[i] = ~p[i];
		}

		fz_unpack_tile(tile, samples, image->n, image->base.bpc, stride, indexed);

		fz_free(ctx, samples);
		samples = NULL;

		if (image->usecolorkey)
			pdf_mask_color_key(tile, image->n, image->colorkey);

		if (indexed)
		{
			fz_pixmap *conv;
			fz_decode_indexed_tile(tile, image->decode, (1 << image->base.bpc) - 1);
			conv = pdf_expand_indexed_pixmap(ctx, tile);
			fz_drop_pixmap(ctx, tile);
			tile = conv;
		}
		else
		{
			fz_decode_tile(tile, image->decode);
		}
	}
	fz_always(ctx)
	{
		fz_close(stm);
	}
	fz_catch(ctx)
	{
		if (tile)
			fz_drop_pixmap(ctx, tile);
		fz_free(ctx, samples);

		fz_rethrow(ctx);
	}

	/* Now apply any extra subsampling required */
	if (l2factor - native_l2factor > 0)
	{
		if (l2factor - native_l2factor > 8)
			l2factor = native_l2factor + 8;
		fz_subsample_pixmap(ctx, tile, l2factor - native_l2factor);
	}

	if (!cache)
		return tile;

	/* Now we try to cache the pixmap. Any failure here will just result
	 * in us not caching. */
	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;
		existing_tile = fz_store_item(ctx, key, tile, fz_pixmap_size(ctx, tile), &pdf_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)
	{
		pdf_drop_image_key(ctx, key);
	}
	fz_catch(ctx)
	{
		/* Do nothing */
	}

	return tile;
}
Exemplo n.º 10
0
static void add_flow_image(fz_context *ctx, fz_html *top, fz_css_style *style, fz_image *img)
{
	fz_html_flow *flow = add_flow(ctx, top, style, FLOW_IMAGE);
	flow->image = fz_keep_image(ctx, img);
}
Exemplo n.º 11
0
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;
}
Exemplo n.º 12
0
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;
}