From fdeb14b5acd8ab24c8c8dab6e78c23c967547747 Mon Sep 17 00:00:00 2001 From: acspike Date: Tue, 13 Jun 2006 01:43:48 +0000 Subject: [PATCH] patch [ 1503865 ] Siox performance patch --- src/trace/potrace/inkscape-potrace.cpp | 26 ++- src/trace/potrace/inkscape-potrace.h | 7 +- src/trace/siox.cpp | 245 +++++++++++++++++-------- src/trace/siox.h | 66 +++++-- src/trace/trace.cpp | 72 ++++---- src/trace/trace.h | 13 +- src/ui/dialog/tracedialog.cpp | 11 +- 7 files changed, 285 insertions(+), 155 deletions(-) diff --git a/src/trace/potrace/inkscape-potrace.cpp b/src/trace/potrace/inkscape-potrace.cpp index 12ffc551a..e18abb338 100644 --- a/src/trace/potrace/inkscape-potrace.cpp +++ b/src/trace/potrace/inkscape-potrace.cpp @@ -13,8 +13,10 @@ * */ +#include "inkscape-potrace.h" + #include -#include +#include #include "trace/filterset.h" #include "trace/imagemap-gdk.h" @@ -27,7 +29,6 @@ #include "curve.h" #include "bitmap.h" -#include "inkscape-potrace.h" static void updateGui() @@ -326,17 +327,20 @@ filterIndexed(PotraceTracingEngine &engine, GdkPixbuf * pixbuf) -GdkPixbuf * -PotraceTracingEngine::preview(GdkPixbuf * pixbuf) +Glib::RefPtr +PotraceTracingEngine::preview(Glib::RefPtr thePixbuf) { + GdkPixbuf *pixbuf = thePixbuf->gobj(); + if ( traceType == TRACE_QUANT_COLOR || traceType == TRACE_QUANT_MONO ) { IndexedMap *gm = filterIndexed(*this, pixbuf); if (!gm) - return NULL; + return Glib::RefPtr(NULL); - GdkPixbuf *newBuf = indexedMapToGdkPixbuf(gm); + Glib::RefPtr newBuf = + Glib::wrap(indexedMapToGdkPixbuf(gm), false); gm->destroy(gm); @@ -346,9 +350,10 @@ PotraceTracingEngine::preview(GdkPixbuf * pixbuf) { GrayMap *gm = filter(*this, pixbuf); if (!gm) - return NULL; + return Glib::RefPtr(NULL); - GdkPixbuf *newBuf = grayMapToGdkPixbuf(gm); + Glib::RefPtr newBuf = + Glib::wrap(grayMapToGdkPixbuf(gm), false); gm->destroy(gm); @@ -668,9 +673,12 @@ PotraceTracingEngine::traceQuant(GdkPixbuf * thePixbuf, int *nrPaths) * of an SVG element. */ TracingEngineResult * -PotraceTracingEngine::trace(GdkPixbuf * thePixbuf, int *nrPaths) +PotraceTracingEngine::trace(Glib::RefPtr pixbuf, + int *nrPaths) { + GdkPixbuf *thePixbuf = pixbuf->gobj(); + //Set up for messages keepGoing = 1; diff --git a/src/trace/potrace/inkscape-potrace.h b/src/trace/potrace/inkscape-potrace.h index 7a8d97b2e..0f257cb95 100644 --- a/src/trace/potrace/inkscape-potrace.h +++ b/src/trace/potrace/inkscape-potrace.h @@ -16,7 +16,7 @@ #ifndef __INKSCAPE_POTRACE_H__ #define __INKSCAPE_POTRACE_H__ -#include +#include #include #include @@ -165,7 +165,8 @@ class PotraceTracingEngine : public TracingEngine * return the path data that is compatible with the d="" attribute * of an SVG element. */ - virtual TracingEngineResult *trace(GdkPixbuf *pixbuf, int *nrPaths); + virtual TracingEngineResult *trace(Glib::RefPtr pixbuf, + int *nrPaths); /** * Abort the thread that is executing getPathDataFromPixbuf() @@ -175,7 +176,7 @@ class PotraceTracingEngine : public TracingEngine /** * */ - GdkPixbuf *preview(GdkPixbuf * pixbuf); + Glib::RefPtr preview(Glib::RefPtr pixbuf); /** * diff --git a/src/trace/siox.cpp b/src/trace/siox.cpp index b0632567c..9c5db4731 100644 --- a/src/trace/siox.cpp +++ b/src/trace/siox.cpp @@ -34,7 +34,7 @@ namespace siox //# C L A B //######################################################################## -static std::map clabLookupTable; +static std::map clabLookupTable; /** * Convert integer A, R, G, B values into an pixel value. @@ -71,17 +71,71 @@ static unsigned long getRGB(float a, float r, float g, float b) +//######################################### +//# Root approximations for large speedup. +//# By njh! +//######################################### +static const int ROOT_TAB_SIZE = 16; +static float cbrt_table[ROOT_TAB_SIZE +1]; + +double CieLab::cbrt(double x) +{ + double y = cbrt_table[int(x*ROOT_TAB_SIZE )]; // assuming x \in [0, 1] + y = (2.0 * y + x/(y*y))/3.0; + y = (2.0 * y + x/(y*y))/3.0; // polish twice + return y; +} + +static float qn_table[ROOT_TAB_SIZE +1]; + +double CieLab::qnrt(double x) +{ + double y = qn_table[int(x*ROOT_TAB_SIZE )]; // assuming x \in [0, 1] + double Y = y*y; + y = (4.0*y + x/(Y*Y))/5.0; + Y = y*y; + y = (4.0*y + x/(Y*Y))/5.0; // polish twice + return y; +} + +double CieLab::pow24(double x) +{ + double onetwo = x*qnrt(x); + return onetwo*onetwo; +} + + +static bool _clab_inited_ = false; +void CieLab::init() +{ + if (!_clab_inited_) + { + cbrt_table[0] = pow(float(1)/float(ROOT_TAB_SIZE*2), 0.3333); + qn_table[0] = pow(float(1)/float(ROOT_TAB_SIZE*2), 0.2); + for(int i = 1; i < ROOT_TAB_SIZE +1; i++) + { + cbrt_table[i] = pow(float(i)/float(ROOT_TAB_SIZE), 0.3333); + qn_table[i] = pow(float(i)/float(ROOT_TAB_SIZE), 0.2); + } + _clab_inited_ = true; + } +} + + + /** - * Construct this CLAB from a packed-pixel ARGB value + * Construct this CieLab from a packed-pixel ARGB value */ -CLAB::CLAB(unsigned long rgb) +CieLab::CieLab(unsigned long rgb) { + init(); + //First try looking up in the cache - std::map::iterator iter; + std::map::iterator iter; iter = clabLookupTable.find(rgb); if (iter != clabLookupTable.end()) { - CLAB res = iter->second; + CieLab res = iter->second; C = res.C; L = res.L; A = res.A; @@ -97,18 +151,22 @@ CLAB::CLAB(unsigned long rgb) float fg = ((float)ig) / 255.0; float fb = ((float)ib) / 255.0; + //printf("fr:%f fg:%f fb:%f\n", fr, fg, fb); if (fr > 0.04045) - fr = (float) pow((fr + 0.055) / 1.055, 2.4); + //fr = (float) pow((fr + 0.055) / 1.055, 2.4); + fr = (float) pow24((fr + 0.055) / 1.055); else fr = fr / 12.92; if (fg > 0.04045) - fg = (float) pow((fg + 0.055) / 1.055, 2.4); + //fg = (float) pow((fg + 0.055) / 1.055, 2.4); + fg = (float) pow24((fg + 0.055) / 1.055); else fg = fg / 12.92; if (fb > 0.04045) - fb = (float) pow((fb + 0.055) / 1.055, 2.4); + //fb = (float) pow((fb + 0.055) / 1.055, 2.4); + fb = (float) pow24((fb + 0.055) / 1.055); else fb = fb / 12.92; @@ -125,18 +183,22 @@ CLAB::CLAB(unsigned long rgb) float vy = y / 100.000; float vz = z / 108.883; + //printf("vx:%f vy:%f vz:%f\n", vx, vy, vz); if (vx > 0.008856) - vx = (float) pow(vx, 0.3333); + //vx = (float) pow(vx, 0.3333); + vx = (float) cbrt(vx); else vx = (7.787 * vx) + (16.0 / 116.0); if (vy > 0.008856) - vy = (float) pow(vy, 0.3333); + //vy = (float) pow(vy, 0.3333); + vy = (float) cbrt(vy); else vy = (7.787 * vy) + (16.0 / 116.0); if (vz > 0.008856) - vz = (float) pow(vz, 0.3333); + //vz = (float) pow(vz, 0.3333); + vz = (float) cbrt(vz); else vz = (7.787 * vz) + (16.0 / 116.0); @@ -153,9 +215,9 @@ CLAB::CLAB(unsigned long rgb) /** - * Return this CLAB's value a a packed-pixel ARGB value + * Return this CieLab's value a a packed-pixel ARGB value */ -unsigned long CLAB::toRGB() +unsigned long CieLab::toRGB() { float vy = (L + 16.0) / 116.0; float vx = A / 500.0 + vy; @@ -212,31 +274,41 @@ unsigned long CLAB::toRGB() /** - * Computes squared euclidian distance in CLAB space for two colors + * Squared Euclidian distance between this and another color + */ +float CieLab::diffSq(const CieLab &other) +{ + float sum=0.0; + sum += (L - other.L) * (L - other.L); + sum += (A - other.A) * (A - other.A); + sum += (B - other.B) * (B - other.B); + return sum; +} + +/** + * Computes squared euclidian distance in CieLab space for two colors * given as RGB values. */ -float CLAB::diffSq(unsigned int rgb1, unsigned int rgb2) +float CieLab::diffSq(unsigned int rgb1, unsigned int rgb2) { - CLAB c1(rgb1); - CLAB c2(rgb2); - float euclid=0.0f; - euclid += (c1.L - c2.L) * (c1.L - c2.L); - euclid += (c1.A - c2.A) * (c1.A - c2.A); - euclid += (c1.B - c2.B) * (c1.B - c2.B); + CieLab c1(rgb1); + CieLab c2(rgb2); + float euclid = c1.diffSq(c2); return euclid; } /** - * Computes squared euclidian distance in CLAB space for two colors + * Computes squared euclidian distance in CieLab space for two colors * given as RGB values. */ -float CLAB::diff(unsigned int rgb0, unsigned int rgb1) +float CieLab::diff(unsigned int rgb0, unsigned int rgb1) { return (float) sqrt(diffSq(rgb0, rgb1)); } + //######################################################################## //# T U P E L //######################################################################## @@ -743,6 +815,8 @@ bool Siox::progressReport(float percentCompleted) SioxImage Siox::extractForeground(const SioxImage &originalImage, unsigned int backgroundFillColor) { + trace("### Start"); + init(); keepGoing = true; @@ -759,26 +833,42 @@ SioxImage Siox::extractForeground(const SioxImage &originalImage, trace("### Creating signatures"); //#### create color signatures - std::vector knownBg; - std::vector knownFg; - std::vector imageClab; + std::vector knownBg; + std::vector knownFg; + CieLab *imageClab = new CieLab[pixelCount]; + for (unsigned long i=0 ; i= FOREGROUND_CONFIDENCE) + knownFg.push_back(lab); + } + + /* + std::vector imageClab; for (int y = 0 ; y < workImage.getHeight() ; y++) for (int x = 0 ; x < workImage.getWidth() ; x++) { float cm = workImage.getConfidence(x, y); unsigned int pix = workImage.getPixel(x, y); - CLAB lab(pix); + CieLab lab(pix); imageClab.push_back(lab); if (cm <= BACKGROUND_CONFIDENCE) - knownBg.push_back(lab); //note: uses CLAB(rgb) + knownBg.push_back(lab); //note: uses CieLab(rgb) else if (cm >= FOREGROUND_CONFIDENCE) knownFg.push_back(lab); } + */ if (!progressReport(10.0)) { error("User aborted"); workImage.setValid(false); + delete[] imageClab; delete[] labelField; return workImage; } @@ -786,11 +876,12 @@ SioxImage Siox::extractForeground(const SioxImage &originalImage, trace("knownBg:%d knownFg:%d", knownBg.size(), knownFg.size()); - std::vector bgSignature ; + std::vector bgSignature ; if (!colorSignature(knownBg, bgSignature, 3)) { error("Could not create background signature"); workImage.setValid(false); + delete[] imageClab; delete[] labelField; return workImage; } @@ -799,16 +890,18 @@ SioxImage Siox::extractForeground(const SioxImage &originalImage, { error("User aborted"); workImage.setValid(false); + delete[] imageClab; delete[] labelField; return workImage; } - std::vector fgSignature ; + std::vector fgSignature ; if (!colorSignature(knownFg, fgSignature, 3)) { error("Could not create foreground signature"); workImage.setValid(false); + delete[] imageClab; delete[] labelField; return workImage; } @@ -820,6 +913,7 @@ SioxImage Siox::extractForeground(const SioxImage &originalImage, // segmentation impossible error("Signature size is < 1. Segmentation is impossible"); workImage.setValid(false); + delete[] imageClab; delete[] labelField; return workImage; } @@ -828,6 +922,7 @@ SioxImage Siox::extractForeground(const SioxImage &originalImage, { error("User aborted"); workImage.setValid(false); + delete[] imageClab; delete[] labelField; return workImage; } @@ -835,6 +930,8 @@ SioxImage Siox::extractForeground(const SioxImage &originalImage, // classify using color signatures, // classification cached in hashmap for drb and speedup purposes + trace("### Analyzing image"); + std::map hs; unsigned int progressResolution = pixelCount / 10; @@ -844,10 +941,12 @@ SioxImage Siox::extractForeground(const SioxImage &originalImage, if (i % progressResolution == 0) { float progress = - 30.0 + 60.0 * (float)i / (float)progressResolution; + 30.0 + 60.0 * (float)i / (float)pixelCount; + //trace("### progress:%f", progress); if (!progressReport(progress)) { error("User aborted"); + delete[] imageClab; delete[] labelField; workImage.setValid(false); return workImage; @@ -868,17 +967,17 @@ SioxImage Siox::extractForeground(const SioxImage &originalImage, std::map::iterator iter = hs.find(i); if (iter != hs.end()) //found { - Tupel tupel = iter->second; + Tupel tupel = iter->second; isBackground = tupel.minBgDist <= tupel.minFgDist; } else { - CLAB lab = imageClab[i]; - float minBg = sqrEuclidianDist(lab, bgSignature[0]); - int minIndex=0; + CieLab lab = imageClab[i]; + float minBg = lab.diffSq(bgSignature[0]); + int minIndex = 0; for (unsigned int j=1; j= threshold) { float scale = (float)(rightBase - leftBase); - CLAB newpoint; + CieLab newpoint; for (; leftBase < rightBase; leftBase++) newpoint.add(points[leftBase]); @@ -1200,8 +1297,8 @@ void Siox::colorSignatureStage2(CLAB *points, /** * Main color signature method */ -bool Siox::colorSignature(const std::vector &inputVec, - std::vector &result, +bool Siox::colorSignature(const std::vector &inputVec, + std::vector &result, const unsigned int dims) { @@ -1210,7 +1307,7 @@ bool Siox::colorSignature(const std::vector &inputVec, if (length < 1) // no error. just don't do anything return true; - CLAB *input = (CLAB *) malloc(length * sizeof(CLAB)); + CieLab *input = (CieLab *) malloc(length * sizeof(CieLab)); if (!input) { @@ -1389,7 +1486,7 @@ void Siox::fillColorRegions() // check all four neighbours int left = pos-1; if (((int)x)-1 >= 0 && labelField[left] == -1 - && CLAB::diff(image[left], origColor)<1.0) + && CieLab::diff(image[left], origColor)<1.0) { labelField[left]=curLabel; cm[left]=CERTAIN_FOREGROUND_CONFIDENCE; @@ -1398,7 +1495,7 @@ void Siox::fillColorRegions() } int right = pos+1; if (x+1 < width && labelField[right]==-1 - && CLAB::diff(image[right], origColor)<1.0) + && CieLab::diff(image[right], origColor)<1.0) { labelField[right]=curLabel; cm[right]=CERTAIN_FOREGROUND_CONFIDENCE; @@ -1407,7 +1504,7 @@ void Siox::fillColorRegions() } int top = pos - width; if (((int)y)-1>=0 && labelField[top]==-1 - && CLAB::diff(image[top], origColor)<1.0) + && CieLab::diff(image[top], origColor)<1.0) { labelField[top]=curLabel; cm[top]=CERTAIN_FOREGROUND_CONFIDENCE; @@ -1416,7 +1513,7 @@ void Siox::fillColorRegions() } int bottom = pos + width; if (y+1 < height && labelField[bottom]==-1 - && CLAB::diff(image[bottom], origColor)<1.0) + && CieLab::diff(image[bottom], origColor)<1.0) { labelField[bottom]=curLabel; cm[bottom]=CERTAIN_FOREGROUND_CONFIDENCE; @@ -1611,20 +1708,6 @@ float Siox::sqrEuclidianDist(float *p, int pSize, float *q) return sum; } -/** - * Squared Euclidian distance of p and q. - */ -float Siox::sqrEuclidianDist(const CLAB &p, const CLAB &q) -{ - float sum=0; - sum += (p.L - q.L) * (p.L - q.L); - sum += (p.A - q.A) * (p.A - q.A); - sum += (p.B - q.B) * (p.B - q.B); - return sum; -} - - - diff --git a/src/trace/siox.h b/src/trace/siox.h index 0dbf76a8e..67c3902e9 100644 --- a/src/trace/siox.h +++ b/src/trace/siox.h @@ -54,15 +54,16 @@ namespace siox /** * */ -class CLAB +class CieLab { public: /** * */ - CLAB() + CieLab() { + init(); C = 0; L = A = B = 0.0f; } @@ -71,14 +72,15 @@ public: /** * */ - CLAB(unsigned long rgb); + CieLab(unsigned long rgb); /** * */ - CLAB(float lArg, float aArg, float bArg) + CieLab(float lArg, float aArg, float bArg) { + init(); C = 0; L = lArg; A = aArg; @@ -89,8 +91,9 @@ public: /** * */ - CLAB(const CLAB &other) + CieLab(const CieLab &other) { + init(); C = other.C; L = other.L; A = other.A; @@ -101,8 +104,9 @@ public: /** * */ - CLAB &operator=(const CLAB &other) + CieLab &operator=(const CieLab &other) { + init(); C = other.C; L = other.L; A = other.A; @@ -113,11 +117,11 @@ public: /** * */ - virtual ~CLAB() + virtual ~CieLab() {} /** - * Retrieve a CLAB value via index. + * Retrieve a CieLab value via index. */ virtual float operator()(unsigned int index) { @@ -131,7 +135,7 @@ public: /** * */ - virtual void add(const CLAB &other) + virtual void add(const CieLab &other) { C += other.C; L += other.L; @@ -157,13 +161,33 @@ public: virtual unsigned long toRGB(); /** - * Computes squared euclidian distance in CLAB space for two colors + * Approximate cube roots + */ + double cbrt(double x); + + /** + * + */ + double qnrt(double x); + + /** + * Raise to the 2.4 power + */ + double pow24(double x); + + /** + * Squared Euclidian distance between this and another color + */ + float diffSq(const CieLab &other); + + /** + * Computes squared euclidian distance in CieLab space for two colors * given as RGB values. */ static float diffSq(unsigned int rgb1, unsigned int rgb2); /** - * Computes squared euclidian distance in CLAB space for two colors + * Computes squared euclidian distance in CieLab space for two colors * given as RGB values. */ static float diff(unsigned int rgb0, unsigned int rgb1); @@ -174,6 +198,13 @@ public: float A; float B; +private: + + /** + * + */ + void init(); + }; @@ -534,7 +565,7 @@ private: * Stage 1 of the color signature work. 'dims' will be either * 2 for grays, or 3 for colors */ - void colorSignatureStage1(CLAB *points, + void colorSignatureStage1(CieLab *points, unsigned int leftBase, unsigned int rightBase, unsigned int recursionDepth, @@ -544,7 +575,7 @@ private: /** * Stage 2 of the color signature work */ - void colorSignatureStage2(CLAB *points, + void colorSignatureStage2(CieLab *points, unsigned int leftBase, unsigned int rightBase, unsigned int recursionDepth, @@ -555,8 +586,8 @@ private: /** * Main color signature method */ - bool colorSignature(const std::vector &inputVec, - std::vector &result, + bool colorSignature(const std::vector &inputVec, + std::vector &result, const unsigned int dims); @@ -610,10 +641,7 @@ private: */ float sqrEuclidianDist(float *p, int pSize, float *q); - /** - * Squared Euclidian distance of p and q. - */ - float sqrEuclidianDist(const CLAB &p, const CLAB &q); + }; diff --git a/src/trace/trace.cpp b/src/trace/trace.cpp index 8e3126501..ae4191a6d 100644 --- a/src/trace/trace.cpp +++ b/src/trace/trace.cpp @@ -46,7 +46,6 @@ namespace Trace - /** * Get the selected image. Also check for any SPItems over it, in * case the user wants SIOX pre-processing. @@ -211,21 +210,27 @@ public: * Process a GdkPixbuf, according to which areas have been * obscured in the GUI. */ -GdkPixbuf * -Tracer::sioxProcessImage(SPImage *img, GdkPixbuf *origPixbuf) +Glib::RefPtr +Tracer::sioxProcessImage(SPImage *img, + Glib::RefPtrorigPixbuf) { if (!sioxEnabled) return origPixbuf; + if (origPixbuf == lastOrigPixbuf) + return lastSioxPixbuf; + + //g_message("siox: start"); + //Convert from gdk, so a format we know. By design, the pixel //format in PackedPixelMap is identical to what is needed by SIOX - SioxImage simage(origPixbuf); + SioxImage simage(origPixbuf->gobj()); SPDesktop *desktop = SP_ACTIVE_DESKTOP; if (!desktop) { g_warning(_("Trace: No active desktop")); - return NULL; + return Glib::RefPtr(NULL); } Inkscape::MessageStack *msgStack = sp_desktop_message_stack(desktop); @@ -236,7 +241,7 @@ Tracer::sioxProcessImage(SPImage *img, GdkPixbuf *origPixbuf) char *msg = _("Select an image to trace"); msgStack->flash(Inkscape::ERROR_MESSAGE, msg); //g_warning(msg); - return NULL; + return Glib::RefPtr(NULL); } NRArenaItem *aImg = sp_item_get_arenaitem(img, desktop->dkey); @@ -257,20 +262,18 @@ Tracer::sioxProcessImage(SPImage *img, GdkPixbuf *origPixbuf) for (iter = sioxShapes.begin() ; iter!=sioxShapes.end() ; iter++) { SPItem *item = *iter; - //### Create ArenaItems and set transform NRArenaItem *aItem = sp_item_get_arenaitem(item, desktop->dkey); - - //nr_arena_item_set_transform(aItem, item->transform); - //g_message("%d %d %d %d\n", aItem->bbox.x0, aItem->bbox.y0, - // aItem->bbox.x1, aItem->bbox.y1); arenaItems.push_back(aItem); } + //g_message("%d arena items\n", arenaItems.size()); //PackedPixelMap *dumpMap = PackedPixelMapCreate( // simage.getWidth(), simage.getHeight()); - for (int row=0 ; rowbbox.y0) + ihscale * (double) row; for (int col=0 ; coltransform; //point *= imgMat; //point = desktop->doc2dt(point); - std::vector::iterator iter; //g_message("x:%f y:%f\n", point[0], point[1]); bool weHaveAHit = false; std::vector::iterator aIter; @@ -314,17 +316,19 @@ Tracer::sioxProcessImage(SPImage *img, GdkPixbuf *origPixbuf) } } + //g_message("siox: selection done"); + //dumpMap->writePPM(dumpMap, "siox1.ppm"); //dumpMap->destroy(dumpMap); //## ok we have our pixel buf - org::siox::Siox sengine; - org::siox::SioxImage result = - sengine.extractForeground(simage, 0xffffff); + TraceSioxObserver observer(this); + Siox sengine(&observer); + SioxImage result = sengine.extractForeground(simage, 0xffffff); if (!result.isValid()) { g_warning(_("Invalid SIOX result")); - return NULL; + return Glib::RefPtr(NULL); } //result.writePPM("siox2.ppm"); @@ -340,7 +344,11 @@ Tracer::sioxProcessImage(SPImage *img, GdkPixbuf *origPixbuf) nr_object_unref((NRObject *) arena); */ - GdkPixbuf *newPixbuf = result.getGdkPixbuf(); + Glib::RefPtr newPixbuf = Glib::wrap(result.getGdkPixbuf()); + + //g_message("siox: done"); + + lastSioxPixbuf = newPixbuf; return newPixbuf; } @@ -349,24 +357,27 @@ Tracer::sioxProcessImage(SPImage *img, GdkPixbuf *origPixbuf) /** * */ -GdkPixbuf * +Glib::RefPtr Tracer::getSelectedImage() { + SPImage *img = getSelectedSPImage(); if (!img) - return NULL; + return Glib::RefPtr(NULL); - GdkPixbuf *pixbuf = img->pixbuf; - if (!pixbuf) - return NULL; + if (!img->pixbuf) + return Glib::RefPtr(NULL); + + Glib::RefPtr pixbuf = + Glib::wrap(img->pixbuf, true); if (sioxEnabled) { - GdkPixbuf *sioxPixbuf = sioxProcessImage(img, pixbuf); + Glib::RefPtr sioxPixbuf = + sioxProcessImage(img, pixbuf); if (!sioxPixbuf) { - g_object_ref(pixbuf); return pixbuf; } else @@ -376,7 +387,6 @@ Tracer::getSelectedImage() } else { - g_object_ref(pixbuf); return pixbuf; } @@ -439,8 +449,7 @@ void Tracer::traceThread() return; } - GdkPixbuf *pixbuf = img->pixbuf; - g_object_ref(pixbuf); + Glib::RefPtr pixbuf = Glib::wrap(img->pixbuf, true); pixbuf = sioxProcessImage(img, pixbuf); @@ -487,8 +496,8 @@ void Tracer::traceThread() NR::Matrix trans(NR::translate(x, y)); - double iwidth = (double)gdk_pixbuf_get_width(pixbuf); - double iheight = (double)gdk_pixbuf_get_height(pixbuf); + double iwidth = (double)pixbuf->get_width(); + double iheight = (double)pixbuf->get_height(); double iwscale = width / iwidth; double ihscale = height / iheight; @@ -543,9 +552,6 @@ void Tracer::traceThread() Inkscape::GC::release(pathRepr); } - //release our pixbuf - g_object_unref(pixbuf); - delete results; // If we have a group, then focus on, then forget it diff --git a/src/trace/trace.h b/src/trace/trace.h index d59ad13a6..5e2c0799d 100644 --- a/src/trace/trace.h +++ b/src/trace/trace.h @@ -24,7 +24,7 @@ # include #endif -#include +#include #include #include @@ -133,7 +133,8 @@ class TracingEngine * compatible with the d="" attribute * of an SVG element. */ - virtual TracingEngineResult *trace(GdkPixbuf *pixbuf, int *nrPaths) + virtual TracingEngineResult *trace(Glib::RefPtr pixbuf, + int *nrPaths) { return NULL; } @@ -189,7 +190,7 @@ public: * A convenience method to allow other software to 'see' the * same image that this class sees. */ - GdkPixbuf *getSelectedImage(); + Glib::RefPtr getSelectedImage(); /** * This is the main working method. Trace the selected image, if @@ -235,7 +236,11 @@ private: bool sioxEnabled; - GdkPixbuf *sioxProcessImage(SPImage *img, GdkPixbuf *origPixbuf); + Glib::RefPtr sioxProcessImage( + SPImage *img, Glib::RefPtr origPixbuf); + + Glib::RefPtr lastSioxPixbuf; + Glib::RefPtr lastOrigPixbuf; };//class Tracer diff --git a/src/ui/dialog/tracedialog.cpp b/src/ui/dialog/tracedialog.cpp index b79d0f0e6..967ed4327 100644 --- a/src/ui/dialog/tracedialog.cpp +++ b/src/ui/dialog/tracedialog.cpp @@ -232,20 +232,19 @@ void TraceDialogImpl::potraceProcess(bool do_i_trace) pte.setMultiScanSmooth(do_i_smooth); //##### Get intermediate bitmap image - GdkPixbuf *pixbuf = tracer.getSelectedImage(); + Glib::RefPtr pixbuf = tracer.getSelectedImage(); if (pixbuf) { - GdkPixbuf *preview = pte.preview(pixbuf); + Glib::RefPtr preview = pte.preview(pixbuf); if (preview) { - Glib::RefPtr thePreview = Glib::wrap(preview); - int width = thePreview->get_width(); - int height = thePreview->get_height(); + int width = preview->get_width(); + int height = preview->get_height(); double scaleFactor = 100.0 / (double)height; int newWidth = (int) (((double)width) * scaleFactor); int newHeight = (int) (((double)height) * scaleFactor); Glib::RefPtr scaledPreview = - thePreview->scale_simple(newWidth, newHeight, + preview->scale_simple(newWidth, newHeight, Gdk::INTERP_NEAREST); //g_object_unref(preview); potracePreviewImage.set(scaledPreview); -- 2.30.2