Merge branch 'genesys-duplication' into 'master'

genesys: Reduce code duplication

See merge request sane-project/backends!344
merge-requests/340/head
Povilas Kanapickas 2020-02-22 14:36:17 +00:00
commit 993a79b594
17 zmienionych plików z 354 dodań i 1239 usunięć

Wyświetl plik

@ -132,11 +132,6 @@ public:
/// eject document from scanner
virtual void eject_document(Genesys_Device* dev) const = 0;
/**
* search for an black or white area in forward or reverse
* direction */
virtual void search_strip(Genesys_Device* dev, const Genesys_Sensor& sensor,
bool forward, bool black) const = 0;
/// move scanning head to transparency adapter
virtual void move_to_ta(Genesys_Device* dev) const = 0;

Wyświetl plik

@ -1071,6 +1071,208 @@ void scanner_move_back_home_ta(Genesys_Device& dev)
throw SaneException("Timeout waiting for XPA lamp to park");
}
namespace gl841 {
void gl841_stop_action(Genesys_Device* dev);
} // namespace gl841
void scanner_search_strip(Genesys_Device& dev, bool forward, bool black)
{
DBG_HELPER_ARGS(dbg, "%s %s", black ? "black" : "white", forward ? "forward" : "reverse");
if (dev.model->asic_type == AsicType::GL841 && !black && forward) {
dev.frontend.set_gain(0, 0xff);
dev.frontend.set_gain(1, 0xff);
dev.frontend.set_gain(2, 0xff);
}
// set up for a gray scan at lowest dpi
const auto& resolution_settings = dev.model->get_resolution_settings(dev.settings.scan_method);
unsigned dpi = resolution_settings.get_min_resolution_x();
unsigned channels = 1;
auto& sensor = sanei_genesys_find_sensor(&dev, dpi, channels, dev.settings.scan_method);
dev.cmd_set->set_fe(&dev, sensor, AFE_SET);
scanner_stop_action(dev);
// shading calibration is done with dev.motor.base_ydpi
unsigned lines = static_cast<unsigned>(dev.model->y_size_calib_mm * dpi / MM_PER_INCH);
if (dev.model->asic_type == AsicType::GL841) {
lines = 10; // TODO: use dev.model->search_lines
lines = static_cast<unsigned>((lines * dpi) / MM_PER_INCH);
}
unsigned pixels = dev.model->x_size_calib_mm * dpi / MM_PER_INCH;
dev.set_head_pos_zero(ScanHeadId::PRIMARY);
unsigned length = 20;
if (dev.model->asic_type == AsicType::GL841) {
// 20 cm max length for calibration sheet
length = static_cast<unsigned>(((200 * dpi) / MM_PER_INCH) / lines);
}
auto local_reg = dev.reg;
ScanSession session;
session.params.xres = dpi;
session.params.yres = dpi;
session.params.startx = 0;
session.params.starty = 0;
session.params.pixels = pixels;
session.params.lines = lines;
session.params.depth = 8;
session.params.channels = channels;
session.params.scan_method = dev.settings.scan_method;
session.params.scan_mode = ScanColorMode::GRAY;
session.params.color_filter = ColorFilter::RED;
session.params.flags = ScanFlag::DISABLE_SHADING |
ScanFlag::DISABLE_GAMMA;
if (dev.model->asic_type != AsicType::GL841 && !forward) {
session.params.flags |= ScanFlag::REVERSE;
}
compute_session(&dev, session, sensor);
dev.cmd_set->init_regs_for_scan_session(&dev, sensor, &local_reg, session);
dev.interface->write_registers(local_reg);
dev.cmd_set->begin_scan(&dev, sensor, &local_reg, true);
if (is_testing_mode()) {
dev.interface->test_checkpoint("search_strip");
if (dev.model->asic_type == AsicType::GL841) {
gl841::gl841_stop_action(&dev);
} else {
scanner_stop_action(dev);
}
return;
}
wait_until_buffer_non_empty(&dev);
// now we're on target, we can read data
auto image = read_unshuffled_image_from_scanner(&dev, session, session.output_total_bytes);
if (dev.model->asic_type == AsicType::GL841) {
gl841::gl841_stop_action(&dev);
} else {
scanner_stop_action(dev);
}
unsigned pass = 0;
if (DBG_LEVEL >= DBG_data) {
char title[80];
std::sprintf(title, "gl_search_strip_%s_%s%02d.pnm",
black ? "black" : "white", forward ? "fwd" : "bwd", pass);
sanei_genesys_write_pnm_file(title, image);
}
// loop until strip is found or maximum pass number done
bool found = false;
while (pass < length && !found) {
dev.interface->write_registers(local_reg);
// now start scan
dev.cmd_set->begin_scan(&dev, sensor, &local_reg, true);
wait_until_buffer_non_empty(&dev);
// now we're on target, we can read data
image = read_unshuffled_image_from_scanner(&dev, session, session.output_total_bytes);
scanner_stop_action(dev);
if (DBG_LEVEL >= DBG_data) {
char title[80];
std::sprintf(title, "gl_search_strip_%s_%s%02d.pnm",
black ? "black" : "white",
forward ? "fwd" : "bwd", static_cast<int>(pass));
sanei_genesys_write_pnm_file(title, image);
}
unsigned white_level = 90;
unsigned black_level = 60;
std::size_t count = 0;
// Search data to find black strip
// When searching forward, we only need one line of the searched color since we
// will scan forward. But when doing backward search, we need all the area of the ame color
if (forward) {
for (std::size_t y = 0; y < image.get_height() && !found; y++) {
count = 0;
// count of white/black pixels depending on the color searched
for (std::size_t x = 0; x < image.get_width(); x++) {
// when searching for black, detect white pixels
if (black && image.get_raw_channel(x, y, 0) > white_level) {
count++;
}
// when searching for white, detect black pixels
if (!black && image.get_raw_channel(x, y, 0) < black_level) {
count++;
}
}
// at end of line, if count >= 3%, line is not fully of the desired color
// so we must go to next line of the buffer */
// count*100/pixels < 3
auto found_percentage = (count * 100 / image.get_width());
if (found_percentage < 3) {
found = 1;
DBG(DBG_data, "%s: strip found forward during pass %d at line %zu\n", __func__,
pass, y);
} else {
DBG(DBG_data, "%s: pixels=%zu, count=%zu (%zu%%)\n", __func__,
image.get_width(), count, found_percentage);
}
}
} else {
/* since calibration scans are done forward, we need the whole area
to be of the required color when searching backward
*/
count = 0;
for (std::size_t y = 0; y < image.get_height(); y++) {
// count of white/black pixels depending on the color searched
for (std::size_t x = 0; x < image.get_width(); x++) {
// when searching for black, detect white pixels
if (black && image.get_raw_channel(x, y, 0) > white_level) {
count++;
}
// when searching for white, detect black pixels
if (!black && image.get_raw_channel(x, y, 0) < black_level) {
count++;
}
}
}
// at end of area, if count >= 3%, area is not fully of the desired color
// so we must go to next buffer
auto found_percentage = count * 100 / (image.get_width() * image.get_height());
if (found_percentage < 3) {
found = 1;
DBG(DBG_data, "%s: strip found backward during pass %d \n", __func__, pass);
} else {
DBG(DBG_data, "%s: pixels=%zu, count=%zu (%zu%%)\n", __func__, image.get_width(),
count, found_percentage);
}
}
pass++;
}
if (found) {
DBG(DBG_info, "%s: %s strip found\n", __func__, black ? "black" : "white");
} else {
throw SaneException(SANE_STATUS_UNSUPPORTED, "%s strip not found",
black ? "black" : "white");
}
}
void sanei_genesys_calculate_zmod(bool two_table,
uint32_t exposure_time,
const std::vector<uint16_t>& slope_table,
@ -2514,7 +2716,7 @@ static void genesys_sheetfed_calibration(Genesys_Device* dev, Genesys_Sensor& se
/* go to a white area */
try {
dev->cmd_set->search_strip(dev, sensor, forward, false);
scanner_search_strip(*dev, forward, false);
} catch (...) {
catch_all_exceptions(__func__, [&](){ dev->cmd_set->eject_document(dev); });
throw;
@ -2534,7 +2736,7 @@ static void genesys_sheetfed_calibration(Genesys_Device* dev, Genesys_Sensor& se
if (has_flag(dev->model->flags, ModelFlag::DARK_CALIBRATION)) {
// seek black/white reverse/forward
try {
dev->cmd_set->search_strip(dev, sensor, forward, true);
scanner_search_strip(*dev, forward, true);
} catch (...) {
catch_all_exceptions(__func__, [&](){ dev->cmd_set->eject_document(dev); });
throw;
@ -2552,7 +2754,7 @@ static void genesys_sheetfed_calibration(Genesys_Device* dev, Genesys_Sensor& se
/* go to a white area */
try {
dev->cmd_set->search_strip(dev, sensor, forward, false);
scanner_search_strip(*dev, forward, false);
} catch (...) {
catch_all_exceptions(__func__, [&](){ dev->cmd_set->eject_document(dev); });
throw;

Wyświetl plik

@ -904,21 +904,24 @@ ScanSession CommandSetGl124::calculate_scan_session(const Genesys_Device* dev,
const Genesys_Sensor& sensor,
const Genesys_Settings& settings) const
{
int start;
DBG(DBG_info, "%s ", __func__);
debug_dump(DBG_info, settings);
/* start */
start = static_cast<int>(dev->model->x_offset);
start += static_cast<int>(settings.tl_x);
start = static_cast<int>((start * settings.xres) / MM_PER_INCH);
unsigned move_dpi = dev->motor.base_ydpi / 4;
float move = dev->model->y_offset;
move += dev->settings.tl_y;
move = static_cast<float>((move * move_dpi) / MM_PER_INCH);
float start = dev->model->x_offset;
start += settings.tl_x;
start /= sensor.get_ccd_size_divisor_for_dpi(settings.xres);
start = static_cast<float>((start * settings.xres) / MM_PER_INCH);
ScanSession session;
session.params.xres = settings.xres;
session.params.yres = settings.yres;
session.params.startx = start;
session.params.starty = 0; // not used
session.params.startx = static_cast<unsigned>(start);
session.params.starty = static_cast<unsigned>(move);
session.params.pixels = settings.pixels;
session.params.requested_pixels = settings.requested_pixels;
session.params.lines = settings.lines;
@ -1026,8 +1029,7 @@ void CommandSetGl124::begin_scan(Genesys_Device* dev, const Genesys_Sensor& sens
// set up GPIO for scan
gl124_setup_scan_gpio(dev,dev->settings.yres);
// clear scan and feed count
dev->interface->write_register(REG_0x0D, REG_0x0D_CLRLNCNT | REG_0x0D_CLRMCNT);
scanner_clear_scan_and_feed_counts(*dev);
// enable scan and motor
uint8_t val = dev->interface->read_register(REG_0x01);
@ -1144,46 +1146,14 @@ void CommandSetGl124::init_regs_for_scan(Genesys_Device* dev, const Genesys_Sens
Genesys_Register_Set& regs) const
{
DBG_HELPER(dbg);
float move;
int move_dpi;
float start;
auto session = calculate_scan_session(dev, sensor, dev->settings);
debug_dump(DBG_info, dev->settings);
/* y (motor) distance to move to reach scanned area */
move_dpi = dev->motor.base_ydpi/4;
move = dev->model->y_offset;
move += dev->settings.tl_y;
move = static_cast<float>((move * move_dpi) / MM_PER_INCH);
DBG (DBG_info, "%s: move=%f steps\n", __func__, move);
if (dev->settings.get_channels() * dev->settings.yres >= 600 && move > 700) {
scanner_move(*dev, dev->model->default_method, static_cast<unsigned>(move - 500),
if (dev->settings.get_channels() * dev->settings.yres >= 600 && session.params.starty > 700) {
scanner_move(*dev, dev->model->default_method,
static_cast<unsigned>(session.params.starty - 500),
Direction::FORWARD);
move=500;
session.params.starty = 500;
}
DBG(DBG_info, "%s: move=%f steps\n", __func__, move);
/* start */
start = dev->model->x_offset;
start += dev->settings.tl_x;
start /= sensor.get_ccd_size_divisor_for_dpi(dev->settings.xres);
start = static_cast<float>((start * dev->settings.xres) / MM_PER_INCH);
ScanSession session;
session.params.xres = dev->settings.xres;
session.params.yres = dev->settings.yres;
session.params.startx = static_cast<unsigned>(start);
session.params.starty = static_cast<unsigned>(move);
session.params.pixels = dev->settings.pixels;
session.params.requested_pixels = dev->settings.requested_pixels;
session.params.lines = dev->settings.lines;
session.params.depth = dev->settings.depth;
session.params.channels = dev->settings.get_channels();
session.params.scan_method = dev->settings.scan_method;
session.params.scan_mode = dev->settings.scan_mode;
session.params.color_filter = dev->settings.color_filter;
session.params.flags = ScanFlag::NONE;
compute_session(dev, session, sensor);
init_regs_for_scan_session(dev, sensor, &regs, session);
@ -2066,16 +2036,6 @@ void CommandSetGl124::eject_document(Genesys_Device* dev) const
throw SaneException("not implemented");
}
void CommandSetGl124::search_strip(Genesys_Device* dev, const Genesys_Sensor& sensor,
bool forward, bool black) const
{
(void) dev;
(void) sensor;
(void) forward;
(void) black;
throw SaneException("not implemented");
}
void CommandSetGl124::move_to_ta(Genesys_Device* dev) const
{
(void) dev;

Wyświetl plik

@ -171,9 +171,6 @@ public:
void eject_document(Genesys_Device* dev) const override;
void search_strip(Genesys_Device* dev, const Genesys_Sensor& sensor,
bool forward, bool black) const override;
void move_to_ta(Genesys_Device* dev) const override;
void send_shading_data(Genesys_Device* dev, const Genesys_Sensor& sensor, uint8_t* data,

Wyświetl plik

@ -3114,154 +3114,6 @@ static void write_control(Genesys_Device* dev, const Genesys_Sensor& sensor, int
dev->interface->write_buffer(0x3c, addr, control, 4);
}
/**
* search for a full width black or white strip.
* @param dev scanner device
* @param forward true if searching forward, false if searching backward
* @param black true if searching for a black strip, false for a white strip
*/
void CommandSetGl646::search_strip(Genesys_Device* dev, const Genesys_Sensor& sensor, bool forward,
bool black) const
{
DBG_HELPER(dbg);
(void) sensor;
Genesys_Settings settings;
int res = get_closest_resolution(dev->model->sensor_id, 75, 1);
unsigned int pass, count, found, x, y;
char title[80];
const auto& calib_sensor = sanei_genesys_find_sensor(dev, res, 1, ScanMethod::FLATBED);
/* we set up for a lowest available resolution color grey scan, full width */
settings.scan_method = dev->model->default_method;
settings.scan_mode = ScanColorMode::GRAY;
settings.xres = res;
settings.yres = res;
settings.tl_x = 0;
settings.tl_y = 0;
settings.pixels = static_cast<unsigned>((dev->model->x_size * res) / MM_PER_INCH);
settings.pixels /= calib_sensor.get_ccd_size_divisor_for_dpi(res);
settings.requested_pixels = settings.pixels;
/* 15 mm at at time */
settings.lines = static_cast<unsigned>((15 * settings.yres) / MM_PER_INCH);
settings.depth = 8;
settings.color_filter = ColorFilter::RED;
settings.disable_interpolation = 0;
settings.threshold = 0;
/* signals if a strip of the given color has been found */
found = 0;
/* detection pass done */
pass = 0;
std::vector<uint8_t> data;
/* loop until strip is found or maximum pass number done */
while (pass < 20 && !found)
{
// scan a full width strip
simple_scan(dev, calib_sensor, settings, true, forward, false, data, "search_strip");
if (is_testing_mode()) {
return;
}
if (DBG_LEVEL >= DBG_data)
{
std::sprintf(title, "gl646_search_strip_%s%02d.pnm", forward ? "fwd" : "bwd", pass);
sanei_genesys_write_pnm_file (title, data.data(), settings.depth, 1,
settings.pixels, settings.lines);
}
/* search data to find black strip */
/* when searching forward, we only need one line of the searched color since we
* will scan forward. But when doing backward search, we need all the area of the
* same color */
if (forward)
{
for (y = 0; y < settings.lines && !found; y++)
{
count = 0;
/* count of white/black pixels depending on the color searched */
for (x = 0; x < settings.pixels; x++)
{
/* when searching for black, detect white pixels */
if (black && data[y * settings.pixels + x] > 90)
{
count++;
}
/* when searching for white, detect black pixels */
if (!black && data[y * settings.pixels + x] < 60)
{
count++;
}
}
/* at end of line, if count >= 3%, line is not fully of the desired color
* so we must go to next line of the buffer */
/* count*100/pixels < 3 */
if ((count * 100) / settings.pixels < 3)
{
found = 1;
DBG(DBG_data, "%s: strip found forward during pass %d at line %d\n", __func__,
pass, y);
}
else
{
DBG(DBG_data, "%s: pixels=%d, count=%d\n", __func__, settings.pixels, count);
}
}
}
else /* since calibration scans are done forward, we need the whole area
to be of the required color when searching backward */
{
count = 0;
for (y = 0; y < settings.lines; y++)
{
/* count of white/black pixels depending on the color searched */
for (x = 0; x < settings.pixels; x++)
{
/* when searching for black, detect white pixels */
if (black && data[y * settings.pixels + x] > 60)
{
count++;
}
/* when searching for white, detect black pixels */
if (!black && data[y * settings.pixels + x] < 60)
{
count++;
}
}
}
/* at end of area, if count >= 3%, area is not fully of the desired color
* so we must go to next buffer */
if ((count * 100) / (settings.pixels * settings.lines) < 3)
{
found = 1;
DBG(DBG_data, "%s: strip found backward during pass %d \n", __func__, pass);
}
else
{
DBG(DBG_data, "%s: pixels=%d, count=%d\n", __func__, settings.pixels, count);
}
}
pass++;
}
if (found)
{
DBG(DBG_info, "%s: strip found\n", __func__);
}
else
{
throw SaneException(SANE_STATUS_UNSUPPORTED, "%s strip not found", black ? "black" : "white");
}
}
void CommandSetGl646::wait_for_motor_stop(Genesys_Device* dev) const
{
(void) dev;

Wyświetl plik

@ -491,9 +491,6 @@ public:
void eject_document(Genesys_Device* dev) const override;
void search_strip(Genesys_Device* dev, const Genesys_Sensor& sensor,
bool forward, bool black) const override;
void move_to_ta(Genesys_Device* dev) const override;
void send_shading_data(Genesys_Device* dev, const Genesys_Sensor& sensor, uint8_t* data,

Wyświetl plik

@ -1819,7 +1819,7 @@ void CommandSetGl841::set_powersaving(Genesys_Device* dev, int delay /* in minut
dev->interface->write_registers(local_reg);
}
static void gl841_stop_action(Genesys_Device* dev)
void gl841_stop_action(Genesys_Device* dev)
{
DBG_HELPER(dbg);
Genesys_Register_Set local_reg;
@ -2225,7 +2225,7 @@ void CommandSetGl841::init_regs_for_shading(Genesys_Device* dev, const Genesys_S
unsigned channels = 3;
unsigned resolution = sensor.get_logical_hwdpi(dev->settings.xres);
unsigned resolution = sensor.get_register_hwdpi(dev->settings.xres);
const auto& calib_sensor = sanei_genesys_find_sensor(dev, resolution, channels,
dev->settings.scan_method);
@ -2313,7 +2313,7 @@ SensorExposure CommandSetGl841::led_calibration(Genesys_Device* dev, const Genes
/* offset calibration is always done in color mode */
unsigned channels = 3;
unsigned resolution = sensor.get_logical_hwdpi(dev->settings.xres);
unsigned resolution = sensor.get_register_hwdpi(dev->settings.xres);
const auto& calib_sensor_base = sanei_genesys_find_sensor(dev, resolution, channels,
dev->settings.scan_method);
@ -2504,7 +2504,7 @@ static void ad_fe_offset_calibration(Genesys_Device* dev, const Genesys_Sensor&
return;
}
unsigned resolution = sensor.get_logical_hwdpi(dev->settings.xres);
unsigned resolution = sensor.get_register_hwdpi(dev->settings.xres);
const auto& calib_sensor = sanei_genesys_find_sensor(dev, resolution, 3,
dev->settings.scan_method);
@ -2626,7 +2626,7 @@ void CommandSetGl841::offset_calibration(Genesys_Device* dev, const Genesys_Sens
/* offset calibration is always done in color mode */
unsigned channels = 3;
unsigned resolution = sensor.get_logical_hwdpi(dev->settings.xres);
unsigned resolution = sensor.get_register_hwdpi(dev->settings.xres);
const auto& calib_sensor = sanei_genesys_find_sensor(dev, resolution, channels,
dev->settings.scan_method);
@ -2963,7 +2963,7 @@ void CommandSetGl841::coarse_gain_calibration(Genesys_Device* dev, const Genesys
/* coarse gain calibration is allways done in color mode */
unsigned channels = 3;
unsigned resolution = sensor.get_logical_hwdpi(dev->settings.xres);
unsigned resolution = sensor.get_register_hwdpi(dev->settings.xres);
const auto& calib_sensor = sanei_genesys_find_sensor(dev, resolution, channels,
dev->settings.scan_method);
@ -3139,22 +3139,6 @@ void CommandSetGl841::init_regs_for_warmup(Genesys_Device* dev, const Genesys_Se
*total_size = num_pixels * 3 * 2 * 1; /* colors * bytes_per_color * scan lines */
}
/*
* this function moves head without scanning, forward, then backward
* so that the head goes to park position.
* as a by-product, also check for lock
*/
static void sanei_gl841_repark_head(Genesys_Device* dev)
{
DBG_HELPER(dbg);
scanner_move(*dev, dev->model->default_method, 232, Direction::FORWARD);
// toggle motor flag, put an huge step number and redo move backward
dev->cmd_set->move_back_home(dev, true);
}
/*
* initialize ASIC : registers, motor tables, and gamma tables
* then ensure scanner's head is at home
@ -3210,7 +3194,8 @@ void CommandSetGl841::init(Genesys_Device* dev) const
if (has_flag(dev->model->flags, ModelFlag::REPARK)) {
// FIXME: if repark fails, we should print an error message that the scanner is locked and
// the user should unlock the lock. We should also rethrow with SANE_STATUS_JAMMED
sanei_gl841_repark_head(dev);
scanner_move(*dev, dev->model->default_method, 232, Direction::FORWARD);
dev->cmd_set->move_back_home(dev, true);
}
// send gamma tables
@ -3220,7 +3205,7 @@ void CommandSetGl841::init(Genesys_Device* dev) const
Genesys_Register_Set& regs = dev->initial_regs;
regs = dev->reg;
unsigned resolution = sensor.get_logical_hwdpi(300);
unsigned resolution = sensor.get_register_hwdpi(300);
unsigned factor = sensor.optical_res / resolution;
const auto& calib_sensor = sanei_genesys_find_sensor(dev, resolution, 3,
@ -3308,204 +3293,6 @@ void CommandSetGl841::update_hardware_sensors(Genesys_Scanner* s) const
}
}
/** @brief search for a full width black or white strip.
* This function searches for a black or white stripe across the scanning area.
* When searching backward, the searched area must completely be of the desired
* color since this area will be used for calibration which scans forward.
* @param dev scanner device
* @param forward true if searching forward, false if searching backward
* @param black true if searching for a black strip, false for a white strip
*/
void CommandSetGl841::search_strip(Genesys_Device* dev, const Genesys_Sensor& sensor, bool forward,
bool black) const
{
DBG_HELPER_ARGS(dbg, "%s %s", black ? "black" : "white", forward ? "forward" : "reverse");
unsigned lines, channels;
Genesys_Register_Set local_reg;
unsigned int pass, count, found, length;
char title[80];
GenesysRegister *r;
uint8_t white_level=90; /**< default white level to detect white dots */
uint8_t black_level=60; /**< default black level to detect black dots */
/* use maximum gain when doing forward white strip detection
* since we don't have calibrated the sensor yet */
if(!black && forward)
{
dev->frontend.set_gain(0, 0xff);
dev->frontend.set_gain(1, 0xff);
dev->frontend.set_gain(2, 0xff);
}
dev->cmd_set->set_fe(dev, sensor, AFE_SET);
gl841_stop_action(dev);
// set up for a gray scan at lowest dpi
const auto& resolution_settings = dev->model->get_resolution_settings(dev->settings.scan_method);
unsigned dpi = resolution_settings.get_min_resolution_x();
channels = 1;
// shading calibation is done with dev->motor.base_ydpi
lines = 10; // TODO: use dev->model->search_lines
lines = static_cast<unsigned>((lines * dpi) / MM_PER_INCH);
/* 20 cm max length for calibration sheet */
length = static_cast<unsigned>(((200 * dpi) / MM_PER_INCH) / lines);
dev->set_head_pos_zero(ScanHeadId::PRIMARY);
local_reg = dev->reg;
ScanSession session;
session.params.xres = dpi;
session.params.yres = dpi;
session.params.startx = 0;
session.params.starty = 0;
session.params.pixels = dev->model->x_size_calib_mm * dpi / MM_PER_INCH;
session.params.lines = lines;
session.params.depth = 8;
session.params.channels = channels;
session.params.scan_method = dev->settings.scan_method;
session.params.scan_mode = ScanColorMode::GRAY;
session.params.color_filter = ColorFilter::RED;
session.params.flags = ScanFlag::DISABLE_SHADING | ScanFlag::DISABLE_GAMMA;
compute_session(dev, session, sensor);
init_regs_for_scan_session(dev, sensor, &local_reg, session);
/* set up for reverse or forward */
r = sanei_genesys_get_address(&local_reg, 0x02);
if (forward) {
r->value &= ~4;
} else {
r->value |= 4;
}
dev->interface->write_registers(local_reg);
dev->cmd_set->begin_scan(dev, sensor, &local_reg, true);
if (is_testing_mode()) {
dev->interface->test_checkpoint("search_strip");
gl841_stop_action(dev);
return;
}
// waits for valid data
wait_until_buffer_non_empty(dev);
// now we're on target, we can read data
auto image = read_unshuffled_image_from_scanner(dev, session, session.output_total_bytes);
gl841_stop_action(dev);
pass = 0;
if (DBG_LEVEL >= DBG_data) {
std::sprintf(title, "gl841_search_strip_%s_%s%02u.pnm", black ? "black" : "white",
forward ? "fwd" : "bwd", pass);
sanei_genesys_write_pnm_file(title, image);
}
/* loop until strip is found or maximum pass number done */
found = 0;
while (pass < length && !found)
{
dev->interface->write_registers(local_reg);
//now start scan
dev->cmd_set->begin_scan(dev, sensor, &local_reg, true);
// waits for valid data
wait_until_buffer_non_empty(dev);
// now we're on target, we can read data
image = read_unshuffled_image_from_scanner(dev, session, session.output_total_bytes);
gl841_stop_action (dev);
if (DBG_LEVEL >= DBG_data) {
std::sprintf(title, "gl841_search_strip_%s_%s%02u.pnm",
black ? "black" : "white", forward ? "fwd" : "bwd", pass);
sanei_genesys_write_pnm_file(title, image);
}
/* search data to find black strip */
/* when searching forward, we only need one line of the searched color since we
* will scan forward. But when doing backward search, we need all the area of the
* same color */
if (forward) {
for (std::size_t y = 0; y < image.get_height() && !found; y++) {
count = 0;
// count of white/black pixels depending on the color searched
for (std::size_t x = 0; x < image.get_width(); x++) {
// when searching for black, detect white pixels
if (black && image.get_raw_channel(x, y, 0) > white_level) {
count++;
}
// when searching for white, detect black pixels
if (!black && image.get_raw_channel(x, y, 0) < black_level) {
count++;
}
}
/* at end of line, if count >= 3%, line is not fully of the desired color
* so we must go to next line of the buffer */
auto found_percentage = (count * 100 / image.get_width());
if (found_percentage < 3) {
found = 1;
DBG(DBG_data, "%s: strip found forward during pass %d at line %zu\n", __func__,
pass, y);
} else {
DBG(DBG_data, "%s: pixels=%zu, count=%d (%zu%%)\n", __func__, image.get_width(),
count, found_percentage);
}
}
} else {
/* since calibration scans are done forward, we need the whole area
to be of the required color when searching backward
*/
count = 0;
for (std::size_t y = 0; y < image.get_height(); y++) {
/* count of white/black pixels depending on the color searched */
for (std::size_t x = 0; x < image.get_width(); x++) {
// when searching for black, detect white pixels
if (black && image.get_raw_channel(x, y, 0) > white_level) {
count++;
}
// when searching for white, detect black pixels
if (!black && image.get_raw_channel(x, y, 0) < black_level) {
count++;
}
}
}
/* at end of area, if count >= 3%, area is not fully of the desired color
* so we must go to next buffer */
auto found_percentage = count * 100 / (image.get_width() * image.get_height());
if (found_percentage < 3) {
found = 1;
DBG(DBG_data, "%s: strip found backward during pass %d \n", __func__, pass);
} else {
DBG(DBG_data, "%s: pixels=%zu, count=%d (%zu%%)\n", __func__, image.get_width(), count,
found_percentage);
}
}
pass++;
}
if (found)
{
DBG(DBG_info, "%s: %s strip found\n", __func__, black ? "black" : "white");
}
else
{
throw SaneException(SANE_STATUS_UNSUPPORTED, "%s strip not found", black ? "black" : "white");
}
}
/**
* Send shading calibration data. The buffer is considered to always hold values
* for all the channels.

Wyświetl plik

@ -105,9 +105,6 @@ public:
void eject_document(Genesys_Device* dev) const override;
void search_strip(Genesys_Device* dev, const Genesys_Sensor& sensor,
bool forward, bool black) const override;
void move_to_ta(Genesys_Device* dev) const override;
void send_shading_data(Genesys_Device* dev, const Genesys_Sensor& sensor, uint8_t* data,

Wyświetl plik

@ -985,6 +985,8 @@ static void gl843_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens
use_shdarea = session.params.xres <= 600;
} else if (dev->model->model_id == ModelId::CANON_8400F) {
use_shdarea = session.params.xres <= 400;
} else if (dev->model->model_id == ModelId::CANON_8600F) {
use_shdarea = true;
}
if (use_shdarea) {
r->value |= REG_0x01_SHDAREA;
@ -1422,8 +1424,7 @@ void CommandSetGl843::begin_scan(Genesys_Device* dev, const Genesys_Sensor& sens
break;
}
// clear scan and feed count
dev->interface->write_register(REG_0x0D, REG_0x0D_CLRLNCNT | REG_0x0D_CLRMCNT);
scanner_clear_scan_and_feed_counts(*dev);
// enable scan and motor
uint8_t val = dev->interface->read_register(REG_0x01);
@ -1513,7 +1514,7 @@ void CommandSetGl843::init_regs_for_shading(Genesys_Device* dev, const Genesys_S
calib_size_mm = dev->model->y_size_calib_mm;
}
unsigned resolution = sensor.get_logical_hwdpi(dev->settings.xres);
unsigned resolution = sensor.get_register_hwdpi(dev->settings.xres);
unsigned channels = 3;
const auto& calib_sensor = sanei_genesys_find_sensor(dev, resolution, channels,
@ -1828,7 +1829,7 @@ void CommandSetGl843::offset_calibration(Genesys_Device* dev, const Genesys_Sens
lines = 8;
// compute divider factor to compute final pixels number
dpihw = sensor.get_logical_hwdpi(dev->settings.xres);
dpihw = sensor.get_register_hwdpi(dev->settings.xres);
factor = sensor.optical_res / dpihw;
resolution = dpihw;
@ -2051,7 +2052,7 @@ void CommandSetGl843::coarse_gain_calibration(Genesys_Device* dev, const Genesys
if (dev->frontend.layout.type != FrontendType::WOLFSON)
return;
dpihw = sensor.get_logical_hwdpi(dpi);
dpihw = sensor.get_register_hwdpi(dpi);
// coarse gain calibration is always done in color mode
unsigned channels = 3;
@ -2192,7 +2193,7 @@ void CommandSetGl843::init_regs_for_warmup(Genesys_Device* dev, const Genesys_Se
/* setup scan */
*channels=3;
resolution=600;
dpihw = sensor.get_logical_hwdpi(resolution);
dpihw = sensor.get_register_hwdpi(resolution);
resolution=dpihw;
const auto& calib_sensor = sanei_genesys_find_sensor(dev, resolution, *channels,
@ -2404,198 +2405,6 @@ void CommandSetGl843::move_to_ta(Genesys_Device* dev) const
scanner_move(*dev, dev->model->default_method, feed, Direction::FORWARD);
}
/** @brief search for a full width black or white strip.
* This function searches for a black or white stripe across the scanning area.
* When searching backward, the searched area must completely be of the desired
* color since this area will be used for calibration which scans forward.
* @param dev scanner device
* @param forward true if searching forward, false if searching backward
* @param black true if searching for a black strip, false for a white strip
*/
void CommandSetGl843::search_strip(Genesys_Device* dev, const Genesys_Sensor& sensor,
bool forward, bool black) const
{
DBG_HELPER_ARGS(dbg, "%s %s", black ? "black" : "white", forward ? "forward" : "reverse");
unsigned channels;
Genesys_Register_Set local_reg;
int dpi;
unsigned int pass, count, found, x, y;
dev->cmd_set->set_fe(dev, sensor, AFE_SET);
scanner_stop_action(*dev);
/* set up for a gray scan at lowest dpi */
dpi = sanei_genesys_get_lowest_dpi(dev);
channels = 1;
const auto& calib_sensor = sanei_genesys_find_sensor(dev, dpi, channels,
dev->settings.scan_method);
/* 10 MM */
/* lines = (10 * dpi) / MM_PER_INCH; */
/* shading calibation is done with dev->motor.base_ydpi */
unsigned lines = static_cast<unsigned>(dev->model->y_size_calib_mm * dpi / MM_PER_INCH);
unsigned pixels = dev->model->x_size_calib_mm * dpi / MM_PER_INCH;
dev->set_head_pos_zero(ScanHeadId::PRIMARY);
local_reg = dev->reg;
ScanSession session;
session.params.xres = dpi;
session.params.yres = dpi;
session.params.startx = 0;
session.params.starty = 0;
session.params.pixels = pixels;
session.params.lines = lines;
session.params.depth = 8;
session.params.channels = channels;
session.params.scan_method = dev->settings.scan_method;
session.params.scan_mode = ScanColorMode::GRAY;
session.params.color_filter = ColorFilter::RED;
session.params.flags = ScanFlag::DISABLE_SHADING | ScanFlag::DISABLE_SHADING;
if (!forward) {
session.params.flags = ScanFlag::REVERSE;
}
compute_session(dev, session, calib_sensor);
init_regs_for_scan_session(dev, calib_sensor, &local_reg, session);
dev->interface->write_registers(local_reg);
dev->cmd_set->begin_scan(dev, calib_sensor, &local_reg, true);
if (is_testing_mode()) {
dev->interface->test_checkpoint("search_strip");
scanner_stop_action(*dev);
return;
}
wait_until_buffer_non_empty(dev);
// now we're on target, we can read data
auto data = read_unshuffled_image_from_scanner(dev, session,
session.output_total_bytes_raw);
scanner_stop_action(*dev);
pass = 0;
if (DBG_LEVEL >= DBG_data)
{
char fn[40];
std::snprintf(fn, 40, "gl843_search_strip_%s_%s%02d.pnm",
black ? "black" : "white", forward ? "fwd" : "bwd", pass);
sanei_genesys_write_pnm_file(fn, data);
}
/* loop until strip is found or maximum pass number done */
found = 0;
while (pass < 20 && !found)
{
dev->interface->write_registers(local_reg);
// now start scan
dev->cmd_set->begin_scan(dev, calib_sensor, &local_reg, true);
wait_until_buffer_non_empty(dev);
// now we're on target, we can read data
data = read_unshuffled_image_from_scanner(dev, session, session.output_total_bytes_raw);
scanner_stop_action(*dev);
if (DBG_LEVEL >= DBG_data)
{
char fn[40];
std::snprintf(fn, 40, "gl843_search_strip_%s_%s%02d.pnm",
black ? "black" : "white", forward ? "fwd" : "bwd", pass);
sanei_genesys_write_pnm_file(fn, data);
}
/* search data to find black strip */
/* when searching forward, we only need one line of the searched color since we
* will scan forward. But when doing backward search, we need all the area of the
* same color */
if (forward)
{
for (y = 0; y < lines && !found; y++)
{
count = 0;
/* count of white/black pixels depending on the color searched */
for (x = 0; x < pixels; x++)
{
/* when searching for black, detect white pixels */
if (black && data.get_raw_channel(x, y, 0) > 90) {
count++;
}
/* when searching for white, detect black pixels */
if (!black && data.get_raw_channel(x, y, 0) < 60) {
count++;
}
}
/* at end of line, if count >= 3%, line is not fully of the desired color
* so we must go to next line of the buffer */
/* count*100/pixels < 3 */
if ((count * 100) / pixels < 3)
{
found = 1;
DBG(DBG_data, "%s: strip found forward during pass %d at line %d\n", __func__,
pass, y);
}
else
{
DBG(DBG_data, "%s: pixels=%d, count=%d (%d%%)\n", __func__, pixels, count,
(100 * count) / pixels);
}
}
}
else /* since calibration scans are done forward, we need the whole area
to be of the required color when searching backward */
{
count = 0;
for (y = 0; y < lines; y++)
{
/* count of white/black pixels depending on the color searched */
for (x = 0; x < pixels; x++)
{
// when searching for black, detect white pixels
if (black && data.get_raw_channel(x, y, 0) > 90) {
count++;
}
// when searching for white, detect black pixels
if (!black && data.get_raw_channel(x, y, 0) < 60) {
count++;
}
}
}
/* at end of area, if count >= 3%, area is not fully of the desired color
* so we must go to next buffer */
if ((count * 100) / (pixels * lines) < 3)
{
found = 1;
DBG(DBG_data, "%s: strip found backward during pass %d \n", __func__, pass);
}
else
{
DBG(DBG_data, "%s: pixels=%d, count=%d (%d%%)\n", __func__, pixels, count,
(100 * count) / pixels);
}
}
pass++;
}
if (found)
{
DBG(DBG_info, "%s: %s strip found\n", __func__, black ? "black" : "white");
}
else
{
throw SaneException(SANE_STATUS_UNSUPPORTED, "%s strip not found", black ? "black" : "white");
}
}
/**
* Send shading calibration data. The buffer is considered to always hold values
* for all the channels.
@ -2631,7 +2440,7 @@ void CommandSetGl843::send_shading_data(Genesys_Device* dev, const Genesys_Senso
dev->model->model_id == ModelId::CANON_8600F)
{
int half_ccd_factor = dev->session.optical_resolution /
sensor.get_logical_hwdpi(dev->session.output_resolution);
sensor.get_register_hwdpi(dev->session.output_resolution);
strpixel /= half_ccd_factor * sensor.ccd_pixels_per_system_pixel();
endpixel /= half_ccd_factor * sensor.ccd_pixels_per_system_pixel();
}

Wyświetl plik

@ -105,9 +105,6 @@ public:
void eject_document(Genesys_Device* dev) const override;
void search_strip(Genesys_Device* dev, const Genesys_Sensor& sensor,
bool forward, bool black) const override;
void move_to_ta(Genesys_Device* dev) const override;
void send_shading_data(Genesys_Device* dev, const Genesys_Sensor& sensor, uint8_t* data,

Wyświetl plik

@ -741,21 +741,33 @@ ScanSession CommandSetGl846::calculate_scan_session(const Genesys_Device* dev,
const Genesys_Sensor& sensor,
const Genesys_Settings& settings) const
{
int start;
DBG(DBG_info, "%s ", __func__);
debug_dump(DBG_info, settings);
/* start */
start = static_cast<int>(dev->model->x_offset);
start += static_cast<int>(settings.tl_x);
start = static_cast<int>((start * settings.xres) / MM_PER_INCH);
/* Steps to move to reach scanning area:
- first we move to physical start of scanning either by a fixed steps amount from the
black strip or by a fixed amount from parking position, minus the steps done during
shading calibration.
- then we move by the needed offset whitin physical scanning area
*/
unsigned move_dpi = dev->motor.base_ydpi;
float move = dev->model->y_offset;
move = move + settings.tl_y;
move = static_cast<float>((move * move_dpi) / MM_PER_INCH);
move -= dev->head_pos(ScanHeadId::PRIMARY);
float start = dev->model->x_offset;
start = start + dev->settings.tl_x;
start = static_cast<float>((start * settings.xres) / MM_PER_INCH);
ScanSession session;
session.params.xres = settings.xres;
session.params.yres = settings.yres;
session.params.startx = start; // not used
session.params.starty = 0; // not used
session.params.startx = static_cast<unsigned>(start);
session.params.starty = static_cast<unsigned>(move);
session.params.pixels = settings.pixels;
session.params.requested_pixels = settings.requested_pixels;
session.params.lines = settings.lines;
@ -764,7 +776,8 @@ ScanSession CommandSetGl846::calculate_scan_session(const Genesys_Device* dev,
session.params.scan_method = settings.scan_method;
session.params.scan_mode = settings.scan_mode;
session.params.color_filter = settings.color_filter;
session.params.flags = ScanFlag::NONE;
// backtracking isn't handled well, so don't enable it
session.params.flags = ScanFlag::DISABLE_BUFFER_FULL_MOVE;
compute_session(dev, session, sensor);
@ -799,10 +812,7 @@ void CommandSetGl846::begin_scan(Genesys_Device* dev, const Genesys_Sensor& sens
dev->interface->write_register(REG_0x6C, val);
*/
val = REG_0x0D_CLRLNCNT;
dev->interface->write_register(REG_0x0D, val);
val = REG_0x0D_CLRMCNT;
dev->interface->write_register(REG_0x0D, val);
scanner_clear_scan_and_feed_counts(*dev);
val = dev->interface->read_register(REG_0x01);
val |= REG_0x01_SCAN;
@ -888,73 +898,21 @@ void CommandSetGl846::init_regs_for_scan(Genesys_Device* dev, const Genesys_Sens
Genesys_Register_Set& regs) const
{
DBG_HELPER(dbg);
float move;
int move_dpi;
float start;
debug_dump(DBG_info, dev->settings);
auto session = calculate_scan_session(dev, sensor, dev->settings);
/* steps to move to reach scanning area:
- first we move to physical start of scanning
either by a fixed steps amount from the black strip
or by a fixed amount from parking position,
minus the steps done during shading calibration
- then we move by the needed offset whitin physical
scanning area
/* Fast move to scan area:
assumption: steps are expressed at maximum motor resolution
we need:
float y_offset;
float y_size;
float y_offset_calib;
mm_to_steps()=motor dpi / 2.54 / 10=motor dpi / MM_PER_INCH */
/* if scanner uses ModelFlag::SEARCH_START y_offset is
relative from origin, else, it is from parking position */
move_dpi = dev->motor.base_ydpi;
move = dev->model->y_offset;
move = move + dev->settings.tl_y;
move = static_cast<float>((move * move_dpi) / MM_PER_INCH);
move -= dev->head_pos(ScanHeadId::PRIMARY);
DBG(DBG_info, "%s: move=%f steps\n", __func__, move);
/* fast move to scan area */
/* we don't move fast the whole distance since it would involve
* computing acceleration/deceleration distance for scan
* resolution. So leave a remainder for it so scan makes the final
* move tuning */
if (dev->settings.get_channels() * dev->settings.yres >= 600 && move > 700) {
scanner_move(*dev, dev->model->default_method, static_cast<unsigned>(move - 500),
We don't move fast the whole distance since it would involve computing
acceleration/deceleration distance for scan resolution. So leave a remainder for it so
scan makes the final move tuning
*/
if (dev->settings.get_channels() * dev->settings.yres >= 600 && session.params.starty > 700) {
scanner_move(*dev, dev->model->default_method,
static_cast<unsigned>(session.params.starty - 500),
Direction::FORWARD);
move=500;
session.params.starty = 500;
}
DBG(DBG_info, "%s: move=%f steps\n", __func__, move);
DBG(DBG_info, "%s: move=%f steps\n", __func__, move);
/* start */
start = dev->model->x_offset;
start = start + dev->settings.tl_x;
start = static_cast<float>((start * dev->settings.xres) / MM_PER_INCH);
ScanSession session;
session.params.xres = dev->settings.xres;
session.params.yres = dev->settings.yres;
session.params.startx = static_cast<unsigned>(start);
session.params.starty = static_cast<unsigned>(move);
session.params.pixels = dev->settings.pixels;
session.params.requested_pixels = dev->settings.requested_pixels;
session.params.lines = dev->settings.lines;
session.params.depth = dev->settings.depth;
session.params.channels = dev->settings.get_channels();
session.params.scan_method = dev->settings.scan_method;
session.params.scan_mode = dev->settings.scan_mode;
session.params.color_filter = dev->settings.color_filter;
// backtracking isn't handled well, so don't enable it
session.params.flags = ScanFlag::DISABLE_BUFFER_FULL_MOVE;
compute_session(dev, session, sensor);
init_regs_for_scan_session(dev, sensor, &regs, session);
@ -1364,192 +1322,6 @@ void CommandSetGl846::update_home_sensor_gpio(Genesys_Device& dev) const
dev.interface->write_register(REG_0x6C, val);
}
/** @brief search for a full width black or white strip.
* This function searches for a black or white stripe across the scanning area.
* When searching backward, the searched area must completely be of the desired
* color since this area will be used for calibration which scans forward.
* @param dev scanner device
* @param forward true if searching forward, false if searching backward
* @param black true if searching for a black strip, false for a white strip
*/
void CommandSetGl846::search_strip(Genesys_Device* dev, const Genesys_Sensor& sensor, bool forward,
bool black) const
{
DBG_HELPER_ARGS(dbg, "%s %s", black ? "black" : "white", forward ? "forward" : "reverse");
unsigned channels;
Genesys_Register_Set local_reg;
unsigned int pass, count, found;
char title[80];
set_fe(dev, sensor, AFE_SET);
scanner_stop_action(*dev);
// set up for a gray scan at lowest dpi
const auto& resolution_settings = dev->model->get_resolution_settings(dev->settings.scan_method);
unsigned dpi = resolution_settings.get_min_resolution_x();
channels = 1;
/* 10 MM */
/* lines = (10 * dpi) / MM_PER_INCH; */
/* shading calibation is done with dev->motor.base_ydpi */
unsigned lines = static_cast<unsigned>(dev->model->y_size_calib_mm * dpi / MM_PER_INCH);
dev->set_head_pos_zero(ScanHeadId::PRIMARY);
local_reg = dev->reg;
ScanSession session;
session.params.xres = dpi;
session.params.yres = dpi;
session.params.startx = 0;
session.params.starty = 0;
session.params.pixels = dev->model->x_size_calib_mm * dpi / MM_PER_INCH;
session.params.lines = lines;
session.params.depth = 8;
session.params.channels = channels;
session.params.scan_mode = ScanColorMode::GRAY;
session.params.color_filter = ColorFilter::RED;
session.params.flags = ScanFlag::DISABLE_SHADING |
ScanFlag::DISABLE_GAMMA;
if (!forward) {
session.params.flags |= ScanFlag::REVERSE;
}
compute_session(dev, session, sensor);
init_regs_for_scan_session(dev, sensor, &local_reg, session);
dev->interface->write_registers(local_reg);
begin_scan(dev, sensor, &local_reg, true);
if (is_testing_mode()) {
dev->interface->test_checkpoint("search_strip");
scanner_stop_action(*dev);
return;
}
wait_until_buffer_non_empty(dev);
// now we're on target, we can read data
auto image = read_unshuffled_image_from_scanner(dev, session, session.output_total_bytes);
scanner_stop_action(*dev);
pass = 0;
if (DBG_LEVEL >= DBG_data)
{
std::sprintf(title, "gl846_search_strip_%s_%s%02d.pnm",
black ? "black" : "white", forward ? "fwd" : "bwd", pass);
sanei_genesys_write_pnm_file(title, image);
}
/* loop until strip is found or maximum pass number done */
found = 0;
while (pass < 20 && !found)
{
dev->interface->write_registers(local_reg);
// now start scan
begin_scan(dev, sensor, &local_reg, true);
wait_until_buffer_non_empty(dev);
// now we're on target, we can read data
image = read_unshuffled_image_from_scanner(dev, session, session.output_total_bytes);
scanner_stop_action(*dev);
if (DBG_LEVEL >= DBG_data)
{
std::sprintf(title, "gl846_search_strip_%s_%s%02d.pnm",
black ? "black" : "white", forward ? "fwd" : "bwd", pass);
sanei_genesys_write_pnm_file(title, image);
}
unsigned white_level = 90;
unsigned black_level = 60;
/* search data to find black strip */
/* when searching forward, we only need one line of the searched color since we
* will scan forward. But when doing backward search, we need all the area of the
* same color */
if (forward) {
for (std::size_t y = 0; y < image.get_height() && !found; y++) {
count = 0;
// count of white/black pixels depending on the color searched
for (std::size_t x = 0; x < image.get_width(); x++) {
// when searching for black, detect white pixels
if (black && image.get_raw_channel(x, y, 0) > white_level) {
count++;
}
// when searching for white, detect black pixels
if (!black && image.get_raw_channel(x, y, 0) < black_level) {
count++;
}
}
/* at end of line, if count >= 3%, line is not fully of the desired color
* so we must go to next line of the buffer */
auto found_percentage = (count * 100 / image.get_width());
if (found_percentage < 3) {
found = 1;
DBG(DBG_data, "%s: strip found forward during pass %d at line %zu\n", __func__,
pass, y);
}
else
{
DBG(DBG_data, "%s: pixels=%zu, count=%d (%zu%%)\n", __func__, image.get_width(),
count, found_percentage);
}
}
} else {
/* since calibration scans are done forward, we need the whole area
to be of the required color when searching backward
*/
count = 0;
for (std::size_t y = 0; y < image.get_height(); y++) {
// count of white/black pixels depending on the color searched
for (std::size_t x = 0; x < image.get_width(); x++) {
// when searching for black, detect white pixels
if (black && image.get_raw_channel(x, y, 0) > white_level) {
count++;
}
// when searching for white, detect black pixels
if (!black && image.get_raw_channel(x, y, 0) < black_level) {
count++;
}
}
}
/* at end of area, if count >= 3%, area is not fully of the desired color
* so we must go to next buffer */
auto found_percentage = count * 100 / (image.get_width() * image.get_height());
if (found_percentage < 3) {
found = 1;
DBG(DBG_data, "%s: strip found backward during pass %d \n", __func__, pass);
} else {
DBG(DBG_data, "%s: pixels=%zu, count=%d (%zu%%)\n", __func__, image.get_width(),
count, found_percentage);
}
}
pass++;
}
if (found)
{
DBG(DBG_info, "%s: %s strip found\n", __func__, black ? "black" : "white");
}
else
{
throw SaneException(SANE_STATUS_UNSUPPORTED, "%s strip not found", black ? "black" : "white");
}
}
/**
* average dark pixels of a 8 bits scan
*/

Wyświetl plik

@ -184,9 +184,6 @@ public:
void eject_document(Genesys_Device* dev) const override;
void search_strip(Genesys_Device* dev, const Genesys_Sensor& sensor,
bool forward, bool black) const override;
void move_to_ta(Genesys_Device* dev) const override;
void send_shading_data(Genesys_Device* dev, const Genesys_Sensor& sensor, uint8_t* data,

Wyświetl plik

@ -743,21 +743,33 @@ ScanSession CommandSetGl847::calculate_scan_session(const Genesys_Device* dev,
const Genesys_Sensor& sensor,
const Genesys_Settings& settings) const
{
int start;
DBG(DBG_info, "%s ", __func__);
debug_dump(DBG_info, settings);
/* start */
start = static_cast<int>(dev->model->x_offset);
start = static_cast<int>(start + settings.tl_x);
start = static_cast<int>((start * settings.xres) / MM_PER_INCH);
/* Steps to move to reach scanning area:
- first we move to physical start of scanning either by a fixed steps amount from the
black strip or by a fixed amount from parking position, minus the steps done during
shading calibration.
- then we move by the needed offset whitin physical scanning area
*/
unsigned move_dpi = dev->motor.base_ydpi;
float move = dev->model->y_offset;
move = move + settings.tl_y;
move = static_cast<float>((move * move_dpi) / MM_PER_INCH);
move -= dev->head_pos(ScanHeadId::PRIMARY);
float start = dev->model->x_offset;
start = start + dev->settings.tl_x;
start = static_cast<float>((start * settings.xres) / MM_PER_INCH);
ScanSession session;
session.params.xres = settings.xres;
session.params.yres = settings.yres;
session.params.startx = start; // not used
session.params.starty = 0; // not used
session.params.startx = static_cast<unsigned>(start);
session.params.starty = static_cast<unsigned>(move);
session.params.pixels = settings.pixels;
session.params.requested_pixels = settings.requested_pixels;
session.params.lines = settings.lines;
@ -766,7 +778,8 @@ ScanSession CommandSetGl847::calculate_scan_session(const Genesys_Device* dev,
session.params.scan_method = settings.scan_method;
session.params.scan_mode = settings.scan_mode;
session.params.color_filter = settings.color_filter;
session.params.flags = ScanFlag::NONE;
// backtracking isn't handled well, so don't enable it
session.params.flags = ScanFlag::DISABLE_BUFFER_FULL_MOVE;
compute_session(dev, session, sensor);
@ -889,73 +902,21 @@ void CommandSetGl847::init_regs_for_scan(Genesys_Device* dev, const Genesys_Sens
Genesys_Register_Set& regs) const
{
DBG_HELPER(dbg);
float move;
int move_dpi;
float start;
debug_dump(DBG_info, dev->settings);
auto session = calculate_scan_session(dev, sensor, dev->settings);
/* steps to move to reach scanning area:
- first we move to physical start of scanning
either by a fixed steps amount from the black strip
or by a fixed amount from parking position,
minus the steps done during shading calibration
- then we move by the needed offset whitin physical
scanning area
/* Fast move to scan area:
assumption: steps are expressed at maximum motor resolution
we need:
float y_offset;
float y_size;
float y_offset_calib;
mm_to_steps()=motor dpi / 2.54 / 10=motor dpi / MM_PER_INCH */
/* if scanner uses ModelFlag::SEARCH_START y_offset is
relative from origin, else, it is from parking position */
move_dpi = dev->motor.base_ydpi;
move = dev->model->y_offset;
move = static_cast<float>(move + dev->settings.tl_y);
move = static_cast<float>((move * move_dpi) / MM_PER_INCH);
move -= dev->head_pos(ScanHeadId::PRIMARY);
DBG(DBG_info, "%s: move=%f steps\n", __func__, move);
/* fast move to scan area */
/* we don't move fast the whole distance since it would involve
* computing acceleration/deceleration distance for scan
* resolution. So leave a remainder for it so scan makes the final
* move tuning */
if (dev->settings.get_channels() * dev->settings.yres >= 600 && move > 700) {
scanner_move(*dev, dev->model->default_method, static_cast<unsigned>(move - 500),
We don't move fast the whole distance since it would involve computing
acceleration/deceleration distance for scan resolution. So leave a remainder for it so
scan makes the final move tuning
*/
if (dev->settings.get_channels() * dev->settings.yres >= 600 && session.params.starty > 700) {
scanner_move(*dev, dev->model->default_method,
static_cast<unsigned>(session.params.starty - 500),
Direction::FORWARD);
move=500;
session.params.starty = 500;
}
DBG(DBG_info, "%s: move=%f steps\n", __func__, move);
DBG(DBG_info, "%s: move=%f steps\n", __func__, move);
/* start */
start = dev->model->x_offset;
start = start + dev->settings.tl_x;
start = static_cast<float>((start * dev->settings.xres) / MM_PER_INCH);
ScanSession session;
session.params.xres = dev->settings.xres;
session.params.yres = dev->settings.yres;
session.params.startx = static_cast<unsigned>(start);
session.params.starty = static_cast<unsigned>(move);
session.params.pixels = dev->settings.pixels;
session.params.requested_pixels = dev->settings.requested_pixels;
session.params.lines = dev->settings.lines;
session.params.depth = dev->settings.depth;
session.params.channels = dev->settings.get_channels();
session.params.scan_method = dev->settings.scan_method;
session.params.scan_mode = dev->settings.scan_mode;
session.params.color_filter = dev->settings.color_filter;
// backtracking isn't handled well, so don't enable it
session.params.flags = ScanFlag::DISABLE_BUFFER_FULL_MOVE;
compute_session(dev, session, sensor);
init_regs_for_scan_session(dev, sensor, &regs, session);
@ -1402,187 +1363,6 @@ void CommandSetGl847::update_home_sensor_gpio(Genesys_Device& dev) const
}
}
/** @brief search for a full width black or white strip.
* This function searches for a black or white stripe across the scanning area.
* When searching backward, the searched area must completely be of the desired
* color since this area will be used for calibration which scans forward.
* @param dev scanner device
* @param forward true if searching forward, false if searching backward
* @param black true if searching for a black strip, false for a white strip
*/
void CommandSetGl847::search_strip(Genesys_Device* dev, const Genesys_Sensor& sensor, bool forward,
bool black) const
{
DBG_HELPER_ARGS(dbg, "%s %s", black ? "black" : "white", forward ? "forward" : "reverse");
Genesys_Register_Set local_reg;
unsigned int pass, count, found;
char title[80];
set_fe(dev, sensor, AFE_SET);
scanner_stop_action(*dev);
// set up for a gray scan at lowest dpi
const auto& resolution_settings = dev->model->get_resolution_settings(dev->settings.scan_method);
unsigned dpi = resolution_settings.get_min_resolution_x();
unsigned channels = 1;
unsigned lines = static_cast<unsigned>(dev->model->y_size_calib_mm * dpi / MM_PER_INCH);
dev->set_head_pos_zero(ScanHeadId::PRIMARY);
local_reg = dev->reg;
ScanSession session;
session.params.xres = dpi;
session.params.yres = dpi;
session.params.startx = 0;
session.params.starty = 0;
session.params.pixels = dev->model->x_size_calib_mm * dpi / MM_PER_INCH;
session.params.lines = lines;
session.params.depth = 8;
session.params.channels = channels;
session.params.scan_method = dev->settings.scan_method;
session.params.scan_mode = ScanColorMode::GRAY;
session.params.color_filter = ColorFilter::RED;
session.params.flags = ScanFlag::DISABLE_SHADING |
ScanFlag::DISABLE_GAMMA;
if (!forward) {
session.params.flags |= ScanFlag::REVERSE;
}
compute_session(dev, session, sensor);
init_regs_for_scan_session(dev, sensor, &local_reg, session);
dev->interface->write_registers(local_reg);
begin_scan(dev, sensor, &local_reg, true);
if (is_testing_mode()) {
dev->interface->test_checkpoint("search_strip");
scanner_stop_action(*dev);
return;
}
wait_until_buffer_non_empty(dev);
// now we're on target, we can read data
auto image = read_unshuffled_image_from_scanner(dev, session, session.output_total_bytes);
scanner_stop_action(*dev);
pass = 0;
if (DBG_LEVEL >= DBG_data) {
std::sprintf(title, "gl847_search_strip_%s_%s%02d.pnm",
black ? "black" : "white", forward ? "fwd" : "bwd", pass);
sanei_genesys_write_pnm_file(title, image);
}
/* loop until strip is found or maximum pass number done */
found = 0;
while (pass < 20 && !found)
{
dev->interface->write_registers(local_reg);
// now start scan
begin_scan(dev, sensor, &local_reg, true);
wait_until_buffer_non_empty(dev);
// now we're on target, we can read data
image = read_unshuffled_image_from_scanner(dev, session, session.output_total_bytes);
scanner_stop_action(*dev);
if (DBG_LEVEL >= DBG_data) {
std::sprintf(title, "gl847_search_strip_%s_%s%02d.pnm",
black ? "black" : "white",
forward ? "fwd" : "bwd", static_cast<int>(pass));
sanei_genesys_write_pnm_file(title, image);
}
unsigned white_level = 90;
unsigned black_level = 60;
/* search data to find black strip */
/* when searching forward, we only need one line of the searched color since we
* will scan forward. But when doing backward search, we need all the area of the
* same color */
if (forward) {
for (std::size_t y = 0; y < image.get_height() && !found; y++) {
count = 0;
// count of white/black pixels depending on the color searched
for (std::size_t x = 0; x < image.get_width(); x++) {
// when searching for black, detect white pixels
if (black && image.get_raw_channel(x, y, 0) > white_level) {
count++;
}
// when searching for white, detect black pixels
if (!black && image.get_raw_channel(x, y, 0) < black_level) {
count++;
}
}
/* at end of line, if count >= 3%, line is not fully of the desired color
* so we must go to next line of the buffer */
/* count*100/pixels < 3 */
auto found_percentage = (count * 100 / image.get_width());
if (found_percentage < 3) {
found = 1;
DBG(DBG_data, "%s: strip found forward during pass %d at line %zu\n", __func__,
pass, y);
}
else
{
DBG(DBG_data, "%s: pixels=%zu, count=%d (%zu%%)\n", __func__, image.get_width(),
count, found_percentage);
}
}
} else {
/* since calibration scans are done forward, we need the whole area
to be of the required color when searching backward
*/
count = 0;
for (std::size_t y = 0; y < image.get_height(); y++) {
// count of white/black pixels depending on the color searched
for (std::size_t x = 0; x < image.get_width(); x++) {
// when searching for black, detect white pixels
if (black && image.get_raw_channel(x, y, 0) > white_level) {
count++;
}
// when searching for white, detect black pixels
if (!black && image.get_raw_channel(x, y, 0) < black_level) {
count++;
}
}
}
/* at end of area, if count >= 3%, area is not fully of the desired color
* so we must go to next buffer */
auto found_percentage = count * 100 / (image.get_width() * image.get_height());
if (found_percentage < 3) {
found = 1;
DBG(DBG_data, "%s: strip found backward during pass %d \n", __func__, pass);
} else {
DBG(DBG_data, "%s: pixels=%zu, count=%d (%zu%%)\n", __func__, image.get_width(),
count, found_percentage);
}
}
pass++;
}
if (found)
{
DBG(DBG_info, "%s: %s strip found\n", __func__, black ? "black" : "white");
}
else
{
throw SaneException(SANE_STATUS_UNSUPPORTED, "%s strip not found", black ? "black" : "white");
}
}
/**
* average dark pixels of a 8 bits scan
*/

Wyświetl plik

@ -172,9 +172,6 @@ public:
void eject_document(Genesys_Device* dev) const override;
void search_strip(Genesys_Device* dev, const Genesys_Sensor& sensor,
bool forward, bool black) const override;
void move_to_ta(Genesys_Device* dev) const override;
void send_shading_data(Genesys_Device* dev, const Genesys_Sensor& sensor, uint8_t* data,

Wyświetl plik

@ -292,6 +292,17 @@ void scanner_move(Genesys_Device& dev, ScanMethod scan_method, unsigned steps, D
void scanner_move_back_home(Genesys_Device& dev, bool wait_until_home);
void scanner_move_back_home_ta(Genesys_Device& dev);
/** Search for a full width black or white strip.
This function searches for a black or white stripe across the scanning area.
When searching backward, the searched area must completely be of the desired
color since this area will be used for calibration which scans forward.
@param dev scanner device
@param forward true if searching forward, false if searching backward
@param black true if searching for a black strip, false for a white strip
*/
void scanner_search_strip(Genesys_Device& dev, bool forward, bool black);
void scanner_clear_scan_and_feed_counts(Genesys_Device& dev);
extern void sanei_genesys_write_file(const char* filename, const std::uint8_t* data,

Wyświetl plik

@ -407,12 +407,10 @@ struct Genesys_Sensor {
// red, green and blue gamma coefficient for default gamma tables
AssignableArray<float, 3> gamma;
std::function<unsigned(const Genesys_Sensor&, unsigned)> get_logical_hwdpi_fun;
std::function<unsigned(const Genesys_Sensor&, unsigned)> get_register_hwdpi_fun;
std::function<unsigned(const Genesys_Sensor&, unsigned)> get_ccd_size_divisor_fun;
std::function<unsigned(const Genesys_Sensor&, unsigned)> get_hwdpi_divisor_fun;
unsigned get_logical_hwdpi(unsigned xres) const { return get_logical_hwdpi_fun(*this, xres); }
unsigned get_register_hwdpi(unsigned xres) const { return get_register_hwdpi_fun(*this, xres); }
unsigned get_ccd_size_divisor_for_dpi(unsigned xres) const
{

Wyświetl plik

@ -47,7 +47,7 @@
namespace genesys {
inline unsigned default_get_logical_hwdpi(const Genesys_Sensor& sensor, unsigned xres)
inline unsigned default_get_register_hwdpi(const Genesys_Sensor& sensor, unsigned xres)
{
if (sensor.logical_dpihw_override)
return sensor.logical_dpihw_override;
@ -106,7 +106,7 @@ inline unsigned get_ccd_size_divisor_gl124(const Genesys_Sensor& sensor, unsigne
inline unsigned default_get_hwdpi_divisor_for_dpi(const Genesys_Sensor& sensor, unsigned xres)
{
return sensor.optical_res / default_get_logical_hwdpi(sensor, xres);
return sensor.optical_res / default_get_register_hwdpi(sensor, xres);
}
StaticInit<std::vector<Genesys_Sensor>> s_sensors;
@ -154,8 +154,7 @@ void genesys_init_sensor_tables()
{ 0x5e, 0x00 },
};
sensor.gamma = { 1.0f, 1.0f, 1.0f };
sensor.get_logical_hwdpi_fun = default_get_logical_hwdpi;
sensor.get_register_hwdpi_fun = default_get_logical_hwdpi;
sensor.get_register_hwdpi_fun = default_get_register_hwdpi;
sensor.get_hwdpi_divisor_fun = default_get_hwdpi_divisor_for_dpi;
sensor.get_ccd_size_divisor_fun = default_get_ccd_size_divisor_for_dpi;
s_sensors->push_back(sensor);
@ -198,8 +197,7 @@ void genesys_init_sensor_tables()
{ 0x5e, 0x00 },
};
sensor.gamma = { 1.0f, 1.0f, 1.0f };
sensor.get_logical_hwdpi_fun = default_get_logical_hwdpi;
sensor.get_register_hwdpi_fun = default_get_logical_hwdpi;
sensor.get_register_hwdpi_fun = default_get_register_hwdpi;
sensor.get_hwdpi_divisor_fun = default_get_hwdpi_divisor_for_dpi;
sensor.get_ccd_size_divisor_fun = default_get_ccd_size_divisor_for_dpi;
s_sensors->push_back(sensor);
@ -242,8 +240,7 @@ void genesys_init_sensor_tables()
{ 0x5e, 0x00 },
};
sensor.gamma = { 1.0f, 1.0f, 1.0f };
sensor.get_logical_hwdpi_fun = default_get_logical_hwdpi;
sensor.get_register_hwdpi_fun = default_get_logical_hwdpi;
sensor.get_register_hwdpi_fun = default_get_register_hwdpi;
sensor.get_hwdpi_divisor_fun = default_get_hwdpi_divisor_for_dpi;
sensor.get_ccd_size_divisor_fun = default_get_ccd_size_divisor_for_dpi;
s_sensors->push_back(sensor);
@ -288,8 +285,7 @@ void genesys_init_sensor_tables()
{ 0x5e, 0x00 },
};
sensor.gamma = { 2.38f, 2.35f, 2.34f };
sensor.get_logical_hwdpi_fun = default_get_logical_hwdpi;
sensor.get_register_hwdpi_fun = default_get_logical_hwdpi;
sensor.get_register_hwdpi_fun = default_get_register_hwdpi;
sensor.get_hwdpi_divisor_fun = default_get_hwdpi_divisor_for_dpi;
sensor.get_ccd_size_divisor_fun = get_ccd_size_divisor_exact;
@ -605,8 +601,7 @@ void genesys_init_sensor_tables()
{ 0x5e, 0x00 },
};
sensor.gamma = { 2.1f, 2.1f, 2.1f };
sensor.get_logical_hwdpi_fun = default_get_logical_hwdpi;
sensor.get_register_hwdpi_fun = default_get_logical_hwdpi;
sensor.get_register_hwdpi_fun = default_get_register_hwdpi;
sensor.get_hwdpi_divisor_fun = default_get_hwdpi_divisor_for_dpi;
sensor.get_ccd_size_divisor_fun = get_ccd_size_divisor_exact;
@ -836,8 +831,7 @@ void genesys_init_sensor_tables()
{ 0x5e, 0x16 },
};
sensor.gamma = { 2.1f, 2.1f, 2.1f };
sensor.get_logical_hwdpi_fun = default_get_logical_hwdpi;
sensor.get_register_hwdpi_fun = default_get_logical_hwdpi;
sensor.get_register_hwdpi_fun = default_get_register_hwdpi;
sensor.get_hwdpi_divisor_fun = default_get_hwdpi_divisor_for_dpi;
sensor.get_ccd_size_divisor_fun = get_ccd_size_divisor_exact;
@ -1013,8 +1007,7 @@ void genesys_init_sensor_tables()
{ 0x5e, 0x00 },
};
sensor.gamma = { 1.0f, 1.0f, 1.0f };
sensor.get_logical_hwdpi_fun = default_get_logical_hwdpi;
sensor.get_register_hwdpi_fun = default_get_logical_hwdpi;
sensor.get_register_hwdpi_fun = default_get_register_hwdpi;
sensor.get_hwdpi_divisor_fun = default_get_hwdpi_divisor_for_dpi;
sensor.get_ccd_size_divisor_fun = default_get_ccd_size_divisor_for_dpi;
s_sensors->push_back(sensor);
@ -1084,8 +1077,7 @@ void genesys_init_sensor_tables()
{ 0x5e, 0x00 }
};
sensor.gamma = { 2.1f, 2.1f, 2.1f };
sensor.get_logical_hwdpi_fun = default_get_logical_hwdpi;
sensor.get_register_hwdpi_fun = default_get_logical_hwdpi;
sensor.get_register_hwdpi_fun = default_get_register_hwdpi;
sensor.get_hwdpi_divisor_fun = default_get_hwdpi_divisor_for_dpi;
sensor.get_ccd_size_divisor_fun = get_ccd_size_divisor_exact;
@ -1159,8 +1151,7 @@ void genesys_init_sensor_tables()
{ 0x5e, 0x00 },
};
sensor.gamma = { 1.0f, 1.0f, 1.0f };
sensor.get_logical_hwdpi_fun = default_get_logical_hwdpi;
sensor.get_register_hwdpi_fun = default_get_logical_hwdpi;
sensor.get_register_hwdpi_fun = default_get_register_hwdpi;
sensor.get_hwdpi_divisor_fun = default_get_hwdpi_divisor_for_dpi;
sensor.get_ccd_size_divisor_fun = get_ccd_size_divisor_exact;
@ -1417,8 +1408,7 @@ void genesys_init_sensor_tables()
{ 0x5e, 0x01 },
};
sensor.gamma = { 1.0f, 1.0f, 1.0f };
sensor.get_logical_hwdpi_fun = default_get_logical_hwdpi;
sensor.get_register_hwdpi_fun = default_get_logical_hwdpi;
sensor.get_register_hwdpi_fun = default_get_register_hwdpi;
sensor.get_hwdpi_divisor_fun = default_get_hwdpi_divisor_for_dpi;
sensor.get_ccd_size_divisor_fun = default_get_ccd_size_divisor_for_dpi;
s_sensors->push_back(sensor);
@ -1461,8 +1451,7 @@ void genesys_init_sensor_tables()
{ 0x5e, 0x01 },
};
sensor.gamma = { 1.0f, 1.0f, 1.0f };
sensor.get_logical_hwdpi_fun = default_get_logical_hwdpi;
sensor.get_register_hwdpi_fun = default_get_logical_hwdpi;
sensor.get_register_hwdpi_fun = default_get_register_hwdpi;
sensor.get_hwdpi_divisor_fun = default_get_hwdpi_divisor_for_dpi;
sensor.get_ccd_size_divisor_fun = default_get_ccd_size_divisor_for_dpi;
s_sensors->push_back(sensor);
@ -1505,8 +1494,7 @@ void genesys_init_sensor_tables()
{ 0x5e, 0x01 },
};
sensor.gamma = { 1.0f, 1.0f, 1.0f };
sensor.get_logical_hwdpi_fun = default_get_logical_hwdpi;
sensor.get_register_hwdpi_fun = default_get_logical_hwdpi;
sensor.get_register_hwdpi_fun = default_get_register_hwdpi;
sensor.get_hwdpi_divisor_fun = default_get_hwdpi_divisor_for_dpi;
sensor.get_ccd_size_divisor_fun = default_get_ccd_size_divisor_for_dpi;
s_sensors->push_back(sensor);
@ -1549,8 +1537,7 @@ void genesys_init_sensor_tables()
{ 0x5e, 0x01 },
};
sensor.gamma = { 1.0f, 1.0f, 1.0f };
sensor.get_logical_hwdpi_fun = default_get_logical_hwdpi;
sensor.get_register_hwdpi_fun = default_get_logical_hwdpi;
sensor.get_register_hwdpi_fun = default_get_register_hwdpi;
sensor.get_hwdpi_divisor_fun = default_get_hwdpi_divisor_for_dpi;
sensor.get_ccd_size_divisor_fun = default_get_ccd_size_divisor_for_dpi;
s_sensors->push_back(sensor);
@ -1593,8 +1580,7 @@ void genesys_init_sensor_tables()
{ 0x5e, 0x01 },
};
sensor.gamma = { 1.0f, 1.0f, 1.0f };
sensor.get_logical_hwdpi_fun = default_get_logical_hwdpi;
sensor.get_register_hwdpi_fun = default_get_logical_hwdpi;
sensor.get_register_hwdpi_fun = default_get_register_hwdpi;
sensor.get_hwdpi_divisor_fun = default_get_hwdpi_divisor_for_dpi;
sensor.get_ccd_size_divisor_fun = default_get_ccd_size_divisor_for_dpi;
s_sensors->push_back(sensor);
@ -1610,8 +1596,7 @@ void genesys_init_sensor_tables()
sensor.gain_white_ref = 200;
sensor.exposure = { 0x0000, 0x0000, 0x0000 };
sensor.gamma = { 2.2f, 2.2f, 2.2f };
sensor.get_logical_hwdpi_fun = default_get_logical_hwdpi;
sensor.get_register_hwdpi_fun = default_get_logical_hwdpi;
sensor.get_register_hwdpi_fun = default_get_register_hwdpi;
sensor.get_hwdpi_divisor_fun = default_get_hwdpi_divisor_for_dpi;
sensor.get_ccd_size_divisor_fun = default_get_ccd_size_divisor_for_dpi;
@ -1712,8 +1697,7 @@ void genesys_init_sensor_tables()
sensor.fau_gain_white_ref = 210;
sensor.gain_white_ref = 200;
sensor.gamma = { 1.0f, 1.0f, 1.0f };
sensor.get_logical_hwdpi_fun = default_get_logical_hwdpi;
sensor.get_register_hwdpi_fun = default_get_logical_hwdpi;
sensor.get_register_hwdpi_fun = default_get_register_hwdpi;
sensor.get_hwdpi_divisor_fun = default_get_hwdpi_divisor_for_dpi;
sensor.get_ccd_size_divisor_fun = default_get_ccd_size_divisor_for_dpi;
@ -1812,8 +1796,7 @@ void genesys_init_sensor_tables()
sensor.gain_white_ref = 200;
sensor.exposure = { 0x01c1, 0x0126, 0x00e5 };
sensor.gamma = { 2.2f, 2.2f, 2.2f };
sensor.get_logical_hwdpi_fun = default_get_logical_hwdpi;
sensor.get_register_hwdpi_fun = default_get_logical_hwdpi;
sensor.get_register_hwdpi_fun = default_get_register_hwdpi;
sensor.get_hwdpi_divisor_fun = default_get_hwdpi_divisor_for_dpi;
sensor.get_ccd_size_divisor_fun = default_get_ccd_size_divisor_for_dpi;
@ -1929,8 +1912,7 @@ void genesys_init_sensor_tables()
{ 0x5a, 0xc0 },
};
sensor.gamma = { 1.0f, 1.0f, 1.0f };
sensor.get_logical_hwdpi_fun = default_get_logical_hwdpi;
sensor.get_register_hwdpi_fun = default_get_logical_hwdpi;
sensor.get_register_hwdpi_fun = default_get_register_hwdpi;
sensor.get_hwdpi_divisor_fun = default_get_hwdpi_divisor_for_dpi;
sensor.get_ccd_size_divisor_fun = default_get_ccd_size_divisor_for_dpi;
s_sensors->push_back(sensor);
@ -1949,8 +1931,7 @@ void genesys_init_sensor_tables()
sensor.stagger_config = StaggerConfig{ 2400, 4 }; // FIXME: may be incorrect
sensor.custom_regs = {};
sensor.gamma = { 1.0f, 1.0f, 1.0f };
sensor.get_logical_hwdpi_fun = default_get_logical_hwdpi;
sensor.get_register_hwdpi_fun = default_get_logical_hwdpi;
sensor.get_register_hwdpi_fun = default_get_register_hwdpi;
sensor.get_hwdpi_divisor_fun = default_get_hwdpi_divisor_for_dpi;
sensor.get_ccd_size_divisor_fun = default_get_ccd_size_divisor_for_dpi;
@ -2129,8 +2110,7 @@ void genesys_init_sensor_tables()
sensor.stagger_config = StaggerConfig{ 2400, 4 }; // FIXME: may be incorrect
sensor.custom_regs = {};
sensor.gamma = { 1.0f, 1.0f, 1.0f };
sensor.get_logical_hwdpi_fun = default_get_logical_hwdpi;
sensor.get_register_hwdpi_fun = default_get_logical_hwdpi;
sensor.get_register_hwdpi_fun = default_get_register_hwdpi;
sensor.get_hwdpi_divisor_fun = default_get_hwdpi_divisor_for_dpi;
sensor.get_ccd_size_divisor_fun = default_get_ccd_size_divisor_for_dpi;
@ -2230,6 +2210,7 @@ void genesys_init_sensor_tables()
sensor = Genesys_Sensor();
sensor.sensor_id = SensorId::CCD_CANON_4400F;
sensor.optical_res = 4800;
sensor.register_dpihw_override = 4800;
sensor.ccd_size_divisor = 4;
sensor.black_pixels = 50*8;
// 31 at 600 dpi, 58 at 1200 dpi
@ -2240,8 +2221,7 @@ void genesys_init_sensor_tables()
sensor.exposure = { 0x9c40, 0x9c40, 0x9c40 };
sensor.stagger_config = StaggerConfig{4800, 8};
sensor.gamma = { 1.0f, 1.0f, 1.0f };
sensor.get_logical_hwdpi_fun = get_sensor_optical_with_ccd_divisor;
sensor.get_register_hwdpi_fun = [](const Genesys_Sensor&, unsigned) { return 4800; };
sensor.get_register_hwdpi_fun = get_sensor_optical_with_ccd_divisor;
sensor.get_hwdpi_divisor_fun = [](const Genesys_Sensor&, unsigned) { return 1; };
sensor.get_ccd_size_divisor_fun = default_get_ccd_size_divisor_for_dpi;
@ -2338,8 +2318,7 @@ void genesys_init_sensor_tables()
sensor.stagger_config = StaggerConfig{ 3200, 6 };
sensor.custom_regs = {};
sensor.gamma = { 1.0f, 1.0f, 1.0f };
sensor.get_logical_hwdpi_fun = get_sensor_optical_with_ccd_divisor;
sensor.get_register_hwdpi_fun = [](const Genesys_Sensor&, unsigned) { return 4800; };
sensor.get_register_hwdpi_fun = get_sensor_optical_with_ccd_divisor;
sensor.get_hwdpi_divisor_fun = [](const Genesys_Sensor&, unsigned) { return 1; };
sensor.get_ccd_size_divisor_fun = default_get_ccd_size_divisor_for_dpi;
@ -2484,6 +2463,7 @@ void genesys_init_sensor_tables()
sensor = Genesys_Sensor();
sensor.sensor_id = SensorId::CCD_CANON_8600F;
sensor.optical_res = 4800;
sensor.register_dpihw_override = 4800;
sensor.ccd_size_divisor = 4;
sensor.black_pixels = 31;
sensor.dummy_pixel = 20;
@ -2494,8 +2474,7 @@ void genesys_init_sensor_tables()
sensor.stagger_config = StaggerConfig{4800, 8};
sensor.custom_regs = {};
sensor.gamma = { 1.0f, 1.0f, 1.0f };
sensor.get_logical_hwdpi_fun = get_sensor_optical_with_ccd_divisor;
sensor.get_register_hwdpi_fun = [](const Genesys_Sensor&, unsigned) { return 4800; };
sensor.get_register_hwdpi_fun = get_sensor_optical_with_ccd_divisor;
sensor.get_hwdpi_divisor_fun = [](const Genesys_Sensor&, unsigned) { return 1; };
sensor.get_ccd_size_divisor_fun = default_get_ccd_size_divisor_for_dpi;
@ -2618,8 +2597,7 @@ void genesys_init_sensor_tables()
{ 0x5a, 0x40 },
};
sensor.gamma = { 1.0f, 1.0f, 1.0f };
sensor.get_logical_hwdpi_fun = default_get_logical_hwdpi;
sensor.get_register_hwdpi_fun = default_get_logical_hwdpi;
sensor.get_register_hwdpi_fun = default_get_register_hwdpi;
sensor.get_hwdpi_divisor_fun = default_get_hwdpi_divisor_for_dpi;
sensor.get_ccd_size_divisor_fun = default_get_ccd_size_divisor_for_dpi;
s_sensors->push_back(sensor);
@ -2636,8 +2614,7 @@ void genesys_init_sensor_tables()
sensor.gain_white_ref = 200;
sensor.exposure = { 0x0000, 0x0000, 0x0000 };
sensor.gamma = { 2.2f, 2.2f, 2.2f };
sensor.get_logical_hwdpi_fun = default_get_logical_hwdpi;
sensor.get_register_hwdpi_fun = default_get_logical_hwdpi;
sensor.get_register_hwdpi_fun = default_get_register_hwdpi;
sensor.get_hwdpi_divisor_fun = default_get_hwdpi_divisor_for_dpi;
sensor.get_ccd_size_divisor_fun = get_ccd_size_divisor_gl124;
@ -2759,8 +2736,7 @@ void genesys_init_sensor_tables()
sensor.gain_white_ref = 200;
sensor.exposure = { 0x0000, 0x0000, 0x0000 };
sensor.gamma = { 2.2f, 2.2f, 2.2f };
sensor.get_logical_hwdpi_fun = default_get_logical_hwdpi;
sensor.get_register_hwdpi_fun = default_get_logical_hwdpi;
sensor.get_register_hwdpi_fun = default_get_register_hwdpi;
sensor.get_hwdpi_divisor_fun = default_get_hwdpi_divisor_for_dpi;
sensor.get_ccd_size_divisor_fun = get_ccd_size_divisor_gl124;
@ -2865,8 +2841,7 @@ void genesys_init_sensor_tables()
sensor.gain_white_ref = 200;
sensor.exposure = { 0x0000, 0x0000, 0x0000 };
sensor.gamma = { 2.2f, 2.2f, 2.2f };
sensor.get_logical_hwdpi_fun = default_get_logical_hwdpi;
sensor.get_register_hwdpi_fun = default_get_logical_hwdpi;
sensor.get_register_hwdpi_fun = default_get_register_hwdpi;
sensor.get_hwdpi_divisor_fun = default_get_hwdpi_divisor_for_dpi;
sensor.get_ccd_size_divisor_fun = get_ccd_size_divisor_gl124;
@ -2975,8 +2950,7 @@ void genesys_init_sensor_tables()
sensor.gain_white_ref = 200;
sensor.exposure = { 0x0000, 0x0000, 0x0000 };
sensor.gamma = { 2.2f, 2.2f, 2.2f };
sensor.get_logical_hwdpi_fun = default_get_logical_hwdpi;
sensor.get_register_hwdpi_fun = default_get_logical_hwdpi;
sensor.get_register_hwdpi_fun = default_get_register_hwdpi;
sensor.get_hwdpi_divisor_fun = default_get_hwdpi_divisor_for_dpi;
sensor.get_ccd_size_divisor_fun = get_ccd_size_divisor_gl124;
@ -3112,8 +3086,7 @@ void genesys_init_sensor_tables()
{ 0x5e, 0x02 },
};
sensor.gamma = { 1.0f, 1.0f, 1.0f };
sensor.get_logical_hwdpi_fun = default_get_logical_hwdpi;
sensor.get_register_hwdpi_fun = default_get_logical_hwdpi;
sensor.get_register_hwdpi_fun = default_get_register_hwdpi;
sensor.get_hwdpi_divisor_fun = default_get_hwdpi_divisor_for_dpi;
sensor.get_ccd_size_divisor_fun = default_get_ccd_size_divisor_for_dpi;
s_sensors->push_back(sensor);
@ -3161,8 +3134,7 @@ void genesys_init_sensor_tables()
{ 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x00 },
};
sensor.gamma = { 1.0f, 1.0f, 1.0f };
sensor.get_logical_hwdpi_fun = default_get_logical_hwdpi;
sensor.get_register_hwdpi_fun = default_get_logical_hwdpi;
sensor.get_register_hwdpi_fun = default_get_register_hwdpi;
sensor.get_hwdpi_divisor_fun = default_get_hwdpi_divisor_for_dpi;
sensor.get_ccd_size_divisor_fun = get_ccd_size_divisor_exact;
{
@ -3252,8 +3224,7 @@ void genesys_init_sensor_tables()
{ 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x00 },
};
sensor.gamma = { 1.0f, 1.0f, 1.0f };
sensor.get_logical_hwdpi_fun = default_get_logical_hwdpi;
sensor.get_register_hwdpi_fun = default_get_logical_hwdpi;
sensor.get_register_hwdpi_fun = default_get_register_hwdpi;
sensor.get_hwdpi_divisor_fun = default_get_hwdpi_divisor_for_dpi;
sensor.get_ccd_size_divisor_fun = get_ccd_size_divisor_exact;
{
@ -3326,8 +3297,7 @@ void genesys_init_sensor_tables()
{ 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x00 },
};
sensor.gamma = { 1.0f, 1.0f, 1.0f };
sensor.get_logical_hwdpi_fun = default_get_logical_hwdpi;
sensor.get_register_hwdpi_fun = default_get_logical_hwdpi;
sensor.get_register_hwdpi_fun = default_get_register_hwdpi;
sensor.get_hwdpi_divisor_fun = default_get_hwdpi_divisor_for_dpi;
sensor.get_ccd_size_divisor_fun = get_ccd_size_divisor_exact;
{
@ -3389,8 +3359,7 @@ void genesys_init_sensor_tables()
{ 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 },
};
sensor.gamma = { 1.7f, 1.7f, 1.7f };
sensor.get_logical_hwdpi_fun = default_get_logical_hwdpi;
sensor.get_register_hwdpi_fun = default_get_logical_hwdpi;
sensor.get_register_hwdpi_fun = default_get_register_hwdpi;
sensor.get_hwdpi_divisor_fun = default_get_hwdpi_divisor_for_dpi;
sensor.get_ccd_size_divisor_fun = default_get_ccd_size_divisor_for_dpi;
s_sensors->push_back(sensor);
@ -3416,8 +3385,7 @@ void genesys_init_sensor_tables()
{ 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x55 },
};
sensor.gamma = { 1.7f, 1.7f, 1.7f };
sensor.get_logical_hwdpi_fun = default_get_logical_hwdpi;
sensor.get_register_hwdpi_fun = default_get_logical_hwdpi;
sensor.get_register_hwdpi_fun = default_get_register_hwdpi;
sensor.get_hwdpi_divisor_fun = default_get_hwdpi_divisor_for_dpi;
sensor.get_ccd_size_divisor_fun = default_get_ccd_size_divisor_for_dpi;
s_sensors->push_back(sensor);
@ -3463,8 +3431,7 @@ void genesys_init_sensor_tables()
{ 0x5e, 0x41 },
};
sensor.gamma = { 1.0f, 1.0f, 1.0f };
sensor.get_logical_hwdpi_fun = default_get_logical_hwdpi;
sensor.get_register_hwdpi_fun = default_get_logical_hwdpi;
sensor.get_register_hwdpi_fun = default_get_register_hwdpi;
sensor.get_hwdpi_divisor_fun = default_get_hwdpi_divisor_for_dpi;
sensor.get_ccd_size_divisor_fun = default_get_ccd_size_divisor_for_dpi;
s_sensors->push_back(sensor);