fixed mem leaks
authorMatthias Kramm <kramm@quiss.org>
Fri, 14 May 2010 01:39:39 +0000 (18:39 -0700)
committerMatthias Kramm <kramm@quiss.org>
Fri, 14 May 2010 01:39:39 +0000 (18:39 -0700)
lib/devices/record.c
lib/devices/record.h
lib/gfxfilter.c
lib/pdf/BitmapOutputDev.cc
lib/pdf/BitmapOutputDev.h
lib/pdf/GFXOutputDev.cc

index fb1c5a9..3485840 100644 (file)
@@ -34,6 +34,7 @@
 #include <assert.h>
 #include "../gfxdevice.h"
 #include "../gfxtools.h"
+#include "../gfxfont.h"
 #include "../types.h"
 #include "../bitio.h"
 #include "../log.h"
@@ -643,18 +644,20 @@ static void record_drawlink(struct _gfxdevice*dev, gfxline_t*line, const char*ac
 
 /* ------------------------------- replaying --------------------------------- */
 
-static void replay(struct _gfxdevice*dev, gfxdevice_t*out, reader_t*r)
+static void replay(struct _gfxdevice*dev, gfxdevice_t*out, reader_t*r, gfxfontlist_t**fontlist)
 {
     internal_t*i = 0;
     if(dev) {
        i = (internal_t*)dev->internal;
     }
+    gfxfontlist_t*_fontlist=0;
+    if(!fontlist) {
+       fontlist = &_fontlist;
+    }
 
     state_t state;
     memset(&state, 0, sizeof(state));
 
-    gfxfontlist_t* fontlist = gfxfontlist_create();
-
     while(1) {
        unsigned char op;
        if(r->read(r, &op, 1)!=1)
@@ -777,8 +780,13 @@ static void replay(struct _gfxdevice*dev, gfxdevice_t*out, reader_t*r)
            case OP_ADDFONT: {
                msg("<trace> replay: ADDFONT out=%08x(%s)", out, out->name);
                gfxfont_t*font = readFont(r, &state);
-               fontlist = gfxfontlist_addfont(fontlist, font);
-               out->addfont(out, font);
+               if(!gfxfontlist_hasfont(*fontlist, font)) {
+                   printf("%08x / %08x: font %s is new\n", out, *fontlist, font->id);
+                   *fontlist = gfxfontlist_addfont(*fontlist, font);
+                   out->addfont(out, font);
+               } else {
+                   gfxfont_free(font);
+               }
                break;
            }
            case OP_DRAWCHAR: {
@@ -790,7 +798,7 @@ static void replay(struct _gfxdevice*dev, gfxdevice_t*out, reader_t*r)
                gfxcolor_t color = read_color(r, &state, op, flags);
                gfxmatrix_t matrix = read_matrix(r, &state, op, flags);
 
-               gfxfont_t*font = id?gfxfontlist_findfont(fontlist, id):0;
+               gfxfont_t*font = id?gfxfontlist_findfont(*fontlist, id):0;
                if(i && !font) {
                    font = gfxfontlist_findfont(i->fontlist, id);
                }
@@ -804,13 +812,10 @@ static void replay(struct _gfxdevice*dev, gfxdevice_t*out, reader_t*r)
     }
 finish:
     r->dealloc(r);
-    /* problem: if we just replayed into a device which stores the
-       font for later use (the record device itself is a nice example),
-       then we can't free it yet */
-    //gfxfontlist_free(fontlist, 1);
-    gfxfontlist_free(fontlist, 0);
+    if(_fontlist)
+       gfxfontlist_free(_fontlist, 0);
 }
-void gfxresult_record_replay(gfxresult_t*result, gfxdevice_t*device)
+void gfxresult_record_replay(gfxresult_t*result, gfxdevice_t*device, gfxfontlist_t**fontlist)
 {
     internal_result_t*i = (internal_result_t*)result->internal;
     
@@ -821,7 +826,7 @@ void gfxresult_record_replay(gfxresult_t*result, gfxdevice_t*device)
        reader_init_memreader(&r, i->data, i->length);
     }
 
-    replay(0, device, &r);
+    replay(0, device, &r, fontlist);
 }
 
 static void record_result_write(gfxresult_t*r, int filedesc)
@@ -896,7 +901,7 @@ static void hexdumpMem(unsigned char*data, int len)
     }
 }
 
-void gfxdevice_record_flush(gfxdevice_t*dev, gfxdevice_t*out)
+void gfxdevice_record_flush(gfxdevice_t*dev, gfxdevice_t*out, gfxfontlist_t**fontlist)
 {
     internal_t*i = (internal_t*)dev->internal;
     if(out) {
@@ -905,7 +910,7 @@ void gfxdevice_record_flush(gfxdevice_t*dev, gfxdevice_t*out)
            void*data = writer_growmemwrite_memptr(&i->w, &len);
            reader_t r;
            reader_init_memreader(&r, data, len);
-           replay(dev, out, &r);
+           replay(dev, out, &r, fontlist);
            writer_growmemwrite_reset(&i->w);
        } else {
            msg("<fatal> Flushing not supported for file based record device");
index 34fe1e4..d47b0ec 100644 (file)
@@ -23,6 +23,7 @@
 #define __record_h__
 
 #include "../gfxdevice.h"
+#include "../gfxtools.h"
 
 
 #ifdef __cplusplus
@@ -33,9 +34,9 @@ void gfxdevice_record_init(gfxdevice_t*, char use_tempfile);
 
 gfxdevice_t* gfxdevice_record_new(char*filename);
 
-void gfxdevice_record_flush(gfxdevice_t*, gfxdevice_t*);
+void gfxdevice_record_flush(gfxdevice_t*, gfxdevice_t*, gfxfontlist_t**);
 
-void gfxresult_record_replay(gfxresult_t*, gfxdevice_t*);
+void gfxresult_record_replay(gfxresult_t*, gfxdevice_t*, gfxfontlist_t**);
 
 #ifdef __cplusplus
 }
index f1a341a..a7ee6c4 100644 (file)
@@ -305,7 +305,7 @@ static gfxresult_t* twopass_finish(gfxdevice_t*dev)
     }
 
     i->pass++;
-    gfxresult_record_replay(r, dev);
+    gfxresult_record_replay(r, dev, 0);
     r->destroy(r);
 
     return twopass_finish(dev);
index 9e8123b..5c005d0 100644 (file)
@@ -29,6 +29,7 @@
 #include "../log.h"
 #include "../png.h"
 #include "../devices/record.h"
+#include "../gfxtools.h"
 #include "../types.h"
 #include "bbox.h"
 
@@ -80,6 +81,7 @@ BitmapOutputDev::BitmapOutputDev(InfoOutputDev*info, PDFDoc*doc)
     this->gfxdev->setDevice(this->gfxoutput);
     
     this->config_extrafontdata = 0;
+    this->config_optimizeplaincolorfills = 0;
     this->bboxpath = 0;
     //this->clipdev = 0;
     //this->clipstates = 0;
@@ -311,7 +313,16 @@ void BitmapOutputDev::flushBitmap()
 void BitmapOutputDev::flushText()
 {
     msg("<verbose> Flushing text");
-    gfxdevice_record_flush(this->gfxoutput, this->dev);
+
+    static gfxfontlist_t*output_font_list = 0;
+    static gfxdevice_t*last = 0;
+    if(last != this->dev) {
+       if(output_font_list)
+           gfxfontlist_free(output_font_list, 0);
+       output_font_list = gfxfontlist_create();
+    }
+    gfxdevice_record_flush(this->gfxoutput, this->dev, &output_font_list);
+    last = this->dev;
     
     this->emptypage = 0;
 }
@@ -1335,11 +1346,47 @@ void BitmapOutputDev::stroke(GfxState *state)
     rgbdev->stroke(state);
     dbg_newdata("stroke");
 }
+
+extern gfxcolor_t getFillColor(GfxState * state);
+
+char area_is_plain_colored(GfxState*state, SplashBitmap*boolpoly, SplashBitmap*rgbbitmap, int x1, int y1, int x2, int y2)
+{
+    int width = boolpoly->getWidth();
+    int height = boolpoly->getHeight();
+    if(!fixBBox(&x1, &y1, &x2, &y2, width, height)) {
+       return 0;
+    }
+    gfxcolor_t color = getFillColor(state);
+    SplashColorPtr rgb = rgbbitmap->getDataPtr() 
+                      + (y1*width+x1)*sizeof(SplashColor);
+    int width8 = (width+7)/8;
+    unsigned char*bits = (unsigned char*)boolpoly->getDataPtr() 
+                        + (y1*width8+x1);
+    int x,y;
+    int w = x2-x1;
+    int h = y2-y1;
+    for(y=0;y<h;y++) {
+       for(x=0;x<w;x++) {
+           if(rgb[x*3+0] != color.r ||
+              rgb[x*3+1] != color.g ||
+              rgb[x*3+2] != color.b)
+               return 0;
+       }
+       rgb += width*sizeof(SplashColor);
+    }
+    return 1;
+}
+
 void BitmapOutputDev::fill(GfxState *state)
 {
     msg("<debug> fill");
     boolpolydev->fill(state);
     gfxbbox_t bbox = getBBox(state);
+    if(config_optimizeplaincolorfills) {
+       if(area_is_plain_colored(state, boolpolybitmap, rgbbitmap, bbox.xmin, bbox.ymin, bbox.xmax, bbox.ymax)) {
+           return;
+       }
+    }
     checkNewBitmap(bbox.xmin, bbox.ymin, ceil(bbox.xmax), ceil(bbox.ymax));
     rgbdev->fill(state);
     dbg_newdata("fill");
index ac13298..69309fc 100644 (file)
@@ -202,6 +202,7 @@ private:
     virtual gfxbbox_t getBBox(GfxState*state);
 
     char config_extrafontdata;
+    char config_optimizeplaincolorfills;
 
     int layerstate;
     GBool emptypage;
index 635d10d..13f7087 100644 (file)
@@ -105,6 +105,7 @@ struct fontentry {
     char*pfb;
     int pfblen;
     char*fullfilename;
+    DisplayFontParam *dfp;
 } pdf2t1map[] ={
 {"Times-Roman",           "n021003l", n021003l_afm, n021003l_afm_len, n021003l_pfb, n021003l_pfb_len},
 {"Times-Italic",          "n021023l", n021023l_afm, n021023l_afm_len, n021023l_pfb, n021023l_pfb_len},
@@ -564,10 +565,11 @@ DisplayFontParam *GFXGlobalParams::getDisplayFont(GString *fontName)
                } else {
                    msg("<verbose> Storing standard PDF font %s at %s", name, pdf2t1map[t].fullfilename);
                }
+               DisplayFontParam *dfp = new DisplayFontParam(new GString(fontName), displayFontT1);
+               dfp->t1.fileName = new GString(pdf2t1map[t].fullfilename);
+               pdf2t1map[t].dfp = dfp;
            }
-           DisplayFontParam *dfp = new DisplayFontParam(new GString(fontName), displayFontT1);
-           dfp->t1.fileName = new GString(pdf2t1map[t].fullfilename);
-           return dfp;
+           return pdf2t1map[t].dfp;
        }
     }
     
@@ -2752,7 +2754,7 @@ void GFXOutputDev::paintTransparencyGroup(GfxState *state, double *bbox)
        gfxdevice_t ops;
        dbg("this->device=%p, this->device->name=%s\n", this->device, this->device->name);
        gfxdevice_ops_init(&ops, this->device, alpha);
-       gfxresult_record_replay(grouprecording, &ops);
+       gfxresult_record_replay(grouprecording, &ops, 0);
        ops.finish(&ops);
     }
     grouprecording->destroy(grouprecording);
@@ -2824,15 +2826,15 @@ void GFXOutputDev::clearSoftMask(GfxState *state)
     /* get outline of all objects below the soft mask */
     gfxdevice_t uniondev;
     gfxdevice_union_init(&uniondev, 0);
-    gfxresult_record_replay(below, &uniondev);
+    gfxresult_record_replay(below, &uniondev, 0);
     gfxline_t*belowoutline = gfxdevice_union_getunion(&uniondev);
     uniondev.finish(&uniondev);
     gfxbbox_t bbox = gfxline_getbbox(belowoutline);
     gfxline_free(belowoutline);belowoutline=0;
 #if 0 
     this->device->startclip(this->device, belowoutline);
-    gfxresult_record_replay(below, this->device);
-    gfxresult_record_replay(mask, this->device);
+    gfxresult_record_replay(below, this->device, 0);
+    gfxresult_record_replay(mask, this->device, 0);
     this->device->endclip(this->device);
 #endif
     
@@ -2847,7 +2849,7 @@ void GFXOutputDev::clearSoftMask(GfxState *state)
     }
     belowrender.setparameter(&belowrender, "antialize", "2");
     belowrender.startpage(&belowrender, width, height);
-    gfxresult_record_replay(below, &belowrender);
+    gfxresult_record_replay(below, &belowrender, 0);
     belowrender.endpage(&belowrender);
     gfxresult_t* belowresult = belowrender.finish(&belowrender);
     gfximage_t* belowimg = (gfximage_t*)belowresult->get(belowresult,"page0");
@@ -2856,7 +2858,7 @@ void GFXOutputDev::clearSoftMask(GfxState *state)
     gfxdevice_t maskrender;
     gfxdevice_render_init(&maskrender);
     maskrender.startpage(&maskrender, width, height);
-    gfxresult_record_replay(mask, &maskrender);
+    gfxresult_record_replay(mask, &maskrender, 0);
     maskrender.endpage(&maskrender);
     gfxresult_t* maskresult = maskrender.finish(&maskrender);
     gfximage_t* maskimg = (gfximage_t*)maskresult->get(maskresult,"page0");