diff options
Diffstat (limited to 'frontend/scanimage.c')
-rw-r--r-- | frontend/scanimage.c | 130 |
1 files changed, 115 insertions, 15 deletions
diff --git a/frontend/scanimage.c b/frontend/scanimage.c index fe02750..6906f90 100644 --- a/frontend/scanimage.c +++ b/frontend/scanimage.c @@ -2,7 +2,7 @@ Uses the SANE library. Copyright (C) 2015 Rolf Bensch <rolf at bensch hyphen online dot de> Copyright (C) 1996, 1997, 1998 Andreas Beck and David Mosberger - + Copyright (C) 1999 - 2009 by the SANE Project -- See AUTHORS and ChangeLog for details. @@ -93,6 +93,7 @@ static struct option basic_options[] = { {"help", no_argument, NULL, 'h'}, {"verbose", no_argument, NULL, 'v'}, {"progress", no_argument, NULL, 'p'}, + {"output-file", required_argument, NULL, 'o'}, {"test", no_argument, NULL, 'T'}, {"all-options", no_argument, NULL, 'A'}, {"version", no_argument, NULL, 'V'}, @@ -111,12 +112,13 @@ static struct option basic_options[] = { {0, 0, NULL, 0} }; -#define OUTPUT_PNM 0 -#define OUTPUT_TIFF 1 -#define OUTPUT_PNG 2 -#define OUTPUT_JPEG 3 +#define OUTPUT_UNKNOWN 0 +#define OUTPUT_PNM 1 +#define OUTPUT_TIFF 2 +#define OUTPUT_PNG 3 +#define OUTPUT_JPEG 4 -#define BASE_OPTSTRING "d:hi:Lf:B::nvVTAbp" +#define BASE_OPTSTRING "d:hi:Lf:o:B::nvVTAbp" #define STRIP_HEIGHT 256 /* # lines we increment image height */ static struct option *all_options; @@ -125,9 +127,10 @@ static int *option_number; static SANE_Handle device; static int verbose; static int progress = 0; +static const char* output_file = NULL; static int test; static int all; -static int output_format = OUTPUT_PNM; +static int output_format = OUTPUT_UNKNOWN; static int help; static int dont_scan = 0; static const char *prog_name; @@ -403,7 +406,7 @@ print_option (SANE_Device * device, int opt_num, const SANE_Option_Descriptor *o }*/ /* if one of these three is not set, option is useless, skip it */ - if(!(opt->cap & + if(!(opt->cap & (SANE_CAP_SOFT_SELECT | SANE_CAP_HARD_SELECT | SANE_CAP_SOFT_DETECT) )){ return; @@ -462,7 +465,7 @@ print_option (SANE_Device * device, int opt_num, const SANE_Option_Descriptor *o if (!strcmp (opt->name, "x")) { printf ("%d..%d", - opt->constraint.range->min, + opt->constraint.range->min, opt->constraint.range->max - tl_x); } else if (!strcmp (opt->name, "y")) @@ -1011,7 +1014,7 @@ set_option (SANE_Handle device, int optnum, void *valuep) prog_name, opt->name); return; } - + if (opt->size == sizeof (SANE_Word) && opt->type != SANE_TYPE_STRING) orig = *(SANE_Word *) valuep; @@ -1483,7 +1486,7 @@ scan_it (FILE *ofp) offset = parm.format - SANE_FRAME_RED; image.x = image.y = 0; } - hundred_percent = parm.bytes_per_line * parm.lines + hundred_percent = parm.bytes_per_line * parm.lines * ((parm.format == SANE_FRAME_RGB || parm.format == SANE_FRAME_GRAY) ? 1:3); while (1) @@ -1968,6 +1971,43 @@ static void print_options(SANE_Device * device, SANE_Int num_dev_options, SANE_B fputc ('\n', stdout); } +static int guess_output_format(const char* output_file) +{ + if (output_file == NULL) + { + fprintf(stderr, "Output format is not set, using pnm as a default.\n"); + return OUTPUT_PNM; + } + + // if the user passes us a path with a known extension then he won't be surprised if we figure + // out correct --format option. No warning is necessary in that case. + const char* extension = strrchr(output_file, '.'); + if (extension != NULL) + { + struct { + const char* extension; + int output_format; + } formats[] = { + { ".pnm", OUTPUT_PNM }, + { ".png", OUTPUT_PNG }, + { ".jpg", OUTPUT_JPEG }, + { ".jpeg", OUTPUT_JPEG }, + { ".tiff", OUTPUT_TIFF }, + { ".tif", OUTPUT_TIFF } + }; + for (unsigned i = 0; i < sizeof(formats) / sizeof(formats[0]); ++i) + { + if (strcmp(extension, formats[i].extension) == 0) + return formats[i].output_format; + } + } + + // it would be very confusing if user makes a typo in the filename and the output format changes. + // This is most likely not what the user wanted. + fprintf(stderr, "Could not guess output format from the given path and no --format given.\n"); + exit(1); +} + int main (int argc, char **argv) { @@ -2033,6 +2073,9 @@ main (int argc, char **argv) case 'p': progress = 1; break; + case 'o': + output_file = optarg; + break; case 'B': if (optarg) buffer_size = 1024 * atoi(optarg); @@ -2088,8 +2131,23 @@ main (int argc, char **argv) exit(1); #endif } - else - output_format = OUTPUT_PNM; + else if (strcmp (optarg, "pnm") == 0) + { + output_format = OUTPUT_PNM; + } + else + { + fprintf(stderr, "Unknown output image format '%s'.\n", optarg); + fprintf(stderr, "Supported formats: pnm, tiff"); +#ifdef HAVE_LIBPNG + fprintf(stderr, ", png"); +#endif +#ifdef HAVE_LIBJPEG + fprintf(stderr, ", jpeg"); +#endif + fprintf(stderr, ".\n"); + exit(1); + } break; case OPTION_MD5: accept_only_md5_auth = 1; @@ -2235,7 +2293,8 @@ Parameters are separated by a blank from single-character options (e.g.\n\ %%m (model), %%t (type), %%i (index number), and\n\ %%n (newline)\n\ -b, --batch[=FORMAT] working in batch mode, FORMAT is `out%%d.pnm' `out%%d.tif'\n\ - `out%%d.png' or `out%%d.jpg' by default depending on --format\n"); + `out%%d.png' or `out%%d.jpg' by default depending on --format\n\ + This option is incompatible with --output-file."); printf ("\ --batch-start=# page number to start naming files with\n\ --batch-count=# how many pages to scan in batch mode\n\ @@ -2247,6 +2306,8 @@ Parameters are separated by a blank from single-character options (e.g.\n\ printf ("\ --accept-md5-only only accept authorization requests using md5\n\ -p, --progress print progress messages\n\ +-o, --output-file=PATH save output to the given file instead of stdout.\n\ + This option is incompatible with --batch.\n\ -n, --dont-scan only set options, don't actually scan\n\ -T, --test test backend thoroughly\n\ -A, --all-options list all available backend options\n\ @@ -2257,6 +2318,15 @@ Parameters are separated by a blank from single-character options (e.g.\n\ -V, --version print version information\n"); } + if (batch && output_file != NULL) + { + fprintf(stderr, "--batch and --output-file can't be used together.\n"); + exit(1); + } + + if (output_format == OUTPUT_UNKNOWN) + output_format = guess_output_format(output_file); + if (!devname) { /* If no device name was specified explicitly, we look at the @@ -2389,6 +2459,7 @@ Parameters are separated by a blank from single-character options (e.g.\n\ case 'd': case 'h': case 'p': + case 'o': case 'v': case 'V': case 'T': @@ -2535,7 +2606,19 @@ List of available devices:", prog_name); } if (!batch) - ofp = stdout; + { + ofp = stdout; + if (output_file != NULL) + { + ofp = fopen(output_file, "w"); + if (ofp == NULL) + { + fprintf(stderr, "%s: could not open input file '%s', " + "exiting\n", prog_name, output_file); + scanimage_exit(1); + } + } + } if (batch) { @@ -2662,6 +2745,14 @@ List of available devices:", prog_name); } } } + else + { + if (output_file && ofp) + { + fclose(ofp); + ofp = NULL; + } + } break; default: if (batch) @@ -2673,6 +2764,15 @@ List of available devices:", prog_name); } unlink (part_path); } + else + { + if (output_file && ofp) + { + fclose(ofp); + ofp = NULL; + } + unlink (output_file); + } break; } /* switch */ n += batch_increment; |