Image::Sane(3)

Okay bestie, welcome to Image::Sane(3) โ€” the Perl situation for the SANE (Scanner Access Now Easy) Project. Grab a snack, we're getting into it. ๐Ÿ“

๐ŸŽ€ NAME ๐ŸŽ€

Image::Sane โ€” Perl extension for the SANE (Scanner Access Now Easy) Project. That's the name, no cap.

โญ VERSION โญ

5

Yep, version 5. Iconic number, honestly.

๐Ÿฆ‹ SYNOPSIS ๐Ÿฆ‹

use Image::Sane;
my @devices = Image::Sane->get_devices;
my $device = Image::Sane::Device->open($devices[0]->{name});
my $param = $device->get_parameters;
$device->write_pnm_header($fh, $param);
my ($data, $len) = $device->read ($param->{bytes_per_line});
print $fh $data;

๐ŸŒˆ DESCRIPTION ๐ŸŒˆ

These Perl bindings for the SANE (Scanner Access Now Easy) Project are your ticket to accessing SANE-compatible scanners in a Perlish and object-oriented way. The whole point? It frees you from the casting and memory management in C, while remaining very close in spirit to the original API. Like, bestie, you get the C-level power without the C-level pain. ๐Ÿ’…

Want to find out more about SANE? It's at http://www.sane-project.org. Go off. โœจ

๐Ÿ’… SUBROUTINES/METHODS

โœจ Image::Sane->get_version

Bestie, this one's your little version-checker ๐ŸŽ€ It hands you back an array holding the SANE_VERSION_(MAJOR|MINOR|BUILD) numbers, and you can smoosh 'em together like this:

join('.', Image::Sane->get_version)

โœจ Image::Sane->get_version_scalar

Same vibes, but scalar this time ๐Ÿฆ‹ You get the SANE_VERSION_(MAJOR|MINOR|BUILD) numbers combined the way Perl does version numbering โ€” so like, sane 1.0.19 gives you back 1.000019. And why do we care? Because now you can do the simplest, most iconic thing in the world: version comparisons. Periodt ๐Ÿ‘‘

โœจ Image::Sane->get_devices

Okay so this is the "who's out there" function ๐Ÿ” It queries the list of devices that are available, and if it runs successfully you get an array of hash references with the devices it found. And the returned list is guaranteed to stay valid until either (a) you call this function again, or (b) somebody calls sane_exit(). So don't go waving it around after that, mkay? ๐Ÿ™ˆ

But the cute part? You can call it repeatedly to detect when new devices show up. New scanner drops? You'll know. ๐Ÿ’–

If the argument local_only is true, then only local devices come back โ€” meaning devices directly attached to the machine SANE is running on. If it's false, then the device list includes all the remote devices the SANE library can reach. ๐ŸŒˆ

try {
    @devices = Image::Sane->get_devices;
    print "Name: $devices[0]->{name}\n";
    print "Vendor: $devices[0]->{vendor}\n";
    print "Model: $devices[0]->{model}\n";
    print "Type: $devices[0]->{type}\n";
}
catch {
    print "Error getting devices:", $_->error, "\n";
};

๐Ÿซถ Image::Sane::Device->open

This is where you actually connect to a device, bestie. You pass the name of the device you wanna open in the argument name. If the call completes successfully, you get an Image::Sane::Device object back. So satisfying. ๐ŸŒธ

And there's a special case that is lowkey iconic: if you pass a zero-length string as the device, you're requesting to open the first available device โ€” if there even is such a device. ๐Ÿคž

my $device = Image::Sane::Device->open($device_name);

๐ŸŽ€ Image::Sane::Device->get_option_descriptor

This is how you peek at the option descriptors ๐Ÿ‘€ The function returns a hash reference with the option descriptor for option number n of the Image::Sane::Device object.

Now listen, because this part matters: option number 0 is guaranteed to be a valid option. Its value is an integer that tells you the number of options available for the Image::Sane::Device object โ€” and yes, that count includes option 0. And if n isn't a valid option index? The function croaks. Rude but fair. ๐Ÿ’€

try {
    $option = $device->get_option_descriptor($n);
    print "Name: $option->{name}\n";
    print "Name: $option->{title}\n";
    print "Name: $option->{desc}\n";
    print "Name: $option->{type}\n";
    print "Name: $option->{unit}\n";
    print "Name: $option->{cap}\n";
    print "Name: $option->{max_values}\n";
    print "Name: $option->{constraint_type}\n";
}
catch {
    print "Error getting option descriptor:", $_->error, "\n";
};

The contents of the hash keys name, title, desc, type, unit, cap and constraint_type are all as per the C API description (http://www.sane-project.org/html) ๐Ÿงš

There's one more constraint key on top of those โ€” and it either contains an array with the possible option values, or a hash with the keys max, min, and quant. iykyk ๐Ÿ’…

Oh and heads up: the max_values key replaced the size key from the C API, and it holds the maximum number of values that the option may contain. โœจ

๐Ÿ’œ Image::Sane::Device->get_option

Returns the current value of the selected option. Simple, clean, slay. ๐ŸŒŸ

try {
    $value = $device->get_option($n);
    print "value: $value\n";
}
catch {
    print "Error getting option:", $_->error, "\n";
};

And for $option->{max_values} > 1, $value is a reference to an array. Not a scalar, bestie โ€” don't get caught out ๐Ÿซ 

๐ŸŒธ Image::Sane::Device->set_auto

This commands the selected device to automatically select an appropriate value ๐ŸŽฏ And this mode stays effective until it gets overridden by an explicit set_option request. It's giving "I'll handle it myself, thanks." ๐Ÿ˜Œ

$device->set_auto($n);

๐Ÿ”ฅ Image::Sane::Device->set_option

Sets the selected option, and returns flags in $info โ€” those flags are described over in the C API (http://www.sane-project.org/html). ๐Ÿ“š

$orig = $device->get_option($n);
$info = $device->set_option($n, $value);
if ($info & SANE_INFO_INEXACT) {
 $value = $device->get_option($n);
 print "rounded value of $opt->{name} from $orig to $value\n";
}

And for $option->{max_values} > 1, $value can be a reference to an array. Same deal as the getter ๐Ÿงš

โญ Image::Sane::Device->get_parameters

Okay this one gets the current scan parameters ๐Ÿ“ And the returned parameters are guaranteed to be accurate in the window between when a scan has been started (i.e. Image::Sane::Device->start() has been called) and the completion of that request.

Outside that window? They're best-effort estimates of what the parameters will be when Image::Sane::Device->start() gets invoked. Which is actually kind of a slay, because calling this before a scan has actually started lets you, for example, get an estimate of how big the scanned image is gonna be. ๐Ÿ”ฎ

try {
    $param = $device->get_parameters;
    print "format $param->{format}\n";
    print "last_frame $param->{last_frame}\n";
    print "bytes_per_line $param->{bytes_per_line}\n";
    print "pixels_per_line $param->{pixels_per_line}\n";
    print "lines $param->{lines}\n";
    print "depth $param->{depth}\n";
}
catch {
    print "Error getting parameters:", $_->error, "\n";
};

Please, please check the C documentation (http://www.sane-project.org/html) for the details of all those values above โ€” I'm not out here making things up ๐Ÿ’–

๐Ÿฆ‹ Image::Sane::Device->start

Initiates acquisition of an image from the device specified. That's it. That's the whole thing. Short queen. ๐Ÿ‘‘

$device->start;

๐ŸŒˆ Image::Sane::Device->read

This is the one that actually pulls image data off the device ๐Ÿ“ฅ The number of bytes returned in $buf gets stored in $len. A backend must set this to zero when an error is thrown. And if the call succeeds, the number of bytes returned can be anywhere in the range from 0 to $maxlen bytes โ€” anywhere in that range, no promises ๐Ÿ’ซ

$param = $device->get_parameters;
$maxlen = $param->{bytes_per_line};
($buf, $len) = $test->read ($maxlen);

Now here's where it splits, bestie. If this function is called when no data is available, one of two things happens โ€” depends on the I/O mode in effect for the device:

  1. If the device is in blocking I/O mode (which is the default mode), the call blocks until at least one data byte is available โ€” or until some error occurs. Just sitting there. Waiting. ๐Ÿ˜ด
  2. If the device is in non-blocking I/O mode, the call returns immediately with $len set to zero. In and out, no loitering ๐Ÿƒโ€โ™€๏ธ

And you set the I/O mode of the device via a call to Image::Sane::Device->set_io_mode(). ๐Ÿ’…

๐Ÿ’€ Image::Sane::Device->cancel

Immediately โ€” or as quickly as possible โ€” cancels the currently pending operation of the device. ๐Ÿ›‘

$device->cancel;

You can call this at any time (as long as $device is valid), but it usually only affects long-running operations, like image acquisition. And it's safe to call asynchronously, e.g. from within a signal handler. ๐Ÿซถ

But real talk, bestie: completion of this operation does not imply that the currently pending operation has been cancelled. It only guarantees that cancellation has been initiated. Cancellation completes only when the cancelled call throws an exception (typically with a status value of SANE_STATUS_CANCELLED). And since the SANE API doesn't require any other operations to be re-entrant, this means a frontend must not call any other operation until the cancelled operation has returned. No cap. Don't do it. ๐Ÿ˜ญ

๐ŸŽ€ Image::Sane::Device->set_io_mode

Sets the I/O mode of the device ๐ŸŽš๏ธ The mode can be either blocking or non-blocking. If the argument $bool is SANE_TRUE, the mode gets set to non-blocking; otherwise it's set to blocking. And โ€” important โ€” this function can be called only after a call to Image::Sane::Device->start() has been performed. โš ๏ธ

$device->set_io_mode ($bool);

By default, newly opened handles operate in blocking mode ๐Ÿ˜ด A backend may elect not to support non-blocking I/O mode โ€” in which case the call throws an exception with the status value SANE_STATUS_UNSUPPORTED. ๐Ÿ™ˆ

But here's the comforting part: blocking I/O must be supported by all backends, so calling this function with SANE_FALSE is guaranteed to complete successfully. Guaranteed, bestie. ๐Ÿซถโœจ

๐Ÿ’– Image::Sane::Device->get_select_fd

This grabs a (platform-specific) file-descriptor for the device that's readable if and only if image data is available โ€” i.e., when a call to Image::Sane::Device->read() will return at least one byte of data. Chef's kiss. ๐Ÿ‘จโ€๐Ÿณ๐Ÿ’‹

$fd = $device->get_select_fd;

You can only call this after a call to Image::Sane::Device->start() has been performed, and the returned file-descriptor is guaranteed to remain valid for the duration of the current image acquisition โ€” that is, until Image::Sane::Device->cancel() or Image::Sane::Device->start() is called again, or until Image::Sane::Device->read() throws an exception with status SANE_STATUS_EOF. ๐Ÿฆ‹

And yeah, a backend must guarantee to close the returned select file descriptor at the point when the next Image::Sane::Device->read() call would throw an exception with SANE_STATUS_EOF. Why? Because that's the only way the application can detect when this condition occurs without actually having to call Image::Sane::Device->read(). Necessity. ๐Ÿ’…

A backend may elect not to support this operation โ€” in that case, the function throws an exception with status code SANE_STATUS_UNSUPPORTED. ๐Ÿซ 

Heads up though: the only operation supported by the returned file-descriptor is a host operating-system dependent test of whether the file-descriptor is readable (e.g. that test can be implemented using select() or poll() under UNIX). If you perform any other operation on that file descriptor, the behaviour of the backend becomes unpredictable. ๐Ÿ’€ So don't get creative.

Once the file-descriptor signals "readable" status, it stays in that state until a call to sane_read() is performed. And since so many input devices are super slow ๐ŸŒ, support for this operation is strongly encouraged โ€” it lets an application go do other work while image acquisition is in progress. Multitasking queen behavior. ๐Ÿ‘‘

๐ŸŒŸ Image::Sane::Device->write_pnm_header

This one's a pure-Perl helper function to write a PNM header ๐Ÿ“ It'll fetch the current image settings using Image::Sane::Device->get_parameters if they're not already provided. Like so:

$device->write_pnm_header($fh);

or, if you're feeling fancy and already have the params:

$parm = $device->get_parameters;
$device->write_pnm_header ($fh, $parm->{format},
                                $parm->{pixels_per_line},
                                $parm->{lines}, $parm->{depth});

๐Ÿšจ DIAGNOSTICS

If the underlying SANE library returns a status value other than SANE_STATUS_GOOD, an exception is thrown ๐Ÿ˜ฑ So yeah โ€” it's suggested that you catch these using the Try::Tiny module. Inside your catch{} clause you can use $_->status and $_->error to get the status code and its equivalent string. Both. You get both. Slay. ๐Ÿ’…โœจ


๐Ÿงš CONFIGURATION AND ENVIRONMENT

This module doesn't require any special configuration or environment โ€” beyond, like, the stuff you already need for Perl and SANE. That's it. No secret setup, no hidden env vars. Breathe. ๐ŸŒธ

โœจ DEPENDENCIES โœจ

Ok so bestie, before you go anywhere, you need the actual SANE library โ€” like, that's non-negotiable, it's the whole entire vibe ๐Ÿ’…. And not just the library itself: you also need the backends for the scanners you're gonna use, so pick those up too or nothing's gonna scan, periodt.

For throwing exceptions, this module uses Exception::Class. And the suggestion from the author (iconic of him honestly) is that you catch those exceptions with Try::Tiny โ€” it's giving responsible coding, and we stan ๐Ÿซถ.


๐ŸŒˆ INCOMPATIBILITIES ๐ŸŒˆ

None known. Literally none. We're clean, we're unbothered, we're compatible ๐Ÿ’–.


๐Ÿฆ‹ BUGS AND LIMITATIONS ๐Ÿฆ‹

None known โ€” which, same energy as above. No cap, nothing to report here ๐Ÿ‘‘.


๐Ÿ”ฅ SEE ALSO ๐Ÿ”ฅ

If you wanna go deeper (and honestly, why wouldn't you), the SANE Standard Reference at <http://www.sane-project.org/html> is a super handy companion to keep around โ€” think of it as the lore wiki for your scanner shenanigans ๐Ÿ“šโœจ.

Also important iykyk: the Perl bindings follow the C API very closely, so the C reference documentation is the canonical source. If something's unclear here, the C docs are the main character, fr fr ๐Ÿ’€ โ€” go check those.


๐Ÿ’œ AUTHOR ๐Ÿ’œ

Jeffrey Ratcliffe, <jffry@posteo.net> โ€” shoutout to the legend himself, we love a maintainer ๐ŸŽ€.


Copyright (C) 2008--2019 by Jeffrey Ratcliffe.

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself โ€” either Perl version 5.8.5 or, at your option, any later version of Perl 5 you may have available. So basically: go off, remix it, share it, just keep the terms cute and legal bestie ๐Ÿงš๐Ÿ’–.


And that's a wrap on the whole page, babes! โœจ This masterpiece of a manpage is from perl v5.42.0, dated 2024-03-04, and it's Image::Sane(3) โ€” screenshot it, bookmark it, tattoo it, whatever your heart says ๐Ÿ’…๐ŸŒŸ. Happy scanning, bestie โ€” you've got this, and I'm obsessed with you for reading all the way through ๐Ÿซถ๐ŸŽ€

๐Ÿ“ฆ where this page comes from