summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 4cd7c53)
raw | patch | inline | side by side (parent: 4cd7c53)
author | acspike <acspike@users.sourceforge.net> | |
Tue, 13 Jun 2006 01:43:48 +0000 (01:43 +0000) | ||
committer | acspike <acspike@users.sourceforge.net> | |
Tue, 13 Jun 2006 01:43:48 +0000 (01:43 +0000) |
index 12ffc551a862c2da0cee7edb673eccf3877eba6b..e18abb3381b3c67dad482890d827eb80a9c33172 100644 (file)
*
*/
+#include "inkscape-potrace.h"
+
#include <glibmm/i18n.h>
-#include <gtkmm/main.h>
+#include <gtkmm.h>
#include "trace/filterset.h"
#include "trace/imagemap-gdk.h"
#include "curve.h"
#include "bitmap.h"
-#include "inkscape-potrace.h"
static void updateGui()
-GdkPixbuf *
-PotraceTracingEngine::preview(GdkPixbuf * pixbuf)
+Glib::RefPtr<Gdk::Pixbuf>
+PotraceTracingEngine::preview(Glib::RefPtr<Gdk::Pixbuf> 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<Gdk::Pixbuf>(NULL);
- GdkPixbuf *newBuf = indexedMapToGdkPixbuf(gm);
+ Glib::RefPtr<Gdk::Pixbuf> newBuf =
+ Glib::wrap(indexedMapToGdkPixbuf(gm), false);
gm->destroy(gm);
{
GrayMap *gm = filter(*this, pixbuf);
if (!gm)
- return NULL;
+ return Glib::RefPtr<Gdk::Pixbuf>(NULL);
- GdkPixbuf *newBuf = grayMapToGdkPixbuf(gm);
+ Glib::RefPtr<Gdk::Pixbuf> newBuf =
+ Glib::wrap(grayMapToGdkPixbuf(gm), false);
gm->destroy(gm);
* of an SVG <path> element.
*/
TracingEngineResult *
-PotraceTracingEngine::trace(GdkPixbuf * thePixbuf, int *nrPaths)
+PotraceTracingEngine::trace(Glib::RefPtr<Gdk::Pixbuf> pixbuf,
+ int *nrPaths)
{
+ GdkPixbuf *thePixbuf = pixbuf->gobj();
+
//Set up for messages
keepGoing = 1;
index 7a8d97b2e2d19af851664edd0483aaa56a76bd1f..0f257cb95833903b2b50d6ee000658ce5f4a1715 100644 (file)
#ifndef __INKSCAPE_POTRACE_H__
#define __INKSCAPE_POTRACE_H__
-#include <glib.h>
+#include <gtkmm.h>
#include <trace/trace.h>
#include <trace/imagemap.h>
* return the path data that is compatible with the d="" attribute
* of an SVG <path> element.
*/
- virtual TracingEngineResult *trace(GdkPixbuf *pixbuf, int *nrPaths);
+ virtual TracingEngineResult *trace(Glib::RefPtr<Gdk::Pixbuf> pixbuf,
+ int *nrPaths);
/**
* Abort the thread that is executing getPathDataFromPixbuf()
/**
*
*/
- GdkPixbuf *preview(GdkPixbuf * pixbuf);
+ Glib::RefPtr<Gdk::Pixbuf> preview(Glib::RefPtr<Gdk::Pixbuf> pixbuf);
/**
*
diff --git a/src/trace/siox.cpp b/src/trace/siox.cpp
index b0632567cfc65c4aaecdff4f8d2d31deee9a9e55..9c5db4731eef30b81b1a2e73d42b045b29f2583c 100644 (file)
--- a/src/trace/siox.cpp
+++ b/src/trace/siox.cpp
//# C L A B
//########################################################################
-static std::map<unsigned long, CLAB> clabLookupTable;
+static std::map<unsigned long, CieLab> clabLookupTable;
/**
* Convert integer A, R, G, B values into an pixel value.
+//#########################################
+//# 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<unsigned long, CLAB>::iterator iter;
+ std::map<unsigned long, CieLab>::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;
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;
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);
/**
- * 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;
/**
- * 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
//########################################################################
SioxImage Siox::extractForeground(const SioxImage &originalImage,
unsigned int backgroundFillColor)
{
+ trace("### Start");
+
init();
keepGoing = true;
trace("### Creating signatures");
//#### create color signatures
- std::vector<CLAB> knownBg;
- std::vector<CLAB> knownFg;
- std::vector<CLAB> imageClab;
+ std::vector<CieLab> knownBg;
+ std::vector<CieLab> knownFg;
+ CieLab *imageClab = new CieLab[pixelCount];
+ for (unsigned long i=0 ; i<pixelCount ; i++)
+ {
+ float conf = cm[i];
+ unsigned int pix = image[i];
+ CieLab lab(pix);
+ imageClab[i] = lab;
+ if (conf <= BACKGROUND_CONFIDENCE)
+ knownBg.push_back(lab);
+ else if (conf >= FOREGROUND_CONFIDENCE)
+ knownFg.push_back(lab);
+ }
+
+ /*
+ std::vector<CieLab> 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;
}
trace("knownBg:%d knownFg:%d", knownBg.size(), knownFg.size());
- std::vector<CLAB> bgSignature ;
+ std::vector<CieLab> bgSignature ;
if (!colorSignature(knownBg, bgSignature, 3))
{
error("Could not create background signature");
workImage.setValid(false);
+ delete[] imageClab;
delete[] labelField;
return workImage;
}
{
error("User aborted");
workImage.setValid(false);
+ delete[] imageClab;
delete[] labelField;
return workImage;
}
- std::vector<CLAB> fgSignature ;
+ std::vector<CieLab> fgSignature ;
if (!colorSignature(knownFg, fgSignature, 3))
{
error("Could not create foreground signature");
workImage.setValid(false);
+ delete[] imageClab;
delete[] labelField;
return workImage;
}
// segmentation impossible
error("Signature size is < 1. Segmentation is impossible");
workImage.setValid(false);
+ delete[] imageClab;
delete[] labelField;
return workImage;
}
{
error("User aborted");
workImage.setValid(false);
+ delete[] imageClab;
delete[] labelField;
return workImage;
}
// classify using color signatures,
// classification cached in hashmap for drb and speedup purposes
+ trace("### Analyzing image");
+
std::map<unsigned int, Tupel> hs;
unsigned int progressResolution = pixelCount / 10;
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;
std::map<unsigned int, Tupel>::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<bgSignature.size() ; j++)
{
- float d = sqrEuclidianDist(lab, bgSignature[j]);
+ float d = lab.diffSq(bgSignature[j]);
if (d<minBg)
{
minBg = d;
Tupel tupel(0.0f, 0, 0.0f, 0);
tupel.minBgDist = minBg;
tupel.indexMinBg = minIndex;
- float minFg = 1.0e6f;
- minIndex = -1;
+ float minFg = 1.0e6f;
+ minIndex = -1;
for (unsigned int j = 0 ; j < fgSignature.size() ; j++)
{
- float d = sqrEuclidianDist(lab, fgSignature[j]);
+ float d = lab.diffSq(fgSignature[j]);
if (d < minFg)
{
minFg = d;
tupel.indexMinFg = minIndex;
if (fgSignature.size() == 0)
{
- isBackground=(minBg <= clusterSize);
+ isBackground = (minBg <= clusterSize);
// remove next line to force behaviour of old algorithm
//error("foreground signature does not exist");
//delete[] labelField;
}
+ delete[] imageClab;
trace("### postProcessing");
- //## postprocessing
- smooth(cm, width, height, 0.33f, 0.33f, 0.33f); // average
+ //#### postprocessing
+ smooth(cm, width, height, 0.333f, 0.333f, 0.333f); // average
normalizeMatrix(cm, pixelCount);
erode(cm, width, height);
keepOnlyLargeComponents(UNKNOWN_REGION_CONFIDENCE, 1.0/*sizeFactorToKeep*/);
- for (int i=0; i < 2/*smoothness*/; i++)
- smooth(cm, width, height, 0.33f, 0.33f, 0.33f); // average
+ //for (int i=0; i < 2/*smoothness*/; i++)
+ // smooth(cm, width, height, 0.333f, 0.333f, 0.333f); // average
normalizeMatrix(cm, pixelCount);
}
- //#### Yaay. We are done. Now clear everything but the background
- for (unsigned int y = 0 ; y < height ; y++)
- for (unsigned int x = 0 ; x < width ; x++)
- {
- float conf = workImage.getConfidence(x, y);
- if (conf < FOREGROUND_CONFIDENCE)
- {
- workImage.setPixel(x, y, backgroundFillColor);
- }
- }
+ //#### We are done. Now clear everything but the background
+ for (unsigned long i = 0; i<pixelCount ; i++)
+ {
+ float conf = cm[i];
+ if (conf < FOREGROUND_CONFIDENCE)
+ image[i] = backgroundFillColor;
+ }
delete[] labelField;
* Stage 1 of the color signature work. 'dims' will be either
* 2 for grays, or 3 for colors
*/
-void Siox::colorSignatureStage1(CLAB *points,
+void Siox::colorSignatureStage1(CieLab *points,
unsigned int leftBase,
unsigned int rightBase,
unsigned int recursionDepth,
{
unsigned int currentDim = recursionDepth % dims;
- CLAB point = points[leftBase];
+ CieLab point = points[leftBase];
float min = point(currentDim);
float max = min;
else
{
//create a leaf
- CLAB newpoint;
+ CieLab newpoint;
newpoint.C = rightBase - leftBase;
/**
* Stage 2 of the color signature work
*/
-void Siox::colorSignatureStage2(CLAB *points,
+void Siox::colorSignatureStage2(CieLab *points,
unsigned int leftBase,
unsigned int rightBase,
unsigned int recursionDepth,
unsigned int currentDim = recursionDepth % dims;
- CLAB point = points[leftBase];
+ CieLab point = points[leftBase];
float min = point(currentDim);
float max = min;
if ((float)sum >= threshold)
{
float scale = (float)(rightBase - leftBase);
- CLAB newpoint;
+ CieLab newpoint;
for (; leftBase < rightBase; leftBase++)
newpoint.add(points[leftBase]);
/**
* Main color signature method
*/
-bool Siox::colorSignature(const std::vector<CLAB> &inputVec,
- std::vector<CLAB> &result,
+bool Siox::colorSignature(const std::vector<CieLab> &inputVec,
+ std::vector<CieLab> &result,
const unsigned int dims)
{
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)
{
// 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;
}
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;
}
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;
}
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;
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 0dbf76a8e0e187b8ea28bc0c5e49b70535519595..67c3902e955b259703a35373a47c4deb53559118 100644 (file)
--- a/src/trace/siox.h
+++ b/src/trace/siox.h
/**
*
*/
-class CLAB
+class CieLab
{
public:
/**
*
*/
- CLAB()
+ CieLab()
{
+ init();
C = 0;
L = A = B = 0.0f;
}
/**
*
*/
- 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;
/**
*
*/
- CLAB(const CLAB &other)
+ CieLab(const CieLab &other)
{
+ init();
C = other.C;
L = other.L;
A = other.A;
/**
*
*/
- CLAB &operator=(const CLAB &other)
+ CieLab &operator=(const CieLab &other)
{
+ init();
C = other.C;
L = other.L;
A = other.A;
/**
*
*/
- virtual ~CLAB()
+ virtual ~CieLab()
{}
/**
- * Retrieve a CLAB value via index.
+ * Retrieve a CieLab value via index.
*/
virtual float operator()(unsigned int index)
{
/**
*
*/
- virtual void add(const CLAB &other)
+ virtual void add(const CieLab &other)
{
C += other.C;
L += other.L;
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);
float A;
float B;
+private:
+
+ /**
+ *
+ */
+ void init();
+
};
* 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,
/**
* Stage 2 of the color signature work
*/
- void colorSignatureStage2(CLAB *points,
+ void colorSignatureStage2(CieLab *points,
unsigned int leftBase,
unsigned int rightBase,
unsigned int recursionDepth,
/**
* Main color signature method
*/
- bool colorSignature(const std::vector<CLAB> &inputVec,
- std::vector<CLAB> &result,
+ bool colorSignature(const std::vector<CieLab> &inputVec,
+ std::vector<CieLab> &result,
const unsigned int dims);
*/
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 8e31265013f011b2b4f7634b3cb614d01df673e8..ae4191a6d5bcd3056182c0df35877e366fab9b1b 100644 (file)
--- a/src/trace/trace.cpp
+++ b/src/trace/trace.cpp
-
/**
* Get the selected image. Also check for any SPItems over it, in
* case the user wants SIOX pre-processing.
* Process a GdkPixbuf, according to which areas have been
* obscured in the GUI.
*/
-GdkPixbuf *
-Tracer::sioxProcessImage(SPImage *img, GdkPixbuf *origPixbuf)
+Glib::RefPtr<Gdk::Pixbuf>
+Tracer::sioxProcessImage(SPImage *img,
+ Glib::RefPtr<Gdk::Pixbuf>origPixbuf)
{
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<Gdk::Pixbuf>(NULL);
}
Inkscape::MessageStack *msgStack = sp_desktop_message_stack(desktop);
char *msg = _("Select an <b>image</b> to trace");
msgStack->flash(Inkscape::ERROR_MESSAGE, msg);
//g_warning(msg);
- return NULL;
+ return Glib::RefPtr<Gdk::Pixbuf>(NULL);
}
NRArenaItem *aImg = sp_item_get_arenaitem(img, desktop->dkey);
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 ; row<simage.getHeight() ; row++)
+ //g_message("siox: start selection");
+
+ for (int row=0 ; row<iheight ; row++)
{
double ypos = ((double)aImg->bbox.y0) + ihscale * (double) row;
for (int col=0 ; col<simage.getWidth() ; col++)
point *= aImg->transform;
//point *= imgMat;
//point = desktop->doc2dt(point);
- std::vector<SPShape *>::iterator iter;
//g_message("x:%f y:%f\n", point[0], point[1]);
bool weHaveAHit = false;
std::vector<NRArenaItem *>::iterator aIter;
}
}
+ //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<Gdk::Pixbuf>(NULL);
}
//result.writePPM("siox2.ppm");
nr_object_unref((NRObject *) arena);
*/
- GdkPixbuf *newPixbuf = result.getGdkPixbuf();
+ Glib::RefPtr<Gdk::Pixbuf> newPixbuf = Glib::wrap(result.getGdkPixbuf());
+
+ //g_message("siox: done");
+
+ lastSioxPixbuf = newPixbuf;
return newPixbuf;
}
/**
*
*/
-GdkPixbuf *
+Glib::RefPtr<Gdk::Pixbuf>
Tracer::getSelectedImage()
{
+
SPImage *img = getSelectedSPImage();
if (!img)
- return NULL;
+ return Glib::RefPtr<Gdk::Pixbuf>(NULL);
- GdkPixbuf *pixbuf = img->pixbuf;
- if (!pixbuf)
- return NULL;
+ if (!img->pixbuf)
+ return Glib::RefPtr<Gdk::Pixbuf>(NULL);
+
+ Glib::RefPtr<Gdk::Pixbuf> pixbuf =
+ Glib::wrap(img->pixbuf, true);
if (sioxEnabled)
{
- GdkPixbuf *sioxPixbuf = sioxProcessImage(img, pixbuf);
+ Glib::RefPtr<Gdk::Pixbuf> sioxPixbuf =
+ sioxProcessImage(img, pixbuf);
if (!sioxPixbuf)
{
- g_object_ref(pixbuf);
return pixbuf;
}
else
}
else
{
- g_object_ref(pixbuf);
return pixbuf;
}
return;
}
- GdkPixbuf *pixbuf = img->pixbuf;
- g_object_ref(pixbuf);
+ Glib::RefPtr<Gdk::Pixbuf> pixbuf = Glib::wrap(img->pixbuf, true);
pixbuf = sioxProcessImage(img, pixbuf);
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;
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 d59ad13a6dbad982402c847ecde79832dd583d99..5e2c0799d7197cd7a9d1ff352b9340d13125a3a4 100644 (file)
--- a/src/trace/trace.h
+++ b/src/trace/trace.h
# include <string.h>
#endif
-#include <gdk/gdkpixbuf.h>
+#include <gtkmm.h>
#include <vector>
#include <sp-shape.h>
* compatible with the d="" attribute
* of an SVG <path> element.
*/
- virtual TracingEngineResult *trace(GdkPixbuf *pixbuf, int *nrPaths)
+ virtual TracingEngineResult *trace(Glib::RefPtr<Gdk::Pixbuf> pixbuf,
+ int *nrPaths)
{ return NULL; }
* A convenience method to allow other software to 'see' the
* same image that this class sees.
*/
- GdkPixbuf *getSelectedImage();
+ Glib::RefPtr<Gdk::Pixbuf> getSelectedImage();
/**
* This is the main working method. Trace the selected image, if
bool sioxEnabled;
- GdkPixbuf *sioxProcessImage(SPImage *img, GdkPixbuf *origPixbuf);
+ Glib::RefPtr<Gdk::Pixbuf> sioxProcessImage(
+ SPImage *img, Glib::RefPtr<Gdk::Pixbuf> origPixbuf);
+
+ Glib::RefPtr<Gdk::Pixbuf> lastSioxPixbuf;
+ Glib::RefPtr<Gdk::Pixbuf> lastOrigPixbuf;
};//class Tracer
index b79d0f0e6241625578572902fd555e0567f5e211..967ed43275e4e05526131b2afea1e27f42b36e6e 100644 (file)
pte.setMultiScanSmooth(do_i_smooth);
//##### Get intermediate bitmap image
- GdkPixbuf *pixbuf = tracer.getSelectedImage();
+ Glib::RefPtr<Gdk::Pixbuf> pixbuf = tracer.getSelectedImage();
if (pixbuf)
{
- GdkPixbuf *preview = pte.preview(pixbuf);
+ Glib::RefPtr<Gdk::Pixbuf> preview = pte.preview(pixbuf);
if (preview)
{
- Glib::RefPtr<Gdk::Pixbuf> 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<Gdk::Pixbuf> scaledPreview =
- thePreview->scale_simple(newWidth, newHeight,
+ preview->scale_simple(newWidth, newHeight,
Gdk::INTERP_NEAREST);
//g_object_unref(preview);
potracePreviewImage.set(scaledPreview);