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;
}
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
get_compression_id(char *s)
{
@ -426,6 +439,7 @@ ScannerDump(BH_Scanner *s)
DBG (5, "autoborder_default=%d\n", info->autoborder_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, "duplex_default=%d\n", info->duplex_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;
} set_window_cmd;
SANE_Status status;
SANE_Int width, length, i, format;
SANE_Int width, length, i, format, rotation, deskew ;
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.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.yres);
_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;
}
/* 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 */
set_window_cmd.window.remote = _OPT_VAL_WORD(s, OPT_CONTROL_PANEL);
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);
DBG (5, "sanei_scsi_cmd executed, status=%d\n", status );
if (status != SANE_STATUS_GOOD)
return status;
@ -1100,7 +1124,7 @@ get_window (BH_Scanner *s, SANE_Int *w, SANE_Int *h, SANE_Bool backpage)
struct window_data window;
} get_window_data;
SANE_Status status;
SANE_Int x, y, i = 0;
SANE_Int x, y, i = 0, get_window_delay = 1;
SANE_Bool autoborder;
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 &&
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;
}
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);
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 (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' */
@ -2389,6 +2420,24 @@ init_options (BH_Scanner * s)
s->opt[OPT_PAPER_SIZE].constraint.string_list = paper_list;
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 */
s->opt[OPT_TL_X].name = SANE_NAME_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
|| 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,
"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.autoborder_default = dev->info.canBorderRecog;
dev->info.batch_default = SANE_FALSE;
dev->info.deskew_default = SANE_FALSE;
dev->info.check_adf_default = SANE_FALSE;
dev->info.duplex_default = SANE_FALSE;
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_COMPRESSION:
case OPT_PAPER_SIZE:
case OPT_ROTATION:
case OPT_BARCODE_SEARCH_BAR:
case OPT_BARCODE_SEARCH_MODE:
case OPT_SECTION:
@ -3359,6 +3410,7 @@ sane_control_option (SANE_Handle handle, SANE_Int option, SANE_Action action,
/* boolean options: */
case OPT_PREVIEW:
case OPT_AUTOBORDER:
case OPT_DESKEW:
case OPT_BATCH:
case OPT_CHECK_ADF:
case OPT_DUPLEX:
@ -3458,6 +3510,7 @@ sane_control_option (SANE_Handle handle, SANE_Int option, SANE_Action action,
/* fall through */
case OPT_SCAN_SOURCE:
case OPT_COMPRESSION:
case OPT_ROTATION:
case OPT_BARCODE_SEARCH_MODE:
case OPT_SECTION:
if (s->val[option].s)
@ -3473,6 +3526,7 @@ sane_control_option (SANE_Handle handle, SANE_Int option, SANE_Action action,
/* fall through */
case OPT_PREVIEW:
case OPT_BATCH:
case OPT_DESKEW:
case OPT_CHECK_ADF:
case OPT_DUPLEX:
case OPT_NEGATIVE:

Wyświetl plik

@ -60,7 +60,7 @@
#define NUM_READS 56 + 1
/* specify sanity limits for autoborder detection and barcode decoding */
#define BH_AUTOBORDER_TRIES 1000
#define BH_AUTOBORDER_TRIES 100
#define BH_DECODE_TRIES 100
/* specify a fudge factor in mm for border around decoded barcodes */
#define BH_DECODE_FUDGE 1.0
@ -88,6 +88,14 @@ typedef enum
BH_COMP_G42D
} bh_compress;
typedef enum
{
BH_ROTATION_0,
BH_ROTATION_90,
BH_ROTATION_180,
BH_ROTATION_270
} bh_rotation;
typedef enum
{
OPT_NUM_OPTS = 0,
@ -107,6 +115,10 @@ typedef enum
OPT_GEOMETRY_GROUP,
/* automatic border detection */
OPT_AUTOBORDER,
/* hardware rotation */
OPT_ROTATION,
/* hardware deskew */
OPT_DESKEW,
/* paper size */
OPT_PAPER_SIZE,
/* top-left x */
@ -243,6 +255,7 @@ typedef struct _BH_Info
SANE_Int res_default;
SANE_Bool autoborder_default;
SANE_Bool batch_default;
SANE_Bool deskew_default;
SANE_Bool check_adf_default;
SANE_Bool duplex_default;
SANE_Int timeout_adf_default;
@ -497,6 +510,16 @@ static SANE_String_Const barcode_search_bar_list[] =
0
};
/* list of supported rotation angles */
static SANE_String_Const rotation_list[] =
{
"0",
"90",
"180",
"270",
0
};
/* list of support paper sizes */
/* 'custom' MUST be item 0; otherwise a width or length of 0 indicates
* the maximum value supported by the scanner
@ -603,6 +626,14 @@ _4btol(SANE_Byte *bytes)
#define SANE_TITLE_COMPRESSION "Data Compression"
#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_TITLE_TIMEOUT_ADF "ADF Timeout"
#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_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 */
typedef struct _BH_SectionBlock {
SANE_Byte ul_x[4];
@ -765,32 +800,34 @@ typedef struct _BH_SectionBlock {
} BH_SectionBlock;
/* used with BH_SCSI_SET_WINDOW, BH_SCSI_GET_WINDOW */
struct window_data {
SANE_Byte windowid;
SANE_Byte autoborder;
SANE_Byte xres[2];
SANE_Byte yres[2];
SANE_Byte ulx[4];
SANE_Byte uly[4];
SANE_Byte windowwidth[4];
SANE_Byte windowlength[4];
SANE_Byte brightness;
SANE_Byte threshold;
SANE_Byte contrast;
SANE_Byte imagecomposition;
SANE_Byte bitsperpixel;
SANE_Byte halftonecode;
SANE_Byte halftoneid;
SANE_Byte paddingtype;
SANE_Byte bitordering[2];
SANE_Byte compressiontype;
SANE_Byte compressionarg;
SANE_Byte reserved2[6];
SANE_Byte remote;
SANE_Byte acefunction;
SANE_Byte acesensitivity;
SANE_Byte batchmode;
SANE_Byte reserved3[20];
struct window_data { /* window descriptor block byte layout */
SANE_Byte windowid; /* 0 */
SANE_Byte autoborder; /* 1 */
SANE_Byte xres[2]; /* 2,3 */
SANE_Byte yres[2]; /* 4,5 */
SANE_Byte ulx[4]; /* 6-9 */
SANE_Byte uly[4]; /* 10-13 */
SANE_Byte windowwidth[4]; /* 14-17 */
SANE_Byte windowlength[4]; /* 18-21 */
SANE_Byte brightness; /* 22 */
SANE_Byte threshold; /* 23 */
SANE_Byte contrast; /* 24 */
SANE_Byte imagecomposition; /* 25 */
SANE_Byte bitsperpixel; /* 26 */
SANE_Byte halftonecode; /* 27 */
SANE_Byte halftoneid; /* 28 */
SANE_Byte paddingtype; /* 29 */
SANE_Byte bitordering[2]; /* 30,31 */
SANE_Byte compressiontype; /* 32 */
SANE_Byte compressionarg; /* 33 */
SANE_Byte reserved2[6]; /* 34-39 */
SANE_Byte remote; /* 40 */
SANE_Byte acefunction; /* 41 */
SANE_Byte acesensitivity; /* 42 */
SANE_Byte batchmode; /* 43 */
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];
};

Wyświetl plik

@ -542,4 +542,4 @@ sane\-scsi(5), scanimage(1), scanadf(1)
.SH AUTHOR
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
of tummy.com ltd.
of tummy.com ltd. Some 8000 enhancements added by Mark Temple.