canon_dr backend version 41

- initial P-208 and P-215 support
- bug fix for calibration of scanners with duplex_offset
- allow duplex_offset to be controlled from config file
merge-requests/1/head
m. allan noah 2013-07-31 21:38:25 -04:00
rodzic 02297e0ae9
commit eacdc3a5b3
5 zmienionych plików z 261 dodań i 34 usunięć

Wyświetl plik

@ -315,6 +315,8 @@ putnbyte (unsigned char *pnt, unsigned int value, unsigned int nbytes)
/* the payload */
#define SSM_PAY_len 0x14
#define SSM_PAY_HEAD_len 0x13
#define set_SSM_pay_head_len(sb, val) sb[0x01] = val
#define set_SSM_page_code(sb, val) sb[0x04] = val
#define SSM_PAGE_len 0x0e
#define set_SSM_page_len(sb, val) sb[0x05] = val
@ -355,10 +357,12 @@ putnbyte (unsigned char *pnt, unsigned int value, unsigned int nbytes)
#define COR_CAL_code 0xe1
#define COR_CAL_len 10
#define set_CC_version(sb, val) sb[5] = val
#define set_CC_xferlen(sb, len) putnbyte(sb + 0x06, len, 3)
/* the payload */
#define CC_pay_len 0x20
#define CC_pay_ver 0x00
#define set_CC_f_gain(sb, val) sb[0] = val
#define set_CC_unk1(sb, val) sb[1] = val
@ -382,6 +386,34 @@ putnbyte (unsigned char *pnt, unsigned int value, unsigned int nbytes)
#define set_CC_exp_b_g2(sb, val) putnbyte(sb + 0x1c, val, 2)
#define set_CC_exp_b_b2(sb, val) putnbyte(sb + 0x1e, val, 2)
/* the 'version 3' payload (P-208 and P-215) */
#define CC3_pay_len 0x28
#define CC3_pay_ver 0x03
#define set_CC3_gain_f_r(sb, val) sb[0] = val
#define set_CC3_gain_f_g(sb, val) sb[1] = val
#define set_CC3_gain_f_b(sb, val) sb[2] = val
#define set_CC3_off_f_r(sb, val) sb[4] = val
#define set_CC3_off_f_g(sb, val) sb[5] = val
#define set_CC3_off_f_b(sb, val) sb[6] = val
#define set_CC3_exp_f_r(sb, val) putnbyte(sb + 0x08, val, 2)
#define set_CC3_exp_f_g(sb, val) putnbyte(sb + 0x0a, val, 2)
#define set_CC3_exp_f_b(sb, val) putnbyte(sb + 0x0c, val, 2)
#define set_CC3_gain_b_r(sb, val) sb[0x14] = val
#define set_CC3_gain_b_g(sb, val) sb[0x15] = val
#define set_CC3_gain_b_b(sb, val) sb[0x16] = val
#define set_CC3_off_b_r(sb, val) sb[0x18] = val
#define set_CC3_off_b_g(sb, val) sb[0x19] = val
#define set_CC3_off_b_b(sb, val) sb[0x1a] = val
#define set_CC3_exp_b_r(sb, val) putnbyte(sb + 0x1c, val, 2)
#define set_CC3_exp_b_g(sb, val) putnbyte(sb + 0x1e, val, 2)
#define set_CC3_exp_b_b(sb, val) putnbyte(sb + 0x20, val, 2)
/* ==================================================================== */
/* SET SCAN MODE 2 */
#define SET_SCAN_MODE2_code 0xe5

Wyświetl plik

@ -276,6 +276,10 @@
- DR-2580C pads the backside of duplex scans
v40 2012-11-01, MAN
- initial DR-9050C, DR-7550C, DR-6050C and DR-3010C support
v41 2013-07-06, MAN
- initial P-208 and P-215 support
- bug fix for calibration of scanners with duplex_offset
- allow duplex_offset to be controlled from config file
SANE FLOW DIAGRAM
@ -324,7 +328,7 @@
#include "canon_dr.h"
#define DEBUG 1
#define BUILD 40
#define BUILD 41
/* values for SANE_DEBUG_CANON_DR env var:
- errors 5
@ -362,6 +366,8 @@ static int global_buffer_size;
static int global_buffer_size_default = 2 * 1024 * 1024;
static int global_padded_read;
static int global_padded_read_default = 0;
static int global_duplex_offset;
static int global_duplex_offset_default = 0;
static char global_vendor_name[9];
static char global_model_name[17];
static char global_version_name[5];
@ -528,6 +534,7 @@ sane_get_devices (const SANE_Device *** device_list, SANE_Bool local_only)
if (buf > 1) {
DBG (5, "sane_get_devices: config option \"padded-read\" "
"(%d) is > 1, ignoring!\n", buf);
continue;
}
DBG (15, "sane_get_devices: setting \"padded-read\" to %d\n",
@ -536,6 +543,32 @@ sane_get_devices (const SANE_Device *** device_list, SANE_Bool local_only)
global_padded_read = buf;
}
/* DUPLEXOFFSET: < 1200 */
else if (!strncmp (lp, "duplex-offset", 13) && isspace (lp[13])) {
int buf;
lp += 13;
lp = sanei_config_skip_whitespace (lp);
buf = atoi (lp);
if (buf > 1200) {
DBG (5, "sane_get_devices: config option \"duplex-offset\" "
"(%d) is > 1200, ignoring!\n", buf);
continue;
}
if (buf < 0) {
DBG (5, "sane_get_devices: config option \"duplex-offset\" "
"(%d) is < 0, ignoring!\n", buf);
continue;
}
DBG (15, "sane_get_devices: setting \"duplex-offset\" to %d\n",
buf);
global_duplex_offset = buf;
}
/* VENDOR: we ingest up to 8 bytes */
else if (!strncmp (lp, "vendor-name", 11) && isspace (lp[11])) {
@ -700,6 +733,7 @@ attach_one (const char *device_name, int connType)
/* config file settings */
s->buffer_size = global_buffer_size;
s->padded_read = global_padded_read;
s->duplex_offset = global_duplex_offset;
/* copy the device name */
strcpy (s->device_name, device_name);
@ -929,10 +963,13 @@ init_inquire (struct scanner *s)
}
/*check for model name*/
if (strncmp ("DR", s->model_name, 2) && strncmp ("CR", s->model_name, 2)) {
if (strncmp ("DR", s->model_name, 2)
&& strncmp ("CR", s->model_name, 2)
&& strncmp ("P-", s->model_name, 2)
) {
DBG (5, "The device at '%s' is reported to be a '%s'\n",
s->device_name, s->model_name);
DBG (5, "This backend only supports Canon CR & DR-series products.\n");
DBG (5, "This backend only supports Canon P-, CR & DR-series products.\n");
return SANE_STATUS_INVAL;
}
@ -1204,7 +1241,7 @@ init_model (struct scanner *s)
s->duplex_interlace = DUPLEX_INTERLACE_FBFB;
s->need_ccal = 1;
s->need_fcal = 1;
s->duplex_offset = 432;
/*s->duplex_offset = 432; now set in config file*/
s->duplex_offset_side = SIDE_BACK;
/*lies*/
@ -1225,7 +1262,7 @@ init_model (struct scanner *s)
s->color_interlace[SIDE_FRONT] = COLOR_INTERLACE_2510;
s->color_interlace[SIDE_BACK] = COLOR_INTERLACE_2510;
s->duplex_interlace = DUPLEX_INTERLACE_2510;
s->duplex_offset = 400;
/*s->duplex_offset = 400; now set in config file*/
s->need_ccal = 1;
s->need_fcal = 1;
s->sw_lut = 1;
@ -1255,7 +1292,7 @@ init_model (struct scanner *s)
s->color_interlace[SIDE_FRONT] = COLOR_INTERLACE_2510;
s->color_interlace[SIDE_BACK] = COLOR_INTERLACE_2510;
s->duplex_interlace = DUPLEX_INTERLACE_2510;
s->duplex_offset = 400;
/*s->duplex_offset = 400; now set in config file*/
s->need_ccal = 1;
s->need_fcal = 1;
s->sw_lut = 1;
@ -1284,7 +1321,7 @@ init_model (struct scanner *s)
s->duplex_interlace = DUPLEX_INTERLACE_FBFB;
s->need_fcal_buffer = 1;
s->bg_color = 0x08;
s->duplex_offset = 840;
/*s->duplex_offset = 840; now set in config file*/
s->sw_lut = 1;
/*lies*/
@ -1317,6 +1354,36 @@ init_model (struct scanner *s)
s->reverse_by_mode[MODE_HALFTONE] = 0;
}
else if (strstr (s->model_name, "P-208")) {
s->color_interlace[SIDE_FRONT] = COLOR_INTERLACE_RRGGBB;
s->color_interlace[SIDE_BACK] = COLOR_INTERLACE_rRgGbB;
s->gray_interlace[SIDE_BACK] = GRAY_INTERLACE_gG;
s->duplex_interlace = DUPLEX_INTERLACE_FBFB;
s->need_ccal = 1;
s->invert_tly = 1;
s->can_color = 1;
s->unknown_byte2 = 0x88;
s->rgb_format = 1;
s->has_ssm_pay_head_len = 1;
s->ppl_mod = 8;
s->ccal_version = 3;
}
else if (strstr (s->model_name, "P-215")) {
s->color_interlace[SIDE_FRONT] = COLOR_INTERLACE_rRgGbB;
s->color_interlace[SIDE_BACK] = COLOR_INTERLACE_RRGGBB;
s->gray_interlace[SIDE_FRONT] = GRAY_INTERLACE_gG;
s->duplex_interlace = DUPLEX_INTERLACE_FBFB;
s->need_ccal = 1;
s->invert_tly = 1;
s->can_color = 1;
s->unknown_byte2 = 0x88;
s->rgb_format = 1;
s->has_ssm_pay_head_len = 1;
s->ppl_mod = 8;
s->ccal_version = 3;
}
DBG (10, "init_model: finish\n");
return SANE_STATUS_GOOD;
@ -2789,6 +2856,9 @@ ssm_buffer (struct scanner *s)
set_SSM_pay_len(cmd, outLen);
memset(out,0,outLen);
if(s->has_ssm_pay_head_len){
set_SSM_pay_head_len(out, SSM_PAY_HEAD_len);
}
set_SSM_page_code(out, SM_pc_buffer);
set_SSM_page_len(out, SSM_PAGE_len);
@ -2844,6 +2914,9 @@ ssm_df (struct scanner *s)
set_SSM_pay_len(cmd, outLen);
memset(out,0,outLen);
if(s->has_ssm_pay_head_len){
set_SSM_pay_head_len(out, SSM_PAY_HEAD_len);
}
set_SSM_page_code(out, SM_pc_df);
set_SSM_page_len(out, SSM_PAGE_len);
@ -2903,6 +2976,9 @@ ssm_do (struct scanner *s)
set_SSM_pay_len(cmd, outLen);
memset(out,0,outLen);
if(s->has_ssm_pay_head_len){
set_SSM_pay_head_len(out, SSM_PAY_HEAD_len);
}
set_SSM_page_code(out, SM_pc_dropout);
set_SSM_page_len(out, SSM_PAGE_len);
@ -3320,7 +3396,7 @@ update_params(struct scanner *s, int calib)
}
/* some scanners need longer scans because front/back is offset */
if(s->u.source == SOURCE_ADF_DUPLEX && s->duplex_offset)
if(s->u.source == SOURCE_ADF_DUPLEX && s->duplex_offset && !calib)
s->s.height = (s->u.br_y-s->u.tl_y+s->duplex_offset) * s->u.dpi_y / 1200;
/* round lines up to even number */
@ -5547,35 +5623,76 @@ write_AFE(struct scanner *s)
unsigned char cmd[COR_CAL_len];
size_t cmdLen = COR_CAL_len;
unsigned char pay[CC_pay_len];
size_t payLen = CC_pay_len;
/*use the longest payload for buffer*/
unsigned char pay[CC3_pay_len];
size_t payLen = CC3_pay_len;
DBG (10, "write_AFE: start\n");
memset(cmd,0,cmdLen);
set_SCSI_opcode(cmd, COR_CAL_code);
set_CC_xferlen(cmd,payLen);
/* newer scanners use a longer cc payload */
if(s->ccal_version == 3){
memset(pay,0,payLen);
set_CC_f_gain(pay,s->c_gain[SIDE_FRONT]);
set_CC_unk1(pay,1);
set_CC_f_offset(pay,s->c_offset[SIDE_FRONT]);
set_CC_unk2(pay,1);
set_CC_exp_f_r1(pay,s->c_exposure[SIDE_FRONT][CHAN_RED]);
set_CC_exp_f_g1(pay,s->c_exposure[SIDE_FRONT][CHAN_GREEN]);
set_CC_exp_f_b1(pay,s->c_exposure[SIDE_FRONT][CHAN_BLUE]);
set_CC_exp_f_r2(pay,s->c_exposure[SIDE_FRONT][CHAN_RED]);
set_CC_exp_f_g2(pay,s->c_exposure[SIDE_FRONT][CHAN_GREEN]);
set_CC_exp_f_b2(pay,s->c_exposure[SIDE_FRONT][CHAN_BLUE]);
memset(cmd,0,cmdLen);
set_SCSI_opcode(cmd, COR_CAL_code);
set_CC_version(cmd,CC3_pay_ver);
set_CC_xferlen(cmd,payLen);
memset(pay,0,payLen);
set_CC_b_gain(pay,s->c_gain[SIDE_BACK]);
set_CC_b_offset(pay,s->c_offset[SIDE_BACK]);
set_CC_exp_b_r1(pay,s->c_exposure[SIDE_BACK][CHAN_RED]);
set_CC_exp_b_g1(pay,s->c_exposure[SIDE_BACK][CHAN_GREEN]);
set_CC_exp_b_b1(pay,s->c_exposure[SIDE_BACK][CHAN_BLUE]);
set_CC_exp_b_r2(pay,s->c_exposure[SIDE_BACK][CHAN_RED]);
set_CC_exp_b_g2(pay,s->c_exposure[SIDE_BACK][CHAN_GREEN]);
set_CC_exp_b_b2(pay,s->c_exposure[SIDE_BACK][CHAN_BLUE]);
set_CC3_gain_f_r(pay,s->c_gain[SIDE_FRONT]);
set_CC3_gain_f_g(pay,s->c_gain[SIDE_FRONT]);
set_CC3_gain_f_b(pay,s->c_gain[SIDE_FRONT]);
set_CC3_off_f_r(pay,s->c_offset[SIDE_FRONT]);
set_CC3_off_f_g(pay,s->c_offset[SIDE_FRONT]);
set_CC3_off_f_b(pay,s->c_offset[SIDE_FRONT]);
set_CC3_exp_f_r(pay,s->c_exposure[SIDE_FRONT][CHAN_RED]);
set_CC3_exp_f_g(pay,s->c_exposure[SIDE_FRONT][CHAN_GREEN]);
set_CC3_exp_f_b(pay,s->c_exposure[SIDE_FRONT][CHAN_BLUE]);
set_CC3_gain_b_r(pay,s->c_gain[SIDE_BACK]);
set_CC3_gain_b_g(pay,s->c_gain[SIDE_BACK]);
set_CC3_gain_b_b(pay,s->c_gain[SIDE_BACK]);
set_CC3_off_b_r(pay,s->c_offset[SIDE_BACK]);
set_CC3_off_b_g(pay,s->c_offset[SIDE_BACK]);
set_CC3_off_b_b(pay,s->c_offset[SIDE_BACK]);
set_CC3_exp_b_r(pay,s->c_exposure[SIDE_BACK][CHAN_RED]);
set_CC3_exp_b_g(pay,s->c_exposure[SIDE_BACK][CHAN_GREEN]);
set_CC3_exp_b_b(pay,s->c_exposure[SIDE_BACK][CHAN_BLUE]);
}
else{
payLen = CC_pay_len;
memset(cmd,0,cmdLen);
set_SCSI_opcode(cmd, COR_CAL_code);
set_CC_version(cmd,CC_pay_ver);
set_CC_xferlen(cmd,payLen);
memset(pay,0,payLen);
set_CC_f_gain(pay,s->c_gain[SIDE_FRONT]);
set_CC_unk1(pay,1);
set_CC_f_offset(pay,s->c_offset[SIDE_FRONT]);
set_CC_unk2(pay,1);
set_CC_exp_f_r1(pay,s->c_exposure[SIDE_FRONT][CHAN_RED]);
set_CC_exp_f_g1(pay,s->c_exposure[SIDE_FRONT][CHAN_GREEN]);
set_CC_exp_f_b1(pay,s->c_exposure[SIDE_FRONT][CHAN_BLUE]);
set_CC_exp_f_r2(pay,s->c_exposure[SIDE_FRONT][CHAN_RED]);
set_CC_exp_f_g2(pay,s->c_exposure[SIDE_FRONT][CHAN_GREEN]);
set_CC_exp_f_b2(pay,s->c_exposure[SIDE_FRONT][CHAN_BLUE]);
set_CC_b_gain(pay,s->c_gain[SIDE_BACK]);
set_CC_b_offset(pay,s->c_offset[SIDE_BACK]);
set_CC_exp_b_r1(pay,s->c_exposure[SIDE_BACK][CHAN_RED]);
set_CC_exp_b_g1(pay,s->c_exposure[SIDE_BACK][CHAN_GREEN]);
set_CC_exp_b_b1(pay,s->c_exposure[SIDE_BACK][CHAN_BLUE]);
set_CC_exp_b_r2(pay,s->c_exposure[SIDE_BACK][CHAN_RED]);
set_CC_exp_b_g2(pay,s->c_exposure[SIDE_BACK][CHAN_GREEN]);
set_CC_exp_b_b2(pay,s->c_exposure[SIDE_BACK][CHAN_BLUE]);
}
ret = do_cmd (
s, 1, 0,
@ -5850,6 +5967,7 @@ default_globals(void)
{
global_buffer_size = global_buffer_size_default;
global_padded_read = global_padded_read_default;
global_duplex_offset = global_duplex_offset_default;
global_vendor_name[0] = 0;
global_model_name[0] = 0;
global_version_name[0] = 0;

Wyświetl plik

@ -46,6 +46,7 @@ scsi CANON DR
# gmail dot com - with canon_dr in the subject line
# DR-2080C (uses weird protocol)
option duplex-offset 840
option vendor-name CANON
option model-name DR-2080C
option version-name XXXX
@ -68,12 +69,14 @@ usb 0x04a9 0x1606
usb 0x04a9 0x1607
# DR-2580C
option duplex-offset 432
usb 0x04a9 0x1608
# DR-3080CII
usb 0x04a9 0x1609
# DR-2050C/SP (uses weird protocol)
option duplex-offset 840
option vendor-name CANON
option model-name DR-2050C
option version-name XXXX
@ -94,6 +97,7 @@ usb 0x04a9 0x2222
usb 0x1083 0x1614
# DR-2510C
option duplex-offset 400
usb 0x1083 0x1617
# DR-X10C
@ -103,9 +107,11 @@ usb 0x1083 0x1618
usb 0x1083 0x161a
# DR-2010C
option duplex-offset 400
usb 0x1083 0x161b
# DR-3010C
option duplex-offset 400
usb 0x1083 0x161d
# DR-7090C
@ -132,3 +138,9 @@ usb 0x1083 0x1638
# CR-135i
usb 0x1083 0x1639
# P-215
usb 0x1083 0x1646
# P-208
usb 0x1083 0x164c

Wyświetl plik

@ -166,6 +166,7 @@ struct scanner
int need_ccal; /* scanner needs software to help with afe calibration */
int need_fcal; /* scanner needs software to help with fine calibration */
int need_fcal_buffer; /* software to apply calibration stored in scanner*/
int ccal_version; /* 0 in most scanners, 3 in newer ones */
int has_counter;
int has_rif;
@ -179,6 +180,7 @@ struct scanner
int has_btc;
int has_ssm; /* older scanners use this set scan mode command */
int has_ssm2; /* newer scanners user this similar command */
int has_ssm_pay_head_len; /* newer scanners put the length twice in ssm */
int can_read_panel;
int can_write_panel;
int rgb_format; /* meaning unknown */

Wyświetl plik

@ -11,9 +11,9 @@
:backend "canon_dr" ; name of backend
:url "http://www.thebility.com/canon/"
:version "38" ; version of backend
:version "41" ; version of backend
:manpage "sane-canon_dr" ; name of manpage (if it exists)
:comment "Backend updated for SANE release 1.0.23, see sane-canon_dr manpage"
:comment "Backend updated for SANE release 1.0.24, see sane-canon_dr manpage"
:devicetype :scanner ; start of a list of devices....
; other types: :stillcam, :vidcam,
; :meta, :api
@ -28,12 +28,24 @@
:status :untested
:comment "Please test!"
:model "CR-50"
:interface "USB"
;:usbid "0x1083" "0x"
:status :untested
:comment "Please test!"
:model "CR-55"
:interface "USB"
:usbid "0x1083" "0x160c"
:status :untested
:comment "Please test!"
:model "CR-80"
:interface "USB"
;:usbid "0x1083" "0x"
:status :untested
:comment "Please test!"
:model "CR-135i"
:interface "USB SCSI"
:usbid "0x1083" "0x1639"
@ -253,3 +265,54 @@
:status :untested
:comment "Please test!"
:model "DR-C125"
:interface "USB"
;:usbid "0x1083" "0x"
:status :untested
:comment "Similar protocol to other canon_dr machines, but unsupported image format."
:model "DR-C130"
:interface "USB"
;:usbid "0x1083" "0x"
:status :untested
:model "DR-G1100"
:interface "USB"
;:usbid "0x1083" "0x"
:status :untested
:model "DR-G1130"
:interface "USB"
;:usbid "0x1083" "0x"
:status :untested
:model "DR-M140"
:interface "USB"
;:usbid "0x1083" "0x"
:status :untested
:model "DR-M160"
:interface "USB"
;:usbid "0x1083" "0x"
:status :untested
:model "P-150"
:interface "USB"
;:usbid "0x1083" "0x"
:status :untested
:model "P-150M"
:interface "USB"
;:usbid "0x1083" "0x"
:status :untested
:model "P-208"
:interface "USB"
:usbid "0x1083" "0x164c"
:status :untested
:model "P-215"
:interface "USB"
:usbid "0x1083" "0x1646"
:status :untested