bugfix: some lines were too thick or too thin
[swftools.git] / pdf2swf / SWFOutputDev.cc
index 766bd6b..c2aa5cb 100644 (file)
@@ -21,6 +21,7 @@
 #include <stdlib.h>
 #include <stddef.h>
 #include <string.h>
+#include <unistd.h>
 //xpdf header files
 #include "GString.h"
 #include "gmem.h"
@@ -45,7 +46,7 @@ extern "C" {
 #include "../lib/log.h"
 }
 
-static char* filename = 0;
+static char* swffilename = 0;
 
 static void printInfoString(Dict *infoDict, char *key, char *fmt);
 static void printInfoDate(Dict *infoDict, char *key, char *fmt);
@@ -216,12 +217,16 @@ public:
                         GBool inlineImg);
 
   private:
+  void drawGeneralImage(GfxState *state, Object *ref, Stream *str,
+                                  int width, int height, GfxImageColorMap*colorMap, GBool invert,
+                                  GBool inlineImg, int mask);
   int clipping[32];
   int clippos;
 
   int setT1Font(char*name,FontEncoding*enc);
-  int initT1Font(int id, FontEncoding*encoding);
   int t1id;
+  int jpeginfo; // did we write "Page contains jpegs" yet?
+  int pbminfo; // did we write "Page contains jpegs" yet?
 };
 
 char mybuf[1024];
@@ -350,13 +355,13 @@ void showFontError(GfxFont*font, int nr)
     if(lastdumppos<sizeof(lastdumps)/sizeof(int))
     lastdumps[lastdumppos++] = r.num;
     if(nr == 0)
-      logf("<error> The following font caused problems:");
+      logf("<warning> The following font caused problems:");
     else if(nr == 1)
-      logf("<error> The following font caused problems (substituting):");
+      logf("<warning> The following font caused problems (substituting):");
     else if(nr == 2)
-      logf("<error> This document contains Type 3 Fonts: (some text may be incorrectly displayed)");
+      logf("<warning> This document contains Type 3 Fonts: (some text may be incorrectly displayed)");
 
-    dumpFontInfo("<error>", font);
+    dumpFontInfo("<warning>", font);
 }
 
 void dumpFontInfo(char*loglevel, GfxFont*font)
@@ -365,7 +370,7 @@ void dumpFontInfo(char*loglevel, GfxFont*font)
   char*name;
   gstr = font->getName();
   Ref r=font->getID();
-  logf("%s=========== %s (ID:%d) ==========\n", loglevel, gstr?gstr->getCString():"(unknown font)", r.num);
+  logf("%s=========== %s (ID:%d,%d) ==========\n", loglevel, gstr?gstr->getCString():"(unknown font)", r.num,r.gen);
 
   gstr  = font->getTag();
   if(gstr) 
@@ -393,9 +398,12 @@ void dumpFontInfo(char*loglevel, GfxFont*font)
      logf("%sType: TrueType\n",loglevel);
     break;
   }
+  
+  Ref embRef;
+  GBool embedded = font->getEmbeddedFontID(&embRef);
   name = font->getEmbeddedFontName();
-  if(name)
-   logf("%sEmbedded name: %s\n",loglevel, name);
+  if(embedded)
+   logf("%sEmbedded name: %s id: %d\n",loglevel, name, embRef.num);
 
   gstr = font->getExtFontFile();
   if(gstr)
@@ -414,6 +422,8 @@ void dumpFontInfo(char*loglevel, GfxFont*font)
 
 SWFOutputDev::SWFOutputDev() 
 {
+    jpeginfo = 0;
+    pbminfo = 0;
     clippos = 0;
     clipping[clippos] = 0;
     outputstarted = 0;
@@ -485,55 +495,56 @@ T1_OUTLINE* gfxPath_to_T1_OUTLINE(GfxState*state, GfxPath*path)
 
 void SWFOutputDev::stroke(GfxState *state) 
 {
-    logf("<debug> %s stroke\n",gfxstate2str(state));
+    logf("<debug> stroke\n");
     GfxPath * path = state->getPath();
     struct swfmatrix m;
     m.m11 = 1; m.m21 = 0; m.m22 = 1;
-    m.m21 = 0; m.m13 = 0; m.m23 = 0;
+    m.m12 = 0; m.m13 = 0; m.m23 = 0;
     T1_OUTLINE*outline = gfxPath_to_T1_OUTLINE(state, path);
     swfoutput_setdrawmode(&output, DRAWMODE_STROKE);
     swfoutput_drawpath(&output, outline, &m);
 }
 void SWFOutputDev::fill(GfxState *state) 
 {
-    logf("<debug> %s fill\n",gfxstate2str(state));
+    logf("<debug> fill\n");
     GfxPath * path = state->getPath();
     struct swfmatrix m;
     m.m11 = 1; m.m21 = 0; m.m22 = 1;
-    m.m21 = 0; m.m13 = 0; m.m23 = 0;
+    m.m12 = 0; m.m13 = 0; m.m23 = 0;
     T1_OUTLINE*outline = gfxPath_to_T1_OUTLINE(state, path);
     swfoutput_setdrawmode(&output, DRAWMODE_FILL);
     swfoutput_drawpath(&output, outline, &m);
 }
 void SWFOutputDev::eoFill(GfxState *state) 
 {
-    logf("<debug> %s eofill\n",gfxstate2str(state));
+    logf("<debug> eofill\n");
     GfxPath * path = state->getPath();
     struct swfmatrix m;
     m.m11 = 1; m.m21 = 0; m.m22 = 1;
-    m.m21 = 0; m.m13 = 0; m.m23 = 0;
+    m.m12 = 0; m.m13 = 0; m.m23 = 0;
     T1_OUTLINE*outline = gfxPath_to_T1_OUTLINE(state, path);
     swfoutput_setdrawmode(&output, DRAWMODE_EOFILL);
     swfoutput_drawpath(&output, outline, &m);
 }
 void SWFOutputDev::clip(GfxState *state) 
 {
-    logf("<debug> %s clip\n",gfxstate2str(state));
+    logf("<debug> clip\n");
     GfxPath * path = state->getPath();
     struct swfmatrix m;
-    m.m11 = 1; m.m21 = 0; m.m22 = 1;
-    m.m21 = 0; m.m13 = 0; m.m23 = 0;
+    m.m11 = 1; m.m22 = 1;
+    m.m12 = 0; m.m21 = 0; 
+    m.m13 = 0; m.m23 = 0;
     T1_OUTLINE*outline = gfxPath_to_T1_OUTLINE(state, path);
     swfoutput_startclip(&output, outline, &m);
     clipping[clippos] = 1;
 }
 void SWFOutputDev::eoClip(GfxState *state) 
 {
-    logf("<debug> %s eoclip\n",gfxstate2str(state));
+    logf("<debug> eoclip\n");
     GfxPath * path = state->getPath();
     struct swfmatrix m;
     m.m11 = 1; m.m21 = 0; m.m22 = 1;
-    m.m21 = 0; m.m13 = 0; m.m23 = 0;
+    m.m12 = 0; m.m13 = 0; m.m23 = 0;
     T1_OUTLINE*outline = gfxPath_to_T1_OUTLINE(state, path);
     swfoutput_startclip(&output, outline, &m);
     clipping[clippos] = 1;
@@ -558,17 +569,17 @@ GBool SWFOutputDev::useDrawChar()
 void SWFOutputDev::beginString(GfxState *state, GString *s) 
 { 
     double m11,m21,m12,m22;
-    logf("<debug> %s beginstring \"%s\"\n", gfxstate2str(state), s->getCString());
+    logf("<debug> beginstring \"%s\"\n", s->getCString());
     state->getFontTransMat(&m11, &m12, &m21, &m22);
     m11 *= state->getHorizScaling();
     m21 *= state->getHorizScaling();
-    swfoutput_setfontmatrix(&output,m11,-m12,m21,-m22);
+    swfoutput_setfontmatrix(&output, m11, -m12, m21, -m22);
 }
 
 int charcounter = 0;
 void SWFOutputDev::drawChar(GfxState *state, double x, double y, double dx, double dy, Guchar c) 
 {
-    logf("<debug> %s drawChar(%f,%f,%f,%f,'%c')\n",gfxstate2str(state), x,y,dx,dy,c);
+    logf("<debug> drawChar(%f,%f,%f,%f,'%c')\n",x,y,dx,dy,c);
     // check for invisible text -- this is used by Acrobat Capture
     if ((state->getRender() & 3) != 3)
     {
@@ -579,31 +590,34 @@ void SWFOutputDev::drawChar(GfxState *state, double x, double y, double dx, doub
        y1 = y;
        state->transform(x, y, &x1, &y1);
 
-       swfoutput_drawchar(&output, x1, y1, c);
+       if(enc->getCharName(c))
+         swfoutput_drawchar(&output, x1, y1, enc->getCharName(c));
+       else
+         logf("<warning> couldn't get name for character %02x from Encoding", c);
     }
 }
 
 void SWFOutputDev::drawChar16(GfxState *state, double x, double y, double dx, double dy, int c) 
 {
-    printf("<error> %s drawChar16(%f,%f,%f,%f,%08x)\n",gfxstate2str(state), x,y,dx,dy,c);
+    printf("<error> drawChar16(%f,%f,%f,%f,%08x)\n",x,y,dx,dy,c);
     exit(1);
 }
 
 void SWFOutputDev::endString(GfxState *state) 
 { 
-    logf("<debug> %s endstring\n", gfxstate2str(state));
+    logf("<debug> endstring\n");
 }    
 
 void SWFOutputDev::startPage(int pageNum, GfxState *state) 
 {
   double x1,y1,x2,y2;
-  logf("<debug> %s, startPage %d\n", gfxstate2str(state), pageNum);
+  logf("<debug> startPage %d\n", pageNum);
   logf("<notice> processing page %d", pageNum);
 
   state->transform(state->getX1(),state->getY1(),&x1,&y1);
   state->transform(state->getX2(),state->getY2(),&x2,&y2);
   if(!outputstarted) {
-    swfoutput_init(&output, filename, abs((int)(x2-x1)),abs((int)(y2-y1)));
+    swfoutput_init(&output, swffilename, abs((int)(x2-x1)),abs((int)(y2-y1)));
     outputstarted = 1;
   }
   else
@@ -678,14 +692,14 @@ void SWFOutputDev::drawLink(Link *link, Catalog *catalog)
 }
 
 void SWFOutputDev::saveState(GfxState *state) {
-  logf("<debug> %s saveState\n", gfxstate2str(state));
+  logf("<debug> saveState\n");
   updateAll(state);
   clippos ++;
   clipping[clippos] = 0;
 };
 
 void SWFOutputDev::restoreState(GfxState *state) {
-  logf("<debug> %s restoreState\n", gfxstate2str(state));
+  logf("<debug> restoreState\n");
   updateAll(state);
   if(clipping[clippos])
       swfoutput_endclip(&output);
@@ -722,50 +736,12 @@ int SWFOutputDev::setT1Font(char*name, FontEncoding*encoding)
     if(id<0)
      return 0;
 
-    initT1Font(id, encoding);
-}
-
-int SWFOutputDev::initT1Font(int id, FontEncoding*encoding)
-{
-    int encStrSize;
-    char *encPtr;
-    int i;
-    T1_DeleteFont(id);
-    T1_LoadFont(id);
-    /* reencode the font: 
-     * This is the only way to get the unmapped characters
-     * from t1lib
-     */
-    encStrSize = 0;
-    for (i = 0; i < 256 && i < encoding->getSize(); ++i) {
-      if (encoding->getCharName(i)) {
-       encStrSize += strlen(encoding->getCharName(i)) + 1;
-      }
-    }
-    char**enc = (char **)gmalloc(257 * sizeof(char *));
-    char*encStr = (char *)gmalloc(encStrSize * sizeof(char));
-    encPtr = encStr;
-    for (i = 0; i < 256 && i < encoding->getSize(); ++i) {
-      if (encoding->getCharName(i)) {
-       strcpy(encPtr, encoding->getCharName(i));
-       enc[i] = encPtr;
-       encPtr += strlen(encPtr) + 1;
-      } else {
-       enc[i] = ".notdef";
-      }
-    }
-    for (; i < 256; ++i) {
-      enc[i] = ".notdef";
-    }
-    enc[256] = "custom";
-    int ret=T1_ReencodeFont(id, enc);
-    t1id = id;
-    return 1;
+    this->t1id = id;
 }
 
 void SWFOutputDev::updateLineWidth(GfxState *state)
 {
-    double width = state->getLineWidth();
+    double width = state->getTransformedLineWidth();
     swfoutput_setlinewidth(&output, width);
 }
 
@@ -789,57 +765,37 @@ void SWFOutputDev::updateStrokeColor(GfxState *state)
                                      (char)(rgb.b*255), (char)(opaq*255));
 }
 
-void SWFOutputDev::updateFont(GfxState *state) {
-  double m11, m12, m21, m22;
-  char * fontname = 0;
-  GfxFont*gfxFont = state->getFont();
-  char * filename;
-
-  if (!gfxFont) {
-    return;
-  }  
-  // look for Type 3 font
-  if (!type3Warning && gfxFont->getType() == fontType3) {
-    type3Warning = gTrue;
-    showFontError(gfxFont, 2);
-  }
-  //dumpFontInfo (gfxFont);
-  
+char*writeEmbeddedFontToFile(GfxFont*font)
+{
+      char*tmpFileName = NULL;
+      char*fileName = NULL;
+      FILE *f;
+      int c;
+      char *fontBuf;
+      int fontLen;
+      Type1CFontConverter *cvt;
+      Ref embRef;
+      Object refObj, strObj;
+      tmpFileName = "/tmp/tmpfont";
+      font->getEmbeddedFontID(&embRef);
 
-  Ref embRef;
-  GBool embedded = gfxFont->getEmbeddedFontID(&embRef);
-  if(embedded) {
-    char*tmpFileName = NULL;
-    char*fileName = NULL;
-    FILE *f;
-    char *fontBuf;
-    int fontLen;
-    Type1CFontConverter *cvt;
-    Ref embRef;
-    Object refObj, strObj;
-    int c;
-    if (!gfxFont->is16Bit() &&
-       (gfxFont->getType() == fontType1 ||
-        gfxFont->getType() == fontType1C) &&
-       gfxFont->getEmbeddedFontID(&embRef)) {
-      tmpFileName = "tmpfont";
       f = fopen(tmpFileName, "wb");
       if (!f) {
        logf("<error> Couldn't create temporary Type 1 font file");
-       return;
+       return 0;
       }
-      if (gfxFont->getType() == fontType1C) {
-       if (!(fontBuf = gfxFont->readEmbFontFile(&fontLen))) {
+      if (font->getType() == fontType1C) {
+       if (!(fontBuf = font->readEmbFontFile(&fontLen))) {
          fclose(f);
          logf("<error> Couldn't read embedded font file");
-         return ;
+         return 0;
        }
        cvt = new Type1CFontConverter(fontBuf, fontLen, f);
        cvt->convert();
        delete cvt;
        gfree(fontBuf);
       } else {
-       gfxFont->getEmbeddedFontID(&embRef);
+       font->getEmbeddedFontID(&embRef);
        refObj.initRef(embRef.num, embRef.gen);
        refObj.fetch(&strObj);
        refObj.free();
@@ -854,15 +810,67 @@ void SWFOutputDev::updateFont(GfxState *state) {
       fileName = tmpFileName;
       if(!fileName) {
          logf("<error> Embedded font writer didn't create a file");
-         return ;
+         return 0;
       }
+      return fileName;
+}
+
+char* gfxFontName(GfxFont* gfxFont)
+{
+      GString *gstr;
+      gstr = gfxFont->getName();
+      if(gstr) {
+         return gstr->getCString();
+      }
+      else {
+         char buf[32];
+         Ref r=gfxFont->getID();
+         sprintf(buf, "UFONT%d", r.num);
+         return strdup(buf);
+      }
+}
+
+void SWFOutputDev::updateFont(GfxState *state) 
+{
+  double m11, m12, m21, m22;
+  char * fontname = 0;
+  GfxFont*gfxFont = state->getFont();
+  char * fileName = 0;
+
+  if (!gfxFont) {
+    return;
+  }  
+
+  if(swfoutput_queryfont(&output, gfxFontName(gfxFont)))
+  {
+      swfoutput_setfont(&output, gfxFontName(gfxFont), -1, 0);
+      return;
+  }
+
+  // look for Type 3 font
+  if (!type3Warning && gfxFont->getType() == fontType3) {
+    type3Warning = gTrue;
+    showFontError(gfxFont, 2);
+  }
+  //dumpFontInfo ("<notice>", gfxFont);
+
+  Ref embRef;
+  GBool embedded = gfxFont->getEmbeddedFontID(&embRef);
+  if(embedded) {
+    if (!gfxFont->is16Bit() &&
+       (gfxFont->getType() == fontType1 ||
+        gfxFont->getType() == fontType1C)) {
+       
+       fileName = writeEmbeddedFontToFile(gfxFont);
+       if(!fileName)
+         return ;
     }
     else {
        showFontError(gfxFont,0);
        return ;
     }
+    
     t1id = T1_AddFont(fileName);
-    initT1Font(t1id, gfxFont->getEncoding());
   } else {
     fontname = NULL;
     if(gfxFont->getName()) {
@@ -934,68 +942,214 @@ void SWFOutputDev::updateFont(GfxState *state) {
     }
   }
 
-  swfoutput_setfont(&output,t1id);
+  swfoutput_setfont(&output,gfxFontName(gfxFont),t1id, fileName);
+  if(fileName)
+      unlink(fileName);
 }
 
-void SWFOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str,
-                                  int width, int height, GBool invert,
-                                  GBool inlineImg) {
+int pic_xids[1024];
+int pic_yids[1024];
+int pic_ids[1024];
+int picpos = 0;
+int pic_id = 0;
+
+void SWFOutputDev::drawGeneralImage(GfxState *state, Object *ref, Stream *str,
+                                  int width, int height, GfxImageColorMap*colorMap, GBool invert,
+                                  GBool inlineImg, int mask)
+{
   FILE *fi;
   int c;
   char fileName[128];
   double x1,y1,x2,y2,x3,y3,x4,y4;
+  ImageStream *imgStr;
+  Guchar pixBuf[4];
+  GfxRGB rgb;
+  if(!width || !height)
+      return;
+  
   state->transform(0, 1, &x1, &y1);
   state->transform(0, 0, &x2, &y2);
   state->transform(1, 0, &x3, &y3);
   state->transform(1, 1, &x4, &y4);
 
-  if (str->getKind() == strDCT) {
+  if (str->getKind() == strDCT &&
+      (colorMap->getNumPixelComps() == 3 || !mask) )
+  {
     sprintf(fileName, "/tmp/tmp%08x.jpg",lrand48());
-    logf("<notice> Found picture. Temporary storage is %s", fileName);
+    logf("<verbose> Found jpeg. Temporary storage is %s", fileName);
+    if(!jpeginfo)
+    {
+       logf("<notice> file contains jpeg pictures");
+       jpeginfo = 1;
+    }
     if (!(fi = fopen(fileName, "wb"))) {
       logf("<error> Couldn't open temporary image file '%s'", fileName);
       return;
     }
     str = ((DCTStream *)str)->getRawStream();
     str->reset();
+    int xid = 0;
+    int yid = 0;
+    int count = 0;
     while ((c = str->getChar()) != EOF)
+    {
       fputc(c, fi);
+      xid += count*c;
+      yid += (~count)*c;
+      count++;
+    }
     fclose(fi);
-    swfoutput_drawimagefile(&output, fileName, width, height, x1,y1,x2,y2,x3,y3,x4,y4);
+    
+    int t,found = -1;
+    for(t=0;t<picpos;t++)
+    {
+       if(pic_xids[t] == xid &&
+          pic_yids[t] == yid) {
+           found = t;break;
+       }
+    }
+    if(found<0) {
+       pic_ids[picpos] = swfoutput_drawimagejpeg(&output, fileName, width, height, 
+               x1,y1,x2,y2,x3,y3,x4,y4);
+       pic_xids[picpos] = xid;
+       pic_yids[picpos] = yid;
+       if(picpos<1024)
+           picpos++;
+    } else {
+       swfoutput_drawimageagain(&output, pic_ids[found], width, height,
+               x1,y1,x2,y2,x3,y3,x4,y4);
+    }
+    unlink(fileName);
   } else {
-      logf("<notice> File contains pbm pictures.");
+
+    if(!pbminfo) {
+       logf("<notice> file contains pbm pictures %s",mask?"(masked)":"");
+       if(mask)
+       logf("<verbose> ignoring %d by %d masked picture\n", width, height);
+       pbminfo = 1;
+    }
+
+    if(mask) {
+       str->reset();
+       int yes=0;
+       while ((c = str->getChar()) != EOF)
+       {
+           if((c<32 || c>'z') && yes && (c!=13) && (c!=10)) {
+               printf("no ascii: %02x\n", c);
+               yes = 1;
+          }
+       }
+    } else {
+       int x,y;
+       int width2 = (width+3)&(~3);
+       imgStr = new ImageStream(str, width, colorMap->getNumPixelComps(),
+                                colorMap->getBits());
+       imgStr->reset();
+
+       if(colorMap->getNumPixelComps()!=1)
+       {
+           RGBA*pic=new RGBA[width*height];
+           int xid = 0;
+           int yid = 0;
+           for (y = 0; y < height; ++y) {
+             for (x = 0; x < width; ++x) {
+               int r,g,b,a;
+               imgStr->getPixel(pixBuf);
+               colorMap->getRGB(pixBuf, &rgb);
+               pic[width*y+x].r = r = (U8)(rgb.r * 255 + 0.5);
+               pic[width*y+x].g = g = (U8)(rgb.g * 255 + 0.5);
+               pic[width*y+x].b = b = (U8)(rgb.b * 255 + 0.5);
+               pic[width*y+x].a = a = 255;//(U8)(rgb.a * 255 + 0.5);
+               xid += x*r+x*b*3+x*g*7+x*a*11;
+               yid += y*r*3+y*b*17+y*g*19+y*a*11;
+             }
+           }
+           int t,found = -1;
+           for(t=0;t<picpos;t++)
+           {
+               if(pic_xids[t] == xid &&
+                  pic_yids[t] == yid) {
+                   found = t;break;
+               }
+           }
+           if(found<0) {
+               pic_ids[picpos] = swfoutput_drawimagelossless(&output, pic, width, height, 
+                       x1,y1,x2,y2,x3,y3,x4,y4);
+               pic_xids[picpos] = xid;
+               pic_yids[picpos] = yid;
+               if(picpos<1024)
+                   picpos++;
+           } else {
+               swfoutput_drawimageagain(&output, pic_ids[found], width, height,
+                       x1,y1,x2,y2,x3,y3,x4,y4);
+           }
+           delete pic;
+       }
+       else
+       {
+           U8*pic = new U8[width2*height];
+           RGBA pal[256];
+           int t;
+           int xid=0,yid=0;
+           for(t=0;t<256;t++)
+           {
+               int r,g,b,a;
+               pixBuf[0] = t;
+               colorMap->getRGB(pixBuf, &rgb);
+               pal[t].r = r = (U8)(rgb.r * 255 + 0.5);
+               pal[t].g = g = (U8)(rgb.g * 255 + 0.5);
+               pal[t].b = b = (U8)(rgb.b * 255 + 0.5);
+               pal[t].a = a = 255;//(U8)(rgb.b * 255 + 0.5);
+               xid += t*r+t*b*3+t*g*7+t*a*11;
+               xid += (~t)*r+t*b*3+t*g*7+t*a*11;
+           }
+           for (y = 0; y < height; ++y) {
+             for (x = 0; x < width; ++x) {
+               imgStr->getPixel(pixBuf);
+               pic[width2*y+x] = pixBuf[0];
+               xid += x*pixBuf[0]*7;
+               yid += y*pixBuf[0]*3;
+             }
+           }
+           int found = -1;
+           for(t=0;t<picpos;t++)
+           {
+               if(pic_xids[t] == xid &&
+                  pic_yids[t] == yid) {
+                   found = t;break;
+               }
+           }
+           if(found<0) {
+               pic_ids[picpos] = swfoutput_drawimagelossless256(&output, pic, pal, width, height, 
+                       x1,y1,x2,y2,x3,y3,x4,y4);
+               pic_xids[picpos] = xid;
+               pic_yids[picpos] = yid;
+               if(picpos<1024)
+                   picpos++;
+           } else {
+               swfoutput_drawimageagain(&output, pic_ids[found], width, height,
+                       x1,y1,x2,y2,x3,y3,x4,y4);
+           }
+           delete pic;
+       }
+       delete imgStr;
+    }
+
   }
 }
 
+void SWFOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str,
+                                  int width, int height, GBool invert,
+                                  GBool inlineImg) 
+{
+  drawGeneralImage(state,ref,str,width,height,0,invert,inlineImg,1);
+}
+
 void SWFOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
                               int width, int height,
-                              GfxImageColorMap *colorMap, GBool inlineImg) {
-  FILE *fi;
-  int c;
-  char fileName[128];
-  double x1,y1,x2,y2,x3,y3,x4,y4;
-  state->transform(0, 1, &x1, &y1);
-  state->transform(0, 0, &x2, &y2);
-  state->transform(1, 0, &x3, &y3);
-  state->transform(1, 1, &x4, &y4);
-
-  if (str->getKind() == strDCT &&
-      colorMap->getNumPixelComps() == 3) {
-    sprintf(fileName, "/tmp/tmp%08x.jpg", lrand48());
-    logf("<notice> Found picture. Temporary storage is %s", fileName);
-    if (!(fi = fopen(fileName, "wb"))) {
-      error(-1, "Couldn't open temporary image file '%s'", fileName);
-      return;
-    }
-    str = ((DCTStream *)str)->getRawStream();
-    str->reset();
-    while ((c = str->getChar()) != EOF)
-      fputc(c, fi);
-    fclose(fi);
-    swfoutput_drawimagefile(&output, fileName, width, height, x1,y1,x2,y2,x3,y3,x4,y4);
-  } else {
-      logf("<notice> File contains pbm pictures.");
-  }
+                              GfxImageColorMap *colorMap, GBool inlineImg) 
+{
+  drawGeneralImage(state,ref,str,width,height,colorMap,0,inlineImg,0);
 }
 
 PDFDoc*doc = 0;
@@ -1076,9 +1230,26 @@ void pdfswf_init(char*filename, char*userPassword)
   output = new SWFOutputDev();
 }
 
+void pdfswf_drawonlyshapes()
+{
+    drawonlyshapes = 1;
+}
+
+void pdfswf_ignoredraworder()
+{
+    ignoredraworder = 1;
+}
+
+void pdfswf_jpegquality(int val)
+{
+    if(val<0) val=0;
+    if(val>100) val=100;
+    jpegquality = val;
+}
+
 void pdfswf_setoutputfilename(char*_filename)
 {
-    filename = _filename;
+    swffilename = _filename;
 }
 
 void pdfswf_convertpage(int page)
@@ -1091,11 +1262,12 @@ int pdfswf_numpages()
   return doc->getNumPages();
 }
 
+int closed=0;
 void pdfswf_close()
 {
-    delete doc;
+    logf("<debug> pdfswf.cc: pdfswf_close()");
     delete output;
-    
+    delete doc;
     freeParams();
     // check for memory leaks
     Object::memCheck(stderr);