summaryrefslogtreecommitdiff
path: root/Build/source/texk/web2c/luatexdir/image
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/web2c/luatexdir/image')
-rw-r--r--Build/source/texk/web2c/luatexdir/image/epdf.h47
-rw-r--r--Build/source/texk/web2c/luatexdir/image/image.h14
-rw-r--r--Build/source/texk/web2c/luatexdir/image/pdftoepdf.cc328
-rw-r--r--Build/source/texk/web2c/luatexdir/image/writeimg.w30
-rw-r--r--Build/source/texk/web2c/luatexdir/image/writejbig2.h5
-rw-r--r--Build/source/texk/web2c/luatexdir/image/writejbig2.w27
-rw-r--r--Build/source/texk/web2c/luatexdir/image/writejp2.h31
-rw-r--r--Build/source/texk/web2c/luatexdir/image/writejp2.w282
-rw-r--r--Build/source/texk/web2c/luatexdir/image/writejpg.w42
-rw-r--r--Build/source/texk/web2c/luatexdir/image/writepng.w61
10 files changed, 636 insertions, 231 deletions
diff --git a/Build/source/texk/web2c/luatexdir/image/epdf.h b/Build/source/texk/web2c/luatexdir/image/epdf.h
index 0ce09ab13eb..c47c9f19f26 100644
--- a/Build/source/texk/web2c/luatexdir/image/epdf.h
+++ b/Build/source/texk/web2c/luatexdir/image/epdf.h
@@ -17,7 +17,7 @@
You should have received a copy of the GNU General Public License along
with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-/* $Id: epdf.h 3650 2010-04-26 08:13:41Z taco $ */
+/* $Id: epdf.h 4054 2011-01-10 19:05:54Z hhenkel $ */
// this is the common header file for C++ sources pdftoepdf.cc and lepdflib.cc
@@ -31,22 +31,15 @@
# 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 <dirent.h>
+# include <poppler-config.h>
+# include <goo/GooString.h>
+# include <goo/gmem.h>
+# include <goo/gfile.h>
# include "Object.h"
# include "Stream.h"
+# include "Gfx.h"
+# include "Annot.h"
# include "Array.h"
# include "Dict.h"
# include "XRef.h"
@@ -64,6 +57,8 @@ extern "C" {
extern char *xstrdup(const char *);
+ typedef enum { FE_FAIL, FE_RETURN_NULL } file_error_mode;
+
/* the following code is extremly ugly but needed for including web2c/config.h */
typedef const char *const_string; /* including kpathsea/types.h doesn't work on some systems */
@@ -75,7 +70,7 @@ extern "C" {
# undef CONFIG_H /* header file */
# endif
-# include <w2c/c-auto.h> /* define SIZEOF_LONG */
+# include <c-auto.h> /* define SIZEOF_LONG */
# include "openbsd-compat.h"
# include "image.h"
@@ -88,25 +83,24 @@ extern "C" {
/* 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)
+ extern void pdf_out_block(PDF pdf, const char *s, size_t n);
+
+# define pdf_out(B, A) do { pdf_room(B, 1); B->buf[B->ptr++] = A; } while (0)
+# define pdf_puts(pdf, s) pdf_out_block((pdf), (s), strlen(s))
/* 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);
+ extern void epdf_free(void);
/* utils.c */
__attribute__ ((format(printf, 1, 2)))
@@ -129,6 +123,9 @@ extern "C" {
// and &obj to get a pointer to the object.
// It is no longer necessary to call Object::free explicitely.
+# if 0
+// PdfObject is replaced by xpdf's Object type, with manual obj.free()
+
// *INDENT-OFF*
class PdfObject {
public:
@@ -150,6 +147,7 @@ class PdfObject {
Object iObject;
};
// *INDENT-ON*
+# endif
/**********************************************************************/
@@ -165,9 +163,10 @@ struct PdfDocument {
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
+ unsigned int occurences; // number of references to the PdfDocument; it can be deleted when occurences == 0
+ unsigned int pc; // counter to track PDFDoc generation or deletion
};
-PdfDocument *refPdfDocument(char *file_path);
+PdfDocument *refPdfDocument(char *file_path, file_error_mode fe);
#endif /* EPDF_H */
diff --git a/Build/source/texk/web2c/luatexdir/image/image.h b/Build/source/texk/web2c/luatexdir/image/image.h
index c4d0c3963f7..c1b91abafb6 100644
--- a/Build/source/texk/web2c/luatexdir/image/image.h
+++ b/Build/source/texk/web2c/luatexdir/image/image.h
@@ -18,7 +18,7 @@
You should have received a copy of the GNU General Public License along
with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
-/* $Id: image.h 3388 2010-01-26 10:59:04Z taco $ */
+/* $Id: image.h 4051 2011-01-09 22:41:33Z hhenkel $ */
#ifndef IMAGE_H
# define IMAGE_H
@@ -30,7 +30,8 @@
# define JPG_UINT32 unsigned long
# define JPG_UINT8 unsigned char
-extern int do_zround(double r); /* from utils.c */
+extern int do_zround(double r); /* from utils.w */
+extern scaled one_hundred_bp; /* from pdfgen.w */
# define bp2int(p) do_zround(p * (one_hundred_bp / 100.0))
# define int2bp(i) (i * 100.0 / one_hundred_bp)
@@ -53,6 +54,10 @@ typedef struct {
JPG_UINT32 length; /* length of file/data */
} jpg_img_struct;
+typedef struct {
+ int length; /* length of file/data */
+} jp2_img_struct;
+
# if 0
typedef struct { /* currently unused */
} jb2_img_struct;
@@ -67,7 +72,7 @@ typedef enum { DICT_NEW, /* fresh dictionary */
} dict_state;
typedef enum { IMG_TYPE_NONE, IMG_TYPE_PDF, IMG_TYPE_PNG, IMG_TYPE_JPG,
- IMG_TYPE_JBIG2, IMG_TYPE_PDFSTREAM, IMG_TYPE_SENTINEL
+ IMG_TYPE_JP2, IMG_TYPE_JBIG2, IMG_TYPE_PDFSTREAM, IMG_TYPE_SENTINEL
} imgtype_e;
typedef enum { IMG_KEEPOPEN, IMG_CLOSEINBETWEEN } img_readtype_e;
@@ -111,6 +116,7 @@ typedef struct {
pdf_stream_struct *pdfstream;
png_img_struct *png;
jpg_img_struct *jpg;
+ jp2_img_struct *jp2;
/* jb2_img_struct *jb2; */
} img_struct;
} image_dict;
@@ -156,6 +162,8 @@ typedef struct {
# define img_jpg_ptr(N) ((N)->img_struct.jpg)
# define img_jpg_color(N) ((N)->img_struct.jpg->color_space)
+# define img_jp2_ptr(N) ((N)->img_struct.jp2)
+
# define img_jb2_ptr(N) ((N)->img_struct.jb2)
# define F_FLAG_BBOX (1 << 0)
diff --git a/Build/source/texk/web2c/luatexdir/image/pdftoepdf.cc b/Build/source/texk/web2c/luatexdir/image/pdftoepdf.cc
index 655fdd8842e..8c112d4261b 100644
--- a/Build/source/texk/web2c/luatexdir/image/pdftoepdf.cc
+++ b/Build/source/texk/web2c/luatexdir/image/pdftoepdf.cc
@@ -19,12 +19,13 @@
with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
static const char _svn_version[] =
- "$Id: pdftoepdf.cc 3606 2010-04-10 12:58:25Z taco $ "
- "$URL: http://foundry.supelec.fr/svn/luatex/branches/0.60.x/source/texk/web2c/luatexdir/image/pdftoepdf.cc $";
+ "$Id: pdftoepdf.cc 4136 2011-04-11 22:06:50Z hhenkel $ "
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.66.0/source/texk/web2c/luatexdir/image/pdftoepdf.cc $";
-#include "epdf.h"
+// define DEBUG
-#define one_hundred_bp 6578176 // one_hundred_bp = 7227 * 65536 / 72
+#include "epdf.h"
+#define HAVE_GETPDFMAJORVERSION 1
// 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++.
@@ -62,41 +63,121 @@ static PdfDocument *findPdfDocument(char *file_path)
return pdf_doc;
}
-// Returns pointer to PdfDocument structure for PDF file.
-// Creates a new structure if it doesn't exist yet.
+#define PDF_CHECKSUM_SIZE 32
-char *get_file_checksum(char *a);
+static char *get_file_checksum(char *a, file_error_mode fe)
+{
+ 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 {
+ switch (fe) {
+ case FE_FAIL:
+ pdftex_fail("PDF inclusion: could not stat() file '%s'", a);
+ break;
+ case FE_RETURN_NULL:
+ if (ck != NULL)
+ free(ck);
+ ck = NULL;
+ break;
+ default:
+ assert(0);
+ }
+ }
+ return ck;
+}
+
+// Returns pointer to PdfDocument structure for PDF file.
+// Creates a new PdfDocument structure if it doesn't exist yet.
+// When fe = FE_RETURN_NULL, the function returns NULL in error case.
-PdfDocument *refPdfDocument(char *file_path)
+PdfDocument *refPdfDocument(char *file_path, file_error_mode fe)
{
- PdfDocument *pdf_doc = findPdfDocument(file_path);
- if (pdf_doc == NULL) {
- if (PdfDocumentTree == NULL)
- PdfDocumentTree =
- avl_create(CompPdfDocument, NULL, &avl_xallocator);
+ char *checksum;
+ PdfDocument *pdf_doc;
+ PDFDoc *doc = NULL;
+ GooString *docName = NULL;
+ int new_flag = 0;
+ if ((checksum = get_file_checksum(file_path, fe)) == NULL) {
+ assert(fe == FE_RETURN_NULL);
+ return (PdfDocument *) NULL;
+ }
+ assert(checksum != NULL);
+ if ((pdf_doc = findPdfDocument(file_path)) == NULL) {
+#ifdef DEBUG
+ fprintf(stderr, "\nDEBUG: New PdfDocument %s\n", file_path);
+#endif
+ new_flag = 1;
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->checksum = checksum;
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->inObjList = NULL;
+ pdf_doc->ObjMapTree = NULL;
pdf_doc->occurences = 0; // 0 = unreferenced
+ pdf_doc->pc = 0;
+ } else {
+#ifdef DEBUG
+ fprintf(stderr, "\nDEBUG: Found PdfDocument %s (%d)\n",
+ pdf_doc->file_path, pdf_doc->occurences);
+#endif
+ assert(pdf_doc->checksum != NULL);
+ if (strncmp(pdf_doc->checksum, checksum, PDF_CHECKSUM_SIZE) != 0) {
+ pdftex_fail("PDF inclusion: file has changed '%s'", file_path);
+ }
+ free(checksum);
}
+ assert(pdf_doc != NULL);
+ if (pdf_doc->doc == NULL) {
#ifdef DEBUG
- fprintf(stderr, "\nluatex Debug: Creating %s (%d)\n",
- pdf_doc->file_path, pdf_doc->occurences);
+ fprintf(stderr, "\nDEBUG: New PDFDoc %s (%d)\n",
+ pdf_doc->file_path, pdf_doc->occurences);
#endif
+ docName = new GooString(file_path);
+ doc = new PDFDoc(docName); // takes ownership of docName
+ pdf_doc->pc++;
+
+ if (!doc->isOk() || !doc->okToPrint()) {
+ switch (fe) {
+ case FE_FAIL:
+ pdftex_fail("xpdf: reading PDF image failed");
+ break;
+ case FE_RETURN_NULL:
+ delete doc;
+ // delete docName;
+ if (new_flag == 1) {
+ if (pdf_doc->file_path != NULL)
+ free(pdf_doc->file_path);
+ if (pdf_doc->checksum != NULL)
+ free(pdf_doc->checksum);
+ delete pdf_doc;
+ }
+ return (PdfDocument *) NULL;
+ break;
+ default:
+ assert(0);
+ }
+ }
+ pdf_doc->doc = doc;
+ }
+ // PDF file could be opened without problems, checksum ok.
+ if (PdfDocumentTree == NULL)
+ PdfDocumentTree = avl_create(CompPdfDocument, NULL, &avl_xallocator);
+ if ((PdfDocument *) avl_find(PdfDocumentTree, pdf_doc) == NULL) {
+ void **aa = avl_probe(PdfDocumentTree, pdf_doc);
+ assert(aa != NULL);
+ }
pdf_doc->occurences++;
#ifdef DEBUG
- fprintf(stderr, "\nluatex Debug: Incrementing %s (%d)\n",
+ fprintf(stderr, "\nDEBUG: Incrementing %s (%d)\n",
pdf_doc->file_path, pdf_doc->occurences);
#endif
return pdf_doc;
@@ -249,7 +330,7 @@ static char *convertNumToPDF(double n)
static void copyObject(PDF, PdfDocument *, Object *);
-static void copyString(PDF pdf, GString * string)
+static void copyString(PDF pdf, GooString * string)
{
char *p;
unsigned char c;
@@ -293,13 +374,14 @@ static void copyName(PDF pdf, char *s)
static void copyArray(PDF pdf, PdfDocument * pdf_doc, Array * array)
{
int i, l;
- PdfObject obj1;
+ Object obj1;
pdf_puts(pdf, "[");
for (i = 0, l = array->getLength(); i < l; ++i) {
array->getNF(i, &obj1);
- if (!obj1->isName())
+ if (!obj1.isName())
pdf_puts(pdf, " ");
copyObject(pdf, pdf_doc, &obj1);
+ obj1.free();
}
pdf_puts(pdf, "]");
}
@@ -307,13 +389,14 @@ static void copyArray(PDF pdf, PdfDocument * pdf_doc, Array * array)
static void copyDict(PDF pdf, PdfDocument * pdf_doc, Dict * dict)
{
int i, l;
- PdfObject obj1;
+ Object 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);
+ obj1.free();
pdf_puts(pdf, "\n");
}
pdf_puts(pdf, ">>");
@@ -392,15 +475,16 @@ static void writeRefs(PDF pdf, PdfDocument * pdf_doc)
{
InObj *r, *n;
XRef *xref;
+ Object obj1;
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())
+ 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);
+ obj1.free();
pdf_puts(pdf, "\n");
pdf_end_obj(pdf);
n = r->next;
@@ -436,26 +520,6 @@ static PDFRectangle *get_pagebox(Page * page, 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.
@@ -469,7 +533,6 @@ read_pdf_info(image_dict * idict, int minor_pdf_version_wanted,
PdfDocument *pdf_doc;
Page *page;
int rotate;
- char *checksum;
PDFRectangle *pagebox;
#ifdef HAVE_GETPDFMAJORVERSION
int pdf_major_version_found, pdf_minor_version_found;
@@ -486,15 +549,8 @@ read_pdf_info(image_dict * idict, int minor_pdf_version_wanted,
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);
+ pdf_doc = refPdfDocument(img_filepath(idict), FE_FAIL);
// 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
@@ -503,13 +559,15 @@ read_pdf_info(image_dict * idict, int minor_pdf_version_wanted,
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)) {
+ || (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);
+ 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);
+ pdftex_warn(msg, pdf_major_version_found, pdf_minor_version_found,
+ minor_pdf_version_wanted);
}
}
#else
@@ -528,7 +586,7 @@ read_pdf_info(image_dict * idict, int minor_pdf_version_wanted,
img_totalpages(idict) = pdf_doc->doc->getCatalog()->getNumPages();
if (img_pagename(idict)) {
// get page by name
- GString name(img_pagename(idict));
+ GooString name(img_pagename(idict));
LinkDest *link = pdf_doc->doc->findDest(&name);
if (link == NULL || !link->isOk())
pdftex_fail("PDF inclusion: invalid destination <%s>",
@@ -607,38 +665,30 @@ read_pdf_info(image_dict * idict, int minor_pdf_version_wanted,
// Here the included PDF is copied, so most errors that can happen
// during PDF inclusion will arise here.
-static void write_epdf1(PDF pdf, image_dict * idict)
+void write_epdf(PDF pdf, image_dict * idict)
{
PdfDocument *pdf_doc;
Page *page;
Ref *pageref;
Dict *pageDict;
- PdfObject info, contents, obj1, pageObj, dictObj;
+ Object obj1, contents, pageobj, pagesobj1, pagesobj2, *op1, *op2, *optmp;
PDFRectangle *pagebox;
int i, l;
float bbox[4];
- char *checksum;
char s[256];
- char *pagedictkeys[] =
+ const char *pagedictkeys[] =
{ "Group", "LastModified", "Metadata", "PieceInfo", "Resources",
"SeparationInfo", 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);
+ pdf_doc = refPdfDocument(img_filepath(idict), FE_FAIL);
page = pdf_doc->doc->getCatalog()->getPage(img_pagenum(idict));
pageref = pdf_doc->doc->getCatalog()->getPageRef(img_pagenum(idict));
assert(pageref != NULL); // was checked already in read_pdf_info()
- pdf_doc->doc->getXRef()->fetch(pageref->num, pageref->gen, &pageObj);
- pageDict = pageObj->getDict();
+ pdf_doc->doc->getXRef()->fetch(pageref->num, pageref->gen, &pageobj);
+ pageDict = pageobj.getDict();
// write the Page header
pdf_puts(pdf, "/Type /XObject\n/Subtype /Form\n");
@@ -652,12 +702,13 @@ static void write_epdf1(PDF pdf, image_dict * idict)
strlen(pdf_doc->file_path)));
pdf_printf(pdf, "/%s.PageNumber %i\n", pdfkeyprefix,
(int) img_pagenum(idict));
- pdf_doc->doc->getDocInfoNF(&info);
- if (info->isRef()) {
+ pdf_doc->doc->getDocInfoNF(&obj1);
+ if (obj1.isRef()) {
// the info dict must be indirect (PDF Ref p. 61)
pdf_printf(pdf, "/%s.InfoDict ", pdfkeyprefix);
- pdf_printf(pdf, "%d 0 R\n", addInObj(pdf, pdf_doc, info->getRef()));
+ pdf_printf(pdf, "%d 0 R\n", addInObj(pdf, pdf_doc, obj1.getRef()));
}
+ obj1.free();
if (img_is_bbox(idict)) {
bbox[0] = int2bp(img_bbox(idict)[0]);
bbox[1] = int2bp(img_bbox(idict)[1]);
@@ -678,33 +729,54 @@ static void write_epdf1(PDF pdf, image_dict * idict)
// Now all relevant parts of the Page dictionary are copied:
- // Resources validity check
- pageDict->lookupNF("Resources", &dictObj);
- if (dictObj->isNull()) {
- // 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.)");
- }
-
// Metadata validity check (as a stream it must be indirect)
- pageDict->lookupNF("Metadata", &dictObj);
- if (!dictObj->isNull() && !dictObj->isRef())
+ pageDict->lookupNF((char *) "Metadata", &obj1);
+ if (!obj1.isNull() && !obj1.isRef())
pdftex_warn("PDF inclusion: /Metadata must be indirect object");
+ obj1.free();
// copy selected items in Page dictionary
for (i = 0; pagedictkeys[i] != NULL; i++) {
- pageDict->lookupNF(pagedictkeys[i], &dictObj);
- if (!dictObj->isNull()) {
+ pageDict->lookupNF((char *) pagedictkeys[i], &obj1);
+ if (!obj1.isNull()) {
pdf_printf(pdf, "/%s ", pagedictkeys[i]);
- copyObject(pdf, pdf_doc, &dictObj); // preserves indirection
+ copyObject(pdf, pdf_doc, &obj1); // preserves indirection
}
+ obj1.free();
+ }
+
+ // If there are no Resources in the Page dict of the embedded page,
+ // try to inherit the Resources from the Pages tree of the embedded
+ // PDF file, climbing up the tree until the Resources are found.
+ // (This fixes a problem with Scribus 1.3.3.14.)
+ pageDict->lookupNF((char *) "Resources", &obj1);
+ if (obj1.isNull()) {
+ op1 = &pagesobj1;
+ op2 = &pagesobj2;
+ pageDict->lookup((char *) "Parent", op1);
+ while (op1->isDict()) {
+ obj1.free();
+ op1->dictLookupNF((char *) "Resources", &obj1);
+ if (!obj1.isNull()) {
+ pdf_puts(pdf, "/Resources ");
+ copyObject(pdf, pdf_doc, &obj1);
+ break;
+ }
+ op1->dictLookup((char *) "Parent", op2);
+ optmp = op1;
+ op1 = op2;
+ op2 = optmp;
+ op2->free();
+ };
+ if (!op1->isDict())
+ pdftex_warn("PDF inclusion: Page /Resources missing.");
+ op1->free();
}
+ obj1.free();
// write the Page contents
page->getContents(&contents);
- if (contents->isStream()) {
+ if (contents.isStream()) {
// Variant A: get stream and recompress under control
// of \pdfcompresslevel
//
@@ -714,37 +786,39 @@ static void write_epdf1(PDF pdf, image_dict * idict)
// Variant B: copy stream without recompressing
//
- contents->streamGetDict()->lookup((char *) "F", &obj1);
- if (!obj1->isNull()) {
+ contents.streamGetDict()->lookup((char *) "F", &obj1);
+ if (!obj1.isNull()) {
pdftex_fail("PDF inclusion: Unsupported external stream");
}
- contents->streamGetDict()->lookup((char *) "Length", &obj1);
- assert(!obj1->isNull());
+ obj1.free();
+ contents.streamGetDict()->lookup((char *) "Length", &obj1);
+ assert(!obj1.isNull());
pdf_puts(pdf, "/Length ");
copyObject(pdf, pdf_doc, &obj1);
+ obj1.free();
pdf_puts(pdf, "\n");
- contents->streamGetDict()->lookup((char *) "Filter", &obj1);
- if (!obj1->isNull()) {
+ contents.streamGetDict()->lookup((char *) "Filter", &obj1);
+ if (!obj1.isNull()) {
pdf_puts(pdf, "/Filter ");
copyObject(pdf, pdf_doc, &obj1);
+ obj1.free();
pdf_puts(pdf, "\n");
- contents->streamGetDict()->lookup((char *) "DecodeParms", &obj1);
- if (!obj1->isNull()) {
+ contents.streamGetDict()->lookup((char *) "DecodeParms", &obj1);
+ if (!obj1.isNull()) {
pdf_puts(pdf, "/DecodeParms ");
copyObject(pdf, pdf_doc, &obj1);
pdf_puts(pdf, "\n");
}
}
+ obj1.free();
pdf_puts(pdf, ">>\nstream\n");
- copyStreamStream(pdf, contents->getStream()->getBaseStream());
+ copyStreamStream(pdf, contents.getStream()->getBaseStream());
pdf_end_stream(pdf);
- } else if (contents->isArray()) {
+ } else if (contents.isArray()) {
pdf_begin_stream(pdf);
- for (i = 0, l = contents->arrayGetLength(); i < l; ++i) {
- PdfObject contentsobj;
- copyStreamStream(pdf,
- (contents->
- arrayGet(i, &contentsobj))->getStream());
+ for (i = 0, l = contents.arrayGetLength(); i < l; ++i) {
+ copyStreamStream(pdf, (contents.arrayGet(i, &obj1))->getStream());
+ obj1.free();
if (i < (l - 1)) {
// put a space between streams to be on the safe side (streams
// should have a trailing space here, but one never knows)
@@ -758,14 +832,13 @@ static void write_epdf1(PDF pdf, image_dict * idict)
}
// write out all indirect objects
writeRefs(pdf, pdf_doc);
-}
-
-// this relay function is needed to keep some destructor quiet (???)
-
-void write_epdf(PDF pdf, image_dict * idict)
-{
- write_epdf1(pdf, idict);
+ contents.free();
+ pageobj.free();
+ // unrefPdfDocument() must come after contents.free() and pageobj.free()!
+ // TH: The next line makes repeated pdf inclusion unacceptably slow
+#if 0
unrefPdfDocument(img_filepath(idict));
+#endif
}
//**********************************************************************
@@ -780,8 +853,12 @@ static void deletePdfDocumentPdfDoc(PdfDocument * pdf_doc)
n = r->next;
delete r;
}
+#ifdef DEBUG
+ fprintf(stderr, "\nDEBUG: Deleting PDFDoc %s\n", pdf_doc->file_path);
+#endif
delete pdf_doc->doc;
pdf_doc->doc = NULL;
+ pdf_doc->pc++;
}
static void destroyPdfDocument(void *pa, void * /*pb */ )
@@ -798,16 +875,13 @@ void unrefPdfDocument(char *file_path)
{
PdfDocument *pdf_doc = findPdfDocument(file_path);
assert(pdf_doc != NULL);
- assert(pdf_doc->occurences > 0); // aim for point landing
+ assert(pdf_doc->occurences != 0); // aim for point landing
pdf_doc->occurences--;
#ifdef DEBUG
- fprintf(stderr, "\nluatex Debug: Decrementing %s (%d)\n",
+ fprintf(stderr, "\nDEBUG: 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);
}
@@ -816,7 +890,7 @@ void unrefPdfDocument(char *file_path)
// Called when PDF embedding system is finalized.
// Now deallocate all remaining PdfDocuments.
-void epdf_check_mem()
+void epdf_free()
{
if (PdfDocumentTree != NULL)
avl_destroy(PdfDocumentTree, destroyPdfDocument);
diff --git a/Build/source/texk/web2c/luatexdir/image/writeimg.w b/Build/source/texk/web2c/luatexdir/image/writeimg.w
index 45aeacd5fe7..57f0740f04b 100644
--- a/Build/source/texk/web2c/luatexdir/image/writeimg.w
+++ b/Build/source/texk/web2c/luatexdir/image/writeimg.w
@@ -22,8 +22,8 @@
@ @c
static const char _svn_version[] =
- "$Id: writeimg.w 3584 2010-04-02 17:45:55Z hhenkel $ "
- "$URL: http://foundry.supelec.fr/svn/luatex/branches/0.60.x/source/texk/web2c/luatexdir/image/writeimg.w $";
+ "$Id: writeimg.w 4055 2011-01-10 19:52:50Z oneiros $ "
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.66.0/source/texk/web2c/luatexdir/image/writeimg.w $";
#include <assert.h>
#include "ptexlib.h"
@@ -33,6 +33,7 @@ static const char _svn_version[] =
@ @c
#include "image/image.h"
#include "image/writejpg.h"
+#include "image/writejp2.h"
#include "image/writepng.h"
#include "image/writejbig2.h"
@@ -122,6 +123,7 @@ static const char _svn_version[] =
#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_JP2 "\x6A\x50\x20\x20"
#define HEADER_PDF "%PDF-1."
#define MAX_HEADER (sizeof(HEADER_PNG)-1)
@@ -145,6 +147,8 @@ static void check_type_by_header(image_dict * idict)
/* tests */
if (strncmp(header, HEADER_JPG, sizeof(HEADER_JPG) - 1) == 0)
img_type(idict) = IMG_TYPE_JPG;
+ else if (strncmp(header + 4, HEADER_JP2, sizeof(HEADER_JP2) - 1) == 0)
+ img_type(idict) = IMG_TYPE_JP2;
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)
@@ -169,6 +173,8 @@ static void check_type_by_extension(image_dict * idict)
else if (strcasecmp(image_suffix, ".jpg") == 0 ||
strcasecmp(image_suffix, ".jpeg") == 0)
img_type(idict) = IMG_TYPE_JPG;
+ else if (strcasecmp(image_suffix, ".jp2") == 0)
+ img_type(idict) = IMG_TYPE_JP2;
else if (strcasecmp(image_suffix, ".jbig2") == 0 ||
strcasecmp(image_suffix, ".jb2") == 0)
img_type(idict) = IMG_TYPE_JBIG2;
@@ -257,6 +263,9 @@ void free_image_dict(image_dict * p)
case IMG_TYPE_JPG: /* assuming |IMG_CLOSEINBETWEEN| */
assert(img_jpg_ptr(p) == NULL);
break;
+ case IMG_TYPE_JP2: /* */
+ assert(img_jp2_ptr(p) == NULL);
+ break;
case IMG_TYPE_JBIG2: /* todo: writejbig2.w cleanup */
break;
case IMG_TYPE_PDFSTREAM:
@@ -295,7 +304,7 @@ void read_img(PDF pdf,
img_filepath(idict) =
kpse_find_file(img_filename(idict), kpse_tex_format, true);
if (img_filepath(idict) == NULL)
- pdftex_fail("cannot find image file");
+ pdftex_fail("cannot find image file '%s'", img_filename(idict));
}
recorder_record_input(img_filename(idict));
/* type checks */
@@ -314,6 +323,9 @@ void read_img(PDF pdf,
case IMG_TYPE_JPG:
read_jpg_info(pdf, idict, IMG_CLOSEINBETWEEN);
break;
+ case IMG_TYPE_JP2:
+ read_jp2_info(idict, IMG_CLOSEINBETWEEN);
+ break;
case IMG_TYPE_JBIG2:
if (minor_version < 4) {
pdftex_fail
@@ -338,9 +350,8 @@ static image_dict *read_image(PDF pdf, char *file_name, int page_num,
{
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;
+ pdf->ximage_count++;
+ img_objnum(idict) = pdf_create_obj(pdf, obj_type_ximage, pdf->ximage_count);
img_index(idict) = pdf->ximage_count;
set_obj_data_ptr(pdf, img_objnum(idict), img_index(idict));
idict_to_array(idict);
@@ -429,7 +440,7 @@ void scan_pdfrefximage(PDF pdf)
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);
+ check_obj_type(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
@@ -577,6 +588,9 @@ void write_img(PDF pdf, image_dict * idict)
case IMG_TYPE_JPG:
write_jpg(pdf, idict);
break;
+ case IMG_TYPE_JP2:
+ write_jp2(pdf, idict);
+ break;
case IMG_TYPE_JBIG2:
write_jbig2(pdf, idict);
break;
@@ -777,8 +791,8 @@ void undumpimagemeta(PDF pdf, int pdfversion, int pdfinclusionerrorlevel)
undumpinteger(img_pagenum(idict));
break;
case IMG_TYPE_PNG:
- break;
case IMG_TYPE_JPG:
+ case IMG_TYPE_JP2:
break;
case IMG_TYPE_JBIG2:
if (pdfversion < 4) {
diff --git a/Build/source/texk/web2c/luatexdir/image/writejbig2.h b/Build/source/texk/web2c/luatexdir/image/writejbig2.h
index a5715d5732e..6609c2d2f99 100644
--- a/Build/source/texk/web2c/luatexdir/image/writejbig2.h
+++ b/Build/source/texk/web2c/luatexdir/image/writejbig2.h
@@ -18,13 +18,16 @@
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 2579 2009-06-23 14:12:23Z taco $ */
+/* $Id: writejbig2.h 4051 2011-01-09 22:41:33Z hhenkel $ */
#ifndef WRITEJBIG2_H
# define WRITEJBIG2_H
# include "image.h"
+unsigned int read2bytes(FILE * f);
+unsigned int read4bytes(FILE * f);
+
void flush_jbig2_page0_objects(PDF);
void read_jbig2_info(image_dict *);
void write_jbig2(PDF, image_dict *);
diff --git a/Build/source/texk/web2c/luatexdir/image/writejbig2.w b/Build/source/texk/web2c/luatexdir/image/writejbig2.w
index 0e578f9b457..6828ba418aa 100644
--- a/Build/source/texk/web2c/luatexdir/image/writejbig2.w
+++ b/Build/source/texk/web2c/luatexdir/image/writejbig2.w
@@ -1,7 +1,8 @@
% writejbig2.w
% Copyright 1996-2006 Han The Thanh <thanh@@pdftex.org>
-% Copyright 2006-2009 Taco Hoekwater <taco@@luatex.org>
+% Copyright 2006-2011 Taco Hoekwater <taco@@luatex.org>
+% Copyright 2003-2011 Hartmut Henkel <hartmut@@luatex.org>
% This file is part of LuaTeX.
@@ -80,8 +81,8 @@ object exists, reference it. Else create fresh one.
@ @c
static const char _svn_version[] =
- "$Id: writejbig2.w 3584 2010-04-02 17:45:55Z hhenkel $ "
- "$URL: http://foundry.supelec.fr/svn/luatex/branches/0.60.x/source/texk/web2c/luatexdir/image/writejbig2.w $";
+ "$Id: writejbig2.w 4058 2011-01-10 20:44:28Z hhenkel $ "
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.66.0/source/texk/web2c/luatexdir/image/writejbig2.w $";
#undef DEBUG
@@ -347,14 +348,14 @@ static SEGINFO *find_seginfo(LIST * slp, unsigned long segnum)
}
@ @c
-static unsigned int read2bytes(FILE * f)
+unsigned int read2bytes(FILE * f)
{
unsigned int c = (unsigned int) ygetc(f);
return (c << 8) + (unsigned int) ygetc(f);
}
@ @c
-static unsigned long read4bytes(FILE * f)
+unsigned int read4bytes(FILE * f)
{
unsigned int l = read2bytes(f);
return (l << 16) + read2bytes(f);
@@ -503,7 +504,7 @@ static boolean readseghdr(FILEINFO * fip, SEGINFO * sip)
}
/* 7.2.6 Segment page association */
if (sip->pageassocsizeflag)
- sip->segpage = (long int) read4bytes(fip->file);
+ sip->segpage = read4bytes(fip->file);
else
sip->segpage = ygetc(fip->file);
/* 7.2.7 Segment data length */
@@ -683,17 +684,17 @@ static void rd_jbig2_info(FILEINFO * fip)
/* 7.4.8 Page information segment syntax */
if (sip->pageinfoflag) {
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->width = read4bytes(fip->file);
+ pip->height = read4bytes(fip->file);
+ pip->xres = read4bytes(fip->file);
+ pip->yres = 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 = (unsigned) read4bytes(fip->file);
+ pip->stripedheight = read4bytes(fip->file);
seekdist -= 4;
}
if (!fip->sequentialaccess
@@ -732,8 +733,8 @@ static void wr_jbig2(PDF pdf, FILEINFO * fip, unsigned long page)
pdf_puts(pdf, "/Filter [/JBIG2Decode]\n");
if (fip->page0.last != NULL) {
if (fip->pdfpage0objnum == 0) {
- pdf_create_obj(pdf, obj_type_others, 0);
- fip->pdfpage0objnum = (unsigned long) pdf->obj_ptr;
+ fip->pdfpage0objnum =
+ (unsigned long) pdf_create_obj(pdf, obj_type_others, 0);
}
pdf_printf(pdf, "/DecodeParms [<< /JBIG2Globals %lu 0 R >>]\n",
fip->pdfpage0objnum);
diff --git a/Build/source/texk/web2c/luatexdir/image/writejp2.h b/Build/source/texk/web2c/luatexdir/image/writejp2.h
new file mode 100644
index 00000000000..04e350f3c9e
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/image/writejp2.h
@@ -0,0 +1,31 @@
+/* writejp2.h
+
+ Copyright 2011 Taco Hoekwater <taco@luatex.org>
+ Copyright 2011 Hartmut Henkel <hartmut@luatex.org>
+
+ This file is part of LuaTeX.
+
+ LuaTeX is free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License as published by the Free
+ Software Foundation; either version 2 of the License, or (at your
+ option) any later version.
+
+ LuaTeX is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
+
+/* $Id: writejp2.h 4060 2011-01-11 00:01:57Z hhenkel $ */
+
+#ifndef WRITEJP2_H
+# define WRITEJP2_H
+
+# include "image.h"
+
+void read_jp2_info(image_dict *, img_readtype_e);
+void write_jp2(PDF, image_dict *);
+
+#endif /* WRITEJP2_H */
diff --git a/Build/source/texk/web2c/luatexdir/image/writejp2.w b/Build/source/texk/web2c/luatexdir/image/writejp2.w
new file mode 100644
index 00000000000..1d27f733c56
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/image/writejp2.w
@@ -0,0 +1,282 @@
+% writejp2.w
+
+% Copyright 2011 Taco Hoekwater <taco@@luatex.org>
+% Copyright 2011 Hartmut Henkel <hartmut@@luatex.org>
+
+% This file is part of LuaTeX.
+
+% LuaTeX is free software; you can redistribute it and/or modify it under
+% the terms of the GNU General Public License as published by the Free
+% Software Foundation; either version 2 of the License, or (at your
+% option) any later version.
+
+% LuaTeX is distributed in the hope that it will be useful, but WITHOUT
+% ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+% FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+% License for more details.
+
+% You should have received a copy of the GNU General Public License along
+% with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
+
+@ @c
+static const char _svn_version[] =
+ "$Id: writejp2.w 4133 2011-04-11 16:54:11Z oneiros $ "
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.66.0/source/texk/web2c/luatexdir/image/writejp2.w $";
+
+@ Basic JPEG~2000 image support. Section and Table references below:
+Information technology --- JPEG~2000 image coding system: Core coding system.
+ISO/IEC 15444-1, Second edition, 2004-09-15, file |15444-1annexi.pdf|.
+
+@c
+#include <math.h>
+#include <assert.h>
+#include "ptexlib.h"
+#include "image/image.h"
+#include "image/writejp2.h"
+#include "image/writejbig2.h" /* read2bytes(), read4bytes() */
+
+/* Table 1.2 -- Defined boxes */
+#define BOX_JP 0x6A502020
+#define BOX_FTYP 0x66747970
+#define BOX_JP2H 0x6a703268
+#define BOX_IHDR 0x69686472
+#define BOX_BPCC 0x62706363
+#define BOX_COLR 0x636D6170
+#define BOX_CDEF 0x63646566
+#define BOX_RES 0x72657320
+#define BOX_RESC 0x72657363
+#define BOX_RESD 0x72657364
+#define BOX_JP2C 0x6A703263
+
+/* 1.4 Box definition */
+typedef struct {
+ unsigned long long lbox;
+ unsigned int tbox;
+} hdr_struct;
+
+static unsigned long long read8bytes(FILE * f)
+{
+ unsigned long long l = read4bytes(f);
+ l = (l << 32) + read4bytes(f);
+ return l;
+}
+
+static hdr_struct read_boxhdr(image_dict * idict)
+{
+ hdr_struct hdr;
+ hdr.lbox = read4bytes(img_file(idict));
+ hdr.tbox = read4bytes(img_file(idict));
+ if (hdr.lbox == 1)
+ hdr.lbox = read8bytes(img_file(idict));
+ if (hdr.lbox == 0 && hdr.tbox != BOX_JP2C)
+ pdftex_fail("reading JP2 image failed (LBox == 0)");
+ return hdr;
+}
+
+/* 1.5.3.1 Image Header box */
+static void scan_ihdr(image_dict * idict)
+{
+ unsigned int height, width, nc;
+ unsigned char bpc, c, unkc, ipr;
+ height = read4bytes(img_file(idict));
+ width = read4bytes(img_file(idict));
+ img_ysize(idict) = (int) height;
+ img_xsize(idict) = (int) width;
+ nc = read2bytes(img_file(idict));
+ bpc = (unsigned char) xgetc(img_file(idict));
+ img_colordepth(idict) = bpc + 1;
+ c = (unsigned char) xgetc(img_file(idict));
+ unkc = (unsigned char) xgetc(img_file(idict));
+ ipr = (unsigned char) xgetc(img_file(idict));
+}
+
+/* 1.5.3.7.1 Capture Resolution box */
+/* 1.5.3.7.2 Default Display Resolution box */
+static void scan_resc_resd(image_dict * idict)
+{
+ unsigned int vr_n, vr_d, hr_n, hr_d;
+ unsigned char vr_e, hr_e;
+ double hr_, vr_;
+ vr_n = read2bytes(img_file(idict));
+ vr_d = read2bytes(img_file(idict));
+ hr_n = read2bytes(img_file(idict));
+ hr_d = read2bytes(img_file(idict));
+ vr_e = (unsigned char) xgetc(img_file(idict));
+ hr_e = (unsigned char) xgetc(img_file(idict));
+ hr_ = ((double) hr_n / hr_d) * exp(hr_e * log(10.0)) * 0.0254;
+ vr_ = ((double) vr_n / vr_d) * exp(vr_e * log(10.0)) * 0.0254;
+ img_xres(idict) = (int) (hr_ + 0.5);
+ img_yres(idict) = (int) (vr_ + 0.5);
+}
+
+/* 1.5.3.7 Resolution box (superbox) */
+static void scan_res(image_dict * idict, unsigned long long epos_s)
+{
+ hdr_struct hdr;
+ unsigned long long spos, epos;
+ epos = xftell(img_file(idict), img_filepath(idict));
+ while (1) {
+ spos = epos;
+ hdr = read_boxhdr(idict);
+ epos = spos + hdr.lbox;
+ switch (hdr.tbox) {
+ case (BOX_RESC):
+ /* arbitrarily: let BOX_RESD have precedence */
+ if (img_xres(idict) == 0 && img_yres(idict) == 0) {
+ scan_resc_resd(idict);
+ if (xftell(img_file(idict), img_filepath(idict)) != (long)epos)
+ pdftex_fail
+ ("reading JP2 image failed (resc box size inconsistent)");
+ }
+ break;
+ case (BOX_RESD):
+ scan_resc_resd(idict);
+ if (xftell(img_file(idict), img_filepath(idict)) != (long)epos)
+ pdftex_fail
+ ("reading JP2 image failed (resd box size inconsistent)");
+ break;
+ default:;
+ }
+ if (epos > epos_s)
+ pdftex_fail("reading JP2 image failed (res box size inconsistent)");
+ if (epos == epos_s)
+ break;
+ xfseek(img_file(idict), (long) epos, SEEK_SET, img_filepath(idict));
+ }
+}
+
+/* 1.5.3 JP2 Header box (superbox) */
+static boolean scan_jp2h(image_dict * idict, unsigned long long epos_s)
+{
+ boolean ihdr_found = false;
+ hdr_struct hdr;
+ unsigned long long spos, epos;
+ epos = xftell(img_file(idict), img_filepath(idict));
+ while (1) {
+ spos = epos;
+ hdr = read_boxhdr(idict);
+ epos = spos + hdr.lbox;
+ switch (hdr.tbox) {
+ case (BOX_IHDR):
+ scan_ihdr(idict);
+ if (xftell(img_file(idict), img_filepath(idict)) != (long)epos)
+ pdftex_fail
+ ("reading JP2 image failed (ihdr box size inconsistent)");
+ ihdr_found = true;
+ break;
+ case (BOX_RES):
+ scan_res(idict, epos);
+ break;
+ default:;
+ }
+ if (epos > epos_s)
+ pdftex_fail
+ ("reading JP2 image failed (jp2h box size inconsistent)");
+ if (epos == epos_s)
+ break;
+ xfseek(img_file(idict), (long) epos, SEEK_SET, img_filepath(idict));
+ }
+ return ihdr_found;
+}
+
+static void close_and_cleanup_jp2(image_dict * idict)
+{
+ assert(idict != NULL);
+ assert(img_file(idict) != NULL);
+ assert(img_filepath(idict) != NULL);
+ xfclose(img_file(idict), img_filepath(idict));
+ img_file(idict) = NULL;
+ assert(img_jp2_ptr(idict) != NULL);
+ xfree(img_jp2_ptr(idict));
+}
+
+void read_jp2_info(image_dict * idict, img_readtype_e readtype)
+{
+ boolean ihdr_found = false;
+ hdr_struct hdr;
+ unsigned long long spos, epos;
+ assert(img_type(idict) == IMG_TYPE_JP2);
+ img_totalpages(idict) = 1;
+ img_pagenum(idict) = 1;
+ img_xres(idict) = img_yres(idict) = 0;
+ assert(img_file(idict) == NULL);
+ img_file(idict) = xfopen(img_filepath(idict), FOPEN_RBIN_MODE);
+ assert(img_jp2_ptr(idict) == NULL);
+ img_jp2_ptr(idict) = xtalloc(1, jp2_img_struct);
+ xfseek(img_file(idict), 0, SEEK_END, img_filepath(idict));
+ img_jp2_ptr(idict)->length =
+ (int) xftell(img_file(idict), img_filepath(idict));
+ xfseek(img_file(idict), 0, SEEK_SET, img_filepath(idict));
+
+ assert(sizeof(unsigned long long) >= 8);
+ spos = epos = 0;
+
+ /* 1.5.1 JPEG 2000 Signature box */
+ hdr = read_boxhdr(idict);
+ assert(hdr.tbox == BOX_JP); /* has already been checked */
+ epos = spos + hdr.lbox;
+ xfseek(img_file(idict), (long) epos, SEEK_SET, img_filepath(idict));
+
+ /* 1.5.2 File Type box */
+ spos = epos;
+ hdr = read_boxhdr(idict);
+ if (hdr.tbox != BOX_FTYP)
+ pdftex_fail("reading JP2 image failed (missing ftyp box)");
+ epos = spos + hdr.lbox;
+ xfseek(img_file(idict), (long) epos, SEEK_SET, img_filepath(idict));
+
+ while (!ihdr_found) {
+ spos = epos;
+ hdr = read_boxhdr(idict);
+ epos = spos + hdr.lbox;
+ switch (hdr.tbox) {
+ case BOX_JP2H:
+ ihdr_found = scan_jp2h(idict, epos);
+ break;
+ case BOX_JP2C:
+ if (!ihdr_found)
+ pdftex_fail("reading JP2 image failed (no ihdr box found)");
+ break;
+ default:;
+ }
+ xfseek(img_file(idict), (long) epos, SEEK_SET, img_filepath(idict));
+ }
+ if (readtype == IMG_CLOSEINBETWEEN)
+ close_and_cleanup_jp2(idict);
+}
+
+static void reopen_jp2(image_dict * idict)
+{
+ int width, height, xres, yres;
+ width = img_xsize(idict);
+ height = img_ysize(idict);
+ xres = img_xres(idict);
+ yres = img_yres(idict);
+ read_jp2_info(idict, IMG_KEEPOPEN);
+ if (width != img_xsize(idict) || height != img_ysize(idict)
+ || xres != img_xres(idict) || yres != img_yres(idict))
+ pdftex_fail("writejp2: image dimensions have changed");
+}
+
+void write_jp2(PDF pdf, image_dict * idict)
+{
+ long unsigned l;
+ FILE *f;
+ assert(idict != NULL);
+ if (img_file(idict) == NULL)
+ reopen_jp2(idict);
+ xfseek(img_file(idict), 0, SEEK_SET, img_filepath(idict));
+ assert(img_jp2_ptr(idict) != NULL);
+ pdf_puts(pdf, "/Type /XObject\n/Subtype /Image\n");
+ if (img_attr(idict) != NULL && strlen(img_attr(idict)) > 0)
+ pdf_printf(pdf, "%s\n", img_attr(idict));
+ pdf_printf(pdf, "/Width %i\n/Height %i\n/Length %i\n",
+ (int) img_xsize(idict),
+ (int) img_ysize(idict), (int) img_jp2_ptr(idict)->length);
+ pdf_puts(pdf, "/Filter /JPXDecode\n>>\nstream\n");
+ for (l = (long unsigned int) img_jp2_ptr(idict)->length, f =
+ img_file(idict); l > 0; l--)
+ pdf_out(pdf, xgetc(f));
+ pdf_end_stream(pdf);
+ close_and_cleanup_jp2(idict);
+}
diff --git a/Build/source/texk/web2c/luatexdir/image/writejpg.w b/Build/source/texk/web2c/luatexdir/image/writejpg.w
index 4f77303ce20..e7a202c54f3 100644
--- a/Build/source/texk/web2c/luatexdir/image/writejpg.w
+++ b/Build/source/texk/web2c/luatexdir/image/writejpg.w
@@ -20,8 +20,8 @@
@ @c
static const char _svn_version[] =
- "$Id: writejpg.w 3612 2010-04-13 09:29:42Z taco $ "
- "$URL: http://foundry.supelec.fr/svn/luatex/branches/0.60.x/source/texk/web2c/luatexdir/image/writejpg.w $";
+ "$Id: writejpg.w 4095 2011-03-31 21:14:27Z hhenkel $ "
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.66.0/source/texk/web2c/luatexdir/image/writejpg.w $";
#include <assert.h>
#include "ptexlib.h"
@@ -41,18 +41,18 @@ typedef enum { /* JPEG marker codes */
M_SOF5 = 0xc5, /* differential sequential DCT */
M_SOF6 = 0xc6, /* differential progressive DCT */
- M_SOF7 = 0xc7, /* differential lossless */
+ M_SOF7 = 0xc7, /* differential lossless (sequential) */
- M_JPG = 0xc8, /* JPEG extensions */
+ M_JPG = 0xc8, /* reserved for JPEG extensions */
M_SOF9 = 0xc9, /* extended sequential DCT */
M_SOF10 = 0xca, /* progressive DCT */
M_SOF11 = 0xcb, /* lossless (sequential) */
M_SOF13 = 0xcd, /* differential sequential DCT */
M_SOF14 = 0xce, /* differential progressive DCT */
- M_SOF15 = 0xcf, /* differential lossless */
+ M_SOF15 = 0xcf, /* differential lossless (sequential) */
- M_DHT = 0xc4, /* define Huffman tables */
+ M_DHT = 0xc4, /* define Huffman table(s) */
M_DAC = 0xcc, /* define arithmetic conditioning table */
@@ -101,13 +101,6 @@ typedef enum { /* JPEG marker codes */
} JPEG_MARKER;
@ @c
-static JPG_UINT16 read2bytes(FILE * f)
-{
- int c = xgetc(f);
- return (JPG_UINT16) ((c << 8) + (int) xgetc(f));
-}
-
-@ @c
static void close_and_cleanup_jpg(image_dict * idict)
{
assert(idict != NULL);
@@ -117,7 +110,6 @@ static void close_and_cleanup_jpg(image_dict * idict)
img_file(idict) = NULL;
assert(img_jpg_ptr(idict) != NULL);
xfree(img_jpg_ptr(idict));
- img_jpg_ptr(idict) = NULL;
}
@ @c
@@ -137,17 +129,17 @@ void read_jpg_info(PDF pdf, image_dict * idict, img_readtype_e readtype)
xfseek(img_file(idict), 0, SEEK_END, img_filepath(idict));
img_jpg_ptr(idict)->length = xftell(img_file(idict), img_filepath(idict));
xfseek(img_file(idict), 0, SEEK_SET, img_filepath(idict));
- if (read2bytes(img_file(idict)) != 0xFFD8)
+ if ((unsigned int) 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| */
- if (read2bytes(img_file(idict)) == 0xFFE0) { /* check for JFIF */
+ if ((unsigned int) read2bytes(img_file(idict)) == 0xFFE0) { /* check for JFIF */
(void) read2bytes(img_file(idict));
for (i = 0; i < 5; i++) {
if (xgetc(img_file(idict)) != jpg_id[i])
break;
}
if (i == 5) { /* it's JFIF */
- read2bytes(img_file(idict));
+ (void) read2bytes(img_file(idict));
units = xgetc(img_file(idict));
img_xres(idict) = (int) read2bytes(img_file(idict));
img_yres(idict) = (int) read2bytes(img_file(idict));
@@ -177,23 +169,25 @@ void read_jpg_info(PDF pdf, image_dict * idict, img_readtype_e readtype)
pdftex_fail("reading JPEG image failed (premature file end)");
if (fgetc(img_file(idict)) != 0xFF)
pdftex_fail("reading JPEG image failed (no marker found)");
- switch (xgetc(img_file(idict))) {
+ i = xgetc(img_file(idict));
+ switch (i) {
+ case M_SOF3: /* lossless */
case M_SOF5:
case M_SOF6:
- case M_SOF7:
+ case M_SOF7: /* lossless */
case M_SOF9:
case M_SOF10:
- case M_SOF11:
+ case M_SOF11: /* lossless */
case M_SOF13:
case M_SOF14:
- case M_SOF15:
- pdftex_fail("unsupported type of compression");
+ case M_SOF15: /* lossless */
+ pdftex_fail("unsupported type of compression (SOF_%d)", i - M_SOF0);
+ break;
case M_SOF2:
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) = (int) read2bytes(img_file(idict));
@@ -230,7 +224,7 @@ void read_jpg_info(PDF pdf, image_dict * idict, img_readtype_e readtype)
case M_RST7:
break;
default: /* skip variable length markers */
- xfseek(img_file(idict), read2bytes(img_file(idict)) - 2,
+ xfseek(img_file(idict), (int) read2bytes(img_file(idict)) - 2,
SEEK_CUR, img_filepath(idict));
break;
}
diff --git a/Build/source/texk/web2c/luatexdir/image/writepng.w b/Build/source/texk/web2c/luatexdir/image/writepng.w
index fbe80259a63..7d497deea0e 100644
--- a/Build/source/texk/web2c/luatexdir/image/writepng.w
+++ b/Build/source/texk/web2c/luatexdir/image/writepng.w
@@ -20,8 +20,8 @@
@ @c
static const char _svn_version[] =
- "$Id: writepng.w 3612 2010-04-13 09:29:42Z taco $ "
- "$URL: http://foundry.supelec.fr/svn/luatex/branches/0.60.x/source/texk/web2c/luatexdir/image/writepng.w $";
+ "$Id: writepng.w 4133 2011-04-11 16:54:11Z oneiros $ "
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.66.0/source/texk/web2c/luatexdir/image/writepng.w $";
#include <assert.h>
#include "ptexlib.h"
@@ -42,7 +42,6 @@ static void close_and_cleanup_png(image_dict * idict)
png_destroy_read_struct(&(img_png_png_ptr(idict)),
&(img_png_info_ptr(idict)), NULL);
xfree(img_png_ptr(idict));
- img_png_ptr(idict) = NULL;
}
@ @c
@@ -115,7 +114,7 @@ void read_png_info(PDF pdf, image_dict * idict, img_readtype_e readtype)
img_procset(idict) |= PROCSET_IMAGE_C;
break;
default:
- pdftex_fail("unsupported type of color_type <%i>", png_get_color_type(png_p, info_p));
+ pdftex_fail("unsupported type of color_type <%i>", (int)png_get_color_type (png_p, info_p));
}
img_colordepth(idict) = png_get_bit_depth(png_p, info_p);
if (readtype == IMG_CLOSEINBETWEEN)
@@ -187,10 +186,9 @@ static void write_png_palette(PDF pdf, image_dict * idict)
if (img_colorspace(idict) != 0) {
pdf_printf(pdf, "%i 0 R\n", (int) img_colorspace(idict));
} else {
- pdf_create_obj(pdf, obj_type_others, 0);
- palette_objnum = pdf->obj_ptr;
+ palette_objnum = pdf_create_obj(pdf, obj_type_others, 0);
pdf_printf(pdf, "[/Indexed /DeviceRGB %i %i 0 R]\n",
- num_palette - 1, (int) palette_objnum);
+ (int) (num_palette - 1), (int) palette_objnum);
}
pdf_begin_stream(pdf);
if (png_get_interlace_type(png_p, info_p) == PNG_INTERLACE_NONE) {
@@ -212,7 +210,7 @@ static void write_png_palette(PDF pdf, image_dict * idict)
if (palette_objnum > 0) {
pdf_begin_dict(pdf, palette_objnum, 0);
pdf_begin_stream(pdf);
- for (i = 0; (unsigned) i < num_palette; i++) {
+ for (i = 0; i < num_palette; i++) {
pdf_room(pdf, 3);
pdf_quick_out(pdf, palette[i].red);
pdf_quick_out(pdf, palette[i].green);
@@ -264,14 +262,13 @@ static void write_png_gray_alpha(PDF pdf, image_dict * idict)
png_bytep smask;
int smask_ptr = 0;
int smask_size = 0;
- int bitdepth;
+ png_byte bitdepth;
if (img_colorspace(idict) != 0) {
pdf_printf(pdf, "%i 0 R\n", (int) img_colorspace(idict));
} else {
pdf_puts(pdf, "/DeviceGray\n");
}
- pdf_create_obj(pdf, obj_type_others, 0);
- smask_objnum = pdf->obj_ptr;
+ smask_objnum = pdf_create_obj(pdf, obj_type_others, 0);
pdf_printf(pdf, "/SMask %i 0 R\n", (int) smask_objnum);
smask_size = (int) ((png_get_rowbytes(png_p, info_p) / 2) * png_get_image_height (png_p, info_p));
smask = xtalloc((unsigned) smask_size, png_byte);
@@ -302,7 +299,7 @@ static void write_png_gray_alpha(PDF pdf, image_dict * idict)
pdf_end_stream(pdf);
pdf_flush(pdf);
/* now write the Smask object */
- bitdepth = (int) png_get_bit_depth(png_p, info_p);
+ bitdepth = png_get_bit_depth (png_p, info_p);
pdf_begin_dict(pdf, smask_objnum, 0);
pdf_puts(pdf, "/Type /XObject\n/Subtype /Image\n");
if (img_attr(idict) != NULL && strlen(img_attr(idict)) > 0)
@@ -366,16 +363,15 @@ static void write_png_rgb_alpha(PDF pdf, image_dict * idict)
png_bytep smask;
int smask_ptr = 0;
int smask_size = 0;
- int bitdepth;
+ png_byte bitdepth;
if (img_colorspace(idict) != 0) {
pdf_printf(pdf, "%i 0 R\n", (int) img_colorspace(idict));
} else {
pdf_puts(pdf, "/DeviceRGB\n");
}
- pdf_create_obj(pdf, obj_type_others, 0);
- smask_objnum = pdf->obj_ptr;
+ smask_objnum = pdf_create_obj(pdf, obj_type_others, 0);
pdf_printf(pdf, "/SMask %i 0 R\n", (int) smask_objnum);
- smask_size = (int) ((png_get_rowbytes(png_p, info_p) / 2) * png_get_image_height (png_p, info_p));
+ smask_size = (int) ((png_get_rowbytes (png_p, info_p) / 4) * png_get_image_height (png_p, info_p));
smask = xtalloc((unsigned) smask_size, png_byte);
pdf_begin_stream(pdf);
if (png_get_interlace_type(png_p, info_p) == PNG_INTERLACE_NONE) {
@@ -405,7 +401,7 @@ static void write_png_rgb_alpha(PDF pdf, image_dict * idict)
pdf_flush(pdf);
/* now write the Smask object */
if (smask_objnum > 0) {
- bitdepth = (int) png_get_bit_depth(png_p, info_p);
+ bitdepth = png_get_bit_depth (png_p, info_p);
pdf_begin_dict(pdf, smask_objnum, 0);
pdf_puts(pdf, "/Type /XObject\n/Subtype /Image\n");
if (img_attr(idict) != NULL && strlen(img_attr(idict)) > 0)
@@ -483,12 +479,12 @@ static void copy_png(PDF pdf, image_dict * idict)
"/Filter/FlateDecode\n"
"/DecodeParms<<"
"/Colors %d"
- "/Columns %d"
+ "/Columns %u"
"/BitsPerComponent %i"
"/Predictor 10>>\n>>\nstream\n", streamlength,
- png_get_color_type(png_p, info_p) == 2 ? 3 : 1,
- (int) png_get_image_width (png_p, info_p),
- png_get_bit_depth(png_p, info_p));
+ png_get_color_type (png_p, info_p) == 2 ? 3 : 1,
+ png_get_image_width (png_p, info_p),
+ png_get_bit_depth (png_p, info_p));
/* 2nd pass to copy data */
endflag = false;
if (fseek(fp, 8, SEEK_SET) != 0)
@@ -575,10 +571,12 @@ void write_png(PDF pdf, image_dict * idict)
}
/* the switching between |info_p| and |png_p| queries has been trial and error.
*/
- if (pdf->minor_version > 1 && png_get_interlace_type(png_p, info_p) == PNG_INTERLACE_NONE
- &&!(png_get_color_type(png_p, info_p) == PNG_COLOR_TYPE_GRAY_ALPHA ||
- png_get_color_type(png_p, info_p) == PNG_COLOR_TYPE_RGB_ALPHA)
- && ((pdf->image_hicolor != 0) || (png_get_bit_depth(png_p, info_p) <= 8))
+ if (pdf->minor_version > 1
+ && png_get_interlace_type (png_p, info_p) == PNG_INTERLACE_NONE
+ && (png_p->transformations == 0 || png_p->transformations == 0x2000) /* gamma */
+ &&!(png_get_color_type (png_p, info_p) == PNG_COLOR_TYPE_GRAY_ALPHA ||
+ png_get_color_type (png_p, info_p) == PNG_COLOR_TYPE_RGB_ALPHA)
+ && ((pdf->image_hicolor != 0) || (png_get_bit_depth (png_p, info_p) <= 8))
&& (checked_gamma <= 1.01 && checked_gamma > 0.99)
) {
png_colorp palette;
@@ -590,8 +588,7 @@ void write_png(PDF pdf, image_dict * idict)
} else {
switch (png_get_color_type(png_p, info_p)) {
case PNG_COLOR_TYPE_PALETTE:
- pdf_create_obj(pdf, obj_type_others, 0);
- palette_objnum = pdf->obj_ptr;
+ palette_objnum = pdf_create_obj(pdf, obj_type_others, 0);
pdf_printf(pdf, "[/Indexed /DeviceRGB %i %i 0 R]\n",
num_palette - 1, (int) palette_objnum);
break;
@@ -608,7 +605,7 @@ void write_png(PDF pdf, image_dict * idict)
if (palette_objnum > 0) {
pdf_begin_dict(pdf, palette_objnum, 0);
pdf_begin_stream(pdf);
- for (i = 0; (unsigned) i < num_palette; i++) {
+ for (i = 0; i < num_palette; i++) {
pdf_room(pdf, 3);
pdf_quick_out(pdf, palette[i].red);
pdf_quick_out(pdf, palette[i].green);
@@ -622,9 +619,11 @@ void write_png(PDF pdf, image_dict * idict)
if ((pdf->image_apply_gamma != 0) &&
(checked_gamma > 1.01 || checked_gamma < 0.99))
tex_printf("gamma delta=%lf ", checked_gamma);
- if ((png_get_color_type(png_p, info_p) != PNG_COLOR_TYPE_GRAY)
- && (png_get_color_type(png_p, info_p) != PNG_COLOR_TYPE_RGB)
- && (png_get_color_type(png_p, info_p) != PNG_COLOR_TYPE_PALETTE))
+ if (png_p->transformations != PNG_TRANSFORM_IDENTITY)
+ tex_printf("transform=%lu", (long) png_p->transformations);
+ if ((png_get_color_type (png_p, info_p) != PNG_COLOR_TYPE_GRAY)
+ && (png_get_color_type (png_p, info_p) != PNG_COLOR_TYPE_RGB)
+ && (png_get_color_type (png_p, info_p) != PNG_COLOR_TYPE_PALETTE))
tex_printf("colortype ");
if (pdf->minor_version <= 1)
tex_printf("version=%d ", pdf->minor_version);