[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