Commited the latest avision backend.

DEVEL_2_0_BRANCH-1
Rene Rebe 2002-08-30 09:21:51 +00:00
rodzic ecfaa7df88
commit c67286adee
5 zmienionych plików z 442 dodań i 257 usunięć

Wyświetl plik

@ -66,12 +66,43 @@
Avision INC for the documentation we got! ;-)
ChangeLog:
2002-06-03/04: René Rebe
* maybe fixed the backend for HP 5370 scanners
* fixed some typos - debug output
2002-08-25: René Rebe
* added "AV620CS Plus" ID and fixed typo in the .conf file
2002-08-14: René Rebe
* implemented ADF support
* reworked "go_home" and some indenting
2002-07-12: René Rebe
* implemented accessories detection
* code cleanups
2002-07-07: René Rebe
* manpage and .desc update
2002-06-30: René Rebe
* limited calibration only if specified in config file
* more readable calibration decision (using goto ...)
2002-06-24: René Rebe
* fixed some comment typos
* fixed the image size calculation
* fixed gamma_table computation
2002-06-14: René Rebe
* better debug priority in the reader
* fixed gamma-table
* suppressed
2002-06-04: René Rebe
* fixed possible memory-leak for error situations
* fixed some compiler warnings
* introduced new gamma-table send variant
* introduced calibration on first scan only
2002-06-03: René Rebe
* maybe fixed the backend for HP 5370 scanners
* fixed some typos - debug output
2002-05-27: René Rebe
* marked HP 5370 to be calib v2 and improved the .conf file
@ -242,7 +273,7 @@
#endif
#define BACKEND_NAME avision
#define BACKEND_BUILD 32 /* avision backend BUILD version */
#define BACKEND_BUILD 37 /* avision backend BUILD version */
static Avision_HWEntry Avision_Device_List [] =
{
@ -288,6 +319,10 @@ static Avision_HWEntry Avision_Device_List [] =
"Avision", "AV620CS",
AV_SCSI, AV_FLATBED, 0},
{ "AVISION", "AV620CS Plus",
"Avision", "AV620CS Plus",
AV_SCSI, AV_FLATBED, 0},
{ "AVISION", "AV630CS",
"Avision", "AV630CS",
AV_SCSI, AV_FLATBED , 0},
@ -346,6 +381,7 @@ static Avision_HWEntry Avision_Device_List [] =
"Hewlett-Packard", "ScanJet 5370C",
AV_USB, AV_FLATBED, AV_CALIB2 | AV_GAMMA3},
/* The HP 7450c seems to use the same ID */
{ "hp", "scanjet 7400c",
"Hewlett-Packard", "ScanJet 7400c",
AV_USB, AV_FLATBED, AV_CALIB2 | AV_GAMMA2},
@ -354,10 +390,13 @@ static Avision_HWEntry Avision_Device_List [] =
/*{"UMAX", "Astra 4500", AV_USB, AV_FLATBED, 0},
{"UMAX", "Astra 6700", AV_USB, AV_FLATBED, 0}, */
/* Minolta Dimage Scan Dual II */
{ "MINOLTA", "FS-V1",
"Minolta", "FS-V1",
AV_USB, AV_FILM, 0},
/* Minolta Scan Elite II - might be basically a Dual II + IR scan */
/* possibly all Minolta film-scanners ? */
/* Only the SS600 is tested ... */
@ -445,9 +484,14 @@ static Avision_Device* first_dev;
static Avision_Scanner* first_handle;
static const SANE_Device** devlist = 0;
static SANE_Bool disable_gamma_table = SANE_FALSE; /* disable the usage of a custom gamma-table */
static SANE_Bool disable_calibration = SANE_FALSE; /* disable the calibration */
static SANE_Bool force_a4 = SANE_FALSE; /* force scanable areas to ISO(DIN) A4 */
/* disable the usage of a custom gamma-table */
static SANE_Bool disable_gamma_table = SANE_FALSE;
/* disable the calibration */
static SANE_Bool disable_calibration = SANE_FALSE;
/* do only one claibration per backend initialization */
static SANE_Bool one_calib_only = SANE_FALSE;
/* force scanable areas to ISO(DIN) A4 */
static SANE_Bool force_a4 = SANE_FALSE;
static const SANE_String_Const mode_list[] =
{
@ -499,6 +543,20 @@ static const u_int8_t get_status[] =
0x00, 0x00, 0x0c, 0x00
};
static void debug_output_raw (int dbg_level, u_int8_t* data, size_t count)
{
size_t i;
DBG (dbg_level, "RAW-Data:\n");
for (i = 0; i < count; ++ i) {
DBG (6, " [%d] %1d%1d%1d%1d%1d%1d%1d%1db %3oo %3dd %2xx\n",
i,
BIT(data[i],7), BIT(data[i],6), BIT(data[i],5), BIT(data[i],4),
BIT(data[i],3), BIT(data[i],2), BIT(data[i],1), BIT(data[i],0),
data[i], data[i], data[i]);
}
}
static int make_mode (char* mode)
{
DBG (3, "make_mode\n");
@ -872,7 +930,7 @@ max_string_size (const SANE_String_Const strings[])
DBG (3, "max_string_size\n");
for (i = 0; strings[i]; ++i)
for (i = 0; strings[i]; ++ i)
{
size = strlen (strings[i]) + 1;
if (size > max_size)
@ -889,6 +947,45 @@ constrain_value (Avision_Scanner *s, SANE_Int option, void *value,
return sanei_constrain_value (s->opt + option, value, info);
}
static SANE_Status
get_accessories_info (int fd, SANE_Bool *adf, SANE_Bool *light_box)
{
/* read stuff */
struct command_read rcmd;
size_t size;
SANE_Status status;
u_int8_t result[8];
DBG (3, "get_accessories_info\n");
size = sizeof (result);
memset (&rcmd, 0, sizeof (rcmd));
rcmd.opc = AVISION_SCSI_READ;
rcmd.datatypecode = 0x64; /* detect accessories */
rcmd.datatypequal [0] = 0x0d;
rcmd.datatypequal [1] = 0x0a;
set_triple (rcmd.transferlen, size);
status = sanei_scsi_cmd (fd, &rcmd, sizeof (rcmd), result, &size);
if (status != SANE_STATUS_GOOD || size != sizeof (result)) {
DBG (1, "get_accessories_info: read failed (%s)\n",
sane_strstatus (status));
return (status);
}
debug_output_raw (6, result, size);
DBG (3, "get_accessories_info: [0] ADF: %x\n", result [0]);
DBG (3, "get_accessories_info: [1] Light Box: %x\n", result [1]);
*adf = result [0];
*light_box = result [1];
return SANE_STATUS_GOOD;
}
static SANE_Status
get_frame_info (int fd, int *number_of_frames, int *frame, int *holder_type)
{
@ -897,7 +994,7 @@ get_frame_info (int fd, int *number_of_frames, int *frame, int *holder_type)
size_t size;
SANE_Status status;
u_int8_t result[8];
unsigned int i;
size_t i;
frame = frame; /* silence gcc */
@ -919,14 +1016,7 @@ get_frame_info (int fd, int *number_of_frames, int *frame, int *holder_type)
return (status);
}
DBG (6, "RAW-Data:\n");
for (i = 0; i < size; ++ i) {
DBG (6, "get_frame_info: result [%2d] %1d%1d%1d%1d%1d%1d%1d%1db %3oo %3dd %2xx\n",
i,
BIT(result[i],7), BIT(result[i],6), BIT(result[i],5), BIT(result[i],4),
BIT(result[i],3), BIT(result[i],2), BIT(result[i],1), BIT(result[i],0),
result[i], result[i], result[i]);
}
debug_output_raw (6, result, size);
DBG (3, "get_frame_info: [0] Holder type: %s\n",
(result[0]==1)?"APS":
@ -1107,7 +1197,7 @@ attach (const char* devname, Avision_Device** devp)
DBG (1, "FOUND\n");
break;
}
++model_num;
++ model_num;
}
if (!found) {
@ -1133,13 +1223,9 @@ attach (const char* devname, Avision_Device** devp)
dev->sane.vendor = dev->hw->real_mfg;
dev->sane.model = dev->hw->real_model;
DBG (6, "RAW-Data:\n");
for (i=0; i<sizeof(result); i++) {
DBG (6, "result [%2d] %1d%1d%1d%1d%1d%1d%1d%1db %3oo %3dd %2xx\n", i,
BIT(result[i],7), BIT(result[i],6), BIT(result[i],5), BIT(result[i],4),
BIT(result[i],3), BIT(result[i],2), BIT(result[i],1), BIT(result[i],0),
result[i], result[i], result[i]);
}
dev->is_calibrated = SANE_FALSE;
debug_output_raw (6, result, sizeof (result) );
DBG (3, "attach: [8-15] Vendor id.: \"%8.8s\"\n", result+8);
DBG (3, "attach: [16-31] Product id.: \"%16.16s\"\n", result+16);
@ -1253,28 +1339,38 @@ attach (const char* devname, Avision_Device** devp)
/* if (BIT(result[62],3) ) { */ /* most scanners report film functionallity ... */
switch(dev->hw->scanner_type) {
case AV_FLATBED:
dev->sane.type = "flatbed scanner";
break;
dev->sane.type = "flatbed scanner";
break;
case AV_FILM:
dev->sane.type = "film scanner";
break;
dev->sane.type = "film scanner";
break;
case AV_SHEETFEED:
dev->sane.type = "sheetfed scanner";
break;
dev->sane.type = "sheetfed scanner";
break;
}
dev->inquiry_new_protocol = BIT (result[39],2);
dev->inquiry_detect_accessories = BIT(result[93],7);
dev->inquiry_needs_calibration = BIT (result[50],4);
dev->inquiry_needs_gamma = BIT (result[50],3);
dev->inquiry_needs_software_colorpack = BIT (result[50],5);
dev->inquiry_color_boundary = result[54];
if (dev->inquiry_color_boundary == 0)
dev->inquiry_color_boundary = 8;
dev->inquiry_color_boundary = 4;
dev->inquiry_grey_boundary = result[55];
if (dev->inquiry_grey_boundary == 0)
dev->inquiry_grey_boundary = 8;
dev->inquiry_grey_boundary = 4;
dev->inquiry_dithered_boundary = result[59];
if (dev->inquiry_dithered_boundary == 0)
dev->inquiry_dithered_boundary = 8;
dev->inquiry_thresholded_boundary = result[57];
if (dev->inquiry_thresholded_boundary == 0)
dev->inquiry_thresholded_boundary = 8;
dev->inquiry_line_difference = result[53];
@ -1376,13 +1472,26 @@ attach (const char* devname, Avision_Device** devp)
DBG (1, "attach: transp_range: %f x %f\n",
dev->inquiry_transp_x_range, dev->inquiry_transp_y_range);
/* Try to retrieve additional accessories information */
if (dev->inquiry_detect_accessories) {
status = get_accessories_info (fd,
&dev->inquiry_adf,
&dev->inquiry_light_box);
if (status != SANE_STATUS_GOOD)
goto close_scanner_and_return;
}
/* For a film scanner try to retrieve additional frame information */
if (dev->hw->scanner_type == AV_FILM) {
get_frame_info (fd, &dev->frame_range.max,
&dev->current_frame,
&dev->holder_type);
status = get_frame_info (fd,
&dev->frame_range.max,
&dev->current_frame,
&dev->holder_type);
dev->frame_range.min = 1;
dev->frame_range.quant = 1;
if (status != SANE_STATUS_GOOD)
goto close_scanner_and_return;
}
status = wait_ready (fd);
@ -1444,12 +1553,7 @@ perform_calibration (Avision_Scanner* s)
return status;
}
DBG (5, "RAW-Data:\n");
for (i = 0; i < size; ++ i) {
DBG (5, "result [%2d] %1d%1d%1d%1d%1d%1d%1d%1db %3oo %3dd %2xx\n", i, BIT(result[i],7),
BIT(result[i],6), BIT(result[i],5), BIT(result[i],4), BIT(result[i],3), BIT(result[i],2),
BIT(result[i],1), BIT(result[i],0), result[i], result[i], result[i]);
}
debug_output_raw (5, result, size);
DBG (3, "calib_info: [0-1] pixels per line %d\n", (result[0]<<8)+result[1]);
DBG (3, "calib_info: [2] bytes per channel %d\n", result[2]);
@ -1552,7 +1656,7 @@ perform_calibration (Avision_Scanner* s)
double avg = 0;
long factor;
for (line = 0; line < lines; ++line) {
for (line = 0; line < lines; ++ line) {
if ( (line * offset) + i >= calib_size)
DBG (3, "perform_calibration: BUG: src out of range!!! %d\n", (line * offset) + i);
else
@ -1561,7 +1665,7 @@ perform_calibration (Avision_Scanner* s)
avg /= lines;
/* we should use some custom per scanner magic here ... */
factor = (255.0 - (avg * 0.8) ) * 255;
factor = 0xffff*(270.452/(1.+4.24955*avg));
if (factor > 0xffff)
factor = 0xffff;
@ -1701,30 +1805,44 @@ set_gamma (Avision_Scanner* s)
Avision_Device* dev = s->hw;
SANE_Status status;
size_t gamma_table_raw_size;
size_t gamma_table_size;
int gamma_values;
size_t gamma_values;
struct command_send scmd;
u_int8_t *gamma_data;
int color; /* current color */
int i; /* big table index */
int j; /* little table index */
int k; /* big table sub index */
size_t i; /* big table index */
size_t j; /* little table index */
size_t k; /* big table sub index */
double v1, v2;
double brightness;
double contrast;
gamma_table_size = 4096;
if (dev->hw->feature_type & AV_GAMMA2)
gamma_table_size = 512;
else if (dev->hw->feature_type & AV_GAMMA3)
gamma_table_size = 256;
/* calculate the gamma table sizes */
if (!dev->inquiry_new_protocol) /* if 11bit (old protocol) table */
{
gamma_table_raw_size = 4096;
gamma_table_size = 2048;
}
else /* new protocol */
{
if (dev->hw->feature_type & AV_GAMMA2)
gamma_table_raw_size = 512;
else if (dev->hw->feature_type & AV_GAMMA3)
gamma_table_raw_size = 256;
else
gamma_table_raw_size = 4096;
gamma_table_size = gamma_table_raw_size;
}
gamma_values = gamma_table_size / 256;
DBG (3, "set_gamma: table_size: %i, value: %i\n", gamma_table_size, gamma_values);
DBG (3, "set_gamma: table_raw_size: %d, table_size: %d, values: %d\n",
gamma_table_raw_size, gamma_table_size, gamma_values);
/* prepare for emulating contrast, brightness ... via the gamma-table */
brightness = SANE_UNFIX (s->val[OPT_BRIGHTNESS].w);
@ -1734,7 +1852,7 @@ set_gamma (Avision_Scanner* s)
DBG (3, "set_gamma: brightness: %f, contrast: %f\n", brightness, contrast);
gamma_data = malloc (gamma_table_size);
gamma_data = malloc (gamma_table_raw_size);
if (!gamma_data)
return SANE_STATUS_NO_MEM;
@ -1742,14 +1860,14 @@ set_gamma (Avision_Scanner* s)
scmd.opc = AVISION_SCSI_SEND;
scmd.datatypecode = 0x81; /* 0x81 for download gama table */
set_triple (scmd.transferlen, gamma_table_size);
set_triple (scmd.transferlen, gamma_table_raw_size);
for (color = 0; color < 3; ++ color)
{
set_double (scmd.datatypequal, color); /* color: 0=red; 1=green; 2=blue */
i = 0; /* big table index */
for (j = 0; j < 256; j++) /* little table index */
for (j = 0; j < 256; ++ j) /* little table index */
{
/* calculate mode dependent values v1 and v2
* v1 <- current value for table
@ -1759,11 +1877,13 @@ set_gamma (Avision_Scanner* s)
{
case TRUECOLOR:
{
v1 = (double) (s->gamma_table [0][j] + s->gamma_table [1 + color][j] ) / 2;
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;
v2 = (double) (s->gamma_table [0][j + 1] +
s->gamma_table [1 + color][j + 1] ) / 2;
}
break;
default:
@ -1777,10 +1897,11 @@ set_gamma (Avision_Scanner* s)
}
} /*end switch */
/* emulate brightness, contrast (at least the Avision AV6[2,3]0 are not able to
* do this in hardware ... --EUR - taken from the GIMP source - I'll optimize
* it when it is known to work (and I have time)
/* emulate brightness, contrast (at least the Avision AV6[2,3]0 are not
* able to do this in hardware ... --EUR - taken from the GIMP source -
* I'll optimize it when it is known to work (and I have time)
*/
v1 /= 255;
v2 /= 255;
@ -1790,22 +1911,23 @@ set_gamma (Avision_Scanner* s)
v1 *= 255;
v2 *= 255;
if (!dev->inquiry_new_protocol) { /* if 11bit (old protocol) table */
for (k = 0; k < 8; k++, i++)
gamma_data [i] = ( ( (u_int8_t)v1 * (8 - k)) + ( (u_int8_t)v2 * k) ) / 8;
}
else {
for (k = 0; k < gamma_values; k++, i++)
gamma_data [i] = ( ( (u_int8_t)v1 * (gamma_values - k)) + ( (u_int8_t)v2 * k) ) / gamma_values;
for (k = 0; k < gamma_values; ++ k, ++ i) {
gamma_data [i] = (u_int8_t)
(((v1 * (gamma_values - k)) + (v2 * k) ) / (double) gamma_values);
}
}
/* fill the gamma table - if 11bit (old protocol) table */
if (!dev->inquiry_new_protocol) {
for (i = 2048; i < 4096; i++)
gamma_data [i] = gamma_data [2047];
/* fill the gamma table - (e.g.) if 11bit (old protocol) table */
{
size_t t_i = i-1;
if (i < gamma_table_raw_size) {
DBG (4, "set_gamma: (old protocol) - filling the rest\n");
for ( ; i < gamma_table_raw_size; ++ i)
gamma_data [i] = gamma_data [t_i];
}
}
status = sanei_scsi_cmd2 (s->fd, &scmd, sizeof (scmd), gamma_data, gamma_table_size, 0, 0);
status = sanei_scsi_cmd2 (s->fd, &scmd, sizeof (scmd),
gamma_data, gamma_table_raw_size, 0, 0);
}
free (gamma_data);
return status;
@ -1814,7 +1936,7 @@ set_gamma (Avision_Scanner* s)
static SANE_Status
set_window (Avision_Scanner* s)
{
Avision_Device* dev = s->hw;
/* Avision_Device* dev = s->hw; */
SANE_Status status;
struct
{
@ -1848,14 +1970,8 @@ set_window (Avision_Scanner* s)
/* width and length in bytes */
set_double (cmd.window_descriptor.linewidth, s->params.bytes_per_line);
if (s->mode == TRUECOLOR && dev->inquiry_needs_software_colorpack) {
set_double (cmd.window_descriptor.linecount,
set_double (cmd.window_descriptor.linecount,
s->params.lines + s->avdimen.line_difference);
}
else {
set_double (cmd.window_descriptor.linecount,
s->params.lines);
}
cmd.window_descriptor.bitset1 = 0x60;
cmd.window_descriptor.bitset1 |= s->val[OPT_SPEED].w;
@ -1864,34 +1980,32 @@ set_window (Avision_Scanner* s)
/* quality scan option switch */
if (s->val[OPT_QSCAN].w == SANE_TRUE) {
cmd.window_descriptor.bitset2 |= AV_QSCAN_ON; /* Q_SCAN ON */
cmd.window_descriptor.bitset2 |= AV_QSCAN_ON;
}
/* quality calibration option switch */
if (s->val[OPT_QCALIB].w == SANE_TRUE) {
cmd.window_descriptor.bitset2 |= AV_QCALIB_ON; /* Q_CALIB ON */
cmd.window_descriptor.bitset2 |= AV_QCALIB_ON;
}
/* transparency switch */
/* transparency option switch */
if (s->val[OPT_TRANS].w == SANE_TRUE) {
cmd.window_descriptor.bitset2 |= AV_TRANS_ON; /* Set to transparency mode */
cmd.window_descriptor.bitset2 |= AV_TRANS_ON;
}
/* fixed value */
/* fixed values */
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 unsupported by all Avision scanner I know ...) */
cmd.window_descriptor.highlight = 0xFF;
cmd.window_descriptor.shadow = 0x00;
/* 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 ...
*/
/* this is normaly unsupported by Avsion scanners, too.
* I clear this only to be sure if another scanner knows about it ...
* we do this via the gamma table - which works for all ... */
cmd.window_descriptor.thresh = 128;
cmd.window_descriptor.brightness = 128;
cmd.window_descriptor.contrast = 128;
@ -1961,7 +2075,7 @@ release_unit (Avision_Scanner *s)
static SANE_Status
check_paper (Avision_Scanner *s)
{
char cmd[] = {0x08, 0, 0, 0, 1, 0};
char cmd[] = {AVISION_SCSI_MEDIA_CHECK, 0, 0, 0, 1, 0};
SANE_Status status;
char buf[1];
size_t size = 1;
@ -1979,15 +2093,17 @@ check_paper (Avision_Scanner *s)
}
static SANE_Status
go_home (Avision_Scanner *s)
object_position (Avision_Scanner *s, u_int8_t position)
{
SANE_Status status;
/* for film scanners! Check adf's as well */
char cmd[] =
{0x31, 0x02, 0, 0, 0, 0, 0, 0, 0, 0}; /* Object position */
u_int8_t cmd [10];
DBG (3, "go_home\n");
memset (cmd, 0, sizeof (cmd));
cmd[0] = AVISION_SCSI_OBJECT_POSITION;
cmd[1] = position;
DBG (3, "object_position: %d\n", position);
status = sanei_scsi_cmd (s->fd, cmd, sizeof(cmd), 0, 0);
return status;
@ -2065,7 +2181,7 @@ do_cancel (Avision_Scanner *s)
/* release the device */
release_unit (s);
/* go_home (s); */
/* object_position (s, AVISION_SCSI_OP_GO_HOME); go_home*/
sanei_scsi_close (s->fd);
s->fd = -1;
@ -2106,7 +2222,7 @@ init_options (Avision_Scanner* s)
memset (s->opt, 0, sizeof (s->opt));
memset (s->val, 0, sizeof (s->val));
for (i = 0; i < NUM_OPTIONS; ++i) {
for (i = 0; i < NUM_OPTIONS; ++ i) {
s->opt[i].size = sizeof (SANE_Word);
s->opt[i].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
}
@ -2450,7 +2566,7 @@ reader_process (Avision_Scanner *s, int fd)
if (processed_bytes + this_read > needed_bytes)
this_read = needed_bytes - processed_bytes;
DBG (5, "this read: %ld\n", (long)this_read);
DBG (7, "this read: %ld\n", (long)this_read);
sigprocmask (SIG_BLOCK, &sigterm_set, 0);
status = read_data (s, stripe_data + bytes_in_stripe, this_read);
@ -2465,7 +2581,7 @@ reader_process (Avision_Scanner *s, int fd)
processed_bytes += this_read;
}
DBG (5, "reader_process: buffer filled\n");
DBG (6, "reader_process: buffer filled\n");
/* perform output convertion */
@ -2473,7 +2589,7 @@ reader_process (Avision_Scanner *s, int fd)
if (s->mode == TRUECOLOR)
usefull_bytes -= s->avdimen.line_difference * bytes_per_line;
DBG (5, "reader_process: usefull_bytes %i\n", usefull_bytes);
DBG (7, "reader_process: usefull_bytes %i\n", usefull_bytes);
if (s->mode == TRUECOLOR) {
if (s->avdimen.line_difference > 0) {
@ -2509,11 +2625,11 @@ reader_process (Avision_Scanner *s, int fd)
memcpy (stripe_data, stripe_data + usefull_bytes, bytes_in_stripe);
s->line += usefull_bytes / bytes_per_line;
DBG (5, "reader_process: end loop\n");
DBG (3, "reader_process: end loop\n");
} /* end while not all lines */
if (dev->inquiry_new_protocol) {
status = go_home(s);
status = object_position (s, AVISION_SCSI_OP_GO_HOME);
if (status != SANE_STATUS_GOOD)
return status;
}
@ -2569,7 +2685,7 @@ sane_init (SANE_Int* version_code, SANE_Auth_Callback authorize)
while (sanei_config_read (line, sizeof (line), fp))
{
word = NULL;
linenumber++;
++ linenumber;
DBG(5, "sane_init: parsing config line \"%s\"\n",
line);
@ -2611,6 +2727,12 @@ sane_init (SANE_Int* version_code, SANE_Auth_Callback authorize)
linenumber);
disable_calibration = SANE_TRUE;
}
if (strcmp (word, "one-calib-only") == 0)
{
DBG(3, "sane_init: config file line %d: one-calib-only\n",
linenumber);
one_calib_only = SANE_TRUE;
}
if (strcmp (word, "force-a4") == 0)
{
DBG(3, "sane_init: config file line %d: enabling force-a4\n",
@ -2711,14 +2833,18 @@ sane_open (SANE_String_Const devicename, SANE_Handle *handle)
s = malloc (sizeof (*s));
if (!s)
return SANE_STATUS_NO_MEM;
/* initialize gamma table */
memset (s, 0, sizeof (*s));
s->fd = -1;
s->pipe = -1;
s->hw = dev;
for (i = 0; i < 4; ++i)
for (j = 0; j < 256; ++j)
for (i = 0; i < 4; ++ i)
for (j = 0; j < 256; ++ j)
s->gamma_table[i][j] = j;
/* the other states (like page, scanning, ...) rely on the
memset (0) above */
init_options (s);
@ -2762,7 +2888,7 @@ sane_close (SANE_Handle handle)
else
first_handle = s->next;
for (i = 1; i < NUM_OPTIONS; i++) {
for (i = 1; i < NUM_OPTIONS; ++ i) {
if (s->opt[i].type == SANE_TYPE_STRING && s->val[i].s) {
free (s->val[i].s);
}
@ -2948,81 +3074,73 @@ sane_get_parameters (SANE_Handle handle, SANE_Parameters* params)
DBG (1, "res: %i\n", s->avdimen.res);
/* the specs say they are specified in inch/1200 ... */
s->avdimen.tlx = (double) 1200 * SANE_UNFIX (s->val[OPT_TL_X].w) / MM_PER_INCH;
s->avdimen.tly = (double) 1200 * SANE_UNFIX (s->val[OPT_TL_Y].w) / MM_PER_INCH;
s->avdimen.brx = (double) 1200 * SANE_UNFIX (s->val[OPT_BR_X].w) / MM_PER_INCH;
s->avdimen.bry = (double) 1200 * SANE_UNFIX (s->val[OPT_BR_Y].w) / MM_PER_INCH;
s->avdimen.tlx = 1200.0 * SANE_UNFIX (s->val[OPT_TL_X].w) / MM_PER_INCH;
s->avdimen.tly = 1200.0 * SANE_UNFIX (s->val[OPT_TL_Y].w) / MM_PER_INCH;
s->avdimen.brx = 1200.0 * SANE_UNFIX (s->val[OPT_BR_X].w) / MM_PER_INCH;
s->avdimen.bry = 1200.0 * SANE_UNFIX (s->val[OPT_BR_Y].w) / MM_PER_INCH;
DBG (1, "tlx: %ld, tly: %ld, brx %ld, bry %ld\n", s->avdimen.tlx, s->avdimen.tly,
s->avdimen.brx, s->avdimen.bry);
s->avdimen.tlx -= s->avdimen.tlx % dev->inquiry_color_boundary;
s->avdimen.tly -= s->avdimen.tly % dev->inquiry_color_boundary;
s->avdimen.brx -= s->avdimen.brx % dev->inquiry_color_boundary;
s->avdimen.bry -= s->avdimen.bry % dev->inquiry_color_boundary;
s->avdimen.width = (s->avdimen.brx - s->avdimen.tlx);
s->avdimen.length = (s->avdimen.bry - s->avdimen.tly);
/* bug check */
if ( !dev->inquiry_needs_software_colorpack && s->avdimen.line_difference > 0)
DBG (1, "reader_process: HINT: no sofware-color-pack but line_def != 0\n");
if (dev->inquiry_needs_software_colorpack)
s->avdimen.line_difference = dev->inquiry_line_difference * s->avdimen.res / dev->inquiry_optical_res;
else
s->avdimen.line_difference = 0;
DBG (1, "line_difference: %i\n", s->avdimen.line_difference);
memset (&s->params, 0, sizeof (s->params));
s->params.pixels_per_line = s->avdimen.width * s->avdimen.res / 1200;
/* Needed for the AV 6[2,3]0 - they procude very poor quality in low
resolutions without this boundary */
s->params.pixels_per_line -= s->params.pixels_per_line % 4;
s->params.lines = s->avdimen.length * s->avdimen.res / 1200;
DBG (1, "tlx: %ld, tly: %ld, brx %ld, bry %ld\n", s->avdimen.tlx, s->avdimen.tly,
s->avdimen.width, s->avdimen.length);
DBG (1, "pixel_per_line: %i, lines: %i\n",
s->params.pixels_per_line, s->params.lines);
s->avdimen.line_difference = 0;
switch (s->mode)
{
case THRESHOLDED:
{
s->params.pixels_per_line -= s->params.pixels_per_line % 32;
s->params.format = SANE_FRAME_GRAY;
s->params.bytes_per_line = s->params.pixels_per_line / 8;
s->params.depth = 1;
break;
}
s->params.pixels_per_line -=
s->params.pixels_per_line % dev->inquiry_thresholded_boundary;
s->params.format = SANE_FRAME_GRAY;
s->params.bytes_per_line = s->params.pixels_per_line / 8;
s->params.depth = 1;
break;
case DITHERED:
{
s->params.pixels_per_line -= s->params.pixels_per_line % 32;
s->params.format = SANE_FRAME_GRAY;
s->params.bytes_per_line = s->params.pixels_per_line / 8;
s->params.depth = 1;
break;
}
s->params.pixels_per_line -=
s->params.pixels_per_line % dev->inquiry_dithered_boundary;
s->params.format = SANE_FRAME_GRAY;
s->params.bytes_per_line = s->params.pixels_per_line / 8;
s->params.depth = 1;
break;
case GREYSCALE:
{
s->params.format = SANE_FRAME_GRAY;
s->params.bytes_per_line = s->params.pixels_per_line;
s->params.depth = 8;
break;
}
s->params.pixels_per_line -=
s->params.pixels_per_line % dev->inquiry_grey_boundary;
s->params.format = SANE_FRAME_GRAY;
s->params.bytes_per_line = s->params.pixels_per_line;
s->params.depth = 8;
break;
case TRUECOLOR:
{
s->params.format = SANE_FRAME_RGB;
s->params.bytes_per_line = s->params.pixels_per_line * 3;
s->params.depth = 8;
break;
}
}
}
/* bug check */
if ( !dev->inquiry_needs_software_colorpack && s->avdimen.line_difference > 0)
DBG (1, "reader_process: HINT: no sofware-color-pack but line_def != 0\n");
if (dev->inquiry_needs_software_colorpack)
s->avdimen.line_difference = (dev->inquiry_line_difference
* s->avdimen.res) / dev->inquiry_optical_res;
s->params.pixels_per_line -=
s->params.pixels_per_line % dev->inquiry_color_boundary;
s->params.format = SANE_FRAME_RGB;
s->params.bytes_per_line = s->params.pixels_per_line * 3;
s->params.depth = 8;
break;
} /* end switch */
} /* end if scanning */
/* compute the position coordinates we use now */
s->avdimen.width = s->params.pixels_per_line * 1200 / s->avdimen.res;
s->avdimen.length = s->params.lines * 1200 / s->avdimen.res;
DBG (1, "tlx: %ld, tly: %ld, brx %ld, bry %ld\n",
s->avdimen.tlx, s->avdimen.tly,
s->avdimen.width, s->avdimen.length);
DBG (1, "pixel_per_line: %i, lines: %i, line_difference: %i\n",
s->params.pixels_per_line, s->params.lines, s->avdimen.line_difference);
s->params.last_frame = SANE_TRUE;
@ -3033,7 +3151,6 @@ sane_get_parameters (SANE_Handle handle, SANE_Parameters* params)
return SANE_STATUS_GOOD;
}
SANE_Status
sane_start (SANE_Handle handle)
{
@ -3043,14 +3160,14 @@ sane_start (SANE_Handle handle)
SANE_Status status;
int fds [2];
DBG (3, "sane_start\n");
DBG (3, "sane_start: page:\n", s->page);
/* First make sure there is no scan running!!! */
if (s->scanning)
return SANE_STATUS_DEVICE_BUSY;
/* Second make sure we have a current parameter set. Some of the
/* Second make sure we have a current parameter set. Some of the
parameters will be overwritten below, but that's OK. */
status = sane_get_parameters (s, 0);
@ -3077,6 +3194,23 @@ sane_start (SANE_Handle handle)
DBG (1, "sane_start: wait_ready() failed: %s\n", sane_strstatus (status));
goto stop_scanner_and_return;
}
/* auto-feed next paper for ADF scanners */
if (dev->inquiry_adf && s->page > 0) {
DBG (1, "sane_start: ADF next paper.\n");
status = object_position (s, AVISION_SCSI_OP_REJECT_PAPER);
if (status != SANE_STATUS_GOOD)
DBG(1, "sane_start: reject paper failed: %s\n",
sane_strstatus (status));
status = object_position (s, AVISION_SCSI_OP_LOAD_PAPER);
if (status != SANE_STATUS_GOOD)
DBG(1, "sane_start: load paper failed: %s\n",
sane_strstatus (status));
}
/* Check for paper in sheetfeed scanners */
if (dev->hw->scanner_type == AV_SHEETFEED) {
status = check_paper(s);
if (status != SANE_STATUS_GOOD) {
@ -3098,45 +3232,53 @@ sane_start (SANE_Handle handle)
/* Only perform the calibration for newer scanners - it is not needed
for my Avision AV 630 - and also not even work ... */
if (dev->inquiry_new_protocol) {
/* TODO: do the calibration here
* If a) the scanner is not initialised
* b) the user asks for it?
* c) there is some change in the media b&w / colour?
*/
if (!disable_calibration)
{
status = perform_calibration (s);
if (status != SANE_STATUS_GOOD) {
DBG (1, "sane_start: perform calibration failed: %s\n",
sane_strstatus (status));
goto stop_scanner_and_return;
}
}
else
DBG (1, "sane_start: calibration disabled - skipped\n");
if (!dev->inquiry_new_protocol) {
DBG (1, "sane_start: old protocol - no calibration needed\n");
goto calib_end;
}
if (!disable_gamma_table)
{
status = set_gamma (s);
if (status != SANE_STATUS_GOOD) {
DBG (1, "sane_start: set gamma failed: %s\n",
sane_strstatus (status));
goto stop_scanner_and_return;
}
/* check whether to do a claibration or not */
if (disable_calibration) {
DBG (1, "sane_start: calibration disabled - skipped\n");
goto calib_end;
}
/* TODO: do the calibration here if the user asks for it? */
if (one_calib_only && dev->is_calibrated) {
DBG (1, "sane_start: already calibrated - skipped\n");
goto calib_end;
}
status = perform_calibration (s);
if (status != SANE_STATUS_GOOD) {
DBG (1, "sane_start: perform calibration failed: %s\n",
sane_strstatus (status));
goto stop_scanner_and_return;
}
dev->is_calibrated = SANE_TRUE;
calib_end:
if (!disable_gamma_table) {
status = set_gamma (s);
if (status != SANE_STATUS_GOOD) {
DBG (1, "sane_start: set gamma failed: %s\n",
sane_strstatus (status));
goto stop_scanner_and_return;
}
}
else
DBG (1, "sane_start: gamma-table disabled - skipped\n");
/* check file holder */
/* check film holder */
if (dev->hw->scanner_type == AV_FILM && dev->holder_type == 0xff) {
DBG (1, "sane_start: no film holder or APS cassette!\n");
/* Normally go_home is executed from the reader process,
/* Normally "go_home" is executed from the reader process,
but as it will not start we have to reset things here */
if (dev->inquiry_new_protocol) {
status = go_home(s);
status = object_position (s, AVISION_SCSI_OP_GO_HOME);
if (status != SANE_STATUS_GOOD)
DBG(1, "sane_start: go home failed: %s\n",
sane_strstatus (status));
@ -3183,7 +3325,7 @@ sane_start (SANE_Handle handle)
stop_scanner_and_return:
/* cancel the scan nicely and do a go_home for the new_protocol */
/* cancel the scan nicely and do a "go_home" for the new_protocol */
do_cancel (s);
return status;
@ -3219,6 +3361,7 @@ sane_read (SANE_Handle handle, SANE_Byte* buf, SANE_Int max_len, SANE_Int* len)
/* if all data is passed through */
if (nread == 0) {
s->scanning = SANE_FALSE;
++ s->page;
return do_eof (s);
}
return SANE_STATUS_GOOD;
@ -3253,7 +3396,7 @@ sane_set_io_mode (SANE_Handle handle, SANE_Bool non_blocking)
SANE_Status
sane_get_select_fd (SANE_Handle handle, SANE_Int *fd)
{
Avision_Scanner *s = handle;
Avision_Scanner* s = handle;
DBG (3, "sane_get_select_fd\n");

Wyświetl plik

@ -10,4 +10,6 @@ scsi hp
#option disable-gamma-table
#option disable-calibration
#option one-calib-only
#option force-a4

Wyświetl plik

@ -86,10 +86,14 @@ typedef struct Avision_HWEntry {
} scanner_type;
/* feature overwrites */
enum {AV_CALIB2 = 1, /* use single command calibraion send (i.e. all new scanners) */
AV_GAMMA2 = 2, /* use 512 bytes gamma table (i.e. Minolta film-scanner) */
AV_GAMMA3 = 4 /* use 256 bytes gamma table (i.e. HP 5370C) */
/* more to come ... */
enum {
/* use single command calibraion send (i.e. all new scanners) */
AV_CALIB2 = 1,
/* use 512 bytes gamma table (i.e. Minolta film-scanner) */
AV_GAMMA2 = 2,
/* use 256 bytes gamma table (i.e. HP 5370C) */
AV_GAMMA3 = 4
/* more to come ... */
} feature_type;
} Avision_HWEntry;
@ -170,12 +174,13 @@ typedef struct Avision_Device
SANE_Range speed_range;
SANE_Bool inquiry_new_protocol;
SANE_Bool inquiry_detect_accessories;
SANE_Bool inquiry_needs_calibration;
SANE_Bool inquiry_needs_gamma;
SANE_Bool inquiry_needs_software_colorpack;
int inquiry_optical_res; /* in dpi */
int inquiry_max_res; /* in dpi */
int inquiry_optical_res; /* in dpi */
int inquiry_max_res; /* in dpi */
double inquiry_x_range; /* in mm */
double inquiry_y_range; /* in mm */
@ -186,16 +191,26 @@ typedef struct Avision_Device
double inquiry_transp_x_range; /* in mm */
double inquiry_transp_y_range; /* in mm */
int inquiry_color_boundary;
int inquiry_grey_boundary;
int inquiry_line_difference; /* software color pack */
int inquiry_color_boundary;
int inquiry_grey_boundary;
int inquiry_dithered_boundary;
int inquiry_thresholded_boundary;
int inquiry_line_difference; /* software color pack */
/* int inquiry_bits_per_channel; */
/* int inquiry_bits_per_channel; */
/* accessories */
SANE_Bool inquiry_adf;
SANE_Bool inquiry_light_box;
/* film scanner atributes - maybe these should be in the scanner struct? */
SANE_Range frame_range;
SANE_Word current_frame;
SANE_Word holder_type;
/* driver state */
SANE_Bool is_calibrated;
Avision_HWEntry* hw;
} Avision_Device;
@ -210,6 +225,9 @@ typedef struct Avision_Scanner
Option_Value val [NUM_OPTIONS];
SANE_Int gamma_table [4][256];
/* page (ADF) state */
int page;
/* Parsed option values and variables that are valid only during
the actual scan: */
@ -326,14 +344,22 @@ typedef struct Avision_Scanner
/* SCSI commands that the Avision scanners understand: */
#define AVISION_SCSI_TEST_UNIT_READY 0x00
#define AVISION_SCSI_MEDIA_CHECK 0x08
#define AVISION_SCSI_INQUIRY 0x12
#define AVISION_SCSI_MODE_SELECT 0x15
#define AVISION_SCSI_SCAN 0x1b
#define AVISION_SCSI_SET_WINDOW 0x24
#define AVISION_SCSI_READ 0x28
#define AVISION_SCSI_SEND 0x2a
#define AVISION_SCSI_OBJECT_POSITION 0x31
#define AVISION_SCSI_GET_DATA_STATUS 0x34
#define AVISION_SCSI_OP_REJECT_PAPER 0x00
#define AVISION_SCSI_OP_LOAD_PAPER 0x01
#define AVISION_SCSI_OP_GO_HOME 0x02
#define AVISION_SCSI_OP_TRANS_CALIB_GREY 0x04
#define AVISION_SCSI_OP_TRANS_CALIB_COLOR 0x05
/* The structures that you have to send to an avision to get it to
do various stuff... */

Wyświetl plik

@ -29,7 +29,7 @@
:interface "SCSI"
:comment "1 pass, 600 DPI"
:mfg "HP"
:mfg "Hewlett-Packard"
:url "http://www.hp.com/"
:model "HP 5300"
@ -41,11 +41,14 @@
:model "HP 7400"
:interface "USB"
:comment "1 pass, 1200 DPI"
:model "HP 7450"
:interface "USB"
:comment "1 pass, 1200 DPI"
:mfg "MINOLTA"
:mfg "Minolta"
:url "http://www.minolta.com/"
:model "FS-V1"
:model "FS-V1 (Dimage Scan Dual II)"
:interface "USB"
:comment "1 pass, 2820 DPI, film-scanner"

Wyświetl plik

@ -1,4 +1,4 @@
.TH sane-avision 5 "10 Dec 2001"
.TH sane-avision 5 "07 Julc 2002"
.IX sane-avision
.SH NAME
@ -36,24 +36,35 @@ the first scans!
#
option force-a4
option disable-gamma-table
option disable-calibration
option disable-calibration
option one-calib-only
- force-a4:
Forces the backend to overwrite the scanable area
returned by the scanner. This might be needed for
the AV 630 which returns no area - or newer scanners
which retuns the area in a unkown format our backend
which retun the area in a unkown format our backend
doesn't recongize yet.
- disable-gamma-table:
Disables the usage of the scanner's gamma-table. You
might try this if your scans hang, or only produces
might try this if your scans hang or only produces
random garbage.
- disable-calibration:
Disables the scanner's color calibration. You
might try this if your scans hang, or only produces
might try this if your scans hang or only produces
random garbage.
- one-calib-only
When this option is enabled, the backend will only
perform a calibration when the backend is initialized
and not before each scan. This might extend the life
of the CCD, but does not work reliable with the newer
USB scanners (they hang sometimes or return garbage
image data). So this option should be used with care.
.SH "DEVICE NAMES"
This backend expects device names of the form:
.PP
@ -118,4 +129,4 @@ sane(7), sane\-scsi(5)
http://drocklinux.dyndns.org/rene/avision/index.html
.SH AUTHOR
René Rebe, Meino Christian Cramer and Martin Jelínek
René Rebe, Meino Christian Cramer and Jose Paulo Moitinho de Almeida