Ejemplo n.º 1
0
void pdf_delete_portfolio_schema(fz_context *ctx, pdf_document *doc, int entry)
{
	pdf_portfolio **pp;
	pdf_portfolio *p;
	pdf_obj *s;

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

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

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

	p = *pp;
	if (p == NULL || entry)
		fz_throw(ctx, FZ_ERROR_GENERIC, "entry out of range in pdf_delete_portfolio_schema");
	*pp = p->next;

	/* Delete the key from the schema */
	s = pdf_dict_getl(ctx, pdf_trailer(ctx, doc), PDF_NAME_Root, PDF_NAME_Collection, PDF_NAME_Schema, NULL);
	pdf_dict_del(ctx, s, p->key);

	/* Delete this entry from all the collection entries */
	s = pdf_dict_getl(ctx, pdf_trailer(ctx, doc), PDF_NAME_Root, PDF_NAME_Names, PDF_NAME_EmbeddedFiles, NULL);
	pdf_name_tree_map(ctx, s, delete_from_node, p->key);

	pdf_drop_obj(ctx, p->entry.name);
	pdf_drop_obj(ctx, p->key);
	pdf_drop_obj(ctx, p->val);
	fz_free(ctx, p);
}
Ejemplo n.º 2
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);
}
Ejemplo n.º 3
0
pdf_obj *
pdf_lookup_dest(pdf_document *xref, pdf_obj *needle)
{
	fz_context *ctx = xref->ctx;

	pdf_obj *root = pdf_dict_gets(pdf_trailer(xref), "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;
}
Ejemplo n.º 4
0
static void
load_portfolio(fz_context *ctx, pdf_document *doc)
{
	pdf_obj *obj;
	int i, n;
	pdf_portfolio **pp;

	obj = pdf_dict_getl(ctx, pdf_trailer(ctx, doc), PDF_NAME_Root, PDF_NAME_Collection, PDF_NAME_Schema, NULL);

	n = pdf_dict_len(ctx, obj);
	for (i = 0; i < n; i++)
	{
		pdf_obj *k = pdf_dict_get_key(ctx, obj, i);
		pdf_obj *v = pdf_dict_get_val(ctx, obj, i);
		int sort = pdf_to_int(ctx, pdf_dict_get(ctx, v, PDF_NAME_O));
		pdf_obj *eo = pdf_dict_get(ctx, v, PDF_NAME_E);
		int editable = eo ? pdf_to_bool(ctx, eo) : 0;
		pdf_obj *vo = pdf_dict_get(ctx, v, PDF_NAME_V);
		int visible = vo ? pdf_to_bool(ctx, vo) : 1;
		char *subtype = pdf_to_name(ctx, pdf_dict_get(ctx, v, PDF_NAME_Subtype));
		pdf_obj *name = pdf_dict_get(ctx, v, PDF_NAME_N);
		pdf_portfolio *p = fz_malloc_struct(ctx, pdf_portfolio);
		p->key = pdf_keep_obj(ctx, k);
		p->val = pdf_keep_obj(ctx, v);
		p->sort = sort;
		p->entry.visible = visible;
		p->entry.editable = editable;
		p->entry.name = pdf_keep_obj(ctx, name);
		if (!strcmp(subtype, "S"))
			p->entry.type = PDF_SCHEMA_TEXT;
		else if (!strcmp(subtype, "D"))
			p->entry.type = PDF_SCHEMA_DATE;
		else if (!strcmp(subtype, "N"))
			p->entry.type = PDF_SCHEMA_NUMBER;
		else if (!strcmp(subtype, "F"))
			p->entry.type = PDF_SCHEMA_FILENAME;
		else if (!strcmp(subtype, "Desc"))
			p->entry.type = PDF_SCHEMA_DESC;
		else if (!strcmp(subtype, "ModDate"))
			p->entry.type = PDF_SCHEMA_MODDATE;
		else if (!strcmp(subtype, "CreationDate"))
			p->entry.type = PDF_SCHEMA_CREATIONDATE;
		else if (!strcmp(subtype, "Size"))
			p->entry.type = PDF_SCHEMA_SIZE;
		else
			p->entry.type = PDF_SCHEMA_UNKNOWN;

		/* Now insert p */
		pp = &doc->portfolio;

		while (*pp && (*pp)->sort <= p->sort)
			pp = &(*pp)->next;

		p->next = *pp;
		*pp = p;
	}
}
Ejemplo n.º 5
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(pdf_trailer(xref), "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);
}
Ejemplo n.º 6
0
int
pdf_count_pages(pdf_document *doc)
{
	if (doc->page_count == 0)
	{
		pdf_obj *count = pdf_dict_getp(pdf_trailer(doc), "Root/Pages/Count");
		doc->page_count = pdf_to_int(count);
	}
	return doc->page_count;
}
Ejemplo n.º 7
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;
}
Ejemplo n.º 8
0
fz_outline *
pdf_load_outline(fz_context *ctx, pdf_document *doc)
{
    pdf_obj *root, *obj, *first;

    root = pdf_dict_get(ctx, pdf_trailer(ctx, doc), PDF_NAME_Root);
    obj = pdf_dict_get(ctx, root, PDF_NAME_Outlines);
    first = pdf_dict_get(ctx, obj, PDF_NAME_First);
    if (first)
        return pdf_load_outline_imp(ctx, doc, first);

    return NULL;
}
Ejemplo n.º 9
0
static void
showglobalinfo(void)
{
	pdf_obj *obj;

	printf("\nPDF-%d.%d\n", doc->version / 10, doc->version % 10);

	obj = pdf_dict_gets(pdf_trailer(doc), "Info");
	if (obj)
	{
		printf("Info object (%d %d R):\n", pdf_to_num(obj), pdf_to_gen(obj));
		pdf_fprint_obj(stdout, pdf_resolve_indirect(obj), 0);
	}

	obj = pdf_dict_gets(pdf_trailer(doc), "Encrypt");
	if (obj)
	{
		printf("\nEncryption object (%d %d R):\n", pdf_to_num(obj), pdf_to_gen(obj));
		pdf_fprint_obj(stdout, pdf_resolve_indirect(obj), 0);
	}

	printf("\nPages: %d\n\n", pagecount);
}
Ejemplo n.º 10
0
pdf_obj *
pdf_load_name_tree(pdf_document *xref, char *which)
{
	fz_context *ctx = xref->ctx;

	pdf_obj *root = pdf_dict_gets(pdf_trailer(xref), "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;
}
Ejemplo n.º 11
0
DocumentInfo j_mu_get_doc_info(void* p_ctx, void* p_doc)
{
	fz_context* ctx = (fz_context*) p_ctx;
	pdf_document* doc = (pdf_document*)p_doc;
	pdf_obj* info = pdf_dict_gets(ctx, pdf_trailer(ctx, doc), "Info");

	DocumentInfo doc_info;
	if (info)
	{
		doc_info.author = get_prop_str(ctx, info, "Author");
		doc_info.creator = get_prop_str(ctx, info, "Creator");
		doc_info.creation_date = get_prop_str(ctx, info, "CreationDate");
		doc_info.producer = get_prop_str(ctx, info, "Producer");
		doc_info.title = get_prop_str(ctx, info, "Title");
	}
	return doc_info;
}
Ejemplo n.º 12
0
/*
	pdf_count_portfolio_entries: Get the number of portfolio entries
	in this document.

	doc: The document in question.
*/
int pdf_count_portfolio_entries(fz_context *ctx, pdf_document *doc)
{
	pdf_obj *s;
	int count;

	if (!doc)
		return 0;

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

	s = pdf_dict_getl(ctx, pdf_trailer(ctx, doc), PDF_NAME_Root, PDF_NAME_Names, PDF_NAME_EmbeddedFiles, NULL);
	count = 0;
	pdf_name_tree_map(ctx, s, count_nodes, &count);

	return count;
}
Ejemplo n.º 13
0
pdfout_data *
pdfout_page_labels_get (fz_context *ctx, pdf_document *doc)
{
  pdf_obj *trailer = pdf_trailer (ctx, doc);
  pdf_obj *labels_obj = pdf_dict_getp (ctx, trailer, "Root/PageLabels");
  pdf_obj *array = pdf_dict_gets (ctx, labels_obj, "Nums");

  if (array && pdf_is_array (ctx, array) == false)
    pdfout_throw (ctx, "Nums is not an array");
		  
  int length = pdf_array_len (ctx, array);

  pdfout_data *labels = pdfout_data_array_new (ctx);

  for (int i = 0; i < length / 2; ++i)
    {
      pdf_obj *object = pdf_array_get (ctx, array, 2 * i);
      
      if (pdf_is_int (ctx, object) == false)
	pdfout_throw (ctx, "key in number tree not an int");

      pdfout_data *hash = pdfout_data_hash_new (ctx);
      
      int page = pdf_to_int (ctx, object);
      if (page < 0)
	pdfout_throw (ctx, "key in number tree is < 0");

      push_int_key (ctx, hash, "page", page);
      
      pdf_obj *dict = pdf_array_get (ctx, array, 2 * i + 1);
      if (pdf_is_dict (ctx, dict) == false)
	pdfout_throw (ctx, "value in number tree not a dict");

      parse_dict (ctx, dict, hash);
      
      pdfout_data_array_push (ctx, labels, hash);
    }
  
  return labels;
}
Ejemplo n.º 14
0
fz_outline *
pdf_load_outline(fz_context *ctx, pdf_document *doc)
{
	pdf_obj *root, *obj, *first;
	fz_outline *outline = NULL;

	pdf_load_page_tree(ctx, doc); /* cache page tree for fast link destination lookups */
	fz_try(ctx)
	{
		root = pdf_dict_get(ctx, pdf_trailer(ctx, doc), PDF_NAME_Root);
		obj = pdf_dict_get(ctx, root, PDF_NAME_Outlines);
		first = pdf_dict_get(ctx, obj, PDF_NAME_First);
		if (first)
			outline = pdf_load_outline_imp(ctx, doc, first);
	}
	fz_always(ctx)
		pdf_drop_page_tree(ctx, doc);
	fz_catch(ctx)
		fz_rethrow(ctx);

	return outline;
}
Ejemplo n.º 15
0
void
pdfout_page_labels_set (fz_context *ctx, pdf_document *doc,
			pdfout_data *labels)
{
  if (labels)
    check_page_labels (ctx, labels);
  
  pdf_obj *root = pdf_dict_get (ctx, pdf_trailer (ctx, doc), PDF_NAME_Root);
  
  if (root == NULL)
    pdfout_throw (ctx, "no document catalog, cannot set/unset page labels");
  
  if (labels == NULL)
    {
      /* Remove page labels.  */
      pdf_dict_dels (ctx, root, "PageLabels");
      return;
    }

  int num = pdfout_data_array_len (ctx, labels);
  pdf_obj *array_obj = pdf_new_array (ctx, doc, 2 * num);
  
  for (int i = 0; i < num; ++i)
    {
      pdfout_data *hash = pdfout_data_array_get (ctx, labels, i);
      int page;
      pdf_obj *dict_obj = hash_to_pdf_dict (ctx, doc, hash, &page);

      pdf_obj *page_obj = pdf_new_int (ctx, doc, page);
      pdf_array_push_drop (ctx, array_obj, page_obj);
      
      pdf_array_push_drop (ctx, array_obj, dict_obj);
    }
      
  pdf_obj *labels_obj = pdf_new_dict (ctx, doc, 1);
  pdf_dict_puts_drop (ctx, labels_obj, "Nums", array_obj);
  pdf_dict_puts_drop (ctx, root, "PageLabels", labels_obj);
  
}
Ejemplo n.º 16
0
/*
	pdf_portfolio_entry_info: Fetch information about a given
	portfolio entry.

	doc: The document in question.

	entry: A value in the 0..n-1 range, where n is the
	value returned from pdf_count_portfolio.

	Returns pdf_object representing this entry. This reference
	is borrowed, so call pdf_keep_obj on it if you wish to keep
	it.
*/
pdf_obj *pdf_portfolio_entry_obj_name(fz_context *ctx, pdf_document *doc, int entry, pdf_obj **name)
{
	struct find_data data;
	pdf_obj *s;

	if (name)
		*name = NULL;

	if (!doc)
		return NULL;

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

	s = pdf_dict_getl(ctx, pdf_trailer(ctx, doc), PDF_NAME_Root, PDF_NAME_Names, PDF_NAME_EmbeddedFiles, NULL);
	data.count = entry;
	data.key = NULL;
	data.val = NULL;
	pdf_name_tree_map(ctx, s, find_entry, &data);

	if (name)
		*name = data.key;
	return data.val;
}
Ejemplo n.º 17
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)
		{
			pdf_obj *root = pdf_dict_gets(pdf_trailer(doc), "Root");
			parent = pdf_dict_gets(root, "Pages");
			if (!parent)
				fz_throw(doc->ctx, FZ_ERROR_GENERIC, "cannot find page tree");

			kids = pdf_dict_gets(parent, "Kids");
			if (!kids)
				fz_throw(doc->ctx, FZ_ERROR_GENERIC, "malformed page tree");

			pdf_array_insert(kids, page_ref, 0);
		}
		else if (at >= count)
		{
			if (at == INT_MAX)
				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);
	}

	doc->page_count = 0; /* invalidate cached value */
}
static void retainpages(fz_context *ctx, globals *glo, int argc, char **argv)
{
	pdf_obj *oldroot, *root, *pages, *kids, *countobj, *parent, *olddests;
	pdf_document *doc = glo->doc;
	int argidx = 0;
	pdf_obj *names_list = NULL;
	int pagecount;
	int i;

	/* Keep only pages/type and (reduced) dest entries to avoid
	 * references to unretained pages */
	oldroot = pdf_dict_get(ctx, pdf_trailer(ctx, doc), PDF_NAME_Root);
	pages = pdf_dict_get(ctx, oldroot, PDF_NAME_Pages);
	olddests = pdf_load_name_tree(ctx, doc, PDF_NAME_Dests);

	root = pdf_new_dict(ctx, doc, 2);
	pdf_dict_put(ctx, root, PDF_NAME_Type, pdf_dict_get(ctx, oldroot, PDF_NAME_Type));
	pdf_dict_put(ctx, root, PDF_NAME_Pages, pdf_dict_get(ctx, oldroot, PDF_NAME_Pages));

	pdf_update_object(ctx, doc, pdf_to_num(ctx, oldroot), root);

	pdf_drop_obj(ctx, root);

	/* Create a new kids array with only the pages we want to keep */
	parent = pdf_new_indirect(ctx, doc, pdf_to_num(ctx, pages), pdf_to_gen(ctx, pages));
	kids = pdf_new_array(ctx, doc, 1);

	/* Retain pages specified */
	while (argc - argidx)
	{
		int page, spage, epage;
		char *spec, *dash;
		char *pagelist = argv[argidx];

		pagecount = pdf_count_pages(ctx, doc);
		spec = fz_strsep(&pagelist, ",");
		while (spec)
		{
			dash = strchr(spec, '-');

			if (dash == spec)
				spage = epage = pagecount;
			else
				spage = epage = atoi(spec);

			if (dash)
			{
				if (strlen(dash) > 1)
					epage = atoi(dash + 1);
				else
					epage = pagecount;
			}

			spage = fz_clampi(spage, 1, pagecount);
			epage = fz_clampi(epage, 1, pagecount);

			if (spage < epage)
				for (page = spage; page <= epage; ++page)
					retainpage(ctx, doc, parent, kids, page);
			else
				for (page = spage; page >= epage; --page)
					retainpage(ctx, doc, parent, kids, page);

			spec = fz_strsep(&pagelist, ",");
		}

		argidx++;
	}

	pdf_drop_obj(ctx, parent);

	/* Update page count and kids array */
	countobj = pdf_new_int(ctx, doc, pdf_array_len(ctx, kids));
	pdf_dict_put(ctx, pages, PDF_NAME_Count, countobj);
	pdf_drop_obj(ctx, countobj);
	pdf_dict_put(ctx, pages, PDF_NAME_Kids, kids);
	pdf_drop_obj(ctx, kids);

	/* Also preserve the (partial) Dests name tree */
	if (olddests)
	{
		pdf_obj *names = pdf_new_dict(ctx, doc, 1);
		pdf_obj *dests = pdf_new_dict(ctx, doc, 1);
		int len = pdf_dict_len(ctx, olddests);

		names_list = pdf_new_array(ctx, doc, 32);

		for (i = 0; i < len; i++)
		{
			pdf_obj *key = pdf_dict_get_key(ctx, olddests, i);
			pdf_obj *val = pdf_dict_get_val(ctx, olddests, i);
			pdf_obj *dest = pdf_dict_get(ctx, val, PDF_NAME_D);

			dest = pdf_array_get(ctx, dest ? dest : val, 0);
			if (pdf_array_contains(ctx, pdf_dict_get(ctx, pages, PDF_NAME_Kids), dest))
			{
				pdf_obj *key_str = pdf_new_string(ctx, doc, pdf_to_name(ctx, key), strlen(pdf_to_name(ctx, key)));
				pdf_array_push(ctx, names_list, key_str);
				pdf_array_push(ctx, names_list, val);
				pdf_drop_obj(ctx, key_str);
			}
		}

		root = pdf_dict_get(ctx, pdf_trailer(ctx, doc), PDF_NAME_Root);
		pdf_dict_put(ctx, dests, PDF_NAME_Names, names_list);
		pdf_dict_put(ctx, names, PDF_NAME_Dests, dests);
		pdf_dict_put(ctx, root, PDF_NAME_Names, names);

		pdf_drop_obj(ctx, names);
		pdf_drop_obj(ctx, dests);
		pdf_drop_obj(ctx, names_list);
		pdf_drop_obj(ctx, olddests);
	}

	/* Force the next call to pdf_count_pages to recount */
	glo->doc->page_count = 0;

	/* Edit each pages /Annot list to remove any links that point to
	 * nowhere. */
	pagecount = pdf_count_pages(ctx, doc);
	for (i = 0; i < pagecount; i++)
	{
		pdf_obj *pageref = pdf_lookup_page_obj(ctx, doc, i);
		pdf_obj *pageobj = pdf_resolve_indirect(ctx, pageref);

		pdf_obj *annots = pdf_dict_get(ctx, pageobj, PDF_NAME_Annots);

		int len = pdf_array_len(ctx, annots);
		int j;

		for (j = 0; j < len; j++)
		{
			pdf_obj *o = pdf_array_get(ctx, annots, j);
			pdf_obj *p;

			if (!pdf_name_eq(ctx, pdf_dict_get(ctx, o, PDF_NAME_Subtype), PDF_NAME_Link))
				continue;

			p = pdf_dict_get(ctx, o, PDF_NAME_A);
			if (!pdf_name_eq(ctx, pdf_dict_get(ctx, p, PDF_NAME_S), PDF_NAME_GoTo))
				continue;

			if (string_in_names_list(ctx, pdf_dict_get(ctx, p, PDF_NAME_D), names_list))
				continue;

			/* FIXME: Should probably look at Next too */

			/* Remove this annotation */
			pdf_array_delete(ctx, annots, j);
			j--;
		}
	}
}
Ejemplo n.º 19
0
static void decimatepages(pdf_document *xref)
{
	pdf_obj *oldroot, *root, *pages, *kids, *parent;
	fz_context *ctx = xref->ctx;
	int num_pages = pdf_count_pages(xref);
	int page, kidcount;

	/* Keep only pages/type and (reduced) dest entries to avoid
	 * references to unretained pages */
	oldroot = pdf_dict_gets(pdf_trailer(xref), "Root");
	pages = pdf_dict_gets(oldroot, "Pages");

	root = pdf_new_dict(ctx, 2);
	pdf_dict_puts(root, "Type", pdf_dict_gets(oldroot, "Type"));
	pdf_dict_puts(root, "Pages", pdf_dict_gets(oldroot, "Pages"));

	pdf_update_object(xref, pdf_to_num(oldroot), root);

	pdf_drop_obj(root);

	/* Create a new kids array with only the pages we want to keep */
	parent = pdf_new_indirect(ctx, pdf_to_num(pages), pdf_to_gen(pages), xref);
	kids = pdf_new_array(ctx, 1);

	kidcount = 0;
	for (page=0; page < num_pages; page++)
	{
		pdf_page *page_details = pdf_load_page(xref, page);
		int xf = x_factor, yf = y_factor;
		int x, y;
		float w = page_details->mediabox.x1 - page_details->mediabox.x0;
		float h = page_details->mediabox.y1 - page_details->mediabox.y0;

		if (xf == 0 && yf == 0)
		{
			/* Nothing specified, so split along the long edge */
			if (w > h)
				xf = 2, yf = 1;
			else
				xf = 1, yf = 2;
		}
		else if (xf == 0)
			xf = 1;
		else if (yf == 0)
			yf = 1;

		for (y = yf-1; y >= 0; y--)
		{
			for (x = 0; x < xf; x++)
			{
				pdf_obj *newpageobj, *newpageref, *newmediabox;
				fz_rect mb;
				int num;

				newpageobj = pdf_copy_dict(ctx, xref->page_objs[page]);
				num = pdf_create_object(xref);
				pdf_update_object(xref, num, newpageobj);
				newpageref = pdf_new_indirect(ctx, num, 0, xref);

				newmediabox = pdf_new_array(ctx, 4);

				mb.x0 = page_details->mediabox.x0 + (w/xf)*x;
				if (x == xf-1)
					mb.x1 = page_details->mediabox.x1;
				else
					mb.x1 = page_details->mediabox.x0 + (w/xf)*(x+1);
				mb.y0 = page_details->mediabox.y0 + (h/yf)*y;
				if (y == yf-1)
					mb.y1 = page_details->mediabox.y1;
				else
					mb.y1 = page_details->mediabox.y0 + (h/yf)*(y+1);

				pdf_array_push(newmediabox, pdf_new_real(ctx, mb.x0));
				pdf_array_push(newmediabox, pdf_new_real(ctx, mb.y0));
				pdf_array_push(newmediabox, pdf_new_real(ctx, mb.x1));
				pdf_array_push(newmediabox, pdf_new_real(ctx, mb.y1));

				pdf_dict_puts(newpageobj, "Parent", parent);
				pdf_dict_puts(newpageobj, "MediaBox", newmediabox);

				/* Store page object in new kids array */
				pdf_array_push(kids, newpageref);

				kidcount++;
			}
		}
	}

	pdf_drop_obj(parent);

	/* Update page count and kids array */
	pdf_dict_puts(pages, "Count", pdf_new_int(ctx, kidcount));
	pdf_dict_puts(pages, "Kids", kids);
	pdf_drop_obj(kids);
}
Ejemplo n.º 20
0
int pdf_add_portfolio_entry(fz_context *ctx, pdf_document *doc,
				const char *name, int name_len,
				const char *desc, int desc_len,
				const char *filename, int filename_len,
				const char *unifile, int unifile_len, fz_buffer *buf)
{
	int entry, len;
	pdf_obj *ef, *f, *params, *s;
	pdf_obj *key;
	pdf_obj *val = NULL;

	fz_var(val);

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

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

	key = pdf_new_string(ctx, doc, name, name_len);
	fz_try(ctx)
	{
		val = pdf_new_dict(ctx, doc, 6);
		pdf_dict_put_drop(ctx, val, PDF_NAME_CI, pdf_new_dict(ctx, doc, 4));
		pdf_dict_put_drop(ctx, val, PDF_NAME_EF, (ef = pdf_new_dict(ctx, doc, 4)));
		pdf_dict_put_drop(ctx, val, PDF_NAME_F, pdf_new_string(ctx, doc, filename, filename_len));
		pdf_dict_put_drop(ctx, val, PDF_NAME_UF, pdf_new_string(ctx, doc, unifile, unifile_len));
		pdf_dict_put_drop(ctx, val, PDF_NAME_Desc, pdf_new_string(ctx, doc, desc, desc_len));
		pdf_dict_put_drop(ctx, val, PDF_NAME_Type, PDF_NAME_Filespec);
		pdf_dict_put_drop(ctx, ef, PDF_NAME_F, (f = pdf_add_stream(ctx, doc, buf, NULL, 0)));
		len = fz_buffer_storage(ctx, buf, NULL);
		pdf_dict_put_drop(ctx, f, PDF_NAME_DL, pdf_new_int(ctx, doc, len));
		pdf_dict_put_drop(ctx, f, PDF_NAME_Length, pdf_new_int(ctx, doc, len));
		pdf_dict_put_drop(ctx, f, PDF_NAME_Params, (params = pdf_new_dict(ctx, doc, 4)));
		pdf_dict_put_drop(ctx, params, PDF_NAME_Size, pdf_new_int(ctx, doc, len));

		s = pdf_dict_getl(ctx, pdf_trailer(ctx, doc), PDF_NAME_Root, PDF_NAME_Collection, NULL);
		if (s == NULL)
		{
			s = pdf_new_dict(ctx, doc, 4);
			pdf_dict_putl_drop(ctx, pdf_trailer(ctx, doc), s, PDF_NAME_Root, PDF_NAME_Collection, NULL);
		}

		s = pdf_dict_getl(ctx, pdf_trailer(ctx, doc), PDF_NAME_Root, PDF_NAME_Names, PDF_NAME_EmbeddedFiles, NULL);
		if (s == NULL)
		{
			s = pdf_new_dict(ctx, doc, 4);
			pdf_dict_putl_drop(ctx, pdf_trailer(ctx, doc), s, PDF_NAME_Root, PDF_NAME_Names, PDF_NAME_EmbeddedFiles, NULL);
		}
		entry = pdf_name_tree_insert(ctx, doc, s, key, val);
	}
	fz_always(ctx)
	{
		pdf_drop_obj(ctx, key);
		pdf_drop_obj(ctx, val);
	}
	fz_catch(ctx)
		fz_rethrow(ctx);

	return entry;
}
Ejemplo n.º 21
0
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);
}
Ejemplo n.º 22
0
char *
pdf_parse_link_action(fz_context *ctx, pdf_document *doc, pdf_obj *action, int pagenum)
{
	pdf_obj *obj, *dest, *file_spec;

	if (!action)
		return NULL;

	obj = pdf_dict_get(ctx, action, PDF_NAME_S);
	if (pdf_name_eq(ctx, PDF_NAME_GoTo, obj))
	{
		dest = pdf_dict_get(ctx, action, PDF_NAME_D);
		return pdf_parse_link_dest(ctx, doc, dest);
	}
	else if (pdf_name_eq(ctx, PDF_NAME_URI, obj))
	{
		/* URI entries are ASCII strings */
		const char *uri = pdf_to_str_buf(ctx, pdf_dict_get(ctx, action, PDF_NAME_URI));
		if (!fz_is_external_link(ctx, uri))
		{
			pdf_obj *uri_base_obj = pdf_dict_getp(ctx, pdf_trailer(ctx, doc), "Root/URI/Base");
			const char *uri_base = uri_base_obj ? pdf_to_str_buf(ctx, uri_base_obj) : "file://";
			char *new_uri = fz_malloc(ctx, strlen(uri_base) + strlen(uri) + 1);
			strcpy(new_uri, uri_base);
			strcat(new_uri, uri);
			return new_uri;
		}
		return fz_strdup(ctx, uri);
	}
	else if (pdf_name_eq(ctx, PDF_NAME_Launch, obj))
	{
		file_spec = pdf_dict_get(ctx, action, PDF_NAME_F);
		return pdf_parse_file_spec(ctx, doc, file_spec, NULL);
	}
	else if (pdf_name_eq(ctx, PDF_NAME_GoToR, obj))
	{
		dest = pdf_dict_get(ctx, action, PDF_NAME_D);
		file_spec = pdf_dict_get(ctx, action, PDF_NAME_F);
		return pdf_parse_file_spec(ctx, doc, file_spec, dest);
	}
	else if (pdf_name_eq(ctx, PDF_NAME_Named, obj))
	{
		dest = pdf_dict_get(ctx, action, PDF_NAME_N);

		if (pdf_name_eq(ctx, PDF_NAME_FirstPage, dest))
			pagenum = 0;
		else if (pdf_name_eq(ctx, PDF_NAME_LastPage, dest))
			pagenum = pdf_count_pages(ctx, doc) - 1;
		else if (pdf_name_eq(ctx, PDF_NAME_PrevPage, dest) && pagenum >= 0)
		{
			if (pagenum > 0)
				pagenum--;
		}
		else if (pdf_name_eq(ctx, PDF_NAME_NextPage, dest) && pagenum >= 0)
		{
			if (pagenum < pdf_count_pages(ctx, doc) - 1)
				pagenum++;
		}
		else
			return NULL;

		return fz_asprintf(ctx, "#%d", pagenum + 1);
	}

	return NULL;
}
Ejemplo n.º 23
0
static void retainpages(fz_context *ctx, globals *glo, int argc, char **argv)
{
	pdf_obj *oldroot, *root, *pages, *kids, *countobj, *parent, *olddests;
	pdf_document *doc = glo->doc;
	int argidx = 0;
	pdf_obj *names_list = NULL;
	pdf_obj *outlines;
	int pagecount;
	int i;
	int *page_object_nums;

	/* Keep only pages/type and (reduced) dest entries to avoid
	 * references to unretained pages */
	oldroot = pdf_dict_get(ctx, pdf_trailer(ctx, doc), PDF_NAME_Root);
	pages = pdf_dict_get(ctx, oldroot, PDF_NAME_Pages);
	olddests = pdf_load_name_tree(ctx, doc, PDF_NAME_Dests);
	outlines = pdf_dict_get(ctx, oldroot, PDF_NAME_Outlines);

	root = pdf_new_dict(ctx, doc, 3);
	pdf_dict_put(ctx, root, PDF_NAME_Type, pdf_dict_get(ctx, oldroot, PDF_NAME_Type));
	pdf_dict_put(ctx, root, PDF_NAME_Pages, pdf_dict_get(ctx, oldroot, PDF_NAME_Pages));
	pdf_dict_put(ctx, root, PDF_NAME_Outlines, outlines);

	pdf_update_object(ctx, doc, pdf_to_num(ctx, oldroot), root);

	/* Create a new kids array with only the pages we want to keep */
	parent = pdf_new_indirect(ctx, doc, pdf_to_num(ctx, pages), pdf_to_gen(ctx, pages));
	kids = pdf_new_array(ctx, doc, 1);

	/* Retain pages specified */
	while (argc - argidx)
	{
		int page, spage, epage;
		char *spec, *dash;
		char *pagelist = argv[argidx];

		pagecount = pdf_count_pages(ctx, doc);
		spec = fz_strsep(&pagelist, ",");
		while (spec)
		{
			dash = strchr(spec, '-');

			if (dash == spec)
				spage = epage = pagecount;
			else
				spage = epage = atoi(spec);

			if (dash)
			{
				if (strlen(dash) > 1)
					epage = atoi(dash + 1);
				else
					epage = pagecount;
			}

			spage = fz_clampi(spage, 1, pagecount);
			epage = fz_clampi(epage, 1, pagecount);

			if (spage < epage)
				for (page = spage; page <= epage; ++page)
					retainpage(ctx, doc, parent, kids, page);
			else
				for (page = spage; page >= epage; --page)
					retainpage(ctx, doc, parent, kids, page);

			spec = fz_strsep(&pagelist, ",");
		}

		argidx++;
	}

	pdf_drop_obj(ctx, parent);

	/* Update page count and kids array */
	countobj = pdf_new_int(ctx, doc, pdf_array_len(ctx, kids));
	pdf_dict_put(ctx, pages, PDF_NAME_Count, countobj);
	pdf_drop_obj(ctx, countobj);
	pdf_dict_put(ctx, pages, PDF_NAME_Kids, kids);
	pdf_drop_obj(ctx, kids);

	/* Force the next call to pdf_count_pages to recount */
	glo->doc->page_count = 0;

	pagecount = pdf_count_pages(ctx, doc);
	page_object_nums = fz_calloc(ctx, pagecount, sizeof(*page_object_nums));
	for (i = 0; i < pagecount; i++)
	{
		pdf_obj *pageref = pdf_lookup_page_obj(ctx, doc, i);
		page_object_nums[i] = pdf_to_num(ctx, pageref);
	}

	/* If we had an old Dests tree (now reformed as an olddests
	 * dictionary), keep any entries in there that point to
	 * valid pages. This may mean we keep more than we need, but
	 * it's safe at least. */
	if (olddests)
	{
		pdf_obj *names = pdf_new_dict(ctx, doc, 1);
		pdf_obj *dests = pdf_new_dict(ctx, doc, 1);
		int len = pdf_dict_len(ctx, olddests);

		names_list = pdf_new_array(ctx, doc, 32);

		for (i = 0; i < len; i++)
		{
			pdf_obj *key = pdf_dict_get_key(ctx, olddests, i);
			pdf_obj *val = pdf_dict_get_val(ctx, olddests, i);
			pdf_obj *dest = pdf_dict_get(ctx, val, PDF_NAME_D);

			dest = pdf_array_get(ctx, dest ? dest : val, 0);
			if (dest_is_valid_page(ctx, dest, page_object_nums, pagecount))
			{
				pdf_obj *key_str = pdf_new_string(ctx, doc, pdf_to_name(ctx, key), strlen(pdf_to_name(ctx, key)));
				pdf_array_push(ctx, names_list, key_str);
				pdf_array_push(ctx, names_list, val);
				pdf_drop_obj(ctx, key_str);
			}
		}

		pdf_dict_put(ctx, dests, PDF_NAME_Names, names_list);
		pdf_dict_put(ctx, names, PDF_NAME_Dests, dests);
		pdf_dict_put(ctx, root, PDF_NAME_Names, names);

		pdf_drop_obj(ctx, names);
		pdf_drop_obj(ctx, dests);
		pdf_drop_obj(ctx, olddests);
	}

	/* Edit each pages /Annot list to remove any links that point to
	 * nowhere. */
	for (i = 0; i < pagecount; i++)
	{
		pdf_obj *pageref = pdf_lookup_page_obj(ctx, doc, i);
		pdf_obj *pageobj = pdf_resolve_indirect(ctx, pageref);

		pdf_obj *annots = pdf_dict_get(ctx, pageobj, PDF_NAME_Annots);

		int len = pdf_array_len(ctx, annots);
		int j;

		for (j = 0; j < len; j++)
		{
			pdf_obj *o = pdf_array_get(ctx, annots, j);

			if (!pdf_name_eq(ctx, pdf_dict_get(ctx, o, PDF_NAME_Subtype), PDF_NAME_Link))
				continue;

			if (!dest_is_valid(ctx, o, pagecount, page_object_nums, names_list))
			{
				/* Remove this annotation */
				pdf_array_delete(ctx, annots, j);
				j--;
			}
		}
	}

	if (strip_outlines(ctx, doc, outlines, pagecount, page_object_nums, names_list) == 0)
	{
		pdf_dict_del(ctx, root, PDF_NAME_Outlines);
	}

	fz_free(ctx, page_object_nums);
	pdf_drop_obj(ctx, names_list);
	pdf_drop_obj(ctx, root);
}
Ejemplo n.º 24
0
/*
	When resetting or submitting a form, the fields to act upon are defined
	by an array of either field references or field names, plus a flag determining
	whether to act upon the fields in the array, or all fields other than those in
	the array. specified_fields interprets this information and produces the array
	of fields to be acted upon.
*/
static pdf_obj *specified_fields(pdf_document *doc, pdf_obj *fields, int exclude)
{
	fz_context *ctx = doc->ctx;
	pdf_obj *form = pdf_dict_getp(pdf_trailer(doc), "Root/AcroForm/Fields");
	int i, n;
	pdf_obj *result = pdf_new_array(doc, 0);
	pdf_obj *nil = NULL;

	fz_var(nil);
	fz_try(ctx)
	{
		/* The 'fields' array not being present signals that all fields
		* should be acted upon, so handle it using the exclude case - excluding none */
		if (exclude || !fields)
		{
			/* mark the fields we don't want to act upon */
			nil = pdf_new_null(doc);

			n = pdf_array_len(fields);

			for (i = 0; i < n; i++)
			{
				pdf_obj *field = pdf_array_get(fields, i);

				if (pdf_is_string(field))
					field = pdf_lookup_field(form, pdf_to_str_buf(field));

				if (field)
					pdf_dict_puts(field, "Exclude", nil);
			}

			/* Act upon all unmarked fields */
			n = pdf_array_len(form);

			for (i = 0; i < n; i++)
				add_field_hierarchy_to_array(result, pdf_array_get(form, i));

			/* Unmark the marked fields */
			n = pdf_array_len(fields);

			for (i = 0; i < n; i++)
			{
				pdf_obj *field = pdf_array_get(fields, i);

				if (pdf_is_string(field))
					field = pdf_lookup_field(form, pdf_to_str_buf(field));

				if (field)
					pdf_dict_dels(field, "Exclude");
			}
		}
		else
		{
			n = pdf_array_len(fields);

			for (i = 0; i < n; i++)
			{
				pdf_obj *field = pdf_array_get(fields, i);

				if (pdf_is_string(field))
					field = pdf_lookup_field(form, pdf_to_str_buf(field));

				if (field)
					add_field_hierarchy_to_array(result, field);
			}
		}
	}
	fz_always(ctx)
	{
		pdf_drop_obj(nil);
	}
	fz_catch(ctx)
	{
		pdf_drop_obj(result);
		fz_rethrow(ctx);
	}

	return result;
}
Ejemplo n.º 25
0
static void decimatepages(fz_context *ctx, pdf_document *doc)
{
	pdf_obj *oldroot, *root, *pages, *kids, *parent;
	int num_pages = pdf_count_pages(ctx, doc);
	int page, kidcount;

	oldroot = pdf_dict_get(ctx, pdf_trailer(ctx, doc), PDF_NAME_Root);
	pages = pdf_dict_get(ctx, oldroot, PDF_NAME_Pages);

	root = pdf_new_dict(ctx, doc, 2);
	pdf_dict_put(ctx, root, PDF_NAME_Type, pdf_dict_get(ctx, oldroot, PDF_NAME_Type));
	pdf_dict_put(ctx, root, PDF_NAME_Pages, pdf_dict_get(ctx, oldroot, PDF_NAME_Pages));

	pdf_update_object(ctx, doc, pdf_to_num(ctx, oldroot), root);

	pdf_drop_obj(ctx, root);

	/* Create a new kids array with our new pages in */
	parent = pdf_new_indirect(ctx, doc, pdf_to_num(ctx, pages), pdf_to_gen(ctx, pages));
	kids = pdf_new_array(ctx, doc, 1);

	kidcount = 0;
	for (page=0; page < num_pages; page++)
	{
		pdf_page *page_details = pdf_load_page(ctx, doc, page);
		int xf = x_factor, yf = y_factor;
		int x, y;
		float w = page_details->mediabox.x1 - page_details->mediabox.x0;
		float h = page_details->mediabox.y1 - page_details->mediabox.y0;

		if (xf == 0 && yf == 0)
		{
			/* Nothing specified, so split along the long edge */
			if (w > h)
				xf = 2, yf = 1;
			else
				xf = 1, yf = 2;
		}
		else if (xf == 0)
			xf = 1;
		else if (yf == 0)
			yf = 1;

		for (y = yf-1; y >= 0; y--)
		{
			for (x = 0; x < xf; x++)
			{
				pdf_obj *newpageobj, *newpageref, *newmediabox;
				fz_rect mb;
				int num;

				newpageobj = pdf_copy_dict(ctx, pdf_lookup_page_obj(ctx, doc, page));
				num = pdf_create_object(ctx, doc);
				pdf_update_object(ctx, doc, num, newpageobj);
				newpageref = pdf_new_indirect(ctx, doc, num, 0);

				newmediabox = pdf_new_array(ctx, doc, 4);

				mb.x0 = page_details->mediabox.x0 + (w/xf)*x;
				if (x == xf-1)
					mb.x1 = page_details->mediabox.x1;
				else
					mb.x1 = page_details->mediabox.x0 + (w/xf)*(x+1);
				mb.y0 = page_details->mediabox.y0 + (h/yf)*y;
				if (y == yf-1)
					mb.y1 = page_details->mediabox.y1;
				else
					mb.y1 = page_details->mediabox.y0 + (h/yf)*(y+1);

				pdf_array_push(ctx, newmediabox, pdf_new_real(ctx, doc, mb.x0));
				pdf_array_push(ctx, newmediabox, pdf_new_real(ctx, doc, mb.y0));
				pdf_array_push(ctx, newmediabox, pdf_new_real(ctx, doc, mb.x1));
				pdf_array_push(ctx, newmediabox, pdf_new_real(ctx, doc, mb.y1));

				pdf_dict_put(ctx, newpageobj, PDF_NAME_Parent, parent);
				pdf_dict_put(ctx, newpageobj, PDF_NAME_MediaBox, newmediabox);

				/* Store page object in new kids array */
				pdf_array_push(ctx, kids, newpageref);

				kidcount++;
			}
		}
	}

	pdf_drop_obj(ctx, parent);

	/* Update page count and kids array */
	pdf_dict_put(ctx, pages, PDF_NAME_Count, pdf_new_int(ctx, doc, kidcount));
	pdf_dict_put(ctx, pages, PDF_NAME_Kids, kids);
	pdf_drop_obj(ctx, kids);
}