[sane-devel] [Suggestion/Patch] xsane-viewer add feature: scale to given output width/height

Peter Seiderer Peter.Seiderer@ciselant.de
Tue, 16 Apr 2002 18:05:41 +0200


--u3/rZRmxL6MmkK24
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Hello,

the attached patch adds the following feature to the xsane-viewer
scale menu:

If you change the x-/y-scale factor, you can see the
resultiing output width and height.

Or if you edit the resulting output widht/height values the scale
factor is adjusted automatically.

In addition there are buttons fore fixed output width/height values.

Any further suggestions/advises?

Peter

-- 
------------------------------------------------------------------------
Peter Seiderer                     E-Mail:  Peter.Seiderer@ciselant.de

--u3/rZRmxL6MmkK24
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="patch-scale_to_output_width_height-0.1"

diff -ru xsane-0.85_new-0.3/src/xsane-text.h xsane-0.85/src/xsane-text.h
--- xsane-0.85_new-0.3/src/xsane-text.h	Tue Apr 16 10:39:07 2002
+++ xsane-0.85/src/xsane-text.h	Tue Apr 16 12:59:40 2002
@@ -221,6 +221,8 @@
 #define TEXT_VIEWER_IMAGE_INFO		_("Size %d x %d pixel, %d bit/color, %d colors, %1.0f dpi x %1.0f dpi, %1.1f %s")
 #define TEXT_X_SCALE_FACTOR		_("X-Scale factor:")
 #define TEXT_Y_SCALE_FACTOR		_("Y-Scale factor:")
+#define TEXT_X_WIDTH_OUTPUT             _("X-Output width: ")
+#define TEXT_Y_HEIGHT_OUTPUT            _("Y-Output height:")
 #define TEXT_DESPECKLE_RADIUS		_("Despeckle radius:")
 #define TEXT_BLUR_RADIUS		_("Blur radius:")
 
diff -ru xsane-0.85_new-0.3/src/xsane-viewer.c xsane-0.85/src/xsane-viewer.c
--- xsane-0.85_new-0.3/src/xsane-viewer.c	Tue Apr 16 10:38:59 2002
+++ xsane-0.85/src/xsane-viewer.c	Tue Apr 16 17:23:36 2002
@@ -89,6 +89,7 @@
   }
 
   remove(v->filename);
+  free(v->filename);
 
   gtk_widget_destroy(v->top);
 
@@ -109,9 +110,17 @@
     list = list->next_viewer;
   }
 
+  if ( v->output_filename != NULL ) {
+    free(v->output_filename);
+  }
+  
+  if ( v->image_info != NULL ) {
+    free(v->image_info);
+  }
+
   free(v);
 
- return TRUE;
+  return TRUE;
 }
 
 /* ---------------------------------------------------------------------------------------------------------------------- */
@@ -478,6 +487,102 @@
 #endif
 }
 
+static void xsane_viewer_spinbutton_float_changed_set_scale_output_width(GtkWidget *spinbutton, gpointer data)
+{
+ Viewer *v = (Viewer *)data;
+ float  val;
+
+#ifdef HAVE_GTK2
+  val = (float) gtk_spin_button_get_value((GtkSpinButton *) spinbutton);
+#else
+  val = gtk_spin_button_get_value_as_float((GtkSpinButton *) spinbutton);
+#endif
+
+  gtk_spin_button_set_value(v->scale_spinbutton_output_width, val * v->image_info->image_width);
+}
+
+static void xsane_viewer_spinbutton_float_changed_set_scale_output_height(GtkWidget *spinbutton, gpointer data)
+{
+ Viewer *v = (Viewer *)data;
+ float  val;
+
+#ifdef HAVE_GTK2
+  val = (float) gtk_spin_button_get_value((GtkSpinButton *) spinbutton);
+#else
+  val = gtk_spin_button_get_value_as_float((GtkSpinButton *) spinbutton);
+#endif
+
+  gtk_spin_button_set_value(v->scale_spinbutton_output_height, val * v->image_info->image_height);
+}
+
+static void xsane_viewer_spinbutton_float_changed_set_scale_x_factor(GtkWidget *spinbutton, gpointer data)
+{
+ Viewer *v = (Viewer *)data;
+ float  val;
+
+#ifdef HAVE_GTK2
+  val = (float) gtk_spin_button_get_value((GtkSpinButton *) spinbutton);
+#else
+  val = gtk_spin_button_get_value_as_float((GtkSpinButton *) spinbutton);
+#endif
+
+  val = val / v->image_info->image_width;
+  v->x_scale_factor = val;
+  
+  gtk_spin_button_set_value(v->scale_spinbutton_x_factor, val);
+}
+
+static void xsane_viewer_spinbutton_float_changed_set_scale_y_factor(GtkWidget *spinbutton, gpointer data)
+{
+ Viewer *v = (Viewer *)data;
+ float  val;
+
+#ifdef HAVE_GTK2
+  val = (float) gtk_spin_button_get_value((GtkSpinButton *) spinbutton);
+#else
+  val = gtk_spin_button_get_value_as_float((GtkSpinButton *) spinbutton);
+#endif
+
+  val = val / v->image_info->image_height;
+  v->y_scale_factor = val;
+  
+  gtk_spin_button_set_value(v->scale_spinbutton_y_factor, val);
+}
+
+static void xsane_viewer_button_set_scale_1024_768(GtkWidget *button, gpointer data)
+{
+ Viewer *v = (Viewer *)data;
+ float  x_scale;
+ float  y_scale;
+
+ x_scale = (1024.0 / v->image_info->image_width)  + 0.0005;
+ y_scale =  (768.0 / v->image_info->image_height) + 0.0005;
+
+ gtk_spin_button_set_value(v->scale_spinbutton_x_factor, x_scale);
+ gtk_spin_button_set_value(v->scale_spinbutton_y_factor, y_scale);
+ gtk_spin_button_set_value(v->scale_spinbutton_output_width,  1024.0);
+ gtk_spin_button_set_value(v->scale_spinbutton_output_height,  768.0);
+ v->x_scale_factor = x_scale;
+ v->y_scale_factor = x_scale;
+}
+
+static void xsane_viewer_button_set_scale_768_1024(GtkWidget *button, gpointer data)
+{
+ Viewer *v = (Viewer *)data;
+ float  x_scale;
+ float  y_scale;
+
+ x_scale =   (768.0 / v->image_info->image_width)  + 0.0005;
+ y_scale =  (1024.0 / v->image_info->image_height) + 0.0005;
+
+ gtk_spin_button_set_value(v->scale_spinbutton_x_factor, x_scale);
+ gtk_spin_button_set_value(v->scale_spinbutton_y_factor, y_scale);
+ gtk_spin_button_set_value(v->scale_spinbutton_output_width,   768.0);
+ gtk_spin_button_set_value(v->scale_spinbutton_output_height, 1024.0);
+ v->x_scale_factor = x_scale;
+ v->y_scale_factor = x_scale;
+}
+
 /* ---------------------------------------------------------------------------------------------------------------------- */
 
 static void xsane_viewer_spinbutton_int_changed(GtkWidget *spinbutton, gpointer data)
@@ -553,11 +658,30 @@
 
   adjustment = (GtkAdjustment *) gtk_adjustment_new(1.0, 0.01, 10.0, 0.01, 0.1, 0.0);
   spinbutton = gtk_spin_button_new(adjustment, 0, 2);
+  v->scale_spinbutton_x_factor = (GtkSpinButton *)spinbutton;
   g_signal_connect(GTK_OBJECT(spinbutton), DEF_GTK_SIGNAL_SPINBUTTON_VALUE_CHANGED, (GtkSignalFunc) xsane_viewer_spinbutton_float_changed, (void *) &v->x_scale_factor);
+  g_signal_connect(GTK_OBJECT(spinbutton), DEF_GTK_SIGNAL_SPINBUTTON_VALUE_CHANGED, (GtkSignalFunc) xsane_viewer_spinbutton_float_changed_set_scale_output_width, (void *) v);
   gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(spinbutton), TRUE);
-  gtk_box_pack_end(GTK_BOX(hbox), spinbutton, FALSE, FALSE, 10);
+  gtk_box_pack_start(GTK_BOX(hbox), spinbutton, FALSE, FALSE, 10);
+  gtk_widget_show(spinbutton);
+
+  label = gtk_label_new(TEXT_X_WIDTH_OUTPUT); 
+  gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 10);
+  gtk_widget_show(label);
+
+  adjustment = (GtkAdjustment *) gtk_adjustment_new(v->image_info->image_width, 1.0, G_MAXFLOAT, 1.0, 10.0, 0.0);
+  spinbutton = gtk_spin_button_new(adjustment, 0, 0);
+  v->scale_spinbutton_output_width = (GtkSpinButton *) spinbutton;
+  g_signal_connect(GTK_OBJECT(spinbutton), DEF_GTK_SIGNAL_SPINBUTTON_VALUE_CHANGED, (GtkSignalFunc) xsane_viewer_spinbutton_float_changed_set_scale_x_factor, (void *) v);
+  gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(spinbutton), TRUE);
+  gtk_box_pack_start(GTK_BOX(hbox), spinbutton, FALSE, FALSE, 10);
   gtk_widget_show(spinbutton);
 
+  button = gtk_button_new_with_label("1024x768");
+  g_signal_connect(GTK_OBJECT(button), "pressed", (GtkSignalFunc) xsane_viewer_button_set_scale_1024_768, (void *) v);
+  gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 10);
+  gtk_widget_show(button);
+
   /* y_scale factor: <-> */
 
   v->y_scale_factor = 1.0;
@@ -572,11 +696,30 @@
 
   adjustment = (GtkAdjustment *) gtk_adjustment_new(1.0, 0.01, 10.0, 0.01, 0.1, 0.0);
   spinbutton = gtk_spin_button_new(adjustment, 0, 2);
+  v->scale_spinbutton_y_factor = (GtkSpinButton *)spinbutton;
   g_signal_connect(GTK_OBJECT(spinbutton), DEF_GTK_SIGNAL_SPINBUTTON_VALUE_CHANGED, (GtkSignalFunc) xsane_viewer_spinbutton_float_changed, (void *) &v->y_scale_factor);
+  g_signal_connect(GTK_OBJECT(spinbutton), DEF_GTK_SIGNAL_SPINBUTTON_VALUE_CHANGED, (GtkSignalFunc) xsane_viewer_spinbutton_float_changed_set_scale_output_height, (void *)v);
   gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(spinbutton), TRUE);
-  gtk_box_pack_end(GTK_BOX(hbox), spinbutton, FALSE, FALSE, 10);
+  gtk_box_pack_start(GTK_BOX(hbox), spinbutton, FALSE, FALSE, 10);
   gtk_widget_show(spinbutton);
 
+  label = gtk_label_new(TEXT_Y_HEIGHT_OUTPUT); 
+  gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 10);
+  gtk_widget_show(label);
+
+  adjustment = (GtkAdjustment *) gtk_adjustment_new(v->image_info->image_height, 1.0, G_MAXFLOAT, 1.0, 10.0, 0.0);
+  spinbutton = gtk_spin_button_new(adjustment, 0, 0);
+  v->scale_spinbutton_output_height = (GtkSpinButton *) spinbutton;
+  g_signal_connect(GTK_OBJECT(spinbutton), DEF_GTK_SIGNAL_SPINBUTTON_VALUE_CHANGED, (GtkSignalFunc) xsane_viewer_spinbutton_float_changed_set_scale_y_factor, (void *) v);
+  gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(spinbutton), TRUE);
+  gtk_box_pack_start(GTK_BOX(hbox), spinbutton, FALSE, FALSE, 10);
+  gtk_widget_show(spinbutton);
+
+  button = gtk_button_new_with_label("768x1024");
+  g_signal_connect(GTK_OBJECT(button), "pressed", (GtkSignalFunc) xsane_viewer_button_set_scale_768_1024, (void *) v);
+  gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 10);
+  gtk_widget_show(button);
+
   /* Apply Cancel */
 
   hbox = gtk_hbox_new(FALSE, 0);
@@ -1226,6 +1369,8 @@
 
   xsane_read_pnm_header(infile, &image_info);
 
+  *v->image_info = image_info;
+
   pos0 = ftell(infile);
 
   if (!image_info.colors) /* == 0 (grayscale) ? */
@@ -1433,6 +1578,12 @@
   memset(v, 0, sizeof(*v));   
 
   v->filename = strdup(filename);
+  if ( (v->image_info = malloc(sizeof(*v->image_info))) == NULL) {
+    free(v);
+    DBG(DBG_error, "could not allocate memory\n");
+    return 0; 
+  }
+  memset(v->image_info, 0, sizeof(*v->image_info));
   v->reduce_to_lineart = reduce_to_lineart;
   v->zoom = 1.0;
   v->image_saved = FALSE;
diff -ru xsane-0.85_new-0.3/src/xsane-viewer.h xsane-0.85/src/xsane-viewer.h
--- xsane-0.85_new-0.3/src/xsane-viewer.h	Tue Apr 16 10:38:54 2002
+++ xsane-0.85/src/xsane-viewer.h	Tue Apr 16 14:02:07 2002
@@ -25,10 +25,13 @@
 #ifndef XSANE_VIEWER_H
 #define XSANE_VIEWER_H
 
+#include "xsane.h"
+
 #include <gdk/gdkkeysyms.h>
 #include <gdk/gdk.h>
 #include <gtk/gtk.h>
 
+
 typedef struct Viewer
 {
   struct Viewer *next_viewer;
@@ -36,6 +39,8 @@
   char *filename;
   char *output_filename;
 
+  struct Image_info *image_info;
+  
   int reduce_to_lineart;
   float zoom;
   int image_saved;
@@ -57,6 +62,10 @@
   GtkWidget *ocr;
   GtkWidget *clone;
   GtkWidget *scale;
+  GtkSpinButton *scale_spinbutton_x_factor;
+  GtkSpinButton *scale_spinbutton_y_factor;
+  GtkSpinButton *scale_spinbutton_output_width;
+  GtkSpinButton *scale_spinbutton_output_height;
 
   GtkWidget *despeckle;
   GtkWidget *blur;

--u3/rZRmxL6MmkK24--