pre-calc the sum of a picture added to an RrImage rather than calculating it every time

This commit is contained in:
Dana Jansens 2008-02-13 09:14:58 -05:00
parent a2e3026d8a
commit 38c96413b3
4 changed files with 29 additions and 29 deletions

View file

@ -28,6 +28,18 @@
#define FLOOR(i) ((i) & (~0UL << FRACTION)) #define FLOOR(i) ((i) & (~0UL << FRACTION))
#define AVERAGE(a, b) (((((a) ^ (b)) & 0xfefefefeL) >> 1) + ((a) & (b))) #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 /*! 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 another size. This may add it to the "originals" list or to the
"resized" list. */ "resized" list. */
@ -98,7 +110,7 @@ static RrImagePic* ResizeImage(RrPixel32 *src,
gulong srcW, gulong srcH, gulong srcW, gulong srcH,
gulong dstW, gulong dstH) gulong dstW, gulong dstH)
{ {
RrPixel32 *dst; RrPixel32 *dst, *dststart;
RrImagePic *pic; RrImagePic *pic;
gulong dstX, dstY, srcX, srcY; gulong dstX, dstY, srcX, srcY;
gulong srcX1, srcX2, srcY1, srcY2; gulong srcX1, srcX2, srcY1, srcY2;
@ -118,11 +130,7 @@ static RrImagePic* ResizeImage(RrPixel32 *src,
if (srcW == dstW && srcH == dstH) if (srcW == dstW && srcH == dstH)
return NULL; /* no scaling needed ! */ return NULL; /* no scaling needed ! */
pic = g_new(RrImagePic, 1); dststart = dst = g_new(RrPixel32, dstW * dstH);
dst = g_new(RrPixel32, dstW * dstH);
pic->width = dstW;
pic->height = dstH;
pic->data = dst;
ratioX = (srcW << FRACTION) / dstW; ratioX = (srcW << FRACTION) / dstW;
ratioY = (srcH << FRACTION) / dstH; 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; return pic;
} }
@ -343,9 +354,7 @@ void RrImageAddPicture(RrImage *self, RrPixel32 *data, gint w, gint h)
/* add the new picture */ /* add the new picture */
pic = g_new(RrImagePic, 1); pic = g_new(RrImagePic, 1);
pic->width = w; RrImagePicInit(pic, w, h, g_memdup(data, w*h*sizeof(RrPixel32)));
pic->height = h;
pic->data = g_memdup(data, w*h*sizeof(RrPixel32));
AddPicture(self, &self->original, &self->n_original, pic); AddPicture(self, &self->original, &self->n_original, pic);
} }

View file

@ -22,6 +22,9 @@
#include "render.h" #include "render.h"
#include "geom.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, void RrImageDrawImage(RrPixel32 *target, RrTextureImage *img,
gint target_w, gint target_h, gint target_w, gint target_h,
RrRect *area); RrRect *area);

View file

@ -18,6 +18,7 @@
#include "render.h" #include "render.h"
#include "imagecache.h" #include "imagecache.h"
#include "image.h"
static gboolean RrImagePicEqual(const RrImagePic *p1, static gboolean RrImagePicEqual(const RrImagePic *p1,
const RrImagePic *p2); const RrImagePic *p2);
@ -56,9 +57,8 @@ RrImage* RrImageCacheFind(RrImageCache *self,
RrPixel32 *data, gint w, gint h) RrPixel32 *data, gint w, gint h)
{ {
RrImagePic pic; RrImagePic pic;
pic.width = w;
pic.height = h; RrImagePicInit(&pic, w, h, data);
pic.data = data;
return g_hash_table_lookup(self->table, &pic); return g_hash_table_lookup(self->table, &pic);
} }
@ -139,21 +139,6 @@ guint RrImagePicHash(const RrImagePic *p)
static gboolean RrImagePicEqual(const RrImagePic *p1, static gboolean RrImagePicEqual(const RrImagePic *p1,
const RrImagePic *p2) const RrImagePic *p2)
{ {
guint s1, s2; return p1->width == p2->width && p1->height == p2->height &&
RrPixel32 *data1, *data2; p1->sum == p2->sum;
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;
} }

View file

@ -227,6 +227,9 @@ struct _RrAppearance {
struct _RrImagePic { struct _RrImagePic {
gint width, height; gint width, height;
RrPixel32 *data; 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 /*! An RrImage is a sort of meta-image. It can contain multiple versions of