kopia lustrzana https://gitlab.com/sane-project/backends
update snapscan to snapshot 20011008
rodzic
e4db2d172b
commit
010db1ed52
Plik diff jest za duży
Load Diff
|
@ -1,47 +1,48 @@
|
|||
/* sane - Scanner Access Now Easy.
|
||||
|
||||
|
||||
Copyright (C) 1997, 1998 Franck Schnefra, Michel Roelofs,
|
||||
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 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.
|
||||
|
||||
|
||||
As a special exception, the authors of SANE give permission for
|
||||
additional uses of the libraries contained in this release of SANE.
|
||||
|
||||
|
||||
The exception is that, if you link a SANE library with other files
|
||||
to produce an executable, this does not by itself cause the
|
||||
resulting executable to be covered by the GNU General Public
|
||||
License. Your use of that executable is in no way restricted on
|
||||
account of linking the SANE library code into it.
|
||||
|
||||
|
||||
This exception does not, however, invalidate any other reasons why
|
||||
the executable file might be covered by the GNU General Public
|
||||
License.
|
||||
|
||||
|
||||
If you submit changes to SANE to the maintainers to be included in
|
||||
a subsequent release, you agree by submitting the changes that
|
||||
those changes may be distributed with this exception intact.
|
||||
|
||||
|
||||
If you write modifications of your own for SANE, it is your choice
|
||||
whether to permit this exception to apply to your modifications.
|
||||
If you do not wish that, delete this exception notice.
|
||||
|
||||
|
||||
This file is a component of the implementation of a backend for many
|
||||
of the the AGFA SnapScan and Acer Vuego/Prisa flatbed scanners. */
|
||||
|
||||
|
@ -92,15 +93,13 @@ typedef enum
|
|||
BUF_SRC
|
||||
} BaseSourceType;
|
||||
|
||||
#define SCSISOURCE_BAD_TIME -1
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SOURCE_GUTS;
|
||||
SANE_Int scsi_buf_pos; /* current position in scsi buffer */
|
||||
SANE_Int scsi_buf_max; /* data limit */
|
||||
SANE_Int absolute_max; /* largest possible data read */
|
||||
struct timeval time; /* time of last scsi read (usec) */
|
||||
SANE_Int scsi_buf_pos; /* current position in scsi buffer */
|
||||
SANE_Int scsi_buf_max; /* data limit */
|
||||
SANE_Int absolute_max; /* largest possible data read */
|
||||
} SCSISource;
|
||||
|
||||
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,
|
||||
SANE_Byte *pbuf,
|
||||
SANE_Int *plen)
|
||||
SANE_Int *plen)
|
||||
{
|
||||
SCSISource *ps = (SCSISource *) pself;
|
||||
SANE_Status status = SANE_STATUS_GOOD;
|
||||
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
|
||||
&&
|
||||
pself->remaining(pself) > 0
|
||||
&&
|
||||
status == SANE_STATUS_GOOD)
|
||||
&& pself->remaining(pself) > 0
|
||||
&& status == SANE_STATUS_GOOD)
|
||||
{
|
||||
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)
|
||||
{
|
||||
/* read more data */
|
||||
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 */
|
||||
ps->pss->expected_read_bytes = ps->absolute_max;
|
||||
/*
|
||||
SANE_Int lines;
|
||||
|
||||
if (is_colour_mode(actual_mode(ps->pss)) == SANE_TRUE)
|
||||
|
@ -181,11 +135,9 @@ static SANE_Status SCSISource_get (Source *pself,
|
|||
else
|
||||
lines = ps->pss->gs_lpr;
|
||||
ps->pss->expected_read_bytes = lines * ps->pss->bytes_per_line;
|
||||
}
|
||||
*/
|
||||
ps->pss->expected_read_bytes = MIN(ps->pss->expected_read_bytes,
|
||||
ps->pss->bytes_remaining);
|
||||
ps->pss->expected_read_bytes = MIN(ps->pss->expected_read_bytes,
|
||||
(size_t) ps->absolute_max);
|
||||
ps->pss->bytes_remaining);
|
||||
ps->scsi_buf_pos = 0;
|
||||
ps->scsi_buf_max = 0;
|
||||
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;
|
||||
ndata = 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);
|
||||
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)
|
||||
{
|
||||
DBG(DL_MINOR_INFO, "SCSISource_done\n");
|
||||
UNREFERENCED_PARAMETER(pself);
|
||||
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,
|
||||
SCSISource_remaining,
|
||||
Source_bytesPerLine,
|
||||
Source_pixelsPerLine,
|
||||
Source_pixelsPerLine,
|
||||
SCSISource_get,
|
||||
SCSISource_done);
|
||||
SCSISource_done);
|
||||
if (status == SANE_STATUS_GOOD)
|
||||
{
|
||||
pself->scsi_buf_max = 0;
|
||||
pself->scsi_buf_pos = 0;
|
||||
pself->absolute_max =
|
||||
(SCANNER_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;
|
||||
}
|
||||
(pss->phys_buf_sz/pss->bytes_per_line)*pss->bytes_per_line;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
@ -258,35 +205,32 @@ static SANE_Status FDSource_get (Source *pself, SANE_Byte *pbuf, SANE_Int *plen)
|
|||
SANE_Int remaining = *plen;
|
||||
|
||||
while (remaining > 0
|
||||
&&
|
||||
pself->remaining(pself) > 0
|
||||
&&
|
||||
status == SANE_STATUS_GOOD)
|
||||
&& pself->remaining(pself) > 0
|
||||
&& status == SANE_STATUS_GOOD)
|
||||
{
|
||||
SANE_Int bytes_read = read (ps->fd, pbuf, remaining);
|
||||
if (bytes_read == -1)
|
||||
{
|
||||
if (errno == EAGAIN)
|
||||
{
|
||||
{
|
||||
/* No data currently available */
|
||||
break;
|
||||
}
|
||||
/* It's an IO error */
|
||||
DBG (DL_MAJOR_ERROR,
|
||||
"%s: read failed: %s\n",
|
||||
__FUNCTION__,
|
||||
strerror(errno));
|
||||
/* It's an IO error */
|
||||
DBG (DL_MAJOR_ERROR, "%s: read failed: %s\n",
|
||||
__FUNCTION__, strerror(errno));
|
||||
status = SANE_STATUS_IO_ERROR;
|
||||
}
|
||||
else if (bytes_read == 0)
|
||||
{
|
||||
{
|
||||
/* EOF of current reading */
|
||||
DBG(DL_DATA_TRACE, "%s: EOF\n",__FUNCTION__);
|
||||
break;
|
||||
}
|
||||
}
|
||||
ps->pss->bytes_remaining -= bytes_read;
|
||||
remaining -= bytes_read;
|
||||
pbuf += bytes_read;
|
||||
}
|
||||
|
||||
*plen -= remaining;
|
||||
return status;
|
||||
}
|
||||
|
@ -299,15 +243,15 @@ static SANE_Status FDSource_done (Source *pself)
|
|||
|
||||
static SANE_Status FDSource_init (FDSource *pself,
|
||||
SnapScan_Scanner *pss,
|
||||
int fd)
|
||||
int fd)
|
||||
{
|
||||
SANE_Status status = Source_init ((Source *) pself,
|
||||
pss,
|
||||
FDSource_remaining,
|
||||
Source_bytesPerLine,
|
||||
Source_pixelsPerLine,
|
||||
Source_pixelsPerLine,
|
||||
FDSource_get,
|
||||
FDSource_done);
|
||||
FDSource_done);
|
||||
if (status == SANE_STATUS_GOOD)
|
||||
pself->fd = fd;
|
||||
return status;
|
||||
|
@ -339,7 +283,6 @@ 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;
|
||||
|
@ -361,16 +304,17 @@ static SANE_Status BufSource_done (Source *pself)
|
|||
|
||||
static SANE_Status BufSource_init (BufSource *pself,
|
||||
SnapScan_Scanner *pss,
|
||||
SANE_Byte *buf,
|
||||
SANE_Int buf_size)
|
||||
SANE_Byte *buf,
|
||||
SANE_Int buf_size)
|
||||
{
|
||||
SANE_Status status = Source_init ((Source *) pself,
|
||||
pss,
|
||||
pss,
|
||||
BufSource_remaining,
|
||||
Source_bytesPerLine,
|
||||
Source_pixelsPerLine,
|
||||
Source_pixelsPerLine,
|
||||
BufSource_get,
|
||||
BufSource_done);
|
||||
BufSource_done);
|
||||
DBG(DL_DATA_TRACE, "BufSource_init: buf_size=%d\n", buf_size);
|
||||
if (status == SANE_STATUS_GOOD)
|
||||
{
|
||||
pself->buf = buf;
|
||||
|
@ -398,10 +342,10 @@ static SANE_Status create_base_source (SnapScan_Scanner *pss,
|
|||
status = SANE_STATUS_NO_MEM;
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
status = SCSISource_init ((SCSISource *) *pps, pss);
|
||||
}
|
||||
break;
|
||||
break;
|
||||
case FD_SRC:
|
||||
*pps = (Source *) malloc(sizeof(FDSource));
|
||||
if (*pps == NULL)
|
||||
|
@ -410,10 +354,10 @@ static SANE_Status create_base_source (SnapScan_Scanner *pss,
|
|||
status = SANE_STATUS_NO_MEM;
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
status = FDSource_init ((FDSource *) *pps, pss, pss->rpipe[0]);
|
||||
}
|
||||
break;
|
||||
break;
|
||||
case BUF_SRC:
|
||||
*pps = (Source *) malloc(sizeof(BufSource));
|
||||
if (*pps == NULL)
|
||||
|
@ -422,13 +366,13 @@ static SANE_Status create_base_source (SnapScan_Scanner *pss,
|
|||
status = SANE_STATUS_NO_MEM;
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
status = BufSource_init ((BufSource *) *pps,
|
||||
pss,
|
||||
pss->buf,
|
||||
pss->read_bytes);
|
||||
}
|
||||
break;
|
||||
break;
|
||||
default:
|
||||
DBG (DL_MAJOR_ERROR, "illegal base source type %d", st);
|
||||
break;
|
||||
|
@ -441,8 +385,8 @@ static SANE_Status create_base_source (SnapScan_Scanner *pss,
|
|||
/* The transformer sources */
|
||||
|
||||
#define TX_SOURCE_GUTS \
|
||||
SOURCE_GUTS;\
|
||||
Source *psub /* sub-source */
|
||||
SOURCE_GUTS;\
|
||||
Source *psub /* sub-source */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
@ -488,16 +432,16 @@ static SANE_Status TxSource_init (TxSource *pself,
|
|||
SourceBytesPerLine bytesPerLine,
|
||||
SourcePixelsPerLine pixelsPerLine,
|
||||
SourceGet get,
|
||||
SourceDone done,
|
||||
Source *psub)
|
||||
SourceDone done,
|
||||
Source *psub)
|
||||
{
|
||||
SANE_Status status = Source_init((Source *) pself,
|
||||
pss,
|
||||
pss,
|
||||
remaining,
|
||||
bytesPerLine,
|
||||
bytesPerLine,
|
||||
pixelsPerLine,
|
||||
get,
|
||||
done);
|
||||
done);
|
||||
if (status == SANE_STATUS_GOOD)
|
||||
pself->psub = psub;
|
||||
return status;
|
||||
|
@ -509,13 +453,13 @@ static SANE_Status TxSource_init (TxSource *pself,
|
|||
typedef struct
|
||||
{
|
||||
TX_SOURCE_GUTS;
|
||||
SANE_Byte *ch_buf; /* channel buffer */
|
||||
SANE_Int ch_size; /* channel buffer size = #bytes in a channel */
|
||||
SANE_Int ch_ndata; /* actual #bytes in channel buffer */
|
||||
SANE_Int ch_pos; /* position in buffer */
|
||||
SANE_Int bit; /* current bit */
|
||||
SANE_Int last_bit; /* current last bit (counting down) */
|
||||
SANE_Int last_last_bit; /* last bit in the last byte of the channel */
|
||||
SANE_Byte *ch_buf; /* channel buffer */
|
||||
SANE_Int ch_size; /* channel buffer size = #bytes in a channel */
|
||||
SANE_Int ch_ndata; /* actual #bytes in channel buffer */
|
||||
SANE_Int ch_pos; /* position in buffer */
|
||||
SANE_Int bit; /* current bit */
|
||||
SANE_Int last_bit; /* current last bit (counting down) */
|
||||
SANE_Int last_last_bit; /* last bit in the last byte of the channel */
|
||||
} Expander;
|
||||
|
||||
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;
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
ps->bit--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*plen -= remaining;
|
||||
|
@ -608,8 +552,8 @@ static SANE_Status Expander_done (Source *pself)
|
|||
}
|
||||
|
||||
static SANE_Status Expander_init (Expander *pself,
|
||||
SnapScan_Scanner *pss,
|
||||
Source *psub)
|
||||
SnapScan_Scanner *pss,
|
||||
Source *psub)
|
||||
{
|
||||
SANE_Status status = TxSource_init((TxSource *) pself,
|
||||
pss,
|
||||
|
@ -626,7 +570,7 @@ static SANE_Status Expander_init (Expander *pself,
|
|||
if (pself->ch_buf == NULL)
|
||||
{
|
||||
DBG (DL_MAJOR_ERROR,
|
||||
"%s: couldn't allocate channel buffer.\n",
|
||||
"%s: couldn't allocate channel buffer.\n",
|
||||
__FUNCTION__);
|
||||
status = SANE_STATUS_NO_MEM;
|
||||
}
|
||||
|
@ -650,14 +594,14 @@ static SANE_Status Expander_init (Expander *pself,
|
|||
|
||||
static SANE_Status create_Expander (SnapScan_Scanner *pss,
|
||||
Source *psub,
|
||||
Source **pps)
|
||||
Source **pps)
|
||||
{
|
||||
SANE_Status status = SANE_STATUS_GOOD;
|
||||
*pps = (Source *) malloc(sizeof(Expander));
|
||||
if (*pps == NULL)
|
||||
{
|
||||
DBG (DL_MAJOR_ERROR,
|
||||
"%s: failed to allocate Expander.\n",
|
||||
"%s: failed to allocate Expander.\n",
|
||||
__FUNCTION__);
|
||||
status = SANE_STATUS_NO_MEM;
|
||||
}
|
||||
|
@ -675,44 +619,27 @@ static SANE_Status create_Expander (SnapScan_Scanner *pss,
|
|||
typedef struct
|
||||
{
|
||||
TX_SOURCE_GUTS;
|
||||
SANE_Byte *cbuf; /* circular line buffer */
|
||||
SANE_Byte *xbuf; /* single line buffer */
|
||||
SANE_Int pos; /* current position in xbuf */
|
||||
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_start; /* start of valid data in the circular buffer */
|
||||
SANE_Int ch_offset[3]; /* offset in cbuf */
|
||||
SANE_Byte *cbuf; /* circular line buffer */
|
||||
SANE_Byte *xbuf; /* single line buffer */
|
||||
SANE_Int pos; /* current position in xbuf */
|
||||
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_start; /* start of valid data in the circular buffer */
|
||||
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;
|
||||
|
||||
static SANE_Int RGBRouter_remaining (Source *pself)
|
||||
{
|
||||
RGBRouter *ps = (RGBRouter *) pself;
|
||||
SANE_Int remaining;
|
||||
|
||||
if (ps->cb_start < 0)
|
||||
remaining = (TxSource_remaining(pself) - ps->cb_size + ps->cb_line_size);
|
||||
SANE_Int remaining;
|
||||
if (ps->round_req == ps->cb_size)
|
||||
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);
|
||||
remaining = TxSource_remaining(pself) + ps->cb_line_size - ps->pos;
|
||||
return (remaining);
|
||||
}
|
||||
|
||||
static SANE_Status RGBRouter_get (Source *pself,
|
||||
|
@ -724,60 +651,76 @@ static SANE_Status RGBRouter_get (Source *pself,
|
|||
SANE_Int remaining = *plen;
|
||||
SANE_Byte *s;
|
||||
SANE_Int i;
|
||||
SANE_Int r;
|
||||
SANE_Int g;
|
||||
SANE_Int b;
|
||||
SANE_Int r, g, b;
|
||||
SANE_Int run_req;
|
||||
SANE_Int org_len = *plen;
|
||||
char *me = "RGBRouter_get";
|
||||
|
||||
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)
|
||||
{
|
||||
/* Try to get more data */
|
||||
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;
|
||||
/* Try to get more data. either one line or
|
||||
full buffer (first time) */
|
||||
do
|
||||
{
|
||||
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;
|
||||
ndata3 = 0;
|
||||
do
|
||||
{
|
||||
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;
|
||||
}
|
||||
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;
|
||||
/* route RGB */
|
||||
ps->cb_start = (ps->cb_start + ps->round_read)%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++)
|
||||
{
|
||||
*s++ = ps->cbuf[r++];
|
||||
*s++ = ps->cbuf[g++];
|
||||
*s++ = ps->cbuf[b++];
|
||||
}
|
||||
ps->pos = 0;
|
||||
{
|
||||
*s++ = ps->cbuf[r++];
|
||||
*s++ = ps->cbuf[g++];
|
||||
*s++ = ps->cbuf[b++];
|
||||
}
|
||||
|
||||
/* 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++];
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -795,35 +738,31 @@ static SANE_Status RGBRouter_done (Source *pself)
|
|||
}
|
||||
|
||||
static SANE_Status RGBRouter_init (RGBRouter *pself,
|
||||
SnapScan_Scanner *pss,
|
||||
Source *psub)
|
||||
SnapScan_Scanner *pss,
|
||||
Source *psub)
|
||||
{
|
||||
SANE_Status status = TxSource_init((TxSource *) pself,
|
||||
pss,
|
||||
RGBRouter_remaining,
|
||||
TxSource_bytesPerLine,
|
||||
TxSource_pixelsPerLine,
|
||||
TxSource_pixelsPerLine,
|
||||
RGBRouter_get,
|
||||
RGBRouter_done,
|
||||
psub);
|
||||
RGBRouter_done,
|
||||
psub);
|
||||
if (status == SANE_STATUS_GOOD)
|
||||
{
|
||||
SANE_Int lines_in_buffer = 1;
|
||||
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++;
|
||||
SANE_Int lines_in_buffer = 0;
|
||||
|
||||
/* 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_size = pself->cb_line_size*lines_in_buffer;
|
||||
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->xbuf = (SANE_Byte *) malloc(pself->cb_line_size);
|
||||
if (pself->cbuf == NULL || pself->xbuf == NULL)
|
||||
|
@ -837,27 +776,34 @@ static SANE_Status RGBRouter_init (RGBRouter *pself,
|
|||
{
|
||||
SANE_Int ch;
|
||||
|
||||
pself->cb_start = -1;
|
||||
pself->cb_start = 0;
|
||||
for (ch = 0; ch < 3; ch++)
|
||||
{
|
||||
pself->ch_offset[ch] = pss->chroma_offset[ch]*pself->bytesPerLine((Source *) pself)
|
||||
+ ch*(pself->bytesPerLine((Source *) pself)/3);
|
||||
pself->ch_offset[ch] =
|
||||
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;
|
||||
}
|
||||
|
||||
static SANE_Status create_RGBRouter (SnapScan_Scanner *pss,
|
||||
Source *psub,
|
||||
Source **pps)
|
||||
Source **pps)
|
||||
{
|
||||
static char me[] = "create_RGBRouter";
|
||||
SANE_Status status = SANE_STATUS_GOOD;
|
||||
|
||||
DBG (DL_CALL_TRACE, "%s\n", me);
|
||||
*pps = (Source *) malloc(sizeof(RGBRouter));
|
||||
if (*pps == NULL)
|
||||
{
|
||||
DBG (DL_MAJOR_ERROR,
|
||||
"%s: failed to allocate RGBRouter.\n",
|
||||
DBG (DL_MAJOR_ERROR, "%s: failed to allocate RGBRouter.\n",
|
||||
__FUNCTION__);
|
||||
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)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < *plen; i++)
|
||||
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,
|
||||
SnapScan_Scanner *pss,
|
||||
Source *psub)
|
||||
Source *psub)
|
||||
{
|
||||
return TxSource_init ((TxSource *) pself,
|
||||
pss,
|
||||
TxSource_remaining,
|
||||
TxSource_bytesPerLine,
|
||||
TxSource_pixelsPerLine,
|
||||
TxSource_pixelsPerLine,
|
||||
Inverter_get,
|
||||
TxSource_done,
|
||||
psub);
|
||||
TxSource_done,
|
||||
psub);
|
||||
}
|
||||
|
||||
static SANE_Status create_Inverter (SnapScan_Scanner *pss,
|
||||
Source *psub,
|
||||
Source **pps)
|
||||
Source **pps)
|
||||
{
|
||||
SANE_Status status = SANE_STATUS_GOOD;
|
||||
*pps = (Source *) malloc(sizeof(Inverter));
|
||||
if (*pps == NULL)
|
||||
{
|
||||
DBG (DL_MAJOR_ERROR,
|
||||
"%s: failed to allocate Inverter.\n",
|
||||
__FUNCTION__);
|
||||
DBG (DL_MAJOR_ERROR, "%s: failed to allocate Inverter.\n",
|
||||
__FUNCTION__);
|
||||
status = SANE_STATUS_NO_MEM;
|
||||
}
|
||||
else
|
||||
|
@ -926,9 +870,12 @@ static SANE_Status create_Inverter (SnapScan_Scanner *pss,
|
|||
|
||||
static SANE_Status create_source_chain (SnapScan_Scanner *pss,
|
||||
BaseSourceType bst,
|
||||
Source **pps)
|
||||
Source **pps)
|
||||
{
|
||||
static char me[] = "create_source_chain";
|
||||
SANE_Status status = create_base_source (pss, bst, pps);
|
||||
|
||||
DBG (DL_CALL_TRACE, "%s\n", me);
|
||||
if (status == SANE_STATUS_GOOD)
|
||||
{
|
||||
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);
|
||||
break;
|
||||
default:
|
||||
DBG (DL_MAJOR_ERROR,
|
||||
"%s: bad mode value %d (internal error)\n",
|
||||
__FUNCTION__,
|
||||
mode);
|
||||
DBG (DL_MAJOR_ERROR, "%s: bad mode value %d (internal error)\n",
|
||||
__FUNCTION__, mode);
|
||||
status = SANE_STATUS_INVAL;
|
||||
break;
|
||||
}
|
||||
|
@ -965,10 +910,31 @@ 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.5 2001/10/09 09:45:12 oliverschwartz
|
||||
* update snapscan to snapshot 20011008
|
||||
*
|
||||
* 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
|
||||
* use absolute_max as expected_read_bytes for PRISA620S
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
|
||||
Copyright (C) 1997, 1998 Franck Schnefra, Michel Roelofs,
|
||||
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.
|
||||
|
||||
|
@ -87,10 +88,14 @@ 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.4 2001/10/09 09:45:13 oliverschwartz
|
||||
* update snapscan to snapshot 20011008
|
||||
*
|
||||
* 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
|
||||
* Applying Mikael Magnusson patch concerning Gamma correction
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
History
|
||||
|
||||
0.1 2000-02-01
|
||||
0.1 2000-02-01
|
||||
|
||||
First version released
|
||||
|
||||
|
@ -47,8 +47,11 @@
|
|||
So far this strategy has worked flawlessly. Thanks Dmitri!
|
||||
*/
|
||||
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/sem.h>
|
||||
/* $Id$
|
||||
SnapScan backend scan data sources */
|
||||
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/sem.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 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";
|
||||
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);
|
||||
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, 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;
|
||||
if ((status == SANE_STATUS_DEVICE_BUSY) && is_queueable(src) ) {
|
||||
enqueue_bq(fd,src,src_size);
|
||||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
|
||||
return status;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
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";
|
||||
|
||||
|
||||
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);
|
||||
fd,(int)src,src_size,(int)dst,(int)dst_size,dst_size ? *dst_size : 0);
|
||||
|
||||
/* Prevent the calling process from being killed */
|
||||
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 */
|
||||
sigprocmask(SIG_SETMASK, &oldset, NULL);
|
||||
|
||||
return status;
|
||||
|
||||
|
||||
return status;
|
||||
|
||||
}
|
||||
|
||||
static SANE_Status snapscani_usb_open(const char *dev, int *fdp,
|
||||
SANEI_SCSI_Sense_Handler handler, void *handler_arg)
|
||||
static SANE_Status snapscani_usb_open(const char *dev, int *fdp)
|
||||
{
|
||||
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 RELEASE_UNIT:
|
||||
case SEND_DIAGNOSTIC:
|
||||
return 6;
|
||||
return 6;
|
||||
case SEND:
|
||||
case SET_WINDOW:
|
||||
case READ:
|
||||
case GET_DATA_BUFFER_STATUS:
|
||||
return 10;
|
||||
return 10;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -158,42 +160,41 @@ static char *usb_debug_data(char *str,const char *data, int len) {
|
|||
|
||||
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);
|
||||
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," ...");
|
||||
strcat(str," ...");
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
static SANE_Status usb_open(const char *dev, int *fdp,
|
||||
SANEI_SCSI_Sense_Handler handler, void *handler_arg)
|
||||
static SANE_Status usb_open(const char *dev, int *fdp)
|
||||
{
|
||||
static const char me[] = "usb_open";
|
||||
|
||||
DBG (DL_CALL_TRACE, "%s(%s)\n", me, dev);
|
||||
static const char me[] = "usb_open";
|
||||
|
||||
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);
|
||||
DBG (DL_CALL_TRACE, "%s(%s)\n", me, dev);
|
||||
|
||||
*fdp = open(dev, O_RDWR);
|
||||
if( *fdp < 0)
|
||||
return SANE_STATUS_INVAL;
|
||||
return SANE_STATUS_GOOD;
|
||||
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 const char me[] = "usb_close";
|
||||
|
||||
DBG (DL_CALL_TRACE, "%s(%d)\n", me, fd);
|
||||
semctl(sem_id, 0, IPC_RMID, 0);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -204,12 +205,12 @@ static int usb_status(char *status_buf) {
|
|||
|
||||
switch(status) {
|
||||
case GOOD:
|
||||
return SANE_STATUS_GOOD;
|
||||
return SANE_STATUS_GOOD;
|
||||
case CHECK_CONDITION:
|
||||
case BUSY:
|
||||
return SANE_STATUS_DEVICE_BUSY;
|
||||
return SANE_STATUS_DEVICE_BUSY;
|
||||
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) {
|
||||
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;
|
||||
DBG (DL_MAJOR_ERROR, "%s Only %d bytes written\n",me,r);
|
||||
return SANE_STATUS_IO_ERROR;
|
||||
}
|
||||
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) {
|
||||
char dbgmsg[16384];
|
||||
int r;
|
||||
|
||||
|
||||
static const char me[] = "usb_read";
|
||||
|
||||
/* 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
|
||||
{
|
||||
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;
|
||||
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);
|
||||
DBG (DL_MAJOR_ERROR, "%s: Got an EAGAIN\n",me);
|
||||
usleep(10000);
|
||||
}
|
||||
} 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)
|
||||
{
|
||||
{
|
||||
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];
|
||||
|
||||
*transaction_status = status_buf[0];
|
||||
|
||||
scsistat = (status_buf[1] & STATUS_MASK) >> 1;
|
||||
|
||||
if(scsistatus)
|
||||
*scsistatus = scsistat;
|
||||
*scsistatus = scsistat;
|
||||
|
||||
switch(scsistat) {
|
||||
case GOOD:
|
||||
return SANE_STATUS_GOOD;
|
||||
return SANE_STATUS_GOOD;
|
||||
case CHECK_CONDITION:
|
||||
case BUSY:
|
||||
return SANE_STATUS_DEVICE_BUSY;
|
||||
return SANE_STATUS_DEVICE_BUSY;
|
||||
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,
|
||||
void *dst, size_t * dst_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);
|
||||
|
||||
|
@ -303,7 +304,7 @@ static SANE_Status usb_cmd(int fd, const void *src, size_t src_size,
|
|||
*/
|
||||
if(((char *)src)[0] == SEND_DIAGNOSTIC)
|
||||
return(SANE_STATUS_GOOD);
|
||||
|
||||
|
||||
cmdlen = usb_cmdlen(*((char *)src));
|
||||
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 */
|
||||
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) );
|
||||
|
||||
/* 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_WRITE)
|
||||
DBG(DL_MAJOR_ERROR,
|
||||
"%s: The transaction should now be completed, but the scanner is expecting more data" ,me);
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -353,9 +354,9 @@ static int is_queueable(const char *src)
|
|||
case SEND:
|
||||
case SET_WINDOW:
|
||||
case SEND_DIAGNOSTIC:
|
||||
return 1;
|
||||
return 1;
|
||||
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";
|
||||
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;
|
||||
|
||||
return -1;
|
||||
|
||||
if((bqe->src = malloc(src_size)) == NULL)
|
||||
return -1;
|
||||
return -1;
|
||||
|
||||
memcpy(bqe->src,src,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;
|
||||
|
||||
if(bqtail) {
|
||||
bqtail->next=bqe;
|
||||
bqtail = bqe;
|
||||
bqtail->next=bqe;
|
||||
bqtail = bqe;
|
||||
} else
|
||||
bqhead = bqtail = bqe;
|
||||
bqhead = bqtail = bqe;
|
||||
|
||||
bqelements++;
|
||||
DBG(DL_DATA_TRACE, "%s: Busy queue: elements=%d, bqhead=%p, bqtail=%p\n",
|
||||
me,bqelements,bqhead,bqtail);
|
||||
me,bqelements,bqhead,bqtail);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dequeue_bq()
|
||||
static void dequeue_bq()
|
||||
{
|
||||
static const char me[] = "dequeue_bq";
|
||||
struct usb_busy_queue *tbqe;
|
||||
|
@ -400,19 +401,31 @@ static void dequeue_bq()
|
|||
DBG (DL_CALL_TRACE, "%s()\n", me);
|
||||
|
||||
if(!bqhead)
|
||||
return;
|
||||
|
||||
return;
|
||||
|
||||
tbqe = bqhead;
|
||||
bqhead = bqhead->next;
|
||||
if(!bqhead)
|
||||
bqtail=NULL;
|
||||
|
||||
bqtail=NULL;
|
||||
|
||||
if(tbqe->src)
|
||||
free(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);
|
||||
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
|
||||
*
|
||||
* */
|
||||
|
|
|
@ -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
|
||||
#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);
|
||||
void *dst, size_t * dst_size);
|
||||
static SANE_Status snapscani_usb_open(const char *dev, int *fdp);
|
||||
static void snapscani_usb_close(int fd);
|
||||
|
||||
/*
|
||||
|
@ -46,13 +74,25 @@ 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);
|
||||
void *dst, size_t * dst_size);
|
||||
static SANE_Status usb_open(const char *dev, int *fdp);
|
||||
|
||||
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);
|
||||
void *dst, size_t * dst_size);
|
||||
|
||||
#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
|
||||
*
|
||||
* */
|
||||
|
|
1434
backend/snapscan.c
1434
backend/snapscan.c
Plik diff jest za duży
Load Diff
|
@ -1,9 +1,14 @@
|
|||
scsi AGFA
|
||||
scsi COLOR
|
||||
scsi ACERPERI
|
||||
|
||||
# If not automatically found from above, then you may manually specify
|
||||
# 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
|
||||
|
||||
# Change to the fully qualified filename of your firmware file, if
|
||||
# firmware upload is needed by the scanner
|
||||
firmware /path/to/your/firmware/file
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
:backend "SnapScan" ; name 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)
|
||||
:url "http://snapscan.sourceforge.net/" ; backend's web page
|
||||
|
||||
|
@ -40,10 +40,18 @@
|
|||
:interface "SCSI"
|
||||
:comment "Ditto. Have no specific programming info yet."
|
||||
|
||||
:model "SnapScan 1236u"
|
||||
:interface "USB"
|
||||
:comment "Ditto. Have no specific programming info yet."
|
||||
|
||||
:model "SnapScan 1212u"
|
||||
:interface "USB"
|
||||
:comment "Ditto. Have no specific programming info yet."
|
||||
|
||||
:model "SnapScan e20"
|
||||
:interface "USB"
|
||||
:comment "Have no specific programming info yet."
|
||||
|
||||
:model "SnapScan e40"
|
||||
:interface "USB"
|
||||
:comment "Have no specific programming info yet."
|
||||
|
@ -52,6 +60,10 @@
|
|||
:interface "USB"
|
||||
:comment "Have no specific programming info yet."
|
||||
|
||||
:model "SnapScan e60"
|
||||
:interface "USB"
|
||||
:comment "Have no specific programming info yet."
|
||||
|
||||
:mfg "Vuego"
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
|
@ -84,6 +96,10 @@
|
|||
:interface "USB"
|
||||
: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"
|
||||
:interface "USB"
|
||||
:comment "Seems to be a close SnapScan 310/600 compatible."
|
||||
|
@ -92,6 +108,22 @@
|
|||
:interface "USB"
|
||||
: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"
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
Copyright (C) 1997, 1998, 1999, 2001 Franck Schnefra, Michel Roelofs,
|
||||
Emmanuel Blot, Mikko Tyolajarvi, David Mosberger-Tang, Wolfgang Goeller,
|
||||
Petter Reinholdtsen, Gary Plewa, Sebastien Sable, Mikael Magnusson
|
||||
and Kevin Charter
|
||||
|
||||
Petter Reinholdtsen, Gary Plewa, Sebastien Sable, Mikael Magnusson,
|
||||
Oliver Schwartz and Kevin Charter
|
||||
|
||||
This file is part of the SANE package.
|
||||
|
||||
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
|
||||
whether to permit this exception to apply to your modifications.
|
||||
If you do not wish that, delete this exception notice.
|
||||
|
||||
|
||||
This file is a component of the implementation of a backend for many
|
||||
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 SNAPSCAN_TYPE "flatbed scanner"
|
||||
/*#define INOPERATIVE*/
|
||||
#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 R_CHAN 0
|
||||
#define G_CHAN 1
|
||||
#define B_CHAN 2
|
||||
#define R_CHAN 0
|
||||
#define G_CHAN 1
|
||||
#define B_CHAN 2
|
||||
|
||||
typedef enum
|
||||
{
|
||||
|
@ -76,16 +77,21 @@ typedef enum
|
|||
typedef enum
|
||||
{
|
||||
UNKNOWN,
|
||||
SNAPSCAN300, /* the original SnapScan or SnapScan 300 */
|
||||
SNAPSCAN310, /* the SnapScan 310 */
|
||||
SNAPSCAN600, /* the SnapScan 600 */
|
||||
SNAPSCAN1236S, /* the SnapScan 1236s */
|
||||
SNAPSCAN300, /* the original SnapScan or SnapScan 300 */
|
||||
SNAPSCAN310, /* the SnapScan 310 */
|
||||
SNAPSCAN600, /* the SnapScan 600 */
|
||||
SNAPSCAN1236, /* the SnapScan 1236 */
|
||||
SNAPSCAN1212U,
|
||||
SNAPSCANE50, /* SnapScan e20/e40/e50 */
|
||||
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 */
|
||||
VUEGO310S, /* Vuego-Version of SnapScan 310 WG changed */
|
||||
VUEGO610S, /* Vuego 610S and 610plus SJU changed */
|
||||
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;
|
||||
struct SnapScan_Model_desc
|
||||
{
|
||||
|
@ -96,24 +102,31 @@ struct SnapScan_Model_desc
|
|||
static struct SnapScan_Model_desc scanners[] =
|
||||
{
|
||||
/* SCSI model name -> enum value */
|
||||
{"FlatbedScanner_2", VUEGO610S},
|
||||
{"FlatbedScanner_4", VUEGO310S},
|
||||
{"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},
|
||||
{"FlatbedScanner_2", VUEGO610S},
|
||||
{"FlatbedScanner_4", VUEGO310S},
|
||||
{"FlatbedScanner_5", PRISA620S},
|
||||
{"FlatbedScanner_9", PRISA620S},
|
||||
{"FlatbedScanner13", PRISA620S},
|
||||
{"FlatbedScanner16", PRISA620S},
|
||||
{"FlatbedScanner17", PRISA620S},
|
||||
{"FlatbedScanner18", PRISA620S},
|
||||
{"FlatbedScanner19", PRISA1240},
|
||||
{"FlatbedScanner20", PRISA640},
|
||||
{"FlatbedScanner21", PRISA4300},
|
||||
{"FlatbedScanner23", PRISA4300_2},
|
||||
{"FlatbedScanner24", PRISA5300},
|
||||
{"SNAPSCAN 1212U", SNAPSCAN1212U},
|
||||
{"SNAPSCAN 1212U_2", SNAPSCAN1212U},
|
||||
{"SNAPSCAN e20", SNAPSCANE50},
|
||||
{"SNAPSCAN e50", SNAPSCANE50},
|
||||
{"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])))
|
||||
|
||||
|
@ -122,52 +135,53 @@ 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_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 */
|
||||
OPT_BRIGHTNESS, /* brightness */
|
||||
OPT_CONTRAST, /* contrast */
|
||||
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 */
|
||||
OPT_INQUIRY, /* inquiry command (button) */
|
||||
OPT_SELF_TEST, /* self test command (button) */
|
||||
OPT_REQ_SENSE, /* request sense command (button) */
|
||||
OPT_REL_UNIT, /* release unit command (button) */
|
||||
NUM_OPTS /* dummy (gives number of options) */
|
||||
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 */
|
||||
OPT_BRIGHTNESS, /* brightness */
|
||||
OPT_CONTRAST, /* contrast */
|
||||
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 */
|
||||
OPT_INQUIRY, /* inquiry command (button) */
|
||||
OPT_SELF_TEST, /* self test command (button) */
|
||||
OPT_REQ_SENSE, /* request sense command (button) */
|
||||
OPT_REL_UNIT, /* release unit command (button) */
|
||||
NUM_OPTS /* dummy (gives number of options) */
|
||||
} SnapScan_Options;
|
||||
|
||||
typedef union
|
||||
|
@ -181,41 +195,41 @@ Option_Value;
|
|||
|
||||
typedef enum
|
||||
{
|
||||
MD_COLOUR = 0, /* full colour */
|
||||
MD_BILEVELCOLOUR, /* 1-bit per channel colour */
|
||||
MD_GREYSCALE, /* grey scale */
|
||||
MD_LINEART, /* black and white */
|
||||
MD_COLOUR = 0, /* full colour */
|
||||
MD_BILEVELCOLOUR, /* 1-bit per channel colour */
|
||||
MD_GREYSCALE, /* grey scale */
|
||||
MD_LINEART, /* black and white */
|
||||
MD_NUM_MODES
|
||||
} SnapScan_Mode;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SRC_FLATBED = 0, /* Flatbed (normal) */
|
||||
SRC_TPO /* Transparency unit */
|
||||
SRC_FLATBED = 0, /* Flatbed (normal) */
|
||||
SRC_TPO /* Transparency unit */
|
||||
} SnapScan_Source;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ST_IDLE, /* between scans */
|
||||
ST_SCAN_INIT, /* scan initialization */
|
||||
ST_SCANNING, /* actively scanning data */
|
||||
ST_CANCEL_INIT /* cancellation begun */
|
||||
ST_IDLE, /* between scans */
|
||||
ST_SCAN_INIT, /* scan initialization */
|
||||
ST_SCANNING, /* actively scanning data */
|
||||
ST_CANCEL_INIT /* cancellation begun */
|
||||
} SnapScan_State;
|
||||
|
||||
typedef struct snapscan_device
|
||||
{
|
||||
SANE_Device dev;
|
||||
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 */
|
||||
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;
|
||||
}
|
||||
SnapScan_Device;
|
||||
|
||||
#define MAX_SCSI_CMD_LEN 256 /* not that large */
|
||||
#define SCANNER_BUF_SZ 31744
|
||||
#define MAX_SCSI_CMD_LEN 256 /* not that large */
|
||||
#define DEFAULT_SCANNER_BUF_SZ 1024*63
|
||||
|
||||
typedef struct snapscan_scanner SnapScan_Scanner;
|
||||
|
||||
|
@ -223,81 +237,107 @@ typedef struct snapscan_scanner SnapScan_Scanner;
|
|||
|
||||
struct snapscan_scanner
|
||||
{
|
||||
SANE_String devname; /* the scsi device name */
|
||||
SnapScan_Device *pdev; /* the device */
|
||||
int fd; /* scsi file descriptor */
|
||||
int opens; /* open count */
|
||||
SANE_String tmpfname; /* temporary file name */
|
||||
int tfd; /* temp file descriptor */
|
||||
int rpipe[2]; /* reader pipe descriptors */
|
||||
int orig_rpipe_flags; /* initial reader pipe flags */
|
||||
pid_t child; /* child reader process pid */
|
||||
SnapScan_Mode mode; /* mode */
|
||||
SnapScan_Mode preview_mode; /* preview mode */
|
||||
SnapScan_Source source; /* scanning source */
|
||||
SnapScan_State state; /* scanner state */
|
||||
u_char cmd[MAX_SCSI_CMD_LEN]; /* scsi command buffer */
|
||||
u_char buf[SCANNER_BUF_SZ]; /* data buffer */
|
||||
size_t buf_sz; /* effective buffer size */
|
||||
size_t expected_read_bytes; /* expected amount of data in a single read */
|
||||
size_t read_bytes; /* amount of actual data read */
|
||||
size_t bytes_remaining; /* remaining bytes expected from scanner */
|
||||
size_t actual_res; /* actual resolution */
|
||||
size_t lines; /* number of scan lines */
|
||||
size_t bytes_per_line; /* bytes per scan line */
|
||||
size_t pixels_per_line; /* pixels per scan line */
|
||||
u_char hconfig; /* hardware configuration byte */
|
||||
float ms_per_line; /* speed: milliseconds per scan line */
|
||||
SANE_Bool nonblocking; /* wait on reads for data? */
|
||||
char *sense_str; /* sense string */
|
||||
char *as_str; /* additional sense string */
|
||||
u_char asi1; /* first additional sense info byte */
|
||||
u_char asi2; /* second additional sense info byte */
|
||||
SANE_Byte chroma_offset[3]; /* chroma offsets */
|
||||
Source *psrc; /* data source */
|
||||
SANE_String devname; /* the scsi device name */
|
||||
SnapScan_Device *pdev; /* the device */
|
||||
int fd; /* scsi file descriptor */
|
||||
int opens; /* open count */
|
||||
SANE_String tmpfname; /* temporary file name */
|
||||
int tfd; /* temp file descriptor */
|
||||
int rpipe[2]; /* reader pipe descriptors */
|
||||
int orig_rpipe_flags; /* initial reader pipe flags */
|
||||
pid_t child; /* child reader process pid */
|
||||
SnapScan_Mode mode; /* mode */
|
||||
SnapScan_Mode preview_mode; /* preview mode */
|
||||
SnapScan_Source source; /* scanning source */
|
||||
SnapScan_State state; /* scanner state */
|
||||
u_char cmd[MAX_SCSI_CMD_LEN]; /* scsi command buffer */
|
||||
u_char *buf; /* data buffer */
|
||||
size_t phys_buf_sz; /* physical buffer size */
|
||||
size_t buf_sz; /* effective buffer size */
|
||||
size_t expected_read_bytes; /* expected amount of data in a single read */
|
||||
size_t read_bytes; /* amount of actual data read */
|
||||
size_t bytes_remaining; /* remaining bytes expected from scanner */
|
||||
size_t actual_res; /* actual resolution */
|
||||
size_t lines; /* number of scan lines */
|
||||
size_t bytes_per_line; /* bytes per scan line */
|
||||
size_t pixels_per_line; /* pixels per scan line */
|
||||
u_char hconfig; /* hardware configuration byte */
|
||||
float ms_per_line; /* speed: milliseconds per scan line */
|
||||
SANE_Bool nonblocking; /* wait on reads for data? */
|
||||
char *sense_str; /* sense string */
|
||||
char *as_str; /* additional sense string */
|
||||
u_char asi1; /* first additional sense info byte */
|
||||
u_char asi2; /* second additional sense info byte */
|
||||
SANE_Byte chroma_offset[3]; /* chroma offsets */
|
||||
SANE_Int chroma;
|
||||
Source *psrc; /* data source */
|
||||
|
||||
SANE_Option_Descriptor
|
||||
options[NUM_OPTS]; /* the option descriptors */
|
||||
options[NUM_OPTS]; /* the option descriptors */
|
||||
Option_Value val[NUM_OPTS];
|
||||
/* the options themselves... */
|
||||
SANE_Int res; /* resolution */
|
||||
SANE_Bool preview; /* preview mode toggle */
|
||||
SANE_String mode_s; /* scanning mode */
|
||||
SANE_String source_s; /* scanning source */
|
||||
SANE_String preview_mode_s; /* scanning mode for preview */
|
||||
SANE_Fixed tlx; /* window top left x */
|
||||
SANE_Fixed tly; /* window top left y */
|
||||
SANE_Fixed brx; /* window bottom right x */
|
||||
SANE_Fixed bry; /* window bottom right y */
|
||||
int bright; /* brightness */
|
||||
int contrast; /* contrast */
|
||||
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 */
|
||||
SANE_Int threshold; /* threshold for line art */
|
||||
SANE_Int rgb_lpr; /* lines per scsi read (RGB) */
|
||||
SANE_Int gs_lpr; /* lines per scsi read (greyscale) */
|
||||
SANE_Int res; /* resolution */
|
||||
SANE_Bool preview; /* preview mode toggle */
|
||||
SANE_String mode_s; /* scanning mode */
|
||||
SANE_String source_s; /* scanning source */
|
||||
SANE_String preview_mode_s; /* scanning mode for preview */
|
||||
SANE_Fixed tlx; /* window top left x */
|
||||
SANE_Fixed tly; /* window top left y */
|
||||
SANE_Fixed brx; /* window bottom right x */
|
||||
SANE_Fixed bry; /* window bottom right y */
|
||||
int bright; /* brightness */
|
||||
int contrast; /* contrast */
|
||||
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 */
|
||||
SANE_Int threshold; /* threshold for line art */
|
||||
SANE_Int rgb_lpr; /* lines per scsi read (RGB) */
|
||||
SANE_Int gs_lpr; /* lines per scsi read (greyscale) */
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* $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.5 2001/10/09 09:45:21 oliverschwartz
|
||||
* update snapscan to snapshot 20011008
|
||||
*
|
||||
* 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
|
||||
* Adding e20 support thanks to Steffen Hübner
|
||||
|
|
Ładowanie…
Reference in New Issue