• 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
18static 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
98static 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
124TDE_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)
248TDE_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.4
This website is maintained by Timothy Pearson.