genesys: Deduplicate strip searching functionality

merge-requests/340/head
Povilas Kanapickas 2020-02-22 11:02:57 +02:00
rodzic 5854246e88
commit d8f09656b2
15 zmienionych plików z 217 dodań i 942 usunięć

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

@ -2036,16 +2036,6 @@ void CommandSetGl124::eject_document(Genesys_Device* dev) const
throw SaneException("not implemented");
}
void CommandSetGl124::search_strip(Genesys_Device* dev, const Genesys_Sensor& sensor,
bool forward, bool black) const
{
(void) dev;
(void) sensor;
(void) forward;
(void) black;
throw SaneException("not implemented");
}
void CommandSetGl124::move_to_ta(Genesys_Device* dev) const
{
(void) dev;

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

@ -1819,7 +1819,7 @@ void CommandSetGl841::set_powersaving(Genesys_Device* dev, int delay /* in minut
dev->interface->write_registers(local_reg);
}
static void gl841_stop_action(Genesys_Device* dev)
void gl841_stop_action(Genesys_Device* dev)
{
DBG_HELPER(dbg);
Genesys_Register_Set local_reg;
@ -3293,204 +3293,6 @@ void CommandSetGl841::update_hardware_sensors(Genesys_Scanner* s) const
}
}
/** @brief search for a full width black or white strip.
* This function searches for a black or white stripe across the scanning area.
* When searching backward, the searched area must completely be of the desired
* color since this area will be used for calibration which scans forward.
* @param dev scanner device
* @param forward true if searching forward, false if searching backward
* @param black true if searching for a black strip, false for a white strip
*/
void CommandSetGl841::search_strip(Genesys_Device* dev, const Genesys_Sensor& sensor, bool forward,
bool black) const
{
DBG_HELPER_ARGS(dbg, "%s %s", black ? "black" : "white", forward ? "forward" : "reverse");
unsigned lines, channels;
Genesys_Register_Set local_reg;
unsigned int pass, count, found, length;
char title[80];
GenesysRegister *r;
uint8_t white_level=90; /**< default white level to detect white dots */
uint8_t black_level=60; /**< default black level to detect black dots */
/* use maximum gain when doing forward white strip detection
* since we don't have calibrated the sensor yet */
if(!black && forward)
{
dev->frontend.set_gain(0, 0xff);
dev->frontend.set_gain(1, 0xff);
dev->frontend.set_gain(2, 0xff);
}
dev->cmd_set->set_fe(dev, sensor, AFE_SET);
gl841_stop_action(dev);
// set up for a gray scan at lowest dpi
const auto& resolution_settings = dev->model->get_resolution_settings(dev->settings.scan_method);
unsigned dpi = resolution_settings.get_min_resolution_x();
channels = 1;
// shading calibation is done with dev->motor.base_ydpi
lines = 10; // TODO: use dev->model->search_lines
lines = static_cast<unsigned>((lines * dpi) / MM_PER_INCH);
/* 20 cm max length for calibration sheet */
length = static_cast<unsigned>(((200 * dpi) / MM_PER_INCH) / lines);
dev->set_head_pos_zero(ScanHeadId::PRIMARY);
local_reg = dev->reg;
ScanSession session;
session.params.xres = dpi;
session.params.yres = dpi;
session.params.startx = 0;
session.params.starty = 0;
session.params.pixels = dev->model->x_size_calib_mm * dpi / MM_PER_INCH;
session.params.lines = lines;
session.params.depth = 8;
session.params.channels = channels;
session.params.scan_method = dev->settings.scan_method;
session.params.scan_mode = ScanColorMode::GRAY;
session.params.color_filter = ColorFilter::RED;
session.params.flags = ScanFlag::DISABLE_SHADING | ScanFlag::DISABLE_GAMMA;
compute_session(dev, session, sensor);
init_regs_for_scan_session(dev, sensor, &local_reg, session);
/* set up for reverse or forward */
r = sanei_genesys_get_address(&local_reg, 0x02);
if (forward) {
r->value &= ~4;
} else {
r->value |= 4;
}
dev->interface->write_registers(local_reg);
dev->cmd_set->begin_scan(dev, sensor, &local_reg, true);
if (is_testing_mode()) {
dev->interface->test_checkpoint("search_strip");
gl841_stop_action(dev);
return;
}
// waits for valid data
wait_until_buffer_non_empty(dev);
// now we're on target, we can read data
auto image = read_unshuffled_image_from_scanner(dev, session, session.output_total_bytes);
gl841_stop_action(dev);
pass = 0;
if (DBG_LEVEL >= DBG_data) {
std::sprintf(title, "gl841_search_strip_%s_%s%02u.pnm", black ? "black" : "white",
forward ? "fwd" : "bwd", pass);
sanei_genesys_write_pnm_file(title, image);
}
/* loop until strip is found or maximum pass number done */
found = 0;
while (pass < length && !found)
{
dev->interface->write_registers(local_reg);
//now start scan
dev->cmd_set->begin_scan(dev, sensor, &local_reg, true);
// waits for valid data
wait_until_buffer_non_empty(dev);
// now we're on target, we can read data
image = read_unshuffled_image_from_scanner(dev, session, session.output_total_bytes);
gl841_stop_action (dev);
if (DBG_LEVEL >= DBG_data) {
std::sprintf(title, "gl841_search_strip_%s_%s%02u.pnm",
black ? "black" : "white", forward ? "fwd" : "bwd", pass);
sanei_genesys_write_pnm_file(title, image);
}
/* search data to find black strip */
/* when searching forward, we only need one line of the searched color since we
* will scan forward. But when doing backward search, we need all the area of the
* same color */
if (forward) {
for (std::size_t y = 0; y < image.get_height() && !found; y++) {
count = 0;
// count of white/black pixels depending on the color searched
for (std::size_t x = 0; x < image.get_width(); x++) {
// when searching for black, detect white pixels
if (black && image.get_raw_channel(x, y, 0) > white_level) {
count++;
}
// when searching for white, detect black pixels
if (!black && image.get_raw_channel(x, y, 0) < black_level) {
count++;
}
}
/* at end of line, if count >= 3%, line is not fully of the desired color
* so we must go to next line of the buffer */
auto found_percentage = (count * 100 / image.get_width());
if (found_percentage < 3) {
found = 1;
DBG(DBG_data, "%s: strip found forward during pass %d at line %zu\n", __func__,
pass, y);
} else {
DBG(DBG_data, "%s: pixels=%zu, count=%d (%zu%%)\n", __func__, image.get_width(),
count, found_percentage);
}
}
} else {
/* since calibration scans are done forward, we need the whole area
to be of the required color when searching backward
*/
count = 0;
for (std::size_t y = 0; y < image.get_height(); y++) {
/* count of white/black pixels depending on the color searched */
for (std::size_t x = 0; x < image.get_width(); x++) {
// when searching for black, detect white pixels
if (black && image.get_raw_channel(x, y, 0) > white_level) {
count++;
}
// when searching for white, detect black pixels
if (!black && image.get_raw_channel(x, y, 0) < black_level) {
count++;
}
}
}
/* at end of area, if count >= 3%, area is not fully of the desired color
* so we must go to next buffer */
auto found_percentage = count * 100 / (image.get_width() * image.get_height());
if (found_percentage < 3) {
found = 1;
DBG(DBG_data, "%s: strip found backward during pass %d \n", __func__, pass);
} else {
DBG(DBG_data, "%s: pixels=%zu, count=%d (%zu%%)\n", __func__, image.get_width(), count,
found_percentage);
}
}
pass++;
}
if (found)
{
DBG(DBG_info, "%s: %s strip found\n", __func__, black ? "black" : "white");
}
else
{
throw SaneException(SANE_STATUS_UNSUPPORTED, "%s strip not found", black ? "black" : "white");
}
}
/**
* Send shading calibration data. The buffer is considered to always hold values
* for all the channels.

Wyświetl plik

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

Wyświetl plik

@ -2405,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.

Wyświetl plik

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

Wyświetl plik

@ -1322,192 +1322,6 @@ void CommandSetGl846::update_home_sensor_gpio(Genesys_Device& dev) const
dev.interface->write_register(REG_0x6C, val);
}
/** @brief search for a full width black or white strip.
* This function searches for a black or white stripe across the scanning area.
* When searching backward, the searched area must completely be of the desired
* color since this area will be used for calibration which scans forward.
* @param dev scanner device
* @param forward true if searching forward, false if searching backward
* @param black true if searching for a black strip, false for a white strip
*/
void CommandSetGl846::search_strip(Genesys_Device* dev, const Genesys_Sensor& sensor, bool forward,
bool black) const
{
DBG_HELPER_ARGS(dbg, "%s %s", black ? "black" : "white", forward ? "forward" : "reverse");
unsigned channels;
Genesys_Register_Set local_reg;
unsigned int pass, count, found;
char title[80];
set_fe(dev, sensor, AFE_SET);
scanner_stop_action(*dev);
// set up for a gray scan at lowest dpi
const auto& resolution_settings = dev->model->get_resolution_settings(dev->settings.scan_method);
unsigned dpi = resolution_settings.get_min_resolution_x();
channels = 1;
/* 10 MM */
/* lines = (10 * dpi) / MM_PER_INCH; */
/* shading calibation is done with dev->motor.base_ydpi */
unsigned lines = static_cast<unsigned>(dev->model->y_size_calib_mm * dpi / MM_PER_INCH);
dev->set_head_pos_zero(ScanHeadId::PRIMARY);
local_reg = dev->reg;
ScanSession session;
session.params.xres = dpi;
session.params.yres = dpi;
session.params.startx = 0;
session.params.starty = 0;
session.params.pixels = dev->model->x_size_calib_mm * dpi / MM_PER_INCH;
session.params.lines = lines;
session.params.depth = 8;
session.params.channels = channels;
session.params.scan_mode = ScanColorMode::GRAY;
session.params.color_filter = ColorFilter::RED;
session.params.flags = ScanFlag::DISABLE_SHADING |
ScanFlag::DISABLE_GAMMA;
if (!forward) {
session.params.flags |= ScanFlag::REVERSE;
}
compute_session(dev, session, sensor);
init_regs_for_scan_session(dev, sensor, &local_reg, session);
dev->interface->write_registers(local_reg);
begin_scan(dev, sensor, &local_reg, true);
if (is_testing_mode()) {
dev->interface->test_checkpoint("search_strip");
scanner_stop_action(*dev);
return;
}
wait_until_buffer_non_empty(dev);
// now we're on target, we can read data
auto image = read_unshuffled_image_from_scanner(dev, session, session.output_total_bytes);
scanner_stop_action(*dev);
pass = 0;
if (DBG_LEVEL >= DBG_data)
{
std::sprintf(title, "gl846_search_strip_%s_%s%02d.pnm",
black ? "black" : "white", forward ? "fwd" : "bwd", pass);
sanei_genesys_write_pnm_file(title, image);
}
/* loop until strip is found or maximum pass number done */
found = 0;
while (pass < 20 && !found)
{
dev->interface->write_registers(local_reg);
// now start scan
begin_scan(dev, sensor, &local_reg, true);
wait_until_buffer_non_empty(dev);
// now we're on target, we can read data
image = read_unshuffled_image_from_scanner(dev, session, session.output_total_bytes);
scanner_stop_action(*dev);
if (DBG_LEVEL >= DBG_data)
{
std::sprintf(title, "gl846_search_strip_%s_%s%02d.pnm",
black ? "black" : "white", forward ? "fwd" : "bwd", pass);
sanei_genesys_write_pnm_file(title, image);
}
unsigned white_level = 90;
unsigned black_level = 60;
/* search data to find black strip */
/* when searching forward, we only need one line of the searched color since we
* will scan forward. But when doing backward search, we need all the area of the
* same color */
if (forward) {
for (std::size_t y = 0; y < image.get_height() && !found; y++) {
count = 0;
// count of white/black pixels depending on the color searched
for (std::size_t x = 0; x < image.get_width(); x++) {
// when searching for black, detect white pixels
if (black && image.get_raw_channel(x, y, 0) > white_level) {
count++;
}
// when searching for white, detect black pixels
if (!black && image.get_raw_channel(x, y, 0) < black_level) {
count++;
}
}
/* at end of line, if count >= 3%, line is not fully of the desired color
* so we must go to next line of the buffer */
auto found_percentage = (count * 100 / image.get_width());
if (found_percentage < 3) {
found = 1;
DBG(DBG_data, "%s: strip found forward during pass %d at line %zu\n", __func__,
pass, y);
}
else
{
DBG(DBG_data, "%s: pixels=%zu, count=%d (%zu%%)\n", __func__, image.get_width(),
count, found_percentage);
}
}
} else {
/* since calibration scans are done forward, we need the whole area
to be of the required color when searching backward
*/
count = 0;
for (std::size_t y = 0; y < image.get_height(); y++) {
// count of white/black pixels depending on the color searched
for (std::size_t x = 0; x < image.get_width(); x++) {
// when searching for black, detect white pixels
if (black && image.get_raw_channel(x, y, 0) > white_level) {
count++;
}
// when searching for white, detect black pixels
if (!black && image.get_raw_channel(x, y, 0) < black_level) {
count++;
}
}
}
/* at end of area, if count >= 3%, area is not fully of the desired color
* so we must go to next buffer */
auto found_percentage = count * 100 / (image.get_width() * image.get_height());
if (found_percentage < 3) {
found = 1;
DBG(DBG_data, "%s: strip found backward during pass %d \n", __func__, pass);
} else {
DBG(DBG_data, "%s: pixels=%zu, count=%d (%zu%%)\n", __func__, image.get_width(),
count, found_percentage);
}
}
pass++;
}
if (found)
{
DBG(DBG_info, "%s: %s strip found\n", __func__, black ? "black" : "white");
}
else
{
throw SaneException(SANE_STATUS_UNSUPPORTED, "%s strip not found", black ? "black" : "white");
}
}
/**
* average dark pixels of a 8 bits scan
*/

Wyświetl plik

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

Wyświetl plik

@ -1363,187 +1363,6 @@ void CommandSetGl847::update_home_sensor_gpio(Genesys_Device& dev) const
}
}
/** @brief search for a full width black or white strip.
* This function searches for a black or white stripe across the scanning area.
* When searching backward, the searched area must completely be of the desired
* color since this area will be used for calibration which scans forward.
* @param dev scanner device
* @param forward true if searching forward, false if searching backward
* @param black true if searching for a black strip, false for a white strip
*/
void CommandSetGl847::search_strip(Genesys_Device* dev, const Genesys_Sensor& sensor, bool forward,
bool black) const
{
DBG_HELPER_ARGS(dbg, "%s %s", black ? "black" : "white", forward ? "forward" : "reverse");
Genesys_Register_Set local_reg;
unsigned int pass, count, found;
char title[80];
set_fe(dev, sensor, AFE_SET);
scanner_stop_action(*dev);
// set up for a gray scan at lowest dpi
const auto& resolution_settings = dev->model->get_resolution_settings(dev->settings.scan_method);
unsigned dpi = resolution_settings.get_min_resolution_x();
unsigned channels = 1;
unsigned lines = static_cast<unsigned>(dev->model->y_size_calib_mm * dpi / MM_PER_INCH);
dev->set_head_pos_zero(ScanHeadId::PRIMARY);
local_reg = dev->reg;
ScanSession session;
session.params.xres = dpi;
session.params.yres = dpi;
session.params.startx = 0;
session.params.starty = 0;
session.params.pixels = dev->model->x_size_calib_mm * dpi / MM_PER_INCH;
session.params.lines = lines;
session.params.depth = 8;
session.params.channels = channels;
session.params.scan_method = dev->settings.scan_method;
session.params.scan_mode = ScanColorMode::GRAY;
session.params.color_filter = ColorFilter::RED;
session.params.flags = ScanFlag::DISABLE_SHADING |
ScanFlag::DISABLE_GAMMA;
if (!forward) {
session.params.flags |= ScanFlag::REVERSE;
}
compute_session(dev, session, sensor);
init_regs_for_scan_session(dev, sensor, &local_reg, session);
dev->interface->write_registers(local_reg);
begin_scan(dev, sensor, &local_reg, true);
if (is_testing_mode()) {
dev->interface->test_checkpoint("search_strip");
scanner_stop_action(*dev);
return;
}
wait_until_buffer_non_empty(dev);
// now we're on target, we can read data
auto image = read_unshuffled_image_from_scanner(dev, session, session.output_total_bytes);
scanner_stop_action(*dev);
pass = 0;
if (DBG_LEVEL >= DBG_data) {
std::sprintf(title, "gl847_search_strip_%s_%s%02d.pnm",
black ? "black" : "white", forward ? "fwd" : "bwd", pass);
sanei_genesys_write_pnm_file(title, image);
}
/* loop until strip is found or maximum pass number done */
found = 0;
while (pass < 20 && !found)
{
dev->interface->write_registers(local_reg);
// now start scan
begin_scan(dev, sensor, &local_reg, true);
wait_until_buffer_non_empty(dev);
// now we're on target, we can read data
image = read_unshuffled_image_from_scanner(dev, session, session.output_total_bytes);
scanner_stop_action(*dev);
if (DBG_LEVEL >= DBG_data) {
std::sprintf(title, "gl847_search_strip_%s_%s%02d.pnm",
black ? "black" : "white",
forward ? "fwd" : "bwd", static_cast<int>(pass));
sanei_genesys_write_pnm_file(title, image);
}
unsigned white_level = 90;
unsigned black_level = 60;
/* search data to find black strip */
/* when searching forward, we only need one line of the searched color since we
* will scan forward. But when doing backward search, we need all the area of the
* same color */
if (forward) {
for (std::size_t y = 0; y < image.get_height() && !found; y++) {
count = 0;
// count of white/black pixels depending on the color searched
for (std::size_t x = 0; x < image.get_width(); x++) {
// when searching for black, detect white pixels
if (black && image.get_raw_channel(x, y, 0) > white_level) {
count++;
}
// when searching for white, detect black pixels
if (!black && image.get_raw_channel(x, y, 0) < black_level) {
count++;
}
}
/* at end of line, if count >= 3%, line is not fully of the desired color
* so we must go to next line of the buffer */
/* count*100/pixels < 3 */
auto found_percentage = (count * 100 / image.get_width());
if (found_percentage < 3) {
found = 1;
DBG(DBG_data, "%s: strip found forward during pass %d at line %zu\n", __func__,
pass, y);
}
else
{
DBG(DBG_data, "%s: pixels=%zu, count=%d (%zu%%)\n", __func__, image.get_width(),
count, found_percentage);
}
}
} else {
/* since calibration scans are done forward, we need the whole area
to be of the required color when searching backward
*/
count = 0;
for (std::size_t y = 0; y < image.get_height(); y++) {
// count of white/black pixels depending on the color searched
for (std::size_t x = 0; x < image.get_width(); x++) {
// when searching for black, detect white pixels
if (black && image.get_raw_channel(x, y, 0) > white_level) {
count++;
}
// when searching for white, detect black pixels
if (!black && image.get_raw_channel(x, y, 0) < black_level) {
count++;
}
}
}
/* at end of area, if count >= 3%, area is not fully of the desired color
* so we must go to next buffer */
auto found_percentage = count * 100 / (image.get_width() * image.get_height());
if (found_percentage < 3) {
found = 1;
DBG(DBG_data, "%s: strip found backward during pass %d \n", __func__, pass);
} else {
DBG(DBG_data, "%s: pixels=%zu, count=%d (%zu%%)\n", __func__, image.get_width(),
count, found_percentage);
}
}
pass++;
}
if (found)
{
DBG(DBG_info, "%s: %s strip found\n", __func__, black ? "black" : "white");
}
else
{
throw SaneException(SANE_STATUS_UNSUPPORTED, "%s strip not found", black ? "black" : "white");
}
}
/**
* average dark pixels of a 8 bits scan
*/

Wyświetl plik

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

Wyświetl plik

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