[gthumb/ext] [adjust colors] added hue and lightness, speed improvements
- From: Paolo Bacchilega <paobac src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gthumb/ext] [adjust colors] added hue and lightness, speed improvements
- Date: Sun, 13 Sep 2009 21:13:42 +0000 (UTC)
commit 11b6e7061adca849d38bd4ed0488beca43d796d9
Author: Paolo Bacchilega <paobac src gnome org>
Date: Sun Sep 13 13:03:53 2009 +0200
[adjust colors] added hue and lightness, speed improvements
.../file_tools/data/ui/adjust-colors-options.ui | 35 ++-
.../file_tools/gth-file-tool-adjust-colors.c | 465 +++++++++++++-------
gthumb/Makefile.am | 2 +
gthumb/pixbuf-cache.c | 74 +++
gthumb/pixbuf-cache.h | 50 +++
5 files changed, 452 insertions(+), 174 deletions(-)
---
diff --git a/extensions/file_tools/data/ui/adjust-colors-options.ui b/extensions/file_tools/data/ui/adjust-colors-options.ui
index 4d6e8d2..7160faa 100644
--- a/extensions/file_tools/data/ui/adjust-colors-options.ui
+++ b/extensions/file_tools/data/ui/adjust-colors-options.ui
@@ -18,7 +18,7 @@
<child>
<object class="GtkTable" id="table1">
<property name="visible">True</property>
- <property name="n_rows">5</property>
+ <property name="n_rows">6</property>
<property name="n_columns">2</property>
<property name="column_spacing">6</property>
<property name="row_spacing">6</property>
@@ -104,6 +104,29 @@
</packing>
</child>
<child>
+ <object class="GtkHBox" id="gamma_hbox">
+ <property name="visible">True</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Gamma:</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
<object class="GtkHBox" id="hue_hbox">
<property name="visible">True</property>
<child>
@@ -131,7 +154,7 @@
</packing>
</child>
<child>
- <object class="GtkHBox" id="gamma_hbox">
+ <object class="GtkHBox" id="lightness_hbox">
<property name="visible">True</property>
<child>
<placeholder/>
@@ -140,16 +163,20 @@
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
+ <property name="top_attach">5</property>
+ <property name="bottom_attach">6</property>
</packing>
</child>
<child>
- <object class="GtkLabel" id="label4">
+ <object class="GtkLabel" id="label6">
<property name="visible">True</property>
<property name="xalign">0</property>
- <property name="label" translatable="yes">_Intensity:</property>
+ <property name="label" translatable="yes">_Lightness:</property>
<property name="use_underline">True</property>
</object>
<packing>
+ <property name="top_attach">5</property>
+ <property name="bottom_attach">6</property>
<property name="x_options">GTK_FILL</property>
</packing>
</child>
diff --git a/extensions/file_tools/gth-file-tool-adjust-colors.c b/extensions/file_tools/gth-file-tool-adjust-colors.c
index 03f632e..1fa88b8 100644
--- a/extensions/file_tools/gth-file-tool-adjust-colors.c
+++ b/extensions/file_tools/gth-file-tool-adjust-colors.c
@@ -34,168 +34,236 @@
static gpointer parent_class = NULL;
-struct _GthFileToolAdjustColorsPrivate {
- GdkPixbuf *src_pixbuf;
- GdkPixbuf *dest_pixbuf;
- GtkBuilder *builder;
- GtkAdjustment *brightness_adj;
- GtkAdjustment *contrast_adj;
- GtkAdjustment *saturation_adj;
- GtkAdjustment *gamma_adj;
- GthTask *pixbuf_task;
- guint apply_event;
-};
-
+/* -- gimpcolorspace -- */
-typedef struct {
- double gamma[5];
- int low_input[5];
- int high_input[5];
- int low_output[5];
- int high_output[5];
-} Levels;
+static void
+gimp_rgb_to_hls_int (gint *red,
+ gint *green,
+ gint *blue)
+{
+ gint r, g, b;
+ gdouble h, l, s;
+ gint min, max;
+ gint delta;
+
+ r = *red;
+ g = *green;
+ b = *blue;
+
+ if (r > g)
+ {
+ max = MAX (r, b);
+ min = MIN (g, b);
+ }
+ else
+ {
+ max = MAX (g, b);
+ min = MIN (r, b);
+ }
+
+ l = (max + min) / 2.0;
+
+ if (max == min)
+ {
+ s = 0.0;
+ h = 0.0;
+ }
+ else
+ {
+ delta = (max - min);
+
+ if (l < 128)
+ s = 255 * (gdouble) delta / (gdouble) (max + min);
+ else
+ s = 255 * (gdouble) delta / (gdouble) (511 - max - min);
+
+ if (r == max)
+ h = (g - b) / (gdouble) delta;
+ else if (g == max)
+ h = 2 + (b - r) / (gdouble) delta;
+ else
+ h = 4 + (r - g) / (gdouble) delta;
+
+ h = h * 42.5;
+
+ if (h < 0)
+ h += 255;
+ else if (h > 255)
+ h -= 255;
+ }
+
+ *red = h;
+ *green = l;
+ *blue = s;
+}
-typedef struct {
- GtkWidget *viewer_page;
- Levels levels;
- double gamma;
- double brightness;
- double contrast;
- double saturation;
-} AdjustData;
+static gint
+gimp_hls_value (gdouble n1,
+ gdouble n2,
+ gdouble hue)
+{
+ gdouble value;
+
+ if (hue > 255)
+ hue -= 255;
+ else if (hue < 0)
+ hue += 255;
+ if (hue < 42.5)
+ value = n1 + (n2 - n1) * (hue / 42.5);
+ else if (hue < 127.5)
+ value = n2;
+ else if (hue < 170)
+ value = n1 + (n2 - n1) * ((170 - hue) / 42.5);
+ else
+ value = n1;
+
+ return (gint) (value * 255);
+}
static void
-levels_init (Levels *levels,
- double brightness,
- double contrast,
- double gamma)
+gimp_hls_to_rgb_int (gint *hue,
+ gint *lightness,
+ gint *saturation)
{
- int channel;
- double slant;
- double value;
-
- for (channel = 0; channel < MAX_N_CHANNELS + 1; channel++) {
- levels->gamma[channel] = 1.0;
- levels->low_input[channel] = 0;
- levels->high_input[channel] = 255;
- levels->low_output[channel] = 0;
- levels->high_output[channel] = 255;
- }
-
- /* */
-
- levels->gamma[0] = pow (10, - (gamma / 100.0));
+ gdouble h, l, s;
+ gdouble m1, m2;
+
+ h = *hue;
+ l = *lightness;
+ s = *saturation;
+
+ if (s == 0)
+ {
+ /* achromatic case */
+ *hue = l;
+ *lightness = l;
+ *saturation = l;
+ }
+ else
+ {
+ if (l < 128)
+ m2 = (l * (255 + s)) / 65025.0;
+ else
+ m2 = (l + s - (l * s) / 255.0) / 255.0;
+
+ m1 = (l / 127.5) - m2;
+
+ /* chromatic case */
+ *hue = gimp_hls_value (m1, m2, h + 85);
+ *lightness = gimp_hls_value (m1, m2, h);
+ *saturation = gimp_hls_value (m1, m2, h - 85);
+ }
+}
- brightness = brightness / 127.0 / 2.0;
- contrast = contrast / 127.0;
- slant = tan ((contrast + 1) * G_PI_4);
- if (brightness >= 0) {
- value = -0.5 * slant + brightness * slant + 0.5;
- if (value < 0.0) {
- value = 0.0;
+/* -- hue, lightness, saturation -- */
- /* this slightly convoluted math follows by inverting the
- * calculation of the brightness/contrast LUT in base/lut-funcs.h */
- levels->low_input[0] = 255.0 * (- brightness * slant + 0.5 * slant - 0.5) / (slant - brightness * slant);
- }
+typedef enum {
+ GIMP_ALL_HUES,
+ GIMP_RED_HUES,
+ GIMP_YELLOW_HUES,
+ GIMP_GREEN_HUES,
+ GIMP_CYAN_HUES,
+ GIMP_BLUE_HUES,
+ GIMP_MAGENTA_HUES
+} GimpHueRange;
- levels->low_output[0] = 255.0 * value;
- value = 0.5 * slant + 0.5;
- if (value > 1.0) {
- value = 1.0;
- levels->high_input[0] = 255.0 * (- brightness * slant + 0.5 * slant + 0.5) / (slant - brightness * slant);
- }
+typedef struct {
+ double hue[7];
+ double lightness[7];
+ double saturation[7];
+ int hue_transfer[6][256];
+ int lightness_transfer[6][256];
+ int saturation_transfer[6][256];
+} HueSaturationData;
- levels->high_output[0] = 255.0 * value;
- }
- else {
- value = 0.5 - 0.5 * slant;
- if (value < 0.0) {
- value = 0.0;
- levels->low_input[0] = 255.0 * (0.5 * slant - 0.5) / (slant + brightness * slant);
- }
- levels->low_output[0] = 255.0 * value;
+static void
+hue_saturation_data_init (HueSaturationData *hs)
+{
+ GimpHueRange partition;
- value = slant * brightness + slant * 0.5 + 0.5;
- if (value > 1.0) {
- value = 1.0;
- levels->high_input[0] = 255.0 * (0.5 * slant + 0.5) / (slant + brightness * slant);
- }
+ g_return_if_fail (hs != NULL);
- levels->high_output[0] = 255.0 * value;
+ for (partition = GIMP_ALL_HUES; partition <= GIMP_MAGENTA_HUES; partition++) {
+ hs->hue[partition] = 0.0;
+ hs->lightness[partition] = 0.0;
+ hs->saturation[partition] = 0.0;
}
}
static void
-adjust_colors_init (GthPixbufTask *pixop)
+hue_saturation_calculate_transfers (HueSaturationData *hs)
{
- /* AdjustData *data = pixop->data; FIXME: delte if not used */
-}
-
-
-static guchar
-adjust_levels_func (guchar value,
- Levels *levels,
- guchar lightness,
- double saturation,
- int channel)
-{
- double inten;
- int j;
-
- inten = value;
-
- /* For color images this runs through the loop with j = channel + 1
- * the first time and j = 0 the second time
- *
- * For bw images this runs through the loop with j = 0 the first and
- * only time
- */
- for (j = channel + 1; j >= 0; j -= (channel + 1)) {
- inten /= 255.0;
-
- /* determine input intensity */
-
- if (levels->high_input[j] != levels->low_input[j])
- inten = (255.0 * inten - levels->low_input[j]) /
- (levels->high_input[j] - levels->low_input[j]);
- else
- inten = 255.0 * inten - levels->low_input[j];
+ int value;
+ int hue;
+ int i;
+
+ g_return_if_fail (hs != NULL);
+
+ /* Calculate transfers */
+ for (hue = 0; hue < 6; hue++)
+ for (i = 0; i < 256; i++) {
+ /* Hue */
+ value = (hs->hue[0] + hs->hue[hue + 1]) * 255.0 / 360.0;
+ if ((i + value) < 0)
+ hs->hue_transfer[hue][i] = 255 + (i + value);
+ else if ((i + value) > 255)
+ hs->hue_transfer[hue][i] = i + value - 255;
+ else
+ hs->hue_transfer[hue][i] = i + value;
- if (levels->gamma[j] != 0.0) {
- if (inten >= 0.0)
- inten = pow ( inten, (1.0 / levels->gamma[j]));
+ /* Lightness */
+ value = (hs->lightness[0] + hs->lightness[hue + 1]) * 127.0 / 100.0;
+ value = CLAMP (value, -255, 255);
+ if (value < 0)
+ hs->lightness_transfer[hue][i] = (unsigned char) ((i * (255 + value)) / 255);
else
- inten = -pow (-inten, (1.0 / levels->gamma[j]));
+ hs->lightness_transfer[hue][i] = (unsigned char) (i + ((255 - i) * value) / 255);
+
+ /* Saturation */
+ value = (hs->saturation[0] + hs->saturation[hue + 1]) * 255.0 / 100.0;
+ value = CLAMP (value, -255, 255);
+ hs->saturation_transfer[hue][i] = CLAMP ((i * (255 + value)) / 255, 0, 255);
}
+}
- inten = (saturation * lightness) + ((1.0 - saturation) * inten);
- /* determine the output intensity */
+/* --- */
- if (levels->high_output[j] >= levels->low_output[j])
- inten = inten * (levels->high_output[j] - levels->low_output[j]) +
- levels->low_output[j];
- else if (levels->high_output[j] < levels->low_output[j])
- inten = levels->low_output[j] - inten *
- (levels->low_output[j] - levels->high_output[j]);
- }
- if (inten < 0.0)
- inten = 0.0;
- else if (inten > 255.0)
- inten = 255.0;
+struct _GthFileToolAdjustColorsPrivate {
+ GdkPixbuf *src_pixbuf;
+ GdkPixbuf *dest_pixbuf;
+ GtkBuilder *builder;
+ GtkAdjustment *gamma_adj;
+ GtkAdjustment *brightness_adj;
+ GtkAdjustment *contrast_adj;
+ GtkAdjustment *saturation_adj;
+ GtkAdjustment *hue_adj;
+ GtkAdjustment *lightness_adj;
+ GthTask *pixbuf_task;
+ guint apply_event;
+};
+
- return (guchar) inten;
-}
+typedef struct {
+ GtkWidget *viewer_page;
+ double gamma;
+ double brightness;
+ double contrast;
+ double saturation;
+ double hue;
+ double lightness;
+ PixbufCache *cache;
+ HueSaturationData *hs;
+} AdjustData;
static guchar
@@ -227,52 +295,100 @@ gamma_correction (guchar original,
static void
-adjust_colors_step (GthPixbufTask *pixop)
+adjust_colors_init (GthPixbufTask *pixop)
{
AdjustData *data = pixop->data;
- guchar min, max, lightness;
- pixop->dest_pixel[RED_PIX] = pixop->src_pixel[RED_PIX];
- pixop->dest_pixel[GREEN_PIX] = pixop->src_pixel[GREEN_PIX];
- pixop->dest_pixel[BLUE_PIX] = pixop->src_pixel[BLUE_PIX];
- if (pixop->has_alpha)
- pixop->dest_pixel[ALPHA_PIX] = pixop->src_pixel[ALPHA_PIX];
+ data->hs = g_new (HueSaturationData, 1);
+ hue_saturation_data_init (data->hs);
+ data->hs->hue[GIMP_ALL_HUES] = data->hue /* -180.0 ==> 180.0 */;
+ data->hs->lightness[GIMP_ALL_HUES] = data->lightness /* -100.0 ==> 100.0 */;
+ data->hs->saturation[GIMP_ALL_HUES] = data->saturation * (- 100.0) /* -100.0 ==> 100.0 */;
+ hue_saturation_calculate_transfers (data->hs);
- /* intensitiy / gamma correction */
+ data->cache = pixbuf_cache_new ();
+}
- pixop->dest_pixel[RED_PIX] = gamma_correction (pixop->dest_pixel[RED_PIX], data->gamma);
- pixop->dest_pixel[GREEN_PIX] = gamma_correction (pixop->dest_pixel[GREEN_PIX], data->gamma);
- pixop->dest_pixel[BLUE_PIX] = gamma_correction (pixop->dest_pixel[BLUE_PIX], data->gamma);
- /* brightness */
+static void
+hue_saturation_step (GthPixbufTask *pixop)
+{
+ AdjustData *data = pixop->data;
+ HueSaturationData *hs = data->hs;
+ int r, g, b, hue_idx;
+
+ r = pixop->dest_pixel[RED_PIX];
+ g = pixop->dest_pixel[GREEN_PIX];
+ b = pixop->dest_pixel[BLUE_PIX];
+
+ gimp_rgb_to_hls_int (&r, &g, &b);
+
+ if (r < 43)
+ hue_idx = 0;
+ else if (r < 85)
+ hue_idx = 1;
+ else if (r < 128)
+ hue_idx = 2;
+ else if (r < 171)
+ hue_idx = 3;
+ else if (r < 213)
+ hue_idx = 4;
+ else
+ hue_idx = 5;
- pixop->dest_pixel[RED_PIX] = interpolate_value (pixop->dest_pixel[RED_PIX], 0, data->brightness);
- pixop->dest_pixel[GREEN_PIX] = interpolate_value (pixop->dest_pixel[GREEN_PIX], 0, data->brightness);
- pixop->dest_pixel[BLUE_PIX] = interpolate_value (pixop->dest_pixel[BLUE_PIX], 0, data->brightness);
+ r = hs->hue_transfer[hue_idx][r];
+ g = hs->lightness_transfer[hue_idx][g];
+ b = hs->saturation_transfer[hue_idx][b];
- /* contrast */
+ gimp_hls_to_rgb_int (&r, &g, &b);
- pixop->dest_pixel[RED_PIX] = interpolate_value (pixop->dest_pixel[RED_PIX], 127, data->contrast);
- pixop->dest_pixel[GREEN_PIX] = interpolate_value (pixop->dest_pixel[GREEN_PIX], 127, data->contrast);
- pixop->dest_pixel[BLUE_PIX] = interpolate_value (pixop->dest_pixel[BLUE_PIX], 127, data->contrast);
+ pixop->dest_pixel[RED_PIX] = r;
+ pixop->dest_pixel[GREEN_PIX] = g;
+ pixop->dest_pixel[BLUE_PIX] = b;
+}
+
+
+static void
+adjust_colors_step (GthPixbufTask *pixop)
+{
+ AdjustData *data = pixop->data;
+ int channel;
+
+ if (pixop->has_alpha)
+ pixop->dest_pixel[ALPHA_PIX] = pixop->src_pixel[ALPHA_PIX];
+ for (channel = RED_PIX; channel <= BLUE_PIX; channel++) {
+ pixop->dest_pixel[channel] = pixop->src_pixel[channel];
+ if (! pixbuf_cache_get (data->cache, channel + 1, &pixop->dest_pixel[channel])) {
+ pixop->dest_pixel[channel] = gamma_correction (pixop->dest_pixel[channel], data->gamma);
+ pixop->dest_pixel[channel] = interpolate_value (pixop->dest_pixel[channel], 0, data->brightness);
+ pixop->dest_pixel[channel] = interpolate_value (pixop->dest_pixel[channel], 127, data->contrast);
+ pixbuf_cache_set (data->cache, channel + 1, pixop->src_pixel[channel], pixop->dest_pixel[channel]);
+ }
+ }
+
+#if 1
+ if ((data->saturation != 0.0) || (data->hue != 0.0) || (data->lightness != 0))
+ hue_saturation_step (pixop);
+#endif
+
+#if 0
/* saturation */
- max = MAX (pixop->dest_pixel[RED_PIX], pixop->dest_pixel[GREEN_PIX]);
- max = MAX (max, pixop->dest_pixel[BLUE_PIX]);
- min = MIN (pixop->dest_pixel[RED_PIX], pixop->dest_pixel[GREEN_PIX]);
- min = MIN (min, pixop->dest_pixel[BLUE_PIX]);
- lightness = (max + min) / 2;
+ if (data->saturation != 0.0) {
+ guchar min, max, lightness;
- pixop->dest_pixel[RED_PIX] = interpolate_value (pixop->dest_pixel[RED_PIX], lightness, data->saturation);
- pixop->dest_pixel[GREEN_PIX] = interpolate_value (pixop->dest_pixel[GREEN_PIX], lightness, data->saturation);
- pixop->dest_pixel[BLUE_PIX] = interpolate_value (pixop->dest_pixel[BLUE_PIX], lightness, data->saturation);
+ max = MAX (pixop->dest_pixel[RED_PIX], pixop->dest_pixel[GREEN_PIX]);
+ max = MAX (max, pixop->dest_pixel[BLUE_PIX]);
+ min = MIN (pixop->dest_pixel[RED_PIX], pixop->dest_pixel[GREEN_PIX]);
+ min = MIN (min, pixop->dest_pixel[BLUE_PIX]);
+ lightness = (max + min) / 2;
- /*pixop->dest_pixel[RED_PIX] = adjust_levels_func (pixop->src_pixel[RED_PIX], &data->levels, lightness, data->saturation, RED_PIX);
- pixop->dest_pixel[GREEN_PIX] = adjust_levels_func (pixop->src_pixel[GREEN_PIX], &data->levels, lightness, data->saturation, GREEN_PIX);
- pixop->dest_pixel[BLUE_PIX] = adjust_levels_func (pixop->src_pixel[BLUE_PIX], &data->levels, lightness, data->saturation, BLUE_PIX);
- if (pixop->has_alpha)
- pixop->dest_pixel[ALPHA_PIX] = pixop->src_pixel[ALPHA_PIX];*/
+ pixop->dest_pixel[RED_PIX] = interpolate_value (pixop->dest_pixel[RED_PIX], lightness, data->saturation);
+ pixop->dest_pixel[GREEN_PIX] = interpolate_value (pixop->dest_pixel[GREEN_PIX], lightness, data->saturation);
+ pixop->dest_pixel[BLUE_PIX] = interpolate_value (pixop->dest_pixel[BLUE_PIX], lightness, data->saturation);
+ }
+#endif
}
@@ -286,6 +402,8 @@ adjust_colors_release (GthPixbufTask *pixop,
gth_image_viewer_page_set_pixbuf (GTH_IMAGE_VIEWER_PAGE (data->viewer_page), pixop->dest, TRUE);
g_object_unref (data->viewer_page);
+ pixbuf_cache_free (data->cache);
+ g_free (data->hs);
g_free (data);
}
@@ -382,15 +500,12 @@ apply_cb (gpointer user_data)
data = g_new0 (AdjustData, 1);
data->viewer_page = g_object_ref (gth_browser_get_viewer_page (GTH_BROWSER (window)));
- levels_init (&data->levels,
- gtk_adjustment_get_value (self->priv->brightness_adj),
- gtk_adjustment_get_value (self->priv->contrast_adj),
- gtk_adjustment_get_value (self->priv->gamma_adj));
-
data->gamma = pow (10, - (gtk_adjustment_get_value (self->priv->gamma_adj) / 100.0));
- data->brightness = gtk_adjustment_get_value (self->priv->brightness_adj) / 100.0;
- data->contrast = gtk_adjustment_get_value (self->priv->contrast_adj) / 100.0;
- data->saturation = gtk_adjustment_get_value (self->priv->saturation_adj) / 100.0;
+ data->brightness = gtk_adjustment_get_value (self->priv->brightness_adj) / 100.0 * -1.0;
+ data->contrast = gtk_adjustment_get_value (self->priv->contrast_adj) / 100.0 * -1.0;
+ data->saturation = gtk_adjustment_get_value (self->priv->saturation_adj) / 100.0 * -1.0;
+ data->hue = gtk_adjustment_get_value (self->priv->hue_adj);
+ data->lightness = gtk_adjustment_get_value (self->priv->lightness_adj);
self->priv->pixbuf_task = gth_pixbuf_task_new (_("Applying changes"),
self->priv->src_pixbuf,
@@ -494,6 +609,8 @@ gth_file_tool_adjust_colors_get_options (GthFileTool *base)
self->priv->contrast_adj = gimp_scale_entry_new (GET_WIDGET ("contrast_hbox"), 0.0, -100.0, 100.0, 1.0, 10.0, 0);
self->priv->gamma_adj = gimp_scale_entry_new (GET_WIDGET ("gamma_hbox"), 0.0, -100.0, 100.0, 1.0, 10.0, 0);
self->priv->saturation_adj = gimp_scale_entry_new (GET_WIDGET ("saturation_hbox"), 0.0, -100.0, 100.0, 1.0, 10.0, 0);
+ self->priv->hue_adj = gimp_scale_entry_new (GET_WIDGET ("hue_hbox"), 0.0, -180.0, 180.0, 1.0, 10.0, 0);
+ self->priv->lightness_adj = gimp_scale_entry_new (GET_WIDGET ("lightness_hbox"), 0.0, -180.0, 180.0, 1.0, 10.0, 0);
g_signal_connect (GET_WIDGET ("ok_button"),
"clicked",
@@ -519,6 +636,14 @@ gth_file_tool_adjust_colors_get_options (GthFileTool *base)
"value-changed",
G_CALLBACK (value_changed_cb),
self);
+ g_signal_connect (G_OBJECT (self->priv->hue_adj),
+ "value-changed",
+ G_CALLBACK (value_changed_cb),
+ self);
+ g_signal_connect (G_OBJECT (self->priv->lightness_adj),
+ "value-changed",
+ G_CALLBACK (value_changed_cb),
+ self);
return options;
}
diff --git a/gthumb/Makefile.am b/gthumb/Makefile.am
index 6850226..6f3f445 100644
--- a/gthumb/Makefile.am
+++ b/gthumb/Makefile.am
@@ -98,6 +98,7 @@ PUBLIC_HEADER_FILES = \
gthumb-error.h \
gtk-utils.h \
main.h \
+ pixbuf-cache.h \
pixbuf-io.h \
pixbuf-utils.h \
typedefs.h \
@@ -210,6 +211,7 @@ gthumb_SOURCES = \
gthumb-error.c \
gtk-utils.c \
main.c \
+ pixbuf-cache.c \
pixbuf-io.c \
pixbuf-utils.c \
zlib-utils.c \
diff --git a/gthumb/pixbuf-cache.c b/gthumb/pixbuf-cache.c
new file mode 100644
index 0000000..b888f8e
--- /dev/null
+++ b/gthumb/pixbuf-cache.c
@@ -0,0 +1,74 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * GThumb
+ *
+ * Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+#include <glib.h>
+#include "pixbuf-cache.h"
+
+
+typedef struct {
+ guchar result[256];
+ guchar mask[32];
+} ChannelCache;
+
+
+struct _PixbufCache {
+ ChannelCache channel[PIXBUF_CACHE_CHANNEL_SIZE];
+};
+
+
+PixbufCache *
+pixbuf_cache_new (void)
+{
+ return g_new0 (PixbufCache, 1);
+}
+
+
+void
+pixbuf_cache_free (PixbufCache *cache)
+{
+ g_free (cache);
+}
+
+
+gboolean
+pixbuf_cache_get (PixbufCache *cache,
+ PixbufCacheChannel channel,
+ guchar *value)
+{
+ if (((cache->channel[channel].mask[*value / 8] >> (*value % 8)) & 1) != 1)
+ return FALSE;
+ *value = cache->channel[channel].result[*value];
+
+ return TRUE;
+}
+
+
+void
+pixbuf_cache_set (PixbufCache *cache,
+ PixbufCacheChannel channel,
+ guchar value,
+ guchar result)
+{
+ cache->channel[channel].result[value] = result;
+ cache->channel[channel].mask[value / 8] |= 1 << (value % 8);
+}
diff --git a/gthumb/pixbuf-cache.h b/gthumb/pixbuf-cache.h
new file mode 100644
index 0000000..11c1f04
--- /dev/null
+++ b/gthumb/pixbuf-cache.h
@@ -0,0 +1,50 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * GThumb
+ *
+ * Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef PIXBUF_CACHE_H
+#define PIXBUF_CACHE_H
+
+
+typedef enum {
+ PIXBUF_CACHE_CHANNEL_VALUE = 0,
+ PIXBUF_CACHE_CHANNEL_RED,
+ PIXBUF_CACHE_CHANNEL_GREEN,
+ PIXBUF_CACHE_CHANNEL_BLUE,
+ PIXBUF_CACHE_CHANNEL_ALPHA,
+ PIXBUF_CACHE_CHANNEL_SIZE
+} PixbufCacheChannel;
+
+
+typedef struct _PixbufCache PixbufCache;
+
+
+PixbufCache * pixbuf_cache_new (void);
+void pixbuf_cache_free (PixbufCache *cache);
+gboolean pixbuf_cache_get (PixbufCache *cache,
+ PixbufCacheChannel channel,
+ guchar *value);
+void pixbuf_cache_set (PixbufCache *cache,
+ PixbufCacheChannel channel,
+ guchar value,
+ guchar result);
+
+#endif /* PIXBUF_CACHE_H */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]