Image-Sane
view release on metacpan or search on metacpan
examples/scanadf-perl view on Meta::CPAN
# The following table lists which units are supported depending on
# what the option's default unit is:
#
# Option's unit: Allowed units:
#
# SANE_UNIT_NONE:
# SANE_UNIT_PIXEL: pel
# SANE_UNIT_BIT: b (bit), B (byte)
# SANE_UNIT_MM: mm (millimeter), cm (centimeter), in or " (inches),
# SANE_UNIT_DPI: dpi
# SANE_UNIT_PERCENT: %
# SANE_UNIT_MICROSECOND: us
sub parse_scalar {
my ( $opt, $str ) = @_;
my ( $v, $unit );
if (
$str =~ qr{^
(\d*[.]?\d*) # value
(cm|mm|in|["bB%]|dpi|us)? # optional unit
}xsm
)
{
$v = $1;
$unit = $2;
if ( not defined $unit ) { $unit = $EMPTY }
}
else {
die
"$prog_name: option --$opt->{name}: bad option value (rest of option: $str)\n";
}
if ( $opt->{unit} == SANE_UNIT_BIT ) {
if ( $unit eq 'B' ) { $v *= $BITS_PER_BYTE }
}
elsif ( $opt->{unit} == SANE_UNIT_MM ) {
if ( $unit eq 'cm' ) {
$v *= $MM_PER_CM;
}
elsif ( $unit eq 'in' ) {
$v *= $MM_PER_INCH;
}
}
return $v, substr $str, length $v + length $unit, length $str;
}
# A vector has the following syntax:
#
# [ '[' I ']' ] S { [','|'-'] [ '[' I ']' S }
#
# The number in brackets (I), if present, determines the index of the
# vector element to be set next. If I is not present, the value of
# last index used plus 1 is used. The first index value used is 0
# unless I is present.
#
# S is a scalar value as defined by parse_scalar().
#
# If two consecutive value specs are separated by a comma (,) their
# values are set independently. If they are separated by a dash (-),
# they define the endpoints of a line and all vector values between
# the two endpoints are set according to the value of the
# interpolated line. For example, [0]15-[255]15 defines a vector of
# 256 elements whose value is 15. Similarly, [0]0-[255]255 defines a
# vector of 256 elements whose value starts at 0 and increases to
# 255.
sub parse_vector {
my ( $opt, $str ) = @_;
my $index = -1; ## no critic (ProhibitMagicNumbers)
my $prev_value = 0;
my $prev_index = 0;
my $separator = $EMPTY;
my ( @vector, $value );
while ( length $str ) {
if ( $str =~ /^\[(\d+)(\])?/xsm ) {
$index = $1;
if ( $2 ne '\]' ) {
die
"$prog_name: option --$opt->{name}: closing bracket missing "
. "(rest of option: $str)\n";
}
}
else {
++$index;
}
if ( $index < 0 or $index >= length $str ) {
printstderr(
sprintf
"$prog_name: option --$opt->{name}: index $index out of range [0..%d]\n",
length $str
);
exit 1;
}
# read value
( $value, $str ) = parse_scalar( $opt, $str );
if ( $str ne $EMPTY and $str !~ /^[-,]/xsm ) {
die
"$prog_name: option --$opt->{name}: illegal separator (rest of option: $str)\n";
}
# store value:
$vector[$index] = $value;
if ( $separator eq $DASH ) {
# interpolate
my $v = $prev_value;
my $slope = ( $value - $v ) / ( $index - $prev_index );
for my $i ( $prev_index + 1 .. $index - 1 ) {
$v += $slope;
$vector[$i] = $v;
}
}
$prev_index = $index;
$prev_value = $value;
$separator = substr $str, 0, 1;
( run in 1.234 second using v1.01-cache-2.11-cpan-524268b4103 )