1 /* This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
2
3 Copyright (C) 2007-2014 by Jin-Hwan Cho and Shunsaku Hirata,
4 the dvipdfmx project team.
5
6 Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
21 */
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include "system.h"
28 #include "error.h"
29 #include "mem.h"
30
31 #include "dpxfile.h"
32
33 #include "pdfobj.h"
34
35 #include "pdfdoc.h"
36 #include "pdfdev.h"
37 #include "pdfdraw.h"
38
39 #include "epdf.h"
40 #include "mpost.h"
41 #include "pngimage.h"
42 #include "jpegimage.h"
43 #include "jp2image.h"
44 #include "bmpimage.h"
45
46 #include "pdfximage.h"
47
48 /* From psimage.h */
49 static int check_for_ps (FILE *fp);
50 static int ps_include_page (pdf_ximage *ximage, const char *file_name);
51
52
53 #define IMAGE_TYPE_UNKNOWN -1
54 #define IMAGE_TYPE_PDF 0
55 #define IMAGE_TYPE_JPEG 1
56 #define IMAGE_TYPE_PNG 2
57 #define IMAGE_TYPE_MPS 4
58 #define IMAGE_TYPE_EPS 5
59 #define IMAGE_TYPE_BMP 6
60 #define IMAGE_TYPE_JP2 7
61
62
63 struct attr_
64 {
65 long width, height;
66 double xdensity, ydensity;
67 pdf_rect bbox;
68 };
69
70 struct pdf_ximage_
71 {
72 char *ident;
73 char res_name[16];
74 long page_no, page_count;
75
76 int subtype;
77
78 struct attr_ attr;
79
80 char *filename;
81 pdf_obj *reference;
82 pdf_obj *resource;
83 pdf_obj *attr_dict;
84
85 char tempfile;
86 };
87
88
89 /* verbose, verbose, verbose... */
90 struct opt_
91 {
92 int verbose;
93 char *cmdtmpl;
94 };
95
96 static struct opt_ _opts = {
97 0, NULL
98 };
99
pdf_ximage_set_verbose(void)100 void pdf_ximage_set_verbose (void) { _opts.verbose++; }
101
102
103 struct ic_
104 {
105 int count, capacity;
106 pdf_ximage *ximages;
107 };
108
109 static struct ic_ _ic = {
110 0, 0, NULL
111 };
112
113 static void
pdf_init_ximage_struct(pdf_ximage * I,const char * ident,const char * filename,long page_no,pdf_obj * dict)114 pdf_init_ximage_struct (pdf_ximage *I,
115 const char *ident, const char *filename,
116 long page_no, pdf_obj *dict)
117 {
118 if (ident) {
119 I->ident = NEW(strlen(ident)+1, char);
120 strcpy(I->ident, ident);
121 } else
122 I ->ident = NULL;
123 I->page_no = page_no;
124 I->page_count = 0;
125 if (filename) {
126 I->filename = NEW(strlen(filename)+1, char);
127 strcpy(I->filename, filename);
128 } else
129 I->filename = NULL;
130 I->subtype = -1;
131 memset(I->res_name, 0, 16);
132 I->reference = NULL;
133 I->resource = NULL;
134 I->attr_dict = dict;
135
136 I->attr.width = I->attr.height = 0;
137 I->attr.xdensity = I->attr.ydensity = 1.0;
138 I->attr.bbox.llx = I->attr.bbox.lly = 0;
139 I->attr.bbox.urx = I->attr.bbox.ury = 0;
140
141 I->tempfile = 0;
142 }
143
144 static void
pdf_set_ximage_tempfile(pdf_ximage * I,const char * filename)145 pdf_set_ximage_tempfile (pdf_ximage *I, const char *filename)
146 {
147 if (I->filename)
148 RELEASE(I->filename);
149 I->filename = NEW(strlen(filename)+1, char);
150 strcpy(I->filename, filename);
151 I->tempfile = 1;
152 }
153
154 static void
pdf_clean_ximage_struct(pdf_ximage * I)155 pdf_clean_ximage_struct (pdf_ximage *I)
156 {
157 if (I->ident)
158 RELEASE(I->ident);
159 if (I->filename)
160 RELEASE(I->filename);
161 if (I->reference)
162 pdf_release_obj(I->reference);
163 if (I->resource)
164 pdf_release_obj(I->resource);
165 if (I->attr_dict)
166 pdf_release_obj(I->attr_dict);
167 pdf_init_ximage_struct(I, NULL, NULL, 0, NULL);
168 }
169
170
171 void
pdf_init_images(void)172 pdf_init_images (void)
173 {
174 struct ic_ *ic = &_ic;
175 ic->count = 0;
176 ic->capacity = 0;
177 ic->ximages = NULL;
178 }
179
180 void
pdf_close_images(void)181 pdf_close_images (void)
182 {
183 struct ic_ *ic = &_ic;
184 if (ic->ximages) {
185 int i;
186 for (i = 0; i < ic->count; i++) {
187 pdf_ximage *I = ic->ximages+i;
188 if (I->tempfile) {
189 /*
190 * It is important to remove temporary files at the end because
191 * we cache file names. Since we use mkstemp to create them, we
192 * might get the same file name again if we delete the first file.
193 * (This happens on NetBSD, reported by Jukka Salmi.)
194 * We also use this to convert a PS file only once if multiple
195 * pages are imported from that file.
196 */
197 if (_opts.verbose > 1 && keep_cache != 1)
198 MESG("pdf_image>> deleting temporary file \"%s\"\n", I->filename);
199 dpx_delete_temp_file(I->filename, false); /* temporary filename freed here */
200 I->filename = NULL;
201 }
202 pdf_clean_ximage_struct(I);
203 }
204 RELEASE(ic->ximages);
205 ic->ximages = NULL;
206 ic->count = ic->capacity = 0;
207 }
208
209 if (_opts.cmdtmpl)
210 RELEASE(_opts.cmdtmpl);
211 _opts.cmdtmpl = NULL;
212 }
213
214 static int
source_image_type(FILE * fp)215 source_image_type (FILE *fp)
216 {
217 int format = IMAGE_TYPE_UNKNOWN;
218
219 rewind(fp);
220 /*
221 * Make sure we check for PS *after* checking for MP since
222 * MP is a special case of PS.
223 */
224 if (check_for_jpeg(fp))
225 {
226 format = IMAGE_TYPE_JPEG;
227 }
228 else if (check_for_jp2(fp))
229 {
230 format = IMAGE_TYPE_JP2;
231 }
232 #ifdef HAVE_LIBPNG
233 else if (check_for_png(fp))
234 {
235 format = IMAGE_TYPE_PNG;
236 }
237 #endif
238 else if (check_for_bmp(fp))
239 {
240 format = IMAGE_TYPE_BMP;
241 } else if (check_for_pdf(fp)) {
242 format = IMAGE_TYPE_PDF;
243 } else if (check_for_mp(fp)) {
244 format = IMAGE_TYPE_MPS;
245 } else if (check_for_ps(fp)) {
246 format = IMAGE_TYPE_EPS;
247 } else {
248 format = IMAGE_TYPE_UNKNOWN;
249 }
250 rewind(fp);
251
252 return format;
253 }
254
255 static int
load_image(const char * ident,const char * fullname,int format,FILE * fp,long page_no,pdf_obj * dict)256 load_image (const char *ident, const char *fullname, int format, FILE *fp,
257 long page_no, pdf_obj *dict)
258 {
259 struct ic_ *ic = &_ic;
260 int id = -1; /* ret */
261 pdf_ximage *I;
262
263 id = ic->count;
264 if (ic->count >= ic->capacity) {
265 ic->capacity += 16;
266 ic->ximages = RENEW(ic->ximages, ic->capacity, pdf_ximage);
267 }
268
269 I = &ic->ximages[id];
270 pdf_init_ximage_struct(I, ident, fullname, page_no, dict);
271
272 switch (format) {
273 case IMAGE_TYPE_JPEG:
274 if (_opts.verbose)
275 MESG("[JPEG]");
276 if (jpeg_include_image(I, fp) < 0)
277 goto error;
278 I->subtype = PDF_XOBJECT_TYPE_IMAGE;
279 break;
280 case IMAGE_TYPE_JP2:
281 if (_opts.verbose)
282 MESG("[JP2]");
283 if (jp2_include_image(I, fp) < 0)
284 goto error;
285 I->subtype = PDF_XOBJECT_TYPE_IMAGE;
286 break;
287 #ifdef HAVE_LIBPNG
288 case IMAGE_TYPE_PNG:
289 if (_opts.verbose)
290 MESG("[PNG]");
291 if (png_include_image(I, fp) < 0)
292 goto error;
293 I->subtype = PDF_XOBJECT_TYPE_IMAGE;
294 break;
295 #endif
296 case IMAGE_TYPE_BMP:
297 if (_opts.verbose)
298 MESG("[BMP]");
299 if (bmp_include_image(I, fp) < 0)
300 goto error;
301 I->subtype = PDF_XOBJECT_TYPE_IMAGE;
302 break;
303 case IMAGE_TYPE_PDF:
304 if (_opts.verbose)
305 MESG("[PDF]");
306 {
307 int result = pdf_include_page(I, fp, fullname);
308 if (result > 0)
309 /* PDF version too recent */
310 result = ps_include_page(I, fullname);
311 if (result < 0)
312 goto error;
313 }
314 if (_opts.verbose)
315 MESG(",Page:%ld", I->page_no);
316 I->subtype = PDF_XOBJECT_TYPE_FORM;
317 break;
318 // case IMAGE_TYPE_EPS:
319 default:
320 if (_opts.verbose)
321 MESG(format == IMAGE_TYPE_EPS ? "[PS]" : "[UNKNOWN]");
322 if (ps_include_page(I, fullname) < 0)
323 goto error;
324 if (_opts.verbose)
325 MESG(",Page:%ld", I->page_no);
326 I->subtype = PDF_XOBJECT_TYPE_FORM;
327 }
328
329 switch (I->subtype) {
330 case PDF_XOBJECT_TYPE_IMAGE:
331 sprintf(I->res_name, "Im%d", id);
332 break;
333 case PDF_XOBJECT_TYPE_FORM:
334 sprintf(I->res_name, "Fm%d", id);
335 break;
336 default:
337 ERROR("Unknown XObject subtype: %d", I->subtype);
338 goto error;
339 }
340
341 ic->count++;
342
343 return id;
344
345 error:
346 pdf_clean_ximage_struct(I);
347 return -1;
348 }
349
350
351 #define dpx_find_file(n,d,s) (kpse_find_pict((n)))
352 #define dpx_fopen(n,m) (MFOPEN((n),(m)))
353 #define dpx_fclose(f) (MFCLOSE((f)))
354
355 int
pdf_ximage_findresource(const char * ident,long page_no,pdf_obj * dict)356 pdf_ximage_findresource (const char *ident, long page_no, pdf_obj *dict)
357 {
358 struct ic_ *ic = &_ic;
359 int id = -1;
360 pdf_ximage *I;
361 char *fullname, *f = NULL;
362 int format;
363 FILE *fp;
364
365 for (id = 0; id < ic->count; id++) {
366 I = &ic->ximages[id];
367 if (I->ident && !strcmp(ident, I->ident)) {
368 f = I->filename;
369 if (I->page_no == page_no + (page_no < 0 ? I->page_count+1 : 0) &&
370 I->attr_dict == dict) {
371 return id;
372 }
373 }
374 }
375
376 if (f) {
377 /* we already have converted this file; f is the temporary file name */
378 fullname = NEW(strlen(f)+1, char);
379 strcpy(fullname, f);
380 } else {
381 /* try loading image */
382 fullname = dpx_find_file(ident, "_pic_", "");
383 if (!fullname) {
384 WARN("Error locating image file \"%s\"", ident);
385 return -1;
386 }
387 }
388
389 fp = dpx_fopen(fullname, FOPEN_RBIN_MODE);
390 if (!fp) {
391 WARN("Error opening image file \"%s\"", fullname);
392 RELEASE(fullname);
393 return -1;
394 }
395 if (_opts.verbose) {
396 MESG("(Image:%s", ident);
397 if (_opts.verbose > 1)
398 MESG("[%s]", fullname);
399 }
400
401 format = source_image_type(fp);
402 switch (format) {
403 case IMAGE_TYPE_MPS:
404 if (_opts.verbose)
405 MESG("[MPS]");
406 id = mps_include_page(ident, fp);
407 if (id < 0) {
408 WARN("Try again with the distiller.");
409 format = IMAGE_TYPE_EPS;
410 rewind(fp);
411 } else
412 break;
413 default:
414 id = load_image(ident, fullname, format, fp, page_no, dict);
415 break;
416 }
417 dpx_fclose(fp);
418
419 RELEASE(fullname);
420
421 if (_opts.verbose)
422 MESG(")");
423
424 if (id < 0)
425 WARN("pdf: image inclusion failed for \"%s\".", ident);
426
427 return id;
428 }
429
430 /* Reference: PDF Reference 1.5 v6, pp.321--322
431 *
432 * TABLE 4.42 Additional entries specific to a type 1 form dictionary
433 *
434 * BBox rectangle (Required) An array of four numbers in the form coordinate
435 * system, giving the coordinates of the left, bottom, right,
436 * and top edges, respectively, of the form XObject's bounding
437 * box. These boundaries are used to clip the form XObject and
438 * to determine its size for caching.
439 *
440 * Matrix array (Optional) An array of six numbers specifying the form
441 * matrix, which maps form space into user space.
442 * Default value: the identity matrix [1 0 0 1 0 0].
443 */
444 void
pdf_ximage_init_form_info(xform_info * info)445 pdf_ximage_init_form_info (xform_info *info)
446 {
447 info->flags = 0;
448 info->bbox.llx = 0;
449 info->bbox.lly = 0;
450 info->bbox.urx = 0;
451 info->bbox.ury = 0;
452 info->matrix.a = 1.0;
453 info->matrix.b = 0.0;
454 info->matrix.c = 0.0;
455 info->matrix.d = 1.0;
456 info->matrix.e = 0.0;
457 info->matrix.f = 0.0;
458 }
459
460 /* Reference: PDF Reference 1.5 v6, pp.303--306
461 *
462 * TABLE 4.42 Additional entries specific to an image dictionary
463 *
464 * Width integer (Required) The width of the image, in samples.
465 *
466 * Height integer (Required) The height of the image, in samples.
467 *
468 * ColorSpace name or array
469 * (Required for images, except those that use the JPXDecode
470 * filter; not allowed for image masks) The color space in
471 * which image samples are specified. This may be any type
472 * of color space except Patter.
473 *
474 * If the image uses the JPXDecode filter, this entry is
475 * optional.
476 *
477 * BitsPerComponent integer
478 * (Required except for image masks and images that use the
479 * JPXDecode filter) The number of bits used to represent
480 * each color component. Only a single value may be specified;
481 * the number of bits is the same for all color components.
482 * Valid values are 1,2,4,8, and (in PDF1.5) 16. If ImageMask
483 * is true, this entry is optional, and if speficified, its
484 * value must be 1.
485 *
486 * If the image stream uses the JPXDecode filter, this entry
487 * is optional and ignored if present. The bit depth is
488 * determined in the process of decoding the JPEG2000 image.
489 */
490 void
pdf_ximage_init_image_info(ximage_info * info)491 pdf_ximage_init_image_info (ximage_info *info)
492 {
493 info->flags = 0;
494 info->width = 0;
495 info->height = 0;
496 info->bits_per_component = 0;
497 info->num_components = 0;
498 info->min_dpi = 0;
499 info->xdensity = info->ydensity = 1.0;
500 }
501
502 void
pdf_ximage_set_image(pdf_ximage * I,void * image_info,pdf_obj * resource)503 pdf_ximage_set_image (pdf_ximage *I, void *image_info, pdf_obj *resource)
504 {
505 pdf_obj *dict;
506 ximage_info *info = image_info;
507
508 if (!PDF_OBJ_STREAMTYPE(resource))
509 ERROR("Image XObject must be of stream type.");
510
511 I->subtype = PDF_XOBJECT_TYPE_IMAGE;
512
513 I->attr.width = info->width; /* The width of the image, in samples */
514 I->attr.height = info->height; /* The height of the image, in samples */
515 I->attr.xdensity = info->xdensity;
516 I->attr.ydensity = info->ydensity;
517
518 I->reference = pdf_ref_obj(resource);
519
520 dict = pdf_stream_dict(resource);
521 pdf_add_dict(dict, pdf_new_name("Type"), pdf_new_name("XObject"));
522 pdf_add_dict(dict, pdf_new_name("Subtype"), pdf_new_name("Image"));
523 pdf_add_dict(dict, pdf_new_name("Width"), pdf_new_number(info->width));
524 pdf_add_dict(dict, pdf_new_name("Height"), pdf_new_number(info->height));
525 if (info->bits_per_component > 0) /* Ignored for JPXDecode filter. FIXME */
526 pdf_add_dict(dict, pdf_new_name("BitsPerComponent"),
527 pdf_new_number(info->bits_per_component));
528 if (I->attr_dict)
529 pdf_merge_dict(dict, I->attr_dict);
530
531 pdf_release_obj(resource); /* Caller don't know we are using reference. */
532 I->resource = NULL;
533 }
534
535 void
pdf_ximage_set_form(pdf_ximage * I,void * form_info,pdf_obj * resource)536 pdf_ximage_set_form (pdf_ximage *I, void *form_info, pdf_obj *resource)
537 {
538 xform_info *info = form_info;
539
540 I->subtype = PDF_XOBJECT_TYPE_FORM;
541
542 I->attr.bbox.llx = info->bbox.llx;
543 I->attr.bbox.lly = info->bbox.lly;
544 I->attr.bbox.urx = info->bbox.urx;
545 I->attr.bbox.ury = info->bbox.ury;
546
547 I->reference = pdf_ref_obj(resource);
548
549 pdf_release_obj(resource); /* Caller don't know we are using reference. */
550 I->resource = NULL;
551 }
552
553 long
pdf_ximage_get_page(pdf_ximage * I)554 pdf_ximage_get_page (pdf_ximage *I)
555 {
556 return I->page_no;
557 }
558
559 #define CHECK_ID(c,n) do {\
560 if ((n) < 0 || (n) >= (c)->count) {\
561 ERROR("Invalid XObject ID: %d", (n));\
562 }\
563 } while (0)
564 #define GET_IMAGE(c,n) (&((c)->ximages[(n)]))
565
566 pdf_obj *
pdf_ximage_get_reference(int id)567 pdf_ximage_get_reference (int id)
568 {
569 struct ic_ *ic = &_ic;
570 pdf_ximage *I;
571
572 CHECK_ID(ic, id);
573
574 I = GET_IMAGE(ic, id);
575 if (!I->reference)
576 I->reference = pdf_ref_obj(I->resource);
577
578 return pdf_link_obj(I->reference);
579 }
580
581 /* called from pdfdoc.c only for late binding */
582 int
pdf_ximage_defineresource(const char * ident,int subtype,void * info,pdf_obj * resource)583 pdf_ximage_defineresource (const char *ident,
584 int subtype, void *info, pdf_obj *resource)
585 {
586 struct ic_ *ic = &_ic;
587 int id;
588 pdf_ximage *I;
589
590 id = ic->count;
591 if (ic->count >= ic->capacity) {
592 ic->capacity += 16;
593 ic->ximages = RENEW(ic->ximages, ic->capacity, pdf_ximage);
594 }
595
596 I = &ic->ximages[id];
597
598 pdf_init_ximage_struct(I, ident, NULL, 0, NULL);
599
600 switch (subtype) {
601 case PDF_XOBJECT_TYPE_IMAGE:
602 pdf_ximage_set_image(I, info, resource);
603 sprintf(I->res_name, "Im%d", id);
604 break;
605 case PDF_XOBJECT_TYPE_FORM:
606 pdf_ximage_set_form (I, info, resource);
607 sprintf(I->res_name, "Fm%d", id);
608 break;
609 default:
610 ERROR("Unknown XObject subtype: %d", subtype);
611 }
612 ic->count++;
613
614 return id;
615 }
616
617
618 char *
pdf_ximage_get_resname(int id)619 pdf_ximage_get_resname (int id)
620 {
621 struct ic_ *ic = &_ic;
622 pdf_ximage *I;
623
624 CHECK_ID(ic, id);
625
626 I = GET_IMAGE(ic, id);
627
628 return I->res_name;
629 }
630
631 int
pdf_ximage_get_subtype(int id)632 pdf_ximage_get_subtype (int id)
633 {
634 struct ic_ *ic = &_ic;
635 pdf_ximage *I;
636
637 CHECK_ID(ic, id);
638
639 I = GET_IMAGE(ic, id);
640
641 return I->subtype;
642 }
643
644 void
pdf_ximage_set_attr(int id,long width,long height,double xdensity,double ydensity,double llx,double lly,double urx,double ury)645 pdf_ximage_set_attr (int id, long width, long height, double xdensity, double ydensity, double llx, double lly, double urx, double ury)
646 {
647 struct ic_ *ic = &_ic;
648 pdf_ximage *I;
649
650 CHECK_ID(ic, id);
651
652 I = GET_IMAGE(ic, id);
653 I->attr.width = width;
654 I->attr.height = height;
655 I->attr.xdensity = xdensity;
656 I->attr.ydensity = ydensity;
657 I->attr.bbox.llx = llx;
658 I->attr.bbox.lly = lly;
659 I->attr.bbox.urx = urx;
660 I->attr.bbox.ury = ury;
661 }
662
663 /* depth...
664 * Dvipdfm treat "depth" as "yoffset" for pdf:image and pdf:uxobj
665 * not as vertical dimension of scaled image. (And there are bugs.)
666 * This part contains incompatibile behaviour than dvipdfm!
667 */
668 #define EBB_DPI 72
669
670 static void
scale_to_fit_I(pdf_tmatrix * T,transform_info * p,pdf_ximage * I)671 scale_to_fit_I (pdf_tmatrix *T,
672 transform_info *p,
673 pdf_ximage *I)
674 {
675 double s_x, s_y, d_x, d_y;
676 double wd0, ht0, dp, xscale, yscale;
677
678 if (p->flags & INFO_HAS_USER_BBOX) {
679 wd0 = p->bbox.urx - p->bbox.llx;
680 ht0 = p->bbox.ury - p->bbox.lly;
681 xscale = I->attr.width * I->attr.xdensity / wd0;
682 yscale = I->attr.height * I->attr.ydensity / ht0;
683 d_x = -p->bbox.llx / wd0;
684 d_y = -p->bbox.lly / ht0;
685 } else {
686 wd0 = I->attr.width * I->attr.xdensity;
687 ht0 = I->attr.height * I->attr.ydensity;
688 xscale = yscale = 1.0;
689 d_x = 0.0;
690 d_y = 0.0;
691 }
692
693 if (wd0 == 0.0) {
694 WARN("Image width=0.0!");
695 wd0 = 1.0;
696 }
697 if (ht0 == 0.0) {
698 WARN("Image height=0.0!");
699 ht0 = 1.0;
700 }
701
702 if ( (p->flags & INFO_HAS_WIDTH ) &&
703 (p->flags & INFO_HAS_HEIGHT) ) {
704 s_x = p->width * xscale;
705 s_y = (p->height + p->depth) * yscale;
706 dp = p->depth * yscale;
707 } else if ( p->flags & INFO_HAS_WIDTH ) {
708 s_x = p->width * xscale;
709 s_y = s_x * ((double)I->attr.height / I->attr.width);
710 dp = 0.0;
711 } else if ( p->flags & INFO_HAS_HEIGHT) {
712 s_y = (p->height + p->depth) * yscale;
713 s_x = s_y * ((double)I->attr.width / I->attr.height);
714 dp = p->depth * yscale;
715 } else {
716 s_x = wd0;
717 s_y = ht0;
718 dp = 0.0;
719 }
720 T->a = s_x; T->c = 0.0;
721 T->b = 0.0; T->d = s_y;
722 T->e = d_x * s_x / xscale; T->f = d_y * s_y / yscale - dp;
723
724 return;
725 }
726
727
728 static void
scale_to_fit_F(pdf_tmatrix * T,transform_info * p,pdf_ximage * I)729 scale_to_fit_F (pdf_tmatrix *T,
730 transform_info *p,
731 pdf_ximage *I)
732 {
733 double s_x, s_y, d_x, d_y;
734 double wd0, ht0, dp;
735
736 if (p->flags & INFO_HAS_USER_BBOX) {
737 wd0 = p->bbox.urx - p->bbox.llx;
738 ht0 = p->bbox.ury - p->bbox.lly;
739 d_x = -p->bbox.llx;
740 d_y = -p->bbox.lly;
741 } else {
742 wd0 = I->attr.bbox.urx - I->attr.bbox.llx;
743 ht0 = I->attr.bbox.ury - I->attr.bbox.lly;
744 d_x = 0.0;
745 d_y = 0.0;
746 }
747
748 if (wd0 == 0.0) {
749 WARN("Image width=0.0!");
750 wd0 = 1.0;
751 }
752 if (ht0 == 0.0) {
753 WARN("Image height=0.0!");
754 ht0 = 1.0;
755 }
756
757 if ( (p->flags & INFO_HAS_WIDTH ) &&
758 (p->flags & INFO_HAS_HEIGHT) ) {
759 s_x = p->width / wd0;
760 s_y = (p->height + p->depth) / ht0;
761 dp = p->depth;
762 } else if ( p->flags & INFO_HAS_WIDTH ) {
763 s_x = p->width / wd0;
764 s_y = s_x;
765 dp = 0.0;
766 } else if ( p->flags & INFO_HAS_HEIGHT) {
767 s_y = (p->height + p->depth) / ht0;
768 s_x = s_y;
769 dp = p->depth;
770 } else {
771 s_x = s_y = 1.0;
772 dp = 0.0;
773 }
774
775 T->a = s_x; T->c = 0.0;
776 T->b = 0.0; T->d = s_y;
777 T->e = s_x * d_x; T->f = s_y * d_y - dp;
778
779 return;
780 }
781
782
783 /* called from pdfdev.c and spc_html.c */
784 int
pdf_ximage_scale_image(int id,pdf_tmatrix * M,pdf_rect * r,transform_info * p)785 pdf_ximage_scale_image (int id,
786 pdf_tmatrix *M, /* return value for trans matrix */
787 pdf_rect *r, /* return value for clipping */
788 transform_info *p /* argument from specials */
789 )
790 {
791 struct ic_ *ic = &_ic;
792 pdf_ximage *I;
793
794 CHECK_ID(ic, id);
795
796 I = GET_IMAGE(ic, id);
797
798 pdf_setmatrix(M, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
799
800 switch (I->subtype) {
801 /* Reference: PDF Reference 1.5 v6, p.302
802 *
803 * An image can be placed on the output page in any desired position,
804 * orientation, and size by using the cm operator to modify the current
805 * transformation matrix (CTM) so as to map the unit square of user space
806 * to the rectangle or parallelogram in which the image is to be painted.
807 *
808 * There is neither BBox nor Matrix key in the image XObject.
809 * Everything must be controlled by the cm operator.
810 *
811 * The argument [p] contains the user-defined bounding box, the scailing
812 * factor of which is bp as EPS and PDF. On the other hand, I->attr
813 * contains the (sampling) width and the (sampling) height of the image.
814 *
815 * There is no problem if a bitmap image has density information.
816 * Otherwise, DVIPDFM's ebb generates bounding box as 100px = 72bp = 1in.
817 * In this case, screen captured images look bad. Moreover, DVIPDFM's ebb
818 * ignores all density information and use just 100px = 72bp = 1in.
819 *
820 * On the other hand, pdfTeX uses 100px = 100bp to get a better quality
821 * for screen captured images.
822 *
823 * DVIPDFMx's xbb generates bounding box as 100px = 100bp in the same
824 * way as pdfTeX. Furthermore, it takes care of density information too.
825 */
826 case PDF_XOBJECT_TYPE_IMAGE:
827 scale_to_fit_I(M, p, I);
828 if (p->flags & INFO_HAS_USER_BBOX) {
829 r->llx = p->bbox.llx / (I->attr.width * I->attr.xdensity);
830 r->lly = p->bbox.lly / (I->attr.height * I->attr.ydensity);
831 r->urx = p->bbox.urx / (I->attr.width * I->attr.xdensity);
832 r->ury = p->bbox.ury / (I->attr.height * I->attr.ydensity);
833 } else {
834 r->llx = 0.0;
835 r->lly = 0.0;
836 r->urx = 1.0;
837 r->ury = 1.0;
838 }
839 break;
840 /* User-defined transformation and clipping are controlled by
841 * the cm operator and W operator, explicitly */
842 case PDF_XOBJECT_TYPE_FORM:
843 scale_to_fit_F(M, p, I);
844 if (p->flags & INFO_HAS_USER_BBOX) {
845 r->llx = p->bbox.llx;
846 r->lly = p->bbox.lly;
847 r->urx = p->bbox.urx;
848 r->ury = p->bbox.ury;
849 } else { /* I->attr.bbox from the image bounding box */
850 r->llx = I->attr.bbox.llx;
851 r->lly = I->attr.bbox.lly;
852 r->urx = I->attr.bbox.urx;
853 r->ury = I->attr.bbox.ury;
854 }
855 break;
856 }
857
858 return 0;
859 }
860
861
862 /* Migrated from psimage.c */
863
set_distiller_template(char * s)864 void set_distiller_template (char *s)
865 {
866 if (_opts.cmdtmpl)
867 RELEASE(_opts.cmdtmpl);
868 if (!s || *s == '\0')
869 _opts.cmdtmpl = NULL;
870 else {
871 _opts.cmdtmpl = NEW(strlen(s) + 1, char);
872 strcpy(_opts.cmdtmpl, s);
873 }
874 return;
875 }
876
get_distiller_template(void)877 char *get_distiller_template (void)
878 {
879 return _opts.cmdtmpl;
880 }
881
882 static int
ps_include_page(pdf_ximage * ximage,const char * filename)883 ps_include_page (pdf_ximage *ximage, const char *filename)
884 {
885 char *distiller_template = _opts.cmdtmpl;
886 char *temp;
887 FILE *fp;
888 int error = 0;
889 struct stat stat_o, stat_t;
890
891 if (!distiller_template) {
892 WARN("No image converter available for converting file \"%s\" to PDF format.", filename);
893 WARN(">> Please check if you have 'D' option in config file.");
894 return -1;
895 }
896
897 temp = dpx_create_fix_temp_file(filename);
898 if (!temp) {
899 WARN("Failed to create temporary file for image conversion: %s", filename);
900 return -1;
901 }
902
903 #ifdef MIKTEX
904 {
905 char *p;
906 for (p = (char *)filename; *p; p++) {
907 if (*p == '\\') *p = '/';
908 }
909 for (p = (char *)temp; *p; p++) {
910 if (*p == '\\') *p = '/';
911 }
912 }
913 #endif
914
915 if (keep_cache != -1 && stat(temp, &stat_t)==0 && stat(filename, &stat_o)==0
916 && stat_t.st_mtime > stat_o.st_mtime) {
917 /* cache exist */
918 /*printf("\nLast file modification: %s", ctime(&stat_o.st_mtime));
919 printf("Last file modification: %s", ctime(&stat_t.st_mtime));*/
920 ;
921 } else {
922 if (_opts.verbose > 1) {
923 MESG("\n");
924 MESG("pdf_image>> Converting file \"%s\" --> \"%s\" via:\n", filename, temp);
925 MESG("pdf_image>> %s\n", distiller_template);
926 MESG("pdf_image>> ...");
927 }
928 error = dpx_file_apply_filter(distiller_template, filename, temp,
929 (unsigned char) pdf_get_version());
930 if (error) {
931 WARN("Image format conversion for \"%s\" failed...", filename);
932 dpx_delete_temp_file(temp, true);
933 return error;
934 }
935 }
936
937 fp = MFOPEN(temp, FOPEN_RBIN_MODE);
938 if (!fp) {
939 WARN("Could not open conversion result \"%s\" for image \"%s\". Why?", temp, filename);
940 dpx_delete_temp_file(temp, true);
941 return -1;
942 }
943 pdf_set_ximage_tempfile(ximage, temp);
944 #if 0
945 error = pdf_include_page(ximage, fp, 0, pdfbox_crop);
946 #endif
947 error = pdf_include_page(ximage, fp, temp);
948 MFCLOSE(fp);
949
950 /* See pdf_close_images for why we cannot delete temporary files here. */
951
952 RELEASE(temp);
953
954 if (error) {
955 WARN("Failed to include image file \"%s\"", filename);
956 WARN(">> Please check if");
957 WARN(">> %s", distiller_template);
958 WARN(">> %%o = output filename, %%i = input filename, %%b = input filename without suffix");
959 WARN(">> can really convert \"%s\" to PDF format image.", filename);
960 }
961
962 return error;
963 }
964
check_for_ps(FILE * image_file)965 static int check_for_ps (FILE *image_file)
966 {
967 rewind (image_file);
968 mfgets (work_buffer, WORK_BUFFER_SIZE, image_file);
969 if (!strncmp (work_buffer, "%!", 2))
970 return 1;
971 return 0;
972 }
973