summaryrefslogtreecommitdiff
path: root/Build/source/texk/web2c/luatexdir/image/pdftoepdf.w
diff options
context:
space:
mode:
authorAkira Kakuto <kakuto@fuk.kindai.ac.jp>2015-12-16 14:50:11 +0000
committerAkira Kakuto <kakuto@fuk.kindai.ac.jp>2015-12-16 14:50:11 +0000
commit621273b5ef8cc9e83d9aca07bf012f727ba26f15 (patch)
tree0b5cb28eec37e3e0e93a09729cbc30834166a5f9 /Build/source/texk/web2c/luatexdir/image/pdftoepdf.w
parentf04f01782aebac8cb2fcde278c02a4fb3be4bb12 (diff)
web2c/luatexdir: LuaTeX beta-0.86.0 (Sync with the upstream).
git-svn-id: svn://tug.org/texlive/trunk@39116 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/web2c/luatexdir/image/pdftoepdf.w')
-rw-r--r--Build/source/texk/web2c/luatexdir/image/pdftoepdf.w669
1 files changed, 315 insertions, 354 deletions
diff --git a/Build/source/texk/web2c/luatexdir/image/pdftoepdf.w b/Build/source/texk/web2c/luatexdir/image/pdftoepdf.w
index 1ece3a2dd48..b9d496ac9f0 100644
--- a/Build/source/texk/web2c/luatexdir/image/pdftoepdf.w
+++ b/Build/source/texk/web2c/luatexdir/image/pdftoepdf.w
@@ -20,40 +20,40 @@
@ @c
-
-// define DEBUG
#define __STDC_FORMAT_MACROS /* for PRId64 etc. */
#include "image/epdf.h"
-// This file is mostly C and not very much C++; it's just used to interface
-// the functions of poppler, which happens to be written in C++.
+/*
+ This file is mostly C and not very much C++; it's just used to interface
+ the functions of poppler, which happens to be written in C++.
+*/
extern void md5(Guchar *msg, int msgLen, Guchar *digest);
static GBool isInit = gFalse;
-//**********************************************************************
-// Maintain AVL tree of all PDF files for embedding
+/* Maintain AVL tree of all PDF files for embedding */
static avl_table *PdfDocumentTree = NULL;
-// AVL sort PdfDocument into PdfDocumentTree by file_path
+/* AVL sort PdfDocument into PdfDocumentTree by file_path */
static int CompPdfDocument(const void *pa, const void *pb, void * /*p */ )
{
- return strcmp(((const PdfDocument *) pa)->file_path,
- ((const PdfDocument *) pb)->file_path);
+ return strcmp(((const PdfDocument *) pa)->file_path, ((const PdfDocument *) pb)->file_path);
}
-// Returns pointer to PdfDocument structure for PDF file.
+/* Returns pointer to PdfDocument structure for PDF file. */
static PdfDocument *findPdfDocument(char *file_path)
{
PdfDocument *pdf_doc, tmp;
- assert(file_path != NULL);
- if (PdfDocumentTree == NULL)
+ if (file_path == NULL) {
+ normal_error("pdf backend","empty filename when loading pdf file");
+ } else if (PdfDocumentTree == NULL) {
return NULL;
+ }
tmp.file_path = file_path;
pdf_doc = (PdfDocument *) avl_find(PdfDocumentTree, &tmp);
return pdf_doc;
@@ -70,22 +70,20 @@ static char *get_file_checksum(const char *a, file_error_mode fe)
time_t mtime = finfo.st_mtime;
ck = (char *) malloc(PDF_CHECKSUM_SIZE);
if (ck == NULL)
- luatex_fail("PDF inclusion: out of memory while processing '%s'",
- a);
- snprintf(ck, PDF_CHECKSUM_SIZE, "%" PRIu64 "_%" PRIu64, (uint64_t) size,
- (uint64_t) mtime);
+ formatted_error("pdf inclusion","out of memory while processing '%s'", a);
+ snprintf(ck, PDF_CHECKSUM_SIZE, "%" PRIu64 "_%" PRIu64, (uint64_t) size,(uint64_t) mtime);
} else {
switch (fe) {
- case FE_FAIL:
- luatex_fail("PDF inclusion: could not stat() file '%s'", a);
- break;
- case FE_RETURN_NULL:
- if (ck != NULL)
- free(ck);
- ck = NULL;
- break;
- default:
- assert(0);
+ case FE_FAIL:
+ formatted_error("pdf inclusion","could not stat() file '%s'", a);
+ break;
+ case FE_RETURN_NULL:
+ if (ck != NULL)
+ free(ck);
+ ck = NULL;
+ break;
+ default:
+ assert(0);
}
}
return ck;
@@ -93,28 +91,28 @@ static char *get_file_checksum(const char *a, file_error_mode fe)
static char *get_stream_checksum (const char *str, unsigned long long str_size){
- /* http://www.cse.yorku.ca/~oz/hash.html */
- /* djb2 */
- unsigned long hash ;
- char *ck = NULL;
- unsigned int i;
- hash = 5381;
- ck = (char *) malloc(STRSTREAM_CHECKSUM_SIZE+1);
- if (ck == NULL)
- luatex_fail("PDF inclusion: out of memory while processing a memstream");
- for(i=0; i<(unsigned int)(str_size); i++) {
- hash = ((hash << 5) + hash) + str[i]; /* hash * 33 + str[i] */
- }
- snprintf(ck,STRSTREAM_CHECKSUM_SIZE+1,"%lx",hash);
- ck[STRSTREAM_CHECKSUM_SIZE]='\0';
- return ck;
+ /* http://www.cse.yorku.ca/~oz/hash.html */
+ /* djb2 */
+ unsigned long hash ;
+ char *ck = NULL;
+ unsigned int i;
+ hash = 5381;
+ ck = (char *) malloc(STRSTREAM_CHECKSUM_SIZE+1);
+ if (ck == NULL)
+ normal_error("pdf inclusion","out of memory while processing a memstream");
+ for(i=0; i<(unsigned int)(str_size); i++) {
+ hash = ((hash << 5) + hash) + str[i]; /* hash * 33 + str[i] */
+ }
+ snprintf(ck,STRSTREAM_CHECKSUM_SIZE+1,"%lx",hash);
+ ck[STRSTREAM_CHECKSUM_SIZE]='\0';
+ return ck;
}
-
-
-// Returns pointer to PdfDocument structure for PDF file.
-// Creates a new PdfDocument structure if it doesn't exist yet.
-// When fe = FE_RETURN_NULL, the function returns NULL in error case.
+/*
+ Returns pointer to PdfDocument structure for PDF file.
+ Creates a new PdfDocument structure if it doesn't exist yet.
+ When fe = FE_RETURN_NULL, the function returns NULL in error case.
+*/
PdfDocument *refPdfDocument(const char *file_path, file_error_mode fe)
{
@@ -124,15 +122,10 @@ PdfDocument *refPdfDocument(const char *file_path, file_error_mode fe)
GooString *docName = NULL;
int new_flag = 0;
if ((checksum = get_file_checksum(file_path, fe)) == NULL) {
- assert(fe == FE_RETURN_NULL);
return (PdfDocument *) NULL;
}
- assert(checksum != NULL);
path_copy = xstrdup(file_path);
if ((pdf_doc = findPdfDocument(path_copy)) == NULL) {
-#ifdef DEBUG
- fprintf(stderr, "\nDEBUG: New PdfDocument %s\n", file_path);
-#endif
new_flag = 1;
pdf_doc = new PdfDocument;
pdf_doc->file_path = path_copy;
@@ -140,38 +133,28 @@ PdfDocument *refPdfDocument(const char *file_path, file_error_mode fe)
pdf_doc->doc = NULL;
pdf_doc->inObjList = NULL;
pdf_doc->ObjMapTree = NULL;
- pdf_doc->occurences = 0; // 0 = unreferenced
+ pdf_doc->occurences = 0; /* 0 = unreferenced */
pdf_doc->pc = 0;
} else {
-#ifdef DEBUG
- fprintf(stderr, "\nDEBUG: Found PdfDocument %s (%d)\n",
- pdf_doc->file_path, pdf_doc->occurences);
-#endif
- assert(pdf_doc->checksum != NULL);
if (strncmp(pdf_doc->checksum, checksum, PDF_CHECKSUM_SIZE) != 0) {
- luatex_fail("PDF inclusion: file has changed '%s'", file_path);
+ formatted_error("pdf inclusion","file has changed '%s'", file_path);
}
free(checksum);
free(path_copy);
}
- assert(pdf_doc != NULL);
if (pdf_doc->doc == NULL) {
-#ifdef DEBUG
- fprintf(stderr, "\nDEBUG: New PDFDoc %s (%d)\n",
- pdf_doc->file_path, pdf_doc->occurences);
-#endif
docName = new GooString(file_path);
- doc = new PDFDoc(docName); // takes ownership of docName
+ doc = new PDFDoc(docName); /* takes ownership of docName */
pdf_doc->pc++;
if (!doc->isOk() || !doc->okToPrint()) {
switch (fe) {
case FE_FAIL:
- luatex_fail("PDF inclusion: reading PDF image failed");
+ normal_error("pdf inclusion","reading image failed");
break;
case FE_RETURN_NULL:
delete doc;
- // delete docName;
+ /* delete docName */
if (new_flag == 1) {
if (pdf_doc->file_path != NULL)
free(pdf_doc->file_path);
@@ -187,27 +170,21 @@ PdfDocument *refPdfDocument(const char *file_path, file_error_mode fe)
}
pdf_doc->doc = doc;
}
- // PDF file could be opened without problems, checksum ok.
+ /* PDF file could be opened without problems, checksum ok. */
if (PdfDocumentTree == NULL)
PdfDocumentTree = avl_create(CompPdfDocument, NULL, &avl_xallocator);
if ((PdfDocument *) avl_find(PdfDocumentTree, pdf_doc) == NULL) {
- void **aa = avl_probe(PdfDocumentTree, pdf_doc);
- assert(aa != NULL);
+ avl_probe(PdfDocumentTree, pdf_doc);
}
pdf_doc->occurences++;
-#ifdef DEBUG
- fprintf(stderr, "\nDEBUG: Incrementing %s (%d)\n",
- pdf_doc->file_path, pdf_doc->occurences);
-#endif
return pdf_doc;
}
-
-
-// Returns pointer to PdfDocument structure for a PDF stream in memory
-// of streamsize dimension
-// As before, creates a new PdfDocument structure if it doesn't exist yet
-// with file_path = file_id
+/*
+ Returns pointer to PdfDocument structure for a PDF stream in memory of streamsize
+ dimension. As before, creates a new PdfDocument structure if it doesn't exist yet
+ with file_path = file_id
+*/
PdfDocument *refMemStreamPdfDocument(char *docstream, unsigned long long streamsize,const char *file_id)
{
@@ -219,21 +196,16 @@ PdfDocument *refMemStreamPdfDocument(char *docstream, unsigned long long streams
MemStream *docmemstream = NULL;
/*int new_flag = 0;*/
size_t cnt = 0;
-
checksum = get_stream_checksum(docstream, streamsize);
- assert(checksum != NULL);
cnt = strlen(file_id);
- assert(cnt>0 && cnt <STREAM_FILE_ID_LEN);
- file_path = (char *) malloc(cnt+STREAM_URI_LEN+STRSTREAM_CHECKSUM_SIZE+1); // 1 for '\0'
+ assert(cnt>0 && cnt <STREAM_FILE_ID_LEN);
+ file_path = (char *) malloc(cnt+STREAM_URI_LEN+STRSTREAM_CHECKSUM_SIZE+1); /* 1 for \0 */
assert(file_path != NULL);
strcpy(file_path,STREAM_URI);
strcat(file_path,file_id);
strcat(file_path,checksum);
file_path[cnt+STREAM_URI_LEN+STRSTREAM_CHECKSUM_SIZE]='\0';
if ((pdf_doc = findPdfDocument(file_path)) == NULL) {
-#ifdef DEBUG
- fprintf(stderr, "\nDEBUG: New MemStreamPdfDocument %s\n", file_path);
-#endif
/*new_flag = 1;*/
pdf_doc = new PdfDocument;
pdf_doc->file_path = file_path;
@@ -241,61 +213,43 @@ PdfDocument *refMemStreamPdfDocument(char *docstream, unsigned long long streams
pdf_doc->doc = NULL;
pdf_doc->inObjList = NULL;
pdf_doc->ObjMapTree = NULL;
- pdf_doc->occurences = 0; // 0 = unreferenced
+ pdf_doc->occurences = 0; /* 0 = unreferenced */
pdf_doc->pc = 0;
} else {
-#ifdef DEBUG
- fprintf(stderr, "\nDEBUG: Found MemStreamPdfDocument %s (%d)\n",
- pdf_doc->file_path, pdf_doc->occurences);
-#endif
- assert(pdf_doc->checksum != NULL);
- // As is now, checksum is in file_path, so this check should be useless.
+ /* As is now, checksum is in file_path, so this check should be useless. */
if (strncmp(pdf_doc->checksum, checksum, STRSTREAM_CHECKSUM_SIZE) != 0) {
- luatex_fail("PDF inclusion: stream has changed '%s'", file_path);
+ formatted_error("pdf inclusion","stream has changed '%s'", file_path);
}
- free(file_path);
+ free(file_path);
free(checksum);
}
- assert(pdf_doc != NULL);
if (pdf_doc->doc == NULL) {
-#ifdef DEBUG
- fprintf(stderr, "\nDEBUG: New PDFDoc %s (%d)\n",
- pdf_doc->file_path, pdf_doc->occurences);
-#endif
- docmemstream = new MemStream( docstream,0,streamsize, obj.initNull() );
- doc = new PDFDoc(docmemstream); // takes ownership of docmemstream
+ docmemstream = new MemStream( docstream,0,streamsize, obj.initNull() );
+ doc = new PDFDoc(docmemstream); /* takes ownership of docmemstream */
pdf_doc->pc++;
-
if (!doc->isOk() || !doc->okToPrint()) {
- luatex_fail("poppler: reading PDF Stream failed");
- }
+ normal_error("pdf inclusion","reading pdf Stream failed");
+ }
pdf_doc->doc = doc;
}
- // PDF file could be opened without problems, checksum ok.
+ /* PDF file could be opened without problems, checksum ok. */
if (PdfDocumentTree == NULL)
PdfDocumentTree = avl_create(CompPdfDocument, NULL, &avl_xallocator);
if ((PdfDocument *) avl_find(PdfDocumentTree, pdf_doc) == NULL) {
- void **aa = avl_probe(PdfDocumentTree, pdf_doc);
- assert(aa != NULL);
+ avl_probe(PdfDocumentTree, pdf_doc);
}
pdf_doc->occurences++;
-#ifdef DEBUG
- fprintf(stderr, "\nDEBUG: Incrementing %s (%d)\n",
- pdf_doc->file_path, pdf_doc->occurences);
-#endif
return pdf_doc;
}
-
-
-//**********************************************************************
-// AVL sort ObjMap into ObjMapTree by object number and generation
-
-// keep the ObjMap struct small, as these are accumulated until the end
+/*
+ AVL sort ObjMap into ObjMapTree by object number and generation keep the ObjMap
+ struct small, as these are accumulated until the end
+*/
struct ObjMap {
- Ref in; // object num/gen in orig. PDF file
- int out_num; // object num after embedding (gen == 0)
+ Ref in;
+ int out_num;
};
static int CompObjMap(const void *pa, const void *pb, void * /*p */ )
@@ -304,11 +258,11 @@ static int CompObjMap(const void *pa, const void *pb, void * /*p */ )
const Ref *b = &(((const ObjMap *) pb)->in);
if (a->num > b->num)
return 1;
- if (a->num < b->num)
+ else if (a->num < b->num)
return -1;
- if (a->gen == b->gen) // most likely gen == 0 anyway
+ else if (a->gen == b->gen)
return 0;
- if (a->gen < b->gen)
+ else if (a->gen < b->gen)
return -1;
return 1;
}
@@ -316,7 +270,6 @@ static int CompObjMap(const void *pa, const void *pb, void * /*p */ )
static ObjMap *findObjMap(PdfDocument * pdf_doc, Ref in)
{
ObjMap *obj_map, tmp;
- assert(pdf_doc != NULL);
if (pdf_doc->ObjMapTree == NULL)
return NULL;
tmp.in = in;
@@ -327,32 +280,31 @@ static ObjMap *findObjMap(PdfDocument * pdf_doc, Ref in)
static void addObjMap(PdfDocument * pdf_doc, Ref in, int out_num)
{
ObjMap *obj_map = NULL;
- assert(findObjMap(pdf_doc, in) == NULL);
if (pdf_doc->ObjMapTree == NULL)
pdf_doc->ObjMapTree = avl_create(CompObjMap, NULL, &avl_xallocator);
obj_map = new ObjMap;
obj_map->in = in;
obj_map->out_num = out_num;
- void **aa = avl_probe(pdf_doc->ObjMapTree, obj_map);
- assert(aa != NULL);
+ avl_probe(pdf_doc->ObjMapTree, obj_map);
}
-// When copying the Resources of the selected page, all objects are
-// copied recursively top-down. The findObjMap() function checks if an
-// object has already been copied; if so, instead of copying just the
-// new object number will be referenced. The ObjMapTree guarantees,
-// that during the entire LuaTeX run any object from any embedded PDF
-// file will end up max. once in the output PDF file. Indirect objects
-// are not fetched during copying, but get a new object number from
-// LuaTeX and then will be appended into a linked list.
+/*
+ When copying the Resources of the selected page, all objects are
+ copied recursively top-down. The findObjMap() function checks if an
+ object has already been copied; if so, instead of copying just the
+ new object number will be referenced. The ObjMapTree guarantees,
+ that during the entire LuaTeX run any object from any embedded PDF
+ file will end up max. once in the output PDF file. Indirect objects
+ are not fetched during copying, but get a new object number from
+ LuaTeX and then will be appended into a linked list.
+*/
static int addInObj(PDF pdf, PdfDocument * pdf_doc, Ref ref)
{
ObjMap *obj_map;
InObj *p, *q, *n;
if (ref.num == 0) {
- luatex_fail("PDF inclusion: reference to invalid object"
- " (is the included pdf broken?)");
+ normal_error("pdf inclusion","reference to invalid object (broken pdf)");
}
if ((obj_map = findObjMap(pdf_doc, ref)) != NULL)
return obj_map->out_num;
@@ -361,12 +313,14 @@ static int addInObj(PDF pdf, PdfDocument * pdf_doc, Ref ref)
n->next = NULL;
n->num = pdf_create_obj(pdf, obj_type_others, 0);
addObjMap(pdf_doc, ref, n->num);
- if (pdf_doc->inObjList == NULL)
+ if (pdf_doc->inObjList == NULL) {
pdf_doc->inObjList = n;
- else {
- // it is important to add new objects at the end of the list,
- // because new objects are being added while the list is being
- // written out by writeRefs().
+ } else {
+ /*
+ It is important to add new objects at the end of the list,
+ because new objects are being added while the list is being
+ written out by writeRefs().
+ */
for (p = pdf_doc->inObjList; p != NULL; p = p->next)
q = p;
q->next = n;
@@ -374,15 +328,16 @@ static int addInObj(PDF pdf, PdfDocument * pdf_doc, Ref ref)
return n->num;
}
-//**********************************************************************
-// Function converts double to pdffloat; very small and very large numbers
-// are NOT converted to scientific notation.
-// n must be a number or real conforming to the implementation limits
-// of PDF as specified in appendix C.1 of the PDF Ref.
-// These are:
-// maximum value of ints is +2^32
-// maximum value of reals is +2^15
-// smalles values of reals is 1/(2^16)
+/*
+ Function converts double to pdffloat; very small and very large numbers
+ are NOT converted to scientific notation. Here n must be a number or real
+ conforming to the implementation limits of PDF as specified in appendix C.1
+ of the PDF Ref. These are:
+
+ maximum value of ints is +2^32
+ maximum value of reals is +2^15
+ smalles values of reals is 1/(2^16)
+*/
static pdffloat conv_double_to_pdffloat(double n)
{
@@ -493,7 +448,6 @@ static void copyStream(PDF pdf, PdfDocument * pdf_doc, Stream * stream)
{
copyDict(pdf, pdf_doc, stream->getDict());
pdf_begin_stream(pdf);
- assert(pdf->zip_write_state == NO_ZIP);
copyStreamStream(pdf, stream->getUndecodedStream());
pdf_end_stream(pdf);
}
@@ -510,9 +464,11 @@ static void copyObject(PDF pdf, PdfDocument * pdf_doc, Object * obj)
case objReal:
copyReal(pdf, obj->getReal());
break;
- // not needed:
- // case objNum:
- // GBool isNum() { return type == objInt || type == objReal; }
+ /*
+ case objNum:
+ GBool isNum() { return type == objInt || type == objReal; }
+ break;
+ */
case objString:
copyString(pdf, obj->getString());
break;
@@ -538,16 +494,14 @@ static void copyObject(PDF pdf, PdfDocument * pdf_doc, Object * obj)
case objError:
case objEOF:
case objNone:
- luatex_fail("PDF inclusion: type <%s> cannot be copied",
- obj->getTypeName());
+ formatted_error("pdf inclusion","type '%s' cannot be copied", obj->getTypeName());
break;
default:
- assert(0); // poppler doesn't have any other types
+ /* poppler doesn't have any other types */
+ assert(0);
}
}
-//**********************************************************************
-
static void writeRefs(PDF pdf, PdfDocument * pdf_doc)
{
InObj *r, *n;
@@ -560,7 +514,7 @@ static void writeRefs(PDF pdf, PdfDocument * pdf_doc)
if (obj1.isStream())
pdf_begin_obj(pdf, r->num, OBJSTM_NEVER);
else
- pdf_begin_obj(pdf, r->num, 2); // \pdfobjcompresslevel = 2 is for this
+ pdf_begin_obj(pdf, r->num, 2);
copyObject(pdf, pdf_doc, &obj1);
obj1.free();
pdf_end_obj(pdf);
@@ -570,115 +524,120 @@ static void writeRefs(PDF pdf, PdfDocument * pdf_doc)
}
}
-// get the pagebox coordinates according to the pagebox_spec
+/* get the pagebox coordinates according to the pagebox_spec */
static PDFRectangle *get_pagebox(Page * page, int pagebox_spec)
{
switch (pagebox_spec) {
- case PDF_BOX_SPEC_MEDIA:
- return page->getMediaBox();
- break;
- case PDF_BOX_SPEC_CROP:
- return page->getCropBox();
- break;
- case PDF_BOX_SPEC_BLEED:
- return page->getBleedBox();
- break;
- case PDF_BOX_SPEC_TRIM:
- return page->getTrimBox();
- break;
- case PDF_BOX_SPEC_ART:
- return page->getArtBox();
- break;
- default:
- luatex_fail("PDF inclusion: unknown value of pagebox spec (%i)",
- (int) pagebox_spec);
+ case PDF_BOX_SPEC_MEDIA:
+ return page->getMediaBox();
+ break;
+ case PDF_BOX_SPEC_CROP:
+ return page->getCropBox();
+ break;
+ case PDF_BOX_SPEC_BLEED:
+ return page->getBleedBox();
+ break;
+ case PDF_BOX_SPEC_TRIM:
+ return page->getTrimBox();
+ break;
+ case PDF_BOX_SPEC_ART:
+ return page->getArtBox();
+ break;
+ default:
+ return page->getMediaBox();
+ break;
}
- return page->getMediaBox(); // to make the compiler happy
}
-// Reads various information about the PDF and sets it up for later inclusion.
-// This will fail if the PDF version of the PDF is higher than
-// minor_pdf_version_wanted or page_name is given and can not be found.
-// It makes no sense to give page_name _and_ page_num.
-// Returns the page number.
+/*
+ Reads various information about the PDF and sets it up for later inclusion.
+ This will fail if the PDF version of the PDF is higher than minor_pdf_version_wanted
+ or page_name is given and can not be found. It makes no sense to give page_name and
+ page_num. Returns the page number.
+*/
-void
-read_pdf_info(image_dict * idict, int minor_pdf_version_wanted,
- int pdf_inclusion_errorlevel, img_readtype_e readtype)
+void flush_pdf_info(image_dict * idict)
{
- PdfDocument *pdf_doc;
- PDFDoc *doc;
+ if (img_keepopen(idict)) {
+ unrefPdfDocument(img_filepath(idict));
+ }
+}
+
+/*
+ void flush_pdfstream_info(image_dict * idict)
+ {
+ if (img_pdfstream_ptr(idict) != NULL) {
+ xfree(img_pdfstream_stream(idict));
+ xfree(img_pdfstream_ptr(idict));
+ img_pdfstream_stream(idict) = NULL;
+ img_pdfstream_ptr(idict) = NULL;
+ }
+ }
+*/
+
+void read_pdf_info(image_dict * idict)
+{
+ PdfDocument *pdf_doc = NULL;
+ PDFDoc *doc = NULL;
Catalog *catalog;
Page *page;
int rotate;
PDFRectangle *pagebox;
int pdf_major_version_found, pdf_minor_version_found;
float xsize, ysize, xorig, yorig;
- assert(idict != NULL);
- assert((img_type(idict) == IMG_TYPE_PDF) || (img_type(idict) == IMG_TYPE_PDFMEMSTREAM));
- assert(readtype == IMG_CLOSEINBETWEEN); // only this is implemented
- // initialize
if (isInit == gFalse) {
- if (!(globalParams)) // globalParams could be already created
- globalParams = new GlobalParams();
- globalParams->setErrQuiet(gFalse);
- isInit = gTrue;
- }
- // open PDF file
- if (img_type(idict) == IMG_TYPE_PDF)
- pdf_doc = refPdfDocument(img_filepath(idict), FE_FAIL);
+ if (!(globalParams))
+ globalParams = new GlobalParams();
+ globalParams->setErrQuiet(gFalse);
+ isInit = gTrue;
+ }
+ if (img_type(idict) == IMG_TYPE_PDF)
+ pdf_doc = refPdfDocument(img_filepath(idict), FE_FAIL);
else if (img_type(idict) == IMG_TYPE_PDFMEMSTREAM) {
- pdf_doc = findPdfDocument(img_filepath(idict)) ;
- assert(pdf_doc != NULL);
- pdf_doc->occurences++;
- } else
- luatex_fail("PDF inclusion: unknown document (1)");
+ pdf_doc = findPdfDocument(img_filepath(idict)) ;
+ pdf_doc->occurences++;
+ } else {
+ normal_error("pdf inclusion","unknown document");
+ }
doc = pdf_doc->doc;
catalog = doc->getCatalog();
- // check PDF version
- // this works only for PDF 1.x -- but since any versions of PDF newer
- // than 1.x will not be backwards compatible to PDF 1.x, pdfTeX will
- // then have to changed drastically anyway.
+ /*
+ Check PDF version. This works only for PDF 1.x but since any versions of
+ PDF newer than 1.x will not be backwards compatible to PDF 1.x, we will
+ then have to changed drastically anyway.
+ */
pdf_major_version_found = doc->getPDFMajorVersion();
pdf_minor_version_found = doc->getPDFMinorVersion();
- if ((pdf_major_version_found > 1)
- || (pdf_minor_version_found > minor_pdf_version_wanted)) {
- const char *msg =
- "PDF inclusion: found PDF version <%d.%d>, but at most version <1.%d> allowed";
- if (pdf_inclusion_errorlevel > 0) {
- luatex_fail(msg, pdf_major_version_found, pdf_minor_version_found,
- minor_pdf_version_wanted);
+ if ((pdf_major_version_found > 1) || (pdf_minor_version_found > img_pdfminorversion(idict))) {
+ const char *msg = "PDF inclusion: found PDF version '%d.%d', but at most version '1.%d' allowed";
+ if (img_errorlevel(idict) > 0) {
+ formatted_error("pdf inclusion",msg, pdf_major_version_found, pdf_minor_version_found, img_pdfminorversion(idict));
} else {
- luatex_warn(msg, pdf_major_version_found, pdf_minor_version_found,
- minor_pdf_version_wanted);
+ formatted_warning("pdf inclusion",msg, pdf_major_version_found, pdf_minor_version_found, img_pdfminorversion(idict));
}
}
img_totalpages(idict) = catalog->getNumPages();
if (img_pagename(idict)) {
- // get page by name
+ /* get page by name */
GooString name(img_pagename(idict));
LinkDest *link = doc->findDest(&name);
if (link == NULL || !link->isOk())
- luatex_fail("PDF inclusion: invalid destination <%s>",
- img_pagename(idict));
+ formatted_error("pdf inclusion","invalid destination '%s'",img_pagename(idict));
Ref ref = link->getPageRef();
img_pagenum(idict) = catalog->findPage(ref.num, ref.gen);
if (img_pagenum(idict) == 0)
- luatex_fail("PDF inclusion: destination is not a page <%s>",
- img_pagename(idict));
+ formatted_error("pdf inclusion","destination is not a page '%s'",img_pagename(idict));
delete link;
} else {
- // get page by number
+ /* get page by number */
if (img_pagenum(idict) <= 0
|| img_pagenum(idict) > img_totalpages(idict))
- luatex_fail("PDF inclusion: required page <%i> does not exist",
- (int) img_pagenum(idict));
+ formatted_error("pdf inclusion","required page '%i' does not exist",(int) img_pagenum(idict));
}
- // get the required page
+ /* get the required page */
page = catalog->getPage(img_pagenum(idict));
-
- // get the pagebox coordinates (media, crop,...) to use.
+ /* get the pagebox coordinates (media, crop,...) to use. */
pagebox = get_pagebox(page, img_pagebox(idict));
if (pagebox->x2 > pagebox->x1) {
xorig = pagebox->x1;
@@ -694,51 +653,64 @@ read_pdf_info(image_dict * idict, int minor_pdf_version_wanted,
yorig = pagebox->y2;
ysize = pagebox->y1 - pagebox->y2;
}
- // The following 4 parameters are raw. Do _not_ modify by /Rotate!
+ /* The following 4 parameters are raw. Do _not_ modify by /Rotate! */
img_xsize(idict) = bp2sp(xsize);
img_ysize(idict) = bp2sp(ysize);
img_xorig(idict) = bp2sp(xorig);
img_yorig(idict) = bp2sp(yorig);
-
- // Handle /Rotate parameter. Only multiples of 90 deg. are allowed
- // (PDF Ref. v1.3, p. 78).
+ /*
+ Handle /Rotate parameter. Only multiples of 90 deg. are allowed (PDF Ref. v1.3,
+ p. 78). We also accept negative angles. Beware: PDF counts clockwise! */
rotate = page->getRotate();
- switch (((rotate % 360) + 360) % 360) { // handles also neg. angles
- case 0:
- img_rotation(idict) = 0;
- break;
- case 90:
- img_rotation(idict) = 3; // PDF counts clockwise!
- break;
- case 180:
- img_rotation(idict) = 2;
- break;
- case 270:
- img_rotation(idict) = 1;
- break;
- default:
- luatex_warn
- ("PDF inclusion: "
- "/Rotate parameter in PDF file not multiple of 90 degrees.");
+ switch (((rotate % 360) + 360) % 360) {
+ case 0:
+ img_rotation(idict) = 0;
+ break;
+ case 90:
+ img_rotation(idict) = 3;
+ break;
+ case 180:
+ img_rotation(idict) = 2;
+ break;
+ case 270:
+ img_rotation(idict) = 1;
+ break;
+ default:
+ formatted_warning("pdf inclusion","/Rotate parameter in PDF file not multiple of 90 degrees");
}
-
- // currently unused info whether PDF contains a /Group
+ /* currently unused info whether PDF contains a /Group */
if (page->getGroup() != NULL)
img_set_group(idict);
+ /*
+ LuaTeX pre 0.85 versions did this:
- if (readtype == IMG_CLOSEINBETWEEN)
+ if (readtype == IMG_CLOSEINBETWEEN) {
+ unrefPdfDocument(img_filepath(idict));
+ }
+
+ and also unref'd in the finalizer zo we got an extra unrefs when garbage was
+ collected. However it is more efficient to keep the file open so we do that
+ now. The (slower) alternative is to unref here (which in most cases forcing a
+ close of the file) but then we must not call flush_pdf_info.
+
+ A close (unref) can be forced by nilling the dict object at the lua end and
+ forcing a collectgarbage("collect") after that.
+
+ */
+ if (! img_keepopen(idict)) {
unrefPdfDocument(img_filepath(idict));
+ }
}
-//**********************************************************************
-// Writes the current epf_doc.
-// Here the included PDF is copied, so most errors that can happen
-// during PDF inclusion will arise here.
+/*
+ Write the current epf_doc. Here the included PDF is copied, so most errors
+ that can happen during PDF inclusion will arise here.
+*/
void write_epdf(PDF pdf, image_dict * idict)
{
- PdfDocument *pdf_doc;
- PDFDoc *doc;
+ PdfDocument *pdf_doc = NULL;
+ PDFDoc *doc = NULL;
Catalog *catalog;
Page *page;
Ref *pageref;
@@ -748,46 +720,39 @@ void write_epdf(PDF pdf, image_dict * idict)
int i, l;
double bbox[4];
char s[256];
- const char *pagedictkeys[] =
- { "Group", "LastModified", "Metadata", "PieceInfo", "Resources",
- "SeparationInfo", NULL
+ const char *pagedictkeys[] = {
+ "Group", "LastModified", "Metadata", "PieceInfo", "Resources", "SeparationInfo", NULL
};
- assert(idict != NULL);
-
- // open PDF file
- if (img_type(idict) == IMG_TYPE_PDF)
- pdf_doc = refPdfDocument(img_filepath(idict), FE_FAIL);
- else if (img_type(idict) == IMG_TYPE_PDFMEMSTREAM) {
- pdf_doc = findPdfDocument(img_filepath(idict)) ;
- assert(pdf_doc != NULL);
- pdf_doc->occurences++;
- } else
- luatex_fail("PDF inclusion: unknown document (2)");
+ /* open PDF file */
+ if (img_type(idict) == IMG_TYPE_PDF) {
+ pdf_doc = refPdfDocument(img_filepath(idict), FE_FAIL);
+ } else if (img_type(idict) == IMG_TYPE_PDFMEMSTREAM) {
+ pdf_doc = findPdfDocument(img_filepath(idict)) ;
+ pdf_doc->occurences++;
+ } else {
+ normal_error("pdf inclusion","unknown document");
+ }
doc = pdf_doc->doc;
catalog = doc->getCatalog();
page = catalog->getPage(img_pagenum(idict));
pageref = catalog->getPageRef(img_pagenum(idict));
- assert(pageref != NULL); // was checked already in read_pdf_info()
doc->getXRef()->fetch(pageref->num, pageref->gen, &pageobj);
pageDict = pageobj.getDict();
-
- // write the Page header
+ /* write the Page header */
pdf_begin_obj(pdf, img_objnum(idict), OBJSTM_NEVER);
pdf_begin_dict(pdf);
pdf_dict_add_name(pdf, "Type", "XObject");
pdf_dict_add_name(pdf, "Subtype", "Form");
-
if (img_attr(idict) != NULL && strlen(img_attr(idict)) > 0)
pdf_printf(pdf, "\n%s\n", img_attr(idict));
pdf_dict_add_int(pdf, "FormType", 1);
-
- // write additional information
+ /* write additional information */
pdf_dict_add_img_filename(pdf, idict);
snprintf(s, 30, "%s.PageNumber", pdfkeyprefix);
pdf_dict_add_int(pdf, s, (int) img_pagenum(idict));
doc->getDocInfoNF(&obj1);
if (obj1.isRef()) {
- // the info dict must be indirect (PDF Ref p. 61)
+ /* the info dict must be indirect (PDF Ref p. 61) */
snprintf(s, 30, "%s.InfoDict", pdfkeyprefix);
pdf_dict_add_ref(pdf, s, addInObj(pdf, pdf_doc, obj1.getRef()));
}
@@ -798,7 +763,7 @@ void write_epdf(PDF pdf, image_dict * idict)
bbox[2] = sp2bp(img_bbox(idict)[2]);
bbox[3] = sp2bp(img_bbox(idict)[3]);
} else {
- // get the pagebox coordinates (media, crop,...) to use.
+ /* get the pagebox coordinates (media, crop,...) to use. */
pagebox = get_pagebox(page, img_pagebox(idict));
bbox[0] = pagebox->x1;
bbox[1] = pagebox->y1;
@@ -812,30 +777,30 @@ void write_epdf(PDF pdf, image_dict * idict)
copyReal(pdf, bbox[2]);
copyReal(pdf, bbox[3]);
pdf_end_array(pdf);
- // The /Matrix calculation is replaced by transforms in out_img().
-
- // Now all relevant parts of the Page dictionary are copied:
-
- // Metadata validity check (as a stream it must be indirect)
+ /*
+ Now all relevant parts of the Page dictionary are copied. Metadata validity
+ check is needed(as a stream it must be indirect).
+ */
pageDict->lookupNF("Metadata", &obj1);
if (!obj1.isNull() && !obj1.isRef())
- luatex_warn("PDF inclusion: /Metadata must be indirect object");
+ formatted_warning("pdf inclusion","/Metadata must be indirect object");
obj1.free();
-
- // copy selected items in Page dictionary
+ /* copy selected items in Page dictionary */
for (i = 0; pagedictkeys[i] != NULL; i++) {
pageDict->lookupNF(pagedictkeys[i], &obj1);
if (!obj1.isNull()) {
pdf_add_name(pdf, pagedictkeys[i]);
- copyObject(pdf, pdf_doc, &obj1); // preserves indirection
+ /* preserves indirection */
+ copyObject(pdf, pdf_doc, &obj1);
}
obj1.free();
}
-
- // If there are no Resources in the Page dict of the embedded page,
- // try to inherit the Resources from the Pages tree of the embedded
- // PDF file, climbing up the tree until the Resources are found.
- // (This fixes a problem with Scribus 1.3.3.14.)
+ /*
+ If there are no Resources in the Page dict of the embedded page,
+ try to inherit the Resources from the Pages tree of the embedded
+ PDF file, climbing up the tree until the Resources are found.
+ (This fixes a problem with Scribus 1.3.3.14.)
+ */
pageDict->lookupNF("Resources", &obj1);
if (obj1.isNull()) {
op1 = &pagesobj1;
@@ -856,30 +821,28 @@ void write_epdf(PDF pdf, image_dict * idict)
op2->free();
};
if (!op1->isDict())
- luatex_warn("PDF inclusion: Page /Resources missing.");
+ formatted_warning("pdf inclusion","Page /Resources missing");
op1->free();
}
obj1.free();
-
- // write the Page contents
+ /* Write the Page contents. */
page->getContents(&contents);
if (contents.isStream()) {
- // Variant A: get stream and recompress under control
- // of \pdfcompresslevel
- //
- // pdf_begin_stream();
- // copyStreamStream(contents->getStream());
- // pdf_end_stream();
-
- // Variant B: copy stream without recompressing
- //
+ /*
+ Variant A: get stream and recompress under control of \pdfcompresslevel
+
+ pdf_begin_stream();
+ copyStreamStream(contents->getStream());
+ pdf_end_stream();
+
+ Variant B: copy stream without recompressing
+ */
contents.streamGetDict()->lookup("F", &obj1);
if (!obj1.isNull()) {
- luatex_fail("PDF inclusion: Unsupported external stream");
+ normal_error("pdf inclusion","unsupported external stream");
}
obj1.free();
contents.streamGetDict()->lookup("Length", &obj1);
- assert(!obj1.isNull());
pdf_add_name(pdf, "Length");
copyObject(pdf, pdf_doc, &obj1);
obj1.free();
@@ -908,46 +871,45 @@ void write_epdf(PDF pdf, image_dict * idict)
copyStreamStream(pdf, (contents.arrayGet(i, &obj1))->getStream());
obj1.free();
if (i < (l - 1)) {
- // put a space between streams to be on the safe side (streams
- // should have a trailing space here, but one never knows)
+ /*
+ Put a space between streams to be on the safe side (streams
+ should have a trailing space here, but one never knows)
+ */
pdf_out(pdf, ' ');
}
}
pdf_end_stream(pdf);
pdf_end_obj(pdf);
- } else { // the contents are optional, but we need to include an empty stream
+ } else {
+ /* the contents are optional, but we need to include an empty stream */
pdf_dict_add_streaminfo(pdf);
pdf_end_dict(pdf);
pdf_begin_stream(pdf);
pdf_end_stream(pdf);
pdf_end_obj(pdf);
}
- // write out all indirect objects
+ /* write out all indirect objects */
writeRefs(pdf, pdf_doc);
contents.free();
pageobj.free();
- // unrefPdfDocument() must come after contents.free() and pageobj.free()!
- // TH: The next line makes repeated pdf inclusion unacceptably slow
-#if 0
- unrefPdfDocument(img_filepath(idict));
-#endif
+ /*
+ unrefPdfDocument() must come after contents.free() and pageobj.free()!
+ TH: The next line makes repeated pdf inclusion unacceptably slow
+
+ unrefPdfDocument(img_filepath(idict));
+ */
}
-//**********************************************************************
-// Deallocate a PdfDocument with all its resources
+/* Deallocate a PdfDocument with all its resources. */
static void deletePdfDocumentPdfDoc(PdfDocument * pdf_doc)
{
InObj *r, *n;
- assert(pdf_doc != NULL);
- // this may be probably needed for an emergency destroyPdfDocument()
+ /* this may be probably needed for an emergency destroyPdfDocument() */
for (r = pdf_doc->inObjList; r != NULL; r = n) {
n = r->next;
delete r;
}
-#ifdef DEBUG
- fprintf(stderr, "\nDEBUG: Deleting PDFDoc %s\n", pdf_doc->file_path);
-#endif
delete pdf_doc->doc;
pdf_doc->doc = NULL;
pdf_doc->pc++;
@@ -957,47 +919,46 @@ static void destroyPdfDocument(void *pa, void * /*pb */ )
{
PdfDocument *pdf_doc = (PdfDocument *) pa;
deletePdfDocumentPdfDoc(pdf_doc);
- // TODO: delete rest of pdf_doc
+ /* TODO: delete rest of pdf_doc */
}
-// Called when an image has been written and its resources in image_tab are
-// freed and it's not referenced anymore.
+/*
+ Called when an image has been written and its resources in image_tab are
+ freed and it's not referenced anymore.
+*/
void unrefPdfDocument(char *file_path)
{
PdfDocument *pdf_doc = findPdfDocument(file_path);
- if (pdf_doc == NULL) /* Does the caller break the contract ? */
-return;
- if (pdf_doc->occurences == 0) /* Again, does the caller breaks the contract ? */
-return;
- /* for the moment we keep these assert here as remind that the code */
- /* should be revisited */
- //assert(pdf_doc != NULL);
- //assert(pdf_doc->occurences != 0); // aim for point landing
- pdf_doc->occurences--;
-#ifdef DEBUG
- fprintf(stderr, "\nDEBUG: Decrementing %s (%d)\n",
- pdf_doc->file_path, pdf_doc->occurences);
-#endif
- if (pdf_doc->occurences == 0) {
- assert(pdf_doc->inObjList == NULL); // should be eaten up already
- deletePdfDocumentPdfDoc(pdf_doc);
+ if (pdf_doc->occurences > 0) {
+ pdf_doc->occurences--;
+ if (pdf_doc->occurences == 0) {
+ deletePdfDocumentPdfDoc(pdf_doc);
+ }
+ } else {
+ /*
+ We either have a mismatch in ref and unref or we're somehow out of sync
+ which can happen when we mess with the same file in lua and tex.
+ */
+ formatted_warning("pdf inclusion","there can be a mismatch in opening and closing file '%s'",file_path);
}
}
-
-
-// For completeness, but it isn't currently used
-// (unreferencing is done by mean of file_path)
+/*
+ For completeness, but it isn't currently used (unreferencing is done by mean
+ of file_path.
+*/
void unrefMemStreamPdfDocument(char *file_id)
{
(void) unrefPdfDocument(file_id);
-
+
}
-// Called when PDF embedding system is finalized.
-// Now deallocate all remaining PdfDocuments.
+/*
+ Called when PDF embedding system is finalized. We now deallocate all remaining
+ PdfDocuments.
+*/
void epdf_free()
{