[sane-devel] [RFC][PATCH] scanimage --batch="| pipe > %d.img" extension

Taisuke Yamada tyamadajp at list.rakugaki.org
Sun Sep 10 10:29:39 UTC 2006


Hi.

I have created a patch to make "scanimage --batch=" accept
command pipeline in addition to plain filename, and wondering
if this could be merged back to the original. I'm currently
scanning thousands of pages with ADF, and this extension
increases overall processing speed significantly.

Check out the following:

  $ time ./scanimage --batch=%.3d.pnm --batch-count=1
  Scanning 1 pages, incrementing by 1, numbering from 1
  Scanning page 1
  Scanned page 1. (scanner status = 5)
  real    0m14.579s
  user    0m0.088s
  sys     0m0.060s

  $ time ./scanimage --batch='| pnmflip -cw > %.3d.pnm' --batch-count=1
  Scanning page 1
  Scanned page 1. (scanner status = 5)
  real    0m14.931s
  user    0m4.740s
  sys     0m0.160s

  $ time sh -c './scanimage --batch=%.3d.pnm --batch-count=1; pnmflip -cw < 001.pnm > a && mv a 001.pnm'
  Scanning 1 pages, incrementing by 1, numbering from 1
  Scanning page 1
  Scanned page 1. (scanner status = 5)
  real    0m19.348s
  user    0m4.736s
  sys     0m0.140s

As you can see, doing on-the-fly conversion brings speed
advantage of nearly 25%, and it also reduces both disk I/O
and space requirement by 50%.

This is similar to scanadf extension posted some time ago, but
since scanimage is more flexible than scanadf, it'd be great
if this gets included as well.

Best Regards,
--
Taisuke Yamada <tyamadajp at spam.rakugaki.org>
2268 E9A2 D4F9 014E F11D  1DF7 DCA3 83BC 78E5 CD3A

Message to my public address may not be handled in a timely manner.
For a direct contact, please use my private address on my namecard.

-------------- next part --------------
--- scanimage.c.orig	2006-09-10 13:21:41.000000000 +0900
+++ scanimage.c	2006-09-10 13:21:45.000000000 +0900
@@ -2117,7 +2117,7 @@
 	{
 	  char path[PATH_MAX];
 	  if (batch)		/* format is NULL unless batch mode */
-	    sprintf (path, format, n);	/* love --(C++) */
+	    sprintf (path, format, n, n, n, n, n);	/* love --(C++) */
 
 
 	  if (batch)
@@ -2146,15 +2146,21 @@
 	    {
 	      fprintf (stderr, "%s: sane_start: %s\n",
 		       prog_name, sane_strstatus (status));
-	      fclose (stdout);
 	      break;
 	    }
 
-	  if (batch && NULL == freopen (path, "w", stdout))
+	  if (batch)
 	    {
-	      fprintf (stderr, "cannot open %s\n", path);
-	      sane_cancel (device);
-	      return SANE_STATUS_ACCESS_DENIED;
+	      FILE *tmp = (path[0] == '|')
+		? popen (&path[1], "w") : freopen (path, "w", stdout);
+
+	      if (tmp == NULL)
+		{
+		  fprintf (stderr, "cannot open %s\n", path);
+		  sane_cancel (device);
+		  return SANE_STATUS_ACCESS_DENIED;
+		}
+	      stdout = tmp;
 	    }
 
 	  status = scan_it ();
@@ -2179,6 +2185,14 @@
 		}
 	      break;
 	    }			/* switch */
+
+	  {
+	    struct stat buf;
+	    fstat (fileno (stdout), &buf);
+	    if (S_ISFIFO (buf.st_mode))
+	      pclose (stdout);
+	  }
+
 	  n += batch_increment;
 	}
       while ((batch


More information about the sane-devel mailing list