kopia lustrzana https://gitlab.com/sane-project/backends
here goes nothing- release updated backend. lets see who screams :)
rodzic
97b8366fc3
commit
4cf409d452
|
@ -1,3 +1,8 @@
|
|||
2006-05-14 m. allan noah <anoah AT pfeiffer DOT edu>
|
||||
* backend/fujitsu*: rewritten backend, supports many more scanners
|
||||
with much better usb support and less model-specific code.
|
||||
* doc/sane-fujitsu.man: updated to match new backend.
|
||||
|
||||
2006-05-12 m. allan noah <anoah AT pfeiffer DOT edu>
|
||||
* doc/descriptions/fujitsu.desc: updated with all known scanners
|
||||
by fujitsu. Most now supported as 'basic'.
|
||||
|
|
|
@ -9,6 +9,16 @@
|
|||
|
||||
/****************************************************/
|
||||
|
||||
#define USB_COMMAND_CODE 0x43
|
||||
#define USB_COMMAND_LEN 0x1F
|
||||
#define USB_COMMAND_OFFSET 0x13
|
||||
#define USB_COMMAND_TIME 1000
|
||||
#define USB_DATA_TIME 1000
|
||||
#define USB_STATUS_CODE 0x53
|
||||
#define USB_STATUS_LEN 0x0D
|
||||
#define USB_STATUS_OFFSET 0x09
|
||||
#define USB_STATUS_TIME 3000
|
||||
|
||||
/*static inline void */
|
||||
static void
|
||||
setbitfield (unsigned char *pageaddr, int mask, int shift, int val)
|
||||
|
@ -99,7 +109,7 @@ scsiblk;
|
|||
#define SCAN 0x1b
|
||||
#define IMPRINTER 0xc1
|
||||
#define HW_STATUS 0xc2
|
||||
#define RESET_UNIT 0xf1
|
||||
#define SCANNER_CONTROL 0xf1
|
||||
|
||||
|
||||
/* ==================================================================== */
|
||||
|
@ -116,9 +126,16 @@ static scsiblk release_unitB = { release_unitC, sizeof (release_unitC) };
|
|||
|
||||
/* ==================================================================== */
|
||||
|
||||
static unsigned char reset_unitC[] =
|
||||
{ RESET_UNIT, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
static scsiblk reset_unitB = { reset_unitC, sizeof (reset_unitC) };
|
||||
static unsigned char scanner_controlC[] =
|
||||
{ SCANNER_CONTROL, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
static scsiblk scanner_controlB = { scanner_controlC, sizeof (scanner_controlC) };
|
||||
|
||||
#define set_SC_function(icb, val) setbitfield(icb + 1, 7, 0, val)
|
||||
#define SC_function_cancel 0x04
|
||||
#define SC_function_lamp_on 0x05
|
||||
#define SC_function_lamp_off 0x03
|
||||
#define SC_function_lamp_normal 0x06
|
||||
#define SC_function_lamp_saving 0x07
|
||||
|
||||
/* ==================================================================== */
|
||||
|
||||
|
@ -143,9 +160,12 @@ static scsiblk inquiryB = { inquiryC, sizeof (inquiryC) };
|
|||
#define get_IN_product(in, buf) strncpy(buf, in + 0x10, 0x010)
|
||||
#define get_IN_version(in, buf) strncpy(buf, in + 0x20, 0x04)
|
||||
#define get_IN_raster(in) getnbyte (in+0x2A, 2) /* offset between colors */
|
||||
#define get_IN_frontback(in) getnbyte (in+0x2E, 2) /* offset between front and back for duplex */
|
||||
#define get_IN_duplex_3091(in) getnbyte (in+0x2D, 1) /* duplex available */
|
||||
|
||||
/* these two only in some scanners */
|
||||
#define get_IN_duplex_3091(in) getnbyte (in+0x2D, 1) /* duplex available */
|
||||
#define get_IN_frontback(in) getnbyte (in+0x2E, 2) /* offset between front and back for duplex */
|
||||
|
||||
/* the VPD response */
|
||||
#define get_IN_page_length(in) getnbyte(in + 0x04, 1)
|
||||
#define get_IN_basic_x_res(in) getnbyte(in + 0x05, 2)
|
||||
#define get_IN_basic_y_res(in) getnbyte(in + 0x07, 2)
|
||||
|
@ -180,23 +200,37 @@ static scsiblk inquiryB = { inquiryC, sizeof (inquiryC) };
|
|||
#define get_IN_monochrome_rgb(in) getbitfield(in+0x1c, 1, 5)
|
||||
#define get_IN_half_tone_rgb(in) getbitfield(in+0x1c, 1, 6)
|
||||
#define get_IN_multilevel_rgb(in) getbitfield(in+0x1c, 1, 7)
|
||||
|
||||
/* vendor unique section */
|
||||
#define get_IN_operator_panel(in) getbitfield(in+0x20, 1, 1)
|
||||
#define get_IN_barcode(in) getbitfield(in+0x20, 1, 2)
|
||||
#define get_IN_endorser(in) getbitfield(in+0x20, 1, 3)
|
||||
#define get_IN_imprinter(in) getbitfield(in+0x20, 1, 3)
|
||||
#define get_IN_duplex(in) getbitfield(in+0x20, 1, 4)
|
||||
#define get_IN_trancepareny(in) getbitfield(in+0x20, 1, 5)
|
||||
#define get_IN_transparency(in) getbitfield(in+0x20, 1, 5)
|
||||
#define get_IN_flatbed(in) getbitfield(in+0x20, 1, 6)
|
||||
#define get_IN_adf(in) getbitfield(in+0x20, 1, 7)
|
||||
|
||||
#define get_IN_adbits(in) getbitfield(in+0x21, 0x0f, 0)
|
||||
#define get_IN_buffer_bytes(in) getnbyte(in + 0x22, 4)
|
||||
#define get_IN_has_set_subwindow(in) (getnbyte(in+0x2a, 2)) & 1
|
||||
#define get_IN_has_imprinter(in) (getnbyte(in+0x2a, 2)) & 2
|
||||
#define get_IN_has_hw_status(in) (getnbyte(in+0x2a, 2)) & 4
|
||||
|
||||
/* more stuff here (std supported commands) */
|
||||
|
||||
#define get_IN_has_subwindow(in) getbitfield(in+0x2b, 1, 0)
|
||||
#define get_IN_has_endorser(in) getbitfield(in+0x2b, 1, 1)
|
||||
#define get_IN_has_hw_status(in) getbitfield(in+0x2b, 1, 2)
|
||||
#define get_IN_has_scanner_ctl(in) getbitfield(in+0x31, 1, 1)
|
||||
|
||||
#define get_IN_brightness_steps(in) getnbyte(in+0x52, 1)
|
||||
#define get_IN_threshold_steps(in) getnbyte(in+0x53, 1)
|
||||
#define get_IN_contrast_steps(in) getnbyte(in+0x54, 1)
|
||||
#define get_IN_num_gamma(in) getbitfield(in+0x57, 15, 4)
|
||||
|
||||
#define get_IN_num_dither_internal(in) getbitfield(in+0x56, 15, 4)
|
||||
#define get_IN_num_dither_download(in) getbitfield(in+0x56, 15, 0)
|
||||
|
||||
#define get_IN_num_gamma_internal(in) getbitfield(in+0x57, 15, 4)
|
||||
#define get_IN_num_gamma_download(in) getbitfield(in+0x57, 15, 0)
|
||||
#define get_IN_ipc_bw_reverse(in) getbitfield(in+0x58, 1, 7)
|
||||
|
||||
#define get_IN_ipc_bw_rif(in) getbitfield(in+0x58, 1, 7)
|
||||
#define get_IN_ipc_auto1(in) getbitfield(in+0x58, 1, 6)
|
||||
#define get_IN_ipc_auto2(in) getbitfield(in+0x58, 1, 5)
|
||||
#define get_IN_ipc_outline_extraction(in) getbitfield(in+0x58, 1, 4)
|
||||
|
@ -204,8 +238,10 @@ static scsiblk inquiryB = { inquiryC, sizeof (inquiryC) };
|
|||
#define get_IN_ipc_auto_separation(in) getbitfield(in+0x58, 1, 2)
|
||||
#define get_IN_ipc_mirroring(in) getbitfield(in+0x58, 1, 1)
|
||||
#define get_IN_ipc_white_level_follow(in) getbitfield(in+0x58, 1, 0)
|
||||
|
||||
#define get_IN_ipc_subwindow(in) getbitfield(in+0x59, 1, 7)
|
||||
#define get_IN_ipc_error_diffusion(in) getbitfield(in+0x59, 1, 6)
|
||||
|
||||
#define get_IN_compression_MH(in) getbitfield(in+0x5a, 1, 7)
|
||||
#define get_IN_compression_MR(in) getbitfield(in+0x5a, 1, 6)
|
||||
#define get_IN_compression_MMR(in) getbitfield(in+0x5a, 1, 5)
|
||||
|
@ -213,9 +249,10 @@ static scsiblk inquiryB = { inquiryC, sizeof (inquiryC) };
|
|||
#define get_IN_compression_JPG_BASE(in) getbitfield(in+0x5a, 1, 3)
|
||||
#define get_IN_compression_JPG_EXT(in) getbitfield(in+0x5a, 1, 2)
|
||||
#define get_IN_compression_JPG_INDEP(in) getbitfield(in+0x5a, 1, 1)
|
||||
#define get_IN_imprinter(in) getbitfield(in+0x5c, 1, 7)
|
||||
#define get_IN_imprinter_stamp(in) getbitfield(in+0x5c, 1, 6)
|
||||
#define get_IN_imprinter_electrical(in) getbitfield(in+0x5c, 1, 5)
|
||||
|
||||
#define get_IN_imprinter2(in) getbitfield(in+0x5c, 1, 7)
|
||||
#define get_IN_imprinter2_stamp(in) getbitfield(in+0x5c, 1, 6)
|
||||
#define get_IN_imprinter2_electrical(in) getbitfield(in+0x5c, 1, 5)
|
||||
|
||||
/* ==================================================================== */
|
||||
|
||||
|
@ -230,16 +267,6 @@ static unsigned char set_windowC[] =
|
|||
{ SET_WINDOW, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
|
||||
/* opcode, lun, _____4 X reserved____, transfer length, control byte */
|
||||
static scsiblk set_windowB = { set_windowC, sizeof (set_windowC) };
|
||||
#define set_SW_xferlen(sb, len) putnbyte(sb + 0x06, len, 3)
|
||||
|
||||
/* With the fi-series scanners, we have to use a 12-byte command
|
||||
* instead of a 10-byte command when communicating via USB. This
|
||||
* may be a firmware bug. */
|
||||
static unsigned char set_usb_windowC[] =
|
||||
{ SET_WINDOW, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00 };
|
||||
/* opcode, lun, _____4 X reserved____, transfer length, control byte */
|
||||
static scsiblk set_usb_windowB = { set_usb_windowC, sizeof (set_usb_windowC) };
|
||||
#define set_SW_xferlen(sb, len) putnbyte(sb + 0x06, len, 3)
|
||||
|
||||
/* ==================================================================== */
|
||||
|
@ -252,7 +279,7 @@ static scsiblk object_positionB =
|
|||
|
||||
#define set_OP_autofeed(b,val) setbitfield(b+0x01, 0x07, 0, val)
|
||||
#define OP_Discharge 0x00
|
||||
#define OP_Feed 0x01
|
||||
#define OP_Feed 0x01
|
||||
|
||||
/* ==================================================================== */
|
||||
|
||||
|
@ -381,75 +408,107 @@ static scsiblk mode_selectB = { mode_selectC, sizeof (mode_selectC) };
|
|||
|
||||
#define set_MSEL_xfer_length(sb, val) sb[0x04] = (unsigned char)val
|
||||
|
||||
|
||||
static unsigned char mode_select_headerC[] = {
|
||||
0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
static scsiblk mode_select_headerB = {
|
||||
mode_select_headerC, sizeof (mode_select_headerC)
|
||||
};
|
||||
|
||||
|
||||
/* With the fi-series scanners, we have to use a 10-byte header
|
||||
* instead of a 4-byte header when communicating via USB. This
|
||||
* may be a firmware bug. */
|
||||
static unsigned char mode_select_usb_headerC[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
static scsiblk mode_select_usb_headerB = {
|
||||
mode_select_usb_headerC, sizeof (mode_select_usb_headerC)
|
||||
};
|
||||
|
||||
|
||||
static unsigned char mode_select_parameter_blockC[] = {
|
||||
0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00,
|
||||
0x00
|
||||
};
|
||||
static scsiblk mode_select_parameter_blockB =
|
||||
{ mode_select_parameter_blockC, sizeof (mode_select_parameter_blockC) };
|
||||
|
||||
#define set_MSEL_len(sb, len) putnbyte(sb + 0x01, len, 1)
|
||||
/*
|
||||
* PageCode:
|
||||
/* combined 4 byte header and 8 byte page
|
||||
* PageCodes: (most scanners know a few of these)
|
||||
* 0x34 = Sleep mode
|
||||
* 0x35 = ADF duplex reading transfer mode
|
||||
* 0x36 = All sorts of device controls switching
|
||||
* 0x37 = Backing switch control
|
||||
* 0x38 = Double feed detection
|
||||
* 0x39 = Drop out color
|
||||
* 0x3c = Paper width, paper length detection, deskew
|
||||
* 0x3c = Auto paper size detection
|
||||
* 0x3d = Lamp light timer set
|
||||
* 0x3e = Special-purpose paper detection mode
|
||||
* 0x3e = Detect job separation sheet
|
||||
* there is also possibly a 'descriptor block'
|
||||
* and a 'vendor-specific block'
|
||||
* fujitsu's seem not to use these two
|
||||
*/
|
||||
#define set_MSEL_pagecode(sb, val) setbitfield(sb, 0x3f, 0, val)
|
||||
#define MSEL_sleep 0x34
|
||||
#define MSEL_transfer_mode 0x35
|
||||
#define MSEL_dropout_color 0x39
|
||||
|
||||
static unsigned char mode_select_sleepC[] = {
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x34, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
static scsiblk mode_select_sleepB = {
|
||||
mode_select_sleepC, sizeof (mode_select_sleepC)
|
||||
};
|
||||
/* time until the device internal power supply switches to Sleep Mode
|
||||
* 0 = Default (15 min)
|
||||
* 1 = 1 min
|
||||
* 2 = 2 min
|
||||
* 0x3c ..0xff = 60 min
|
||||
*/
|
||||
#define set_MSEL_sleep_mode(sb, val) setbitfield(sb + 0x02, 0x0f, 0, val)
|
||||
#define set_MSEL_sleep_mode(sb, val) sb[0x06]=val
|
||||
|
||||
static unsigned char mode_select_duplexC[] = {
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x35, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
static scsiblk mode_select_duplexB = {
|
||||
mode_select_duplexC, sizeof (mode_select_duplexC)
|
||||
};
|
||||
/* adf duplex reading transfer method
|
||||
* 0 = front side - back side sequential transfer
|
||||
* 1 = front side - back side alternate transfer
|
||||
*/
|
||||
#define set_MSEL_transfer_mode(sb, val) setbitfield(sb + 0x02, 0x01, 0, val)
|
||||
|
||||
#define set_MSEL_dropout_front(sb, val) setbitfield(sb + 0x02, 0x0f, 0, val)
|
||||
#define set_MSEL_dropout_back(sb, val) setbitfield(sb + 0x02, 0x0f, 4, val)
|
||||
static unsigned char mode_select_randC[] = {
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x36, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
static scsiblk mode_select_randB = {
|
||||
mode_select_randC, sizeof (mode_select_randC)
|
||||
};
|
||||
|
||||
static unsigned char mode_select_backingC[] = {
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x37, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
static scsiblk mode_select_backingB = {
|
||||
mode_select_backingC, sizeof (mode_select_backingC)
|
||||
};
|
||||
|
||||
/*byte 0x06 is bitmask controlling double feed detection*/
|
||||
static unsigned char mode_select_dfeedC[] = {
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x38, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
static scsiblk mode_select_dfeedB = {
|
||||
mode_select_dfeedC, sizeof (mode_select_dfeedC)
|
||||
};
|
||||
|
||||
/*byte 0x06 is bitmask controlling monochrome color*/
|
||||
static unsigned char mode_select_dropoutC[] = {
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x39, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
static scsiblk mode_select_dropoutB = {
|
||||
mode_select_dropoutC, sizeof (mode_select_dropoutC)
|
||||
};
|
||||
#define set_MSEL_dropout_front(sb, val) setbitfield(sb + 0x06, 0x0f, 0, val)
|
||||
#define set_MSEL_dropout_back(sb, val) setbitfield(sb + 0x06, 0x0f, 4, val)
|
||||
#define MSEL_dropout_DEFAULT 0
|
||||
#define MSEL_dropout_GREEN 8
|
||||
#define MSEL_dropout_RED 9
|
||||
#define MSEL_dropout_BLUE 11
|
||||
#define MSEL_dropout_CUSTOM 12
|
||||
/* ==================================================================== */
|
||||
|
||||
/*bytes 0x06-07 and 0x09 control paper size detection*/
|
||||
static unsigned char mode_select_autoC[] = {
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x3C, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
static scsiblk mode_select_autoB = {
|
||||
mode_select_autoC, sizeof (mode_select_autoC)
|
||||
};
|
||||
|
||||
static unsigned char mode_select_lampC[] = {
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x3D, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
static scsiblk mode_select_lampB= {
|
||||
mode_select_lampC, sizeof (mode_select_lampC)
|
||||
};
|
||||
|
||||
/* ==================================================================== */
|
||||
#if 0
|
||||
|
@ -478,37 +537,44 @@ static scsiblk hw_statusB = { hw_statusC, sizeof (hw_statusC) };
|
|||
|
||||
#define set_HW_allocation_length(sb, len) putnbyte(sb + 0x07, len, 2)
|
||||
|
||||
#define get_HW_B5_present(in) getbitfield(in+0x02, 1, 0)
|
||||
#define get_HW_A4_present(in) getbitfield(in+0x02, 1, 1)
|
||||
#define get_HW_B4_present(in) getbitfield(in+0x02, 1, 2)
|
||||
#define get_HW_A3_present(in) getbitfield(in+0x02, 1, 3)
|
||||
#define get_HW_adf_empty(in) getbitfield(in+0x03, 1, 7)
|
||||
#define get_HW_omr(in) getbitfield(in+0x03, 1, 6)
|
||||
#define get_HW_adfc_open(in) getbitfield(in+0x03, 1, 5)
|
||||
#define get_HW_sleep(in) getbitfield(in+0x04, 1, 7)
|
||||
#define get_HW_manual_feed(in) getbitfield(in+0x04, 1, 1)
|
||||
#define get_HW_start_button(in) getbitfield(in+0x04, 1, 0)
|
||||
#define get_HW_ink_empty(in) getbitfield(in+0x06, 1, 7)
|
||||
#define get_HW_dfeed_detected(in) getbitfield(in+0x06, 1, 0)
|
||||
#define get_HW_skew_angle(in) getnbyte(in+0x08, 2)
|
||||
#define get_HW_top(in) getbitfield(in+0x02, 1, 7)
|
||||
#define get_HW_A3(in) getbitfield(in+0x02, 1, 3)
|
||||
#define get_HW_B4(in) getbitfield(in+0x02, 1, 2)
|
||||
#define get_HW_A4(in) getbitfield(in+0x02, 1, 1)
|
||||
#define get_HW_B5(in) getbitfield(in+0x02, 1, 0)
|
||||
|
||||
#define get_HW_hopper(in) !getbitfield(in+0x03, 1, 7)
|
||||
#define get_HW_omr(in) getbitfield(in+0x03, 1, 6)
|
||||
#define get_HW_adf_open(in) getbitfield(in+0x03, 1, 5)
|
||||
|
||||
#define get_HW_sleep(in) getbitfield(in+0x04, 1, 7)
|
||||
#define get_HW_send_sw(in) getbitfield(in+0x04, 1, 2)
|
||||
#define get_HW_manual_feed(in) getbitfield(in+0x04, 1, 1)
|
||||
#define get_HW_scan_sw(in) getbitfield(in+0x04, 1, 0)
|
||||
|
||||
#define get_HW_function(in) getbitfield(in+0x05, 0x0f, 0)
|
||||
|
||||
#define get_HW_ink_empty(in) getbitfield(in+0x06, 1, 7)
|
||||
#define get_HW_double_feed(in) getbitfield(in+0x06, 1, 0)
|
||||
|
||||
#define get_HW_error_code(in) in[0x07]
|
||||
|
||||
#define get_HW_skew_angle(in) getnbyte(in+0x08, 2)
|
||||
|
||||
#define get_HW_ink_remain(in) in[0x0a]
|
||||
|
||||
/* ==================================================================== */
|
||||
|
||||
/* We use the same structure for both SET WINDOW and GET WINDOW. */
|
||||
static unsigned char window_parameter_data_blockC[] = {
|
||||
static unsigned char window_descriptor_headerC[] = {
|
||||
0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, /* reserved */
|
||||
0x00, 0x00, /* Window Descriptor Length */
|
||||
};
|
||||
static scsiblk window_parameter_data_blockB =
|
||||
{ window_parameter_data_blockC, sizeof (window_parameter_data_blockC) };
|
||||
|
||||
static scsiblk window_descriptor_headerB=
|
||||
{ window_descriptor_headerC, sizeof (window_descriptor_headerC) };
|
||||
#define set_WPDB_wdblen(sb, len) putnbyte(sb + 0x06, len, 2)
|
||||
|
||||
#define used_WDB_size 0x60
|
||||
#define max_WDB_size 0xff
|
||||
|
||||
/* ==================================================================== */
|
||||
|
||||
static unsigned char window_descriptor_blockC[] = {
|
||||
|
@ -617,7 +683,9 @@ static unsigned char window_descriptor_blockC[] = {
|
|||
#define WD_comp_LA 0
|
||||
#define WD_comp_HT 1
|
||||
#define WD_comp_GS 2
|
||||
#define WD_comp_RC 5
|
||||
#define WD_comp_CL 3
|
||||
#define WD_comp_CH 4
|
||||
#define WD_comp_CG 5
|
||||
|
||||
/* 0x1a - Depth
|
||||
* 3091 - use 0x01 for b/w or 0x08 for gray/color
|
||||
|
@ -694,7 +762,7 @@ static unsigned char window_descriptor_blockC[] = {
|
|||
* 3091 - use 0xc0
|
||||
* 3096 - use 0xc0
|
||||
*/
|
||||
0xC0,
|
||||
0x00,
|
||||
#define set_WD_vendor_id_code(sb, val) sb[0x28] = val
|
||||
#define get_WD_vendor_id_code(sb) sb[0x28]
|
||||
|
||||
|
@ -757,10 +825,10 @@ static unsigned char window_descriptor_blockC[] = {
|
|||
#define get_WD_mirroring(sb) getbitfield(sb + 0x2d, 1, 7)
|
||||
#define set_WD_lamp_color(sb, val) sb[0x2d] = val
|
||||
#define get_WD_lamp_color(sb) sb[0x2d]
|
||||
#define LAMP_DEFAULT 0x00
|
||||
#define LAMP_BLUE 0x01
|
||||
#define LAMP_RED 0x02
|
||||
#define LAMP_GREEN 0x04
|
||||
#define WD_LAMP_DEFAULT 0x00
|
||||
#define WD_LAMP_BLUE 0x01
|
||||
#define WD_LAMP_RED 0x02
|
||||
#define WD_LAMP_GREEN 0x04
|
||||
|
||||
/* 0x2e - variance/bit padding
|
||||
* 3091 - unsupported, use 0x00
|
||||
|
@ -828,13 +896,27 @@ static unsigned char window_descriptor_blockC[] = {
|
|||
#define set_WD_subwindow_list(sb, val) putnbyte(sb + 0x33, val, 2)
|
||||
#define get_WD_subwindow_list(sb) getnbyte(sb + 0x33, 2)
|
||||
|
||||
/* 0x35 - paper size
|
||||
/* 0x35 - paper size
|
||||
* 3091 unsupported, always use 0xc0
|
||||
* 3096 if bits 6-7 both set, custom paper size enabled,
|
||||
* bytes 0x36-0x3d used. Otherwise, a number of
|
||||
* valid fixed values denote common paper formats.
|
||||
*/
|
||||
0xC0,
|
||||
#define set_WD_paper_selection(sb, val) setbitfield(sb + 0x35, 3, 6, val)
|
||||
#define WD_paper_SEL_UNDEFINED 0
|
||||
#define WD_paper_SEL_NON_STANDARD 3
|
||||
|
||||
/* we no longer use these, custom size (0xc0) overrides,
|
||||
and more recent scanners only use custom size anyway
|
||||
#define get_WD_paper_selection(sb) getbitfield(sb + 0x35, 3, 6)
|
||||
#define WD_paper_SEL_STANDARD 2
|
||||
|
||||
#define set_WD_paper_orientation(sb, val) setbitfield(sb + 0x35, 1, 4, val)
|
||||
#define get_WD_paper_orientation(sb) getbitfield(sb + 0x35, 1, 4)
|
||||
#define WD_paper_PORTRAIT 0
|
||||
#define WD_paper_LANDSCAPE 1
|
||||
|
||||
#define set_WD_paper_size(sb, val) setbitfield(sb + 0x35, 0x0f, 0, val)
|
||||
#define get_WD_paper_size(sb) getbitfield(sb + 0x35, 0x0f, 0)
|
||||
#define WD_paper_UNDEFINED 0
|
||||
|
@ -847,15 +929,7 @@ static unsigned char window_descriptor_blockC[] = {
|
|||
#define WD_paper_B5 13
|
||||
#define WD_paper_LEGAL 15
|
||||
#define WD_paper_CUSTOM 14
|
||||
#define set_WD_paper_orientation(sb, val) setbitfield(sb + 0x35, 1, 4, val)
|
||||
#define get_WD_paper_orientation(sb) getbitfield(sb + 0x35, 1, 4)
|
||||
#define WD_paper_PORTRAIT 0
|
||||
#define WD_paper_LANDSCAPE 1
|
||||
#define set_WD_paper_selection(sb, val) setbitfield(sb + 0x35, 3, 6, val)
|
||||
#define get_WD_paper_selection(sb) getbitfield(sb + 0x35, 3, 6)
|
||||
#define WD_paper_SEL_UNDEFINED 0
|
||||
#define WD_paper_SEL_STANDARD 2
|
||||
#define WD_paper_SEL_NON_STANDARD 3
|
||||
*/
|
||||
|
||||
/* 0x36-0x39 - custom paper width
|
||||
* 3091 0<w<=10200
|
||||
|
@ -905,28 +979,18 @@ static unsigned char window_descriptor_blockC[] = {
|
|||
0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58 - 0x5c reserved */
|
||||
0x00, 0x00, 0x00 /* 0x5d - 0x5f reserved */
|
||||
};
|
||||
|
||||
static scsiblk window_descriptor_blockB =
|
||||
{ window_descriptor_blockC, sizeof (window_descriptor_blockC) };
|
||||
#define max_WDB_size 0xc8
|
||||
|
||||
/* ==================================================================== */
|
||||
|
||||
/*#define set_WDB_length(length) (window_descriptor_block.size = (length)) */
|
||||
#define WPDB_OFF(b) (b + set_window.size)
|
||||
#define WDB_OFF(b, n) (b + set_window.size + \
|
||||
window_parameter_data_block.size + \
|
||||
( window_descriptor_block.size * (n - 1) ) )
|
||||
#define set_WPDB_wdbnum(sb,n) set_WPDB_wdblen(sb,window_descriptor_block.size*n)
|
||||
#define RS_return_size 0x12
|
||||
|
||||
/* ==================================================================== */
|
||||
static unsigned char request_senseC[] =
|
||||
{REQUEST_SENSE, 0x00, 0x00, 0x00, RS_return_size, 0x00};
|
||||
static scsiblk request_senseB = {request_senseC, sizeof (request_senseC)};
|
||||
|
||||
static unsigned char request_senseC[] =
|
||||
{REQUEST_SENSE, 0x00, 0x00, 0x00, 0x12, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
static scsiblk request_senseB =
|
||||
{request_senseC, sizeof (request_senseC)};
|
||||
|
||||
#define set_RS_allocation_length(sb,val) sb[0x04] = (unsigned char)val
|
||||
/* defines for request sense return block */
|
||||
#define get_RS_information_valid(b) getbitfield(b + 0x00, 1, 7)
|
||||
#define get_RS_error_code(b) getbitfield(b + 0x00, 0x7f, 0)
|
||||
|
@ -938,12 +1002,24 @@ static scsiblk window_descriptor_blockB =
|
|||
#define get_RS_additional_length(b) b[0x07] /* always 10 */
|
||||
#define get_RS_ASC(b) b[0x0c]
|
||||
#define get_RS_ASCQ(b) b[0x0d]
|
||||
#define get_RS_SKSV(b) getbitfield(b+0x0f,1,7) /* valid, always 0 */
|
||||
#define get_RS_SKSV(b) getbitfield(b+0x0f,1,7) /* valid=0 */
|
||||
#define get_RS_SKSB(b) getnbyte(b+0x0f, 3)
|
||||
|
||||
/* when RS is 0x05/0x26 bad bytes listed in sksb */
|
||||
#define get_RS_offending_byte(b) getnbyte(b+0x10, 2)
|
||||
|
||||
#define rs_return_block_size 18 /* Says Nikon */
|
||||
/* 3091 and 3092 use RS instead of ghs. RS must be 0x00/0x80 */
|
||||
/* in ascq */
|
||||
#define get_RS_adf_open(in) getbitfield(in+0x0d, 1, 7)
|
||||
#define get_RS_send_sw(in) getbitfield(in+0x0d, 1, 5)
|
||||
#define get_RS_scan_sw(in) getbitfield(in+0x0d, 1, 4)
|
||||
#define get_RS_duplex_sw(in) getbitfield(in+0x0d, 1, 2)
|
||||
#define get_RS_top(in) getbitfield(in+0x0d, 1, 1)
|
||||
#define get_RS_hopper(in) getbitfield(in+0x0d, 1, 0)
|
||||
|
||||
/* ==================================================================== */
|
||||
/* in sksb */
|
||||
#define get_RS_function(in) getbitfield(in+0x0f, 0x0f, 3)
|
||||
#define get_RS_density(in) getbitfield(in+0x0f, 0x07, 0)
|
||||
|
||||
/* ==================================================================== */
|
||||
|
||||
|
|
10716
backend/fujitsu.c
10716
backend/fujitsu.c
Plik diff jest za duży
Load Diff
|
@ -1,16 +1,25 @@
|
|||
# NOTE: any 'option' lines must come first
|
||||
|
||||
# to override data buffer size, in bytes
|
||||
# if unset, the backend will figure it out.
|
||||
# the value ranges from 4096 - infinity
|
||||
# but will likely not work above 32768
|
||||
# dont use this unless you KNOW you need it
|
||||
#option scsi-buffer-size 32768
|
||||
|
||||
# To search for all FUJITSU scsi devices
|
||||
scsi FUJITSU
|
||||
|
||||
# To use a specific scsi device
|
||||
#/dev/sg1
|
||||
#scsi /dev/sg1
|
||||
|
||||
# For Fujitsu scanners connected via USB on a known device (kernel driver):
|
||||
#usb /dev/usb/scanner0
|
||||
|
||||
# For Fujitsu scanners connected via USB using vendor and device ids (libusb):
|
||||
#usb 0x04c5 0x1042
|
||||
#usb 0x04c5 0x1041
|
||||
|
||||
# To force the Fujitsu backend to treat all devices it finds as a certain type:
|
||||
#option force-model fi-4340Cdi
|
||||
usb 0x04c5 0x1042
|
||||
usb 0x04c5 0x1041
|
||||
usb 0x04c5 0x1097
|
||||
usb 0x04c5 0x10e0
|
||||
usb 0x04c5 0x10ae
|
||||
|
||||
|
|
|
@ -3,15 +3,9 @@
|
|||
|
||||
/*
|
||||
* Part of SANE - Scanner Access Now Easy.
|
||||
*
|
||||
* Please see opening comment in fujitsu.c
|
||||
*/
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static int num_devices = 0;
|
||||
static struct fujitsu *first_dev;
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
* This option list has to contain all options for all scanners supported by
|
||||
* this driver. If a certain scanner cannot handle a certain option, there's
|
||||
|
@ -22,410 +16,389 @@ enum fujitsu_Option
|
|||
OPT_NUM_OPTS = 0,
|
||||
|
||||
OPT_MODE_GROUP,
|
||||
OPT_SOURCE,
|
||||
OPT_MODE,
|
||||
OPT_DUPLEX,
|
||||
OPT_X_RES,
|
||||
OPT_Y_RES,
|
||||
OPT_SOURCE, /*fb/adf/front/back/duplex*/
|
||||
OPT_MODE, /*mono/gray/color*/
|
||||
OPT_X_RES, /*a range or a list*/
|
||||
OPT_Y_RES, /*a range or a list*/
|
||||
|
||||
OPT_GEOMETRY_GROUP,
|
||||
OPT_TL_X, /* in mm/2^16 */
|
||||
OPT_TL_Y, /* in mm/2^16 */
|
||||
OPT_BR_X, /* in mm/2^16 */
|
||||
OPT_BR_Y, /* in mm/2^16 */
|
||||
OPT_TL_X,
|
||||
OPT_TL_Y,
|
||||
OPT_BR_X,
|
||||
OPT_BR_Y,
|
||||
OPT_PAGE_WIDTH,
|
||||
OPT_PAGE_HEIGHT,
|
||||
|
||||
|
||||
OPT_ENHANCEMENT_GROUP,
|
||||
OPT_AVERAGING,
|
||||
OPT_BRIGHTNESS,
|
||||
OPT_THRESHOLD,
|
||||
OPT_CONTRAST,
|
||||
|
||||
OPT_RIF,
|
||||
OPT_COMPRESSION,
|
||||
OPT_COMPRESSION_ARG,
|
||||
|
||||
OPT_DTC_SELECTION,
|
||||
OPT_GAMMA,
|
||||
OPT_OUTLINE_EXTRACTION,
|
||||
OPT_EMPHASIS,
|
||||
OPT_AUTOSEP,
|
||||
OPT_MIRROR_IMAGE,
|
||||
OPT_VARIANCE_RATE,
|
||||
OPT_THRESHOLD_CURVE,
|
||||
OPT_GRADATION,
|
||||
OPT_SMOOTHING_MODE,
|
||||
OPT_FILTERING,
|
||||
OPT_BACKGROUND,
|
||||
OPT_NOISE_REMOVAL,
|
||||
OPT_MATRIX2X2,
|
||||
OPT_MATRIX3X3,
|
||||
OPT_MATRIX4X4,
|
||||
OPT_MATRIX5X5,
|
||||
OPT_WHITE_LEVEL_FOLLOW,
|
||||
|
||||
OPT_PAPER_SIZE,
|
||||
OPT_PAPER_WIDTH,
|
||||
OPT_PAPER_HEIGHT,
|
||||
OPT_PAPER_ORIENTATION,
|
||||
|
||||
OPT_ADVANCED_GROUP,
|
||||
OPT_DROPOUT_COLOR,
|
||||
OPT_START_BUTTON,
|
||||
|
||||
OPT_TUNING_GROUP,
|
||||
OPT_LAMP_COLOR,
|
||||
OPT_SLEEP_TIME,
|
||||
OPT_DUPLEX_OFFSET,
|
||||
OPT_BLUE_OFFSET,
|
||||
OPT_GREEN_OFFSET,
|
||||
OPT_USE_SWAPFILE,
|
||||
|
||||
OPT_IMPRINTER_GROUP,
|
||||
OPT_IMPRINTER,
|
||||
OPT_IMPRINTER_DIR,
|
||||
OPT_IMPRINTER_YOFFSET,
|
||||
OPT_IMPRINTER_STRING,
|
||||
OPT_IMPRINTER_CTR_INIT,
|
||||
OPT_IMPRINTER_CTR_STEP,
|
||||
OPT_IMPRINTER_CTR_DIR,
|
||||
|
||||
OPT_SLEEP_MODE,
|
||||
OPT_SENSOR_GROUP,
|
||||
OPT_TOP,
|
||||
OPT_A3,
|
||||
OPT_B4,
|
||||
OPT_A4,
|
||||
OPT_B5,
|
||||
OPT_HOPPER,
|
||||
OPT_OMR,
|
||||
OPT_ADF_OPEN,
|
||||
OPT_SLEEP,
|
||||
OPT_SEND_SW,
|
||||
OPT_MANUAL_FEED,
|
||||
OPT_SCAN_SW,
|
||||
OPT_FUNCTION,
|
||||
OPT_INK_EMPTY,
|
||||
OPT_DOUBLE_FEED,
|
||||
OPT_ERROR_CODE,
|
||||
OPT_SKEW_ANGLE,
|
||||
OPT_INK_REMAIN,
|
||||
OPT_DUPLEX_SW,
|
||||
OPT_DENSITY_SW,
|
||||
|
||||
/* must come last: */
|
||||
NUM_OPTIONS
|
||||
};
|
||||
|
||||
|
||||
typedef enum { /* hardware connection to the scanner */
|
||||
SANE_FUJITSU_NODEV, /* default, no HW specified yet */
|
||||
SANE_FUJITSU_SCSI, /* SCSI interface */
|
||||
SANE_FUJITSU_PIO, /* parallel interface */
|
||||
SANE_FUJITSU_USB /* USB interface */
|
||||
} Fujitsu_Connection_Type;
|
||||
|
||||
struct fujitsu
|
||||
{
|
||||
/* --------------------------------------------------------------------- */
|
||||
/* immutable values which are set during init of scanner. */
|
||||
struct fujitsu *next;
|
||||
char *device_name; /* The name of the scanner device for sane */
|
||||
|
||||
SANE_Option_Descriptor opt[NUM_OPTIONS];
|
||||
Option_Value val[NUM_OPTIONS];
|
||||
/* --------------------------------------------------------------------- */
|
||||
/* immutable values which are set during reading of config file. */
|
||||
int scsi_buf_size;
|
||||
int connection; /* hardware interface type */
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/* immutable values which are set during inquiry probing of the scanner. */
|
||||
/* members in order found in scsi data... */
|
||||
SANE_Device sane;
|
||||
|
||||
|
||||
/* Immutable values which are set during initial probing of the scanner. */
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
char vendorName[9]; /* raw data as returned by SCSI inquiry. */
|
||||
char productName[17]; /* raw data as returned by SCSI inquiry. */
|
||||
char versionName[5]; /* raw data as returned by SCSI inquiry. */
|
||||
|
||||
int model; /* The scanner model. */
|
||||
|
||||
char *devicename; /* The name of the scanner device. */
|
||||
|
||||
Fujitsu_Connection_Type connection; /* hardware interface type */
|
||||
|
||||
int sfd; /* The scanner device file descriptor. */
|
||||
char vendor_name[9]; /* raw data as returned by SCSI inquiry. */
|
||||
char product_name[17]; /* raw data as returned by SCSI inquiry. */
|
||||
char version_name[5]; /* raw data as returned by SCSI inquiry. */
|
||||
|
||||
int color_raster_offset; /* offset between r and b scan line and */
|
||||
/* between b and g scan line (4 for all */
|
||||
/* known models) */
|
||||
int duplex_raster_offset; /* offset between front and rear page when */
|
||||
/* when scanning duplex */
|
||||
/* between b and g scan line (0 or 4) */
|
||||
int duplex_raster_offset; /* offset between front and rear page when */
|
||||
/* when scanning 3091 style duplex */
|
||||
|
||||
int can_read_alternate; /* duplex transfer mode front/back/front/back... */
|
||||
int read_mode; /* constants READ_MODE_* and funcs convert_* */
|
||||
int has_adf; /* true if an ADF has been detected. */
|
||||
int has_fb;
|
||||
int duplex_present; /* true if a duplex unit has been detected. */
|
||||
int ipc_present; /* true if ipc2/3 option detected */
|
||||
int cmp_present; /* true if cmp2 present */
|
||||
int has_hw_status; /* true for M409X series */
|
||||
int has_outline; /* ............ */
|
||||
int has_emphasis; /* ............ */
|
||||
int has_autosep; /* ............ */
|
||||
int has_mirroring; /* ............ */
|
||||
int has_reverse;
|
||||
int has_white_level_follow; /* ............ */
|
||||
int has_subwindow; /* ............ */
|
||||
int has_dropout_color; /* */
|
||||
/* --------------------------------------------------------------------- */
|
||||
/* immutable values which are set during std VPD probing of the scanner. */
|
||||
/* members in order found in scsi data... */
|
||||
int basic_x_res;
|
||||
int basic_y_res;
|
||||
int step_x_res;
|
||||
int step_y_res;
|
||||
int max_x_res;
|
||||
int max_y_res;
|
||||
int min_x_res;
|
||||
int min_y_res;
|
||||
|
||||
int std_res_200;
|
||||
int std_res_180;
|
||||
int std_res_160;
|
||||
int std_res_150;
|
||||
int std_res_120;
|
||||
int std_res_100;
|
||||
int std_res_75;
|
||||
int std_res_60;
|
||||
int std_res_1200;
|
||||
int std_res_800;
|
||||
int std_res_600;
|
||||
int std_res_480;
|
||||
int std_res_400;
|
||||
int std_res_320;
|
||||
int std_res_300;
|
||||
int std_res_240;
|
||||
|
||||
/* max scan size in pixels comes from scanner in basic res units */
|
||||
int max_x_basic;
|
||||
int max_y_basic;
|
||||
|
||||
int can_overflow;
|
||||
int can_monochrome;
|
||||
int can_halftone;
|
||||
int can_grayscale;
|
||||
int can_color_monochrome;
|
||||
int can_color_halftone;
|
||||
int can_color_grayscale;
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/* immutable values which are set during vndr VPD probing of the scanner */
|
||||
/* members in order found in scsi data... */
|
||||
int has_operator_panel;
|
||||
int has_barcode;
|
||||
int has_imprinter;
|
||||
int has_threshold;
|
||||
int has_brightness;
|
||||
int has_contrast;
|
||||
int has_gamma;
|
||||
int has_duplex;
|
||||
int has_transparency;
|
||||
int has_flatbed;
|
||||
int has_adf;
|
||||
|
||||
int adbits;
|
||||
int buffer_bytes;
|
||||
|
||||
/*FIXME: do we need the std cmd list? */
|
||||
|
||||
/*FIXME: there are more vendor cmds? */
|
||||
int has_cmd_subwindow;
|
||||
int has_cmd_endorser;
|
||||
int has_cmd_hw_status;
|
||||
int has_cmd_scanner_ctl;
|
||||
|
||||
/*FIXME: do we need the vendor window param list? */
|
||||
|
||||
int brightness_steps;
|
||||
int threshold_steps;
|
||||
int contrast_steps;
|
||||
|
||||
int num_internal_gamma;
|
||||
int num_download_gamma;
|
||||
int has_fixed_paper_size;
|
||||
int num_internal_dither;
|
||||
int num_download_dither;
|
||||
|
||||
SANE_Range adf_width_range;
|
||||
SANE_Range adf_height_range;
|
||||
SANE_Range x_range;
|
||||
SANE_Range y_range;
|
||||
int has_rif;
|
||||
int has_auto1;
|
||||
int has_auto2;
|
||||
int has_outline;
|
||||
int has_emphasis;
|
||||
int has_autosep;
|
||||
int has_mirroring;
|
||||
int has_white_level_follow;
|
||||
int has_subwindow;
|
||||
|
||||
int has_comp_MH;
|
||||
int has_comp_MR;
|
||||
int has_comp_MMR;
|
||||
int has_comp_JBIG;
|
||||
int has_comp_JPG1;
|
||||
int has_comp_JPG2;
|
||||
int has_comp_JPG3;
|
||||
|
||||
/*FIXME: endorser data? */
|
||||
|
||||
/*FIXME: barcode data? */
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/* immutable values which are hard coded because they are not in vpd */
|
||||
/* this section replaces all the old 'switch (s->model)' code */
|
||||
|
||||
/* the scan size in 1/1200th inches, NOT basic_units or sane units */
|
||||
int max_x;
|
||||
int max_y;
|
||||
int min_x;
|
||||
int min_y;
|
||||
|
||||
int has_back; /* not all duplex scanners can do adf back side only */
|
||||
int color_interlace; /* different models interlace colors differently */
|
||||
int duplex_interlace; /* different models interlace sides differently */
|
||||
int has_MS_dropout; /* dropout color specified in mode select data */
|
||||
int has_SW_dropout; /* dropout color specified in set window data */
|
||||
int window_vid; /* some models want different vendor ID in set window */
|
||||
int ghs_in_rs;
|
||||
|
||||
int reverse_by_mode[6]; /* mode specific */
|
||||
/* --------------------------------------------------------------------- */
|
||||
/* changeable SANE_Option structs provide our interface to frontend. */
|
||||
/* some options require lists of strings or numbers, we keep them here */
|
||||
/* instead of in global vars so that they can differ for each scanner */
|
||||
/* these are loaded in init_options(), but may be changed by other funcs */
|
||||
|
||||
/* long array of option structs */
|
||||
SANE_Option_Descriptor opt[NUM_OPTIONS];
|
||||
|
||||
/*mode group*/
|
||||
SANE_String_Const mode_list[7];
|
||||
SANE_String_Const source_list[5];
|
||||
|
||||
SANE_Int x_res_list[17];
|
||||
SANE_Int y_res_list[17];
|
||||
SANE_Range x_res_range;
|
||||
SANE_Range y_res_range;
|
||||
SANE_Range x_grey_res_range;
|
||||
SANE_Range y_grey_res_range;
|
||||
|
||||
SANE_String_Const vpd_mode_list[7];
|
||||
SANE_String_Const compression_mode_list[9];
|
||||
/*geometry group*/
|
||||
SANE_Range tl_x_range;
|
||||
SANE_Range tl_y_range;
|
||||
SANE_Range br_x_range;
|
||||
SANE_Range br_y_range;
|
||||
SANE_Range paper_x_range;
|
||||
SANE_Range paper_y_range;
|
||||
|
||||
SANE_Int x_res_list[17]; /* range of x and y resolution */
|
||||
SANE_Int y_res_list[17]; /* if scanner has only fixed resolutions */
|
||||
SANE_Int x_res_list_grey[17];
|
||||
SANE_Int y_res_list_grey[17];
|
||||
|
||||
SANE_Range threshold_range;
|
||||
/*enhancement group*/
|
||||
SANE_Range brightness_range;
|
||||
SANE_Range threshold_range;
|
||||
SANE_Range contrast_range;
|
||||
|
||||
/* User settable values (usually mirrored in SANE options) */
|
||||
/*ipc group*/
|
||||
|
||||
/*advanced group*/
|
||||
SANE_String_Const do_color_list[5];
|
||||
SANE_String_Const lamp_color_list[5];
|
||||
SANE_Range sleep_time_range;
|
||||
SANE_Range duplex_offset_range;
|
||||
SANE_Range blue_offset_range;
|
||||
SANE_Range green_offset_range;
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/* changeable vars to hold user input. modified by SANE_Options above */
|
||||
|
||||
int duplex_mode; /* Use DUPLEX_* constants below */
|
||||
int resolution_x; /* X resolution in dpi */
|
||||
int resolution_y; /* Y resolution in dpi */
|
||||
int resolution_linked; /* When true, Y resolution is set whenever */
|
||||
/* X resolution gets changed. true initially, */
|
||||
/* becomes false if Y resolution is ever */
|
||||
/* set independently */
|
||||
int top_left_x; /* The desired size of the scan, in */
|
||||
int top_left_y; /* mm/2^16. Notice that there's a second */
|
||||
int bottom_right_x; /* group of these with the "rounded" */
|
||||
int bottom_right_y; /* prefix, below. */
|
||||
/*mode group*/
|
||||
int mode; /*color,lineart,etc*/
|
||||
int source; /*fb,adf front,adf duplex,etc*/
|
||||
int resolution_x; /* X resolution in dpi */
|
||||
int resolution_y; /* Y resolution in dpi */
|
||||
|
||||
/* A note on the scan are size (topLeft/bottomRight) values. When the
|
||||
* user (the front-end) sets one of these, we change the above values
|
||||
* and immediately calculate from it the scan height and width in
|
||||
* 1/1200 inches (the internal scanner unit). Depending on the scan
|
||||
* mode, depth, etc., other rules may be used to change the value,
|
||||
* e.g. in 1bpp scans, the width is always increased until each scan
|
||||
* line has a full number of bytes.
|
||||
*
|
||||
* The results of these calculations are the "top_margin", "left_margin",
|
||||
* "scan_width", and "scan_height" values below. In addition, these
|
||||
* values are now converted back into SANE units (1/2^16mm) and stored
|
||||
* in roundedTopLeft... and roundedBottomRight... - when the front-end
|
||||
* _sets_ the scan area size, the topLeft... and bottomRight... values
|
||||
* will be set, but when the front-end _gets_ the scan area size,
|
||||
* the rounded values will be returned.
|
||||
*
|
||||
* By keeping the original values instead of rounding them "in place",
|
||||
* we can revise our rounded values later. Assume the resolution is set
|
||||
* to 75dpi, and then the scan size is set - it will be rounded to
|
||||
* the nearest 1/75 inch. Later the resolution is changed to 600dpi,
|
||||
* making a better approximation of the original desired size possible.
|
||||
*
|
||||
* All these calculations are done within the "calculateDerivedValues"
|
||||
* function.
|
||||
*/
|
||||
|
||||
int page_width; /* paper width and height may influence the */
|
||||
int page_height; /* way the ADF operates - in 1/1200 inch */
|
||||
|
||||
int output_depth; /* How many bits per pixel the user wants. */
|
||||
int scanner_depth; /* How many bpp the scanner will send. */
|
||||
|
||||
/* A note on "depth" values. Many colour scanners require you to use
|
||||
* the value "8" for depth if you're doing colour scans even if they
|
||||
* deliver 24. The front-end, when it calls "sane_get_parameters", will
|
||||
* expect to see the value 8 as well. However, internally, we use
|
||||
* scanner_depth as the real number of bits sent per pixel, which is
|
||||
* obvoiusly 24 for coulour scans.
|
||||
*
|
||||
* output_depth uses the same logic and normally both values would be
|
||||
* identical; however it may be desirable to implement, say, a 4-bit
|
||||
* grayscale mode in the backend even if the scanner only supports
|
||||
* 8-bit grayscale. In that case, the backend would to the reduction
|
||||
* "on the fly", and output_depth would be 4, while scanner_depth is 8.
|
||||
*/
|
||||
|
||||
int color_mode; /* Color/Gray/..., use MODE_* constants */
|
||||
int use_adf; /* Whether the ADF should be used or not. */
|
||||
int use_temp_file; /* Whether to use a temp file for duplex. */
|
||||
int mirror; /* Whether to mirror scan area for rear side */
|
||||
int lamp_color; /* lamp color to use for monochrome scans */
|
||||
int green_offset; /* color tuning - green scan line offset */
|
||||
int blue_offset; /* color tuning - blue scan line offset */
|
||||
|
||||
|
||||
|
||||
/* Derived values (calculated by calculateDerivedValues from the above) */
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
int rounded_top_left_x; /* Same as topLeft... and bottomRight..., */
|
||||
int rounded_top_left_y; /* but "rounded" to the nearest 1/1200 */
|
||||
int rounded_bottom_right_x; /* value, i.e. these are the values really */
|
||||
int rounded_bottom_right_y; /* used for scanning. */
|
||||
int top_margin; /* Top margin in 1/1200 inch */
|
||||
int left_margin; /* Left margin in 1/1200 inch */
|
||||
int scan_width; /* Width of scan in 1/1200 inch */
|
||||
int scan_height; /* Height of scan in 1/1200 inch */
|
||||
int scan_width_pixels; /* Pixels per scan line for this job */
|
||||
int scan_height_pixels; /* Number of lines in this job */
|
||||
int bytes_per_scan_line; /* Number of bytes per line in this job */
|
||||
|
||||
/* Operational values (contain internal status information etc.) */
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
int default_pipe_r; /* Pipe between reader process and backend. */
|
||||
int default_pipe_w; /* Pipe between reader process and backend. */
|
||||
int duplex_pipe_r; /* Additional pipe for duplex scans. */
|
||||
int duplex_pipe_w; /* Additional pipe for duplex scans. */
|
||||
int reader_pid; /* Process ID of the reader process. */
|
||||
|
||||
int reverse; /* Whether to reverse the image. Not user */
|
||||
/* settable but required internally. */
|
||||
|
||||
int i_transfer_length; /* needed when the scanner returns */
|
||||
/* compressed data and size of return data */
|
||||
/* is unknown in advance */
|
||||
|
||||
|
||||
|
||||
/* This replaced the former "scanning" flag. object_count represents the
|
||||
* number of objects acquired (or being acquired) by the scanner which
|
||||
* haven't been read. Thus, an object_count of != 0 means the scanner is
|
||||
* busy. If the scanner is scanning the first page, it's 1; if the scanner
|
||||
* is scanning the second page of a duplex scan, it's 2.
|
||||
*/
|
||||
int object_count;
|
||||
|
||||
/* This is set to "true" by sane_read when it encounters the end of a data
|
||||
* stream.
|
||||
*/
|
||||
int eof;
|
||||
|
||||
unsigned char *buffer; /* Buffer used for SCSI transfers. */
|
||||
unsigned int scsi_buf_size; /* Max amount of data in one SCSI call. */
|
||||
|
||||
/** these can be set */
|
||||
/*geometry group*/
|
||||
/* The desired size of the scan, all in 1/1200 inch */
|
||||
int tl_x;
|
||||
int tl_y;
|
||||
int br_x;
|
||||
int br_y;
|
||||
int page_width;
|
||||
int page_height;
|
||||
|
||||
/*enhancement group*/
|
||||
int brightness;
|
||||
int threshold;
|
||||
int contrast;
|
||||
int rif;
|
||||
|
||||
int bitorder;
|
||||
int compress_type;
|
||||
int compress_arg;
|
||||
int vendor_id_code;
|
||||
int gamma;
|
||||
int outline;
|
||||
int emphasis;
|
||||
int auto_sep;
|
||||
int mirroring;
|
||||
int var_rate_dyn_thresh;
|
||||
int white_level_follow;
|
||||
int gradation;
|
||||
int smoothing_mode;
|
||||
int filtering;
|
||||
int background;
|
||||
int matrix2x2;
|
||||
int matrix3x3;
|
||||
int matrix4x4;
|
||||
int matrix5x5;
|
||||
int noise_removal;
|
||||
int paper_orientation;
|
||||
int paper_selection;
|
||||
int paper_size;
|
||||
int dtc_threshold_curve;
|
||||
int dtc_selection;
|
||||
|
||||
int subwindow_list;
|
||||
/***** end of "set window" terms *****/
|
||||
/*ipc group*/
|
||||
int gamma; /* not currently user settable */
|
||||
|
||||
/*advanced group*/
|
||||
int dropout_color;
|
||||
int lamp_color;
|
||||
int sleep_time;
|
||||
int duplex_offset;
|
||||
int blue_offset;
|
||||
int green_offset;
|
||||
int use_temp_file;
|
||||
|
||||
SANE_Bool use_imprinter;
|
||||
int imprinter_direction;
|
||||
SANE_Word imprinter_y_offset;
|
||||
SANE_Char imprinter_string[max_imprinter_string_length];
|
||||
int imprinter_ctr_init;
|
||||
int imprinter_ctr_step;
|
||||
int imprinter_ctr_dir;
|
||||
/* --------------------------------------------------------------------- */
|
||||
/* values which are derived from setting the options above */
|
||||
/* the user never directly modifies these */
|
||||
|
||||
SANE_Int sleep_time;
|
||||
/* this is defined in sane spec as a struct containing:
|
||||
SANE_Frame format;
|
||||
SANE_Bool last_frame;
|
||||
SANE_Int lines;
|
||||
SANE_Int depth; ( binary=1, gray=8, color=8 (!24) )
|
||||
SANE_Int pixels_per_line;
|
||||
SANE_Int bytes_per_line;
|
||||
*/
|
||||
SANE_Parameters params;
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/* values which are set by scanning functions to keep track of pages, etc */
|
||||
int started;
|
||||
int img_count; /* how many 'sides' delivered */
|
||||
|
||||
/* how far we have read */
|
||||
int bytes_rx[2];
|
||||
int eof_rx[2];
|
||||
|
||||
/* how far we have written */
|
||||
int bytes_tx[2];
|
||||
int eof_tx[2];
|
||||
|
||||
int duplex_fd;
|
||||
unsigned char *duplex_buffer;
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/* values which used by the command and data sending functions (scsi/usb)*/
|
||||
int fd; /* The scanner device file descriptor. */
|
||||
unsigned char *buffer;
|
||||
unsigned char rs_buffer[RS_return_size];
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/* values which are used by the get hardware status command */
|
||||
time_t last_ghs;
|
||||
|
||||
int hw_top;
|
||||
int hw_A3;
|
||||
int hw_B4;
|
||||
int hw_A4;
|
||||
int hw_B5;
|
||||
|
||||
int hw_hopper;
|
||||
int hw_omr;
|
||||
int hw_adf_open;
|
||||
|
||||
int hw_sleep;
|
||||
int hw_send_sw;
|
||||
int hw_manual_feed;
|
||||
int hw_scan_sw;
|
||||
|
||||
int hw_function;
|
||||
|
||||
int hw_ink_empty;
|
||||
int hw_double_feed;
|
||||
|
||||
int hw_error_code;
|
||||
int hw_skew_angle;
|
||||
int hw_ink_remain;
|
||||
|
||||
int hw_duplex_sw;
|
||||
int hw_density_sw;
|
||||
};
|
||||
|
||||
/** scan only front page */
|
||||
#define DUPLEX_FRONT 1
|
||||
/** scan only reverse page */
|
||||
#define DUPLEX_BACK 2
|
||||
/** scan both sides and return them in two different image acquisition operations */
|
||||
#define DUPLEX_BOTH 3
|
||||
#define CONNECTION_SCSI 0 /* SCSI interface */
|
||||
#define CONNECTION_USB 1 /* USB interface */
|
||||
|
||||
#define MODEL_FORCE 0
|
||||
/** Fujitsu M3091DCd (300x600dpi, color, duplex, ADF-only) */
|
||||
#define MODEL_3091 1
|
||||
/** Fujitsu M3096 (400x400dpi grayscale, simplex, FB and optional ADF) */
|
||||
#define MODEL_3096 2
|
||||
/** 3093 */
|
||||
#define MODEL_3093 4
|
||||
/** 4097 */
|
||||
#define MODEL_4097 5
|
||||
/** fi-???? */
|
||||
#define MODEL_FI 6
|
||||
#define MODEL_3097 7
|
||||
/** Fujitsu M3092DCd (300x600dpi, color, duplex, FB and ADF) */
|
||||
#define MODEL_3092 8
|
||||
/** ScanPartner fi-4120 and ScanParter fi-4220 scsi/usb */
|
||||
#define MODEL_FI4x20 9
|
||||
#define SIDE_FRONT 0
|
||||
#define SIDE_BACK 1
|
||||
|
||||
/* A note regarding the MODEL... constants. There's a place in
|
||||
* identifyScanner() where the INQUIRY data is parsed and the model
|
||||
* set accordingly. Now while there is, for example, only one 3091
|
||||
* model (called M3091DCd), there may be different sub-models (e.g.
|
||||
* the 1000abc and the 1000xyz).
|
||||
*
|
||||
* It is suggested that a new MODEL... type be introduced for these if
|
||||
* there are significant differences in capability that have to be
|
||||
* treated differently in the backend. For example, if the "abc" model
|
||||
* has an optional ADF and the "xyz" model has the ADF built-in, we
|
||||
* don't need to distinguish these models, and it's sufficient to set
|
||||
* the "has_adf" variable accordingly.
|
||||
*
|
||||
* The same would apply if two sub-models behave in the same way but
|
||||
* one of them is faster, or has some exotic extra capability that we
|
||||
* don't support anyway.
|
||||
*
|
||||
* If, on the other hand, one model supports a different resolution,
|
||||
* page size, different scan parameters and modes, and such, then it's
|
||||
* probably necessary to create a new MODEL... constant.
|
||||
*
|
||||
* It may also be feasible to introduce a "subModel" member in the
|
||||
* structure above for those cases where subtle, but important,
|
||||
* differences exist - e.g. one model is 100% the same as another but
|
||||
* supports twice the resolution.
|
||||
*/
|
||||
#define SOURCE_FLATBED 0
|
||||
#define SOURCE_ADF_FRONT 1
|
||||
#define SOURCE_ADF_BACK 2
|
||||
#define SOURCE_ADF_DUPLEX 3
|
||||
|
||||
/** Black-and-White (Line Art) - depth always 1 */
|
||||
#define MODE_LINEART 1
|
||||
/** Black-and-White (Halftone) - depth always 1 */
|
||||
#define MODE_HALFTONE 2
|
||||
/** Grayscale */
|
||||
#define MODE_GRAYSCALE 3
|
||||
/** RGB Color */
|
||||
#define MODE_COLOR 4
|
||||
/** Binary RGB Color*/
|
||||
#define MODE_BIN_COLOR 5
|
||||
/** half-tones RGB Color*/
|
||||
#define MODE_HALFTONE_COLOR 6
|
||||
/* these are same as scsi data to make code easier */
|
||||
#define MODE_LINEART WD_comp_LA
|
||||
#define MODE_HALFTONE WD_comp_HT
|
||||
#define MODE_GRAYSCALE WD_comp_GS
|
||||
#define MODE_COLOR_LINEART WD_comp_CL
|
||||
#define MODE_COLOR_HALFTONE WD_comp_CH
|
||||
#define MODE_COLOR WD_comp_CG
|
||||
|
||||
/* these are same as scsi data to make code easier */
|
||||
#define COLOR_DEFAULT MSEL_dropout_DEFAULT
|
||||
#define COLOR_RED MSEL_dropout_RED
|
||||
#define COLOR_GREEN MSEL_dropout_GREEN
|
||||
#define COLOR_BLUE MSEL_dropout_BLUE
|
||||
|
||||
#define COLOR_INTERLACE_NONE 0
|
||||
#define COLOR_INTERLACE_3091 1
|
||||
#define COLOR_INTERLACE_BGR 2
|
||||
#define COLOR_INTERLACE_RRGGBB 3
|
||||
|
||||
#define DUPLEX_INTERLACE_NONE 0
|
||||
#define DUPLEX_INTERLACE_3091 1
|
||||
|
||||
#define GHS_TIME 1 /* seconds passed before calling GHS */
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#define MM_PER_INCH 25.4
|
||||
#define length_quant SANE_UNFIX(SANE_FIX(MM_PER_INCH / 1200.0))
|
||||
#define mmToIlu(mm) ((mm) / length_quant)
|
||||
#define iluToMm(ilu) ((ilu) * length_quant)
|
||||
#define MM_PER_UNIT_UNFIX SANE_UNFIX(SANE_FIX(MM_PER_INCH / 1200.0))
|
||||
#define MM_PER_UNIT_FIX SANE_FIX(SANE_UNFIX(SANE_FIX(MM_PER_INCH / 1200.0)))
|
||||
|
||||
#define SCANNER_UNIT_TO_FIXED_MM(number) SANE_FIX(number * MM_PER_UNIT_UNFIX)
|
||||
#define FIXED_MM_TO_SCANNER_UNIT(number) SANE_UNFIX(number) / MM_PER_UNIT_UNFIX
|
||||
|
||||
#define FUJITSU_CONFIG_FILE "fujitsu.conf"
|
||||
#define READ_MODE_PASS 1
|
||||
#define READ_MODE_RRGGBB 2
|
||||
#define READ_MODE_3091RGB 3
|
||||
#define READ_MODE_BGR 4
|
||||
|
||||
|
||||
#define FIXED_MM_TO_SCANNER_UNIT(number) SANE_UNFIX(number) * 1200 / MM_PER_INCH
|
||||
#define SCANNER_UNIT_TO_FIXED_MM(number) SANE_FIX(number * MM_PER_INCH / 1200)
|
||||
|
||||
#ifndef PATH_MAX
|
||||
# define PATH_MAX 1024
|
||||
|
@ -441,7 +414,6 @@ struct fujitsu
|
|||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
SANE_Status sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize);
|
||||
|
||||
SANE_Status sane_get_devices (const SANE_Device *** device_list,
|
||||
|
@ -453,7 +425,7 @@ SANE_Status sane_set_io_mode (SANE_Handle h, SANE_Bool non_blocking);
|
|||
|
||||
SANE_Status sane_get_select_fd (SANE_Handle h, SANE_Int * fdp);
|
||||
|
||||
const SANE_Option_Descriptor *sane_get_option_descriptor (SANE_Handle handle,
|
||||
const SANE_Option_Descriptor * sane_get_option_descriptor (SANE_Handle handle,
|
||||
SANE_Int option);
|
||||
|
||||
SANE_Status sane_control_option (SANE_Handle handle, SANE_Int option,
|
||||
|
@ -476,36 +448,42 @@ void sane_exit (void);
|
|||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static void do_inquiry (struct fujitsu *s);
|
||||
static SANE_Status find_scanners (void);
|
||||
|
||||
static SANE_Status attachScanner (const char *devicename,
|
||||
struct fujitsu **devp);
|
||||
static SANE_Status attach_one_scsi (const char *name);
|
||||
static SANE_Status attach_one_usb (const char *name);
|
||||
static SANE_Status attach_one (const char *devicename, int connType);
|
||||
|
||||
static SANE_Status scsi_sense_handler (int scsi_fd, u_char * result, void *arg);
|
||||
static SANE_Status connect_fd (struct fujitsu *s);
|
||||
static SANE_Status disconnect_fd (struct fujitsu *s);
|
||||
|
||||
static int identify_scanner (struct fujitsu *s);
|
||||
|
||||
static int
|
||||
do_cmd (Fujitsu_Connection_Type connection, int fd, unsigned char *cmd,
|
||||
int cmd_len, unsigned char *out, size_t req_out_len,
|
||||
size_t *res_out_len);
|
||||
|
||||
static int do_scsi_cmd (int fd, unsigned char *cmd, int cmd_len,
|
||||
unsigned char *out, size_t req_out_len,
|
||||
size_t *res_out_len);
|
||||
|
||||
static int
|
||||
do_usb_cmd (int fd, unsigned char *cmd,
|
||||
int cmd_len, unsigned char *out, size_t req_out_len,
|
||||
size_t *res_out_len);
|
||||
|
||||
static void hexdump (int level, char *comment, unsigned char *p, int l);
|
||||
static SANE_Status sense_handler (int scsi_fd, u_char * result, void *arg);
|
||||
|
||||
static SANE_Status init_inquire (struct fujitsu *s);
|
||||
static SANE_Status init_vpd (struct fujitsu *s);
|
||||
static SANE_Status init_model (struct fujitsu *s);
|
||||
static SANE_Status init_options (struct fujitsu *scanner);
|
||||
|
||||
static int grab_scanner (struct fujitsu *s);
|
||||
static SANE_Status
|
||||
do_cmd(struct fujitsu *s, int busyRetry, int busySleep, int runRS,
|
||||
unsigned char * cmdBuff, int cmdLen, int cmdTime,
|
||||
unsigned char * outBuff, int outLen, int outTime,
|
||||
unsigned char * inBuff, int inLen, int inTime
|
||||
);
|
||||
|
||||
static int free_scanner (struct fujitsu *s);
|
||||
static SANE_Status
|
||||
do_scsi_cmd(struct fujitsu *s, int busyRetry, int busySleep, int runRS,
|
||||
unsigned char * cmdBuff, int cmdLen, int cmdTime,
|
||||
unsigned char * outBuff, int outLen, int outTime,
|
||||
unsigned char * inBuff, int inLen, int inTime
|
||||
);
|
||||
|
||||
static SANE_Status
|
||||
do_usb_cmd(struct fujitsu *s, int busyRetry, int busySleep, int runRS,
|
||||
unsigned char * cmdBuff, int cmdLen, int cmdTime,
|
||||
unsigned char * outBuff, int outLen, int outTime,
|
||||
unsigned char * inBuff, int inLen, int inTime
|
||||
);
|
||||
|
||||
static int wait_scanner (struct fujitsu *s);
|
||||
|
||||
|
@ -513,71 +491,36 @@ static int object_position (struct fujitsu *s, int i_load);
|
|||
|
||||
static SANE_Status do_cancel (struct fujitsu *scanner);
|
||||
|
||||
static SANE_Status do_reset (struct fujitsu *scanner);
|
||||
static SANE_Status scanner_control (struct fujitsu *s, int function);
|
||||
|
||||
/*static int objectDischarge (struct fujitsu *s);*/
|
||||
static SANE_Status mode_select_dropout(struct fujitsu *s);
|
||||
|
||||
static int fujitsu_set_sleep_mode(struct fujitsu *s);
|
||||
static SANE_Status set_sleep_mode(struct fujitsu *s);
|
||||
|
||||
static int set_mode_params (struct fujitsu *s);
|
||||
int get_current_side (struct fujitsu *s);
|
||||
|
||||
static int imprinter(struct fujitsu *s);
|
||||
|
||||
static int fujitsu_send(struct fujitsu *s);
|
||||
|
||||
static int setWindowParam (struct fujitsu *s);
|
||||
|
||||
static size_t maxStringSize (const SANE_String_Const strings[]);
|
||||
static int set_window (struct fujitsu *s);
|
||||
|
||||
static int start_scan (struct fujitsu *s);
|
||||
|
||||
static int reader_process (void *scanner);
|
||||
static SANE_Status read_from_scanner(struct fujitsu *s, SANE_Byte * buf, SANE_Int max_len, SANE_Int * len, int side);
|
||||
|
||||
static unsigned int reader3091ColorDuplex (struct fujitsu *scanner, FILE * fd,
|
||||
FILE * fd2);
|
||||
static unsigned int reader3091ColorSimplex (struct fujitsu *scanner,
|
||||
FILE * fd);
|
||||
static unsigned int reader3091GrayDuplex (struct fujitsu *scanner, FILE * fd,
|
||||
FILE * fd2);
|
||||
static void convert_bgr_to_rgb(struct fujitsu *scanner, unsigned char * buffptr, unsigned int length);
|
||||
static SANE_Status read_from_buffer(struct fujitsu *s, SANE_Byte * buf, SANE_Int max_len, SANE_Int * len, int side);
|
||||
|
||||
static void convert_rrggbb_to_rgb(struct fujitsu *scanner, unsigned char * buffptr, unsigned int length);
|
||||
static SANE_Status convert_bgr_to_rgb(struct fujitsu *s, unsigned char * buffptr, unsigned int length);
|
||||
|
||||
static unsigned int reader_gray_duplex_sequential (struct fujitsu *scanner,
|
||||
FILE * fd, FILE * fd2);
|
||||
static unsigned int reader_gray_duplex_alternate (struct fujitsu *scanner,
|
||||
FILE * fd, FILE * fd2);
|
||||
static SANE_Status convert_rrggbb_to_rgb(struct fujitsu *s, unsigned char * buffptr, unsigned int length);
|
||||
|
||||
static unsigned int reader_duplex_sequential (struct fujitsu *scanner,
|
||||
FILE * fd, FILE * fd2);
|
||||
static unsigned int reader_duplex_alternate (struct fujitsu *scanner,
|
||||
FILE * fd, FILE * fd2);
|
||||
static unsigned int reader_simplex (struct fujitsu *scanner, FILE * fd,
|
||||
int i_window_id);
|
||||
|
||||
static unsigned int reader_generic_passthrough (struct fujitsu *scanner,
|
||||
FILE * fd, int i_window_id);
|
||||
|
||||
static int read_large_data_block (struct fujitsu *s,
|
||||
unsigned char *buffer, unsigned int length,
|
||||
int i_window_id,
|
||||
unsigned int *i_data_read);
|
||||
|
||||
static SANE_Status attachOne (const char *name);
|
||||
|
||||
static int modelMatch (const char *product);
|
||||
|
||||
static void setDefaults3091 (struct fujitsu *scanner);
|
||||
static void setDefaults3096 (struct fujitsu *scanner);
|
||||
|
||||
static SANE_Status setMode3091 (struct fujitsu *scanner, int mode);
|
||||
static SANE_Status setMode3096 (struct fujitsu *scanner, int mode);
|
||||
static SANE_Status convert_3091rgb_to_rgb(struct fujitsu *s, unsigned char * buff, unsigned int length);
|
||||
|
||||
static void calculateDerivedValues (struct fujitsu *scanner);
|
||||
|
||||
static int makeTempFile (void);
|
||||
static SANE_Status get_hardware_status (struct fujitsu *s);
|
||||
static void fujitsu_set_standard_size (SANE_Handle handle);
|
||||
static SANE_Status setup_duplex_buffer (struct fujitsu *s);
|
||||
|
||||
static SANE_Status get_hardware_status (struct fujitsu *s);
|
||||
|
||||
static void hexdump (int level, char *comment, unsigned char *p, int l);
|
||||
|
||||
static size_t maxStringSize (const SANE_String_Const strings[]);
|
||||
|
||||
#endif /* FUJITSU_H */
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
.TH sane-fujitsu 5 "17 Apr 2002" "@PACKAGEVERSION@" "SANE Scanner Access Now Easy"
|
||||
.TH sane-fujitsu 5 "2006-05-12" "@PACKAGEVERSION@" "SANE Scanner Access Now Easy"
|
||||
.IX sane-fujitsu
|
||||
.IX sane-fcpa
|
||||
.IX sane-m3096g
|
||||
|
||||
.SH NAME
|
||||
sane-fujitsu \- SANE backend for Fujitsu flatbed and ADF scanners
|
||||
|
@ -10,173 +8,261 @@ sane-fujitsu \- SANE backend for Fujitsu flatbed and ADF scanners
|
|||
The
|
||||
.B sane-fujitsu
|
||||
library implements a SANE (Scanner Access Now Easy) backend which
|
||||
provides access to Fujitsu flatbed and ADF scanners.
|
||||
At present, the following
|
||||
scanners are known to work with this backend:
|
||||
provides access to most Fujitsu flatbed and ADF scanners.
|
||||
|
||||
This document describes the rewritten backend versions 1.0.21 and greater.
|
||||
|
||||
The backend supports lineart, halftone, grayscale, and color
|
||||
scanning for most scanners, depending on hardware capabilities.
|
||||
Most simple scanning related features are exposed. This version
|
||||
features better usb support, and less model-specific code.
|
||||
This enables at least basic support for many more models.
|
||||
See LIMITATIONS.
|
||||
|
||||
.SH HARDWARE SUPPORT
|
||||
The following scanners are thought to have at least basic scanning
|
||||
capability, either because they have been tested with a prior
|
||||
version, or because documentation indicates they are compatible
|
||||
with a tested model.
|
||||
.PP
|
||||
.RS
|
||||
.ft CR
|
||||
.nf
|
||||
Vendor: Model: Rev:
|
||||
-------- ---------------- -----
|
||||
FUJITSU M3096Gm 02
|
||||
FUJITSU M3093GX
|
||||
FUJITSU M3093GD
|
||||
FUJITSU M4097
|
||||
FUJITSU fi-4220C
|
||||
FUJITSU fi-4340C
|
||||
FUJITSU M3091DCd BF21
|
||||
FUJITSU M3092DCd
|
||||
WORKGROUP SIZED SCANNERS:
|
||||
--------------------------------------
|
||||
SCSI: SCSI/USB: USB:
|
||||
------------ ------------ ------------
|
||||
M3091DC fi-4120C fi-5110C
|
||||
M3092DC fi-4220C fi-5110EOX
|
||||
SP-93GX fi-4120C2
|
||||
fi-4220C2
|
||||
fi-5120C
|
||||
fi-5220C
|
||||
.fi
|
||||
.ft R
|
||||
.RE
|
||||
.P
|
||||
The driver supports lineart, halftone, grayscale, and color
|
||||
(3091 and 3092) scanning depending on hardware capabilities.
|
||||
.PP
|
||||
.RS
|
||||
.ft CR
|
||||
.nf
|
||||
DEPARTMENTAL SIZED SCANNERS:
|
||||
--------------------------------------
|
||||
SCSI: SCSI/USB:
|
||||
------------ ------------
|
||||
M3093GX/DG fi-4340C
|
||||
M3096G/GX fi-4530C
|
||||
M3097G+/DG fi-5530C
|
||||
fi-4640S
|
||||
fi-4750C
|
||||
.fi
|
||||
.ft R
|
||||
.RE
|
||||
.P
|
||||
.PP
|
||||
.RS
|
||||
.ft CR
|
||||
.nf
|
||||
PRODUCTION SIZED SCANNERS:
|
||||
--------------------------------------
|
||||
SCSI: SCSI/USB:
|
||||
------------ ------------
|
||||
M3099G/GH/GX fi-5650C
|
||||
M4097D fi-5750C
|
||||
fi-4750L fi-5900C
|
||||
fi-4860C
|
||||
M4099D
|
||||
.fi
|
||||
.ft R
|
||||
.RE
|
||||
.P
|
||||
The following scanners are known NOT to work with this backend,
|
||||
either because they have a non-fujitsu chipset, or an unsupported
|
||||
interface type. Some of these scanners may be supported by another
|
||||
backend.
|
||||
.PP
|
||||
.RS
|
||||
.ft CR
|
||||
.nf
|
||||
UNSUPPORTED SCANNERS:
|
||||
SCSI: SERIAL: USB:
|
||||
------------ ------------ ------------
|
||||
ScanStation M3093E/DE/EX fi-4110EOX2
|
||||
ScanPartner M3096EX
|
||||
SP-Jr M3097E+/DE
|
||||
SP-10/10C M3099A/EH/EX
|
||||
SP-15C/300C
|
||||
SP-600C/620C
|
||||
.fi
|
||||
.ft R
|
||||
.RE
|
||||
.P
|
||||
This backend may support scanners not listed here. The best
|
||||
way to determine level of support is to test the scanner directly.
|
||||
Fujitsu equipment has historically been good enough to not be
|
||||
damaged by incorrect commands if the scanner is incompatible.
|
||||
Please contact the author with test results, positive or negative.
|
||||
|
||||
The "Fujitsu" driver is a first attempt at integrating support
|
||||
for all Fujitsu scanners \- previously available as different
|
||||
single drivers \- in one driver. At present, the M3091DCd
|
||||
is working (lineart, halftone, 8-bit grayscale and 24-bit color,
|
||||
simplex and duplex), and the driver should also support the
|
||||
M3096 as the M3096g driver code has been incorporated.
|
||||
This driver supersedes the old "m3091"/"fujitsu" drivers and
|
||||
the old "m3096g" driver.
|
||||
|
||||
Other scanners in these families may work.
|
||||
The ScanPartner 15C seems to be a repackaging
|
||||
of the ScanPartner 600C, but I don't know if it works.
|
||||
Look at the sp15c backend for this scanner.
|
||||
Perusal of the M3096GX/M3093GX/M3093DG manual
|
||||
suggests the M3096G driver offers access to a
|
||||
subset of the new scanners.
|
||||
People are encouraged to try these driver with the other scanners
|
||||
and to contact the author with test results.
|
||||
|
||||
.SH DUPLEX MODE
|
||||
The M3091 driver supports duplex scanning. To the front-end, a duplex
|
||||
scan looks very much like scanning two separate pages from the document
|
||||
feeder, i.e. the SANE front-end receives two images instead of one.
|
||||
Front-ends which are not capable of dealing with that \- e.g. the
|
||||
command-line tool scanimage \- cannot be used for duplex scanning.
|
||||
If you want to do duplex scans from the command line, get Tom
|
||||
Martone's scanadf program from
|
||||
http://www.martoneconsulting.com/sane-scanadf.html.
|
||||
|
||||
.SH CONFIGURATION
|
||||
.SH OPTIONS
|
||||
A modest effort has been made to expose the standard options to the API.
|
||||
This allows frontends such as xscanimage to set scanning region,
|
||||
resolution, bit-depth (and color), and enable the automatic document feeder.
|
||||
.br
|
||||
The "Fujitsu" driver supports the following options:
|
||||
.br
|
||||
This allows a frontend to set scanning region, resolution, bit-depth,
|
||||
color mode, and enable the automatic document feeder. The fujitsu backend
|
||||
supports the following basic options for most scanners:
|
||||
.PP
|
||||
source s
|
||||
.RS
|
||||
Selects the source for the scan. Options
|
||||
may include "Flatbed", "ADF Front", "ADF Back", "ADF Duplex".
|
||||
.RE
|
||||
.PP
|
||||
mode m
|
||||
.RS
|
||||
.I m
|
||||
may be one of "Color", "Lineart", "Halftone", or "Gray", dependent on the
|
||||
scanner model. It is advisable to specify this option first when using
|
||||
command line tools, as the validity of some of the other options depends
|
||||
on the mode setting.
|
||||
.RE
|
||||
.PP
|
||||
x, y
|
||||
.RS
|
||||
Scan width and height
|
||||
.RE
|
||||
.PP
|
||||
pagewidth, pageheight
|
||||
.RS
|
||||
Page size; when using the ADF, the driver will assume that a page of the
|
||||
given width is centered
|
||||
Selects the mode for the scan. Options
|
||||
may include "Lineart", "Halftone", "Gray", and "Color".
|
||||
.RE
|
||||
.PP
|
||||
resolution, y-resolution
|
||||
.RS
|
||||
Controls scan resolution. Permissible values dependent on model and scan mode;
|
||||
setting --resolution also sets --y-resolution but not vice versa. This makes
|
||||
it possible to set the 3091's maximum resolution of 300x600dpi.
|
||||
Controls scan resolution. Setting --resolution also sets --y-resolution
|
||||
but not vice versa. This behavior is overridden by some frontends.
|
||||
.RE
|
||||
.PP
|
||||
brightness b
|
||||
tlx, tly, brx, bry
|
||||
.RS
|
||||
Only supported for M3096
|
||||
Sets scan area upper left and lower right coordinates. Often converted
|
||||
to t, l, x, y by frontend code.
|
||||
.RE
|
||||
.PP
|
||||
threshold t
|
||||
pagewidth, pageheight
|
||||
.RS
|
||||
Only supported for M3096
|
||||
Sets paper size. Used by scanner to determine centering of scan
|
||||
coordinates when using ADF.
|
||||
.RE
|
||||
.PP
|
||||
duplex d
|
||||
Other options will be available based on the capabilities of the scanner.
|
||||
Use 'scanimage --help' to get a list. Be aware that some options may
|
||||
appear only when another option has been set.
|
||||
.PP
|
||||
.SH CONFIGURATION FILE
|
||||
The configuration file "fujitsu.conf" is used to tell the backend how to look for
|
||||
scanners, and provide options controlling the operation of the backend.
|
||||
This file is read each time the frontend asks the backend for a list
|
||||
of scanners, generally only when the frontend starts. If the configuration
|
||||
file is missing, the backend will use a set of compiled defaults, which
|
||||
are identical to the default configuration file shipped with SANE.
|
||||
.PP
|
||||
Scanners can be specified in the configuration file in 4 ways:
|
||||
.PP
|
||||
"scsi FUJITSU"
|
||||
.RS
|
||||
.I d
|
||||
may be "front", "back", or "both" and denotes which sides of the page
|
||||
are to be scanned (duplex scanner only for example 3091, 3093Gd).
|
||||
Requests backend to search all scsi busses in the system for a device
|
||||
which reports itself to be a scanner made by 'FUJITSU'.
|
||||
.RE
|
||||
.PP
|
||||
lampcolor c
|
||||
"scsi /dev/sg0" (or other scsi device file)
|
||||
.RS
|
||||
.I c
|
||||
may be "red", "green", "blue", or "default" \- the lamp color to be used
|
||||
when doing graysacale or b/w scans on the M3091.
|
||||
Requests backend to open the named scsi device. Only useful if you have
|
||||
multiple compatible scanners connected to your system, and need to
|
||||
specify one. Probably should not be used with the other "scsi" line above.
|
||||
.RE
|
||||
.PP
|
||||
blueoffset, greenoffset
|
||||
"usb 0x04c5 0x1042" (or other vendor/product ids)
|
||||
.RS
|
||||
Color justification options for the M3091; anything other than +1/-1 will
|
||||
probably distort the image. Should be left alone unless your scanner is
|
||||
buggy.
|
||||
Requests backend to search all usb busses in the system for a device
|
||||
which uses that vendor and product id. The device will then be queried
|
||||
to determine if it is a Fujitsu scanner.
|
||||
.RE
|
||||
.PP
|
||||
swapfile
|
||||
"usb /dev/usb/scanner0" (or other device file)
|
||||
.RS
|
||||
boolean option for the M3091. Only affects duplex scans. If set, a swap
|
||||
file will be used for storing the rear side of a document as it is scanned;
|
||||
otherwise the whole page will be kept in memory.
|
||||
Some systems use a kernel driver to access usb scanners. This method is untested.
|
||||
.RE
|
||||
|
||||
.br
|
||||
|
||||
You may specify the line "forceModel=xxx"
|
||||
in the configuration file to make the driver treat your scanner as an
|
||||
"xxx" scanner (currently supported: 3096, 3091). Use this if you have
|
||||
another scanner that is not automatically detected as being compatible.
|
||||
|
||||
.br
|
||||
|
||||
The only other configuration option supported is "scsi-buf-size=xxx",
|
||||
.PP
|
||||
The only configuration option supported is "scsi-buf-size=xxx",
|
||||
allowing you to set the SCSI buffer size to something other than the
|
||||
compiled-in default. Especially with the M3091 scanner, some users
|
||||
had the problem that the scanner would "hang" mid-page, and this can
|
||||
often be alleviated by using "scsi-buf-size=32768".
|
||||
compiled-in default. Some users report that the scanner would "hang"
|
||||
mid-page, and this can often be alleviated by increasing scsi-buf-size.
|
||||
.PP
|
||||
Note: This option may appear multiple times in the configuration file. It only
|
||||
applies to scanners discovered by "scanner" lines that follow this option, and will be updated to the new value each time it occurs.
|
||||
.PP
|
||||
Note: The backend does not place an upper bound on this value, as some users
|
||||
required it to be quite large. Values above 32768 are not recommended,
|
||||
and may crash your OS or lockup your scsi card driver. You have been
|
||||
warned.
|
||||
|
||||
.SH ENVIRONMENT
|
||||
The backend uses a single environment variable, SANE_DEBUG_FUJITSU, which
|
||||
enables debugging output to stderr. Valid values are:
|
||||
.PP
|
||||
.RS
|
||||
5 Errors
|
||||
.br
|
||||
10 Function trace
|
||||
.br
|
||||
15 Function detail
|
||||
.br
|
||||
20 Option commands
|
||||
.br
|
||||
30 Scsi/Usb packets
|
||||
.RE
|
||||
|
||||
.SH OLDER VERSIONS
|
||||
Backend versions prior to this were numbered with a two part version,
|
||||
or with no version number at all. At the time this version was written,
|
||||
all older versions were retroactively renumbered, 1.0.2 - 1.0.20.
|
||||
.PP
|
||||
The current backend may have lost support for some important feature
|
||||
you were using. The last of the "old" backends, 1.0.20, is still available
|
||||
as source from:
|
||||
.PP
|
||||
http://www2.pfeiffer.edu/~anoah/fujitsu/
|
||||
.PP
|
||||
If you find that you need to use the older version, please contact the
|
||||
author, to try and get those features restored to a later version.
|
||||
|
||||
.SH KNOWN ISSUES
|
||||
.PP
|
||||
.RS
|
||||
3091/3092 color and duplex modes are broken.
|
||||
.br
|
||||
All IPC and compression options are disabled.
|
||||
.br
|
||||
Most scanner specific 'quirks' are not accounted for, making it possible
|
||||
to set some options in ways that the scanner does not support.
|
||||
.br
|
||||
Some flatbed options are affected by adf settings.
|
||||
.br
|
||||
Speed is too low, especially at higher resolutions, due to single-threading.
|
||||
.RE
|
||||
|
||||
.SH HISTORY
|
||||
m3091 backend: Frederik Ramm <frederik a t remote d o t org>
|
||||
.br
|
||||
m3096g backend: Randolph Bentson <bentson a t holmsjoen d o t com>
|
||||
.br
|
||||
(with credit to the unnamed author of the coolscan driver)
|
||||
.br
|
||||
merged fujitsu backend: Frederik?
|
||||
.br
|
||||
3092: Mario Goppold <mgoppold a t tbzpariv d o t tcc-chemnitz d o t de>
|
||||
.br
|
||||
3093,fi-4340C,ipc,cmp support, and long-time backend maintainer:
|
||||
.br
|
||||
Oliver Schirrmeister <oschirr a t abm d o t de>
|
||||
.br
|
||||
fi-4220C and basic USB support: Ron Cemer <ron a t roncemer d o t com>
|
||||
.br
|
||||
fi-4120, fi-series color support, backend re-write, current maintainer:
|
||||
M. Allan Noah: <anoah a t pfeiffer d o t edu>
|
||||
|
||||
.SH "SEE ALSO"
|
||||
sane(7),
|
||||
sane-scsi(5),
|
||||
sane-sp15c(5)
|
||||
sane-usb(5),
|
||||
.br
|
||||
Fujitsu ScanPartner 15C OEM Manual, Doc. No. 250-0081-0
|
||||
.br
|
||||
Fujitsu M3096G OEM Manual, part number 50FH5028E-05
|
||||
.br
|
||||
Fujitsu M3096GX/M3093GX/M3093DG OEM Manual, part number C150-E015...03
|
||||
sane-sp15c(5),
|
||||
sane-avision(5)
|
||||
|
||||
.SH AUTHOR
|
||||
3096/SP15 drivers: Randolph Bentson
|
||||
<bentson@holmsjoen.com>,
|
||||
with credit to the unnamed author of the coolscan driver
|
||||
.br
|
||||
3091 driver: Frederik Ramm <frederik@remote.org>
|
||||
3093GD,fi-4340C, ipc and cmp options: Oliver Schirrmeister <oschirr@abm.de>
|
||||
3092 patch: Mario Goppold <mgoppold@tbzpariv.tcc-chemnitz.de>
|
||||
fi-4220C patch and USB support: Ronald B. Cemer <ron@roncemer.com>
|
||||
.SH LIMITATIONS
|
||||
Only tested with Linux 2.4
|
||||
M. Allan Noah: <anoah a t pfeiffer d o t edu>
|
||||
|
||||
.SH BUGS
|
||||
I'm sure there are plenty, and not too well hidden,
|
||||
but I haven't seen them yet.
|
||||
I don't know if the ScanPartner 15C still works, because I'm not able
|
||||
to test it.
|
||||
3091/3092 don't support halftone
|
||||
|
|
Ładowanie…
Reference in New Issue