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
Henning Geinitz 2002-04-17 18:50:39 +00:00
rodzic 7e13df9195
commit 1982eec1dd
6 zmienionych plików z 7279 dodań i 40 usunięć

Wyświetl plik

@ -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

5782
backend/fujitsu.c 100644

Plik diff jest za duży Load Diff

Wyświetl plik

@ -0,0 +1,3 @@
#option force-model fi-4340Cdi
#/dev/sg1
scsi FUJITSU

497
backend/fujitsu.h 100644
Wyświetl plik

@ -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 */

Wyświetl plik

@ -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"

Wyświetl plik

@ -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.