diff options
Diffstat (limited to 'backend/genesys_low.h')
-rw-r--r-- | backend/genesys_low.h | 2042 |
1 files changed, 0 insertions, 2042 deletions
diff --git a/backend/genesys_low.h b/backend/genesys_low.h deleted file mode 100644 index e750808..0000000 --- a/backend/genesys_low.h +++ /dev/null @@ -1,2042 +0,0 @@ -/* sane - Scanner Access Now Easy. - - Copyright (C) 2003 Oliver Rauch - Copyright (C) 2003, 2004 Henning Meier-Geinitz <henning@meier-geinitz.de> - Copyright (C) 2004, 2005 Gerhard Jaeger <gerhard@gjaeger.de> - Copyright (C) 2004-2013 Stéphane Voltz <stef.dev@free.fr> - Copyright (C) 2005-2009 Pierre Willenbrock <pierre@pirsoft.dnsalias.org> - Copyright (C) 2006 Laurent Charpentier <laurent_pubs@yahoo.com> - Parts of the structs have been taken from the gt68xx backend by - Sergey Vlasov <vsu@altlinux.ru> et al. - - 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 GENESYS_LOW_H -#define GENESYS_LOW_H - - -#include "../include/sane/config.h" - -#include <errno.h> -#include <string.h> -#include <stdlib.h> -#include <stdio.h> -#include <unistd.h> -#include <math.h> -#include <stddef.h> -#ifdef HAVE_SYS_TIME_H -#include <sys/time.h> -#endif -#ifdef HAVE_SYS_TYPES_H -#include <sys/types.h> -#endif -#ifdef HAVE_MKDIR -#include <sys/stat.h> -#include <sys/types.h> -#endif - -#include "../include/sane/sane.h" -#include "../include/sane/sanei.h" -#include "../include/sane/saneopts.h" - -#include "../include/sane/sanei_backend.h" -#include "../include/sane/sanei_usb.h" - -#include "../include/_stdint.h" - -#include "genesys_error.h" -#include "genesys_sanei.h" -#include "genesys_serialize.h" - -#include <algorithm> -#include <array> -#include <cstring> -#include <functional> -#include <iostream> -#include <limits> -#include <memory> -#include <stdexcept> -#include <string> -#include <vector> - -#define FREE_IFNOT_NULL(x) if(x!=NULL) { free(x); x=NULL;} - -#define GENESYS_RED 0 -#define GENESYS_GREEN 1 -#define GENESYS_BLUE 2 - -/* Flags */ -#define GENESYS_FLAG_UNTESTED (1 << 0) /**< Print a warning for these scanners */ -#define GENESYS_FLAG_14BIT_GAMMA (1 << 1) /**< use 14bit Gamma table instead of 12 */ -#define GENESYS_FLAG_LAZY_INIT (1 << 2) /**< skip extensive ASIC test at init */ -#define GENESYS_FLAG_XPA (1 << 3) -#define GENESYS_FLAG_SKIP_WARMUP (1 << 4) /**< skip genesys_warmup() */ -/** @brief offset calibration flag - * signals that the scanner does offset calibration. In this case off_calibration() and - * coarse_gain_calibration() functions must be implemented - */ -#define GENESYS_FLAG_OFFSET_CALIBRATION (1 << 5) -#define GENESYS_FLAG_SEARCH_START (1 << 6) /**< do start search before scanning */ -#define GENESYS_FLAG_REPARK (1 << 7) /**< repark head (and check for lock) by - moving without scanning */ -#define GENESYS_FLAG_DARK_CALIBRATION (1 << 8) /**< do dark calibration */ -#define GENESYS_FLAG_STAGGERED_LINE (1 << 9) /**< pixel columns are shifted vertically for hi-res modes */ - -#define GENESYS_FLAG_MUST_WAIT (1 << 10) /**< tells wether the scanner must wait for the head when parking */ - - -#define GENESYS_FLAG_HAS_UTA (1 << 11) /**< scanner has a transparency adapter */ - -#define GENESYS_FLAG_DARK_WHITE_CALIBRATION (1 << 12) /**< yet another calibration method. does white and dark shading in one run, depending on a black and a white strip*/ -#define GENESYS_FLAG_CUSTOM_GAMMA (1 << 13) /**< allow custom gamma tables */ -#define GENESYS_FLAG_NO_CALIBRATION (1 << 14) /**< allow scanners to use skip the calibration, needed for sheetfed scanners */ -#define GENESYS_FLAG_SIS_SENSOR (1 << 16) /**< handling of multi-segments sensors in software */ -#define GENESYS_FLAG_SHADING_NO_MOVE (1 << 17) /**< scanner doesn't move sensor during shading calibration */ -#define GENESYS_FLAG_SHADING_REPARK (1 << 18) /**< repark head between shading scans */ -#define GENESYS_FLAG_FULL_HWDPI_MODE (1 << 19) /**< scanner always use maximum hw dpi to setup the sensor */ -// scanner has infrared transparency scanning capability -#define GENESYS_FLAG_HAS_UTA_INFRARED (1 << 20) - -#define GENESYS_HAS_NO_BUTTONS 0 /**< scanner has no supported button */ -#define GENESYS_HAS_SCAN_SW (1 << 0) /**< scanner has SCAN button */ -#define GENESYS_HAS_FILE_SW (1 << 1) /**< scanner has FILE button */ -#define GENESYS_HAS_COPY_SW (1 << 2) /**< scanner has COPY button */ -#define GENESYS_HAS_EMAIL_SW (1 << 3) /**< scanner has EMAIL button */ -#define GENESYS_HAS_PAGE_LOADED_SW (1 << 4) /**< scanner has paper in detection */ -#define GENESYS_HAS_OCR_SW (1 << 5) /**< scanner has OCR button */ -#define GENESYS_HAS_POWER_SW (1 << 6) /**< scanner has power button */ -#define GENESYS_HAS_CALIBRATE (1 << 7) /**< scanner has 'calibrate' software button to start calibration */ -#define GENESYS_HAS_EXTRA_SW (1 << 8) /**< scanner has extra function button */ - -/* USB control message values */ -#define REQUEST_TYPE_IN (USB_TYPE_VENDOR | USB_DIR_IN) -#define REQUEST_TYPE_OUT (USB_TYPE_VENDOR | USB_DIR_OUT) -#define REQUEST_REGISTER 0x0c -#define REQUEST_BUFFER 0x04 -#define VALUE_BUFFER 0x82 -#define VALUE_SET_REGISTER 0x83 -#define VALUE_READ_REGISTER 0x84 -#define VALUE_WRITE_REGISTER 0x85 -#define VALUE_INIT 0x87 -#define GPIO_OUTPUT_ENABLE 0x89 -#define GPIO_READ 0x8a -#define GPIO_WRITE 0x8b -#define VALUE_BUF_ENDACCESS 0x8c -#define VALUE_GET_REGISTER 0x8e -#define INDEX 0x00 - -/* todo: used? -#define VALUE_READ_STATUS 0x86 -*/ - -/* Read/write bulk data/registers */ -#define BULK_OUT 0x01 -#define BULK_IN 0x00 -#define BULK_RAM 0x00 -#define BULK_REGISTER 0x11 - -#define BULKOUT_MAXSIZE 0xF000 - -/* AFE values */ -#define AFE_INIT 1 -#define AFE_SET 2 -#define AFE_POWER_SAVE 4 - -#define LOWORD(x) ((uint16_t)((x) & 0xffff)) -#define HIWORD(x) ((uint16_t)((x) >> 16)) -#define LOBYTE(x) ((uint8_t)((x) & 0xFF)) -#define HIBYTE(x) ((uint8_t)((x) >> 8)) - -/* Global constants */ -/* TODO: emove this leftover of early backend days */ -#define MOTOR_SPEED_MAX 350 -#define DARK_VALUE 0 - -#define PWRBIT 0x80 -#define BUFEMPTY 0x40 -#define FEEDFSH 0x20 -#define SCANFSH 0x10 -#define HOMESNR 0x08 -#define LAMPSTS 0x04 -#define FEBUSY 0x02 -#define MOTORENB 0x01 - -#define GENESYS_MAX_REGS 256 - -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); -} - -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: - 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(GENESYS_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_; -}; - -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 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_); -} - -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; - 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; - - 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; - } - - 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); -} - -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_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; -}; - -typedef enum Genesys_Color_Order -{ - COLOR_ORDER_RGB, - COLOR_ORDER_BGR -} -Genesys_Color_Order; - - -#define MAX_RESOLUTIONS 13 -#define MAX_DPI 4 - -#define GENESYS_GL646 646 -#define GENESYS_GL841 841 -#define GENESYS_GL843 843 -#define GENESYS_GL845 845 -#define GENESYS_GL846 846 -#define GENESYS_GL847 847 -#define GENESYS_GL848 848 -#define GENESYS_GL123 123 -#define GENESYS_GL124 124 - -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_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_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_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 -}; - -/* Forward typedefs */ -typedef struct Genesys_Device Genesys_Device; -struct Genesys_Scanner; -typedef struct Genesys_Calibration_Cache Genesys_Calibration_Cache; - -/** - * Scanner command set description. - * - * This description contains parts which are common to all scanners with the - * same command set, but may have different optical resolution and other - * parameters. - */ -typedef struct Genesys_Command_Set -{ - /** @name Identification */ - /*@{ */ - - /** Name of this command set */ - SANE_String_Const name; - - /*@} */ - - bool (*needs_home_before_init_regs_for_scan) (Genesys_Device* dev); - - /** For ASIC initialization */ - SANE_Status (*init) (Genesys_Device * dev); - - SANE_Status (*init_regs_for_warmup) (Genesys_Device * dev, - const Genesys_Sensor& sensor, - Genesys_Register_Set * regs, - int *channels, int *total_size); - SANE_Status (*init_regs_for_coarse_calibration) (Genesys_Device * dev, - const Genesys_Sensor& sensor, - Genesys_Register_Set& regs); - SANE_Status (*init_regs_for_shading) (Genesys_Device * dev, const Genesys_Sensor& sensor, - Genesys_Register_Set& regs); - SANE_Status (*init_regs_for_scan) (Genesys_Device * dev, const Genesys_Sensor& sensor); - - SANE_Bool (*get_filter_bit) (Genesys_Register_Set * reg); - SANE_Bool (*get_lineart_bit) (Genesys_Register_Set * reg); - SANE_Bool (*get_bitset_bit) (Genesys_Register_Set * reg); - SANE_Bool (*get_gain4_bit) (Genesys_Register_Set * reg); - SANE_Bool (*get_fast_feed_bit) (Genesys_Register_Set * reg); - - SANE_Bool (*test_buffer_empty_bit) (SANE_Byte val); - SANE_Bool (*test_motor_flag_bit) (SANE_Byte val); - - SANE_Status (*set_fe) (Genesys_Device * dev, const Genesys_Sensor& sensor, uint8_t set); - SANE_Status (*set_powersaving) (Genesys_Device * dev, int delay); - SANE_Status (*save_power) (Genesys_Device * dev, SANE_Bool enable); - - SANE_Status (*begin_scan) (Genesys_Device * dev, - const Genesys_Sensor& sensor, - Genesys_Register_Set * regs, - SANE_Bool start_motor); - SANE_Status (*end_scan) (Genesys_Device * dev, - Genesys_Register_Set * regs, - SANE_Bool check_stop); - - /** - * Send gamma tables to ASIC - */ - SANE_Status (*send_gamma_table) (Genesys_Device * dev, const Genesys_Sensor& sensor); - - SANE_Status (*search_start_position) (Genesys_Device * dev); - SANE_Status (*offset_calibration) (Genesys_Device * dev, const Genesys_Sensor& sensor, - Genesys_Register_Set& regs); - SANE_Status (*coarse_gain_calibration) (Genesys_Device * dev, - const Genesys_Sensor& sensor, - Genesys_Register_Set& regs, int dpi); - SANE_Status (*led_calibration) (Genesys_Device * dev, Genesys_Sensor& sensor, - Genesys_Register_Set& regs); - - void (*wait_for_motor_stop) (Genesys_Device* dev); - SANE_Status (*slow_back_home) (Genesys_Device * dev, SANE_Bool wait_until_home); - SANE_Status (*rewind) (Genesys_Device * dev); - - SANE_Status (*bulk_write_register) (Genesys_Device * dev, - Genesys_Register_Set& regs); - - SANE_Status (*bulk_write_data) (Genesys_Device * dev, uint8_t addr, - uint8_t * data, size_t len); - - SANE_Status (*bulk_read_data) (Genesys_Device * dev, uint8_t addr, - uint8_t * data, size_t len); - - // Updates hardware sensor information in Genesys_Scanner.val[]. - SANE_Status (*update_hardware_sensors) (struct Genesys_Scanner * s); - - /* functions for sheetfed scanners */ - /** - * load document into scanner - */ - SANE_Status (*load_document) (Genesys_Device * dev); - /** - * detects is the scanned document has left scanner. In this - * case it updates the amount of data to read and set up - * flags in the dev struct - */ - SANE_Status (*detect_document_end) (Genesys_Device * dev); - /** - * eject document from scanner - */ - SANE_Status (*eject_document) (Genesys_Device * dev); - /** - * search for an black or white area in forward or reverse - * direction */ - SANE_Status (*search_strip) (Genesys_Device * dev, const Genesys_Sensor& sensor, - SANE_Bool forward, SANE_Bool black); - - bool (*is_compatible_calibration) (Genesys_Device* dev, const Genesys_Sensor& sensor, - Genesys_Calibration_Cache* cache, SANE_Bool for_overwrite); - - /* functions for transparency adapter */ - /** - * move scanning head to transparency adapter - */ - SANE_Status (*move_to_ta) (Genesys_Device * dev); - - /** - * write shading data calibration to ASIC - */ - SANE_Status (*send_shading_data) (Genesys_Device * dev, const Genesys_Sensor& sensor, - uint8_t * data, int size); - - // calculate current scan setup - void (*calculate_current_setup) (Genesys_Device * dev, const Genesys_Sensor& sensor); - - /** - * cold boot init function - */ - SANE_Status (*asic_boot) (Genesys_Device * dev, SANE_Bool cold); - -} 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. - */ -typedef struct Genesys_Model -{ - SANE_String_Const name; - SANE_String_Const vendor; - SANE_String_Const model; - SANE_Int model_id; - - SANE_Int asic_type; /* ASIC type gl646 or gl841 */ - Genesys_Command_Set *cmd_set; /* pointers to low level functions */ - - SANE_Int xdpi_values[MAX_RESOLUTIONS]; /* possible x resolutions */ - SANE_Int ydpi_values[MAX_RESOLUTIONS]; /* possible y resolutions */ - SANE_Int bpp_gray_values[MAX_DPI]; /* possible depths in gray mode */ - SANE_Int bpp_color_values[MAX_DPI]; /* possible depths in color mode */ - - SANE_Fixed x_offset; /* Start of scan area in mm */ - SANE_Fixed y_offset; /* Start of scan area in mm (Amount of - feeding needed to get to the medium) */ - SANE_Fixed x_size; /* Size of scan area in mm */ - SANE_Fixed y_size; /* Size of scan area in mm */ - - SANE_Fixed y_offset_calib; /* Start of white strip in mm */ - SANE_Fixed x_offset_mark; /* Start of black mark in mm */ - - SANE_Fixed x_offset_ta; /* Start of scan area in TA mode in mm */ - SANE_Fixed y_offset_ta; /* Start of scan area in TA mode in mm */ - SANE_Fixed x_size_ta; /* Size of scan area in TA mode in mm */ - SANE_Fixed y_size_ta; /* Size of scan area in TA mode in mm */ - - SANE_Fixed y_offset_calib_ta; /* Start of white strip in TA mode in mm */ - - SANE_Fixed post_scan; /* Size of scan area after paper sensor stops - sensing document in mm */ - SANE_Fixed eject_feed; /* Amount of feeding needed to eject document - after finishing scanning in mm */ - - /* Line-distance correction (in pixel at optical_ydpi) for CCD scanners */ - SANE_Int ld_shift_r; /* red */ - SANE_Int ld_shift_g; /* green */ - SANE_Int ld_shift_b; /* blue */ - - Genesys_Color_Order line_mode_color_order; /* Order of the CCD/CIS colors */ - - SANE_Bool is_cis; /* Is this a CIS or CCD scanner? */ - SANE_Bool is_sheetfed; /* Is this sheetfed scanner? */ - - SANE_Int ccd_type; /* which SENSOR type do we have ? */ - SANE_Int dac_type; /* which DAC do we have ? */ - SANE_Int gpo_type; /* General purpose output type */ - SANE_Int motor_type; /* stepper motor type */ - SANE_Word flags; /* Which hacks are needed for this scanner? */ - SANE_Word buttons; /* Button flags, described existing buttons for the model */ - /*@} */ - SANE_Int shading_lines; /* how many lines are used for shading calibration */ - SANE_Int shading_ta_lines; // how many lines are used for shading calibration in TA mode - SANE_Int search_lines; /* how many lines are used to search start position */ -} Genesys_Model; - -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 - 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); -} - -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; -}; - -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); -} - -/** - * 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; - 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] = {}; - time_t init_date = 0; - - 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; - uint16_t dark[3] = {}; - - SANE_Bool already_initialized = 0; - SANE_Int scanhead_position_in_steps = 0; - SANE_Int lamp_off_time = 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; -}; - -typedef struct Genesys_USB_Device_Entry -{ - SANE_Word vendor; /**< USB vendor identifier */ - SANE_Word product; /**< USB product identifier */ - Genesys_Model *model; /**< Scanner model information */ -} Genesys_USB_Device_Entry; - -/** - * structure for motor database - */ -typedef struct { - int motor_type; /**< motor id */ - int exposure; /**< exposure for the slope table */ - int step_type; /**< default step type for given exposure */ - uint32_t *table; // 0-terminated slope table at full step (i.e. step_type == 0) -} Motor_Profile; - -#define FULL_STEP 0 -#define HALF_STEP 1 -#define QUARTER_STEP 2 -#define EIGHTH_STEP 3 - -#define SLOPE_TABLE_SIZE 1024 - -#define SCAN_TABLE 0 /* table 1 at 0x4000 for gl124 */ -#define BACKTRACK_TABLE 1 /* table 2 at 0x4800 for gl124 */ -#define STOP_TABLE 2 /* table 3 at 0x5000 for gl124 */ -#define FAST_TABLE 3 /* table 4 at 0x5800 for gl124 */ -#define HOME_TABLE 4 /* table 5 at 0x6000 for gl124 */ - -#define SCAN_FLAG_SINGLE_LINE 0x001 -#define SCAN_FLAG_DISABLE_SHADING 0x002 -#define SCAN_FLAG_DISABLE_GAMMA 0x004 -#define SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE 0x008 -#define SCAN_FLAG_IGNORE_LINE_DISTANCE 0x010 -#define SCAN_FLAG_USE_OPTICAL_RES 0x020 -#define SCAN_FLAG_DISABLE_LAMP 0x040 -#define SCAN_FLAG_DYNAMIC_LINEART 0x080 -#define SCAN_FLAG_CALIBRATION 0x100 -#define SCAN_FLAG_FEEDING 0x200 -#define SCAN_FLAG_USE_XPA 0x400 -#define SCAN_FLAG_ENABLE_LEDADD 0x800 -#define MOTOR_FLAG_AUTO_GO_HOME 0x01 -#define MOTOR_FLAG_DISABLE_BUFFER_FULL_MOVE 0x02 -#define MOTOR_FLAG_FEED 0x04 -#define MOTOR_FLAG_USE_XPA 0x08 - -/** @name "Optical flags" */ -/*@{ optical flags available when setting up sensor for scan */ - -#define OPTICAL_FLAG_DISABLE_GAMMA 0x01 /**< disable gamma correction */ -#define OPTICAL_FLAG_DISABLE_SHADING 0x02 /**< disable shading correction */ -#define OPTICAL_FLAG_DISABLE_LAMP 0x04 /**< turn off lamp */ -#define OPTICAL_FLAG_ENABLE_LEDADD 0x08 /**< enable true CIS gray by enabling LED addition */ -#define OPTICAL_FLAG_DISABLE_DOUBLE 0x10 /**< disable automatic x-direction double data expansion */ -#define OPTICAL_FLAG_STAGGER 0x20 /**< disable stagger correction */ -#define OPTICAL_FLAG_USE_XPA 0x40 /**< use XPA lamp rather than regular one */ - -/*@} */ - -/*--------------------------------------------------------------------------*/ -/* common functions needed by low level specific functions */ -/*--------------------------------------------------------------------------*/ - -inline GenesysRegister* sanei_genesys_get_address(Genesys_Register_Set* regs, uint16_t addr) -{ - auto* ret = regs->find_reg_address(addr); - if (ret == nullptr) { - DBG(DBG_error, "%s: failed to find address for register 0x%02x, crash expected !\n", - __func__, addr); - } - return ret; -} - -inline uint8_t sanei_genesys_read_reg_from_set(Genesys_Register_Set* regs, uint16_t address) -{ - return regs->get8(address); -} - -inline void sanei_genesys_set_reg_from_set(Genesys_Register_Set* regs, uint16_t address, - uint8_t value) -{ - regs->set8(address, value); -} - -extern SANE_Status sanei_genesys_init_cmd_set (Genesys_Device * dev); - -extern SANE_Status -sanei_genesys_read_register (Genesys_Device * dev, uint16_t reg, uint8_t * val); - -extern SANE_Status -sanei_genesys_write_register (Genesys_Device * dev, uint16_t reg, uint8_t val); - -extern SANE_Status -sanei_genesys_read_hregister (Genesys_Device * dev, uint16_t reg, uint8_t * val); - -extern SANE_Status -sanei_genesys_write_hregister (Genesys_Device * dev, uint16_t reg, uint8_t val); - -extern SANE_Status -sanei_genesys_bulk_write_register(Genesys_Device * dev, - Genesys_Register_Set& regs); - -extern SANE_Status sanei_genesys_write_0x8c (Genesys_Device * dev, uint8_t index, uint8_t val); - -extern unsigned sanei_genesys_get_bulk_max_size(Genesys_Device * dev); - -extern SANE_Status sanei_genesys_bulk_read_data(Genesys_Device * dev, uint8_t addr, uint8_t* data, - size_t len); - -extern SANE_Status sanei_genesys_bulk_write_data(Genesys_Device * dev, uint8_t addr, uint8_t* data, - size_t len); - -extern SANE_Status sanei_genesys_get_status (Genesys_Device * dev, uint8_t * status); - -extern void sanei_genesys_print_status (uint8_t val); - -extern SANE_Status -sanei_genesys_write_ahb(Genesys_Device* dev, uint32_t addr, uint32_t size, uint8_t * data); - -extern void sanei_genesys_init_structs (Genesys_Device * dev); - -const Genesys_Sensor& sanei_genesys_find_sensor_any(Genesys_Device* dev); -Genesys_Sensor& sanei_genesys_find_sensor_any_for_write(Genesys_Device* dev); -const Genesys_Sensor& sanei_genesys_find_sensor(Genesys_Device* dev, int dpi, - ScanMethod scan_method = ScanMethod::FLATBED); -Genesys_Sensor& sanei_genesys_find_sensor_for_write(Genesys_Device* dev, int dpi, - ScanMethod scan_method = ScanMethod::FLATBED); - -extern SANE_Status -sanei_genesys_init_shading_data (Genesys_Device * dev, const Genesys_Sensor& sensor, - int pixels_per_line); - -extern SANE_Status sanei_genesys_read_valid_words (Genesys_Device * dev, - unsigned int *steps); - -extern SANE_Status sanei_genesys_read_scancnt (Genesys_Device * dev, - unsigned int *steps); - -extern SANE_Status sanei_genesys_read_feed_steps (Genesys_Device * dev, - unsigned int *steps); - -void sanei_genesys_set_lamp_power(Genesys_Device* dev, const Genesys_Sensor& sensor, - Genesys_Register_Set& regs, bool set); - -void sanei_genesys_set_motor_power(Genesys_Register_Set& regs, bool set); - -extern void -sanei_genesys_calculate_zmode2 (SANE_Bool two_table, - uint32_t exposure_time, - uint16_t * slope_table, - int reg21, - int move, int reg22, uint32_t * z1, - uint32_t * z2); - -extern void -sanei_genesys_calculate_zmode (uint32_t exposure_time, - uint32_t steps_sum, - uint16_t last_speed, uint32_t feedl, - uint8_t fastfed, uint8_t scanfed, - uint8_t fwdstep, uint8_t tgtime, - uint32_t * z1, uint32_t * z2); - -extern SANE_Status -sanei_genesys_set_buffer_address (Genesys_Device * dev, uint32_t addr); - -/** @brief Reads data from frontend register. - * Reads data from the given frontend register. May be used to query - * analog frontend status by reading the right register. - */ -extern SANE_Status -sanei_genesys_fe_read_data (Genesys_Device * dev, uint8_t addr, - uint16_t *data); -/** @brief Write data to frontend register. - * Writes data to analog frontend register at the given address. - * The use and address of registers change from model to model. - */ -extern SANE_Status -sanei_genesys_fe_write_data (Genesys_Device * dev, uint8_t addr, - uint16_t data); - -extern SANE_Int -sanei_genesys_exposure_time2 (Genesys_Device * dev, - float ydpi, int step_type, int endpixel, - int led_exposure, int power_mode); - -extern SANE_Int -sanei_genesys_exposure_time (Genesys_Device * dev, Genesys_Register_Set * reg, - int xdpi); -extern SANE_Int -sanei_genesys_generate_slope_table (uint16_t * slope_table, unsigned int max_steps, - unsigned int use_steps, uint16_t stop_at, - uint16_t vstart, uint16_t vend, - unsigned int steps, double g, - unsigned int *used_steps, unsigned int *vfinal); - -extern SANE_Int -sanei_genesys_create_slope_table (Genesys_Device * dev, - uint16_t * slope_table, int steps, - int step_type, int exposure_time, - SANE_Bool same_speed, double yres, - int power_mode); - -SANE_Int -sanei_genesys_create_slope_table3 (Genesys_Device * dev, - uint16_t * slope_table, int max_step, - unsigned int use_steps, - int step_type, int exposure_time, - double yres, - unsigned int *used_steps, - unsigned int *final_exposure, - int power_mode); - -void sanei_genesys_create_default_gamma_table(Genesys_Device* dev, - std::vector<uint16_t>& gamma_table, float gamma); - -std::vector<uint16_t> get_gamma_table(Genesys_Device* dev, const Genesys_Sensor& sensor, - int color); - -SANE_Status sanei_genesys_send_gamma_table(Genesys_Device * dev, const Genesys_Sensor& sensor); - -extern SANE_Status sanei_genesys_start_motor (Genesys_Device * dev); - -extern SANE_Status sanei_genesys_stop_motor (Genesys_Device * dev); - -extern SANE_Status -sanei_genesys_search_reference_point(Genesys_Device * dev, Genesys_Sensor& sensor, - uint8_t * data, - int start_pixel, int dpi, int width, - int height); - -extern SANE_Status sanei_genesys_write_file(const char *filename, uint8_t* data, size_t length); - -extern SANE_Status -sanei_genesys_write_pnm_file (const char *filename, uint8_t * data, int depth, - int channels, int pixels_per_line, int lines); - -extern SANE_Status -sanei_genesys_test_buffer_empty (Genesys_Device * dev, SANE_Bool * empty); - -extern SANE_Status -sanei_genesys_read_data_from_scanner (Genesys_Device * dev, uint8_t * data, - size_t size); - -inline void sanei_genesys_set_double(Genesys_Register_Set* regs, uint16_t addr, uint16_t value) -{ - regs->set16(addr, value); -} - -inline void sanei_genesys_set_triple(Genesys_Register_Set* regs, uint16_t addr, uint32_t value) -{ - regs->set24(addr, value); -} - -inline void sanei_genesys_get_double(Genesys_Register_Set* regs, uint16_t addr, uint16_t* value) -{ - *value = regs->get16(addr); -} - -inline void sanei_genesys_get_triple(Genesys_Register_Set* regs, uint16_t addr, uint32_t* value) -{ - *value = regs->get24(addr); -} - -inline void sanei_genesys_set_exposure(Genesys_Register_Set& regs, const SensorExposure& exposure) -{ - regs.set8(0x10, (exposure.red >> 8) & 0xff); - regs.set8(0x11, exposure.red & 0xff); - regs.set8(0x12, (exposure.green >> 8) & 0xff); - regs.set8(0x13, exposure.green & 0xff); - regs.set8(0x14, (exposure.blue >> 8) & 0xff); - regs.set8(0x15, exposure.blue & 0xff); -} - -inline uint16_t sanei_genesys_fixup_exposure_value(uint16_t value) -{ - if ((value & 0xff00) == 0) { - value |= 0x100; - } - if ((value & 0x00ff) == 0) { - value |= 0x1; - } - return value; -} - -inline SensorExposure sanei_genesys_fixup_exposure(SensorExposure exposure) -{ - exposure.red = sanei_genesys_fixup_exposure_value(exposure.red); - exposure.green = sanei_genesys_fixup_exposure_value(exposure.green); - exposure.blue = sanei_genesys_fixup_exposure_value(exposure.blue); - return exposure; -} - -extern SANE_Status -sanei_genesys_wait_for_home(Genesys_Device *dev); - -extern SANE_Status -sanei_genesys_asic_init(Genesys_Device *dev, SANE_Bool cold); - -int sanei_genesys_compute_dpihw(Genesys_Device *dev, const Genesys_Sensor& sensor, int xres); - -int sanei_genesys_compute_dpihw_calibration(Genesys_Device *dev, const Genesys_Sensor& sensor, - int xres); - -extern -Motor_Profile *sanei_genesys_get_motor_profile(Motor_Profile *motors, int motor_type, int exposure); - -extern -int sanei_genesys_compute_step_type(Motor_Profile *motors, int motor_type, int exposure); - -extern -int sanei_genesys_slope_table(uint16_t *slope, int *steps, int dpi, int exposure, int base_dpi, int step_type, int factor, int motor_type, Motor_Profile *motors); - -/** @brief find lowest motor resolution for the device. - * Parses the resolution list for motor and - * returns the lowest value. - * @param dev for which to find the lowest motor resolution - * @return the lowest available motor resolution for the device - */ -extern -int sanei_genesys_get_lowest_ydpi(Genesys_Device *dev); - -/** @brief find lowest resolution for the device. - * Parses the resolution list for motor and sensor and - * returns the lowest value. - * @param dev for which to find the lowest resolution - * @return the lowest available resolution for the device - */ -extern -int sanei_genesys_get_lowest_dpi(Genesys_Device *dev); - -extern bool -sanei_genesys_is_compatible_calibration (Genesys_Device * dev, const Genesys_Sensor& sensor, - Genesys_Calibration_Cache * cache, - int for_overwrite); - -/** @brief compute maximum line distance shift - * compute maximum line distance shift for the motor and sensor - * combination. Line distance shift is the distance between different - * color component of CCD sensors. Since these components aren't at - * the same physical place, they scan diffrent lines. Software must - * take this into account to accurately mix color data. - * @param dev device session to compute max_shift for - * @param channels number of color channels for the scan - * @param yres motor resolution used for the scan - * @param flags scan flags - * @return 0 or line distance shift - */ -extern -int sanei_genesys_compute_max_shift(Genesys_Device *dev, - int channels, - int yres, - int flags); - -extern SANE_Status -sanei_genesys_load_lut (unsigned char * lut, - int in_bits, - int out_bits, - int out_min, - int out_max, - int slope, - int offset); - -extern SANE_Status -sanei_genesys_generate_gamma_buffer(Genesys_Device * dev, - const Genesys_Sensor& sensor, - int bits, - int max, - int size, - uint8_t *gamma); - -/*---------------------------------------------------------------------------*/ -/* ASIC specific functions declarations */ -/*---------------------------------------------------------------------------*/ -extern SANE_Status sanei_gl646_init_cmd_set (Genesys_Device * dev); -extern SANE_Status sanei_gl841_init_cmd_set (Genesys_Device * dev); -extern SANE_Status sanei_gl843_init_cmd_set (Genesys_Device * dev); -extern SANE_Status sanei_gl846_init_cmd_set (Genesys_Device * dev); -extern SANE_Status sanei_gl847_init_cmd_set (Genesys_Device * dev); -extern SANE_Status sanei_gl124_init_cmd_set (Genesys_Device * dev); - -// same as usleep, except that it does nothing if testing mode is enabled -extern void sanei_genesys_usleep(unsigned int useconds); - -// same as sanei_genesys_usleep just that the duration is in milliseconds -extern void sanei_genesys_sleep_ms(unsigned int milliseconds); - -void add_function_to_run_at_backend_exit(std::function<void()> function); - -// calls functions added via add_function_to_run_at_backend_exit() in reverse order of being -// added. -void run_functions_at_backend_exit(); - -template<class T> -class StaticInit { -public: - StaticInit() = default; - StaticInit(const StaticInit&) = delete; - StaticInit& operator=(const StaticInit&) = delete; - - template<class... Args> - void init(Args&& ... args) - { - ptr_ = std::unique_ptr<T>(new T(std::forward<Args>(args)...)); - add_function_to_run_at_backend_exit([this](){ deinit(); }); - } - - void deinit() - { - ptr_.release(); - } - - const T* operator->() const { return ptr_.get(); } - T* operator->() { return ptr_.get(); } - const T& operator*() const { return *ptr_.get(); } - T& operator*() { return *ptr_.get(); } - -private: - std::unique_ptr<T> ptr_; -}; - -extern StaticInit<std::vector<Genesys_Sensor>> s_sensors; -void genesys_init_sensor_tables(); -void genesys_init_frontend_tables(); - -void debug_dump(unsigned level, const Genesys_Settings& settings); -void debug_dump(unsigned level, const SetupParams& params); -void debug_dump(unsigned level, const Genesys_Current_Setup& setup); - -#endif /* not GENESYS_LOW_H */ |