2005-12-04 Rene Rebe <rene@exactcode.de>

* src/scanadf.c doc/scanadf.man: Added -p, --pipe option to scanadf
	  to pass data to the scripts via stdin and thus process the image
	  data parallel to the scan.
merge-requests/2/head
Rene Rebe 2005-12-04 20:37:58 +00:00
rodzic 032982c557
commit f79f2c3016
3 zmienionych plików z 138 dodań i 67 usunięć

Wyświetl plik

@ -1,3 +1,10 @@
2005-12-04 Rene Rebe <rene@exactcode.de>
* src/scanadf.c doc/scanadf.man: Added -p, --pipe option to scanadf
to pass data to the scripts via stdin and thus process the image
data parallel to the scan.
2005-10-09 Henning Meier-Geinitz <henning@meier-geinitz.de>
* configure configure.in: Changed version to 1.0.14-cvs.

Wyświetl plik

@ -20,6 +20,7 @@ scanadf - acquire multiple images from a scanner equipped with an ADF
.IR num ]
.RB [ -e | --end-count
.IR num ]
.RB [ -p | --pipe ]
.RB [ -r | --raw ]
.RI [ device-specific-options ]
.SH DESCRIPTION
@ -158,6 +159,9 @@ information about the parameters of the image.
.B SCAN_FORMAT_ID
- the numeric image format identifier
.br
.B SCAN_PIPE
- non-zero if a pipe is used for data transfer (instead of files)
.br
.RE
.PP
@ -199,6 +203,16 @@ the file to a more useful format. NOTE: With support for the
optional frame types and the default handling of unrecognized
frametypes, this option becomes less and less useful.
The
.B -p
or
.B --pipe
option allows passing the image date to the scan-script via a pipe
rather than saving it to a file and executing the script thereafter.
It might be useful for high-performance batch scans that should do
post-processing, such as format convertion, on-the-fly.
.PP
As you might imagine, much of the power of
.B scanadf
comes from the fact that it can control any SANE backend. Thus, the
@ -251,6 +265,10 @@ work at this time are:
.RS
.br
.B sane-avision
- Avision (and compatible) scanners. For batch scanning the --source "ADF",
"ADF Rear" or "ADF Duplex" should be used.
.br
.B sane-bh
- Bell+Howell Copiscan II series scanners.
.br

Wyświetl plik

@ -4,6 +4,7 @@
scanimage by Andreas Beck and David Mosberger
Copyright (C) 1999 Tom Martone
Copyright (C) 2005 Rene Rebe ([ -p | --pipe] script option)
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
@ -105,10 +106,11 @@ static struct option basic_options[] =
{ "scan-script", required_argument, 0, 'S' },
{ "script-wait", no_argument, 0, 128 },
{ "raw", no_argument, 0, 'r' },
{ "pipe", no_argument, 0, 'p' },
{0, }
};
#define BASE_OPTSTRING "d:hLvVNTo:s:e:S:r"
#define BASE_OPTSTRING "d:hLvVNTo:s:e:S:pr"
#define STRIP_HEIGHT 256 /* # lines we increment image height */
static struct option * all_options;
@ -875,8 +877,89 @@ get_resolution(SANE_Device *device)
return res;
}
static int
exec_script (const char *script, const char* fname, SANE_Bool use_pipe,
SANE_Parameters *parm, int *fd)
{
static char cmd[PATH_MAX * 2];
static char env[7][PATH_MAX * 2];
int pid;
SANE_Int res;
SANE_Frame format;
extern char **environ;
int pipefd[2];
res = get_resolution(device);
format = parm->format;
if (format == SANE_FRAME_RED ||
format == SANE_FRAME_GREEN ||
format == SANE_FRAME_BLUE)
{
/* the resultant format is RGB */
format = SANE_FRAME_RGB;
}
sprintf(env[0], "SCAN_RES=%d", res);
if (putenv(env[0]))
fprintf(stderr, "putenv:failed\n");
sprintf(env[1], "SCAN_WIDTH=%d", parm->pixels_per_line);
if (putenv(env[1]))
fprintf(stderr, "putenv:failed\n");
sprintf(env[2], "SCAN_HEIGHT=%d", parm->lines);
if (putenv(env[2]))
fprintf(stderr, "putenv:failed\n");
sprintf(env[3], "SCAN_FORMAT_ID=%d", (int) parm->format);
if (putenv(env[3]))
fprintf(stderr, "putenv:failed\n");
sprintf(env[4], "SCAN_FORMAT=%s",
sane_strframe(parm->format));
if (putenv(env[4]))
fprintf(stderr, "putenv:failed\n");
sprintf(env[5], "SCAN_DEPTH=%d", parm->depth);
if (putenv(env[5]))
fprintf(stderr, "putenv:failed\n");
sprintf(env[6], "SCAN_PIPE=%d", use_pipe);
if (putenv(env[6]))
fprintf(stderr, "putenv:failed\n");
if (use_pipe) {
pipe(pipefd);
}
/*signal(SIGCHLD, SIG_IGN);*/
switch ((pid = fork()))
{
case -1:
/* fork failed */
fprintf(stderr, "Error forking: %s (%d)\n", strerror(errno), errno);
break;
case 0:
/* in child process */
if (use_pipe) {
dup2(pipefd[0],0); close(pipefd[0]); close(pipefd[1]);
}
sprintf(cmd, "%s '%s'", script, fname);
execle(script, script, fname, NULL, environ);
exit(0);
default:
if (verbose)
fprintf(stderr, "Started script `%s' as pid=%d\n", script, pid);
break;
}
if (use_pipe) {
close(pipefd[0]);
*fd = pipefd[1];
}
return pid;
}
static SANE_Status
scan_it_raw (const char *fname, SANE_Bool raw, const char *script)
scan_it_raw (const char *fname, SANE_Bool raw, const char *script,
SANE_Bool use_pipe)
{
int i, len, first_frame = 1, offset = 0, must_buffer = 0;
SANE_Byte buffer[32*1024], min = 0xff, max = 0;
@ -884,6 +967,7 @@ scan_it_raw (const char *fname, SANE_Bool raw, const char *script)
SANE_Status status;
Image image = {0, };
FILE *fp = NULL;
int pid = 0;
do
{
@ -906,7 +990,15 @@ scan_it_raw (const char *fname, SANE_Bool raw, const char *script)
goto cleanup;
}
fp = fopen(fname, "wb");
if (script && use_pipe)
{
int fd = 0;
pid = exec_script(script, fname, use_pipe, &parm, &fd);
fp = fdopen (fd, "wb");
}
else
fp = fopen(fname, "wb");
if (!fp) {
fprintf(stderr, "Error opening output `%s': %s (%d)\n",
fname, strerror(errno), errno);
@ -1147,65 +1239,16 @@ scan_it_raw (const char *fname, SANE_Bool raw, const char *script)
fp = NULL;
}
if (script)
{
static char cmd[PATH_MAX * 2];
static char env[6][PATH_MAX * 2];
int pid;
SANE_Int res;
SANE_Frame format;
extern char **environ;
if (script && !use_pipe)
pid = exec_script (script, fname, use_pipe, &parm, NULL);
res = get_resolution(device);
format = parm.format;
if (format == SANE_FRAME_RED ||
format == SANE_FRAME_GREEN ||
format == SANE_FRAME_BLUE)
{
/* the resultant format is RGB */
format = SANE_FRAME_RGB;
}
sprintf(env[0], "SCAN_RES=%d", res);
if (putenv(env[0]))
fprintf(stderr, "putenv:failed\n");
sprintf(env[1], "SCAN_WIDTH=%d", parm.pixels_per_line);
if (putenv(env[1]))
fprintf(stderr, "putenv:failed\n");
sprintf(env[2], "SCAN_HEIGHT=%d", parm.lines);
if (putenv(env[2]))
fprintf(stderr, "putenv:failed\n");
sprintf(env[3], "SCAN_FORMAT_ID=%d", (int) parm.format);
if (putenv(env[3]))
fprintf(stderr, "putenv:failed\n");
sprintf(env[4], "SCAN_FORMAT=%s",
sane_strframe(parm.format));
if (putenv(env[4]))
fprintf(stderr, "putenv:failed\n");
sprintf(env[5], "SCAN_DEPTH=%d", parm.depth);
if (putenv(env[5]))
fprintf(stderr, "putenv:failed\n");
signal(SIGCHLD, SIG_IGN);
switch ((pid = fork()))
{
case -1:
/* fork failed */
fprintf(stderr, "Error forking: %s (%d)\n", strerror(errno), errno);
break;
case 0:
/* in child process */
sprintf(cmd, "%s '%s'", script, fname);
/* system(cmd); */
execle(script, script, fname, NULL, environ);
exit(0);
default:
if (verbose)
fprintf(stderr, "Started script `%s' as pid=%d\n", script, pid);
break;
}
}
if (script) {
int exit_status = 0;
waitpid (pid, &exit_status, 0);
if (exit_status && verbose)
fprintf(stderr, "%s: WARNING: child exited with %d\n",
prog_name, exit_status);
}
cleanup:
if (image.data)
@ -1216,7 +1259,8 @@ cleanup:
}
static SANE_Int
scan_docs (int start, int end, int no_overwrite, SANE_Bool raw, const char *outfmt, const char *script)
scan_docs (int start, int end, int no_overwrite, SANE_Bool raw,
const char *outfmt, const char *script, SANE_Bool use_pipe)
{
SANE_Status status = SANE_STATUS_GOOD;
SANE_Int scannedPages = 0;
@ -1226,8 +1270,7 @@ scan_docs (int start, int end, int no_overwrite, SANE_Bool raw, const char *outf
while (end < 0 || start <= end)
{
/*!!! buffer overflow; need protection */
sprintf(fname, outfmt, start);
snprintf(fname, sizeof (fname), outfmt, start);
/* does the filename already exist? */
if (no_overwrite)
@ -1242,7 +1285,7 @@ scan_docs (int start, int end, int no_overwrite, SANE_Bool raw, const char *outf
/* Scan the document */
if (status == SANE_STATUS_GOOD)
status = scan_it_raw(fname, raw, script);
status = scan_it_raw(fname, raw, script, use_pipe);
/* Any scan errors? */
if (status == SANE_STATUS_NO_DOCS)
@ -1283,6 +1326,7 @@ main (int argc, char **argv)
SANE_Status status;
char *full_optstring;
SANE_Bool raw = SANE_FALSE;
SANE_Bool use_pipe = SANE_FALSE;
const char *scanScript = NULL; /* script to run at end of scan */
int scriptWait = 0;
const char *outputFile = "image-%04d"; /* file name(format) to write output to */
@ -1343,6 +1387,7 @@ main (int argc, char **argv)
case 's': startNum = atoi(optarg); break;
case 'e': endNum = atoi(optarg); break;
case 'r': raw = SANE_TRUE; break;
case 'p': use_pipe = SANE_TRUE; break;
case 'V':
printf ("scanadf (%s) %s\n", PACKAGE, VERSION);
@ -1463,7 +1508,7 @@ main (int argc, char **argv)
exit (1); /* error message is printed by getopt_long() */
case 'd': case 'h': case 'v': case 'V': case 'T':
case 'o': case 'S': case 's': case 'e': case 'r':
case 'o': case 'S': case 's': case 'e': case 'p': case 'r':
/* previously handled options */
break;
@ -1577,7 +1622,8 @@ List of available devices:", prog_name);
signal (SIGPIPE, sighandler);
signal (SIGTERM, sighandler);
status = scan_docs (startNum, endNum, no_overwrite, raw, outputFile, scanScript);
status = scan_docs (startNum, endNum, no_overwrite, raw,
outputFile, scanScript, use_pipe);
sane_cancel (device);
sane_close (device);