X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=render%2Fimage.c;h=6fbd8a8e3c860473f6ae200f53aff1764b556007;hb=610e80e05286fd8fa189ad19aecd68dc978a48b8;hp=a618f7828b531f01fcf99402dc3b886c6d03658f;hpb=a2e3026d8a398a4d08c05610c3f652dd14fcdf45;p=chaz%2Fopenbox diff --git a/render/image.c b/render/image.c index a618f782..6fbd8a8e 100644 --- a/render/image.c +++ b/render/image.c @@ -28,6 +28,26 @@ #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++); +} + +static void RrImagePicFree(RrImagePic *pic) +{ + if (pic) { + g_free(pic->data); + g_free(pic); + } +} + /*! 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. */ @@ -54,10 +74,10 @@ static void AddPicture(RrImage *self, RrImagePic ***list, gint *len, g_hash_table_insert(self->cache->table, (*list)[0], self); #ifdef DEBUG - g_print("Adding %s picture to the cache: " - "Image 0x%x, w %d h %d Hash %u\n", - (*list == self->original ? "ORIGINAL" : "RESIZED"), - (guint)self, pic->width, pic->height, RrImagePicHash(pic)); + g_message("Adding %s picture to the cache:\n " + "Image 0x%x, w %d h %d Hash %u", + (*list == self->original ? "ORIGINAL" : "RESIZED"), + (guint)self, pic->width, pic->height, RrImagePicHash(pic)); #endif } @@ -69,19 +89,18 @@ static void RemovePicture(RrImage *self, RrImagePic ***list, gint j; #ifdef DEBUG - g_print("Removing %s picture from the cache: " - "Image 0x%x, w %d h %d Hash %u\n", - (*list == self->original ? "ORIGINAL" : "RESIZED"), - (guint)self, (*list)[i]->width, (*list)[i]->height, - RrImagePicHash((*list)[i])); + g_message("Removing %s picture from the cache:\n " + "Image 0x%x, w %d h %d Hash %u", + (*list == self->original ? "ORIGINAL" : "RESIZED"), + (guint)self, (*list)[i]->width, (*list)[i]->height, + RrImagePicHash((*list)[i])); #endif /* remove the picture as a key in the cache */ g_hash_table_remove(self->cache->table, (*list)[i]); - /* free the picture (and its rgba data) */ - g_free((*list)[i]); - g_free((*list)[i]->data); + /* free the picture */ + RrImagePicFree((*list)[i]); /* shift everything down one */ for (j = i; j < *len-1; ++j) (*list)[j] = (*list)[j+1]; @@ -98,7 +117,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 +137,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 +209,9 @@ static RrImagePic* ResizeImage(RrPixel32 *src, } } + pic = g_new(RrImagePic, 1); + RrImagePicInit(pic, dstW, dstH, dststart); + return pic; } @@ -305,8 +323,8 @@ void RrImageUnref(RrImage *self) { if (self && --self->ref == 0) { #ifdef DEBUG - g_print("Refcount to 0, removing ALL pictures from the cache: " - "Image 0x%x\n", (guint)self); + g_message("Refcount to 0, removing ALL pictures from the cache:\n " + "Image 0x%x", (guint)self); #endif while (self->n_original > 0) RemovePicture(self, &self->original, 0, &self->n_original); @@ -328,8 +346,8 @@ void RrImageAddPicture(RrImage *self, RrPixel32 *data, gint w, gint h) for (i = 0; i < self->n_original; ++i) if (self->original[i]->width == w && self->original[i]->height == h) { #ifdef DEBUG - g_print("Found duplicate ORIGINAL image: " - "Image 0x%x, w %d h %d\n", (guint)self, w, h); + g_message("Found duplicate ORIGINAL image:\n " + "Image 0x%x, w %d h %d", (guint)self, w, h); #endif return; } @@ -343,9 +361,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); } @@ -376,9 +392,11 @@ void RrImageDrawImage(RrPixel32 *target, RrTextureImage *img, gint i, min_diff, min_i, min_aspect_diff, min_aspect_i; RrImage *self; RrImagePic *pic; + gboolean free_pic; self = img->image; pic = NULL; + free_pic = FALSE; /* is there an original of this size? (only w or h has to be right cuz we maintain aspect ratios) */ @@ -465,6 +483,8 @@ void RrImageDrawImage(RrPixel32 *target, RrTextureImage *img, if (self->cache->max_resized_saved) /* add it to the top of the resized list */ AddPicture(self, &self->resized, &self->n_resized, pic); + else + free_pic = TRUE; /* don't leak mem! */ } g_assert(pic != NULL); @@ -472,4 +492,6 @@ void RrImageDrawImage(RrPixel32 *target, RrTextureImage *img, DrawRGBA(target, target_w, target_h, pic->data, pic->width, pic->height, img->alpha, area); + if (free_pic) + RrImagePicFree(pic); }