Esempio n. 1
0
pdf_obj *
pdf_new_xobject(pdf_document *xref, fz_rect *bbox, 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 = xref->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(ctx, 0);

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

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

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

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

		res = pdf_new_dict(ctx, 0);
		procset = pdf_new_array(ctx, 2);
		obj = pdf_new_name(ctx, "PDF");
		pdf_array_push(procset, obj);
		pdf_drop_obj(obj);
		obj = NULL;
		obj = pdf_new_name(ctx, "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(ctx, "Form");
		pdf_dict_puts(dict, "Subtype", obj);
		pdf_drop_obj(obj);
		obj = NULL;

		obj = pdf_new_name(ctx, "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(xref);
		pdf_update_object(xref, idict_num, dict);
		idict = pdf_new_indirect(ctx, idict_num, 0, xref);
		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_throw(ctx, "failed to create xobject)");
	}

	return idict;
}
Esempio n. 2
0
static pdf_obj *
make_param_Cal (png_byte color_type,
		double G, /* Gamma */
		double xw, double yw,
		double xr, double yr, double xg, double yg, double xb, double yb)
{
  pdf_obj *cal_param;
  pdf_obj *white_point, *matrix, *dev_gamma;
  double Xw, Yw, Zw; /* Yw = 1.0 */
  double Xr, Xg, Xb, Yr, Yb, Yg, Zr, Zg, Zb;

#ifndef ABS
#define ABS(x) ((x) < 0 ? -(x) : (x))
#endif
  /*
   * TODO: Check validity
   *
   * Conversion found in
   *
   *  com.sixlegs.image.png - Java package to read and display PNG images
   *  Copyright (C) 1998, 1999, 2001 Chris Nokleberg
   *
   *  http://www.sixlegs.com/software/png/
   *
   */
  {
    double zw, zr, zg, zb;
    double fr, fg, fb;
    double det;

    /* WhitePoint */
    zw = 1 - (xw + yw);
    zr = 1 - (xr + yr); zg = 1 - (xg + yg); zb = 1 - (xb + yb);
    Xw = xw / yw; Yw = 1.0; Zw = zw / yw;

    /* Matrix */
    det = xr * (yg * zb - zg * yb) - xg * (yr * zb - zr * yb) + xb * (yr * zg - zr * yg);
    if (ABS(det) < 1.0e-10) {
      WARN("Non invertible matrix: Maybe invalid value(s) specified in cHRM chunk.");
      return NULL;
    }
    fr  = (Xw * (yg * zb - zg * yb) - xg * (zb - Zw * yb) + xb * (zg - Zw * yg)) / det;
    fg  = (xr * (zb - Zw * yb) - Xw * (yr * zb - zr * yb) + xb * (yr * Zw - zr)) / det;
    fb  = (xr * (yg * Zw - zg) - xg * (yr * Zw - zr) + Xw * (yr * zg - zr * yg)) / det;
    Xr = fr * xr; Yr = fr * yr; Zr = fr * zr;
    Xg = fg * xg; Yg = fg * yg; Zg = fg * zg;
    Xb = fb * xb; Yb = fb * yb; Zb = fb * zb;
  }

  if (G < 1.0e-2) {
    WARN("Unusual Gamma specified: 1.0 / %g", G);
    return NULL;
  }

  cal_param = pdf_new_dict();

  /* White point is always required. */
  white_point = pdf_new_array();
  pdf_add_array(white_point, pdf_new_number(ROUND(Xw, 0.00001)));
  pdf_add_array(white_point, pdf_new_number(ROUND(Yw, 0.00001)));
  pdf_add_array(white_point, pdf_new_number(ROUND(Zw, 0.00001)));
  pdf_add_dict(cal_param, pdf_new_name("WhitePoint"), white_point);

  /* Matrix - default: Identity */
  if (color_type & PNG_COLOR_MASK_COLOR) {
    if (G != 1.0) {
      dev_gamma = pdf_new_array();
      pdf_add_array(dev_gamma, pdf_new_number(ROUND(G, 0.00001)));
      pdf_add_array(dev_gamma, pdf_new_number(ROUND(G, 0.00001)));
      pdf_add_array(dev_gamma, pdf_new_number(ROUND(G, 0.00001)));
      pdf_add_dict(cal_param, pdf_new_name("Gamma"), dev_gamma);
    }

    matrix = pdf_new_array();
    pdf_add_array(matrix, pdf_new_number(ROUND(Xr, 0.00001)));
    pdf_add_array(matrix, pdf_new_number(ROUND(Yr, 0.00001)));
    pdf_add_array(matrix, pdf_new_number(ROUND(Zr, 0.00001)));
    pdf_add_array(matrix, pdf_new_number(ROUND(Xg, 0.00001)));
    pdf_add_array(matrix, pdf_new_number(ROUND(Yg, 0.00001)));
    pdf_add_array(matrix, pdf_new_number(ROUND(Zg, 0.00001)));
    pdf_add_array(matrix, pdf_new_number(ROUND(Xb, 0.00001)));
    pdf_add_array(matrix, pdf_new_number(ROUND(Yb, 0.00001)));
    pdf_add_array(matrix, pdf_new_number(ROUND(Zb, 0.00001)));
    pdf_add_dict (cal_param, pdf_new_name("Matrix"), matrix);
  } else { /* Gray */
    if (G != 1.0)
      pdf_add_dict(cal_param,
		   pdf_new_name("Gamma"),
		   pdf_new_number(ROUND(G, 0.00001)));
  }

  return cal_param;
}
static void retainpages(int argc, char **argv)
{
	pdf_obj *oldroot, *root, *pages, *kids, *countobj, *parent, *olddests;

	/* Keep only pages/type and (reduced) dest entries to avoid
	 * references to unretained pages */
	oldroot = pdf_dict_gets(xref->trailer, "Root");
	pages = pdf_dict_gets(oldroot, "Pages");
	olddests = pdf_load_name_tree(xref, "Dests");

	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);

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

		pagecount = pdf_count_pages(xref);
		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;
			}

			if (spage > epage)
				page = spage, spage = epage, epage = page;

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

			for (page = spage; page <= epage; page++)
			{
				pdf_obj *pageobj = xref->page_objs[page-1];
				pdf_obj *pageref = xref->page_refs[page-1];

				pdf_dict_puts(pageobj, "Parent", parent);

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

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

		fz_optind++;
	}

	pdf_drop_obj(parent);

	/* Update page count and kids array */
	countobj = pdf_new_int(ctx, pdf_array_len(kids));
	pdf_dict_puts(pages, "Count", countobj);
	pdf_drop_obj(countobj);
	pdf_dict_puts(pages, "Kids", kids);
	pdf_drop_obj(kids);

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

		for (i = 0; i < len; i++)
		{
			pdf_obj *key = pdf_dict_get_key(olddests, i);
			pdf_obj *val = pdf_dict_get_val(olddests, i);
			pdf_obj *key_str = pdf_new_string(ctx, pdf_to_name(key), strlen(pdf_to_name(key)));
			pdf_obj *dest = pdf_dict_gets(val, "D");

			dest = pdf_array_get(dest ? dest : val, 0);
			if (pdf_array_contains(pdf_dict_gets(pages, "Kids"), dest))
			{
				pdf_array_push(names_list, key_str);
				pdf_array_push(names_list, val);
			}
			pdf_drop_obj(key_str);
		}

		root = pdf_dict_gets(xref->trailer, "Root");
		pdf_dict_puts(dests, "Names", names_list);
		pdf_dict_puts(names, "Dests", dests);
		pdf_dict_puts(root, "Names", names);

		pdf_drop_obj(names);
		pdf_drop_obj(dests);
		pdf_drop_obj(names_list);
		pdf_drop_obj(olddests);
	}
}
Esempio n. 4
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;
	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--;
		}
	}
}
Esempio n. 5
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);
}
Esempio n. 6
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);

				intersect_box(ctx, doc, newpageobj, PDF_NAME_CropBox, &mb);
				intersect_box(ctx, doc, newpageobj, PDF_NAME_BleedBox, &mb);
				intersect_box(ctx, doc, newpageobj, PDF_NAME_TrimBox, &mb);
				intersect_box(ctx, doc, newpageobj, PDF_NAME_ArtBox, &mb);

				/* 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);
}
Esempio n. 7
0
int
bmp_include_image (pdf_ximage *ximage, FILE *fp)
{
  pdf_obj *stream, *stream_dict, *colorspace;
  ximage_info     info;
  struct hdr_info hdr;
  int  num_palette, flip;
  int  i;

  pdf_ximage_init_image_info(&info);

  stream = stream_dict = colorspace = NULL;

  rewind(fp);
  if (read_header(fp, &hdr) < 0)
    return -1;

  get_density(&info.xdensity, &info.ydensity, &hdr);
  info.width  = hdr.width;
  info.height = hdr.height;
  if (info.height < 0) {
    info.height = -info.height;
    flip = 0;
  } else {
    flip = 1;
  }


  if (hdr.bit_count < 24) {
    if (hdr.bit_count != 1 &&
        hdr.bit_count != 4 && hdr.bit_count != 8) {
      WARN("Unsupported palette size: %ld", hdr.bit_count);
      return -1;
    }
    num_palette = (hdr.offset - hdr.hsize - DIB_FILE_HEADER_SIZE) / hdr.psize;
    info.bits_per_component = hdr.bit_count;
    info.num_components = 1;
  } else if (hdr.bit_count == 24) { /* full color */
    num_palette = 1; /* dummy */
    info.bits_per_component = 8;
    info.num_components = 3;
  } else {
    WARN("Unkown/Unsupported BMP bitCount value: %ld", hdr.bit_count);
    return -1;
  }

  if (info.width == 0 || info.height == 0 || num_palette < 1) {
    WARN("Invalid BMP file: width=%ld, height=%ld, #palette=%d",
   info.width, info.height, num_palette);
    return -1;
  }

  /* Start reading raster data */
  stream      = pdf_new_stream(STREAM_COMPRESS);
  stream_dict = pdf_stream_dict(stream);

  /* Color space: Indexed or DeviceRGB */
  if (hdr.bit_count < 24) {
    pdf_obj *lookup;
    unsigned char *palette, bgrq[4];

    palette = NEW(num_palette*3+1, unsigned char);
    for (i = 0; i < num_palette; i++) {
      if (fread(bgrq, 1,  hdr.psize, fp) != hdr.psize) {
        WARN("Reading file failed...");
        RELEASE(palette);
        return -1;
      }
      /* BGR data */
      palette[3*i  ] = bgrq[2];
      palette[3*i+1] = bgrq[1];
      palette[3*i+2] = bgrq[0];
    }
    lookup = pdf_new_string(palette, num_palette*3);
    RELEASE(palette);

    colorspace = pdf_new_array();
    pdf_add_array(colorspace, pdf_new_name("Indexed"));
    pdf_add_array(colorspace, pdf_new_name("DeviceRGB"));
    pdf_add_array(colorspace, pdf_new_number(num_palette-1));
    pdf_add_array(colorspace, lookup);
  } else {
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(xref->trailer, "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);
}
Esempio n. 9
0
static int wmupdf_pdfdoc_newpages(pdf_document *xref,fz_context *ctx,WPDFPAGEINFO *pageinfo,
                                  int use_forms,FILE *out)

    {
    static char *funcname="wmupdf_pdfdoc_newpages";
    pdf_obj *root,*oldroot,*pages,*kids,*countobj,*parent,*olddests;
    pdf_obj *srcpageobj,*srcpagecontents;
    pdf_obj *destpageobj,*destpagecontents,*destpageresources;
    double srcx0,srcy0;
    int qref,i,i0,pagecount,srccount,destpageref,nbb;
    int *srcpageused;
    char *bigbuf;
    double srcpagerot;

    /* Avoid compiler warning */
    destpageref = 0;
    destpageobj = NULL;
    srcx0=srcy0=0.;
    /* Keep only pages/type and (reduced) dest entries to avoid references to unretained pages */
    pagecount = pdf_count_pages(xref);
    if (use_forms)
        {
        willus_mem_alloc_warn((void **)&srcpageused,sizeof(int)*(pagecount+1),funcname,10);
        /* Mark all source pages as "not done" */
        for (i=0;i<=pagecount;i++)
            srcpageused[i]=0;
        nbb=4096;
        willus_mem_alloc_warn((void **)&bigbuf,nbb,funcname,10);
        bigbuf[0]='\0';
        }
    oldroot = pdf_dict_gets(xref->trailer,"Root");
    /*
    ** pages points to /Pages object in PDF file.
    ** Has:  /Type /Pages, /Count <numpages>, /Kids [ obj obj obj obj ]
    */
    pages = pdf_dict_gets(oldroot,"Pages");
    olddests = pdf_load_name_tree(xref,"Dests");

    /*
    ** Create new root object with only /Pages and /Type (and reduced dest entries)
    ** to avoid references to unretained pages.
    */
    root = pdf_new_dict(ctx,4);
    pdf_dict_puts(root,"Type",pdf_dict_gets(oldroot,"Type"));
    pdf_dict_puts(root,"Pages",pages);
    pdf_update_object(xref,pdf_to_num(oldroot),root);
    pdf_drop_obj(root);

    /* Parent indirectly references the /Pages object in the file */
    /* (Each new page we create has to point to this.)            */
    parent = pdf_new_indirect(ctx, pdf_to_num(pages), pdf_to_gen(pages), xref);
    /* Create a new kids array with only the pages we want to keep */
    kids = pdf_new_array(ctx, 1);


    qref=0;
    /* Avoid compiler warnings */
    destpageresources=NULL;
    destpagecontents=NULL;
    srcpagecontents=NULL;
    srcpagerot=0.;
    for (i=0;i<=pageinfo->boxes.n;i++)
        if (pageinfo->boxes.box[i].dstpage>0)
            break;
    if (i>0)
        {
        if (i<pageinfo->boxes.n)
            memmove(&pageinfo->boxes.box[0],&pageinfo->boxes.box[i],sizeof(WPDFBOX)*pageinfo->boxes.n-i);
        pageinfo->boxes.n -= i;
        }
    /* Walk through PFDBOXES array */
    for (i=srccount=i0=0;i<=pageinfo->boxes.n;i++)
        {
        WPDFBOX *box;
        int j,k,newsrc;
        static char buf[512];
        pdf_obj *s1indirect,*qindirect,*rotobj;
        static double cpm[3][3],m[3][3],m1[3][3];
        static double xclip[4],yclip[4];

/*
printf("box[%d]\n",i);
if (i<pageinfo->boxes.n)
{
box=&pageinfo->boxes.box[i];
printf("    srcpage=%d, dstpage=%d\n",box->srcbox.pageno,box->dstpage);
printf("    x0=%g, y0=%g\n",box->x0,box->y0);
printf("    w=%g, h=%g\n",box->w,box->h);
printf("    x1=%g, y1=%g\n",box->x1,box->y1);
printf("    sr=%g, dr=%g\n",box->srcrot_deg,box->dstrot_deg);
printf("    scale=%g\n",box->scale);
}
*/
        /* Check to see if we are done with an output page */
        if (srccount>0 && (i==pageinfo->boxes.n
               || (i>0 && pageinfo->boxes.box[i].dstpage!=pageinfo->boxes.box[i-1].dstpage)))
            {
            pdf_obj *newpageref;
            /*
            ** Store destination page into document structure
            */
/*
printf("    ADDING NEW PAGE. (srccount=%d)\n",srccount);
*/
            if (use_forms)
                {
                pdf_obj *dest_stream;

                /* Create new object in document for destination page stream */
                dest_stream = pdf_new_indirect(ctx,new_stream_object(xref,ctx,bigbuf),
                                               0,(void *)xref);
                /* Store this into the destination page contents array */
                pdf_array_push(destpagecontents,dest_stream);
                pdf_drop_obj(dest_stream);
                }
            newpageref=pdf_new_indirect(ctx,destpageref,0,(void *)xref);
            /* Reference parent list of pages */
            pdf_dict_puts(destpageobj,"Parent",parent);
            pdf_dict_puts(destpageobj,"Contents",destpagecontents);
            pdf_dict_puts(destpageobj,"Resources",destpageresources);
            /* Store page object in document's kids array */
            pdf_array_push(kids,newpageref);
            /* Update document with new page */
            pdf_update_object(xref,destpageref,destpageobj);
            /* Clean up */
            pdf_drop_obj(newpageref);
            pdf_drop_obj(destpageresources);
            pdf_drop_obj(destpagecontents);
            pdf_drop_obj(destpageobj);
            /* Reset source page and index to start of new destination page */
            i0=i;
            srccount=0;
            }
        /* Quit loop if beyond last box */
        if (i>=pageinfo->boxes.n)
            break;
        box=&pageinfo->boxes.box[i];
        if (box->srcbox.pageno<1 || box->srcbox.pageno>pagecount)
            continue;
        /* Is this a source page we haven't processed yet (for this destination page)? */
        for (newsrc=1,j=i0;j<i;j++)
            {
            if (pageinfo->boxes.box[j].srcbox.pageno==box->srcbox.pageno)
                {
                newsrc=0;
                break;
                }
            }
        if (newsrc)
            {
            double v[4];

            srccount++;
            if (use_forms)
                srcpageused[box->srcbox.pageno]=1;
/*
printf("    NEW SOURCE PAGE (srccount=%d)\n",srccount);
*/
            if (srccount==1)
                {
                /*
                ** Start a new destination page.
                **
                ** Each new page object is a dict type with:
                ** /Type /Page
                ** /Contents (array of objects)
                ** /Resources (dict)
                ** /MediaBox [0 0 612 792]
                ** /Parent <PagesObj>
                ** [Can have /Rotate 90, for example.]
                **
                */
/*
printf("        (STARTING NEW DEST. PAGE)\n");
*/
                destpageobj=start_new_destpage(ctx,box->dst_width_pts,box->dst_height_pts);
                destpageresources=pdf_new_dict(ctx,1);
                if (use_forms)
                    pdf_dict_puts(destpageresources,"XObject",pdf_new_dict(ctx,1));
                destpageref=pdf_create_object(xref);
                destpagecontents=pdf_new_array(ctx,1);
                /* Init the destination page stream for forms */
                if (use_forms)
                    bigbuf[0]='\0';
                }
            /* New source page, so get the source page objects */
            srcpageobj = xref->page_objs[box->srcbox.pageno-1];
            wmupdf_page_bbox(srcpageobj,v);
            srcx0=v[0];
            srcy0=v[1];
/*
printf("SRCX0=%g, SRCY0=%g\n",srcx0,srcy0);
*/
            rotobj=pdf_dict_gets(srcpageobj,"Rotate");
            srcpagerot = rotobj!=NULL ? pdf_to_real(rotobj) : 0.;
/*
printf("Page rotation = %g\n",srcpagerot);
*/
            srcpagecontents=pdf_dict_gets(srcpageobj,"Contents");
/*
if (pdf_is_array(srcpagecontents))
{
int k;
printf("    source page contents = array.\n");
for (k=0;k<pdf_array_len(srcpagecontents);k++)
{
pdf_obj *obj;
obj=pdf_array_get(srcpagecontents,k);
if (pdf_is_indirect(obj))
{
printf("    contents[%d] = indirect (%d)\n",k,pdf_to_num(obj));
pdf_resolve_indirect(obj);
}
}
}
*/
            if (use_forms)
                {
                pdf_obj *xobjdict;
                int pageno;

                xobjdict=pdf_dict_gets(destpageresources,"XObject");
                pageno=box->srcbox.pageno;
                pdf_dict_puts(xobjdict,xobject_name(pageno),xref->page_refs[pageno-1]);
                pdf_dict_puts(destpageresources,"XObject",xobjdict);
                }
            else
                {
                pdf_obj *srcpageresources;

                /* Merge source page resources into destination page resources */
                srcpageresources=pdf_dict_gets(srcpageobj,"Resources");
/*
printf("box->dstpage=%d, srcpage=%d (ind.#=%d)\n",box->dstpage,box->srcbox.pageno,pdf_to_num(xref->page_refs[box->srcbox.pageno-1]));
*/
                wmupdf_dict_merge(ctx,"Resources",destpageresources,srcpageresources);
                }
            }
        /*
        ** Process this source box:
        **
        ** Create a tranformation matrix and clipping path to only show the
        ** desired part of the source page at the appropriate place on the
        ** destination page.
        **
        ** How the tranformation matrix works:
        ** - Translations shall be specified as [ 1 0 0 1 tx ty ], where tx and ty
        **   shall be the distances to translate the origin of the coordinate system
        **   in the horizontal and vertical dimensions, respectively.
        **
        ** - Scaling shall be obtained by [ sx 0 0 sy 0 0 ]. This scales the coordinates
        **   so that 1 unit in the horizontal and vertical dimensions of the new coordinate
        **   system is the same size as sx and sy units, respectively, in the previous
        **   coordinate system.
        **
        ** - Rotations shall be produced by [ cos q sin q -sin q cos q 0 0 ], which has the
        **   effect of rotating the coordinate system axes by an angle q counter-clockwise.
        **
        ** - Skew shall be specified by [ 1 tan a tan b 1 0 0 ], which skews the x axis by
        **   an angle a and the y axis by an angle b.
        **
        */
        wpdfbox_determine_original_source_position(box);
/*
printf("Before unrotate.\n");
printf("box->srcrot=%g\n",box->srcrot_deg);
printf("box->x0=%g, box->y0=%g\n",box->x0,box->y0);
printf("box->w=%g, box->h=%g\n",box->w,box->h);
printf("box->pw=%g, box->ph=%g\n",box->src_width_pts,box->src_height_pts);
*/
        if (fabs(srcpagerot) > 1.0e-4)
            wpdfbox_unrotate(box,srcpagerot);
/*
printf("box->srcrot=%g\n",box->srcrot_deg);
printf("box->x0=%g, box->y0=%g\n",box->x0,box->y0);
printf("box->w=%g, box->h=%g\n",box->w,box->h);
printf("box->pw=%g, box->ph=%g\n",box->src_width_pts,box->src_height_pts);
*/
        matrix_unity(m,1.);
/*
printf("xfmatrix = [  %9.6f   %9.6f   %9.6f  ]\n"
       "           [  %9.6f   %9.6f   %9.6f  ]\n"
       "           [  %9.6f   %9.6f   %9.6f  ]\n",
        m[0][0],m[0][1],m[0][2],
        m[1][0],m[1][1],m[1][2],
        m[2][0],m[2][1],m[2][2]);
*/
        matrix_translate(m1,-box->x0-srcx0,-box->y0-srcy0);
        matrix_mul(m,m1);
        matrix_rotate(m1,-box->srcrot_deg+box->dstrot_deg);
        matrix_mul(m,m1);
        matrix_unity(m1,box->scale);
        matrix_mul(m,m1);
        matrix_translate(m1,box->x1,box->y1);
        matrix_mul(m,m1);
        matrix_zero_round(m);
        matrix_rotate(cpm,box->srcrot_deg);
        matrix_translate(m1,box->x0+srcx0,box->y0+srcy0);
        matrix_mul(cpm,m1);
/*
printf("Clip matrix:\n");
printf("xfmatrix = [  %9.6f   %9.6f   %9.6f  ]\n"
       "           [  %9.6f   %9.6f   %9.6f  ]\n"
       "           [  %9.6f   %9.6f   %9.6f  ]\n",
        cpm[0][0],cpm[0][1],cpm[0][2],
        cpm[1][0],cpm[1][1],cpm[1][2],
        cpm[2][0],cpm[2][1],cpm[2][2]);
*/


        set_clip_array(xclip,yclip,box->srcrot_deg,box->w,box->h);
        for (k=0;k<4;k++)
            matrix_xymul(cpm,&xclip[k],&yclip[k]);
/*
printf("Clip path:\n    %7.2f %7.2f\n    %7.2f,%7.2f\n    %7.2f,%7.2f\n"
                   "    %7.2f %7.2f\n    %7.2f,%7.2f\n",
                xclip[0],yclip[0],xclip[1],yclip[1],xclip[2],yclip[2],
                xclip[3],yclip[3],xclip[0],yclip[0]);
*/
        strcpy(buf,"q");
        for (k=0;k<=2;k++)
            {
            cat_pdf_double(buf,m[k][0]);
            cat_pdf_double(buf,m[k][1]);
            }
        strcat(buf," cm");
        for (k=0;k<=4;k++)
            {
            cat_pdf_double(buf,xclip[k&3]);
            cat_pdf_double(buf,yclip[k&3]);
            strcat(buf,k==0 ? " m" : " l");
            }
        strcat(buf," W n");
        if (use_forms)
            {
            /* FORM METHOD */
            sprintf(&buf[strlen(buf)]," /%s Do Q\n",xobject_name(box->srcbox.pageno));
            if (strlen(bigbuf)+strlen(buf) > nbb)
                {
                int newsize;
                newsize=nbb*2;
                willus_mem_realloc_robust_warn((void **)&bigbuf,newsize,nbb,funcname,10);
                nbb=newsize;
                }
            strcat(bigbuf,buf);
            }
        else
            {
            /* NO-FORMS METHOD */
            strcat(buf,"\n");
            /* Create new objects in document for tx matrix and restore matrix */
            s1indirect = pdf_new_indirect(ctx,new_stream_object(xref,ctx,buf),0,(void *)xref);
            if (qref==0)
                qref=new_stream_object(xref,ctx,"Q\n");
            qindirect = pdf_new_indirect(ctx,qref,0,(void *)xref);
            /* Store this region into the destination page contents array */
            pdf_array_push(destpagecontents,s1indirect);
            if (pdf_is_array(srcpagecontents))
                {
                int k;
                for (k=0;k<pdf_array_len(srcpagecontents);k++)
                    pdf_array_push(destpagecontents,pdf_array_get(srcpagecontents,k));
                }
            else
                pdf_array_push(destpagecontents,srcpagecontents);
            pdf_array_push(destpagecontents,qindirect);
            pdf_drop_obj(s1indirect);
            pdf_drop_obj(qindirect);
            }
        }
    pdf_drop_obj(parent);

    /* For forms, convert all original source pages to XObject Forms */
    if (use_forms)
        wmupdf_convert_pages_to_forms(xref,ctx,srcpageused);

    /* Update page count and kids array */
    countobj = pdf_new_int(ctx, pdf_array_len(kids));
    pdf_dict_puts(pages, "Count", countobj);
    pdf_drop_obj(countobj);
    pdf_dict_puts(pages, "Kids", kids);
    pdf_drop_obj(kids);

    /* Also preserve the (partial) Dests name tree */
    if (olddests)
        wmupdf_preserve_old_dests(olddests,ctx,xref,pages);
    if (use_forms)
        {
        /* Free memory */
        willus_mem_free((double **)&bigbuf,funcname);
        willus_mem_free((double **)&srcpageused,funcname);
        }
    return(0);
    }
Esempio n. 10
0
static void wmupdf_convert_single_page_to_form(pdf_document *xref,fz_context *ctx,int pageno)

    {
    pdf_obj *array,*srcpageobj,*srcpagecontents;
    int i,len,streamlen,pageref,pagegen,compressed;
    double bbox_array[4];
    double matrix[6];

    /* New source page, so get the source page objects */
    srcpageobj = xref->page_objs[pageno-1];
    pageref=pdf_to_num(xref->page_refs[pageno-1]);
    pagegen=pdf_to_gen(xref->page_refs[pageno-1]);
    wmupdf_page_bbox(srcpageobj,bbox_array);
    for (i=0;i<6;i++)
        matrix[i]=0.;
    matrix[0]=matrix[3]=1.;
    srcpagecontents=pdf_dict_gets(srcpageobj,"Contents");
    /* Concatenate all indirect streams from source page directly into it. */
// printf("Adding streams to source page %d (pageref=%d, pagegen=%d)...\n",pageno,pageref,pagegen);
    streamlen=0;
    if (pdf_is_array(srcpagecontents))
        {
        int k;
        for (k=0;k<pdf_array_len(srcpagecontents);k++)
            {
            pdf_obj *obj;
            obj=pdf_array_get(srcpagecontents,k);
            if (pdf_is_indirect(obj))
                pdf_resolve_indirect(obj);
            streamlen=add_to_srcpage_stream(xref,ctx,pageref,pagegen,obj);
            }
        }
    else
        {
        if (pdf_is_indirect(srcpagecontents))
            pdf_resolve_indirect(srcpagecontents);
        streamlen=add_to_srcpage_stream(xref,ctx,pageref,pagegen,srcpagecontents);
        }
    compressed=stream_deflate(xref,ctx,pageref,pagegen,&streamlen);
    srcpageobj = xref->page_objs[pageno-1];
    pageref=pdf_to_num(xref->page_refs[pageno-1]);
    len=pdf_dict_len(srcpageobj);
    for (i=0;i<len;i++)
        {
        pdf_obj *key; /* *value */

        key=pdf_dict_get_key(srcpageobj,i);
/*
if (pdf_is_name(key))
printf("key[%d] = name = %s\n",i,pdf_to_name(key));
else
printf("key[%d] = ??\n",i);
*/
        /* value=pdf_dict_get_val(srcpageobj,i); */
        /* Keep same resources */
        if (!pdf_is_name(key))
            continue;
        if (pdf_is_name(key) && !stricmp("Resources",pdf_to_name(key)))
            continue;
        /* Drop dictionary entry otherwise */
// printf("Deleting key %s.\n",pdf_to_name(key));
        pdf_dict_del(srcpageobj,key);
        i=-1;
        len=pdf_dict_len(srcpageobj);
        }
    pdf_dict_puts(srcpageobj,"Type",pdf_new_name(ctx,"XObject"));
    pdf_dict_puts(srcpageobj,"Subtype",pdf_new_name(ctx,"Form"));
    pdf_dict_puts(srcpageobj,"FormType",pdf_new_int(ctx,1));
    if (compressed)
        pdf_dict_puts(srcpageobj,"Filter",pdf_new_name(ctx,"FlateDecode"));
    pdf_dict_puts(srcpageobj,"Length",pdf_new_int(ctx,streamlen));
    array=pdf_new_array(ctx,4);
    for (i=0;i<4;i++)
        pdf_array_push(array,pdf_new_real(ctx,bbox_array[i]));
    pdf_dict_puts(srcpageobj,"BBox",array);
    array=pdf_new_array(ctx,6);
    for (i=0;i<6;i++)
        pdf_array_push(array,pdf_new_real(ctx,matrix[i]));
    pdf_dict_puts(srcpageobj,"Matrix",array);
    /* (It's no longer a "page"--it's a Form-type XObject) */
    /* I don't think this call should be made since it will call fz_drop_object on srcpageobj */
    /* pdf_update_object(xref,pageref,srcpageobj); */
    }