update snapscan to snapshot 20011008

DEVEL_2_0_BRANCH-1
Oliver Schwartz 2001-10-09 09:45:21 +00:00
rodzic e4db2d172b
commit 010db1ed52
9 zmienionych plików z 1784 dodań i 1543 usunięć

Plik diff jest za duży Load Diff

Wyświetl plik

@ -1,47 +1,48 @@
/* sane - Scanner Access Now Easy. /* sane - Scanner Access Now Easy.
Copyright (C) 1997, 1998 Franck Schnefra, Michel Roelofs, Copyright (C) 1997, 1998 Franck Schnefra, Michel Roelofs,
Emmanuel Blot, Mikko Tyolajarvi, David Mosberger-Tang, Wolfgang Goeller, Emmanuel Blot, Mikko Tyolajarvi, David Mosberger-Tang, Wolfgang Goeller,
Petter Reinholdtsen, Gary Plewa, Sebastien Sable and Kevin Charter Petter Reinholdtsen, Gary Plewa, Sebastien Sable, Oliver Schwartz
and Kevin Charter
This file is part of the SANE package. This file is part of the SANE package.
This program is free software; you can redistribute it and/or This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version. License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details. General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA. MA 02111-1307, USA.
As a special exception, the authors of SANE give permission for As a special exception, the authors of SANE give permission for
additional uses of the libraries contained in this release of SANE. additional uses of the libraries contained in this release of SANE.
The exception is that, if you link a SANE library with other files The exception is that, if you link a SANE library with other files
to produce an executable, this does not by itself cause the to produce an executable, this does not by itself cause the
resulting executable to be covered by the GNU General Public resulting executable to be covered by the GNU General Public
License. Your use of that executable is in no way restricted on License. Your use of that executable is in no way restricted on
account of linking the SANE library code into it. account of linking the SANE library code into it.
This exception does not, however, invalidate any other reasons why This exception does not, however, invalidate any other reasons why
the executable file might be covered by the GNU General Public the executable file might be covered by the GNU General Public
License. License.
If you submit changes to SANE to the maintainers to be included in If you submit changes to SANE to the maintainers to be included in
a subsequent release, you agree by submitting the changes that a subsequent release, you agree by submitting the changes that
those changes may be distributed with this exception intact. those changes may be distributed with this exception intact.
If you write modifications of your own for SANE, it is your choice If you write modifications of your own for SANE, it is your choice
whether to permit this exception to apply to your modifications. whether to permit this exception to apply to your modifications.
If you do not wish that, delete this exception notice. If you do not wish that, delete this exception notice.
This file is a component of the implementation of a backend for many This file is a component of the implementation of a backend for many
of the the AGFA SnapScan and Acer Vuego/Prisa flatbed scanners. */ of the the AGFA SnapScan and Acer Vuego/Prisa flatbed scanners. */
@ -92,15 +93,13 @@ typedef enum
BUF_SRC BUF_SRC
} BaseSourceType; } BaseSourceType;
#define SCSISOURCE_BAD_TIME -1
typedef struct typedef struct
{ {
SOURCE_GUTS; SOURCE_GUTS;
SANE_Int scsi_buf_pos; /* current position in scsi buffer */ SANE_Int scsi_buf_pos; /* current position in scsi buffer */
SANE_Int scsi_buf_max; /* data limit */ SANE_Int scsi_buf_max; /* data limit */
SANE_Int absolute_max; /* largest possible data read */ SANE_Int absolute_max; /* largest possible data read */
struct timeval time; /* time of last scsi read (usec) */
} SCSISource; } SCSISource;
static SANE_Int SCSISource_remaining (Source *pself) static SANE_Int SCSISource_remaining (Source *pself)
@ -111,69 +110,24 @@ static SANE_Int SCSISource_remaining (Source *pself)
static SANE_Status SCSISource_get (Source *pself, static SANE_Status SCSISource_get (Source *pself,
SANE_Byte *pbuf, SANE_Byte *pbuf,
SANE_Int *plen) SANE_Int *plen)
{ {
SCSISource *ps = (SCSISource *) pself; SCSISource *ps = (SCSISource *) pself;
SANE_Status status = SANE_STATUS_GOOD; SANE_Status status = SANE_STATUS_GOOD;
SANE_Int remaining = *plen; SANE_Int remaining = *plen;
static SANE_Int warned_expected_bytes = 0; char* me = "SCSISource_get";
DBG (DL_CALL_TRACE, "%s\n", me);
while (remaining > 0 while (remaining > 0
&& && pself->remaining(pself) > 0
pself->remaining(pself) > 0 && status == SANE_STATUS_GOOD)
&&
status == SANE_STATUS_GOOD)
{ {
SANE_Int ndata = ps->scsi_buf_max - ps->scsi_buf_pos; SANE_Int ndata = ps->scsi_buf_max - ps->scsi_buf_pos;
DBG (DL_DATA_TRACE, "%s: ndata %d; remaining %d\n", me, ndata, remaining);
if (ndata == 0) if (ndata == 0)
{ {
/* read more data */ ps->pss->expected_read_bytes = ps->absolute_max;
struct timeval oldtime = ps->time; /*
if (ps->time.tv_sec != SCSISOURCE_BAD_TIME
&&
gettimeofday(&(ps->time), NULL) == 0)
{
/* estimate number of lines to read from the elapsed time
since the last read and the scanner's reported speed */
double msecs = (ps->time.tv_sec - oldtime.tv_sec)*1000.0
+ (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
{
/* use the "lines_per_read" values */
SANE_Int lines; SANE_Int lines;
if (is_colour_mode(actual_mode(ps->pss)) == SANE_TRUE) if (is_colour_mode(actual_mode(ps->pss)) == SANE_TRUE)
@ -181,11 +135,9 @@ static SANE_Status SCSISource_get (Source *pself,
else else
lines = ps->pss->gs_lpr; lines = ps->pss->gs_lpr;
ps->pss->expected_read_bytes = lines * ps->pss->bytes_per_line; ps->pss->expected_read_bytes = lines * ps->pss->bytes_per_line;
} */
ps->pss->expected_read_bytes = MIN(ps->pss->expected_read_bytes, ps->pss->expected_read_bytes = MIN(ps->pss->expected_read_bytes,
ps->pss->bytes_remaining); ps->pss->bytes_remaining);
ps->pss->expected_read_bytes = MIN(ps->pss->expected_read_bytes,
(size_t) ps->absolute_max);
ps->scsi_buf_pos = 0; ps->scsi_buf_pos = 0;
ps->scsi_buf_max = 0; ps->scsi_buf_max = 0;
status = scsi_read (ps->pss, READ_IMAGE); status = scsi_read (ps->pss, READ_IMAGE);
@ -194,6 +146,9 @@ static SANE_Status SCSISource_get (Source *pself,
ps->scsi_buf_max = ps->pss->read_bytes; ps->scsi_buf_max = ps->pss->read_bytes;
ndata = ps->pss->read_bytes; ndata = ps->pss->read_bytes;
ps->pss->bytes_remaining -= ps->pss->read_bytes; ps->pss->bytes_remaining -= ps->pss->read_bytes;
DBG (DL_DATA_TRACE, "%s: pos: %d; max: %d; expected: %d; read: %d\n",
me, ps->scsi_buf_pos, ps->scsi_buf_max, ps->pss->expected_read_bytes,
ps->pss->read_bytes);
} }
ndata = MIN(ndata, remaining); ndata = MIN(ndata, remaining);
memcpy (pbuf, ps->pss->buf + ps->scsi_buf_pos, (size_t)ndata); memcpy (pbuf, ps->pss->buf + ps->scsi_buf_pos, (size_t)ndata);
@ -207,6 +162,7 @@ static SANE_Status SCSISource_get (Source *pself,
static SANE_Status SCSISource_done (Source *pself) static SANE_Status SCSISource_done (Source *pself)
{ {
DBG(DL_MINOR_INFO, "SCSISource_done\n");
UNREFERENCED_PARAMETER(pself); UNREFERENCED_PARAMETER(pself);
return SANE_STATUS_GOOD; return SANE_STATUS_GOOD;
} }
@ -216,24 +172,15 @@ static SANE_Status SCSISource_init (SCSISource *pself, SnapScan_Scanner *pss)
SANE_Status status = Source_init ((Source *) pself, pss, SANE_Status status = Source_init ((Source *) pself, pss,
SCSISource_remaining, SCSISource_remaining,
Source_bytesPerLine, Source_bytesPerLine,
Source_pixelsPerLine, Source_pixelsPerLine,
SCSISource_get, SCSISource_get,
SCSISource_done); SCSISource_done);
if (status == SANE_STATUS_GOOD) if (status == SANE_STATUS_GOOD)
{ {
pself->scsi_buf_max = 0; pself->scsi_buf_max = 0;
pself->scsi_buf_pos = 0; pself->scsi_buf_pos = 0;
pself->absolute_max = pself->absolute_max =
(SCANNER_BUF_SZ/pss->bytes_per_line)*pss->bytes_per_line; (pss->phys_buf_sz/pss->bytes_per_line)*pss->bytes_per_line;
if (gettimeofday(&(pself->time), NULL) != 0)
{
DBG (DL_MAJOR_ERROR,
"%s: error in gettimeofday(): %s\n",
__FUNCTION__,
strerror(errno));
pself->time.tv_sec = SCSISOURCE_BAD_TIME;
pself->time.tv_usec = SCSISOURCE_BAD_TIME;
}
} }
return status; return status;
} }
@ -258,35 +205,32 @@ static SANE_Status FDSource_get (Source *pself, SANE_Byte *pbuf, SANE_Int *plen)
SANE_Int remaining = *plen; SANE_Int remaining = *plen;
while (remaining > 0 while (remaining > 0
&& && pself->remaining(pself) > 0
pself->remaining(pself) > 0 && status == SANE_STATUS_GOOD)
&&
status == SANE_STATUS_GOOD)
{ {
SANE_Int bytes_read = read (ps->fd, pbuf, remaining); SANE_Int bytes_read = read (ps->fd, pbuf, remaining);
if (bytes_read == -1) if (bytes_read == -1)
{ {
if (errno == EAGAIN) if (errno == EAGAIN)
{ {
/* No data currently available */ /* No data currently available */
break; break;
} }
/* It's an IO error */ /* It's an IO error */
DBG (DL_MAJOR_ERROR, DBG (DL_MAJOR_ERROR, "%s: read failed: %s\n",
"%s: read failed: %s\n", __FUNCTION__, strerror(errno));
__FUNCTION__,
strerror(errno));
status = SANE_STATUS_IO_ERROR; status = SANE_STATUS_IO_ERROR;
} }
else if (bytes_read == 0) else if (bytes_read == 0)
{ {
/* EOF of current reading */
DBG(DL_DATA_TRACE, "%s: EOF\n",__FUNCTION__);
break; break;
} }
ps->pss->bytes_remaining -= bytes_read; ps->pss->bytes_remaining -= bytes_read;
remaining -= bytes_read; remaining -= bytes_read;
pbuf += bytes_read; pbuf += bytes_read;
} }
*plen -= remaining; *plen -= remaining;
return status; return status;
} }
@ -299,15 +243,15 @@ static SANE_Status FDSource_done (Source *pself)
static SANE_Status FDSource_init (FDSource *pself, static SANE_Status FDSource_init (FDSource *pself,
SnapScan_Scanner *pss, SnapScan_Scanner *pss,
int fd) int fd)
{ {
SANE_Status status = Source_init ((Source *) pself, SANE_Status status = Source_init ((Source *) pself,
pss, pss,
FDSource_remaining, FDSource_remaining,
Source_bytesPerLine, Source_bytesPerLine,
Source_pixelsPerLine, Source_pixelsPerLine,
FDSource_get, FDSource_get,
FDSource_done); FDSource_done);
if (status == SANE_STATUS_GOOD) if (status == SANE_STATUS_GOOD)
pself->fd = fd; pself->fd = fd;
return status; return status;
@ -339,7 +283,6 @@ static SANE_Status BufSource_get (Source *pself,
BufSource *ps = (BufSource *) pself; BufSource *ps = (BufSource *) pself;
SANE_Status status = SANE_STATUS_GOOD; SANE_Status status = SANE_STATUS_GOOD;
SANE_Int to_move = MIN(*plen, pself->remaining(pself)); SANE_Int to_move = MIN(*plen, pself->remaining(pself));
if (to_move == 0) if (to_move == 0)
{ {
status = SANE_STATUS_EOF; status = SANE_STATUS_EOF;
@ -361,16 +304,17 @@ static SANE_Status BufSource_done (Source *pself)
static SANE_Status BufSource_init (BufSource *pself, static SANE_Status BufSource_init (BufSource *pself,
SnapScan_Scanner *pss, SnapScan_Scanner *pss,
SANE_Byte *buf, SANE_Byte *buf,
SANE_Int buf_size) SANE_Int buf_size)
{ {
SANE_Status status = Source_init ((Source *) pself, SANE_Status status = Source_init ((Source *) pself,
pss, pss,
BufSource_remaining, BufSource_remaining,
Source_bytesPerLine, Source_bytesPerLine,
Source_pixelsPerLine, Source_pixelsPerLine,
BufSource_get, BufSource_get,
BufSource_done); BufSource_done);
DBG(DL_DATA_TRACE, "BufSource_init: buf_size=%d\n", buf_size);
if (status == SANE_STATUS_GOOD) if (status == SANE_STATUS_GOOD)
{ {
pself->buf = buf; pself->buf = buf;
@ -398,10 +342,10 @@ static SANE_Status create_base_source (SnapScan_Scanner *pss,
status = SANE_STATUS_NO_MEM; status = SANE_STATUS_NO_MEM;
} }
else else
{ {
status = SCSISource_init ((SCSISource *) *pps, pss); status = SCSISource_init ((SCSISource *) *pps, pss);
} }
break; break;
case FD_SRC: case FD_SRC:
*pps = (Source *) malloc(sizeof(FDSource)); *pps = (Source *) malloc(sizeof(FDSource));
if (*pps == NULL) if (*pps == NULL)
@ -410,10 +354,10 @@ static SANE_Status create_base_source (SnapScan_Scanner *pss,
status = SANE_STATUS_NO_MEM; status = SANE_STATUS_NO_MEM;
} }
else else
{ {
status = FDSource_init ((FDSource *) *pps, pss, pss->rpipe[0]); status = FDSource_init ((FDSource *) *pps, pss, pss->rpipe[0]);
} }
break; break;
case BUF_SRC: case BUF_SRC:
*pps = (Source *) malloc(sizeof(BufSource)); *pps = (Source *) malloc(sizeof(BufSource));
if (*pps == NULL) if (*pps == NULL)
@ -422,13 +366,13 @@ static SANE_Status create_base_source (SnapScan_Scanner *pss,
status = SANE_STATUS_NO_MEM; status = SANE_STATUS_NO_MEM;
} }
else else
{ {
status = BufSource_init ((BufSource *) *pps, status = BufSource_init ((BufSource *) *pps,
pss, pss,
pss->buf, pss->buf,
pss->read_bytes); pss->read_bytes);
} }
break; break;
default: default:
DBG (DL_MAJOR_ERROR, "illegal base source type %d", st); DBG (DL_MAJOR_ERROR, "illegal base source type %d", st);
break; break;
@ -441,8 +385,8 @@ static SANE_Status create_base_source (SnapScan_Scanner *pss,
/* The transformer sources */ /* The transformer sources */
#define TX_SOURCE_GUTS \ #define TX_SOURCE_GUTS \
SOURCE_GUTS;\ SOURCE_GUTS;\
Source *psub /* sub-source */ Source *psub /* sub-source */
typedef struct typedef struct
{ {
@ -488,16 +432,16 @@ static SANE_Status TxSource_init (TxSource *pself,
SourceBytesPerLine bytesPerLine, SourceBytesPerLine bytesPerLine,
SourcePixelsPerLine pixelsPerLine, SourcePixelsPerLine pixelsPerLine,
SourceGet get, SourceGet get,
SourceDone done, SourceDone done,
Source *psub) Source *psub)
{ {
SANE_Status status = Source_init((Source *) pself, SANE_Status status = Source_init((Source *) pself,
pss, pss,
remaining, remaining,
bytesPerLine, bytesPerLine,
pixelsPerLine, pixelsPerLine,
get, get,
done); done);
if (status == SANE_STATUS_GOOD) if (status == SANE_STATUS_GOOD)
pself->psub = psub; pself->psub = psub;
return status; return status;
@ -509,13 +453,13 @@ static SANE_Status TxSource_init (TxSource *pself,
typedef struct typedef struct
{ {
TX_SOURCE_GUTS; TX_SOURCE_GUTS;
SANE_Byte *ch_buf; /* channel buffer */ SANE_Byte *ch_buf; /* channel buffer */
SANE_Int ch_size; /* channel buffer size = #bytes in a channel */ SANE_Int ch_size; /* channel buffer size = #bytes in a channel */
SANE_Int ch_ndata; /* actual #bytes in channel buffer */ SANE_Int ch_ndata; /* actual #bytes in channel buffer */
SANE_Int ch_pos; /* position in buffer */ SANE_Int ch_pos; /* position in buffer */
SANE_Int bit; /* current bit */ SANE_Int bit; /* current bit */
SANE_Int last_bit; /* current last bit (counting down) */ SANE_Int last_bit; /* current last bit (counting down) */
SANE_Int last_last_bit; /* last bit in the last byte of the channel */ SANE_Int last_last_bit; /* last bit in the last byte of the channel */
} Expander; } Expander;
static SANE_Int Expander_remaining (Source *pself) static SANE_Int Expander_remaining (Source *pself)
@ -587,9 +531,9 @@ static SANE_Status Expander_get (Source *pself, SANE_Byte *pbuf, SANE_Int *plen)
ps->last_bit = 0; ps->last_bit = 0;
} }
else else
{ {
ps->bit--; ps->bit--;
} }
} }
*plen -= remaining; *plen -= remaining;
@ -608,8 +552,8 @@ static SANE_Status Expander_done (Source *pself)
} }
static SANE_Status Expander_init (Expander *pself, static SANE_Status Expander_init (Expander *pself,
SnapScan_Scanner *pss, SnapScan_Scanner *pss,
Source *psub) Source *psub)
{ {
SANE_Status status = TxSource_init((TxSource *) pself, SANE_Status status = TxSource_init((TxSource *) pself,
pss, pss,
@ -626,7 +570,7 @@ static SANE_Status Expander_init (Expander *pself,
if (pself->ch_buf == NULL) if (pself->ch_buf == NULL)
{ {
DBG (DL_MAJOR_ERROR, DBG (DL_MAJOR_ERROR,
"%s: couldn't allocate channel buffer.\n", "%s: couldn't allocate channel buffer.\n",
__FUNCTION__); __FUNCTION__);
status = SANE_STATUS_NO_MEM; status = SANE_STATUS_NO_MEM;
} }
@ -650,14 +594,14 @@ static SANE_Status Expander_init (Expander *pself,
static SANE_Status create_Expander (SnapScan_Scanner *pss, static SANE_Status create_Expander (SnapScan_Scanner *pss,
Source *psub, Source *psub,
Source **pps) Source **pps)
{ {
SANE_Status status = SANE_STATUS_GOOD; SANE_Status status = SANE_STATUS_GOOD;
*pps = (Source *) malloc(sizeof(Expander)); *pps = (Source *) malloc(sizeof(Expander));
if (*pps == NULL) if (*pps == NULL)
{ {
DBG (DL_MAJOR_ERROR, DBG (DL_MAJOR_ERROR,
"%s: failed to allocate Expander.\n", "%s: failed to allocate Expander.\n",
__FUNCTION__); __FUNCTION__);
status = SANE_STATUS_NO_MEM; status = SANE_STATUS_NO_MEM;
} }
@ -675,44 +619,27 @@ static SANE_Status create_Expander (SnapScan_Scanner *pss,
typedef struct typedef struct
{ {
TX_SOURCE_GUTS; TX_SOURCE_GUTS;
SANE_Byte *cbuf; /* circular line buffer */ SANE_Byte *cbuf; /* circular line buffer */
SANE_Byte *xbuf; /* single line buffer */ SANE_Byte *xbuf; /* single line buffer */
SANE_Int pos; /* current position in xbuf */ SANE_Int pos; /* current position in xbuf */
SANE_Int cb_size; /* size of the circular buffer */ SANE_Int cb_size; /* size of the circular buffer */
SANE_Int cb_line_size; /* size of a line in the circular buffer */ SANE_Int cb_line_size;/* size of a line in the circular buffer */
SANE_Int cb_start; /* start of valid data in the circular buffer */ SANE_Int cb_start; /* start of valid data in the circular buffer */
SANE_Int ch_offset[3]; /* offset in cbuf */ SANE_Int cb_finish; /* finish of valid data, for next read */
SANE_Int ch_offset[3];/* offset in cbuf */
SANE_Int round_req;
SANE_Int round_read;
} RGBRouter; } RGBRouter;
static SANE_Int RGBRouter_remaining (Source *pself) static SANE_Int RGBRouter_remaining (Source *pself)
{ {
RGBRouter *ps = (RGBRouter *) pself; RGBRouter *ps = (RGBRouter *) pself;
SANE_Int remaining; SANE_Int remaining;
if (ps->round_req == ps->cb_size)
if (ps->cb_start < 0) remaining = TxSource_remaining(pself) - ps->cb_size + ps->cb_line_size;
remaining = (TxSource_remaining(pself) - ps->cb_size + ps->cb_line_size);
else else
remaining = (TxSource_remaining(pself) + ps->cb_line_size - ps->pos); remaining = TxSource_remaining(pself) + ps->cb_line_size - ps->pos;
return (remaining);
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, static SANE_Status RGBRouter_get (Source *pself,
@ -724,60 +651,76 @@ static SANE_Status RGBRouter_get (Source *pself,
SANE_Int remaining = *plen; SANE_Int remaining = *plen;
SANE_Byte *s; SANE_Byte *s;
SANE_Int i; SANE_Int i;
SANE_Int r; SANE_Int r, g, b;
SANE_Int g; SANE_Int run_req;
SANE_Int b; SANE_Int org_len = *plen;
char *me = "RGBRouter_get";
while (remaining > 0 && pself->remaining(pself) > 0) while (remaining > 0 && pself->remaining(pself) > 0)
{ {
DBG(DL_DATA_TRACE, "%s: remaining=%d, pself->remaining=%d, round_req=%d, cb_size=%d\n",
me, remaining, pself->remaining(pself), ps->round_req, ps->cb_size);
/* Check if there is no valid data left from previous get */
if (ps->pos >= ps->cb_line_size) if (ps->pos >= ps->cb_line_size)
{ {
/* Try to get more data */ /* Try to get more data. either one line or
SANE_Int ndata = (ps->cb_start < 0) ? ps->cb_size : (ps->cb_line_size - ps->cb_start%ps->cb_line_size); full buffer (first time) */
SANE_Int start = (ps->cb_start < 0) ? 0 : ps->cb_start; do
SANE_Int ndata2; {
SANE_Int ndata3; run_req = ps->round_req - ps->round_read;
status = TxSource_get (pself,
ps->cbuf + ps->cb_start + ps->round_read,
&run_req);
if (status != SANE_STATUS_GOOD || run_req==0)
{
*plen -= remaining;
if ( *plen > 0 )
DBG(DL_DATA_TRACE, "%s: request=%d, read=%d\n",
me, org_len, *plen);
return status;
}
ps->round_read += run_req;
}
while (ps->round_req > ps->round_read);
ndata2 = ndata; /* route RGB */
ndata3 = 0; ps->cb_start = (ps->cb_start + ps->round_read)%ps->cb_size;
do s = ps->xbuf;
{ r = (ps->cb_start + ps->ch_offset[0])%ps->cb_size;
status = TxSource_get (pself, ps->cbuf + start + ndata3, &ndata2); g = (ps->cb_start + ps->ch_offset[1])%ps->cb_size;
if (status != SANE_STATUS_GOOD || ndata2 == 0) b = (ps->cb_start + ps->ch_offset[2])%ps->cb_size;
{
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;
}
ndata3 += ndata2;
ndata2 = ndata - ndata3;
}
while (ndata3 < ndata);
ps->cb_start = (start + ndata3)%ps->cb_size;
s = ps->xbuf;
r = (ps->cb_start + ps->ch_offset[0])%ps->cb_size;
g = (ps->cb_start + ps->ch_offset[1])%ps->cb_size;
b = (ps->cb_start + ps->ch_offset[2])%ps->cb_size;
for (i = 0; i < ps->cb_line_size/3; i++) for (i = 0; i < ps->cb_line_size/3; i++)
{ {
*s++ = ps->cbuf[r++]; *s++ = ps->cbuf[r++];
*s++ = ps->cbuf[g++]; *s++ = ps->cbuf[g++];
*s++ = ps->cbuf[b++]; *s++ = ps->cbuf[b++];
} }
ps->pos = 0;
/* end of reading & offsetiing whole line data;
reset valid position */
ps->pos = 0;
/* prepare for next round */
ps->round_req = ps->cb_line_size;
ps->round_read =0;
} }
/* Repack the whole scan line now */
while (remaining > 0 && ps->pos < ps->cb_line_size) /* Repack the whole scan line and copy to caller's buffer */
{ while (remaining > 0 && ps->pos < ps->cb_line_size)
{
*pbuf++ = ps->xbuf[ps->pos++]; *pbuf++ = ps->xbuf[ps->pos++];
remaining--; remaining--;
} }
} }
*plen -= remaining; *plen -= remaining;
DBG(DL_DATA_TRACE,
"%s: Request=%d, remaining=%d, read=%d, TXSource_rem=%d, bytes_rem=%d\n",
me,
org_len,
pself->remaining(pself),
*plen,
TxSource_remaining(pself),
ps->pss->bytes_remaining);
return status; return status;
} }
@ -795,35 +738,31 @@ static SANE_Status RGBRouter_done (Source *pself)
} }
static SANE_Status RGBRouter_init (RGBRouter *pself, static SANE_Status RGBRouter_init (RGBRouter *pself,
SnapScan_Scanner *pss, SnapScan_Scanner *pss,
Source *psub) Source *psub)
{ {
SANE_Status status = TxSource_init((TxSource *) pself, SANE_Status status = TxSource_init((TxSource *) pself,
pss, pss,
RGBRouter_remaining, RGBRouter_remaining,
TxSource_bytesPerLine, TxSource_bytesPerLine,
TxSource_pixelsPerLine, TxSource_pixelsPerLine,
RGBRouter_get, RGBRouter_get,
RGBRouter_done, RGBRouter_done,
psub); psub);
if (status == SANE_STATUS_GOOD) if (status == SANE_STATUS_GOOD)
{ {
SANE_Int lines_in_buffer = 1; SANE_Int lines_in_buffer = 0;
SANE_Int ch;
/* Size the buffer to accomodate the necessary number of scan lines
to cater for the offset between R, G and B */
lines_in_buffer = 0;
for (ch = 0; ch < 3; ch++)
{
if (pss->chroma_offset[ch] > lines_in_buffer)
lines_in_buffer = pss->chroma_offset[ch];
}
lines_in_buffer++;
/* Size the buffer to accomodate the necessary number of scan
lines to cater for the offset between R, G and B */
lines_in_buffer = pss->chroma + 1;
pself->cb_line_size = pself->bytesPerLine((Source *) pself); pself->cb_line_size = pself->bytesPerLine((Source *) pself);
pself->cb_size = pself->cb_line_size*lines_in_buffer; pself->cb_size = pself->cb_line_size*lines_in_buffer;
pself->pos = pself->cb_line_size; pself->pos = pself->cb_line_size;
pself->round_req = pself->cb_size;
pself->round_read = 0;
pself->cbuf = (SANE_Byte *) malloc(pself->cb_size); pself->cbuf = (SANE_Byte *) malloc(pself->cb_size);
pself->xbuf = (SANE_Byte *) malloc(pself->cb_line_size); pself->xbuf = (SANE_Byte *) malloc(pself->cb_line_size);
if (pself->cbuf == NULL || pself->xbuf == NULL) if (pself->cbuf == NULL || pself->xbuf == NULL)
@ -837,27 +776,34 @@ static SANE_Status RGBRouter_init (RGBRouter *pself,
{ {
SANE_Int ch; SANE_Int ch;
pself->cb_start = -1; pself->cb_start = 0;
for (ch = 0; ch < 3; ch++) for (ch = 0; ch < 3; ch++)
{ {
pself->ch_offset[ch] = pss->chroma_offset[ch]*pself->bytesPerLine((Source *) pself) pself->ch_offset[ch] =
+ ch*(pself->bytesPerLine((Source *) pself)/3); pss->chroma_offset[ch] * pself->cb_line_size
+ ch * (pself->cb_line_size / 3);
} }
} }
DBG(DL_MINOR_INFO, "RGBRouter_init: buf_size: %d x %d = %d\n",
pself->cb_line_size, lines_in_buffer, pself->cb_size);
DBG(DL_MINOR_INFO, "RGBRouter_init: buf offset R:%d G:%d B:%d\n",
pself->ch_offset[0], pself->ch_offset[1],pself->ch_offset[2]);
} }
return status; return status;
} }
static SANE_Status create_RGBRouter (SnapScan_Scanner *pss, static SANE_Status create_RGBRouter (SnapScan_Scanner *pss,
Source *psub, Source *psub,
Source **pps) Source **pps)
{ {
static char me[] = "create_RGBRouter";
SANE_Status status = SANE_STATUS_GOOD; SANE_Status status = SANE_STATUS_GOOD;
DBG (DL_CALL_TRACE, "%s\n", me);
*pps = (Source *) malloc(sizeof(RGBRouter)); *pps = (Source *) malloc(sizeof(RGBRouter));
if (*pps == NULL) if (*pps == NULL)
{ {
DBG (DL_MAJOR_ERROR, DBG (DL_MAJOR_ERROR, "%s: failed to allocate RGBRouter.\n",
"%s: failed to allocate RGBRouter.\n",
__FUNCTION__); __FUNCTION__);
status = SANE_STATUS_NO_MEM; status = SANE_STATUS_NO_MEM;
} }
@ -881,7 +827,6 @@ static SANE_Status Inverter_get (Source *pself, SANE_Byte *pbuf, SANE_Int *plen)
if (status == SANE_STATUS_GOOD) if (status == SANE_STATUS_GOOD)
{ {
int i; int i;
for (i = 0; i < *plen; i++) for (i = 0; i < *plen; i++)
pbuf[i] ^= 0xFF; pbuf[i] ^= 0xFF;
} }
@ -890,29 +835,28 @@ static SANE_Status Inverter_get (Source *pself, SANE_Byte *pbuf, SANE_Int *plen)
static SANE_Status Inverter_init (Inverter *pself, static SANE_Status Inverter_init (Inverter *pself,
SnapScan_Scanner *pss, SnapScan_Scanner *pss,
Source *psub) Source *psub)
{ {
return TxSource_init ((TxSource *) pself, return TxSource_init ((TxSource *) pself,
pss, pss,
TxSource_remaining, TxSource_remaining,
TxSource_bytesPerLine, TxSource_bytesPerLine,
TxSource_pixelsPerLine, TxSource_pixelsPerLine,
Inverter_get, Inverter_get,
TxSource_done, TxSource_done,
psub); psub);
} }
static SANE_Status create_Inverter (SnapScan_Scanner *pss, static SANE_Status create_Inverter (SnapScan_Scanner *pss,
Source *psub, Source *psub,
Source **pps) Source **pps)
{ {
SANE_Status status = SANE_STATUS_GOOD; SANE_Status status = SANE_STATUS_GOOD;
*pps = (Source *) malloc(sizeof(Inverter)); *pps = (Source *) malloc(sizeof(Inverter));
if (*pps == NULL) if (*pps == NULL)
{ {
DBG (DL_MAJOR_ERROR, DBG (DL_MAJOR_ERROR, "%s: failed to allocate Inverter.\n",
"%s: failed to allocate Inverter.\n", __FUNCTION__);
__FUNCTION__);
status = SANE_STATUS_NO_MEM; status = SANE_STATUS_NO_MEM;
} }
else else
@ -926,9 +870,12 @@ static SANE_Status create_Inverter (SnapScan_Scanner *pss,
static SANE_Status create_source_chain (SnapScan_Scanner *pss, static SANE_Status create_source_chain (SnapScan_Scanner *pss,
BaseSourceType bst, BaseSourceType bst,
Source **pps) Source **pps)
{ {
static char me[] = "create_source_chain";
SANE_Status status = create_base_source (pss, bst, pps); SANE_Status status = create_base_source (pss, bst, pps);
DBG (DL_CALL_TRACE, "%s\n", me);
if (status == SANE_STATUS_GOOD) if (status == SANE_STATUS_GOOD)
{ {
SnapScan_Mode mode = actual_mode(pss); SnapScan_Mode mode = actual_mode(pss);
@ -952,10 +899,8 @@ static SANE_Status create_source_chain (SnapScan_Scanner *pss,
status = create_Inverter (pss, *pps, pps); status = create_Inverter (pss, *pps, pps);
break; break;
default: default:
DBG (DL_MAJOR_ERROR, DBG (DL_MAJOR_ERROR, "%s: bad mode value %d (internal error)\n",
"%s: bad mode value %d (internal error)\n", __FUNCTION__, mode);
__FUNCTION__,
mode);
status = SANE_STATUS_INVAL; status = SANE_STATUS_INVAL;
break; break;
} }
@ -965,10 +910,31 @@ static SANE_Status create_source_chain (SnapScan_Scanner *pss,
/* /*
* $Log$ * $Log$
* Revision 1.4 2001/05/26 12:47:31 hmg * Revision 1.5 2001/10/09 09:45:12 oliverschwartz
* Updated snapscan backend to version 1.2 (from * update snapscan to snapshot 20011008
* Sebastien Sable <Sebastien.Sable@snv.jussieu.fr>). *
* Henning Meier-Geinitz <henning@meier-geinitz.de> * Revision 1.16 2001/10/08 18:22:02 oliverschwartz
* - Disable quality calibration for Acer Vuego 310F
* - Use sanei_scsi_max_request_size as scanner buffer size
* for SCSI devices
* - Added new devices to snapscan.desc
*
* Revision 1.15 2001/09/28 15:56:51 oliverschwartz
* - fix hanging for SNAPSCAN300 / VUEGO 310
*
* Revision 1.14 2001/09/28 13:39:16 oliverschwartz
* - Added "Snapscan 300" ID string
* - cleanup
* - more debugging messages in snapscan-sources.c
*
* Revision 1.13 2001/09/18 15:01:07 oliverschwartz
* - Read scanner id string again after firmware upload
* to indentify correct model
* - Make firmware upload work for AGFA scanners
* - Change copyright notice
*
* Revision 1.12 2001/09/09 18:06:32 oliverschwartz
* add changes from Acer (new models; automatic firmware upload for USB scanners); fix distorted colour scans after greyscale scans (call set_window only in sane_start); code cleanup
* *
* Revision 1.11 2001/04/13 13:12:18 oliverschwartz * Revision 1.11 2001/04/13 13:12:18 oliverschwartz
* use absolute_max as expected_read_bytes for PRISA620S * use absolute_max as expected_read_bytes for PRISA620S

Wyświetl plik

@ -2,7 +2,8 @@
Copyright (C) 1997, 1998 Franck Schnefra, Michel Roelofs, Copyright (C) 1997, 1998 Franck Schnefra, Michel Roelofs,
Emmanuel Blot, Mikko Tyolajarvi, David Mosberger-Tang, Wolfgang Goeller, Emmanuel Blot, Mikko Tyolajarvi, David Mosberger-Tang, Wolfgang Goeller,
Petter Reinholdtsen, Gary Plewa, Sebastien Sable and Kevin Charter Petter Reinholdtsen, Gary Plewa, Sebastien Sable, Oliver Schwartz
and Kevin Charter
This file is part of the SANE package. This file is part of the SANE package.
@ -87,10 +88,14 @@ static SANE_Status Source_init (Source *pself,
/* /*
* $Log$ * $Log$
* Revision 1.3 2001/05/26 12:47:31 hmg * Revision 1.4 2001/10/09 09:45:13 oliverschwartz
* Updated snapscan backend to version 1.2 (from * update snapscan to snapshot 20011008
* Sebastien Sable <Sebastien.Sable@snv.jussieu.fr>). *
* Henning Meier-Geinitz <henning@meier-geinitz.de> * Revision 1.4 2001/09/18 15:01:07 oliverschwartz
* - Read scanner id string again after firmware upload
* to indentify correct model
* - Make firmware upload work for AGFA scanners
* - Change copyright notice
* *
* Revision 1.3 2001/03/17 22:53:21 sable * Revision 1.3 2001/03/17 22:53:21 sable
* Applying Mikael Magnusson patch concerning Gamma correction * Applying Mikael Magnusson patch concerning Gamma correction

Wyświetl plik

@ -25,7 +25,7 @@
History History
0.1 2000-02-01 0.1 2000-02-01
First version released First version released
@ -47,8 +47,11 @@
So far this strategy has worked flawlessly. Thanks Dmitri! So far this strategy has worked flawlessly. Thanks Dmitri!
*/ */
#include <sys/ipc.h> /* $Id$
#include <sys/sem.h> SnapScan backend scan data sources */
#include <sys/ipc.h>
#include <sys/sem.h>
#include "snapscan-usb.h" #include "snapscan-usb.h"
@ -59,48 +62,48 @@ static struct sembuf sem_wait = { 0, -1, 0 };
static struct sembuf sem_signal = { 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, static SANE_Status snapscani_usb_cmd(int fd, const void *src, size_t src_size,
void *dst, size_t * dst_size) void *dst, size_t * dst_size)
{ {
static const char me[] = "snapscani_usb_cmd"; static const char me[] = "snapscani_usb_cmd";
int status; int status;
DBG (DL_CALL_TRACE, "%s(%d,0x%x,%d,0x%x,0x%x (%d))\n", me, 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); fd,(int)src,src_size,(int)dst,(int)dst_size,dst_size ? *dst_size : 0);
while(bqhead) { while(bqhead) {
status = atomic_usb_cmd(fd, bqhead->src, bqhead->src_size, NULL, NULL); status = atomic_usb_cmd(fd, bqhead->src, bqhead->src_size, NULL, NULL);
if(status == SANE_STATUS_DEVICE_BUSY) { if(status == SANE_STATUS_DEVICE_BUSY) {
if(is_queueable(src)) { if(is_queueable(src)) {
enqueue_bq(fd,src,src_size); enqueue_bq(fd,src,src_size);
return SANE_STATUS_GOOD; return SANE_STATUS_GOOD;
} else { } else {
sleep(1); sleep(1);
continue; continue;
} }
} }
dequeue_bq(); dequeue_bq();
} }
status = atomic_usb_cmd(fd,src,src_size,dst,dst_size); status = atomic_usb_cmd(fd,src,src_size,dst,dst_size);
if((status == SANE_STATUS_DEVICE_BUSY) && is_queueable(src) ) { if ((status == SANE_STATUS_DEVICE_BUSY) && is_queueable(src) ) {
enqueue_bq(fd,src,src_size); enqueue_bq(fd,src,src_size);
return SANE_STATUS_GOOD; return SANE_STATUS_GOOD;
} }
return status; return status;
} }
static SANE_Status atomic_usb_cmd(int fd, const void *src, size_t src_size, static SANE_Status atomic_usb_cmd(int fd, const void *src, size_t src_size,
void *dst, size_t * dst_size) void *dst, size_t * dst_size)
{ {
static const char me[] = "atomic_usb_cmd"; static const char me[] = "atomic_usb_cmd";
int status; int status;
sigset_t all,oldset; sigset_t all,oldset;
DBG (DL_CALL_TRACE, "%s(%d,0x%x,%d,0x%x,0x%x (%d))\n", me, 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); fd,(int)src,src_size,(int)dst,(int)dst_size,dst_size ? *dst_size : 0);
/* Prevent the calling process from being killed */ /* Prevent the calling process from being killed */
sigfillset(&all); sigfillset(&all);
@ -115,15 +118,14 @@ static SANE_Status atomic_usb_cmd(int fd, const void *src, size_t src_size,
/* Now it is ok to be killed */ /* Now it is ok to be killed */
sigprocmask(SIG_SETMASK, &oldset, NULL); sigprocmask(SIG_SETMASK, &oldset, NULL);
return status; return status;
} }
static SANE_Status snapscani_usb_open(const char *dev, int *fdp, 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); return usb_open(dev,fdp);
} }
@ -142,12 +144,12 @@ static int usb_cmdlen(int cmd)
case RESERVE_UNIT: case RESERVE_UNIT:
case RELEASE_UNIT: case RELEASE_UNIT:
case SEND_DIAGNOSTIC: case SEND_DIAGNOSTIC:
return 6; return 6;
case SEND: case SEND:
case SET_WINDOW: case SET_WINDOW:
case READ: case READ:
case GET_DATA_BUFFER_STATUS: case GET_DATA_BUFFER_STATUS:
return 10; return 10;
} }
return 0; return 0;
} }
@ -158,42 +160,41 @@ static char *usb_debug_data(char *str,const char *data, int len) {
str[0]=0; str[0]=0;
for(i=0; i < (len < 10 ? len : 10); i++) { for(i=0; i < (len < 10 ? len : 10); i++) {
sprintf(tmpstr," 0x%02x",((int)data[i]) & 0xff); sprintf(tmpstr," 0x%02x",((int)data[i]) & 0xff);
if(i%16 == 0 && i != 0) if(i%16 == 0 && i != 0)
strcat(str,"\n"); strcat(str,"\n");
strcat(str,tmpstr); strcat(str,tmpstr);
} }
if(i < len) if(i < len)
strcat(str," ..."); strcat(str," ...");
return str; return str;
} }
static SANE_Status usb_open(const char *dev, int *fdp, static SANE_Status usb_open(const char *dev, int *fdp)
SANEI_SCSI_Sense_Handler handler, void *handler_arg)
{ {
static const char me[] = "usb_open"; 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_CALL_TRACE, "%s(%s)\n", me, dev);
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((sem_id = semget( ftok(dev,0x1234), 1, IPC_CREAT | 0660 )) == -1) {
if( *fdp < 0) DBG (DL_MAJOR_ERROR, "%s: Can't get semaphore\n", me);
return SANE_STATUS_INVAL; return SANE_STATUS_INVAL;
return SANE_STATUS_GOOD; }
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 void usb_close(int fd) {
static const char me[] = "usb_close"; static const char me[] = "usb_close";
DBG (DL_CALL_TRACE, "%s(%d)\n", me, fd); DBG (DL_CALL_TRACE, "%s(%d)\n", me, fd);
semctl(sem_id, 0, IPC_RMID, 0); semctl(sem_id, 0, IPC_RMID, 0);
close(fd); close(fd);
} }
/* /*
@ -204,12 +205,12 @@ static int usb_status(char *status_buf) {
switch(status) { switch(status) {
case GOOD: case GOOD:
return SANE_STATUS_GOOD; return SANE_STATUS_GOOD;
case CHECK_CONDITION: case CHECK_CONDITION:
case BUSY: case BUSY:
return SANE_STATUS_DEVICE_BUSY; return SANE_STATUS_DEVICE_BUSY;
default: default:
return SANE_STATUS_IO_ERROR; return SANE_STATUS_IO_ERROR;
} }
} }
*/ */
@ -219,13 +220,13 @@ static int usb_status(char *status_buf) {
static SANE_Status usb_write(int fd, const void *buf, int n) { static SANE_Status usb_write(int fd, const void *buf, int n) {
char dbgmsg[16384]; char dbgmsg[16384];
int r; int r;
static const char me[] = "usb_write"; static const char me[] = "usb_write";
DBG(DL_DATA_TRACE, "%s: writing: %s\n",me,usb_debug_data(dbgmsg,buf,n)); DBG(DL_DATA_TRACE, "%s: writing: %s\n",me,usb_debug_data(dbgmsg,buf,n));
if((r=write(fd,buf,n)) != n) { if((r=write(fd,buf,n)) != n) {
DBG (DL_MAJOR_ERROR, "%s Only %d bytes written\n",me,r); DBG (DL_MAJOR_ERROR, "%s Only %d bytes written\n",me,r);
return SANE_STATUS_IO_ERROR; return SANE_STATUS_IO_ERROR;
} }
return SANE_STATUS_GOOD; return SANE_STATUS_GOOD;
} }
@ -233,7 +234,7 @@ static SANE_Status usb_write(int fd, const void *buf, int n) {
static SANE_Status usb_read(int fd, void *buf, int n) { static SANE_Status usb_read(int fd, void *buf, int n) {
char dbgmsg[16384]; char dbgmsg[16384];
int r; int r;
static const char me[] = "usb_read"; static const char me[] = "usb_read";
/* USB driver appears to block in all cases when asking for data /* USB driver appears to block in all cases when asking for data
@ -245,13 +246,13 @@ static SANE_Status usb_read(int fd, void *buf, int n) {
do do
{ {
if((r=read(fd,buf,n)) != n && !(r == -1 && errno == EAGAIN)) { if((r=read(fd,buf,n)) != n && !(r == -1 && errno == EAGAIN)) {
DBG (DL_MAJOR_ERROR, "%s Only %d bytes read\n",me,r); DBG (DL_MAJOR_ERROR, "%s Only %d bytes read\n",me,r);
return SANE_STATUS_IO_ERROR; return SANE_STATUS_IO_ERROR;
} }
if (r == -1 && errno == EAGAIN) if (r == -1 && errno == EAGAIN)
{ {
DBG (DL_MAJOR_ERROR, "%s: Got an EAGAIN\n",me); DBG (DL_MAJOR_ERROR, "%s: Got an EAGAIN\n",me);
usleep(10000); usleep(10000);
} }
} while (r == -1 && errno == EAGAIN); } while (r == -1 && errno == EAGAIN);
@ -260,40 +261,40 @@ static SANE_Status usb_read(int fd, void *buf, int n) {
} }
static SANE_Status usb_read_status(int fd, int *scsistatus, int *transaction_status) static SANE_Status usb_read_status(int fd, int *scsistatus, int *transaction_status)
{ {
unsigned char status_buf[8]; unsigned char status_buf[8];
int scsistat; int scsistat;
int status; int status;
RETURN_ON_FAILURE(usb_read(fd,status_buf,8)); RETURN_ON_FAILURE(usb_read(fd,status_buf,8));
if(transaction_status) if(transaction_status)
*transaction_status = status_buf[0]; *transaction_status = status_buf[0];
scsistat = (status_buf[1] & STATUS_MASK) >> 1; scsistat = (status_buf[1] & STATUS_MASK) >> 1;
if(scsistatus) if(scsistatus)
*scsistatus = scsistat; *scsistatus = scsistat;
switch(scsistat) { switch(scsistat) {
case GOOD: case GOOD:
return SANE_STATUS_GOOD; return SANE_STATUS_GOOD;
case CHECK_CONDITION: case CHECK_CONDITION:
case BUSY: case BUSY:
return SANE_STATUS_DEVICE_BUSY; return SANE_STATUS_DEVICE_BUSY;
default: default:
return SANE_STATUS_IO_ERROR; return SANE_STATUS_IO_ERROR;
} }
} }
static SANE_Status usb_cmd(int fd, const void *src, size_t src_size, static SANE_Status usb_cmd(int fd, const void *src, size_t src_size,
void *dst, size_t * dst_size) void *dst, size_t * dst_size)
{ {
static const char me[] = "usb_cmd"; static const char me[] = "usb_cmd";
int status,tstatus; int status,tstatus;
int cmdlen,datalen; int cmdlen,datalen;
DBG (DL_CALL_TRACE, "%s(%d,0x%x,%d,0x%x,0x%x (%d))\n", me, 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); fd,(int)src,src_size,(int)dst,(int)dst_size,dst_size ? *dst_size : 0);
@ -303,7 +304,7 @@ static SANE_Status usb_cmd(int fd, const void *src, size_t src_size,
*/ */
if(((char *)src)[0] == SEND_DIAGNOSTIC) if(((char *)src)[0] == SEND_DIAGNOSTIC)
return(SANE_STATUS_GOOD); return(SANE_STATUS_GOOD);
cmdlen = usb_cmdlen(*((char *)src)); cmdlen = usb_cmdlen(*((char *)src));
datalen = src_size - cmdlen; datalen = src_size - cmdlen;
@ -317,7 +318,7 @@ static SANE_Status usb_cmd(int fd, const void *src, size_t src_size,
/* Send data only if the scanner is expecting it */ /* Send data only if the scanner is expecting it */
if(datalen > 0 && (tstatus == TRANSACTION_WRITE)) { if(datalen > 0 && (tstatus == TRANSACTION_WRITE)) {
/* Send data to scanner */ /* Send data to scanner */
RETURN_ON_FAILURE( usb_write(fd, ((SANE_Byte *) src) + cmdlen, datalen) ); RETURN_ON_FAILURE( usb_write(fd, ((SANE_Byte *) src) + cmdlen, datalen) );
/* Read status */ /* Read status */
@ -334,14 +335,14 @@ static SANE_Status usb_cmd(int fd, const void *src, size_t src_size,
if(tstatus != TRANSACTION_COMPLETED) { if(tstatus != TRANSACTION_COMPLETED) {
if(tstatus == TRANSACTION_WRITE) if(tstatus == TRANSACTION_WRITE)
DBG(DL_MAJOR_ERROR, DBG(DL_MAJOR_ERROR,
"%s: The transaction should now be completed, but the scanner is expecting more data" ,me); "%s: The transaction should now be completed, but the scanner is expecting more data" ,me);
else else
DBG(DL_MAJOR_ERROR, DBG(DL_MAJOR_ERROR,
"%s: The transaction should now be completed, but the scanner has more data to send" ,me); "%s: The transaction should now be completed, but the scanner has more data to send" ,me);
return SANE_STATUS_IO_ERROR; return SANE_STATUS_IO_ERROR;
} }
return status; return status;
} }
@ -353,9 +354,9 @@ static int is_queueable(const char *src)
case SEND: case SEND:
case SET_WINDOW: case SET_WINDOW:
case SEND_DIAGNOSTIC: case SEND_DIAGNOSTIC:
return 1; return 1;
default: default:
return 0; return 0;
} }
} }
@ -366,14 +367,14 @@ static int enqueue_bq(int fd,const void *src, size_t src_size)
{ {
static const char me[] = "enqueue_bq"; static const char me[] = "enqueue_bq";
struct usb_busy_queue *bqe; struct usb_busy_queue *bqe;
DBG (DL_CALL_TRACE, "%s(%d,%p,%d)\n", me, fd,src,src_size); DBG (DL_CALL_TRACE, "%s(%d,%p,%d)\n", me, fd,src,src_size);
if((bqe = malloc(sizeof(struct usb_busy_queue))) == NULL) if((bqe = malloc(sizeof(struct usb_busy_queue))) == NULL)
return -1; return -1;
if((bqe->src = malloc(src_size)) == NULL) if((bqe->src = malloc(src_size)) == NULL)
return -1; return -1;
memcpy(bqe->src,src,src_size); memcpy(bqe->src,src,src_size);
bqe->src_size=src_size; bqe->src_size=src_size;
@ -381,18 +382,18 @@ static int enqueue_bq(int fd,const void *src, size_t src_size)
bqe->next=NULL; bqe->next=NULL;
if(bqtail) { if(bqtail) {
bqtail->next=bqe; bqtail->next=bqe;
bqtail = bqe; bqtail = bqe;
} else } else
bqhead = bqtail = bqe; bqhead = bqtail = bqe;
bqelements++; bqelements++;
DBG(DL_DATA_TRACE, "%s: Busy queue: elements=%d, bqhead=%p, bqtail=%p\n", DBG(DL_DATA_TRACE, "%s: Busy queue: elements=%d, bqhead=%p, bqtail=%p\n",
me,bqelements,bqhead,bqtail); me,bqelements,bqhead,bqtail);
return 0; return 0;
} }
static void dequeue_bq() static void dequeue_bq()
{ {
static const char me[] = "dequeue_bq"; static const char me[] = "dequeue_bq";
struct usb_busy_queue *tbqe; struct usb_busy_queue *tbqe;
@ -400,19 +401,31 @@ static void dequeue_bq()
DBG (DL_CALL_TRACE, "%s()\n", me); DBG (DL_CALL_TRACE, "%s()\n", me);
if(!bqhead) if(!bqhead)
return; return;
tbqe = bqhead; tbqe = bqhead;
bqhead = bqhead->next; bqhead = bqhead->next;
if(!bqhead) if(!bqhead)
bqtail=NULL; bqtail=NULL;
if(tbqe->src) if(tbqe->src)
free(tbqe->src); free(tbqe->src);
free(tbqe); free(tbqe);
bqelements--; bqelements--;
DBG(DL_DATA_TRACE, "%s: Busy queue: elements=%d, bqhead=%p, bqtail=%p\n", DBG(DL_DATA_TRACE, "%s: Busy queue: elements=%d, bqhead=%p, bqtail=%p\n",
me,bqelements,bqhead,bqtail); me,bqelements,bqhead,bqtail);
} }
/*
* $Log$
* Revision 1.2 2001/10/09 09:45:14 oliverschwartz
* update snapscan to snapshot 20011008
*
* Revision 1.12 2001/09/18 15:01:07 oliverschwartz
* - Read scanner id string again after firmware upload
* to indentify correct model
* - Make firmware upload work for AGFA scanners
* - Change copyright notice
*
* */

Wyświetl plik

@ -1,10 +1,38 @@
/*
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.
*/
/* $Id$
SnapScan backend scan data sources */
#ifndef snapscan_usb_h #ifndef snapscan_usb_h
#define snapscan_usb_h #define snapscan_usb_h
static SANE_Status snapscani_usb_cmd(int fd, const void *src, size_t src_size, static SANE_Status snapscani_usb_cmd(int fd, const void *src, size_t src_size,
void *dst, size_t * dst_size); void *dst, size_t * dst_size);
static SANE_Status snapscani_usb_open(const char *dev, int *fdp, 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); static void snapscani_usb_close(int fd);
/* /*
@ -46,13 +74,25 @@ static void dequeue_bq(void);
static int is_queueable(const char *src); static int is_queueable(const char *src);
static SANE_Status atomic_usb_cmd(int fd, const void *src, size_t src_size, static SANE_Status atomic_usb_cmd(int fd, const void *src, size_t src_size,
void *dst, size_t * dst_size); void *dst, size_t * dst_size);
static SANE_Status usb_open(const char *dev, int *fdp, 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 void usb_close(int fd);
static SANE_Status usb_cmd(int fd, const void *src, size_t src_size, static SANE_Status usb_cmd(int fd, const void *src, size_t src_size,
void *dst, size_t * dst_size); void *dst, size_t * dst_size);
#endif #endif
/*
* $Log$
* Revision 1.2 2001/10/09 09:45:15 oliverschwartz
* update snapscan to snapshot 20011008
*
* Revision 1.8 2001/09/18 15:01:07 oliverschwartz
* - Read scanner id string again after firmware upload
* to indentify correct model
* - Make firmware upload work for AGFA scanners
* - Change copyright notice
*
* */

Plik diff jest za duży Load Diff

Wyświetl plik

@ -1,9 +1,14 @@
scsi AGFA
scsi COLOR
scsi ACERPERI
# If not automatically found from above, then you may manually specify # If not automatically found from above, then you may manually specify
# a device name. # a device name.
/dev/scanner
#/dev/usbscanner # For USB devices, make sure that the name contains 'usb' somewhere, as in
# '/dev/usbscanner' or '/dev/usb/scanner0'. Do not use a link
# from /dev/scanner to your USB device.
/dev/usbscanner
#/dev/scanner
#/dev/sga #/dev/sga
# Change to the fully qualified filename of your firmware file, if
# firmware upload is needed by the scanner
firmware /path/to/your/firmware/file

Wyświetl plik

@ -12,7 +12,7 @@
:backend "SnapScan" ; name of backend :backend "SnapScan" ; name of backend
:version "1.2" ; version of backend :version "1.2" ; version of backend
:status :alpha ; :alpha, :beta, :stable, :new :status :beta ; :alpha, :beta, :stable, :new
:manpage "sane-snapscan" ; name of manpage (if it exists) :manpage "sane-snapscan" ; name of manpage (if it exists)
:url "http://snapscan.sourceforge.net/" ; backend's web page :url "http://snapscan.sourceforge.net/" ; backend's web page
@ -40,10 +40,18 @@
:interface "SCSI" :interface "SCSI"
:comment "Ditto. Have no specific programming info yet." :comment "Ditto. Have no specific programming info yet."
:model "SnapScan 1236u"
:interface "USB"
:comment "Ditto. Have no specific programming info yet."
:model "SnapScan 1212u" :model "SnapScan 1212u"
:interface "USB" :interface "USB"
:comment "Ditto. Have no specific programming info yet." :comment "Ditto. Have no specific programming info yet."
:model "SnapScan e20"
:interface "USB"
:comment "Have no specific programming info yet."
:model "SnapScan e40" :model "SnapScan e40"
:interface "USB" :interface "USB"
:comment "Have no specific programming info yet." :comment "Have no specific programming info yet."
@ -52,6 +60,10 @@
:interface "USB" :interface "USB"
:comment "Have no specific programming info yet." :comment "Have no specific programming info yet."
:model "SnapScan e60"
:interface "USB"
:comment "Have no specific programming info yet."
:mfg "Vuego" :mfg "Vuego"
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
@ -84,6 +96,10 @@
:interface "USB" :interface "USB"
:comment "Seems to be a close SnapScan 310/600 compatible." :comment "Seems to be a close SnapScan 310/600 compatible."
:model "Prisa 620ut"
:interface "USB"
:comment "Seems to be a close SnapScan 310/600 compatible."
:model "Prisa 640u" :model "Prisa 640u"
:interface "USB" :interface "USB"
:comment "Seems to be a close SnapScan 310/600 compatible." :comment "Seems to be a close SnapScan 310/600 compatible."
@ -92,6 +108,22 @@
:interface "USB" :interface "USB"
:comment "Seems to be a close SnapScan 310/600 compatible." :comment "Seems to be a close SnapScan 310/600 compatible."
:model "Prisa 1240"
:interface "USB"
:comment "Seems to be a close SnapScan 310/600 compatible."
:model "Prisa 3300"
:interface "USB"
:comment "Seems to be a close SnapScan 310/600 compatible."
:model "Prisa 4300"
:interface "USB"
:comment "Seems to be a close SnapScan 310/600 compatible."
:model "Prisa 5300"
:interface "USB"
:comment "Seems to be a close SnapScan 310/600 compatible."
:mfg "Guillemot International" :mfg "Guillemot International"
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------

Wyświetl plik

@ -2,9 +2,9 @@
Copyright (C) 1997, 1998, 1999, 2001 Franck Schnefra, Michel Roelofs, Copyright (C) 1997, 1998, 1999, 2001 Franck Schnefra, Michel Roelofs,
Emmanuel Blot, Mikko Tyolajarvi, David Mosberger-Tang, Wolfgang Goeller, Emmanuel Blot, Mikko Tyolajarvi, David Mosberger-Tang, Wolfgang Goeller,
Petter Reinholdtsen, Gary Plewa, Sebastien Sable, Mikael Magnusson Petter Reinholdtsen, Gary Plewa, Sebastien Sable, Mikael Magnusson,
and Kevin Charter Oliver Schwartz and Kevin Charter
This file is part of the SANE package. This file is part of the SANE package.
This program is free software; you can redistribute it and/or This program is free software; you can redistribute it and/or
@ -42,7 +42,7 @@
If you write modifications of your own for SANE, it is your choice If you write modifications of your own for SANE, it is your choice
whether to permit this exception to apply to your modifications. whether to permit this exception to apply to your modifications.
If you do not wish that, delete this exception notice. If you do not wish that, delete this exception notice.
This file is a component of the implementation of a backend for many This file is a component of the implementation of a backend for many
of the the AGFA SnapScan and Acer Vuego/Prisa flatbed scanners. */ of the the AGFA SnapScan and Acer Vuego/Prisa flatbed scanners. */
@ -58,13 +58,14 @@
#define DEFAULT_DEVICE "/dev/scanner" /* Check this if config is missing */ #define DEFAULT_DEVICE "/dev/scanner" /* Check this if config is missing */
#define SNAPSCAN_TYPE "flatbed scanner" #define SNAPSCAN_TYPE "flatbed scanner"
/*#define INOPERATIVE*/
#define TMP_FILE_PREFIX "/var/tmp/snapscan" #define TMP_FILE_PREFIX "/var/tmp/snapscan"
#define SNAPSCAN_CONFIG_FILE "snapscan.conf"
#define FIRMWARE_KW "firmware"
/* Define the colour channel order in arrays */ /* Define the colour channel order in arrays */
#define R_CHAN 0 #define R_CHAN 0
#define G_CHAN 1 #define G_CHAN 1
#define B_CHAN 2 #define B_CHAN 2
typedef enum typedef enum
{ {
@ -76,16 +77,21 @@ typedef enum
typedef enum typedef enum
{ {
UNKNOWN, UNKNOWN,
SNAPSCAN300, /* the original SnapScan or SnapScan 300 */ SNAPSCAN300, /* the original SnapScan or SnapScan 300 */
SNAPSCAN310, /* the SnapScan 310 */ SNAPSCAN310, /* the SnapScan 310 */
SNAPSCAN600, /* the SnapScan 600 */ SNAPSCAN600, /* the SnapScan 600 */
SNAPSCAN1236S, /* the SnapScan 1236s */ SNAPSCAN1236, /* the SnapScan 1236 */
SNAPSCAN1212U, SNAPSCAN1212U,
SNAPSCANE50, /* SnapScan e20/e40/e50 */ SNAPSCANE50, /* SnapScan e20/e40/e50 */
ACER300F, ACER300F,
VUEGO310S, /* Vuego-Version of SnapScan 310 WG changed */ VUEGO310S, /* Vuego-Version of SnapScan 310 WG changed */
VUEGO610S, /* Vuego 610S and 610plus SJU changed */ VUEGO610S, /* Vuego 610S and 610plus SJU changed */
PRISA620S /* Prisa-Version of SnapScan 600 GP added */ PRISA620S, /* Acer ScanPrisa 620 - 600 DPI */
PRISA640, /* Acer ScanPrisa 640 - 600 DPI */
PRISA4300, /* Acer ScanPrisa 3300/4300 - 600 DPI */
PRISA4300_2, /* Acer ScanPrisa 3300/4300 - 600 DPI */
PRISA1240, /* Acer ScanPrisa 1240 - 1200 DPI */
PRISA5300 /* Acer ScanPrisa 5300 - 1200 DPI */
} SnapScan_Model; } SnapScan_Model;
struct SnapScan_Model_desc struct SnapScan_Model_desc
{ {
@ -96,24 +102,31 @@ struct SnapScan_Model_desc
static struct SnapScan_Model_desc scanners[] = static struct SnapScan_Model_desc scanners[] =
{ {
/* SCSI model name -> enum value */ /* SCSI model name -> enum value */
{"FlatbedScanner_2", VUEGO610S}, {"FlatbedScanner_2", VUEGO610S},
{"FlatbedScanner_4", VUEGO310S}, {"FlatbedScanner_4", VUEGO310S},
{"FlatbedScanner_9", PRISA620S}, {"FlatbedScanner_5", PRISA620S},
{"FlatbedScanner13", PRISA620S}, {"FlatbedScanner_9", PRISA620S},
{"FlatbedScanner16", PRISA620S}, {"FlatbedScanner13", PRISA620S},
{"FlatbedScanner18", PRISA620S}, {"FlatbedScanner16", PRISA620S},
{"FlatbedScanner19", PRISA620S}, /* Acer ScanPrisa 1240UT */ {"FlatbedScanner17", PRISA620S},
{"FlatbedScanner20", PRISA620S}, {"FlatbedScanner18", PRISA620S},
{"SNAPSCAN 1212U", SNAPSCAN1212U}, {"FlatbedScanner19", PRISA1240},
{"SNAPSCAN 1212U_2", SNAPSCAN1212U}, {"FlatbedScanner20", PRISA640},
{"SNAPSCAN e20", SNAPSCANE50}, {"FlatbedScanner21", PRISA4300},
{"SNAPSCAN e50", SNAPSCANE50}, {"FlatbedScanner23", PRISA4300_2},
{"SNAPSCAN e40", SNAPSCANE50}, {"FlatbedScanner24", PRISA5300},
{"SNAPSCAN 1236", SNAPSCAN1236S}, {"SNAPSCAN 1212U", SNAPSCAN1212U},
{"SNAPSCAN 310", SNAPSCAN310}, {"SNAPSCAN 1212U_2", SNAPSCAN1212U},
{"SNAPSCAN 600", SNAPSCAN600}, {"SNAPSCAN e20", SNAPSCANE50},
{"SnapScan", SNAPSCAN300}, {"SNAPSCAN e50", SNAPSCANE50},
{"ACERSCAN_A4____1", ACER300F}, {"SNAPSCAN e40", SNAPSCANE50},
{"SNAPSCAN 1236", SNAPSCAN1236},
{"SNAPSCAN 1236U", SNAPSCAN1236},
{"SNAPSCAN 300", SNAPSCAN300},
{"SNAPSCAN 310", SNAPSCAN310},
{"SNAPSCAN 600", SNAPSCAN600},
{"SnapScan", SNAPSCAN300},
{"ACERSCAN_A4____1", ACER300F}
}; };
#define known_scanners ((int) (sizeof(scanners)/sizeof(scanners[0]))) #define known_scanners ((int) (sizeof(scanners)/sizeof(scanners[0])))
@ -122,52 +135,53 @@ static char *vendors[] =
/* SCSI Vendor name */ /* SCSI Vendor name */
"AGFA", "AGFA",
"COLOR", "COLOR",
"Color",
"ACERPER" "ACERPER"
}; };
#define known_vendors ((int) (sizeof(vendors)/sizeof(vendors[0]))) #define known_vendors ((int) (sizeof(vendors)/sizeof(vendors[0])))
typedef enum typedef enum
{ {
OPT_COUNT = 0, /* option count */ OPT_COUNT = 0, /* option count */
OPT_MODE_GROUP, /* scan mode group */ OPT_MODE_GROUP, /* scan mode group */
OPT_SCANRES, /* scan resolution */ OPT_SCANRES, /* scan resolution */
OPT_PREVIEW, /* preview mode toggle */ OPT_PREVIEW, /* preview mode toggle */
OPT_MODE, /* scan mode */ OPT_MODE, /* scan mode */
OPT_PREVIEW_MODE, /* preview mode */ OPT_PREVIEW_MODE, /* preview mode */
OPT_SOURCE, /* scan source (flatbed / TPO) */ OPT_SOURCE, /* scan source (flatbed / TPO) */
OPT_GEOMETRY_GROUP, /* geometry group */ OPT_GEOMETRY_GROUP, /* geometry group */
OPT_TLX, /* top left x */ OPT_TLX, /* top left x */
OPT_TLY, /* top left y */ OPT_TLY, /* top left y */
OPT_BRX, /* bottom right x */ OPT_BRX, /* bottom right x */
OPT_BRY, /* bottom right y */ OPT_BRY, /* bottom right y */
OPT_PREDEF_WINDOW, /* predefined window configuration */ OPT_PREDEF_WINDOW, /* predefined window configuration */
OPT_ENHANCEMENT_GROUP, /* enhancement group */ OPT_ENHANCEMENT_GROUP, /* enhancement group */
OPT_QUALITY_CAL, /* quality calibration */ OPT_QUALITY_CAL, /* quality calibration */
OPT_HALFTONE, /* halftone flag */ OPT_HALFTONE, /* halftone flag */
OPT_HALFTONE_PATTERN, /* halftone matrix */ OPT_HALFTONE_PATTERN, /* halftone matrix */
OPT_CUSTOM_GAMMA, /* use custom gamma tables */ OPT_CUSTOM_GAMMA, /* use custom gamma tables */
OPT_GAMMA_BIND, OPT_GAMMA_BIND,
OPT_GAMMA_GS, /* gamma correction (greyscale) */ OPT_GAMMA_GS, /* gamma correction (greyscale) */
OPT_GAMMA_R, /* gamma correction (red) */ OPT_GAMMA_R, /* gamma correction (red) */
OPT_GAMMA_G, /* gamma correction (green) */ OPT_GAMMA_G, /* gamma correction (green) */
OPT_GAMMA_B, /* gamma correction (blue) */ OPT_GAMMA_B, /* gamma correction (blue) */
OPT_GAMMA_VECTOR_GS, /* gamma correction vector (greyscale) */ OPT_GAMMA_VECTOR_GS, /* gamma correction vector (greyscale) */
OPT_GAMMA_VECTOR_R, /* gamma correction vector (red) */ OPT_GAMMA_VECTOR_R, /* gamma correction vector (red) */
OPT_GAMMA_VECTOR_G, /* gamma correction vector (green) */ OPT_GAMMA_VECTOR_G, /* gamma correction vector (green) */
OPT_GAMMA_VECTOR_B, /* gamma correction vector (blue) */ OPT_GAMMA_VECTOR_B, /* gamma correction vector (blue) */
OPT_NEGATIVE, /* swap black and white */ OPT_NEGATIVE, /* swap black and white */
OPT_THRESHOLD, /* threshold for line art */ OPT_THRESHOLD, /* threshold for line art */
OPT_BRIGHTNESS, /* brightness */ OPT_BRIGHTNESS, /* brightness */
OPT_CONTRAST, /* contrast */ OPT_CONTRAST, /* contrast */
OPT_ADVANCED_GROUP, /* advanced group */ OPT_ADVANCED_GROUP, /* advanced group */
OPT_RGB_LPR, /* lines per scsi read (RGB) */ OPT_RGB_LPR, /* lines per scsi read (RGB) */
OPT_GS_LPR, /* lines per scsi read (GS) */ OPT_GS_LPR, /* lines per scsi read (GS) */
OPT_SCSI_CMDS, /* a group */ OPT_SCSI_CMDS, /* a group */
OPT_INQUIRY, /* inquiry command (button) */ OPT_INQUIRY, /* inquiry command (button) */
OPT_SELF_TEST, /* self test command (button) */ OPT_SELF_TEST, /* self test command (button) */
OPT_REQ_SENSE, /* request sense command (button) */ OPT_REQ_SENSE, /* request sense command (button) */
OPT_REL_UNIT, /* release unit command (button) */ OPT_REL_UNIT, /* release unit command (button) */
NUM_OPTS /* dummy (gives number of options) */ NUM_OPTS /* dummy (gives number of options) */
} SnapScan_Options; } SnapScan_Options;
typedef union typedef union
@ -181,41 +195,41 @@ Option_Value;
typedef enum typedef enum
{ {
MD_COLOUR = 0, /* full colour */ MD_COLOUR = 0, /* full colour */
MD_BILEVELCOLOUR, /* 1-bit per channel colour */ MD_BILEVELCOLOUR, /* 1-bit per channel colour */
MD_GREYSCALE, /* grey scale */ MD_GREYSCALE, /* grey scale */
MD_LINEART, /* black and white */ MD_LINEART, /* black and white */
MD_NUM_MODES MD_NUM_MODES
} SnapScan_Mode; } SnapScan_Mode;
typedef enum typedef enum
{ {
SRC_FLATBED = 0, /* Flatbed (normal) */ SRC_FLATBED = 0, /* Flatbed (normal) */
SRC_TPO /* Transparency unit */ SRC_TPO /* Transparency unit */
} SnapScan_Source; } SnapScan_Source;
typedef enum typedef enum
{ {
ST_IDLE, /* between scans */ ST_IDLE, /* between scans */
ST_SCAN_INIT, /* scan initialization */ ST_SCAN_INIT, /* scan initialization */
ST_SCANNING, /* actively scanning data */ ST_SCANNING, /* actively scanning data */
ST_CANCEL_INIT /* cancellation begun */ ST_CANCEL_INIT /* cancellation begun */
} SnapScan_State; } SnapScan_State;
typedef struct snapscan_device typedef struct snapscan_device
{ {
SANE_Device dev; SANE_Device dev;
SANE_Range x_range; /* x dimension of scan area */ SANE_Range x_range; /* x dimension of scan area */
SANE_Range y_range; /* y dimension of scan area */ SANE_Range y_range; /* y dimension of scan area */
SnapScan_Model model; /* type of scanner */ SnapScan_Model model; /* type of scanner */
SnapScan_Bus bus; /* bus of the device usb/scsi */ SnapScan_Bus bus; /* bus of the device usb/scsi */
u_char *depths; /* bit depth table */ u_char *depths; /* bit depth table */
struct snapscan_device *pnext; struct snapscan_device *pnext;
} }
SnapScan_Device; SnapScan_Device;
#define MAX_SCSI_CMD_LEN 256 /* not that large */ #define MAX_SCSI_CMD_LEN 256 /* not that large */
#define SCANNER_BUF_SZ 31744 #define DEFAULT_SCANNER_BUF_SZ 1024*63
typedef struct snapscan_scanner SnapScan_Scanner; typedef struct snapscan_scanner SnapScan_Scanner;
@ -223,81 +237,107 @@ typedef struct snapscan_scanner SnapScan_Scanner;
struct snapscan_scanner struct snapscan_scanner
{ {
SANE_String devname; /* the scsi device name */ SANE_String devname; /* the scsi device name */
SnapScan_Device *pdev; /* the device */ SnapScan_Device *pdev; /* the device */
int fd; /* scsi file descriptor */ int fd; /* scsi file descriptor */
int opens; /* open count */ int opens; /* open count */
SANE_String tmpfname; /* temporary file name */ SANE_String tmpfname; /* temporary file name */
int tfd; /* temp file descriptor */ int tfd; /* temp file descriptor */
int rpipe[2]; /* reader pipe descriptors */ int rpipe[2]; /* reader pipe descriptors */
int orig_rpipe_flags; /* initial reader pipe flags */ int orig_rpipe_flags; /* initial reader pipe flags */
pid_t child; /* child reader process pid */ pid_t child; /* child reader process pid */
SnapScan_Mode mode; /* mode */ SnapScan_Mode mode; /* mode */
SnapScan_Mode preview_mode; /* preview mode */ SnapScan_Mode preview_mode; /* preview mode */
SnapScan_Source source; /* scanning source */ SnapScan_Source source; /* scanning source */
SnapScan_State state; /* scanner state */ SnapScan_State state; /* scanner state */
u_char cmd[MAX_SCSI_CMD_LEN]; /* scsi command buffer */ u_char cmd[MAX_SCSI_CMD_LEN]; /* scsi command buffer */
u_char buf[SCANNER_BUF_SZ]; /* data buffer */ u_char *buf; /* data buffer */
size_t buf_sz; /* effective buffer size */ size_t phys_buf_sz; /* physical buffer size */
size_t expected_read_bytes; /* expected amount of data in a single read */ size_t buf_sz; /* effective buffer size */
size_t read_bytes; /* amount of actual data read */ size_t expected_read_bytes; /* expected amount of data in a single read */
size_t bytes_remaining; /* remaining bytes expected from scanner */ size_t read_bytes; /* amount of actual data read */
size_t actual_res; /* actual resolution */ size_t bytes_remaining; /* remaining bytes expected from scanner */
size_t lines; /* number of scan lines */ size_t actual_res; /* actual resolution */
size_t bytes_per_line; /* bytes per scan line */ size_t lines; /* number of scan lines */
size_t pixels_per_line; /* pixels per scan line */ size_t bytes_per_line; /* bytes per scan line */
u_char hconfig; /* hardware configuration byte */ size_t pixels_per_line; /* pixels per scan line */
float ms_per_line; /* speed: milliseconds per scan line */ u_char hconfig; /* hardware configuration byte */
SANE_Bool nonblocking; /* wait on reads for data? */ float ms_per_line; /* speed: milliseconds per scan line */
char *sense_str; /* sense string */ SANE_Bool nonblocking; /* wait on reads for data? */
char *as_str; /* additional sense string */ char *sense_str; /* sense string */
u_char asi1; /* first additional sense info byte */ char *as_str; /* additional sense string */
u_char asi2; /* second additional sense info byte */ u_char asi1; /* first additional sense info byte */
SANE_Byte chroma_offset[3]; /* chroma offsets */ u_char asi2; /* second additional sense info byte */
Source *psrc; /* data source */ SANE_Byte chroma_offset[3]; /* chroma offsets */
SANE_Int chroma;
Source *psrc; /* data source */
SANE_Option_Descriptor SANE_Option_Descriptor
options[NUM_OPTS]; /* the option descriptors */ options[NUM_OPTS]; /* the option descriptors */
Option_Value val[NUM_OPTS]; Option_Value val[NUM_OPTS];
/* the options themselves... */ /* the options themselves... */
SANE_Int res; /* resolution */ SANE_Int res; /* resolution */
SANE_Bool preview; /* preview mode toggle */ SANE_Bool preview; /* preview mode toggle */
SANE_String mode_s; /* scanning mode */ SANE_String mode_s; /* scanning mode */
SANE_String source_s; /* scanning source */ SANE_String source_s; /* scanning source */
SANE_String preview_mode_s; /* scanning mode for preview */ SANE_String preview_mode_s; /* scanning mode for preview */
SANE_Fixed tlx; /* window top left x */ SANE_Fixed tlx; /* window top left x */
SANE_Fixed tly; /* window top left y */ SANE_Fixed tly; /* window top left y */
SANE_Fixed brx; /* window bottom right x */ SANE_Fixed brx; /* window bottom right x */
SANE_Fixed bry; /* window bottom right y */ SANE_Fixed bry; /* window bottom right y */
int bright; /* brightness */ int bright; /* brightness */
int contrast; /* contrast */ int contrast; /* contrast */
SANE_String predef_window; /* predefined window name */ SANE_String predef_window; /* predefined window name */
SANE_Fixed gamma_gs; /* gamma correction value (greyscale) */ SANE_Fixed gamma_gs; /* gamma correction value (greyscale) */
SANE_Fixed gamma_r; /* gamma correction value (red) */ SANE_Fixed gamma_r; /* gamma correction value (red) */
SANE_Fixed gamma_g; /* gamma correction value (green) */ SANE_Fixed gamma_g; /* gamma correction value (green) */
SANE_Fixed gamma_b; /* gamma correction value (blue) */ SANE_Fixed gamma_b; /* gamma correction value (blue) */
SANE_Int *gamma_tables; /* gamma correction vectors */ SANE_Int *gamma_tables; /* gamma correction vectors */
SANE_Int *gamma_table_gs; /* gamma correction vector (greyscale) */ SANE_Int *gamma_table_gs; /* gamma correction vector (greyscale) */
SANE_Int *gamma_table_r; /* gamma correction vector (red) */ SANE_Int *gamma_table_r; /* gamma correction vector (red) */
SANE_Int *gamma_table_g; /* gamma correction vector (green) */ SANE_Int *gamma_table_g; /* gamma correction vector (green) */
SANE_Int *gamma_table_b; /* gamma correction vector (blue) */ SANE_Int *gamma_table_b; /* gamma correction vector (blue) */
int gamma_length; /* length of gamma vectors */ int gamma_length; /* length of gamma vectors */
SANE_Bool halftone; /* halftone toggle */ SANE_Bool halftone; /* halftone toggle */
SANE_String dither_matrix; /* the halftone dither matrix */ SANE_String dither_matrix; /* the halftone dither matrix */
SANE_Bool negative; /* swap black and white */ SANE_Bool negative; /* swap black and white */
SANE_Int threshold; /* threshold for line art */ SANE_Int threshold; /* threshold for line art */
SANE_Int rgb_lpr; /* lines per scsi read (RGB) */ SANE_Int rgb_lpr; /* lines per scsi read (RGB) */
SANE_Int gs_lpr; /* lines per scsi read (greyscale) */ SANE_Int gs_lpr; /* lines per scsi read (greyscale) */
}; };
#endif #endif
/* /*
* $Log$ * $Log$
* Revision 1.4 2001/05/26 12:47:34 hmg * Revision 1.5 2001/10/09 09:45:21 oliverschwartz
* Updated snapscan backend to version 1.2 (from * update snapscan to snapshot 20011008
* Sebastien Sable <Sebastien.Sable@snv.jussieu.fr>). *
* Henning Meier-Geinitz <henning@meier-geinitz.de> * Revision 1.17 2001/10/08 18:22:02 oliverschwartz
* - Disable quality calibration for Acer Vuego 310F
* - Use sanei_scsi_max_request_size as scanner buffer size
* for SCSI devices
* - Added new devices to snapscan.desc
*
* Revision 1.16 2001/09/28 13:39:16 oliverschwartz
* - Added "Snapscan 300" ID string
* - cleanup
* - more debugging messages in snapscan-sources.c
*
* Revision 1.15 2001/09/18 15:01:07 oliverschwartz
* - Read scanner id string again after firmware upload
* to indentify correct model
* - Make firmware upload work for AGFA scanners
* - Change copyright notice
*
* Revision 1.14 2001/09/17 10:01:08 sable
* Added model AGFA 1236U
*
* Revision 1.13 2001/09/09 20:39:52 oliverschwartz
* add identification for 620ST+
*
* Revision 1.12 2001/09/09 18:06:32 oliverschwartz
* add changes from Acer (new models; automatic firmware upload for USB scanners); fix distorted colour scans after greyscale scans (call set_window only in sane_start); code cleanup
* *
* Revision 1.11 2001/04/10 12:38:21 sable * Revision 1.11 2001/04/10 12:38:21 sable
* Adding e20 support thanks to Steffen Hübner * Adding e20 support thanks to Steffen Hübner