beta-0.89.2
[luatex.git] / source / texk / web2c / luatexdir / image / writeimg.w
blob7407d228a0f246bd0c25e535130be744a08c68d5
1 % writeimg.w
3 % Copyright 1996-2006 Han The Thanh <thanh@@pdftex.org>
4 % Copyright 2006-2012 Taco Hoekwater <taco@@luatex.org>
6 % This file is part of LuaTeX.
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.
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.
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/>.
21 @* Image inclusion.
23 @ @c
24 #include "ptexlib.h"
25 #include <kpathsea/c-auto.h>
26 #include <kpathsea/c-memstr.h>
28 @ @c
29 #include "image/image.h"
30 #include "image/writejpg.h"
31 #include "image/writejp2.h"
32 #include "image/writepng.h"
33 #include "image/writejbig2.h"
35 #include "lua.h" /* for |LUA_NOREF| */
36 #include "lauxlib.h"
38 @* Patch ImageTypeDetection 2003/02/08 by Heiko Oberdiek.
40 Function |readimage| performs some basic initializations. Then it looks at the
41 file extension to determine the image type and calls specific code/functions. The
42 main disadvantage is that standard file extensions have to be used, otherwise
43 pdfTeX is not able to detect the correct image type. The patch now looks at the
44 file header first regardless of the file extension. This is implemented in
45 function |check_type_by_header|. If this check fails, the traditional test of
46 standard file extension is tried, done in function |check_type_by_extension|.
48 Magic headers:
50 * "PNG (Portable Network Graphics) Specification", Version 1.2
51 (http://www.libpng.org/pub/png):
53 3.1. PNG file signature
55 The first eight bytes of a PNG file always contain the following
56 (decimal) values: 137 80 78 71 13 10 26 10
58 Translation to C: |"\x89PNG\r\n\x1A\n"|
60 * "JPEG File Interchange Format", Version 1.02:
62 * you can identify a JFIF file by looking for the following sequence:
63 X'FF', SOI X'FF', APP0, <2 bytes to be skipped>, "JFIF", X'00'.
65 Function |check_type_by_header| only looks at the first two bytes: |"\xFF\xD8"|
67 * ISO/IEC JTC 1/SC 29/WG 1
68 (ITU-T SG8)
69 Coding of Still Pictures
70 Title: 14492 FCD
71 Source: JBIG Committee
72 Project: JTC 1.29.10
73 Status: Final Committee Draft
75 D.4.1, ID string
77 This is an 8-byte sequence containing 0x97 0x4A 0x42 0x32 0x0D 0x0A 0x1A 0x0A.
79 * "PDF Reference", third edition:
81 * The first line should contain \%PDF-1.0 -- \%PDF-1.4 (section 3.4.1 "File Header").
82 * The "implementation notes" say:
84 3.4.1, File Header
85 12. Acrobat viewers require only that the header appear somewhere within the
86 first 1024 bytes of the file.
87 13. Acrobat viewers will also accept a header of the form \%!PS-Adobe-N.n PDF-M.m
89 The check in function |check_type_by_header| only implements the first issue. The
90 implementation notes are not considered. Therefore files with garbage at start of
91 file must have the standard extension.
93 Functions |check_type_by_header| and |check_type_by_extension|: |img_type(img)|
94 is set to |IMG_TYPE_NONE| by |new_image_dict()|. Both functions try to detect a
95 type and set |img_type(img)|. Thus a value other than |IMG_TYPE_NONE| indicates
96 that a type has been found.
99 #define HEADER_JPG "\xFF\xD8"
100 #define HEADER_PNG "\x89PNG\r\n\x1A\n"
101 #define HEADER_JBIG2 "\x97\x4A\x42\x32\x0D\x0A\x1A\x0A"
102 #define HEADER_JP2 "\x6A\x50\x20\x20"
103 #define HEADER_PDF "%PDF-1."
104 #define MAX_HEADER (sizeof(HEADER_PNG)-1)
105 #define HEADER_PDF_MEMSTREAM "data:application/pdf," /* see epdf.h */
106 #define LEN_PDF_MEMSTREAM 21 /* see epdf.h */
108 static void check_type_by_header(image_dict * idict)
110 int i;
111 FILE *file = NULL;
112 char header[MAX_HEADER];
113 char prefix[LEN_PDF_MEMSTREAM+1];
114 if (idict == NULL)
115 return;
116 if (img_type(idict) != IMG_TYPE_NONE)
117 return;
118 /* here we read the and also check for a memstream object */
119 if (!img_filepath(idict) || !FOPEN_RBIN_MODE) {
120 normal_error("pdf backend","reading image file failed");
122 file = fopen(img_filepath(idict), FOPEN_RBIN_MODE);
123 if (file == NULL) {
124 /* check the prefix of img_filepath(idict) */
125 for (i = 0; (unsigned) i < LEN_PDF_MEMSTREAM; i++) {
126 prefix[i] = (char) (img_filepath(idict)[i]);
128 prefix[LEN_PDF_MEMSTREAM]='\0';
129 if (strncmp(prefix, HEADER_PDF_MEMSTREAM, LEN_PDF_MEMSTREAM) == 0) {
130 img_type(idict) = IMG_TYPE_PDFMEMSTREAM;
131 return;
132 } else {
133 formatted_error("pdf backend","reading image file '%s' failed",img_filepath(idict));
136 /* a valid file, but perhaps unsupported */
137 for (i = 0; (unsigned) i < MAX_HEADER; i++) {
138 header[i] = (char) xgetc(file);
139 if (feof(file)) {
140 normal_error("pdf backend","reading image file failed");
143 xfclose(file, img_filepath(idict));
144 /* tests */
145 if (strncmp(header, HEADER_JPG, sizeof(HEADER_JPG) - 1) == 0)
146 img_type(idict) = IMG_TYPE_JPG;
147 else if (strncmp(header + 4, HEADER_JP2, sizeof(HEADER_JP2) - 1) == 0)
148 img_type(idict) = IMG_TYPE_JP2;
149 else if (strncmp(header, HEADER_PNG, sizeof(HEADER_PNG) - 1) == 0)
150 img_type(idict) = IMG_TYPE_PNG;
151 else if (strncmp(header, HEADER_JBIG2, sizeof(HEADER_JBIG2) - 1) == 0)
152 img_type(idict) = IMG_TYPE_JBIG2;
153 else if (strncmp(header, HEADER_PDF, sizeof(HEADER_PDF) - 1) == 0)
154 img_type(idict) = IMG_TYPE_PDF;
157 @ @c
158 static void check_type_by_extension(image_dict * idict)
160 char *image_suffix;
161 if (idict != NULL)
162 return;
163 if (img_type(idict) != IMG_TYPE_NONE) /* nothing to do */
164 return;
165 /* tests */
166 if ((image_suffix = strrchr(img_filename(idict), '.')) == 0)
167 img_type(idict) = IMG_TYPE_NONE;
168 else if (strcasecmp(image_suffix, ".png") == 0)
169 img_type(idict) = IMG_TYPE_PNG;
170 else if (strcasecmp(image_suffix, ".jpg") == 0 ||
171 strcasecmp(image_suffix, ".jpeg") == 0)
172 img_type(idict) = IMG_TYPE_JPG;
173 else if (strcasecmp(image_suffix, ".jp2") == 0)
174 img_type(idict) = IMG_TYPE_JP2;
175 else if (strcasecmp(image_suffix, ".jbig2") == 0 ||
176 strcasecmp(image_suffix, ".jb2") == 0)
177 img_type(idict) = IMG_TYPE_JBIG2;
178 else if (strcasecmp(image_suffix, ".pdf") == 0)
179 img_type(idict) = IMG_TYPE_PDF;
182 @ @c
183 void new_img_pdfstream_struct(image_dict * p)
185 img_pdfstream_ptr(p) = xtalloc(1, pdf_stream_struct);
186 img_pdfstream_stream(p) = NULL;
189 @ @c
190 image *new_image(void)
192 image *p = xtalloc(1, image);
193 set_wd_running(p);
194 set_ht_running(p);
195 set_dp_running(p);
196 img_transform(p) = 0;
197 img_dict(p) = NULL;
198 img_dictref(p) = LUA_NOREF;
199 return p;
202 @ @c
203 image_dict *new_image_dict(void)
205 image_dict *p = xtalloc(1, image_dict);
206 memset(p, 0, sizeof(image_dict));
207 set_wd_running(p);
208 set_ht_running(p);
209 set_dp_running(p);
210 img_transform(p) = 0;
211 img_pagenum(p) = 1;
212 img_type(p) = IMG_TYPE_NONE;
213 img_pagebox(p) = PDF_BOX_SPEC_MEDIA;
214 img_unset_bbox(p);
215 img_unset_group(p);
216 img_state(p) = DICT_NEW;
217 img_index(p) = -1; /* -1 = unused, used count from 0 */
218 img_luaref(p) = 0;
219 img_errorlevel(p) = pdf_inclusion_errorlevel;
220 fix_pdf_minorversion(static_pdf);
221 img_pdfminorversion(p) = pdf_minor_version;
222 return p;
225 @ @c
226 static void free_dict_strings(image_dict * p)
228 xfree(img_filename(p));
229 xfree(img_filepath(p));
230 xfree(img_attr(p));
231 xfree(img_pagename(p));
234 @ @c
235 void free_image_dict(image_dict * p)
237 if (ini_version)
238 return; /* The image may be \.{\\dump}ed to a format */
239 /* called from limglib.c */
240 switch (img_type(p)) {
241 case IMG_TYPE_PDFMEMSTREAM:
242 case IMG_TYPE_PDF:
243 flush_pdf_info(p);
244 break;
245 case IMG_TYPE_PNG:
246 flush_png_info(p);
247 break;
248 case IMG_TYPE_JPG:
249 flush_jpg_info(p);
250 break;
251 case IMG_TYPE_JP2:
252 flush_jp2_info(p);
253 break;
254 case IMG_TYPE_JBIG2:
255 flush_jbig2_info(p);
256 break;
257 case IMG_TYPE_PDFSTREAM:
258 /* flush_pdfstream_info(p); */
259 if (img_pdfstream_ptr(p) != NULL) {
260 xfree(img_pdfstream_stream(p));
261 xfree(img_pdfstream_ptr(p));
263 break;
264 case IMG_TYPE_NONE:
265 break;
266 default:
267 normal_error("pdf backend","unknown image type");
269 free_dict_strings(p);
270 xfree(p);
273 @ @c
274 void read_img(image_dict * idict)
276 char *filepath = NULL;
277 int callback_id;
278 if (img_filename(idict) == NULL) {
279 normal_error("pdf backend","image file name missing");
281 callback_id = callback_defined(find_image_file_callback);
282 if (img_filepath(idict) == NULL) {
283 if (callback_id > 0) {
284 if (run_callback(callback_id, "S->S", img_filename(idict),&filepath)) {
285 if (filepath && (strlen(filepath) > 0)) {
286 img_filepath(idict) = strdup(filepath);
289 } else {
290 img_filepath(idict) = kpse_find_file(img_filename(idict), kpse_tex_format, true);
292 if (img_filepath(idict) == NULL) {
293 formatted_error("pdf backend","cannot find image file '%s'", img_filename(idict));
296 recorder_record_input(img_filename(idict));
297 /* type checks */
298 check_type_by_header(idict);
299 check_type_by_extension(idict);
300 /* read image */
301 switch (img_type(idict)) {
302 case IMG_TYPE_PDFMEMSTREAM:
303 case IMG_TYPE_PDF:
304 read_pdf_info(idict);
305 break;
306 case IMG_TYPE_PNG:
307 read_png_info(idict);
308 break;
309 case IMG_TYPE_JPG:
310 read_jpg_info(idict);
311 break;
312 case IMG_TYPE_JP2:
313 read_jp2_info(idict);
314 break;
315 case IMG_TYPE_JBIG2:
316 read_jbig2_info(idict);
317 break;
318 default:
319 img_type(idict) = IMG_TYPE_NONE;
320 if (pdf_ignore_unknown_images) {
321 normal_warning("pdf backend","internal error: ignoring unknown image type");
322 } else {
323 normal_error("pdf backend","internal error: unknown image type");
325 break;
327 cur_file_name = NULL;
328 if (img_type(idict) == IMG_TYPE_NONE) {
329 img_state(idict) = DICT_NEW;
330 } else if (img_state(idict) < DICT_FILESCANNED) {
331 img_state(idict) = DICT_FILESCANNED;
335 @ @c
336 static image_dict *read_image(char *file_name, int page_num, char *page_name, int colorspace, int page_box)
338 image *a = new_image();
339 image_dict *idict = img_dict(a) = new_image_dict();
340 static_pdf->ximage_count++;
341 img_objnum(idict) = pdf_create_obj(static_pdf, obj_type_ximage, static_pdf->ximage_count);
342 img_index(idict) = static_pdf->ximage_count;
343 set_obj_data_ptr(static_pdf, img_objnum(idict), img_index(idict));
344 idict_to_array(idict);
345 img_colorspace(idict) = colorspace;
346 img_pagenum(idict) = page_num;
347 img_pagename(idict) = page_name;
348 if (file_name == NULL) {
349 normal_error("pdf backend","no image filename given");
351 cur_file_name = file_name;
352 img_filename(idict) = file_name;
353 img_pagebox(idict) = page_box;
354 read_img(idict);
355 return idict;
358 @ scans PDF pagebox specification
360 static pdfboxspec_e scan_pdf_box_spec(void)
362 if (scan_keyword("mediabox"))
363 return PDF_BOX_SPEC_MEDIA;
364 else if (scan_keyword("cropbox"))
365 return PDF_BOX_SPEC_CROP;
366 else if (scan_keyword("bleedbox"))
367 return PDF_BOX_SPEC_BLEED;
368 else if (scan_keyword("trimbox"))
369 return PDF_BOX_SPEC_TRIM;
370 else if (scan_keyword("artbox"))
371 return PDF_BOX_SPEC_ART;
372 else
373 return PDF_BOX_SPEC_NONE;
376 @ @c
377 void scan_pdfximage(PDF pdf) /* static_pdf */
379 scaled_whd alt_rule;
380 image_dict *idict;
381 int transform = 0, page = 1, pagebox, colorspace = 0;
382 char *named = NULL, *attr = NULL, *file_name = NULL;
383 alt_rule = scan_alt_rule(); /* scans |<rule spec>| to |alt_rule| */
384 if (scan_keyword("attr")) {
385 scan_toks(false, true);
386 attr = tokenlist_to_cstring(def_ref, true, NULL);
387 delete_token_ref(def_ref);
389 if (scan_keyword("named")) {
390 scan_toks(false, true);
391 named = tokenlist_to_cstring(def_ref, true, NULL);
392 delete_token_ref(def_ref);
393 page = 0;
394 } else if (scan_keyword("page")) {
395 scan_int();
396 page = cur_val;
398 if (scan_keyword("colorspace")) {
399 scan_int();
400 colorspace = cur_val;
402 pagebox = scan_pdf_box_spec();
403 if (pagebox == PDF_BOX_SPEC_NONE) {
404 pagebox = pdf_pagebox;
405 if (pagebox == PDF_BOX_SPEC_NONE)
406 pagebox = PDF_BOX_SPEC_CROP;
408 scan_toks(false, true);
409 file_name = tokenlist_to_cstring(def_ref, true, NULL);
410 if (file_name == NULL) {
411 normal_error("pdf backend","no image filename given");
413 delete_token_ref(def_ref);
414 idict = read_image(file_name, page, named, colorspace, pagebox);
415 img_attr(idict) = attr;
416 img_dimen(idict) = alt_rule;
417 img_transform(idict) = transform;
418 last_saved_image_index = img_objnum(idict);
419 last_saved_image_pages = img_totalpages(idict);
422 @ @c
423 #define tail cur_list.tail_field
425 void scan_pdfrefximage(PDF pdf)
427 int transform = 0; /* one could scan transform as well */
428 image_dict *idict;
429 scaled_whd alt_rule, dim;
430 alt_rule = scan_alt_rule(); /* scans |<rule spec>| to |alt_rule| */
431 scan_int();
432 check_obj_type(pdf, obj_type_ximage, cur_val);
433 tail_append(new_rule(image_rule));
434 idict = idict_array[obj_data_ptr(pdf, cur_val)];
435 if (img_state(idict) == DICT_NEW) {
436 normal_warning("image","don't rely on the image data to be okay");
437 width(tail) = 0;
438 height(tail) = 0;
439 depth(tail) = 0;
440 } else {
441 if (alt_rule.wd != null_flag || alt_rule.ht != null_flag || alt_rule.dp != null_flag) {
442 dim = scale_img(idict, alt_rule, transform);
443 } else {
444 dim = scale_img(idict, img_dimen(idict), img_transform(idict));
446 width(tail) = dim.wd;
447 height(tail) = dim.ht;
448 depth(tail) = dim.dp;
449 rule_transform(tail) = transform;
450 rule_index(tail) = img_index(idict);
454 @ |tex_scale()| sequence of decisions:
456 {\obeylines\obeyspaces\tt
457 wd ht dp : res = tex;
458 wd ht --
459 wd -- dp
460 wd -- --
461 -- ht dp
462 -- ht --
463 -- -- dp
464 -- -- -- : res = nat;
468 scaled_whd tex_scale(scaled_whd nat, scaled_whd tex)
470 scaled_whd res;
471 if (!is_running(tex.wd) && !is_running(tex.ht) && !is_running(tex.dp)) {
472 /* width, height, and depth specified */
473 res = tex;
474 } else /* max. 2 dimensions are specified */ if (!is_running(tex.wd)) {
475 res.wd = tex.wd;
476 if (!is_running(tex.ht)) {
477 res.ht = tex.ht;
478 /* width and height specified */
479 res.dp = ext_xn_over_d(tex.ht, nat.dp, nat.ht);
480 } else if (!is_running(tex.dp)) {
481 res.dp = tex.dp;
482 /* width and depth specified */
483 res.ht = ext_xn_over_d(tex.wd, nat.ht + nat.dp, nat.wd) - tex.dp;
484 } else {
485 /* only width specified */
486 res.ht = ext_xn_over_d(tex.wd, nat.ht, nat.wd);
487 res.dp = ext_xn_over_d(tex.wd, nat.dp, nat.wd);
489 } else if (!is_running(tex.ht)) {
490 res.ht = tex.ht;
491 if (!is_running(tex.dp)) {
492 res.dp = tex.dp;
493 /* height and depth specified */
494 res.wd = ext_xn_over_d(tex.ht + tex.dp, nat.wd, nat.ht + nat.dp);
495 } else {
496 /* only height specified */
497 res.wd = ext_xn_over_d(tex.ht, nat.wd, nat.ht);
498 res.dp = ext_xn_over_d(tex.ht, nat.dp, nat.ht);
500 } else if (!is_running(tex.dp)) {
501 res.dp = tex.dp;
502 /* only depth specified */
503 res.ht = nat.ht - (tex.dp - nat.dp);
504 res.wd = nat.wd;
505 } else {
506 /* nothing specified */
507 res = nat;
509 return res;
512 @ Within |scale_img()| only image width and height matter;
513 the offsets and positioning are not interesting here.
514 But one needs rotation info to swap width and height.
515 |img_rotation()| comes from the optional /Rotate key in the PDF file.
518 scaled_whd scale_img(image_dict * idict, scaled_whd alt_rule, int transform)
520 int x, y, xr, yr, tmp; /* size and resolution of image */
521 scaled_whd nat; /* natural size corresponding to image resolution */
522 int default_res;
523 if ((img_type(idict) == IMG_TYPE_PDF || img_type(idict) == IMG_TYPE_PDFMEMSTREAM
524 || img_type(idict) == IMG_TYPE_PDFSTREAM) && img_is_bbox(idict)) {
525 x = img_xsize(idict) = img_bbox(idict)[2] - img_bbox(idict)[0]; /* dimensions from image.bbox */
526 y = img_ysize(idict) = img_bbox(idict)[3] - img_bbox(idict)[1];
527 img_xorig(idict) = img_bbox(idict)[0];
528 img_yorig(idict) = img_bbox(idict)[1];
529 } else {
530 x = img_xsize(idict); /* dimensions, resolutions from image file */
531 y = img_ysize(idict);
533 xr = img_xres(idict);
534 yr = img_yres(idict);
535 if (x <= 0 || y <= 0 || xr < 0 || yr < 0)
536 normal_error("pdf backend","invalid image dimensions");
537 if (xr > 65535 || yr > 65535) {
538 xr = 0;
539 yr = 0;
540 normal_warning("pdf backend","too large image resolution ignored");
542 if (((transform - img_rotation(idict)) & 1) == 1) {
543 tmp = x;
544 x = y;
545 y = tmp;
546 tmp = xr;
547 xr = yr;
548 yr = tmp;
550 nat.dp = 0; /* always for images */
551 if (img_type(idict) == IMG_TYPE_PDF || img_type(idict) == IMG_TYPE_PDFMEMSTREAM
552 || img_type(idict) == IMG_TYPE_PDFSTREAM) {
553 nat.wd = x;
554 nat.ht = y;
555 } else {
556 default_res = fix_int(pdf_image_resolution, 0, 65535);
557 if (default_res > 0 && (xr == 0 || yr == 0)) {
558 xr = default_res;
559 yr = default_res;
561 if (xr > 0 && yr > 0) {
562 nat.wd = ext_xn_over_d(one_hundred_inch, x, 100 * xr);
563 nat.ht = ext_xn_over_d(one_hundred_inch, y, 100 * yr);
564 } else {
565 nat.wd = ext_xn_over_d(one_hundred_inch, x, 7200);
566 nat.ht = ext_xn_over_d(one_hundred_inch, y, 7200);
569 return tex_scale(nat, alt_rule);
572 @ @c
573 void write_img(PDF pdf, image_dict * idict)
575 if (img_state(idict) < DICT_WRITTEN) {
576 report_start_file(filetype_image, img_filepath(idict));
577 switch (img_type(idict)) {
578 case IMG_TYPE_PNG:
579 write_png(pdf, idict);
580 break;
581 case IMG_TYPE_JPG:
582 write_jpg(pdf, idict);
583 break;
584 case IMG_TYPE_JP2:
585 write_jp2(pdf, idict);
586 break;
587 case IMG_TYPE_JBIG2:
588 write_jbig2(pdf, idict);
589 break;
590 case IMG_TYPE_PDFMEMSTREAM:
591 case IMG_TYPE_PDF:
592 write_epdf(pdf, idict);
593 break;
594 case IMG_TYPE_PDFSTREAM:
595 write_pdfstream(pdf, idict);
596 break;
597 default:
598 normal_error("pdf backend","internal error: writing unknown image type");
600 report_stop_file(filetype_image);
601 if (img_type(idict) == IMG_TYPE_PNG) {
602 write_additional_png_objects(pdf);
605 if (img_state(idict) < DICT_WRITTEN)
606 img_state(idict) = DICT_WRITTEN;
609 @ write an image
611 void pdf_write_image(PDF pdf, int n)
613 if (pdf->draftmode == 0)
614 write_img(pdf, idict_array[obj_data_ptr(pdf, n)]);
617 @ @c
618 void check_pdfstream_dict(image_dict * idict)
620 if (!img_is_bbox(idict))
621 normal_error("pdf backend","image.stream: no bbox given");
622 if (img_state(idict) < DICT_FILESCANNED)
623 img_state(idict) = DICT_FILESCANNED;
626 @ @c
627 void write_pdfstream(PDF pdf, image_dict * idict)
629 pdf_begin_obj(pdf, img_objnum(idict), OBJSTM_NEVER);
630 pdf_begin_dict(pdf);
631 pdf_dict_add_name(pdf, "Type", "XObject");
632 pdf_dict_add_name(pdf, "Subtype", "Form");
633 if (img_attr(idict) != NULL && strlen(img_attr(idict)) > 0)
634 pdf_printf(pdf, "\n%s\n", img_attr(idict));
635 pdf_dict_add_int(pdf, "FormType", 1);
636 pdf_add_name(pdf, "BBox");
637 pdf_begin_array(pdf);
638 copyReal(pdf, sp2bp(img_bbox(idict)[0]));
639 copyReal(pdf, sp2bp(img_bbox(idict)[1]));
640 copyReal(pdf, sp2bp(img_bbox(idict)[2]));
641 copyReal(pdf, sp2bp(img_bbox(idict)[3]));
642 pdf_end_array(pdf);
643 pdf_dict_add_streaminfo(pdf);
644 pdf_end_dict(pdf);
645 pdf_begin_stream(pdf);
646 if (img_pdfstream_stream(idict) != NULL)
647 pdf_puts(pdf, img_pdfstream_stream(idict));
648 pdf_end_stream(pdf);
649 pdf_end_obj(pdf);
652 @ @c
653 idict_entry *idict_ptr, *idict_array = NULL;
654 size_t idict_limit;
656 void idict_to_array(image_dict * idict)
658 if (idict_ptr - idict_array == 0) { /* align to count from 1 */
659 alloc_array(idict, 1, SMALL_BUF_SIZE); /* /Im0 unused */
660 idict_ptr++;
662 alloc_array(idict, 1, SMALL_BUF_SIZE);
663 *idict_ptr = idict;
664 idict_ptr++;
667 void pdf_dict_add_img_filename(PDF pdf, image_dict * idict)
669 char s[21], *p;
670 if (pdf_image_addfilename>0) {
671 /* for now PTEX.FileName only for PDF, but prepared for JPG, PNG, ... */
672 if (! ( (img_type(idict) == IMG_TYPE_PDF) || (img_type(idict) == IMG_TYPE_PDFMEMSTREAM) ))
673 return;
674 if (img_visiblefilename(idict) != NULL) {
675 if (strlen(img_visiblefilename(idict)) == 0) {
676 return; /* empty string blocks PTEX.FileName output */
677 } else {
678 p = img_visiblefilename(idict);
680 } else {
681 /* unset so let's use the default */
682 p = img_filepath(idict);
684 // write additional information
685 snprintf(s, 20, "%s.FileName", pdfkeyprefix);
686 pdf_add_name(pdf, s);
687 pdf_printf(pdf, " (%s)", convertStringToPDFString(p, strlen(p)));
691 /* hh: why store images in the format ... let's get rid of this */
693 @ To allow the use of box resources inside saved boxes in -ini mode,
694 the information in the array has to be (un)dumped with the format.
695 The next two routines take care of that.
697 Most of the work involved in setting up the images is simply
698 executed again. This solves the many possible errors resulting from
699 the split in two separate runs.
701 There was only one problem remaining: The pdfversion and
702 pdfinclusionerrorlevel can have changed inbetween the call to
703 |readimage()| and dump time.
705 some of the dumped values are really type int, not integer,
706 but since the macro falls back to |generic_dump| anyway, that
707 does not matter.
710 #define dumpinteger generic_dump
711 #define undumpinteger generic_undump
713 @ (un)dumping a string means dumping the allocation size, followed
714 by the bytes. The trailing \.{\\0} is dumped as well, because that
715 makes the code simpler.
717 @ scan rule spec to |alt_rule|
719 scaled_whd scan_alt_rule(void)
721 boolean loop;
722 scaled_whd alt_rule;
723 alt_rule.wd = null_flag;
724 alt_rule.ht = null_flag;
725 alt_rule.dp = null_flag;
726 do {
727 loop = false;
728 if (scan_keyword("width")) {
729 scan_normal_dimen();
730 alt_rule.wd = cur_val;
731 loop = true;
732 } else if (scan_keyword("height")) {
733 scan_normal_dimen();
734 alt_rule.ht = cur_val;
735 loop = true;
736 } else if (scan_keyword("depth")) {
737 scan_normal_dimen();
738 alt_rule.dp = cur_val;
739 loop = true;
741 } while (loop);
742 return alt_rule;
745 @ copy file of arbitrary size to PDF buffer and flush as needed
747 size_t read_file_to_buf(PDF pdf, FILE * f, size_t len)
749 size_t i, j, k = 0;
750 while (len > 0) {
751 i = (size_t) (len > pdf->buf->size) ? (size_t) pdf->buf->size : len;
752 pdf_room(pdf, (int) i);
753 j = fread(pdf->buf->p, 1, i, f);
754 pdf->buf->p += j;
755 k += j;
756 len -= j;
757 if (i != j)
758 break;
760 return k;