From: ishmal Date: Sat, 25 Mar 2006 05:57:21 +0000 (+0000) Subject: Add PackedPixelMap to make pixbuf->pixel array conversion much cleaner. Also make... X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=41629a744eebd14552631d1a23cfbe9e6a4cf358;p=inkscape.git Add PackedPixelMap to make pixbuf->pixel array conversion much cleaner. Also make certain that packed pixels are unsigned long. --- 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 @@ -80,6 +80,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 ; ysetPixel(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 ; yheight ; y++) + { + guchar *p = pixdata + row; + for (x=0 ; xwidth ; 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) { @@ -101,6 +101,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 ; yheight; y++) + { + for (int x=0 ; xwidth ; 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 ; irows[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 @@ -93,6 +93,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 RGB_TO_LAB; +static std::map 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::iterator iter = RGB_TO_LAB.find(rgb); + std::map::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::iterator iter = hs.find(i); + std::map::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::iterator iter = hs.find(val); + std::map::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 ; itrue if the segmentation algorithm succeeded, * false 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 hs; + std::map 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 ; jheight ; j++) - for (int i=0 ; iwidth ; 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 ; jheight ; j++) - for (int i=0 ; iwidth ; 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;