fixed crash and offset error in transparency groups
[swftools.git] / lib / pdf / GFXOutputDev.cc
index d110976..43aa743 100644 (file)
@@ -156,7 +156,7 @@ typedef struct _feature
 } feature_t;
 feature_t*featurewarnings = 0;
 
-void GFXOutputDev::showfeature(const char*feature,char fully, char warn)
+void GFXOutputDev::showfeature(const char*feature, char fully, char warn)
 {
     feature_t*f = featurewarnings;
     while(f) {
@@ -1206,6 +1206,10 @@ void GFXOutputDev::processLink(Link *link, Catalog *catalog)
            points[1].x, points[1].y,
            points[2].x, points[2].y,
            points[3].x, points[3].y); 
+    
+    if(getLogLevel() >= LOGLEVEL_TRACE)  {
+       dump_outline(points);
+    }
 
     LinkAction*action=link->getAction();
     char buf[128];
@@ -1728,7 +1732,7 @@ void GFXOutputDev::drawGeneralImage(GfxState *state, Object *ref, Stream *str,
   imgStr = new ImageStream(str, width, ncomps,bits);
   imgStr->reset();
 
-  if(!width || !height || (height<=1 && width<=1))
+  if(!width || !height || (height<=1 && width<=1 && maskWidth<=1 && maskHeight<=1))
   {
       msg("<verbose> Ignoring %d by %d image", width, height);
       unsigned char buf[8];
@@ -1798,7 +1802,7 @@ void GFXOutputDev::drawGeneralImage(GfxState *state, Object *ref, Stream *str,
          pic2 = antialize(pic,width,height,realwidth,realheight,numpalette);
 
          if(!pic2) {
-           delete pic;
+           delete[] pic;
            delete imgStr;
            return;
          }
@@ -1855,7 +1859,7 @@ void GFXOutputDev::drawGeneralImage(GfxState *state, Object *ref, Stream *str,
          drawimagejpeg(device, pic, width, height, x1,y1,x2,y2,x3,y3,x4,y4);
       else
          drawimagelossless(device, pic, width, height, x1,y1,x2,y2,x3,y3,x4,y4);
-      delete pic;
+      delete[] pic;
       delete imgStr;
       if(maskbitmap) free(maskbitmap);
       return;
@@ -1899,14 +1903,39 @@ void GFXOutputDev::drawGeneralImage(GfxState *state, Object *ref, Stream *str,
        for (x = 0; x < width; ++x) {
          imgStr->getPixel(pixBuf);
          pic[width*y+x] = pal[pixBuf[0]];
-         if(maskbitmap) {
-             pic[width*y+x].a = maskbitmap[(y*maskHeight/height)*maskWidth+(x*maskWidth/width)];
-         }
        }
       }
+      if(maskbitmap) {
+         if(maskWidth < width && maskHeight < height) {
+             for(y = 0; y < height; y++) {
+                 for (x = 0; x < width; x++) {
+                     pic[width*y+x].a = maskbitmap[(y*maskHeight/height)*maskWidth+(x*maskWidth/width)];
+                 }
+             }
+         } else {
+             msg("<verbose> resampling %dx%d to mask size (%dx%d)", width, height, maskWidth, maskHeight);
+             gfxcolor_t*newpic=new gfxcolor_t[maskWidth*maskHeight];
+             double dx = width / maskWidth;
+             double dy = height / maskHeight;
+             double yy = 0;
+             for(y = 0; y < maskHeight; y++) {
+                 double xx = 0;
+                 for (x = 0; x < maskWidth; x++) {
+                     newpic[maskWidth*y+x] = pic[int(yy)*width+int(xx)];
+                     newpic[maskWidth*y+x].a = maskbitmap[maskWidth*y+x];
+                     xx += dx;
+                 }
+                 yy += dy;
+             }
+             delete[] pic;
+             pic = newpic;
+             width = maskWidth;
+             height = maskHeight;
+         }
+      }
       drawimagelossless(device, pic, width, height, x1,y1,x2,y2,x3,y3,x4,y4);
 
-      delete pic;
+      delete[] pic;
       delete imgStr;
       if(maskbitmap) free(maskbitmap);
       return;
@@ -2221,7 +2250,8 @@ void GFXOutputDev::beginTransparencyGroup(GfxState *state, double *bbox,
     dbg("beginTransparencyGroup %.1f/%.1f/%.1f/%.1f %s isolated=%d knockout=%d forsoftmask=%d", bbox[0],bbox[1],bbox[2],bbox[3], colormodename, isolated, knockout, forSoftMask);
     msg("<verbose> beginTransparencyGroup %.1f/%.1f/%.1f/%.1f %s isolated=%d knockout=%d forsoftmask=%d", bbox[0],bbox[1],bbox[2],bbox[3], colormodename, isolated, knockout, forSoftMask);
     
-    states[statepos].createsoftmask |= forSoftMask;
+    //states[statepos].createsoftmask |= forSoftMask;
+    states[statepos].createsoftmask = forSoftMask;
     states[statepos].transparencygroup = !forSoftMask;
     states[statepos].isolated = isolated;
 
@@ -2246,10 +2276,11 @@ void GFXOutputDev::endTransparencyGroup(GfxState *state)
 
     this->device = states[statepos].olddevice;
 
+    gfxresult_t*recording = r->finish(r);
     if(states[statepos].createsoftmask) {
-       states[statepos-1].softmaskrecording = r->finish(r);
+       states[statepos-1].softmaskrecording = recording;
     } else {
-       states[statepos-1].grouprecording = r->finish(r);
+       states[statepos-1].grouprecording = recording;
     }
     
     states[statepos].createsoftmask = 0;