kopia lustrzana https://gitlab.com/sane-project/backends
Added new fujitsu backend (from Oliver Schirrmeister <oschirr@abm.de>). This
backend supersedes the m3096g backend and also includes the m3091 backend. Henning Meier-Geinitz <henning@meier-geinitz.de>DEVEL_2_0_BRANCH-1
rodzic
7e13df9195
commit
1982eec1dd
|
@ -0,0 +1,834 @@
|
|||
#ifndef FUJITSU_SCSI_H
|
||||
#define FUJITSU_SCSI_H
|
||||
|
||||
/*
|
||||
* Part of SANE - Scanner Access Now Easy.
|
||||
*
|
||||
* Please see to opening comments in fujitsu.c
|
||||
*/
|
||||
|
||||
/****************************************************/
|
||||
|
||||
/*static inline void */
|
||||
static void
|
||||
setbitfield (unsigned char *pageaddr, int mask, int shift, int val)
|
||||
{
|
||||
*pageaddr = (*pageaddr & ~(mask << shift)) | ((val & mask) << shift);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/*static inline void */
|
||||
/*static void
|
||||
resetbitfield (unsigned char *pageaddr, int mask, int shift, int val) \
|
||||
{
|
||||
*pageaddr = (*pageaddr & ~(mask << shift)) | (((!val) & mask) << shift);
|
||||
}
|
||||
*/
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/*static inline int */
|
||||
static int
|
||||
getbitfield (unsigned char *pageaddr, int mask, int shift)
|
||||
{
|
||||
return ((*pageaddr >> shift) & mask);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static int
|
||||
getnbyte (unsigned char *pnt, int nbytes)
|
||||
{
|
||||
unsigned int result = 0;
|
||||
int i;
|
||||
|
||||
#ifdef DEBUG
|
||||
assert (nbytes < 5);
|
||||
#endif
|
||||
for (i = 0; i < nbytes; i++)
|
||||
result = (result << 8) | (pnt[i] & 0xff);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/*static inline void */
|
||||
static void
|
||||
putnbyte (unsigned char *pnt, unsigned int value, unsigned int nbytes)
|
||||
{
|
||||
int i;
|
||||
|
||||
#ifdef DEBUG
|
||||
assert (nbytes < 5);
|
||||
#endif
|
||||
for (i = nbytes - 1; i >= 0; i--)
|
||||
|
||||
{
|
||||
pnt[i] = value & 0xff;
|
||||
value = value >> 8;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ==================================================================== */
|
||||
/* SCSI commands */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char *cmd;
|
||||
int size;
|
||||
}
|
||||
scsiblk;
|
||||
|
||||
/* ==================================================================== */
|
||||
|
||||
#define RESERVE_UNIT 0x16
|
||||
#define RELEASE_UNIT 0x17
|
||||
#define INQUIRY 0x12
|
||||
#define REQUEST_SENSE 0x03
|
||||
#define SEND_DIAGNOSTIC 0x1d
|
||||
#define TEST_UNIT_READY 0x00
|
||||
#define SET_WINDOW 0x24
|
||||
#define SET_SUBWINDOW 0xc0
|
||||
#define OBJECT_POSITION 0x31
|
||||
#define SEND 0x2a
|
||||
#define READ 0x28
|
||||
#define MODE_SELECT 0x15
|
||||
#define MODE_SENSE 0x1a
|
||||
#define SCAN 0x1b
|
||||
#define HW_STATUS 0xc2
|
||||
|
||||
|
||||
/* ==================================================================== */
|
||||
|
||||
static unsigned char reserve_unitC[] =
|
||||
{ RESERVE_UNIT, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
static scsiblk reserve_unitB = { reserve_unitC, sizeof (reserve_unitC) };
|
||||
|
||||
/* ==================================================================== */
|
||||
|
||||
static unsigned char release_unitC[] =
|
||||
{ RELEASE_UNIT, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
static scsiblk release_unitB = { release_unitC, sizeof (release_unitC) };
|
||||
|
||||
/* ==================================================================== */
|
||||
|
||||
static unsigned char inquiryC[] = { INQUIRY, 0x00, 0x00, 0x00, 0x1f, 0x00 };
|
||||
static scsiblk inquiryB = { inquiryC, sizeof (inquiryC) };
|
||||
|
||||
#define set_IN_evpd(icb, val) setbitfield(icb + 1, 1, 0, val)
|
||||
#define set_IN_page_code(icb, val) icb[0x02]=val
|
||||
#define set_IN_return_size(icb,val) icb[0x04]=val
|
||||
#define set_IN_length(out,n) out[0x04]=n-5
|
||||
|
||||
#define get_IN_periph_qual(in) getbitfield(in, 0x07, 5)
|
||||
#define IN_periph_qual_lun 0x00
|
||||
#define IN_periph_qual_nolun 0x03
|
||||
#define get_IN_periph_devtype(in) getbitfield(in, 0x1f, 0)
|
||||
#define IN_periph_devtype_scanner 0x06
|
||||
#define IN_periph_devtype_unknown 0x1f
|
||||
#define get_IN_response_format(in) getbitfield(in + 0x03, 0x07, 0)
|
||||
#define IN_recognized 0x02
|
||||
#define get_IN_additional_length(in) in[0x04]
|
||||
#define get_IN_vendor(in, buf) strncpy(buf, in + 0x08, 0x08)
|
||||
#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 */
|
||||
|
||||
#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)
|
||||
#define get_IN_step_x_res(in) getbitfield(in+0x09, 1, 0)
|
||||
#define get_IN_step_y_res(in) getbitfield(in+0x09, 1, 4)
|
||||
#define get_IN_max_x_res(in) getnbyte(in + 0x0a, 2)
|
||||
#define get_IN_max_y_res(in) getnbyte(in + 0x0c, 2)
|
||||
#define get_IN_min_x_res(in) getnbyte(in + 0x0e, 2)
|
||||
#define get_IN_min_y_res(in) getnbyte(in + 0x10, 2)
|
||||
#define get_IN_std_res_200(in) getbitfield(in+ 0x12, 1, 0)
|
||||
#define get_IN_std_res_180(in) getbitfield(in+ 0x12, 1, 1)
|
||||
#define get_IN_std_res_160(in) getbitfield(in+ 0x12, 1, 2)
|
||||
#define get_IN_std_res_150(in) getbitfield(in+ 0x12, 1, 3)
|
||||
#define get_IN_std_res_120(in) getbitfield(in+ 0x12, 1, 4)
|
||||
#define get_IN_std_res_100(in) getbitfield(in+ 0x12, 1, 5)
|
||||
#define get_IN_std_res_75(in) getbitfield(in+ 0x12, 1, 6)
|
||||
#define get_IN_std_res_60(in) getbitfield(in+ 0x12, 1, 7)
|
||||
#define get_IN_std_res_1200(in) getbitfield(in+ 0x13, 1, 0)
|
||||
#define get_IN_std_res_800(in) getbitfield(in+ 0x13, 1, 1)
|
||||
#define get_IN_std_res_600(in) getbitfield(in+ 0x13, 1, 2)
|
||||
#define get_IN_std_res_480(in) getbitfield(in+ 0x13, 1, 3)
|
||||
#define get_IN_std_res_400(in) getbitfield(in+ 0x13, 1, 4)
|
||||
#define get_IN_std_res_320(in) getbitfield(in+ 0x13, 1, 5)
|
||||
#define get_IN_std_res_300(in) getbitfield(in+ 0x13, 1, 6)
|
||||
#define get_IN_std_res_240(in) getbitfield(in+ 0x13, 1, 7)
|
||||
#define get_IN_window_width(in) getnbyte(in + 0x14, 4)
|
||||
#define get_IN_window_length(in) getnbyte(in + 0x18, 4)
|
||||
#define get_IN_overflow(in) getbitfield(in+0x1c, 1, 0)
|
||||
#define get_IN_monochrome(in) getbitfield(in+0x1c, 1, 1)
|
||||
#define get_IN_half_tone(in) getbitfield(in+0x1c, 1, 2)
|
||||
#define get_IN_multilevel(in) getbitfield(in+0x1c, 1, 3)
|
||||
#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)
|
||||
#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_duplex(in) getbitfield(in+0x20, 1, 4)
|
||||
#define get_IN_trancepareny(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_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
|
||||
#define get_IN_ipc_outline_extraction(in) getbitfield(in+0x58, 1, 4)
|
||||
#define get_IN_ipc_image_emphasis(in) getbitfield(in+0x58, 1, 3)
|
||||
#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)
|
||||
#define get_IN_compression_JBIG(in) getbitfield(in+0x5a, 1, 4)
|
||||
#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)
|
||||
|
||||
/* ==================================================================== */
|
||||
|
||||
static unsigned char test_unit_readyC[] =
|
||||
{ TEST_UNIT_READY, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
static scsiblk test_unit_readyB =
|
||||
{ test_unit_readyC, sizeof (test_unit_readyC) };
|
||||
|
||||
/* ==================================================================== */
|
||||
|
||||
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)
|
||||
|
||||
/* ==================================================================== */
|
||||
|
||||
static unsigned char object_positionC[] =
|
||||
{ OBJECT_POSITION, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
/* ADF, _____Count_____, ________Reserved______, Ctl */
|
||||
static scsiblk object_positionB =
|
||||
{ object_positionC, sizeof (object_positionC) };
|
||||
|
||||
#define set_OP_autofeed(b,val) setbitfield(b+0x01, 0x07, 0, val)
|
||||
#define OP_Discharge 0x00
|
||||
#define OP_Feed 0x01
|
||||
|
||||
/* ==================================================================== */
|
||||
|
||||
/*
|
||||
static unsigned char sendC[] =
|
||||
{SEND, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
static scsiblk sendB =
|
||||
{sendC, sizeof (sendC)};
|
||||
*/
|
||||
|
||||
#define set_S_datatype_code(sb, val) sb[0x02] = (unsigned char)val
|
||||
#define S_datatype_imagedatai 0x00
|
||||
#define S_EX_datatype_LUT 0x01 /* Experiment code */
|
||||
#define S_EX_datatype_shading_data 0xa0 /* Experiment code */
|
||||
#define S_user_reg_gamma 0xc0
|
||||
#define S_device_internal_info 0x03
|
||||
#define set_S_datatype_qual_upper(sb, val) sb[0x04] = (unsigned char)val
|
||||
#define S_DQ_none 0x00
|
||||
#define S_DQ_Rcomp 0x06
|
||||
#define S_DQ_Gcomp 0x07
|
||||
#define S_DQ_Bcomp 0x08
|
||||
#define S_DQ_Reg1 0x01
|
||||
#define S_DQ_Reg2 0x02
|
||||
#define S_DQ_Reg3 0x03
|
||||
#define set_S_xfer_length(sb, val) putnbyte(sb + 0x06, val, 3)
|
||||
|
||||
/*
|
||||
static unsigned char gamma_user_LUT_LS1K[512] = { 0x00 };
|
||||
static scsiblk gamma_user_LUT_LS1K_LS1K = {
|
||||
gamma_user_LUT_LS1K, sizeof(gamma_user_LUT_LS1K)
|
||||
};
|
||||
*/
|
||||
|
||||
/* ==================================================================== */
|
||||
|
||||
static unsigned char readC[] =
|
||||
{ READ, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
/* Type, rsvd, type qual, __xfer length__, Ctl */
|
||||
static scsiblk readB = { readC, sizeof (readC) };
|
||||
|
||||
#define set_R_datatype_code(sb, val) sb[0x02] = val
|
||||
#define R_datatype_imagedata 0x00
|
||||
#define R_pixel_size 0x80
|
||||
#define set_R_xfer_length(sb, val) putnbyte(sb + 0x06, val, 3)
|
||||
#define set_R_window_id(sb, val) sb[0x05] = val
|
||||
#define set_R_xfer_length(sb, val) putnbyte(sb + 0x06, val, 3)
|
||||
#define get_PSIZE_num_x(in) getnbyte(in + 0x00, 4)
|
||||
#define get_PSIZE_num_y(in) getnbyte(in + 0x04, 4)
|
||||
|
||||
/* ==================================================================== */
|
||||
|
||||
static unsigned char mode_selectC[] =
|
||||
{ MODE_SELECT, 0x10, 0x00, 0x00, 0x00, 0x00 };
|
||||
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)
|
||||
};
|
||||
|
||||
|
||||
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:
|
||||
* 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
|
||||
* 0x3d = Lamp light timer set
|
||||
* 0x3e = Special-purpose paper detection mode
|
||||
*/
|
||||
#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
|
||||
|
||||
/* 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)
|
||||
|
||||
/* 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)
|
||||
#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
|
||||
/* ==================================================================== */
|
||||
|
||||
/* ==================================================================== */
|
||||
#if 0
|
||||
/* currently not used */
|
||||
static unsigned char mode_senseC[] =
|
||||
{ MODE_SENSE, 0x18, 0x03, 0x00, 0x00, 0x00, /* PF set, page type 03 */ };
|
||||
static scsiblk mode_senseB = { mode_senseC, sizeof (mode_senseC) };
|
||||
|
||||
#define set_MS_DBD(b, val) setbitfield(b, 0x01, 3, (val?1:0))
|
||||
#define set_MS_len(b, val) putnbyte(b+0x04, val, 1)
|
||||
#define get_MS_MUD(b) getnbyte(b+(0x04+((int)*(b+0x3)))+0x4,2)
|
||||
#endif
|
||||
|
||||
/* ==================================================================== */
|
||||
|
||||
static unsigned char scanC[] = { SCAN, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
static scsiblk scanB = { scanC, sizeof (scanC) };
|
||||
|
||||
#define set_SC_xfer_length(sb, val) sb[0x04] = (unsigned char)val
|
||||
|
||||
/* ==================================================================== */
|
||||
|
||||
static unsigned char hw_statusC[] =
|
||||
{ HW_STATUS, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
static scsiblk hw_statusB = { hw_statusC, sizeof (hw_statusC) };
|
||||
|
||||
#define set_HW_allocation_length(sb, len) putnbyte(sb + 0x06, 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)
|
||||
|
||||
|
||||
/* ==================================================================== */
|
||||
|
||||
/* We use the same structure for both SET WINDOW and GET WINDOW. */
|
||||
static unsigned char window_parameter_data_blockC[] = {
|
||||
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) };
|
||||
|
||||
#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[] = {
|
||||
/* 0x00 - Window Identifier
|
||||
* 0x00 for 3096
|
||||
* 0x00 (front) or 0x80 (back) for 3091
|
||||
*/
|
||||
0x00,
|
||||
#define set_WD_wid(sb, val) sb[0] = val
|
||||
#define WD_wid_front 0x00
|
||||
#define WD_wid_back 0x80
|
||||
|
||||
/* 0x01 - Reserved (bits 7-1), AUTO (bit 0)
|
||||
* Use 0x00 for 3091, 3096
|
||||
*/
|
||||
0x00,
|
||||
#define set_WD_auto(sb, val) setbitfield(sb + 0x01, 1, 0, val)
|
||||
#define get_WD_auto(sb) getbitfield(sb + 0x01, 1, 0)
|
||||
|
||||
/* 0x02,0x03 - X resolution in dpi
|
||||
* 3091 supports 50-300 in steps of 1
|
||||
* 3096 suppors 200,240,300,400; or 100-1600 in steps of 4
|
||||
* if image processiong option installed
|
||||
*/
|
||||
0x00, 0x00,
|
||||
#define set_WD_Xres(sb, val) putnbyte(sb + 0x02, val, 2)
|
||||
#define get_WD_Xres(sb) getnbyte(sb + 0x02, 2)
|
||||
|
||||
/* 0x04,0x05 - X resolution in dpi
|
||||
* 3091 supports 50-600 in steps of 1; 75,150,300,600 only
|
||||
* in color mode
|
||||
* 3096 suppors 200,240,300,400; or 100-1600 in steps of 4
|
||||
* if image processiong option installed
|
||||
*/
|
||||
0x00, 0x00,
|
||||
#define set_WD_Yres(sb, val) putnbyte(sb + 0x04, val, 2)
|
||||
#define get_WD_Yres(sb) getnbyte(sb + 0x04, 2)
|
||||
|
||||
/* 0x06-0x09 - Upper Left X in 1/1200 inch
|
||||
*/
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
#define set_WD_ULX(sb, val) putnbyte(sb + 0x06, val, 4)
|
||||
#define get_WD_ULX(sb) getnbyte(sb + 0x06, 4)
|
||||
|
||||
/* 0x0a-0x0d - Upper Left Y in 1/1200 inch
|
||||
*/
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
#define set_WD_ULY(sb, val) putnbyte(sb + 0x0a, val, 4)
|
||||
#define get_WD_ULY(sb) getnbyte(sb + 0x0a, 4)
|
||||
|
||||
/* 0x0e-0x11 - Width in 1/1200 inch
|
||||
* 3091 left+width max 10200
|
||||
* 3096 left+width max 14592
|
||||
* also limited to page size, see bytes 0x35ff.
|
||||
*/
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
#define set_WD_width(sb, val) putnbyte(sb + 0x0e, val, 4)
|
||||
#define get_WD_width(sb) getnbyte(sb + 0x0e, 4)
|
||||
|
||||
/* 0x12-0x15 - Height in 1/1200 inch
|
||||
* 3091 top+height max 16832
|
||||
* 3096 top+height max 20736, also if left+width>13199,
|
||||
* top+height has to be less than 19843
|
||||
*/
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
#define set_WD_length(sb, val) putnbyte(sb + 0x12, val, 4)
|
||||
#define get_WD_length(sb) getnbyte(sb + 0x12, 4)
|
||||
|
||||
/* 0x16 - Brightness
|
||||
* 3091 always use 0x00
|
||||
* 3096 if in halftone mode, 8 levels supported (01-1F, 20-3F,
|
||||
..., E0-FF)
|
||||
* use 0x00 for user defined dither pattern
|
||||
*/
|
||||
0x00,
|
||||
#define set_WD_brightness(sb, val) sb[0x16] = val
|
||||
#define get_WD_brightness(sb) sb[0x16]
|
||||
|
||||
/* 0x17 - Threshold
|
||||
* 3091 0x00 = use floating slice; 0x01..0xff fixed slice
|
||||
* with 0x01=brightest, 0x80=medium, 0xff=darkest;
|
||||
* only effective for line art mode.
|
||||
* 3096 0x00 = use "simplified dynamic treshold", otherwise
|
||||
* same as above but resolution is only 64 steps.
|
||||
*/
|
||||
0x00,
|
||||
#define set_WD_threshold(sb, val) sb[0x17] = val
|
||||
#define get_WD_threshold(sb) sb[0x17]
|
||||
|
||||
/* 0x18 - Contrast
|
||||
* 3091 - not supported, always use 0x00
|
||||
* 3096 - the same
|
||||
*/
|
||||
0x00,
|
||||
#define set_WD_contrast(sb, val) sb[0x18] = val
|
||||
#define get_WD_contrast(sb) sb[0x18]
|
||||
|
||||
/* 0x19 - Image Composition (color mode)
|
||||
* 3091 - use 0x00 for line art, 0x01 for halftone,
|
||||
* 0x02 for grayscale, 0x05 for color.
|
||||
* 3096 - same but minus color.
|
||||
*/
|
||||
0x00,
|
||||
#define set_WD_composition(sb, val) sb[0x19] = val
|
||||
#define get_WD_composition(sb) sb[0x19]
|
||||
#define WD_comp_LA 0
|
||||
#define WD_comp_HT 1
|
||||
#define WD_comp_GS 2
|
||||
#define WD_comp_RC 5
|
||||
|
||||
/* 0x1a - Depth
|
||||
* 3091 - use 0x01 for b/w or 0x08 for gray/color
|
||||
* 3096 - use 0x01 for b/w or 0x08 for gray
|
||||
*/
|
||||
0x08,
|
||||
#define set_WD_bitsperpixel(sb, val) sb[0x1a] = val
|
||||
#define get_WD_bitsperpixel(sb) sb[0x1a]
|
||||
|
||||
/* 0x1b,0x1c - Halftone Pattern
|
||||
* 3091 byte 1b: 00h default(=dither), 01h dither,
|
||||
* 02h error dispersion
|
||||
* 1c: 00 dark images, 01h dark text+images,
|
||||
* 02h light images,
|
||||
* 03h light text+images, 80h download pattern
|
||||
* 3096: 1b unused; 1c bit 7=1: use downloadable pattern,
|
||||
* bit 7=0: use builtin pattern; rest of byte 1b denotes
|
||||
* pattern number, three builtin and five downloadable
|
||||
* supported; higher numbers = error.
|
||||
*/
|
||||
0x00, 0x00,
|
||||
#define set_WD_halftone(sb, val) putnbyte(sb + 0x1b, val, 2)
|
||||
#define get_WD_halftone(sb) getnbyte(sb + 0x1b, 2)
|
||||
|
||||
/* 0x1d - Reverse image, padding type
|
||||
* 3091: bit 7=1: reverse black&white
|
||||
* bits 0-2: padding type, must be 0
|
||||
* 3096: the same; bit 7 must be set for gray and not
|
||||
* set for b/w.
|
||||
*/
|
||||
0x00,
|
||||
#define set_WD_rif(sb, val) setbitfield(sb + 0x1d, 1, 7, val)
|
||||
#define get_WD_rif(sb) getbitfield(sb + 0x1d, 1, 7)
|
||||
|
||||
/* 0x1e,0x1f - Bit ordering
|
||||
* 3091 not supported, use 0x00
|
||||
* 3096 not supported, use 0x00
|
||||
*/
|
||||
0x00, 0x00, /* 0x1e *//* bit ordering */
|
||||
#define set_WD_bitorder(sb, val) putnbyte(sb + 0x1e, val, 2)
|
||||
#define get_WD_bitorder(sb) getnbyte(sb + 0x1e, 2)
|
||||
|
||||
/* 0x20 - compression type
|
||||
* 3091 - not supported, use 0x00
|
||||
* 3096 - only allowed with CMP option and not in gray
|
||||
* mode; use 0x01=MH,0x02=MR,0x03=MMR
|
||||
*/
|
||||
0x00,
|
||||
#define set_WD_compress_type(sb, val) sb[0x20] = val
|
||||
#define get_WD_compress_type(sb) sb[0x20]
|
||||
#define WD_cmp_NONE 0
|
||||
#define WD_cmp_MH 1
|
||||
#define WD_cmp_MR 2
|
||||
#define WD_cmp_MMR 3
|
||||
#define WD_cmp_JBIG 0x80
|
||||
|
||||
/* 0x21 - compression argument
|
||||
* 3091 - not supported, use 0x00
|
||||
* 3096 - only allowed with 0x02 ar byte 0x20 (MR compress),
|
||||
* use this to specify "k" parameter
|
||||
*/
|
||||
0x00,
|
||||
#define set_WD_compress_arg(sb, val) sb[0x21] = val
|
||||
#define get_WD_compress_arg(sb) sb[0x21]
|
||||
|
||||
/* 0x22-0x27 - reserved */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
|
||||
/* 0x28 - vendor id code
|
||||
* 3091 - use 0xc0
|
||||
* 3096 - use 0xc0
|
||||
*/
|
||||
0xC0,
|
||||
#define set_WD_vendor_id_code(sb, val) sb[0x28] = val
|
||||
#define get_WD_vendor_id_code(sb) sb[0x28]
|
||||
|
||||
/* 0x29 - pattern setting
|
||||
* 3091 - use 0x00
|
||||
* 3096 - reserved, use 0x00
|
||||
*/
|
||||
0x00,
|
||||
#define set_WD_gamma(sb, val) sb[0x29] = val
|
||||
#define get_WD_gamma(sb) sb[0x29]
|
||||
#define WD_gamma_DEFAULT 0
|
||||
#define WD_gamma_NORMAL 1
|
||||
#define WD_gamma_SOFT 2
|
||||
#define WD_gamma_SHARP 3
|
||||
|
||||
/* 0x2a - outline/scanning order
|
||||
* 3091 - scanning order. Only 0x00 (line order) supported
|
||||
* 3096 - outlining. 0x00=off, 0x80=on. 0x80 only permitted
|
||||
* when image processing option fitted.
|
||||
*/
|
||||
0x00,
|
||||
#define set_WD_outline(sb, val) sb[0x2a] = val
|
||||
#define get_WD_outline(sb) sb[0x2a]
|
||||
#define set_WD_scanning_order(sb, val) sb[0x2a] = val
|
||||
#define get_WD_scanning_order(sb) sb[0x2a]
|
||||
|
||||
/* 0x2b - emphasis/scanning order argument
|
||||
* 3091 - scanning order argument. Only 0x00 (RGB) supported
|
||||
* 3096 - emphasis. 0x00=off, others only permitted when
|
||||
* image processing option fitted:
|
||||
* 0x2F=low emphasis, 0x4F=medium emphasis,
|
||||
* 0x7F=high emphasis, 0xFF=smoothing
|
||||
*/
|
||||
0x00,
|
||||
#define set_WD_emphasis(sb, val) sb[0x2b] = val
|
||||
#define get_WD_emphasis(sb) sb[0x2b]
|
||||
#define WD_emphasis_NONE 0x00
|
||||
#define WD_emphasis_LOW 0x01
|
||||
#define WD_emphasis_MEDIUM 0x30
|
||||
#define WD_emphasis_HIGH 0x50
|
||||
#define WD_emphasis_SMOOTH 0x80
|
||||
|
||||
/* 0x2c - auto separation
|
||||
* 3091 - reserved, use 0x00
|
||||
* 3096 - auto separation. 0x00=off, 0x80=on. 0x80 only
|
||||
* permitted when image processing option fitted.
|
||||
*/
|
||||
0x00,
|
||||
#define set_WD_auto_sep(sb, val) setbitfield(sb + 0x2c, 1, 7, val)
|
||||
#define get_WD_auto_sep(sb) getbitfield(sb + 0x2c, 1, 7)
|
||||
|
||||
/* 0x2d - mirroring/single color
|
||||
* 3091 - determines which color is used in monochrome
|
||||
* scans: 0x00/0x04=G,0x01=B,0x02=R
|
||||
* 3096 - window mirroring. 0x00=off, 0x80=on. 0x80 only
|
||||
* permitted when image processing option fitted.
|
||||
*/
|
||||
0x00,
|
||||
#define set_WD_mirroring(sb, val) setbitfield(sb + 0x2d, 1, 7, val)
|
||||
#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
|
||||
|
||||
/* 0x2e - variance/bit padding
|
||||
* 3091 - unsupported, use 0x00
|
||||
* 3096 - variance rate for dynamic treshold. 0x00=default,
|
||||
* 0x1f, 0x3f, ... 0xff = small...large
|
||||
*/
|
||||
0x00,
|
||||
#define set_WD_var_rate_dyn_thresh(sb, val) sb[0x2e] = val
|
||||
#define get_WD_var_rate_dyn_thresh(sb) sb[0x2e]
|
||||
|
||||
0x00, /* 0x2f *//* DTC mode */
|
||||
#define set_WD_dtc_threshold_curve(sb, val) setbitfield(sb + 0x2f, 7, 0, val)
|
||||
#define get_WD_dtc_threshold_curve(sb) getbitfield(sb + 0x2f, 7, 0)
|
||||
#define set_WD_gradation(sb, val) setbitfield(sb + 0x2f, 3, 3, val)
|
||||
#define get_WD_gradation(sb) getbitfield(sb + 0x2f, 3, 3)
|
||||
#define WD_gradation_ORDINARY 0
|
||||
#define WD_gradation_HIGH 2
|
||||
#define set_WD_smoothing_mode(sb, val) setbitfield(sb + 0x2f, 3, 5, val)
|
||||
#define get_WD_smoothing_mode(sb) getbitfield(sb + 0x2f, 3, 5)
|
||||
#define WD_smoothing_OCR 0
|
||||
#define WD_smoothing_IMAGE 1
|
||||
#define set_WD_filtering(sb, val) setbitfield(sb + 0x2f, 1, 7, val)
|
||||
#define get_WD_filtering(sb) getbitfield(sb + 0x2f, 1, 7)
|
||||
#define WD_filtering_BALLPOINT 0
|
||||
#define WD_filtering_ORDINARY 1
|
||||
|
||||
0x00, /* 0x30 *//* DTC mode 2 */
|
||||
#define set_WD_background(sb, val) setbitfield(sb + 0x30, 1, 0, val)
|
||||
#define get_WD_background(sb) getbitfield(sb + 0x30, 1, 0)
|
||||
#define WD_background_WHITE 0
|
||||
#define WD_background_BLACK 1
|
||||
#define set_WD_matrix2x2(sb, val) setbitfield(sb + 0x30, 1, 1, val)
|
||||
#define get_WD_matrix2x2(sb) getbitfield(sb + 0x30, 1, 1)
|
||||
#define set_WD_matrix3x3(sb, val) setbitfield(sb + 0x30, 1, 2, val)
|
||||
#define get_WD_matrix3x3(sb) getbitfield(sb + 0x30, 1, 2)
|
||||
#define set_WD_matrix4x4(sb, val) setbitfield(sb + 0x30, 1, 3, val)
|
||||
#define get_WD_matrix4x4(sb) getbitfield(sb + 0x30, 1, 3)
|
||||
#define set_WD_matrix5x5(sb, val) setbitfield(sb + 0x30, 1, 4, val)
|
||||
#define get_WD_matrix5x5(sb) getbitfield(sb + 0x30, 1, 4)
|
||||
#define set_WD_noise_removal(sb, val) setbitfield(sb + 0x30, 1, 5, !val)
|
||||
#define get_WD_noise_removal(sb) !getbitfield(sb + 0x30, 1, 5)
|
||||
|
||||
0x00, /* 0x31 *//* reserved */
|
||||
|
||||
|
||||
/* 0x32 - scanning mode/white level follower
|
||||
* 3091 - scan mode 0x00=normal, 0x02=high quality
|
||||
* 3096 - white level follower, 0x00=default,
|
||||
* 0x80 enable (line mode), 0xc0 disable (photo mode)
|
||||
*/
|
||||
0x00,
|
||||
#define set_WD_white_level_follow(sb, val) sb[0x32] = val
|
||||
#define get_WD_white_level_follow(sb) sb[0x32]
|
||||
#define set_WD_quality(sb, val) sb[0x32] = val
|
||||
#define get_WD_quality(sb) sb[0x32]
|
||||
#define WD_white_level_follow_DEFAULT 0x00
|
||||
#define WD_white_level_follow_ENABLED 0x80
|
||||
#define WD_white_level_follow_DISABLED 0xC0
|
||||
|
||||
/* 0x33,0x34 - subwindow list
|
||||
* 3091 reserved, use 0x00
|
||||
* 3096 bits 0-3 of byte 34 denote use of subwindows 1...4
|
||||
*/
|
||||
0x00, 0x00,
|
||||
#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
|
||||
* 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_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
|
||||
#define WD_paper_A3 3
|
||||
#define WD_paper_A4 4
|
||||
#define WD_paper_A5 5
|
||||
#define WD_paper_DOUBLE 6
|
||||
#define WD_paper_LETTER 7
|
||||
#define WD_paper_B4 12
|
||||
#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
|
||||
* 3096 0<w<=14592
|
||||
*/
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
#define set_WD_paper_width_X(sb, val) putnbyte(sb + 0x36, val, 4)
|
||||
#define get_WD_paper_width_X(sb) getnbyte(sb + 0x36, 4)
|
||||
|
||||
/* 0x3a-0x3d - custom paper length
|
||||
* 3091 0<w<=16832
|
||||
* 3096 0<w<=20736
|
||||
*/
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
#define set_WD_paper_length_Y(sb, val) putnbyte(sb+0x3a, val, 4)
|
||||
#define get_WD_paper_length_Y(sb) getnbyte(sb+0x3a, 4)
|
||||
|
||||
0X00, /* 0x3e *//* DTC selection (3091: reserved) */
|
||||
#define set_WD_dtc_selection(sb, val) setbitfield(sb + 0x3e, 3, 6, val)
|
||||
#define get_WD_dtc_selection(sb) getbitfield(sb + 0x3e, 3, 6)
|
||||
#define WD_dtc_selection_DEFAULT 0
|
||||
#define WD_dtc_selection_DYNAMIC 1
|
||||
#define WD_dtc_selection_SIMPLIFIED 2
|
||||
/* - the rest of this is all zeroes, comments from the 3091 docs. */
|
||||
|
||||
0x00, /* 0x3f reserved */
|
||||
0x00, /* 0x40 intial slice (floating slice parameter) */
|
||||
0x00, /* 0x41 paper color ratio (white level slice ratio) (floating slice parameter) */
|
||||
0x00, /* 0x42 black/white ratio (black/white slice) (floating slice parameter) */
|
||||
0x00, /* 0x43 Up (+UP count setting) (floating slice parameter) */
|
||||
0x00, /* 0x44 Down (+Down count setting) (floating slice parameter) */
|
||||
0x00, /* 0x45 Lower Limit Slice (floating slice parameter) */
|
||||
0x00, /* 0x46 Compensation Line Interval (floating slice parameter) */
|
||||
0x00, /* 0x47 Reserved */
|
||||
0x00, /* 0x48 Error Diffusion upper limit slice (error diffusion parameter) */
|
||||
0x00, /* 0x49 Error Diffusion lower limit slice (error diffusion parameter) */
|
||||
0x00, /* 0x4a Reserved */
|
||||
0x00, /* 0x4b Reserved */
|
||||
0x00, /* 0x4c Enhancement Setting */
|
||||
0x00, /* 0x4d Laplacian Gradient Coefficient (enhancement parameter) */
|
||||
0x00, /* 0x4e Gradient Coefficient (enhancement parameter) */
|
||||
0x00, /* 0x4f Laplacian Slice (enhancement parameter) */
|
||||
0x00, /* 0x50 Gradient Slice (enhancement parameter) */
|
||||
0x00, /* 0x51 Reserved */
|
||||
0x00, /* 0x52 Primary Scan Ratio Compensation */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, /* 0x53 - 0x57 reserved */
|
||||
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 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)
|
||||
|
||||
/* ==================================================================== */
|
||||
|
||||
/*
|
||||
static unsigned char request_senseC[] =
|
||||
{REQUEST_SENSE, 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)
|
||||
#define get_RS_filemark(b) getbitfield(b + 0x02, 1, 7)
|
||||
#define get_RS_EOM(b) getbitfield(b + 0x02, 1, 6)
|
||||
#define get_RS_ILI(b) getbitfield(b + 0x02, 1, 5)
|
||||
#define get_RS_sense_key(b) getbitfield(b + 0x02, 0x0f, 0)
|
||||
#define get_RS_information(b) getnbyte(b+0x03, 4) /* normally 0 */
|
||||
#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 rs_return_block_size 18 /* Says Nikon */
|
||||
|
||||
/* ==================================================================== */
|
||||
|
||||
/* ==================================================================== */
|
||||
|
||||
#endif
|
Plik diff jest za duży
Load Diff
|
@ -0,0 +1,3 @@
|
|||
#option force-model fi-4340Cdi
|
||||
#/dev/sg1
|
||||
scsi FUJITSU
|
|
@ -0,0 +1,497 @@
|
|||
#ifndef FUJITSU_H
|
||||
#define FUJITSU_H
|
||||
|
||||
/*
|
||||
* Part of SANE - Scanner Access Now Easy.
|
||||
*
|
||||
* Please see opening comment in fujitsu.c
|
||||
*/
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static int num_devices;
|
||||
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
|
||||
* still the possibility to say so, later.
|
||||
*/
|
||||
enum fujitsu_Option
|
||||
{
|
||||
OPT_NUM_OPTS = 0,
|
||||
|
||||
OPT_MODE_GROUP,
|
||||
OPT_SOURCE,
|
||||
OPT_MODE,
|
||||
OPT_DUPLEX,
|
||||
OPT_X_RES,
|
||||
OPT_Y_RES,
|
||||
|
||||
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_PAGE_WIDTH,
|
||||
OPT_PAGE_HEIGHT,
|
||||
|
||||
|
||||
OPT_ENHANCEMENT_GROUP,
|
||||
OPT_AVERAGING,
|
||||
OPT_BRIGHTNESS,
|
||||
OPT_THRESHOLD,
|
||||
OPT_CONTRAST,
|
||||
|
||||
OPT_RIF,
|
||||
OPT_COMPRESSION,
|
||||
|
||||
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_DROPOUT_COLOR,
|
||||
OPT_START_BUTTON,
|
||||
|
||||
OPT_TUNING_GROUP,
|
||||
OPT_LAMP_COLOR,
|
||||
OPT_BLUE_OFFSET,
|
||||
OPT_GREEN_OFFSET,
|
||||
OPT_USE_SWAPFILE,
|
||||
|
||||
/* must come last: */
|
||||
NUM_OPTIONS
|
||||
};
|
||||
|
||||
|
||||
struct fujitsu
|
||||
{
|
||||
struct fujitsu *next;
|
||||
|
||||
SANE_Option_Descriptor opt[NUM_OPTIONS];
|
||||
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. */
|
||||
int sfd; /* The scanner device file descriptor. */
|
||||
|
||||
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 */
|
||||
|
||||
int can_read_alternate; /* duplex transfer mode front/back/front/back... */
|
||||
int adf_present; /* true if an ADF has been detected. */
|
||||
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_white_level_follow; /* ............ */
|
||||
int has_subwindow; /* ............ */
|
||||
int has_dropout_color; /* */
|
||||
/* User settable values (usually mirrored in SANE options) */
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
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. */
|
||||
|
||||
/* 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 */
|
||||
|
||||
SANE_Range adf_width_range;
|
||||
SANE_Range adf_height_range;
|
||||
SANE_Range x_range;
|
||||
SANE_Range y_range;
|
||||
|
||||
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];
|
||||
|
||||
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];
|
||||
|
||||
|
||||
/* 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; /* Pipe between reader process and backend. */
|
||||
int duplex_pipe; /* 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 */
|
||||
|
||||
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 *****/
|
||||
|
||||
int dropout_color;
|
||||
};
|
||||
|
||||
/** 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 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
|
||||
/** Fujitsu ScanPartner 15C (....) */
|
||||
#define MODEL_SP15 3
|
||||
/** 3093 */
|
||||
#define MODEL_3093 4
|
||||
/** 4097 */
|
||||
#define MODEL_4097 5
|
||||
/** fi-???? */
|
||||
#define MODEL_FI 6
|
||||
|
||||
/* 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 "adf_present" 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.
|
||||
*/
|
||||
|
||||
/** 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
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#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 FUJITSU_CONFIG_FILE "fujitsu.conf"
|
||||
|
||||
#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
|
||||
#endif
|
||||
|
||||
#ifndef PATH_SEP
|
||||
#ifdef HAVE_OS2_H
|
||||
# define PATH_SEP '\\'
|
||||
#else
|
||||
# define PATH_SEP '/'
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
SANE_Status sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize);
|
||||
|
||||
SANE_Status sane_get_devices (const SANE_Device *** device_list,
|
||||
SANE_Bool local_only);
|
||||
|
||||
SANE_Status sane_open (SANE_String_Const name, SANE_Handle * handle);
|
||||
|
||||
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,
|
||||
SANE_Int option);
|
||||
|
||||
SANE_Status sane_control_option (SANE_Handle handle, SANE_Int option,
|
||||
SANE_Action action, void *val,
|
||||
SANE_Int * info);
|
||||
|
||||
SANE_Status sane_start (SANE_Handle handle);
|
||||
|
||||
SANE_Status sane_get_parameters (SANE_Handle handle,
|
||||
SANE_Parameters * params);
|
||||
|
||||
SANE_Status sane_read (SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len,
|
||||
SANE_Int * len);
|
||||
|
||||
void sane_cancel (SANE_Handle h);
|
||||
|
||||
void sane_close (SANE_Handle h);
|
||||
|
||||
void sane_exit (void);
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static void doInquiry (struct fujitsu *s);
|
||||
|
||||
static SANE_Status attachScanner (const char *devicename,
|
||||
struct fujitsu **devp);
|
||||
|
||||
static SANE_Status senseHandler (int scsi_fd, u_char * result, void *arg);
|
||||
|
||||
static int identifyScanner (struct fujitsu *s);
|
||||
|
||||
static void doInquiry (struct fujitsu *s);
|
||||
|
||||
static int do_scsi_cmd (int fd, unsigned char *cmd, int cmd_len,
|
||||
unsigned char *out, size_t out_len);
|
||||
|
||||
static void hexdump (int level, char *comment, unsigned char *p, int l);
|
||||
|
||||
static SANE_Status initOptions (struct fujitsu *scanner);
|
||||
|
||||
static int grabScanner (struct fujitsu *s);
|
||||
|
||||
static int freeScanner (struct fujitsu *s);
|
||||
|
||||
static int waitScanner (struct fujitsu *s);
|
||||
|
||||
static int objectPosition (struct fujitsu *s);
|
||||
|
||||
static SANE_Status doCancel (struct fujitsu *scanner);
|
||||
|
||||
static int objectDischarge (struct fujitsu *s);
|
||||
|
||||
static int set_mode_params (struct fujitsu *s);
|
||||
|
||||
static int setWindowParam (struct fujitsu *s);
|
||||
|
||||
static size_t maxStringSize (const SANE_String_Const strings[]);
|
||||
|
||||
static int startScan (struct fujitsu *s);
|
||||
|
||||
static int reader_process (struct fujitsu *scanner, int fd1, int fd2);
|
||||
|
||||
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 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 unsigned int readerGenericPassthrough (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);
|
||||
|
||||
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 void setDefaultsSP15 (struct fujitsu *scanner);
|
||||
|
||||
static SANE_Status setMode3091 (struct fujitsu *scanner, int mode);
|
||||
static SANE_Status setMode3096 (struct fujitsu *scanner, int mode);
|
||||
static SANE_Status setModeSP15 (struct fujitsu *scanner, int mode);
|
||||
|
||||
static void calculateDerivedValues (struct fujitsu *scanner);
|
||||
|
||||
static int makeTempFile (void);
|
||||
static SANE_Status getHardwareStatus (struct fujitsu *s);
|
||||
static void fujitsu_set_standard_size (SANE_Handle handle);
|
||||
|
||||
|
||||
#endif /* FUJITSU_H */
|
|
@ -0,0 +1,35 @@
|
|||
;
|
||||
; SANE Backend specification file
|
||||
;
|
||||
; It's basically emacs-lisp --- so ";" indicates comment to end of line.
|
||||
; All syntactic elements are keyword tokens, followed by a string or
|
||||
; keyword argument, as specified.
|
||||
;
|
||||
; ":backend" *must* be specified.
|
||||
; All other information is optional (but what good is the file without it?).
|
||||
;
|
||||
|
||||
:backend "fujitsu" ; name of backend
|
||||
;:url "http://www.remote.org/frederik/projects/software/sane/"
|
||||
:version "1.0" ; version of backend
|
||||
:status :new ; :alpha, :beta, :stable, :new
|
||||
:manpage "sane-fujitsu" ; name of manpage (if it exists)
|
||||
|
||||
:devicetype :scanner ; start of a list of devices....
|
||||
; other types: :stillcam, :vidcam,
|
||||
; :meta, :api
|
||||
|
||||
:mfg "Fujitsu" ; name a manufacturer
|
||||
:model "M3096G" ; name models for above-specified mfg.
|
||||
:interface "SCSI"
|
||||
;:url "http://www.aa.net/~bentson/sane.html"
|
||||
:model "M3091DCd" ; name models for above-specified mfg.
|
||||
:interface "SCSI"
|
||||
:url "http://www.remote.org/frederik/projects/software/sane/"
|
||||
:model "M3093GXim"
|
||||
:interface "SCSI"
|
||||
:model "M3093GDim"
|
||||
:interface "SCSI"
|
||||
:model "fi-4340C"
|
||||
:interface "SCSI"
|
||||
|
|
@ -1,57 +1,158 @@
|
|||
.TH sane-fujitsu 5 "10 Oct 2001"
|
||||
.TH sane-fujitsu 5 "17 Apr 2002"
|
||||
.IX sane-fujitsu
|
||||
.IX sane-fcpa
|
||||
.IX sane-m3096g
|
||||
.IX sane-sp15c
|
||||
|
||||
.SH NAME
|
||||
sane-m3096g, sane-sp15c - SANE backends for Fujitsu flatbed scanners
|
||||
sane-fujitsu - SANE backend for Fujitsu flatbed scanners
|
||||
|
||||
.SH DESCRIPTION
|
||||
The
|
||||
.B sane-m3096g
|
||||
and
|
||||
.B sane-sp15c
|
||||
libraries implement SANE (Scanner Access Now Easy) backends which
|
||||
provide access to Fujitsu flatbed scanners.
|
||||
.B sane-fujitsu
|
||||
library implements a SANE (Scanner Access Now Easy) backend which
|
||||
provides access to Fujitsu flatbed scanners.
|
||||
At present, the following
|
||||
scanners are known to work with these backends:
|
||||
scanners are known to work with this backend:
|
||||
.PP
|
||||
.RS
|
||||
Vendor: Model: Rev:
|
||||
Vendor: Model: Rev:
|
||||
.br
|
||||
-------- ---------------- -----
|
||||
.br
|
||||
FUJITSU M3096Gm 02
|
||||
.br
|
||||
FCPA ScanPartner 15C 1.01
|
||||
FUJITSU M3093GX
|
||||
.br
|
||||
FUJITSU M3093GD
|
||||
.br
|
||||
FUJITSU fi-4340C
|
||||
.br
|
||||
FUJITSU M3091DCd BF21
|
||||
.RE
|
||||
.P
|
||||
The M3096G driver supports
|
||||
lineart (1-bit), halftone (1-bit),
|
||||
and grayscale (8-bit) scanning.
|
||||
The driver supports lineart, halftone, grayscale, and color
|
||||
scanning depending on hardware capabiliites.
|
||||
|
||||
The ScanPartner 15C driver supports
|
||||
lineart (1-bit), halftone (1-bit),
|
||||
grayscale (4-bit and 8-bit),
|
||||
and color (3 x 8-bit) scanning.
|
||||
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.
|
||||
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
|
||||
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
|
||||
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
|
||||
.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.
|
||||
.RE
|
||||
.PP
|
||||
brightness b
|
||||
.RS
|
||||
Only supported for M3096
|
||||
.RE
|
||||
.PP
|
||||
treshold t
|
||||
.RS
|
||||
Only supported for M3096
|
||||
.RE
|
||||
.PP
|
||||
duplex d
|
||||
.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).
|
||||
.RE
|
||||
.PP
|
||||
lampcolor c
|
||||
.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.
|
||||
.RE
|
||||
.PP
|
||||
blueoffset, greenoffset
|
||||
.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.
|
||||
.RE
|
||||
.PP
|
||||
swapfile
|
||||
.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.
|
||||
.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",
|
||||
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".
|
||||
|
||||
.SH "SEE ALSO"
|
||||
sane(7), sane\-scsi(5)
|
||||
sane(7),
|
||||
sane\-scsi(5),
|
||||
sane\-sp15c(5)
|
||||
.br
|
||||
Fujitsu ScanPartner 15C OEM Manual, Doc. No. 250-0081-0
|
||||
.br
|
||||
|
@ -60,31 +161,18 @@ Fujitsu M3096G OEM Manual, part number 50FH5028E-05
|
|||
Fujitsu M3096GX/M3093GX/M3093DG OEM Manual, part number C150-E015...03
|
||||
|
||||
.SH AUTHOR
|
||||
Randolph Bentson
|
||||
3096/SP15 drivers: Randolph Bentson
|
||||
<bentson@holmsjoen.com>,
|
||||
and Oliver Schirrmeister <oschirr@abm.de>,
|
||||
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>
|
||||
|
||||
.SH LIMITATIONS
|
||||
Testing limited to a Linux 2.2.5 kernel
|
||||
.br
|
||||
Can't quite get the scan page/minute performance in ADF modes.
|
||||
This may be due to limited system buffer size.
|
||||
Only tested with Linux 2.4
|
||||
|
||||
.SH BUGS
|
||||
I'm sure there are plenty, and not too well hidden,
|
||||
but I haven't seen them yet.
|
||||
.br
|
||||
Both scanners claim to have separate control
|
||||
of resolution in X and Y directions.
|
||||
I confess I haven't tested this yet.
|
||||
I have found that xsane doesn't even display this capability.
|
||||
.br
|
||||
Threshold settings on the SP15C don't seem to
|
||||
affect the results of lineart mode scans.
|
||||
.br
|
||||
It might be possible to merge these two drivers without much effort
|
||||
since the SP15C driver was derived from the M3096G driver.
|
||||
They were split so as to keep the second driver development from breaking
|
||||
the working first driver.
|
||||
Watch this space for changes.
|
||||
I don't know if the ScanPartner 15C still works, because I'm not able
|
||||
to test it.
|
Ładowanie…
Reference in New Issue