kopia lustrzana https://gitlab.com/sane-project/backends
Merge branch 'genesys-duplication' into 'master'
genesys: Reduce code duplication See merge request sane-project/backends!344merge-requests/340/head
commit
993a79b594
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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, ®s, 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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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, ®s, 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
|
||||
*/
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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, ®s, 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
|
||||
*/
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
Ładowanie…
Reference in New Issue