kopia lustrzana https://gitlab.com/sane-project/backends
* backend/canon_pp.c: Now always uses as much scanner buffer as
possible, then feeds data to frontend. Results in large speed increase in ECP mode. Also fixed problems with saned compatibility. * backend/canon_pp.h: Added bytes_sent to scanner data structure. * doc/sane-canon_pp.man: Discuss hardware problems at high resolutions.DEVEL_2_0_BRANCH-1
rodzic
2f409340a9
commit
68937254bf
|
@ -50,7 +50,7 @@
|
|||
#include <lalloca.h> /* MUST come first for AIX! */
|
||||
#endif
|
||||
|
||||
#define VERSION "$Revision$ (0.3)"
|
||||
#define VERSION "$Revision$"
|
||||
#define BACKEND_NAME canon_pp
|
||||
|
||||
#define THREE_BITS 0xE0
|
||||
|
@ -872,7 +872,8 @@ sane_get_parameters (SANE_Handle h, SANE_Parameters *params)
|
|||
|
||||
/*
|
||||
* These don't change whether we're scanning or not
|
||||
* NOTE: Assumes options don't change after scanning commences
|
||||
* NOTE: Assumes options don't change after scanning commences, which
|
||||
* is part of the standard
|
||||
*/
|
||||
|
||||
/* Copy the options stored in the vals into the scaninfo */
|
||||
|
@ -888,12 +889,16 @@ sane_get_parameters (SANE_Handle h, SANE_Parameters *params)
|
|||
/* x values have to be divisible by 4 (round down) */
|
||||
params->pixels_per_line -= (params->pixels_per_line%4);
|
||||
|
||||
/* Can't scan nothing */
|
||||
if (!(params->pixels_per_line)) params->pixels_per_line = 4;
|
||||
|
||||
max_width = cs->params.scanheadwidth / (max_res / res);
|
||||
|
||||
max_height = (cs->params.scanheadwidth == 2552 ? 3508 : 7016) /
|
||||
(max_res / res);
|
||||
|
||||
if(params->pixels_per_line > max_width) params->pixels_per_line = max_width;
|
||||
if(params->pixels_per_line > max_width)
|
||||
params->pixels_per_line = max_width;
|
||||
if(total_lines > max_height) total_lines = max_height;
|
||||
|
||||
|
||||
|
@ -921,7 +926,6 @@ sane_get_parameters (SANE_Handle h, SANE_Parameters *params)
|
|||
/* Always assume next packet will be the last
|
||||
* - frontends seem to like it that way */
|
||||
params->last_frame = SANE_TRUE;
|
||||
params->lines = total_lines - cs->lines_scanned;
|
||||
|
||||
switch (cs->vals[OPT_COLOUR_MODE])
|
||||
{
|
||||
|
@ -938,6 +942,21 @@ sane_get_parameters (SANE_Handle h, SANE_Parameters *params)
|
|||
break;
|
||||
}
|
||||
|
||||
if (cs->bytes_sent > 0)
|
||||
/* we want to round up the number of lines still to come */
|
||||
params->lines = total_lines -
|
||||
ceilf((float)(cs->bytes_sent) /
|
||||
(float)(params->bytes_per_line));
|
||||
else
|
||||
params->lines = total_lines;
|
||||
|
||||
DBG(10, "get_params: bytes_per_line=%d, pixels_per_line=%d, lines=%d\n"
|
||||
"max_res=%d, res=%d, max_height=%d, total_lines=%d\n"
|
||||
"br_y=%d, tl_y=%d, mm_per_in=%f\n",
|
||||
params->bytes_per_line, params->pixels_per_line, params->lines,
|
||||
max_res, res, max_height, total_lines,
|
||||
cs->vals[OPT_BR_Y], cs->vals[OPT_TL_Y], MM_PER_IN);
|
||||
|
||||
/* FIXME: Do we need to account for the scanner's max buffer here? */
|
||||
|
||||
DBG(2, "<< sane_get_parameters\n");
|
||||
|
@ -975,8 +994,10 @@ sane_start (SANE_Handle h)
|
|||
res = res630[cs->vals[OPT_RESOLUTION]];
|
||||
|
||||
/* Copy the options stored in the vals into the scaninfo */
|
||||
cs->scan.width = ((cs->vals[OPT_BR_X] - cs->vals[OPT_TL_X]) * res) / MM_PER_IN;
|
||||
cs->scan.height = ((cs->vals[OPT_BR_Y] - cs->vals[OPT_TL_Y]) * res) / MM_PER_IN;
|
||||
cs->scan.width = ((cs->vals[OPT_BR_X] - cs->vals[OPT_TL_X]) * res)
|
||||
/ MM_PER_IN;
|
||||
cs->scan.height = ((cs->vals[OPT_BR_Y] - cs->vals[OPT_TL_Y]) * res)
|
||||
/ MM_PER_IN;
|
||||
|
||||
cs->scan.xoffset = (cs->vals[OPT_TL_X] * res) / MM_PER_IN;
|
||||
cs->scan.yoffset = (cs->vals[OPT_TL_Y] * res) / MM_PER_IN;
|
||||
|
@ -995,6 +1016,9 @@ sane_start (SANE_Handle h)
|
|||
cs->scan.width -= (cs->scan.width%4);
|
||||
cs->scan.xoffset -= (cs->scan.xoffset%4);
|
||||
|
||||
/* Can't scan nothing */
|
||||
if (!(cs->scan.width)) cs->scan.width = 4;
|
||||
|
||||
max_width = cs->params.scanheadwidth / (max_res / res);
|
||||
|
||||
max_height = (cs->params.scanheadwidth == 2552 ? 3508 : 7016) /
|
||||
|
@ -1047,6 +1071,8 @@ sane_start (SANE_Handle h)
|
|||
cs->scanning = SANE_TRUE;
|
||||
cs->cancelled = SANE_FALSE;
|
||||
cs->sent_eof = SANE_FALSE;
|
||||
cs->lines_scanned = 0;
|
||||
cs->bytes_sent = 0;
|
||||
|
||||
/* init_scan doesn't return a value yet... but Simon might get keen
|
||||
* one day
|
||||
|
@ -1083,7 +1109,7 @@ sane_read (SANE_Handle h, SANE_Byte *buf, SANE_Int maxlen, SANE_Int *lenp)
|
|||
unsigned int i;
|
||||
short *shortptr;
|
||||
SANE_Byte *charptr;
|
||||
int max_buf, tmp;
|
||||
int tmp;
|
||||
|
||||
static SANE_Byte *lbuf;
|
||||
static unsigned int bytesleft;
|
||||
|
@ -1107,25 +1133,30 @@ sane_read (SANE_Handle h, SANE_Byte *buf, SANE_Int maxlen, SANE_Int *lenp)
|
|||
/* feed some more data in until we've run out - don't care
|
||||
* whether or not we _think_ the scanner is scanning now,
|
||||
* because we may still have data left over to send */
|
||||
DBG(100, "sane_read: didn't send it all last time\n");
|
||||
|
||||
/* Now feed it some data from lbuf */
|
||||
if (bytesleft <= (unsigned int)maxlen)
|
||||
{
|
||||
/* enough buffer to send the lot */
|
||||
memcpy(buf, lbuf, bytesleft);
|
||||
memcpy(buf, read_leftover, bytesleft);
|
||||
free(lbuf);
|
||||
*lenp = bytesleft;
|
||||
lbuf = NULL;
|
||||
read_leftover = NULL;
|
||||
bytesleft = 0;
|
||||
cs->bytes_sent += bytesleft;
|
||||
return SANE_STATUS_GOOD;
|
||||
|
||||
} else {
|
||||
/* only enough to send maxlen */
|
||||
memcpy(buf, lbuf, maxlen);
|
||||
read_leftover = lbuf + maxlen;
|
||||
memcpy(buf, read_leftover, maxlen);
|
||||
read_leftover += maxlen;
|
||||
bytesleft -= maxlen;
|
||||
*lenp = maxlen;
|
||||
cs->bytes_sent += maxlen;
|
||||
DBG(100, "sane_read: sent %d bytes, still have %d to "
|
||||
"go\n", maxlen, bytesleft);
|
||||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
|
||||
|
@ -1137,11 +1168,13 @@ sane_read (SANE_Handle h, SANE_Byte *buf, SANE_Int maxlen, SANE_Int *lenp)
|
|||
}
|
||||
|
||||
/* Has the last scan ended? */
|
||||
if (((unsigned)cs->scan.height == (unsigned)cs->lines_scanned)
|
||||
if (((unsigned)cs->scan.height <= (unsigned)cs->lines_scanned)
|
||||
|| !(cs->scanning))
|
||||
{
|
||||
if (cs->cancelled)
|
||||
{
|
||||
return SANE_STATUS_CANCELLED;
|
||||
}
|
||||
|
||||
if (cs->sent_eof)
|
||||
{
|
||||
|
@ -1150,6 +1183,9 @@ sane_read (SANE_Handle h, SANE_Byte *buf, SANE_Int maxlen, SANE_Int *lenp)
|
|||
return SANE_STATUS_INVAL;
|
||||
} else {
|
||||
cs->sent_eof = SANE_TRUE;
|
||||
cs->scanning = SANE_FALSE;
|
||||
cs->lines_scanned = 0;
|
||||
cs->bytes_sent = 0;
|
||||
return SANE_STATUS_EOF;
|
||||
}
|
||||
}
|
||||
|
@ -1166,23 +1202,27 @@ sane_read (SANE_Handle h, SANE_Byte *buf, SANE_Int maxlen, SANE_Int *lenp)
|
|||
/* We will have as many lines as possible, or the size of the scan.
|
||||
* Each pixel is 5/4 bytes per colour, so we multiply the buffer
|
||||
* size by 4/5 to get the number of lines. */
|
||||
|
||||
/* New way: scan a whole scanner buffer full, and return as much as
|
||||
* the frontend wants. It's faster and more reliable since the
|
||||
* scanners crack the shits if we ask for too many small packets */
|
||||
#if 0
|
||||
if ((int)maxlen > (BUF_MAX * 4 / 5))
|
||||
max_buf = (BUF_MAX * 4 / 5);
|
||||
else
|
||||
max_buf = (int)maxlen;
|
||||
|
||||
lines = max_buf / (int)bpl;
|
||||
if (lines > cs->scan.height) lines = cs->scan.height;
|
||||
if ((cs->scan.height - cs->lines_scanned) < lines)
|
||||
#endif
|
||||
lines = (BUF_MAX * 4 / 5) / bpl;
|
||||
|
||||
if (lines > (cs->scan.height - cs->lines_scanned))
|
||||
lines = cs->scan.height - cs->lines_scanned;
|
||||
|
||||
if (!lines)
|
||||
{
|
||||
/* can't fit a whole line into the buffer */
|
||||
DBG(10, "sane_read: Tighter than a duck's butt (can't fit a "
|
||||
"whole scanline in the buffer)\n");
|
||||
/* return SANE_STATUS_INVAL; */
|
||||
/* Try and deal with this gracefully */
|
||||
/* can't fit a whole line into the buffer
|
||||
* (should never happen!) */
|
||||
lines = 1;
|
||||
}
|
||||
|
||||
|
@ -1302,6 +1342,7 @@ sane_read (SANE_Handle h, SANE_Byte *buf, SANE_Int maxlen, SANE_Int *lenp)
|
|||
lbuf = NULL;
|
||||
read_leftover = NULL;
|
||||
bytesleft = 0;
|
||||
cs->bytes_sent += bytes;
|
||||
|
||||
} else {
|
||||
/* only enough to send maxlen */
|
||||
|
@ -1309,6 +1350,9 @@ sane_read (SANE_Handle h, SANE_Byte *buf, SANE_Int maxlen, SANE_Int *lenp)
|
|||
*lenp = maxlen;
|
||||
read_leftover = lbuf + maxlen;
|
||||
bytesleft = bytes - maxlen;
|
||||
cs->bytes_sent += maxlen;
|
||||
DBG(100, "sane_read: sent %d bytes, still have %d to go\n",
|
||||
maxlen, bytesleft);
|
||||
}
|
||||
|
||||
if ((unsigned)cs->lines_scanned >= cs->scan.height)
|
||||
|
@ -1318,6 +1362,7 @@ sane_read (SANE_Handle h, SANE_Byte *buf, SANE_Int maxlen, SANE_Int *lenp)
|
|||
DBG(10, "sane_read: Scan is finished.\n");
|
||||
cs->scanning = SANE_FALSE;
|
||||
cs->lines_scanned = 0;
|
||||
cs->bytes_sent = 0;
|
||||
}
|
||||
|
||||
DBG(2, "<< sane_read\n");
|
||||
|
@ -1353,6 +1398,7 @@ sane_cancel (SANE_Handle h)
|
|||
cs->cancelled = SANE_TRUE;
|
||||
|
||||
cs->lines_scanned = 0;
|
||||
cs->bytes_sent = 0;
|
||||
DBG(2, "sane_cancel: >> abort_scan\n");
|
||||
tmp = sanei_canon_pp_abort_scan(&(cs->params), &(cs->scan));
|
||||
DBG(2, "sane_cancel: << abort_scan\n");
|
||||
|
@ -1563,6 +1609,8 @@ static SANE_Status init_device(struct parport *pp)
|
|||
cs->scanning = SANE_FALSE;
|
||||
cs->cancelled = SANE_FALSE;
|
||||
cs->sent_eof = SANE_TRUE;
|
||||
cs->lines_scanned = 0;
|
||||
cs->bytes_sent = 0;
|
||||
|
||||
DBG(10, "init_device: [configuring options]\n");
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@
|
|||
/* options: num,res,colour,depth,tl-x,tl-y,br-x,br-y,cal */
|
||||
/* preview option disabled */
|
||||
#define NUM_OPTIONS 9
|
||||
#define BUF_MAX 65520
|
||||
#define BUF_MAX 64000
|
||||
|
||||
/* Indexes into options array */
|
||||
#define OPT_NUM_OPTIONS 0
|
||||
|
@ -101,6 +101,7 @@ struct CANONP_Scanner_Struct
|
|||
SANE_Bool cancelled;
|
||||
SANE_Bool setup;
|
||||
SANE_Int lines_scanned;
|
||||
SANE_Int bytes_sent;
|
||||
|
||||
char *weights_file;
|
||||
SANE_Bool cal_readonly;
|
||||
|
|
|
@ -164,6 +164,17 @@ the power. You may find if you try a scan very soon after plugging in the
|
|||
power that the backend will incorrectly report that you have no scanner present.
|
||||
To avoid this, give it about 10 seconds to reset itself before attempting any
|
||||
scans.
|
||||
.PP
|
||||
.B Repeated Lines
|
||||
.PP
|
||||
Sometimes at high resolutions (ie. 600dpi) you will notice lines which appear
|
||||
twice. These lines correspond to points where the scanner head has stopped
|
||||
during the scan (it stops every time the internal 64kb buffer is full).
|
||||
Basically it's a mechanical problem inside the scanner, that the tolerance of
|
||||
movement for a start/stop event is greater than 1/600 inches. I've never
|
||||
tried the windows driver so I'm not sure how (or if) it works around
|
||||
this problem, but as we don't know how to rewind the scanner head to do these
|
||||
bits again, there's currently no nice way to deal with the problem.
|
||||
|
||||
.SH "SEE ALSO"
|
||||
sane(7), sane-dll(5)
|
||||
|
|
Ładowanie…
Reference in New Issue