Author: abrander
Date: 2009-06-01 23:41:16 +0200 (Mon, 01 Jun 2009)
New Revision: 2496

Modified:
   trunk/librawstudio/rs-image16.c
   trunk/librawstudio/rs-image16.h
Log:
Added rs_image16_new_subframe().

Modified: trunk/librawstudio/rs-image16.c
===================================================================
--- trunk/librawstudio/rs-image16.c     2009-06-01 17:00:57 UTC (rev 2495)
+++ trunk/librawstudio/rs-image16.c     2009-06-01 21:41:16 UTC (rev 2496)
@@ -71,9 +71,11 @@
 {
        RS_IMAGE16 *self = (RS_IMAGE16 *)obj;
 
-       if (self->pixels)
+       if (self->pixels && (self->pixels_refcount == 1))
                free(self->pixels);
 
+       self->pixels_refcount--;
+
        /* Chain up to the parent class */
        G_OBJECT_CLASS (parent_class)->finalize (obj);
 }
@@ -105,6 +107,7 @@
        self->filters = 0;
        self->preview = FALSE;
        self->pixels = NULL;
+       self->pixels_refcount = 0;
 }
 
 void
@@ -807,7 +810,8 @@
                rsi->pixels = NULL;
                g_object_unref(rsi);
                return NULL;
-       } 
+       }
+       rsi->pixels_refcount = 1;
 
        /* Verify alignment */
        g_assert((GPOINTER_TO_INT(rsi->pixels) % 16) == 0);
@@ -817,6 +821,74 @@
 }
 
 /**
+ * Initializes a new RS_IMAGE16 with pixeldata from @input.
+ * @note Pixeldata is NOT copied to new RS_IMAGE16.
+ * @param input A RS_IMAGE16
+ * @param rectangle A GdkRectangle describing the area to subframe
+ * @return A new RS_IMAGE16 with a refcount of 1, the image can be bigger
+ *         than rectangle to retain 16 byte alignment.
+ */
+RS_IMAGE16 *
+rs_image16_new_subframe(RS_IMAGE16 *input, GdkRectangle *rectangle)
+{
+       RS_IMAGE16 *output;
+       gint width, height;
+       gint x, y;
+
+       g_assert(RS_IS_IMAGE16(input));
+       g_assert(rectangle->x >= 0);
+       g_assert(rectangle->y >= 0);
+       g_assert(rectangle->width > 0);
+       g_assert(rectangle->height > 0);
+
+       g_assert(rectangle->width <= input->w);
+       g_assert(rectangle->height <= input->h);
+
+       g_assert((rectangle->width + rectangle->x) <= input->w);
+       g_assert((rectangle->height + rectangle->y) <= input->h);
+
+       output = g_object_new(RS_TYPE_IMAGE16, NULL);
+
+       /* Align x to 16 byte boundary */
+       x = rectangle->x - (rectangle->x & 0x3);
+       x = CLAMP(x, 0, input->w-1);
+
+       y = CLAMP(rectangle->y, 0, input->h-1);
+
+       width = CLAMP(rectangle->width + (rectangle->x & 0x3), 1, input->w - x);
+       height = CLAMP(rectangle->height, 1, input->h - y);
+
+       output->w = width;
+       output->h = height;
+       output->rowstride = input->rowstride;
+       output->pitch = input->pitch;
+       output->channels = input->channels;
+       output->pixelsize = input->pixelsize;
+       output->filters = input->filters;
+
+       output->pixels = GET_PIXEL(input, x, y);
+       output->pixels_refcount = input->pixels_refcount + 1;
+
+       /* Some sanity checks */
+       g_assert(output->w <= input->w);
+       g_assert(output->h <= input->h);
+
+       g_assert(output->w > 64);
+       g_assert(output->h > 64);
+
+       g_assert(output->w >= rectangle->width);
+       g_assert(output->h >= rectangle->height);
+
+       g_assert((output->w - 4) <= rectangle->width);
+
+       /* Verify alignment */
+       g_assert((GPOINTER_TO_INT(output->pixels) % 16) == 0);
+       g_assert((output->rowstride % 16) == 0);
+
+       return output;
+}
+
+/**
  * Renders an exposure map on top of an GdkPixbuf with 3 channels
  * @param pixbuf A GdkPixbuf
  * @param only_row A single row to render or -1 to render all

Modified: trunk/librawstudio/rs-image16.h
===================================================================
--- trunk/librawstudio/rs-image16.h     2009-06-01 17:00:57 UTC (rev 2495)
+++ trunk/librawstudio/rs-image16.h     2009-06-01 21:41:16 UTC (rev 2496)
@@ -39,6 +39,7 @@
        guint pixelsize; /* the size of a pixel in SHORTS */
        guint orientation;
        gushort *pixels;
+       gint pixels_refcount;
        guint filters;
        gboolean preview;
        gboolean dispose_has_run;
@@ -71,6 +72,17 @@
 extern RS_IMAGE16 *rs_image16_new(const guint width, const guint height, const 
guint channels, const guint pixelsize);
 
 /**
+ * Initializes a new RS_IMAGE16 with pixeldata from @input.
+ * @note Pixeldata is NOT copied to new RS_IMAGE16.
+ * @param input A RS_IMAGE16
+ * @param rectangle A GdkRectangle describing the area to subframe
+ * @return A new RS_IMAGE16 with a refcount of 1, the image can be bigger
+ *         than rectangle to retain 16 byte alignment.
+ */
+extern RS_IMAGE16 *
+rs_image16_new_subframe(RS_IMAGE16 *input, GdkRectangle *rectangle);
+
+/**
  * Renders an exposure map on top of an GdkPixbuf with 3 channels
  * @param pixbuf A GdkPixbuf
  * @param only_row A single row to render or -1 to render all


_______________________________________________
Rawstudio-commit mailing list
[email protected]
http://rawstudio.org/cgi-bin/mailman/listinfo/rawstudio-commit

Reply via email to