Back to index

texmacs  1.0.7.15
epdf.c
Go to the documentation of this file.
00001 /*  $Header: /home/cvsroot/dvipdfmx/src/epdf.c,v 1.30 2009/09/19 18:48:27 matthias Exp $
00002 
00003     This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
00004 
00005     Copyright (C) 2007 by Jin-Hwan Cho and Shunsaku Hirata,
00006     the dvipdfmx project team <dvipdfmx@project.ktug.or.kr>
00007     
00008     Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
00009 
00010     This program is free software; you can redistribute it and/or modify
00011     it under the terms of the GNU General Public License as published by
00012     the Free Software Foundation; either version 2 of the License, or
00013     (at your option) any later version.
00014     
00015     This program is distributed in the hope that it will be useful,
00016     but WITHOUT ANY WARRANTY; without even the implied warranty of
00017     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018     GNU General Public License for more details.
00019     
00020     You should have received a copy of the GNU General Public License
00021     along with this program; if not, write to the Free Software
00022     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
00023 */
00024 
00025 /*
00026  * Concatinating content streams are only supported for streams that only uses
00027  * single FlateDecode filter, i.e.,
00028  *
00029  *   /Filter /FlateDecode or /Filter [/FlateDecode]
00030  *
00031  * TrimBox, BleedBox, ArtBox, Rotate ...
00032  */
00033 
00034 #if HAVE_CONFIG_H
00035 #include "config.h"
00036 #endif
00037 
00038 #include "system.h"
00039 #include "mem.h"
00040 #include "mfileio.h"
00041 #include "error.h"
00042 
00043 #include "dvipdfmx.h"
00044 
00045 #include "pdfobj.h"
00046 #include "pdfdev.h"
00047 #include "pdfdoc.h"
00048 
00049 #include "pdfximage.h"
00050 
00051 #include "epdf.h"
00052 
00053 int compat_mode; //FIXME: Unused in TeXmacs. Remove.
00054 
00055 int
00056 pdf_include_page (pdf_ximage *ximage, FILE *image_file, const char *filename)
00057 {
00058   pdf_file *pf;
00059   xform_info info;
00060   pdf_obj *contents = NULL, *catalog;
00061   pdf_obj *page = NULL, *resources = NULL, *markinfo = NULL;
00062 
00063   pf = pdf_open(filename, image_file);
00064   if (!pf)
00065     return -1;
00066 
00067   if (pdf_file_get_version(pf) > pdf_get_version())
00068     goto too_recent;
00069 
00070   pdf_ximage_init_form_info(&info);  
00071 
00072   page = pdf_doc_get_page(pf, pdf_ximage_get_page(ximage), NULL,
00073                        &info.bbox, &resources);
00074 
00075   if(!page)
00076     goto error_silent;
00077 
00078   catalog = pdf_file_get_catalog(pf);
00079   markinfo = pdf_deref_obj(pdf_lookup_dict(catalog, "MarkInfo"));
00080   if (markinfo) {
00081     pdf_obj *tmp = pdf_deref_obj(pdf_lookup_dict(markinfo, "Marked"));
00082     pdf_release_obj(markinfo);
00083     if (!PDF_OBJ_BOOLEANTYPE(tmp)) {
00084       if (tmp)
00085        pdf_release_obj(tmp);
00086       goto error;
00087     } else if (pdf_boolean_value(tmp))
00088       WARN("File contains tagged PDF. Ignoring tags.");
00089     pdf_release_obj(tmp);
00090   }
00091 
00092   contents = pdf_deref_obj(pdf_lookup_dict(page, "Contents"));
00093   pdf_release_obj(page);
00094 
00095   /*
00096    * Handle page content stream.
00097    */
00098   {
00099     pdf_obj *content_new;
00100 
00101     if (!contents) {
00102       /*
00103        * Empty page
00104        */
00105       content_new = pdf_new_stream(0);
00106       /* TODO: better don't include anything if the page is empty */
00107     } else if (PDF_OBJ_STREAMTYPE(contents)) {
00108       /* 
00109        * We must import the stream because its dictionary
00110        * may contain indirect references.
00111        */
00112       content_new = pdf_import_object(contents);
00113     } else if (PDF_OBJ_ARRAYTYPE(contents)) {
00114       /*
00115        * Concatenate all content streams.
00116        */
00117       int idx, len = pdf_array_length(contents);
00118       content_new = pdf_new_stream(STREAM_COMPRESS);
00119       for (idx = 0; idx < len; idx++) {
00120        pdf_obj *content_seg = pdf_deref_obj(pdf_get_array(contents, idx));
00121        if (!PDF_OBJ_STREAMTYPE(content_seg) ||
00122            pdf_concat_stream(content_new, content_seg) < 0) {
00123          pdf_release_obj(content_seg);
00124          pdf_release_obj(content_new);
00125          goto error;
00126        }
00127        pdf_release_obj(content_seg);
00128       }
00129     } else
00130       goto error;
00131 
00132     if (contents)
00133       pdf_release_obj(contents);
00134     contents = content_new;
00135   }
00136 
00137   /*
00138    * Add entries to contents stream dictionary.
00139    */
00140   {
00141     pdf_obj *contents_dict, *bbox, *matrix;
00142 
00143     contents_dict = pdf_stream_dict(contents);
00144     pdf_add_dict(contents_dict,
00145                pdf_new_name("Type"), 
00146                pdf_new_name("XObject"));
00147     pdf_add_dict(contents_dict,
00148                pdf_new_name("Subtype"),
00149                pdf_new_name("Form"));
00150     pdf_add_dict(contents_dict,
00151                pdf_new_name("FormType"),
00152                pdf_new_number(1.0));
00153 
00154     bbox = pdf_new_array();
00155     pdf_add_array(bbox, pdf_new_number(info.bbox.llx));
00156     pdf_add_array(bbox, pdf_new_number(info.bbox.lly));
00157     pdf_add_array(bbox, pdf_new_number(info.bbox.urx));
00158     pdf_add_array(bbox, pdf_new_number(info.bbox.ury));
00159 
00160     pdf_add_dict(contents_dict, pdf_new_name("BBox"), bbox);
00161 
00162     matrix = pdf_new_array();
00163     pdf_add_array(matrix, pdf_new_number(1.0));
00164     pdf_add_array(matrix, pdf_new_number(0.0));
00165     pdf_add_array(matrix, pdf_new_number(0.0));
00166     pdf_add_array(matrix, pdf_new_number(1.0));
00167     pdf_add_array(matrix, pdf_new_number(0.0));
00168     pdf_add_array(matrix, pdf_new_number(0.0));
00169 
00170     pdf_add_dict(contents_dict, pdf_new_name("Matrix"), matrix);
00171 
00172     pdf_add_dict(contents_dict,
00173                pdf_new_name("Resources"),
00174                pdf_import_object(resources));
00175     pdf_release_obj(resources);
00176   }
00177 
00178   pdf_close(pf);
00179 
00180   pdf_ximage_set_form(ximage, &info, contents);
00181 
00182   return 0;
00183 
00184  error:
00185   WARN("Cannot parse document. Broken PDF file?");
00186  error_silent:
00187   if (resources)
00188     pdf_release_obj(resources);
00189   if (markinfo)
00190     pdf_release_obj(markinfo);
00191   if (page)
00192     pdf_release_obj(page);
00193   if (contents)
00194     pdf_release_obj(contents);
00195 
00196   pdf_close(pf);
00197 
00198   return -1;
00199 
00200  too_recent:
00201   pdf_close(pf);
00202   WARN("PDF version of input file more recent than in output file.");
00203   if (compat_mode) {
00204     WARN("Converting. Use \"-V\" switch to change output PDF version.");
00205     return 1;
00206   } else {
00207     WARN("Use \"-V\" switch to change output PDF version.");
00208     return -1;
00209   }
00210 }