diff options
Diffstat (limited to 'Build/source/texk/web2c/luatexdir/image')
-rw-r--r-- | Build/source/texk/web2c/luatexdir/image/epdf.h | 44 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/image/image.h | 10 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/image/pdftoepdf.h | 9 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/image/pdftoepdf.w (renamed from Build/source/texk/web2c/luatexdir/image/pdftoepdf.cc) | 291 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/image/writeimg.h | 6 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/image/writeimg.w | 129 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/image/writejbig2.w | 135 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/image/writejp2.w | 60 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/image/writejpg.w | 69 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/image/writepng.h | 6 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/image/writepng.w | 586 |
11 files changed, 698 insertions, 647 deletions
diff --git a/Build/source/texk/web2c/luatexdir/image/epdf.h b/Build/source/texk/web2c/luatexdir/image/epdf.h index 798a2c8e5e2..ba25ff70934 100644 --- a/Build/source/texk/web2c/luatexdir/image/epdf.h +++ b/Build/source/texk/web2c/luatexdir/image/epdf.h @@ -17,7 +17,7 @@ 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 4054 2011-01-10 19:05:54Z hhenkel $ */ +/* $Id: epdf.h 4559 2013-01-20 19:58:26Z hhenkel $ */ // this is the common header file for C++ sources pdftoepdf.cc and lepdflib.cc @@ -54,6 +54,7 @@ extern "C" { # include "PDFDoc.h" # include "GlobalParams.h" # include "Error.h" +# include "FileSpec.h" extern "C" { @@ -80,36 +81,59 @@ extern "C" { # include "utils/avlstuff.h" # include "pdf/pdftypes.h" -# include "lua51/lua.h" -# include "lua51/lauxlib.h" +# include "lua52/lua.h" +# include "lua52/lauxlib.h" - /* pdfgen.c */ + /* pdfgen.w */ + extern int ten_pow[10]; __attribute__ ((format(printf, 2, 3))) extern void pdf_printf(PDF, const char *fmt, ...); extern void pdf_begin_obj(PDF, int, int); extern void pdf_end_obj(PDF); + extern void pdf_begin_dict(PDF); + extern void pdf_end_dict(PDF); + extern void pdf_begin_array(PDF); + extern void pdf_end_array(PDF); + extern void pdf_add_null(PDF); + extern void pdf_add_bool(PDF, int i); + extern void pdf_add_int(PDF, int i); + extern void pdf_add_ref(PDF, int num); + extern void pdf_add_name(PDF, const char *name); + extern void pdf_dict_add_streaminfo(PDF); extern void pdf_begin_stream(PDF); extern void pdf_end_stream(PDF); extern void pdf_room(PDF, int); extern void pdf_out_block(PDF pdf, const char *s, size_t n); -# define pdf_out(B, A) do { pdf_room(B, 1); B->buf[B->ptr++] = A; } while (0) + extern void pdf_dict_add_int(PDF, const char *key, int i); + extern void pdf_dict_add_ref(PDF, const char *key, int num); + extern void pdf_dict_add_name(PDF, const char *key, const char *val); + extern void pdf_dict_add_streaminfo(PDF); + +# define pdf_out(pdf, A) do { pdf_room(pdf, 1); *(pdf->buf->p++) = A; } while (0) +# define pdf_quick_out(pdf,A) *(pdf->buf->p++)=(unsigned char)(A) # define pdf_puts(pdf, s) pdf_out_block((pdf), (s), strlen(s)) - /* pdftables.c */ - extern int pdf_new_objnum(PDF); + /* pdfpage.w */ + extern void print_pdffloat(PDF pdf, pdffloat f); + + /* pdftables.w */ + 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 write_epdf(PDF, image_dict *); extern void unrefPdfDocument(char *); extern void epdf_free(void); + extern void copyReal(PDF pdf, double d); + + /* writeimg.w */ + extern void pdf_dict_add_img_filename(PDF pdf, image_dict * idict); - /* utils.c */ + /* utils.w */ extern char *convertStringToPDFString(char *in, int len); - extern char *stripzeros(char *a); - /* lepdflib.c */ + /* lepdflib.w */ int luaopen_epdf(lua_State * L); # include "luatex-common.h" diff --git a/Build/source/texk/web2c/luatexdir/image/image.h b/Build/source/texk/web2c/luatexdir/image/image.h index c1b91abafb6..4e88dbeeaba 100644 --- a/Build/source/texk/web2c/luatexdir/image/image.h +++ b/Build/source/texk/web2c/luatexdir/image/image.h @@ -18,7 +18,7 @@ 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 4051 2011-01-09 22:41:33Z hhenkel $ */ +/* $Id: image.h 4406 2012-05-07 21:47:26Z hhenkel $ */ #ifndef IMAGE_H # define IMAGE_H @@ -32,8 +32,8 @@ extern int do_zround(double r); /* from utils.w */ extern scaled one_hundred_bp; /* from pdfgen.w */ -# define bp2int(p) do_zround(p * (one_hundred_bp / 100.0)) -# define int2bp(i) (i * 100.0 / one_hundred_bp) +# define bp2sp(p) do_zround(p * (one_hundred_bp / 100.0)) +# define sp2bp(i) (i * 100.0 / one_hundred_bp) # define TYPE_IMG "image" # define TYPE_IMG_DICT "image-dict" @@ -72,7 +72,7 @@ typedef enum { DICT_NEW, /* fresh dictionary */ } dict_state; typedef enum { IMG_TYPE_NONE, IMG_TYPE_PDF, IMG_TYPE_PNG, IMG_TYPE_JPG, - IMG_TYPE_JP2, IMG_TYPE_JBIG2, IMG_TYPE_PDFSTREAM, IMG_TYPE_SENTINEL + IMG_TYPE_JP2, IMG_TYPE_JBIG2, IMG_TYPE_PDFSTREAM, IMG_TYPE_SENTINEL } imgtype_e; typedef enum { IMG_KEEPOPEN, IMG_CLOSEINBETWEEN } img_readtype_e; @@ -102,6 +102,7 @@ typedef struct { int page_num; /* requested page (by number) */ char *pagename; /* requested page (by name) */ char *filename; /* requested raw file name */ + char *visiblefilename; /* blocks or overwrites filename as it appears in PDF output */ char *filepath; /* full file path after kpathsea */ char *attr; /* additional image dict entries */ FILE *file; @@ -141,6 +142,7 @@ typedef struct { # 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) diff --git a/Build/source/texk/web2c/luatexdir/image/pdftoepdf.h b/Build/source/texk/web2c/luatexdir/image/pdftoepdf.h index 05bb85eeaa5..bbe4d3c8a63 100644 --- a/Build/source/texk/web2c/luatexdir/image/pdftoepdf.h +++ b/Build/source/texk/web2c/luatexdir/image/pdftoepdf.h @@ -1,7 +1,7 @@ /* pdftoepdf.h Copyright 1996-2006 Han The Thanh <thanh@pdftex.org> - Copyright 2006-2009 Taco Hoekwater <taco@luatex.org> + Copyright 2006-2011 Taco Hoekwater <taco@luatex.org> This file is part of LuaTeX. @@ -18,7 +18,7 @@ You should have received a copy of the GNU General Public License along with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */ -/* $Id: pdftoepdf.h 3319 2009-12-27 20:05:36Z hhenkel $ */ +/* $Id: pdftoepdf.h 4351 2011-10-03 22:22:01Z hhenkel $ */ #ifndef PDFTOEPDF_H # define PDFTOEPDF_H @@ -29,6 +29,11 @@ void read_pdf_info(image_dict *, int, int, img_readtype_e); void unrefPdfDocument(char *); void write_epdf(PDF, image_dict *); void epdf_check_mem(void); +void copyReal(PDF pdf, double d); + +int poppler_version_major(void); +int poppler_version_minor(void); +int poppler_version_micro(void); /* epdf.c --- this should go in an own header file */ diff --git a/Build/source/texk/web2c/luatexdir/image/pdftoepdf.cc b/Build/source/texk/web2c/luatexdir/image/pdftoepdf.w index e0fa02927dc..2b07c303dd5 100644 --- a/Build/source/texk/web2c/luatexdir/image/pdftoepdf.cc +++ b/Build/source/texk/web2c/luatexdir/image/pdftoepdf.w @@ -1,41 +1,36 @@ -/* pdftoepdf.cc - - Copyright 1996-2006 Han The Thanh <thanh@pdftex.org> - Copyright 2006-2012 Taco Hoekwater <taco@luatex.org> - - This file is part of LuaTeX. - - 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. - - 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 LuaTeX; if not, see <http://www.gnu.org/licenses/>. */ - +% pdftoepdf.w +% +% Copyright 1996-2006 Han The Thanh <thanh@@pdftex.org> +% Copyright 2006-2012 Taco Hoekwater <taco@@luatex.org> +% +% This file is part of LuaTeX. +% +% 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. +% +% 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 LuaTeX; if not, see <http://www.gnu.org/licenses/>. + +@ @c static const char _svn_version[] = - "$Id: pdftoepdf.cc 4136 2011-04-11 22:06:50Z hhenkel $ " - "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.66.0/source/texk/web2c/luatexdir/image/pdftoepdf.cc $"; - -#define __STDC_FORMAT_MACROS /* for PRId64 etc. */ + "$Id: pdftoepdf.w 4479 2012-11-07 16:38:55Z taco $" + "$URL: http://foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/image/pdftoepdf.w $"; // define DEBUG +#define __STDC_FORMAT_MACROS /* for PRId64 etc. */ -#include "epdf.h" +#include "image/epdf.h" // This file is mostly C and not very much C++; it's just used to interface // the functions of xpdf, which happens to be written in C++. -// The prefix "PTEX" for the PDF keys is special to pdfTeX; -// this has been registered with Adobe by Hans Hagen. - -#define pdfkeyprefix "PTEX" - static GBool isInit = gFalse; //********************************************************************** @@ -79,7 +74,7 @@ static char *get_file_checksum(char *a, file_error_mode fe) a); snprintf(ck, PDF_CHECKSUM_SIZE, "%" PRIu64 "_%" PRIu64, (uint64_t) size, (uint64_t) mtime); - } else { + } else { switch (fe) { case FE_FAIL: pdftex_fail("PDF inclusion: could not stat() file '%s'", a); @@ -255,7 +250,7 @@ static int addInObj(PDF pdf, PdfDocument * pdf_doc, Ref ref) n = new InObj; n->ref = ref; n->next = NULL; - n->num = pdf_new_objnum(pdf); + n->num = pdf_create_obj(pdf, obj_type_others, 0); addObjMap(pdf_doc, ref, n->num); if (pdf_doc->inObjList == NULL) pdf_doc->inObjList = n; @@ -271,7 +266,7 @@ static int addInObj(PDF pdf, PdfDocument * pdf_doc, Ref ref) } //********************************************************************** -// Function converts double to string; very small and very large numbers +// 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. @@ -280,57 +275,24 @@ static int addInObj(PDF pdf, PdfDocument * pdf_doc, Ref ref) // maximum value of reals is +2^15 // smalles values of reals is 1/(2^16) -static char *convertNumToPDF(double n) +static pdffloat conv_double_to_pdffloat(double n) { - static const int precision = 6; - static const int fact = (int) 1E6; // must be 10^precision - static const double epsilon = 0.5E-6; // 2epsilon must be 10^-precision - static char buf[64]; - // handle very small values: return 0 - if (fabs(n) < epsilon) { - buf[0] = '0'; - buf[1] = '\0'; - } else { - char ints[64]; - int bindex = 0, sindex = 0; - int ival, fval; - // handle the sign part if n is negative - if (n < 0) { - buf[bindex++] = '-'; - n = -n; - } - n += epsilon; // for rounding - // handle the integer part, simply with sprintf - ival = (int) floor(n); - n -= ival; - sprintf(ints, "%d", ival); - while (ints[sindex] != 0) - buf[bindex++] = ints[sindex++]; - // handle the fractional part up to 'precision' digits - fval = (int) floor(n * fact); - if (fval) { - // set a dot - buf[bindex++] = '.'; - sindex = bindex + precision; - buf[sindex--] = '\0'; - // fill up trailing zeros with the string terminator NULL - while (((fval % 10) == 0) && (sindex >= bindex)) { - buf[sindex--] = '\0'; - fval /= 10; - } - // fill up the fractional part back to front - while (sindex >= bindex) { - buf[sindex--] = (fval % 10) + '0'; - fval /= 10; - } - } else - buf[bindex++] = '\0'; - } - return (char *) buf; + pdffloat a; + a.e = 6; + a.m = lround(n * ten_pow[a.e]); + return a; } static void copyObject(PDF, PdfDocument *, Object *); +void copyReal(PDF pdf, double d) +{ + if (pdf->cave) + pdf_out(pdf, ' '); + print_pdffloat(pdf, conv_double_to_pdffloat(d)); + pdf->cave = true; +} + static void copyString(PDF pdf, GooString * string) { char *p; @@ -338,8 +300,10 @@ static void copyString(PDF pdf, GooString * string) size_t i, l; p = string->getCString(); l = (size_t) string->getLength(); + if (pdf->cave) + pdf_out(pdf, ' '); if (strlen(p) == l) { - pdf_puts(pdf, "("); + pdf_out(pdf, '('); for (; *p != 0; p++) { c = (unsigned char) *p; if (c == '(' || c == ')' || c == '\\') @@ -349,20 +313,21 @@ static void copyString(PDF pdf, GooString * string) else pdf_out(pdf, c); } - pdf_puts(pdf, ")"); + pdf_out(pdf, ')'); } else { - pdf_puts(pdf, "<"); + pdf_out(pdf, '<'); for (i = 0; i < l; i++) { c = (unsigned char) string->getChar(i); pdf_printf(pdf, "%.2x", (int) c); } - pdf_puts(pdf, ">"); + pdf_out(pdf, '>'); } + pdf->cave = true; } static void copyName(PDF pdf, char *s) { - pdf_puts(pdf, "/"); + pdf_out(pdf, '/'); for (; *s != 0; s++) { if (isdigit(*s) || isupper(*s) || islower(*s) || *s == '_' || *s == '.' || *s == '-' || *s == '+') @@ -370,72 +335,74 @@ static void copyName(PDF pdf, char *s) else pdf_printf(pdf, "#%.2X", *s & 0xFF); } + pdf->cave = true; } static void copyArray(PDF pdf, PdfDocument * pdf_doc, Array * array) { int i, l; Object obj1; - pdf_puts(pdf, "["); + pdf_begin_array(pdf); for (i = 0, l = array->getLength(); i < l; ++i) { array->getNF(i, &obj1); - if (!obj1.isName()) - pdf_puts(pdf, " "); copyObject(pdf, pdf_doc, &obj1); obj1.free(); } - pdf_puts(pdf, "]"); + pdf_end_array(pdf); } static void copyDict(PDF pdf, PdfDocument * pdf_doc, Dict * dict) { int i, l; Object obj1; - pdf_puts(pdf, "<<"); + pdf_begin_dict(pdf); for (i = 0, l = dict->getLength(); i < l; ++i) { copyName(pdf, dict->getKey(i)); - pdf_puts(pdf, " "); dict->getValNF(i, &obj1); copyObject(pdf, pdf_doc, &obj1); obj1.free(); - pdf_puts(pdf, "\n"); } - pdf_puts(pdf, ">>"); + pdf_end_dict(pdf); } static void copyStreamStream(PDF pdf, Stream * str) { - int c; + int c, i, len = 1024; str->reset(); + i = len; while ((c = str->getChar()) != EOF) { - pdf_out(pdf, c); - pdf->last_byte = c; + if (i == len) { + pdf_room(pdf, len); + i = 0; + } + pdf_quick_out(pdf, c); + i++; } } static void copyStream(PDF pdf, PdfDocument * pdf_doc, Stream * stream) { copyDict(pdf, pdf_doc, stream->getDict()); - pdf_puts(pdf, "stream\n"); + pdf_begin_stream(pdf); + assert(pdf->zip_write_state == NO_ZIP); copyStreamStream(pdf, stream->getUndecodedStream()); - if (pdf->last_byte != '\n') - pdf_puts(pdf, "\n"); - pdf_puts(pdf, "endstream"); // can't simply write pdf_end_stream() + pdf_end_stream(pdf); } static void copyObject(PDF pdf, PdfDocument * pdf_doc, Object * obj) { switch (obj->getType()) { case objBool: - pdf_printf(pdf, "%s", obj->getBool()? "true" : "false"); + pdf_add_bool(pdf, (int) obj->getBool()); break; case objInt: - pdf_printf(pdf, "%i", obj->getInt()); + pdf_add_int(pdf, obj->getInt()); break; case objReal: - pdf_printf(pdf, "%s", convertNumToPDF(obj->getReal())); + copyReal(pdf, obj->getReal()); break; // not needed: + // case objNum: // GBool isNum() { return type == objInt || type == objReal; } case objString: copyString(pdf, obj->getString()); @@ -444,7 +411,7 @@ static void copyObject(PDF pdf, PdfDocument * pdf_doc, Object * obj) copyName(pdf, obj->getName()); break; case objNull: - pdf_puts(pdf, "null"); + pdf_add_null(pdf); break; case objArray: copyArray(pdf, pdf_doc, obj->getArray()); @@ -456,7 +423,7 @@ static void copyObject(PDF pdf, PdfDocument * pdf_doc, Object * obj) copyStream(pdf, pdf_doc, obj->getStream()); break; case objRef: - pdf_printf(pdf, "%d 0 R", addInObj(pdf, pdf_doc, obj->getRef())); + pdf_add_ref(pdf, addInObj(pdf, pdf_doc, obj->getRef())); break; case objCmd: case objError: @@ -475,18 +442,18 @@ static void copyObject(PDF pdf, PdfDocument * pdf_doc, Object * obj) static void writeRefs(PDF pdf, PdfDocument * pdf_doc) { InObj *r, *n; - XRef *xref; Object obj1; - xref = pdf_doc->doc->getXRef(); + XRef *xref; + PDFDoc *doc = pdf_doc->doc; + xref = doc->getXRef(); for (r = pdf_doc->inObjList; r != NULL;) { xref->fetch(r->ref.num, r->ref.gen, &obj1); if (obj1.isStream()) - pdf_begin_obj(pdf, r->num, 0); + pdf_begin_obj(pdf, r->num, OBJSTM_NEVER); else pdf_begin_obj(pdf, r->num, 2); // \pdfobjcompresslevel = 2 is for this copyObject(pdf, pdf_doc, &obj1); obj1.free(); - pdf_puts(pdf, "\n"); pdf_end_obj(pdf); n = r->next; delete r; @@ -532,6 +499,8 @@ read_pdf_info(image_dict * idict, int minor_pdf_version_wanted, int pdf_inclusion_errorlevel, img_readtype_e readtype) { PdfDocument *pdf_doc; + PDFDoc *doc; + Catalog *catalog; Page *page; int rotate; PDFRectangle *pagebox; @@ -548,12 +517,14 @@ read_pdf_info(image_dict * idict, int minor_pdf_version_wanted, } // open PDF file pdf_doc = refPdfDocument(img_filepath(idict), FE_FAIL); + 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. - pdf_major_version_found = pdf_doc->doc->getPDFMajorVersion(); - pdf_minor_version_found = pdf_doc->doc->getPDFMinorVersion(); + 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 = @@ -566,17 +537,16 @@ read_pdf_info(image_dict * idict, int minor_pdf_version_wanted, minor_pdf_version_wanted); } } - img_totalpages(idict) = pdf_doc->doc->getCatalog()->getNumPages(); + img_totalpages(idict) = catalog->getNumPages(); if (img_pagename(idict)) { // get page by name GooString name(img_pagename(idict)); - LinkDest *link = pdf_doc->doc->findDest(&name); + LinkDest *link = doc->findDest(&name); if (link == NULL || !link->isOk()) pdftex_fail("PDF inclusion: invalid destination <%s>", img_pagename(idict)); Ref ref = link->getPageRef(); - img_pagenum(idict) = - pdf_doc->doc->getCatalog()->findPage(ref.num, ref.gen); + img_pagenum(idict) = catalog->findPage(ref.num, ref.gen); if (img_pagenum(idict) == 0) pdftex_fail("PDF inclusion: destination is not a page <%s>", img_pagename(idict)); @@ -589,7 +559,7 @@ read_pdf_info(image_dict * idict, int minor_pdf_version_wanted, (int) img_pagenum(idict)); } // get the required page - page = pdf_doc->doc->getCatalog()->getPage(img_pagenum(idict)); + page = catalog->getPage(img_pagenum(idict)); // get the pagebox coordinates (media, crop,...) to use. pagebox = get_pagebox(page, img_pagebox(idict)); @@ -608,10 +578,10 @@ read_pdf_info(image_dict * idict, int minor_pdf_version_wanted, 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); + 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). @@ -651,13 +621,15 @@ read_pdf_info(image_dict * idict, int minor_pdf_version_wanted, void write_epdf(PDF pdf, image_dict * idict) { PdfDocument *pdf_doc; + PDFDoc *doc; + Catalog *catalog; Page *page; Ref *pageref; Dict *pageDict; Object obj1, contents, pageobj, pagesobj1, pagesobj2, *op1, *op2, *optmp; PDFRectangle *pagebox; int i, l; - float bbox[4]; + double bbox[4]; char s[256]; const char *pagedictkeys[] = { "Group", "LastModified", "Metadata", "PieceInfo", "Resources", @@ -667,36 +639,40 @@ void write_epdf(PDF pdf, image_dict * idict) // open PDF file pdf_doc = refPdfDocument(img_filepath(idict), FE_FAIL); - page = pdf_doc->doc->getCatalog()->getPage(img_pagenum(idict)); - pageref = pdf_doc->doc->getCatalog()->getPageRef(img_pagenum(idict)); + 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() - pdf_doc->doc->getXRef()->fetch(pageref->num, pageref->gen, &pageobj); + doc->getXRef()->fetch(pageref->num, pageref->gen, &pageobj); pageDict = pageobj.getDict(); // write the Page header - pdf_puts(pdf, "/Type /XObject\n/Subtype /Form\n"); + 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, "%s\n", img_attr(idict)); - pdf_puts(pdf, "/FormType 1\n"); + pdf_printf(pdf, "\n%s\n", img_attr(idict)); + pdf_dict_add_int(pdf, "FormType", 1); // write additional information - pdf_printf(pdf, "/%s.FileName (%s)\n", pdfkeyprefix, - convertStringToPDFString(pdf_doc->file_path, - strlen(pdf_doc->file_path))); - pdf_printf(pdf, "/%s.PageNumber %i\n", pdfkeyprefix, - (int) img_pagenum(idict)); - pdf_doc->doc->getDocInfoNF(&obj1); + 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) - pdf_printf(pdf, "/%s.InfoDict ", pdfkeyprefix); - pdf_printf(pdf, "%d 0 R\n", addInObj(pdf, pdf_doc, obj1.getRef())); + snprintf(s, 30, "%s.InfoDict", pdfkeyprefix); + pdf_dict_add_ref(pdf, s, addInObj(pdf, pdf_doc, obj1.getRef())); } obj1.free(); 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]); + bbox[0] = sp2bp(img_bbox(idict)[0]); + bbox[1] = sp2bp(img_bbox(idict)[1]); + bbox[2] = sp2bp(img_bbox(idict)[2]); + bbox[3] = sp2bp(img_bbox(idict)[3]); } else { // get the pagebox coordinates (media, crop,...) to use. pagebox = get_pagebox(page, img_pagebox(idict)); @@ -705,9 +681,13 @@ void write_epdf(PDF pdf, image_dict * idict) bbox[2] = pagebox->x2; bbox[3] = pagebox->y2; } - sprintf(s, "/BBox [%.8f %.8f %.8f %.8f]\n", bbox[0], bbox[1], bbox[2], - bbox[3]); - pdf_puts(pdf, stripzeros(s)); + pdf_add_name(pdf, "BBox"); + pdf_begin_array(pdf); + copyReal(pdf, bbox[0]); + copyReal(pdf, bbox[1]); + 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: @@ -722,7 +702,7 @@ void write_epdf(PDF pdf, image_dict * idict) for (i = 0; pagedictkeys[i] != NULL; i++) { pageDict->lookupNF((char *) pagedictkeys[i], &obj1); if (!obj1.isNull()) { - pdf_printf(pdf, "/%s ", pagedictkeys[i]); + pdf_add_name(pdf, pagedictkeys[i]); copyObject(pdf, pdf_doc, &obj1); // preserves indirection } obj1.free(); @@ -741,7 +721,7 @@ void write_epdf(PDF pdf, image_dict * idict) obj1.free(); op1->dictLookupNF((char *) "Resources", &obj1); if (!obj1.isNull()) { - pdf_puts(pdf, "/Resources "); + pdf_add_name(pdf, (const char *) "Resources"); copyObject(pdf, pdf_doc, &obj1); break; } @@ -763,9 +743,9 @@ void write_epdf(PDF pdf, image_dict * idict) // Variant A: get stream and recompress under control // of \pdfcompresslevel // - // pdfbeginstream(); + // pdf_begin_stream(); // copyStreamStream(contents->getStream()); - // pdfendstream(); + // pdf_end_stream(); // Variant B: copy stream without recompressing // @@ -776,28 +756,29 @@ void write_epdf(PDF pdf, image_dict * idict) obj1.free(); contents.streamGetDict()->lookup((char *) "Length", &obj1); assert(!obj1.isNull()); - pdf_puts(pdf, "/Length "); + pdf_add_name(pdf, (const char *) "Length"); copyObject(pdf, pdf_doc, &obj1); obj1.free(); - pdf_puts(pdf, "\n"); contents.streamGetDict()->lookup((char *) "Filter", &obj1); if (!obj1.isNull()) { - pdf_puts(pdf, "/Filter "); + pdf_add_name(pdf, (const char *) "Filter"); copyObject(pdf, pdf_doc, &obj1); obj1.free(); - pdf_puts(pdf, "\n"); contents.streamGetDict()->lookup((char *) "DecodeParms", &obj1); if (!obj1.isNull()) { - pdf_puts(pdf, "/DecodeParms "); + pdf_add_name(pdf, (const char *) "DecodeParms"); copyObject(pdf, pdf_doc, &obj1); - pdf_puts(pdf, "\n"); } } obj1.free(); - pdf_puts(pdf, ">>\nstream\n"); + pdf_end_dict(pdf); + pdf_begin_stream(pdf); copyStreamStream(pdf, contents.getStream()->getBaseStream()); pdf_end_stream(pdf); + pdf_end_obj(pdf); } else if (contents.isArray()) { + pdf_dict_add_streaminfo(pdf); + pdf_end_dict(pdf); pdf_begin_stream(pdf); for (i = 0, l = contents.arrayGetLength(); i < l; ++i) { copyStreamStream(pdf, (contents.arrayGet(i, &obj1))->getStream()); @@ -805,13 +786,17 @@ void write_epdf(PDF pdf, image_dict * idict) 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) - pdf_puts(pdf, " "); + pdf_out(pdf, ' '); } } pdf_end_stream(pdf); + pdf_end_obj(pdf); } 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 writeRefs(pdf, pdf_doc); diff --git a/Build/source/texk/web2c/luatexdir/image/writeimg.h b/Build/source/texk/web2c/luatexdir/image/writeimg.h index 66ef946d842..1cf6683856e 100644 --- a/Build/source/texk/web2c/luatexdir/image/writeimg.h +++ b/Build/source/texk/web2c/luatexdir/image/writeimg.h @@ -1,7 +1,7 @@ /* writeimg.h Copyright 1996-2006 Han The Thanh <thanh@pdftex.org> - Copyright 2006-2009 Taco Hoekwater <taco@luatex.org> + Copyright 2006-2012 Taco Hoekwater <taco@luatex.org> This file is part of LuaTeX. @@ -18,7 +18,7 @@ You should have received a copy of the GNU General Public License along with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */ -/* $Id: writeimg.h 3388 2010-01-26 10:59:04Z taco $ */ +/* $Id: writeimg.h 4405 2012-05-07 21:16:45Z hhenkel $ */ #ifndef WRITEIMG_H # define WRITEIMG_H @@ -48,5 +48,7 @@ void idict_to_array(image_dict *); void dumpimagemeta(void); void undumpimagemeta(PDF, int, int); 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 */ diff --git a/Build/source/texk/web2c/luatexdir/image/writeimg.w b/Build/source/texk/web2c/luatexdir/image/writeimg.w index 4d3eeef15a8..b101fbb65c5 100644 --- a/Build/source/texk/web2c/luatexdir/image/writeimg.w +++ b/Build/source/texk/web2c/luatexdir/image/writeimg.w @@ -1,29 +1,29 @@ % writeimg.w - +% % Copyright 1996-2006 Han The Thanh <thanh@@pdftex.org> -% Copyright 2006-2010 Taco Hoekwater <taco@@luatex.org> - +% Copyright 2006-2012 Taco Hoekwater <taco@@luatex.org> +% % This file is part of LuaTeX. - +% % 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. - +% % 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 LuaTeX; if not, see <http://www.gnu.org/licenses/>. +% with LuaTeX; if not, see <http://www.gnu.org/licenses/>. @* Image inclusion. @ @c static const char _svn_version[] = - "$Id: writeimg.w 4271 2011-05-16 14:40:06Z taco $ " - "$URL: http://foundry.supelec.fr/svn/luatex/branches/0.70.x/source/texk/web2c/luatexdir/image/writeimg.w $"; + "$Id: writeimg.w 4524 2012-12-20 15:38:02Z taco $" + "$URL: http://foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/image/writeimg.w $"; #include "ptexlib.h" #include <assert.h> @@ -37,8 +37,8 @@ static const char _svn_version[] = #include "image/writepng.h" #include "image/writejbig2.h" -#include "lua51/lua.h" /* for |LUA_NOREF| */ -#include "lua51/lauxlib.h" +#include "lua52/lua.h" /* for |LUA_NOREF| */ +#include "lua52/lauxlib.h" @ @c #define pdf_image_resolution int_par(pdf_image_resolution_code) @@ -66,10 +66,10 @@ static const char _svn_version[] = (http://www.libpng.org/pub/png): 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 Translation to C: |"\x89PNG\r\n\x1A\n"| @@ -92,7 +92,7 @@ static const char _svn_version[] = Status: Final Committee Draft D.4.1, ID string - + This is an 8-byte sequence containing 0x97 0x4A 0x42 0x32 0x0D 0x0A 0x1A 0x0A. @@ -318,7 +318,7 @@ void read_img(PDF pdf, IMG_CLOSEINBETWEEN); break; case IMG_TYPE_PNG: - read_png_info(pdf, idict, IMG_CLOSEINBETWEEN); + read_png_info(idict, IMG_CLOSEINBETWEEN); break; case IMG_TYPE_JPG: read_jpg_info(pdf, idict, IMG_CLOSEINBETWEEN); @@ -366,7 +366,7 @@ static image_dict *read_image(PDF pdf, char *file_name, int page_num, return idict; } -@ scans PDF pagebox specification +@ scans PDF pagebox specification @c static pdfboxspec_e scan_pdf_box_spec(void) { @@ -617,7 +617,6 @@ void write_img(PDF pdf, image_dict * idict) @c void pdf_write_image(PDF pdf, int n) { - pdf_begin_dict(pdf, n, 0); if (pdf->draftmode == 0) write_img(pdf, idict_array[obj_data_ptr(pdf, n)]); } @@ -634,21 +633,29 @@ void check_pdfstream_dict(image_dict * idict) @ @c void write_pdfstream(PDF pdf, image_dict * idict) { - char s[256]; assert(img_pdfstream_ptr(idict) != NULL); assert(img_is_bbox(idict)); - pdf_puts(pdf, "/Type /XObject\n/Subtype /Form\n"); + 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, "%s\n", img_attr(idict)); - pdf_puts(pdf, "/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(pdf, stripzeros(s)); + pdf_printf(pdf, "\n%s\n", img_attr(idict)); + pdf_dict_add_int(pdf, "FormType", 1); + pdf_add_name(pdf, "BBox"); + pdf_begin_array(pdf); + copyReal(pdf, sp2bp(img_bbox(idict)[0])); + copyReal(pdf, sp2bp(img_bbox(idict)[1])); + copyReal(pdf, sp2bp(img_bbox(idict)[2])); + copyReal(pdf, sp2bp(img_bbox(idict)[3])); + pdf_end_array(pdf); + pdf_dict_add_streaminfo(pdf); + pdf_end_dict(pdf); pdf_begin_stream(pdf); if (img_pdfstream_stream(idict) != NULL) pdf_puts(pdf, img_pdfstream_stream(idict)); pdf_end_stream(pdf); + pdf_end_obj(pdf); } @ @c @@ -669,6 +676,25 @@ void idict_to_array(image_dict * idict) idict_ptr++; } +void pdf_dict_add_img_filename(PDF pdf, image_dict * idict) +{ + char s[21], *p; + assert(idict != NULL); + /* for now PTEX.FileName only for PDF, but prepared for JPG, PNG, ... */ + if (img_type(idict) != IMG_TYPE_PDF) + return; + if (img_visiblefilename(idict) != NULL) { + if (strlen(img_visiblefilename(idict)) == 0) + return; /* empty string blocks PTEX.FileName output */ + else + p = img_visiblefilename(idict); + } else + p = img_filepath(idict); + // write additional information + snprintf(s, 20, "%s.FileName", pdfkeyprefix); + pdf_add_name(pdf, s); + pdf_printf(pdf, " (%s)", convertStringToPDFString(p, strlen(p))); +} @ 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. @@ -809,29 +835,48 @@ void undumpimagemeta(PDF pdf, int pdfversion, int pdfinclusionerrorlevel) } } -@ scans rule spec to |alt_rule| +@ scan rule spec to |alt_rule| @c scaled_whd scan_alt_rule(void) { + boolean loop; scaled_whd alt_rule; alt_rule.wd = null_flag; alt_rule.ht = null_flag; alt_rule.dp = null_flag; - RESWITCH: - if (scan_keyword("width")) { - scan_normal_dimen(); - alt_rule.wd = cur_val; - goto RESWITCH; - } - if (scan_keyword("height")) { - scan_normal_dimen(); - alt_rule.ht = cur_val; - goto RESWITCH; - } - if (scan_keyword("depth")) { - scan_normal_dimen(); - alt_rule.dp = cur_val; - goto RESWITCH; - } + do { + loop = false; + if (scan_keyword("width")) { + scan_normal_dimen(); + alt_rule.wd = cur_val; + loop = true; + } else if (scan_keyword("height")) { + scan_normal_dimen(); + alt_rule.ht = cur_val; + loop = true; + } else if (scan_keyword("depth")) { + scan_normal_dimen(); + alt_rule.dp = cur_val; + loop = true; + } + } while (loop); return alt_rule; } + +@ copy file of arbitrary size to PDF buffer and flush as needed +@c +size_t read_file_to_buf(PDF pdf, FILE * f, size_t len) +{ + size_t i, j, k = 0; + while (len > 0) { + i = (size_t) (len > pdf->buf->size) ? (size_t) pdf->buf->size : len; + pdf_room(pdf, (int) i); + j = fread(pdf->buf->p, 1, i, f); + pdf->buf->p += j; + k += j; + len -= j; + if (i != j) + break; + } + return k; +} diff --git a/Build/source/texk/web2c/luatexdir/image/writejbig2.w b/Build/source/texk/web2c/luatexdir/image/writejbig2.w index 90f291c02eb..be9a303853a 100644 --- a/Build/source/texk/web2c/luatexdir/image/writejbig2.w +++ b/Build/source/texk/web2c/luatexdir/image/writejbig2.w @@ -1,21 +1,21 @@ % writejbig2.w - +% % Copyright 1996-2006 Han The Thanh <thanh@@pdftex.org> -% Copyright 2006-2011 Taco Hoekwater <taco@@luatex.org> -% Copyright 2003-2011 Hartmut Henkel <hartmut@@luatex.org> - +% Copyright 2006-2012 Taco Hoekwater <taco@@luatex.org> +% Copyright 2003-2012 Hartmut Henkel <hartmut@@luatex.org> +% % This file is part of LuaTeX. - +% % 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. - +% % 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 LuaTeX; if not, see <http://www.gnu.org/licenses/>. @@ -81,8 +81,8 @@ object exists, reference it. Else create fresh one. @ @c static const char _svn_version[] = - "$Id: writejbig2.w 4058 2011-01-10 20:44:28Z hhenkel $ " - "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.66.0/source/texk/web2c/luatexdir/image/writejbig2.w $"; + "$Id: writejbig2.w 4442 2012-05-25 22:40:34Z hhenkel $" + "$URL: http://foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/image/writejbig2.w $"; #undef DEBUG @@ -146,10 +146,10 @@ typedef struct _SEGINFO { unsigned int segnumwidth; /* set by readseghdr() */ long segpage; /* set by readseghdr() */ unsigned long segdatalen; /* set by readseghdr() */ - off_t hdrstart; /* set by readseghdr() */ - off_t hdrend; /* set by readseghdr() */ - off_t datastart; - off_t dataend; + 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() */ @@ -171,13 +171,13 @@ typedef struct _PAGEINFO { typedef struct _FILEINFO { FILE *file; char *filepath; - off_t filesize; + long filesize; LIST pages; /* not including page0 */ LIST page0; unsigned int filehdrflags; /* set by readfilehdr() */ boolean sequentialaccess; /* set by readfilehdr() */ unsigned long numofpages; /* set by readfilehdr() */ - off_t streamstart; /* set by |get_jbig2_info()| */ + unsigned long streamstart; /* set by |get_jbig2_info()| */ unsigned long pdfpage0objnum; PHASE phase; } FILEINFO; @@ -365,14 +365,14 @@ unsigned int read4bytes(FILE * f) } @ @c -static off_t getstreamlen(LITEM * slip, boolean refer) +static unsigned long getstreamlen(LITEM * slip, boolean refer) { SEGINFO *sip; - off_t len = 0; + unsigned long len = 0; for (; slip != NULL; slip = slip->next) { sip = slip->d; if (refer || sip->isrefered) - len += (sip->hdrend - sip->hdrstart) + (sip->dataend - sip->datastart); + len += sip->hdrend - sip->hdrstart + sip->dataend - sip->datastart; } return len; } @@ -384,7 +384,7 @@ static void readfilehdr(FILEINFO * fip) /* Annex D.4 File header syntax */ /* Annex D.4.1 ID string */ unsigned char jbig2_id[] = { 0x97, 'J', 'B', '2', 0x0d, 0x0a, 0x1a, 0x0a }; - xfseeko(fip->file, 0, SEEK_SET, fip->filepath); + xfseek(fip->file, 0, SEEK_SET, fip->filepath); for (i = 0; i < 8; i++) if (ygetc(fip->file) != jbig2_id[i]) pdftex_fail @@ -393,9 +393,9 @@ static void readfilehdr(FILEINFO * fip) fip->filehdrflags = (unsigned int) ygetc(fip->file); fip->sequentialaccess = (fip->filehdrflags & 0x01) ? true : false; if (fip->sequentialaccess) { /* Annex D.1 vs. Annex D.2 */ - xfseeko(fip->file, 0, SEEK_END, fip->filepath); - fip->filesize = xftello(fip->file, fip->filepath); - xfseeko(fip->file, 9, SEEK_SET, fip->filepath); + xfseek(fip->file, 0, SEEK_END, 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 */ if (!(fip->filehdrflags >> 1) & 0x01) /* known number of pages */ @@ -450,13 +450,13 @@ static void checkseghdrflags(SEGINFO * sip) } } -@ for first reading of file; return value tells if header been read +@ for first reading of file; return value tells if header been read @c static boolean readseghdr(FILEINFO * fip, SEGINFO * sip) { unsigned int i; - sip->hdrstart = xftello(fip->file, fip->filepath); + 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 @@ -483,7 +483,7 @@ static boolean readseghdr(FILEINFO * fip, SEGINFO * sip) sip->fieldlen = 1; else { sip->fieldlen = 5 + sip->countofrefered / 8; - xfseeko(fip->file, (off_t) sip->fieldlen - 1, SEEK_CUR, fip->filepath); + xfseek(fip->file, sip->fieldlen - 1, SEEK_CUR, fip->filepath); } /* 7.2.5 Referred-to segment numbers */ if (sip->segnum <= 256) @@ -512,7 +512,7 @@ static boolean readseghdr(FILEINFO * fip, SEGINFO * sip) sip->segpage = ygetc(fip->file); /* 7.2.7 Segment data length */ sip->segdatalen = read4bytes(fip->file); - sip->hdrend = xftello(fip->file, fip->filepath); + sip->hdrend = (unsigned long) xftello(fip->file, fip->filepath); /* ---- at end of segment header ---- */ return true; } @@ -533,7 +533,7 @@ static void markpage0seg(FILEINFO * fip, unsigned long referedseg) } } -@ for writing, marks refered page0 segments, sets segpage > 0 to 1 +@ for writing, marks refered page0 segments, sets segpage > 0 to 1 @c static void writeseghdr(PDF pdf, FILEINFO * fip, SEGINFO * sip) @@ -584,7 +584,7 @@ static void writeseghdr(PDF pdf, FILEINFO * fip, SEGINFO * sip) /* ---- at end of segment header ---- */ } -@ for recursive marking of refered page0 segments +@ for recursive marking of refered page0 segments @c static void checkseghdr(FILEINFO * fip, SEGINFO * sip) { @@ -593,7 +593,7 @@ static void checkseghdr(FILEINFO * fip, SEGINFO * sip) /* 7.2.2 Segment number */ /* 7.2.3 Segment header flags */ /* 7.2.4 Referred-to segment count and retention flags */ - xfseeko(fip->file, (off_t) sip->fieldlen + 5, SEEK_CUR, fip->filepath); + xfseek(fip->file, 5 + sip->fieldlen, SEEK_CUR, fip->filepath); /* 7.2.5 Referred-to segment numbers */ for (i = 0; i < sip->countofrefered; i++) { switch (sip->segnumwidth) { @@ -615,14 +615,14 @@ static void checkseghdr(FILEINFO * fip, SEGINFO * sip) /* 7.2.6 Segment page association */ /* 7.2.7 Segment data length */ if (sip->pageassocsizeflag) - xfseeko(fip->file, 8, SEEK_CUR, fip->filepath); + xfseek(fip->file, 8, SEEK_CUR, fip->filepath); else - xfseeko(fip->file, 5, SEEK_CUR, fip->filepath); + xfseek(fip->file, 5, SEEK_CUR, fip->filepath); /* ---- at end of segment header ---- */ } @ @c -static off_t findstreamstart(FILEINFO * fip) +static unsigned long findstreamstart(FILEINFO * fip) { SEGINFO tmp; assert(!fip->sequentialaccess); /* D.2 Random-access organisation */ @@ -637,8 +637,8 @@ static off_t findstreamstart(FILEINFO * fip) @ @c static void rd_jbig2_info(FILEINFO * fip) { - off_t seekdist = 0; /* for sequential-access only */ - off_t 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; @@ -682,8 +682,8 @@ static void rd_jbig2_info(FILEINFO * fip) sip->dataend = sip->datastart + sip->segdatalen; if (!fip->sequentialaccess && (sip->pageinfoflag || sip->endofstripeflag)) - xfseeko(fip->file, sip->datastart, SEEK_SET, fip->filepath); - seekdist = (off_t) sip->segdatalen; + xfseeko(fip->file, (off_t) sip->datastart, SEEK_SET, fip->filepath); + seekdist = sip->segdatalen; /* 7.4.8 Page information segment syntax */ if (sip->pageinfoflag) { pip->pagenum = (unsigned long) sip->segpage; @@ -702,11 +702,11 @@ static void rd_jbig2_info(FILEINFO * fip) } if (!fip->sequentialaccess && (sip->pageinfoflag || sip->endofstripeflag)) - xfseeko(fip->file, sip->hdrend, SEEK_SET, fip->filepath); + xfseeko(fip->file, (off_t) sip->hdrend, SEEK_SET, fip->filepath); if (!fip->sequentialaccess) streampos += sip->segdatalen; if (fip->sequentialaccess) - xfseeko(fip->file, seekdist, SEEK_CUR, fip->filepath); + xfseeko(fip->file, (off_t) seekdist, SEEK_CUR, fip->filepath); if (sip->endofpageflag && currentpage && (pip->stripinginfo >> 15)) pip->height = pip->stripedheight; } @@ -717,53 +717,70 @@ static void rd_jbig2_info(FILEINFO * fip) } @ @c -static void wr_jbig2(PDF pdf, FILEINFO * fip, unsigned long page) +static void wr_jbig2(PDF pdf, image_dict * idict, FILEINFO * fip, + unsigned long page) { LITEM *slip; PAGEINFO *pip; SEGINFO *sip; - off_t i; + unsigned long i; if (page > 0) { + assert(idict != NULL); pip = find_pageinfo(&(fip->pages), page); assert(pip != NULL); - pdf_puts(pdf, "/Type /XObject\n/Subtype /Image\n"); - pdf_printf(pdf, "/Width %i\n", pip->width); - pdf_printf(pdf, "/Height %i\n", pip->height); - pdf_puts(pdf, "/ColorSpace /DeviceGray\n"); - pdf_puts(pdf, "/BitsPerComponent 1\n"); - pdf_printf(pdf, "/Length %" LONGINTEGER_PRI "d\n", - (LONGINTEGER_TYPE) getstreamlen(pip->segments.first, true)); - pdf_puts(pdf, "/Filter [/JBIG2Decode]\n"); + 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); + pdf_dict_add_int(pdf, "Width", pip->width); + 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_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); } - pdf_printf(pdf, "/DecodeParms [<< /JBIG2Globals %lu 0 R >>]\n", - fip->pdfpage0objnum); + pdf_add_name(pdf, "DecodeParms"); + pdf_begin_array(pdf); + pdf_begin_dict(pdf); + pdf_dict_add_ref(pdf, "JBIG2Globals", fip->pdfpage0objnum); + pdf_end_dict(pdf); + pdf_end_array(pdf); } + pdf_end_dict(pdf); } else { + assert(idict == NULL); pip = find_pageinfo(&(fip->page0), page); assert(pip != NULL); - pdf_begin_dict(pdf, (int) fip->pdfpage0objnum, 0); - pdf_printf(pdf, "/Length %" LONGINTEGER_PRI "d\n", - (LONGINTEGER_TYPE) getstreamlen(pip->segments.first, false)); + 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_end_dict(pdf); } - pdf_puts(pdf, ">>\n"); - pdf_puts(pdf, "stream\n"); + pdf_begin_stream(pdf); fip->file = xfopen(fip->filepath, FOPEN_RBIN_MODE); for (slip = pip->segments.first; slip != NULL; slip = slip->next) { /* loop over page segments */ sip = slip->d; if (sip->isrefered || page > 0) { - xfseeko(fip->file, sip->hdrstart, SEEK_SET, fip->filepath); + xfseeko(fip->file, (off_t) sip->hdrstart, SEEK_SET, fip->filepath); /* mark refered-to page 0 segments, change segpages > 1 to 1 */ writeseghdr(pdf, fip, sip); - xfseeko(fip->file, sip->datastart, SEEK_SET, fip->filepath); + xfseeko(fip->file, (off_t) sip->datastart, SEEK_SET, fip->filepath); for (i = sip->datastart; i < sip->dataend; i++) pdf_out(pdf, ygetc(fip->file)); } } pdf_end_stream(pdf); + pdf_end_obj(pdf); xfclose(fip->file, fip->filepath); } @@ -825,7 +842,7 @@ void write_jbig2(PDF pdf, image_dict * idict) assert(fip->phase == HAVEINFO); /* don't write before |rd_jbig2_info()| call */ pip = find_pageinfo(&(fip->pages), (unsigned long) img_pagenum(idict)); assert(pip != NULL); - wr_jbig2(pdf, fip, pip->pagenum); + wr_jbig2(pdf, idict, fip, pip->pagenum); img_file(idict) = NULL; } @@ -839,7 +856,7 @@ void flush_jbig2_page0_objects(PDF pdf) for (fip = avl_t_first(&t, file_tree); fip != NULL; fip = avl_t_next(&t)) { if (fip->page0.last != NULL) - wr_jbig2(pdf, fip, 0); + wr_jbig2(pdf, NULL, fip, 0); /* NULL: page0 */ } } } diff --git a/Build/source/texk/web2c/luatexdir/image/writejp2.w b/Build/source/texk/web2c/luatexdir/image/writejp2.w index 6317c36ee3f..4ce7d017dad 100644 --- a/Build/source/texk/web2c/luatexdir/image/writejp2.w +++ b/Build/source/texk/web2c/luatexdir/image/writejp2.w @@ -1,27 +1,27 @@ % writejp2.w - -% Copyright 2011 Taco Hoekwater <taco@@luatex.org> -% Copyright 2011 Hartmut Henkel <hartmut@@luatex.org> - +% +% Copyright 2011-2012 Taco Hoekwater <taco@@luatex.org> +% Copyright 2011-2012 Hartmut Henkel <hartmut@@luatex.org> +% % This file is part of LuaTeX. - +% % 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. - +% % 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 LuaTeX; if not, see <http://www.gnu.org/licenses/>. @ @c static const char _svn_version[] = - "$Id: writejp2.w 4133 2011-04-11 16:54:11Z oneiros $ " - "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.66.0/source/texk/web2c/luatexdir/image/writejp2.w $"; + "$Id: writejp2.w 4479 2012-11-07 16:38:55Z taco $" + "$URL: http://foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/image/writejp2.w $"; @ Basic JPEG~2000 image support. Section and Table references below: Information technology --- JPEG~2000 image coding system: Core coding system. @@ -54,7 +54,7 @@ typedef struct { unsigned int tbox; } hdr_struct; -static uint64_t read8bytes(FILE * f) +static unsigned long long read8bytes(FILE * f) { uint64_t l = read4bytes(f); l = (l << 32) + read4bytes(f); @@ -76,18 +76,18 @@ static hdr_struct read_boxhdr(image_dict * idict) /* 1.5.3.1 Image Header box */ static void scan_ihdr(image_dict * idict) { - unsigned int height, width, nc; - unsigned char bpc, c, unkc, ipr; + unsigned int height, width; + unsigned char bpc; height = read4bytes(img_file(idict)); width = read4bytes(img_file(idict)); img_ysize(idict) = (int) height; img_xsize(idict) = (int) width; - nc = read2bytes(img_file(idict)); + (void) read2bytes(img_file(idict)); /* nc */ bpc = (unsigned char) xgetc(img_file(idict)); img_colordepth(idict) = bpc + 1; - c = (unsigned char) xgetc(img_file(idict)); - unkc = (unsigned char) xgetc(img_file(idict)); - ipr = (unsigned char) xgetc(img_file(idict)); + (void) xgetc(img_file(idict)); /* c */ + (void) xgetc(img_file(idict)); /* unkc */ + (void) xgetc(img_file(idict)); /* ipr */ } /* 1.5.3.7.1 Capture Resolution box */ @@ -261,22 +261,28 @@ static void reopen_jp2(image_dict * idict) void write_jp2(PDF pdf, image_dict * idict) { long unsigned l; - FILE *f; assert(idict != NULL); if (img_file(idict) == NULL) reopen_jp2(idict); - xfseek(img_file(idict), 0, SEEK_SET, img_filepath(idict)); assert(img_jp2_ptr(idict) != NULL); - pdf_puts(pdf, "/Type /XObject\n/Subtype /Image\n"); + 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) - pdf_printf(pdf, "%s\n", img_attr(idict)); - pdf_printf(pdf, "/Width %i\n/Height %i\n/Length %i\n", - (int) img_xsize(idict), - (int) img_ysize(idict), (int) img_jp2_ptr(idict)->length); - pdf_puts(pdf, "/Filter /JPXDecode\n>>\nstream\n"); - for (l = (long unsigned int) img_jp2_ptr(idict)->length, f = - img_file(idict); l > 0; l--) - pdf_out(pdf, xgetc(f)); + 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, "Length", (int) img_jp2_ptr(idict)->length); + pdf_dict_add_name(pdf, "Filter", "JPXDecode"); + pdf_end_dict(pdf); + pdf_begin_stream(pdf); + 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) + pdftex_fail("writejp2: fread failed"); pdf_end_stream(pdf); + pdf_end_obj(pdf); close_and_cleanup_jp2(idict); } diff --git a/Build/source/texk/web2c/luatexdir/image/writejpg.w b/Build/source/texk/web2c/luatexdir/image/writejpg.w index e7a202c54f3..75becb49a1c 100644 --- a/Build/source/texk/web2c/luatexdir/image/writejpg.w +++ b/Build/source/texk/web2c/luatexdir/image/writejpg.w @@ -1,27 +1,27 @@ % writejpg.w - +% % Copyright 1996-2006 Han The Thanh <thanh@@pdftex.org> -% Copyright 2006-2010 Taco Hoekwater <taco@@luatex.org> - +% Copyright 2006-2011 Taco Hoekwater <taco@@luatex.org> +% % This file is part of LuaTeX. - +% % 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. - +% % 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 LuaTeX; if not, see <http://www.gnu.org/licenses/>. +% with LuaTeX; if not, see <http://www.gnu.org/licenses/>. @ @c static const char _svn_version[] = - "$Id: writejpg.w 4095 2011-03-31 21:14:27Z hhenkel $ " - "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.66.0/source/texk/web2c/luatexdir/image/writejpg.w $"; + "$Id: writejpg.w 4442 2012-05-25 22:40:34Z hhenkel $" + "$URL: http://foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/image/writejpg.w $"; #include <assert.h> #include "ptexlib.h" @@ -249,41 +249,60 @@ static void reopen_jpg(PDF pdf, image_dict * idict) @ @c void write_jpg(PDF pdf, image_dict * idict) { - long unsigned l; - FILE *f; + size_t l; assert(idict != NULL); if (img_file(idict) == NULL) reopen_jpg(pdf, idict); assert(img_jpg_ptr(idict) != NULL); - pdf_puts(pdf, "/Type /XObject\n/Subtype /Image\n"); + 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) - pdf_printf(pdf, "%s\n", img_attr(idict)); - pdf_printf(pdf, "/Width %i\n/Height %i\n/BitsPerComponent %i\n/Length %i\n", - (int) img_xsize(idict), - (int) img_ysize(idict), - (int) img_colordepth(idict), (int) img_jpg_ptr(idict)->length); - pdf_puts(pdf, "/ColorSpace "); + 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)); + pdf_dict_add_int(pdf, "Length", (int) img_jpg_ptr(idict)->length); if (img_colorspace(idict) != 0) { - pdf_printf(pdf, "%i 0 R\n", (int) img_colorspace(idict)); + pdf_dict_add_ref(pdf, "ColorSpace", (int) img_colorspace(idict)); } else { switch (img_jpg_color(idict)) { case JPG_GRAY: - pdf_puts(pdf, "/DeviceGray\n"); + pdf_dict_add_name(pdf, "ColorSpace", "DeviceGray"); break; case JPG_RGB: - pdf_puts(pdf, "/DeviceRGB\n"); + pdf_dict_add_name(pdf, "ColorSpace", "DeviceRGB"); break; case JPG_CMYK: - pdf_puts(pdf, "/DeviceCMYK\n/Decode [1 0 1 0 1 0 1 0]\n"); + 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: pdftex_fail("Unsupported color space %i", (int) img_jpg_color(idict)); } } - pdf_puts(pdf, "/Filter /DCTDecode\n>>\nstream\n"); - for (l = img_jpg_ptr(idict)->length, f = img_file(idict); l > 0; l--) - pdf_out(pdf, xgetc(f)); + 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) + pdftex_fail("writejpg: fread failed"); pdf_end_stream(pdf); + pdf_end_obj(pdf); 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 56a96436389..d728582014a 100644 --- a/Build/source/texk/web2c/luatexdir/image/writepng.h +++ b/Build/source/texk/web2c/luatexdir/image/writepng.h @@ -1,7 +1,7 @@ /* writepng.h Copyright 1996-2006 Han The Thanh <thanh@pdftex.org> - Copyright 2006-2009 Taco Hoekwater <taco@luatex.org> + Copyright 2006-2011 Taco Hoekwater <taco@luatex.org> This file is part of LuaTeX. @@ -18,14 +18,14 @@ You should have received a copy of the GNU General Public License along with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */ -/* $Id: writepng.h 2580 2009-06-23 15:55:52Z taco $ */ +/* $Id: writepng.h 4227 2011-04-30 07:11:25Z oneiros $ */ #ifndef WRITEPNG_H # define WRITEPNG_H # include "image.h" -void read_png_info(PDF, image_dict *, img_readtype_e); +void read_png_info(image_dict *, img_readtype_e); void write_additional_png_objects(PDF); void write_png(PDF, image_dict *); diff --git a/Build/source/texk/web2c/luatexdir/image/writepng.w b/Build/source/texk/web2c/luatexdir/image/writepng.w index 08daac984e6..3464f9205fa 100644 --- a/Build/source/texk/web2c/luatexdir/image/writepng.w +++ b/Build/source/texk/web2c/luatexdir/image/writepng.w @@ -1,27 +1,27 @@ % writepng.w - +% % Copyright 1996-2006 Han The Thanh <thanh@@pdftex.org> -% Copyright 2006-2010 Taco Hoekwater <taco@@luatex.org> - +% Copyright 2006-2011 Taco Hoekwater <taco@@luatex.org> +% % This file is part of LuaTeX. - +% % 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. - +% % 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 LuaTeX; if not, see <http://www.gnu.org/licenses/>. +% with LuaTeX; if not, see <http://www.gnu.org/licenses/>. @ @c static const char _svn_version[] = - "$Id: writepng.w 4258 2011-05-11 05:36:13Z taco $ " - "$URL: http://foundry.supelec.fr/svn/luatex/branches/0.70.x/source/texk/web2c/luatexdir/image/writepng.w $"; + "$Id: writepng.w 4442 2012-05-25 22:40:34Z hhenkel $" + "$URL: http://foundry.supelec.fr/svn/luatex/trunk/source/texk/web2c/luatexdir/image/writepng.w $"; #include <assert.h> #include "ptexlib.h" @@ -45,7 +45,7 @@ static void close_and_cleanup_png(image_dict * idict) } @ @c -void read_png_info(PDF pdf, image_dict * idict, img_readtype_e readtype) +void read_png_info(image_dict * idict, img_readtype_e readtype) { png_structp png_p; png_infop info_p; @@ -100,139 +100,154 @@ void read_png_info(PDF pdf, image_dict * idict, img_readtype_e readtype) } @ @c -#define write_gray_pixel_16(r) \ - if (j % 4 == 0||j % 4 == 1) pdf_quick_out(pdf,*r++); \ - else smask[smask_ptr++] = *r++ - -#define write_gray_pixel_8(r) \ - if (j % 2 == 0) pdf_quick_out(pdf,*r++); \ - else smask[smask_ptr++] = *r++ - -#define write_rgb_pixel_16(r) \ - if (!(j % 8 == 6||j % 8 == 7)) pdf_quick_out(pdf,*r++); \ - else smask[smask_ptr++] = *r++ - -#define write_rgb_pixel_8(r) \ - if (j % 4 != 3) pdf_quick_out(pdf,*r++); \ - else smask[smask_ptr++] = *r++ +#define write_gray_pixel_16(r) \ + if (j % 4 == 0 || j % 4 == 1) \ + pdf_quick_out(pdf, *r++); \ + else \ + smask[smask_ptr++] = *r++ \ + +#define write_gray_pixel_8(r) \ + if (j % 2 == 0) \ + pdf_quick_out(pdf, *r++); \ + else \ + smask[smask_ptr++] = *r++ + +#define write_rgb_pixel_16(r) \ + if (!(j % 8 == 6 || j % 8 == 7)) \ + pdf_quick_out(pdf, *r++); \ + else \ + smask[smask_ptr++] = *r++ + +#define write_rgb_pixel_8(r) \ + if (j % 4 != 3) \ + pdf_quick_out(pdf, *r++); \ + else \ + smask[smask_ptr++] = *r++ #define write_simple_pixel(r) pdf_quick_out(pdf,*r++) -#define write_noninterlaced(outmac) \ - for (i = 0; i < (int)png_get_image_height (png_p, info_p); i++) { \ - png_read_row(png_p, row, NULL); \ - r = row; \ - k = (int)png_get_rowbytes(png_p, info_p); \ - while(k > 0) { \ - l = (k > pdf->buf_size)? pdf->buf_size : k; \ - pdf_room(pdf,l); \ - for (j = 0; j < l; j++) { \ - outmac; \ - } \ - k -= l; \ - } \ - } +#define write_noninterlaced(outmac) \ + for (i = 0; i < (int) png_get_image_height(png_p, info_p); i++) { \ + png_read_row(png_p, row, NULL); \ + r = row; \ + k = (size_t) png_get_rowbytes(png_p, info_p); \ + while (k > 0) { \ + l = (k > pdf->buf->size) ? pdf->buf->size : k; \ + pdf_room(pdf, l); \ + for (j = 0; j < l; j++) { \ + outmac; \ + } \ + k -= l; \ + } \ + } -#define write_interlaced(outmac) \ - for (i = 0; i < (int)png_get_image_height (png_p, info_p); i++) { \ - row = rows[i]; \ - k = (int)png_get_rowbytes(png_p, info_p); \ - while(k > 0) { \ - l = (k > pdf->buf_size)?pdf->buf_size: k;\ - pdf_room(pdf,l); \ - for (j = 0; j < l; j++) { \ - outmac; \ - } \ - k -= l; \ - } \ - xfree(rows[i]); \ - } +#define write_interlaced(outmac) \ + for (i = 0; i < (int) png_get_image_height(png_p, info_p); i++) { \ + row = rows[i]; \ + k = (size_t) png_get_rowbytes(png_p, info_p); \ + while (k > 0) { \ + l = (k > pdf->buf->size) ? pdf->buf->size : k; \ + pdf_room(pdf, l); \ + for (j = 0; j < l; j++) { \ + outmac; \ + } \ + k -= l; \ + } \ + xfree(rows[i]); \ + } + +@ @c +static void write_palette_streamobj(PDF pdf, int palette_objnum, + png_colorp palette, int num_palette) +{ + int i; + if (palette_objnum == 0) + return; + assert(palette != NULL); + pdf_begin_obj(pdf, palette_objnum, OBJSTM_NEVER); + pdf_begin_dict(pdf); + pdf_dict_add_streaminfo(pdf); + pdf_end_dict(pdf); + pdf_begin_stream(pdf); + for (i = 0; i < num_palette; i++) { + pdf_room(pdf, 3); + pdf_quick_out(pdf, palette[i].red); + pdf_quick_out(pdf, palette[i].green); + pdf_quick_out(pdf, palette[i].blue); + } + pdf_end_stream(pdf); + pdf_end_obj(pdf); +} @ @c -static void write_png_palette(PDF pdf, image_dict * idict) +static void write_smask_streamobj(PDF pdf, image_dict * idict, int smask_objnum, + png_bytep smask, int smask_size) { - int i, j, k, l; + int i; png_structp png_p = img_png_png_ptr(idict); png_infop info_p = img_png_info_ptr(idict); - png_bytep row, r, *rows; - int palette_objnum = 0; - png_colorp palette; - int num_palette; - - png_get_PLTE(png_p, info_p, &palette, &num_palette); - - if (img_colorspace(idict) != 0) { - pdf_printf(pdf, "%i 0 R\n", (int) img_colorspace(idict)); - } else { - palette_objnum = pdf_create_obj(pdf, obj_type_others, 0); - pdf_printf(pdf, "[/Indexed /DeviceRGB %i %i 0 R]\n", - (int) (num_palette - 1), (int) palette_objnum); - } + png_byte bitdepth = png_get_bit_depth(png_p, info_p); + pdf_begin_obj(pdf, smask_objnum, 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) + 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", (bitdepth == 16 ? 8 : bitdepth)); + pdf_dict_add_name(pdf, "ColorSpace", "DeviceGray"); + 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); - 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) - pdftex_warn - ("large interlaced PNG might cause out of memory (use non-interlaced PNG to fix this)"); - rows = xtalloc(png_get_image_height (png_p, info_p), png_bytep); - for (i = 0; (unsigned) i < 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); + for (i = 0; i < smask_size; i++) { + if (i % 8 == 0) + pdf_room(pdf, 8); + pdf_quick_out(pdf, smask[i]); + if (bitdepth == 16) + i++; } pdf_end_stream(pdf); - if (palette_objnum > 0) { - pdf_begin_dict(pdf, palette_objnum, 0); - pdf_begin_stream(pdf); - for (i = 0; i < num_palette; i++) { - pdf_room(pdf, 3); - pdf_quick_out(pdf, palette[i].red); - pdf_quick_out(pdf, palette[i].green); - pdf_quick_out(pdf, palette[i].blue); - } - pdf_end_stream(pdf); - } + pdf_end_obj(pdf); } @ @c static void write_png_gray(PDF pdf, image_dict * idict) { - int i, j, k, l; + int i; + size_t j, k, l; png_structp png_p = img_png_png_ptr(idict); png_infop info_p = img_png_info_ptr(idict); png_bytep row, r, *rows; - if (img_colorspace(idict) != 0) { - pdf_printf(pdf, "%i 0 R\n", (int) img_colorspace(idict)); - } else { - pdf_puts(pdf, "/DeviceGray\n"); - } + 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); 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) + if (png_get_image_height(png_p, info_p) * + png_get_rowbytes(png_p, info_p) >= 10240000L) pdftex_warn ("large interlaced PNG might cause out of memory (use non-interlaced PNG to fix this)"); - rows = xtalloc(png_get_image_height (png_p, info_p), png_bytep); - for (i = 0; (unsigned) i < png_get_image_height (png_p, info_p); i++) + 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++) 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); } pdf_end_stream(pdf); + pdf_end_obj(pdf); } @ @c static void write_png_gray_alpha(PDF pdf, image_dict * idict) { - int i, j, k, l; + int i; + size_t j, k, l; png_structp png_p = img_png_png_ptr(idict); png_infop info_p = img_png_info_ptr(idict); png_bytep row, r, *rows; @@ -240,34 +255,35 @@ static void write_png_gray_alpha(PDF pdf, image_dict * idict) png_bytep smask; int smask_ptr = 0; int smask_size = 0; - png_byte bitdepth; - if (img_colorspace(idict) != 0) { - pdf_printf(pdf, "%i 0 R\n", (int) img_colorspace(idict)); - } else { - pdf_puts(pdf, "/DeviceGray\n"); - } smask_objnum = pdf_create_obj(pdf, obj_type_others, 0); - pdf_printf(pdf, "/SMask %i 0 R\n", (int) smask_objnum); - smask_size = (int) ((png_get_rowbytes(png_p, info_p) / 2) * png_get_image_height (png_p, info_p)); + 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 = 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) + if (png_get_image_height(png_p, info_p) * + png_get_rowbytes(png_p, info_p) >= 10240000L) pdftex_warn ("large interlaced PNG might cause out of memory (use non-interlaced PNG to fix this)"); - rows = xtalloc(png_get_image_height (png_p, info_p), png_bytep); - for (i = 0; (unsigned) i < png_get_image_height (png_p, info_p); i++) + 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++) 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)); @@ -275,65 +291,16 @@ static void write_png_gray_alpha(PDF pdf, image_dict * idict) xfree(rows); } pdf_end_stream(pdf); - pdf_flush(pdf); - /* now write the Smask object */ - bitdepth = png_get_bit_depth (png_p, info_p); - pdf_begin_dict(pdf, smask_objnum, 0); - pdf_puts(pdf, "/Type /XObject\n/Subtype /Image\n"); - if (img_attr(idict) != NULL && strlen(img_attr(idict)) > 0) - pdf_printf(pdf, "%s\n", img_attr(idict)); - pdf_printf(pdf, "/Width %i\n/Height %i\n/BitsPerComponent %i\n", - (int) png_get_image_width (png_p, info_p), - (int) png_get_image_height (png_p, info_p), - (bitdepth == 16 ? 8 : bitdepth)); - pdf_puts(pdf, "/ColorSpace /DeviceGray\n"); - pdf_begin_stream(pdf); - for (i = 0; i < smask_size; i++) { - if (i % 8 == 0) - pdf_room(pdf, 8); - pdf_quick_out(pdf, smask[i]); - if (bitdepth == 16) - i++; - } - pdf_end_stream(pdf); + pdf_end_obj(pdf); + write_smask_streamobj(pdf, idict, smask_objnum, smask, smask_size); xfree(smask); } @ @c -static void write_png_rgb(PDF pdf, image_dict * idict) -{ - int i, j, k, l; - png_structp png_p = img_png_png_ptr(idict); - png_infop info_p = img_png_info_ptr(idict); - png_bytep row, r, *rows; - if (img_colorspace(idict) != 0) { - pdf_printf(pdf, "%i 0 R\n", (int) img_colorspace(idict)); - } else { - pdf_puts(pdf, "/DeviceRGB\n"); - } - 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); - 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) - pdftex_warn - ("large interlaced PNG might cause out of memory (use non-interlaced PNG to fix this)"); - rows = xtalloc(png_get_image_height (png_p, info_p), png_bytep); - for (i = 0; (unsigned) i < 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); - } - pdf_end_stream(pdf); -} - -@ @c static void write_png_rgb_alpha(PDF pdf, image_dict * idict) { - int i, j, k, l; + int i; + size_t j, k, l; png_structp png_p = img_png_png_ptr(idict); png_infop info_p = img_png_info_ptr(idict); png_bytep row, r, *rows; @@ -341,34 +308,35 @@ static void write_png_rgb_alpha(PDF pdf, image_dict * idict) png_bytep smask; int smask_ptr = 0; int smask_size = 0; - png_byte bitdepth; - if (img_colorspace(idict) != 0) { - pdf_printf(pdf, "%i 0 R\n", (int) img_colorspace(idict)); - } else { - pdf_puts(pdf, "/DeviceRGB\n"); - } smask_objnum = pdf_create_obj(pdf, obj_type_others, 0); - pdf_printf(pdf, "/SMask %i 0 R\n", (int) smask_objnum); - smask_size = (int) ((png_get_rowbytes (png_p, info_p) / 4) * png_get_image_height (png_p, info_p)); + 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 = 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) + if (png_get_image_height(png_p, info_p) * + png_get_rowbytes(png_p, info_p) >= 10240000L) pdftex_warn ("large interlaced PNG might cause out of memory (use non-interlaced PNG to fix this)"); - rows = xtalloc(png_get_image_height (png_p, info_p), png_bytep); - for (i = 0; (unsigned) i < png_get_image_height (png_p, info_p); i++) + 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++) 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)); @@ -376,47 +344,29 @@ static void write_png_rgb_alpha(PDF pdf, image_dict * idict) xfree(rows); } pdf_end_stream(pdf); - pdf_flush(pdf); - /* now write the Smask object */ - if (smask_objnum > 0) { - bitdepth = png_get_bit_depth (png_p, info_p); - pdf_begin_dict(pdf, smask_objnum, 0); - pdf_puts(pdf, "/Type /XObject\n/Subtype /Image\n"); - if (img_attr(idict) != NULL && strlen(img_attr(idict)) > 0) - pdf_printf(pdf, "%s\n", img_attr(idict)); - pdf_printf(pdf, "/Width %i\n/Height %i\n/BitsPerComponent %i\n", - (int) png_get_image_width (png_p, info_p), - (int) png_get_image_height (png_p, info_p), - (bitdepth == 16 ? 8 : bitdepth)); - pdf_puts(pdf, "/ColorSpace /DeviceGray\n"); - pdf_begin_stream(pdf); - for (i = 0; i < smask_size; i++) { - if (i % 8 == 0) - pdf_room(pdf, 8); - pdf_quick_out(pdf, smask[i]); - if (bitdepth == 16) - i++; - } - xfree(smask); - pdf_end_stream(pdf); - } + pdf_end_obj(pdf); + write_smask_streamobj(pdf, idict, smask_objnum, smask, smask_size); + xfree(smask); } -@ The |copy_png| function is from Hartmut Henkel. The goal is to use -pdf's native FlateDecode support if that is possible. - -Only a subset of the png files allows this, but when possible it -greatly improves inclusion speed. - -Code cheerfully gleaned from Thomas Merz' PDFlib, -file |p_png.c| "SPNG - Simple PNG" +@ The |copy_png| code is cheerfully gleaned from Thomas Merz' PDFlib, +file |p_png.c| ``SPNG - Simple PNG''. +The goal is to use pdf's native FlateDecode support, if that is possible. +Only a subset of the png files allows this, but for these it greatly +improves inclusion speed. +In the ``PNG Copy'' mode only the IDAT chunks are copied; +all other chunks from the PNG file are discarded. +If there are any other chunks in the PNG file, +which might influence the visual appearance of the image, +or if image processing like gamma change is requested, +the ``PNG Copy'' function must be skipped; therefore the lengthy tests. @c -static int spng_getint(FILE * fp) +static int spng_getint(FILE * f) { unsigned char buf[4]; - if (fread(buf, 1, 4, fp) != 4) + if (fread(buf, 1, 4, f) != 4) pdftex_fail("writepng: reading chunk type failed"); return ((((((int) buf[0] << 8) + buf[1]) << 8) + buf[2]) << 8) + buf[3]; } @@ -426,22 +376,22 @@ static int spng_getint(FILE * fp) static void copy_png(PDF pdf, image_dict * idict) { + int type, streamlength = 0, idat = 0; + size_t len; + boolean endflag = false; + FILE *f; png_structp png_p; png_infop info_p; - FILE *fp; - int i, len, type, streamlength = 0; - boolean endflag = false; - int idat = 0; /* flag to check continuous IDAT chunks sequence */ assert(idict != NULL); png_p = img_png_png_ptr(idict); info_p = img_png_info_ptr(idict); - fp = (FILE *) png_get_io_ptr(png_p); + f = (FILE *) png_get_io_ptr(png_p); /* 1st pass to find overall stream /Length */ - if (fseek(fp, 8, SEEK_SET) != 0) - pdftex_fail("writepng: fseek in PNG file failed"); + if (fseek(f, 8, SEEK_SET) != 0) + pdftex_fail("writepng: fseek in PNG file failed (1)"); do { - len = spng_getint(fp); - type = spng_getint(fp); + len = spng_getint(f); + type = spng_getint(f); switch (type) { case SPNG_CHUNK_IEND: endflag = true; @@ -449,64 +399,64 @@ static void copy_png(PDF pdf, image_dict * idict) case SPNG_CHUNK_IDAT: streamlength += len; default: - if (fseek(fp, len + 4, SEEK_CUR) != 0) - pdftex_fail("writepng: fseek in PNG file failed"); + if (fseek(f, len + 4, SEEK_CUR) != 0) + pdftex_fail("writepng: fseek in PNG file failed (2)"); } } while (endflag == false); - pdf_printf(pdf, "/Length %d\n" - "/Filter/FlateDecode\n" - "/DecodeParms<<" - "/Colors %d" - "/Columns %u" - "/BitsPerComponent %i" - "/Predictor 10>>\n>>\nstream\n", streamlength, - png_get_color_type (png_p, info_p) == 2 ? 3 : 1, - png_get_image_width (png_p, info_p), - png_get_bit_depth (png_p, info_p)); + 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, "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 */ /* 2nd pass to copy data */ endflag = false; - if (fseek(fp, 8, SEEK_SET) != 0) - pdftex_fail("writepng: fseek in PNG file failed"); + if (fseek(f, 8, SEEK_SET) != 0) + pdftex_fail("writepng: fseek in PNG file failed (3)"); do { - len = spng_getint(fp); - type = spng_getint(fp); + len = spng_getint(f); + type = spng_getint(f); switch (type) { case SPNG_CHUNK_IDAT: /* do copy */ if (idat == 2) pdftex_fail("writepng: IDAT chunk sequence broken"); idat = 1; - while (len > 0) { - i = (len > pdf->buf_size) ? pdf->buf_size : len; - pdf_room(pdf, i); - fread(&pdf->buf[pdf->ptr], 1, (size_t) i, fp); - pdf->ptr += i; - len -= i; - } - if (fseek(fp, 4, SEEK_CUR) != 0) - pdftex_fail("writepng: fseek in PNG file failed"); + if (read_file_to_buf(pdf, f, len) != len) + pdftex_fail("writepng: fread failed"); + if (fseek(f, 4, SEEK_CUR) != 0) + pdftex_fail("writepng: fseek in PNG file failed (4)"); break; case SPNG_CHUNK_IEND: /* done */ - pdf_end_stream(pdf); endflag = true; break; default: if (idat == 1) idat = 2; - if (fseek(fp, len + 4, SEEK_CUR) != 0) - pdftex_fail("writepng: fseek in PNG file failed"); + if (fseek(f, len + 4, SEEK_CUR) != 0) + pdftex_fail("writepng: fseek in PNG file failed (5)"); } } while (endflag == false); + pdf_end_stream(pdf); + pdf_end_obj(pdf); } @ @c -static void reopen_png(PDF pdf, image_dict * idict) +static void reopen_png(image_dict * idict) { int width, height, xres, yres; width = img_xsize(idict); /* do consistency check */ height = img_ysize(idict); xres = img_xres(idict); yres = img_yres(idict); - read_png_info(pdf, idict, IMG_KEEPOPEN); + read_png_info(idict, IMG_KEEPOPEN); if (width != img_xsize(idict) || height != img_ysize(idict) || xres != img_xres(idict) || yres != img_yres(idict)) pdftex_fail("writepng: image dimensions have changed"); @@ -517,29 +467,24 @@ static boolean last_png_needs_page_group; void write_png(PDF pdf, image_dict * idict) { +#ifndef PNG_FP_1 + /* for libpng < 1.5.0 */ +# define PNG_FP_1 100000 +#endif + int num_palette, palette_objnum = 0; boolean png_copy = true; double gamma = 0.0; png_fixed_point int_file_gamma = 0; -#ifndef PNG_FP_1 - /* for libpng < 1.5.0 */ -#define PNG_FP_1 100000 -#endif - int i; - int palette_objnum = 0; png_structp png_p; png_infop info_p; + png_colorp palette; assert(idict != NULL); last_png_needs_page_group = false; if (img_file(idict) == NULL) - reopen_png(pdf, idict); + reopen_png(idict); assert(img_png_ptr(idict) != NULL); png_p = img_png_png_ptr(idict); info_p = img_png_info_ptr(idict); - if (pdf->minor_version < 5) - pdf->image_hicolor = 0; - pdf_puts(pdf, "/Type /XObject\n/Subtype /Image\n"); - if (img_attr(idict) != NULL && strlen(img_attr(idict)) > 0) - pdf_printf(pdf, "%s\n", img_attr(idict)); /* simple transparency support */ if (png_get_valid(png_p, info_p, PNG_INFO_tRNS)) { png_set_tRNS_to_alpha(png_p); @@ -575,11 +520,45 @@ void write_png(PDF pdf, image_dict * idict) (void) png_set_interlace_handling(png_p); png_read_update_info(png_p, info_p); - pdf_printf(pdf, "/Width %i\n/Height %i\n/BitsPerComponent %i\n", - (int) png_get_image_width(png_p, info_p), - (int) png_get_image_height(png_p, info_p), - (int) png_get_bit_depth(png_p, info_p)); - pdf_puts(pdf, "/ColorSpace "); + 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) + 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)); + 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: + pdftex_fail("unsupported type of color_type <%i>", + png_get_color_type(png_p, info_p)); + } + } 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 @@ -594,43 +573,11 @@ void write_png(PDF pdf, image_dict * idict) && !png_get_valid(png_p, info_p, PNG_INFO_bKGD) && !png_get_valid(png_p, info_p, PNG_INFO_hIST) && !png_get_valid(png_p, info_p, PNG_INFO_tRNS) - && !png_get_valid(png_p, info_p, PNG_INFO_sPLT) - ) { - /* Copy PNG */ - png_colorp palette; - int num_palette; - - png_get_PLTE(png_p, info_p, &palette, &num_palette); - if (img_colorspace(idict) != 0) { - pdf_printf(pdf, "%i 0 R\n", (int) img_colorspace(idict)); - } else { - switch (png_get_color_type(png_p, info_p)) { - case PNG_COLOR_TYPE_PALETTE: - palette_objnum = pdf_create_obj(pdf, obj_type_others, 0); - pdf_printf(pdf, "[/Indexed /DeviceRGB %i %i 0 R]\n", - num_palette - 1, (int) palette_objnum); - break; - case PNG_COLOR_TYPE_GRAY: - pdf_puts(pdf, "/DeviceGray\n"); - break; - default: /* RGB */ - pdf_puts(pdf, "/DeviceRGB\n"); - }; - } + && !png_get_valid(png_p, info_p, PNG_INFO_sPLT)) { + /* PNG copy */ if (tracefilenames) tex_printf(" (PNG copy)"); copy_png(pdf, idict); - if (palette_objnum > 0) { - pdf_begin_dict(pdf, palette_objnum, 0); - pdf_begin_stream(pdf); - for (i = 0; i < num_palette; i++) { - pdf_room(pdf, 3); - pdf_quick_out(pdf, palette[i].red); - pdf_quick_out(pdf, palette[i].green); - pdf_quick_out(pdf, palette[i].blue); - } - pdf_end_stream(pdf); - } } else { if (0) { tex_printf(" *** PNG copy skipped because: "); @@ -667,9 +614,8 @@ void write_png(PDF pdf, image_dict * idict) } switch (png_get_color_type(png_p, info_p)) { case PNG_COLOR_TYPE_PALETTE: - write_png_palette(pdf, idict); - break; case PNG_COLOR_TYPE_GRAY: + case PNG_COLOR_TYPE_RGB: write_png_gray(pdf, idict); break; case PNG_COLOR_TYPE_GRAY_ALPHA: @@ -679,22 +625,18 @@ void write_png(PDF pdf, image_dict * idict) } else write_png_gray(pdf, idict); break; - case PNG_COLOR_TYPE_RGB: - write_png_rgb(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_rgb(pdf, idict); + write_png_gray(pdf, idict); break; default: - pdftex_fail("unsupported type of color_type <%i>", - png_get_color_type(png_p, info_p)); + assert(0); } } - pdf_flush(pdf); + write_palette_streamobj(pdf, palette_objnum, palette, num_palette); close_and_cleanup_png(idict); } @@ -709,7 +651,7 @@ 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) { @@ -719,9 +661,13 @@ void write_additional_png_objects(PDF pdf) if (pdf->compress_level == 0) { pdf_puts(pdf, "%PTEX Group needed for transparent pngs\n"); } - pdf_puts - (pdf, - "<</Type/Group /S/Transparency /CS/DeviceRGB /I true /K true>>\n"); + pdf_begin_dict(pdf); + pdf_dict_add_name(pdf, "Type", "Group"); + pdf_dict_add_name(pdf, "S", "Transparency"); + pdf_dict_add_name(pdf, "CS", "DeviceRGB"); + pdf_dict_add_bool(pdf, "I", 1); + pdf_dict_add_bool(pdf, "K", 1); + pdf_end_dict(pdf); pdf_end_obj(pdf); } } |