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