Code

Add PackedPixelMap to make pixbuf->pixel array conversion much cleaner. Also make...
authorishmal <ishmal@users.sourceforge.net>
Sat, 25 Mar 2006 05:57:21 +0000 (05:57 +0000)
committerishmal <ishmal@users.sourceforge.net>
Sat, 25 Mar 2006 05:57:21 +0000 (05:57 +0000)
src/trace/imagemap-gdk.cpp
src/trace/imagemap-gdk.h
src/trace/imagemap.cpp
src/trace/imagemap.h
src/trace/siox.cpp
src/trace/siox.h
src/trace/trace.cpp

index 93a1d05aa50c1fa90ecef9d5212fe33c1cf6a18e..e217dd6199e14037cd311f093674682e05831906 100644 (file)
@@ -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 ; 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
 #########################################################################*/
index 5eaf78faa2d138cbfd01ddd0362ee87d20272e2d..d04a84d8e3eb0d2520fec70047d724c9bb188078 100644 (file)
@@ -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);
index 1e65ddf5f77d9ea2faa3c7bc90b81d56a63bd8e5..0d4a01d7eeeb3c6a862d1a7b1410722ae7a36647 100644 (file)
@@ -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 ; 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++)
index d69adefd7250220777ca8efd45b80c1312f27c17..7aa7e739d6c253da666065003b2b867f5ce73dce 100644 (file)
@@ -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__ */
 
 /*#########################################################################
index def699003101a9e99bd103b2428895242e09936c..876e8eb7cf48526543b02a03f98c821faabd96c7 100644 (file)
@@ -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++)
index 4d92a9182da276c5519eb521811567fe1928dde2..bb955f28adebbe8d0ed410f4facc52cb130c9dac 100644 (file)
@@ -215,7 +215,7 @@ public:
      * @return <CODE>true</CODE> if the segmentation algorithm succeeded,\r
      *         <CODE>false</CODE> if segmentation is impossible\r
      */\r
-    bool segmentate(long *image, int imageSize,\r
+    bool segmentate(unsigned long *image, int imageSize,\r
                     float *cm, int cmSize,\r
                     int smoothness, double sizeFactorToKeep);\r
 \r
@@ -316,7 +316,7 @@ public:
      * @param cm confidence matrix to be searched\r
      * @param image image to be searched\r
      */\r
-    void fillColorRegions(float *cm, int cmSize, long *image);\r
+    void fillColorRegions(float *cm, int cmSize, unsigned long *image);\r
 \r
 private:\r
 \r
@@ -375,7 +375,7 @@ private:
     /**\r
      * Stores Tupels for fast access to nearest background/foreground pixels.\r
      */\r
-    std::map<long, Tupel> hs;\r
+    std::map<unsigned long, Tupel> hs;\r
 \r
     /** Size of the biggest blob.*/\r
     int regionCount;\r
index b7e83a979012358b1f9a5dac2b595e3ea5e72f26..f28b42d2bb2a8b41ed36433b3a7584112391f85f 100644 (file)
@@ -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;