OSDN Git Service

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