kopia lustrzana https://gitlab.com/sane-project/backends
* 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
rodzic
2958f7a844
commit
284233e77e
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
Ładowanie…
Reference in New Issue