|
View:
New views
1 Messages
—
Rating Filter:
Alert me
|
|
|
[PATCH][RFC] gt68xx backend: sheetfed calibration WIP Hello,
thanks for another hardware donation from Jack McGill (an OpticSlim M12), I have started to work on adding sheet fed scanner calibration for gt68xx based scanners. Since to my knowledge there is no active maintainer for this backend, I submit the first patches done so I can get feedback before committing anything. The appended patches bring only calibration for the M12 for 100 dpi full width scans for now. It works by adding a gt68xx_sheetfed_calibrate() function. It is called whenever the OPT_CALIBRATE button option is set. It then find a white area on the inserted document and runs the existing calibration code. Once the corresponding image GT68xx_Calibrator are created, all subsequent 100 dpi scans can be done with image quality corrections. The new code is guarded by a device specific flag, so existing device aren't impacted and only tested device can use this calibration. In its current form, it only works for 100 dpi full width scans, and white area detection is picky. The next steps I plan are: - extend the GT68xx_Scanner struct to keep per dpi calibration data - improve calibration function do calibration for all available resolution in one call - build needed GT68xx_Calibrator with these data before each scan - make the calibration persist in file I don't expect to have all this finished soon, so I don't think anything should bet committed before next release. Regards, Stef [0001-add-GT68XX_FLAG_HAS_CALIBRATE-flag.patch] From f4de7bf40dc7e83752ec23787fc16009fb2f4152 Mon Sep 17 00:00:00 2001 From: =?ISO-8859-1?q?St=E9phane=20Voltz?= <stef.dev@...> Date: Wed, 11 Nov 2009 07:46:34 +0100 Subject: [PATCH 1/5] add GT68XX_FLAG_HAS_CALIBRATE flag - add a flag to handle the case of sheetfed scanners that will be calibrated using a dedicated function that uses an external calibration sheet - enable image OPT_QUALITY_CAL for scanners with GT68XX__FLAG_HAS_CALIBRATE --- backend/gt68xx.c | 10 ++++++++-- backend/gt68xx_low.h | 2 ++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/backend/gt68xx.c b/backend/gt68xx.c index 5b8ac9f..55a6726 100644 --- a/backend/gt68xx.c +++ b/backend/gt68xx.c @@ -638,7 +638,9 @@ init_options (GT68xx_Scanner * s) s->val[OPT_QUALITY_CAL].w = SANE_TRUE; if (!debug_options) DISABLE (OPT_QUALITY_CAL); - if (s->dev->model->flags & GT68XX_FLAG_SHEET_FED) + /* we disable image correction for scanners that can't calibrate */ + if ((s->dev->model->flags & GT68XX_FLAG_SHEET_FED) + &&(!(s->dev->model->flags & GT68XX_FLAG_HAS_CALIBRATE))) { s->val[OPT_QUALITY_CAL].w = SANE_FALSE; DISABLE (OPT_QUALITY_CAL); @@ -1833,7 +1835,11 @@ sane_start (SANE_Handle handle) else scan_request.backtrack_lines = 0; - RIE (gt68xx_scanner_calibrate (s, &scan_request)); + /* don't call calibration for scanners that use sheetfed_calibrate */ + if(!(s->dev->model->flags & GT68XX_FLAG_HAS_CALIBRATE)) + { + RIE (gt68xx_scanner_calibrate (s, &scan_request)); + } RIE (gt68xx_scanner_start_scan (s, &scan_request, &scan_params)); for (i = 0; i < scan_params.overscan_lines; ++i) diff --git a/backend/gt68xx_low.h b/backend/gt68xx_low.h index 182c748..4c06fc9 100644 --- a/backend/gt68xx_low.h +++ b/backend/gt68xx_low.h @@ -113,6 +113,8 @@ #define GT68XX_FLAG_USE_OPTICAL_X (1 << 10) /* Use optical xdpi for 50 dpi and below */ #define GT68XX_FLAG_ALWAYS_LINEMODE (1 << 11) /* Linemode must be used for any resolution */ #define GT68XX_FLAG_SHEET_FED (1 << 12) /* we have a sheet fed scanner */ +#define GT68XX_FLAG_HAS_CALIBRATE (1 << 13) /* for sheet fed scanners that be calibrated with + an calibration sheet */ /* Forward typedefs */ typedef struct GT68xx_USB_Device_Entry GT68xx_USB_Device_Entry; -- 1.6.5 [0003-add-an-OPT_CALIBRATE-option.patch] From d9cc01fd8994844be985c8a570b2ca8bf07d6d2c Mon Sep 17 00:00:00 2001 From: =?ISO-8859-1?q?St=E9phane=20Voltz?= <stef.dev@...> Date: Wed, 11 Nov 2009 08:04:41 +0100 Subject: [PATCH 3/5] add an OPT_CALIBRATE option - add an OPT_CALIBRATION option - call gt68xx_sheetfed_scanner_calibrate() when the OPT_CALIBRATE option is set --- backend/gt68xx.c | 33 +++++++++++++++++++++++++++++++-- backend/gt68xx_high.h | 4 ++++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/backend/gt68xx.c b/backend/gt68xx.c index 55a6726..b02e749 100644 --- a/backend/gt68xx.c +++ b/backend/gt68xx.c @@ -747,6 +747,31 @@ init_options (GT68xx_Scanner * s) s->opt[OPT_BR_Y].constraint.range = &y_range; s->val[OPT_BR_Y].w = y_range.max; + /* sensor group, mainly for sheet fed scanners calibration + * for now */ + if (s->dev->model->flags & GT68XX_FLAG_HAS_CALIBRATE) + { + /* sensor/button group */ + s->opt[OPT_SENSOR_GROUP].name = SANE_NAME_SENSORS; + s->opt[OPT_SENSOR_GROUP].title = SANE_TITLE_SENSORS; + s->opt[OPT_SENSOR_GROUP].desc = SANE_DESC_SENSORS; + s->opt[OPT_SENSOR_GROUP].type = SANE_TYPE_GROUP; + s->opt[OPT_SENSOR_GROUP].constraint_type = SANE_CONSTRAINT_NONE; + + /* calibrate button */ + s->opt[OPT_CALIBRATE].name = "calibrate"; + s->opt[OPT_CALIBRATE].title = SANE_I18N ("Calibrate"); + s->opt[OPT_CALIBRATE].desc = + SANE_I18N ("Start calibration using special sheet"); + s->opt[OPT_CALIBRATE].type = SANE_TYPE_BUTTON; + s->opt[OPT_CALIBRATE].unit = SANE_UNIT_NONE; + s->opt[OPT_CALIBRATE].cap = + SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT | SANE_CAP_ADVANCED | + SANE_CAP_AUTOMATIC; + s->val[OPT_CALIBRATE].b = 0; + } + + RIE (calc_parameters (s)); DBG (5, "init_options: exit\n"); @@ -1506,7 +1531,7 @@ sane_control_option (SANE_Handle handle, SANE_Int option, SANE_Action action, void *val, SANE_Int * info) { GT68xx_Scanner *s = handle; - SANE_Status status; + SANE_Status status = SANE_STATUS_GOOD; SANE_Word cap; SANE_Int myinfo = 0; @@ -1705,6 +1730,10 @@ sane_control_option (SANE_Handle handle, SANE_Int option, myinfo |= SANE_INFO_RELOAD_OPTIONS; break; + case OPT_CALIBRATE: + status = gt68xx_sheetfed_scanner_calibrate (s); + break; + default: DBG (2, "sane_control_option: can't set unknown option %d\n", option); @@ -1720,7 +1749,7 @@ sane_control_option (SANE_Handle handle, SANE_Int option, *info = myinfo; DBG (5, "sane_control_option: exit\n"); - return SANE_STATUS_GOOD; + return status; } SANE_Status diff --git a/backend/gt68xx_high.h b/backend/gt68xx_high.h index 7ef8db4..7510cad 100644 --- a/backend/gt68xx_high.h +++ b/backend/gt68xx_high.h @@ -213,6 +213,10 @@ enum GT68xx_Option OPT_BR_X, /* bottom-right x */ OPT_BR_Y, /* bottom-right y */ + OPT_SENSOR_GROUP, + OPT_CALIBRATE, /* button option to trigger call + to sheetfed calibration */ + /* must come last: */ NUM_OPTIONS }; -- 1.6.5 [0002-add-gt68xx_sheetfed_scanner_calibrate-function.patch] From 31a0ee74c17924673ebdd18de534f7cd5e998043 Mon Sep 17 00:00:00 2001 From: =?ISO-8859-1?q?St=E9phane=20Voltz?= <stef.dev@...> Date: Wed, 11 Nov 2009 07:53:29 +0100 Subject: [PATCH 2/5] add gt68xx_sheetfed_scanner_calibrate function --- backend/gt68xx_high.c | 143 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 143 insertions(+), 0 deletions(-) diff --git a/backend/gt68xx_high.c b/backend/gt68xx_high.c index 23be5a7..25d023b 100644 --- a/backend/gt68xx_high.c +++ b/backend/gt68xx_high.c @@ -1911,6 +1911,149 @@ gt68xx_afe_cis_auto (GT68xx_Scanner * scanner) return SANE_STATUS_GOOD; } + +/**< number of consecutive white line to detect a white area */ +#define WHITE_LINES 2 + +/** @brief calibrate sheet fed scanner + * This function calibrates sheet fed scanner by scanning a calibration + * target (which may be a blank page). It first move to a white area then + * does afe and exposure calibration. Then it scans white lines to get data + * for shading correction. + * @param scanner structur describin the frontedn session and the device + * @return SANE_STATUS_GOOD is everything goes right, SANE_STATUS_INVAL + * otherwise. + */ +static SANE_Status +gt68xx_sheetfed_scanner_calibrate (GT68xx_Scanner * scanner) +{ + SANE_Status status; + GT68xx_Scan_Request request; + GT68xx_Scan_Parameters params; + int count, i, x, y, white; + unsigned int *buffer_pointers[3]; + + DBG (3, "gt68xx_sheetfed_scanner_calibrate: start.\n"); + + /* find minimum resolution */ + request.ydpi = 9600; + for (i = 0; scanner->dev->model->ydpi_values[i] != 0; i++) + { + if (scanner->dev->model->ydpi_values[i] < request.ydpi) + request.ydpi = scanner->dev->model->ydpi_values[i]; + } + request.xdpi = 9600; + for (i = 0; scanner->dev->model->xdpi_values[i] != 0; i++) + { + if (scanner->dev->model->xdpi_values[i] < request.xdpi) + request.xdpi = scanner->dev->model->xdpi_values[i]; + } + + /* move to white area */ + request.x0 = 0; + request.y0 = SANE_FIX (10.0); + request.xs = scanner->dev->model->x_size; + /* maximum vertical size to scan */ + request.ys = SANE_FIX (500.0); + request.depth = 8; + request.color = SANE_FALSE; + request.mbs = SANE_TRUE; + request.mds = SANE_TRUE; + request.mas = SANE_FALSE; + request.lamp = SANE_TRUE; + request.calculate = SANE_FALSE; + request.use_ta = SANE_FALSE; + request.backtrack = SANE_FALSE; + request.backtrack_lines = 0; + + status = gt68xx_device_lamp_control (scanner->dev, SANE_FALSE, SANE_TRUE); + if (status != SANE_STATUS_GOOD) + { + DBG (1, + "gt68xx_sheetfed_scanner_calibrate: gt68xx_device_lamp_control returned %s\n", + sane_strstatus (status)); + return status; + } + + /* start scan */ + status = + gt68xx_scanner_start_scan_extended (scanner, &request, SA_CALIBRATE, + ¶ms); + if (status != SANE_STATUS_GOOD) + { + DBG (1, + "gt68xx_sheetfed_scanner_calibrate: gt68xx_scanner_start_scan_extended returned %s\n", + sane_strstatus (status)); + return status; + } + + /* loop until we find WHITE_LINES consecutive white lines or we reach and of area */ + white = 0; + y = 0; + do + { + status = gt68xx_line_reader_read (scanner->reader, buffer_pointers); + if (status != SANE_STATUS_GOOD) + { + DBG (1, + "gt68xx_sheetfed_scanner_calibrate: gt68xx_line_reader_read returned %s\n", + sane_strstatus (status)); + gt68xx_scanner_stop_scan (scanner); + return status; + } + + /* check for white line */ + count = 0; + for (x = 0; x < params.pixel_xs; x++) + { + if (((buffer_pointers[0][x] >> 8) & 0xff) > 50) + { + count++; + } + } + + /* line is white if 93% is above black level */ + if ((100 * count) / params.pixel_xs < 93) + { + white = 0; + } + else + { + white++; + } + y++; + } + while ((white < WHITE_LINES) && (y < params.pixel_ys)); + + /* end scan */ + gt68xx_scanner_stop_scan (scanner); + + /* check if we found a white area */ + if (white != WHITE_LINES) + { + DBG (1, + "gt68xx_sheetfed_scanner_calibrate: didn't find a white area\n"); + return SANE_STATUS_INVAL; + } + + /* now do calibration */ + /* TODO : done at find white dpi ? need to compute 'right' request ? + * or shall we loop through available resolutions ? */ + request.color = SANE_TRUE; + scanner->auto_afe = SANE_TRUE; + scanner->calib = SANE_TRUE; + status = gt68xx_scanner_calibrate (scanner, &request); + if (status != SANE_STATUS_GOOD) + { + DBG (1, + "gt68xx_sheetfed_scanner_calibrate: gt68xx_scanner_calibrate returned %s\n", + sane_strstatus (status)); + return status; + } + + DBG (3, "gt68xx_sheetfed_scanner_calibrate: end.\n"); + return SANE_STATUS_GOOD; +} /* vim: set sw=2 cino=>2se-1sn-1s{s^-1st0(0u0 smarttab expandtab: */ -- 1.6.5 [0004-add-needed-flags-to-Optic-Slim-M12.patch] From d93ade38f302cac6b1730efa28d0b044e722fc5e Mon Sep 17 00:00:00 2001 From: =?ISO-8859-1?q?St=E9phane=20Voltz?= <stef.dev@...> Date: Wed, 11 Nov 2009 08:09:47 +0100 Subject: [PATCH 4/5] add needed flags to Optic Slim M12 --- backend/gt68xx_devices.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/backend/gt68xx_devices.c b/backend/gt68xx_devices.c index f84bc6f..bdf5bfb 100644 --- a/backend/gt68xx_devices.c +++ b/backend/gt68xx_devices.c @@ -1593,7 +1593,7 @@ static GT68xx_Model plustek_opticslim_m12_model = { SANE_FIX (2.0), /* Default gamma value */ SANE_TRUE, /* Is this a CIS scanner? */ - GT68XX_FLAG_NO_POWER_STATUS | GT68XX_FLAG_SHEET_FED + GT68XX_FLAG_NO_POWER_STATUS | GT68XX_FLAG_SHEET_FED | GT68XX_FLAG_OFFSET_INV | GT68XX_FLAG_HAS_CALIBRATE }; static GT68xx_Model genius_sf600_model = { -- 1.6.5 [0005-OpticSlim-M12-geometry-fixup.patch] From 96181c014540466bf7d1e3c888c4745a71cd28a4 Mon Sep 17 00:00:00 2001 From: =?ISO-8859-1?q?St=E9phane=20Voltz?= <stef.dev@...> Date: Wed, 11 Nov 2009 08:14:14 +0100 Subject: [PATCH 5/5] OpticSlim M12 geometry fixup --- backend/gt68xx_devices.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/gt68xx_devices.c b/backend/gt68xx_devices.c index bdf5bfb..b0f918d 100644 --- a/backend/gt68xx_devices.c +++ b/backend/gt68xx_devices.c @@ -1569,13 +1569,13 @@ static GT68xx_Model plustek_opticslim_m12_model = { {16, 8, 0}, /* possible depths in gray mode */ {16, 8, 0}, /* possible depths in color mode */ - SANE_FIX (1.0), /* Start of scan area in mm (x) */ - SANE_FIX (9.5), /* Start of scan area in mm (y) */ + SANE_FIX (0.0), /* Start of scan area in mm (x) */ + SANE_FIX (1.5), /* Start of scan area in mm (y) */ SANE_FIX (218.0), /* Size of scan area in mm (x) */ SANE_FIX (299.0), /* Size of scan area in mm (y) */ SANE_FIX (10.0), /* Start of white strip in mm (y) */ - SANE_FIX (140.0), /* Start of black mark in mm (x) */ + SANE_FIX (21.72), /* Start of black mark in mm (x) */ SANE_FIX (0.0), /* Start of scan area in TA mode in mm (x) */ SANE_FIX (0.0), /* Start of scan area in TA mode in mm (y) */ -- 1.6.5 -- sane-devel mailing list: sane-devel@... http://lists.alioth.debian.org/mailman/listinfo/sane-devel Unsubscribe: Send mail with subject "unsubscribe your_password" to sane-devel-request@... |
| Free embeddable forum powered by Nabble | Forum Help |