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