From 58912f68c2489bcee787599837447e0d64dfd61a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Wed, 24 May 2017 21:03:56 +0200 Subject: New upstream version 1.0.27 --- backend/fujitsu.c | 629 +++++++++++++++++++++++++++++------------------------- 1 file changed, 337 insertions(+), 292 deletions(-) (limited to 'backend/fujitsu.c') diff --git a/backend/fujitsu.c b/backend/fujitsu.c index 9fddb1c..433f75a 100644 --- a/backend/fujitsu.c +++ b/backend/fujitsu.c @@ -6,7 +6,7 @@ Copyright (C) 2000 Randolph Bentson Copyright (C) 2001 Frederik Ramm Copyright (C) 2001-2004 Oliver Schirrmeister - Copyright (C) 2003-2014 m. allan noah + Copyright (C) 2003-2016 m. allan noah JPEG output and low memory usage support funded by: Archivista GmbH, www.archivista.ch @@ -574,9 +574,32 @@ v126 2015-08-23, MAN - initial support for iX100 - add late_lut support for iX500/iX100 - v127 2015-08-25, MAN + v127 2015-08-25, MAN (SANE 1.0.25) - separate iX100 from iX500 settings - iX100 has gray and lineart + v128 2015-11-08, MAN + - do not ask fi-4340 for serial number + v129 2015-11-21, MAN + - br_x and br_y locked to page_width/height until changed + v130 2016-02-23, MAN + - run init_model before init_ms so some scanners can override + - set all M309x and M409x scanners s->broken_diag_serial = 1 + v131 2016-06-06, MAN + - hide compression-arg option when jpeg disabled + - add Send/SC/GHS macros for recent scanners + - add initial support for fi-74x0 + - add initial support for fi-7030 + - set has_MS_lamp=0 for fi-71x0 + - add I18N macros to all option titles and descriptions + v132 2016-10-07, MAN + - remove ipc_mode option and variables + - set ipc mode based on other options + - cleanup inverted logic DTC options + - fixes threshold option reported in #315069 + v133 2017-04-08, MAN + - initial support for fi-7600/7700 + - autodetect various double feed capabilities using VPD + - call send_lut if we are using a downloaded gamma table SANE FLOW DIAGRAM @@ -626,7 +649,7 @@ #include "fujitsu.h" #define DEBUG 1 -#define BUILD 127 +#define BUILD 133 /* values for SANE_DEBUG_FUJITSU env var: - errors 5 @@ -990,22 +1013,22 @@ attach_one (const char *device_name, int connType) return ret; } - /* see what mode pages device supports */ - ret = init_ms (s); + /* clean up the scanner struct based on model */ + /* this is the only piece of model specific code */ + ret = init_model (s); if (ret != SANE_STATUS_GOOD) { disconnect_fd(s); free (s); - DBG (5, "attach_one: ms failed\n"); + DBG (5, "attach_one: model failed\n"); return ret; } - /* clean up the scanner struct based on model */ - /* this is the only piece of model specific code */ - ret = init_model (s); + /* see what mode pages device supports */ + ret = init_ms (s); if (ret != SANE_STATUS_GOOD) { disconnect_fd(s); free (s); - DBG (5, "attach_one: model failed\n"); + DBG (5, "attach_one: ms failed\n"); return ret; } @@ -1682,6 +1705,9 @@ init_vpd (struct fujitsu *s) DBG (15, " skew check: %d\n", get_IN_skew_check(in)); DBG (15, " new feed roller: %d\n", get_IN_new_fd_roll(in)); + + s->has_adv_paper_prot = get_IN_paper_prot_2(in); + DBG (15, " paper protection: %d\n", s->has_adv_paper_prot); } if (get_IN_page_length (in) > 0x70-5) { @@ -1689,7 +1715,10 @@ init_vpd (struct fujitsu *s) DBG (15, " paper count: %d\n", get_IN_paper_count(in)); DBG (15, " paper number: %d\n", get_IN_paper_number(in)); DBG (15, " ext send to: %d\n", get_IN_ext_send_to(in)); - DBG (15, " staple det: %d\n", get_IN_staple_det(in)); + + s->has_staple_detect = get_IN_staple_det(in); + DBG (15, " staple det: %d\n", s->has_staple_detect); + DBG (15, " pause host: %d\n", get_IN_pause_host(in)); DBG (15, " pause panel: %d\n", get_IN_pause_panel(in)); DBG (15, " pause conf: %d\n", get_IN_pause_conf(in)); @@ -1701,7 +1730,9 @@ init_vpd (struct fujitsu *s) DBG (15, " imprint chk b: %d\n", get_IN_imprint_chk_b(in)); DBG (15, " imprint chk f: %d\n", get_IN_imprint_chk_f(in)); DBG (15, " force w bg: %d\n", get_IN_force_w_bg(in)); - DBG (15, " mf recover lvl: %d\n", get_IN_mf_recover_lvl(in)); + + s->has_df_recovery = get_IN_mf_recover_lvl(in); + DBG (15, " mf recover lvl: %d\n", s->has_df_recovery); DBG (15, " first read time: %d\n", get_IN_first_read_time(in)); DBG (15, " div scanning: %d\n", get_IN_div_scanning(in)); @@ -1720,7 +1751,7 @@ init_vpd (struct fujitsu *s) DBG (15, " sync next feed: %d\n", get_IN_sync_next_feed(in)); s->has_op_halt = get_IN_op_halt(in); - DBG (15, " object postion halt: %d\n", s->has_op_halt); + DBG (15, " object position halt: %d\n", s->has_op_halt); } ret = SANE_STATUS_GOOD; @@ -2014,19 +2045,12 @@ init_model (struct fujitsu *s) /* if scanner has built-in gamma tables, we use the first one (0) */ /* otherwise, we use the first downloaded one (0x80) */ - /* note that you may NOT need to send the table to use it? */ + /* note that you may NOT need to send the table to use it, */ + /* the scanner will fall back to the brightness/contrast LUT */ if (!s->num_internal_gamma && s->num_download_gamma){ s->window_gamma = 0x80; } - /* older scanners would enable their highest */ - /* IPC mode by default. Newer scanners don't, */ - /* so we go ahead and turn it on. */ - if (s->has_sdtc) - s->ipc_mode = WD_ipc_SDTC; - else if (s->has_dtc) - s->ipc_mode = WD_ipc_DTC; - /* endorser type tells string length (among other things) */ if(s->has_endorser_b){ /*old-style is 40 bytes*/ @@ -2141,6 +2165,9 @@ init_model (struct fujitsu *s) else if ( strstr (s->model_name, "M309") || strstr (s->model_name, "M409")){ + /* weirdness */ + s->broken_diag_serial = 1; + /* lies */ s->adbits = 8; } @@ -2160,7 +2187,8 @@ init_model (struct fujitsu *s) s->max_y_fb = 14032; } - else if (strstr (s->model_name, "fi-4750") ) { + else if (strstr (s->model_name,"fi-4340") + || strstr (s->model_name, "fi-4750") ) { /* weirdness */ s->broken_diag_serial = 1; } @@ -2265,10 +2293,8 @@ init_model (struct fujitsu *s) } else if (strstr (s->model_name,"fi-6800") - || strstr (s->model_name,"fi-5900")){ /* guessing this scanner too */ - /* missing from vpd */ - s->has_staple_detect=1; /* may not actually work? */ - s->has_df_recovery=1; + || strstr (s->model_name,"fi-5900")){ + /* do not need overrides */ } else if (strstr (s->model_name,"iX500")){ @@ -2316,6 +2342,8 @@ init_model (struct fujitsu *s) else if (strstr (s->model_name,"fi-7180") || strstr (s->model_name,"fi-7160")){ + /* locks up scanner if we try to auto detect */ + s->has_MS_lamp = 0; /* weirdness */ /* these machines have longer max paper at lower res */ @@ -2325,10 +2353,6 @@ init_model (struct fujitsu *s) s->max_y_by_res[2].len = 260268; s->max_y_by_res[3].res = 200; s->max_y_by_res[3].len = 266268; - - /* missing from vpd */ - s->has_df_recovery=1; - s->has_adv_paper_prot=1; } else if (strstr (s->model_name,"fi-7280") @@ -2344,12 +2368,48 @@ init_model (struct fujitsu *s) s->max_y_by_res[3].len = 266268; /* missing from vpd */ - s->has_df_recovery=1; - s->has_adv_paper_prot=1; s->max_x_fb = 10764; s->max_y_fb = 14032; /* some scanners can be slightly more? */ } + else if (strstr (s->model_name,"fi-7480") + || strstr (s->model_name,"fi-7460")){ + + /* weirdness */ + /* these machines have longer max paper at lower res */ + s->max_y_by_res[1].res = 400; + s->max_y_by_res[1].len = 194268; + s->max_y_by_res[2].res = 300; + s->max_y_by_res[2].len = 260268; + s->max_y_by_res[3].res = 200; + s->max_y_by_res[3].len = 266268; + } + + else if (strstr (s->model_name,"fi-7030")){ + + /* weirdness */ + /* these machines have longer max paper at lower res */ + s->max_y_by_res[1].res = 400; + s->max_y_by_res[1].len = 192000; + s->max_y_by_res[2].res = 300; + s->max_y_by_res[2].len = 258000; + s->max_y_by_res[3].res = 200; + s->max_y_by_res[3].len = 264000; + } + + else if (strstr (s->model_name,"fi-7700") + || strstr (s->model_name,"fi-7600")){ + + /* weirdness */ + /* these machines have longer max paper at lower res */ + s->max_y_by_res[1].res = 400; + s->max_y_by_res[1].len = 192000; + s->max_y_by_res[2].res = 300; + s->max_y_by_res[2].len = 258000; + s->max_y_by_res[3].res = 200; + s->max_y_by_res[3].len = 264000; + } + DBG (10, "init_model: finish\n"); return SANE_STATUS_GOOD; @@ -2439,11 +2499,6 @@ init_user (struct fujitsu *s) s->u_endorser_dir=DIR_TTB; strcpy((char *)s->u_endorser_string,"%05ud"); - /* inverted logic ipc settings */ - s->noise_removal = 1; - s->bp_filter = 1; - s->smoothing = 1; - /* more recent machines default to this being 'on', * * which causes the scanner to ingest multiple pages * * even when the user only wants one */ @@ -3039,8 +3094,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) /* gamma */ if(option==OPT_GAMMA){ opt->name = "gamma"; - opt->title = "Gamma function exponent"; - opt->desc = "Changes intensity of midtones"; + opt->title = SANE_I18N ("Gamma function exponent"); + opt->desc = SANE_I18N ("Changes intensity of midtones"); opt->type = SANE_TYPE_FIXED; opt->unit = SANE_UNIT_NONE; opt->constraint_type = SANE_CONSTRAINT_RANGE; @@ -3089,8 +3144,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) /* =============== common ipc params ================================ */ if(option==OPT_RIF){ opt->name = "rif"; - opt->title = "RIF"; - opt->desc = "Reverse image format"; + opt->title = SANE_I18N ("RIF"); + opt->desc = SANE_I18N ("Reverse image format"); opt->type = SANE_TYPE_BOOL; opt->unit = SANE_UNIT_NONE; if (s->has_rif) @@ -3107,8 +3162,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) s->ht_type_list[i]=NULL; opt->name = "ht-type"; - opt->title = "Halftone type"; - opt->desc = "Control type of halftone filter"; + opt->title = SANE_I18N ("Halftone type"); + opt->desc = SANE_I18N ("Control type of halftone filter"); opt->type = SANE_TYPE_STRING; opt->unit = SANE_UNIT_NONE; @@ -3128,8 +3183,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) if(option==OPT_HT_PATTERN){ opt->name = "ht-pattern"; - opt->title = "Halftone pattern"; - opt->desc = "Control pattern of halftone filter"; + opt->title = SANE_I18N ("Halftone pattern"); + opt->desc = SANE_I18N ("Control pattern of halftone filter"); opt->type = SANE_TYPE_INT; opt->unit = SANE_UNIT_NONE; @@ -3151,8 +3206,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) if(option==OPT_OUTLINE){ opt->name = "outline"; - opt->title = "Outline"; - opt->desc = "Perform outline extraction"; + opt->title = SANE_I18N ("Outline"); + opt->desc = SANE_I18N ("Perform outline extraction"); opt->type = SANE_TYPE_BOOL; opt->unit = SANE_UNIT_NONE; if (s->has_outline) @@ -3163,8 +3218,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) if(option==OPT_EMPHASIS){ opt->name = "emphasis"; - opt->title = "Emphasis"; - opt->desc = "Negative to smooth or positive to sharpen image"; + opt->title = SANE_I18N ("Emphasis"); + opt->desc = SANE_I18N ("Negative to smooth or positive to sharpen image"); opt->type = SANE_TYPE_INT; opt->unit = SANE_UNIT_NONE; @@ -3182,8 +3237,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) if(option==OPT_SEPARATION){ opt->name = "separation"; - opt->title = "Separation"; - opt->desc = "Enable automatic separation of image and text"; + opt->title = SANE_I18N ("Separation"); + opt->desc = SANE_I18N ("Enable automatic separation of image and text"); opt->type = SANE_TYPE_BOOL; opt->unit = SANE_UNIT_NONE; if (s->has_autosep) @@ -3194,8 +3249,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) if(option==OPT_MIRRORING){ opt->name = "mirroring"; - opt->title = "Mirroring"; - opt->desc = "Reflect output image horizontally"; + opt->title = SANE_I18N ("Mirroring"); + opt->desc = SANE_I18N ("Reflect output image horizontally"); opt->type = SANE_TYPE_BOOL; opt->unit = SANE_UNIT_NONE; if (s->has_mirroring) @@ -3212,8 +3267,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) s->wl_follow_list[i]=NULL; opt->name = "wl-follow"; - opt->title = "White level follower"; - opt->desc = "Control white level follower"; + opt->title = SANE_I18N ("White level follower"); + opt->desc = SANE_I18N ("Control white level follower"); opt->type = SANE_TYPE_STRING; opt->unit = SANE_UNIT_NONE; @@ -3227,50 +3282,18 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) opt->cap = SANE_CAP_INACTIVE; } - if(option==OPT_IPC_MODE){ - i=0; - s->ipc_mode_list[i++]=STRING_DEFAULT; - if(s->has_dtc){ - s->ipc_mode_list[i++]=STRING_DTC; - } - if(s->has_sdtc){ - s->ipc_mode_list[i++]=STRING_SDTC; - } - s->ipc_mode_list[i]=NULL; - - opt->name = "ipc-mode"; - opt->title = "IPC mode"; - opt->desc = "Image processing mode, enables additional options"; - opt->type = SANE_TYPE_STRING; - opt->unit = SANE_UNIT_NONE; - - opt->constraint_type = SANE_CONSTRAINT_STRING_LIST; - opt->constraint.string_list = s->ipc_mode_list; - opt->size = maxStringSize (opt->constraint.string_list); - - if ( i > 2 ){ - opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; - if(s->s_mode != MODE_HALFTONE && s->s_mode != MODE_LINEART){ - opt->cap |= SANE_CAP_INACTIVE; - } - } - else - opt->cap = SANE_CAP_INACTIVE; - } - /* =============== DTC params ================================ */ /* enabled when in dtc mode (manually or by default) */ if(option==OPT_BP_FILTER){ opt->name = "bp-filter"; - opt->title = "BP filter"; - opt->desc = "Improves quality of high resolution ball-point pen text"; + opt->title = SANE_I18N ("BP filter"); + opt->desc = SANE_I18N ("Improves quality of high resolution ball-point pen text"); opt->type = SANE_TYPE_BOOL; opt->unit = SANE_UNIT_NONE; if ( s->has_dtc ){ opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; - if(s->ipc_mode == WD_ipc_SDTC - || (s->has_sdtc && s->ipc_mode == WD_ipc_DEFAULT)){ + if(get_ipc_mode(s) == WD_ipc_SDTC){ opt->cap |= SANE_CAP_INACTIVE; } } @@ -3280,15 +3303,14 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) if(option==OPT_SMOOTHING){ opt->name = "smoothing"; - opt->title = "Smoothing"; - opt->desc = "Enable smoothing for improved OCR"; + opt->title = SANE_I18N ("Smoothing"); + opt->desc = SANE_I18N ("Enable smoothing for improved OCR"); opt->type = SANE_TYPE_BOOL; opt->unit = SANE_UNIT_NONE; if ( s->has_dtc ){ opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; - if(s->ipc_mode == WD_ipc_SDTC - || (s->has_sdtc && s->ipc_mode == WD_ipc_DEFAULT)){ + if(get_ipc_mode(s) == WD_ipc_SDTC){ opt->cap |= SANE_CAP_INACTIVE; } } @@ -3298,9 +3320,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) if(option==OPT_GAMMA_CURVE){ opt->name = "gamma-curve"; - opt->title = "Gamma curve"; - opt->desc = "Gamma curve"; - opt->desc = "Gamma curve, from light to dark, but upper two may not work"; + opt->title = SANE_I18N ("Gamma curve"); + opt->desc = SANE_I18N ("Gamma curve, from light to dark, but upper two may not work"); opt->type = SANE_TYPE_INT; opt->unit = SANE_UNIT_NONE; @@ -3312,8 +3333,7 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) if ( s->has_dtc ){ opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; - if(s->ipc_mode == WD_ipc_SDTC - || (s->has_sdtc && s->ipc_mode == WD_ipc_DEFAULT)){ + if(get_ipc_mode(s) == WD_ipc_SDTC){ opt->cap |= SANE_CAP_INACTIVE; } } @@ -3323,8 +3343,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) if(option==OPT_THRESHOLD_CURVE){ opt->name = "threshold-curve"; - opt->title = "Threshold curve"; - opt->desc = "Threshold curve, from light to dark, but upper two may not be linear"; + opt->title = SANE_I18N ("Threshold curve"); + opt->desc = SANE_I18N ("Threshold curve, from light to dark, but upper two may not be linear"); opt->type = SANE_TYPE_INT; opt->unit = SANE_UNIT_NONE; @@ -3336,8 +3356,7 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) if ( s->has_dtc ){ opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; - if(s->ipc_mode == WD_ipc_SDTC - || (s->has_sdtc && s->ipc_mode == WD_ipc_DEFAULT)){ + if(get_ipc_mode(s) == WD_ipc_SDTC){ opt->cap |= SANE_CAP_INACTIVE; } } @@ -3347,15 +3366,14 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) if(option==OPT_THRESHOLD_WHITE){ opt->name = "threshold-white"; - opt->title = "Threshold white"; - opt->desc = "Set pixels equal to threshold to white instead of black"; + opt->title = SANE_I18N ("Threshold white"); + opt->desc = SANE_I18N ("Set pixels equal to threshold to white instead of black"); opt->type = SANE_TYPE_BOOL; opt->unit = SANE_UNIT_NONE; if ( s->has_dtc ){ opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; - if(s->ipc_mode == WD_ipc_SDTC - || (s->has_sdtc && s->ipc_mode == WD_ipc_DEFAULT)){ + if(get_ipc_mode(s) == WD_ipc_SDTC){ opt->cap |= SANE_CAP_INACTIVE; } } @@ -3365,15 +3383,14 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) if(option==OPT_NOISE_REMOVAL){ opt->name = "noise-removal"; - opt->title = "Noise removal"; - opt->desc = "Noise removal"; + opt->title = SANE_I18N ("Noise removal"); + opt->desc = SANE_I18N ("Noise removal"); opt->type = SANE_TYPE_BOOL; opt->unit = SANE_UNIT_NONE; if ( s->has_dtc ){ opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; - if(s->ipc_mode == WD_ipc_SDTC - || (s->has_sdtc && s->ipc_mode == WD_ipc_DEFAULT)){ + if(get_ipc_mode(s) == WD_ipc_SDTC){ opt->cap |= SANE_CAP_INACTIVE; } } @@ -3383,16 +3400,14 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) if(option==OPT_MATRIX_5){ opt->name = "matrix-5x5"; - opt->title = "Matrix 5x5"; - opt->desc = "Remove 5 pixel square noise"; + opt->title = SANE_I18N ("Matrix 5x5"); + opt->desc = SANE_I18N ("Remove 5 pixel square noise"); opt->type = SANE_TYPE_BOOL; opt->unit = SANE_UNIT_NONE; if ( s->has_dtc ){ opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; - if( !s->noise_removal - || s->ipc_mode == WD_ipc_SDTC - || (s->has_sdtc && s->ipc_mode == WD_ipc_DEFAULT)){ + if(!s->noise_removal){ opt->cap |= SANE_CAP_INACTIVE; } } @@ -3402,16 +3417,14 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) if(option==OPT_MATRIX_4){ opt->name = "matrix-4x4"; - opt->title = "Matrix 4x4"; - opt->desc = "Remove 4 pixel square noise"; + opt->title = SANE_I18N ("Matrix 4x4"); + opt->desc = SANE_I18N ("Remove 4 pixel square noise"); opt->type = SANE_TYPE_BOOL; opt->unit = SANE_UNIT_NONE; if ( s->has_dtc ){ opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; - if( !s->noise_removal - || s->ipc_mode == WD_ipc_SDTC - || (s->has_sdtc && s->ipc_mode == WD_ipc_DEFAULT)){ + if(!s->noise_removal){ opt->cap |= SANE_CAP_INACTIVE; } } @@ -3421,16 +3434,14 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) if(option==OPT_MATRIX_3){ opt->name = "matrix-3x3"; - opt->title = "Matrix 3x3"; - opt->desc = "Remove 3 pixel square noise"; + opt->title = SANE_I18N ("Matrix 3x3"); + opt->desc = SANE_I18N ("Remove 3 pixel square noise"); opt->type = SANE_TYPE_BOOL; opt->unit = SANE_UNIT_NONE; if ( s->has_dtc ){ opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; - if( !s->noise_removal - || s->ipc_mode == WD_ipc_SDTC - || (s->has_sdtc && s->ipc_mode == WD_ipc_DEFAULT)){ + if(!s->noise_removal){ opt->cap |= SANE_CAP_INACTIVE; } } @@ -3440,16 +3451,14 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) if(option==OPT_MATRIX_2){ opt->name = "matrix-2x2"; - opt->title = "Matrix 2x2"; - opt->desc = "Remove 2 pixel square noise"; + opt->title = SANE_I18N ("Matrix 2x2"); + opt->desc = SANE_I18N ("Remove 2 pixel square noise"); opt->type = SANE_TYPE_BOOL; opt->unit = SANE_UNIT_NONE; if ( s->has_dtc ){ opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; - if( !s->noise_removal - || s->ipc_mode == WD_ipc_SDTC - || (s->has_sdtc && s->ipc_mode == WD_ipc_DEFAULT)){ + if(!s->noise_removal){ opt->cap |= SANE_CAP_INACTIVE; } } @@ -3462,8 +3471,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) /* called variance with ipc2, sensitivity with ipc3 */ if(option==OPT_VARIANCE){ opt->name = "variance"; - opt->title = "Variance"; - opt->desc = "Set SDTC variance rate (sensitivity), 0 equals 127"; + opt->title = SANE_I18N ("Variance"); + opt->desc = SANE_I18N ("Set SDTC variance rate (sensitivity), 0 equals 127"); opt->type = SANE_TYPE_INT; opt->unit = SANE_UNIT_NONE; @@ -3475,7 +3484,7 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) if ( s->has_sdtc ){ opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; - if (s->ipc_mode == WD_ipc_DTC){ + if(get_ipc_mode(s) == WD_ipc_DTC){ opt->cap |= SANE_CAP_INACTIVE; } } @@ -3496,8 +3505,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) if(option==OPT_AWD){ opt->name = "awd"; - opt->title = "Auto width detection"; - opt->desc = "Scanner detects paper sides. May reduce scanning speed."; + opt->title = SANE_I18N ("Auto width detection"); + opt->desc = SANE_I18N ("Scanner detects paper sides. May reduce scanning speed."); opt->type = SANE_TYPE_BOOL; opt->unit = SANE_UNIT_NONE; opt->constraint_type = SANE_CONSTRAINT_NONE; @@ -3514,8 +3523,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) if(option==OPT_ALD){ opt->name = "ald"; - opt->title = "Auto length detection"; - opt->desc = "Scanner detects paper lower edge. May confuse some frontends."; + opt->title = SANE_I18N ("Auto length detection"); + opt->desc = SANE_I18N ("Scanner detects paper lower edge. May confuse some frontends."); opt->type = SANE_TYPE_BOOL; opt->unit = SANE_UNIT_NONE; opt->constraint_type = SANE_CONSTRAINT_NONE; @@ -3541,8 +3550,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) s->compress_list[i]=NULL; opt->name = "compression"; - opt->title = "Compression"; - opt->desc = "Enable compressed data. May crash your front-end program"; + opt->title = SANE_I18N ("Compression"); + opt->desc = SANE_I18N ("Enable compressed data. May crash your front-end program"); opt->type = SANE_TYPE_STRING; opt->constraint_type = SANE_CONSTRAINT_STRING_LIST; opt->constraint.string_list = s->compress_list; @@ -3562,8 +3571,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) if(option==OPT_COMPRESS_ARG){ opt->name = "compression-arg"; - opt->title = "Compression argument"; - opt->desc = "Level of JPEG compression. 1 is small file, 7 is large file. 0 (default) is same as 4"; + opt->title = SANE_I18N ("Compression argument"); + opt->desc = SANE_I18N ("Level of JPEG compression. 1 is small file, 7 is large file. 0 (default) is same as 4"); opt->type = SANE_TYPE_INT; opt->unit = SANE_UNIT_NONE; opt->constraint_type = SANE_CONSTRAINT_RANGE; @@ -3573,7 +3582,9 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) if(s->has_comp_JPG1){ s->compress_arg_range.min=0; s->compress_arg_range.max=7; +#ifndef SANE_JPEG_DISABLED opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; +#endif if(s->compress != COMP_JPEG){ opt->cap |= SANE_CAP_INACTIVE; @@ -3591,8 +3602,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) s->df_action_list[3] = NULL; opt->name = "df-action"; - opt->title = "DF action"; - opt->desc = "Action following double feed error"; + opt->title = SANE_I18N ("DF action"); + opt->desc = SANE_I18N ("Action following double feed error"); opt->type = SANE_TYPE_STRING; opt->constraint_type = SANE_CONSTRAINT_STRING_LIST; opt->constraint.string_list = s->df_action_list; @@ -3608,8 +3619,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) if(option==OPT_DF_SKEW){ opt->name = "df-skew"; - opt->title = "DF skew"; - opt->desc = "Enable double feed error due to skew"; + opt->title = SANE_I18N ("DF skew"); + opt->desc = SANE_I18N ("Enable double feed error due to skew"); opt->type = SANE_TYPE_BOOL; opt->unit = SANE_UNIT_NONE; opt->constraint_type = SANE_CONSTRAINT_NONE; @@ -3627,8 +3638,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) if(option==OPT_DF_THICKNESS){ opt->name = "df-thickness"; - opt->title = "DF thickness"; - opt->desc = "Enable double feed error due to paper thickness"; + opt->title = SANE_I18N ("DF thickness"); + opt->desc = SANE_I18N ("Enable double feed error due to paper thickness"); opt->type = SANE_TYPE_BOOL; opt->unit = SANE_UNIT_NONE; opt->constraint_type = SANE_CONSTRAINT_NONE; @@ -3646,8 +3657,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) if(option==OPT_DF_LENGTH){ opt->name = "df-length"; - opt->title = "DF length"; - opt->desc = "Enable double feed error due to paper length"; + opt->title = SANE_I18N ("DF length"); + opt->desc = SANE_I18N ("Enable double feed error due to paper length"); opt->type = SANE_TYPE_BOOL; opt->unit = SANE_UNIT_NONE; opt->constraint_type = SANE_CONSTRAINT_NONE; @@ -3670,8 +3681,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) s->df_diff_list[4] = NULL; opt->name = "df-diff"; - opt->title = "DF length difference"; - opt->desc = "Difference in page length to trigger double feed error"; + opt->title = SANE_I18N ("DF length difference"); + opt->desc = SANE_I18N ("Difference in page length to trigger double feed error"); opt->type = SANE_TYPE_STRING; opt->constraint_type = SANE_CONSTRAINT_STRING_LIST; opt->constraint.string_list = s->df_diff_list; @@ -3694,8 +3705,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) s->df_recovery_list[3] = NULL; opt->name = "df-recovery"; - opt->title = "DF recovery mode"; - opt->desc = "Request scanner to reverse feed on paper jam"; + opt->title = SANE_I18N ("DF recovery mode"); + opt->desc = SANE_I18N ("Request scanner to reverse feed on paper jam"); opt->type = SANE_TYPE_STRING; opt->constraint_type = SANE_CONSTRAINT_STRING_LIST; opt->constraint.string_list = s->df_recovery_list; @@ -3714,8 +3725,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) s->paper_protect_list[3] = NULL; opt->name = "paper-protect"; - opt->title = "Paper protection"; - opt->desc = "Request scanner to predict jams in the ADF"; + opt->title = SANE_I18N ("Paper protection"); + opt->desc = SANE_I18N ("Request scanner to predict jams in the ADF"); opt->type = SANE_TYPE_STRING; opt->constraint_type = SANE_CONSTRAINT_STRING_LIST; opt->constraint.string_list = s->paper_protect_list; @@ -3734,8 +3745,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) s->adv_paper_prot_list[3] = NULL; opt->name = "adv-paper-protect"; - opt->title = "Advanced paper protection"; - opt->desc = "Request scanner to predict jams in the ADF using improved sensors"; + opt->title = SANE_I18N ("Advanced paper protection"); + opt->desc = SANE_I18N ("Request scanner to predict jams in the ADF using improved sensors"); opt->type = SANE_TYPE_STRING; opt->constraint_type = SANE_CONSTRAINT_STRING_LIST; opt->constraint.string_list = s->adv_paper_prot_list; @@ -3754,8 +3765,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) s->staple_detect_list[3] = NULL; opt->name = "staple-detect"; - opt->title = "Staple detection"; - opt->desc = "Request scanner to detect jams in the ADF caused by staples"; + opt->title = SANE_I18N ("Staple detection"); + opt->desc = SANE_I18N ("Request scanner to detect jams in the ADF caused by staples"); opt->type = SANE_TYPE_STRING; opt->constraint_type = SANE_CONSTRAINT_STRING_LIST; opt->constraint.string_list = s->staple_detect_list; @@ -3774,8 +3785,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) s->bg_color_list[3] = NULL; opt->name = "bgcolor"; - opt->title = "Background color"; - opt->desc = "Set color of background for scans. May conflict with overscan option"; + opt->title = SANE_I18N ("Background color"); + opt->desc = SANE_I18N ("Set color of background for scans. May conflict with overscan option"); opt->type = SANE_TYPE_STRING; opt->constraint_type = SANE_CONSTRAINT_STRING_LIST; opt->constraint.string_list = s->bg_color_list; @@ -3795,8 +3806,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) s->do_color_list[4] = NULL; opt->name = "dropoutcolor"; - opt->title = "Dropout color"; - opt->desc = "One-pass scanners use only one color during gray or binary scanning, useful for colored paper or ink"; + opt->title = SANE_I18N ("Dropout color"); + opt->desc = SANE_I18N ("One-pass scanners use only one color during gray or binary scanning, useful for colored paper or ink"); opt->type = SANE_TYPE_STRING; opt->constraint_type = SANE_CONSTRAINT_STRING_LIST; opt->constraint.string_list = s->do_color_list; @@ -3819,8 +3830,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) s->buff_mode_list[3] = NULL; opt->name = "buffermode"; - opt->title = "Buffer mode"; - opt->desc = "Request scanner to read pages quickly from ADF into internal memory"; + opt->title = SANE_I18N ("Buffer mode"); + opt->desc = SANE_I18N ("Request scanner to read pages quickly from ADF into internal memory"); opt->type = SANE_TYPE_STRING; opt->constraint_type = SANE_CONSTRAINT_STRING_LIST; opt->constraint.string_list = s->buff_mode_list; @@ -3839,8 +3850,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) s->prepick_list[3] = NULL; opt->name = "prepick"; - opt->title = "Prepick"; - opt->desc = "Request scanner to grab next page from ADF"; + opt->title = SANE_I18N ("Prepick"); + opt->desc = SANE_I18N ("Request scanner to grab next page from ADF"); opt->type = SANE_TYPE_STRING; opt->constraint_type = SANE_CONSTRAINT_STRING_LIST; opt->constraint.string_list = s->prepick_list; @@ -3859,8 +3870,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) s->overscan_list[3] = NULL; opt->name = "overscan"; - opt->title = "Overscan"; - opt->desc = "Collect a few mm of background on top side of scan, before paper enters ADF, and increase maximum scan area beyond paper size, to allow collection on remaining sides. May conflict with bgcolor option"; + opt->title = SANE_I18N ("Overscan"); + opt->desc = SANE_I18N ("Collect a few mm of background on top side of scan, before paper enters ADF, and increase maximum scan area beyond paper size, to allow collection on remaining sides. May conflict with bgcolor option"); opt->type = SANE_TYPE_STRING; opt->constraint_type = SANE_CONSTRAINT_STRING_LIST; opt->constraint.string_list = s->overscan_list; @@ -3878,8 +3889,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) s->sleep_time_range.quant = 1; opt->name = "sleeptimer"; - opt->title = "Sleep timer"; - opt->desc = "Time in minutes until the internal power supply switches to sleep mode"; + opt->title = SANE_I18N ("Sleep timer"); + opt->desc = SANE_I18N ("Time in minutes until the internal power supply switches to sleep mode"); opt->type = SANE_TYPE_INT; opt->unit = SANE_UNIT_NONE; opt->constraint_type = SANE_CONSTRAINT_RANGE; @@ -3897,8 +3908,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) s->off_time_range.quant = 1; opt->name = "offtimer"; - opt->title = "Off timer"; - opt->desc = "Time in minutes until the internal power supply switches the scanner off. Will be rounded to nearest 15 minutes. Zero means never power off."; + opt->title = SANE_I18N ("Off timer"); + opt->desc = SANE_I18N ("Time in minutes until the internal power supply switches the scanner off. Will be rounded to nearest 15 minutes. Zero means never power off."); opt->type = SANE_TYPE_INT; opt->unit = SANE_UNIT_NONE; opt->constraint_type = SANE_CONSTRAINT_RANGE; @@ -3916,8 +3927,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) s->duplex_offset_range.quant = 1; opt->name = "duplexoffset"; - opt->title = "Duplex offset"; - opt->desc = "Adjust front/back offset"; + opt->title = SANE_I18N ("Duplex offset"); + opt->desc = SANE_I18N ("Adjust front/back offset"); opt->type = SANE_TYPE_INT; opt->unit = SANE_UNIT_NONE; opt->constraint_type = SANE_CONSTRAINT_RANGE; @@ -3934,8 +3945,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) s->green_offset_range.quant = 1; opt->name = "greenoffset"; - opt->title = "Green offset"; - opt->desc = "Adjust green/red offset"; + opt->title = SANE_I18N ("Green offset"); + opt->desc = SANE_I18N ("Adjust green/red offset"); opt->type = SANE_TYPE_INT; opt->unit = SANE_UNIT_NONE; opt->constraint_type = SANE_CONSTRAINT_RANGE; @@ -3952,8 +3963,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) s->blue_offset_range.quant = 1; opt->name = "blueoffset"; - opt->title = "Blue offset"; - opt->desc = "Adjust blue/red offset"; + opt->title = SANE_I18N ("Blue offset"); + opt->desc = SANE_I18N ("Adjust blue/red offset"); opt->type = SANE_TYPE_INT; opt->unit = SANE_UNIT_NONE; opt->constraint_type = SANE_CONSTRAINT_RANGE; @@ -3966,8 +3977,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) if(option==OPT_LOW_MEM){ opt->name = "lowmemory"; - opt->title = "Low Memory"; - opt->desc = "Limit driver memory usage for use in embedded systems. Causes some duplex transfers to alternate sides on each call to sane_read. Value of option 'side' can be used to determine correct image. This option should only be used with custom front-end software."; + opt->title = SANE_I18N ("Low Memory"); + opt->desc = SANE_I18N ("Limit driver memory usage for use in embedded systems. Causes some duplex transfers to alternate sides on each call to sane_read. Value of option 'side' can be used to determine correct image. This option should only be used with custom front-end software."); opt->type = SANE_TYPE_BOOL; opt->unit = SANE_UNIT_NONE; opt->size = sizeof(SANE_Word); @@ -3982,8 +3993,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) if(option==OPT_SIDE){ opt->name = "side"; - opt->title = "Duplex side"; - opt->desc = "Tells which side (0=front, 1=back) of a duplex scan the next call to sane_read will return."; + opt->title = SANE_I18N ("Duplex side"); + opt->desc = SANE_I18N ("Tells which side (0=front, 1=back) of a duplex scan the next call to sane_read will return."); opt->type = SANE_TYPE_BOOL; opt->unit = SANE_UNIT_NONE; opt->size = sizeof(SANE_Word); @@ -3994,8 +4005,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) /*deskew and crop by hardware*/ if(option==OPT_HWDESKEWCROP){ opt->name = "hwdeskewcrop"; - opt->title = "Hardware deskew and crop"; - opt->desc = "Request scanner to rotate and crop pages digitally."; + opt->title = SANE_I18N ("Hardware deskew and crop"); + opt->desc = SANE_I18N ("Request scanner to rotate and crop pages digitally."); opt->type = SANE_TYPE_BOOL; if (s->has_hybrid_crop_deskew) opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED; @@ -4006,8 +4017,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) /*deskew by software*/ if(option==OPT_SWDESKEW){ opt->name = "swdeskew"; - opt->title = "Software deskew"; - opt->desc = "Request driver to rotate skewed pages digitally."; + opt->title = SANE_I18N ("Software deskew"); + opt->desc = SANE_I18N ("Request driver to rotate skewed pages digitally."); opt->type = SANE_TYPE_BOOL; if (1) opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED; @@ -4019,8 +4030,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) if(option==OPT_SWDESPECK){ opt->name = "swdespeck"; - opt->title = "Software despeckle diameter"; - opt->desc = "Maximum diameter of lone dots to remove from scan."; + opt->title = SANE_I18N ("Software despeckle diameter"); + opt->desc = SANE_I18N ("Maximum diameter of lone dots to remove from scan."); opt->type = SANE_TYPE_INT; opt->unit = SANE_UNIT_NONE; opt->constraint_type = SANE_CONSTRAINT_RANGE; @@ -4039,8 +4050,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) /*crop by software*/ if(option==OPT_SWCROP){ opt->name = "swcrop"; - opt->title = "Software crop"; - opt->desc = "Request driver to remove border from pages digitally."; + opt->title = SANE_I18N ("Software crop"); + opt->desc = SANE_I18N ("Request driver to remove border from pages digitally."); opt->type = SANE_TYPE_BOOL; if (1) opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED; @@ -4069,8 +4080,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) /*halt scanner feeder when cancelling*/ if(option==OPT_HALT_ON_CANCEL){ opt->name = "halt-on-cancel"; - opt->title = "Halt on Cancel"; - opt->desc = "Request driver to halt the paper feed instead of eject during a cancel."; + opt->title = SANE_I18N ("Halt on Cancel"); + opt->desc = SANE_I18N ("Request driver to halt the paper feed instead of eject during a cancel."); opt->type = SANE_TYPE_BOOL; if (s->has_op_halt) opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED; @@ -4081,8 +4092,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) /* "Endorser" group ------------------------------------------------------ */ if(option==OPT_ENDORSER_GROUP){ opt->name = "endorser-options"; - opt->title = "Endorser Options"; - opt->desc = "Controls for endorser unit"; + opt->title = SANE_I18N ("Endorser Options"); + opt->desc = SANE_I18N ("Controls for endorser unit"); opt->type = SANE_TYPE_GROUP; opt->constraint_type = SANE_CONSTRAINT_NONE; @@ -4093,8 +4104,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) if(option==OPT_ENDORSER){ opt->name = "endorser"; - opt->title = "Endorser"; - opt->desc = "Enable endorser unit"; + opt->title = SANE_I18N ("Endorser"); + opt->desc = SANE_I18N ("Enable endorser unit"); opt->type = SANE_TYPE_BOOL; opt->unit = SANE_UNIT_NONE; opt->size = sizeof(SANE_Word); @@ -4109,8 +4120,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) if(option==OPT_ENDORSER_BITS){ opt->name = "endorser-bits"; - opt->title = "Endorser bits"; - opt->desc = "Determines maximum endorser counter value."; + opt->title = SANE_I18N ("Endorser bits"); + opt->desc = SANE_I18N ("Determines maximum endorser counter value."); opt->type = SANE_TYPE_INT; opt->unit = SANE_UNIT_NONE; opt->size = sizeof(SANE_Word); @@ -4135,8 +4146,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) if(option==OPT_ENDORSER_VAL){ opt->name = "endorser-val"; - opt->title = "Endorser value"; - opt->desc = "Initial endorser counter value."; + opt->title = SANE_I18N ("Endorser value"); + opt->desc = SANE_I18N ("Initial endorser counter value."); opt->type = SANE_TYPE_INT; opt->unit = SANE_UNIT_NONE; opt->size = sizeof(SANE_Word); @@ -4159,8 +4170,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) if(option==OPT_ENDORSER_STEP){ opt->name = "endorser-step"; - opt->title = "Endorser step"; - opt->desc = "Change endorser counter value by this much for each page."; + opt->title = SANE_I18N ("Endorser step"); + opt->desc = SANE_I18N ("Change endorser counter value by this much for each page."); opt->type = SANE_TYPE_INT; opt->unit = SANE_UNIT_NONE; opt->size = sizeof(SANE_Word); @@ -4183,8 +4194,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) if(option==OPT_ENDORSER_Y){ opt->name = "endorser-y"; - opt->title = "Endorser Y"; - opt->desc = "Endorser print offset from top of paper."; + opt->title = SANE_I18N ("Endorser Y"); + opt->desc = SANE_I18N ("Endorser print offset from top of paper."); opt->type = SANE_TYPE_FIXED; opt->unit = SANE_UNIT_MM; opt->size = sizeof(SANE_Word); @@ -4209,8 +4220,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) if(option==OPT_ENDORSER_FONT){ opt->name = "endorser-font"; - opt->title = "Endorser font"; - opt->desc = "Endorser printing font."; + opt->title = SANE_I18N ("Endorser font"); + opt->desc = SANE_I18N ("Endorser printing font."); opt->type = SANE_TYPE_STRING; opt->unit = SANE_UNIT_NONE; @@ -4239,8 +4250,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) if(option==OPT_ENDORSER_DIR){ opt->name = "endorser-dir"; - opt->title = "Endorser direction"; - opt->desc = "Endorser printing direction."; + opt->title = SANE_I18N ("Endorser direction"); + opt->desc = SANE_I18N ("Endorser printing direction."); opt->type = SANE_TYPE_STRING; opt->unit = SANE_UNIT_NONE; @@ -4264,8 +4275,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) if(option==OPT_ENDORSER_SIDE){ opt->name = "endorser-side"; - opt->title = "Endorser side"; - opt->desc = "Endorser printing side, requires hardware support to change"; + opt->title = SANE_I18N ("Endorser side"); + opt->desc = SANE_I18N ("Endorser printing side, requires hardware support to change"); opt->type = SANE_TYPE_STRING; opt->unit = SANE_UNIT_NONE; @@ -4290,8 +4301,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) if(option==OPT_ENDORSER_STRING){ opt->name = "endorser-string"; - opt->title = "Endorser string"; - opt->desc = "Endorser alphanumeric print format. %05ud or %08ud at the end will be replaced by counter value."; + opt->title = SANE_I18N ("Endorser string"); + opt->desc = SANE_I18N ("Endorser alphanumeric print format. %05ud or %08ud at the end will be replaced by counter value."); opt->type = SANE_TYPE_STRING; opt->unit = SANE_UNIT_NONE; opt->size = s->endorser_string_len + 1; @@ -4318,8 +4329,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) if(option==OPT_TOP){ opt->name = "top-edge"; - opt->title = "Top edge"; - opt->desc = "Paper is pulled partly into adf"; + opt->title = SANE_I18N ("Top edge"); + opt->desc = SANE_I18N ("Paper is pulled partly into adf"); opt->type = SANE_TYPE_BOOL; opt->unit = SANE_UNIT_NONE; if (s->has_cmd_hw_status || s->ghs_in_rs) @@ -4330,8 +4341,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) if(option==OPT_A3){ opt->name = "a3-paper"; - opt->title = "A3 paper"; - opt->desc = "A3 paper detected"; + opt->title = SANE_I18N ("A3 paper"); + opt->desc = SANE_I18N ("A3 paper detected"); opt->type = SANE_TYPE_BOOL; opt->unit = SANE_UNIT_NONE; if (s->has_cmd_hw_status) @@ -4342,8 +4353,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) if(option==OPT_B4){ opt->name = "b4-paper"; - opt->title = "B4 paper"; - opt->desc = "B4 paper detected"; + opt->title = SANE_I18N ("B4 paper"); + opt->desc = SANE_I18N ("B4 paper detected"); opt->type = SANE_TYPE_BOOL; opt->unit = SANE_UNIT_NONE; if (s->has_cmd_hw_status) @@ -4354,8 +4365,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) if(option==OPT_A4){ opt->name = "a4-paper"; - opt->title = "A4 paper"; - opt->desc = "A4 paper detected"; + opt->title = SANE_I18N ("A4 paper"); + opt->desc = SANE_I18N ("A4 paper detected"); opt->type = SANE_TYPE_BOOL; opt->unit = SANE_UNIT_NONE; if (s->has_cmd_hw_status) @@ -4366,8 +4377,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) if(option==OPT_B5){ opt->name = "b5-paper"; - opt->title = "B5 paper"; - opt->desc = "B5 paper detected"; + opt->title = SANE_I18N ("B5 paper"); + opt->desc = SANE_I18N ("B5 paper detected"); opt->type = SANE_TYPE_BOOL; opt->unit = SANE_UNIT_NONE; if (s->has_cmd_hw_status) @@ -4390,8 +4401,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) if(option==OPT_OMR){ opt->name = "omr-df"; - opt->title = "OMR or DF"; - opt->desc = "OMR or double feed detected"; + opt->title = SANE_I18N ("OMR or DF"); + opt->desc = SANE_I18N ("OMR or double feed detected"); opt->type = SANE_TYPE_BOOL; opt->unit = SANE_UNIT_NONE; if (s->has_cmd_hw_status) @@ -4414,8 +4425,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) if(option==OPT_SLEEP){ opt->name = "power-save"; - opt->title = "Power saving"; - opt->desc = "Scanner in power saving mode"; + opt->title = SANE_I18N ("Power saving"); + opt->desc = SANE_I18N ("Scanner in power saving mode"); opt->type = SANE_TYPE_BOOL; opt->unit = SANE_UNIT_NONE; if (s->has_cmd_hw_status) @@ -4438,8 +4449,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) if(option==OPT_MANUAL_FEED){ opt->name = "manual-feed"; - opt->title = "Manual feed"; - opt->desc = "Manual feed selected"; + opt->title = SANE_I18N ("Manual feed"); + opt->desc = SANE_I18N ("Manual feed selected"); opt->type = SANE_TYPE_BOOL; opt->unit = SANE_UNIT_NONE; if (s->has_cmd_hw_status) @@ -4462,8 +4473,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) if(option==OPT_FUNCTION){ opt->name = "function"; - opt->title = "Function"; - opt->desc = "Function character on screen"; + opt->title = SANE_I18N ("Function"); + opt->desc = SANE_I18N ("Function character on screen"); opt->type = SANE_TYPE_INT; opt->unit = SANE_UNIT_NONE; if (s->has_cmd_hw_status || s->ghs_in_rs) @@ -4474,8 +4485,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) if(option==OPT_INK_EMPTY){ opt->name = "ink-low"; - opt->title = "Ink low"; - opt->desc = "Imprinter ink running low"; + opt->title = SANE_I18N ("Ink low"); + opt->desc = SANE_I18N ("Imprinter ink running low"); opt->type = SANE_TYPE_BOOL; opt->unit = SANE_UNIT_NONE; if (s->has_cmd_hw_status && (s->has_endorser_f || s->has_endorser_b)) @@ -4486,8 +4497,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) if(option==OPT_DOUBLE_FEED){ opt->name = "double-feed"; - opt->title = "Double feed"; - opt->desc = "Double feed detected"; + opt->title = SANE_I18N ("Double feed"); + opt->desc = SANE_I18N ("Double feed detected"); opt->type = SANE_TYPE_BOOL; opt->unit = SANE_UNIT_NONE; if (s->has_cmd_hw_status || s->ghs_in_rs) @@ -4498,8 +4509,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) if(option==OPT_ERROR_CODE){ opt->name = "error-code"; - opt->title = "Error code"; - opt->desc = "Hardware error code"; + opt->title = SANE_I18N ("Error code"); + opt->desc = SANE_I18N ("Hardware error code"); opt->type = SANE_TYPE_INT; opt->unit = SANE_UNIT_NONE; if (s->has_cmd_hw_status) @@ -4510,8 +4521,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) if(option==OPT_SKEW_ANGLE){ opt->name = "skew-angle"; - opt->title = "Skew angle"; - opt->desc = "Requires black background for scanning"; + opt->title = SANE_I18N ("Skew angle"); + opt->desc = SANE_I18N ("Requires black background for scanning"); opt->type = SANE_TYPE_INT; opt->unit = SANE_UNIT_NONE; if (s->has_cmd_hw_status) @@ -4522,8 +4533,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) if(option==OPT_INK_REMAIN){ opt->name = "ink-remain"; - opt->title = "Ink remaining"; - opt->desc = "Imprinter ink level"; + opt->title = SANE_I18N ("Ink remaining"); + opt->desc = SANE_I18N ("Imprinter ink level"); opt->type = SANE_TYPE_INT; opt->unit = SANE_UNIT_NONE; if (s->has_cmd_hw_status && (s->has_endorser_f || s->has_endorser_b)) @@ -4534,8 +4545,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) if(option==OPT_DENSITY_SW){ opt->name = "density"; - opt->title = "Density"; - opt->desc = "Density dial"; + opt->title = SANE_I18N ("Density"); + opt->desc = SANE_I18N ("Density dial"); opt->type = SANE_TYPE_INT; opt->unit = SANE_UNIT_NONE; if (s->ghs_in_rs) @@ -4546,8 +4557,8 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) if(option==OPT_DUPLEX_SW){ opt->name = "duplex"; - opt->title = "Duplex switch"; - opt->desc = "Duplex switch"; + opt->title = SANE_I18N ("Duplex switch"); + opt->desc = SANE_I18N ("Duplex switch"); opt->type = SANE_TYPE_BOOL; opt->unit = SANE_UNIT_NONE; if (s->ghs_in_rs) @@ -4749,18 +4760,7 @@ sane_control_option (SANE_Handle handle, SANE_Int option, } return SANE_STATUS_GOOD; - case OPT_IPC_MODE: - if(s->ipc_mode == WD_ipc_DEFAULT){ - strcpy (val, STRING_DEFAULT); - } - else if(s->ipc_mode == WD_ipc_DTC){ - strcpy (val, STRING_DTC); - } - else if(s->ipc_mode == WD_ipc_SDTC){ - strcpy (val, STRING_SDTC); - } - return SANE_STATUS_GOOD; - + /* DTC params*/ case OPT_BP_FILTER: *val_p = s->bp_filter; return SANE_STATUS_GOOD; @@ -4801,6 +4801,7 @@ sane_control_option (SANE_Handle handle, SANE_Int option, *val_p = s->matrix_2; return SANE_STATUS_GOOD; + /* SDTC params*/ case OPT_VARIANCE: *val_p = s->variance; return SANE_STATUS_GOOD; @@ -5357,6 +5358,14 @@ sane_control_option (SANE_Handle handle, SANE_Int option, if (s->page_width == FIXED_MM_TO_SCANNER_UNIT(val_c)) return SANE_STATUS_GOOD; + /* if full width image, and paper size is changed, + change the image size to match new paper */ + if (s->tl_x == 0 && s->br_x == s->page_width){ + DBG (20, "sane_control_option: br_x tracking page_width\n"); + s->br_x = FIXED_MM_TO_SCANNER_UNIT(val_c); + *info |= SANE_INFO_RELOAD_PARAMS; + } + s->page_width = FIXED_MM_TO_SCANNER_UNIT(val_c); *info |= SANE_INFO_RELOAD_OPTIONS; return SANE_STATUS_GOOD; @@ -5365,6 +5374,14 @@ sane_control_option (SANE_Handle handle, SANE_Int option, if (s->page_height == FIXED_MM_TO_SCANNER_UNIT(val_c)) return SANE_STATUS_GOOD; + /* if full height image, and paper size is changed, + change the image size to match new paper */ + if (s->tl_y == 0 && s->br_y == s->page_height){ + DBG (20, "sane_control_option: br_y tracking page_height\n"); + s->br_y = FIXED_MM_TO_SCANNER_UNIT(val_c); + *info |= SANE_INFO_RELOAD_PARAMS; + } + s->page_height = FIXED_MM_TO_SCANNER_UNIT(val_c); *info |= SANE_INFO_RELOAD_OPTIONS; return SANE_STATUS_GOOD; @@ -5429,48 +5446,35 @@ sane_control_option (SANE_Handle handle, SANE_Int option, s->wl_follow = WD_wl_follow_OFF; return SANE_STATUS_GOOD; - case OPT_IPC_MODE: - if (!strcmp (val, STRING_DEFAULT)) { - tmp = WD_ipc_DEFAULT; - } - else if (!strcmp (val, STRING_DTC)) { - tmp = WD_ipc_DTC; - } - else { - tmp = WD_ipc_SDTC; - } - - if (tmp != s->ipc_mode) - *info |= SANE_INFO_RELOAD_OPTIONS; - - s->ipc_mode = tmp; - return SANE_STATUS_GOOD; - + /* DTC params*/ case OPT_BP_FILTER: s->bp_filter = val_c; + *info |= SANE_INFO_RELOAD_OPTIONS; return SANE_STATUS_GOOD; case OPT_SMOOTHING: s->smoothing = val_c; + *info |= SANE_INFO_RELOAD_OPTIONS; return SANE_STATUS_GOOD; case OPT_GAMMA_CURVE: s->gamma_curve = val_c; + *info |= SANE_INFO_RELOAD_OPTIONS; return SANE_STATUS_GOOD; case OPT_THRESHOLD_CURVE: s->threshold_curve = val_c; + *info |= SANE_INFO_RELOAD_OPTIONS; return SANE_STATUS_GOOD; case OPT_THRESHOLD_WHITE: s->threshold_white = val_c; + *info |= SANE_INFO_RELOAD_OPTIONS; return SANE_STATUS_GOOD; case OPT_NOISE_REMOVAL: - if (val_c != s->noise_removal) - *info |= SANE_INFO_RELOAD_OPTIONS; - s->noise_removal = val_c; + *info |= SANE_INFO_RELOAD_OPTIONS; return SANE_STATUS_GOOD; case OPT_MATRIX_5: @@ -5489,8 +5493,10 @@ sane_control_option (SANE_Handle handle, SANE_Int option, s->matrix_2 = val_c; return SANE_STATUS_GOOD; + /* SDTC params*/ case OPT_VARIANCE: s->variance = val_c; + *info |= SANE_INFO_RELOAD_OPTIONS; return SANE_STATUS_GOOD; /* Advanced Group */ @@ -6681,7 +6687,7 @@ sane_get_parameters (SANE_Handle handle, SANE_Parameters * params) return ret; } -/* set s_param and u_param data based on user settings +/* set s_params and u_params data based on user settings * and scanner capabilities. */ SANE_Status update_params (struct fujitsu * s) @@ -6926,8 +6932,9 @@ sane_start (SANE_Handle handle) if (ret != SANE_STATUS_GOOD) DBG (5, "sane_start: WARNING: cannot send_endorser %d\n", ret); - /* send lut if scanner has no hardware brightness/contrast */ - if (!s->late_lut && (!s->brightness_steps || !s->contrast_steps)){ + /* send lut if scanner has no hardware brightness/contrast, + * or we are going to ask it to use a downloaded gamma table */ + if (!s->late_lut && (!s->brightness_steps || !s->contrast_steps || s->window_gamma & 0x80)){ ret = send_lut(s); if (ret != SANE_STATUS_GOOD) DBG (5, "sane_start: WARNING: cannot early send_lut %d\n", ret); @@ -6940,8 +6947,9 @@ sane_start (SANE_Handle handle) goto errors; } - /* send lut if scanner has no hardware brightness/contrast */ - if (s->late_lut && (!s->brightness_steps || !s->contrast_steps)){ + /* send lut if scanner has no hardware brightness/contrast, + * or we are going to ask it to use a downloaded gamma table */ + if (s->late_lut && (!s->brightness_steps || !s->contrast_steps || s->window_gamma & 0x80)){ ret = send_lut(s); if (ret != SANE_STATUS_GOOD) DBG (5, "sane_start: WARNING: cannot late send_lut %d\n", ret); @@ -7573,15 +7581,15 @@ set_window (struct fujitsu *s) set_WD_separation(desc1,s->separation); set_WD_mirroring(desc1,s->mirroring); - if (s->has_sdtc && s->ipc_mode != WD_ipc_DTC) + if (get_ipc_mode(s) == WD_ipc_SDTC) set_WD_variance(desc1,s->variance); - if ((s->has_dtc && !s->has_sdtc) || s->ipc_mode == WD_ipc_DTC){ - set_WD_filtering(desc1,!s->bp_filter); - set_WD_smoothing(desc1,!s->smoothing); + else if (get_ipc_mode(s) == WD_ipc_DTC){ + set_WD_filtering(desc1,s->bp_filter); + set_WD_smoothing(desc1,s->smoothing); set_WD_gamma_curve(desc1,s->gamma_curve); set_WD_threshold_curve(desc1,s->threshold_curve); - set_WD_noise_removal(desc1,!s->noise_removal); + set_WD_noise_removal(desc1,s->noise_removal); if(s->noise_removal){ set_WD_matrix5x5(desc1,s->matrix_5); set_WD_matrix4x4(desc1,s->matrix_4); @@ -7593,7 +7601,7 @@ set_window (struct fujitsu *s) set_WD_wl_follow(desc1,s->wl_follow); set_WD_subwindow_list(desc1,0); - set_WD_ipc_mode(desc1,s->ipc_mode); + set_WD_ipc_mode(desc1,get_ipc_mode(s)); } else{ @@ -7691,8 +7699,8 @@ get_pixelsize(struct fujitsu *s, int actual) /* when we are called post-scan, the scanner may give * more accurate data in other fields */ if(actual && !s->has_short_pixelsize && get_PSIZE_paper_w(in)){ + DBG(5,"get_pixelsize: Actual width %d -> %d\n", s->s_params.pixels_per_line, get_PSIZE_paper_w(in)); s->s_params.pixels_per_line = get_PSIZE_paper_w(in); - DBG(5,"get_pixelsize: Actual width\n"); } else{ s->s_params.pixels_per_line = get_PSIZE_num_x(in); @@ -7707,8 +7715,8 @@ get_pixelsize(struct fujitsu *s, int actual) /* when we are called post-scan, the scanner may give * more accurate data in other fields */ else if(actual && !s->has_short_pixelsize && get_PSIZE_paper_l(in)){ + DBG(5,"get_pixelsize: Actual length %d -> %d\n", s->s_params.lines, get_PSIZE_paper_l(in)); s->s_params.lines = get_PSIZE_paper_l(in); - DBG(5,"get_pixelsize: Actual length\n"); } else{ s->s_params.lines = get_PSIZE_num_y(in); @@ -9867,6 +9875,43 @@ get_page_height(struct fujitsu *s) return height; } +/* scanners have two different possible IPC + * modes, which enable a different series of + * subordinate options. Rather than provide + * the user with an option to pick the IPC + * mode, we show them the subordinate ones, + * and pick the right mode to match. + */ +static int +get_ipc_mode(struct fujitsu *s) +{ + if ( s->bp_filter + || s->smoothing + || s->gamma_curve + || s->threshold_curve + || s->threshold_white + || s->noise_removal + || s->matrix_5 + || s->matrix_4 + || s->matrix_3 + || s->matrix_2 + ) + return WD_ipc_DTC; + + if(s->variance) + return WD_ipc_SDTC; + + /* special case: 0 threshold should activate IPC */ + if(!s->threshold){ + if(s->has_sdtc) + return WD_ipc_SDTC; + if(s->has_dtc) + return WD_ipc_DTC; + } + + return WD_ipc_DEFAULT; +} + /* s->max_y gives the maximum height of paper which can be scanned * this actually varies by resolution, so a helper to change it */ static int -- cgit v1.2.3 From 1687222e1b9e74c89cafbb5910e72d8ec7bfd40f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Wed, 31 Jul 2019 16:59:49 +0200 Subject: New upstream version 1.0.28 --- backend/fujitsu.c | 1316 +++++++++++++++++++++++++++-------------------------- 1 file changed, 681 insertions(+), 635 deletions(-) (limited to 'backend/fujitsu.c') diff --git a/backend/fujitsu.c b/backend/fujitsu.c index 433f75a..3ac4c8e 100644 --- a/backend/fujitsu.c +++ b/backend/fujitsu.c @@ -107,7 +107,7 @@ - removed SP15 code - sane_open actually opens the device you request v11 2003-06-11, MAN - - fixed bug in that code when a scanner is disconnected + - fixed bug in that code when a scanner is disconnected v12 2003-10-06, MAN - added code to support color modes of more recent scanners v13 2003-11-07, OS @@ -136,7 +136,7 @@ v19 2004-06-28, MAN - 4220 use model code not strcmp (stan a t saticed.me.uk) v20 2004-08-24, OS - - bugfix: 3091 did not work since 15.12.2003 + - bugfix: 3091 did not work since 15.12.2003 - M4099 supported (bw only) v21 2006-05-01, MAN - Complete rewrite, half code size @@ -264,7 +264,7 @@ - change window_gamma determination - add fi-5650C usb id and color mode v48 2007-04-16, MAN - - re-enable brightness/contrast for built-in models + - re-enable brightness/contrast for built-in models v49 2007-06-28, MAN - add fi-5750C usb id and color mode v50 2007-07-10, MAN @@ -600,6 +600,9 @@ - initial support for fi-7600/7700 - autodetect various double feed capabilities using VPD - call send_lut if we are using a downloaded gamma table + v134 2019-02-23, MAN + - rewrite init_vpd for scanners which fail to report + overscan correctly SANE FLOW DIAGRAM @@ -617,7 +620,7 @@ . . - sane_start() : start image acquisition . . - sane_get_parameters() : returns actual scan parameters . . - sane_read() : read image data (from pipe) - . . (sane_read called multiple times; after sane_read returns EOF, + . . (sane_read called multiple times; after sane_read returns EOF, . . loop may continue with sane_start which may return a 2nd page . . when doing duplex scans, or load the next page from the ADF) . . @@ -649,14 +652,14 @@ #include "fujitsu.h" #define DEBUG 1 -#define BUILD 133 +#define BUILD 134 /* values for SANE_DEBUG_FUJITSU env var: - errors 5 - function trace 10 - function detail 15 - get/setopt cmds 20 - - scsi/usb trace 25 + - scsi/usb trace 25 - scsi/usb writes 30 - scsi/usb reads 31 - useless noise 35 @@ -736,7 +739,7 @@ static struct fujitsu *fujitsu_devList = NULL; /* * Called by SANE initially. - * + * * From the SANE spec: * This function must be called before any other SANE function can be * called. The behavior of a SANE backend is undefined if this @@ -770,7 +773,7 @@ sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize) /* * Called by SANE to find out about supported devices. - * + * * From the SANE spec: * This function can be used to query the list of devices that are * available. If the function executes successfully, it stores a @@ -783,7 +786,7 @@ sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize) * returned (devices directly attached to the machine that SANE is * running on). If it is false, the device list includes all remote * devices that are accessible to the SANE library. - * + * * SANE does not require that this function is called before a * sane_open() call is performed. A device name may be specified * explicitly by a user which would make it unnecessary and @@ -827,39 +830,39 @@ sane_get_devices (const SANE_Device *** device_list, SANE_Bool local_only) FUJITSU_CONFIG_FILE); while (sanei_config_read (line, PATH_MAX, fp)) { - + lp = line; - + /* ignore comments */ if (*lp == '#') continue; - + /* skip empty lines */ if (*lp == 0) continue; - + if ((strncmp ("option", lp, 6) == 0) && isspace (lp[6])) { - + lp += 6; lp = sanei_config_skip_whitespace (lp); - + /* we allow setting buffersize too big */ if ((strncmp (lp, "buffer-size", 11) == 0) && isspace (lp[11])) { - + int buf; lp += 11; lp = sanei_config_skip_whitespace (lp); buf = atoi (lp); - + if (buf < 4096) { DBG (5, "sane_get_devices: config option \"buffer-size\" (%d) is < 4096, ignoring!\n", buf); continue; } - + if (buf > 64*1024) { DBG (5, "sane_get_devices: config option \"buffer-size\" (%d) is > %d, warning!\n", buf, 64*1024); } - + DBG (15, "sane_get_devices: setting \"buffer-size\" to %d\n", buf); global_buffer_size = buf; } @@ -956,8 +959,8 @@ attach_one_usb (const char *device_name) return attach_one(device_name,CONNECTION_USB); } -/* build the scanner struct and link to global list - * unless struct is already loaded, then pretend +/* build the scanner struct and link to global list + * unless struct is already loaded, then pretend */ static SANE_Status attach_one (const char *device_name, int connType) @@ -1105,7 +1108,7 @@ connect_fd (struct fujitsu *s) } else { DBG (15, "connect_fd: opening SCSI device\n"); - ret = sanei_scsi_open_extended (s->device_name, &(s->fd), sense_handler, s, + ret = sanei_scsi_open_extended (s->device_name, &(s->fd), sense_handler, s, &s->buffer_size); if(!ret && buffer_size != s->buffer_size){ DBG (5, "connect_fd: cannot get requested buffer size (%d/%d)\n", @@ -1115,8 +1118,8 @@ connect_fd (struct fujitsu *s) if(ret == SANE_STATUS_GOOD){ - /* first generation usb scanners can get flaky if not closed - * properly after last use. very first commands sent to device + /* first generation usb scanners can get flaky if not closed + * properly after last use. very first commands sent to device * must be prepared to correct this- see wait_scanner() */ ret = wait_scanner(s); if (ret != SANE_STATUS_GOOD) { @@ -1157,9 +1160,9 @@ init_inquire (struct fujitsu *s) set_IN_return_size (cmd, inLen); set_IN_evpd (cmd, 0); set_IN_page_code (cmd, 0); - + ret = do_cmd ( - s, 1, 0, + s, 1, 0, cmd, cmdLen, NULL, 0, in, &inLen @@ -1238,6 +1241,8 @@ init_vpd (struct fujitsu *s) unsigned char in[INQUIRY_vpd_len]; size_t inLen = INQUIRY_vpd_len; + int payload_len, payload_off; + DBG (10, "init_vpd: start\n"); /* get EVPD */ @@ -1254,531 +1259,573 @@ init_vpd (struct fujitsu *s) in, &inLen ); + /*FIXME no vpd, set some defaults? */ + if (ret != SANE_STATUS_GOOD && ret != SANE_STATUS_EOF) { + DBG (5, "init_vpd: Your scanner does not support VPD?\n"); + DBG (5, "init_vpd: Please contact kitno455 at gmail dot com\n"); + DBG (5, "init_vpd: with details of your scanner model.\n"); + return ret; + } + + /* In byte 4, the scanner sends the length of the remainder of + * the payload. But, this value is often bogus. */ + payload_len = get_IN_page_length(in); + + DBG (15, "init_vpd: length=%0x\n", payload_len); + /* M3099 gives all data, but wrong length */ - if (strstr (s->model_name, "M3099") - && (ret == SANE_STATUS_GOOD || ret == SANE_STATUS_EOF) - && get_IN_page_length (in) == 0x19){ - DBG (5, "init_vpd: M3099 repair\n"); - set_IN_page_length(in,0x5f); + if (strstr (s->model_name, "M3099") && payload_len == 0x19){ + DBG (5, "init_vpd: M3099 repair\n"); + payload_len = 0x5f; } /* M3097G has short vpd, fill in missing part */ - else if (strstr (s->model_name, "M3097G") - && (ret == SANE_STATUS_GOOD || ret == SANE_STATUS_EOF) - && get_IN_page_length (in) == 0x19){ - unsigned char vpd3097g[] = { + else if (strstr (s->model_name, "M3097G") && payload_len == 0x19){ + unsigned char vpd3097g[] = { 0, 0, 0xc2, 0x08, 0, 0, 0, 0, 0, 0, 0xed, 0xbf, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0, 0x45, 0x35, 0, 0xe0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; - DBG (5, "init_vpd: M3097G repair\n"); - set_IN_page_length(in,0x5f); - memcpy(in+0x1e,vpd3097g,sizeof(vpd3097g)); + }; - /*IPC*/ - if(strstr (s->model_name, "i")){ - DBG (5, "init_vpd: M3097G IPC repair\n"); + DBG (5, "init_vpd: M3097G repair\n"); + payload_len = 0x5f; + memcpy(in+0x1e,vpd3097g,sizeof(vpd3097g)); - /*subwin cmd*/ - in[0x2b] = 1; + /*IPC*/ + if(strstr (s->model_name, "i")){ + DBG (5, "init_vpd: M3097G IPC repair\n"); - /*rif/dtc/sdtc/outline/emph/sep/mirr/wlf*/ - in[0x58] = 0xff; + /*subwin cmd*/ + in[0x2b] = 1; - /*subwin/diffusion*/ - in[0x59] = 0xc0; - } + /*rif/dtc/sdtc/outline/emph/sep/mirr/wlf*/ + in[0x58] = 0xff; - /*CMP*/ - if(strstr (s->model_name, "m")){ - DBG (5, "init_vpd: M3097G CMP repair\n"); + /*subwin/diffusion*/ + in[0x59] = 0xc0; + } - /*4megs*/ - in[0x23] = 0x40; + /*CMP*/ + if(strstr (s->model_name, "m")){ + DBG (5, "init_vpd: M3097G CMP repair\n"); - /*mh/mr/mmr*/ - in[0x5a] = 0xe0; - } + /*4megs*/ + in[0x23] = 0x40; + + /*mh/mr/mmr*/ + in[0x5a] = 0xe0; + } } - DBG (15, "init_vpd: length=%0x\n",get_IN_page_length (in)); + /* all other known scanners have at least 0x5f, + * less would require software changes like above */ + else if (payload_len < 0x5f) { + DBG (5, "init_vpd: Your scanner supports only partial VPD?\n"); + DBG (5, "init_vpd: Please contact kitno455 at gmail dot com\n"); + DBG (5, "init_vpd: with details of your scanner model.\n"); + return SANE_STATUS_INVAL; + } - /* This scanner supports vital product data. - * Use this data to set dpi-lists etc. */ - if (ret == SANE_STATUS_GOOD || ret == SANE_STATUS_EOF) { + /* Special case- some scanners will under-report the amount of + * valid vpd that they send, and return the default length. + * Adding 4 more bytes allows us to include the overscan info. + * Scanners that don't support overscan seem to have all zeros + * in these bytes, so no harm is done. + * This may be an 'off-by-four' error in the firmware. */ + else if (payload_len == 0x5f){ + payload_len += 4; + } - DBG (15, "standard options\n"); + /* Having an offset from the beginning of the payload + * is more useful than from byte 4, as that matches the + * documentation more closely. */ + payload_off = payload_len + 4; - s->basic_x_res = get_IN_basic_x_res (in); - DBG (15, " basic x res: %d dpi\n",s->basic_x_res); + /* everything that appears in bytes 0 to 0x1d */ + DBG (15, "standard options\n"); - s->basic_y_res = get_IN_basic_y_res (in); - DBG (15, " basic y res: %d dpi\n",s->basic_y_res); + s->basic_x_res = get_IN_basic_x_res (in); + DBG (15, " basic x res: %d dpi\n",s->basic_x_res); - s->step_x_res[MODE_LINEART] = get_IN_step_x_res (in); - DBG (15, " step x res: %d dpi\n", s->step_x_res[MODE_LINEART]); + s->basic_y_res = get_IN_basic_y_res (in); + DBG (15, " basic y res: %d dpi\n",s->basic_y_res); - s->step_y_res[MODE_LINEART] = get_IN_step_y_res (in); - DBG (15, " step y res: %d dpi\n", s->step_y_res[MODE_LINEART]); + s->step_x_res[MODE_LINEART] = get_IN_step_x_res (in); + DBG (15, " step x res: %d dpi\n", s->step_x_res[MODE_LINEART]); - s->max_x_res = get_IN_max_x_res (in); - DBG (15, " max x res: %d dpi\n", s->max_x_res); + s->step_y_res[MODE_LINEART] = get_IN_step_y_res (in); + DBG (15, " step y res: %d dpi\n", s->step_y_res[MODE_LINEART]); - s->max_y_res = get_IN_max_y_res (in); - DBG (15, " max y res: %d dpi\n", s->max_y_res); + s->max_x_res = get_IN_max_x_res (in); + DBG (15, " max x res: %d dpi\n", s->max_x_res); - s->min_x_res = get_IN_min_x_res (in); - DBG (15, " min x res: %d dpi\n", s->min_x_res); + s->max_y_res = get_IN_max_y_res (in); + DBG (15, " max y res: %d dpi\n", s->max_y_res); - s->min_y_res = get_IN_min_y_res (in); - DBG (15, " min y res: %d dpi\n", s->min_y_res); + s->min_x_res = get_IN_min_x_res (in); + DBG (15, " min x res: %d dpi\n", s->min_x_res); - /* some scanners list B&W resolutions. */ - s->std_res[0] = get_IN_std_res_60 (in); - DBG (15, " 60 dpi: %d\n", s->std_res[0]); + s->min_y_res = get_IN_min_y_res (in); + DBG (15, " min y res: %d dpi\n", s->min_y_res); - s->std_res[1] = get_IN_std_res_75 (in); - DBG (15, " 75 dpi: %d\n", s->std_res[1]); + /* some scanners list B&W resolutions. */ + s->std_res[0] = get_IN_std_res_60 (in); + DBG (15, " 60 dpi: %d\n", s->std_res[0]); - s->std_res[2] = get_IN_std_res_100 (in); - DBG (15, " 100 dpi: %d\n", s->std_res[2]); + s->std_res[1] = get_IN_std_res_75 (in); + DBG (15, " 75 dpi: %d\n", s->std_res[1]); - s->std_res[3] = get_IN_std_res_120 (in); - DBG (15, " 120 dpi: %d\n", s->std_res[3]); + s->std_res[2] = get_IN_std_res_100 (in); + DBG (15, " 100 dpi: %d\n", s->std_res[2]); - s->std_res[4] = get_IN_std_res_150 (in); - DBG (15, " 150 dpi: %d\n", s->std_res[4]); + s->std_res[3] = get_IN_std_res_120 (in); + DBG (15, " 120 dpi: %d\n", s->std_res[3]); - s->std_res[5] = get_IN_std_res_160 (in); - DBG (15, " 160 dpi: %d\n", s->std_res[5]); + s->std_res[4] = get_IN_std_res_150 (in); + DBG (15, " 150 dpi: %d\n", s->std_res[4]); - s->std_res[6] = get_IN_std_res_180 (in); - DBG (15, " 180 dpi: %d\n", s->std_res[6]); + s->std_res[5] = get_IN_std_res_160 (in); + DBG (15, " 160 dpi: %d\n", s->std_res[5]); - s->std_res[7] = get_IN_std_res_200 (in); - DBG (15, " 200 dpi: %d\n", s->std_res[7]); + s->std_res[6] = get_IN_std_res_180 (in); + DBG (15, " 180 dpi: %d\n", s->std_res[6]); - s->std_res[8] = get_IN_std_res_240 (in); - DBG (15, " 240 dpi: %d\n", s->std_res[8]); + s->std_res[7] = get_IN_std_res_200 (in); + DBG (15, " 200 dpi: %d\n", s->std_res[7]); - s->std_res[9] = get_IN_std_res_300 (in); - DBG (15, " 300 dpi: %d\n", s->std_res[9]); + s->std_res[8] = get_IN_std_res_240 (in); + DBG (15, " 240 dpi: %d\n", s->std_res[8]); - s->std_res[10] = get_IN_std_res_320 (in); - DBG (15, " 320 dpi: %d\n", s->std_res[10]); + s->std_res[9] = get_IN_std_res_300 (in); + DBG (15, " 300 dpi: %d\n", s->std_res[9]); - s->std_res[11] = get_IN_std_res_400 (in); - DBG (15, " 400 dpi: %d\n", s->std_res[11]); + s->std_res[10] = get_IN_std_res_320 (in); + DBG (15, " 320 dpi: %d\n", s->std_res[10]); - s->std_res[12] = get_IN_std_res_480 (in); - DBG (15, " 480 dpi: %d\n", s->std_res[12]); + s->std_res[11] = get_IN_std_res_400 (in); + DBG (15, " 400 dpi: %d\n", s->std_res[11]); - s->std_res[13] = get_IN_std_res_600 (in); - DBG (15, " 600 dpi: %d\n", s->std_res[13]); + s->std_res[12] = get_IN_std_res_480 (in); + DBG (15, " 480 dpi: %d\n", s->std_res[12]); - s->std_res[14] = get_IN_std_res_800 (in); - DBG (15, " 800 dpi: %d\n", s->std_res[14]); + s->std_res[13] = get_IN_std_res_600 (in); + DBG (15, " 600 dpi: %d\n", s->std_res[13]); - s->std_res[15] = get_IN_std_res_1200 (in); - DBG (15, " 1200 dpi: %d\n", s->std_res[15]); + s->std_res[14] = get_IN_std_res_800 (in); + DBG (15, " 800 dpi: %d\n", s->std_res[14]); - /* maximum window width and length are reported in basic units.*/ - s->max_x_basic = get_IN_window_width(in); - DBG(15, " max width: %2.2f inches\n",(float)s->max_x_basic/s->basic_x_res); + s->std_res[15] = get_IN_std_res_1200 (in); + DBG (15, " 1200 dpi: %d\n", s->std_res[15]); - s->max_y_basic = get_IN_window_length(in); - DBG(15, " max length: %2.2f inches\n",(float)s->max_y_basic/s->basic_y_res); + /* maximum window width and length are reported in basic units.*/ + s->max_x_basic = get_IN_window_width(in); + DBG(15, " max width: %2.2f inches\n",(float)s->max_x_basic/s->basic_x_res); - /* known modes */ - s->can_overflow = get_IN_overflow(in); - DBG (15, " overflow: %d\n", s->can_overflow); + s->max_y_basic = get_IN_window_length(in); + DBG(15, " max length: %2.2f inches\n",(float)s->max_y_basic/s->basic_y_res); - s->can_mode[MODE_LINEART] = get_IN_monochrome (in); - DBG (15, " monochrome: %d\n", s->can_mode[MODE_LINEART]); + /* known modes */ + s->can_overflow = get_IN_overflow(in); + DBG (15, " overflow: %d\n", s->can_overflow); - s->can_mode[MODE_HALFTONE] = get_IN_half_tone (in); - DBG (15, " halftone: %d\n", s->can_mode[MODE_HALFTONE]); + s->can_mode[MODE_LINEART] = get_IN_monochrome (in); + DBG (15, " monochrome: %d\n", s->can_mode[MODE_LINEART]); - s->can_mode[MODE_GRAYSCALE] = get_IN_multilevel (in); - DBG (15, " grayscale: %d\n", s->can_mode[MODE_GRAYSCALE]); + s->can_mode[MODE_HALFTONE] = get_IN_half_tone (in); + DBG (15, " halftone: %d\n", s->can_mode[MODE_HALFTONE]); - DBG (15, " color_monochrome: %d\n", get_IN_monochrome_rgb(in)); - DBG (15, " color_halftone: %d\n", get_IN_half_tone_rgb(in)); + s->can_mode[MODE_GRAYSCALE] = get_IN_multilevel (in); + DBG (15, " grayscale: %d\n", s->can_mode[MODE_GRAYSCALE]); - s->can_mode[MODE_COLOR] = get_IN_multilevel_rgb (in); - DBG (15, " color_grayscale: %d\n", s->can_mode[MODE_COLOR]); + DBG (15, " color_monochrome: %d\n", get_IN_monochrome_rgb(in)); + DBG (15, " color_halftone: %d\n", get_IN_half_tone_rgb(in)); - /* now we look at vendor specific data */ - if (get_IN_page_length (in) >= 0x5f) { + s->can_mode[MODE_COLOR] = get_IN_multilevel_rgb (in); + DBG (15, " color_grayscale: %d\n", s->can_mode[MODE_COLOR]); - DBG (15, "vendor options\n"); + /* now we look at vendor specific data in bytes 0x1e onward */ + DBG (15, "vendor options\n"); - s->has_adf = get_IN_adf(in); - DBG (15, " adf: %d\n", s->has_adf); + s->has_adf = get_IN_adf(in); + DBG (15, " adf: %d\n", s->has_adf); - s->has_flatbed = get_IN_flatbed(in); - DBG (15, " flatbed: %d\n", s->has_flatbed); + s->has_flatbed = get_IN_flatbed(in); + DBG (15, " flatbed: %d\n", s->has_flatbed); - s->has_transparency = get_IN_transparency(in); - DBG (15, " transparency: %d\n", s->has_transparency); + s->has_transparency = get_IN_transparency(in); + DBG (15, " transparency: %d\n", s->has_transparency); - s->has_duplex = get_IN_duplex(in); - s->has_back = s->has_duplex; - DBG (15, " duplex: %d\n", s->has_duplex); + s->has_duplex = get_IN_duplex(in); + s->has_back = s->has_duplex; + DBG (15, " duplex: %d\n", s->has_duplex); - s->has_endorser_b = get_IN_endorser_b(in); - DBG (15, " back endorser: %d\n", s->has_endorser_b); + s->has_endorser_b = get_IN_endorser_b(in); + DBG (15, " back endorser: %d\n", s->has_endorser_b); - s->has_barcode = get_IN_barcode(in); - DBG (15, " barcode: %d\n", s->has_barcode); + s->has_barcode = get_IN_barcode(in); + DBG (15, " barcode: %d\n", s->has_barcode); - s->has_operator_panel = get_IN_operator_panel(in); - DBG (15, " operator panel: %d\n", s->has_operator_panel); + s->has_operator_panel = get_IN_operator_panel(in); + DBG (15, " operator panel: %d\n", s->has_operator_panel); - s->has_endorser_f = get_IN_endorser_f(in); - DBG (15, " front endorser: %d\n", s->has_endorser_f); + s->has_endorser_f = get_IN_endorser_f(in); + DBG (15, " front endorser: %d\n", s->has_endorser_f); - DBG (15, " multi-purpose stacker: %d\n", get_IN_mp_stacker(in)); + DBG (15, " multi-purpose stacker: %d\n", get_IN_mp_stacker(in)); - DBG (15, " prepick: %d\n", get_IN_prepick(in)); - DBG (15, " mf detect: %d\n", get_IN_mf_detect(in)); + DBG (15, " prepick: %d\n", get_IN_prepick(in)); + DBG (15, " mf detect: %d\n", get_IN_mf_detect(in)); - s->has_paper_protect = get_IN_paperprot(in); - DBG (15, " paper protection: %d\n", s->has_paper_protect); + s->has_paper_protect = get_IN_paperprot(in); + DBG (15, " paper protection: %d\n", s->has_paper_protect); - s->adbits = get_IN_adbits(in); - DBG (15, " A/D bits: %d\n",s->adbits); + s->adbits = get_IN_adbits(in); + DBG (15, " A/D bits: %d\n",s->adbits); - s->buffer_bytes = get_IN_buffer_bytes(in); - DBG (15, " buffer bytes: %d\n",s->buffer_bytes); + s->buffer_bytes = get_IN_buffer_bytes(in); + DBG (15, " buffer bytes: %d\n",s->buffer_bytes); - DBG (15, "Standard commands\n"); + DBG (15, "Standard commands\n"); - /* std scsi command support byte 26*/ - s->has_cmd_msen10 = get_IN_has_cmd_msen10(in); - DBG (15, " mode_sense_10 cmd: %d\n", s->has_cmd_msen10); + /* std scsi command support byte 26*/ + s->has_cmd_msen10 = get_IN_has_cmd_msen10(in); + DBG (15, " mode_sense_10 cmd: %d\n", s->has_cmd_msen10); - s->has_cmd_msel10 = get_IN_has_cmd_msel10(in); - DBG (15, " mode_select_10 cmd: %d\n", s->has_cmd_msel10); + s->has_cmd_msel10 = get_IN_has_cmd_msel10(in); + DBG (15, " mode_select_10 cmd: %d\n", s->has_cmd_msel10); - /* std scsi command support byte 27*/ - s->has_cmd_lsen = get_IN_has_cmd_lsen(in); - DBG (15, " log_sense cmd: %d\n", s->has_cmd_lsen); + /* std scsi command support byte 27*/ + s->has_cmd_lsen = get_IN_has_cmd_lsen(in); + DBG (15, " log_sense cmd: %d\n", s->has_cmd_lsen); - s->has_cmd_lsel = get_IN_has_cmd_lsel(in); - DBG (15, " log_select cmd: %d\n", s->has_cmd_lsel); + s->has_cmd_lsel = get_IN_has_cmd_lsel(in); + DBG (15, " log_select cmd: %d\n", s->has_cmd_lsel); - s->has_cmd_change = get_IN_has_cmd_change(in); - DBG (15, " change cmd: %d\n", s->has_cmd_change); + s->has_cmd_change = get_IN_has_cmd_change(in); + DBG (15, " change cmd: %d\n", s->has_cmd_change); - s->has_cmd_rbuff = get_IN_has_cmd_rbuff(in); - DBG (15, " read_buffer cmd: %d\n", s->has_cmd_rbuff); + s->has_cmd_rbuff = get_IN_has_cmd_rbuff(in); + DBG (15, " read_buffer cmd: %d\n", s->has_cmd_rbuff); - s->has_cmd_wbuff = get_IN_has_cmd_wbuff(in); - DBG (15, " write_buffer cmd: %d\n", s->has_cmd_wbuff); + s->has_cmd_wbuff = get_IN_has_cmd_wbuff(in); + DBG (15, " write_buffer cmd: %d\n", s->has_cmd_wbuff); - s->has_cmd_cav = get_IN_has_cmd_cav(in); - DBG (15, " copy_and_verify cmd: %d\n", s->has_cmd_cav); + s->has_cmd_cav = get_IN_has_cmd_cav(in); + DBG (15, " copy_and_verify cmd: %d\n", s->has_cmd_cav); - s->has_cmd_comp = get_IN_has_cmd_comp(in); - DBG (15, " compare cmd: %d\n", s->has_cmd_comp); + s->has_cmd_comp = get_IN_has_cmd_comp(in); + DBG (15, " compare cmd: %d\n", s->has_cmd_comp); - s->has_cmd_gdbs = get_IN_has_cmd_gdbs(in); - DBG (15, " get_d_b_status cmd: %d\n", s->has_cmd_gdbs); + s->has_cmd_gdbs = get_IN_has_cmd_gdbs(in); + DBG (15, " get_d_b_status cmd: %d\n", s->has_cmd_gdbs); - /* std scsi command support byte 28*/ - s->has_cmd_op = get_IN_has_cmd_op(in); - DBG (15, " object_pos cmd: %d\n", s->has_cmd_op); + /* std scsi command support byte 28*/ + s->has_cmd_op = get_IN_has_cmd_op(in); + DBG (15, " object_pos cmd: %d\n", s->has_cmd_op); - s->has_cmd_send = get_IN_has_cmd_send(in); - DBG (15, " send cmd: %d\n", s->has_cmd_send); + s->has_cmd_send = get_IN_has_cmd_send(in); + DBG (15, " send cmd: %d\n", s->has_cmd_send); - s->has_cmd_read = get_IN_has_cmd_read(in); - DBG (15, " read cmd: %d\n", s->has_cmd_read); + s->has_cmd_read = get_IN_has_cmd_read(in); + DBG (15, " read cmd: %d\n", s->has_cmd_read); - s->has_cmd_gwin = get_IN_has_cmd_gwin(in); - DBG (15, " get_window cmd: %d\n", s->has_cmd_gwin); + s->has_cmd_gwin = get_IN_has_cmd_gwin(in); + DBG (15, " get_window cmd: %d\n", s->has_cmd_gwin); - s->has_cmd_swin = get_IN_has_cmd_swin(in); - DBG (15, " set_window cmd: %d\n", s->has_cmd_swin); + s->has_cmd_swin = get_IN_has_cmd_swin(in); + DBG (15, " set_window cmd: %d\n", s->has_cmd_swin); - s->has_cmd_sdiag = get_IN_has_cmd_sdiag(in); - DBG (15, " send_diag cmd: %d\n", s->has_cmd_sdiag); + s->has_cmd_sdiag = get_IN_has_cmd_sdiag(in); + DBG (15, " send_diag cmd: %d\n", s->has_cmd_sdiag); - s->has_cmd_rdiag = get_IN_has_cmd_rdiag(in); - DBG (15, " read_diag cmd: %d\n", s->has_cmd_rdiag); + s->has_cmd_rdiag = get_IN_has_cmd_rdiag(in); + DBG (15, " read_diag cmd: %d\n", s->has_cmd_rdiag); - s->has_cmd_scan = get_IN_has_cmd_scan(in); - DBG (15, " scan cmd: %d\n", s->has_cmd_scan); + s->has_cmd_scan = get_IN_has_cmd_scan(in); + DBG (15, " scan cmd: %d\n", s->has_cmd_scan); - /* std scsi command support byte 29*/ - s->has_cmd_msen6 = get_IN_has_cmd_msen6(in); - DBG (15, " mode_sense_6 cmd: %d\n", s->has_cmd_msen6); + /* std scsi command support byte 29*/ + s->has_cmd_msen6 = get_IN_has_cmd_msen6(in); + DBG (15, " mode_sense_6 cmd: %d\n", s->has_cmd_msen6); - s->has_cmd_copy = get_IN_has_cmd_copy(in); - DBG (15, " copy cmd: %d\n", s->has_cmd_copy); + s->has_cmd_copy = get_IN_has_cmd_copy(in); + DBG (15, " copy cmd: %d\n", s->has_cmd_copy); - s->has_cmd_rel = get_IN_has_cmd_rel(in); - DBG (15, " release cmd: %d\n", s->has_cmd_rel); + s->has_cmd_rel = get_IN_has_cmd_rel(in); + DBG (15, " release cmd: %d\n", s->has_cmd_rel); - s->has_cmd_runit = get_IN_has_cmd_runit(in); - DBG (15, " reserve_unit cmd: %d\n", s->has_cmd_runit); + s->has_cmd_runit = get_IN_has_cmd_runit(in); + DBG (15, " reserve_unit cmd: %d\n", s->has_cmd_runit); - s->has_cmd_msel6 = get_IN_has_cmd_msel6(in); - DBG (15, " mode_select_6 cmd: %d\n", s->has_cmd_msel6); + s->has_cmd_msel6 = get_IN_has_cmd_msel6(in); + DBG (15, " mode_select_6 cmd: %d\n", s->has_cmd_msel6); - s->has_cmd_inq = get_IN_has_cmd_inq(in); - DBG (15, " inquiry cmd: %d\n", s->has_cmd_inq); + s->has_cmd_inq = get_IN_has_cmd_inq(in); + DBG (15, " inquiry cmd: %d\n", s->has_cmd_inq); - s->has_cmd_rs = get_IN_has_cmd_rs(in); - DBG (15, " request_sense cmd: %d\n", s->has_cmd_rs); + s->has_cmd_rs = get_IN_has_cmd_rs(in); + DBG (15, " request_sense cmd: %d\n", s->has_cmd_rs); - s->has_cmd_tur = get_IN_has_cmd_tur(in); - DBG (15, " test_unit_ready cmd: %d\n", s->has_cmd_tur); + s->has_cmd_tur = get_IN_has_cmd_tur(in); + DBG (15, " test_unit_ready cmd: %d\n", s->has_cmd_tur); - /* vendor added scsi command support */ - /* FIXME: there are more of these... */ - DBG (15, "Vendor commands\n"); + /* vendor added scsi command support */ + /* FIXME: there are more of these... */ + DBG (15, "Vendor commands\n"); - s->has_cmd_subwindow = get_IN_has_cmd_subwindow(in); - DBG (15, " subwindow cmd: %d\n", s->has_cmd_subwindow); + s->has_cmd_subwindow = get_IN_has_cmd_subwindow(in); + DBG (15, " subwindow cmd: %d\n", s->has_cmd_subwindow); - s->has_cmd_endorser = get_IN_has_cmd_endorser(in); - DBG (15, " endorser cmd: %d\n", s->has_cmd_endorser); + s->has_cmd_endorser = get_IN_has_cmd_endorser(in); + DBG (15, " endorser cmd: %d\n", s->has_cmd_endorser); - s->has_cmd_hw_status = get_IN_has_cmd_hw_status (in); - DBG (15, " hardware status cmd: %d\n", s->has_cmd_hw_status); + s->has_cmd_hw_status = get_IN_has_cmd_hw_status (in); + DBG (15, " hardware status cmd: %d\n", s->has_cmd_hw_status); - s->has_cmd_hw_status_2 = get_IN_has_cmd_hw_status_2 (in); - DBG (15, " hardware status 2 cmd: %d\n", s->has_cmd_hw_status_2); + s->has_cmd_hw_status_2 = get_IN_has_cmd_hw_status_2 (in); + DBG (15, " hardware status 2 cmd: %d\n", s->has_cmd_hw_status_2); - s->has_cmd_hw_status_3 = get_IN_has_cmd_hw_status_3 (in); - DBG (15, " hardware status 3 cmd: %d\n", s->has_cmd_hw_status_3); + s->has_cmd_hw_status_3 = get_IN_has_cmd_hw_status_3 (in); + DBG (15, " hardware status 3 cmd: %d\n", s->has_cmd_hw_status_3); - s->has_cmd_scanner_ctl = get_IN_has_cmd_scanner_ctl(in); - DBG (15, " scanner control cmd: %d\n", s->has_cmd_scanner_ctl); + s->has_cmd_scanner_ctl = get_IN_has_cmd_scanner_ctl(in); + DBG (15, " scanner control cmd: %d\n", s->has_cmd_scanner_ctl); - s->has_cmd_device_restart = get_IN_has_cmd_device_restart(in); - DBG (15, " device restart cmd: %d\n", s->has_cmd_device_restart); + s->has_cmd_device_restart = get_IN_has_cmd_device_restart(in); + DBG (15, " device restart cmd: %d\n", s->has_cmd_device_restart); - /* get threshold, brightness and contrast ranges. */ - s->brightness_steps = get_IN_brightness_steps(in); - DBG (15, " brightness steps: %d\n", s->brightness_steps); + /* get threshold, brightness and contrast ranges. */ + s->brightness_steps = get_IN_brightness_steps(in); + DBG (15, " brightness steps: %d\n", s->brightness_steps); - s->threshold_steps = get_IN_threshold_steps(in); - DBG (15, " threshold steps: %d\n", s->threshold_steps); + s->threshold_steps = get_IN_threshold_steps(in); + DBG (15, " threshold steps: %d\n", s->threshold_steps); - s->contrast_steps = get_IN_contrast_steps(in); - DBG (15, " contrast steps: %d\n", s->contrast_steps); + s->contrast_steps = get_IN_contrast_steps(in); + DBG (15, " contrast steps: %d\n", s->contrast_steps); - /* dither/gamma patterns */ - s->num_internal_gamma = get_IN_num_gamma_internal (in); - DBG (15, " built in gamma patterns: %d\n", s->num_internal_gamma); + /* dither/gamma patterns */ + s->num_internal_gamma = get_IN_num_gamma_internal (in); + DBG (15, " built in gamma patterns: %d\n", s->num_internal_gamma); - s->num_download_gamma = get_IN_num_gamma_download (in); - DBG (15, " download gamma patterns: %d\n", s->num_download_gamma); + s->num_download_gamma = get_IN_num_gamma_download (in); + DBG (15, " download gamma patterns: %d\n", s->num_download_gamma); - s->num_internal_dither = get_IN_num_dither_internal (in); - DBG (15, " built in dither patterns: %d\n", s->num_internal_dither); + s->num_internal_dither = get_IN_num_dither_internal (in); + DBG (15, " built in dither patterns: %d\n", s->num_internal_dither); - s->num_download_dither = get_IN_num_dither_download (in); - DBG (15, " download dither patterns: %d\n", s->num_download_dither); + s->num_download_dither = get_IN_num_dither_download (in); + DBG (15, " download dither patterns: %d\n", s->num_download_dither); - /* ipc functions */ - s->has_rif = get_IN_ipc_bw_rif (in); - DBG (15, " RIF: %d\n", s->has_rif); + /* ipc functions */ + s->has_rif = get_IN_ipc_bw_rif (in); + DBG (15, " RIF: %d\n", s->has_rif); - s->has_dtc = get_IN_ipc_dtc(in); - DBG (15, " DTC (AutoI): %d\n", s->has_dtc); + s->has_dtc = get_IN_ipc_dtc(in); + DBG (15, " DTC (AutoI): %d\n", s->has_dtc); - s->has_sdtc = get_IN_ipc_sdtc(in); - DBG (15, " SDTC (AutoII): %d\n", s->has_sdtc); + s->has_sdtc = get_IN_ipc_sdtc(in); + DBG (15, " SDTC (AutoII): %d\n", s->has_sdtc); - s->has_outline = get_IN_ipc_outline_extraction (in); - DBG (15, " outline extraction: %d\n", s->has_outline); + s->has_outline = get_IN_ipc_outline_extraction (in); + DBG (15, " outline extraction: %d\n", s->has_outline); - s->has_emphasis = get_IN_ipc_image_emphasis (in); - DBG (15, " image emphasis: %d\n", s->has_emphasis); + s->has_emphasis = get_IN_ipc_image_emphasis (in); + DBG (15, " image emphasis: %d\n", s->has_emphasis); - s->has_autosep = get_IN_ipc_auto_separation (in); - DBG (15, " automatic separation: %d\n", s->has_autosep); + s->has_autosep = get_IN_ipc_auto_separation (in); + DBG (15, " automatic separation: %d\n", s->has_autosep); - s->has_mirroring = get_IN_ipc_mirroring (in); - DBG (15, " mirror image: %d\n", s->has_mirroring); + s->has_mirroring = get_IN_ipc_mirroring (in); + DBG (15, " mirror image: %d\n", s->has_mirroring); - s->has_wl_follow = get_IN_ipc_wl_follow (in); - DBG (15, " white level follower: %d\n", s->has_wl_follow); + s->has_wl_follow = get_IN_ipc_wl_follow (in); + DBG (15, " white level follower: %d\n", s->has_wl_follow); - /* byte 58 */ - s->has_subwindow = get_IN_ipc_subwindow (in); - DBG (15, " subwindow: %d\n", s->has_subwindow); + /* byte 58 */ + s->has_subwindow = get_IN_ipc_subwindow (in); + DBG (15, " subwindow: %d\n", s->has_subwindow); - s->has_diffusion = get_IN_ipc_diffusion (in); - DBG (15, " diffusion: %d\n", s->has_diffusion); + s->has_diffusion = get_IN_ipc_diffusion (in); + DBG (15, " diffusion: %d\n", s->has_diffusion); - s->has_ipc3 = get_IN_ipc_ipc3 (in); - DBG (15, " ipc3: %d\n", s->has_ipc3); + s->has_ipc3 = get_IN_ipc_ipc3 (in); + DBG (15, " ipc3: %d\n", s->has_ipc3); - s->has_rotation = get_IN_ipc_rotation (in); - DBG (15, " rotation: %d\n", s->has_rotation); + s->has_rotation = get_IN_ipc_rotation (in); + DBG (15, " rotation: %d\n", s->has_rotation); - s->has_hybrid_crop_deskew = get_IN_ipc_hybrid_crop_deskew(in); - DBG (15, " hybrid crop deskew: %d\n", s->has_hybrid_crop_deskew); + s->has_hybrid_crop_deskew = get_IN_ipc_hybrid_crop_deskew(in); + DBG (15, " hybrid crop deskew: %d\n", s->has_hybrid_crop_deskew); - DBG (15, " ipc2 byte 67: %d\n", get_IN_ipc_ipc2_byte67(in)); + /* this one is weird, overrides the payload length from scanner */ + DBG (15, " vpd extends to byte 6f: %d\n", get_IN_vpd_thru_byte_6f(in)); + if(get_IN_vpd_thru_byte_6f(in) && payload_off < 0x6f){ + payload_off = 0x6f; + } - /* compression modes */ - s->has_comp_MH = get_IN_compression_MH (in); - DBG (15, " compression MH: %d\n", s->has_comp_MH); + /* compression modes */ + s->has_comp_MH = get_IN_compression_MH (in); + DBG (15, " compression MH: %d\n", s->has_comp_MH); - s->has_comp_MR = get_IN_compression_MR (in); - DBG (15, " compression MR: %d\n", s->has_comp_MR); + s->has_comp_MR = get_IN_compression_MR (in); + DBG (15, " compression MR: %d\n", s->has_comp_MR); - s->has_comp_MMR = get_IN_compression_MMR (in); - DBG (15, " compression MMR: %d\n", s->has_comp_MMR); + s->has_comp_MMR = get_IN_compression_MMR (in); + DBG (15, " compression MMR: %d\n", s->has_comp_MMR); - s->has_comp_JBIG = get_IN_compression_JBIG (in); - DBG (15, " compression JBIG: %d\n", s->has_comp_JBIG); + s->has_comp_JBIG = get_IN_compression_JBIG (in); + DBG (15, " compression JBIG: %d\n", s->has_comp_JBIG); - s->has_comp_JPG1 = get_IN_compression_JPG_BASE (in); - DBG (15, " compression JPG1: %d\n", s->has_comp_JPG1); + s->has_comp_JPG1 = get_IN_compression_JPG_BASE (in); + DBG (15, " compression JPG1: %d\n", s->has_comp_JPG1); #ifdef SANE_JPEG_DISABLED - DBG (15, " (Disabled)\n"); + DBG (15, " (Disabled)\n"); #endif - s->has_comp_JPG2 = get_IN_compression_JPG_EXT (in); - DBG (15, " compression JPG2: %d\n", s->has_comp_JPG2); - - s->has_comp_JPG3 = get_IN_compression_JPG_INDEP (in); - DBG (15, " compression JPG3: %d\n", s->has_comp_JPG3); - - /* FIXME: we dont store these? */ - DBG (15, " back endorser mech: %d\n", get_IN_endorser_b_mech(in)); - DBG (15, " back endorser stamp: %d\n", get_IN_endorser_b_stamp(in)); - DBG (15, " back endorser elec: %d\n", get_IN_endorser_b_elec(in)); - DBG (15, " endorser max id: %d\n", get_IN_endorser_max_id(in)); - - DBG (15, " front endorser mech: %d\n", get_IN_endorser_f_mech(in)); - DBG (15, " front endorser stamp: %d\n", get_IN_endorser_f_stamp(in)); - DBG (15, " front endorser elec: %d\n", get_IN_endorser_f_elec(in)); - - s->endorser_type_b = get_IN_endorser_b_type(in); - DBG (15, " back endorser type: %d\n", s->endorser_type_b); - - s->endorser_type_f = get_IN_endorser_f_type(in); - DBG (15, " back endorser type: %d\n", s->endorser_type_f); - - /*not all scanners go this far*/ - if (get_IN_page_length (in) >= 0x67-5) { - DBG (15, " connection type: %d\n", get_IN_connection(in)); - - DBG (15, " endorser ext: %d\n", get_IN_endorser_type_ext(in)); - DBG (15, " endorser pr_b: %d\n", get_IN_endorser_pre_back(in)); - DBG (15, " endorser pr_f: %d\n", get_IN_endorser_pre_front(in)); - DBG (15, " endorser po_b: %d\n", get_IN_endorser_post_back(in)); - DBG (15, " endorser po_f: %d\n", get_IN_endorser_post_front(in)); - - s->os_x_basic = get_IN_x_overscan_size(in); - DBG (15, " horizontal overscan: %d\n", s->os_x_basic); - - s->os_y_basic = get_IN_y_overscan_size(in); - DBG (15, " vertical overscan: %d\n", s->os_y_basic); - } + s->has_comp_JPG2 = get_IN_compression_JPG_EXT (in); + DBG (15, " compression JPG2: %d\n", s->has_comp_JPG2); - if (get_IN_page_length (in) >= 0x70-5) { - DBG (15, " default bg adf b: %d\n", get_IN_default_bg_adf_b(in)); - DBG (15, " default bg adf f: %d\n", get_IN_default_bg_adf_f(in)); - DBG (15, " default bg fb: %d\n", get_IN_default_bg_fb(in)); + s->has_comp_JPG3 = get_IN_compression_JPG_INDEP (in); + DBG (15, " compression JPG3: %d\n", s->has_comp_JPG3); - DBG (15, " auto color: %d\n", get_IN_auto_color(in)); - DBG (15, " blank skip: %d\n", get_IN_blank_skip(in)); - DBG (15, " multi image: %d\n", get_IN_multi_image(in)); - DBG (15, " f b type indep: %d\n", get_IN_f_b_type_indep(in)); - DBG (15, " f b res indep: %d\n", get_IN_f_b_res_indep(in)); + /* FIXME: we dont store these? */ + DBG (15, " back endorser mech: %d\n", get_IN_endorser_b_mech(in)); + DBG (15, " back endorser stamp: %d\n", get_IN_endorser_b_stamp(in)); + DBG (15, " back endorser elec: %d\n", get_IN_endorser_b_elec(in)); + DBG (15, " endorser max id: %d\n", get_IN_endorser_max_id(in)); - DBG (15, " dropout spec: %d\n", get_IN_dropout_spec(in)); - DBG (15, " dropout non: %d\n", get_IN_dropout_non(in)); - DBG (15, " dropout white: %d\n", get_IN_dropout_white(in)); + DBG (15, " front endorser mech: %d\n", get_IN_endorser_f_mech(in)); + DBG (15, " front endorser stamp: %d\n", get_IN_endorser_f_stamp(in)); + DBG (15, " front endorser elec: %d\n", get_IN_endorser_f_elec(in)); - DBG (15, " skew check: %d\n", get_IN_skew_check(in)); - DBG (15, " new feed roller: %d\n", get_IN_new_fd_roll(in)); + s->endorser_type_b = get_IN_endorser_b_type(in); + DBG (15, " back endorser type: %d\n", s->endorser_type_b); - s->has_adv_paper_prot = get_IN_paper_prot_2(in); - DBG (15, " paper protection: %d\n", s->has_adv_paper_prot); - } + s->endorser_type_f = get_IN_endorser_f_type(in); + DBG (15, " back endorser type: %d\n", s->endorser_type_f); - if (get_IN_page_length (in) > 0x70-5) { + DBG (15, " connection type: %d\n", get_IN_connection(in)); - DBG (15, " paper count: %d\n", get_IN_paper_count(in)); - DBG (15, " paper number: %d\n", get_IN_paper_number(in)); - DBG (15, " ext send to: %d\n", get_IN_ext_send_to(in)); + DBG (15, " endorser ext: %d\n", get_IN_endorser_type_ext(in)); + DBG (15, " endorser pr_b: %d\n", get_IN_endorser_pre_back(in)); + DBG (15, " endorser pr_f: %d\n", get_IN_endorser_pre_front(in)); + DBG (15, " endorser po_b: %d\n", get_IN_endorser_post_back(in)); + DBG (15, " endorser po_f: %d\n", get_IN_endorser_post_front(in)); - s->has_staple_detect = get_IN_staple_det(in); - DBG (15, " staple det: %d\n", s->has_staple_detect); + s->os_x_basic = get_IN_x_overscan_size(in); + DBG (15, " horizontal overscan: %d\n", s->os_x_basic); - DBG (15, " pause host: %d\n", get_IN_pause_host(in)); - DBG (15, " pause panel: %d\n", get_IN_pause_panel(in)); - DBG (15, " pause conf: %d\n", get_IN_pause_conf(in)); - DBG (15, " hq print: %d\n", get_IN_hq_print(in)); + s->os_y_basic = get_IN_y_overscan_size(in); + DBG (15, " vertical overscan: %d\n", s->os_y_basic); - DBG (15, " ext GHS len: %d\n", get_IN_ext_GHS_len(in)); + /* not all scanners go this far */ + if (payload_off >= 0x68) { + DBG (15, " default bg adf b: %d\n", get_IN_default_bg_adf_b(in)); + DBG (15, " default bg adf f: %d\n", get_IN_default_bg_adf_f(in)); + DBG (15, " default bg fb: %d\n", get_IN_default_bg_fb(in)); + } - DBG (15, " smbc func: %d\n", get_IN_smbc_func(in)); - DBG (15, " imprint chk b: %d\n", get_IN_imprint_chk_b(in)); - DBG (15, " imprint chk f: %d\n", get_IN_imprint_chk_f(in)); - DBG (15, " force w bg: %d\n", get_IN_force_w_bg(in)); + if (payload_off >= 0x69) { + DBG (15, " auto color: %d\n", get_IN_auto_color(in)); + DBG (15, " blank skip: %d\n", get_IN_blank_skip(in)); + DBG (15, " multi image: %d\n", get_IN_multi_image(in)); + DBG (15, " f b type indep: %d\n", get_IN_f_b_type_indep(in)); + DBG (15, " f b res indep: %d\n", get_IN_f_b_res_indep(in)); + } - s->has_df_recovery = get_IN_mf_recover_lvl(in); - DBG (15, " mf recover lvl: %d\n", s->has_df_recovery); + if (payload_off >= 0x6a) { + DBG (15, " dropout spec: %d\n", get_IN_dropout_spec(in)); + DBG (15, " dropout non: %d\n", get_IN_dropout_non(in)); + DBG (15, " dropout white: %d\n", get_IN_dropout_white(in)); + } - DBG (15, " first read time: %d\n", get_IN_first_read_time(in)); - DBG (15, " div scanning: %d\n", get_IN_div_scanning(in)); - DBG (15, " start job: %d\n", get_IN_start_job(in)); - DBG (15, " lifetime log: %d\n", get_IN_lifetime_log(in)); - DBG (15, " imff save rest: %d\n", get_IN_imff_save_rest(in)); - DBG (15, " wide scsi type: %d\n", get_IN_wide_scsi_type(in)); + if (payload_off >= 0x6d) { + DBG (15, " skew check: %d\n", get_IN_skew_check(in)); + DBG (15, " new feed roller: %d\n", get_IN_new_fd_roll(in)); + s->has_adv_paper_prot = get_IN_paper_prot_2(in); + DBG (15, " paper protection: %d\n", s->has_adv_paper_prot); + } - DBG (15, " lut hybrid crop: %d\n", get_IN_lut_hybrid_crop(in)); - DBG (15, " over under amt: %d\n", get_IN_over_under_amt(in)); - DBG (15, " rgb lut: %d\n", get_IN_rgb_lut(in)); - DBG (15, " num lut dl: %d\n", get_IN_num_lut_dl(in)); + /* this one is weird, overrides the payload length from scanner, + * but the enlarged area is just null bytes, so we ignore this */ + if (payload_off >= 0x6f) { + DBG (15, " extra evpd length: %d\n", get_IN_evpd_len(in)); + } - s->has_off_mode = get_IN_erp_lot6_supp(in); - DBG (15, " ErP Lot6 (power off timer): %d\n", s->has_off_mode); - DBG (15, " sync next feed: %d\n", get_IN_sync_next_feed(in)); + if (payload_off >= 0x70) { + DBG (15, " paper count: %d\n", get_IN_paper_count(in)); + DBG (15, " paper number: %d\n", get_IN_paper_number(in)); + DBG (15, " ext send to: %d\n", get_IN_ext_send_to(in)); - s->has_op_halt = get_IN_op_halt(in); - DBG (15, " object position halt: %d\n", s->has_op_halt); - } + s->has_staple_detect = get_IN_staple_det(in); + DBG (15, " staple det: %d\n", s->has_staple_detect); - ret = SANE_STATUS_GOOD; - } + DBG (15, " pause host: %d\n", get_IN_pause_host(in)); + DBG (15, " pause panel: %d\n", get_IN_pause_panel(in)); + DBG (15, " pause conf: %d\n", get_IN_pause_conf(in)); + DBG (15, " hq print: %d\n", get_IN_hq_print(in)); + } - /*FIXME no vendor vpd, set some defaults? */ - else{ - DBG (5, "init_vpd: Your scanner supports only partial VPD?\n"); - DBG (5, "init_vpd: Please contact kitno455 at gmail dot com\n"); - DBG (5, "init_vpd: with details of your scanner model.\n"); - ret = SANE_STATUS_INVAL; - } + if (payload_off >= 0x71) { + DBG (15, " ext GHS len: %d\n", get_IN_ext_GHS_len(in)); } - /*FIXME no vpd, set some defaults? */ - else{ - DBG (5, "init_vpd: Your scanner does not support VPD?\n"); - DBG (5, "init_vpd: Please contact kitno455 at gmail dot com\n"); - DBG (5, "init_vpd: with details of your scanner model.\n"); + + if (payload_off >= 0x72) { + DBG (15, " smbc func: %d\n", get_IN_smbc_func(in)); + DBG (15, " imprint chk b: %d\n", get_IN_imprint_chk_b(in)); + DBG (15, " imprint chk f: %d\n", get_IN_imprint_chk_f(in)); + DBG (15, " force w bg: %d\n", get_IN_force_w_bg(in)); + + s->has_df_recovery = get_IN_mf_recover_lvl(in); + DBG (15, " mf recover lvl: %d\n", s->has_df_recovery); + } + + if (payload_off >= 0x73) { + DBG (15, " first read time: %d\n", get_IN_first_read_time(in)); + DBG (15, " div scanning: %d\n", get_IN_div_scanning(in)); + DBG (15, " start job: %d\n", get_IN_start_job(in)); + DBG (15, " lifetime log: %d\n", get_IN_lifetime_log(in)); + DBG (15, " imff save rest: %d\n", get_IN_imff_save_rest(in)); + DBG (15, " wide scsi type: %d\n", get_IN_wide_scsi_type(in)); + } + + if (payload_off >= 0x74) { + DBG (15, " lut hybrid crop: %d\n", get_IN_lut_hybrid_crop(in)); + DBG (15, " over under amt: %d\n", get_IN_over_under_amt(in)); + DBG (15, " rgb lut: %d\n", get_IN_rgb_lut(in)); + DBG (15, " num lut dl: %d\n", get_IN_num_lut_dl(in)); + } + + /* Various items below are poorly documented or missing */ + + if (payload_off >= 0x76) { + s->has_off_mode = get_IN_erp_lot6_supp(in); + DBG (15, " ErP Lot6 (power off timer): %d\n", s->has_off_mode); + DBG (15, " sync next feed: %d\n", get_IN_sync_next_feed(in)); + } + + if (payload_off >= 0x79) { + DBG (15, " battery: %d\n", get_IN_battery(in)); + DBG (15, " battery save: %d\n", get_IN_battery_save(in)); + DBG (15, " object position reverse: %d\n", get_IN_op_reverse(in)); + } + + if (payload_off >= 0x7a) { + s->has_op_halt = get_IN_op_halt(in); + DBG (15, " object position halt: %d\n", s->has_op_halt); } DBG (10, "init_vpd: finish\n"); - return ret; + return SANE_STATUS_GOOD; } static SANE_Status -init_ms(struct fujitsu *s) +init_ms(struct fujitsu *s) { int ret; int oldDbg=0; @@ -2543,9 +2590,9 @@ init_options (struct fujitsu *s) s->opt[i].cap = SANE_CAP_INACTIVE; } - /* go ahead and setup the first opt, because - * frontend may call control_option on it - * before calling get_option_descriptor + /* go ahead and setup the first opt, because + * frontend may call control_option on it + * before calling get_option_descriptor */ s->opt[OPT_NUM_OPTS].name = SANE_NAME_NUM_OPTIONS; s->opt[OPT_NUM_OPTS].title = SANE_TITLE_NUM_OPTIONS; @@ -2660,11 +2707,11 @@ init_serial (struct fujitsu *s) set_SCSI_opcode(cmd, SEND_DIAGNOSTIC_code); set_SD_slftst(cmd, 0); set_SD_xferlen(cmd, outLen); - + memcpy(out,SD_gdi_string,outLen); ret = do_cmd ( - s, 1, 0, + s, 1, 0, cmd, cmdLen, out, outLen, NULL, NULL @@ -2680,7 +2727,7 @@ init_serial (struct fujitsu *s) set_RD_xferlen(cmd, inLen); ret = do_cmd ( - s, 1, 0, + s, 1, 0, cmd, cmdLen, NULL, 0, in, &inLen @@ -2719,7 +2766,7 @@ sane_open (SANE_String_Const name, SANE_Handle * handle) struct fujitsu *dev = NULL; struct fujitsu *s = NULL; SANE_Status ret; - + DBG (10, "sane_open: start\n"); if(fujitsu_devList){ @@ -2740,7 +2787,7 @@ sane_open (SANE_String_Const name, SANE_Handle * handle) } else{ DBG (15, "sane_open: device %s requested\n", name); - + for (dev = fujitsu_devList; dev; dev = dev->next) { if (strcmp (dev->sane.name, name) == 0 || strcmp (dev->device_name, name) == 0) { /*always allow sanei devname*/ @@ -2816,7 +2863,7 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) } if(s->has_adf){ s->source_list[i++]=STRING_ADFFRONT; - + if(s->has_back){ s->source_list[i++]=STRING_ADFBACK; } @@ -2852,7 +2899,7 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) s->mode_list[i++]=STRING_COLOR; } s->mode_list[i]=NULL; - + opt->name = SANE_NAME_SCAN_MODE; opt->title = SANE_TITLE_SCAN_MODE; opt->desc = SANE_DESC_SCAN_MODE; @@ -2873,7 +2920,7 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) opt->type = SANE_TYPE_INT; opt->unit = SANE_UNIT_DPI; opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT; - + if(s->step_x_res[s->s_mode] && s->step_y_res[s->s_mode]){ s->res_range.min = s->min_x_res; s->res_range.max = s->max_x_res; @@ -2895,7 +2942,7 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) } } s->res_list[0] = i; - + opt->constraint_type = SANE_CONSTRAINT_WORD_LIST; opt->constraint.word_list = s->res_list; } @@ -2917,7 +2964,7 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) s->tl_x_range.min = SCANNER_UNIT_TO_FIXED_MM(s->min_x); s->tl_x_range.max = SCANNER_UNIT_TO_FIXED_MM(get_page_width(s)); s->tl_x_range.quant = MM_PER_UNIT_FIX; - + opt->name = SANE_NAME_SCAN_TL_X; opt->title = SANE_TITLE_SCAN_TL_X; opt->desc = SANE_DESC_SCAN_TL_X; @@ -2935,7 +2982,7 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) s->tl_y_range.min = SCANNER_UNIT_TO_FIXED_MM(s->min_y); s->tl_y_range.max = SCANNER_UNIT_TO_FIXED_MM(get_page_height(s)); s->tl_y_range.quant = MM_PER_UNIT_FIX; - + opt->name = SANE_NAME_SCAN_TL_Y; opt->title = SANE_TITLE_SCAN_TL_Y; opt->desc = SANE_DESC_SCAN_TL_Y; @@ -2953,7 +3000,7 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) s->br_x_range.min = SCANNER_UNIT_TO_FIXED_MM(s->min_x); s->br_x_range.max = SCANNER_UNIT_TO_FIXED_MM(get_page_width(s)); s->br_x_range.quant = MM_PER_UNIT_FIX; - + opt->name = SANE_NAME_SCAN_BR_X; opt->title = SANE_TITLE_SCAN_BR_X; opt->desc = SANE_DESC_SCAN_BR_X; @@ -2971,7 +3018,7 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) s->br_y_range.min = SCANNER_UNIT_TO_FIXED_MM(s->min_y); s->br_y_range.max = SCANNER_UNIT_TO_FIXED_MM(get_page_height(s)); s->br_y_range.quant = MM_PER_UNIT_FIX; - + opt->name = SANE_NAME_SCAN_BR_Y; opt->title = SANE_TITLE_SCAN_BR_Y; opt->desc = SANE_DESC_SCAN_BR_Y; @@ -3160,7 +3207,7 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) s->ht_type_list[i++]=STRING_DITHER; s->ht_type_list[i++]=STRING_DIFFUSION; s->ht_type_list[i]=NULL; - + opt->name = "ht-type"; opt->title = SANE_I18N ("Halftone type"); opt->desc = SANE_I18N ("Control type of halftone filter"); @@ -3265,7 +3312,7 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) s->wl_follow_list[i++]=STRING_ON; s->wl_follow_list[i++]=STRING_OFF; s->wl_follow_list[i]=NULL; - + opt->name = "wl-follow"; opt->title = SANE_I18N ("White level follower"); opt->desc = SANE_I18N ("Control white level follower"); @@ -3503,7 +3550,7 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) /*automatic width detection */ if(option==OPT_AWD){ - + opt->name = "awd"; opt->title = SANE_I18N ("Auto width detection"); opt->desc = SANE_I18N ("Scanner detects paper sides. May reduce scanning speed."); @@ -3521,7 +3568,7 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) /*automatic length detection */ if(option==OPT_ALD){ - + opt->name = "ald"; opt->title = SANE_I18N ("Auto length detection"); opt->desc = SANE_I18N ("Scanner detects paper lower edge. May confuse some frontends."); @@ -3600,7 +3647,7 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) s->df_action_list[1] = STRING_CONTINUE; s->df_action_list[2] = STRING_STOP; s->df_action_list[3] = NULL; - + opt->name = "df-action"; opt->title = SANE_I18N ("DF action"); opt->desc = SANE_I18N ("Action following double feed error"); @@ -3617,7 +3664,7 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) /*double feed by skew*/ if(option==OPT_DF_SKEW){ - + opt->name = "df-skew"; opt->title = SANE_I18N ("DF skew"); opt->desc = SANE_I18N ("Enable double feed error due to skew"); @@ -3636,7 +3683,7 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) /*double feed by thickness */ if(option==OPT_DF_THICKNESS){ - + opt->name = "df-thickness"; opt->title = SANE_I18N ("DF thickness"); opt->desc = SANE_I18N ("Enable double feed error due to paper thickness"); @@ -3655,7 +3702,7 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) /*double feed by length*/ if(option==OPT_DF_LENGTH){ - + opt->name = "df-length"; opt->title = SANE_I18N ("DF length"); opt->desc = SANE_I18N ("Enable double feed error due to paper length"); @@ -3679,7 +3726,7 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) s->df_diff_list[2] = STRING_15MM; s->df_diff_list[3] = STRING_20MM; s->df_diff_list[4] = NULL; - + opt->name = "df-diff"; opt->title = SANE_I18N ("DF length difference"); opt->desc = SANE_I18N ("Difference in page length to trigger double feed error"); @@ -3703,7 +3750,7 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) s->df_recovery_list[1] = STRING_OFF; s->df_recovery_list[2] = STRING_ON; s->df_recovery_list[3] = NULL; - + opt->name = "df-recovery"; opt->title = SANE_I18N ("DF recovery mode"); opt->desc = SANE_I18N ("Request scanner to reverse feed on paper jam"); @@ -3723,7 +3770,7 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) s->paper_protect_list[1] = STRING_OFF; s->paper_protect_list[2] = STRING_ON; s->paper_protect_list[3] = NULL; - + opt->name = "paper-protect"; opt->title = SANE_I18N ("Paper protection"); opt->desc = SANE_I18N ("Request scanner to predict jams in the ADF"); @@ -3743,7 +3790,7 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) s->adv_paper_prot_list[1] = STRING_OFF; s->adv_paper_prot_list[2] = STRING_ON; s->adv_paper_prot_list[3] = NULL; - + opt->name = "adv-paper-protect"; opt->title = SANE_I18N ("Advanced paper protection"); opt->desc = SANE_I18N ("Request scanner to predict jams in the ADF using improved sensors"); @@ -3763,7 +3810,7 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) s->staple_detect_list[1] = STRING_OFF; s->staple_detect_list[2] = STRING_ON; s->staple_detect_list[3] = NULL; - + opt->name = "staple-detect"; opt->title = SANE_I18N ("Staple detection"); opt->desc = SANE_I18N ("Request scanner to detect jams in the ADF caused by staples"); @@ -3783,7 +3830,7 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) s->bg_color_list[1] = STRING_WHITE; s->bg_color_list[2] = STRING_BLACK; s->bg_color_list[3] = NULL; - + opt->name = "bgcolor"; opt->title = SANE_I18N ("Background color"); opt->desc = SANE_I18N ("Set color of background for scans. May conflict with overscan option"); @@ -3804,7 +3851,7 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) s->do_color_list[2] = STRING_GREEN; s->do_color_list[3] = STRING_BLUE; s->do_color_list[4] = NULL; - + opt->name = "dropoutcolor"; opt->title = SANE_I18N ("Dropout color"); opt->desc = SANE_I18N ("One-pass scanners use only one color during gray or binary scanning, useful for colored paper or ink"); @@ -3828,7 +3875,7 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) s->buff_mode_list[1] = STRING_OFF; s->buff_mode_list[2] = STRING_ON; s->buff_mode_list[3] = NULL; - + opt->name = "buffermode"; opt->title = SANE_I18N ("Buffer mode"); opt->desc = SANE_I18N ("Request scanner to read pages quickly from ADF into internal memory"); @@ -3848,7 +3895,7 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) s->prepick_list[1] = STRING_OFF; s->prepick_list[2] = STRING_ON; s->prepick_list[3] = NULL; - + opt->name = "prepick"; opt->title = SANE_I18N ("Prepick"); opt->desc = SANE_I18N ("Request scanner to grab next page from ADF"); @@ -3868,7 +3915,7 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) s->overscan_list[1] = STRING_OFF; s->overscan_list[2] = STRING_ON; s->overscan_list[3] = NULL; - + opt->name = "overscan"; opt->title = SANE_I18N ("Overscan"); opt->desc = SANE_I18N ("Collect a few mm of background on top side of scan, before paper enters ADF, and increase maximum scan area beyond paper size, to allow collection on remaining sides. May conflict with bgcolor option"); @@ -3887,10 +3934,10 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) s->sleep_time_range.min = 0; s->sleep_time_range.max = 60; s->sleep_time_range.quant = 1; - + opt->name = "sleeptimer"; opt->title = SANE_I18N ("Sleep timer"); - opt->desc = SANE_I18N ("Time in minutes until the internal power supply switches to sleep mode"); + opt->desc = SANE_I18N ("Time in minutes until the internal power supply switches to sleep mode"); opt->type = SANE_TYPE_INT; opt->unit = SANE_UNIT_NONE; opt->constraint_type = SANE_CONSTRAINT_RANGE; @@ -3906,10 +3953,10 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) s->off_time_range.min = 0; s->off_time_range.max = 960; s->off_time_range.quant = 1; - + opt->name = "offtimer"; opt->title = SANE_I18N ("Off timer"); - opt->desc = SANE_I18N ("Time in minutes until the internal power supply switches the scanner off. Will be rounded to nearest 15 minutes. Zero means never power off."); + opt->desc = SANE_I18N ("Time in minutes until the internal power supply switches the scanner off. Will be rounded to nearest 15 minutes. Zero means never power off."); opt->type = SANE_TYPE_INT; opt->unit = SANE_UNIT_NONE; opt->constraint_type = SANE_CONSTRAINT_RANGE; @@ -3925,7 +3972,7 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) s->duplex_offset_range.min = -16; s->duplex_offset_range.max = 16; s->duplex_offset_range.quant = 1; - + opt->name = "duplexoffset"; opt->title = SANE_I18N ("Duplex offset"); opt->desc = SANE_I18N ("Adjust front/back offset"); @@ -3943,7 +3990,7 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) s->green_offset_range.min = -16; s->green_offset_range.max = 16; s->green_offset_range.quant = 1; - + opt->name = "greenoffset"; opt->title = SANE_I18N ("Green offset"); opt->desc = SANE_I18N ("Adjust green/red offset"); @@ -3956,12 +4003,12 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) else opt->cap = SANE_CAP_INACTIVE; } - + if(option==OPT_BLUE_OFFSET){ s->blue_offset_range.min = -16; s->blue_offset_range.max = 16; s->blue_offset_range.quant = 1; - + opt->name = "blueoffset"; opt->title = SANE_I18N ("Blue offset"); opt->desc = SANE_I18N ("Adjust blue/red offset"); @@ -3974,7 +4021,7 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) else opt->cap = SANE_CAP_INACTIVE; } - + if(option==OPT_LOW_MEM){ opt->name = "lowmemory"; opt->title = SANE_I18N ("Low Memory"); @@ -3985,7 +4032,7 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) if (1) opt->cap= SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED; - else + else opt->cap = SANE_CAP_INACTIVE; opt->constraint_type = SANE_CONSTRAINT_NONE; @@ -4112,7 +4159,7 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) if (s->has_endorser_f || s->has_endorser_b) opt->cap= SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED; - else + else opt->cap = SANE_CAP_INACTIVE; opt->constraint_type = SANE_CONSTRAINT_NONE; @@ -4335,7 +4382,7 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) opt->unit = SANE_UNIT_NONE; if (s->has_cmd_hw_status || s->ghs_in_rs) opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; - else + else opt->cap = SANE_CAP_INACTIVE; } @@ -4347,7 +4394,7 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) opt->unit = SANE_UNIT_NONE; if (s->has_cmd_hw_status) opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; - else + else opt->cap = SANE_CAP_INACTIVE; } @@ -4359,7 +4406,7 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) opt->unit = SANE_UNIT_NONE; if (s->has_cmd_hw_status) opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; - else + else opt->cap = SANE_CAP_INACTIVE; } @@ -4371,7 +4418,7 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) opt->unit = SANE_UNIT_NONE; if (s->has_cmd_hw_status) opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; - else + else opt->cap = SANE_CAP_INACTIVE; } @@ -4383,7 +4430,7 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) opt->unit = SANE_UNIT_NONE; if (s->has_cmd_hw_status) opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; - else + else opt->cap = SANE_CAP_INACTIVE; } @@ -4395,7 +4442,7 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) opt->unit = SANE_UNIT_NONE; if (s->has_cmd_hw_status || s->ghs_in_rs) opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; - else + else opt->cap = SANE_CAP_INACTIVE; } @@ -4407,7 +4454,7 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) opt->unit = SANE_UNIT_NONE; if (s->has_cmd_hw_status) opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; - else + else opt->cap = SANE_CAP_INACTIVE; } @@ -4419,7 +4466,7 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) opt->unit = SANE_UNIT_NONE; if (s->has_cmd_hw_status || s->ghs_in_rs) opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; - else + else opt->cap = SANE_CAP_INACTIVE; } @@ -4431,7 +4478,7 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) opt->unit = SANE_UNIT_NONE; if (s->has_cmd_hw_status) opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; - else + else opt->cap = SANE_CAP_INACTIVE; } @@ -4443,7 +4490,7 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) opt->unit = SANE_UNIT_NONE; if (s->has_cmd_hw_status || s->ghs_in_rs) opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; - else + else opt->cap = SANE_CAP_INACTIVE; } @@ -4455,7 +4502,7 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) opt->unit = SANE_UNIT_NONE; if (s->has_cmd_hw_status) opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; - else + else opt->cap = SANE_CAP_INACTIVE; } @@ -4467,7 +4514,7 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) opt->unit = SANE_UNIT_NONE; if (s->has_cmd_hw_status || s->ghs_in_rs) opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; - else + else opt->cap = SANE_CAP_INACTIVE; } @@ -4479,7 +4526,7 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) opt->unit = SANE_UNIT_NONE; if (s->has_cmd_hw_status || s->ghs_in_rs) opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; - else + else opt->cap = SANE_CAP_INACTIVE; } @@ -4491,7 +4538,7 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) opt->unit = SANE_UNIT_NONE; if (s->has_cmd_hw_status && (s->has_endorser_f || s->has_endorser_b)) opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; - else + else opt->cap = SANE_CAP_INACTIVE; } @@ -4503,7 +4550,7 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) opt->unit = SANE_UNIT_NONE; if (s->has_cmd_hw_status || s->ghs_in_rs) opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; - else + else opt->cap = SANE_CAP_INACTIVE; } @@ -4515,7 +4562,7 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) opt->unit = SANE_UNIT_NONE; if (s->has_cmd_hw_status) opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; - else + else opt->cap = SANE_CAP_INACTIVE; } @@ -4527,7 +4574,7 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) opt->unit = SANE_UNIT_NONE; if (s->has_cmd_hw_status) opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; - else + else opt->cap = SANE_CAP_INACTIVE; } @@ -4539,7 +4586,7 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) opt->unit = SANE_UNIT_NONE; if (s->has_cmd_hw_status && (s->has_endorser_f || s->has_endorser_b)) opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; - else + else opt->cap = SANE_CAP_INACTIVE; } @@ -4551,7 +4598,7 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) opt->unit = SANE_UNIT_NONE; if (s->ghs_in_rs) opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; - else + else opt->cap = SANE_CAP_INACTIVE; } @@ -4563,7 +4610,7 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) opt->unit = SANE_UNIT_NONE; if (s->ghs_in_rs) opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED; - else + else opt->cap = SANE_CAP_INACTIVE; } @@ -4572,7 +4619,7 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) /** * Gets or sets an option value. - * + * * From the SANE spec: * This function is used to set or inquire the current value of option * number n of the device represented by handle h. The manner in which @@ -4583,7 +4630,7 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) * area pointed to by v must be big enough to hold the entire option * value (determined by member size in the corresponding option * descriptor). - * + * * The only exception to this rule is that when setting the value of a * string option, the string pointed to by argument v may be shorter * since the backend will stop reading the option value upon @@ -5056,23 +5103,23 @@ sane_control_option (SANE_Handle handle, SANE_Int option, case OPT_ENDORSER: *val_p = s->u_endorser; return SANE_STATUS_GOOD; - + case OPT_ENDORSER_BITS: *val_p = s->u_endorser_bits; return SANE_STATUS_GOOD; - + case OPT_ENDORSER_VAL: *val_p = s->u_endorser_val; return SANE_STATUS_GOOD; - + case OPT_ENDORSER_STEP: *val_p = s->u_endorser_step; return SANE_STATUS_GOOD; - + case OPT_ENDORSER_Y: *val_p = SCANNER_UNIT_TO_FIXED_MM(s->u_endorser_y); return SANE_STATUS_GOOD; - + case OPT_ENDORSER_FONT: switch (s->u_endorser_font) { case FONT_H: @@ -5092,7 +5139,7 @@ sane_control_option (SANE_Handle handle, SANE_Int option, break; } return SANE_STATUS_GOOD; - + case OPT_ENDORSER_DIR: switch (s->u_endorser_dir) { case DIR_TTB: @@ -5103,7 +5150,7 @@ sane_control_option (SANE_Handle handle, SANE_Int option, break; } return SANE_STATUS_GOOD; - + case OPT_ENDORSER_SIDE: switch (s->u_endorser_side) { case ED_front: @@ -5114,7 +5161,7 @@ sane_control_option (SANE_Handle handle, SANE_Int option, break; } return SANE_STATUS_GOOD; - + case OPT_ENDORSER_STRING: strncpy( (SANE_String)val, @@ -5128,102 +5175,102 @@ sane_control_option (SANE_Handle handle, SANE_Int option, ret = get_hardware_status(s,option); *val_p = s->hw_top; return ret; - + case OPT_A3: ret = get_hardware_status(s,option); *val_p = s->hw_A3; return ret; - + case OPT_B4: ret = get_hardware_status(s,option); *val_p = s->hw_B4; return ret; - + case OPT_A4: ret = get_hardware_status(s,option); *val_p = s->hw_A4; return ret; - + case OPT_B5: ret = get_hardware_status(s,option); *val_p = s->hw_B5; return ret; - + case OPT_HOPPER: ret = get_hardware_status(s,option); *val_p = s->hw_hopper; return ret; - + case OPT_OMR: ret = get_hardware_status(s,option); *val_p = s->hw_omr; return ret; - + case OPT_ADF_OPEN: ret = get_hardware_status(s,option); *val_p = s->hw_adf_open; return ret; - + case OPT_SLEEP: ret = get_hardware_status(s,option); *val_p = s->hw_sleep; return ret; - + case OPT_SEND_SW: ret = get_hardware_status(s,option); *val_p = s->hw_send_sw; return ret; - + case OPT_MANUAL_FEED: ret = get_hardware_status(s,option); *val_p = s->hw_manual_feed; return ret; - + case OPT_SCAN_SW: ret = get_hardware_status(s,option); *val_p = s->hw_scan_sw; return ret; - + case OPT_FUNCTION: ret = get_hardware_status(s,option); *val_p = s->hw_function; return ret; - + case OPT_INK_EMPTY: ret = get_hardware_status(s,option); *val_p = s->hw_ink_empty; return ret; - + case OPT_DOUBLE_FEED: ret = get_hardware_status(s,option); *val_p = s->hw_double_feed; return ret; - + case OPT_ERROR_CODE: ret = get_hardware_status(s,option); *val_p = s->hw_error_code; return ret; - + case OPT_SKEW_ANGLE: ret = get_hardware_status(s,option); *val_p = s->hw_skew_angle; return ret; - + case OPT_INK_REMAIN: ret = get_hardware_status(s,option); *val_p = s->hw_ink_remain; return ret; - + case OPT_DENSITY_SW: ret = get_hardware_status(s,option); *val_p = s->hw_density_sw; return ret; - + case OPT_DUPLEX_SW: ret = get_hardware_status(s,option); *val_p = s->hw_duplex_sw; return ret; - + } } else if (action == SANE_ACTION_SET_VALUE) { @@ -5260,7 +5307,7 @@ sane_control_option (SANE_Handle handle, SANE_Int option, * below. */ switch (option) { - + /* Mode Group */ case OPT_SOURCE: if (!strcmp (val, STRING_ADFFRONT)) { @@ -5276,7 +5323,7 @@ sane_control_option (SANE_Handle handle, SANE_Int option, tmp = SOURCE_FLATBED; } - if (s->source == tmp) + if (s->source == tmp) return SANE_STATUS_GOOD; s->source = tmp; @@ -5307,7 +5354,7 @@ sane_control_option (SANE_Handle handle, SANE_Int option, case OPT_RES: - if (s->resolution_x == val_c) + if (s->resolution_x == val_c) return SANE_STATUS_GOOD; s->resolution_x = val_c; @@ -5703,24 +5750,24 @@ sane_control_option (SANE_Handle handle, SANE_Int option, s->u_endorser = val_c; *info |= SANE_INFO_RELOAD_OPTIONS; return SANE_STATUS_GOOD; - + case OPT_ENDORSER_BITS: s->u_endorser_bits = val_c; return SANE_STATUS_GOOD; - + /*this val not used in send_endorser*/ case OPT_ENDORSER_VAL: s->u_endorser_val = val_c; return SANE_STATUS_GOOD; - + case OPT_ENDORSER_STEP: s->u_endorser_step = val_c; return SANE_STATUS_GOOD; - + case OPT_ENDORSER_Y: s->u_endorser_y = FIXED_MM_TO_SCANNER_UNIT(val_c); return SANE_STATUS_GOOD; - + case OPT_ENDORSER_FONT: if (!strcmp (val, STRING_HORIZONTAL)){ @@ -5739,7 +5786,7 @@ sane_control_option (SANE_Handle handle, SANE_Int option, s->u_endorser_font = FONT_VB; } return SANE_STATUS_GOOD; - + case OPT_ENDORSER_DIR: if (!strcmp (val, STRING_TOPTOBOTTOM)){ s->u_endorser_dir = DIR_TTB; @@ -5748,7 +5795,7 @@ sane_control_option (SANE_Handle handle, SANE_Int option, s->u_endorser_dir = DIR_BTT; } return SANE_STATUS_GOOD; - + /*this val not used in send_endorser*/ case OPT_ENDORSER_SIDE: if (!strcmp (val, STRING_FRONT)){ @@ -5758,7 +5805,7 @@ sane_control_option (SANE_Handle handle, SANE_Int option, s->u_endorser_side = ED_back; } return SANE_STATUS_GOOD; - + case OPT_ENDORSER_STRING: strncpy( (SANE_String)s->u_endorser_string, @@ -5773,7 +5820,7 @@ sane_control_option (SANE_Handle handle, SANE_Int option, } static SANE_Status -set_sleep_mode(struct fujitsu *s) +set_sleep_mode(struct fujitsu *s) { SANE_Status ret = SANE_STATUS_GOOD; @@ -5830,13 +5877,13 @@ set_off_mode(struct fujitsu *s) set_SCSI_opcode(cmd, SEND_DIAGNOSTIC_code); set_SD_slftst(cmd, 0); set_SD_xferlen(cmd, outLen); - + memcpy(out,SD_powoff_string,SD_powoff_stringlen); set_SD_powoff_disable(out,!s->off_time); set_SD_powoff_interval(out,s->off_time/15); ret = do_cmd ( - s, 1, 0, + s, 1, 0, cmd, cmdLen, out, outLen, NULL, NULL @@ -5880,14 +5927,14 @@ get_hardware_status (struct fujitsu *s, SANE_Int option) set_GHS_allocation_length(cmd, inLen); DBG (15, "get_hardware_status: calling ghs\n"); - + ret = do_cmd ( s, 1, 0, cmd, cmdLen, NULL, 0, in, &inLen ); - + if (ret == SANE_STATUS_GOOD || ret == SANE_STATUS_EOF) { s->hw_top = get_GHS_top(in); @@ -5895,23 +5942,23 @@ get_hardware_status (struct fujitsu *s, SANE_Int option) s->hw_B4 = get_GHS_B4(in); s->hw_A4 = get_GHS_A4(in); s->hw_B5 = get_GHS_B5(in); - + s->hw_hopper = get_GHS_hopper(in); s->hw_omr = get_GHS_omr(in); s->hw_adf_open = get_GHS_adf_open(in); - + s->hw_sleep = get_GHS_sleep(in); s->hw_send_sw = get_GHS_send_sw(in); s->hw_manual_feed = get_GHS_manual_feed(in); s->hw_scan_sw = get_GHS_scan_sw(in); - + s->hw_function = get_GHS_function(in); s->hw_ink_empty = get_GHS_ink_empty(in); s->hw_double_feed = get_GHS_double_feed(in); - + s->hw_error_code = get_GHS_error_code(in); - + s->hw_skew_angle = get_GHS_skew_angle(in); if(inLen > 9){ @@ -5942,7 +5989,7 @@ get_hardware_status (struct fujitsu *s, SANE_Int option) NULL,0, in, &inLen ); - + /* parse the rs data */ if(ret == SANE_STATUS_GOOD){ if(get_RS_sense_key(in)==0 && get_RS_ASC(in)==0x80){ @@ -5972,13 +6019,13 @@ get_hardware_status (struct fujitsu *s, SANE_Int option) } static SANE_Status -send_endorser(struct fujitsu *s) +send_endorser(struct fujitsu *s) { SANE_Status ret = SANE_STATUS_GOOD; unsigned char cmd[SEND_len]; size_t cmdLen = SEND_len; - + size_t strLen = strlen(s->u_endorser_string); unsigned char out[S_e_data_max_len]; /*we probably send less below*/ @@ -6080,7 +6127,7 @@ send_endorser(struct fujitsu *s) /* instead of internal brightness/contrast/gamma most scanners use a 256x256 or 1024x256 LUT default is linear table of slope 1 or 1/4 resp. - brightness and contrast inputs are -127 to +127 + brightness and contrast inputs are -127 to +127 contrast rotates slope of line around central input val @@ -6096,7 +6143,7 @@ send_endorser(struct fujitsu *s) bright dark . xxxxxxxx . - . x . + . x . out x . x . . x ............ xxxxxxxx.... @@ -6128,7 +6175,7 @@ send_lut (struct fujitsu *s) * first [-127,127] to [0,254] then to [0,1] * then multiply by PI/2 to convert to radians * then take the tangent to get slope (T.O.A) - * then multiply by the normal linear slope + * then multiply by the normal linear slope * because the table may not be square, i.e. 1024x256*/ slope = tan(((double)s->contrast+127)/254 * M_PI/2) * 256/bytes; @@ -6156,7 +6203,7 @@ send_lut (struct fujitsu *s) set_S_lut_order (out, S_lut_order_single); set_S_lut_ssize (out, bytes); set_S_lut_dsize (out, 256); - + for(i=0;iresolution_x); set_SD_preread_yres(out,s->resolution_y); @@ -6322,7 +6369,7 @@ diag_preread (struct fujitsu *s) set_SD_preread_composition(out, s->s_mode); ret = do_cmd ( - s, 1, 0, + s, 1, 0, cmd, cmdLen, out, outLen, NULL, NULL @@ -6374,17 +6421,17 @@ mode_select_df (struct fujitsu *s) if(s->df_action == DF_CONTINUE){ set_MSEL_df_continue (page, 1); } - + /* skew */ if(s->df_skew){ set_MSEL_df_skew (page, 1); } - + /* thickness */ if(s->df_thickness){ set_MSEL_df_thickness (page, 1); } - + /* length */ if(s->df_length){ set_MSEL_df_length (page, 1); @@ -6446,7 +6493,7 @@ mode_select_bg (struct fujitsu *s) set_MSEL_bg_fb (page, 1); } } - + ret = do_cmd ( s, 1, 0, cmd, cmdLen, @@ -6489,7 +6536,7 @@ mode_select_dropout (struct fujitsu *s) set_MSEL_dropout_front (page, s->dropout_color); set_MSEL_dropout_back (page, s->dropout_color); - + ret = do_cmd ( s, 1, 0, cmd, cmdLen, @@ -6574,7 +6621,7 @@ mode_select_prepick (struct fujitsu *s) set_MSEL_page_len(page, MSEL_data_min_len-2); set_MSEL_prepick(page, s->prepick); - + ret = do_cmd ( s, 1, 0, cmd, cmdLen, @@ -6620,7 +6667,7 @@ mode_select_auto (struct fujitsu *s) set_MSEL_awd(page, s->awd || s->hwdeskewcrop); set_MSEL_req_driv_crop(page, s->hwdeskewcrop && (s->swcrop || s->swdeskew)); set_MSEL_deskew(page, s->hwdeskewcrop); - + ret = do_cmd ( s, 1, 0, cmd, cmdLen, @@ -6648,7 +6695,7 @@ mode_select_auto (struct fujitsu *s) * completion of that request. Outside of that window, the returned * values are best-effort estimates of what the parameters will be * when sane_start() gets invoked. - * + * * Calling this function before a scan has actually started allows, * for example, to get an estimate of how big the scanned image will * be. The parameters passed to this function are the handle h of the @@ -6660,9 +6707,9 @@ sane_get_parameters (SANE_Handle handle, SANE_Parameters * params) { SANE_Status ret = SANE_STATUS_GOOD; struct fujitsu *s = (struct fujitsu *) handle; - + DBG (10, "sane_get_parameters: start\n"); - + /* not started? update param data from user settings */ if(!s->started){ ret = update_params(s); @@ -6760,10 +6807,10 @@ update_params (struct fujitsu * s) DBG(15,"update_params: area: tlx=%d, brx=%d, tly=%d, bry=%d\n", s->tl_x, s->br_x, s->tl_y, s->br_y); - DBG(15,"update_params: params: ppl=%d, Bpl=%d, lines=%d\n", + DBG(15,"update_params: params: ppl=%d, Bpl=%d, lines=%d\n", params->pixels_per_line, params->bytes_per_line, params->lines); - DBG(15,"update_params: params: format=%d, depth=%d, last=%d\n", + DBG(15,"update_params: params: format=%d, depth=%d, last=%d\n", params->format, params->depth, params->last_frame); /* second, we setup u_params to describe the image to the user */ @@ -6801,20 +6848,20 @@ update_u_params (struct fujitsu * s) params->format = SANE_FRAME_GRAY; params->bytes_per_line = params->pixels_per_line / 8; } - + DBG(15,"update_u_params: x: max=%d, page=%d, gpw=%d, res=%d\n", s->max_x, s->page_width, get_page_width(s), s->resolution_x); - + DBG(15,"update_u_params: y: max=%d, page=%d, gph=%d, res=%d\n", s->max_y, s->page_height, get_page_height(s), s->resolution_y); - + DBG(15,"update_u_params: area: tlx=%d, brx=%d, tly=%d, bry=%d\n", s->tl_x, s->br_x, s->tl_y, s->br_y); - - DBG(15,"update_u_params: params: ppl=%d, Bpl=%d, lines=%d\n", + + DBG(15,"update_u_params: params: ppl=%d, Bpl=%d, lines=%d\n", params->pixels_per_line, params->bytes_per_line, params->lines); - - DBG(15,"update_u_params: params: format=%d, depth=%d, last=%d\n", + + DBG(15,"update_u_params: params: format=%d, depth=%d, last=%d\n", params->format, params->depth, params->last_frame); } @@ -6939,14 +6986,14 @@ sane_start (SANE_Handle handle) if (ret != SANE_STATUS_GOOD) DBG (5, "sane_start: WARNING: cannot early send_lut %d\n", ret); } - + /* set window command */ ret = set_window(s); if (ret != SANE_STATUS_GOOD) { DBG (5, "sane_start: ERROR: cannot set window\n"); goto errors; } - + /* send lut if scanner has no hardware brightness/contrast, * or we are going to ask it to use a downloaded gamma table */ if (s->late_lut && (!s->brightness_steps || !s->contrast_steps || s->window_gamma & 0x80)){ @@ -6954,7 +7001,7 @@ sane_start (SANE_Handle handle) if (ret != SANE_STATUS_GOOD) DBG (5, "sane_start: WARNING: cannot late send_lut %d\n", ret); } - + /* some scanners need the q table sent, even when not scanning jpeg */ if (s->need_q_table){ ret = send_q_table(s); @@ -6968,7 +7015,7 @@ sane_start (SANE_Handle handle) DBG (5, "sane_start: ERROR: cannot start/stop endorser\n"); goto errors; } - + /* turn lamp on */ ret = scanner_control(s, SC_function_lamp_on); if (ret != SANE_STATUS_GOOD) { @@ -7043,7 +7090,7 @@ sane_start (SANE_Handle handle) goto errors; } - /* store the number of front bytes */ + /* store the number of front bytes */ if ( s->source != SOURCE_ADF_BACK ){ s->bytes_tot[SIDE_FRONT] = s->s_params.bytes_per_line * s->s_params.lines; s->buff_tot[SIDE_FRONT] = s->buffer_size; @@ -7062,7 +7109,7 @@ sane_start (SANE_Handle handle) s->buff_tot[SIDE_FRONT] = 0; } - /* store the number of back bytes */ + /* store the number of back bytes */ if ( s->source == SOURCE_ADF_DUPLEX || s->source == SOURCE_ADF_BACK ){ s->bytes_tot[SIDE_BACK] = s->s_params.bytes_per_line * s->s_params.lines; s->buff_tot[SIDE_BACK] = s->bytes_tot[SIDE_BACK]; @@ -7087,7 +7134,7 @@ sane_start (SANE_Handle handle) DBG (5, "sane_start: ERROR: cannot load buffers\n"); goto errors; } - + s->started=1; } } @@ -7102,9 +7149,9 @@ sane_start (SANE_Handle handle) DBG (15, "started=%d, side=%d, source=%d\n", s->started, s->side, s->source); - /* certain options require the entire image to + /* certain options require the entire image to * be collected from the scanner before we can - * tell the user the size of the image. the sane + * tell the user the size of the image. the sane * API has no way to inform the frontend of this, * so we block and buffer. yuck */ if( must_fully_buffer(s) ){ @@ -7142,7 +7189,7 @@ sane_start (SANE_Handle handle) } if(s->swskip){ /* Skipping means throwing out this image. - * Pretend the user read the whole thing + * Pretend the user read the whole thing * and call sane_start again. * This assumes we are running in batch mode. */ if(buffer_isblank(s,s->side)){ @@ -7166,7 +7213,7 @@ sane_start (SANE_Handle handle) errors: DBG (10, "sane_start: error %d\n", ret); - /* if we are started, but something went wrong, + /* if we are started, but something went wrong, * chances are there is image data inside scanner, * which should be discarded via cancel command */ if(s->started){ @@ -7181,7 +7228,7 @@ sane_start (SANE_Handle handle) } static SANE_Status -endorser(struct fujitsu *s) +endorser(struct fujitsu *s) { SANE_Status ret = SANE_STATUS_GOOD; @@ -7243,7 +7290,7 @@ endorser(struct fujitsu *s) } static SANE_Status -scanner_control (struct fujitsu *s, int function) +scanner_control (struct fujitsu *s, int function) { SANE_Status ret = SANE_STATUS_GOOD; int tries = 0; @@ -7283,7 +7330,7 @@ scanner_control (struct fujitsu *s, int function) } usleep(500000); - } + } if(ret == SANE_STATUS_GOOD){ DBG (15, "scanner_control: success, tries %d, ret %d\n",tries,ret); @@ -7299,7 +7346,7 @@ scanner_control (struct fujitsu *s, int function) } static SANE_Status -scanner_control_ric (struct fujitsu *s, int bytes, int side) +scanner_control_ric (struct fujitsu *s, int bytes, int side) { SANE_Status ret = SANE_STATUS_GOOD; int tries = 0; @@ -7325,7 +7372,7 @@ scanner_control_ric (struct fujitsu *s, int bytes, int side) set_SC_ric_len(cmd, bytes); DBG (15, "scanner_control_ric: %d %d\n",bytes,side); - + /* extremely long retry period */ while(tries++ < 120){ @@ -7341,7 +7388,7 @@ scanner_control_ric (struct fujitsu *s, int bytes, int side) } usleep(500000); - } + } if(ret == SANE_STATUS_GOOD){ DBG (15, "scanner_control_ric: success, tries %d, ret %d\n",tries,ret); @@ -7408,14 +7455,14 @@ set_window (struct fujitsu *s) { SANE_Status ret = SANE_STATUS_GOOD; - /* The command specifies the number of bytes in the data phase - * the data phase has a header, followed by 1 or 2 window desc blocks + /* The command specifies the number of bytes in the data phase + * the data phase has a header, followed by 1 or 2 window desc blocks * the header specifies the number of bytes in 1 window desc block */ unsigned char cmd[SET_WINDOW_len]; size_t cmdLen = SET_WINDOW_len; - + /*this is max size, we might send less below*/ unsigned char out[SW_header_len + SW_desc_len + SW_desc_len]; size_t outLen = SW_header_len + SW_desc_len + SW_desc_len; @@ -7687,7 +7734,7 @@ get_pixelsize(struct fujitsu *s, int actual) set_R_window_id (cmd, WD_wid_front); } set_R_xfer_length (cmd, inLen); - + ret = do_cmd ( s, 1, 0, cmd, cmdLen, @@ -7732,7 +7779,7 @@ get_pixelsize(struct fujitsu *s, int actual) else { s->s_params.bytes_per_line = s->s_params.pixels_per_line / 8; } - + /* some scanners can request that the driver clean img */ if(!s->has_short_pixelsize && get_PSIZE_req_driv_valid(in)){ s->req_driv_crop = get_PSIZE_req_driv_crop(in); @@ -7741,7 +7788,7 @@ get_pixelsize(struct fujitsu *s, int actual) s->req_driv_crop,s->req_driv_lut); } - DBG (15, "get_pixelsize: scan_x=%d, Bpl=%d, scan_y=%d\n", + DBG (15, "get_pixelsize: scan_x=%d, Bpl=%d, scan_y=%d\n", s->s_params.pixels_per_line, s->s_params.bytes_per_line, s->s_params.lines ); /* the user params are usually the same */ @@ -7758,7 +7805,7 @@ get_pixelsize(struct fujitsu *s, int actual) else { s->u_params.bytes_per_line = s->u_params.pixels_per_line / 8; } - + } else{ DBG (10, "get_pixelsize: got bad status %d, ignoring\n", ret); @@ -7812,7 +7859,7 @@ object_position (struct fujitsu *s, int action) /* * Issues SCAN command. - * + * * (This doesn't actually read anything, it just tells the scanner * to start scanning.) */ @@ -7897,7 +7944,7 @@ check_for_cancel(struct fujitsu *s) /* * Called by SANE to read data. - * + * * From the SANE spec: * This function is used to read image data from the device * represented by handle h. Argument buf is a pointer to a memory @@ -7905,7 +7952,7 @@ check_for_cancel(struct fujitsu *s) * returned is stored in *len. A backend must set this to zero when * the call fails (i.e., when a status other than SANE_STATUS_GOOD is * returned). - * + * * When the call succeeds, the number of bytes returned can be * anywhere in the range from 0 to maxlen bytes. */ @@ -7963,7 +8010,7 @@ sane_read (SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len, SANE_Int * len /* alternating jpeg duplex interlacing */ else if(s->source == SOURCE_ADF_DUPLEX - && s->s_params.format == SANE_FRAME_JPEG + && s->s_params.format == SANE_FRAME_JPEG && s->jpeg_interlace == JPEG_INTERLACE_ALT ){ ret = read_from_JPEGduplex(s); @@ -7985,7 +8032,7 @@ sane_read (SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len, SANE_Int * len DBG(5,"sane_read: front returning %d\n",ret); return ret; } - + /* buffer back side, but don't get too far ahead of the front! */ if(s->bytes_rx[SIDE_BACK] < s->bytes_rx[SIDE_FRONT] + s->buffer_size){ ret = read_from_scanner(s, SIDE_BACK); @@ -8084,9 +8131,9 @@ read_from_JPEGduplex(struct fujitsu *s) int bytes = s->buffer_size; int i = 0; - + DBG (10, "read_from_JPEGduplex: start\n"); - + if(s->eof_rx[SIDE_FRONT] && s->eof_rx[SIDE_BACK]){ DBG (10, "read_from_JPEGduplex: already have eofs, done\n"); return ret; @@ -8112,7 +8159,7 @@ read_from_JPEGduplex(struct fujitsu *s) bytes -= JFIF_APP0_LENGTH; } } - + DBG(15, "read_from_JPEGduplex: fto:%d frx:%d bto:%d brx:%d pa:%d\n", s->bytes_tot[SIDE_FRONT], s->bytes_rx[SIDE_FRONT], s->bytes_tot[SIDE_BACK], s->bytes_rx[SIDE_BACK], @@ -8123,7 +8170,7 @@ read_from_JPEGduplex(struct fujitsu *s) DBG(5, "read_from_JPEGduplex: Warning: no bytes this pass\n"); return ret; } - + /* fi-6770A gets mad if you 'read' too soon on usb, see if it is ready */ if(!s->bytes_rx[SIDE_FRONT] && s->connection == CONNECTION_USB){ DBG (15, "read: start of usb page, checking RIC\n"); @@ -8147,14 +8194,14 @@ read_from_JPEGduplex(struct fujitsu *s) /* interlaced jpeg duplex always reads from front */ set_R_window_id (cmd, WD_wid_front); set_R_xfer_length (cmd, inLen); - + ret = do_cmd ( s, 1, 0, cmd, cmdLen, NULL, 0, in, &inLen ); - + if (ret == SANE_STATUS_GOOD || ret == SANE_STATUS_EOF) { DBG(15, "read_from_JPEGduplex: got GOOD/EOF, returning GOOD\n"); } @@ -8167,7 +8214,7 @@ read_from_JPEGduplex(struct fujitsu *s) DBG(5, "read_from_JPEGduplex: error reading data status = %d\n", ret); inLen = 0; } - + for(i=0;i<(int)inLen;i++){ /* about to change stage */ @@ -8359,9 +8406,9 @@ read_from_JPEGduplex(struct fujitsu *s) s->eof_rx[SIDE_BACK] = 1; } } - + free(in); - + /* jpeg uses in-band EOI marker, so this is ususally redundant */ if(ret == SANE_STATUS_EOF){ DBG(15, "read_from_JPEGduplex: got EOF, finishing\n"); @@ -8372,7 +8419,7 @@ read_from_JPEGduplex(struct fujitsu *s) } DBG (10, "read_from_JPEGduplex: finish\n"); - + return ret; } @@ -8411,7 +8458,7 @@ read_from_3091duplex(struct fujitsu *s) if(bytes > avail) bytes = avail; } - + /* all requests must end on a line boundary */ bytes -= (bytes % s->s_params.bytes_per_line); @@ -8534,9 +8581,9 @@ read_from_scanner(struct fujitsu *s, int side) int bytes = s->buffer_size; int avail = s->buff_tot[side] - s->buff_rx[side]; int remain = s->bytes_tot[side] - s->bytes_rx[side]; - + DBG (10, "read_from_scanner: start %d\n", side); - + if(s->eof_rx[side]){ DBG (10, "read_from_scanner: already have eof, done\n"); return ret; @@ -8545,7 +8592,7 @@ read_from_scanner(struct fujitsu *s, int side) /* figure out the max amount to transfer */ if(bytes > avail) bytes = avail; - + /* all requests must end on line boundary */ bytes -= (bytes % s->s_params.bytes_per_line); @@ -8559,7 +8606,7 @@ read_from_scanner(struct fujitsu *s, int side) /* jpeg scans leave space for JFIF header at start of image */ if(s->s_params.format == SANE_FRAME_JPEG && s->bytes_rx[side] < 2) bytes -= JFIF_APP0_LENGTH; - + DBG(15, "read_from_scanner: si:%d re:%d bs:%d by:%d av:%d\n", side, remain, s->buffer_size, bytes, avail); @@ -8569,13 +8616,13 @@ read_from_scanner(struct fujitsu *s, int side) DBG(15, "read_from_scanner: buf to:%d rx:%d tx:%d\n", s->buff_tot[side], s->buff_rx[side], s->buff_tx[side]); - + /* this will happen if buffer is not drained yet */ if(bytes < 1){ DBG(5, "read_from_scanner: no bytes this pass\n"); return ret; } - + /* fi-6770A gets mad if you 'read' too soon on usb, see if it is ready */ if(!s->bytes_rx[side] && s->connection == CONNECTION_USB){ DBG (15, "read_from_scanner: start of usb page, checking RIC\n"); @@ -8592,27 +8639,27 @@ read_from_scanner(struct fujitsu *s, int side) DBG(5, "read_from_scanner: not enough mem for buffer: %d\n",(int)inLen); return SANE_STATUS_NO_MEM; } - + memset(cmd,0,cmdLen); set_SCSI_opcode(cmd, READ_code); set_R_datatype_code (cmd, R_datatype_imagedata); - + if (side == SIDE_BACK) { set_R_window_id (cmd, WD_wid_back); } else{ set_R_window_id (cmd, WD_wid_front); } - + set_R_xfer_length (cmd, inLen); - + ret = do_cmd ( s, 1, 0, cmd, cmdLen, NULL, 0, in, &inLen ); - + if (ret == SANE_STATUS_GOOD || ret == SANE_STATUS_EOF) { DBG(15, "read_from_scanner: got GOOD/EOF, returning GOOD\n"); ret = SANE_STATUS_GOOD; @@ -8626,7 +8673,7 @@ read_from_scanner(struct fujitsu *s, int side) DBG(5, "read_from_scanner: error reading data block status = %d\n",ret); inLen = 0; } - + DBG(15, "read_from_scanner: read %lu bytes\n",(unsigned long)inLen); if(inLen){ @@ -8640,7 +8687,7 @@ read_from_scanner(struct fujitsu *s, int side) copy_buffer (s, in, inLen, side); } } - + free(in); /* if this was a short read or not, log it */ @@ -8655,7 +8702,7 @@ read_from_scanner(struct fujitsu *s, int side) s->eom_rx = 1; } - /* paper ran out. lets try to set the eof flag on both sides, + /* paper ran out. lets try to set the eof flag on both sides, * but only if that side had a short read last time */ if(s->eom_rx){ int i; @@ -8668,7 +8715,7 @@ read_from_scanner(struct fujitsu *s, int side) } DBG (10, "read_from_scanner: finish\n"); - + return ret; } @@ -8682,7 +8729,7 @@ copy_3091(struct fujitsu *s, unsigned char * buf, int len, int side) /* Data is RR...GG...BB... on each line, * green is back 8 lines from red at 300 dpi - * blue is back 4 lines from red at 300 dpi. + * blue is back 4 lines from red at 300 dpi. * * Here, we get things on correct line, and * interlace to make RGBRGB. @@ -8726,12 +8773,12 @@ copy_3091(struct fujitsu *s, unsigned char * buf, int len, int side) s->lines_rx[side]++; } - /* even if we have read data, we may not have any + /* even if we have read data, we may not have any * full lines loaded yet, so we may have to lie */ i = (s->lines_rx[side]-goff) * s->s_params.bytes_per_line; if(i < 0){ i = 0; - } + } s->bytes_rx[side] = i; s->buff_rx[side] = i; @@ -8753,11 +8800,11 @@ copy_JPEG(struct fujitsu *s, unsigned char * buf, int len, int side) { SANE_Status ret=SANE_STATUS_GOOD; int i, seen = 0; - + DBG (10, "copy_JPEG: start\n"); /* A jpeg image starts with the SOI marker, FF D8. - * This is optionally followed by the JFIF APP0 + * This is optionally followed by the JFIF APP0 * marker, FF E0. If that marker is not present, * we add it, so we can insert the resolution */ @@ -8797,7 +8844,7 @@ copy_buffer(struct fujitsu *s, unsigned char * buf, int len, int side) int i, j; int bwidth = s->s_params.bytes_per_line; int pwidth = s->s_params.pixels_per_line; - + DBG (10, "copy_buffer: start\n"); /* invert image if scanner needs it for this mode */ @@ -8810,9 +8857,9 @@ copy_buffer(struct fujitsu *s, unsigned char * buf, int len, int side) /* scanners interlace colors in many different ways */ if(s->s_params.format == SANE_FRAME_RGB){ - + switch (s->color_interlace) { - + /* scanner returns pixel data as bgrbgr... */ case COLOR_INTERLACE_BGR: for(i=0; ibuffers[side]+s->buff_rx[side],buf,len); s->buff_rx[side] += len; @@ -8847,7 +8894,7 @@ copy_buffer(struct fujitsu *s, unsigned char * buf, int len, int side) memcpy(s->buffers[side]+s->buff_rx[side],buf,len); s->buff_rx[side] += len; } - + s->bytes_rx[side] += len; s->lines_rx[side] += len/s->s_params.bytes_per_line; @@ -8867,16 +8914,16 @@ read_from_buffer(struct fujitsu *s, SANE_Byte * buf, SANE_Status ret=SANE_STATUS_GOOD; int bytes = max_len; int remain = s->buff_rx[side] - s->buff_tx[side]; - + DBG (10, "read_from_buffer: start\n"); - + /* figure out the max amount to transfer */ if(bytes > remain){ bytes = remain; } - + *len = bytes; - + DBG(15, "read_from_buffer: si:%d re:%d ml:%d by:%d\n", side, remain, max_len, bytes); @@ -8885,19 +8932,19 @@ read_from_buffer(struct fujitsu *s, SANE_Byte * buf, DBG(15, "read_from_buffer: buf to:%d rx:%d tx:%d\n", s->buff_tot[side], s->buff_rx[side], s->buff_tx[side]); - + /*FIXME this needs to timeout eventually */ if(!bytes){ DBG(5,"read_from_buffer: nothing to do\n"); return SANE_STATUS_GOOD; } - + memcpy(buf,s->buffers[side]+s->buff_tx[side],bytes); s->buff_tx[side] += bytes; s->bytes_tx[side] += bytes; DBG (10, "read_from_buffer: finish\n"); - + return ret; } @@ -8911,7 +8958,7 @@ downsample_from_buffer(struct fujitsu *s, SANE_Byte * buf, SANE_Status ret=SANE_STATUS_GOOD; DBG (10, "downsample_from_buffer: start %d %d %d %d\n", s->bytes_rx[side], s->bytes_tx[side], s->buff_rx[side], s->buff_tx[side]); - + if(s->s_mode == MODE_COLOR && s->u_mode == MODE_GRAYSCALE){ while(*len < max_len && s->buff_rx[side] - s->buff_tx[side] >= 3){ @@ -8959,7 +9006,7 @@ downsample_from_buffer(struct fujitsu *s, SANE_Byte * buf, for(i=0; i<8; i++){ int gray = 0; - + switch (s->dropout_color) { case COLOR_RED: gray = *(s->buffers[side]+s->buff_tx[side]) * 3; @@ -8999,7 +9046,7 @@ downsample_from_buffer(struct fujitsu *s, SANE_Byte * buf, } DBG (10, "downsample_from_buffer: finish %d %d %d %d\n", s->bytes_rx[side], s->bytes_tx[side], s->buff_rx[side], s->buff_tx[side]); - + return ret; } @@ -9008,26 +9055,26 @@ downsample_from_buffer(struct fujitsu *s, SANE_Byte * buf, * @@ Section 5 - SANE cleanup functions */ /* - * Cancels a scan. + * Cancels a scan. * * It has been said on the mailing list that sane_cancel is a bit of a * misnomer because it is routinely called to signal the end of a * batch - quoting David Mosberger-Tang: - * + * * > In other words, the idea is to have sane_start() be called, and * > collect as many images as the frontend wants (which could in turn * > consist of multiple frames each as indicated by frame-type) and - * > when the frontend is done, it should call sane_cancel(). + * > when the frontend is done, it should call sane_cancel(). * > Sometimes it's better to think of sane_cancel() as "sane_stop()" * > but that name would have had some misleading connotations as * > well, that's why we stuck with "cancel". - * + * * The current consensus regarding duplex and ADF scans seems to be * the following call sequence: sane_start; sane_read (repeat until * EOF); sane_start; sane_read... and then call sane_cancel if the * batch is at an end. I.e. do not call sane_cancel during the run but * as soon as you get a SANE_STATUS_NO_DOCS. - * + * * From the SANE spec: * This function is used to immediately or as quickly as possible * cancel the currently pending operation of the device represented by @@ -9061,7 +9108,7 @@ sane_cancel (SANE_Handle handle) /* * Ends use of the scanner. - * + * * From the SANE spec: * This function terminates the association between the device handle * passed in argument h and the device it represents. If the device is @@ -9104,7 +9151,7 @@ disconnect_fd (struct fujitsu *s) /* * Terminates the backend. - * + * * From the SANE spec: * This function must be called to terminate use of a backend. The * function will first close all device handles that still might be @@ -9703,7 +9750,7 @@ do_usb_cmd(struct fujitsu *s, int runRS, int shortTime, rs_in, &rs_inLen ); DBG(25,"rs sub call <<\n"); - + if(ret2 == SANE_STATUS_EOF){ DBG(5,"rs: got EOF, returning IO_ERROR\n"); return SANE_STATUS_IO_ERROR; @@ -9736,7 +9783,7 @@ do_usb_cmd(struct fujitsu *s, int runRS, int shortTime, } static SANE_Status -wait_scanner(struct fujitsu *s) +wait_scanner(struct fujitsu *s) { SANE_Status ret = SANE_STATUS_GOOD; @@ -9754,7 +9801,7 @@ wait_scanner(struct fujitsu *s) NULL, 0, NULL, NULL ); - + if (ret != SANE_STATUS_GOOD) { DBG(5,"WARNING: Brain-dead scanner. Hitting with stick\n"); ret = do_cmd ( @@ -9783,7 +9830,7 @@ wait_scanner(struct fujitsu *s) return ret; } -/* certain options require the entire image to +/* certain options require the entire image to * be collected from the scanner before we can * tell the user the size of the image. */ static int @@ -9803,7 +9850,7 @@ must_fully_buffer(struct fujitsu *s) return 0; } -/* certain scanners require the mode of the +/* certain scanners require the mode of the * image to be changed in software. */ static int must_downsample(struct fujitsu *s) @@ -9823,7 +9870,7 @@ must_downsample(struct fujitsu *s) * due to using FB or overscan. */ static int -get_page_width(struct fujitsu *s) +get_page_width(struct fujitsu *s) { int width = s->page_width + 2 * (s->os_x_basic*1200/s->basic_x_res); @@ -9852,7 +9899,7 @@ get_page_width(struct fujitsu *s) * due to using FB or overscan. */ static int -get_page_height(struct fujitsu *s) +get_page_height(struct fujitsu *s) { int height = s->page_height + 2 * (s->os_y_basic*1200/s->basic_y_res); @@ -9883,7 +9930,7 @@ get_page_height(struct fujitsu *s) * and pick the right mode to match. */ static int -get_ipc_mode(struct fujitsu *s) +get_ipc_mode(struct fujitsu *s) { if ( s->bp_filter || s->smoothing @@ -9912,10 +9959,10 @@ get_ipc_mode(struct fujitsu *s) return WD_ipc_DEFAULT; } -/* s->max_y gives the maximum height of paper which can be scanned +/* s->max_y gives the maximum height of paper which can be scanned * this actually varies by resolution, so a helper to change it */ static int -set_max_y(struct fujitsu *s) +set_max_y(struct fujitsu *s) { int i; @@ -10046,7 +10093,7 @@ buffer_deskew(struct fujitsu *s, int side) s->deskew_stat = sanei_magic_findSkew( &s->s_params,s->buffers[side],s->resolution_x,s->resolution_y, &s->deskew_vals[0],&s->deskew_vals[1],&s->deskew_slope); - + if(s->deskew_stat){ DBG (5, "buffer_deskew: bad findSkew, bailing\n"); goto cleanup; @@ -10101,7 +10148,7 @@ buffer_crop(struct fujitsu *s, int side) ret = SANE_STATUS_GOOD; goto cleanup; } - + DBG (15, "buffer_crop: t:%d b:%d l:%d r:%d\n", s->crop_vals[0],s->crop_vals[1],s->crop_vals[2],s->crop_vals[3]); @@ -10127,7 +10174,7 @@ buffer_crop(struct fujitsu *s, int side) /* update image size counter to new, smaller size */ s->bytes_rx[side] = s->s_params.lines * s->s_params.bytes_per_line; s->buff_rx[side] = s->bytes_rx[side]; - + cleanup: DBG (10, "buffer_crop: finish\n"); return ret; @@ -10178,4 +10225,3 @@ buffer_isblank(struct fujitsu *s, int side) DBG (10, "buffer_isblank: finished\n"); return status; } - -- cgit v1.2.3 From ffa8801644a7d53cc1c785e3450f794c07a14eb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Sun, 2 Feb 2020 17:13:01 +0100 Subject: New upstream version 1.0.29 --- backend/fujitsu.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'backend/fujitsu.c') diff --git a/backend/fujitsu.c b/backend/fujitsu.c index 3ac4c8e..5dc466c 100644 --- a/backend/fujitsu.c +++ b/backend/fujitsu.c @@ -6,7 +6,7 @@ Copyright (C) 2000 Randolph Bentson Copyright (C) 2001 Frederik Ramm Copyright (C) 2001-2004 Oliver Schirrmeister - Copyright (C) 2003-2016 m. allan noah + Copyright (C) 2003-2019 m. allan noah JPEG output and low memory usage support funded by: Archivista GmbH, www.archivista.ch @@ -603,6 +603,8 @@ v134 2019-02-23, MAN - rewrite init_vpd for scanners which fail to report overscan correctly + v135 2019-11-10, MAN + - set has_MS_lamp=0 for fi-72x0, bug #134 SANE FLOW DIAGRAM @@ -2404,6 +2406,8 @@ init_model (struct fujitsu *s) else if (strstr (s->model_name,"fi-7280") || strstr (s->model_name,"fi-7260")){ + /* locks up scanner if we try to auto detect */ + s->has_MS_lamp = 0; /* weirdness */ /* these machines have longer max paper at lower res */ @@ -4377,7 +4381,7 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option) if(option==OPT_TOP){ opt->name = "top-edge"; opt->title = SANE_I18N ("Top edge"); - opt->desc = SANE_I18N ("Paper is pulled partly into adf"); + opt->desc = SANE_I18N ("Paper is pulled partly into ADF"); opt->type = SANE_TYPE_BOOL; opt->unit = SANE_UNIT_NONE; if (s->has_cmd_hw_status || s->ghs_in_rs) @@ -6935,7 +6939,7 @@ sane_start (SANE_Handle handle) else{ ret = scanner_control(s, SC_function_adf); if (ret != SANE_STATUS_GOOD) { - DBG (5, "sane_start: ERROR: cannot control adf, ignoring\n"); + DBG (5, "sane_start: ERROR: cannot control ADF, ignoring\n"); } } -- cgit v1.2.3