[sane-devel] [PATCH 10/10] epjitsu: ScanSnap S1100 support
Hiroshi Miura
miurahr at linux.com
Sun Nov 4 10:38:41 UTC 2012
Add S1100 support
The ideas and cmd data are comes from:
http://ubuntuforums.org/showthread.php?t=1678335
TBD: test on S1100, I don't have a machine.
Signed-off-by: Hiroshi Miura <miurahr at linux.com>
---
backend/epjitsu-cmd.h | 88 +++++++++++++++++
backend/epjitsu.c | 217 +++++++++++++++++++++++++++++++++++------
backend/epjitsu.conf.in | 4 +
backend/epjitsu.h | 3 +
doc/descriptions/epjitsu.desc | 4 +-
5 files changed, 285 insertions(+), 31 deletions(-)
diff --git a/backend/epjitsu-cmd.h b/backend/epjitsu-cmd.h
index 2e914d9..4bc8052 100644
--- a/backend/epjitsu-cmd.h
+++ b/backend/epjitsu-cmd.h
@@ -38,6 +38,10 @@ static unsigned char coarseCalData_S300[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x24, 0x00, 0x28, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
+static unsigned char coarseCalData_S1100[] = {
+0x00, 0x00, 0x00, 0x00, 0x00, 0x25, 0x00, 0x25, 0x00, 0x00, 0x00, 0x26, 0x00, 0x26, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
/*************** fi-60F 150dpi *************/
/* 1b d1 (set window) before coarse cal (read 1 line of 0x____ bytes) */
@@ -457,3 +461,87 @@ static unsigned char setWindowScan_S300_300_U[] = {
};
/*************** S300 600dpi USB is same as AC power *************/
+
+/*************** S1100 300dpi USB *************/
+/* 1b d1 (set window) before coarse cal (read 1 line of 0x45a0 bytes) */
+static unsigned char setWindowCoarseCal_S1100_300_U[] = {
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x01, 0x2c, 0x01, 0x2c, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x58, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+0x00, 0x05, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x01, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+/* 1b d1 (set window) before fine cal (read 16 lines of 0x45a0 bytes) */
+static unsigned char setWindowFineCal_S1100_300_U[] = {
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x01, 0x2c, 0x03, 0x20, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x58, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+0x00, 0x05, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x01, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+/* 1b d1 (set window) before gain/offset tables (write 1 line of 0x45a0 bytes) */
+static unsigned char setWindowSendCal_S1100_300_U[] = {
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x01, 0x2c, 0x01, 0x2c, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0xd0, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+0x00, 0x05, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x01, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+/* 1b c3 (gain?) command header */
+static unsigned char sendCal1Header_S1100_300_U[] = { /* plus 0x45a0 data bytes */
+0x1e, 0x10, 0x1e, 0x10, 0x1e, 0x10, 0x1e, 0x10, 0x1e, 0x10, 0x1e, 0x10, 0x00, 0x03
+};
+/* 1b c4 (offset?) command header */
+static unsigned char sendCal2Header_S1100_300_U[] = { /* plus 0x45a0 data bytes */
+0x63, 0x86, 0x63, 0x86, 0x63, 0x86, 0x07
+};
+/* 1b d1 (set window) before scan */
+static unsigned char setWindowScan_S1100_300_U[] = {
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x01, 0x2c, 0x01, 0x2c, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x58, 0x00, 0x00, 0x1b, 0xe1, 0x00, 0x00,
+0x00, 0x05, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x80, 0x80, 0x01, 0x3a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+/*************** S1100 600dpi USB *************/
+/* 1b d1 (set window) before coarse cal (read 1 line of 0x3e20 bytes) */
+static unsigned char setWindowCoarseCal_S1100_600_U[] = {
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x02, 0x58, 0x02, 0x58, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xf0, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+0x00, 0x05, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x02, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+/* 1b d1 (set window) before fine cal (read 16 lines of 0x3e20 bytes) */
+static unsigned char setWindowFineCal_S1100_600_U[] = {
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x02, 0x58, 0x03, 0x20, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xf0, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+0x00, 0x05, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x02, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+/* 1b d1 (set window) before gain/offset tables (write 1 line of 0x7c40 bytes) */
+static unsigned char setWindowSendCal_S1100_600_U[] = {
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x02, 0x58, 0x02, 0x58, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+0x00, 0x05, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x02, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+/* 1b c3 (gain?) command header */
+static unsigned char sendCal1Header_S1100_600_U[] = { /* plus 0x7c40 data bytes */
+0xff, 0x11, 0xff, 0x11, 0xff, 0x11, 0xff, 0x11, 0xff, 0x11, 0xff, 0x11, 0x00, 0x03
+};
+/* 1b c4 (offset?) command header */
+static unsigned char sendCal2Header_S1100_600_U[] = { /* plus 0x7c40 data bytes */
+0x4b, 0x81, 0x4b, 0x81, 0x4b, 0x81, 0x07
+};
+/* 1b d1 (set window) before scan */
+static unsigned char setWindowScan_S1100_600_U[] = {
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x02, 0x58, 0x02, 0x58, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xf0, 0x00, 0x00, 0x37, 0xbf, 0x00, 0x00,
+0x00, 0x05, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x80, 0x80, 0x01, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
diff --git a/backend/epjitsu.c b/backend/epjitsu.c
index 91b0d59..a995076 100644
--- a/backend/epjitsu.c
+++ b/backend/epjitsu.c
@@ -474,6 +474,7 @@ attach_one (const char *name)
s->model = MODEL_S300;
s->has_adf = 1;
+ s->has_adf_duplex = 1;
s->x_res_150 = 1;
s->x_res_225 = 1;
s->x_res_300 = 1;
@@ -484,14 +485,37 @@ attach_one (const char *name)
s->y_res_600 = 1;
s->source = SOURCE_ADF_FRONT;
- s->mode = MODE_LINEART;
+ s->mode = MODE_LINEART;
s->resolution_x = 300;
s->page_height = 11.5 * 1200;
s->threshold = 120;
s->threshold_curve = 55;
}
+ else if (strstr (s->sane.model, "S1100")){
+ DBG (15, "attach_one: Found S1100\n");
+ s->model = MODEL_S1100;
+ s->usb_power = 1;
+ s->has_adf = 1;
+ s->has_adf_duplex = 0;
+ s->x_res_150 = 0;
+ s->x_res_225 = 0;
+ s->x_res_300 = 1;
+ s->x_res_600 = 1;
+ s->y_res_150 = 0;
+ s->y_res_225 = 0;
+ s->y_res_300 = 1;
+ s->y_res_600 = 1;
+
+ s->source = SOURCE_ADF_FRONT;
+ s->mode = MODE_LINEART;
+ s->resolution_x = 300;
+ s->page_height = 11.5 * 1200;
+
+ s->threshold = 120;
+ s->threshold_curve = 55;
+ }
else if (strstr (s->sane.model, "fi-60F")){
DBG (15, "attach_one: Found fi-60F\n");
@@ -506,7 +530,7 @@ attach_one (const char *name)
s->y_res_600 = 1;
s->source = SOURCE_FLATBED;
- s->mode = MODE_COLOR;
+ s->mode = MODE_COLOR;
s->resolution_x = 300;
s->page_height = 5.83 * 1200;
@@ -948,8 +972,10 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option)
}
if(s->has_adf){
s->source_list[i++]=STRING_ADFFRONT;
- s->source_list[i++]=STRING_ADFBACK;
- s->source_list[i++]=STRING_ADFDUPLEX;
+ if(s->has_adf_duplex){
+ s->source_list[i++]=STRING_ADFBACK;
+ s->source_list[i++]=STRING_ADFDUPLEX;
+ }
}
s->source_list[i]=NULL;
@@ -1769,6 +1795,18 @@ static struct model_res settings[] = {
setWindowSendCal_FI60F_600, sendCal1Header_FI60F_600,
sendCal2Header_FI60F_600, setWindowScan_FI60F_600 },
+ /*S1100 USB*/
+/* model xres yres u mxx mnx mxy mny actw reqw hedw padw bh calw cal_hedw cal_reqw */
+ { MODEL_S1100, 300, 300, 1, 2592, 32, 5324, 32, 8912/3, 3160/3, 8912/3-3160/3, 2592, 58, 8912/3, 3160/3, 2592,
+ setWindowCoarseCal_S1100_300_U, setWindowFineCal_S1100_300_U,
+ setWindowSendCal_S1100_300_U, sendCal1Header_S1100_300_U,
+ sendCal2Header_S1100_300_U, setWindowScan_S1100_300_U },
+
+ { MODEL_S1100, 600, 600, 1, 5184, 32, 10648, 32, 15904/3, 5360/3, 15904/3-5360/3, 5184, 32, 15904/3, 5360/3, 5184,
+ setWindowCoarseCal_S1100_600_U, setWindowFineCal_S1100_600_U,
+ setWindowSendCal_S1100_600_U, sendCal1Header_S1100_600_U,
+ sendCal2Header_S1100_600_U, setWindowScan_S1100_600_U },
+
{ MODEL_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
NULL, NULL, NULL, NULL, NULL, NULL },
@@ -1835,6 +1873,11 @@ change_params(struct scanner *s)
img_heads = 1; /* image width is the same as the plane width on the S300 */
img_pages = 2;
}
+ else if (s->model == MODEL_S1100)
+ {
+ img_heads = 1; /* image width is the same as the plane width on the S1000 */
+ img_pages = 1;
+ }
else /* (s->model == MODEL_FI60F) */
{
img_heads = 3; /* image width is 3* the plane width on the FI-60F */
@@ -2731,6 +2774,9 @@ coarsecal(struct scanner *s)
if(s->model == MODEL_S300){
memcpy(pay,coarseCalData_S300,payLen);
}
+ else if(s->model == MODEL_S1100){
+ memcpy(pay,coarseCalData_S1100,payLen);
+ }
else{
memcpy(pay,coarseCalData_FI60F,payLen);
}
@@ -2742,8 +2788,13 @@ coarsecal(struct scanner *s)
return ret;
}
- ret = coarsecal_dark(s, pay);
- ret = coarsecal_light(s, pay);
+ if(s->model == MODEL_S1100){
+ ret = coarsecal_send_cal(s, pay);
+ }
+ else{
+ ret = coarsecal_dark(s, pay);
+ ret = coarsecal_light(s, pay);
+ }
DBG (10, "coarsecal: finish\n");
return ret;
@@ -2762,7 +2813,14 @@ finecal_send_cal(struct scanner *s)
int i, j, k;
unsigned short *p_out, *p_in = (unsigned short *) s->sendcal.buffer;
- int planes = (s->model == MODEL_S300) ? 2 : 3;
+ int planes;
+
+ if(s->model == MODEL_FI60F)
+ planes = 3;
+ if(s->model == MODEL_S300)
+ planes = 2;
+ if(s->model == MODEL_S1100)
+ planes = 1;
/* scramble the raster buffer data into scanner raw format */
memset(s->cal_data.raw_data, 0, s->cal_data.line_stride);
@@ -2949,13 +3007,21 @@ finecal(struct scanner *s)
{
SANE_Status ret = SANE_STATUS_GOOD;
- const int max_pages = (s->model == MODEL_S300 ? 2 : 1);
+ int max_pages;
int gain_delta = 0xff - 0xbf;
float *gain_slope, *last_error;
int i, j, k, idx, try_count, cal_good;
DBG (10, "finecal: start\n");
+ if (s->model == MODEL_S300) { /* S300, S1300 */
+ max_pages = 2;
+ }
+ else /* fi-60f, S1100 */
+ {
+ max_pages = 1;
+ }
+
/* set fine dark offset to 0 and fix all fine gains to lowest parameter (0xFF) */
for (i = 0; i < s->sendcal.width_bytes * s->sendcal.pages / 2; i++)
{
@@ -3290,16 +3356,31 @@ send_lut (struct scanner *s)
size_t cmdLen = 2;
unsigned char stat[1];
size_t statLen = 1;
- unsigned char out[0x6000];
- size_t outLen = 0x6000;
+ unsigned char *out;
+ size_t outLen;
int i, j;
double b, slope, offset;
- int width = outLen / 6; /* 3 colors, 2 bytes */
- int height = width; /* square table */
+ int width;
+ int height;
DBG (10, "send_lut: start\n");
+ if (s->model == MODEL_S1100){
+ outLen = 0x200;
+ width = outLen / 2; /* 1 color, 2 bytes */
+ height = width; /* square table */
+ }
+ else {
+ outLen = 0x6000;
+ width = outLen / 6; /* 3 colors, 2 bytes */
+ height = width; /* square table */
+ }
+ out = ( unsigned char *)malloc(outLen*sizeof(unsigned char));
+ if (out == NULL){
+ return SANE_STATUS_NO_MEM;
+ }
+
/* contrast is converted to a slope [0,90] degrees:
* first [-127,127] to [0,254] then to [0,1]
* then multiply by PI/2 to convert to radians
@@ -3330,18 +3411,25 @@ send_lut (struct scanner *s)
if(j>(height-1)){
j=height-1;
}
-
- /*first table, le order*/
- out[i*2] = j & 0xff;
- out[i*2+1] = (j >> 8) & 0x0f;
-
- /*second table, le order*/
- out[width*2 + i*2] = j & 0xff;
- out[width*2 + i*2+1] = (j >> 8) & 0x0f;
- /*third table, le order*/
- out[width*4 + i*2] = j & 0xff;
- out[width*4 + i*2+1] = (j >> 8) & 0x0f;
+ if (s->model == MODEL_S1100){
+ /*only one table, be order*/
+ out[i*2] = (j >> 8) & 0xff;
+ out[i*2+1] = j & 0xff;
+ }
+ else {
+ /*first table, le order*/
+ out[i*2] = j & 0xff;
+ out[i*2+1] = (j >> 8) & 0x0f;
+
+ /*second table, le order*/
+ out[width*2 + i*2] = j & 0xff;
+ out[width*2 + i*2+1] = (j >> 8) & 0x0f;
+
+ /*third table, le order*/
+ out[width*4 + i*2] = j & 0xff;
+ out[width*4 + i*2+1] = (j >> 8) & 0x0f;
+ }
}
ret = do_cmd(
@@ -3510,7 +3598,7 @@ scan(struct scanner *s)
DBG (10, "scan: start\n");
- if(s->model == MODEL_S300){
+ if(s->model == MODEL_S300 || s->model == MODEL_S1100){
cmd[1] = 0xd6;
}
@@ -3570,7 +3658,27 @@ sane_read (SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len, SANE_Int * len
/* have sent all of current buffer */
if(s->fullscan.done && page->done){
DBG (10, "sane_read: returning eof\n");
- return SANE_STATUS_EOF;
+
+ /*S1100 needs help to turn off button*/
+ if(s->model == MODEL_S1100){
+ usleep(15000);
+
+ /* eject paper */
+ ret = object_position(s,EPJITSU_PAPER_EJECT);
+ if (ret != SANE_STATUS_GOOD && ret != SANE_STATUS_NO_DOCS) {
+ DBG (5, "sane_read: ERROR: failed to eject\n");
+ return ret;
+ }
+
+ /* reset flashing button? */
+ ret = six5(s);
+ if (ret != SANE_STATUS_GOOD) {
+ DBG (5, "sane_read: ERROR: failed to six6\n");
+ return ret;
+ }
+ }
+
+ return SANE_STATUS_EOF;
}
/* scan not finished, get more into block buffer */
@@ -3586,8 +3694,8 @@ sane_read (SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len, SANE_Int * len
DBG (15, "sane_read: shrinking block to %lu\n", (unsigned long)remainTotal);
s->block_xfr.total_bytes = remainTotal;
}
- /* send d3 cmd for S300 */
- if(s->model == MODEL_S300)
+ /* send d3 cmd for S300, S1100, S1300 */
+ if(s->model == MODEL_S300 || s->model == MODEL_S1100)
{
unsigned char cmd[] = {0x1b, 0xd3};
size_t cmdLen = 2;
@@ -3629,8 +3737,8 @@ sane_read (SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len, SANE_Int * len
s->block_xfr.done = 0;
- /* get the 0x43 cmd for the S300 */
- if(s->model == MODEL_S300){
+ /* get the 0x43 cmd for the S300, S1100, S1300 */
+ if(s->model == MODEL_S300 || s->model == MODEL_S1100){
unsigned char cmd[] = {0x1b, 0x43};
size_t cmdLen = 2;
@@ -3726,6 +3834,42 @@ sane_read (SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len, SANE_Int * len
return ret;
}
+static SANE_Status
+six5 (struct scanner *s)
+{
+ SANE_Status ret = SANE_STATUS_GOOD;
+
+ unsigned char cmd[2];
+ size_t cmdLen = sizeof(cmd);
+ unsigned char stat[1];
+ size_t statLen = sizeof(stat);
+
+ DBG (10, "six5: start\n");
+
+ cmd[0] = 0x1b;
+ cmd[1] = 0x65;
+ statLen = 1;
+
+ ret = do_cmd(
+ s, 0,
+ cmd, cmdLen,
+ NULL, 0,
+ stat, &statLen
+ );
+ if(ret){
+ DBG (5, "six5: error sending cmd\n");
+ return ret;
+ }
+ if(stat[0] != 6){
+ DBG (5, "six5: cmd bad status? %d\n",stat[0]);
+ return SANE_STATUS_IO_ERROR;
+ }
+
+ DBG (10, "six5: finish\n");
+
+ return ret;
+}
+
/* de-scrambles the raw data from the scanner into the image buffer */
static SANE_Status
descramble_raw(struct scanner *s, struct transfer * tp)
@@ -3746,6 +3890,21 @@ descramble_raw(struct scanner *s, struct transfer * tp)
*p_out++ = *p_in;
}
}
+ else if (s->model == MODEL_S1100){
+ for (j = 0; j < height; j++){ /* row (y)*/
+ for (k = 0; k <= tp->plane_width; k++){ /* column (x) */
+ /*red is second*/
+ p_in = (unsigned char *) tp->raw_data + (j*tp->line_stride) + (tp->plane_stride) + k;
+ *p_out++ = *p_in;
+ /*green is third*/
+ p_in = (unsigned char *) tp->raw_data + (j*tp->line_stride) + (2*tp->plane_stride) + k;
+ *p_out++ = *p_in;
+ /*blue is first*/
+ p_in = (unsigned char *) tp->raw_data + (j*tp->line_stride) + k;
+ *p_out++ = *p_in;
+ }
+ }
+ }
else /* MODEL_FI60F */
{
for (i = 0; i < height; i++) /* row (y)*/
diff --git a/backend/epjitsu.conf.in b/backend/epjitsu.conf.in
index cabe6b2..a5d882d 100644
--- a/backend/epjitsu.conf.in
+++ b/backend/epjitsu.conf.in
@@ -32,6 +32,10 @@ usb 0x04c5 0x1156
firmware @DATADIR@/sane/epjitsu/300M_0C00.nal
usb 0x04c5 0x117f
+# Fujitsu S1100
+firmware @DATADIR@/sane/epjitsu/1100_0A00.nal
+usb 0x04c5 0x1200
+
# Fujitsu S1300
firmware @DATADIR@/sane/epjitsu/1300_0C26.nal
usb 0x04c5 0x11ed
diff --git a/backend/epjitsu.h b/backend/epjitsu.h
index 3d70e73..b96adf9 100644
--- a/backend/epjitsu.h
+++ b/backend/epjitsu.h
@@ -96,6 +96,7 @@ struct scanner
int has_fb;
int has_adf;
+ int has_adf_duplex;
int x_res_150;
int x_res_225;
int x_res_300;
@@ -259,6 +260,7 @@ struct scanner
#define MODEL_NONE 0
#define MODEL_S300 1
#define MODEL_FI60F 2
+#define MODEL_S1100 3
#define USB_COMMAND_TIME 10000
#define USB_DATA_TIME 10000
@@ -363,6 +365,7 @@ static SANE_Status teardown_buffers(struct scanner *s);
static SANE_Status setup_buffers(struct scanner *s);
static SANE_Status object_position(struct scanner *s, int ingest);
+static SANE_Status six5 (struct scanner *s);
static SANE_Status coarsecal(struct scanner *s);
static SANE_Status finecal(struct scanner *s);
static SANE_Status send_lut(struct scanner *s);
diff --git a/doc/descriptions/epjitsu.desc b/doc/descriptions/epjitsu.desc
index 7c453df..8eaebc2 100644
--- a/doc/descriptions/epjitsu.desc
+++ b/doc/descriptions/epjitsu.desc
@@ -42,9 +42,9 @@
:model "ScanSnap S1100"
:interface "USB"
-:status :unsupported
+:status :untested
:usbid "0x04c5" "0x1200"
-:comment "Beta version of backend source available, which works well, but breaks support for other epjitsu scanners. See http://ubuntuforums.org/showthread.php?t=1678335"
+:comment "Test needed."
:model "ScanSnap S1300"
:interface "USB"
--
1.7.9.5
More information about the sane-devel
mailing list