diff options
Diffstat (limited to 'Build/source/texk/web2c/luatexdir/image/writeimg.w')
-rw-r--r-- | Build/source/texk/web2c/luatexdir/image/writeimg.w | 408 |
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) |