Author: abrander
Date: 2009-08-03 21:15:15 +0200 (Mon, 03 Aug 2009)
New Revision: 2598

Modified:
   trunk/plugins/crop/crop.c
Log:
Refactored crop to better support alternating orientation.

Modified: trunk/plugins/crop/crop.c
===================================================================
--- trunk/plugins/crop/crop.c   2009-08-01 11:48:14 UTC (rev 2597)
+++ trunk/plugins/crop/crop.c   2009-08-03 19:15:15 UTC (rev 2598)
@@ -33,7 +33,10 @@
 struct _RSCrop {
        RSFilter parent;
 
-       RS_RECT rectangle;
+       RS_RECT target;
+       RS_RECT effective;
+       gint width;
+       gint height;
 };
 
 struct _RSCropClass {
@@ -48,11 +51,18 @@
        PROP_X1,
        PROP_X2,
        PROP_Y1,
-       PROP_Y2
+       PROP_Y2,
+       PROP_EFFECTIVE_X1,
+       PROP_EFFECTIVE_X2,
+       PROP_EFFECTIVE_Y1,
+       PROP_EFFECTIVE_Y2,
+       PROP_WIDTH,
+       PROP_HEIGHT
 };
 
 static void get_property (GObject *object, guint property_id, GValue *value, 
GParamSpec *pspec);
 static void set_property (GObject *object, guint property_id, const GValue 
*value, GParamSpec *pspec);
+static void calc(RSCrop *crop);
 static RSFilterResponse *get_image(RSFilter *filter, const RSFilterParam 
*param);
 static gint get_width(RSFilter *filter);
 static gint get_height(RSFilter *filter);
@@ -97,6 +107,26 @@
                PROP_Y2, g_param_spec_int("y2", "y2", "y2", 0, 2147483647, 0, 
G_PARAM_READWRITE)
        );
 
+       g_object_class_install_property(object_class,
+               PROP_EFFECTIVE_X1, g_param_spec_int("effective-x1", 
"effective-x1", "Effective x1", 0, 2147483647, 0, G_PARAM_READABLE)
+       );
+       g_object_class_install_property(object_class,
+               PROP_EFFECTIVE_Y1, g_param_spec_int("effective-y1", 
"effective-y1", "Effective y1", 0, 2147483647, 0, G_PARAM_READABLE)
+       );
+       g_object_class_install_property(object_class,
+               PROP_EFFECTIVE_X2, g_param_spec_int("effective-x2", 
"effective-x2", "Effective x2", 0, 2147483647, 0, G_PARAM_READABLE)
+       );
+       g_object_class_install_property(object_class,
+               PROP_EFFECTIVE_Y2, g_param_spec_int("effective-y2", 
"effective-y2", "Effective y2", 0, 2147483647, 0, G_PARAM_READABLE)
+       );
+
+       g_object_class_install_property(object_class,
+               PROP_WIDTH, g_param_spec_int("width", "width", "Width", 0, 
2147483647, 0, G_PARAM_READABLE)
+       );
+       g_object_class_install_property(object_class,
+               PROP_HEIGHT, g_param_spec_int("height", "height", "Height", 0, 
2147483647, 0, G_PARAM_READABLE)
+       );
+
        filter_class->name = "Crop filter";
        filter_class->get_image = get_image;
        filter_class->get_width = get_width;
@@ -106,10 +136,10 @@
 static void
 rs_crop_init (RSCrop *crop)
 {
-       crop->rectangle.x1 = 0;
-       crop->rectangle.x2 = 65535;
-       crop->rectangle.y1 = 0;
-       crop->rectangle.y2 = 65535;
+       crop->target.x1 = 0;
+       crop->target.x2 = 65535;
+       crop->target.y1 = 0;
+       crop->target.y2 = 65535;
 }
 
 static void
@@ -117,11 +147,43 @@
 {
        RSCrop *crop = RS_CROP(object);
 
+       calc(crop);
+
        switch (property_id)
        {
                case PROP_RECTANGLE:
-                       g_value_set_pointer(value, &crop->rectangle);
+                       g_value_set_pointer(value, &crop->target);
                        break;
+               case PROP_X1:
+                       g_value_set_int(value, crop->target.x1);
+                       break;
+               case PROP_X2:
+                       g_value_set_int(value, crop->target.x2);
+                       break;
+               case PROP_Y1:
+                       g_value_set_int(value, crop->target.y1);
+                       break;
+               case PROP_Y2:
+                       g_value_set_int(value, crop->target.y2);
+                       break;
+               case PROP_EFFECTIVE_X1:
+                       g_value_set_int(value, crop->effective.x1);
+                       break;
+               case PROP_EFFECTIVE_X2:
+                       g_value_set_int(value, crop->effective.x2);
+                       break;
+               case PROP_EFFECTIVE_Y1:
+                       g_value_set_int(value, crop->effective.y1);
+                       break;
+               case PROP_EFFECTIVE_Y2:
+                       g_value_set_int(value, crop->effective.y2);
+                       break;
+               case PROP_WIDTH:
+                       g_value_set_int(value, crop->width);
+                       break;
+               case PROP_HEIGHT:
+                       g_value_set_int(value, crop->height);
+                       break;
                default:
                        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, 
pspec);
        }
@@ -132,43 +194,37 @@
 {
        RSCrop *crop = RS_CROP(object);
        RSFilter *filter = RS_FILTER(crop);
-       gint parent_width = rs_filter_get_width(filter->previous);
-       gint parent_height = rs_filter_get_height(filter->previous);
        RS_RECT *rect;
+
        switch (property_id)
        {
                case PROP_RECTANGLE:
                        rect = g_value_get_pointer(value);
                        if (rect)
-                       {
-                               crop->rectangle.x1 = MAX(rect->x1, 0);
-                               crop->rectangle.y1 = MAX(rect->y1, 0);
-                               crop->rectangle.x2 = MIN(rect->x2, 
parent_width);
-                               crop->rectangle.y2 = MIN(rect->y2, 
parent_height);
-                       }
+                               crop->target = *rect;
                        else
                        {
-                               crop->rectangle.x1 = 0;
-                               crop->rectangle.x2 = 65535;
-                               crop->rectangle.y1 = 0;
-                               crop->rectangle.y2 = 65535;
+                               crop->target.x1 = 0;
+                               crop->target.x2 = 65535;
+                               crop->target.y1 = 0;
+                               crop->target.y2 = 65535;
                        }
                        rs_filter_changed(filter, RS_FILTER_CHANGED_DIMENSION);
                        break;
                case PROP_X1:
-                       crop->rectangle.x1 = MAX(g_value_get_int(value), 0);
+                       crop->target.x1 = g_value_get_int(value);
                        rs_filter_changed(filter, RS_FILTER_CHANGED_DIMENSION);
                        break;
                case PROP_Y1:
-                       crop->rectangle.y1 = MAX(g_value_get_int(value), 0);
+                       crop->target.y1 = g_value_get_int(value);
                        rs_filter_changed(filter, RS_FILTER_CHANGED_DIMENSION);
                        break;
                case PROP_X2:
-                       crop->rectangle.x2 = MIN(g_value_get_int(value), 
parent_width);
+                       crop->target.x2 = g_value_get_int(value);
                        rs_filter_changed(filter, RS_FILTER_CHANGED_DIMENSION);
                        break;
                case PROP_Y2:
-                       crop->rectangle.y2 = MIN(g_value_get_int(value), 
parent_height);
+                       crop->target.y2 = g_value_get_int(value);
                        rs_filter_changed(filter, RS_FILTER_CHANGED_DIMENSION);
                        break;
                default:
@@ -176,6 +232,23 @@
        }
 }
 
+static void
+calc(RSCrop *crop)
+{
+       RSFilter *filter = RS_FILTER(crop);
+
+       gint parent_width = rs_filter_get_width(filter->previous);
+       gint parent_height = rs_filter_get_height(filter->previous);
+
+       crop->effective.x1 = CLAMP(crop->target.x1, 0, parent_width-1);
+       crop->effective.x2 = CLAMP(crop->target.x2, 0, parent_width-1);
+       crop->effective.y1 = CLAMP(crop->target.y1, 0, parent_height-1);
+       crop->effective.y2 = CLAMP(crop->target.y2, 0, parent_height-1);
+
+       crop->width = crop->effective.x2 - crop->effective.x1 + 1;
+       crop->height = crop->effective.y2 - crop->effective.y1 + 1;
+}
+
 static RSFilterResponse *
 get_image(RSFilter *filter, const RSFilterParam *param)
 {
@@ -187,18 +260,13 @@
        RS_IMAGE16 *input;
        gint parent_width = rs_filter_get_width(filter->previous);
        gint parent_height = rs_filter_get_height(filter->previous);
-
-       gint x1 = CLAMP(crop->rectangle.x1, 0, parent_width-1);
-       gint x2 = CLAMP(crop->rectangle.x2, 0, parent_width-1);
-       gint y1 = CLAMP(crop->rectangle.y1, 0, parent_height-1);
-       gint y2 = CLAMP(crop->rectangle.y2, 0, parent_height-1);
        gint row;
-       gint width = x2 - x1 + 1;
-       gint height = y2 - y1 + 1;
 
+       calc(crop);
+
        previous_response = rs_filter_get_image(filter->previous, param);
        /* Special case for full crop */
-       if ((width == parent_width) && (height==parent_height))
+       if ((crop->width == parent_width) && (crop->height==parent_height))
                return previous_response;
 
        input = rs_filter_response_get_image(previous_response);
@@ -209,13 +277,13 @@
        response = rs_filter_response_clone(previous_response);
        g_object_unref(previous_response);
 
-       output = rs_image16_new(width, height, 3, 4);
+       output = rs_image16_new(crop->width, crop->height, 3, 4);
        rs_filter_response_set_image(response, output);
        g_object_unref(output);
 
        /* Copy a row at a time */
        for(row=0; row<output->h; row++)
-               memcpy(GET_PIXEL(output, 0, row), GET_PIXEL(input, x1, row+y1), 
output->rowstride*sizeof(gushort));
+               memcpy(GET_PIXEL(output, 0, row), GET_PIXEL(input, 
crop->effective.x1, row+crop->effective.y1), output->rowstride*sizeof(gushort));
 
        g_object_unref(input);
 
@@ -226,18 +294,17 @@
 get_width(RSFilter *filter)
 {
        RSCrop *crop = RS_CROP(filter);
-       gint parent_width = rs_filter_get_width(filter->previous);
-       gint width = crop->rectangle.x2 - crop->rectangle.x1 + 1;
 
-       return CLAMP(width, 0, parent_width);
+       calc(crop);
+
+       return crop->width;
 }
 
 static gint
 get_height(RSFilter *filter)
 {
        RSCrop *crop = RS_CROP(filter);
-       gint parent_height = rs_filter_get_height(filter->previous);
-       gint height = crop->rectangle.y2 - crop->rectangle.y1 + 1;
+       calc(crop);
 
-       return CLAMP(height, 0, parent_height);
+       return crop->height;
 }


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

Reply via email to