* backend/canon_pp.c backend/canon_pp-dev.c backend/canon_pp-dev.h:

Finally fixed cancelling, which I broke some time ago in the quest
  for speed.  FB620P still doesn't abort nicely (firmware bug?).
* doc/sane-canon_pp.man: Added notes on FB620P problems.
* doc/descriptions/canon_pp.desc: Bumped version number.
DEVEL_2_0_BRANCH-1
Matthew Duggan 2002-09-30 15:25:14 +00:00
rodzic 2958f7a844
commit 284233e77e
5 zmienionych plików z 82 dodań i 111 usunięć

Wyświetl plik

@ -104,7 +104,6 @@ static void DBG(int level, const char *format, ...)
/*const int scanline_count = 6;*/ /*const int scanline_count = 6;*/
static const char *header = "#CANONPP"; static const char *header = "#CANONPP";
static const int fileversion = 3; static const int fileversion = 3;
static int abort_now = 0;
/* Internal functions */ /* Internal functions */
static unsigned long column_sum(image_segment *image, int x); static unsigned long column_sum(image_segment *image, int x);
@ -659,7 +658,8 @@ int sanei_canon_pp_read_segment(image_segment **dest, scanner_parameters *sp,
/* Allocate memory for dest image segment */ /* Allocate memory for dest image segment */
output_image->image_data = malloc(output_image->width * output_image->height * output_image->image_data =
malloc(output_image->width * output_image->height *
(scanp->mode ? 3 : 1) * 2); (scanp->mode ? 3 : 1) * 2);
if (output_image->image_data == NULL) if (output_image->image_data == NULL)
@ -711,7 +711,7 @@ int sanei_canon_pp_read_segment(image_segment **dest, scanner_parameters *sp,
/* This is the only place we can abort safely - /* This is the only place we can abort safely -
* between reading one segment and requesting the next one. */ * between reading one segment and requesting the next one. */
if (abort_now) goto error_out; if (sp->abort_now) goto error_out;
if (scanlines_left >= (scanline_number * 2)) if (scanlines_left >= (scanline_number * 2))
{ {
@ -739,10 +739,11 @@ int sanei_canon_pp_read_segment(image_segment **dest, scanner_parameters *sp,
return 0; return 0;
error_out: error_out:
if (output_image && output_image->image_data) free(output_image->image_data); if (output_image && output_image->image_data)
free(output_image->image_data);
if (output_image) free(output_image); if (output_image) free(output_image);
if (input_buffer) free(input_buffer); if (input_buffer) free(input_buffer);
abort_now = 0; sp->abort_now = 0;
return -1; return -1;
} }
@ -970,7 +971,7 @@ int sanei_canon_pp_calibrate(scanner_parameters *sp, char *cal_file)
if (!(sp->type) ) scanline_count = 8; if (!(sp->type) ) scanline_count = 8;
/* Probably shouldn't have to abort *just* yet, but may as well check */ /* Probably shouldn't have to abort *just* yet, but may as well check */
if (abort_now) return -1; if (sp->abort_now) return -1;
DBG(40, "Calibrating %ix%i pixels calibration image " DBG(40, "Calibrating %ix%i pixels calibration image "
"(%i bytes each scan).\n", "(%i bytes each scan).\n",
@ -1010,7 +1011,7 @@ int sanei_canon_pp_calibrate(scanner_parameters *sp, char *cal_file)
DBG(40, " * Black scan number %d/%d.\n", readnum + 1, DBG(40, " * Black scan number %d/%d.\n", readnum + 1,
calibration_reads); calibration_reads);
if (abort_now) return -1; if (sp->abort_now) return -1;
if (send_command(sp->port, command_buffer, 10, 100000, 5000000)) if (send_command(sp->port, command_buffer, 10, 100000, 5000000))
{ {
@ -1056,7 +1057,7 @@ int sanei_canon_pp_calibrate(scanner_parameters *sp, char *cal_file)
DBG(40, "Step 2/3: Gamma tables...\n"); DBG(40, "Step 2/3: Gamma tables...\n");
DBG(40, " * Requesting creation of new of gamma tables...\n"); DBG(40, " * Requesting creation of new of gamma tables...\n");
if (abort_now) return -1; if (sp->abort_now) return -1;
if (send_command(sp->port, cmd_cleargamma, 10, 100000, 5000000)) if (send_command(sp->port, cmd_cleargamma, 10, 100000, 5000000))
{ {
DBG(1,"Error sending gamma command!\n"); DBG(1,"Error sending gamma command!\n");
@ -1083,7 +1084,7 @@ int sanei_canon_pp_calibrate(scanner_parameters *sp, char *cal_file)
sanei_canon_pp_read(sp->port, 32, sp->gamma); sanei_canon_pp_read(sp->port, 32, sp->gamma);
DBG(40, "done.\n"); DBG(40, "done.\n");
if (abort_now) return -1; if (sp->abort_now) return -1;
memcpy(command_buffer, cmd_calcolour, 10); memcpy(command_buffer, cmd_calcolour, 10);
@ -1103,7 +1104,7 @@ int sanei_canon_pp_calibrate(scanner_parameters *sp, char *cal_file)
colours[colournum-1], readnum + 1, colours[colournum-1], readnum + 1,
calibration_reads); calibration_reads);
if (abort_now) return -1; if (sp->abort_now) return -1;
if (send_command(sp->port, command_buffer, 10, if (send_command(sp->port, command_buffer, 10,
100000, 5000000)) 100000, 5000000))
{ {
@ -1146,7 +1147,7 @@ int sanei_canon_pp_calibrate(scanner_parameters *sp, char *cal_file)
} }
if (abort_now) return -1; if (sp->abort_now) return -1;
/* cal_file == NUL indicates we want an in-memory scan only */ /* cal_file == NUL indicates we want an in-memory scan only */
if (cal_file != NULL) if (cal_file != NULL)
@ -1290,11 +1291,6 @@ int sanei_canon_pp_abort_scan(scanner_parameters *sp)
return 0; return 0;
} }
void sanei_canon_pp_abort(void)
{
abort_now = 1;
}
/* adjust_gamma: Upload a gamma profile to the scanner */ /* adjust_gamma: Upload a gamma profile to the scanner */
int sanei_canon_pp_adjust_gamma(scanner_parameters *sp) int sanei_canon_pp_adjust_gamma(scanner_parameters *sp)
{ {

Wyświetl plik

@ -125,6 +125,9 @@ typedef struct scanner_parameter_struct
/* Type of scanner ( 0 = *20P, 1 = [*30P|*40P] ) */ /* Type of scanner ( 0 = *20P, 1 = [*30P|*40P] ) */
unsigned char type; unsigned char type;
/* Are we aborting this scanner now */
unsigned char abort_now;
} scanner_parameters; } scanner_parameters;
typedef struct scan_parameter_struct typedef struct scan_parameter_struct
@ -164,7 +167,6 @@ int sanei_canon_pp_read_segment(image_segment **dest, scanner_parameters *sp,
int scanlines_left); int scanlines_left);
int sanei_canon_pp_abort_scan(scanner_parameters *sp); int sanei_canon_pp_abort_scan(scanner_parameters *sp);
void sanei_canon_pp_abort(void);
/* Loads the gain offset values. Needs a new name. */ /* Loads the gain offset values. Needs a new name. */
int sanei_canon_pp_load_weights(const char *filename, scanner_parameters *sp); int sanei_canon_pp_load_weights(const char *filename, scanner_parameters *sp);

Wyświetl plik

@ -1102,21 +1102,8 @@ sane_start (SANE_Handle h)
cs->lines_scanned = 0; cs->lines_scanned = 0;
cs->bytes_sent = 0; cs->bytes_sent = 0;
/* init_scan doesn't return a value yet... but Simon might get keen
* one day
if (!(init_scan(&(cs->params), &(cs->scan))))
{
cs->scanning = SANE_TRUE;
return SANE_STATUS_GOOD;
}
else
{
cs->scanning = SANE_FALSE;
return SANE_STATUS_IO_ERROR;
}
*/
DBG(2, "<< sane_start\n"); DBG(2, "<< sane_start\n");
return SANE_STATUS_GOOD; return SANE_STATUS_GOOD;
} }
@ -1150,14 +1137,14 @@ sane_read (SANE_Handle h, SANE_Byte *buf, SANE_Int maxlen, SANE_Int *lenp)
if ((h == NULL) || (buf == NULL) || (lenp == NULL)) if ((h == NULL) || (buf == NULL) || (lenp == NULL))
{ {
DBG(1, "sane_read: This frontend's passing me dodgy gear! " DBG(1, "sane_read: This frontend's passing me dodgy gear! "
"(h=%p, buf=%p, lenp=%p)\n", "(h=%p, buf=%p, lenp=%p)\n", h, buf, lenp);
h, buf, lenp);
return SANE_STATUS_INVAL; return SANE_STATUS_INVAL;
} }
/* Now we have to see if we have some leftover from last time */ /* Now we have to see if we have some leftover from last time */
if (read_leftover != NULL) { if (read_leftover != NULL)
{
/* feed some more data in until we've run out - don't care /* feed some more data in until we've run out - don't care
* whether or not we _think_ the scanner is scanning now, * whether or not we _think_ the scanner is scanning now,
* because we may still have data left over to send */ * because we may still have data left over to send */
@ -1188,38 +1175,25 @@ sane_read (SANE_Handle h, SANE_Byte *buf, SANE_Int maxlen, SANE_Int *lenp)
return SANE_STATUS_GOOD; return SANE_STATUS_GOOD;
} }
} else { }
/* fix potential memory leak if cancelling at the very end
* of a scan */
if (lbuf != NULL) free(lbuf);
lbuf = NULL;
}
/* Has the last scan ended? */
/* Has the last scan ended (other than by cancelling)? */
if (((unsigned)cs->scan.height <= (unsigned)cs->lines_scanned) if (((unsigned)cs->scan.height <= (unsigned)cs->lines_scanned)
|| !(cs->scanning)) || (cs->sent_eof) || !(cs->scanning))
{ {
if (cs->cancelled) cs->sent_eof = SANE_TRUE;
{ cs->scanning = SANE_FALSE;
return SANE_STATUS_CANCELLED; cs->cancelled = SANE_FALSE;
} cs->lines_scanned = 0;
cs->bytes_sent = 0;
if (cs->sent_eof) read_leftover = NULL;
{ return SANE_STATUS_EOF;
/* It's over mate, get over it */
DBG(10, "sane_read: Already sent EOF!\n");
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;
}
} }
/* At this point we have to read more data from the scanner */ /* At this point we have to read more data from the scanner - or the
* scan has been cancelled, which means we have to call read_segment
* to leave the scanner consistant */
/* Decide how many lines we can fit into this buffer */ /* Decide how many lines we can fit into this buffer */
if (cs->vals[OPT_DEPTH] == 0) if (cs->vals[OPT_DEPTH] == 0)
@ -1227,21 +1201,9 @@ sane_read (SANE_Handle h, SANE_Byte *buf, SANE_Int maxlen, SANE_Int *lenp)
else else
bpl = cs->scan.width * (cs->vals[OPT_COLOUR_MODE] ? 6 : 2); bpl = cs->scan.width * (cs->vals[OPT_COLOUR_MODE] ? 6 : 2);
/* 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 /* New way: scan a whole scanner buffer full, and return as much as
* the frontend wants. It's faster and more reliable since the * the frontend wants. It's faster and more reliable since the
* scanners crack the shits if we ask for too many small packets */ * 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;
#endif
lines = (BUF_MAX * 4 / 5) / bpl; lines = (BUF_MAX * 4 / 5) / bpl;
if (lines > (cs->scan.height - cs->lines_scanned)) if (lines > (cs->scan.height - cs->lines_scanned))
@ -1276,23 +1238,30 @@ sane_read (SANE_Handle h, SANE_Byte *buf, SANE_Int maxlen, SANE_Int *lenp)
(cs->params.id_string)+8); (cs->params.id_string)+8);
DBG(10, "scan_params->: width=%d, height=%d, xoffset=%d, " DBG(10, "scan_params->: width=%d, height=%d, xoffset=%d, "
"yoffset=%d\n\txresolution=%d, yresolution=%d, " "yoffset=%d\n\txresolution=%d, yresolution=%d, "
"mode=%d\n", "mode=%d, (lines=%d)\n",
cs->scan.width, cs->scan.height, cs->scan.width, cs->scan.height,
cs->scan.xoffset, cs->scan.yoffset, cs->scan.xoffset, cs->scan.yoffset,
cs->scan.xresolution, cs->scan.yresolution, cs->scan.xresolution, cs->scan.yresolution,
cs->scan.mode cs->scan.mode, lines);
);
DBG(10, "lines=%d\n",lines);
DBG(2, ">> read_segment(%p, %p, %p, %d, %d, %d)\n", DBG(2, ">> read_segment(%p, %p, %p, %d, %d, %d)\n",
&is, &(cs->params), &(cs->scan), lines, &is, &(cs->params), &(cs->scan), lines,
cs->cal_valid, cs->scan.height - cs->lines_scanned); cs->cal_valid, cs->scan.height - cs->lines_scanned);
tmp = sanei_canon_pp_read_segment(&is, &(cs->params), tmp = sanei_canon_pp_read_segment(&is, &(cs->params), &(cs->scan),
&(cs->scan), lines, cs->cal_valid, lines, cs->cal_valid,
cs->scan.height - cs->lines_scanned); cs->scan.height - cs->lines_scanned);
DBG(2, "<< %d read_segment\n", tmp); DBG(2, "<< %d read_segment\n", tmp);
if (tmp != 0) { if (tmp != 0) {
if (cs->cancelled)
{
DBG(10, "sane_read: cancelling.\n");
cs->sent_eof = SANE_TRUE;
cs->scanning = SANE_FALSE;
read_leftover = NULL;
sanei_canon_pp_abort_scan(&(cs->params));
return SANE_STATUS_CANCELLED;
}
DBG(1, "sane_read: WARNING: read_segment returned %d!\n", tmp); DBG(1, "sane_read: WARNING: read_segment returned %d!\n", tmp);
return SANE_STATUS_IO_ERROR; return SANE_STATUS_IO_ERROR;
} }
@ -1386,31 +1355,22 @@ sane_read (SANE_Handle h, SANE_Byte *buf, SANE_Int maxlen, SANE_Int *lenp)
void void
sane_cancel (SANE_Handle h) sane_cancel (SANE_Handle h)
{ {
int tmp;
/* Note: assume handle is valid apart from NULLs */ /* Note: assume handle is valid apart from NULLs */
CANONP_Scanner *cs = ((CANONP_Scanner *)h); CANONP_Scanner *cs = ((CANONP_Scanner *)h);
DBG(2, ">> sane_cancel (h=%p)\n", h); DBG(2, ">> sane_cancel (h=%p)\n", h);
if (h == NULL) return; if (h == NULL) return;
if (cs->scanning == SANE_FALSE) read_leftover = NULL;
if (!(cs->scanning))
{ {
/* ensure we don't try to send old data */ DBG(2, "<< sane_cancel (not scanning)\n");
read_leftover = NULL;
return; return;
} }
cs->scanning = SANE_FALSE;
/* cs->sent_eof = SANE_TRUE; */
cs->cancelled = SANE_TRUE; cs->cancelled = SANE_TRUE;
cs->params.abort_now = 1;
cs->lines_scanned = 0;
cs->bytes_sent = 0;
DBG(2, "sane_cancel: >> abort_scan\n");
tmp = sanei_canon_pp_abort_scan(&(cs->params));
DBG(2, "sane_cancel: << abort_scan\n");
if (tmp != 0) {
DBG(1, "sane_cancel: WARNING: abort_scan returned %d!", tmp);
}
DBG(2, "<< sane_cancel\n"); DBG(2, "<< sane_cancel\n");
} }

Wyświetl plik

@ -10,7 +10,7 @@
:backend "canon_pp" ; name of backend :backend "canon_pp" ; name of backend
:manpage "sane-canon_pp" :manpage "sane-canon_pp"
:version "0.2" ; version of backend :version "0.3" ; version of backend
:status :alpha ; :alpha, :beta, :stable, :new :status :alpha ; :alpha, :beta, :stable, :new
:url "http://canon-fb330p.sourceforge.net" ; backend home page :url "http://canon-fb330p.sourceforge.net" ; backend home page

Wyświetl plik

@ -1,4 +1,4 @@
.TH sane-canon_pp 5 "4 September 2002" .TH sane-canon_pp 5 "1 October 2002"
.IX sane-canon_pp .IX sane-canon_pp
.SH NAME .SH NAME
sane-canon_pp - SANE backend for Canon CanoScan Parallel Port flatbed scanners sane-canon_pp - SANE backend for Canon CanoScan Parallel Port flatbed scanners
@ -28,7 +28,7 @@ CanoScan N640P ex
No USB scanners are supported and there are no plans to support them in the No USB scanners are supported and there are no plans to support them in the
future. Other projects are working on support for USB scanners. See the future. Other projects are working on support for USB scanners. See the
.B PROJECTS .B PROJECTS
file for more detail. The FB310P and FB610P are rebadged Avision scanners file for more detail. The FB310P and FB610P are re-badged Avision scanners
which use a different command set, so are unlikely to be supported by this which use a different command set, so are unlikely to be supported by this
backend in the future. backend in the future.
.PP .PP
@ -43,7 +43,7 @@ below).
.PP .PP
.SH "DEVICE NAMES" .SH "DEVICE NAMES"
This backend expects device names of the form presented by libieee1284. These This backend expects device names of the form presented by libieee1284. These
names are highly dependant on operating system and version. names are highly dependent on operating system and version.
On Linux 2.4 kernels this will be of the form On Linux 2.4 kernels this will be of the form
.I "parport0" .I "parport0"
@ -71,20 +71,20 @@ and
Option Option
.B ieee1284 .B ieee1284
.IR portname .IR port-name
defines which port to use. The format of portname is OS dependant, based on defines which port to use. The format of port-name is OS dependent, based on
the names presented by libieee1284. Please only have one of these lines, or the names presented by libieee1284. Please only have one of these lines, or
all but one will be ignored. all but one will be ignored.
Option Option
.B calibrate .B calibrate
.IR cal-file .IR cal-file
.IR [portname] .IR [port-name]
defines which calibration file to use on a per-port basis. If you only have defines which calibration file to use on a per-port basis. If you only have
one parport, the portname argument may be omitted - but be careful as this one parport, the port-name argument may be omitted - but be careful as this
will cause problems on multi-scanner systems. You may have as many of these will cause problems on multi-scanner systems. You may have as many of these
lines as you like, as long as each has a unique port name. The tilde (`~') lines as you like, as long as each has a unique port name. The tilde (`~')
character is acceptable and will be expaned to the value of the HOME character is acceptable and will be expanded to the value of the HOME
environment. environment.
Option Option
@ -156,12 +156,12 @@ export SANE_DEBUG_CANON_PP=4
.TP .TP
.B Brightness and Contrast .B Brightness and Contrast
These are not implemented, and probably never will be. These appear to be These are not implemented, and probably never will be. These appear to be
implented entirely in software. Use GIMP or a similar program if you need implemented entirely in software. Use GIMP or a similar program if you need
these features. these features.
.TP .TP
.B Descreen Mode .B Descreen Mode
This appears on our first analysis to be just oversampling with an This appears on our first analysis to be just oversampling with an
anti-aliasing filter. Again, it seems to be implemeneted entirely in software, anti-aliasing filter. Again, it seems to be implemented entirely in software,
so GIMP is your best bet for now. so GIMP is your best bet for now.
.TP .TP
.B Gamma Tables .B Gamma Tables
@ -171,14 +171,14 @@ one returned during calibration) will be loaded.
.B Communication Problems .B Communication Problems
.PP .PP
ECP mode in libieee1284 doesn't always work properly, even with new hardware. ECP mode in libieee1284 doesn't always work properly, even with new hardware.
We beleive that this is a ppdev problem. If you change the configuration file We believe that this is a ppdev problem. If you change the configuration file
to include to include
.B force_nibble .B force_nibble
, the problem will go away, but you will only be able to scan in nibble mode. , the problem will go away, but you will only be able to scan in nibble mode.
.PP .PP
Sometimes the scanner can be left in a state where our code cannot revive it. Sometimes the scanner can be left in a state where our code cannot revive it.
If the backend reports no scanner present, try unplugging the power and If the backend reports no scanner present, try unplugging the power and
plugging it back in. Also try unplugging printers from the passthrough port. plugging it back in. Also try unplugging printers from the pass-through port.
.PP .PP
The scanner will not respond correctly to our commands when you first plug in The scanner will not respond correctly to our commands when you first plug in
the power. You may find if you try a scan very soon after plugging in the the power. You may find if you try a scan very soon after plugging in the
@ -197,13 +197,26 @@ 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, 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. there's currently no nice way to deal with the problem.
.PP .PP
.B Greyscale Scans .B Grey-scale Scans
.PP .PP
Be aware that the scanner uses the green LEDs to read greyscale scans, meaning Be aware that the scanner uses the green LEDs to read grey-scale scans, meaning
green coloured things will appear lighter than normal, and red and blue green coloured things will appear lighter than normal, and red and blue
coloured items will appear darker than normal. For high-accuracy greyscale coloured items will appear darker than normal. For high-accuracy grey-scale
scans of colour items, it's best just to scan in colour and convert to scans of colour items, it's best just to scan in colour and convert to
greyscale in graphics software such as the GIMP. grey-scale in graphics software such as the GIMP.
.PP
.B FB620P/FB320P Caveats
.PP
These models can not be reset in the same way as the others. The windows driver
doesn't know how to reset them either - when left with an inconsistent scanner,
it will start scanning half way down the page!
.PP
Aborting is known to work correctly on the FB*30P models, and is known to be
broken on the FB*20P models. The FB620P which I tested on simply returns
garbage after a scan has been aborted using the method we know.
Aborting is able to leave the scanner in a state where it can be shut down,
but not where another scan can be made.
.SH "SEE ALSO" .SH "SEE ALSO"
sane(7), sane-dll(5) sane(7), sane-dll(5)