]> Dogcows Code - chaz/openbox/blobdiff - render/image.c
Merge branch 'backport' into work
[chaz/openbox] / render / image.c
index d0633d948d0a3b1f9f4edc5b24f26f316e8eaa82..924504fdf9c1e3a8973191852a40ce854c71179e 100644 (file)
@@ -40,6 +40,14 @@ void RrImagePicInit(RrImagePic *pic, gint w, gint h, RrPixel32 *data)
         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. */
@@ -65,12 +73,14 @@ static void AddPicture(RrImage *self, RrImagePic ***list, gint *len,
     /* add the picture as a key to point to this image in the cache */
     g_hash_table_insert(self->cache->table, (*list)[0], self);
 
+/*
 #ifdef DEBUG
-    g_message("Adding %s picture to the cache:\n    "
-              "Image 0x%x, w %d h %d Hash %u\n",
-              (*list == self->original ? "ORIGINAL" : "RESIZED"),
-              (guint)self, pic->width, pic->height, RrImagePicHash(pic));
+    g_debug("Adding %s picture to the cache:\n    "
+            "Image 0x%lx, w %d h %d Hash %u",
+            (*list == self->original ? "ORIGINAL" : "RESIZED"),
+            (gulong)self, pic->width, pic->height, RrImagePicHash(pic));
 #endif
+*/
 }
 
 /*! Remove a picture from an Image.  This may remove it from the "originals"
@@ -80,20 +90,21 @@ static void RemovePicture(RrImage *self, RrImagePic ***list,
 {
     gint j;
 
+/*
 #ifdef DEBUG
-    g_message("Removing %s picture from the cache:\n    "
-              "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_debug("Removing %s picture from the cache:\n    "
+            "Image 0x%lx, w %d h %d Hash %u",
+            (*list == self->original ? "ORIGINAL" : "RESIZED"),
+            (gulong)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];
@@ -117,6 +128,12 @@ static RrImagePic* ResizeImage(RrPixel32 *src,
     gulong ratioX, ratioY;
     gulong aspectW, aspectH;
 
+    /* XXX should these variables be ensured to not be zero in the callers? */
+    srcW = srcW ? srcW : 1;
+    srcH = srcH ? srcH : 1;
+    dstW = dstW ? dstW : 1;
+    dstH = dstH ? dstH : 1;
+
     /* keep the aspect ratio */
     aspectW = dstW;
     aspectH = (gint)(dstW * ((gdouble)srcH / srcW));
@@ -124,11 +141,11 @@ static RrImagePic* ResizeImage(RrPixel32 *src,
         aspectH = dstH;
         aspectW = (gint)(dstH * ((gdouble)srcW / srcH));
     }
-    dstW = aspectW;
-    dstH = aspectH;
+    dstW = aspectW ? aspectW : 1;
+    dstH = aspectH ? aspectH : 1;
 
     if (srcW == dstW && srcH == dstH)
-        return NULL; /* no scaling needed ! */
+        return NULL; /* no scaling needed! */
 
     dststart = dst = g_new(RrPixel32, dstW * dstH);
 
@@ -208,7 +225,7 @@ static RrImagePic* ResizeImage(RrPixel32 *src,
     return pic;
 }
 
-/*! This drawns an RGBA picture into the target, within the rectangle specified
+/*! This draws an RGBA picture into the target, within the rectangle specified
   by the area parameter.  If the area's size differs from the source's then it
   will be centered within the rectangle */
 void DrawRGBA(RrPixel32 *target, gint target_w, gint target_h,
@@ -287,6 +304,7 @@ void RrImageDrawRGBA(RrPixel32 *target, RrTextureRGBA *rgba,
             DrawRGBA(target, target_w, target_h,
                      scaled->data, scaled->width, scaled->height,
                      rgba->alpha, area);
+            RrImagePicFree(scaled);
     }
     else
         DrawRGBA(target, target_w, target_h,
@@ -315,10 +333,12 @@ void RrImageRef(RrImage *self)
 void RrImageUnref(RrImage *self)
 {
     if (self && --self->ref == 0) {
+/*
 #ifdef DEBUG
-        g_message("Refcount to 0, removing ALL pictures from the cache:\n    "
-                  "Image 0x%x\n", (guint)self);
+        g_debug("Refcount to 0, removing ALL pictures from the cache:\n    "
+                "Image 0x%lx", (gulong)self);
 #endif
+*/
         while (self->n_original > 0)
             RemovePicture(self, &self->original, 0, &self->n_original);
         while (self->n_resized > 0)
@@ -338,10 +358,12 @@ void RrImageAddPicture(RrImage *self, RrPixel32 *data, gint w, gint h)
     /* make sure we don't already have this size.. */
     for (i = 0; i < self->n_original; ++i)
         if (self->original[i]->width == w && self->original[i]->height == h) {
+/*
 #ifdef DEBUG
-            g_message("Found duplicate ORIGINAL image:\n    "
-                      "Image 0x%x, w %d h %d\n", (guint)self, w, h);
+            g_debug("Found duplicate ORIGINAL image:\n    "
+                    "Image 0x%lx, w %d h %d", (gulong)self, w, h);
 #endif
+*/
             return;
         }
 
@@ -385,15 +407,19 @@ 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) */
+    /* is there an original of this size? (only the larger of
+       w or h has to be right cuz we maintain aspect ratios) */
     for (i = 0; i < self->n_original; ++i)
-        if (self->original[i]->width == area->width ||
-            self->original[i]->height == area->height)
+        if ((self->original[i]->width >= self->original[i]->height &&
+             self->original[i]->width == area->width) ||
+            (self->original[i]->width <= self->original[i]->height &&
+             self->original[i]->height == area->height))
         {
             pic = self->original[i];
             break;
@@ -401,8 +427,10 @@ void RrImageDrawImage(RrPixel32 *target, RrTextureImage *img,
 
     /* is there a resize of this size? */
     for (i = 0; i < self->n_resized; ++i)
-        if (self->resized[i]->width == area->width ||
-            self->resized[i]->height == area->height)
+        if ((self->resized[i]->width >= self->resized[i]->height &&
+             self->resized[i]->width == area->width) ||
+            (self->resized[i]->width <= self->resized[i]->height &&
+             self->resized[i]->height == area->height))
         {
             gint j;
             RrImagePic *saved;
@@ -474,6 +502,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);
@@ -481,4 +511,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);
 }
This page took 0.025005 seconds and 4 git commands to generate.