[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-devel
Subject:    [PATCH] Add MS-DOS EPS files in EPS kimgio
From:       Nicolas Goutte <nicolasg () snafu ! de>
Date:       2003-08-28 16:43:42
[Download RAW message or body]

The attached patch is for the file kdelibs/kimgio/eps.cpp.

It adds support for reading MS-DOS EPS files (those binary files with TIFF or 
WMF preview.)

The patch was made for KDE_3_1_BRANCH but it should apply to head.

The remaining questions are:
- the kdDebug: remove, leave or create a new area number for kimgio.
- the backport: should it be commited to KDE_3_1_BRANCH too (with the patched 
eps.kimgio)

(I can commit to HEAD, but I cannot compile or test HEAD.)

Have a nice day!


["patch_eps_cpp.diff" (text/x-diff)]

Index: eps.cpp
===================================================================
RCS file: /home/kde/kdelibs/kimgio/eps.cpp,v
retrieving revision 1.18.2.3
diff -u -r1.18.2.3 eps.cpp
--- eps.cpp	9 Apr 2003 19:11:39 -0000	1.18.2.3
+++ eps.cpp	28 Aug 2003 16:38:33 -0000
@@ -7,6 +7,7 @@
 #include <qprinter.h>
 #include <kapplication.h>
 #include <ktempfile.h>
+#include <kdebug.h>
 #include "eps.h"
 
 #define BUFLEN 200
@@ -14,20 +15,102 @@
 #define BBOX "%%BoundingBox:"
 #define BBOX_LEN strlen(BBOX)
 
-bool bbox ( QImageIO *imageio, int *x1, int *y1, int *x2, int *y2)
+static bool seekToCodeStart( QIODevice * io, Q_UINT32 & ps_offset, Q_UINT32 & \
ps_size ) +{
+    char buf[4]; // We at most need to read 4 bytes at a time
+    ps_offset=0L;
+    ps_size=0L;
+
+    if ( io->readBlock(buf, 2)!=2 ) // Read first two bytes
+    {
+        kdError() << "kimgio EPS: EPS file has less than 2 bytes." << endl;
+        return false;
+    }
+
+    if ( buf[0]=='%' && buf[1]=='!' ) // Check %! magic
+    {
+        kdDebug() << "kimgio EPS: normal EPS file" << endl;
+    }
+    else if ( buf[0]==char(0xc5) && buf[1]==char(0xd0) ) // Check start of MS-DOS \
EPS magic +    {   // May be a MS-DOS EPS file
+        if ( io->readBlock(buf+2, 2)!=2 ) // Read further bytes of MS-DOS EPS magic
+        {
+            kdError() << "kimgio EPS: potential MS-DOS EPS file has less than 4 \
bytes." << endl; +            return false;
+        }
+        if ( buf[2]==char(0xd3) && buf[3]==char(0xc6) ) // Check last bytes of \
MS-DOS EPS magic +        {
+            if (io->readBlock(buf, 4)!=4) // Get offset of PostScript code in the \
MS-DOS EPS file. +            {
+                kdError() << "kimgio EPS: cannot read offset of MS-DOS EPS file" << \
endl; +                return false;
+            }
+            ps_offset // Offset is in little endian
+                = ((unsigned char) buf[0])
+                + ((unsigned char) buf[1] << 8)
+                + ((unsigned char) buf[2] << 16)
+                + ((unsigned char) buf[3] << 24);
+            if (io->readBlock(buf, 4)!=4) // Get size of PostScript code in the \
MS-DOS EPS file. +            {
+                kdError() << "kimgio EPS: cannot read size of MS-DOS EPS file" << \
endl; +                return false;
+            }
+            ps_size // Size is in little endian
+                = ((unsigned char) buf[0])
+                + ((unsigned char) buf[1] << 8)
+                + ((unsigned char) buf[2] << 16)
+                + ((unsigned char) buf[3] << 24);
+            kdDebug() << "kimgio EPS: Offset: " << ps_offset <<" Size: " << ps_size \
<< endl; +            if ( !io->at(ps_offset) ) // Get offset of PostScript code in \
the MS-DOS EPS file. +            {
+                kdError() << "kimgio EPS: cannot seek in MS-DOS EPS file" << endl;
+                return false;
+            }
+            if ( io->readBlock(buf, 2)!=2 ) // Read first two bytes of what should \
be the Postscript code +            {
+                kdError() << "kimgio EPS: PostScript code has less than 2 bytes." << \
endl; +                return false;
+            }
+            if ( buf[0]=='%' && buf[1]=='!' ) // Check %! magic
+            {
+                kdDebug() << "kimgio EPS: MS-DOS EPS file" << endl;
+            }
+            else
+            {
+                kdError() << "kimgio EPS: supposed Postscript code of a MS-DOS EPS \
file doe not start with %!." << endl; +                return false;
+            }
+        }
+        else
+        {
+            kdError() << "kimgio EPS: wrong magic for potential MS-DOS EPS file!" << \
endl; +            return false;
+        }
+    }
+    else
+    {
+        kdError() << "kimgio EPS: not an EPS file!" << endl;
+        return false;
+    }
+    return true;
+}
+
+static bool bbox ( QIODevice *io, int *x1, int *y1, int *x2, int *y2)
 {
-        int ret = false;
         char buf[BUFLEN+1];
 
-        while (imageio->ioDevice()->readLine(buf, BUFLEN) > 0)
+        bool ret = false;
+
+        while (io->readLine(buf, BUFLEN) > 0)
         {
                 if (strncmp (buf, BBOX, BBOX_LEN) == 0)
                 {
                         // Some EPS files have non-integer values for the bbox
                         // We don't support that currently, but at least we parse it
                         float _x1, _y1, _x2, _y2;
-                        if ( sscanf (buf, "%*s %f %f %f %f", 
+                        if ( sscanf (buf, "%*s %f %f %f %f",
                                 &_x1, &_y1, &_x2, &_y2) == 4) {
+                                kdDebug() << "kimgio EPS BBOX: " << _x1 << " " << \
                _y1 << " " << _x2 << " " << _y2 << endl;
                                 *x1=(int)_x1; *y1=(int)_y1; *x2=(int)_x2; \
*y2=(int)_y2;  ret = true;
                                 break;
@@ -40,6 +123,8 @@
 
 void kimgio_eps_read (QImageIO *image)
 {
+        kdDebug() << "kimgio EPS: starting..." << endl;
+
         FILE * ghostfd;
         int x1, y1, x2, y2;
         //QTime dt;
@@ -48,8 +133,16 @@
         QString cmdBuf;
         QString tmp;
 
+        QIODevice* io = image->ioDevice();
+        Q_UINT32 ps_offset, ps_size;
+
+        // find start of PostScript code
+        if ( !seekToCodeStart(io, ps_offset, ps_size) )
+            return;
+
         // find bounding box
-        if ( !bbox (image, &x1, &y1, &x2, &y2)) {
+        if ( !bbox (io, &x1, &y1, &x2, &y2)) {
+            kdError() << "kimgio EPS: no bounding box found!" << endl;
             return;
         }
 
@@ -57,6 +150,7 @@
         tmpFile.setAutoDelete(true);
 
         if( tmpFile.status() != 0 ) {
+            kdError() << "kimgio EPS: no temp file!" << endl;
             return;
         }
         tmpFile.close(); // Close the file, we just want the filename
@@ -112,6 +206,7 @@
         ghostfd = popen (QFile::encodeName(cmdBuf), "w");
 
         if ( ghostfd == 0 ) {
+            kdError() << "kimgio EPS: no GhostScript?" << endl;
             return;
         }
 
@@ -121,8 +216,16 @@
 
         // write image to gs
 
-        QByteArray buffer = image->ioDevice()->readAll();
-        fwrite(buffer.data(), sizeof(char), buffer.size(), ghostfd);
+        io->reset(); // Go back to start of file to give all the file to GhostScript
+        if (ps_offset>0L) // We have an offset
+              io->at(ps_offset);
+        QByteArray buffer ( io->readAll() );
+
+        // If we have no MS-DOS EPS file or if the size seems wrong, then choose the \
buffer size +        if (ps_size<=0L || ps_size>buffer.size())
+            ps_size=buffer.size();
+
+        fwrite(buffer.data(), sizeof(char), ps_size, ghostfd);
         buffer.resize(0);
 
         pclose ( ghostfd );
@@ -132,7 +235,10 @@
         if( myimage.load (tmpFile.name()) ) {
                 image->setImage (myimage);
                 image->setStatus (0);
+                kdDebug() << "kimgio EPS: success!" << endl;
         }
+        else
+            kdError() << "kimgio EPS: no image!" << endl;
 
         //kdDebug() << "Loading EPS took " << (float)(dt.elapsed()) / 1000 << " \
seconds" << endl;  return;



>> Visit http://mail.kde.org/mailman/listinfo/kde-devel#unsub to unsubscribe <<


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic