Author: post
Date: 2010-08-20 17:39:54 +0200 (Fri, 20 Aug 2010)
New Revision: 3497
Modified:
trunk/plugins/crop/crop.c
trunk/plugins/demosaic/demosaic.c
trunk/plugins/rotate/rotate.c
trunk/src/rs-preview-widget.c
Log:
Implement downscale of image to half size, for initial preview of image in
zoom-to-fit mode. When creating the de-mosaic, the 4 pixel components are
merged into a single pixel. Gives big speedup on image select to display time.
Filters adjusted, so they are invariant to changes from get_size request to
actual image data being delivered to them.
Modified: trunk/plugins/crop/crop.c
===================================================================
--- trunk/plugins/crop/crop.c 2010-08-20 11:22:24 UTC (rev 3496)
+++ trunk/plugins/crop/crop.c 2010-08-20 15:39:54 UTC (rev 3497)
@@ -314,15 +314,18 @@
return previous_response;
response = rs_filter_response_clone(previous_response);
+ gboolean half_size = FALSE;
+ rs_filter_param_get_boolean(RS_FILTER_PARAM(previous_response),
"half-size", &half_size);
g_object_unref(previous_response);
- output = rs_image16_new(crop->width, crop->height, 3, input->pixelsize);
+ int shift = half_size ? 1 : 0;
+ output = rs_image16_new(crop->width>>shift, crop->height>>shift, 3,
input->pixelsize);
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,
crop->effective.x1, row+crop->effective.y1), output->rowstride*sizeof(gushort));
+ memcpy(GET_PIXEL(output, 0, row), GET_PIXEL(input,
crop->effective.x1>>shift, row+(crop->effective.y1>>shift)),
output->rowstride*sizeof(gushort));
g_object_unref(input);
Modified: trunk/plugins/demosaic/demosaic.c
===================================================================
--- trunk/plugins/demosaic/demosaic.c 2010-08-20 11:22:24 UTC (rev 3496)
+++ trunk/plugins/demosaic/demosaic.c 2010-08-20 15:39:54 UTC (rev 3497)
@@ -40,7 +40,8 @@
RS_DEMOSAIC_NONE,
RS_DEMOSAIC_BILINEAR,
RS_DEMOSAIC_PPG,
- RS_DEMOSAIC_MAX
+ RS_DEMOSAIC_MAX,
+ RS_DEMOSAIC_NONE_HALF
} RS_DEMOSAIC;
const static gchar *rs_demosaic_ascii[RS_DEMOSAIC_MAX] = {
@@ -56,6 +57,7 @@
RSFilter parent;
RS_DEMOSAIC method;
+ gboolean allow_half;
};
struct _RSDemosaicClass {
@@ -66,7 +68,8 @@
enum {
PROP_0,
- PROP_METHOD
+ PROP_METHOD,
+ PROP_ALLOW_HALF,
};
static void get_property (GObject *object, guint property_id, GValue *value,
GParamSpec *pspec);
@@ -76,7 +79,7 @@
static void border_interpolate_INDI (const ThreadInfo* t, int colors, int
border);
static void lin_interpolate_INDI(RS_IMAGE16 *image, RS_IMAGE16 *output, const
unsigned int filters, const int colors);
static void ppg_interpolate_INDI(RS_IMAGE16 *image, RS_IMAGE16 *output, const
unsigned int filters, const int colors);
-static void none_interpolate_INDI(RS_IMAGE16 *in, RS_IMAGE16 *out, const
unsigned int filters, const int colors);
+static void none_interpolate_INDI(RS_IMAGE16 *in, RS_IMAGE16 *out, const
unsigned int filters, const int colors, gboolean half_size);
static void hotpixel_detect(const ThreadInfo* t);
static void expand_cfa_data(const ThreadInfo* t);
@@ -106,6 +109,12 @@
rs_demosaic_ascii[RS_DEMOSAIC_PPG], G_PARAM_READWRITE)
);
+ g_object_class_install_property(object_class,
+ PROP_ALLOW_HALF, g_param_spec_boolean(
+ "demosaic-allow-downscale", "demosaic-allow-downscale",
"Allow demosaic to return half size image",
+ FALSE, G_PARAM_READWRITE)
+ );
+
filter_class->name = "Demosaic filter";
filter_class->get_image = get_image;
}
@@ -126,6 +135,9 @@
case PROP_METHOD:
g_value_set_string(value,
rs_demosaic_ascii[demosaic->method]);
break;
+ case PROP_ALLOW_HALF:
+ g_value_set_boolean(value, demosaic->allow_half);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id,
pspec);
}
@@ -147,6 +159,10 @@
if (g_str_equal(rs_demosaic_ascii[i], str))
demosaic->method = i;
}
+ break;
+ case PROP_ALLOW_HALF:
+ demosaic->allow_half = g_value_get_boolean(value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id,
pspec);
}
@@ -212,7 +228,18 @@
method = RS_DEMOSAIC_PPG;
if (method == RS_DEMOSAIC_NONE)
- output = rs_image16_new(input->w, input->h, 3, 4);
+ {
+ if (demosaic->allow_half)
+ {
+ output = rs_image16_new(input->w/2, input->h/2, 3, 4);
+ rs_filter_param_set_boolean(RS_FILTER_PARAM(response),
"half-size", TRUE);
+ method = RS_DEMOSAIC_NONE_HALF;
+ }
+ else
+ {
+ output = rs_image16_new(input->w, input->h, 3, 4);
+ }
+ }
else
output = rs_image16_new(input->w, input->h, 3, 4);
@@ -229,8 +256,11 @@
ppg_interpolate_INDI(input,output, filters, 3);
break;
case RS_DEMOSAIC_NONE:
- none_interpolate_INDI(input, output, filters, 3);
+ none_interpolate_INDI(input, output, filters, 3, FALSE);
break;
+ case RS_DEMOSAIC_NONE_HALF:
+ none_interpolate_INDI(input, output, filters, 3, TRUE);
+ break;
default:
/* Do nothing */
break;
@@ -511,7 +541,7 @@
g_free(t);
}
-#if 1
+
gpointer
start_none_thread(gpointer _thread_info)
{
@@ -592,10 +622,9 @@
return NULL; /* Make the compiler shut up - we'll never return */
}
-#else
gpointer
-start_none_thread(gpointer _thread_info)
+start_none_thread_half(gpointer _thread_info)
{
gint row, col, i, j;
gushort *src;
@@ -642,10 +671,10 @@
return NULL; /* Make the compiler shut up - we'll never return */
}
-#endif
+
static void
-none_interpolate_INDI(RS_IMAGE16 *in, RS_IMAGE16 *out, const unsigned int
filters, const int colors)
+none_interpolate_INDI(RS_IMAGE16 *in, RS_IMAGE16 *out, const unsigned int
filters, const int colors, gboolean half_size)
{
guint i, y_offset, y_per_thread, threaded_h;
const guint threads = rs_get_number_of_processor_cores();
@@ -666,7 +695,10 @@
y_offset = MIN(out->h-1, y_offset);
t[i].end_y = y_offset;
- t[i].threadid = g_thread_create(start_none_thread, &t[i], TRUE,
NULL);
+ if (half_size)
+ t[i].threadid = g_thread_create(start_none_thread_half,
&t[i], TRUE, NULL);
+ else
+ t[i].threadid = g_thread_create(start_none_thread,
&t[i], TRUE, NULL);
}
/* Wait for threads to finish */
Modified: trunk/plugins/rotate/rotate.c
===================================================================
--- trunk/plugins/rotate/rotate.c 2010-08-20 11:22:24 UTC (rev 3496)
+++ trunk/plugins/rotate/rotate.c 2010-08-20 15:39:54 UTC (rev 3497)
@@ -76,6 +76,7 @@
static void inline bilinear(RS_IMAGE16 *in, gushort *out, gint x, gint y);
static void inline nearest(RS_IMAGE16 *in, gushort *out, gint x, gint y);
static void recalculate(RSRotate *rotate, const RSFilterRequest *request);
+static void recalculate_dims(RSRotate *rotate, gint previous_width, gint
previous_height);
gpointer start_rotate_thread(gpointer _thread_info);
static RSFilterClass *rs_rotate_parent_class = NULL;
@@ -255,8 +256,8 @@
output = rs_image16_new(input->h, input->w, 3,
input->pixelsize);
straight = TRUE;
} else {
+ recalculate_dims(rotate, input->w, input->h);
output = rs_image16_new(rotate->new_width, rotate->new_height,
3, 4);
- recalculate(rotate, request);
}
if (rs_filter_request_get_quick(request))
@@ -352,8 +353,7 @@
RSRotate *rotate = RS_ROTATE(filter);
RSFilterResponse *previous_response =
rs_filter_get_size(filter->previous, request);
- if (rotate->dirty)
- recalculate(rotate, request);
+ recalculate(rotate, request);
RSFilterResponse *response =
rs_filter_response_clone(previous_response);
g_object_unref(previous_response);
@@ -448,14 +448,8 @@
}
static void
-recalculate(RSRotate *rotate, const RSFilterRequest *request)
+recalculate_dims(RSRotate *rotate, gint previous_width, gint previous_height)
{
- RSFilter *previous = RS_FILTER(rotate)->previous;
- RSFilterResponse *response = rs_filter_get_size(previous, request);
- gint previous_width = rs_filter_response_get_width(response);
- gint previous_height = rs_filter_response_get_height(response);
- g_object_unref(response);
-
/* Bail out, if parent returns negative dimensions */
if ((previous_width < 0) || (previous_height < 0))
{
@@ -492,6 +486,17 @@
rotate->dirty = FALSE;
}
+static void
+recalculate(RSRotate *rotate, const RSFilterRequest *request)
+{
+ RSFilter *previous = RS_FILTER(rotate)->previous;
+ RSFilterResponse *response = rs_filter_get_size(previous, request);
+ gint previous_width = rs_filter_response_get_width(response);
+ gint previous_height = rs_filter_response_get_height(response);
+ g_object_unref(response);
+ recalculate_dims(rotate, previous_width, previous_height);
+}
+
static void turn_right_angle(RS_IMAGE16 *in, RS_IMAGE16 *out, gint start_y,
gint end_y, const int direction)
{
int srcp_offset, x, y, p;
Modified: trunk/src/rs-preview-widget.c
===================================================================
--- trunk/src/rs-preview-widget.c 2010-08-20 11:22:24 UTC (rev 3496)
+++ trunk/src/rs-preview-widget.c 2010-08-20 15:39:54 UTC (rev 3497)
@@ -560,6 +560,7 @@
preview->zoom_to_fit = zoom_to_fit;
GtkToggleAction *fit_action =
GTK_TOGGLE_ACTION(rs_core_action_group_get_action("ZommToFit"));
gtk_toggle_action_set_active(fit_action, zoom_to_fit);
+ rs_filter_set_recursive(RS_FILTER(preview->filter_input),
"demosaic-allow-downscale", preview->zoom_to_fit, NULL);
}
/**
@@ -654,6 +655,7 @@
g_assert(RS_IS_FILTER(filter));
preview->filter_input = filter;
+ rs_filter_set_recursive(RS_FILTER(preview->filter_input),
"demosaic-allow-downscale", preview->zoom_to_fit, NULL);
rs_filter_set_previous(preview->filter_resample[0],
preview->filter_input);
rs_filter_set_previous(preview->filter_resample[1],
preview->filter_input);
if (fast_filter)
_______________________________________________
Rawstudio-commit mailing list
[email protected]
http://rawstudio.org/cgi-bin/mailman/listinfo/rawstudio-commit