1141cc406Sopenharmony_ci/* sane - Scanner Access Now Easy. 2141cc406Sopenharmony_ci 3141cc406Sopenharmony_ci Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt> 4141cc406Sopenharmony_ci 5141cc406Sopenharmony_ci This file is part of the SANE package. 6141cc406Sopenharmony_ci 7141cc406Sopenharmony_ci This program is free software; you can redistribute it and/or 8141cc406Sopenharmony_ci modify it under the terms of the GNU General Public License as 9141cc406Sopenharmony_ci published by the Free Software Foundation; either version 2 of the 10141cc406Sopenharmony_ci License, or (at your option) any later version. 11141cc406Sopenharmony_ci 12141cc406Sopenharmony_ci This program is distributed in the hope that it will be useful, but 13141cc406Sopenharmony_ci WITHOUT ANY WARRANTY; without even the implied warranty of 14141cc406Sopenharmony_ci MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15141cc406Sopenharmony_ci General Public License for more details. 16141cc406Sopenharmony_ci 17141cc406Sopenharmony_ci You should have received a copy of the GNU General Public License 18141cc406Sopenharmony_ci along with this program. If not, see <https://www.gnu.org/licenses/>. 19141cc406Sopenharmony_ci*/ 20141cc406Sopenharmony_ci 21141cc406Sopenharmony_ci#ifndef BACKEND_GENESYS_SETTINGS_H 22141cc406Sopenharmony_ci#define BACKEND_GENESYS_SETTINGS_H 23141cc406Sopenharmony_ci 24141cc406Sopenharmony_ci#include "enums.h" 25141cc406Sopenharmony_ci#include "serialize.h" 26141cc406Sopenharmony_ci#include "utilities.h" 27141cc406Sopenharmony_ci#include "sensor.h" 28141cc406Sopenharmony_ci 29141cc406Sopenharmony_cinamespace genesys { 30141cc406Sopenharmony_ci 31141cc406Sopenharmony_cistruct Genesys_Settings 32141cc406Sopenharmony_ci{ 33141cc406Sopenharmony_ci ScanMethod scan_method = ScanMethod::FLATBED; 34141cc406Sopenharmony_ci ScanColorMode scan_mode = ScanColorMode::LINEART; 35141cc406Sopenharmony_ci 36141cc406Sopenharmony_ci // horizontal dpi 37141cc406Sopenharmony_ci unsigned xres = 0; 38141cc406Sopenharmony_ci // vertical dpi 39141cc406Sopenharmony_ci unsigned yres = 0; 40141cc406Sopenharmony_ci 41141cc406Sopenharmony_ci //x start on scan table in mm 42141cc406Sopenharmony_ci float tl_x = 0; 43141cc406Sopenharmony_ci // y start on scan table in mm 44141cc406Sopenharmony_ci float tl_y = 0; 45141cc406Sopenharmony_ci 46141cc406Sopenharmony_ci // number of lines at scan resolution 47141cc406Sopenharmony_ci unsigned int lines = 0; 48141cc406Sopenharmony_ci // number of pixels expected from the scanner 49141cc406Sopenharmony_ci unsigned int pixels = 0; 50141cc406Sopenharmony_ci // number of pixels expected by the frontend 51141cc406Sopenharmony_ci unsigned requested_pixels = 0; 52141cc406Sopenharmony_ci 53141cc406Sopenharmony_ci // bit depth of the scan 54141cc406Sopenharmony_ci unsigned int depth = 0; 55141cc406Sopenharmony_ci 56141cc406Sopenharmony_ci ColorFilter color_filter = ColorFilter::NONE; 57141cc406Sopenharmony_ci 58141cc406Sopenharmony_ci // value for contrast enhancement in the [-100..100] range 59141cc406Sopenharmony_ci int contrast = 0; 60141cc406Sopenharmony_ci 61141cc406Sopenharmony_ci // value for brightness enhancement in the [-100..100] range 62141cc406Sopenharmony_ci int brightness = 0; 63141cc406Sopenharmony_ci 64141cc406Sopenharmony_ci // cache entries expiration time 65141cc406Sopenharmony_ci int expiration_time = 0; 66141cc406Sopenharmony_ci 67141cc406Sopenharmony_ci unsigned get_channels() const 68141cc406Sopenharmony_ci { 69141cc406Sopenharmony_ci if (scan_mode == ScanColorMode::COLOR_SINGLE_PASS) 70141cc406Sopenharmony_ci return 3; 71141cc406Sopenharmony_ci return 1; 72141cc406Sopenharmony_ci } 73141cc406Sopenharmony_ci}; 74141cc406Sopenharmony_ci 75141cc406Sopenharmony_cistd::ostream& operator<<(std::ostream& out, const Genesys_Settings& settings); 76141cc406Sopenharmony_ci 77141cc406Sopenharmony_ci 78141cc406Sopenharmony_cistruct SetupParams { 79141cc406Sopenharmony_ci 80141cc406Sopenharmony_ci static constexpr unsigned NOT_SET = std::numeric_limits<unsigned>::max(); 81141cc406Sopenharmony_ci static constexpr unsigned NOT_SET_I = std::numeric_limits<int>::max(); 82141cc406Sopenharmony_ci 83141cc406Sopenharmony_ci // resolution in x direction 84141cc406Sopenharmony_ci unsigned xres = NOT_SET; 85141cc406Sopenharmony_ci // resolution in y direction 86141cc406Sopenharmony_ci unsigned yres = NOT_SET; 87141cc406Sopenharmony_ci // start pixel in X direction, from dummy_pixel + 1. Counted in terms of xres. 88141cc406Sopenharmony_ci unsigned startx = NOT_SET; 89141cc406Sopenharmony_ci // start pixel in Y direction, counted according to base_ydpi 90141cc406Sopenharmony_ci unsigned starty = NOT_SET; 91141cc406Sopenharmony_ci // the number of pixels in X direction. Counted in terms of xres. 92141cc406Sopenharmony_ci // Note that each logical pixel may correspond to more than one CCD pixel, see CKSEL and 93141cc406Sopenharmony_ci // GenesysSensor::ccd_pixels_per_system_pixel() 94141cc406Sopenharmony_ci unsigned pixels = NOT_SET; 95141cc406Sopenharmony_ci 96141cc406Sopenharmony_ci // the number of pixels in the X direction as requested by the frontend. This will be different 97141cc406Sopenharmony_ci // from `pixels` if the X resolution requested by the frontend is different than the actual 98141cc406Sopenharmony_ci // resolution. This is only needed to compute dev->total_bytes_to_read. If 0, then the value 99141cc406Sopenharmony_ci // is the same as pixels. 100141cc406Sopenharmony_ci // TODO: move the computation of total_bytes_to_read to a higher layer. 101141cc406Sopenharmony_ci unsigned requested_pixels = 0; 102141cc406Sopenharmony_ci 103141cc406Sopenharmony_ci // the number of pixels in Y direction 104141cc406Sopenharmony_ci unsigned lines = NOT_SET; 105141cc406Sopenharmony_ci // the depth of the scan in bits. Allowed are 1, 8, 16 106141cc406Sopenharmony_ci unsigned depth = NOT_SET; 107141cc406Sopenharmony_ci // the number of channels 108141cc406Sopenharmony_ci unsigned channels = NOT_SET; 109141cc406Sopenharmony_ci 110141cc406Sopenharmony_ci ScanMethod scan_method = static_cast<ScanMethod>(NOT_SET); 111141cc406Sopenharmony_ci 112141cc406Sopenharmony_ci ScanColorMode scan_mode = static_cast<ScanColorMode>(NOT_SET); 113141cc406Sopenharmony_ci 114141cc406Sopenharmony_ci ColorFilter color_filter = static_cast<ColorFilter>(NOT_SET); 115141cc406Sopenharmony_ci 116141cc406Sopenharmony_ci // the values for contrast and brightness adjustment in the range of [-100..100] 117141cc406Sopenharmony_ci int contrast_adjustment = NOT_SET_I; 118141cc406Sopenharmony_ci int brightness_adjustment = NOT_SET_I; 119141cc406Sopenharmony_ci 120141cc406Sopenharmony_ci ScanFlag flags = ScanFlag::NONE; 121141cc406Sopenharmony_ci 122141cc406Sopenharmony_ci unsigned get_requested_pixels() const 123141cc406Sopenharmony_ci { 124141cc406Sopenharmony_ci if (requested_pixels != 0) { 125141cc406Sopenharmony_ci return requested_pixels; 126141cc406Sopenharmony_ci } 127141cc406Sopenharmony_ci return pixels; 128141cc406Sopenharmony_ci } 129141cc406Sopenharmony_ci 130141cc406Sopenharmony_ci void assert_valid() const 131141cc406Sopenharmony_ci { 132141cc406Sopenharmony_ci if (xres == NOT_SET || yres == NOT_SET || startx == NOT_SET || starty == NOT_SET || 133141cc406Sopenharmony_ci pixels == NOT_SET || lines == NOT_SET ||depth == NOT_SET || channels == NOT_SET || 134141cc406Sopenharmony_ci scan_method == static_cast<ScanMethod>(NOT_SET) || 135141cc406Sopenharmony_ci scan_mode == static_cast<ScanColorMode>(NOT_SET) || 136141cc406Sopenharmony_ci color_filter == static_cast<ColorFilter>(NOT_SET) || 137141cc406Sopenharmony_ci contrast_adjustment == NOT_SET_I || brightness_adjustment == NOT_SET_I) 138141cc406Sopenharmony_ci { 139141cc406Sopenharmony_ci throw std::runtime_error("SetupParams are not valid"); 140141cc406Sopenharmony_ci } 141141cc406Sopenharmony_ci } 142141cc406Sopenharmony_ci 143141cc406Sopenharmony_ci bool operator==(const SetupParams& other) const 144141cc406Sopenharmony_ci { 145141cc406Sopenharmony_ci return xres == other.xres && 146141cc406Sopenharmony_ci yres == other.yres && 147141cc406Sopenharmony_ci startx == other.startx && 148141cc406Sopenharmony_ci starty == other.starty && 149141cc406Sopenharmony_ci pixels == other.pixels && 150141cc406Sopenharmony_ci requested_pixels == other.requested_pixels && 151141cc406Sopenharmony_ci lines == other.lines && 152141cc406Sopenharmony_ci depth == other.depth && 153141cc406Sopenharmony_ci channels == other.channels && 154141cc406Sopenharmony_ci scan_method == other.scan_method && 155141cc406Sopenharmony_ci scan_mode == other.scan_mode && 156141cc406Sopenharmony_ci color_filter == other.color_filter && 157141cc406Sopenharmony_ci contrast_adjustment == other.contrast_adjustment && 158141cc406Sopenharmony_ci brightness_adjustment == other.brightness_adjustment && 159141cc406Sopenharmony_ci flags == other.flags; 160141cc406Sopenharmony_ci } 161141cc406Sopenharmony_ci}; 162141cc406Sopenharmony_ci 163141cc406Sopenharmony_cistd::ostream& operator<<(std::ostream& out, const SetupParams& params); 164141cc406Sopenharmony_ci 165141cc406Sopenharmony_citemplate<class Stream> 166141cc406Sopenharmony_civoid serialize(Stream& str, SetupParams& x) 167141cc406Sopenharmony_ci{ 168141cc406Sopenharmony_ci serialize(str, x.xres); 169141cc406Sopenharmony_ci serialize(str, x.yres); 170141cc406Sopenharmony_ci serialize(str, x.startx); 171141cc406Sopenharmony_ci serialize(str, x.starty); 172141cc406Sopenharmony_ci serialize(str, x.pixels); 173141cc406Sopenharmony_ci serialize(str, x.requested_pixels); 174141cc406Sopenharmony_ci serialize(str, x.lines); 175141cc406Sopenharmony_ci serialize(str, x.depth); 176141cc406Sopenharmony_ci serialize(str, x.channels); 177141cc406Sopenharmony_ci serialize(str, x.scan_method); 178141cc406Sopenharmony_ci serialize(str, x.scan_mode); 179141cc406Sopenharmony_ci serialize(str, x.color_filter); 180141cc406Sopenharmony_ci serialize(str, x.contrast_adjustment); 181141cc406Sopenharmony_ci serialize(str, x.brightness_adjustment); 182141cc406Sopenharmony_ci serialize(str, x.flags); 183141cc406Sopenharmony_ci} 184141cc406Sopenharmony_ci 185141cc406Sopenharmony_cistruct ScanSession { 186141cc406Sopenharmony_ci SetupParams params; 187141cc406Sopenharmony_ci 188141cc406Sopenharmony_ci // whether the session setup has been computed via compute_session() 189141cc406Sopenharmony_ci bool computed = false; 190141cc406Sopenharmony_ci 191141cc406Sopenharmony_ci // specifies the full resolution of the sensor that is being used. 192141cc406Sopenharmony_ci unsigned full_resolution = 0; 193141cc406Sopenharmony_ci 194141cc406Sopenharmony_ci // the optical resolution of the sensor that is being used. 195141cc406Sopenharmony_ci unsigned optical_resolution = 0; 196141cc406Sopenharmony_ci 197141cc406Sopenharmony_ci // the number of pixels at the optical resolution, not including segmentation overhead. 198141cc406Sopenharmony_ci unsigned optical_pixels = 0; 199141cc406Sopenharmony_ci 200141cc406Sopenharmony_ci // the number of pixels at the optical resolution, including segmentation overhead. 201141cc406Sopenharmony_ci // only on gl846, g847 202141cc406Sopenharmony_ci unsigned optical_pixels_raw = 0; 203141cc406Sopenharmony_ci 204141cc406Sopenharmony_ci // the number of optical scan lines. Equal to output_line_count on CCD scanners. 205141cc406Sopenharmony_ci unsigned optical_line_count = 0; 206141cc406Sopenharmony_ci 207141cc406Sopenharmony_ci // the resolution of the output data. 208141cc406Sopenharmony_ci unsigned output_resolution = 0; 209141cc406Sopenharmony_ci 210141cc406Sopenharmony_ci // the offset in pixels from the beginning of output data 211141cc406Sopenharmony_ci unsigned output_startx = 0; 212141cc406Sopenharmony_ci 213141cc406Sopenharmony_ci // the number of pixels in output data (after desegmentation) 214141cc406Sopenharmony_ci unsigned output_pixels = 0; 215141cc406Sopenharmony_ci 216141cc406Sopenharmony_ci // the number of bytes in the output of a channel of a single line (after desegmentation) 217141cc406Sopenharmony_ci unsigned output_channel_bytes = 0; 218141cc406Sopenharmony_ci 219141cc406Sopenharmony_ci // the number of bytes in the output of a single line (after desegmentation) 220141cc406Sopenharmony_ci unsigned output_line_bytes = 0; 221141cc406Sopenharmony_ci 222141cc406Sopenharmony_ci // the number of bytes per line in the output data from the scanner (before desegmentation) 223141cc406Sopenharmony_ci // Equal to output_line_bytes if sensor does not have segments 224141cc406Sopenharmony_ci unsigned output_line_bytes_raw = 0; 225141cc406Sopenharmony_ci 226141cc406Sopenharmony_ci // the number of bytes per line as requested by the frontend 227141cc406Sopenharmony_ci unsigned output_line_bytes_requested = 0; 228141cc406Sopenharmony_ci 229141cc406Sopenharmony_ci // the number of lines in the output of the scanner. This must be larger than the user 230141cc406Sopenharmony_ci // requested number due to line staggering and color channel shifting. 231141cc406Sopenharmony_ci unsigned output_line_count = 0; 232141cc406Sopenharmony_ci 233141cc406Sopenharmony_ci // the total number of bytes to read from the scanner (before desegmentation) 234141cc406Sopenharmony_ci unsigned output_total_bytes_raw = 0; 235141cc406Sopenharmony_ci 236141cc406Sopenharmony_ci // the total number of bytes to read from the scanner (after desegmentation) 237141cc406Sopenharmony_ci unsigned output_total_bytes = 0; 238141cc406Sopenharmony_ci 239141cc406Sopenharmony_ci // the number of staggered lines (i.e. lines that overlap during scanning due to line being 240141cc406Sopenharmony_ci // thinner than the CCD element). Computed according to stagger_y. 241141cc406Sopenharmony_ci unsigned num_staggered_lines = 0; 242141cc406Sopenharmony_ci 243141cc406Sopenharmony_ci // the number of lines that color channels shift due to different physical positions of 244141cc406Sopenharmony_ci // different color channels. 245141cc406Sopenharmony_ci unsigned max_color_shift_lines = 0; 246141cc406Sopenharmony_ci 247141cc406Sopenharmony_ci // actual line shift of the red color 248141cc406Sopenharmony_ci unsigned color_shift_lines_r = 0; 249141cc406Sopenharmony_ci // actual line shift of the green color 250141cc406Sopenharmony_ci unsigned color_shift_lines_g = 0; 251141cc406Sopenharmony_ci // actual line shift of the blue color 252141cc406Sopenharmony_ci unsigned color_shift_lines_b = 0; 253141cc406Sopenharmony_ci 254141cc406Sopenharmony_ci // The shifts that need to be applied to the output pixels in x direction. 255141cc406Sopenharmony_ci StaggerConfig stagger_x; 256141cc406Sopenharmony_ci // The shifts that need to be applied to the output pixels in y direction. 257141cc406Sopenharmony_ci StaggerConfig stagger_y; 258141cc406Sopenharmony_ci 259141cc406Sopenharmony_ci // the number of scanner segments used in the current scan 260141cc406Sopenharmony_ci unsigned segment_count = 1; 261141cc406Sopenharmony_ci 262141cc406Sopenharmony_ci // the physical pixel positions that are sent to the registers 263141cc406Sopenharmony_ci unsigned pixel_startx = 0; 264141cc406Sopenharmony_ci unsigned pixel_endx = 0; 265141cc406Sopenharmony_ci 266141cc406Sopenharmony_ci /* The following defines the ratio between logical pixel count and pixel count setting sent to 267141cc406Sopenharmony_ci the scanner. The ratio is affected by the following: 268141cc406Sopenharmony_ci 269141cc406Sopenharmony_ci - Certain scanners just like to multiply the pixel number by a multiplier that depends on 270141cc406Sopenharmony_ci the resolution. 271141cc406Sopenharmony_ci 272141cc406Sopenharmony_ci - The sensor may be configured to output one value per multiple physical pixels 273141cc406Sopenharmony_ci 274141cc406Sopenharmony_ci - The scanner will automatically average the pixels that come from the sensor using a 275141cc406Sopenharmony_ci certain ratio. 276141cc406Sopenharmony_ci */ 277141cc406Sopenharmony_ci Ratio pixel_count_ratio = Ratio{1, 1}; 278141cc406Sopenharmony_ci 279141cc406Sopenharmony_ci // Distance in pixels between consecutive pixels, e.g. between odd and even pixels. Note that 280141cc406Sopenharmony_ci // the number of segments can be large. 281141cc406Sopenharmony_ci // only on gl124, gl846, gl847 282141cc406Sopenharmony_ci unsigned conseq_pixel_dist = 0; 283141cc406Sopenharmony_ci 284141cc406Sopenharmony_ci // The number of "even" pixels to scan. This corresponds to the number of pixels that will be 285141cc406Sopenharmony_ci // scanned from a single segment 286141cc406Sopenharmony_ci // only on gl124, gl846, gl847 287141cc406Sopenharmony_ci unsigned output_segment_pixel_group_count = 0; 288141cc406Sopenharmony_ci 289141cc406Sopenharmony_ci // The number of bytes to skip at start of line during desegmentation. 290141cc406Sopenharmony_ci // Currently it's always zero. 291141cc406Sopenharmony_ci unsigned output_segment_start_offset = 0; 292141cc406Sopenharmony_ci 293141cc406Sopenharmony_ci // How many pixels the shading data is offset to the right from the acquired data. Calculated 294141cc406Sopenharmony_ci // in shading resolution. 295141cc406Sopenharmony_ci int shading_pixel_offset = 0; 296141cc406Sopenharmony_ci 297141cc406Sopenharmony_ci // the size of the read buffer. 298141cc406Sopenharmony_ci size_t buffer_size_read = 0; 299141cc406Sopenharmony_ci 300141cc406Sopenharmony_ci // whether to enable ledadd functionality 301141cc406Sopenharmony_ci bool enable_ledadd = false; 302141cc406Sopenharmony_ci 303141cc406Sopenharmony_ci // whether calibration should be performed host-side 304141cc406Sopenharmony_ci bool use_host_side_calib = false; 305141cc406Sopenharmony_ci 306141cc406Sopenharmony_ci // whether gray scanning should be performed host-side (scan as color and merge to gray) 307141cc406Sopenharmony_ci bool use_host_side_gray = false; 308141cc406Sopenharmony_ci 309141cc406Sopenharmony_ci void assert_computed() const 310141cc406Sopenharmony_ci { 311141cc406Sopenharmony_ci if (!computed) { 312141cc406Sopenharmony_ci throw std::runtime_error("ScanSession is not computed"); 313141cc406Sopenharmony_ci } 314141cc406Sopenharmony_ci } 315141cc406Sopenharmony_ci 316141cc406Sopenharmony_ci bool operator==(const ScanSession& other) const; 317141cc406Sopenharmony_ci}; 318141cc406Sopenharmony_ci 319141cc406Sopenharmony_cistd::ostream& operator<<(std::ostream& out, const ScanSession& session); 320141cc406Sopenharmony_ci 321141cc406Sopenharmony_citemplate<class Stream> 322141cc406Sopenharmony_civoid serialize(Stream& str, ScanSession& x) 323141cc406Sopenharmony_ci{ 324141cc406Sopenharmony_ci serialize(str, x.params); 325141cc406Sopenharmony_ci serialize_newline(str); 326141cc406Sopenharmony_ci serialize(str, x.computed); 327141cc406Sopenharmony_ci serialize(str, x.full_resolution); 328141cc406Sopenharmony_ci serialize(str, x.optical_resolution); 329141cc406Sopenharmony_ci serialize(str, x.optical_pixels); 330141cc406Sopenharmony_ci serialize(str, x.optical_pixels_raw); 331141cc406Sopenharmony_ci serialize(str, x.optical_line_count); 332141cc406Sopenharmony_ci serialize(str, x.output_resolution); 333141cc406Sopenharmony_ci serialize(str, x.output_startx); 334141cc406Sopenharmony_ci serialize(str, x.output_pixels); 335141cc406Sopenharmony_ci serialize(str, x.output_channel_bytes); 336141cc406Sopenharmony_ci serialize(str, x.output_line_bytes); 337141cc406Sopenharmony_ci serialize(str, x.output_line_bytes_raw); 338141cc406Sopenharmony_ci serialize(str, x.output_line_bytes_requested); 339141cc406Sopenharmony_ci serialize(str, x.output_line_count); 340141cc406Sopenharmony_ci serialize(str, x.output_total_bytes_raw); 341141cc406Sopenharmony_ci serialize(str, x.output_total_bytes); 342141cc406Sopenharmony_ci serialize(str, x.num_staggered_lines); 343141cc406Sopenharmony_ci serialize(str, x.max_color_shift_lines); 344141cc406Sopenharmony_ci serialize(str, x.color_shift_lines_r); 345141cc406Sopenharmony_ci serialize(str, x.color_shift_lines_g); 346141cc406Sopenharmony_ci serialize(str, x.color_shift_lines_b); 347141cc406Sopenharmony_ci serialize(str, x.stagger_x); 348141cc406Sopenharmony_ci serialize(str, x.stagger_y); 349141cc406Sopenharmony_ci serialize(str, x.segment_count); 350141cc406Sopenharmony_ci serialize(str, x.pixel_startx); 351141cc406Sopenharmony_ci serialize(str, x.pixel_endx); 352141cc406Sopenharmony_ci serialize(str, x.pixel_count_ratio); 353141cc406Sopenharmony_ci serialize(str, x.conseq_pixel_dist); 354141cc406Sopenharmony_ci serialize(str, x.output_segment_pixel_group_count); 355141cc406Sopenharmony_ci serialize(str, x.output_segment_start_offset); 356141cc406Sopenharmony_ci serialize(str, x.shading_pixel_offset); 357141cc406Sopenharmony_ci serialize(str, x.buffer_size_read); 358141cc406Sopenharmony_ci serialize(str, x.enable_ledadd); 359141cc406Sopenharmony_ci serialize(str, x.use_host_side_calib); 360141cc406Sopenharmony_ci serialize(str, x.use_host_side_gray); 361141cc406Sopenharmony_ci} 362141cc406Sopenharmony_ci 363141cc406Sopenharmony_cistd::ostream& operator<<(std::ostream& out, const SANE_Parameters& params); 364141cc406Sopenharmony_ci 365141cc406Sopenharmony_ci} // namespace genesys 366141cc406Sopenharmony_ci 367141cc406Sopenharmony_ci#endif // BACKEND_GENESYS_SETTINGS_H 368