summaryrefslogtreecommitdiff
path: root/Build/source/texk/web2c/luatexdir/image/writeimg.w
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/web2c/luatexdir/image/writeimg.w')
-rw-r--r--Build/source/texk/web2c/luatexdir/image/writeimg.w408
1 files changed, 126 insertions, 282 deletions
diff --git a/Build/source/texk/web2c/luatexdir/image/writeimg.w b/Build/source/texk/web2c/luatexdir/image/writeimg.w
index ff667cfe62e..c002b56dca9 100644
--- a/Build/source/texk/web2c/luatexdir/image/writeimg.w
+++ b/Build/source/texk/web2c/luatexdir/image/writeimg.w
@@ -21,8 +21,6 @@
@* Image inclusion.
@ @c
-
-
#include "ptexlib.h"
#include <assert.h>
#include <kpathsea/c-auto.h>
@@ -40,78 +38,63 @@
@* 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.
+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|.
- 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:
- Magic headers:
+* "PNG (Portable Network Graphics) Specification", Version 1.2
+ (http://www.libpng.org/pub/png):
- * "PNG (Portable Network Graphics) Specification", Version 1.2
- (http://www.libpng.org/pub/png):
+ 3.1. PNG file signature
- 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
- The first eight bytes of a PNG file always contain the following
- (decimal) values:
+Translation to C: |"\x89PNG\r\n\x1A\n"|
- 137 80 78 71 13 10 26 10
+* "JPEG File Interchange Format", Version 1.02:
- Translation to C: |"\x89PNG\r\n\x1A\n"|
+ * 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'.
- * "JPEG File Interchange Format", Version 1.02:
+Function |check_type_by_header| only looks at the first two bytes: |"\xFF\xD8"|
- 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'.
+* 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
- Function |check_type_by_header| only looks at the first two bytes:
- |"\xFF\xD8"|
+ D.4.1, ID string
- * 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
+ This is an 8-byte sequence containing 0x97 0x4A 0x42 0x32 0x0D 0x0A 0x1A 0x0A.
- D.4.1, ID string
+* "PDF Reference", third edition:
- This is an 8-byte sequence containing 0x97 0x4A 0x42 0x32 0x0D 0x0A
- 0x1A 0x0A.
+ * The first line should contain \%PDF-1.0 -- \%PDF-1.4 (section 3.4.1 "File Header").
+ * The "implementation notes" say:
- * "PDF Reference", third edition:
+ 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 first line should contain "\%PDF-1.0" until "\%PDF-1.4"
- (section 3.4.1 "File Header").
- * The "implementation notes" say:
+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.
- 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.
+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"
@@ -121,8 +104,7 @@
#define HEADER_PDF "%PDF-1."
#define MAX_HEADER (sizeof(HEADER_PNG)-1)
#define HEADER_PDF_MEMSTREAM "data:application/pdf," /* see epdf.h */
-#define LEN_PDF_MEMSTREAM 21 /* see epdf.h */
-
+#define LEN_PDF_MEMSTREAM 21 /* see epdf.h */
static void check_type_by_header(image_dict * idict)
{
@@ -132,17 +114,13 @@ static void check_type_by_header(image_dict * idict)
char prefix[LEN_PDF_MEMSTREAM+1];
assert(idict != NULL);
- if (img_type(idict) != IMG_TYPE_NONE) /* nothing to do */
+ if (img_type(idict) != IMG_TYPE_NONE)
return;
-
- /* read the header */
- /* Like */
- /* file = xfopen(img_filepath(idict), FOPEN_RBIN_MODE);*/
- /* but we also check for a memstream object */
+ /* here we read the and also check for a memstream object */
assert(img_filepath(idict) && FOPEN_RBIN_MODE);
file = fopen(img_filepath(idict), FOPEN_RBIN_MODE);
if (file == NULL) {
- /* check the prefix of img_filepath(idict) */
+ /* check the prefix of img_filepath(idict) */
for (i = 0; (unsigned) i < LEN_PDF_MEMSTREAM; i++) {
prefix[i] = (char) (img_filepath(idict)[i]);
}
@@ -158,7 +136,7 @@ static void check_type_by_header(image_dict * idict)
for (i = 0; (unsigned) i < MAX_HEADER; i++) {
header[i] = (char) xgetc(file);
if (feof(file))
- luatex_fail("reading image file failed");
+ normal_error("pdf backend","reading image file failed");
}
xfclose(file, img_filepath(idict));
/* tests */
@@ -178,8 +156,8 @@ static void check_type_by_header(image_dict * idict)
static void check_type_by_extension(image_dict * idict)
{
char *image_suffix;
-
- assert(idict != NULL);
+ if (idict != NULL)
+ return;
if (img_type(idict) != IMG_TYPE_NONE) /* nothing to do */
return;
/* tests */
@@ -209,28 +187,22 @@ void new_img_pdfstream_struct(image_dict * p)
}
@ @c
-static void init_image(image * p)
+image *new_image(void)
{
- assert(p != NULL);
+ image *p = xtalloc(1, image);
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)
+image_dict *new_image_dict(void)
{
+ image_dict *p = xtalloc(1, image_dict);
assert(p != NULL);
memset(p, 0, sizeof(image_dict));
set_wd_running(p);
@@ -243,14 +215,11 @@ static void init_image_dict(image_dict * p)
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);
+ img_index(p) = -1; /* -1 = unused, used count from 0 */
+ img_luaref(p) = 0;
+ img_errorlevel(p) = pdf_inclusion_errorlevel;
+ fix_pdf_minorversion(static_pdf);
+ img_pdfminorversion(p) = pdf_minor_version;
return p;
}
@@ -271,31 +240,33 @@ void free_image_dict(image_dict * p)
/* called from limglib.c */
assert(img_state(p) < DICT_REFERED);
switch (img_type(p)) {
- case IMG_TYPE_PDFMEMSTREAM:
- 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_JP2: /* */
- assert(img_jp2_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);
+ case IMG_TYPE_PDFMEMSTREAM:
+ case IMG_TYPE_PDF:
+ flush_pdf_info(p);
+ break;
+ case IMG_TYPE_PNG:
+ flush_png_info(p);
+ break;
+ case IMG_TYPE_JPG:
+ flush_jpg_info(p);
+ break;
+ case IMG_TYPE_JP2:
+ flush_jp2_info(p);
+ break;
+ case IMG_TYPE_JBIG2:
+ flush_jbig2_info(p);
+ break;
+ case IMG_TYPE_PDFSTREAM:
+ /* flush_pdfstream_info(p); */
+ 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);
@@ -303,14 +274,13 @@ void free_image_dict(image_dict * p)
}
@ @c
-void read_img(PDF pdf,
- image_dict * idict, int minor_version, int inclusion_errorlevel)
+void read_img(image_dict * idict)
{
char *filepath = NULL;
int callback_id;
assert(idict != NULL);
if (img_filename(idict) == NULL) {
- luatex_fail("image file name missing");
+ normal_error("pdf backend","image file name missing");
}
callback_id = callback_defined(find_image_file_callback);
if (img_filepath(idict) == NULL) {
@@ -324,7 +294,7 @@ void read_img(PDF pdf,
img_filepath(idict) = kpse_find_file(img_filename(idict), kpse_tex_format, true);
}
if (img_filepath(idict) == NULL) {
- luatex_fail("cannot find image file '%s'", img_filename(idict));
+ formatted_error("pdf backend","cannot find image file '%s'", img_filename(idict));
}
}
recorder_record_input(img_filename(idict));
@@ -333,31 +303,24 @@ void read_img(PDF pdf,
check_type_by_extension(idict);
/* read image */
switch (img_type(idict)) {
- case IMG_TYPE_PDFMEMSTREAM:
- 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(idict, IMG_CLOSEINBETWEEN);
- break;
- 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) {
- luatex_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:
- luatex_fail("internal error: unknown image type (2)");
+ case IMG_TYPE_PDFMEMSTREAM:
+ case IMG_TYPE_PDF:
+ read_pdf_info(idict);
+ break;
+ case IMG_TYPE_PNG:
+ read_png_info(idict);
+ break;
+ case IMG_TYPE_JPG:
+ read_jpg_info(idict);
+ break;
+ case IMG_TYPE_JP2:
+ read_jp2_info(idict);
+ break;
+ case IMG_TYPE_JBIG2:
+ read_jbig2_info(idict);
+ break;
+ default:
+ normal_error("pdf backend","internal error: unknown image type");
}
cur_file_name = NULL;
if (img_state(idict) < DICT_FILESCANNED)
@@ -365,17 +328,14 @@ void read_img(PDF pdf,
}
@ @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)
+static image_dict *read_image(char *file_name, int page_num, char *page_name, int colorspace, int page_box)
{
image *a = new_image();
image_dict *idict = img_dict(a) = new_image_dict();
- 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));
+ static_pdf->ximage_count++;
+ img_objnum(idict) = pdf_create_obj(static_pdf, obj_type_ximage, static_pdf->ximage_count);
+ img_index(idict) = static_pdf->ximage_count;
+ set_obj_data_ptr(static_pdf, img_objnum(idict), img_index(idict));
idict_to_array(idict);
img_colorspace(idict) = colorspace;
img_pagenum(idict) = page_num;
@@ -384,7 +344,7 @@ static image_dict *read_image(PDF pdf, char *file_name, int page_num,
cur_file_name = file_name;
img_filename(idict) = file_name;
img_pagebox(idict) = page_box;
- read_img(pdf, idict, minor_version, inclusion_errorlevel);
+ read_img(idict);
return idict;
}
@@ -402,11 +362,12 @@ static pdfboxspec_e scan_pdf_box_spec(void)
return PDF_BOX_SPEC_TRIM;
else if (scan_keyword("artbox"))
return PDF_BOX_SPEC_ART;
- return PDF_BOX_SPEC_NONE;
+ else
+ return PDF_BOX_SPEC_NONE;
}
@ @c
-void scan_pdfximage(PDF pdf)
+void scan_pdfximage(PDF pdf) /* static_pdf */
{
scaled_whd alt_rule;
image_dict *idict;
@@ -414,12 +375,12 @@ void scan_pdfximage(PDF pdf)
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();
+ scan_toks(false, true);
attr = tokenlist_to_cstring(def_ref, true, NULL);
delete_token_ref(def_ref);
}
if (scan_keyword("named")) {
- scan_pdf_ext_toks();
+ scan_toks(false, true);
named = tokenlist_to_cstring(def_ref, true, NULL);
delete_token_ref(def_ref);
page = 0;
@@ -437,13 +398,11 @@ void scan_pdfximage(PDF pdf)
if (pagebox == PDF_BOX_SPEC_NONE)
pagebox = PDF_BOX_SPEC_CROP;
}
- scan_pdf_ext_toks();
+ scan_toks(false, true);
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);
+ idict = read_image(file_name, page, named, colorspace, pagebox);
img_attr(idict) = attr;
img_dimen(idict) = alt_rule;
img_transform(idict) = transform;
@@ -452,7 +411,7 @@ void scan_pdfximage(PDF pdf)
}
@ @c
-#define tail cur_list.tail_field
+#define tail cur_list.tail_field
void scan_pdfrefximage(PDF pdf)
{
@@ -559,11 +518,11 @@ scaled_whd scale_img(image_dict * idict, scaled_whd alt_rule, int transform)
xr = img_xres(idict);
yr = img_yres(idict);
if (x <= 0 || y <= 0 || xr < 0 || yr < 0)
- luatex_fail("ext1: invalid image dimensions");
+ normal_error("pdf backend","invalid image dimensions");
if (xr > 65535 || yr > 65535) {
xr = 0;
yr = 0;
- luatex_warn("ext1: too large image resolution ignored");
+ normal_warning("pdf backend","too large image resolution ignored");
}
if (((transform - img_rotation(idict)) & 1) == 1) {
tmp = x;
@@ -622,7 +581,7 @@ void write_img(PDF pdf, image_dict * idict)
write_pdfstream(pdf, idict);
break;
default:
- luatex_fail("internal error: unknown image type (1)");
+ normal_error("pdf backend","internal error: unknown image type");
}
report_stop_file(filetype_image);
if (img_type(idict) == IMG_TYPE_PNG) {
@@ -645,7 +604,7 @@ void pdf_write_image(PDF pdf, int n)
void check_pdfstream_dict(image_dict * idict)
{
if (!img_is_bbox(idict))
- luatex_fail("image.stream: no bbox given");
+ normal_error("pdf backend","image.stream: no bbox given");
if (img_state(idict) < DICT_FILESCANNED)
img_state(idict) = DICT_FILESCANNED;
}
@@ -679,7 +638,6 @@ void write_pdfstream(PDF pdf, image_dict * idict)
}
@ @c
-/* define |idict_ptr|, |idict_array|, and |idict_limit| */
idict_entry *idict_ptr, *idict_array = NULL;
size_t idict_limit;
@@ -721,6 +679,8 @@ void pdf_dict_add_img_filename(PDF pdf, image_dict * idict)
}
}
+/* hh: why store images in the format ... let's get rid of this */
+
@ To allow the use of box resources 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.
@@ -731,8 +691,7 @@ 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.
+|readimage()| and dump time.
some of the dumped values are really type int, not integer,
but since the macro falls back to |generic_dump| anyway, that
@@ -746,121 +705,6 @@ does not matter.
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)|| (img_type(idict) == IMG_TYPE_PDFMEMSTREAM)) {
- 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_PDFMEMSTREAM:
- case IMG_TYPE_PDF:
- undumpinteger(img_pagebox(idict));
- undumpinteger(img_pagenum(idict));
- break;
- case IMG_TYPE_PNG:
- case IMG_TYPE_JPG:
- case IMG_TYPE_JP2:
- break;
- case IMG_TYPE_JBIG2:
- if (pdfversion < 4) {
- luatex_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:
- luatex_fail("unknown type of image");
- }
- read_img(pdf, idict, pdfversion, pdfinclusionerrorlevel);
- }
-}
-
@ scan rule spec to |alt_rule|
@c
scaled_whd scan_alt_rule(void)