summaryrefslogtreecommitdiff
path: root/Build/source/texk/web2c/luatexdir/image
diff options
context:
space:
mode:
authorPeter Breitenlohner <peb@mppmu.mpg.de>2013-03-21 09:16:59 +0000
committerPeter Breitenlohner <peb@mppmu.mpg.de>2013-03-21 09:16:59 +0000
commit388463b9fa865c3b2311508c41647b0f3c532031 (patch)
tree1cdfbf5552d0783ecbcc52017e49567e5042af33 /Build/source/texk/web2c/luatexdir/image
parentabd0b00a4e8c1ac6f5b20c7474d70ef579129991 (diff)
Import MetaPost 1.800 and LuaTeX beta-0.75.0 from LuaTeX repository r4604
git-svn-id: svn://tug.org/texlive/trunk@29453 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/web2c/luatexdir/image')
-rw-r--r--Build/source/texk/web2c/luatexdir/image/epdf.h44
-rw-r--r--Build/source/texk/web2c/luatexdir/image/image.h10
-rw-r--r--Build/source/texk/web2c/luatexdir/image/pdftoepdf.h9
-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.h6
-rw-r--r--Build/source/texk/web2c/luatexdir/image/writeimg.w129
-rw-r--r--Build/source/texk/web2c/luatexdir/image/writejbig2.w135
-rw-r--r--Build/source/texk/web2c/luatexdir/image/writejp2.w60
-rw-r--r--Build/source/texk/web2c/luatexdir/image/writejpg.w69
-rw-r--r--Build/source/texk/web2c/luatexdir/image/writepng.h6
-rw-r--r--Build/source/texk/web2c/luatexdir/image/writepng.w586
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);
}
}