summaryrefslogtreecommitdiff
path: root/Build/source/texk/dvipdfm-x/src/epdf.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/dvipdfm-x/src/epdf.c')
-rw-r--r--Build/source/texk/dvipdfm-x/src/epdf.c208
1 files changed, 208 insertions, 0 deletions
diff --git a/Build/source/texk/dvipdfm-x/src/epdf.c b/Build/source/texk/dvipdfm-x/src/epdf.c
new file mode 100644
index 00000000000..17fdcf3ee26
--- /dev/null
+++ b/Build/source/texk/dvipdfm-x/src/epdf.c
@@ -0,0 +1,208 @@
+/*
+
+ This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
+
+ Copyright (C) 2007-2012 by Jin-Hwan Cho and Shunsaku Hirata,
+ the dvipdfmx project team.
+
+ Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+*/
+
+/*
+ * Concatinating content streams are only supported for streams that only uses
+ * single FlateDecode filter, i.e.,
+ *
+ * /Filter /FlateDecode or /Filter [/FlateDecode]
+ *
+ * TrimBox, BleedBox, ArtBox, Rotate ...
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "system.h"
+#include "mem.h"
+#include "mfileio.h"
+#include "error.h"
+
+#include "dvipdfmx.h"
+
+#include "pdfobj.h"
+#include "pdfdev.h"
+#include "pdfdoc.h"
+
+#include "pdfximage.h"
+
+#include "epdf.h"
+
+int
+pdf_include_page (pdf_ximage *ximage, FILE *image_file, const char *filename)
+{
+ pdf_file *pf;
+ xform_info info;
+ pdf_obj *contents = NULL, *catalog;
+ pdf_obj *page = NULL, *resources = NULL, *markinfo = NULL;
+
+ pf = pdf_open(filename, image_file);
+ if (!pf)
+ return -1;
+
+ if (pdf_file_get_version(pf) > pdf_get_version())
+ goto too_recent;
+
+ pdf_ximage_init_form_info(&info);
+
+ page = pdf_doc_get_page(pf, pdf_ximage_get_page(ximage), NULL,
+ &info.bbox, &resources);
+
+ if(!page)
+ goto error_silent;
+
+ catalog = pdf_file_get_catalog(pf);
+ markinfo = pdf_deref_obj(pdf_lookup_dict(catalog, "MarkInfo"));
+ if (markinfo) {
+ pdf_obj *tmp = pdf_deref_obj(pdf_lookup_dict(markinfo, "Marked"));
+ pdf_release_obj(markinfo);
+ if (!PDF_OBJ_BOOLEANTYPE(tmp)) {
+ if (tmp)
+ pdf_release_obj(tmp);
+ goto error;
+ } else if (pdf_boolean_value(tmp))
+ WARN("File contains tagged PDF. Ignoring tags.");
+ pdf_release_obj(tmp);
+ }
+
+ contents = pdf_deref_obj(pdf_lookup_dict(page, "Contents"));
+ pdf_release_obj(page);
+
+ /*
+ * Handle page content stream.
+ */
+ {
+ pdf_obj *content_new;
+
+ if (!contents) {
+ /*
+ * Empty page
+ */
+ content_new = pdf_new_stream(0);
+ /* TODO: better don't include anything if the page is empty */
+ } else if (PDF_OBJ_STREAMTYPE(contents)) {
+ /*
+ * We must import the stream because its dictionary
+ * may contain indirect references.
+ */
+ content_new = pdf_import_object(contents);
+ } else if (PDF_OBJ_ARRAYTYPE(contents)) {
+ /*
+ * Concatenate all content streams.
+ */
+ int idx, len = pdf_array_length(contents);
+ content_new = pdf_new_stream(STREAM_COMPRESS);
+ for (idx = 0; idx < len; idx++) {
+ pdf_obj *content_seg = pdf_deref_obj(pdf_get_array(contents, idx));
+ if (!PDF_OBJ_STREAMTYPE(content_seg) ||
+ pdf_concat_stream(content_new, content_seg) < 0) {
+ pdf_release_obj(content_seg);
+ pdf_release_obj(content_new);
+ goto error;
+ }
+ pdf_release_obj(content_seg);
+ }
+ } else
+ goto error;
+
+ if (contents)
+ pdf_release_obj(contents);
+ contents = content_new;
+ }
+
+ /*
+ * Add entries to contents stream dictionary.
+ */
+ {
+ pdf_obj *contents_dict, *bbox, *matrix;
+
+ contents_dict = pdf_stream_dict(contents);
+ pdf_add_dict(contents_dict,
+ pdf_new_name("Type"),
+ pdf_new_name("XObject"));
+ pdf_add_dict(contents_dict,
+ pdf_new_name("Subtype"),
+ pdf_new_name("Form"));
+ pdf_add_dict(contents_dict,
+ pdf_new_name("FormType"),
+ pdf_new_number(1.0));
+
+ bbox = pdf_new_array();
+ pdf_add_array(bbox, pdf_new_number(info.bbox.llx));
+ pdf_add_array(bbox, pdf_new_number(info.bbox.lly));
+ pdf_add_array(bbox, pdf_new_number(info.bbox.urx));
+ pdf_add_array(bbox, pdf_new_number(info.bbox.ury));
+
+ pdf_add_dict(contents_dict, pdf_new_name("BBox"), bbox);
+
+ matrix = pdf_new_array();
+ pdf_add_array(matrix, pdf_new_number(1.0));
+ pdf_add_array(matrix, pdf_new_number(0.0));
+ pdf_add_array(matrix, pdf_new_number(0.0));
+ pdf_add_array(matrix, pdf_new_number(1.0));
+ pdf_add_array(matrix, pdf_new_number(0.0));
+ pdf_add_array(matrix, pdf_new_number(0.0));
+
+ pdf_add_dict(contents_dict, pdf_new_name("Matrix"), matrix);
+
+ pdf_add_dict(contents_dict,
+ pdf_new_name("Resources"),
+ pdf_import_object(resources));
+ pdf_release_obj(resources);
+ }
+
+ pdf_close(pf);
+
+ pdf_ximage_set_form(ximage, &info, contents);
+
+ return 0;
+
+ error:
+ WARN("Cannot parse document. Broken PDF file?");
+ error_silent:
+ if (resources)
+ pdf_release_obj(resources);
+ if (markinfo)
+ pdf_release_obj(markinfo);
+ if (page)
+ pdf_release_obj(page);
+ if (contents)
+ pdf_release_obj(contents);
+
+ pdf_close(pf);
+
+ return -1;
+
+ too_recent:
+ pdf_close(pf);
+ WARN("PDF version of input file more recent than in output file.");
+ if (compat_mode) {
+ WARN("Converting. Use \"-V\" switch to change output PDF version.");
+ return 1;
+ } else {
+ WARN("Use \"-V\" switch to change output PDF version.");
+ return -1;
+ }
+}