1 /* scanimage -- command line scanning utility
2    Uses the SANE library.
3    Copyright (C) 2015 Rolf Bensch <rolf at bensch hyphen online dot de>
4    Copyright (C) 1996, 1997, 1998 Andreas Beck and David Mosberger
5 
6    Copyright (C) 1999 - 2009 by the SANE Project -- See AUTHORS and ChangeLog
7    for details.
8 
9    For questions and comments contact the sane-devel mailinglist (see
10    http://www.sane-project.org/mailing-lists.html).
11 
12    This program is free software; you can redistribute it and/or
13    modify it under the terms of the GNU General Public License as
14    published by the Free Software Foundation; either version 2 of the
15    License, or (at your option) any later version.
16 
17    This program is distributed in the hope that it will be useful, but
18    WITHOUT ANY WARRANTY; without even the implied warranty of
19    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20    General Public License for more details.
21 
22    You should have received a copy of the GNU General Public License
23    along with this program.  If not, see <https://www.gnu.org/licenses/>.
24 */
25 
26 #ifdef _AIX
27 # include "../include/lalloca.h"                /* MUST come first for AIX! */
28 #endif
29 
30 #include "../include/sane/config.h"
31 #include "../include/lalloca.h"
32 
33 #include <assert.h>
34 #include "lgetopt.h"
35 #include <inttypes.h>
36 #include <signal.h>
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #include <unistd.h>
41 #include <stdarg.h>
42 
43 #ifdef __FreeBSD__
44 #include <libgen.h>
45 #endif
46 
47 #if defined (__APPLE__) && defined (__MACH__)
48 #include <libgen.h>     // for basename()
49 #endif
50 
51 #include <sys/types.h>
52 #include <sys/stat.h>
53 
54 #ifdef HAVE_LIBPNG
55 #include <png.h>
56 #endif
57 
58 #ifdef HAVE_LIBJPEG
59 #include <jpeglib.h>
60 #endif
61 
62 #include "../include/_stdint.h"
63 
64 #include "../include/sane/sane.h"
65 #include "../include/sane/sanei.h"
66 #include "../include/sane/saneopts.h"
67 
68 #include "sicc.h"
69 #include "stiff.h"
70 
71 #ifdef HAVE_LIBJPEG
72 #include "jpegtopdf.h"
73 #endif
74 
75 #include "../include/md5.h"
76 
77 #ifndef PATH_MAX
78 #define PATH_MAX 1024
79 #endif
80 
81 typedef struct
82 {
83   uint8_t *data;
84   int width;    /*WARNING: this is in bytes, get pixel width from param*/
85   int height;
86   int x;
87   int y;
88   int num_channels;
89 }
90 Image;
91 
92 #define OPTION_FORMAT   1001
93 #define OPTION_MD5	1002
94 #define OPTION_BATCH_COUNT	1003
95 #define OPTION_BATCH_START_AT	1004
96 #define OPTION_BATCH_DOUBLE	1005
97 #define OPTION_BATCH_INCREMENT	1006
98 #define OPTION_BATCH_PROMPT    1007
99 #define OPTION_BATCH_PRINT     1008
100 
101 #define BATCH_COUNT_UNLIMITED -1
102 
103 static struct option basic_options[] = {
104   {"device-name", required_argument, NULL, 'd'},
105   {"list-devices", no_argument, NULL, 'L'},
106   {"formatted-device-list", required_argument, NULL, 'f'},
107   {"help", no_argument, NULL, 'h'},
108   {"verbose", no_argument, NULL, 'v'},
109   {"progress", no_argument, NULL, 'p'},
110   {"output-file", required_argument, NULL, 'o'},
111   {"test", no_argument, NULL, 'T'},
112   {"all-options", no_argument, NULL, 'A'},
113   {"version", no_argument, NULL, 'V'},
114   {"buffer-size", optional_argument, NULL, 'B'},
115   {"batch", optional_argument, NULL, 'b'},
116   {"batch-count", required_argument, NULL, OPTION_BATCH_COUNT},
117   {"batch-start", required_argument, NULL, OPTION_BATCH_START_AT},
118   {"batch-double", no_argument, NULL, OPTION_BATCH_DOUBLE},
119   {"batch-increment", required_argument, NULL, OPTION_BATCH_INCREMENT},
120   {"batch-print", no_argument, NULL, OPTION_BATCH_PRINT},
121   {"batch-prompt", no_argument, NULL, OPTION_BATCH_PROMPT},
122   {"format", required_argument, NULL, OPTION_FORMAT},
123   {"accept-md5-only", no_argument, NULL, OPTION_MD5},
124   {"icc-profile", required_argument, NULL, 'i'},
125   {"dont-scan", no_argument, NULL, 'n'},
126   {0, 0, NULL, 0}
127 };
128 
129 #define OUTPUT_UNKNOWN  0
130 #define OUTPUT_PNM      1
131 #define OUTPUT_TIFF     2
132 #define OUTPUT_PNG      3
133 #define OUTPUT_JPEG     4
134 #define OUTPUT_PDF      5
135 
136 #define BASE_OPTSTRING	"d:hi:Lf:o:B::nvVTAbp"
137 #define STRIP_HEIGHT	256	/* # lines we increment image height */
138 
139 static struct option *all_options;
140 static int option_number_len;
141 static int *option_number;
142 static SANE_Handle device;
143 static int verbose;
144 static int progress = 0;
145 static const char* output_file = NULL;
146 static int test;
147 static int all;
148 static int output_format = OUTPUT_UNKNOWN;
149 static int help;
150 static int dont_scan = 0;
151 static const char *prog_name;
152 static int resolution_optind = -1, resolution_value = 0;
153 
154 /* window (area) related options */
155 static SANE_Option_Descriptor window_option[4]; /*updated descs for x,y,l,t*/
156 static int window[4]; /*index into backend options for x,y,l,t*/
157 static SANE_Word window_val[2]; /*the value for x,y options*/
158 static int window_val_user[2];	/* is x,y user-specified? */
159 
160 static int accept_only_md5_auth = 0;
161 static const char *icc_profile = NULL;
162 
163 static void fetch_options (SANE_Device * device);
164 static void scanimage_exit (int);
165 
166 static SANE_Word tl_x = 0;
167 static SANE_Word tl_y = 0;
168 static SANE_Word br_x = 0;
169 static SANE_Word br_y = 0;
170 static SANE_Byte *buffer;
171 static size_t buffer_size;
172 
173 
174 static void
auth_callback(SANE_String_Const resource, SANE_Char * username, SANE_Char * password)175 auth_callback (SANE_String_Const resource,
176 	       SANE_Char * username, SANE_Char * password)
177 {
178   char tmp[3 + 128 + SANE_MAX_USERNAME_LEN + SANE_MAX_PASSWORD_LEN], *wipe;
179   unsigned char md5digest[16];
180   int md5mode = 0, len, query_user = 1;
181   FILE *pass_file;
182   struct stat stat_buf;
183   char * uname = NULL;
184 
185   *tmp = 0;
186 
187   if (getenv ("HOME") != NULL)
188     {
189       if (strlen (getenv ("HOME")) < 500)
190 	{
191 	  sprintf (tmp, "%s/.sane/pass", getenv ("HOME"));
192 	}
193     }
194 
195   if ((strlen (tmp) > 0) && (stat (tmp, &stat_buf) == 0))
196     {
197 
198       if ((stat_buf.st_mode & 63) != 0)
199 	{
200 	  fprintf (stderr, "%s has wrong permissions (use at least 0600)\n",
201 		   tmp);
202 	}
203       else
204 	{
205 
206 	  if ((pass_file = fopen (tmp, "r")) != NULL)
207 	    {
208 
209 	      if (strstr (resource, "$MD5$") != NULL)
210 		len = (strstr (resource, "$MD5$") - resource);
211 	      else
212 		len = strlen (resource);
213 
214 	      while (fgets (tmp, sizeof(tmp), pass_file))
215 		{
216 
217 		  if ((strlen (tmp) > 0) && (tmp[strlen (tmp) - 1] == '\n'))
218 		    tmp[strlen (tmp) - 1] = 0;
219 		  if ((strlen (tmp) > 0) && (tmp[strlen (tmp) - 1] == '\r'))
220 		    tmp[strlen (tmp) - 1] = 0;
221 
222 		  char *colon1 = strchr (tmp, ':');
223 		  if (colon1 != NULL)
224 		    {
225 		      char *tmp_username = tmp;
226 		      *colon1 = '\0';
227 
228 		      char *colon2 = strchr (colon1 + 1, ':');
229 		      if (colon2 != NULL)
230 			{
231 			  char *tmp_password = colon1 + 1;
232 			  *colon2 = '\0';
233 
234 			  if ((strncmp (colon2 + 1, resource, len) == 0)
235 			      && ((int) strlen (colon2 + 1) == len))
236 			    {
237 			      if ((strlen (tmp_username) < SANE_MAX_USERNAME_LEN) &&
238                                   (strlen (tmp_password) < SANE_MAX_PASSWORD_LEN))
239                                 {
240                                   strncpy (username, tmp_username, SANE_MAX_USERNAME_LEN);
241                                   strncpy (password, tmp_password, SANE_MAX_PASSWORD_LEN);
242 
243                                   query_user = 0;
244                                   break;
245                                 }
246 			    }
247 			}
248 		    }
249 		}
250 
251 	      fclose (pass_file);
252 	    }
253 	}
254     }
255 
256   if (strstr (resource, "$MD5$") != NULL)
257     {
258       md5mode = 1;
259       len = (strstr (resource, "$MD5$") - resource);
260       if (query_user == 1)
261 	fprintf (stderr, "Authentication required for resource %*.*s. "
262 		 "Enter username: ", len, len, resource);
263     }
264   else
265     {
266 
267       if (accept_only_md5_auth != 0)
268 	{
269 	  fprintf (stderr, "ERROR: backend requested plain-text password\n");
270 	  return;
271 	}
272       else
273 	{
274 	  fprintf (stderr,
275 		   "WARNING: backend requested plain-text password\n");
276 	  query_user = 1;
277 	}
278 
279       if (query_user == 1)
280 	fprintf (stderr,
281 		 "Authentication required for resource %s. Enter username: ",
282 		 resource);
283     }
284 
285   if (query_user == 1)
286     uname = fgets (username, SANE_MAX_USERNAME_LEN, stdin);
287 
288   if (uname != NULL && (strlen (username)) && (username[strlen (username) - 1] == '\n'))
289     username[strlen (username) - 1] = 0;
290 
291   if (query_user == 1)
292     {
293 #ifdef HAVE_GETPASS
294       strcpy (password, (wipe = getpass ("Enter password: ")));
295       memset (wipe, 0, strlen (password));
296 #else
297       printf("OS has no getpass().  User Queries will not work\n");
298 #endif
299     }
300 
301   if (md5mode)
302     {
303 
304       sprintf (tmp, "%.128s%.*s", (strstr (resource, "$MD5$")) + 5,
305 	       SANE_MAX_PASSWORD_LEN - 1, password);
306 
307       md5_buffer (tmp, strlen (tmp), md5digest);
308 
309       memset (password, 0, SANE_MAX_PASSWORD_LEN);
310 
311       sprintf (password, "$MD5$%02x%02x%02x%02x%02x%02x%02x%02x"
312 	       "%02x%02x%02x%02x%02x%02x%02x%02x",
313 	       md5digest[0], md5digest[1],
314 	       md5digest[2], md5digest[3],
315 	       md5digest[4], md5digest[5],
316 	       md5digest[6], md5digest[7],
317 	       md5digest[8], md5digest[9],
318 	       md5digest[10], md5digest[11],
319 	       md5digest[12], md5digest[13], md5digest[14], md5digest[15]);
320     }
321 }
322 
323 static void
sighandler(int signum)324 sighandler (int signum)
325 {
326   static SANE_Bool first_time = SANE_TRUE;
327 
328   if (device)
329     {
330       fprintf (stderr, "%s: received signal %d\n", prog_name, signum);
331       if (first_time)
332 	{
333 	  first_time = SANE_FALSE;
334 	  fprintf (stderr, "%s: trying to stop scanner\n", prog_name);
335 	  sane_cancel (device);
336 	}
337       else
338 	{
339 	  fprintf (stderr, "%s: aborting\n", prog_name);
340 	  _exit (0);
341 	}
342     }
343 }
344 
345 static void
print_unit(SANE_Unit unit)346 print_unit (SANE_Unit unit)
347 {
348   switch (unit)
349     {
350     case SANE_UNIT_NONE:
351       break;
352     case SANE_UNIT_PIXEL:
353       fputs ("pel", stdout);
354       break;
355     case SANE_UNIT_BIT:
356       fputs ("bit", stdout);
357       break;
358     case SANE_UNIT_MM:
359       fputs ("mm", stdout);
360       break;
361     case SANE_UNIT_DPI:
362       fputs ("dpi", stdout);
363       break;
364     case SANE_UNIT_PERCENT:
365       fputc ('%', stdout);
366       break;
367     case SANE_UNIT_MICROSECOND:
368       fputs ("us", stdout);
369       break;
370     }
371 }
372 
373 static void
print_option(SANE_Device * device, int opt_num, const SANE_Option_Descriptor *opt)374 print_option (SANE_Device * device, int opt_num, const SANE_Option_Descriptor *opt)
375 {
376   const char *str, *last_break, *start;
377   SANE_Bool not_first = SANE_FALSE;
378   int i, column;
379 
380   if (opt->type == SANE_TYPE_GROUP){
381     printf ("  %s:\n", opt->title);
382     return;
383   }
384 
385   /* if both of these are set, option is invalid */
386   if((opt->cap & SANE_CAP_SOFT_SELECT) && (opt->cap & SANE_CAP_HARD_SELECT)){
387     fprintf (stderr, "%s: invalid option caps, SS+HS\n", prog_name);
388     return;
389   }
390 
391   /* invalid to select but not detect */
392   if((opt->cap & SANE_CAP_SOFT_SELECT) && !(opt->cap & SANE_CAP_SOFT_DETECT)){
393     fprintf (stderr, "%s: invalid option caps, SS!SD\n", prog_name);
394     return;
395   }
396   /* standard allows this, though it makes little sense
397   if(opt->cap & SANE_CAP_HARD_SELECT && !(opt->cap & SANE_CAP_SOFT_DETECT)){
398     fprintf (stderr, "%s: invalid option caps, HS!SD\n", prog_name);
399     return;
400   }*/
401 
402   /* if one of these three is not set, option is useless, skip it */
403   if(!(opt->cap &
404    (SANE_CAP_SOFT_SELECT | SANE_CAP_HARD_SELECT | SANE_CAP_SOFT_DETECT)
405   )){
406     return;
407   }
408 
409   /* print the option */
410   if ( !strcmp (opt->name, "x")
411     || !strcmp (opt->name, "y")
412     || !strcmp (opt->name, "t")
413     || !strcmp (opt->name, "l"))
414       printf ("    -%s", opt->name);
415   else
416     printf ("    --%s", opt->name);
417 
418   /* print the option choices */
419   if (opt->type == SANE_TYPE_BOOL)
420     {
421       fputs ("[=(", stdout);
422       if (opt->cap & SANE_CAP_AUTOMATIC)
423 	fputs ("auto|", stdout);
424       fputs ("yes|no)]", stdout);
425     }
426   else if (opt->type != SANE_TYPE_BUTTON)
427     {
428       fputc (' ', stdout);
429       if (opt->cap & SANE_CAP_AUTOMATIC)
430 	{
431 	  fputs ("auto|", stdout);
432 	  not_first = SANE_TRUE;
433 	}
434       switch (opt->constraint_type)
435 	{
436 	case SANE_CONSTRAINT_NONE:
437 	  switch (opt->type)
438 	    {
439 	    case SANE_TYPE_INT:
440 	      fputs ("<int>", stdout);
441 	      break;
442 	    case SANE_TYPE_FIXED:
443 	      fputs ("<float>", stdout);
444 	      break;
445 	    case SANE_TYPE_STRING:
446 	      fputs ("<string>", stdout);
447 	      break;
448 	    default:
449 	      break;
450 	    }
451 	  if (opt->type != SANE_TYPE_STRING
452            && opt->size > (SANE_Int) sizeof (SANE_Word))
453 	    fputs (",...", stdout);
454 	  break;
455 
456 	case SANE_CONSTRAINT_RANGE:
457 	  // Check for no range - some buggy backends can miss this out.
458           if (!opt->constraint.range)
459             {
460               fputs ("{no_range}", stdout);
461             }
462           else
463             {
464               if (opt->type == SANE_TYPE_INT)
465                 {
466                   if (!strcmp (opt->name, "x"))
467                     {
468                       printf ("%d..%d", opt->constraint.range->min,
469                               opt->constraint.range->max - tl_x);
470                     }
471                   else if (!strcmp (opt->name, "y"))
472                     {
473                       printf ("%d..%d", opt->constraint.range->min,
474                               opt->constraint.range->max - tl_y);
475                     }
476                   else
477                     {
478                       printf ("%d..%d", opt->constraint.range->min,
479                               opt->constraint.range->max);
480                     }
481                   print_unit (opt->unit);
482                   if (opt->size > (SANE_Int) sizeof(SANE_Word))
483                     fputs (",...", stdout);
484                   if (opt->constraint.range->quant)
485                     printf (" (in steps of %d)", opt->constraint.range->quant);
486                 }
487               else
488                 {
489                   if (!strcmp (opt->name, "x"))
490                     {
491                       printf ("%g..%g", SANE_UNFIX(opt->constraint.range->min),
492                               SANE_UNFIX(opt->constraint.range->max - tl_x));
493                     }
494                   else if (!strcmp (opt->name, "y"))
495                     {
496                       printf ("%g..%g", SANE_UNFIX(opt->constraint.range->min),
497                               SANE_UNFIX(opt->constraint.range->max - tl_y));
498                     }
499                   else
500                     {
501                       printf ("%g..%g", SANE_UNFIX(opt->constraint.range->min),
502                               SANE_UNFIX(opt->constraint.range->max));
503                     }
504                   print_unit (opt->unit);
505                   if (opt->size > (SANE_Int) sizeof(SANE_Word))
506                     fputs (",...", stdout);
507                   if (opt->constraint.range->quant)
508                     printf (" (in steps of %g)",
509                             SANE_UNFIX(opt->constraint.range->quant));
510                 }
511             }
512           break;
513 
514 	case SANE_CONSTRAINT_WORD_LIST:
515 	  // Check no words in list or no list -  - some buggy backends can miss this out.
516 	  // Note the check on < 1 as SANE_Int is signed.
517           if (!opt->constraint.word_list || (opt->constraint.word_list[0] < 1))
518             {
519               fputs ("{no_wordlist}", stdout);
520             }
521           else
522             {
523               for (i = 0; i < opt->constraint.word_list[0]; ++i)
524                 {
525                   if (not_first)
526                     fputc ('|', stdout);
527 
528                   not_first = SANE_TRUE;
529 
530                   if (opt->type == SANE_TYPE_INT)
531                     printf ("%d", opt->constraint.word_list[i + 1]);
532                   else
533                     printf ("%g", SANE_UNFIX(opt->constraint.word_list[i + 1]));
534                 }
535             }
536 
537 	  print_unit (opt->unit);
538 	  if (opt->size > (SANE_Int) sizeof (SANE_Word))
539 	    fputs (",...", stdout);
540 	  break;
541 
542 	case SANE_CONSTRAINT_STRING_LIST:
543           // Check for missing strings - some buggy backends can miss this out.
544           if (!opt->constraint.string_list || !opt->constraint.string_list[0])
545             {
546               fputs ("{no_stringlist}", stdout);
547             }
548           else
549             {
550               for (i = 0; opt->constraint.string_list[i]; ++i)
551                 {
552                   if (i > 0)
553                     fputc ('|', stdout);
554 
555                   fputs (opt->constraint.string_list[i], stdout);
556                 }
557             }
558           break;
559 	}
560     }
561 
562   /* print current option value */
563   if (opt->type == SANE_TYPE_STRING || opt->size == sizeof (SANE_Word))
564     {
565       if (SANE_OPTION_IS_ACTIVE (opt->cap))
566 	{
567 	  void *val = alloca (opt->size);
568 	  sane_control_option (device, opt_num, SANE_ACTION_GET_VALUE, val,
569 			       0);
570 	  fputs (" [", stdout);
571 	  switch (opt->type)
572 	    {
573 	    case SANE_TYPE_BOOL:
574 	      fputs (*(SANE_Bool *) val ? "yes" : "no", stdout);
575 	      break;
576 
577 	    case SANE_TYPE_INT:
578 	      if (strcmp (opt->name, "l") == 0)
579 		{
580 		  tl_x = (*(SANE_Fixed *) val);
581 		  printf ("%d", tl_x);
582 		}
583 	      else if (strcmp (opt->name, "t") == 0)
584 		{
585 		  tl_y = (*(SANE_Fixed *) val);
586 		  printf ("%d", tl_y);
587 		}
588 	      else if (strcmp (opt->name, "x") == 0)
589 		{
590 		  br_x = (*(SANE_Fixed *) val);
591 		  printf ("%d", br_x - tl_x);
592 		}
593 	      else if (strcmp (opt->name, "y") == 0)
594 		{
595 		  br_y = (*(SANE_Fixed *) val);
596 		  printf ("%d", br_y - tl_y);
597 		}
598 	      else
599 		printf ("%d", *(SANE_Int *) val);
600 	      break;
601 
602 	    case SANE_TYPE_FIXED:
603 
604 	      if (strcmp (opt->name, "l") == 0)
605 		{
606 		  tl_x = (*(SANE_Fixed *) val);
607 		  printf ("%g", SANE_UNFIX (tl_x));
608 		}
609 	      else if (strcmp (opt->name, "t") == 0)
610 		{
611 		  tl_y = (*(SANE_Fixed *) val);
612 		  printf ("%g", SANE_UNFIX (tl_y));
613 		}
614 	      else if (strcmp (opt->name, "x") == 0)
615 		{
616 		  br_x = (*(SANE_Fixed *) val);
617 		  printf ("%g", SANE_UNFIX (br_x - tl_x));
618 		}
619 	      else if (strcmp (opt->name, "y") == 0)
620 		{
621 		  br_y = (*(SANE_Fixed *) val);
622 		  printf ("%g", SANE_UNFIX (br_y - tl_y));
623 		}
624 	      else
625 		printf ("%g", SANE_UNFIX (*(SANE_Fixed *) val));
626 
627 	      break;
628 
629 	    case SANE_TYPE_STRING:
630 	      fputs ((char *) val, stdout);
631 	      break;
632 
633 	    default:
634 	      break;
635 	    }
636 	  fputc (']', stdout);
637 	}
638     }
639 
640   if (!SANE_OPTION_IS_ACTIVE (opt->cap))
641     fputs (" [inactive]", stdout);
642 
643   else if(opt->cap & SANE_CAP_HARD_SELECT)
644     fputs (" [hardware]", stdout);
645 
646   else if(!(opt->cap & SANE_CAP_SOFT_SELECT) && (opt->cap & SANE_CAP_SOFT_DETECT))
647     fputs (" [read-only]", stdout);
648 
649   else if (opt->cap & SANE_CAP_ADVANCED)
650     fputs (" [advanced]", stdout);
651 
652   fputs ("\n        ", stdout);
653 
654   column = 8;
655   last_break = 0;
656   start = opt->desc;
657   for (str = opt->desc; *str; ++str)
658     {
659       ++column;
660       if (*str == ' ')
661         last_break = str;
662       else if (*str == '\n'){
663         column=80;
664         last_break = str;
665       }
666       if (column >= 79 && last_break)
667         {
668           while (start < last_break)
669             fputc (*start++, stdout);
670           start = last_break + 1;	/* skip blank */
671           fputs ("\n        ", stdout);
672           column = 8 + (str - start);
673         }
674     }
675   while (*start)
676     fputc (*start++, stdout);
677   fputc ('\n', stdout);
678 }
679 
680 /* A scalar has the following syntax:
681 
682      V [ U ]
683 
684    V is the value of the scalar.  It is either an integer or a
685    floating point number, depending on the option type.
686 
687    U is an optional unit.  If not specified, the default unit is used.
688    The following table lists which units are supported depending on
689    what the option's default unit is:
690 
691      Option's unit:	Allowed units:
692 
693      SANE_UNIT_NONE:
694      SANE_UNIT_PIXEL:	pel
695      SANE_UNIT_BIT:	b (bit), B (byte)
696      SANE_UNIT_MM:	mm (millimeter), cm (centimeter), in or " (inches),
697      SANE_UNIT_DPI:	dpi
698      SANE_UNIT_PERCENT:	%
699      SANE_UNIT_PERCENT:	us
700  */
701 static const char *
parse_scalar(const SANE_Option_Descriptor * opt, const char *str, SANE_Word * value)702 parse_scalar (const SANE_Option_Descriptor * opt, const char *str,
703 	      SANE_Word * value)
704 {
705   char *end;
706   double v;
707 
708   if (opt->type == SANE_TYPE_FIXED)
709     v = strtod (str, &end) * (1 << SANE_FIXED_SCALE_SHIFT);
710   else
711     v = strtol (str, &end, 10);
712 
713   if (str == end)
714     {
715       fprintf (stderr,
716 	       "%s: option --%s: bad option value (rest of option: %s)\n",
717 	       prog_name, opt->name, str);
718       scanimage_exit (1);
719     }
720   str = end;
721 
722   switch (opt->unit)
723     {
724     case SANE_UNIT_NONE:
725     case SANE_UNIT_PIXEL:
726       break;
727 
728     case SANE_UNIT_BIT:
729       if (*str == 'b' || *str == 'B')
730 	{
731 	  if (*str++ == 'B')
732 	    v *= 8;
733 	}
734       break;
735 
736     case SANE_UNIT_MM:
737       if (str[0] == '\0')
738 	v *= 1.0;		/* default to mm */
739       else if (strcmp (str, "mm") == 0)
740 	str += sizeof ("mm") - 1;
741       else if (strcmp (str, "cm") == 0)
742 	{
743 	  str += sizeof ("cm") - 1;
744 	  v *= 10.0;
745 	}
746       else if (strcmp (str, "in") == 0 || *str == '"')
747 	{
748 	  if (*str++ != '"')
749 	    ++str;
750 	  v *= 25.4;		/* 25.4 mm/inch */
751 	}
752       else
753 	{
754 	  fprintf (stderr,
755 		   "%s: option --%s: illegal unit (rest of option: %s)\n",
756 		   prog_name, opt->name, str);
757 	  return 0;
758 	}
759       break;
760 
761     case SANE_UNIT_DPI:
762       if (strcmp (str, "dpi") == 0)
763 	str += sizeof ("dpi") - 1;
764       break;
765 
766     case SANE_UNIT_PERCENT:
767       if (*str == '%')
768 	++str;
769       break;
770 
771     case SANE_UNIT_MICROSECOND:
772       if (strcmp (str, "us") == 0)
773 	str += sizeof ("us") - 1;
774       break;
775     }
776 
777   if(v < 0){
778     *value = v - 0.5;
779   }
780   else{
781     *value = v + 0.5;
782   }
783 
784   return str;
785 }
786 
787 /* A vector has the following syntax:
788 
789      [ '[' I ']' ] S { [','|'-'] [ '[' I ']' S }
790 
791    The number in brackets (I), if present, determines the index of the
792    vector element to be set next.  If I is not present, the value of
793    last index used plus 1 is used.  The first index value used is 0
794    unless I is present.
795 
796    S is a scalar value as defined by parse_scalar().
797 
798    If two consecutive value specs are separated by a comma (,) their
799    values are set independently.  If they are separated by a dash (-),
800    they define the endpoints of a line and all vector values between
801    the two endpoints are set according to the value of the
802    interpolated line.  For example, [0]15-[255]15 defines a vector of
803    256 elements whose value is 15.  Similarly, [0]0-[255]255 defines a
804    vector of 256 elements whose value starts at 0 and increases to
805    255.  */
806 static void
parse_vector(const SANE_Option_Descriptor * opt, const char *str, SANE_Word * vector, size_t vector_length)807 parse_vector (const SANE_Option_Descriptor * opt, const char *str,
808 	      SANE_Word * vector, size_t vector_length)
809 {
810   SANE_Word value, prev_value = 0;
811   int index = -1, prev_index = 0;
812   char *end, separator = '\0';
813 
814   /* initialize vector to all zeroes: */
815   memset (vector, 0, vector_length * sizeof (SANE_Word));
816 
817   do
818     {
819       if (*str == '[')
820 	{
821 	  /* read index */
822 	  index = strtol (++str, &end, 10);
823 	  if (str == end || *end != ']')
824 	    {
825 	      fprintf (stderr, "%s: option --%s: closing bracket missing "
826 		       "(rest of option: %s)\n", prog_name, opt->name, str);
827 	      scanimage_exit (1);
828 	    }
829 	  str = end + 1;
830 	}
831       else
832 	++index;
833 
834       if (index < 0 || index >= (int) vector_length)
835 	{
836 	  fprintf (stderr,
837 		   "%s: option --%s: index %d out of range [0..%ld]\n",
838 		   prog_name, opt->name, index, (long) vector_length - 1);
839 	  scanimage_exit (1);
840 	}
841 
842       /* read value */
843       str = parse_scalar (opt, str, &value);
844       if (!str)
845         scanimage_exit (1);
846 
847       if (*str && *str != '-' && *str != ',')
848 	{
849 	  fprintf (stderr,
850 		   "%s: option --%s: illegal separator (rest of option: %s)\n",
851 		   prog_name, opt->name, str);
852 	  scanimage_exit (1);
853 	}
854 
855       /* store value: */
856       vector[index] = value;
857       if (separator == '-')
858 	{
859 	  /* interpolate */
860 	  double v, slope;
861 	  int i;
862 
863 	  v = (double) prev_value;
864 	  slope = ((double) value - v) / (index - prev_index);
865 
866 	  for (i = prev_index + 1; i < index; ++i)
867 	    {
868 	      v += slope;
869 	      vector[i] = (SANE_Word) v;
870 	    }
871 	}
872 
873       prev_index = index;
874       prev_value = value;
875       separator = *str++;
876     }
877   while (separator == ',' || separator == '-');
878 
879   if (verbose > 2)
880     {
881       int i;
882 
883       fprintf (stderr, "%s: value for --%s is: ", prog_name, opt->name);
884       for (i = 0; i < (int) vector_length; ++i)
885 	if (opt->type == SANE_TYPE_FIXED)
886 	  fprintf (stderr, "%g ", SANE_UNFIX (vector[i]));
887 	else
888 	  fprintf (stderr, "%d ", vector[i]);
889       fputc ('\n', stderr);
890     }
891 }
892 
893 static void
fetch_options(SANE_Device * device)894 fetch_options (SANE_Device * device)
895 {
896   const SANE_Option_Descriptor *opt;
897   SANE_Int num_dev_options;
898   int i, option_count;
899   SANE_Status status;
900 
901   opt = sane_get_option_descriptor (device, 0);
902   if (opt == NULL)
903     {
904       fprintf (stderr, "Could not get option descriptor for option 0\n");
905       scanimage_exit (1);
906     }
907 
908   status = sane_control_option (device, 0, SANE_ACTION_GET_VALUE,
909                                 &num_dev_options, 0);
910   if (status != SANE_STATUS_GOOD)
911     {
912       fprintf (stderr, "Could not get value for option 0: %s\n",
913                sane_strstatus (status));
914       scanimage_exit (1);
915     }
916 
917   /* build the full table of long options */
918   option_count = 0;
919   for (i = 1; i < num_dev_options; ++i)
920     {
921       opt = sane_get_option_descriptor (device, i);
922       if (opt == NULL)
923 	{
924 	  fprintf (stderr, "Could not get option descriptor for option %d\n",i);
925 	  scanimage_exit (1);
926 	}
927 
928       /* create command line option only for non-group options */
929       /* Also we sometimes see options with no name in rogue backends. */
930       if ((opt->type == SANE_TYPE_GROUP) || (opt->name == NULL))
931         continue;
932 
933       option_number[option_count] = i;
934 
935       all_options[option_count].name = (const char *) opt->name;
936       all_options[option_count].flag = 0;
937       all_options[option_count].val = 0;
938 
939       if (opt->type == SANE_TYPE_BOOL)
940 	all_options[option_count].has_arg = optional_argument;
941       else if (opt->type == SANE_TYPE_BUTTON)
942 	all_options[option_count].has_arg = no_argument;
943       else
944 	all_options[option_count].has_arg = required_argument;
945 
946       /* Look for scan resolution */
947       if ((opt->type == SANE_TYPE_FIXED || opt->type == SANE_TYPE_INT)
948 	  && opt->size == sizeof (SANE_Int)
949 	  && (opt->unit == SANE_UNIT_DPI)
950 	  && (strcmp (opt->name, SANE_NAME_SCAN_RESOLUTION) == 0))
951 	resolution_optind = i;
952 
953       /* Keep track of top-left corner options (if they exist at
954          all) and replace the bottom-right corner options by a
955          width/height option (if they exist at all).  */
956       if ((opt->type == SANE_TYPE_FIXED || opt->type == SANE_TYPE_INT)
957 	  && opt->size == sizeof (SANE_Int)
958 	  && (opt->unit == SANE_UNIT_MM || opt->unit == SANE_UNIT_PIXEL))
959 	{
960 	  if (strcmp (opt->name, SANE_NAME_SCAN_BR_X) == 0)
961 	    {
962 	      window[0] = i;
963 	      all_options[option_count].name = "width";
964 	      all_options[option_count].val = 'x';
965 	      window_option[0] = *opt;
966 	      window_option[0].title = "Scan width";
967 	      window_option[0].desc = "Width of scan-area.";
968 	      window_option[0].name = "x";
969 	    }
970 	  else if (strcmp (opt->name, SANE_NAME_SCAN_BR_Y) == 0)
971 	    {
972 	      window[1] = i;
973 	      all_options[option_count].name = "height";
974 	      all_options[option_count].val = 'y';
975 	      window_option[1] = *opt;
976 	      window_option[1].title = "Scan height";
977 	      window_option[1].desc = "Height of scan-area.";
978 	      window_option[1].name = "y";
979 	    }
980 	  else if (strcmp (opt->name, SANE_NAME_SCAN_TL_X) == 0)
981 	    {
982 	      window[2] = i;
983 	      all_options[option_count].val = 'l';
984 	      window_option[2] = *opt;
985 	      window_option[2].name = "l";
986 	    }
987 	  else if (strcmp (opt->name, SANE_NAME_SCAN_TL_Y) == 0)
988 	    {
989 	      window[3] = i;
990 	      all_options[option_count].val = 't';
991 	      window_option[3] = *opt;
992 	      window_option[3].name = "t";
993 	    }
994 	}
995       ++option_count;
996     }
997   memcpy (all_options + option_count, basic_options, sizeof (basic_options));
998   option_count += NELEMS (basic_options);
999   memset (all_options + option_count, 0, sizeof (all_options[0]));
1000 
1001   /* Initialize width & height options based on backend default
1002      values for top-left x/y and bottom-right x/y: */
1003   for (i = 0; i < 2; ++i)
1004     {
1005       if (window[i] && !window_val_user[i])
1006 	{
1007 	  sane_control_option (device, window[i],
1008                                 SANE_ACTION_GET_VALUE, &window_val[i], 0);
1009           if (window[i + 2]){
1010 	    SANE_Word pos;
1011 	    sane_control_option (device, window[i + 2],
1012 			       SANE_ACTION_GET_VALUE, &pos, 0);
1013 	    window_val[i] -= pos;
1014           }
1015 	}
1016     }
1017 }
1018 
1019 static void
set_option(SANE_Handle device, int optnum, void *valuep)1020 set_option (SANE_Handle device, int optnum, void *valuep)
1021 {
1022   const SANE_Option_Descriptor *opt;
1023   SANE_Status status;
1024   SANE_Word orig = 0;
1025   SANE_Int info = 0;
1026 
1027   opt = sane_get_option_descriptor (device, optnum);
1028   if (!opt)
1029     {
1030       if (verbose > 0)
1031         fprintf (stderr, "%s: ignored request to set invalid option %d\n",
1032                  prog_name, optnum);
1033       return;
1034     }
1035 
1036   if (!SANE_OPTION_IS_ACTIVE (opt->cap))
1037     {
1038       if (verbose > 0)
1039 	fprintf (stderr, "%s: ignored request to set inactive option %s\n",
1040 		 prog_name, opt->name);
1041       return;
1042     }
1043 
1044   if (opt->size == sizeof (SANE_Word) && opt->type != SANE_TYPE_STRING)
1045     orig = *(SANE_Word *) valuep;
1046 
1047   status = sane_control_option (device, optnum, SANE_ACTION_SET_VALUE,
1048 				valuep, &info);
1049   if (status != SANE_STATUS_GOOD)
1050     {
1051       fprintf (stderr, "%s: setting of option --%s failed (%s)\n",
1052 	       prog_name, opt->name, sane_strstatus (status));
1053       scanimage_exit (1);
1054     }
1055 
1056   if ((info & SANE_INFO_INEXACT) && opt->size == sizeof (SANE_Word))
1057     {
1058       if (opt->type == SANE_TYPE_INT)
1059 	fprintf (stderr, "%s: rounded value of %s from %d to %d\n",
1060 		 prog_name, opt->name, orig, *(SANE_Word *) valuep);
1061       else if (opt->type == SANE_TYPE_FIXED)
1062 	fprintf (stderr, "%s: rounded value of %s from %g to %g\n",
1063 		 prog_name, opt->name,
1064 		 SANE_UNFIX (orig), SANE_UNFIX (*(SANE_Word *) valuep));
1065     }
1066 
1067   if (info & SANE_INFO_RELOAD_OPTIONS)
1068     fetch_options (device);
1069 }
1070 
1071 static void
process_backend_option(SANE_Handle device, int optnum, const char *optarg)1072 process_backend_option (SANE_Handle device, int optnum, const char *optarg)
1073 {
1074   static SANE_Word *vector = 0;
1075   static size_t vector_size = 0;
1076   const SANE_Option_Descriptor *opt;
1077   size_t vector_length;
1078   SANE_Status status;
1079   SANE_Word value;
1080   void *valuep;
1081 
1082   opt = sane_get_option_descriptor (device, optnum);
1083 
1084   if (!SANE_OPTION_IS_SETTABLE (opt->cap))
1085     {
1086       fprintf (stderr, "%s: attempted to set readonly option %s\n",
1087                prog_name, opt->name);
1088       scanimage_exit (1);
1089     }
1090   if (!SANE_OPTION_IS_ACTIVE (opt->cap))
1091     {
1092       fprintf (stderr, "%s: attempted to set inactive option %s\n",
1093 	       prog_name, opt->name);
1094       scanimage_exit (1);
1095     }
1096 
1097   if ((opt->cap & SANE_CAP_AUTOMATIC) && optarg &&
1098       strncasecmp (optarg, "auto", 4) == 0)
1099     {
1100       status = sane_control_option (device, optnum, SANE_ACTION_SET_AUTO,
1101 				    0, 0);
1102       if (status != SANE_STATUS_GOOD)
1103 	{
1104 	  fprintf (stderr,
1105 		   "%s: failed to set option --%s to automatic (%s)\n",
1106 		   prog_name, opt->name, sane_strstatus (status));
1107 	  scanimage_exit (1);
1108 	}
1109       return;
1110     }
1111 
1112   valuep = &value;
1113   switch (opt->type)
1114     {
1115     case SANE_TYPE_BOOL:
1116       value = 1;		/* no argument means option is set */
1117       if (optarg)
1118 	{
1119 	  if (strncasecmp (optarg, "yes", strlen (optarg)) == 0)
1120 	    value = 1;
1121 	  else if (strncasecmp (optarg, "no", strlen (optarg)) == 0)
1122 	    value = 0;
1123 	  else
1124 	    {
1125 	      fprintf (stderr, "%s: option --%s: bad option value `%s'\n",
1126 		       prog_name, opt->name, optarg);
1127 	      scanimage_exit (1);
1128 	    }
1129 	}
1130       break;
1131 
1132     case SANE_TYPE_INT:
1133     case SANE_TYPE_FIXED:
1134       /* ensure vector is long enough: */
1135       vector_length = opt->size / sizeof (SANE_Word);
1136       if (vector_size < vector_length)
1137 	{
1138 	  vector_size = vector_length;
1139 	  vector = realloc (vector, vector_length * sizeof (SANE_Word));
1140 	  if (!vector)
1141 	    {
1142 	      fprintf (stderr, "%s: out of memory\n", prog_name);
1143 	      scanimage_exit (1);
1144 	    }
1145 	}
1146       parse_vector (opt, optarg, vector, vector_length);
1147       valuep = vector;
1148       break;
1149 
1150     case SANE_TYPE_STRING:
1151       valuep = malloc (opt->size);
1152       if (!valuep)
1153 	{
1154 	  fprintf (stderr, "%s: out of memory\n", prog_name);
1155 	  scanimage_exit (1);
1156 	}
1157       strncpy (valuep, optarg, opt->size);
1158       ((char *) valuep)[opt->size - 1] = 0;
1159       break;
1160 
1161     case SANE_TYPE_BUTTON:
1162       value = 0;		/* value doesn't matter */
1163       break;
1164 
1165     default:
1166       fprintf (stderr, "%s: duh, got unknown option type %d\n",
1167 	       prog_name, opt->type);
1168       return;
1169     }
1170   set_option (device, optnum, valuep);
1171   if (opt->type == SANE_TYPE_STRING && valuep)
1172     free(valuep);
1173 }
1174 
1175 static void
write_pnm_header(SANE_Frame format, int width, int height, int depth, FILE *ofp)1176 write_pnm_header (SANE_Frame format, int width, int height, int depth, FILE *ofp)
1177 {
1178   /* The netpbm-package does not define raw image data with maxval > 255. */
1179   /* But writing maxval 65535 for 16bit data gives at least a chance */
1180   /* to read the image. */
1181   switch (format)
1182     {
1183     case SANE_FRAME_RED:
1184     case SANE_FRAME_GREEN:
1185     case SANE_FRAME_BLUE:
1186     case SANE_FRAME_RGB:
1187       fprintf (ofp, "P6\n# SANE data follows\n%d %d\n%d\n", width, height,
1188 	      (depth <= 8) ? 255 : 65535);
1189       break;
1190 
1191     default:
1192       if (depth == 1)
1193        fprintf (ofp, "P4\n# SANE data follows\n%d %d\n", width, height);
1194       else
1195        fprintf (ofp, "P5\n# SANE data follows\n%d %d\n%d\n", width, height,
1196 		(depth <= 8) ? 255 : 65535);
1197       break;
1198     }
1199 #ifdef __EMX__			/* OS2 - write in binary mode. */
1200   _fsetmode (ofp, "b");
1201 #endif
1202 }
1203 
1204 #ifdef HAVE_LIBPNG
1205 static void
write_png_header(SANE_Frame format, int width, int height, int depth, int dpi, const char * icc_profile, FILE *ofp, png_structp* png_ptr, png_infop* info_ptr)1206 write_png_header (SANE_Frame format, int width, int height, int depth, int dpi, const char * icc_profile, FILE *ofp, png_structp* png_ptr, png_infop* info_ptr)
1207 {
1208   int color_type;
1209   /* PNG does not have imperial reference units, so we must convert to metric. */
1210   /* There are nominally 39.3700787401575 inches in a meter. */
1211   const double pixels_per_meter = dpi * 39.3700787401575;
1212   size_t icc_size = 0;
1213   void *icc_buffer;
1214 
1215   *png_ptr = png_create_write_struct
1216        (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
1217   if (!*png_ptr) {
1218     fprintf(stderr, "png_create_write_struct failed\n");
1219     exit(1);
1220   }
1221   *info_ptr = png_create_info_struct(*png_ptr);
1222   if (!*info_ptr) {
1223     fprintf(stderr, "png_create_info_struct failed\n");
1224     exit(1);
1225   }
1226   png_init_io(*png_ptr, ofp);
1227 
1228   switch (format)
1229     {
1230     case SANE_FRAME_RED:
1231     case SANE_FRAME_GREEN:
1232     case SANE_FRAME_BLUE:
1233     case SANE_FRAME_RGB:
1234       color_type = PNG_COLOR_TYPE_RGB;
1235       break;
1236 
1237     default:
1238       color_type = PNG_COLOR_TYPE_GRAY;
1239       break;
1240     }
1241 
1242   png_set_IHDR(*png_ptr, *info_ptr, width, height,
1243     depth, color_type, PNG_INTERLACE_NONE,
1244     PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
1245 
1246   png_set_pHYs(*png_ptr, *info_ptr,
1247     pixels_per_meter, pixels_per_meter,
1248     PNG_RESOLUTION_METER);
1249 
1250   if (icc_profile)
1251     {
1252       icc_buffer = sanei_load_icc_profile(icc_profile, &icc_size);
1253       if (icc_size > 0)
1254         {
1255 	  /* libpng will abort if the profile and image colour spaces do not match*/
1256 	  /* The data colour space field is at bytes 16 to 20 in an ICC profile */
1257 	  /* see: ICC.1:2010 § 7.2.6 */
1258 	  int is_gray_profile = strncmp((char *) icc_buffer + 16, "GRAY", 4) == 0;
1259 	  int is_rgb_profile = strncmp((char *) icc_buffer + 16, "RGB ", 4) == 0;
1260 	  if ((is_gray_profile && color_type == PNG_COLOR_TYPE_GRAY) ||
1261 	      (is_rgb_profile && color_type == PNG_COLOR_TYPE_RGB))
1262 	    {
1263 	      png_set_iCCP(*png_ptr, *info_ptr, basename(icc_profile), PNG_COMPRESSION_TYPE_BASE, icc_buffer, icc_size);
1264 	    }
1265 	  else
1266 	    {
1267 	      if (is_gray_profile)
1268 	        {
1269 		  fprintf(stderr, "Ignoring 'GRAY' space ICC profile because the image is RGB.\n");
1270 	        }
1271 	      if (is_rgb_profile)
1272 	        {
1273 		  fprintf(stderr, "Ignoring 'RGB ' space ICC profile because the image is Grayscale.\n");
1274 		}
1275 	    }
1276 	  free(icc_buffer);
1277 	}
1278     }
1279 
1280   png_write_info(*png_ptr, *info_ptr);
1281 }
1282 #endif
1283 
1284 #ifdef HAVE_LIBJPEG
1285 static void
write_jpeg_header(SANE_Frame format, int width, int height, int dpi, FILE *ofp, struct jpeg_compress_struct *cinfo, struct jpeg_error_mgr *jerr)1286 write_jpeg_header (SANE_Frame format, int width, int height, int dpi, FILE *ofp,
1287                    struct jpeg_compress_struct *cinfo,
1288                    struct jpeg_error_mgr *jerr)
1289 {
1290   cinfo->err = jpeg_std_error(jerr);
1291   jpeg_create_compress(cinfo);
1292   jpeg_stdio_dest(cinfo, ofp);
1293 
1294   cinfo->image_width = width;
1295   cinfo->image_height = height;
1296   switch (format)
1297     {
1298     case SANE_FRAME_RED:
1299     case SANE_FRAME_GREEN:
1300     case SANE_FRAME_BLUE:
1301     case SANE_FRAME_RGB:
1302       cinfo->in_color_space = JCS_RGB;
1303       cinfo->input_components = 3;
1304       break;
1305 
1306     default:
1307       cinfo->in_color_space = JCS_GRAYSCALE;
1308       cinfo->input_components = 1;
1309       break;
1310     }
1311 
1312   jpeg_set_defaults(cinfo);
1313   /* jpeg_set_defaults overrides density, be careful. */
1314   cinfo->density_unit = 1;   /* Inches */
1315   cinfo->X_density = cinfo->Y_density = dpi;
1316   cinfo->write_JFIF_header = TRUE;
1317 
1318   jpeg_set_quality(cinfo, 75, TRUE);
1319   jpeg_start_compress(cinfo, TRUE);
1320 }
1321 #endif
1322 
1323 static void *
advance(Image * image)1324 advance (Image * image)
1325 {
1326   if (++image->x >= image->width)
1327     {
1328       image->x = 0;
1329       if (++image->y >= image->height || !image->data)
1330 	{
1331 	  size_t old_size = 0, new_size;
1332 
1333 	  if (image->data)
1334 	    old_size = image->height * image->width * image->num_channels;
1335 
1336 	  image->height += STRIP_HEIGHT;
1337 	  new_size = image->height * image->width * image->num_channels;
1338 
1339 	  if (image->data)
1340 	    image->data = realloc (image->data, new_size);
1341 	  else
1342 	    image->data = malloc (new_size);
1343 	  if (image->data)
1344 	    memset (image->data + old_size, 0, new_size - old_size);
1345 	}
1346     }
1347   if (!image->data)
1348     fprintf (stderr, "%s: can't allocate image buffer (%dx%d)\n",
1349 	     prog_name, image->width, image->height);
1350   return image->data;
1351 }
1352 
1353 static SANE_Status
scan_it(FILE *ofp, void* pw)1354 scan_it (FILE *ofp, void* pw)
1355 {
1356   int i, len, first_frame = 1, offset = 0, must_buffer = 0;
1357   uint64_t hundred_percent = 0;
1358   SANE_Byte min = 0xff, max = 0;
1359   SANE_Parameters parm;
1360   SANE_Status status;
1361   Image image = { 0, 0, 0, 0, 0, 0 };
1362   static const char *format_name[] = {
1363     "gray", "RGB", "red", "green", "blue"
1364   };
1365   uint64_t total_bytes = 0, expected_bytes;
1366   SANE_Int hang_over = -1;
1367 #ifdef HAVE_LIBPNG
1368   int pngrow = 0;
1369   png_bytep pngbuf = NULL;
1370   png_structp png_ptr;
1371   png_infop info_ptr;
1372 #endif
1373 #ifdef HAVE_LIBJPEG
1374   int jpegrow = 0;
1375   JSAMPLE *jpegbuf = NULL;
1376   struct jpeg_compress_struct cinfo;
1377   struct jpeg_error_mgr jerr;
1378 #endif
1379 
1380   (void)pw;
1381 
1382   do
1383     {
1384       if (!first_frame)
1385 	{
1386 #ifdef SANE_STATUS_WARMING_UP
1387           do
1388 	    {
1389 	      status = sane_start (device);
1390 	    }
1391 	  while(status == SANE_STATUS_WARMING_UP);
1392 #else
1393 	  status = sane_start (device);
1394 #endif
1395 	  if (status != SANE_STATUS_GOOD)
1396 	    {
1397 	      fprintf (stderr, "%s: sane_start: %s\n",
1398 		       prog_name, sane_strstatus (status));
1399 	      goto cleanup;
1400 	    }
1401 	}
1402 
1403       status = sane_get_parameters (device, &parm);
1404       if (status != SANE_STATUS_GOOD)
1405 	{
1406 	  fprintf (stderr, "%s: sane_get_parameters: %s\n",
1407 		   prog_name, sane_strstatus (status));
1408 	  goto cleanup;
1409 	}
1410 
1411       if (verbose)
1412 	{
1413 	  if (first_frame)
1414 	    {
1415 	      if (parm.lines >= 0)
1416 		fprintf (stderr, "%s: scanning image of size %dx%d pixels at "
1417 			 "%d bits/pixel\n",
1418 			 prog_name, parm.pixels_per_line, parm.lines,
1419 			 parm.depth * (SANE_FRAME_RGB == parm.format ? 3 : 1));
1420 	      else
1421 		fprintf (stderr, "%s: scanning image %d pixels wide and "
1422 			 "variable height at %d bits/pixel\n",
1423 			 prog_name, parm.pixels_per_line,
1424 			 parm.depth * (SANE_FRAME_RGB == parm.format ? 3 : 1));
1425 	    }
1426 
1427 	  fprintf (stderr, "%s: acquiring %s frame\n", prog_name,
1428 	   parm.format <= SANE_FRAME_BLUE ? format_name[parm.format]:"Unknown");
1429 	}
1430 
1431       if (first_frame)
1432 	{
1433           image.num_channels = 1;
1434 	  switch (parm.format)
1435 	    {
1436 	    case SANE_FRAME_RED:
1437 	    case SANE_FRAME_GREEN:
1438 	    case SANE_FRAME_BLUE:
1439 	      assert (parm.depth == 8);
1440 	      must_buffer = 1;
1441 	      offset = parm.format - SANE_FRAME_RED;
1442 	      image.num_channels = 3;
1443 	      break;
1444 
1445 	    case SANE_FRAME_RGB:
1446 	      assert ((parm.depth == 8) || (parm.depth == 16));
1447 	    case SANE_FRAME_GRAY:
1448 	      assert ((parm.depth == 1) || (parm.depth == 8)
1449 		      || (parm.depth == 16));
1450 	      if (parm.lines < 0)
1451 		{
1452 		  must_buffer = 1;
1453 		  offset = 0;
1454 		}
1455 	      else
1456 		  switch(output_format)
1457 		  {
1458 		  case OUTPUT_TIFF:
1459 		    sanei_write_tiff_header (parm.format,
1460 					     parm.pixels_per_line, parm.lines,
1461 					     parm.depth, resolution_value,
1462 					     icc_profile, ofp);
1463 		    break;
1464 		  case OUTPUT_PNM:
1465 		    write_pnm_header (parm.format, parm.pixels_per_line,
1466 				      parm.lines, parm.depth, ofp);
1467 		    break;
1468 #ifdef HAVE_LIBPNG
1469 		  case OUTPUT_PNG:
1470 		    write_png_header (parm.format, parm.pixels_per_line,
1471 				      parm.lines, parm.depth, resolution_value,
1472 				      icc_profile, ofp, &png_ptr, &info_ptr);
1473 		    break;
1474 #endif
1475 #ifdef HAVE_LIBJPEG
1476 		  case OUTPUT_PDF:
1477 		    sane_pdf_start_page ( pw, parm.pixels_per_line, parm.lines,
1478 		               resolution_value, SANE_PDF_IMAGE_COLOR,
1479 		               SANE_PDF_ROTATE_OFF);
1480 		    write_jpeg_header (parm.format, parm.pixels_per_line,
1481 				       parm.lines, resolution_value,
1482 				       ofp, &cinfo, &jerr);
1483 		    break;
1484 		  case OUTPUT_JPEG:
1485 		    write_jpeg_header (parm.format, parm.pixels_per_line,
1486 				       parm.lines, resolution_value,
1487 				       ofp, &cinfo, &jerr);
1488 		    break;
1489 #endif
1490 		  }
1491 	      break;
1492 
1493             default:
1494 	      break;
1495 	    }
1496 #ifdef HAVE_LIBPNG
1497 	  if(output_format == OUTPUT_PNG)
1498 	    pngbuf = malloc(parm.bytes_per_line);
1499 #endif
1500 #ifdef HAVE_LIBJPEG
1501 	  if(output_format == OUTPUT_JPEG || output_format == OUTPUT_PDF)
1502 	    jpegbuf = malloc(parm.bytes_per_line);
1503 #endif
1504 
1505 	  if (must_buffer)
1506 	    {
1507 	      /* We're either scanning a multi-frame image or the
1508 		 scanner doesn't know what the eventual image height
1509 		 will be (common for hand-held scanners).  In either
1510 		 case, we need to buffer all data before we can write
1511 		 the image.  */
1512 	      image.width = parm.bytes_per_line;
1513 
1514 	      if (parm.lines >= 0)
1515 		/* See advance(); we allocate one extra line so we
1516 		   don't end up realloc'ing in when the image has been
1517 		   filled in.  */
1518 		image.height = parm.lines - STRIP_HEIGHT + 1;
1519 	      else
1520 		image.height = 0;
1521 
1522 	      image.x = image.width - 1;
1523 	      image.y = -1;
1524 	      if (!advance (&image))
1525 		{
1526 		  status = SANE_STATUS_NO_MEM;
1527 		  goto cleanup;
1528 		}
1529 	    }
1530 	}
1531       else
1532 	{
1533 	  assert (parm.format >= SANE_FRAME_RED
1534 		  && parm.format <= SANE_FRAME_BLUE);
1535 	  offset = parm.format - SANE_FRAME_RED;
1536 	  image.x = image.y = 0;
1537 	}
1538       hundred_percent = ((uint64_t)parm.bytes_per_line) * parm.lines
1539 	* ((parm.format == SANE_FRAME_RGB || parm.format == SANE_FRAME_GRAY) ? 1:3);
1540 
1541       while (1)
1542 	{
1543 	  double progr;
1544 	  status = sane_read (device, buffer, buffer_size, &len);
1545 	  total_bytes += (SANE_Word) len;
1546           progr = ((total_bytes * 100.) / (double) hundred_percent);
1547           if (progr > 100.)
1548 	    progr = 100.;
1549           if (progress)
1550             {
1551               if (parm.lines >= 0)
1552                 fprintf(stderr, "Progress: %3.1f%%\r", progr);
1553               else
1554                 fprintf(stderr, "Progress: (unknown)\r");
1555             }
1556 
1557 	  if (status != SANE_STATUS_GOOD)
1558 	    {
1559 	      if (verbose && parm.depth == 8)
1560 		fprintf (stderr, "%s: min/max graylevel value = %d/%d\n",
1561 			 prog_name, min, max);
1562 	      if (status != SANE_STATUS_EOF)
1563 		{
1564 		  fprintf (stderr, "%s: sane_read: %s\n",
1565 			   prog_name, sane_strstatus (status));
1566 		  return status;
1567 		}
1568 	      break;
1569 	    }
1570 
1571 	  if (must_buffer)
1572 	    {
1573 	      switch (parm.format)
1574 		{
1575 		case SANE_FRAME_RED:
1576 		case SANE_FRAME_GREEN:
1577 		case SANE_FRAME_BLUE:
1578 		  image.num_channels = 3;
1579 		  for (i = 0; i < len; ++i)
1580 		    {
1581 		      image.data[offset + 3 * i] = buffer[i];
1582 		      if (!advance (&image))
1583 			{
1584 			  status = SANE_STATUS_NO_MEM;
1585 			  goto cleanup;
1586 			}
1587 		    }
1588 		  offset += 3 * len;
1589 		  break;
1590 
1591 		case SANE_FRAME_RGB:
1592 		  image.num_channels = 1;
1593 		  for (i = 0; i < len; ++i)
1594 		    {
1595 		      image.data[offset + i] = buffer[i];
1596 		      if (!advance (&image))
1597 			  {
1598 			    status = SANE_STATUS_NO_MEM;
1599 			    goto cleanup;
1600 			  }
1601 		    }
1602 		  offset += len;
1603 		  break;
1604 
1605 		case SANE_FRAME_GRAY:
1606 		  image.num_channels = 1;
1607 		  for (i = 0; i < len; ++i)
1608 		    {
1609 		      image.data[offset + i] = buffer[i];
1610 		      if (!advance (&image))
1611 			  {
1612 			    status = SANE_STATUS_NO_MEM;
1613 			    goto cleanup;
1614 			  }
1615 		    }
1616 		  offset += len;
1617 		  break;
1618 
1619                 default:
1620 		  break;
1621 		}
1622 	    }
1623 	  else			/* ! must_buffer */
1624 	    {
1625 #ifdef HAVE_LIBPNG
1626 	      if (output_format == OUTPUT_PNG)
1627 	        {
1628 		  int i = 0;
1629 		  int left = len;
1630 		  while(pngrow + left >= parm.bytes_per_line)
1631 		    {
1632 		      memcpy(pngbuf + pngrow, buffer + i, parm.bytes_per_line - pngrow);
1633 		      if(parm.depth == 1)
1634 			{
1635 			  int j;
1636 			  for(j = 0; j < parm.bytes_per_line; j++)
1637 			    pngbuf[j] = ~pngbuf[j];
1638 			}
1639 #ifndef WORDS_BIGENDIAN
1640                       /* SANE is endian-native, PNG is big-endian, */
1641                       /* see: https://www.w3.org/TR/2003/REC-PNG-20031110/#7Integers-and-byte-order */
1642                       if (parm.depth == 16)
1643                         {
1644                           int j;
1645                           for (j = 0; j < parm.bytes_per_line; j += 2)
1646                             {
1647                               SANE_Byte LSB;
1648                               LSB = pngbuf[j];
1649                               pngbuf[j] = pngbuf[j + 1];
1650                               pngbuf[j + 1] = LSB;
1651                             }
1652                         }
1653 #endif
1654 		      png_write_row(png_ptr, pngbuf);
1655 		      i += parm.bytes_per_line - pngrow;
1656 		      left -= parm.bytes_per_line - pngrow;
1657 		      pngrow = 0;
1658 		    }
1659 		  memcpy(pngbuf + pngrow, buffer + i, left);
1660 		  pngrow += left;
1661 		}
1662 	      else
1663 #endif
1664 #ifdef HAVE_LIBJPEG
1665 	      if (output_format == OUTPUT_JPEG || output_format == OUTPUT_PDF)
1666 	        {
1667 		  int i = 0;
1668 		  int left = len;
1669 		  while(jpegrow + left >= parm.bytes_per_line)
1670 		    {
1671 		      memcpy(jpegbuf + jpegrow, buffer + i, parm.bytes_per_line - jpegrow);
1672 		      if(parm.depth == 1)
1673 			{
1674 			  int col1, col8;
1675 			  JSAMPLE *buf8 = malloc(parm.bytes_per_line * 8);
1676 			  for(col1 = 0; col1 < parm.bytes_per_line; col1++)
1677 			    for(col8 = 0; col8 < 8; col8++)
1678 			      buf8[col1 * 8 + col8] = jpegbuf[col1] & (1 << (8 - col8 - 1)) ? 0 : 0xff;
1679 		          jpeg_write_scanlines(&cinfo, &buf8, 1);
1680 			  free(buf8);
1681 			} else {
1682 		          jpeg_write_scanlines(&cinfo, &jpegbuf, 1);
1683 			}
1684 		      i += parm.bytes_per_line - jpegrow;
1685 		      left -= parm.bytes_per_line - jpegrow;
1686 		      jpegrow = 0;
1687 		    }
1688 		  memcpy(jpegbuf + jpegrow, buffer + i, left);
1689 		  jpegrow += left;
1690 		}
1691 	      else
1692 #endif
1693 	      if ((output_format == OUTPUT_TIFF) || (parm.depth != 16))
1694 		fwrite (buffer, 1, len, ofp);
1695 	      else
1696 		{
1697 #if !defined(WORDS_BIGENDIAN)
1698 		  int i, start = 0;
1699 
1700 		  /* check if we have saved one byte from the last sane_read */
1701 		  if (hang_over > -1)
1702 		    {
1703 		      if (len > 0)
1704 			{
1705 			  fwrite (buffer, 1, 1, ofp);
1706 			  buffer[0] = (SANE_Byte) hang_over;
1707 			  hang_over = -1;
1708 			  start = 1;
1709 			}
1710 		    }
1711 		  /* now do the byte-swapping */
1712 		  for (i = start; i < (len - 1); i += 2)
1713 		    {
1714 		      unsigned char LSB;
1715 		      LSB = buffer[i];
1716 		      buffer[i] = buffer[i + 1];
1717 		      buffer[i + 1] = LSB;
1718 		    }
1719 		  /* check if we have an odd number of bytes */
1720 		  if (((len - start) % 2) != 0)
1721 		    {
1722 		      hang_over = buffer[len - 1];
1723 		      len--;
1724 		    }
1725 #endif
1726 		  fwrite (buffer, 1, len, ofp);
1727 		}
1728 	    }
1729 
1730 	  if (verbose && parm.depth == 8)
1731 	    {
1732 	      for (i = 0; i < len; ++i)
1733 		if (buffer[i] >= max)
1734 		  max = buffer[i];
1735 		else if (buffer[i] < min)
1736 		  min = buffer[i];
1737 	    }
1738 	}
1739       first_frame = 0;
1740     }
1741   while (!parm.last_frame);
1742 
1743   if (must_buffer)
1744     {
1745       image.height = image.y;
1746 
1747       switch(output_format) {
1748       case OUTPUT_TIFF:
1749 	sanei_write_tiff_header (parm.format, parm.pixels_per_line,
1750 				 image.height, parm.depth, resolution_value,
1751 				 icc_profile, ofp);
1752       break;
1753       case OUTPUT_PNM:
1754 	write_pnm_header (parm.format, parm.pixels_per_line,
1755                           image.height, parm.depth, ofp);
1756       break;
1757 #ifdef HAVE_LIBPNG
1758       case OUTPUT_PNG:
1759 	write_png_header (parm.format, parm.pixels_per_line,
1760 			  image.height, parm.depth, resolution_value,
1761 			  icc_profile, ofp, &png_ptr, &info_ptr);
1762       break;
1763 #endif
1764 #ifdef HAVE_LIBJPEG
1765       case OUTPUT_PDF:
1766 	sane_pdf_start_page ( pw, parm.pixels_per_line, parm.lines,
1767 	           resolution_value, SANE_PDF_IMAGE_COLOR,
1768 	           SANE_PDF_ROTATE_OFF);
1769 	write_jpeg_header (parm.format, parm.pixels_per_line,
1770 			   parm.lines, resolution_value,
1771 			   ofp, &cinfo, &jerr);
1772       break;
1773       case OUTPUT_JPEG:
1774 	write_jpeg_header (parm.format, parm.pixels_per_line,
1775 			   parm.lines, resolution_value,
1776 			   ofp, &cinfo, &jerr);
1777       break;
1778 #endif
1779       }
1780 
1781 #if !defined(WORDS_BIGENDIAN)
1782       /* multibyte pnm file may need byte swap to LE */
1783       /* FIXME: other bit depths? */
1784       if (output_format != OUTPUT_TIFF && parm.depth == 16)
1785 	{
1786 	  int i;
1787 	  for (i = 0; i < image.height * image.width; i += 2)
1788 	    {
1789 	      unsigned char LSB;
1790 	      LSB = image.data[i];
1791 	      image.data[i] = image.data[i + 1];
1792 	      image.data[i + 1] = LSB;
1793 	    }
1794 	}
1795 #endif
1796 
1797 	fwrite (image.data, 1, image.height * image.width * image.num_channels, ofp);
1798     }
1799 #ifdef HAVE_LIBPNG
1800     if(output_format == OUTPUT_PNG)
1801 	png_write_end(png_ptr, info_ptr);
1802 #endif
1803 #ifdef HAVE_LIBJPEG
1804     if(output_format == OUTPUT_JPEG || output_format == OUTPUT_PDF)
1805 	jpeg_finish_compress(&cinfo);
1806 #endif
1807 
1808   /* flush the output buffer */
1809   fflush( ofp );
1810 
1811 cleanup:
1812 #ifdef HAVE_LIBPNG
1813   if(output_format == OUTPUT_PNG) {
1814     png_destroy_write_struct(&png_ptr, &info_ptr);
1815     free(pngbuf);
1816   }
1817 #endif
1818 #ifdef HAVE_LIBJPEG
1819   if(output_format == OUTPUT_JPEG || output_format == OUTPUT_PDF) {
1820     jpeg_destroy_compress(&cinfo);
1821     free(jpegbuf);
1822   }
1823 #endif
1824   if (image.data)
1825     free (image.data);
1826 
1827 
1828   expected_bytes = ((uint64_t)parm.bytes_per_line) * parm.lines *
1829     ((parm.format == SANE_FRAME_RGB
1830       || parm.format == SANE_FRAME_GRAY) ? 1 : 3);
1831   if (parm.lines < 0)
1832     expected_bytes = 0;
1833   if (total_bytes > expected_bytes && expected_bytes != 0)
1834     {
1835       fprintf (stderr,
1836 	       "%s: WARNING: read more data than announced by backend "
1837                "(%" PRIu64 "/%" PRIu64 ")\n", prog_name, total_bytes, expected_bytes);
1838     }
1839   else if (verbose)
1840     fprintf (stderr, "%s: read %" PRIu64 " bytes in total\n", prog_name, total_bytes);
1841 
1842   return status;
1843 }
1844 
1845 #define clean_buffer(buf,size)	memset ((buf), 0x23, size)
1846 
1847 static void
pass_fail(int max, int len, SANE_Byte * buffer, SANE_Status status)1848 pass_fail (int max, int len, SANE_Byte * buffer, SANE_Status status)
1849 {
1850   if (status != SANE_STATUS_GOOD)
1851     fprintf (stderr, "FAIL Error: %s\n", sane_strstatus (status));
1852   else if (buffer[len] != 0x23)
1853     {
1854       while (len <= max && buffer[len] != 0x23)
1855 	++len;
1856       fprintf (stderr, "FAIL Cheat: %d bytes\n", len);
1857     }
1858   else if (len > max)
1859     fprintf (stderr, "FAIL Overflow: %d bytes\n", len);
1860   else if (len == 0)
1861     fprintf (stderr, "FAIL No data\n");
1862   else
1863     fprintf (stderr, "PASS\n");
1864 }
1865 
1866 static SANE_Status
test_it(void)1867 test_it (void)
1868 {
1869   int i, len;
1870   SANE_Parameters parm;
1871   SANE_Status status;
1872   Image image = { 0, 0, 0, 0, 0, 0 };
1873   static const char *format_name[] =
1874     { "gray", "RGB", "red", "green", "blue" };
1875 
1876 #ifdef SANE_STATUS_WARMING_UP
1877   do
1878     {
1879       status = sane_start (device);
1880     }
1881   while(status == SANE_STATUS_WARMING_UP);
1882 #else
1883   status = sane_start (device);
1884 #endif
1885 
1886   if (status != SANE_STATUS_GOOD)
1887     {
1888       fprintf (stderr, "%s: sane_start: %s\n",
1889 	       prog_name, sane_strstatus (status));
1890       goto cleanup;
1891     }
1892 
1893   status = sane_get_parameters (device, &parm);
1894   if (status != SANE_STATUS_GOOD)
1895     {
1896       fprintf (stderr, "%s: sane_get_parameters: %s\n",
1897 	       prog_name, sane_strstatus (status));
1898       goto cleanup;
1899     }
1900 
1901   if (parm.lines >= 0)
1902     fprintf (stderr, "%s: scanning image of size %dx%d pixels at "
1903 	     "%d bits/pixel\n", prog_name, parm.pixels_per_line, parm.lines,
1904 	     parm.depth * (SANE_FRAME_RGB == parm.format ? 3 : 1));
1905   else
1906     fprintf (stderr, "%s: scanning image %d pixels wide and "
1907 	     "variable height at %d bits/pixel\n",
1908 	     prog_name, parm.pixels_per_line,
1909 	     parm.depth * (SANE_FRAME_RGB == parm.format ? 3 : 1));
1910   fprintf (stderr, "%s: acquiring %s frame, %d bits/sample\n", prog_name,
1911 	   parm.format <= SANE_FRAME_BLUE ? format_name[parm.format]:"Unknown",
1912            parm.depth);
1913 
1914   image.data = malloc (parm.bytes_per_line * 2);
1915 
1916   clean_buffer (image.data, parm.bytes_per_line * 2);
1917   fprintf (stderr, "%s: reading one scanline, %d bytes...\t", prog_name,
1918 	   parm.bytes_per_line);
1919   status = sane_read (device, image.data, parm.bytes_per_line, &len);
1920   pass_fail (parm.bytes_per_line, len, image.data, status);
1921   if (status != SANE_STATUS_GOOD)
1922     goto cleanup;
1923 
1924   clean_buffer (image.data, parm.bytes_per_line * 2);
1925   fprintf (stderr, "%s: reading one byte...\t\t", prog_name);
1926   status = sane_read (device, image.data, 1, &len);
1927   pass_fail (1, len, image.data, status);
1928   if (status != SANE_STATUS_GOOD)
1929     goto cleanup;
1930 
1931   for (i = 2; i < parm.bytes_per_line * 2; i *= 2)
1932     {
1933       clean_buffer (image.data, parm.bytes_per_line * 2);
1934       fprintf (stderr, "%s: stepped read, %d bytes... \t", prog_name, i);
1935       status = sane_read (device, image.data, i, &len);
1936       pass_fail (i, len, image.data, status);
1937       if (status != SANE_STATUS_GOOD)
1938 	goto cleanup;
1939     }
1940 
1941   for (i /= 2; i > 2; i /= 2)
1942     {
1943       clean_buffer (image.data, parm.bytes_per_line * 2);
1944       fprintf (stderr, "%s: stepped read, %d bytes... \t", prog_name, i - 1);
1945       status = sane_read (device, image.data, i - 1, &len);
1946       pass_fail (i - 1, len, image.data, status);
1947       if (status != SANE_STATUS_GOOD)
1948 	goto cleanup;
1949     }
1950 
1951 cleanup:
1952   sane_cancel (device);
1953   if (image.data)
1954     free (image.data);
1955   return status;
1956 }
1957 
1958 
1959 static int
get_resolution(void)1960 get_resolution (void)
1961 {
1962   const SANE_Option_Descriptor *resopt;
1963   int resol = 0;
1964   void *val;
1965 
1966   if (resolution_optind < 0)
1967     return 0;
1968   resopt = sane_get_option_descriptor (device, resolution_optind);
1969   if (!resopt)
1970     return 0;
1971 
1972   val = alloca (resopt->size);
1973   if (!val)
1974     return 0;
1975 
1976   sane_control_option (device, resolution_optind, SANE_ACTION_GET_VALUE, val,
1977 		       0);
1978   if (resopt->type == SANE_TYPE_INT)
1979     resol = *(SANE_Int *) val;
1980   else
1981     resol = (int) (SANE_UNFIX (*(SANE_Fixed *) val) + 0.5);
1982 
1983   return resol;
1984 }
1985 
1986 static void
scanimage_exit(int status)1987 scanimage_exit (int status)
1988 {
1989   if (device)
1990     {
1991       if (verbose > 1)
1992 	fprintf (stderr, "Closing device\n");
1993       sane_close (device);
1994     }
1995   if (verbose > 1)
1996     fprintf (stderr, "Calling sane_exit\n");
1997   sane_exit ();
1998 
1999   if (all_options)
2000     free (all_options);
2001   if (option_number)
2002     free (option_number);
2003   if (verbose > 1)
2004     fprintf (stderr, "scanimage: finished\n");
2005   exit (status);
2006 }
2007 
2008 /** @brief print device options to stdout
2009  *
2010  * @param device struct of the opened device to describe
2011  * @param num_dev_options number of device options
2012  * @param ro SANE_TRUE to print read-only options
2013  */
print_options(SANE_Device * device, SANE_Int num_dev_options, SANE_Bool ro)2014 static void print_options(SANE_Device * device, SANE_Int num_dev_options, SANE_Bool ro)
2015 {
2016   int i, j;
2017   const SANE_Option_Descriptor *opt;
2018 
2019   for (i = 1; i < num_dev_options; ++i)
2020     {
2021       opt = 0;
2022 
2023       /* scan area uses modified option struct */
2024       for (j = 0; j < 4; ++j)
2025 	if (i == window[j])
2026 	  opt = window_option + j;
2027 
2028       if (!opt)
2029 	opt = sane_get_option_descriptor (device, i);
2030 
2031       /* Some options from rogue backends are empty. */
2032       if (opt->name == NULL)
2033         continue;
2034 
2035       if (ro || SANE_OPTION_IS_SETTABLE (opt->cap)
2036 	  || opt->type == SANE_TYPE_GROUP)
2037 	print_option (device, i, opt);
2038     }
2039   if (num_dev_options)
2040     fputc ('\n', stdout);
2041 }
2042 
guess_output_format(const char* output_file)2043 static int guess_output_format(const char* output_file)
2044 {
2045   if (output_file == NULL)
2046     {
2047       fprintf(stderr, "Output format is not set, using pnm as a default.\n");
2048       return OUTPUT_PNM;
2049     }
2050 
2051   // if the user passes us a path with a known extension then he won't be surprised if we figure
2052   // out correct --format option. No warning is necessary in that case.
2053   const char* extension = strrchr(output_file, '.');
2054   if (extension != NULL)
2055     {
2056       struct {
2057         const char* extension;
2058         int output_format;
2059       } formats[] = {
2060         { ".pnm", OUTPUT_PNM },
2061         { ".png", OUTPUT_PNG },
2062         { ".jpg", OUTPUT_JPEG },
2063         { ".jpeg", OUTPUT_JPEG },
2064         { ".tiff", OUTPUT_TIFF },
2065         { ".tif", OUTPUT_TIFF },
2066         { ".pdf", OUTPUT_PDF }
2067       };
2068       for (unsigned i = 0; i < sizeof(formats) / sizeof(formats[0]); ++i)
2069         {
2070           if (strcmp(extension, formats[i].extension) == 0)
2071             return formats[i].output_format;
2072         }
2073     }
2074 
2075   // it would be very confusing if user makes a typo in the filename and the output format changes.
2076   // This is most likely not what the user wanted.
2077   fprintf(stderr, "Could not guess output format from the given path and no --format given.\n");
2078   exit(1);
2079 }
2080 
2081 int
main(int argc, char **argv)2082 main (int argc, char **argv)
2083 {
2084   int ch, i, index, all_options_len;
2085   const SANE_Device **device_list;
2086   SANE_Int num_dev_options = 0;
2087   const char *devname = 0;
2088   const char *defdevname = 0;
2089   const char *format = 0;
2090   char readbuf[2];
2091   char *readbuf2;
2092   int batch = 0;
2093   int batch_print = 0;
2094   int batch_prompt = 0;
2095   int batch_count = BATCH_COUNT_UNLIMITED;
2096   int batch_start_at = 1;
2097   int batch_increment = 1;
2098   SANE_Status status;
2099   char *full_optstring;
2100   SANE_Int version_code;
2101   void *pw = NULL;
2102   FILE *ofp = NULL;
2103 
2104   buffer_size = (32 * 1024);	/* default size */
2105 
2106   prog_name = strrchr (argv[0], '/');
2107   if (prog_name)
2108     ++prog_name;
2109   else
2110     prog_name = argv[0];
2111 
2112   defdevname = getenv ("SANE_DEFAULT_DEVICE");
2113 
2114   sane_init (&version_code, auth_callback);
2115 
2116   /* make a first pass through the options with error printing and argument
2117      permutation disabled: */
2118   opterr = 0;
2119   while ((ch = getopt_long (argc, argv, "-" BASE_OPTSTRING, basic_options,
2120 			    &index)) != EOF)
2121     {
2122       switch (ch)
2123 	{
2124 	case ':':
2125 	case '?':
2126 	  break;		/* may be an option that we'll parse later on */
2127 	case 'd':
2128 	  devname = optarg;
2129 	  break;
2130 	case 'b':
2131 	  /* This may have already been set by the batch-count flag */
2132 	  batch = 1;
2133 	  format = optarg;
2134 	  break;
2135 	case 'h':
2136 	  help = 1;
2137 	  break;
2138 	case 'i':		/* icc profile */
2139 	  icc_profile = optarg;
2140 	  break;
2141 	case 'v':
2142 	  ++verbose;
2143 	  break;
2144 	case 'p':
2145           progress = 1;
2146 	  break;
2147         case 'o':
2148           output_file = optarg;
2149           break;
2150 	case 'B':
2151           if (optarg)
2152 	    buffer_size = 1024 * atoi(optarg);
2153           else
2154 	    buffer_size = (1024 * 1024);
2155 	  break;
2156 	case 'T':
2157 	  test = 1;
2158 	  break;
2159 	case 'A':
2160 	  all = 1;
2161 	  break;
2162 	case 'n':
2163 	  dont_scan = 1;
2164 	  break;
2165 	case OPTION_BATCH_PRINT:
2166 	  batch_print = 1;
2167 	  break;
2168 	case OPTION_BATCH_PROMPT:
2169 	  batch_prompt = 1;
2170 	  break;
2171 	case OPTION_BATCH_INCREMENT:
2172 	  batch_increment = atoi (optarg);
2173 	  break;
2174 	case OPTION_BATCH_START_AT:
2175 	  batch_start_at = atoi (optarg);
2176 	  break;
2177 	case OPTION_BATCH_DOUBLE:
2178 	  batch_increment = 2;
2179 	  break;
2180 	case OPTION_BATCH_COUNT:
2181 	  batch_count = atoi (optarg);
2182 	  batch = 1;
2183 	  break;
2184 	case OPTION_FORMAT:
2185 	  if (strcmp (optarg, "tiff") == 0)
2186 	    output_format = OUTPUT_TIFF;
2187 	  else if (strcmp (optarg, "png") == 0)
2188 	    {
2189 #ifdef HAVE_LIBPNG
2190 	      output_format = OUTPUT_PNG;
2191 #else
2192 	      fprintf(stderr, "PNG support not compiled in\n");
2193 	      exit(1);
2194 #endif
2195 	    }
2196 	  else if (strcmp (optarg, "jpeg") == 0)
2197 	    {
2198 #ifdef HAVE_LIBJPEG
2199 	      output_format = OUTPUT_JPEG;
2200 #else
2201 	      fprintf(stderr, "JPEG support not compiled in\n");
2202 	      exit(1);
2203 #endif
2204 	    }
2205 	  else if (strcmp (optarg, "pdf") == 0)
2206 	    {
2207 #ifdef HAVE_LIBJPEG
2208 	      output_format = OUTPUT_PDF;
2209 #else
2210 	      fprintf(stderr, "PDF support not compiled in\n");
2211 	      exit(1);
2212 #endif
2213 	    }
2214           else if (strcmp (optarg, "pnm") == 0)
2215             {
2216               output_format = OUTPUT_PNM;
2217             }
2218           else
2219             {
2220               fprintf(stderr, "Unknown output image format '%s'.\n", optarg);
2221               fprintf(stderr, "Supported formats: pnm, tiff");
2222 #ifdef HAVE_LIBPNG
2223               fprintf(stderr, ", png");
2224 #endif
2225 #ifdef HAVE_LIBJPEG
2226               fprintf(stderr, ", jpeg");
2227 #endif
2228               fprintf(stderr, ".\n");
2229               exit(1);
2230             }
2231 	  break;
2232 	case OPTION_MD5:
2233 	  accept_only_md5_auth = 1;
2234 	  break;
2235 	case 'L':
2236 	case 'f':
2237 	  {
2238 	    int i = 0;
2239 
2240 	    status = sane_get_devices (&device_list, SANE_FALSE);
2241 	    if (status != SANE_STATUS_GOOD)
2242 	      {
2243 		fprintf (stderr, "%s: sane_get_devices() failed: %s\n",
2244 			 prog_name, sane_strstatus (status));
2245 		scanimage_exit (1);
2246 	      }
2247 
2248 	    if (ch == 'L')
2249 	      {
2250 		for (i = 0; device_list[i]; ++i)
2251 		  {
2252 		    printf ("device `%s' is a %s %s %s\n",
2253 			    device_list[i]->name, device_list[i]->vendor,
2254 			    device_list[i]->model, device_list[i]->type);
2255 		  }
2256 	      }
2257 	    else
2258 	      {
2259 		int i = 0, int_arg = 0;
2260 		const char *percent, *start;
2261 		const char *text_arg = 0;
2262 		char ftype;
2263 
2264 		for (i = 0; device_list[i]; ++i)
2265 		  {
2266 		    start = optarg;
2267 		    while (*start && (percent = strchr (start, '%')))
2268 		      {
2269 			int start_len = percent - start;
2270 			percent++;
2271 			if (*percent)
2272 			  {
2273 			    switch (*percent)
2274 			      {
2275 			      case 'd':
2276 				text_arg = device_list[i]->name;
2277 				ftype = 's';
2278 				break;
2279 			      case 'v':
2280 				text_arg = device_list[i]->vendor;
2281 				ftype = 's';
2282 				break;
2283 			      case 'm':
2284 				text_arg = device_list[i]->model;
2285 				ftype = 's';
2286 				break;
2287 			      case 't':
2288 				text_arg = device_list[i]->type;
2289 				ftype = 's';
2290 				break;
2291 			      case 'i':
2292 				int_arg = i;
2293 				ftype = 'i';
2294 				break;
2295 			      case 'n':
2296 				text_arg = "\n";
2297 				ftype = 's';
2298 				break;
2299 			      case '%':
2300 				text_arg = "%";
2301 				ftype = 's';
2302 				break;
2303 			      default:
2304 				fprintf (stderr,
2305 					 "%s: unknown format specifier %%%c\n",
2306 					 prog_name, *percent);
2307                                 text_arg = "%";
2308 				ftype = 's';
2309 			      }
2310 			    printf ("%.*s", start_len, start);
2311 			    switch (ftype)
2312 			      {
2313 			      case 's':
2314 				printf ("%s", text_arg);
2315 				break;
2316 			      case 'i':
2317 				printf ("%i", int_arg);
2318 				break;
2319 			      }
2320 			    start = percent + 1;
2321 			  }
2322 			else
2323 			  {
2324 			    /* last char of the string is a '%', ignore it */
2325 			    start++;
2326 			    break;
2327 			  }
2328 		      }
2329 		    if (*start)
2330 		      printf ("%s", start);
2331 		  }
2332 	      }
2333 	    if (i == 0 && ch != 'f')
2334 	      printf ("\nNo scanners were identified. If you were expecting "
2335                 "something different,\ncheck that the scanner is plugged "
2336 		"in, turned on and detected by the\nsane-find-scanner tool "
2337 		"(if appropriate). Please read the documentation\nwhich came "
2338 		"with this software (README, FAQ, manpages).\n");
2339 
2340 	    if (defdevname)
2341 	      printf ("default device is `%s'\n", defdevname);
2342 	    scanimage_exit (0);
2343 	    break;
2344 	  }
2345 	case 'V':
2346 	  printf ("scanimage (%s) %s; backend version %d.%d.%d\n", PACKAGE,
2347 		  VERSION, SANE_VERSION_MAJOR (version_code),
2348 		  SANE_VERSION_MINOR (version_code),
2349 		  SANE_VERSION_BUILD (version_code));
2350 	  scanimage_exit (0);
2351 	  break;
2352 	default:
2353 	  break;		/* ignore device specific options for now */
2354 	}
2355     }
2356 
2357   if (help)
2358     {
2359       printf ("Usage: %s [OPTION]...\n\
2360 \n\
2361 Start image acquisition on a scanner device and write image data to\n\
2362 standard output.\n\
2363 \n\
2364 Parameters are separated by a blank from single-character options (e.g.\n\
2365 -d epson) and by a \"=\" from multi-character options (e.g. --device-name=epson).\n\
2366 -d, --device-name=DEVICE   use a given scanner device (e.g. hp:/dev/scanner)\n\
2367     --format=pnm|tiff|png|jpeg|pdf  file format of output file\n\
2368 -i, --icc-profile=PROFILE  include this ICC profile into TIFF file\n", prog_name);
2369       printf ("\
2370 -L, --list-devices         show available scanner devices\n\
2371 -f, --formatted-device-list=FORMAT similar to -L, but the FORMAT of the output\n\
2372                            can be specified: %%d (device name), %%v (vendor),\n\
2373                            %%m (model), %%t (type), %%i (index number), and\n\
2374                            %%n (newline)\n\
2375 -b, --batch[=FORMAT]       working in batch mode, FORMAT is `out%%d.pnm' `out%%d.tif'\n\
2376                            `out%%d.png' or `out%%d.jpg' by default depending on --format\n\
2377                            This option is incompatible with --output-file.");
2378       printf ("\
2379     --batch-start=#        page number to start naming files with\n\
2380     --batch-count=#        how many pages to scan in batch mode\n\
2381     --batch-increment=#    increase page number in filename by #\n\
2382     --batch-double         increment page number by two, same as\n\
2383                            --batch-increment=2\n\
2384     --batch-print          print image filenames to stdout\n\
2385     --batch-prompt         ask for pressing a key before scanning a page\n");
2386       printf ("\
2387     --accept-md5-only      only accept authorization requests using md5\n\
2388 -p, --progress             print progress messages\n\
2389 -o, --output-file=PATH     save output to the given file instead of stdout.\n\
2390                            This option is incompatible with --batch.\n\
2391 -n, --dont-scan            only set options, don't actually scan\n\
2392 -T, --test                 test backend thoroughly\n\
2393 -A, --all-options          list all available backend options\n\
2394 -h, --help                 display this help message and exit\n\
2395 -v, --verbose              give even more status messages\n\
2396 -B, --buffer-size=#        change input buffer size (in kB, default 32)\n");
2397       printf ("\
2398 -V, --version              print version information\n");
2399     }
2400 
2401   if (batch && output_file != NULL)
2402     {
2403       fprintf(stderr, "--batch and --output-file can't be used together.\n");
2404       exit(1);
2405     }
2406 
2407   if (output_format == OUTPUT_UNKNOWN)
2408     output_format = guess_output_format(output_file);
2409 
2410   if (!devname)
2411     {
2412       /* If no device name was specified explicitly, we look at the
2413          environment variable SANE_DEFAULT_DEVICE.  If this variable
2414          is not set, we open the first device we find (if any): */
2415       devname = defdevname;
2416       if (!devname)
2417 	{
2418 	  status = sane_get_devices (&device_list, SANE_FALSE);
2419 	  if (status != SANE_STATUS_GOOD)
2420 	    {
2421 	      fprintf (stderr, "%s: sane_get_devices() failed: %s\n",
2422 		       prog_name, sane_strstatus (status));
2423 	      scanimage_exit (1);
2424 	    }
2425 	  if (!device_list[0])
2426 	    {
2427 	      fprintf (stderr, "%s: no SANE devices found\n", prog_name);
2428 	      scanimage_exit (1);
2429 	    }
2430 	  devname = device_list[0]->name;
2431 	}
2432     }
2433 
2434   status = sane_open (devname, &device);
2435   if (status != SANE_STATUS_GOOD)
2436     {
2437       fprintf (stderr, "%s: open of device %s failed: %s\n",
2438 	       prog_name, devname, sane_strstatus (status));
2439       if (devname[0] == '/')
2440 	fprintf (stderr, "\nYou seem to have specified a UNIX device name, "
2441 		 "or filename instead of selecting\nthe SANE scanner or "
2442 		 "image acquisition device you want to use. As an example,\n"
2443 		 "you might want \"epson:/dev/sg0\" or "
2444 		 "\"hp:/dev/usbscanner0\". If any supported\ndevices are "
2445 		 "installed in your system, you should be able to see a "
2446 		 "list with\n\"scanimage --list-devices\".\n");
2447       if (help)
2448 	device = 0;
2449       else
2450         scanimage_exit (1);
2451     }
2452 
2453   if (device)
2454     {
2455       const SANE_Option_Descriptor * desc_ptr;
2456 
2457       /* Good form to always get the descriptor once before value */
2458       desc_ptr = sane_get_option_descriptor(device, 0);
2459       if (!desc_ptr)
2460 	{
2461 	  fprintf (stderr, "%s: unable to get option count descriptor\n",
2462 		   prog_name);
2463 	  scanimage_exit (1);
2464 	}
2465 
2466       /* We got a device, find out how many options it has */
2467       status = sane_control_option (device, 0, SANE_ACTION_GET_VALUE,
2468 				    &num_dev_options, 0);
2469       if (status != SANE_STATUS_GOOD)
2470 	{
2471 	  fprintf (stderr, "%s: unable to determine option count\n",
2472 		   prog_name);
2473 	  scanimage_exit (1);
2474 	}
2475 
2476       /* malloc global option lists */
2477       all_options_len = num_dev_options + NELEMS (basic_options) + 1;
2478       all_options = malloc (all_options_len * sizeof (all_options[0]));
2479       option_number_len = num_dev_options;
2480       option_number = malloc (option_number_len * sizeof (option_number[0]));
2481       if (!all_options || !option_number)
2482 	{
2483 	  fprintf (stderr, "%s: out of memory in main()\n",
2484 		   prog_name);
2485 	  scanimage_exit (1);
2486 	}
2487 
2488       /* load global option lists */
2489       fetch_options (device);
2490 
2491       {
2492 	char *larg, *targ, *xarg, *yarg;
2493 	larg = targ = xarg = yarg = "";
2494 
2495 	/* Maybe accept t, l, x, and y options. */
2496 	if (window[0])
2497 	  xarg = "x:";
2498 
2499 	if (window[1])
2500 	  yarg = "y:";
2501 
2502 	if (window[2])
2503 	  larg = "l:";
2504 
2505 	if (window[3])
2506 	  targ = "t:";
2507 
2508 	/* Now allocate the full option list. */
2509 	full_optstring = malloc (strlen (BASE_OPTSTRING)
2510 				 + strlen (larg) + strlen (targ)
2511 				 + strlen (xarg) + strlen (yarg) + 1);
2512 
2513 	if (!full_optstring)
2514 	  {
2515 	    fprintf (stderr, "%s: out of memory\n", prog_name);
2516 	    scanimage_exit (1);
2517 	  }
2518 
2519 	strcpy (full_optstring, BASE_OPTSTRING);
2520 	strcat (full_optstring, larg);
2521 	strcat (full_optstring, targ);
2522 	strcat (full_optstring, xarg);
2523 	strcat (full_optstring, yarg);
2524       }
2525 
2526       /* re-run argument processing with backend-specific options included
2527        * this time, enable error printing and arg permutation */
2528       optind = 0;
2529       opterr = 1;
2530       while ((ch = getopt_long (argc, argv, full_optstring, all_options,
2531 				&index)) != EOF)
2532 	{
2533 	  switch (ch)
2534 	    {
2535 	    case ':':
2536 	    case '?':
2537 	      scanimage_exit (1);		/* error message is printed by getopt_long() */
2538 
2539 	    case 'd':
2540 	    case 'h':
2541 	    case 'p':
2542             case 'o':
2543 	    case 'v':
2544 	    case 'V':
2545 	    case 'T':
2546 	    case 'B':
2547 	      /* previously handled options */
2548 	      break;
2549 
2550 	    case 'x':
2551 	      window_val_user[0] = 1;
2552 	      parse_vector (&window_option[0], optarg, &window_val[0], 1);
2553 	      break;
2554 
2555 	    case 'y':
2556 	      window_val_user[1] = 1;
2557 	      parse_vector (&window_option[1], optarg, &window_val[1], 1);
2558 	      break;
2559 
2560 	    case 'l':		/* tl-x */
2561 	      process_backend_option (device, window[2], optarg);
2562 	      break;
2563 
2564 	    case 't':		/* tl-y */
2565 	      process_backend_option (device, window[3], optarg);
2566 	      break;
2567 
2568 	    case 0:
2569 	      process_backend_option (device, option_number[index], optarg);
2570 	      break;
2571 	    }
2572 	}
2573       if (optind < argc)
2574 	{
2575 	  fprintf (stderr, "%s: argument without option: `%s'; ", prog_name,
2576 		   argv[argc - 1]);
2577 	  fprintf (stderr, "try %s --help\n", prog_name);
2578 	  scanimage_exit (1);
2579 	}
2580 
2581       free (full_optstring);
2582 
2583       /* convert x/y to br_x/br_y */
2584       for (index = 0; index < 2; ++index)
2585 	if (window[index])
2586 	  {
2587             SANE_Word pos = 0;
2588 	    SANE_Word val = window_val[index];
2589 
2590 	    if (window[index + 2])
2591 	      {
2592 		sane_control_option (device, window[index + 2],
2593 				     SANE_ACTION_GET_VALUE, &pos, 0);
2594 		val += pos;
2595 	      }
2596 	    set_option (device, window[index], &val);
2597 	  }
2598 
2599       /* output device-specific help */
2600       if (help)
2601 	{
2602 	  printf ("\nOptions specific to device `%s':\n", devname);
2603 	  print_options(device, num_dev_options, SANE_FALSE);
2604 	}
2605 
2606       /*  list all device-specific options */
2607       if (all)
2608 	{
2609 	  printf ("\nAll options specific to device `%s':\n", devname);
2610 	  print_options(device, num_dev_options, SANE_TRUE);
2611 	  scanimage_exit (0);
2612 	}
2613     }
2614 
2615   /* output device list */
2616   if (help)
2617     {
2618       printf ("\
2619 Type ``%s --help -d DEVICE'' to get list of all options for DEVICE.\n\
2620 \n\
2621 List of available devices:", prog_name);
2622       status = sane_get_devices (&device_list, SANE_FALSE);
2623       if (status == SANE_STATUS_GOOD)
2624 	{
2625 	  int column = 80;
2626 
2627 	  for (i = 0; device_list[i]; ++i)
2628 	    {
2629 	      if (column + strlen (device_list[i]->name) + 1 >= 80)
2630 		{
2631 		  printf ("\n    ");
2632 		  column = 4;
2633 		}
2634 	      if (column > 4)
2635 		{
2636 		  fputc (' ', stdout);
2637 		  column += 1;
2638 		}
2639 	      fputs (device_list[i]->name, stdout);
2640 	      column += strlen (device_list[i]->name);
2641 	    }
2642 	}
2643       fputc ('\n', stdout);
2644       scanimage_exit (0);
2645     }
2646 
2647   if (dont_scan)
2648     scanimage_exit (0);
2649 
2650   if (output_format != OUTPUT_PNM)
2651     resolution_value = get_resolution ();
2652 
2653 #ifdef SIGHUP
2654   signal (SIGHUP, sighandler);
2655 #endif
2656 #ifdef SIGPIPE
2657   signal (SIGPIPE, sighandler);
2658 #endif
2659   signal (SIGINT, sighandler);
2660   signal (SIGTERM, sighandler);
2661 
2662   if (test == 0)
2663     {
2664       int n = batch_start_at;
2665 
2666       if (batch && NULL == format)
2667 	{
2668 	  switch(output_format) {
2669 	  case OUTPUT_TIFF:
2670 	    format = "out%d.tif";
2671 	    break;
2672 	  case OUTPUT_PNM:
2673 	    format = "out%d.pnm";
2674 	    break;
2675 #ifdef HAVE_LIBPNG
2676 	  case OUTPUT_PNG:
2677 	    format = "out%d.png";
2678 	    break;
2679 #endif
2680 #ifdef HAVE_LIBJPEG
2681 	  case OUTPUT_PDF:
2682 	    format = "out%d.pdf";
2683 	    break;
2684 	  case OUTPUT_JPEG:
2685 	    format = "out%d.jpg";
2686 	    break;
2687 #endif
2688 	  }
2689 	}
2690 
2691       if (!batch)
2692         {
2693           ofp = stdout;
2694           if (output_file != NULL)
2695             {
2696               ofp = fopen(output_file, "w");
2697               if (ofp == NULL)
2698                 {
2699                   fprintf(stderr, "%s: could not open output file '%s', "
2700                           "exiting\n", prog_name, output_file);
2701                   scanimage_exit(1);
2702                 }
2703             }
2704 #ifdef HAVE_LIBJPEG
2705          if (output_format == OUTPUT_PDF)
2706            {
2707              sane_pdf_open(&pw, ofp );
2708              sane_pdf_start_doc( pw );
2709            }
2710 #endif
2711         }
2712 
2713       if (batch)
2714 	{
2715 	  fputs("Scanning ", stderr);
2716 	  if (batch_count == BATCH_COUNT_UNLIMITED)
2717 	    fputs("infinity", stderr);
2718 	  else
2719 	    fprintf(stderr, "%d", batch_count);
2720 	  fprintf (stderr,
2721 		   " page%s, incrementing by %d, numbering from %d\n",
2722 		   batch_count == 1 ? "" : "s", batch_increment, batch_start_at);
2723 	}
2724 
2725       else if(isatty(fileno(ofp))){
2726 	fprintf (stderr,"%s: output is not a file, exiting\n", prog_name);
2727 	scanimage_exit (1);
2728       }
2729 
2730       buffer = malloc (buffer_size);
2731 
2732       do
2733 	{
2734 	  char path[PATH_MAX];
2735 	  char part_path[PATH_MAX];
2736 	  if (batch)  /* format is NULL unless batch mode */
2737 	    {
2738 	      sprintf (path, format, n);	/* love --(C++) */
2739 	      strcpy (part_path, path);
2740 #ifdef HAVE_LIBJPEG
2741 	      if (output_format != OUTPUT_PDF)
2742 #endif
2743      	         strcat (part_path, ".part");
2744 	    }
2745 
2746 
2747 	  if (batch)
2748 	    {
2749 	      if (batch_prompt)
2750 		{
2751 		  fprintf (stderr, "Place document no. %d on the scanner.\n",
2752 			   n);
2753 		  fprintf (stderr, "Press <RETURN> to continue.\n");
2754 		  fprintf (stderr, "Press Ctrl + D to terminate.\n");
2755 		  readbuf2 = fgets (readbuf, 2, stdin);
2756 
2757 		  if (readbuf2 == NULL)
2758 		    {
2759 		      if (ofp)
2760 			{
2761 #ifdef HAVE_LIBJPEG
2762 	                  if (output_format == OUTPUT_PDF)
2763 			    {
2764 		              sane_pdf_end_doc( pw );
2765 			      sane_pdf_close ( pw );
2766 			    }
2767 #endif
2768 			  fclose (ofp);
2769 			  ofp = NULL;
2770 			}
2771 		      break;	/* get out of this loop */
2772 		    }
2773 		}
2774 	      fprintf (stderr, "Scanning page %d\n", n);
2775 	    }
2776 
2777 #ifdef SANE_STATUS_WARMING_UP
2778           do
2779 	    {
2780 	      status = sane_start (device);
2781 	    }
2782 	  while(status == SANE_STATUS_WARMING_UP);
2783 #else
2784 	  status = sane_start (device);
2785 #endif
2786 	  if (status != SANE_STATUS_GOOD)
2787 	    {
2788 	      fprintf (stderr, "%s: sane_start: %s\n",
2789 		       prog_name, sane_strstatus (status));
2790 	      if (ofp )
2791 		{
2792 #ifdef HAVE_LIBJPEG
2793 	          if (output_format == OUTPUT_PDF)
2794 		    {
2795 		       sane_pdf_end_doc( pw );
2796 		       sane_pdf_close ( pw );
2797 		     }
2798 #endif
2799 		  fclose (ofp);
2800 		  ofp = NULL;
2801 		}
2802 	      break;
2803 	    }
2804 
2805 
2806 	  /* write to .part file while scanning is in progress */
2807 	  if (batch)
2808 	    {
2809 #ifdef HAVE_LIBJPEG
2810 	      SANE_Bool init_pdf = SANE_FALSE;
2811 #endif
2812 	      if (ofp == NULL)
2813 	        {
2814 	          ofp = fopen (part_path, "w");
2815 #ifdef HAVE_LIBJPEG
2816 	          if (output_format == OUTPUT_PDF && ofp != NULL)
2817 	             init_pdf = SANE_TRUE;
2818 #endif
2819 	        }
2820 	      if (NULL == ofp)
2821 		{
2822 		  fprintf (stderr, "cannot open %s\n", part_path);
2823 		  sane_cancel (device);
2824 		  return SANE_STATUS_ACCESS_DENIED;
2825 		}
2826 #ifdef HAVE_LIBJPEG
2827 	      if (init_pdf )
2828 	        {
2829 		  sane_pdf_open( &pw, ofp );
2830 		  sane_pdf_start_doc ( pw );
2831 		}
2832 #endif
2833 	    }
2834 
2835 	  status = scan_it (ofp, pw);
2836 
2837 #ifdef HAVE_LIBJPEG
2838 	  if (output_format == OUTPUT_PDF)
2839 	    {
2840 		  sane_pdf_end_page( pw );
2841 		  fflush( ofp );
2842 	    }
2843 #endif
2844 
2845 	  if (batch)
2846 	    {
2847 	      fprintf (stderr, "Scanned page %d.", n);
2848 	      fprintf (stderr, " (scanner status = %d)\n", status);
2849 	    }
2850 
2851 	  switch (status)
2852 	    {
2853 	    case SANE_STATUS_GOOD:
2854 	    case SANE_STATUS_EOF:
2855 	      status = SANE_STATUS_GOOD;
2856 	      if (batch)
2857 		{
2858 #ifdef HAVE_LIBJPEG
2859 	          if (output_format != OUTPUT_PDF)
2860 		    {
2861 #endif
2862 		      if (!ofp || 0 != fclose(ofp))
2863 		        {
2864 		           fprintf (stderr, "cannot close image file\n");
2865 		           sane_cancel (device);
2866 		           return SANE_STATUS_ACCESS_DENIED;
2867 		        }
2868 		      else
2869 		        {
2870 		           ofp = NULL;
2871 		           /* let the fully scanned file show up */
2872 		           if (rename (part_path, path))
2873 		             {
2874 		               fprintf (stderr, "cannot rename %s to %s\n",
2875 		                        part_path, path);
2876 			       sane_cancel (device);
2877 			       return SANE_STATUS_ACCESS_DENIED;
2878 			     }
2879 		           if (batch_print)
2880 			     {
2881 			        fprintf (stdout, "%s\n", path);
2882 			        fflush (stdout);
2883 			     }
2884 		        }
2885 #ifdef HAVE_LIBJPEG
2886 		    }
2887 #endif
2888 		}
2889               else
2890                 {
2891 #ifdef HAVE_LIBJPEG
2892 	              if (output_format == OUTPUT_PDF)
2893 		            {
2894 			          sane_pdf_end_doc( pw );
2895 			          fflush( ofp );
2896 			          sane_pdf_close ( pw );
2897 			        }
2898 #endif
2899                   if (output_file && ofp)
2900                     {
2901                       fclose(ofp);
2902                       ofp = NULL;
2903                     }
2904                 }
2905 	      break;
2906 	    default:
2907 	      if (batch)
2908 		{
2909 		  if (ofp)
2910 		    {
2911 		          fclose (ofp);
2912 		          ofp = NULL;
2913 			}
2914 		  unlink (part_path);
2915 		}
2916               else
2917                 {
2918 #ifdef HAVE_LIBJPEG
2919                   if (output_format == OUTPUT_PDF)
2920                     {
2921                        sane_pdf_end_doc( pw );
2922                        sane_pdf_close ( pw );
2923                     }
2924 #endif
2925                   if (output_file && ofp)
2926                     {
2927                       fclose(ofp);
2928                       ofp = NULL;
2929                     }
2930                   unlink (output_file);
2931                 }
2932 	      break;
2933 	    }			/* switch */
2934 	  n += batch_increment;
2935 	}
2936       while ((batch
2937 	      && (batch_count == BATCH_COUNT_UNLIMITED || --batch_count))
2938 	     && SANE_STATUS_GOOD == status);
2939 
2940       if (batch)
2941 	{
2942 #ifdef HAVE_LIBJPEG
2943 	  if (output_format == OUTPUT_PDF)
2944             {
2945 	      if (output_file && ofp)
2946 	        {
2947 	          sane_pdf_end_doc( pw );
2948 	          fflush( ofp );
2949 	          sane_pdf_close ( pw );
2950                   fclose(ofp);
2951                   ofp = NULL;
2952 		}
2953 	    }
2954 #endif
2955 	  int num_pgs = (n - batch_start_at) / batch_increment;
2956 	  fprintf (stderr, "Batch terminated, %d page%s scanned\n",
2957 		   num_pgs, num_pgs == 1 ? "" : "s");
2958 	}
2959 
2960       if (batch
2961 	  && SANE_STATUS_NO_DOCS == status
2962 	  && (batch_count == BATCH_COUNT_UNLIMITED)
2963 	  && n > batch_start_at)
2964 	status = SANE_STATUS_GOOD;
2965 
2966       sane_cancel (device);
2967     }
2968   else
2969     status = test_it ();
2970 
2971   scanimage_exit (status);
2972   /* the line below avoids compiler warnings */
2973   return status;
2974 }
2975