summaryrefslogtreecommitdiffstats
path: root/src/trace
diff options
context:
space:
mode:
authorBob Jamison <ishmalius@gmail.com>2006-03-25 05:57:21 +0000
committerishmal <ishmal@users.sourceforge.net>2006-03-25 05:57:21 +0000
commit72c233de4b889debcc509186be8114abbb06f6aa (patch)
tree8dd159b66503e9ae24d4bd9665591d5fae6fb9a8 /src/trace
parentinitial hookup of siox into Tracer. much work still to be done, and testing too (diff)
downloadinkscape-72c233de4b889debcc509186be8114abbb06f6aa.tar.gz
inkscape-72c233de4b889debcc509186be8114abbb06f6aa.zip
Add PackedPixelMap to make pixbuf->pixel array conversion much cleaner. Also make certain that packed pixels are unsigned long.
(bzr r294)
Diffstat (limited to 'src/trace')
-rw-r--r--src/trace/imagemap-gdk.cpp81
-rw-r--r--src/trace/imagemap-gdk.h4
-rw-r--r--src/trace/imagemap.cpp125
-rw-r--r--src/trace/imagemap.h94
-rw-r--r--src/trace/siox.cpp48
-rw-r--r--src/trace/siox.h6
-rw-r--r--src/trace/trace.cpp39
7 files changed, 331 insertions, 66 deletions
diff --git a/src/trace/imagemap-gdk.cpp b/src/trace/imagemap-gdk.cpp
index 93a1d05aa..e217dd619 100644
--- a/src/trace/imagemap-gdk.cpp
+++ b/src/trace/imagemap-gdk.cpp
@@ -81,6 +81,87 @@ GdkPixbuf *grayMapToGdkPixbuf(GrayMap *grayMap)
/*#########################################################################
+## P A C K E D P I X E L M A P
+#########################################################################*/
+
+PackedPixelMap *gdkPixbufToPackedPixelMap(GdkPixbuf *buf)
+{
+ if (!buf)
+ return NULL;
+
+ int width = gdk_pixbuf_get_width(buf);
+ int height = gdk_pixbuf_get_height(buf);
+ guchar *pixdata = gdk_pixbuf_get_pixels(buf);
+ int rowstride = gdk_pixbuf_get_rowstride(buf);
+ int n_channels = gdk_pixbuf_get_n_channels(buf);
+
+ PackedPixelMap *ppMap = PackedPixelMapCreate(width, height);
+ if (!ppMap)
+ return NULL;
+
+ //### Fill in the cells with RGB values
+ int x,y;
+ int row = 0;
+ for (y=0 ; y<height ; y++)
+ {
+ guchar *p = pixdata + row;
+ for (x=0 ; x<width ; x++)
+ {
+ int alpha = (int)p[3];
+ int white = 255 - alpha;
+ int r = (int)p[0]; r = r * alpha / 256 + white;
+ int g = (int)p[1]; g = g * alpha / 256 + white;
+ int b = (int)p[2]; b = b * alpha / 256 + white;
+
+ ppMap->setPixel(ppMap, x, y, r, g, b);
+ p += n_channels;
+ }
+ row += rowstride;
+ }
+
+ return ppMap;
+}
+
+GdkPixbuf *packedPixelMapToGdkPixbuf(PackedPixelMap *ppMap)
+{
+ if (!ppMap)
+ return NULL;
+
+ guchar *pixdata = (guchar *)
+ malloc(sizeof(guchar) * ppMap->width * ppMap->height * 3);
+ if (!pixdata)
+ return NULL;
+
+ int n_channels = 3;
+ int rowstride = ppMap->width * 3;
+
+ GdkPixbuf *buf = gdk_pixbuf_new_from_data(pixdata, GDK_COLORSPACE_RGB,
+ 0, 8, ppMap->width, ppMap->height,
+ rowstride, NULL, NULL);
+
+ //### Fill in the cells with RGB values
+ int x,y;
+ int row = 0;
+ for (y=0 ; y<ppMap->height ; y++)
+ {
+ guchar *p = pixdata + row;
+ for (x=0 ; x<ppMap->width ; x++)
+ {
+ unsigned long rgb = ppMap->getPixel(ppMap, x, y);
+ p[0] = (rgb >> 16) & 0xff;
+ p[1] = (rgb >> 8) & 0xff;
+ p[2] = (rgb ) & 0xff;
+ p += n_channels;
+ }
+ row += rowstride;
+ }
+
+ return buf;
+}
+
+
+
+/*#########################################################################
## R G B M A P
#########################################################################*/
diff --git a/src/trace/imagemap-gdk.h b/src/trace/imagemap-gdk.h
index 5eaf78faa..d04a84d8e 100644
--- a/src/trace/imagemap-gdk.h
+++ b/src/trace/imagemap-gdk.h
@@ -27,6 +27,10 @@ GrayMap *gdkPixbufToGrayMap(GdkPixbuf *buf);
GdkPixbuf *grayMapToGdkPixbuf(GrayMap *grayMap);
+PackedPixelMap *gdkPixbufToPackedPixelMap(GdkPixbuf *buf);
+
+GdkPixbuf *packedPixelMapToGdkPixbuf(PackedPixelMap *ppMap);
+
RgbMap *gdkPixbufToRgbMap(GdkPixbuf *buf);
GdkPixbuf *rgbMapToGdkPixbuf(RgbMap *rgbMap);
diff --git a/src/trace/imagemap.cpp b/src/trace/imagemap.cpp
index 1e65ddf5f..0d4a01d7e 100644
--- a/src/trace/imagemap.cpp
+++ b/src/trace/imagemap.cpp
@@ -77,9 +77,9 @@ GrayMap *GrayMapCreate(int width, int height)
/** fields **/
me->width = width;
me->height = height;
- me->pixels = (unsigned long *)
+ me->pixels = (unsigned long *)
malloc(sizeof(unsigned long) * width * height);
- me->rows = (unsigned long **)
+ me->rows = (unsigned long **)
malloc(sizeof(unsigned long *) * height);
if (!me->pixels || !me->rows)
{
@@ -102,6 +102,115 @@ GrayMap *GrayMapCreate(int width, int height)
/*#########################################################################
+### P A C K E D P I X E L M A P
+#########################################################################*/
+
+
+
+static void ppSetPixel(PackedPixelMap *me, int x, int y, int r, int g, int b)
+{
+ unsigned long *pix = me->rows[y] + x;
+ *pix = ((unsigned long)r)<<16 & 0xff0000L |
+ ((unsigned long)g)<< 8 & 0x00ff00L |
+ ((unsigned long)b) & 0x0000ffL;
+}
+
+static void ppSetPixelLong(PackedPixelMap *me, int x, int y, unsigned long rgb)
+{
+ unsigned long *pix = me->rows[y] + x;
+ *pix = rgb;
+}
+
+static unsigned long ppGetPixel(PackedPixelMap *me, int x, int y)
+{
+ unsigned long *pix = me->rows[y] + x;
+ return *pix;
+}
+
+
+
+static int ppWritePPM(PackedPixelMap *me, char *fileName)
+{
+ if (!fileName)
+ return FALSE;
+
+ Inkscape::IO::dump_fopen_call(fileName, "D");
+ FILE *f = Inkscape::IO::fopen_utf8name(fileName, "wb");
+ if (!f)
+ return FALSE;
+
+ fprintf(f, "P6 %d %d 255\n", me->width, me->height);
+
+ for (int y=0 ; y<me->height; y++)
+ {
+ for (int x=0 ; x<me->width ; x++)
+ {
+ unsigned long rgb = me->getPixel(me, x, y);
+ unsigned char r = (unsigned char) ((rgb>>16) & 0xff);
+ unsigned char g = (unsigned char) ((rgb>> 8) & 0xff);
+ unsigned char b = (unsigned char) ((rgb ) & 0xff);
+ fputc(r, f);
+ fputc(g, f);
+ fputc(b, f);
+ }
+ }
+ fclose(f);
+ return TRUE;
+}
+
+
+static void ppDestroy(PackedPixelMap *me)
+{
+ if (me->pixels)
+ free(me->pixels);
+ if (me->rows)
+ free(me->rows);
+ free(me);
+}
+
+
+
+PackedPixelMap *PackedPixelMapCreate(int width, int height)
+{
+
+ PackedPixelMap *me = (PackedPixelMap *)malloc(sizeof(PackedPixelMap));
+ if (!me)
+ return NULL;
+
+ /** methods **/
+ me->setPixel = ppSetPixel;
+ me->setPixelLong = ppSetPixelLong;
+ me->getPixel = ppGetPixel;
+ me->writePPM = ppWritePPM;
+ me->destroy = ppDestroy;
+
+
+ /** fields **/
+ me->width = width;
+ me->height = height;
+ me->pixels = (unsigned long *)
+ malloc(sizeof(unsigned long) * width * height);
+ me->rows = (unsigned long **)
+ malloc(sizeof(unsigned long *) * height);
+ if (!me->pixels)
+ {
+ free(me);
+ return NULL;
+ }
+
+ unsigned long *row = me->pixels;
+ for (int i=0 ; i<height ; i++)
+ {
+ me->rows[i] = row;
+ row += width;
+ }
+
+ return me;
+}
+
+
+
+/*#########################################################################
### R G B M A P
#########################################################################*/
@@ -185,9 +294,9 @@ RgbMap *RgbMapCreate(int width, int height)
/** fields **/
me->width = width;
me->height = height;
- me->pixels = (RGB *)
+ me->pixels = (RGB *)
malloc(sizeof(RGB) * width * height);
- me->rows = (RGB **)
+ me->rows = (RGB **)
malloc(sizeof(RGB *) * height);
if (!me->pixels)
{
@@ -292,9 +401,9 @@ IndexedMap *IndexedMapCreate(int width, int height)
/** fields **/
me->width = width;
me->height = height;
- me->pixels = (unsigned int *)
+ me->pixels = (unsigned int *)
malloc(sizeof(unsigned int) * width * height);
- me->rows = (unsigned int **)
+ me->rows = (unsigned int **)
malloc(sizeof(unsigned int *) * height);
if (!me->pixels)
{
@@ -308,9 +417,9 @@ IndexedMap *IndexedMapCreate(int width, int height)
me->rows[i] = row;
row += width;
}
-
+
me->nrColors = 0;
-
+
RGB rgb;
rgb.r = rgb.g = rgb.b = 0;
for (int i=0; i<256 ; i++)
diff --git a/src/trace/imagemap.h b/src/trace/imagemap.h
index d69adefd7..7aa7e739d 100644
--- a/src/trace/imagemap.h
+++ b/src/trace/imagemap.h
@@ -94,6 +94,96 @@ GrayMap *GrayMapCreate(int width, int height);
/*#########################################################################
+### P A C K E D P I X E L M A P
+#########################################################################*/
+
+
+typedef struct PackedPixelMap_def PackedPixelMap;
+
+/**
+ *
+ */
+struct PackedPixelMap_def
+{
+
+ /*#################
+ ### METHODS
+ #################*/
+
+ /**
+ *
+ */
+ void (*setPixel)(PackedPixelMap *me, int x, int y, int r, int g, int b);
+
+
+ /**
+ *
+ */
+ void (*setPixelLong)(PackedPixelMap *me, int x, int y, unsigned long rgb);
+
+
+ /**
+ *
+ */
+ unsigned long (*getPixel)(PackedPixelMap *me, int x, int y);
+
+
+ /**
+ *
+ */
+ int (*writePPM)(PackedPixelMap *me, char *fileName);
+
+
+
+ /**
+ *
+ */
+ void (*destroy)(PackedPixelMap *me);
+
+
+
+ /*#################
+ ### FIELDS
+ #################*/
+
+ /**
+ *
+ */
+ int width;
+
+ /**
+ *
+ */
+ int height;
+
+ /**
+ * The allocated array of pixels
+ */
+ unsigned long *pixels;
+
+ /**
+ * Pointers to the beginning of each row of pixels
+ */
+ unsigned long **rows;
+
+
+};
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+PackedPixelMap *PackedPixelMapCreate(int width, int height);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+/*#########################################################################
### R G B M A P
#########################################################################*/
@@ -264,7 +354,7 @@ struct IndexedMap_def
*
*/
int nrColors;
-
+
/**
* Color look up table
*/
@@ -285,6 +375,8 @@ IndexedMap *IndexedMapCreate(int width, int height);
#endif
+
+
#endif /* __IMAGEMAP_H__ */
/*#########################################################################
diff --git a/src/trace/siox.cpp b/src/trace/siox.cpp
index def699003..876e8eb7c 100644
--- a/src/trace/siox.cpp
+++ b/src/trace/siox.cpp
@@ -45,17 +45,17 @@ namespace siox
/** Caches color conversion values to speed up RGB->CIELAB conversion.*/
-static std::map<long, CLAB> RGB_TO_LAB;
+static std::map<unsigned long, CLAB> RGB_TO_LAB;
//forward decls
static void premultiplyMatrix(float alpha, float *cm, int cmSize);
-//static float colordiffsq(long rgb0, long rgb1);
-//static int getAlpha(long argb);
-static int getRed(long rgb);
-static int getGreen(long rgb);
-static int getBlue(long rgb);
-//static long packPixel(int a, int r, int g, int b);
-static CLAB rgbToClab(long rgb);
+//static float colordiffsq(unsigned long rgb0, unsigned long rgb1);
+//static int getAlpha(unsigned long argb);
+static int getRed(unsigned long rgb);
+static int getGreen(unsigned long rgb);
+static int getBlue(unsigned long rgb);
+//static unsigned long packPixel(int a, int r, int g, int b);
+static CLAB rgbToClab(unsigned long rgb);
/**
* Applies the morphological dilate operator.
@@ -337,7 +337,7 @@ static long average(long argb0, long argb1)
* @param rgb1 Second color value.
* @return Squared Euclidian distance in CLAB space.
*/
-static float labcolordiffsq(long rgb1, long rgb2)
+static float labcolordiffsq(unsigned long rgb1, unsigned long rgb2)
{
CLAB c1 = rgbToClab(rgb1);
CLAB c2 = rgbToClab(rgb2);
@@ -357,7 +357,7 @@ static float labcolordiffsq(long rgb1, long rgb2)
* @param rgb1 Second color value.
* @return Euclidian distance in CLAB space.
*/
-static float labcolordiff(long rgb0, long rgb1)
+static float labcolordiff(unsigned long rgb0, unsigned long rgb1)
{
return (float)sqrt(labcolordiffsq(rgb0, rgb1));
}
@@ -374,9 +374,9 @@ static float labcolordiff(long rgb0, long rgb1)
* @param rgb RGB color value,
* @return CLAB color value tripel.
*/
-static CLAB rgbToClab(long rgb)
+static CLAB rgbToClab(unsigned long rgb)
{
- std::map<long, CLAB>::iterator iter = RGB_TO_LAB.find(rgb);
+ std::map<unsigned long, CLAB>::iterator iter = RGB_TO_LAB.find(rgb);
if (iter != RGB_TO_LAB.end())
{
CLAB res = iter->second;
@@ -522,7 +522,7 @@ static long clabToRGB(const CLAB &clab)
* @param rgb The 24bit rgb color to be combined with the alpga value.
* @return An ARBG calor value.
*/
-static long setAlpha(int alpha, long rgb)
+static long setAlpha(int alpha, unsigned long rgb)
{
if (alpha>255)
alpha=0;
@@ -539,7 +539,7 @@ static long setAlpha(int alpha, long rgb)
* @param rgb The 24bit rgb color to be combined with the alpga value.
* @return An ARBG calor value.
*/
-static long setAlpha(float alpha, long rgb)
+static long setAlpha(float alpha, unsigned long rgb)
{
return setAlpha((int)(255.0f*alpha), rgb);
}
@@ -588,7 +588,7 @@ static long packPixel(int a, int r, int g, int b)
* @return The alpha component, ranging from 0 to 255.
*/
/*
-static int getAlpha(long argb)
+static int getAlpha(unsigned long argb)
{
return (argb>>24)&0xFF;
}
@@ -600,7 +600,7 @@ static int getAlpha(long argb)
* @param rgb An (A)RGB color value.
* @return The red component, ranging from 0 to 255.
*/
-static int getRed(long rgb)
+static int getRed(unsigned long rgb)
{
return (rgb>>16)&0xFF;
}
@@ -612,7 +612,7 @@ static int getRed(long rgb)
* @param rgb An (A)RGB color value.
* @return The green component, ranging from 0 to 255.
*/
-static int getGreen(long rgb)
+static int getGreen(unsigned long rgb)
{
return (rgb>>8)&0xFF;
}
@@ -623,7 +623,7 @@ static int getGreen(long rgb)
* @param rgb An (A)RGB color value.
* @return The blue component, ranging from 0 to 255.
*/
-static int getBlue(long rgb)
+static int getBlue(unsigned long rgb)
{
return (rgb)&0xFF;
}
@@ -994,7 +994,7 @@ void SioxSegmentator::trace(char *fmt, ...)
-bool SioxSegmentator::segmentate(long *image, int imageSize,
+bool SioxSegmentator::segmentate(unsigned long *image, int imageSize,
float *cm, int cmSize,
int smoothness, double sizeFactorToKeep)
{
@@ -1032,7 +1032,7 @@ bool SioxSegmentator::segmentate(long *image, int imageSize,
}
if (cm[i]>BACKGROUND_CONFIDENCE) {
bool isBackground=true;
- std::map<long, Tupel>::iterator iter = hs.find(i);
+ std::map<unsigned long, Tupel>::iterator iter = hs.find(i);
Tupel tupel(0.0f, 0, 0.0f, 0);
if (iter == hs.end()) {
CLAB lab = rgbToClab(image[i]);
@@ -1230,11 +1230,11 @@ bool SioxSegmentator::subpixelRefine(int xa, int ya, int dx, int dy,
continue;
}
*/
- long val=origImage[ey*imgWidth+ex];
- long orig=val;
+ unsigned long val=origImage[ey*imgWidth+ex];
+ unsigned long orig=val;
float minDistBg = 0.0f;
float minDistFg = 0.0f;
- std::map<long, Tupel>::iterator iter = hs.find(val);
+ std::map<unsigned long, Tupel>::iterator iter = hs.find(val);
if (iter != hs.end()) {
minDistBg=(float) sqrt((float)iter->second.minBgDist);
minDistFg=(float) sqrt((float)iter->second.minFgDist);
@@ -1286,7 +1286,7 @@ bool SioxSegmentator::subpixelRefine(int xa, int ya, int dx, int dy,
-void SioxSegmentator::fillColorRegions(float *cm, int cmSize, long *image)
+void SioxSegmentator::fillColorRegions(float *cm, int cmSize, unsigned long *image)
{
int idx = 0;
for (int i=0 ; i<imgHeight ; i++)
diff --git a/src/trace/siox.h b/src/trace/siox.h
index 4d92a9182..bb955f28a 100644
--- a/src/trace/siox.h
+++ b/src/trace/siox.h
@@ -215,7 +215,7 @@ public:
* @return <CODE>true</CODE> if the segmentation algorithm succeeded,
* <CODE>false</CODE> if segmentation is impossible
*/
- bool segmentate(long *image, int imageSize,
+ bool segmentate(unsigned long *image, int imageSize,
float *cm, int cmSize,
int smoothness, double sizeFactorToKeep);
@@ -316,7 +316,7 @@ public:
* @param cm confidence matrix to be searched
* @param image image to be searched
*/
- void fillColorRegions(float *cm, int cmSize, long *image);
+ void fillColorRegions(float *cm, int cmSize, unsigned long *image);
private:
@@ -375,7 +375,7 @@ private:
/**
* Stores Tupels for fast access to nearest background/foreground pixels.
*/
- std::map<long, Tupel> hs;
+ std::map<unsigned long, Tupel> hs;
/** Size of the biggest blob.*/
int regionCount;
diff --git a/src/trace/trace.cpp b/src/trace/trace.cpp
index b7e83a979..f28b42d2b 100644
--- a/src/trace/trace.cpp
+++ b/src/trace/trace.cpp
@@ -151,45 +151,24 @@ GdkPixbuf *
Tracer::sioxProcessImage(SPImage *img, GdkPixbuf *origPixbuf)
{
- RgbMap *rgbMap = gdkPixbufToRgbMap(origPixbuf);
+ PackedPixelMap *ppMap = gdkPixbufToPackedPixelMap(origPixbuf);
//We need to create two things:
// 1. An array of long pixel values of ARGB
// 2. A matching array of per-pixel float 'confidence' values
- long *imgBuf = new long[rgbMap->width * rgbMap->height];
- float *confidenceMatrix = new float[rgbMap->width * rgbMap->height];
+ unsigned long *imgBuf = ppMap->pixels;
+ float *confidenceMatrix = new float[ppMap->width * ppMap->height];
- long idx = 0;
- for (int j=0 ; j<rgbMap->height ; j++)
- for (int i=0 ; i<rgbMap->width ; i++)
- {
- RGB rgb = rgbMap->getPixel(rgbMap, i, j);
- long pix = (((long)rgb.r) << 16 & 0xFF0000L) |
- (((long)rgb.g) << 8 & 0x00FF00L) |
- (((long)rgb.b) & 0x0000FFL);
- imgBuf[idx++] = pix;
- }
//## ok we have our pixel buf
- org::siox::SioxSegmentator ss(rgbMap->width, rgbMap->height, NULL, 0);
- ss.segmentate(imgBuf, rgbMap->width * rgbMap->height,
- confidenceMatrix, rgbMap->width * rgbMap->height,
+ org::siox::SioxSegmentator ss(ppMap->width, ppMap->height, NULL, 0);
+ ss.segmentate(imgBuf, ppMap->width * ppMap->height,
+ confidenceMatrix, ppMap->width * ppMap->height,
0, 0.0);
- idx = 0;
- for (int j=0 ; j<rgbMap->height ; j++)
- for (int i=0 ; i<rgbMap->width ; i++)
- {
- long pix = imgBuf[idx++];
- RGB rgb;
- rgb.r = (pix>>16) & 0xff;
- rgb.g = (pix>> 8) & 0xff;
- rgb.b = (pix ) & 0xff;
- rgbMap->setPixelRGB(rgbMap, i, j, rgb);
- }
- GdkPixbuf *newPixbuf = rgbMapToGdkPixbuf(rgbMap);
- rgbMap->destroy(rgbMap);
- delete imgBuf;
+
+ GdkPixbuf *newPixbuf = packedPixelMapToGdkPixbuf(ppMap);
+ ppMap->destroy(ppMap);
delete confidenceMatrix;
return newPixbuf;