コード例 #1
0
ファイル: output-cbz.c プロジェクト: ArtifexSoftware/mupdf
fz_document_writer *
fz_new_cbz_writer(fz_context *ctx, const char *path, const char *options)
{
	fz_cbz_writer *wri;

	wri = fz_malloc_struct(ctx, fz_cbz_writer);
	wri->super.begin_page = cbz_begin_page;
	wri->super.end_page = cbz_end_page;
	wri->super.close_writer = cbz_close_writer;
	wri->super.drop_writer = cbz_drop_writer;

	fz_try(ctx)
	{
		fz_parse_draw_options(ctx, &wri->options, options);
		wri->zip = fz_new_zip_writer(ctx, path ? path : "out.cbz");
	}
	fz_catch(ctx)
	{
		fz_free(ctx, wri);
		fz_rethrow(ctx);
	}

	return (fz_document_writer*)wri;
}
コード例 #2
0
ファイル: xps-resource.c プロジェクト: JorjMcKie/mupdf
xps_resource *
xps_parse_resource_dictionary(fz_context *ctx, xps_document *doc, char *base_uri, fz_xml *root)
{
	xps_resource *head;
	xps_resource *entry;
	fz_xml *node;
	char *source;
	char *key;

	source = fz_xml_att(root, "Source");
	if (source)
		return xps_parse_remote_resource_dictionary(ctx, doc, base_uri, source);

	head = NULL;

	for (node = fz_xml_down(root); node; node = fz_xml_next(node))
	{
		key = fz_xml_att(node, "x:Key");
		if (key)
		{
			entry = fz_malloc_struct(ctx, xps_resource);
			entry->name = key;
			entry->base_uri = NULL;
			entry->base_xml = NULL;
			entry->data = node;
			entry->next = head;
			entry->parent = NULL;
			head = entry;
		}
	}

	if (head)
		head->base_uri = fz_strdup(ctx, base_uri);

	return head;
}
コード例 #3
0
ファイル: buffer.c プロジェクト: Leadrive/mupdf-converter
fz_buffer *
fz_new_buffer(fz_context *ctx, int size)
{
	fz_buffer *b;

	size = size > 1 ? size : 16;

	b = fz_malloc_struct(ctx, fz_buffer);
	b->refs = 1;
	fz_try(ctx)
	{
		b->data = fz_malloc(ctx, size);
	}
	fz_catch(ctx)
	{
		fz_free(ctx, b);
		fz_rethrow(ctx);
	}
	b->cap = size;
	b->len = 0;
	b->unused_bits = 0;

	return b;
}
コード例 #4
0
ファイル: pdf-cmap.c プロジェクト: josgraha/sumatrapdf
pdf_cmap *
pdf_new_cmap(fz_context *ctx)
{
    pdf_cmap *cmap;

    cmap = fz_malloc_struct(ctx, pdf_cmap);
    FZ_INIT_STORABLE(cmap, 1, pdf_free_cmap_imp);

    strcpy(cmap->cmap_name, "");
    strcpy(cmap->usecmap_name, "");
    cmap->usecmap = NULL;
    cmap->wmode = 0;
    cmap->codespace_len = 0;

    cmap->rlen = 0;
    cmap->rcap = 0;
    cmap->ranges = NULL;

    cmap->tlen = 0;
    cmap->tcap = 0;
    cmap->table = NULL;

    return cmap;
}
コード例 #5
0
ファイル: draw_device.c プロジェクト: Buminta/BibDroid
fz_device *
fz_new_draw_device(fz_context *ctx, fz_pixmap *dest)
{
	fz_device *dev = NULL;
	fz_draw_device *ddev = fz_malloc_struct(ctx, fz_draw_device);

	fz_var(dev);
	fz_try(ctx)
	{
		ddev->gel = fz_new_gel(ctx);
		ddev->flags = 0;
		ddev->ctx = ctx;
		ddev->top = 0;
		ddev->stack = &ddev->init_stack[0];
		ddev->stack_max = STACK_SIZE;
		ddev->stack[0].dest = dest;
		ddev->stack[0].shape = NULL;
		ddev->stack[0].mask = NULL;
		ddev->stack[0].blendmode = 0;
		ddev->stack[0].scissor.x0 = dest->x;
		ddev->stack[0].scissor.y0 = dest->y;
		ddev->stack[0].scissor.x1 = dest->x + dest->w;
		ddev->stack[0].scissor.y1 = dest->y + dest->h;

		dev = fz_new_device(ctx, ddev);
	}
	fz_catch(ctx)
	{
		fz_free_gel(ddev->gel);
		fz_free(ctx, ddev);
		fz_rethrow(ctx);
	}
	dev->free_user = fz_draw_free_user;

	dev->fill_path = fz_draw_fill_path;
	dev->stroke_path = fz_draw_stroke_path;
	dev->clip_path = fz_draw_clip_path;
	dev->clip_stroke_path = fz_draw_clip_stroke_path;

	dev->fill_text = fz_draw_fill_text;
	dev->stroke_text = fz_draw_stroke_text;
	dev->clip_text = fz_draw_clip_text;
	dev->clip_stroke_text = fz_draw_clip_stroke_text;
	dev->ignore_text = fz_draw_ignore_text;

	dev->fill_image_mask = fz_draw_fill_image_mask;
	dev->clip_image_mask = fz_draw_clip_image_mask;
	dev->fill_image = fz_draw_fill_image;
	dev->fill_shade = fz_draw_fill_shade;

	dev->pop_clip = fz_draw_pop_clip;

	dev->begin_mask = fz_draw_begin_mask;
	dev->end_mask = fz_draw_end_mask;
	dev->begin_group = fz_draw_begin_group;
	dev->end_group = fz_draw_end_group;

	dev->begin_tile = fz_draw_begin_tile;
	dev->end_tile = fz_draw_end_tile;

	return dev;
}
コード例 #6
0
ファイル: pdf_image.c プロジェクト: clchiou/mupdf
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;
}
コード例 #7
0
ファイル: pdf_shade.c プロジェクト: modulexcite/windows8
static fz_shade *
pdf_load_shading_dict(pdf_document *xref, pdf_obj *dict, fz_matrix transform)
{
    fz_shade *shade = NULL;
    pdf_function *func[FZ_MAX_COLORS] = { NULL };
    pdf_obj *obj;
    int funcs = 0;
    int type = 0;
    int i, in, out;
    fz_context *ctx = xref->ctx;

    fz_var(shade);
    fz_var(func);
    fz_var(funcs);
    fz_var(type);

    fz_try(ctx)
    {
        shade = fz_malloc_struct(ctx, fz_shade);
        FZ_INIT_STORABLE(shade, 1, fz_free_shade_imp);
        shade->type = FZ_MESH_TYPE4;
        shade->use_background = 0;
        shade->use_function = 0;
        shade->matrix = transform;
        shade->bbox = fz_infinite_rect;

        shade->colorspace = NULL;

        funcs = 0;

        obj = pdf_dict_gets(dict, "ShadingType");
        type = pdf_to_int(obj);

        obj = pdf_dict_gets(dict, "ColorSpace");
        if (!obj)
            fz_throw(ctx, "shading colorspace is missing");
        shade->colorspace = pdf_load_colorspace(xref, obj);

        obj = pdf_dict_gets(dict, "Background");
        if (obj)
        {
            shade->use_background = 1;
            for (i = 0; i < shade->colorspace->n; i++)
                shade->background[i] = pdf_to_real(pdf_array_get(obj, i));
        }

        obj = pdf_dict_gets(dict, "BBox");
        if (pdf_is_array(obj))
        {
            shade->bbox = pdf_to_rect(ctx, obj);
        }

        obj = pdf_dict_gets(dict, "Function");
        if (pdf_is_dict(obj))
        {
            funcs = 1;

            if (type == 1)
                in = 2;
            else
                in = 1;
            out = shade->colorspace->n;

            func[0] = pdf_load_function(xref, obj, in, out);
            if (!func[0])
                fz_throw(ctx, "cannot load shading function (%d %d R)", pdf_to_num(obj), pdf_to_gen(obj));
        }
        else if (pdf_is_array(obj))
        {
            funcs = pdf_array_len(obj);
            if (funcs != 1 && funcs != shade->colorspace->n)
            {
                funcs = 0;
                fz_throw(ctx, "incorrect number of shading functions");
            }
            if (funcs > FZ_MAX_COLORS)
            {
                funcs = 0;
                fz_throw(ctx, "too many shading functions");
            }

            if (type == 1)
                in = 2;
            else
                in = 1;
            out = 1;

            for (i = 0; i < funcs; i++)
            {
                func[i] = pdf_load_function(xref, pdf_array_get(obj, i), in, out);
                if (!func[i])
                    fz_throw(ctx, "cannot load shading function (%d %d R)", pdf_to_num(obj), pdf_to_gen(obj));
            }
        }
        else if (type < 4)
        {
            /* Functions are compulsory for types 1,2,3 */
            fz_throw(ctx, "cannot load shading function (%d %d R)", pdf_to_num(obj), pdf_to_gen(obj));
        }

        shade->type = type;
        switch (type)
        {
        case 1:
            pdf_load_function_based_shading(shade, xref, dict, func[0]);
            break;
        case 2:
            pdf_load_linear_shading(shade, xref, dict, funcs, func);
            break;
        case 3:
            pdf_load_radial_shading(shade, xref, dict, funcs, func);
            break;
        case 4:
            pdf_load_type4_shade(shade, xref, dict, funcs, func);
            break;
        case 5:
            pdf_load_type5_shade(shade, xref, dict, funcs, func);
            break;
        case 6:
            pdf_load_type6_shade(shade, xref, dict, funcs, func);
            break;
        case 7:
            pdf_load_type7_shade(shade, xref, dict, funcs, func);
            break;
        default:
            fz_throw(ctx, "unknown shading type: %d", type);
        }

        for (i = 0; i < funcs; i++)
            if (func[i])
                pdf_drop_function(ctx, func[i]);
    }
    fz_catch(ctx)
    {
        for (i = 0; i < funcs; i++)
            if (func[i])
                pdf_drop_function(ctx, func[i]);
        fz_drop_shade(ctx, shade);

        fz_throw(ctx, "cannot load shading type %d (%d %d R)", type, pdf_to_num(dict), pdf_to_gen(dict));
    }
    return shade;
}
コード例 #8
0
ファイル: pdf_annot.c プロジェクト: CentMeng/PDFViewer
pdf_annot *
pdf_load_annots(pdf_document *xref, pdf_obj *annots, fz_matrix page_ctm)
{
	pdf_annot *annot, *head, *tail;
	pdf_obj *obj, *ap, *as, *n, *d, *c, *rect;
	int i, len;
	int mouse_states;
	int has_states = 0;
	fz_context *ctx = xref->ctx;

	head = tail = NULL;
	annot = NULL;

	len = pdf_array_len(annots);
	for (i = 0; i < len; i++)
	{
		obj = pdf_array_get(annots, i);

		pdf_update_appearance(xref, obj);

		rect = pdf_dict_gets(obj, "Rect");
		ap = pdf_dict_gets(obj, "AP");
		as = pdf_dict_gets(obj, "AS");

		if (pdf_is_dict(ap))
		{
			pdf_hotspot *hp = &xref->hotspot;

			n = pdf_dict_gets(ap, "N"); /* normal state */
			d = pdf_dict_gets(ap, "D"); /* down state */

			if (n && d)
			{
				if (hp->num == pdf_to_num(obj)
					&& hp->gen == pdf_to_gen(obj)
					&& (hp->state & HOTSPOT_POINTER_DOWN))
				{
					/* Use the down appearance, but as we also have
					 * a normal appearance, it is suitable only for mouse
					 * down */
					c = d;
					mouse_states = MOUSE_DOWN_APPEARANCE;
				}
				else
				{
					/* Use the normal appearance, but as we also have
					 * a down appearance, it is suitable only for mouse
					 * up */
					c = n;
					mouse_states = MOUSE_UP_APPEARANCE;
				}
			}
			else
			{
				/* Use whichever appearance we have for both states */
				c = n?n:d;
				mouse_states = MOUSE_UP_APPEARANCE|MOUSE_DOWN_APPEARANCE;
			}


			/* lookup current state in sub-dictionary */
			if (!pdf_is_stream(xref, pdf_to_num(c), pdf_to_gen(c)))
			{
				has_states = 1;
				c = pdf_dict_get(c, as);
			}


			annot = fz_malloc_struct(ctx, pdf_annot);
			annot->obj = pdf_keep_obj(obj);
			annot->rect = pdf_to_rect(ctx, rect);
			annot->pagerect = fz_transform_rect(page_ctm, annot->rect);
			annot->ap = NULL;
			annot->type = pdf_field_type(xref, obj);
			annot->mouse_states = mouse_states;
			annot->has_states = has_states;

			if (pdf_is_stream(xref, pdf_to_num(c), pdf_to_gen(c)))
			{
				fz_try(ctx)
				{
					annot->ap = pdf_load_xobject(xref, c);
					pdf_transform_annot(annot);
				}
				fz_catch(ctx)
				{
					fz_warn(ctx, "ignoring broken annotation");
				}
			}

			annot->next = NULL;

			if (obj == xref->focus_obj)
				xref->focus = annot;

			if (!head)
				head = tail = annot;
			else
			{
				tail->next = annot;
				tail = annot;
			}
		}
	}

	return head;
}
コード例 #9
0
ファイル: PdfCreator.cpp プロジェクト: eottone/sumatrapdf
static fz_image *render_to_pixmap(fz_context *ctx, HBITMAP hbmp, SizeI size)
{
    int w = size.dx, h = size.dy;
    int stride = ((w * 3 + 3) / 4) * 4;

    unsigned char *data = (unsigned char *)fz_malloc(ctx, stride * h);

    BITMAPINFO bmi = { 0 };
    bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
    bmi.bmiHeader.biWidth = w;
    bmi.bmiHeader.biHeight = -h;
    bmi.bmiHeader.biPlanes = 1;
    bmi.bmiHeader.biBitCount = 24;
    bmi.bmiHeader.biCompression = BI_RGB;

    HDC hDC = GetDC(nullptr);
    int res = GetDIBits(hDC, hbmp, 0, h, data, &bmi, DIB_RGB_COLORS);
    ReleaseDC(nullptr, hDC);
    if (!res) {
        fz_free(ctx, data);
        fz_throw(ctx, FZ_ERROR_GENERIC, "GetDIBits failed");
    }

    // convert BGR with padding to RGB without padding
    unsigned char *out = data;
    bool is_grayscale = true;
    for (int y = 0; y < h; y++) {
        const unsigned char *in = data + y * stride;
        unsigned char green, blue;
        for (int x = 0; x < w; x++) {
            is_grayscale = is_grayscale && in[0] == in[1] && in[0] == in[2];
            blue = *in++;
            green = *in++;
            *out++ = *in++;
            *out++ = green;
            *out++ = blue;
        }
    }
    // convert grayscale RGB to proper grayscale
    if (is_grayscale) {
        const unsigned char *in = out = data;
        for (int i = 0; i < w * h; i++) {
            *out++ = *in++;
            in += 2;
        }
    }

    fz_compressed_buffer *buf = nullptr;
    fz_var(buf);

    fz_try(ctx) {
        buf = fz_malloc_struct(ctx, fz_compressed_buffer);
        buf->buffer = fz_new_buffer(ctx, w * h * 4 + 10);
        buf->params.type = FZ_IMAGE_FLATE;
        buf->params.u.flate.predictor = 1;

        z_stream zstm = { 0 };
        zstm.next_in = data;
        zstm.avail_in = out - data;
        zstm.next_out = buf->buffer->data;
        zstm.avail_out = buf->buffer->cap;

        res = deflateInit(&zstm, 9);
        if (res != Z_OK)
            fz_throw(ctx, FZ_ERROR_GENERIC, "deflate failure %d", res);
        res = deflate(&zstm, Z_FINISH);
        if (res != Z_STREAM_END)
            fz_throw(ctx, FZ_ERROR_GENERIC, "deflate failure %d", res);
        buf->buffer->len = zstm.total_out;
        res = deflateEnd(&zstm);
        if (res != Z_OK)
            fz_throw(ctx, FZ_ERROR_GENERIC, "deflate failure %d", res);
    }
    fz_always(ctx) {
        fz_free(ctx, data);
    }
    fz_catch(ctx) {
        fz_free_compressed_buffer(ctx, buf);
        fz_rethrow(ctx);
    }

    fz_colorspace *cs = is_grayscale ? fz_device_gray(ctx) : fz_device_rgb(ctx);
    return fz_new_image(ctx, w, h, 8, cs, 96, 96, 0, 0, nullptr, nullptr, buf, nullptr);
}
コード例 #10
0
ファイル: font.c プロジェクト: chrox/libk2pdfopt
static fz_font *
fz_new_font(fz_context *ctx, char *name, int use_glyph_bbox, int glyph_count)
{
	fz_font *font;
	int i;

	font = fz_malloc_struct(ctx, fz_font);
	font->refs = 1;

	if (name)
		fz_strlcpy(font->name, name, sizeof font->name);
	else
		fz_strlcpy(font->name, "(null)", sizeof font->name);

	font->ft_face = NULL;
	font->ft_substitute = 0;
	font->ft_bold = 0;
	font->ft_italic = 0;
	font->ft_hint = 0;

	font->ft_file = NULL;
	font->ft_data = NULL;
	font->ft_size = 0;

	font->t3matrix = fz_identity;
	font->t3resources = NULL;
	font->t3procs = NULL;
	font->t3lists = NULL;
	font->t3widths = NULL;
	font->t3flags = NULL;
	font->t3doc = NULL;
	font->t3run = NULL;

	font->bbox.x0 = 0;
	font->bbox.y0 = 0;
	font->bbox.x1 = 1;
	font->bbox.y1 = 1;

	font->use_glyph_bbox = use_glyph_bbox;
	if (use_glyph_bbox && glyph_count <= MAX_BBOX_TABLE_SIZE)
	{
		font->bbox_count = glyph_count;
		font->bbox_table = fz_malloc_array(ctx, glyph_count, sizeof(fz_rect));
		for (i = 0; i < glyph_count; i++)
			font->bbox_table[i] = fz_infinite_rect;
	}
	else
	{
/* willus.com mod -- no warning */
/*
		if (use_glyph_bbox)
			fz_warn(ctx, "not building glyph bbox table for font '%s' with %d glyphs", font->name, glyph_count);
*/
		font->bbox_count = 0;
		font->bbox_table = NULL;
	}

	font->width_count = 0;
	font->width_table = NULL;

	return font;
}
コード例 #11
0
ファイル: pdf-xobject.c プロジェクト: suyuancheng13/Mupdf_S
pdf_obj *
pdf_new_xobject(pdf_document *doc, const fz_rect *bbox, const fz_matrix *mat)
{
	int idict_num;
	pdf_obj *idict = NULL;
	pdf_obj *dict = NULL;
	pdf_xobject *form = NULL;
	pdf_obj *obj = NULL;
	pdf_obj *res = NULL;
	pdf_obj *procset = NULL;
	fz_context *ctx = doc->ctx;

	fz_var(idict);
	fz_var(dict);
	fz_var(form);
	fz_var(obj);
	fz_var(res);
	fz_var(procset);
	fz_try(ctx)
	{
		dict = pdf_new_dict(doc, 0);

		obj = pdf_new_rect(doc, bbox);
        pdf_print_obj(obj);
		pdf_dict_puts(dict, "BBox", obj);
		pdf_drop_obj(obj);
		obj = NULL;

		obj = pdf_new_int(doc, 1);
		pdf_dict_puts(dict, "FormType", obj);
		pdf_drop_obj(obj);
		obj = NULL;

		obj = pdf_new_int(doc, 0);
		pdf_dict_puts(dict, "Length", obj);
		pdf_drop_obj(obj);
		obj = NULL;

		obj = pdf_new_matrix(doc, mat);
		pdf_dict_puts(dict, "Matrix", obj);
		pdf_drop_obj(obj);
		obj = NULL;

		res = pdf_new_dict(doc, 0);
		procset = pdf_new_array(doc, 2);
		obj = pdf_new_name(doc, "PDF");
		pdf_array_push(procset, obj);
		pdf_drop_obj(obj);
		obj = NULL;
		obj = pdf_new_name(doc, "Text");
		pdf_array_push(procset, obj);
		pdf_drop_obj(obj);
		obj = NULL;
		pdf_dict_puts(res, "ProcSet", procset);
		pdf_drop_obj(procset);
		procset = NULL;
		pdf_dict_puts(dict, "Resources", res);

		obj = pdf_new_name(doc, "Form");
		pdf_dict_puts(dict, "Subtype", obj);
		pdf_drop_obj(obj);
		obj = NULL;

		obj = pdf_new_name(doc, "XObject");
		pdf_dict_puts(dict, "Type", obj);
		pdf_drop_obj(obj);
		obj = NULL;

		form = fz_malloc_struct(ctx, pdf_xobject);
		FZ_INIT_STORABLE(form, 1, pdf_free_xobject_imp);
		form->resources = NULL;
		form->contents = NULL;
		form->colorspace = NULL;
		form->me = NULL;
		form->iteration = 0;

		form->bbox = *bbox;

		form->matrix = *mat;

		form->isolated = 0;
		form->knockout = 0;
		form->transparency = 0;

		form->resources = res;
		res = NULL;

		idict_num = pdf_create_object(doc);
		pdf_update_object(doc, idict_num, dict);
		idict = pdf_new_indirect(doc, idict_num, 0);
		pdf_drop_obj(dict);
		dict = NULL;

		pdf_store_item(ctx, idict, form, pdf_xobject_size(form));

		form->contents = pdf_keep_obj(idict);
		form->me = pdf_keep_obj(idict);

		pdf_drop_xobject(ctx, form);
		form = NULL;
	}
	fz_catch(ctx)
	{
		pdf_drop_obj(procset);
		pdf_drop_obj(res);
		pdf_drop_obj(obj);
		pdf_drop_obj(dict);
		pdf_drop_obj(idict);
		pdf_drop_xobject(ctx, form);
		fz_rethrow_message(ctx, "failed to create xobject)");
	}

	return idict;
}
コード例 #12
0
/*
	Render a glyph and return a bitmap.
	If the glyph is too large to fit the cache we have two choices:
	1) Return NULL so the caller can draw the glyph using an outline.
		Only supported for freetype fonts.
	2) Render a clipped glyph by using the scissor rectangle.
		Only supported for type 3 fonts.
		This must not be inserted into the cache.
 */
fz_pixmap *
fz_render_glyph(fz_context *ctx, fz_font *font, int gid, const fz_matrix *ctm, fz_colorspace *model, fz_irect scissor)
{
	fz_glyph_cache *cache;
	fz_glyph_key key;
	fz_pixmap *val;
	float size = fz_matrix_expansion(ctm);
	int do_cache, locked, caching;
	fz_matrix local_ctm = *ctm;
	fz_glyph_cache_entry *entry;
	unsigned hash;

	fz_var(locked);
	fz_var(caching);

	if (size <= MAX_GLYPH_SIZE)
	{
		scissor = fz_infinite_irect;
		do_cache = 1;
	}
	else
	{
		/* SumatraPDF: don't break clipping by larger glyphs */
		if (font->ft_face && size > 3000)
			return NULL;
		do_cache = 0;
	}

	cache = ctx->glyph_cache;

	memset(&key, 0, sizeof key);
	key.font = font;
	key.gid = gid;
	key.a = local_ctm.a * 65536;
	key.b = local_ctm.b * 65536;
	key.c = local_ctm.c * 65536;
	key.d = local_ctm.d * 65536;
	key.e = (local_ctm.e - floorf(local_ctm.e)) * 256;
	key.f = (local_ctm.f - floorf(local_ctm.f)) * 256;
	key.aa = fz_aa_level(ctx);

	local_ctm.e = floorf(local_ctm.e) + key.e / 256.0f;
	local_ctm.f = floorf(local_ctm.f) + key.f / 256.0f;

	fz_lock(ctx, FZ_LOCK_GLYPHCACHE);
	hash = do_hash((unsigned char *)&key, sizeof(key)) % GLYPH_HASH_LEN;
	entry = cache->entry[hash];
	while (entry)
	{
		if (memcmp(&entry->key, &key, sizeof(key)) == 0)
		{
			move_to_front(cache, entry);
			val = fz_keep_pixmap(ctx, entry->val);
			fz_unlock(ctx, FZ_LOCK_GLYPHCACHE);
			return val;
		}
		entry = entry->bucket_next;
	}

	locked = 1;
	caching = 0;

	fz_try(ctx)
	{
		if (font->ft_face)
		{
			val = fz_render_ft_glyph(ctx, font, gid, &local_ctm, key.aa);
		}
		else if (font->t3procs)
		{
			/* We drop the glyphcache here, and execute the t3
			 * glyph code. The danger here is that some other
			 * thread will come along, and want the same glyph
			 * too. If it does, we may both end up rendering
			 * pixmaps. We cope with this later on, by ensuring
			 * that only one gets inserted into the cache. If
			 * we insert ours to find one already there, we
			 * abandon ours, and use the one there already.
			 */
			fz_unlock(ctx, FZ_LOCK_GLYPHCACHE);
			locked = 0;
			val = fz_render_t3_glyph(ctx, font, gid, &local_ctm, model, scissor);
			fz_lock(ctx, FZ_LOCK_GLYPHCACHE);
			locked = 1;
		}
		else
		{
			fz_warn(ctx, "assert: uninitialized font structure");
			val = NULL;
		}
		if (val && do_cache)
		{
			if (val->w < MAX_GLYPH_SIZE && val->h < MAX_GLYPH_SIZE)
			{
				/* If we throw an exception whilst caching,
				 * just ignore the exception and carry on. */
				caching = 1;
				if (!font->ft_face)
				{
					/* We had to unlock. Someone else might
					 * have rendered in the meantime */
					entry = cache->entry[hash];
					while (entry)
					{
						if (memcmp(&entry->key, &key, sizeof(key)) == 0)
						{
							fz_drop_pixmap(ctx, val);
							move_to_front(cache, entry);
							val = fz_keep_pixmap(ctx, entry->val);
							fz_unlock(ctx, FZ_LOCK_GLYPHCACHE);
							return val;
						}
						entry = entry->bucket_next;
					}
				}

				entry = fz_malloc_struct(ctx, fz_glyph_cache_entry);
				entry->key = key;
				entry->hash = hash;
				entry->bucket_next = cache->entry[hash];
				if (entry->bucket_next)
					entry->bucket_next->bucket_prev = entry;
				cache->entry[hash] = entry;
				entry->val = fz_keep_pixmap(ctx, val);
				fz_keep_font(ctx, key.font);

				entry->lru_next = cache->lru_head;
				if (entry->lru_next)
					entry->lru_next->lru_prev = entry;
				else
					cache->lru_tail = entry;
				cache->lru_head = entry;

				cache->total += val->w * val->h;
				while (cache->total > MAX_CACHE_SIZE)
				{
					drop_glyph_cache_entry(ctx, cache->lru_tail);
				}

			}
		}
	}
	fz_always(ctx)
	{
		if (locked)
			fz_unlock(ctx, FZ_LOCK_GLYPHCACHE);
	}
	fz_catch(ctx)
	{
		if (caching)
			fz_warn(ctx, "cannot encache glyph; continuing");
		else
			fz_rethrow(ctx);
	}

	return val;
}
コード例 #13
0
ファイル: pdf-shade.c プロジェクト: muennich/mupdf
static fz_shade *
pdf_load_shading_dict(fz_context *ctx, pdf_document *doc, pdf_obj *dict, const fz_matrix *transform)
{
	fz_shade *shade = NULL;
	pdf_function *func[FZ_MAX_COLORS] = { NULL };
	pdf_obj *obj;
	int funcs = 0;
	int type = 0;
	int i, in, out, n;

	fz_var(shade);
	fz_var(func);
	fz_var(funcs);
	fz_var(type);

	fz_try(ctx)
	{
		shade = fz_malloc_struct(ctx, fz_shade);
		FZ_INIT_STORABLE(shade, 1, fz_drop_shade_imp);
		shade->type = FZ_MESH_TYPE4;
		shade->use_background = 0;
		shade->use_function = 0;
		shade->matrix = *transform;
		shade->bbox = fz_infinite_rect;

		shade->colorspace = NULL;

		funcs = 0;

		obj = pdf_dict_get(ctx, dict, PDF_NAME(ShadingType));
		type = pdf_to_int(ctx, obj);

		obj = pdf_dict_get(ctx, dict, PDF_NAME(ColorSpace));
		if (!obj)
			fz_throw(ctx, FZ_ERROR_SYNTAX, "shading colorspace is missing");
		shade->colorspace = pdf_load_colorspace(ctx, obj);
		n = fz_colorspace_n(ctx, shade->colorspace);

		obj = pdf_dict_get(ctx, dict, PDF_NAME(Background));
		if (obj)
		{
			shade->use_background = 1;
			for (i = 0; i < n; i++)
				shade->background[i] = pdf_array_get_real(ctx, obj, i);
		}

		obj = pdf_dict_get(ctx, dict, PDF_NAME(BBox));
		if (pdf_is_array(ctx, obj))
			pdf_to_rect(ctx, obj, &shade->bbox);

		obj = pdf_dict_get(ctx, dict, PDF_NAME(Function));
		if (pdf_is_dict(ctx, obj))
		{
			funcs = 1;

			if (type == 1)
				in = 2;
			else
				in = 1;
			out = n;

			func[0] = pdf_load_function(ctx, obj, in, out);
			if (!func[0])
				fz_throw(ctx, FZ_ERROR_SYNTAX, "cannot load shading function (%d 0 R)", pdf_to_num(ctx, obj));
		}
		else if (pdf_is_array(ctx, obj))
		{
			funcs = pdf_array_len(ctx, obj);
			if (funcs != 1 && funcs != n)
			{
				funcs = 0;
				fz_throw(ctx, FZ_ERROR_SYNTAX, "incorrect number of shading functions");
			}
			if (funcs > FZ_MAX_COLORS)
			{
				funcs = 0;
				fz_throw(ctx, FZ_ERROR_SYNTAX, "too many shading functions");
			}

			if (type == 1)
				in = 2;
			else
				in = 1;
			out = 1;

			for (i = 0; i < funcs; i++)
			{
				func[i] = pdf_load_function(ctx, pdf_array_get(ctx, obj, i), in, out);
				if (!func[i])
					fz_throw(ctx, FZ_ERROR_SYNTAX, "cannot load shading function (%d 0 R)", pdf_to_num(ctx, obj));
			}
		}
		else if (type < 4)
		{
			/* Functions are compulsory for types 1,2,3 */
			fz_throw(ctx, FZ_ERROR_SYNTAX, "cannot load shading function (%d 0 R)", pdf_to_num(ctx, obj));
		}

		shade->type = type;
		switch (type)
		{
		case 1: pdf_load_function_based_shading(ctx, doc, shade, dict, func[0]); break;
		case 2: pdf_load_linear_shading(ctx, doc, shade, dict, funcs, func); break;
		case 3: pdf_load_radial_shading(ctx, doc, shade, dict, funcs, func); break;
		case 4: pdf_load_type4_shade(ctx, doc, shade, dict, funcs, func); break;
		case 5: pdf_load_type5_shade(ctx, doc, shade, dict, funcs, func); break;
		case 6: pdf_load_type6_shade(ctx, doc, shade, dict, funcs, func); break;
		case 7: pdf_load_type7_shade(ctx, doc, shade, dict, funcs, func); break;
		default:
			fz_throw(ctx, FZ_ERROR_SYNTAX, "unknown shading type: %d", type);
		}
	}
	fz_always(ctx)
	{
		for (i = 0; i < funcs; i++)
			pdf_drop_function(ctx, func[i]);
	}
	fz_catch(ctx)
	{
		fz_drop_shade(ctx, shade);
		fz_rethrow(ctx);
	}
	return shade;
}
コード例 #14
0
pdf_annot *
pdf_create_annot(fz_context *ctx, pdf_document *doc, pdf_page *page, fz_annot_type type)
{
	pdf_annot *annot = NULL;
	pdf_obj *annot_obj = pdf_new_dict(ctx, doc, 0);
	pdf_obj *ind_obj = NULL;

	fz_var(annot);
	fz_var(ind_obj);
	fz_try(ctx)
	{
		int ind_obj_num;
		fz_rect rect = {0.0, 0.0, 0.0, 0.0};
		const char *type_str = annot_type_str(type);
		pdf_obj *annot_arr = pdf_dict_get(ctx, page->me, PDF_NAME_Annots);
		if (annot_arr == NULL)
		{
			annot_arr = pdf_new_array(ctx, doc, 0);
			pdf_dict_put_drop(ctx, page->me, PDF_NAME_Annots, annot_arr);
		}

		pdf_dict_put_drop(ctx, annot_obj, PDF_NAME_Type, PDF_NAME_Annot);

		pdf_dict_put_drop(ctx, annot_obj, PDF_NAME_Subtype, pdf_new_name(ctx, doc, type_str));
		pdf_dict_put_drop(ctx, annot_obj, PDF_NAME_Rect, pdf_new_rect(ctx, doc, &rect));

		/* Make printable as default */
		pdf_dict_put_drop(ctx, annot_obj, PDF_NAME_F, pdf_new_int(ctx, doc, F_Print));

		annot = fz_malloc_struct(ctx, pdf_annot);
		annot->page = page;
		annot->rect = rect;
		annot->pagerect = rect;
		annot->ap = NULL;
		annot->widget_type = PDF_WIDGET_TYPE_NOT_WIDGET;
		annot->annot_type = type;

		/*
			Both annotation object and annotation structure are now created.
			Insert the object in the hierarchy and the structure in the
			page's array.
		*/
		ind_obj_num = pdf_create_object(ctx, doc);
		pdf_update_object(ctx, doc, ind_obj_num, annot_obj);
		ind_obj = pdf_new_indirect(ctx, doc, ind_obj_num, 0);
		pdf_array_push(ctx, annot_arr, ind_obj);
		annot->obj = pdf_keep_obj(ctx, ind_obj);

		/*
			Linking must be done after any call that might throw because
			pdf_drop_annot below actually frees a list. Put the new annot
			at the end of the list, so that it will be drawn last.
		*/
		*page->annot_tailp = annot;
		page->annot_tailp = &annot->next;

		doc->dirty = 1;
	}
	fz_always(ctx)
	{
		pdf_drop_obj(ctx, annot_obj);
		pdf_drop_obj(ctx, ind_obj);
	}
	fz_catch(ctx)
	{
		pdf_drop_annot(ctx, annot);
		fz_rethrow(ctx);
	}

	return annot;
}
コード例 #15
0
ファイル: html-font.c プロジェクト: PuzzleFlow/mupdf
fz_html_font_set *fz_new_html_font_set(fz_context *ctx)
{
	return fz_malloc_struct(ctx, fz_html_font_set);
}
コード例 #16
0
ファイル: pdf-portfolio.c プロジェクト: ArtifexSoftware/mupdf
void pdf_add_portfolio_schema(fz_context *ctx, pdf_document *doc, int entry, const pdf_portfolio_schema *info)
{
	pdf_portfolio **pp;
	pdf_portfolio *p;
	pdf_obj *s;
	pdf_obj *sc;
	int num;
	char str_name[32];
	pdf_obj *num_name = NULL;

	if (!doc)
		fz_throw(ctx, FZ_ERROR_GENERIC, "Bad pdf_add_portfolio_schema call");

	if (doc->portfolio == NULL)
		load_portfolio(ctx, doc);

	fz_var(num_name);

	pp = &doc->portfolio;
	while (*pp && entry > 0)
		pp = &(*pp)->next, entry--;

	fz_try(ctx)
	{
		/* Find a name for the new schema entry */
		num = 0;
		do
		{
			pdf_drop_obj(ctx, num_name);
			num_name = NULL;
			num++;
			sprintf(str_name, "%d", num);
			num_name = pdf_new_name(ctx, doc, str_name);
			p = doc->portfolio;
			for (p = doc->portfolio; p; p = p->next)
				if (pdf_name_eq(ctx, num_name, p->key))
					break;
		}
		while (p);

		sc = pdf_new_dict(ctx, doc, 4);
		pdf_dict_put_drop(ctx, sc, PDF_NAME_E, pdf_new_bool(ctx, doc, !!info->editable));
		pdf_dict_put_drop(ctx, sc, PDF_NAME_V, pdf_new_bool(ctx, doc, !!info->visible));
		pdf_dict_put_drop(ctx, sc, PDF_NAME_N, info->name);
		pdf_dict_put(ctx, sc, PDF_NAME_Subtype, PDF_NAME_S);

		/* Add to our linked list (in the correct sorted place) */
		p = fz_malloc_struct(ctx, pdf_portfolio);
		p->entry = *info;
		p->sort = 0; /* Will be rewritten in a mo */
		p->key = pdf_keep_obj(ctx, num_name);
		p->val = pdf_keep_obj(ctx, sc);
		p->next = *pp;
		*pp = p;

		/* Add the key to the schema */
		s = pdf_dict_getl(ctx, pdf_trailer(ctx, doc), PDF_NAME_Root, PDF_NAME_Collection, PDF_NAME_Schema, NULL);
		pdf_dict_put(ctx, s, num_name, sc);

		/* Renumber the schema entries */
		for (num = 0, p = doc->portfolio; p; num++, p = p->next)
		{
			pdf_dict_put_drop(ctx, p->val, PDF_NAME_O, pdf_new_int(ctx, doc, num));
			p->sort = num;
		}
	}
	fz_always(ctx)
		pdf_drop_obj(ctx, num_name);
	fz_catch(ctx)
		fz_rethrow(ctx);
}
コード例 #17
0
ファイル: pdf-op-filter.c プロジェクト: GKerison/mupdf-1
pdf_processor *
pdf_new_filter_processor(fz_context *ctx, pdf_processor *chain, pdf_document *doc, pdf_obj *old_rdb, pdf_obj *new_rdb)
{

	pdf_filter_processor *proc = pdf_new_processor(ctx, sizeof *proc);
	{
		proc->super.drop_imp = pdf_drop_imp_filter_processor;

		/* general graphics state */
		proc->super.op_w = pdf_filter_w;
		proc->super.op_j = pdf_filter_j;
		proc->super.op_J = pdf_filter_J;
		proc->super.op_M = pdf_filter_M;
		proc->super.op_d = pdf_filter_d;
		proc->super.op_ri = pdf_filter_ri;
		proc->super.op_i = pdf_filter_i;
		proc->super.op_gs_begin = pdf_filter_gs_begin;
		proc->super.op_gs_end = pdf_filter_gs_end;

		/* transparency graphics state */
		proc->super.op_gs_BM = pdf_filter_gs_BM;
		proc->super.op_gs_CA = pdf_filter_gs_CA;
		proc->super.op_gs_ca = pdf_filter_gs_ca;
		proc->super.op_gs_SMask = pdf_filter_gs_SMask;

		/* special graphics state */
		proc->super.op_q = pdf_filter_q;
		proc->super.op_Q = pdf_filter_Q;
		proc->super.op_cm = pdf_filter_cm;

		/* path construction */
		proc->super.op_m = pdf_filter_m;
		proc->super.op_l = pdf_filter_l;
		proc->super.op_c = pdf_filter_c;
		proc->super.op_v = pdf_filter_v;
		proc->super.op_y = pdf_filter_y;
		proc->super.op_h = pdf_filter_h;
		proc->super.op_re = pdf_filter_re;

		/* path painting */
		proc->super.op_S = pdf_filter_S;
		proc->super.op_s = pdf_filter_s;
		proc->super.op_F = pdf_filter_F;
		proc->super.op_f = pdf_filter_f;
		proc->super.op_fstar = pdf_filter_fstar;
		proc->super.op_B = pdf_filter_B;
		proc->super.op_Bstar = pdf_filter_Bstar;
		proc->super.op_b = pdf_filter_b;
		proc->super.op_bstar = pdf_filter_bstar;
		proc->super.op_n = pdf_filter_n;

		/* clipping paths */
		proc->super.op_W = pdf_filter_W;
		proc->super.op_Wstar = pdf_filter_Wstar;

		/* text objects */
		proc->super.op_BT = pdf_filter_BT;
		proc->super.op_ET = pdf_filter_ET;

		/* text state */
		proc->super.op_Tc = pdf_filter_Tc;
		proc->super.op_Tw = pdf_filter_Tw;
		proc->super.op_Tz = pdf_filter_Tz;
		proc->super.op_TL = pdf_filter_TL;
		proc->super.op_Tf = pdf_filter_Tf;
		proc->super.op_Tr = pdf_filter_Tr;
		proc->super.op_Ts = pdf_filter_Ts;

		/* text positioning */
		proc->super.op_Td = pdf_filter_Td;
		proc->super.op_TD = pdf_filter_TD;
		proc->super.op_Tm = pdf_filter_Tm;
		proc->super.op_Tstar = pdf_filter_Tstar;

		/* text showing */
		proc->super.op_TJ = pdf_filter_TJ;
		proc->super.op_Tj = pdf_filter_Tj;
		proc->super.op_squote = pdf_filter_squote;
		proc->super.op_dquote = pdf_filter_dquote;

		/* type 3 fonts */
		proc->super.op_d0 = pdf_filter_d0;
		proc->super.op_d1 = pdf_filter_d1;

		/* color */
		proc->super.op_CS = pdf_filter_CS;
		proc->super.op_cs = pdf_filter_cs;
		proc->super.op_SC_color = pdf_filter_SC_color;
		proc->super.op_sc_color = pdf_filter_sc_color;
		proc->super.op_SC_pattern = pdf_filter_SC_pattern;
		proc->super.op_sc_pattern = pdf_filter_sc_pattern;
		proc->super.op_SC_shade = pdf_filter_SC_shade;
		proc->super.op_sc_shade = pdf_filter_sc_shade;

		proc->super.op_G = pdf_filter_G;
		proc->super.op_g = pdf_filter_g;
		proc->super.op_RG = pdf_filter_RG;
		proc->super.op_rg = pdf_filter_rg;
		proc->super.op_K = pdf_filter_K;
		proc->super.op_k = pdf_filter_k;

		/* shadings, images, xobjects */
		proc->super.op_BI = pdf_filter_BI;
		proc->super.op_sh = pdf_filter_sh;
		proc->super.op_Do_image = pdf_filter_Do_image;
		proc->super.op_Do_form = pdf_filter_Do_form;

		/* marked content */
		proc->super.op_MP = pdf_filter_MP;
		proc->super.op_DP = pdf_filter_DP;
		proc->super.op_BMC = pdf_filter_BMC;
		proc->super.op_BDC = pdf_filter_BDC;
		proc->super.op_EMC = pdf_filter_EMC;

		/* compatibility */
		proc->super.op_BX = pdf_filter_BX;
		proc->super.op_EX = pdf_filter_EX;

		proc->super.op_END = pdf_filter_END;
	}

	proc->chain = chain;
	proc->doc = doc;
	proc->old_rdb = old_rdb;
	proc->new_rdb = new_rdb;

	proc->gstate = fz_malloc_struct(ctx, filter_gstate);
	proc->gstate->ctm = fz_identity;
	proc->gstate->current_ctm = fz_identity;

	proc->gstate->stroke = proc->gstate->stroke;
	proc->gstate->current_stroke = proc->gstate->stroke;

	return (pdf_processor*)proc;
}
コード例 #18
0
ファイル: pdf-page.c プロジェクト: niife/sumatrapdf
pdf_page *
pdf_create_page(pdf_document *doc, fz_rect mediabox, int res, int rotate)
{
	pdf_page *page = NULL;
	pdf_obj *pageobj, *obj;
	float userunit = 1;
	fz_context *ctx = doc->ctx;
	fz_matrix ctm, tmp;
	fz_rect realbox;

	page = fz_malloc_struct(ctx, pdf_page);
	obj = NULL;
	fz_var(obj);

	fz_try(ctx)
	{
		page->resources = NULL;
		page->contents = NULL;
		page->transparency = 0;
		page->links = NULL;
		page->annots = NULL;
		page->me = pageobj = pdf_new_dict(doc, 4);

		pdf_dict_puts_drop(pageobj, "Type", pdf_new_name(doc, "Page"));

		page->mediabox.x0 = fz_min(mediabox.x0, mediabox.x1) * userunit;
		page->mediabox.y0 = fz_min(mediabox.y0, mediabox.y1) * userunit;
		page->mediabox.x1 = fz_max(mediabox.x0, mediabox.x1) * userunit;
		page->mediabox.y1 = fz_max(mediabox.y0, mediabox.y1) * userunit;
		pdf_dict_puts_drop(pageobj, "MediaBox", pdf_new_rect(doc, &page->mediabox));

		/* Snap page->rotate to 0, 90, 180 or 270 */
		if (page->rotate < 0)
			page->rotate = 360 - ((-page->rotate) % 360);
		if (page->rotate >= 360)
			page->rotate = page->rotate % 360;
		page->rotate = 90*((page->rotate + 45)/90);
		if (page->rotate > 360)
			page->rotate = 0;
		pdf_dict_puts_drop(pageobj, "Rotate", pdf_new_int(doc, page->rotate));

		fz_pre_rotate(fz_scale(&ctm, 1, -1), -page->rotate);
		realbox = page->mediabox;
		fz_transform_rect(&realbox, &ctm);
		fz_pre_scale(fz_translate(&tmp, -realbox.x0, -realbox.y0), userunit, userunit);
		fz_concat(&ctm, &ctm, &tmp);
		page->ctm = ctm;
		obj = pdf_new_dict(doc, 4);
		page->contents = pdf_new_ref(doc, obj);
		pdf_drop_obj(obj);
		obj = NULL;
		pdf_dict_puts(pageobj, "Contents", page->contents);
	}
	fz_catch(ctx)
	{
		pdf_drop_obj(page->me);
		pdf_drop_obj(obj);
		fz_free(ctx, page);
		fz_rethrow_message(ctx, "Failed to create page");
	}

	return page;
}
コード例 #19
0
ファイル: pdf_image.c プロジェクト: Jshauk/sumatrapdf
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;
}
コード例 #20
0
ファイル: draw-glyph.c プロジェクト: iezbli/zbli
fz_glyph *
fz_render_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix *ctm, fz_colorspace *model, const fz_irect *scissor, int alpha)
{
	fz_glyph_cache *cache;
	fz_glyph_key key;
	fz_matrix subpix_ctm;
	fz_irect subpix_scissor;
	float size;
	fz_glyph *val;
	int do_cache, locked, caching;
	fz_glyph_cache_entry *entry;
	unsigned hash;

	fz_var(locked);
	fz_var(caching);
	fz_var(val);

	memset(&key, 0, sizeof key);
	size = fz_subpixel_adjust(ctx, ctm, &subpix_ctm, &key.e, &key.f);
	if (size <= MAX_GLYPH_SIZE)
	{
		scissor = &fz_infinite_irect;
		do_cache = 1;
	}
	else
	{
		if (font->ft_face)
			return NULL;
		subpix_scissor.x0 = scissor->x0 - floorf(ctm->e);
		subpix_scissor.y0 = scissor->y0 - floorf(ctm->f);
		subpix_scissor.x1 = scissor->x1 - floorf(ctm->e);
		subpix_scissor.y1 = scissor->y1 - floorf(ctm->f);
		scissor = &subpix_scissor;
		do_cache = 0;
	}

	cache = ctx->glyph_cache;

	key.font = font;
	key.gid = gid;
	key.a = subpix_ctm.a * 65536;
	key.b = subpix_ctm.b * 65536;
	key.c = subpix_ctm.c * 65536;
	key.d = subpix_ctm.d * 65536;
	key.aa = fz_text_aa_level(ctx);

	hash = do_hash((unsigned char *)&key, sizeof(key)) % GLYPH_HASH_LEN;
	fz_lock(ctx, FZ_LOCK_GLYPHCACHE);
	entry = cache->entry[hash];
	while (entry)
	{
		if (memcmp(&entry->key, &key, sizeof(key)) == 0)
		{
			move_to_front(cache, entry);
			val = fz_keep_glyph(ctx, entry->val);
			fz_unlock(ctx, FZ_LOCK_GLYPHCACHE);
			return val;
		}
		entry = entry->bucket_next;
	}

	locked = 1;
	caching = 0;
	val = NULL;

	fz_try(ctx)
	{
		if (font->ft_face)
		{
			val = fz_render_ft_glyph(ctx, font, gid, &subpix_ctm, key.aa);
		}
		else if (font->t3procs)
		{
			/* We drop the glyphcache here, and execute the t3
			 * glyph code. The danger here is that some other
			 * thread will come along, and want the same glyph
			 * too. If it does, we may both end up rendering
			 * pixmaps. We cope with this later on, by ensuring
			 * that only one gets inserted into the cache. If
			 * we insert ours to find one already there, we
			 * abandon ours, and use the one there already.
			 */
			fz_unlock(ctx, FZ_LOCK_GLYPHCACHE);
			locked = 0;
			val = fz_render_t3_glyph(ctx, font, gid, &subpix_ctm, model, scissor);
			fz_lock(ctx, FZ_LOCK_GLYPHCACHE);
			locked = 1;
		}
		else
		{
			fz_warn(ctx, "assert: uninitialized font structure");
		}
		if (val && do_cache)
		{
			if (val->w < MAX_GLYPH_SIZE && val->h < MAX_GLYPH_SIZE)
			{
				/* If we throw an exception whilst caching,
				 * just ignore the exception and carry on. */
				caching = 1;
				if (!font->ft_face)
				{
					/* We had to unlock. Someone else might
					 * have rendered in the meantime */
					entry = cache->entry[hash];
					while (entry)
					{
						if (memcmp(&entry->key, &key, sizeof(key)) == 0)
						{
							fz_drop_glyph(ctx, val);
							move_to_front(cache, entry);
							val = fz_keep_glyph(ctx, entry->val);
							goto unlock_and_return_val;
						}
						entry = entry->bucket_next;
					}
				}

				entry = fz_malloc_struct(ctx, fz_glyph_cache_entry);
				entry->key = key;
				entry->hash = hash;
				entry->bucket_next = cache->entry[hash];
				if (entry->bucket_next)
					entry->bucket_next->bucket_prev = entry;
				cache->entry[hash] = entry;
				entry->val = fz_keep_glyph(ctx, val);
				fz_keep_font(ctx, key.font);

				entry->lru_next = cache->lru_head;
				if (entry->lru_next)
					entry->lru_next->lru_prev = entry;
				else
					cache->lru_tail = entry;
				cache->lru_head = entry;

				cache->total += fz_glyph_size(ctx, val);
				while (cache->total > MAX_CACHE_SIZE)
				{
#ifndef NDEBUG
					cache->num_evictions++;
					cache->evicted += fz_glyph_size(ctx, cache->lru_tail->val);
#endif
					drop_glyph_cache_entry(ctx, cache->lru_tail);
				}

			}
		}
unlock_and_return_val:
		{
		}
	}
	fz_always(ctx)
	{
		if (locked)
			fz_unlock(ctx, FZ_LOCK_GLYPHCACHE);
	}
	fz_catch(ctx)
	{
		if (caching)
			fz_warn(ctx, "cannot encache glyph; continuing");
		else
			fz_rethrow(ctx);
	}

	return val;
}
コード例 #21
0
ファイル: pdf_xobject.c プロジェクト: Ernest0x/mupdf
pdf_xobject *
pdf_load_xobject(pdf_document *xref, pdf_obj *dict)
{
	pdf_xobject *form;
	pdf_obj *obj;
	fz_context *ctx = xref->ctx;

	if ((form = pdf_find_item(ctx, pdf_free_xobject_imp, dict)))
	{
		return form;
	}

	form = fz_malloc_struct(ctx, pdf_xobject);
	FZ_INIT_STORABLE(form, 1, pdf_free_xobject_imp);
	form->resources = NULL;
	form->contents = NULL;
	form->colorspace = NULL;
	form->me = NULL;

	/* Store item immediately, to avoid possible recursion if objects refer back to this one */
	pdf_store_item(ctx, dict, form, pdf_xobject_size(form));

	obj = pdf_dict_gets(dict, "BBox");
	form->bbox = pdf_to_rect(ctx, obj);

	obj = pdf_dict_gets(dict, "Matrix");
	if (obj)
		form->matrix = pdf_to_matrix(ctx, obj);
	else
		form->matrix = fz_identity;

	form->isolated = 0;
	form->knockout = 0;
	form->transparency = 0;

	obj = pdf_dict_gets(dict, "Group");
	if (obj)
	{
		pdf_obj *attrs = obj;

		form->isolated = pdf_to_bool(pdf_dict_gets(attrs, "I"));
		form->knockout = pdf_to_bool(pdf_dict_gets(attrs, "K"));

		obj = pdf_dict_gets(attrs, "S");
		if (pdf_is_name(obj) && !strcmp(pdf_to_name(obj), "Transparency"))
			form->transparency = 1;

		obj = pdf_dict_gets(attrs, "CS");
		if (obj)
		{
			form->colorspace = pdf_load_colorspace(xref, obj);
			if (!form->colorspace)
				fz_throw(ctx, "cannot load xobject colorspace");
		}
	}

	form->resources = pdf_dict_gets(dict, "Resources");
	if (form->resources)
		pdf_keep_obj(form->resources);

	fz_try(ctx)
	{
		form->contents = pdf_load_stream(xref, pdf_to_num(dict), pdf_to_gen(dict));
	}
	fz_catch(ctx)
	{
		pdf_remove_item(ctx, pdf_free_xobject_imp, dict);
		pdf_drop_xobject(ctx, form);
		fz_throw(ctx, "cannot load xobject content stream (%d %d R)", pdf_to_num(dict), pdf_to_gen(dict));
	}
	form->me = pdf_keep_obj(dict);

	return form;
}
コード例 #22
0
ファイル: html-layout.c プロジェクト: Crayonic/muPDFC
static fz_html *new_box(fz_context *ctx)
{
	fz_html *box = fz_malloc_struct(ctx, fz_html);
	init_box(ctx, box);
	return box;
}
コード例 #23
0
ファイル: stext-device.c プロジェクト: ziel/mupdf
static fz_text_line *
push_span(fz_context *ctx, fz_text_device *tdev, fz_text_span *span, int new_line, float distance)
{
	fz_text_line *line;
	fz_text_block *block;
	fz_text_page *page = tdev->page;
	int prev_not_text = 0;

	if (page->len == 0 || page->blocks[page->len-1].type != FZ_PAGE_BLOCK_TEXT)
		prev_not_text = 1;

	if (new_line || prev_not_text)
	{
		float size = fz_matrix_expansion(&span->transform);
		/* So, a new line. Part of the same block or not? */
		if (distance == 0 || distance > size * 1.5 || distance < -size * PARAGRAPH_DIST || page->len == 0 || prev_not_text)
		{
			/* 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_text_block);
			page->blocks[page->len].type = FZ_PAGE_BLOCK_TEXT;
			page->blocks[page->len].u.text = block;
			block->cap = 0;
			block->len = 0;
			block->lines = 0;
			block->bbox = fz_empty_rect;
			page->len++;
			distance = 0;
		}

		/* New line */
		block = page->blocks[page->len-1].u.text;
		if (block->len == block->cap)
		{
			int newcap = (block->cap ? block->cap*2 : 4);
			block->lines = fz_resize_array(ctx, block->lines, newcap, sizeof(*block->lines));
			block->cap = newcap;
		}
		block->lines[block->len].first_span = NULL;
		block->lines[block->len].last_span = NULL;
		block->lines[block->len].distance = distance;
		block->lines[block->len].bbox = fz_empty_rect;
		block->len++;
	}

	/* Find last line and append to it */
	block = page->blocks[page->len-1].u.text;
	line = &block->lines[block->len-1];

	fz_union_rect(&block->lines[block->len-1].bbox, &span->bbox);
	fz_union_rect(&block->bbox, &span->bbox);
	span->base_offset = (new_line ? 0 : distance);

	if (!line->first_span)
	{
		line->first_span = line->last_span = span;
		span->next = NULL;
	}
	else
	{
		line->last_span->next = span;
		line->last_span = span;
	}

	return line;
}
コード例 #24
0
ファイル: pdf-page.c プロジェクト: codepongo/sumatrapdf
pdf_page *
pdf_load_page_by_obj(pdf_document *doc, int number, pdf_obj *pageref)
{
	fz_context *ctx = doc->ctx;
	pdf_page *page;
	pdf_annot *annot;
	pdf_obj *pageobj, *obj;
	fz_rect mediabox, cropbox, realbox;
	float userunit;
	fz_matrix mat;

	/* SumatraPDF: allow replacing potentially slow pdf_lookup_page_obj */
	pageobj = pdf_resolve_indirect(pageref);

	page = fz_malloc_struct(ctx, pdf_page);
	page->resources = NULL;
	page->contents = NULL;
	page->transparency = 0;
	page->links = NULL;
	page->annots = NULL;
	page->annot_tailp = &page->annots;
	page->deleted_annots = NULL;
	page->tmp_annots = NULL;
	page->me = pdf_keep_obj(pageobj);
	page->incomplete = 0;

	obj = pdf_dict_gets(pageobj, "UserUnit");
	if (pdf_is_real(obj))
		userunit = pdf_to_real(obj);
	else
		userunit = 1;

	pdf_to_rect(ctx, pdf_lookup_inherited_page_item(doc, pageobj, "MediaBox"), &mediabox);
	if (fz_is_empty_rect(&mediabox))
	{
		fz_warn(ctx, "cannot find page size for page %d", number + 1);
		mediabox.x0 = 0;
		mediabox.y0 = 0;
		mediabox.x1 = 612;
		mediabox.y1 = 792;
	}

	pdf_to_rect(ctx, pdf_lookup_inherited_page_item(doc, pageobj, "CropBox"), &cropbox);
	if (!fz_is_empty_rect(&cropbox))
		fz_intersect_rect(&mediabox, &cropbox);

	page->mediabox.x0 = fz_min(mediabox.x0, mediabox.x1) * userunit;
	page->mediabox.y0 = fz_min(mediabox.y0, mediabox.y1) * userunit;
	page->mediabox.x1 = fz_max(mediabox.x0, mediabox.x1) * userunit;
	page->mediabox.y1 = fz_max(mediabox.y0, mediabox.y1) * userunit;

	if (page->mediabox.x1 - page->mediabox.x0 < 1 || page->mediabox.y1 - page->mediabox.y0 < 1)
	{
		fz_warn(ctx, "invalid page size in page %d", number + 1);
		page->mediabox = fz_unit_rect;
	}

	page->rotate = pdf_to_int(pdf_lookup_inherited_page_item(doc, pageobj, "Rotate"));
	/* Snap page->rotate to 0, 90, 180 or 270 */
	if (page->rotate < 0)
		page->rotate = 360 - ((-page->rotate) % 360);
	if (page->rotate >= 360)
		page->rotate = page->rotate % 360;
	page->rotate = 90*((page->rotate + 45)/90);
	if (page->rotate > 360)
		page->rotate = 0;

	fz_pre_rotate(fz_scale(&page->ctm, 1, -1), -page->rotate);
	realbox = page->mediabox;
	fz_transform_rect(&realbox, &page->ctm);
	fz_pre_scale(fz_translate(&mat, -realbox.x0, -realbox.y0), userunit, userunit);
	fz_concat(&page->ctm, &page->ctm, &mat);

	fz_try(ctx)
	{
		obj = pdf_dict_gets(pageobj, "Annots");
		if (obj)
		{
			page->links = pdf_load_link_annots(doc, obj, &page->ctm);
			pdf_load_annots(doc, page, obj);
		}
	}
	fz_catch(ctx)
	{
		if (fz_caught(ctx) != FZ_ERROR_TRYLATER)
			/* SumatraPDF: ignore annotations in case of unexpected errors */
			fz_warn(ctx, "unexpectedly failed to load page annotations");
		page->incomplete |= PDF_PAGE_INCOMPLETE_ANNOTS;
	}

	page->duration = pdf_to_real(pdf_dict_gets(pageobj, "Dur"));

	obj = pdf_dict_gets(pageobj, "Trans");
	page->transition_present = (obj != NULL);
	if (obj)
	{
		pdf_load_transition(doc, page, obj);
	}

	// TODO: inherit
	page->resources = pdf_lookup_inherited_page_item(doc, pageobj, "Resources");
	if (page->resources)
		pdf_keep_obj(page->resources);

	obj = pdf_dict_gets(pageobj, "Contents");
	fz_try(ctx)
	{
		page->contents = pdf_keep_obj(obj);

		if (pdf_resources_use_blending(doc, page->resources))
			page->transparency = 1;
		/* cf. http://code.google.com/p/sumatrapdf/issues/detail?id=2107 */
		else if (!strcmp(pdf_to_name(pdf_dict_getp(pageobj, "Group/S")), "Transparency"))
			page->transparency = 1;

		for (annot = page->annots; annot && !page->transparency; annot = annot->next)
			if (annot->ap && pdf_resources_use_blending(doc, annot->ap->resources))
				page->transparency = 1;
	}
	fz_catch(ctx)
	{
		if (fz_caught(ctx) != FZ_ERROR_TRYLATER)
		{
			pdf_free_page(doc, page);
			fz_rethrow_message(ctx, "cannot load page %d contents (%d 0 R)", number + 1, pdf_to_num(pageref));
		}
		page->incomplete |= PDF_PAGE_INCOMPLETE_CONTENTS;
	}

	return page;
}
コード例 #25
0
ファイル: image.c プロジェクト: ArphonePei/PDFConverter
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;
}
コード例 #26
0
ファイル: pdf_image.c プロジェクト: clchiou/mupdf
static pdf_image *
pdf_load_image_imp(pdf_document *xref, pdf_obj *rdb, pdf_obj *dict, fz_stream *cstm, int forcemask)
{
	fz_stream *stm = NULL;
	pdf_image *image = NULL;
	pdf_obj *obj, *res;

	int w, h, bpc, n;
	int imagemask;
	int interpolate;
	int indexed;
	fz_image *mask = NULL; /* explicit mask/soft mask image */
	int usecolorkey;

	int i;
	fz_context *ctx = xref->ctx;

	fz_var(stm);
	fz_var(mask);

	image = fz_malloc_struct(ctx, pdf_image);

	fz_try(ctx)
	{
		/* special case for JPEG2000 images */
		if (pdf_is_jpx_image(ctx, dict))
		{
			pdf_load_jpx(xref, dict, image, forcemask);

			if (forcemask)
			{
				fz_pixmap *mask_pixmap;
				if (image->n != 2)
					fz_throw(ctx, "soft mask must be grayscale");
				mask_pixmap = fz_alpha_from_gray(ctx, image->tile, 1);
				fz_drop_pixmap(ctx, image->tile);
				image->tile = mask_pixmap;
			}
			break; /* Out of fz_try */
		}

		w = pdf_to_int(pdf_dict_getsa(dict, "Width", "W"));
		h = pdf_to_int(pdf_dict_getsa(dict, "Height", "H"));
		bpc = pdf_to_int(pdf_dict_getsa(dict, "BitsPerComponent", "BPC"));
		if (bpc == 0)
			bpc = 8;
		imagemask = pdf_to_bool(pdf_dict_getsa(dict, "ImageMask", "IM"));
		interpolate = pdf_to_bool(pdf_dict_getsa(dict, "Interpolate", "I"));

		indexed = 0;
		usecolorkey = 0;
		mask = NULL;

		if (imagemask)
			bpc = 1;

		if (w <= 0)
			fz_throw(ctx, "image width is zero (or less)");
		if (h <= 0)
			fz_throw(ctx, "image height is zero (or less)");
		if (bpc <= 0)
			fz_throw(ctx, "image depth is zero (or less)");
		if (bpc > 16)
			fz_throw(ctx, "image depth is too large: %d", bpc);
		if (w > (1 << 16))
			fz_throw(ctx, "image is too wide");
		if (h > (1 << 16))
			fz_throw(ctx, "image is too high");

		obj = pdf_dict_getsa(dict, "ColorSpace", "CS");
		if (obj && !imagemask && !forcemask)
		{
			/* colorspace resource lookup is only done for inline images */
			if (pdf_is_name(obj))
			{
				res = pdf_dict_get(pdf_dict_gets(rdb, "ColorSpace"), obj);
				if (res)
					obj = res;
			}

			image->base.colorspace = pdf_load_colorspace(xref, obj);

			if (!strcmp(image->base.colorspace->name, "Indexed"))
				indexed = 1;

			n = image->base.colorspace->n;
		}
		else
		{
			n = 1;
		}

		obj = pdf_dict_getsa(dict, "Decode", "D");
		if (obj)
		{
			for (i = 0; i < n * 2; i++)
				image->decode[i] = pdf_to_real(pdf_array_get(obj, i));
		}
		else
		{
			float maxval = indexed ? (1 << bpc) - 1 : 1;
			for (i = 0; i < n * 2; i++)
				image->decode[i] = i & 1 ? maxval : 0;
		}

		obj = pdf_dict_getsa(dict, "SMask", "Mask");
		if (pdf_is_dict(obj))
		{
			/* Not allowed for inline images or soft masks */
			if (cstm)
				fz_warn(ctx, "Ignoring invalid inline image soft mask");
			else if (forcemask)
				fz_warn(ctx, "Ignoring recursive image soft mask");
			else
				mask = (fz_image *)pdf_load_image_imp(xref, rdb, obj, NULL, 1);
		}
		else if (pdf_is_array(obj))
		{
			usecolorkey = 1;
			for (i = 0; i < n * 2; i++)
			{
				if (!pdf_is_int(pdf_array_get(obj, i)))
				{
					fz_warn(ctx, "invalid value in color key mask");
					usecolorkey = 0;
				}
				image->colorkey[i] = pdf_to_int(pdf_array_get(obj, i));
			}
		}

		/* Now, do we load a ref, or do we load the actual thing? */
		FZ_INIT_STORABLE(&image->base, 1, pdf_free_image);
		image->base.get_pixmap = pdf_image_get_pixmap;
		image->base.w = w;
		image->base.h = h;
		image->base.bpc = bpc;
		image->n = n;
		image->interpolate = interpolate;
		image->imagemask = imagemask;
		image->usecolorkey = usecolorkey;
		image->base.mask = mask;
		if (!cstm)
		{
			/* Just load the compressed image data now and we can
			 * decode it on demand. */
			int num = pdf_to_num(dict);
			int gen = pdf_to_gen(dict);
			image->buffer = pdf_load_compressed_stream(xref, num, gen);
			break; /* Out of fz_try */
		}

		/* We need to decompress the image now */
		if (cstm)
		{
			int stride = (w * image->n * image->base.bpc + 7) / 8;
			stm = pdf_open_inline_stream(xref, dict, stride * h, cstm, NULL);
		}
		else
		{
			stm = pdf_open_stream(xref, pdf_to_num(dict), pdf_to_gen(dict));
		}

		image->tile = decomp_image_from_stream(ctx, stm, image, cstm != NULL, indexed, 0, 0, 0);
	}
	fz_catch(ctx)
	{
		pdf_free_image(ctx, (fz_storable *) image);
		fz_rethrow(ctx);
	}
	return image;
}
コード例 #27
0
ファイル: document.c プロジェクト: BYogesh/mupdf
void fz_new_document_handler_context(fz_context *ctx)
{
	ctx->handler = fz_malloc_struct(ctx, fz_document_handler_context);
	ctx->handler->refs = 1;
}