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

Reply via email to