Exemple #1
1
static void execute_action(pdf_document *doc, pdf_obj *obj, pdf_obj *a)
{
	fz_context *ctx = doc->ctx;
	if (a)
	{
		char *type = pdf_to_name(pdf_dict_gets(a, "S"));

		if (!strcmp(type, "JavaScript"))
		{
			pdf_obj *js = pdf_dict_gets(a, "JS");
			if (js)
			{
				char *code = pdf_to_utf8(doc, js);
				fz_try(ctx)
				{
					pdf_js_execute(doc->js, code);
				}
				fz_always(ctx)
				{
					fz_free(ctx, code);
				}
				fz_catch(ctx)
				{
					fz_rethrow(ctx);
				}
			}
		}
		else if (!strcmp(type, "ResetForm"))
Exemple #2
0
static void
pdf_load_name_tree_imp(pdf_obj *dict, pdf_document *xref, pdf_obj *node)
{
	fz_context *ctx = xref->ctx;
	pdf_obj *kids = pdf_dict_gets(node, "Kids");
	pdf_obj *names = pdf_dict_gets(node, "Names");
	int i;

	if (kids && !pdf_dict_mark(node))
	{
		for (i = 0; i < pdf_array_len(kids); i++)
			pdf_load_name_tree_imp(dict, xref, pdf_array_get(kids, i));
		pdf_dict_unmark(node);
	}

	if (names)
	{
		for (i = 0; i + 1 < pdf_array_len(names); i += 2)
		{
			pdf_obj *key = pdf_array_get(names, i);
			pdf_obj *val = pdf_array_get(names, i + 1);
			if (pdf_is_string(key))
			{
				key = pdf_to_utf8_name(ctx, key);
				pdf_dict_put(dict, key, val);
				pdf_drop_obj(key);
			}
			else if (pdf_is_name(key))
			{
				pdf_dict_put(dict, key, val);
			}
		}
	}
}
Exemple #3
0
/* returns the number of attachments saved */
int save_attachments(int pageno, char *targetdir)
{
	pdf_page *page = pdf_load_page(doc, pageno-1);
	pdf_annot *annot;
	int saved_count = 0;

	for (annot = page->annots; annot ; annot = annot->next) {
		pdf_obj *fs_obj = pdf_dict_gets(annot->obj, "FS");
		if (fs_obj) {
			pdf_obj *ef_obj;
			char *name = basename(strdup(pdf_to_str_buf(pdf_dict_gets(fs_obj, "F"))));
			ef_obj = pdf_dict_gets(fs_obj, "EF");
			if (ef_obj) {
				pdf_obj *f_obj = pdf_dict_gets(ef_obj, "F");
				if (f_obj && pdf_is_indirect(f_obj)) {
					static char pathname[PATH_MAX];
					sprintf(pathname, "%s/%s", targetdir, name);
					FILE *fout = fopen(pathname, "w");
					if (!fout) {
						fprintf(stderr, "extr: cannot write to file %s\n", pathname);
						exit(1);
					}
					dump_stream(pdf_to_num(f_obj), fout);
					fclose(fout);
					saved_count++;
				}
			}
		}
	}
	return saved_count;
}
static pdf_font_desc *
pdf_load_type0_font(pdf_document *xref, pdf_obj *dict)
{
	pdf_obj *dfonts;
	pdf_obj *dfont;
	pdf_obj *subtype;
	pdf_obj *encoding;
	pdf_obj *to_unicode;

	dfonts = pdf_dict_gets(dict, "DescendantFonts");
	if (!dfonts)
		fz_throw(xref->ctx, "cid font is missing descendant fonts");

	dfont = pdf_array_get(dfonts, 0);

	subtype = pdf_dict_gets(dfont, "Subtype");
	encoding = pdf_dict_gets(dict, "Encoding");
	to_unicode = pdf_dict_gets(dict, "ToUnicode");

	if (pdf_is_name(subtype) && !strcmp(pdf_to_name(subtype), "CIDFontType0"))
		return load_cid_font(xref, dfont, encoding, to_unicode);
	else if (pdf_is_name(subtype) && !strcmp(pdf_to_name(subtype), "CIDFontType2"))
		return load_cid_font(xref, dfont, encoding, to_unicode);
	else
		fz_throw(xref->ctx, "syntaxerror: unknown cid font type");

	return NULL; /* Stupid MSVC */
}
Exemple #5
0
static int find_destination_pages(fz_context *ctx, pdf_obj *current, int page_num, pdf_obj **dest_pages, int *index)
{
	if(!strcmp(pdf_to_name(ctx, pdf_dict_gets(ctx, current, "Type")), "Page")) {
		return(--page_num);
	} if(!strcmp(pdf_to_name(ctx, pdf_dict_gets(ctx, current, "Type")), "Pages")) {
		pdf_obj *kids = pdf_dict_gets(ctx, current, "Kids");
		pdf_obj *count_obj = pdf_dict_gets(ctx, current, "Count");
		if(!pdf_is_array(ctx, kids) || !pdf_is_int(ctx, count_obj))
			return(-2);

		int count = pdf_to_int(ctx, count_obj);
		int i;
		for(i = 0; i < count; i++) {
			pdf_obj *current_kid = pdf_array_get(ctx, kids, i);

			page_num = find_destination_pages(ctx, current_kid, page_num, dest_pages, index);
			if(page_num == -1) {
				*index = i;
				*dest_pages = current;
				return(-2);
			} else if(page_num == -2) {
				return(-2); // just return, preserve index and dest_pages
			}
		}

		return(page_num);
	}

	return(page_num);
}
static fz_colorspace *
load_icc_based(pdf_document *doc, pdf_obj *dict)
{
	int n;

	n = pdf_to_int(pdf_dict_gets(dict, "N"));

	/* SumatraPDF: support alternate colorspaces for ICCBased */
	if (pdf_dict_gets(dict, "Alternate"))
	{
		fz_colorspace *cs_alt = pdf_load_colorspace(doc, pdf_dict_gets(dict, "Alternate"));
		if (cs_alt->n != n)
		{
			fz_drop_colorspace(doc->ctx, cs_alt);
			fz_throw(doc->ctx, FZ_ERROR_GENERIC, "ICCBased /Alternate colorspace must have %d components (not %d)", n, cs_alt->n);
		}
		return cs_alt;
	}

	switch (n)
	{
	case 1: return fz_device_gray(doc->ctx);
	case 3: return fz_device_rgb(doc->ctx);
	case 4: return fz_device_cmyk(doc->ctx);
	}

	fz_throw(doc->ctx, FZ_ERROR_GENERIC, "syntaxerror: ICCBased must have 1, 3 or 4 components");
	return NULL; /* Stupid MSVC */
}
Exemple #7
0
pdf_obj *
pdf_lookup_dest(pdf_document *xref, pdf_obj *needle)
{
	fz_context *ctx = xref->ctx;

	pdf_obj *root = pdf_dict_gets(xref->trailer, "Root");
	pdf_obj *dests = pdf_dict_gets(root, "Dests");
	pdf_obj *names = pdf_dict_gets(root, "Names");
	pdf_obj *dest = NULL;

	/* PDF 1.1 has destinations in a dictionary */
	if (dests)
	{
		if (pdf_is_name(needle))
			return pdf_dict_get(dests, needle);
		else
			return pdf_dict_gets(dests, pdf_to_str_buf(needle));
	}

	/* PDF 1.2 has destinations in a name tree */
	if (names && !dest)
	{
		pdf_obj *tree = pdf_dict_gets(names, "Dests");
		return pdf_lookup_name_imp(ctx, tree, needle);
	}

	return NULL;
}
Exemple #8
0
/* Find the point in a field hierarchy where all descendents
 * share the same name */
static pdf_obj *find_head_of_field_group(pdf_obj *obj)
{
	if (obj == NULL || pdf_dict_gets(obj, "T"))
		return obj;
	else
		return find_head_of_field_group(pdf_dict_gets(obj, "Parent"));
}
Exemple #9
0
static void
pdf_load_linear_shading(fz_context *ctx, pdf_document *doc, fz_shade *shade, pdf_obj *dict, int funcs, fz_function **func)
{
	pdf_obj *obj;
	float d0, d1;
	int e0, e1;

	obj = pdf_dict_gets(ctx, dict, "Coords");
	shade->u.l_or_r.coords[0][0] = pdf_to_real(ctx, pdf_array_get(ctx, obj, 0));
	shade->u.l_or_r.coords[0][1] = pdf_to_real(ctx, pdf_array_get(ctx, obj, 1));
	shade->u.l_or_r.coords[1][0] = pdf_to_real(ctx, pdf_array_get(ctx, obj, 2));
	shade->u.l_or_r.coords[1][1] = pdf_to_real(ctx, pdf_array_get(ctx, obj, 3));

	d0 = 0;
	d1 = 1;
	obj = pdf_dict_gets(ctx, dict, "Domain");
	if (obj)
	{
		d0 = pdf_to_real(ctx, pdf_array_get(ctx, obj, 0));
		d1 = pdf_to_real(ctx, pdf_array_get(ctx, obj, 1));
	}

	e0 = e1 = 0;
	obj = pdf_dict_gets(ctx, dict, "Extend");
	if (obj)
	{
		e0 = pdf_to_bool(ctx, pdf_array_get(ctx, obj, 0));
		e1 = pdf_to_bool(ctx, pdf_array_get(ctx, obj, 1));
	}

	pdf_sample_shade_function(ctx, shade, funcs, func, d0, d1);

	shade->u.l_or_r.extend[0] = e0;
	shade->u.l_or_r.extend[1] = e1;
}
Exemple #10
0
void
pdf_update_annot(pdf_document *doc, pdf_annot *annot)
{
	/* SumatraPDF: prevent regressions */
#if 0
	pdf_obj *obj, *ap, *as, *n;
	fz_context *ctx = doc->ctx;

	if (doc->update_appearance)
		doc->update_appearance(doc, annot);

	obj = annot->obj;

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

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

		n = NULL;

		if (hp->num == pdf_to_num(obj)
			&& hp->gen == pdf_to_gen(obj)
			&& (hp->state & HOTSPOT_POINTER_DOWN))
		{
			n = pdf_dict_gets(ap, "D"); /* down state */
		}

		if (n == NULL)
			n = pdf_dict_gets(ap, "N"); /* normal state */

		/* lookup current state in sub-dictionary */
		if (!pdf_is_stream(doc, pdf_to_num(n), pdf_to_gen(n)))
			n = pdf_dict_get(n, as);

		pdf_drop_xobject(ctx, annot->ap);
		annot->ap = NULL;

		if (pdf_is_stream(doc, pdf_to_num(n), pdf_to_gen(n)))
		{
			fz_try(ctx)
			{
				annot->ap = pdf_load_xobject(doc, n);
				pdf_transform_annot(annot);
				annot->ap_iteration = annot->ap->iteration;
			}
			fz_catch(ctx)
			{
				fz_rethrow_if(ctx, FZ_ERROR_TRYLATER);
				fz_warn(ctx, "ignoring broken annotation");
			}
		}
	}
#endif
}
Exemple #11
0
void
pdf_insert_page(pdf_document *doc, pdf_page *page, int at)
{
	fz_context *ctx = doc->ctx;
	int count = pdf_count_pages(doc);
	pdf_obj *parent, *kids;
	pdf_obj *page_ref;
	int i;

	page_ref = pdf_new_ref(doc, page->me);

	fz_try(ctx)
	{
		if (count == 0)
		{
			/* TODO: create new page tree? */
			fz_throw(ctx, FZ_ERROR_GENERIC, "empty page tree, cannot insert page");
		}
		else if (at >= count)
		{
			if (at > count)
				fz_throw(ctx, FZ_ERROR_GENERIC, "cannot insert page beyond end of page tree");

			/* append after last page */
			pdf_lookup_page_loc(doc, count - 1, &parent, &i);
			kids = pdf_dict_gets(parent, "Kids");
			pdf_array_insert(kids, page_ref, i + 1);
		}
		else
		{
			/* insert before found page */
			pdf_lookup_page_loc(doc, at, &parent, &i);
			kids = pdf_dict_gets(parent, "Kids");
			pdf_array_insert(kids, page_ref, i);
		}

		pdf_dict_puts(page->me, "Parent", parent);

		/* Adjust page counts */
		while (parent)
		{
			int count = pdf_to_int(pdf_dict_gets(parent, "Count"));
			pdf_dict_puts_drop(parent, "Count", pdf_new_int(doc, count + 1));
			parent = pdf_dict_gets(parent, "Parent");
		}

	}
	fz_always(ctx)
	{
		pdf_drop_obj(page_ref);
	}
	fz_catch(ctx)
	{
		fz_rethrow(ctx);
	}
}
Exemple #12
0
pdf_obj *
pdf_lookup_name(pdf_document *xref, char *which, pdf_obj *needle)
{
	fz_context *ctx = xref->ctx;

	pdf_obj *root = pdf_dict_gets(xref->trailer, "Root");
	pdf_obj *names = pdf_dict_gets(root, "Names");
	pdf_obj *tree = pdf_dict_gets(names, which);
	return pdf_lookup_name_imp(ctx, tree, needle);
}
Exemple #13
0
static int
pdf_pattern_uses_blending(pdf_document *doc, pdf_obj *dict)
{
	pdf_obj *obj;
	obj = pdf_dict_gets(dict, "Resources");
	if (pdf_resources_use_blending(doc, obj))
		return 1;
	obj = pdf_dict_gets(dict, "ExtGState");
	return pdf_extgstate_uses_blending(doc, obj);
}
Exemple #14
0
static int
pdf_resources_use_blending(pdf_document *doc, pdf_obj *rdb)
{
	fz_context *ctx = doc->ctx;
	pdf_obj *obj;
	int i, n, useBM = 0;

	if (!rdb)
		return 0;

	/* Have we been here before and remembered an answer? */
	if (pdf_obj_memo(rdb, &useBM))
		return useBM;

	/* stop on cyclic resource dependencies */
	if (pdf_mark_obj(rdb))
		return 0;

	fz_try(ctx)
	{
		obj = pdf_dict_gets(rdb, "ExtGState");
		n = pdf_dict_len(obj);
		for (i = 0; i < n; i++)
			if (pdf_extgstate_uses_blending(doc, pdf_dict_get_val(obj, i)))
				goto found;

		obj = pdf_dict_gets(rdb, "Pattern");
		n = pdf_dict_len(obj);
		for (i = 0; i < n; i++)
			if (pdf_pattern_uses_blending(doc, pdf_dict_get_val(obj, i)))
				goto found;

		obj = pdf_dict_gets(rdb, "XObject");
		n = pdf_dict_len(obj);
		for (i = 0; i < n; i++)
			if (pdf_xobject_uses_blending(doc, pdf_dict_get_val(obj, i)))
				goto found;
		if (0)
		{
found:
			useBM = 1;
		}
	}
	fz_always(ctx)
	{
		pdf_unmark_obj(rdb);
	}
	fz_catch(ctx)
	{
		fz_rethrow(ctx);
	}

	pdf_set_obj_memo(rdb, useBM);
	return useBM;
}
Exemple #15
0
pdf_obj *
pdf_lookup_page_loc(pdf_document *doc, int needle, pdf_obj **parentp, int *indexp)
{
	pdf_obj *root = pdf_dict_gets(pdf_trailer(doc), "Root");
	pdf_obj *node = pdf_dict_gets(root, "Pages");
	int skip = needle;
	pdf_obj *hit = pdf_lookup_page_loc_imp(doc, node, &skip, parentp, indexp);
	if (!hit)
		fz_throw(doc->ctx, FZ_ERROR_GENERIC, "cannot find page %d in page tree", needle);
	return hit;
}
Exemple #16
0
static void
gatherforms(int page, pdf_obj *pageref, pdf_obj *pageobj, pdf_obj *dict)
{
	int i, n;

	n = pdf_dict_len(dict);
	for (i = 0; i < n; i++)
	{
		pdf_obj *xobjdict;
		pdf_obj *type;
		pdf_obj *subtype;
		pdf_obj *group;
		pdf_obj *groupsubtype;
		pdf_obj *reference;
		int k;

		xobjdict = pdf_dict_get_val(dict, i);
		if (!pdf_is_dict(xobjdict))
		{
			fz_warn(ctx, "not a xobject dict (%d %d R)", pdf_to_num(xobjdict), pdf_to_gen(xobjdict));
			continue;
		}

		type = pdf_dict_gets(xobjdict, "Subtype");
		if (strcmp(pdf_to_name(type), "Form"))
			continue;

		subtype = pdf_dict_gets(xobjdict, "Subtype2");
		if (!strcmp(pdf_to_name(subtype), "PS"))
			continue;

		group = pdf_dict_gets(xobjdict, "Group");
		groupsubtype = pdf_dict_gets(group, "S");
		reference = pdf_dict_gets(xobjdict, "Ref");

		for (k = 0; k < forms; k++)
			if (!pdf_objcmp(form[k].u.form.obj, xobjdict))
				break;

		if (k < forms)
			continue;

		form = fz_resize_array(ctx, form, forms+1, sizeof(struct info));
		forms++;

		form[forms - 1].page = page;
		form[forms - 1].pageref = pageref;
		form[forms - 1].pageobj = pageobj;
		form[forms - 1].u.form.obj = xobjdict;
		form[forms - 1].u.form.groupsubtype = groupsubtype;
		form[forms - 1].u.form.reference = reference;
	}
}
Exemple #17
0
ErrorCode juggler_add_pages_from_file(juggler_t *dest, juggler_t *src, int dest_index)
{
	pdf_obj *dest_pages = pdf_dict_getp(dest->ctx, 
		pdf_trailer(dest->ctx, dest->pdf), "Root/Pages");
	int dest_pages_index = pdf_array_len(dest->ctx, 
		pdf_dict_gets(dest->ctx, dest_pages, "Kids"));
		
	/* be aware that this function does not change the two variables if the page
	   index is greater than the number of pages */
	find_destination_pages(dest->ctx, 
		dest_pages, dest_index, &dest_pages, &dest_pages_index);

	pdf_obj *dest_kids = pdf_dict_gets(dest->ctx, dest_pages, "Kids");
	if(!pdf_is_indirect(dest->ctx, dest_pages) || 
		!pdf_is_dict(dest->ctx, dest_pages) || !pdf_is_array(dest->ctx, dest_kids))
	{
		return(ERROR_INVALID_RANGE);
	}
	
	pdf_obj *pages_root = pdf_dict_getp(src->ctx, pdf_trailer(src->ctx, src->pdf), "Root/Pages");
	if(!pdf_is_indirect(src->ctx, pages_root) || !pdf_is_dict(src->ctx, pages_root))
		return(ERROR_NO_PAGES);

	/* if we copy the root pages-node and it's referenced objects, we will copy 
	   all pages and all objects those pages need */
	pdf_obj *new_pages_ref = copy_object_single(dest->ctx, dest->pdf, src->ctx, src->pdf, pages_root);

	/* insert new pages-node */
	pdf_array_insert_drop(dest->ctx, dest_kids, new_pages_ref, dest_pages_index);

	/* update the parent */
	pdf_obj *new_pages_parent = pdf_new_indirect(dest->ctx, dest->pdf, 
		pdf_to_num(dest->ctx, dest_pages), pdf_to_gen(dest->ctx, dest_pages));
	pdf_dict_puts_drop(dest->ctx, new_pages_ref, "Parent", new_pages_parent);

	/* TODO: If dest_pages contains anything inheritable but not the new node
	         we need to insert empty items to prevent this inerhitance */

	/* update count */
	int new_count = pdf_to_int(dest->ctx, 
		pdf_dict_gets(dest->ctx, dest_pages, "Count")) + src->pagecount;
	pdf_dict_puts_drop(dest->ctx, dest_pages, "Count", 
		pdf_new_int(dest->ctx, dest->pdf, new_count));

	/* let MuPDF rebuild the page tree */
	pdf_finish_edit(dest->ctx, dest->pdf);
	dest->pdf->page_count = new_count;

	/* update juggler's state */
	juggler_page_tree_changed_due_to_insert(dest, dest_index, src->pagecount);

	return(NoError);
}
Exemple #18
0
static void
pdf_load_radial_shading(fz_shade *shade, pdf_document *xref, pdf_obj *dict, int funcs, pdf_function **func)
{
	pdf_obj *obj;
	float d0, d1;
	int e0, e1;
	float x0, y0, r0, x1, y1, r1;
	struct vertex p1, p2;
	fz_context *ctx = xref->ctx;

	obj = pdf_dict_gets(dict, "Coords");
	x0 = pdf_to_real(pdf_array_get(obj, 0));
	y0 = pdf_to_real(pdf_array_get(obj, 1));
	r0 = pdf_to_real(pdf_array_get(obj, 2));
	x1 = pdf_to_real(pdf_array_get(obj, 3));
	y1 = pdf_to_real(pdf_array_get(obj, 4));
	r1 = pdf_to_real(pdf_array_get(obj, 5));

	d0 = 0;
	d1 = 1;
	obj = pdf_dict_gets(dict, "Domain");
	if (pdf_array_len(obj) == 2)
	{
		d0 = pdf_to_real(pdf_array_get(obj, 0));
		d1 = pdf_to_real(pdf_array_get(obj, 1));
	}

	e0 = e1 = 0;
	obj = pdf_dict_gets(dict, "Extend");
	if (pdf_array_len(obj) == 2)
	{
		e0 = pdf_to_bool(pdf_array_get(obj, 0));
		e1 = pdf_to_bool(pdf_array_get(obj, 1));
	}

	pdf_sample_shade_function(ctx, shade, funcs, func, d0, d1);

	shade->type = FZ_RADIAL;

	shade->extend[0] = e0;
	shade->extend[1] = e1;

	p1.x = x0;
	p1.y = y0;
	p1.c[0] = r0;
	pdf_add_vertex(ctx, shade, &p1);

	p2.x = x1;
	p2.y = y1;
	p2.c[0] = r1;
	pdf_add_vertex(ctx, shade, &p2);
}
fz_outline *
pdf_load_outline(pdf_document *xref)
{
	pdf_obj *root, *obj, *first;

	root = pdf_dict_gets(xref->trailer, "Root");
	obj = pdf_dict_gets(root, "Outlines");
	first = pdf_dict_gets(obj, "First");
	if (first)
		return pdf_load_outline_imp(xref, first);

	return NULL;
}
Exemple #20
0
static void
pdf_load_function_based_shading(fz_shade *shade, pdf_document *xref, pdf_obj *dict, pdf_function *func)
{
	pdf_obj *obj;
	float x0, y0, x1, y1;
	float fv[2];
	fz_matrix matrix;
	int xx, yy;
	fz_context *ctx = xref->ctx;
	float *p;

	x0 = y0 = 0;
	x1 = y1 = 1;
	obj = pdf_dict_gets(dict, "Domain");
	if (obj)
	{
		x0 = pdf_to_real(pdf_array_get(obj, 0));
		x1 = pdf_to_real(pdf_array_get(obj, 1));
		y0 = pdf_to_real(pdf_array_get(obj, 2));
		y1 = pdf_to_real(pdf_array_get(obj, 3));
	}

	obj = pdf_dict_gets(dict, "Matrix");
	if (obj)
		pdf_to_matrix(ctx, obj, &matrix);
	else
		matrix = fz_identity;
	shade->u.f.matrix = matrix;
	shade->u.f.xdivs = FUNSEGS;
	shade->u.f.ydivs = FUNSEGS;
	shade->u.f.fn_vals = fz_malloc(ctx, (FUNSEGS+1)*(FUNSEGS+1)*shade->colorspace->n*sizeof(float));
	shade->u.f.domain[0][0] = x0;
	shade->u.f.domain[0][1] = y0;
	shade->u.f.domain[1][0] = x1;
	shade->u.f.domain[1][1] = y1;

	p = shade->u.f.fn_vals;
	for (yy = 0; yy <= FUNSEGS; yy++)
	{
		fv[1] = y0 + (y1 - y0) * yy / FUNSEGS;

		for (xx = 0; xx <= FUNSEGS; xx++)
		{
			fv[0] = x0 + (x1 - x0) * xx / FUNSEGS;

			pdf_eval_function(ctx, func, fv, 2, p, shade->colorspace->n);
			p += shade->colorspace->n;
		}
	}
}
Exemple #21
0
pdf_pattern *
pdf_load_pattern(fz_context *ctx, pdf_document *doc, pdf_obj *dict)
{
	pdf_pattern *pat;
	pdf_obj *obj;

	if ((pat = pdf_find_item(ctx, pdf_drop_pattern_imp, dict)) != NULL)
	{
		return pat;
	}

	pat = fz_malloc_struct(ctx, pdf_pattern);
	FZ_INIT_STORABLE(pat, 1, pdf_drop_pattern_imp);
	pat->document = doc;
	pat->resources = NULL;
	pat->contents = NULL;

	fz_try(ctx)
	{
		/* Store pattern now, to avoid possible recursion if objects refer back to this one */
		pdf_store_item(ctx, dict, pat, pdf_pattern_size(pat));

		pat->ismask = pdf_to_int(ctx, pdf_dict_get(ctx, dict, PDF_NAME_PaintType)) == 2;
		pat->xstep = pdf_to_real(ctx, pdf_dict_get(ctx, dict, PDF_NAME_XStep));
		pat->ystep = pdf_to_real(ctx, pdf_dict_get(ctx, dict, PDF_NAME_YStep));

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

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

		pat->resources = pdf_dict_get(ctx, dict, PDF_NAME_Resources);
		if (pat->resources)
			pdf_keep_obj(ctx, pat->resources);

		pat->contents = pdf_keep_obj(ctx, dict);
	}
	fz_catch(ctx)
	{
		pdf_remove_item(ctx, pdf_drop_pattern_imp, dict);
		pdf_drop_pattern(ctx, pat);
		fz_rethrow_message(ctx, "cannot load pattern (%d %d R)", pdf_to_num(ctx, dict), pdf_to_gen(ctx, dict));
	}
	return pat;
}
Exemple #22
0
static void
pdf_load_mesh_params(pdf_document *xref, pdf_obj *dict, struct mesh_params *p)
{
	pdf_obj *obj;
	int i, n;

	p->x0 = p->y0 = 0;
	p->x1 = p->y1 = 1;
	for (i = 0; i < FZ_MAX_COLORS; i++)
	{
		p->c0[i] = 0;
		p->c1[i] = 1;
	}

	p->vprow = pdf_to_int(pdf_dict_gets(dict, "VerticesPerRow"));
	p->bpflag = pdf_to_int(pdf_dict_gets(dict, "BitsPerFlag"));
	p->bpcoord = pdf_to_int(pdf_dict_gets(dict, "BitsPerCoordinate"));
	p->bpcomp = pdf_to_int(pdf_dict_gets(dict, "BitsPerComponent"));

	obj = pdf_dict_gets(dict, "Decode");
	if (pdf_array_len(obj) >= 6)
	{
		n = (pdf_array_len(obj) - 4) / 2;
		p->x0 = pdf_to_real(pdf_array_get(obj, 0));
		p->x1 = pdf_to_real(pdf_array_get(obj, 1));
		p->y0 = pdf_to_real(pdf_array_get(obj, 2));
		p->y1 = pdf_to_real(pdf_array_get(obj, 3));
		for (i = 0; i < n; i++)
		{
			p->c0[i] = pdf_to_real(pdf_array_get(obj, 4 + i * 2));
			p->c1[i] = pdf_to_real(pdf_array_get(obj, 5 + i * 2));
		}
	}

	if (p->vprow < 2)
		p->vprow = 2;

	if (p->bpflag != 2 && p->bpflag != 4 && p->bpflag != 8)
		p->bpflag = 8;

	if (p->bpcoord != 1 && p->bpcoord != 2 && p->bpcoord != 4 &&
		p->bpcoord != 8 && p->bpcoord != 12 && p->bpcoord != 16 &&
		p->bpcoord != 24 && p->bpcoord != 32)
		p->bpcoord = 8;

	if (p->bpcomp != 1 && p->bpcomp != 2 && p->bpcomp != 4 &&
		p->bpcomp != 8 && p->bpcomp != 12 && p->bpcomp != 16)
		p->bpcomp = 8;
}
Exemple #23
0
static void info_update(fz_context *ctx,pdf_document *xref,char *producer)

    {
    char moddate[64];
    time_t now;
    struct tm date;
    pdf_obj *info;
    int newinfo;

    if (xref->trailer==NULL)
        return;
    time(&now);
    date=(*localtime(&now));
    sprintf(moddate,"D:%04d%02d%02d%02d%02d%02d%s",
           date.tm_year+1900,date.tm_mon+1,date.tm_mday,
           date.tm_hour,date.tm_min,date.tm_sec,
           wsys_utc_string());
    info=pdf_dict_gets(xref->trailer,"Info");
    if (info==NULL)
        {
        newinfo=1;
        info=pdf_new_dict(ctx,2);
        }
    else
        newinfo=0;
    dict_put_string(ctx,info,"Producer",producer);
    dict_put_string(ctx,info,"ModDate",moddate);
    if (newinfo)
        {
        pdf_dict_puts(xref->trailer,"Info",info);
        pdf_drop_obj(info);
        }
    }
Exemple #24
0
pdf_obj *
pdf_load_name_tree(pdf_document *xref, char *which)
{
	fz_context *ctx = xref->ctx;

	pdf_obj *root = pdf_dict_gets(xref->trailer, "Root");
	pdf_obj *names = pdf_dict_gets(root, "Names");
	pdf_obj *tree = pdf_dict_gets(names, which);
	if (pdf_is_dict(tree))
	{
		pdf_obj *dict = pdf_new_dict(ctx, 100);
		pdf_load_name_tree_imp(dict, xref, tree);
		return dict;
	}
	return NULL;
}
Exemple #25
0
/*
 * Build a filter for reading raw stream data.
 * This is a null filter to constrain reading to the
 * stream length, followed by a decryption filter.
 */
static fz_stream *
pdf_open_raw_filter(fz_stream *chain, pdf_document *xref, pdf_obj *stmobj, int num, int gen)
{
    int hascrypt;
    int len;
    fz_context *ctx = chain->ctx;

    /* don't close chain when we close this filter */
    fz_keep_stream(chain);

    len = pdf_to_int(pdf_dict_gets(stmobj, "Length"));
    chain = fz_open_null(chain, len);

    fz_try(ctx)
    {
        hascrypt = pdf_stream_has_crypt(ctx, stmobj);
        if (xref->crypt && !hascrypt)
            chain = pdf_open_crypt(chain, xref->crypt, num, gen);
    }
    fz_catch(ctx)
    {
        fz_close(chain);
        fz_rethrow(ctx);
    }

    return chain;
}
Exemple #26
0
static void
gatherdimensions(int page, pdf_obj *pageref, pdf_obj *pageobj)
{
	fz_rect bbox;
	pdf_obj *obj;
	int j;

	obj = pdf_dict_gets(pageobj, "MediaBox");
	if (!pdf_is_array(obj))
		return;

	bbox = pdf_to_rect(ctx, obj);

	for (j = 0; j < dims; j++)
		if (!memcmp(dim[j].u.dim.bbox, &bbox, sizeof (fz_rect)))
			break;

	if (j < dims)
		return;

	dims++;

	dim = fz_resize_array(ctx, dim, dims, sizeof(struct info));
	dim[dims - 1].page = page;
	dim[dims - 1].pageref = pageref;
	dim[dims - 1].pageobj = pageobj;
	dim[dims - 1].u.dim.bbox = fz_malloc(ctx, sizeof(fz_rect));
	memcpy(dim[dims - 1].u.dim.bbox, &bbox, sizeof (fz_rect));

	return;
}
Exemple #27
0
static pdf_obj *
resolve_dest_rec(pdf_document *xref, pdf_obj *dest, int depth)
{
	if (depth > 10) /* Arbitrary to avoid infinite recursion */
		return NULL;

	if (pdf_is_name(dest) || pdf_is_string(dest))
	{
		dest = pdf_lookup_dest(xref, dest);
		return resolve_dest_rec(xref, dest, depth+1);
	}

	else if (pdf_is_array(dest))
	{
		return dest;
	}

	else if (pdf_is_dict(dest))
	{
		dest = pdf_dict_gets(dest, "D");
		return resolve_dest_rec(xref, dest, depth+1);
	}

	else if (pdf_is_indirect(dest))
		return dest;

	return NULL;
}
Exemple #28
0
static pdf_font_desc *
pdf_load_simple_font(pdf_document *doc, pdf_obj *dict)
{
	char *basefont = pdf_to_name(pdf_dict_gets(dict, "BaseFont"));

	return pdf_load_simple_font_by_name(doc, dict, basefont);
}
Exemple #29
0
fz_buffer *
pdf_load_raw_renumbered_stream(pdf_document *xref, 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 < xref->len && xref->table[num].stm_buf)
		return fz_keep_buffer(xref->ctx, xref->table[num].stm_buf);

	dict = pdf_load_object(xref, num, gen);
	/* RJW: "cannot load stream dictionary (%d %d R)", num, gen */

	len = pdf_to_int(pdf_dict_gets(dict, "Length"));

	pdf_drop_obj(dict);

	stm = pdf_open_raw_renumbered_stream(xref, num, gen, orig_num, orig_gen);
	/* RJW: "cannot open raw stream (%d %d R)", num, gen */

	buf = fz_read_all(stm, len);
	/* RJW: "cannot read raw stream (%d %d R)", num, gen */

	fz_close(stm);
	return buf;
}
static fz_outline *
pdf_load_outline_imp(pdf_document *xref, pdf_obj *dict)
{
	fz_context *ctx = xref->ctx;
	fz_outline *node, **prev, *first;
	pdf_obj *obj;
	pdf_obj *odict = dict;

	fz_var(dict);

	fz_try(ctx)
	{
		first = NULL;
		prev = &first;
		while (dict && pdf_is_dict(dict))
		{
			if (pdf_dict_mark(dict))
				break;
			node = fz_malloc_struct(ctx, fz_outline);
			node->title = NULL;
			node->dest.kind = FZ_LINK_NONE;
			node->down = NULL;
			node->next = NULL;
			*prev = node;
			prev = &node->next;

			obj = pdf_dict_gets(dict, "Title");
			if (obj)
				node->title = pdf_to_utf8(ctx, obj);

			/* SumatraPDF: support expansion states */
			node->is_open = pdf_to_int(pdf_dict_gets(dict, "Count")) >= 0;

			if ((obj = pdf_dict_gets(dict, "Dest")))
				node->dest = pdf_parse_link_dest(xref, obj);
			else if ((obj = pdf_dict_gets(dict, "A")))
				node->dest = pdf_parse_action(xref, obj);

			obj = pdf_dict_gets(dict, "First");
			if (obj)
				node->down = pdf_load_outline_imp(xref, obj);

			dict = pdf_dict_gets(dict, "Next");
		}
	}
	fz_catch(ctx)
	{
		for (dict = odict; dict && pdf_dict_marked(dict); dict = pdf_dict_gets(dict, "Next"))
			pdf_dict_unmark(dict);
		fz_rethrow(ctx);
	}

	for (dict = odict; dict && pdf_dict_marked(dict); dict = pdf_dict_gets(dict, "Next"))
		pdf_dict_unmark(dict);

	return first;
}