diff --git a/backend/genesys_gl124.cc b/backend/genesys_gl124.cc index 57e9d1510..ba8faea70 100644 --- a/backend/genesys_gl124.cc +++ b/backend/genesys_gl124.cc @@ -781,8 +781,6 @@ static void gl124_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens const ScanSession& session) { DBG_HELPER_ARGS(dbg, "exposure_time=%d", exposure_time); - unsigned int segcnt; - unsigned int startx, endx; unsigned int dpihw; GenesysRegister *r; uint32_t expmax; @@ -801,21 +799,6 @@ static void gl124_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens session.ccd_size_divisor); gl124_setup_sensor(dev, sensor, sensor_profile, reg); - /* start and end coordinate in optical dpi coordinates */ - /* startx = start / ccd_pixels_per_system_pixel + sensor.dummy_pixel; XXX STEF XXX */ - unsigned start = session.params.startx; - - if (session.num_staggered_lines > 0) { - start |= 1; - } - - startx = start / ccd_pixels_per_system_pixel; - endx = startx + session.optical_pixels / ccd_pixels_per_system_pixel; - - /* pixel coordinate factor correction when used dpihw is not maximal one */ - startx /= session.hwdpi_divisor; - endx /= session.hwdpi_divisor; - gl124_set_fe(dev, sensor, AFE_SET); /* enable shading */ @@ -936,14 +919,8 @@ static void gl124_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens } } - reg->set24(REG_STRPIXEL, startx / session.segment_count); - DBG(DBG_io2, "%s: strpixel used=%d\n", __func__, startx / session.segment_count); - segcnt = reg->get24(REG_SEGCNT); - if (endx / session.segment_count == segcnt) { - endx=0; - } - reg->set24(REG_ENDPIXEL, endx / session.segment_count); - DBG(DBG_io2, "%s: endpixel used=%d\n", __func__, endx / session.segment_count); + reg->set24(REG_STRPIXEL, session.pixel_startx); + reg->set24(REG_ENDPIXEL, session.pixel_endx); dev->line_count = 0; diff --git a/backend/genesys_gl646.cc b/backend/genesys_gl646.cc index c4b333d10..69d2c3999 100644 --- a/backend/genesys_gl646.cc +++ b/backend/genesys_gl646.cc @@ -319,8 +319,7 @@ static void gl646_setup_registers(Genesys_Device* dev, Genesys_Register_Set* regs, const ScanSession& session, std::vector& slope_table1, - std::vector& slope_table2, - bool xcorrection) + std::vector& slope_table2) { DBG_HELPER(dbg); session.assert_computed(); @@ -329,39 +328,12 @@ static void gl646_setup_registers(Genesys_Device* dev, uint32_t move = session.params.starty; - uint32_t startx = 0; - /* pixels are allways given at full CCD optical resolution */ - /* use detected left margin and fixed value */ - if (xcorrection == SANE_TRUE) { - if (sensor.CCD_start_xoffset > 0) { - startx = sensor.CCD_start_xoffset; - } else { - startx = sensor.dummy_pixel; - } - } else { - // startx cannot be below dummy pixel value - startx = sensor.dummy_pixel; - } - - /* add x coordinates : expressed in sensor max dpi */ - startx += session.params.startx; - - /* stagger works with odd start cordinates */ - if (dev->model->flags & GENESYS_FLAG_STAGGERED_LINE) { - startx |= 1; - } - - /* TODO check for pixel width overflow */ - uint32_t endx = startx + session.optical_pixels; - int i, nb; Motor_Master *motor = NULL; unsigned int used1, used2, vfinal; uint32_t z1, z2; - uint16_t ex, sx; int feedl; - DBG(DBG_info, "%s: startx=%d, endx=%d\n", __func__, startx, endx); /* for the given resolution, search for master * motor mode setting */ @@ -555,13 +527,8 @@ static void gl646_setup_registers(Genesys_Device* dev, regs->set24(REG_LINCNT, session.output_line_count); } - /* scanner's x coordinates are expressed in physical DPI but they must be divided by cksel */ - sx = startx / sensor.ccd_pixels_per_system_pixel() / session.ccd_size_divisor; - ex = endx / sensor.ccd_pixels_per_system_pixel() / session.ccd_size_divisor; - regs->set16(REG_STRPIXEL, sx); - regs->set16(REG_ENDPIXEL, ex); - DBG(DBG_info, "%s: startx=%d, endx=%d, ccd_size_divisor=%d\n", __func__, sx, ex, - session.ccd_size_divisor); + regs->set16(REG_STRPIXEL, session.pixel_startx); + regs->set16(REG_ENDPIXEL, session.pixel_endx); regs->set24(REG_MAXWD, session.output_line_bytes); @@ -2166,13 +2133,16 @@ static void setup_for_scan(Genesys_Device* dev, if (settings.scan_method == ScanMethod::TRANSPARENCY) { session.params.flags |= SCAN_FLAG_USE_XPA; } + if (xcorrection) { + session.params.flags |= SCAN_FLAG_USE_XCORRECTION; + } gl646_compute_session(dev, session, sensor); std::vector slope_table0; std::vector slope_table1; // set up correct values for scan (gamma and shading enabled) - gl646_setup_registers(dev, sensor, regs, session, slope_table0, slope_table1, xcorrection); + gl646_setup_registers(dev, sensor, regs, session, slope_table0, slope_table1); // send computed slope tables gl646_send_slope_table(dev, 0, slope_table0, regs->get8(0x21)); diff --git a/backend/genesys_gl841.cc b/backend/genesys_gl841.cc index e810b7918..1ab1b0eeb 100644 --- a/backend/genesys_gl841.cc +++ b/backend/genesys_gl841.cc @@ -1453,15 +1453,12 @@ static void gl841_init_optical_regs_off(Genesys_Register_Set* reg) static void gl841_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sensor& sensor, Genesys_Register_Set* reg, unsigned int exposure_time, - const ScanSession& session, unsigned int start) + const ScanSession& session) { - DBG_HELPER_ARGS(dbg, "exposure_time=%d, start=%d", exposure_time, start); - unsigned int end; + DBG_HELPER_ARGS(dbg, "exposure_time=%d", exposure_time); GenesysRegister* r; uint16_t expavg, expr, expb, expg; - end = start + session.optical_pixels; - gl841_set_fe(dev, sensor, AFE_SET); /* gpio part.*/ @@ -1600,9 +1597,8 @@ static void gl841_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens r->value = 255; /*<<<"magic" number, only suitable for cis*/ reg->set16(REG_DPISET, gl841_get_dpihw(dev) * session.output_resolution / session.optical_resolution); - reg->set16(REG_STRPIXEL, start); - reg->set16(REG_ENDPIXEL, end); - DBG(DBG_io2, "%s: STRPIXEL=%d, ENDPIXEL=%d\n", __func__, start, end); + reg->set16(REG_STRPIXEL, session.pixel_startx); + reg->set16(REG_ENDPIXEL, session.pixel_endx); reg->set24(REG_MAXWD, session.output_line_bytes); @@ -1735,10 +1731,8 @@ static void gl841_init_scan_regs(Genesys_Device* dev, const Genesys_Sensor& sens DBG_HELPER(dbg); session.assert_computed(); - int start; int move; int exposure_time; - int avg; int slope_dpi = 0; int dummy = 0; @@ -1774,29 +1768,6 @@ independent of our calculated values: gl841_assert_supported_resolution(session); - /* compute scan parameters values */ - /* pixels are allways given at half or full CCD optical resolution */ - /* use detected left margin and fixed value */ - start = ((sensor.CCD_start_xoffset + session.params.startx) * session.optical_resolution) - / sensor.optical_res; - - - start += sensor.dummy_pixel + 1; - - if (session.num_staggered_lines > 0) { - start |= 1; - } - - /* in case of SHDAREA, we need to align start - * on pixel average factor, startx is different of - * 0 only when calling for function to setup for - * scan, where shading data needs to be align */ - if((dev->reg.find_reg(0x01).value & REG01_SHDAREA) != 0) - { - avg = session.optical_resolution / session.params.xres; - start=(start/avg)*avg; - } - /* dummy */ /* dummy lines: may not be usefull, for instance 250 dpi works with 0 or 1 dummy line. Maybe the dummy line adds correctness since the motor runs @@ -1839,11 +1810,11 @@ dummy \ scanned lines exposure_time = gl841_exposure_time(dev, sensor, slope_dpi, scan_step_type, - start, + session.pixel_startx, session.optical_pixels); DBG(DBG_info, "%s : exposure_time=%d pixels\n", __func__, exposure_time); - gl841_init_optical_regs_scan(dev, sensor, reg, exposure_time, session, start); + gl841_init_optical_regs_scan(dev, sensor, reg, exposure_time, session); move = session.params.starty; DBG(DBG_info, "%s: move=%d steps\n", __func__, move); @@ -1939,17 +1910,6 @@ static void gl841_calculate_current_setup(Genesys_Device * dev, const Genesys_Se gl841_assert_supported_resolution(session); - /* compute scan parameters values */ - /* pixels are allways given at half or full CCD optical resolution */ - /* use detected left margin and fixed value */ - start = ((sensor.CCD_start_xoffset + session.params.startx) * session.optical_resolution) / sensor.optical_res; - - start += sensor.dummy_pixel + 1; - - if (session.num_staggered_lines > 0) { - start |= 1; - } - /* dummy lines: may not be usefull, for instance 250 dpi works with 0 or 1 dummy line. Maybe the dummy line adds correctness since the motor runs slower (higher dpi) @@ -1990,7 +1950,7 @@ dummy \ scanned lines exposure_time = gl841_exposure_time(dev, sensor, slope_dpi, scan_step_type, - start, + session.pixel_startx, session.optical_pixels); DBG(DBG_info, "%s : exposure_time=%d pixels\n", __func__, exposure_time); diff --git a/backend/genesys_gl843.cc b/backend/genesys_gl843.cc index 727a91734..bba2b5466 100644 --- a/backend/genesys_gl843.cc +++ b/backend/genesys_gl843.cc @@ -1190,20 +1190,6 @@ static void gl843_compute_session(Genesys_Device* dev, ScanSession& s, compute_session(dev, s, sensor); - // compute physical pixel positions - unsigned ccd_pixels_per_system_pixel = sensor.ccd_pixels_per_system_pixel(); - s.pixel_startx = (s.params.startx + sensor.dummy_pixel) / ccd_pixels_per_system_pixel; - s.pixel_endx = s.pixel_startx + s.optical_pixels / ccd_pixels_per_system_pixel; - - s.pixel_startx /= s.hwdpi_divisor; - s.pixel_endx /= s.hwdpi_divisor; - - // in case of stagger we have to start at an odd coordinate - if (s.num_staggered_lines > 0 && (s.pixel_startx & 1) == 0) { - s.pixel_startx++; - s.pixel_endx++; - } - s.computed = true; DBG(DBG_info, "%s ", __func__); diff --git a/backend/genesys_gl846.cc b/backend/genesys_gl846.cc index 7b0d3006b..36e809e50 100644 --- a/backend/genesys_gl846.cc +++ b/backend/genesys_gl846.cc @@ -700,19 +700,6 @@ static void gl846_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens const auto& sensor_profile = get_sensor_profile(dev->model->asic_type, sensor, dpihw, 1); gl846_setup_sensor(dev, sensor, sensor_profile, reg); - // start and end coordinate in optical dpi coordinates - unsigned start = session.params.startx; - - if (session.num_staggered_lines > 0) { - start |= 1; - } - unsigned startx = start + sensor.CCD_start_xoffset * ccd_pixels_per_system_pixel; - unsigned endx = startx + session.optical_pixels_raw; - - // compute pixel coordinate in the given dpihw space, taking segments into account - startx /= session.hwdpi_divisor * session.segment_count; - endx /= session.hwdpi_divisor * session.segment_count; - gl846_set_fe(dev, sensor, AFE_SET); /* enable shading */ @@ -811,10 +798,8 @@ static void gl846_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens reg->set16(REG_DPISET, dpiset); DBG(DBG_io2, "%s: dpiset used=%d\n", __func__, dpiset); - reg->set16(REG_STRPIXEL, startx / ccd_pixels_per_system_pixel); - reg->set16(REG_ENDPIXEL, endx / ccd_pixels_per_system_pixel); - DBG(DBG_io2, "%s: startx=%d\n", __func__, startx / ccd_pixels_per_system_pixel); - DBG(DBG_io2, "%s: endx =%d\n", __func__, endx / ccd_pixels_per_system_pixel); + reg->set16(REG_STRPIXEL, session.pixel_startx); + reg->set16(REG_ENDPIXEL, session.pixel_endx); DBG (DBG_io2, "%s: pixels =%d\n", __func__, session.optical_pixels); DBG (DBG_io2, "%s: depth =%d\n", __func__, session.params.depth); diff --git a/backend/genesys_gl847.cc b/backend/genesys_gl847.cc index 21ea22ea2..c614e653d 100644 --- a/backend/genesys_gl847.cc +++ b/backend/genesys_gl847.cc @@ -717,19 +717,6 @@ static void gl847_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens const auto& sensor_profile = get_sensor_profile(dev->model->asic_type, sensor, dpihw, 1); gl847_setup_sensor(dev, sensor, sensor_profile, reg); - unsigned start = session.params.startx; - if (session.num_staggered_lines > 0) { - start |= 1; - } - - // start and end coordinate in optical dpi coordinates - unsigned startx = start + sensor.CCD_start_xoffset * ccd_pixels_per_system_pixel; - unsigned endx = startx + session.optical_pixels_raw; - - // compute pixel coordinate in the given dpihw space, taking segments into account - startx /= session.hwdpi_divisor * session.segment_count; - endx /= session.hwdpi_divisor * session.segment_count; - gl847_set_fe(dev, sensor, AFE_SET); /* enable shading */ @@ -828,10 +815,8 @@ static void gl847_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens reg->set16(REG_DPISET, dpiset); DBG (DBG_io2, "%s: dpiset used=%d\n", __func__, dpiset); - reg->set16(REG_STRPIXEL, startx / ccd_pixels_per_system_pixel); - reg->set16(REG_ENDPIXEL, endx / ccd_pixels_per_system_pixel); - DBG(DBG_io2, "%s: startx=%d\n", __func__, startx / ccd_pixels_per_system_pixel); - DBG(DBG_io2, "%s: endx =%d\n", __func__, endx / ccd_pixels_per_system_pixel); + reg->set16(REG_STRPIXEL, session.pixel_startx); + reg->set16(REG_ENDPIXEL, session.pixel_endx); DBG (DBG_io2, "%s: pixels =%d\n", __func__, session.optical_pixels); DBG (DBG_io2, "%s: depth =%d\n", __func__, session.params.depth); diff --git a/backend/genesys_low.cc b/backend/genesys_low.cc index 678ff9483..cf401ebd5 100644 --- a/backend/genesys_low.cc +++ b/backend/genesys_low.cc @@ -1234,6 +1234,110 @@ void compute_session_pipeline(const Genesys_Device* dev, ScanSession& s) s.pipeline_needs_reverse = depth == 1; } +void compute_session_pixel_offsets(const Genesys_Device* dev, ScanSession& s, + const Genesys_Sensor& sensor, + const SensorProfile* sensor_profile) +{ + unsigned ccd_pixels_per_system_pixel = sensor.ccd_pixels_per_system_pixel(); + + if (dev->model->asic_type == AsicType::GL646) { + + // startx cannot be below dummy pixel value + s.pixel_startx = sensor.dummy_pixel; + if ((s.params.flags & SCAN_FLAG_USE_XCORRECTION) && sensor.CCD_start_xoffset > 0) { + s.pixel_startx = sensor.CCD_start_xoffset; + } + s.pixel_startx += s.params.startx; + + if (dev->model->flags & GENESYS_FLAG_STAGGERED_LINE) { + s.pixel_startx |= 1; + } + + s.pixel_endx = s.pixel_startx + s.optical_pixels; + + s.pixel_startx /= sensor.ccd_pixels_per_system_pixel() * s.ccd_size_divisor; + s.pixel_endx /= sensor.ccd_pixels_per_system_pixel() * s.ccd_size_divisor; + + } else if (dev->model->asic_type == AsicType::GL841) { + s.pixel_startx = ((sensor.CCD_start_xoffset + s.params.startx) * s.optical_resolution) + / sensor.optical_res; + + s.pixel_startx += sensor.dummy_pixel + 1; + + if (s.num_staggered_lines > 0 && (s.pixel_startx & 1) == 0) { + s.pixel_startx++; + } + + /* In case of SHDAREA, we need to align start on pixel average factor, startx is + different than 0 only when calling for function to setup for scan, where shading data + needs to be align. + + NOTE: we can check the value of the register here, because we don't set this bit + anywhere except in initialization. + */ + const uint8_t REG01_SHDAREA = 0x02; + if ((dev->reg.find_reg(0x01).value & REG01_SHDAREA) != 0) { + unsigned average_factor = s.optical_resolution / s.params.xres; + s.pixel_startx = align_multiple_floor(s.pixel_startx, average_factor); + } + + s.pixel_endx = s.pixel_startx + s.optical_pixels; + + } else if (dev->model->asic_type == AsicType::GL843) { + + s.pixel_startx = (s.params.startx + sensor.dummy_pixel) / ccd_pixels_per_system_pixel; + s.pixel_endx = s.pixel_startx + s.optical_pixels / ccd_pixels_per_system_pixel; + + s.pixel_startx /= s.hwdpi_divisor; + s.pixel_endx /= s.hwdpi_divisor; + + // in case of stagger we have to start at an odd coordinate + if (s.num_staggered_lines > 0 && (s.pixel_startx & 1) == 0) { + s.pixel_startx++; + s.pixel_endx++; + } + + } else if (dev->model->asic_type == AsicType::GL845 || + dev->model->asic_type == AsicType::GL846 || + dev->model->asic_type == AsicType::GL847) + { + s.pixel_startx = s.params.startx; + + if (s.num_staggered_lines > 0) { + s.pixel_startx |= 1; + } + + s.pixel_startx += sensor.CCD_start_xoffset * ccd_pixels_per_system_pixel; + s.pixel_endx = s.pixel_startx + s.optical_pixels_raw; + + s.pixel_startx /= s.hwdpi_divisor * s.segment_count * ccd_pixels_per_system_pixel; + s.pixel_endx /= s.hwdpi_divisor * s.segment_count * ccd_pixels_per_system_pixel; + + } else if (dev->model->asic_type == AsicType::GL124) { + s.pixel_startx = s.params.startx; + + if (s.num_staggered_lines > 0) { + s.pixel_startx |= 1; + } + + s.pixel_startx /= ccd_pixels_per_system_pixel; + // FIXME: should we add sensor.dummy_pxel to pixel_startx at this point? + s.pixel_endx = s.pixel_startx + s.optical_pixels / ccd_pixels_per_system_pixel; + + s.pixel_startx /= s.hwdpi_divisor * s.segment_count; + s.pixel_endx /= s.hwdpi_divisor * s.segment_count; + + const uint16_t REG_SEGCNT = 0x93; + + std::uint32_t segcnt = (sensor_profile->custom_regs.get_value(REG_SEGCNT) << 16) + + (sensor_profile->custom_regs.get_value(REG_SEGCNT + 1) << 8) + + sensor_profile->custom_regs.get_value(REG_SEGCNT + 2); + if (s.pixel_endx == segcnt) { + s.pixel_endx = 0; + } + } +} + void compute_session(Genesys_Device* dev, ScanSession& s, const Genesys_Sensor& sensor) { DBG_HELPER(dbg); @@ -1417,6 +1521,7 @@ void compute_session(Genesys_Device* dev, ScanSession& s, const Genesys_Sensor& compute_session_buffer_sizes(dev->model->asic_type, s); compute_session_pipeline(dev, s); + compute_session_pixel_offsets(dev, s, sensor, sensor_profile); } static std::size_t get_usb_buffer_read_size(AsicType asic, const ScanSession& session) diff --git a/backend/genesys_low.h b/backend/genesys_low.h index fe65a8715..cb1aaf0f5 100644 --- a/backend/genesys_low.h +++ b/backend/genesys_low.h @@ -378,6 +378,7 @@ extern Motor_Profile gl124_motor_profiles[]; #define SCAN_FLAG_FEEDING 0x200 #define SCAN_FLAG_USE_XPA 0x400 #define SCAN_FLAG_ENABLE_LEDADD 0x800 +#define SCAN_FLAG_USE_XCORRECTION 0x1000 #define MOTOR_FLAG_AUTO_GO_HOME 0x01 #define MOTOR_FLAG_DISABLE_BUFFER_FULL_MOVE 0x02 #define MOTOR_FLAG_FEED 0x04