Updated snapscan backend to version 1.2 (from

Sebastien Sable <Sebastien.Sable@snv.jussieu.fr>).
Henning Meier-Geinitz <henning@meier-geinitz.de>
DEVEL_2_0_BRANCH-1
Henning Geinitz 2001-05-26 12:47:34 +00:00
rodzic d7f2982cdc
commit 73f193944d
9 zmienionych plików z 1669 dodań i 258 usunięć

Wyświetl plik

@ -1,8 +1,9 @@
/* sane - Scanner Access Now Easy.
Copyright (C) 1997, 1998 Franck Schnefra, Michel Roelofs,
Copyright (C) 1997, 1998, 2001 Franck Schnefra, Michel Roelofs,
Emmanuel Blot, Mikko Tyolajarvi, David Mosberger-Tang, Wolfgang Goeller,
Petter Reinholdtsen, Gary Plewa, and Kevin Charter
Petter Reinholdtsen, Gary Plewa, Sebastien Sable, Mikael Magnusson
and Kevin Charter
This file is part of the SANE package.
@ -51,8 +52,7 @@
/* scanner scsi commands */
/* Remove comment from following line to use USB instead of SCSI */
/* #include "snapscan-usb.h" */
#include "snapscan-usb.h"
/* a sensible sense handler, courtesy of Franck;
the last argument is expected to be a pointer to the associated
@ -65,12 +65,8 @@ static SANE_Status sense_handler (int scsi_fd, u_char * result, void *arg)
char *sense_str = NULL, *as_str = NULL;
SANE_Status status = SANE_STATUS_GOOD;
DBG (DL_CALL_TRACE,
"%s(%ld, %p, %p)\n",
me,
(long) scsi_fd,
(void *) result,
(void *) arg);
DBG (DL_CALL_TRACE, "%s(%ld, %p, %p)\n", me, (long) scsi_fd,
(void *) result, (void *) arg);
sense = result[2] & 0x0f;
asc = result[12];
@ -158,10 +154,16 @@ static SANE_Status open_scanner (SnapScan_Scanner *pss)
DBG (DL_CALL_TRACE, "open_scanner\n");
if (!pss->opens)
{
status = sanei_scsi_open (pss->devname,
&(pss->fd),
sense_handler,
(void *) pss);
if(pss->pdev->bus == SCSI)
{
status = sanei_scsi_open (pss->devname, &(pss->fd),
sense_handler, (void *) pss);
}
else
{
status = snapscani_usb_open (pss->devname, &(pss->fd),
sense_handler, (void *) pss);
}
}
else
{
@ -177,11 +179,36 @@ static void close_scanner (SnapScan_Scanner *pss)
{
DBG (DL_CALL_TRACE, "close_scanner\n");
if (pss->opens)
{
{
pss->opens--;
if (!pss->opens)
sanei_scsi_close (pss->fd);
{
if(pss->pdev->bus == SCSI)
{
sanei_scsi_close (pss->fd);
}
else if(pss->pdev->bus == USB)
{
snapscani_usb_close (pss->fd);
}
}
}
}
static SANE_Status snapscan_cmd(SnapScan_Bus bus, int fd, const void *src,
size_t src_size, void *dst, size_t * dst_size)
{
SANE_Status status;
DBG (DL_CALL_TRACE, "snapscan_cmd\n");
if(bus == USB)
{
status = snapscani_usb_cmd(fd, src, src_size, dst, dst_size);
}
else
{
status = sanei_scsi_cmd(fd, src, src_size, dst, dst_size);
}
return status;
}
/* SCSI commands */
@ -197,7 +224,6 @@ static void close_scanner (SnapScan_Scanner *pss)
#define SEND_DIAGNOSTIC 0x1D
#define GET_DATA_BUFFER_STATUS 0x34
#define SCAN_LEN 6
#define READ_LEN 10
@ -294,7 +320,7 @@ static void check_range (int *v, SANE_Range r)
must point to character buffers of size at least 8 and 17
respectively */
static SANE_Status mini_inquiry (int fd, char *vendor, char *model)
static SANE_Status mini_inquiry (SnapScan_Bus bus, int fd, char *vendor, char *model)
{
static const char *me = "mini_inquiry";
size_t read_bytes;
@ -305,8 +331,8 @@ static SANE_Status mini_inquiry (int fd, char *vendor, char *model)
read_bytes = 36;
DBG (DL_CALL_TRACE, "%s\n", me);
status = sanei_scsi_cmd (fd, cmd, sizeof (cmd), data, &read_bytes);
CHECK_STATUS (status, me, "sanei_scsi_cmd");
status = snapscan_cmd (bus, fd, cmd, sizeof (cmd), data, &read_bytes);
CHECK_STATUS (status, me, "snapscan_cmd");
memcpy (vendor, data + 8, 7);
vendor[7] = 0;
@ -331,12 +357,13 @@ static SANE_Status inquiry (SnapScan_Scanner *pss)
pss->cmd[4] = INQUIRY_RET_LEN;
DBG (DL_CALL_TRACE, "%s\n", me);
status = sanei_scsi_cmd (pss->fd,
pss->cmd,
INQUIRY_LEN,
pss->buf,
&pss->read_bytes);
CHECK_STATUS (status, me, "sanei_scsi_cmd");
status = snapscan_cmd (pss->pdev->bus,
pss->fd,
pss->cmd,
INQUIRY_LEN,
pss->buf,
&pss->read_bytes);
CHECK_STATUS (status, me, "snapscan_cmd");
/* record current parameters */
@ -370,6 +397,8 @@ static SANE_Status inquiry (SnapScan_Scanner *pss)
case SNAPSCAN310:
case SNAPSCAN600:
case SNAPSCAN1236S:
case SNAPSCAN1212U:
case SNAPSCANE50:
case VUEGO310S: /* WG changed */
case VUEGO610S: /* SJU changed */
case PRISA620S: /* GP added */
@ -432,14 +461,8 @@ static SANE_Status test_unit_ready (SnapScan_Scanner *pss)
SANE_Status status;
DBG (DL_CALL_TRACE, "%s\n", me);
status = sanei_scsi_cmd (pss->fd, cmd, sizeof (cmd), NULL, NULL);
if (status != SANE_STATUS_GOOD)
{
DBG (DL_MAJOR_ERROR,
"%s: scsi command error: %s\n",
me,
sane_strstatus (status));
}
status = snapscan_cmd (pss->pdev->bus, pss->fd, cmd, sizeof (cmd), NULL, NULL);
CHECK_STATUS (status, me, "snapscan_cmd");
return status;
}
@ -450,7 +473,7 @@ static void reserve_unit (SnapScan_Scanner *pss)
SANE_Status status;
DBG (DL_CALL_TRACE, "%s\n", me);
status = sanei_scsi_cmd (pss->fd, cmd, sizeof (cmd), NULL, NULL);
status = snapscan_cmd (pss->pdev->bus, pss->fd, cmd, sizeof (cmd), NULL, NULL);
if (status != SANE_STATUS_GOOD)
{
DBG (DL_MAJOR_ERROR,
@ -467,7 +490,7 @@ static void release_unit (SnapScan_Scanner *pss)
SANE_Status status;
DBG (DL_CALL_TRACE, "%s\n", me);
status = sanei_scsi_cmd (pss->fd, cmd, sizeof (cmd), NULL, NULL);
status = snapscan_cmd (pss->pdev->bus, pss->fd, cmd, sizeof (cmd), NULL, NULL);
if (status != SANE_STATUS_GOOD)
{
DBG (DL_MAJOR_ERROR,
@ -480,6 +503,7 @@ static void release_unit (SnapScan_Scanner *pss)
#define DTC_HALFTONE 0x02
#define DTC_GAMMA 0x03
#define DTC_SPEED 0x81
#define DTC_CALIBRATION 0x82
#define DTCQ_HALFTONE_BW8 0x00
#define DTCQ_HALFTONE_COLOR8 0x01
#define DTCQ_HALFTONE_BW16 0x80
@ -550,6 +574,9 @@ static SANE_Status send (SnapScan_Scanner *pss, u_char dtc, u_char dtcq)
case DTC_SPEED: /* static transfer speed */
tl = 2;
break;
case DTC_CALIBRATION:
tl = calibration_line_length(pss);
break;
default:
DBG (DL_MAJOR_ERROR, "%s: unsupported data type code 0x%x\n",
me, (unsigned) dtc);
@ -562,9 +589,9 @@ static SANE_Status send (SnapScan_Scanner *pss, u_char dtc, u_char dtcq)
pss->buf[7] = (tl >> 8) & 0xff;
pss->buf[8] = tl & 0xff;
status = sanei_scsi_cmd (pss->fd, pss->buf, SEND_LENGTH + tl,
status = snapscan_cmd (pss->pdev->bus, pss->fd, pss->buf, SEND_LENGTH + tl,
NULL, NULL);
CHECK_STATUS (status, me, "sane_scsi_cmd");
CHECK_STATUS (status, me, "snapscan_cmd");
return status;
}
@ -636,15 +663,15 @@ static SANE_Status set_window (SnapScan_Scanner *pss)
check_range(&(pss->brx), pss->pdev->x_range);
check_range(&(pss->bry), pss->pdev->y_range);
{
unsigned tlxp =
(unsigned) (pss->actual_res*IN_PER_MM*SANE_UNFIX(pss->tlx));
unsigned tlyp =
(unsigned) (pss->actual_res*IN_PER_MM*SANE_UNFIX(pss->tly));
unsigned brxp =
(unsigned) (pss->actual_res*IN_PER_MM*SANE_UNFIX(pss->brx));
unsigned bryp =
(unsigned) (pss->actual_res*IN_PER_MM*SANE_UNFIX(pss->bry));
unsigned tmp;
int tlxp =
(int) (pss->actual_res*IN_PER_MM*SANE_UNFIX(pss->tlx));
int tlyp =
(int) (pss->actual_res*IN_PER_MM*SANE_UNFIX(pss->tly));
int brxp =
(int) (pss->actual_res*IN_PER_MM*SANE_UNFIX(pss->brx));
int bryp =
(int) (pss->actual_res*IN_PER_MM*SANE_UNFIX(pss->bry));
int tmp;
/* we don't guard against brx < tlx and bry < tly in the options */
if (brxp < tlxp)
@ -667,16 +694,10 @@ static SANE_Status set_window (SnapScan_Scanner *pss)
u_int_to_u_char4p (MAX (((unsigned) (bryp - tlyp)), 75),
pc + SET_WINDOW_P_LENGTH);
}
#ifdef INOPERATIVE
pc[SET_WINDOW_P_BRIGHTNESS] =
(u_char) (255.0*((pss->bright + 100) / 200.0));
#endif
pc[SET_WINDOW_P_BRIGHTNESS] = 128;
pc[SET_WINDOW_P_THRESHOLD] =
(u_char) (255.0*(pss->threshold / 100.0));
#ifdef INOPERATIVE
pc[SET_WINDOW_P_CONTRAST] =
(u_char) (255.0*((pss->contrast + 100) / 200.0));
#endif
pc[SET_WINDOW_P_CONTRAST] = 128;
{
SnapScan_Mode mode = pss->mode;
u_char bpp;
@ -725,8 +746,21 @@ static SANE_Status set_window (SnapScan_Scanner *pss)
u_short_to_u_charp (0x0000, pc + SET_WINDOW_P_BIT_ORDERING); /* used? */
pc[SET_WINDOW_P_COMPRESSION_TYPE] = 0; /* none */
pc[SET_WINDOW_P_COMPRESSION_ARG] = 0; /* none applicable */
pc[SET_WINDOW_P_DEBUG_MODE] = 2; /* use full 128k buffer */
pc[SET_WINDOW_P_GAMMA_NO] = 0x01; /* downloaded table */
if(pss->pdev->model != ACER300F
&&
pss->pdev->model != SNAPSCAN310
&&
pss->pdev->model != SNAPSCAN1236S
&&
pss->pdev->model != SNAPSCANE50
&&
pss->pdev->model != VUEGO310S
&&
pss->pdev->model != VUEGO610S)
{
pc[SET_WINDOW_P_DEBUG_MODE] = 2; /* use full 128k buffer */
pc[SET_WINDOW_P_GAMMA_NO] = 0x01; /* downloaded table */
}
source = 0x20;
if (pss->preview)
source |= 0x40;
@ -738,12 +772,9 @@ static SANE_Status set_window (SnapScan_Scanner *pss)
pc[SET_WINDOW_P_GREEN_UNDER_COLOR] = 0xff;
DBG (DL_CALL_TRACE, "%s\n", me);
status = sanei_scsi_cmd (pss->fd,
pss->cmd,
SET_WINDOW_TOTAL_LEN,
NULL, NULL);
CHECK_STATUS (status, me, "sanei_scsi_cmd");
status = snapscan_cmd (pss->pdev->bus, pss->fd, pss->cmd,
SET_WINDOW_TOTAL_LEN, NULL, NULL);
CHECK_STATUS (status, me, "snapscan_cmd");
return status;
}
@ -755,11 +786,8 @@ static SANE_Status scan (SnapScan_Scanner *pss)
DBG (DL_CALL_TRACE, "%s\n", me);
zero_buf (pss->cmd, MAX_SCSI_CMD_LEN);
pss->cmd[0] = SCAN;
DBG (DL_CALL_TRACE, "%s\n", me);
status = sanei_scsi_cmd (pss->fd, pss->cmd, SCAN_LEN, NULL, NULL);
CHECK_STATUS (status, me, "sanei_scsi_cmd");
status = snapscan_cmd (pss->pdev->bus, pss->fd, pss->cmd, SCAN_LEN, NULL, NULL);
CHECK_STATUS (status, me, "snapscan_cmd");
return status;
}
@ -782,12 +810,9 @@ static SANE_Status scsi_read (SnapScan_Scanner *pss, u_char read_type)
pss->read_bytes = pss->expected_read_bytes;
status = sanei_scsi_cmd (pss->fd,
pss->cmd,
READ_LEN,
pss->buf,
&pss->read_bytes);
CHECK_STATUS (status, me, "sanei_scsi_cmd");
status = snapscan_cmd (pss->pdev->bus, pss->fd, pss->cmd,
READ_LEN, pss->buf, &pss->read_bytes);
CHECK_STATUS (status, me, "snapscan_cmd");
return status;
}
@ -802,13 +827,12 @@ static SANE_Status request_sense (SnapScan_Scanner *pss)
read_bytes = 20;
DBG (DL_CALL_TRACE, "%s\n", me);
status = sanei_scsi_cmd (pss->fd, cmd, sizeof (cmd), data, &read_bytes);
status = snapscan_cmd (pss->pdev->bus, pss->fd, cmd, sizeof (cmd),
data, &read_bytes);
if (status != SANE_STATUS_GOOD)
{
DBG (DL_MAJOR_ERROR,
"%s: scsi command error: %s\n",
me,
sane_strstatus (status));
DBG (DL_MAJOR_ERROR, "%s: scsi command error: %s\n",
me, sane_strstatus (status));
}
else
{
@ -817,7 +841,6 @@ static SANE_Status request_sense (SnapScan_Scanner *pss)
return status;
}
static SANE_Status send_diagnostic (SnapScan_Scanner *pss)
{
static const char *me = "send_diagnostic";
@ -832,14 +855,8 @@ static SANE_Status send_diagnostic (SnapScan_Scanner *pss)
}
DBG (DL_CALL_TRACE, "%s\n", me);
status = sanei_scsi_cmd (pss->fd, cmd, sizeof (cmd), NULL, NULL);
if (status != SANE_STATUS_GOOD)
{
DBG (DL_MAJOR_ERROR,
"%s: scsi command error: %s\n",
me,
sane_strstatus (status));
}
status = snapscan_cmd (pss->pdev->bus, pss->fd, cmd, sizeof (cmd), NULL, NULL);
CHECK_STATUS (status, me, "snapscan_cmd");
return status;
}
@ -870,12 +887,12 @@ static SANE_Status get_data_buffer_status (SnapScan_Scanner *pss, int wait)
pss->cmd[1] = 0x01;
u_short_to_u_charp (DESCRIPTOR_LENGTH, pss->cmd + 7);
status = sanei_scsi_cmd (pss->fd,
status = snapscan_cmd (pss->pdev->bus, pss->fd,
pss->cmd,
GET_DATA_BUFFER_STATUS_LEN,
pss->buf,
&pss->read_bytes);
CHECK_STATUS (status, me, "sanei_scsi_cmd");
CHECK_STATUS (status, me, "snapscan_cmd");
return status;
}
@ -905,8 +922,7 @@ static SANE_Status wait_scanner_ready (SnapScan_Scanner *pss)
int delay = pss->asi1 + 1;
DBG (DL_INFO,
"%s: scanner warming up. Waiting %ld seconds.\n",
me,
(long) delay);
me, (long) delay);
sleep (delay);
}
break;
@ -926,8 +942,127 @@ static SANE_Status wait_scanner_ready (SnapScan_Scanner *pss)
return status;
}
#define READ_CALIBRATION 0x82
#define NUM_CALIBRATION_LINES 16
static SANE_Status read_calibration_data (SnapScan_Scanner *pss, void *buf, u_char num_lines)
{
static const char *me = "read_calibration_data";
SANE_Status status;
size_t expected_read_bytes = num_lines * calibration_line_length(pss);
size_t read_bytes;
DBG (DL_CALL_TRACE, "%s\n", me);
zero_buf (pss->cmd, MAX_SCSI_CMD_LEN);
pss->cmd[0] = READ;
pss->cmd[2] = READ_CALIBRATION;
pss->cmd[5] = num_lines;
u_int_to_u_char3p (expected_read_bytes, pss->cmd + 6);
read_bytes = expected_read_bytes;
status = snapscan_cmd (pss->pdev->bus, pss->fd, pss->cmd,
READ_LEN, buf, &read_bytes);
CHECK_STATUS (status, me, "snapscan_cmd");
if(read_bytes != expected_read_bytes) {
DBG (DL_MAJOR_ERROR, "%s: read %d of %d calibration data\n", me, read_bytes, expected_read_bytes);
return SANE_STATUS_IO_ERROR;
}
return SANE_STATUS_GOOD;
}
static SANE_Status calibrate (SnapScan_Scanner *pss)
{
int r;
int c;
u_char *buf;
static const char *me = "calibrate";
SANE_Status status;
int line_length = calibration_line_length(pss);
buf = (u_char *) malloc(NUM_CALIBRATION_LINES * line_length);
if (!buf)
{
DBG (DL_MAJOR_ERROR, "%s: out of memory allocating calibration, %d bytes.", me, NUM_CALIBRATION_LINES * line_length);
return SANE_STATUS_NO_MEM;
}
DBG (DL_MAJOR_ERROR, "%s: reading calibration data\n", me);
status = read_calibration_data(pss, buf, NUM_CALIBRATION_LINES);
CHECK_STATUS(status, me, "read_calibration_data");
/* status = test_unit_ready (pss);
CHECK_STATUS(status, me, "test unit ready");*/
for(c=0; c < line_length; c++) {
u_int sum = 0;
for(r=0; r < NUM_CALIBRATION_LINES; r++) {
sum += buf[c + r * line_length];
}
pss->buf[c + SEND_LENGTH] = sum / NUM_CALIBRATION_LINES;
}
status = send (pss, DTC_CALIBRATION, 1);
CHECK_STATUS(status, me, "send calibration");
/* status = test_unit_ready (pss);
CHECK_STATUS(status, me, "test unit ready");*/
return SANE_STATUS_GOOD;
}
/*
* $Log$
* Revision 1.4 2001/05/26 12:47:30 hmg
* Updated snapscan backend to version 1.2 (from
* Sebastien Sable <Sebastien.Sable@snv.jussieu.fr>).
* Henning Meier-Geinitz <henning@meier-geinitz.de>
*
* Revision 1.12 2001/04/10 13:00:31 sable
* Moving sanei_usb_* to snapscani_usb*
*
* Revision 1.11 2001/04/10 11:04:31 sable
* Adding support for snapscan e40 an e50 thanks to Giuseppe Tanzilli
*
* Revision 1.10 2001/03/17 22:53:21 sable
* Applying Mikael Magnusson patch concerning Gamma correction
* Support for 1212U_2
*
* Revision 1.3 2001/03/04 16:37:57 mikael
* Remove brightness and contrast settings in window.
*
* Revision 1.2 2001/02/16 18:32:28 mikael
* impl calibration, signed position, increased buffer size
*
* Revision 1.1.1.1 2001/02/10 17:09:29 mikael
* Imported from snapscan-11282000.tar.gz
*
* Revision 1.9 2000/11/10 01:01:59 sable
* USB (kind of) autodetection
*
* Revision 1.8 2000/11/01 01:26:43 sable
* Support for 1212U
*
* Revision 1.7 2000/10/30 22:32:20 sable
* Support for vuego310s vuego610s and 1236s
*
* Revision 1.6 2000/10/29 22:44:55 sable
* Bug correction for 1236s
*
* Revision 1.5 2000/10/28 14:16:10 sable
* Bug correction for SnapScan310
*
* Revision 1.4 2000/10/28 14:06:35 sable
* Add support for Acer300f
*
* Revision 1.3 2000/10/15 19:52:06 cbagwell
* Changed USB support to a 1 line modification instead of multi-file
* changes.
*
* Revision 1.2 2000/10/13 03:50:27 cbagwell
* Updating to source from SANE 1.0.3. Calling this versin 1.1
*
* Revision 1.3 2000/08/12 15:09:34 pere
* Merge devel (v1.0.3) into head branch.
*

Wyświetl plik

@ -2,7 +2,7 @@
Copyright (C) 1997, 1998 Franck Schnefra, Michel Roelofs,
Emmanuel Blot, Mikko Tyolajarvi, David Mosberger-Tang, Wolfgang Goeller,
Petter Reinholdtsen, Gary Plewa, and Kevin Charter
Petter Reinholdtsen, Gary Plewa, Sebastien Sable and Kevin Charter
This file is part of the SANE package.
@ -116,6 +116,8 @@ static SANE_Status SCSISource_get (Source *pself,
SCSISource *ps = (SCSISource *) pself;
SANE_Status status = SANE_STATUS_GOOD;
SANE_Int remaining = *plen;
static SANE_Int warned_expected_bytes = 0;
while (remaining > 0
&&
pself->remaining(pself) > 0
@ -137,6 +139,37 @@ static SANE_Status SCSISource_get (Source *pself,
+ (ps->time.tv_usec - oldtime.tv_usec)/1000.0;
ps->pss->expected_read_bytes =
((int) (msecs/ps->pss->ms_per_line))*ps->pss->bytes_per_line;
if(ps->pss->pdev->model == ACER300F
||
ps->pss->pdev->model == SNAPSCAN310
||
ps->pss->pdev->model == PRISA620S
||
ps->pss->pdev->model == SNAPSCAN1212U
||
ps->pss->pdev->model == SNAPSCAN1236S
||
ps->pss->pdev->model == SNAPSCANE50
||
ps->pss->pdev->model == VUEGO310S
||
ps->pss->pdev->model == VUEGO610S)
{
ps->pss->expected_read_bytes = (size_t) ps->absolute_max;
}
if (ps->pss->expected_read_bytes == 0)
{
if (!warned_expected_bytes)
{
warned_expected_bytes++;
DBG (DL_MAJOR_ERROR,
"%s: Hung up because expected bytes is 0. Please report!",
__FUNCTION__);
}
}
}
else
{
@ -306,6 +339,7 @@ static SANE_Status BufSource_get (Source *pself,
BufSource *ps = (BufSource *) pself;
SANE_Status status = SANE_STATUS_GOOD;
SANE_Int to_move = MIN(*plen, pself->remaining(pself));
if (to_move == 0)
{
status = SANE_STATUS_EOF;
@ -653,9 +687,32 @@ typedef struct
static SANE_Int RGBRouter_remaining (Source *pself)
{
RGBRouter *ps = (RGBRouter *) pself;
SANE_Int remaining;
if (ps->cb_start < 0)
return (TxSource_remaining(pself) - ps->cb_size + ps->cb_line_size);
return (TxSource_remaining(pself) + ps->cb_line_size - ps->pos);
remaining = (TxSource_remaining(pself) - ps->cb_size + ps->cb_line_size);
else
remaining = (TxSource_remaining(pself) + ps->cb_line_size - ps->pos);
if (remaining < 0)
{
/* We are in big trouble. Someone is using the RBGRouter routines
* to find out how much is remaining. There is a case were not
* enough data has been read yet to fill the circular buffer.
* Until it is filled then no one should be accessing it or
* checking how much is remaining (in current implemntation).
* FIXME: For now, there is some code (measure_transfer_rate) that
* will do this at times and setting remaining = 1 allows some
* scans to squeak by.
*/
remaining = 1;
DBG (DL_MAJOR_ERROR,
"%s: Computed a negative size for circular buffer! Forcing to size of 1 to keep going\n",
__FUNCTION__);
}
return (remaining);
}
static SANE_Status RGBRouter_get (Source *pself,
@ -676,7 +733,7 @@ static SANE_Status RGBRouter_get (Source *pself,
if (ps->pos >= ps->cb_line_size)
{
/* Try to get more data */
SANE_Int ndata = (ps->cb_start < 0) ? ps->cb_size : ps->cb_line_size;
SANE_Int ndata = (ps->cb_start < 0) ? ps->cb_size : (ps->cb_line_size - ps->cb_start%ps->cb_line_size);
SANE_Int start = (ps->cb_start < 0) ? 0 : ps->cb_start;
SANE_Int ndata2;
SANE_Int ndata3;
@ -688,6 +745,10 @@ static SANE_Status RGBRouter_get (Source *pself,
status = TxSource_get (pself, ps->cbuf + start + ndata3, &ndata2);
if (status != SANE_STATUS_GOOD || ndata2 == 0)
{
DBG (DL_MINOR_ERROR,
"TxSource_get failed status:%d, ndata:%d, ndata2:%d ndata3:%d\n", status, ndata, ndata2, ndata3);
ps->cb_start = (start + ndata3)%ps->cb_size;
*plen -= remaining;
return status;
}
@ -904,6 +965,58 @@ static SANE_Status create_source_chain (SnapScan_Scanner *pss,
/*
* $Log$
* Revision 1.4 2001/05/26 12:47:31 hmg
* Updated snapscan backend to version 1.2 (from
* Sebastien Sable <Sebastien.Sable@snv.jussieu.fr>).
* Henning Meier-Geinitz <henning@meier-geinitz.de>
*
* Revision 1.11 2001/04/13 13:12:18 oliverschwartz
* use absolute_max as expected_read_bytes for PRISA620S
*
* Revision 1.10 2001/04/10 11:04:31 sable
* Adding support for snapscan e40 an e50 thanks to Giuseppe Tanzilli
*
* Revision 1.9 2001/03/17 22:53:21 sable
* Applying Mikael Magnusson patch concerning Gamma correction
* Support for 1212U_2
*
* Revision 1.3 2001/03/04 16:53:21 mikael
* Reading absolute max from SNAPSCAN 1212U
*
* Revision 1.2 2001/02/16 18:32:28 mikael
* impl calibration, signed position, increased buffer size
*
* Revision 1.1.1.1 2001/02/10 17:09:29 mikael
* Imported from snapscan-11282000.tar.gz
*
* Revision 1.8 2000/11/28 03:55:07 cbagwell
* Reverting a fix to RGBRouter_remaining to original fix. This allows
* most scanners to scan at 600 dpi by ignoring insufficent data in
* the RGB circular buffer and always returning size = 1 in those cases.
* This should probably be fixed at a higher level.
*
* Revision 1.7 2000/11/20 01:02:42 cbagwell
* Updates so that USB will continue reading when it receives an EAGAIN error.
* Also, changed RGBRouter_remaining to not be able to return a negative
* value.
*
* Revision 1.6 2000/11/04 01:53:58 cbagwell
* Commiting some needed USB updates. Added extra test logic to detect
* bad bytes_expected values. Just to help debug faster on scanners
* that tickle the bug.
*
* Revision 1.5 2000/10/30 22:32:20 sable
* Support for vuego310s vuego610s and 1236s
*
* Revision 1.4 2000/10/28 14:16:10 sable
* Bug correction for SnapScan310
*
* Revision 1.3 2000/10/28 14:06:35 sable
* Add support for Acer300f
*
* Revision 1.2 2000/10/13 03:50:27 cbagwell
* Updating to source from SANE 1.0.3. Calling this versin 1.1
*
* Revision 1.3 2000/08/12 15:09:35 pere
* Merge devel (v1.0.3) into head branch.
*

Wyświetl plik

@ -2,7 +2,7 @@
Copyright (C) 1997, 1998 Franck Schnefra, Michel Roelofs,
Emmanuel Blot, Mikko Tyolajarvi, David Mosberger-Tang, Wolfgang Goeller,
Petter Reinholdtsen, Gary Plewa, and Kevin Charter
Petter Reinholdtsen, Gary Plewa, Sebastien Sable and Kevin Charter
This file is part of the SANE package.
@ -87,6 +87,21 @@ static SANE_Status Source_init (Source *pself,
/*
* $Log$
* Revision 1.3 2001/05/26 12:47:31 hmg
* Updated snapscan backend to version 1.2 (from
* Sebastien Sable <Sebastien.Sable@snv.jussieu.fr>).
* Henning Meier-Geinitz <henning@meier-geinitz.de>
*
* Revision 1.3 2001/03/17 22:53:21 sable
* Applying Mikael Magnusson patch concerning Gamma correction
* Support for 1212U_2
*
* Revision 1.1.1.1 2001/02/10 17:09:29 mikael
* Imported from snapscan-11282000.tar.gz
*
* Revision 1.2 2000/10/13 03:50:27 cbagwell
* Updating to source from SANE 1.0.3. Calling this versin 1.1
*
* Revision 1.2 2000/08/12 15:09:35 pere
* Merge devel (v1.0.3) into head branch.
*

Wyświetl plik

@ -0,0 +1,418 @@
/*
Snapscan 1212U modifications for the Snapscan SANE backend
Copyright (C) 2000 Henrik Johansson
Henrik Johansson (henrikjo@post.urfors.se)
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA.
This file implements USB equivalents to the SCSI routines used by the Snapscan
backend.
History
0.1 2000-02-01
First version released
0.2 2000-02-12
The Send Diagnostics SCSI command seems to hang some 1212U scanners.
Bypassing this command fixes the problem. This bug was reported by
Dmitri (dmitri@advantrix.com).
0.3 2000-02-13
The "Set window" command returns with status "Device busy" when the
scanner is busy. One consequence is that some frontends exits with an
error message if it's started when the scanner is warming up.
A solution was suggested by Dmitri (dmitri@advantrix.com)
The idea is that a SCSI command which returns "device busy" is stored
in a "TODO" queue. The send command function is modified to first send
commands in the queue before the intended command.
So far this strategy has worked flawlessly. Thanks Dmitri!
*/
#include <sys/ipc.h>
#include <sys/sem.h>
#include "snapscan-usb.h"
/* Global variables */
static int sem_id;
static struct sembuf sem_wait = { 0, -1, 0 };
static struct sembuf sem_signal = { 0, 1, 0 };
static SANE_Status snapscani_usb_cmd(int fd, const void *src, size_t src_size,
void *dst, size_t * dst_size)
{
static const char me[] = "snapscani_usb_cmd";
int status;
DBG (DL_CALL_TRACE, "%s(%d,0x%x,%d,0x%x,0x%x (%d))\n", me,
fd,(int)src,src_size,(int)dst,(int)dst_size,dst_size ? *dst_size : 0);
while(bqhead) {
status = atomic_usb_cmd(fd, bqhead->src, bqhead->src_size, NULL, NULL);
if(status == SANE_STATUS_DEVICE_BUSY) {
if(is_queueable(src)) {
enqueue_bq(fd,src,src_size);
return SANE_STATUS_GOOD;
} else {
sleep(1);
continue;
}
}
dequeue_bq();
}
status = atomic_usb_cmd(fd,src,src_size,dst,dst_size);
if((status == SANE_STATUS_DEVICE_BUSY) && is_queueable(src) ) {
enqueue_bq(fd,src,src_size);
return SANE_STATUS_GOOD;
}
return status;
}
static SANE_Status atomic_usb_cmd(int fd, const void *src, size_t src_size,
void *dst, size_t * dst_size)
{
static const char me[] = "atomic_usb_cmd";
int status;
sigset_t all,oldset;
DBG (DL_CALL_TRACE, "%s(%d,0x%x,%d,0x%x,0x%x (%d))\n", me,
fd,(int)src,src_size,(int)dst,(int)dst_size,dst_size ? *dst_size : 0);
/* Prevent the calling process from being killed */
sigfillset(&all);
sigprocmask(SIG_BLOCK, &all, &oldset);
/* Make sure we are alone */
semop(sem_id, &sem_wait, 1);
status = usb_cmd(fd,src,src_size,dst,dst_size);
semop(sem_id, &sem_signal, 1);
/* Now it is ok to be killed */
sigprocmask(SIG_SETMASK, &oldset, NULL);
return status;
}
static SANE_Status snapscani_usb_open(const char *dev, int *fdp,
SANEI_SCSI_Sense_Handler handler, void *handler_arg)
{
return usb_open(dev,fdp,handler,handler_arg);
}
static void snapscani_usb_close(int fd) {
usb_close(fd);
}
static int usb_cmdlen(int cmd)
{
switch(cmd) {
case TEST_UNIT_READY:
case INQUIRY:
case SCAN:
case REQUEST_SENSE:
case RESERVE_UNIT:
case RELEASE_UNIT:
case SEND_DIAGNOSTIC:
return 6;
case SEND:
case SET_WINDOW:
case READ:
case GET_DATA_BUFFER_STATUS:
return 10;
}
return 0;
}
static char *usb_debug_data(char *str,const char *data, int len) {
char tmpstr[10];
int i;
str[0]=0;
for(i=0; i < (len < 10 ? len : 10); i++) {
sprintf(tmpstr," 0x%02x",((int)data[i]) & 0xff);
if(i%16 == 0 && i != 0)
strcat(str,"\n");
strcat(str,tmpstr);
}
if(i < len)
strcat(str," ...");
return str;
}
static SANE_Status usb_open(const char *dev, int *fdp,
SANEI_SCSI_Sense_Handler handler, void *handler_arg)
{
static const char me[] = "usb_open";
DBG (DL_CALL_TRACE, "%s(%s)\n", me, dev);
if((sem_id = semget( ftok(dev,0x1234), 1, IPC_CREAT | 0660 )) == -1) {
DBG (DL_MAJOR_ERROR, "%s: Can't get semaphore\n", me);
return SANE_STATUS_INVAL;
}
semop(sem_id, &sem_signal, 1);
*fdp = open(dev, O_RDWR);
if( *fdp < 0)
return SANE_STATUS_INVAL;
return SANE_STATUS_GOOD;
}
static void usb_close(int fd) {
static const char me[] = "usb_close";
DBG (DL_CALL_TRACE, "%s(%d)\n", me, fd);
semctl(sem_id, 0, IPC_RMID, 0);
close(fd);
}
/*
static int usb_status(char *status_buf) {
int status;
status = (status_buf[1] & STATUS_MASK) >> 1;
switch(status) {
case GOOD:
return SANE_STATUS_GOOD;
case CHECK_CONDITION:
case BUSY:
return SANE_STATUS_DEVICE_BUSY;
default:
return SANE_STATUS_IO_ERROR;
}
}
*/
#define RETURN_ON_FAILURE(x) if((status = x) != SANE_STATUS_GOOD) return status;
static SANE_Status usb_write(int fd, const void *buf, int n) {
char dbgmsg[16384];
int r;
static const char me[] = "usb_write";
DBG(DL_DATA_TRACE, "%s: writing: %s\n",me,usb_debug_data(dbgmsg,buf,n));
if((r=write(fd,buf,n)) != n) {
DBG (DL_MAJOR_ERROR, "%s Only %d bytes written\n",me,r);
return SANE_STATUS_IO_ERROR;
}
return SANE_STATUS_GOOD;
}
static SANE_Status usb_read(int fd, void *buf, int n) {
char dbgmsg[16384];
int r;
static const char me[] = "usb_read";
/* USB driver appears to block in all cases when asking for data
* except if the device says its not ready. In this case, we
* attempt to block ourselves to act like the sane SCSI driver.
* This relies on the USB driver to eventually report something
* besides EAGAIN if there is a serious problem.
*/
do
{
if((r=read(fd,buf,n)) != n && !(r == -1 && errno == EAGAIN)) {
DBG (DL_MAJOR_ERROR, "%s Only %d bytes read\n",me,r);
return SANE_STATUS_IO_ERROR;
}
if (r == -1 && errno == EAGAIN)
{
DBG (DL_MAJOR_ERROR, "%s: Got an EAGAIN\n",me);
usleep(10000);
}
} while (r == -1 && errno == EAGAIN);
DBG(DL_DATA_TRACE, "%s: reading: %s\n",me,usb_debug_data(dbgmsg,buf,n));
return SANE_STATUS_GOOD;
}
static SANE_Status usb_read_status(int fd, int *scsistatus, int *transaction_status)
{
unsigned char status_buf[8];
int scsistat;
int status;
RETURN_ON_FAILURE(usb_read(fd,status_buf,8));
if(transaction_status)
*transaction_status = status_buf[0];
scsistat = (status_buf[1] & STATUS_MASK) >> 1;
if(scsistatus)
*scsistatus = scsistat;
switch(scsistat) {
case GOOD:
return SANE_STATUS_GOOD;
case CHECK_CONDITION:
case BUSY:
return SANE_STATUS_DEVICE_BUSY;
default:
return SANE_STATUS_IO_ERROR;
}
}
static SANE_Status usb_cmd(int fd, const void *src, size_t src_size,
void *dst, size_t * dst_size)
{
static const char me[] = "usb_cmd";
int status,tstatus;
int cmdlen,datalen;
DBG (DL_CALL_TRACE, "%s(%d,0x%x,%d,0x%x,0x%x (%d))\n", me,
fd,(int)src,src_size,(int)dst,(int)dst_size,dst_size ? *dst_size : 0);
/* Since the "Send Diagnostic" command isn't supported by
all Snapscan USB-scanners it's disabled .
*/
if(((char *)src)[0] == SEND_DIAGNOSTIC)
return(SANE_STATUS_GOOD);
cmdlen = usb_cmdlen(*((char *)src));
datalen = src_size - cmdlen;
DBG(DL_DATA_TRACE, "%s: cmdlen=%d, datalen=%d\n",me,cmdlen,datalen);
/* Send command to scanner */
RETURN_ON_FAILURE( usb_write(fd,src,cmdlen) );
/* Read status */
RETURN_ON_FAILURE( usb_read_status(fd, NULL, &tstatus) );
/* Send data only if the scanner is expecting it */
if(datalen > 0 && (tstatus == TRANSACTION_WRITE)) {
/* Send data to scanner */
RETURN_ON_FAILURE( usb_write(fd, ((SANE_Byte *) src) + cmdlen, datalen) );
/* Read status */
RETURN_ON_FAILURE( usb_read_status(fd, NULL, &tstatus) );
}
/* Receive data only when new data is waiting */
if(dst_size && *dst_size && (tstatus == TRANSACTION_READ)) {
RETURN_ON_FAILURE( usb_read(fd,dst,*dst_size) );
/* Read status */
RETURN_ON_FAILURE( usb_read_status(fd, NULL, &tstatus) );
}
if(tstatus != TRANSACTION_COMPLETED) {
if(tstatus == TRANSACTION_WRITE)
DBG(DL_MAJOR_ERROR,
"%s: The transaction should now be completed, but the scanner is expecting more data" ,me);
else
DBG(DL_MAJOR_ERROR,
"%s: The transaction should now be completed, but the scanner has more data to send" ,me);
return SANE_STATUS_IO_ERROR;
}
return status;
}
/* Busy queue data structures and function implementations*/
static int is_queueable(const char *src)
{
switch(src[0]) {
case SEND:
case SET_WINDOW:
case SEND_DIAGNOSTIC:
return 1;
default:
return 0;
}
}
static struct usb_busy_queue *bqhead=NULL,*bqtail=NULL;
int bqelements=0;
static int enqueue_bq(int fd,const void *src, size_t src_size)
{
static const char me[] = "enqueue_bq";
struct usb_busy_queue *bqe;
DBG (DL_CALL_TRACE, "%s(%d,%p,%d)\n", me, fd,src,src_size);
if((bqe = malloc(sizeof(struct usb_busy_queue))) == NULL)
return -1;
if((bqe->src = malloc(src_size)) == NULL)
return -1;
memcpy(bqe->src,src,src_size);
bqe->src_size=src_size;
bqe->next=NULL;
if(bqtail) {
bqtail->next=bqe;
bqtail = bqe;
} else
bqhead = bqtail = bqe;
bqelements++;
DBG(DL_DATA_TRACE, "%s: Busy queue: elements=%d, bqhead=%p, bqtail=%p\n",
me,bqelements,bqhead,bqtail);
return 0;
}
static void dequeue_bq()
{
static const char me[] = "dequeue_bq";
struct usb_busy_queue *tbqe;
DBG (DL_CALL_TRACE, "%s()\n", me);
if(!bqhead)
return;
tbqe = bqhead;
bqhead = bqhead->next;
if(!bqhead)
bqtail=NULL;
if(tbqe->src)
free(tbqe->src);
free(tbqe);
bqelements--;
DBG(DL_DATA_TRACE, "%s: Busy queue: elements=%d, bqhead=%p, bqtail=%p\n",
me,bqelements,bqhead,bqtail);
}

Wyświetl plik

@ -0,0 +1,58 @@
#ifndef snapscan_usb_h
#define snapscan_usb_h
static SANE_Status snapscani_usb_cmd(int fd, const void *src, size_t src_size,
void *dst, size_t * dst_size);
static SANE_Status snapscani_usb_open(const char *dev, int *fdp,
SANEI_SCSI_Sense_Handler handler, void *handler_arg);
static void snapscani_usb_close(int fd);
/*
* USB status codes
*/
#define GOOD 0x00
#define CHECK_CONDITION 0x01
#define CONDITION_GOOD 0x02
#define BUSY 0x04
#define INTERMEDIATE_GOOD 0x08
#define INTERMEDIATE_C_GOOD 0x0a
#define RESERVATION_CONFLICT 0x0c
#define COMMAND_TERMINATED 0x11
#define QUEUE_FULL 0x14
#define STATUS_MASK 0x3e
/*
* USB transaction status
*/
#define TRANSACTION_COMPLETED 0xfb /* Scanner considers the transaction done */
#define TRANSACTION_READ 0xf9 /* Scanner has data to deliver */
#define TRANSACTION_WRITE 0xf8 /* Scanner is expecting more data */
/*
* Busy queue data structure and prototypes
*/
struct usb_busy_queue {
int fd;
void *src;
size_t src_size;
struct usb_busy_queue *next;
};
static struct usb_busy_queue *bqhead,*bqtail;
extern int bqelements;
static int enqueue_bq(int fd,const void *src, size_t src_size);
static void dequeue_bq(void);
static int is_queueable(const char *src);
static SANE_Status atomic_usb_cmd(int fd, const void *src, size_t src_size,
void *dst, size_t * dst_size);
static SANE_Status usb_open(const char *dev, int *fdp,
SANEI_SCSI_Sense_Handler handler, void *handler_arg);
static void usb_close(int fd);
static SANE_Status usb_cmd(int fd, const void *src, size_t src_size,
void *dst, size_t * dst_size);
#endif

Plik diff jest za duży Load Diff

Wyświetl plik

@ -1,4 +1,9 @@
scsi AGFA
scsi COLOR
scsi ACERPERI
# If not automatically found from above, then you may manually specify
# a device name.
/dev/scanner
/dev/sga
#/dev/usbscanner
#/dev/sga

Wyświetl plik

@ -10,56 +10,94 @@
; All other information is optional (but what good is the file without it?).
;
:backend "SnapScan" ; name of backend
:version "0.7" ; version of backend
:status :alpha ; :alpha, :beta, :stable, :new
:manpage "sane-snapscan" ; name of manpage (if it exists)
:url "http://snapscan.sourceforge.net" ; backend's web page
:backend "SnapScan" ; name of backend
:version "1.2" ; version of backend
:status :alpha ; :alpha, :beta, :stable, :new
:manpage "sane-snapscan" ; name of manpage (if it exists)
:url "http://snapscan.sourceforge.net/" ; backend's web page
:devicetype :scanner ; start of a list of devices....
; other types: :stillcam, :vidcam,
; :meta, :api
:devicetype :scanner ; start of a list of devices....
; other types: :stillcam, :vidcam,
; :meta, :api
:mfg "AGFA" ; name a manufacturer
:mfg "AGFA" ; name a manufacturer
:url "http://www.agfa.com/"
:model "SnapScan 300" ; name models for above-specified mfg.
;-----------------------------------------------------------------------------
:model "SnapScan 300" ; name models for above-specified mfg.
:interface "SCSI"
:comment "Only 8 bits/sample at present."
:model "SnapScan 310"
:interface "SCSI"
:comment "Ditto"
:model "SnapScan 600"
:interface "SCSI"
:comment "Ditto"
:model "SnapScan 1236s"
:interface "SCSI"
:comment "Ditto. Have no specific programming info yet."
:model "SnapScan 1212u"
:interface "USB"
:comment "Ditto. Have no specific programming info yet."
:model "SnapScan e40"
:interface "USB"
:comment "Have no specific programming info yet."
:model "SnapScan e50"
:interface "USB"
:comment "Have no specific programming info yet."
:mfg "Vuego"
;------------------------------------------------------------------------------
:model "310s"
:interface "SCSI"
:comment "Close SnapScan 310 compatible."
:mfg "Acer"
;------------------------------------------------------------------------------
:model "300f"
:interface "SCSI"
:model "310s"
:interface "SCSI"
:comment "Same thing as the Vuego 310s."
:model "610s"
:interface "SCSI"
:model "610plus"
:interface "SCSI"
:comment "Seems to be a close SnapScan 310/600 compatible."
:model "Prisa 620s"
:interface "SCSI"
:comment "Seems to be a close SnapScan 310/600 compatible."
:model "Prisa 620u"
:interface "USB"
:comment "Seems to be a close SnapScan 310/600 compatible."
:model "Prisa 640u"
:interface "USB"
:comment "Seems to be a close SnapScan 310/600 compatible."
:model "Prisa 640bu"
:interface "USB"
:comment "Seems to be a close SnapScan 310/600 compatible."
:mfg "Guillemot International"
;------------------------------------------------------------------------------
:model "Maxi Scan A4 Deluxe (SCSI)"
:interface "SCSI"
:comment "May be a repackaged Vuego 310s or SnapScan 310s."
;:devicetype :api ; specify a different type
;:desc "Interface to FrObYz API" ; describe a non-hardware device
; :comment and :url specifiers are optional after :mfg, :model, :desc,
; and at the top-level.

Wyświetl plik

@ -1,8 +1,9 @@
/* sane - Scanner Access Now Easy.
Copyright (C) 1997, 1998, 1999 Franck Schnefra, Michel Roelofs,
Copyright (C) 1997, 1998, 1999, 2001 Franck Schnefra, Michel Roelofs,
Emmanuel Blot, Mikko Tyolajarvi, David Mosberger-Tang, Wolfgang Goeller,
Petter Reinholdtsen, Gary Plewa, and Kevin Charter
Petter Reinholdtsen, Gary Plewa, Sebastien Sable, Mikael Magnusson
and Kevin Charter
This file is part of the SANE package.
@ -65,6 +66,13 @@
#define G_CHAN 1
#define B_CHAN 2
typedef enum
{
UNKNOWN_BUS,
SCSI,
USB
} SnapScan_Bus;
typedef enum
{
UNKNOWN,
@ -72,6 +80,9 @@ typedef enum
SNAPSCAN310, /* the SnapScan 310 */
SNAPSCAN600, /* the SnapScan 600 */
SNAPSCAN1236S, /* the SnapScan 1236s */
SNAPSCAN1212U,
SNAPSCANE50, /* SnapScan e20/e40/e50 */
ACER300F,
VUEGO310S, /* Vuego-Version of SnapScan 310 WG changed */
VUEGO610S, /* Vuego 610S and 610plus SJU changed */
PRISA620S /* Prisa-Version of SnapScan 600 GP added */
@ -90,10 +101,19 @@ static struct SnapScan_Model_desc scanners[] =
{"FlatbedScanner_9", PRISA620S},
{"FlatbedScanner13", PRISA620S},
{"FlatbedScanner16", PRISA620S},
{"FlatbedScanner18", PRISA620S},
{"FlatbedScanner19", PRISA620S}, /* Acer ScanPrisa 1240UT */
{"FlatbedScanner20", PRISA620S},
{"SNAPSCAN 1212U", SNAPSCAN1212U},
{"SNAPSCAN 1212U_2", SNAPSCAN1212U},
{"SNAPSCAN e20", SNAPSCANE50},
{"SNAPSCAN e50", SNAPSCANE50},
{"SNAPSCAN e40", SNAPSCANE50},
{"SNAPSCAN 1236", SNAPSCAN1236S},
{"SNAPSCAN 310", SNAPSCAN310},
{"SNAPSCAN 600", SNAPSCAN600},
{"SnapScan", SNAPSCAN300},
{"ACERSCAN_A4____1", ACER300F},
};
#define known_scanners ((int) (sizeof(scanners)/sizeof(scanners[0])))
@ -101,35 +121,45 @@ static char *vendors[] =
{
/* SCSI Vendor name */
"AGFA",
"COLOR"
"COLOR",
"ACERPER"
};
#define known_vendors ((int) (sizeof(vendors)/sizeof(vendors[0])))
typedef enum
{
OPT_COUNT = 0, /* option count */
OPT_MODE_GROUP, /* scan mode group */
OPT_SCANRES, /* scan resolution */
OPT_PREVIEW, /* preview mode toggle */
OPT_MODE, /* scan mode */
OPT_PREVIEW_MODE, /* preview mode */
OPT_SOURCE, /* scan source (flatbed / TPO) */
OPT_GEOMETRY_GROUP, /* geometry group */
OPT_TLX, /* top left x */
OPT_TLY, /* top left y */
OPT_BRX, /* bottom right x */
OPT_BRY, /* bottom right y */
OPT_PREDEF_WINDOW, /* predefined window configuration */
OPT_ENHANCEMENT_GROUP, /* enhancement group */
OPT_QUALITY_CAL, /* quality calibration */
OPT_HALFTONE, /* halftone flag */
OPT_HALFTONE_PATTERN, /* halftone matrix */
OPT_CUSTOM_GAMMA, /* use custom gamma tables */
OPT_GAMMA_BIND,
OPT_GAMMA_GS, /* gamma correction (greyscale) */
OPT_GAMMA_R, /* gamma correction (red) */
OPT_GAMMA_G, /* gamma correction (green) */
OPT_GAMMA_B, /* gamma correction (blue) */
OPT_GAMMA_VECTOR_GS, /* gamma correction vector (greyscale) */
OPT_GAMMA_VECTOR_R, /* gamma correction vector (red) */
OPT_GAMMA_VECTOR_G, /* gamma correction vector (green) */
OPT_GAMMA_VECTOR_B, /* gamma correction vector (blue) */
OPT_NEGATIVE, /* swap black and white */
OPT_THRESHOLD, /* threshold for line art */
#ifdef INOPERATIVE
OPT_BRIGHTNESS, /* brightness */
OPT_CONTRAST, /* contrast */
#endif
OPT_ADVANCED_GROUP, /* advanced group */
OPT_RGB_LPR, /* lines per scsi read (RGB) */
OPT_GS_LPR, /* lines per scsi read (GS) */
OPT_SCSI_CMDS, /* a group */
@ -140,6 +170,15 @@ typedef enum
NUM_OPTS /* dummy (gives number of options) */
} SnapScan_Options;
typedef union
{
SANE_Bool b;
SANE_Word w;
SANE_Word *wa; /* word array */
SANE_String s;
}
Option_Value;
typedef enum
{
MD_COLOUR = 0, /* full colour */
@ -169,6 +208,7 @@ typedef struct snapscan_device
SANE_Range x_range; /* x dimension of scan area */
SANE_Range y_range; /* y dimension of scan area */
SnapScan_Model model; /* type of scanner */
SnapScan_Bus bus; /* bus of the device usb/scsi */
u_char *depths; /* bit depth table */
struct snapscan_device *pnext;
}
@ -218,6 +258,7 @@ struct snapscan_scanner
SANE_Option_Descriptor
options[NUM_OPTS]; /* the option descriptors */
Option_Value val[NUM_OPTS];
/* the options themselves... */
SANE_Int res; /* resolution */
SANE_Bool preview; /* preview mode toggle */
@ -228,15 +269,19 @@ struct snapscan_scanner
SANE_Fixed tly; /* window top left y */
SANE_Fixed brx; /* window bottom right x */
SANE_Fixed bry; /* window bottom right y */
#ifdef INOPERATIVE
int bright; /* brightness */
int contrast; /* contrast */
#endif
SANE_String predef_window; /* predefined window name */
SANE_Fixed gamma_gs; /* gamma correction value (greyscale) */
SANE_Fixed gamma_r; /* gamma correction value (red) */
SANE_Fixed gamma_g; /* gamma correction value (green) */
SANE_Fixed gamma_b; /* gamma correction value (blue) */
SANE_Int *gamma_tables; /* gamma correction vectors */
SANE_Int *gamma_table_gs; /* gamma correction vector (greyscale) */
SANE_Int *gamma_table_r; /* gamma correction vector (red) */
SANE_Int *gamma_table_g; /* gamma correction vector (green) */
SANE_Int *gamma_table_b; /* gamma correction vector (blue) */
int gamma_length; /* length of gamma vectors */
SANE_Bool halftone; /* halftone toggle */
SANE_String dither_matrix; /* the halftone dither matrix */
SANE_Bool negative; /* swap black and white */
@ -249,6 +294,45 @@ struct snapscan_scanner
/*
* $Log$
* Revision 1.4 2001/05/26 12:47:34 hmg
* Updated snapscan backend to version 1.2 (from
* Sebastien Sable <Sebastien.Sable@snv.jussieu.fr>).
* Henning Meier-Geinitz <henning@meier-geinitz.de>
*
* Revision 1.11 2001/04/10 12:38:21 sable
* Adding e20 support thanks to Steffen Hübner
*
* Revision 1.10 2001/04/10 11:04:31 sable
* Adding support for snapscan e40 an e50 thanks to Giuseppe Tanzilli
*
* Revision 1.9 2001/03/17 22:53:21 sable
* Applying Mikael Magnusson patch concerning Gamma correction
* Support for 1212U_2
*
* Revision 1.3 2001/03/04 16:51:29 mikael
* Added Scan Mode, Geometry, Enhancement and Advanced groups. Added Quality Calibration, Analog Gamma Bind, Custom Gamma and Gamma Vector GS,R,G,B options. Added SNAPSCAN 1212U_2.
*
* Revision 1.2 2001/02/16 18:32:28 mikael
* impl calibration, signed position, increased buffer size
*
* Revision 1.1.1.1 2001/02/10 17:09:29 mikael
* Imported from snapscan-11282000.tar.gz
*
* Revision 1.8 2000/11/10 01:01:59 sable
* USB (kind of) autodetection
*
* Revision 1.7 2000/11/01 01:26:43 sable
* Support for 1212U
*
* Revision 1.6 2000/10/28 14:06:35 sable
* Add support for Acer300f
*
* Revision 1.5 2000/10/15 17:54:58 cbagwell
* Adding USB files for optional USB compiles.
*
* Revision 1.4 2000/10/13 03:50:27 cbagwell
* Updating to source from SANE 1.0.3. Calling this versin 1.1
*
* Revision 1.3 2000/08/12 15:09:37 pere
* Merge devel (v1.0.3) into head branch.
*