From 84357741a6a6e6430f199b2c3f7498e0e97da9ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Sun, 12 Feb 2023 17:35:53 +0100 Subject: New upstream version 1.2.1 --- backend/epjitsu.c | 121 +++++++++++++++++++++++++++++------------------------- 1 file changed, 65 insertions(+), 56 deletions(-) (limited to 'backend/epjitsu.c') 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 + Copyright 2007-2022 by m. allan noah Copyright 2009 by Richard Goedeken 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(jout_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(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; -- cgit v1.2.3