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