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