genesys: Allow pipeline to be created without mutating device

merge-requests/244/head
Povilas Kanapickas 2020-05-24 16:42:41 +03:00
rodzic ddeae7e8b0
commit a23d61c26b
10 zmienionych plików z 80 dodań i 85 usunięć

Wyświetl plik

@ -722,7 +722,7 @@ static void gl124_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens
dev->line_count = 0; dev->line_count = 0;
build_image_pipeline(dev, session); setup_image_pipeline(*dev, session);
// MAXWD is expressed in 2 words unit // MAXWD is expressed in 2 words unit

Wyświetl plik

@ -840,7 +840,7 @@ void CommandSetGl646::init_regs_for_scan_session(Genesys_Device* dev, const Gene
// setup analog frontend // setup analog frontend
gl646_set_fe(dev, sensor, AFE_SET, session.output_resolution); gl646_set_fe(dev, sensor, AFE_SET, session.output_resolution);
build_image_pipeline(dev, session); setup_image_pipeline(*dev, session);
dev->read_active = true; dev->read_active = true;

Wyświetl plik

@ -1056,7 +1056,7 @@ dummy \ scanned lines
session.params.flags); session.params.flags);
} }
build_image_pipeline(dev, session); setup_image_pipeline(*dev, session);
dev->read_active = true; dev->read_active = true;

Wyświetl plik

@ -521,7 +521,7 @@ void CommandSetGl842::init_regs_for_scan_session(Genesys_Device* dev, const Gene
session.optical_line_count, dummy, session.params.starty, session.optical_line_count, dummy, session.params.starty,
session.params.flags); session.params.flags);
build_image_pipeline(dev, session); setup_image_pipeline(*dev, session);
dev->read_active = true; dev->read_active = true;

Wyświetl plik

@ -1054,7 +1054,7 @@ void CommandSetGl843::init_regs_for_scan_session(Genesys_Device* dev, const Gene
session.optical_line_count, dummy, session.params.starty, session.optical_line_count, dummy, session.params.starty,
session.params.flags); session.params.flags);
build_image_pipeline(dev, session); setup_image_pipeline(*dev, session);
dev->read_active = true; dev->read_active = true;

Wyświetl plik

@ -646,7 +646,7 @@ static void gl846_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens
reg->set16(REG_STRPIXEL, session.pixel_startx); reg->set16(REG_STRPIXEL, session.pixel_startx);
reg->set16(REG_ENDPIXEL, session.pixel_endx); reg->set16(REG_ENDPIXEL, session.pixel_endx);
build_image_pipeline(dev, session); setup_image_pipeline(*dev, session);
/* MAXWD is expressed in 4 words unit */ /* MAXWD is expressed in 4 words unit */
// BUG: we shouldn't multiply by channels here // BUG: we shouldn't multiply by channels here

Wyświetl plik

@ -524,7 +524,7 @@ static void gl847_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens
reg->set16(REG_STRPIXEL, session.pixel_startx); reg->set16(REG_STRPIXEL, session.pixel_startx);
reg->set16(REG_ENDPIXEL, session.pixel_endx); reg->set16(REG_ENDPIXEL, session.pixel_endx);
build_image_pipeline(dev, session); setup_image_pipeline(*dev, session);
/* MAXWD is expressed in 4 words unit */ /* MAXWD is expressed in 4 words unit */
// BUG: we shouldn't multiply by channels here // BUG: we shouldn't multiply by channels here

Wyświetl plik

@ -524,6 +524,8 @@ class ImagePipelineStack
{ {
public: public:
ImagePipelineStack() {} ImagePipelineStack() {}
ImagePipelineStack(ImagePipelineStack&&) = default;
ImagePipelineStack& operator=(ImagePipelineStack&&) = default;
~ImagePipelineStack() { clear(); } ~ImagePipelineStack() { clear(); }
std::size_t get_input_width() const; std::size_t get_input_width() const;

Wyświetl plik

@ -926,28 +926,26 @@ void compute_session(const Genesys_Device* dev, ScanSession& s, const Genesys_Se
debug_dump(DBG_info, s); debug_dump(DBG_info, s);
} }
void build_image_pipeline(Genesys_Device* dev, const ScanSession& session) ImagePipelineStack build_image_pipeline(const Genesys_Device& dev, const ScanSession& session,
unsigned pipeline_index, bool log_image_data)
{ {
static unsigned s_pipeline_index = 0;
s_pipeline_index++;
auto format = create_pixel_format(session.params.depth, auto format = create_pixel_format(session.params.depth,
dev->model->is_cis ? 1 : session.params.channels, dev.model->is_cis ? 1 : session.params.channels,
dev->model->line_mode_color_order); dev.model->line_mode_color_order);
auto depth = get_pixel_format_depth(format); auto depth = get_pixel_format_depth(format);
auto width = get_pixels_from_row_bytes(format, session.output_line_bytes_raw); auto width = get_pixels_from_row_bytes(format, session.output_line_bytes_raw);
auto read_data_from_usb = [dev](std::size_t size, std::uint8_t* data) auto read_data_from_usb = [&dev](std::size_t size, std::uint8_t* data)
{ {
dev->interface->bulk_read_data(0x45, data, size); dev.interface->bulk_read_data(0x45, data, size);
return true; return true;
}; };
auto debug_prefix = "gl_pipeline_" + std::to_string(pipeline_index);
ImagePipelineStack pipeline;
auto lines = session.optical_line_count; auto lines = session.optical_line_count;
dev->pipeline.clear();
auto buffer_size = session.buffer_size_read; auto buffer_size = session.buffer_size_read;
// At least GL841 requires reads to be aligned to 2 bytes and will fail on some devices on // At least GL841 requires reads to be aligned to 2 bytes and will fail on some devices on
@ -958,141 +956,132 @@ void build_image_pipeline(Genesys_Device* dev, const ScanSession& session)
new ImagePipelineNodeBufferedCallableSource( new ImagePipelineNodeBufferedCallableSource(
width, lines, format, buffer_size, read_data_from_usb)); width, lines, format, buffer_size, read_data_from_usb));
node->set_last_read_multiple(2); node->set_last_read_multiple(2);
dev->pipeline.push_first_node(std::move(node)); pipeline.push_first_node(std::move(node));
if (dbg_log_image_data()) { if (log_image_data) {
dev->pipeline.push_node<ImagePipelineNodeDebug>("gl_pipeline_" + pipeline.push_node<ImagePipelineNodeDebug>(debug_prefix + "_0_from_usb.tiff");
std::to_string(s_pipeline_index) +
"_0_from_usb.tiff");
} }
if (session.segment_count > 1) { if (session.segment_count > 1) {
auto output_width = session.output_segment_pixel_group_count * session.segment_count; auto output_width = session.output_segment_pixel_group_count * session.segment_count;
dev->pipeline.push_node<ImagePipelineNodeDesegment>(output_width, dev->segment_order, pipeline.push_node<ImagePipelineNodeDesegment>(output_width, dev.segment_order,
session.conseq_pixel_dist, session.conseq_pixel_dist,
1, 1); 1, 1);
if (dbg_log_image_data()) { if (log_image_data) {
dev->pipeline.push_node<ImagePipelineNodeDebug>("gl_pipeline_" + pipeline.push_node<ImagePipelineNodeDebug>(debug_prefix + "_1_after_desegment.tiff");
std::to_string(s_pipeline_index) +
"_1_after_desegment.tiff");
} }
} }
if (depth == 16) { if (depth == 16) {
unsigned num_swaps = 0; unsigned num_swaps = 0;
if (has_flag(dev->model->flags, ModelFlag::SWAP_16BIT_DATA)) { if (has_flag(dev.model->flags, ModelFlag::SWAP_16BIT_DATA)) {
num_swaps++; num_swaps++;
} }
#ifdef WORDS_BIGENDIAN #ifdef WORDS_BIGENDIAN
num_swaps++; num_swaps++;
#endif #endif
if (num_swaps % 2 != 0) { if (num_swaps % 2 != 0) {
dev->pipeline.push_node<ImagePipelineNodeSwap16BitEndian>(); pipeline.push_node<ImagePipelineNodeSwap16BitEndian>();
if (dbg_log_image_data()) { if (log_image_data) {
dev->pipeline.push_node<ImagePipelineNodeDebug>("gl_pipeline_" + pipeline.push_node<ImagePipelineNodeDebug>(debug_prefix + "_2_after_swap.tiff");
std::to_string(s_pipeline_index) +
"_2_after_swap.tiff");
} }
} }
} }
if (has_flag(dev->model->flags, ModelFlag::INVERT_PIXEL_DATA)) { if (has_flag(dev.model->flags, ModelFlag::INVERT_PIXEL_DATA)) {
dev->pipeline.push_node<ImagePipelineNodeInvert>(); pipeline.push_node<ImagePipelineNodeInvert>();
if (dbg_log_image_data()) { if (log_image_data) {
dev->pipeline.push_node<ImagePipelineNodeDebug>("gl_pipeline_" + pipeline.push_node<ImagePipelineNodeDebug>(debug_prefix + "_3_after_invert.tiff");
std::to_string(s_pipeline_index) +
"_3_after_invert.tiff");
} }
} }
if (dev->model->is_cis && session.params.channels == 3) { if (dev.model->is_cis && session.params.channels == 3) {
dev->pipeline.push_node<ImagePipelineNodeMergeMonoLines>(dev->model->line_mode_color_order); pipeline.push_node<ImagePipelineNodeMergeMonoLines>(dev.model->line_mode_color_order);
if (dbg_log_image_data()) { if (log_image_data) {
dev->pipeline.push_node<ImagePipelineNodeDebug>("gl_pipeline_" + pipeline.push_node<ImagePipelineNodeDebug>(debug_prefix + "_4_after_merge_mono.tiff");
std::to_string(s_pipeline_index) +
"_4_after_merge_mono.tiff");
} }
} }
if (dev->pipeline.get_output_format() == PixelFormat::BGR888) { if (pipeline.get_output_format() == PixelFormat::BGR888) {
dev->pipeline.push_node<ImagePipelineNodeFormatConvert>(PixelFormat::RGB888); pipeline.push_node<ImagePipelineNodeFormatConvert>(PixelFormat::RGB888);
} }
if (dev->pipeline.get_output_format() == PixelFormat::BGR161616) { if (pipeline.get_output_format() == PixelFormat::BGR161616) {
dev->pipeline.push_node<ImagePipelineNodeFormatConvert>(PixelFormat::RGB161616); pipeline.push_node<ImagePipelineNodeFormatConvert>(PixelFormat::RGB161616);
} }
if (dbg_log_image_data()) { if (log_image_data) {
dev->pipeline.push_node<ImagePipelineNodeDebug>("gl_pipeline_" + pipeline.push_node<ImagePipelineNodeDebug>(debug_prefix + "_5_after_format.tiff");
std::to_string(s_pipeline_index) +
"_5_after_format.tiff");
} }
if (session.max_color_shift_lines > 0 && session.params.channels == 3) { if (session.max_color_shift_lines > 0 && session.params.channels == 3) {
dev->pipeline.push_node<ImagePipelineNodeComponentShiftLines>( pipeline.push_node<ImagePipelineNodeComponentShiftLines>(
session.color_shift_lines_r, session.color_shift_lines_r,
session.color_shift_lines_g, session.color_shift_lines_g,
session.color_shift_lines_b); session.color_shift_lines_b);
if (dbg_log_image_data()) { if (log_image_data) {
dev->pipeline.push_node<ImagePipelineNodeDebug>("gl_pipeline_" + pipeline.push_node<ImagePipelineNodeDebug>(debug_prefix + "_6_after_color_unshift.tiff");
std::to_string(s_pipeline_index) +
"_6_after_color_unshift.tiff");
} }
} }
if (!session.stagger_x.empty()) { if (!session.stagger_x.empty()) {
// FIXME: the image will be scaled to requested pixel count without regard to the reduction // FIXME: the image will be scaled to requested pixel count without regard to the reduction
// of image size in this step. // of image size in this step.
dev->pipeline.push_node<ImagePipelineNodePixelShiftColumns>(session.stagger_x.shifts()); pipeline.push_node<ImagePipelineNodePixelShiftColumns>(session.stagger_x.shifts());
if (dbg_log_image_data()) { if (log_image_data) {
dev->pipeline.push_node<ImagePipelineNodeDebug>("gl_pipeline_" + pipeline.push_node<ImagePipelineNodeDebug>(debug_prefix + "_7_after_x_unstagger.tiff");
std::to_string(s_pipeline_index) +
"_7_after_x_unstagger.tiff");
} }
} }
if (session.num_staggered_lines > 0) { if (session.num_staggered_lines > 0) {
dev->pipeline.push_node<ImagePipelineNodePixelShiftLines>(session.stagger_y.shifts()); pipeline.push_node<ImagePipelineNodePixelShiftLines>(session.stagger_y.shifts());
if (dbg_log_image_data()) { if (log_image_data) {
dev->pipeline.push_node<ImagePipelineNodeDebug>("gl_pipeline_" + pipeline.push_node<ImagePipelineNodeDebug>(debug_prefix + "_8_after_y_unstagger.tiff");
std::to_string(s_pipeline_index) +
"_8_after_y_unstagger.tiff");
} }
} }
if (session.use_host_side_calib && if (session.use_host_side_calib &&
!has_flag(dev->model->flags, ModelFlag::DISABLE_SHADING_CALIBRATION) && !has_flag(dev.model->flags, ModelFlag::DISABLE_SHADING_CALIBRATION) &&
!has_flag(session.params.flags, ScanFlag::DISABLE_SHADING)) !has_flag(session.params.flags, ScanFlag::DISABLE_SHADING))
{ {
dev->pipeline.push_node<ImagePipelineNodeCalibrate>(dev->dark_average_data, pipeline.push_node<ImagePipelineNodeCalibrate>(dev.dark_average_data,
dev->white_average_data, dev.white_average_data,
session.params.startx * session.params.startx *
dev->calib_session.params.channels); dev.calib_session.params.channels);
if (dbg_log_image_data()) { if (log_image_data) {
dev->pipeline.push_node<ImagePipelineNodeDebug>("gl_pipeline_" + pipeline.push_node<ImagePipelineNodeDebug>(debug_prefix + "_9_after_calibrate.tiff");
std::to_string(s_pipeline_index) +
"_9_after_calibrate.tiff");
} }
} }
if (dev->pipeline.get_output_width() != session.params.get_requested_pixels()) { if (pipeline.get_output_width() != session.params.get_requested_pixels()) {
dev->pipeline.push_node<ImagePipelineNodeScaleRows>(session.params.get_requested_pixels()); pipeline.push_node<ImagePipelineNodeScaleRows>(session.params.get_requested_pixels());
} }
auto read_from_pipeline = [dev](std::size_t size, std::uint8_t* out_data) return pipeline;
}
void setup_image_pipeline(Genesys_Device& dev, const ScanSession& session)
{ {
(void) size; // will be always equal to dev->pipeline.get_output_row_bytes() static unsigned s_pipeline_index = 0;
return dev->pipeline.get_next_row_data(out_data);
s_pipeline_index++;
dev.pipeline = build_image_pipeline(dev, session, s_pipeline_index, dbg_log_image_data());
auto read_from_pipeline = [&dev](std::size_t size, std::uint8_t* out_data)
{
(void) size; // will be always equal to dev.pipeline.get_output_row_bytes()
return dev.pipeline.get_next_row_data(out_data);
}; };
dev->pipeline_buffer = ImageBuffer{dev->pipeline.get_output_row_bytes(), dev.pipeline_buffer = ImageBuffer{dev.pipeline.get_output_row_bytes(),
read_from_pipeline}; read_from_pipeline};
} }

Wyświetl plik

@ -418,7 +418,11 @@ extern void sanei_genesys_generate_gamma_buffer(Genesys_Device* dev,
void compute_session(const Genesys_Device* dev, ScanSession& s, const Genesys_Sensor& sensor); void compute_session(const Genesys_Device* dev, ScanSession& s, const Genesys_Sensor& sensor);
void build_image_pipeline(Genesys_Device* dev, const ScanSession& session); ImagePipelineStack build_image_pipeline(const Genesys_Device& dev, const ScanSession& session,
unsigned pipeline_index, bool log_image_data);
// sets up a image pipeline for device `dev`
void setup_image_pipeline(Genesys_Device& dev, const ScanSession& session);
std::uint8_t compute_frontend_gain(float value, float target_value, std::uint8_t compute_frontend_gain(float value, float target_value,
FrontendType frontend_type); FrontendType frontend_type);