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