diff --git a/backend/snapscan-scsi.c b/backend/snapscan-scsi.c index b1c8c96a3..bc294be7a 100644 --- a/backend/snapscan-scsi.c +++ b/backend/snapscan-scsi.c @@ -78,11 +78,13 @@ static SANE_Status sense_handler (int scsi_fd, u_char * result, void *arg) pss->asi1 = result[18]; pss->asi2 = result[19]; } - if ((result[0] & 0x80) == 0) { DBG (DL_DATA_TRACE, "%s: sense key is invalid.\n", me); return SANE_STATUS_GOOD; /* sense key invalid */ + } else { + DBG (DL_DATA_TRACE, "%s: sense key: 0x%02x, asc: 0x%02x, ascq: 0x%02x, i1: 0x%02x, i2: 0x%02x\n", + me, sense, asc, ascq, result[18], result[19]); } switch (sense) @@ -90,49 +92,61 @@ static SANE_Status sense_handler (int scsi_fd, u_char * result, void *arg) case 0x00: /* no sense */ sense_str = "No sense."; + DBG (DL_MINOR_INFO, "%s: %s\n", me, sense_str); break; case 0x02: /* not ready */ sense_str = "Not ready."; + DBG (DL_MINOR_INFO, "%s: %s\n", me, sense_str); if (asc == 0x04 && ascq == 0x01) { /* warming up; byte 18 contains remaining seconds */ as_str = "Logical unit is in process of becoming ready."; + DBG (DL_MINOR_INFO, "%s: %s (%d seconds)\n", me, as_str, result[18]); status = SANE_STATUS_DEVICE_BUSY; + DBG (DL_MINOR_INFO, "%s: %s\n", me, sense_str); } break; case 0x04: /* hardware error */ sense_str = "Hardware error."; /* byte 18 and 19 detail the hardware problems */ + DBG (DL_MINOR_INFO, "%s: %s (0x%02x, 0x%02x)\n", me, sense_str, result[18], + result[19]); status = SANE_STATUS_IO_ERROR; break; case 0x05: /* illegal request */ sense_str = "Illegal request."; + DBG (DL_MINOR_INFO, "%s: %s\n", me, sense_str); if (asc == 0x25 && ascq == 0x00) as_str = "Logical unit not supported."; + DBG (DL_MINOR_INFO, "%s: %s\n", me, as_str); status = SANE_STATUS_IO_ERROR; break; case 0x09: /* process error */ sense_str = "Process error."; + DBG (DL_MINOR_INFO, "%s: %s\n", me, sense_str); if (asc == 0x00 && ascq == 0x05) { /* no documents in ADF */ as_str = "End of data detected."; + DBG (DL_MINOR_INFO, "%s: %s\n", me, as_str); status = SANE_STATUS_NO_DOCS; } else if (asc == 0x3b && ascq == 0x05) { /* paper jam in ADF */ as_str = "Paper jam."; + DBG (DL_MINOR_INFO, "%s: %s\n", me, as_str); status = SANE_STATUS_JAMMED; } else if (asc == 0x3b && ascq == 0x09) { /* scanning area exceeds end of paper in ADF */ as_str = "Read past end of medium."; + DBG (DL_MINOR_INFO, "%s: %s\n", me, as_str); status = SANE_STATUS_EOF; } break; @@ -163,7 +177,8 @@ static SANE_Status open_scanner (SnapScan_Scanner *pss) } else { - status = snapscani_usb_open (pss->devname, &(pss->fd)); + status = snapscani_usb_open (pss->devname, &(pss->fd), + sense_handler, (void *) pss); } } else @@ -435,17 +450,20 @@ static SANE_Status inquiry (SnapScan_Scanner *pss) default: { signed char min_diff; + u_char r_off, g_off, b_off; signed char g = (pss->buf[INQUIRY_G2R_DIFF] & 0x80) ? -(pss->buf[INQUIRY_G2R_DIFF] & 0x7F) : pss->buf[INQUIRY_G2R_DIFF]; signed char b = (pss->buf[INQUIRY_B2R_DIFF] & 0x80) ? -(pss->buf[INQUIRY_B2R_DIFF] & 0x7F) : pss->buf[INQUIRY_B2R_DIFF]; DBG (DL_DATA_TRACE, "%s: G2R_DIFF: %d\n", me, pss->buf[INQUIRY_G2R_DIFF]); DBG (DL_DATA_TRACE, "%s: B2R_DIFF: %d\n", me, pss->buf[INQUIRY_B2R_DIFF]); min_diff = MIN (MIN (b, g), 0); - - pss->chroma_offset[R_CHAN] = (u_char) (0 - min_diff); - pss->chroma_offset[G_CHAN] = (u_char) (g - min_diff); - pss->chroma_offset[B_CHAN] = (u_char) (b - min_diff); - pss->chroma = abs(min_diff); + r_off = (u_char) (0 - min_diff); + g_off = (u_char) (g - min_diff); + b_off = (u_char) (b - min_diff); + pss->chroma_offset[R_CHAN] = r_off; + pss->chroma_offset[G_CHAN] = g_off; + pss->chroma_offset[B_CHAN] = b_off; + pss->chroma = MAX(MAX(r_off, g_off), b_off); DBG (DL_DATA_TRACE, "%s: Chroma offsets=%d; Red=%u, Green:=%u, Blue=%u\n", me, pss->chroma, @@ -799,19 +817,21 @@ static SANE_Status set_window (SnapScan_Scanner *pss) && pss->pdev->model != VUEGO310S && - pss->pdev->model != VUEGO610S) - { - pc[SET_WINDOW_P_DEBUG_MODE] = 2; /* use full 128k buffer */ - pc[SET_WINDOW_P_GAMMA_NO] = 0x01; /* downloaded table */ - } - if (pss->preview) { - source = 0x20 + 0x40; - - } else { - source = 0x20 + 0x80; + pss->pdev->model != VUEGO610S + ) { + pc[SET_WINDOW_P_DEBUG_MODE] = 2; /* use full 128k buffer */ + pc[SET_WINDOW_P_GAMMA_NO] = 0x01; /* downloaded table */ + } + source = 0x20; + if (pss->preview) { + source |= 0x80; /* no high quality */ + } else { + source |= 0x40; /* no preview */ + } + + if (pss->source == SRC_TPO) { + source |= 0x08; } - if (pss->source == SRC_TPO) - source |= 0x08; pc[SET_WINDOW_P_OPERATION_MODE] = source; DBG (DL_DATA_TRACE, "%s: operation mode set to %d\n", me, (int) source); pc[SET_WINDOW_P_RED_UNDER_COLOR] = 0xff; /* defaults */ @@ -918,33 +938,29 @@ static SANE_Status wait_scanner_ready (SnapScan_Scanner *pss) for (retries = 5; retries; retries--) { status = test_unit_ready (pss); - if (status == SANE_STATUS_GOOD) + switch (status) { - status = request_sense (pss); - switch (status) + case SANE_STATUS_GOOD: + return status; + case SANE_STATUS_DEVICE_BUSY: + /* first additional sense byte contains time to wait */ { - case SANE_STATUS_GOOD: - return status; - case SANE_STATUS_DEVICE_BUSY: - /* first additional sense byte contains time to wait */ - { - int delay = pss->asi1 + 1; - DBG (DL_INFO, - "%s: scanner warming up. Waiting %ld seconds.\n", - me, (long) delay); - sleep (delay); - } - break; - case SANE_STATUS_IO_ERROR: - /* hardware error; bail */ - DBG (DL_MAJOR_ERROR, "%s: hardware error detected.\n", me); - return status; - default: - DBG (DL_MAJOR_ERROR, - "%s: unhandled request_sense result; trying again.\n", - me); - break; + int delay = pss->asi1 + 1; + DBG (DL_INFO, + "%s: scanner warming up. Waiting %ld seconds.\n", + me, (long) delay); + sleep (delay); } + break; + case SANE_STATUS_IO_ERROR: + /* hardware error; bail */ + DBG (DL_MAJOR_ERROR, "%s: hardware error detected.\n", me); + return status; + default: + DBG (DL_MAJOR_ERROR, + "%s: unhandled request_sense result; trying again.\n", + me); + break; } } @@ -1159,11 +1175,28 @@ static SANE_Status download_firmware(SnapScan_Scanner * pss) /* * $Log$ - * Revision 1.8 2001/10/22 22:14:20 oliverschwartz - * Limit number of scan lines for quality calibration to fit in SCSI buffer (thanks to Mikko Työläjärvi) + * Revision 1.9 2001/12/17 22:51:49 oliverschwartz + * Update to snapscan-20011212 (snapscan 1.4.3) * - * Revision 1.7 2001/10/12 21:19:13 oliverschwartz - * update to snapscan-20011012 + * Revision 1.25 2001/12/12 19:44:59 oliverschwartz + * Clean up CVS log + * + * Revision 1.24 2001/12/09 23:01:00 oliverschwartz + * - use sense handler for USB + * - fix scan mode + * + * Revision 1.23 2001/12/08 11:53:31 oliverschwartz + * - Additional logging in sense handler + * - Fix wait_scanner_ready() if device reports busy + * - Fix scanning mode (preview/normal) + * + * Revision 1.22 2001/11/27 23:16:17 oliverschwartz + * - Fix color alignment for SnapScan 600 + * - Added documentation in snapscan-sources.c + * - Guard against TL_X < BR_X and TL_Y < BR_Y + * + * Revision 1.21 2001/10/21 08:49:37 oliverschwartz + * correct number of scan lines for calibration thanks to Mikko Työläjärvi * * Revision 1.20 2001/10/12 20:54:04 oliverschwartz * enable gamma correction for Snapscan 1236, e20 and e50 scanners @@ -1205,15 +1238,6 @@ static SANE_Status download_firmware(SnapScan_Scanner * pss) * Applying Mikael Magnusson patch concerning Gamma correction * Support for 1212U_2 * - * Revision 1.3 2001/03/04 16:37:57 mikael - * Remove brightness and contrast settings in window. - * - * Revision 1.2 2001/02/16 18:32:28 mikael - * impl calibration, signed position, increased buffer size - * - * Revision 1.1.1.1 2001/02/10 17:09:29 mikael - * Imported from snapscan-11282000.tar.gz - * * Revision 1.9 2000/11/10 01:01:59 sable * USB (kind of) autodetection * @@ -1239,19 +1263,4 @@ static SANE_Status download_firmware(SnapScan_Scanner * pss) * Revision 1.2 2000/10/13 03:50:27 cbagwell * Updating to source from SANE 1.0.3. Calling this versin 1.1 * - * Revision 1.3 2000/08/12 15:09:34 pere - * Merge devel (v1.0.3) into head branch. - * - * Revision 1.1.2.3 2000/07/17 21:37:27 hmg - * 2000-07-17 Henning Meier-Geinitz - * - * * backend/snapscan.c backend/snapscan-scsi.c: Replace C++ comment - * with C comment. - * - * Revision 1.1.2.2 2000/07/13 04:47:44 pere - * New snapscan backend version dated 20000514 from Steve Underwood. - * - * Revision 1.2.1 2000/05/14 13:30:20 coppice - * Added history log to pre-existing code. Some reformatting and minor - * tidying. * */ diff --git a/backend/snapscan-sources.c b/backend/snapscan-sources.c index 39134a45e..c79bdd65c 100644 --- a/backend/snapscan-sources.c +++ b/backend/snapscan-sources.c @@ -50,6 +50,61 @@ /* $Id$ SnapScan backend data sources (implementation) */ +/************************************************************************************** +If you get confused from all the structs (like I did when I first saw them), +think of it as "C++ in C". If you're accustomed to OO and UML maybe the +following diagram helps you to make sense of it: + + ------------------------ + ! Source ! + ------------------------ + !pss: SnapScan_Scanner*! + ------------------------ +psub + !init() = 0 !----------------- + !remaining() = 0 ! ! + !bytesPerLine() ! ! + !pixelsPerLine() ! ! + !get() = 0 ! !{TransformerSource forwards + !done() = 0 ! ! function calls to corres- + ------------------------ ! ponding functions in psub} + ^ ! + /_\ ! + ! ! + -------------------------------------------------- /\ + ! ! ! ! \/ +------------- ------------- ------------- ------------------- +!SCSISource ! ! FDSource ! !BufSource ! !TransformerSource! +============= ============= ============= =================== +!remaining()! !remaining()! !remaining()! !init() ! +!get() ! !get() ! !get() ! !remaining() ! +!done() ! !done() ! !done() ! !bytesPerLine() ! +!init() ! !init() ! !init() ! !pixelsPerLine() ! +------------- ------------- ------------- !get() ! + !done() ! + ------------------- + ^ + /_\ + ! + ------------------------------------ + ! ! ! + ---------------- ------------- ------------- + ! Expander ! ! RGBRouter ! ! Inverter ! + ================ ============= ============= + !remaining() ! !remaining()! !remaining()! + !bytesPerLine()! !get() ! !get() ! + !get() ! !done() ! !done() ! + !done() ! !init() ! !init() ! + !init() ! ------------- ------------- + ---------------- +All instances of the descendants of TransformerSource can be chained together. For +color scanning, a typical source chain would consist of an RGBRouter sitting on top +of a SCSISource. In the get() method, RGBRouter will then call the get() method of +the subsource, process the data and return it. + +I hope this makes sense to you (and I got the right idea of the original author's +intention). +***********************************************************************************/ + #ifndef __FUNCTION__ #define __FUNCTION__ "(undef)" #endif @@ -910,8 +965,16 @@ static SANE_Status create_source_chain (SnapScan_Scanner *pss, /* * $Log$ - * Revision 1.5 2001/10/09 09:45:12 oliverschwartz - * update snapscan to snapshot 20011008 + * Revision 1.6 2001/12/17 22:51:49 oliverschwartz + * Update to snapscan-20011212 (snapscan 1.4.3) + * + * Revision 1.18 2001/12/12 19:44:59 oliverschwartz + * Clean up CVS log + * + * Revision 1.17 2001/11/27 23:16:17 oliverschwartz + * - Fix color alignment for SnapScan 600 + * - Added documentation in snapscan-sources.c + * - Guard against TL_X < BR_X and TL_Y < BR_Y * * Revision 1.16 2001/10/08 18:22:02 oliverschwartz * - Disable quality calibration for Acer Vuego 310F @@ -946,15 +1009,6 @@ static SANE_Status create_source_chain (SnapScan_Scanner *pss, * Applying Mikael Magnusson patch concerning Gamma correction * Support for 1212U_2 * - * Revision 1.3 2001/03/04 16:53:21 mikael - * Reading absolute max from SNAPSCAN 1212U - * - * Revision 1.2 2001/02/16 18:32:28 mikael - * impl calibration, signed position, increased buffer size - * - * Revision 1.1.1.1 2001/02/10 17:09:29 mikael - * Imported from snapscan-11282000.tar.gz - * * Revision 1.8 2000/11/28 03:55:07 cbagwell * Reverting a fix to RGBRouter_remaining to original fix. This allows * most scanners to scan at 600 dpi by ignoring insufficent data in @@ -982,15 +1036,4 @@ static SANE_Status create_source_chain (SnapScan_Scanner *pss, * * Revision 1.2 2000/10/13 03:50:27 cbagwell * Updating to source from SANE 1.0.3. Calling this versin 1.1 - * - * Revision 1.3 2000/08/12 15:09:35 pere - * Merge devel (v1.0.3) into head branch. - * - * Revision 1.1.2.2 2000/07/13 04:47:45 pere - * New snapscan backend version dated 20000514 from Steve Underwood. - * - * Revision 1.2.1 2000/05/14 13:30:20 coppice - * Added history log to pre-existing code.Some reformatting. - * R, G and B images now merge correctly. There are still some outstanding - * issues in this area, but its a lot more usable than before. * */ diff --git a/backend/snapscan-sources.h b/backend/snapscan-sources.h index 57d78acc5..53b705be2 100644 --- a/backend/snapscan-sources.h +++ b/backend/snapscan-sources.h @@ -88,8 +88,11 @@ static SANE_Status Source_init (Source *pself, /* * $Log$ - * Revision 1.4 2001/10/09 09:45:13 oliverschwartz - * update snapscan to snapshot 20011008 + * Revision 1.5 2001/12/17 22:51:50 oliverschwartz + * Update to snapscan-20011212 (snapscan 1.4.3) + * + * Revision 1.5 2001/12/12 19:44:59 oliverschwartz + * Clean up CVS log * * Revision 1.4 2001/09/18 15:01:07 oliverschwartz * - Read scanner id string again after firmware upload @@ -101,18 +104,6 @@ static SANE_Status Source_init (Source *pself, * Applying Mikael Magnusson patch concerning Gamma correction * Support for 1212U_2 * - * Revision 1.1.1.1 2001/02/10 17:09:29 mikael - * Imported from snapscan-11282000.tar.gz - * * Revision 1.2 2000/10/13 03:50:27 cbagwell * Updating to source from SANE 1.0.3. Calling this versin 1.1 - * - * Revision 1.2 2000/08/12 15:09:35 pere - * Merge devel (v1.0.3) into head branch. - * - * Revision 1.1.2.1 2000/07/13 04:47:46 pere - * New snapscan backend version dated 20000514 from Steve Underwood. - * - * Revision 1.1.1 2000/05/14 13:30:20 coppice - * Added history log to pre-existing code. Some reformatting. * */ diff --git a/backend/snapscan-usb.c b/backend/snapscan-usb.c index df2440866..57df2dc5d 100644 --- a/backend/snapscan-usb.c +++ b/backend/snapscan-usb.c @@ -4,7 +4,7 @@ Copyright (C) 2000 Henrik Johansson Henrik Johansson (henrikjo@post.urfors.se) - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the @@ -60,6 +60,11 @@ static int sem_id; static struct sembuf sem_wait = { 0, -1, 0 }; static struct sembuf sem_signal = { 0, 1, 0 }; +static sense_handler_type usb_sense_handler; +static void* usb_pss; + +/* Forward declarations */ +static SANE_Status usb_request_sense(SnapScan_Scanner *pss); static SANE_Status snapscani_usb_cmd(int fd, const void *src, size_t src_size, void *dst, size_t * dst_size) @@ -123,7 +128,8 @@ static SANE_Status atomic_usb_cmd(int fd, const void *src, size_t src_size, } -static SANE_Status snapscani_usb_open(const char *dev, int *fdp) +static SANE_Status snapscani_usb_open(const char *dev, int *fdp, + sense_handler_type sense_handler, void* pss) { static const char me[] = "snapscani_usb_open"; @@ -135,6 +141,8 @@ static SANE_Status snapscani_usb_open(const char *dev, int *fdp) } semop(sem_id, &sem_signal, 1); sanei_usb_init(); + usb_sense_handler=sense_handler; + usb_pss = pss; return sanei_usb_open(dev, fdp); } @@ -184,24 +192,6 @@ static char *usb_debug_data(char *str,const char *data, int len) { return str; } -/* -static int usb_status(char *status_buf) { - int status; - - status = (status_buf[1] & STATUS_MASK) >> 1; - - switch(status) { - case GOOD: - return SANE_STATUS_GOOD; - case CHECK_CONDITION: - case BUSY: - return SANE_STATUS_DEVICE_BUSY; - default: - return SANE_STATUS_IO_ERROR; - } -} -*/ - #define RETURN_ON_FAILURE(x) if((status = x) != SANE_STATUS_GOOD) return status; static SANE_Status usb_write(int fd, const void *buf, int n) { @@ -249,6 +239,7 @@ static SANE_Status usb_read(int fd, void *buf, int n) { static SANE_Status usb_read_status(int fd, int *scsistatus, int *transaction_status) { + static const char me[] = "usb_read_status"; unsigned char status_buf[8]; int scsistat; int status; @@ -267,6 +258,14 @@ static SANE_Status usb_read_status(int fd, int *scsistatus, int *transaction_sta case GOOD: return SANE_STATUS_GOOD; case CHECK_CONDITION: + if (usb_pss != NULL) { + return usb_request_sense(usb_pss); + } else { + DBG (DL_MAJOR_ERROR, "%s: scanner structure not set, returning default error\n", + me); + return SANE_STATUS_DEVICE_BUSY; + } + break; case BUSY: return SANE_STATUS_DEVICE_BUSY; default: @@ -402,15 +401,48 @@ static void dequeue_bq() bqelements--; DBG(DL_DATA_TRACE, "%s: Busy queue: elements=%d, bqhead=%p, bqtail=%p\n", me,bqelements,bqhead,bqtail); - } + +static SANE_Status usb_request_sense(SnapScan_Scanner *pss) { + static const char *me = "usb_request_sense"; + size_t read_bytes = 0; + u_char cmd[] = {REQUEST_SENSE, 0, 0, 0, 20, 0}; + u_char data[20]; + SANE_Status status; + + read_bytes = 20; + + DBG (DL_CALL_TRACE, "%s\n", me); + status = usb_cmd (pss->fd, cmd, sizeof (cmd), data, &read_bytes); + if (status != SANE_STATUS_GOOD) + { + DBG (DL_MAJOR_ERROR, "%s: usb command error: %s\n", + me, sane_strstatus (status)); + } + else + { + if (usb_sense_handler) { + status = usb_sense_handler (pss->fd, data, (void *) pss); + } else { + DBG (DL_MAJOR_ERROR, "%s: No sense handler for USB\n", me); + status = SANE_STATUS_UNSUPPORTED; + } + } + return status; +} + /* * $Log$ - * Revision 1.4 2001/10/27 09:08:13 oliverschwartz - * Check USB vendor IDs to avoid hanging scanners, fix bug in dither matrix computation + * Revision 1.5 2001/12/17 22:51:50 oliverschwartz + * Update to snapscan-20011212 (snapscan 1.4.3) * - * Revision 1.3 2001/10/10 07:30:06 oliverschwartz - * fix compiler warnings + * Revision 1.15 2001/12/09 23:06:44 oliverschwartz + * - use sense handler for USB if scanner reports CHECK_CONDITION + * + * Revision 1.14 2001/11/16 20:23:16 oliverschwartz + * Merge with sane-1.0.6 + * - Check USB vendor IDs to avoid hanging scanners + * - fix bug in dither matrix computation * * Revision 1.13 2001/10/09 22:34:23 oliverschwartz * fix compiler warnings diff --git a/backend/snapscan-usb.h b/backend/snapscan-usb.h index af56a237a..311101f5b 100644 --- a/backend/snapscan-usb.h +++ b/backend/snapscan-usb.h @@ -30,9 +30,12 @@ #ifndef snapscan_usb_h #define snapscan_usb_h +typedef SANE_Status (*sense_handler_type)(int fd, u_char *sense_buffer, void *arg); + static SANE_Status snapscani_usb_cmd(int fd, const void *src, size_t src_size, void *dst, size_t * dst_size); -static SANE_Status snapscani_usb_open(const char *dev, int *fdp); +static SANE_Status snapscani_usb_open(const char *dev, int *fdp, + sense_handler_type, void*); static void snapscani_usb_close(int fd); /* @@ -82,11 +85,16 @@ static SANE_Status usb_cmd(int fd, const void *src, size_t src_size, /* * $Log$ - * Revision 1.3 2001/10/27 09:08:14 oliverschwartz - * Check USB vendor IDs to avoid hanging scanners, fix bug in dither matrix computation + * Revision 1.4 2001/12/17 22:51:50 oliverschwartz + * Update to snapscan-20011212 (snapscan 1.4.3) * - * Revision 1.2 2001/10/09 09:45:15 oliverschwartz - * update snapscan to snapshot 20011008 + * Revision 1.10 2001/12/09 23:06:45 oliverschwartz + * - use sense handler for USB if scanner reports CHECK_CONDITION + * + * Revision 1.9 2001/11/16 20:23:16 oliverschwartz + * Merge with sane-1.0.6 + * - Check USB vendor IDs to avoid hanging scanners + * - fix bug in dither matrix computation * * Revision 1.8 2001/09/18 15:01:07 oliverschwartz * - Read scanner id string again after firmware upload diff --git a/backend/snapscan.c b/backend/snapscan.c index 3c78f503b..e38b4a212 100644 --- a/backend/snapscan.c +++ b/backend/snapscan.c @@ -78,7 +78,7 @@ #define EXPECTED_MAJOR 1 #define MINOR_VERSION 4 -#define BUILD 0 +#define BUILD 3 #include "snapscan.h" @@ -396,6 +396,7 @@ static void init_options (SnapScan_Scanner * ps) po[OPT_SCANRES].constraint.word_list = resolutions_300; break; case SNAPSCANE50: + case SNAPSCANE52: case PRISA5300: case PRISA1240: po[OPT_SCANRES].constraint.word_list = resolutions_1200; @@ -589,8 +590,11 @@ static void init_options (SnapScan_Scanner * ps) po[OPT_QUALITY_CAL].constraint_type = SANE_CONSTRAINT_NONE; po[OPT_QUALITY_CAL].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; ps->val[OPT_QUALITY_CAL].b = DEFAULT_QUALITY; - /* Disable quality calibration option if not supported */ - if (!(ps->hconfig & HCFG_CAL_ALLOWED)) { + /* Disable quality calibration option if not supported + Note: Snapscan e52 does not support quality calibration, + although HCFG_CAL_ALLOWED is set. */ + if ((!(ps->hconfig & HCFG_CAL_ALLOWED)) + || (ps->pdev->model == SNAPSCANE52)) { po[OPT_QUALITY_CAL].cap |= SANE_CAP_INACTIVE; ps->val[OPT_QUALITY_CAL].b = SANE_FALSE; } @@ -917,57 +921,26 @@ static void gamma_to_sane (int length, u_char *in, SANE_Int *out) } /* dispersed-dot dither matrices; this is discussed in Foley, Van Dam, - Feiner and Hughes, 2nd ed., pp 570-571. - + Feiner and Hughes: Computer Graphics: principles and practice, + 2nd ed. (Addison-Wesley), pp 570-571. + The function mfDn computes the nth dispersed-dot dither matrix Dn given D(n/2) and n; n is presumed to be a power of 2. D8 and D16 are the matrices of interest to us, since the SnapScan supports only 8x8 and 16x16 dither matrices. */ -static u_char D2[] = -{ - 0, 2, 3, 1 -}; +static u_char D2[] ={0, 2, 3, 1}; static u_char D4[16], D8[64], D16[256]; -static void mkDn (u_char *Dn, u_char *Dn2, unsigned n) +static void mkDn (u_char *Dn, u_char *Dn_half, unsigned n) { - static u_char tmp[256]; - unsigned n2 = n/2; - unsigned nsq = n*n; - unsigned i; - unsigned r; - unsigned imin; - unsigned f; - - /* compute 4*D(n/2) */ - /* Oliver Schwartz, 27 Oct. 2001: Changed code from - tmp[i] = (u_char) (4 * Dn2[i]); - to - tmp[i] = (u_char) (4 * Dn2[i/4]); - to avoid illegal indices in Dn2. Don't know if this - is the desired algorithm. - */ - for (i = 0; i < nsq; i++) - tmp[i] = (u_char) (4 * Dn2[i/4]); - - /* now the dither matrix */ - for (r = 0, imin = 0, f = 0; r < 2; r++, imin += n2) - { - unsigned c; - unsigned jmin; - for (c = 0, jmin = 0; c < 2; c++, jmin += n2, f++) - { - unsigned i; - unsigned i2; - unsigned j; - unsigned j2; - for (i = imin, i2 = 0; i < imin + n2; i++, i2++) - { - for (j = jmin, j2 = 0; j < jmin + n2; j++, j2++) - Dn[i * n + j] = (u_char) (tmp[i2 * n2 + j2] + D2[f]); - } + unsigned int x, y; + for (y = 0; y < n; y++) { + for (x = 0; x < n; x++) { + /* Dn(x,y) = D2(2*x/n, 2*y/n) +4*Dn_half(x%(n/2), y%(n/2)) */ + Dn[y*n + x] = D2[((int)(2*y/n))*2 + (int)(2*x/n)] + + 4*Dn_half[(y%(n/2))*(n/2) + x%(n/2)]; } } } @@ -1026,7 +999,7 @@ static SANE_Status add_device (SANE_String_Const name) name += 3; name = sanei_config_skip_whitespace(name); } - status = snapscani_usb_open (name, &fd); + status = snapscani_usb_open (name, &fd, sense_handler, NULL); if (status != SANE_STATUS_GOOD) { DBG (DL_MAJOR_ERROR, @@ -1129,9 +1102,11 @@ static SANE_Status add_device (SANE_String_Const name) me, vendor, model, - "AGFA SnapScan 300, 310, 600 or 1236, " - "Acer VUEGO 300, 310S, 610S, or 610plus, " - "Acer PRISA 620, 640, 1240, 3300, 4300 or 5300"); + "AGFA SnapScan 300, 310, 600, 1212, 1236, e20, e25, e26, " + "e40, e50, e52 or e60\n" + "Acer 300, 310, 610, 610+, " + "620, 620+, 640, 1240, 3300, 4300 or 5300\n" + "Guillemot MaxiScan A4 Deluxe"); if(bus_type == SCSI) { @@ -1314,7 +1289,7 @@ SANE_Status sane_init (SANE_Int *version_code, { u_char i; for (i = 0; i < 64; i++) - D8[i] = (u_char) (4 * D8[i] + 3); + D8[i] = (u_char) (4 * D8[i] + 2); } return SANE_STATUS_GOOD; @@ -1660,6 +1635,7 @@ SANE_Status sane_control_option (SANE_Handle h, { static const char *me = "sane_snapscan_control_option"; SnapScan_Scanner *pss = h; + SnapScan_Device *pdev = pss->pdev; static SANE_Status status; DBG (DL_CALL_TRACE, @@ -1791,6 +1767,10 @@ SANE_Status sane_control_option (SANE_Handle h, } break; case SANE_ACTION_SET_VALUE: + status = sanei_constrain_value(&pss->options[n], v, i); + if (status != SANE_STATUS_GOOD) { + return status; + } switch (n) { case OPT_COUNT: @@ -1959,9 +1939,9 @@ SANE_Status sane_control_option (SANE_Handle h, } /* Adjust actual range values to new max values */ if (pss->brx > pss->pdev->x_range.max) - pss->brx = pss->pdev->x_range.max; + pss->brx = pss->pdev->x_range.max - pdev->x_range.quant; if (pss->bry > pss->pdev->y_range.max) - pss->bry = pss->pdev->y_range.max; + pss->bry = pss->pdev->y_range.max - pdev->y_range.quant; pss->predef_window = pdw_none; if (pss->source_s) free (pss->source_s); @@ -1972,23 +1952,47 @@ SANE_Status sane_control_option (SANE_Handle h, case OPT_TLX: pss->tlx = *(SANE_Fixed *) v; pss->predef_window = pdw_none; + if (fabs(pss->tlx - pdev->x_range.max) < pdev->x_range.quant) { + pss->tlx -= pdev->x_range.quant; + } + if (pss->brx < pss->tlx) { + pss->brx = pss->tlx + pdev->x_range.quant; + } if (i) *i = SANE_INFO_RELOAD_PARAMS; break; case OPT_TLY: pss->tly = *(SANE_Fixed *) v; + if (fabs(pss->tly - pdev->y_range.max) < pdev->y_range.quant) { + pss->tly -= pdev->y_range.quant; + } pss->predef_window = pdw_none; + if (pss->bry < pss->tly) { + pss->bry = pss->tly + pdev->y_range.quant; + } if (i) *i = SANE_INFO_RELOAD_PARAMS; break; case OPT_BRX: pss->brx = *(SANE_Fixed *) v; + if (fabs(pss->brx - pdev->x_range.min) < pdev->x_range.quant) { + pss->brx += pdev->x_range.quant; + } + if (pss->brx < pss->tlx) { + pss->tlx = pss->brx - pdev->x_range.quant; + } pss->predef_window = pdw_none; if (i) *i = SANE_INFO_RELOAD_PARAMS; break; case OPT_BRY: pss->bry = *(SANE_Fixed *) v; + if (fabs(pss->bry - pdev->y_range.min) < pdev->y_range.quant) { + pss->bry += pdev->y_range.quant; + } + if (pss->bry < pss->tly) { + pss->tly = pss->bry - pdev->y_range.quant; + } pss->predef_window = pdw_none; if (i) *i = SANE_INFO_RELOAD_PARAMS; @@ -2353,7 +2357,7 @@ SANE_Status sane_control_option (SANE_Handle h, *i = 0; break; case OPT_NEGATIVE: - pss->halftone = DEFAULT_NEGATIVE; + pss->negative = DEFAULT_NEGATIVE; if (i) *i = 0; break; @@ -2694,7 +2698,7 @@ static SANE_Status download_gamma_tables (SnapScan_Scanner *pss) pss->buf + SEND_LENGTH); status = send (pss, DTC_GAMMA, dtcq_gamma_green); CHECK_STATUS (status, me, "send"); - + gamma_from_sane (pss->gamma_length, pss->gamma_table_b, pss->buf + SEND_LENGTH); status = send (pss, DTC_GAMMA, dtcq_gamma_blue); @@ -2732,7 +2736,7 @@ static SANE_Status download_gamma_tables (SnapScan_Scanner *pss) pss->buf + SEND_LENGTH, bpp); status = send (pss, DTC_GAMMA, dtcq_gamma_green); CHECK_STATUS (status, me, "send"); - + gamma_n (gamma_b, pss->bright, pss->contrast, pss->buf + SEND_LENGTH, bpp); status = send (pss, DTC_GAMMA, dtcq_gamma_blue); @@ -2764,7 +2768,8 @@ static SANE_Status download_halftone_matrices (SnapScan_Scanner *pss) { static char me[] = "download_halftone_matrices"; SANE_Status status = SANE_STATUS_GOOD; - if (pss->halftone) + if ((pss->halftone) && + ((actual_mode(pss) == MD_LINEART) || (actual_mode(pss) == MD_BILEVELCOLOUR))) { u_char *matrix; size_t matrix_sz; @@ -3123,15 +3128,41 @@ SANE_Status sane_get_select_fd (SANE_Handle h, SANE_Int * fd) /* * $Log$ - * Revision 1.10 2001/10/27 09:08:14 oliverschwartz - * Check USB vendor IDs to avoid hanging scanners, fix bug in dither matrix computation + * Revision 1.11 2001/12/17 22:51:51 oliverschwartz + * Update to snapscan-20011212 (snapscan 1.4.3) * - * Revision 1.9 2001/10/25 10:56:39 oliverschwartz + * Revision 1.33 2001/12/12 19:43:30 oliverschwartz + * - Set version number to 1.4.3 + * - Clean up CVS Log + * + * Revision 1.32 2001/12/09 23:06:45 oliverschwartz + * - use sense handler for USB if scanner reports CHECK_CONDITION + * + * Revision 1.31 2001/12/08 11:50:34 oliverschwartz + * Fix dither matrix computation + * + * Revision 1.30 2001/11/29 22:50:14 oliverschwartz + * Add support for SnapScan e52 + * + * Revision 1.29 2001/11/27 23:16:17 oliverschwartz + * - Fix color alignment for SnapScan 600 + * - Added documentation in snapscan-sources.c + * - Guard against TL_X < BR_X and TL_Y < BR_Y + * + * Revision 1.28 2001/11/25 18:51:41 oliverschwartz + * added support for SnapScan e52 thanks to Rui Lopes + * + * Revision 1.27 2001/11/16 20:28:35 oliverschwartz + * add support for Snapscan e26 + * + * Revision 1.26 2001/11/16 20:23:16 oliverschwartz + * Merge with sane-1.0.6 + * - Check USB vendor IDs to avoid hanging scanners + * - fix bug in dither matrix computation + * + * Revision 1.25 2001/10/25 11:06:22 oliverschwartz * Change snapscan backend version number to 1.4.0 * - * Revision 1.8 2001/10/12 21:19:14 oliverschwartz - * update to snapscan-20011012 - * * Revision 1.24 2001/10/11 14:02:10 oliverschwartz * Distinguish between e20/e25 and e40/e50 * diff --git a/backend/snapscan.desc b/backend/snapscan.desc index d110fb7c1..84ab72cb1 100644 --- a/backend/snapscan.desc +++ b/backend/snapscan.desc @@ -56,6 +56,10 @@ :interface "USB" :comment "Have no specific programming info yet." +:model "SnapScan e26" +:interface "USB" +:comment "Have no specific programming info yet." + :model "SnapScan e40" :interface "USB" :comment "Have no specific programming info yet." @@ -64,6 +68,10 @@ :interface "USB" :comment "Have no specific programming info yet." +:model "SnapScan e52" +:interface "USB" +:comment "Have no specific programming info yet." + :model "SnapScan e60" :interface "USB" :comment "Have no specific programming info yet." diff --git a/backend/snapscan.h b/backend/snapscan.h index 55c381c15..ed3d341a9 100644 --- a/backend/snapscan.h +++ b/backend/snapscan.h @@ -84,6 +84,7 @@ typedef enum SNAPSCAN1212U, SNAPSCANE20, /* SnapScan e20/e25, 600 DPI */ SNAPSCANE50, /* SnapScan e40/e50, 1200 DPI */ + SNAPSCANE52, /* SnapScan e52, 1200 DPI, no quality calibration */ ACER300F, VUEGO310S, /* Vuego-Version of SnapScan 310 WG changed */ VUEGO610S, /* Vuego 610S and 610plus SJU changed */ @@ -120,8 +121,11 @@ static struct SnapScan_Model_desc scanners[] = {"SNAPSCAN 1212U_2", SNAPSCAN1212U}, {"SNAPSCAN e20", SNAPSCANE20}, {"SNAPSCAN e25", SNAPSCANE20}, + {"SNAPSCAN e26", SNAPSCANE20}, + {"SNAPSCAN e26 ", SNAPSCANE20}, {"SNAPSCAN e40", SNAPSCANE50}, {"SNAPSCAN e50", SNAPSCANE50}, + {"SNAPSCAN e52", SNAPSCANE52}, {"SNAPSCAN 1236", SNAPSCAN1236}, {"SNAPSCAN 1236U", SNAPSCAN1236}, {"SNAPSCAN 300", SNAPSCAN300}, @@ -321,11 +325,25 @@ struct snapscan_scanner /* * $Log$ - * Revision 1.7 2001/10/27 09:08:17 oliverschwartz - * Check USB vendor IDs to avoid hanging scanners, fix bug in dither matrix computation + * Revision 1.8 2001/12/17 22:51:52 oliverschwartz + * Update to snapscan-20011212 (snapscan 1.4.3) * - * Revision 1.6 2001/10/12 21:19:16 oliverschwartz - * update to snapscan-20011012 + * Revision 1.24 2001/12/12 19:44:59 oliverschwartz + * Clean up CVS log + * + * Revision 1.23 2001/11/25 18:51:41 oliverschwartz + * added support for SnapScan e52 thanks to Rui Lopes + * + * Revision 1.22 2001/11/16 20:56:47 oliverschwartz + * additional identification string for e26 added + * + * Revision 1.21 2001/11/16 20:28:35 oliverschwartz + * add support for Snapscan e26 + * + * Revision 1.20 2001/11/16 20:23:16 oliverschwartz + * Merge with sane-1.0.6 + * - Check USB vendor IDs to avoid hanging scanners + * - fix bug in dither matrix computation * * Revision 1.19 2001/10/11 14:02:10 oliverschwartz * Distinguish between e20/e25 and e40/e50 @@ -369,15 +387,6 @@ struct snapscan_scanner * Applying Mikael Magnusson patch concerning Gamma correction * Support for 1212U_2 * - * Revision 1.3 2001/03/04 16:51:29 mikael - * Added Scan Mode, Geometry, Enhancement and Advanced groups. Added Quality Calibration, Analog Gamma Bind, Custom Gamma and Gamma Vector GS,R,G,B options. Added SNAPSCAN 1212U_2. - * - * Revision 1.2 2001/02/16 18:32:28 mikael - * impl calibration, signed position, increased buffer size - * - * Revision 1.1.1.1 2001/02/10 17:09:29 mikael - * Imported from snapscan-11282000.tar.gz - * * Revision 1.8 2000/11/10 01:01:59 sable * USB (kind of) autodetection *