summaryrefslogtreecommitdiff
path: root/backend
diff options
context:
space:
mode:
authorJörg Frings-Fürst <debian@jff.email>2025-06-09 14:27:29 +0200
committerJörg Frings-Fürst <debian@jff.email>2025-06-09 14:27:29 +0200
commit652efae78c00b812033ea162d76cd13bd40dcab6 (patch)
tree7c139f4d2a28061607cd7e2269693df993e5d60a /backend
parentbfa2ae8e43fcbab696f272fffd164d0637e965c5 (diff)
New upstream version 1.4.0upstream/1.4.0upstream
Diffstat (limited to 'backend')
-rw-r--r--backend/Makefile.am2
-rw-r--r--backend/avision.c9
-rw-r--r--backend/bh.h3
-rw-r--r--backend/canon_dr-cmd.h1
-rw-r--r--backend/canon_dr.c24
-rw-r--r--backend/canon_dr.h5
-rw-r--r--backend/dell1600n_net.c2
-rw-r--r--backend/epson.c112
-rw-r--r--backend/epson2-ops.c14
-rw-r--r--backend/escl/escl.c81
-rw-r--r--backend/escl/escl.h6
-rw-r--r--backend/escl/escl_capabilities.c14
-rw-r--r--backend/escl/escl_crop.c8
-rw-r--r--backend/escl/escl_devices.c8
-rw-r--r--backend/escl/escl_jpeg.c4
-rw-r--r--backend/escl/escl_mupdf.c18
-rw-r--r--backend/escl/escl_newjob.c71
-rw-r--r--backend/escl/escl_pdf.c24
-rw-r--r--backend/escl/escl_png.c16
-rw-r--r--backend/escl/escl_reset.c42
-rw-r--r--backend/escl/escl_scan.c2
-rw-r--r--backend/escl/escl_status.c137
-rw-r--r--backend/escl/escl_tiff.c8
-rw-r--r--backend/genesys/genesys.cpp3
-rw-r--r--backend/genesys/gl124.cpp4
-rw-r--r--backend/genesys/gl124_registers.h2
-rw-r--r--backend/hp-option.c4
-rw-r--r--backend/hp-scl.c2
-rw-r--r--backend/hp3900_config.c10
-rw-r--r--backend/hp3900_rts8822.c8
-rw-r--r--backend/hp3900_sane.c4
-rw-r--r--backend/hp5400_internal.c4
-rw-r--r--backend/hp5590.c18
-rw-r--r--backend/hp5590_low.c8
-rw-r--r--backend/hpsj5s.c22
-rw-r--r--backend/kodakaio.c2
-rw-r--r--backend/lexmark_low.c6
-rw-r--r--backend/lexmark_x2600.c2
-rw-r--r--backend/magicolor.c71
-rw-r--r--backend/mustek_scsi_pp.c2
-rw-r--r--backend/mustek_usb2.c10
-rw-r--r--backend/mustek_usb2_high.c12
-rw-r--r--backend/mustek_usb2_reflective.c10
-rw-r--r--backend/mustek_usb2_transparent.c8
-rw-r--r--backend/net.c2
-rw-r--r--backend/pixma/pixma_common.h2
-rw-r--r--backend/pixma/pixma_imageclass.c1
-rw-r--r--backend/pixma/pixma_io_sanei.c4
-rw-r--r--backend/pixma/pixma_mp150.c24
-rw-r--r--backend/plustek-pp_io.c4
-rw-r--r--backend/rts8891.c1243
-rw-r--r--backend/rts8891_devices.c85
-rw-r--r--backend/rts8891_low.c74
-rw-r--r--backend/rts8891_low.h6
-rw-r--r--backend/sm3600.h4
-rw-r--r--backend/snapscan-usb.c2
-rw-r--r--backend/test.c2
-rw-r--r--backend/umax_pp_low.c2
-rw-r--r--backend/umax_pp_mid.c2
-rw-r--r--backend/xerox_mfp-usb.c2
-rw-r--r--backend/xerox_mfp.c66
-rw-r--r--backend/xerox_mfp.conf.in4
-rw-r--r--backend/xerox_mfp.h1
63 files changed, 1873 insertions, 480 deletions
diff --git a/backend/Makefile.am b/backend/Makefile.am
index 86b1d1f..4bf4e6f 100644
--- a/backend/Makefile.am
+++ b/backend/Makefile.am
@@ -1619,7 +1619,7 @@ libsane_rts8891_la_LIBADD = $(COMMON_LIBS) \
sane_strstatus.lo \
../sanei/sanei_scsi.lo \
../sanei/sanei_usb.lo \
- $(SCSI_LIBS) $(USB_LIBS) $(RESMGR_LIBS) $(RESMGR_LIBS)
+ $(MATH_LIB) $(SCSI_LIBS) $(USB_LIBS) $(RESMGR_LIBS) $(RESMGR_LIBS)
EXTRA_DIST += rts8891.conf.in
# TODO: Why are these distributed but not compiled?
EXTRA_DIST += rts8891_devices.c rts8891_low.c rts8891_low.h
diff --git a/backend/avision.c b/backend/avision.c
index a681ed2..3189e41 100644
--- a/backend/avision.c
+++ b/backend/avision.c
@@ -1321,6 +1321,15 @@ static Avision_HWEntry Avision_Device_List [] =
/* status="complete" */
{ NULL, NULL,
+ 0x262c, 0x2001,
+ "Xerox", "Book Scanner 4167",
+ AV_NON_INTERLACED_DUPLEX_300,
+ { 0, {0, 0}, {{0, 0}, {0, 0}} }
+ },
+ /* comment="1 pass, 1200 dpi, A3 - duplex! - zero edge! (rebadged Avision FB6080E)" */
+ /* status="complete" */
+
+ { NULL, NULL,
0x04a7, 0x049C,
"Xerox", "DocuMate150",
AV_INT_BUTTON | AV_SOFT_SCALE | AV_DOES_KEEP_WINDOW | AV_DOES_KEEP_GAMMA | AV_BACKGROUND_QUIRK,
diff --git a/backend/bh.h b/backend/bh.h
index c96dc79..1a4c7f1 100644
--- a/backend/bh.h
+++ b/backend/bh.h
@@ -544,9 +544,8 @@ static SANE_String_Const paper_list[] =
0
};
-static /* inline */ int _is_host_little_endian(void);
static /* inline */ int
-_is_host_little_endian()
+_is_host_little_endian(void)
{
SANE_Int val = 255;
unsigned char *firstbyte = (unsigned char *) &val;
diff --git a/backend/canon_dr-cmd.h b/backend/canon_dr-cmd.h
index 0ef883f..7812232 100644
--- a/backend/canon_dr-cmd.h
+++ b/backend/canon_dr-cmd.h
@@ -247,6 +247,7 @@ putnbyte (unsigned char *pnt, unsigned int value, unsigned int nbytes)
#define get_R_PANEL_count_only(in) getbitfield(in+1, 1, 1)
#define get_R_PANEL_bypass_mode(in) getbitfield(in+1, 1, 2)
#define get_R_PANEL_enable_led(in) getbitfield(in+2, 1, 0)
+#define get_R_PANEL_function_number(in) getbitfield(in+3, 0xf, 0)
#define get_R_PANEL_counter(in) getnbyte(in + 0x04, 4)
/*sensors*/
diff --git a/backend/canon_dr.c b/backend/canon_dr.c
index 359005a..9607e3c 100644
--- a/backend/canon_dr.c
+++ b/backend/canon_dr.c
@@ -464,6 +464,7 @@
#define STRING_IMPRINTER_ADDON_BoI SANE_I18N("Black-on-Image")
#define STRING_IMPRINTER_ADDON_WoB SANE_I18N("White-on-Black")
+
/* Also set via config file. */
static int global_buffer_size;
static int global_buffer_size_default = 2 * 1024 * 1024;
@@ -1564,6 +1565,7 @@ init_model (struct scanner *s)
s->fcal_dest = FCAL_DEST_SW;
s->sw_lut = 1;
s->invert_tly = 1;
+ s->has_function_number = 1;
/*only in Y direction, so we trash them in X*/
s->std_res_x[DPI_100]=0;
@@ -3214,6 +3216,22 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option)
opt->cap = SANE_CAP_INACTIVE;
}
+ if(option==OPT_FUNCTION_NUMBER){
+ opt->name = "function-number";
+ opt->title = "Function number";
+ opt->desc = "Function number set on panel";
+ opt->type = SANE_TYPE_INT;
+ opt->unit = SANE_UNIT_NONE;
+ opt->constraint_type = SANE_CONSTRAINT_RANGE;
+ opt->constraint.range = &s->counter_range;
+ s->counter_range.min=1;
+ s->counter_range.max=9;
+ s->counter_range.quant=1;
+ opt->cap = SANE_CAP_SOFT_DETECT | SANE_CAP_HARD_SELECT | SANE_CAP_ADVANCED;
+ if(!s->can_read_panel || !s->has_function_number)
+ opt->cap = SANE_CAP_INACTIVE;
+ }
+
if(option==OPT_ADF_LOADED){
opt->name = "adf-loaded";
opt->title = "ADF Loaded";
@@ -3654,6 +3672,11 @@ sane_control_option (SANE_Handle handle, SANE_Int option,
*val_p = s->total_counter;
return ret;
+ case OPT_FUNCTION_NUMBER:
+ ret = read_panel(s, OPT_FUNCTION_NUMBER);
+ *val_p = s->panel_function_number;
+ return ret;
+
case OPT_ADF_LOADED:
ret = read_sensors(s,OPT_ADF_LOADED);
*val_p = s->sensor_adf_loaded;
@@ -4674,6 +4697,7 @@ read_panel(struct scanner *s,SANE_Int option)
s->panel_bypass_mode = get_R_PANEL_bypass_mode(in);
s->panel_enable_led = get_R_PANEL_enable_led(in);
s->panel_counter = get_R_PANEL_counter(in);
+ s->panel_function_number = get_R_PANEL_function_number(in);
ret = SANE_STATUS_GOOD;
}
diff --git a/backend/canon_dr.h b/backend/canon_dr.h
index e84b5b7..d591e7a 100644
--- a/backend/canon_dr.h
+++ b/backend/canon_dr.h
@@ -78,6 +78,7 @@ enum scanner_Option
OPT_COUNTER,
OPT_ROLLERCOUNTER,
OPT_TOTALCOUNTER,
+ OPT_FUNCTION_NUMBER,
OPT_ADF_LOADED,
OPT_CARD_LOADED,
@@ -250,6 +251,7 @@ struct scanner
int has_hwcrop;
int has_pre_imprinter;
int has_post_imprinter;
+ int has_function_number;
int can_read_sensors;
int can_read_panel;
int can_write_panel;
@@ -445,13 +447,14 @@ struct scanner
int panel_bypass_mode;
int panel_enable_led;
int panel_counter;
+ int panel_function_number;
int sensor_adf_loaded;
int sensor_card_loaded;
int roller_counter;
int total_counter;
/* values which are used to track the frontend's access to sensors */
- char panel_read[OPT_COUNTER - OPT_START + 1];
+ char panel_read[OPT_FUNCTION_NUMBER - OPT_START + 1];
char sensors_read[OPT_CARD_LOADED - OPT_ADF_LOADED + 1];
};
diff --git a/backend/dell1600n_net.c b/backend/dell1600n_net.c
index 9f2d48d..45b0d2c 100644
--- a/backend/dell1600n_net.c
+++ b/backend/dell1600n_net.c
@@ -907,7 +907,7 @@ sane_get_select_fd (SANE_Handle __sane_unused__ handle,
/* Clears the contents of gKnownDevices and zeros it */
void
-ClearKnownDevices ()
+ClearKnownDevices (void)
{
int i;
diff --git a/backend/epson.c b/backend/epson.c
index d2aba4c..d1cad9f 100644
--- a/backend/epson.c
+++ b/backend/epson.c
@@ -851,9 +851,9 @@ static EpsonHdrUnion command (Epson_Scanner * s, u_char * cmd, size_t cmd_size,
SANE_Status * status);
static SANE_Status get_identity_information (SANE_Handle handle);
static SANE_Status get_identity2_information (SANE_Handle handle);
-static int send (Epson_Scanner * s, void *buf, size_t buf_size,
+static int scanner_send (Epson_Scanner * s, void *buf, size_t buf_size,
SANE_Status * status);
-static ssize_t receive (Epson_Scanner * s, void *buf, ssize_t buf_size,
+static ssize_t scanner_receive (Epson_Scanner * s, void *buf, ssize_t buf_size,
SANE_Status * status);
static SANE_Status color_shuffle (SANE_Handle handle, int *new_length);
static SANE_Status request_focus_position (SANE_Handle handle,
@@ -880,7 +880,7 @@ static void scan_finish (Epson_Scanner * s);
*/
static int
-send (Epson_Scanner * s, void *buf, size_t buf_size, SANE_Status * status)
+scanner_send (Epson_Scanner * s, void *buf, size_t buf_size, SANE_Status * status)
{
DBG (3, "send buf, size = %lu\n", (u_long) buf_size);
@@ -933,7 +933,7 @@ send (Epson_Scanner * s, void *buf, size_t buf_size, SANE_Status * status)
*/
static ssize_t
-receive (Epson_Scanner * s, void *buf, ssize_t buf_size, SANE_Status * status)
+scanner_receive (Epson_Scanner * s, void *buf, ssize_t buf_size, SANE_Status * status)
{
ssize_t n = 0;
@@ -1044,7 +1044,7 @@ expect_ack (Epson_Scanner * s)
len = sizeof (result);
- receive (s, result, len, &status);
+ scanner_receive (s, result, len, &status);
if (SANE_STATUS_GOOD != status)
return status;
@@ -1072,12 +1072,12 @@ set_cmd (Epson_Scanner * s, u_char cmd, int val)
params[0] = ESC;
params[1] = cmd;
- send (s, params, 2, &status);
+ scanner_send (s, params, 2, &status);
if (SANE_STATUS_GOOD != (status = expect_ack (s)))
return status;
params[0] = val;
- send (s, params, 1, &status);
+ scanner_send (s, params, 1, &status);
status = expect_ack (s);
return status;
@@ -1151,7 +1151,7 @@ set_zoom (Epson_Scanner * s, int x_zoom, int y_zoom)
cmd[0] = ESC;
cmd[1] = s->hw->cmd->set_zoom;
- send (s, cmd, 2, &status);
+ scanner_send (s, cmd, 2, &status);
status = expect_ack (s);
if (status != SANE_STATUS_GOOD)
@@ -1160,7 +1160,7 @@ set_zoom (Epson_Scanner * s, int x_zoom, int y_zoom)
params[0] = x_zoom;
params[1] = y_zoom;
- send (s, params, 2, &status);
+ scanner_send (s, params, 2, &status);
status = expect_ack (s);
return status;
@@ -1179,7 +1179,7 @@ set_resolution (Epson_Scanner * s, int xres, int yres)
params[0] = ESC;
params[1] = s->hw->cmd->set_resolution;
- send (s, params, 2, &status);
+ scanner_send (s, params, 2, &status);
status = expect_ack (s);
if (status != SANE_STATUS_GOOD)
@@ -1190,7 +1190,7 @@ set_resolution (Epson_Scanner * s, int xres, int yres)
params[2] = yres;
params[3] = yres >> 8;
- send (s, params, 4, &status);
+ scanner_send (s, params, 4, &status);
status = expect_ack (s);
return status;
@@ -1224,7 +1224,7 @@ set_scan_area (Epson_Scanner * s, int x, int y, int width, int height)
params[0] = ESC;
params[1] = s->hw->cmd->set_scan_area;
- send (s, params, 2, &status);
+ scanner_send (s, params, 2, &status);
status = expect_ack (s);
if (status != SANE_STATUS_GOOD)
return status;
@@ -1238,7 +1238,7 @@ set_scan_area (Epson_Scanner * s, int x, int y, int width, int height)
params[6] = height;
params[7] = height >> 8;
- send (s, params, 8, &status);
+ scanner_send (s, params, 8, &status);
status = expect_ack (s);
return status;
@@ -1267,7 +1267,7 @@ set_color_correction_coefficients (Epson_Scanner * s)
params[0] = ESC;
params[1] = cmd;
- send (s, params, 2, &status);
+ scanner_send (s, params, 2, &status);
if (SANE_STATUS_GOOD != (status = expect_ack (s)))
return status;
@@ -1285,7 +1285,7 @@ set_color_correction_coefficients (Epson_Scanner * s)
cct[0], cct[1], cct[2], cct[3],
cct[4], cct[5], cct[6], cct[7], cct[8]);
- send (s, cct, length, &status);
+ scanner_send (s, cct, length, &status);
status = expect_ack (s);
DBG (1, "set_color_correction_coefficients: ending=%d.\n", status);
@@ -1376,11 +1376,11 @@ set_gamma_table (Epson_Scanner * s)
}
}
- send (s, params, 2, &status);
+ scanner_send (s, params, 2, &status);
if (SANE_STATUS_GOOD != (status = expect_ack (s)))
return status;
- send (s, gamma, length, &status);
+ scanner_send (s, gamma, length, &status);
if (SANE_STATUS_GOOD != (status = expect_ack (s)))
return status;
@@ -1621,7 +1621,7 @@ reset (Epson_Scanner * s)
return status;
}
- send (s, param, 2, &status);
+ scanner_send (s, param, 2, &status);
status = expect_ack (s);
if (needToClose)
@@ -1658,8 +1658,8 @@ close_scanner (Epson_Scanner * s)
param[0] = ESC;
param[1] = s->hw->cmd->request_status;
param[2]='\0';
- send(s,param,2,&status);
- receive(s,result,4,&status);
+ scanner_send(s,param,2,&status);
+ scanner_receive(s,result,4,&status);
}
@@ -1782,7 +1782,7 @@ feed (Epson_Scanner * s)
params[0] = cmd;
- send (s, params, 1, &status);
+ scanner_send (s, params, 1, &status);
if (SANE_STATUS_GOOD != (status = expect_ack (s)))
{
@@ -1824,7 +1824,7 @@ eject (Epson_Scanner * s)
params[0] = cmd;
- send (s, params, 1, &status);
+ scanner_send (s, params, 1, &status);
if (SANE_STATUS_GOOD != (status = expect_ack (s)))
{
@@ -1866,7 +1866,7 @@ command (Epson_Scanner * s, u_char * cmd, size_t cmd_size,
head = &(hdrunion->hdr);
- send (s, cmd, cmd_size, status);
+ scanner_send (s, cmd, cmd_size, status);
if (SANE_STATUS_GOOD != *status)
{
@@ -1874,7 +1874,7 @@ command (Epson_Scanner * s, u_char * cmd, size_t cmd_size,
it seems to fix the problem. It should not have any
ill effects on other scanners. */
*status = SANE_STATUS_GOOD;
- send (s, cmd, cmd_size, status);
+ scanner_send (s, cmd, cmd_size, status);
if (SANE_STATUS_GOOD != *status)
return (EpsonHdrUnion) 0;
}
@@ -1883,18 +1883,18 @@ command (Epson_Scanner * s, u_char * cmd, size_t cmd_size,
if (s->hw->connection == SANE_EPSON_SCSI)
{
- receive (s, buf, 4, status);
+ scanner_receive (s, buf, 4, status);
buf += 4;
}
else if (s->hw->connection == SANE_EPSON_USB)
{
int bytes_read;
- bytes_read = receive (s, buf, 4, status);
+ bytes_read = scanner_receive (s, buf, 4, status);
buf += bytes_read;
}
else
{
- receive (s, buf, 1, status);
+ scanner_receive (s, buf, 1, status);
buf += 1;
}
@@ -1923,7 +1923,7 @@ command (Epson_Scanner * s, u_char * cmd, size_t cmd_size,
}
else
{
- receive (s, buf, 3, status);
+ scanner_receive (s, buf, 3, status);
/* buf += 3; */
}
@@ -1948,7 +1948,7 @@ command (Epson_Scanner * s, u_char * cmd, size_t cmd_size,
head = &(hdrunion->hdr);
buf = head->buf;
- receive (s, buf, count, status);
+ scanner_receive (s, buf, count, status);
if (SANE_STATUS_GOOD != *status)
return (EpsonHdrUnion) 0;
@@ -4958,20 +4958,20 @@ sane_start (SANE_Handle handle)
params[0] = ESC;
params[1] = s->hw->cmd->request_extended_status;
- send (s, params, 2, &status); /* send ESC f (request extended status) */
+ scanner_send (s, params, 2, &status); /* send ESC f (request extended status) */
if (SANE_STATUS_GOOD == status)
{
len = 4; /* receive header */
- receive (s, result, len, &status);
+ scanner_receive (s, result, len, &status);
if (SANE_STATUS_GOOD != status)
return status;
len = result[3] << 8 | result[2];
buf = alloca (len);
- receive (s, buf, len, &status); /* receive actual status data */
+ scanner_receive (s, buf, len, &status); /* receive actual status data */
if (buf[0] & 0x80)
{
@@ -4999,20 +4999,20 @@ sane_start (SANE_Handle handle)
params[0] = ESC;
params[1] = s->hw->cmd->request_condition;
- send (s, params, 2, &status); /* send request condition */
+ scanner_send (s, params, 2, &status); /* send request condition */
if (SANE_STATUS_GOOD != status)
return status;
len = 4;
- receive (s, result, len, &status);
+ scanner_receive (s, result, len, &status);
if (SANE_STATUS_GOOD != status)
return status;
len = result[3] << 8 | result[2];
buf = alloca (len);
- receive (s, buf, len, &status);
+ scanner_receive (s, buf, len, &status);
if (SANE_STATUS_GOOD != status)
return status;
@@ -5081,7 +5081,7 @@ sane_start (SANE_Handle handle)
params[0] = ESC;
params[1] = s->hw->cmd->start_scanning;
- send (s, params, 2, &status);
+ scanner_send (s, params, 2, &status);
if (SANE_STATUS_GOOD != status)
{
@@ -5120,7 +5120,7 @@ sane_auto_eject (Epson_Scanner * s)
params[0] = cmd;
- send (s, params, 1, &status);
+ scanner_send (s, params, 1, &status);
if (SANE_STATUS_GOOD != (status = expect_ack (s)))
{
@@ -5142,7 +5142,7 @@ read_data_block (Epson_Scanner * s, EpsonDataRec * result)
SANE_Status status;
u_char param[3];
- receive (s, result, s->block ? 6 : 4, &status);
+ scanner_receive (s, result, s->block ? 6 : 4, &status);
if (SANE_STATUS_GOOD != status)
return status;
@@ -5207,7 +5207,7 @@ read_data_block (Epson_Scanner * s, EpsonDataRec * result)
param[0] = ESC;
param[1] = s->hw->cmd->start_scanning;
- send (s, param, 2, &status);
+ scanner_send (s, param, 2, &status);
if (SANE_STATUS_GOOD != status)
{
@@ -5338,7 +5338,7 @@ START_READ:
break;
}
- receive (s, s->buf + index * s->params.pixels_per_line, buf_len,
+ scanner_receive (s, s->buf + index * s->params.pixels_per_line, buf_len,
&status);
if (SANE_STATUS_GOOD != status)
@@ -5347,7 +5347,7 @@ START_READ:
* send the ACK signal to the scanner in order to make
* it ready for the next data block.
*/
- send (s, S_ACK, 1, &status);
+ scanner_send (s, S_ACK, 1, &status);
/*
* ... and request the next data block
@@ -5378,7 +5378,7 @@ START_READ:
break;
}
- receive (s, s->buf + index * s->params.pixels_per_line, buf_len,
+ scanner_receive (s, s->buf + index * s->params.pixels_per_line, buf_len,
&status);
if (SANE_STATUS_GOOD != status)
@@ -5388,7 +5388,7 @@ START_READ:
return status;
}
- send (s, S_ACK, 1, &status);
+ scanner_send (s, S_ACK, 1, &status);
/*
* ... and the last data block
@@ -5420,7 +5420,7 @@ START_READ:
break;
}
- receive (s, s->buf + index * s->params.pixels_per_line, buf_len,
+ scanner_receive (s, s->buf + index * s->params.pixels_per_line, buf_len,
&status);
if (SANE_STATUS_GOOD != status)
@@ -5442,7 +5442,7 @@ START_READ:
reorder = SANE_TRUE;
}
- receive (s, s->buf, buf_len, &status);
+ scanner_receive (s, s->buf, buf_len, &status);
if (SANE_STATUS_GOOD != status)
{
@@ -5460,7 +5460,7 @@ START_READ:
{
if (s->canceling)
{
- send (s, S_CAN, 1, &status);
+ scanner_send (s, S_CAN, 1, &status);
expect_ack (s);
*length = 0;
@@ -5470,7 +5470,7 @@ START_READ:
return SANE_STATUS_CANCELLED;
}
else
- send (s, S_ACK, 1, &status);
+ scanner_send (s, S_ACK, 1, &status);
}
s->end = s->buf + buf_len;
@@ -6132,21 +6132,21 @@ get_identity2_information (SANE_Handle handle)
param[1] = s->hw->cmd->request_identity2;
param[2] = '\0';
- send (s, param, 2, &status);
+ scanner_send (s, param, 2, &status);
if (SANE_STATUS_GOOD != status)
return status;
len = 4; /* receive header */
- receive (s, result, len, &status);
+ scanner_receive (s, result, len, &status);
if (SANE_STATUS_GOOD != status)
return status;
len = result[3] << 8 | result[2];
buf = alloca (len);
- receive (s, buf, len, &status); /* receive actual status data */
+ scanner_receive (s, buf, len, &status); /* receive actual status data */
/* the first two bytes of the buffer contain the optical resolution */
s->hw->optical_res = buf[1] << 8 | buf[0];
@@ -6234,21 +6234,21 @@ request_focus_position (SANE_Handle handle, u_char * position)
param[1] = s->hw->cmd->request_focus_position;
param[2] = '\0';
- send (s, param, 2, &status);
+ scanner_send (s, param, 2, &status);
if (SANE_STATUS_GOOD != status)
return status;
len = 4; /* receive header */
- receive (s, result, len, &status);
+ scanner_receive (s, result, len, &status);
if (SANE_STATUS_GOOD != status)
return status;
len = result[3] << 8 | result[2];
buf = alloca (len);
- receive (s, buf, len, &status); /* receive actual status data */
+ scanner_receive (s, buf, len, &status); /* receive actual status data */
*position = buf[1];
DBG (1, "Focus position = 0x%x\n", buf[1]);
@@ -6287,7 +6287,7 @@ request_push_button_status (SANE_Handle handle, SANE_Bool * theButtonStatus)
param[1] = s->hw->cmd->request_push_button_status;
param[2] = '\0';
- send (s, param, 2, &status);
+ scanner_send (s, param, 2, &status);
if (SANE_STATUS_GOOD != status)
{
@@ -6297,14 +6297,14 @@ request_push_button_status (SANE_Handle handle, SANE_Bool * theButtonStatus)
len = 4; /* receive header */
- receive (s, result, len, &status);
+ scanner_receive (s, result, len, &status);
if (SANE_STATUS_GOOD != status)
return status;
len = result[3] << 8 | result[2]; /* this should be 1 for scanners with one button */
buf = alloca (len);
- receive (s, buf, len, &status); /* receive actual status data */
+ scanner_receive (s, buf, len, &status); /* receive actual status data */
DBG (1, "Push button status = %d\n", buf[0] & 0x01);
*theButtonStatus = ((buf[0] & 0x01) != 0);
diff --git a/backend/epson2-ops.c b/backend/epson2-ops.c
index faf0ffa..61930f6 100644
--- a/backend/epson2-ops.c
+++ b/backend/epson2-ops.c
@@ -1774,10 +1774,16 @@ e2_ext_read(struct Epson_Scanner *s)
return status;
}
- if (e2_dev_model(dev, "GT-8200") || e2_dev_model(dev, "Perfection1650")) {
- /* See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=597922#127 */
- s->buf[buf_len] &= 0xc0;
- }
+ /* Some scanners wrongly set FSG_STATUS_CANCEL_REQ. Mask it out.
+ * https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=597922#127
+ * https://gitlab.com/sane-project/backends/-/issues/716
+ */
+ if (e2_dev_model(dev, "GT-8200") || e2_dev_model(dev, "Perfection1650") ||
+ e2_dev_model(dev, "GT-10000") || e2_dev_model(dev, "ES-6000") ||
+ e2_dev_model(dev, "Perfection610") || e2_dev_model(dev, "GT-6600") ||
+ e2_dev_model(dev, "Perfection1200") || e2_dev_model(dev, "GT-7600") ||
+ e2_dev_model(dev, "Expression1600") || e2_dev_model(dev, "ES-2000"))
+ s->buf[buf_len] &= FSG_STATUS_FER | FSG_STATUS_NOT_READY;
if (s->buf[buf_len] & FSG_STATUS_CANCEL_REQ) {
DBG(0, "%s: cancel request received\n", __func__);
diff --git a/backend/escl/escl.c b/backend/escl/escl.c
index 77b753f..6bd3429 100644
--- a/backend/escl/escl.c
+++ b/backend/escl/escl.c
@@ -61,25 +61,6 @@ static const SANE_Device **devlist = NULL;
static ESCL_Device *list_devices_primary = NULL;
static int num_devices = 0;
-#ifdef CURL_SSLVERSION_MAX_DEFAULT
-static int proto_tls[] = {
- CURL_SSLVERSION_MAX_DEFAULT,
- #ifdef CURL_SSLVERSION_MAX_TLSv1_3
- CURL_SSLVERSION_MAX_TLSv1_3,
- #endif
- #ifdef CURL_SSLVERSION_MAX_TLSv1_2
- CURL_SSLVERSION_MAX_TLSv1_2,
- #endif
- #ifdef CURL_SSLVERSION_MAX_TLSv1_1
- CURL_SSLVERSION_MAX_TLSv1_1,
- #endif
- #ifdef CURL_SSLVERSION_MAX_TLSv1_0
- CURL_SSLVERSION_MAX_TLSv1_0,
- #endif
- -1
-};
-#endif
-
typedef struct Handled {
struct Handled *next;
@@ -120,17 +101,15 @@ escl_free_device(ESCL_Device *current)
}
-#ifdef CURL_SSLVERSION_MAX_DEFAULT
static int
-escl_tls_protocol_supported(char *url, int proto)
+escl_tls_protocol_supported(char *url)
{
CURLcode res = CURLE_UNSUPPORTED_PROTOCOL;
CURL *curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, url);
- /* ask libcurl to use TLS version 1.0 or later */
- curl_easy_setopt(curl, CURLOPT_SSLVERSION, proto);
+ curl_easy_setopt(curl, CURLOPT_USE_SSL, (long)CURLUSESSL_TRY);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
@@ -145,33 +124,17 @@ escl_tls_protocol_supported(char *url, int proto)
static int
escl_is_tls(char * url, char *type)
{
- int tls_version = 0;
if(!strcmp(type, "_uscans._tcp") ||
!strcmp(type, "https"))
{
- while(proto_tls[tls_version] != -1)
- {
- if (escl_tls_protocol_supported(url, proto_tls[tls_version]) == CURLE_OK)
+ if (escl_tls_protocol_supported(url) == CURLE_OK)
{
- DBG(10, "curl tls compatible (%d)\n", proto_tls[tls_version]);
- break;
+ DBG(10, "curl tls compatible\n");
+ return 1;
}
- tls_version++;
- }
- if (proto_tls[tls_version] < 1)
- return 0;
}
- return proto_tls[tls_version];
-}
-#else
-static int
-escl_is_tls(char * url, char *type)
-{
- (void)url;
- (void)type;
return 0;
}
-#endif
void
escl_free_handler(escl_sane_t *handler)
@@ -416,7 +379,7 @@ convertFromESCLDev(ESCL_Device *cdev)
unix_path, cdev->https ? "s" : "", cdev->ip_address, cdev->port_nb);
sdev->name = tmp;
- DBG( 1, "Escl add device : %s\n", tmp);
+ DBG( 10, "Escl add device : %s\n", tmp);
sdev->vendor = get_vendor(cdev->model_name);
if (!sdev->vendor)
@@ -523,7 +486,7 @@ attach_one_config(SANEI_Config __sane_unused__ *config, const char *line,
line = sanei_config_get_string(line + 6, &name_str);
DBG (10, "New Escl_Device URL [%s].\n", (name_str ? name_str : "VIDE"));
if (!name_str || !*name_str) {
- DBG (1, "Escl_Device URL missing.\n");
+ DBG(10, "Escl_Device URL missing.\n");
return SANE_STATUS_INVAL;
}
if (*line) {
@@ -1163,19 +1126,19 @@ escl_parse_name(SANE_String_Const name, ESCL_Device *device)
device->type = strdup("http");
host = name + 7;
} else {
- DBG(1, "Unknown URL scheme in %s", name);
+ DBG(10, "Unknown URL scheme in %s", name);
return SANE_STATUS_INVAL;
}
port_str = strchr(host, ':');
if (port_str == NULL) {
- DBG(1, "Port missing from URL: %s", name);
+ DBG(10, "Port missing from URL: %s", name);
return SANE_STATUS_INVAL;
}
port_str++;
device->port_nb = atoi(port_str);
if (device->port_nb < 1 || device->port_nb > 65535) {
- DBG(1, "Invalid port number in URL: %s", name);
+ DBG(10, "Invalid port number in URL: %s", name);
return SANE_STATUS_INVAL;
}
@@ -1201,7 +1164,7 @@ _get_hack(SANE_String_Const name, ESCL_Device *device)
fp = sanei_config_open (ESCL_CONFIG_FILE);
if (!fp)
{
- DBG (2, "_get_hack: couldn't access %s\n", ESCL_CONFIG_FILE);
+ DBG(4, "_get_hack: couldn't access %s\n", ESCL_CONFIG_FILE);
DBG (3, "_get_hack: exit\n");
}
@@ -1236,7 +1199,7 @@ _get_blacklist_pdf(void)
fp = sanei_config_open (ESCL_CONFIG_FILE);
if (!fp)
{
- DBG (2, "_get_blacklit: couldn't access %s\n", ESCL_CONFIG_FILE);
+ DBG(4, "_get_blacklit: couldn't access %s\n", ESCL_CONFIG_FILE);
DBG (3, "_get_blacklist: exit\n");
}
@@ -1345,7 +1308,7 @@ sane_cancel(SANE_Handle h)
}
handler->scanner->work = SANE_FALSE;
handler->cancel = SANE_TRUE;
- escl_scanner(handler->device, handler->scanner->scanJob, handler->result);
+ escl_scanner(handler->device, handler->scanner->scanJob, handler->result, SANE_TRUE);
free(handler->result);
handler->result = NULL;
free(handler->scanner->scanJob);
@@ -1558,7 +1521,7 @@ sane_start(SANE_Handle h)
int bps = 0;
if (handler->device == NULL) {
- DBG(1, "Missing handler device.\n");
+ DBG(10, "Missing handler device.\n");
return (SANE_STATUS_INVAL);
}
handler->cancel = SANE_FALSE;
@@ -1566,6 +1529,7 @@ sane_start(SANE_Handle h)
handler->decompress_scan_data = SANE_FALSE;
handler->end_read = SANE_FALSE;
if (handler->scanner->work == SANE_FALSE) {
+ escl_reset_all_jobs(handler->device);
SANE_Status st = escl_status(handler->device,
handler->scanner->source,
NULL,
@@ -1887,24 +1851,23 @@ escl_curl_url(CURL *handle, const ESCL_Device *device, SANE_String_Const path)
(device->https ? "https" : "http"), device->ip_address,
device->port_nb, path);
- DBG( 1, "escl_curl_url: URL: %s\n", url );
+ DBG( 10, "escl_curl_url: URL: %s\n", url );
curl_easy_setopt(handle, CURLOPT_URL, url);
free(url);
- DBG( 1, "Before use hack\n");
+ DBG( 10, "Before use hack\n");
if (device->hack) {
- DBG( 1, "Use hack\n");
+ DBG( 10, "Use hack\n");
curl_easy_setopt(handle, CURLOPT_HTTPHEADER, device->hack);
}
- DBG( 1, "After use hack\n");
+ DBG( 10, "After use hack\n");
if (device->https) {
- DBG( 1, "Ignoring safety certificates, use https\n");
+ DBG( 10, "Ignoring safety certificates, use https\n");
+ curl_easy_setopt(handle, CURLOPT_USE_SSL, (long)CURLUSESSL_TRY);
curl_easy_setopt(handle, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(handle, CURLOPT_SSL_VERIFYHOST, 0L);
- if (device->tls > 0)
- curl_easy_setopt(handle, CURLOPT_SSLVERSION, device->tls);
}
if (device->unix_socket != NULL) {
- DBG( 1, "Using local socket %s\n", device->unix_socket );
+ DBG( 10, "Using local socket %s\n", device->unix_socket );
curl_easy_setopt(handle, CURLOPT_UNIX_SOCKET_PATH,
device->unix_socket);
}
diff --git a/backend/escl/escl.h b/backend/escl/escl.h
index b59a3ff..2dce59b 100644
--- a/backend/escl/escl.h
+++ b/backend/escl/escl.h
@@ -248,7 +248,11 @@ SANE_Status escl_scan(capabilities_t *scanner,
void escl_scanner(const ESCL_Device *device,
char *scanJob,
- char *result);
+ char *result,
+ SANE_Bool status);
+
+SANE_Status escl_reset_all_jobs(ESCL_Device *device);
+
typedef void CURL;
diff --git a/backend/escl/escl_capabilities.c b/backend/escl/escl_capabilities.c
index 950efaa..05b3fd2 100644
--- a/backend/escl/escl_capabilities.c
+++ b/backend/escl/escl_capabilities.c
@@ -48,7 +48,7 @@ header_callback(void *str, size_t size, size_t nmemb, void *userp)
char *content = realloc(header->memory, header->size + realsize + 1);
if (content == NULL) {
- DBG( 1, "Not enough memory (realloc returned NULL)\n");
+ DBG( 10, "Not enough memory (realloc returned NULL)\n");
return (0);
}
header->memory = content;
@@ -201,10 +201,8 @@ find_valor_of_array_variables(xmlNode *node, capabilities_t *scanner, int type)
{
const char *name = (const char *)node->name;
if (strcmp(name, "ColorMode") == 0) {
+#ifndef HAVE_POPPLER_GLIB
const char *color = (SANE_String_Const)xmlNodeGetContent(node);
-#if HAVE_POPPLER_GLIB
- if (type == PLATEN || strcmp(color, "BlackAndWhite1"))
-#else
if (strcmp(color, "BlackAndWhite1"))
#endif
scanner->caps[type].ColorModes = char_to_array(scanner->caps[type].ColorModes, &scanner->caps[type].ColorModesSize, (SANE_String_Const)xmlNodeGetContent(node), 1);
@@ -235,14 +233,14 @@ find_valor_of_array_variables(xmlNode *node, capabilities_t *scanner, int type)
}
#endif
#if(defined HAVE_TIFFIO_H)
- else if(type == PLATEN && !strcmp(scanner->caps[type].DocumentFormats[i], "image/tiff"))
+ else if(!strcmp(scanner->caps[type].DocumentFormats[i], "image/tiff"))
{
have_tiff = SANE_TRUE;
scanner->caps[type].have_tiff = i;
}
#endif
#if HAVE_POPPLER_GLIB
- else if(type == PLATEN && !strcmp(scanner->caps[type].DocumentFormats[i], "application/pdf"))
+ else if(!strcmp(scanner->caps[type].DocumentFormats[i], "application/pdf"))
{
have_pdf = SANE_TRUE;
scanner->caps[type].have_pdf = i;
@@ -568,9 +566,9 @@ escl_capabilities(ESCL_Device *device, char *blacklist, SANE_Status *status)
curl_easy_setopt(curl_handle, CURLOPT_MAXREDIRS, 3L);
CURLcode res = curl_easy_perform(curl_handle);
if (res == CURLE_OK)
- DBG( 1, "Create NewJob : the scanner header responded : [%s]\n", header->memory);
+ DBG( 10, "Create NewJob : the scanner header responded : [%s]\n", header->memory);
if (res != CURLE_OK) {
- DBG( 1, "The scanner didn't respond: %s\n", curl_easy_strerror(res));
+ DBG( 10, "The scanner didn't respond: %s\n", curl_easy_strerror(res));
*status = SANE_STATUS_INVAL;
goto clean_data;
}
diff --git a/backend/escl/escl_crop.c b/backend/escl/escl_crop.c
index 59284ac..a7e0fa0 100644
--- a/backend/escl/escl_crop.c
+++ b/backend/escl/escl_crop.c
@@ -44,7 +44,7 @@ escl_crop_surface(capabilities_t *scanner,
int real_h = 0;
unsigned char *surface_crop = NULL;
- DBG( 1, "Escl Image Crop\n");
+ DBG( 10, "Escl Image Crop\n");
ratio = (double)w / (double)scanner->caps[scanner->source].width;
scanner->caps[scanner->source].width = w;
if (scanner->caps[scanner->source].pos_x < 0)
@@ -62,18 +62,18 @@ escl_crop_surface(capabilities_t *scanner,
y_off = (int)((double)scanner->caps[scanner->source].pos_y * ratio);
real_h = scanner->caps[scanner->source].height - y_off;
- DBG( 1, "Escl Image Crop [%dx%d|%dx%d]\n", scanner->caps[scanner->source].pos_x, scanner->caps[scanner->source].pos_y,
+ DBG( 10, "Escl Image Crop [%dx%d|%dx%d]\n", scanner->caps[scanner->source].pos_x, scanner->caps[scanner->source].pos_y,
scanner->caps[scanner->source].width, scanner->caps[scanner->source].height);
*width = real_w;
*height = real_h;
- DBG( 1, "Escl Image Crop [%dx%d]\n", *width, *height);
+ DBG( 10, "Escl Image Crop [%dx%d]\n", *width, *height);
if (x_off > 0 || real_w < scanner->caps[scanner->source].width ||
y_off > 0 || real_h < scanner->caps[scanner->source].height) {
surface_crop = (unsigned char *)malloc (sizeof (unsigned char) * real_w
* real_h * bps);
if(!surface_crop) {
- DBG( 1, "Escl Crop : Surface_crop Memory allocation problem\n");
+ DBG( 10, "Escl Crop : Surface_crop Memory allocation problem\n");
free(surface);
surface = NULL;
goto finish;
diff --git a/backend/escl/escl_devices.c b/backend/escl/escl_devices.c
index a2fdb80..05598ed 100644
--- a/backend/escl/escl_devices.c
+++ b/backend/escl/escl_devices.c
@@ -193,21 +193,21 @@ escl_devices(SANE_Status *status)
*status = SANE_STATUS_GOOD;
if (!(simple_poll = avahi_simple_poll_new())) {
- DBG( 1, "Failed to create simple poll object.\n");
+ DBG( 10, "Failed to create simple poll object.\n");
*status = SANE_STATUS_INVAL;
goto fail;
}
client = avahi_client_new(avahi_simple_poll_get(simple_poll), 0,
client_callback, NULL, &error);
if (!client) {
- DBG( 1, "Failed to create client: %s\n", avahi_strerror(error));
+ DBG( 10, "Failed to create client: %s\n", avahi_strerror(error));
*status = SANE_STATUS_INVAL;
goto fail;
}
if (!(sb = avahi_service_browser_new(client, AVAHI_IF_UNSPEC,
AVAHI_PROTO_UNSPEC, "_uscan._tcp",
NULL, 0, browse_callback, client))) {
- DBG( 1, "Failed to create service browser: %s\n",
+ DBG( 10, "Failed to create service browser: %s\n",
avahi_strerror(avahi_client_errno(client)));
*status = SANE_STATUS_INVAL;
goto fail;
@@ -216,7 +216,7 @@ escl_devices(SANE_Status *status)
AVAHI_PROTO_UNSPEC,
"_uscans._tcp", NULL, 0,
browse_callback, client))) {
- DBG( 1, "Failed to create service browser: %s\n",
+ DBG( 10, "Failed to create service browser: %s\n",
avahi_strerror(avahi_client_errno(client)));
*status = SANE_STATUS_INVAL;
goto fail;
diff --git a/backend/escl/escl_jpeg.c b/backend/escl/escl_jpeg.c
index 62c20c0..9008dae 100644
--- a/backend/escl/escl_jpeg.c
+++ b/backend/escl/escl_jpeg.c
@@ -179,7 +179,7 @@ get_JPEG_data(capabilities_t *scanner, int *width, int *height, int *bps)
if (surface != NULL)
free(surface);
fseek(scanner->tmp, start, SEEK_SET);
- DBG( 1, "Escl Jpeg : Error reading jpeg\n");
+ DBG( 10, "Escl Jpeg : Error reading jpeg\n");
if (scanner->tmp) {
fclose(scanner->tmp);
scanner->tmp = NULL;
@@ -241,7 +241,7 @@ get_JPEG_data(capabilities_t *scanner, int *width, int *height, int *bps)
surface = malloc(cinfo.output_width * cinfo.output_height * cinfo.output_components);
if (surface == NULL) {
jpeg_destroy_decompress(&cinfo);
- DBG( 1, "Escl Jpeg : Memory allocation problem\n");
+ DBG( 10, "Escl Jpeg : Memory allocation problem\n");
if (scanner->tmp) {
fclose(scanner->tmp);
scanner->tmp = NULL;
diff --git a/backend/escl/escl_mupdf.c b/backend/escl/escl_mupdf.c
index dd23482..f5b3b7e 100644
--- a/backend/escl/escl_mupdf.c
+++ b/backend/escl/escl_mupdf.c
@@ -137,7 +137,7 @@ get_PDF_data(capabilities_t *scanner, int *width, int *height, int *bps)
ctx = fz_new_context(NULL, NULL, FZ_STORE_UNLIMITED);
if (!ctx)
{
- DBG(1, "cannot create mupdf context\n");
+ DBG(10, "cannot create mupdf context\n");
status = SANE_STATUS_INVAL;
goto close_file;
}
@@ -147,7 +147,7 @@ get_PDF_data(capabilities_t *scanner, int *width, int *height, int *bps)
fz_register_document_handlers(ctx);
fz_catch(ctx)
{
- DBG(1, "cannot register document handlers: %s\n", fz_caught_message(ctx));
+ DBG(10, "cannot register document handlers: %s\n", fz_caught_message(ctx));
status = SANE_STATUS_INVAL;
goto drop_context;
}
@@ -157,7 +157,7 @@ get_PDF_data(capabilities_t *scanner, int *width, int *height, int *bps)
stream = fz_open_file_ptr_escl(ctx, scanner->tmp);
fz_catch(ctx)
{
- DBG(1, "cannot open stream: %s\n", fz_caught_message(ctx));
+ DBG(10, "cannot open stream: %s\n", fz_caught_message(ctx));
status = SANE_STATUS_INVAL;
goto drop_context;
}
@@ -167,7 +167,7 @@ get_PDF_data(capabilities_t *scanner, int *width, int *height, int *bps)
fz_seek(ctx, stream, 0, SEEK_SET);
fz_catch(ctx)
{
- DBG(1, "cannot seek stream: %s\n", fz_caught_message(ctx));
+ DBG(10, "cannot seek stream: %s\n", fz_caught_message(ctx));
status = SANE_STATUS_INVAL;
goto drop_stream;
}
@@ -177,7 +177,7 @@ get_PDF_data(capabilities_t *scanner, int *width, int *height, int *bps)
doc = fz_open_document_with_stream(ctx, "filename.pdf", stream);
fz_catch(ctx)
{
- DBG(1, "cannot open document: %s\n", fz_caught_message(ctx));
+ DBG(10, "cannot open document: %s\n", fz_caught_message(ctx));
status = SANE_STATUS_INVAL;
goto drop_stream;
}
@@ -187,14 +187,14 @@ get_PDF_data(capabilities_t *scanner, int *width, int *height, int *bps)
page_count = fz_count_pages(ctx, doc);
fz_catch(ctx)
{
- DBG(1, "cannot count number of pages: %s\n", fz_caught_message(ctx));
+ DBG(10, "cannot count number of pages: %s\n", fz_caught_message(ctx));
status = SANE_STATUS_INVAL;
goto drop_document;
}
if (page_number < 0 || page_number >= page_count)
{
- DBG(1, "page number out of range: %d (page count %d)\n", page_number + 1, page_count);
+ DBG(10, "page number out of range: %d (page count %d)\n", page_number + 1, page_count);
status = SANE_STATUS_INVAL;
goto drop_document;
}
@@ -209,7 +209,7 @@ get_PDF_data(capabilities_t *scanner, int *width, int *height, int *bps)
pix = fz_new_pixmap_from_page_number(ctx, doc, 0, &ctm, fz_device_rgb(ctx), 0);
fz_catch(ctx)
{
- DBG(1, "cannot render page: %s\n", fz_caught_message(ctx));
+ DBG(10, "cannot render page: %s\n", fz_caught_message(ctx));
status = SANE_STATUS_INVAL;
goto drop_document;
}
@@ -220,7 +220,7 @@ get_PDF_data(capabilities_t *scanner, int *width, int *height, int *bps)
// If necessary, trim the image.
surface = escl_crop_surface(scanner, surface, pix->w, pix->h, pix->n, width, height);
if (!surface) {
- DBG( 1, "Escl Pdf : Surface Memory allocation problem\n");
+ DBG( 10, "Escl Pdf : Surface Memory allocation problem\n");
status = SANE_STATUS_NO_MEM;
goto drop_pix;
}
diff --git a/backend/escl/escl_newjob.c b/backend/escl/escl_newjob.c
index cb48bd1..ed2f4b0 100644
--- a/backend/escl/escl_newjob.c
+++ b/backend/escl/escl_newjob.c
@@ -96,7 +96,7 @@ download_callback(void *str, size_t size, size_t nmemb, void *userp)
char *content = realloc(download->memory, download->size + realsize + 1);
if (content == NULL) {
- DBG( 1, "Not enough memory (realloc returned NULL)\n");
+ DBG( 10, "Not enough memory (realloc returned NULL)\n");
return (0);
}
download->memory = content;
@@ -144,19 +144,19 @@ escl_newjob (capabilities_t *scanner, const ESCL_Device *device, SANE_Status *st
*status = SANE_STATUS_GOOD;
if (device == NULL || scanner == NULL) {
*status = SANE_STATUS_NO_MEM;
- DBG( 1, "Create NewJob : the name or the scan are invalid.\n");
+ DBG( 10, "Create NewJob : the name or the scan are invalid.\n");
return (NULL);
}
upload = (struct downloading *)calloc(1, sizeof(struct downloading));
if (upload == NULL) {
*status = SANE_STATUS_NO_MEM;
- DBG( 1, "Create NewJob : memory allocation failure\n");
+ DBG( 10, "Create NewJob : memory allocation failure\n");
return (NULL);
}
download = (struct downloading *)calloc(1, sizeof(struct downloading));
if (download == NULL) {
free(upload);
- DBG( 1, "Create NewJob : memory allocation failure\n");
+ DBG( 10, "Create NewJob : memory allocation failure\n");
*status = SANE_STATUS_NO_MEM;
return (NULL);
}
@@ -168,38 +168,21 @@ escl_newjob (capabilities_t *scanner, const ESCL_Device *device, SANE_Status *st
int have_tiff = scanner->caps[scanner->source].have_tiff;
int have_pdf = scanner->caps[scanner->source].have_pdf;
- if ((scanner->source == PLATEN && have_pdf == -1) ||
- (scanner->source > PLATEN)) {
- if (have_tiff != -1) {
- scanner->caps[scanner->source].default_format =
- strdup(scanner->caps[scanner->source].DocumentFormats[have_tiff]);
- }
- else if (have_png != -1) {
- scanner->caps[scanner->source].default_format =
- strdup(scanner->caps[scanner->source].DocumentFormats[have_png]);
- }
- else if (have_jpeg != -1) {
- scanner->caps[scanner->source].default_format =
- strdup(scanner->caps[scanner->source].DocumentFormats[have_jpeg]);
- }
+ if (have_pdf != -1) {
+ scanner->caps[scanner->source].default_format =
+ strdup(scanner->caps[scanner->source].DocumentFormats[have_pdf]);
}
- else {
- if (have_pdf != -1) {
- scanner->caps[scanner->source].default_format =
- strdup(scanner->caps[scanner->source].DocumentFormats[have_pdf]);
- }
- else if (have_tiff != -1) {
- scanner->caps[scanner->source].default_format =
- strdup(scanner->caps[scanner->source].DocumentFormats[have_tiff]);
- }
- else if (have_png != -1) {
- scanner->caps[scanner->source].default_format =
- strdup(scanner->caps[scanner->source].DocumentFormats[have_png]);
- }
- else if (have_jpeg != -1) {
- scanner->caps[scanner->source].default_format =
- strdup(scanner->caps[scanner->source].DocumentFormats[have_jpeg]);
- }
+ else if (have_tiff != -1) {
+ scanner->caps[scanner->source].default_format =
+ strdup(scanner->caps[scanner->source].DocumentFormats[have_tiff]);
+ }
+ else if (have_png != -1) {
+ scanner->caps[scanner->source].default_format =
+ strdup(scanner->caps[scanner->source].DocumentFormats[have_png]);
+ }
+ else if (have_jpeg != -1) {
+ scanner->caps[scanner->source].default_format =
+ strdup(scanner->caps[scanner->source].DocumentFormats[have_jpeg]);
}
if (atof ((const char *)device->version) <= 2.0)
{
@@ -222,7 +205,7 @@ escl_newjob (capabilities_t *scanner, const ESCL_Device *device, SANE_Status *st
" <scan:Duplex>%s</scan:Duplex>",
scanner->source == ADFDUPLEX ? "true" : "false");
}
- DBG( 1, "Create NewJob : %s\n", scanner->caps[scanner->source].default_format);
+ DBG( 10, "Create NewJob : %s\n", scanner->caps[scanner->source].default_format);
if (scanner->caps[scanner->source].pos_x > scanner->caps[scanner->source].width)
off_x = (scanner->caps[scanner->source].pos_x > scanner->caps[scanner->source].width) / 2;
if (scanner->caps[scanner->source].pos_y > scanner->caps[scanner->source].height)
@@ -295,7 +278,7 @@ escl_newjob (capabilities_t *scanner, const ESCL_Device *device, SANE_Status *st
upload->memory = strdup(cap_data);
upload->size = strlen(cap_data);
wake_up_device:
- DBG( 1, "Create NewJob : %s\n", cap_data);
+ DBG( 10, "Create NewJob : %s\n", cap_data);
download->memory = malloc(1);
download->size = 0;
curl_handle = curl_easy_init();
@@ -310,12 +293,12 @@ wake_up_device:
curl_easy_setopt(curl_handle, CURLOPT_MAXREDIRS, 3L);
CURLcode res = curl_easy_perform(curl_handle);
if (res != CURLE_OK) {
- DBG( 1, "Create NewJob : the scanner responded incorrectly: %s\n", curl_easy_strerror(res));
+ DBG( 10, "Create NewJob : the scanner responded incorrectly: %s\n", curl_easy_strerror(res));
*status = SANE_STATUS_INVAL;
}
else {
if (download->memory != NULL) {
- char *tmp_location = strstr(download->memory, "Location:");
+ char *tmp_location = strcasestr(download->memory, "Location:");
if (tmp_location) {
temporary = strchr(tmp_location, '\r');
if (temporary == NULL)
@@ -325,7 +308,7 @@ wake_up_device:
location = strrchr(tmp_location,'/');
if (location) {
result = strdup(location);
- DBG( 1, "Create NewJob : %s\n", result);
+ DBG( 10, "Create NewJob : %s\n", result);
*temporary = '\n';
*location = '\0';
location = strrchr(tmp_location,'/');
@@ -333,7 +316,7 @@ wake_up_device:
if (location) {
location++;
scanner->scanJob = strdup(location);
- DBG( 1, "Full location header [%s]\n", scanner->scanJob);
+ DBG( 10, "Full location header [%s]\n", scanner->scanJob);
}
else
scanner->scanJob = strdup("ScanJobs");
@@ -341,14 +324,14 @@ wake_up_device:
}
}
if (result == NULL) {
- DBG( 1, "Error : Create NewJob, no location: %s\n", download->memory);
+ DBG( 10, "Error : Create NewJob, no location: %s\n", download->memory);
*status = SANE_STATUS_INVAL;
}
free(download->memory);
download->memory = NULL;
}
else {
- DBG( 1, "Create NewJob : The creation of the failed job: %s\n", download->memory);
+ DBG( 10, "Create NewJob : The creation of the failed job: %s\n", download->memory);
// If "409 Conflict" appear it means that there is no paper in feeder
if (strstr(download->memory, "409 Conflict") != NULL)
*status = SANE_STATUS_NO_DOCS;
@@ -363,7 +346,7 @@ wake_up_device:
}
else {
*status = SANE_STATUS_NO_MEM;
- DBG( 1, "Create NewJob : The creation of the failed job\n");
+ DBG( 10, "Create NewJob : The creation of the failed job\n");
return (NULL);
}
}
diff --git a/backend/escl/escl_pdf.c b/backend/escl/escl_pdf.c
index 8277e1d..0bfa3b3 100644
--- a/backend/escl/escl_pdf.c
+++ b/backend/escl/escl_pdf.c
@@ -121,21 +121,21 @@ get_PDF_data(capabilities_t *scanner, int *width, int *height, int *bps)
file = g_mapped_file_new_from_fd (fileno (scanner->tmp), 0, NULL);
if (!file) {
- DBG(1, "Error : g_mapped_file_new_from_fd");
+ DBG(10, "Error : g_mapped_file_new_from_fd");
status = SANE_STATUS_INVAL;
goto close_file;
}
bytes = g_mapped_file_get_bytes (file);
if (!bytes) {
- DBG(1, "Error : g_mapped_file_get_bytes");
+ DBG(10, "Error : g_mapped_file_get_bytes");
status = SANE_STATUS_INVAL;
goto free_file;
}
doc = poppler_document_new_from_bytes (bytes, NULL, NULL);
if (!doc) {
- DBG(1, "Error : poppler_document_new_from_bytes");
+ DBG(10, "Error : poppler_document_new_from_bytes");
status = SANE_STATUS_INVAL;
goto free_bytes;
}
@@ -145,14 +145,14 @@ get_PDF_data(capabilities_t *scanner, int *width, int *height, int *bps)
data = (char*)set_file_in_buffer(scanner->tmp, &size);
if (!data) {
- DBG(1, "Error : set_file_in_buffer");
+ DBG(10, "Error : set_file_in_buffer");
status = SANE_STATUS_INVAL;
goto close_file;
}
doc = poppler_document_new_from_data (data, size, NULL, NULL);
if (!doc) {
- DBG(1, "Error : poppler_document_new_from_data");
+ DBG(10, "Error : poppler_document_new_from_data");
status = SANE_STATUS_INVAL;
goto free_data;
}
@@ -160,7 +160,7 @@ get_PDF_data(capabilities_t *scanner, int *width, int *height, int *bps)
page = poppler_document_get_page (doc, 0);
if (!page) {
- DBG(1, "Error : poppler_document_get_page");
+ DBG(10, "Error : poppler_document_get_page");
status = SANE_STATUS_INVAL;
goto free_doc;
}
@@ -172,14 +172,14 @@ get_PDF_data(capabilities_t *scanner, int *width, int *height, int *bps)
h = (int)ceil(dh);
cairo_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, w, h);
if (!cairo_surface) {
- DBG(1, "Error : cairo_image_surface_create");
+ DBG(10, "Error : cairo_image_surface_create");
status = SANE_STATUS_INVAL;
goto free_page;
}
cr = cairo_create (cairo_surface);
if (!cairo_surface) {
- DBG(1, "Error : cairo_create");
+ DBG(10, "Error : cairo_create");
status = SANE_STATUS_INVAL;
goto free_surface;
}
@@ -196,26 +196,26 @@ get_PDF_data(capabilities_t *scanner, int *width, int *height, int *bps)
int st = cairo_status(cr);
if (st)
{
- DBG(1, "%s", cairo_status_to_string (st));
+ DBG(10, "%s", cairo_status_to_string (st));
status = SANE_STATUS_INVAL;
goto destroy_cr;
}
*bps = 3;
- DBG(1, "Escl Pdf : Image Size [%dx%d]\n", w, h);
+ DBG(10, "Escl Pdf : Image Size [%dx%d]\n", w, h);
surface = cairo_surface_to_pixels (cairo_surface, *bps);
if (!surface) {
status = SANE_STATUS_NO_MEM;
- DBG(1, "Escl Pdf : Surface Memory allocation problem");
+ DBG(10, "Escl Pdf : Surface Memory allocation problem");
goto destroy_cr;
}
// If necessary, trim the image.
surface = escl_crop_surface(scanner, surface, w, h, *bps, width, height);
if (!surface) {
- DBG(1, "Escl Pdf Crop: Surface Memory allocation problem");
+ DBG(10, "Escl Pdf Crop: Surface Memory allocation problem");
status = SANE_STATUS_NO_MEM;
}
diff --git a/backend/escl/escl_png.c b/backend/escl/escl_png.c
index 294ec00..fc8d02d 100644
--- a/backend/escl/escl_png.c
+++ b/backend/escl/escl_png.c
@@ -64,7 +64,7 @@ get_PNG_data(capabilities_t *scanner, int *width, int *height, int *bps)
// check for valid magic number
if (!png_check_sig (magic, sizeof (magic)))
{
- DBG( 1, "Escl Png : PNG error is not a valid PNG image!\n");
+ DBG( 10, "Escl Png : PNG error is not a valid PNG image!\n");
status = SANE_STATUS_INVAL;
goto close_file;
}
@@ -73,7 +73,7 @@ get_PNG_data(capabilities_t *scanner, int *width, int *height, int *bps)
(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!png_ptr)
{
- DBG( 1, "Escl Png : PNG error create a png read struct\n");
+ DBG( 10, "Escl Png : PNG error create a png read struct\n");
status = SANE_STATUS_INVAL;
goto close_file;
}
@@ -81,7 +81,7 @@ get_PNG_data(capabilities_t *scanner, int *width, int *height, int *bps)
png_infop info_ptr = png_create_info_struct (png_ptr);
if (!info_ptr)
{
- DBG( 1, "Escl Png : PNG error create a png info struct\n");
+ DBG( 10, "Escl Png : PNG error create a png info struct\n");
png_destroy_read_struct (&png_ptr, NULL, NULL);
status = SANE_STATUS_INVAL;
goto close_file;
@@ -93,7 +93,7 @@ get_PNG_data(capabilities_t *scanner, int *width, int *height, int *bps)
png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
if (surface)
free (surface);
- DBG( 1, "Escl Png : PNG read error.\n");
+ DBG( 10, "Escl Png : PNG read error.\n");
status = SANE_STATUS_INVAL;
goto close_file;
}
@@ -115,7 +115,7 @@ get_PNG_data(capabilities_t *scanner, int *width, int *height, int *bps)
png_set_palette_to_rgb (png_ptr);
else if (color_type != PNG_COLOR_TYPE_RGB && color_type != PNG_COLOR_TYPE_RGB_ALPHA)
{
- DBG(1, "PNG format not supported.\n");
+ DBG(10, "PNG format not supported.\n");
status = SANE_STATUS_NO_MEM;
goto close_file;
}
@@ -145,7 +145,7 @@ get_PNG_data(capabilities_t *scanner, int *width, int *height, int *bps)
surface = (unsigned char *)malloc (sizeof (unsigned char) * w
* h * components);
if (!surface) {
- DBG( 1, "Escl Png : texels Memory allocation problem\n");
+ DBG( 10, "Escl Png : texels Memory allocation problem\n");
status = SANE_STATUS_NO_MEM;
goto close_file;
}
@@ -153,7 +153,7 @@ get_PNG_data(capabilities_t *scanner, int *width, int *height, int *bps)
// setup a pointer array. Each one points at the begening of a row.
row_pointers = (png_bytep *)malloc (sizeof (png_bytep) * h);
if (!row_pointers) {
- DBG( 1, "Escl Png : row_pointers Memory allocation problem\n");
+ DBG( 10, "Escl Png : row_pointers Memory allocation problem\n");
free(surface);
status = SANE_STATUS_NO_MEM;
goto close_file;
@@ -169,7 +169,7 @@ get_PNG_data(capabilities_t *scanner, int *width, int *height, int *bps)
// If necessary, trim the image.
surface = escl_crop_surface(scanner, surface, w, h, components, width, height);
if (!surface) {
- DBG( 1, "Escl Png : Surface Memory allocation problem\n");
+ DBG( 10, "Escl Png : Surface Memory allocation problem\n");
status = SANE_STATUS_NO_MEM;
goto close_file;
}
diff --git a/backend/escl/escl_reset.c b/backend/escl/escl_reset.c
index 95e3f2d..ad3080b 100644
--- a/backend/escl/escl_reset.c
+++ b/backend/escl/escl_reset.c
@@ -44,7 +44,32 @@ write_callback(void __sane_unused__*str,
* This function is called in the 'sane_cancel' function.
*/
void
-escl_scanner(const ESCL_Device *device, char *scanJob, char *result)
+escl_delete(const ESCL_Device *device, char *uri)
+{
+ CURL *curl_handle = NULL;
+ long answer = 0;
+
+ if (uri == NULL)
+ return;
+ curl_handle = curl_easy_init();
+ if (curl_handle != NULL) {
+ escl_curl_url(curl_handle, device, uri);
+ curl_easy_setopt(curl_handle, CURLOPT_CUSTOMREQUEST, "DELETE");
+ if (curl_easy_perform(curl_handle) == CURLE_OK) {
+ curl_easy_getinfo(curl_handle, CURLINFO_RESPONSE_CODE, &answer);
+ return;
+ }
+ curl_easy_cleanup(curl_handle);
+ }
+}
+
+/**
+ * \fn void escl_scanner(const ESCL_Device *device, char *result)
+ * \brief Function that resets the scanner after each scan, using curl.
+ * This function is called in the 'sane_cancel' function.
+ */
+void
+escl_scanner(const ESCL_Device *device, char *scanJob, char *result, SANE_Bool status)
{
CURL *curl_handle = NULL;
const char *scan_jobs = "/eSCL/";
@@ -70,10 +95,15 @@ CURL_CALL:
if (i >= 15) return;
}
curl_easy_cleanup(curl_handle);
- if (SANE_STATUS_GOOD != escl_status(device,
- PLATEN,
- NULL,
- NULL))
- goto CURL_CALL;
+ char* end = strrchr(scan_cmd, '/');
+ *end = 0;
+ escl_delete(device, scan_cmd);
+ if (status) {
+ if (SANE_STATUS_GOOD != escl_status(device,
+ PLATEN,
+ NULL,
+ NULL))
+ goto CURL_CALL;
+ }
}
}
diff --git a/backend/escl/escl_scan.c b/backend/escl/escl_scan.c
index 8af6bb2..b7f344d 100644
--- a/backend/escl/escl_scan.c
+++ b/backend/escl/escl_scan.c
@@ -83,7 +83,7 @@ escl_scan(capabilities_t *scanner, const ESCL_Device *device, char *scanJob, cha
curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, scanner);
CURLcode res = curl_easy_perform(curl_handle);
if (res != CURLE_OK) {
- DBG( 1, "Unable to scan: %s\n", curl_easy_strerror(res));
+ DBG( 10, "Unable to scan: %s\n", curl_easy_strerror(res));
scanner->real_read = 0;
fclose(scanner->tmp);
scanner->tmp = NULL;
diff --git a/backend/escl/escl_status.c b/backend/escl/escl_status.c
index 1f848a2..eec8041 100644
--- a/backend/escl/escl_status.c
+++ b/backend/escl/escl_status.c
@@ -29,6 +29,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <unistd.h>
#include <libxml/parser.h>
@@ -52,7 +53,7 @@ memory_callback_s(void *contents, size_t size, size_t nmemb, void *userp)
char *str = realloc(mem->memory, mem->size + realsize + 1);
if (str == NULL) {
- DBG(1, "not enough memory (realloc returned NULL)\n");
+ DBG(10, "not enough memory (realloc returned NULL)\n");
return (0);
}
mem->memory = str;
@@ -224,7 +225,7 @@ reload:
curl_easy_setopt(curl_handle, CURLOPT_MAXREDIRS, 3L);
CURLcode res = curl_easy_perform(curl_handle);
if (res != CURLE_OK) {
- DBG( 1, "The scanner didn't respond: %s\n", curl_easy_strerror(res));
+ DBG( 10, "The scanner didn't respond: %s\n", curl_easy_strerror(res));
status = SANE_STATUS_INVAL;
goto clean_data;
}
@@ -270,3 +271,135 @@ clean_data:
}
return (status);
}
+
+static void
+print_xml_job_finish(xmlNode *node,
+ SANE_Status *job)
+{
+ while (node) {
+ if (node->type == XML_ELEMENT_NODE) {
+ if (find_nodes_s(node)) {
+ if (strcmp((const char *)node->name, "JobState") == 0) {
+ const char *state = (const char *)xmlNodeGetContent(node);
+ if (!strcmp(state, "Canceled")) {
+ *job = SANE_STATUS_GOOD;
+ DBG(10, "jobId Completed SANE_STATUS_GOOD\n");
+ }
+ else if (!strcmp(state, "Aborted")) {
+ *job = SANE_STATUS_GOOD;
+ DBG(10, "jobId Completed SANE_STATUS_GOOD\n");
+ }
+ else if (!strcmp(state, "Completed")) {
+ *job = SANE_STATUS_GOOD;
+ DBG(10, "jobId Completed SANE_STATUS_GOOD\n");
+ }
+ }
+ }
+ }
+ print_xml_job_finish(node->children, job);
+ node = node->next;
+ }
+}
+
+static void
+print_xml_reset_all_jobs (xmlNode *node,
+ ESCL_Device *device)
+{
+ DBG(10, "print_xml_reset_all_jobs\n");
+ SANE_Status status = SANE_STATUS_DEVICE_BUSY;
+ while (node) {
+ if (node->type == XML_ELEMENT_NODE) {
+ if (find_nodes_s(node)) {
+ if (strcmp((const char *)node->name, "JobUri") == 0) {
+ DBG(10, "print_xml_reset_all_jobs: %s\n", node->name);
+ if (device != NULL) {
+ print_xml_job_finish (node, &status);
+ if (status == SANE_STATUS_DEVICE_BUSY) {
+ char *jobUri = (char *)xmlNodeGetContent(node);
+ char *job = strrchr((const char *)jobUri, '/');
+ char *scanj = NULL;
+ if (job != NULL) {
+ if (strstr(jobUri,"ScanJobs"))
+ scanj = strdup("ScanJobs");
+ else
+ scanj = strdup("ScanJob");
+ DBG(10, "print_xml_reset_all_jobs: %s/%s\n", scanj, job);
+ escl_scanner(device, scanj, job, SANE_FALSE);
+ free(scanj);
+ }
+ DBG(10, "print_xml_reset_all_jobs: sleep to finish the job\n");
+ }
+ }
+ }
+ }
+ }
+ print_xml_reset_all_jobs (node->children,
+ device);
+ node = node->next;
+ }
+}
+
+/**
+ * \fn SANE_Status escl_reset_all_jobs (ESCL_Device *device, , char *scanJob)
+ * \brief Function that forces the end of jobs, using curl.
+ * This function is called in the 'sane_start' function.
+ *
+ * \return status (if everything is OK, status = SANE_STATUS_GOOD, otherwise, SANE_STATUS_NO_MEM/SANE_STATUS_INVAL)
+ */
+SANE_Status
+escl_reset_all_jobs(ESCL_Device *device)
+{
+ CURL *curl_handle = NULL;
+ xmlDoc *data = NULL;
+ xmlNode *node = NULL;
+ struct idle *var = NULL;
+ const char *scanner_status = "/eSCL/ScannerStatus";
+ SANE_Status status = SANE_STATUS_DEVICE_BUSY;
+
+ DBG(10, "escl_reset_all_jobs\n");
+ if (device == NULL)
+ return (SANE_STATUS_NO_MEM);
+ DBG(10, "1 - escl_reset_all_jobs\n");
+ var = (struct idle*)calloc(1, sizeof(struct idle));
+ if (var == NULL)
+ return (SANE_STATUS_NO_MEM);
+ DBG(10, "2 - escl_reset_all_jobs\n");
+ var->memory = malloc(1);
+ var->size = 0;
+ curl_handle = curl_easy_init();
+
+ escl_curl_url(curl_handle, device, scanner_status);
+ curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, memory_callback_s);
+ curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)var);
+ curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1L);
+ curl_easy_setopt(curl_handle, CURLOPT_MAXREDIRS, 3L);
+ CURLcode res = curl_easy_perform(curl_handle);
+ if (res != CURLE_OK) {
+ DBG( 10, "The scanner didn't respond: %s\n", curl_easy_strerror(res));
+ status = SANE_STATUS_INVAL;
+ goto clean_data1;
+ }
+ DBG(10, "3 - escl_reset_all_jobs\n");
+ DBG( 10, "eSCL : Status : %s.\n", var->memory);
+ data = xmlReadMemory(var->memory, var->size, "file.xml", NULL, 0);
+ if (data == NULL) {
+ status = SANE_STATUS_NO_MEM;
+ goto clean_data1;
+ }
+ node = xmlDocGetRootElement(data);
+ if (node == NULL) {
+ status = SANE_STATUS_NO_MEM;
+ goto clean1;
+ }
+ print_xml_reset_all_jobs (node, device);
+ status = SANE_STATUS_GOOD;
+clean1:
+ xmlFreeDoc(data);
+clean_data1:
+ xmlCleanupParser();
+ xmlMemoryDump();
+ curl_easy_cleanup(curl_handle);
+ free(var->memory);
+ free(var);
+ return status;
+}
diff --git a/backend/escl/escl_tiff.c b/backend/escl/escl_tiff.c
index e17554e..6270ff4 100644
--- a/backend/escl/escl_tiff.c
+++ b/backend/escl/escl_tiff.c
@@ -65,7 +65,7 @@ get_TIFF_data(capabilities_t *scanner, int *width, int *height, int *bps)
lseek(fileno(scanner->tmp), 0, SEEK_SET);
tif = TIFFFdOpen(fileno(scanner->tmp), "temp", "r");
if (!tif) {
- DBG( 1, "Escl Tiff : Can not open, or not a TIFF file.\n");
+ DBG( 10, "Escl Tiff : Can not open, or not a TIFF file.\n");
status = SANE_STATUS_INVAL;
goto close_file;
}
@@ -76,14 +76,14 @@ get_TIFF_data(capabilities_t *scanner, int *width, int *height, int *bps)
surface = (unsigned char*) malloc(npixels * sizeof (uint32_t));
if (surface == NULL)
{
- DBG( 1, "Escl Tiff : raster Memory allocation problem.\n");
+ DBG( 10, "Escl Tiff : raster Memory allocation problem.\n");
status = SANE_STATUS_INVAL;
goto close_tiff;
}
if (!TIFFReadRGBAImage(tif, w, h, (uint32_t *)surface, 0))
{
- DBG( 1, "Escl Tiff : Problem reading image data.\n");
+ DBG( 10, "Escl Tiff : Problem reading image data.\n");
status = SANE_STATUS_INVAL;
free(surface);
goto close_tiff;
@@ -94,7 +94,7 @@ get_TIFF_data(capabilities_t *scanner, int *width, int *height, int *bps)
// If necessary, trim the image.
surface = escl_crop_surface(scanner, surface, w, h, components, width, height);
if (!surface) {
- DBG( 1, "Escl Tiff : Surface Memory allocation problem\n");
+ DBG( 10, "Escl Tiff : Surface Memory allocation problem\n");
status = SANE_STATUS_INVAL;
}
diff --git a/backend/genesys/genesys.cpp b/backend/genesys/genesys.cpp
index ab1367e..74ef74e 100644
--- a/backend/genesys/genesys.cpp
+++ b/backend/genesys/genesys.cpp
@@ -840,7 +840,8 @@ void scanner_move(Genesys_Device& dev, ScanMethod scan_method, unsigned steps, D
// FIXME: should porbably wait for some timeout
Status status;
- for (unsigned i = 0;; ++i) {
+// for (unsigned i = 0;; ++i) {
+ for(;;) {
status = scanner_read_status(dev);
if (status.is_feeding_finished || (
direction == Direction::BACKWARD && status.is_at_home))
diff --git a/backend/genesys/gl124.cpp b/backend/genesys/gl124.cpp
index af193a3..ef3cca0 100644
--- a/backend/genesys/gl124.cpp
+++ b/backend/genesys/gl124.cpp
@@ -83,8 +83,8 @@ gl124_init_registers (Genesys_Device * dev)
dev->reg.init_reg(0x05, 0x00);
if(dev->model->sensor_id == SensorId::CIS_CANON_LIDE_120) {
- dev->reg.init_reg(0x06, 0x50);
- dev->reg.init_reg(0x07, 0x00);
+ dev->reg.init_reg(0x06, 0x50);
+ dev->reg.init_reg(0x07, 0x00);
} else {
dev->reg.init_reg(0x03, 0x50 & ~REG_0x03_AVEENB);
dev->reg.init_reg(0x06, 0x50 | REG_0x06_GAIN4);
diff --git a/backend/genesys/gl124_registers.h b/backend/genesys/gl124_registers.h
index dfc25f6..2c08e1c 100644
--- a/backend/genesys/gl124_registers.h
+++ b/backend/genesys/gl124_registers.h
@@ -290,4 +290,4 @@ static constexpr RegAddr REG_TRUEB = 0x112;
} // namespace gl124
} // namespace genesys
-#endif // BACKEND_GENESYS_GL843_REGISTERS_H
+#endif // BACKEND_GENESYS_GL124_REGISTERS_H
diff --git a/backend/hp-option.c b/backend/hp-option.c
index 6aed680..99dad31 100644
--- a/backend/hp-option.c
+++ b/backend/hp-option.c
@@ -3809,7 +3809,7 @@ hp_optset_isEnabled (HpOptSet this, HpData data, const char *name,
SANE_Status
sanei_hp_optset_download (HpOptSet this, HpData data, HpScsi scsi)
{
- int i, errcount = 0;
+ int i; //, errcount = 0;
DBG(3, "Start downloading parameters to scanner\n");
@@ -3839,7 +3839,7 @@ sanei_hp_optset_download (HpOptSet this, HpData data, HpScsi scsi)
if ( sanei_hp_scl_errcheck (scsi) != SANE_STATUS_GOOD )
{
- errcount++;
+ //errcount++;
DBG(3, "Option %s generated scanner error\n",
this->options[i]->descriptor->name);
diff --git a/backend/hp-scl.c b/backend/hp-scl.c
index 37a01e8..8b6ada1 100644
--- a/backend/hp-scl.c
+++ b/backend/hp-scl.c
@@ -143,7 +143,7 @@ typedef struct
/* Initialize structure where we remember out open file descriptors */
void
-sanei_hp_init_openfd ()
+sanei_hp_init_openfd (void)
{int iCount;
memset (asHpOpenFd, 0, sizeof (asHpOpenFd));
diff --git a/backend/hp3900_config.c b/backend/hp3900_config.c
index c40920f..9f64d31 100644
--- a/backend/hp3900_config.c
+++ b/backend/hp3900_config.c
@@ -3813,7 +3813,7 @@ static SANE_Int cfg_timing_get(SANE_Int sensortype, SANE_Int tm, struct st_timin
/** SEC: Motor curves ---------- */
-static SANE_Int *bq5550_motor()
+static SANE_Int *bq5550_motor(void)
{
SANE_Int *rst = NULL;
SANE_Int steps[] =
@@ -3835,7 +3835,7 @@ static SANE_Int *bq5550_motor()
return rst;
}
-static SANE_Int *hp4370_motor()
+static SANE_Int *hp4370_motor(void)
{
SANE_Int *rst = NULL;
SANE_Int steps[] =
@@ -3936,7 +3936,7 @@ static SANE_Int *hp4370_motor()
return rst;
}
-static SANE_Int *hp3970_motor()
+static SANE_Int *hp3970_motor(void)
{
SANE_Int *rst = NULL;
SANE_Int steps[] =
@@ -4037,7 +4037,7 @@ static SANE_Int *hp3970_motor()
return rst;
}
-static SANE_Int *hp3800_motor()
+static SANE_Int *hp3800_motor(void)
{
SANE_Int *rst = NULL;
SANE_Int steps[] =
@@ -4182,7 +4182,7 @@ static SANE_Int *hp3800_motor()
return rst;
}
-static SANE_Int *cfg_motorcurve_get()
+static SANE_Int *cfg_motorcurve_get(void)
{
/* returns motor setting buffer for a device */
diff --git a/backend/hp3900_rts8822.c b/backend/hp3900_rts8822.c
index f74d586..5cdfafe 100644
--- a/backend/hp3900_rts8822.c
+++ b/backend/hp3900_rts8822.c
@@ -618,7 +618,7 @@ RTS_Free (struct st_device *dev)
}
static struct st_device *
-RTS_Alloc ()
+RTS_Alloc (void)
{
/* this function allocates space for device's variable */
@@ -6304,7 +6304,7 @@ Gamma_GetTables (struct st_device *dev, SANE_Byte * Gamma_buffer)
}
static void
-Gamma_FreeTables ()
+Gamma_FreeTables (void)
{
SANE_Int c;
@@ -11319,7 +11319,7 @@ Head_Relocate (struct st_device *dev, SANE_Int speed, SANE_Int direction,
}
static SANE_Int
-Calib_CreateFixedBuffers ()
+Calib_CreateFixedBuffers (void)
{
SANE_Byte channel;
SANE_Int ret;
@@ -14002,7 +14002,7 @@ Free_Constrains (struct st_device *dev)
}
static void
-RTS_DebugInit ()
+RTS_DebugInit (void)
{
/* Default values */
RTS_Debug->dev_model = HP3970;
diff --git a/backend/hp3900_sane.c b/backend/hp3900_sane.c
index 5face5e..daf04f1 100644
--- a/backend/hp3900_sane.c
+++ b/backend/hp3900_sane.c
@@ -1752,7 +1752,7 @@ sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize)
SANE_Char line[PATH_MAX];
SANE_Char *str = NULL;
SANE_String_Const proper_str;
- SANE_Int nline = 0;
+ //SANE_Int nline = 0;
/* Initialize debug */
DBG_INIT ();
@@ -1771,7 +1771,7 @@ sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize)
{
while (sanei_config_read (line, sizeof (line), conf_fp))
{
- nline++;
+ //nline++;
if (str)
free (str);
diff --git a/backend/hp5400_internal.c b/backend/hp5400_internal.c
index 95866c4..e78e9e5 100644
--- a/backend/hp5400_internal.c
+++ b/backend/hp5400_internal.c
@@ -109,7 +109,7 @@ static TScannerModel Model_HP54xx =
HP5400_SANE_STATIC
int
-InitHp5400_internal() {
+InitHp5400_internal(void) {
MatchVersions = malloc( sizeof(versionString) * numVersions );
strcpy( MatchVersions[0].strVersion, "SilitekIBlizd C3 ScannerV0.84");
@@ -121,7 +121,7 @@ InitHp5400_internal() {
HP5400_SANE_STATIC
int
-FreeHp5400_internal() {
+FreeHp5400_internal(void) {
free(MatchVersions);
MatchVersions = NULL;
diff --git a/backend/hp5590.c b/backend/hp5590.c
index 78c9313..56acfb1 100644
--- a/backend/hp5590.c
+++ b/backend/hp5590.c
@@ -2154,6 +2154,24 @@ sane_read_internal (struct hp5590_scanner * scanner, SANE_Byte * data,
max_length,
scanner->transferred_image_size);
+ /*
+ * We will truncate down the buffer size to *under* what the
+ * internal USB reading buffer can supply. This will avoid page read issues
+ * at the end of the buffer.
+ *
+ * See: https://gitlab.com/sane-project/backends/-/issues/781
+ *
+ */
+ if (max_length > BULK_READ_PAGE_SIZE * MAX_READ_PAGES)
+ {
+ DBG (DBG_proc, "%s, truncating sane_read buffer from %u to %u\n",
+ __func__,
+ max_length,
+ BULK_READ_PAGE_SIZE * MAX_READ_PAGES);
+
+ max_length = BULK_READ_PAGE_SIZE * MAX_READ_PAGES;
+ }
+
SANE_Int length_limited = 0;
*length = max_length;
if ((unsigned long long) *length > scanner->transferred_image_size)
diff --git a/backend/hp5590_low.c b/backend/hp5590_low.c
index 2d19dcf..7038f43 100644
--- a/backend/hp5590_low.c
+++ b/backend/hp5590_low.c
@@ -99,9 +99,15 @@ struct usb_in_usb_ctrl_setup {
#define CORE_FLAG_NOT_READY 1 << 1
/* Bulk transfers are done in pages, below their respective sizes */
+/*
+ * Note that we limit the amount we can supply to sane_read() to avoid
+ * clashes with the size of the internal read buffer.
+ *
+ */
#define BULK_WRITE_PAGE_SIZE 0x0f000
#define BULK_READ_PAGE_SIZE 0x10000
-#define ALLOCATE_BULK_READ_PAGES 16 /* 16 * 65536 = 1Mb */
+#define ALLOCATE_BULK_READ_PAGES 17 /* 16 * 65536 = 1Mb */
+#define MAX_READ_PAGES 16 /* maximum that we will return to sane_read() */
/* Structure describing bulk read state, because bulk reads will be done in
* pages, but function caller uses its own buffer, whose size is certainly
diff --git a/backend/hpsj5s.c b/backend/hpsj5s.c
index 5ff5064..4c58dbf 100644
--- a/backend/hpsj5s.c
+++ b/backend/hpsj5s.c
@@ -648,7 +648,7 @@ DetectScanner (void)
}
static void
-StandByScanner ()
+StandByScanner (void)
{
WriteScannerRegister (0x74, 0x80);
WriteScannerRegister (0x75, 0x0C);
@@ -678,7 +678,7 @@ SwitchHardwareState (SANE_Byte mask, SANE_Byte invert_mask)
/*return value: 0 - no paper, 1 - paper loaded.*/
static int
-CheckPaperPresent ()
+CheckPaperPresent (void)
{
if ((CallFunctionWithRetVal (0xB2) & 0x10) == 0)
return 1; /*Ok - paper present. */
@@ -686,7 +686,7 @@ CheckPaperPresent ()
}
static int
-ReleasePaper ()
+ReleasePaper (void)
{
int i;
@@ -874,7 +874,7 @@ TurnOnPaperPulling (enumColorDepth enColor, SANE_Word wResolution)
}
static void
-TurnOffPaperPulling ()
+TurnOffPaperPulling (void)
{
CallFunctionWithParameter (0x91, 0);
}
@@ -884,7 +884,7 @@ TurnOffPaperPulling ()
While paper not loaded this is base "white point".
*/
static SANE_Byte
-GetCalibration ()
+GetCalibration (void)
{
int i;
int Result;
@@ -1041,7 +1041,7 @@ PaperFeed (SANE_Word wLinesToFeed)
/*For now we do no calibrate elements - just set maximum limits. FIX ME?*/
static void
-CalibrateScanElements ()
+CalibrateScanElements (void)
{
/*Those arrays will be used in future for correct calibration. */
/*Then we need to transfer UP brightness border, we use these registers */
@@ -1260,7 +1260,7 @@ CalibrateScanElements ()
/*Returns 0 in case of fail and 1 in success.*/
static int
-OutputCheck ()
+OutputCheck (void)
{
int i;
@@ -1277,7 +1277,7 @@ OutputCheck ()
}
static int
-InputCheck ()
+InputCheck (void)
{
int i;
SANE_Byte Buffer[256];
@@ -1298,7 +1298,7 @@ InputCheck ()
}
static int
-CallCheck ()
+CallCheck (void)
{
int i;
SANE_Byte Buffer[256];
@@ -1331,7 +1331,7 @@ CallCheck ()
}
static void
-LoadingPaletteToScanner ()
+LoadingPaletteToScanner (void)
{
/*For now we have statical gamma. */
SANE_Byte Gamma[256];
@@ -1394,7 +1394,7 @@ CallFunctionWithRetVal (SANE_Byte Function)
}
static SANE_Byte
-ReadDataByte ()
+ReadDataByte (void)
{
SANE_Byte Result;
diff --git a/backend/kodakaio.c b/backend/kodakaio.c
index 0241e2a..da3e234 100644
--- a/backend/kodakaio.c
+++ b/backend/kodakaio.c
@@ -1827,7 +1827,7 @@ k_init_parametersta(KodakAio_Scanner * s)
SANE_UNFIX(s->val[OPT_BR_X].w), SANE_UNFIX(s->val[OPT_BR_Y].w));
/*
- * The default color depth is stored in mode_params.depth:‭
+ * The default color depth is stored in mode_params.depth:
*/
if (mode_params[s->val[OPT_MODE].w].depth == 1)
s->params.depth = 1;
diff --git a/backend/lexmark_low.c b/backend/lexmark_low.c
index 246455f..a0237c7 100644
--- a/backend/lexmark_low.c
+++ b/backend/lexmark_low.c
@@ -2497,7 +2497,7 @@ sanei_lexmark_low_find_start_line (Lexmark_Device * dev)
*/
- int blackLineCount = 0;
+// int blackLineCount = 0;
int whiteLineCount = 0;
int blackByteCounter = 0;
unsigned char max_byte = 0;
@@ -2838,14 +2838,14 @@ sanei_lexmark_low_find_start_line (Lexmark_Device * dev)
if (blackByteCounter > 0)
{
/* This was a black line */
- blackLineCount++;
+// blackLineCount++;
whiteLineCount = 0;
}
else
{
/* This is a white line */
whiteLineCount++;
- blackLineCount = 0;
+// blackLineCount = 0;
}
} /* end for buffer */
diff --git a/backend/lexmark_x2600.c b/backend/lexmark_x2600.c
index 610064e..08a5e3b 100644
--- a/backend/lexmark_x2600.c
+++ b/backend/lexmark_x2600.c
@@ -624,7 +624,7 @@ attach_one (SANE_String_Const devname)
}
SANE_Status
-scan_devices(){
+scan_devices(void){
DBG (2, "scan_devices\n");
SANE_Char config_line[PATH_MAX];
FILE *fp;
diff --git a/backend/magicolor.c b/backend/magicolor.c
index 5278937..aac46be 100644
--- a/backend/magicolor.c
+++ b/backend/magicolor.c
@@ -105,16 +105,19 @@
static struct MagicolorCmd magicolor_cmd[] = {
{"mc1690mf", CMD, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x12, NET, 0x00, 0x01, 0x02, 0x03},
{"mc4690mf", CMD, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x12, NET, 0x00, 0x01, 0x02, 0x03},
+ {"es2323am", CMD, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x12, NET, 0x00, 0x01, 0x02, 0x03},
};
static SANE_Int magicolor_default_resolutions[] = {150, 300, 600};
static SANE_Int magicolor_default_depths[] = {1,8};
+static SANE_Int estudio_default_resolutions[] = {150, 200, 300, 400, 600};
+
static struct MagicolorCap magicolor_cap[] = {
/* KONICA MINOLTA magicolor 1690MF, USB ID 0x123b:2089 */
{
- 0x2089, "mc1690mf", "KONICA MINOLTA magicolor 1690MF", ".1.3.6.1.4.1.18334.1.1.1.1.1.23.1.1",
+ 0x2089, "mc1690mf", "magicolor 1690MF", ".1.3.6.1.4.1.18334.1.1.1.1.1.23.1.1",
-1, 0x85,
600, {150, 600, 0}, magicolor_default_resolutions, 3, /* 600 dpi max, 3 resolutions */
8, magicolor_default_depths, /* color depth 8 default, 1 and 8 possible */
@@ -126,7 +129,7 @@ static struct MagicolorCap magicolor_cap[] = {
/* KONICA MINOLTA magicolor 4690MF, USB ID 0x132b:2079 */
{
- 0x2079, "mc4690mf", "KONICA MINOLTA magicolor 4690MF",
+ 0x2079, "mc4690mf", "magicolor 4690MF",
"FIXME", /* FIXME: fill in the correct OID! */
0x03, 0x85,
600, {150, 600, 0}, magicolor_default_resolutions, 3, /* 600 dpi max, 3 resolutions */
@@ -137,13 +140,25 @@ static struct MagicolorCap magicolor_cap[] = {
{0, SANE_FIX(0x1390 * MM_PER_INCH / 600), 0}, {0, SANE_FIX(0x20dc * MM_PER_INCH / 600), 0},
},
+ /* TOSHIBA e-STUDIO2323AM, USB ID 0x08a6:8056 */
+ {
+ 0x8056, "es2323am", "e-STUDIO2323AM", ".1.3.6.1.4.1.1129.2.3.72.1",
+ 0x03, 0x85,
+ 600, {150, 600, 0}, estudio_default_resolutions, 5,
+ 8, magicolor_default_depths,
+ {-100, 100, 0},
+ {0, SANE_FIX(0x13f8 * MM_PER_INCH / 600), 0}, {0, SANE_FIX(0x1b9c * MM_PER_INCH / 600), 0},
+ SANE_TRUE, SANE_TRUE,
+ {0, SANE_FIX(0x1390 * MM_PER_INCH / 600), 0}, {0, SANE_FIX(0x20dc * MM_PER_INCH / 600), 0},
+ },
+
};
static int MC_SNMP_Timeout = 2500;
static int MC_Scan_Data_Timeout = 15000;
static int MC_Request_Timeout = 5000;
-
+#define ESTUDIO_DEVICE(s) ((s)->hw->cap->id == 0x8056)
/****************************************************************************
* General configuration parameter definitions
@@ -235,7 +250,7 @@ print_params(const SANE_Parameters params)
#define MAGICOLOR_SNMP_SYSOBJECT_OID ".1.3.6.1.2.1.1.2.0"
#define MAGICOLOR_SNMP_MAC_OID ".1.3.6.1.2.1.2.2.1.6.1"
#define MAGICOLOR_SNMP_DEVICE_TREE ".1.3.6.1.4.1.18334.1.1.1.1.1"
-
+#define ESTUDIO_SNMP_DEVICE_TREE ".1.3.6.1.4.1.1129.2.3.72.1"
/* We don't have a packet wrapper, which holds packet size etc., so we
don't have to use a *read_raw and a *_read function... */
@@ -342,8 +357,13 @@ sanei_magicolor_net_open(struct Magicolor_Scanner *s)
buf[1] = cmd->net_lock;
buf[2] = 0x00;
/* Copy the device's USB id to bytes 3-4: */
- buf[3] = s->hw->cap->id & 0xff;
- buf[4] = (s->hw->cap->id >> 8) & 0xff;
+ if (ESTUDIO_DEVICE(s)) {
+ buf[3] = (s->hw->cap->id >> 8) & 0xff;
+ buf[4] = s->hw->cap->id & 0xff;
+ } else {
+ buf[3] = s->hw->cap->id & 0xff;
+ buf[4] = (s->hw->cap->id >> 8) & 0xff;
+ }
DBG(32, "Proper welcome message received, locking the scanner...\n");
sanei_magicolor_net_write_raw(s, buf, 5, &status);
@@ -777,7 +797,6 @@ cmd_finish_scan (SANE_Handle handle)
return status;
}
memset (&returned[0], 0x00, 0x0b);
-
status = mc_txrx (s, buf, buflen, returned, 0x0b);
free (buf);
if (status != SANE_STATUS_GOOD)
@@ -995,7 +1014,20 @@ cmd_read_data (SANE_Handle handle, unsigned char *buf, size_t len)
/* Temporarily set the poll timeout to 10 seconds instead of 2,
* because a color scan needs >5 seconds to initialize. */
MC_Request_Timeout = MC_Scan_Data_Timeout;
- status = mc_txrx (s, txbuf, txbuflen, buf, len);
+
+ if (ESTUDIO_DEVICE(s)) {
+ /* e-STUDIO device returns 5-bytes of ack data here
+ * ignore it to not mess up image buffer */
+ unsigned char ack[5];
+
+ status = mc_txrx (s, txbuf, txbuflen, ack, sizeof(ack));
+ if (status == SANE_STATUS_GOOD) {
+ mc_recv (s, buf, len, &status);
+ }
+ } else {
+ status = mc_txrx (s, txbuf, txbuflen, buf, len);
+ }
+
MC_Request_Timeout = oldtimeout;
free (txbuf);
if (status != SANE_STATUS_GOOD)
@@ -1029,8 +1061,8 @@ mc_dev_init(Magicolor_Device *dev, const char *devname, int conntype)
dev->connection = conntype;
dev->sane.name = devname;
dev->sane.model = NULL;
- dev->sane.type = "flatbed scanner";
- dev->sane.vendor = "Magicolor";
+ dev->sane.type = "multi-function peripheral";
+ dev->sane.vendor = "Konica Minolta";
dev->cap = &magicolor_cap[MAGICOLOR_CAP_DEFAULT];
dev->cmd = &magicolor_cmd[MAGICOLOR_LEVEL_DEFAULT];
/* Change default level when using a network connection */
@@ -1042,8 +1074,10 @@ static SANE_Status
mc_dev_post_init(struct Magicolor_Device *dev)
{
DBG(5, "%s\n", __func__);
- NOT_USED (dev);
/* Correct device parameters if needed */
+ if (dev->cap->id == 0x8056)
+ dev->sane.vendor = "Toshiba";
+
return SANE_STATUS_GOOD;
}
@@ -1305,7 +1339,8 @@ mc_scan_finish(Magicolor_Scanner * s)
s->buf = s->end = s->ptr = NULL;
/* TODO: Any magicolor command for "scan finished"? */
- status = cmd_finish_scan (s);
+ if (!ESTUDIO_DEVICE(s))
+ status = cmd_finish_scan (s);
status = cmd_request_error(s);
if (status != SANE_STATUS_GOOD) {
@@ -1922,8 +1957,16 @@ mc_network_discovery_handle (struct snmp_pdu *pdu, snmp_discovery_data *magic)
vp->val.objid, value_len) == 0) {
DBG (5, "%s: Device appears to be a magicolor device (OID=%s)\n", __func__, device);
} else {
- DBG (5, "%s: Device is not a Magicolor device\n", __func__);
- return 0;
+ anOID_len = MAX_OID_LEN;
+ read_objid(ESTUDIO_SNMP_DEVICE_TREE, anOID, &anOID_len);
+
+ if (netsnmp_oid_is_subtree (anOID, anOID_len,
+ vp->val.objid, value_len) == 0) {
+ DBG (5, "%s: Device appears to be a estudio device (OID=%s)\n", __func__, device);
+ } else {
+ DBG (5, "%s: Device is not a e-STUDIO / Magicolor device\n", __func__);
+ return 0;
+ }
}
}
diff --git a/backend/mustek_scsi_pp.c b/backend/mustek_scsi_pp.c
index 98e3f20..860fca3 100644
--- a/backend/mustek_scsi_pp.c
+++ b/backend/mustek_scsi_pp.c
@@ -78,7 +78,7 @@ static int mustek_scsi_pp_timeout = 5000;
/* FIXME: use same method as mustek.c ? */
static int
-mustek_scsi_pp_get_time ()
+mustek_scsi_pp_get_time (void)
{
struct timeval tv;
int retval;
diff --git a/backend/mustek_usb2.c b/backend/mustek_usb2.c
index cb511b9..785bdb3 100644
--- a/backend/mustek_usb2.c
+++ b/backend/mustek_usb2.c
@@ -537,7 +537,7 @@ Return value:
return FALSE
***********************************************************************/
static SANE_Bool
-GetDeviceStatus ()
+GetDeviceStatus (void)
{
DBG (DBG_FUNC, "GetDeviceStatus: start\n");
return MustScanner_GetScannerState ();
@@ -576,7 +576,7 @@ Return value:
return FALSE
***********************************************************************/
static SANE_Bool
-CarriageHome ()
+CarriageHome (void)
{
DBG (DBG_FUNC, "CarriageHome: start\n");
return MustScanner_BackHome ();
@@ -914,7 +914,7 @@ Return value:
return FALSE
***********************************************************************/
static SANE_Bool
-StartScan ()
+StartScan (void)
{
DBG (DBG_FUNC, "StartScan: start\n");
if (ST_Reflective == g_ScanType)
@@ -1099,7 +1099,7 @@ Return value:
return FALSE
***********************************************************************/
static SANE_Bool
-StopScan ()
+StopScan (void)
{
SANE_Bool rt;
int i;
@@ -1159,7 +1159,7 @@ Return value:
return FALSE
***********************************************************************/
static SANE_Bool
-IsTAConnected ()
+IsTAConnected (void)
{
SANE_Bool hasTA;
diff --git a/backend/mustek_usb2_high.c b/backend/mustek_usb2_high.c
index e8b067f..cf0157b 100644
--- a/backend/mustek_usb2_high.c
+++ b/backend/mustek_usb2_high.c
@@ -199,7 +199,7 @@ Return value:
return FALSE
***********************************************************************/
static SANE_Bool
-MustScanner_Init ()
+MustScanner_Init (void)
{
DBG (DBG_FUNC, "MustScanner_Init: Call in\n");
@@ -260,7 +260,7 @@ Return value:
return FASLE
***********************************************************************/
static SANE_Bool
-MustScanner_GetScannerState ()
+MustScanner_GetScannerState (void)
{
if (SANE_STATUS_GOOD != Asic_Open (&g_chip, g_pDeviceFile))
@@ -343,7 +343,7 @@ Return value:
return FALSE
***********************************************************************/
static SANE_Bool
-MustScanner_BackHome ()
+MustScanner_BackHome (void)
{
DBG (DBG_FUNC, "MustScanner_BackHome: call in \n");
@@ -3081,7 +3081,7 @@ Return value:
the lines of scanned
***********************************************************************/
static unsigned int
-GetScannedLines ()
+GetScannedLines (void)
{
unsigned int dwScannedLines = 0;
@@ -3103,7 +3103,7 @@ Return value:
the lines which pass to superstratum
***********************************************************************/
static unsigned int
-GetReadyLines ()
+GetReadyLines (void)
{
unsigned int dwReadyLines = 0;
@@ -3143,7 +3143,7 @@ Return value:
none
***********************************************************************/
static void
-AddReadyLines ()
+AddReadyLines (void)
{
pthread_mutex_lock (&g_readyLinesMutex);
g_wtheReadyLines++;
diff --git a/backend/mustek_usb2_reflective.c b/backend/mustek_usb2_reflective.c
index ed37296..e0b0d10 100644
--- a/backend/mustek_usb2_reflective.c
+++ b/backend/mustek_usb2_reflective.c
@@ -72,7 +72,7 @@ Return value:
return FALSE
***********************************************************************/
static SANE_Bool
-Reflective_Reset ()
+Reflective_Reset (void)
{
DBG (DBG_FUNC, "Reflective_Reset: call in\n");
@@ -576,7 +576,7 @@ Return value:
return FALSE
***********************************************************************/
static SANE_Bool
-Reflective_AdjustAD ()
+Reflective_AdjustAD (void)
{
SANE_Byte * lpCalData;
unsigned short wCalWidth;
@@ -1293,7 +1293,7 @@ Return value:
return FALSE
***********************************************************************/
static SANE_Bool
-Reflective_StopScan ()
+Reflective_StopScan (void)
{
DBG (DBG_FUNC, "Reflective_StopScan: call in\n");
if (!g_bOpened)
@@ -1338,7 +1338,7 @@ Return value:
return FALSE
***********************************************************************/
static SANE_Bool
-Reflective_LineCalibration16Bits ()
+Reflective_LineCalibration16Bits (void)
{
SANE_Status status;
SANE_Byte * lpWhiteData;
@@ -1758,7 +1758,7 @@ Return value:
return FALSE
***********************************************************************/
static SANE_Bool
-Reflective_PrepareScan ()
+Reflective_PrepareScan (void)
{
g_wScanLinesPerBlock = g_dwBufferSize / g_BytesPerRow;
g_wMaxScanLines = g_dwImageBufferSize / g_BytesPerRow;
diff --git a/backend/mustek_usb2_transparent.c b/backend/mustek_usb2_transparent.c
index 1c4b91b..04b9eda 100644
--- a/backend/mustek_usb2_transparent.c
+++ b/backend/mustek_usb2_transparent.c
@@ -73,7 +73,7 @@ Return value:
return FALSE
***********************************************************************/
static SANE_Bool
-Transparent_Reset ()
+Transparent_Reset (void)
{
DBG (DBG_FUNC, "Transparent_Reset: call in\n");
@@ -502,7 +502,7 @@ Return value:
return FALSE
***********************************************************************/
static SANE_Bool
-Transparent_StopScan ()
+Transparent_StopScan (void)
{
DBG (DBG_FUNC, "Transparent_StopScan: call in\n");
@@ -613,7 +613,7 @@ Return value:
return FALSE
***********************************************************************/
static SANE_Bool
-Transparent_AdjustAD ()
+Transparent_AdjustAD (void)
{
SANE_Byte * lpCalData;
unsigned short wCalWidth;
@@ -1659,7 +1659,7 @@ Return value:
return FALSE
***********************************************************************/
static SANE_Bool
-Transparent_PrepareScan ()
+Transparent_PrepareScan (void)
{
DBG (DBG_FUNC, "Transparent_PrepareScan: call in\n");
diff --git a/backend/net.c b/backend/net.c
index 7b1ea05..bea22cc 100644
--- a/backend/net.c
+++ b/backend/net.c
@@ -313,7 +313,7 @@ add_device (const char *name, Net_Device ** ndp)
#endif /* NET_USES_AF_INDEP */
/* Calls getpwuid_r(). The return value must be freed by the caller. */
-char* get_current_username()
+static char* get_current_username(void)
{
long bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
if (bufsize == -1)
diff --git a/backend/pixma/pixma_common.h b/backend/pixma/pixma_common.h
index 5b393dc..68d10ff 100644
--- a/backend/pixma/pixma_common.h
+++ b/backend/pixma/pixma_common.h
@@ -70,7 +70,7 @@
#define PIXMA_STATUS_FAILED 0x1515
#define PIXMA_STATUS_BUSY 0x1414
-#define PIXMA_MAX_ID_LEN 30
+#define PIXMA_MAX_ID_LEN 40
/* These may have been defined elsewhere */
#ifndef MIN
diff --git a/backend/pixma/pixma_imageclass.c b/backend/pixma/pixma_imageclass.c
index 83b19bd..c750b20 100644
--- a/backend/pixma/pixma_imageclass.c
+++ b/backend/pixma/pixma_imageclass.c
@@ -953,6 +953,7 @@ const pixma_config_t pixma_iclass_devices[] = {
DEV ("Canon i-SENSYS MF4700 Series", "MF4700", MF4700_PID, 600, 0, 640, 1050, PIXMA_CAP_ADF),
DEV ("Canon i-SENSYS MF4800 Series", "MF4800", MF4800_PID, 600, 0, 640, 1050, PIXMA_CAP_ADF),
DEV ("Canon imageCLASS MF4570dw", "MF4570dw", MF4570_PID, 600, 0, 640, 877, 0),
+ DEV ("Canon imageClass MF4500w Series", "MF4500w", MF4570_PID, 600, 0, 640, 877, 0),
DEV ("Canon i-SENSYS MF8200C Series", "MF8200C", MF8200_PID, 600, 300, 640, 1050, PIXMA_CAP_ADF),
DEV ("Canon i-SENSYS MF8300 Series", "MF8300", MF8300_PID, 600, 0, 640, 1050, PIXMA_CAP_ADF),
DEV ("Canon imageCLASS D530", "D530", D530_PID, 600, 0, 640, 877, 0),
diff --git a/backend/pixma/pixma_io_sanei.c b/backend/pixma/pixma_io_sanei.c
index 394523e..756e0de 100644
--- a/backend/pixma/pixma_io_sanei.c
+++ b/backend/pixma/pixma_io_sanei.c
@@ -132,7 +132,7 @@ attach_bjnp (SANE_String_Const devname,
return SANE_STATUS_NO_MEM;
si->cfg = cfg;
- sprintf(si->serial, "%s_%s", cfg->model, serial);
+ snprintf(si->serial, sizeof(si->serial), "%s_%s", cfg->model, serial);
si -> interface = INT_BJNP;
si->next = first_scanner;
first_scanner = si;
@@ -188,7 +188,7 @@ u16tohex (uint16_t x, char *str)
static void
read_serial_number (scanner_info_t * si)
{
- uint8_t unicode[2 * (PIXMA_MAX_ID_LEN - 9) + 2];
+ uint8_t unicode[2 * (PIXMA_MAX_ID_LEN - 9) + 2]; // 9 = size of VID + PID + "_"
uint8_t ddesc[18];
int iSerialNumber;
SANE_Int usb;
diff --git a/backend/pixma/pixma_mp150.c b/backend/pixma/pixma_mp150.c
index 99024ca..b582c48 100644
--- a/backend/pixma/pixma_mp150.c
+++ b/backend/pixma/pixma_mp150.c
@@ -363,6 +363,18 @@
#define TS7700A_PID 0x1111
#define GX6500_PID 0x1148
+/* 2024 new device (untested) */
+#define TS3600_PID 0x1156
+#define TS3700_PID 0x1158
+#define E3600_PID 0x1157
+
+#define G4090_PID 0x114A
+#define G4080_PID 0x114B
+#define G3090_PID 0x114C
+#define G3080_PID 0x114D
+#define TS8800_PID 0x1159
+#define XK130_PID 0x115A
+
/* Generation 4 XML messages that encapsulates the Pixma protocol messages */
#define XML_START_1 \
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\
@@ -2017,5 +2029,17 @@ const pixma_config_t pixma_mp150_devices[] = {
DEVICE ("Canon PIXMA TS7700A series", "TS7700A", TS7700A_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
DEVICE ("Canon PIXMA GX6500 series", "GX6500", GX6500_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS | PIXMA_CAP_ADF),
+ DEVICE ("Canon PIXMA TS3600 Series", "TS3600", TS3600_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
+ DEVICE ("Canon PIXMA TS3700 Series", "TS3700", TS3700_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
+ DEVICE ("Canon PIXMA E3600 Series", "E3600", E3600_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS | PIXMA_CAP_ADF),
+
+ DEVICE ("Canon PIXMA G4090", "G4090", G4090_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS),
+ DEVICE ("Canon PIXMA G4080", "G4080", G4080_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS),
+ DEVICE ("Canon PIXMA G3090", "G3090", G3090_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS),
+ DEVICE ("Canon PIXMA G3080", "G3080", G3080_PID, 0, 600, 0, 0, 638, 877, PIXMA_CAP_CIS),
+ DEVICE ("Canon PIXMA TS8800 series", "TS8800", TS8800_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
+ DEVICE ("Canon PIXMA XK130 series", "XK130", XK130_PID, 0, 1200, 0, 0, 638, 877, PIXMA_CAP_CIS),
+
+
END_OF_DEVICE_LIST
};
diff --git a/backend/plustek-pp_io.c b/backend/plustek-pp_io.c
index 45ffe8b..d979c8b 100644
--- a/backend/plustek-pp_io.c
+++ b/backend/plustek-pp_io.c
@@ -422,7 +422,7 @@ static Bool ioP98OpenScanPath( pScanData ps )
{
Byte tmp;
ULong dw;
- ULong dwTime = 1;
+// ULong dwTime = 1; // Doesn't seem to be used. [RL]
if( 0 == ps->IO.bOpenCount ) {
@@ -457,7 +457,7 @@ static Bool ioP98OpenScanPath( pScanData ps )
ps->IO.bOpenCount = 0;
}
- dwTime++;
+// dwTime++; // Doesn't seem to be used. [RL]
}
DBG( DBG_IO, "ioP98OpenScanPath() failed!\n" );
return _FALSE;
diff --git a/backend/rts8891.c b/backend/rts8891.c
index 2732871..16aecca 100644
--- a/backend/rts8891.c
+++ b/backend/rts8891.c
@@ -83,6 +83,7 @@
#include <string.h>
#include <ctype.h>
#include <time.h>
+#include <math.h>
#include <sys/types.h>
#include <unistd.h>
@@ -109,12 +110,6 @@
#define MARGIN_LEVEL 128 /* white level for margin detection */
-/* width used for calibration */
-#define CALIBRATION_WIDTH 637
-
-/* data size for calibration: one RGB line*/
-#define CALIBRATION_SIZE CALIBRATION_WIDTH*3
-
/* #define FAST_INIT 1 */
#define BUILD 2401
@@ -233,6 +228,8 @@ static SANE_Status find_origin (struct Rts8891_Device *dev,
static SANE_Status find_margin (struct Rts8891_Device *dev);
static SANE_Status dark_calibration (struct Rts8891_Device *dev, int mode,
int light);
+static SANE_Status lamp_warm_up (struct Rts8891_Device *dev, int mode,
+ int light);
static SANE_Status gain_calibration (struct Rts8891_Device *dev, int mode,
int light);
static SANE_Status offset_calibration (struct Rts8891_Device *dev, int mode,
@@ -1051,6 +1048,8 @@ static char *sensor_name (int sensor)
return "SENSOR_TYPE_4400";
case SENSOR_TYPE_4400_BARE:
return "SENSOR_TYPE_4400_BARE";
+ case SENSOR_TYPE_UMAX:
+ return "SENSOR_TYPE_UMAX";
default:
return "BOGUS";
}
@@ -1136,7 +1135,7 @@ sane_start (SANE_Handle handle)
init_lamp (dev);
/* do warming up if needed: just detected or at sane_open() */
- if (dev->needs_warming == SANE_TRUE)
+ if (dev->needs_warming == SANE_TRUE && dev->sensor != SENSOR_TYPE_UMAX)
{
DBG (DBG_info, "sane_start: warming lamp ...\n");
#ifdef HAVE_SYS_TIME_H
@@ -1213,6 +1212,11 @@ sane_start (SANE_Handle handle)
"sane_start: sensor changed to type 'SENSOR_TYPE_4400'!\n");
dev->sensor = SENSOR_TYPE_4400;
break;
+ case SENSOR_TYPE_UMAX:
+ DBG (DBG_info,
+ "sane_start: sensor changed to type 'SENSOR_TYPE_XPA'!\n");
+ dev->sensor = SENSOR_TYPE_XPA;
+ break;
}
}
}
@@ -1226,6 +1230,7 @@ sane_start (SANE_Handle handle)
mode = 0x20;
break;
case SENSOR_TYPE_BARE:
+ case SENSOR_TYPE_UMAX:
light = 0x3b;
mode = 0x20;
break;
@@ -1272,6 +1277,21 @@ sane_start (SANE_Handle handle)
sanei_rts88xx_write_reg (dev->devnum, LAMP_BRIGHT_REG,
dev->regs + LAMP_BRIGHT_REG);
+ /* step 3a: lamp warm-up (UMAX-only) */
+ if (dev->sensor == SENSOR_TYPE_UMAX)
+ {
+ status = lamp_warm_up(dev, mode, light);
+ if (status != SANE_STATUS_GOOD)
+ {
+ if (dev->conf.allowsharing == SANE_TRUE)
+ {
+ sanei_usb_release_interface (dev->devnum, 0);
+ }
+ DBG (DBG_error, "sane_start: lamp warm-up failed!\n");
+ return status;
+ }
+ }
+
/* step 4: gain calibration */
status = gain_calibration (dev, mode, light);
if (status != SANE_STATUS_GOOD)
@@ -1771,8 +1791,11 @@ sane_read (SANE_Handle handle, SANE_Byte * buf,
return SANE_STATUS_EOF;
}
- dev->regs[LAMP_REG] = 0xad;
- sanei_rts88xx_write_reg (dev->devnum, LAMP_REG, &(dev->regs[LAMP_REG]));
+ if (dev->sensor != SENSOR_TYPE_UMAX)
+ {
+ dev->regs[LAMP_REG] = 0xad;
+ sanei_rts88xx_write_reg (dev->devnum, LAMP_REG, &(dev->regs[LAMP_REG]));
+ }
/* byte length for high dpi mode */
length = (session->params.bytes_per_line * 8) / session->params.depth;
@@ -1830,8 +1853,11 @@ sane_read (SANE_Handle handle, SANE_Byte * buf,
dev->current = dev->start;
}
- dev->regs[LAMP_REG] = 0x8d;
- sanei_rts88xx_write_reg (dev->devnum, LAMP_REG, &(dev->regs[LAMP_REG]));
+ if (dev->sensor != SENSOR_TYPE_UMAX)
+ {
+ dev->regs[LAMP_REG] = 0x8d;
+ sanei_rts88xx_write_reg (dev->devnum, LAMP_REG, &(dev->regs[LAMP_REG]));
+ }
/* it seems there is no gray or lineart hardware mode for the rts8891 */
if (session->params.format == SANE_FRAME_GRAY
@@ -2912,6 +2938,15 @@ average_area (int color, SANE_Byte * data, int width, int height,
return global;
}
+static void
+gamma_correction (unsigned char *data, int length, float gamma)
+{
+ int i;
+
+ for (i = 0; i < length; i++)
+ data[i] = 255 * pow(data[i] / 255.0, 1/gamma);
+}
+
/**
* Sets lamp brightness (hum, maybe some timing before light off)
@@ -2922,6 +2957,11 @@ set_lamp_brightness (struct Rts8891_Device *dev, int level)
SANE_Status status = SANE_STATUS_GOOD;
SANE_Byte reg;
+ if (dev->sensor == SENSOR_TYPE_UMAX)
+ {
+ return status;
+ }
+
reg = 0xA0 | (level & 0x0F);
sanei_rts88xx_write_reg (dev->devnum, LAMP_BRIGHT_REG, &reg);
switch (level)
@@ -2945,7 +2985,12 @@ set_lamp_brightness (struct Rts8891_Device *dev, int level)
sanei_rts88xx_get_status (dev->devnum, dev->regs);
DBG (DBG_io, "set_lamp_brightness: status=0x%02x 0x%02x\n", dev->regs[0x10],
dev->regs[0x11]);
- if (dev->sensor != SENSOR_TYPE_4400)
+ if (dev->sensor == SENSOR_TYPE_UMAX)
+ {
+ dev->regs[0x10] = 0x20;
+ dev->regs[0x11] = 0x3b;
+ }
+ else if (dev->sensor != SENSOR_TYPE_4400)
{
dev->regs[0x10] = 0x28;
dev->regs[0x11] = 0x3f;
@@ -2988,7 +3033,12 @@ init_lamp (struct Rts8891_Device *dev)
sanei_rts88xx_write_regs (dev->devnum, 0x14, dev->regs + 0x14, 2);
sanei_rts88xx_write_control (dev->devnum, 0x00);
sanei_rts88xx_write_control (dev->devnum, 0x00);
- if (dev->sensor != SENSOR_TYPE_4400 && dev->sensor != SENSOR_TYPE_4400_BARE)
+ if (dev->sensor == SENSOR_TYPE_UMAX)
+ {
+ sanei_rts88xx_set_status (dev->devnum, dev->regs, 0x20, 0x3b);
+ dev->regs[0x11] = 0x3b;
+ }
+ else if (dev->sensor != SENSOR_TYPE_4400 && dev->sensor != SENSOR_TYPE_4400_BARE)
{
sanei_rts88xx_set_status (dev->devnum, dev->regs, 0x28, 0x3f);
dev->regs[0x11] = 0x3f;
@@ -2998,11 +3048,14 @@ init_lamp (struct Rts8891_Device *dev)
sanei_rts88xx_set_status (dev->devnum, dev->regs, 0x10, 0x22);
dev->regs[0x11] = 0x22;
}
- reg = 0x8d;
- sanei_rts88xx_write_reg (dev->devnum, LAMP_REG, &reg);
- dev->regs[LAMP_REG] = 0xa2;
- dev->regs[LAMP_BRIGHT_REG] = 0xa0;
- rts8891_write_all (dev->devnum, dev->regs, dev->reg_count);
+ if (dev->sensor != SENSOR_TYPE_UMAX)
+ {
+ reg = 0x8d;
+ sanei_rts88xx_write_reg (dev->devnum, LAMP_REG, &reg);
+ dev->regs[LAMP_REG] = 0xa2;
+ dev->regs[LAMP_BRIGHT_REG] = 0xa0;
+ rts8891_write_all (dev->devnum, dev->regs, dev->reg_count);
+ }
return set_lamp_brightness (dev, 7);
}
@@ -3022,7 +3075,7 @@ find_origin (struct Rts8891_Device *dev, SANE_Bool * changed)
int startx = 300;
int width = 1200;
int x, y, sum, current;
- int starty = 18;
+ int starty = (dev->sensor == SENSOR_TYPE_UMAX) ? 42 : 18;
int height = 180;
int timing;
@@ -3152,6 +3205,38 @@ find_origin (struct Rts8891_Device *dev, SANE_Bool * changed)
dev->regs[0xd7] = 0x30; /* 0x10 */
dev->regs[0xda] = 0xa7; /* 0xa0 */
}
+ if (dev->sensor == SENSOR_TYPE_UMAX)
+ {
+ dev->regs[0x14] = 0xf0;
+ dev->regs[0x16] = 0x0f;
+ dev->regs[0x23] = 0x00;
+ dev->regs[0x35] = 0x0e;
+ dev->regs[0x36] = 0x2c;
+ dev->regs[0x3a] = 0x0e;
+ dev->regs[0xc0] = 0x87;
+ dev->regs[0xc1] = 0x07;
+ dev->regs[0xc2] = 0xf8;
+ dev->regs[0xc3] = 0x78;
+ dev->regs[0xc4] = 0xf8;
+ dev->regs[0xc5] = 0x07;
+ dev->regs[0xc6] = 0x87;
+ dev->regs[0xc7] = 0x07;
+ dev->regs[0xc8] = 0xf8;
+ dev->regs[0xc9] = 0xfc;
+ dev->regs[0xca] = 0x0f;
+ dev->regs[0xcd] = 0x00;
+ dev->regs[0xce] = 0x80;
+ dev->regs[0xcf] = 0xe2;
+ dev->regs[0xd0] = 0xe4;
+ dev->regs[0xd7] = 0x10;
+ dev->regs[0xd8] = 0xa6;
+ dev->regs[0xd9] = 0x2d;
+ dev->regs[0xda] = 0x00;
+ dev->regs[0xe2] = 0x03;
+ SET_DOUBLE (dev->regs, EXPOSURE_REG, 2061);
+ /* dev->regs[0xe5] = 0x0d;
+ dev->regs[0xe6] = 0x08; 080d=2061 */
+ }
SET_DOUBLE (dev->regs, TIMING_REG, timing);
SET_DOUBLE (dev->regs, TIMING1_REG, timing+1);
SET_DOUBLE (dev->regs, TIMING2_REG, timing+2);
@@ -3180,8 +3265,11 @@ find_origin (struct Rts8891_Device *dev, SANE_Bool * changed)
sanei_rts88xx_set_gain (dev->regs, 0x10, 0x10, 0x10);
/* gray level scan */
- dev->regs[LAMP_REG] = 0xad;
- sanei_rts88xx_write_reg (dev->devnum, LAMP_REG, dev->regs + LAMP_REG);
+ if (dev->sensor != SENSOR_TYPE_UMAX)
+ {
+ dev->regs[LAMP_REG] = 0xad;
+ sanei_rts88xx_write_reg (dev->devnum, LAMP_REG, dev->regs + LAMP_REG);
+ }
if (dev->sensor != SENSOR_TYPE_4400
&& (dev->sensor != SENSOR_TYPE_4400_BARE))
{
@@ -3208,6 +3296,16 @@ find_origin (struct Rts8891_Device *dev, SANE_Bool * changed)
write_gray_data (data, "find_origin.pnm", width, height);
}
+ /* strong gamma correction (16) for reliable detection with cold lamp */
+ if (dev->sensor == SENSOR_TYPE_UMAX)
+ {
+ gamma_correction(data, total, 16);
+ if (DBG_LEVEL > DBG_io2)
+ {
+ write_gray_data (data, "find_origin_gamma.pnm", width, height);
+ }
+ }
+
/* now we have the data, search for the black area so that we can */
/* deduce start of scan area */
/* we apply an Y direction sobel filter to get reliable edge detection */
@@ -3291,6 +3389,20 @@ find_origin (struct Rts8891_Device *dev, SANE_Bool * changed)
dev->regs[0xe6] = 0x08; 0x10 080d=2061=1030*2+1 */
SET_DOUBLE (dev->regs, EXPOSURE_REG, 2061);
}
+ else if (dev->sensor == SENSOR_TYPE_UMAX)
+ {
+ dev->regs[0x36] = 0x24; /* direction reverse (& ~0x08) */
+ dev->regs[0xb2] = 0x02;
+ dev->regs[0xd9] = 0x2d;
+ dev->regs[0xda] = 0x00;
+ dev->regs[0xe2] = 0x07;
+
+ /*
+ dev->regs[0xe5] = 0x06;
+ dev->regs[0xe6] = 0x04; 406=1030 */
+ SET_DOUBLE (dev->regs, EXPOSURE_REG, 1030);
+ sum -= 32;
+ }
else
{
dev->regs[0x11] = 0x3f; /* 0x3b */
@@ -3306,6 +3418,7 @@ find_origin (struct Rts8891_Device *dev, SANE_Bool * changed)
}
/* move by a fixed amount relative to the 'top' of the scanner */
+ DBG (DBG_info, "find_origin: moving back %d lines\n", height - sum + 10);
sanei_rts88xx_set_scan_area (dev->regs, height - sum + 10,
height - sum + 11, 637, 893);
rts8891_write_all (dev->devnum, dev->regs, dev->reg_count);
@@ -3341,6 +3454,7 @@ find_margin (struct Rts8891_Device *dev)
int height = 1;
SANE_Byte reg = 0xa2;
int timing=0;
+ unsigned char margin_level = MARGIN_LEVEL;
DBG (DBG_proc, "find_margin: start\n");
@@ -3352,12 +3466,25 @@ find_margin (struct Rts8891_Device *dev)
{
sanei_rts88xx_set_status (dev->devnum, dev->regs, 0x10, 0x23);
}
+ else if (dev->sensor == SENSOR_TYPE_UMAX)
+ {
+ sanei_rts88xx_set_status (dev->devnum, dev->regs, 0x20, 0x3b);
+ }
else
{
sanei_rts88xx_set_status (dev->devnum, dev->regs, 0x28, 0x3b);
}
- sanei_rts88xx_set_gain (dev->regs, 0x3f, 0x3f, 0x3f);
+ if (dev->sensor == SENSOR_TYPE_UMAX)
+ {
+ sanei_rts88xx_set_offset (dev->regs, 0xad, 0xb2, 0xb1);
+ sanei_rts88xx_set_gain (dev->regs, 0x00, 0x00, 0x00);
+ startx = 66;
+ }
+ else
+ {
+ sanei_rts88xx_set_gain (dev->regs, 0x3f, 0x3f, 0x3f);
+ }
/* set scan parameters */
dev->regs[0x33] = 0x01;
@@ -3447,6 +3574,49 @@ find_margin (struct Rts8891_Device *dev)
dev->regs[0x8d] = 0x3b; /* 0x00 */
timing=0x00b0;
}
+ if (dev->sensor == SENSOR_TYPE_UMAX)
+ {
+ dev->regs[0x35] = 0x0e;
+ dev->regs[0x3a] = 0x0e;
+ dev->regs[0x40] = 0x20;
+ dev->regs[0x72] = 0xe1;
+ dev->regs[0x73] = 0x14;
+ dev->regs[0x74] = 0x18;
+ dev->regs[0x7a] = 0x01;
+ dev->regs[0x8d] = 0x07;
+ timing=0x32;
+ dev->regs[0xc1] = 0x07;
+ dev->regs[0xc2] = 0x80;
+ dev->regs[0xc4] = 0xf8;
+ dev->regs[0xc5] = 0x7f;
+ dev->regs[0xc6] = 0xff;
+ dev->regs[0xc7] = 0x07;
+ dev->regs[0xc8] = 0x80;
+ dev->regs[0xc9] = 0x00;
+ dev->regs[0xca] = 0x0f;
+ dev->regs[0xcb] = 0x00;
+ dev->regs[0xcc] = 0xfe;
+ dev->regs[0xcd] = 0x00;
+ dev->regs[0xce] = 0x00;
+ dev->regs[0xcf] = 0xf7;
+ dev->regs[0xd0] = 0xe1;
+ dev->regs[0xd1] = 0xea;
+ dev->regs[0xd2] = 0x0b;
+ dev->regs[0xd3] = 0x03;
+ dev->regs[0xd4] = 0x05;
+ dev->regs[0xd6] = 0xab;
+ dev->regs[0xd7] = 0x10;
+ dev->regs[0xd8] = 0xa6;
+ dev->regs[0xda] = 0x00;
+ dev->regs[0xe2] = 0x03;
+ dev->regs[0xee] = 0x00;
+ dev->regs[0xf1] = 0x00;
+
+ /* dev->regs[0xe5] = 0xbd;
+ dev->regs[0xe6] = 0x0a; 0abd=2749 */
+ SET_DOUBLE (dev->regs, EXPOSURE_REG, 2749);
+ margin_level = 32;
+ }
SET_DOUBLE (dev->regs, TIMING_REG, timing);
SET_DOUBLE (dev->regs, TIMING1_REG, timing+1);
SET_DOUBLE (dev->regs, TIMING2_REG, timing+2);
@@ -3480,11 +3650,28 @@ find_margin (struct Rts8891_Device *dev)
write_gray_data (data, "find_margin.pnm", width, height);
}
- /* we search from left to right the first white pixel */
+ /* gamma correction (2) for reliable detection with cold lamp */
+ if (dev->sensor == SENSOR_TYPE_UMAX)
+ {
+ gamma_correction(data, total, 2);
+ if (DBG_LEVEL > DBG_io2)
+ {
+ write_gray_data (data, "find_margin_gamma.pnm", width, height);
+ }
+ }
+
+ /* search from left for the first white pixel (4 consecutive for UMAX) */
x = 0;
- while (x < width && data[x] < MARGIN_LEVEL)
- x++;
- if (x == width)
+ if (dev->sensor == SENSOR_TYPE_UMAX)
+ while (x < width - 3 && (data[x] < margin_level ||
+ data[x + 1] < margin_level ||
+ data[x + 2] < margin_level ||
+ data[x + 3] < margin_level))
+ x++;
+ else
+ while (x < width && data[x] < margin_level)
+ x++;
+ if (x == width || (dev->sensor == SENSOR_TYPE_UMAX && x == width - 3))
{
DBG (DBG_warn, "find_margin: failed to find left margin!\n");
DBG (DBG_warn, "find_margin: using default...\n");
@@ -3679,7 +3866,10 @@ initialize_device (struct Rts8891_Device *dev)
dev->regs[0xd5] = 0x86; /* 0x06 */
dev->regs[0xd7] = 0x30; /* 0x10 */
dev->regs[0xd8] = 0xf6; /* 0x7a */
- dev->regs[0xd9] = 0x80; /* 0x00 */
+ if (dev->sensor != SENSOR_TYPE_UMAX)
+ {
+ dev->regs[0xd9] = 0x80; /* 0x00 */
+ }
dev->regs[0xda] = 0x00; /* 0x15 */
dev->regs[0xe2] = 0x01; /* 0x00 */
/* dev->regs[0xe5] = 0x14; 0x0f */
@@ -4011,6 +4201,38 @@ int i;
dev->regs[0x90] = 0x80; /* 0x00 */
}
break;
+ case SENSOR_TYPE_UMAX:
+ for (i = 0; i < dev->reg_count; i++)
+ dev->regs[i] = 0x00;
+ dev->regs[0x00] = 0xe5;
+ dev->regs[0x01] = 0x41;
+ dev->regs[0x0b] = 0x70;
+ dev->regs[0x10] = 0xd0;
+ dev->regs[0x11] = 0x1b;
+ dev->regs[0x13] = 0x20;
+ dev->regs[0x15] = 0x20;
+ dev->regs[0x1d] = 0x20;
+ dev->regs[0x20] = 0x3a;
+ dev->regs[0x21] = 0xf2;
+ dev->regs[0x34] = 0x10;
+ dev->regs[0x36] = 0x07;
+ dev->regs[0x40] = 0x20;
+ dev->regs[0x44] = 0x8c;
+ dev->regs[0x45] = 0x76;
+ dev->regs[0x8d] = 0x80;
+ dev->regs[0x8e] = 0x68;
+ dev->regs[0x93] = 0x02;
+ dev->regs[0x94] = 0x0e;
+ dev->regs[0xa3] = 0xcc;
+ dev->regs[0xa4] = 0x27;
+ dev->regs[0xa5] = 0x64;
+ dev->regs[0xb2] = 0x02;
+ dev->regs[0xd5] = 0x86;
+ dev->regs[0xd6] = 0x1b;
+ dev->regs[0xd8] = 0xff;
+ dev->regs[0xe2] = 0x01;
+ dev->regs[0xe5] = 0x14;
+ break;
}
return SANE_STATUS_GOOD;
}
@@ -4093,6 +4315,14 @@ init_device (struct Rts8891_Device *dev)
DBG (DBG_io, "init_device: status=0x%02x 0x%02x\n", dev->regs[0x10],
dev->regs[0x11]);
+ if (dev->model->sensor == SENSOR_TYPE_UMAX)
+ {
+ /* bit 7 in reg 0x10 is set on USB plug when UTA is attached
+ * we keep track of it and set it back on exit so we can detect UTA next time
+ */
+ dev->has_uta = (dev->regs[0x10] & 0x80) ? SANE_TRUE : SANE_FALSE;
+ DBG (DBG_io, "init_device: UMAX UTA (Transparency adapter) %s\n", dev->has_uta ? "detected":"not detected");
+ }
/* reads lamp status and sensor information */
sanei_rts88xx_get_lamp_status (dev->devnum, dev->regs);
DBG (DBG_io, "init_device: lamp status=0x%02x\n", dev->regs[0x8e]);
@@ -4194,39 +4424,77 @@ init_device (struct Rts8891_Device *dev)
DBG (DBG_warn, "init_device: got unexpected id 0x%02x\n", id);
}
+ if (dev->sensor == SENSOR_TYPE_UMAX)
+ {
+ dev->regs[0x10] = 0x28;
+ dev->regs[0x11] = 0x28;
+ dev->regs[0x12] = 0xff;
+ dev->regs[0x14] = 0xf0; /* GPIO/buttons direction? */
+ dev->regs[0x15] = 0x28;
+ dev->regs[0x16] = 0x0f; /* GPIO/buttons direction? */
+ dev->regs[0x18] = 0xff;
+ dev->regs[0x24] = 0xff;
+ dev->regs[0x72] = 0xe1;
+ dev->regs[0x73] = 0x14;
+ dev->regs[0x74] = 0x18;
+ dev->regs[0x75] = 0x15;
+ dev->regs[0xc0] = 0x87;
+ dev->regs[0xc1] = 0x07;
+ dev->regs[0xc2] = 0xf8;
+ dev->regs[0xc3] = 0x78;
+ dev->regs[0xc4] = 0xf8;
+ dev->regs[0xc5] = 0x07;
+ dev->regs[0xc6] = 0x87;
+ dev->regs[0xc7] = 0x07;
+ dev->regs[0xc8] = 0xf8;
+ dev->regs[0xc9] = 0xfc;
+ dev->regs[0xca] = 0x0f;
+ dev->regs[0xce] = 0x80;
+ dev->regs[0xcf] = 0xe2;
+ dev->regs[0xd0] = 0xe4;
+ dev->regs[0xd1] = 0xea;
+ dev->regs[0xd2] = 0x0b;
+ dev->regs[0xd3] = 0x03;
+ dev->regs[0xd4] = 0x05;
+ dev->regs[0xd7] = 0x10;
+ dev->regs[0xd8] = 0xa6;
+ }
+ else
+ {
+ dev->regs[0x12] = 0xff;
+ dev->regs[0x14] = 0xf8;
+ dev->regs[0x15] = 0x28;
+ dev->regs[0x16] = 0x07;
+ dev->regs[0x18] = 0xff;
+ dev->regs[0x23] = 0xff;
+ dev->regs[0x24] = 0xff;
- dev->regs[0x12] = 0xff;
- dev->regs[0x14] = 0xf8;
- dev->regs[0x15] = 0x28;
- dev->regs[0x16] = 0x07;
- dev->regs[0x18] = 0xff;
- dev->regs[0x23] = 0xff;
- dev->regs[0x24] = 0xff;
+ dev->regs[0x72] = 0xe1;
+ dev->regs[0x73] = 0x14;
+ dev->regs[0x74] = 0x18;
+ dev->regs[0x75] = 0x15;
+ dev->regs[0xc0] = 0xff;
+ dev->regs[0xc1] = 0x0f;
+ dev->regs[0xc3] = 0xff;
+ dev->regs[0xc4] = 0xff;
+ dev->regs[0xc5] = 0xff;
+ dev->regs[0xc6] = 0xff;
+ dev->regs[0xc7] = 0xff;
+ dev->regs[0xc8] = 0xff;
+ dev->regs[0xca] = 0x0e;
+ dev->regs[0xcd] = 0xf0;
+ dev->regs[0xce] = 0xff;
+ dev->regs[0xcf] = 0xf5;
+ dev->regs[0xd0] = 0xf7;
+ dev->regs[0xd1] = 0xea;
+ dev->regs[0xd2] = 0x0b;
+ dev->regs[0xd3] = 0x03;
+ dev->regs[0xd4] = 0x05;
+ dev->regs[0xd7] = 0x30;
+ dev->regs[0xd8] = 0xf6;
+ dev->regs[0xd9] = 0x80;
+ }
- dev->regs[0x72] = 0xe1;
- dev->regs[0x73] = 0x14;
- dev->regs[0x74] = 0x18;
- dev->regs[0x75] = 0x15;
- dev->regs[0xc0] = 0xff;
- dev->regs[0xc1] = 0x0f;
- dev->regs[0xc3] = 0xff;
- dev->regs[0xc4] = 0xff;
- dev->regs[0xc5] = 0xff;
- dev->regs[0xc6] = 0xff;
- dev->regs[0xc7] = 0xff;
- dev->regs[0xc8] = 0xff;
- dev->regs[0xca] = 0x0e;
- dev->regs[0xcd] = 0xf0;
- dev->regs[0xce] = 0xff;
- dev->regs[0xcf] = 0xf5;
- dev->regs[0xd0] = 0xf7;
- dev->regs[0xd1] = 0xea;
- dev->regs[0xd2] = 0x0b;
- dev->regs[0xd3] = 0x03;
- dev->regs[0xd4] = 0x05;
- dev->regs[0xd7] = 0x30;
- dev->regs[0xd8] = 0xf6;
- dev->regs[0xd9] = 0x80;
rts8891_write_all (dev->devnum, dev->regs, dev->reg_count);
/* now we are writing and reading back from memory, it is surely a memory test since the written data
@@ -4370,14 +4638,17 @@ init_device (struct Rts8891_Device *dev)
return SANE_STATUS_IO_ERROR;
}
}
- reg = 0x80;
- sanei_rts88xx_write_reg (dev->devnum, LAMP_REG, &reg);
- reg = 0xad;
- sanei_rts88xx_write_reg (dev->devnum, LAMP_REG, &reg);
- sanei_rts88xx_read_regs (dev->devnum, 0x14, dev->regs + 0x14, 2);
- /* we expect 0xF8 0x28 here */
- dev->regs[0x14] = dev->regs[0x14] & 0x7F;
- sanei_rts88xx_write_regs (dev->devnum, 0x14, dev->regs + 0x14, 2);
+ if (dev->sensor != SENSOR_TYPE_UMAX)
+ {
+ reg = 0x80;
+ sanei_rts88xx_write_reg (dev->devnum, LAMP_REG, &reg);
+ reg = 0xad;
+ sanei_rts88xx_write_reg (dev->devnum, LAMP_REG, &reg);
+ sanei_rts88xx_read_regs (dev->devnum, 0x14, dev->regs + 0x14, 2);
+ /* we expect 0xF8 0x28 here */
+ dev->regs[0x14] = dev->regs[0x14] & 0x7F;
+ sanei_rts88xx_write_regs (dev->devnum, 0x14, dev->regs + 0x14, 2);
+ }
/* reads scanner status */
sanei_rts88xx_get_status (dev->devnum, dev->regs);
@@ -4387,10 +4658,13 @@ init_device (struct Rts8891_Device *dev)
DBG (DBG_io, "init_device: link=0x%02x\n", control);
sanei_rts88xx_read_reg (dev->devnum, CONTROL_REG, &control);
sanei_rts88xx_reset_lamp (dev->devnum, dev->regs);
- reg = 0x8d;
- sanei_rts88xx_write_reg (dev->devnum, LAMP_REG, &reg);
- reg = 0xad;
- sanei_rts88xx_write_reg (dev->devnum, LAMP_REG, &reg);
+ if (dev->sensor != SENSOR_TYPE_UMAX)
+ {
+ reg = 0x8d;
+ sanei_rts88xx_write_reg (dev->devnum, LAMP_REG, &reg);
+ reg = 0xad;
+ sanei_rts88xx_write_reg (dev->devnum, LAMP_REG, &reg);
+ }
/* here, we are in iddle state */
@@ -4480,19 +4754,25 @@ init_device (struct Rts8891_Device *dev)
dev->regs[0x12] = 0xff;
dev->regs[0x13] = 0x20;
sanei_rts88xx_write_regs (dev->devnum, 0x12, dev->regs + 0x12, 2);
- dev->regs[0x14] = 0xf8;
- dev->regs[0x15] = 0x28;
- sanei_rts88xx_write_regs (dev->devnum, 0x14, dev->regs + 0x14, 2);
+ if (dev->sensor != SENSOR_TYPE_UMAX)
+ {
+ dev->regs[0x14] = 0xf8;
+ dev->regs[0x15] = 0x28;
+ sanei_rts88xx_write_regs (dev->devnum, 0x14, dev->regs + 0x14, 2);
+ }
reg = 0;
sanei_rts88xx_write_control (dev->devnum, 0x00);
sanei_rts88xx_write_control (dev->devnum, 0x00);
sanei_rts88xx_set_status (dev->devnum, dev->regs, 0x28, 0x28);
- reg = 0x80;
- sanei_rts88xx_write_reg (dev->devnum, LAMP_REG, &reg);
+ if (dev->sensor != SENSOR_TYPE_UMAX)
+ {
+ reg = 0x80;
+ sanei_rts88xx_write_reg (dev->devnum, LAMP_REG, &reg);
+ dev->regs[LAMP_REG] = 0xad;
+ }
dev->regs[0x8b] = 0xff;
dev->regs[0x8c] = 0x3f;
- dev->regs[LAMP_REG] = 0xad;
rts8891_write_all (dev->devnum, dev->regs, dev->reg_count);
set_lamp_brightness (dev, 0);
@@ -4601,7 +4881,7 @@ detect_device (struct Rts8891_Device *dev)
/**
* Do dark calibration. We scan a well defined area until average pixel value
* of the black area is about 0x03 for each color channel. This calibration is
- * currently done at 75 dpi regardless of the final scan dpi.
+ * currently done at 75 dpi (100 for UMAX) regardless of the final scan dpi.
*/
static SANE_Status
dark_calibration (struct Rts8891_Device *dev, int mode, int light)
@@ -4611,7 +4891,7 @@ dark_calibration (struct Rts8891_Device *dev, int mode, int light)
int ro = 250, tro = 250, bro = 0;
int bo = 250, tbo = 250, bbo = 0;
int go = 250, tgo = 250, bgo = 0;
- unsigned char image[CALIBRATION_SIZE];
+ unsigned char image[dev->model->calibration_width * 3];
float global, ra, ga, ba;
int num = 0;
char name[32];
@@ -4628,7 +4908,15 @@ dark_calibration (struct Rts8891_Device *dev, int mode, int light)
/* set up starting values */
sanei_rts88xx_set_gain (dev->regs, 0, 0, 0);
- sanei_rts88xx_set_scan_area (dev->regs, 1, 2, 4, 4 + CALIBRATION_WIDTH);
+ if (dev->sensor == SENSOR_TYPE_UMAX)
+ {
+ /* UMAX calibratration area is 1500 but the width is halved by reg. 0x7a */
+ sanei_rts88xx_set_scan_area (dev->regs, 1, 2, 2, 2 + 2 * dev->model->calibration_width);
+ }
+ else
+ {
+ sanei_rts88xx_set_scan_area (dev->regs, 1, 2, 4, 4 + dev->model->calibration_width);
+ }
sanei_rts88xx_set_status (dev->devnum, dev->regs, mode, light);
@@ -4743,6 +5031,51 @@ dark_calibration (struct Rts8891_Device *dev, int mode, int light)
dev->regs[0xef] = 0x02; /* 0x03 */
dev->regs[0xf0] = 0xa8; /* 0x70 */
}
+ if (dev->sensor == SENSOR_TYPE_UMAX)
+ {
+ dev->regs[0x33] = 0x01;
+ dev->regs[0x35] = 0x47;
+ dev->regs[0x40] = 0xa0;
+ dev->regs[0x7a] = 0x02;
+ dev->regs[0x8d] = 0x46;
+ dev->regs[0xc0] = 0x66;
+ dev->regs[0xc1] = 0xc0;
+ dev->regs[0xc2] = 0x7f;
+ dev->regs[0xc3] = 0x99;
+ dev->regs[0xc4] = 0x3f;
+ dev->regs[0xc5] = 0x80;
+ dev->regs[0xc6] = 0x66;
+ dev->regs[0xc7] = 0xc0;
+ dev->regs[0xc8] = 0x7f;
+ dev->regs[0xc9] = 0xff;
+ dev->regs[0xcb] = 0x00;
+ dev->regs[0xcc] = 0x00;
+ dev->regs[0xcd] = 0x80;
+ dev->regs[0xce] = 0xff;
+ dev->regs[0xcf] = 0xe3;
+ dev->regs[0xd0] = 0xe8;
+ dev->regs[0xd1] = 0xee;
+ dev->regs[0xd2] = 0x0f;
+ dev->regs[0xd3] = 0x0b;
+ dev->regs[0xd4] = 0x0d;
+ dev->regs[0xd8] = 0xa6;
+ dev->regs[0xe2] = 0x07;
+
+ /*dev->regs[0xe5] = 0x1b; 28=40
+ dev->regs[0xe6] = 0x01; */
+ SET_DOUBLE (dev->regs, EXPOSURE_REG, 283);
+
+ dev->regs[0xe7] = 0x4b;
+ dev->regs[0xe9] = 0x40;
+ dev->regs[0xea] = 0x7d;
+ dev->regs[0xeb] = 0x04;
+ dev->regs[0xec] = 0x18;
+ dev->regs[0xed] = 0x85;
+ dev->regs[0xee] = 0x02;
+ dev->regs[0xef] = 0x0a;
+ dev->regs[0xf0] = 0x81;
+ dev->regs[0xf1] = 0x01;
+ }
/* we loop scanning a 637 (1911 bytes) pixels wide area in color mode
* until each black average reaches the desired value */
@@ -4757,7 +5090,7 @@ dark_calibration (struct Rts8891_Device *dev, int mode, int light)
/* do scan */
status =
rts8891_simple_scan (dev->devnum, dev->regs, dev->reg_count, 0x02,
- CALIBRATION_SIZE, image);
+ dev->model->calibration_width * 3, image);
if (status != SANE_STATUS_GOOD)
{
DBG (DBG_error, "dark_calibration: failed to scan\n");
@@ -4768,12 +5101,13 @@ dark_calibration (struct Rts8891_Device *dev, int mode, int light)
if (DBG_LEVEL >= DBG_io2)
{
sprintf (name, "dark%03d.pnm", num);
- write_rgb_data (name, image, CALIBRATION_WIDTH, 1);
+ write_rgb_data (name, image, dev->model->calibration_width, 1);
num++;
}
/* we now compute the average of red pixels from the first 15 pixels */
global = average_area (SANE_TRUE, image, 15, 1, &ra, &ga, &ba);
+// global = average_area (SANE_TRUE, image, dev->model->calibration_width, 1, &ra, &ga, &ba);
DBG (DBG_info,
"dark_calibration: global=%.2f, channels=(%.2f,%.2f,%.2f)\n",
global, ra, ga, ba);
@@ -4855,6 +5189,133 @@ dark_calibration (struct Rts8891_Device *dev, int mode, int light)
}
/*
+ * wait until lamp is warmed up enough. We repeat 6 single-line scans at
+ * 1200dpi until the average value change between first and last is below
+ * 0.3 %
+ */
+static SANE_Status
+lamp_warm_up (struct Rts8891_Device *dev, int mode, int light)
+{
+ SANE_Status status = SANE_STATUS_GOOD;
+ int num = 0;
+ char name[32];
+ unsigned char image[9600 * 3];
+ float global, ra, ga, ba, first = 0;
+ int seq = 1;
+#define LAMP_MAX_CYCLES 360 /* max. 2 minutes (120s/2s * 6) */
+
+ DBG (DBG_proc, "lamp_warm_up: start\n");
+
+ sanei_rts88xx_set_gain (dev->regs, 0, 0, 0);
+ sanei_rts88xx_set_scan_area (dev->regs, 1, 2, 400, 400 + 9600); /* why 400? */
+
+ sanei_rts88xx_set_status (dev->devnum, dev->regs, mode, light);
+
+ dev->regs[0x00] = 0xe5; /* scan */
+ dev->regs[0x32] = 0x00;
+ dev->regs[0x33] = 0x03;
+ dev->regs[0x35] = 0x0e;
+ dev->regs[0x36] = 0x22;
+ dev->regs[0x3a] = 0x0e;
+ dev->regs[0x40] = 0x20;
+
+ dev->regs[0x7a] = 0x01;
+
+ dev->regs[0x8d] = 0x84;
+ dev->regs[0x8e] = 0x63;
+
+ dev->regs[0xb2] = 0x02;
+
+ dev->regs[0xc0] = 0x1f;
+ dev->regs[0xc1] = 0x00;
+ dev->regs[0xc2] = 0xfe;
+ dev->regs[0xc3] = 0xe0;
+ dev->regs[0xc4] = 0xff;
+ dev->regs[0xc5] = 0x01;
+ dev->regs[0xc6] = 0x1f;
+ dev->regs[0xc7] = 0x00;
+ dev->regs[0xc8] = 0xfe;
+ dev->regs[0xc9] = 0x00;
+ dev->regs[0xca] = 0x00;
+ dev->regs[0xcb] = 0x1c;
+ dev->regs[0xcc] = 0x00;
+ dev->regs[0xcd] = 0xc0;
+ dev->regs[0xce] = 0x01;
+ dev->regs[0xcf] = 0xeb;
+ dev->regs[0xd0] = 0xed;
+ dev->regs[0xd1] = 0xe1;
+ dev->regs[0xd2] = 0x02;
+ dev->regs[0xd3] = 0x12;
+ dev->regs[0xd4] = 0xf4;
+ dev->regs[0xd5] = 0x86;
+ dev->regs[0xd6] = 0x1b;
+ dev->regs[0xd7] = 0x10;
+ dev->regs[0xd8] = 0xa6;
+ dev->regs[0xd9] = 0x2d;
+ dev->regs[0xda] = 0x00;
+ dev->regs[0xe2] = 0x00;
+
+ /*dev->regs[0xe5] = 0xf7;
+ dev->regs[0xe6] = 0x2a; */
+ SET_DOUBLE (dev->regs, EXPOSURE_REG, 0x2af7);
+
+ dev->regs[0xe7] = 0x00;
+ dev->regs[0xe8] = 0x00;
+ dev->regs[0xe9] = 0x00;
+ dev->regs[0xea] = 0x00;
+ dev->regs[0xeb] = 0x00;
+ dev->regs[0xec] = 0x00;
+ dev->regs[0xed] = 0x00;
+ dev->regs[0xef] = 0x00;
+ dev->regs[0xf0] = 0x00;
+ dev->regs[0xf2] = 0x00;
+
+ /* scan 9600 pixels wide area in color mode 6 times
+ * if average value difference between first and last scan is 0.3% or greater,
+ * retry after 2 seconds */
+ sanei_rts88xx_set_status (dev->devnum, dev->regs, mode, light);
+ while (seq < LAMP_MAX_CYCLES)
+ {
+ /* do scan */
+ status =
+ rts8891_simple_scan (dev->devnum, dev->regs, dev->reg_count, 0x12,
+ 9600 * 3, image);
+ if (status != SANE_STATUS_GOOD)
+ {
+ DBG (DBG_error, "lamp_warm_up: failed to scan\n");
+ return status;
+ }
+
+ /* save scanned picture for data debugging */
+ if (DBG_LEVEL >= DBG_io2)
+ {
+ sprintf (name, "warm%03d.pnm", num);
+ write_rgb_data (name, image, 9600, 1);
+ num++;
+ }
+ global = average_area (SANE_TRUE, image, 9600, 1, &ra, &ga, &ba);
+ if (seq % 6 == 1)
+ first = global;
+ if (seq % 6 == 0)
+ {
+ DBG (DBG_info, "lamp_warm_up: change=%f\n", global / first);
+ if (global / first < 1.003)
+ break;
+ sleep(2);
+ }
+ seq++;
+ }
+ if (seq >= LAMP_MAX_CYCLES)
+ {
+ DBG (DBG_error0, "lamp_warm_up: timed out waiting for lamp to stabilize\n");
+ /* continue anyway */
+ }
+
+ DBG (DBG_proc, "lamp_warm_up: exit\n");
+ return status;
+}
+
+/*
* do gain calibration. We do scans until averaged values of the area match
* the target code. We're doing a dichotomy again.
*/
@@ -4871,9 +5332,9 @@ gain_calibration (struct Rts8891_Device *dev, int mode, int light)
int trg, tbg, tgg, bgg, brg, bbg;
int num = 0;
char name[32];
- int width = CALIBRATION_WIDTH;
- int length = CALIBRATION_SIZE;
- unsigned char image[CALIBRATION_SIZE];
+ int width = dev->model->calibration_width;
+ int length = dev->model->calibration_width * 3;
+ unsigned char image[dev->model->calibration_width * 3];
int pass = 0;
int timing=0;
@@ -4882,7 +5343,10 @@ gain_calibration (struct Rts8891_Device *dev, int mode, int light)
DBG (DBG_proc, "gain_calibration: start\n");
/* set up starting values */
- sanei_rts88xx_set_scan_area (dev->regs, 1, 2, xstart, xstart + width);
+ if (dev->sensor == SENSOR_TYPE_UMAX)
+ sanei_rts88xx_set_scan_area (dev->regs, 1, 2, xstart, xstart + 2 * width);
+ else
+ sanei_rts88xx_set_scan_area (dev->regs, 1, 2, xstart, xstart + width);
sanei_rts88xx_set_offset (dev->regs, dev->red_offset, dev->green_offset,
dev->blue_offset);
@@ -5023,6 +5487,54 @@ gain_calibration (struct Rts8891_Device *dev, int mode, int light)
dev->regs[0x87] = 0x00;
dev->regs[0x88] = 0x06;
}
+ if (dev->sensor == SENSOR_TYPE_UMAX)
+ {
+ dev->regs[0x33] = 0x01;
+ dev->regs[0x35] = 0x47;
+ dev->regs[0x40] = 0xa0;
+ dev->regs[0x7a] = 0x02;
+ timing = 0x32;
+ dev->regs[0x8d] = 0x4f;
+ dev->regs[0xc0] = 0x66;
+ dev->regs[0xc1] = 0xc0;
+ dev->regs[0xc2] = 0x7f;
+ dev->regs[0xc3] = 0x99;
+ dev->regs[0xc4] = 0x3f;
+ dev->regs[0xc5] = 0x80;
+ dev->regs[0xc6] = 0x66;
+ dev->regs[0xc7] = 0xc0;
+ dev->regs[0xc8] = 0x7f;
+ dev->regs[0xc9] = 0xff;
+ dev->regs[0xcb] = 0x00;
+ dev->regs[0xcc] = 0x00;
+ dev->regs[0xcd] = 0x80;
+ dev->regs[0xce] = 0xff;
+ dev->regs[0xcf] = 0xe3;
+ dev->regs[0xd0] = 0xe8;
+ dev->regs[0xd1] = 0xee;
+ dev->regs[0xd2] = 0x0f;
+ dev->regs[0xd3] = 0x0b;
+ dev->regs[0xd4] = 0x0d;
+ dev->regs[0xd7] = 0x10;
+ dev->regs[0xd8] = 0xa6;
+ dev->regs[0xda] = 0x00;
+ dev->regs[0xe2] = 0x07;
+
+ /*dev->regs[0xe5] = 0x1b; 28=40
+ dev->regs[0xe6] = 0x01; */
+ SET_DOUBLE (dev->regs, EXPOSURE_REG, 283);
+
+ dev->regs[0xe7] = 0x4b;
+ dev->regs[0xe9] = 0x40;
+ dev->regs[0xea] = 0x7d;
+ dev->regs[0xeb] = 0x04;
+ dev->regs[0xec] = 0x18;
+ dev->regs[0xed] = 0x85;
+ dev->regs[0xee] = 0x02;
+ dev->regs[0xef] = 0x0a;
+ dev->regs[0xf0] = 0x81;
+ dev->regs[0xf1] = 0x01;
+ }
SET_DOUBLE (dev->regs, TIMING_REG, timing);
SET_DOUBLE (dev->regs, TIMING1_REG, timing+1);
SET_DOUBLE (dev->regs, TIMING2_REG, timing+2);
@@ -5039,9 +5551,18 @@ gain_calibration (struct Rts8891_Device *dev, int mode, int light)
bgg = 0;
bbg = 0;
/* top values */
- trg = 0x1f;
- tgg = 0x1f;
- tbg = 0x1f;
+ if (dev->sensor == SENSOR_TYPE_UMAX)
+ {
+ trg = 0x3f;
+ tgg = 0x3f;
+ tbg = 0x3f;
+ }
+ else
+ {
+ trg = 0x1f;
+ tgg = 0x1f;
+ tbg = 0x1f;
+ }
/* loop on gain calibration until we find until we find stable value
* or we do more than 20 tries */
@@ -5228,7 +5749,7 @@ offset_calibration (struct Rts8891_Device *dev, int mode, int light)
int ro = 250, tro = 250, bro = 123;
int go = 250, tgo = 250, bgo = 123;
int bo = 250, tbo = 250, bbo = 123;
- unsigned char image[CALIBRATION_SIZE];
+ unsigned char image[dev->model->calibration_width * 3];
float global, ra, ga, ba;
int num = 0;
char name[32];
@@ -5239,7 +5760,10 @@ offset_calibration (struct Rts8891_Device *dev, int mode, int light)
/* gains from previous step are a little higher than the one used */
sanei_rts88xx_set_gain (dev->regs, dev->red_gain, dev->green_gain,
dev->blue_gain);
- sanei_rts88xx_set_scan_area (dev->regs, 1, 2, 4, 4 + CALIBRATION_WIDTH);
+ if (dev->sensor == SENSOR_TYPE_UMAX)
+ sanei_rts88xx_set_scan_area (dev->regs, 1, 2, 4, 4 + 2 * dev->model->calibration_width);
+ else
+ sanei_rts88xx_set_scan_area (dev->regs, 1, 2, 4, 4 + dev->model->calibration_width);
dev->regs[0x32] = 0x00;
dev->regs[0x33] = 0x03;
@@ -5341,6 +5865,52 @@ offset_calibration (struct Rts8891_Device *dev, int mode, int light)
dev->regs[0xef] = 0x02; /* 0x03 */
dev->regs[0xf0] = 0xa8; /* 0x70 */
}
+ if (dev->sensor == SENSOR_TYPE_UMAX)
+ {
+ dev->regs[0x33] = 0x01;
+ dev->regs[0x35] = 0x47;
+ dev->regs[0x40] = 0xa0;
+ dev->regs[0x7a] = 0x02;
+ /* timing = 0x32; */
+ dev->regs[0x8d] = 0x46;
+ dev->regs[0xc0] = 0x66;
+ dev->regs[0xc1] = 0xc0;
+ dev->regs[0xc2] = 0x7f;
+ dev->regs[0xc3] = 0x99;
+ dev->regs[0xc4] = 0x3f;
+ dev->regs[0xc5] = 0x80;
+ dev->regs[0xc6] = 0x66;
+ dev->regs[0xc7] = 0xc0;
+ dev->regs[0xc8] = 0x7f;
+ dev->regs[0xc9] = 0xff;
+ dev->regs[0xcb] = 0x00;
+ dev->regs[0xcc] = 0x00;
+ dev->regs[0xcd] = 0x80;
+ dev->regs[0xce] = 0xff;
+ dev->regs[0xcf] = 0xe3;
+ dev->regs[0xd0] = 0xe8;
+ dev->regs[0xd1] = 0xee;
+ dev->regs[0xd2] = 0x0f;
+ dev->regs[0xd3] = 0x0b;
+ dev->regs[0xd4] = 0x0d;
+ dev->regs[0xd8] = 0xa6;
+ dev->regs[0xe2] = 0x07;
+
+ /*dev->regs[0xe5] = 0x1b; 28=40
+ dev->regs[0xe6] = 0x01; */
+ SET_DOUBLE (dev->regs, EXPOSURE_REG, 283);
+
+ dev->regs[0xe7] = 0x4b;
+ dev->regs[0xe9] = 0x40;
+ dev->regs[0xea] = 0x7d;
+ dev->regs[0xeb] = 0x04;
+ dev->regs[0xec] = 0x18;
+ dev->regs[0xed] = 0x85;
+ dev->regs[0xee] = 0x02;
+ dev->regs[0xef] = 0x0a;
+ dev->regs[0xf0] = 0x81;
+ dev->regs[0xf1] = 0x01;
+ }
/* we loop scanning a 637 (1911 bytes) pixels wide area in color mode until each black average
* reaches the desired value */
@@ -5351,13 +5921,13 @@ offset_calibration (struct Rts8891_Device *dev, int mode, int light)
sanei_rts88xx_set_offset (dev->regs, ro, go, bo);
sanei_rts88xx_set_status (dev->devnum, dev->regs, mode, light);
rts8891_simple_scan (dev->devnum, dev->regs, dev->reg_count, 0x02,
- CALIBRATION_SIZE, image);
+ dev->model->calibration_width * 3, image);
/* save scanned picture for data debugging */
if (DBG_LEVEL >= DBG_io2)
{
sprintf (name, "offset%03d.pnm", num);
- write_rgb_data (name, image, CALIBRATION_WIDTH, 1);
+ write_rgb_data (name, image, dev->model->calibration_width, 1);
num++;
}
@@ -5465,7 +6035,7 @@ setup_shading_calibration (struct Rts8891_Device *dev, int mode, int *light, int
*status1 |= 0x08;
}
- /* we default to 75 dpi then override needed registers */
+ /* we default to 75 dpi (100 for UMAX) then override needed registers */
timing=0x00b0;
regs[0x32] = 0x20;
regs[0x33] = 0x83;
@@ -5543,10 +6113,25 @@ setup_shading_calibration (struct Rts8891_Device *dev, int mode, int *light, int
regs[0xe2] = 0x02; /* 0x05 */
exposure=443;
}
+ if (dev->sensor == SENSOR_TYPE_UMAX)
+ {
+ regs[0x36] = 0x29;
+ regs[0x7a] = 0x02;
+ timing = 0x32;
+ regs[0x8d] = 0x4f;
+ regs[0xe2] = 0x00;
+ /* regs[0xe5] = 0xdf;
+ regs[0xe6] = 0x08; 8df =2271 */
+ exposure=2271;
+ regs[0xee] = 00;
+ regs[0xf1] = 00;
+ }
switch (dev->xdpi)
{
case 75:
+ case 100:
+ case 200:
break;
case 150:
@@ -5796,6 +6381,37 @@ setup_shading_calibration (struct Rts8891_Device *dev, int mode, int *light, int
"setup_shading_calibration: setting up SENSOR_TYPE_4400_BARE for 300 dpi\n");
return SANE_STATUS_INVAL;
break;
+ case SENSOR_TYPE_UMAX:
+ DBG (DBG_io,
+ "setup_shading_calibration: setting up SENSOR_TYPE_UMAX for 300 dpi\n");
+ regs[0x36] = 0x2c;
+ regs[0x40] = 0x20;
+ regs[0x7a] = 0x01;
+ regs[0x8d] = 0x12;
+ regs[0xc0] = 0x87;
+ regs[0xc1] = 0x07;
+ regs[0xc2] = 0xf8;
+ regs[0xc3] = 0x78;
+ regs[0xc4] = 0xf8;
+ regs[0xc5] = 0x07;
+ regs[0xc6] = 0x87;
+ regs[0xc7] = 0x07;
+ regs[0xc8] = 0xf8;
+ regs[0xc9] = 0xfc;
+ regs[0xca] = 0x0f;
+ regs[0xcd] = 0x00;
+ regs[0xce] = 0x80;
+ regs[0xcf] = 0xe2;
+ regs[0xd0] = 0xe4;
+ regs[0xd1] = 0xea;
+ regs[0xd2] = 0x0b;
+ regs[0xd3] = 0x17;
+ regs[0xd4] = 0x01;
+ regs[0xe2] = 0x07;
+ /* regs[0xe5] = 0xc9;
+ regs[0xe6] = 0x01; 0x1c9=457 */
+ exposure=457;
+ break;
}
break;
@@ -5950,6 +6566,46 @@ setup_shading_calibration (struct Rts8891_Device *dev, int mode, int *light, int
"setup_shading_calibration: setting up SENSOR_TYPE_4400_BARE for 600 dpi\n");
return SANE_STATUS_INVAL;
break;
+ case SENSOR_TYPE_UMAX:
+ DBG (DBG_io,
+ "setup_shading_calibration: setting up SENSOR_TYPE_UMAX for 600 dpi\n");
+ *status1 = 0x20;
+
+ regs[0x36] = 0x2c;
+ regs[0x40] = 0x20;
+ regs[0x7a] = 0x01;
+ regs[0x8d] = 0x24;
+ regs[0xc0] = 0xff;
+ regs[0xc1] = 0x07;
+ regs[0xc2] = 0x80;
+ regs[0xc3] = 0x00;
+ regs[0xc4] = 0xf8;
+ regs[0xc5] = 0x7f;
+ regs[0xc6] = 0xff;
+ regs[0xc7] = 0x07;
+ regs[0xc8] = 0x80;
+ regs[0xc9] = 0x00;
+ regs[0xca] = 0x0f;
+ regs[0xcc] = 0xfe;
+ regs[0xcd] = 0x00;
+ regs[0xce] = 0x00;
+ regs[0xcf] = 0xd7;
+ regs[0xd0] = 0x61;
+ regs[0xd1] = 0xaa;
+ regs[0xd2] = 0x0b;
+ regs[0xd3] = 0x03;
+ regs[0xd4] = 0x05;
+ regs[0xd5] = 0x86;
+ regs[0xd6] = 0x1b;
+ regs[0xd7] = 0x10;
+ regs[0xd8] = 0xa6;
+ regs[0xd9] = 0x2d;
+
+ regs[0xe2] = 0x07;
+ /* regs[0xe5] = 0xae;
+ regs[0xe6] = 0x02;*/
+ exposure=0x02ae;
+ break;
}
break;
@@ -6100,6 +6756,44 @@ setup_shading_calibration (struct Rts8891_Device *dev, int mode, int *light, int
"setup_shading_calibration: setting up SENSOR_TYPE_4400_BARE for 1200 dpi\n");
return SANE_STATUS_INVAL;
break;
+
+ case SENSOR_TYPE_UMAX:
+ DBG (DBG_io,
+ "setup_shading_calibration: setting up SENSOR_TYPE_UMAX for 1200 dpi\n");
+ *status1 = 0x20;
+ regs[0x36] = 0x2c;
+ regs[0x40] = 0x20;
+ regs[0x7a] = 0x01;
+ regs[0x8d] = 0x48;
+
+ regs[0xc0] = 0x1f;
+ regs[0xc1] = 0x00;
+ regs[0xc2] = 0xfe;
+ regs[0xc3] = 0xe0;
+ regs[0xc4] = 0xff;
+ regs[0xc5] = 0x01;
+ regs[0xc6] = 0x1f;
+ regs[0xc7] = 0x00;
+ regs[0xc8] = 0xfe;
+ regs[0xc9] = 0x00;
+ regs[0xca] = 0x00;
+ regs[0xcb] = 0x1c;
+ regs[0xcc] = 0x00;
+ regs[0xcd] = 0xc0;
+ regs[0xce] = 0x01;
+ regs[0xcf] = 0xeb;
+ regs[0xd0] = 0xed;
+ regs[0xd1] = 0xe1;
+ regs[0xd2] = 0x02;
+ /* regs[0xd3] = 0x12; */
+ regs[0xd4] = 0xf4;
+ regs[0xd5] = 0x86;
+ regs[0xd6] = 0x1b;
+ regs[0xe2] = 0x07;
+ /* regs[0xe5] = 0x5e;
+ regs[0xe6] = 0x05; 0x55e=1374 */
+ exposure=1374;
+ break;
}
break;
}
@@ -6113,7 +6807,10 @@ setup_shading_calibration (struct Rts8891_Device *dev, int mode, int *light, int
/* in logs, the driver use the computed offset minus 2 */
sanei_rts88xx_set_offset (regs, dev->red_offset, dev->green_offset, dev->blue_offset);
sanei_rts88xx_set_gain (regs, dev->red_gain, dev->green_gain, dev->blue_gain);
- sanei_rts88xx_set_scan_area (regs, 1, 1 + lines, dev->xstart, dev->xstart + dev->pixels);
+ if (dev->sensor == SENSOR_TYPE_UMAX && dev->xdpi == 100)
+ sanei_rts88xx_set_scan_area (regs, 1, 1 + lines, dev->xstart, dev->xstart + 2 * dev->pixels);
+ else
+ sanei_rts88xx_set_scan_area (regs, 1, 1 + lines, dev->xstart, dev->xstart + dev->pixels);
DBG (DBG_proc, "setup_shading_calibration: exit\n");
return status;
@@ -6153,7 +6850,10 @@ shading_calibration (struct Rts8891_Device *dev, SANE_Bool color, int mode, int
}
if (dev->shading_data != NULL)
free (dev->shading_data);
- dev->shading_data = (unsigned char *) malloc (dev->bytes_per_line);
+ if (dev->sensor == SENSOR_TYPE_UMAX && dev->xdpi == 100)
+ dev->shading_data = (unsigned char *) malloc (2 * dev->bytes_per_line);
+ else
+ dev->shading_data = (unsigned char *) malloc (dev->bytes_per_line);
if (dev->shading_data == NULL)
{
free (image);
@@ -6217,7 +6917,13 @@ shading_calibration (struct Rts8891_Device *dev, SANE_Bool color, int mode, int
{
sum += image[x + y * width];
}
- dev->shading_data[x] = sum / (lines - 13);
+ if (dev->sensor == SENSOR_TYPE_UMAX && dev->xdpi == 100)
+ {
+ dev->shading_data[2 * x] = sum / (lines - 13);
+ dev->shading_data[2 * x + 1] = sum / (lines - 13);
+ }
+ else
+ dev->shading_data[x] = sum / (lines - 13);
}
if (DBG_LEVEL >= DBG_io2)
{
@@ -6292,10 +6998,17 @@ send_calibration_data (struct Rts8891_Session *session)
/* 675 pixels at 75 DPI, 16 bits values, 3 color channels */
/* 5400 pixels at max sensor 600 dpi */
/* 3 16bits 256 value gamma tables plus start/end markers */
- /* must multiple of 32 */
- data_size = (675 * dev->xdpi) / 75;
-
- width = dev->pixels;
+ /* must multple of 32 */
+ if (dev->sensor == SENSOR_TYPE_UMAX && dev->xdpi == 100)
+ {
+ data_size = (675 * 2 * dev->xdpi) / 75;
+ width = 2 * dev->pixels;
+ }
+ else
+ {
+ data_size = (675 * dev->xdpi) / 75;
+ width = dev->pixels;
+ }
/* effective data calibration size */
size = data_size * 2 * 3 + 3 * (512 + 2);
@@ -6563,7 +7276,11 @@ setup_scan_registers (struct Rts8891_Session *session, SANE_Byte *status1, SANE_
DBG (DBG_warn,
"setup_scan_registers: native gray modes not implemented for this model, failure expected\n");
}
- sanei_rts88xx_set_scan_area (regs, dev->ystart, dev->ystart + dev->lines, dev->xstart, dev->xstart + dev->pixels);
+ DBG (DBG_info, "setup_scan_registers: dev->xdpi = %d\n", dev->xdpi);
+ if (dev->sensor == SENSOR_TYPE_UMAX && dev->xdpi == 100)
+ sanei_rts88xx_set_scan_area (regs, dev->ystart, dev->ystart + dev->lines, dev->xstart, dev->xstart + 2 * dev->pixels);
+ else
+ sanei_rts88xx_set_scan_area (regs, dev->ystart, dev->ystart + dev->lines, dev->xstart, dev->xstart + dev->pixels);
DBG (DBG_info, "setup_scan_registers: xstart=%d, pixels=%d\n", dev->xstart, dev->pixels);
DBG (DBG_info, "setup_scan_registers: ystart=%d, lines =%d\n", dev->ystart, dev->lines);
@@ -6590,7 +7307,7 @@ setup_scan_registers (struct Rts8891_Session *session, SANE_Byte *status1, SANE_
*status2 = 0x3b;
}
- /* default to 75 dpi color scan */
+ /* default to 75 dpi (100 for UMAX) color scan */
regs[0x0b] = 0x70;
regs[0x0c] = 0x00;
regs[0x0d] = 0x00;
@@ -6923,9 +7640,73 @@ setup_scan_registers (struct Rts8891_Session *session, SANE_Byte *status1, SANE_
regs[0xf0] = 0xa8; /* 0x00 */
regs[0xf2] = 0x01; /* 0x00 */
}
+ if (dev->sensor == SENSOR_TYPE_UMAX)
+ {
+ regs[0x14] = 0xf0;
+ regs[0x16] = 0x00;
+ regs[0x23] = 0x00;
+ regs[0x32] = 0x80;
+ regs[0x33] = 0x81;
+ regs[0x40] = 0xa4;
+ regs[0x7a] = 0x02;
+ timing=0x0182;
+ regs[0x85] = 0x10;
+ regs[0x86] = 0x14;
+ regs[0x87] = 0x20;
+ regs[0x88] = 0x22;
+ regs[0x8d] = 0x4f;
+ regs[0xc0] = 0x66;
+ regs[0xc1] = 0xc0;
+ regs[0xc2] = 0x7f;
+ regs[0xc3] = 0x99;
+ regs[0xc4] = 0x3f;
+ regs[0xc5] = 0x80;
+ regs[0xc6] = 0x66;
+ regs[0xc7] = 0xc0;
+ regs[0xc8] = 0x7f;
+ regs[0xc9] = 0xff;
+ regs[0xcb] = 0x00;
+ regs[0xcc] = 0x00;
+ regs[0xcd] = 0x80;
+ regs[0xce] = 0xff;
+ regs[0xcf] = 0xe3;
+ regs[0xd0] = 0xe8;
+ regs[0xd1] = 0xee;
+ regs[0xd2] = 0x0f;
+ /*regs[0xd3] = 0x0b;*/
+ regs[0xd4] = 0x0d;
+
+ regs[0xd6] = 0x0f;
+ regs[0xd7] = 0x10; /* 4111 */
+
+ regs[0xd8] = 0xa6; /* 0xa610=42512 */
+
+ regs[0xd9] = 0x2d;
+ regs[0xda] = 0x00;
+ regs[0xe2] = 0x07;
+ regs[0xe3] = 0xbd;
+ regs[0xe4] = 0x08;
+
+ /* regs[0xe5] = 0x1b;
+ regs[0xe6] = 0x01; exposure time 0x011b=283 */
+ exposure=283;
+
+ regs[0xe7] = 0x4b;
+ regs[0xe9] = 0x40;
+ regs[0xea] = 0x7d;
+ regs[0xeb] = 0x04;
+ regs[0xec] = 0x18;
+ regs[0xed] = 0x85;
+ regs[0xee] = 0x02;
+ regs[0xef] = 0x0a;
+ regs[0xf0] = 0x81;
+ regs[0xf1] = 0x01;
+ }
switch (dev->xdpi)
{
case 75:
+ case 100:
+ case 200:
break;
case 150:
regs[0x35] = 0x45;
@@ -7042,6 +7823,48 @@ setup_scan_registers (struct Rts8891_Session *session, SANE_Byte *status1, SANE_
regs[0xf0] = 0x02;
regs[0xf2] = 0x00;
break;
+ case SENSOR_TYPE_UMAX:
+ DBG (DBG_io, "setup_scan_registers: setting up SENSOR_TYPE_UMAX for 150 dpi\n");
+ regs[0x32] = 0x20;
+ regs[0x33] = 0x83;
+ regs[0x40] = 0x2c;
+ regs[0x7a] = 0x01;
+ regs[0x8d] = 0x09;
+ regs[0xc1] = 0x06;
+ regs[0xc2] = 0x7e;
+ regs[0xc4] = 0xf9;
+ regs[0xc5] = 0x81;
+ regs[0xc7] = 0x06;
+ regs[0xc8] = 0x7e;
+ regs[0xca] = 0x0f;
+ regs[0xcb] = 0xc0;
+ regs[0xcd] = 0x00;
+ regs[0xce] = 0x30;
+ regs[0xcf] = 0xe4;
+ regs[0xd0] = 0xe6;
+ regs[0xd1] = 0xea;
+ regs[0xd2] = 0x0b;
+ regs[0xd3] = 0x17;
+ regs[0xd4] = 0x01;
+ regs[0xe2] = 0x0f;
+ regs[0xe3] = 0x89;
+ regs[0xe4] = 0x03;
+ /* regs[0xe5] = 0xaa;*/
+ exposure = 170;
+
+ regs[0xe7] = 0x00;
+ regs[0xe8] = 0x79;
+ regs[0xe9] = 0x01;
+ regs[0xea] = 0x0b;
+ regs[0xeb] = 0x58;
+ regs[0xec] = 0x01;
+ regs[0xed] = 0x04;
+ regs[0xee] = 0xbc;
+ regs[0xef] = 0x00;
+ regs[0xf0] = 0x03;
+ regs[0xf1] = 0x00;
+ regs[0xf2] = 0x00;
+ break;
}
break;
@@ -7194,6 +8017,59 @@ setup_scan_registers (struct Rts8891_Session *session, SANE_Byte *status1, SANE_
regs[0xf0] = 0x00;
regs[0xf2] = 0x00;
break;
+ case SENSOR_TYPE_UMAX:
+ DBG (DBG_io, "setup_scan_registers: setting up SENSOR_TYPE_UMAX for 300 dpi\n");
+ regs[0x32] = 0x20;
+ regs[0x33] = 0x83;
+ regs[0x35] = 0x0e;
+ regs[0x3a] = 0x0e;
+ regs[0x40] = 0x2c;
+ regs[0x7a] = 0x01;
+ timing=0x022b;
+ regs[0x85] = 0x18;
+ regs[0x86] = 0x1b;
+ regs[0x87] = 0x30;
+ regs[0x88] = 0x30;
+ regs[0x8d] = 0x12;
+ regs[0xc0] = 0x87;
+ regs[0xc1] = 0x07;
+ regs[0xc2] = 0xf8;
+ regs[0xc3] = 0x78;
+ regs[0xc4] = 0xf8;
+ regs[0xc5] = 0x07;
+ regs[0xc6] = 0x87;
+ regs[0xc7] = 0x07;
+ regs[0xc8] = 0xf8;
+ regs[0xc9] = 0xfc;
+ regs[0xca] = 0x0f;
+ regs[0xcd] = 0x00;
+ regs[0xce] = 0x80;
+ regs[0xcf] = 0xe2;
+ regs[0xd0] = 0xe4;
+ regs[0xd1] = 0xea;
+ regs[0xd2] = 0x0b;
+ regs[0xd3] = 0x17;
+ regs[0xd4] = 0x01;
+ regs[0xe3] = 0x00;
+ regs[0xe4] = 0x00;
+ /* regs[0xe5] = 0xc9;
+ regs[0xe6] = 0x01; */
+ exposure = 457;
+
+ regs[0xe7] = 0x00;
+ regs[0xe8] = 0x00;
+ regs[0xe9] = 0x00;
+ regs[0xea] = 0x00;
+ regs[0xeb] = 0x00;
+ regs[0xec] = 0x00;
+ regs[0xed] = 0x00;
+ regs[0xee] = 0x00;
+ regs[0xef] = 0x00;
+ regs[0xf0] = 0x00;
+ regs[0xf1] = 0x00;
+ regs[0xf2] = 0x00;
+
+ break;
}
break;
case 600:
@@ -7391,6 +8267,75 @@ setup_scan_registers (struct Rts8891_Session *session, SANE_Byte *status1, SANE_
DBG (DBG_io, "setup_scan_registers: setting up SENSOR_TYPE_4400_BARE for 600 dpi\n");
return SANE_STATUS_INVAL;
break;
+
+ case SENSOR_TYPE_UMAX:
+ DBG (DBG_io, "setup_scan_registers: setting up SENSOR_TYPE_UMAX for 600 dpi\n");
+/* *status1 = 0x10;
+ *status2 = 0x23;*/
+
+ regs[0x32] = 0x20;
+ regs[0x33] = 0x83;
+ regs[0x34] = 0xf0;
+ regs[0x35] = 0x1b;
+ regs[0x36] = 0x29;
+ regs[0x3a] = 0x1b;
+ regs[0x40] = 0x2c;
+ regs[0x7a] = 0x01;
+ regs[0x85] = 0x30;
+ regs[0x86] = 0x30;
+ regs[0x87] = 0x60;
+ regs[0x88] = 0x5a;
+ regs[0x8d] = 0x24;
+
+ regs[0xc0] = 0xff;
+ regs[0xc1] = 0x07;
+ regs[0xc2] = 0x80;
+ regs[0xc3] = 0x00;
+ regs[0xc4] = 0xf8;
+ regs[0xc5] = 0x7f;
+ regs[0xc6] = 0xff;
+ regs[0xc7] = 0x07;
+ regs[0xc8] = 0x80;
+ regs[0xc9] = 0x00;
+ regs[0xca] = 0x0f;
+
+ regs[0xcc] = 0xfe;
+ regs[0xcd] = 0x00;
+ regs[0xce] = 0x00;
+ regs[0xcf] = 0xd7;
+ regs[0xd0] = 0x61;
+ regs[0xd1] = 0xaa;
+ regs[0xd2] = 0x0b;
+ regs[0xd3] = 0x03;
+ regs[0xd4] = 0x05;
+ regs[0xd5] = 0x86;
+ regs[0xd6] = 0x1b;
+ regs[0xd7] = 0x10;
+ regs[0xd8] = 0xa6;
+ regs[0xd9] = 0x2d;
+
+ regs[0xe0] = 0x00;
+ regs[0xe1] = 0x00;
+ regs[0xe2] = 0x01;
+ regs[0xe3] = 0x00;
+ regs[0xe4] = 0x00;
+/* regs[0xe5] = 0xbd;
+ regs[0xe6] = 0x0a;*/
+ exposure=0x0abd;
+ regs[0xe7] = 0x00;
+ regs[0xe8] = 0x00;
+ regs[0xe9] = 0x00;
+ regs[0xea] = 0x00;
+ regs[0xeb] = 0x00;
+ regs[0xec] = 0x00;
+ regs[0xed] = 0x00;
+ regs[0xee] = 0x00;
+ regs[0xef] = 0x00;
+ regs[0xf0] = 0x00;
+ regs[0xf1] = 0x00;
+ regs[0xf2] = 0x00;
+ timing=0x0425;
+ break;
}
break;
case 1200:
@@ -7584,6 +8529,68 @@ setup_scan_registers (struct Rts8891_Session *session, SANE_Byte *status1, SANE_
DBG (DBG_io, "setup_scan_registers: setting up SENSOR_TYPE_4400_BARE for 1200 dpi\n");
return SANE_STATUS_INVAL;
break;
+
+ case SENSOR_TYPE_UMAX:
+ DBG (DBG_io, "setup_scan_registers: setting up SENSOR_TYPE_UMAX for 1200 dpi\n");
+ regs[0x32] = 0x20;
+ regs[0x33] = 0x83;
+ regs[0x34] = 0xf0;
+ regs[0x35] = 0x0e;
+ regs[0x36] = 0x29;
+ regs[0x3a] = 0x0e;
+ regs[0x40] = 0x2c;
+ regs[0x7a] = 0x01;
+ timing=0x081a;
+ regs[0x85] = 0x60;
+ regs[0x86] = 0x5a;
+ regs[0x87] = 0xc0;
+ regs[0x88] = 0xae;
+ regs[0x8d] = 0x48;
+
+ regs[0xc0] = 0x1f;
+ regs[0xc1] = 0x00;
+ regs[0xc2] = 0xfe;
+ regs[0xc3] = 0xe0;
+ regs[0xc4] = 0xff;
+ regs[0xc5] = 0x01;
+ regs[0xc6] = 0x1f;
+ regs[0xc7] = 0x00;
+ regs[0xc8] = 0xfe;
+ regs[0xc9] = 0x00;
+ regs[0xca] = 0x00;
+ regs[0xcb] = 0x1c;
+ regs[0xcc] = 0x00;
+ regs[0xcd] = 0xc0;
+ regs[0xce] = 0x01;
+ regs[0xcf] = 0xeb;
+ regs[0xd0] = 0xed;
+ regs[0xd1] = 0xe1;
+ regs[0xd2] = 0x02;
+ /* regs[0xd3] = 0x12; */
+ regs[0xd4] = 0xf4;
+ regs[0xd5] = 0x86;
+ regs[0xd6] = 0x1b;
+
+ regs[0xe2] = 0x00;
+ regs[0xe3] = 0x00;
+ regs[0xe4] = 0x00;
+ /* regs[0xe5] = 0xf7;
+ regs[0xe6] = 0x2a; */
+ exposure=0x2af7;
+ regs[0xe7] = 0x00;
+ regs[0xe8] = 0x00;
+ regs[0xe9] = 0x00;
+ regs[0xea] = 0x00;
+ regs[0xeb] = 0x00;
+ regs[0xec] = 0x00;
+ regs[0xed] = 0x00;
+ regs[0xee] = 0x00;
+ regs[0xef] = 0x00;
+ regs[0xf0] = 0x00;
+ regs[0xf1] = 0x00;
+ regs[0xf2] = 0x00;
+
+ break;
}
break;
}
@@ -7661,10 +8668,13 @@ park_head (struct Rts8891_Device *dev, SANE_Bool wait)
DBG (DBG_proc, "park_head: start\n");
- reg = 0x8d;
- sanei_rts88xx_write_reg (dev->devnum, LAMP_REG, &reg);
- reg = 0xad;
- sanei_rts88xx_write_reg (dev->devnum, LAMP_REG, &reg);
+ if (dev->sensor != SENSOR_TYPE_UMAX)
+ {
+ reg = 0x8d;
+ sanei_rts88xx_write_reg (dev->devnum, LAMP_REG, &reg);
+ reg = 0xad;
+ sanei_rts88xx_write_reg (dev->devnum, LAMP_REG, &reg);
+ }
status = sanei_rts88xx_read_reg (dev->devnum, CONTROL_REG, &control);
@@ -7684,10 +8694,13 @@ park_head (struct Rts8891_Device *dev, SANE_Bool wait)
}
sanei_rts88xx_write_regs (dev->devnum, 0x16, dev->regs + 0x16, 2);
- reg = 0x8d;
- sanei_rts88xx_write_reg (dev->devnum, LAMP_REG, &reg);
- reg = 0xad;
- sanei_rts88xx_write_reg (dev->devnum, LAMP_REG, &reg);
+ if (dev->sensor != SENSOR_TYPE_UMAX)
+ {
+ reg = 0x8d;
+ sanei_rts88xx_write_reg (dev->devnum, LAMP_REG, &reg);
+ reg = 0xad;
+ sanei_rts88xx_write_reg (dev->devnum, LAMP_REG, &reg);
+ }
/* 0x20 expected */
sanei_rts88xx_read_reg (dev->devnum, CONTROLER_REG, &reg);
@@ -7738,6 +8751,11 @@ update_button_status (struct Rts8891_Session *session)
/* effective button reading */
status = rts8891_read_buttons (session->dev->devnum, &mask);
+ if (session->dev->sensor == SENSOR_TYPE_UMAX)
+ {
+ mask >>= 8;
+ }
+
/* release interface if needed */
if (lock == SANE_TRUE)
{
@@ -7778,6 +8796,11 @@ set_lamp_state (struct Rts8891_Session *session, int on)
}
}
+ if (session->dev->sensor == SENSOR_TYPE_UMAX) /* main lamp on UMAX */
+ {
+ sanei_rts88xx_set_status (session->dev->devnum, session->dev->regs, session->dev->has_uta ? 0xa0 : 0x20, on ? 0x3b : 0x1b);
+ }
+
status = sanei_rts88xx_read_reg (session->dev->devnum, LAMP_REG, &reg);
if (on)
{
diff --git a/backend/rts8891_devices.c b/backend/rts8891_devices.c
index 8216a0a..82a934b 100644
--- a/backend/rts8891_devices.c
+++ b/backend/rts8891_devices.c
@@ -68,6 +68,9 @@ static Rts8891_Model hp4400c_model = {
/* default sensor */
SENSOR_TYPE_4400,
+ /* calibration width */
+ 637,
+
/* default gamma table */
{0x00, 0x04, 0x08, 0x0c, 0x10, 0x14, 0x18, 0x1c, 0x20, 0x24, 0x28, 0x2c,
0x30, 0x34, 0x38, 0x3c, 0x40, 0x44, 0x48, 0x4c, 0x50, 0x52, 0x53, 0x55,
@@ -132,6 +135,9 @@ static Rts8891_Model hp4470c_model = {
/* default sensor */
SENSOR_TYPE_XPA,
+ /* calibration width */
+ 637,
+
/* default gamma table */
{0x00, 0x04, 0x08, 0x0c, 0x10, 0x14, 0x18, 0x1c, 0x20, 0x24, 0x28, 0x2c,
0x30, 0x34, 0x38, 0x3c, 0x40, 0x44, 0x48, 0x4c, 0x50, 0x52, 0x53, 0x55,
@@ -177,11 +183,25 @@ static Rts8891_Model astra4400_model = {
"Astra 4400", /* Device model name */
"flatbed scanner", /* Device type */
- {1200, 600, 300, 150, 75, 0}, /* possible x-resolutions */
- {600, 300, 150, 0}, /* possible y-resolutions */
+/* Some resolutions supported by Windows driver are emulated:
+ driver dpi real dpi
+ -------------------------
+ 75 (+preview) 200x100 very fast
+ 100 200x100 very fast
+ 150 150x150
+ 200 200x200
+ 300 300x300
+ 400 600x400
+ 600 600x600
+ 800 1200x1200
+ 1200 1200x1200
+*/
+
+ {1200, 600, 300, 150, 100, 0}, /* possible x-resolutions */
+ {1200, 600, 400, 300, 150, 100, 0}, /* possible y-resolutions */
1200, /* max physical x dpi */
- 600, /* max physical y dpi */
- 150, /* min physical y dpi */
+ 1200, /* max physical y dpi */
+ 100, /* min physical y dpi */
SANE_FIX (8.3), /* Start of scan area in mm (x) */
SANE_FIX (3.0), /* Start of scan area in mm (y) */
@@ -196,42 +216,43 @@ static Rts8891_Model astra4400_model = {
24, 12, 0, /* R, G, and B CCD Line-distance correction in lines at
max motor resolution */
/* default sensor */
- SENSOR_TYPE_XPA,
+ SENSOR_TYPE_UMAX,
+
+ /* calibration width */
+ 750,
/* default gamma table */
- {0x00, 0x04, 0x08, 0x0c, 0x10, 0x14, 0x18, 0x1c, 0x20, 0x24, 0x28, 0x2c,
- 0x30, 0x34, 0x38, 0x3c, 0x40, 0x44, 0x48, 0x4c, 0x50, 0x52, 0x53, 0x55,
- 0x57, 0x58, 0x5a, 0x5c, 0x5d, 0x5f, 0x60, 0x62, 0x63, 0x64, 0x66, 0x67,
- 0x68, 0x6a, 0x6b, 0x6c, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x74, 0x75, 0x76,
- 0x77, 0x78, 0x79, 0x7a, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83,
- 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8d, 0x8e,
- 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x96, 0x97, 0x98, 0x99,
- 0x9a, 0x9b, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3,
- 0xa3, 0xa4, 0xa5, 0xa6, 0xa6, 0xa7, 0xa8, 0xa9, 0xa9, 0xaa, 0xab, 0xac,
- 0xac, 0xad, 0xae, 0xaf, 0xaf, 0xb0, 0xb1, 0xb1, 0xb2, 0xb3, 0xb4, 0xb4,
- 0xb5, 0xb6, 0xb6, 0xb7, 0xb8, 0xb8, 0xb9, 0xba, 0xba, 0xbb, 0xbc, 0xbc,
- 0xbd, 0xbe, 0xbe, 0xbf, 0xc0, 0xc0, 0xc1, 0xc1, 0xc2, 0xc3, 0xc3, 0xc4,
- 0xc5, 0xc5, 0xc6, 0xc6, 0xc7, 0xc8, 0xc8, 0xc9, 0xc9, 0xca, 0xcb, 0xcb,
- 0xcc, 0xcc, 0xcd, 0xce, 0xce, 0xcf, 0xcf, 0xd0, 0xd1, 0xd1, 0xd2, 0xd2,
- 0xd3, 0xd3, 0xd4, 0xd5, 0xd5, 0xd6, 0xd6, 0xd7, 0xd7, 0xd8, 0xd9, 0xd9,
- 0xda, 0xda, 0xdb, 0xdb, 0xdc, 0xdc, 0xdd, 0xdd, 0xde, 0xdf, 0xdf, 0xe0,
- 0xe0, 0xe1, 0xe1, 0xe2, 0xe2, 0xe3, 0xe3, 0xe4, 0xe4, 0xe5, 0xe5, 0xe6,
- 0xe6, 0xe7, 0xe7, 0xe8, 0xe8, 0xe9, 0xe9, 0xea, 0xea, 0xeb, 0xeb, 0xec,
- 0xec, 0xed, 0xed, 0xee, 0xee, 0xef, 0xef, 0xf0, 0xf0, 0xf1, 0xf1, 0xf2,
- 0xf2, 0xf3, 0xf3, 0xf4, 0xf4, 0xf5, 0xf5, 0xf6, 0xf6, 0xf7, 0xf7, 0xf8,
- 0xf8, 0xf9, 0xf9, 0xfa, 0xfa, 0xfa, 0xfb, 0xfb, 0xfc, 0xfc, 0xfd, 0xfd,
- 0xfe, 0xfe, 0xff, 0xff},
+ {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
+ 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
+ 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24,
+ 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
+ 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c,
+ 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
+ 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54,
+ 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60,
+ 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c,
+ 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
+ 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84,
+ 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90,
+ 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c,
+ 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8,
+ 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4,
+ 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0,
+ 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc,
+ 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
+ 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4,
+ 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0,
+ 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc,
+ 0xfd, 0xfe, 0xff},
/* number of buttons */
- 11,
+ 4,
/* button names */
- {"plus", "minus", "copy", "mail", "image-copy", "www", "scan", "power",
- "cancel", "options", "toggle-mode"},
+ {"scan", "copy", "mail", "custom"},
/* button titles */
- {"plus", "minus", "copy", "mail", "image copy", "www", "scan", "power",
- "cancel", "options", "toggle color/gray mode"},
+ {"scan", "copy", "mail", "custom"},
/* flags */
RTS8891_FLAG_EMULATED_GRAY_MODE
diff --git a/backend/rts8891_low.c b/backend/rts8891_low.c
index 1b95765..0eeab87 100644
--- a/backend/rts8891_low.c
+++ b/backend/rts8891_low.c
@@ -132,10 +132,16 @@ rts8891_write_all (SANE_Int devnum, SANE_Byte * regs, SANE_Int count)
buffer[1] = 0xb4;
buffer[2] = 0x00;
buffer[3] = size;
- for (i = 0; i < size; i++)
- buffer[i + 4] = regs[0xb4 + i];
+ j = 0;
+ for (i = 0; i < size; i++) {
+ buffer[i + 4 + j] = regs[0xb4 + i];
+ if (buffer[i + 4 + j] == 0xaa) {
+ j++;
+ buffer[i + 4 + j] = 0x00;
+ }
+ }
/* the USB block is size + 4 bytes of header long */
- size += 4;
+ size += 4 + j;
if (sanei_usb_write_bulk (devnum, buffer, &size) != SANE_STATUS_GOOD)
{
DBG (DBG_error,
@@ -368,6 +374,28 @@ rts8891_data_format (SANE_Int dpi, int sensor)
break;
}
}
+ if (sensor == SENSOR_TYPE_UMAX)
+ {
+ switch (dpi)
+ {
+ case 100: /* emulated */
+ case 200:
+ reg = 0x0b;
+ break;
+ case 150:
+ reg = 0x17;
+ break;
+ case 300:
+ reg = 0x17;
+ break;
+ case 600:
+ reg = 0x03;
+ break;
+ case 1200:
+ reg = 0x12;
+ break;
+ }
+ }
return reg;
}
@@ -423,7 +451,12 @@ rts8891_move (struct Rts8891_Device *device, SANE_Byte * regs,
/* prepare scan */
rts8891_set_default_regs (regs);
- if (device->sensor != SENSOR_TYPE_4400
+ if (device->sensor == SENSOR_TYPE_UMAX)
+ {
+ regs10 = 0x20;
+ regs11 = 0x3b;
+ }
+ else if (device->sensor != SENSOR_TYPE_4400
&& device->sensor != SENSOR_TYPE_4400_BARE)
{
regs10 = 0x20;
@@ -509,6 +542,29 @@ rts8891_move (struct Rts8891_Device *device, SANE_Byte * regs,
regs[0xe5] = 0xf3; /* 0xf9 */
regs[0xe6] = 0x01; /* 0x00 */
}
+ if (device->sensor == SENSOR_TYPE_UMAX)
+ {
+ regs[0x14] = 0xf0;
+ regs[0x16] = 0x0f;
+ regs[0x23] = 0x00;
+ regs[0x40] = 0xa0;
+ /* regs[0x7a] = 0x02; */
+ regs[0x80] = 0x83;
+ regs[0x81] = 0x01;
+ regs[0x82] = 0x84;
+ regs[0x83] = 0x01;
+ regs[0x85] = 0x10;
+ regs[0x86] = 0x14;
+ regs[0x87] = 0x20;
+ regs[0x88] = 0x22;
+ regs[0x89] = 0x85;
+ regs[0x8a] = 0x01;
+ regs[0x8d] = 0x4f;
+ regs[0xd9] = 0x2d;
+ regs[0xda] = 0x00;
+ regs[0xe5] = 0x1b;
+ regs[0xe6] = 0x01;
+ }
/* disable CCD */
regs[0] = 0xf5;
@@ -661,11 +717,13 @@ read_data (struct Rts8891_Session *session, SANE_Byte * dest, SANE_Int length)
/* come yet */
if (session->non_blocking && count == 0)
{
-
- dev->regs[LAMP_REG] = 0x8d;
- sanei_rts88xx_write_reg (dev->devnum, LAMP_REG,
+ if (dev->sensor != SENSOR_TYPE_UMAX)
+ {
+ dev->regs[LAMP_REG] = 0x8d;
+ sanei_rts88xx_write_reg (dev->devnum, LAMP_REG,
&(dev->regs[LAMP_REG]));
- DBG (DBG_io, "read_data: no data available\n");
+ }
+ DBG (DBG_io, "read_data: no data vailable\n");
DBG (DBG_proc, "read_data: end\n");
return SANE_STATUS_DEVICE_BUSY;
}
diff --git a/backend/rts8891_low.h b/backend/rts8891_low.h
index 453800c..a15b817 100644
--- a/backend/rts8891_low.h
+++ b/backend/rts8891_low.h
@@ -72,7 +72,8 @@
#define SENSOR_TYPE_XPA 1 /* sensor for hp4470 sold with XPA */
#define SENSOR_TYPE_4400 2 /* sensor for hp4400 */
#define SENSOR_TYPE_4400_BARE 3 /* sensor for hp4400 */
-#define SENSOR_TYPE_MAX 3 /* maximum sensor number value */
+#define SENSOR_TYPE_UMAX 4 /* sensor for Umax Astra 4400/4450 */
+#define SENSOR_TYPE_MAX 4 /* maximum sensor number value */
/* Forward typedefs */
typedef struct Rts8891_Device Rts8891_Device;
@@ -130,6 +131,8 @@ typedef struct Rts8891_Model
/* default sensor type */
SANE_Int sensor;
+ SANE_Int calibration_width;
+
/* default gamma table */
SANE_Word gamma[256];
SANE_Int buttons; /* number of buttons for the scanner */
@@ -173,6 +176,7 @@ struct Rts8891_Device
SANE_Bool initialized; /* true if device has been initialized */
SANE_Bool needs_warming; /* true if device needs warming up */
SANE_Bool parking; /* true if device is parking head */
+ SANE_Bool has_uta; /* true if UTA is connected */
/* values detected during find origin */
/* TODO these are currently unused after detection */
diff --git a/backend/sm3600.h b/backend/sm3600.h
index 2ecbeb2..5d8a8d8 100644
--- a/backend/sm3600.h
+++ b/backend/sm3600.h
@@ -77,7 +77,11 @@ Start: 2.4.2001
/* ====================================================================== */
+#if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 202311L
typedef enum { false, true } TBool;
+#else
+typedef bool TBool;
+#endif /* GCC < 15 */
typedef SANE_Status TState;
diff --git a/backend/snapscan-usb.c b/backend/snapscan-usb.c
index 49cca1a..6e6751f 100644
--- a/backend/snapscan-usb.c
+++ b/backend/snapscan-usb.c
@@ -457,7 +457,7 @@ static int enqueue_bq(int fd,const void *src, size_t src_size)
return 0;
}
-static void dequeue_bq()
+static void dequeue_bq(void)
{
static const char me[] = "dequeue_bq";
struct usb_busy_queue *tbqe;
diff --git a/backend/test.c b/backend/test.c
index 4663a16..bb2b643 100644
--- a/backend/test.c
+++ b/backend/test.c
@@ -1255,7 +1255,7 @@ fail:
}
static void
-cleanup_initial_string_values ()
+cleanup_initial_string_values (void)
{
// Cleanup backing memory for initial values of string options.
free (init_mode);
diff --git a/backend/umax_pp_low.c b/backend/umax_pp_low.c
index d1f3c16..6d80d43 100644
--- a/backend/umax_pp_low.c
+++ b/backend/umax_pp_low.c
@@ -1496,7 +1496,7 @@ ECPFifoMode (void)
/* wait for ack bit */
/* return 1 on success, 0 on error */
static int
-waitAck ()
+waitAck (void)
{
unsigned char breg = 0;
int i = 0;
diff --git a/backend/umax_pp_mid.c b/backend/umax_pp_mid.c
index ef608ac..b5266b3 100644
--- a/backend/umax_pp_mid.c
+++ b/backend/umax_pp_mid.c
@@ -449,7 +449,7 @@ sanei_umax_pp_status (void)
}
int
-sanei_umax_pp_close ()
+sanei_umax_pp_close (void)
{
#ifdef HAVE_LINUX_PPDEV_H
int fd;
diff --git a/backend/xerox_mfp-usb.c b/backend/xerox_mfp-usb.c
index 519aba6..d083238 100644
--- a/backend/xerox_mfp-usb.c
+++ b/backend/xerox_mfp-usb.c
@@ -22,7 +22,7 @@
extern int sanei_debug_xerox_mfp;
static int
-xerox_need_clear_halt()
+xerox_need_clear_halt(void)
{
char *env;
int workaround = 0;
diff --git a/backend/xerox_mfp.c b/backend/xerox_mfp.c
index 0821754..48e1eca 100644
--- a/backend/xerox_mfp.c
+++ b/backend/xerox_mfp.c
@@ -212,6 +212,7 @@ static int isSupportedDevice(struct device __sane_unused__ *dev)
/* blacklist malfunctioning device(s) */
if (!strncmp (dev->sane.model, "SCX-4500W", 9)
|| !strncmp (dev->sane.model, "C460", 4)
+ || !!strstr(dev->sane.model, "SCX-472")
|| !!strstr (dev->sane.model, "WorkCentre 3225")
|| !!strstr (dev->sane.model, "CLX-3170")
|| !!strstr (dev->sane.model, "4x24")
@@ -502,7 +503,7 @@ static SANE_String_Const doc_sources[] = {
};
static int doc_source_to_code[] = {
- 0x40, 0x20, 0x80
+ DOC_FLATBED, DOC_ADF, DOC_AUTO
};
static SANE_String_Const scan_modes[] = {
@@ -702,6 +703,14 @@ static void set_parameters(struct device *dev)
}
}
+/* determine if document is to be sourced from ADF */
+static int sourcing_from_adf(struct device *dev)
+{
+ return (dev->doc_source == DOC_ADF ||
+ (dev->doc_source == DOC_AUTO && dev->doc_loaded));
+}
+
+
/* resolve all options related to scan window */
/* called after option changed and in set_window */
static int fix_window(struct device *dev)
@@ -731,11 +740,10 @@ static int fix_window(struct device *dev)
dev->doc_source = doc_source_to_code[string_match_index(doc_sources, dev->val[OPT_SOURCE].s)];
/* max window len is dependent of document source */
- if (dev->doc_source == DOC_FLATBED ||
- (dev->doc_source == DOC_AUTO && !dev->doc_loaded))
- dev->max_len = dev->max_len_fb;
- else
+ if (sourcing_from_adf(dev))
dev->max_len = dev->max_len_adf;
+ else
+ dev->max_len = dev->max_len_fb;
/* parameters */
dev->win_y_range.max = SANE_FIX((double)dev->max_len / PNT_PER_MM);
@@ -879,8 +887,9 @@ dev_inquiry(struct device *dev)
dev->res[0x3f];
dev->line_order = dev->res[0x31];
dev->compressionTypes = dev->res[0x32];
- dev->doc_loaded = (dev->res[0x35] == 0x02) &&
- (dev->res[0x26] & 0x03);
+ dev->has_adf = ((dev->res[0x26] & 0x03) != 0);
+ dev->doc_loaded = (dev->res[0x35] == 0x02)
+ && dev->has_adf;
init_options(dev);
reset_options(dev);
@@ -891,6 +900,25 @@ dev_inquiry(struct device *dev)
return SANE_STATUS_GOOD;
}
+
+static SANE_Status
+dev_inquiry_adf_status(struct device *dev)
+{
+ if (!dev_cmd(dev, CMD_INQUIRY))
+ return SANE_STATUS_IO_ERROR;
+
+ dev->has_adf = ((dev->res[0x26] & 0x03) != 0);
+ dev->doc_loaded = (dev->res[0x35] == 0x02)
+ && dev->has_adf;
+
+ DBG(3, "%s: ADF present: %s, loaded: %s\n", __func__,
+ (dev->has_adf ? "true" : "false"),
+ (dev->doc_loaded ? "true" : "false"));
+
+ return SANE_STATUS_GOOD;
+}
+
+
const SANE_Option_Descriptor *
sane_get_option_descriptor(SANE_Handle h, SANE_Int opt)
{
@@ -1361,7 +1389,10 @@ sane_read(SANE_Handle h, SANE_Byte *buf, SANE_Int maxlen, SANE_Int *lenp)
remove(encTmpFileName);
}
/* that's all */
- dev_stop(dev);
+ /* finished receving the document; */
+ /* stop and release the unit, unless sourcing from ADF */
+ if (!sourcing_from_adf(dev))
+ dev_stop(dev);
return SANE_STATUS_EOF;
}
@@ -1465,7 +1496,6 @@ SANE_Status
sane_start(SANE_Handle h)
{
struct device *dev = h;
-
DBG(3, "%s: %p\n", __func__, h);
dev->cancel = 0;
@@ -1476,22 +1506,24 @@ sane_start(SANE_Handle h)
dev->blocks = 0;
if (!dev->reserved) {
+ if (dev->has_adf
+ && (dev->doc_source == DOC_AUTO || dev->doc_source == DOC_ADF)) {
+ if (dev_inquiry_adf_status(dev) != SANE_STATUS_GOOD)
+ return dev_stop(dev);
+ }
+
if (!dev_cmd_wait(dev, CMD_RESERVE_UNIT))
return dev->state;
dev->reserved++;
- }
- if (!dev_set_window(dev) ||
- (dev->state && dev->state != SANE_STATUS_DEVICE_BUSY))
- return dev_stop(dev);
+ if (!dev_set_window(dev) ||
+ (dev->state && dev->state != SANE_STATUS_DEVICE_BUSY))
+ return dev_stop(dev);
+ }
if (!dev_cmd_wait(dev, CMD_OBJECT_POSITION))
return dev_stop(dev);
- if (!dev_cmd(dev, CMD_READ) ||
- (dev->state && dev->state != SANE_STATUS_DEVICE_BUSY))
- return dev_stop(dev);
-
dev->scanning = 1;
dev->final_block = 0;
dev->blocklen = 0;
diff --git a/backend/xerox_mfp.conf.in b/backend/xerox_mfp.conf.in
index d9deecc..4d1d934 100644
--- a/backend/xerox_mfp.conf.in
+++ b/backend/xerox_mfp.conf.in
@@ -169,6 +169,10 @@ usb 0x04e8 0x3450
#Samsung SCX-472x Series, Samsung SCX-4729FD
usb 0x04e8 0x3453
+#Samsung SCX-4729FW, network mode
+# tcp HOST_NAME_OR_IP PORT
+#tcp scx4729fw 9400
+
#Samsung CLX-6260 Series
usb 0x04e8 0x3455
diff --git a/backend/xerox_mfp.h b/backend/xerox_mfp.h
index 6aa83a4..ebd1b56 100644
--- a/backend/xerox_mfp.h
+++ b/backend/xerox_mfp.h
@@ -64,6 +64,7 @@ struct device {
int state; /* current state */
int reserved; /* CMD_RESERVE_UNIT */
int reading; /* READ_IMAGE is sent */
+ int has_adf; /* ADF is present */
SANE_Byte *data; /* postprocessing cyclic buffer 64k */
int datalen; /* how data in buffer */