Author: post
Date: 2010-02-14 17:52:21 +0100 (Sun, 14 Feb 2010)
New Revision: 3229

Modified:
   trunk/librawstudio/rs-curve.c
   trunk/librawstudio/rs-curve.h
   trunk/src/rs-histogram.c
   trunk/src/rs-histogram.h
   trunk/src/rs-preview-widget.c
   trunk/src/rs-toolbox.c
   trunk/src/rs-toolbox.h
Log:
Use proper filter chain to calculate histogram and levels histogram.

Modified: trunk/librawstudio/rs-curve.c
===================================================================
--- trunk/librawstudio/rs-curve.c       2010-02-14 16:43:40 UTC (rev 3228)
+++ trunk/librawstudio/rs-curve.c       2010-02-14 16:52:21 UTC (rev 3229)
@@ -36,10 +36,11 @@
        guint size_timeout_helper;
 
        /* For drawing the histogram */
-       guint histogram_data[4][256];
+       guint histogram_data[256];
+       RSFilter *input;
        guchar *bg_buffer;
        RSColorTransform *rct;
-       RSSettings *settings;
+       RSColorSpace *display_color_space;
 
        gint last_width[2];
 };
@@ -119,8 +120,6 @@
        curve->spline = rs_spline_new(NULL, 0, NATURAL);
        curve->marker = -1.0;
        curve->bg_buffer = NULL;
-       curve->settings = rs_settings_new();
-       curve->settings->saturation = 0.0f; /* We want the histogram to be 
desaturated */
        curve->rct = rs_color_transform_new();
        rs_color_transform_set_gamma(curve->rct, GAMMA);
 
@@ -187,20 +186,85 @@
                curve->array_length = 0;
        }
 }
+#define LUM_PRECISION 15
+#define LUM_FIXED(a) ((guint)((a)*(1<<LUM_PRECISION)))
+#define RLUMF LUM_FIXED(0.212671f)
+#define GLUMF LUM_FIXED(0.715160f)
+#define BLUMF LUM_FIXED(0.072169f)
+#define HALFF LUM_FIXED(0.5f)
 
+static void 
+calculate_histogram(RSCurveWidget *curve)
+{
+       gint x, y;
+       
+       guint *hist = &curve->histogram_data[0];
+       /* Reset table */
+       memset(hist, 0x00, sizeof(guint)*256);
+
+       if (!curve->input)
+               return;
+
+       RSFilterRequest *request = rs_filter_request_new();
+       rs_filter_request_set_quick(RS_FILTER_REQUEST(request), FALSE);
+       rs_filter_param_set_object(RS_FILTER_PARAM(request), "colorspace", 
curve->display_color_space);
+               
+       RSFilterResponse *response = rs_filter_get_image8(curve->input, 
request);
+       g_object_unref(request);
+
+       GdkPixbuf *pixbuf = rs_filter_response_get_image8(response);
+       if (!pixbuf)
+               return;
+
+       const gint pix_width = gdk_pixbuf_get_n_channels(pixbuf);
+       const gint w = gdk_pixbuf_get_width(pixbuf);
+       const gint h = gdk_pixbuf_get_height(pixbuf);
+       for(y = 0; y < h; y++) 
+       {
+               guchar *i = GET_PIXBUF_PIXEL(pixbuf, 0, y);
+
+               for(x = 0; x < w ; x++)
+               {
+                       guchar r = i[R];
+                       guchar g = i[G];
+                       guchar b = i[B];
+                       guchar luma = (guchar)((RLUMF * (int)r + GLUMF * (int)g 
+ BLUMF * (int)b + HALFF) >> LUM_PRECISION);
+                       hist[luma]++;
+                       i += pix_width;
+               }
+       }
+       g_object_unref(pixbuf);
+       g_object_unref(response);
+}
+
 /**
+ * Set an image to base the histogram of
+ * @param curve A RSCurveWidget
+ * @param image An image
+ * @param display_color_space Colorspace to use to transform the input.
+ */
+void
+rs_curve_set_input(RSCurveWidget *curve, RSFilter* input, RSColorSpace 
*display_color_space)
+{
+       g_return_if_fail (RS_IS_CURVE_WIDGET(curve));
+       g_return_if_fail (RS_IS_FILTER(input));
+
+       curve->input = input;
+       curve->display_color_space = display_color_space;
+}
+
+/**
  * Draw a histogram in the background of the widget
  * @param curve A RSCurveWidget
  * @param image A image to sample from
  * @param setting Settings to use, curve and saturation will be ignored
  */
 void
-rs_curve_draw_histogram(RSCurveWidget *curve, RS_IMAGE16 *image, RSSettings 
*settings)
+rs_curve_draw_histogram(RSCurveWidget *curve)
 {
-       rs_settings_copy(settings, MASK_ALL-MASK_CURVE-MASK_SATURATION, 
curve->settings);
-       rs_color_transform_set_from_settings(curve->rct, curve->settings, 
MASK_ALL);
-       rs_color_transform_make_histogram(curve->rct, image, 
curve->histogram_data);
+       g_assert(RS_IS_CURVE_WIDGET(curve));
 
+       calculate_histogram(curve);
        if (curve->bg_buffer)
                g_free(curve->bg_buffer);
        curve->bg_buffer = NULL;
@@ -557,8 +621,8 @@
                        /* find the max value */
                        /* Except 0 and 255! */
                        for (i = 1; i < 255; i++)
-                               if (curve->histogram_data[3][i] > max)
-                                       max = curve->histogram_data[3][i];
+                               if (curve->histogram_data[i] > max)
+                                       max = curve->histogram_data[i];
 
                        /* Find height scale factor */
                        gfloat factor = (gfloat)(max+height)/(gfloat)height;
@@ -575,8 +639,8 @@
                                weight1 = 1.0 - (source-source1);
                                weight2 = 1.0 - weight1;
 
-                               hist[i] = (curve->histogram_data[3][1+source1] 
* weight1
-                                       + curve->histogram_data[3][1+source2] * 
weight2)/factor;
+                               hist[i] = (curve->histogram_data[1+source1] * 
weight1
+                                       + curve->histogram_data[1+source2] * 
weight2)/factor;
                        }
 
                        for (x = 0; x < width; x++)

Modified: trunk/librawstudio/rs-curve.h
===================================================================
--- trunk/librawstudio/rs-curve.h       2010-02-14 16:43:40 UTC (rev 3228)
+++ trunk/librawstudio/rs-curve.h       2010-02-14 16:52:21 UTC (rev 3229)
@@ -61,7 +61,7 @@
  * @param setting Settings to use, curve and saturation will be ignored
  */
 extern void
-rs_curve_draw_histogram(RSCurveWidget *curve, RS_IMAGE16 *image, RSSettings 
*settings);
+rs_curve_draw_histogram(RSCurveWidget *curve);
 
 /**
  * Add a knot to a curve widget
@@ -135,6 +135,15 @@
 extern gboolean
 rs_curve_widget_load(RSCurveWidget *curve, const gchar *filename);
 
+/**
+ * Set an image to base the histogram of
+ * @param curve A RSCurveWidget
+ * @param image An image
+ * @param display_color_space Colorspace to use to transform the input.
+ */
+extern void
+rs_curve_set_input(RSCurveWidget *curve, RSFilter* input, RSColorSpace 
*display_color_space);
+
 #define RS_CURVE_TYPE_WIDGET             (rs_curve_widget_get_type ())
 #define RS_CURVE_WIDGET(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), 
RS_CURVE_TYPE_WIDGET, RSCurveWidget))
 #define RS_CURVE_WIDGET_CLASS(obj)       (G_TYPE_CHECK_CLASS_CAST ((obj), 
RS_CURVE_WIDGET, RSCurveWidgetClass))

Modified: trunk/src/rs-histogram.c
===================================================================
--- trunk/src/rs-histogram.c    2010-02-14 16:43:40 UTC (rev 3228)
+++ trunk/src/rs-histogram.c    2010-02-14 16:52:21 UTC (rev 3229)
@@ -29,11 +29,11 @@
        gint width;
        gint height;
        GdkPixmap *blitter;
-       RS_IMAGE16 *image;
+       RSFilter *input;
        RSSettings *settings;
-       RSColorTransform *rct;
        guint input_samples[4][256];
        guint *output_samples[4];
+       RSColorSpace *display_color_space;
 };
 
 struct _RSHistogramWidgetClass
@@ -70,9 +70,8 @@
        hist->output_samples[1] = NULL;
        hist->output_samples[2] = NULL;
        hist->output_samples[3] = NULL;
-       hist->image = NULL;
+       hist->input = NULL;
        hist->settings = NULL;
-       hist->rct = rs_color_transform_new();
        hist->blitter = NULL;
 
        g_signal_connect(G_OBJECT(hist), "size-allocate", 
G_CALLBACK(size_allocate), NULL);
@@ -122,40 +121,74 @@
 }
 
 /**
- * Set an image to base the histogram from
+ * Set an image to base the histogram of
  * @param histogram A RSHistogramWidget
- * @param image An image
+ * @param input An input RSFilter
  */
 void
-rs_histogram_set_image(RSHistogramWidget *histogram, RS_IMAGE16 *image)
+rs_histogram_set_input(RSHistogramWidget *histogram, RSFilter* input, 
RSColorSpace *display_color_space)
 {
        g_return_if_fail (RS_IS_HISTOGRAM_WIDGET(histogram));
-       g_return_if_fail (image);
+       g_return_if_fail (RS_IS_FILTER(input));
 
-       histogram->image = image;
+       histogram->input = input;
+       histogram->display_color_space = display_color_space;
 
        rs_histogram_redraw(histogram);
 }
 
-/**
- * Set a RSSettings to use
- * @param histogram A RSHistogramWidget
- * @param settings A RSSettings object to use
- */
-void
-rs_histogram_set_settings(RSHistogramWidget *histogram, RSSettings *settings)
+#define LUM_PRECISION 15
+#define LUM_FIXED(a) ((guint)((a)*(1<<LUM_PRECISION)))
+#define RLUMF LUM_FIXED(0.212671f)
+#define GLUMF LUM_FIXED(0.715160f)
+#define BLUMF LUM_FIXED(0.072169f)
+#define HALFF LUM_FIXED(0.5f)
+
+static void 
+calculate_histogram(RSHistogramWidget *histogram)
 {
-       g_return_if_fail (RS_IS_HISTOGRAM_WIDGET(histogram));
-       g_return_if_fail (RS_IS_SETTINGS(settings));
+       gint x, y;
+       
+       guint *hist = &histogram->input_samples[0][0];
+       /* Reset table */
+       memset(hist, 0x00, sizeof(guint)*4*256);
 
-       if (histogram->settings)
-               g_object_unref(histogram->settings);
+       if (!histogram->input)
+               return;
 
-       histogram->settings = g_object_ref(settings);
+       RSFilterRequest *request = rs_filter_request_new();
+       rs_filter_request_set_quick(RS_FILTER_REQUEST(request), FALSE);
+       rs_filter_param_set_object(RS_FILTER_PARAM(request), "colorspace", 
histogram->display_color_space);
+               
+       RSFilterResponse *response = rs_filter_get_image8(histogram->input, 
request);
+       g_object_unref(request);
 
-       rs_color_transform_set_from_settings(histogram->rct, 
histogram->settings, MASK_ALL);
+       GdkPixbuf *pixbuf = rs_filter_response_get_image8(response);
+       if (!pixbuf)
+               return;
 
-       rs_histogram_redraw(histogram);
+       const gint pix_width = gdk_pixbuf_get_n_channels(pixbuf);
+       const gint w = gdk_pixbuf_get_width(pixbuf);
+       const gint h = gdk_pixbuf_get_height(pixbuf);
+       for(y = 0; y < h; y++) 
+       {
+               guchar *i = GET_PIXBUF_PIXEL(pixbuf, 0, y);
+
+               for(x = 0; x < w ; x++)
+               {
+                       guchar r = i[R];
+                       guchar g = i[G];
+                       guchar b = i[B];
+                       hist[r]++;
+                       hist[g+256]++;
+                       hist[b+512]++;
+                       guchar luma = (guchar)((RLUMF * (int)r + GLUMF * (int)g 
+ BLUMF * (int)b + HALFF) >> LUM_PRECISION);
+                       hist[luma+768]++;
+                       i += pix_width;
+               }
+       }
+       g_object_unref(pixbuf);
+       g_object_unref(response);
 }
 
 /**
@@ -175,7 +208,7 @@
 
        widget = GTK_WIDGET(histogram);
        /* Draw histogram if we got everything needed */
-       if (histogram->rct && histogram->image && GTK_WIDGET_VISIBLE(widget) && 
GTK_WIDGET_REALIZED(widget))
+       if (histogram->input && GTK_WIDGET_VISIBLE(widget) && 
GTK_WIDGET_REALIZED(widget))
        {
                const static GdkColor bg = {0, 0x9900, 0x9900, 0x9900};
                const static GdkColor lines = {0, 0x7700, 0x7700, 0x7700};
@@ -198,7 +231,7 @@
                gdk_draw_line(histogram->blitter, gc, histogram->width*0.75, 0, 
histogram->width*0.75, histogram->height-1);
 
                /* Sample some data */
-               rs_color_transform_make_histogram(histogram->rct, 
histogram->image, histogram->input_samples);
+               calculate_histogram(histogram);
 
                /* Interpolate data for correct width and find maximum value */
                max = 0;

Modified: trunk/src/rs-histogram.h
===================================================================
--- trunk/src/rs-histogram.h    2010-02-14 16:43:40 UTC (rev 3228)
+++ trunk/src/rs-histogram.h    2010-02-14 16:52:21 UTC (rev 3229)
@@ -15,18 +15,13 @@
 extern GtkWidget *rs_histogram_new();
 
 /**
- * Set an image to base the histogram from
+ * Set an image to base the histogram of
  * @param histogram A RSHistogramWidget
  * @param image An image
+ * @param display_color_space Colorspace to use to transform the input.
  */
-extern void rs_histogram_set_image(RSHistogramWidget *histogram, RS_IMAGE16 
*image);
+extern void rs_histogram_set_input(RSHistogramWidget *histogram, RSFilter* 
input, RSColorSpace *display_color_space);
 
-/**
- * Set a RSSettings to use
- * @param histogram A RSHistogramWidget
- * @param settings A RSSettings object to use
- */
-extern void rs_histogram_set_settings(RSHistogramWidget *histogram, RSSettings 
*settings);
 
 /**
  * Redraw a RSHistogramWidget

Modified: trunk/src/rs-preview-widget.c
===================================================================
--- trunk/src/rs-preview-widget.c       2010-02-14 16:43:40 UTC (rev 3228)
+++ trunk/src/rs-preview-widget.c       2010-02-14 16:52:21 UTC (rev 3229)
@@ -189,6 +189,7 @@
        RSFilter *navigator_filter_crop;
        RSFilter *navigator_filter_cache;
        RSFilter *navigator_filter_cache2;
+       RSFilter *navigator_filter_cache3;
        RSFilter *navigator_filter_scale2;
        RSFilter *navigator_filter_dcp;
        RSFilter *navigator_transform_display;
@@ -400,7 +401,8 @@
        preview->navigator_filter_scale2 = rs_filter_new("RSResample", 
preview->navigator_filter_rotate);
        preview->navigator_filter_cache2 = rs_filter_new("RSCache", 
preview->navigator_filter_scale2);
        preview->navigator_filter_dcp = rs_filter_new("RSDcp", 
preview->navigator_filter_cache2);
-       preview->navigator_transform_display = 
rs_filter_new("RSColorspaceTransform", preview->navigator_filter_dcp);
+       preview->navigator_filter_cache3 = rs_filter_new("RSCache", 
preview->navigator_filter_dcp);
+       preview->navigator_transform_display = 
rs_filter_new("RSColorspaceTransform", preview->navigator_filter_cache3);
        preview->navigator_filter_end = preview->navigator_transform_display;
        
        /* We'll take care of double buffering ourself */
@@ -434,6 +436,8 @@
        preview = RS_PREVIEW_WIDGET(widget);
        preview->toolbox = RS_TOOLBOX(toolbox);
 
+       rs_toolbox_set_histogram_input(preview->toolbox, 
preview->navigator_filter_end, preview->display_color_space);
+
        return widget;
 }
 
@@ -529,9 +533,6 @@
 
                /* Build navigator */
                rs_filter_set_recursive(preview->navigator_filter_end,
-                       "bounding-box", TRUE,
-                       "width", NAVIGATOR_WIDTH,
-                       "height", NAVIGATOR_HEIGHT,
                        "orientation", preview->photo->orientation,
                        "rectangle", rs_photo_get_crop(preview->photo),
                        "angle", rs_photo_get_angle(preview->photo),
@@ -622,6 +623,14 @@
                        rs_filter_set_recursive(preview->filter_end[view], 
"settings", preview->photo->settings[preview->snapshot[view]], NULL);
                }
        }
+
+       rs_filter_set_recursive(preview->navigator_filter_end,
+               "bounding-box", TRUE,
+               "width", NAVIGATOR_WIDTH,
+               "height", NAVIGATOR_HEIGHT,
+               NULL);
+
+       rs_toolbox_set_histogram_input(preview->toolbox, 
preview->navigator_filter_end, preview->display_color_space);
 }
 
 /**
@@ -673,6 +682,7 @@
 //     if (preview->display_color_space)
 //             g_object_unref(preview->display_color_space);
 //     preview->display_color_space = rs_color_space_icc_new_from_icc(profile);
+//     rs_toolbox_set_histogram_input(preview->toolbox, 
preview->navigator_filter_end, preview->display_color_space);
 }
 
 /**

Modified: trunk/src/rs-toolbox.c
===================================================================
--- trunk/src/rs-toolbox.c      2010-02-14 16:43:40 UTC (rev 3228)
+++ trunk/src/rs-toolbox.c      2010-02-14 16:52:21 UTC (rev 3229)
@@ -89,8 +89,8 @@
        GtkWidget *transforms;
        gint selected_snapshot;
        RS_PHOTO *photo;
+       RSFilter* histogram_input;
        GtkWidget *histogram;
-       RS_IMAGE16 *histogram_dataset;
 
        rs_profile_camera last_camera;
 
@@ -216,9 +216,6 @@
        self->transforms = new_transform(self, TRUE);
        gtk_box_pack_start(self->toolbox, self->transforms, FALSE, FALSE, 0);
 
-       /* Initialize this to some dummy image to keep it simple */
-       self->histogram_dataset = rs_image16_new(1,1,4,4);
-
        /* Histogram */
        self->histogram = rs_histogram_new();
        if (!rs_conf_get_integer(CONF_HISTHEIGHT, &height))
@@ -785,13 +782,22 @@
        if (!toolbox->mute_from_photo)
                toolbox_copy_from_photo(toolbox, snapshot, mask, photo);
 
+       
        if (mask)
-               /* Update histogram */
-               
rs_histogram_set_settings(RS_HISTOGRAM_WIDGET(toolbox->histogram), 
photo->settings[toolbox->selected_snapshot]);
-
-       if (mask ^ MASK_CURVE)
-               /* Update histogram in curve editor */
-               
rs_curve_draw_histogram(RS_CURVE_WIDGET(toolbox->curve[snapshot]), 
toolbox->histogram_dataset, photo->settings[snapshot]);
+       {
+               rs_filter_set_recursive(toolbox->histogram_input,
+                       "bounding-box", TRUE,
+                       "orientation", photo->orientation,
+                       "rectangle", rs_photo_get_crop(photo),
+                       "angle", rs_photo_get_angle(photo),
+                       "settings", photo->settings[toolbox->selected_snapshot],
+                  NULL);
+       }
+       /* Update histogram */
+       rs_histogram_redraw(RS_HISTOGRAM_WIDGET(toolbox->histogram));
+       
+       /* Update histogram in curve editor */
+       rs_curve_draw_histogram(RS_CURVE_WIDGET(toolbox->curve[snapshot]));
 }
 
 static void
@@ -799,14 +805,6 @@
 {
        RSToolbox *toolbox = RS_TOOLBOX(user_data);
 
-       g_object_unref(toolbox->histogram_dataset);
-
-       toolbox->histogram_dataset = rs_image16_transform(photo->input, NULL,
-               NULL, NULL, photo->crop, 250, 250,
-               TRUE, -1.0f, photo->angle, photo->orientation, NULL);
-
-       rs_histogram_set_image(RS_HISTOGRAM_WIDGET(toolbox->histogram), 
toolbox->histogram_dataset);
-
        /* Force update of histograms */
        photo_settings_changed(photo, MASK_ALL, toolbox);
 
@@ -946,6 +944,7 @@
                g_object_weak_ref(G_OBJECT(toolbox->photo), (GWeakNotify) 
photo_finalized, toolbox);
                g_signal_connect(G_OBJECT(toolbox->photo), "settings-changed", 
G_CALLBACK(photo_settings_changed), toolbox);
                g_signal_connect(G_OBJECT(toolbox->photo), "spatial-changed", 
G_CALLBACK(photo_spatial_changed), toolbox);
+               g_signal_connect(G_OBJECT(toolbox->photo), "profile-changed", 
G_CALLBACK(photo_settings_changed), toolbox);
 
                for(snapshot=0;snapshot<3;snapshot++)
                {
@@ -1045,3 +1044,16 @@
 {
        gtk_notebook_set_page(GTK_NOTEBOOK(toolbox->notebook), snapshot);
 }
+
+void rs_toolbox_set_histogram_input(RSToolbox * toolbox, RSFilter *input, 
RSColorSpace *display_color_space)
+{
+       int i;
+       g_assert(RS_IS_TOOLBOX(toolbox));
+       g_assert(RS_IS_FILTER(input));
+
+       toolbox->histogram_input = input;
+       rs_histogram_set_input(RS_HISTOGRAM_WIDGET(toolbox->histogram), input, 
display_color_space);
+       for( i = 0 ; i < 3 ; i++)
+               rs_curve_set_input(RS_CURVE_WIDGET(toolbox->curve[i]), input, 
display_color_space);
+       
+}

Modified: trunk/src/rs-toolbox.h
===================================================================
--- trunk/src/rs-toolbox.h      2010-02-14 16:43:40 UTC (rev 3228)
+++ trunk/src/rs-toolbox.h      2010-02-14 16:52:21 UTC (rev 3229)
@@ -59,6 +59,9 @@
 extern void
 rs_toolbox_set_selected_snapshot(RSToolbox *toolbox, const gint snapshot);
 
+extern void
+rs_toolbox_set_histogram_input(RSToolbox *toolbox, RSFilter *input, 
RSColorSpace *display_color_space);
+
 G_END_DECLS
 
 #endif /* RS_TOOLBOX_H */


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

Reply via email to