Author: post
Date: 2010-02-06 16:53:23 +0100 (Sat, 06 Feb 2010)
New Revision: 3165

Modified:
   trunk/librawstudio/rs-filter.c
Log:
Filters: Clamp ROI between each filter, to avoid having an out-of-bound ROI - 
fixes crash when using rotate.

Modified: trunk/librawstudio/rs-filter.c
===================================================================
--- trunk/librawstudio/rs-filter.c      2010-02-06 15:35:58 UTC (rev 3164)
+++ trunk/librawstudio/rs-filter.c      2010-02-06 15:53:23 UTC (rev 3165)
@@ -171,6 +171,26 @@
        g_signal_emit(G_OBJECT(filter), signals[CHANGED_SIGNAL], 0, mask);
 }
 
+/* Clamps ROI rectangle to image size */
+/* Returns a new rectangle, or NULL if ROI was within bounds*/
+
+static GdkRectangle* 
+clamp_roi(const GdkRectangle *roi, RSFilter *filter)
+{
+       int w = rs_filter_get_width(filter);
+       int h = rs_filter_get_height(filter);
+
+       if ((roi->x >= 0) && (roi->y >=0) && (roi->x + roi->width <= w) && 
(roi->y + roi->height <= h))
+               return NULL;
+
+       GdkRectangle* new_roi = g_new(GdkRectangle, 1);
+       new_roi->x = MAX(0, roi->x);
+       new_roi->y = MAX(0, roi->y);
+       new_roi->width = MIN(w - new_roi->x, roi->width);
+       new_roi->height = MAX(h - new_roi->y, roi->height);
+       return new_roi;
+}
+
 /**
  * Get the output image from a RSFilter
  * @param filter A RSFilter
@@ -180,6 +200,9 @@
 RSFilterResponse *
 rs_filter_get_image(RSFilter *filter, const RSFilterRequest *request)
 {
+       GdkRectangle* roi = NULL;
+       RSFilterRequest *r = NULL;
+
        filter_debug("rs_filter_get_image(%s [%p])", RS_FILTER_NAME(filter), 
filter);
 
        /* This timer-hack will break badly when multithreaded! */
@@ -196,6 +219,17 @@
                gt = g_timer_new();
        count++;
 
+       if (filter->enabled && (roi = rs_filter_request_get_roi(request)))
+       {
+               roi = clamp_roi(roi, filter);
+               if (roi)
+               {
+                       r = rs_filter_request_clone(request);
+                       rs_filter_request_set_roi(r, roi);
+                       request = r;
+               }
+       }
+
        if (RS_FILTER_GET_CLASS(filter)->get_image && filter->enabled)
                response = RS_FILTER_GET_CLASS(filter)->get_image(filter, 
request);
        else
@@ -207,14 +241,18 @@
 
        elapsed = g_timer_elapsed(gt, NULL) - last_elapsed;
 
+       if (roi)
+               g_free(roi);
+       if (r)
+               g_object_unref(r);
 
-       if ((elapsed > 0.05) && (image != NULL)) 
+       if ((elapsed > 0.001) && (image != NULL)) 
        {
                gint iw = image->w;
                gint ih = image->h;
                if (rs_filter_response_get_roi(response)) 
                {
-                       GdkRectangle *roi = 
rs_filter_response_get_roi(response);
+                       roi = rs_filter_response_get_roi(response);
                        iw = roi->width;
                        ih = roi->height;
                }
@@ -246,6 +284,7 @@
        return response;
 }
 
+
 /**
  * Get 8 bit output image from a RSFilter
  * @param filter A RSFilter
@@ -265,12 +304,25 @@
 
        RSFilterResponse *response = NULL;
        GdkPixbuf *image = NULL;
+       GdkRectangle* roi = NULL;
+       RSFilterRequest *r = NULL;
        g_assert(RS_IS_FILTER(filter));
 
        if (count == -1)
                gt = g_timer_new();
        count++;
 
+       if (filter->enabled && (roi = rs_filter_request_get_roi(request)))
+       {
+               roi = clamp_roi(roi, filter);
+               if (roi)
+               {
+                       r = rs_filter_request_clone(request);
+                       rs_filter_request_set_roi(r, roi);
+                       request = r;
+               }
+       }
+
        if (RS_FILTER_GET_CLASS(filter)->get_image8 && filter->enabled)
                response = RS_FILTER_GET_CLASS(filter)->get_image8(filter, 
request);
        else if (filter->previous)
@@ -281,6 +333,11 @@
        image = rs_filter_response_get_image8(response);
        elapsed = g_timer_elapsed(gt, NULL) - last_elapsed;
        
+       if (roi)
+               g_free(roi);
+       if (r)
+               g_object_unref(r);
+
        if ((elapsed > 0.05) && (image != NULL)) {
                gint iw = gdk_pixbuf_get_width(image);
                gint ih = gdk_pixbuf_get_height(image);


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

Reply via email to