kopia lustrzana https://gitlab.com/sane-project/backends
Added gamma table support and brightness / contrast emulation via the gamma
-table to the avision backend. Additional code clean ups ... Added my new e-mail address to the AUTHORS file.DEVEL_2_0_BRANCH-1
rodzic
2fd09894c1
commit
83d084d8d3
2
AUTHORS
2
AUTHORS
|
@ -110,7 +110,7 @@ Peter Fales <psfales@earthling.net>
|
|||
Peter Kirchgessner <peter@kirchgessner.net>
|
||||
Petter Reinholdtsen <pere@td.org.uit.no>
|
||||
Randolph Bentson <bentson@grieg.holmsjoen.com>
|
||||
Rene Rebe <rene.rebe@myokay.net>
|
||||
Rene Rebe <rene.rebe@gmx.net>
|
||||
Roger Wolff <R.E.Wolff@BitWizard.nl>
|
||||
Simon Munton <simon@munton.demon.co.uk>
|
||||
Tristan Tarrant <ttarrant@etnoteam.it>
|
||||
|
|
|
@ -41,14 +41,14 @@
|
|||
|
||||
*****************************************************************************
|
||||
|
||||
This file implements a SANE backend for the Avision AV 630CS scanner with
|
||||
SCSI-2 command set.
|
||||
This file implements a SANE backend for the Avision AV 630CS (and other ...)
|
||||
scanner with SCSI-2 command set.
|
||||
|
||||
(feedback to: mccramer@s.netic.de and rene.rebe@myokay.net)
|
||||
|
||||
Very much thanks to:
|
||||
Avision INC for the documentation we got! ;-)
|
||||
Gunter Wagner for some fixes and the transparency option
|
||||
Gunter Wagner for some fixes and the transparency option.
|
||||
|
||||
********************************************************************************/
|
||||
|
||||
|
@ -66,6 +66,8 @@
|
|||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include <sane/sane.h>
|
||||
#include <sane/sanei.h>
|
||||
#include <sane/saneopts.h>
|
||||
|
@ -82,6 +84,10 @@
|
|||
|
||||
|
||||
#define BACKEND_NAME avision
|
||||
#define BACKEND_BUILD 12 /* avision backend BUILD version */
|
||||
|
||||
#define MAX_X_RANGE 8.5 /* used when scanner returns invaild ragne fields ... */
|
||||
#define MAX_Y_RANGE 11.8
|
||||
|
||||
#ifndef PATH_MAX
|
||||
# define PATH_MAX 1024
|
||||
|
@ -89,7 +95,7 @@
|
|||
|
||||
#define AVISION_CONFIG_FILE "avision.conf"
|
||||
|
||||
#define MM_PER_INCH (254.0 / 10.0)
|
||||
#define MM_PER_INCH (25.4)
|
||||
|
||||
static int num_devices;
|
||||
static Avision_Device* first_dev;
|
||||
|
@ -476,13 +482,20 @@ sense_handler (int fd, u_char *sense, void *arg)
|
|||
static SANE_Status
|
||||
attach (const char* devname, Avision_Device** devp)
|
||||
{
|
||||
char result[INQ_LEN];
|
||||
unsigned char result [INQ_LEN];
|
||||
int fd;
|
||||
Avision_Device* dev;
|
||||
SANE_Status status;
|
||||
size_t size;
|
||||
char *mfg, *model;
|
||||
char *p;
|
||||
|
||||
char mfg[9];
|
||||
char model[17];
|
||||
char rev[5];
|
||||
|
||||
int i;
|
||||
|
||||
double x_range;
|
||||
double y_range;
|
||||
|
||||
DBG (3, "attach\n");
|
||||
|
||||
|
@ -514,30 +527,18 @@ attach (const char *devname, Avision_Device **devp)
|
|||
if (status != SANE_STATUS_GOOD)
|
||||
return status;
|
||||
|
||||
/* DEBUG CODE!! To test new Scanenr Output...
|
||||
printf ("RAW.Result: ");
|
||||
for (i = 0; i < sizeof (result); i++)
|
||||
{
|
||||
printf ("%d:[%c-%x], ", i, result[i], (unsigned char) result[i]);
|
||||
}
|
||||
printf ("\n");
|
||||
*/
|
||||
/* copy string information - and build zero terminated c-strings */
|
||||
memcpy (&mfg, result + 8, 8);
|
||||
mfg [8] = 0;
|
||||
memcpy (&model, result + 16, 16);
|
||||
model [16] = 0;
|
||||
memcpy (&rev, result + 32, 4);
|
||||
rev [4] = 0;
|
||||
|
||||
result[33]= '\0';
|
||||
p = strchr(result+16,' ');
|
||||
if (p) *p = '\0';
|
||||
model = strdup (result+16);
|
||||
DBG (1, "attach: Inquiry gives mfg=%s, model=%s, product revision=%s.\n", &mfg, &model, &rev);
|
||||
|
||||
result[16]= '\0';
|
||||
p = strchr(result+8,' ');
|
||||
if (p) *p = '\0';
|
||||
mfg = strdup (result+8);
|
||||
|
||||
DBG(1, "attach: Inquiry gives mfg=%s, model=%s.\n", mfg, model);
|
||||
|
||||
if (strcmp (mfg, "AVISION") != 0) {
|
||||
DBG(1, "attach: device doesn't look like a AVISION scanner "
|
||||
"(result[0]=%#02x)\n", result[0]);
|
||||
if (strcmp (&mfg, "AVISION ") != 0) {
|
||||
DBG (1, "attach: device doesn't look like a AVISION scanner!");
|
||||
return SANE_STATUS_INVAL;
|
||||
}
|
||||
|
||||
|
@ -545,39 +546,47 @@ attach (const char *devname, Avision_Device **devp)
|
|||
if (!dev)
|
||||
return SANE_STATUS_NO_MEM;
|
||||
|
||||
memset (dev, 0, sizeof (*dev));
|
||||
memset (dev, 0x0, sizeof (*dev));
|
||||
|
||||
dev->sane.name = strdup (devname);
|
||||
dev->sane.vendor = "AVISION";
|
||||
dev->sane.model = model;
|
||||
dev->sane.model = strdup (&model);
|
||||
dev->sane.type = "flatbed scanner";
|
||||
|
||||
dev->x_range.min = 0;
|
||||
dev->y_range.min = 0;
|
||||
/* Getting max X and max > ...*/
|
||||
/* Doesn't work! Avision doesn't return the information! ...
|
||||
dev->x_range.max = SANE_FIX ( (int) ((((int) result[81] << 8) + result[82]) / 300) * MM_PER_INCH);
|
||||
dev->y_range.max = SANE_FIX ( (int) ((((int) result[83] << 8) + result[84]) / 300) * MM_PER_INCH);
|
||||
*/
|
||||
dev->x_range.max = SANE_FIX ( 8.5 * MM_PER_INCH);
|
||||
dev->y_range.max = SANE_FIX (11.8 * MM_PER_INCH);
|
||||
/* Get max X and max Y ...*/
|
||||
x_range = ( ( ( (unsigned int)result[81] << 8) + (unsigned int)result[82] ) / 300 ) * MM_PER_INCH;
|
||||
y_range = ( ( ( (unsigned int)result[83] << 8) + (unsigned int)result[84] ) / 300 ) * MM_PER_INCH;
|
||||
dev->x_range.max = SANE_FIX (x_range);
|
||||
dev->y_range.max = SANE_FIX (y_range);
|
||||
|
||||
dev->x_range.quant = 0;
|
||||
dev->y_range.quant = 0;
|
||||
|
||||
/* Maybe an other Avision Scanner returns this ... and I like test it...
|
||||
printf ("X-Range: %d inch\n", dev->x_range.max);
|
||||
printf ("Y-Range: %d inch\n", dev->y_range.max);
|
||||
|
||||
printf ("Raw-Range: %d, %d, %d, %d\n", (int)result[81], (int)result[82], (int)result[83], (int)result[84]);
|
||||
*/
|
||||
|
||||
dev->dpi_range.min = 50;
|
||||
dev->dpi_range.quant = 1;
|
||||
dev->dpi_range.max = 1200;
|
||||
|
||||
DBG(3, "attach: found AVISION scanner model %s (%s)\n",
|
||||
dev->sane.model, dev->sane.type);
|
||||
DBG (3, "attach: found AVISION scanner model %s (%s)\n", dev->sane.model, dev->sane.type);
|
||||
DBG (3, " X-Range: %fmm, Y-Range: %fmm (Raw-Range: %d, %d, %d, %d)\n",
|
||||
SANE_UNFIX (dev->x_range.max),
|
||||
SANE_UNFIX (dev->y_range.max),
|
||||
(int)result[81], (int)result[82], (int)result[83], (int)result[84]);
|
||||
|
||||
DBG (5, "RAW.Result:\n");
|
||||
for (i = 0; i < sizeof (result); i++)
|
||||
{
|
||||
DBG (5, "[%d]:%x->""%c""\n", i, (unsigned char) result[i], result[i]);
|
||||
}
|
||||
|
||||
/* check if x/y range is vaild :-((( */
|
||||
if (dev->x_range.max == 0 || dev->y_range.max == 0)
|
||||
{
|
||||
DBG (3, "Inquiry x/y-range is invaild! Using defauld %fx%finch (ISO A4).\n", MAX_X_RANGE, MAX_Y_RANGE);
|
||||
dev->x_range.max = SANE_FIX (MAX_X_RANGE * MM_PER_INCH);
|
||||
dev->y_range.max = SANE_FIX (MAX_Y_RANGE * MM_PER_INCH);
|
||||
}
|
||||
else
|
||||
DBG (3, "Inquiry x/y-range is vaild?!?\n");
|
||||
|
||||
++num_devices;
|
||||
dev->next = first_dev;
|
||||
|
@ -606,7 +615,6 @@ max_string_size (const SANE_String_Const strings[])
|
|||
return max_size;
|
||||
}
|
||||
|
||||
|
||||
static SANE_Status
|
||||
constrain_value (Avision_Scanner *s, SANE_Int option, void *value,
|
||||
SANE_Int *info)
|
||||
|
@ -615,124 +623,278 @@ constrain_value (Avision_Scanner *s, SANE_Int option, void *value,
|
|||
return sanei_constrain_value (s->opt + option, value, info);
|
||||
}
|
||||
|
||||
|
||||
/* Will we need this ever??? Clean up in next release Meino???
|
||||
static unsigned char sign_mag (double val)
|
||||
/* next was taken from the GIMP and is a bit modifyed ... ;-)
|
||||
* original Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||||
*/
|
||||
static double
|
||||
brightness_contrast_func (double brightness, double contrast, double value)
|
||||
{
|
||||
if (val > 100) val = 100;
|
||||
if (val < -100) val = -100;
|
||||
if (val >= 0) return ( val);
|
||||
else return ((unsigned char)(-val)) | 0x80;
|
||||
double nvalue;
|
||||
double power;
|
||||
|
||||
/* apply brightness */
|
||||
if (brightness < 0.0)
|
||||
value = value * (1.0 + brightness);
|
||||
else
|
||||
value = value + ((1.0 - value) * brightness);
|
||||
|
||||
/* apply contrast */
|
||||
if (contrast < 0.0)
|
||||
{
|
||||
if (value > 0.5)
|
||||
nvalue = 1.0 - value;
|
||||
else
|
||||
nvalue = value;
|
||||
if (nvalue < 0.0)
|
||||
nvalue = 0.0;
|
||||
nvalue = 0.5 * pow (nvalue * 2.0 , (double) (1.0 + contrast));
|
||||
if (value > 0.5)
|
||||
value = 1.0 - nvalue;
|
||||
else
|
||||
value = nvalue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (value > 0.5)
|
||||
nvalue = 1.0 - value;
|
||||
else
|
||||
nvalue = value;
|
||||
if (nvalue < 0.0)
|
||||
nvalue = 0.0;
|
||||
power = (contrast == 1.0) ? 127 : 1.0 / (1.0 - contrast);
|
||||
nvalue = 0.5 * pow (2.0 * nvalue, power);
|
||||
if (value > 0.5)
|
||||
value = 1.0 - nvalue;
|
||||
else
|
||||
value = nvalue;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
static SANE_Status
|
||||
set_gamma (Avision_Scanner* s)
|
||||
{
|
||||
#define GAMMA_TABLE_SIZE 4096
|
||||
|
||||
SANE_Status status;
|
||||
struct gamma_cmd
|
||||
{
|
||||
struct command_send cmd;
|
||||
unsigned char gamma_data [GAMMA_TABLE_SIZE];
|
||||
};
|
||||
|
||||
struct gamma_cmd* cmd;
|
||||
|
||||
int color; /* current color */
|
||||
int i; /* big table index */
|
||||
int j; /* little table index */
|
||||
int k; /* big table sub index */
|
||||
double v1, v2;
|
||||
|
||||
double brightness;
|
||||
double contrast;
|
||||
/* double threshold; */
|
||||
|
||||
DBG (3, "set_gamma\n");
|
||||
|
||||
/* prepare for emulating contrast, brightness ... via the gamma-table */
|
||||
brightness = SANE_UNFIX (s->val[OPT_BRIGHTNESS].w);
|
||||
brightness /= 100;
|
||||
contrast = SANE_UNFIX (s->val[OPT_CONTRAST].w);
|
||||
contrast /= 100;
|
||||
|
||||
DBG (3, "brightness: %f, contrast: %f\n", brightness, contrast);
|
||||
|
||||
/* threshold = SANE_UNFIX (s->val[OPT_THRESHOLD].w); */
|
||||
/* threshold /= 100; */
|
||||
|
||||
/* should we sent a custom gamma-table ??
|
||||
* don't send anything if no - the scanner may not understand the gamma-table
|
||||
*/
|
||||
if (s->val[OPT_CUSTOM_GAMMA].w == SANE_TRUE)
|
||||
{
|
||||
DBG (4, "use custom gamma-table\n");
|
||||
for (color = 0; color < 3; color++)
|
||||
{
|
||||
cmd = malloc (sizeof (*cmd) );
|
||||
|
||||
memset (cmd, 0x0, sizeof (*cmd) );
|
||||
|
||||
cmd->cmd.opc = AVISION_SCSI_SEND;
|
||||
cmd->cmd.datatypecode = 0x81; /* 0x81 for download gama table */
|
||||
set_double (cmd->cmd.datatypequal, color); /* color: 0=red; 1=green; 2=blue */
|
||||
set_triple (cmd->cmd.transferlen, GAMMA_TABLE_SIZE);
|
||||
|
||||
i = 0; /* big table index */
|
||||
for (j = 0; j < 256; j++) /* little table index */
|
||||
{
|
||||
/* calculate mode dependent values v1 and v2
|
||||
* v1 <- current value for table
|
||||
* v2 <- next value for table (for interpolation)
|
||||
*/
|
||||
switch (s->mode)
|
||||
{
|
||||
case TRUECOLOR:
|
||||
{
|
||||
v1 = (double) (s->gamma_table [0][j] + s->gamma_table [1 + color][j] ) / 2;
|
||||
if (j == 255)
|
||||
v2 = (double) v1;
|
||||
else
|
||||
v2 = (double) (s->gamma_table [0][j + 1] + s->gamma_table [1 + color][j + 1] ) / 2;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* for all other modes: */
|
||||
{
|
||||
v1 = (double) s->gamma_table [0][j];
|
||||
if (j == 255)
|
||||
v2 = (double) v1;
|
||||
else
|
||||
v2 = (double) s->gamma_table [0][j + 1];
|
||||
}
|
||||
} /*end switch */
|
||||
/* emulate brightness, contrast ...
|
||||
* taken from the GIMP source - I'll optimize it when it is known to work
|
||||
*/
|
||||
|
||||
v1 /= 255;
|
||||
v2 /= 255;
|
||||
|
||||
v1 = (brightness_contrast_func (brightness, contrast, v1) );
|
||||
v2 = (brightness_contrast_func (brightness, contrast, v2) );
|
||||
|
||||
v1 *= 255;
|
||||
v2 *= 255;
|
||||
for (k = 0; k < 8; k++, i++)
|
||||
cmd->gamma_data [i] = ( ( (unsigned char)v1 * (8 - k)) + ( (unsigned char)v2 * k) ) / 8;
|
||||
}
|
||||
/* fill the gamma table */
|
||||
for (i = 2048; i < 4096; i++)
|
||||
cmd->gamma_data [i] = cmd->gamma_data [2047];
|
||||
|
||||
status = sanei_scsi_cmd (s->fd, cmd, sizeof (*cmd), 0, 0);
|
||||
|
||||
free (cmd);
|
||||
}
|
||||
} /* end if custom gamma*/
|
||||
else /* no custom gamma */
|
||||
{
|
||||
DBG (4, "don't use custom gamma-table\n");
|
||||
status = SANE_STATUS_GOOD;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
static SANE_Status
|
||||
scan_area_and_windows (Avision_Scanner *s)
|
||||
set_window (Avision_Scanner* s)
|
||||
{
|
||||
SANE_Status status;
|
||||
struct def_win_par dwp;
|
||||
struct
|
||||
{
|
||||
struct command_set_window cmd;
|
||||
struct command_set_window_window_header window_header;
|
||||
struct command_set_window_window_descriptor window_descriptor;
|
||||
} cmd;
|
||||
|
||||
DBG(3, "scan_area_and_windows\n" );
|
||||
DBG (3, "set_windows\n");
|
||||
|
||||
/* wipe out anything
|
||||
*/
|
||||
memset (&dwp,'\0',sizeof (dwp));
|
||||
/* wipe out anything */
|
||||
memset (&cmd, 0x0, sizeof (cmd) );
|
||||
|
||||
/* command setup
|
||||
*/
|
||||
dwp.dwph.opc = AVISION_SCSI_AREA_AND_WINDOWS;
|
||||
set_triple (dwp.dwph.len,sizeof (dwp.wdh) + sizeof (dwp.wdb));
|
||||
set_double (dwp.wdh.wpll, sizeof (dwp.wdb));
|
||||
/* command setup */
|
||||
cmd.cmd.opc = AVISION_SCSI_SET_WINDOWS;
|
||||
set_triple (cmd.cmd.transferlen,
|
||||
sizeof (cmd.window_header) + sizeof (cmd.window_descriptor) );
|
||||
set_double (cmd.window_header.desclen, sizeof (cmd.window_descriptor) );
|
||||
|
||||
/* resolution parameters
|
||||
*/
|
||||
set_double (dwp.wdb.xres, s->avdimen.res);
|
||||
set_double (dwp.wdb.yres, s->avdimen.res);
|
||||
/* resolution parameters */
|
||||
set_double (cmd.window_descriptor.xres, s->avdimen.res);
|
||||
set_double (cmd.window_descriptor.yres, s->avdimen.res);
|
||||
|
||||
/* upper left corner coordinates
|
||||
*/
|
||||
set_quad (dwp.wdb.ulx, s->avdimen.tlx);
|
||||
set_quad (dwp.wdb.uly, s->avdimen.tly);
|
||||
/* upper left corner coordinates */
|
||||
set_quad (cmd.window_descriptor.ulx, s->avdimen.tlx);
|
||||
set_quad (cmd.window_descriptor.uly, s->avdimen.tly);
|
||||
|
||||
/* width and length in inch/1200
|
||||
*/
|
||||
set_quad (dwp.wdb.width, s->avdimen.wid);
|
||||
set_quad (dwp.wdb.length, s->avdimen.len);
|
||||
/* width and length in inch/1200 */
|
||||
set_quad (cmd.window_descriptor.width, s->avdimen.wid);
|
||||
set_quad (cmd.window_descriptor.length, s->avdimen.len);
|
||||
|
||||
/* width and length in bytes
|
||||
*/
|
||||
set_double (dwp.wdb.linewidth, s->params.bytes_per_line );
|
||||
set_double (dwp.wdb.linecount, s->params.lines );
|
||||
/* width and length in bytes */
|
||||
set_double (cmd.window_descriptor.linewidth, s->params.bytes_per_line );
|
||||
set_double (cmd.window_descriptor.linecount, s->params.lines );
|
||||
|
||||
dwp.wdb.bitset1 = 0x60;
|
||||
dwp.wdb.bitset1 |= s->val[OPT_SPEED].w;
|
||||
cmd.window_descriptor.bitset1 = 0x60;
|
||||
cmd.window_descriptor.bitset1 |= s->val[OPT_SPEED].w;
|
||||
|
||||
dwp.wdb.bitset2 = 0x00;
|
||||
cmd.window_descriptor.bitset2 = 0x00;
|
||||
|
||||
/* quality scan option switch
|
||||
*/
|
||||
/* quality scan option switch */
|
||||
if( s->val[OPT_QSCAN].w == SANE_TRUE )
|
||||
{
|
||||
dwp.wdb.bitset2 |= AV_QSCAN_ON; /* Q_SCAN ON */
|
||||
cmd.window_descriptor.bitset2 |= AV_QSCAN_ON; /* Q_SCAN ON */
|
||||
}
|
||||
|
||||
/* quality calibration option switch
|
||||
*/
|
||||
/* quality calibration option switch */
|
||||
if ( s->val[OPT_QCALIB].w == SANE_TRUE )
|
||||
{
|
||||
dwp.wdb.bitset2 |= AV_QCALIB_ON; /* Q_CALIB ON */
|
||||
cmd.window_descriptor.bitset2 |= AV_QCALIB_ON; /* Q_CALIB ON */
|
||||
}
|
||||
/* transparency switch
|
||||
*/
|
||||
/* transparency switch */
|
||||
if ( s->val[OPT_TRANS].w == SANE_TRUE )
|
||||
{
|
||||
dwp.wdb.bitset2 |= AV_TRANS_ON; /* Set to transparency mode */
|
||||
cmd.window_descriptor.bitset2 |= AV_TRANS_ON; /* Set to transparency mode */
|
||||
}
|
||||
|
||||
/* fixed value
|
||||
*/
|
||||
dwp.wdb.pad_type = 3;
|
||||
dwp.wdb.vendor_specid = 0xFF;
|
||||
dwp.wdb.paralen = 9;
|
||||
cmd.window_descriptor.pad_type = 3;
|
||||
cmd.window_descriptor.vendor_specid = 0xFF;
|
||||
cmd.window_descriptor.paralen = 9;
|
||||
|
||||
/* currently also fixed
|
||||
(and unsopported by all Avision scanner I know ...)
|
||||
* (and unsopported by all Avision scanner I know ...)
|
||||
*/
|
||||
dwp.wdb.highlight = 0xFF;
|
||||
dwp.wdb.shadow = 0x00;
|
||||
cmd.window_descriptor.highlight = 0xFF;
|
||||
cmd.window_descriptor.shadow = 0x00;
|
||||
|
||||
/* mode dependant settings
|
||||
/* this is normaly unsupported by avsion scanner.
|
||||
* I clear this only to be shure if an other scanner knows about it ...
|
||||
* we do this via the gamma table (soon) ...
|
||||
*/
|
||||
switch (s->mode) {
|
||||
cmd.window_descriptor.thresh = 128;
|
||||
cmd.window_descriptor.brightness = 128;
|
||||
cmd.window_descriptor.contrast = 128;
|
||||
|
||||
/*
|
||||
* cmd.window_descriptor.thresh = 1 + 2.55 * (SANE_UNFIX (s->val[OPT_THRESHOLD].w));
|
||||
* cmd.window_descriptor.brightness = 128 + 1.28 * (SANE_UNFIX (s->val[OPT_BRIGHTNESS].w));
|
||||
* cmd.window_descriptor.contrast = 128 + 1.28 * (SANE_UNFIX (s->val[OPT_CONTRAST].w));
|
||||
*/
|
||||
|
||||
/* mode dependant settings */
|
||||
switch (s->mode)
|
||||
{
|
||||
case THRESHOLDED:
|
||||
dwp.wdb.bpp = 1;
|
||||
dwp.wdb.image_comp = 0;
|
||||
dwp.wdb.bitset1 &= 0xC7;
|
||||
dwp.wdb.thresh = 1 + 2.55 * (SANE_UNFIX (s->val[OPT_THRESHOLD].w));
|
||||
dwp.wdb.brightness = 128 + 1.28 * (SANE_UNFIX (s->val[OPT_BRIGHTNESS].w));
|
||||
dwp.wdb.contrast = 128 + 1.28 * (SANE_UNFIX (s->val[OPT_CONTRAST].w));
|
||||
cmd.window_descriptor.bpp = 1;
|
||||
cmd.window_descriptor.image_comp = 0;
|
||||
cmd.window_descriptor.bitset1 &= 0xC7;
|
||||
break;
|
||||
|
||||
case DITHERED:
|
||||
dwp.wdb.bpp = 1;
|
||||
dwp.wdb.image_comp = 1;
|
||||
dwp.wdb.bitset1 &= 0xC7;
|
||||
dwp.wdb.thresh = 1 + 2.55 * (SANE_UNFIX (s->val[OPT_THRESHOLD].w));
|
||||
dwp.wdb.brightness = 128 + 1.28 * (SANE_UNFIX (s->val[OPT_BRIGHTNESS].w));
|
||||
dwp.wdb.contrast = 128 + 1.28 * (SANE_UNFIX (s->val[OPT_CONTRAST].w));
|
||||
cmd.window_descriptor.bpp = 1;
|
||||
cmd.window_descriptor.image_comp = 1;
|
||||
cmd.window_descriptor.bitset1 &= 0xC7;
|
||||
break;
|
||||
|
||||
case GREYSCALE:
|
||||
dwp.wdb.bpp = 8;
|
||||
dwp.wdb.image_comp = 2;
|
||||
dwp.wdb.bitset1 &= 0xC7;
|
||||
/*dwp.wdb.bitset1 |= 0x30; *//* thanks Gunter */
|
||||
cmd.window_descriptor.bpp = 8;
|
||||
cmd.window_descriptor.image_comp = 2;
|
||||
cmd.window_descriptor.bitset1 &= 0xC7;
|
||||
/* cmd.window_descriptor.bitset1 |= 0x30; */ /* what is it for Gunter ?? - doesn't work */
|
||||
break;
|
||||
|
||||
case TRUECOLOR:
|
||||
dwp.wdb.bpp = 8;
|
||||
dwp.wdb.image_comp = 5;
|
||||
cmd.window_descriptor.bpp = 8;
|
||||
cmd.window_descriptor.image_comp = 5;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -742,7 +904,7 @@ scan_area_and_windows (Avision_Scanner *s)
|
|||
|
||||
/* set window command
|
||||
*/
|
||||
status = sanei_scsi_cmd (s->fd, &dwp, sizeof (dwp), 0, 0);
|
||||
status = sanei_scsi_cmd (s->fd, &cmd, sizeof (cmd), 0, 0);
|
||||
|
||||
/* back to caller
|
||||
*/
|
||||
|
@ -756,7 +918,7 @@ start_scan (Avision_Scanner *s)
|
|||
|
||||
DBG (3, "start_scan\n");
|
||||
|
||||
memset (&cmd,'\0',sizeof (cmd));
|
||||
memset (&cmd, 0x0, sizeof (cmd));
|
||||
cmd.opc = AVISION_SCSI_START_STOP;
|
||||
cmd.transferlen = 1;
|
||||
|
||||
|
@ -777,7 +939,6 @@ start_scan (Avision_Scanner *s)
|
|||
return sanei_scsi_cmd (s->fd, &cmd, sizeof (cmd), 0, 0);
|
||||
}
|
||||
|
||||
|
||||
static SANE_Status
|
||||
stop_scan (Avision_Scanner *s)
|
||||
{
|
||||
|
@ -789,7 +950,6 @@ stop_scan (Avision_Scanner *s)
|
|||
return sanei_scsi_cmd (s->fd, stop, sizeof (stop), 0, 0);
|
||||
}
|
||||
|
||||
|
||||
static SANE_Status
|
||||
do_eof (Avision_Scanner *s)
|
||||
{
|
||||
|
@ -809,7 +969,6 @@ do_eof (Avision_Scanner *s)
|
|||
return SANE_STATUS_EOF;
|
||||
}
|
||||
|
||||
|
||||
static SANE_Status
|
||||
do_cancel (Avision_Scanner *s)
|
||||
{
|
||||
|
@ -851,7 +1010,7 @@ read_data (Avision_Scanner *s, SANE_Byte *buf, int lines, int bpl)
|
|||
DBG (3, "read_data\n");
|
||||
|
||||
nbytes = bpl * lines;
|
||||
memset (&rcmd,'\0',sizeof (rcmd));
|
||||
memset (&rcmd, 0x0, sizeof (rcmd));
|
||||
rcmd.opc = 0x28;
|
||||
set_triple (rcmd.transferlen, nbytes);
|
||||
rcmd.datatypequal [0] = 0x0d;
|
||||
|
@ -864,8 +1023,6 @@ read_data (Avision_Scanner *s, SANE_Byte *buf, int lines, int bpl)
|
|||
return status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static SANE_Status
|
||||
init_options (Avision_Scanner* s)
|
||||
{
|
||||
|
@ -873,8 +1030,8 @@ init_options (Avision_Scanner *s)
|
|||
|
||||
DBG (3, "init_options\n");
|
||||
|
||||
memset (s->opt, 0, sizeof (s->opt));
|
||||
memset (s->val, 0, sizeof (s->val));
|
||||
memset (s->opt, 0x0, sizeof (s->opt));
|
||||
memset (s->val, 0x0, sizeof (s->val));
|
||||
|
||||
for (i = 0; i < NUM_OPTIONS; ++i) {
|
||||
s->opt[i].size = sizeof (SANE_Word);
|
||||
|
@ -882,13 +1039,13 @@ init_options (Avision_Scanner *s)
|
|||
}
|
||||
|
||||
s->opt[OPT_NUM_OPTS].title = SANE_TITLE_NUM_OPTIONS;
|
||||
s->opt[OPT_NUM_OPTS].desc = SANE_DESC_NUM_OPTIONS;
|
||||
s->opt[OPT_NUM_OPTS].desc = "";
|
||||
s->opt[OPT_NUM_OPTS].cap = SANE_CAP_SOFT_DETECT;
|
||||
s->val[OPT_NUM_OPTS].w = NUM_OPTIONS;
|
||||
|
||||
/* "Mode" group: */
|
||||
s->opt[OPT_MODE_GROUP].title = "Scan Mode";
|
||||
s->opt[OPT_MODE_GROUP].desc = "";
|
||||
s->opt[OPT_MODE_GROUP].title = SANE_TITLE_SCAN_MODE;
|
||||
s->opt[OPT_MODE_GROUP].desc = ""; /* for groups only title and type are vaild */
|
||||
s->opt[OPT_MODE_GROUP].type = SANE_TYPE_GROUP;
|
||||
s->opt[OPT_MODE_GROUP].cap = 0;
|
||||
s->opt[OPT_MODE_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
|
||||
|
@ -896,7 +1053,7 @@ init_options (Avision_Scanner *s)
|
|||
/* scan mode */
|
||||
s->opt[OPT_MODE].name = SANE_NAME_SCAN_MODE;
|
||||
s->opt[OPT_MODE].title = SANE_TITLE_SCAN_MODE;
|
||||
s->opt[OPT_MODE].desc = "Select the scan mode";
|
||||
s->opt[OPT_MODE].desc = SANE_DESC_SCAN_MODE;
|
||||
s->opt[OPT_MODE].type = SANE_TYPE_STRING;
|
||||
s->opt[OPT_MODE].size = max_string_size (mode_list);
|
||||
s->opt[OPT_MODE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
|
||||
|
@ -938,7 +1095,7 @@ init_options (Avision_Scanner *s)
|
|||
|
||||
/* "Geometry" group: */
|
||||
s->opt[OPT_GEOMETRY_GROUP].title = "Geometry";
|
||||
s->opt[OPT_GEOMETRY_GROUP].desc = "";
|
||||
s->opt[OPT_GEOMETRY_GROUP].desc = ""; /* for groups only title and type are vaild */
|
||||
s->opt[OPT_GEOMETRY_GROUP].type = SANE_TYPE_GROUP;
|
||||
s->opt[OPT_GEOMETRY_GROUP].cap = SANE_CAP_ADVANCED;
|
||||
s->opt[OPT_GEOMETRY_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
|
||||
|
@ -985,15 +1142,17 @@ init_options (Avision_Scanner *s)
|
|||
|
||||
/* "Enhancement" group: */
|
||||
s->opt[OPT_ENHANCEMENT_GROUP].title = "Enhancement";
|
||||
s->opt[OPT_ENHANCEMENT_GROUP].desc = "";
|
||||
s->opt[OPT_ENHANCEMENT_GROUP].desc = ""; /* for groups only title and type are vaild */
|
||||
s->opt[OPT_ENHANCEMENT_GROUP].type = SANE_TYPE_GROUP;
|
||||
s->opt[OPT_ENHANCEMENT_GROUP].cap = 0;
|
||||
s->opt[OPT_ENHANCEMENT_GROUP].constraint_type = SANE_CONSTRAINT_NONE;
|
||||
|
||||
/* transparency adapter. */
|
||||
s->opt[OPT_TRANS].name = "transparency";
|
||||
s->opt[OPT_TRANS].title = "transparency";
|
||||
s->opt[OPT_TRANS].desc = "Switch transparency mode on.";
|
||||
s->opt[OPT_TRANS].title = "Enable transparency adapter";
|
||||
s->opt[OPT_TRANS].desc = "Switch transparency mode on. Which mainly switches the scanner " \
|
||||
"lamp off. (Hint: This can also be used to switch the scanner lamp off when you don't " \
|
||||
"use the scanner in the next time. Simply enable this option and do a preview.)";
|
||||
s->opt[OPT_TRANS].type = SANE_TYPE_BOOL;
|
||||
s->opt[OPT_TRANS].unit = SANE_UNIT_NONE;
|
||||
s->val[OPT_TRANS].w = SANE_FALSE;
|
||||
|
@ -1001,9 +1160,7 @@ init_options (Avision_Scanner *s)
|
|||
/* brightness */
|
||||
s->opt[OPT_BRIGHTNESS].name = SANE_NAME_BRIGHTNESS;
|
||||
s->opt[OPT_BRIGHTNESS].title = SANE_TITLE_BRIGHTNESS;
|
||||
s->opt[OPT_BRIGHTNESS].desc = SANE_DESC_BRIGHTNESS
|
||||
" This option is active for lineart/halftone modes only. "
|
||||
"For multibit modes (grey/color) use the gamma-table(s).";
|
||||
s->opt[OPT_BRIGHTNESS].desc = SANE_DESC_BRIGHTNESS;
|
||||
s->opt[OPT_BRIGHTNESS].type = SANE_TYPE_FIXED;
|
||||
s->opt[OPT_BRIGHTNESS].unit = SANE_UNIT_PERCENT;
|
||||
s->opt[OPT_BRIGHTNESS].constraint_type = SANE_CONSTRAINT_RANGE;
|
||||
|
@ -1013,9 +1170,7 @@ init_options (Avision_Scanner *s)
|
|||
/* contrast */
|
||||
s->opt[OPT_CONTRAST].name = SANE_NAME_CONTRAST;
|
||||
s->opt[OPT_CONTRAST].title = SANE_TITLE_CONTRAST;
|
||||
s->opt[OPT_CONTRAST].desc = SANE_DESC_CONTRAST
|
||||
" This option is active for lineart/halftone modes only. "
|
||||
"For multibit modes (grey/color) use the gamma-table(s).";
|
||||
s->opt[OPT_CONTRAST].desc = SANE_DESC_CONTRAST;
|
||||
s->opt[OPT_CONTRAST].type = SANE_TYPE_FIXED;
|
||||
s->opt[OPT_CONTRAST].unit = SANE_UNIT_PERCENT;
|
||||
s->opt[OPT_CONTRAST].constraint_type = SANE_CONSTRAINT_RANGE;
|
||||
|
@ -1034,8 +1189,8 @@ init_options (Avision_Scanner *s)
|
|||
s->val[OPT_THRESHOLD].w = SANE_FIX(50);
|
||||
|
||||
/* Quality Scan */
|
||||
s->opt[OPT_QSCAN].name = "Qualitiy Scan";
|
||||
s->opt[OPT_QSCAN].title = "Quality Scan";
|
||||
s->opt[OPT_QSCAN].name = "quality-scan";
|
||||
s->opt[OPT_QSCAN].title = "Quality scan";
|
||||
s->opt[OPT_QSCAN].desc = "Turn on quality scanning (slower & better)";
|
||||
s->opt[OPT_QSCAN].type = SANE_TYPE_BOOL;
|
||||
s->opt[OPT_QSCAN].unit = SANE_UNIT_NONE;
|
||||
|
@ -1049,21 +1204,22 @@ init_options (Avision_Scanner *s)
|
|||
s->opt[OPT_QCALIB].unit = SANE_UNIT_NONE;
|
||||
s->val[OPT_QCALIB].w = SANE_TRUE;
|
||||
|
||||
#if 0
|
||||
/* custom-gamma table */
|
||||
s->opt[OPT_CUSTOM_GAMMA].name = SANE_NAME_CUSTOM_GAMMA;
|
||||
s->opt[OPT_CUSTOM_GAMMA].title = SANE_TITLE_CUSTOM_GAMMA;
|
||||
s->opt[OPT_CUSTOM_GAMMA].desc = SANE_DESC_CUSTOM_GAMMA;
|
||||
s->opt[OPT_CUSTOM_GAMMA].desc = SANE_DESC_CUSTOM_GAMMA " (Hint: When this option is " \
|
||||
"disabled NO gamma-table will be send at all. The scanner will use the build in " \
|
||||
" gamma-table or (if it got one already) use the last gamma-table it got.";
|
||||
s->opt[OPT_CUSTOM_GAMMA].type = SANE_TYPE_BOOL;
|
||||
s->opt[OPT_CUSTOM_GAMMA].cap |= SANE_CAP_INACTIVE;
|
||||
s->val[OPT_CUSTOM_GAMMA].w = SANE_FALSE;
|
||||
/* s->opt[OPT_CUSTOM_GAMMA].cap |= SANE_CAP_INACTIVE; */
|
||||
s->val[OPT_CUSTOM_GAMMA].w = SANE_TRUE;
|
||||
|
||||
/* grayscale gamma vector */
|
||||
s->opt[OPT_GAMMA_VECTOR].name = SANE_NAME_GAMMA_VECTOR;
|
||||
s->opt[OPT_GAMMA_VECTOR].title = SANE_TITLE_GAMMA_VECTOR;
|
||||
s->opt[OPT_GAMMA_VECTOR].desc = SANE_DESC_GAMMA_VECTOR;
|
||||
s->opt[OPT_GAMMA_VECTOR].type = SANE_TYPE_INT;
|
||||
s->opt[OPT_GAMMA_VECTOR].cap |= SANE_CAP_INACTIVE;
|
||||
/* s->opt[OPT_GAMMA_VECTOR].cap |= SANE_CAP_INACTIVE; */
|
||||
s->opt[OPT_GAMMA_VECTOR].unit = SANE_UNIT_NONE;
|
||||
s->opt[OPT_GAMMA_VECTOR].size = 256 * sizeof (SANE_Word);
|
||||
s->opt[OPT_GAMMA_VECTOR].constraint_type = SANE_CONSTRAINT_RANGE;
|
||||
|
@ -1075,7 +1231,7 @@ init_options (Avision_Scanner *s)
|
|||
s->opt[OPT_GAMMA_VECTOR_R].title = SANE_TITLE_GAMMA_VECTOR_R;
|
||||
s->opt[OPT_GAMMA_VECTOR_R].desc = SANE_DESC_GAMMA_VECTOR_R;
|
||||
s->opt[OPT_GAMMA_VECTOR_R].type = SANE_TYPE_INT;
|
||||
s->opt[OPT_GAMMA_VECTOR_R].cap |= SANE_CAP_INACTIVE;
|
||||
/* s->opt[OPT_GAMMA_VECTOR_R].cap |= SANE_CAP_INACTIVE; */
|
||||
s->opt[OPT_GAMMA_VECTOR_R].unit = SANE_UNIT_NONE;
|
||||
s->opt[OPT_GAMMA_VECTOR_R].size = 256 * sizeof (SANE_Word);
|
||||
s->opt[OPT_GAMMA_VECTOR_R].constraint_type = SANE_CONSTRAINT_RANGE;
|
||||
|
@ -1087,7 +1243,7 @@ init_options (Avision_Scanner *s)
|
|||
s->opt[OPT_GAMMA_VECTOR_G].title = SANE_TITLE_GAMMA_VECTOR_G;
|
||||
s->opt[OPT_GAMMA_VECTOR_G].desc = SANE_DESC_GAMMA_VECTOR_G;
|
||||
s->opt[OPT_GAMMA_VECTOR_G].type = SANE_TYPE_INT;
|
||||
s->opt[OPT_GAMMA_VECTOR_G].cap |= SANE_CAP_INACTIVE;
|
||||
/* s->opt[OPT_GAMMA_VECTOR_G].cap |= SANE_CAP_INACTIVE; */
|
||||
s->opt[OPT_GAMMA_VECTOR_G].unit = SANE_UNIT_NONE;
|
||||
s->opt[OPT_GAMMA_VECTOR_G].size = 256 * sizeof (SANE_Word);
|
||||
s->opt[OPT_GAMMA_VECTOR_G].constraint_type = SANE_CONSTRAINT_RANGE;
|
||||
|
@ -1099,13 +1255,12 @@ init_options (Avision_Scanner *s)
|
|||
s->opt[OPT_GAMMA_VECTOR_B].title = SANE_TITLE_GAMMA_VECTOR_B;
|
||||
s->opt[OPT_GAMMA_VECTOR_B].desc = SANE_DESC_GAMMA_VECTOR_B;
|
||||
s->opt[OPT_GAMMA_VECTOR_B].type = SANE_TYPE_INT;
|
||||
s->opt[OPT_GAMMA_VECTOR_B].cap |= SANE_CAP_INACTIVE;
|
||||
/* s->opt[OPT_GAMMA_VECTOR_B].cap |= SANE_CAP_INACTIVE; */
|
||||
s->opt[OPT_GAMMA_VECTOR_B].unit = SANE_UNIT_NONE;
|
||||
s->opt[OPT_GAMMA_VECTOR_B].size = 256 * sizeof (SANE_Word);
|
||||
s->opt[OPT_GAMMA_VECTOR_B].constraint_type = SANE_CONSTRAINT_RANGE;
|
||||
s->opt[OPT_GAMMA_VECTOR_B].constraint.range = &u8_range;
|
||||
s->val[OPT_GAMMA_VECTOR_B].wa = &s->gamma_table[3][0];
|
||||
#endif
|
||||
|
||||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
|
@ -1224,7 +1379,7 @@ sane_init (SANE_Int *version_code, SANE_Auth_Callback authorize)
|
|||
DBG_INIT();
|
||||
|
||||
if (version_code)
|
||||
*version_code = SANE_VERSION_CODE (V_MAJOR, V_MINOR, 0);
|
||||
*version_code = SANE_VERSION_CODE (V_MAJOR, V_MINOR, BACKEND_BUILD);
|
||||
|
||||
fp = sanei_config_open (AVISION_CONFIG_FILE);
|
||||
if (!fp) {
|
||||
|
@ -1323,7 +1478,7 @@ sane_open (SANE_String_Const devicename, SANE_Handle *handle)
|
|||
s = malloc (sizeof (*s));
|
||||
if (!s)
|
||||
return SANE_STATUS_NO_MEM;
|
||||
memset (s, 0, sizeof (*s));
|
||||
memset (s, 0x0, sizeof (*s));
|
||||
s->fd = -1;
|
||||
s->pipe = -1;
|
||||
s->hw = dev;
|
||||
|
@ -1413,8 +1568,10 @@ sane_control_option (SANE_Handle handle, SANE_Int option,
|
|||
if (!SANE_OPTION_IS_ACTIVE (cap))
|
||||
return SANE_STATUS_INVAL;
|
||||
|
||||
if (action == SANE_ACTION_GET_VALUE) {
|
||||
switch (option) {
|
||||
if (action == SANE_ACTION_GET_VALUE)
|
||||
{
|
||||
switch (option)
|
||||
{
|
||||
/* word options: */
|
||||
case OPT_PREVIEW:
|
||||
|
||||
|
@ -1432,13 +1589,12 @@ sane_control_option (SANE_Handle handle, SANE_Int option,
|
|||
case OPT_QSCAN:
|
||||
case OPT_QCALIB:
|
||||
case OPT_TRANS:
|
||||
#if 0
|
||||
|
||||
case OPT_CUSTOM_GAMMA:
|
||||
#endif
|
||||
|
||||
*(SANE_Word*) val = s->val[option].w;
|
||||
return SANE_STATUS_GOOD;
|
||||
|
||||
#if 0
|
||||
/* word-array options: */
|
||||
case OPT_GAMMA_VECTOR:
|
||||
case OPT_GAMMA_VECTOR_R:
|
||||
|
@ -1446,14 +1602,15 @@ sane_control_option (SANE_Handle handle, SANE_Int option,
|
|||
case OPT_GAMMA_VECTOR_B:
|
||||
memcpy (val, s->val[option].wa, s->opt[option].size);
|
||||
return SANE_STATUS_GOOD;
|
||||
#endif
|
||||
|
||||
/* string options: */
|
||||
case OPT_MODE:
|
||||
strcpy (val, s->val[option].s);
|
||||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
} else if (action == SANE_ACTION_SET_VALUE) {
|
||||
}
|
||||
else if (action == SANE_ACTION_SET_VALUE)
|
||||
{
|
||||
if (!SANE_OPTION_IS_SETTABLE (cap))
|
||||
return SANE_STATUS_INVAL;
|
||||
|
||||
|
@ -1485,7 +1642,6 @@ sane_control_option (SANE_Handle handle, SANE_Int option,
|
|||
s->val[option].w = *(SANE_Word*) val;
|
||||
return SANE_STATUS_GOOD;
|
||||
|
||||
#if 0
|
||||
/* side-effect-free word-array options: */
|
||||
case OPT_GAMMA_VECTOR:
|
||||
case OPT_GAMMA_VECTOR_R:
|
||||
|
@ -1497,23 +1653,25 @@ sane_control_option (SANE_Handle handle, SANE_Int option,
|
|||
/* options with side-effects: */
|
||||
|
||||
case OPT_CUSTOM_GAMMA:
|
||||
w = *(SANE_Word *) val;
|
||||
if (w == s->val[OPT_CUSTOM_GAMMA].w)
|
||||
return SANE_STATUS_GOOD; /* no change */
|
||||
|
||||
s->val[OPT_CUSTOM_GAMMA].w = w;
|
||||
if (w) {
|
||||
s->val[option].w = *(SANE_Word*) val;
|
||||
if (*(SANE_Word*) val)
|
||||
{
|
||||
s->mode = make_mode (s->val[OPT_MODE].s);
|
||||
|
||||
if (s->mode == GREYSCALE) {
|
||||
if (s->mode == GREYSCALE)
|
||||
{
|
||||
s->opt[OPT_GAMMA_VECTOR].cap &= ~SANE_CAP_INACTIVE;
|
||||
} else if (s->mode == TRUECOLOR) {
|
||||
}
|
||||
else if (s->mode == TRUECOLOR)
|
||||
{
|
||||
s->opt[OPT_GAMMA_VECTOR].cap &= ~SANE_CAP_INACTIVE;
|
||||
s->opt[OPT_GAMMA_VECTOR_R].cap &= ~SANE_CAP_INACTIVE;
|
||||
s->opt[OPT_GAMMA_VECTOR_G].cap &= ~SANE_CAP_INACTIVE;
|
||||
s->opt[OPT_GAMMA_VECTOR_B].cap &= ~SANE_CAP_INACTIVE;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
s->opt[OPT_GAMMA_VECTOR].cap |= SANE_CAP_INACTIVE;
|
||||
s->opt[OPT_GAMMA_VECTOR_R].cap |= SANE_CAP_INACTIVE;
|
||||
s->opt[OPT_GAMMA_VECTOR_G].cap |= SANE_CAP_INACTIVE;
|
||||
|
@ -1522,7 +1680,7 @@ sane_control_option (SANE_Handle handle, SANE_Int option,
|
|||
if (info)
|
||||
*info |= SANE_INFO_RELOAD_OPTIONS;
|
||||
return SANE_STATUS_GOOD;
|
||||
#endif
|
||||
|
||||
|
||||
case OPT_MODE:
|
||||
{
|
||||
|
@ -1538,14 +1696,12 @@ sane_control_option (SANE_Handle handle, SANE_Int option,
|
|||
s->opt[OPT_BRIGHTNESS].cap |= SANE_CAP_INACTIVE;
|
||||
s->opt[OPT_CONTRAST].cap |= SANE_CAP_INACTIVE;
|
||||
s->opt[OPT_THRESHOLD].cap |= SANE_CAP_INACTIVE;
|
||||
#if 0
|
||||
|
||||
s->opt[OPT_CUSTOM_GAMMA].cap |= SANE_CAP_INACTIVE;
|
||||
s->opt[OPT_GAMMA_VECTOR].cap |= SANE_CAP_INACTIVE;
|
||||
s->opt[OPT_GAMMA_VECTOR_R].cap |= SANE_CAP_INACTIVE;
|
||||
s->opt[OPT_GAMMA_VECTOR_G].cap |= SANE_CAP_INACTIVE;
|
||||
s->opt[OPT_GAMMA_VECTOR_B].cap |= SANE_CAP_INACTIVE;
|
||||
#endif
|
||||
|
||||
|
||||
if (strcmp (val, "Thresholded") == 0)
|
||||
s->opt[OPT_THRESHOLD].cap &= ~SANE_CAP_INACTIVE;
|
||||
|
@ -1553,8 +1709,8 @@ sane_control_option (SANE_Handle handle, SANE_Int option,
|
|||
s->opt[OPT_BRIGHTNESS].cap &= ~SANE_CAP_INACTIVE;
|
||||
s->opt[OPT_CONTRAST].cap &= ~SANE_CAP_INACTIVE;
|
||||
}
|
||||
#if 0
|
||||
if (!binary)
|
||||
|
||||
/* if (!binary) */
|
||||
s->opt[OPT_CUSTOM_GAMMA].cap &= ~SANE_CAP_INACTIVE;
|
||||
|
||||
if (s->val[OPT_CUSTOM_GAMMA].w) {
|
||||
|
@ -1567,7 +1723,7 @@ sane_control_option (SANE_Handle handle, SANE_Int option,
|
|||
s->opt[OPT_GAMMA_VECTOR_B].cap &= ~SANE_CAP_INACTIVE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
}
|
||||
|
@ -1618,7 +1774,7 @@ sane_get_parameters (SANE_Handle handle, SANE_Parameters *params)
|
|||
s->params.pixels_per_line = s->avdimen.pixelnum;
|
||||
s->params.lines = s->avdimen.linenum;
|
||||
|
||||
memset (&s->params, 0, sizeof (s->params));
|
||||
memset (&s->params, 0x0, sizeof (s->params));
|
||||
|
||||
if (s->avdimen.res > 0 && s->avdimen.wid > 0 && s->avdimen.len > 0)
|
||||
{
|
||||
|
@ -1688,7 +1844,6 @@ sane_start (SANE_Handle handle)
|
|||
SANE_Status status;
|
||||
int fds [2];
|
||||
|
||||
|
||||
DBG (3, "sane_start\n");
|
||||
|
||||
/* Fisrt make sure there is no scan running!!! */
|
||||
|
@ -1735,7 +1890,8 @@ sane_start (SANE_Handle handle)
|
|||
goto stop_scanner_and_return;
|
||||
}
|
||||
|
||||
status = scan_area_and_windows (s);
|
||||
|
||||
status = set_window (s);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
DBG (1, "open: set scan area command failed: %s\n",
|
||||
|
@ -1743,6 +1899,14 @@ sane_start (SANE_Handle handle)
|
|||
goto stop_scanner_and_return;
|
||||
}
|
||||
|
||||
status = set_gamma (s);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
DBG (1, "open: set gamma failed: %s\n",
|
||||
sane_strstatus (status));
|
||||
goto stop_scanner_and_return;
|
||||
}
|
||||
|
||||
s->scanning = SANE_TRUE;
|
||||
|
||||
status = start_scan (s);
|
||||
|
@ -1770,7 +1934,7 @@ sane_start (SANE_Handle handle)
|
|||
sigdelset (&ignore_set, SIGTERM);
|
||||
sigprocmask (SIG_SETMASK, &ignore_set, 0);
|
||||
|
||||
memset (&act, 0, sizeof (act));
|
||||
memset (&act, 0x0, sizeof (act));
|
||||
sigaction (SIGTERM, &act, 0);
|
||||
|
||||
/* don't use exit() since that would run the atexit() handlers... */
|
||||
|
|
|
@ -41,14 +41,14 @@
|
|||
|
||||
*****************************************************************************
|
||||
|
||||
This file implements a SANE backend for the Avision AV 630CS scanner with
|
||||
SCSI-2 command set.
|
||||
This file implements a SANE backend for the Avision AV 630CS (and other ...)
|
||||
scanner with SCSI-2 command set.
|
||||
|
||||
(feedback to: mccramer@s.netic.de and rene.rebe@myokay.net)
|
||||
|
||||
Very much thanks to:
|
||||
Avision INC for the documentation we got! ;-)
|
||||
Gunter Wagner for some fixes and the transparency option
|
||||
Gunter Wagner for some fixes and the transparency option.
|
||||
|
||||
*****************************************************************************/
|
||||
|
||||
|
@ -57,10 +57,9 @@
|
|||
|
||||
#include <sys/types.h>
|
||||
|
||||
|
||||
enum Avision_Option
|
||||
{
|
||||
OPT_NUM_OPTS = 0,
|
||||
OPT_NUM_OPTS = 0, /* must come first */
|
||||
|
||||
OPT_MODE_GROUP,
|
||||
OPT_MODE,
|
||||
|
@ -83,21 +82,15 @@ enum Avision_Option
|
|||
OPT_QSCAN,
|
||||
OPT_QCALIB,
|
||||
OPT_TRANS, /* Transparency Mode */
|
||||
#if 0
|
||||
|
||||
OPT_CUSTOM_GAMMA, /* use custom gamma tables? */
|
||||
/* The gamma vectors MUST appear in the order gray, red, green,
|
||||
blue. */
|
||||
OPT_GAMMA_VECTOR,
|
||||
OPT_GAMMA_VECTOR_R,
|
||||
|
||||
OPT_GAMMA_VECTOR, /* first must be grey */
|
||||
OPT_GAMMA_VECTOR_R, /* then r g b vector */
|
||||
OPT_GAMMA_VECTOR_G,
|
||||
OPT_GAMMA_VECTOR_B,
|
||||
|
||||
OPT_HALFTONE_DIMENSION,
|
||||
OPT_HALFTONE_PATTERN,
|
||||
#endif
|
||||
|
||||
/* must come last: */
|
||||
NUM_OPTIONS
|
||||
NUM_OPTIONS /* must come last */
|
||||
};
|
||||
|
||||
|
||||
|
@ -108,7 +101,7 @@ typedef union
|
|||
SANE_String s;
|
||||
} Option_Value;
|
||||
|
||||
typedef struct Avision_Dimensions
|
||||
typedef struct
|
||||
{
|
||||
long tlx;
|
||||
long tly;
|
||||
|
@ -123,7 +116,7 @@ typedef struct Avision_Dimensions
|
|||
int res;
|
||||
} Avision_Dimensions;
|
||||
|
||||
typedef struct Avision_Device
|
||||
typedef struct
|
||||
{
|
||||
struct Avision_Device* next;
|
||||
SANE_Device sane;
|
||||
|
@ -134,7 +127,7 @@ typedef struct Avision_Device
|
|||
unsigned flags;
|
||||
} Avision_Device;
|
||||
|
||||
typedef struct Avision_Scanner
|
||||
typedef struct
|
||||
{
|
||||
/* all the state needed to define a scan request: */
|
||||
struct Avision_Scanner *next;
|
||||
|
@ -265,19 +258,69 @@ typedef struct Avision_Scanner
|
|||
#define AVISION_SCSI_INQUIRY 0x12
|
||||
#define AVISION_SCSI_MODE_SELECT 0x15
|
||||
#define AVISION_SCSI_START_STOP 0x1b
|
||||
#define AVISION_SCSI_AREA_AND_WINDOWS 0x24
|
||||
#define AVISION_SCSI_READ_SCANNED_DATA 0x28
|
||||
#define AVISION_SCSI_SET_WINDOWS 0x24
|
||||
#define AVISION_SCSI_READ 0x28
|
||||
#define AVISION_SCSI_SEND 0x2a
|
||||
#define AVISION_SCSI_GET_DATA_STATUS 0x34
|
||||
|
||||
/* The structures that you have to send to the avision to get it to
|
||||
/* The structures that you have to send to an avision to get it to
|
||||
do various stuff... */
|
||||
|
||||
struct win_desc_header {
|
||||
unsigned char pad0[6];
|
||||
unsigned char wpll[2];
|
||||
struct command_header
|
||||
{
|
||||
unsigned char opc;
|
||||
unsigned char pad0 [3];
|
||||
unsigned char len;
|
||||
unsigned char pad1;
|
||||
};
|
||||
|
||||
struct win_desc_block {
|
||||
struct command_set_window
|
||||
{
|
||||
unsigned char opc;
|
||||
unsigned char reserved0 [5];
|
||||
unsigned char transferlen [3];
|
||||
unsigned char control;
|
||||
};
|
||||
|
||||
struct command_read
|
||||
{
|
||||
unsigned char opc;
|
||||
unsigned char bitset1;
|
||||
unsigned char datatypecode;
|
||||
unsigned char calibchn;
|
||||
unsigned char datatypequal [2];
|
||||
unsigned char transferlen [3];
|
||||
unsigned char control;
|
||||
};
|
||||
|
||||
struct command_scan
|
||||
{
|
||||
unsigned char opc;
|
||||
unsigned char pad0 [3];
|
||||
unsigned char transferlen;
|
||||
unsigned char bitset1;
|
||||
};
|
||||
|
||||
struct command_send
|
||||
{
|
||||
unsigned char opc;
|
||||
unsigned char bitset1;
|
||||
unsigned char datatypecode;
|
||||
unsigned char reserved0;
|
||||
unsigned char datatypequal [2];
|
||||
unsigned char transferlen [3];
|
||||
unsigned char reserved1;
|
||||
};
|
||||
|
||||
|
||||
struct command_set_window_window_header
|
||||
{
|
||||
unsigned char reserved0 [6];
|
||||
unsigned char desclen [2];
|
||||
};
|
||||
|
||||
struct command_set_window_window_descriptor
|
||||
{
|
||||
unsigned char winid;
|
||||
unsigned char pad0;
|
||||
unsigned char xres [2];
|
||||
|
@ -311,53 +354,17 @@ struct win_desc_block {
|
|||
unsigned char g_exposure_time [2];
|
||||
unsigned char b_exposure_time [2];
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
struct command_header {
|
||||
unsigned char opc;
|
||||
unsigned char pad0[3];
|
||||
unsigned char len;
|
||||
unsigned char pad1;
|
||||
};
|
||||
|
||||
struct command_header_10 {
|
||||
unsigned char opc;
|
||||
unsigned char pad0[5];
|
||||
unsigned char len[3];
|
||||
unsigned char pad1;
|
||||
};
|
||||
|
||||
struct command_read {
|
||||
unsigned char opc;
|
||||
unsigned char bitset1;
|
||||
unsigned char datatypecode;
|
||||
unsigned char calibchn;
|
||||
unsigned char datatypequal[2];
|
||||
unsigned char transferlen[3];
|
||||
unsigned char pad0;
|
||||
};
|
||||
|
||||
struct command_scan {
|
||||
unsigned char opc;
|
||||
unsigned char pad0[3];
|
||||
unsigned char transferlen;
|
||||
unsigned char bitset1;
|
||||
};
|
||||
|
||||
struct def_win_par {
|
||||
struct command_header_10 dwph;
|
||||
struct win_desc_header wdh;
|
||||
struct win_desc_block wdb;
|
||||
};
|
||||
|
||||
struct page_header{
|
||||
struct page_header
|
||||
{
|
||||
char pad0 [4];
|
||||
char code;
|
||||
char length;
|
||||
};
|
||||
|
||||
struct avision_page {
|
||||
struct avision_page
|
||||
{
|
||||
char gamma;
|
||||
char thresh;
|
||||
char masks;
|
||||
|
|
Ładowanie…
Reference in New Issue