PLearn 0.1
GhostScript.cc
Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 // PLearn (A C++ Machine Learning Library)
00004 // Copyright (C) 1998 Pascal Vincent
00005 // Copyright (C) 1999-2002 Pascal Vincent, Yoshua Bengio and University of Montreal
00006 //
00007 
00008 // Redistribution and use in source and binary forms, with or without
00009 // modification, are permitted provided that the following conditions are met:
00010 // 
00011 //  1. Redistributions of source code must retain the above copyright
00012 //     notice, this list of conditions and the following disclaimer.
00013 // 
00014 //  2. Redistributions in binary form must reproduce the above copyright
00015 //     notice, this list of conditions and the following disclaimer in the
00016 //     documentation and/or other materials provided with the distribution.
00017 // 
00018 //  3. The name of the authors may not be used to endorse or promote
00019 //     products derived from this software without specific prior written
00020 //     permission.
00021 // 
00022 // THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
00023 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00024 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
00025 // NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00026 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
00027 // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00028 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00029 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00030 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00031 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00032 // 
00033 // This file is part of the PLearn library. For more information on the PLearn
00034 // library, go to the PLearn Web site at www.plearn.org
00035 
00036 
00037  
00038 
00039 /* *******************************************************      
00040    * $Id: GhostScript.cc 6057 2006-07-14 19:10:23Z tihocan $
00041    * AUTHORS: Pascal Vincent & Yoshua Bengio
00042    * This file is part of the PLearn library.
00043    ******************************************************* */
00044 
00045 #include "GhostScript.h"
00046 #include <plearn/io/FdPStreamBuf.h>
00047 
00048 #if defined(WIN32) && !defined(__CYGWIN__) && !defined(_MINGW_)
00049 #include <io.h>
00050 // norman: potentially dangerous if there is a function called with the same name in this
00051 //         file. Beware!
00052 #define popen _popen
00053 #define pclose _pclose
00054 #define fileno _fileno
00055 #endif
00056 
00057 namespace PLearn {
00058 using namespace std;
00059 
00060   real rgb2real(real r, real g, real b)
00061   { 
00062     int r100 = int(r*99.99);
00063     int g100 = int(g*99.99);
00064     int b100 = int(b*99.99);
00065     return real(r100*10000+g100*100+b100);
00066   }
00067 
00068   void real2rgb(real colorval, real& r, real& g, real& b)
00069   {
00070     int col = int(colorval);
00071     int r100 = col/10000;
00072     col = col%10000;
00073     int g100 = col/100;
00074     col = col%100;
00075     int b100 = col;
00076     r = real(r100)/100.0;
00077     g = real(g100)/100.0;
00078     b = real(b100)/100.0;
00079   }
00080 
00081   GhostScript::GhostScript(int width, int height)
00082     :isfile(false)
00083   {
00084     static char command_string[1000];
00085     // sprintf(command_string,"gs -sDEVICE=x11 -g%d%c%d - > /dev/null",width,'x',height);
00086     sprintf(command_string,"gs -sDEVICE=x11 -g%d%c%d > /dev/null",width,'x',height);
00087 
00088     gs_cstream = popen(command_string,"w");
00089     togs = new FdPStreamBuf(-1, fileno(gs_cstream));
00090     togs.outmode=PStream::raw_ascii;
00091   }
00092 
00093   GhostScript::GhostScript(const string& filename, real x1, real y1, real x2, real y2)
00094     :isfile(true)
00095     // :gs_cstream(0), togs(filename.c_str())
00096   {
00097     gs_cstream= fopen(filename.c_str(), "w");
00098     togs = new FdPStreamBuf(-1, fileno(gs_cstream));
00099     togs.outmode=PStream::raw_ascii;
00100     togs << "%!PS-Adobe-2.0 EPSF-2.0" << endl;
00101     togs << "%%BoundingBox: " << x1 << " " << y1 << " " << x2 << " " << y2 << endl;
00102   }
00103 
00104   GhostScript::~GhostScript()
00105   { 
00106     if(gs_cstream)
00107       {
00108         if(!isfile)
00109           togs << "\nquit" << endl; 
00110         fclose(gs_cstream);
00111       }
00112   }
00113 
00114   void GhostScript::flush() 
00115   { 
00116     togs.flush(); 
00117     if(gs_cstream) 
00118       copypage();
00119   }
00120 
00121   void GhostScript::writeBitmapHexString1Bit(const Mat& bm, PStream& out, bool lastrowfirst)
00122   {
00123     unsigned char bitmask = 128;
00124     unsigned char value = 0;
00125     for(int i=0; i<bm.length(); i++)
00126       {
00127         const real* bm_i = lastrowfirst ?bm.rowdata(bm.length()-1-i) :bm.rowdata(i);
00128         for(int j=0; j<bm.width(); j++)
00129           {
00130             if(bm_i[j]>0)
00131               value |= bitmask;
00132             bitmask = bitmask>>1;
00133             if(bitmask==0)
00134               {
00135                 out.writeAsciiHexNum((unsigned char)value);
00136                 out.put(' ');
00137                 bitmask = 128;
00138                 value = 0;
00139               }
00140           }
00141         if(bitmask!=128)
00142           {
00143             out.writeAsciiHexNum((unsigned char)value);
00144             bitmask = 128;
00145             value = 0;
00146           }
00147       }
00148   }
00149 
00150   void GhostScript::writeBitmapHexString8Bits(const Mat& bm, PStream& out, bool lastrowfirst)
00151   {
00152     for(int i=0; i<bm.length(); i++)
00153       {
00154         const real* bm_i = lastrowfirst ?bm.rowdata(bm.length()-1-i) :bm.rowdata(i);
00155         for( int j=0; j<bm.width(); j++)
00156           out.writeAsciiHexNum((unsigned char)(bm_i[j]*255.99));
00157         out << "\n";
00158       }
00159   }
00160   
00161   void GhostScript::writeBitmapHexString24Bits(const Mat& bm, PStream& out, bool lastrowfirst)
00162   {
00163     for(int i=0; i<bm.length(); i++)
00164       {
00165         const real* bm_i = lastrowfirst ?bm.rowdata(bm.length()-1-i) :bm.rowdata(i);
00166         for( int j=0; j<bm.width(); j++)
00167           {
00168             real r,g,b; // values between 0 and 255
00169             real2rgb(bm_i[j],r,g,b);
00170             out.writeAsciiHexNum((unsigned char)(r*255.99));
00171             out.writeAsciiHexNum((unsigned char)(g*255.99));
00172             out.writeAsciiHexNum((unsigned char)(b*255.99));
00173           }
00174         out << "\n";
00175       }
00176   }
00177   
00178   void GhostScript::displayBlack(const Mat& bm, real x, real y, real w, real h, bool painton1)
00179   {
00180     togs << "\ngsave\n" 
00181          << "/pstr " << bm.width() << " string def\n"
00182          << x << " " << y << " translate\n"
00183          << w << " " << h << " scale\n" 
00184          << bm.width() << " " << bm.length() << " " << (painton1 ?"true" :"false") << " "
00185          << "[" << bm.width() << " 0 0 " << bm.length() << " 0 0 ]\n";
00186     // * Version using huge string
00187     togs << "<";
00188     writeBitmapHexString1Bit(bm,togs,true);
00189     togs << ">\nimage\ngrestore" << endl;
00190     // * Version using procedure
00191     // togs << "{currentfile pstr readhexstring pop} imagemask\n";
00192     // writeBitmapHexString1Bit(bm,togs,true);
00193     // togs << "\ngrestore\n";
00194   }
00195 
00196   void GhostScript::displayGray(const Mat& bm, real x, real y, real w, real h)
00197   {
00198     togs << "\ngsave\n" 
00199          << "/pstr " << bm.width() << " string def\n"
00200          << x << " " << y << " translate\n"
00201          << w << " " << h << " scale\n" 
00202          << bm.width() << " " << bm.length() << " 8 "
00203          << "[" << bm.width() << " 0 0 " << bm.length() << " 0 0 ]\n";
00204     // * Version using huge string
00205     togs << "<";
00206     writeBitmapHexString8Bits(bm,togs,true);
00207     togs << ">\nimage\ngrestore" << endl;
00208     // * Version using procedure
00209     // togs << "{currentfile pstr readhexstring pop} image\n";
00210     // writeBitmapHexString8Bits(bm,togs,true);
00211     // togs << "\ngrestore\n";
00212   }
00213 
00214   void GhostScript::displayRGB(const Mat& bm, real x, real y, real w, real h)
00215   {
00216     togs << "\ngsave\n" 
00217          << "/pstr " << 3*bm.width() << " string def\n"
00218          << x << " " << y << " translate\n"
00219          << w << " " << h << " scale\n" 
00220          << bm.width() << " " << bm.length() << " 8 "
00221          << "[" << bm.width() << " 0 0 " << bm.length() << " 0 0 ]\n";
00222     // * Version using huge string
00223     // togs << "<";
00224     // writeBitmapHexString24Bits(bm,togs);
00225     // togs << ">\nfalse 3 image\ngrestore" << endl;
00226     // * Version using procedure
00227     togs << "{currentfile pstr readhexstring pop} false 3 colorimage\n";
00228     writeBitmapHexString24Bits(bm,togs,true);
00229     togs << "\ngrestore\n";
00230   }
00231 
00232 void GhostScript::show(real x, real y, const char* str, char halign, char valign)
00233 {
00234   togs << "\n" << x << " " << y << " moveto ";
00235   togs << "(" << str << ") dup stringwidth ";
00236   
00237   switch(valign)
00238     {
00239     case 't':
00240       togs << " neg ";
00241       break;
00242     case 'm':
00243       togs << " -2 div ";
00244       break;
00245     case 'b':
00246       togs << " pop 0 ";
00247       break;
00248     default:
00249       PLERROR("In GhostScript::show wrong valign parameter '%c'",valign);
00250     }
00251 
00252   togs << " exch ";
00253   switch(halign)
00254     {
00255     case 'l':
00256       togs << " pop 0 ";
00257       break;
00258     case 'c':
00259       togs << " -2 div ";
00260       break;
00261     case 'r':
00262       togs << " neg ";
00263       break;
00264     default:
00265       PLERROR("In GhostScript::show wrong halign parameter '%c'",halign);
00266     }
00267 
00268   togs << " exch rmoveto show" << endl;
00269 }
00270 
00271 void GhostScript::setcolor(char* colorname)
00272     {
00273       if(!strcmp(colorname,"white")) setcolor(1,1,1);
00274       else if(!strcmp(colorname,"black")) setcolor(0,0,0);
00275       else if(!strcmp(colorname,"gray")) setcolor(.5,.5,.5);
00276       else if(!strcmp(colorname,"darkgray")) setcolor(.25,.25,.25);
00277       else if(!strcmp(colorname,"lightgray")) setcolor(.75,.75,.75);
00278       else if(!strcmp(colorname,"red")) setcolor(1,0,0);
00279       else if(!strcmp(colorname,"green")) setcolor(0,1,0);
00280       else if(!strcmp(colorname,"blue")) setcolor(0,0,1);
00281       else if(!strcmp(colorname,"magenta")) setcolor(1,0,1);
00282       else if(!strcmp(colorname,"yellow")) setcolor(1,1,0);
00283       else if(!strcmp(colorname,"cyan")) setcolor(0,1,1);
00284       else setcolor(0,0,0); 
00285     }
00286 
00287 void GhostScript::multilineShow(real x, real y, const string& text, real newlinesize, char halign, char valign)
00288 {
00289   vector<string> splits = split(text, '\n');
00290   vector<string>::size_type nsplits = splits.size();
00291   for(unsigned int i=0; i<nsplits; i++)
00292     {
00293       show(x,y,splits[i].c_str(),halign,valign);
00294       y -= newlinesize;
00295     }
00296 }
00297 
00298   void GhostScript::drawBox(real x, real y, real width, real height)
00299   { 
00300     togs << "\n" << x << " " << y << " moveto "
00301          << x+width << " " << y << " lineto "
00302          << x+width << " " << y+height << " lineto "
00303          << x << " " << y+height << " lineto "
00304          << x << " " << y << " lineto "
00305          << "stroke" << endl;
00306   }
00307 
00308   void GhostScript::fillBox(real x, real y, real width, real height)
00309   { 
00310     togs << "\n" << x << " " << y << " moveto "
00311          << x+width << " " << y << " lineto "
00312          << x+width << " " << y+height << " lineto "
00313          << x << " " << y+height << " lineto "
00314          << x << " " << y << " lineto "
00315          << "fill" << endl;
00316   }
00317 
00318   void GhostScript::drawCircle(real x, real y, real r)
00319   {
00320     moveto(x+r, y);
00321     togs << x << ' ' << y << ' ' << r << " 0 360 arc stroke" << endl; 
00322   }
00323 
00324   void GhostScript::drawCross(real x, real y, real r, bool vertical, real ry)
00325   {
00326     if (ry<0) ry=r;
00327     if(vertical)
00328       {
00329         drawLine(x-r,y,x+r,y);
00330         drawLine(x,y-ry,x,y+ry);
00331       }
00332     else // diagonal
00333       {
00334         r /= M_SQRT2; // M_SQRT2 == sqrt(2.0)
00335         drawLine(x-r,y-ry,x+r,y+ry);
00336         drawLine(x-r,y+ry,x+r,y-ry);
00337       }
00338   }
00339 
00340   void GhostScript::fillCircle(real x, real y, real r)
00341   {
00342     moveto(x+r, y);
00343     togs << x << ' ' << y << ' ' << r << " 0 360 arc fill" << endl; 
00344   }
00345 
00346 #ifdef WIN32
00347 #undef _fileno
00348 #undef _popen
00349 #undef _pclose
00350 #endif
00351 
00352 } // end of namespace PLearn
00353 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines