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