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