• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • kimgio
 

kimgio

  • kimgio
eps.cpp
1 // This library is distributed under the conditions of the GNU LGPL.
2 #include <unistd.h>
3 #include <stdio.h>
4 #include <tqimage.h>
5 #include <tqfile.h>
6 #include <tqpainter.h>
7 #include <tqprinter.h>
8 #include <tdeapplication.h>
9 #include <tdetempfile.h>
10 #include <kdebug.h>
11 #include "eps.h"
12 
13 #define BUFLEN 200
14 
15 #define BBOX "%%BoundingBox:"
16 #define BBOX_LEN strlen(BBOX)
17 
18 static bool seekToCodeStart( TQIODevice * io, TQ_UINT32 & ps_offset, TQ_UINT32 & ps_size )
19 {
20  char buf[4]; // We at most need to read 4 bytes at a time
21  ps_offset=0L;
22  ps_size=0L;
23 
24  if ( io->readBlock(buf, 2)!=2 ) // Read first two bytes
25  {
26  kdError(399) << "kimgio EPS: EPS file has less than 2 bytes." << endl;
27  return false;
28  }
29 
30  if ( buf[0]=='%' && buf[1]=='!' ) // Check %! magic
31  {
32  kdDebug(399) << "kimgio EPS: normal EPS file" << endl;
33  }
34  else if ( buf[0]==char(0xc5) && buf[1]==char(0xd0) ) // Check start of MS-DOS EPS magic
35  { // May be a MS-DOS EPS file
36  if ( io->readBlock(buf+2, 2)!=2 ) // Read further bytes of MS-DOS EPS magic
37  {
38  kdError(399) << "kimgio EPS: potential MS-DOS EPS file has less than 4 bytes." << endl;
39  return false;
40  }
41  if ( buf[2]==char(0xd3) && buf[3]==char(0xc6) ) // Check last bytes of MS-DOS EPS magic
42  {
43  if (io->readBlock(buf, 4)!=4) // Get offset of PostScript code in the MS-DOS EPS file.
44  {
45  kdError(399) << "kimgio EPS: cannot read offset of MS-DOS EPS file" << endl;
46  return false;
47  }
48  ps_offset // Offset is in little endian
49  = ((unsigned char) buf[0])
50  + ((unsigned char) buf[1] << 8)
51  + ((unsigned char) buf[2] << 16)
52  + ((unsigned char) buf[3] << 24);
53  if (io->readBlock(buf, 4)!=4) // Get size of PostScript code in the MS-DOS EPS file.
54  {
55  kdError(399) << "kimgio EPS: cannot read size of MS-DOS EPS file" << endl;
56  return false;
57  }
58  ps_size // Size is in little endian
59  = ((unsigned char) buf[0])
60  + ((unsigned char) buf[1] << 8)
61  + ((unsigned char) buf[2] << 16)
62  + ((unsigned char) buf[3] << 24);
63  kdDebug(399) << "kimgio EPS: Offset: " << ps_offset <<" Size: " << ps_size << endl;
64  if ( !io->at(ps_offset) ) // Get offset of PostScript code in the MS-DOS EPS file.
65  {
66  kdError(399) << "kimgio EPS: cannot seek in MS-DOS EPS file" << endl;
67  return false;
68  }
69  if ( io->readBlock(buf, 2)!=2 ) // Read first two bytes of what should be the Postscript code
70  {
71  kdError(399) << "kimgio EPS: PostScript code has less than 2 bytes." << endl;
72  return false;
73  }
74  if ( buf[0]=='%' && buf[1]=='!' ) // Check %! magic
75  {
76  kdDebug(399) << "kimgio EPS: MS-DOS EPS file" << endl;
77  }
78  else
79  {
80  kdError(399) << "kimgio EPS: supposed Postscript code of a MS-DOS EPS file doe not start with %!." << endl;
81  return false;
82  }
83  }
84  else
85  {
86  kdError(399) << "kimgio EPS: wrong magic for potential MS-DOS EPS file!" << endl;
87  return false;
88  }
89  }
90  else
91  {
92  kdError(399) << "kimgio EPS: not an EPS file!" << endl;
93  return false;
94  }
95  return true;
96 }
97 
98 static bool bbox ( TQIODevice *io, int *x1, int *y1, int *x2, int *y2)
99 {
100  char buf[BUFLEN+1];
101 
102  bool ret = false;
103 
104  while (io->readLine(buf, BUFLEN) > 0)
105  {
106  if (strncmp (buf, BBOX, BBOX_LEN) == 0)
107  {
108  // Some EPS files have non-integer values for the bbox
109  // We don't support that currently, but at least we parse it
110  float _x1, _y1, _x2, _y2;
111  if ( sscanf (buf, "%*s %f %f %f %f",
112  &_x1, &_y1, &_x2, &_y2) == 4) {
113  kdDebug(399) << "kimgio EPS BBOX: " << _x1 << " " << _y1 << " " << _x2 << " " << _y2 << endl;
114  *x1=(int)_x1; *y1=(int)_y1; *x2=(int)_x2; *y2=(int)_y2;
115  ret = true;
116  break;
117  }
118  }
119  }
120 
121  return ret;
122 }
123 
124 TDE_EXPORT void kimgio_eps_read (TQImageIO *image)
125 {
126  kdDebug(399) << "kimgio EPS: starting..." << endl;
127 
128  FILE * ghostfd;
129  int x1, y1, x2, y2;
130  //TQTime dt;
131  //dt.start();
132 
133  TQString cmdBuf;
134  TQString tmp;
135 
136  TQIODevice* io = image->ioDevice();
137  TQ_UINT32 ps_offset, ps_size;
138 
139  // find start of PostScript code
140  if ( !seekToCodeStart(io, ps_offset, ps_size) )
141  return;
142 
143  // find bounding box
144  if ( !bbox (io, &x1, &y1, &x2, &y2)) {
145  kdError(399) << "kimgio EPS: no bounding box found!" << endl;
146  return;
147  }
148 
149  KTempFile tmpFile;
150  tmpFile.setAutoDelete(true);
151 
152  if( tmpFile.status() != 0 ) {
153  kdError(399) << "kimgio EPS: no temp file!" << endl;
154  return;
155  }
156  tmpFile.close(); // Close the file, we just want the filename
157 
158  // x1, y1 -> translation
159  // x2, y2 -> new size
160 
161  x2 -= x1;
162  y2 -= y1;
163  //kdDebug(399) << "origin point: " << x1 << "," << y1 << " size:" << x2 << "," << y2 << endl;
164  double xScale = 1.0;
165  double yScale = 1.0;
166  bool needsScaling = false;
167  int wantedWidth = x2;
168  int wantedHeight = y2;
169 
170  if (image->parameters())
171  {
172  // Size forced by the caller
173  TQStringList params = TQStringList::split(':', image->parameters());
174  if (params.count() >= 2 && x2 != 0.0 && y2 != 0.0)
175  {
176  wantedWidth = params[0].toInt();
177  xScale = (double)wantedWidth / (double)x2;
178  wantedHeight = params[1].toInt();
179  yScale = (double)wantedHeight / (double)y2;
180  //kdDebug(399) << "wanted size:" << wantedWidth << "x" << wantedHeight << endl;
181  //kdDebug(399) << "scaling:" << xScale << "," << yScale << endl;
182  needsScaling = true;
183  }
184  }
185 
186  // create GS command line
187 
188  cmdBuf = "gs -sOutputFile=";
189  cmdBuf += tmpFile.name();
190  cmdBuf += " -q -g";
191  tmp.setNum( wantedWidth );
192  cmdBuf += tmp;
193  tmp.setNum( wantedHeight );
194  cmdBuf += "x";
195  cmdBuf += tmp;
196  cmdBuf += " -dSAFER -dPARANOIDSAFER -dNOPAUSE -sDEVICE=ppm -c "
197  "0 0 moveto "
198  "1000 0 lineto "
199  "1000 1000 lineto "
200  "0 1000 lineto "
201  "1 1 254 255 div setrgbcolor fill "
202  "0 0 0 setrgbcolor - -c showpage quit";
203 
204  // run ghostview
205 
206  ghostfd = popen (TQFile::encodeName(cmdBuf), "w");
207 
208  if ( ghostfd == 0 ) {
209  kdError(399) << "kimgio EPS: no GhostScript?" << endl;
210  return;
211  }
212 
213  fprintf (ghostfd, "\n%d %d translate\n", -tqRound(x1*xScale), -tqRound(y1*yScale));
214  if ( needsScaling )
215  fprintf (ghostfd, "%g %g scale\n", xScale, yScale);
216 
217  // write image to gs
218 
219  io->reset(); // Go back to start of file to give all the file to GhostScript
220  if (ps_offset>0L) // We have an offset
221  io->at(ps_offset);
222  TQByteArray buffer ( io->readAll() );
223 
224  // If we have no MS-DOS EPS file or if the size seems wrong, then choose the buffer size
225  if (ps_size<=0L || ps_size>buffer.size())
226  ps_size=buffer.size();
227 
228  fwrite(buffer.data(), sizeof(char), ps_size, ghostfd);
229  buffer.resize(0);
230 
231  pclose ( ghostfd );
232 
233  // load image
234  TQImage myimage;
235  if( myimage.load (tmpFile.name()) ) {
236  image->setImage (myimage);
237  image->setStatus (0);
238  kdDebug(399) << "kimgio EPS: success!" << endl;
239  }
240  else
241  kdError(399) << "kimgio EPS: no image!" << endl;
242 
243  //kdDebug(399) << "Loading EPS took " << (float)(dt.elapsed()) / 1000 << " seconds" << endl;
244  return;
245 }
246 
247 // Sven Wiegand <SWiegand@tfh-berlin.de> -- eps output filter (from KSnapshot)
248 TDE_EXPORT void kimgio_eps_write( TQImageIO *imageio )
249 {
250  TQPrinter psOut(TQPrinter::PrinterResolution);
251  TQPainter p;
252 
253  // making some definitions (papersize, output to file, filename):
254  psOut.setCreator( "KDE " TDE_VERSION_STRING );
255  psOut.setOutputToFile( true );
256 
257  // Extension must be .eps so that Qt generates EPS file
258  KTempFile tmpFile(TQString::null, ".eps");
259  tmpFile.setAutoDelete(true);
260  if ( tmpFile.status() != 0)
261  return;
262  tmpFile.close(); // Close the file, we just want the filename
263 
264  psOut.setOutputFileName(tmpFile.name());
265  psOut.setFullPage(true);
266 
267  // painting the pixmap to the "printer" which is a file
268  p.begin( &psOut );
269  // Qt uses the clip rect for the bounding box
270  p.setClipRect( 0, 0, imageio->image().width(), imageio->image().height(), TQPainter::CoordPainter);
271  p.drawImage( TQPoint( 0, 0 ), imageio->image() );
272  p.end();
273 
274  // Copy file to imageio struct
275  TQFile inFile(tmpFile.name());
276  inFile.open( IO_ReadOnly );
277 
278  TQTextStream in( &inFile );
279  in.setEncoding( TQTextStream::Latin1 );
280  TQTextStream out( imageio->ioDevice() );
281  out.setEncoding( TQTextStream::Latin1 );
282 
283  TQString szInLine = in.readLine();
284  out << szInLine << '\n';
285 
286  while( !in.atEnd() ){
287  szInLine = in.readLine();
288  out << szInLine << '\n';
289  }
290 
291  inFile.close();
292 
293  imageio->setStatus(0);
294 }

kimgio

Skip menu "kimgio"
  • Main Page
  • File List
  • Related Pages

kimgio

Skip menu "kimgio"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdeioslave
  •   http
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for kimgio by doxygen 1.9.1
This website is maintained by Timothy Pearson.