[sane-devel] [PATCH] 16bpp support for xscanimage

Sergey Vlasov vsu at altlinux.ru
Tue Nov 12 14:18:10 GMT 2002


Hello!

I have added support for 16bpp mode in xscanimage (in standalone mode,
don't know if the current Gimp version supports more than 8 bits per
channel).

Only SANE_FRAME_GRAY and SANE_FRAME_RGB are supported with depth > 8 -
separate SANE_FRAME_{RED,GREEN,BLUE} transfers are not supported.

-- 
Sergey Vlasov
-------------- next part --------------
--- sane-frontends/src/xscanimage.c.16bpp	Thu Oct 24 15:31:55 2002
+++ sane-frontends/src/xscanimage.c	Tue Nov 12 15:48:44 2002
@@ -126,6 +126,8 @@
     GtkWidget *filename_entry;
     FILE *out;
     long header_size;
+    gboolean have_odd_byte;
+    guint8 odd_byte;
 #ifdef HAVE_LIBGIMP_GIMP_H
     /* for GIMP mode: */
     gint32 image_ID;
@@ -145,6 +147,7 @@
 static gint seldev = -1;	/* The selected device */
 static gint defdev = -1;	/* The default device */
 static gint ndevs;		/* The number of available devices */
+static gboolean little_endian;	/* Is this computer little-endian ?*/
 static struct option long_options[] =
   {
     {"help", no_argument, NULL, 'h'},
@@ -163,6 +166,18 @@
 static void scan_start (void);
 static void scan_done (void);
 
+/* Test if this machine is little endian (from coolscan.c) */
+static gboolean
+calc_little_endian (void)
+{
+  SANE_Int testvalue = 255;
+  u_int8_t *firstbyte = (u_int8_t *) & testvalue;
+
+  if (*firstbyte == 255)
+    return TRUE;
+  return FALSE;
+}
+
 #ifdef HAVE_LIBGIMP_GIMP_H
 
 static int
@@ -589,6 +604,40 @@
 #endif /* HAVE_LIBGIMP_GIMP_H */
 
 static void
+write_swapped_words(FILE *f, char *buf, guint len)
+{
+  char tmp_buf[2];
+  char tmp;
+  unsigned int i;
+
+  if (!len)
+    return;
+  if (scan_win.have_odd_byte)
+    {
+      tmp_buf[0] = *buf++;
+      tmp_buf[1] = scan_win.odd_byte;
+      fwrite(tmp_buf, 1, 2, f);
+      --len;
+      scan_win.have_odd_byte = FALSE;
+    }
+  if (len)
+    {
+      for (i = 1; i < len; i += 2)
+	{
+	  tmp = buf[i];
+	  buf[i] = buf[i - 1];
+	  buf[i - 1] = tmp;
+	}
+      fwrite(buf, 1, len & ~1, f);
+      if (len & 1)
+	{
+	  scan_win.have_odd_byte = TRUE;
+	  scan_win.odd_byte = buf[len - 1];
+	}
+    }
+}
+
+static void
 input_available (gpointer data, gint source, GdkInputCondition cond)
 {
   SANE_Handle dev = gsg_dialog_get_device (dialog);
@@ -652,7 +701,12 @@
 	{
 	case SANE_FRAME_GRAY:
 	  if (scan_win.mode == STANDALONE)
-	    fwrite (buf, 1, len, scan_win.out);
+	    {
+	      if (scan_win.param.depth > 8 && little_endian)
+		write_swapped_words(scan_win.out, buf, len);
+	      else
+		fwrite (buf, 1, len, scan_win.out);
+	    }
 #ifdef HAVE_LIBGIMP_GIMP_H
 	  else
 	    {
@@ -693,7 +747,12 @@
 
 	case SANE_FRAME_RGB:
 	  if (scan_win.mode == STANDALONE)
-	    fwrite (buf, 1, len, scan_win.out);
+	    {
+	      if (scan_win.param.depth > 8 && little_endian)
+		write_swapped_words(scan_win.out, buf, len);
+	      else
+		fwrite (buf, 1, len, scan_win.out);
+	    }
 #ifdef HAVE_LIBGIMP_GIMP_H
 	  else
 	    {
@@ -933,6 +992,7 @@
 
   scan_win.num_bytes = scan_win.param.lines * scan_win.param.bytes_per_line;
   scan_win.bytes_read = 0;
+  scan_win.have_odd_byte = FALSE;
 
   switch (scan_win.param.format)
     {
@@ -949,10 +1009,20 @@
 	{
 	  switch (scan_win.param.format)
 	    {
-	    case SANE_FRAME_RGB:
 	    case SANE_FRAME_RED:
 	    case SANE_FRAME_GREEN:
 	    case SANE_FRAME_BLUE:
+	      if (scan_win.param.depth > 8)
+		{
+		  gsg_set_sensitivity (dialog, TRUE);
+		  snprintf (buf, sizeof (buf),
+			    "Separate channel transfers are not supported "
+			    "with %d bits/channel.", scan_win.param.depth);
+		  gsg_error (buf);
+		  return;
+		}
+	      /*FALLTHROUGH*/
+	    case SANE_FRAME_RGB:
 	      fprintf (scan_win.out, "P6\n# SANE data follows\n%d %d\n%d\n",
 		       scan_win.param.pixels_per_line, scan_win.param.lines,
 		       (scan_win.param.depth <= 8) ? 255 : 65535);
@@ -1831,6 +1901,7 @@
   DBG_INIT();
   DBG(DBG_error, "xscanimage (version: %s, package: %s) starting\n", VERSION,
       PACKAGE);
+  little_endian = calc_little_endian();
   scan_win.mode = STANDALONE;
   gtk_quit_flag = 0;
   prog_name = strrchr (argv[0], '/');
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
URL: <http://alioth-lists.debian.net/pipermail/sane-devel/attachments/20021112/65039227/attachment.sig>


More information about the sane-devel mailing list