summaryrefslogtreecommitdiff
path: root/src/xsane-gamma.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/xsane-gamma.c')
-rw-r--r--src/xsane-gamma.c473
1 files changed, 370 insertions, 103 deletions
diff --git a/src/xsane-gamma.c b/src/xsane-gamma.c
index d47f6b7..d43eecf 100644
--- a/src/xsane-gamma.c
+++ b/src/xsane-gamma.c
@@ -3,7 +3,7 @@
xsane-gamma.c
Oliver Rauch <Oliver.Rauch@rauch-domain.de>
- Copyright (C) 1998-2002 Oliver Rauch
+ Copyright (C) 1998-2005 Oliver Rauch
This file is part of the XSANE package.
This program is free software; you can redistribute it and/or modify
@@ -55,7 +55,8 @@ void xsane_update_sliders(void);
static gint xsane_slider_callback(GtkWidget *widget, GdkEvent *event, XsaneSlider *slider);
void xsane_create_slider(XsaneSlider *slider);
void xsane_create_histogram(GtkWidget *parent, const char *title, int width, int height, XsanePixmap *hist);
-void xsane_get_free_gamma_curve(gfloat *free_color_gamma_data, SANE_Int *gammadata,
+/* void xsane_get_free_gamma_curve(gfloat *free_color_gamma_data, SANE_Int *gammadata, */
+void xsane_get_free_gamma_curve(gfloat *free_color_gamma_data, u_char *gammadata,
int negative, double gamma, double brightness, double contrast,
int len, int maxout);
static void xsane_calculate_auto_enhancement(SANE_Int *count_raw,
@@ -96,19 +97,12 @@ void xsane_set_auto_enhancement(void);
void xsane_clear_histogram(XsanePixmap *hist)
{
- GdkRectangle rect;
-
DBG(DBG_proc, "xsane_clear_histogram\n");
if(hist->pixmap)
{
- rect.x=0;
- rect.y=0;
- rect.width = HIST_WIDTH;
- rect.height = HIST_HEIGHT;
-
gdk_draw_rectangle(hist->pixmap, xsane.gc_backg, TRUE, 0, 0, HIST_WIDTH, HIST_HEIGHT);
- gtk_widget_draw(hist->pixmapwid, &rect);
+ gtk_widget_queue_draw(hist->pixmapwid);
}
}
@@ -118,7 +112,6 @@ static void xsane_draw_histogram_with_points(XsanePixmap *hist,
SANE_Int *count, SANE_Int *count_red, SANE_Int *count_green, SANE_Int *count_blue,
int show_red, int show_green, int show_blue, int show_inten, double scale)
{
- GdkRectangle rect;
int i;
int inten, red, green, blue;
@@ -129,11 +122,6 @@ static void xsane_draw_histogram_with_points(XsanePixmap *hist,
if(hist->pixmap)
{
- rect.x=0;
- rect.y=0;
- rect.width = HIST_WIDTH;
- rect.height = HIST_HEIGHT;
-
gdk_draw_rectangle(hist->pixmap, xsane.gc_backg, TRUE, 0, 0, HIST_WIDTH, HIST_HEIGHT);
red = 0;
@@ -170,7 +158,25 @@ static void xsane_draw_histogram_with_points(XsanePixmap *hist,
gdk_draw_rectangle(hist->pixmap, xsane.gc_black, TRUE, i, HIST_HEIGHT - inten, XD, YD);
}
- gtk_widget_draw(hist->pixmapwid, &rect);
+#ifdef HAVE_GTK2
+ gtk_widget_queue_draw(hist->pixmapwid);
+
+ if (hist->pixmapwid->window)
+ {
+ gdk_window_process_updates(hist->pixmapwid->window, FALSE);
+ }
+#else
+ {
+ GdkRectangle rect;
+
+ rect.x=0;
+ rect.y=0;
+ rect.width = HIST_WIDTH;
+ rect.height = HIST_HEIGHT;
+
+ gtk_widget_draw(hist->pixmapwid, &rect);
+ }
+#endif
}
}
/* ---------------------------------------------------------------------------------------------------------------------- */
@@ -179,7 +185,6 @@ static void xsane_draw_histogram_with_lines(XsanePixmap *hist,
SANE_Int *count, SANE_Int *count_red, SANE_Int *count_green, SANE_Int *count_blue,
int show_red, int show_green, int show_blue, int show_inten, double scale)
{
- GdkRectangle rect;
int i, j, k;
int inten, red, green, blue;
int inten0=0, red0=0, green0=0, blue0=0;
@@ -193,11 +198,6 @@ static void xsane_draw_histogram_with_lines(XsanePixmap *hist,
if (hist->pixmap)
{
- rect.x=0;
- rect.y=0;
- rect.width = HIST_WIDTH;
- rect.height = HIST_HEIGHT;
-
gdk_draw_rectangle(hist->pixmap, xsane.gc_backg, TRUE, 0, 0, HIST_WIDTH, HIST_HEIGHT);
red = 0;
@@ -282,7 +282,25 @@ static void xsane_draw_histogram_with_lines(XsanePixmap *hist,
gdk_draw_line(hist->pixmap, xsane.gc_black, i, HIST_HEIGHT - inten, i, HIST_HEIGHT - inten0);
}
- gtk_widget_draw(hist->pixmapwid, &rect);
+#ifdef HAVE_GTK2
+ gtk_widget_queue_draw(hist->pixmapwid);
+
+ if (hist->pixmapwid->window)
+ {
+ gdk_window_process_updates(hist->pixmapwid->window, FALSE);
+ }
+#else
+ {
+ GdkRectangle rect;
+
+ rect.x=0;
+ rect.y=0;
+ rect.width = HIST_WIDTH;
+ rect.height = HIST_HEIGHT;
+
+ gtk_widget_draw(hist->pixmapwid, &rect);
+ }
+#endif
}
}
@@ -292,7 +310,6 @@ void xsane_establish_slider(XsaneSlider *slider)
{
int x, y, pos, len;
guchar buf[XSANE_SLIDER_WIDTH*3];
- GdkRectangle rect;
DBG(DBG_proc, "xsane_establish_slider\n");
@@ -390,12 +407,25 @@ void xsane_establish_slider(XsaneSlider *slider)
gtk_preview_draw_row(GTK_PREVIEW(slider->preview),buf, 0, y, XSANE_SLIDER_WIDTH);
}
- rect.x=0;
- rect.y=0;
- rect.width = XSANE_SLIDER_WIDTH;
- rect.height = XSANE_SLIDER_HEIGHT;
+#ifdef HAVE_GTK2
+ gtk_widget_queue_draw(slider->preview);
- gtk_widget_draw(slider->preview, &rect);
+ if (slider->preview->window)
+ {
+ gdk_window_process_updates(slider->preview->window, FALSE);
+ }
+#else
+ {
+ GdkRectangle rect;
+
+ rect.x=0;
+ rect.y=0;
+ rect.width = HIST_WIDTH;
+ rect.height = HIST_HEIGHT;
+
+ gtk_widget_draw(slider->preview, &rect);
+ }
+#endif
}
/* ---------------------------------------------------------------------------------------------------------------------- */
@@ -404,7 +434,6 @@ void xsane_draw_slider_level(XsaneSlider *slider)
{
int i;
guchar buf[XSANE_SLIDER_WIDTH*3];
- GdkRectangle rect;
DBG(DBG_proc, "xsane_draw_slider_level\n");
@@ -431,12 +460,25 @@ void xsane_draw_slider_level(XsaneSlider *slider)
gtk_preview_draw_row(GTK_PREVIEW(slider->preview),buf, 0, i, XSANE_SLIDER_WIDTH);
}
- rect.x=0;
- rect.y=0;
- rect.width = XSANE_SLIDER_WIDTH;
- rect.height = XSANE_SLIDER_HEIGHT;
+#ifdef HAVE_GTK2
+ gtk_widget_queue_draw(slider->preview);
+
+ if (slider->preview->window)
+ {
+ gdk_window_process_updates(slider->preview->window, FALSE);
+ }
+#else
+ {
+ GdkRectangle rect;
+
+ rect.x=0;
+ rect.y=0;
+ rect.width = HIST_WIDTH;
+ rect.height = HIST_HEIGHT;
- gtk_widget_draw(slider->preview, &rect);
+ gtk_widget_draw(slider->preview, &rect);
+ }
+#endif
}
/* ---------------------------------------------------------------------------------------------------------------------- */
@@ -511,6 +553,20 @@ void xsane_update_sliders()
/* ---------------------------------------------------------------------------------------------------------------------- */
+static gint xsane_batch_scan_gamma_event()
+{
+ DBG(DBG_proc, "xsane_batch_scan_gamma_event\n");
+
+ xsane_batch_scan_update_icon_list(); /* update gamma of batch scan icons */
+
+ gtk_timeout_remove(xsane.batch_scan_gamma_timer);
+ xsane.batch_scan_gamma_timer = 0;
+
+ return FALSE;
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
static gint xsane_slider_hold_event()
{
DBG(DBG_proc, "xsane_slider_hold_event\n");
@@ -650,7 +706,7 @@ void xsane_create_slider(XsaneSlider *slider)
slider->preview = gtk_preview_new(GTK_PREVIEW_COLOR);
gtk_preview_size(GTK_PREVIEW(slider->preview), XSANE_SLIDER_WIDTH, XSANE_SLIDER_HEIGHT);
gtk_widget_set_events(slider->preview, XSANE_SLIDER_EVENTS);
- gtk_signal_connect(GTK_OBJECT(slider->preview), "event", GTK_SIGNAL_FUNC(xsane_slider_callback), slider);
+ g_signal_connect(GTK_OBJECT(slider->preview), "event", GTK_SIGNAL_FUNC(xsane_slider_callback), slider);
}
/* ---------------------------------------------------------------------------------------------------------------------- */
@@ -663,7 +719,7 @@ void xsane_create_histogram(GtkWidget *parent, const char *title, int width, int
hist->frame = gtk_frame_new(title);
hist->pixmap = gdk_pixmap_new(xsane.histogram_dialog->window, width, height, -1);
- hist->pixmapwid = gtk_pixmap_new(hist->pixmap, mask);
+ hist->pixmapwid = gtk_image_new_from_pixmap(hist->pixmap, mask);
gtk_container_add(GTK_CONTAINER(hist->frame), hist->pixmapwid);
gdk_draw_rectangle(hist->pixmap, xsane.gc_backg, TRUE, 0, 0, width, height);
@@ -1078,7 +1134,7 @@ void xsane_create_preview_threshold_curve(u_char *gammadata, double threshold, i
}
/* ---------------------------------------------------------------------------------------------------------------------- */
-
+#if 0
void xsane_create_preview_gamma_curve(u_char *gammadata, int negative, double gamma,
double brightness, double contrast,
double medium_shadow, double medium_highlight, double medium_gamma,
@@ -1089,9 +1145,193 @@ void xsane_create_preview_gamma_curve(u_char *gammadata, int negative, double ga
double val;
double m;
double b;
+ double medium_m;
+ double medium_mid;
int maxin = numbers-1;
+ double clip_shadow, clip_highlight;
+ double m_shadow, m_highlight;
+ double s2 = 0.0, s3 = 0.0;
+ double h2 = 0.0, h3 = 0.0;
+ double clip_alpha = 0.34; /* 1/3 ... 1/2 are allowed */
+ int medium_range;
+ int unclipped_range;
+ double medium_shadow_val, medium_highlight_val;
+ double medium_highlight_val_from_maxin;
+ double clip_highlight_from_maxin;
+
+ medium_range = (medium_highlight - medium_shadow)/ 100.0 * maxin;
+
+ m_shadow = 1.0;
+ m_highlight = 1.0;
+
+ medium_shadow_val = medium_shadow/100.0 * maxin;
+ medium_highlight_val = medium_highlight/100.0 * maxin;
+ medium_highlight_val_from_maxin = maxin - medium_highlight_val;
+
+ for (i=1; i<10; i++)
+ {
+ clip_shadow = clip_alpha * m_shadow * medium_shadow_val;
+ clip_highlight_from_maxin = clip_alpha * (m_highlight * medium_highlight_val_from_maxin);
+ clip_highlight = maxin - clip_highlight_from_maxin;
+ unclipped_range = clip_highlight - clip_shadow;
+
+ m_shadow = (4 * m_shadow + unclipped_range / medium_range / medium_gamma) / 5;
+ m_highlight = (4 * m_highlight + unclipped_range / medium_range) / 5;
+ }
+ m_shadow = 1.0;
+ m_highlight = 1.0;
+
+ /* soft clipping constants for shadow of medium */
+
+ if (medium_shadow_val)
+ {
+ clip_shadow = clip_alpha * m_shadow * medium_shadow_val;
+ s2 = 3 * clip_shadow / (medium_shadow_val * medium_shadow_val) - m_shadow / medium_shadow_val;
+ s3 = m_shadow / (medium_shadow_val * medium_shadow_val) - 2 * clip_shadow / (medium_shadow_val * medium_shadow_val * medium_shadow_val);
+
+ DBG(DBG_info2, "\n");
+ DBG(DBG_info2, "maxin = %d\n", maxin);
+ DBG(DBG_info2, "m_shadow = %f\n", m_shadow);
+ DBG(DBG_info2, "medium_shadow_val = %d\n", medium_shadow_val);
+ DBG(DBG_info2, "clip_shadow = %f\n", clip_shadow);
+ DBG(DBG_info2, "s2 = %f\n", s2);
+ DBG(DBG_info2, "s3 = %f\n", s3);
+ DBG(DBG_info2, "s2*shadow^2 + s3*shadow^3 = %f\n", s2 * medium_shadow_val * medium_shadow_val + s3 * medium_shadow_val * medium_shadow_val* medium_shadow_val);
+ }
+ else
+ {
+ clip_shadow = 0;
+ }
+
+
+ /* soft clipping constants for highlight of medium */
+
+ if (medium_highlight_val < maxin)
+ {
+ medium_highlight_val_from_maxin = maxin - medium_highlight_val;
+ clip_highlight_from_maxin = clip_alpha * (m_highlight * medium_highlight_val_from_maxin);
+ clip_highlight = maxin - clip_highlight_from_maxin;
+ h2 = 3 * clip_highlight_from_maxin / (medium_highlight_val_from_maxin * medium_highlight_val_from_maxin) - m_highlight / medium_highlight_val_from_maxin;
+ h3 = m_highlight / (medium_highlight_val_from_maxin * medium_highlight_val_from_maxin) - 2 * clip_highlight_from_maxin / (medium_highlight_val_from_maxin * medium_highlight_val_from_maxin * medium_highlight_val_from_maxin);
+
+ DBG(DBG_info2, "\n");
+ DBG(DBG_info2, "maxin = %d\n", maxin);
+ DBG(DBG_info2, "m_highlight = %f\n", m_highlight);
+ DBG(DBG_info2, "medium_highlight_val = %d\n", medium_highlight_val);
+ DBG(DBG_info2, "clip_highlight = %f\n", clip_highlight);
+ DBG(DBG_info2, "h2 = %f\n", h2);
+ DBG(DBG_info2, "h3 = %f\n", h3);
+ DBG(DBG_info2, "h2*highlight^2 + h3*highlight^3 = %f\n", h2 * (maxin - medium_highlight_val) * (maxin - medium_highlight_val) + h3 * (maxin - medium_highlight_val) * (maxin - medium_highlight_val) * (maxin - medium_highlight_val));
+ }
+ else
+ {
+ clip_highlight = maxin;
+ }
+
+ /* standard gamma constants for medium */
+
+ unclipped_range = clip_highlight - clip_shadow;
+ DBG(DBG_info2, "medium_range = %d\n", medium_range);
+ DBG(DBG_info2, "unclipped_range = %d\n", unclipped_range);
+
+ medium_m = 100.0/(medium_highlight - medium_shadow);
+ medium_mid = (medium_shadow + medium_highlight)/200.0 * maxin;
+
+ DBG(DBG_proc, "xsane_create_preview_gamma_curve(neg=%d, gam=%3.2f, bri=%3.2f, ctr=%3.2f, nrs=%d)\n",
+ negative, gamma, brightness, contrast, numbers);
+
+ if (contrast < -100.0)
+ {
+ contrast = -100.0;
+ }
+
+ midin = (int)(numbers / 2.0);
+
+ m = 1.0 + contrast/100.0;
+ b = (1.0 + brightness/100.0) * midin;
+
+ if (negative)
+ {
+ for (i=0; i <= maxin; i++)
+ {
+ val = ((double) i);
+
+ /* medium correction */
+ val = (val - medium_mid) * medium_m + midin;
+ val = maxin - val; /* invert */
+
+ if (i < medium_shadow_val)
+ {
+ val = maxin - s2 * i * i - s3 * i * i * i;
+ }
+ else if (i > medium_highlight_val)
+ {
+ val = h2 * (maxin - i) * (maxin - i) + h3 * (maxin - i) * (maxin - i) * (maxin - i);
+ }
+ else
+ {
+ xsane_bound_double(&val, 0.0, maxin);
+ val = (maxin - clip_highlight) + unclipped_range * pow( val/maxin, (1.0/medium_gamma) );
+ }
+
+ val = val - midin;
+
+ /* user correction */
+ val = val * m + b;
+ xsane_bound_double(&val, 0.0, maxin);
+
+ gammadata[i] = (u_char) (255.99999 * pow( ceil(val)/maxin, (1.0/gamma) ));
+ }
+ }
+ else /* positive */
+ {
+ for (i=0; i <= maxin; i++)
+ {
+ val = ((double) i);
+
+ /* medium correction */
+ val = (val - medium_mid) * medium_m + midin;
+
+ if (i < medium_shadow_val)
+ {
+ val = s2 * i * i + s3 * i * i * i;
+ }
+ else if (i > medium_highlight_val)
+ {
+ val = maxin - (h2 * (maxin - i) * (maxin - i) + h3 * (maxin - i) * (maxin - i) * (maxin - i));
+ }
+ else
+ {
+ xsane_bound_double(&val, 0.0, maxin);
+ val = clip_shadow + unclipped_range * pow( val/maxin, (1.0/medium_gamma) );
+ }
+
+ val = val - midin;
+
+ /* user correction */
+ val = val * m + b;
+ xsane_bound_double(&val, 0.0, maxin);
+
+ gammadata[i] = (u_char) (255.99999 * pow( val/maxin, (1.0/gamma) ));
+ }
+ }
+}
+
+#else
+
+void xsane_create_preview_gamma_curve(u_char *gammadata, int negative, double gamma,
+ double brightness, double contrast,
+ double medium_shadow, double medium_highlight, double medium_gamma,
+ int numbers)
+{
+ int i;
+ double midin;
+ double val;
+ double m;
+ double b;
double medium_m;
double medium_mid;
+ int maxin = numbers-1;
medium_m = 100.0/(medium_highlight - medium_shadow);
medium_mid = (medium_shadow + medium_highlight)/200.0 * maxin;
@@ -1127,7 +1367,7 @@ void xsane_create_preview_gamma_curve(u_char *gammadata, int negative, double ga
val = val * m + b;
xsane_bound_double(&val, 0.0, maxin);
- gammadata[i] = (u_char) (255 * pow( val/maxin, (1.0/gamma) ));
+ gammadata[i] = (u_char) (255.99999 * pow( ceil(val)/maxin, (1.0/gamma) ));
}
}
else /* positive */
@@ -1147,10 +1387,11 @@ void xsane_create_preview_gamma_curve(u_char *gammadata, int negative, double ga
val = val * m + b;
xsane_bound_double(&val, 0.0, maxin);
- gammadata[i] = (u_char) (255 * pow( val/maxin, (1.0/gamma) ));
+ gammadata[i] = (u_char) (255.99999 * pow( val/maxin, (1.0/gamma) ));
}
}
}
+#endif
/* ---------------------------------------------------------------------------------------------------------------------- */
@@ -1205,7 +1446,7 @@ void xsane_create_gamma_curve(SANE_Int *gammadata,
/* user correction */
val = val * m + b;
xsane_bound_double(&val, 0.0, maxin);
- gammadata[i] = maxout * pow( val/maxin, (1.0/gamma) );
+ gammadata[i] = (int) (maxout * pow( val/maxin, (1.0/gamma) ));
}
}
else /* positive */
@@ -1224,7 +1465,7 @@ void xsane_create_gamma_curve(SANE_Int *gammadata,
/* user correction */
val = val * m + b;
xsane_bound_double(&val, 0.0, maxin);
- gammadata[i] = maxout * pow( val/maxin, (1.0/gamma) );
+ gammadata[i] = (int) (maxout * pow( val/maxin, (1.0/gamma) ));
}
}
}
@@ -1578,8 +1819,6 @@ void xsane_update_gamma_curve(int update_raw)
static void xsane_enhancement_update(void)
{
- guint sig_changed=0;
-
DBG(DBG_proc, "xsane_enhancement_update\n");
if (xsane.param.depth == 1) /* lineart? no gamma */
@@ -1587,43 +1826,28 @@ static void xsane_enhancement_update(void)
return;
}
- sig_changed = gtk_signal_lookup("changed", GTK_OBJECT_TYPE(xsane.gamma_widget));
+ xsane.block_enhancement_update = TRUE;
- GTK_ADJUSTMENT(xsane.gamma_widget)->value = xsane.gamma;
- GTK_ADJUSTMENT(xsane.brightness_widget)->value = xsane.brightness;
- GTK_ADJUSTMENT(xsane.contrast_widget)->value = xsane.contrast;
+ gtk_adjustment_set_value(GTK_ADJUSTMENT(xsane.gamma_widget), xsane.gamma);
+ gtk_adjustment_set_value(GTK_ADJUSTMENT(xsane.brightness_widget), xsane.brightness);
+ gtk_adjustment_set_value(GTK_ADJUSTMENT(xsane.contrast_widget), xsane.contrast);
if ( (xsane.xsane_colors > 1) && (!xsane.enhancement_rgb_default) )
{
- GTK_ADJUSTMENT(xsane.gamma_red_widget)->value = xsane.gamma_red;
- GTK_ADJUSTMENT(xsane.gamma_green_widget)->value = xsane.gamma_green;
- GTK_ADJUSTMENT(xsane.gamma_blue_widget)->value = xsane.gamma_blue;
-
- GTK_ADJUSTMENT(xsane.brightness_red_widget)->value = xsane.brightness_red;
- GTK_ADJUSTMENT(xsane.brightness_green_widget)->value = xsane.brightness_green;
- GTK_ADJUSTMENT(xsane.brightness_blue_widget)->value = xsane.brightness_blue;
+ gtk_adjustment_set_value(GTK_ADJUSTMENT(xsane.gamma_red_widget), xsane.gamma_red);
+ gtk_adjustment_set_value(GTK_ADJUSTMENT(xsane.brightness_red_widget), xsane.brightness_red);
+ gtk_adjustment_set_value(GTK_ADJUSTMENT(xsane.contrast_red_widget), xsane.contrast_red);
- GTK_ADJUSTMENT(xsane.contrast_red_widget)->value = xsane.contrast_red;
- GTK_ADJUSTMENT(xsane.contrast_green_widget)->value = xsane.contrast_green;
- GTK_ADJUSTMENT(xsane.contrast_blue_widget)->value = xsane.contrast_blue;
+ gtk_adjustment_set_value(GTK_ADJUSTMENT(xsane.gamma_green_widget), xsane.gamma_green);
+ gtk_adjustment_set_value(GTK_ADJUSTMENT(xsane.brightness_green_widget), xsane.brightness_green);
+ gtk_adjustment_set_value(GTK_ADJUSTMENT(xsane.contrast_green_widget), xsane.contrast_green);
- gtk_signal_emit(xsane.gamma_red_widget, sig_changed);
- gtk_signal_emit(xsane.gamma_green_widget, sig_changed);
- gtk_signal_emit(xsane.gamma_blue_widget, sig_changed);
-
- gtk_signal_emit(xsane.brightness_red_widget, sig_changed);
- gtk_signal_emit(xsane.brightness_green_widget, sig_changed);
- gtk_signal_emit(xsane.brightness_blue_widget, sig_changed);
-
- gtk_signal_emit(xsane.contrast_red_widget, sig_changed);
- gtk_signal_emit(xsane.contrast_green_widget, sig_changed);
- gtk_signal_emit(xsane.contrast_blue_widget, sig_changed);
-
+ gtk_adjustment_set_value(GTK_ADJUSTMENT(xsane.gamma_blue_widget), xsane.gamma_blue);
+ gtk_adjustment_set_value(GTK_ADJUSTMENT(xsane.brightness_blue_widget), xsane.brightness_blue);
+ gtk_adjustment_set_value(GTK_ADJUSTMENT(xsane.contrast_blue_widget), xsane.contrast_blue);
}
- gtk_signal_emit(xsane.gamma_widget, sig_changed);
- gtk_signal_emit(xsane.brightness_widget, sig_changed);
- gtk_signal_emit(xsane.contrast_widget, sig_changed);
+ xsane.block_enhancement_update = FALSE;
xsane_update_sliders(); /* update histogram slider */
}
@@ -1680,9 +1904,9 @@ void xsane_enhancement_by_gamma(void)
brightness = xsane.brightness + xsane.brightness_red;
gamma = xsane.gamma * xsane.gamma_red;
- if (contrast < -100)
+ if (contrast < xsane.contrast_min)
{
- contrast = -100;
+ contrast = xsane.contrast_min;
}
xsane_gamma_to_histogram(&min, &mid, &max, contrast, brightness, gamma);
@@ -1698,9 +1922,9 @@ void xsane_enhancement_by_gamma(void)
brightness = xsane.brightness + xsane.brightness_green;
gamma = xsane.gamma * xsane.gamma_green;
- if (contrast < -100)
+ if (contrast < xsane.contrast_min)
{
- contrast = -100;
+ contrast = xsane.contrast_min;
}
xsane_gamma_to_histogram(&min, &mid, &max, contrast, brightness, gamma);
@@ -1715,9 +1939,9 @@ void xsane_enhancement_by_gamma(void)
brightness = xsane.brightness + xsane.brightness_blue;
gamma = xsane.gamma * xsane.gamma_blue;
- if (contrast < -100)
+ if (contrast < xsane.contrast_min)
{
- contrast = -100;
+ contrast = xsane.contrast_min;
}
xsane_gamma_to_histogram(&min, &mid, &max, contrast, brightness, gamma);
@@ -1729,6 +1953,12 @@ void xsane_enhancement_by_gamma(void)
xsane_enhancement_update();
xsane_update_gamma_curve(FALSE);
+
+ if (xsane.batch_scan_gamma_timer)
+ {
+ gtk_timeout_remove(xsane.batch_scan_gamma_timer);
+ }
+ xsane.batch_scan_gamma_timer = gtk_timeout_add(XSANE_CONTINUOUS_HOLD_TIME * 4, xsane_batch_scan_gamma_event, 0);
}
/* ---------------------------------------------------------------------------------------------------------------------- */
@@ -1824,7 +2054,7 @@ static int xsane_histogram_to_gamma(XsaneSlider *slider,
*contrast = (10000.0 / (slider->value[2] - slider->value[0]) - 100.0);
if (correct_bound)
{
- xsane_bound_double(contrast, -100.0 + contrast_offset, xsane.contrast_max + contrast_offset);
+ xsane_bound_double(contrast, xsane.contrast_min + contrast_offset, xsane.contrast_max + contrast_offset);
}
*brightness = - (slider->value[0] - 50.0) * (*contrast + 100.0)/50.0 - 100.0;
@@ -1837,17 +2067,19 @@ static int xsane_histogram_to_gamma(XsaneSlider *slider,
range = slider->value[2] - slider->value[0];
*gamma = log(mid/range) / log(0.5);
+
if (correct_bound)
{
xsane_bound_double(gamma, XSANE_GAMMA_MIN * gamma_multiplier, XSANE_GAMMA_MAX * gamma_multiplier);
return 1; /* in bound */
}
- else if (xsane_check_bound_double(*contrast, -100.0 + contrast_offset, xsane.contrast_max + contrast_offset) &&
- xsane_check_bound_double(*brightness, XSANE_BRIGHTNESS_MIN + brightness_offset, xsane.brightness_max + brightness_offset) &&
+ else if (xsane_check_bound_double(*contrast, xsane.contrast_min + contrast_offset, xsane.contrast_max + contrast_offset) &&
+ xsane_check_bound_double(*brightness, xsane.brightness_min + brightness_offset, xsane.brightness_max + brightness_offset) &&
xsane_check_bound_double(*gamma, XSANE_GAMMA_MIN * gamma_multiplier, XSANE_GAMMA_MAX * gamma_multiplier))
{
return 1; /* in bound */
}
+
return 0; /* out of bound */
}
@@ -1949,14 +2181,14 @@ void xsane_create_histogram_dialog(const char *devicetext)
DBG(DBG_proc, "xsane_create_histogram_dialog\n");
- xsane.histogram_dialog = gtk_window_new(GTK_WINDOW_DIALOG);
- gtk_window_set_policy(GTK_WINDOW(xsane.histogram_dialog), FALSE, FALSE, FALSE);
- gtk_widget_set_uposition(xsane.histogram_dialog, XSANE_HISTOGRAM_POS_X, XSANE_HISTOGRAM_POS_Y);
- gtk_signal_connect(GTK_OBJECT(xsane.histogram_dialog), "delete_event", GTK_SIGNAL_FUNC(xsane_histogram_win_delete), NULL);
+ xsane.histogram_dialog = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_resizable(GTK_WINDOW(xsane.histogram_dialog), FALSE);
+ gtk_window_move(GTK_WINDOW(xsane.histogram_dialog), XSANE_HISTOGRAM_POS_X, XSANE_HISTOGRAM_POS_Y);
+ g_signal_connect(GTK_OBJECT(xsane.histogram_dialog), "delete_event", GTK_SIGNAL_FUNC(xsane_histogram_win_delete), NULL);
sprintf(windowname, "%s %s", WINDOW_HISTOGRAM, devicetext);
gtk_window_set_title(GTK_WINDOW(xsane.histogram_dialog), windowname);
xsane_set_window_icon(xsane.histogram_dialog, 0);
- gtk_accel_group_attach(xsane.accelerator_group, GTK_OBJECT(xsane.histogram_dialog));
+ gtk_window_add_accel_group(GTK_WINDOW(xsane.histogram_dialog), xsane.accelerator_group);
xsane_histogram_vbox = gtk_vbox_new(FALSE, 0);
gtk_container_set_border_width(GTK_CONTAINER(xsane_histogram_vbox), 5);
@@ -1976,7 +2208,7 @@ void xsane_create_histogram_dialog(const char *devicetext)
xsane.gc_trans = style->bg_gc[GTK_STATE_NORMAL];
xsane.bg_trans = &style->bg[GTK_STATE_NORMAL];
- colormap = gdk_window_get_colormap(xsane.histogram_dialog->window);
+ colormap = gdk_drawable_get_colormap(xsane.histogram_dialog->window);
xsane.gc_black = gdk_gc_new(xsane.histogram_dialog->window);
color_black.red = 0;
@@ -2078,27 +2310,27 @@ void xsane_create_histogram_dialog(const char *devicetext)
button = xsane_toggle_button_new_with_pixmap(xsane.histogram_dialog->window, xsane_color_hbox, intensity_xpm, DESC_HIST_INTENSITY,
&xsane.histogram_int, xsane_histogram_toggle_button_callback);
- gtk_widget_add_accelerator(button, "clicked", xsane.accelerator_group, GDK_I, GDK_MOD1_MASK, GTK_ACCEL_LOCKED);
+ gtk_widget_add_accelerator(button, "clicked", xsane.accelerator_group, GDK_I, GDK_MOD1_MASK, DEF_GTK_ACCEL_LOCKED);
button = xsane_toggle_button_new_with_pixmap(xsane.histogram_dialog->window, xsane_color_hbox, red_xpm, DESC_HIST_RED,
&xsane.histogram_red, xsane_histogram_toggle_button_callback);
- gtk_widget_add_accelerator(button, "clicked", xsane.accelerator_group, GDK_R, GDK_MOD1_MASK, GTK_ACCEL_LOCKED);
+ gtk_widget_add_accelerator(button, "clicked", xsane.accelerator_group, GDK_R, GDK_MOD1_MASK, DEF_GTK_ACCEL_LOCKED);
button = xsane_toggle_button_new_with_pixmap(xsane.histogram_dialog->window, xsane_color_hbox, green_xpm, DESC_HIST_GREEN,
&xsane.histogram_green, xsane_histogram_toggle_button_callback);
- gtk_widget_add_accelerator(button, "clicked", xsane.accelerator_group, GDK_G, GDK_MOD1_MASK, GTK_ACCEL_LOCKED);
+ gtk_widget_add_accelerator(button, "clicked", xsane.accelerator_group, GDK_G, GDK_MOD1_MASK, DEF_GTK_ACCEL_LOCKED);
button = xsane_toggle_button_new_with_pixmap(xsane.histogram_dialog->window, xsane_color_hbox, blue_xpm, DESC_HIST_BLUE,
&xsane.histogram_blue, xsane_histogram_toggle_button_callback);
- gtk_widget_add_accelerator(button, "clicked", xsane.accelerator_group, GDK_B, GDK_MOD1_MASK, GTK_ACCEL_LOCKED);
+ gtk_widget_add_accelerator(button, "clicked", xsane.accelerator_group, GDK_B, GDK_MOD1_MASK, DEF_GTK_ACCEL_LOCKED);
button = xsane_toggle_button_new_with_pixmap(xsane.histogram_dialog->window, xsane_color_hbox, pixel_xpm, DESC_HIST_PIXEL,
&xsane.histogram_lines, xsane_histogram_toggle_button_callback);
- gtk_widget_add_accelerator(button, "clicked", xsane.accelerator_group, GDK_M, GDK_MOD1_MASK, GTK_ACCEL_LOCKED);
+ gtk_widget_add_accelerator(button, "clicked", xsane.accelerator_group, GDK_M, GDK_MOD1_MASK, DEF_GTK_ACCEL_LOCKED);
button = xsane_toggle_button_new_with_pixmap(xsane.histogram_dialog->window, xsane_color_hbox, log_xpm, DESC_HIST_LOG,
&xsane.histogram_log, xsane_histogram_toggle_button_callback);
- gtk_widget_add_accelerator(button, "clicked", xsane.accelerator_group, GDK_L, GDK_MOD1_MASK, GTK_ACCEL_LOCKED);
+ gtk_widget_add_accelerator(button, "clicked", xsane.accelerator_group, GDK_L, GDK_MOD1_MASK, DEF_GTK_ACCEL_LOCKED);
gtk_widget_show(xsane_color_hbox);
}
@@ -2107,7 +2339,8 @@ void xsane_create_histogram_dialog(const char *devicetext)
#ifdef HAVE_WORKING_GTK_GAMMACURVE
/* xsane_get_free_gamma_curve transforms gamma table with 65536 entries and value range 0.0-1.0 to requested gamma table */
/* it combines the color gamma table given by gamma_widget and the gray gamma table (xsane.gamma_curve_gray) */
-void xsane_get_free_gamma_curve(gfloat *free_color_gamma_data, SANE_Int *gammadata,
+/* void xsane_get_free_gamma_curve(gfloat *free_color_gamma_data, SANE_Int *gammadata, */
+void xsane_get_free_gamma_curve(gfloat *free_color_gamma_data, u_char *gammadata,
int negative, double gamma, double brightness, double contrast,
int len, int maxout)
{
@@ -2238,13 +2471,13 @@ GtkWidget* xsane_gamma_curve_notebook_page_new(GtkWidget *notebook, char *title)
gtk_widget_show(label);
gamma = gtk_gamma_curve_new();
- gtk_widget_set_usize(gamma, 0, 256);
+ gtk_widget_set_size_request(gamma, -1, 256);
curve = GTK_GAMMA_CURVE(gamma)->curve;
vector = alloca(optlen * sizeof(vector[0]));
gtk_curve_set_range(GTK_CURVE(curve), 0, optlen - 1, fmin, fmax);
-#if 1
+#if 0
gtk_curve_maintain_accuracy(GTK_CURVE(curve), 1.0);
#endif
@@ -2269,14 +2502,14 @@ void xsane_create_gamma_dialog(const char *devicetext)
xsane.free_gamma_data_green = calloc(65536, sizeof(xsane.free_gamma_data_green[0]));
xsane.free_gamma_data_blue = calloc(65536, sizeof(xsane.free_gamma_data_green[0]));
- xsane.gamma_dialog = gtk_window_new(GTK_WINDOW_DIALOG);
- gtk_window_set_policy(GTK_WINDOW(xsane.gamma_dialog), FALSE, FALSE, FALSE);
- gtk_widget_set_uposition(xsane.gamma_dialog, XSANE_GAMMA_POS_X, XSANE_GAMMA_POS_Y);
- gtk_signal_connect(GTK_OBJECT(xsane.gamma_dialog), "delete_event", GTK_SIGNAL_FUNC(xsane_gamma_win_delete), NULL);
+ xsane.gamma_dialog = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_resizable(GTK_WINDOW(xsane.gamma_dialog), FALSE);
+ gtk_window_move(GTK_WINDOW(xsane.gamma_dialog), XSANE_GAMMA_POS_X, XSANE_GAMMA_POS_Y);
+ g_signal_connect(GTK_OBJECT(xsane.gamma_dialog), "delete_event", GTK_SIGNAL_FUNC(xsane_gamma_win_delete), NULL);
sprintf(windowname, "%s %s", WINDOW_GAMMA, devicetext);
gtk_window_set_title(GTK_WINDOW(xsane.gamma_dialog), windowname);
xsane_set_window_icon(xsane.gamma_dialog, 0);
- gtk_accel_group_attach(xsane.accelerator_group, GTK_OBJECT(xsane.gamma_dialog));
+ gtk_window_add_accel_group(GTK_WINDOW(xsane.gamma_dialog), xsane.accelerator_group);
xsane_vbox_gamma = gtk_vbox_new(TRUE, 5);
gtk_container_set_border_width(GTK_CONTAINER(xsane_vbox_gamma), 5);
@@ -2354,6 +2587,40 @@ void xsane_set_auto_enhancement()
}
/* ---------------------------------------------------------------------------------------------------------------------- */
+
+/* set medium values as gamma/contrast/brightness */
+void xsane_apply_medium_definition_as_enhancement(Preferences_medium_t *medium)
+{
+ xsane.gamma = medium->gamma_gray;
+ xsane.contrast = 10000.0 / (medium->highlight_gray - medium->shadow_gray) - 100.0;
+ xsane.brightness = - (medium->shadow_gray - 50.0) * (xsane.contrast + 100.0) / 50.0 - 100.0;
+
+ xsane.gamma_red = medium->gamma_red / xsane.gamma;
+ xsane.gamma_green = medium->gamma_green / xsane.gamma;
+ xsane.gamma_blue = medium->gamma_blue / xsane.gamma;
+
+ xsane.contrast_red = 10000.0 / (medium->highlight_red - medium->shadow_red) - 100.0 - xsane.contrast;
+ xsane.contrast_green = 10000.0 / (medium->highlight_green - medium->shadow_green) - 100.0 - xsane.contrast;
+ xsane.contrast_blue = 10000.0 / (medium->highlight_blue - medium->shadow_blue) - 100.0 - xsane.contrast;
+
+ xsane.brightness_red = - (medium->shadow_red - 50.0) * (xsane.contrast + xsane.contrast_red + 100.0) / 50.0 - 100.0 - xsane.brightness;
+ xsane.brightness_green = - (medium->shadow_green - 50.0) * (xsane.contrast + xsane.contrast_green + 100.0) / 50.0 - 100.0 - xsane.brightness;
+ xsane.brightness_blue = - (medium->shadow_blue - 50.0) * (xsane.contrast + xsane.contrast_blue + 100.0) / 50.0 - 100.0 - xsane.brightness;
+
+ xsane.negative = medium->negative;
+
+ if (xsane.negative)
+ {
+ xsane.brightness = -xsane.brightness;
+ xsane.brightness_red = -xsane.brightness_red;
+ xsane.brightness_green = -xsane.brightness_green;
+ xsane.brightness_blue = -xsane.brightness_blue;
+ }
+}
+
+/* ---------------------------------------------------------------------------------------------------------------------- */
+
+/* set medium values */
void xsane_set_medium(Preferences_medium_t *medium)
{
const SANE_Option_Descriptor *opt;