summaryrefslogtreecommitdiff
path: root/Build/source/texk/web2c/luatexdir/image
diff options
context:
space:
mode:
authorAkira Kakuto <kakuto@fuk.kindai.ac.jp>2015-10-07 02:16:02 +0000
committerAkira Kakuto <kakuto@fuk.kindai.ac.jp>2015-10-07 02:16:02 +0000
commita021762e6ccc1101fefbac38abb168b69a11f0ca (patch)
treebaf31827b9c7c7af518a3f4aa58ccba0de18b640 /Build/source/texk/web2c/luatexdir/image
parent4ca2692153042a0c2f7db8d681e190b867ae2faf (diff)
web2c/luatexdir: Sync with the upstream trunk.
git-svn-id: svn://tug.org/texlive/trunk@38575 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/web2c/luatexdir/image')
-rw-r--r--Build/source/texk/web2c/luatexdir/image/epdf.h10
-rw-r--r--Build/source/texk/web2c/luatexdir/image/image.h5
-rw-r--r--Build/source/texk/web2c/luatexdir/image/pdftoepdf.h1
-rw-r--r--Build/source/texk/web2c/luatexdir/image/pdftoepdf.w153
-rw-r--r--Build/source/texk/web2c/luatexdir/image/writeimg.w37
5 files changed, 190 insertions, 16 deletions
diff --git a/Build/source/texk/web2c/luatexdir/image/epdf.h b/Build/source/texk/web2c/luatexdir/image/epdf.h
index 2c9d5db53e5..1a4cc78c381 100644
--- a/Build/source/texk/web2c/luatexdir/image/epdf.h
+++ b/Build/source/texk/web2c/luatexdir/image/epdf.h
@@ -124,6 +124,7 @@ extern "C" {
extern void read_pdf_info(image_dict *, int, int, img_readtype_e);
extern void write_epdf(PDF, image_dict *);
extern void unrefPdfDocument(char *);
+ extern void unrefMemStreamPdfDocument(char *);
extern void epdf_free(void);
extern void copyReal(PDF pdf, double d);
@@ -194,4 +195,13 @@ struct PdfDocument {
PdfDocument *refPdfDocument(const char *file_path, file_error_mode fe);
+PdfDocument *refMemStreamPdfDocument(char *docstream, unsigned long long streamsize, const char *file_id);
+
+
+#define STREAM_CHECKSUM_SIZE 16 // md5
+#define STRSTREAM_CHECKSUM_SIZE 1+((unsigned int)(log(ULONG_MAX)/log(16))) // djb2 printable digest as hex stream
+#define STREAM_FILE_ID_LEN 2048 // 2048 bytes are enough to make a strong almost-unique name
+#define STREAM_URI "data:application/pdf,"
+#define STREAM_URI_LEN 21 // length of "data:application/pdf," without final '\0'
+
#endif /* EPDF_H */
diff --git a/Build/source/texk/web2c/luatexdir/image/image.h b/Build/source/texk/web2c/luatexdir/image/image.h
index 32ead6a0f65..5a9adfdc9bb 100644
--- a/Build/source/texk/web2c/luatexdir/image/image.h
+++ b/Build/source/texk/web2c/luatexdir/image/image.h
@@ -70,8 +70,9 @@ typedef enum { DICT_NEW, /* fresh dictionary */
DICT_WRITTEN /* image dict written to file */
} dict_state;
+
typedef enum { IMG_TYPE_NONE, IMG_TYPE_PDF, IMG_TYPE_PNG, IMG_TYPE_JPG,
- IMG_TYPE_JP2, IMG_TYPE_JBIG2, IMG_TYPE_PDFSTREAM, IMG_TYPE_SENTINEL
+ IMG_TYPE_JP2, IMG_TYPE_JBIG2, IMG_TYPE_PDFSTREAM, IMG_TYPE_PDFMEMSTREAM, IMG_TYPE_SENTINEL
} imgtype_e;
typedef enum { IMG_KEEPOPEN, IMG_CLOSEINBETWEEN } img_readtype_e;
@@ -183,7 +184,7 @@ typedef struct {
# define epdf_orig_x(a) img_xorig(idict_array[a])
# define epdf_orig_y(a) img_yorig(idict_array[a])
-# define is_pdf_image(a) (img_type(idict_array[a]) == IMG_TYPE_PDF)
+# define is_pdf_image(a) ((img_type(idict_array[a]) == IMG_TYPE_PDF) || (img_type(idict_array[a]) == IMG_TYPE_PDFMEMSTREAM))
# define is_png_image(a) (img_type(idict_array[a]) == IMG_TYPE_PNG)
# define img_is_refered(N) (img_index(N) != -1)
diff --git a/Build/source/texk/web2c/luatexdir/image/pdftoepdf.h b/Build/source/texk/web2c/luatexdir/image/pdftoepdf.h
index 4e2dc36717c..203f85c5c31 100644
--- a/Build/source/texk/web2c/luatexdir/image/pdftoepdf.h
+++ b/Build/source/texk/web2c/luatexdir/image/pdftoepdf.h
@@ -26,6 +26,7 @@
void read_pdf_info(image_dict *, int, int, img_readtype_e);
void unrefPdfDocument(char *);
+void unrefMemStreamPdfDocument(char *);
void write_epdf(PDF, image_dict *);
void epdf_check_mem(void);
void copyReal(PDF pdf, double d);
diff --git a/Build/source/texk/web2c/luatexdir/image/pdftoepdf.w b/Build/source/texk/web2c/luatexdir/image/pdftoepdf.w
index b01a10bb8c1..cacaea11389 100644
--- a/Build/source/texk/web2c/luatexdir/image/pdftoepdf.w
+++ b/Build/source/texk/web2c/luatexdir/image/pdftoepdf.w
@@ -27,7 +27,9 @@
#include "image/epdf.h"
// This file is mostly C and not very much C++; it's just used to interface
-// the functions of xpdf, which happens to be written in C++.
+// the functions of poppler, which happens to be written in C++.
+
+extern void md5(Guchar *msg, int msgLen, Guchar *digest);
static GBool isInit = gFalse;
@@ -89,6 +91,27 @@ static char *get_file_checksum(const char *a, file_error_mode fe)
return ck;
}
+
+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;
+}
+
+
+
// 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.
@@ -144,7 +167,7 @@ PdfDocument *refPdfDocument(const char *file_path, file_error_mode fe)
if (!doc->isOk() || !doc->okToPrint()) {
switch (fe) {
case FE_FAIL:
- luatex_fail("xpdf: reading PDF image failed");
+ luatex_fail("PDF inclusion: reading PDF image failed");
break;
case FE_RETURN_NULL:
delete doc;
@@ -179,6 +202,92 @@ PdfDocument *refPdfDocument(const char *file_path, file_error_mode fe)
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
+
+PdfDocument *refMemStreamPdfDocument(char *docstream, unsigned long long streamsize,const char *file_id)
+{
+ char *checksum;
+ char *file_path;
+ PdfDocument *pdf_doc;
+ PDFDoc *doc = NULL;
+ Object obj;
+ 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(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;
+ pdf_doc->checksum = checksum;
+ pdf_doc->doc = NULL;
+ pdf_doc->inObjList = NULL;
+ pdf_doc->ObjMapTree = NULL;
+ 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 is should be useless.
+ if (strncmp(pdf_doc->checksum, checksum, STRSTREAM_CHECKSUM_SIZE) != 0) {
+ luatex_fail("PDF inclusion: stream has changed '%s'", 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
+ pdf_doc->pc++;
+
+ if (!doc->isOk() || !doc->okToPrint()) {
+ luatex_fail("poppler: reading PDF Stream failed");
+ }
+ pdf_doc->doc = doc;
+ }
+ // 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);
+ }
+ 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
@@ -433,7 +542,7 @@ static void copyObject(PDF pdf, PdfDocument * pdf_doc, Object * obj)
obj->getTypeName());
break;
default:
- assert(0); // xpdf doesn't have any other types
+ assert(0); // poppler doesn't have any other types
}
}
@@ -507,16 +616,24 @@ read_pdf_info(image_dict * idict, int minor_pdf_version_wanted,
int pdf_major_version_found, pdf_minor_version_found;
float xsize, ysize, xorig, yorig;
assert(idict != NULL);
- assert(img_type(idict) == IMG_TYPE_PDF);
+ 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) {
- globalParams = new GlobalParams();
- globalParams->setErrQuiet(gFalse);
- isInit = gTrue;
+ if (!(globalParams)) // globalParams could be already created
+ globalParams = new GlobalParams();
+ globalParams->setErrQuiet(gFalse);
+ isInit = gTrue;
}
// open PDF file
- pdf_doc = refPdfDocument(img_filepath(idict), FE_FAIL);
+ 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)");
doc = pdf_doc->doc;
catalog = doc->getCatalog();
// check PDF version
@@ -638,7 +755,14 @@ void write_epdf(PDF pdf, image_dict * idict)
assert(idict != NULL);
// open PDF file
- pdf_doc = refPdfDocument(img_filepath(idict), FE_FAIL);
+ 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)");
doc = pdf_doc->doc;
catalog = doc->getCatalog();
page = catalog->getPage(img_pagenum(idict));
@@ -855,6 +979,17 @@ void unrefPdfDocument(char *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.
diff --git a/Build/source/texk/web2c/luatexdir/image/writeimg.w b/Build/source/texk/web2c/luatexdir/image/writeimg.w
index 3f6da1a4bee..561efd514c0 100644
--- a/Build/source/texk/web2c/luatexdir/image/writeimg.w
+++ b/Build/source/texk/web2c/luatexdir/image/writeimg.w
@@ -124,18 +124,41 @@
#define HEADER_JP2 "\x6A\x50\x20\x20"
#define HEADER_PDF "%PDF-1."
#define MAX_HEADER (sizeof(HEADER_PNG)-1)
+#define HEADER_PDF_MEMSTREAM "data:application/pdf," /* see epdf.h */
+#define LEN_PDF_MEMSTREAM 21 /* see epdf.h */
+
static void check_type_by_header(image_dict * idict)
{
int i;
FILE *file = NULL;
char header[MAX_HEADER];
+ char prefix[LEN_PDF_MEMSTREAM+1];
assert(idict != NULL);
if (img_type(idict) != IMG_TYPE_NONE) /* nothing to do */
return;
+
/* read the header */
- file = xfopen(img_filepath(idict), FOPEN_RBIN_MODE);
+ /* Like */
+ /* file = xfopen(img_filepath(idict), FOPEN_RBIN_MODE);*/
+ /* but we also check for a memstream object */
+ assert(img_filepath(idict) && FOPEN_RBIN_MODE);
+ file = fopen(img_filepath(idict), FOPEN_RBIN_MODE);
+ if (file == NULL) {
+ /* check the prefix of img_filepath(idict) */
+ for (i = 0; (unsigned) i < LEN_PDF_MEMSTREAM; i++) {
+ prefix[i] = (char) (img_filepath(idict)[i]);
+ }
+ prefix[LEN_PDF_MEMSTREAM]='\0';
+ if (strncmp(prefix, HEADER_PDF_MEMSTREAM, LEN_PDF_MEMSTREAM) == 0) {
+ img_type(idict) = IMG_TYPE_PDFMEMSTREAM;
+ return;
+ } else {
+ FATAL_PERROR(img_filepath(idict));
+ }
+ }
+ /* a valid file, but perhaps unsupported */
for (i = 0; (unsigned) i < MAX_HEADER; i++) {
header[i] = (char) xgetc(file);
if (feof(file))
@@ -252,6 +275,7 @@ void free_image_dict(image_dict * p)
/* called from limglib.c */
assert(img_state(p) < DICT_REFERED);
switch (img_type(p)) {
+ case IMG_TYPE_PDFMEMSTREAM:
case IMG_TYPE_PDF:
unrefPdfDocument(img_filepath(p));
break;
@@ -310,6 +334,7 @@ void read_img(PDF pdf,
check_type_by_extension(idict);
/* read image */
switch (img_type(idict)) {
+ case IMG_TYPE_PDFMEMSTREAM:
case IMG_TYPE_PDF:
assert(pdf != NULL); /* TODO! */
read_pdf_info(idict, minor_version, inclusion_errorlevel,
@@ -523,7 +548,7 @@ scaled_whd scale_img(image_dict * idict, scaled_whd alt_rule, int transform)
scaled_whd nat; /* natural size corresponding to image resolution */
int default_res;
assert(idict != NULL);
- if ((img_type(idict) == IMG_TYPE_PDF
+ if ((img_type(idict) == IMG_TYPE_PDF || img_type(idict) == IMG_TYPE_PDFMEMSTREAM
|| img_type(idict) == IMG_TYPE_PDFSTREAM) && img_is_bbox(idict)) {
x = img_xsize(idict) = img_bbox(idict)[2] - img_bbox(idict)[0]; /* dimensions from image.bbox */
y = img_ysize(idict) = img_bbox(idict)[3] - img_bbox(idict)[1];
@@ -551,7 +576,7 @@ scaled_whd scale_img(image_dict * idict, scaled_whd alt_rule, int transform)
yr = tmp;
}
nat.dp = 0; /* always for images */
- if (img_type(idict) == IMG_TYPE_PDF
+ if (img_type(idict) == IMG_TYPE_PDF || img_type(idict) == IMG_TYPE_PDFMEMSTREAM
|| img_type(idict) == IMG_TYPE_PDFSTREAM) {
nat.wd = x;
nat.ht = y;
@@ -591,6 +616,7 @@ void write_img(PDF pdf, image_dict * idict)
case IMG_TYPE_JBIG2:
write_jbig2(pdf, idict);
break;
+ case IMG_TYPE_PDFMEMSTREAM:
case IMG_TYPE_PDF:
write_epdf(pdf, idict);
break;
@@ -677,7 +703,7 @@ void pdf_dict_add_img_filename(PDF pdf, image_dict * idict)
char s[21], *p;
assert(idict != NULL);
/* for now PTEX.FileName only for PDF, but prepared for JPG, PNG, ... */
- if (img_type(idict) != IMG_TYPE_PDF)
+ if ((img_type(idict) != IMG_TYPE_PDF) || (img_type(idict) != IMG_TYPE_PDFMEMSTREAM))
return;
if (img_visiblefilename(idict) != NULL) {
if (strlen(img_visiblefilename(idict)) == 0)
@@ -768,7 +794,7 @@ void dumpimagemeta(void)
/* the |image_struct| is not dumped at all, except for a few
variables that are needed to restore the contents */
- if (img_type(idict) == IMG_TYPE_PDF) {
+ if ((img_type(idict) == IMG_TYPE_PDF)|| (img_type(idict) == IMG_TYPE_PDFMEMSTREAM)) {
dumpinteger(img_pagebox(idict));
dumpinteger(img_pagenum(idict));
} else if (img_type(idict) == IMG_TYPE_JBIG2) {
@@ -808,6 +834,7 @@ void undumpimagemeta(PDF pdf, int pdfversion, int pdfinclusionerrorlevel)
undumpinteger(img_colorspace(idict));
switch (img_type(idict)) {
+ case IMG_TYPE_PDFMEMSTREAM:
case IMG_TYPE_PDF:
undumpinteger(img_pagebox(idict));
undumpinteger(img_pagenum(idict));