diff options
author | Akira Kakuto <kakuto@fuk.kindai.ac.jp> | 2015-12-16 14:50:11 +0000 |
---|---|---|
committer | Akira Kakuto <kakuto@fuk.kindai.ac.jp> | 2015-12-16 14:50:11 +0000 |
commit | 621273b5ef8cc9e83d9aca07bf012f727ba26f15 (patch) | |
tree | 0b5cb28eec37e3e0e93a09729cbc30834166a5f9 /Build/source/texk/web2c/luatexdir/image | |
parent | f04f01782aebac8cb2fcde278c02a4fb3be4bb12 (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')
-rw-r--r-- | Build/source/texk/web2c/luatexdir/image/epdf.h | 3 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/image/image.h | 194 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/image/pdftoepdf.h | 4 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/image/pdftoepdf.w | 669 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/image/writeimg.h | 8 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/image/writeimg.w | 408 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/image/writejbig2.h | 7 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/image/writejbig2.w | 265 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/image/writejp2.h | 4 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/image/writejp2.w | 115 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/image/writejpg.h | 6 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/image/writejpg.w | 521 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/image/writepng.h | 7 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/image/writepng.w | 319 |
14 files changed, 1196 insertions, 1334 deletions
diff --git a/Build/source/texk/web2c/luatexdir/image/epdf.h b/Build/source/texk/web2c/luatexdir/image/epdf.h index 09bc7cc84e4..3d4751c4587 100644 --- a/Build/source/texk/web2c/luatexdir/image/epdf.h +++ b/Build/source/texk/web2c/luatexdir/image/epdf.h @@ -121,7 +121,8 @@ extern "C" { extern int pdf_create_obj(PDF pdf, int t, int i); /* pdftoepdf.cc */ - extern void read_pdf_info(image_dict *, int, int, img_readtype_e); + extern void read_pdf_info(image_dict *); + extern void flush_pdf_info(image_dict *); extern void write_epdf(PDF, image_dict *); extern void unrefPdfDocument(char *); extern void unrefMemStreamPdfDocument(char *); diff --git a/Build/source/texk/web2c/luatexdir/image/image.h b/Build/source/texk/web2c/luatexdir/image/image.h index 5a9adfdc9bb..49996947e26 100644 --- a/Build/source/texk/web2c/luatexdir/image/image.h +++ b/Build/source/texk/web2c/luatexdir/image/image.h @@ -18,7 +18,6 @@ You should have received a copy of the GNU General Public License along with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */ - #ifndef IMAGE_H # define IMAGE_H @@ -31,14 +30,13 @@ extern int do_zround(double r); /* from utils.w */ extern scaled one_hundred_bp; /* from pdfgen.w */ + # define bp2sp(p) do_zround(p * (one_hundred_bp / 100.0)) # define sp2bp(i) (i * 100.0 / one_hundred_bp) # define TYPE_IMG "image.meta" # define TYPE_IMG_DICT "image.dict" -/**********************************************************************/ - typedef struct { char *stream; } pdf_stream_struct; @@ -49,41 +47,52 @@ typedef struct { } png_img_struct; typedef struct { - int color_space; /* used color space. See JPG_ constants */ - JPG_UINT32 length; /* length of file/data */ + int color_space; /* used color space. See JPG_ constants */ + JPG_UINT32 length; /* length of file/data */ } jpg_img_struct; typedef struct { - int length; /* length of file/data */ + int length; /* length of file/data */ } jp2_img_struct; # if 0 -typedef struct { /* currently unused */ +typedef struct { /* currently unused */ } jb2_img_struct; # endif -typedef enum { DICT_NEW, /* fresh dictionary */ - DICT_FILESCANNED, /* image file scanned */ - DICT_REFERED, /* pdf_refximage_node in node list --> read-only dict */ - DICT_OUTIMG, /* /Im* appears in pagestream */ - DICT_SCHEDULED, /* image dict scheduled for writing (PONR) */ - DICT_WRITTEN /* image dict written to file */ +typedef enum { + DICT_NEW, /* fresh dictionary */ + DICT_FILESCANNED, /* image file scanned */ + DICT_REFERED, /* pdf_refximage_node in node list --> read-only dict */ + DICT_OUTIMG, /* /Im* appears in pagestream */ + DICT_SCHEDULED, /* image dict scheduled for writing (PONR) */ + 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_PDFMEMSTREAM, IMG_TYPE_SENTINEL +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_PDFMEMSTREAM, + IMG_TYPE_SENTINEL } imgtype_e; typedef enum { IMG_KEEPOPEN, IMG_CLOSEINBETWEEN } img_readtype_e; -typedef enum { PDF_BOX_SPEC_NONE, PDF_BOX_SPEC_MEDIA, PDF_BOX_SPEC_CROP, - PDF_BOX_SPEC_BLEED, PDF_BOX_SPEC_TRIM, PDF_BOX_SPEC_ART, +typedef enum { + PDF_BOX_SPEC_NONE, + PDF_BOX_SPEC_MEDIA, + PDF_BOX_SPEC_CROP, + PDF_BOX_SPEC_BLEED, + PDF_BOX_SPEC_TRIM, + PDF_BOX_SPEC_ART, PDF_BOX_SPEC_SENTINEL } pdfboxspec_e; -/**********************************************************************/ - typedef struct { int objnum; int index; /* /Im1, /Im2, ... */ @@ -113,100 +122,105 @@ typedef struct { int bbox[4]; dict_state state; int flags; + int luaref ; + boolean keepopen; + int errorlevel; + int pdfminorversion; union { pdf_stream_struct *pdfstream; png_img_struct *png; jpg_img_struct *jpg; jp2_img_struct *jp2; - /* jb2_img_struct *jb2; */ + /* jb2_img_struct *jb2; */ } img_struct; } image_dict; -# define img_objnum(N) ((N)->objnum) -# define img_index(N) ((N)->index) -# define img_dimen(N) ((N)->dimen) -# define img_width(N) ((N)->dimen.wd) -# define img_height(N) ((N)->dimen.ht) -# define img_depth(N) ((N)->dimen.dp) -# define img_transform(N) ((N)->transform) -# define img_xsize(N) ((N)->x_size) -# define img_ysize(N) ((N)->y_size) -# define img_xorig(N) ((N)->x_orig) -# define img_yorig(N) ((N)->y_orig) -# define img_xres(N) ((N)->x_res) -# define img_yres(N) ((N)->y_res) -# define img_rotation(N) ((N)->rotation) -# define img_colorspace(N) ((N)->colorspace) -# define img_group_ref(N) ((N)->group_ref) -# define img_totalpages(N) ((N)->total_pages) -# define img_pagenum(N) ((N)->page_num) -# define img_pagename(N) ((N)->pagename) -# define img_filename(N) ((N)->filename) -# define img_visiblefilename(N)((N)->visiblefilename) -# define img_filepath(N) ((N)->filepath) -# define img_attr(N) ((N)->attr) -# define img_file(N) ((N)->file) -# define img_type(N) ((N)->image_type) -# define img_procset(N) ((N)->procset) -# define img_colordepth(N) ((N)->color_depth) -# define img_pagebox(N) ((N)->page_box_spec) -# define img_bbox(N) ((N)->bbox) -# define img_state(N) ((N)->state) -# define img_flags(N) ((N)->flags) - -# define img_pdfstream_ptr(N) ((N)->img_struct.pdfstream) +# define img_objnum(N) ((N)->objnum) +# define img_index(N) ((N)->index) +# define img_dimen(N) ((N)->dimen) +# define img_width(N) ((N)->dimen.wd) +# define img_height(N) ((N)->dimen.ht) +# define img_depth(N) ((N)->dimen.dp) +# define img_transform(N) ((N)->transform) +# define img_xsize(N) ((N)->x_size) +# define img_ysize(N) ((N)->y_size) +# define img_xorig(N) ((N)->x_orig) +# define img_yorig(N) ((N)->y_orig) +# define img_xres(N) ((N)->x_res) +# define img_yres(N) ((N)->y_res) +# define img_rotation(N) ((N)->rotation) +# define img_colorspace(N) ((N)->colorspace) +# define img_group_ref(N) ((N)->group_ref) +# define img_totalpages(N) ((N)->total_pages) +# define img_pagenum(N) ((N)->page_num) +# define img_pagename(N) ((N)->pagename) +# define img_filename(N) ((N)->filename) +# define img_visiblefilename(N) ((N)->visiblefilename) +# define img_filepath(N) ((N)->filepath) +# define img_attr(N) ((N)->attr) +# define img_file(N) ((N)->file) +# define img_type(N) ((N)->image_type) +# define img_procset(N) ((N)->procset) +# define img_colordepth(N) ((N)->color_depth) +# define img_pagebox(N) ((N)->page_box_spec) +# define img_bbox(N) ((N)->bbox) +# define img_state(N) ((N)->state) +# define img_flags(N) ((N)->flags) +# define img_luaref(N) ((N)->luaref) +# define img_keepopen(N) ((N)->keepopen) +# define img_errorlevel(N) ((N)->errorlevel) +# define img_pdfminorversion(N) ((N)->pdfminorversion) + +# define img_pdfstream_ptr(N) ((N)->img_struct.pdfstream) # define img_pdfstream_stream(N) ((N)->img_struct.pdfstream->stream) -# define img_png_ptr(N) ((N)->img_struct.png) -# define img_png_png_ptr(N) ((N)->img_struct.png->png_ptr) -# define img_png_info_ptr(N) ((N)->img_struct.png->info_ptr) - -# define img_jpg_ptr(N) ((N)->img_struct.jpg) -# define img_jpg_color(N) ((N)->img_struct.jpg->color_space) +# define img_png_ptr(N) ((N)->img_struct.png) +# define img_png_png_ptr(N) ((N)->img_struct.png->png_ptr) +# define img_png_info_ptr(N) ((N)->img_struct.png->info_ptr) -# define img_jp2_ptr(N) ((N)->img_struct.jp2) +# define img_jpg_ptr(N) ((N)->img_struct.jpg) +# define img_jpg_color(N) ((N)->img_struct.jpg->color_space) -# define img_jb2_ptr(N) ((N)->img_struct.jb2) +# define img_jp2_ptr(N) ((N)->img_struct.jp2) -# define F_FLAG_BBOX (1 << 0) -# define F_FLAG_GROUP (1 << 1) +# define img_jb2_ptr(N) ((N)->img_struct.jb2) -# define img_set_bbox(N) (img_flags(N) |= F_FLAG_BBOX) -# define img_unset_bbox(N) (img_flags(N) &= ~F_FLAG_BBOX) -# define img_is_bbox(N) ((img_flags(N) & F_FLAG_BBOX) != 0) +# define F_FLAG_BBOX (1 << 0) +# define F_FLAG_GROUP (1 << 1) -# define img_set_group(N) (img_flags(N) |= F_FLAG_GROUP) -# define img_unset_group(N) (img_flags(N) &= ~F_FLAG_GROUP) -# define img_is_group(N) ((img_flags(N) & F_FLAG_GROUP) != 0) +# define img_set_bbox(N) (img_flags(N) |= F_FLAG_BBOX) +# define img_unset_bbox(N) (img_flags(N) &= ~F_FLAG_BBOX) +# define img_is_bbox(N) ((img_flags(N) & F_FLAG_BBOX) != 0) -# define epdf_xsize(a) img_xsize(idict_array[a]) -# define epdf_ysize(a) img_ysize(idict_array[a]) -# define epdf_orig_x(a) img_xorig(idict_array[a]) -# define epdf_orig_y(a) img_yorig(idict_array[a]) +# define img_set_group(N) (img_flags(N) |= F_FLAG_GROUP) +# define img_unset_group(N) (img_flags(N) &= ~F_FLAG_GROUP) +# define img_is_group(N) ((img_flags(N) & F_FLAG_GROUP) != 0) -# 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 epdf_xsize(a) img_xsize(idict_array[a]) +# define epdf_ysize(a) img_ysize(idict_array[a]) +# define epdf_orig_x(a) img_xorig(idict_array[a]) +# define epdf_orig_y(a) img_yorig(idict_array[a]) -# define img_is_refered(N) (img_index(N) != -1) +# 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) -/**********************************************************************/ -/* image structure corresponds to pdfrefximage node */ +# define img_is_refered(N) (img_index(N) != -1) typedef struct { - scaled_whd dimen; /* requested/actual TeX dimensions */ + scaled_whd dimen; /* requested/actual TeX dimensions */ int transform; image_dict *dict; - int dict_ref; /* luaL_ref() reference */ + int dict_ref; /* luaL_ref() reference */ } image; -# define img_dict(N) ((N)->dict) -# define img_dictref(N) ((N)->dict_ref) +# define img_dict(N) ((N)->dict) +# define img_dictref(N) ((N)->dict_ref) -# define set_wd_running(N) (img_width(N) = null_flag) -# define set_ht_running(N) (img_height(N) = null_flag) -# define set_dp_running(N) (img_depth(N) = null_flag) -# define is_wd_running(N) (img_width(N) == null_flag) -# define is_ht_running(N) (img_height(N) == null_flag) -# define is_dp_running(N) (img_depth(N) == null_flag) +# define set_wd_running(N) (img_width(N) = null_flag) +# define set_ht_running(N) (img_height(N) = null_flag) +# define set_dp_running(N) (img_depth(N) = null_flag) +# define is_wd_running(N) (img_width(N) == null_flag) +# define is_ht_running(N) (img_height(N) == null_flag) +# define is_dp_running(N) (img_depth(N) == null_flag) -#endif /* IMAGE_H */ +#endif diff --git a/Build/source/texk/web2c/luatexdir/image/pdftoepdf.h b/Build/source/texk/web2c/luatexdir/image/pdftoepdf.h index 203f85c5c31..12d15121017 100644 --- a/Build/source/texk/web2c/luatexdir/image/pdftoepdf.h +++ b/Build/source/texk/web2c/luatexdir/image/pdftoepdf.h @@ -24,7 +24,9 @@ # include "image.h" -void read_pdf_info(image_dict *, int, int, img_readtype_e); +void read_pdf_info(image_dict *); +void flush_pdf_info(image_dict *); +/* flush_pdfstream_info(image_dict *); */ /* somehow doesn't work due to xfree macro */ void unrefPdfDocument(char *); void unrefMemStreamPdfDocument(char *); void write_epdf(PDF, image_dict *); 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() { diff --git a/Build/source/texk/web2c/luatexdir/image/writeimg.h b/Build/source/texk/web2c/luatexdir/image/writeimg.h index 13f2d3642a5..46c42d2657e 100644 --- a/Build/source/texk/web2c/luatexdir/image/writeimg.h +++ b/Build/source/texk/web2c/luatexdir/image/writeimg.h @@ -18,11 +18,10 @@ You should have received a copy of the GNU General Public License along with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */ - #ifndef WRITEIMG_H # define WRITEIMG_H -# include "dvi/dvigen.h" /* for scaled_whd only */ +# include "dvi/dvigen.h" # include "image.h" # include "pdf/pdfpage.h" @@ -31,10 +30,9 @@ idict_entry *idict_array; void new_img_pdfstream_struct(image_dict *); image *new_image(void); -/*void init_image_dict(image_dict *);*/ image_dict *new_image_dict(void); void free_image_dict(image_dict * p); -void read_img(PDF, image_dict *, int, int); +void read_img(image_dict * p); void scan_pdfximage(PDF pdf); void scan_pdfrefximage(PDF pdf); scaled_whd tex_scale(scaled_whd nat, scaled_whd tex); @@ -50,4 +48,4 @@ scaled_whd scan_alt_rule(void); size_t read_file_to_buf(PDF pdf, FILE * f, size_t len); void pdf_dict_add_img_filename(PDF pdf, image_dict * idict); -#endif /* WRITEIMG_H */ +#endif diff --git a/Build/source/texk/web2c/luatexdir/image/writeimg.w b/Build/source/texk/web2c/luatexdir/image/writeimg.w index ff667cfe62e..c002b56dca9 100644 --- a/Build/source/texk/web2c/luatexdir/image/writeimg.w +++ b/Build/source/texk/web2c/luatexdir/image/writeimg.w @@ -21,8 +21,6 @@ @* Image inclusion. @ @c - - #include "ptexlib.h" #include <assert.h> #include <kpathsea/c-auto.h> @@ -40,78 +38,63 @@ @* Patch ImageTypeDetection 2003/02/08 by Heiko Oberdiek. - Function |readimage| performs some basic initializations. - Then it looks at the file extension to determine the - image type and calls specific code/functions. - - The main disadvantage is that standard file extensions - have to be used, otherwise pdfTeX is not able to detect - the correct image type. +Function |readimage| performs some basic initializations. Then it looks at the +file extension to determine the image type and calls specific code/functions. The +main disadvantage is that standard file extensions have to be used, otherwise +pdfTeX is not able to detect the correct image type. The patch now looks at the +file header first regardless of the file extension. This is implemented in +function |check_type_by_header|. If this check fails, the traditional test of +standard file extension is tried, done in function |check_type_by_extension|. - The patch now looks at the file header first regardless of - the file extension. This is implemented in function - |check_type_by_header|. If this check fails, the traditional - test of standard file extension is tried, done in function - |check_type_by_extension|. +Magic headers: - Magic headers: +* "PNG (Portable Network Graphics) Specification", Version 1.2 + (http://www.libpng.org/pub/png): - * "PNG (Portable Network Graphics) Specification", Version 1.2 - (http://www.libpng.org/pub/png): + 3.1. PNG file signature - 3.1. PNG file signature + The first eight bytes of a PNG file always contain the following + (decimal) values: 137 80 78 71 13 10 26 10 - The first eight bytes of a PNG file always contain the following - (decimal) values: +Translation to C: |"\x89PNG\r\n\x1A\n"| - 137 80 78 71 13 10 26 10 +* "JPEG File Interchange Format", Version 1.02: - Translation to C: |"\x89PNG\r\n\x1A\n"| + * you can identify a JFIF file by looking for the following sequence: + X'FF', SOI X'FF', APP0, <2 bytes to be skipped>, "JFIF", X'00'. - * "JPEG File Interchange Format", Version 1.02: +Function |check_type_by_header| only looks at the first two bytes: |"\xFF\xD8"| - o you can identify a JFIF file by looking for the following - sequence: X'FF', SOI X'FF', APP0, <2 bytes to be skipped>, - "JFIF", X'00'. +* ISO/IEC JTC 1/SC 29/WG 1 + (ITU-T SG8) + Coding of Still Pictures + Title: 14492 FCD + Source: JBIG Committee + Project: JTC 1.29.10 + Status: Final Committee Draft - Function |check_type_by_header| only looks at the first two bytes: - |"\xFF\xD8"| + D.4.1, ID string - * ISO/IEC JTC 1/SC 29/WG 1 - (ITU-T SG8) - Coding of Still Pictures - Title: 14492 FCD - Source: JBIG Committee - Project: JTC 1.29.10 - Status: Final Committee Draft + This is an 8-byte sequence containing 0x97 0x4A 0x42 0x32 0x0D 0x0A 0x1A 0x0A. - D.4.1, ID string +* "PDF Reference", third edition: - This is an 8-byte sequence containing 0x97 0x4A 0x42 0x32 0x0D 0x0A - 0x1A 0x0A. + * The first line should contain \%PDF-1.0 -- \%PDF-1.4 (section 3.4.1 "File Header"). + * The "implementation notes" say: - * "PDF Reference", third edition: + 3.4.1, File Header + 12. Acrobat viewers require only that the header appear somewhere within the + first 1024 bytes of the file. + 13. Acrobat viewers will also accept a header of the form \%!PS-Adobe-N.n PDF-M.m - * The first line should contain "\%PDF-1.0" until "\%PDF-1.4" - (section 3.4.1 "File Header"). - * The "implementation notes" say: +The check in function |check_type_by_header| only implements the first issue. The +implementation notes are not considered. Therefore files with garbage at start of +file must have the standard extension. - 3.4.1, File Header - 12. Acrobat viewers require only that the header appear - somewhere within the first 1024 bytes of the file. - 13. Acrobat viewers will also accept a header of the form - \%!PS-Adobe-N.n PDF-M.m - - The check in function |check_type_by_header| only implements - the first issue. The implementation notes are not considered. - Therefore files with garbage at start of file must have the - standard extension. - - Functions |check_type_by_header| and |check_type_by_extension|: - |img_type(img)| is set to |IMG_TYPE_NONE| by |new_image_dict()|. - Both functions try to detect a type and set |img_type(img)|. - Thus a value other than |IMG_TYPE_NONE| indicates that a - type has been found. +Functions |check_type_by_header| and |check_type_by_extension|: |img_type(img)| +is set to |IMG_TYPE_NONE| by |new_image_dict()|. Both functions try to detect a +type and set |img_type(img)|. Thus a value other than |IMG_TYPE_NONE| indicates +that a type has been found. @c #define HEADER_JPG "\xFF\xD8" @@ -121,8 +104,7 @@ #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 */ - +#define LEN_PDF_MEMSTREAM 21 /* see epdf.h */ static void check_type_by_header(image_dict * idict) { @@ -132,17 +114,13 @@ static void check_type_by_header(image_dict * idict) char prefix[LEN_PDF_MEMSTREAM+1]; assert(idict != NULL); - if (img_type(idict) != IMG_TYPE_NONE) /* nothing to do */ + if (img_type(idict) != IMG_TYPE_NONE) return; - - /* read the header */ - /* Like */ - /* file = xfopen(img_filepath(idict), FOPEN_RBIN_MODE);*/ - /* but we also check for a memstream object */ + /* here we read the and 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) */ + /* check the prefix of img_filepath(idict) */ for (i = 0; (unsigned) i < LEN_PDF_MEMSTREAM; i++) { prefix[i] = (char) (img_filepath(idict)[i]); } @@ -158,7 +136,7 @@ static void check_type_by_header(image_dict * idict) for (i = 0; (unsigned) i < MAX_HEADER; i++) { header[i] = (char) xgetc(file); if (feof(file)) - luatex_fail("reading image file failed"); + normal_error("pdf backend","reading image file failed"); } xfclose(file, img_filepath(idict)); /* tests */ @@ -178,8 +156,8 @@ static void check_type_by_header(image_dict * idict) static void check_type_by_extension(image_dict * idict) { char *image_suffix; - - assert(idict != NULL); + if (idict != NULL) + return; if (img_type(idict) != IMG_TYPE_NONE) /* nothing to do */ return; /* tests */ @@ -209,28 +187,22 @@ void new_img_pdfstream_struct(image_dict * p) } @ @c -static void init_image(image * p) +image *new_image(void) { - assert(p != NULL); + image *p = xtalloc(1, image); set_wd_running(p); set_ht_running(p); set_dp_running(p); img_transform(p) = 0; img_dict(p) = NULL; img_dictref(p) = LUA_NOREF; -} - -@ @c -image *new_image(void) -{ - image *p = xtalloc(1, image); - init_image(p); return p; } @ @c -static void init_image_dict(image_dict * p) +image_dict *new_image_dict(void) { + image_dict *p = xtalloc(1, image_dict); assert(p != NULL); memset(p, 0, sizeof(image_dict)); set_wd_running(p); @@ -243,14 +215,11 @@ static void init_image_dict(image_dict * p) img_unset_bbox(p); img_unset_group(p); img_state(p) = DICT_NEW; - img_index(p) = -1; /* -1 = unused, used count from 0 */ -} - -@ @c -image_dict *new_image_dict(void) -{ - image_dict *p = xtalloc(1, image_dict); - init_image_dict(p); + img_index(p) = -1; /* -1 = unused, used count from 0 */ + img_luaref(p) = 0; + img_errorlevel(p) = pdf_inclusion_errorlevel; + fix_pdf_minorversion(static_pdf); + img_pdfminorversion(p) = pdf_minor_version; return p; } @@ -271,31 +240,33 @@ 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; - case IMG_TYPE_PNG: /* assuming |IMG_CLOSEINBETWEEN| */ - assert(img_png_ptr(p) == NULL); - break; - case IMG_TYPE_JPG: /* assuming |IMG_CLOSEINBETWEEN| */ - assert(img_jpg_ptr(p) == NULL); - break; - case IMG_TYPE_JP2: /* */ - assert(img_jp2_ptr(p) == NULL); - break; - case IMG_TYPE_JBIG2: /* todo: writejbig2.w cleanup */ - break; - case IMG_TYPE_PDFSTREAM: - if (img_pdfstream_ptr(p) != NULL) { - xfree(img_pdfstream_stream(p)); - xfree(img_pdfstream_ptr(p)); - } - break; - case IMG_TYPE_NONE: - break; - default: - assert(0); + case IMG_TYPE_PDFMEMSTREAM: + case IMG_TYPE_PDF: + flush_pdf_info(p); + break; + case IMG_TYPE_PNG: + flush_png_info(p); + break; + case IMG_TYPE_JPG: + flush_jpg_info(p); + break; + case IMG_TYPE_JP2: + flush_jp2_info(p); + break; + case IMG_TYPE_JBIG2: + flush_jbig2_info(p); + break; + case IMG_TYPE_PDFSTREAM: + /* flush_pdfstream_info(p); */ + if (img_pdfstream_ptr(p) != NULL) { + xfree(img_pdfstream_stream(p)); + xfree(img_pdfstream_ptr(p)); + } + break; + case IMG_TYPE_NONE: + break; + default: + assert(0); } free_dict_strings(p); assert(img_file(p) == NULL); @@ -303,14 +274,13 @@ void free_image_dict(image_dict * p) } @ @c -void read_img(PDF pdf, - image_dict * idict, int minor_version, int inclusion_errorlevel) +void read_img(image_dict * idict) { char *filepath = NULL; int callback_id; assert(idict != NULL); if (img_filename(idict) == NULL) { - luatex_fail("image file name missing"); + normal_error("pdf backend","image file name missing"); } callback_id = callback_defined(find_image_file_callback); if (img_filepath(idict) == NULL) { @@ -324,7 +294,7 @@ void read_img(PDF pdf, img_filepath(idict) = kpse_find_file(img_filename(idict), kpse_tex_format, true); } if (img_filepath(idict) == NULL) { - luatex_fail("cannot find image file '%s'", img_filename(idict)); + formatted_error("pdf backend","cannot find image file '%s'", img_filename(idict)); } } recorder_record_input(img_filename(idict)); @@ -333,31 +303,24 @@ 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, - IMG_CLOSEINBETWEEN); - break; - case IMG_TYPE_PNG: - read_png_info(idict, IMG_CLOSEINBETWEEN); - break; - case IMG_TYPE_JPG: - read_jpg_info(pdf, idict, IMG_CLOSEINBETWEEN); - break; - case IMG_TYPE_JP2: - read_jp2_info(idict, IMG_CLOSEINBETWEEN); - break; - case IMG_TYPE_JBIG2: - if (minor_version < 4) { - luatex_fail - ("JBIG2 images only possible with at least PDF 1.4; you are generating PDF 1.%i", - (int) minor_version); - } - read_jbig2_info(idict); - break; - default: - luatex_fail("internal error: unknown image type (2)"); + case IMG_TYPE_PDFMEMSTREAM: + case IMG_TYPE_PDF: + read_pdf_info(idict); + break; + case IMG_TYPE_PNG: + read_png_info(idict); + break; + case IMG_TYPE_JPG: + read_jpg_info(idict); + break; + case IMG_TYPE_JP2: + read_jp2_info(idict); + break; + case IMG_TYPE_JBIG2: + read_jbig2_info(idict); + break; + default: + normal_error("pdf backend","internal error: unknown image type"); } cur_file_name = NULL; if (img_state(idict) < DICT_FILESCANNED) @@ -365,17 +328,14 @@ void read_img(PDF pdf, } @ @c -static image_dict *read_image(PDF pdf, char *file_name, int page_num, - char *page_name, int colorspace, - int page_box, int minor_version, - int inclusion_errorlevel) +static image_dict *read_image(char *file_name, int page_num, char *page_name, int colorspace, int page_box) { image *a = new_image(); image_dict *idict = img_dict(a) = new_image_dict(); - pdf->ximage_count++; - img_objnum(idict) = pdf_create_obj(pdf, obj_type_ximage, pdf->ximage_count); - img_index(idict) = pdf->ximage_count; - set_obj_data_ptr(pdf, img_objnum(idict), img_index(idict)); + static_pdf->ximage_count++; + img_objnum(idict) = pdf_create_obj(static_pdf, obj_type_ximage, static_pdf->ximage_count); + img_index(idict) = static_pdf->ximage_count; + set_obj_data_ptr(static_pdf, img_objnum(idict), img_index(idict)); idict_to_array(idict); img_colorspace(idict) = colorspace; img_pagenum(idict) = page_num; @@ -384,7 +344,7 @@ static image_dict *read_image(PDF pdf, char *file_name, int page_num, cur_file_name = file_name; img_filename(idict) = file_name; img_pagebox(idict) = page_box; - read_img(pdf, idict, minor_version, inclusion_errorlevel); + read_img(idict); return idict; } @@ -402,11 +362,12 @@ static pdfboxspec_e scan_pdf_box_spec(void) return PDF_BOX_SPEC_TRIM; else if (scan_keyword("artbox")) return PDF_BOX_SPEC_ART; - return PDF_BOX_SPEC_NONE; + else + return PDF_BOX_SPEC_NONE; } @ @c -void scan_pdfximage(PDF pdf) +void scan_pdfximage(PDF pdf) /* static_pdf */ { scaled_whd alt_rule; image_dict *idict; @@ -414,12 +375,12 @@ void scan_pdfximage(PDF pdf) char *named = NULL, *attr = NULL, *file_name = NULL; alt_rule = scan_alt_rule(); /* scans |<rule spec>| to |alt_rule| */ if (scan_keyword("attr")) { - scan_pdf_ext_toks(); + scan_toks(false, true); attr = tokenlist_to_cstring(def_ref, true, NULL); delete_token_ref(def_ref); } if (scan_keyword("named")) { - scan_pdf_ext_toks(); + scan_toks(false, true); named = tokenlist_to_cstring(def_ref, true, NULL); delete_token_ref(def_ref); page = 0; @@ -437,13 +398,11 @@ void scan_pdfximage(PDF pdf) if (pagebox == PDF_BOX_SPEC_NONE) pagebox = PDF_BOX_SPEC_CROP; } - scan_pdf_ext_toks(); + scan_toks(false, true); file_name = tokenlist_to_cstring(def_ref, true, NULL); assert(file_name != NULL); delete_token_ref(def_ref); - idict = - read_image(pdf, file_name, page, named, colorspace, pagebox, - pdf_minor_version, pdf_inclusion_errorlevel); + idict = read_image(file_name, page, named, colorspace, pagebox); img_attr(idict) = attr; img_dimen(idict) = alt_rule; img_transform(idict) = transform; @@ -452,7 +411,7 @@ void scan_pdfximage(PDF pdf) } @ @c -#define tail cur_list.tail_field +#define tail cur_list.tail_field void scan_pdfrefximage(PDF pdf) { @@ -559,11 +518,11 @@ scaled_whd scale_img(image_dict * idict, scaled_whd alt_rule, int transform) xr = img_xres(idict); yr = img_yres(idict); if (x <= 0 || y <= 0 || xr < 0 || yr < 0) - luatex_fail("ext1: invalid image dimensions"); + normal_error("pdf backend","invalid image dimensions"); if (xr > 65535 || yr > 65535) { xr = 0; yr = 0; - luatex_warn("ext1: too large image resolution ignored"); + normal_warning("pdf backend","too large image resolution ignored"); } if (((transform - img_rotation(idict)) & 1) == 1) { tmp = x; @@ -622,7 +581,7 @@ void write_img(PDF pdf, image_dict * idict) write_pdfstream(pdf, idict); break; default: - luatex_fail("internal error: unknown image type (1)"); + normal_error("pdf backend","internal error: unknown image type"); } report_stop_file(filetype_image); if (img_type(idict) == IMG_TYPE_PNG) { @@ -645,7 +604,7 @@ void pdf_write_image(PDF pdf, int n) void check_pdfstream_dict(image_dict * idict) { if (!img_is_bbox(idict)) - luatex_fail("image.stream: no bbox given"); + normal_error("pdf backend","image.stream: no bbox given"); if (img_state(idict) < DICT_FILESCANNED) img_state(idict) = DICT_FILESCANNED; } @@ -679,7 +638,6 @@ void write_pdfstream(PDF pdf, image_dict * idict) } @ @c -/* define |idict_ptr|, |idict_array|, and |idict_limit| */ idict_entry *idict_ptr, *idict_array = NULL; size_t idict_limit; @@ -721,6 +679,8 @@ void pdf_dict_add_img_filename(PDF pdf, image_dict * idict) } } +/* hh: why store images in the format ... let's get rid of this */ + @ To allow the use of box resources inside saved boxes in -ini mode, the information in the array has to be (un)dumped with the format. The next two routines take care of that. @@ -731,8 +691,7 @@ the split in two separate runs. There was only one problem remaining: The pdfversion and pdfinclusionerrorlevel can have changed inbetween the call to -|readimage()| and dump time. That is why they are passed as arguments -to undumpimagemeta once more. +|readimage()| and dump time. some of the dumped values are really type int, not integer, but since the macro falls back to |generic_dump| anyway, that @@ -746,121 +705,6 @@ does not matter. by the bytes. The trailing \.{\\0} is dumped as well, because that makes the code simpler. -@c -#define dumpcharptr(a) \ - do { \ - int x; \ - if (a!=NULL) { \ - x = (int)strlen(a)+1; \ - dumpinteger(x); dump_things(*a, x); \ - } else { \ - x = 0; dumpinteger(x); \ - } \ - } while (0) - -#define undumpcharptr(s) \ - do { \ - int x; \ - char *a; \ - undumpinteger (x); \ - if (x>0) { \ - a = xmalloc((unsigned)x); \ - undump_things(*a,x); \ - s = a ; \ - } else { s = NULL; } \ - } while (0) - -@ @c -void dumpimagemeta(void) -{ - int cur_index, i; - image_dict *idict; - - i = (int) idict_limit; - dumpinteger(i); - cur_index = (int) (idict_ptr - idict_array); - dumpinteger(cur_index); - - for (i = 1; i < cur_index; i++) { - idict = idict_array[i]; - assert(idict != NULL); - dumpcharptr(img_filename(idict)); - dumpinteger(img_type(idict)); - dumpinteger(img_procset(idict)); - dumpinteger(img_xsize(idict)); - dumpinteger(img_ysize(idict)); - dumpinteger(img_xres(idict)); - dumpinteger(img_yres(idict)); - dumpinteger(img_totalpages(idict)); - dumpinteger(img_colorspace(idict)); - - /* 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)|| (img_type(idict) == IMG_TYPE_PDFMEMSTREAM)) { - dumpinteger(img_pagebox(idict)); - dumpinteger(img_pagenum(idict)); - } else if (img_type(idict) == IMG_TYPE_JBIG2) { - dumpinteger(img_pagenum(idict)); - } - - } -} - -@ @c -void undumpimagemeta(PDF pdf, int pdfversion, int pdfinclusionerrorlevel) -{ - int cur_index, i; - image_dict *idict; - - assert(pdf != NULL); - undumpinteger(i); - idict_limit = (size_t) i; - - idict_array = xtalloc(idict_limit, idict_entry); - undumpinteger(cur_index); - idict_ptr = idict_array + cur_index; - - for (i = 1; i < cur_index; i++) { - idict = new_image_dict(); - assert(idict != NULL); - assert(img_index(idict) == -1); - idict_to_array(idict); - undumpcharptr(img_filename(idict)); - undumpinteger(img_type(idict)); - undumpinteger(img_procset(idict)); - undumpinteger(img_xsize(idict)); - undumpinteger(img_ysize(idict)); - undumpinteger(img_xres(idict)); - undumpinteger(img_yres(idict)); - undumpinteger(img_totalpages(idict)); - undumpinteger(img_colorspace(idict)); - - switch (img_type(idict)) { - case IMG_TYPE_PDFMEMSTREAM: - case IMG_TYPE_PDF: - undumpinteger(img_pagebox(idict)); - undumpinteger(img_pagenum(idict)); - break; - case IMG_TYPE_PNG: - case IMG_TYPE_JPG: - case IMG_TYPE_JP2: - break; - case IMG_TYPE_JBIG2: - if (pdfversion < 4) { - luatex_fail - ("JBIG2 images only possible with at least PDF 1.4; you are generating PDF 1.%i", - (int) pdfversion); - } - undumpinteger(img_pagenum(idict)); - break; - default: - luatex_fail("unknown type of image"); - } - read_img(pdf, idict, pdfversion, pdfinclusionerrorlevel); - } -} - @ scan rule spec to |alt_rule| @c scaled_whd scan_alt_rule(void) diff --git a/Build/source/texk/web2c/luatexdir/image/writejbig2.h b/Build/source/texk/web2c/luatexdir/image/writejbig2.h index 95019b6c81b..e2c907bf687 100644 --- a/Build/source/texk/web2c/luatexdir/image/writejbig2.h +++ b/Build/source/texk/web2c/luatexdir/image/writejbig2.h @@ -18,7 +18,6 @@ You should have received a copy of the GNU General Public License along with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */ - #ifndef WRITEJBIG2_H # define WRITEJBIG2_H @@ -27,8 +26,10 @@ unsigned int read2bytes(FILE * f); unsigned int read4bytes(FILE * f); -void flush_jbig2_page0_objects(PDF); +boolean supported_jbig2(image_dict *); void read_jbig2_info(image_dict *); +void flush_jbig2_info(image_dict *); void write_jbig2(PDF, image_dict *); +void flush_jbig2_page0_objects(PDF); -#endif /* WRITEJBIG"_H */ +#endif diff --git a/Build/source/texk/web2c/luatexdir/image/writejbig2.w b/Build/source/texk/web2c/luatexdir/image/writejbig2.w index 7b676fb6e87..d1ed0a408d4 100644 --- a/Build/source/texk/web2c/luatexdir/image/writejbig2.w +++ b/Build/source/texk/web2c/luatexdir/image/writejbig2.w @@ -20,7 +20,6 @@ % with LuaTeX; if not, see <http://www.gnu.org/licenses/>. @ - This is experimental JBIG2 image support to pdfTeX. JBIG2 image decoding is part of Adobe PDF-1.4, and requires Acroread 5.0 or later. @@ -80,8 +79,6 @@ object exists, reference it. Else create fresh one. 09 Dec. 2002: JBIG2 seg. page numbers > 0 are now set to 1, see PDF Ref. @ @c - - #undef DEBUG #include "ptexlib.h" @@ -120,7 +117,7 @@ typedef enum { INITIAL, HAVEINFO, WRITEPDF } PHASE; typedef struct _LITEM { struct _LITEM *prev; struct _LITEM *next; - void *d; /* data */ + void *d; /* data */ } LITEM; typedef struct _LIST { @@ -133,26 +130,26 @@ typedef struct _SEGINFO { unsigned long segnum; boolean isrefered; boolean refers; - unsigned int seghdrflags; /* set by readseghdr() */ - boolean pageassocsizeflag; /* set by readseghdr() */ - unsigned int reftosegcount; /* set by readseghdr() */ - unsigned int countofrefered; /* set by readseghdr() */ - unsigned int fieldlen; /* set by readseghdr() */ - unsigned int segnumwidth; /* set by readseghdr() */ - long segpage; /* set by readseghdr() */ - unsigned long segdatalen; /* set by readseghdr() */ - unsigned long hdrstart; /* set by readseghdr() */ - unsigned long hdrend; /* set by readseghdr() */ + unsigned int seghdrflags; /* set by readseghdr() */ + boolean pageassocsizeflag; /* set by readseghdr() */ + unsigned int reftosegcount; /* set by readseghdr() */ + unsigned int countofrefered; /* set by readseghdr() */ + unsigned int fieldlen; /* set by readseghdr() */ + unsigned int segnumwidth; /* set by readseghdr() */ + long segpage; /* set by readseghdr() */ + unsigned long segdatalen; /* set by readseghdr() */ + unsigned long hdrstart; /* set by readseghdr() */ + unsigned long hdrend; /* set by readseghdr() */ unsigned long datastart; unsigned long dataend; - boolean endofstripeflag; /* set by checkseghdrflags() */ - boolean endofpageflag; /* set by checkseghdrflags() */ - boolean pageinfoflag; /* set by checkseghdrflags() */ - boolean endoffileflag; /* set by checkseghdrflags() */ + boolean endofstripeflag; /* set by checkseghdrflags() */ + boolean endofpageflag; /* set by checkseghdrflags() */ + boolean pageinfoflag; /* set by checkseghdrflags() */ + boolean endoffileflag; /* set by checkseghdrflags() */ } SEGINFO; typedef struct _PAGEINFO { - LIST segments; /* segments associated with page */ + LIST segments; /* segments associated with page */ unsigned long pagenum; unsigned int width; unsigned int height; @@ -167,12 +164,12 @@ typedef struct _FILEINFO { FILE *file; char *filepath; long filesize; - LIST pages; /* not including page0 */ + LIST pages; /* not including page0 */ LIST page0; - unsigned int filehdrflags; /* set by readfilehdr() */ - boolean sequentialaccess; /* set by readfilehdr() */ - unsigned long numofpages; /* set by readfilehdr() */ - unsigned long streamstart; /* set by |get_jbig2_info()| */ + unsigned int filehdrflags; /* set by readfilehdr() */ + boolean sequentialaccess; /* set by readfilehdr() */ + unsigned long numofpages; /* set by readfilehdr() */ + unsigned long streamstart; /* set by |get_jbig2_info()| */ unsigned long pdfpage0objnum; PHASE phase; } FILEINFO; @@ -183,22 +180,19 @@ static struct avl_table *file_tree = NULL; static int comp_file_entry(const void *pa, const void *pb, void *p) { (void) p; - return strcmp(((const FILEINFO *) pa)->filepath, - ((const FILEINFO *) pb)->filepath); + return strcmp(((const FILEINFO *) pa)->filepath,((const FILEINFO *) pb)->filepath); } static int comp_page_entry(const void *pa, const void *pb, void *p) { (void) p; - return (int) (((const PAGEINFO *) pa)->pagenum - - ((const PAGEINFO *) pb)->pagenum); + return (int) (((const PAGEINFO *) pa)->pagenum - ((const PAGEINFO *) pb)->pagenum); } static int comp_segment_entry(const void *pa, const void *pb, void *p) { (void) p; - return (int) (((const SEGINFO *) pa)->segnum - - ((const SEGINFO *) pb)->segnum); + return (int) (((const SEGINFO *) pa)->segnum - ((const SEGINFO *) pb)->segnum); } @ @c @@ -207,9 +201,9 @@ static int ygetc(FILE * stream) int c = getc(stream); if (c < 0) { if (c == EOF) - luatex_fail("getc() failed; premature end of JBIG2 image file"); + normal_error("readjbig2","premature end file"); else - luatex_fail("getc() failed (can't happen)"); + normal_error("readjbig2","can't happen"); } return c; } @@ -382,8 +376,7 @@ static void readfilehdr(FILEINFO * fip) xfseek(fip->file, 0, SEEK_SET, fip->filepath); for (i = 0; i < 8; i++) if (ygetc(fip->file) != jbig2_id[i]) - luatex_fail - ("readfilehdr(): reading JBIG2 image file failed: ID string missing"); + normal_error("readjbig2","ID string missing"); /* Annex D.4.2 File header flags */ fip->filehdrflags = (unsigned int) ygetc(fip->file); fip->sequentialaccess = (fip->filehdrflags & 0x01) ? true : false; @@ -407,41 +400,40 @@ static void checkseghdrflags(SEGINFO * sip) sip->endoffileflag = false; /* 7.3 Segment types */ switch (sip->seghdrflags & 0x3f) { - case M_SymbolDictionary: - case M_IntermediateTextRegion: - case M_ImmediateTextRegion: - case M_ImmediateLosslessTextRegion: - case M_PatternDictionary: - case M_IntermediateHalftoneRegion: - case M_ImmediateHalftoneRegion: - case M_ImmediateLosslessHalftoneRegion: - case M_IntermediateGenericRegion: - case M_ImmediateGenericRegion: - case M_ImmediateLosslessGenericRegion: - case M_IntermediateGenericRefinementRegion: - case M_ImmediateGenericRefinementRegion: - case M_ImmediateLosslessGenericRefinementRegion: - break; - case M_PageInformation: - sip->pageinfoflag = true; - break; - case M_EndOfPage: - sip->endofpageflag = true; - break; - case M_EndOfStripe: - sip->endofstripeflag = true; - break; - case M_EndOfFile: - sip->endoffileflag = true; - break; - case M_Profiles: - case M_Tables: - case M_Extension: - break; - default: - luatex_fail - ("checkseghdrflags(): unknown segment type in JBIG2 image file"); - break; + case M_SymbolDictionary: + case M_IntermediateTextRegion: + case M_ImmediateTextRegion: + case M_ImmediateLosslessTextRegion: + case M_PatternDictionary: + case M_IntermediateHalftoneRegion: + case M_ImmediateHalftoneRegion: + case M_ImmediateLosslessHalftoneRegion: + case M_IntermediateGenericRegion: + case M_ImmediateGenericRegion: + case M_ImmediateLosslessGenericRegion: + case M_IntermediateGenericRefinementRegion: + case M_ImmediateGenericRefinementRegion: + case M_ImmediateLosslessGenericRefinementRegion: + break; + case M_PageInformation: + sip->pageinfoflag = true; + break; + case M_EndOfPage: + sip->endofpageflag = true; + break; + case M_EndOfStripe: + sip->endofstripeflag = true; + break; + case M_EndOfFile: + sip->endoffileflag = true; + break; + case M_Profiles: + case M_Tables: + case M_Extension: + break; + default: + normal_error("readjbig2","unknown segment type file"); + break; } } @@ -454,19 +446,10 @@ static boolean readseghdr(FILEINFO * fip, SEGINFO * sip) sip->hdrstart = xftell(fip->file, fip->filepath); if (fip->sequentialaccess && sip->hdrstart == (unsigned) fip->filesize) return false; /* no endoffileflag is ok for sequentialaccess */ -#ifdef DEBUG - printf("\nhdrstart %d\n", sip->hdrstart); -#endif /* 7.2.2 Segment number */ sip->segnum = read4bytes(fip->file); -#ifdef DEBUG - printf(" segnum %d\n", sip->segnum); -#endif /* 7.2.3 Segment header flags */ sip->seghdrflags = (unsigned int) ygetc(fip->file); -#ifdef DEBUG - printf(" hdrflags %d\n", sip->seghdrflags & 0x3f); -#endif checkseghdrflags(sip); if (fip->sequentialaccess && sip->endoffileflag) /* accept shorter segment, */ return true; /* makes it compliant with Example 3.4 of PDFRef. 5th ed. */ @@ -489,15 +472,15 @@ static boolean readseghdr(FILEINFO * fip, SEGINFO * sip) sip->segnumwidth = 4; for (i = 0; i < sip->countofrefered; i++) { switch (sip->segnumwidth) { - case 1: - (void) ygetc(fip->file); - break; - case 2: - (void) read2bytes(fip->file); - break; - case 4: - (void) read4bytes(fip->file); - break; + case 1: + (void) ygetc(fip->file); + break; + case 2: + (void) read2bytes(fip->file); + break; + case 4: + (void) read4bytes(fip->file); + break; } } /* 7.2.6 Segment page association */ @@ -543,22 +526,22 @@ static void writeseghdr(PDF pdf, FILEINFO * fip, SEGINFO * sip) /* 7.2.5 Referred-to segment numbers */ for (i = 0; i < sip->countofrefered; i++) { switch (sip->segnumwidth) { - case 1: - referedseg = (unsigned long) ygetc(fip->file); - pdf_out(pdf, referedseg); - break; - case 2: - referedseg = read2bytes(fip->file); - pdf_out(pdf, (referedseg >> 8) & 0xff); - pdf_out(pdf, referedseg & 0xff); - break; - case 4: - referedseg = read4bytes(fip->file); - pdf_out(pdf, (referedseg >> 24) & 0xff); - pdf_out(pdf, (referedseg >> 16) & 0xff); - pdf_out(pdf, (referedseg >> 8) & 0xff); - pdf_out(pdf, referedseg & 0xff); - break; + case 1: + referedseg = (unsigned long) ygetc(fip->file); + pdf_out(pdf, referedseg); + break; + case 2: + referedseg = read2bytes(fip->file); + pdf_out(pdf, (referedseg >> 8) & 0xff); + pdf_out(pdf, referedseg & 0xff); + break; + case 4: + referedseg = read4bytes(fip->file); + pdf_out(pdf, (referedseg >> 24) & 0xff); + pdf_out(pdf, (referedseg >> 16) & 0xff); + pdf_out(pdf, (referedseg >> 8) & 0xff); + pdf_out(pdf, referedseg & 0xff); + break; } if (fip->page0.last != NULL && !sip->refers) markpage0seg(fip, referedseg); @@ -592,15 +575,15 @@ static void checkseghdr(FILEINFO * fip, SEGINFO * sip) /* 7.2.5 Referred-to segment numbers */ for (i = 0; i < sip->countofrefered; i++) { switch (sip->segnumwidth) { - case 1: - referedseg = (unsigned long) ygetc(fip->file); - break; - case 2: - referedseg = read2bytes(fip->file); - break; - case 4: - referedseg = read4bytes(fip->file); - break; + case 1: + referedseg = (unsigned long) ygetc(fip->file); + break; + case 2: + referedseg = read2bytes(fip->file); + break; + case 4: + referedseg = read4bytes(fip->file); + break; } if (!sip->refers) markpage0seg(fip, referedseg); @@ -620,8 +603,8 @@ static void checkseghdr(FILEINFO * fip, SEGINFO * sip) static unsigned long findstreamstart(FILEINFO * fip) { SEGINFO tmp; - assert(!fip->sequentialaccess); /* D.2 Random-access organisation */ - do /* find random-access stream start */ + assert(!fip->sequentialaccess); /* D.2 Random-access organisation */ + do /* find random-access stream start */ (void) readseghdr(fip, &tmp); while (!tmp.endoffileflag); fip->streamstart = tmp.hdrend; @@ -632,8 +615,8 @@ static unsigned long findstreamstart(FILEINFO * fip) @ @c static void rd_jbig2_info(FILEINFO * fip) { - unsigned long seekdist = 0; /* for sequential-access only */ - unsigned long streampos = 0; /* for random-access only */ + unsigned long seekdist = 0; /* for sequential-access only */ + unsigned long streampos = 0; /* for random-access only */ unsigned long currentpage = 0; boolean sipavail = false; PAGEINFO *pip; @@ -732,16 +715,14 @@ static void wr_jbig2(PDF pdf, image_dict * idict, FILEINFO * fip, pdf_dict_add_int(pdf, "Height", pip->height); pdf_dict_add_name(pdf, "ColorSpace", "DeviceGray"); pdf_dict_add_int(pdf, "BitsPerComponent", 1); - pdf_dict_add_int(pdf, "Length", - getstreamlen(pip->segments.first, true)); + pdf_dict_add_int(pdf, "Length", getstreamlen(pip->segments.first, true)); pdf_add_name(pdf, "Filter"); pdf_begin_array(pdf); pdf_add_name(pdf, "JBIG2Decode"); pdf_end_array(pdf); if (fip->page0.last != NULL) { if (fip->pdfpage0objnum == 0) { - fip->pdfpage0objnum = - (unsigned long) pdf_create_obj(pdf, obj_type_others, 0); + fip->pdfpage0objnum = (unsigned long) pdf_create_obj(pdf, obj_type_others, 0); } pdf_add_name(pdf, "DecodeParms"); pdf_begin_array(pdf); @@ -757,8 +738,7 @@ static void wr_jbig2(PDF pdf, image_dict * idict, FILEINFO * fip, assert(pip != NULL); pdf_begin_obj(pdf, (int) fip->pdfpage0objnum, OBJSTM_NEVER); pdf_begin_dict(pdf); - pdf_dict_add_int(pdf, "Length", - getstreamlen(pip->segments.first, false)); + pdf_dict_add_int(pdf, "Length", getstreamlen(pip->segments.first, false)); pdf_end_dict(pdf); } pdf_begin_stream(pdf); @@ -780,28 +760,43 @@ static void wr_jbig2(PDF pdf, image_dict * idict, FILEINFO * fip, } @ @c +boolean supported_jbig2(image_dict * idict) +{ + if (img_pdfminorversion(idict) < 4) { + normal_error("readjbig2","you need to generate at least PDF 1.4"); + return false; + } else { + return true; + } +} + +@ @c +void flush_jbig2_info(image_dict * idict) +{ + /* todo */ +} + +@ @c void read_jbig2_info(image_dict * idict) { FILEINFO *fip, tmp; PAGEINFO *pip; - void **aa; - assert(idict != NULL); - img_type(idict) = IMG_TYPE_JBIG2; - if (img_pagenum(idict) < 1) - luatex_fail - ("read_jbig2_info(): page %d not in JBIG2 image file; page must be > 0", - (int) img_pagenum(idict)); + img_type(idict) = IMG_TYPE_JBIG2; /* already set probably, see other read_... */ + if (! supported_jbig2(idict)) { + /* already an error done */ + } + if (img_pagenum(idict) < 1) { + normal_error("readjbig2","page must be > 0"); + } if (file_tree == NULL) { file_tree = avl_create(comp_file_entry, NULL, &avl_xallocator); - assert(file_tree != NULL); } tmp.filepath = img_filepath(idict); fip = (FILEINFO *) avl_find(file_tree, &tmp); if (fip == NULL) { fip = new_fileinfo(); fip->filepath = xstrdup(img_filepath(idict)); - aa = avl_probe(file_tree, fip); - assert(aa != NULL); + avl_probe(file_tree, fip); } if (fip->phase == INITIAL) { rd_jbig2_info(fip); @@ -813,9 +808,9 @@ void read_jbig2_info(image_dict * idict) } } pip = find_pageinfo(&(fip->pages), (unsigned long) img_pagenum(idict)); - if (pip == NULL) - luatex_fail("read_jbig2_info(): page %d not found in JBIG2 image file", - (int) img_pagenum(idict)); + if (pip == NULL) { + formatted_error("readjbig2","page %d not found in image file",(int) img_pagenum(idict)); + } img_totalpages(idict) = (int) fip->numofpages; img_xsize(idict) = (int) pip->width; img_ysize(idict) = (int) pip->height; diff --git a/Build/source/texk/web2c/luatexdir/image/writejp2.h b/Build/source/texk/web2c/luatexdir/image/writejp2.h index ed9bbe47c72..aa8248fd25a 100644 --- a/Build/source/texk/web2c/luatexdir/image/writejp2.h +++ b/Build/source/texk/web2c/luatexdir/image/writejp2.h @@ -18,13 +18,13 @@ You should have received a copy of the GNU General Public License along with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */ - #ifndef WRITEJP2_H # define WRITEJP2_H # include "image.h" -void read_jp2_info(image_dict *, img_readtype_e); +void read_jp2_info(image_dict *); +void flush_jp2_info(image_dict *); void write_jp2(PDF, image_dict *); #endif /* WRITEJP2_H */ diff --git a/Build/source/texk/web2c/luatexdir/image/writejp2.w b/Build/source/texk/web2c/luatexdir/image/writejp2.w index 8ea537e9f75..cb317e11928 100644 --- a/Build/source/texk/web2c/luatexdir/image/writejp2.w +++ b/Build/source/texk/web2c/luatexdir/image/writejp2.w @@ -20,7 +20,6 @@ @ @c - @ Basic JPEG~2000 image support. Section and Table references below: Information technology --- JPEG~2000 image coding system: Core coding system. ISO/IEC 15444-1, Second edition, 2004-09-15, file |15444-1annexi.pdf|. @@ -66,8 +65,9 @@ static hdr_struct read_boxhdr(image_dict * idict) hdr.tbox = read4bytes(img_file(idict)); if (hdr.lbox == 1) hdr.lbox = read8bytes(img_file(idict)); - if (hdr.lbox == 0 && hdr.tbox != BOX_JP2C) - luatex_fail("reading JP2 image failed (LBox == 0)"); + if (hdr.lbox == 0 && hdr.tbox != BOX_JP2C) { + normal_error("readjp2","LBox == 0"); + } return hdr; } @@ -90,6 +90,7 @@ static void scan_ihdr(image_dict * idict) /* 1.5.3.7.1 Capture Resolution box */ /* 1.5.3.7.2 Default Display Resolution box */ + static void scan_resc_resd(image_dict * idict) { unsigned int vr_n, vr_d, hr_n, hr_d; @@ -108,6 +109,7 @@ static void scan_resc_resd(image_dict * idict) } /* 1.5.3.7 Resolution box (superbox) */ + static void scan_res(image_dict * idict, uint64_t epos_s) { hdr_struct hdr; @@ -118,25 +120,23 @@ static void scan_res(image_dict * idict, uint64_t epos_s) hdr = read_boxhdr(idict); epos = spos + hdr.lbox; switch (hdr.tbox) { - case (BOX_RESC): - /* arbitrarily: let BOX_RESD have precedence */ - if (img_xres(idict) == 0 && img_yres(idict) == 0) { + case (BOX_RESC): + /* arbitrarily: let BOX_RESD have precedence */ + if (img_xres(idict) == 0 && img_yres(idict) == 0) { + scan_resc_resd(idict); + if (xftell(img_file(idict), img_filepath(idict)) != (long)epos) + normal_error("readjp2","resc box size inconsistent"); + } + break; + case (BOX_RESD): scan_resc_resd(idict); if (xftell(img_file(idict), img_filepath(idict)) != (long)epos) - luatex_fail - ("reading JP2 image failed (resc box size inconsistent)"); - } - break; - case (BOX_RESD): - scan_resc_resd(idict); - if (xftell(img_file(idict), img_filepath(idict)) != (long)epos) - luatex_fail - ("reading JP2 image failed (resd box size inconsistent)"); - break; - default:; + normal_error("readjp2","resd box size inconsistent"); + break; + default:; } if (epos > epos_s) - luatex_fail("reading JP2 image failed (res box size inconsistent)"); + normal_error("readjp2","res box size inconsistent"); if (epos == epos_s) break; xfseek(img_file(idict), (long) epos, SEEK_SET, img_filepath(idict)); @@ -144,6 +144,7 @@ static void scan_res(image_dict * idict, uint64_t epos_s) } /* 1.5.3 JP2 Header box (superbox) */ + static boolean scan_jp2h(image_dict * idict, uint64_t epos_s) { boolean ihdr_found = false; @@ -158,8 +159,7 @@ static boolean scan_jp2h(image_dict * idict, uint64_t epos_s) case (BOX_IHDR): scan_ihdr(idict); if (xftell(img_file(idict), img_filepath(idict)) != (long)epos) - luatex_fail - ("reading JP2 image failed (ihdr box size inconsistent)"); + normal_error("readjp2","ihdr box size inconsistent"); ihdr_found = true; break; case (BOX_RES): @@ -168,8 +168,7 @@ static boolean scan_jp2h(image_dict * idict, uint64_t epos_s) default:; } if (epos > epos_s) - luatex_fail - ("reading JP2 image failed (jp2h box size inconsistent)"); + normal_error("readjp2","jp2h box size inconsistent"); if (epos == epos_s) break; xfseek(img_file(idict), (long) epos, SEEK_SET, img_filepath(idict)); @@ -179,50 +178,56 @@ static boolean scan_jp2h(image_dict * idict, uint64_t epos_s) static void close_and_cleanup_jp2(image_dict * idict) { - assert(idict != NULL); - assert(img_file(idict) != NULL); - assert(img_filepath(idict) != NULL); - xfclose(img_file(idict), img_filepath(idict)); - img_file(idict) = NULL; - assert(img_jp2_ptr(idict) != NULL); - xfree(img_jp2_ptr(idict)); + /* if one of then is not NULL we already cleaned up */ + if (img_file(idict) != NULL) { + xfclose(img_file(idict), img_filepath(idict)); + img_file(idict) = NULL; + } + if (img_jp2_ptr(idict) != NULL) { + xfree(img_jp2_ptr(idict)); + } +} + +void flush_jp2_info(image_dict * idict) +{ + close_and_cleanup_jp2(idict); } -void read_jp2_info(image_dict * idict, img_readtype_e readtype) +void read_jp2_info(image_dict * idict) { boolean ihdr_found = false; hdr_struct hdr; uint64_t spos, epos; - assert(img_type(idict) == IMG_TYPE_JP2); + if (img_type(idict) != IMG_TYPE_JP2) { + normal_error("readjp2","conflicting image dictionary"); + } + if (img_file(idict) != NULL) { + normal_error("readjp2","image data already read"); + } img_totalpages(idict) = 1; img_pagenum(idict) = 1; img_xres(idict) = img_yres(idict) = 0; - assert(img_file(idict) == NULL); img_file(idict) = xfopen(img_filepath(idict), FOPEN_RBIN_MODE); - assert(img_jp2_ptr(idict) == NULL); img_jp2_ptr(idict) = xtalloc(1, jp2_img_struct); xfseek(img_file(idict), 0, SEEK_END, img_filepath(idict)); - img_jp2_ptr(idict)->length = - (int) xftell(img_file(idict), img_filepath(idict)); + img_jp2_ptr(idict)->length = (int) xftell(img_file(idict), img_filepath(idict)); xfseek(img_file(idict), 0, SEEK_SET, img_filepath(idict)); - - assert(sizeof(uint64_t) >= 8); + if (sizeof(uint64_t) < 8) { + normal_error("readjp2","size problem"); + } spos = epos = 0; - /* 1.5.1 JPEG 2000 Signature box */ hdr = read_boxhdr(idict); - assert(hdr.tbox == BOX_JP); /* has already been checked */ epos = spos + hdr.lbox; xfseek(img_file(idict), (long) epos, SEEK_SET, img_filepath(idict)); - /* 1.5.2 File Type box */ spos = epos; hdr = read_boxhdr(idict); - if (hdr.tbox != BOX_FTYP) - luatex_fail("reading JP2 image failed (missing ftyp box)"); + if (hdr.tbox != BOX_FTYP) { + normal_error("readjp2","missing ftyp box"); + } epos = spos + hdr.lbox; xfseek(img_file(idict), (long) epos, SEEK_SET, img_filepath(idict)); - while (!ihdr_found) { spos = epos; hdr = read_boxhdr(idict); @@ -233,14 +238,15 @@ void read_jp2_info(image_dict * idict, img_readtype_e readtype) break; case BOX_JP2C: if (!ihdr_found) - luatex_fail("reading JP2 image failed (no ihdr box found)"); + normal_error("readjp2","no ihdr box found"); break; default:; } xfseek(img_file(idict), (long) epos, SEEK_SET, img_filepath(idict)); } - if (readtype == IMG_CLOSEINBETWEEN) + if (! img_keepopen(idict)) { close_and_cleanup_jp2(idict); + } } static void reopen_jp2(image_dict * idict) @@ -250,19 +256,23 @@ static void reopen_jp2(image_dict * idict) height = img_ysize(idict); xres = img_xres(idict); yres = img_yres(idict); - read_jp2_info(idict, IMG_KEEPOPEN); + /* + we need to make sure that the file kept open + */ + img_keepopen(idict) = 1; + read_jp2_info(idict); if (width != img_xsize(idict) || height != img_ysize(idict) - || xres != img_xres(idict) || yres != img_yres(idict)) - luatex_fail("writejp2: image dimensions have changed"); + || xres != img_xres(idict) || yres != img_yres(idict)) { + normal_error("writejp2","image dimensions have changed"); + } } void write_jp2(PDF pdf, image_dict * idict) { long unsigned l; - assert(idict != NULL); - if (img_file(idict) == NULL) + if (img_file(idict) == NULL) { reopen_jp2(idict); - assert(img_jp2_ptr(idict) != NULL); + } pdf_begin_obj(pdf, img_objnum(idict), OBJSTM_NEVER); pdf_begin_dict(pdf); pdf_dict_add_name(pdf, "Type", "XObject"); @@ -279,8 +289,9 @@ void write_jp2(PDF pdf, image_dict * idict) l = (long unsigned int) img_jp2_ptr(idict)->length; xfseek(img_file(idict), 0, SEEK_SET, img_filepath(idict)); if (read_file_to_buf(pdf, img_file(idict), l) != l) - luatex_fail("writejp2: fread failed"); + normal_error("writejp2","fread failed"); pdf_end_stream(pdf); pdf_end_obj(pdf); + /* always */ close_and_cleanup_jp2(idict); } diff --git a/Build/source/texk/web2c/luatexdir/image/writejpg.h b/Build/source/texk/web2c/luatexdir/image/writejpg.h index 8ef290d4746..96bf961246f 100644 --- a/Build/source/texk/web2c/luatexdir/image/writejpg.h +++ b/Build/source/texk/web2c/luatexdir/image/writejpg.h @@ -18,13 +18,13 @@ You should have received a copy of the GNU General Public License along with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */ - #ifndef WRITEJPG_H # define WRITEJPG_H # include "image.h" -void read_jpg_info(PDF, image_dict *, img_readtype_e); +void read_jpg_info(image_dict *); +void flush_jpg_info(image_dict *); void write_jpg(PDF, image_dict *); -#endif /* WRITEJPG_H */ +#endif diff --git a/Build/source/texk/web2c/luatexdir/image/writejpg.w b/Build/source/texk/web2c/luatexdir/image/writejpg.w index 7780f312922..07c51f5e1d0 100644 --- a/Build/source/texk/web2c/luatexdir/image/writejpg.w +++ b/Build/source/texk/web2c/luatexdir/image/writejpg.w @@ -20,87 +20,85 @@ @ @c - #include "ptexlib.h" #include <assert.h> #include "image/image.h" #include "image/writejpg.h" @ @c -#define JPG_GRAY 1 /* Gray color space, use /DeviceGray */ -#define JPG_RGB 3 /* RGB color space, use /DeviceRGB */ -#define JPG_CMYK 4 /* CMYK color space, use /DeviceCMYK */ +#define JPG_GRAY 1 /* Gray color space, use /DeviceGray */ +#define JPG_RGB 3 /* RGB color space, use /DeviceRGB */ +#define JPG_CMYK 4 /* CMYK color space, use /DeviceCMYK */ -typedef enum { /* JPEG marker codes */ - M_SOF0 = 0xc0, /* baseline DCT */ - M_SOF1 = 0xc1, /* extended sequential DCT */ - M_SOF2 = 0xc2, /* progressive DCT */ - M_SOF3 = 0xc3, /* lossless (sequential) */ +typedef enum { + M_SOF0 = 0xc0, /* baseline DCT */ + M_SOF1 = 0xc1, /* extended sequential DCT */ + M_SOF2 = 0xc2, /* progressive DCT */ + M_SOF3 = 0xc3, /* lossless (sequential) */ - M_SOF5 = 0xc5, /* differential sequential DCT */ - M_SOF6 = 0xc6, /* differential progressive DCT */ - M_SOF7 = 0xc7, /* differential lossless (sequential) */ + M_SOF5 = 0xc5, /* differential sequential DCT */ + M_SOF6 = 0xc6, /* differential progressive DCT */ + M_SOF7 = 0xc7, /* differential lossless (sequential) */ - M_JPG = 0xc8, /* reserved for JPEG extensions */ - M_SOF9 = 0xc9, /* extended sequential DCT */ - M_SOF10 = 0xca, /* progressive DCT */ - M_SOF11 = 0xcb, /* lossless (sequential) */ + M_JPG = 0xc8, /* reserved for JPEG extensions */ + M_SOF9 = 0xc9, /* extended sequential DCT */ + M_SOF10 = 0xca, /* progressive DCT */ + M_SOF11 = 0xcb, /* lossless (sequential) */ - M_SOF13 = 0xcd, /* differential sequential DCT */ - M_SOF14 = 0xce, /* differential progressive DCT */ - M_SOF15 = 0xcf, /* differential lossless (sequential) */ + M_SOF13 = 0xcd, /* differential sequential DCT */ + M_SOF14 = 0xce, /* differential progressive DCT */ + M_SOF15 = 0xcf, /* differential lossless (sequential) */ - M_DHT = 0xc4, /* define Huffman table(s) */ + M_DHT = 0xc4, /* define Huffman table(s) */ - M_DAC = 0xcc, /* define arithmetic conditioning table */ + M_DAC = 0xcc, /* define arithmetic conditioning table */ - M_RST0 = 0xd0, /* restart */ - M_RST1 = 0xd1, /* restart */ - M_RST2 = 0xd2, /* restart */ - M_RST3 = 0xd3, /* restart */ - M_RST4 = 0xd4, /* restart */ - M_RST5 = 0xd5, /* restart */ - M_RST6 = 0xd6, /* restart */ - M_RST7 = 0xd7, /* restart */ + M_RST0 = 0xd0, /* restart */ + M_RST1 = 0xd1, /* restart */ + M_RST2 = 0xd2, /* restart */ + M_RST3 = 0xd3, /* restart */ + M_RST4 = 0xd4, /* restart */ + M_RST5 = 0xd5, /* restart */ + M_RST6 = 0xd6, /* restart */ + M_RST7 = 0xd7, /* restart */ - M_SOI = 0xd8, /* start of image */ - M_EOI = 0xd9, /* end of image */ - M_SOS = 0xda, /* start of scan */ - M_DQT = 0xdb, /* define quantization tables */ - M_DNL = 0xdc, /* define number of lines */ - M_DRI = 0xdd, /* define restart interval */ - M_DHP = 0xde, /* define hierarchical progression */ - M_EXP = 0xdf, /* expand reference image(s) */ + M_SOI = 0xd8, /* start of image */ + M_EOI = 0xd9, /* end of image */ + M_SOS = 0xda, /* start of scan */ + M_DQT = 0xdb, /* define quantization tables */ + M_DNL = 0xdc, /* define number of lines */ + M_DRI = 0xdd, /* define restart interval */ + M_DHP = 0xde, /* define hierarchical progression */ + M_EXP = 0xdf, /* expand reference image(s) */ - M_APP0 = 0xe0, /* application marker, used for JFIF */ - M_APP1 = 0xe1, /* application marker */ - M_APP2 = 0xe2, /* application marker */ - M_APP3 = 0xe3, /* application marker */ - M_APP4 = 0xe4, /* application marker */ - M_APP5 = 0xe5, /* application marker */ - M_APP6 = 0xe6, /* application marker */ - M_APP7 = 0xe7, /* application marker */ - M_APP8 = 0xe8, /* application marker */ - M_APP9 = 0xe9, /* application marker */ - M_APP10 = 0xea, /* application marker */ - M_APP11 = 0xeb, /* application marker */ - M_APP12 = 0xec, /* application marker */ - M_APP13 = 0xed, /* application marker */ - M_APP14 = 0xee, /* application marker, used by Adobe */ - M_APP15 = 0xef, /* application marker */ + M_APP0 = 0xe0, /* application marker, used for JFIF */ + M_APP1 = 0xe1, /* application marker */ + M_APP2 = 0xe2, /* application marker */ + M_APP3 = 0xe3, /* application marker */ + M_APP4 = 0xe4, /* application marker */ + M_APP5 = 0xe5, /* application marker */ + M_APP6 = 0xe6, /* application marker */ + M_APP7 = 0xe7, /* application marker */ + M_APP8 = 0xe8, /* application marker */ + M_APP9 = 0xe9, /* application marker */ + M_APP10 = 0xea, /* application marker */ + M_APP11 = 0xeb, /* application marker */ + M_APP12 = 0xec, /* application marker */ + M_APP13 = 0xed, /* application marker */ + M_APP14 = 0xee, /* application marker, used by Adobe */ + M_APP15 = 0xef, /* application marker */ - M_JPG0 = 0xf0, /* reserved for JPEG extensions */ - M_JPG13 = 0xfd, /* reserved for JPEG extensions */ - M_COM = 0xfe, /* comment */ + M_JPG0 = 0xf0, /* reserved for JPEG extensions */ + M_JPG13 = 0xfd, /* reserved for JPEG extensions */ + M_COM = 0xfe, /* comment */ - M_TEM = 0x01, /* temporary use */ + M_TEM = 0x01, /* temporary use */ - M_ERROR = 0x100 /* dummy marker, internal use only */ + M_ERROR = 0x100 /* dummy marker, internal use only */ } JPEG_MARKER; @ @c -static unsigned char -myget_unsigned_byte (FILE *file) +static unsigned char myget_unsigned_byte (FILE *file) { int ch; ch = fgetc (file); @@ -108,8 +106,7 @@ myget_unsigned_byte (FILE *file) } @ @c -static unsigned short -myget_unsigned_pair (FILE *file) +static unsigned short myget_unsigned_pair (FILE *file) { unsigned short pair = myget_unsigned_byte(file); pair = (pair << 8) | myget_unsigned_byte(file); @@ -117,31 +114,30 @@ myget_unsigned_pair (FILE *file) } @ @c -static unsigned int -read_exif_bytes(unsigned char **p, int n, int b) +static unsigned int read_exif_bytes(unsigned char **p, int n, int b) { unsigned int rval = 0; unsigned char *pp = *p; if (b) { switch (n) { - case 4: - rval += *pp++; rval <<= 8; - rval += *pp++; rval <<= 8; - case 2: - rval += *pp++; rval <<= 8; - rval += *pp; - break; + case 4: + rval += *pp++; rval <<= 8; + rval += *pp++; rval <<= 8; + case 2: + rval += *pp++; rval <<= 8; + rval += *pp; + break; } } else { pp += n; switch (n) { - case 4: - rval += *--pp; rval <<= 8; - rval += *--pp; rval <<= 8; - case 2: - rval += *--pp; rval <<= 8; - rval += *--pp; - break; + case 4: + rval += *--pp; rval <<= 8; + rval += *--pp; rval <<= 8; + case 2: + rval += *--pp; rval <<= 8; + rval += *--pp; + break; } } *p += n; @@ -149,8 +145,7 @@ read_exif_bytes(unsigned char **p, int n, int b) } @ @c -static void -read_APP1_Exif (FILE *fp, unsigned short length, int *xx, int *yy) +static void read_APP1_Exif (FILE *fp, unsigned short length, int *xx, int *yy) { /* this doesn't save the data, just reads the tags we need */ /* based on info from http://www.exif.org/Exif2-2.PDF */ @@ -160,7 +155,7 @@ read_APP1_Exif (FILE *fp, unsigned short length, int *xx, int *yy) char bigendian; int i; int num_fields, tag, type; - int value = 0, num = 0, den = 0; /* silence uninitialized warnings */ + int value = 0, num = 0, den = 0; /* silence uninitialized warnings */ double xres = 72.0; double yres = 72.0; double res_unit = 1.0; @@ -190,133 +185,156 @@ read_APP1_Exif (FILE *fp, unsigned short length, int *xx, int *yy) type = read_exif_bytes(&p, 2, bigendian); read_exif_bytes(&p, 4, bigendian); switch (type) { - case 1: /* byte */ - value = *p++; - p += 3; - break; - case 3: /* short */ - value = read_exif_bytes(&p, 2, bigendian); - p += 2; - break; - case 4: /* long */ - case 9: /* slong */ - value = read_exif_bytes(&p, 4, bigendian); - break; - case 5: /* rational */ - case 10: /* srational */ - value = read_exif_bytes(&p, 4, bigendian); - rp = tiff_header + value; - num = read_exif_bytes(&rp, 4, bigendian); - den = read_exif_bytes(&rp, 4, bigendian); - break; - case 7: /* undefined */ - value = *p++; - p += 3; - break; - case 2: /* ascii */ - default: - p += 4; - break; - } + case 1: /* byte */ + value = *p++; + p += 3; + break; + case 3: /* short */ + value = read_exif_bytes(&p, 2, bigendian); + p += 2; + break; + case 4: /* long */ + case 9: /* slong */ + value = read_exif_bytes(&p, 4, bigendian); + break; + case 5: /* rational */ + case 10: /* srational */ + value = read_exif_bytes(&p, 4, bigendian); + rp = tiff_header + value; + num = read_exif_bytes(&rp, 4, bigendian); + den = read_exif_bytes(&rp, 4, bigendian); + break; + case 7: /* undefined */ + value = *p++; + p += 3; + break; + case 2: /* ascii */ + default: + p += 4; + break; + } switch (tag) { - case 282: /* x res */ - if (den != 0) - xres = num / den; - break; - case 283: /* y res */ - if (den != 0) - yres = num / den; - break; - case 296: /* res unit */ - switch (value) { - case 2: - res_unit = 1.0; + case 282: /* x res */ + if (den != 0) + xres = num / den; break; - case 3: - res_unit = 2.54; + case 283: /* y res */ + if (den != 0) + yres = num / den; break; - } + case 296: /* res unit */ + switch (value) { + case 2: + res_unit = 1.0; + break; + case 3: + res_unit = 2.54; + break; + } } } *xx = (int)(xres * res_unit); *yy = (int)(yres * res_unit); - err: free(buffer); return; } +/* + + Contrary to pdf where several parallel usage can happen (epdf, tex, lua) with + bitmaps we care less about keeping files open. So, we can keep files open in + the img lib but then they are closed after inclusion anyway. + +*/ + @ @c static void close_and_cleanup_jpg(image_dict * idict) { - assert(idict != NULL); - assert(img_file(idict) != NULL); - assert(img_filepath(idict) != NULL); - xfclose(img_file(idict), img_filepath(idict)); - img_file(idict) = NULL; - assert(img_jpg_ptr(idict) != NULL); - xfree(img_jpg_ptr(idict)); + /* if one of then is not NULL we already cleaned up */ + if (img_file(idict) != NULL) { + xfclose(img_file(idict), img_filepath(idict)); + img_file(idict) = NULL; + } + if (img_jpg_ptr(idict) != NULL) { + xfree(img_jpg_ptr(idict)); + } +} + +@ @c +void flush_jpg_info(image_dict * idict) +{ + close_and_cleanup_jpg(idict); } @ @c -void read_jpg_info(PDF pdf, image_dict * idict, img_readtype_e readtype) +void read_jpg_info(image_dict * idict) { int i, units = 0; unsigned short appmk, length; unsigned char jpg_id[] = "JFIF"; - assert(idict != NULL); - assert(img_type(idict) == IMG_TYPE_JPG); + if (img_type(idict) != IMG_TYPE_JPG) { + normal_error("readjpg","conflicting image dictionary"); + } + if (img_file(idict) != NULL) { + normal_error("readjpg","image data already read"); + } img_totalpages(idict) = 1; img_pagenum(idict) = 1; img_xres(idict) = img_yres(idict) = 0; - assert(img_file(idict) == NULL); img_file(idict) = xfopen(img_filepath(idict), FOPEN_RBIN_MODE); - assert(img_jpg_ptr(idict) == NULL); + if (img_file(idict) == NULL) { + normal_error("readjpg","unable to read image file"); + } img_jpg_ptr(idict) = xtalloc(1, jpg_img_struct); xfseek(img_file(idict), 0, SEEK_END, img_filepath(idict)); img_jpg_ptr(idict)->length = xftell(img_file(idict), img_filepath(idict)); xfseek(img_file(idict), 0, SEEK_SET, img_filepath(idict)); - if ((unsigned int) read2bytes(img_file(idict)) != 0xFFD8) - luatex_fail("reading JPEG image failed (no JPEG header found)"); + if ((unsigned int) read2bytes(img_file(idict)) != 0xFFD8) { + normal_error("readjpg","no header found"); + } /* currently JFIF and Exif files allow extracting |img_xres| and |img_yres| */ appmk = read2bytes(img_file(idict)); - if (appmk == 0xFFE0) { /* check for JFIF */ + if (appmk == 0xFFE0) { + /* check for JFIF */ (void) read2bytes(img_file(idict)); for (i = 0; i < 5; i++) { if (xgetc(img_file(idict)) != jpg_id[i]) break; } - if (i == 5) { /* it's JFIF */ + if (i == 5) { + /* it's JFIF */ (void) read2bytes(img_file(idict)); units = xgetc(img_file(idict)); img_xres(idict) = (int) read2bytes(img_file(idict)); img_yres(idict) = (int) read2bytes(img_file(idict)); switch (units) { case 1: + /* pixels per inch */ if ((img_xres(idict) == 1) || (img_yres(idict) == 1)) { - luatex_warn("The image specifies an unusual resolution of %ddpi by %ddpi. ", - img_xres(idict), img_yres(idict)); + formatted_warning("readjpg","unusual resolution of %ddpi by %ddpi", img_xres(idict), img_yres(idict)); } - break; /* pixels per inch */ + break; case 2: + /* pixels per cm */ img_xres(idict) = (int) ((double) img_xres(idict) * 2.54); img_yres(idict) = (int) ((double) img_yres(idict) * 2.54); - break; /* pixels per cm */ + break; default: img_xres(idict) = img_yres(idict) = 0; break; } } - /* if either xres or yres is 0 but the other isn't, - set it to the value of the other */ + /* if either xres or yres is 0 but the other isn't, set it to the value of the other */ if ((img_xres(idict) == 0) && (img_yres(idict) != 0)) { img_xres(idict) = img_yres(idict); } if ((img_yres(idict) == 0) && (img_xres(idict) != 0)) { img_yres(idict) = img_xres(idict); } - } else if (appmk == 0xFFE1) { /* check for Exif */ + } else if (appmk == 0xFFE1) { + /* check for Exif */ FILE *fp = img_file(idict); int xxres = 0; int yyres = 0; @@ -335,102 +353,111 @@ void read_jpg_info(PDF pdf, image_dict * idict, img_readtype_e readtype) } xfseek(img_file(idict), 0, SEEK_SET, img_filepath(idict)); while (1) { - if (feof(img_file(idict))) - luatex_fail("reading JPEG image failed (premature file end)"); - if (fgetc(img_file(idict)) != 0xFF) - luatex_fail("reading JPEG image failed (no marker found)"); + if (feof(img_file(idict))) { + normal_error("readjpg","premature file end"); + } else if (fgetc(img_file(idict)) != 0xFF) { + normal_error("readjpg","no marker found"); + } i = xgetc(img_file(idict)); switch (i) { - case M_SOF3: /* lossless */ - case M_SOF5: - case M_SOF6: - case M_SOF7: /* lossless */ - case M_SOF9: - case M_SOF10: - case M_SOF11: /* lossless */ - case M_SOF13: - case M_SOF14: - case M_SOF15: /* lossless */ - luatex_fail("unsupported type of compression (SOF_%d)", i - M_SOF0); - break; - case M_SOF2: - if (pdf->minor_version <= 2) - luatex_fail("cannot use progressive DCT with PDF-1.2"); - case M_SOF0: - case M_SOF1: - (void) read2bytes(img_file(idict)); /* read segment length */ - img_colordepth(idict) = xgetc(img_file(idict)); - img_ysize(idict) = (int) read2bytes(img_file(idict)); - img_xsize(idict) = (int) read2bytes(img_file(idict)); - img_jpg_color(idict) = xgetc(img_file(idict)); - xfseek(img_file(idict), 0, SEEK_SET, img_filepath(idict)); - switch (img_jpg_color(idict)) { - case JPG_GRAY: - img_procset(idict) |= PROCSET_IMAGE_B; + case M_SOF3: /* lossless */ + case M_SOF5: + case M_SOF6: + case M_SOF7: /* lossless */ + case M_SOF9: + case M_SOF10: + case M_SOF11: /* lossless */ + case M_SOF13: + case M_SOF14: + case M_SOF15: /* lossless */ + formatted_error("readjpg","unsupported compression SOF_%d", i - M_SOF0); break; - case JPG_RGB: - img_procset(idict) |= PROCSET_IMAGE_C; - break; - case JPG_CMYK: - img_procset(idict) |= PROCSET_IMAGE_C; + case M_SOF2: + if (img_pdfminorversion(idict) <= 2) { + normal_error("readjpg","progressive DCT with PDF-1.2 is not permitted"); + } + case M_SOF0: + case M_SOF1: + (void) read2bytes(img_file(idict)); /* read segment length */ + img_colordepth(idict) = xgetc(img_file(idict)); + img_ysize(idict) = (int) read2bytes(img_file(idict)); + img_xsize(idict) = (int) read2bytes(img_file(idict)); + img_jpg_color(idict) = xgetc(img_file(idict)); + xfseek(img_file(idict), 0, SEEK_SET, img_filepath(idict)); + switch (img_jpg_color(idict)) { + case JPG_GRAY: + img_procset(idict) |= PROCSET_IMAGE_B; + break; + case JPG_RGB: + img_procset(idict) |= PROCSET_IMAGE_C; + break; + case JPG_CMYK: + img_procset(idict) |= PROCSET_IMAGE_C; + break; + default: + formatted_error("readjpg","unsupported color space %i", (int) img_jpg_color(idict)); + } + /* + So we can optionally keep open a file in img. + */ + if (! img_keepopen(idict)) { + close_and_cleanup_jpg(idict); + } + return; + /* ignore markers without parameters */ + case M_SOI: + case M_EOI: + case M_TEM: + case M_RST0: + case M_RST1: + case M_RST2: + case M_RST3: + case M_RST4: + case M_RST5: + case M_RST6: + case M_RST7: break; default: - luatex_fail("Unsupported color space %i", - (int) img_jpg_color(idict)); - } - if (readtype == IMG_CLOSEINBETWEEN) - close_and_cleanup_jpg(idict); - return; - case M_SOI: /* ignore markers without parameters */ - case M_EOI: - case M_TEM: - case M_RST0: - case M_RST1: - case M_RST2: - case M_RST3: - case M_RST4: - case M_RST5: - case M_RST6: - case M_RST7: - break; - default: /* skip variable length markers */ - xfseek(img_file(idict), (int) read2bytes(img_file(idict)) - 2, - SEEK_CUR, img_filepath(idict)); - break; + /* skip variable length markers */ + xfseek(img_file(idict), (int) read2bytes(img_file(idict)) - 2, SEEK_CUR, img_filepath(idict)); + break; } } - assert(0); + normal_error("readjpg","unknown fatal error"); } @ @c -static void reopen_jpg(PDF pdf, image_dict * idict) +static void reopen_jpg(image_dict * idict) { - int width, height, xres, yres; - width = img_xsize(idict); - height = img_ysize(idict); - xres = img_xres(idict); - yres = img_yres(idict); - read_jpg_info(pdf, idict, IMG_KEEPOPEN); - if (width != img_xsize(idict) || height != img_ysize(idict) - || xres != img_xres(idict) || yres != img_yres(idict)) - luatex_fail("writejpg: image dimensions have changed"); + int width = img_xsize(idict); + int height = img_ysize(idict); + int xres = img_xres(idict); + int yres = img_yres(idict); + /* + we need to make sure that the file kept open + */ + img_keepopen(idict) = 1; + read_jpg_info(idict); + if (width != img_xsize(idict) || height != img_ysize(idict) || xres != img_xres(idict) || yres != img_yres(idict)) { + normal_error("writejpg","image dimensions have changed"); + } } @ @c void write_jpg(PDF pdf, image_dict * idict) { size_t l; - assert(idict != NULL); - if (img_file(idict) == NULL) - reopen_jpg(pdf, idict); - assert(img_jpg_ptr(idict) != NULL); + if (img_file(idict) == NULL) { + reopen_jpg(idict); + } 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", "Image"); pdf_dict_add_img_filename(pdf, idict); - if (img_attr(idict) != NULL && strlen(img_attr(idict)) > 0) + if (img_attr(idict) != NULL && strlen(img_attr(idict)) > 0) { pdf_printf(pdf, "\n%s\n", img_attr(idict)); + } pdf_dict_add_int(pdf, "Width", (int) img_xsize(idict)); pdf_dict_add_int(pdf, "Height", (int) img_ysize(idict)); pdf_dict_add_int(pdf, "BitsPerComponent", (int) img_colordepth(idict)); @@ -439,40 +466,40 @@ void write_jpg(PDF pdf, image_dict * idict) pdf_dict_add_ref(pdf, "ColorSpace", (int) img_colorspace(idict)); } else { switch (img_jpg_color(idict)) { - case JPG_GRAY: - pdf_dict_add_name(pdf, "ColorSpace", "DeviceGray"); - break; - case JPG_RGB: - pdf_dict_add_name(pdf, "ColorSpace", "DeviceRGB"); - break; - case JPG_CMYK: - pdf_dict_add_name(pdf, "ColorSpace", "DeviceCMYK"); - pdf_add_name(pdf, "Decode"); - pdf_begin_array(pdf); - pdf_add_int(pdf, 1); - pdf_add_int(pdf, 0); - pdf_add_int(pdf, 1); - pdf_add_int(pdf, 0); - pdf_add_int(pdf, 1); - pdf_add_int(pdf, 0); - pdf_add_int(pdf, 1); - pdf_add_int(pdf, 0); - pdf_end_array(pdf); - break; - default: - luatex_fail("Unsupported color space %i", - (int) img_jpg_color(idict)); + case JPG_GRAY: + pdf_dict_add_name(pdf, "ColorSpace", "DeviceGray"); + break; + case JPG_RGB: + pdf_dict_add_name(pdf, "ColorSpace", "DeviceRGB"); + break; + case JPG_CMYK: + pdf_dict_add_name(pdf, "ColorSpace", "DeviceCMYK"); + pdf_add_name(pdf, "Decode"); + pdf_begin_array(pdf); + pdf_add_int(pdf, 1); + pdf_add_int(pdf, 0); + pdf_add_int(pdf, 1); + pdf_add_int(pdf, 0); + pdf_add_int(pdf, 1); + pdf_add_int(pdf, 0); + pdf_add_int(pdf, 1); + pdf_add_int(pdf, 0); + pdf_end_array(pdf); + break; + default: + formatted_error("writejpg","unsupported JPEG color space %i", (int) img_jpg_color(idict)); } } pdf_dict_add_name(pdf, "Filter", "DCTDecode"); pdf_end_dict(pdf); pdf_begin_stream(pdf); - assert(pdf->zip_write_state == NO_ZIP); l = (size_t) img_jpg_ptr(idict)->length; xfseek(img_file(idict), 0, SEEK_SET, img_filepath(idict)); - if (read_file_to_buf(pdf, img_file(idict), l) != l) - luatex_fail("writejpg: fread failed"); + if (read_file_to_buf(pdf, img_file(idict), l) != l) { + normal_error("writejpg","fread failed"); + } pdf_end_stream(pdf); pdf_end_obj(pdf); + /* always */ close_and_cleanup_jpg(idict); } diff --git a/Build/source/texk/web2c/luatexdir/image/writepng.h b/Build/source/texk/web2c/luatexdir/image/writepng.h index 4dd425c0405..2af2a3fa2fb 100644 --- a/Build/source/texk/web2c/luatexdir/image/writepng.h +++ b/Build/source/texk/web2c/luatexdir/image/writepng.h @@ -18,14 +18,15 @@ You should have received a copy of the GNU General Public License along with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */ - #ifndef WRITEPNG_H # define WRITEPNG_H # include "image.h" -void read_png_info(image_dict *, img_readtype_e); +void read_png_info(image_dict *); +void flush_png_info(image_dict *); + void write_additional_png_objects(PDF); void write_png(PDF, image_dict *); -#endif /* WRITEPNG_H */ +#endif diff --git a/Build/source/texk/web2c/luatexdir/image/writepng.w b/Build/source/texk/web2c/luatexdir/image/writepng.w index 40f8e0e2635..412000c427f 100644 --- a/Build/source/texk/web2c/luatexdir/image/writepng.w +++ b/Build/source/texk/web2c/luatexdir/image/writepng.w @@ -20,7 +20,6 @@ @ @c - #include "ptexlib.h" #include <assert.h> #include "image/image.h" @@ -31,45 +30,55 @@ static int transparent_page_group = -1; static void close_and_cleanup_png(image_dict * idict) { - assert(idict != NULL); - assert(img_file(idict) != NULL); - assert(img_filepath(idict) != NULL); - xfclose(img_file(idict), img_filepath(idict)); - img_file(idict) = NULL; - assert(img_png_ptr(idict) != NULL); - png_destroy_read_struct(&(img_png_png_ptr(idict)), - &(img_png_info_ptr(idict)), NULL); - xfree(img_png_ptr(idict)); + /* if one of then is not NULL we already cleaned up */ + if (img_file(idict) != NULL) { + xfclose(img_file(idict), img_filepath(idict)); + img_file(idict) = NULL; + } + if (img_png_ptr(idict) != NULL) { + png_destroy_read_struct(&(img_png_png_ptr(idict)), &(img_png_info_ptr(idict)), NULL); + xfree(img_png_ptr(idict)); + } +} + +@ @c +void flush_png_info(image_dict * idict) +{ + close_and_cleanup_png(idict); } @ @c static void warn(png_structp png_ptr, png_const_charp msg) { - (void)png_ptr; (void)msg; /* Make compiler happy */ + (void)png_ptr; (void)msg; /* Make compiler happy */ } -void read_png_info(image_dict * idict, img_readtype_e readtype) +void read_png_info(image_dict * idict) { png_structp png_p; png_infop info_p; - assert(idict != NULL); - assert(img_type(idict) == IMG_TYPE_PNG); + if (img_type(idict) != IMG_TYPE_PNG) { + normal_error("readpng","conflicting image dictionary"); + } + if (img_file(idict) != NULL) { + normal_error("readpng","image data already read"); + } img_totalpages(idict) = 1; img_pagenum(idict) = 1; img_xres(idict) = img_yres(idict) = 0; - assert(img_file(idict) == NULL); img_file(idict) = xfopen(img_filepath(idict), FOPEN_RBIN_MODE); - assert(img_png_ptr(idict) == NULL); img_png_ptr(idict) = xtalloc(1, png_img_struct); - if ((png_p = png_create_read_struct(PNG_LIBPNG_VER_STRING, - NULL, NULL, warn)) == NULL) - luatex_fail("libpng: png_create_read_struct() failed"); + if ((png_p = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, warn)) == NULL) { + normal_error("readpng","png_create_read_struct() failed"); + } img_png_png_ptr(idict) = png_p; - if ((info_p = png_create_info_struct(png_p)) == NULL) - luatex_fail("libpng: png_create_info_struct() failed"); + if ((info_p = png_create_info_struct(png_p)) == NULL) { + normal_error("readpng","png_create_info_struct() failed"); + } img_png_info_ptr(idict) = info_p; - if (setjmp(png_jmpbuf(png_p))) - luatex_fail("libpng: internal error"); + if (setjmp(png_jmpbuf(png_p))) { + normal_error("readpng","internal error"); + } #if PNG_LIBPNG_VER >= 10603 /* ignore possibly incorrect CMF bytes */ png_set_option(png_p, PNG_MAXIMUM_INFLATE_WINDOW, PNG_OPTION_ON); @@ -80,10 +89,8 @@ void read_png_info(image_dict * idict, img_readtype_e readtype) img_xsize(idict) = (int) png_get_image_width(png_p, info_p); img_ysize(idict) = (int) png_get_image_height(png_p, info_p); if (png_get_valid(png_p, info_p, PNG_INFO_pHYs)) { - img_xres(idict) = - round(0.0254 * (double) png_get_x_pixels_per_meter(png_p, info_p)); - img_yres(idict) = - round(0.0254 * (double) png_get_y_pixels_per_meter(png_p, info_p)); + img_xres(idict) = round(0.0254 * (double) png_get_x_pixels_per_meter(png_p, info_p)); + img_yres(idict) = round(0.0254 * (double) png_get_y_pixels_per_meter(png_p, info_p)); } switch (png_get_color_type(png_p, info_p)) { case PNG_COLOR_TYPE_PALETTE: @@ -98,12 +105,15 @@ void read_png_info(image_dict * idict, img_readtype_e readtype) img_procset(idict) |= PROCSET_IMAGE_C; break; default: - luatex_fail("unsupported type of color_type <%i>", - (int) png_get_color_type(png_p, info_p)); + formatted_error("readpng","unsupported type of color_type '%i'",(int) png_get_color_type(png_p, info_p)); } img_colordepth(idict) = png_get_bit_depth(png_p, info_p); - if (readtype == IMG_CLOSEINBETWEEN) + /* + So we can optionally keep open a file in img. + */ + if (! img_keepopen(idict)) { close_and_cleanup_png(idict); + } } @ @c @@ -164,8 +174,7 @@ void read_png_info(image_dict * idict, img_readtype_e readtype) } @ @c -static void write_palette_streamobj(PDF pdf, int palette_objnum, - png_colorp palette, int num_palette) +static void write_palette_streamobj(PDF pdf, int palette_objnum, png_colorp palette, int num_palette) { int i; if (palette_objnum == 0) @@ -187,8 +196,7 @@ static void write_palette_streamobj(PDF pdf, int palette_objnum, } @ @c -static void write_smask_streamobj(PDF pdf, image_dict * idict, int smask_objnum, - png_bytep smask, int smask_size) +static void write_smask_streamobj(PDF pdf, image_dict * idict, int smask_objnum, png_bytep smask, int smask_size) { int i; png_structp png_p = img_png_png_ptr(idict); @@ -235,13 +243,13 @@ static void write_png_gray(PDF pdf, image_dict * idict) write_noninterlaced(write_simple_pixel(r)); xfree(row); } else { - if (png_get_image_height(png_p, info_p) * - png_get_rowbytes(png_p, info_p) >= 10240000L) - luatex_warn - ("large interlaced PNG might cause out of memory (use non-interlaced PNG to fix this)"); + if (png_get_image_height(png_p, info_p) * png_get_rowbytes(png_p, info_p) >= 10240000L) { + formatted_warning("pngwrite","large interlaced bitmap might cause out of memory"); + } rows = xtalloc(png_get_image_height(png_p, info_p), png_bytep); - for (i = 0; i < (int) png_get_image_height(png_p, info_p); i++) + for (i = 0; i < (int) png_get_image_height(png_p, info_p); i++) { rows[i] = xtalloc(png_get_rowbytes(png_p, info_p), png_byte); + } png_read_image(png_p, rows); write_interlaced(write_simple_pixel(row)); xfree(rows); @@ -264,33 +272,29 @@ static void write_png_gray_alpha(PDF pdf, image_dict * idict) int smask_size = 0; smask_objnum = pdf_create_obj(pdf, obj_type_others, 0); pdf_dict_add_ref(pdf, "SMask", (int) smask_objnum); - smask_size = - (int) ((png_get_rowbytes(png_p, info_p) / 2) * - png_get_image_height(png_p, info_p)); + smask_size = (int) ((png_get_rowbytes(png_p, info_p) / 2) * png_get_image_height(png_p, info_p)); smask = xtalloc((unsigned) smask_size, png_byte); pdf_dict_add_streaminfo(pdf); pdf_end_dict(pdf); pdf_begin_stream(pdf); if (png_get_interlace_type(png_p, info_p) == PNG_INTERLACE_NONE) { row = xtalloc(png_get_rowbytes(png_p, info_p), png_byte); - if ((png_get_bit_depth(png_p, info_p) == 16) - && (pdf->image_hicolor != 0)) { + if ((png_get_bit_depth(png_p, info_p) == 16) && (pdf->image_hicolor != 0)) { write_noninterlaced(write_gray_pixel_16(r)); } else { write_noninterlaced(write_gray_pixel_8(r)); } xfree(row); } else { - if (png_get_image_height(png_p, info_p) * - png_get_rowbytes(png_p, info_p) >= 10240000L) - luatex_warn - ("large interlaced PNG might cause out of memory (use non-interlaced PNG to fix this)"); + if (png_get_image_height(png_p, info_p) * png_get_rowbytes(png_p, info_p) >= 10240000L) { + formatted_warning("pngwrite","large interlaced bitmap might cause out of memory"); + } rows = xtalloc(png_get_image_height(png_p, info_p), png_bytep); - for (i = 0; i < (int) png_get_image_height(png_p, info_p); i++) + for (i = 0; i < (int) png_get_image_height(png_p, info_p); i++) { rows[i] = xtalloc(png_get_rowbytes(png_p, info_p), png_byte); + } png_read_image(png_p, rows); - if ((png_get_bit_depth(png_p, info_p) == 16) - && (pdf->image_hicolor != 0)) { + if ((png_get_bit_depth(png_p, info_p) == 16) && (pdf->image_hicolor != 0)) { write_interlaced(write_gray_pixel_16(row)); } else { write_interlaced(write_gray_pixel_8(row)); @@ -317,33 +321,29 @@ static void write_png_rgb_alpha(PDF pdf, image_dict * idict) int smask_size = 0; smask_objnum = pdf_create_obj(pdf, obj_type_others, 0); pdf_dict_add_ref(pdf, "SMask", (int) smask_objnum); - smask_size = - (int) ((png_get_rowbytes(png_p, info_p) / 4) * - png_get_image_height(png_p, info_p)); + smask_size = (int) ((png_get_rowbytes(png_p, info_p) / 4) * png_get_image_height(png_p, info_p)); smask = xtalloc((unsigned) smask_size, png_byte); pdf_dict_add_streaminfo(pdf); pdf_end_dict(pdf); pdf_begin_stream(pdf); if (png_get_interlace_type(png_p, info_p) == PNG_INTERLACE_NONE) { row = xtalloc(png_get_rowbytes(png_p, info_p), png_byte); - if ((png_get_bit_depth(png_p, info_p) == 16) - && (pdf->image_hicolor != 0)) { + if ((png_get_bit_depth(png_p, info_p) == 16) && (pdf->image_hicolor != 0)) { write_noninterlaced(write_rgb_pixel_16(r)); } else { write_noninterlaced(write_rgb_pixel_8(r)); } xfree(row); } else { - if (png_get_image_height(png_p, info_p) * - png_get_rowbytes(png_p, info_p) >= 10240000L) - luatex_warn - ("large interlaced PNG might cause out of memory (use non-interlaced PNG to fix this)"); + if (png_get_image_height(png_p, info_p) * png_get_rowbytes(png_p, info_p) >= 10240000L) { + formatted_warning("pngwrite","large interlaced bitmap might cause out of memory"); + } rows = xtalloc(png_get_image_height(png_p, info_p), png_bytep); - for (i = 0; i < (int) png_get_image_height(png_p, info_p); i++) + for (i = 0; i < (int) png_get_image_height(png_p, info_p); i++) { rows[i] = xtalloc(png_get_rowbytes(png_p, info_p), png_byte); + } png_read_image(png_p, rows); - if ((png_get_bit_depth(png_p, info_p) == 16) - && (pdf->image_hicolor != 0)) { + if ((png_get_bit_depth(png_p, info_p) == 16) && (pdf->image_hicolor != 0)) { write_interlaced(write_rgb_pixel_16(row)); } else { write_interlaced(write_rgb_pixel_8(row)); @@ -373,8 +373,9 @@ the ``PNG Copy'' function must be skipped; therefore the lengthy tests. static int spng_getint(FILE * f) { unsigned char buf[4]; - if (fread(buf, 1, 4, f) != 4) - luatex_fail("writepng: reading chunk type failed"); + if (fread(buf, 1, 4, f) != 4) { + normal_error("writepng", "reading chunk type failed"); + } return ((((((int) buf[0] << 8) + buf[1]) << 8) + buf[2]) << 8) + buf[3]; } @@ -395,7 +396,7 @@ static void copy_png(PDF pdf, image_dict * idict) f = (FILE *) png_get_io_ptr(png_p); /* 1st pass to find overall stream /Length */ if (fseek(f, 8, SEEK_SET) != 0) - luatex_fail("writepng: fseek in PNG file failed (1)"); + normal_error("writepng", "fseek in file failed"); do { len = spng_getint(f); type = spng_getint(f); @@ -406,49 +407,52 @@ static void copy_png(PDF pdf, image_dict * idict) case SPNG_CHUNK_IDAT: streamlength += len; default: - if (fseek(f, len + 4, SEEK_CUR) != 0) - luatex_fail("writepng: fseek in PNG file failed (2)"); + if (fseek(f, len + 4, SEEK_CUR) != 0) { + normal_error("writepng", "fseek in file failed"); + } } } while (endflag == false); pdf_dict_add_int(pdf, "Length", streamlength); pdf_dict_add_name(pdf, "Filter", "FlateDecode"); pdf_add_name(pdf, "DecodeParms"); pdf_begin_dict(pdf); - pdf_dict_add_int(pdf, "Colors", - png_get_color_type(png_p, - info_p) == PNG_COLOR_TYPE_RGB ? 3 : 1); + pdf_dict_add_int(pdf, "Colors", png_get_color_type(png_p,info_p) == PNG_COLOR_TYPE_RGB ? 3 : 1); pdf_dict_add_int(pdf, "Columns", png_get_image_width(png_p, info_p)); pdf_dict_add_int(pdf, "BitsPerComponent", png_get_bit_depth(png_p, info_p)); pdf_dict_add_int(pdf, "Predictor", 10); pdf_end_dict(pdf); pdf_end_dict(pdf); pdf_begin_stream(pdf); - assert(pdf->zip_write_state == NO_ZIP); /* the PNG stream is already compressed */ + assert(pdf->zip_write_state == NO_ZIP); /* the PNG stream is already compressed */ /* 2nd pass to copy data */ endflag = false; if (fseek(f, 8, SEEK_SET) != 0) - luatex_fail("writepng: fseek in PNG file failed (3)"); + normal_error("writepng", "fseek in file failed"); do { len = spng_getint(f); type = spng_getint(f); switch (type) { - case SPNG_CHUNK_IDAT: /* do copy */ - if (idat == 2) - luatex_fail("writepng: IDAT chunk sequence broken"); + case SPNG_CHUNK_IDAT: + /* do copy */ + if (idat == 2) { + normal_error("writepng", "IDAT chunk sequence broken"); + } idat = 1; - if (read_file_to_buf(pdf, f, len) != len) - luatex_fail("writepng: fread failed"); - if (fseek(f, 4, SEEK_CUR) != 0) - luatex_fail("writepng: fseek in PNG file failed (4)"); + if (read_file_to_buf(pdf, f, len) != len) { + normal_error("writepng", "fread failed"); + } else if (fseek(f, 4, SEEK_CUR) != 0) { + normal_error("writepng", "fseek in file failed"); + } break; - case SPNG_CHUNK_IEND: /* done */ + case SPNG_CHUNK_IEND: + /* done */ endflag = true; break; default: if (idat == 1) idat = 2; if (fseek(f, len + 4, SEEK_CUR) != 0) - luatex_fail("writepng: fseek in PNG file failed (5)"); + normal_error("writepng", "fseek in file failed"); } } while (endflag == false); pdf_end_stream(pdf); @@ -463,10 +467,14 @@ static void reopen_png(image_dict * idict) height = img_ysize(idict); xres = img_xres(idict); yres = img_yres(idict); - read_png_info(idict, IMG_KEEPOPEN); - if (width != img_xsize(idict) || height != img_ysize(idict) - || xres != img_xres(idict) || yres != img_yres(idict)) - luatex_fail("writepng: image dimensions have changed"); + /* + we need to ake sure that the file kept open + */ + img_keepopen(idict) = 1; + read_png_info(idict); + if (width != img_xsize(idict) || height != img_ysize(idict) || xres != img_xres(idict) || yres != img_yres(idict)) { + normal_error("writepng", "image dimensions have changed"); + } } @ @c @@ -526,53 +534,51 @@ void write_png(PDF pdf, image_dict * idict) /* reset structure */ (void) png_set_interlace_handling(png_p); png_read_update_info(png_p, info_p); - 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", "Image"); pdf_dict_add_img_filename(pdf, idict); - if (img_attr(idict) != NULL && strlen(img_attr(idict)) > 0) + if (img_attr(idict) != NULL && strlen(img_attr(idict)) > 0) { pdf_printf(pdf, "\n%s\n", img_attr(idict)); + } pdf_dict_add_int(pdf, "Width", (int) png_get_image_width(png_p, info_p)); pdf_dict_add_int(pdf, "Height", (int) png_get_image_height(png_p, info_p)); - pdf_dict_add_int(pdf, "BitsPerComponent", - (int) png_get_bit_depth(png_p, info_p)); + pdf_dict_add_int(pdf, "BitsPerComponent", (int) png_get_bit_depth(png_p, info_p)); if (img_colorspace(idict) != 0) { pdf_dict_add_ref(pdf, "ColorSpace", (int) img_colorspace(idict)); } else { switch (png_get_color_type(png_p, info_p)) { - case PNG_COLOR_TYPE_PALETTE: - png_get_PLTE(png_p, info_p, &palette, &num_palette); - palette_objnum = pdf_create_obj(pdf, obj_type_others, 0); - pdf_add_name(pdf, "ColorSpace"); - pdf_begin_array(pdf); - pdf_add_name(pdf, "Indexed"); - pdf_add_name(pdf, "DeviceRGB"); /* base; PDFRef. 4.5.5 */ - pdf_add_int(pdf, (int) (num_palette - 1)); /* hival */ - pdf_add_ref(pdf, (int) palette_objnum); /* lookup */ - pdf_end_array(pdf); - break; - case PNG_COLOR_TYPE_GRAY: - case PNG_COLOR_TYPE_GRAY_ALPHA: - pdf_dict_add_name(pdf, "ColorSpace", "DeviceGray"); - break; - case PNG_COLOR_TYPE_RGB: - case PNG_COLOR_TYPE_RGB_ALPHA: - pdf_dict_add_name(pdf, "ColorSpace", "DeviceRGB"); - break; - default: - luatex_fail("unsupported type of color_type <%i>", - png_get_color_type(png_p, info_p)); + case PNG_COLOR_TYPE_PALETTE: + png_get_PLTE(png_p, info_p, &palette, &num_palette); + palette_objnum = pdf_create_obj(pdf, obj_type_others, 0); + pdf_add_name(pdf, "ColorSpace"); + pdf_begin_array(pdf); + pdf_add_name(pdf, "Indexed"); + pdf_add_name(pdf, "DeviceRGB"); /* base; PDFRef. 4.5.5 */ + pdf_add_int(pdf, (int) (num_palette - 1)); /* hival */ + pdf_add_ref(pdf, (int) palette_objnum); /* lookup */ + pdf_end_array(pdf); + break; + case PNG_COLOR_TYPE_GRAY: + case PNG_COLOR_TYPE_GRAY_ALPHA: + pdf_dict_add_name(pdf, "ColorSpace", "DeviceGray"); + break; + case PNG_COLOR_TYPE_RGB: + case PNG_COLOR_TYPE_RGB_ALPHA: + pdf_dict_add_name(pdf, "ColorSpace", "DeviceRGB"); + break; + default: + formatted_error("writepng", "unsupported color_type '%i'", png_get_color_type(png_p, info_p)); } } - if (png_copy && pdf->minor_version > 1 + if (png_copy + && pdf->minor_version > 1 && png_get_interlace_type(png_p, info_p) == PNG_INTERLACE_NONE && (png_get_color_type(png_p, info_p) == PNG_COLOR_TYPE_GRAY - || png_get_color_type(png_p, info_p) == PNG_COLOR_TYPE_RGB) + || png_get_color_type(png_p, info_p) == PNG_COLOR_TYPE_RGB) && !pdf->image_apply_gamma - && (!png_get_valid(png_p, info_p, PNG_INFO_gAMA) - || int_file_gamma == PNG_FP_1) + && (!png_get_valid(png_p, info_p, PNG_INFO_gAMA) || int_file_gamma == PNG_FP_1) && !png_get_valid(png_p, info_p, PNG_INFO_cHRM) && !png_get_valid(png_p, info_p, PNG_INFO_iCCP) && !png_get_valid(png_p, info_p, PNG_INFO_sBIT) @@ -583,64 +589,63 @@ void write_png(PDF pdf, image_dict * idict) && !png_get_valid(png_p, info_p, PNG_INFO_sPLT)) { copy_png(pdf, idict); } else { - if (0) { - tex_printf(" *** PNG copy skipped because: "); + if (img_errorlevel(idict) > 1) { if (!png_copy) - tex_printf("!png_copy "); + normal_warning("pngcopy","failed"); if (!(pdf->minor_version > 1)) - tex_printf("minorversion=%d ", pdf->minor_version); + formatted_warning("pngcopy","skipped because minorversion is '%d'", pdf->minor_version); if (!(png_get_interlace_type(png_p, info_p) == PNG_INTERLACE_NONE)) - tex_printf("interlaced "); + normal_warning("pngcopy","skipped because of interlacing"); if (!((png_get_color_type(png_p, info_p) == PNG_COLOR_TYPE_GRAY) - || (png_get_color_type(png_p, info_p) == PNG_COLOR_TYPE_RGB))) - tex_printf("colortype "); + || (png_get_color_type(png_p, info_p) == PNG_COLOR_TYPE_RGB))) + normal_warning("pngcopy","skipped because of colortype"); if (pdf->image_apply_gamma) - tex_printf("apply gamma "); - if (!(!png_get_valid(png_p, info_p, PNG_INFO_gAMA) - || int_file_gamma == PNG_FP_1)) - tex_printf("gamma "); + normal_warning("pngcopy","skipped because of gamma (1)"); + if (!(!png_get_valid(png_p, info_p, PNG_INFO_gAMA) || int_file_gamma == PNG_FP_1)) + normal_warning("pngcopy","skipped because of gamma (2)"); if (png_get_valid(png_p, info_p, PNG_INFO_cHRM)) - tex_printf("cHRM "); + normal_warning("pngcopy","skipped because of cHRM"); if (png_get_valid(png_p, info_p, PNG_INFO_iCCP)) - tex_printf("iCCP "); + normal_warning("pngcopy","skipped because of iCCP"); if (png_get_valid(png_p, info_p, PNG_INFO_sBIT)) - tex_printf("sBIT "); + normal_warning("pngcopy","skipped because of sBIT"); if (png_get_valid(png_p, info_p, PNG_INFO_sRGB)) - tex_printf("sRGB "); + normal_warning("pngcopy","skipped because of sRGB"); if (png_get_valid(png_p, info_p, PNG_INFO_bKGD)) - tex_printf("bKGD "); + normal_warning("pngcopy","skipped because of bKGD"); if (png_get_valid(png_p, info_p, PNG_INFO_hIST)) - tex_printf("hIST "); + normal_warning("pngcopy","skipped because of hIST"); if (png_get_valid(png_p, info_p, PNG_INFO_tRNS)) - tex_printf("tRNS "); + normal_warning("pngcopy","skipped because of tRNS"); if (png_get_valid(png_p, info_p, PNG_INFO_sPLT)) - tex_printf("sPLT "); + normal_warning("pngcopy","skipped because of sPLT"); } switch (png_get_color_type(png_p, info_p)) { - case PNG_COLOR_TYPE_PALETTE: - case PNG_COLOR_TYPE_GRAY: - case PNG_COLOR_TYPE_RGB: - write_png_gray(pdf, idict); - break; - case PNG_COLOR_TYPE_GRAY_ALPHA: - if (pdf->minor_version >= 4) { - write_png_gray_alpha(pdf, idict); - last_png_needs_page_group = true; - } else + case PNG_COLOR_TYPE_PALETTE: + case PNG_COLOR_TYPE_GRAY: + case PNG_COLOR_TYPE_RGB: write_png_gray(pdf, idict); - break; - case PNG_COLOR_TYPE_RGB_ALPHA: - if (pdf->minor_version >= 4) { - write_png_rgb_alpha(pdf, idict); - last_png_needs_page_group = true; - } else - write_png_gray(pdf, idict); - break; - default: - assert(0); + break; + case PNG_COLOR_TYPE_GRAY_ALPHA: + if (pdf->minor_version >= 4) { + write_png_gray_alpha(pdf, idict); + last_png_needs_page_group = true; + } else + write_png_gray(pdf, idict); + break; + case PNG_COLOR_TYPE_RGB_ALPHA: + if (pdf->minor_version >= 4) { + write_png_rgb_alpha(pdf, idict); + last_png_needs_page_group = true; + } else + write_png_gray(pdf, idict); + break; + default: + assert(0); } } write_palette_streamobj(pdf, palette_objnum, palette, num_palette); + /* always */ close_and_cleanup_png(idict); } @@ -649,13 +654,15 @@ static boolean transparent_page_group_was_written = false; @ Called after the xobject generated by |write_png| has been finished; used to write out additional objects + @c void write_additional_png_objects(PDF pdf) { (void) pdf; (void) transparent_page_group; (void) transparent_page_group_was_written; - return; /* this interferes with current macro-based usage and cannot be configured */ + return; + /* this interferes with current macro-based usage and cannot be configured */ #if 0 if (last_png_needs_page_group) { if (!transparent_page_group_was_written && transparent_page_group > 1) { |