Fujitsu backend v107 and v108

- M3091 does not support scanner_control(adf)
- Correct buffer overflow in read_from_3091duplex()
- sane_read() now always calls read_from_*()
- read_from_*() are callable when there is no data, and read to eof
- sane_read() will keep alternate duplex reads to similar length
- Added debugging statements
- Corrected comments
- Updated Copyright
- merged x/y resolution options
- moved page width/height to start of geometry group
- use mode to pick resolution list v/s range
- improved M3091 resolution choices
merge-requests/1/head
m. allan noah 2011-11-21 15:16:02 -05:00
rodzic d7c50263ae
commit 69b5f8cfcf
3 zmienionych plików z 276 dodań i 326 usunięć

Wyświetl plik

@ -1,3 +1,18 @@
2011-11-21 m. allan noah <kitno455 at gmail dot com>
* backend/fujitsu.[ch]: backend v107 and v108
- M3091 does not support scanner_control(adf)
- Correct buffer overflow in read_from_3091duplex()
- sane_read() now always calls read_from_*()
- read_from_*() are callable when there is no data, and read to eof
- sane_read() will keep alternate duplex reads to similar length
- Added debugging statements
- Corrected comments
- Updated Copyright
- merged x/y resolution options
- moved page width/height to start of geometry group
- use mode to pick resolution list v/s range
- improved M3091 resolution choices
2011-11-20 Chris Bagwell <chris at cnpbagwell dot com>
* epson2-commands.c: Include <sys/types.h> to resolve u_long.
* epson2.c, magicolor.c, xerox_mfp-tcp.c: Include <sys/types.h>

Wyświetl plik

@ -6,7 +6,7 @@
Copyright (C) 2000 Randolph Bentson
Copyright (C) 2001 Frederik Ramm
Copyright (C) 2001-2004 Oliver Schirrmeister
Copyright (C) 2003-2010 m. allan noah
Copyright (C) 2003-2011 m. allan noah
JPEG output and low memory usage support funded by:
Archivista GmbH, www.archivista.ch
@ -483,6 +483,20 @@
- fi-6110 does not support bgcolor or prepick
v106 2011-01-30, MAN (SANE 1.0.22)
- dont call mode_select with a page code the scanner does not support
v107 2011-11-03, MAN
- M3091 does not support scanner_control(adf)
- Correct buffer overflow in read_from_3091duplex()
- sane_read() now always calls read_from_*()
- read_from_*() are callable when there is no data, and read to eof
- sane_read() will keep alternate duplex reads to similar length
- Added debugging statements
- Corrected comments
- Updated Copyright
v108 2011-11-21, MAN
- merged x/y resolution options
- moved page width/height to start of geometry group
- use mode to pick resolution list v/s range
- improved M3091 resolution choices
SANE FLOW DIAGRAM
@ -532,7 +546,7 @@
#include "fujitsu.h"
#define DEBUG 1
#define BUILD 106
#define BUILD 108
/* values for SANE_DEBUG_FUJITSU env var:
- errors 5
@ -1192,11 +1206,11 @@ init_vpd (struct fujitsu *s)
s->basic_y_res = get_IN_basic_y_res (in);
DBG (15, " basic y res: %d dpi\n",s->basic_y_res);
s->step_x_res = get_IN_step_x_res (in);
DBG (15, " step x res: %d dpi\n", s->step_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->step_y_res = get_IN_step_y_res (in);
DBG (15, " step y res: %d dpi\n", s->step_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->max_x_res = get_IN_max_x_res (in);
DBG (15, " max x res: %d dpi\n", s->max_x_res);
@ -1211,53 +1225,53 @@ init_vpd (struct fujitsu *s)
DBG (15, " min y res: %d dpi\n", s->min_y_res);
/* some scanners list B&W resolutions. */
s->std_res_60 = get_IN_std_res_60 (in);
DBG (15, " 60 dpi: %d\n", s->std_res_60);
s->std_res[0] = get_IN_std_res_60 (in);
DBG (15, " 60 dpi: %d\n", s->std_res[0]);
s->std_res_75 = get_IN_std_res_75 (in);
DBG (15, " 75 dpi: %d\n", s->std_res_75);
s->std_res[1] = get_IN_std_res_75 (in);
DBG (15, " 75 dpi: %d\n", s->std_res[1]);
s->std_res_100 = get_IN_std_res_100 (in);
DBG (15, " 100 dpi: %d\n", s->std_res_100);
s->std_res[2] = get_IN_std_res_100 (in);
DBG (15, " 100 dpi: %d\n", s->std_res[2]);
s->std_res_120 = get_IN_std_res_120 (in);
DBG (15, " 120 dpi: %d\n", s->std_res_120);
s->std_res[3] = get_IN_std_res_120 (in);
DBG (15, " 120 dpi: %d\n", s->std_res[3]);
s->std_res_150 = get_IN_std_res_150 (in);
DBG (15, " 150 dpi: %d\n", s->std_res_150);
s->std_res[4] = get_IN_std_res_150 (in);
DBG (15, " 150 dpi: %d\n", s->std_res[4]);
s->std_res_160 = get_IN_std_res_160 (in);
DBG (15, " 160 dpi: %d\n", s->std_res_160);
s->std_res[5] = get_IN_std_res_160 (in);
DBG (15, " 160 dpi: %d\n", s->std_res[5]);
s->std_res_180 = get_IN_std_res_180 (in);
DBG (15, " 180 dpi: %d\n", s->std_res_180);
s->std_res[6] = get_IN_std_res_180 (in);
DBG (15, " 180 dpi: %d\n", s->std_res[6]);
s->std_res_200 = get_IN_std_res_200 (in);
DBG (15, " 200 dpi: %d\n", s->std_res_200);
s->std_res[7] = get_IN_std_res_200 (in);
DBG (15, " 200 dpi: %d\n", s->std_res[7]);
s->std_res_240 = get_IN_std_res_240 (in);
DBG (15, " 240 dpi: %d\n", s->std_res_240);
s->std_res[8] = get_IN_std_res_240 (in);
DBG (15, " 240 dpi: %d\n", s->std_res[8]);
s->std_res_300 = get_IN_std_res_300 (in);
DBG (15, " 300 dpi: %d\n", s->std_res_300);
s->std_res[9] = get_IN_std_res_300 (in);
DBG (15, " 300 dpi: %d\n", s->std_res[9]);
s->std_res_320 = get_IN_std_res_320 (in);
DBG (15, " 320 dpi: %d\n", s->std_res_320);
s->std_res[10] = get_IN_std_res_320 (in);
DBG (15, " 320 dpi: %d\n", s->std_res[10]);
s->std_res_400 = get_IN_std_res_400 (in);
DBG (15, " 400 dpi: %d\n", s->std_res_400);
s->std_res[11] = get_IN_std_res_400 (in);
DBG (15, " 400 dpi: %d\n", s->std_res[11]);
s->std_res_480 = get_IN_std_res_480 (in);
DBG (15, " 480 dpi: %d\n", s->std_res_480);
s->std_res[12] = get_IN_std_res_480 (in);
DBG (15, " 480 dpi: %d\n", s->std_res[12]);
s->std_res_600 = get_IN_std_res_600 (in);
DBG (15, " 600 dpi: %d\n", s->std_res_600);
s->std_res[13] = get_IN_std_res_600 (in);
DBG (15, " 600 dpi: %d\n", s->std_res[13]);
s->std_res_800 = get_IN_std_res_800 (in);
DBG (15, " 800 dpi: %d\n", s->std_res_800);
s->std_res[14] = get_IN_std_res_800 (in);
DBG (15, " 800 dpi: %d\n", s->std_res[14]);
s->std_res_1200 = get_IN_std_res_1200 (in);
DBG (15, " 1200 dpi: %d\n", s->std_res_1200);
s->std_res[15] = get_IN_std_res_1200 (in);
DBG (15, " 1200 dpi: %d\n", s->std_res[15]);
/* maximum window width and length are reported in basic units.*/
s->max_x_basic = get_IN_window_width(in);
@ -1775,6 +1789,7 @@ init_ms(struct fujitsu *s)
static SANE_Status
init_model (struct fujitsu *s)
{
int i;
DBG (10, "init_model: start\n");
@ -1786,6 +1801,11 @@ init_model (struct fujitsu *s)
s->has_vuid_color = 1;
}
for(i=MODE_HALFTONE;i<=MODE_COLOR;i++){
s->step_x_res[i] = s->step_x_res[MODE_LINEART];
s->step_y_res[i] = s->step_y_res[MODE_LINEART];
}
s->reverse_by_mode[MODE_LINEART] = 0;
s->reverse_by_mode[MODE_HALFTONE] = 0;
s->reverse_by_mode[MODE_GRAYSCALE] = 1;
@ -1853,6 +1873,20 @@ init_model (struct fujitsu *s)
if (strstr (s->model_name, "M3092"))
s->has_flatbed = 1;
/*actually does have res range in non-color modes */
for(i=MODE_LINEART;i<MODE_COLOR;i++){
s->step_x_res[i] = 1;
s->step_y_res[i] = 1;
}
/*but the color mode y list is very limited, only 75, 150, 300 (and 600)*/
for(i=0;i<16;i++){
s->std_res[i] = 0;
}
s->std_res[1] = 1;
s->std_res[4] = 1;
s->std_res[9] = 1;
/* weirdness */
s->has_vuid_3091 = 1;
s->has_vuid_color = 0;
@ -2323,7 +2357,7 @@ const SANE_Option_Descriptor *
sane_get_option_descriptor (SANE_Handle handle, SANE_Int option)
{
struct fujitsu *s = handle;
int i;
int i,j;
SANE_Option_Descriptor *opt = &s->opt[option];
DBG (20, "sane_get_option_descriptor: %d\n", option);
@ -2395,151 +2429,41 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option)
opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
}
/* x resolution */
/* resolution */
/* some scanners only support fixed res
* build a list of possible choices */
if(option==OPT_X_RES){
i=0;
if(s->std_res_60 && s->max_x_res >= 60 && s->min_x_res <= 60){
s->x_res_list[++i] = 60;
}
if(s->std_res_75 && s->max_x_res >= 75 && s->min_x_res <= 75){
s->x_res_list[++i] = 75;
}
if(s->std_res_100 && s->max_x_res >= 100 && s->min_x_res <= 100){
s->x_res_list[++i] = 100;
}
if(s->std_res_120 && s->max_x_res >= 120 && s->min_x_res <= 120){
s->x_res_list[++i] = 120;
}
if(s->std_res_150 && s->max_x_res >= 150 && s->min_x_res <= 150){
s->x_res_list[++i] = 150;
}
if(s->std_res_160 && s->max_x_res >= 160 && s->min_x_res <= 160){
s->x_res_list[++i] = 160;
}
if(s->std_res_180 && s->max_x_res >= 180 && s->min_x_res <= 180){
s->x_res_list[++i] = 180;
}
if(s->std_res_200 && s->max_x_res >= 200 && s->min_x_res <= 200){
s->x_res_list[++i] = 200;
}
if(s->std_res_240 && s->max_x_res >= 240 && s->min_x_res <= 240){
s->x_res_list[++i] = 240;
}
if(s->std_res_300 && s->max_x_res >= 300 && s->min_x_res <= 300){
s->x_res_list[++i] = 300;
}
if(s->std_res_320 && s->max_x_res >= 320 && s->min_x_res <= 320){
s->x_res_list[++i] = 320;
}
if(s->std_res_400 && s->max_x_res >= 400 && s->min_x_res <= 400){
s->x_res_list[++i] = 400;
}
if(s->std_res_480 && s->max_x_res >= 480 && s->min_x_res <= 480){
s->x_res_list[++i] = 480;
}
if(s->std_res_600 && s->max_x_res >= 600 && s->min_x_res <= 600){
s->x_res_list[++i] = 600;
}
if(s->std_res_800 && s->max_x_res >= 800 && s->min_x_res <= 800){
s->x_res_list[++i] = 800;
}
if(s->std_res_1200 && s->max_x_res >= 1200 && s->min_x_res <= 1200){
s->x_res_list[++i] = 1200;
}
s->x_res_list[0] = i;
if(option==OPT_RES){
opt->name = SANE_NAME_SCAN_RESOLUTION;
opt->title = SANE_TITLE_SCAN_X_RESOLUTION;
opt->desc = SANE_DESC_SCAN_X_RESOLUTION;
opt->title = SANE_TITLE_SCAN_RESOLUTION;
opt->desc = SANE_DESC_SCAN_RESOLUTION;
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->x_res_range.min = s->min_x_res;
s->x_res_range.max = s->max_x_res;
s->x_res_range.quant = s->step_x_res;
if(s->step_x_res[s->mode] && s->step_y_res[s->mode]){
s->res_range.min = s->min_x_res;
s->res_range.max = s->max_x_res;
s->res_range.quant = s->step_x_res[s->mode];
opt->constraint_type = SANE_CONSTRAINT_RANGE;
opt->constraint.range = &s->x_res_range;
opt->constraint.range = &s->res_range;
}
else{
opt->constraint_type = SANE_CONSTRAINT_WORD_LIST;
opt->constraint.word_list = s->x_res_list;
}
}
int reses[]
= {60,75,100,120,150,160,180,200,240,300,320,400,480,600,800,1200};
/* y resolution */
if(option==OPT_Y_RES){
i=0;
if(s->std_res_60 && s->max_y_res >= 60 && s->min_y_res <= 60){
s->y_res_list[++i] = 60;
}
if(s->std_res_75 && s->max_y_res >= 75 && s->min_y_res <= 75){
s->y_res_list[++i] = 75;
}
if(s->std_res_100 && s->max_y_res >= 100 && s->min_y_res <= 100){
s->y_res_list[++i] = 100;
}
if(s->std_res_120 && s->max_y_res >= 120 && s->min_y_res <= 120){
s->y_res_list[++i] = 120;
}
if(s->std_res_150 && s->max_y_res >= 150 && s->min_y_res <= 150){
s->y_res_list[++i] = 150;
}
if(s->std_res_160 && s->max_y_res >= 160 && s->min_y_res <= 160){
s->y_res_list[++i] = 160;
}
if(s->std_res_180 && s->max_y_res >= 180 && s->min_y_res <= 180){
s->y_res_list[++i] = 180;
}
if(s->std_res_200 && s->max_y_res >= 200 && s->min_y_res <= 200){
s->y_res_list[++i] = 200;
}
if(s->std_res_240 && s->max_y_res >= 240 && s->min_y_res <= 240){
s->y_res_list[++i] = 240;
}
if(s->std_res_300 && s->max_y_res >= 300 && s->min_y_res <= 300){
s->y_res_list[++i] = 300;
}
if(s->std_res_320 && s->max_y_res >= 320 && s->min_y_res <= 320){
s->y_res_list[++i] = 320;
}
if(s->std_res_400 && s->max_y_res >= 400 && s->min_y_res <= 400){
s->y_res_list[++i] = 400;
}
if(s->std_res_480 && s->max_y_res >= 480 && s->min_y_res <= 480){
s->y_res_list[++i] = 480;
}
if(s->std_res_600 && s->max_y_res >= 600 && s->min_y_res <= 600){
s->y_res_list[++i] = 600;
}
if(s->std_res_800 && s->max_y_res >= 800 && s->min_y_res <= 800){
s->y_res_list[++i] = 800;
}
if(s->std_res_1200 && s->max_y_res >= 1200 && s->min_y_res <= 1200){
s->y_res_list[++i] = 1200;
}
s->y_res_list[0] = i;
i=0;
for(j=0;j<16;j++){
if(s->std_res[j]
&& s->max_x_res >= reses[j] && s->min_x_res <= reses[j]
&& s->max_y_res >= reses[j] && s->min_y_res <= reses[j]
){
s->res_list[++i] = reses[j];
}
}
s->res_list[0] = i;
opt->name = SANE_NAME_SCAN_Y_RESOLUTION;
opt->title = SANE_TITLE_SCAN_Y_RESOLUTION;
opt->desc = SANE_DESC_SCAN_Y_RESOLUTION;
opt->type = SANE_TYPE_INT;
opt->unit = SANE_UNIT_DPI;
opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
if(s->step_y_res){
s->y_res_range.min = s->min_y_res;
s->y_res_range.max = s->max_y_res;
s->y_res_range.quant = s->step_y_res;
opt->constraint_type = SANE_CONSTRAINT_RANGE;
opt->constraint.range = &s->y_res_range;
}
else{
opt->constraint_type = SANE_CONSTRAINT_WORD_LIST;
opt->constraint.word_list = s->y_res_list;
opt->constraint.word_list = s->res_list;
}
}
@ -4188,14 +4112,10 @@ sane_control_option (SANE_Handle handle, SANE_Int option,
}
return SANE_STATUS_GOOD;
case OPT_X_RES:
case OPT_RES:
*val_p = s->resolution_x;
return SANE_STATUS_GOOD;
case OPT_Y_RES:
*val_p = s->resolution_y;
return SANE_STATUS_GOOD;
case OPT_TL_X:
*val_p = SCANNER_UNIT_TO_FIXED_MM(s->tl_x);
return SANE_STATUS_GOOD;
@ -4767,27 +4687,12 @@ sane_control_option (SANE_Handle handle, SANE_Int option,
*info |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
return SANE_STATUS_GOOD;
case OPT_X_RES:
case OPT_RES:
if (s->resolution_x == val_c)
return SANE_STATUS_GOOD;
/* currently the same? move y too */
if (s->resolution_x == s->resolution_y){
s->resolution_y = val_c;
/*sanei_constrain_value (s->opt + OPT_Y_RES, (void *) &val_c, 0) == SANE_STATUS_GOOD*/
}
s->resolution_x = val_c;
*info |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
return SANE_STATUS_GOOD;
case OPT_Y_RES:
if (s->resolution_y == val_c)
return SANE_STATUS_GOOD;
s->resolution_y = val_c;
*info |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
@ -6062,7 +5967,7 @@ sane_start (SANE_Handle handle)
s->side = SIDE_BACK;
}
/* batch start? inititalize struct and scanner */
/* batch start? initialize struct and scanner */
if(!s->started){
/* load side marker */
@ -6189,7 +6094,7 @@ sane_start (SANE_Handle handle)
* option combinations can't handle it, so we make a big one */
if(
(s->mode == MODE_COLOR && s->color_interlace == COLOR_INTERLACE_3091)
|| (s->swcrop || s->swdeskew || s->swdespeck
|| ( (s->swcrop || s->swdeskew || s->swdespeck)
#ifdef SANE_FRAME_JPEG
&& s->params.format != SANE_FRAME_JPEG
#endif
@ -6383,7 +6288,14 @@ scanner_control (struct fujitsu *s, int function)
set_SC_function (cmd, function);
DBG (15, "scanner_control: function %d\n",function);
/* don't really need to ask for adf if that's the only option */
/* doing so causes the 3091 to complain */
if(function == SC_function_adf && !s->has_flatbed){
DBG (10, "scanner_control: adf function not required\n");
return ret;
}
/* extremely long retry period */
while(tries++ < 120){
@ -6808,7 +6720,16 @@ get_pixelsize(struct fujitsu *s)
if (ret == SANE_STATUS_GOOD){
s->params.pixels_per_line = get_PSIZE_num_x(in);
s->params.lines = get_PSIZE_num_y(in);
/* stupid trick. 3091/2 require reading extra lines,
* because they have a gap between R G and B
* we only want to report the shorter value to the frontend */
if(s->mode == MODE_COLOR && s->color_interlace == COLOR_INTERLACE_3091){
DBG(5,"get_pixelsize: Ignoring length %d\n",get_PSIZE_num_y(in));
}
else{
s->params.lines = get_PSIZE_num_y(in);
}
/* bytes per line differs by mode */
if (s->mode == MODE_COLOR) {
@ -7005,70 +6926,66 @@ sane_read (SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len, SANE_Int * len
/* protect this block from sane_cancel */
s->reading = 1;
/* get more data if there is room for at least 2 lines */
if(s->buff_tot[s->side]-s->buff_rx[s->side] >= s->params.bytes_per_line*2){
/* ----------------------------------------------
* try to read some data from scanner into buffer
* these functions are expected not to overrun */
/* 3091/2 are on crack, get their own duplex reader function */
if(s->source == SOURCE_ADF_DUPLEX
&& s->duplex_interlace == DUPLEX_INTERLACE_3091
&& (!s->eof_rx[SIDE_FRONT] || !s->eof_rx[SIDE_BACK])
){
ret = read_from_3091duplex(s);
if(ret){
DBG(5,"sane_read: 3091 returning %d\n",ret);
return ret;
}
} /* end 3091 */
/* 3091/2 are on crack, get their own duplex reader function */
if(s->source == SOURCE_ADF_DUPLEX
&& s->duplex_interlace == DUPLEX_INTERLACE_3091
){
ret = read_from_3091duplex(s);
if(ret){
DBG(5,"sane_read: 3091 returning %d\n",ret);
return ret;
}
} /* end 3091 */
#ifdef SANE_FRAME_JPEG
/* alternating jpeg duplex interlacing */
else if(s->source == SOURCE_ADF_DUPLEX
&& s->params.format == SANE_FRAME_JPEG
&& s->jpeg_interlace == JPEG_INTERLACE_ALT
&& (!s->eof_rx[SIDE_FRONT] || !s->eof_rx[SIDE_BACK])
){
ret = read_from_JPEGduplex(s);
if(ret){
DBG(5,"sane_read: jpeg duplex returning %d\n",ret);
return ret;
}
} /* end alt jpeg */
/* alternating jpeg duplex interlacing */
else if(s->source == SOURCE_ADF_DUPLEX
&& s->params.format == SANE_FRAME_JPEG
&& s->jpeg_interlace == JPEG_INTERLACE_ALT
){
ret = read_from_JPEGduplex(s);
if(ret){
DBG(5,"sane_read: jpeg duplex returning %d\n",ret);
return ret;
}
} /* end alt jpeg */
#endif
/* alternating pnm duplex interlacing */
else if(s->source == SOURCE_ADF_DUPLEX
&& s->params.format <= SANE_FRAME_RGB
&& s->duplex_interlace == DUPLEX_INTERLACE_ALT
){
/* alternating pnm duplex interlacing */
else if(s->source == SOURCE_ADF_DUPLEX
&& s->params.format <= SANE_FRAME_RGB
&& s->duplex_interlace == DUPLEX_INTERLACE_ALT
){
/* buffer front side */
if(!s->eof_rx[SIDE_FRONT]){
ret = read_from_scanner(s, SIDE_FRONT);
if(ret){
DBG(5,"sane_read: front returning %d\n",ret);
return ret;
}
}
/* buffer back side */
if(!s->eof_rx[SIDE_BACK]){
ret = read_from_scanner(s, SIDE_BACK);
if(ret){
DBG(5,"sane_read: back returning %d\n",ret);
return ret;
}
}
} /* end alt pnm */
/* simplex or non-alternating duplex */
else if(!s->eof_rx[s->side]){
ret = read_from_scanner(s, s->side);
/* buffer front side */
ret = read_from_scanner(s, SIDE_FRONT);
if(ret){
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);
if(ret){
DBG(5,"sane_read: side %d returning %d\n",s->side,ret);
DBG(5,"sane_read: back returning %d\n",ret);
return ret;
}
} /*end simplex*/
} /*end get more from scanner*/
}
} /* end alt pnm */
/* simplex or non-alternating duplex */
else{
ret = read_from_scanner(s, s->side);
if(ret){
DBG(5,"sane_read: side %d returning %d\n",s->side,ret);
return ret;
}
} /*end simplex*/
/* copy a block from buffer to frontend */
ret = read_from_buffer(s,buf,max_len,len,s->side);
@ -7106,29 +7023,37 @@ read_from_JPEGduplex(struct fujitsu *s)
size_t inLen = 0;
int bytes = s->buffer_size;
int remain = (s->bytes_tot[SIDE_FRONT] - s->bytes_rx[SIDE_FRONT])
+ (s->bytes_tot[SIDE_BACK] - s->bytes_rx[SIDE_BACK]);
int i=0;
int i = 0;
DBG (10, "read_from_JPEGduplex: start\n");
/* figure out the max amount to transfer */
if(bytes > remain){
bytes = remain;
if(s->eof_rx[SIDE_FRONT] && s->eof_rx[SIDE_BACK]){
DBG (10, "read_from_JPEGduplex: already have eofs, done\n");
return ret;
}
if(bytes > s->buffer_size){
bytes = s->buffer_size;
/* we don't know if the following read will give us front or back data
* so we only get enough to fill whichever is smaller (and not yet done) */
if(!s->eof_rx[SIDE_FRONT]){
int avail = s->buff_tot[SIDE_FRONT] - s->buff_rx[SIDE_FRONT];
if(bytes > avail)
bytes = avail;
}
if(!s->eof_rx[SIDE_BACK]){
int avail = s->buff_tot[SIDE_BACK] - s->buff_rx[SIDE_BACK];
if(bytes > avail)
bytes = avail;
}
DBG(15, "read_from_JPEGduplex: fto:%d frx:%d bto:%d brx:%d re:%d pa:%d\n",
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],
remain, bytes);
bytes);
/* this should never happen */
/* this will happen if buffer is not drained yet */
if(bytes < 1){
DBG(5, "read_from_JPEGduplex: ERROR: no bytes this pass\n");
return SANE_STATUS_INVAL;
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 */
@ -7366,37 +7291,54 @@ read_from_3091duplex(struct fujitsu *s)
int side = SIDE_FRONT;
int bytes = s->buffer_size;
int remain = (s->bytes_tot[SIDE_FRONT] - s->bytes_rx[SIDE_FRONT])
+ (s->bytes_tot[SIDE_BACK] - s->bytes_rx[SIDE_BACK]);
int off = (s->duplex_raster_offset+s->duplex_offset) * s->resolution_y/300;
unsigned int i;
DBG (10, "read_from_3091duplex: start\n");
/* figure out the max amount to transfer */
if(bytes > remain){
bytes = remain;
}
if(bytes > s->buffer_size){
bytes = s->buffer_size;
if(s->eof_rx[SIDE_FRONT] && s->eof_rx[SIDE_BACK]){
DBG (10, "read_from_3091duplex: already have eofs, done\n");
return ret;
}
/* all requests must end on line boundary */
/* we don't know if the following read will give us front,back or both data
* so we only get enough to fill whichever is smaller (and not yet done) */
if(!s->eof_rx[SIDE_FRONT]){
int avail = s->buff_tot[SIDE_FRONT] - s->buff_rx[SIDE_FRONT];
if(bytes > avail)
bytes = avail;
}
if(!s->eof_rx[SIDE_BACK]){
int avail = s->buff_tot[SIDE_BACK] - s->buff_rx[SIDE_BACK];
if(bytes > avail)
bytes = avail;
}
/* all requests must end on a line boundary */
bytes -= (bytes % s->params.bytes_per_line);
/* this should never happen */
DBG(15, "read_from_3091duplex: front img: to:%d rx:%d tx:%d li:%d\n",
s->bytes_tot[SIDE_FRONT], s->bytes_rx[SIDE_FRONT],
s->bytes_tx[SIDE_FRONT], s->lines_rx[SIDE_FRONT]);
DBG(15, "read_from_3091duplex: front buf: to:%d rx:%d tx:%d\n",
s->buff_tot[SIDE_FRONT], s->buff_rx[SIDE_FRONT],
s->buff_tx[SIDE_FRONT]);
DBG(15, "read_from_3091duplex: back img: to:%d rx:%d tx:%d li:%d\n",
s->bytes_tot[SIDE_BACK], s->bytes_rx[SIDE_BACK],
s->bytes_tx[SIDE_BACK], s->lines_rx[SIDE_BACK]);
DBG(15, "read_from_3091duplex: back buf: to:%d rx:%d tx:%d\n",
s->buff_tot[SIDE_BACK], s->buff_rx[SIDE_BACK],
s->buff_tx[SIDE_BACK]);
DBG(15, "read_from_3091duplex: bu:%d pa:%d of:%d\n",
s->buffer_size, bytes, off);
/* this could happen if the front buffer is not drained fast enough */
if(bytes < 1){
DBG(5, "read_from_3091duplex: ERROR: no bytes this pass\n");
ret = SANE_STATUS_INVAL;
}
DBG(15, "read_from_3091duplex: to:%d rx:%d li:%d re:%d bu:%d pa:%d of:%d\n",
s->bytes_tot[SIDE_FRONT] + s->bytes_tot[SIDE_BACK],
s->bytes_rx[SIDE_FRONT] + s->bytes_rx[SIDE_BACK],
s->lines_rx[SIDE_FRONT] + s->lines_rx[SIDE_BACK],
remain, s->buffer_size, bytes, off);
if(ret){
DBG(10, "read_from_3091duplex: Warning: no bytes this pass\n");
return ret;
}
@ -7491,18 +7433,20 @@ read_from_scanner(struct fujitsu *s, int side)
unsigned char * in;
size_t inLen = 0;
int bytes = s->buff_tot[side] - s->buff_rx[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\n");
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;
}
/* figure out the max amount to transfer */
if(bytes > remain){
bytes = remain;
}
if(bytes > s->buffer_size){
bytes = s->buffer_size;
}
if(bytes > avail)
bytes = avail;
/* all requests must end on line boundary */
bytes -= (bytes % s->params.bytes_per_line);
@ -7514,11 +7458,12 @@ read_from_scanner(struct fujitsu *s, int side)
bytes -= s->params.bytes_per_line;
}
DBG(15, "read_from_scanner: si:%d re:%d bs:%d by:%d\n",
side, remain, s->buffer_size, bytes);
DBG(15, "read_from_scanner: si:%d re:%d bs:%d by:%d av:%d\n",
side, remain, s->buffer_size, bytes, avail);
DBG(15, "read_from_scanner: img to:%d rx:%d tx:%d\n",
s->bytes_tot[side], s->bytes_rx[side], s->bytes_tx[side]);
DBG(15, "read_from_scanner: img to:%d rx:%d tx:%d li:%d\n",
s->bytes_tot[side], s->bytes_rx[side], s->bytes_tx[side],
s->lines_rx[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]);
@ -7580,6 +7525,8 @@ read_from_scanner(struct fujitsu *s, int side)
inLen = 0;
}
DBG(15, "read_from_scanner: read %d bytes\n",inLen);
if(inLen){
if(s->mode==MODE_COLOR && s->color_interlace == COLOR_INTERLACE_3091){
copy_3091 (s, in, inLen, side);
@ -7631,8 +7578,10 @@ 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.
* Here, we just get things on correct line,
* interlacing to make RGBRGB comes later.
*
* Here, we get things on correct line, and
* interlace to make RGBRGB.
*
* We add the user-supplied offsets before we scale
* so that they are independent of scanning resolution.
*/
@ -7640,7 +7589,7 @@ copy_3091(struct fujitsu *s, unsigned char * buf, int len, int side)
boff = (s->color_raster_offset+s->blue_offset) * s->resolution_y/300;
/* loop thru all lines in read buffer */
for(i=0;i<len/s->params.bytes_per_line;i+=s->params.bytes_per_line){
for(i=0;i<len;i+=s->params.bytes_per_line){
/* red at start of line */
dest = s->lines_rx[side] * s->params.bytes_per_line;
@ -7685,6 +7634,10 @@ copy_3091(struct fujitsu *s, unsigned char * buf, int len, int side)
s->eof_rx[side] = 1;
}
DBG(15, "copy_3091: si:%d imgrx:%d bufrx:%d li:%d eof:%d\n",
side, s->bytes_rx[side], s->buff_rx[side], s->lines_rx[side],
s->eof_rx[side]);
DBG (10, "copy_3091: finish\n");
return ret;

Wyświetl plik

@ -18,16 +18,15 @@ enum fujitsu_Option
OPT_STANDARD_GROUP,
OPT_SOURCE, /*fb/adf/front/back/duplex*/
OPT_MODE, /*mono/gray/color*/
OPT_X_RES, /*a range or a list*/
OPT_Y_RES, /*a range or a list*/
OPT_RES, /*a range or a list*/
OPT_GEOMETRY_GROUP,
OPT_PAGE_WIDTH,
OPT_PAGE_HEIGHT,
OPT_TL_X,
OPT_TL_Y,
OPT_BR_X,
OPT_BR_Y,
OPT_PAGE_WIDTH,
OPT_PAGE_HEIGHT,
OPT_ENHANCEMENT_GROUP,
OPT_BRIGHTNESS,
@ -153,29 +152,14 @@ struct fujitsu
/* members in order found in scsi data... */
int basic_x_res;
int basic_y_res;
int step_x_res;
int step_y_res;
int step_x_res[6]; /*one for each mode*/
int step_y_res[6]; /*one for each mode*/
int max_x_res;
int max_y_res;
int min_x_res;
int min_y_res;
int std_res_200;
int std_res_180;
int std_res_160;
int std_res_150;
int std_res_120;
int std_res_100;
int std_res_75;
int std_res_60;
int std_res_1200;
int std_res_800;
int std_res_600;
int std_res_480;
int std_res_400;
int std_res_320;
int std_res_300;
int std_res_240;
int std_res[16]; /*some scanners only support a few resolutions*/
/* max scan size in pixels comes from scanner in basic res units */
int max_x_basic;
@ -348,10 +332,8 @@ struct fujitsu
SANE_String_Const mode_list[7];
SANE_String_Const source_list[5];
SANE_Int x_res_list[17];
SANE_Int y_res_list[17];
SANE_Range x_res_range;
SANE_Range y_res_range;
SANE_Int res_list[17];
SANE_Range res_range;
/*geometry group*/
SANE_Range tl_x_range;