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
/>.
25 #include
<kpathsea
/c-auto.h
>
26 #include
<kpathsea
/c-memstr.h
>
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|
*/
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|.
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
69 Coding of Still Pictures
71 Source
: JBIG Committee
73 Status
: Final Committee Draft
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
:
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
)
112 char header
[MAX_HEADER
];
113 char prefix
[LEN_PDF_MEMSTREAM
+1];
116 if
(img_type
(idict
) != IMG_TYPE_NONE
)
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
);
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
;
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
);
140 normal_error
("pdf backend","reading image file failed");
143 xfclose
(file
, img_filepath
(idict
));
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
;
158 static void check_type_by_extension
(image_dict
* idict
)
163 if
(img_type
(idict
) != IMG_TYPE_NONE
) /* nothing to do
*/
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
;
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;
190 image
*new_image
(void
)
192 image
*p
= xtalloc
(1, image
);
196 img_transform
(p
) = 0;
198 img_dictref
(p
) = LUA_NOREF
;
203 image_dict
*new_image_dict
(void
)
205 image_dict
*p
= xtalloc
(1, image_dict
);
206 memset
(p
, 0, sizeof
(image_dict
));
210 img_transform
(p
) = 0;
212 img_type
(p
) = IMG_TYPE_NONE
;
213 img_pagebox
(p
) = PDF_BOX_SPEC_MEDIA
;
216 img_state
(p
) = DICT_NEW
;
217 img_index
(p
) = -1; /* -1 = unused
, used count from
0 */
219 img_errorlevel
(p
) = pdf_inclusion_errorlevel
;
220 fix_pdf_minorversion
(static_pdf
);
221 img_pdfminorversion
(p
) = pdf_minor_version
;
226 static void free_dict_strings
(image_dict
* p
)
228 xfree
(img_filename
(p
));
229 xfree
(img_filepath
(p
));
231 xfree
(img_pagename
(p
));
235 void free_image_dict
(image_dict
* p
)
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
:
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
));
267 normal_error
("pdf backend","unknown image type");
269 free_dict_strings
(p
);
274 void read_img
(image_dict
* idict
)
276 char
*filepath
= NULL;
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 /* we always callback
, also for a mem stream
*/
285 if
(run_callback
(callback_id
, "S->S", img_filename
(idict
),&filepath)) {
286 if
(filepath
&& (strlen(filepath) > 0)) {
287 img_filepath
(idict
) = strdup
(filepath
);
291 if
(img_filepath
(idict
) == NULL && (strstr(img_filename(idict),"data:application/pdf,") != NULL)) {
292 /* we need to check here for a pdf memstream
*/
293 img_filepath
(idict
) = strdup
(img_filename
(idict
));
294 } else if
(callback_id
== 0) {
295 /* otherwise we use kpse but only when we don't callback
*/
296 img_filepath
(idict
) = kpse_find_file
(img_filename
(idict
), kpse_tex_format
, true
);
298 if
(img_filepath
(idict
) == NULL) {
299 /* in any case we need a name
*/
300 formatted_error
("pdf backend","cannot find image file '%s'", img_filename
(idict
));
303 recorder_record_input
(img_filename
(idict
));
305 check_type_by_header
(idict
);
306 check_type_by_extension
(idict
);
308 switch
(img_type
(idict
)) {
309 case IMG_TYPE_PDFMEMSTREAM
:
311 read_pdf_info
(idict
);
314 read_png_info
(idict
);
317 read_jpg_info
(idict
);
320 read_jp2_info
(idict
);
323 read_jbig2_info
(idict
);
326 img_type
(idict
) = IMG_TYPE_NONE
;
327 if
(pdf_ignore_unknown_images
) {
328 normal_warning
("pdf backend","internal error: ignoring unknown image type");
330 normal_error
("pdf backend","internal error: unknown image type");
334 cur_file_name
= NULL;
335 if
(img_type
(idict
) == IMG_TYPE_NONE
) {
336 img_state
(idict
) = DICT_NEW
;
337 } else if
(img_state
(idict
) < DICT_FILESCANNED
) {
338 img_state
(idict
) = DICT_FILESCANNED
;
343 static image_dict
*read_image
(char
*file_name
, int page_num
, char
*page_name
, int colorspace
, int page_box
)
345 image
*a
= new_image
();
346 image_dict
*idict
= img_dict
(a
) = new_image_dict
();
347 static_pdf-
>ximage_count
++;
348 img_objnum
(idict
) = pdf_create_obj
(static_pdf
, obj_type_ximage
, static_pdf-
>ximage_count
);
349 img_index
(idict
) = static_pdf-
>ximage_count
;
350 set_obj_data_ptr
(static_pdf
, img_objnum
(idict
), img_index
(idict
));
351 idict_to_array
(idict
);
352 img_colorspace
(idict
) = colorspace
;
353 img_pagenum
(idict
) = page_num
;
354 img_pagename
(idict
) = page_name
;
355 if
(file_name
== NULL) {
356 normal_error
("pdf backend","no image filename given");
358 cur_file_name
= file_name
;
359 img_filename
(idict
) = file_name
;
360 img_pagebox
(idict
) = page_box
;
365 @ scans PDF pagebox specification
367 static pdfboxspec_e scan_pdf_box_spec
(void
)
369 if
(scan_keyword
("mediabox"))
370 return PDF_BOX_SPEC_MEDIA
;
371 else if
(scan_keyword
("cropbox"))
372 return PDF_BOX_SPEC_CROP
;
373 else if
(scan_keyword
("bleedbox"))
374 return PDF_BOX_SPEC_BLEED
;
375 else if
(scan_keyword
("trimbox"))
376 return PDF_BOX_SPEC_TRIM
;
377 else if
(scan_keyword
("artbox"))
378 return PDF_BOX_SPEC_ART
;
380 return PDF_BOX_SPEC_NONE
;
384 void scan_pdfximage
(PDF pdf
) /* static_pdf
*/
388 int transform
= 0, page
= 1, pagebox
, colorspace
= 0;
389 char
*named
= NULL, *attr
= NULL, *file_name
= NULL;
390 alt_rule
= scan_alt_rule
(); /* scans |
<rule spec
>| to |alt_rule|
*/
391 if
(scan_keyword
("attr")) {
392 scan_toks
(false
, true
);
393 attr
= tokenlist_to_cstring
(def_ref
, true
, NULL);
394 delete_token_ref
(def_ref
);
396 if
(scan_keyword
("named")) {
397 scan_toks
(false
, true
);
398 named
= tokenlist_to_cstring
(def_ref
, true
, NULL);
399 delete_token_ref
(def_ref
);
401 } else if
(scan_keyword
("page")) {
405 if
(scan_keyword
("colorspace")) {
407 colorspace
= cur_val
;
409 pagebox
= scan_pdf_box_spec
();
410 if
(pagebox
== PDF_BOX_SPEC_NONE
) {
411 pagebox
= pdf_pagebox
;
412 if
(pagebox
== PDF_BOX_SPEC_NONE
)
413 pagebox
= PDF_BOX_SPEC_CROP
;
415 scan_toks
(false
, true
);
416 file_name
= tokenlist_to_cstring
(def_ref
, true
, NULL);
417 if
(file_name
== NULL) {
418 normal_error
("pdf backend","no image filename given");
420 delete_token_ref
(def_ref
);
421 idict
= read_image
(file_name
, page
, named
, colorspace
, pagebox
);
422 img_attr
(idict
) = attr
;
423 img_dimen
(idict
) = alt_rule
;
424 img_transform
(idict
) = transform
;
425 last_saved_image_index
= img_objnum
(idict
);
426 last_saved_image_pages
= img_totalpages
(idict
);
430 void scan_pdfrefximage
(PDF pdf
)
432 int transform
= 0; /* one could scan transform as well
*/
434 scaled_whd alt_rule
, dim
;
435 alt_rule
= scan_alt_rule
(); /* scans |
<rule spec
>| to |alt_rule|
*/
437 check_obj_type
(pdf
, obj_type_ximage
, cur_val
);
438 tail_append
(new_rule
(image_rule
));
439 idict
= idict_array
[obj_data_ptr
(pdf
, cur_val
)];
440 if
(img_state
(idict
) == DICT_NEW
) {
441 normal_warning
("image","don't rely on the image data to be okay");
443 height
(tail_par
) = 0;
446 if
(alt_rule.wd
!= null_flag || alt_rule.ht
!= null_flag || alt_rule.dp
!= null_flag
) {
447 dim
= scale_img
(idict
, alt_rule
, transform
);
449 dim
= scale_img
(idict
, img_dimen
(idict
), img_transform
(idict
));
451 width
(tail_par
) = dim.wd
;
452 height
(tail_par
) = dim.ht
;
453 depth
(tail_par
) = dim.dp
;
454 rule_transform
(tail_par
) = transform
;
455 rule_index
(tail_par
) = img_index
(idict
);
459 @ |tex_scale
()| sequence of decisions
:
461 {\obeylines\obeyspaces\tt
462 wd ht dp
: res
= tex
;
469 -- -- -- : res
= nat
;
473 scaled_whd tex_scale
(scaled_whd nat
, scaled_whd tex
)
476 if
(!is_running
(tex.wd
) && !is_running(tex.ht) && !is_running(tex.dp)) {
477 /* width
, height
, and depth specified
*/
479 } else
/* max.
2 dimensions are specified
*/ if
(!is_running
(tex.wd
)) {
481 if
(!is_running
(tex.ht
)) {
483 /* width and height specified
*/
484 res.dp
= ext_xn_over_d
(tex.ht
, nat.dp
, nat.ht
);
485 } else if
(!is_running
(tex.dp
)) {
487 /* width and depth specified
*/
488 res.ht
= ext_xn_over_d
(tex.wd
, nat.ht
+ nat.dp
, nat.wd
) - tex.dp
;
490 /* only width specified
*/
491 res.ht
= ext_xn_over_d
(tex.wd
, nat.ht
, nat.wd
);
492 res.dp
= ext_xn_over_d
(tex.wd
, nat.dp
, nat.wd
);
494 } else if
(!is_running
(tex.ht
)) {
496 if
(!is_running
(tex.dp
)) {
498 /* height and depth specified
*/
499 res.wd
= ext_xn_over_d
(tex.ht
+ tex.dp
, nat.wd
, nat.ht
+ nat.dp
);
501 /* only height specified
*/
502 res.wd
= ext_xn_over_d
(tex.ht
, nat.wd
, nat.ht
);
503 res.dp
= ext_xn_over_d
(tex.ht
, nat.dp
, nat.ht
);
505 } else if
(!is_running
(tex.dp
)) {
507 /* only depth specified
*/
508 res.ht
= nat.ht
- (tex.dp
- nat.dp
);
511 /* nothing specified
*/
517 @ Within |scale_img
()| only image width and height matter
;
518 the offsets and positioning are not interesting here.
519 But one needs rotation info to swap width and height.
520 |img_rotation
()| comes from the optional
/Rotate key in the PDF file.
523 scaled_whd scale_img
(image_dict
* idict
, scaled_whd alt_rule
, int transform
)
525 int x
, y
, xr
, yr
, tmp
; /* size and resolution of image
*/
526 scaled_whd nat
; /* natural size corresponding to image resolution
*/
528 if
((img_type
(idict
) == IMG_TYPE_PDF || img_type
(idict
) == IMG_TYPE_PDFMEMSTREAM
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];
535 x
= img_xsize
(idict
); /* dimensions
, resolutions from image file
*/
536 y
= img_ysize
(idict
);
538 xr
= img_xres
(idict
);
539 yr
= img_yres
(idict
);
540 if
(x
<= 0 || y
<= 0 || xr
< 0 || yr
< 0)
541 normal_error
("pdf backend","invalid image dimensions");
542 if
(xr
> 65535 || yr
> 65535) {
545 normal_warning
("pdf backend","too large image resolution ignored");
547 if
(((transform
- img_rotation
(idict
)) & 1) == 1) {
555 nat.dp
= 0; /* always for images
*/
556 if
(img_type
(idict
) == IMG_TYPE_PDF || img_type
(idict
) == IMG_TYPE_PDFMEMSTREAM
557 || img_type
(idict
) == IMG_TYPE_PDFSTREAM
) {
561 default_res
= fix_int
(pdf_image_resolution
, 0, 65535);
562 if
(default_res
> 0 && (xr == 0 || yr == 0)) {
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
);
570 nat.wd
= ext_xn_over_d
(one_hundred_inch
, x
, 7200);
571 nat.ht
= ext_xn_over_d
(one_hundred_inch
, y
, 7200);
574 return tex_scale
(nat
, alt_rule
);
578 void write_img
(PDF pdf
, image_dict
* idict
)
580 if
(img_state
(idict
) < DICT_WRITTEN
) {
581 report_start_file
(filetype_image
, img_filepath
(idict
));
582 switch
(img_type
(idict
)) {
584 write_png
(pdf
, idict
);
587 write_jpg
(pdf
, idict
);
590 write_jp2
(pdf
, idict
);
593 write_jbig2
(pdf
, idict
);
595 case IMG_TYPE_PDFMEMSTREAM
:
597 write_epdf
(pdf
, idict
,(int
) pdf_suppress_optional_info
);
599 case IMG_TYPE_PDFSTREAM
:
600 write_pdfstream
(pdf
, idict
);
603 normal_error
("pdf backend","internal error: writing unknown image type");
605 report_stop_file
(filetype_image
);
606 if
(img_type
(idict
) == IMG_TYPE_PNG
) {
607 write_additional_png_objects
(pdf
);
610 if
(img_state
(idict
) < DICT_WRITTEN
)
611 img_state
(idict
) = DICT_WRITTEN
;
616 void pdf_write_image
(PDF pdf
, int n
)
618 if
(pdf-
>draftmode
== 0)
619 write_img
(pdf
, idict_array
[obj_data_ptr
(pdf
, n
)]);
623 void check_pdfstream_dict
(image_dict
* idict
)
625 if
(!img_is_bbox
(idict
))
626 normal_error
("pdf backend","image.stream: no bbox given");
627 if
(img_state
(idict
) < DICT_FILESCANNED
)
628 img_state
(idict
) = DICT_FILESCANNED
;
632 void write_pdfstream
(PDF pdf
, image_dict
* idict
)
634 pdf_begin_obj
(pdf
, img_objnum
(idict
), OBJSTM_NEVER
);
636 pdf_dict_add_name
(pdf
, "Type", "XObject");
637 pdf_dict_add_name
(pdf
, "Subtype", "Form");
638 if
(img_attr
(idict
) != NULL && strlen(img_attr(idict)) > 0)
639 pdf_printf
(pdf
, "\n%s\n", img_attr
(idict
));
640 pdf_dict_add_int
(pdf
, "FormType", 1);
641 pdf_add_name
(pdf
, "BBox");
642 pdf_begin_array
(pdf
);
643 copyReal
(pdf
, sp2bp
(img_bbox
(idict
)[0]));
644 copyReal
(pdf
, sp2bp
(img_bbox
(idict
)[1]));
645 copyReal
(pdf
, sp2bp
(img_bbox
(idict
)[2]));
646 copyReal
(pdf
, sp2bp
(img_bbox
(idict
)[3]));
648 pdf_dict_add_streaminfo
(pdf
);
650 pdf_begin_stream
(pdf
);
651 if
(img_pdfstream_stream
(idict
) != NULL)
652 pdf_puts
(pdf
, img_pdfstream_stream
(idict
));
658 idict_entry
*idict_ptr
, *idict_array
= NULL;
661 void idict_to_array
(image_dict
* idict
)
663 if
(idict_ptr
- idict_array
== 0) { /* align to count from
1 */
664 alloc_array
(idict
, 1, SMALL_BUF_SIZE
); /* /Im0 unused
*/
667 alloc_array
(idict
, 1, SMALL_BUF_SIZE
);
672 void pdf_dict_add_img_filename
(PDF pdf
, image_dict
* idict
)
675 if
((pdf_image_addfilename
> 0) && ((pdf_suppress_optional_info & 2) == 0)) {
676 /* for now PTEX.FileName only for PDF
, but prepared for JPG
, PNG
, ...
*/
677 if
(! ( (img_type
(idict
) == IMG_TYPE_PDF
) ||
(img_type
(idict
) == IMG_TYPE_PDFMEMSTREAM
) ))
679 if
(img_visiblefilename
(idict
) != NULL) {
680 if
(strlen
(img_visiblefilename
(idict
)) == 0) {
681 return
; /* empty string blocks PTEX.FileName output
*/
683 p
= img_visiblefilename
(idict
);
686 /* unset so let's use the default
*/
687 p
= img_filepath
(idict
);
689 // write additional information
690 pdf_add_name
(pdf
, "PTEX.FileName");
691 pdf_printf
(pdf
, " (%s)", convertStringToPDFString
(p
, strlen
(p
)));
695 /* hh
: why store images in the format ... let's get rid of this
*/
697 @ To allow the use of box resources inside saved boxes in
-ini mode
,
698 the information in the array has to be
(un
)dumped with the format.
699 The next two routines take care of that.
701 Most of the work involved in setting up the images is simply
702 executed again. This solves the many possible errors resulting from
703 the split in two separate runs.
705 There was only one problem remaining
: The pdfversion and
706 pdfinclusionerrorlevel can have changed inbetween the call to
707 |readimage
()| and dump time.
709 some of the dumped values are really type int
, not integer
,
710 but since the macro falls back to |generic_dump| anyway
, that
714 #define dumpinteger generic_dump
715 #define undumpinteger generic_undump
717 @
(un
)dumping a string means dumping the allocation size
, followed
718 by the bytes. The trailing \.
{\\
0} is dumped as well
, because that
719 makes the code simpler.
721 @ scan rule spec to |alt_rule|
723 scaled_whd scan_alt_rule
(void
)
727 alt_rule.wd
= null_flag
;
728 alt_rule.ht
= null_flag
;
729 alt_rule.dp
= null_flag
;
732 if
(scan_keyword
("width")) {
734 alt_rule.wd
= cur_val
;
736 } else if
(scan_keyword
("height")) {
738 alt_rule.ht
= cur_val
;
740 } else if
(scan_keyword
("depth")) {
742 alt_rule.dp
= cur_val
;
749 @ copy file of arbitrary size to PDF buffer and flush as needed
751 size_t read_file_to_buf
(PDF pdf
, FILE * f
, size_t len
)
755 i
= (size_t
) (len
> pdf-
>buf-
>size
) ?
(size_t
) pdf-
>buf-
>size
: len
;
756 pdf_room
(pdf
, (int
) i
);
757 j
= fread
(pdf-
>buf-
>p
, 1, i
, f
);