1#!/usr/bin/perl
2
3use warnings;
4use strict;
5use Sane;
6use Data::Dumper;
7use Getopt::Long qw(:config no_ignore_case pass_through);
8use File::Basename;
9use IO::Handle;
10
11#$Sane::DEBUG = 1;
12
13my (%options, @window_val_user, @window_option, @window_val,
14    @window, $device, $format, $devname, %option_number);
15my $num_dev_options = 0;
16my $verbose = 0;
17my $help = 0;
18my $test = 0;
19my $batch_start_at = 1;
20my $batch_count = -1;
21my $batch_increment = 1;
22my $buffer_size = (32 * 1024);	# default size
23my $tl_x = 0;
24my $tl_y = 0;
25my $br_x = 0;
26my $br_y = 0;
27my $w_x = 0;
28my $h_y = 0;
29my $resolution_optind = -1;
30my $resolution_value = 0;
31my $prog_name = basename($0);
32my $SANE_FRAME_TEXT = 10;
33my $SANE_FRAME_JPEG = 11;
34my $SANE_FRAME_G31D = 12;
35my $SANE_FRAME_G32D = 13;
36my $SANE_FRAME_G42D = 14;
37my $no_overwrite = 0;
38my $outputFile = "image-%04d";        # file name(format) to write output to
39my $raw = SANE_FALSE;
40my $scanScript;		# script to run at end of scan
41my $startNum = 1, my $endNum = -1;                # start/end numbers of pages to scan
42my @args = (\%options, 'd|device-name=s' => \$devname,
43                       'L|list-devices',
44                       'h|help' => \$help,
45                       'v|verbose+' => \$verbose,
46                       'N|no-overwrite' => \$no_overwrite,
47
48                       'o|output-file:s' => \$outputFile,
49                       's|start-count=i' => \$startNum,
50                       'e|end-count=i' => \$endNum,
51                       'r|raw' => \$raw);
52
53sub sane_strframe {
54 my $frame = shift;
55 my %frame = (
56  SANE_FRAME_GRAY => "gray",
57  SANE_FRAME_RGB => "RGB",
58  SANE_FRAME_RED => "red",
59  SANE_FRAME_GREEN => "green",
60  SANE_FRAME_BLUE => "blue",
61  $SANE_FRAME_TEXT => "text",
62  $SANE_FRAME_JPEG => "jpeg",
63  $SANE_FRAME_G31D => "g31d",
64  $SANE_FRAME_G32D => "g32d",
65  $SANE_FRAME_G42D => "g42d",
66 );
67 if (defined $frame{$frame}) {
68  return $frame{$frame};
69 }
70 else {
71  return "unknown";
72 }
73}
74
75
76sub sane_isbasicframe {
77 my $frame = shift;
78 return
79  $frame == SANE_FRAME_GRAY ||
80  $frame == SANE_FRAME_RGB ||
81  $frame == SANE_FRAME_RED ||
82  $frame == SANE_FRAME_GREEN ||
83  $frame == SANE_FRAME_BLUE
84}
85
86
87sub sighandler {
88 my $signum = shift;
89
90 if ($device) {
91  print STDERR "$prog_name: stopping scanner...\n";
92  $device->cancel;
93 }
94}
95
96
97sub print_unit {
98 my ($unit) = @_;
99
100 if ($unit == SANE_UNIT_PIXEL) {
101  print "pel";
102 }
103 elsif ($unit == SANE_UNIT_BIT) {
104  print "bit";
105 }
106 elsif ($unit == SANE_UNIT_MM) {
107  print "mm";
108 }
109 elsif ($unit == SANE_UNIT_DPI) {
110  print "dpi";
111 }
112 elsif ($unit == SANE_UNIT_PERCENT) {
113  print "%";
114 }
115 elsif ($unit == SANE_UNIT_MICROSECOND) {
116  print "us";
117 }
118}
119
120
121sub print_option {
122 my ($device, $opt_num, $short_name) = @_;
123
124 my $not_first = SANE_FALSE;
125 my $maxwindow = 0;
126
127 my $opt = $device->get_option_descriptor ($opt_num);
128
129 if ($short_name) {
130  printf "    -%s", $short_name;
131 }
132 else {
133  printf "    --%s", $opt->{name};
134 }
135
136 if ($opt->{type} == SANE_TYPE_BOOL) {
137  print "[=(";
138  print "auto|" if ($opt->{cap} & SANE_CAP_AUTOMATIC);
139  print "yes|no)]";
140 }
141 elsif ($opt->{type} != SANE_TYPE_BUTTON) {
142  print ' ';
143  if ($opt->{cap} & SANE_CAP_AUTOMATIC) {
144   print "auto|";
145   $not_first = SANE_TRUE;
146  }
147  if ($opt->{constraint_type} == SANE_CONSTRAINT_NONE) {
148   if ($opt->{type} == SANE_TYPE_INT) {
149    print "<int>";
150   }
151   elsif ($opt->{type} == SANE_TYPE_FIXED) {
152    print "<float>";
153   }
154   elsif ($opt->{type} == SANE_TYPE_STRING) {
155    print "<string>";
156   }
157   print ",..." if ($opt->{max_values} > 1);
158  }
159  elsif ($opt->{constraint_type} == SANE_CONSTRAINT_RANGE) {
160   my $format = "%g..%g";
161   $format = "%d..%d" if ($opt->{type} == SANE_TYPE_INT);
162   if ($opt->{name} eq SANE_NAME_SCAN_BR_X) {
163    $maxwindow = $opt->{constraint}{max} - $tl_x;
164    printf $format, $opt->{constraint}{min}, $maxwindow;
165   }
166   elsif ($opt->{name} eq SANE_NAME_SCAN_BR_Y) {
167    $maxwindow = $opt->{constraint}{max} - $tl_y;
168    printf $format, $opt->{constraint}{min}, $maxwindow;
169   }
170   else {
171    printf $format, $opt->{constraint}{min}, $opt->{constraint}{max};
172   }
173   print_unit ($opt->{unit});
174   print ",..." if ($opt->{max_values} > 1);
175   print " (in steps of $opt->{constraint}{quant})"
176    if ($opt->{constraint}{quant});
177  }
178  elsif ($opt->{constraint_type} == SANE_CONSTRAINT_STRING_LIST
179                      or $opt->{constraint_type} == SANE_CONSTRAINT_WORD_LIST) {
180   for (my $i = 0; $i < @{$opt->{constraint}}; ++$i) {
181    print '|' if ($i > 0);
182
183    print $opt->{constraint}[$i];
184   }
185   if ($opt->{constraint_type} == SANE_CONSTRAINT_WORD_LIST) {
186    print_unit ($opt->{unit});
187    print ",..." if ($opt->{max_values} > 1);
188   }
189  }
190 }
191 if ($opt->{max_values} == 1) {
192  # print current option value
193  if (! ($opt->{cap} & SANE_CAP_INACTIVE)) {
194   my $val = $device->get_option ($opt_num);
195   print " [";
196   if ($opt->{type} == SANE_TYPE_BOOL) {
197    print ($val ? "yes" : "no");
198   }
199   elsif ($opt->{type} == SANE_TYPE_INT or $opt->{type} == SANE_TYPE_FIXED) {
200    my $format = "%g";
201    $format = "%d" if ($opt->{type} == SANE_TYPE_INT);
202    if ($opt->{name} eq SANE_NAME_SCAN_TL_X) {
203     $tl_x = $val;
204     printf $format, $tl_x;
205    }
206    elsif ($opt->{name} eq SANE_NAME_SCAN_TL_Y) {
207     $tl_y = $val;
208     printf $format, $tl_y;
209    }
210    elsif ($opt->{name} eq SANE_NAME_SCAN_BR_X) {
211     $br_x = $val;
212     $w_x = $br_x - $tl_x;
213     printf $format, $w_x;
214    }
215    elsif ($opt->{name} eq SANE_NAME_SCAN_BR_Y) {
216     $br_y = $val;
217     $h_y = $br_y - $tl_y;
218     printf $format, $h_y;
219    }
220    else {
221     printf $format, $val;
222    }
223   }
224   elsif ($opt->{type} == SANE_TYPE_STRING) {
225    print $val;
226   }
227   print ']';
228  }
229 }
230
231 print " [inactive]" if ($opt->{cap} & SANE_CAP_INACTIVE);
232
233 print "\n        ";
234
235 if ($short_name eq 'x') {
236  print "Width of scan-area.";
237 }
238 elsif ($short_name eq 'y') {
239  print "Height of scan-area.";
240 }
241 else {
242  my $column = 8;
243  my $last_break = 0;
244  my $start = 0;
245  for (my $pos = 0; $pos < length($opt->{desc}); ++$pos) {
246   ++$column;
247   $last_break = $pos if (substr($opt->{desc}, $pos, 1) eq ' ');
248   if ($column >= 79 and $last_break) {
249    print substr($opt->{desc}, $start++, 1) while ($start < $last_break);
250    $start = $last_break + 1;   # skip blank
251    print "\n        ";
252    $column = 8 + $pos - $start;
253   }
254  }
255  print substr($opt->{desc}, $start++, 1) while ($start < length($opt->{desc}));
256 }
257 print "\n";
258}
259
260
261# A scalar has the following syntax:
262#
263#     V [ U ]
264#
265#   V is the value of the scalar.  It is either an integer or a
266#   floating point number, depending on the option type.
267#
268#   U is an optional unit.  If not specified, the default unit is used.
269#   The following table lists which units are supported depending on
270#   what the option's default unit is:
271#
272#     Option's unit:	Allowed units:
273#
274#     SANE_UNIT_NONE:
275#     SANE_UNIT_PIXEL:	pel
276#     SANE_UNIT_BIT:	b (bit), B (byte)
277#     SANE_UNIT_MM:	mm (millimeter), cm (centimeter), in or " (inches),
278#     SANE_UNIT_DPI:	dpi
279#     SANE_UNIT_PERCENT:	%
280#     SANE_UNIT_MICROSECOND:	us
281
282sub parse_scalar {
283 my ($opt, $str) = @_;
284
285 my ($v, $unit);
286 if ($str =~ /^(\d*\.?\d*)(cm|mm|in|\"|b|B|dpi|%|us)?/) {
287  $v = $1;
288  $unit = $2;
289  $unit = '' if not defined $unit;
290 }
291 else {
292  print STDERR
293             "$prog_name: option --$opt->{name}: bad option value (rest of option: $str)\n";
294  exit (1);
295 }
296
297 if ($opt->{unit} == SANE_UNIT_BIT) {
298  $v *= 8 if ($unit eq 'B');
299 }
300 elsif ($opt->{unit} == SANE_UNIT_MM) {
301  if ($unit eq 'cm') {
302   $v *= 10;
303  }
304  elsif ($unit eq 'in') {
305   $v *= 25.4;
306  }
307 }
308 return $v, substr($str, length($v) + length($unit), length($str));
309}
310
311
312# A vector has the following syntax:
313#
314#     [ '[' I ']' ] S { [','|'-'] [ '[' I ']' S }
315#
316#   The number in brackets (I), if present, determines the index of the
317#   vector element to be set next.  If I is not present, the value of
318#   last index used plus 1 is used.  The first index value used is 0
319#   unless I is present.
320#
321#   S is a scalar value as defined by parse_scalar().
322#
323#   If two consecutive value specs are separated by a comma (,) their
324#   values are set independently.  If they are separated by a dash (-),
325#   they define the endpoints of a line and all vector values between
326#   the two endpoints are set according to the value of the
327#   interpolated line.  For example, [0]15-[255]15 defines a vector of
328#   256 elements whose value is 15.  Similarly, [0]0-[255]255 defines a
329#   vector of 256 elements whose value starts at 0 and increases to
330#   255.
331
332sub parse_vector {
333 my ($opt, $str) = @_;
334
335 my $index = -1;
336 my $prev_value = 0;
337 my $prev_index = 0;
338 my $separator = '';
339 my (@vector, $value);
340 do {
341  if ($str =~ /^\[/) {
342   if ($str =~ /^\[(\d*\.?\d*)\]/) {
343    $index = $1;
344   }
345   else {
346    print STDERR
347             "$prog_name: option --$opt->{name}: closing bracket missing "
348                ."(rest of option: $str)\n";
349    exit (1);
350   }
351  }
352  else {
353   ++$index;
354  }
355
356  if ($index < 0 or $index >= length($str)) {
357   printf STDERR
358             "$prog_name: option --$opt->{name}: index $index out of range [0..%d]\n",
359               length($str);
360   exit (1);
361  }
362
363  # read value
364  ($value, $str) = parse_scalar ($opt, $str);
365
366  if ($str ne '' and $str !~ /^[-,]/) {
367   print STDERR
368             "$prog_name: option --$opt->{name}: illegal separator (rest of option: $str)\n";
369   exit (1);
370  }
371
372  # store value:
373  $vector[$index] = $value;
374  if ($separator eq '-') {
375   # interpolate
376   my $v = $prev_value;
377   my $slope = ($value - $v) / ($index - $prev_index);
378
379   for (my $i = $prev_index + 1; $i < $index; ++$i) {
380    $v += $slope;
381    $vector[$i] = $v;
382   }
383  }
384
385  $prev_index = $index;
386  $prev_value = $value;
387  $separator = substr($str, 0, 1);
388 }
389 while ($separator eq ',' || $separator eq '-');
390
391 if ($verbose > 2) {
392  print STDERR "$prog_name: value for --$opt->{name} is: ";
393  for (@vector) {
394   print STDERR "$_ ";
395  }
396  print STDERR "\n";
397 }
398
399 return @vector;
400}
401
402
403sub fetch_options {
404 my $device = shift;
405
406# We got a device, find out how many options it has:
407 $num_dev_options = $device->get_option(0);
408 if ($Sane::STATUS != SANE_STATUS_GOOD) {
409  print STDERR "$prog_name: unable to determine option count\n";
410  exit (1);
411 }
412
413 for (my $i = 0; $i < $num_dev_options; ++$i) {
414  my $opt = $device->get_option_descriptor ($i);
415
416  next if (! ($opt->{cap} & SANE_CAP_SOFT_SELECT));
417
418  $option_number{$opt->{name}} = $i;
419
420  # Look for scan resolution
421  $resolution_optind = $i
422   if (($opt->{type} == SANE_TYPE_FIXED || $opt->{type} == SANE_TYPE_INT)
423      and ($opt->{unit} == SANE_UNIT_DPI)
424      and ($opt->{name} eq SANE_NAME_SCAN_RESOLUTION));
425
426# Keep track of top-left corner options (if they exist at
427# all) and replace the bottom-right corner options by a
428# width/height option (if they exist at all).
429  if (($opt->{type} == SANE_TYPE_FIXED || $opt->{type} == SANE_TYPE_INT)
430      and ($opt->{unit} == SANE_UNIT_MM || $opt->{unit} == SANE_UNIT_PIXEL)) {
431   if ($opt->{name} eq SANE_NAME_SCAN_TL_X) {
432    $window[2] = $i;
433    $opt->{name} = 'l';
434   }
435   elsif ($opt->{name} eq SANE_NAME_SCAN_TL_Y) {
436    $window[3] = $i;
437    $opt->{name} = 't';
438   }
439   elsif ($opt->{name} eq SANE_NAME_SCAN_BR_X) {
440    $window[0] = $i;
441    $opt->{name} = 'x';
442    $window_option[0] = $opt;
443    $window_option[0]->{title} = 'Scan width';
444    $window_option[0]->{desc} = 'Width of scanning area.';
445    $window_val[0] = $device->get_option ($i)
446     if (!$window_val_user[0]);
447   }
448   elsif ($opt->{name} eq SANE_NAME_SCAN_BR_Y) {
449    $window[1] = $i;
450    $opt->{name} = 'y';
451    $window_option[1] = $opt;
452    $window_option[1]->{title} = 'Scan height';
453    $window_option[1]->{desc} = 'Height of scanning area.';
454    $window_val[1] = $device->get_option ($i)
455     if (!$window_val_user[1]);
456   }
457  }
458
459  if ($opt->{type} == SANE_TYPE_BOOL) {
460   push @args, "$opt->{name}:s";
461  }
462  elsif ($opt->{type} == SANE_TYPE_BUTTON) {
463   push @args, $opt->{name};
464  }
465  else {
466   push @args, "$opt->{name}=s";
467  }
468 }
469
470# Initialize width & height options based on backend default
471# values for top-left x/y and bottom-right x/y:
472 for (my $i = 0; $i < 2; ++$i) {
473  if ($window[$i] and $window[$i + 2] and !$window_val_user[$i]) {
474   my $pos = $device->get_option ($window[$i + 2]);
475   $window_val[$i] = $window_val[$i] - $pos if (defined $pos);
476  }
477 }
478}
479
480
481sub set_option {
482 my ($device, $optnum, $value) = @_;
483
484 my $opt = $device->get_option_descriptor ($optnum);
485 if ($opt and ($opt->{cap} & SANE_CAP_INACTIVE)) {
486  print STDERR
487             "$prog_name: ignored request to set inactive option $opt->{name}\n"
488   if ($verbose > 0);
489  return;
490 }
491
492 my $info = $device->set_option($optnum, $value);
493 if ($Sane::STATUS != SANE_STATUS_GOOD) {
494  print STDERR
495            "$prog_name: setting of option --$opt->{name} failed ($Sane::STATUS)\n";
496  exit (1);
497 }
498
499 if (($info & SANE_INFO_INEXACT) and $opt->{max_values} == 1) {
500  my $orig = $value;
501  $value = $device->get_option($optnum);
502  if ($opt->{type} == SANE_TYPE_INT) {
503   printf STDERR
504     "$prog_name: rounded value of $opt->{name} from %d to %d\n", $orig, $value;
505  }
506  elsif ($opt->{type} == SANE_TYPE_FIXED) {
507   printf STDERR
508     "$prog_name: rounded value of $opt->{name} from %g to %g\n", $orig, $value;
509  }
510 }
511 fetch_options ($device) if ($info & SANE_INFO_RELOAD_OPTIONS);
512}
513
514
515sub process_backend_option {
516 my ($device, $optnum, $optarg) = @_;
517
518 my $opt = $device->get_option_descriptor ($optnum);
519
520 if ($opt and ($opt->{cap} & SANE_CAP_INACTIVE)) {
521  print STDERR "$prog_name: attempted to set inactive option $opt->{name}\n";
522  exit (1);
523 }
524
525 if (($opt->{cap} & SANE_CAP_AUTOMATIC) and $optarg and $optarg =~ /^auto$/i) {
526  $device->set_auto($optnum);
527  if ($Sane::STATUS != SANE_STATUS_GOOD) {
528   printf STDERR "$prog_name: failed to set option --$opt->{name} to automatic ($Sane::STATUS)\n";
529   exit (1);
530  }
531  return;
532 }
533
534 my $value;
535 if ($opt->{type} == SANE_TYPE_BOOL) {
536  $value = 1;                # no argument means option is set
537  if ($optarg) {
538   if ($optarg =~ /^yes$/i) {
539    $value = 1;
540   }
541   elsif ($optarg =~ /^no$/i) {
542    $value = 0;
543   }
544   else {
545    printf STDERR "$prog_name: option --$opt->{name}: bad option value `$optarg'\n";
546    exit (1);
547   }
548  }
549 }
550 elsif ($opt->{type} == SANE_TYPE_INT or $opt->{type} == SANE_TYPE_FIXED) {
551  my @vector = parse_vector ($opt, $optarg);
552  $value = \@vector;
553 }
554 elsif ($opt->{type} == SANE_TYPE_STRING) {
555  $value = $optarg;
556 }
557 elsif ($opt->{type} == SANE_TYPE_BUTTON) {
558  $value = 0;                # value doesn't matter
559 }
560 else {
561  printf STDERR "$prog_name: duh, got unknown option type $opt->{type}\n";
562  return;
563 }
564 set_option ($device, $optnum, $value);
565}
566
567
568sub write_pnm_header_to_file {
569 my ($fh, $format, $width, $height, $depth) = @_;
570
571# The netpbm-package does not define raw image data with maxval > 255.
572# But writing maxval 65535 for 16bit data gives at least a chance
573# to read the image.
574
575 if ($format == SANE_FRAME_RED or $format == SANE_FRAME_GREEN or
576                      $format == SANE_FRAME_BLUE or $format == SANE_FRAME_RGB) {
577  printf $fh "P6\n# SANE data follows\n%d %d\n%d\n", $width, $height,
578	      ($depth <= 8) ? 255 : 65535;
579 }
580 elsif ($format == SANE_FRAME_GRAY) {
581  if ($depth == 1) {
582   printf $fh "P4\n# SANE data follows\n%d %d\n", $width, $height;
583  }
584  else {
585   printf $fh "P5\n# SANE data follows\n%d %d\n%d\n", $width, $height,
586		($depth <= 8) ? 255 : 65535;
587  }
588 }
589}
590
591
592sub scan_it_raw {
593 my ($fname, $raw, $script) = @_;
594
595 my $first_frame = 1, my $offset = 0, my $must_buffer = 0;
596 my $min = 0xff, my $max = 0;
597 my (%image, $fp);
598
599 my $parm;
600 {do { # extra braces to get last to work.
601  $device->start;
602  if ($Sane::STATUS != SANE_STATUS_GOOD) {
603   print STDERR "$prog_name: sane_start: $Sane::STATUS\n"
604    if ($Sane::STATUS != SANE_STATUS_NO_DOCS);
605   goto cleanup;
606  }
607
608  $parm = $device->get_parameters;
609  if ($Sane::STATUS != SANE_STATUS_GOOD) {
610   print STDERR "$prog_name: sane_get_parameters: $Sane::STATUS\n";
611   goto cleanup;
612  }
613
614  open $fp, '>', $fname;
615  if (!$fp) {
616   print STDERR "Error opening output `$fname': $@\n";
617   $Sane::_status = SANE_STATUS_IO_ERROR;
618   goto cleanup;
619  }
620
621  if ($verbose) {
622   if ($first_frame) {
623    if (sane_isbasicframe($parm->{format})) {
624     if ($parm->{lines} >= 0) {
625      printf STDERR "$prog_name: scanning image of size %dx%d pixels at "
626                ."%d bits/pixel\n",
627                $parm->{pixels_per_line}, $parm->{lines},
628                8 * $parm->{bytes_per_line} / $parm->{pixels_per_line};
629     }
630     else {
631       printf STDERR "$prog_name: scanning image %d pixels wide and "
632                ."variable height at %d bits/pixel\n",
633                $parm->{pixels_per_line},
634                8 * $parm->{bytes_per_line} / $parm->{pixels_per_line};
635     }
636    }
637    else {
638     printf STDERR "$prog_name: receiving %s frame "
639			     ."bytes/line=%d, "
640			     ."pixels/line=%d, "
641			     ."lines=%d, "
642			     ."depth=%d\n",
643			     , sane_strframe($parm->{format}),
644			     $parm->{bytes_per_line},
645			     $parm->{pixels_per_line},
646			     $parm->{lines},
647			     $parm->{depth};
648    }
649   }
650
651   printf STDERR "$prog_name: acquiring %s frame\n",
652                                                 sane_strframe($parm->{format});
653  }
654
655  if ($first_frame) {
656   if ($parm->{format} == SANE_FRAME_RED
657       or $parm->{format} == SANE_FRAME_GREEN
658       or $parm->{format} == SANE_FRAME_BLUE) {
659    die unless ($parm->{depth} == 8);
660    $must_buffer = 1;
661    $offset = $parm->{format} - SANE_FRAME_RED;
662   }
663   elsif ($parm->{format} == SANE_FRAME_RGB) {
664    die unless ($parm->{depth} == 8);
665   }
666   if ($parm->{format} == SANE_FRAME_RGB or $parm->{format} == SANE_FRAME_GRAY) {
667    die unless (($parm->{depth} == 1) || ($parm->{depth} == 8));
668    # if we're writing raw, we skip the header and never
669    # have to buffer a single frame format.
670    if ($raw == SANE_FALSE) {
671     if ($parm->{lines} < 0) {
672      $must_buffer = 1;
673      $offset = 0;
674     }
675     else {
676      write_pnm_header_to_file ($fp, $parm->{format},
677                                $parm->{pixels_per_line},
678                                $parm->{lines}, $parm->{depth});
679     }
680    }
681   }
682   elsif ($parm->{format} == $SANE_FRAME_TEXT
683          or $parm->{format} == $SANE_FRAME_JPEG
684          or $parm->{format} == $SANE_FRAME_G31D
685          or $parm->{format} == $SANE_FRAME_G32D
686          or $parm->{format} == $SANE_FRAME_G42D) {
687    if (!$parm->{last_frame}) {
688     $Sane::_status = SANE_STATUS_INVAL;
689     printf STDERR "$prog_name: bad %s frame: must be last_frame\n",
690              sane_strframe ($parm->{format});
691     goto cleanup;
692    }
693   }
694
695    # write them out without a header; don't buffer
696   else {
697    # Default action for unknown frametypes; write them out
698    # without a header; issue a warning in verbose mode.
699    # Since we're not writing a header, there's no need to
700    # buffer.
701    printf STDERR "$prog_name: unknown frame format $parm->{format}\n"
702     if ($verbose);
703    if (!$parm->{last_frame}) {
704     $Sane::_status = SANE_STATUS_INVAL;
705     printf STDERR "$prog_name: bad %s frame: must be last_frame\n",
706              sane_strframe ($parm->{format});
707     goto cleanup;
708    }
709   }
710  }
711  else {
712   die unless ($parm->{format} >= SANE_FRAME_RED
713           && $parm->{format} <= SANE_FRAME_BLUE);
714   $offset = $parm->{format} - SANE_FRAME_RED;
715   $image{x} = $image{y} = 0;
716  }
717
718  while (1) {
719   my ($buffer, $len) = $device->read ($buffer_size);
720   if ($Sane::STATUS != SANE_STATUS_GOOD) {
721    printf STDERR "$prog_name: min/max graylevel value = %d/%d\n", $min, $max
722     if ($verbose && $parm->{depth} == 8);
723    if ($Sane::STATUS != SANE_STATUS_EOF) {
724     print STDERR "$prog_name: sane_read: $Sane::STATUS\n";
725     return;
726    }
727    last;
728   }
729
730   if ($must_buffer) {
731    # We're either scanning a multi-frame image or the
732    # scanner doesn't know what the eventual image height
733    # will be (common for hand-held scanners).  In either
734    # case, we need to buffer all data before we can write
735    # the image
736    if ($parm->{format} == SANE_FRAME_RED
737        or $parm->{format} == SANE_FRAME_GREEN
738        or $parm->{format} == SANE_FRAME_BLUE) {
739     for (my $i = 0; $i < $len; ++$i) {
740      $image{data}[$offset + 3 * $i] = substr($buffer, $i, 1);
741     }
742     $offset += 3 * $len;
743    }
744    elsif ($parm->{format} == SANE_FRAME_RGB
745           or $parm->{format} == SANE_FRAME_GRAY) {
746     for (my $i = 0; $i < $len; ++$i) {
747      $image{data}[$offset + $i] = substr($buffer, $i, 1);
748     }
749     $offset += $len;
750    }
751    else {
752     # optional frametypes are never buffered
753     printf STDERR "$prog_name: ERROR: trying to buffer %s frametype\n",
754             sane_strframe($parm->{format});
755    }
756   }
757   else {
758    print $fp $buffer;
759   }
760
761   if ($verbose && $parm->{depth} == 8) {
762    for (split(//, $buffer)) {
763     my $c = ord;
764     if ($c >= $max) {
765      $max = $c;
766     }
767     elsif ($c < $min) {
768      $min = $c;
769     }
770    }
771   }
772
773  }
774  $first_frame = 0;
775 }
776 while (!$parm->{last_frame});}
777
778 if ($must_buffer) {
779  if ($parm->{lines} > 0) {
780   $image{height} = $parm->{lines};
781  }
782  else {
783   $image{height} = @{$image{data}}/$parm->{pixels_per_line};
784   $image{height} /= 3 if ($parm->{format} == SANE_FRAME_RED
785                         or $parm->{format} == SANE_FRAME_GREEN
786                         or $parm->{format} == SANE_FRAME_BLUE);
787  }
788  if ($raw == SANE_FALSE) {
789   # if we're writing raw, we skip the header
790   write_pnm_header_to_file ($fp, $parm->{format}, $parm->{pixels_per_line},
791                                                $image{height}, $parm->{depth});
792  }
793  for (@{$image{data}}) {print $fp $_;}
794 }
795
796 if ($fp) {
797  close $fp;
798  undef $fp;
799 }
800
801cleanup:
802 close $fp if ($fp);
803 return;
804}
805
806
807sub scan_docs {
808 my ($start, $end, $no_overwrite, $raw, $outfmt, $script) = @_;
809
810 $Sane::_status = SANE_STATUS_GOOD;
811 my $scannedPages = 0;
812
813 while ($end < 0 || $start <= $end) {
814  #!!! buffer overflow; need protection
815  my $fname = sprintf($outfmt, $start);
816
817  # does the filename already exist?
818  if ($no_overwrite and -r $fname) {
819   $Sane::_status = SANE_STATUS_INVAL;
820   print STDERR "Filename $fname already exists; will not overwrite\n";
821  }
822
823  # Scan the document
824  scan_it_raw($fname, $raw, $script) if ($Sane::STATUS == SANE_STATUS_GOOD);
825
826  # Any scan errors?
827  if ($Sane::STATUS == SANE_STATUS_NO_DOCS) {
828   # out of paper in the hopper; this is our normal exit
829   $Sane::_status = SANE_STATUS_GOOD;
830   last;
831  }
832  elsif ($Sane::STATUS == SANE_STATUS_EOF) {
833   # done with this doc
834   $Sane::_status = SANE_STATUS_GOOD;
835   print STDERR "Scanned document $fname\n";
836   $scannedPages++;
837   $start++;
838  }
839  else {
840   # unexpected error
841   print STDERR "$Sane::STATUS\n";
842   last;
843  }
844 }
845
846 print STDERR "Scanned $scannedPages pages\n";
847
848 return;
849}
850
851# There seems to be a bug in Getopt::Long 2.37 where l is treated as L whilst
852# l is not in @args. Therefore the workaround is to rename l to m for the first
853# scan and back to l for the second.
854for (@ARGV) {
855 $_ = '-m' if ($_ eq '-l');
856 $_ = '-u' if ($_ eq '-t');
857}
858# make a first pass through the options with error printing and argument
859# permutation disabled:
860GetOptions (@args);
861
862if (defined $options{L}) {
863 my @device_list = Sane->get_devices;
864 if ($Sane::STATUS != SANE_STATUS_GOOD) {
865  print STDERR "$prog_name: sane_get_devices() failed: $Sane::STATUS\n";
866  exit (1);
867 }
868 foreach (@device_list) {
869  printf "device `%s' is a %s %s %s\n", $_->{name}, $_->{vendor},
870                                         $_->{model}, $_->{type};
871 }
872 printf "\nNo scanners were identified. If you were expecting "
873         ."something different,\ncheck that the scanner is plugged "
874         ."in, turned on and detected by the\nsane-find-scanner tool "
875         ."(if appropriate). Please read the documentation\nwhich came "
876         ."with this software (README, FAQ, manpages).\n"
877  if ($#device_list == -1);
878 printf "default device is `%s'\n", $ENV{'SANE_DEFAULT_DEVICE'}
879  if (defined($ENV{'SANE_DEFAULT_DEVICE'}));
880 exit (0);
881}
882
883if (defined($options{V})) {
884 printf "$prog_name (sane-backends) %s\n", Sane->get_version;
885 exit (0);
886}
887
888if ($help) {
889 print "Usage: $prog_name [OPTION]...\n
890Start image acquisition on a scanner device and write image data to
891output files.\n
892   [ -d | --device-name <device> ]   use a given scanner device.
893   [ -h | --help ]                   display this help message and exit.
894   [ -L | --list-devices ]           show available scanner devices.
895   [ -v | --verbose ]                give even more status messages.
896   [ -V | --version ]                print version information.
897   [ -N | --no-overwrite ]           don't overwrite existing files.\n
898   [ -o | --output-file <name> ]     name of file to write image data
899                                     (\%d replacement in output file name).
900   [ -S | --scan-script <name> ]     name of script to run after every scan.
901   [ --script-wait ]                 wait for scripts to finish before exit
902   [ -s | --start-count <num> ]      page count of first scanned image.
903   [ -e | --end-count <num> ]        last page number to scan.
904   [ -r | --raw ]                    write raw image data to file.\n";
905}
906
907if (! $devname) {
908# If no device name was specified explicitly,
909# we open the first device we find (if any):
910 my @device_list = Sane->get_devices;
911 if ($Sane::STATUS != SANE_STATUS_GOOD) {
912  print STDERR "$prog_name: sane_get_devices() failed: $Sane::STATUS\n";
913  exit (1);
914 }
915 if ($#device_list == -1) {
916  print STDERR "$prog_name: no SANE devices found\n";
917  exit (1);
918 }
919 $devname = $device_list[0]{name};
920}
921
922$device = Sane::Device->open($devname);
923if ($Sane::STATUS != SANE_STATUS_GOOD) {
924 print STDERR "$prog_name: open of device $devname failed: $Sane::STATUS\n";
925 if ($help) {
926  undef $device;
927 }
928 else {
929  exit (1);
930 }
931}
932
933if (defined($device)) {
934 fetch_options($device);
935# re-enable error printing and arg permutation
936 Getopt::Long::Configure('no_pass_through');
937# There seems to be a bug in Getopt::Long 2.37 where l is treated as L whilst
938# l is not in @args. Therefore the workaround is to rename l to m for the first
939# scan and back to l for the second.
940 for (@ARGV) {
941  $_ = '-l' if ($_ eq '-m');
942  $_ = '-t' if ($_ eq '-u');
943 }
944 my @ARGV_old = @ARGV;
945 exit 1 if (! GetOptions (@args));
946# As it isn't possible to get the argument order from Getopt::Long 2.37, do
947# this myself
948 for (@ARGV_old) {
949  my $ch;
950  if (/--(.*)/) {
951   $ch = $1;
952   my $i = index($ch, '=');
953   $ch = substr($ch, 0, $i) if ($i > -1);
954  }
955  elsif (/-(.)/) {
956   $ch = $1;
957  }
958  else {
959   next;
960  }
961  if (defined $options{$ch}) {
962   if ($ch eq 'x') {
963    $window_val_user[0] = 1;
964    ($window_val[0]) = parse_vector ($window_option[0], $options{x});
965   }
966   elsif ($ch eq 'y') {
967    $window_val_user[1] = 1;
968    ($window_val[1]) = parse_vector ($window_option[1], $options{y});
969   }
970   elsif ($ch eq 'l') { # tl-x
971    process_backend_option ($device, $window[2], $options{l});
972   }
973   elsif ($ch eq 't') { # tl-y
974    process_backend_option ($device, $window[3], $options{t});
975   }
976   else {
977    process_backend_option ($device, $option_number{$ch}, $options{$ch});
978   }
979  }
980 }
981
982 for (my $index = 0; $index < 2; ++$index) {
983  if ($window[$index] and defined($window_val[$index])) {
984   my $val = $window_val[$index] - 1;
985   if ($window[$index + 2]) {
986    my $pos = $device->get_option ($window[$index + 2]);
987    $val = $pos + $window_val[$index] if (defined $pos);
988   }
989   set_option ($device, $window[$index], $val);
990  }
991 }
992 if ($help) {
993  printf "\nOptions specific to device `%s':\n", $devname;
994
995  for (my $i = 0; $i < $num_dev_options; ++$i) {
996   my $short_name = '';
997
998   my $opt = 0;
999   for (my $j = 0; $j < 4; ++$j) {
1000    if ($i == $window[$j]) {
1001     $short_name = substr("xylt", $j, 1);
1002     $opt = $window_option[$j] if ($j < 2);
1003    }
1004   }
1005   $opt = $device->get_option_descriptor ($i) if (!$opt);
1006
1007   printf "  %s:\n", $opt->{title} if ($opt->{type} == SANE_TYPE_GROUP);
1008
1009   next if (! ($opt->{cap} & SANE_CAP_SOFT_SELECT));
1010
1011   print_option ($device, $i, $short_name);
1012  }
1013  print "\n" if ($num_dev_options);
1014 }
1015}
1016
1017if ($help) {
1018 printf "Type ``$prog_name --help -d DEVICE'' to get list of all options for DEVICE.\n\nList of available devices:";
1019 my @device_list = Sane->get_devices;
1020 if ($Sane::STATUS == SANE_STATUS_GOOD) {
1021  my $column = 80;
1022
1023  foreach (@device_list) {
1024   if ($column + length ($_->{name}) + 1 >= 80) {
1025    printf "\n    ";
1026    $column = 4;
1027   }
1028   if ($column > 4) {
1029    print ' ';
1030    $column += 1;
1031   }
1032   print $_->{name};
1033   $column += length ($_->{name});
1034  }
1035 }
1036 print "\n";
1037 exit (0);
1038}
1039
1040$SIG{HUP} = \&sighandler;
1041$SIG{INT} = \&sighandler;
1042$SIG{PIPE} = \&sighandler;
1043$SIG{TERM} = \&sighandler;
1044
1045scan_docs ($startNum, $endNum, $no_overwrite, $raw, $outputFile, $scanScript);
1046
1047exit $Sane::STATUS;
1048
1049__END__
1050
1051=head1 NAME
1052
1053scanadf - acquire multiple images from a scanner equipped with an ADF
1054
1055=head1 SYNOPSIS
1056
1057B<scanadf>
1058B<[ -d | --device-name>
1059I<dev ]>
1060B<[ -h | --help ]>
1061B<[ -L | --list-devices ]>
1062B<[ -v | --verbose ]>
1063B<[ -V | --version ]>
1064B<[ -o | --output-file>
1065I<name ]>
1066B<[ -N | --no-overwrite ]>
1067B<[ -S | --scan-script>
1068I<name ]>
1069B<[ --script-wait ] >
1070B<[ -s | --start-count>
1071I<num ]>
1072B<[ -e | --end-count>
1073I<num ]>
1074B<[ -r | --raw ]>
1075I<[ device-specific-options ]>
1076
1077=head1 DESCRIPTION
1078
1079B<scanadf>
1080is a command-line interface to control image acquisition devices which
1081are capable of returning a series of images (e.g. a scanner with an
1082automatic document feeder (ADF)).  The device is controlled via
1083command-line options.  After command-line processing,
1084B<scanadf>
1085normally proceeds to acquire a series of images until the device returns
1086the
1087B<SANE_STATUS_NO_DOCS>
1088status code.
1089
1090The images are written to output files, specified by the
1091B<--output-file>
1092option.  These files are typically written in one of the PNM (portable aNyMaP)
1093formats (PBM for black-and-white images, PGM for grayscale images,
1094and PPM for color images).  Several optional frame formats (SANE_FRAME_JPEG,
1095SANE_FRAME_G31D, SANE_FRAME_G32D, SANE_FRAME_G42D, and SANE_FRAME_TEXT)
1096are supported.  In each case, the data is written out to the output file
1097as-is without a header.  Unrecognized frame formats are handled in
1098the same way, although a warning message is printed in verbose mode.
1099
1100Typically, the optional frame formats are used in conjunction with a scan
1101script (specified by the
1102B<--scanscript>
1103option) which is invoked for each acquired image.  The script is provided
1104with a series of environment variables which describe the parameters
1105and format of the image file.
1106
1107B<scanadf>
1108accesses image acquisition devices through the SANE (Scanner Access
1109Now Easy) interface and can thus support any device for which there
1110exists a SANE backend (try "apropos sane\-" to get a list of available
1111backends).
1112
1113=head1 OPTIONS
1114
1115The
1116B<-d>
1117or
1118B<--device-name>
1119options must be followed by a SANE device-name.  A (partial) list of
1120available devices can be obtained with the
1121B<--list-devices>
1122option (see below).  If no device-name is specified explicitly,
1123B<scanadf>
1124will attempt to open the first available device.
1125
1126The
1127B<-h>
1128or
1129B<--help>
1130options request help information.  The information is printed on
1131standard output and in this case, no attempt will be made to acquire
1132an image.
1133
1134The
1135B<-L>
1136or
1137B<--list-devices>
1138option requests a (partial) list of devices that are available.  The
1139list is not complete since some devices may be available, but are not
1140listed in any of the configuration files (which are typically stored
1141in directory /usr/etc/sane.d).  This is particularly the case when
1142accessing scanners through the network.  If a device is not listed in
1143a configuration file, the only way to access it is by its full device
1144name.  You may need to consult your system administrator to find out
1145the names of such devices.
1146
1147The
1148B<-v>
1149or
1150B<--verbose>
1151options increase the verbosity of the operation of
1152B<scanadf.>
1153The option may be specified repeatedly, each time increasing the verbosity
1154level.
1155
1156The
1157B<-V>
1158or
1159B<--version>
1160option requests that
1161B<scanadf>
1162print the program and package name, as well as the version number of
1163the SANE distribution that it came with.
1164
1165The
1166B<-o>
1167or
1168B<--output-file>
1169option specifies a format string used to generate the name of file to
1170write the image data to.  You can use %d replacement in the output file
1171name; this will be replaced with the current page number.  The default
1172format string is image-%04d.
1173
1174The
1175B<-N>
1176or
1177B<--no-overwrite>
1178option prevents
1179B<scanadf >
1180from overwriting existing image files.
1181
1182The
1183B<-S>
1184or
1185B<--scan-script>
1186option specifies the name of script to run after each scanned image
1187is acquired.  The script receives the name of the image output file
1188as its first and only command line argument.  Additionally the scan
1189script can reference the following environment variables to get
1190information about the parameters of the image.
1191
1192=over
1193
1194=item B<SCAN_RES>
1195
1196- the image resolution (in DPI)
1197
1198=item B<SCAN_WIDTH>
1199
1200- the image width (in pixels)
1201
1202=item B<SCAN_HEIGHT>
1203
1204- the image height (in pixels)
1205
1206=item B<SCAN_DEPTH>
1207
1208- the image bit-depth (in bits)
1209
1210=item B<SCAN_FORMAT>
1211
1212- a string representing the image format (e.g. gray, g42d, text, etc)
1213
1214=item B<SCAN_FORMAT_ID>
1215
1216- the numeric image format identifier
1217
1218=back
1219
1220If the
1221B<--scipt-wait>
1222option is given, scanadf will wait until all scan-scripts have been finished before
1223exiting. That will be useful if scanadf is used in conjunction with tools to modify
1224the scanned images.
1225
1226The
1227B<-s>
1228or
1229B<--start-count>
1230option specifies the page number of first scanned image.
1231
1232The
1233B<-e>
1234or
1235B<--end-count>
1236option specifies the last page number to scan.  Using this option,
1237you can request a specific number of pages to be scanned, rather than
1238scanning until there are no more images available.
1239
1240The
1241B<-r>
1242or
1243B<--raw>
1244option specifies that the raw image data be written to the output file
1245as-is without interpretation.  This disables the writing of the PNM
1246header for basic frame types.  This feature is usually used in
1247conjunction with the
1248B<--scan-script>
1249option where the scan script uses the environment variables to
1250understand the format and parameters of the image and converts
1251the file to a more useful format.  NOTE: With support for the
1252optional frame types and the default handling of unrecognized
1253frametypes, this option becomes less and less useful.
1254
1255As you might imagine, much of the power of
1256B<scanadf>
1257comes from the fact that it can control any SANE backend.  Thus, the
1258exact set of command-line options depends on the capabilities of the
1259selected device.  To see the options for a device named
1260I<dev ,>
1261invoke
1262B<scanadf>
1263via a command-line of the form:
1264
1265=over
1266
1267scanadf --help --device
1268I<dev>
1269
1270=back
1271
1272The documentation for the device-specific options printed by
1273B<--help>
1274is explained in the manual page for
1275B<scanimage.>
1276
1277=head1 FILES
1278
1279=over
1280
1281=item I</usr/etc/sane.d>
1282
1283This directory holds various configuration files.  For details, please
1284refer to the manual pages listed below.
1285
1286=back
1287
1288=head1 "SEE ALSO"
1289
1290scanimage(1), xscanimage(1), sane(7)
1291
1292=head1 AUTHOR
1293
1294Transliterated from the C original by Jeffrey Ratcliffe.
1295
1296=head1 BUGS
1297
1298All the bugs of scanadf and much, much more.
1299
1300This program relies on the backend to return the
1301B<SANE_STATUS_NO_DOCS>
1302status code when the automatic document feeder is out of paper.  Use of
1303this program with backends that do not support ADFs (e.g. flatbed scanners)
1304will likely result in repeated scans of the same document.  In this
1305case, it is essential to use the start-count and end-count to
1306control the number of images acquired.
1307
1308Only a subset of the SANE backends support feeders and return
1309SANE_STATUS_NO_DOCS appropriately.  Backends which are known to
1310work at this time are:
1311
1312=over
1313
1314=item B<sane-bh>
1315
1316- Bell+Howell Copiscan II series scanners.
1317
1318=item B<sane-hp>
1319
1320- Hewlett Packard scanners.  A patch to the sane-hp backend
1321is necessary.  The --scantype=ADF option must be specified (earlier
1322versions of the backend used the --scan-from-adf option, instead).
1323
1324=item B<sane-umax>
1325
1326- UMAX scanners.  Support exists in build 12 and later.
1327The --source="Automatic Document Feeder" option must be specified.
1328
1329=back
1330