pre-calc the sum of a picture added to an RrImage rather than calculating it every...
authorDana Jansens <danakj@orodu.net>
Wed, 13 Feb 2008 14:14:58 +0000 (09:14 -0500)
committerMikael Magnusson <mikachu@comhem.se>
Thu, 14 Feb 2008 10:44:51 +0000 (11:44 +0100)
render/image.c
render/image.h
render/imagecache.c
render/render.h

index a618f78..a374ceb 100644 (file)
 #define FLOOR(i)        ((i) & (~0UL << FRACTION))
 #define AVERAGE(a, b)   (((((a) ^ (b)) & 0xfefefefeL) >> 1) + ((a) & (b)))
 
+void RrImagePicInit(RrImagePic *pic, gint w, gint h, RrPixel32 *data)
+{
+    gint i;
+
+    pic->width = w;
+    pic->height = h;
+    pic->data = data;
+    pic->sum = 0;
+    for (i = w*h; i > 0; --i)
+        pic->sum += *(data++);
+}
+
 /*! Add a picture to an Image, that is, add another copy of the image at
   another size.  This may add it to the "originals" list or to the
   "resized" list. */
@@ -98,7 +110,7 @@ static RrImagePic* ResizeImage(RrPixel32 *src,
                                gulong srcW, gulong srcH,
                                gulong dstW, gulong dstH)
 {
-    RrPixel32 *dst;
+    RrPixel32 *dst, *dststart;
     RrImagePic *pic;
     gulong dstX, dstY, srcX, srcY;
     gulong srcX1, srcX2, srcY1, srcY2;
@@ -118,11 +130,7 @@ static RrImagePic* ResizeImage(RrPixel32 *src,
     if (srcW == dstW && srcH == dstH)
         return NULL; /* no scaling needed ! */
 
-    pic = g_new(RrImagePic, 1);
-    dst = g_new(RrPixel32, dstW * dstH);
-    pic->width = dstW;
-    pic->height = dstH;
-    pic->data = dst;
+    dststart = dst = g_new(RrPixel32, dstW * dstH);
 
     ratioX = (srcW << FRACTION) / dstW;
     ratioY = (srcH << FRACTION) / dstH;
@@ -194,6 +202,9 @@ static RrImagePic* ResizeImage(RrPixel32 *src,
         }
     }
 
+    pic = g_new(RrImagePic, 1);
+    RrImagePicInit(pic, dstW, dstH, dststart);
+
     return pic;
 }
 
@@ -343,9 +354,7 @@ void RrImageAddPicture(RrImage *self, RrPixel32 *data, gint w, gint h)
 
     /* add the new picture */
     pic = g_new(RrImagePic, 1);
-    pic->width = w;
-    pic->height = h;
-    pic->data = g_memdup(data, w*h*sizeof(RrPixel32));
+    RrImagePicInit(pic, w, h, g_memdup(data, w*h*sizeof(RrPixel32)));
     AddPicture(self, &self->original, &self->n_original, pic);
 }
 
index 28f29c2..b478daf 100644 (file)
@@ -22,6 +22,9 @@
 #include "render.h"
 #include "geom.h"
 
+/*! Initialize an RrImagePicture to the specified dimensions and pixel data */
+void RrImagePicInit(RrImagePic *pic, gint w, gint h, RrPixel32 *data);
+
 void RrImageDrawImage(RrPixel32 *target, RrTextureImage *img,
                       gint target_w, gint target_h,
                       RrRect *area);
index 9ebaec1..9c605f9 100644 (file)
@@ -18,6 +18,7 @@
 
 #include "render.h"
 #include "imagecache.h"
+#include "image.h"
 
 static gboolean RrImagePicEqual(const RrImagePic *p1,
                                 const RrImagePic *p2);
@@ -56,9 +57,8 @@ RrImage* RrImageCacheFind(RrImageCache *self,
                           RrPixel32 *data, gint w, gint h)
 {
     RrImagePic pic;
-    pic.width = w;
-    pic.height = h;
-    pic.data = data;
+
+    RrImagePicInit(&pic, w, h, data);
     return g_hash_table_lookup(self->table, &pic);
 }
 
@@ -139,21 +139,6 @@ guint RrImagePicHash(const RrImagePic *p)
 static gboolean RrImagePicEqual(const RrImagePic *p1,
                                 const RrImagePic *p2)
 {
-    guint s1, s2;
-    RrPixel32 *data1, *data2;
-    gint i;
-
-    if (p1->width != p2->width || p1->height != p2->height) return FALSE;
-
-    /* strcmp() would probably suck on 4k of data.. sum all their values and
-       see if they get the same thing.  they already matched on their hashes
-       at this point. */
-    s1 = s2 = 0;
-    data1 = p1->data;
-    data2 = p2->data;
-    for (i = 0; i < p1->width * p1->height; ++i, ++data1)
-        s1 += *data1;
-    for (i = 0; i < p2->width * p2->height; ++i, ++data2)
-        s2 += *data2;
-    return s1 == s2;
+    return p1->width == p2->width && p1->height == p2->height &&
+        p1->sum == p2->sum;
 }
index 5f14508..6905059 100644 (file)
@@ -227,6 +227,9 @@ struct _RrAppearance {
 struct _RrImagePic {
     gint width, height;
     RrPixel32 *data;
+    /* The sum of all the pixels.  This is used to compare pictures if their
+       hashes match. */
+    gint sum;
 };
 
 /*! An RrImage is a sort of meta-image.  It can contain multiple versions of