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;
|
||||
|
||||
build_image_pipeline(dev, session);
|
||||
setup_image_pipeline(*dev, session);
|
||||
|
||||
// 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
|
||||
gl646_set_fe(dev, sensor, AFE_SET, session.output_resolution);
|
||||
|
||||
build_image_pipeline(dev, session);
|
||||
setup_image_pipeline(*dev, session);
|
||||
|
||||
dev->read_active = true;
|
||||
|
||||
|
|
|
@ -1056,7 +1056,7 @@ dummy \ scanned lines
|
|||
session.params.flags);
|
||||
}
|
||||
|
||||
build_image_pipeline(dev, session);
|
||||
setup_image_pipeline(*dev, session);
|
||||
|
||||
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.params.flags);
|
||||
|
||||
build_image_pipeline(dev, session);
|
||||
setup_image_pipeline(*dev, session);
|
||||
|
||||
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.params.flags);
|
||||
|
||||
build_image_pipeline(dev, session);
|
||||
setup_image_pipeline(*dev, session);
|
||||
|
||||
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_ENDPIXEL, session.pixel_endx);
|
||||
|
||||
build_image_pipeline(dev, session);
|
||||
setup_image_pipeline(*dev, session);
|
||||
|
||||
/* MAXWD is expressed in 4 words unit */
|
||||
// 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_ENDPIXEL, session.pixel_endx);
|
||||
|
||||
build_image_pipeline(dev, session);
|
||||
setup_image_pipeline(*dev, session);
|
||||
|
||||
/* MAXWD is expressed in 4 words unit */
|
||||
// BUG: we shouldn't multiply by channels here
|
||||
|
|
|
@ -524,6 +524,8 @@ class ImagePipelineStack
|
|||
{
|
||||
public:
|
||||
ImagePipelineStack() {}
|
||||
ImagePipelineStack(ImagePipelineStack&&) = default;
|
||||
ImagePipelineStack& operator=(ImagePipelineStack&&) = default;
|
||||
~ImagePipelineStack() { clear(); }
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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,
|
||||
dev->model->is_cis ? 1 : session.params.channels,
|
||||
dev->model->line_mode_color_order);
|
||||
dev.model->is_cis ? 1 : session.params.channels,
|
||||
dev.model->line_mode_color_order);
|
||||
auto depth = get_pixel_format_depth(format);
|
||||
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;
|
||||
};
|
||||
|
||||
auto debug_prefix = "gl_pipeline_" + std::to_string(pipeline_index);
|
||||
|
||||
ImagePipelineStack pipeline;
|
||||
|
||||
auto lines = session.optical_line_count;
|
||||
|
||||
dev->pipeline.clear();
|
||||
|
||||
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
|
||||
|
@ -958,141 +956,132 @@ void build_image_pipeline(Genesys_Device* dev, const ScanSession& session)
|
|||
new ImagePipelineNodeBufferedCallableSource(
|
||||
width, lines, format, buffer_size, read_data_from_usb));
|
||||
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()) {
|
||||
dev->pipeline.push_node<ImagePipelineNodeDebug>("gl_pipeline_" +
|
||||
std::to_string(s_pipeline_index) +
|
||||
"_0_from_usb.tiff");
|
||||
if (log_image_data) {
|
||||
pipeline.push_node<ImagePipelineNodeDebug>(debug_prefix + "_0_from_usb.tiff");
|
||||
}
|
||||
|
||||
if (session.segment_count > 1) {
|
||||
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,
|
||||
1, 1);
|
||||
|
||||
if (dbg_log_image_data()) {
|
||||
dev->pipeline.push_node<ImagePipelineNodeDebug>("gl_pipeline_" +
|
||||
std::to_string(s_pipeline_index) +
|
||||
"_1_after_desegment.tiff");
|
||||
if (log_image_data) {
|
||||
pipeline.push_node<ImagePipelineNodeDebug>(debug_prefix + "_1_after_desegment.tiff");
|
||||
}
|
||||
}
|
||||
|
||||
if (depth == 16) {
|
||||
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++;
|
||||
}
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
num_swaps++;
|
||||
#endif
|
||||
if (num_swaps % 2 != 0) {
|
||||
dev->pipeline.push_node<ImagePipelineNodeSwap16BitEndian>();
|
||||
pipeline.push_node<ImagePipelineNodeSwap16BitEndian>();
|
||||
|
||||
if (dbg_log_image_data()) {
|
||||
dev->pipeline.push_node<ImagePipelineNodeDebug>("gl_pipeline_" +
|
||||
std::to_string(s_pipeline_index) +
|
||||
"_2_after_swap.tiff");
|
||||
if (log_image_data) {
|
||||
pipeline.push_node<ImagePipelineNodeDebug>(debug_prefix + "_2_after_swap.tiff");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (has_flag(dev->model->flags, ModelFlag::INVERT_PIXEL_DATA)) {
|
||||
dev->pipeline.push_node<ImagePipelineNodeInvert>();
|
||||
if (has_flag(dev.model->flags, ModelFlag::INVERT_PIXEL_DATA)) {
|
||||
pipeline.push_node<ImagePipelineNodeInvert>();
|
||||
|
||||
if (dbg_log_image_data()) {
|
||||
dev->pipeline.push_node<ImagePipelineNodeDebug>("gl_pipeline_" +
|
||||
std::to_string(s_pipeline_index) +
|
||||
"_3_after_invert.tiff");
|
||||
if (log_image_data) {
|
||||
pipeline.push_node<ImagePipelineNodeDebug>(debug_prefix + "_3_after_invert.tiff");
|
||||
}
|
||||
}
|
||||
|
||||
if (dev->model->is_cis && session.params.channels == 3) {
|
||||
dev->pipeline.push_node<ImagePipelineNodeMergeMonoLines>(dev->model->line_mode_color_order);
|
||||
if (dev.model->is_cis && session.params.channels == 3) {
|
||||
pipeline.push_node<ImagePipelineNodeMergeMonoLines>(dev.model->line_mode_color_order);
|
||||
|
||||
if (dbg_log_image_data()) {
|
||||
dev->pipeline.push_node<ImagePipelineNodeDebug>("gl_pipeline_" +
|
||||
std::to_string(s_pipeline_index) +
|
||||
"_4_after_merge_mono.tiff");
|
||||
if (log_image_data) {
|
||||
pipeline.push_node<ImagePipelineNodeDebug>(debug_prefix + "_4_after_merge_mono.tiff");
|
||||
}
|
||||
}
|
||||
|
||||
if (dev->pipeline.get_output_format() == PixelFormat::BGR888) {
|
||||
dev->pipeline.push_node<ImagePipelineNodeFormatConvert>(PixelFormat::RGB888);
|
||||
if (pipeline.get_output_format() == PixelFormat::BGR888) {
|
||||
pipeline.push_node<ImagePipelineNodeFormatConvert>(PixelFormat::RGB888);
|
||||
}
|
||||
|
||||
if (dev->pipeline.get_output_format() == PixelFormat::BGR161616) {
|
||||
dev->pipeline.push_node<ImagePipelineNodeFormatConvert>(PixelFormat::RGB161616);
|
||||
if (pipeline.get_output_format() == PixelFormat::BGR161616) {
|
||||
pipeline.push_node<ImagePipelineNodeFormatConvert>(PixelFormat::RGB161616);
|
||||
}
|
||||
|
||||
if (dbg_log_image_data()) {
|
||||
dev->pipeline.push_node<ImagePipelineNodeDebug>("gl_pipeline_" +
|
||||
std::to_string(s_pipeline_index) +
|
||||
"_5_after_format.tiff");
|
||||
if (log_image_data) {
|
||||
pipeline.push_node<ImagePipelineNodeDebug>(debug_prefix + "_5_after_format.tiff");
|
||||
}
|
||||
|
||||
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_g,
|
||||
session.color_shift_lines_b);
|
||||
|
||||
if (dbg_log_image_data()) {
|
||||
dev->pipeline.push_node<ImagePipelineNodeDebug>("gl_pipeline_" +
|
||||
std::to_string(s_pipeline_index) +
|
||||
"_6_after_color_unshift.tiff");
|
||||
if (log_image_data) {
|
||||
pipeline.push_node<ImagePipelineNodeDebug>(debug_prefix + "_6_after_color_unshift.tiff");
|
||||
}
|
||||
}
|
||||
|
||||
if (!session.stagger_x.empty()) {
|
||||
// FIXME: the image will be scaled to requested pixel count without regard to the reduction
|
||||
// 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()) {
|
||||
dev->pipeline.push_node<ImagePipelineNodeDebug>("gl_pipeline_" +
|
||||
std::to_string(s_pipeline_index) +
|
||||
"_7_after_x_unstagger.tiff");
|
||||
if (log_image_data) {
|
||||
pipeline.push_node<ImagePipelineNodeDebug>(debug_prefix + "_7_after_x_unstagger.tiff");
|
||||
}
|
||||
}
|
||||
|
||||
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()) {
|
||||
dev->pipeline.push_node<ImagePipelineNodeDebug>("gl_pipeline_" +
|
||||
std::to_string(s_pipeline_index) +
|
||||
"_8_after_y_unstagger.tiff");
|
||||
if (log_image_data) {
|
||||
pipeline.push_node<ImagePipelineNodeDebug>(debug_prefix + "_8_after_y_unstagger.tiff");
|
||||
}
|
||||
}
|
||||
|
||||
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))
|
||||
{
|
||||
dev->pipeline.push_node<ImagePipelineNodeCalibrate>(dev->dark_average_data,
|
||||
dev->white_average_data,
|
||||
pipeline.push_node<ImagePipelineNodeCalibrate>(dev.dark_average_data,
|
||||
dev.white_average_data,
|
||||
session.params.startx *
|
||||
dev->calib_session.params.channels);
|
||||
dev.calib_session.params.channels);
|
||||
|
||||
if (dbg_log_image_data()) {
|
||||
dev->pipeline.push_node<ImagePipelineNodeDebug>("gl_pipeline_" +
|
||||
std::to_string(s_pipeline_index) +
|
||||
"_9_after_calibrate.tiff");
|
||||
if (log_image_data) {
|
||||
pipeline.push_node<ImagePipelineNodeDebug>(debug_prefix + "_9_after_calibrate.tiff");
|
||||
}
|
||||
}
|
||||
|
||||
if (dev->pipeline.get_output_width() != session.params.get_requested_pixels()) {
|
||||
dev->pipeline.push_node<ImagePipelineNodeScaleRows>(session.params.get_requested_pixels());
|
||||
if (pipeline.get_output_width() != 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)
|
||||
{
|
||||
static unsigned s_pipeline_index = 0;
|
||||
|
||||
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);
|
||||
(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};
|
||||
}
|
||||
|
||||
|
|
|
@ -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 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,
|
||||
FrontendType frontend_type);
|
||||
|
|
Ładowanie…
Reference in New Issue