kopia lustrzana https://gitlab.com/sane-project/backends
Merge branch 'genesys-split-genesys-low' into 'master'
genesys: Split genesys_low.h into several files See merge request sane-project/backends!109merge-requests/110/head
commit
5bd9ab4941
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
@ -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
|
|
@ -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
|
|
@ -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 //
|
|
@ -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
|
Ładowanie…
Reference in New Issue