kopia lustrzana https://gitlab.com/sane-project/backends
backend/canon_dr.[ch], backend/canon_dr-cmd.c,
doc/descriptions/canon_dr.desc: backend v5 - remove EOF ejection code - add SSM and GSM commands - add dropout, doublefeed, and jpeg compression options - disable adf backside - fix adf duplex - read two extra lines (ignore errors) at end of image - only send scan command at beginning of batch - fix bug in hexdump with 0 length string - DR-7580 supportmerge-requests/1/head
rodzic
251153010d
commit
9e0e272a9b
16
ChangeLog
16
ChangeLog
|
@ -1,3 +1,16 @@
|
|||
2008-11-25 m. allan noah <kitno455 a t gmail d o t com>
|
||||
* backend/canon_dr.[ch], backend/canon_dr-cmd.c,
|
||||
doc/descriptions/canon_dr.desc: backend v5
|
||||
- remove EOF ejection code
|
||||
- add SSM and GSM commands
|
||||
- add dropout, doublefeed, and jpeg compression options
|
||||
- disable adf backside
|
||||
- fix adf duplex
|
||||
- read two extra lines (ignore errors) at end of image
|
||||
- only send scan command at beginning of batch
|
||||
- fix bug in hexdump with 0 length string
|
||||
- DR-7580 support
|
||||
|
||||
2008-11-25 Nicolas Martin <nicols-guest at users.alioth.debian.org>
|
||||
* backend/pixma.c:
|
||||
Fixed regression bug at end of scan for all PIXMA, noticeable
|
||||
|
@ -7,7 +20,8 @@
|
|||
* backend/pixma_mp150.c, sane-backends/po/sane-backends.fr.po,
|
||||
doc/descriptions/pixma.desc, doc/sane-pixma.man:
|
||||
Support for MP630 in pixma backend.
|
||||
Updated docs for MP630, and network interface to various PIXMA models in pixma.desc.
|
||||
Updated docs for MP630, and network interface to various PIXMA models
|
||||
in pixma.desc.
|
||||
Fixed some typos in French translations.
|
||||
|
||||
2008-11-20 Stéphane Voltz <stef.dev@free.fr>
|
||||
|
|
|
@ -280,9 +280,13 @@ putnbyte (unsigned char *pnt, unsigned int value, unsigned int nbytes)
|
|||
#define SM_pc_adf 0x01
|
||||
#define SM_pc_tpu 0x02
|
||||
#define SM_pc_scan_ctl 0x20
|
||||
#define SM_pc_unknown30 0x30
|
||||
#define SM_pc_unknown32 0x32
|
||||
#define SM_pc_unknown34 0x34
|
||||
|
||||
#define SM_pc_df 0x30
|
||||
#define SM_pc_duplex 0x32
|
||||
#define SM_pc_imprinter 0x34
|
||||
#define SM_pc_dropout 0x36
|
||||
#define SM_pc_unknown 0x37
|
||||
|
||||
#define SM_pc_all_pc 0x3F
|
||||
|
||||
/* ==================================================================== */
|
||||
|
@ -301,11 +305,35 @@ putnbyte (unsigned char *pnt, unsigned int value, unsigned int nbytes)
|
|||
#define SET_SCAN_MODE_code 0xd6
|
||||
#define SET_SCAN_MODE_len 6
|
||||
|
||||
#define set_SSM_unkown(sb, val) sb[0x01] = val
|
||||
#define set_SSM_page_code(sb, val) sb[0x02] = val
|
||||
#define set_SSM_len(sb, val) sb[0x04] = val
|
||||
#define set_SSM_pf(sb, val) setbitfield(sb + 1, 1, 4, val)
|
||||
#define set_SSM_pay_len(sb, val) sb[0x04] = val
|
||||
|
||||
#define SSM_PSIZE_len 0x14
|
||||
/* the payload */
|
||||
#define SSM_PAY_len 0x14
|
||||
#define set_SSM_page_code(sb, val) sb[0x04] = val
|
||||
#define SSM_PAGE_len 0x0e
|
||||
#define set_SSM_page_len(sb, val) sb[0x05] = val
|
||||
|
||||
/* for DF page */
|
||||
#define set_SSM_DF_unk1(sb, val) setbitfield(sb+7, 1, 5, val)
|
||||
#define set_SSM_DF_len(sb, val) setbitfield(sb+7, 1, 0, val)
|
||||
#define set_SSM_DF_thick(sb, val) setbitfield(sb+7, 1, 2, val)
|
||||
|
||||
/* for DUPLEX page */
|
||||
#define set_SSM_DUP_1(sb, val) sb[0x06] = val
|
||||
#define set_SSM_DUP_2(sb, val) sb[0x0a] = val
|
||||
|
||||
/* for DO page */
|
||||
#define SSM_DO_none 0
|
||||
#define SSM_DO_red 1
|
||||
#define SSM_DO_green 2
|
||||
#define SSM_DO_blue 3
|
||||
#define set_SSM_DO_unk1(sb, val) sb[0x07] = val
|
||||
#define set_SSM_DO_unk2(sb, val) sb[0x09] = val
|
||||
#define set_SSM_DO_f_do(sb, val) sb[0x0b] = val
|
||||
#define set_SSM_DO_b_do(sb, val) sb[0x0c] = val
|
||||
#define set_SSM_DO_f_en(sb, val) sb[0x0d] = val
|
||||
#define set_SSM_DO_b_en(sb, val) sb[0x0e] = val
|
||||
|
||||
/* ==================================================================== */
|
||||
/* window descriptor macros for SET_WINDOW and GET_WINDOW */
|
||||
|
@ -400,10 +428,7 @@ putnbyte (unsigned char *pnt, unsigned int value, unsigned int nbytes)
|
|||
#define WD_cmp_MH 1
|
||||
#define WD_cmp_MR 2
|
||||
#define WD_cmp_MMR 3
|
||||
#define WD_cmp_JBIG 0x80
|
||||
#define WD_cmp_JPG1 0x81
|
||||
#define WD_cmp_JPG2 0x82
|
||||
#define WD_cmp_JPG3 0x83
|
||||
#define WD_cmp_JPEG 0x80
|
||||
|
||||
/* 0x21 - compression argument
|
||||
* specify "k" parameter with MR compress,
|
||||
|
|
|
@ -72,6 +72,16 @@
|
|||
- add rif option
|
||||
v4 2008-11-11, MAN
|
||||
- eject document when sane_read() returns EOF
|
||||
v5 2008-11-25, MAN
|
||||
- remove EOF ejection code
|
||||
- add SSM and GSM commands
|
||||
- add dropout, doublefeed, and jpeg compression options
|
||||
- disable adf backside
|
||||
- fix adf duplex
|
||||
- read two extra lines (ignore errors) at end of image
|
||||
- only send scan command at beginning of batch
|
||||
- fix bug in hexdump with 0 length string
|
||||
- DR-7580 support
|
||||
|
||||
SANE FLOW DIAGRAM
|
||||
|
||||
|
@ -132,7 +142,7 @@
|
|||
#include "canon_dr.h"
|
||||
|
||||
#define DEBUG 1
|
||||
#define BUILD 4
|
||||
#define BUILD 5
|
||||
|
||||
/* values for SANE_DEBUG_CANON_DR env var:
|
||||
- errors 5
|
||||
|
@ -159,37 +169,22 @@ static const char string_Default[] = "Default";
|
|||
static const char string_On[] = "On";
|
||||
static const char string_Off[] = "Off";
|
||||
|
||||
static const char string_DTC[] = "DTC";
|
||||
static const char string_SDTC[] = "SDTC";
|
||||
|
||||
static const char string_Dither[] = "Dither";
|
||||
static const char string_Diffusion[] = "Diffusion";
|
||||
|
||||
static const char string_Red[] = "Red";
|
||||
static const char string_Green[] = "Green";
|
||||
static const char string_Blue[] = "Blue";
|
||||
static const char string_En_Red[] = "Enhance Red";
|
||||
static const char string_En_Green[] = "Enhance Green";
|
||||
static const char string_En_Blue[] = "Enhance Blue";
|
||||
|
||||
static const char string_White[] = "White";
|
||||
static const char string_Black[] = "Black";
|
||||
|
||||
static const char string_None[] = "None";
|
||||
static const char string_JPEG[] = "JPEG";
|
||||
|
||||
static const char string_Continue[] = "Continue";
|
||||
static const char string_Stop[] = "Stop";
|
||||
|
||||
static const char string_10mm[] = "10mm";
|
||||
static const char string_15mm[] = "15mm";
|
||||
static const char string_20mm[] = "20mm";
|
||||
|
||||
static const char string_Horizontal[] = "Horizontal";
|
||||
static const char string_HorizontalBold[] = "Horizontal bold";
|
||||
static const char string_HorizontalNarrow[] = "Horizontal narrow";
|
||||
static const char string_Vertical[] = "Vertical";
|
||||
static const char string_VerticalBold[] = "Vertical bold";
|
||||
|
||||
static const char string_TopToBottom[] = "Top to bottom";
|
||||
static const char string_BottomToTop[] = "Bottom to top";
|
||||
|
||||
static const char string_Front[] = "Front";
|
||||
static const char string_Back[] = "Back";
|
||||
|
||||
|
@ -864,6 +859,13 @@ init_model (struct scanner *s)
|
|||
s->reverse_by_mode[MODE_GRAYSCALE] = 0;
|
||||
s->reverse_by_mode[MODE_COLOR] = 0;
|
||||
|
||||
s->can_color = 1;
|
||||
s->has_rif = 1;
|
||||
s->has_adf = 1;
|
||||
s->has_duplex = 1;
|
||||
s->has_back = 0;
|
||||
s->has_comp_JPEG = 0;
|
||||
|
||||
/* convert to 1200dpi units */
|
||||
s->max_x = s->max_x_basic * 1200 / s->basic_x_res;
|
||||
s->max_y = s->max_y_basic * 1200 / s->basic_y_res;
|
||||
|
@ -874,12 +876,12 @@ init_model (struct scanner *s)
|
|||
|
||||
/* any settings missing from vpd */
|
||||
if (strstr (s->model_name,"DR-9080")){
|
||||
s->can_color = 1;
|
||||
s->has_comp_JPEG = 1;
|
||||
}
|
||||
|
||||
s->has_rif = 1;
|
||||
s->has_adf = 1;
|
||||
s->has_duplex = 1;
|
||||
s->has_back = 1;
|
||||
if (strstr (s->model_name,"DR-7580")){
|
||||
s->can_color = 0;
|
||||
s->has_comp_JPEG = 1;
|
||||
}
|
||||
|
||||
DBG (10, "init_model: finish\n");
|
||||
|
@ -1512,6 +1514,166 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option)
|
|||
opt->cap = SANE_CAP_INACTIVE;
|
||||
}
|
||||
|
||||
/* "Advanced" group ------------------------------------------------------ */
|
||||
if(option==OPT_ADVANCED_GROUP){
|
||||
opt->name = SANE_NAME_ADVANCED;
|
||||
opt->title = SANE_TITLE_ADVANCED;
|
||||
opt->desc = SANE_DESC_ADVANCED;
|
||||
opt->type = SANE_TYPE_GROUP;
|
||||
opt->constraint_type = SANE_CONSTRAINT_NONE;
|
||||
}
|
||||
|
||||
/*image compression*/
|
||||
if(option==OPT_COMPRESS){
|
||||
i=0;
|
||||
s->compress_list[i++]=string_None;
|
||||
|
||||
if(s->has_comp_JPEG){
|
||||
s->compress_list[i++]=string_JPEG;
|
||||
}
|
||||
|
||||
s->compress_list[i]=NULL;
|
||||
|
||||
opt->name = "compression";
|
||||
opt->title = "Compression";
|
||||
opt->desc = "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;
|
||||
opt->size = maxStringSize (opt->constraint.string_list);
|
||||
|
||||
if (i > 1){
|
||||
opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
|
||||
if (s->mode != MODE_COLOR && s->mode != MODE_GRAYSCALE){
|
||||
opt->cap |= SANE_CAP_INACTIVE;
|
||||
}
|
||||
}
|
||||
else
|
||||
opt->cap = SANE_CAP_INACTIVE;
|
||||
}
|
||||
|
||||
/*image compression arg*/
|
||||
if(option==OPT_COMPRESS_ARG){
|
||||
|
||||
opt->name = "compression-arg";
|
||||
opt->title = "Compression argument";
|
||||
opt->desc = "Level of JPEG compression. 1 is small file, 100 is large file.";
|
||||
opt->type = SANE_TYPE_INT;
|
||||
opt->unit = SANE_UNIT_NONE;
|
||||
opt->constraint_type = SANE_CONSTRAINT_RANGE;
|
||||
opt->constraint.range = &s->compress_arg_range;
|
||||
s->compress_arg_range.quant=1;
|
||||
|
||||
if(s->has_comp_JPEG){
|
||||
s->compress_arg_range.min=0;
|
||||
s->compress_arg_range.max=100;
|
||||
opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
|
||||
|
||||
if(s->compress != COMP_JPEG){
|
||||
opt->cap |= SANE_CAP_INACTIVE;
|
||||
}
|
||||
}
|
||||
else
|
||||
opt->cap = SANE_CAP_INACTIVE;
|
||||
}
|
||||
|
||||
/*double feed by length*/
|
||||
if(option==OPT_DF_LENGTH){
|
||||
opt->name = "df-length";
|
||||
opt->title = "DF by length";
|
||||
opt->desc = "Detect double feeds by comparing document lengths";
|
||||
opt->type = SANE_TYPE_BOOL;
|
||||
opt->unit = SANE_UNIT_NONE;
|
||||
opt->constraint_type = SANE_CONSTRAINT_NONE;
|
||||
|
||||
if (1)
|
||||
opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
|
||||
else
|
||||
opt->cap = SANE_CAP_INACTIVE;
|
||||
}
|
||||
|
||||
/*double feed by thickness */
|
||||
if(option==OPT_DF_THICKNESS){
|
||||
|
||||
opt->name = "df-thickness";
|
||||
opt->title = "DF by thickness";
|
||||
opt->desc = "Detect double feeds using thickness sensor";
|
||||
opt->type = SANE_TYPE_BOOL;
|
||||
opt->unit = SANE_UNIT_NONE;
|
||||
opt->constraint_type = SANE_CONSTRAINT_NONE;
|
||||
|
||||
if (1){
|
||||
opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_ADVANCED;
|
||||
}
|
||||
else
|
||||
opt->cap = SANE_CAP_INACTIVE;
|
||||
}
|
||||
|
||||
/*dropout color front*/
|
||||
if(option==OPT_DROPOUT_COLOR_F){
|
||||
s->do_color_list[0] = string_None;
|
||||
s->do_color_list[1] = string_Red;
|
||||
s->do_color_list[2] = string_Green;
|
||||
s->do_color_list[3] = string_Blue;
|
||||
s->do_color_list[4] = string_En_Red;
|
||||
s->do_color_list[5] = string_En_Green;
|
||||
s->do_color_list[6] = string_En_Blue;
|
||||
s->do_color_list[7] = NULL;
|
||||
|
||||
opt->name = "dropout-front";
|
||||
opt->title = "Dropout color front";
|
||||
opt->desc = "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;
|
||||
opt->size = maxStringSize (opt->constraint.string_list);
|
||||
|
||||
if (1){
|
||||
opt->cap = SANE_CAP_SOFT_SELECT|SANE_CAP_SOFT_DETECT|SANE_CAP_ADVANCED;
|
||||
if(s->mode == MODE_COLOR)
|
||||
opt->cap |= SANE_CAP_INACTIVE;
|
||||
}
|
||||
else
|
||||
opt->cap = SANE_CAP_INACTIVE;
|
||||
}
|
||||
|
||||
/*dropout color back*/
|
||||
if(option==OPT_DROPOUT_COLOR_B){
|
||||
s->do_color_list[0] = string_None;
|
||||
s->do_color_list[1] = string_Red;
|
||||
s->do_color_list[2] = string_Green;
|
||||
s->do_color_list[3] = string_Blue;
|
||||
s->do_color_list[4] = string_En_Red;
|
||||
s->do_color_list[5] = string_En_Green;
|
||||
s->do_color_list[6] = string_En_Blue;
|
||||
s->do_color_list[7] = NULL;
|
||||
|
||||
opt->name = "dropout-back";
|
||||
opt->title = "Dropout color back";
|
||||
opt->desc = "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;
|
||||
opt->size = maxStringSize (opt->constraint.string_list);
|
||||
|
||||
if (1){
|
||||
opt->cap = SANE_CAP_SOFT_SELECT|SANE_CAP_SOFT_DETECT|SANE_CAP_ADVANCED;
|
||||
if(s->mode == MODE_COLOR)
|
||||
opt->cap |= SANE_CAP_INACTIVE;
|
||||
}
|
||||
else
|
||||
opt->cap = SANE_CAP_INACTIVE;
|
||||
}
|
||||
|
||||
/* "Sensor" group ------------------------------------------------------ */
|
||||
if(option==OPT_SENSOR_GROUP){
|
||||
opt->name = SANE_NAME_SENSORS;
|
||||
opt->title = SANE_TITLE_SENSORS;
|
||||
opt->desc = SANE_DESC_SENSORS;
|
||||
opt->type = SANE_TYPE_GROUP;
|
||||
opt->constraint_type = SANE_CONSTRAINT_NONE;
|
||||
}
|
||||
|
||||
if(option==OPT_COUNTER){
|
||||
opt->name = "counter";
|
||||
opt->title = "Counter";
|
||||
|
@ -1670,6 +1832,81 @@ sane_control_option (SANE_Handle handle, SANE_Int option,
|
|||
*val_p = s->rif;
|
||||
return SANE_STATUS_GOOD;
|
||||
|
||||
/* Advanced Group */
|
||||
case OPT_COMPRESS:
|
||||
if(s->compress == COMP_JPEG){
|
||||
strcpy (val, string_JPEG);
|
||||
}
|
||||
else{
|
||||
strcpy (val, string_None);
|
||||
}
|
||||
return SANE_STATUS_GOOD;
|
||||
|
||||
case OPT_COMPRESS_ARG:
|
||||
*val_p = s->compress_arg;
|
||||
return SANE_STATUS_GOOD;
|
||||
|
||||
case OPT_DF_LENGTH:
|
||||
*val_p = s->df_length;
|
||||
return SANE_STATUS_GOOD;
|
||||
|
||||
case OPT_DF_THICKNESS:
|
||||
*val_p = s->df_thickness;
|
||||
return SANE_STATUS_GOOD;
|
||||
|
||||
case OPT_DROPOUT_COLOR_F:
|
||||
switch (s->dropout_color_f) {
|
||||
case COLOR_NONE:
|
||||
strcpy (val, string_None);
|
||||
break;
|
||||
case COLOR_RED:
|
||||
strcpy (val, string_Red);
|
||||
break;
|
||||
case COLOR_GREEN:
|
||||
strcpy (val, string_Green);
|
||||
break;
|
||||
case COLOR_BLUE:
|
||||
strcpy (val, string_Blue);
|
||||
break;
|
||||
case COLOR_EN_RED:
|
||||
strcpy (val, string_En_Red);
|
||||
break;
|
||||
case COLOR_EN_GREEN:
|
||||
strcpy (val, string_En_Green);
|
||||
break;
|
||||
case COLOR_EN_BLUE:
|
||||
strcpy (val, string_En_Blue);
|
||||
break;
|
||||
}
|
||||
return SANE_STATUS_GOOD;
|
||||
|
||||
case OPT_DROPOUT_COLOR_B:
|
||||
switch (s->dropout_color_b) {
|
||||
case COLOR_NONE:
|
||||
strcpy (val, string_None);
|
||||
break;
|
||||
case COLOR_RED:
|
||||
strcpy (val, string_Red);
|
||||
break;
|
||||
case COLOR_GREEN:
|
||||
strcpy (val, string_Green);
|
||||
break;
|
||||
case COLOR_BLUE:
|
||||
strcpy (val, string_Blue);
|
||||
break;
|
||||
case COLOR_EN_RED:
|
||||
strcpy (val, string_En_Red);
|
||||
break;
|
||||
case COLOR_EN_GREEN:
|
||||
strcpy (val, string_En_Green);
|
||||
break;
|
||||
case COLOR_EN_BLUE:
|
||||
strcpy (val, string_En_Blue);
|
||||
break;
|
||||
}
|
||||
return SANE_STATUS_GOOD;
|
||||
|
||||
/* Sensor Group */
|
||||
case OPT_COUNTER:
|
||||
return read_counter (s,val_p);
|
||||
|
||||
|
@ -1730,7 +1967,7 @@ sane_control_option (SANE_Handle handle, SANE_Int option,
|
|||
|
||||
s->source = tmp;
|
||||
*info |= SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS;
|
||||
return SANE_STATUS_GOOD;
|
||||
return ssm_duplex(s);
|
||||
|
||||
case OPT_MODE:
|
||||
if (!strcmp (val, string_Lineart)) {
|
||||
|
@ -1845,11 +2082,67 @@ sane_control_option (SANE_Handle handle, SANE_Int option,
|
|||
s->threshold = val_c;
|
||||
return SANE_STATUS_GOOD;
|
||||
|
||||
/* IPC */
|
||||
case OPT_RIF:
|
||||
s->rif = val_c;
|
||||
return SANE_STATUS_GOOD;
|
||||
|
||||
/* Advanced Group */
|
||||
case OPT_COMPRESS:
|
||||
if (!strcmp (val, string_JPEG)) {
|
||||
s->compress = COMP_JPEG;
|
||||
}
|
||||
else{
|
||||
s->compress = COMP_NONE;
|
||||
}
|
||||
return SANE_STATUS_GOOD;
|
||||
|
||||
case OPT_COMPRESS_ARG:
|
||||
s->compress_arg = val_c;
|
||||
return SANE_STATUS_GOOD;
|
||||
|
||||
case OPT_DF_LENGTH:
|
||||
s->df_length = val_c;
|
||||
return ssm_df(s);
|
||||
|
||||
case OPT_DF_THICKNESS:
|
||||
s->df_thickness = val_c;
|
||||
return ssm_df(s);
|
||||
|
||||
case OPT_DROPOUT_COLOR_F:
|
||||
if (!strcmp(val, string_None))
|
||||
s->dropout_color_f = COLOR_NONE;
|
||||
else if (!strcmp(val, string_Red))
|
||||
s->dropout_color_f = COLOR_RED;
|
||||
else if (!strcmp(val, string_Green))
|
||||
s->dropout_color_f = COLOR_GREEN;
|
||||
else if (!strcmp(val, string_Blue))
|
||||
s->dropout_color_f = COLOR_BLUE;
|
||||
else if (!strcmp(val, string_En_Red))
|
||||
s->dropout_color_f = COLOR_EN_RED;
|
||||
else if (!strcmp(val, string_En_Green))
|
||||
s->dropout_color_f = COLOR_EN_GREEN;
|
||||
else if (!strcmp(val, string_En_Blue))
|
||||
s->dropout_color_f = COLOR_EN_BLUE;
|
||||
return ssm_do(s);
|
||||
|
||||
case OPT_DROPOUT_COLOR_B:
|
||||
if (!strcmp(val, string_None))
|
||||
s->dropout_color_b = COLOR_NONE;
|
||||
else if (!strcmp(val, string_Red))
|
||||
s->dropout_color_b = COLOR_RED;
|
||||
else if (!strcmp(val, string_Green))
|
||||
s->dropout_color_b = COLOR_GREEN;
|
||||
else if (!strcmp(val, string_Blue))
|
||||
s->dropout_color_b = COLOR_BLUE;
|
||||
else if (!strcmp(val, string_En_Red))
|
||||
s->dropout_color_b = COLOR_EN_RED;
|
||||
else if (!strcmp(val, string_En_Green))
|
||||
s->dropout_color_b = COLOR_EN_GREEN;
|
||||
else if (!strcmp(val, string_En_Blue))
|
||||
s->dropout_color_b = COLOR_EN_BLUE;
|
||||
return ssm_do(s);
|
||||
|
||||
/* Sensor Group */
|
||||
case OPT_COUNTER:
|
||||
return send_counter(s,val_c);
|
||||
}
|
||||
|
@ -1858,6 +2151,183 @@ sane_control_option (SANE_Handle handle, SANE_Int option,
|
|||
return SANE_STATUS_INVAL;
|
||||
}
|
||||
|
||||
static SANE_Status
|
||||
ssm_duplex (struct scanner *s)
|
||||
{
|
||||
SANE_Status ret = SANE_STATUS_GOOD;
|
||||
|
||||
unsigned char cmd[SET_SCAN_MODE_len];
|
||||
size_t cmdLen = SET_SCAN_MODE_len;
|
||||
|
||||
unsigned char out[SSM_PAY_len];
|
||||
size_t outLen = SSM_PAY_len;
|
||||
|
||||
DBG (10, "ssm_duplex: start\n");
|
||||
|
||||
memset(cmd,0,cmdLen);
|
||||
set_SCSI_opcode(cmd, SET_SCAN_MODE_code);
|
||||
set_SSM_pf(cmd, 1);
|
||||
set_SSM_pay_len(cmd, outLen);
|
||||
|
||||
memset(out,0,outLen);
|
||||
set_SSM_page_code(out, SM_pc_duplex);
|
||||
set_SSM_page_len(out, SSM_PAGE_len);
|
||||
|
||||
if(s->source == SOURCE_ADF_DUPLEX){
|
||||
set_SSM_DUP_1(out, 0x02);
|
||||
set_SSM_DUP_2(out, 0x40);
|
||||
}
|
||||
|
||||
ret = do_cmd (
|
||||
s, 1, 0,
|
||||
cmd, cmdLen,
|
||||
out, outLen,
|
||||
NULL, NULL
|
||||
);
|
||||
|
||||
DBG (10, "ssm_duplex: finish\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static SANE_Status
|
||||
ssm_df (struct scanner *s)
|
||||
{
|
||||
SANE_Status ret = SANE_STATUS_GOOD;
|
||||
|
||||
unsigned char cmd[SET_SCAN_MODE_len];
|
||||
size_t cmdLen = SET_SCAN_MODE_len;
|
||||
|
||||
unsigned char out[SSM_PAY_len];
|
||||
size_t outLen = SSM_PAY_len;
|
||||
|
||||
DBG (10, "ssm_df: start\n");
|
||||
|
||||
memset(cmd,0,cmdLen);
|
||||
set_SCSI_opcode(cmd, SET_SCAN_MODE_code);
|
||||
set_SSM_pf(cmd, 1);
|
||||
set_SSM_pay_len(cmd, outLen);
|
||||
|
||||
memset(out,0,outLen);
|
||||
set_SSM_page_code(out, SM_pc_df);
|
||||
set_SSM_page_len(out, SSM_PAGE_len);
|
||||
|
||||
if(s->df_thickness || s->df_length){
|
||||
set_SSM_DF_unk1(out, 1);
|
||||
|
||||
/* thickness */
|
||||
if(s->df_thickness){
|
||||
set_SSM_DF_thick(out, 1);
|
||||
}
|
||||
|
||||
/* length */
|
||||
if(s->df_length){
|
||||
set_SSM_DF_len(out, 1);
|
||||
}
|
||||
}
|
||||
|
||||
ret = do_cmd (
|
||||
s, 1, 0,
|
||||
cmd, cmdLen,
|
||||
out, outLen,
|
||||
NULL, NULL
|
||||
);
|
||||
|
||||
DBG (10, "ssm_df: finish\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static SANE_Status
|
||||
ssm_do (struct scanner *s)
|
||||
{
|
||||
SANE_Status ret = SANE_STATUS_GOOD;
|
||||
|
||||
unsigned char cmd[SET_SCAN_MODE_len];
|
||||
size_t cmdLen = SET_SCAN_MODE_len;
|
||||
|
||||
unsigned char out[SSM_PAY_len];
|
||||
size_t outLen = SSM_PAY_len;
|
||||
|
||||
DBG (10, "ssm_do: start\n");
|
||||
|
||||
memset(cmd,0,cmdLen);
|
||||
set_SCSI_opcode(cmd, SET_SCAN_MODE_code);
|
||||
set_SSM_pf(cmd, 1);
|
||||
set_SSM_pay_len(cmd, outLen);
|
||||
|
||||
memset(out,0,outLen);
|
||||
set_SSM_page_code(out, SM_pc_dropout);
|
||||
set_SSM_page_len(out, SSM_PAGE_len);
|
||||
|
||||
set_SSM_DO_unk1(out, 0x03);
|
||||
|
||||
switch(s->dropout_color_f){
|
||||
case COLOR_RED:
|
||||
set_SSM_DO_unk2(out, 0x05);
|
||||
set_SSM_DO_f_do(out,SSM_DO_red);
|
||||
break;
|
||||
case COLOR_GREEN:
|
||||
set_SSM_DO_unk2(out, 0x05);
|
||||
set_SSM_DO_f_do(out,SSM_DO_green);
|
||||
break;
|
||||
case COLOR_BLUE:
|
||||
set_SSM_DO_unk2(out, 0x05);
|
||||
set_SSM_DO_f_do(out,SSM_DO_blue);
|
||||
break;
|
||||
case COLOR_EN_RED:
|
||||
set_SSM_DO_unk2(out, 0x05);
|
||||
set_SSM_DO_f_en(out,SSM_DO_red);
|
||||
break;
|
||||
case COLOR_EN_GREEN:
|
||||
set_SSM_DO_unk2(out, 0x05);
|
||||
set_SSM_DO_f_en(out,SSM_DO_green);
|
||||
break;
|
||||
case COLOR_EN_BLUE:
|
||||
set_SSM_DO_unk2(out, 0x05);
|
||||
set_SSM_DO_f_en(out,SSM_DO_blue);
|
||||
break;
|
||||
}
|
||||
|
||||
switch(s->dropout_color_b){
|
||||
case COLOR_RED:
|
||||
set_SSM_DO_unk2(out, 0x05);
|
||||
set_SSM_DO_b_do(out,SSM_DO_red);
|
||||
break;
|
||||
case COLOR_GREEN:
|
||||
set_SSM_DO_unk2(out, 0x05);
|
||||
set_SSM_DO_b_do(out,SSM_DO_green);
|
||||
break;
|
||||
case COLOR_BLUE:
|
||||
set_SSM_DO_unk2(out, 0x05);
|
||||
set_SSM_DO_b_do(out,SSM_DO_blue);
|
||||
break;
|
||||
case COLOR_EN_RED:
|
||||
set_SSM_DO_unk2(out, 0x05);
|
||||
set_SSM_DO_b_en(out,SSM_DO_red);
|
||||
break;
|
||||
case COLOR_EN_GREEN:
|
||||
set_SSM_DO_unk2(out, 0x05);
|
||||
set_SSM_DO_b_en(out,SSM_DO_green);
|
||||
break;
|
||||
case COLOR_EN_BLUE:
|
||||
set_SSM_DO_unk2(out, 0x05);
|
||||
set_SSM_DO_b_en(out,SSM_DO_blue);
|
||||
break;
|
||||
}
|
||||
|
||||
ret = do_cmd (
|
||||
s, 1, 0,
|
||||
cmd, cmdLen,
|
||||
out, outLen,
|
||||
NULL, NULL
|
||||
);
|
||||
|
||||
DBG (10, "ssm_do: finish\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static SANE_Status
|
||||
read_counter(struct scanner *s,SANE_Word * val_p)
|
||||
{
|
||||
|
@ -1996,11 +2466,17 @@ sane_get_parameters (SANE_Handle handle, SANE_Parameters * params)
|
|||
params->format = SANE_FRAME_RGB;
|
||||
params->depth = 8;
|
||||
params->bytes_per_line = params->pixels_per_line * 3;
|
||||
if(s->compress == COMP_JPEG){
|
||||
params->format = SANE_FRAME_JPEG;
|
||||
}
|
||||
}
|
||||
else if (s->mode == MODE_GRAYSCALE) {
|
||||
params->format = SANE_FRAME_GRAY;
|
||||
params->depth = 8;
|
||||
params->bytes_per_line = params->pixels_per_line;
|
||||
if(s->compress == COMP_JPEG){
|
||||
params->format = SANE_FRAME_JPEG;
|
||||
}
|
||||
}
|
||||
else {
|
||||
params->format = SANE_FRAME_GRAY;
|
||||
|
@ -2126,6 +2602,11 @@ sane_start (SANE_Handle handle)
|
|||
return ret;
|
||||
}
|
||||
*/
|
||||
|
||||
/* eject paper leftover*/
|
||||
if(object_position (s, SANE_FALSE)){
|
||||
DBG (5, "sane_read: ERROR: cannot eject page\n");
|
||||
}
|
||||
}
|
||||
/* if already running, duplex needs to switch sides */
|
||||
else if(s->source == SOURCE_ADF_DUPLEX){
|
||||
|
@ -2163,23 +2644,6 @@ sane_start (SANE_Handle handle)
|
|||
s->bytes_tot[SIDE_BACK] = 0;
|
||||
}
|
||||
|
||||
/* first page of batch: make large buffer to hold the images, */
|
||||
/* eject any existing paper, and set started flag */
|
||||
if(!s->started){
|
||||
ret = setup_buffers(s);
|
||||
if (ret != SANE_STATUS_GOOD) {
|
||||
DBG (5, "sane_start: ERROR: cannot load buffers\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = object_position (s, SANE_FALSE);
|
||||
if (ret != SANE_STATUS_GOOD) {
|
||||
DBG (5, "sane_start: ERROR: cannot eject page\n");
|
||||
}
|
||||
|
||||
s->started=1;
|
||||
}
|
||||
|
||||
ret = object_position (s, SANE_TRUE);
|
||||
if (ret != SANE_STATUS_GOOD) {
|
||||
DBG (5, "sane_start: ERROR: cannot load page\n");
|
||||
|
@ -2187,12 +2651,24 @@ sane_start (SANE_Handle handle)
|
|||
return ret;
|
||||
}
|
||||
|
||||
ret = start_scan (s);
|
||||
if (ret != SANE_STATUS_GOOD) {
|
||||
DBG (5, "sane_start: ERROR: cannot start_scan\n");
|
||||
s->started=0;
|
||||
return ret;
|
||||
/* first page of batch: make large buffer to hold the images, */
|
||||
/* and set started flag */
|
||||
if(!s->started){
|
||||
ret = setup_buffers(s);
|
||||
if (ret != SANE_STATUS_GOOD) {
|
||||
DBG (5, "sane_start: ERROR: cannot load buffers\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = start_scan (s);
|
||||
if (ret != SANE_STATUS_GOOD) {
|
||||
DBG (5, "sane_start: ERROR: cannot start_scan\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
s->started=1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
DBG (15, "started=%d, side=%d, source=%d\n", s->started, s->side, s->source);
|
||||
|
@ -2333,8 +2809,13 @@ set_window (struct scanner *s)
|
|||
/*FIXME: what is this? */
|
||||
set_WD_reserved(desc1, 1);
|
||||
|
||||
set_WD_compress_type(desc1, 0);
|
||||
set_WD_compress_type(desc1, COMP_NONE);
|
||||
set_WD_compress_arg(desc1, 0);
|
||||
/* some scanners support jpeg image compression, for color/gs only */
|
||||
if(s->params.format == SANE_FRAME_JPEG){
|
||||
set_WD_compress_type(desc1, COMP_JPEG);
|
||||
set_WD_compress_arg(desc1, s->compress_arg);
|
||||
}
|
||||
|
||||
/*build the command*/
|
||||
memset(cmd,0,cmdLen);
|
||||
|
@ -2625,16 +3106,6 @@ sane_read (SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len, SANE_Int * len
|
|||
|
||||
/* sane_start required between sides */
|
||||
if(s->bytes_tx[s->side] == s->bytes_tot[s->side]){
|
||||
|
||||
/* eject paper at the end */
|
||||
if(s->source == SOURCE_ADF_FRONT || s->source == SOURCE_ADF_BACK
|
||||
|| (s->source == SOURCE_ADF_DUPLEX && s->side == SIDE_BACK)
|
||||
){
|
||||
if(object_position (s, SANE_FALSE)){
|
||||
DBG (5, "sane_read: ERROR: cannot eject page\n");
|
||||
}
|
||||
}
|
||||
|
||||
DBG (15, "sane_read: returning eof\n");
|
||||
return SANE_STATUS_EOF;
|
||||
}
|
||||
|
@ -2675,8 +3146,13 @@ sane_read (SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len, SANE_Int * len
|
|||
DBG(5,"sane_read: side %d returning %d\n",s->side,ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* we have finished reading, clean up */
|
||||
/* grab a bit more so scanner will send eof */
|
||||
if(s->bytes_rx[s->side] == s->bytes_tot[s->side]){
|
||||
read_from_scanner(s, s->side);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* copy a block from buffer to frontend */
|
||||
|
@ -2705,6 +3181,7 @@ read_from_scanner(struct scanner *s, int side)
|
|||
|
||||
int bytes = s->buffer_size;
|
||||
int remain = s->bytes_tot[side] - s->bytes_rx[side];
|
||||
int extra = 0;
|
||||
|
||||
DBG (10, "read_from_scanner: start\n");
|
||||
|
||||
|
@ -2716,19 +3193,17 @@ read_from_scanner(struct scanner *s, int side)
|
|||
/* all requests must end on line boundary */
|
||||
bytes -= (bytes % s->params.bytes_per_line);
|
||||
|
||||
/* this should never happen */
|
||||
if(bytes < 1){
|
||||
DBG(5, "read_from_scanner: ERROR: no bytes this pass\n");
|
||||
ret = SANE_STATUS_INVAL;
|
||||
/* these machines always send 1 extra line, and they need to send EOF too
|
||||
* so we ask for two full lines extra, and throw them away */
|
||||
if(!bytes){
|
||||
DBG(5, "read_from_scanner: no bytes, asking for two lines\n");
|
||||
bytes = 2 * s->params.bytes_per_line;
|
||||
extra = 1;
|
||||
}
|
||||
|
||||
DBG(15, "read_from_scanner: si:%d to:%d rx:%d re:%d bu:%d pa:%d\n", side,
|
||||
s->bytes_tot[side], s->bytes_rx[side], remain, s->buffer_size, bytes);
|
||||
|
||||
if(ret){
|
||||
return ret;
|
||||
}
|
||||
|
||||
inLen = bytes;
|
||||
in = malloc(inLen);
|
||||
if(!in){
|
||||
|
@ -2740,13 +3215,6 @@ read_from_scanner(struct scanner *s, int side)
|
|||
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 (
|
||||
|
@ -2772,7 +3240,7 @@ read_from_scanner(struct scanner *s, int side)
|
|||
inLen = 0;
|
||||
}
|
||||
|
||||
if(inLen){
|
||||
if(inLen && !extra){
|
||||
copy_buffer (s, in, inLen, side);
|
||||
}
|
||||
|
||||
|
@ -3694,6 +4162,8 @@ hexdump (int level, char *comment, unsigned char *p, int l)
|
|||
if(DBG_LEVEL < level)
|
||||
return;
|
||||
|
||||
line[0] = 0;
|
||||
|
||||
DBG (level, "%s\n", comment);
|
||||
|
||||
for (i = 0; i < l; i++, p++) {
|
||||
|
|
|
@ -55,6 +55,16 @@ enum scanner_Option
|
|||
OPT_THRESHOLD,
|
||||
OPT_RIF,
|
||||
|
||||
OPT_ADVANCED_GROUP,
|
||||
OPT_COMPRESS,
|
||||
OPT_COMPRESS_ARG,
|
||||
OPT_DF_THICKNESS,
|
||||
OPT_DF_LENGTH,
|
||||
OPT_DROPOUT_COLOR_F,
|
||||
OPT_DROPOUT_COLOR_B,
|
||||
|
||||
/*sensor group*/
|
||||
OPT_SENSOR_GROUP,
|
||||
OPT_COUNTER,
|
||||
|
||||
/* must come last: */
|
||||
|
@ -142,6 +152,7 @@ struct scanner
|
|||
int has_flatbed;
|
||||
int has_duplex;
|
||||
int has_back; /* not all duplex scanners can do adf back side only */
|
||||
int has_comp_JPEG;
|
||||
|
||||
int color_interlace; /* different models interlace colors differently */
|
||||
int duplex_interlace; /* different models interlace sides differently */
|
||||
|
@ -187,6 +198,12 @@ struct scanner
|
|||
SANE_Range contrast_range;
|
||||
SANE_Range threshold_range;
|
||||
|
||||
/*advanced group*/
|
||||
SANE_String_Const compress_list[3];
|
||||
SANE_Range compress_arg_range;
|
||||
SANE_String_Const do_color_list[8];
|
||||
|
||||
/*sensor group*/
|
||||
SANE_Range counter_range;
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
@ -213,6 +230,14 @@ struct scanner
|
|||
int threshold;
|
||||
int rif;
|
||||
|
||||
/*advanced group*/
|
||||
int compress;
|
||||
int compress_arg;
|
||||
int df_length;
|
||||
int df_thickness;
|
||||
int dropout_color_f;
|
||||
int dropout_color_b;
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/* values which are derived from setting the options above */
|
||||
/* the user never directly modifies these */
|
||||
|
@ -265,20 +290,26 @@ struct scanner
|
|||
#define SOURCE_ADF_BACK 2
|
||||
#define SOURCE_ADF_DUPLEX 3
|
||||
|
||||
#define COMP_NONE WD_cmp_NONE
|
||||
#define COMP_JPEG WD_cmp_JPEG
|
||||
|
||||
/* these are same as scsi data to make code easier */
|
||||
#define MODE_LINEART WD_comp_LA
|
||||
#define MODE_HALFTONE WD_comp_HT
|
||||
#define MODE_GRAYSCALE WD_comp_GS
|
||||
#define MODE_COLOR_LINEART WD_comp_CL
|
||||
#define MODE_COLOR_HALFTONE WD_comp_CH
|
||||
#define MODE_COLOR WD_comp_CG
|
||||
|
||||
/* these are same as dropout scsi data to make code easier */
|
||||
#define COLOR_DEFAULT 0
|
||||
#define COLOR_GREEN 8
|
||||
#define COLOR_RED 9
|
||||
#define COLOR_BLUE 11
|
||||
enum {
|
||||
COLOR_NONE = 0,
|
||||
COLOR_RED,
|
||||
COLOR_GREEN,
|
||||
COLOR_BLUE,
|
||||
COLOR_EN_RED,
|
||||
COLOR_EN_GREEN,
|
||||
COLOR_EN_BLUE
|
||||
};
|
||||
|
||||
/* these are same as scsi data to make code easier */
|
||||
#define COLOR_WHITE 1
|
||||
#define COLOR_BLACK 2
|
||||
|
||||
|
@ -286,11 +317,9 @@ struct scanner
|
|||
#define COLOR_INTERLACE_RGB 1
|
||||
#define COLOR_INTERLACE_BGR 2
|
||||
#define COLOR_INTERLACE_RRGGBB 3
|
||||
#define COLOR_INTERLACE_3091 4
|
||||
|
||||
#define DUPLEX_INTERLACE_ALT 0
|
||||
#define DUPLEX_INTERLACE_NONE 1
|
||||
#define DUPLEX_INTERLACE_3091 2
|
||||
#define DUPLEX_INTERLACE_NONE 0
|
||||
#define DUPLEX_INTERLACE_ALT 1
|
||||
|
||||
#define CROP_RELATIVE 0
|
||||
#define CROP_ABSOLUTE 1
|
||||
|
@ -396,6 +425,10 @@ static SANE_Status wait_scanner (struct scanner *s);
|
|||
|
||||
static SANE_Status object_position (struct scanner *s, int i_load);
|
||||
|
||||
static SANE_Status ssm_duplex (struct scanner *s);
|
||||
static SANE_Status ssm_do (struct scanner *s);
|
||||
static SANE_Status ssm_df (struct scanner *s);
|
||||
|
||||
int get_page_width (struct scanner *s);
|
||||
int get_page_height (struct scanner *s);
|
||||
|
||||
|
|
|
@ -82,14 +82,14 @@
|
|||
:model "DR-7580"
|
||||
:interface "USB SCSI"
|
||||
:usbid "0x04a9" "0x160b"
|
||||
:status :untested
|
||||
:comment "Please test!"
|
||||
:status :good
|
||||
:comment "Jpeg output broken, simplex/duplex working, multi-feed/dropout untested, imprinter unsupported"
|
||||
|
||||
:model "DR-9080C"
|
||||
:interface "USB SCSI"
|
||||
:usbid "0x04a9" "0x1603"
|
||||
:status :good
|
||||
:comment "No support for advanced options like compression, multifeed detection, etc."
|
||||
:comment "Jpeg output broken, simplex/duplex working, multi-feed/dropout untested, imprinter unsupported"
|
||||
|
||||
:model "DR-X10C"
|
||||
:interface "USB SCSI"
|
||||
|
|
Ładowanie…
Reference in New Issue