kopia lustrzana https://gitlab.com/sane-project/backends
genesys: Allow pipeline to be created without mutating device
rodzic
ddeae7e8b0
commit
a23d61c26b
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Ładowanie…
Reference in New Issue