diff options
author | Taco Hoekwater <taco@elvenkind.com> | 2009-03-27 15:30:55 +0000 |
---|---|---|
committer | Taco Hoekwater <taco@elvenkind.com> | 2009-03-27 15:30:55 +0000 |
commit | 178de0871d690556af74f3768c11bc812b07f347 (patch) | |
tree | a939c31adc90d6207848effaec87dd78ec00e658 /Build/source/texk/web2c/luatexdir/image | |
parent | 4865b23b5199697829e4e6633f2f697b4634c462 (diff) |
Import of luatex 0.37.0 (autoreconf has not been run yet!)
git-svn-id: svn://tug.org/texlive/trunk@12529 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/web2c/luatexdir/image')
-rw-r--r-- | Build/source/texk/web2c/luatexdir/image/epdf.c | 42 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/image/epdf.h | 43 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/image/image.h | 81 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/image/pdftoepdf.cc | 333 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/image/writeimg.c | 496 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/image/writejbig2.c | 52 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/image/writejbig2.h | 32 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/image/writejpg.c | 36 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/image/writepng.c | 129 |
9 files changed, 818 insertions, 426 deletions
diff --git a/Build/source/texk/web2c/luatexdir/image/epdf.c b/Build/source/texk/web2c/luatexdir/image/epdf.c index 071181f17bd..05ba93fdcf2 100644 --- a/Build/source/texk/web2c/luatexdir/image/epdf.c +++ b/Build/source/texk/web2c/luatexdir/image/epdf.c @@ -1,32 +1,32 @@ -/* -Copyright (c) 1996-2002 Han The Thanh, <thanh@pdftex.org> +/* epdf.c + + Copyright 1996-2006 Han The Thanh <thanh@pdftex.org> + Copyright 2006-2008 Taco Hoekwater <taco@luatex.org> -This file is part of pdfTeX. + This file is part of LuaTeX. -pdfTeX is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. -pdfTeX is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. -You should have received a copy of the GNU General Public License -along with pdfTeX; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -$Id: epdf.c 1012 2008-02-14 00:00:57Z oneiros $ -*/ + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */ #include "ptexlib.h" - #include <kpathsea/c-vararg.h> #include <kpathsea/c-proto.h> #include <string.h> +static const char _svn_version[] = + "$Id: epdf.c 1407 2008-07-15 10:49:28Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/image/epdf.c $"; + extern void epdf_check_mem(void); extern void register_fd_entry(fd_entry *); @@ -37,7 +37,7 @@ int is_subsetable(fm_entry * fm) return is_subsetted(fm); } -fd_entry *epdf_create_fontdescriptor(fm_entry * fm) +fd_entry *epdf_create_fontdescriptor(fm_entry * fm, int stemV) { fd_entry *fd; if ((fd = lookup_fd_entry(fm->ff_name, fm->slant, fm->extend)) == NULL) { @@ -48,7 +48,9 @@ fd_entry *epdf_create_fontdescriptor(fm_entry * fm) fd->fd_objnum = pdf_new_objnum(); assert(fm->ps_name != NULL); fd->fontname = xstrdup(fm->ps_name); /* just fallback */ - /* preset_fontmetrics (fo->fd, f); */ + // stemV must be copied + fd->font_dim[STEMV_CODE].val = stemV; + fd->font_dim[STEMV_CODE].set = true; fd->gl_tree = avl_create(comp_string_entry, NULL, &avl_xallocator); assert(fd->gl_tree != NULL); } diff --git a/Build/source/texk/web2c/luatexdir/image/epdf.h b/Build/source/texk/web2c/luatexdir/image/epdf.h index 93a9e1c45eb..d079c4c98c4 100644 --- a/Build/source/texk/web2c/luatexdir/image/epdf.h +++ b/Build/source/texk/web2c/luatexdir/image/epdf.h @@ -1,24 +1,24 @@ -/* -Copyright (c) 1996-2006 Han The Thanh, <thanh@pdftex.org> +/* epdf.h + + Copyright 1996-2006 Han The Thanh <thanh@pdftex.org> + Copyright 2006-2008 Taco Hoekwater <taco@luatex.org> -This file is part of pdfTeX. + This file is part of LuaTeX. -pdfTeX is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. -pdfTeX is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. -You should have received a copy of the GNU General Public License -along with pdfTeX; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */ -$Id: epdf.h 1125 2008-03-25 19:36:52Z hhenkel $ -*/ +/* $Id: epdf.h 2073 2009-03-21 10:06:50Z hhenkel $ */ extern "C" { @@ -45,12 +45,13 @@ extern "C" { #include <web2c/luatexdir/ptexmac.h> #include "openbsd-compat.h" #include "image.h" -#include "../avlstuff.h" +#include "../utils/avlstuff.h" /* #-define pdfbufsize pdfbufmax */ extern integer epdf_page_box; extern void *epdf_xref; + extern integer epdf_lastGroupObjectNum; extern integer pdf_box_spec_media; extern integer pdf_box_spec_crop; @@ -58,14 +59,15 @@ extern "C" { extern integer pdf_box_spec_trim; extern integer pdf_box_spec_art; - extern integer pdf_stream_length; - extern integer pdf_ptr; + extern longinteger pdf_stream_length; + extern longinteger pdf_ptr; extern integer pool_ptr; typedef unsigned char eight_bits; extern eight_bits *pdf_buf; extern integer pdf_buf_size; extern integer pdf_os_mode; extern eight_bits pdf_last_byte; + extern integer fixed_inclusion_copy_font; extern char notdef[]; @@ -94,6 +96,7 @@ extern "C" { __attribute__ ((format(printf, 1, 2))) extern void tex_printf(const char *, ...); extern void write_epdf(image_dict *); + extern void write_additional_epdf_objects(void); extern void zpdf_begin_dict(integer, bool); extern void zpdf_begin_obj(integer, bool); extern void zpdf_create_obj(integer, integer); @@ -102,7 +105,7 @@ extern "C" { /* epdf.c */ extern void epdf_mark_glyphs(struct fd_entry *, char *); - extern struct fd_entry *epdf_create_fontdescriptor(struct fm_entry *); + extern struct fd_entry *epdf_create_fontdescriptor(struct fm_entry *, int); extern int get_fd_objnum(struct fd_entry *); extern int get_fn_objnum(struct fd_entry *); diff --git a/Build/source/texk/web2c/luatexdir/image/image.h b/Build/source/texk/web2c/luatexdir/image/image.h index 33f09274433..7d9bb8b0e00 100644 --- a/Build/source/texk/web2c/luatexdir/image/image.h +++ b/Build/source/texk/web2c/luatexdir/image/image.h @@ -1,23 +1,24 @@ -/* -Copyright (c) 1996-2002 Han The Thanh, <thanh@pdftex.org> +/* image.h + + Copyright 1996-2006 Han The Thanh <thanh@pdftex.org> + Copyright 2006-2008 Taco Hoekwater <taco@luatex.org> -This file is part of pdfTeX. -pdfTeX is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + This file is part of LuaTeX. -pdfTeX is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. -You should have received a copy of the GNU General Public License -along with pdfTeX; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. -$Id: image.h 1125 2008-03-25 19:36:52Z hhenkel $ -*/ + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */ + +/* $Id: image.h 1407 2008-07-15 10:49:28Z taco $ */ #ifndef IMAGE_H # define IMAGE_H @@ -34,6 +35,7 @@ $Id: image.h 1125 2008-03-25 19:36:52Z hhenkel $ extern integer zround(double); /* from zround.c */ # define bp2int(p) zround(p * (one_hundred_bp / 100.0)) +# define int2bp(i) (i * 100.0 / one_hundred_bp) # define TYPE_IMG "image" # define TYPE_IMG_DICT "image-dict" @@ -43,6 +45,10 @@ extern integer zround(double); /* from zround.c */ /**********************************************************************/ typedef struct { + char *stream; +} pdf_stream_struct; + +typedef struct { png_structp png_ptr; png_infop info_ptr; } png_img_struct; @@ -52,21 +58,21 @@ typedef struct { JPG_UINT32 length; /* length of file/data */ } jpg_img_struct; -#if 0 +# if 0 typedef struct { /* currently unused */ } jb2_img_struct; -#endif +# 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 */ + DICT_SCHEDULED, /* image dict scheduled for writing (PONR) */ DICT_WRITTEN /* image dict written to file */ } dict_state; -typedef enum { IMAGE_TYPE_NONE, IMAGE_TYPE_PDF, IMAGE_TYPE_PNG, IMAGE_TYPE_JPG, - IMAGE_TYPE_JBIG2, IMAGE_TYPE_SENTINEL +typedef enum { IMG_TYPE_NONE, IMG_TYPE_PDF, IMG_TYPE_PNG, IMG_TYPE_JPG, + IMG_TYPE_JBIG2, IMG_TYPE_PDFSTREAM, IMG_TYPE_SENTINEL } imgtype_e; typedef enum { IMG_KEEPOPEN, IMG_CLOSEINBETWEEN } img_readtype_e; @@ -87,7 +93,9 @@ typedef struct { integer y_orig; integer x_res; /* pixel resolution as in JPG/PNG/JBIG2 file */ integer y_res; + integer rotation; /* rotation (multiples of 90 deg.) for PDF files */ integer colorspace; /* number of /ColorSpace object */ + integer group_ref; /* if it's <=0, the page has no group */ integer total_pages; integer page_num; /* requested page (by number) */ char *pagename; /* requested page (by name) */ @@ -99,8 +107,11 @@ typedef struct { int color_space; /* used color space. See JPG_ constants */ int color_depth; /* color depth */ pdfboxspec_e page_box_spec; /* PDF page box spec.: media/crop/bleed/trim/art */ + integer bbox[4]; dict_state state; + integer flags; union { + pdf_stream_struct *pdfstream; png_img_struct *png; jpg_img_struct *jpg; /* jb2_img_struct *jb2; */ @@ -115,7 +126,9 @@ typedef struct { # 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) @@ -127,8 +140,12 @@ typedef struct { # define img_color(N) ((N)->color_space) # 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_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) @@ -138,6 +155,12 @@ typedef struct { # define img_jb2_ptr(N) ((N)->img_struct.jb2) +# define F_FLAG_BBOX (1 << 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) + /**********************************************************************/ typedef struct { @@ -147,6 +170,7 @@ typedef struct { integer transform; integer flags; image_dict *dict; + int array_idx; /* index within img_array */ int dict_ref; /* luaL_ref() reference */ } image; @@ -156,18 +180,17 @@ typedef struct { # define img_transform(N) ((N)->transform) # define img_flags(N) ((N)->flags) # define img_dict(N) ((N)->dict) +# define img_arrayidx(N) ((N)->array_idx) # define img_dictref(N) ((N)->dict_ref) -# define F_FLAG_SCALED 0x01 -# define F_FLAG_REFERED 0x02 +# define img_is_refered(N) (img_arrayidx(N) != -1) + +# define F_FLAG_SCALED (1 << 0) # define img_flags(N) ((N)->flags) # define img_set_scaled(N) (img_flags(N) |= F_FLAG_SCALED) -# define img_set_refered(N) (img_flags(N) |= F_FLAG_REFERED) # define img_unset_scaled(N) (img_flags(N) &= ~F_FLAG_SCALED) -# define img_unset_refered(N) (img_flags(N) &= ~F_FLAG_REFERED) # define img_is_scaled(N) ((img_flags(N) & F_FLAG_SCALED) != 0) -# define img_is_refered(N) ((img_flags(N) & F_FLAG_REFERED) != 0) # define set_wd_running(N) (img_width(N) = null_flag) # define set_ht_running(N) (img_height(N) = null_flag) @@ -180,6 +203,9 @@ typedef struct { /* writeimg.c */ +void new_img_pdfstream_struct(image_dict *); +void check_pdfstream_dict(image_dict *); +void write_pdfstream(image_dict *); image *new_image(); image_dict *new_image_dict(); void init_image(image *); @@ -206,6 +232,9 @@ void write_jpg(image_dict *); void write_jbig2(image_dict *); void write_epdf(image_dict *); +extern void write_additional_epdf_objects(void); +extern void write_additional_png_objects(void); + /* pdftoepdf.cc */ void unrefPdfDocument(char *); diff --git a/Build/source/texk/web2c/luatexdir/image/pdftoepdf.cc b/Build/source/texk/web2c/luatexdir/image/pdftoepdf.cc index 81b74369bb9..663e37d073b 100644 --- a/Build/source/texk/web2c/luatexdir/image/pdftoepdf.cc +++ b/Build/source/texk/web2c/luatexdir/image/pdftoepdf.cc @@ -1,24 +1,22 @@ -/* -Copyright 1996-2006 Han The Thanh, <thanh@pdftex.org> +/* pdftoepdf.cc + + Copyright 1996-2006 Han The Thanh <thanh@pdftex.org> + Copyright 2006-2008 Taco Hoekwater <taco@luatex.org> -This file is part of pdfTeX. + This file is part of LuaTeX. -pdfTeX is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. -pdfTeX is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. -You should have received a copy of the GNU General Public License -along with pdfTeX; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -$Id: pdftoepdf.cc 1129 2008-03-27 19:43:44Z hhenkel $ -*/ + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */ #include <stdlib.h> #include <math.h> @@ -46,24 +44,14 @@ $Id: pdftoepdf.cc 1129 2008-03-27 19:43:44Z hhenkel $ #include "epdf.h" +static const char _svn_version[] = + "$Id: pdftoepdf.cc 1539 2008-10-06 09:52:07Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/image/pdftoepdf.cc $"; + #define one_hundred_bp 6578176 /* 7227 * 65536 / 72 */ // This file is mostly C and not very much C++; it's just used to interface // the functions of xpdf, which happens to be written in C++. -// Used flags below: -// PDFTEX_COPY_PAGEGROUP -// If pdfTeX should copy a page group (a new feature in PDF 1.4 for -// transparency) of an included file. The current support for this is -// most likely broken. pdfTeX will at least give a warning if this flag -// is not set. Surprisingly Acrobat and Jaws display files without a -// page group correctly, so it might be safe to not set the flag. -// See also PDFTEX_COPY_PAGEGROUP_NOFAIL. -// PDFTEX_COPY_PAGEGROUP_NOFAIL -// If set to false, pdfTeX will treat a page group in an included file -// as an error and abort gracefully. This is only evaluated if -// PDFTEX_COPY_PAGEGROUP is set. - // The prefix "PTEX" for the PDF keys is special to pdfTeX; // this has been registered with Adobe by Hans Hagen. @@ -75,6 +63,7 @@ $Id: pdftoepdf.cc 1129 2008-03-27 19:43:44Z hhenkel $ // and &obj to get a pointer to the object. // It is no longer necessary to call Object::free explicitely. +/* *INDENT-OFF* */ class PdfObject { public: PdfObject() { // nothing @@ -94,6 +83,7 @@ class PdfObject { public: Object iObject; }; +/* *INDENT-ON* */ // When copying the Resources of the selected page, all objects are copied // recusively top-down. Indirect objects however are not fetched during @@ -123,6 +113,8 @@ static XRef *xref = NULL; static InObj *inObjList = NULL; static UsedEncoding *encodingList; static GBool isInit = gFalse; +static bool groupIsIndirect; +static PdfObject lastGroup; //********************************************************************** // Maintain AVL tree of open embedded PDF files @@ -290,13 +282,28 @@ static void copyName(char *s) pdf_puts("/"); for (; *s != 0; s++) { if (isdigit(*s) || isupper(*s) || islower(*s) || *s == '_' || - *s == '.' || *s == '-') + *s == '.' || *s == '-' || *s == '+') pdfout(*s); else pdf_printf("#%.2X", *s & 0xFF); } } +static int getNewObjectNumber(Ref ref) +{ + InObj *p; + if (inObjList == 0) { + pdftex_fail("No objects copied yet"); + } else { + for (p = inObjList; p != 0; p = p->next) { + if (p->ref.num == ref.num && p->ref.gen == ref.gen) { + return p->num; + } + } + pdftex_fail("Object not yet copied: %i %i", ref.num, ref.gen); + } +} + static void copyObject(Object *); static void copyDictEntry(Object * obj, int i) @@ -347,9 +354,10 @@ static void copyStream(Stream * str) { int c; str->reset(); - while ((c = str->getChar()) != EOF) + while ((c = str->getChar()) != EOF) { pdfout(c); - pdf_last_byte = pdf_buf[pdf_ptr - 1]; + pdf_last_byte = c; + } } static void copyProcSet(Object * obj) @@ -376,7 +384,7 @@ static void copyProcSet(Object * obj) static void copyFont(char *tag, Object * fontRef) { PdfObject fontdict, subtype, basefont, fontdescRef, fontdesc, charset, - fontfile, ffsubtype; + fontfile, ffsubtype, stemV; GfxFont *gfont; fd_entry *fd; fm_entry *fontmap; @@ -392,7 +400,7 @@ static void copyFont(char *tag, Object * fontRef) } // Only handle included Type1 (and Type1C) fonts; anything else will be copied. // Type1C fonts are replaced by Type1 fonts, if REPLACE_TYPE1C is true. - if (fixed_replace_font && fontRef->fetch(xref, &fontdict)->isDict() + if (!fixed_inclusion_copy_font && fontRef->fetch(xref, &fontdict)->isDict() && fontdict->dictLookup("Subtype", &subtype)->isName() && !strcmp(subtype->getName(), "Type1") && fontdict->dictLookup("BaseFont", &basefont)->isName() @@ -405,7 +413,9 @@ static void copyFont(char *tag, Object * fontRef) &ffsubtype)->isName() && !strcmp(ffsubtype->getName(), "Type1C"))) && (fontmap = lookup_fontmap(basefont->getName())) != NULL) { - fd = epdf_create_fontdescriptor(fontmap); + // copy the value of /StemV + fontdesc->dictLookup("StemV", &stemV); + fd = epdf_create_fontdescriptor(fontmap, stemV->getInt()); if (fontdesc->dictLookup("CharSet", &charset) && charset->isString() && is_subsetable(fontmap)) epdf_mark_glyphs(fd, charset->getString()->getCString()); @@ -579,16 +589,16 @@ static void copyObject(Object * obj) copyDict(&obj1); pdf_puts(">>\n"); pdf_puts("stream\n"); - copyStream(obj->getStream()->getBaseStream()); + copyStream(obj->getStream()->getUndecodedStream()); if (pdf_last_byte != '\n') pdf_puts("\n"); pdf_puts("endstream"); // can't simply write pdf_end_stream() } else if (obj->isRef()) { ref = obj->getRef(); if (ref.num == 0) { - pdftex_warn - ("PDF inclusion: reference to invalid object was replaced by <null>"); - pdf_puts("null"); + pdftex_fail + ("PDF inclusion: reference to invalid object" + " (is the included pdf broken?)"); } else pdf_printf("%d 0 R", addOther(ref)); } else { @@ -633,8 +643,9 @@ static void writeEncodings() for (r = encodingList; r != NULL; r = r->next) { for (i = 0; i < 256; i++) { if (r->font->isCIDFont()) { - pdftex_warn - ("PDF inclusion: CID font included, encoding maybe wrong"); + pdftex_fail + ("PDF inclusion: CID fonts are not supported" + " (try to disable font replacement to fix this)"); } if ((s = ((Gfx8BitFont *) r->font)->getCharName(i)) != NULL) glyphNames[i] = s; @@ -684,10 +695,9 @@ read_pdf_info(image_dict * idict, integer minor_pdf_version_wanted, Page *page; int rotate; PDFRectangle *pagebox; - float pdf_version_found, pdf_version_wanted, pdf_width, pdf_height, - pdf_xorig, pdf_yorig; + float pdf_version_found, pdf_version_wanted, xsize, ysize, xorig, yorig; assert(idict != NULL); - assert(img_type(idict) == IMAGE_TYPE_PDF); + assert(img_type(idict) == IMG_TYPE_PDF); // initialize if (isInit == gFalse) { globalParams = new GlobalParams(); @@ -733,49 +743,75 @@ read_pdf_info(image_dict * idict, integer minor_pdf_version_wanted, pdftex_fail("PDF inclusion: required page <%i> does not exist", (int) img_pagenum(idict)); } + pdf_doc->xref = pdf_doc->doc->getXRef(); // get the required page page = pdf_doc->doc->getCatalog()->getPage(img_pagenum(idict)); // get the pagebox (media, crop...) to use. pagebox = get_pagebox(page, img_pagebox(idict)); if (pagebox->x2 > pagebox->x1) { - pdf_xorig = pagebox->x1; - pdf_width = pagebox->x2 - pagebox->x1; + xorig = pagebox->x1; + xsize = pagebox->x2 - pagebox->x1; } else { - pdf_xorig = pagebox->x2; - pdf_width = pagebox->x1 - pagebox->x2; + xorig = pagebox->x2; + xsize = pagebox->x1 - pagebox->x2; } if (pagebox->y2 > pagebox->y1) { - pdf_yorig = pagebox->y1; - pdf_height = pagebox->y2 - pagebox->y1; + yorig = pagebox->y1; + ysize = pagebox->y2 - pagebox->y1; } else { - pdf_yorig = pagebox->y2; - pdf_height = pagebox->y1 - pagebox->y2; + yorig = pagebox->y2; + ysize = pagebox->y1 - pagebox->y2; } - + // The following 4 parameters are raw. Do _not_ modify by /Rotate! + img_xsize(idict) = bp2int(xsize); + img_ysize(idict) = bp2int(ysize); + img_xorig(idict) = bp2int(xorig); + img_yorig(idict) = bp2int(yorig); + + // Handle /Rotate parameter. Only multiples of 90 deg. are allowed + // (PDF Ref. v1.3, p. 78). rotate = page->getRotate(); - // handle page rotation and adjust dimens as needed - if (rotate != 0) { - // handle only the simple case: multiple of 90s. - // these are the only values allowed according to the - // reference (v1.3, p. 78). - // 180 needs no special treatment here - register float f; - switch (rotate % 360) { - case 90: - case 270: - f = pdf_height; - pdf_height = pdf_width; - pdf_width = f; - break; - default:; + 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: + pdftex_warn + ("PDF inclusion: " + "/Rotate parameter in PDF file not multiple of 90 degrees."); + } + if (page->getGroup() != NULL) { + initDictFromDict(lastGroup, page->getGroup()); + if (lastGroup->dictGetLength() > 0) { + groupIsIndirect = lastGroup->isRef(); + if (groupIsIndirect) { + // FIXME: Here we already copy the object. It would be + // better to do this only after write_epdf, otherwise we + // may copy ununsed /Group objects + copyObject(&lastGroup); + epdf_lastGroupObjectNum = + getNewObjectNumber(lastGroup->getRef()); + } else { + // make the group an indirect object; copying is done later + // by write_additional_epdf_objects after write_epdf + epdf_lastGroupObjectNum = pdf_new_objnum(); + } + pdf_puts("\n"); } + } else { + epdf_lastGroupObjectNum = 0; } - pdf_doc->xref = pdf_doc->doc->getXRef(); - img_xsize(idict) = bp2int(pdf_width); - img_ysize(idict) = bp2int(pdf_height); - img_xorig(idict) = bp2int(pdf_xorig); - img_yorig(idict) = bp2int(pdf_yorig); + } // Writes the current epf_doc. @@ -786,22 +822,19 @@ static void write_epdf1(image_dict * idict) { Page *page; PdfObject contents, obj1, obj2; - PdfObject group, metadata, pieceinfo, separationInfo; + PdfObject metadata, pieceinfo, separationInfo; Object info; char *key; char s[256]; int i, l; - int rotate; - double scale[6] = { 0, 0, 0, 0, 0, 0 }; - bool writematrix = false; PdfDocument *pdf_doc = (PdfDocument *) findPdfDocument(img_filepath(idict)); assert(pdf_doc != NULL); xref = pdf_doc->xref; inObjList = pdf_doc->inObjList; encodingList = NULL; page = pdf_doc->doc->getCatalog()->getPage(img_pagenum(idict)); - rotate = page->getRotate(); PDFRectangle *pagebox; + float bbox[4]; // write the Page header pdf_puts("/Type /XObject\n/Subtype /Form\n"); if (img_attr(idict) != NULL && strlen(img_attr(idict)) > 0) @@ -819,73 +852,35 @@ static void write_epdf1(image_dict * idict) pdf_printf("/%s.InfoDict ", pdfkeyprefix); pdf_printf("%d 0 R\n", addOther(info.getRef())); } - // get the pagebox (media, crop...) to use. - pagebox = get_pagebox(page, img_pagebox(idict)); - - // handle page rotation - if (rotate != 0) { - // this handles only the simple case: multiple of 90s but these - // are the only values allowed according to the reference - // (v1.3, p. 78). - // the image is rotated around its center. - // the /Rotate key is clockwise while the matrix is - // counterclockwise :-% - tex_printf(", page is rotated %d degrees", rotate); - switch (rotate % 360) { - case 90: - scale[1] = -1; - scale[2] = 1; - scale[4] = pagebox->x1 - pagebox->y1; - scale[5] = pagebox->y1 + pagebox->x2; - writematrix = true; - break; - case 180: - scale[0] = scale[3] = -1; - scale[4] = pagebox->x1 + pagebox->x2; - scale[5] = pagebox->y1 + pagebox->y2; - writematrix = true; - break; // width and height are exchanged - case 270: - scale[1] = 1; - scale[2] = -1; - scale[4] = pagebox->x1 + pagebox->y2; - scale[5] = pagebox->y1 - pagebox->x1; - writematrix = true; - break; - default:; - } - if (writematrix) { // The matrix is only written if the image is rotated. - sprintf(s, "/Matrix [%.8f %.8f %.8f %.8f %.8f %.8f]\n", - scale[0], scale[1], scale[2], scale[3], scale[4], scale[5]); - pdf_printf(stripzeros(s)); - } + if (img_is_bbox(idict)) { + bbox[0] = int2bp(img_bbox(idict)[0]); + bbox[1] = int2bp(img_bbox(idict)[1]); + bbox[2] = int2bp(img_bbox(idict)[2]); + bbox[3] = int2bp(img_bbox(idict)[3]); + } else { + // get the pagebox (media, crop...) to use. + pagebox = get_pagebox(page, img_pagebox(idict)); + bbox[0] = pagebox->x1; + bbox[1] = pagebox->y1; + bbox[2] = pagebox->x2; + bbox[3] = pagebox->y2; } - - sprintf(s, "/BBox [%.8f %.8f %.8f %.8f]\n", - pagebox->x1, pagebox->y1, pagebox->x2, pagebox->y2); - pdf_printf(stripzeros(s)); + sprintf(s, "/BBox [%.8f %.8f %.8f %.8f]\n", bbox[0], bbox[1], bbox[2], + bbox[3]); + pdf_puts(stripzeros(s)); + // The /Matrix calculation is replaced by transforms in out_img(). // write the page Group if it's there - if (page->getGroup() != NULL) { -#if PDFTEX_COPY_PAGEGROUP -# if PDFTEX_COPY_PAGEGROUP_NOFAIL - // FIXME: This will most likely produce incorrect PDFs :-( - initDictFromDict(group, page->getGroup()); - if (group->dictGetLength() > 0) { + if (epdf_lastGroupObjectNum > 0) { + if (page->getGroup() != NULL) { + initDictFromDict(lastGroup, page->getGroup()); + if (lastGroup->dictGetLength() > 0) { pdf_puts("/Group "); - copyObject(&group); + groupIsIndirect = lastGroup->isRef(); + pdf_printf("%d 0 R", epdf_lastGroupObjectNum); pdf_puts("\n"); } -# else - // FIXME: currently we don't know how to handle Page Groups so we abort gracefully :-( - pdftex_fail - ("PDF inclusion: Page Group detected which luatex can't handle. Sorry."); -# endif -#else - // FIXME: currently we don't know how to handle Page Groups so we at least give a warning :-( - pdftex_warn - ("PDF inclusion: Page Group detected which luatex can't handle. Ignoring it."); -#endif + } } // write the page Metadata if it's there if (page->getMetadata() != NULL) { @@ -903,6 +898,11 @@ static void write_epdf1(image_dict * idict) pdf_puts("\n"); } } + // copy LastModified (needed when PieceInfo is there) + if (page->getLastModified() != NULL) { + pdf_printf("/LastModified (%s)\n", + page->getLastModified()->getCString()); + } // write the page SeparationInfo if it's there if (page->getSeparationInfo() != NULL) { initDictFromDict(separationInfo, page->getSeparationInfo()); @@ -915,13 +915,10 @@ static void write_epdf1(image_dict * idict) // write the Resources dictionary if (page->getResourceDict() == NULL) { // Resources can be missing (files without them have been spotted - // in the wild). This violates the PDF Ref., which claims they are - // required, but all RIPs accept them. - // We "replace" them with empty /Resources, although in form xobjects - // /Resources are not required. + // in the wild); in which case the /Resouces of the /Page will be used. + // "This practice is not recommended". pdftex_warn - ("PDF inclusion: no /Resources detected. Replacing with empty /Resources."); - pdf_puts("/Resources <<>>\n"); + ("PDF inclusion: /Resources missing. 'This practice is not recommended' (PDF Ref)"); } else { initDictFromDict(obj1, page->getResourceDict()); page->getResourceDict()->incRef(); @@ -944,9 +941,36 @@ static void write_epdf1(image_dict * idict) // write the page contents page->getContents(&contents); if (contents->isStream()) { - initDictFromDict(obj1, contents->streamGetDict()); - contents->streamGetDict()->incRef(); - copyDict(&obj1); + // Variant A: get stream and recompress under control + // of \pdfcompresslevel + // + // pdfbeginstream(); + // copyStream(contents->getStream()); + // pdfendstream(); + + // Variant B: copy stream without recompressing + // + contents->streamGetDict()->lookup("F", &obj1); + if (!obj1->isNull()) { + pdftex_fail("PDF inclusion: Unsupported external stream"); + } + contents->streamGetDict()->lookup("Length", &obj1); + assert(!obj1->isNull()); + pdf_puts("/Length "); + copyObject(&obj1); + pdf_puts("\n"); + contents->streamGetDict()->lookup("Filter", &obj1); + if (!obj1->isNull()) { + pdf_puts("/Filter "); + copyObject(&obj1); + pdf_puts("\n"); + contents->streamGetDict()->lookup("DecodeParms", &obj1); + if (!obj1->isNull()) { + pdf_puts("/DecodeParms "); + copyObject(&obj1); + pdf_puts("\n"); + } + } pdf_puts(">>\nstream\n"); copyStream(contents->getStream()->getBaseStream()); pdf_end_stream(); @@ -1013,3 +1037,14 @@ void epdf_check_mem() delete globalParams; isInit = gFalse; } + +// Called after the xobject generated by write_epdf has been finished; used to +// write out objects that have been made indirect +void write_additional_epdf_objects(void) +{ + if ((epdf_lastGroupObjectNum > 0) && !groupIsIndirect) { + zpdf_begin_obj(epdf_lastGroupObjectNum, 2); + copyObject(&lastGroup); + pdf_end_obj(); + } +} diff --git a/Build/source/texk/web2c/luatexdir/image/writeimg.c b/Build/source/texk/web2c/luatexdir/image/writeimg.c index 79c3445945d..b105f507b42 100644 --- a/Build/source/texk/web2c/luatexdir/image/writeimg.c +++ b/Build/source/texk/web2c/luatexdir/image/writeimg.c @@ -1,24 +1,22 @@ -/* -Copyright (c) 1996-2002, 2005 Han The Thanh, <thanh@pdftex.org> +/* writeimg.c + + Copyright 1996-2006 Han The Thanh <thanh@pdftex.org> + Copyright 2006-2008 Taco Hoekwater <taco@luatex.org> -This file is part of pdfTeX. -pdfTeX is free software; -you can redistribute it and / or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + This file is part of LuaTeX. -pdfTeX is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. -You should have received a copy of the GNU General Public License -along with pdfTeX; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. -$Id: writeimg.c 1152 2008-04-13 22:29:59Z hhenkel $ -*/ + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */ #include <assert.h> #include "ptexlib.h" @@ -30,8 +28,13 @@ $Id: writeimg.c 1152 2008-04-13 22:29:59Z hhenkel $ #include <../lua51/lua.h> #include <../lua51/lauxlib.h> +static const char _svn_version[] = + "$Id: writeimg.c 2019 2009-03-14 00:15:58Z hhenkel $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/image/writeimg.c $"; + extern void pdf_print_real(integer m, integer d); +extern pdfstructure *pstruct; + #define obj_aux(A) obj_tab[(A)].int4 /**********************************************************************/ @@ -104,9 +107,9 @@ extern void pdf_print_real(integer m, integer d); standard extension. Functions "check_type_by_header" and "check_type_by_extension": - img_type(img) is set to IMAGE_TYPE_NONE by new_image_dict(). + 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 IMAGE_TYPE_NONE indicates that a + Thus a value other than IMG_TYPE_NONE indicates that a type has been found. */ @@ -116,6 +119,8 @@ extern void pdf_print_real(integer m, integer d); #define HEADER_PDF "%PDF-1." #define MAX_HEADER (sizeof(HEADER_PNG)-1) +integer epdf_lastGroupObjectNum; + static void check_type_by_header(image_dict * idict) { int i; @@ -123,7 +128,7 @@ static void check_type_by_header(image_dict * idict) char header[MAX_HEADER]; assert(idict != NULL); - if (img_type(idict) != IMAGE_TYPE_NONE) /* nothing to do */ + if (img_type(idict) != IMG_TYPE_NONE) /* nothing to do */ return; /* read the header */ file = xfopen(img_filepath(idict), FOPEN_RBIN_MODE); @@ -135,13 +140,13 @@ static void check_type_by_header(image_dict * idict) xfclose(file, img_filepath(idict)); /* tests */ if (strncmp(header, HEADER_JPG, sizeof(HEADER_JPG) - 1) == 0) - img_type(idict) = IMAGE_TYPE_JPG; + img_type(idict) = IMG_TYPE_JPG; else if (strncmp(header, HEADER_PNG, sizeof(HEADER_PNG) - 1) == 0) - img_type(idict) = IMAGE_TYPE_PNG; + img_type(idict) = IMG_TYPE_PNG; else if (strncmp(header, HEADER_JBIG2, sizeof(HEADER_JBIG2) - 1) == 0) - img_type(idict) = IMAGE_TYPE_JBIG2; + img_type(idict) = IMG_TYPE_JBIG2; else if (strncmp(header, HEADER_PDF, sizeof(HEADER_PDF) - 1) == 0) - img_type(idict) = IMAGE_TYPE_PDF; + img_type(idict) = IMG_TYPE_PDF; } static void check_type_by_extension(image_dict * idict) @@ -149,21 +154,31 @@ static void check_type_by_extension(image_dict * idict) char *image_suffix; assert(idict != NULL); - if (img_type(idict) != IMAGE_TYPE_NONE) /* nothing to do */ + if (img_type(idict) != IMG_TYPE_NONE) /* nothing to do */ return; /* tests */ if ((image_suffix = strrchr(img_filename(idict), '.')) == 0) - img_type(idict) = IMAGE_TYPE_NONE; + img_type(idict) = IMG_TYPE_NONE; else if (strcasecmp(image_suffix, ".png") == 0) - img_type(idict) = IMAGE_TYPE_PNG; + img_type(idict) = IMG_TYPE_PNG; else if (strcasecmp(image_suffix, ".jpg") == 0 || strcasecmp(image_suffix, ".jpeg") == 0) - img_type(idict) = IMAGE_TYPE_JPG; + img_type(idict) = IMG_TYPE_JPG; else if (strcasecmp(image_suffix, ".jbig2") == 0 || strcasecmp(image_suffix, ".jb2") == 0) - img_type(idict) = IMAGE_TYPE_JBIG2; + img_type(idict) = IMG_TYPE_JBIG2; else if (strcasecmp(image_suffix, ".pdf") == 0) - img_type(idict) = IMAGE_TYPE_PDF; + img_type(idict) = IMG_TYPE_PDF; +} + +/**********************************************************************/ + +void new_img_pdfstream_struct(image_dict * p) +{ + assert(p != NULL); + assert(img_pdfstream_ptr(p) == NULL); + img_pdfstream_ptr(p) = xtalloc(1, pdf_stream_struct); + img_pdfstream_stream(p) = NULL; } /**********************************************************************/ @@ -176,9 +191,9 @@ void init_image(image * p) set_dp_running(p); img_transform(p) = 0; img_flags(p) = 0; - img_unset_refered(p); /* wd/ht/dp may be modified */ img_unset_scaled(p); img_dict(p) = NULL; + img_arrayidx(p) = -1; /* -1 = unused, used count from 0 */ img_dictref(p) = LUA_NOREF; } @@ -200,7 +215,9 @@ void init_image_dict(image_dict * p) img_yorig(p) = 0; img_xres(p) = 0; img_yres(p) = 0; + img_rotation(p) = 0; img_colorspace(p) = 0; + img_group_ref(p) = 0; img_totalpages(p) = 0; img_pagenum(p) = 1; img_pagename(p) = NULL; @@ -208,10 +225,15 @@ void init_image_dict(image_dict * p) img_filepath(p) = NULL; img_attr(p) = NULL; img_file(p) = NULL; - img_type(p) = IMAGE_TYPE_NONE; + img_type(p) = IMG_TYPE_NONE; img_color(p) = 0; img_colordepth(p) = 0; img_pagebox(p) = PDF_BOX_SPEC_MEDIA; + img_bbox(p)[0] = 0; + img_bbox(p)[1] = 0; + img_bbox(p)[2] = 0; + img_bbox(p)[3] = 0; + img_unset_bbox(p); img_state(p) = DICT_NEW; img_png_ptr(p) = NULL; /* union */ } @@ -240,21 +262,31 @@ void free_dict_strings(image_dict * p) } void free_image_dict(image_dict * p) -{ /* called from limglib.c */ +{ + if (ini_version) + return; /* The image may be \dump{}ed to a format */ + /* called from limglib.c */ assert(img_state(p) < DICT_REFERED); switch (img_type(p)) { - case IMAGE_TYPE_PDF: + case IMG_TYPE_PDF: unrefPdfDocument(img_filepath(p)); break; - case IMAGE_TYPE_PNG: /* assuming IMG_CLOSEINBETWEEN */ + case IMG_TYPE_PNG: /* assuming IMG_CLOSEINBETWEEN */ assert(img_png_ptr(p) == NULL); break; - case IMAGE_TYPE_JPG: /* assuming IMG_CLOSEINBETWEEN */ + case IMG_TYPE_JPG: /* assuming IMG_CLOSEINBETWEEN */ assert(img_jpg_ptr(p) == NULL); break; - case IMAGE_TYPE_JBIG2: /* todo: writejbig2.c cleanup */ + case IMG_TYPE_JBIG2: /* todo: writejbig2.c cleanup */ break; - case IMAGE_TYPE_NONE: + case IMG_TYPE_PDFSTREAM: + if (img_pdfstream_ptr(p) != NULL) { + if (img_pdfstream_stream(p) != NULL) + xfree(img_pdfstream_stream(p)); + xfree(img_pdfstream_ptr(p)); + } + break; + case IMG_TYPE_NONE: break; default: assert(0); @@ -293,21 +325,23 @@ void read_img(image_dict * idict, integer pdf_minor_version, } if (img_filepath(idict) == NULL) pdftex_fail("cannot find image file"); + recorder_record_input(img_filename(idict)); /* type checks */ check_type_by_header(idict); check_type_by_extension(idict); /* read image */ switch (img_type(idict)) { - case IMAGE_TYPE_PDF: + case IMG_TYPE_PDF: read_pdf_info(idict, pdf_minor_version, pdf_inclusion_errorlevel); + img_group_ref(idict) = epdf_lastGroupObjectNum; break; - case IMAGE_TYPE_PNG: + case IMG_TYPE_PNG: read_png_info(idict, IMG_CLOSEINBETWEEN); break; - case IMAGE_TYPE_JPG: + case IMG_TYPE_JPG: read_jpg_info(idict, IMG_CLOSEINBETWEEN); break; - case IMAGE_TYPE_JBIG2: + case IMG_TYPE_JBIG2: if (pdf_minor_version < 4) { pdftex_fail ("JBIG2 images only possible with at least PDF 1.4; you are generating PDF 1.%i", @@ -316,42 +350,56 @@ void read_img(image_dict * idict, integer pdf_minor_version, read_jbig2_info(idict); break; default: - pdftex_fail("internal error: unknown image type"); + pdftex_fail("internal error: unknown image type (2)"); } cur_file_name = NULL; if (img_state(idict) < DICT_FILESCANNED) img_state(idict) = DICT_FILESCANNED; } +// Within scale_img() only image width and height matter; +// the offsets and positioning are not interesting here. +// But one needs rotation info to swap width and height. +// img_rotation() comes from the optional /Rotate key in the PDF file. + void scale_img(image * img) { - integer x, y, xr, yr; /* size and resolution of image */ - scaled w, h; /* indeed size corresponds to image resolution */ + integer x, y, xr, yr, tmp; /* size and resolution of image */ + scaled w = 0, h = 0; /* indeed size corresponds to image resolution */ integer default_res; image_dict *idict; assert(img != NULL); idict = img_dict(img); assert(idict != NULL); - x = img_xsize(idict); /* dimensions, resolutions from image file */ - y = img_ysize(idict); + if ((img_type(idict) == IMG_TYPE_PDF + || img_type(idict) == IMG_TYPE_PDFSTREAM) && img_is_bbox(idict)) { + x = img_xsize(idict) = img_bbox(idict)[2] - img_bbox(idict)[0]; /* dimensions from image.bbox */ + y = img_ysize(idict) = img_bbox(idict)[3] - img_bbox(idict)[1]; + img_xorig(idict) = img_bbox(idict)[0]; + img_yorig(idict) = img_bbox(idict)[1]; + } else { + x = img_xsize(idict); /* dimensions, resolutions from image file */ + y = img_ysize(idict); + } xr = img_xres(idict); yr = img_yres(idict); - if ((img_transform(img) & 1) == 1) { - int tmp = x; + if (x <= 0 || y <= 0 || xr < 0 || yr < 0) + pdftex_fail("ext1: invalid image dimensions"); + if (xr > 65535 || yr > 65535) { + xr = 0; + yr = 0; + pdftex_warn("ext1: too large image resolution ignored"); + } + if (((img_transform(img) - img_rotation(idict)) & 1) == 1) { + tmp = x; x = y; y = tmp; tmp = xr; xr = yr; yr = tmp; } - if (xr > 65535 || yr > 65535) { - xr = 0; - yr = 0; - pdftex_warn("ext1: too large image resolution ignored"); - } - if (x <= 0 || y <= 0 || xr < 0 || yr < 0) - pdftex_fail("ext1: invalid image dimensions"); - if (img_type(idict) == IMAGE_TYPE_PDF) { + if (img_type(idict) == IMG_TYPE_PDF + || img_type(idict) == IMG_TYPE_PDFSTREAM) { w = x; h = y; } else { @@ -410,41 +458,50 @@ void scale_img(image * img) img_set_scaled(img); } -void out_img(image * img, scaled hpos, scaled vpos) +void out_img(image * img, pdfstructure * p, scaledpos * pos) { float a[6]; /* transformation matrix */ float xoff, yoff, tmp; int r; /* number of digits after the decimal point */ - image_dict *idict; + int k; scaled wd, ht, dp; + scaledpos tmppos; + pdffloat cm[6]; + image_dict *idict; + integer groupref; /* added from web for 1.40.8 */ assert(img != 0); idict = img_dict(img); assert(idict != 0); wd = img_width(img); ht = img_height(img); dp = img_depth(img); - if ((img_transform(img) & 1) == 1) { /* 90 deg. or 270 deg. rotated */ - if (ht == -dp) - pdftex_fail("image transform: division by zero (height == -depth)"); - if (wd == 0) - pdftex_fail("image transform: division by zero (width == 0)"); - } + a[0] = a[3] = 1.0e6; a[1] = a[2] = 0; - if (img_type(idict) == IMAGE_TYPE_PDF) { - a[0] = 1.0e6 / img_xsize(idict); - a[3] = 1.0e6 / img_ysize(idict); + if (img_type(idict) == IMG_TYPE_PDF + || img_type(idict) == IMG_TYPE_PDFSTREAM) { + a[0] /= img_xsize(idict); + a[3] /= img_ysize(idict); + xoff = (float) img_xorig(idict) / img_xsize(idict); + yoff = (float) img_yorig(idict) / img_ysize(idict); r = 6; } else { - a[3] = a[0] = 1.0e6 / one_hundred_bp; + /* added from web for 1.40.8 */ + if (img_type(idict) == IMG_TYPE_PNG) { + groupref = img_group_ref(idict); + if ((groupref > 0) && (pdf_page_group_val < 1)) + pdf_page_group_val = groupref; + } + /* /added from web */ + a[0] /= one_hundred_bp; + a[3] = a[0]; + xoff = yoff = 0; r = 4; } - xoff = (float) img_xorig(idict) / img_xsize(idict); - yoff = (float) img_yorig(idict) / img_ysize(idict); - if ((img_transform(img) & 7) > 3) { /* mirrored */ + if ((img_transform(img) & 7) > 3) { // mirror cases a[0] *= -1; xoff *= -1; } - switch (img_transform(img) & 3) { + switch ((img_transform(img) + img_rotation(idict)) & 3) { case 0: /* no transform */ break; case 1: /* rot. 90 deg. (counterclockwise) */ @@ -477,41 +534,42 @@ void out_img(image * img, scaled hpos, scaled vpos) a[1] *= ht + dp; a[2] *= wd; a[3] *= ht + dp; - a[4] = hpos - xoff; - a[5] = vpos - yoff; - switch (img_transform(img) & 7) { + a[4] = pos->h - xoff; + a[5] = pos->v - yoff; + k = img_transform(img) + img_rotation(idict); + if ((img_transform(img) & 7) > 3) + k++; + switch (k & 3) { case 0: /* no transform */ - case 7: /* mirrored, then rot. 270 deg. */ break; case 1: /* rot. 90 deg. (counterclockwise) */ - case 4: /* mirrored, unrotated */ a[4] += wd; break; case 2: /* rot. 180 deg. */ - case 5: /* mirrored, then rot. 90 deg. */ a[4] += wd; a[5] += ht + dp; break; case 3: /* rot. 270 deg. */ - case 6: /* mirrored, then rot. 180 deg. */ a[5] += ht + dp; break; default:; } - pdf_end_text(); + /* the following is a kludge, TODO: use pdfpage.c functions */ + setpdffloat(cm[0], round(a[0]), r); + setpdffloat(cm[1], round(a[1]), r); + setpdffloat(cm[2], round(a[2]), r); + setpdffloat(cm[3], round(a[3]), r); + tmppos.h = round(a[4]); + tmppos.v = round(a[5]); + (void) calc_pdfpos(p, &tmppos); + cm[4] = p->cm[4]; + cm[5] = p->cm[5]; + pdf_goto_pagemode(); + if (pdf_page_group_val < 1) + pdf_page_group_val = img_group_ref(idict); /* added from web for 1.40.8 */ pdf_printf("q\n"); - pdf_print_real((integer) a[0], r); - pdfout(' '); - pdf_print_real((integer) a[1], r); - pdfout(' '); - pdf_print_real((integer) a[2], r); - pdfout(' '); - pdf_print_real((integer) a[3], r); - pdfout(' '); - pdf_print_bp((integer) a[4]); - pdfout(' '); - pdf_print_bp((integer) a[5]); - pdf_printf(" cm\n/Im"); + pdf_print_cm(cm); + pdf_printf("/Im"); pdf_print_int(img_index(idict)); pdf_print_resname_prefix(); pdf_printf(" Do\nQ\n"); @@ -526,23 +584,34 @@ void write_img(image_dict * idict) if (tracefilenames) tex_printf(" <%s", img_filepath(idict)); switch (img_type(idict)) { - case IMAGE_TYPE_PNG: + case IMG_TYPE_PNG: write_png(idict); break; - case IMAGE_TYPE_JPG: + case IMG_TYPE_JPG: write_jpg(idict); break; - case IMAGE_TYPE_JBIG2: + case IMG_TYPE_JBIG2: write_jbig2(idict); break; - case IMAGE_TYPE_PDF: + case IMG_TYPE_PDF: write_epdf(idict); + epdf_lastGroupObjectNum = img_group_ref(idict); + break; + case IMG_TYPE_PDFSTREAM: + write_pdfstream(idict); break; default: - pdftex_fail("internal error: unknown image type"); + pdftex_fail("internal error: unknown image type (1)"); } if (tracefilenames) tex_printf(">"); + if (img_type(idict) == IMG_TYPE_PDF) { + write_additional_epdf_objects(); + } else { + if (img_type(idict) == IMG_TYPE_PNG) { + write_additional_png_objects(); + } + } } if (img_state(idict) < DICT_WRITTEN) img_state(idict) = DICT_WRITTEN; @@ -550,9 +619,41 @@ void write_img(image_dict * idict) /**********************************************************************/ +void check_pdfstream_dict(image_dict * idict) +{ + if (!img_is_bbox(idict)) + pdftex_fail("image.stream: no bbox given"); + if (img_state(idict) < DICT_FILESCANNED) + img_state(idict) = DICT_FILESCANNED; +} + +void write_pdfstream(image_dict * idict) +{ + char s[256]; + assert(img_pdfstream_ptr(idict) != NULL); + assert(img_is_bbox(idict)); + pdf_puts("/Type /XObject\n/Subtype /Form\n"); + if (img_attr(idict) != NULL && strlen(img_attr(idict)) > 0) + pdf_printf("%s\n", img_attr(idict)); + pdf_puts("/FormType 1\n"); + sprintf(s, "/BBox [%.8f %.8f %.8f %.8f]\n", int2bp(img_bbox(idict)[0]), + int2bp(img_bbox(idict)[1]), int2bp(img_bbox(idict)[2]), + int2bp(img_bbox(idict)[3])); + pdf_printf(stripzeros(s)); + pdf_begin_stream(); + if (img_pdfstream_stream(idict) != NULL) + pdf_puts(img_pdfstream_stream(idict)); + pdf_end_stream(); +} + +/**********************************************************************/ + typedef image *img_entry; /* define img_ptr, img_array, & img_limit */ -define_array(img); /* array of pointers to image structures */ +/* avoid use of size_t */ +img_entry *img_ptr, *img_array = NULL; +integer img_limit; + integer img_to_array(image * img) { @@ -562,20 +663,168 @@ integer img_to_array(image * img) return img_ptr++ - img_array; /* now img is read-only */ } + + +/**********************************************************************/ + +/* To allow the use of \pdfrefximage 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. + * + * Most of the work involved in setting up the images is simply + * executed again. This solves the many possible errors resulting from + * 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. + */ + +/* some of the dumped values are really type int, not integer, + * but since the macro falls back to generic_dump anyway, that + * does not matter. + */ + +#define dumpinteger generic_dump +#define undumpinteger generic_undump + +/* (un)dumping a string means dumping the allocation size, followed + * by the bytes. The trailing \0 is dumped as well, because that + * makes the code simpler. + */ + +#define dumpcharptr(a) \ + do { \ + integer x; \ + if (a!=NULL) { \ + x = strlen(a)+1; \ + dumpinteger(x); dump_things(*a, x); \ + } else { \ + x = 0; dumpinteger(x); \ + } \ + } while (0) + +#define undumpcharptr(s) \ + do { \ + integer x; \ + char *a; \ + undumpinteger (x); \ + if (x>0) { \ + a = malloc(x); \ + undump_things(*a,x); \ + s = a ; \ + } else { s = NULL; } \ + } while (0) + + + +void dumpimagemeta(void) +{ + int cur_image, i; + image *img; + image_dict *idict; + + dumpinteger(img_limit); + cur_image = (img_ptr - img_array); + dumpinteger(cur_image); + + for (i = 0; i < cur_image; i++) { + img = img_array[i]; + assert(img != NULL); + idict = img_dict(img); + dumpcharptr(img_filename(idict)); + dumpinteger(img_type(idict)); + dumpinteger(img_color(idict)); + dumpinteger(img_width(img)); + dumpinteger(img_height(img)); + dumpinteger(img_xres(idict)); + dumpinteger(img_yres(idict)); + dumpinteger(img_totalpages(idict)); + dumpinteger(img_colorspace(idict)); + dumpinteger(img_group_ref(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) { + dumpinteger(img_pagebox(idict)); + dumpinteger(img_pagenum(idict)); + } else if (img_type(idict) == IMG_TYPE_JBIG2) { + dumpinteger(img_pagenum(idict)); + } + + } +} + +void undumpimagemeta(integer pdfversion, integer pdfinclusionerrorlevel) +{ + int cur_image, i; + image *img; + image_dict *idict; + + undumpinteger(img_limit); + + img_array = xtalloc(img_limit, img_entry); + undumpinteger(cur_image); + img_ptr = img_array + cur_image; + + for (i = 0; i < cur_image; i++) { + img = new_image(); + assert(img_arrayidx(img) == -1); + img_arrayidx(img) = img_to_array(img); + idict = img_dict(img) = new_image_dict(); + assert(idict != NULL); + undumpcharptr(img_filename(idict)); + undumpinteger(img_type(idict)); + undumpinteger(img_color(idict)); + undumpinteger(img_width(img)); + undumpinteger(img_height(img)); + undumpinteger(img_xres(idict)); + undumpinteger(img_yres(idict)); + undumpinteger(img_totalpages(idict)); + undumpinteger(img_colorspace(idict)); + undumpinteger(img_group_ref(idict)); + + switch (img_type(idict)) { + case IMG_TYPE_PDF: + undumpinteger(img_pagebox(idict)); + undumpinteger(img_pagenum(idict)); + break; + case IMG_TYPE_PNG: + break; + case IMG_TYPE_JPG: + break; + case IMG_TYPE_JBIG2: + if (pdfversion < 4) { + pdftex_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: + pdftex_fail("unknown type of image"); + } + read_img(idict, pdfversion, pdfinclusionerrorlevel); + } +} + + + + /**********************************************************************/ /* stuff to be accessible from TeX */ integer read_image(integer objnum, integer index, strnumber filename, - integer page_num, - strnumber attr, - strnumber page_name, + integer page_num, strnumber page_name, strnumber attr, integer colorspace, integer page_box, integer pdf_minor_version, integer pdf_inclusion_errorlevel) { - integer ref; - image *a = new_image(); image_dict *idict; - ref = img_to_array(a); + image *a = new_image(); + assert(img_arrayidx(a) == -1); + img_arrayidx(a) = img_to_array(a); idict = img_dict(a) = new_image_dict(); assert(idict != NULL); img_objnum(idict) = objnum; @@ -594,8 +843,7 @@ integer read_image(integer objnum, integer index, strnumber filename, img_pagebox(idict) = page_box; read_img(idict, pdf_minor_version, pdf_inclusion_errorlevel); img_unset_scaled(a); - img_set_refered(a); - return ref; + return img_arrayidx(a); } void set_image_dimensions(integer ref, integer wd, integer ht, integer dp) @@ -613,8 +861,11 @@ void scale_image(integer ref) void out_image(integer ref, scaled hpos, scaled vpos) { + scaledpos pos; + pos.h = hpos; + pos.v = vpos; image *a = img_array[ref]; - out_img(a, hpos, vpos); + out_img(a, pstruct, &pos); } void write_image(integer ref) @@ -632,6 +883,24 @@ integer image_colordepth(integer ref) return img_colordepth(img_dict(img_array[ref])); } +integer image_group_ref(integer ref) +{ + return img_group_ref(img_dict(img_array[ref])); +} + + +/* The following five functions are for \pdfximagebbox */ + +integer epdf_xsize(integer ref) +{ + return img_xsize(img_dict(img_array[ref])); +} + +integer epdf_ysize(integer ref) +{ + return img_ysize(img_dict(img_array[ref])); +} + integer epdf_orig_x(integer ref) { return img_xorig(img_dict(img_array[ref])); @@ -642,6 +911,17 @@ integer epdf_orig_y(integer ref) return img_yorig(img_dict(img_array[ref])); } +boolean is_pdf_image(integer ref) +{ + return img_type(img_dict(img_array[ref])) == IMG_TYPE_PDF; +} + +boolean is_png_image(integer ref) +{ + return img_type(img_dict(img_array[ref])) == IMG_TYPE_PNG; +} + + integer image_objnum(integer ref) { return img_objnum(img_dict(img_array[ref])); diff --git a/Build/source/texk/web2c/luatexdir/image/writejbig2.c b/Build/source/texk/web2c/luatexdir/image/writejbig2.c index 2d7d4560548..c2f01d1bfca 100644 --- a/Build/source/texk/web2c/luatexdir/image/writejbig2.c +++ b/Build/source/texk/web2c/luatexdir/image/writejbig2.c @@ -1,21 +1,24 @@ -/*********************************************************************** -Copyright (c) 2002-2006 Han The Thanh, <thanh@pdftex.org> +/* writejbig2.c + + Copyright 1996-2006 Han The Thanh <thanh@pdftex.org> + Copyright 2006-2008 Taco Hoekwater <taco@luatex.org> + + This file is part of LuaTeX. -This file is part of pdfTeX. + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. -pdfTeX is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 2 of the License, or (at your option) -any later version. + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. -pdfTeX is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */ -You should have received a copy of the GNU General Public License along -with pdfTeX; if not, write to the Free Software Foundation, Inc., 59 -Temple Place, Suite 330, Boston, MA 02111-1307 USA +/*********************************************************************** 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. @@ -75,10 +78,13 @@ object exists, reference it. Else create fresh one. 09 Dec. 2002: JBIG2 seg. page numbers > 0 are now set to 1, see PDF Ref. -$Id: writejbig2.c 1127 2008-03-25 21:32:54Z hhenkel $ ***********************************************************************/ #include "writejbig2.h" + +static const char _svn_version[] = + "$Id: writejbig2.c 1407 2008-07-15 10:49:28Z taco $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/image/writejbig2.c $"; + #undef DEBUG /**********************************************************************/ @@ -292,7 +298,7 @@ void readfilehdr(FILEINFO * fip) fip->sequentialaccess = (fip->filehdrflags & 0x01) ? true : false; if (fip->sequentialaccess) { /* Annex D.1 vs. Annex D.2 */ xfseek(fip->file, 0, SEEK_END, fip->filepath); - fip->filesize = xftell(fip->file, fip->filepath); + fip->filesize = (long) xftello(fip->file, fip->filepath); xfseek(fip->file, 9, SEEK_SET, fip->filepath); } /* Annex D.4.3 Number of pages */ @@ -363,7 +369,7 @@ boolean readseghdr(FILEINFO * fip, SEGINFO * sip) sip->segpage = ygetc(fip->file); /* 7.2.7 Segment data length */ sip->segdatalen = read4bytes(fip->file); - sip->hdrend = xftell(fip->file, fip->filepath); + sip->hdrend = (long) xftello(fip->file, fip->filepath); /* ---- at end of segment header ---- */ return true; } @@ -583,7 +589,7 @@ void rd_jbig2_info(FILEINFO * fip) sip->dataend = sip->datastart + sip->segdatalen; if (!fip->sequentialaccess && (sip->pageinfoflag || sip->endofstripeflag)) - xfseek(fip->file, sip->datastart, SEEK_SET, fip->filepath); + xfseeko(fip->file, sip->datastart, SEEK_SET, fip->filepath); seekdist = sip->segdatalen; /* 7.4.8 Page information segment syntax */ if (sip->pageinfoflag) { @@ -603,11 +609,11 @@ void rd_jbig2_info(FILEINFO * fip) } if (!fip->sequentialaccess && (sip->pageinfoflag || sip->endofstripeflag)) - xfseek(fip->file, sip->hdrend, SEEK_SET, fip->filepath); + xfseeko(fip->file, sip->hdrend, SEEK_SET, fip->filepath); if (!fip->sequentialaccess) streampos += sip->segdatalen; if (fip->sequentialaccess) - xfseek(fip->file, seekdist, SEEK_CUR, fip->filepath); + xfseeko(fip->file, seekdist, SEEK_CUR, fip->filepath); if (sip->endofpageflag && currentpage && (pip->stripinginfo >> 15)) pip->height = pip->stripedheight; } @@ -655,10 +661,10 @@ void wr_jbig2(FILEINFO * fip, unsigned long page) for (slip = pip->segments.first; slip != NULL; slip = slip->next) { /* loop over page segments */ sip = slip->d; if (sip->isrefered || page > 0) { - xfseek(fip->file, sip->hdrstart, SEEK_SET, fip->filepath); + xfseeko(fip->file, sip->hdrstart, SEEK_SET, fip->filepath); /* mark refered-to page 0 segments, change segpages > 1 to 1 */ writeseghdr(fip, sip); - xfseek(fip->file, sip->datastart, SEEK_SET, fip->filepath); + xfseeko(fip->file, sip->datastart, SEEK_SET, fip->filepath); for (i = sip->datastart; i < sip->dataend; i++) pdfout(ygetc(fip->file)); } @@ -675,7 +681,7 @@ void read_jbig2_info(image_dict * idict) PAGEINFO *pip; void **aa; assert(idict != NULL); - img_type(idict) = IMAGE_TYPE_JBIG2; + img_type(idict) = IMG_TYPE_JBIG2; if (img_pagenum(idict) < 1) pdftex_fail ("read_jbig2_info(): page %d not in JBIG2 image file; page must be > 0", diff --git a/Build/source/texk/web2c/luatexdir/image/writejbig2.h b/Build/source/texk/web2c/luatexdir/image/writejbig2.h index c1bec32d859..5bc91920889 100644 --- a/Build/source/texk/web2c/luatexdir/image/writejbig2.h +++ b/Build/source/texk/web2c/luatexdir/image/writejbig2.h @@ -1,26 +1,28 @@ -/*********************************************************************** -Copyright (c) 2002-2006 Han The Thanh, <thanh@pdftex.org> +/* writejbig2.h + + Copyright 1996-2006 Han The Thanh <thanh@pdftex.org> + Copyright 2006-2008 Taco Hoekwater <taco@luatex.org> -This file is part of pdfTeX. + This file is part of LuaTeX. -pdfTeX is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 2 of the License, or (at your option) -any later version. + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. -pdfTeX is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. -You should have received a copy of the GNU General Public License along -with pdfTeX; if not, write to the Free Software Foundation, Inc., 59 -Temple Place, Suite 330, Boston, MA 02111-1307 USA + You should have received a copy of the GNU General Public License along + 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. -$Id: writejbig2.h 1012 2008-02-14 00:00:57Z oneiros $ +$Id: writejbig2.h 1224 2008-05-02 15:26:27Z oneiros $ ***********************************************************************/ #include <stdlib.h> diff --git a/Build/source/texk/web2c/luatexdir/image/writejpg.c b/Build/source/texk/web2c/luatexdir/image/writejpg.c index 422c29470fb..8e439c76ca5 100644 --- a/Build/source/texk/web2c/luatexdir/image/writejpg.c +++ b/Build/source/texk/web2c/luatexdir/image/writejpg.c @@ -1,28 +1,30 @@ -/* -Copyright (c) 1996-2006 Han The Thanh, <thanh@pdftex.org> +/* writejpg.c + + Copyright 1996-2006 Han The Thanh <thanh@pdftex.org> + Copyright 2006-2008 Taco Hoekwater <taco@luatex.org> -This file is part of pdfTeX. -pdfTeX is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + This file is part of LuaTeX. -pdfTeX is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. -You should have received a copy of the GNU General Public License -along with pdfTeX; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. -$Id: writejpg.c 1100 2008-03-09 13:40:48Z hhenkel $ -*/ + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */ #include <assert.h> #include "ptexlib.h" #include "image.h" +static const char _svn_version[] = + "$Id: writejpg.c 1224 2008-05-02 15:26:27Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/image/writejpg.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 */ @@ -117,7 +119,7 @@ void read_jpg_info(image_dict * idict, img_readtype_e readtype) int i, units = 0; unsigned char jpg_id[] = "JFIF"; assert(idict != NULL); - assert(img_type(idict) == IMAGE_TYPE_JPG); + assert(img_type(idict) == IMG_TYPE_JPG); img_totalpages(idict) = 1; img_pagenum(idict) = 1; img_xres(idict) = img_yres(idict) = 0; diff --git a/Build/source/texk/web2c/luatexdir/image/writepng.c b/Build/source/texk/web2c/luatexdir/image/writepng.c index d431b3b7ed1..1981d002218 100644 --- a/Build/source/texk/web2c/luatexdir/image/writepng.c +++ b/Build/source/texk/web2c/luatexdir/image/writepng.c @@ -1,29 +1,32 @@ -/* -Copyright (c) 1996-2004 Han The Thanh, <thanh@pdftex.org> - -This file is part of pdfTeX. +/* writepng.c + + Copyright 1996-2006 Han The Thanh <thanh@pdftex.org> + Copyright 2006-2008 Taco Hoekwater <taco@luatex.org> -pdfTeX is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + This file is part of LuaTeX. -pdfTeX is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + LuaTeX is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. -You should have received a copy of the GNU General Public License -along with pdfTeX; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + LuaTeX is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. -$Id: writepng.c 1101 2008-03-09 16:12:15Z hhenkel $ -*/ + You should have received a copy of the GNU General Public License along + with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */ #include <assert.h> #include "ptexlib.h" #include "image.h" +static const char _svn_version[] = + "$Id: writepng.c 2029 2009-03-14 19:10:25Z oneiros $ $URL: http://scm.foundry.supelec.fr/svn/luatex/trunk/src/texk/web2c/luatexdir/image/writepng.c $"; + +static int transparent_page_group = -1; + void close_and_cleanup_png(image_dict * idict) { assert(idict != NULL); @@ -44,7 +47,7 @@ void read_png_info(image_dict * idict, img_readtype_e readtype) png_structp png_p; png_infop info_p; assert(idict != NULL); - assert(img_type(idict) == IMAGE_TYPE_PNG); + assert(img_type(idict) == IMG_TYPE_PNG); img_totalpages(idict) = 1; img_pagenum(idict) = 1; img_xres(idict) = img_yres(idict) = 0; @@ -120,7 +123,7 @@ void read_png_info(image_dict * idict, img_readtype_e readtype) #define write_gray_pixel_8(r) \ if (j % 2 == 0) pdf_buf[pdf_ptr++] = *r++; \ - else smask[smask_ptr++] = *r++ + else smask[smask_ptr++] = *r++ #define write_rgb_pixel_16(r) \ @@ -139,27 +142,27 @@ void read_png_info(image_dict * idict, img_readtype_e readtype) r = row; \ k = info_p->rowbytes; \ while(k > 0) { \ - l = (k > pdf_buf_size)? pdf_buf_size : k; \ - pdfroom(l); \ - for (j = 0; j < l; j++) { \ - outmac; \ - } \ - k -= l; \ - } \ + l = (k > pdf_buf_size)? pdf_buf_size : k; \ + pdfroom(l); \ + for (j = 0; j < l; j++) { \ + outmac; \ + } \ + k -= l; \ + } \ } #define write_interlaced(outmac) \ for (i = 0; (unsigned) i < (int)info_p->height; i++) { \ row = rows[i]; \ - k = info_p->rowbytes; \ - while(k > 0) { \ - l = (k > pdf_buf_size)? pdf_buf_size : k;\ - pdfroom(l); \ - for (j = 0; j < l; j++) { \ - outmac; \ - } \ - k -= l; \ - } \ + k = info_p->rowbytes; \ + while(k > 0) { \ + l = (k > pdf_buf_size)? pdf_buf_size : k;\ + pdfroom(l); \ + for (j = 0; j < l; j++) { \ + outmac; \ + } \ + k -= l; \ + } \ xfree(rows[i]); \ } @@ -389,7 +392,7 @@ void write_png_rgb_alpha(image_dict * idict) bitdepth = (int) info_p->bit_depth; pdf_begin_dict(smask_objnum, 0); pdf_puts("/Type /XObject\n/Subtype /Image\n"); - if (img_attr(idict) != NULL) + if (img_attr(idict) != NULL && strlen(img_attr(idict)) > 0) pdf_printf("%s\n", img_attr(idict)); pdf_printf("/Width %i\n/Height %i\n/BitsPerComponent %i\n", (int) info_p->width, @@ -460,14 +463,15 @@ void copy_png(image_dict * idict) pdftex_fail("writepng: fseek in PNG file failed"); } } while (endflag == false); - pdf_printf("/Length %d\n", streamlength); - pdf_printf("/Filter /FlateDecode\n"); - pdf_printf("/DecodeParms << "); - pdf_printf("/Colors %d ", info_p->color_type == 2 ? 3 : 1); - pdf_printf("/Columns %d ", (int) info_p->width); - pdf_printf("/BitsPerComponent %i ", (int) info_p->bit_depth); - pdf_printf("/Predictor %d ", 10); /* actual predictor defined on line basis */ - pdf_printf(">>\n>>\nstream\n"); + pdf_printf("/Length %d\n" + "/Filter/FlateDecode\n" + "/DecodeParms<<" + "/Colors %d" + "/Columns %d" + "/BitsPerComponent %i" + "/Predictor 10>>\n>>\nstream\n", streamlength, + info_p->color_type == 2 ? 3 : 1, + (int) info_p->width, info_p->bit_depth); /* 2nd pass to copy data */ endflag = false; if (fseek(fp, 8, SEEK_SET) != 0) @@ -516,6 +520,8 @@ void reopen_png(image_dict * idict) pdftex_fail("writepng: image dimensions have changed"); } +static boolean last_png_needs_page_group; + void write_png(image_dict * idict) { double gamma, checked_gamma; @@ -524,6 +530,7 @@ void write_png(image_dict * idict) png_structp png_p; png_infop info_p; assert(idict != NULL); + last_png_needs_page_group = false; if (img_file(idict) == NULL) reopen_png(idict); assert(img_png_ptr(idict) != NULL); @@ -616,18 +623,20 @@ void write_png(image_dict * idict) write_png_gray(idict); break; case PNG_COLOR_TYPE_GRAY_ALPHA: - if (fixed_pdf_minor_version >= 4) + if (fixed_pdf_minor_version >= 4) { write_png_gray_alpha(idict); - else + last_png_needs_page_group = true; + } else write_png_gray(idict); break; case PNG_COLOR_TYPE_RGB: write_png_rgb(idict); break; case PNG_COLOR_TYPE_RGB_ALPHA: - if (fixed_pdf_minor_version >= 4) + if (fixed_pdf_minor_version >= 4) { write_png_rgb_alpha(idict); - else + last_png_needs_page_group = true; + } else write_png_rgb(idict); break; default: @@ -638,3 +647,27 @@ void write_png(image_dict * idict) pdf_flush(); close_and_cleanup_png(idict); } + + + +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 */ +void write_additional_png_objects(void) +{ + return; /* this interferes with current macro-based usage and cannot be configured */ + if (last_png_needs_page_group) { + if (!transparent_page_group_was_written && transparent_page_group > 1) { + /* create new group object */ + transparent_page_group_was_written = true; + pdf_begin_obj(transparent_page_group, 2); + if (get_pdf_compress_level() == 0) { + pdf_puts("%PTEX Group needed for transparent pngs\n"); + } + pdf_puts + ("<</Type/Group /S/Transparency /CS/DeviceRGB /I true /K true>>\n"); + pdf_end_obj(); + } + } +} |