diff options
Diffstat (limited to 'Build/source/texk/web2c/luatexdir/image/writeimg.w')
-rw-r--r-- | Build/source/texk/web2c/luatexdir/image/writeimg.w | 823 |
1 files changed, 823 insertions, 0 deletions
diff --git a/Build/source/texk/web2c/luatexdir/image/writeimg.w b/Build/source/texk/web2c/luatexdir/image/writeimg.w new file mode 100644 index 00000000000..a6b03ee4290 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/image/writeimg.w @@ -0,0 +1,823 @@ +% writeimg.w + +% Copyright 1996-2006 Han The Thanh <thanh@@pdftex.org> +% Copyright 2006-2010 Taco Hoekwater <taco@@luatex.org> + +% This file is part of LuaTeX. + +% LuaTeX is free software; you can redistribute it and/or modify it under +% the terms of the GNU General Public License as published by the Free +% Software Foundation; either version 2 of the License, or (at your +% option) any later version. + +% LuaTeX is distributed in the hope that it will be useful, but WITHOUT +% ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +% FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +% License for more details. + +% You should have received a copy of the GNU General Public License along +% with LuaTeX; if not, see <http://www.gnu.org/licenses/>. + +@* Image inclusion. + +@ @c +static const char _svn_version[] = + "$Id: writeimg.w 3584 2010-04-02 17:45:55Z hhenkel $ " + "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/image/writeimg.w $"; + +#include <assert.h> +#include "ptexlib.h" +#include <kpathsea/c-auto.h> +#include <kpathsea/c-memstr.h> + +@ @c +#include "image/image.h" +#include "image/writejpg.h" +#include "image/writepng.h" +#include "image/writejbig2.h" + +#include "lua51/lua.h" /* for |LUA_NOREF| */ +#include "lua51/lauxlib.h" + +@ @c +#define pdf_image_resolution int_par(pdf_image_resolution_code) +#define pdf_pagebox int_par(pdf_pagebox_code) + +@* Patch ImageTypeDetection 2003/02/08 by Heiko Oberdiek. + + Function |readimage| performs some basic initializations. + Then it looks at the file extension to determine the + image type and calls specific code/functions. + + The main disadvantage is that standard file extensions + have to be used, otherwise pdfTeX is not able to detect + the correct image type. + + The patch now looks at the file header first regardless of + the file extension. This is implemented in function + |check_type_by_header|. If this check fails, the traditional + test of standard file extension is tried, done in function + |check_type_by_extension|. + + Magic headers: + + * "PNG (Portable Network Graphics) Specification", Version 1.2 + (http://www.libpng.org/pub/png): + + 3.1. PNG file signature + + The first eight bytes of a PNG file always contain the following + (decimal) values: + + 137 80 78 71 13 10 26 10 + + Translation to C: |"\x89PNG\r\n\x1A\n"| + + * "JPEG File Interchange Format", Version 1.02: + + o you can identify a JFIF file by looking for the following + sequence: X'FF', SOI X'FF', APP0, <2 bytes to be skipped>, + "JFIF", X'00'. + + Function |check_type_by_header| only looks at the first two bytes: + |"\xFF\xD8"| + + * ISO/IEC JTC 1/SC 29/WG 1 + (ITU-T SG8) + Coding of Still Pictures + Title: 14492 FCD + Source: JBIG Committee + Project: JTC 1.29.10 + Status: Final Committee Draft + + D.4.1, ID string + + This is an 8-byte sequence containing 0x97 0x4A 0x42 0x32 0x0D 0x0A + 0x1A 0x0A. + + * "PDF Reference", third edition: + + * The first line should contain "\%PDF-1.0" until "\%PDF-1.4" + (section 3.4.1 "File Header"). + * The "implementation notes" say: + + 3.4.1, File Header + 12. Acrobat viewers require only that the header appear + somewhere within the first 1024 bytes of the file. + 13. Acrobat viewers will also accept a header of the form + \%!PS-Adobe-N.n PDF-M.m + + The check in function |check_type_by_header| only implements + the first issue. The implementation notes are not considered. + Therefore files with garbage at start of file must have the + standard extension. + + Functions |check_type_by_header| and |check_type_by_extension|: + |img_type(img)| is set to |IMG_TYPE_NONE| by |new_image_dict()|. + Both functions try to detect a type and set |img_type(img)|. + Thus a value other than |IMG_TYPE_NONE| indicates that a + type has been found. + +@c +#define HEADER_JPG "\xFF\xD8" +#define HEADER_PNG "\x89PNG\r\n\x1A\n" +#define HEADER_JBIG2 "\x97\x4A\x42\x32\x0D\x0A\x1A\x0A" +#define HEADER_PDF "%PDF-1." +#define MAX_HEADER (sizeof(HEADER_PNG)-1) + +static void check_type_by_header(image_dict * idict) +{ + int i; + FILE *file = NULL; + char header[MAX_HEADER]; + + assert(idict != NULL); + if (img_type(idict) != IMG_TYPE_NONE) /* nothing to do */ + return; + /* read the header */ + file = xfopen(img_filepath(idict), FOPEN_RBIN_MODE); + for (i = 0; (unsigned) i < MAX_HEADER; i++) { + header[i] = (char) xgetc(file); + if (feof(file)) + pdftex_fail("reading image file failed"); + } + xfclose(file, img_filepath(idict)); + /* tests */ + if (strncmp(header, HEADER_JPG, sizeof(HEADER_JPG) - 1) == 0) + img_type(idict) = IMG_TYPE_JPG; + else if (strncmp(header, HEADER_PNG, sizeof(HEADER_PNG) - 1) == 0) + img_type(idict) = IMG_TYPE_PNG; + else if (strncmp(header, HEADER_JBIG2, sizeof(HEADER_JBIG2) - 1) == 0) + img_type(idict) = IMG_TYPE_JBIG2; + else if (strncmp(header, HEADER_PDF, sizeof(HEADER_PDF) - 1) == 0) + img_type(idict) = IMG_TYPE_PDF; +} + +@ @c +static void check_type_by_extension(image_dict * idict) +{ + char *image_suffix; + + assert(idict != NULL); + if (img_type(idict) != IMG_TYPE_NONE) /* nothing to do */ + return; + /* tests */ + if ((image_suffix = strrchr(img_filename(idict), '.')) == 0) + img_type(idict) = IMG_TYPE_NONE; + else if (strcasecmp(image_suffix, ".png") == 0) + img_type(idict) = IMG_TYPE_PNG; + else if (strcasecmp(image_suffix, ".jpg") == 0 || + strcasecmp(image_suffix, ".jpeg") == 0) + img_type(idict) = IMG_TYPE_JPG; + else if (strcasecmp(image_suffix, ".jbig2") == 0 || + strcasecmp(image_suffix, ".jb2") == 0) + img_type(idict) = IMG_TYPE_JBIG2; + else if (strcasecmp(image_suffix, ".pdf") == 0) + img_type(idict) = IMG_TYPE_PDF; +} + +@ @c +void new_img_pdfstream_struct(image_dict * p) +{ + assert(p != NULL); + assert(img_pdfstream_ptr(p) == NULL); + img_pdfstream_ptr(p) = xtalloc(1, pdf_stream_struct); + img_pdfstream_stream(p) = NULL; +} + +@ @c +static void init_image(image * p) +{ + assert(p != NULL); + set_wd_running(p); + set_ht_running(p); + set_dp_running(p); + img_transform(p) = 0; + img_dict(p) = NULL; + img_dictref(p) = LUA_NOREF; +} + +@ @c +image *new_image(void) +{ + image *p = xtalloc(1, image); + init_image(p); + return p; +} + +@ @c +static void init_image_dict(image_dict * p) +{ + assert(p != NULL); + memset(p, 0, sizeof(image_dict)); + set_wd_running(p); + set_ht_running(p); + set_dp_running(p); + img_transform(p) = 0; + img_pagenum(p) = 1; + img_type(p) = IMG_TYPE_NONE; + img_pagebox(p) = PDF_BOX_SPEC_MEDIA; + img_unset_bbox(p); + img_unset_group(p); + img_state(p) = DICT_NEW; + img_index(p) = -1; /* -1 = unused, used count from 0 */ +} + +@ @c +image_dict *new_image_dict(void) +{ + image_dict *p = xtalloc(1, image_dict); + init_image_dict(p); + return p; +} + +@ @c +static void free_dict_strings(image_dict * p) +{ + xfree(img_filename(p)); + xfree(img_filepath(p)); + xfree(img_attr(p)); + xfree(img_pagename(p)); +} + +@ @c +void free_image_dict(image_dict * p) +{ + if (ini_version) + return; /* The image may be \.{\\dump}ed to a format */ + /* called from limglib.c */ + assert(img_state(p) < DICT_REFERED); + switch (img_type(p)) { + case IMG_TYPE_PDF: + unrefPdfDocument(img_filepath(p)); + break; + case IMG_TYPE_PNG: /* assuming |IMG_CLOSEINBETWEEN| */ + assert(img_png_ptr(p) == NULL); + break; + case IMG_TYPE_JPG: /* assuming |IMG_CLOSEINBETWEEN| */ + assert(img_jpg_ptr(p) == NULL); + break; + case IMG_TYPE_JBIG2: /* todo: writejbig2.w cleanup */ + break; + case IMG_TYPE_PDFSTREAM: + if (img_pdfstream_ptr(p) != NULL) { + xfree(img_pdfstream_stream(p)); + xfree(img_pdfstream_ptr(p)); + } + break; + case IMG_TYPE_NONE: + break; + default: + assert(0); + } + free_dict_strings(p); + assert(img_file(p) == NULL); + xfree(p); +} + +@ @c +void read_img(PDF pdf, + image_dict * idict, int minor_version, int inclusion_errorlevel) +{ + char *filepath; + int callback_id; + assert(idict != NULL); + if (img_filename(idict) == NULL) + pdftex_fail("image file name missing"); + callback_id = callback_defined(find_image_file_callback); + if (img_filepath(idict) == NULL) { + if (callback_id > 0 + && run_callback(callback_id, "S->S", img_filename(idict), + &filepath)) { + if (filepath && (strlen(filepath) > 0)) + img_filepath(idict) = strdup(filepath); + } else + img_filepath(idict) = + kpse_find_file(img_filename(idict), kpse_tex_format, true); + if (img_filepath(idict) == NULL) + pdftex_fail("cannot find image file"); + } + recorder_record_input(img_filename(idict)); + /* type checks */ + check_type_by_header(idict); + check_type_by_extension(idict); + /* read image */ + switch (img_type(idict)) { + case IMG_TYPE_PDF: + assert(pdf != NULL); /* TODO! */ + read_pdf_info(idict, minor_version, inclusion_errorlevel, + IMG_CLOSEINBETWEEN); + break; + case IMG_TYPE_PNG: + read_png_info(pdf, idict, IMG_CLOSEINBETWEEN); + break; + case IMG_TYPE_JPG: + read_jpg_info(pdf, idict, IMG_CLOSEINBETWEEN); + break; + case IMG_TYPE_JBIG2: + if (minor_version < 4) { + pdftex_fail + ("JBIG2 images only possible with at least PDF 1.4; you are generating PDF 1.%i", + (int) minor_version); + } + read_jbig2_info(idict); + break; + default: + pdftex_fail("internal error: unknown image type (2)"); + } + cur_file_name = NULL; + if (img_state(idict) < DICT_FILESCANNED) + img_state(idict) = DICT_FILESCANNED; +} + +@ @c +static image_dict *read_image(PDF pdf, char *file_name, int page_num, + char *page_name, int colorspace, + int page_box, int minor_version, + int inclusion_errorlevel) +{ + image *a = new_image(); + image_dict *idict = img_dict(a) = new_image_dict(); + incr(pdf->ximage_count); + pdf_create_obj(pdf, obj_type_ximage, pdf->ximage_count); + img_objnum(idict) = pdf->obj_ptr; + img_index(idict) = pdf->ximage_count; + set_obj_data_ptr(pdf, img_objnum(idict), img_index(idict)); + idict_to_array(idict); + img_colorspace(idict) = colorspace; + img_pagenum(idict) = page_num; + img_pagename(idict) = page_name; + assert(file_name != NULL); + cur_file_name = file_name; + img_filename(idict) = file_name; + img_pagebox(idict) = page_box; + read_img(pdf, idict, minor_version, inclusion_errorlevel); + return idict; +} + +@ scans PDF pagebox specification +@c +static pdfboxspec_e scan_pdf_box_spec(void) +{ + if (scan_keyword("mediabox")) + return PDF_BOX_SPEC_MEDIA; + else if (scan_keyword("cropbox")) + return PDF_BOX_SPEC_CROP; + else if (scan_keyword("bleedbox")) + return PDF_BOX_SPEC_BLEED; + else if (scan_keyword("trimbox")) + return PDF_BOX_SPEC_TRIM; + else if (scan_keyword("artbox")) + return PDF_BOX_SPEC_ART; + return PDF_BOX_SPEC_NONE; +} + +@ @c +void scan_pdfximage(PDF pdf) +{ + scaled_whd alt_rule; + image_dict *idict; + int transform = 0, page = 1, pagebox, colorspace = 0; + char *named = NULL, *attr = NULL, *file_name = NULL; + alt_rule = scan_alt_rule(); /* scans |<rule spec>| to |alt_rule| */ + if (scan_keyword("attr")) { + scan_pdf_ext_toks(); + attr = tokenlist_to_cstring(def_ref, true, NULL); + delete_token_ref(def_ref); + } + if (scan_keyword("named")) { + scan_pdf_ext_toks(); + named = tokenlist_to_cstring(def_ref, true, NULL); + delete_token_ref(def_ref); + page = 0; + } else if (scan_keyword("page")) { + scan_int(); + page = cur_val; + } + if (scan_keyword("colorspace")) { + scan_int(); + colorspace = cur_val; + } + pagebox = scan_pdf_box_spec(); + if (pagebox == PDF_BOX_SPEC_NONE) { + pagebox = pdf_pagebox; + if (pagebox == PDF_BOX_SPEC_NONE) + pagebox = PDF_BOX_SPEC_CROP; + } + scan_pdf_ext_toks(); + file_name = tokenlist_to_cstring(def_ref, true, NULL); + assert(file_name != NULL); + delete_token_ref(def_ref); + idict = + read_image(pdf, file_name, page, named, colorspace, pagebox, + pdf_minor_version, pdf_inclusion_errorlevel); + img_attr(idict) = attr; + img_dimen(idict) = alt_rule; + img_transform(idict) = transform; + pdf_last_ximage = img_objnum(idict); + pdf_last_ximage_pages = img_totalpages(idict); + pdf_last_ximage_colordepth = img_colordepth(idict); +} + +@ @c +#define tail cur_list.tail_field + +void scan_pdfrefximage(PDF pdf) +{ + int transform = 0; /* one could scan transform as well */ + image_dict *idict; + scaled_whd alt_rule, dim; + alt_rule = scan_alt_rule(); /* scans |<rule spec>| to |alt_rule| */ + scan_int(); + check_obj_exists(pdf, obj_type_ximage, cur_val); + new_whatsit(pdf_refximage_node); + idict = idict_array[obj_data_ptr(pdf, cur_val)]; + if (alt_rule.wd != null_flag || alt_rule.ht != null_flag + || alt_rule.dp != null_flag) + dim = scale_img(idict, alt_rule, transform); + else + dim = scale_img(idict, img_dimen(idict), img_transform(idict)); + width(tail) = dim.wd; + height(tail) = dim.ht; + depth(tail) = dim.dp; + pdf_ximage_transform(tail) = transform; + pdf_ximage_index(tail) = img_index(idict); +} + +@ |tex_scale()| sequence of decisions: + +{\obeylines\obeyspaces\tt +wd ht dp : res = tex; +wd ht -- +wd -- dp +wd -- -- +-- ht dp +-- ht -- +-- -- dp +-- -- -- : res = nat; +} + +@c +scaled_whd tex_scale(scaled_whd nat, scaled_whd tex) +{ + scaled_whd res; + if (!is_running(tex.wd) && !is_running(tex.ht) && !is_running(tex.dp)) { + /* width, height, and depth specified */ + res = tex; + } else /* max. 2 dimensions are specified */ if (!is_running(tex.wd)) { + res.wd = tex.wd; + if (!is_running(tex.ht)) { + res.ht = tex.ht; + /* width and height specified */ + res.dp = ext_xn_over_d(tex.ht, nat.dp, nat.ht); + } else if (!is_running(tex.dp)) { + res.dp = tex.dp; + /* width and depth specified */ + res.ht = ext_xn_over_d(tex.wd, nat.ht + nat.dp, nat.wd) - tex.dp; + } else { + /* only width specified */ + res.ht = ext_xn_over_d(tex.wd, nat.ht, nat.wd); + res.dp = ext_xn_over_d(tex.wd, nat.dp, nat.wd); + } + } else if (!is_running(tex.ht)) { + res.ht = tex.ht; + if (!is_running(tex.dp)) { + res.dp = tex.dp; + /* height and depth specified */ + res.wd = ext_xn_over_d(tex.ht + tex.dp, nat.wd, nat.ht + nat.dp); + } else { + /* only height specified */ + res.wd = ext_xn_over_d(tex.ht, nat.wd, nat.ht); + res.dp = ext_xn_over_d(tex.ht, nat.dp, nat.ht); + } + } else if (!is_running(tex.dp)) { + res.dp = tex.dp; + /* only depth specified */ + res.ht = nat.ht - (tex.dp - nat.dp); + res.wd = nat.wd; + } else { + /* nothing specified */ + res = nat; + } + return res; +} + +@ Within |scale_img()| only image width and height matter; +the offsets and positioning are not interesting here. +But one needs rotation info to swap width and height. +|img_rotation()| comes from the optional /Rotate key in the PDF file. + +@c +scaled_whd scale_img(image_dict * idict, scaled_whd alt_rule, int transform) +{ + int x, y, xr, yr, tmp; /* size and resolution of image */ + scaled_whd nat; /* natural size corresponding to image resolution */ + int default_res; + assert(idict != NULL); + if ((img_type(idict) == IMG_TYPE_PDF + || img_type(idict) == IMG_TYPE_PDFSTREAM) && img_is_bbox(idict)) { + x = img_xsize(idict) = img_bbox(idict)[2] - img_bbox(idict)[0]; /* dimensions from image.bbox */ + y = img_ysize(idict) = img_bbox(idict)[3] - img_bbox(idict)[1]; + img_xorig(idict) = img_bbox(idict)[0]; + img_yorig(idict) = img_bbox(idict)[1]; + } else { + x = img_xsize(idict); /* dimensions, resolutions from image file */ + y = img_ysize(idict); + } + xr = img_xres(idict); + yr = img_yres(idict); + if (x <= 0 || y <= 0 || xr < 0 || yr < 0) + pdftex_fail("ext1: invalid image dimensions"); + if (xr > 65535 || yr > 65535) { + xr = 0; + yr = 0; + pdftex_warn("ext1: too large image resolution ignored"); + } + if (((transform - img_rotation(idict)) & 1) == 1) { + tmp = x; + x = y; + y = tmp; + tmp = xr; + xr = yr; + yr = tmp; + } + nat.dp = 0; /* always for images */ + if (img_type(idict) == IMG_TYPE_PDF + || img_type(idict) == IMG_TYPE_PDFSTREAM) { + nat.wd = x; + nat.ht = y; + } else { + default_res = fix_int(pdf_image_resolution, 0, 65535); + if (default_res > 0 && (xr == 0 || yr == 0)) { + xr = default_res; + yr = default_res; + } + if (xr > 0 && yr > 0) { + nat.wd = ext_xn_over_d(one_hundred_inch, x, 100 * xr); + nat.ht = ext_xn_over_d(one_hundred_inch, y, 100 * yr); + } else { + nat.wd = ext_xn_over_d(one_hundred_inch, x, 7200); + nat.ht = ext_xn_over_d(one_hundred_inch, y, 7200); + } + } + return tex_scale(nat, alt_rule); +} + +@ @c +void write_img(PDF pdf, image_dict * idict) +{ + assert(idict != NULL); + if (img_state(idict) < DICT_WRITTEN) { + if (tracefilenames) + tex_printf(" <%s", img_filepath(idict)); + switch (img_type(idict)) { + case IMG_TYPE_PNG: + write_png(pdf, idict); + break; + case IMG_TYPE_JPG: + write_jpg(pdf, idict); + break; + case IMG_TYPE_JBIG2: + write_jbig2(pdf, idict); + break; + case IMG_TYPE_PDF: + write_epdf(pdf, idict); + break; + case IMG_TYPE_PDFSTREAM: + write_pdfstream(pdf, idict); + break; + default: + pdftex_fail("internal error: unknown image type (1)"); + } + if (tracefilenames) + tex_printf(">"); + if (img_type(idict) == IMG_TYPE_PNG) { + write_additional_png_objects(pdf); + } + } + if (img_state(idict) < DICT_WRITTEN) + img_state(idict) = DICT_WRITTEN; +} + +@ write an image +@c +void pdf_write_image(PDF pdf, int n) +{ + pdf_begin_dict(pdf, n, 0); + if (pdf->draftmode == 0) + write_img(pdf, idict_array[obj_data_ptr(pdf, n)]); +} + +@ @c +void check_pdfstream_dict(image_dict * idict) +{ + if (!img_is_bbox(idict)) + pdftex_fail("image.stream: no bbox given"); + if (img_state(idict) < DICT_FILESCANNED) + img_state(idict) = DICT_FILESCANNED; +} + +@ @c +void write_pdfstream(PDF pdf, image_dict * idict) +{ + char s[256]; + assert(img_pdfstream_ptr(idict) != NULL); + assert(img_is_bbox(idict)); + pdf_puts(pdf, "/Type /XObject\n/Subtype /Form\n"); + if (img_attr(idict) != NULL && strlen(img_attr(idict)) > 0) + pdf_printf(pdf, "%s\n", img_attr(idict)); + pdf_puts(pdf, "/FormType 1\n"); + sprintf(s, "/BBox [%.8f %.8f %.8f %.8f]\n", int2bp(img_bbox(idict)[0]), + int2bp(img_bbox(idict)[1]), int2bp(img_bbox(idict)[2]), + int2bp(img_bbox(idict)[3])); + pdf_printf(pdf, stripzeros(s)); + pdf_begin_stream(pdf); + if (img_pdfstream_stream(idict) != NULL) + pdf_puts(pdf, img_pdfstream_stream(idict)); + pdf_end_stream(pdf); +} + +@ @c +/* define |idict_ptr|, |idict_array|, and |idict_limit| */ +idict_entry *idict_ptr, *idict_array = NULL; +size_t idict_limit; + +void idict_to_array(image_dict * idict) +{ + assert(idict != NULL); + if (idict_ptr - idict_array == 0) { /* align to count from 1 */ + alloc_array(idict, 1, SMALL_BUF_SIZE); /* /Im0 unused */ + idict_ptr++; + } + alloc_array(idict, 1, SMALL_BUF_SIZE); + *idict_ptr = idict; + assert(img_index(idict) == idict_ptr - idict_array); + idict_ptr++; +} + + +@ To allow the use of \.{\\pdfrefximage} inside saved boxes in -ini mode, +the information in the array has to be (un)dumped with the format. +The next two routines take care of that. + +Most of the work involved in setting up the images is simply +executed again. This solves the many possible errors resulting from +the split in two separate runs. + +There was only one problem remaining: The pdfversion and +pdfinclusionerrorlevel can have changed inbetween the call to +|readimage()| and dump time. That is why they are passed as arguments +to undumpimagemeta once more. + +some of the dumped values are really type int, not integer, +but since the macro falls back to |generic_dump| anyway, that +does not matter. + +@c +#define dumpinteger generic_dump +#define undumpinteger generic_undump + +@ (un)dumping a string means dumping the allocation size, followed + by the bytes. The trailing \.{\\0} is dumped as well, because that + makes the code simpler. + +@c +#define dumpcharptr(a) \ + do { \ + int x; \ + if (a!=NULL) { \ + x = (int)strlen(a)+1; \ + dumpinteger(x); dump_things(*a, x); \ + } else { \ + x = 0; dumpinteger(x); \ + } \ + } while (0) + +#define undumpcharptr(s) \ + do { \ + int x; \ + char *a; \ + undumpinteger (x); \ + if (x>0) { \ + a = xmalloc((unsigned)x); \ + undump_things(*a,x); \ + s = a ; \ + } else { s = NULL; } \ + } while (0) + +@ @c +void dumpimagemeta(void) +{ + int cur_index, i; + image_dict *idict; + + i = (int) idict_limit; + dumpinteger(i); + cur_index = (int) (idict_ptr - idict_array); + dumpinteger(cur_index); + + for (i = 1; i < cur_index; i++) { + idict = idict_array[i]; + assert(idict != NULL); + dumpcharptr(img_filename(idict)); + dumpinteger(img_type(idict)); + dumpinteger(img_procset(idict)); + dumpinteger(img_xsize(idict)); + dumpinteger(img_ysize(idict)); + dumpinteger(img_xres(idict)); + dumpinteger(img_yres(idict)); + dumpinteger(img_totalpages(idict)); + dumpinteger(img_colorspace(idict)); + + /* the |image_struct| is not dumped at all, except for a few + variables that are needed to restore the contents */ + + if (img_type(idict) == IMG_TYPE_PDF) { + dumpinteger(img_pagebox(idict)); + dumpinteger(img_pagenum(idict)); + } else if (img_type(idict) == IMG_TYPE_JBIG2) { + dumpinteger(img_pagenum(idict)); + } + + } +} + +@ @c +void undumpimagemeta(PDF pdf, int pdfversion, int pdfinclusionerrorlevel) +{ + int cur_index, i; + image_dict *idict; + + assert(pdf != NULL); + undumpinteger(i); + idict_limit = (size_t) i; + + idict_array = xtalloc(idict_limit, idict_entry); + undumpinteger(cur_index); + idict_ptr = idict_array + cur_index; + + for (i = 1; i < cur_index; i++) { + idict = new_image_dict(); + assert(idict != NULL); + assert(img_index(idict) == -1); + idict_to_array(idict); + undumpcharptr(img_filename(idict)); + undumpinteger(img_type(idict)); + undumpinteger(img_procset(idict)); + undumpinteger(img_xsize(idict)); + undumpinteger(img_ysize(idict)); + undumpinteger(img_xres(idict)); + undumpinteger(img_yres(idict)); + undumpinteger(img_totalpages(idict)); + undumpinteger(img_colorspace(idict)); + + switch (img_type(idict)) { + case IMG_TYPE_PDF: + undumpinteger(img_pagebox(idict)); + undumpinteger(img_pagenum(idict)); + break; + case IMG_TYPE_PNG: + break; + case IMG_TYPE_JPG: + break; + case IMG_TYPE_JBIG2: + if (pdfversion < 4) { + pdftex_fail + ("JBIG2 images only possible with at least PDF 1.4; you are generating PDF 1.%i", + (int) pdfversion); + } + undumpinteger(img_pagenum(idict)); + break; + default: + pdftex_fail("unknown type of image"); + } + read_img(pdf, idict, pdfversion, pdfinclusionerrorlevel); + } +} + +@ scans rule spec to |alt_rule| +@c +scaled_whd scan_alt_rule(void) +{ + scaled_whd alt_rule; + alt_rule.wd = null_flag; + alt_rule.ht = null_flag; + alt_rule.dp = null_flag; + RESWITCH: + if (scan_keyword("width")) { + scan_normal_dimen(); + alt_rule.wd = cur_val; + goto RESWITCH; + } + if (scan_keyword("height")) { + scan_normal_dimen(); + alt_rule.ht = cur_val; + goto RESWITCH; + } + if (scan_keyword("depth")) { + scan_normal_dimen(); + alt_rule.dp = cur_val; + goto RESWITCH; + } + return alt_rule; +} |