2001-02-10 Tom Martone <tom@martoneconsulting.com>

* backend/bh.c backend/bh.h doc/sane-bh.man
          added support for Copiscan 8000 series by Mark Temple
	  added options deskew and rotation
	  inquiry compares product to COPISCAN rather than COPISCAN II
DEVEL_2_0_BRANCH-1
Tom Martone 2001-02-10 18:23:28 +00:00
rodzic 5d284b9f2f
commit 86ee15cba9
3 zmienionych plików z 122 dodań i 31 usunięć

Wyświetl plik

@ -247,6 +247,19 @@ print_read_type (SANE_Int i)
return buf; return buf;
} }
static SANE_Int
get_rotation_id(char *s)
{
SANE_Int i;
for (i = 0; rotation_list[i]; i++)
if (strcmp(s, rotation_list[i]) == 0)
break;
/* unknown strings are treated as '0' */
return rotation_list[i] ? i : 0;
}
static SANE_Int static SANE_Int
get_compression_id(char *s) get_compression_id(char *s)
{ {
@ -426,6 +439,7 @@ ScannerDump(BH_Scanner *s)
DBG (5, "autoborder_default=%d\n", info->autoborder_default); DBG (5, "autoborder_default=%d\n", info->autoborder_default);
DBG (5, "batch_default=%d\n", info->batch_default); DBG (5, "batch_default=%d\n", info->batch_default);
DBG (5, "deskew_default=%d\n", info->deskew_default);
DBG (5, "check_adf_default=%d\n", info->check_adf_default); DBG (5, "check_adf_default=%d\n", info->check_adf_default);
DBG (5, "duplex_default=%d\n", info->duplex_default); DBG (5, "duplex_default=%d\n", info->duplex_default);
DBG (5, "timeout_adf_default=%d\n", info->timeout_adf_default); DBG (5, "timeout_adf_default=%d\n", info->timeout_adf_default);
@ -963,7 +977,7 @@ set_window (BH_Scanner *s, SANE_Byte batchmode)
struct window_data window; struct window_data window;
} set_window_cmd; } set_window_cmd;
SANE_Status status; SANE_Status status;
SANE_Int width, length, i, format; SANE_Int width, length, i, format, rotation, deskew ;
DBG (3, "set_window called\n"); DBG (3, "set_window called\n");
@ -986,6 +1000,7 @@ set_window (BH_Scanner *s, SANE_Byte batchmode)
set_window_cmd.window.windowid = 0; set_window_cmd.window.windowid = 0;
set_window_cmd.window.autoborder = _OPT_VAL_WORD(s, OPT_AUTOBORDER); set_window_cmd.window.autoborder = _OPT_VAL_WORD(s, OPT_AUTOBORDER);
DBG (5, "autoborder set to=%d\n", set_window_cmd.window.autoborder);
_lto2b(_OPT_VAL_WORD(s, OPT_RESOLUTION), set_window_cmd.window.xres); _lto2b(_OPT_VAL_WORD(s, OPT_RESOLUTION), set_window_cmd.window.xres);
_lto2b(_OPT_VAL_WORD(s, OPT_RESOLUTION), set_window_cmd.window.yres); _lto2b(_OPT_VAL_WORD(s, OPT_RESOLUTION), set_window_cmd.window.yres);
_lto4b((int) _OPT_VAL_WORD_THOUSANDTHS(s, OPT_TL_X), set_window_cmd.window.ulx); _lto4b((int) _OPT_VAL_WORD_THOUSANDTHS(s, OPT_TL_X), set_window_cmd.window.ulx);
@ -1053,6 +1068,14 @@ set_window (BH_Scanner *s, SANE_Byte batchmode)
break; break;
} }
/* rotation and deskew settings, if autoborder is turned on */
if(set_window_cmd.window.autoborder){ /*--- setting byte 46 of the window descriptor block only works with autoborder */
rotation = get_rotation_id(_OPT_VAL_STRING(s, OPT_ROTATION));
if (_OPT_VAL_WORD(s, OPT_DESKEW) == SANE_TRUE) deskew = BH_DESKEW_ENABLE;
else deskew = BH_DESKEW_DISABLE;
set_window_cmd.window.border_rotation = ( rotation | deskew ); /*--- deskew assumes autoborder */
}
/* remote - 0x00 ACE set in window; 0x01 ACE set by control panel */ /* remote - 0x00 ACE set in window; 0x01 ACE set by control panel */
set_window_cmd.window.remote = _OPT_VAL_WORD(s, OPT_CONTROL_PANEL); set_window_cmd.window.remote = _OPT_VAL_WORD(s, OPT_CONTROL_PANEL);
if (set_window_cmd.window.remote == 0x00) { if (set_window_cmd.window.remote == 0x00) {
@ -1080,6 +1103,7 @@ set_window (BH_Scanner *s, SANE_Byte batchmode)
} }
status = sanei_scsi_cmd (s->fd, &set_window_cmd, sizeof (set_window_cmd), 0, 0); status = sanei_scsi_cmd (s->fd, &set_window_cmd, sizeof (set_window_cmd), 0, 0);
DBG (5, "sanei_scsi_cmd executed, status=%d\n", status );
if (status != SANE_STATUS_GOOD) if (status != SANE_STATUS_GOOD)
return status; return status;
@ -1100,7 +1124,7 @@ get_window (BH_Scanner *s, SANE_Int *w, SANE_Int *h, SANE_Bool backpage)
struct window_data window; struct window_data window;
} get_window_data; } get_window_data;
SANE_Status status; SANE_Status status;
SANE_Int x, y, i = 0; SANE_Int x, y, i = 0, get_window_delay = 1;
SANE_Bool autoborder; SANE_Bool autoborder;
size_t len; size_t len;
@ -1137,6 +1161,10 @@ get_window (BH_Scanner *s, SANE_Int *w, SANE_Int *h, SANE_Bool backpage)
if (get_window_data.window.autoborder != 1 && if (get_window_data.window.autoborder != 1 &&
i < BH_AUTOBORDER_TRIES) i < BH_AUTOBORDER_TRIES)
{ {
DBG (5, "waiting %d second[s], try: %d\n",get_window_delay,i);
sleep(get_window_delay); /*--- page 4-5 of B&H Copiscan 8000 ESC OEM Tech Manual */
/*--- requires at least 50ms wait between each GET WINDOW command */
/*--- experience shows that this can take 3 to 4 seconds */
continue; continue;
} }
if (get_window_data.window.autoborder != 1) if (get_window_data.window.autoborder != 1)
@ -1145,8 +1173,11 @@ get_window (BH_Scanner *s, SANE_Int *w, SANE_Int *h, SANE_Bool backpage)
BH_AUTOBORDER_TRIES); BH_AUTOBORDER_TRIES);
status = SANE_STATUS_IO_ERROR; status = SANE_STATUS_IO_ERROR;
} }
DBG (0, "page dimension: wide:%d high:%d \n",*w,*h);
} }
DBG (3, "*** Window size: %dx%d+%d+%d\n", *w, *h, x, y); DBG (3, "*** Window size: %dx%d+%d+%d\n", *w, *h, x, y);
DBG (5, "*** get_window found autoborder=%02xh\n", get_window_data.window.autoborder);
DBG (5, "*** get_window found border_rotation=%02xh\n", get_window_data.window.border_rotation);
} }
/* we are 'outta here' */ /* we are 'outta here' */
@ -2389,6 +2420,24 @@ init_options (BH_Scanner * s)
s->opt[OPT_PAPER_SIZE].constraint.string_list = paper_list; s->opt[OPT_PAPER_SIZE].constraint.string_list = paper_list;
s->val[OPT_PAPER_SIZE].s = strdup (paper_list[0]); s->val[OPT_PAPER_SIZE].s = strdup (paper_list[0]);
/* rotation */
s->opt[OPT_ROTATION].name = SANE_NAME_ROTATION;
s->opt[OPT_ROTATION].title = SANE_TITLE_ROTATION;
s->opt[OPT_ROTATION].desc = SANE_DESC_ROTATION;
s->opt[OPT_ROTATION].type = SANE_TYPE_STRING;
s->opt[OPT_ROTATION].size = max_string_size (rotation_list);
s->opt[OPT_ROTATION].constraint_type = SANE_CONSTRAINT_STRING_LIST;
s->opt[OPT_ROTATION].constraint.string_list = rotation_list;
s->val[OPT_ROTATION].s = strdup (rotation_list[0]);
/* Deskew: */
s->opt[OPT_DESKEW].name = SANE_NAME_DESKEW;
s->opt[OPT_DESKEW].title = SANE_TITLE_DESKEW;
s->opt[OPT_DESKEW].desc = SANE_DESC_DESKEW;
s->opt[OPT_DESKEW].type = SANE_TYPE_BOOL;
s->opt[OPT_DESKEW].constraint_type = SANE_CONSTRAINT_NONE;
s->val[OPT_DESKEW].w = s->hw->info.deskew_default;
/* top-left x */ /* top-left x */
s->opt[OPT_TL_X].name = SANE_NAME_SCAN_TL_X; s->opt[OPT_TL_X].name = SANE_NAME_SCAN_TL_X;
s->opt[OPT_TL_X].title = SANE_TITLE_SCAN_TL_X; s->opt[OPT_TL_X].title = SANE_TITLE_SCAN_TL_X;
@ -2866,7 +2915,7 @@ attach (const char *devnam, BH_Device ** devp)
if (ibuf.devtype != 6 if (ibuf.devtype != 6
|| strncmp ((char *)ibuf.vendor, "B&H SCSI", 8) != 0 || strncmp ((char *)ibuf.vendor, "B&H SCSI", 8) != 0
|| strncmp ((char *)ibuf.product, "COPISCAN II", 11) != 0) || strncmp ((char *)ibuf.product, "COPISCAN ", 9) != 0)
{ {
DBG (1, DBG (1,
"attach: device is not a recognized Bell and Howell scanner\n"); "attach: device is not a recognized Bell and Howell scanner\n");
@ -3063,6 +3112,7 @@ attach (const char *devnam, BH_Device ** devp)
dev->info.res_default = dev->info.resBasicX; dev->info.res_default = dev->info.resBasicX;
dev->info.autoborder_default = dev->info.canBorderRecog; dev->info.autoborder_default = dev->info.canBorderRecog;
dev->info.batch_default = SANE_FALSE; dev->info.batch_default = SANE_FALSE;
dev->info.deskew_default = SANE_FALSE;
dev->info.check_adf_default = SANE_FALSE; dev->info.check_adf_default = SANE_FALSE;
dev->info.duplex_default = SANE_FALSE; dev->info.duplex_default = SANE_FALSE;
dev->info.timeout_adf_default = 0; dev->info.timeout_adf_default = 0;
@ -3350,6 +3400,7 @@ sane_control_option (SANE_Handle handle, SANE_Int option, SANE_Action action,
case OPT_SCAN_MODE: case OPT_SCAN_MODE:
case OPT_COMPRESSION: case OPT_COMPRESSION:
case OPT_PAPER_SIZE: case OPT_PAPER_SIZE:
case OPT_ROTATION:
case OPT_BARCODE_SEARCH_BAR: case OPT_BARCODE_SEARCH_BAR:
case OPT_BARCODE_SEARCH_MODE: case OPT_BARCODE_SEARCH_MODE:
case OPT_SECTION: case OPT_SECTION:
@ -3359,6 +3410,7 @@ sane_control_option (SANE_Handle handle, SANE_Int option, SANE_Action action,
/* boolean options: */ /* boolean options: */
case OPT_PREVIEW: case OPT_PREVIEW:
case OPT_AUTOBORDER: case OPT_AUTOBORDER:
case OPT_DESKEW:
case OPT_BATCH: case OPT_BATCH:
case OPT_CHECK_ADF: case OPT_CHECK_ADF:
case OPT_DUPLEX: case OPT_DUPLEX:
@ -3458,6 +3510,7 @@ sane_control_option (SANE_Handle handle, SANE_Int option, SANE_Action action,
/* fall through */ /* fall through */
case OPT_SCAN_SOURCE: case OPT_SCAN_SOURCE:
case OPT_COMPRESSION: case OPT_COMPRESSION:
case OPT_ROTATION:
case OPT_BARCODE_SEARCH_MODE: case OPT_BARCODE_SEARCH_MODE:
case OPT_SECTION: case OPT_SECTION:
if (s->val[option].s) if (s->val[option].s)
@ -3473,6 +3526,7 @@ sane_control_option (SANE_Handle handle, SANE_Int option, SANE_Action action,
/* fall through */ /* fall through */
case OPT_PREVIEW: case OPT_PREVIEW:
case OPT_BATCH: case OPT_BATCH:
case OPT_DESKEW:
case OPT_CHECK_ADF: case OPT_CHECK_ADF:
case OPT_DUPLEX: case OPT_DUPLEX:
case OPT_NEGATIVE: case OPT_NEGATIVE:

Wyświetl plik

@ -60,7 +60,7 @@
#define NUM_READS 56 + 1 #define NUM_READS 56 + 1
/* specify sanity limits for autoborder detection and barcode decoding */ /* specify sanity limits for autoborder detection and barcode decoding */
#define BH_AUTOBORDER_TRIES 1000 #define BH_AUTOBORDER_TRIES 100
#define BH_DECODE_TRIES 100 #define BH_DECODE_TRIES 100
/* specify a fudge factor in mm for border around decoded barcodes */ /* specify a fudge factor in mm for border around decoded barcodes */
#define BH_DECODE_FUDGE 1.0 #define BH_DECODE_FUDGE 1.0
@ -88,6 +88,14 @@ typedef enum
BH_COMP_G42D BH_COMP_G42D
} bh_compress; } bh_compress;
typedef enum
{
BH_ROTATION_0,
BH_ROTATION_90,
BH_ROTATION_180,
BH_ROTATION_270
} bh_rotation;
typedef enum typedef enum
{ {
OPT_NUM_OPTS = 0, OPT_NUM_OPTS = 0,
@ -107,6 +115,10 @@ typedef enum
OPT_GEOMETRY_GROUP, OPT_GEOMETRY_GROUP,
/* automatic border detection */ /* automatic border detection */
OPT_AUTOBORDER, OPT_AUTOBORDER,
/* hardware rotation */
OPT_ROTATION,
/* hardware deskew */
OPT_DESKEW,
/* paper size */ /* paper size */
OPT_PAPER_SIZE, OPT_PAPER_SIZE,
/* top-left x */ /* top-left x */
@ -243,6 +255,7 @@ typedef struct _BH_Info
SANE_Int res_default; SANE_Int res_default;
SANE_Bool autoborder_default; SANE_Bool autoborder_default;
SANE_Bool batch_default; SANE_Bool batch_default;
SANE_Bool deskew_default;
SANE_Bool check_adf_default; SANE_Bool check_adf_default;
SANE_Bool duplex_default; SANE_Bool duplex_default;
SANE_Int timeout_adf_default; SANE_Int timeout_adf_default;
@ -497,6 +510,16 @@ static SANE_String_Const barcode_search_bar_list[] =
0 0
}; };
/* list of supported rotation angles */
static SANE_String_Const rotation_list[] =
{
"0",
"90",
"180",
"270",
0
};
/* list of support paper sizes */ /* list of support paper sizes */
/* 'custom' MUST be item 0; otherwise a width or length of 0 indicates /* 'custom' MUST be item 0; otherwise a width or length of 0 indicates
* the maximum value supported by the scanner * the maximum value supported by the scanner
@ -603,6 +626,14 @@ _4btol(SANE_Byte *bytes)
#define SANE_TITLE_COMPRESSION "Data Compression" #define SANE_TITLE_COMPRESSION "Data Compression"
#define SANE_DESC_COMPRESSION "Sets the compression mode of the scanner" #define SANE_DESC_COMPRESSION "Sets the compression mode of the scanner"
#define SANE_NAME_ROTATION "rotation"
#define SANE_TITLE_ROTATION "Page Rotation"
#define SANE_DESC_ROTATION "Sets the page rotation mode of the scanner"
#define SANE_NAME_DESKEW "deskew"
#define SANE_TITLE_DESKEW "Page Deskew"
#define SANE_DESC_DESKEW "Enable Deskew Mode"
#define SANE_NAME_TIMEOUT_ADF "timeout-adf" #define SANE_NAME_TIMEOUT_ADF "timeout-adf"
#define SANE_TITLE_TIMEOUT_ADF "ADF Timeout" #define SANE_TITLE_TIMEOUT_ADF "ADF Timeout"
#define SANE_DESC_TIMEOUT_ADF "Sets the timeout in seconds for the ADF" #define SANE_DESC_TIMEOUT_ADF "Sets the timeout in seconds for the ADF"
@ -753,6 +784,10 @@ _4btol(SANE_Byte *bytes)
#define BH_BATCH_TERMINATE 0x02 #define BH_BATCH_TERMINATE 0x02
#define BH_BATCH_ABORT 0x03 #define BH_BATCH_ABORT 0x03
/* deskew mode codes used with BH_SCSI_SET_WINDOW */
#define BH_DESKEW_DISABLE 0x00 /* border detection is assumed, see page 3-37 of 8000 manual */
#define BH_DESKEW_ENABLE 0x04 /* deskew and border detection */
/* used with BH_SCSI_SET_WINDOW, BH_SCSI_GET_WINDOW */ /* used with BH_SCSI_SET_WINDOW, BH_SCSI_GET_WINDOW */
typedef struct _BH_SectionBlock { typedef struct _BH_SectionBlock {
SANE_Byte ul_x[4]; SANE_Byte ul_x[4];
@ -765,32 +800,34 @@ typedef struct _BH_SectionBlock {
} BH_SectionBlock; } BH_SectionBlock;
/* used with BH_SCSI_SET_WINDOW, BH_SCSI_GET_WINDOW */ /* used with BH_SCSI_SET_WINDOW, BH_SCSI_GET_WINDOW */
struct window_data { struct window_data { /* window descriptor block byte layout */
SANE_Byte windowid; SANE_Byte windowid; /* 0 */
SANE_Byte autoborder; SANE_Byte autoborder; /* 1 */
SANE_Byte xres[2]; SANE_Byte xres[2]; /* 2,3 */
SANE_Byte yres[2]; SANE_Byte yres[2]; /* 4,5 */
SANE_Byte ulx[4]; SANE_Byte ulx[4]; /* 6-9 */
SANE_Byte uly[4]; SANE_Byte uly[4]; /* 10-13 */
SANE_Byte windowwidth[4]; SANE_Byte windowwidth[4]; /* 14-17 */
SANE_Byte windowlength[4]; SANE_Byte windowlength[4]; /* 18-21 */
SANE_Byte brightness; SANE_Byte brightness; /* 22 */
SANE_Byte threshold; SANE_Byte threshold; /* 23 */
SANE_Byte contrast; SANE_Byte contrast; /* 24 */
SANE_Byte imagecomposition; SANE_Byte imagecomposition; /* 25 */
SANE_Byte bitsperpixel; SANE_Byte bitsperpixel; /* 26 */
SANE_Byte halftonecode; SANE_Byte halftonecode; /* 27 */
SANE_Byte halftoneid; SANE_Byte halftoneid; /* 28 */
SANE_Byte paddingtype; SANE_Byte paddingtype; /* 29 */
SANE_Byte bitordering[2]; SANE_Byte bitordering[2]; /* 30,31 */
SANE_Byte compressiontype; SANE_Byte compressiontype; /* 32 */
SANE_Byte compressionarg; SANE_Byte compressionarg; /* 33 */
SANE_Byte reserved2[6]; SANE_Byte reserved2[6]; /* 34-39 */
SANE_Byte remote; SANE_Byte remote; /* 40 */
SANE_Byte acefunction; SANE_Byte acefunction; /* 41 */
SANE_Byte acesensitivity; SANE_Byte acesensitivity; /* 42 */
SANE_Byte batchmode; SANE_Byte batchmode; /* 43 */
SANE_Byte reserved3[20]; SANE_Byte reserved3[2]; /* 44,45 */
SANE_Byte border_rotation; /* 46 added this for copiscan 8080 */
SANE_Byte reserved4[17]; /* 47-63 added this for copiscan 8080 */
BH_SectionBlock sectionblock[NUM_SECTIONS]; BH_SectionBlock sectionblock[NUM_SECTIONS];
}; };

Wyświetl plik

@ -542,4 +542,4 @@ sane\-scsi(5), scanimage(1), scanadf(1)
.SH AUTHOR .SH AUTHOR
The sane-bh backend was written by Tom Martone, based on the sane-ricoh The sane-bh backend was written by Tom Martone, based on the sane-ricoh
backend by Feico W. Dillema and the bnhscan program by Sean Reifschneider backend by Feico W. Dillema and the bnhscan program by Sean Reifschneider
of tummy.com ltd. of tummy.com ltd. Some 8000 enhancements added by Mark Temple.