Back to index

texmacs  1.0.7.15
image_files.cpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : image_files.cpp
00004 * DESCRIPTION: image file handling
00005 * COPYRIGHT  : (C) 1999  Joris van der Hoeven
00006 *******************************************************************************
00007 * This software falls under the GNU general public license version 3 or later.
00008 * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
00009 * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
00010 ******************************************************************************/
00011 
00012 #include "file.hpp"
00013 #include "image_files.hpp"
00014 #include "web_files.hpp"
00015 #include "sys_utils.hpp"
00016 #include "analyze.hpp"
00017 #include "hashmap.hpp"
00018 #include "scheme.hpp"
00019 #include "Imlib2/imlib2.hpp"
00020 
00021 #ifdef MACOSX_EXTENSIONS
00022 #include "MacOS/mac_images.h"
00023 #endif
00024 
00025 #ifdef QTTEXMACS
00026 #include "Qt/qt_utilities.hpp"
00027 #endif
00028 
00029 #ifdef OS_WIN32
00030 #include <x11/xlib.h>
00031 #endif
00032 
00033 #ifdef USE_GS
00034 #include "Ghostscript/gs_utilities.hpp"
00035 #endif
00036 
00037 hashmap<tree,string> ps_bbox ("");
00038 
00039 /******************************************************************************
00040 * Loading xpm pixmaps
00041 ******************************************************************************/
00042 
00043 tree
00044 xpm_load (url u) {
00045   string s;
00046   load_string ("$TEXMACS_PIXMAP_PATH" * u, s, false);
00047   if (s == "") load_string ("$TEXMACS_PATH/misc/pixmaps/TeXmacs.xpm", s, true);
00048 
00049   int i, j;
00050   tree t (TUPLE);
00051   for (i=0; i<N(s); i++)
00052     if (s[i]=='\x22') {
00053       i++;
00054       j=i;
00055       while ((i<N(s)) && (s[i]!='\x22')) i++;
00056       t << s (j, i);
00057     }
00058   if (N(t)==0) return xpm_load ("$TEXMACS_PATH/misc/pixmaps/TeXmacs.xpm");
00059   return t;
00060 }
00061 
00062 void
00063 xpm_size (url u, int& w, int& h) {
00064   static hashmap<string,string> xpm_size_table ("");
00065   string file_name= as_string (u);
00066   if (!xpm_size_table->contains (file_name)) {
00067     tree t= xpm_load (u);
00068     xpm_size_table (file_name)= t[0]->label;
00069   }
00070 
00071   int i= 0;
00072   bool ok;
00073   string s= xpm_size_table[file_name];
00074   skip_spaces (s, i);
00075   ok= read_int (s, i, w);
00076   skip_spaces (s, i);
00077   ok= read_int (s, i, h) && ok;
00078   if (!ok) {
00079     cerr << "File name= " << file_name << "\n";
00080     FAILED ("invalid xpm");
00081   }
00082 }
00083 
00084 array<string>
00085 xpm_colors (tree t) {
00086   array<string> res(0);
00087   string s= t[0]->label;
00088   int ok, i=0, j, k, w, h, c, b;
00089   skip_spaces (s, i);
00090   ok= read_int (s, i, w);
00091   skip_spaces (s, i);
00092   ok= read_int (s, i, h) && ok;
00093   skip_spaces (s, i);
00094   ok= read_int (s, i, c) && ok;
00095   skip_spaces (s, i);
00096   ok= read_int (s, i, b) && ok;
00097   ASSERT (ok && N(t)>c && c>0, "invalid xpm tree");
00098 
00099   for (k=0; k<c; k++) {
00100     string s   = as_string (t[k+1]);
00101     string def = "none";
00102     if (N(s)<b) i=N(s); else i=b;
00103 
00104     skip_spaces (s, i);
00105     if ((i<N(s)) && (s[i]=='s')) {
00106       i++;
00107       skip_spaces (s, i);
00108       while ((i<N(s)) && (s[i]!=' ') && (s[i]!='\t')) i++;
00109       skip_spaces (s, i);
00110     }
00111     if ((i<N(s)) && (s[i]=='c')) {
00112       i++;
00113       skip_spaces (s, i);
00114       j=i;
00115       while ((i<N(s)) && (s[i]!=' ') && (s[i]!='\t')) i++;
00116       def= locase_all (s (j, i));
00117     }
00118     res<<def;
00119   }
00120   return res;
00121 }
00122 
00123 array<SI>
00124 xpm_hotspot (tree t) {
00125   array<SI> res(0);
00126   string s= t[0]->label;
00127   int ok, i=0, w, h, c, b, x, y;
00128   skip_spaces (s, i);
00129   ok= read_int (s, i, w);
00130   skip_spaces (s, i);
00131   ok= read_int (s, i, h) && ok;
00132   skip_spaces (s, i);
00133   ok= read_int (s, i, c) && ok;
00134   skip_spaces (s, i);
00135   ok= read_int (s, i, b) && ok;
00136   ASSERT (ok && N(t)>c && c>0, "invalid xpm tree");
00137 
00138   skip_spaces (s, i);
00139   ok= read_int (s, i, x) && ok;
00140   skip_spaces (s, i);
00141   ok= read_int (s, i, y) && ok;
00142   if (ok) {
00143     res<<x;
00144     res<<y;
00145   }
00146   return res;
00147 }
00148 
00149 /******************************************************************************
00150 * Loading postscript files or conversion to postscript
00151 ******************************************************************************/
00152 
00153 string
00154 ps_load (url image) {
00155   url name= resolve (image);
00156   if (is_none (name))
00157     name= "$TEXMACS_PATH/misc/pixmaps/unknown.ps";
00158 
00159 #ifdef OS_WIN32
00160   if (is_ramdisc (name)) name= get_from_ramdisc (name);
00161 #endif
00162 
00163   string s, suf= suffix (name);
00164   if (suf == "ps" || suf == "eps") load_string (name, s, false);
00165   else s= as_string (call ("image->postscript", object (name)));
00166 
00167 #ifdef OS_WIN32
00168   if (s == "") {
00169     char *data;
00170     char *path= as_charp (as_string (name));
00171     data= XLoadImageAsPS (path);
00172     tm_delete_array (path);
00173     if (!data) s= "";
00174     else {
00175       s= string (data);
00176       free (data);
00177     }
00178   }
00179 #endif
00180 
00181   if (s == "") load_string ("$TEXMACS_PATH/misc/pixmaps/unknown.ps", s, true);
00182   return s;
00183 }
00184 
00185 void
00186 ps_bounding_box (url image, int& x1, int& y1, int& x2, int& y2) {
00187   tree lookup= image->t;
00188   if (!ps_bbox->contains (image->t)) {
00189     int i;
00190     string s= ps_load (image);
00191     string r= "0 0 32 32";
00192     for (i=0; i<N(s); i++)
00193       if (read (s, i, "%%BoundingBox: ")) {
00194        double tmp;
00195        int j = i;
00196        read_line (s, i, r);
00197        // Check whether we really have a bounding box line with numbers
00198        skip_spaces (s, j);
00199        if(read_double (s, j, tmp))
00200          break;
00201       }
00202     ps_bbox (image->t)= r;
00203   }
00204 
00205   int i= 0;
00206   bool ok;
00207   string s= ps_bbox [image->t];
00208   double X1=0.0, Y1=0.0, X2=0.0, Y2=0.0;
00209   skip_spaces (s, i);
00210   ok= read_double (s, i, X1);
00211   skip_spaces (s, i);
00212   ok= read_double (s, i, Y1) && ok;
00213   skip_spaces (s, i);
00214   ok= read_double (s, i, X2) && ok;
00215   skip_spaces (s, i);
00216   ok= read_double (s, i, Y2) && ok;
00217   x1= (int) X1; y1= (int) Y1;
00218   x2= (int) X2; y2= (int) Y2;
00219   if (ok) return;
00220   x1= y1= 0; x2= 596; y2= 842;
00221 }
00222 
00223 /******************************************************************************
00224 * Getting the size of an image, using internal plug-ins if possible
00225 ******************************************************************************/
00226 
00227 void
00228 image_size (url image, int& w, int& h) {
00229 #ifdef QTTEXMACS
00230   if (qt_supports (image)) {
00231     qt_image_size (image, w, h); // default to 72 dpi
00232     //cout << "qt " << image << ", " << w << ", " << h << "\n";
00233     return;
00234   }
00235 #endif
00236 #ifdef MACOSX_EXTENSIONS 
00237   if (mac_image_size (image, w, h) ) {
00238     //cout << "mac " << image << ", " << w << ", " << h << "\n";
00239     return;
00240   }
00241 #endif
00242 #ifdef USE_IMLIB2
00243   if (imlib2_supports (image)) {
00244     imlib2_image_size (image, w, h);
00245     //cout << "imlib2 " << image << ", " << w << ", " << h << "\n";
00246     return;
00247   }
00248 #endif
00249 #ifdef USE_GS
00250   if (gs_supports (image)) {
00251     gs_image_size (image, w, h);
00252     //cout << "gs " << image << ", " << w << ", " << h << "\n";
00253     return;
00254   }
00255 #endif
00256   int x1, y1, x2, y2;
00257   ps_bounding_box (image, x1, y1, x2, y2);
00258   w= x2 - x1;
00259   h= y2 - y1;
00260   //cout << "default " << image << ", " << w << ", " << h << "\n";
00261 }
00262 
00263 /******************************************************************************
00264 * Converting image formats
00265 ******************************************************************************/
00266 
00267 void
00268 image_to_eps (url image, url eps, int w_pt, int h_pt, int dpi) {
00269 /*  if ((suffix (eps) != "eps") && (suffix (eps) != "ps")) {
00270     cerr << "TeXmacs] warning: " << concretize (eps) << " has no .eps or .ps suffix\n";
00271   }*/
00272 #ifdef QTTEXMACS
00273   if (qt_supports (image)) {
00274     qt_image_to_eps (image, eps, w_pt, h_pt, dpi);
00275     return;
00276   }
00277 #endif
00278 #ifdef USE_GS
00279   if (gs_supports (image)) {
00280     gs_to_eps (image, eps);
00281     return;
00282   }
00283 #endif
00284   string s= suffix (image);
00285   string cmd= "convert";
00286   if (s != "pdf" && s != "ps" && s != "eps" && dpi > 0 && w_pt > 0 && h_pt > 0) {
00287     int ww= w_pt * dpi / 72;
00288     int hh= h_pt * dpi / 72;
00289     string sz= eval_system ("identify -format \"%[fx:w] %[fx:h]\"", image);
00290     int w_px, h_px, ok= true, pos= 0;
00291     ok= read_int (sz, pos, w_px);
00292     skip_spaces (sz, pos);  
00293     ok= ok && read_int (sz, pos, h_px);
00294     if (ok && (ww < w_px || hh < h_px)) {
00295       cmd << " -resize " * as_string (ww) * "x" * as_string (hh) * "!";
00296     }
00297   }
00298   system (cmd, image, eps);
00299 }
00300 
00301 string
00302 image_to_psdoc (url image) {
00303   url psfile= url_temp (".eps");
00304   image_to_eps (image, psfile);
00305   string psdoc;
00306   load_string (psfile, psdoc, false);
00307   remove (psfile);
00308   return psdoc;
00309 }
00310 
00311 void
00312 image_to_png (url image, url png, int w, int h) {
00313 /*  if (suffix (png) != "png") {
00314     cerr << "TeXmacs] warning: " << concretize (png) << " has no .png suffix\n";
00315   }*/
00316 #ifdef MACOSX_EXTENSIONS
00317   //cout << "mac convert " << image << ", " << png << "\n";
00318   if (mac_supports (image)) {
00319     mac_image_to_png (image, png, w, h);
00320     return;
00321   }
00322 #endif
00323 #ifdef QTTEXMACS
00324   if (qt_supports (image)) {
00325     //cout << "qt convert " << image << ", " << png << "\n";
00326     qt_convert_image (image, png, w, h);
00327     return;
00328   }
00329 #endif
00330 #ifdef USE_GS
00331   if (gs_supports (image)) {
00332     //cout << "gs convert " << image << ", " << png << "\n";
00333     gs_to_png (image, png, w, h);
00334     return;
00335   }
00336 #endif
00337   //cout << "default convert " << image << ", " << png << "\n";
00338   string cmd= "convert";
00339   if (w > 0 && h > 0) cmd << " -resize " * as_string(w) * "x" * as_string(h) * "!";
00340   system (cmd, image, png);
00341 }
00342