summaryrefslogtreecommitdiff
path: root/Build/source/texk/web2c/luatexdir/image
diff options
context:
space:
mode:
authorTaco Hoekwater <taco@elvenkind.com>2010-04-04 13:55:46 +0000
committerTaco Hoekwater <taco@elvenkind.com>2010-04-04 13:55:46 +0000
commitf372862c42d234710b6057449b46818e63181c90 (patch)
treea9ebec66dd31ac37aed442502ebd1b9fe76245ec /Build/source/texk/web2c/luatexdir/image
parent2dad291ab056f30816e0aea61970f38033c2f6a5 (diff)
import luatex 0.60.0 (with small local changes, see luatexdir/ChangeLog)
and do an autoreconf git-svn-id: svn://tug.org/texlive/trunk@17680 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/web2c/luatexdir/image')
-rw-r--r--Build/source/texk/web2c/luatexdir/image/epdf.c81
-rw-r--r--Build/source/texk/web2c/luatexdir/image/epdf.h211
-rw-r--r--Build/source/texk/web2c/luatexdir/image/epdf.w34
-rw-r--r--Build/source/texk/web2c/luatexdir/image/image.h94
-rw-r--r--Build/source/texk/web2c/luatexdir/image/pdftoepdf.cc1103
-rw-r--r--Build/source/texk/web2c/luatexdir/image/pdftoepdf.h10
-rw-r--r--Build/source/texk/web2c/luatexdir/image/writeimg.c959
-rw-r--r--Build/source/texk/web2c/luatexdir/image/writeimg.h57
-rw-r--r--Build/source/texk/web2c/luatexdir/image/writeimg.w823
-rw-r--r--Build/source/texk/web2c/luatexdir/image/writejbig2.h6
-rw-r--r--Build/source/texk/web2c/luatexdir/image/writejbig2.w (renamed from Build/source/texk/web2c/luatexdir/image/writejbig2.c)257
-rw-r--r--Build/source/texk/web2c/luatexdir/image/writejpg.h6
-rw-r--r--Build/source/texk/web2c/luatexdir/image/writejpg.w (renamed from Build/source/texk/web2c/luatexdir/image/writejpg.c)111
-rw-r--r--Build/source/texk/web2c/luatexdir/image/writepng.h8
-rw-r--r--Build/source/texk/web2c/luatexdir/image/writepng.w (renamed from Build/source/texk/web2c/luatexdir/image/writepng.c)406
15 files changed, 1887 insertions, 2279 deletions
diff --git a/Build/source/texk/web2c/luatexdir/image/epdf.c b/Build/source/texk/web2c/luatexdir/image/epdf.c
deleted file mode 100644
index cf86a38fa34..00000000000
--- a/Build/source/texk/web2c/luatexdir/image/epdf.c
+++ /dev/null
@@ -1,81 +0,0 @@
-/* epdf.c
-
- Copyright 1996-2006 Han The Thanh <thanh@pdftex.org>
- Copyright 2006-2009 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/>. */
-
-#include "ptexlib.h"
-#include "inc-epdf.h"
-
-#include <string.h>
-
-static const char _svn_version[] =
- "$Id: epdf.c 2599 2009-06-25 10:35:26Z taco $ "
- "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/image/epdf.c $";
-
-fd_entry *epdf_create_fontdescriptor(fm_entry * fm, int stemV)
-{
- fd_entry *fd;
- if ((fd = lookup_fd_entry(fm->ff_name, fm->slant, fm->extend)) == NULL) {
- fm->in_use = true;
- fd = new_fd_entry();
- fd->fm = fm;
- register_fd_entry(fd);
- fd->fd_objnum = pdf_new_objnum();
- assert(fm->ps_name != NULL);
- fd->fontname = xstrdup(fm->ps_name); /* just fallback */
- // stemV must be copied
- fd->font_dim[STEMV_CODE].val = stemV;
- fd->font_dim[STEMV_CODE].set = true;
- fd->gl_tree = avl_create(comp_string_entry, NULL, &avl_xallocator);
- assert(fd->gl_tree != NULL);
- }
- return fd;
-}
-
-/***********************************************************************
- * Mark glyphs used by embedded PDF file:
- * 1. build fontdescriptor, if not yet existing
- * 2. mark glyphs directly there
- *
- * Input charset from xpdf is a string of glyph names including
- * leading slashes, but without blanks between them, like: /a/b/c
-***********************************************************************/
-
-void epdf_mark_glyphs(fd_entry * fd, char *charset)
-{
- char *p, *q, *s;
- char *glyph;
- void **aa;
- if (charset == NULL)
- return;
- assert(fd != NULL);
- for (s = charset + 1, q = charset + strlen(charset); s < q; s = p + 1) {
- for (p = s; *p != '\0' && *p != '/'; p++);
- *p = '\0';
- if ((char *) avl_find(fd->gl_tree, s) == NULL) {
- glyph = xstrdup(s);
- aa = avl_probe(fd->gl_tree, glyph);
- assert(aa != NULL);
- }
- }
-}
-
-void epdf_free(void)
-{
- epdf_check_mem();
-}
diff --git a/Build/source/texk/web2c/luatexdir/image/epdf.h b/Build/source/texk/web2c/luatexdir/image/epdf.h
index c619b20f08f..6d2632b0e54 100644
--- a/Build/source/texk/web2c/luatexdir/image/epdf.h
+++ b/Build/source/texk/web2c/luatexdir/image/epdf.h
@@ -1,8 +1,7 @@
/* epdf.h
Copyright 1996-2006 Han The Thanh <thanh@pdftex.org>
- Copyright 2006-2009 Taco Hoekwater <taco@luatex.org>
-
+ Copyright 2006-2010 Taco Hoekwater <taco@luatex.org>
This file is part of LuaTeX.
LuaTeX is free software; you can redistribute it and/or modify it under
@@ -18,11 +17,50 @@
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 2327 2009-04-18 12:47:21Z hhenkel $ */
+/* $Id: epdf.h 3407 2010-01-28 16:27:39Z taco $ */
+
+// this is the common header file for C++ sources pdftoepdf.cc and lepdflib.cc
+
+#ifndef EPDF_H
+# define EPDF_H
+
+# include <stdlib.h>
+# include <math.h>
+# include <stddef.h>
+# include <stdio.h>
+# include <string.h>
+# include <kpathsea/c-ctype.h>
+# include <sys/stat.h>
+# ifdef POPPLER_VERSION
+# define GString GooString
+# include <dirent.h>
+# include <poppler-config.h>
+# include <goo/GooString.h>
+# include <goo/gmem.h>
+# include <goo/gfile.h>
+# else
+# include <aconf.h>
+# include <GString.h>
+# include <gmem.h>
+# include <gfile.h>
+# include <assert.h>
+# endif
+# include "Object.h"
+# include "Stream.h"
+# include "Array.h"
+# include "Dict.h"
+# include "XRef.h"
+# include "Catalog.h"
+# include "Link.h"
+# include "Page.h"
+# include "GfxFont.h"
+# include "PDFDoc.h"
+# include "GlobalParams.h"
+# include "Error.h"
extern "C" {
-#include <kpathsea/c-auto.h>
+# include <kpathsea/c-auto.h>
extern char *xstrdup(const char *);
@@ -30,91 +68,106 @@ extern "C" {
typedef const char *const_string; /* including kpathsea/types.h doesn't work on some systems */
-#define KPATHSEA_CONFIG_H /* avoid including other kpathsea header files */
+# define KPATHSEA_CONFIG_H /* avoid including other kpathsea header files */
/* from web2c/config.h */
-#ifdef CONFIG_H /* CONFIG_H has been defined by some xpdf */
-# undef CONFIG_H /* header file */
-#endif
+# ifdef CONFIG_H /* CONFIG_H has been defined by some xpdf */
+# undef CONFIG_H /* header file */
+# endif
-#include <web2c/c-auto.h> /* define SIZEOF_LONG */
-#include <web2c/config.h> /* define type integer */
+# include <web2c/c-auto.h> /* define SIZEOF_LONG */
-#include <web2c/luatexdir/ptexmac.h>
-#include "openbsd-compat.h"
-#include "image.h"
-#include "../utils/avlstuff.h"
+# include "openbsd-compat.h"
+# include "image.h"
+# include "utils/avlstuff.h"
+# include "pdf/pdftypes.h"
- extern void unrefPdfDocument(char *);
+# include "lua51/lua.h"
+# include "lua51/lauxlib.h"
- extern integer epdf_page_box;
- extern void *epdf_xref;
- extern integer epdf_lastGroupObjectNum;
-
- extern integer pdf_box_spec_media;
- extern integer pdf_box_spec_crop;
- extern integer pdf_box_spec_bleed;
- extern integer pdf_box_spec_trim;
- extern integer pdf_box_spec_art;
-
- extern longinteger pdf_stream_length;
- extern longinteger pdf_ptr;
- extern integer pool_ptr;
- typedef unsigned char eight_bits;
- extern eight_bits *pdf_buf;
- extern integer pdf_buf_size;
- extern integer pdf_os_mode;
- extern eight_bits pdf_last_byte;
- extern integer fixed_inclusion_copy_font;
-
- extern char notdef[];
-
- extern integer fixed_replace_font;
-
- extern int is_subsetable(struct fm_entry *);
- extern struct fm_entry *lookup_fontmap(char *);
- extern integer get_fontfile(struct fm_entry *);
- extern integer get_fontname(struct fm_entry *);
- extern integer pdf_new_objnum(void);
- extern void read_pdf_info(image_dict *, integer, integer);
- extern void embed_whole_font(struct fd_entry *);
- extern void epdf_check_mem(void);
+ /* pdfgen.c */
+ __attribute__ ((format(printf, 2, 3)))
+ extern void pdf_printf(PDF, const char *fmt, ...);
+ extern void pdf_puts(PDF, const char *);
+ extern void pdf_begin_obj(PDF, int, bool);
+ extern void pdf_end_obj(PDF);
+ extern void pdf_begin_stream(PDF);
+ extern void pdf_end_stream(PDF);
+ extern void pdf_room(PDF, int);
+# define pdf_out(B,A) do { pdf_room(B,1); B->buf[B->ptr++] = A; } while (0)
+
+ /* pdftables.c */
+ extern int pdf_new_objnum(PDF);
+
+ /* epdf.c */
extern void epdf_free(void);
+
+ /* 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_check_mem(void);
+
+ /* utils.c */
__attribute__ ((format(printf, 1, 2)))
- extern void pdf_printf(const char *fmt, ...);
- extern void pdf_puts(const char *);
- extern void pdf_begin_stream(void);
- extern void pdf_end_obj(void);
- extern void pdf_end_stream(void);
- extern void pdf_flush(void);
+ extern void pdftex_warn(const char *fmt, ...);
__attribute__ ((noreturn, format(printf, 1, 2)))
extern void pdftex_fail(const char *fmt, ...);
- __attribute__ ((format(printf, 1, 2)))
- extern void pdftex_warn(const char *fmt, ...);
- __attribute__ ((format(printf, 1, 2)))
- extern void tex_printf(const char *, ...);
- extern void write_epdf(image_dict *);
- extern void write_additional_epdf_objects(void);
- extern void zpdf_begin_dict(integer, bool);
- extern void zpdf_begin_obj(integer, bool);
- extern void zpdf_create_obj(integer, integer);
- extern void zpdf_new_dict(integer, integer, bool);
- extern void zpdf_os_get_os_buf(integer);
-
-/* epdf.c */
- extern int get_fd_objnum(struct fd_entry *);
- extern int get_fn_objnum(struct fd_entry *);
-
-#include "../inc-epdf.h"
-
-/* utils.c */
extern char *convertStringToPDFString(char *in, int len);
extern char *stripzeros(char *a);
-/* config.c */
- extern integer cfgpar(integer);
-
-/* avlstuff.c */
- extern void avl_put_obj(integer, integer);
- extern integer avl_find_obj(integer, integer, integer);
-}
+ /* lepdflib.c */
+ int luaopen_epdf(lua_State * L);
+
+};
+
+/**********************************************************************/
+
+// PdfObject encapsulates the xpdf Object type,
+// and properly frees its resources on destruction.
+// Use obj-> to access members of the Object,
+// and &obj to get a pointer to the object.
+// It is no longer necessary to call Object::free explicitely.
+
+// *INDENT-OFF*
+class PdfObject {
+ public:
+ PdfObject() { // nothing
+ }
+ ~PdfObject() {
+ iObject.free();
+ }
+ Object *operator->() {
+ return &iObject;
+ }
+ Object *operator&() {
+ return &iObject;
+ }
+ private: // no copying or assigning
+ PdfObject(const PdfObject &);
+ void operator=(const PdfObject &);
+ public:
+ Object iObject;
+};
+// *INDENT-ON*
+
+/**********************************************************************/
+
+struct InObj {
+ Ref ref; // ref in original PDF
+ int num; // new object number in output PDF
+ InObj *next; // next entry in list of indirect objects
+};
+
+struct PdfDocument {
+ char *file_path; // full file name including path
+ char *checksum; // for reopening
+ PDFDoc *doc;
+ InObj *inObjList; // temporary linked list
+ avl_table *ObjMapTree; // permanent over luatex run
+ int occurences; // number of references to the PdfDocument; it can be deleted when occurences == 0
+};
+
+PdfDocument *refPdfDocument(char *file_path);
+
+#endif /* EPDF_H */
diff --git a/Build/source/texk/web2c/luatexdir/image/epdf.w b/Build/source/texk/web2c/luatexdir/image/epdf.w
new file mode 100644
index 00000000000..c52f148ffdf
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/image/epdf.w
@@ -0,0 +1,34 @@
+% epdf.w
+
+% Copyright 1996-2006 Han The Thanh <thanh@@pdftex.org>
+% Copyright 2006-2009 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: epdf.w 3584 2010-04-02 17:45:55Z hhenkel $ "
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/image/epdf.w $";
+
+#include "ptexlib.h"
+
+@ This must the be shortest C file we have that actually does something.
+
+@c
+void epdf_free(void)
+{
+ epdf_check_mem();
+}
diff --git a/Build/source/texk/web2c/luatexdir/image/image.h b/Build/source/texk/web2c/luatexdir/image/image.h
index a2d47f6a471..c4d0c3963f7 100644
--- a/Build/source/texk/web2c/luatexdir/image/image.h
+++ b/Build/source/texk/web2c/luatexdir/image/image.h
@@ -1,7 +1,7 @@
/* image.h
Copyright 1996-2006 Han The Thanh <thanh@pdftex.org>
- Copyright 2006-2009 Taco Hoekwater <taco@luatex.org>
+ Copyright 2006-2010 Taco Hoekwater <taco@luatex.org>
This file is part of LuaTeX.
@@ -18,23 +18,20 @@
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 2336 2009-04-19 08:38:24Z hhenkel $ */
+/* $Id: image.h 3388 2010-01-26 10:59:04Z taco $ */
#ifndef IMAGE_H
# define IMAGE_H
# include <png.h>
+# include "pdf/pdftypes.h" /* for scaled_whd */
# define JPG_UINT16 unsigned int
# define JPG_UINT32 unsigned long
# define JPG_UINT8 unsigned char
-# define IMAGE_COLOR_B 1
-# define IMAGE_COLOR_C 2
-# define IMAGE_COLOR_I 4
-
-extern integer zround(double); /* from zround.c */
-# define bp2int(p) zround(p * (one_hundred_bp / 100.0))
+extern int do_zround(double r); /* from utils.c */
+# define bp2int(p) do_zround(p * (one_hundred_bp / 100.0))
# define int2bp(i) (i * 100.0 / one_hundred_bp)
# define TYPE_IMG "image"
@@ -83,31 +80,33 @@ typedef enum { PDF_BOX_SPEC_NONE, PDF_BOX_SPEC_MEDIA, PDF_BOX_SPEC_CROP,
/**********************************************************************/
typedef struct {
- integer objnum;
- integer index; /* /Im1, /Im2, ... */
- integer x_size; /* dimensions in pixel counts as in JPG/PNG/JBIG2 file */
- integer y_size;
- integer x_orig; /* origin in sp for PDF files */
- integer y_orig;
- integer x_res; /* pixel resolution as in JPG/PNG/JBIG2 file */
- integer y_res;
- integer rotation; /* rotation (multiples of 90 deg.) for PDF files */
- integer colorspace; /* number of /ColorSpace object */
- integer group_ref; /* if it's <=0, the page has no group */
- integer total_pages;
- integer page_num; /* requested page (by number) */
+ int objnum;
+ int index; /* /Im1, /Im2, ... */
+ scaled_whd dimen; /* TeX dimensions given to \pdfximage */
+ int transform; /* transform given to \pdfximage */
+ int x_size; /* dimensions in pixel counts as in JPG/PNG/JBIG2 file */
+ int y_size;
+ int x_orig; /* origin in sp for PDF files */
+ int y_orig;
+ int x_res; /* pixel resolution as in JPG/PNG/JBIG2 file */
+ int y_res;
+ int rotation; /* rotation (multiples of 90 deg.) for PDF files */
+ int colorspace; /* number of /ColorSpace object */
+ int group_ref; /* if it's <=0, the page has no group */
+ int total_pages;
+ int page_num; /* requested page (by number) */
char *pagename; /* requested page (by name) */
char *filename; /* requested raw file name */
char *filepath; /* full file path after kpathsea */
char *attr; /* additional image dict entries */
FILE *file;
imgtype_e image_type;
- int color_space; /* used color space. See JPG_ constants */
+ int procset; /* /ProcSet flags */
int color_depth; /* color depth */
pdfboxspec_e page_box_spec; /* PDF page box spec.: media/crop/bleed/trim/art */
- integer bbox[4];
+ int bbox[4];
dict_state state;
- integer flags;
+ int flags;
union {
pdf_stream_struct *pdfstream;
png_img_struct *png;
@@ -118,6 +117,11 @@ typedef struct {
# define img_objnum(N) ((N)->objnum)
# define img_index(N) ((N)->index)
+# define img_dimen(N) ((N)->dimen)
+# define img_width(N) ((N)->dimen.wd)
+# define img_height(N) ((N)->dimen.ht)
+# define img_depth(N) ((N)->dimen.dp)
+# define img_transform(N) ((N)->transform)
# define img_xsize(N) ((N)->x_size)
# define img_ysize(N) ((N)->y_size)
# define img_xorig(N) ((N)->x_orig)
@@ -135,11 +139,12 @@ typedef struct {
# define img_attr(N) ((N)->attr)
# define img_file(N) ((N)->file)
# define img_type(N) ((N)->image_type)
-# define img_color(N) ((N)->color_space)
+# define img_procset(N) ((N)->procset)
# define img_colordepth(N) ((N)->color_depth)
# define img_pagebox(N) ((N)->page_box_spec)
# define img_bbox(N) ((N)->bbox)
# define img_state(N) ((N)->state)
+# define img_flags(N) ((N)->flags)
# define img_pdfstream_ptr(N) ((N)->img_struct.pdfstream)
# define img_pdfstream_stream(N) ((N)->img_struct.pdfstream->stream)
@@ -154,42 +159,39 @@ typedef struct {
# define img_jb2_ptr(N) ((N)->img_struct.jb2)
# define F_FLAG_BBOX (1 << 0)
+# define F_FLAG_GROUP (1 << 1)
# define img_set_bbox(N) (img_flags(N) |= F_FLAG_BBOX)
# define img_unset_bbox(N) (img_flags(N) &= ~F_FLAG_BBOX)
# define img_is_bbox(N) ((img_flags(N) & F_FLAG_BBOX) != 0)
+# define img_set_group(N) (img_flags(N) |= F_FLAG_GROUP)
+# define img_unset_group(N) (img_flags(N) &= ~F_FLAG_GROUP)
+# define img_is_group(N) ((img_flags(N) & F_FLAG_GROUP) != 0)
+
+# define epdf_xsize(a) img_xsize(idict_array[a])
+# define epdf_ysize(a) img_ysize(idict_array[a])
+# define epdf_orig_x(a) img_xorig(idict_array[a])
+# define epdf_orig_y(a) img_yorig(idict_array[a])
+
+# define is_pdf_image(a) (img_type(idict_array[a]) == IMG_TYPE_PDF)
+# define is_png_image(a) (img_type(idict_array[a]) == IMG_TYPE_PNG)
+
+# define img_is_refered(N) (img_index(N) != -1)
+
/**********************************************************************/
+/* image structure corresponds to pdfrefximage node */
typedef struct {
- integer width; /* requested/actual TeX dimensions */
- integer height;
- integer depth;
- integer transform;
- integer flags;
+ scaled_whd dimen; /* requested/actual TeX dimensions */
+ int transform;
image_dict *dict;
- int array_idx; /* index within img_array */
int dict_ref; /* luaL_ref() reference */
} image;
-# define img_width(N) ((N)->width)
-# define img_height(N) ((N)->height)
-# define img_depth(N) ((N)->depth)
-# define img_transform(N) ((N)->transform)
-# define img_flags(N) ((N)->flags)
# define img_dict(N) ((N)->dict)
-# define img_arrayidx(N) ((N)->array_idx)
# define img_dictref(N) ((N)->dict_ref)
-# define img_is_refered(N) (img_arrayidx(N) != -1)
-
-# define F_FLAG_SCALED (1 << 0)
-
-# define img_flags(N) ((N)->flags)
-# define img_set_scaled(N) (img_flags(N) |= F_FLAG_SCALED)
-# define img_unset_scaled(N) (img_flags(N) &= ~F_FLAG_SCALED)
-# define img_is_scaled(N) ((img_flags(N) & F_FLAG_SCALED) != 0)
-
# define set_wd_running(N) (img_width(N) = null_flag)
# define set_ht_running(N) (img_height(N) = null_flag)
# define set_dp_running(N) (img_depth(N) = null_flag)
diff --git a/Build/source/texk/web2c/luatexdir/image/pdftoepdf.cc b/Build/source/texk/web2c/luatexdir/image/pdftoepdf.cc
index 536c6398cd7..8a177163a76 100644
--- a/Build/source/texk/web2c/luatexdir/image/pdftoepdf.cc
+++ b/Build/source/texk/web2c/luatexdir/image/pdftoepdf.cc
@@ -1,7 +1,7 @@
/* pdftoepdf.cc
-
+
Copyright 1996-2006 Han The Thanh <thanh@pdftex.org>
- Copyright 2006-2008 Taco Hoekwater <taco@luatex.org>
+ Copyright 2006-2010 Taco Hoekwater <taco@luatex.org>
This file is part of LuaTeX.
@@ -18,46 +18,13 @@
You should have received a copy of the GNU General Public License along
with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-#include <stdlib.h>
-#include <math.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <string.h>
-#include <ctype.h>
-#ifdef POPPLER_VERSION
-# define GString GooString
-# include <dirent.h>
-# include <poppler-config.h>
-# include <goo/GooString.h>
-# include <goo/gmem.h>
-# include <goo/gfile.h>
-#else
-# include <aconf.h>
-# include <GString.h>
-# include <gmem.h>
-# include <gfile.h>
-# include <assert.h>
-#endif
-#include "Object.h"
-#include "Stream.h"
-#include "Array.h"
-#include "Dict.h"
-#include "XRef.h"
-#include "Catalog.h"
-#include "Link.h"
-#include "Page.h"
-#include "GfxFont.h"
-#include "PDFDoc.h"
-#include "GlobalParams.h"
-#include "Error.h"
+static const char _svn_version[] =
+ "$Id: pdftoepdf.cc 3431 2010-02-17 20:35:50Z oneiros $ "
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/image/pdftoepdf.cc $";
#include "epdf.h"
-static const char _svn_version[] =
- "$Id: pdftoepdf.cc 2448 2009-06-08 07:43:50Z taco $ "
- "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/image/pdftoepdf.cc $";
-
-#define one_hundred_bp 6578176 /* 7227 * 65536 / 72 */
+#define one_hundred_bp 6578176 // one_hundred_bp = 7227 * 65536 / 72
// This file is mostly C and not very much C++; it's just used to interface
// the functions of xpdf, which happens to be written in C++.
@@ -67,81 +34,16 @@ static const char _svn_version[] =
#define pdfkeyprefix "PTEX"
-// PdfObject encapsulates the xpdf Object type,
-// and properly frees its resources on destruction.
-// Use obj-> to access members of the Object,
-// and &obj to get a pointer to the object.
-// It is no longer necessary to call Object::free explicitely.
-
-/* *INDENT-OFF* */
-class PdfObject {
- public:
- PdfObject() { // nothing
- }
- ~PdfObject() {
- iObject.free();
- }
- Object *operator->() {
- return &iObject;
- }
- Object *operator&() {
- return &iObject;
- }
- private: // no copying or assigning
- PdfObject(const PdfObject &);
- void operator=(const PdfObject &);
- public:
- Object iObject;
-};
-/* *INDENT-ON* */
-
-// When copying the Resources of the selected page, all objects are copied
-// recusively top-down. Indirect objects however are not fetched during
-// copying, but get a new object number from pdfTeX and then will be
-// appended into a linked list. Duplicates are checked and removed from the
-// list of indirect objects during appending.
-
-enum InObjType { objFont, objFontDesc, objOther };
-
-struct InObj {
- Ref ref; // ref in original PDF
- InObjType type; // object type
- integer num; // new object number in output PDF
- fd_entry *fd; // pointer to /FontDescriptor object structure
- integer enc_objnum; // Encoding for objFont
- int written; // has it been written to output PDF?
- InObj *next; // next entry in list of indirect objects
-};
-
-struct UsedEncoding {
- integer enc_objnum;
- GfxFont *font;
- UsedEncoding *next;
-};
-
-static XRef *xref = NULL;
-static InObj *inObjList = NULL;
-static UsedEncoding *encodingList;
static GBool isInit = gFalse;
-static bool groupIsIndirect;
-static PdfObject lastGroup;
//**********************************************************************
-// Maintain AVL tree of open embedded PDF files
+// Maintain AVL tree of all PDF files for embedding
static avl_table *PdfDocumentTree = NULL;
-struct PdfDocument {
- char *file_path; // full file name including path
- PDFDoc *doc;
- XRef *xref;
- InObj *inObjList;
- int occurences; // number of references to the PdfDocument; it can be deleted when occurences == 0
-};
-
-/* AVL sort PdfDocument into PdfDocumentTree by file_path */
+// AVL sort PdfDocument into PdfDocumentTree by file_path
-static int CompPdfDocument(const void *pa, const void *pb, void *p)
+static int CompPdfDocument(const void *pa, const void *pb, void * /*p */ )
{
return strcmp(((const PdfDocument *) pa)->file_path,
((const PdfDocument *) pb)->file_path);
@@ -154,8 +56,7 @@ static PdfDocument *findPdfDocument(char *file_path)
PdfDocument *pdf_doc, tmp;
assert(file_path != NULL);
if (PdfDocumentTree == NULL)
- PdfDocumentTree = avl_create(CompPdfDocument, NULL, &avl_xallocator);
- assert(PdfDocumentTree != NULL);
+ return NULL;
tmp.file_path = file_path;
pdf_doc = (PdfDocument *) avl_find(PdfDocumentTree, &tmp);
return pdf_doc;
@@ -164,26 +65,35 @@ static PdfDocument *findPdfDocument(char *file_path)
// Returns pointer to PdfDocument structure for PDF file.
// Creates a new structure if it doesn't exist yet.
-static PdfDocument *refPdfDocument(char *file_path)
+char *get_file_checksum(char *a);
+
+PdfDocument *refPdfDocument(char *file_path)
{
PdfDocument *pdf_doc = findPdfDocument(file_path);
if (pdf_doc == NULL) {
+ if (PdfDocumentTree == NULL)
+ PdfDocumentTree =
+ avl_create(CompPdfDocument, NULL, &avl_xallocator);
pdf_doc = new PdfDocument;
pdf_doc->file_path = xstrdup(file_path);
+ pdf_doc->checksum = get_file_checksum(file_path);
void **aa = avl_probe(PdfDocumentTree, pdf_doc);
assert(aa != NULL);
+ pdf_doc->ObjMapTree = NULL;
+ pdf_doc->doc = NULL;
+ }
+ if (pdf_doc->doc == NULL) {
GString *docName = new GString(pdf_doc->file_path);
pdf_doc->doc = new PDFDoc(docName); // takes ownership of docName
if (!pdf_doc->doc->isOk() || !pdf_doc->doc->okToPrint())
pdftex_fail("xpdf: reading PDF image failed");
- pdf_doc->xref = NULL;
pdf_doc->inObjList = NULL;
pdf_doc->occurences = 0; // 0 = unreferenced
+ }
#ifdef DEBUG
- fprintf(stderr, "\nluatex Debug: Creating %s (%d)\n",
- pdf_doc->file_path, pdf_doc->occurences);
+ fprintf(stderr, "\nluatex Debug: Creating %s (%d)\n",
+ pdf_doc->file_path, pdf_doc->occurences);
#endif
- }
pdf_doc->occurences++;
#ifdef DEBUG
fprintf(stderr, "\nluatex Debug: Incrementing %s (%d)\n",
@@ -192,293 +102,94 @@ static PdfDocument *refPdfDocument(char *file_path)
return pdf_doc;
}
-static void deletePdfDocument(PdfDocument *);
+//**********************************************************************
+// AVL sort ObjMap into ObjMapTree by object number and generation
-// Called when an image has been written and its resources in image_tab are
-// freed and it's not referenced anymore.
+// keep the ObjMap struct small, as these are accumulated until the end
-void unrefPdfDocument(char *file_path)
+struct ObjMap {
+ Ref in; // object num/gen in orig. PDF file
+ int out_num; // object num after embedding (gen == 0)
+};
+
+static int CompObjMap(const void *pa, const void *pb, void * /*p */ )
{
- PdfDocument *pdf_doc = findPdfDocument(file_path);
- assert(pdf_doc != NULL);
- assert(pdf_doc->occurences > 0); // aim for point landing
- pdf_doc->occurences--;
-#ifdef DEBUG
- fprintf(stderr, "\nluatex Debug: Decrementing %s (%d)\n",
- pdf_doc->file_path, pdf_doc->occurences);
-#endif
- if (pdf_doc->occurences == 0) {
-#ifdef DEBUG
- fprintf(stderr, "\nluatex Debug: Deleting %s\n", pdf_doc->file_path);
-#endif
- void *a = avl_delete(PdfDocumentTree, pdf_doc);
- assert((PdfDocument *) a == pdf_doc);
- deletePdfDocument(pdf_doc);
- }
+ const Ref *a = &(((const ObjMap *) pa)->in);
+ const Ref *b = &(((const ObjMap *) pb)->in);
+ if (a->num > b->num)
+ return 1;
+ if (a->num < b->num)
+ return -1;
+ if (a->gen == b->gen) // most likely gen == 0 anyway
+ return 0;
+ if (a->gen < b->gen)
+ return -1;
+ return 1;
}
-//**********************************************************************
-
-// Replacement for
-// Object *initDict(Dict *dict1){ initObj(objDict); dict = dict1; return this; }
-
-static void initDictFromDict(PdfObject & obj, Dict * dict)
+static ObjMap *findObjMap(PdfDocument * pdf_doc, Ref in)
{
- obj->initDict(xref);
- for (int i = 0, l = dict->getLength(); i < l; i++) {
- Object obj1;
- obj->dictAdd(copyString(dict->getKey(i)), dict->getValNF(i, &obj1));
- }
+ ObjMap *obj_map, tmp;
+ assert(pdf_doc != NULL);
+ if (pdf_doc->ObjMapTree == NULL)
+ return NULL;
+ tmp.in = in;
+ obj_map = (ObjMap *) avl_find(pdf_doc->ObjMapTree, &tmp);
+ return obj_map;
}
-static int addEncoding(GfxFont * gfont)
+static void addObjMap(PdfDocument * pdf_doc, Ref in, int out_num)
{
- UsedEncoding *n;
- n = new UsedEncoding;
- n->next = encodingList;
- encodingList = n;
- n->font = gfont;
- n->enc_objnum = pdf_new_objnum();
- return n->enc_objnum;
+ ObjMap *obj_map = NULL;
+ assert(findObjMap(pdf_doc, in) == NULL);
+ if (pdf_doc->ObjMapTree == NULL)
+ pdf_doc->ObjMapTree = avl_create(CompObjMap, NULL, &avl_xallocator);
+ obj_map = new ObjMap;
+ obj_map->in = in;
+ obj_map->out_num = out_num;
+ void **aa = avl_probe(pdf_doc->ObjMapTree, obj_map);
+ assert(aa != NULL);
}
-#define addFont(ref, fd, enc_objnum) \
- addInObj(objFont, ref, fd, enc_objnum)
+// When copying the Resources of the selected page, all objects are
+// copied recursively top-down. The findObjMap() function checks if an
+// object has already been copied; if so, instead of copying just the
+// new object number will be referenced. The ObjMapTree guarantees,
+// that during the entire LuaTeX run any object from any embedded PDF
+// file will end up max. once in the output PDF file. Indirect objects
+// are not fetched during copying, but get a new object number from
+// LuaTeX and then will be appended into a linked list.
-// addFontDesc is only used to avoid writing the original FontDescriptor
-// from the PDF file.
-
-#define addFontDesc(ref, fd) \
- addInObj(objFontDesc, ref, fd, 0)
-
-#define addOther(ref) \
- addInObj(objOther, ref, NULL, 0)
-
-static int addInObj(InObjType type, Ref ref, fd_entry * fd, integer e)
+static int addInObj(PDF pdf, PdfDocument * pdf_doc, Ref ref)
{
- InObj *p, *q, *n = new InObj;
- if (ref.num == 0)
- pdftex_fail("PDF inclusion: invalid reference");
+ ObjMap *obj_map;
+ InObj *p, *q, *n;
+ if (ref.num == 0) {
+ pdftex_fail("PDF inclusion: reference to invalid object"
+ " (is the included pdf broken?)");
+ }
+ if ((obj_map = findObjMap(pdf_doc, ref)) != NULL)
+ return obj_map->out_num;
+ n = new InObj;
n->ref = ref;
- n->type = type;
n->next = NULL;
- n->fd = fd;
- n->enc_objnum = e;
- n->written = 0;
- if (inObjList == NULL)
- inObjList = n;
+ n->num = pdf_new_objnum(pdf);
+ addObjMap(pdf_doc, ref, n->num);
+ if (pdf_doc->inObjList == NULL)
+ pdf_doc->inObjList = n;
else {
- for (p = inObjList; p != NULL; p = p->next) {
- if (p->ref.num == ref.num && p->ref.gen == ref.gen) {
- delete n;
- return p->num;
- }
- q = p;
- }
// it is important to add new objects at the end of the list,
// because new objects are being added while the list is being
// written out by writeRefs().
+ for (p = pdf_doc->inObjList; p != NULL; p = p->next)
+ q = p;
q->next = n;
}
- if (type == objFontDesc)
- n->num = get_fd_objnum(fd);
- else
- n->num = pdf_new_objnum();
return n->num;
}
-static void copyName(char *s)
-{
- pdf_puts("/");
- for (; *s != 0; s++) {
- if (isdigit(*s) || isupper(*s) || islower(*s) || *s == '_' ||
- *s == '.' || *s == '-' || *s == '+')
- pdfout(*s);
- else
- pdf_printf("#%.2X", *s & 0xFF);
- }
-}
-
-static int getNewObjectNumber(Ref ref)
-{
- InObj *p;
- if (inObjList == 0) {
- pdftex_fail("No objects copied yet");
- } else {
- for (p = inObjList; p != 0; p = p->next) {
- if (p->ref.num == ref.num && p->ref.gen == ref.gen) {
- return p->num;
- }
- }
- pdftex_fail("Object not yet copied: %i %i", ref.num, ref.gen);
- }
-}
-
-static void copyObject(Object *);
-
-static void copyDictEntry(Object * obj, int i)
-{
- PdfObject obj1;
- copyName(obj->dictGetKey(i));
- pdf_puts(" ");
- obj->dictGetValNF(i, &obj1);
- copyObject(&obj1);
- pdf_puts("\n");
-}
-
-static void copyDict(Object * obj)
-{
- int i, l;
- if (!obj->isDict())
- pdftex_fail("PDF inclusion: invalid dict type <%s>",
- obj->getTypeName());
- for (i = 0, l = obj->dictGetLength(); i < l; ++i)
- copyDictEntry(obj, i);
-}
-
-static void copyFontDict(Object * obj, InObj * r)
-{
- int i, l;
- char *key;
- if (!obj->isDict())
- pdftex_fail("PDF inclusion: invalid dict type <%s>",
- obj->getTypeName());
- pdf_puts("<<\n");
- assert(r->type == objFont); // FontDescriptor is in fd_tree
- for (i = 0, l = obj->dictGetLength(); i < l; ++i) {
- key = obj->dictGetKey(i);
- if (strncmp("FontDescriptor", key, strlen("FontDescriptor")) == 0
- || strncmp("BaseFont", key, strlen("BaseFont")) == 0
- || strncmp("Encoding", key, strlen("Encoding")) == 0)
- continue; // skip original values
- copyDictEntry(obj, i);
- }
- // write new FontDescriptor, BaseFont, and Encoding
- pdf_printf("/FontDescriptor %d 0 R\n", (int) get_fd_objnum(r->fd));
- pdf_printf("/BaseFont %d 0 R\n", (int) get_fn_objnum(r->fd));
- pdf_printf("/Encoding %d 0 R\n", (int) r->enc_objnum);
- pdf_puts(">>");
-}
-
-static void copyStream(Stream * str)
-{
- int c;
- str->reset();
- while ((c = str->getChar()) != EOF) {
- pdfout(c);
- pdf_last_byte = c;
- }
-}
-
-static void copyProcSet(Object * obj)
-{
- int i, l;
- PdfObject procset;
- if (!obj->isArray())
- pdftex_fail("PDF inclusion: invalid ProcSet array type <%s>",
- obj->getTypeName());
- pdf_puts("/ProcSet [ ");
- for (i = 0, l = obj->arrayGetLength(); i < l; ++i) {
- obj->arrayGetNF(i, &procset);
- if (!procset->isName())
- pdftex_fail("PDF inclusion: invalid ProcSet entry type <%s>",
- procset->getTypeName());
- copyName(procset->getName());
- pdf_puts(" ");
- }
- pdf_puts("]\n");
-}
-
-#define REPLACE_TYPE1C true
-
-static void copyFont(char *tag, Object * fontRef)
-{
- PdfObject fontdict, subtype, basefont, fontdescRef, fontdesc, charset,
- fontfile, ffsubtype, stemV;
- GfxFont *gfont;
- fd_entry *fd;
- fm_entry *fontmap;
- // Check whether the font has already been embedded before analysing it.
- InObj *p;
- Ref ref = fontRef->getRef();
- for (p = inObjList; p; p = p->next) {
- if (p->ref.num == ref.num && p->ref.gen == ref.gen) {
- copyName(tag);
- pdf_printf(" %d 0 R ", (int) p->num);
- return;
- }
- }
- // Only handle included Type1 (and Type1C) fonts; anything else will be copied.
- // Type1C fonts are replaced by Type1 fonts, if REPLACE_TYPE1C is true.
- if (!fixed_inclusion_copy_font && fontRef->fetch(xref, &fontdict)->isDict()
- && fontdict->dictLookup("Subtype", &subtype)->isName()
- && !strcmp(subtype->getName(), "Type1")
- && fontdict->dictLookup("BaseFont", &basefont)->isName()
- && fontdict->dictLookupNF("FontDescriptor", &fontdescRef)->isRef()
- && fontdescRef->fetch(xref, &fontdesc)->isDict()
- && (fontdesc->dictLookup("FontFile", &fontfile)->isStream()
- || (REPLACE_TYPE1C
- && fontdesc->dictLookup("FontFile3", &fontfile)->isStream()
- && fontfile->streamGetDict()->lookup("Subtype",
- &ffsubtype)->isName()
- && !strcmp(ffsubtype->getName(), "Type1C")))
- && (fontmap = lookup_fontmap(basefont->getName())) != NULL) {
- // copy the value of /StemV
- fontdesc->dictLookup("StemV", &stemV);
- fd = epdf_create_fontdescriptor(fontmap, stemV->getInt());
- if (fontdesc->dictLookup("CharSet", &charset) &&
- charset->isString() && is_subsetable(fontmap))
- epdf_mark_glyphs(fd, charset->getString()->getCString());
- else
- embed_whole_font(fd);
- addFontDesc(fontdescRef->getRef(), fd);
- copyName(tag);
- gfont = GfxFont::makeFont(xref, tag, fontRef->getRef(),
- fontdict->getDict());
- pdf_printf(" %d 0 R ", addFont(fontRef->getRef(), fd,
- addEncoding(gfont)));
- } else {
- copyName(tag);
- pdf_puts(" ");
- copyObject(fontRef);
- }
-}
-
-static void copyFontResources(Object * obj)
-{
- PdfObject fontRef;
- int i, l;
- if (!obj->isDict())
- pdftex_fail("PDF inclusion: invalid font resources dict type <%s>",
- obj->getTypeName());
- pdf_puts("/Font << ");
- for (i = 0, l = obj->dictGetLength(); i < l; ++i) {
- obj->dictGetValNF(i, &fontRef);
- if (fontRef->isRef())
- copyFont(obj->dictGetKey(i), &fontRef);
- else
- pdftex_fail("PDF inclusion: invalid font in reference type <%s>",
- fontRef->getTypeName());
- }
- pdf_puts(">>\n");
-}
-
-static void copyOtherResources(Object * obj, char *key)
-{
- // copies all other resources (write_epdf handles Fonts and ProcSets),
- // but gives a warning if an object is not a dictionary.
-
- if (!obj->isDict())
- //FIXME: Write the message only to the log file
- pdftex_warn("PDF inclusion: invalid other resource which is no dict"
- " (key '%s', type <%s>); copying it anyway.",
- key, obj->getTypeName());
- copyName(key);
- pdf_puts(" ");
- copyObject(obj);
-}
-
-// Function onverts double to string; very small and very large numbers
+//**********************************************************************
+// Function converts double to string; 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.
@@ -536,165 +247,215 @@ static char *convertNumToPDF(double n)
return (char *) buf;
}
-static void copyObject(Object * obj)
+static void copyObject(PDF, PdfDocument *, Object *);
+
+static void copyString(PDF pdf, GString * string)
{
- PdfObject obj1;
- int i, l, c;
- Ref ref;
char *p;
- GString *s;
- if (obj->isBool()) {
- pdf_printf("%s", obj->getBool()? "true" : "false");
- } else if (obj->isInt()) {
- pdf_printf("%i", obj->getInt());
- } else if (obj->isReal()) {
- pdf_printf("%s", convertNumToPDF(obj->getReal()));
- } else if (obj->isNum()) {
- pdf_printf("%s", convertNumToPDF(obj->getNum()));
- } else if (obj->isString()) {
- s = obj->getString();
- p = s->getCString();
- l = s->getLength();
- if (strlen(p) == (unsigned int) l) {
- pdf_puts("(");
- for (; *p != 0; p++) {
- c = (unsigned char) *p;
- if (c == '(' || c == ')' || c == '\\')
- pdf_printf("\\%c", c);
- else if (c < 0x20 || c > 0x7F)
- pdf_printf("\\%03o", c);
- else
- pdfout(c);
- }
- pdf_puts(")");
- } else {
- pdf_puts("<");
- for (i = 0; i < l; i++) {
- c = s->getChar(i) & 0xFF;
- pdf_printf("%.2x", c);
- }
- pdf_puts(">");
- }
- } else if (obj->isName()) {
- copyName(obj->getName());
- } else if (obj->isNull()) {
- pdf_puts("null");
- } else if (obj->isArray()) {
- pdf_puts("[");
- for (i = 0, l = obj->arrayGetLength(); i < l; ++i) {
- obj->arrayGetNF(i, &obj1);
- if (!obj1->isName())
- pdf_puts(" ");
- copyObject(&obj1);
+ unsigned char c;
+ size_t i, l;
+ p = string->getCString();
+ l = (size_t) string->getLength();
+ if (strlen(p) == l) {
+ pdf_puts(pdf, "(");
+ for (; *p != 0; p++) {
+ c = (unsigned char) *p;
+ if (c == '(' || c == ')' || c == '\\')
+ pdf_printf(pdf, "\\%c", c);
+ else if (c < 0x20 || c > 0x7F)
+ pdf_printf(pdf, "\\%03o", (int) c);
+ else
+ pdf_out(pdf, c);
}
- pdf_puts("]");
- } else if (obj->isDict()) {
- pdf_puts("<<\n");
- copyDict(obj);
- pdf_puts(">>");
- } else if (obj->isStream()) {
- initDictFromDict(obj1, obj->streamGetDict());
- obj->streamGetDict()->incRef();
- pdf_puts("<<\n");
- copyDict(&obj1);
- pdf_puts(">>\n");
- pdf_puts("stream\n");
- copyStream(obj->getStream()->getUndecodedStream());
- if (pdf_last_byte != '\n')
- pdf_puts("\n");
- pdf_puts("endstream"); // can't simply write pdf_end_stream()
- } else if (obj->isRef()) {
- ref = obj->getRef();
- if (ref.num == 0) {
- pdftex_fail
- ("PDF inclusion: reference to invalid object"
- " (is the included pdf broken?)");
- } else
- pdf_printf("%d 0 R", addOther(ref));
+ pdf_puts(pdf, ")");
} else {
- pdftex_fail("PDF inclusion: type <%s> cannot be copied",
- obj->getTypeName());
+ pdf_puts(pdf, "<");
+ for (i = 0; i < l; i++) {
+ c = (unsigned char) string->getChar(i);
+ pdf_printf(pdf, "%.2x", (int) c);
+ }
+ pdf_puts(pdf, ">");
}
}
-static void writeRefs()
+static void copyName(PDF pdf, char *s)
{
- InObj *r;
- for (r = inObjList; r != NULL; r = r->next) {
- if (!r->written) {
- Object obj1;
- r->written = 1;
- xref->fetch(r->ref.num, r->ref.gen, &obj1);
- if (r->type == objFont) {
- assert(!obj1.isStream());
- zpdf_begin_obj(r->num, 2); // \pdfobjcompresslevel = 2 is for this
- copyFontDict(&obj1, r);
- pdf_puts("\n");
- pdf_end_obj();
- } else if (r->type != objFontDesc) { // /FontDescriptor is written via write_fontdescriptor()
- if (obj1.isStream())
- zpdf_begin_obj(r->num, 0);
- else
- zpdf_begin_obj(r->num, 2); // \pdfobjcompresslevel = 2 is for this
- copyObject(&obj1);
- pdf_puts("\n");
- pdf_end_obj();
- }
- obj1.free();
- }
+ pdf_puts(pdf, "/");
+ for (; *s != 0; s++) {
+ if (isdigit(*s) || isupper(*s) || islower(*s) || *s == '_' ||
+ *s == '.' || *s == '-' || *s == '+')
+ pdf_out(pdf, *s);
+ else
+ pdf_printf(pdf, "#%.2X", *s & 0xFF);
}
}
-static void writeEncodings()
+static void copyArray(PDF pdf, PdfDocument * pdf_doc, Array * array)
{
- UsedEncoding *r, *n;
- char *glyphNames[256], *s;
- int i;
- for (r = encodingList; r != NULL; r = r->next) {
- for (i = 0; i < 256; i++) {
- if (r->font->isCIDFont()) {
- pdftex_fail
- ("PDF inclusion: CID fonts are not supported"
- " (try to disable font replacement to fix this)");
- }
- if ((s = ((Gfx8BitFont *) r->font)->getCharName(i)) != NULL)
- glyphNames[i] = s;
- else
- glyphNames[i] = notdef;
- }
- epdf_write_enc(glyphNames, r->enc_objnum);
+ int i, l;
+ PdfObject obj1;
+ pdf_puts(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);
+ }
+ pdf_puts(pdf, "]");
+}
+
+static void copyDict(PDF pdf, PdfDocument * pdf_doc, Dict * dict)
+{
+ int i, l;
+ PdfObject obj1;
+ pdf_puts(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);
+ pdf_puts(pdf, "\n");
+ }
+ pdf_puts(pdf, ">>");
+}
+
+static void copyStreamStream(PDF pdf, Stream * str)
+{
+ int c;
+ str->reset();
+ while ((c = str->getChar()) != EOF) {
+ pdf_out(pdf, c);
+ pdf->last_byte = c;
+ }
+}
+
+static void copyStream(PDF pdf, PdfDocument * pdf_doc, Stream * stream)
+{
+ copyDict(pdf, pdf_doc, stream->getDict());
+ pdf_puts(pdf, "stream\n");
+ copyStreamStream(pdf, stream->getUndecodedStream());
+ if (pdf->last_byte != '\n')
+ pdf_puts(pdf, "\n");
+ pdf_puts(pdf, "endstream"); // can't simply write pdf_end_stream()
+}
+
+static void copyObject(PDF pdf, PdfDocument * pdf_doc, Object * obj)
+{
+ switch (obj->getType()) {
+ case objBool:
+ pdf_printf(pdf, "%s", obj->getBool()? "true" : "false");
+ break;
+ case objInt:
+ pdf_printf(pdf, "%i", obj->getInt());
+ break;
+ case objReal:
+ pdf_printf(pdf, "%s", convertNumToPDF(obj->getReal()));
+ break;
+ // not needed:
+ // GBool isNum() { return type == objInt || type == objReal; }
+ case objString:
+ copyString(pdf, obj->getString());
+ break;
+ case objName:
+ copyName(pdf, obj->getName());
+ break;
+ case objNull:
+ pdf_puts(pdf, "null");
+ break;
+ case objArray:
+ copyArray(pdf, pdf_doc, obj->getArray());
+ break;
+ case objDict:
+ copyDict(pdf, pdf_doc, obj->getDict());
+ break;
+ case objStream:
+ copyStream(pdf, pdf_doc, obj->getStream());
+ break;
+ case objRef:
+ pdf_printf(pdf, "%d 0 R", addInObj(pdf, pdf_doc, obj->getRef()));
+ break;
+ case objCmd:
+ case objError:
+ case objEOF:
+ case objNone:
+ pdftex_fail("PDF inclusion: type <%s> cannot be copied",
+ obj->getTypeName());
+ break;
+ default:
+ assert(0); // xpdf doesn't have any other types
}
- for (r = encodingList; r != NULL; r = n) {
+}
+
+//**********************************************************************
+
+static void writeRefs(PDF pdf, PdfDocument * pdf_doc)
+{
+ InObj *r, *n;
+ XRef *xref;
+ xref = pdf_doc->doc->getXRef();
+ for (r = pdf_doc->inObjList; r != NULL;) {
+ PdfObject obj1;
+ xref->fetch(r->ref.num, r->ref.gen, &obj1);
+ if (obj1->isStream())
+ pdf_begin_obj(pdf, r->num, 0);
+ else
+ pdf_begin_obj(pdf, r->num, 2); // \pdfobjcompresslevel = 2 is for this
+ copyObject(pdf, pdf_doc, &obj1);
+ pdf_puts(pdf, "\n");
+ pdf_end_obj(pdf);
n = r->next;
-#ifdef POPPLER_VERSION
- r->font->decRefCnt();
-#else
- delete r->font;
-#endif
delete r;
+ pdf_doc->inObjList = r = n;
}
}
-// get the pagebox according to the pagebox_spec
+// get the pagebox coordinates according to the pagebox_spec
-static PDFRectangle *get_pagebox(Page * page, integer pagebox_spec)
+static PDFRectangle *get_pagebox(Page * page, int pagebox_spec)
{
- if (pagebox_spec == pdf_box_spec_media)
+ switch (pagebox_spec) {
+ case PDF_BOX_SPEC_MEDIA:
return page->getMediaBox();
- else if (pagebox_spec == pdf_box_spec_crop)
+ break;
+ case PDF_BOX_SPEC_CROP:
return page->getCropBox();
- else if (pagebox_spec == pdf_box_spec_bleed)
+ break;
+ case PDF_BOX_SPEC_BLEED:
return page->getBleedBox();
- else if (pagebox_spec == pdf_box_spec_trim)
+ break;
+ case PDF_BOX_SPEC_TRIM:
return page->getTrimBox();
- else if (pagebox_spec == pdf_box_spec_art)
+ break;
+ case PDF_BOX_SPEC_ART:
return page->getArtBox();
- else
+ break;
+ default:
pdftex_fail("PDF inclusion: unknown value of pagebox spec (%i)",
(int) pagebox_spec);
+ }
return page->getMediaBox(); // to make the compiler happy
}
+#define PDF_CHECKSUM_SIZE 32
+char *get_file_checksum(char *a)
+{
+ struct stat finfo;
+ char *ck = NULL;
+ if (stat(a, &finfo) == 0) {
+ off_t size = finfo.st_size;
+ time_t mtime = finfo.st_mtime;
+ ck = (char *) malloc(PDF_CHECKSUM_SIZE);
+ if (ck == NULL)
+ pdftex_fail("PDF inclusion: out of memory while processing '%s'",
+ a);
+ snprintf(ck, PDF_CHECKSUM_SIZE, "%llu_%llu", (unsigned long long) size,
+ (unsigned long long) mtime);
+ } else {
+ pdftex_fail("PDF inclusion: could not stat() file '%s'", a);
+ }
+ return ck;
+}
+
// Reads various information about the PDF and sets it up for later inclusion.
// This will fail if the PDF version of the PDF is higher than
// minor_pdf_version_wanted or page_name is given and can not be found.
@@ -702,47 +463,37 @@ static PDFRectangle *get_pagebox(Page * page, integer pagebox_spec)
// Returns the page number.
void
-read_pdf_info(image_dict * idict, integer minor_pdf_version_wanted,
- integer pdf_inclusion_errorlevel)
+read_pdf_info(image_dict * idict, int minor_pdf_version_wanted,
+ int pdf_inclusion_errorlevel, img_readtype_e readtype)
{
PdfDocument *pdf_doc;
Page *page;
int rotate;
+ char *checksum;
PDFRectangle *pagebox;
-#ifdef HAVE_GETPDFMAJORVERSION
- int pdf_major_version_found, pdf_minor_version_found;
-#else
- float pdf_version_found, pdf_version_wanted;
-#endif
- float xsize, ysize, xorig, yorig;
+ float pdf_version_found, pdf_version_wanted, xsize, ysize, xorig, yorig;
assert(idict != NULL);
assert(img_type(idict) == IMG_TYPE_PDF);
+ assert(readtype == IMG_CLOSEINBETWEEN); // only this is implemented
// initialize
if (isInit == gFalse) {
globalParams = new GlobalParams();
globalParams->setErrQuiet(gFalse);
isInit = gTrue;
}
+ // calculate a checksum string
+ checksum = get_file_checksum(img_filepath(idict));
// open PDF file
pdf_doc = refPdfDocument(img_filepath(idict));
+ if (strncmp(pdf_doc->checksum, checksum, PDF_CHECKSUM_SIZE) != 0) {
+ pdftex_fail("PDF inclusion: file has changed '%s'",
+ img_filename(idict));
+ }
+ free(checksum);
// 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.
-#ifdef HAVE_GETPDFMAJORVERSION
- pdf_major_version_found = pdf_doc->doc->getPDFMajorVersion();
- pdf_minor_version_found = pdf_doc->doc->getPDFMinorVersion();
- if ((pdf_major_version_found > 1)
- || (pdf_minor_version_found > minor_pdf_version_wanted)) {
- const char *msg =
- "PDF inclusion: found PDF version <%d.%d>, but at most version <1.%d> allowed";
- if (pdf_inclusion_errorlevel > 0) {
- pdftex_fail(msg, pdf_major_version_found, pdf_minor_version_found, minor_pdf_version_wanted);
- } else {
- pdftex_warn(msg, pdf_major_version_found, pdf_minor_version_found, minor_pdf_version_wanted);
- }
- }
-#else
pdf_version_found = pdf_doc->doc->getPDFVersion();
pdf_version_wanted = 1 + (minor_pdf_version_wanted * 0.1);
if (pdf_version_found > pdf_version_wanted + 0.01) {
@@ -754,7 +505,6 @@ read_pdf_info(image_dict * idict, integer minor_pdf_version_wanted,
pdftex_warn(msg, pdf_version_found, pdf_version_wanted);
}
}
-#endif
img_totalpages(idict) = pdf_doc->doc->getCatalog()->getNumPages();
if (img_pagename(idict)) {
// get page by name
@@ -777,11 +527,10 @@ read_pdf_info(image_dict * idict, integer minor_pdf_version_wanted,
pdftex_fail("PDF inclusion: required page <%i> does not exist",
(int) img_pagenum(idict));
}
- pdf_doc->xref = pdf_doc->doc->getXRef();
// get the required page
page = pdf_doc->doc->getCatalog()->getPage(img_pagenum(idict));
- // get the pagebox (media, crop...) to use.
+ // get the pagebox coordinates (media, crop,...) to use.
pagebox = get_pagebox(page, img_pagebox(idict));
if (pagebox->x2 > pagebox->x1) {
xorig = pagebox->x1;
@@ -824,67 +573,60 @@ read_pdf_info(image_dict * idict, integer minor_pdf_version_wanted,
("PDF inclusion: "
"/Rotate parameter in PDF file not multiple of 90 degrees.");
}
- if (page->getGroup() != NULL) {
- initDictFromDict(lastGroup, page->getGroup());
- if (lastGroup->dictGetLength() > 0) {
- groupIsIndirect = lastGroup->isRef();
- if (groupIsIndirect) {
- // FIXME: Here we already copy the object. It would be
- // better to do this only after write_epdf, otherwise we
- // may copy ununsed /Group objects
- copyObject(&lastGroup);
- epdf_lastGroupObjectNum =
- getNewObjectNumber(lastGroup->getRef());
- } else {
- // make the group an indirect object; copying is done later
- // by write_additional_epdf_objects after write_epdf
- epdf_lastGroupObjectNum = pdf_new_objnum();
- }
- pdf_puts("\n");
- }
- } else {
- epdf_lastGroupObjectNum = 0;
- }
+ // currently unused info whether PDF contains a /Group
+ if (page->getGroup() != NULL)
+ img_set_group(idict);
+
+ if (readtype == IMG_CLOSEINBETWEEN)
+ unrefPdfDocument(img_filepath(idict));
}
+//**********************************************************************
// Writes the current epf_doc.
-// Here the included PDF is copied, so most errors that can happen during PDF
-// inclusion will arise here.
+// Here the included PDF is copied, so most errors that can happen
+// during PDF inclusion will arise here.
-static void write_epdf1(image_dict * idict)
+static void write_epdf1(PDF pdf, image_dict * idict)
{
+ PdfDocument *pdf_doc;
Page *page;
- PdfObject contents, obj1, obj2;
- PdfObject metadata, pieceinfo, separationInfo;
- Object info;
- char *key;
+ PdfObject info, contents, metadata, obj1;
+ Object *metadataNF, *resourcesNF;
+ char *checksum;
char s[256];
int i, l;
- PdfDocument *pdf_doc = (PdfDocument *) findPdfDocument(img_filepath(idict));
- assert(pdf_doc != NULL);
- xref = pdf_doc->xref;
- inObjList = pdf_doc->inObjList;
- encodingList = NULL;
+ assert(idict != NULL);
+ // calculate a checksum string
+ checksum = get_file_checksum(img_filepath(idict));
+ // open PDF file
+ pdf_doc = refPdfDocument(img_filepath(idict));
+ if (strncmp(pdf_doc->checksum, checksum, PDF_CHECKSUM_SIZE) != 0) {
+ pdftex_fail("PDF inclusion: file has changed '%s'",
+ img_filename(idict));
+ }
+ free(checksum);
+ (void) pdf_doc->doc->getCatalog()->getPage(img_pagenum(idict));
page = pdf_doc->doc->getCatalog()->getPage(img_pagenum(idict));
PDFRectangle *pagebox;
float bbox[4];
// write the Page header
- pdf_puts("/Type /XObject\n/Subtype /Form\n");
+ pdf_puts(pdf, "/Type /XObject\n/Subtype /Form\n");
if (img_attr(idict) != NULL && strlen(img_attr(idict)) > 0)
- pdf_printf("%s\n", img_attr(idict));
- pdf_puts("/FormType 1\n");
+ pdf_printf(pdf, "%s\n", img_attr(idict));
+ pdf_puts(pdf, "/FormType 1\n");
// write additional information
- pdf_printf("/%s.FileName (%s)\n", pdfkeyprefix,
+ pdf_printf(pdf, "/%s.FileName (%s)\n", pdfkeyprefix,
convertStringToPDFString(pdf_doc->file_path,
strlen(pdf_doc->file_path)));
- pdf_printf("/%s.PageNumber %i\n", pdfkeyprefix, (int) img_pagenum(idict));
+ pdf_printf(pdf, "/%s.PageNumber %i\n", pdfkeyprefix,
+ (int) img_pagenum(idict));
pdf_doc->doc->getDocInfoNF(&info);
- if (info.isRef()) {
+ if (info->isRef()) {
// the info dict must be indirect (PDF Ref p. 61)
- pdf_printf("/%s.InfoDict ", pdfkeyprefix);
- pdf_printf("%d 0 R\n", addOther(info.getRef()));
+ pdf_printf(pdf, "/%s.InfoDict ", pdfkeyprefix);
+ pdf_printf(pdf, "%d 0 R\n", addInObj(pdf, pdf_doc, info->getRef()));
}
if (img_is_bbox(idict)) {
bbox[0] = int2bp(img_bbox(idict)[0]);
@@ -892,7 +634,7 @@ static void write_epdf1(image_dict * idict)
bbox[2] = int2bp(img_bbox(idict)[2]);
bbox[3] = int2bp(img_bbox(idict)[3]);
} else {
- // get the pagebox (media, crop...) to use.
+ // get the pagebox coordinates (media, crop,...) to use.
pagebox = get_pagebox(page, img_pagebox(idict));
bbox[0] = pagebox->x1;
bbox[1] = pagebox->y1;
@@ -901,77 +643,57 @@ static void write_epdf1(image_dict * idict)
}
sprintf(s, "/BBox [%.8f %.8f %.8f %.8f]\n", bbox[0], bbox[1], bbox[2],
bbox[3]);
- pdf_puts(stripzeros(s));
+ pdf_puts(pdf, stripzeros(s));
// The /Matrix calculation is replaced by transforms in out_img().
- // write the page Group if it's there
- if (epdf_lastGroupObjectNum > 0) {
- if (page->getGroup() != NULL) {
- initDictFromDict(lastGroup, page->getGroup());
- if (lastGroup->dictGetLength() > 0) {
- pdf_puts("/Group ");
- groupIsIndirect = lastGroup->isRef();
- pdf_printf("%d 0 R", (int) epdf_lastGroupObjectNum);
- pdf_puts("\n");
- }
- }
+ // Now all relevant parts of the /Page dictionary are copied:
+
+ // write the /Resources dictionary
+ if (page->getResourceDict() == NULL) {
+ // Resources can be missing (files without them have been spotted
+ // in the wild); in which case the /Resouces of the /Page will be used.
+ // "This practice is not recommended".
+ pdftex_warn
+ ("PDF inclusion: /Resources missing. 'This practice is not recommended' (PDF Ref.)");
+ } else {
+#if 0 // TEMP, waiting for XPDF patch
+ resourcesNF = page->getResourcesNF();
+ pdf_puts(pdf, "/Resources ");
+ copyObject(pdf, pdf_doc, resourcesNF);
+#endif
}
- // write the page Metadata if it's there
+ // write the page /Metadata if it's there (as a stream it must be indirect)
if (page->getMetadata() != NULL) {
- metadata->initStream(page->getMetadata());
- pdf_puts("/Metadata ");
- copyObject(&metadata);
- pdf_puts("\n");
+#if 0 // TEMP, waiting for XPDF patch
+ metadataNF = page->getMetadataNF(); // *NF = "don't resolve indirects"
+ if (!metadataNF->isRef())
+ pdftex_warn("PDF inclusion: /Metadata must be indirect object");
+ else {
+ pdf_printf(pdf, "/Metadata %d 0 R",
+ addInObj(pdf, pdf_doc, metadataNF->getRef()));
+ }
+#endif
}
- // write the page PieceInfo if it's there
+ // write the page /Group if it's there
+ if (page->getGroup() != NULL) {
+ pdf_puts(pdf, "/Group ");
+ copyDict(pdf, pdf_doc, page->getGroup());
+ }
+ // write the page /PieceInfo if it's there
if (page->getPieceInfo() != NULL) {
- initDictFromDict(pieceinfo, page->getPieceInfo());
- if (pieceinfo->dictGetLength() > 0) {
- pdf_puts("/PieceInfo ");
- copyObject(&pieceinfo);
- pdf_puts("\n");
- }
+ pdf_puts(pdf, "/PieceInfo ");
+ copyDict(pdf, pdf_doc, page->getPieceInfo());
+ }
+ // write the page /SeparationInfo if it's there
+ if (page->getSeparationInfo() != NULL) {
+ pdf_puts(pdf, "/SeparationInfo ");
+ copyDict(pdf, pdf_doc, page->getSeparationInfo());
}
// copy LastModified (needed when PieceInfo is there)
if (page->getLastModified() != NULL) {
- pdf_printf("/LastModified (%s)\n",
+ pdf_printf(pdf, "/LastModified (%s)\n",
page->getLastModified()->getCString());
}
- // write the page SeparationInfo if it's there
- if (page->getSeparationInfo() != NULL) {
- initDictFromDict(separationInfo, page->getSeparationInfo());
- if (separationInfo->dictGetLength() > 0) {
- pdf_puts("/SeparationInfo ");
- copyObject(&separationInfo);
- pdf_puts("\n");
- }
- }
- // write the Resources dictionary
- if (page->getResourceDict() == NULL) {
- // Resources can be missing (files without them have been spotted
- // in the wild); in which case the /Resouces of the /Page will be used.
- // "This practice is not recommended".
- pdftex_warn
- ("PDF inclusion: /Resources missing. 'This practice is not recommended' (PDF Ref)");
- } else {
- initDictFromDict(obj1, page->getResourceDict());
- page->getResourceDict()->incRef();
- if (!obj1->isDict())
- pdftex_fail("PDF inclusion: invalid resources dict type <%s>",
- obj1->getTypeName());
- pdf_puts("/Resources <<\n");
- for (i = 0, l = obj1->dictGetLength(); i < l; ++i) {
- obj1->dictGetVal(i, &obj2);
- key = obj1->dictGetKey(i);
- if (strcmp("Font", key) == 0)
- copyFontResources(&obj2);
- else if (strcmp("ProcSet", key) == 0)
- copyProcSet(&obj2);
- else
- copyOtherResources(&obj2, key);
- }
- pdf_puts(">>\n");
- }
// write the page contents
page->getContents(&contents);
if (contents->isStream()) {
@@ -979,84 +701,108 @@ static void write_epdf1(image_dict * idict)
// of \pdfcompresslevel
//
// pdfbeginstream();
- // copyStream(contents->getStream());
+ // copyStreamStream(contents->getStream());
// pdfendstream();
// Variant B: copy stream without recompressing
//
- contents->streamGetDict()->lookup("F", &obj1);
+ contents->streamGetDict()->lookup((char *) "F", &obj1);
if (!obj1->isNull()) {
pdftex_fail("PDF inclusion: Unsupported external stream");
}
- contents->streamGetDict()->lookup("Length", &obj1);
+ contents->streamGetDict()->lookup((char *) "Length", &obj1);
assert(!obj1->isNull());
- pdf_puts("/Length ");
- copyObject(&obj1);
- pdf_puts("\n");
- contents->streamGetDict()->lookup("Filter", &obj1);
+ pdf_puts(pdf, "/Length ");
+ copyObject(pdf, pdf_doc, &obj1);
+ pdf_puts(pdf, "\n");
+ contents->streamGetDict()->lookup((char *) "Filter", &obj1);
if (!obj1->isNull()) {
- pdf_puts("/Filter ");
- copyObject(&obj1);
- pdf_puts("\n");
- contents->streamGetDict()->lookup("DecodeParms", &obj1);
+ pdf_puts(pdf, "/Filter ");
+ copyObject(pdf, pdf_doc, &obj1);
+ pdf_puts(pdf, "\n");
+ contents->streamGetDict()->lookup((char *) "DecodeParms", &obj1);
if (!obj1->isNull()) {
- pdf_puts("/DecodeParms ");
- copyObject(&obj1);
- pdf_puts("\n");
+ pdf_puts(pdf, "/DecodeParms ");
+ copyObject(pdf, pdf_doc, &obj1);
+ pdf_puts(pdf, "\n");
}
}
- pdf_puts(">>\nstream\n");
- copyStream(contents->getStream()->getBaseStream());
- pdf_end_stream();
+ pdf_puts(pdf, ">>\nstream\n");
+ copyStreamStream(pdf, contents->getStream()->getBaseStream());
+ pdf_end_stream(pdf);
} else if (contents->isArray()) {
- pdf_begin_stream();
+ pdf_begin_stream(pdf);
for (i = 0, l = contents->arrayGetLength(); i < l; ++i) {
- Object contentsobj;
- copyStream((contents->arrayGet(i, &contentsobj))->getStream());
- contentsobj.free();
+ PdfObject contentsobj;
+ copyStreamStream(pdf,
+ (contents->arrayGet(i, &contentsobj))->
+ getStream());
+ 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_end_stream();
+ pdf_end_stream(pdf);
} else { // the contents are optional, but we need to include an empty stream
- pdf_begin_stream();
- pdf_end_stream();
+ pdf_begin_stream(pdf);
+ pdf_end_stream(pdf);
}
// write out all indirect objects
- writeRefs();
- // write out all used encodings (and delete list)
- writeEncodings();
- // save object list
- pdf_doc->inObjList = inObjList;
- assert(xref == pdf_doc->xref); // xref should be unchanged
+ writeRefs(pdf, pdf_doc);
}
-void write_epdf(image_dict * idict)
+// this relay function is needed to keep some destructor quiet (???)
+
+void write_epdf(PDF pdf, image_dict * idict)
{
- assert(idict != NULL);
- write_epdf1(idict);
+ write_epdf1(pdf, idict);
unrefPdfDocument(img_filepath(idict));
}
//**********************************************************************
// Deallocate a PdfDocument with all its resources
-static void deletePdfDocument(PdfDocument * pdf_doc)
+static void deletePdfDocumentPdfDoc(PdfDocument * pdf_doc)
{
- assert(pdf_doc != NULL);
- // free PdfDocument's resources
InObj *r, *n;
+ assert(pdf_doc != NULL);
+ // this may be probably needed for an emergency destroyPdfDocument()
for (r = pdf_doc->inObjList; r != NULL; r = n) {
n = r->next;
delete r;
}
delete pdf_doc->doc;
- xfree(pdf_doc->file_path);
- delete pdf_doc;
+ pdf_doc->doc = NULL;
}
-static void destroyPdfDocument(void *pa, void *pb)
+static void destroyPdfDocument(void *pa, void * /*pb */ )
{
PdfDocument *pdf_doc = (PdfDocument *) pa;
- deletePdfDocument(pdf_doc);
+ deletePdfDocumentPdfDoc(pdf_doc);
+ // TODO: delete rest of pdf_doc
+}
+
+// Called when an image has been written and its resources in image_tab are
+// freed and it's not referenced anymore.
+
+void unrefPdfDocument(char *file_path)
+{
+ PdfDocument *pdf_doc = findPdfDocument(file_path);
+ assert(pdf_doc != NULL);
+ assert(pdf_doc->occurences > 0); // aim for point landing
+ pdf_doc->occurences--;
+#ifdef DEBUG
+ fprintf(stderr, "\nluatex Debug: Decrementing %s (%d)\n",
+ pdf_doc->file_path, pdf_doc->occurences);
+#endif
+ if (pdf_doc->occurences == 0) {
+#ifdef DEBUG
+ fprintf(stderr, "\nluatex Debug: Deleting %s\n", pdf_doc->file_path);
+#endif
+ assert(pdf_doc->inObjList == NULL); // should be eaten up already
+ deletePdfDocumentPdfDoc(pdf_doc);
+ }
}
// Called when PDF embedding system is finalized.
@@ -1071,14 +817,3 @@ void epdf_check_mem()
delete globalParams;
isInit = gFalse;
}
-
-// Called after the xobject generated by write_epdf has been finished; used to
-// write out objects that have been made indirect
-void write_additional_epdf_objects(void)
-{
- if ((epdf_lastGroupObjectNum > 0) && !groupIsIndirect) {
- zpdf_begin_obj(epdf_lastGroupObjectNum, 2);
- copyObject(&lastGroup);
- pdf_end_obj();
- }
-}
diff --git a/Build/source/texk/web2c/luatexdir/image/pdftoepdf.h b/Build/source/texk/web2c/luatexdir/image/pdftoepdf.h
index 50d89c0a861..05bb85eeaa5 100644
--- a/Build/source/texk/web2c/luatexdir/image/pdftoepdf.h
+++ b/Build/source/texk/web2c/luatexdir/image/pdftoepdf.h
@@ -18,22 +18,20 @@
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 2331 2009-04-18 16:39:50Z hhenkel $ */
+/* $Id: pdftoepdf.h 3319 2009-12-27 20:05:36Z hhenkel $ */
#ifndef PDFTOEPDF_H
# define PDFTOEPDF_H
# include "image.h"
-void read_pdf_info(image_dict *, integer, integer);
+void read_pdf_info(image_dict *, int, int, img_readtype_e);
void unrefPdfDocument(char *);
-void write_additional_epdf_objects(void);
-void write_epdf(image_dict *);
+void write_epdf(PDF, image_dict *);
void epdf_check_mem(void);
/* epdf.c --- this should go in an own header file */
-extern integer get_fontfile_num(int);
-extern integer get_fontname_num(int);
+
extern void epdf_free(void);
#endif /* PDFTOEPDF_H */
diff --git a/Build/source/texk/web2c/luatexdir/image/writeimg.c b/Build/source/texk/web2c/luatexdir/image/writeimg.c
deleted file mode 100644
index f570fd46996..00000000000
--- a/Build/source/texk/web2c/luatexdir/image/writeimg.c
+++ /dev/null
@@ -1,959 +0,0 @@
-/* writeimg.c
-
- Copyright 1996-2006 Han The Thanh <thanh@pdftex.org>
- Copyright 2006-2009 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/>. */
-
-#include <assert.h>
-#include "ptexlib.h"
-#include <kpathsea/c-auto.h>
-#include <kpathsea/c-memstr.h>
-
-#include "image.h"
-#include "writejpg.h"
-#include "writepng.h"
-#include "writejbig2.h"
-#include "pdftoepdf.h"
-
-#include <../lua51/lua.h>
-#include <../lua51/lauxlib.h>
-
-static const char _svn_version[] =
- "$Id: writeimg.c 2448 2009-06-08 07:43:50Z taco $ "
- "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/image/writeimg.c $";
-
-/**********************************************************************/
-/*
- Patch ImageTypeDetection 2003/02/08 by Heiko Oberdiek.
-
- Function "readimage" performs some basic initializations.
- Then it looks at the file extension to determine the
- image type and calls specific code/functions.
- The main disadvantage is that standard file extensions
- have to be used, otherwise pdfTeX is not able to detect
- the correct image type.
-
- The patch now looks at the file header first regardless of
- the file extension. This is implemented in function
- "check_type_by_header". If this check fails, the traditional
- test of standard file extension is tried, done in function
- "check_type_by_extension".
-
- Magic headers:
-
- * "PNG (Portable Network Graphics) Specification", Version 1.2
- (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"
-
- * "JPEG File Interchange Format", Version 1.02:
-
- | o you can identify a JFIF file by looking for the following
- | sequence: X'FF', SOI X'FF', APP0, <2 bytes to be skipped>,
- | "JFIF", X'00'.
-
- Function "check_type_by_header" only looks at the first two bytes:
- "\xFF\xD8"
-
- * ISO/IEC JTC 1/SC 29/WG 1
- (ITU-T SG8)
- Coding of Still Pictures
- Title: 14492 FCD
- Source: JBIG Committee
- Project: JTC 1.29.10
- Status: Final Committee Draft
-
- | D.4.1, ID string
- |
- | This is an 8-byte sequence containing 0x97 0x4A 0x42 0x32 0x0D 0x0A
- | 0x1A 0x0A.
-
- * "PDF Reference", third edition:
- * The first line should contain "%PDF-1.0" until "%PDF-1.4"
- (section 3.4.1 "File Header").
- * The "implementation notes" say:
-
- | 3.4.1, File Header
- | 12. Acrobat viewers require only that the header appear
- | somewhere within the first 1024 bytes of the file.
- | 13. Acrobat viewers will also accept a header of the form
- | %!PS-Adobe-N.n PDF-M.m
-
- The check in function "check_type_by_header" only implements
- the first issue. The implementation notes are not considered.
- Therefore files with garbage at start of file must have the
- standard extension.
-
- Functions "check_type_by_header" and "check_type_by_extension":
- img_type(img) is set to IMG_TYPE_NONE by new_image_dict().
- Both functions try to detect a type and set img_type(img).
- Thus a value other than IMG_TYPE_NONE indicates that a
- type has been found.
-*/
-
-#define HEADER_JPG "\xFF\xD8"
-#define HEADER_PNG "\x89PNG\r\n\x1A\n"
-#define HEADER_JBIG2 "\x97\x4A\x42\x32\x0D\x0A\x1A\x0A"
-#define HEADER_PDF "%PDF-1."
-#define MAX_HEADER (sizeof(HEADER_PNG)-1)
-
-integer epdf_lastGroupObjectNum;
-
-static void check_type_by_header(image_dict * idict)
-{
- int i;
- FILE *file = NULL;
- char header[MAX_HEADER];
-
- assert(idict != NULL);
- if (img_type(idict) != IMG_TYPE_NONE) /* nothing to do */
- return;
- /* read the header */
- file = xfopen(img_filepath(idict), FOPEN_RBIN_MODE);
- for (i = 0; (unsigned) i < MAX_HEADER; i++) {
- header[i] = xgetc(file);
- if (feof(file))
- pdftex_fail("reading image file failed");
- }
- xfclose(file, img_filepath(idict));
- /* tests */
- if (strncmp(header, HEADER_JPG, sizeof(HEADER_JPG) - 1) == 0)
- img_type(idict) = IMG_TYPE_JPG;
- else if (strncmp(header, HEADER_PNG, sizeof(HEADER_PNG) - 1) == 0)
- img_type(idict) = IMG_TYPE_PNG;
- else if (strncmp(header, HEADER_JBIG2, sizeof(HEADER_JBIG2) - 1) == 0)
- img_type(idict) = IMG_TYPE_JBIG2;
- else if (strncmp(header, HEADER_PDF, sizeof(HEADER_PDF) - 1) == 0)
- img_type(idict) = IMG_TYPE_PDF;
-}
-
-static void check_type_by_extension(image_dict * idict)
-{
- char *image_suffix;
-
- assert(idict != NULL);
- if (img_type(idict) != IMG_TYPE_NONE) /* nothing to do */
- return;
- /* tests */
- if ((image_suffix = strrchr(img_filename(idict), '.')) == 0)
- img_type(idict) = IMG_TYPE_NONE;
- else if (strcasecmp(image_suffix, ".png") == 0)
- img_type(idict) = IMG_TYPE_PNG;
- else if (strcasecmp(image_suffix, ".jpg") == 0 ||
- strcasecmp(image_suffix, ".jpeg") == 0)
- img_type(idict) = IMG_TYPE_JPG;
- else if (strcasecmp(image_suffix, ".jbig2") == 0 ||
- strcasecmp(image_suffix, ".jb2") == 0)
- img_type(idict) = IMG_TYPE_JBIG2;
- else if (strcasecmp(image_suffix, ".pdf") == 0)
- img_type(idict) = IMG_TYPE_PDF;
-}
-
-/**********************************************************************/
-
-void new_img_pdfstream_struct(image_dict * p)
-{
- assert(p != NULL);
- assert(img_pdfstream_ptr(p) == NULL);
- img_pdfstream_ptr(p) = xtalloc(1, pdf_stream_struct);
- img_pdfstream_stream(p) = NULL;
-}
-
-/**********************************************************************/
-
-void init_image(image * p)
-{
- assert(p != NULL);
- set_wd_running(p);
- set_ht_running(p);
- set_dp_running(p);
- img_transform(p) = 0;
- img_flags(p) = 0;
- img_unset_scaled(p);
- img_dict(p) = NULL;
- img_arrayidx(p) = -1; /* -1 = unused, used count from 0 */
- img_dictref(p) = LUA_NOREF;
-}
-
-image *new_image(void)
-{
- image *p = xtalloc(1, image);
- init_image(p);
- return p;
-}
-
-void init_image_dict(image_dict * p)
-{
- assert(p != NULL);
- img_objnum(p) = 0;
- img_index(p) = 0;
- img_xsize(p) = 0;
- img_ysize(p) = 0;
- img_xorig(p) = 0;
- img_yorig(p) = 0;
- img_xres(p) = 0;
- img_yres(p) = 0;
- img_rotation(p) = 0;
- img_colorspace(p) = 0;
- img_group_ref(p) = 0;
- img_totalpages(p) = 0;
- img_pagenum(p) = 1;
- img_pagename(p) = NULL;
- img_filename(p) = NULL;
- img_filepath(p) = NULL;
- img_attr(p) = NULL;
- img_file(p) = NULL;
- img_type(p) = IMG_TYPE_NONE;
- img_color(p) = 0;
- img_colordepth(p) = 0;
- img_pagebox(p) = PDF_BOX_SPEC_MEDIA;
- img_bbox(p)[0] = 0;
- img_bbox(p)[1] = 0;
- img_bbox(p)[2] = 0;
- img_bbox(p)[3] = 0;
- img_unset_bbox(p);
- img_state(p) = DICT_NEW;
- img_png_ptr(p) = NULL; /* union */
-}
-
-image_dict *new_image_dict(void)
-{
- image_dict *p = xtalloc(1, image_dict);
- init_image_dict(p);
- return p;
-}
-
-static void free_dict_strings(image_dict * p)
-{
- if (img_filename(p) != NULL)
- xfree(img_filename(p));
- img_filename(p) = NULL;
- if (img_filepath(p) != NULL)
- xfree(img_filepath(p));
- img_filepath(p) = NULL;
- if (img_attr(p) != NULL)
- xfree(img_attr(p));
- img_attr(p) = NULL;
- if (img_pagename(p) != NULL)
- xfree(img_pagename(p));
- img_pagename(p) = NULL;
-}
-
-void free_image_dict(image_dict * p)
-{
- if (ini_version)
- return; /* The image may be \dump{}ed to a format */
- /* called from limglib.c */
- assert(img_state(p) < DICT_REFERED);
- switch (img_type(p)) {
- case IMG_TYPE_PDF:
- unrefPdfDocument(img_filepath(p));
- break;
- case IMG_TYPE_PNG: /* assuming IMG_CLOSEINBETWEEN */
- assert(img_png_ptr(p) == NULL);
- break;
- case IMG_TYPE_JPG: /* assuming IMG_CLOSEINBETWEEN */
- assert(img_jpg_ptr(p) == NULL);
- break;
- case IMG_TYPE_JBIG2: /* todo: writejbig2.c cleanup */
- break;
- case IMG_TYPE_PDFSTREAM:
- if (img_pdfstream_ptr(p) != NULL) {
- if (img_pdfstream_stream(p) != NULL)
- xfree(img_pdfstream_stream(p));
- xfree(img_pdfstream_ptr(p));
- }
- break;
- case IMG_TYPE_NONE:
- break;
- default:
- assert(0);
- }
- free_dict_strings(p);
- assert(img_file(p) == NULL);
- xfree(p);
-}
-
-/**********************************************************************/
-
-void pdf_print_resname_prefix(void)
-{
- if (pdf_resname_prefix != 0)
- pdf_printf(makecstring(pdf_resname_prefix));
-}
-
-void read_img(image_dict * idict, integer pdf_minor_version,
- integer pdf_inclusion_errorlevel)
-{
- char *filepath;
- int callback_id;
- assert(idict != NULL);
- if (img_filename(idict) == NULL)
- pdftex_fail("image file name missing");
- callback_id = callback_defined(find_image_file_callback);
- if (img_filepath(idict) == NULL) {
- if (callback_id > 0
- && run_callback(callback_id, "S->S", img_filename(idict),
- &filepath)) {
- if (filepath && (strlen(filepath) > 0))
- img_filepath(idict) = strdup(filepath);
- } else
- img_filepath(idict) =
- kpse_find_file(img_filename(idict), kpse_tex_format, true);
- }
- if (img_filepath(idict) == NULL)
- pdftex_fail("cannot find image file");
- recorder_record_input(img_filename(idict));
- /* type checks */
- check_type_by_header(idict);
- check_type_by_extension(idict);
- /* read image */
- switch (img_type(idict)) {
- case IMG_TYPE_PDF:
- read_pdf_info(idict, pdf_minor_version, pdf_inclusion_errorlevel);
- img_group_ref(idict) = epdf_lastGroupObjectNum;
- break;
- case IMG_TYPE_PNG:
- read_png_info(idict, IMG_CLOSEINBETWEEN);
- break;
- case IMG_TYPE_JPG:
- read_jpg_info(idict, IMG_CLOSEINBETWEEN);
- break;
- case IMG_TYPE_JBIG2:
- if (pdf_minor_version < 4) {
- pdftex_fail
- ("JBIG2 images only possible with at least PDF 1.4; you are generating PDF 1.%i",
- (int) pdf_minor_version);
- }
- read_jbig2_info(idict);
- break;
- default:
- pdftex_fail("internal error: unknown image type (2)");
- }
- cur_file_name = NULL;
- if (img_state(idict) < DICT_FILESCANNED)
- img_state(idict) = DICT_FILESCANNED;
-}
-
-// Within scale_img() only image width and height matter;
-// the offsets and positioning are not interesting here.
-// But one needs rotation info to swap width and height.
-// img_rotation() comes from the optional /Rotate key in the PDF file.
-
-void scale_img(image * img)
-{
- integer x, y, xr, yr, tmp; /* size and resolution of image */
- scaled w = 0, h = 0; /* indeed size corresponds to image resolution */
- integer default_res;
- image_dict *idict;
- assert(img != NULL);
- idict = img_dict(img);
- assert(idict != NULL);
- if ((img_type(idict) == IMG_TYPE_PDF
- || img_type(idict) == IMG_TYPE_PDFSTREAM) && img_is_bbox(idict)) {
- x = img_xsize(idict) = img_bbox(idict)[2] - img_bbox(idict)[0]; /* dimensions from image.bbox */
- y = img_ysize(idict) = img_bbox(idict)[3] - img_bbox(idict)[1];
- img_xorig(idict) = img_bbox(idict)[0];
- img_yorig(idict) = img_bbox(idict)[1];
- } else {
- x = img_xsize(idict); /* dimensions, resolutions from image file */
- y = img_ysize(idict);
- }
- xr = img_xres(idict);
- yr = img_yres(idict);
- if (x <= 0 || y <= 0 || xr < 0 || yr < 0)
- pdftex_fail("ext1: invalid image dimensions");
- if (xr > 65535 || yr > 65535) {
- xr = 0;
- yr = 0;
- pdftex_warn("ext1: too large image resolution ignored");
- }
- if (((img_transform(img) - img_rotation(idict)) & 1) == 1) {
- tmp = x;
- x = y;
- y = tmp;
- tmp = xr;
- xr = yr;
- yr = tmp;
- }
- if (img_type(idict) == IMG_TYPE_PDF
- || img_type(idict) == IMG_TYPE_PDFSTREAM) {
- w = x;
- h = y;
- } else {
- default_res = fix_int(get_pdf_image_resolution(), 0, 65535);
- if (default_res > 0 && (xr == 0 || yr == 0)) {
- xr = default_res;
- yr = default_res;
- }
- if (is_wd_running(img) && is_ht_running(img)) {
- if (xr > 0 && yr > 0) {
- w = ext_xn_over_d(one_hundred_inch, x, 100 * xr);
- h = ext_xn_over_d(one_hundred_inch, y, 100 * yr);
- } else {
- w = ext_xn_over_d(one_hundred_inch, x, 7200);
- h = ext_xn_over_d(one_hundred_inch, y, 7200);
- }
- }
- }
- if (is_wd_running(img) && is_ht_running(img) && is_dp_running(img)) {
- img_width(img) = w;
- img_height(img) = h;
- img_depth(img) = 0;
- } else if (is_wd_running(img)) {
- /* image depth or height is explicitly specified */
- if (is_ht_running(img)) {
- /* image depth is explicitly specified */
- img_width(img) = ext_xn_over_d(h, x, y);
- img_height(img) = h - img_depth(img);
- } else if (is_dp_running(img)) {
- /* image height is explicitly specified */
- img_width(img) = ext_xn_over_d(img_height(img), x, y);
- img_depth(img) = 0;
- } else {
- /* both image depth and height are explicitly specified */
- img_width(img) =
- ext_xn_over_d(img_height(img) + img_depth(img), x, y);
- }
- } else {
- /* image width is explicitly specified */
- if (is_ht_running(img) && is_dp_running(img)) {
- /* both image depth and height are not specified */
- img_height(img) = ext_xn_over_d(img_width(img), y, x);
- img_depth(img) = 0;
- }
- /* image depth is explicitly specified */
- else if (is_ht_running(img)) {
- img_height(img) =
- ext_xn_over_d(img_width(img), y, x) - img_depth(img);
- }
- /* image height is explicitly specified */
- else if (is_dp_running(img)) {
- img_depth(img) = 0;
- }
- /* else both image depth and height are explicitly specified */
- }
- img_set_scaled(img);
-}
-
-static void out_img(image * img, pdfstructure * p, scaledpos * pos)
-{
- float a[6]; /* transformation matrix */
- float xoff, yoff, tmp;
- int r; /* number of digits after the decimal point */
- int k;
- scaled wd, ht, dp;
- scaledpos tmppos;
- pdffloat cm[6];
- image_dict *idict;
- integer groupref; /* added from web for 1.40.8 */
- assert(img != 0);
- idict = img_dict(img);
- assert(idict != 0);
- wd = img_width(img);
- ht = img_height(img);
- dp = img_depth(img);
- a[0] = a[3] = 1.0e6;
- a[1] = a[2] = 0;
- if (img_type(idict) == IMG_TYPE_PDF
- || img_type(idict) == IMG_TYPE_PDFSTREAM) {
- a[0] /= img_xsize(idict);
- a[3] /= img_ysize(idict);
- xoff = (float) img_xorig(idict) / img_xsize(idict);
- yoff = (float) img_yorig(idict) / img_ysize(idict);
- r = 6;
- } else {
- /* added from web for 1.40.8 */
- if (img_type(idict) == IMG_TYPE_PNG) {
- groupref = img_group_ref(idict);
- if ((groupref > 0) && (pdf_page_group_val < 1))
- pdf_page_group_val = groupref;
- }
- /* /added from web */
- a[0] /= one_hundred_bp;
- a[3] = a[0];
- xoff = yoff = 0;
- r = 4;
- }
- if ((img_transform(img) & 7) > 3) { // mirror cases
- a[0] *= -1;
- xoff *= -1;
- }
- switch ((img_transform(img) + img_rotation(idict)) & 3) {
- case 0: /* no transform */
- break;
- case 1: /* rot. 90 deg. (counterclockwise) */
- a[1] = a[0];
- a[2] = -a[3];
- a[3] = a[0] = 0;
- tmp = yoff;
- yoff = xoff;
- xoff = -tmp;
- break;
- case 2: /* rot. 180 deg. (counterclockwise) */
- a[0] *= -1;
- a[3] *= -1;
- xoff *= -1;
- yoff *= -1;
- break;
- case 3: /* rot. 270 deg. (counterclockwise) */
- a[1] = -a[0];
- a[2] = a[3];
- a[3] = a[0] = 0;
- tmp = yoff;
- yoff = -xoff;
- xoff = tmp;
- break;
- default:;
- }
- xoff *= wd;
- yoff *= ht + dp;
- a[0] *= wd;
- a[1] *= ht + dp;
- a[2] *= wd;
- a[3] *= ht + dp;
- a[4] = pos->h - xoff;
- a[5] = pos->v - yoff;
- k = img_transform(img) + img_rotation(idict);
- if ((img_transform(img) & 7) > 3)
- k++;
- switch (k & 3) {
- case 0: /* no transform */
- break;
- case 1: /* rot. 90 deg. (counterclockwise) */
- a[4] += wd;
- break;
- case 2: /* rot. 180 deg. */
- a[4] += wd;
- a[5] += ht + dp;
- break;
- case 3: /* rot. 270 deg. */
- a[5] += ht + dp;
- break;
- default:;
- }
- /* the following is a kludge, TODO: use pdfpage.c functions */
- setpdffloat(cm[0], round(a[0]), r);
- setpdffloat(cm[1], round(a[1]), r);
- setpdffloat(cm[2], round(a[2]), r);
- setpdffloat(cm[3], round(a[3]), r);
- tmppos.h = round(a[4]);
- tmppos.v = round(a[5]);
- (void) calc_pdfpos(p, &tmppos);
- cm[4] = p->cm[4];
- cm[5] = p->cm[5];
- pdf_goto_pagemode();
- if (pdf_page_group_val < 1)
- pdf_page_group_val = img_group_ref(idict); /* added from web for 1.40.8 */
- pdf_printf("q\n");
- pdf_print_cm(cm);
- pdf_printf("/Im");
- pdf_print_int(img_index(idict));
- pdf_print_resname_prefix();
- pdf_printf(" Do\nQ\n");
- if (img_state(idict) < DICT_OUTIMG)
- img_state(idict) = DICT_OUTIMG;
-}
-
-void write_img(image_dict * idict)
-{
- assert(idict != NULL);
- if (img_state(idict) < DICT_WRITTEN) {
- if (tracefilenames)
- tex_printf(" <%s", img_filepath(idict));
- switch (img_type(idict)) {
- case IMG_TYPE_PNG:
- write_png(idict);
- break;
- case IMG_TYPE_JPG:
- write_jpg(idict);
- break;
- case IMG_TYPE_JBIG2:
- write_jbig2(idict);
- break;
- case IMG_TYPE_PDF:
- write_epdf(idict);
- epdf_lastGroupObjectNum = img_group_ref(idict);
- break;
- case IMG_TYPE_PDFSTREAM:
- write_pdfstream(idict);
- break;
- default:
- pdftex_fail("internal error: unknown image type (1)");
- }
- if (tracefilenames)
- tex_printf(">");
- if (img_type(idict) == IMG_TYPE_PDF) {
- write_additional_epdf_objects();
- } else {
- if (img_type(idict) == IMG_TYPE_PNG) {
- write_additional_png_objects();
- }
- }
- }
- if (img_state(idict) < DICT_WRITTEN)
- img_state(idict) = DICT_WRITTEN;
-}
-
-/**********************************************************************/
-
-void check_pdfstream_dict(image_dict * idict)
-{
- if (!img_is_bbox(idict))
- pdftex_fail("image.stream: no bbox given");
- if (img_state(idict) < DICT_FILESCANNED)
- img_state(idict) = DICT_FILESCANNED;
-}
-
-void write_pdfstream(image_dict * idict)
-{
- char s[256];
- assert(img_pdfstream_ptr(idict) != NULL);
- assert(img_is_bbox(idict));
- pdf_puts("/Type /XObject\n/Subtype /Form\n");
- if (img_attr(idict) != NULL && strlen(img_attr(idict)) > 0)
- pdf_printf("%s\n", img_attr(idict));
- pdf_puts("/FormType 1\n");
- sprintf(s, "/BBox [%.8f %.8f %.8f %.8f]\n", int2bp(img_bbox(idict)[0]),
- int2bp(img_bbox(idict)[1]), int2bp(img_bbox(idict)[2]),
- int2bp(img_bbox(idict)[3]));
- pdf_printf(stripzeros(s));
- pdf_begin_stream();
- if (img_pdfstream_stream(idict) != NULL)
- pdf_puts(img_pdfstream_stream(idict));
- pdf_end_stream();
-}
-
-/**********************************************************************/
-
-typedef image *img_entry;
-/* define img_ptr, img_array, & img_limit */
-/* avoid use of size_t */
-img_entry *img_ptr, *img_array = NULL;
-size_t img_limit;
-
-integer img_to_array(image * img)
-{
- assert(img != NULL);
- alloc_array(img, 1, SMALL_BUF_SIZE);
- *img_ptr = img;
- return img_ptr++ - img_array; /* now img is read-only */
-}
-
-/**********************************************************************/
-
-/* To allow the use of \pdfrefximage inside saved boxes in -ini mode,
- * the information in the array has to be (un)dumped with the format.
- * The next two routines take care of that.
- *
- * Most of the work involved in setting up the images is simply
- * executed again. This solves the many possible errors resulting from
- * the split in two separate runs.
-
- * There was only one problem remaining: The pdfversion and
- * pdfinclusionerrorlevel can have changed inbetween the call to
- * readimage() and dump time. That is why they are passed as arguments
- * to undumpimagemeta once more.
- */
-
-/* some of the dumped values are really type int, not integer,
- * but since the macro falls back to generic_dump anyway, that
- * does not matter.
- */
-
-#define dumpinteger generic_dump
-#define undumpinteger generic_undump
-
-/* (un)dumping a string means dumping the allocation size, followed
- * by the bytes. The trailing \0 is dumped as well, because that
- * makes the code simpler.
- */
-
-#define dumpcharptr(a) \
- do { \
- integer x; \
- if (a!=NULL) { \
- x = strlen(a)+1; \
- dumpinteger(x); dump_things(*a, x); \
- } else { \
- x = 0; dumpinteger(x); \
- } \
- } while (0)
-
-#define undumpcharptr(s) \
- do { \
- integer x; \
- char *a; \
- undumpinteger (x); \
- if (x>0) { \
- a = malloc(x); \
- undump_things(*a,x); \
- s = a ; \
- } else { s = NULL; } \
- } while (0)
-
-void dumpimagemeta(void)
-{
- int cur_image, i;
- image *img;
- image_dict *idict;
-
- dumpinteger(img_limit);
- cur_image = (img_ptr - img_array);
- dumpinteger(cur_image);
-
- for (i = 0; i < cur_image; i++) {
- img = img_array[i];
- assert(img != NULL);
- idict = img_dict(img);
- dumpcharptr(img_filename(idict));
- dumpinteger(img_type(idict));
- dumpinteger(img_color(idict));
- dumpinteger(img_width(img));
- dumpinteger(img_height(img));
- dumpinteger(img_xres(idict));
- dumpinteger(img_yres(idict));
- dumpinteger(img_totalpages(idict));
- dumpinteger(img_colorspace(idict));
- dumpinteger(img_group_ref(idict));
-
- /* the image_struct is not dumped at all, except for a few
- variables that are needed to restore the contents */
-
- if (img_type(idict) == IMG_TYPE_PDF) {
- dumpinteger(img_pagebox(idict));
- dumpinteger(img_pagenum(idict));
- } else if (img_type(idict) == IMG_TYPE_JBIG2) {
- dumpinteger(img_pagenum(idict));
- }
-
- }
-}
-
-void undumpimagemeta(integer pdfversion, integer pdfinclusionerrorlevel)
-{
- int cur_image, i;
- image *img;
- image_dict *idict;
-
- undumpinteger(img_limit);
-
- img_array = xtalloc(img_limit, img_entry);
- undumpinteger(cur_image);
- img_ptr = img_array + cur_image;
-
- for (i = 0; i < cur_image; i++) {
- img = new_image();
- assert(img_arrayidx(img) == -1);
- img_arrayidx(img) = img_to_array(img);
- idict = img_dict(img) = new_image_dict();
- assert(idict != NULL);
- undumpcharptr(img_filename(idict));
- undumpinteger(img_type(idict));
- undumpinteger(img_color(idict));
- undumpinteger(img_width(img));
- undumpinteger(img_height(img));
- undumpinteger(img_xres(idict));
- undumpinteger(img_yres(idict));
- undumpinteger(img_totalpages(idict));
- undumpinteger(img_colorspace(idict));
- undumpinteger(img_group_ref(idict));
-
- switch (img_type(idict)) {
- case IMG_TYPE_PDF:
- undumpinteger(img_pagebox(idict));
- undumpinteger(img_pagenum(idict));
- break;
- case IMG_TYPE_PNG:
- break;
- case IMG_TYPE_JPG:
- break;
- case IMG_TYPE_JBIG2:
- if (pdfversion < 4) {
- pdftex_fail
- ("JBIG2 images only possible with at least PDF 1.4; you are generating PDF 1.%i",
- (int) pdfversion);
- }
- undumpinteger(img_pagenum(idict));
- break;
- default:
- pdftex_fail("unknown type of image");
- }
- read_img(idict, pdfversion, pdfinclusionerrorlevel);
- }
-}
-
-/**********************************************************************/
-/* stuff to be accessible from TeX */
-
-integer read_image(integer objnum, integer index, str_number filename,
- integer page_num, str_number page_name, str_number attr,
- integer colorspace, integer page_box,
- integer pdf_minor_version, integer pdf_inclusion_errorlevel)
-{
- image_dict *idict;
- image *a = new_image();
- assert(img_arrayidx(a) == -1);
- img_arrayidx(a) = img_to_array(a);
- idict = img_dict(a) = new_image_dict();
- assert(idict != NULL);
- img_objnum(idict) = objnum;
- img_index(idict) = index;
- /* img_xsize, img_ysize, img_xres, img_yres set by read_img() */
- img_colorspace(idict) = colorspace;
- img_pagenum(idict) = page_num;
- /* img_totalpages set by read_img() */
- if (page_name != 0)
- img_pagename(idict) = xstrdup(makecstring(page_name));
- cur_file_name = makecfilename(filename);
- assert(cur_file_name != NULL);
- img_filename(idict) = xstrdup(cur_file_name);
- if (attr != 0)
- img_attr(idict) = xstrdup(makecstring(attr));
- img_pagebox(idict) = page_box;
- read_img(idict, pdf_minor_version, pdf_inclusion_errorlevel);
- img_unset_scaled(a);
- return img_arrayidx(a);
-}
-
-void set_image_dimensions(integer ref, integer wd, integer ht, integer dp)
-{
- image *a = img_array[ref];
- img_width(a) = wd;
- img_height(a) = ht;
- img_depth(a) = dp;
-}
-
-void scale_image(integer ref)
-{
- scale_img(img_array[ref]);
-}
-
-void out_image(integer ref, scaled hpos, scaled vpos)
-{
- image *a = img_array[ref];
- scaledpos pos;
- pos.h = hpos;
- pos.v = vpos;
- out_img(a, pstruct, &pos);
-}
-
-void write_image(integer ref)
-{
- write_img(img_dict(img_array[ref]));
-}
-
-integer image_pages(integer ref)
-{
- return img_totalpages(img_dict(img_array[ref]));
-}
-
-integer image_colordepth(integer ref)
-{
- return img_colordepth(img_dict(img_array[ref]));
-}
-
-#if 0 /* unused */
-static integer image_group_ref(integer ref)
-{
- return img_group_ref(img_dict(img_array[ref]));
-}
-#endif
-
-/* The following five functions are for \pdfximagebbox */
-
-integer epdf_xsize(integer ref)
-{
- return img_xsize(img_dict(img_array[ref]));
-}
-
-integer epdf_ysize(integer ref)
-{
- return img_ysize(img_dict(img_array[ref]));
-}
-
-integer epdf_orig_x(integer ref)
-{
- return img_xorig(img_dict(img_array[ref]));
-}
-
-integer epdf_orig_y(integer ref)
-{
- return img_yorig(img_dict(img_array[ref]));
-}
-
-boolean is_pdf_image(integer ref)
-{
- return img_type(img_dict(img_array[ref])) == IMG_TYPE_PDF;
-}
-
-boolean is_png_image(integer ref)
-{
- return img_type(img_dict(img_array[ref])) == IMG_TYPE_PNG;
-}
-
-integer image_objnum(integer ref)
-{
- return img_objnum(img_dict(img_array[ref]));
-}
-
-integer image_index(integer ref)
-{
- return img_index(img_dict(img_array[ref]));
-}
-
-integer image_width(integer ref)
-{
- return img_width(img_array[ref]);
-}
-
-integer image_height(integer ref)
-{
- return img_height(img_array[ref]);
-}
-
-integer image_depth(integer ref)
-{
- return img_depth(img_array[ref]);
-}
-
-void update_image_procset(integer ref)
-{
- pdf_image_procset |= img_color(img_dict(img_array[ref]));
-}
-
-boolean check_image_b(integer procset)
-{
- return procset & IMAGE_COLOR_B;
-}
-
-boolean check_image_c(integer procset)
-{
- return procset & IMAGE_COLOR_C;
-}
-
-boolean check_image_i(integer procset)
-{
- return procset & IMAGE_COLOR_I;
-}
diff --git a/Build/source/texk/web2c/luatexdir/image/writeimg.h b/Build/source/texk/web2c/luatexdir/image/writeimg.h
index bee82acaa97..66ef946d842 100644
--- a/Build/source/texk/web2c/luatexdir/image/writeimg.h
+++ b/Build/source/texk/web2c/luatexdir/image/writeimg.h
@@ -18,50 +18,35 @@
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 2448 2009-06-08 07:43:50Z taco $ */
+/* $Id: writeimg.h 3388 2010-01-26 10:59:04Z taco $ */
#ifndef WRITEIMG_H
# define WRITEIMG_H
+# include "dvi/dvigen.h" /* for scaled_whd only */
# include "image.h"
+# include "pdf/pdfpage.h"
-boolean check_image_b(integer);
-boolean check_image_c(integer);
-boolean check_image_i(integer);
-boolean is_pdf_image(integer);
-boolean is_png_image(integer);
-image_dict *new_image_dict(void);
+typedef image_dict *idict_entry;
+idict_entry *idict_array;
+
+void new_img_pdfstream_struct(image_dict *);
image *new_image(void);
-integer epdf_orig_x(integer i);
-integer epdf_orig_y(integer i);
-integer epdf_xsize(integer i);
-integer epdf_ysize(integer i);
-integer image_colordepth(integer img);
-integer image_depth(integer);
-integer image_height(integer);
-integer image_index(integer);
-integer image_objnum(integer);
-integer image_pages(integer);
-integer image_width(integer);
-integer img_to_array(image *);
-integer read_image(integer, integer, str_number, integer, str_number,
- str_number, integer, integer, integer, integer);
+/*void init_image_dict(image_dict *);*/
+image_dict *new_image_dict(void);
+void free_image_dict(image_dict * p);
+void read_img(PDF, image_dict *, int, int);
+void scan_pdfximage(PDF pdf);
+void scan_pdfrefximage(PDF pdf);
+scaled_whd tex_scale(scaled_whd nat, scaled_whd tex);
+scaled_whd scale_img(image_dict *, scaled_whd, int);
+void write_img(PDF, image_dict *);
+void pdf_write_image(PDF pdf, int n);
void check_pdfstream_dict(image_dict *);
+void write_pdfstream(PDF, image_dict *);
+void idict_to_array(image_dict *);
void dumpimagemeta(void);
-void free_image_dict(image_dict * p);
-void init_image_dict(image_dict *);
-void init_image(image *);
-void new_img_pdfstream_struct(image_dict *);
-void out_image(integer, scaled, scaled);
-void pdf_print_resname_prefix(void);
-void read_img(image_dict *, integer, integer);
-void scale_image(integer);
-void scale_img(image *);
-void set_image_dimensions(integer, integer, integer, integer);
-void undumpimagemeta(integer, integer);
-void update_image_procset(integer);
-void write_image(integer);
-void write_img(image_dict *);
-void write_pdfstream(image_dict *);
+void undumpimagemeta(PDF, int, int);
+scaled_whd scan_alt_rule(void);
#endif /* WRITEIMG_H */
diff --git a/Build/source/texk/web2c/luatexdir/image/writeimg.w b/Build/source/texk/web2c/luatexdir/image/writeimg.w
new file mode 100644
index 00000000000..a6b03ee4290
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/image/writeimg.w
@@ -0,0 +1,823 @@
+% writeimg.w
+
+% Copyright 1996-2006 Han The Thanh <thanh@@pdftex.org>
+% Copyright 2006-2010 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/>.
+
+@* Image inclusion.
+
+@ @c
+static const char _svn_version[] =
+ "$Id: writeimg.w 3584 2010-04-02 17:45:55Z hhenkel $ "
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/image/writeimg.w $";
+
+#include <assert.h>
+#include "ptexlib.h"
+#include <kpathsea/c-auto.h>
+#include <kpathsea/c-memstr.h>
+
+@ @c
+#include "image/image.h"
+#include "image/writejpg.h"
+#include "image/writepng.h"
+#include "image/writejbig2.h"
+
+#include "lua51/lua.h" /* for |LUA_NOREF| */
+#include "lua51/lauxlib.h"
+
+@ @c
+#define pdf_image_resolution int_par(pdf_image_resolution_code)
+#define pdf_pagebox int_par(pdf_pagebox_code)
+
+@* Patch ImageTypeDetection 2003/02/08 by Heiko Oberdiek.
+
+ Function |readimage| performs some basic initializations.
+ Then it looks at the file extension to determine the
+ image type and calls specific code/functions.
+
+ The main disadvantage is that standard file extensions
+ have to be used, otherwise pdfTeX is not able to detect
+ the correct image type.
+
+ The patch now looks at the file header first regardless of
+ the file extension. This is implemented in function
+ |check_type_by_header|. If this check fails, the traditional
+ test of standard file extension is tried, done in function
+ |check_type_by_extension|.
+
+ Magic headers:
+
+ * "PNG (Portable Network Graphics) Specification", Version 1.2
+ (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"|
+
+ * "JPEG File Interchange Format", Version 1.02:
+
+ o you can identify a JFIF file by looking for the following
+ sequence: X'FF', SOI X'FF', APP0, <2 bytes to be skipped>,
+ "JFIF", X'00'.
+
+ Function |check_type_by_header| only looks at the first two bytes:
+ |"\xFF\xD8"|
+
+ * ISO/IEC JTC 1/SC 29/WG 1
+ (ITU-T SG8)
+ Coding of Still Pictures
+ Title: 14492 FCD
+ Source: JBIG Committee
+ Project: JTC 1.29.10
+ Status: Final Committee Draft
+
+ D.4.1, ID string
+
+ This is an 8-byte sequence containing 0x97 0x4A 0x42 0x32 0x0D 0x0A
+ 0x1A 0x0A.
+
+ * "PDF Reference", third edition:
+
+ * The first line should contain "\%PDF-1.0" until "\%PDF-1.4"
+ (section 3.4.1 "File Header").
+ * The "implementation notes" say:
+
+ 3.4.1, File Header
+ 12. Acrobat viewers require only that the header appear
+ somewhere within the first 1024 bytes of the file.
+ 13. Acrobat viewers will also accept a header of the form
+ \%!PS-Adobe-N.n PDF-M.m
+
+ The check in function |check_type_by_header| only implements
+ the first issue. The implementation notes are not considered.
+ Therefore files with garbage at start of file must have the
+ standard extension.
+
+ Functions |check_type_by_header| and |check_type_by_extension|:
+ |img_type(img)| is set to |IMG_TYPE_NONE| by |new_image_dict()|.
+ Both functions try to detect a type and set |img_type(img)|.
+ Thus a value other than |IMG_TYPE_NONE| indicates that a
+ type has been found.
+
+@c
+#define HEADER_JPG "\xFF\xD8"
+#define HEADER_PNG "\x89PNG\r\n\x1A\n"
+#define HEADER_JBIG2 "\x97\x4A\x42\x32\x0D\x0A\x1A\x0A"
+#define HEADER_PDF "%PDF-1."
+#define MAX_HEADER (sizeof(HEADER_PNG)-1)
+
+static void check_type_by_header(image_dict * idict)
+{
+ int i;
+ FILE *file = NULL;
+ char header[MAX_HEADER];
+
+ assert(idict != NULL);
+ if (img_type(idict) != IMG_TYPE_NONE) /* nothing to do */
+ return;
+ /* read the header */
+ file = xfopen(img_filepath(idict), FOPEN_RBIN_MODE);
+ for (i = 0; (unsigned) i < MAX_HEADER; i++) {
+ header[i] = (char) xgetc(file);
+ if (feof(file))
+ pdftex_fail("reading image file failed");
+ }
+ xfclose(file, img_filepath(idict));
+ /* tests */
+ if (strncmp(header, HEADER_JPG, sizeof(HEADER_JPG) - 1) == 0)
+ img_type(idict) = IMG_TYPE_JPG;
+ else if (strncmp(header, HEADER_PNG, sizeof(HEADER_PNG) - 1) == 0)
+ img_type(idict) = IMG_TYPE_PNG;
+ else if (strncmp(header, HEADER_JBIG2, sizeof(HEADER_JBIG2) - 1) == 0)
+ img_type(idict) = IMG_TYPE_JBIG2;
+ else if (strncmp(header, HEADER_PDF, sizeof(HEADER_PDF) - 1) == 0)
+ img_type(idict) = IMG_TYPE_PDF;
+}
+
+@ @c
+static void check_type_by_extension(image_dict * idict)
+{
+ char *image_suffix;
+
+ assert(idict != NULL);
+ if (img_type(idict) != IMG_TYPE_NONE) /* nothing to do */
+ return;
+ /* tests */
+ if ((image_suffix = strrchr(img_filename(idict), '.')) == 0)
+ img_type(idict) = IMG_TYPE_NONE;
+ else if (strcasecmp(image_suffix, ".png") == 0)
+ img_type(idict) = IMG_TYPE_PNG;
+ else if (strcasecmp(image_suffix, ".jpg") == 0 ||
+ strcasecmp(image_suffix, ".jpeg") == 0)
+ img_type(idict) = IMG_TYPE_JPG;
+ else if (strcasecmp(image_suffix, ".jbig2") == 0 ||
+ strcasecmp(image_suffix, ".jb2") == 0)
+ img_type(idict) = IMG_TYPE_JBIG2;
+ else if (strcasecmp(image_suffix, ".pdf") == 0)
+ img_type(idict) = IMG_TYPE_PDF;
+}
+
+@ @c
+void new_img_pdfstream_struct(image_dict * p)
+{
+ assert(p != NULL);
+ assert(img_pdfstream_ptr(p) == NULL);
+ img_pdfstream_ptr(p) = xtalloc(1, pdf_stream_struct);
+ img_pdfstream_stream(p) = NULL;
+}
+
+@ @c
+static void init_image(image * p)
+{
+ assert(p != NULL);
+ set_wd_running(p);
+ set_ht_running(p);
+ set_dp_running(p);
+ img_transform(p) = 0;
+ img_dict(p) = NULL;
+ img_dictref(p) = LUA_NOREF;
+}
+
+@ @c
+image *new_image(void)
+{
+ image *p = xtalloc(1, image);
+ init_image(p);
+ return p;
+}
+
+@ @c
+static void init_image_dict(image_dict * p)
+{
+ assert(p != NULL);
+ memset(p, 0, sizeof(image_dict));
+ set_wd_running(p);
+ set_ht_running(p);
+ set_dp_running(p);
+ img_transform(p) = 0;
+ img_pagenum(p) = 1;
+ img_type(p) = IMG_TYPE_NONE;
+ img_pagebox(p) = PDF_BOX_SPEC_MEDIA;
+ img_unset_bbox(p);
+ img_unset_group(p);
+ img_state(p) = DICT_NEW;
+ img_index(p) = -1; /* -1 = unused, used count from 0 */
+}
+
+@ @c
+image_dict *new_image_dict(void)
+{
+ image_dict *p = xtalloc(1, image_dict);
+ init_image_dict(p);
+ return p;
+}
+
+@ @c
+static void free_dict_strings(image_dict * p)
+{
+ xfree(img_filename(p));
+ xfree(img_filepath(p));
+ xfree(img_attr(p));
+ xfree(img_pagename(p));
+}
+
+@ @c
+void free_image_dict(image_dict * p)
+{
+ if (ini_version)
+ return; /* The image may be \.{\\dump}ed to a format */
+ /* called from limglib.c */
+ assert(img_state(p) < DICT_REFERED);
+ switch (img_type(p)) {
+ case IMG_TYPE_PDF:
+ unrefPdfDocument(img_filepath(p));
+ break;
+ case IMG_TYPE_PNG: /* assuming |IMG_CLOSEINBETWEEN| */
+ assert(img_png_ptr(p) == NULL);
+ break;
+ case IMG_TYPE_JPG: /* assuming |IMG_CLOSEINBETWEEN| */
+ assert(img_jpg_ptr(p) == NULL);
+ break;
+ case IMG_TYPE_JBIG2: /* todo: writejbig2.w cleanup */
+ break;
+ case IMG_TYPE_PDFSTREAM:
+ if (img_pdfstream_ptr(p) != NULL) {
+ xfree(img_pdfstream_stream(p));
+ xfree(img_pdfstream_ptr(p));
+ }
+ break;
+ case IMG_TYPE_NONE:
+ break;
+ default:
+ assert(0);
+ }
+ free_dict_strings(p);
+ assert(img_file(p) == NULL);
+ xfree(p);
+}
+
+@ @c
+void read_img(PDF pdf,
+ image_dict * idict, int minor_version, int inclusion_errorlevel)
+{
+ char *filepath;
+ int callback_id;
+ assert(idict != NULL);
+ if (img_filename(idict) == NULL)
+ pdftex_fail("image file name missing");
+ callback_id = callback_defined(find_image_file_callback);
+ if (img_filepath(idict) == NULL) {
+ if (callback_id > 0
+ && run_callback(callback_id, "S->S", img_filename(idict),
+ &filepath)) {
+ if (filepath && (strlen(filepath) > 0))
+ img_filepath(idict) = strdup(filepath);
+ } else
+ img_filepath(idict) =
+ kpse_find_file(img_filename(idict), kpse_tex_format, true);
+ if (img_filepath(idict) == NULL)
+ pdftex_fail("cannot find image file");
+ }
+ recorder_record_input(img_filename(idict));
+ /* type checks */
+ check_type_by_header(idict);
+ check_type_by_extension(idict);
+ /* read image */
+ switch (img_type(idict)) {
+ case IMG_TYPE_PDF:
+ assert(pdf != NULL); /* TODO! */
+ read_pdf_info(idict, minor_version, inclusion_errorlevel,
+ IMG_CLOSEINBETWEEN);
+ break;
+ case IMG_TYPE_PNG:
+ read_png_info(pdf, idict, IMG_CLOSEINBETWEEN);
+ break;
+ case IMG_TYPE_JPG:
+ read_jpg_info(pdf, idict, IMG_CLOSEINBETWEEN);
+ break;
+ case IMG_TYPE_JBIG2:
+ if (minor_version < 4) {
+ pdftex_fail
+ ("JBIG2 images only possible with at least PDF 1.4; you are generating PDF 1.%i",
+ (int) minor_version);
+ }
+ read_jbig2_info(idict);
+ break;
+ default:
+ pdftex_fail("internal error: unknown image type (2)");
+ }
+ cur_file_name = NULL;
+ if (img_state(idict) < DICT_FILESCANNED)
+ img_state(idict) = DICT_FILESCANNED;
+}
+
+@ @c
+static image_dict *read_image(PDF pdf, char *file_name, int page_num,
+ char *page_name, int colorspace,
+ int page_box, int minor_version,
+ int inclusion_errorlevel)
+{
+ image *a = new_image();
+ image_dict *idict = img_dict(a) = new_image_dict();
+ incr(pdf->ximage_count);
+ pdf_create_obj(pdf, obj_type_ximage, pdf->ximage_count);
+ img_objnum(idict) = pdf->obj_ptr;
+ img_index(idict) = pdf->ximage_count;
+ set_obj_data_ptr(pdf, img_objnum(idict), img_index(idict));
+ idict_to_array(idict);
+ img_colorspace(idict) = colorspace;
+ img_pagenum(idict) = page_num;
+ img_pagename(idict) = page_name;
+ assert(file_name != NULL);
+ cur_file_name = file_name;
+ img_filename(idict) = file_name;
+ img_pagebox(idict) = page_box;
+ read_img(pdf, idict, minor_version, inclusion_errorlevel);
+ return idict;
+}
+
+@ scans PDF pagebox specification
+@c
+static pdfboxspec_e scan_pdf_box_spec(void)
+{
+ if (scan_keyword("mediabox"))
+ return PDF_BOX_SPEC_MEDIA;
+ else if (scan_keyword("cropbox"))
+ return PDF_BOX_SPEC_CROP;
+ else if (scan_keyword("bleedbox"))
+ return PDF_BOX_SPEC_BLEED;
+ else if (scan_keyword("trimbox"))
+ return PDF_BOX_SPEC_TRIM;
+ else if (scan_keyword("artbox"))
+ return PDF_BOX_SPEC_ART;
+ return PDF_BOX_SPEC_NONE;
+}
+
+@ @c
+void scan_pdfximage(PDF pdf)
+{
+ scaled_whd alt_rule;
+ image_dict *idict;
+ int transform = 0, page = 1, pagebox, colorspace = 0;
+ char *named = NULL, *attr = NULL, *file_name = NULL;
+ alt_rule = scan_alt_rule(); /* scans |<rule spec>| to |alt_rule| */
+ if (scan_keyword("attr")) {
+ scan_pdf_ext_toks();
+ attr = tokenlist_to_cstring(def_ref, true, NULL);
+ delete_token_ref(def_ref);
+ }
+ if (scan_keyword("named")) {
+ scan_pdf_ext_toks();
+ named = tokenlist_to_cstring(def_ref, true, NULL);
+ delete_token_ref(def_ref);
+ page = 0;
+ } else if (scan_keyword("page")) {
+ scan_int();
+ page = cur_val;
+ }
+ if (scan_keyword("colorspace")) {
+ scan_int();
+ colorspace = cur_val;
+ }
+ pagebox = scan_pdf_box_spec();
+ if (pagebox == PDF_BOX_SPEC_NONE) {
+ pagebox = pdf_pagebox;
+ if (pagebox == PDF_BOX_SPEC_NONE)
+ pagebox = PDF_BOX_SPEC_CROP;
+ }
+ scan_pdf_ext_toks();
+ file_name = tokenlist_to_cstring(def_ref, true, NULL);
+ assert(file_name != NULL);
+ delete_token_ref(def_ref);
+ idict =
+ read_image(pdf, file_name, page, named, colorspace, pagebox,
+ pdf_minor_version, pdf_inclusion_errorlevel);
+ img_attr(idict) = attr;
+ img_dimen(idict) = alt_rule;
+ img_transform(idict) = transform;
+ pdf_last_ximage = img_objnum(idict);
+ pdf_last_ximage_pages = img_totalpages(idict);
+ pdf_last_ximage_colordepth = img_colordepth(idict);
+}
+
+@ @c
+#define tail cur_list.tail_field
+
+void scan_pdfrefximage(PDF pdf)
+{
+ int transform = 0; /* one could scan transform as well */
+ image_dict *idict;
+ scaled_whd alt_rule, dim;
+ alt_rule = scan_alt_rule(); /* scans |<rule spec>| to |alt_rule| */
+ scan_int();
+ check_obj_exists(pdf, obj_type_ximage, cur_val);
+ new_whatsit(pdf_refximage_node);
+ idict = idict_array[obj_data_ptr(pdf, cur_val)];
+ if (alt_rule.wd != null_flag || alt_rule.ht != null_flag
+ || alt_rule.dp != null_flag)
+ dim = scale_img(idict, alt_rule, transform);
+ else
+ dim = scale_img(idict, img_dimen(idict), img_transform(idict));
+ width(tail) = dim.wd;
+ height(tail) = dim.ht;
+ depth(tail) = dim.dp;
+ pdf_ximage_transform(tail) = transform;
+ pdf_ximage_index(tail) = img_index(idict);
+}
+
+@ |tex_scale()| sequence of decisions:
+
+{\obeylines\obeyspaces\tt
+wd ht dp : res = tex;
+wd ht --
+wd -- dp
+wd -- --
+-- ht dp
+-- ht --
+-- -- dp
+-- -- -- : res = nat;
+}
+
+@c
+scaled_whd tex_scale(scaled_whd nat, scaled_whd tex)
+{
+ scaled_whd res;
+ if (!is_running(tex.wd) && !is_running(tex.ht) && !is_running(tex.dp)) {
+ /* width, height, and depth specified */
+ res = tex;
+ } else /* max. 2 dimensions are specified */ if (!is_running(tex.wd)) {
+ res.wd = tex.wd;
+ if (!is_running(tex.ht)) {
+ res.ht = tex.ht;
+ /* width and height specified */
+ res.dp = ext_xn_over_d(tex.ht, nat.dp, nat.ht);
+ } else if (!is_running(tex.dp)) {
+ res.dp = tex.dp;
+ /* width and depth specified */
+ res.ht = ext_xn_over_d(tex.wd, nat.ht + nat.dp, nat.wd) - tex.dp;
+ } else {
+ /* only width specified */
+ res.ht = ext_xn_over_d(tex.wd, nat.ht, nat.wd);
+ res.dp = ext_xn_over_d(tex.wd, nat.dp, nat.wd);
+ }
+ } else if (!is_running(tex.ht)) {
+ res.ht = tex.ht;
+ if (!is_running(tex.dp)) {
+ res.dp = tex.dp;
+ /* height and depth specified */
+ res.wd = ext_xn_over_d(tex.ht + tex.dp, nat.wd, nat.ht + nat.dp);
+ } else {
+ /* only height specified */
+ res.wd = ext_xn_over_d(tex.ht, nat.wd, nat.ht);
+ res.dp = ext_xn_over_d(tex.ht, nat.dp, nat.ht);
+ }
+ } else if (!is_running(tex.dp)) {
+ res.dp = tex.dp;
+ /* only depth specified */
+ res.ht = nat.ht - (tex.dp - nat.dp);
+ res.wd = nat.wd;
+ } else {
+ /* nothing specified */
+ res = nat;
+ }
+ return res;
+}
+
+@ Within |scale_img()| only image width and height matter;
+the offsets and positioning are not interesting here.
+But one needs rotation info to swap width and height.
+|img_rotation()| comes from the optional /Rotate key in the PDF file.
+
+@c
+scaled_whd scale_img(image_dict * idict, scaled_whd alt_rule, int transform)
+{
+ int x, y, xr, yr, tmp; /* size and resolution of image */
+ scaled_whd nat; /* natural size corresponding to image resolution */
+ int default_res;
+ assert(idict != NULL);
+ if ((img_type(idict) == IMG_TYPE_PDF
+ || img_type(idict) == IMG_TYPE_PDFSTREAM) && img_is_bbox(idict)) {
+ x = img_xsize(idict) = img_bbox(idict)[2] - img_bbox(idict)[0]; /* dimensions from image.bbox */
+ y = img_ysize(idict) = img_bbox(idict)[3] - img_bbox(idict)[1];
+ img_xorig(idict) = img_bbox(idict)[0];
+ img_yorig(idict) = img_bbox(idict)[1];
+ } else {
+ x = img_xsize(idict); /* dimensions, resolutions from image file */
+ y = img_ysize(idict);
+ }
+ xr = img_xres(idict);
+ yr = img_yres(idict);
+ if (x <= 0 || y <= 0 || xr < 0 || yr < 0)
+ pdftex_fail("ext1: invalid image dimensions");
+ if (xr > 65535 || yr > 65535) {
+ xr = 0;
+ yr = 0;
+ pdftex_warn("ext1: too large image resolution ignored");
+ }
+ if (((transform - img_rotation(idict)) & 1) == 1) {
+ tmp = x;
+ x = y;
+ y = tmp;
+ tmp = xr;
+ xr = yr;
+ yr = tmp;
+ }
+ nat.dp = 0; /* always for images */
+ if (img_type(idict) == IMG_TYPE_PDF
+ || img_type(idict) == IMG_TYPE_PDFSTREAM) {
+ nat.wd = x;
+ nat.ht = y;
+ } else {
+ default_res = fix_int(pdf_image_resolution, 0, 65535);
+ if (default_res > 0 && (xr == 0 || yr == 0)) {
+ xr = default_res;
+ yr = default_res;
+ }
+ if (xr > 0 && yr > 0) {
+ nat.wd = ext_xn_over_d(one_hundred_inch, x, 100 * xr);
+ nat.ht = ext_xn_over_d(one_hundred_inch, y, 100 * yr);
+ } else {
+ nat.wd = ext_xn_over_d(one_hundred_inch, x, 7200);
+ nat.ht = ext_xn_over_d(one_hundred_inch, y, 7200);
+ }
+ }
+ return tex_scale(nat, alt_rule);
+}
+
+@ @c
+void write_img(PDF pdf, image_dict * idict)
+{
+ assert(idict != NULL);
+ if (img_state(idict) < DICT_WRITTEN) {
+ if (tracefilenames)
+ tex_printf(" <%s", img_filepath(idict));
+ switch (img_type(idict)) {
+ case IMG_TYPE_PNG:
+ write_png(pdf, idict);
+ break;
+ case IMG_TYPE_JPG:
+ write_jpg(pdf, idict);
+ break;
+ case IMG_TYPE_JBIG2:
+ write_jbig2(pdf, idict);
+ break;
+ case IMG_TYPE_PDF:
+ write_epdf(pdf, idict);
+ break;
+ case IMG_TYPE_PDFSTREAM:
+ write_pdfstream(pdf, idict);
+ break;
+ default:
+ pdftex_fail("internal error: unknown image type (1)");
+ }
+ if (tracefilenames)
+ tex_printf(">");
+ if (img_type(idict) == IMG_TYPE_PNG) {
+ write_additional_png_objects(pdf);
+ }
+ }
+ if (img_state(idict) < DICT_WRITTEN)
+ img_state(idict) = DICT_WRITTEN;
+}
+
+@ write an image
+@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)]);
+}
+
+@ @c
+void check_pdfstream_dict(image_dict * idict)
+{
+ if (!img_is_bbox(idict))
+ pdftex_fail("image.stream: no bbox given");
+ if (img_state(idict) < DICT_FILESCANNED)
+ img_state(idict) = DICT_FILESCANNED;
+}
+
+@ @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");
+ 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_begin_stream(pdf);
+ if (img_pdfstream_stream(idict) != NULL)
+ pdf_puts(pdf, img_pdfstream_stream(idict));
+ pdf_end_stream(pdf);
+}
+
+@ @c
+/* define |idict_ptr|, |idict_array|, and |idict_limit| */
+idict_entry *idict_ptr, *idict_array = NULL;
+size_t idict_limit;
+
+void idict_to_array(image_dict * idict)
+{
+ assert(idict != NULL);
+ if (idict_ptr - idict_array == 0) { /* align to count from 1 */
+ alloc_array(idict, 1, SMALL_BUF_SIZE); /* /Im0 unused */
+ idict_ptr++;
+ }
+ alloc_array(idict, 1, SMALL_BUF_SIZE);
+ *idict_ptr = idict;
+ assert(img_index(idict) == idict_ptr - idict_array);
+ idict_ptr++;
+}
+
+
+@ To allow the use of \.{\\pdfrefximage} inside saved boxes in -ini mode,
+the information in the array has to be (un)dumped with the format.
+The next two routines take care of that.
+
+Most of the work involved in setting up the images is simply
+executed again. This solves the many possible errors resulting from
+the split in two separate runs.
+
+There was only one problem remaining: The pdfversion and
+pdfinclusionerrorlevel can have changed inbetween the call to
+|readimage()| and dump time. That is why they are passed as arguments
+to undumpimagemeta once more.
+
+some of the dumped values are really type int, not integer,
+but since the macro falls back to |generic_dump| anyway, that
+does not matter.
+
+@c
+#define dumpinteger generic_dump
+#define undumpinteger generic_undump
+
+@ (un)dumping a string means dumping the allocation size, followed
+ by the bytes. The trailing \.{\\0} is dumped as well, because that
+ makes the code simpler.
+
+@c
+#define dumpcharptr(a) \
+ do { \
+ int x; \
+ if (a!=NULL) { \
+ x = (int)strlen(a)+1; \
+ dumpinteger(x); dump_things(*a, x); \
+ } else { \
+ x = 0; dumpinteger(x); \
+ } \
+ } while (0)
+
+#define undumpcharptr(s) \
+ do { \
+ int x; \
+ char *a; \
+ undumpinteger (x); \
+ if (x>0) { \
+ a = xmalloc((unsigned)x); \
+ undump_things(*a,x); \
+ s = a ; \
+ } else { s = NULL; } \
+ } while (0)
+
+@ @c
+void dumpimagemeta(void)
+{
+ int cur_index, i;
+ image_dict *idict;
+
+ i = (int) idict_limit;
+ dumpinteger(i);
+ cur_index = (int) (idict_ptr - idict_array);
+ dumpinteger(cur_index);
+
+ for (i = 1; i < cur_index; i++) {
+ idict = idict_array[i];
+ assert(idict != NULL);
+ dumpcharptr(img_filename(idict));
+ dumpinteger(img_type(idict));
+ dumpinteger(img_procset(idict));
+ dumpinteger(img_xsize(idict));
+ dumpinteger(img_ysize(idict));
+ dumpinteger(img_xres(idict));
+ dumpinteger(img_yres(idict));
+ dumpinteger(img_totalpages(idict));
+ dumpinteger(img_colorspace(idict));
+
+ /* the |image_struct| is not dumped at all, except for a few
+ variables that are needed to restore the contents */
+
+ if (img_type(idict) == IMG_TYPE_PDF) {
+ dumpinteger(img_pagebox(idict));
+ dumpinteger(img_pagenum(idict));
+ } else if (img_type(idict) == IMG_TYPE_JBIG2) {
+ dumpinteger(img_pagenum(idict));
+ }
+
+ }
+}
+
+@ @c
+void undumpimagemeta(PDF pdf, int pdfversion, int pdfinclusionerrorlevel)
+{
+ int cur_index, i;
+ image_dict *idict;
+
+ assert(pdf != NULL);
+ undumpinteger(i);
+ idict_limit = (size_t) i;
+
+ idict_array = xtalloc(idict_limit, idict_entry);
+ undumpinteger(cur_index);
+ idict_ptr = idict_array + cur_index;
+
+ for (i = 1; i < cur_index; i++) {
+ idict = new_image_dict();
+ assert(idict != NULL);
+ assert(img_index(idict) == -1);
+ idict_to_array(idict);
+ undumpcharptr(img_filename(idict));
+ undumpinteger(img_type(idict));
+ undumpinteger(img_procset(idict));
+ undumpinteger(img_xsize(idict));
+ undumpinteger(img_ysize(idict));
+ undumpinteger(img_xres(idict));
+ undumpinteger(img_yres(idict));
+ undumpinteger(img_totalpages(idict));
+ undumpinteger(img_colorspace(idict));
+
+ switch (img_type(idict)) {
+ case IMG_TYPE_PDF:
+ undumpinteger(img_pagebox(idict));
+ undumpinteger(img_pagenum(idict));
+ break;
+ case IMG_TYPE_PNG:
+ break;
+ case IMG_TYPE_JPG:
+ break;
+ case IMG_TYPE_JBIG2:
+ if (pdfversion < 4) {
+ pdftex_fail
+ ("JBIG2 images only possible with at least PDF 1.4; you are generating PDF 1.%i",
+ (int) pdfversion);
+ }
+ undumpinteger(img_pagenum(idict));
+ break;
+ default:
+ pdftex_fail("unknown type of image");
+ }
+ read_img(pdf, idict, pdfversion, pdfinclusionerrorlevel);
+ }
+}
+
+@ scans rule spec to |alt_rule|
+@c
+scaled_whd scan_alt_rule(void)
+{
+ 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;
+ }
+ return alt_rule;
+}
diff --git a/Build/source/texk/web2c/luatexdir/image/writejbig2.h b/Build/source/texk/web2c/luatexdir/image/writejbig2.h
index f28e91281fe..a5715d5732e 100644
--- a/Build/source/texk/web2c/luatexdir/image/writejbig2.h
+++ b/Build/source/texk/web2c/luatexdir/image/writejbig2.h
@@ -18,15 +18,15 @@
You should have received a copy of the GNU General Public License along
with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-/* $Id: writejbig2.h 2327 2009-04-18 12:47:21Z hhenkel $ */
+/* $Id: writejbig2.h 2579 2009-06-23 14:12:23Z taco $ */
#ifndef WRITEJBIG2_H
# define WRITEJBIG2_H
# include "image.h"
-void flush_jbig2_page0_objects(void);
+void flush_jbig2_page0_objects(PDF);
void read_jbig2_info(image_dict *);
-void write_jbig2(image_dict *);
+void write_jbig2(PDF, image_dict *);
#endif /* WRITEJBIG"_H */
diff --git a/Build/source/texk/web2c/luatexdir/image/writejbig2.c b/Build/source/texk/web2c/luatexdir/image/writejbig2.w
index c22c27e11b6..936ae29c6bd 100644
--- a/Build/source/texk/web2c/luatexdir/image/writejbig2.c
+++ b/Build/source/texk/web2c/luatexdir/image/writejbig2.w
@@ -1,24 +1,24 @@
-/* writejbig2.c
+% writejbig2.w
- Copyright 1996-2006 Han The Thanh <thanh@pdftex.org>
- Copyright 2006-2009 Taco Hoekwater <taco@luatex.org>
+% Copyright 1996-2006 Han The Thanh <thanh@@pdftex.org>
+% Copyright 2006-2009 Taco Hoekwater <taco@@luatex.org>
- This file is part of LuaTeX.
+% 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 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.
+% 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/>. */
+% You should have received a copy of the GNU General Public License along
+% with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
-/***********************************************************************
+@
This is experimental JBIG2 image support to pdfTeX. JBIG2 image decoding
is part of Adobe PDF-1.4, and requires Acroread 5.0 or later.
@@ -40,21 +40,21 @@ http://partners.adobe.com/public/developer/en/pdf/PDFReference16.pdf
News
====
-31 May 2006: no need to wait for endoffileflag in sequential access
+31 May 2006: no need to wait for |endoffileflag| in sequential access
organization.
-10 May 2006: ygetc() for some catching of broken JBIG2 files; modify to
+10 May 2006: |ygetc()| for some catching of broken JBIG2 files; modify to
accept Example 3.4 from PDFRef 5th ed. with short end-of-file segment.
-09 May 2006: pages_maketree() and segments_maketree() by AVL tree,
+09 May 2006: |pages_maketree()| and |segments_maketree()| by AVL tree,
some cleaning up.
-06 May 2006: File list replaced by AVL tree; new_fileinfo(),
-new_pageinfo().
+06 May 2006: File list replaced by AVL tree; |new_fileinfo()|,
+|new_pageinfo()|.
04 May 2006: Updated for pdftex-1.40-beta-20060213.
-08 Jan. 2003: Added flushjbig2page0objects() function. Now at the end
+08 Jan. 2003: Added |flushjbig2page0objects()| function. Now at the end
of the pdfTeX run all pending page0 objects are written out.
08 Jan. 2003: Release on private webpage.
@@ -78,11 +78,10 @@ object exists, reference it. Else create fresh one.
09 Dec. 2002: JBIG2 seg. page numbers > 0 are now set to 1, see PDF Ref.
-***********************************************************************/
-
+@ @c
static const char _svn_version[] =
- "$Id: writejbig2.c 2315 2009-04-17 23:34:42Z hhenkel $ "
- "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/image/writejbig2.c $";
+ "$Id: writejbig2.w 3584 2010-04-02 17:45:55Z hhenkel $ "
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/image/writejbig2.w $";
#undef DEBUG
@@ -90,11 +89,9 @@ static const char _svn_version[] =
#include <stdio.h>
#include <assert.h>
#include "ptexlib.h"
-#include "ptexmac.h"
-#include "image.h"
-
-/**********************************************************************/
+#include "image/image.h"
+@ @c
/* 7.3 Segment types */
#define M_SymbolDictionary 0
#define M_IntermediateTextRegion 4
@@ -118,8 +115,7 @@ static const char _svn_version[] =
#define M_Tables 53
#define M_Extension 62
-/**********************************************************************/
-
+@ @c
typedef enum { INITIAL, HAVEINFO, WRITEPDF } PHASE;
typedef struct _LITEM {
@@ -177,13 +173,12 @@ typedef struct _FILEINFO {
unsigned int filehdrflags; /* set by readfilehdr() */
boolean sequentialaccess; /* set by readfilehdr() */
unsigned long numofpages; /* set by readfilehdr() */
- unsigned long streamstart; /* set by get_jbig2_info() */
+ unsigned long streamstart; /* set by |get_jbig2_info()| */
unsigned long pdfpage0objnum;
PHASE phase;
} FILEINFO;
-/**********************************************************************/
-
+@ @c
static struct avl_table *file_tree = NULL;
static int comp_file_entry(const void *pa, const void *pb, void *p)
@@ -196,17 +191,18 @@ static int comp_file_entry(const void *pa, const void *pb, void *p)
static int comp_page_entry(const void *pa, const void *pb, void *p)
{
(void) p;
- return ((const PAGEINFO *) pa)->pagenum - ((const PAGEINFO *) pb)->pagenum;
+ return (int) (((const PAGEINFO *) pa)->pagenum -
+ ((const PAGEINFO *) pb)->pagenum);
}
static int comp_segment_entry(const void *pa, const void *pb, void *p)
{
(void) p;
- return ((const SEGINFO *) pa)->segnum - ((const SEGINFO *) pb)->segnum;
+ return (int) (((const SEGINFO *) pa)->segnum -
+ ((const SEGINFO *) pb)->segnum);
}
-/**********************************************************************/
-
+@ @c
static int ygetc(FILE * stream)
{
int c = getc(stream);
@@ -219,8 +215,7 @@ static int ygetc(FILE * stream)
return c;
}
-/**********************************************************************/
-
+@ @c
static void initlinkedlist(LIST * lp)
{
lp->first = NULL;
@@ -245,8 +240,7 @@ static LIST *litem_append(LIST * lp)
return lp;
}
-/**********************************************************************/
-
+@ @c
static FILEINFO *new_fileinfo(void)
{
FILEINFO *fip;
@@ -265,6 +259,7 @@ static FILEINFO *new_fileinfo(void)
return fip;
}
+@ @c
static PAGEINFO *new_pageinfo(void)
{
PAGEINFO *pip;
@@ -281,6 +276,7 @@ static PAGEINFO *new_pageinfo(void)
return pip;
}
+@ @c
static void init_seginfo(SEGINFO * sip)
{
sip->segnum = 0;
@@ -304,8 +300,7 @@ static void init_seginfo(SEGINFO * sip)
sip->endoffileflag = false;
}
-/**********************************************************************/
-
+@ @c
static void pages_maketree(LIST * plp)
{
LITEM *ip;
@@ -319,6 +314,7 @@ static void pages_maketree(LIST * plp)
}
}
+@ @c
static void segments_maketree(LIST * slp)
{
LITEM *ip;
@@ -332,8 +328,7 @@ static void segments_maketree(LIST * slp)
}
}
-/**********************************************************************/
-
+@ @c
static PAGEINFO *find_pageinfo(LIST * plp, unsigned long pagenum)
{
PAGEINFO tmp;
@@ -342,6 +337,7 @@ static PAGEINFO *find_pageinfo(LIST * plp, unsigned long pagenum)
return (PAGEINFO *) avl_find(plp->tree, &tmp);
}
+@ @c
static SEGINFO *find_seginfo(LIST * slp, unsigned long segnum)
{
SEGINFO tmp;
@@ -350,22 +346,21 @@ static SEGINFO *find_seginfo(LIST * slp, unsigned long segnum)
return (SEGINFO *) avl_find(slp->tree, &tmp);
}
-/**********************************************************************/
-
+@ @c
static unsigned int read2bytes(FILE * f)
{
- unsigned int c = ygetc(f);
- return (c << 8) + ygetc(f);
+ unsigned int c = (unsigned int) ygetc(f);
+ return (c << 8) + (unsigned int) ygetc(f);
}
+@ @c
static unsigned long read4bytes(FILE * f)
{
unsigned int l = read2bytes(f);
return (l << 16) + read2bytes(f);
}
-/**********************************************************************/
-
+@ @c
static unsigned long getstreamlen(LITEM * slip, boolean refer)
{
SEGINFO *sip;
@@ -378,8 +373,7 @@ static unsigned long getstreamlen(LITEM * slip, boolean refer)
return len;
}
-/**********************************************************************/
-
+@ @c
static void readfilehdr(FILEINFO * fip)
{
unsigned int i;
@@ -392,7 +386,7 @@ static void readfilehdr(FILEINFO * fip)
pdftex_fail
("readfilehdr(): reading JBIG2 image file failed: ID string missing");
/* Annex D.4.2 File header flags */
- fip->filehdrflags = ygetc(fip->file);
+ fip->filehdrflags = (unsigned int) ygetc(fip->file);
fip->sequentialaccess = (fip->filehdrflags & 0x01) ? true : false;
if (fip->sequentialaccess) { /* Annex D.1 vs. Annex D.2 */
xfseek(fip->file, 0, SEEK_END, fip->filepath);
@@ -405,8 +399,7 @@ static void readfilehdr(FILEINFO * fip)
/* --- at end of file header --- */
}
-/**********************************************************************/
-
+@ @c
static void checkseghdrflags(SEGINFO * sip)
{
sip->endofstripeflag = false;
@@ -453,9 +446,9 @@ 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;
@@ -471,7 +464,7 @@ static boolean readseghdr(FILEINFO * fip, SEGINFO * sip)
printf(" segnum %d\n", sip->segnum);
#endif
/* 7.2.3 Segment header flags */
- sip->seghdrflags = ygetc(fip->file);
+ sip->seghdrflags = (unsigned int) ygetc(fip->file);
#ifdef DEBUG
printf(" hdrflags %d\n", sip->seghdrflags & 0x3f);
#endif
@@ -510,18 +503,17 @@ static boolean readseghdr(FILEINFO * fip, SEGINFO * sip)
}
/* 7.2.6 Segment page association */
if (sip->pageassocsizeflag)
- sip->segpage = read4bytes(fip->file);
+ sip->segpage = (long int) read4bytes(fip->file);
else
sip->segpage = ygetc(fip->file);
/* 7.2.7 Segment data length */
sip->segdatalen = read4bytes(fip->file);
- sip->hdrend = (long) xftello(fip->file, fip->filepath);
+ sip->hdrend = (unsigned long) xftello(fip->file, fip->filepath);
/* ---- at end of segment header ---- */
return true;
}
-/**********************************************************************/
-
+@ @c
static void checkseghdr(FILEINFO * fip, SEGINFO * sip);
static void markpage0seg(FILEINFO * fip, unsigned long referedseg)
@@ -537,10 +529,10 @@ 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
-static void writeseghdr(FILEINFO * fip, SEGINFO * sip)
+@c
+static void writeseghdr(PDF pdf, FILEINFO * fip, SEGINFO * sip)
{
unsigned int i;
unsigned long referedseg = 0;
@@ -548,25 +540,25 @@ static void writeseghdr(FILEINFO * fip, SEGINFO * sip)
/* 7.2.3 Segment header flags */
/* 7.2.4 Referred-to segment count and retention flags */
for (i = 0; i < 5 + sip->fieldlen; i++)
- pdfout(ygetc(fip->file));
+ pdf_out(pdf, ygetc(fip->file));
/* 7.2.5 Referred-to segment numbers */
for (i = 0; i < sip->countofrefered; i++) {
switch (sip->segnumwidth) {
case 1:
- referedseg = ygetc(fip->file);
- pdfout(referedseg);
+ referedseg = (unsigned long) ygetc(fip->file);
+ pdf_out(pdf, referedseg);
break;
case 2:
referedseg = read2bytes(fip->file);
- pdfout((referedseg >> 8) & 0xff);
- pdfout(referedseg & 0xff);
+ pdf_out(pdf, (referedseg >> 8) & 0xff);
+ pdf_out(pdf, referedseg & 0xff);
break;
case 4:
referedseg = read4bytes(fip->file);
- pdfout((referedseg >> 24) & 0xff);
- pdfout((referedseg >> 16) & 0xff);
- pdfout((referedseg >> 8) & 0xff);
- pdfout(referedseg & 0xff);
+ pdf_out(pdf, (referedseg >> 24) & 0xff);
+ pdf_out(pdf, (referedseg >> 16) & 0xff);
+ pdf_out(pdf, (referedseg >> 8) & 0xff);
+ pdf_out(pdf, referedseg & 0xff);
break;
}
if (fip->page0.last != NULL && !sip->refers)
@@ -578,19 +570,18 @@ static void writeseghdr(FILEINFO * fip, SEGINFO * sip)
if (sip->pageassocsizeflag)
for (i = 0; i < 3; i++) {
(void) ygetc(fip->file);
- pdfout(0);
+ pdf_out(pdf, 0);
}
(void) ygetc(fip->file);
- pdfout((sip->segpage > 0) ? 1 : 0);
+ pdf_out(pdf, (unsigned char) ((sip->segpage > 0) ? 1 : 0));
/* 7.2.7 Segment data length */
for (i = 0; i < 4; i++)
- pdfout(ygetc(fip->file));
+ pdf_out(pdf, ygetc(fip->file));
/* ---- 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)
{
unsigned int i;
@@ -603,7 +594,7 @@ static void checkseghdr(FILEINFO * fip, SEGINFO * sip)
for (i = 0; i < sip->countofrefered; i++) {
switch (sip->segnumwidth) {
case 1:
- referedseg = ygetc(fip->file);
+ referedseg = (unsigned long) ygetc(fip->file);
break;
case 2:
referedseg = read2bytes(fip->file);
@@ -626,8 +617,7 @@ static void checkseghdr(FILEINFO * fip, SEGINFO * sip)
/* ---- at end of segment header ---- */
}
-/**********************************************************************/
-
+@ @c
static unsigned long findstreamstart(FILEINFO * fip)
{
SEGINFO tmp;
@@ -640,8 +630,7 @@ static unsigned long findstreamstart(FILEINFO * fip)
return fip->streamstart;
}
-/**********************************************************************/
-
+@ @c
static void rd_jbig2_info(FILEINFO * fip)
{
unsigned long seekdist = 0; /* for sequential-access only */
@@ -667,7 +656,7 @@ static void rd_jbig2_info(FILEINFO * fip)
if (sip->segpage > (int) currentpage) {
plp = litem_append(&(fip->pages));
plp->last->d = new_pageinfo();
- currentpage = sip->segpage;
+ currentpage = (unsigned long) sip->segpage;
}
pip = fip->pages.last->d;
} else {
@@ -689,31 +678,31 @@ 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);
+ 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 = sip->segpage;
- pip->width = read4bytes(fip->file);
- pip->height = read4bytes(fip->file);
- pip->xres = read4bytes(fip->file);
- pip->yres = read4bytes(fip->file);
- pip->pagesegmentflags = ygetc(fip->file);
+ pip->pagenum = (unsigned long) sip->segpage;
+ pip->width = (unsigned) read4bytes(fip->file);
+ pip->height = (unsigned) read4bytes(fip->file);
+ pip->xres = (unsigned) read4bytes(fip->file);
+ pip->yres = (unsigned) read4bytes(fip->file);
+ pip->pagesegmentflags = (unsigned) ygetc(fip->file);
/* 7.4.8.6 Page striping information */
pip->stripinginfo = read2bytes(fip->file);
seekdist -= 19;
}
if (sip->endofstripeflag) {
- pip->stripedheight = read4bytes(fip->file);
+ pip->stripedheight = (unsigned) read4bytes(fip->file);
seekdist -= 4;
}
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;
}
@@ -723,9 +712,8 @@ static void rd_jbig2_info(FILEINFO * fip)
xfclose(fip->file, fip->filepath);
}
-/**********************************************************************/
-
-static void wr_jbig2(FILEINFO * fip, unsigned long page)
+@ @c
+static void wr_jbig2(PDF pdf, FILEINFO * fip, unsigned long page)
{
LITEM *slip;
PAGEINFO *pip;
@@ -734,47 +722,48 @@ static void wr_jbig2(FILEINFO * fip, unsigned long page)
if (page > 0) {
pip = find_pageinfo(&(fip->pages), page);
assert(pip != NULL);
- pdf_puts("/Type /XObject\n/Subtype /Image\n");
- pdf_printf("/Width %i\n", pip->width);
- pdf_printf("/Height %i\n", pip->height);
- pdf_puts("/ColorSpace /DeviceGray\n");
- pdf_puts("/BitsPerComponent 1\n");
- pdf_printf("/Length %lu\n", getstreamlen(pip->segments.first, true));
- pdf_puts("/Filter [/JBIG2Decode]\n");
+ 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 %lu\n",
+ getstreamlen(pip->segments.first, true));
+ pdf_puts(pdf, "/Filter [/JBIG2Decode]\n");
if (fip->page0.last != NULL) {
if (fip->pdfpage0objnum == 0) {
- pdf_create_obj(0, 0);
- fip->pdfpage0objnum = obj_ptr;
+ pdf_create_obj(pdf, obj_type_others, 0);
+ fip->pdfpage0objnum = (unsigned long) pdf->obj_ptr;
}
- pdf_printf("/DecodeParms [<< /JBIG2Globals %lu 0 R >>]\n",
+ pdf_printf(pdf, "/DecodeParms [<< /JBIG2Globals %lu 0 R >>]\n",
fip->pdfpage0objnum);
}
} else {
pip = find_pageinfo(&(fip->page0), page);
assert(pip != NULL);
- pdf_begin_dict(fip->pdfpage0objnum, 0);
- pdf_printf("/Length %lu\n", getstreamlen(pip->segments.first, false));
+ pdf_begin_dict(pdf, (int) fip->pdfpage0objnum, 0);
+ pdf_printf(pdf, "/Length %lu\n",
+ getstreamlen(pip->segments.first, false));
}
- pdf_puts(">>\n");
- pdf_puts("stream\n");
+ pdf_puts(pdf, ">>\n");
+ pdf_puts(pdf, "stream\n");
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(fip, sip);
- xfseeko(fip->file, sip->datastart, SEEK_SET, fip->filepath);
+ writeseghdr(pdf, fip, sip);
+ xfseeko(fip->file, (off_t) sip->datastart, SEEK_SET, fip->filepath);
for (i = sip->datastart; i < sip->dataend; i++)
- pdfout(ygetc(fip->file));
+ pdf_out(pdf, ygetc(fip->file));
}
}
- pdf_end_stream();
+ pdf_end_stream(pdf);
xfclose(fip->file, fip->filepath);
}
-/**********************************************************************/
-
+@ @c
void read_jbig2_info(image_dict * idict)
{
FILEINFO *fip, tmp;
@@ -807,19 +796,20 @@ void read_jbig2_info(image_dict * idict)
segments_maketree(&(pip->segments));
}
}
- pip = find_pageinfo(&(fip->pages), img_pagenum(idict));
+ pip = find_pageinfo(&(fip->pages), (unsigned long) img_pagenum(idict));
if (pip == NULL)
pdftex_fail("read_jbig2_info(): page %d not found in JBIG2 image file",
(int) img_pagenum(idict));
- img_totalpages(idict) = fip->numofpages;
- img_xsize(idict) = pip->width;
- img_ysize(idict) = pip->height;
+ img_totalpages(idict) = (int) fip->numofpages;
+ img_xsize(idict) = (int) pip->width;
+ img_ysize(idict) = (int) pip->height;
img_xres(idict) = (int) (pip->xres * 0.0254 + 0.5);
img_yres(idict) = (int) (pip->yres * 0.0254 + 0.5);
img_colordepth(idict) = 1;
}
-void write_jbig2(image_dict * idict)
+@ @c
+void write_jbig2(PDF pdf, image_dict * idict)
{
FILEINFO *fip, tmp;
PAGEINFO *pip;
@@ -828,14 +818,15 @@ void write_jbig2(image_dict * idict)
tmp.filepath = img_filepath(idict);
fip = (FILEINFO *) avl_find(file_tree, &tmp);
assert(fip != NULL);
- assert(fip->phase == HAVEINFO); /* don't write before rd_jbig2_info() call */
- pip = find_pageinfo(&(fip->pages), img_pagenum(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(fip, pip->pagenum);
+ wr_jbig2(pdf, fip, pip->pagenum);
img_file(idict) = NULL;
}
-void flush_jbig2_page0_objects(void)
+@ @c
+void flush_jbig2_page0_objects(PDF pdf)
{
FILEINFO *fip;
struct avl_traverser t;
@@ -844,9 +835,7 @@ void flush_jbig2_page0_objects(void)
for (fip = avl_t_first(&t, file_tree); fip != NULL;
fip = avl_t_next(&t)) {
if (fip->page0.last != NULL)
- wr_jbig2(fip, 0);
+ wr_jbig2(pdf, fip, 0);
}
}
}
-
-/**********************************************************************/
diff --git a/Build/source/texk/web2c/luatexdir/image/writejpg.h b/Build/source/texk/web2c/luatexdir/image/writejpg.h
index bd497c9e114..d3c7cdb806a 100644
--- a/Build/source/texk/web2c/luatexdir/image/writejpg.h
+++ b/Build/source/texk/web2c/luatexdir/image/writejpg.h
@@ -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: writejpg.h 2327 2009-04-18 12:47:21Z hhenkel $ */
+/* $Id: writejpg.h 2653 2009-06-27 14:30:05Z taco $ */
#ifndef WRITEJPG_H
# define WRITEJPG_H
# include "image.h"
-void read_jpg_info(image_dict *, img_readtype_e);
-void write_jpg(image_dict *);
+void read_jpg_info(PDF, image_dict *, img_readtype_e);
+void write_jpg(PDF, image_dict *);
#endif /* WRITEJPG_H */
diff --git a/Build/source/texk/web2c/luatexdir/image/writejpg.c b/Build/source/texk/web2c/luatexdir/image/writejpg.w
index 187c55ea6c2..cb0e2fedcde 100644
--- a/Build/source/texk/web2c/luatexdir/image/writejpg.c
+++ b/Build/source/texk/web2c/luatexdir/image/writejpg.w
@@ -1,32 +1,33 @@
-/* writejpg.c
+% writejpg.w
- Copyright 1996-2006 Han The Thanh <thanh@pdftex.org>
- Copyright 2006-2009 Taco Hoekwater <taco@luatex.org>
+% Copyright 1996-2006 Han The Thanh <thanh@@pdftex.org>
+% Copyright 2006-2010 Taco Hoekwater <taco@@luatex.org>
- This file is part of LuaTeX.
+% 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 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.
+% 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/>. */
+% 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: writejpg.w 3584 2010-04-02 17:45:55Z hhenkel $ "
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/image/writejpg.w $";
#include <assert.h>
#include "ptexlib.h"
-#include "image.h"
-#include "writejpg.h"
-
-static const char _svn_version[] =
- "$Id: writejpg.c 2320 2009-04-18 08:52:30Z hhenkel $ "
- "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/image/writejpg.c $";
+#include "image/image.h"
+@ @c
#define JPG_GRAY 1 /* Gray color space, use /DeviceGray */
#define JPG_RGB 3 /* RGB color space, use /DeviceRGB */
#define JPG_CMYK 4 /* CMYK color space, use /DeviceCMYK */
@@ -98,12 +99,14 @@ typedef enum { /* JPEG marker codes */
M_ERROR = 0x100 /* dummy marker, internal use only */
} JPEG_MARKER;
+@ @c
static JPG_UINT16 read2bytes(FILE * f)
{
int c = xgetc(f);
- return (c << 8) + xgetc(f);
+ return (JPG_UINT16) ((c << 8) + (int) xgetc(f));
}
+@ @c
static void close_and_cleanup_jpg(image_dict * idict)
{
assert(idict != NULL);
@@ -116,7 +119,8 @@ static void close_and_cleanup_jpg(image_dict * idict)
img_jpg_ptr(idict) = NULL;
}
-void read_jpg_info(image_dict * idict, img_readtype_e readtype)
+@ @c
+void read_jpg_info(PDF pdf, image_dict * idict, img_readtype_e readtype)
{
int i, units = 0;
unsigned char jpg_id[] = "JFIF";
@@ -134,7 +138,7 @@ void read_jpg_info(image_dict * idict, img_readtype_e readtype)
xfseek(img_file(idict), 0, SEEK_SET, img_filepath(idict));
if (read2bytes(img_file(idict)) != 0xFFD8)
pdftex_fail("reading JPEG image failed (no JPEG header found)");
- /* currently only true JFIF files allow extracting img_xres and img_yres */
+ /* currently only true JFIF files allow extracting |img_xres| and |img_yres| */
if (read2bytes(img_file(idict)) == 0xFFE0) { /* check for JFIF */
(void) read2bytes(img_file(idict));
for (i = 0; i < 5; i++) {
@@ -144,20 +148,27 @@ void read_jpg_info(image_dict * idict, img_readtype_e readtype)
if (i == 5) { /* it's JFIF */
read2bytes(img_file(idict));
units = xgetc(img_file(idict));
- img_xres(idict) = read2bytes(img_file(idict));
- img_yres(idict) = read2bytes(img_file(idict));
+ img_xres(idict) = (int) read2bytes(img_file(idict));
+ img_yres(idict) = (int) read2bytes(img_file(idict));
switch (units) {
case 1:
break; /* pixels per inch */
case 2:
- img_xres(idict) *= 2.54;
- img_yres(idict) *= 2.54;
+ img_xres(idict) = (int) ((double) img_xres(idict) * 2.54);
+ img_yres(idict) = (int) ((double) img_yres(idict) * 2.54);
break; /* pixels per cm */
default:
img_xres(idict) = img_yres(idict) = 0;
break;
}
}
+ /* if either xres or yres is 0 but the other isn't, set it to the value of the other */
+ if ((img_xres(idict) == 0) && (img_yres(idict) != 0)) {
+ img_xres(idict) = img_yres(idict);
+ }
+ if ((img_yres(idict) == 0) && (img_xres(idict) != 0)) {
+ img_yres(idict) = img_xres(idict);
+ }
}
xfseek(img_file(idict), 0, SEEK_SET, img_filepath(idict));
while (1) {
@@ -177,26 +188,26 @@ void read_jpg_info(image_dict * idict, img_readtype_e readtype)
case M_SOF15:
pdftex_fail("unsupported type of compression");
case M_SOF2:
- if (fixed_pdf_minor_version <= 2)
+ if (pdf->minor_version <= 2)
pdftex_fail("cannot use progressive DCT with PDF-1.2");
case M_SOF0:
case M_SOF1:
case M_SOF3:
(void) read2bytes(img_file(idict)); /* read segment length */
img_colordepth(idict) = xgetc(img_file(idict));
- img_ysize(idict) = read2bytes(img_file(idict));
- img_xsize(idict) = read2bytes(img_file(idict));
+ img_ysize(idict) = (int) read2bytes(img_file(idict));
+ img_xsize(idict) = (int) read2bytes(img_file(idict));
img_jpg_color(idict) = xgetc(img_file(idict));
xfseek(img_file(idict), 0, SEEK_SET, img_filepath(idict));
switch (img_jpg_color(idict)) {
case JPG_GRAY:
- img_color(idict) = IMAGE_COLOR_B;
+ img_procset(idict) |= PROCSET_IMAGE_B;
break;
case JPG_RGB:
- img_color(idict) = IMAGE_COLOR_C;
+ img_procset(idict) |= PROCSET_IMAGE_C;
break;
case JPG_CMYK:
- img_color(idict) = IMAGE_COLOR_C;
+ img_procset(idict) |= PROCSET_IMAGE_C;
break;
default:
pdftex_fail("Unsupported color space %i",
@@ -226,56 +237,58 @@ void read_jpg_info(image_dict * idict, img_readtype_e readtype)
assert(0);
}
-static void reopen_jpg(image_dict * idict)
+@ @c
+static void reopen_jpg(PDF pdf, image_dict * idict)
{
- integer width, height, xres, yres;
+ int width, height, xres, yres;
width = img_xsize(idict);
height = img_ysize(idict);
xres = img_xres(idict);
yres = img_yres(idict);
- read_jpg_info(idict, IMG_KEEPOPEN);
+ read_jpg_info(pdf, idict, IMG_KEEPOPEN);
if (width != img_xsize(idict) || height != img_ysize(idict)
|| xres != img_xres(idict) || yres != img_yres(idict))
pdftex_fail("writejpg: image dimensions have changed");
}
-void write_jpg(image_dict * idict)
+@ @c
+void write_jpg(PDF pdf, image_dict * idict)
{
long unsigned l;
FILE *f;
assert(idict != NULL);
if (img_file(idict) == NULL)
- reopen_jpg(idict);
+ reopen_jpg(pdf, idict);
assert(img_jpg_ptr(idict) != NULL);
- pdf_puts("/Type /XObject\n/Subtype /Image\n");
+ pdf_puts(pdf, "/Type /XObject\n/Subtype /Image\n");
if (img_attr(idict) != NULL && strlen(img_attr(idict)) > 0)
- pdf_printf("%s\n", img_attr(idict));
- pdf_printf("/Width %i\n/Height %i\n/BitsPerComponent %i\n/Length %i\n",
+ 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("/ColorSpace ");
+ pdf_puts(pdf, "/ColorSpace ");
if (img_colorspace(idict) != 0) {
- pdf_printf("%i 0 R\n", (int) img_colorspace(idict));
+ pdf_printf(pdf, "%i 0 R\n", (int) img_colorspace(idict));
} else {
switch (img_jpg_color(idict)) {
case JPG_GRAY:
- pdf_puts("/DeviceGray\n");
+ pdf_puts(pdf, "/DeviceGray\n");
break;
case JPG_RGB:
- pdf_puts("/DeviceRGB\n");
+ pdf_puts(pdf, "/DeviceRGB\n");
break;
case JPG_CMYK:
- pdf_puts("/DeviceCMYK\n/Decode [1 0 1 0 1 0 1 0]\n");
+ pdf_puts(pdf, "/DeviceCMYK\n/Decode [1 0 1 0 1 0 1 0]\n");
break;
default:
pdftex_fail("Unsupported color space %i",
(int) img_jpg_color(idict));
}
}
- pdf_puts("/Filter /DCTDecode\n>>\nstream\n");
+ pdf_puts(pdf, "/Filter /DCTDecode\n>>\nstream\n");
for (l = img_jpg_ptr(idict)->length, f = img_file(idict); l > 0; l--)
- pdfout(xgetc(f));
- pdf_end_stream();
+ pdf_out(pdf, xgetc(f));
+ pdf_end_stream(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 4683e694a0c..56a96436389 100644
--- a/Build/source/texk/web2c/luatexdir/image/writepng.h
+++ b/Build/source/texk/web2c/luatexdir/image/writepng.h
@@ -18,15 +18,15 @@
You should have received a copy of the GNU General Public License along
with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-/* $Id: writepng.h 2327 2009-04-18 12:47:21Z hhenkel $ */
+/* $Id: writepng.h 2580 2009-06-23 15:55:52Z taco $ */
#ifndef WRITEPNG_H
# define WRITEPNG_H
# include "image.h"
-void read_png_info(image_dict *, img_readtype_e);
-void write_additional_png_objects(void);
-void write_png(image_dict *);
+void read_png_info(PDF, image_dict *, img_readtype_e);
+void write_additional_png_objects(PDF);
+void write_png(PDF, image_dict *);
#endif /* WRITEPNG_H */
diff --git a/Build/source/texk/web2c/luatexdir/image/writepng.c b/Build/source/texk/web2c/luatexdir/image/writepng.w
index 154a8a351c2..1b8ecb56b49 100644
--- a/Build/source/texk/web2c/luatexdir/image/writepng.c
+++ b/Build/source/texk/web2c/luatexdir/image/writepng.w
@@ -1,32 +1,33 @@
-/* writepng.c
+% writepng.w
- Copyright 1996-2006 Han The Thanh <thanh@pdftex.org>
- Copyright 2006-2009 Taco Hoekwater <taco@luatex.org>
+% Copyright 1996-2006 Han The Thanh <thanh@@pdftex.org>
+% Copyright 2006-2010 Taco Hoekwater <taco@@luatex.org>
- This file is part of LuaTeX.
+% 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 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.
+% 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/>. */
+% 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: writepng.w 3584 2010-04-02 17:45:55Z hhenkel $ "
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/image/writepng.w $";
#include <assert.h>
#include "ptexlib.h"
-#include "image.h"
-#include "writepng.h"
-
-static const char _svn_version[] =
- "$Id: writepng.c 2317 2009-04-18 00:12:18Z hhenkel $ "
- "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.40.6/source/texk/web2c/luatexdir/image/writepng.c $";
+#include "image/image.h"
+@ @c
static int transparent_page_group = -1;
static void close_and_cleanup_png(image_dict * idict)
@@ -43,7 +44,8 @@ static void close_and_cleanup_png(image_dict * idict)
img_png_ptr(idict) = NULL;
}
-void read_png_info(image_dict * idict, img_readtype_e readtype)
+@ @c
+void read_png_info(PDF pdf, image_dict * idict, img_readtype_e readtype)
{
double gamma;
png_structp png_p;
@@ -73,43 +75,43 @@ void read_png_info(image_dict * idict, img_readtype_e readtype)
png_set_tRNS_to_alpha(png_p);
}
/* alpha channel support */
- if (fixed_pdf_minor_version < 4 && png_p->color_type | PNG_COLOR_MASK_ALPHA)
+ if (pdf->minor_version < 4 && png_p->color_type | PNG_COLOR_MASK_ALPHA)
png_set_strip_alpha(png_p);
/* 16bit depth support */
- if (fixed_pdf_minor_version < 5)
- fixed_image_hicolor = 0;
- if (info_p->bit_depth == 16 && !fixed_image_hicolor)
+ if (pdf->minor_version < 5)
+ pdf->image_hicolor = 0;
+ if ((info_p->bit_depth == 16) && (pdf->image_hicolor == 0))
png_set_strip_16(png_p);
/* gamma support */
- if (fixed_image_apply_gamma) {
+ if (pdf->image_apply_gamma) {
if (png_get_gAMA(png_p, info_p, &gamma))
- png_set_gamma(png_p, (fixed_gamma / 1000.0), gamma);
+ png_set_gamma(png_p, (pdf->gamma / 1000.0), gamma);
else
- png_set_gamma(png_p, (fixed_gamma / 1000.0),
- (1000.0 / fixed_image_gamma));
+ png_set_gamma(png_p, (pdf->gamma / 1000.0),
+ (1000.0 / pdf->image_gamma));
}
/* reset structure */
png_read_update_info(png_p, info_p);
/* resolution support */
- img_xsize(idict) = info_p->width;
- img_ysize(idict) = info_p->height;
+ img_xsize(idict) = (int) info_p->width;
+ img_ysize(idict) = (int) info_p->height;
if (info_p->valid & PNG_INFO_pHYs) {
img_xres(idict) =
- round(0.0254 * png_get_x_pixels_per_meter(png_p, info_p));
+ round(0.0254 * (double) png_get_x_pixels_per_meter(png_p, info_p));
img_yres(idict) =
- round(0.0254 * png_get_y_pixels_per_meter(png_p, info_p));
+ round(0.0254 * (double) png_get_y_pixels_per_meter(png_p, info_p));
}
switch (info_p->color_type) {
case PNG_COLOR_TYPE_PALETTE:
- img_color(idict) = IMAGE_COLOR_C | IMAGE_COLOR_I;
+ img_procset(idict) |= PROCSET_IMAGE_C | PROCSET_IMAGE_I;
break;
case PNG_COLOR_TYPE_GRAY:
case PNG_COLOR_TYPE_GRAY_ALPHA:
- img_color(idict) = IMAGE_COLOR_B;
+ img_procset(idict) |= PROCSET_IMAGE_B;
break;
case PNG_COLOR_TYPE_RGB:
case PNG_COLOR_TYPE_RGB_ALPHA:
- img_color(idict) = IMAGE_COLOR_C;
+ img_procset(idict) |= PROCSET_IMAGE_C;
break;
default:
pdftex_fail("unsupported type of color_type <%i>", info_p->color_type);
@@ -119,32 +121,33 @@ void read_png_info(image_dict * idict, img_readtype_e readtype)
close_and_cleanup_png(idict);
}
+@ @c
#define write_gray_pixel_16(r) \
- if (j % 4 == 0||j % 4 == 1) pdf_buf[pdf_ptr++] = *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_buf[pdf_ptr++] = *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_buf[pdf_ptr++] = *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_buf[pdf_ptr++] = *r++; \
+ if (j % 4 != 3) pdf_quick_out(pdf,*r++); \
else smask[smask_ptr++] = *r++
-#define write_simple_pixel(r) pdf_buf[pdf_ptr++] = *r++
+#define write_simple_pixel(r) pdf_quick_out(pdf,*r++)
#define write_noninterlaced(outmac) \
for (i = 0; i < (int)info_p->height; i++) { \
png_read_row(png_p, row, NULL); \
r = row; \
- k = info_p->rowbytes; \
+ k = (int)info_p->rowbytes; \
while(k > 0) { \
- l = (k > pdf_buf_size)? pdf_buf_size : k; \
- pdfroom(l); \
+ l = (k > pdf->buf_size)? pdf->buf_size : k; \
+ pdf_room(pdf,l); \
for (j = 0; j < l; j++) { \
outmac; \
} \
@@ -155,10 +158,10 @@ void read_png_info(image_dict * idict, img_readtype_e readtype)
#define write_interlaced(outmac) \
for (i = 0; i < (int)info_p->height; i++) { \
row = rows[i]; \
- k = info_p->rowbytes; \
+ k = (int)info_p->rowbytes; \
while(k > 0) { \
- l = (k > pdf_buf_size)? pdf_buf_size : k;\
- pdfroom(l); \
+ l = (k > pdf->buf_size)?pdf->buf_size: k;\
+ pdf_room(pdf,l); \
for (j = 0; j < l; j++) { \
outmac; \
} \
@@ -167,22 +170,23 @@ void read_png_info(image_dict * idict, img_readtype_e readtype)
xfree(rows[i]); \
}
-static void write_png_palette(image_dict * idict)
+@ @c
+static void write_png_palette(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;
- integer palette_objnum = 0;
+ int palette_objnum = 0;
if (img_colorspace(idict) != 0) {
- pdf_printf("%i 0 R\n", (int) img_colorspace(idict));
+ pdf_printf(pdf, "%i 0 R\n", (int) img_colorspace(idict));
} else {
- pdf_create_obj(0, 0);
- palette_objnum = obj_ptr;
- pdf_printf("[/Indexed /DeviceRGB %i %i 0 R]\n",
+ pdf_create_obj(pdf, obj_type_others, 0);
+ palette_objnum = pdf->obj_ptr;
+ pdf_printf(pdf, "[/Indexed /DeviceRGB %i %i 0 R]\n",
(int) (info_p->num_palette - 1), (int) palette_objnum);
}
- pdf_begin_stream();
+ pdf_begin_stream(pdf);
if (info_p->interlace_type == PNG_INTERLACE_NONE) {
row = xtalloc(info_p->rowbytes, png_byte);
write_noninterlaced(write_simple_pixel(r));
@@ -198,32 +202,33 @@ static void write_png_palette(image_dict * idict)
write_interlaced(write_simple_pixel(row));
xfree(rows);
}
- pdf_end_stream();
+ pdf_end_stream(pdf);
if (palette_objnum > 0) {
- pdf_begin_dict(palette_objnum, 0);
- pdf_begin_stream();
+ pdf_begin_dict(pdf, palette_objnum, 0);
+ pdf_begin_stream(pdf);
for (i = 0; (unsigned) i < info_p->num_palette; i++) {
- pdfroom(3);
- pdf_buf[pdf_ptr++] = info_p->palette[i].red;
- pdf_buf[pdf_ptr++] = info_p->palette[i].green;
- pdf_buf[pdf_ptr++] = info_p->palette[i].blue;
+ pdf_room(pdf, 3);
+ pdf_quick_out(pdf, info_p->palette[i].red);
+ pdf_quick_out(pdf, info_p->palette[i].green);
+ pdf_quick_out(pdf, info_p->palette[i].blue);
}
- pdf_end_stream();
+ pdf_end_stream(pdf);
}
}
-static void write_png_gray(image_dict * idict)
+@ @c
+static void write_png_gray(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("%i 0 R\n", (int) img_colorspace(idict));
+ pdf_printf(pdf, "%i 0 R\n", (int) img_colorspace(idict));
} else {
- pdf_puts("/DeviceGray\n");
+ pdf_puts(pdf, "/DeviceGray\n");
}
- pdf_begin_stream();
+ pdf_begin_stream(pdf);
if (info_p->interlace_type == PNG_INTERLACE_NONE) {
row = xtalloc(info_p->rowbytes, png_byte);
write_noninterlaced(write_simple_pixel(r));
@@ -239,34 +244,35 @@ static void write_png_gray(image_dict * idict)
write_interlaced(write_simple_pixel(row));
xfree(rows);
}
- pdf_end_stream();
+ pdf_end_stream(pdf);
}
-static void write_png_gray_alpha(image_dict * idict)
+@ @c
+static void write_png_gray_alpha(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;
- integer smask_objnum = 0;
+ int smask_objnum = 0;
png_bytep smask;
- integer smask_ptr = 0;
- integer smask_size = 0;
+ int smask_ptr = 0;
+ int smask_size = 0;
int bitdepth;
if (img_colorspace(idict) != 0) {
- pdf_printf("%i 0 R\n", (int) img_colorspace(idict));
+ pdf_printf(pdf, "%i 0 R\n", (int) img_colorspace(idict));
} else {
- pdf_puts("/DeviceGray\n");
+ pdf_puts(pdf, "/DeviceGray\n");
}
- pdf_create_obj(0, 0);
- smask_objnum = obj_ptr;
- pdf_printf("/SMask %i 0 R\n", (int) smask_objnum);
- smask_size = (info_p->rowbytes / 2) * info_p->height;
- smask = xtalloc(smask_size, png_byte);
- pdf_begin_stream();
+ pdf_create_obj(pdf, obj_type_others, 0);
+ smask_objnum = pdf->obj_ptr;
+ pdf_printf(pdf, "/SMask %i 0 R\n", (int) smask_objnum);
+ smask_size = (int) ((info_p->rowbytes / 2) * info_p->height);
+ smask = xtalloc((unsigned) smask_size, png_byte);
+ pdf_begin_stream(pdf);
if (info_p->interlace_type == PNG_INTERLACE_NONE) {
row = xtalloc(info_p->rowbytes, png_byte);
- if ((info_p->bit_depth == 16) && fixed_image_hicolor) {
+ if ((info_p->bit_depth == 16) && (pdf->image_hicolor != 0)) {
write_noninterlaced(write_gray_pixel_16(r));
} else {
write_noninterlaced(write_gray_pixel_8(r));
@@ -280,49 +286,50 @@ static void write_png_gray_alpha(image_dict * idict)
for (i = 0; (unsigned) i < info_p->height; i++)
rows[i] = xtalloc(info_p->rowbytes, png_byte);
png_read_image(png_p, rows);
- if ((info_p->bit_depth == 16) && fixed_image_hicolor) {
+ if ((info_p->bit_depth == 16) && (pdf->image_hicolor != 0)) {
write_interlaced(write_gray_pixel_16(row));
} else {
write_interlaced(write_gray_pixel_8(row));
}
xfree(rows);
}
- pdf_end_stream();
- pdf_flush();
+ pdf_end_stream(pdf);
+ pdf_flush(pdf);
/* now write the Smask object */
bitdepth = (int) info_p->bit_depth;
- pdf_begin_dict(smask_objnum, 0);
- pdf_puts("/Type /XObject\n/Subtype /Image\n");
+ 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("%s\n", img_attr(idict));
- pdf_printf("/Width %i\n/Height %i\n/BitsPerComponent %i\n",
+ pdf_printf(pdf, "%s\n", img_attr(idict));
+ pdf_printf(pdf, "/Width %i\n/Height %i\n/BitsPerComponent %i\n",
(int) info_p->width,
(int) info_p->height, (bitdepth == 16 ? 8 : bitdepth));
- pdf_puts("/ColorSpace /DeviceGray\n");
- pdf_begin_stream();
+ pdf_puts(pdf, "/ColorSpace /DeviceGray\n");
+ pdf_begin_stream(pdf);
for (i = 0; i < smask_size; i++) {
if (i % 8 == 0)
- pdfroom(8);
- pdf_buf[pdf_ptr++] = smask[i];
+ pdf_room(pdf, 8);
+ pdf_quick_out(pdf, smask[i]);
if (bitdepth == 16)
i++;
}
- pdf_end_stream();
+ pdf_end_stream(pdf);
xfree(smask);
}
-static void write_png_rgb(image_dict * idict)
+@ @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("%i 0 R\n", (int) img_colorspace(idict));
+ pdf_printf(pdf, "%i 0 R\n", (int) img_colorspace(idict));
} else {
- pdf_puts("/DeviceRGB\n");
+ pdf_puts(pdf, "/DeviceRGB\n");
}
- pdf_begin_stream();
+ pdf_begin_stream(pdf);
if (info_p->interlace_type == PNG_INTERLACE_NONE) {
row = xtalloc(info_p->rowbytes, png_byte);
write_noninterlaced(write_simple_pixel(r));
@@ -338,34 +345,35 @@ static void write_png_rgb(image_dict * idict)
write_interlaced(write_simple_pixel(row));
xfree(rows);
}
- pdf_end_stream();
+ pdf_end_stream(pdf);
}
-static void write_png_rgb_alpha(image_dict * idict)
+@ @c
+static void write_png_rgb_alpha(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;
- integer smask_objnum = 0;
+ int smask_objnum = 0;
png_bytep smask;
- integer smask_ptr = 0;
- integer smask_size = 0;
+ int smask_ptr = 0;
+ int smask_size = 0;
int bitdepth;
if (img_colorspace(idict) != 0) {
- pdf_printf("%i 0 R\n", (int) img_colorspace(idict));
+ pdf_printf(pdf, "%i 0 R\n", (int) img_colorspace(idict));
} else {
- pdf_puts("/DeviceRGB\n");
+ pdf_puts(pdf, "/DeviceRGB\n");
}
- pdf_create_obj(0, 0);
- smask_objnum = obj_ptr;
- pdf_printf("/SMask %i 0 R\n", (int) smask_objnum);
- smask_size = (info_p->rowbytes / 2) * info_p->height;
- smask = xtalloc(smask_size, png_byte);
- pdf_begin_stream();
+ pdf_create_obj(pdf, obj_type_others, 0);
+ smask_objnum = pdf->obj_ptr;
+ pdf_printf(pdf, "/SMask %i 0 R\n", (int) smask_objnum);
+ smask_size = (int) ((info_p->rowbytes / 2) * info_p->height);
+ smask = xtalloc((unsigned) smask_size, png_byte);
+ pdf_begin_stream(pdf);
if (info_p->interlace_type == PNG_INTERLACE_NONE) {
row = xtalloc(info_p->rowbytes, png_byte);
- if ((info_p->bit_depth == 16) && fixed_image_hicolor) {
+ if ((info_p->bit_depth == 16) && (pdf->image_hicolor != 0)) {
write_noninterlaced(write_rgb_pixel_16(r));
} else {
write_noninterlaced(write_rgb_pixel_8(r));
@@ -379,51 +387,50 @@ static void write_png_rgb_alpha(image_dict * idict)
for (i = 0; (unsigned) i < info_p->height; i++)
rows[i] = xtalloc(info_p->rowbytes, png_byte);
png_read_image(png_p, rows);
- if ((info_p->bit_depth == 16) && fixed_image_hicolor) {
+ if ((info_p->bit_depth == 16) && (pdf->image_hicolor != 0)) {
write_interlaced(write_rgb_pixel_16(row));
} else {
write_interlaced(write_rgb_pixel_8(row));
}
xfree(rows);
}
- pdf_end_stream();
- pdf_flush();
+ pdf_end_stream(pdf);
+ pdf_flush(pdf);
/* now write the Smask object */
if (smask_objnum > 0) {
bitdepth = (int) info_p->bit_depth;
- pdf_begin_dict(smask_objnum, 0);
- pdf_puts("/Type /XObject\n/Subtype /Image\n");
+ 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("%s\n", img_attr(idict));
- pdf_printf("/Width %i\n/Height %i\n/BitsPerComponent %i\n",
+ pdf_printf(pdf, "%s\n", img_attr(idict));
+ pdf_printf(pdf, "/Width %i\n/Height %i\n/BitsPerComponent %i\n",
(int) info_p->width,
(int) info_p->height, (bitdepth == 16 ? 8 : bitdepth));
- pdf_puts("/ColorSpace /DeviceGray\n");
- pdf_begin_stream();
+ pdf_puts(pdf, "/ColorSpace /DeviceGray\n");
+ pdf_begin_stream(pdf);
for (i = 0; i < smask_size; i++) {
if (i % 8 == 0)
- pdfroom(8);
- pdf_buf[pdf_ptr++] = smask[i];
+ pdf_room(pdf, 8);
+ pdf_quick_out(pdf, smask[i]);
if (bitdepth == 16)
i++;
}
xfree(smask);
- pdf_end_stream();
+ pdf_end_stream(pdf);
}
}
-/**********************************************************************/
-/*
- * 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| 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"
+
+
+@c
static int spng_getint(FILE * fp)
{
unsigned char buf[4];
@@ -435,7 +442,7 @@ static int spng_getint(FILE * fp)
#define SPNG_CHUNK_IDAT 0x49444154
#define SPNG_CHUNK_IEND 0x49454E44
-static void copy_png(image_dict * idict)
+static void copy_png(PDF pdf, image_dict * idict)
{
png_structp png_p;
png_infop info_p;
@@ -464,7 +471,7 @@ static void copy_png(image_dict * idict)
pdftex_fail("writepng: fseek in PNG file failed");
}
} while (endflag == false);
- pdf_printf("/Length %d\n"
+ pdf_printf(pdf, "/Length %d\n"
"/Filter/FlateDecode\n"
"/DecodeParms<<"
"/Colors %d"
@@ -486,17 +493,17 @@ static void copy_png(image_dict * idict)
pdftex_fail("writepng: IDAT chunk sequence broken");
idat = 1;
while (len > 0) {
- i = (len > pdf_buf_size) ? pdf_buf_size : len;
- pdfroom(i);
- fread(&pdf_buf[pdf_ptr], 1, i, fp);
- pdf_ptr += i;
+ 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");
break;
case SPNG_CHUNK_IEND: /* done */
- pdf_end_stream();
+ pdf_end_stream(pdf);
endflag = true;
break;
default:
@@ -508,97 +515,99 @@ static void copy_png(image_dict * idict)
} while (endflag == false);
}
-static void reopen_png(image_dict * idict)
+@ @c
+static void reopen_png(PDF pdf, image_dict * idict)
{
- integer width, height, xres, yres;
+ 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(idict, IMG_KEEPOPEN);
+ read_png_info(pdf, 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");
}
+@ @c
static boolean last_png_needs_page_group;
-void write_png(image_dict * idict)
+void write_png(PDF pdf, image_dict * idict)
{
double gamma, checked_gamma;
int i;
- integer palette_objnum = 0;
+ int palette_objnum = 0;
png_structp png_p;
png_infop info_p;
assert(idict != NULL);
last_png_needs_page_group = false;
if (img_file(idict) == NULL)
- reopen_png(idict);
+ reopen_png(pdf, idict);
assert(img_png_ptr(idict) != NULL);
png_p = img_png_png_ptr(idict);
info_p = img_png_info_ptr(idict);
- if (fixed_pdf_minor_version < 5)
- fixed_image_hicolor = 0;
- pdf_puts("/Type /XObject\n/Subtype /Image\n");
+ 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("%s\n", img_attr(idict));
- pdf_printf("/Width %i\n/Height %i\n/BitsPerComponent %i\n",
+ pdf_printf(pdf, "%s\n", img_attr(idict));
+ pdf_printf(pdf, "/Width %i\n/Height %i\n/BitsPerComponent %i\n",
(int) info_p->width,
(int) info_p->height, (int) info_p->bit_depth);
- pdf_puts("/ColorSpace ");
+ pdf_puts(pdf, "/ColorSpace ");
checked_gamma = 1.0;
- if (fixed_image_apply_gamma) {
+ if (pdf->image_apply_gamma) {
if (png_get_gAMA(png_p, info_p, &gamma)) {
- checked_gamma = (fixed_gamma / 1000.0) * gamma;
+ checked_gamma = (pdf->gamma / 1000.0) * gamma;
} else {
- checked_gamma =
- (fixed_gamma / 1000.0) * (1000.0 / fixed_image_gamma);
+ checked_gamma = (pdf->gamma / 1000.0) * (1000.0 / pdf->image_gamma);
}
}
/* the switching between |info_p| and |png_p| queries has been trial and error.
*/
- if (fixed_pdf_minor_version > 1 && info_p->interlace_type == PNG_INTERLACE_NONE && (png_p->transformations == 0 || png_p->transformations == 0x2000) /* gamma */
+ if (pdf->minor_version > 1 && info_p->interlace_type == PNG_INTERLACE_NONE &&
+ (png_p->transformations == 0 || png_p->transformations == 0x2000) /* gamma */
&&!(png_p->color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
png_p->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
- && (fixed_image_hicolor || (png_p->bit_depth <= 8))
+ && ((pdf->image_hicolor != 0) || (png_p->bit_depth <= 8))
&& (checked_gamma <= 1.01 && checked_gamma > 0.99)
) {
if (img_colorspace(idict) != 0) {
- pdf_printf("%i 0 R\n", (int) img_colorspace(idict));
+ pdf_printf(pdf, "%i 0 R\n", (int) img_colorspace(idict));
} else {
switch (info_p->color_type) {
case PNG_COLOR_TYPE_PALETTE:
- pdf_create_obj(0, 0);
- palette_objnum = obj_ptr;
- pdf_printf("[/Indexed /DeviceRGB %i %i 0 R]\n",
+ pdf_create_obj(pdf, obj_type_others, 0);
+ palette_objnum = pdf->obj_ptr;
+ pdf_printf(pdf, "[/Indexed /DeviceRGB %i %i 0 R]\n",
(int) (info_p->num_palette - 1),
(int) palette_objnum);
break;
case PNG_COLOR_TYPE_GRAY:
- pdf_puts("/DeviceGray\n");
+ pdf_puts(pdf, "/DeviceGray\n");
break;
default: /* RGB */
- pdf_puts("/DeviceRGB\n");
+ pdf_puts(pdf, "/DeviceRGB\n");
};
}
if (tracefilenames)
tex_printf(" (PNG copy)");
- copy_png(idict);
+ copy_png(pdf, idict);
if (palette_objnum > 0) {
- pdf_begin_dict(palette_objnum, 0);
- pdf_begin_stream();
+ pdf_begin_dict(pdf, palette_objnum, 0);
+ pdf_begin_stream(pdf);
for (i = 0; (unsigned) i < info_p->num_palette; i++) {
- pdfroom(3);
- pdf_buf[pdf_ptr++] = info_p->palette[i].red;
- pdf_buf[pdf_ptr++] = info_p->palette[i].green;
- pdf_buf[pdf_ptr++] = info_p->palette[i].blue;
+ pdf_room(pdf, 3);
+ pdf_quick_out(pdf, info_p->palette[i].red);
+ pdf_quick_out(pdf, info_p->palette[i].green);
+ pdf_quick_out(pdf, info_p->palette[i].blue);
}
- pdf_end_stream();
+ pdf_end_stream(pdf);
}
} else {
if (0) {
tex_printf(" PNG copy skipped because: ");
- if (fixed_image_apply_gamma &&
+ if ((pdf->image_apply_gamma != 0) &&
(checked_gamma > 1.01 || checked_gamma < 0.99))
tex_printf("gamma delta=%lf ", checked_gamma);
if (png_p->transformations != PNG_TRANSFORM_IDENTITY)
@@ -607,8 +616,8 @@ void write_png(image_dict * idict)
&& (info_p->color_type != PNG_COLOR_TYPE_RGB)
&& (info_p->color_type != PNG_COLOR_TYPE_PALETTE))
tex_printf("colortype ");
- if (fixed_pdf_minor_version <= 1)
- tex_printf("version=%d ", (int) fixed_pdf_minor_version);
+ if (pdf->minor_version <= 1)
+ tex_printf("version=%d ", pdf->minor_version);
if (info_p->interlace_type != PNG_INTERLACE_NONE)
tex_printf("interlaced ");
if (info_p->bit_depth > 8)
@@ -618,56 +627,63 @@ void write_png(image_dict * idict)
}
switch (info_p->color_type) {
case PNG_COLOR_TYPE_PALETTE:
- write_png_palette(idict);
+ write_png_palette(pdf, idict);
break;
case PNG_COLOR_TYPE_GRAY:
- write_png_gray(idict);
+ write_png_gray(pdf, idict);
break;
case PNG_COLOR_TYPE_GRAY_ALPHA:
- if (fixed_pdf_minor_version >= 4) {
- write_png_gray_alpha(idict);
+ if (pdf->minor_version >= 4) {
+ write_png_gray_alpha(pdf, idict);
last_png_needs_page_group = true;
} else
- write_png_gray(idict);
+ write_png_gray(pdf, idict);
break;
case PNG_COLOR_TYPE_RGB:
- write_png_rgb(idict);
+ write_png_rgb(pdf, idict);
break;
case PNG_COLOR_TYPE_RGB_ALPHA:
- if (fixed_pdf_minor_version >= 4) {
- write_png_rgb_alpha(idict);
+ if (pdf->minor_version >= 4) {
+ write_png_rgb_alpha(pdf, idict);
last_png_needs_page_group = true;
} else
- write_png_rgb(idict);
+ write_png_rgb(pdf, idict);
break;
default:
pdftex_fail("unsupported type of color_type <%i>",
info_p->color_type);
}
}
- pdf_flush();
+ pdf_flush(pdf);
close_and_cleanup_png(idict);
}
+@ @c
static boolean transparent_page_group_was_written = false;
-/* Called after the xobject generated by write_png has been finished; used to
- * write out additional objects */
-
-void write_additional_png_objects(void)
+@ Called after the xobject generated by |write_png| has been finished; used to
+write out additional objects
+@c
+void write_additional_png_objects(PDF pdf)
{
- return; /* this interferes with current macro-based usage and cannot be configured */
+ (void) pdf;
+ (void) transparent_page_group;
+ (void) transparent_page_group_was_written;
+ 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) {
/* create new group object */
transparent_page_group_was_written = true;
- pdf_begin_obj(transparent_page_group, 2);
- if (get_pdf_compress_level() == 0) {
- pdf_puts("%PTEX Group needed for transparent pngs\n");
+ pdf_begin_obj(pdf, transparent_page_group, 2);
+ if (pdf->compress_level == 0) {
+ pdf_puts(pdf, "%PTEX Group needed for transparent pngs\n");
}
pdf_puts
- ("<</Type/Group /S/Transparency /CS/DeviceRGB /I true /K true>>\n");
- pdf_end_obj();
+ (pdf,
+ "<</Type/Group /S/Transparency /CS/DeviceRGB /I true /K true>>\n");
+ pdf_end_obj(pdf);
}
}
+#endif
}