From 284233e77e7ad44b3b1336f4098751492b7af674 Mon Sep 17 00:00:00 2001 From: Matthew Duggan Date: Mon, 30 Sep 2002 15:25:14 +0000 Subject: [PATCH] * 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. --- backend/canon_pp-dev.c | 28 ++++---- backend/canon_pp-dev.h | 4 +- backend/canon_pp.c | 114 +++++++++++---------------------- doc/descriptions/canon_pp.desc | 2 +- doc/sane-canon_pp.man | 45 ++++++++----- 5 files changed, 82 insertions(+), 111 deletions(-) diff --git a/backend/canon_pp-dev.c b/backend/canon_pp-dev.c index 5beb2c148..ce2fb36b1 100644 --- a/backend/canon_pp-dev.c +++ b/backend/canon_pp-dev.c @@ -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) { diff --git a/backend/canon_pp-dev.h b/backend/canon_pp-dev.h index dd9f7ae6c..e8f36a8a8 100644 --- a/backend/canon_pp-dev.h +++ b/backend/canon_pp-dev.h @@ -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); diff --git a/backend/canon_pp.c b/backend/canon_pp.c index 0d21a067b..7d921b7d2 100644 --- a/backend/canon_pp.c +++ b/backend/canon_pp.c @@ -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"); } diff --git a/doc/descriptions/canon_pp.desc b/doc/descriptions/canon_pp.desc index 1d21ae870..2949d24e3 100644 --- a/doc/descriptions/canon_pp.desc +++ b/doc/descriptions/canon_pp.desc @@ -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 diff --git a/doc/sane-canon_pp.man b/doc/sane-canon_pp.man index afc2bce7b..906d57c6f 100644 --- a/doc/sane-canon_pp.man +++ b/doc/sane-canon_pp.man @@ -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)