Implementation was a little intrusive because there is no recovery
from calling freopen()  on stdout. This preliminary patch follows
the recommendations of the C FAQ and introduces an explicit
stream variable. I've only done light testing.

http://c-faq.com/stdio/undofreopen.html

$ scanimage --batch 2> /dev/null | cat
out1.pnm
out2.pnm

Cheers,
Jeff


--- /tmp/orig/sane-backends-1.0.23/frontend/scanimage.c 2014-05-12
13:44:40.000000000 -0700
+++ sane-backends-1.0.23/frontend/scanimage.c 2014-05-12
14:17:18.000000000 -0700
@@ -1124,7 +1124,8 @@
 }

 static void
-write_pnm_header (SANE_Frame format, int width, int height, int depth)
+write_pnm_header (SANE_Frame format, int width, int height, int depth,
+                  FILE *ofp)
 {
   /* The netpbm-package does not define raw image data with maxval > 255. */
   /* But writing maxval 65535 for 16bit data gives at least a chance */
@@ -1135,20 +1136,20 @@
     case SANE_FRAME_GREEN:
     case SANE_FRAME_BLUE:
     case SANE_FRAME_RGB:
-      printf ("P6\n# SANE data follows\n%d %d\n%d\n", width, height,
+      fprintf (ofp, "P6\n# SANE data follows\n%d %d\n%d\n", width, height,
       (depth <= 8) ? 255 : 65535);
       break;

     default:
       if (depth == 1)
- printf ("P4\n# SANE data follows\n%d %d\n", width, height);
+ fprintf (ofp, "P4\n# SANE data follows\n%d %d\n", width, height);
       else
- printf ("P5\n# SANE data follows\n%d %d\n%d\n", width, height,
+ fprintf (ofp, "P5\n# SANE data follows\n%d %d\n%d\n", width, height,
  (depth <= 8) ? 255 : 65535);
       break;
     }
 #ifdef __EMX__ /* OS2 - write in binary mode. */
-  _fsetmode (stdout, "b");
+  _fsetmode (ofp, "b");
 #endif
 }

@@ -1183,7 +1184,7 @@
 }

 static SANE_Status
-scan_it (void)
+scan_it (FILE *ofp)
 {
   int i, len, first_frame = 1, offset = 0, must_buffer = 0, hundred_percent;
   SANE_Byte min = 0xff, max = 0;
@@ -1273,10 +1274,10 @@
     sanei_write_tiff_header (parm.format,
      parm.pixels_per_line, parm.lines,
      parm.depth, resolution_value,
-     icc_profile);
+     icc_profile, ofp);
   else
     write_pnm_header (parm.format, parm.pixels_per_line,
-      parm.lines, parm.depth);
+      parm.lines, parm.depth, ofp);
  }
       break;

@@ -1397,7 +1398,7 @@
   else /* ! must_buffer */
     {
       if ((output_format == OUTPUT_TIFF) || (parm.depth != 16))
- fwrite (buffer, 1, len, stdout);
+ fwrite (buffer, 1, len, ofp);
       else
  {
 #if !defined(WORDS_BIGENDIAN)
@@ -1408,7 +1409,7 @@
     {
       if (len > 0)
  {
-  fwrite (buffer, 1, 1, stdout);
+  fwrite (buffer, 1, 1, ofp);
   buffer[0] = (SANE_Byte) hang_over;
   hang_over = -1;
   start = 1;
@@ -1429,7 +1430,7 @@
       len--;
     }
 #endif
-  fwrite (buffer, 1, len, stdout);
+  fwrite (buffer, 1, len, ofp);
  }
     }

@@ -1453,10 +1454,10 @@
       if (output_format == OUTPUT_TIFF)
  sanei_write_tiff_header (parm.format, parm.pixels_per_line,
  image.height, parm.depth, resolution_value,
- icc_profile);
+ icc_profile, ofp);
       else
  write_pnm_header (parm.format, parm.pixels_per_line,
-                          image.height, parm.depth);
+                          image.height, parm.depth, ofp);

 #if !defined(WORDS_BIGENDIAN)
       /* multibyte pnm file may need byte swap to LE */
@@ -1474,11 +1475,11 @@
  }
 #endif

- fwrite (image.data, 1, image.height * image.width, stdout);
+ fwrite (image.data, 1, image.height * image.width, ofp);
     }

   /* flush the output buffer */
-  fflush( stdout );
+  fflush( ofp );

 cleanup:
   if (image.data)
@@ -1714,6 +1715,7 @@
   SANE_Status status;
   char *full_optstring;
   SANE_Int version_code;
+  FILE *ofp;

   atexit (scanimage_exit);

@@ -2236,12 +2238,15 @@
     format = "out%d.pnm";
  }

+      if (!batch)
+        ofp = stdout;
+
       if (batch)
  fprintf (stderr,
  "Scanning %d pages, incrementing by %d, numbering from %d\n",
  batch_count, batch_increment, batch_start_at);

-      else if(isatty(fileno(stdout))){
+      else if(isatty(fileno(ofp))){
  fprintf (stderr,"%s: output is not a file, exiting\n", prog_name);
         exit (1);
       }
@@ -2274,7 +2279,11 @@
     {
       fprintf (stderr, "Batch terminated, %d pages scanned\n",
        (n - batch_increment));
-      fclose (stdout);
+      if (ofp)
+ {
+  fclose (ofp);
+  ofp = NULL;
+ }
       break; /* get out of this loop */
     }
  }
@@ -2294,19 +2303,27 @@
     {
       fprintf (stderr, "%s: sane_start: %s\n",
        prog_name, sane_strstatus (status));
-      fclose (stdout);
-      break;
+      if (ofp)
+ {
+  fclose (ofp);
+  ofp = NULL;
+  break;
+ }
     }

+
   /* write to .part file while scanning is in progress */
-  if (batch && NULL == freopen (part_path, "w", stdout))
+  if (batch)
+    ofp = fopen (part_path, "w");
+
+  if (batch && ofp == NULL)
     {
       fprintf (stderr, "cannot open %s\n", part_path);
       sane_cancel (device);
       return SANE_STATUS_ACCESS_DENIED;
     }

-  status = scan_it ();
+  status = scan_it (ofp);
   if (batch)
     {
       fprintf (stderr, "Scanned page %d.", n);
@@ -2321,10 +2338,16 @@
       if (batch)
  {
   /* close output file by redirecting, do not close
-     stdout here! */
-  if (NULL == freopen ("/dev/null", "w", stdout))
+     ofp here! */
+                  int r = -1;
+  if (ofp)
     {
-      fprintf (stderr, "cannot open /dev/null\n");
+      r = fclose(ofp);
+      ofp = NULL;
+    }
+  if (0 != r)
+    {
+      fprintf (stderr, "cannot close image file\n");
       sane_cancel (device);
       return SANE_STATUS_ACCESS_DENIED;
     }
@@ -2338,13 +2361,19 @@
   sane_cancel (device);
   return SANE_STATUS_ACCESS_DENIED;
  }
+      fprintf (stdout, "%s\n", path);
+      fflush (stdout);
     }
  }
       break;
     default:
       if (batch)
  {
-  fclose (stdout);
+  if (ofp)
+    {
+      fclose (ofp);
+      ofp = NULL;
+    }
   unlink (part_path);
  }
       break;
--- /tmp/orig/sane-backends-1.0.23/frontend/stiff.c 2011-06-27
10:40:22.000000000 -0700
+++ sane-backends-1.0.23/frontend/stiff.c 2014-05-12 14:17:18.000000000 -0700
@@ -586,10 +586,10 @@

 void
 sanei_write_tiff_header (SANE_Frame format, int width, int height, int depth,
-                         int resolution, const char *icc_profile)
+                         int resolution, const char *icc_profile, FILE *ofp)
 {
 #ifdef __EMX__ /* OS2 - write in binary mode. */
-    _fsetmode(stdout, "b");
+    _fsetmode(ofp, "b");
 #endif
     switch (format)
     {
@@ -597,14 +597,14 @@
     case SANE_FRAME_GREEN:
     case SANE_FRAME_BLUE:
     case SANE_FRAME_RGB:
-        write_tiff_color_header (stdout, width, height, depth,
resolution, icc_profile);
+        write_tiff_color_header (ofp, width, height, depth,
resolution, icc_profile);
         break;

     default:
         if (depth == 1)
-            write_tiff_bw_header (stdout, width, height, resolution);
+            write_tiff_bw_header (ofp, width, height, resolution);
         else
-            write_tiff_grey_header (stdout, width, height, depth,
resolution, icc_profile);
+            write_tiff_grey_header (ofp, width, height, depth,
resolution, icc_profile);
         break;
     }
 }
--- /tmp/orig/sane-backends-1.0.23/frontend/stiff.h 2011-06-27
10:40:22.000000000 -0700
+++ sane-backends-1.0.23/frontend/stiff.h 2014-05-12 14:17:18.000000000 -0700
@@ -17,4 +17,4 @@

 void
 sanei_write_tiff_header (SANE_Frame format, int width, int height, int depth,
-                         int resolution, const char *icc_profile);
+                         int resolution, const char *icc_profile, FILE *ofp);

Attachment: names-to-stdout-1.0.gz
Description: GNU Zip compressed data

-- 
sane-devel mailing list: sane-devel@lists.alioth.debian.org
http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/sane-devel
Unsubscribe: Send mail with subject "unsubscribe your_password"
             to sane-devel-requ...@lists.alioth.debian.org

Reply via email to