Merge branch 'genesys-split-genesys-low' into 'master'

genesys: Split genesys_low.h into several files

See merge request sane-project/backends!109
merge-requests/110/head
Povilas Kanapickas 2019-08-09 09:57:02 +00:00
commit 5bd9ab4941
14 zmienionych plików z 1956 dodań i 1432 usunięć

Wyświetl plik

@ -480,11 +480,21 @@ libsane_fujitsu_la_LDFLAGS = $(DIST_SANELIBS_LDFLAGS)
libsane_fujitsu_la_LIBADD = $(COMMON_LIBS) libfujitsu.la ../sanei/sanei_init_debug.lo ../sanei/sanei_constrain_value.lo ../sanei/sanei_config.lo ../sanei/sanei_config2.lo sane_strstatus.lo ../sanei/sanei_usb.lo ../sanei/sanei_scsi.lo ../sanei/sanei_magic.lo $(MATH_LIB) $(SCSI_LIBS) $(USB_LIBS) $(RESMGR_LIBS)
EXTRA_DIST += fujitsu.conf.in
libgenesys_la_SOURCES = genesys.cc genesys.h genesys_sanei.h genesys_sanei.cc genesys_error.h genesys_error.cc \
genesys_serialize.h \
libgenesys_la_SOURCES = genesys.cc genesys.h \
genesys_buffer.h genesys_buffer.cc \
genesys_calibration.h \
genesys_device.h genesys_device.cc \
genesys_enums.h \
genesys_error.h genesys_error.cc \
genesys_gl646.cc genesys_gl646.h genesys_gl841.cc genesys_gl841.h \
genesys_gl843.cc genesys_gl843.h genesys_gl846.cc genesys_gl846.h \
genesys_gl847.cc genesys_gl847.h genesys_gl124.cc genesys_gl124.h \
genesys_motor.h \
genesys_register.h \
genesys_sanei.h genesys_sanei.cc \
genesys_sensor.h \
genesys_settings.h \
genesys_serialize.h \
genesys_low.cc genesys_low.h
libgenesys_la_CPPFLAGS = $(AM_CPPFLAGS) -DBACKEND_NAME=genesys $(XML_CFLAGS)

Wyświetl plik

@ -3471,64 +3471,6 @@ static void genesys_start_scan(Genesys_Device* dev, SANE_Bool lamp_off)
}
}
/* this is _not_ a ringbuffer.
if we need a block which does not fit at the end of our available data,
we move the available data to the beginning.
*/
void Genesys_Buffer::alloc(size_t size)
{
buffer_.resize(size);
avail_ = 0;
pos_ = 0;
}
void Genesys_Buffer::clear()
{
buffer_.clear();
avail_ = 0;
pos_ = 0;
}
void Genesys_Buffer::reset()
{
avail_ = 0;
pos_ = 0;
}
uint8_t* Genesys_Buffer::get_write_pos(size_t size)
{
if (avail_ + size > buffer_.size())
return nullptr;
if (pos_ + avail_ + size > buffer_.size())
{
std::memmove(buffer_.data(), buffer_.data() + pos_, avail_);
pos_ = 0;
}
return buffer_.data() + pos_ + avail_;
}
uint8_t* Genesys_Buffer::get_read_pos()
{
return buffer_.data() + pos_;
}
void Genesys_Buffer::produce(size_t size)
{
if (size > buffer_.size() - avail_)
throw std::runtime_error("buffer size exceeded");
avail_ += size;
}
void Genesys_Buffer::consume(size_t size)
{
if (size > avail_)
throw std::runtime_error("no more data in buffer");
avail_ -= size;
pos_ += size;
}
#include "genesys_conv.cc"
static void accurate_line_read(Genesys_Device* dev, Genesys_Buffer& buffer)

Wyświetl plik

@ -0,0 +1,98 @@
/* sane - Scanner Access Now Easy.
Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt>
This file is part of the SANE package.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA.
As a special exception, the authors of SANE give permission for
additional uses of the libraries contained in this release of SANE.
The exception is that, if you link a SANE library with other files
to produce an executable, this does not by itself cause the
resulting executable to be covered by the GNU General Public
License. Your use of that executable is in no way restricted on
account of linking the SANE library code into it.
This exception does not, however, invalidate any other reasons why
the executable file might be covered by the GNU General Public
License.
If you submit changes to SANE to the maintainers to be included in
a subsequent release, you agree by submitting the changes that
those changes may be distributed with this exception intact.
If you write modifications of your own for SANE, it is your choice
whether to permit this exception to apply to your modifications.
If you do not wish that, delete this exception notice.
*/
#include "genesys_buffer.h"
#include <cstring>
#include <stdexcept>
void Genesys_Buffer::alloc(size_t size)
{
buffer_.resize(size);
avail_ = 0;
pos_ = 0;
}
void Genesys_Buffer::clear()
{
buffer_.clear();
avail_ = 0;
pos_ = 0;
}
void Genesys_Buffer::reset()
{
avail_ = 0;
pos_ = 0;
}
uint8_t* Genesys_Buffer::get_write_pos(size_t size)
{
if (avail_ + size > buffer_.size())
return nullptr;
if (pos_ + avail_ + size > buffer_.size())
{
std::memmove(buffer_.data(), buffer_.data() + pos_, avail_);
pos_ = 0;
}
return buffer_.data() + pos_ + avail_;
}
uint8_t* Genesys_Buffer::get_read_pos()
{
return buffer_.data() + pos_;
}
void Genesys_Buffer::produce(size_t size)
{
if (size > buffer_.size() - avail_)
throw std::runtime_error("buffer size exceeded");
avail_ += size;
}
void Genesys_Buffer::consume(size_t size)
{
if (size > avail_)
throw std::runtime_error("no more data in buffer");
avail_ -= size;
pos_ += size;
}

Wyświetl plik

@ -0,0 +1,85 @@
/* sane - Scanner Access Now Easy.
Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt>
This file is part of the SANE package.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA.
As a special exception, the authors of SANE give permission for
additional uses of the libraries contained in this release of SANE.
The exception is that, if you link a SANE library with other files
to produce an executable, this does not by itself cause the
resulting executable to be covered by the GNU General Public
License. Your use of that executable is in no way restricted on
account of linking the SANE library code into it.
This exception does not, however, invalidate any other reasons why
the executable file might be covered by the GNU General Public
License.
If you submit changes to SANE to the maintainers to be included in
a subsequent release, you agree by submitting the changes that
those changes may be distributed with this exception intact.
If you write modifications of your own for SANE, it is your choice
whether to permit this exception to apply to your modifications.
If you do not wish that, delete this exception notice.
*/
#ifndef BACKEND_GENESYS_BUFFER_H
#define BACKEND_GENESYS_BUFFER_H
#include <vector>
#include <cstddef>
#include <cstdint>
/* A FIFO buffer. Note, that this is _not_ a ringbuffer.
if we need a block which does not fit at the end of our available data,
we move the available data to the beginning.
*/
struct Genesys_Buffer
{
Genesys_Buffer() = default;
size_t size() const { return buffer_.size(); }
size_t avail() const { return avail_; }
size_t pos() const { return pos_; }
// TODO: refactor code that uses this function to no longer use it
void set_pos(size_t pos) { pos_ = pos; }
void alloc(size_t size);
void clear();
void reset();
uint8_t* get_write_pos(size_t size);
uint8_t* get_read_pos(); // TODO: mark as const
void produce(size_t size);
void consume(size_t size);
private:
std::vector<uint8_t> buffer_;
// current position in read buffer
size_t pos_ = 0;
// data bytes currently in buffer
size_t avail_ = 0;
};
#endif // BACKEND_GENESYS_BUFFER_H

Wyświetl plik

@ -0,0 +1,102 @@
/* sane - Scanner Access Now Easy.
Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt>
This file is part of the SANE package.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA.
As a special exception, the authors of SANE give permission for
additional uses of the libraries contained in this release of SANE.
The exception is that, if you link a SANE library with other files
to produce an executable, this does not by itself cause the
resulting executable to be covered by the GNU General Public
License. Your use of that executable is in no way restricted on
account of linking the SANE library code into it.
This exception does not, however, invalidate any other reasons why
the executable file might be covered by the GNU General Public
License.
If you submit changes to SANE to the maintainers to be included in
a subsequent release, you agree by submitting the changes that
those changes may be distributed with this exception intact.
If you write modifications of your own for SANE, it is your choice
whether to permit this exception to apply to your modifications.
If you do not wish that, delete this exception notice.
*/
#ifndef BACKEND_GENESYS_CALIBRATION_H
#define BACKEND_GENESYS_CALIBRATION_H
#include "genesys_sensor.h"
#include "genesys_settings.h"
struct Genesys_Calibration_Cache
{
Genesys_Calibration_Cache() = default;
~Genesys_Calibration_Cache() = default;
// used to check if entry is compatible
Genesys_Current_Setup used_setup;
time_t last_calibration = 0;
Genesys_Frontend frontend;
Genesys_Sensor sensor;
size_t calib_pixels = 0;
size_t calib_channels = 0;
size_t average_size = 0;
std::vector<uint8_t> white_average_data;
std::vector<uint8_t> dark_average_data;
bool operator==(const Genesys_Calibration_Cache& other) const
{
return used_setup == other.used_setup &&
last_calibration == other.last_calibration &&
frontend == other.frontend &&
sensor == other.sensor &&
calib_pixels == other.calib_pixels &&
calib_channels == other.calib_channels &&
average_size == other.average_size &&
white_average_data == other.white_average_data &&
dark_average_data == other.dark_average_data;
}
};
template<class Stream>
void serialize(Stream& str, Genesys_Calibration_Cache& x)
{
serialize(str, x.used_setup);
serialize_newline(str);
serialize(str, x.last_calibration);
serialize_newline(str);
serialize(str, x.frontend);
serialize_newline(str);
serialize(str, x.sensor);
serialize_newline(str);
serialize(str, x.calib_pixels);
serialize(str, x.calib_channels);
serialize(str, x.average_size);
serialize_newline(str);
serialize(str, x.white_average_data);
serialize_newline(str);
serialize(str, x.dark_average_data);
}
#endif // BACKEND_GENESYS_CALIBRATION_H

Wyświetl plik

@ -0,0 +1,83 @@
/* sane - Scanner Access Now Easy.
Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt>
This file is part of the SANE package.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA.
As a special exception, the authors of SANE give permission for
additional uses of the libraries contained in this release of SANE.
The exception is that, if you link a SANE library with other files
to produce an executable, this does not by itself cause the
resulting executable to be covered by the GNU General Public
License. Your use of that executable is in no way restricted on
account of linking the SANE library code into it.
This exception does not, however, invalidate any other reasons why
the executable file might be covered by the GNU General Public
License.
If you submit changes to SANE to the maintainers to be included in
a subsequent release, you agree by submitting the changes that
those changes may be distributed with this exception intact.
If you write modifications of your own for SANE, it is your choice
whether to permit this exception to apply to your modifications.
If you do not wish that, delete this exception notice.
*/
#define DEBUG_DECLARE_ONLY
#include "genesys_device.h"
#include "genesys_low.h"
Genesys_Device::~Genesys_Device()
{
clear();
if (file_name != nullptr)
free(file_name);
}
void Genesys_Device::clear()
{
read_buffer.clear();
lines_buffer.clear();
shrink_buffer.clear();
out_buffer.clear();
binarize_buffer.clear();
local_buffer.clear();
calib_file.clear();
calibration_cache.clear();
white_average_data.clear();
dark_average_data.clear();
}
void apply_reg_settings_to_device(Genesys_Device& dev, const GenesysRegisterSettingSet& regs)
{
for (const auto& reg : regs) {
uint8_t val;
sanei_genesys_read_register(&dev, reg.address, &val);
val = (val & ~reg.mask) | (reg.value & reg.mask);
sanei_genesys_write_register(&dev, reg.address, val);
}
}

Wyświetl plik

@ -0,0 +1,338 @@
/* sane - Scanner Access Now Easy.
Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt>
This file is part of the SANE package.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA.
As a special exception, the authors of SANE give permission for
additional uses of the libraries contained in this release of SANE.
The exception is that, if you link a SANE library with other files
to produce an executable, this does not by itself cause the
resulting executable to be covered by the GNU General Public
License. Your use of that executable is in no way restricted on
account of linking the SANE library code into it.
This exception does not, however, invalidate any other reasons why
the executable file might be covered by the GNU General Public
License.
If you submit changes to SANE to the maintainers to be included in
a subsequent release, you agree by submitting the changes that
those changes may be distributed with this exception intact.
If you write modifications of your own for SANE, it is your choice
whether to permit this exception to apply to your modifications.
If you do not wish that, delete this exception notice.
*/
#ifndef BACKEND_GENESYS_DEVICE_H
#define BACKEND_GENESYS_DEVICE_H
#include "genesys_calibration.h"
#include "genesys_buffer.h"
#include "genesys_enums.h"
#include "genesys_motor.h"
#include "genesys_settings.h"
#include "genesys_sensor.h"
#include "genesys_register.h"
#include "genesys_sanei.h"
#include <vector>
struct Genesys_Gpo
{
Genesys_Gpo() = default;
Genesys_Gpo(uint8_t id, const std::array<uint8_t, 2>& v, const std::array<uint8_t, 2>& e)
{
gpo_id = id;
value[0] = v[0];
value[1] = v[1];
enable[0] = e[0];
enable[1] = e[1];
}
// Genesys_Gpo
uint8_t gpo_id = 0;
// registers 0x6c and 0x6d on GL841, GL842, GL843, GL846, GL848 and possibly others
uint8_t value[2] = { 0, 0 };
// registers 0x6e and 0x6f on GL841, GL842, GL843, GL846, GL848 and possibly others
uint8_t enable[2] = { 0, 0 };
};
struct Genesys_Command_Set;
/** @brief structure to describe a scanner model
* This structure describes a model. It is composed of information on the
* sensor, the motor, scanner geometry and flags to drive operation.
*/
struct Genesys_Model
{
Genesys_Model() = default;
const char* name = nullptr;
const char* vendor = nullptr;
const char* model = nullptr;
unsigned model_id = 0;
// ASIC type gl646 or gl841
unsigned asic_type = 0;
// pointers to low level functions
Genesys_Command_Set* cmd_set = nullptr;
// possible x resolutions
std::vector<unsigned> xdpi_values;
// possible y resolutions
std::vector<unsigned> ydpi_values;
// possible depths in gray mode
std::vector<unsigned> bpp_gray_values;
// possible depths in color mode
std::vector<unsigned> bpp_color_values;
// All offsets below are with respect to the sensor home position
// Start of scan area in mm
SANE_Fixed x_offset = 0;
// Start of scan area in mm (Amount of feeding needed to get to the medium)
SANE_Fixed y_offset = 0;
// Size of scan area in mm
SANE_Fixed x_size = 0;
// Size of scan area in mm
SANE_Fixed y_size = 0;
// Start of white strip in mm
SANE_Fixed y_offset_calib = 0;
// Start of black mark in mm
SANE_Fixed x_offset_mark = 0;
// Start of scan area in TA mode in mm
SANE_Fixed x_offset_ta = 0;
// Start of scan area in TA mode in mm
SANE_Fixed y_offset_ta = 0;
// Size of scan area in TA mode in mm
SANE_Fixed x_size_ta = 0;
// Size of scan area in TA mode in mm
SANE_Fixed y_size_ta = 0;
// The position of the sensor when it's aligned with the lamp for transparency scanning
SANE_Fixed y_offset_sensor_to_ta = 0;
// Start of white strip in TA mode in mm
SANE_Fixed y_offset_calib_ta = 0;
// Size of scan area after paper sensor stop sensing document in mm
SANE_Fixed post_scan = 0;
// Amount of feeding needed to eject document after finishing scanning in mm
SANE_Fixed eject_feed = 0;
// Line-distance correction (in pixel at optical_ydpi) for CCD scanners
SANE_Int ld_shift_r = 0;
SANE_Int ld_shift_g = 0;
SANE_Int ld_shift_b = 0;
// Order of the CCD/CIS colors
Genesys_Color_Order line_mode_color_order = COLOR_ORDER_RGB;
// Is this a CIS or CCD scanner?
SANE_Bool is_cis = false;
// Is this sheetfed scanner?
SANE_Bool is_sheetfed = false;
// sensor type
SANE_Int ccd_type = 0;
// Digital-Analog converter type (TODO: rename to ADC)
SANE_Int dac_type = 0;
// General purpose output type
SANE_Int gpo_type = 0;
// stepper motor type
SANE_Int motor_type = 0;
// Which hacks are needed for this scanner?
SANE_Word flags = 0;
// Button flags, described existing buttons for the model
SANE_Word buttons = 0;
// how many lines are used for shading calibration
SANE_Int shading_lines = 0;
// how many lines are used for shading calibration in TA mode
SANE_Int shading_ta_lines = 0;
// how many lines are used to search start position
SANE_Int search_lines = 0;
};
/**
* Describes the current device status for the backend
* session. This should be more accurately called
* Genesys_Session .
*/
struct Genesys_Device
{
Genesys_Device() = default;
~Genesys_Device();
using Calibration = std::vector<Genesys_Calibration_Cache>;
// frees commonly used data
void clear();
UsbDevice usb_dev;
SANE_Word vendorId = 0; /**< USB vendor identifier */
SANE_Word productId = 0; /**< USB product identifier */
// USB mode:
// 0: not set
// 1: USB 1.1
// 2: USB 2.0
SANE_Int usb_mode = 0;
SANE_String file_name = nullptr;
std::string calib_file;
// if enabled, no calibration data will be loaded or saved to files
SANE_Int force_calibration = 0;
// if enabled, will ignore the scan offsets and start scanning at true origin. This allows
// acquiring the positions of the black and white strips and the actual scan area
bool ignore_offsets = false;
Genesys_Model *model = nullptr;
Genesys_Register_Set reg;
Genesys_Register_Set calib_reg;
Genesys_Settings settings;
Genesys_Frontend frontend, frontend_initial;
Genesys_Gpo gpo;
Genesys_Motor motor;
uint8_t control[6] = {};
size_t average_size = 0;
// number of pixels used during shading calibration
size_t calib_pixels = 0;
// number of lines used during shading calibration
size_t calib_lines = 0;
size_t calib_channels = 0;
size_t calib_resolution = 0;
// bytes to read from USB when calibrating. If 0, this is not set
size_t calib_total_bytes_to_read = 0;
// certain scanners support much higher resolution when scanning transparency, but we can't
// read whole width of the scanner as a single line at that resolution. Thus for stuff like
// calibration we want to read only the possible calibration area.
size_t calib_pixels_offset = 0;
// gamma overrides. If a respective array is not empty then it means that the gamma for that
// color is overridden.
std::vector<uint16_t> gamma_override_tables[3];
std::vector<uint8_t> white_average_data;
std::vector<uint8_t> dark_average_data;
SANE_Bool already_initialized = 0;
SANE_Int scanhead_position_in_steps = 0;
SANE_Bool read_active = 0;
// signal wether the park command has been issued
SANE_Bool parking = 0;
// for sheetfed scanner's, is TRUE when there is a document in the scanner
SANE_Bool document = 0;
SANE_Bool needs_home_ta = 0;
Genesys_Buffer read_buffer;
Genesys_Buffer lines_buffer;
Genesys_Buffer shrink_buffer;
Genesys_Buffer out_buffer;
// buffer for digital lineart from gray data
Genesys_Buffer binarize_buffer;
// local buffer for gray data during dynamix lineart
Genesys_Buffer local_buffer;
// bytes to read from scanner
size_t read_bytes_left = 0;
// total bytes read sent to frontend
size_t total_bytes_read = 0;
// total bytes read to be sent to frontend
size_t total_bytes_to_read = 0;
// asic's word per line
size_t wpl = 0;
// contains the real used values
Genesys_Current_Setup current_setup;
// look up table used in dynamic rasterization
unsigned char lineart_lut[256] = {};
Calibration calibration_cache;
// used red line-distance shift
SANE_Int ld_shift_r = 0;
// used green line-distance shift
SANE_Int ld_shift_g = 0;
// used blue line-distance shift
SANE_Int ld_shift_b = 0;
// number of segments composing the sensor
int segnb = 0;
// number of lines used in line interpolation
int line_interp = 0;
// number of scan lines used during scan
int line_count = 0;
// bytes per full scan widthline
size_t bpl = 0;
// bytes distance between an odd and an even pixel
size_t dist = 0;
// number of even pixels
size_t len = 0;
// current pixel position within sub window
size_t cur = 0;
// number of bytes to skip at start of line
size_t skip = 0;
// array describing the order of the sub-segments of the sensor
size_t* order = nullptr;
// buffer to handle even/odd data
Genesys_Buffer oe_buffer = {};
// when true the scanned picture is first buffered to allow software image enhancements
SANE_Bool buffer_image = 0;
// image buffer where the scanned picture is stored
std::vector<uint8_t> img_buffer;
// binary logger file
FILE *binary = nullptr;
};
void apply_reg_settings_to_device(Genesys_Device& dev, const GenesysRegisterSettingSet& regs);
#endif

Wyświetl plik

@ -0,0 +1,289 @@
/* sane - Scanner Access Now Easy.
Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt>
This file is part of the SANE package.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA.
As a special exception, the authors of SANE give permission for
additional uses of the libraries contained in this release of SANE.
The exception is that, if you link a SANE library with other files
to produce an executable, this does not by itself cause the
resulting executable to be covered by the GNU General Public
License. Your use of that executable is in no way restricted on
account of linking the SANE library code into it.
This exception does not, however, invalidate any other reasons why
the executable file might be covered by the GNU General Public
License.
If you submit changes to SANE to the maintainers to be included in
a subsequent release, you agree by submitting the changes that
those changes may be distributed with this exception intact.
If you write modifications of your own for SANE, it is your choice
whether to permit this exception to apply to your modifications.
If you do not wish that, delete this exception notice.
*/
#ifndef BACKEND_GENESYS_ENUMS_H
#define BACKEND_GENESYS_ENUMS_H
#include <iostream>
#include "genesys_serialize.h"
enum class ScanMethod : unsigned {
// normal scan method
FLATBED = 0,
// scan using transparency adaptor
TRANSPARENCY = 1,
// scan using transparency adaptor via infrared channel
TRANSPARENCY_INFRARED = 2
};
inline void serialize(std::istream& str, ScanMethod& x)
{
unsigned value;
serialize(str, value);
x = static_cast<ScanMethod>(value);
}
inline void serialize(std::ostream& str, ScanMethod& x)
{
unsigned value = static_cast<unsigned>(x);
serialize(str, value);
}
enum class ScanColorMode : unsigned {
LINEART = 0,
HALFTONE,
GRAY,
COLOR_SINGLE_PASS
};
inline void serialize(std::istream& str, ScanColorMode& x)
{
unsigned value;
serialize(str, value);
x = static_cast<ScanColorMode>(value);
}
inline void serialize(std::ostream& str, ScanColorMode& x)
{
unsigned value = static_cast<unsigned>(x);
serialize(str, value);
}
enum class ColorFilter : unsigned {
RED = 0,
GREEN,
BLUE,
NONE
};
inline void serialize(std::istream& str, ColorFilter& x)
{
unsigned value;
serialize(str, value);
x = static_cast<ColorFilter>(value);
}
inline void serialize(std::ostream& str, ColorFilter& x)
{
unsigned value = static_cast<unsigned>(x);
serialize(str, value);
}
enum Genesys_Color_Order
{
COLOR_ORDER_RGB,
COLOR_ORDER_BGR
};
enum Genesys_Model_Type
{
MODEL_UMAX_ASTRA_4500 = 0,
MODEL_CANON_LIDE_50,
MODEL_PANASONIC_KV_SS080,
MODEL_HP_SCANJET_4850C,
MODEL_HP_SCANJET_G4010,
MODEL_HP_SCANJET_G4050,
MODEL_CANON_CANOSCAN_4400F,
MODEL_CANON_CANOSCAN_8400F,
MODEL_CANON_CANOSCAN_8600F,
MODEL_CANON_LIDE_100,
MODEL_CANON_LIDE_110,
MODEL_CANON_LIDE_120,
MODEL_CANON_LIDE_210,
MODEL_CANON_LIDE_220,
MODEL_CANON_CANOSCAN_5600F,
MODEL_CANON_LIDE_700F,
MODEL_CANON_LIDE_200,
MODEL_CANON_LIDE_60,
MODEL_CANON_LIDE_80,
MODEL_HP_SCANJET_2300C,
MODEL_HP_SCANJET_2400C,
MODEL_VISIONEER_STROBE_XP200,
MODEL_HP_SCANJET_3670C,
MODEL_PLUSTEK_OPTICPRO_ST12,
MODEL_PLUSTEK_OPTICPRO_ST24,
MODEL_MEDION_MD5345,
MODEL_VISIONEER_STROBE_XP300,
MODEL_SYSCAN_DOCKETPORT_665,
MODEL_VISIONEER_ROADWARRIOR,
MODEL_SYSCAN_DOCKETPORT_465,
MODEL_VISIONEER_STROBE_XP100_REVISION3,
MODEL_PENTAX_DSMOBILE_600,
MODEL_SYSCAN_DOCKETPORT_467,
MODEL_SYSCAN_DOCKETPORT_685,
MODEL_SYSCAN_DOCKETPORT_485,
MODEL_DCT_DOCKETPORT_487,
MODEL_VISIONEER_7100,
MODEL_XEROX_2400,
MODEL_XEROX_TRAVELSCANNER_100,
MODEL_PLUSTEK_OPTICPRO_3600,
MODEL_HP_SCANJET_N6310,
MODEL_PLUSTEK_OPTICBOOK_3800,
MODEL_CANON_IMAGE_FORMULA_101
};
enum Genesys_Sensor_Type
{
CCD_UMAX = 0,
CCD_ST12, // SONY ILX548: 5340 Pixel ???
CCD_ST24, // SONY ILX569: 10680 Pixel ???
CCD_5345,
CCD_HP2400,
CCD_HP2300,
CCD_CANONLIDE35,
CIS_XP200, // CIS sensor for Strobe XP200,
CCD_HP3670,
CCD_DP665,
CCD_ROADWARRIOR,
CCD_DSMOBILE600,
CCD_XP300,
CCD_DP685,
CIS_CANONLIDE200,
CIS_CANONLIDE100,
CCD_KVSS080,
CCD_G4050,
CIS_CANONLIDE110,
CCD_PLUSTEK_3600,
CCD_HP_N6310,
CIS_CANONLIDE700,
CCD_CS4400F,
CCD_CS8400F,
CCD_CS8600F,
CCD_IMG101,
CCD_PLUSTEK3800,
CIS_CANONLIDE210,
CIS_CANONLIDE80,
CIS_CANONLIDE220,
CIS_CANONLIDE120,
};
enum Genesys_Dac_Type
{
DAC_WOLFSON_UMAX = 0,
DAC_WOLFSON_ST12,
DAC_WOLFSON_ST24,
DAC_WOLFSON_5345,
DAC_WOLFSON_HP2400,
DAC_WOLFSON_HP2300,
DAC_CANONLIDE35,
DAC_AD_XP200,
DAC_WOLFSON_XP300,
DAC_WOLFSON_HP3670,
DAC_WOLFSON_DSM600,
DAC_CANONLIDE200,
DAC_KVSS080,
DAC_G4050,
DAC_CANONLIDE110,
DAC_PLUSTEK_3600,
DAC_CANONLIDE700,
DAC_CS8400F,
DAC_CS8600F,
DAC_IMG101,
DAC_PLUSTEK3800,
DAC_CANONLIDE80,
DAC_CANONLIDE120
};
enum Genesys_Gpo_Type
{
GPO_UMAX,
GPO_ST12,
GPO_ST24,
GPO_5345,
GPO_HP2400,
GPO_HP2300,
GPO_CANONLIDE35,
GPO_XP200,
GPO_XP300,
GPO_HP3670,
GPO_DP665,
GPO_DP685,
GPO_CANONLIDE200,
GPO_KVSS080,
GPO_G4050,
GPO_CANONLIDE110,
GPO_PLUSTEK_3600,
GPO_CANONLIDE210,
GPO_HP_N6310,
GPO_CANONLIDE700,
GPO_CS4400F,
GPO_CS8400F,
GPO_CS8600F,
GPO_IMG101,
GPO_PLUSTEK3800,
GPO_CANONLIDE80,
GPO_CANONLIDE120
};
enum Genesys_Motor_Type
{
MOTOR_UMAX = 0,
MOTOR_5345,
MOTOR_ST24,
MOTOR_HP2400,
MOTOR_HP2300,
MOTOR_CANONLIDE35,
MOTOR_XP200,
MOTOR_XP300,
MOTOR_HP3670,
MOTOR_DP665,
MOTOR_ROADWARRIOR,
MOTOR_DSMOBILE_600,
MOTOR_CANONLIDE200,
MOTOR_CANONLIDE100,
MOTOR_KVSS080,
MOTOR_G4050,
MOTOR_CANONLIDE110,
MOTOR_PLUSTEK_3600,
MOTOR_CANONLIDE700,
MOTOR_CS8400F,
MOTOR_CS8600F,
MOTOR_IMG101,
MOTOR_PLUSTEK3800,
MOTOR_CANONLIDE210,
MOTOR_CANONLIDE80,
MOTOR_CANONLIDE120
};
#endif // BACKEND_GENESYS_ENUMS_H

Wyświetl plik

@ -49,42 +49,6 @@
#include <vector>
Genesys_Device::~Genesys_Device()
{
clear();
if (file_name != nullptr)
free(file_name);
}
void Genesys_Device::clear()
{
read_buffer.clear();
lines_buffer.clear();
shrink_buffer.clear();
out_buffer.clear();
binarize_buffer.clear();
local_buffer.clear();
calib_file.clear();
calibration_cache.clear();
white_average_data.clear();
dark_average_data.clear();
}
void apply_reg_settings_to_device(Genesys_Device& dev, const GenesysRegisterSettingSet& regs)
{
for (const auto& reg : regs) {
uint8_t val;
sanei_genesys_read_register(&dev, reg.address, &val);
val = (val & ~reg.mask) | (reg.value & reg.mask);
sanei_genesys_write_register(&dev, reg.address, val);
}
}
/* ------------------------------------------------------------------------ */
/* functions calling ASIC specific functions */
/* ------------------------------------------------------------------------ */

Plik diff jest za duży Load Diff

Wyświetl plik

@ -0,0 +1,106 @@
/* sane - Scanner Access Now Easy.
Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt>
This file is part of the SANE package.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA.
As a special exception, the authors of SANE give permission for
additional uses of the libraries contained in this release of SANE.
The exception is that, if you link a SANE library with other files
to produce an executable, this does not by itself cause the
resulting executable to be covered by the GNU General Public
License. Your use of that executable is in no way restricted on
account of linking the SANE library code into it.
This exception does not, however, invalidate any other reasons why
the executable file might be covered by the GNU General Public
License.
If you submit changes to SANE to the maintainers to be included in
a subsequent release, you agree by submitting the changes that
those changes may be distributed with this exception intact.
If you write modifications of your own for SANE, it is your choice
whether to permit this exception to apply to your modifications.
If you do not wish that, delete this exception notice.
*/
#ifndef BACKEND_GENESYS_MOTOR_H
#define BACKEND_GENESYS_MOTOR_H
#include <cstdint>
#include <vector>
struct Genesys_Motor_Slope
{
Genesys_Motor_Slope() = default;
Genesys_Motor_Slope(int p_maximum_start_speed, int p_maximum_speed, int p_minimum_steps,
float p_g) :
maximum_start_speed(p_maximum_start_speed),
maximum_speed(p_maximum_speed),
minimum_steps(p_minimum_steps),
g(p_g)
{}
// maximum speed allowed when accelerating from standstill. Unit: pixeltime/step
int maximum_start_speed = 0;
// maximum speed allowed. Unit: pixeltime/step
int maximum_speed = 0;
// number of steps used for default curve
int minimum_steps = 0;
/* power for non-linear acceleration curves.
vs*(1-i^g)+ve*(i^g) where
vs = start speed, ve = end speed,
i = 0.0 for first entry and i = 1.0 for last entry in default table
*/
float g = 0;
};
struct Genesys_Motor
{
Genesys_Motor() = default;
Genesys_Motor(uint8_t p_motor_id, int p_base_ydpi, int p_optical_ydpi, int p_max_step_type,
int p_power_mode_count,
const std::vector<std::vector<Genesys_Motor_Slope>>& p_slopes) :
motor_id(p_motor_id),
base_ydpi(p_base_ydpi),
optical_ydpi(p_optical_ydpi),
max_step_type(p_max_step_type),
power_mode_count(p_power_mode_count),
slopes(p_slopes)
{}
// id of the motor description
uint8_t motor_id = 0;
// motor base steps. Unit: 1/inch
int base_ydpi = 0;
// maximum resolution in y-direction. Unit: 1/inch
int optical_ydpi = 0;
// maximum step type. 0-2
int max_step_type = 0;
// number of power modes
int power_mode_count = 0;
// slopes to derive individual slopes from
std::vector<std::vector<Genesys_Motor_Slope>> slopes;
};
#endif // BACKEND_GENESYS_MOTOR_H

Wyświetl plik

@ -0,0 +1,334 @@
/* sane - Scanner Access Now Easy.
Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt>
This file is part of the SANE package.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA.
As a special exception, the authors of SANE give permission for
additional uses of the libraries contained in this release of SANE.
The exception is that, if you link a SANE library with other files
to produce an executable, this does not by itself cause the
resulting executable to be covered by the GNU General Public
License. Your use of that executable is in no way restricted on
account of linking the SANE library code into it.
This exception does not, however, invalidate any other reasons why
the executable file might be covered by the GNU General Public
License.
If you submit changes to SANE to the maintainers to be included in
a subsequent release, you agree by submitting the changes that
those changes may be distributed with this exception intact.
If you write modifications of your own for SANE, it is your choice
whether to permit this exception to apply to your modifications.
If you do not wish that, delete this exception notice.
*/
#ifndef BACKEND_GENESYS_REGISTER_H
#define BACKEND_GENESYS_REGISTER_H
#include <algorithm>
#include <cstdint>
#include <iostream>
#include <stdexcept>
#include <vector>
struct GenesysRegister
{
uint16_t address = 0;
uint8_t value = 0;
};
inline bool operator<(const GenesysRegister& lhs, const GenesysRegister& rhs)
{
return lhs.address < rhs.address;
}
struct GenesysRegisterSetState
{
bool is_lamp_on = false;
bool is_xpa_on = false;
};
class Genesys_Register_Set
{
public:
static constexpr unsigned MAX_REGS = 256;
using container = std::vector<GenesysRegister>;
using iterator = typename container::iterator;
using const_iterator = typename container::const_iterator;
// FIXME: this shouldn't live here, but in a separate struct that contains Genesys_Register_Set
GenesysRegisterSetState state;
enum Options {
SEQUENTIAL = 1
};
Genesys_Register_Set()
{
registers_.reserve(MAX_REGS);
}
// by default the register set is sorted by address. In certain cases it's importand to send
// the registers in certain order: use the SEQUENTIAL option for that
Genesys_Register_Set(Options opts) : Genesys_Register_Set()
{
if ((opts & SEQUENTIAL) == SEQUENTIAL) {
sorted_ = false;
}
}
void init_reg(uint16_t address, uint8_t default_value)
{
if (find_reg_index(address) >= 0) {
set8(address, default_value);
return;
}
GenesysRegister reg;
reg.address = address;
reg.value = default_value;
registers_.push_back(reg);
if (sorted_)
std::sort(registers_.begin(), registers_.end());
}
void remove_reg(uint16_t address)
{
int i = find_reg_index(address);
if (i < 0) {
throw std::runtime_error("the register does not exist");
}
registers_.erase(registers_.begin() + i);
}
GenesysRegister& find_reg(uint16_t address)
{
int i = find_reg_index(address);
if (i < 0) {
throw std::runtime_error("the register does not exist");
}
return registers_[i];
}
const GenesysRegister& find_reg(uint16_t address) const
{
int i = find_reg_index(address);
if (i < 0) {
throw std::runtime_error("the register does not exist");
}
return registers_[i];
}
GenesysRegister* find_reg_address(uint16_t address)
{
return &find_reg(address);
}
const GenesysRegister* find_reg_address(uint16_t address) const
{
return &find_reg(address);
}
void set8(uint16_t address, uint8_t value)
{
find_reg(address).value = value;
}
void set8_mask(uint16_t address, uint8_t value, uint8_t mask)
{
auto& reg = find_reg(address);
reg.value = (reg.value & ~mask) | value;
}
void set16(uint16_t address, uint16_t value)
{
find_reg(address).value = (value >> 8) & 0xff;
find_reg(address + 1).value = value & 0xff;
}
void set24(uint16_t address, uint32_t value)
{
find_reg(address).value = (value >> 16) & 0xff;
find_reg(address + 1).value = (value >> 8) & 0xff;
find_reg(address + 2).value = value & 0xff;
}
uint8_t get8(uint16_t address) const
{
return find_reg(address).value;
}
uint16_t get16(uint16_t address) const
{
return (find_reg(address).value << 8) | find_reg(address + 1).value;
}
uint32_t get24(uint16_t address) const
{
return (find_reg(address).value << 16) |
(find_reg(address + 1).value << 8) |
find_reg(address + 2).value;
}
void clear() { registers_.clear(); }
size_t size() const { return registers_.size(); }
iterator begin() { return registers_.begin(); }
const_iterator begin() const { return registers_.begin(); }
iterator end() { return registers_.end(); }
const_iterator end() const { return registers_.end(); }
private:
int find_reg_index(uint16_t address) const
{
if (!sorted_) {
for (size_t i = 0; i < registers_.size(); i++) {
if (registers_[i].address == address) {
return i;
}
}
return -1;
}
GenesysRegister search;
search.address = address;
auto it = std::lower_bound(registers_.begin(), registers_.end(), search);
if (it == registers_.end())
return -1;
if (it->address != address)
return -1;
return std::distance(registers_.begin(), it);
}
// registers are stored in a sorted vector
bool sorted_ = true;
std::vector<GenesysRegister> registers_;
};
struct GenesysRegisterSetting
{
GenesysRegisterSetting() = default;
GenesysRegisterSetting(uint16_t p_address, uint8_t p_value) :
address(p_address), value(p_value)
{}
GenesysRegisterSetting(uint16_t p_address, uint8_t p_value, uint8_t p_mask) :
address(p_address), value(p_value), mask(p_mask)
{}
uint16_t address = 0;
uint8_t value = 0;
uint8_t mask = 0xff;
bool operator==(const GenesysRegisterSetting& other) const
{
return address == other.address && value == other.value && mask == other.mask;
}
};
template<class Stream>
void serialize(Stream& str, GenesysRegisterSetting& reg)
{
serialize(str, reg.address);
serialize(str, reg.value);
serialize(str, reg.mask);
}
class GenesysRegisterSettingSet
{
public:
using container = std::vector<GenesysRegisterSetting>;
using iterator = typename container::iterator;
using const_iterator = typename container::const_iterator;
GenesysRegisterSettingSet() = default;
GenesysRegisterSettingSet(std::initializer_list<GenesysRegisterSetting> ilist) : regs_(ilist) {}
iterator begin() { return regs_.begin(); }
const_iterator begin() const { return regs_.begin(); }
iterator end() { return regs_.end(); }
const_iterator end() const { return regs_.end(); }
GenesysRegisterSetting& operator[](size_t i) { return regs_[i]; }
const GenesysRegisterSetting& operator[](size_t i) const { return regs_[i]; }
size_t size() const { return regs_.size(); }
bool empty() const { return regs_.empty(); }
void clear() { regs_.clear(); }
void push_back(GenesysRegisterSetting reg) { regs_.push_back(reg); }
void merge(const GenesysRegisterSettingSet& other)
{
for (const auto& reg : other) {
set_value(reg.address, reg.value);
}
}
uint8_t get_value(uint16_t address) const
{
for (const auto& reg : regs_) {
if (reg.address == address)
return reg.value;
}
throw std::runtime_error("Unknown register");
}
void set_value(uint16_t address, uint8_t value)
{
for (auto& reg : regs_) {
if (reg.address == address) {
reg.value = value;
return;
}
}
push_back(GenesysRegisterSetting(address, value));
}
friend void serialize(std::istream& str, GenesysRegisterSettingSet& reg);
friend void serialize(std::ostream& str, GenesysRegisterSettingSet& reg);
bool operator==(const GenesysRegisterSettingSet& other) const
{
return regs_ == other.regs_;
}
private:
std::vector<GenesysRegisterSetting> regs_;
};
inline void serialize(std::istream& str, GenesysRegisterSettingSet& reg)
{
reg.clear();
const size_t max_register_address =
1 << (sizeof(GenesysRegisterSetting::address) * CHAR_BIT);
serialize(str, reg.regs_, max_register_address);
}
inline void serialize(std::ostream& str, GenesysRegisterSettingSet& reg)
{
serialize(str, reg.regs_);
}
#endif // BACKEND_GENESYS_REGISTER_H

Wyświetl plik

@ -0,0 +1,268 @@
/* sane - Scanner Access Now Easy.
Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt>
This file is part of the SANE package.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA.
As a special exception, the authors of SANE give permission for
additional uses of the libraries contained in this release of SANE.
The exception is that, if you link a SANE library with other files
to produce an executable, this does not by itself cause the
resulting executable to be covered by the GNU General Public
License. Your use of that executable is in no way restricted on
account of linking the SANE library code into it.
This exception does not, however, invalidate any other reasons why
the executable file might be covered by the GNU General Public
License.
If you submit changes to SANE to the maintainers to be included in
a subsequent release, you agree by submitting the changes that
those changes may be distributed with this exception intact.
If you write modifications of your own for SANE, it is your choice
whether to permit this exception to apply to your modifications.
If you do not wish that, delete this exception notice.
*/
#ifndef BACKEND_GENESYS_SENSOR_H
#define BACKEND_GENESYS_SENSOR_H
#include "genesys_enums.h"
#include "genesys_register.h"
#include "genesys_serialize.h"
#include <array>
#include <functional>
template<class T, size_t Size>
struct AssignableArray : public std::array<T, Size> {
AssignableArray() = default;
AssignableArray(const AssignableArray&) = default;
AssignableArray& operator=(const AssignableArray&) = default;
AssignableArray& operator=(std::initializer_list<T> init)
{
if (init.size() != std::array<T, Size>::size())
throw std::runtime_error("An array of incorrect size assigned");
std::copy(init.begin(), init.end(), std::array<T, Size>::begin());
return *this;
}
};
struct GenesysFrontendLayout
{
std::array<uint16_t, 3> offset_addr = {};
std::array<uint16_t, 3> gain_addr = {};
bool operator==(const GenesysFrontendLayout& other) const
{
return offset_addr == other.offset_addr && gain_addr == other.gain_addr;
}
};
/** @brief Data structure to set up analog frontend.
The analog frontend converts analog value from image sensor to digital value. It has its own
control registers which are set up with this structure. The values are written using
sanei_genesys_fe_write_data.
*/
struct Genesys_Frontend
{
Genesys_Frontend() = default;
// id of the frontend description
uint8_t fe_id = 0;
// all registers of the frontend
GenesysRegisterSettingSet regs;
// extra control registers
std::array<uint8_t, 3> reg2 = {};
GenesysFrontendLayout layout;
void set_offset(unsigned which, uint8_t value)
{
regs.set_value(layout.offset_addr[which], value);
}
void set_gain(unsigned which, uint8_t value)
{
regs.set_value(layout.gain_addr[which], value);
}
uint8_t get_offset(unsigned which) const
{
return regs.get_value(layout.offset_addr[which]);
}
uint8_t get_gain(unsigned which) const
{
return regs.get_value(layout.gain_addr[which]);
}
bool operator==(const Genesys_Frontend& other) const
{
return fe_id == other.fe_id &&
regs == other.regs &&
reg2 == other.reg2 &&
layout == other.layout;
}
};
template<class Stream>
void serialize(Stream& str, Genesys_Frontend& x)
{
serialize(str, x.fe_id);
serialize_newline(str);
serialize(str, x.regs);
serialize_newline(str);
serialize(str, x.reg2);
serialize_newline(str);
serialize(str, x.layout.offset_addr);
serialize(str, x.layout.gain_addr);
}
struct SensorExposure {
uint16_t red, green, blue;
};
struct Genesys_Sensor {
Genesys_Sensor() = default;
~Genesys_Sensor() = default;
// id of the sensor description
uint8_t sensor_id = 0;
// sensor resolution in CCD pixels. Note that we may read more than one CCD pixel per logical
// pixel, see ccd_pixels_per_system_pixel()
int optical_res = 0;
// the minimum and maximum resolution this sensor is usable at. -1 means that the resolution
// can be any.
int min_resolution = -1;
int max_resolution = -1;
// the scan method used with the sensor
ScanMethod method = ScanMethod::FLATBED;
// CCD may present itself as half or quarter-size CCD on certain resolutions
int ccd_size_divisor = 1;
int black_pixels = 0;
// value of the dummy register
int dummy_pixel = 0;
// last pixel of CCD margin at optical resolution
int CCD_start_xoffset = 0;
// total pixels used by the sensor
int sensor_pixels = 0;
// TA CCD target code (reference gain)
int fau_gain_white_ref = 0;
// CCD target code (reference gain)
int gain_white_ref = 0;
// red, green and blue initial exposure values
SensorExposure exposure;
int exposure_lperiod = -1;
GenesysRegisterSettingSet custom_regs;
GenesysRegisterSettingSet custom_fe_regs;
// 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;
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); }
int get_ccd_size_divisor_for_dpi(int xres) const
{
if (ccd_size_divisor >= 4 && xres * 4 <= optical_res) {
return 4;
}
if (ccd_size_divisor >= 2 && xres * 2 <= optical_res) {
return 2;
}
return 1;
}
// how many CCD pixels are processed per system pixel time. This corresponds to CKSEL + 1
unsigned ccd_pixels_per_system_pixel() const
{
// same on GL646, GL841, GL843, GL846, GL847, GL124
constexpr unsigned REG_0x18_CKSEL = 0x03;
return (custom_regs.get_value(0x18) & REG_0x18_CKSEL) + 1;
}
bool operator==(const Genesys_Sensor& other) const
{
return sensor_id == other.sensor_id &&
optical_res == other.optical_res &&
min_resolution == other.min_resolution &&
max_resolution == other.max_resolution &&
method == other.method &&
ccd_size_divisor == other.ccd_size_divisor &&
black_pixels == other.black_pixels &&
dummy_pixel == other.dummy_pixel &&
CCD_start_xoffset == other.CCD_start_xoffset &&
sensor_pixels == other.sensor_pixels &&
fau_gain_white_ref == other.fau_gain_white_ref &&
gain_white_ref == other.gain_white_ref &&
exposure.blue == other.exposure.blue &&
exposure.green == other.exposure.green &&
exposure.red == other.exposure.red &&
exposure_lperiod == other.exposure_lperiod &&
custom_regs == other.custom_regs &&
custom_fe_regs == other.custom_fe_regs &&
gamma == other.gamma;
}
};
template<class Stream>
void serialize(Stream& str, Genesys_Sensor& x)
{
serialize(str, x.sensor_id);
serialize(str, x.optical_res);
serialize(str, x.min_resolution);
serialize(str, x.max_resolution);
serialize(str, x.method);
serialize(str, x.ccd_size_divisor);
serialize(str, x.black_pixels);
serialize(str, x.dummy_pixel);
serialize(str, x.CCD_start_xoffset);
serialize(str, x.sensor_pixels);
serialize(str, x.fau_gain_white_ref);
serialize(str, x.gain_white_ref);
serialize_newline(str);
serialize(str, x.exposure.blue);
serialize(str, x.exposure.green);
serialize(str, x.exposure.red);
serialize(str, x.exposure_lperiod);
serialize_newline(str);
serialize(str, x.custom_regs);
serialize_newline(str);
serialize(str, x.custom_fe_regs);
serialize_newline(str);
serialize(str, x.gamma);
}
#endif //

Wyświetl plik

@ -0,0 +1,236 @@
/* sane - Scanner Access Now Easy.
Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt>
This file is part of the SANE package.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA.
As a special exception, the authors of SANE give permission for
additional uses of the libraries contained in this release of SANE.
The exception is that, if you link a SANE library with other files
to produce an executable, this does not by itself cause the
resulting executable to be covered by the GNU General Public
License. Your use of that executable is in no way restricted on
account of linking the SANE library code into it.
This exception does not, however, invalidate any other reasons why
the executable file might be covered by the GNU General Public
License.
If you submit changes to SANE to the maintainers to be included in
a subsequent release, you agree by submitting the changes that
those changes may be distributed with this exception intact.
If you write modifications of your own for SANE, it is your choice
whether to permit this exception to apply to your modifications.
If you do not wish that, delete this exception notice.
*/
#ifndef BACKEND_GENESYS_SETTINGS_H
#define BACKEND_GENESYS_SETTINGS_H
#include "genesys_enums.h"
#include "genesys_serialize.h"
struct Genesys_Settings
{
ScanMethod scan_method = ScanMethod::FLATBED;
ScanColorMode scan_mode = ScanColorMode::LINEART;
// horizontal dpi
int xres = 0;
// vertical dpi
int yres = 0;
//x start on scan table in mm
double tl_x = 0;
// y start on scan table in mm
double tl_y = 0;
// number of lines at scan resolution
unsigned int lines = 0;
// number of pixels at scan resolution
unsigned int pixels = 0;
// bit depth of the scan
unsigned int depth = 0;
ColorFilter color_filter = ColorFilter::NONE;
// true if scan is true gray, false if monochrome scan
int true_gray = 0;
// lineart threshold
int threshold = 0;
// lineart threshold curve for dynamic rasterization
int threshold_curve = 0;
// Disable interpolation for xres<yres
int disable_interpolation = 0;
// true is lineart is generated from gray data by the dynamic rasterization algoright
int dynamic_lineart = 0;
// value for contrast enhancement in the [-100..100] range
int contrast = 0;
// value for brightness enhancement in the [-100..100] range
int brightness = 0;
// cache entries expiration time
int expiration_time = 0;
};
struct SetupParams {
static constexpr unsigned NOT_SET = std::numeric_limits<unsigned>::max();
// resolution in x direction
unsigned xres = NOT_SET;
// resolution in y direction
unsigned yres = NOT_SET;
// start pixel in X direction, from dummy_pixel + 1
float startx = -1;
// start pixel in Y direction, counted according to base_ydpi
float starty = -1;
// the number of pixels in X direction. Note that each logical pixel may correspond to more
// than one CCD pixel, see CKSEL and GenesysSensor::ccd_pixels_per_system_pixel()
unsigned pixels = NOT_SET;
// the number of pixels in Y direction
unsigned lines = NOT_SET;
// the depth of the scan in bits. Allowed are 1, 8, 16
unsigned depth = NOT_SET;
// the number of channels
unsigned channels = NOT_SET;
ScanMethod scan_method = static_cast<ScanMethod>(NOT_SET);
ScanColorMode scan_mode = static_cast<ScanColorMode>(NOT_SET);
ColorFilter color_filter = static_cast<ColorFilter>(NOT_SET);
unsigned flags = NOT_SET;
void assert_valid() const
{
if (xres == NOT_SET || yres == NOT_SET || startx < 0 || starty < 0 ||
pixels == NOT_SET || lines == NOT_SET ||depth == NOT_SET || channels == NOT_SET ||
scan_method == static_cast<ScanMethod>(NOT_SET) ||
scan_mode == static_cast<ScanColorMode>(NOT_SET) ||
color_filter == static_cast<ColorFilter>(NOT_SET) ||
flags == NOT_SET)
{
throw std::runtime_error("SetupParams are not valid");
}
}
bool operator==(const SetupParams& other) const
{
return xres == other.xres &&
yres == other.yres &&
startx == other.startx &&
starty == other.starty &&
pixels == other.pixels &&
lines == other.lines &&
depth == other.depth &&
channels == other.channels &&
scan_method == other.scan_method &&
scan_mode == other.scan_mode &&
color_filter == other.color_filter &&
flags == other.flags;
}
};
template<class Stream>
void serialize(Stream& str, SetupParams& x)
{
serialize(str, x.xres);
serialize(str, x.yres);
serialize(str, x.startx);
serialize(str, x.starty);
serialize(str, x.pixels);
serialize(str, x.lines);
serialize(str, x.depth);
serialize(str, x.channels);
serialize(str, x.scan_method);
serialize(str, x.scan_mode);
serialize(str, x.color_filter);
serialize(str, x.flags);
}
struct Genesys_Current_Setup
{
// params used for this setup
SetupParams params;
// pixel count expected from scanner
int pixels = 0;
// line count expected from scanner
int lines = 0;
// depth expected from scanner
int depth = 0;
// channel count expected from scanner
int channels = 0;
// used exposure time
int exposure_time = 0;
// used xres
float xres = 0;
// used yres
float yres = 0;
// half ccd mode
unsigned ccd_size_divisor = 1;
SANE_Int stagger = 0;
// max shift of any ccd component, including staggered pixels
SANE_Int max_shift = 0;
bool operator==(const Genesys_Current_Setup& other) const
{
return params == other.params &&
pixels == other.pixels &&
lines == other.lines &&
depth == other.depth &&
channels == other.channels &&
exposure_time == other.exposure_time &&
xres == other.xres &&
yres == other.yres &&
ccd_size_divisor == other.ccd_size_divisor &&
stagger == other.stagger &&
max_shift == other.max_shift;
}
};
template<class Stream>
void serialize(Stream& str, Genesys_Current_Setup& x)
{
serialize(str, x.params);
serialize_newline(str);
serialize(str, x.pixels);
serialize(str, x.lines);
serialize(str, x.depth);
serialize(str, x.channels);
serialize(str, x.exposure_time);
serialize(str, x.xres);
serialize(str, x.yres);
serialize(str, x.ccd_size_divisor);
serialize(str, x.stagger);
serialize(str, x.max_shift);
}
#endif // BACKEND_GENESYS_SETTINGS_H