diff options
Diffstat (limited to 'backend/epjitsu.c')
| -rw-r--r-- | backend/epjitsu.c | 121 | 
1 files changed, 65 insertions, 56 deletions
| diff --git a/backend/epjitsu.c b/backend/epjitsu.c index 6fda662..7430108 100644 --- a/backend/epjitsu.c +++ b/backend/epjitsu.c @@ -3,7 +3,7 @@     This file implements a SANE backend for the Fujitsu fi-60F, the     ScanSnap S300/S1300, and (hopefully) other Epson-based scanners. -   Copyright 2007-2015 by m. allan noah <kitno455 at gmail dot com> +   Copyright 2007-2022 by m. allan noah <kitno455 at gmail dot com>     Copyright 2009 by Richard Goedeken <richard at fascinationsoftware dot com>     Development funded by Microdea, Inc., TrueCheck, Inc. and Archivista, GmbH @@ -155,6 +155,10 @@        v31 2017-04-09, MAN           - hardware gray support for fi-60F/65F (disabled pending calibration)           - merge fi-60F/65F settings +      v32 2022-11-15, MAN +         - fix hanging scan when using source = ADF Back (fixes #601) +      v33 2022-11-17, MAN +         - S1300i: fix color plane offset at 225 and 330 dpi (fixes #538)     SANE FLOW DIAGRAM @@ -203,8 +207,14 @@  #include "epjitsu-cmd.h"  #define DEBUG 1 -#define BUILD 31 +#define BUILD 33 +#ifndef MIN +  #define MIN(a,b) ((a) < (b) ? (a) : (b)) +#endif +#ifndef MAX +  #define MAX(a,b) ((a) > (b) ? (a) : (b)) +#endif  #ifndef MAX3    #define MAX3(a,b,c) ((a) > (b) ? ((a) > (c) ? a : c) : ((b) > (c) ? b : c))  #endif @@ -265,7 +275,7 @@ static struct scanner *scanner_devList = NULL;  SANE_Status  sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize)  { -    authorize = authorize;        /* get rid of compiler warning */ +    (void) authorize;           /* get rid of compiler warning */      DBG_INIT ();      DBG (10, "sane_init: start\n"); @@ -317,7 +327,7 @@ sane_get_devices (const SANE_Device *** device_list, SANE_Bool local_only)      int num_devices=0;      int i=0; -    local_only = local_only;        /* get rid of compiler warning */ +    (void) local_only;          /* get rid of compiler warning */      DBG (10, "sane_get_devices: start\n"); @@ -1137,7 +1147,7 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option)      /* values stored in 1200 dpi units */      /* must be converted to MM for sane */      s->tl_x_range.min = SCANNER_UNIT_TO_FIXED_MM(0); -    s->tl_x_range.max = SCANNER_UNIT_TO_FIXED_MM(get_page_width(s)-s->min_x); +    s->tl_x_range.max = SCANNER_UNIT_TO_FIXED_MM(MAX(0, get_page_width(s)-s->min_x));      s->tl_x_range.quant = MM_PER_UNIT_FIX;      opt->name = SANE_NAME_SCAN_TL_X; @@ -1156,7 +1166,7 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option)      /* values stored in 1200 dpi units */      /* must be converted to MM for sane */      s->tl_y_range.min = SCANNER_UNIT_TO_FIXED_MM(0); -    s->tl_y_range.max = SCANNER_UNIT_TO_FIXED_MM(get_page_height(s)-s->min_y); +    s->tl_y_range.max = SCANNER_UNIT_TO_FIXED_MM(MAX(0, get_page_height(s)-s->min_y));      s->tl_y_range.quant = MM_PER_UNIT_FIX;      opt->name = SANE_NAME_SCAN_TL_Y; @@ -1174,7 +1184,7 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option)      /* values stored in 1200 dpi units */      /* must be converted to MM for sane */      s->br_x_range.min = SCANNER_UNIT_TO_FIXED_MM(s->min_x); -    s->br_x_range.max = SCANNER_UNIT_TO_FIXED_MM(get_page_width(s)); +    s->br_x_range.max = SCANNER_UNIT_TO_FIXED_MM(MAX(s->min_x, get_page_width(s)));      s->br_x_range.quant = MM_PER_UNIT_FIX;      opt->name = SANE_NAME_SCAN_BR_X; @@ -1193,7 +1203,7 @@ sane_get_option_descriptor (SANE_Handle handle, SANE_Int option)      /* values stored in 1200 dpi units */      /* must be converted to MM for sane */      s->br_y_range.min = SCANNER_UNIT_TO_FIXED_MM(s->min_y); -    s->br_y_range.max = SCANNER_UNIT_TO_FIXED_MM(get_page_height(s)); +    s->br_y_range.max = SCANNER_UNIT_TO_FIXED_MM(MAX(s->min_y, get_page_height(s)));      s->br_y_range.quant = MM_PER_UNIT_FIX;      opt->name = SANE_NAME_SCAN_BR_Y; @@ -2042,14 +2052,12 @@ change_params(struct scanner *s)      /* height */      if (s->tl_y > s->max_y - s->min_y)         s->tl_y = s->max_y - s->min_y - s->adf_height_padding; -    if (s->tl_y + s->page_height > s->max_y - s->adf_height_padding) -       s->page_height = s->max_y - s->adf_height_padding - s->tl_y; -    if (s->page_height < s->min_y && s->page_height > 0) -       s->page_height = s->min_y; +    s->page_height = MIN(s->page_height, s->max_y - s->adf_height_padding - s->tl_y); +    if (s->page_height > 0) +       s->page_height = MAX(s->page_height, s->min_y);      if (s->tl_y + s->page_height > s->max_y)         s->tl_y = s->max_y - s->adf_height_padding - s->page_height; -    if (s->tl_y < 0) -       s->tl_y = 0; +    s->tl_y = MAX(s->tl_y, 0);      if (s->page_height > 0) {          s->br_y = s->tl_y + s->page_height; @@ -2059,10 +2067,9 @@ change_params(struct scanner *s)      }      /*width*/ -    if (s->page_width > s->max_x) -       s->page_width = s->max_x; -    else if (s->page_width < s->min_x) -       s->page_width = s->min_x; +    s->page_width = MIN(s->page_width, s->max_x); +    s->page_width = MAX(s->page_width, s->min_x); +      s->tl_x = (s->max_x - s->page_width)/2;      s->br_x = (s->max_x + s->page_width)/2; @@ -2177,7 +2184,7 @@ change_params(struct scanner *s)        /* adf with specified paper size */        s->front.height = SCANNER_UNIT_TO_PIX(s->page_height, s->front.y_res);      } -    s->front.width_pix = s->block_img.width_pix; +    s->front.width_pix = SCANNER_UNIT_TO_PIX(s->page_width, s->resolution * img_heads);      s->front.x_start_offset = (s->block_xfr.image->width_pix - s->front.width_pix)/2;      switch (s->mode) {        case MODE_COLOR: @@ -2310,12 +2317,8 @@ load_lut (unsigned char * lut,    for(i=0;i<=max_in_val;i++){      j = rise*i + shift; -    if(j<out_min){ -      j=out_min; -    } -    else if(j>out_max){ -      j=out_max; -    } +    j = MAX(j, out_min); +    j = MIN(j, out_max);      *lut_p=j;      lut_p++; @@ -2654,7 +2657,7 @@ coarsecal_send_cal(struct scanner *s, unsigned char *pay)      unsigned char stat[1];      size_t cmdLen,statLen,payLen; -    DBG (5, "coarsecal_send_cal: start\n"); +    DBG (10, "coarsecal_send_cal: start\n");      /* send coarse cal (c6) */      cmd[0] = 0x1b;      cmd[1] = 0xc6; @@ -2697,7 +2700,7 @@ coarsecal_send_cal(struct scanner *s, unsigned char *pay)          return SANE_STATUS_IO_ERROR;      } -    DBG (5, "coarsecal_send_cal: finish\n"); +    DBG (10, "coarsecal_send_cal: finish\n");      return ret;  } @@ -2709,7 +2712,7 @@ coarsecal_get_line(struct scanner *s, struct image *img)      unsigned char stat[1];      size_t cmdLen,statLen; -    DBG (5, "coarsecal_get_line: start\n"); +    DBG (10, "coarsecal_get_line: start\n");      /* send scan d2 command */      cmd[0] = 0x1b; @@ -2746,7 +2749,7 @@ coarsecal_get_line(struct scanner *s, struct image *img)      /* convert the raw data into normal packed pixel data */      descramble_raw(s, &s->cal_image); -    DBG (5, "coarsecal_get_line: finish\n"); +    DBG (10, "coarsecal_get_line: finish\n");      return ret;  } @@ -2758,7 +2761,7 @@ coarsecal_dark(struct scanner *s, unsigned char *pay)      int try_count, cal_good[2], x, j;      int param[2], zcount[2], high_param[2], low_param[2], avg[2], maxval[2]; -    DBG (5, "coarsecal_dark: start\n"); +    DBG (10, "coarsecal_dark: start\n");      /* dark cal, lamp off */      ret = lamp(s,0); @@ -2844,7 +2847,7 @@ coarsecal_dark(struct scanner *s, unsigned char *pay)      } /* continue looping for up to 8 tries */ -    DBG (5, "coarsecal_dark: finish\n"); +    DBG (10, "coarsecal_dark: finish\n");      return ret;  } @@ -2857,7 +2860,7 @@ coarsecal_light(struct scanner *s, unsigned char *pay)      int param[2], zcount[2], high_param[2], low_param[2], avg[2];      int rgb_avg[2][3], rgb_hicount[2][3]; -    DBG (5, "coarsecal_light: start\n"); +    DBG (10, "coarsecal_light: start\n");      /* light cal, lamp on */      ret = lamp(s,1); @@ -2961,7 +2964,7 @@ coarsecal_light(struct scanner *s, unsigned char *pay)          }      } -    DBG (5, "coarsecal_light: finish\n"); +    DBG (10, "coarsecal_light: finish\n");      return ret;  } @@ -3023,6 +3026,8 @@ finecal_send_cal(struct scanner *s)      unsigned char *p_out, *p_in = s->sendcal.buffer;      int planes; +    DBG (10, "finecal_send_cal: start\n"); +      if(s->model == MODEL_FI60F || s->model == MODEL_FI65F)        planes = 3;      if(s->model == MODEL_S300 || s->model == MODEL_S1300i) @@ -3165,6 +3170,7 @@ finecal_send_cal(struct scanner *s)          return SANE_STATUS_IO_ERROR;      } +    DBG (10, "finecal_send_cal: finish\n");      return ret;  } @@ -3182,6 +3188,8 @@ finecal_get_line(struct scanner *s, struct image *img)      int round_offset = img->height / 2;      int i, j, k; +    DBG (10, "finecal_get_line: start\n"); +      /* ask for 16 lines */      ret = set_window(s, WINDOW_FINECAL);      if(ret){ @@ -3238,6 +3246,8 @@ finecal_get_line(struct scanner *s, struct image *img)              avgpix[j] = (total + round_offset) / img->height;          }      } + +    DBG (10, "finecal_get_line: finish\n");      return ret;  } @@ -3385,8 +3395,8 @@ finecal(struct scanner *s)                      else                          s->sendcal.buffer[idx * 2 + 1] = newgain;                      /* update statistics */ -                    if (pixvalue < min_value[i][k]) min_value[i][k] = pixvalue; -                    if (pixvalue > max_value[i][k]) max_value[i][k] = pixvalue; +                    min_value[i][k] = MIN(min_value[i][k], pixvalue); +                    max_value[i][k] = MAX(max_value[i][k], pixvalue);                      avg_value[i][k] += pixerror;                      variance[i][k] += (pixerror * pixerror);                      idx++; @@ -3658,13 +3668,8 @@ send_lut (struct scanner *s)      for(i=0;i<width;i++){        j=slope*i + offset + b; -      if(j<0){ -        j=0; -      } - -      if(j>(height-1)){ -        j=height-1; -      } +      j = MAX(j, 0); +      j = MIN(j, height-1);          if (s->model == MODEL_S1100){              /*only one table, be order*/ @@ -4078,9 +4083,7 @@ sane_read (SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len, SANE_Int * len      }      *len = page->bytes_scanned - page->bytes_read; -    if(*len > max_len){ -        *len = max_len; -    } +    *len = MIN(*len, max_len);      if(*len){          DBG (10, "sane_read: copy rx:%d tx:%d tot:%d len:%d\n", @@ -4088,12 +4091,12 @@ sane_read (SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len, SANE_Int * len          memcpy(buf, page->image->buffer + page->bytes_read, *len);          page->bytes_read += *len; +    } -        /* sent it all, return eof on next read */ -        if(page->bytes_read == page->bytes_scanned && s->fullscan.done){ -            DBG (10, "sane_read: side done\n"); -            page->done = 1; -        } +    /* sent it all, return eof on next read */ +    if(page->bytes_read == page->bytes_scanned && s->fullscan.done){ +        DBG (10, "sane_read: side done\n"); +        page->done = 1;      }      DBG (10, "sane_read: finish si:%d len:%d max:%d\n",s->side,*len,max_len); @@ -4161,6 +4164,7 @@ descramble_raw(struct scanner *s, struct transfer * tp)          for (j = 0; j < height; j++){             /* row (y)*/            int curr_col = 0;            int r=0, g=0, b=0, ppc=0; +          int g_offset=0, b_offset=0;            for (k = 0; k <= tp->plane_width; k++){  /* column (x) */              int this_col = k*tp->image->x_res/tp->x_res; @@ -4185,14 +4189,20 @@ descramble_raw(struct scanner *s, struct transfer * tp)                break;              } +            /* if we're using an S1300i with scan resolution 225 or 300, on AC power, the color planes are shifted */ +            if(s->model == MODEL_S1300i && !s->usb_power && (tp->x_res == 225 || tp->x_res == 300) && tp != &s->cal_image && k + 2 <= tp->plane_width){ +              g_offset = 3; +              b_offset = 6; +            } +              /*red is first*/              r += tp->raw_data[j*tp->line_stride + k*3 + i];              /*green is second*/ -            g += tp->raw_data[j*tp->line_stride + tp->plane_stride + k*3 + i]; +            g += tp->raw_data[j*tp->line_stride + tp->plane_stride + k*3 + i + g_offset];              /*blue is third*/ -            b += tp->raw_data[j*tp->line_stride + 2*tp->plane_stride + k*3 + i]; +            b += tp->raw_data[j*tp->line_stride + 2*tp->plane_stride + k*3 + i + b_offset];              ppc++;            } @@ -4341,8 +4351,8 @@ read_from_scanner(struct scanner *s, struct transfer * tp)      size_t bufLen;      /* determine amount to ask for, S1300i wants big requests */ -    if(bytes > remainBlock && s->model != MODEL_S1300i){ -        bytes = remainBlock; +    if(s->model != MODEL_S1300i){ +        bytes = MIN(bytes, remainBlock);      }      if (tp->image == NULL) @@ -4932,8 +4942,7 @@ maxStringSize (const SANE_String_Const strings[])    for (i = 0; strings[i]; ++i) {      size = strlen (strings[i]) + 1; -    if (size > max_size) -      max_size = size; +    max_size = MAX(max_size, size);    }    return max_size; | 
