* 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;*/
static const char *header = "#CANONPP";
static const int fileversion = 3;
static int abort_now = 0;
/* Internal functions */
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 */
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);
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 -
* 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))
{
@ -739,10 +739,11 @@ int sanei_canon_pp_read_segment(image_segment **dest, scanner_parameters *sp,
return 0;
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 (input_buffer) free(input_buffer);
abort_now = 0;
sp->abort_now = 0;
return -1;
}
@ -970,7 +971,7 @@ int sanei_canon_pp_calibrate(scanner_parameters *sp, char *cal_file)
if (!(sp->type) ) scanline_count = 8;
/* 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 "
"(%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,
calibration_reads);
if (abort_now) return -1;
if (sp->abort_now) return -1;
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, " * 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))
{
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);
DBG(40, "done.\n");
if (abort_now) return -1;
if (sp->abort_now) return -1;
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,
calibration_reads);
if (abort_now) return -1;
if (sp->abort_now) return -1;
if (send_command(sp->port, command_buffer, 10,
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 */
if (cal_file != NULL)
@ -1290,11 +1291,6 @@ int sanei_canon_pp_abort_scan(scanner_parameters *sp)
return 0;
}
void sanei_canon_pp_abort(void)
{
abort_now = 1;
}
/* adjust_gamma: Upload a gamma profile to the scanner */
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] ) */
unsigned char type;
/* Are we aborting this scanner now */
unsigned char abort_now;
} scanner_parameters;
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 sanei_canon_pp_abort_scan(scanner_parameters *sp);
void sanei_canon_pp_abort(void);
/* Loads the gain offset values. Needs a new name. */
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->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");
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))
{
DBG(1, "sane_read: This frontend's passing me dodgy gear! "
"(h=%p, buf=%p, lenp=%p)\n",
h, buf, lenp);
"(h=%p, buf=%p, lenp=%p)\n", h, buf, lenp);
return SANE_STATUS_INVAL;
}
/* 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
* whether or not we _think_ the scanner is scanning now,
* 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;
}
} 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)
|| !(cs->scanning))
|| (cs->sent_eof) || !(cs->scanning))
{
if (cs->cancelled)
{
return SANE_STATUS_CANCELLED;
}
if (cs->sent_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;
}
cs->sent_eof = SANE_TRUE;
cs->scanning = SANE_FALSE;
cs->cancelled = SANE_FALSE;
cs->lines_scanned = 0;
cs->bytes_sent = 0;
read_leftover = NULL;
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 */
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
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
* 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;
#endif
lines = (BUF_MAX * 4 / 5) / bpl;
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);
DBG(10, "scan_params->: width=%d, height=%d, xoffset=%d, "
"yoffset=%d\n\txresolution=%d, yresolution=%d, "
"mode=%d\n",
"mode=%d, (lines=%d)\n",
cs->scan.width, cs->scan.height,
cs->scan.xoffset, cs->scan.yoffset,
cs->scan.xresolution, cs->scan.yresolution,
cs->scan.mode
);
DBG(10, "lines=%d\n",lines);
cs->scan.mode, lines);
DBG(2, ">> read_segment(%p, %p, %p, %d, %d, %d)\n",
&is, &(cs->params), &(cs->scan), lines,
cs->cal_valid, cs->scan.height - cs->lines_scanned);
tmp = sanei_canon_pp_read_segment(&is, &(cs->params),
&(cs->scan), lines, cs->cal_valid,
tmp = sanei_canon_pp_read_segment(&is, &(cs->params), &(cs->scan),
lines, cs->cal_valid,
cs->scan.height - cs->lines_scanned);
DBG(2, "<< %d read_segment\n", tmp);
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);
return SANE_STATUS_IO_ERROR;
}
@ -1386,31 +1355,22 @@ sane_read (SANE_Handle h, SANE_Byte *buf, SANE_Int maxlen, SANE_Int *lenp)
void
sane_cancel (SANE_Handle h)
{
int tmp;
/* Note: assume handle is valid apart from NULLs */
CANONP_Scanner *cs = ((CANONP_Scanner *)h);
DBG(2, ">> sane_cancel (h=%p)\n", h);
if (h == NULL) return;
if (cs->scanning == SANE_FALSE)
read_leftover = NULL;
if (!(cs->scanning))
{
/* ensure we don't try to send old data */
read_leftover = NULL;
DBG(2, "<< sane_cancel (not scanning)\n");
return;
}
cs->scanning = SANE_FALSE;
/* cs->sent_eof = SANE_TRUE; */
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));
DBG(2, "sane_cancel: << abort_scan\n");
if (tmp != 0) {
DBG(1, "sane_cancel: WARNING: abort_scan returned %d!", tmp);
}
cs->params.abort_now = 1;
DBG(2, "<< sane_cancel\n");
}

Wyświetl plik

@ -10,7 +10,7 @@
:backend "canon_pp" ; name of backend
:manpage "sane-canon_pp"
:version "0.2" ; version of backend
:version "0.3" ; version of backend
:status :alpha ; :alpha, :beta, :stable, :new
: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
.SH NAME
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
future. Other projects are working on support for USB scanners. See the
.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
backend in the future.
.PP
@ -43,7 +43,7 @@ below).
.PP
.SH "DEVICE NAMES"
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
.I "parport0"
@ -71,20 +71,20 @@ and
Option
.B ieee1284
.IR portname
defines which port to use. The format of portname is OS dependant, based on
.IR port-name
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
all but one will be ignored.
Option
.B calibrate
.IR cal-file
.IR [portname]
.IR [port-name]
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
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.
Option
@ -156,12 +156,12 @@ export SANE_DEBUG_CANON_PP=4
.TP
.B Brightness and Contrast
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.
.TP
.B Descreen Mode
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.
.TP
.B Gamma Tables
@ -171,14 +171,14 @@ one returned during calibration) will be loaded.
.B Communication Problems
.PP
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
.B force_nibble
, the problem will go away, but you will only be able to scan in nibble mode.
.PP
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
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
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
@ -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,
there's currently no nice way to deal with the problem.
.PP
.B Greyscale Scans
.B Grey-scale Scans
.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
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
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"
sane(7), sane-dll(5)