diff options
Diffstat (limited to 'backend/microtek2.h')
-rw-r--r-- | backend/microtek2.h | 1384 |
1 files changed, 1384 insertions, 0 deletions
diff --git a/backend/microtek2.h b/backend/microtek2.h new file mode 100644 index 0000000..4100fad --- /dev/null +++ b/backend/microtek2.h @@ -0,0 +1,1384 @@ +/******************************************************************************* + * SANE - Scanner Access Now Easy. + + microtek2.h + + This file (C) 1998, 1999 Bernd Schroeder + 2000, 2001 Karsten Festag + + This file is part of the SANE package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + fOUNDATIOn, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA. + + As a special exception, the authors of SANE give permission for + additional uses of the libraries contained in this release of SANE. + + The exception is that, if you link a SANE library with other files + to produce an executable, this does not by itself cause the + resulting executable to be covered by the GNU General Public + License. Your use of that executable is in no way restricted on + account of linking the SANE library code into it. + + This exception does not, however, invalidate any other reasons why + the executable file might be covered by the GNU General Public + License. + + If you submit changes to SANE to the maintainers to be included in + a subsequent release, you agree by submitting the changes that + those changes may be distributed with this exception intact. + + If you write modifications of your own for SANE, it is your choice + whether to permit this exception to apply to your modifications. + If you do not wish that, delete this exception notice. + + +*******************************************************************************/ + + +#ifndef microtek2_h +#define microtek2_h + +#include <sys/types.h> + + +/******************************************************************************/ +/* Miscellaneous defines */ +/******************************************************************************/ + +#ifndef PATH_MAX +# define PATH_MAX 1024 +#endif + +#ifdef HAVE_AUTHORIZATION +#ifndef PATH_SEP +#if defined(_WIN32) || defined(HAVE_OS2_H) +# define PATH_SEP "\\" +#else +# define PATH_SEP "/" +#endif +#endif + +#define MAX_LINE_LEN 512 /* max length of entry in password file */ +#define PASSWD_FILE STRINGIFY(PATH_SANE_CONFIG_DIR) PATH_SEP "auth" +#define SEPARATOR ':' /* separator in that file */ +#define SALT "ab" /* used by crypt() */ + +#endif /* HAVE_AUTHORIZATION */ + + +#define ENDIAN_TYPE(d) { unsigned i, test = 0; \ + for (i=0; i < sizeof(int); i++ ) \ + test += i << (8 * i); \ + d = ((char *) &test)[0] == 0 ? 0 : 1; } + +#define MIN(a,b) ((a) < (b)) ? (a) : (b) +#define MAX(a,b) ((a) > (b)) ? (a) : (b) + +#define MICROTEK2_MAJOR 0 +#define MICROTEK2_MINOR 96 +#define MICROTEK2_BUILD "200410042220" +#define MICROTEK2_CONFIG_FILE "microtek2.conf" + + +/******************************************************************************/ +/* defines that are common to all devices */ +/******************************************************************************/ + +#define MD_RESOLUTION_DEFAULT 72 << SANE_FIXED_SCALE_SHIFT +#define MD_BRIGHTNESS_DEFAULT 100 << SANE_FIXED_SCALE_SHIFT +#define MD_CONTRAST_DEFAULT 100 << SANE_FIXED_SCALE_SHIFT +#define MD_THRESHOLD_DEFAULT 128 +#define MD_GAMMA_DEFAULT SANE_FIX(2.2) +#define MD_SHADOW_DEFAULT 0 +#define MD_MIDTONE_DEFAULT 128 +#define MD_HIGHLIGHT_DEFAULT 255 +#define MD_EXPOSURE_DEFAULT 0 +#define M_BRIGHTNESS_DEFAULT 128 +#define M_CONTRAST_DEFAULT 128 +#define M_SHADOW_DEFAULT 0 +#define M_MIDTONE_DEFAULT 128 +#define M_HIGHLIGHT_DEFAULT 255 +#define M_EXPOSURE_DEFAULT 0 +#define M_THRESHOLD_DEFAULT 128 + + +/******************************************************************************/ +/* SCSI commands used by the scanner */ +/******************************************************************************/ + +/* INQUIRY */ +#define INQ_CMD(d) d[0] = 0x12; d[1] = 0x00; d[2] = 0x00; \ + d[3] = 0x00; d[4] = 0x00; d[5] = 0x00 +#define INQ_CMD_L 6 +#define INQ_ALLOC_L 5 /* first get 5 bytes */ +#define INQ_ALLOC_P 4 +#define INQ_SET_ALLOC(d,s) (d)[4] = (s) + +#define INQ_GET_INQLEN(d,s) d = (s)[4] +#define INQ_GET_QUAL(d,s) d = ((s)[0] >> 5) & 0x07 +#define INQ_GET_DEVT(d,s) d = (s)[0] & 0x1f +#define INQ_GET_VERSION(d,s) d = (s)[2] & 0x02 +#define INQ_VENDOR_L 8 +#define INQ_GET_VENDOR(d,s) strncpy(d, &(s)[8], INQ_VENDOR_L); \ + d[INQ_VENDOR_L] = '\0' +#define INQ_MODEL_L 16 +#define INQ_GET_MODEL(d,s) strncpy(d, &(s)[16], INQ_MODEL_L); \ + d[INQ_MODEL_L] = '\0' +#define INQ_REV_L 4 +#define INQ_GET_REV(d,s) strncpy(d, &(s)[32], INQ_REV_L); \ + d[INQ_REV_L] = '\0' +#define INQ_GET_MODELCODE(d,s) d = (s)[36] + + + +/* TEST_UNIT_READY */ +#define TUR_CMD(d) d[0]=0x00; d[1]=0x00; d[2]=0x00; \ + d[3]=0x00; d[4]=0x00; d[5]=0x00 +#define TUR_CMD_L 6 + + +/* READ GAMMA TABLE */ +#define RG_CMD(d) (d)[0] = 0x28; (d)[1] = 0x00; (d)[2] = 0x03; \ + (d)[3] = 0x00; (d)[4] = 0x00; (d)[5] = 0x00; \ + (d)[6] = 0x00; (d)[7] = 0x00; (d)[8] = 0x00; \ + (d)[9] = 0x00 +#define RG_CMD_L 10 +#define RG_PCORMAC(d,p) (d)[5] |= (((p) << 7) & 0x80) +#define RG_COLOR(d,p) (d)[5] |= (((p) << 5) & 0x60) +#define RG_WORD(d,p) (d)[5] |= ((p) & 0x01) +#define RG_TRANSFERLENGTH(d,p) (d)[7] = (((p) >> 8) & 0xff); \ + (d)[8] = ((p) & 0xff) + +/* SEND GAMMA TABLE */ +#define SG_SET_CMD(d) (d)[0] = 0x2a; (d)[1] = 0x00; (d)[2] = 0x03; \ + (d)[3] = 0x00; (d)[4] = 0x00; (d)[5] = 0x00; \ + (d)[6] = 0x00; (d)[7] = 0x00; (d)[8] = 0x00; \ + (d)[9] = 0x00 +#define SG_CMD_L 10 +#define SG_SET_PCORMAC(d,p) (d)[5] |= (((p) << 7) & 0x80) +#define SG_SET_COLOR(d,p) (d)[5] |= (((p) << 5) & 0x60) +#define SG_SET_WORD(d,p) (d)[5] |= ((p) & 0x01) +#define SG_SET_TRANSFERLENGTH(d,p) (d)[7] = (((p) >> 8) & 0xff); \ + (d)[8] = ((p) & 0xff) +#define SG_DATA_P SG_CMD_L + + +/* READ CONTROL BITS */ +#define RCB_SET_CMD(d) (d)[0] = 0x28; (d)[1] = 0x00; (d)[2] = 0x90; \ + (d)[3] = 0x00; (d)[4] = 0x00; (d)[5] = 0x00; \ + (d)[6] = 0x00; (d)[7] = 0x00; (d)[8] = 0x00; \ + (d)[9] = 0x00 +#define RCB_CMD_L 10 +#define RCB_SET_LENGTH(d,s) (d)[6] = (((s) >> 16) & 0xff); \ + (d)[7] = (((s) >> 8) & 0xff); \ + (d)[8] = ((s) & 0xff); + + +/* READ_SCANNER_ATTRIBUTES */ +#define RSA_CMD(d) d[0]=0x28; d[1]=0x00; d[2]=0x82; d[3]=0x00; \ + d[4]=0x00; d[5]=0x00; d[6]=0x00; d[7]=0x00; \ + d[8]=0x28; d[9]=0x00 +#define RSA_CMD_L 10 +#define RSA_SETMEDIA(d,p) d[5] |= ((p) & 0x77) +#define RSA_TRANSFERLENGTH 40 + +#define RSA_COLOR(d,s) d = (((s)[0] >> 7) & 0x01) +#define RSA_ONEPASS(d,s) d = (((s)[0] >> 6) & 0x01) +#define RSA_SCANNERTYPE(d,s) d = (((s)[0] >> 4) & 0x03) +#define RSA_FEPROM(d,s) d = (((s)[0] >> 3) & 0x01) +#define RSA_DATAFORMAT(d,s) d = ((s)[0] & 0x07) +#define RSA_COLORSEQUENCE_L 3 +#define RSA_COLORSEQUENCE(d,s) { \ + d[0] = (((s)[1] >> 6) & 0x03); \ + d[1] = (((s)[1] >> 4) & 0x03); \ + d[2] = (((s)[1] >> 2) & 0x03); \ + } +#define RSA_NIS(d,s) d = ((s)[1] & 0x02) +#define RSA_DATSEQ(d,s) d = ((s)[1] & 0x01) +#define RSA_CCDGAP(d,s) d = (s)[2] +#define RSA_MAX_XRESOLUTION(d,s) d = ((s)[3] << 8) + (s)[4] +#define RSA_MAX_YRESOLUTION(d,s) d = ((s)[5] << 8) + (s)[6] +#define RSA_GEOWIDTH(d,s) d = ((s)[7] << 8) + (s)[8] +#define RSA_GEOHEIGHT(d,s) d = ((s)[9] << 8) + (s)[10] +#define RSA_OPTRESOLUTION(d,s) d = ((s)[11] << 8) + (s)[12] +#define RSA_DEPTH(d,s) d = (((s)[13] >> 4) & 0x0f) +#define RSA_SCANMODE(d,s) d = (s)[13] & 0x0f +#define RSA_CCDPIXELS(d,s) d = ((s)[14] << 8) + (s)[15] +#define RSA_LUTCAP(d,s) d = (s)[16] +#define RSA_DNLDPTRN(d,s) d = (((s)[17] >> 7) & 0x01) +#define RSA_GRAINSLCT(d,s) d = (s)[17] & 0x7f +#define RSA_SUPPOPT(d,s) d = (s)[18] & 0xf3 +#define RSA_CALIBWHITE(d,s) d = ((s)[19] << 24) + ((s)[20] << 16) \ + + ((s)[21] << 8) + (s)[22] +#define RSA_CALIBSPACE(d,s) d = ((s)[23] << 24) + ((s)[24] << 16) \ + + ((s)[25] << 8) + (s)[26] +#define RSA_NLENS(d,s) d = (s)[27] +#define RSA_NWINDOWS(d,s) d = (s)[28] +#define RSA_SHTRNSFEREQU(d,s) d = (((s)[29] >> 2) & 0x3f) +#define RSA_SCNBTTN(d,s) d = (((s)[29] >> 1) & 0x01) +#define RSA_BUFTYPE(d,s) d = (s)[29] & 0x01 +#define RSA_REDBALANCE(d,s) d = ((s)[30] << 8) | (s)[31] +#define RSA_GREENBALANCE(d,s) d = ((s)[32] << 8) | (s)[33] +#define RSA_BLUEBALANCE(d,s) d = ((s)[34] << 8) | (s)[35] +#define RSA_APSMAXFRAMES(d,s) d = (s)[36] + + +/* READ IMAGE INFORMATION */ +#define RII_SET_CMD(d) (d)[0] = 0x28; (d)[1] = 0x00; (d)[2] = 0x80; \ + (d)[3] = 0x00; (d)[4] = 0x00; (d)[5] = 0x00; \ + (d)[6] = 0x00; (d)[7] = 0x00; (d)[8] = 0x10; \ + (d)[9] = 0x00 +#define RII_CMD_L 10 +#define RII_RESULT_L 16 + +#define RII_GET_WIDTHPIXEL(d,s) d = ((s)[0] << 24) + ((s)[1] << 16) \ + + ((s)[2] << 8) + (s)[3] +#define RII_GET_WIDTHBYTES(d,s) d = ((s)[4] << 24) + ((s)[5] << 16) \ + + ((s)[6] << 8) + (s)[7] +#define RII_GET_HEIGHTLINES(d,s) d = ((s)[8] << 24) + ((s)[9] << 16) \ + + ((s)[10] << 8) + (s)[11] +#define RII_GET_REMAINBYTES(d,s) d = ((s)[12] << 24) + ((s)[13] << 16) \ + + ((s)[14] << 8) + (s)[15] + +/* The V300 returns some values in only two bytes */ +#define RII_GET_V300_WIDTHPIXEL(d,s) d = ((s)[0] << 8) + (s)[1] +#define RII_GET_V300_WIDTHBYTES(d,s) d = ((s)[2] << 8) + (s)[3] +#define RII_GET_V300_HEIGHTLINES(d,s) d = ((s)[4] << 8) + (s)[5] +#define RII_GET_V300_REMAINBYTES(d,s) d = ((s)[6] << 24) + ((s)[7] << 16) \ + + ((s)[8] << 8) + (s)[9] + +/* READ SHADING INFORMATION */ +#define RSI_SET_CMD(d) (d)[0] = 0x28; (d)[1] = 0x00; (d)[2] = 0x01; \ + (d)[3] = 0x00; (d)[4] = 0x00; (d)[5] = 0x00; \ + (d)[6] = 0x00; (d)[7] = 0x00; (d)[8] = 0x10; \ + (d)[9] = 0x00 +#define RSI_CMD_L 10 +#define RSI_SET_PCORMAC(d,s) (d)[5] |= (((s) << 7) & 0x80) +#define RSI_SET_COLOR(d,s) (d)[5] |= (((s) << 5) & 0x60) +#define RSI_SET_DARK(d,s) (d)[5] |= (((s) << 1) & 0x02) /*(KF)*/ + /* RSI_SET_DARK was missing*/ +#define RSI_SET_WORD(d,s) (d)[5] |= ((s) & 0x01) +#define RSI_SET_TRANSFERLENGTH(d,s) (d)[6] = (((s) >> 16) & 0xff); \ + (d)[7] = (((s) >> 8) & 0xff); \ + (d)[8] = ((s) & 0xff); + +/* SEND SHADING INFORMATION */ +#define SSI_SET_CMD(d) (d)[0] = 0x2a; (d)[1] = 0x00; (d)[2] = 0x01; \ + (d)[3] = 0x00; (d)[4] = 0x00; (d)[5] = 0x00; \ + (d)[6] = 0x00; (d)[7] = 0x00; (d)[8] = 0x00; \ + (d)[9] = 0x00 +#define SSI_CMD_L 10 +#define SSI_SET_PCORMAC(d,s) (d)[5] |= (((s) << 7) & 0x80) +#define SSI_SET_COLOR(d,s) (d)[5] |= (((s) << 5) & 0x60) +#define SSI_SET_DARK(d,s) (d)[5] |= (((s) << 1) & 0x02) +#define SSI_SET_WORD(d,s) (d)[5] |= ((s) & 0x01) +#define SSI_SET_TRANSFERLENGTH(d,s) (d)[6] = (((s) >> 16) & 0xff); \ + (d)[7] = (((s) >> 8) & 0xff); \ + (d)[8] = ((s) & 0xff); + + +/* READ IMAGE */ + +/* READ IMAGE */ +#define RI_SET_CMD(d) (d)[0] = 0x28; (d)[1] = 0x00; (d)[2] = 0x00; \ + (d)[3] = 0x00; (d)[4] = 0x00; (d)[5] = 0x00; \ + (d)[6] = 0x00; (d)[7] = 0x00; (d)[8] = 0x00; \ + (d)[9] = 0x00 +#define RI_CMD_L 10 + + +#define RI_SET_PCORMAC(d,s) (d)[4] |= (((s) << 7) & 0x80) +#define RI_SET_COLOR(d,s) (d)[4] |= (((s) << 5) & 0x60) +#define RI_SET_TRANSFERLENGTH(d,s) (d)[6] = (((s) >> 16) & 0xff); \ + (d)[7] = (((s) >> 8) & 0xff); \ + (d)[8] = ((s) & 0xff); + + +/* READ SYSTEM_STATUS */ +#define RSS_CMD(d) (d)[0] = 0x28; (d)[1] = 0x00; (d)[2] = 0x81; \ + (d)[3] = 0x00; (d)[4] = 0x00; (d)[5] = 0x00; \ + (d)[6] = 0x00; (d)[7] = 0x00; (d)[8] = 0x09; \ + (d)[9] = 0x00 +#define RSS_CMD_L 10 +#define RSS_RESULT_L 9 + +#define RSS_FIRSTSCAN(s) (s)[0] & 0x80 +#define RSS_AFOCUS(s) (s)[0] & 0x40 +#define RSS_SSKIP(s) (s)[0] & 0x20 +#define RSS_STICK(s) (s)[0] & 0x10 +#define RSS_NTRACK(s) (s)[0] & 0x08 +#define RSS_NCALIB(s) (s)[0] & 0x04 +#define RSS_TLAMP(s) (s)[0] & 0x02 +#define RSS_FLAMP(s) (s)[0] & 0x01 +#define RSS_FSH(s) (s)[1] & 0x20 +#define RSS_TEFLAG(s) (s)[1] & 0x10 +#define RSS_WHITESTRIE(s) (s)[1] & 0x08 +#define RSS_RDYMAN(s) (s)[1] & 0x04 +#define RSS_TRDY(s) (s)[1] & 0x02 +#define RSS_FRDY(s) (s)[1] & 0x01 +#define RSS_ADP(s) (s)[2] & 0x80 +#define RSS_DETECT(s) (s)[2] & 0x40 +#define RSS_ADPTIME(s) (s)[2] & 0x3f +#define RSS_LENSSTATUS(s) (s)[3] +#define RSS_ALOFF(s) (s)[4] & 0x80 +#define RSS_TIMEREMAIN(s) (s)[4] & 0x7f +#define RSS_MTMACNT(s) (s)[5] & 0x40 +#define RSS_MOVE(s) (s)[5] & 0x20 +#define RSS_LAMP(s) (s)[5] & 0x10 +#define RSS_EJECT(s) (s)[5] & 0x08 +#define RSS_TMACNT(s) (s)[5] & 0x04 +#define RSS_PAPER(s) (s)[5] & 0x02 +#define RSS_ADFCNT(s) (s)[5] & 0x01 +#define RSS_CANCELBTN(s) (s)[6] & 0x80 +#define RSS_COPYBTN(s) (s)[6] & 0x40 +#define RSS_EMAILBTN(s) (s)[6] & 0x20 +#define RSS_GOBTN(s) (s)[6] & 0x10 +#define RSS_TURBOBTN(s) (s)[6] & 0x08 +#define RSS_CURRENTMODE(s) (s)[6] & 0x07 +#define RSS_BUTTONCOUNT(s) (s)[7] +#define RSS_MFOCUS(s) (s)[9] + +/* SEND SYSTEM STATUS */ +#define SSS_CMD(d) (d)[0] = 0x2a; (d)[1] = 0x00; (d)[2] = 0x81; \ + (d)[3] = 0x00; (d)[4] = 0x00; (d)[5] = 0x00; \ + (d)[6] = 0x00; (d)[7] = 0x00; (d)[8] = 0x09; \ + (d)[9] = 0x00 +#define SSS_CMD_L 10 +#define SSS_DATA_L 9 + +#define SSS_AFOCUS(d,p) d[0] |= (p) & 0x40 +#define SSS_STICK(d,p) d[0] |= (p) & 0x10 +#define SSS_NTRACK(d,p) d[0] |= (p) & 0x08 +#define SSS_NCALIB(d,p) d[0] |= (p) & 0x04 +#define SSS_TLAMP(d,p) d[0] |= (p) & 0x02 +#define SSS_FLAMP(d,p) d[0] |= (p) & 0x01 +#define SSS_RESERVED17(d,p) d[1] |= (p) & 0x80 +#define SSS_FSH(d,p) d[1] |= (p) & 0x40 +#define SSS_RDYMAN(d,p) d[1] |= (p) & 0x04 +#define SSS_TRDY(d,p) d[1] |= (p) & 0x02 +#define SSS_FRDY(d,p) d[1] |= (p) & 0x01 +#define SSS_ADP(d,p) d[2] |= (p) & 0x80 +#define SSS_DETECT(d,p) d[2] |= (p) & 0x40 +#define SSS_ADPTIME(d,p) d[2] |= (p) & 0x3f +#define SSS_LENSSTATUS(d,p) d[3] |= (p) +#define SSS_ALOFF(d,p) d[4] |= (p) & 0x80 +#define SSS_TIMEREMAIN(d,p) d[4] |= (p) & 0x7f +#define SSS_TMACNT(d,p) d[5] |= (p) & 0x04 +#define SSS_PAPER(d,p) d[5] |= (p) & 0x02 +#define SSS_ADFCNT(d,p) d[5] |= (p) & 0x01 +#define SSS_CURRENTMODE(d,p) d[6] |= (p) & 0x07 +#define SSS_BUTTONCOUNT(d,p) d[6] |= (p) +#define SSS_MFOCUS(s) d[9] |= (p) + + +/* SET WINDOW */ +#define SW_CMD(d) d[0]=0x24; d[1]=0x00; d[2]=0x00; d[3]=0x00; \ + d[4]=0x00; d[5]=0x00; d[6]=0x00; d[7]=0x00;\ + d[8]=0x00; d[9]=0x00 + +#define SW_CMD_L 10 +#define SW_HEADER_L 8 +#define SW_BODY_L 61 +#define SW_CMD_P 0 /* command at postion 0 */ +#define SW_HEADER_P SW_CMD_L +#define SW_BODY_P(n) SW_CMD_L + SW_HEADER_L + (n) * SW_BODY_L + +/* d: SW_CMD_P, SW_HEADER_P, SW_BODY_P(n) */ +#define SW_PARAM_LENGTH(d,p) (d)[6] = ((p) >> 16) & 0xff; \ + (d)[7] = ((p) >> 8) & 0xff;\ + (d)[8] = (p) & 0xff +#define SW_WNDDESCVAL SW_BODY_L +#define SW_WNDDESCLEN(d,p) (d)[6] = ((p) >> 8) & 0xff; \ + (d)[7] = (p) & 0xff +#define SW_WNDID(d,p) (d)[0] = (p) +#define SW_XRESDPI(d,p) (d)[2] = ((p) >> 8) & 0xff; \ + (d)[3] = (p) & 0xff +#define SW_YRESDPI(d,p) (d)[4] = ((p) >> 8) & 0xff; \ + (d)[5] = (p) & 0xff +#define SW_XPOSTL(d,p) (d)[6] = ((p) >> 24) & 0xff; \ + (d)[7] = ((p) >> 16) & 0xff; \ + (d)[8] = ((p) >> 8) & 0xff; \ + (d)[9] = ((p)) & 0xff +#define SW_YPOSTL(d,p) (d)[10] = ((p) >> 24) & 0xff; \ + (d)[11] = ((p) >> 16) & 0xff; \ + (d)[12] = ((p) >> 8) & 0xff; \ + (d)[13] = (p) & 0xff +#define SW_WNDWIDTH(d,p) (d)[14] = ((p) >> 24) & 0xff; \ + (d)[15] = ((p) >> 16) & 0xff; \ + (d)[16] = ((p) >> 8) & 0xff; \ + (d)[17] = (p) & 0xff +#define SW_WNDHEIGHT(d,p) (d)[18] = ((p) >> 24) & 0xff; \ + (d)[19] = ((p) >> 16) & 0xff; \ + (d)[20] = ((p) >> 8) & 0xff; \ + (d)[21] = (p) & 0xff +#define SW_BRIGHTNESS_M(d,p) (d)[22] = (p) +#define SW_THRESHOLD(d,p) (d)[23] = (p) +#define SW_CONTRAST_M(d,p) (d)[24] = (p) +#define SW_IMGCOMP(d,p) (d)[25] = (p) & 0x0f /* take lineartfake */ + /* into account */ +#define SW_BITSPERPIXEL(d,p) (d)[26] = (p) +#define SW_EXPOSURE_M(d,p) (d)[27] = (p) +#define SW_EXTHT(d,p) (d)[28] |= (((p) << 7) & 0x80) +#define SW_INTHTINDEX(d,p) (d)[28] |= ((p) & 0x7f) +#define SW_RIF(d,p) (d)[29] |= (((p) << 7) & 0x80) +#define SW_NOGAMMA(d,p) (d)[29] |= (((p) << 6) & 0x40) +#define SW_SLOWSCAN(d,p) (d)[29] |= (((p) << 5) & 0x20) +#define SW_LENS(d,p) (d)[30] = (p) +#define SW_INFINITE(d,p) (d)[31] |= (((p) << 7) & 0x80) +#define SW_STAY(d,p) (d)[31] |= (((p) << 6) & 0x40) +#define SW_RAWDAT(d,p) (d)[31] |= (((p) << 5) & 0x20) +#define SW_QUALITY(d,p) (d)[31] |= (((p) << 4) & 0x10) +#define SW_FASTSCAN(d,p) (d)[31] |= (((p) << 3) & 0x08) +#define SW_MEDIA(d,p) (d)[31] |= ((p) & 0x07) +#define SW_JPEGENABLE(d,p) (d)[34] |= (((p) << 7) & 0x80) +#define SW_JPEGALGOR(d,p) (d)[34] |= (((p) << 5) & 0x60) +#define SW_JPEGMODE(d,p) (d)[34] |= (((p) << 3) & 0x18) +#define SW_SHADOW_M(d,p) (d)[40] = (p) +#define SW_MIDTONE_M(d,p) (d)[41] = (p) +#define SW_HIGHLIGHT_M(d,p) (d)[42] = (p) +#define SW_BRIGHTNESS_R(d,p) (d)[43] = (p) +#define SW_CONTRAST_R(d,p) (d)[44] = (p) +#define SW_EXPOSURE_R(d,p) (d)[45] = (p) +#define SW_SHADOW_R(d,p) (d)[46] = (p) +#define SW_MIDTONE_R(d,p) (d)[47] = (p) +#define SW_HIGHLIGHT_R(d,p) (d)[48] = (p) +#define SW_BRIGHTNESS_G(d,p) (d)[49] = (p) +#define SW_CONTRAST_G(d,p) (d)[50] = (p) +#define SW_EXPOSURE_G(d,p) (d)[51] = (p) +#define SW_SHADOW_G(d,p) (d)[52] = (p) +#define SW_MIDTONE_G(d,p) (d)[53] = (p) +#define SW_HIGHLIGHT_G(d,p) (d)[54] = (p) +#define SW_BRIGHTNESS_B(d,p) (d)[55] = (p) +#define SW_CONTRAST_B(d,p) (d)[56] = (p) +#define SW_EXPOSURE_B(d,p) (d)[57] = (p) +#define SW_SHADOW_B(d,p) (d)[58] = (p) +#define SW_MIDTONE_B(d,p) (d)[59] = (p) +#define SW_HIGHLIGHT_B(d,p) (d)[60] = (p) + + +/* READ IMAGE STATUS */ +#define RIS_SET_CMD(d) (d)[0] = 0x28; (d)[1] = 0x00; (d)[2] = 0x83; \ + (d)[3] = 0x00; (d)[4] = 0x00; (d)[5] = 0x00; \ + (d)[6] = 0x00; (d)[7] = 0x00; (d)[8] = 0x00; \ + (d)[9] = 0x00 +#define RIS_CMD_L 10 +#define RIS_SET_PCORMAC(d,p) (d)[4] |= (((p) << 7) & 0x80) +#define RIS_SET_COLOR(d,p) (d)[4] |= (((p) << 5) & 0x60) + + +/* REQUEST SENSE */ +#define RQS_CMD(d) (d)[0] = 0x03; (d)[1] = 0x00; (d)[2] = 0x00; \ + (d)[3] = 0x00; (d)[5] = 0x00 +#define RQS_CMD_L 6 +#define RQS_ALLOCLENGTH(d,p) (d)[4] = (p) + +#define RQS_LENGTH(s) (s)[7] + 7 + +#define RQS_SENSEKEY_NOSENSE 0x00 +#define RQS_SENSEKEY_HWERR 0x04 +#define RQS_SENSEKEY_ILLEGAL 0x05 +#define RQS_SENSEKEY_VENDOR 0x09 +#define RQS_SENSEKEY(s) ((s)[2] & 0x0f) + +#define RQS_INFO(s) ((s)[3] << 24) + ((s)[4] << 16) \ + + ((s)[5] << 8) + ((s)[6]) +#define RQS_ASL(s) (s)[7] +#define RQS_REMAINBYTES(s) ((s)[8] << 24) + ((s)[9] << 16) \ + + ((s)[10] << 8) + ((s)[11]) +#define RQS_ASC(s) (s)[12] +/* ASC == 0x40 */ +#define RQS_ASCQ_CPUERR 0x81 +#define RQS_ASCQ_SRAMERR 0x82 +#define RQS_ASCQ_DRAMERR 0x84 +#define RQS_ASCQ_DCOFF 0x88 +#define RQS_ASCQ_GAIN 0x90 +#define RQS_ASCQ_POS 0xa0 +#define RQS_ASCQ(s) (s)[13] + +#define RQS_ASINFO(s) &((s)[18]) +#define RQS_ASINFOLENGTH(s) (s)[7] - 11 + +/******************************************************************************/ +/* enumeration of Option Descriptors */ +/******************************************************************************/ + +enum Microtek2_Option +{ + /*0*/ + OPT_NUM_OPTS = 0, + + /*1*/OPT_MODE_GROUP, + OPT_SOURCE, + OPT_MODE, + OPT_BITDEPTH, + OPT_RESOLUTION, + OPT_Y_RESOLUTION, + OPT_PREVIEW, + + /*9*/ OPT_GEOMETRY_GROUP, + OPT_TL_X, /* top-left x */ + OPT_TL_Y, /* top-left y */ + OPT_BR_X, /* bottom-right x */ + OPT_BR_Y, /* bottom-right y */ + + /*14*/ OPT_ENHANCEMENT_GROUP, + OPT_BRIGHTNESS, + OPT_CONTRAST, + OPT_THRESHOLD, + OPT_HALFTONE, + OPT_AUTOADJUST, + + /*20*/ OPT_GAMMA_GROUP, + OPT_GAMMA_MODE, + OPT_GAMMA_SCALAR, + OPT_GAMMA_SCALAR_R, + OPT_GAMMA_SCALAR_G, + OPT_GAMMA_SCALAR_B, + OPT_GAMMA_CUSTOM, + OPT_GAMMA_CUSTOM_R, + OPT_GAMMA_CUSTOM_G, + OPT_GAMMA_CUSTOM_B, + OPT_GAMMA_BIND, + + /*31*/ OPT_SMH_GROUP, + /* these options must appear in exactly this order, */ + /* sane_control_option relies on it */ + OPT_CHANNEL, + OPT_SHADOW, + OPT_MIDTONE, + OPT_HIGHLIGHT, + OPT_SHADOW_R, + OPT_MIDTONE_R, + OPT_HIGHLIGHT_R, + OPT_SHADOW_G, + OPT_MIDTONE_G, + OPT_HIGHLIGHT_G, + OPT_SHADOW_B, + OPT_MIDTONE_B, + OPT_HIGHLIGHT_B, + OPT_EXPOSURE, + OPT_EXPOSURE_R, + OPT_EXPOSURE_G, + OPT_EXPOSURE_B, + + /*49*/ OPT_SPECIAL, + OPT_RESOLUTION_BIND, + OPT_DISABLE_BACKTRACK, + OPT_CALIB_BACKEND, + OPT_LIGHTLID35, + OPT_TOGGLELAMP, + + /*55*/ OPT_COLORBALANCE, + OPT_BALANCE_R, + OPT_BALANCE_G, + OPT_BALANCE_B, + OPT_BALANCE_FW, + + /*60*/ NUM_OPTIONS +}; + + +/******************************************************************************/ +/* Description of options not included in saneopts.h */ +/******************************************************************************/ + +#define M_TITLE_SCANMODEGRP SANE_I18N("Scan Mode") +#define M_TITLE_GEOMGRP SANE_I18N("Geometry") +#define M_TITLE_ENHANCEGRP SANE_I18N("Enhancement") +#define M_TITLE_SMHGRP SANE_I18N("Shadow, midtone, highlight,"\ + " exposure time"); +#define M_TITLE_SPECIALGRP SANE_I18N("Special options") +#define M_TITLE_COLBALANCEGRP SANE_I18N("Color balance") + +#define M_NAME_NOBACKTRACK "no-backtracking" +#define M_TITLE_NOBACKTRACK SANE_I18N("Disable backtracking") +#define M_DESC_NOBACKTRACK SANE_I18N("If checked the scanner does not" \ + " perform backtracking") + +#define M_NAME_TOGGLELAMP "toggle-lamp" +#define M_TITLE_TOGGLELAMP SANE_I18N("Toggle lamp of flatbed") +#define M_DESC_TOGGLELAMP SANE_I18N("Toggles the lamp of the flatbed") + +#define M_NAME_CALIBBACKEND "backend-calibration" +#define M_TITLE_CALIBBACKEND SANE_I18N("Calibration by backend") +#define M_DESC_CALIBBACKEND SANE_I18N("If checked the color calibration" \ + " before a scan is done by the backend") + +#define M_NAME_LIGHTLID35 "lightlid35" +#define M_TITLE_LIGHTLID35 SANE_I18N("Use the lightlid-35mm adapter") +#define M_DESC_LIGHTLID35 SANE_I18N("This option turns off the lamp of" \ + " the flatbed during a scan") + +#define M_NAME_QUALITY_SCAN "quality-scan" +#define M_TITLE_QUALITY_SCAN SANE_I18N("Quality scan") +#define M_DESC_QUALITY_SCAN SANE_I18N("Highest quality but lower speed") + +#define M_NAME_FAST_SCAN "fast-scan" +#define M_TITLE_FAST_SCAN SANE_I18N("Fast scan") +#define M_DESC_FAST_SCAN SANE_I18N("Highest speed but lower quality") + +#define M_NAME_AUTOADJUST "lineart-auto-adjust" +#define M_TITLE_AUTOADJUST SANE_I18N("Automatic adjustment of threshold") +#define M_DESC_AUTOADJUST SANE_I18N("If checked the backend automatically"\ + " tries to determine an optimal value for the" \ + " threshold.") + +#define M_NAME_GAMMA_MODE "gamma-correction" +#define M_TITLE_GAMMA_MODE SANE_I18N("Gamma correction") +#define M_DESC_GAMMA_MODE SANE_I18N("Selects the gamma correction mode.") + +#define M_NAME_GAMMA_BIND "bind-gamma" +#define M_TITLE_GAMMA_BIND SANE_I18N("Bind gamma") +#define M_DESC_GAMMA_BIND SANE_I18N("Use same gamma values for all" \ + " colour channels.") + +#define M_NAME_GAMMA_SCALAR "scalar-gamma" +#define M_TITLE_GAMMA_SCALAR SANE_I18N("Scalar gamma") +#define M_DESC_GAMMA_SCALAR SANE_I18N("Selects a value for scalar" \ + " gamma correction.") + +#define M_NAME_GAMMA_SCALAR_R "scalar-gamma-r" +#define M_TITLE_GAMMA_SCALAR_R SANE_I18N("Scalar gamma red") +#define M_DESC_GAMMA_SCALAR_R SANE_I18N("Selects a value for scalar gamma" \ + " correction (red channel)") + +#define M_NAME_GAMMA_SCALAR_G "scalar-gamma-g" +#define M_TITLE_GAMMA_SCALAR_G SANE_I18N("Scalar gamma green") +#define M_DESC_GAMMA_SCALAR_G SANE_I18N("Selects a value for scalar gamma" \ + " correction (green channel)") + +#define M_NAME_GAMMA_SCALAR_B "scalar-gamma-b" +#define M_TITLE_GAMMA_SCALAR_B SANE_I18N("Scalar gamma blue") +#define M_DESC_GAMMA_SCALAR_B SANE_I18N("Selects a value for scalar gamma" \ + " correction (blue channel)") + +#define M_NAME_CHANNEL "channel" +#define M_TITLE_CHANNEL SANE_I18N("Channel") +#define M_DESC_CHANNEL SANE_I18N("Selects the colour band, \"Master\"" \ + " means that all colours are affected.") + +#define M_NAME_MIDTONE "midtone" +#define M_TITLE_MIDTONE SANE_I18N("Midtone") +#define M_DESC_MIDTONE SANE_I18N("Selects which radiance level should" \ + " be considered \"50 % gray\".") + +#define M_NAME_MIDTONE_R "midtone-r" +#define M_TITLE_MIDTONE_R SANE_I18N("Midtone for red") +#define M_DESC_MIDTONE_R SANE_I18N("Selects which radiance level should" \ + " be considered \"50 % red\".") + +#define M_NAME_MIDTONE_G "midtone-g" +#define M_TITLE_MIDTONE_G SANE_I18N("Midtone for green") +#define M_DESC_MIDTONE_G SANE_I18N("Selects which radiance level should" \ + " be considered \"50 % green\".") + +#define M_NAME_MIDTONE_B "midtone-b" +#define M_TITLE_MIDTONE_B SANE_I18N("Midtone for blue") +#define M_DESC_MIDTONE_B SANE_I18N("Selects which radiance level should" \ + " be considered \"50 % blue\".") + +#define M_NAME_BALANCE_R "balance-r" +#define M_TITLE_BALANCE_R SANE_I18N("Red balance") +#define M_DESC_BALANCE_R SANE_I18N("Balance factor for red. A value of" \ + " 100% means no correction.") + +#define M_NAME_BALANCE_G "balance-g" +#define M_TITLE_BALANCE_G SANE_I18N("Green balance") +#define M_DESC_BALANCE_G SANE_I18N("Balance factor for green. A value of"\ + " 100% means no correction.") + +#define M_NAME_BALANCE_B "balance-b" +#define M_TITLE_BALANCE_B SANE_I18N("Blue balance") +#define M_DESC_BALANCE_B SANE_I18N("Balance factor for blue. A value of" \ + " 100% means no correction.") + +#define M_NAME_BALANCE_FW "balance-fw" +#define M_TITLE_BALANCE_FW SANE_I18N("Firmware balance") +#define M_DESC_BALANCE_FW SANE_I18N("Sets the color balance values to"\ + " the firmware provided values.") + +/******************************************************************************/ +/* Structure that contains global options */ +/******************************************************************************/ + +typedef struct Config_Options +{ + double strip_height; /* inch */ + char *no_backtracking; /* enable/disable option for */ + /* backtracking */ + char *lightlid35; /* enable/disable lightlid35 option */ + char *toggle_lamp; /* enable/disable lightlid35 option */ + char *backend_calibration; /* calibration by backend */ + char *auto_adjust; /* automatically choose threshold */ + char *colorbalance_adjust; /* color balance can be modified */ +} Config_Options; + + + +/******************************************************************************/ +/* Structure that is temporarily used, when the config file is parsed */ +/******************************************************************************/ + +typedef struct Config_Temp +{ + struct Config_Temp *next; + char *device; /* possible device name */ + Config_Options opts; /* options belonging to this device name */ + +} Config_Temp; + + +/******************************************************************************/ +/* scanner hardware info (as discovered by INQUIRY and READ ATTRIBUTES) */ +/******************************************************************************/ + +typedef struct Microtek2_Info { + /* from inquiry */ + SANE_Byte device_qualifier; +#define MI_DEVTYPE_SCANNER 0x06 + SANE_Byte device_type; +#define MI_SCSI_II_VERSION 0x02 + SANE_Byte scsi_version; + SANE_Char vendor[INQ_VENDOR_L + 1]; + SANE_Char model[INQ_MODEL_L + 1]; + SANE_Char revision[INQ_REV_L + 1]; + SANE_Byte model_code; + /* from read scanner attributes */ + SANE_Bool color; +#define MI_HAS_ONEPASS SANE_TRUE + SANE_Bool onepass; + /* the following 3 defines must correspond to byte 31 of SET WINDOW cmd */ +#define MI_TYPE_FLATBED 0x01 +#define MI_TYPE_SHEEDFEED 0x02 +#define MI_TYPE_TRANSPARENCY 0x03 + SANE_Byte scanner_type; +#define MI_HAS_FEPROM SANE_TRUE + SANE_Bool feprom; + /* MI_DATAFMT_X must correspond to Byte 0 in READ SCANNER ATTRIBUTE */ +#define MI_DATAFMT_CHUNKY 1 +#define MI_DATAFMT_LPLCONCAT 2 +#define MI_DATAFMT_LPLSEGREG 3 +#define MI_DATAFMT_9800 4 +#define MI_DATAFMT_WORDCHUNKY 5 + SANE_Byte data_format; +#define MI_COLSEQ_RED 0 +#define MI_COLSEQ_GREEN 1 +#define MI_COLSEQ_BLUE 2 +#define MI_COLSEQ_ILLEGAL 3 + uint8_t color_sequence[RSA_COLORSEQUENCE_L]; + SANE_Bool new_image_status; +#define MI_DATSEQ_RTOL 1 + uint8_t direction; + SANE_Byte ccd_gap; + SANE_Int max_xresolution; + SANE_Int max_yresolution; + SANE_Int geo_width; + SANE_Int geo_height; + SANE_Int opt_resolution; +#define MI_HASDEPTH_NIBBLE 1 +#define MI_HASDEPTH_10 2 +#define MI_HASDEPTH_12 4 +#define MI_HASDEPTH_16 8 +#define MI_HASDEPTH_14 16 /*This is not in Byte 13 of + scanner attributes but in + byte 48-bit0*/ + + SANE_Byte depth; +#define MI_LINEART_NONE(d) (((d) & 0x01) == 0) +#define MI_HASMODE_LINEART 1 +#define MI_HASMODE_HALFTONE 2 +#define MI_HASMODE_GRAY 4 +#define MI_HASMODE_COLOR 8 + SANE_Byte scanmode; + SANE_Int ccd_pixels; +#define MI_LUTCAP_NONE(d) ((d) == 0) +#define MI_LUTCAP_256B 1 +#define MI_LUTCAP_1024B 2 +#define MI_LUTCAP_1024W 4 +#define MI_LUTCAP_4096B 8 +#define MI_LUTCAP_4096W 16 +#define MI_LUTCAP_64k_W 32 +#define MI_LUTCAP_16k_W 64 +#define MI_LUTCAP_UNKNOWN 128 + SANE_Byte lut_cap; +#define MI_HAS_DNLDPTRN SANE_TRUE + SANE_Bool has_dnldptrn; + SANE_Byte grain_slct; +#define MI_OPTDEV_ADF 0x01 +#define MI_OPTDEV_TMA 0x02 +#define MI_OPTDEV_ADP 0x10 +#define MI_OPTDEV_APS 0x20 +#define MI_OPTDEV_STRIPE 0x40 +#define MI_OPTDEV_SLIDE 0x80 + SANE_Byte option_device; + SANE_Int calib_white; + SANE_Int calib_space; + SANE_Byte nlens; + SANE_Byte nwindows; + SANE_Byte shtrnsferequ; +#define MI_WHITE_SHADING_ONLY(x) ((x) & 0x20) == 0 +#define MI_HAS_SCNBTTN SANE_TRUE + SANE_Bool scnbuttn; +#define MI_HAS_PIPOBUF SANE_TRUE + SANE_Bool buftype; + uint16_t balance[3]; /* balance factor for red, green */ + /* and blue data */ + uint16_t aps_maxframes; + SANE_Int calib_divisor; /* e.g. the X12USL reads and sends */ + /* shading at 1/2 * opt_resolution */ +} Microtek2_Info; + +/******************************************************************************/ +/* device structure (one for each device in config file) */ +/******************************************************************************/ + +typedef struct Microtek2_Device { + struct Microtek2_Device *next; /* next, for linked list */ + +#define MD_SOURCE_FLATBED 0 +#define MD_SOURCE_ADF 1 +#define MD_SOURCE_TMA 2 +#define MD_SOURCE_SLIDE 3 +#define MD_SOURCE_STRIPE 4 + Microtek2_Info info[5]; /* detailed scanner spec */ + SANE_Device sane; /* SANE generic device block */ + char name[PATH_MAX]; /* name from config file */ + + SANE_Int *custom_gamma_table[4]; /* used for the custom gamma */ + /* values before a scan starts */ + /* the following two are derived from lut_cap */ + int max_lut_size; /* in bytes */ + int lut_entry_size; /* word or byte transfer in LUT */ + uint8_t scan_source; + double revision; + + /* basically the following two variables should go into the */ + /* Microtek2_Scanner structure, but their values must be retained */ + /* over several scans, and would be lost, if the application issues */ + /* a sane_close. */ + uint8_t *shading_table_w; /* shading table white */ + uint8_t *shading_table_d; /* shading table dark */ + uint8_t shading_table_contents; /* values like ms->mode */ + /* the following structure describes the device status */ +#define MD_TLAMP_ON 2 +#define MD_FLAMP_ON 1 +#define MD_NCALIB_ON 4 +#define MD_NTRACK_ON 8 +#define MD_STICK_ON 16 +#define MD_RESERVED17_ON 128 +#define MD_CURRENT_MODE_FLATBED 0 + struct { + uint8_t sskip; + uint8_t stick; + uint8_t ntrack; + uint8_t ncalib; + uint8_t tlamp; + uint8_t flamp; + uint8_t reserved17; + uint8_t rdyman; + uint8_t trdy; + uint8_t frdy; + uint8_t adp; + uint8_t detect; + uint8_t adptime; + uint8_t lensstatus; + uint8_t aloff; + uint8_t timeremain; + uint8_t tmacnt; + uint8_t paper; + uint8_t adfcnt; + uint8_t currentmode; + uint8_t buttoncount; + } status; + + /* The following defines are related to the model. Some models have */ + /* more or less subtle deviations from the spec, which are indicated */ + /* by these defines */ + uint32_t model_flags; +#define MD_NO_SLIDE_MODE 1 /* indicates that it has slide */ + /* mode, but it does not */ +#define MD_DATA_FORMAT_WRONG 2 /* X6 indicates wrong mode for TMA */ +#define MD_NO_ENHANCEMENTS 4 /* image enhancements do not work */ + /* (Brightness, contrast, .....) */ +#define MD_RII_TWO_BYTES 8 /* return some image information */ + /* in two byte */ +#define MD_NO_GAMMA 16 /* if device does not accept */ + /* gamma tables */ +#define MD_PHANTOM336CX_TYPE_SHADING 32 /* Phantom 336cx type shading */ +#define MD_READ_CONTROL_BIT 64 /* uses "read control bit" */ +#define MD_PHANTOM_C6 128 /* It is a Phantom C6 */ +#define MD_OFFSET_2 256 /* Image data starts 2 bytes */ + /* from the beginning of a */ + /* scanline */ +#define MD_X6_SHORT_TRANSFER 512 /* X6 USB crashes if you read + too much */ +#define MD_NO_RIS_COMMAND 1024 /* doesn't like read_image_status */ +#define MD_16BIT_TRANSFER 2048 /* transfers 10/12/14bit scans as */ + /* 16bit data */ +#define MD_CALIB_DIVISOR_600 4096 /* uses mi->calib_divisor=2 below + 600dpi */ + + size_t n_control_bytes; /* for read_control_bits; the */ + /* number is model dependent */ + /* and can not be inquired */ + uint32_t shading_length; /* length of the shading image */ + /* Phantom 336cx, C6, ... */ + uint8_t shading_depth; /* bit depth of shading image */ + uint8_t controlbit_offset; /* first relevant control bit */ + + +#define MD_MODESTRING_NUMS 4 +#define MD_MODESTRING_COLOR SANE_VALUE_SCAN_MODE_COLOR +#define MD_MODESTRING_GRAY SANE_VALUE_SCAN_MODE_GRAY +#define MD_MODESTRING_HALFTONE SANE_VALUE_SCAN_MODE_HALFTONE +#define MD_MODESTRING_LINEART SANE_VALUE_SCAN_MODE_LINEART + SANE_String_Const scanmode_list[MD_MODESTRING_NUMS + 1]; + +#define MD_DEPTHVAL_NUMS 6 +#define MD_DEPTHVAL_16 16 +#define MD_DEPTHVAL_14 14 +#define MD_DEPTHVAL_12 12 +#define MD_DEPTHVAL_10 10 +#define MD_DEPTHVAL_8 8 +#define MD_DEPTHVAL_4 4 + SANE_Int bitdepth_list[MD_DEPTHVAL_NUMS + 1]; + +#define MD_SOURCESTRING_NUMS 5 +#define MD_SOURCESTRING_FLATBED "Flatbed" +#define MD_SOURCESTRING_ADF "ADF" +#define MD_SOURCESTRING_TMA "TMA" +#define MD_SOURCESTRING_STRIPE "Filmstrip" +#define MD_SOURCESTRING_SLIDE "Slide" + SANE_String_Const scansource_list[MD_SOURCESTRING_NUMS + 1]; + +#define MD_HALFTONE_NUMS 12 +#define MD_HALFTONE0 "53-dot screen (53 gray levels)" +#define MD_HALFTONE1 "Horiz. screen (65 gray levels)" +#define MD_HALFTONE2 "Vert. screen (65 gray levels)" +#define MD_HALFTONE3 "Mixed page (33 gray levels)" +#define MD_HALFTONE4 "71-dot screen (29 gray levels)" +#define MD_HALFTONE5 "60-dot #1 (26 gray levels)" +#define MD_HALFTONE6 "60-dot #2 (26 gray levels)" +#define MD_HALFTONE7 "Fine detail #1 (17 gray levels)" +#define MD_HALFTONE8 "Fine detail #2 (17 gray levels)" +#define MD_HALFTONE9 "Slant line (17 gray levels)" +#define MD_HALFTONE10 "Posterizing (10 gray levels)" +#define MD_HALFTONE11 "High Contrast (5 gray levels)" + SANE_String_Const halftone_mode_list[MD_HALFTONE_NUMS + 1]; + +#define MD_CHANNEL_NUMS 4 +#define MD_CHANNEL_MASTER "Master" +#define MD_CHANNEL_RED "Red" +#define MD_CHANNEL_GREEN "Green" +#define MD_CHANNEL_BLUE "Blue" + SANE_String_Const channel_list[MD_CHANNEL_NUMS + 1]; + +#define MD_GAMMAMODE_NUMS 3 +#define MD_GAMMAMODE_LINEAR "None" +#define MD_GAMMAMODE_SCALAR "Scalar" +#define MD_GAMMAMODE_CUSTOM "Custom" + SANE_String_Const gammamode_list[MD_GAMMAMODE_NUMS + 1]; + + SANE_Range x_res_range_dpi; /* X resolution in dpi */ + SANE_Range y_res_range_dpi; /* Y resolution in dpi */ + SANE_Range x_range_mm; /* scan width in mm */ + SANE_Range y_range_mm; /* scan height in mm */ + SANE_Range percentage_range; /* for brightness, shadow, ... */ + SANE_Range custom_gamma_range; /* for custom gamma values */ + SANE_Range scalar_gamma_range; /* for scalar gamma values */ + SANE_Range shadow_range; /* shadow of blue channel */ + SANE_Range midtone_range; /* midtone shadow of blue channel */ + SANE_Range exposure_range; /* for lengthening exposure time */ + SANE_Range highlight_range; /* highlight of master channel */ + SANE_Range threshold_range; /* 1 - 255 */ + SANE_Range balance_range; /* for user provided color balance */ + Config_Options opts; /* options from the config file */ + SANE_Word opt_backend_calib_default; /* corresponds to scanner model */ + SANE_Word opt_no_backtrack_default; /* corresponds to scanner model */ +} Microtek2_Device; + + + +/******************************************************************************/ +/* scanner structure (one for each device in use) */ +/* ....all the state needed to define a scan request */ +/******************************************************************************/ + +typedef struct Microtek2_Scanner { + struct Microtek2_Scanner *next; /* for linked list */ + Microtek2_Device *dev; /* raw device info */ + Option_Value val[NUM_OPTIONS + 1]; /* option values for session */ + SANE_Parameters params; /* format, lastframe, lines, depth, ppl, bpl */ + SANE_Option_Descriptor sod[NUM_OPTIONS + 1]; /* option list for session */ + + uint8_t *gamma_table; + uint8_t *shading_image; /* used for shading image */ + uint8_t *condensed_shading_w; /* used when a model uses "read */ + uint8_t *condensed_shading_d; /* control bit", stores the relevant */ + /* shading pixels for each color */ + uint8_t *temporary_buffer; /* used when automatic adjustment */ + /* is selected */ + char *gamma_mode; /* none, linear or custom */ + +/* the following defines must correspond to byte 25 of SET WINDOW body */ +#define MS_MODE_LINEART 0x00 +#define MS_MODE_HALFTONE 0x01 +#define MS_MODE_GRAY 0x02 +#define MS_MODE_LINEARTFAKE 0x12 /* no real mode */ +#define MS_MODE_COLOR 0x05 + +/* the following defines must correspond to byte 31 of SET WINDOW body */ +#define MS_SOURCE_FLATBED 0x00 +#define MS_SOURCE_ADF 0x01 +#define MS_SOURCE_TMA 0x02 +#define MS_SOURCE_STRIPE 0x05 +#define MS_SOURCE_SLIDE 0x06 + + SANE_Int mode; + SANE_Int depth; + SANE_Int x_resolution_dpi; + SANE_Int y_resolution_dpi; + SANE_Int x1_dots; /* x-position in units of optical resolution */ + SANE_Int y1_dots; /* same for y-position */ + SANE_Int width_dots; /* scan width in units of optical resolution */ + SANE_Int height_dots; /* same for height */ + uint8_t brightness_m; + uint8_t contrast_m; + uint8_t exposure_m; + uint8_t shadow_m; + uint8_t midtone_m; + uint8_t highlight_m; + uint8_t brightness_r; + uint8_t contrast_r; + uint8_t exposure_r; + uint8_t shadow_r; + uint8_t midtone_r; + uint8_t highlight_r; + uint8_t brightness_g; + uint8_t contrast_g; + uint8_t exposure_g; + uint8_t shadow_g; + uint8_t midtone_g; + uint8_t highlight_g; + uint8_t brightness_b; + uint8_t contrast_b; + uint8_t exposure_b; + uint8_t shadow_b; + uint8_t midtone_b; + uint8_t highlight_b; + uint8_t threshold; + + SANE_Bool use_external_ht; + SANE_Byte internal_ht_index; + uint8_t stay; + uint8_t rawdat; + SANE_Bool quality; + SANE_Bool fastscan; + SANE_Byte scan_source; + uint8_t no_backtracking; + uint8_t lightlid35; + uint8_t auto_adjust; + uint8_t calib_backend; + uint8_t colorbalance_adjust; + int current_pass; /* current pass if 3-pass scan */ + int lut_size; /* size of gamma lookup table */ + int lut_entry_size; /* size of one entry in lookup table */ + uint32_t lut_size_bytes; /* size of LUT in bytes */ + uint8_t word; /* word transfer, used in some read cmds */ + /* MS_COLOR_X must correspond to color field in READ IMAGE STATUS */ +#define MS_COLOR_RED 0 +#define MS_COLOR_GREEN 1 +#define MS_COLOR_BLUE 2 +#define MS_COLOR_ALL 3 + uint8_t current_color; /* for gamma calc. and 3-pass scanners */ + uint8_t current_read_color; /* dto, for RI and RIS */ + uint8_t dark; /* is 1 for reading dark shading */ + uint32_t ppl; /* pixels per line as returned by RII */ + uint32_t bpl; /* bytes per line as returned by RII */ + uint32_t remaining_bytes; /* remaining bytes as returned by RII */ + uint32_t real_remaining_bytes;/* bytes to transfer to the frontend */ + uint32_t real_bpl; /* bpl to transfer to the frontend */ + SANE_Int src_remaining_lines; /* remaining lines to read */ + SANE_Int src_lines_to_read; /* actual number of lines read */ + SANE_Int src_max_lines; /* maximum number of lines that fit */ + /* into the scsi buffer */ + /* sent to the frontend */ + int bits_per_pixel_in; /* bits per pixel transferred from scanner */ + int bits_per_pixel_out; /* bits per pixel transf. to frontend */ + uint32_t src_buffer_size; /* size of the buffer */ + int transfer_length; /* transfer length for RI command */ + uint8_t balance[3]; /* user provided balance factor for */ + /* red, green and blue data */ + struct { + uint8_t *src_buffer[2]; /* two buffers because of CCD gap */ + uint8_t *src_buf; + int current_src; + SANE_Int free_lines; + SANE_Int free_max_lines; + uint8_t *current_pos[3]; /* actual position in the source buffer */ + int planes[2][3]; /* # of red, green, blue planes in the */ + /* current source buffer and leftover */ + /* planes from previous "read image" */ + } buf; + + SANE_Bool onepass; + + size_t n_control_bytes; /* for READ CONTROL BITS */ + uint8_t *control_bytes; /* pointer to the result */ + + int scanning; /* true == between sane_start & sane_read=EOF */ + int cancelled; + int sfd; /* SCSI filedescriptor */ + int fd[2]; /* file descriptors for pipe */ + SANE_Pid pid; /* pid of child process */ + FILE *fp; + +} Microtek2_Scanner; + +/******************************************************************************/ +/* Function prototypes */ +/******************************************************************************/ + +static SANE_Status +add_device_list(SANE_String_Const, Microtek2_Device **); + +static SANE_Status +attach(Microtek2_Device *); + +static SANE_Status +attach_one (const char *); + +static SANE_Status +auto_adjust_proc_data (Microtek2_Scanner *, uint8_t **); + +static SANE_Status +calc_cx_shading_line(Microtek2_Scanner *); /* (KF) new */ + +static SANE_Status +calculate_gamma(Microtek2_Scanner *, uint8_t *, int, char *); + +static SANE_Status +calculate_sane_params(Microtek2_Scanner *); + +static SANE_Status +cancel_scan(Microtek2_Scanner *); + +static SANE_Status +check_inquiry(Microtek2_Device *, SANE_String *); + +static void +check_option(const char *, Config_Options *); + +static SANE_Status +chunky_copy_pixels(Microtek2_Scanner *, uint8_t *); + +static SANE_Status +chunky_proc_data(Microtek2_Scanner *); + +#if 0 +static void +chunky_set_exposure(uint8_t *, uint32_t, uint8_t, uint8_t, int); +#endif + +static void +cleanup_scanner(Microtek2_Scanner *); + +static SANE_Status +condense_shading(Microtek2_Scanner *); + +#ifdef HAVE_AUTHORIZATION +static SANE_Status +do_authorization(char *); +#endif + +static SANE_Status +read_shading_image(Microtek2_Scanner *); + +static SANE_Status +dump_area(uint8_t *, int, char *); + +static SANE_Status +dump_area2(uint8_t *, int, char *); + +/* currently not used */ +#if 0 +static SANE_Status +dump_to_file(uint8_t *, int, char *, char *); +#endif + +static SANE_Status +dump_attributes(Microtek2_Info *); + +static void +get_calib_params(Microtek2_Scanner *); + +static SANE_Status +get_cshading_values(Microtek2_Scanner *,uint8_t, uint32_t, float, int, + float *, float *); /* (KF) new */ +static SANE_Status +get_scan_mode_and_depth(Microtek2_Scanner *, int *, SANE_Int *, int *, int *); + +static SANE_Status +get_scan_parameters(Microtek2_Scanner *); + +static SANE_Status +get_lut_size(Microtek2_Info *, int *, int *); + +static SANE_Status +gray_copy_pixels(Microtek2_Scanner *ms, uint8_t *, int, int); + +static SANE_Status +gray_proc_data(Microtek2_Scanner *); + +#if 0 +static void +gray_set_exposure(uint8_t *, uint32_t, uint8_t, uint8_t); +#endif + +static SANE_Status +init_options(Microtek2_Scanner *, uint8_t); + +static SANE_Status +lineartfake_copy_pixels(Microtek2_Scanner *, uint8_t *, uint32_t, uint8_t, + int, FILE *); + +static SANE_Status +lineartfake_proc_data(Microtek2_Scanner *); + +static SANE_Status +lplconcat_copy_pixels(Microtek2_Scanner *, uint8_t **, int, int); + +static SANE_Status +lplconcat_proc_data(Microtek2_Scanner *ms); + +static size_t +max_string_size (const SANE_String_Const * /* strings[] */); + +static void +parse_config_file(FILE *, Config_Temp **); + +static SANE_Status +prepare_buffers(Microtek2_Scanner *); + +static SANE_Status +prepare_shading_data(Microtek2_Scanner *, uint32_t, uint8_t **); + +static SANE_Status +proc_onebit_data(Microtek2_Scanner *); + +static SANE_Status +read_cx_shading_image(Microtek2_Scanner *); + +static SANE_Status +read_cx_shading(Microtek2_Scanner *); + +static int +reader_process(void *); + +static SANE_Status +restore_gamma_options(SANE_Option_Descriptor *, Option_Value *); + +static SANE_Status +segreg_copy_pixels(Microtek2_Scanner *); + +static SANE_Status +segreg_proc_data(Microtek2_Scanner *ms); + +static void +set_exposure(Microtek2_Scanner *); + +static SANE_Status +set_option_dependencies(Microtek2_Scanner *, + SANE_Option_Descriptor *, Option_Value *); + +static SANE_Status +shading_function(Microtek2_Scanner *, uint8_t *); + +static RETSIGTYPE +signal_handler (int); + +static SANE_Status +wordchunky_copy_pixels(uint8_t *, uint32_t, int, FILE *); + +static SANE_Status +wordchunky_proc_data(Microtek2_Scanner *); + +typedef int (*qsortfunc)(const void *, const void *); + +static int compare_func_16(const uint16_t *p1, uint16_t *p2) + { + return ( *p1 - *p2 ); + } + + +/******************************************************************************/ +/* Function prototypes for basic SCSI commands */ +/******************************************************************************/ + +static SANE_Status +scsi_inquiry(Microtek2_Info *, char *); + +static SANE_Status +scsi_read_attributes(Microtek2_Info *, char *, uint8_t); + +static SANE_Status +scsi_read_control_bits(Microtek2_Scanner *); + +/* currently not used */ +/* static SANE_Status +scsi_read_gamma(Microtek2_Scanner *); */ + +static SANE_Status +scsi_read_image(Microtek2_Scanner *, uint8_t *, int); + +static SANE_Status +scsi_read_image_info(Microtek2_Scanner *); + +static SANE_Status +scsi_read_image_status(Microtek2_Scanner *); + +static SANE_Status +scsi_read_system_status(Microtek2_Device *, int); + +/* currently not used */ +/* static SANE_Status +scsi_request_sense(Microtek2_Scanner *); */ + +static SANE_Status +scsi_send_gamma(Microtek2_Scanner *); + +static SANE_Status +scsi_send_shading(Microtek2_Scanner *, uint8_t *, uint32_t, uint8_t); + +static SANE_Status +scsi_read_shading(Microtek2_Scanner *, uint8_t *, uint32_t); + +static SANE_Status +scsi_send_system_status(Microtek2_Device *, int); + +static SANE_Status +scsi_sense_handler (int, u_char *, void *); + +static SANE_Status +scsi_test_unit_ready(Microtek2_Device *); + +static SANE_Status +scsi_set_window(Microtek2_Scanner *, int); + +static SANE_Status +scsi_wait_for_image(Microtek2_Scanner *); + +#endif |