1% writeimg.w 2% 3% Copyright 1996-2006 Han The Thanh <thanh@@pdftex.org> 4% Copyright 2006-2012 Taco Hoekwater <taco@@luatex.org> 5% 6% This file is part of LuaTeX. 7% 8% LuaTeX is free software; you can redistribute it and/or modify it under 9% the terms of the GNU General Public License as published by the Free 10% Software Foundation; either version 2 of the License, or (at your 11% option) any later version. 12% 13% LuaTeX is distributed in the hope that it will be useful, but WITHOUT 14% ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 15% FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 16% License for more details. 17% 18% You should have received a copy of the GNU General Public License along 19% with LuaTeX; if not, see <http://www.gnu.org/licenses/>. 20 21@* Image inclusion. 22 23@ @c 24 25 26#include "ptexlib.h" 27#include <assert.h> 28#include <kpathsea/c-auto.h> 29#include <kpathsea/c-memstr.h> 30 31@ @c 32#include "image/image.h" 33#include "image/writejpg.h" 34#include "image/writejp2.h" 35#include "image/writepng.h" 36#include "image/writejbig2.h" 37 38#include "lua.h" /* for |LUA_NOREF| */ 39#include "lauxlib.h" 40 41@ @c 42#define pdf_image_resolution int_par(pdf_image_resolution_code) 43#define pdf_pagebox int_par(pdf_pagebox_code) 44 45@* Patch ImageTypeDetection 2003/02/08 by Heiko Oberdiek. 46 47 Function |readimage| performs some basic initializations. 48 Then it looks at the file extension to determine the 49 image type and calls specific code/functions. 50 51 The main disadvantage is that standard file extensions 52 have to be used, otherwise pdfTeX is not able to detect 53 the correct image type. 54 55 The patch now looks at the file header first regardless of 56 the file extension. This is implemented in function 57 |check_type_by_header|. If this check fails, the traditional 58 test of standard file extension is tried, done in function 59 |check_type_by_extension|. 60 61 Magic headers: 62 63 * "PNG (Portable Network Graphics) Specification", Version 1.2 64 (http://www.libpng.org/pub/png): 65 66 3.1. PNG file signature 67 68 The first eight bytes of a PNG file always contain the following 69 (decimal) values: 70 71 137 80 78 71 13 10 26 10 72 73 Translation to C: |"\x89PNG\r\n\x1A\n"| 74 75 * "JPEG File Interchange Format", Version 1.02: 76 77 o you can identify a JFIF file by looking for the following 78 sequence: X'FF', SOI X'FF', APP0, <2 bytes to be skipped>, 79 "JFIF", X'00'. 80 81 Function |check_type_by_header| only looks at the first two bytes: 82 |"\xFF\xD8"| 83 84 * ISO/IEC JTC 1/SC 29/WG 1 85 (ITU-T SG8) 86 Coding of Still Pictures 87 Title: 14492 FCD 88 Source: JBIG Committee 89 Project: JTC 1.29.10 90 Status: Final Committee Draft 91 92 D.4.1, ID string 93 94 This is an 8-byte sequence containing 0x97 0x4A 0x42 0x32 0x0D 0x0A 95 0x1A 0x0A. 96 97 * "PDF Reference", third edition: 98 99 * The first line should contain "\%PDF-1.0" until "\%PDF-1.4" 100 (section 3.4.1 "File Header"). 101 * The "implementation notes" say: 102 103 3.4.1, File Header 104 12. Acrobat viewers require only that the header appear 105 somewhere within the first 1024 bytes of the file. 106 13. Acrobat viewers will also accept a header of the form 107 \%!PS-Adobe-N.n PDF-M.m 108 109 The check in function |check_type_by_header| only implements 110 the first issue. The implementation notes are not considered. 111 Therefore files with garbage at start of file must have the 112 standard extension. 113 114 Functions |check_type_by_header| and |check_type_by_extension|: 115 |img_type(img)| is set to |IMG_TYPE_NONE| by |new_image_dict()|. 116 Both functions try to detect a type and set |img_type(img)|. 117 Thus a value other than |IMG_TYPE_NONE| indicates that a 118 type has been found. 119 120@c 121#define HEADER_JPG "\xFF\xD8" 122#define HEADER_PNG "\x89PNG\r\n\x1A\n" 123#define HEADER_JBIG2 "\x97\x4A\x42\x32\x0D\x0A\x1A\x0A" 124#define HEADER_JP2 "\x6A\x50\x20\x20" 125#define HEADER_PDF "%PDF-1." 126#define MAX_HEADER (sizeof(HEADER_PNG)-1) 127 128idict_entry *idict_array; 129 130static void check_type_by_header(image_dict * idict) 131{ 132 int i; 133 FILE *file = NULL; 134 char header[MAX_HEADER]; 135 136 assert(idict != NULL); 137 if (img_type(idict) != IMG_TYPE_NONE) /* nothing to do */ 138 return; 139 /* read the header */ 140 file = xfopen(img_filepath(idict), FOPEN_RBIN_MODE); 141 for (i = 0; (unsigned) i < MAX_HEADER; i++) { 142 header[i] = (char) xgetc(file); 143 if (feof(file)) 144 luatex_fail("reading image file failed"); 145 } 146 xfclose(file, img_filepath(idict)); 147 /* tests */ 148 if (strncmp(header, HEADER_JPG, sizeof(HEADER_JPG) - 1) == 0) 149 img_type(idict) = IMG_TYPE_JPG; 150 else if (strncmp(header + 4, HEADER_JP2, sizeof(HEADER_JP2) - 1) == 0) 151 img_type(idict) = IMG_TYPE_JP2; 152 else if (strncmp(header, HEADER_PNG, sizeof(HEADER_PNG) - 1) == 0) 153 img_type(idict) = IMG_TYPE_PNG; 154 else if (strncmp(header, HEADER_JBIG2, sizeof(HEADER_JBIG2) - 1) == 0) 155 img_type(idict) = IMG_TYPE_JBIG2; 156 else if (strncmp(header, HEADER_PDF, sizeof(HEADER_PDF) - 1) == 0) 157 img_type(idict) = IMG_TYPE_PDF; 158} 159 160@ @c 161static void check_type_by_extension(image_dict * idict) 162{ 163 char *image_suffix; 164 165 assert(idict != NULL); 166 if (img_type(idict) != IMG_TYPE_NONE) /* nothing to do */ 167 return; 168 /* tests */ 169 if ((image_suffix = strrchr(img_filename(idict), '.')) == 0) 170 img_type(idict) = IMG_TYPE_NONE; 171 else if (strcasecmp(image_suffix, ".png") == 0) 172 img_type(idict) = IMG_TYPE_PNG; 173 else if (strcasecmp(image_suffix, ".jpg") == 0 || 174 strcasecmp(image_suffix, ".jpeg") == 0) 175 img_type(idict) = IMG_TYPE_JPG; 176 else if (strcasecmp(image_suffix, ".jp2") == 0) 177 img_type(idict) = IMG_TYPE_JP2; 178 else if (strcasecmp(image_suffix, ".jbig2") == 0 || 179 strcasecmp(image_suffix, ".jb2") == 0) 180 img_type(idict) = IMG_TYPE_JBIG2; 181 else if (strcasecmp(image_suffix, ".pdf") == 0) 182 img_type(idict) = IMG_TYPE_PDF; 183} 184 185@ @c 186void new_img_pdfstream_struct(image_dict * p) 187{ 188 assert(p != NULL); 189 assert(img_pdfstream_ptr(p) == NULL); 190 img_pdfstream_ptr(p) = xtalloc(1, pdf_stream_struct); 191 img_pdfstream_stream(p) = NULL; 192} 193 194@ @c 195static void init_image(image * p) 196{ 197 assert(p != NULL); 198 set_wd_running(p); 199 set_ht_running(p); 200 set_dp_running(p); 201 img_transform(p) = 0; 202 img_dict(p) = NULL; 203 img_dictref(p) = LUA_NOREF; 204} 205 206@ @c 207image *new_image(void) 208{ 209 image *p = xtalloc(1, image); 210 init_image(p); 211 return p; 212} 213 214@ @c 215static void init_image_dict(image_dict * p) 216{ 217 assert(p != NULL); 218 memset(p, 0, sizeof(image_dict)); 219 set_wd_running(p); 220 set_ht_running(p); 221 set_dp_running(p); 222 img_transform(p) = 0; 223 img_pagenum(p) = 1; 224 img_type(p) = IMG_TYPE_NONE; 225 img_pagebox(p) = PDF_BOX_SPEC_MEDIA; 226 img_unset_bbox(p); 227 img_unset_group(p); 228 img_state(p) = DICT_NEW; 229 img_index(p) = -1; /* -1 = unused, used count from 0 */ 230} 231 232@ @c 233image_dict *new_image_dict(void) 234{ 235 image_dict *p = xtalloc(1, image_dict); 236 init_image_dict(p); 237 return p; 238} 239 240@ @c 241static void free_dict_strings(image_dict * p) 242{ 243 xfree(img_filename(p)); 244 xfree(img_filepath(p)); 245 xfree(img_attr(p)); 246 xfree(img_pagename(p)); 247} 248 249@ @c 250void free_image_dict(image_dict * p) 251{ 252 if (ini_version) 253 return; /* The image may be \.{\\dump}ed to a format */ 254 /* called from limglib.c */ 255 assert(img_state(p) < DICT_REFERED); 256 switch (img_type(p)) { 257 case IMG_TYPE_PDF: 258 unrefPdfDocument(img_filepath(p)); 259 break; 260 case IMG_TYPE_PNG: /* assuming |IMG_CLOSEINBETWEEN| */ 261 assert(img_png_ptr(p) == NULL); 262 break; 263 case IMG_TYPE_JPG: /* assuming |IMG_CLOSEINBETWEEN| */ 264 assert(img_jpg_ptr(p) == NULL); 265 break; 266 case IMG_TYPE_JP2: /* */ 267 assert(img_jp2_ptr(p) == NULL); 268 break; 269 case IMG_TYPE_JBIG2: /* todo: writejbig2.w cleanup */ 270 break; 271 case IMG_TYPE_PDFSTREAM: 272 if (img_pdfstream_ptr(p) != NULL) { 273 xfree(img_pdfstream_stream(p)); 274 xfree(img_pdfstream_ptr(p)); 275 } 276 break; 277 case IMG_TYPE_NONE: 278 break; 279 default: 280 assert(0); 281 } 282 free_dict_strings(p); 283 assert(img_file(p) == NULL); 284 xfree(p); 285} 286 287@ @c 288void read_img(PDF pdf, 289 image_dict * idict, int minor_version, int inclusion_errorlevel) 290{ 291 char *filepath = NULL; 292 int callback_id; 293 assert(idict != NULL); 294 if (img_filename(idict) == NULL) 295 luatex_fail("image file name missing"); 296 callback_id = callback_defined(find_image_file_callback); 297 if (img_filepath(idict) == NULL) { 298 if (callback_id > 0 299 && run_callback(callback_id, "S->S", img_filename(idict), 300 &filepath)) { 301 if (filepath && (strlen(filepath) > 0)) 302 img_filepath(idict) = strdup(filepath); 303 } else 304 img_filepath(idict) = 305 kpse_find_file(img_filename(idict), kpse_tex_format, true); 306 if (img_filepath(idict) == NULL) 307 luatex_fail("cannot find image file '%s'", img_filename(idict)); 308 } 309 recorder_record_input(img_filename(idict)); 310 /* type checks */ 311 check_type_by_header(idict); 312 check_type_by_extension(idict); 313 /* read image */ 314 switch (img_type(idict)) { 315 case IMG_TYPE_PDF: 316 assert(pdf != NULL); /* TODO! */ 317 read_pdf_info(idict, minor_version, inclusion_errorlevel, 318 IMG_CLOSEINBETWEEN); 319 break; 320 case IMG_TYPE_PNG: 321 read_png_info(idict, IMG_CLOSEINBETWEEN); 322 break; 323 case IMG_TYPE_JPG: 324 read_jpg_info(pdf, idict, IMG_CLOSEINBETWEEN); 325 break; 326 case IMG_TYPE_JP2: 327 read_jp2_info(idict, IMG_CLOSEINBETWEEN); 328 break; 329 case IMG_TYPE_JBIG2: 330 if (minor_version < 4) { 331 luatex_fail 332 ("JBIG2 images only possible with at least PDF 1.4; you are generating PDF 1.%i", 333 (int) minor_version); 334 } 335 read_jbig2_info(idict); 336 break; 337 default: 338 luatex_fail("internal error: unknown image type (2)"); 339 } 340 cur_file_name = NULL; 341 if (img_state(idict) < DICT_FILESCANNED) 342 img_state(idict) = DICT_FILESCANNED; 343} 344 345@ @c 346static image_dict *read_image(PDF pdf, char *file_name, int page_num, 347 char *page_name, int colorspace, 348 int page_box, int minor_version, 349 int inclusion_errorlevel) 350{ 351 image *a = new_image(); 352 image_dict *idict = img_dict(a) = new_image_dict(); 353 pdf->ximage_count++; 354 img_objnum(idict) = pdf_create_obj(pdf, obj_type_ximage, pdf->ximage_count); 355 img_index(idict) = pdf->ximage_count; 356 set_obj_data_ptr(pdf, img_objnum(idict), img_index(idict)); 357 idict_to_array(idict); 358 img_colorspace(idict) = colorspace; 359 img_pagenum(idict) = page_num; 360 img_pagename(idict) = page_name; 361 assert(file_name != NULL); 362 cur_file_name = file_name; 363 img_filename(idict) = file_name; 364 img_pagebox(idict) = page_box; 365 read_img(pdf, idict, minor_version, inclusion_errorlevel); 366 return idict; 367} 368 369@ scans PDF pagebox specification 370@c 371static pdfboxspec_e scan_pdf_box_spec(void) 372{ 373 if (scan_keyword("mediabox")) 374 return PDF_BOX_SPEC_MEDIA; 375 else if (scan_keyword("cropbox")) 376 return PDF_BOX_SPEC_CROP; 377 else if (scan_keyword("bleedbox")) 378 return PDF_BOX_SPEC_BLEED; 379 else if (scan_keyword("trimbox")) 380 return PDF_BOX_SPEC_TRIM; 381 else if (scan_keyword("artbox")) 382 return PDF_BOX_SPEC_ART; 383 return PDF_BOX_SPEC_NONE; 384} 385 386@ @c 387void scan_pdfximage(PDF pdf) 388{ 389 scaled_whd alt_rule; 390 image_dict *idict; 391 int transform = 0, page = 1, pagebox, colorspace = 0; 392 char *named = NULL, *attr = NULL, *file_name = NULL; 393 alt_rule = scan_alt_rule(); /* scans |<rule spec>| to |alt_rule| */ 394 if (scan_keyword("attr")) { 395 scan_pdf_ext_toks(); 396 attr = tokenlist_to_cstring(def_ref, true, NULL); 397 delete_token_ref(def_ref); 398 } 399 if (scan_keyword("named")) { 400 scan_pdf_ext_toks(); 401 named = tokenlist_to_cstring(def_ref, true, NULL); 402 delete_token_ref(def_ref); 403 page = 0; 404 } else if (scan_keyword("page")) { 405 scan_int(); 406 page = cur_val; 407 } 408 if (scan_keyword("colorspace")) { 409 scan_int(); 410 colorspace = cur_val; 411 } 412 pagebox = scan_pdf_box_spec(); 413 if (pagebox == PDF_BOX_SPEC_NONE) { 414 pagebox = pdf_pagebox; 415 if (pagebox == PDF_BOX_SPEC_NONE) 416 pagebox = PDF_BOX_SPEC_CROP; 417 } 418 scan_pdf_ext_toks(); 419 file_name = tokenlist_to_cstring(def_ref, true, NULL); 420 assert(file_name != NULL); 421 delete_token_ref(def_ref); 422 idict = 423 read_image(pdf, file_name, page, named, colorspace, pagebox, 424 pdf_minor_version, pdf_inclusion_errorlevel); 425 img_attr(idict) = attr; 426 img_dimen(idict) = alt_rule; 427 img_transform(idict) = transform; 428 pdf_last_ximage = img_objnum(idict); 429 pdf_last_ximage_pages = img_totalpages(idict); 430 pdf_last_ximage_colordepth = img_colordepth(idict); 431} 432 433@ @c 434#define tail cur_list.tail_field 435 436void scan_pdfrefximage(PDF pdf) 437{ 438 int transform = 0; /* one could scan transform as well */ 439 image_dict *idict; 440 scaled_whd alt_rule, dim; 441 alt_rule = scan_alt_rule(); /* scans |<rule spec>| to |alt_rule| */ 442 scan_int(); 443 check_obj_type(pdf, obj_type_ximage, cur_val); 444 new_whatsit(pdf_refximage_node); 445 idict = idict_array[obj_data_ptr(pdf, cur_val)]; 446 if (alt_rule.wd != null_flag || alt_rule.ht != null_flag 447 || alt_rule.dp != null_flag) 448 dim = scale_img(idict, alt_rule, transform); 449 else 450 dim = scale_img(idict, img_dimen(idict), img_transform(idict)); 451 width(tail) = dim.wd; 452 height(tail) = dim.ht; 453 depth(tail) = dim.dp; 454 pdf_ximage_transform(tail) = transform; 455 pdf_ximage_index(tail) = img_index(idict); 456} 457 458@ |tex_scale()| sequence of decisions: 459 460{\obeylines\obeyspaces\tt 461wd ht dp : res = tex; 462wd ht -- 463wd -- dp 464wd -- -- 465-- ht dp 466-- ht -- 467-- -- dp 468-- -- -- : res = nat; 469} 470 471@c 472scaled_whd tex_scale(scaled_whd nat, scaled_whd tex) 473{ 474 scaled_whd res; 475 if (!is_running(tex.wd) && !is_running(tex.ht) && !is_running(tex.dp)) { 476 /* width, height, and depth specified */ 477 res = tex; 478 } else /* max. 2 dimensions are specified */ if (!is_running(tex.wd)) { 479 res.wd = tex.wd; 480 if (!is_running(tex.ht)) { 481 res.ht = tex.ht; 482 /* width and height specified */ 483 res.dp = ext_xn_over_d(tex.ht, nat.dp, nat.ht); 484 } else if (!is_running(tex.dp)) { 485 res.dp = tex.dp; 486 /* width and depth specified */ 487 res.ht = ext_xn_over_d(tex.wd, nat.ht + nat.dp, nat.wd) - tex.dp; 488 } else { 489 /* only width specified */ 490 res.ht = ext_xn_over_d(tex.wd, nat.ht, nat.wd); 491 res.dp = ext_xn_over_d(tex.wd, nat.dp, nat.wd); 492 } 493 } else if (!is_running(tex.ht)) { 494 res.ht = tex.ht; 495 if (!is_running(tex.dp)) { 496 res.dp = tex.dp; 497 /* height and depth specified */ 498 res.wd = ext_xn_over_d(tex.ht + tex.dp, nat.wd, nat.ht + nat.dp); 499 } else { 500 /* only height specified */ 501 res.wd = ext_xn_over_d(tex.ht, nat.wd, nat.ht); 502 res.dp = ext_xn_over_d(tex.ht, nat.dp, nat.ht); 503 } 504 } else if (!is_running(tex.dp)) { 505 res.dp = tex.dp; 506 /* only depth specified */ 507 res.ht = nat.ht - (tex.dp - nat.dp); 508 res.wd = nat.wd; 509 } else { 510 /* nothing specified */ 511 res = nat; 512 } 513 return res; 514} 515 516@ Within |scale_img()| only image width and height matter; 517the offsets and positioning are not interesting here. 518But one needs rotation info to swap width and height. 519|img_rotation()| comes from the optional /Rotate key in the PDF file. 520 521@c 522scaled_whd scale_img(image_dict * idict, scaled_whd alt_rule, int transform) 523{ 524 int x, y, xr, yr, tmp; /* size and resolution of image */ 525 scaled_whd nat; /* natural size corresponding to image resolution */ 526 int default_res; 527 assert(idict != NULL); 528 if ((img_type(idict) == IMG_TYPE_PDF 529 || img_type(idict) == IMG_TYPE_PDFSTREAM) && img_is_bbox(idict)) { 530 x = img_xsize(idict) = img_bbox(idict)[2] - img_bbox(idict)[0]; /* dimensions from image.bbox */ 531 y = img_ysize(idict) = img_bbox(idict)[3] - img_bbox(idict)[1]; 532 img_xorig(idict) = img_bbox(idict)[0]; 533 img_yorig(idict) = img_bbox(idict)[1]; 534 } else { 535 x = img_xsize(idict); /* dimensions, resolutions from image file */ 536 y = img_ysize(idict); 537 } 538 xr = img_xres(idict); 539 yr = img_yres(idict); 540 if (x <= 0 || y <= 0 || xr < 0 || yr < 0) 541 luatex_fail("ext1: invalid image dimensions"); 542 if (xr > 65535 || yr > 65535) { 543 xr = 0; 544 yr = 0; 545 luatex_warn("ext1: too large image resolution ignored"); 546 } 547 if (((transform - img_rotation(idict)) & 1) == 1) { 548 tmp = x; 549 x = y; 550 y = tmp; 551 tmp = xr; 552 xr = yr; 553 yr = tmp; 554 } 555 nat.dp = 0; /* always for images */ 556 if (img_type(idict) == IMG_TYPE_PDF 557 || img_type(idict) == IMG_TYPE_PDFSTREAM) { 558 nat.wd = x; 559 nat.ht = y; 560 } else { 561 default_res = fix_int(pdf_image_resolution, 0, 65535); 562 if (default_res > 0 && (xr == 0 || yr == 0)) { 563 xr = default_res; 564 yr = default_res; 565 } 566 if (xr > 0 && yr > 0) { 567 nat.wd = ext_xn_over_d(one_hundred_inch, x, 100 * xr); 568 nat.ht = ext_xn_over_d(one_hundred_inch, y, 100 * yr); 569 } else { 570 nat.wd = ext_xn_over_d(one_hundred_inch, x, 7200); 571 nat.ht = ext_xn_over_d(one_hundred_inch, y, 7200); 572 } 573 } 574 return tex_scale(nat, alt_rule); 575} 576 577@ @c 578void write_img(PDF pdf, image_dict * idict) 579{ 580 assert(idict != NULL); 581 if (img_state(idict) < DICT_WRITTEN) { 582 report_start_file(filetype_image, img_filepath(idict)); 583 switch (img_type(idict)) { 584 case IMG_TYPE_PNG: 585 write_png(pdf, idict); 586 break; 587 case IMG_TYPE_JPG: 588 write_jpg(pdf, idict); 589 break; 590 case IMG_TYPE_JP2: 591 write_jp2(pdf, idict); 592 break; 593 case IMG_TYPE_JBIG2: 594 write_jbig2(pdf, idict); 595 break; 596 case IMG_TYPE_PDF: 597 write_epdf(pdf, idict); 598 break; 599 case IMG_TYPE_PDFSTREAM: 600 write_pdfstream(pdf, idict); 601 break; 602 default: 603 luatex_fail("internal error: unknown image type (1)"); 604 } 605 report_stop_file(filetype_image); 606 if (img_type(idict) == IMG_TYPE_PNG) { 607 write_additional_png_objects(pdf); 608 } 609 } 610 if (img_state(idict) < DICT_WRITTEN) 611 img_state(idict) = DICT_WRITTEN; 612} 613 614@ write an image 615@c 616void pdf_write_image(PDF pdf, int n) 617{ 618 if (pdf->draftmode == 0) 619 write_img(pdf, idict_array[obj_data_ptr(pdf, n)]); 620} 621 622@ @c 623void check_pdfstream_dict(image_dict * idict) 624{ 625 if (!img_is_bbox(idict)) 626 luatex_fail("image.stream: no bbox given"); 627 if (img_state(idict) < DICT_FILESCANNED) 628 img_state(idict) = DICT_FILESCANNED; 629} 630 631@ @c 632void write_pdfstream(PDF pdf, image_dict * idict) 633{ 634 assert(img_pdfstream_ptr(idict) != NULL); 635 assert(img_is_bbox(idict)); 636 pdf_begin_obj(pdf, img_objnum(idict), OBJSTM_NEVER); 637 pdf_begin_dict(pdf); 638 pdf_dict_add_name(pdf, "Type", "XObject"); 639 pdf_dict_add_name(pdf, "Subtype", "Form"); 640 if (img_attr(idict) != NULL && strlen(img_attr(idict)) > 0) 641 pdf_printf(pdf, "\n%s\n", img_attr(idict)); 642 pdf_dict_add_int(pdf, "FormType", 1); 643 pdf_add_name(pdf, "BBox"); 644 pdf_begin_array(pdf); 645 copyReal(pdf, sp2bp(img_bbox(idict)[0])); 646 copyReal(pdf, sp2bp(img_bbox(idict)[1])); 647 copyReal(pdf, sp2bp(img_bbox(idict)[2])); 648 copyReal(pdf, sp2bp(img_bbox(idict)[3])); 649 pdf_end_array(pdf); 650 pdf_dict_add_streaminfo(pdf); 651 pdf_end_dict(pdf); 652 pdf_begin_stream(pdf); 653 if (img_pdfstream_stream(idict) != NULL) 654 pdf_puts(pdf, img_pdfstream_stream(idict)); 655 pdf_end_stream(pdf); 656 pdf_end_obj(pdf); 657} 658 659@ @c 660/* define |idict_ptr|, |idict_array|, and |idict_limit| */ 661idict_entry *idict_ptr, *idict_array = NULL; 662size_t idict_limit; 663 664void idict_to_array(image_dict * idict) 665{ 666 assert(idict != NULL); 667 if (idict_ptr - idict_array == 0) { /* align to count from 1 */ 668 alloc_array(idict, 1, SMALL_BUF_SIZE); /* /Im0 unused */ 669 idict_ptr++; 670 } 671 alloc_array(idict, 1, SMALL_BUF_SIZE); 672 *idict_ptr = idict; 673 assert(img_index(idict) == idict_ptr - idict_array); 674 idict_ptr++; 675} 676 677void pdf_dict_add_img_filename(PDF pdf, image_dict * idict) 678{ 679 char s[21], *p; 680 assert(idict != NULL); 681 /* for now PTEX.FileName only for PDF, but prepared for JPG, PNG, ... */ 682 if (img_type(idict) != IMG_TYPE_PDF) 683 return; 684 if (img_visiblefilename(idict) != NULL) { 685 if (strlen(img_visiblefilename(idict)) == 0) 686 return; /* empty string blocks PTEX.FileName output */ 687 else 688 p = img_visiblefilename(idict); 689 } else 690 p = img_filepath(idict); 691 // write additional information 692 snprintf(s, 20, "%s.FileName", pdfkeyprefix); 693 pdf_add_name(pdf, s); 694 pdf_printf(pdf, " (%s)", convertStringToPDFString(p, strlen(p))); 695} 696 697@ To allow the use of \.{\\pdfrefximage} inside saved boxes in -ini mode, 698the information in the array has to be (un)dumped with the format. 699The next two routines take care of that. 700 701Most of the work involved in setting up the images is simply 702executed again. This solves the many possible errors resulting from 703the split in two separate runs. 704 705There was only one problem remaining: The pdfversion and 706pdfinclusionerrorlevel can have changed inbetween the call to 707|readimage()| and dump time. That is why they are passed as arguments 708to undumpimagemeta once more. 709 710some of the dumped values are really type int, not integer, 711but since the macro falls back to |generic_dump| anyway, that 712does not matter. 713 714@c 715#define dumpinteger generic_dump 716#define undumpinteger generic_undump 717 718@ (un)dumping a string means dumping the allocation size, followed 719 by the bytes. The trailing \.{\\0} is dumped as well, because that 720 makes the code simpler. 721 722@c 723#define dumpcharptr(a) \ 724 do { \ 725 int x; \ 726 if (a!=NULL) { \ 727 x = (int)strlen(a)+1; \ 728 dumpinteger(x); dump_things(*a, x); \ 729 } else { \ 730 x = 0; dumpinteger(x); \ 731 } \ 732 } while (0) 733 734#define undumpcharptr(s) \ 735 do { \ 736 int x; \ 737 char *a; \ 738 undumpinteger (x); \ 739 if (x>0) { \ 740 a = xmalloc((unsigned)x); \ 741 undump_things(*a,x); \ 742 s = a ; \ 743 } else { s = NULL; } \ 744 } while (0) 745 746@ @c 747void dumpimagemeta(void) 748{ 749 int cur_index, i; 750 image_dict *idict; 751 752 i = (int) idict_limit; 753 dumpinteger(i); 754 cur_index = (int) (idict_ptr - idict_array); 755 dumpinteger(cur_index); 756 757 for (i = 1; i < cur_index; i++) { 758 idict = idict_array[i]; 759 assert(idict != NULL); 760 dumpcharptr(img_filename(idict)); 761 dumpinteger(img_type(idict)); 762 dumpinteger(img_procset(idict)); 763 dumpinteger(img_xsize(idict)); 764 dumpinteger(img_ysize(idict)); 765 dumpinteger(img_xres(idict)); 766 dumpinteger(img_yres(idict)); 767 dumpinteger(img_totalpages(idict)); 768 dumpinteger(img_colorspace(idict)); 769 770 /* the |image_struct| is not dumped at all, except for a few 771 variables that are needed to restore the contents */ 772 773 if (img_type(idict) == IMG_TYPE_PDF) { 774 dumpinteger(img_pagebox(idict)); 775 dumpinteger(img_pagenum(idict)); 776 } else if (img_type(idict) == IMG_TYPE_JBIG2) { 777 dumpinteger(img_pagenum(idict)); 778 } 779 780 } 781} 782 783@ @c 784void undumpimagemeta(PDF pdf, int pdfversion, int pdfinclusionerrorlevel) 785{ 786 int cur_index, i; 787 image_dict *idict; 788 789 assert(pdf != NULL); 790 undumpinteger(i); 791 idict_limit = (size_t) i; 792 793 idict_array = xtalloc(idict_limit, idict_entry); 794 undumpinteger(cur_index); 795 idict_ptr = idict_array + cur_index; 796 797 for (i = 1; i < cur_index; i++) { 798 idict = new_image_dict(); 799 assert(idict != NULL); 800 assert(img_index(idict) == -1); 801 idict_to_array(idict); 802 undumpcharptr(img_filename(idict)); 803 undumpinteger(img_type(idict)); 804 undumpinteger(img_procset(idict)); 805 undumpinteger(img_xsize(idict)); 806 undumpinteger(img_ysize(idict)); 807 undumpinteger(img_xres(idict)); 808 undumpinteger(img_yres(idict)); 809 undumpinteger(img_totalpages(idict)); 810 undumpinteger(img_colorspace(idict)); 811 812 switch (img_type(idict)) { 813 case IMG_TYPE_PDF: 814 undumpinteger(img_pagebox(idict)); 815 undumpinteger(img_pagenum(idict)); 816 break; 817 case IMG_TYPE_PNG: 818 case IMG_TYPE_JPG: 819 case IMG_TYPE_JP2: 820 break; 821 case IMG_TYPE_JBIG2: 822 if (pdfversion < 4) { 823 luatex_fail 824 ("JBIG2 images only possible with at least PDF 1.4; you are generating PDF 1.%i", 825 (int) pdfversion); 826 } 827 undumpinteger(img_pagenum(idict)); 828 break; 829 default: 830 luatex_fail("unknown type of image"); 831 } 832 read_img(pdf, idict, pdfversion, pdfinclusionerrorlevel); 833 } 834} 835 836@ scan rule spec to |alt_rule| 837@c 838scaled_whd scan_alt_rule(void) 839{ 840 boolean loop; 841 scaled_whd alt_rule; 842 alt_rule.wd = null_flag; 843 alt_rule.ht = null_flag; 844 alt_rule.dp = null_flag; 845 do { 846 loop = false; 847 if (scan_keyword("width")) { 848 scan_normal_dimen(); 849 alt_rule.wd = cur_val; 850 loop = true; 851 } else if (scan_keyword("height")) { 852 scan_normal_dimen(); 853 alt_rule.ht = cur_val; 854 loop = true; 855 } else if (scan_keyword("depth")) { 856 scan_normal_dimen(); 857 alt_rule.dp = cur_val; 858 loop = true; 859 } 860 } while (loop); 861 return alt_rule; 862} 863 864@ copy file of arbitrary size to PDF buffer and flush as needed 865@c 866size_t read_file_to_buf(PDF pdf, FILE * f, size_t len) 867{ 868 size_t i, j, k = 0; 869 while (len > 0) { 870 i = (size_t) (len > pdf->buf->size) ? (size_t) pdf->buf->size : len; 871 pdf_room(pdf, (int) i); 872 j = fread(pdf->buf->p, 1, i, f); 873 pdf->buf->p += j; 874 k += j; 875 len -= j; 876 if (i != j) 877 break; 878 } 879 return k; 880} 881