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