1 2 #ifndef INST_H 3 4 /* 5 * instlib API definition. 6 * 7 * See spotread.c, chartread.c, illumread.c & ccxxmake.c for examples of 8 * the API usage. 9 * 10 * Abstract base class for common color instrument interface 11 * and other common instrument stuff. 12 */ 13 14 /* 15 * Argyll Color Correction System 16 * 17 * Author: Graeme W. Gill 18 * Date: 15/3/2001 19 * 20 * Copyright 2001 - 2013 Graeme W. Gill 21 * All rights reserved. 22 * 23 * This material is licenced under the GNU GENERAL PUBLIC LICENSE Version 2 or later :- 24 * see the License2.txt file for licencing details. 25 * 26 */ 27 28 /* 29 If you make use of the instrument driver code here, please note 30 that it is the author(s) of the code who take responsibility 31 for its operation. Any problems or queries regarding driving 32 instruments with the Argyll drivers, should be directed to 33 the Argyll's author(s), and not to any other party. 34 35 If there is some instrument feature or function that you 36 would like supported here, it is recommended that you 37 contact Argyll's author(s) first, rather than attempt to 38 modify the software yourself, if you don't have firm knowledge 39 of the instrument communicate protocols. There is a chance 40 that an instrument could be damaged by an incautious command 41 sequence, and the instrument companies generally cannot and 42 will not support developers that they have not qualified 43 and agreed to support. 44 */ 45 46 #include "insttypes.h" /* libinst Includes this functionality */ 47 #include "disptechs.h" /* libinst Includes this functionality */ 48 #include "icoms.h" /* libinst Includes this functionality */ 49 #include "conv.h" 50 51 #ifdef __cplusplus 52 extern "C" { 53 #endif 54 55 /* ------------------------------------------------- */ 56 /* aprox. debug level guide: 57 58 1,2 Applications, internal errors 59 2,3 High level instrument drivers 60 4,5 High level instrument communications 61 6,7 High level serial/USB communications 62 8,9 Low level serial/USB communications 63 64 */ 65 66 /* ------------------------------------------------- */ 67 /* Structure for holding an instrument patch reading */ 68 69 #ifdef NEVER /* Declared in xicc/xspect.h */ 70 71 /* Type of measurement result */ 72 typedef enum { /* XYZ units, Spectral units */ 73 inst_mrt_none = 0, /* Not set */ 74 inst_mrt_emission = 1, /* cd/m^2, mW/(m^2.sr.nm) */ 75 inst_mrt_ambient = 2, /* Lux mW/(m^2.nm) */ 76 inst_mrt_emission_flash = 3, /* cd.s/m^2, mW.s/(m^2.sr.nm) */ 77 inst_mrt_ambient_flash = 4, /* Lux.s mW.s/(m^2.nm) */ 78 inst_mrt_reflective = 5, /* %, %/nm */ 79 inst_mrt_transmissive = 6, /* %, %/nm */ 80 inst_mrt_frequency = 7 /* Hz */ 81 } inst_meas_type; 82 83 #endif // NEVER 84 85 #define ICOM_MAX_LOC_LEN 10 86 87 struct _ipatch { 88 char loc[ICOM_MAX_LOC_LEN]; /* patch location */ 89 90 inst_meas_type mtype; /* Measurement type */ 91 92 int XYZ_v; /* XYZ valid */ 93 double XYZ[3]; /* XYZ values */ 94 95 xspect sp; /* Spectrum. sp.spec_n > 0 if valid */ 96 /* Reflectance/Transmittance 0.0 .. 100.0%, norm = 100.0 */ 97 /* or mW/nm/m^2, norm = 1.0, etc. */ 98 99 double duration; /* Apparent total duration in seconds (flash measurement) */ 100 /* Typicall limited to sampling rate of instrument. */ 101 102 }; typedef struct _ipatch ipatch; 103 104 /* ------------------------------------------------------ */ 105 /* Gretag/X-Rite specific reflective measurement standard */ 106 107 typedef enum { 108 xcalstd_none = -2, /* Not set */ 109 xcalstd_native = -1, /* No conversion */ 110 xcalstd_xrdi = 0, /* Historical X-Rite */ 111 xcalstd_gmdi = 1, /* Historical Gretag-Macbeth */ 112 xcalstd_xrga = 2, /* Current X-Rite */ 113 } xcalstd; 114 115 /* Return a string for the xcalstd enum */ 116 char *xcalstd2str(xcalstd std); 117 118 /* ---------------------------------------- */ 119 /* Instrument interface abstract base class */ 120 121 /* Abstract return codes in ms 8bits. */ 122 /* Instrument dependant codes in ls 16 bits. */ 123 /* Note :- update inst_interp_error() in inst.c if anything here is changed. */ 124 /* and also check all the instrument specific XXX_interp_code() routines too. */ 125 typedef enum { 126 inst_ok = 0x000000, 127 inst_notify = 0x010000, /* A Notification */ 128 inst_warning = 0x020000, /* A Warning */ 129 inst_no_coms = 0x030000, /* init_coms() hasn't been called yet */ 130 inst_no_init = 0x040000, /* init_inst() hasn't been called yet */ 131 inst_unsupported = 0x050000, /* Unsupported function */ 132 inst_internal_error = 0x060000, /* Internal software error */ 133 inst_coms_fail = 0x070000, /* Communication failure */ 134 inst_unknown_model = 0x080000, /* Not the expected instrument */ 135 inst_protocol_error = 0x090000, /* Read or Write protocol error */ 136 inst_user_abort = 0x0A0000, /* User hit escape */ 137 inst_user_trig = 0x0C0000, /* User hit trigger key */ 138 inst_misread = 0x0E0000, /* Bad reading, or strip misread */ 139 inst_nonesaved = 0x0F0000, /* No saved data to read */ 140 inst_nochmatch = 0x100000, /* Chart doesn't match */ 141 inst_needs_cal = 0x110000, /* Instrument needs calibration, and read retried */ 142 inst_cal_setup = 0x120000, /* Calibration retry with correct setup is needed */ 143 inst_wrong_config = 0x130000, /* Retry with correct inst. config./sensor posn. needed */ 144 inst_unexpected_reply = 0x140000, /* Unexpected Reply */ 145 inst_wrong_setup = 0x150000, /* Setup is wrong or conflicting */ 146 inst_hardware_fail = 0x160000, /* Hardware failure */ 147 inst_system_error = 0x170000, /* System call (ie malloc) fail */ 148 inst_bad_parameter = 0x180000, /* Bad parameter value */ 149 inst_other_error = 0x190000, /* Some other error */ 150 inst_mask = 0xff0000, /* inst_code mask value */ 151 inst_imask = 0x00ffff /* instrument specific mask value */ 152 } inst_code; 153 154 155 /* 156 possible UV modes: 157 158 Do the reflective measurement with UV rather than normal illuminant 159 [ Should this be reflectivity against 'A', or absolute ?? ] 160 (ie. spot, strip, xy or chart). inst_mode_ref_uv 161 162 Do a white & UV measurement at the start of each strip reading. 163 Return result with special call after each strip read. 164 inst_mode_ref_uv_strip_1 165 166 Do a dual white & UV measurement 167 [ Can do in one hit for spot, but how should two strip passes be handled ? 168 ie. two separate strip reads of phase 1 & then 2 ? ] 169 (ie. spot, strip, xy or chart). inst_mode_ref_uv_2pass 170 171 Get normal illuminant spectrum. 172 173 Get UV spectrum. 174 175 get_meas_illum_spectrum(mode); 176 */ 177 178 /* Instrument capabilities & modes */ 179 /* Note that due to the binary combinations, capabilities is not definititive */ 180 /* as to valid modes. check_mode() is definitive. */ 181 /* #defines are for saving modes in a version independent way. */ 182 /* Note :- update inst_mode_sym[] table in inst.c if anything here is changed. */ 183 typedef enum { 184 inst_mode_none = 0x00000000, /* No capability or mode */ 185 186 /* Light measurement mode */ 187 inst_mode_reflection = 0x00000001, /* General reflection mode */ 188 # define inst_mode_reflection_sym "REFL" 189 inst_mode_s_reflection = 0x00000002, /* General saved reflection mode */ 190 # define inst_mode_s_reflection_sym "SRFL" 191 inst_mode_transmission = 0x00000004, /* General transmission mode */ 192 # define inst_mode_transmission_sym "TRAN" 193 inst_mode_emission = 0x00000008, /* General emission mode */ 194 # define inst_mode_emission_sym "EMIS" 195 inst_mode_illum_mask = 0x0000000f, /* Mask of sample illumination sub mode */ 196 197 /* Action of measurement */ 198 inst_mode_spot = 0x00000010, /* General spot measurement mode */ 199 # define inst_mode_spot_sym "SPOT" 200 inst_mode_strip = 0x00000020, /* General strip measurement mode */ 201 # define inst_mode_strip_sym "STRP" 202 inst_mode_xy = 0x00000040, /* General X-Y measurement mode */ 203 # define inst_mode_xy_sym "CHXY" 204 inst_mode_chart = 0x00000080, /* General chart measurement mode */ 205 # define inst_mode_chart_sym "CHRT" 206 inst_mode_ambient = 0x00000100, /* General ambient measurement mode */ 207 # define inst_mode_ambient_sym "AMBI" 208 inst_mode_ambient_flash = 0x00000200, /* General ambient flash measurement mode */ 209 # define inst_mode_ambient_flash_sym "ABFL" 210 inst_mode_tele = 0x00000400, /* General telephoto measurement mode */ 211 # define inst_mode_tele_sym "TELE" 212 // Hmm. Should there be a tele_flash mode ???? 213 inst_mode_sub_mask = 0x000007f0, /* Mask of sub-mode */ 214 215 /* Basic mode */ 216 inst_mode_basic_mask = inst_mode_illum_mask | inst_mode_sub_mask, 217 218 /* Extra dependent modes */ 219 inst_mode_emis_nonadaptive = 0x00000800, /* Emissom Non-adaptive mode */ 220 # define inst_mode_emis_nonadaptive_sys "EMNA" 221 inst_mode_ref_uv = 0x00001000, /* Ultra Violet measurement mode */ 222 # define inst_mode_ref_uv_sym "REUV" 223 inst_mode_emis_refresh_ovd = 0x00002000, /* Emissom Refresh mode override */ 224 # define inst_mode_emis_refresh_ovd_sym "EMRO" 225 inst_mode_emis_norefresh_ovd = 0x00006000, /* Emissom Non-refresh mode override */ 226 # define inst_mode_emis_norefresh_ovd_sym "ENRO" 227 inst_mode_dep_extra_mask = 0x00007800, /* Mask of measurement modifiers */ 228 229 /* Extra independent modes */ 230 inst_mode_colorimeter = 0x00004000, /* Colorimetric mode */ 231 # define inst_mode_colorimeter_sym "COLI" 232 inst_mode_spectral = 0x00008000, /* Spectral mode */ 233 # define inst_mode_spectral_sym "SPEC" 234 inst_mode_highres = 0x00010000, /* High Resolution Spectral mode */ 235 # define inst_mode_highres_sym "HIRZ" 236 inst_mode_extra_mask = 0x0001c000, /* Mask of extra modes */ 237 238 /* Configured for calibration & capable of returning it from inst_mode_calibration */ 239 inst_mode_calibration = 0x80000000, /* Configured for calibration */ 240 # define inst_mode_calibration_sym "CALB" 241 242 /* Combined operating modes (from above): */ 243 /* These mode capabilities are also use to set the mode */ 244 /* Test for a mode should be IMODETST(flags, mode) */ 245 inst_mode_ref_spot = inst_mode_spot /* Reflection spot measurement mode */ 246 | inst_mode_reflection, 247 inst_mode_ref_strip = inst_mode_strip /* Reflection strip measurement mode */ 248 | inst_mode_reflection, 249 inst_mode_ref_xy = inst_mode_xy /* Reflection X-Y measurement mode */ 250 | inst_mode_reflection, 251 inst_mode_ref_chart = inst_mode_chart /* Reflection Chart measurement mode */ 252 | inst_mode_reflection, 253 254 inst_mode_s_ref_spot = inst_mode_spot /* Saved reflection spot measurement mode */ 255 | inst_mode_s_reflection, 256 inst_mode_s_ref_strip = inst_mode_strip /* Saved reflection strip measurement mode */ 257 | inst_mode_s_reflection, 258 inst_mode_s_ref_xy = inst_mode_xy /* Saved reflection X-Y measurement mode */ 259 | inst_mode_s_reflection, 260 inst_mode_s_ref_chart = inst_mode_chart /* Saved reflection Chart measurement mode */ 261 | inst_mode_s_reflection, 262 263 inst_mode_trans_spot = inst_mode_spot /* Transmission spot measurement mode */ 264 | inst_mode_transmission, /* Normal Diffuse/90 */ 265 inst_mode_trans_spot_a = inst_mode_ambient /* Transmission spot measurement mode */ 266 | inst_mode_transmission, /* Alternate 90/diffuse */ 267 inst_mode_trans_strip = inst_mode_strip /* Transmission strip measurement mode */ 268 | inst_mode_transmission, 269 inst_mode_trans_xy = inst_mode_xy /* Transmission X-Y measurement mode */ 270 | inst_mode_transmission, 271 inst_mode_trans_chart = inst_mode_chart /* Transmission chart measurement mode */ 272 | inst_mode_transmission, 273 274 inst_mode_emis_spot = inst_mode_spot /* Spot emission measurement mode */ 275 | inst_mode_emission, 276 inst_mode_emis_tele = inst_mode_tele /* Telephoto emission measurement mode */ 277 | inst_mode_emission, 278 inst_mode_emis_ambient = inst_mode_ambient /* Ambient emission measurement mode */ 279 | inst_mode_emission, 280 inst_mode_emis_ambient_flash = inst_mode_ambient_flash /* Ambient emission flash measurement */ 281 | inst_mode_emission, 282 283 inst_mode_emis_strip = inst_mode_strip /* Strip emission measurement mode */ 284 | inst_mode_emission, 285 286 inst_mode_measurement_mask = inst_mode_illum_mask /* Mask of exclusive measurement modes */ 287 | inst_mode_sub_mask 288 | inst_mode_dep_extra_mask 289 } inst_mode; 290 291 /* Test for a specific mode */ 292 /* (This isn't foolproof - it->check_mode() is better for modes */ 293 /* composed of more than one bit) */ 294 #define IMODETST(mbits, mode) (((mbits) & (mode)) == (mode)) 295 296 /* Test for a specific mode in capability and mode */ 297 #define IMODETST2(mcap, mbits, mode) (IMODETST(mcap, mode) && IMODETST(mbits, mode)) 298 299 #define MAX_INST_MODE_SYM_SZ (32 * (4 + 1)) /* Each bit sym is 4 chars */ 300 301 /* Return a string with a symbolic encoding of the mode flags */ 302 void inst_mode_to_sym(char sym[MAX_INST_MODE_SYM_SZ], inst_mode mode); 303 304 /* Return a set of mode flags that correspondf to the symbolic encoding */ 305 /* Return nz if a symbol wasn't recognized */ 306 int sym_to_inst_mode(inst_mode *mode, const char *sym); 307 308 309 /* Instrument capabilities 2 */ 310 /* (Available capabilities may be mode dependent) */ 311 typedef enum { 312 inst2_none = 0x00000000, /* No capabilities */ 313 314 inst2_xy_holdrel = 0x00000001, /* Needs paper hold/release between each sheet */ 315 inst2_xy_locate = 0x00000002, /* Needs user to locate patch locations */ 316 inst2_xy_position = 0x00000004, /* Can be positioned at a given location */ 317 318 inst2_meas_disp_update = 0x00000010, /* Is able to measure display update delay */ 319 320 inst2_get_refresh_rate = 0x00000020, /* Is able to get the calibrated refresh rate */ 321 inst2_set_refresh_rate = 0x00000040, /* Is able to set the calibrated refresh rate */ 322 323 inst2_emis_refr_meas = 0x00000080, /* Has an emissive refresh rate measurement func. */ 324 325 inst2_prog_trig = 0x00000100, /* Progromatic trigger measure capability */ 326 inst2_user_trig = 0x00000200, /* User trigger measure capability, */ 327 /* i.e. via user button and uicallback. */ 328 inst2_switch_trig = 0x00000400, /* Inst. switch trigger measure capability, */ 329 /* i.e. instrument directly starts measurement */ 330 /* via mechanical switch. */ 331 inst2_user_switch_trig = 0x00000800, /* User or switch trigger measure capability */ 332 333 inst2_bidi_scan = 0x00001000, /* Try and recognise patches scanned from either dir. */ 334 inst2_cal_using_switch = 0x00002000, /* DTP22 special - use switch triggered calibration */ 335 inst2_has_scan_toll = 0x00004000, /* Instrument will honour modified scan tollerance */ 336 inst2_no_feedback = 0x00008000, /* Instrument doesn't give any user feedback */ 337 338 inst2_opt_calibs = 0x00010000, /* Instrument has optional calibrations */ 339 340 inst2_has_leds = 0x00200000, /* Instrument has some user viewable indicator LEDs */ 341 inst2_has_target = 0x00400000, /* Instrument has aiming target */ 342 inst2_has_sensmode = 0x00800000, /* Instrument can report it's sensors mode */ 343 344 inst2_has_battery = 0x01000000, /* Instrument is battery powered */ 345 346 inst2_disptype = 0x02000000, /* Has a display/calibration type selector */ 347 /* (ie. get_disptypesel(), set_disptype */ 348 349 inst2_ccmx = 0x04000000, /* Colorimeter Correction Matrix capability */ 350 inst2_ccss = 0x08000000, /* Colorimeter Cal. Spectral Set capability */ 351 352 inst2_ambient_mono = 0x10000000, /* The ambient measurement is monochrome */ 353 354 inst2_ambient_cardioid = 0x20000000, /* The ambient measurement has a cardioid response */ 355 356 inst2_get_min_int_time = 0x40000000, /* Is able to get the minimum integration time */ 357 inst2_set_min_int_time = 0x80000000 /* Is able to set the minimum integration time */ 358 359 } inst2_capability; 360 361 /* Instrument capabilities 3 (room for expansion) */ 362 /* (Available capabilities may be mode dependent) */ 363 typedef enum { 364 inst3_none = 0x00000000, /* No capabilities */ 365 366 } inst3_capability; 367 368 /* - - - - - - - - - - - - - - - - - - - */ 369 370 /* API ideas for supporting calibration management: 371 372 functions to: 373 374 return number of used and free builtin slots, + password required flag. 375 376 write builtin calibration or ccss/ccmx file 377 378 write builtin calibration or ccss/ccmx file 379 380 delete builtin calibration or ccss/ccmx file 381 382 Things to be allowed for: 383 384 optional password 385 configuration specific calibrations. How are they marked ? 386 387 388 Also for ccss capable instruments: 389 390 write corresponding ccmx for given ccss. 391 */ 392 393 typedef enum { 394 inst_dtflags_none = 0x0000, /* no flags - assume builtin calibration */ 395 inst_dtflags_mtx = 0x0001, /* matrix read from instrument */ 396 inst_dtflags_ccss = 0x0002, /* ccss file */ 397 inst_dtflags_ccmx = 0x0004, /* ccmx file */ 398 inst_dtflags_custom = 0x0010, /* custom (i.e. not built in or OEM) */ 399 inst_dtflags_wr = 0x0020, /* Writable slot */ 400 inst_dtflags_ld = 0x0040, /* mtx/ccss/ccmx is loaded */ 401 inst_dtflags_default = 0x1000, /* Default calibration to use */ 402 inst_dtflags_end = 0x8000 /* end marker */ 403 } inst_dtflags; 404 405 #define INST_DTYPE_SEL_LEN 10 406 #define INST_DTYPE_DESC_LEN 100 407 408 /* Structure used to return display type selection information. */ 409 /* Calibrations may be implicit (based on ix and driver code), or */ 410 /* explicit mtx/ccss/ccmx information contained in structure. */ 411 typedef struct _inst_disptypesel { 412 413 /* Public: */ 414 inst_dtflags flags; /* Attribute flags */ 415 int cbid; /* Calibration base ID. NZ if valid ccmx calibration base. */ 416 /* Should remain constant between releases */ 417 char sel[INST_DTYPE_SEL_LEN]; /* String of selector character aliases */ 418 char desc[INST_DTYPE_DESC_LEN]; /* Textural description */ 419 int refr; /* Refresh mode flag */ 420 421 disptech dtech; /* display techology */ 422 423 /* Private: */ 424 int ix; /* Internal index, */ 425 char isel[INST_DTYPE_SEL_LEN]; /* String of potential selector characters */ 426 427 // Stuff for ccss & ccmx 428 char *path; /* Path to ccss or ccmx. NULL if not valid */ 429 int cc_cbid; /* cbid that matrix requires */ 430 double mat[3][3]; /* ccmx matrix */ 431 xspect *sets; /* ccss set of sample spectra. NULL if not valid */ 432 int no_sets; /* ccs number of sets. 0 if not valid */ 433 434 } inst_disptypesel; 435 436 /* - - - - - - - - - - - - - - - - - - - */ 437 438 /* Instrument options for get_set_opt() */ 439 typedef enum { 440 inst_opt_unknown = 0x0000, /* Option not specified */ 441 442 inst_stat_saved_readings = 0x0001, /* Return status of saved reading values */ 443 /* [1 argument type *inst_stat_savdrd] */ 444 inst_stat_s_spot = 0x0002, /* Return number of saved spot readings */ 445 /* [1 argument type *int] */ 446 inst_stat_s_strip = 0x0003, /* Return saved strip details */ 447 /* [args: int *no_patches, int *no_rows */ 448 /* int *pat_per_row] */ 449 inst_stat_s_xy = 0x0004, /* Return saved strip details */ 450 /* [args: int *no_sheets, int *no_patches, */ 451 /* int *no_rows, int *pat_per_row] */ 452 inst_stat_s_chart = 0x0005, /* Return number saved chart details */ 453 /* [args: int *no_patches, int *no_rows */ 454 /* int *pat_per_row, int *chart_id, */ 455 /* int *missing_row ] */ 456 457 inst_stat_battery = 0x0006, /* Return charged status of battery */ 458 /* [1 argument type *double : range 0.0 - 1.0 ] */ 459 460 inst_stat_get_filter = 0x0007, /* Get a filter configuration */ 461 /* [1 argument type *inst_opt_filter ] */ 462 463 inst_opt_initcalib = 0x0008, /* Enable initial calibration (default) [No args] */ 464 inst_opt_noinitcalib = 0x0009, /* Disable initial calibration if < losecs since last */ /* opened, or losecs == 0 [int losecs] */ 465 466 inst_opt_askcalib = 0x000A, /* Ask before proceeding with calibration (default) */ 467 /* [ No args] */ 468 inst_opt_noaskcalib = 0x000B, /* Proceed with calibration immediately if possible */ 469 /* [ No args] */ 470 471 inst_opt_set_ccss_obs = 0x000C, /* Set the observer used with ccss device types - */ 472 /* Not applicable to any other type of instrument. */ 473 /* [args: icxObserverType obType,*/ 474 /* xspect custObserver[3] */ 475 476 inst_opt_set_filter = 0x000D, /* Set a filter configuration */ 477 /* [1 argument type inst_opt_filter] */ 478 479 inst_opt_trig_prog = 0x000E, /* Trigger progromatically [No args] */ 480 inst_opt_trig_user = 0x000F, /* Trigger from user via uicallback [No args] */ 481 inst_opt_trig_switch = 0x0010, /* Trigger directly using instrument switch [No args] */ 482 inst_opt_trig_user_switch = 0x0011, /* Trigger from user via uicallback or switch (def) [No args] */ 483 484 inst_opt_highres = 0x0012, /* Enable high res spectral mode indep. of set_mode() */ 485 inst_opt_stdres = 0x0013, /* Revert to standard resolution spectral mode */ 486 487 inst_opt_scan_toll = 0x0014, /* Modify the patch scan recognition tollnce [double] */ 488 489 inst_opt_get_gen_ledmask = 0x0015, /* Get the bitmask for general indication LEDs [*int] */ 490 /* (More specialized indicator masks go here) */ 491 inst_opt_set_led_state = 0x0016, /* Set the current LED state. 0 = off, 1 == on [int] */ 492 inst_opt_get_led_state = 0x0017, /* Get the current LED state. 0 = off, 1 == on [*int] */ 493 inst_opt_get_pulse_ledmask = 0x0018, /* Get the bitmask for pulseable ind. LEDs [*int] */ 494 inst_opt_set_led_pulse_state= 0x0019, /* Set the current LED state. [double period_in_secs, */ 495 /* double on_time_prop, double trans_time_prop] */ 496 inst_opt_get_led_pulse_state= 0x001A, /* Get the current pulse LED state. [*double period] */ 497 inst_opt_get_target_state = 0x001B, /* Get the aiming target state 0 = off, 1 == on [*int] */ 498 inst_opt_set_target_state = 0x001C, /* Set the aiming target state 0 = off, 1 == on, 2 = toggle [int] */ 499 500 inst_opt_get_min_int_time = 0x001D, /* Get the minimum integration time [*double time] */ 501 inst_opt_set_min_int_time = 0x001E, /* Set the minimum integration time [double time] */ 502 503 inst_opt_opt_calibs_valid = 0x001F, /* Are optional (white/black/gloss etc.) calibrations */ 504 /* valid? [*int valid] */ 505 inst_opt_clear_opt_calibs = 0x0020, /* Clear all optional calibrations. */ 506 507 inst_opt_get_cal_tile_sp = 0x0021, /* Return refl. white tile reference spectrum. */ 508 /* for current filter. [*xspect tile] */ 509 510 inst_opt_set_xcalstd = 0x0022, /* Set the X-Rite reflective calibration standard */ 511 /* [xcalstd standard] */ 512 inst_opt_get_xcalstd = 0x0023, /* Get the effective X-Rite ref. cal. standard */ 513 /* [xcalstd *standard] */ 514 inst_opt_lamp_remediate = 0x0024 /* Remediate i1Pro lamp [double seconds] */ 515 516 517 } inst_opt_type; 518 519 /* Optional filter fitted to instrument (for inst_opt_set_filter) */ 520 /* Set this before calling init_coms() */ 521 typedef enum { 522 inst_opt_filter_unknown = 0xffff, /* Unspecified filter */ 523 inst_opt_filter_none = 0x0000, /* No filters fitted */ 524 inst_opt_filter_pol = 0x0001, /* Polarising filter */ 525 inst_opt_filter_D65 = 0x0002, /* D65 Illuminant filter */ 526 inst_opt_filter_UVCut = 0x0004, /* U.V. Cut filter */ 527 inst_opt_filter_Custom = 0x0008 /* Custom Filter */ 528 } inst_opt_filter; 529 530 /* Off-line pending readings available (status) */ 531 typedef enum { 532 inst_stat_savdrd_none = 0x00, /* No saved readings */ 533 inst_stat_savdrd_spot = 0x01, /* There are saved spot readings available */ 534 inst_stat_savdrd_strip = 0x02, /* There are saved strip readings available */ 535 inst_stat_savdrd_xy = 0x04, /* There are saved page readings available */ 536 inst_stat_savdrd_chart = 0x08 /* There are saved chart readings available */ 537 } inst_stat_savdrd; 538 539 /* Type of calibration needed/available/requested - corresponds to capabilities */ 540 /* [ inst_calt_trans_vwhite is "variable" white transmission calibration, needed */ 541 /* where transmission mode is being emulated. ] */ 542 /* Remember to update calt2str() */ 543 typedef enum { 544 /* Response to needs_calibration() */ 545 inst_calt_none = 0x00000000, /* No calibration or unknown */ 546 547 /* Psudo-calibration types */ 548 inst_calt_all = 0x00000001, /* Do required non-deferable cals for mode, but also */ 549 /* do all possible calibrations for all other modes */ 550 /* using the calibration conditions. This may be slow */ 551 /* Hmm. We don't have an "calt_all_needed" - do all needed cals of all possible modes. */ 552 /* This might be more useful than inst_calt_all ? */ 553 inst_calt_needed = 0x00000002, /* Do all required non-deferable cals for c.m. */ 554 inst_calt_available = 0x00000003, /* Do all available non-deferable cals for c.m. */ 555 556 /* Specific type of calibration - corresponds to capabilities */ 557 inst_calt_wavelength = 0x00000010, /* Wavelength calibration using refl. cal. surface */ 558 inst_calt_ref_white = 0x00000020, /* Reflective white/emissive dark calibration */ 559 inst_calt_ref_dark = 0x00000040, /* Reflective dark calibration (light trap) */ 560 inst_calt_ref_dark_gl = 0x00000080, /* Reflective gloss calibration (black gloss surface) */ 561 inst_calt_emis_offset = 0x00000100, /* Emissive offset/black calibration (dark surface) */ 562 inst_calt_emis_ratio = 0x00000200, /* Emissive ratio calibration */ 563 inst_calt_em_dark = 0x00000400, /* Emissive dark calibration (in dark) */ 564 inst_calt_trans_white = 0x00000800, /* Transmissive white reference calibration */ 565 inst_calt_trans_vwhite = 0x00001000, /* Transmissive variable white reference calibration */ 566 inst_calt_trans_dark = 0x00002000, /* Transmissive dark reference calibration */ 567 568 inst_calt_n_dfrble_mask = 0x0000fff0, /* Mask of non-deferrable calibrations */ 569 570 /* Calibrations that might be deferred until measurement */ 571 inst_calt_emis_int_time = 0x00100000, /* Emissive measurement range (integration time) */ 572 inst_calt_ref_freq = 0x00200000, /* Display refresh frequency calibration */ 573 574 inst_calt_dfrble_mask = 0x00f00000, /* Mask of deferrable calibrations */ 575 576 inst_calt_all_mask = 0x00f0fff0, /* Mask of all specific calibrations */ 577 578 inst_calt_ap_flag = 0x80000000 /* Implementation flag indicating do all possible */ 579 580 } inst_cal_type; 581 582 /* Return a description of the first calibration type */ 583 char *calt2str(inst_cal_type calt); 584 585 /* Calibration conditions. */ 586 /* This is how the instrument communicates to the calling program */ 587 /* about how to facilitate a calibration, or what it's current measurement */ 588 /* configuration provides. */ 589 /* [There is no provission for explictly indicating calibrations that can be */ 590 /* performed automatically and transparently by the instrument - for instance */ 591 /* in the case of the spectroscan, since the required condition can be obtained */ 592 /* without the users interaction. ] */ 593 typedef enum { 594 inst_calc_none = 0x00000000, /* Not suitable for calibration */ 595 inst_calc_unknown = 0xffffffff, /* Unknown calibration setup */ 596 597 /* uop means that user has to trigger the within instrument */ 598 /* calibration using its "front panel" or other direct keys */ 599 inst_calc_uop_ref_white = 0x00000001, /* user operated reflective white calibration */ 600 inst_calc_uop_trans_white = 0x00000002, /* user operated tranmissive white calibration */ 601 inst_calc_uop_trans_dark = 0x00000003, /* user operated tranmissive dark calibration */ 602 inst_calc_uop_mask = 0x0000000F, /* user operated calibration mask */ 603 604 /* Man means that the user has to manualy configure the instrument */ 605 /* to be on the correct reference for the software triggered cal. */ 606 inst_calc_man_ref_white = 0x00000010, /* place instrument on reflective white reference */ 607 inst_calc_man_ref_whitek = 0x00000020, /* click instrument on reflective white reference */ 608 inst_calc_man_ref_dark = 0x00000030, /* place instrument on light trap */ 609 inst_calc_man_dark_gloss = 0x00000040, /* place instrument on gloss black reference */ 610 inst_calc_man_em_dark = 0x00000050, /* place cap on instrument, put on dark surface or white ref. */ 611 inst_calc_man_am_dark = 0x00000060, /* Place cap over ambient sensor (wl calib capable) */ 612 inst_calc_man_cal_smode = 0x00000070, /* Put instrument sensor in calibration position */ 613 614 inst_calc_man_trans_white = 0x00000080, /* place instrument on transmissive white reference */ 615 inst_calc_man_trans_dark = 0x00000090, /* place instrument on transmissive dark reference */ 616 inst_calc_man_man_mask = 0x000000F0, /* user configured calibration mask */ 617 618 inst_calc_emis_white = 0x00000100, /* Provide a white test patch */ 619 inst_calc_emis_80pc = 0x00000200, /* Provide an 80% white test patch */ 620 inst_calc_emis_grey = 0x00000300, /* Provide a grey test patch */ 621 inst_calc_emis_grey_darker = 0x00000400, /* Provide a darker grey test patch */ 622 inst_calc_emis_grey_ligher = 0x00000500, /* Provide a darker grey test patch */ 623 624 inst_calc_emis_mask = 0x00000F00, /* Emmissive/display provided reference patch */ 625 626 inst_calc_change_filter = 0x00010000, /* Filter needs changing on device - see id[] */ 627 inst_calc_message = 0x00020000, /* Issue a message. - see id[] */ 628 629 inst_calc_cond_mask = 0x0fffffff, /* Mask for conditions (i.e. remove flags) */ 630 631 inst_calc_optional_flag = 0x80000000 /* Flag indicating calibration can be skipped */ 632 633 } inst_cal_cond; 634 635 /* Condition identifier message type. This can be useful in internationalizing the */ 636 /* string returned in id[] from calibrate() */ 637 typedef enum { 638 inst_calc_id_none = 0x00000000, /* No id */ 639 inst_calc_id_ref_sn = 0x00000001, /* Calibration reference (ie. tile) serial number */ 640 641 inst_calc_id_trans_low = 0x00010000, /* Trans. Ref. light is too low for accuracy warning */ 642 inst_calc_id_trans_wl = 0x00020000, /* Trans. Ref. light is low at some wavelengths warning */ 643 inst_calc_id_filt_unkn = 0x00100000, /* Request unknown filter */ 644 inst_calc_id_filt_none = 0x00200000, /* Request no filter */ 645 inst_calc_id_filt_pol = 0x00300000, /* Request polarizing filter */ 646 inst_calc_id_filt_D65 = 0x00400000, /* Request D65 filter */ 647 inst_calc_id_filt_UV = 0x00500000, /* Request UV cut filter */ 648 inst_calc_id_filt_cust = 0x00600000 /* Request custom filter */ 649 } inst_calc_id_type; 650 651 /* Clamping state */ 652 typedef enum { 653 instNoClamp = 0, /* Don't clamp XYZ/Lab to +ve */ 654 instClamp = 1, /* Clamp XYZ/Lab to +ve */ 655 } instClamping; 656 657 /* User interaction callback (uicallback()) function purpose */ 658 typedef enum { 659 inst_negcoms, /* Negotiating communications - can abort */ 660 inst_armed, /* Armed and waiting for a measurement trigger - can wait, trigger, abort */ 661 inst_triggered, /* Measurement triggered by switch or user (not progromatic) - notice */ 662 /* (Also triggered by switch driven calibration,i.e. DTP41) */ 663 inst_measuring /* Busy measuring - can abort */ 664 } inst_ui_purp; 665 666 /* Asynchronous event callback type */ 667 typedef enum { 668 inst_event_switch, /* Instrument measure/calibrate switch pressed. */ 669 inst_event_mconf, /* Change in measurement configuration (ie. sensor position) */ 670 inst_event_scan_ready /* Ready for manual strip scan (i.e. issue audible prompt) */ 671 } inst_event_type; 672 673 /* Instrument configuration/sensor position*/ 674 typedef enum { 675 inst_conf_unknown, 676 inst_conf_projector, 677 inst_conf_surface, 678 inst_conf_emission, 679 inst_conf_calibration, 680 inst_conf_ambient 681 } inst_config; 682 683 # define EXRA_INST_OBJ 684 685 /* Off-line pending readings available (status) */ 686 #define CALIDLEN 200 /* Maxumum length of calibration tile ID string */ 687 688 /* Color instrument interface base object */ 689 /* Note that some methods work after creation, while many */ 690 /* will return an error if communications hasn't been established and */ 691 /* the instrument initialised. Some may change their response before and */ 692 /* after initialisation. */ 693 #define INST_OBJ_BASE \ 694 \ 695 EXRA_INST_OBJ \ 696 a1log *log; /* Pointer to debug & error logging class */ \ 697 instType itype; /* Instrument type determined by driver */ \ 698 icoms *icom; /* Instrument coms object */ \ 699 int gotcoms; /* Coms established flag */ \ 700 int inited; /* Instrument open and initialized flag */ \ 701 double cal_gy_level; /* Display calibration test window state */ \ 702 int cal_gy_count; /* Display calibration test window state */ \ 703 inst_code (*uicallback)(void *cntx, inst_ui_purp purp); \ 704 void *uic_cntx; /* User interaction callback function */ \ 705 void (*eventcallback)(void *cntx, inst_event_type event); \ 706 void *event_cntx; /* Asynchronous event callback function */ \ 707 athread *scan_ready_thread; /* msec_scan_ready() support */ \ 708 int scan_ready_delay; /* msec_scan_ready() support */ \ 709 \ 710 /* Virtual delete. Cleans up things done by new_inst(). */ \ 711 inst_code (*vdel)( \ 712 struct _inst *p); \ 713 \ 714 /* Establish communications at the indicated baud rate. */ \ 715 /* (Serial parameters are ignored for USB instrument) */ \ 716 /* Timout in to seconds, and return non-zero error code */ \ 717 inst_code (*init_coms)( \ 718 struct _inst *p, \ 719 baud_rate br, /* Baud rate */ \ 720 flow_control fc, /* Flow control */ \ 721 double tout); /* Timeout */ \ 722 \ 723 /* Initialise or re-initialise the INST */ \ 724 /* return non-zero on an error, with inst error code */ \ 725 inst_code (*init_inst)( \ 726 struct _inst *p); \ 727 \ 728 /* Return the instrument type */ \ 729 /* (this could concievably change after init_inst()) */ \ 730 /* Can be called before init */ \ 731 instType (*get_itype)( \ 732 struct _inst *p); \ 733 \ 734 /* Return the instrument serial number. */ \ 735 /* (This will be an empty string if there is no serial no) */ \ 736 char *(*get_serial_no)( \ 737 struct _inst *p); \ 738 \ 739 /* Return the avilable instrument modes and capabilities. */ \ 740 /* Can be called before init, but may be different to */ \ 741 /* what's returned after initilisation. */ \ 742 /* Note that these may change with the mode. */ \ 743 /* Arguments may be NULL */ \ 744 void (*capabilities)(struct _inst *p, \ 745 inst_mode *cap1, \ 746 inst2_capability *cap2, \ 747 inst3_capability *cap3); \ 748 \ 749 /* Return current or given configuration available measurement modes. */ \ 750 /* Most instruments have only one detectable configuration. */ \ 751 /* If conf_ix == NULL or *conf_ix is an invalid configuration index, */ \ 752 /* then the current configuration modes are returned. */ \ 753 /* Otherwise the given configuration index is returned. */ \ 754 /* The i1d3 has 2, the Munki has 4, one being calibration. */ \ 755 /* *cconds is valid if *mmodes = inst_mode_calibration */ \ 756 inst_code (*meas_config)(struct _inst *p, \ 757 inst_mode *mmodes, /* Return all the valid measurement modes */ \ 758 /* for the current configuration */ \ 759 inst_cal_cond *cconds, /* Return the valid calibration conditions */ \ 760 int *conf_ix); /* Request mode for given configuration, and */ \ 761 /* return the index of the configuration returned */ \ 762 \ 763 /* Check that the particular device measurement mode is valid, */ \ 764 /* since it's not possible to be 100% sure from capabilities */ \ 765 inst_code (*check_mode)( \ 766 struct _inst *p, \ 767 inst_mode m); /* Requested mode */ \ 768 \ 769 /* Set the device measurement mode */ \ 770 /* Note that this may change the capabilities. */ \ 771 inst_code (*set_mode)( \ 772 struct _inst *p, \ 773 inst_mode m); /* Requested mode */ \ 774 \ 775 /* Return array of display type selectors */ \ 776 inst_code (*get_disptypesel)( \ 777 struct _inst *p, \ 778 int *no_selectors, /* Return number of display types */ \ 779 inst_disptypesel **sels,/* Return the array of display types */ \ 780 int allconfig, /* nz to return list for all configs, not just current. */ \ 781 int recreate); /* nz to re-check for new ccmx & ccss files */ \ 782 \ 783 /* Set the display type or calibration mode. */ \ 784 /* index is into the inst_disptypesel[] returned */ \ 785 /* returned by get_disptypesel(). clears col_cor_mat() and */ \ 786 /* col_cal_spec_set(). */ \ 787 inst_code (*set_disptype)( \ 788 struct _inst *p, \ 789 int index); \ 790 \ 791 /* Get the disptech and other corresponding info for the current */ \ 792 /* selected display type or calibration mode. Returns disptype_unknown */ \ 793 /* by default. Because refrmode can be overridden, it may not */ \ 794 /* match the refrmode of the dtech. */ \ 795 /* (Pointers may be NULL if not needed) */ \ 796 inst_code (*get_disptechi)( \ 797 struct _inst *p, \ 798 disptech *dtech, \ 799 int *refrmode, \ 800 int *cbid); \ 801 \ 802 /* Get a status or get or set an option */ \ 803 /* option state. */ \ 804 /* Some options can be set before init */ \ 805 /* See inst_opt_type typedef for list of mode types */ \ 806 inst_code (*get_set_opt)( \ 807 struct _inst *p, \ 808 inst_opt_type m, /* Requested option mode */ \ 809 ...); /* Option parameters */ \ 810 \ 811 /* Read a full test chart composed of multiple sheets */ \ 812 /* DOESN'T use the trigger mode */ \ 813 /* Return the inst error code */ \ 814 inst_code (*read_chart)( \ 815 struct _inst *p, \ 816 int npatch, /* Total patches/values in chart */ \ 817 int pich, /* Passes (rows) in chart */ \ 818 int sip, /* Steps in each pass (patches in each row) */ \ 819 int *pis, /* Passes in each strip (rows in each sheet) */ \ 820 int chid, /* Chart ID number */ \ 821 ipatch *vals); /* Pointer to array of values */ \ 822 \ 823 \ 824 /* For an xy instrument, release the paper */ \ 825 /* (if cap has inst_xy_holdrel) */ \ 826 /* Return the inst error code */ \ 827 inst_code (*xy_sheet_release)( \ 828 struct _inst *p); \ 829 \ 830 /* For an xy instrument, hold the paper */ \ 831 /* (if cap has inst_xy_holdrel) */ \ 832 /* Return the inst error code */ \ 833 inst_code (*xy_sheet_hold)( \ 834 struct _inst *p); \ 835 \ 836 /* For an xy instrument, allow the user to locate a point */ \ 837 /* (if cap has inst_xy_locate) */ \ 838 /* Return the inst error code */ \ 839 inst_code (*xy_locate_start)( \ 840 struct _inst *p); \ 841 \ 842 /* For an xy instrument, read back the location */ \ 843 /* (if cap has inst_xy_locate) */ \ 844 /* Return the inst error code */ \ 845 inst_code (*xy_get_location)( \ 846 struct _inst *p, \ 847 double *x, double *y); \ 848 \ 849 /* For an xy instrument, end allowing the user to locate a point */ \ 850 /* (if cap has inst_xy_locate) */ \ 851 /* Return the inst error code */ \ 852 inst_code (*xy_locate_end)( \ 853 struct _inst *p); \ 854 \ 855 /* For an xy instrument, move the measurement point */ \ 856 /* (if cap has inst_xy_position) */ \ 857 /* Return the inst error code */ \ 858 inst_code (*xy_position)( \ 859 struct _inst *p, \ 860 int measure, /* nz for measure point, z for locate point */ \ 861 double x, double y); \ 862 \ 863 /* For an xy instrument, try and clear the table after an abort */ \ 864 /* Return the inst error code */ \ 865 inst_code (*xy_clear)( \ 866 struct _inst *p); \ 867 \ 868 /* Read a sheet full of patches using xy mode */ \ 869 /* DOESN'T use the trigger mode */ \ 870 /* Return the inst error code */ \ 871 inst_code (*read_xy)( \ 872 struct _inst *p, \ 873 int pis, /* Passes in strips (letters in sheet) */ \ 874 int sip, /* Steps in pass (numbers in sheet) */ \ 875 int npatch, /* Total patches in strip (skip in last pass) */ \ 876 char *pname, /* Starting pass name (' A' to 'ZZ') */ \ 877 char *sname, /* Starting step name (' 1' to '99') */ \ 878 double ox, double oy, /* Origin of first patch */ \ 879 double ax, double ay, /* pass increment */ \ 880 double aax, double aay, /* pass offset for odd patches */ \ 881 double px, double py, /* step/patch increment */ \ 882 ipatch *vals); /* Pointer to array of values */ \ 883 \ 884 \ 885 /* Read a set of strips (applicable to strip reader) */ \ 886 /* Obeys the trigger mode set, and may return user trigger code, */ \ 887 /* to hint that a user command may be available. */ \ 888 /* Return the inst error code */ \ 889 inst_code (*read_strip)( \ 890 struct _inst *p, \ 891 char *name, /* Strip name (up to 7 chars, for DTP51) */ \ 892 int npatch, /* Number of patches in each pass */ \ 893 char *pname, /* Pass name (3 chars, for DTP51) */ \ 894 int sguide, /* Guide number (for DTP51, decrements by 5) */ \ 895 double pwid, /* Patch width in mm (For DTP20/DTP41) */ \ 896 double gwid, /* Gap width in mm (For DTP20/DTP41) */ \ 897 double twid, /* Trailer width in mm (For DTP41T) */ \ 898 ipatch *vals); /* Pointer to array of values */ \ 899 \ 900 \ 901 /* Read a single sample (applicable to spot instruments) */ \ 902 /* Obeys the trigger mode set, and may return user trigger code */ \ 903 /* Values are in XYZ % (0..100) for reflective & transmissive, */ \ 904 /* cd/m^2 for emissive, and Lux for ambient. */ \ 905 /* Spectral will be analogous to the XYZ (see inst_meas_type). */ \ 906 /* By default values may be -ve due to noise (depending on instrument) */ \ 907 /* Return the inst error code */ \ 908 inst_code (*read_sample)( \ 909 struct _inst *p, \ 910 char *name, /* Patch identifier (up to 7 chars) */ \ 911 ipatch *val, /* Pointer to value to be returned */ \ 912 instClamping clamp); /* NZ to clamp XYZ to be +ve */ \ 913 \ 914 /* Measure the emissive refresh rate in Hz. */ \ 915 /* (Available if cap2 & inst2_emis_refr_meas) */ \ 916 /* Returns: */ \ 917 /* inst_unsupported - if this instrument doesn't suport this measuremet */ \ 918 /* or not in an emissive measurement mode */ \ 919 /* inst_misread - if no refresh rate could be determined */ \ 920 /* inst_ok - on returning a valid reading */ \ 921 inst_code (*read_refrate)( \ 922 struct _inst *p, \ 923 double *ref_rate); /* Return the Hz */ \ 924 \ 925 /* Determine if a calibration is needed. Returns inst_calt_none if not */ \ 926 /* or unknown, or a mask of the needed calibrations. */ \ 927 /* This call checks if calibrations are invalid or have timed out. */ \ 928 /* With the exception of instruments with automated calibration */ \ 929 /* (ie. SpectroScan), an instrument will typically */ \ 930 /* not check for calibration timout any other way. */ \ 931 /* [What's returned is the same as get_n_a_cals() [ needed_calibrations.] */\ 932 inst_cal_type (*needs_calibration)( \ 933 struct _inst *p); \ 934 \ 935 /* Return combined mask of needed and available inst_cal_type's */ \ 936 /* for the current mode. */ \ 937 inst_code (*get_n_a_cals)( \ 938 struct _inst *p, \ 939 inst_cal_type *needed_calibrations, \ 940 inst_cal_type *available_calibrations); \ 941 \ 942 /* Request an instrument calibration. */ \ 943 /* This is use if the user decides they want to do a calibration */ \ 944 /* in anticipation of a calibration (needs_calibration()) to avoid */ \ 945 /* requiring one during measurement, or in response to measuring */ \ 946 /* returning inst_needs_cal before retrying the measurement, */ \ 947 /* or to do one or more re-calibrations. */ \ 948 \ 949 /* *calt should contain the mask of calibrations to be performed, */ \ 950 /* with *calc set to the current calibration condition. */ \ 951 /* Alternately, one of the psudo-calibration types inst_calt_all, */ \ 952 /* inst_calt_needed or inst_calt_available can be used, */ \ 953 /* and/or the *calc of inst_calc_none to get calibrate() */ \ 954 /* to determine the required calibration types and conditions. */ \ 955 /* (The corresponding calibration types will be used & returned. */ \ 956 \ 957 /* If no error is returned to the first call to calibrate() */ \ 958 /* then the instrument was capable of calibrating without user or */ \ 959 /* application intervention. If on the other hand calibrate() returns */ \ 960 /* inst_cal_setup, then the appropriate action indicated by the value */ \ 961 /* returned in *calc should be taken by the user or application, */ \ 962 /* before retrying calibration() with the current setup indicated */ \ 963 /* by *calc. If more than one calibration type is requested, then */ \ 964 /* several retries may be needed with different calibration conditions. */ \ 965 /* Each call to calibrate() will update *calt to reflect the remaining */ \ 966 /* calibration to be performed. calibrate() returns inst_ok when no */ \ 967 /* more calibrations remain. */ \ 968 \ 969 /* If the calc has the inst_calc_optional_flag flag set, */ \ 970 /* then the user should be offered the option of skipping the */ \ 971 /* calibration. If they decide to skip it, return a calc with */ \ 972 /* inst_calc_optional_flag set, and if they want to proceed, */ \ 973 /* make sure the inst_calc_optional_flag is cleared in the returned */ \ 974 /* calc. */ \ 975 \ 976 /* DOESN'T use the trigger mode */ \ 977 /* Return inst_unsupported if *calt is not appropriate, */ \ 978 /* inst_cal_setup if *calc is not appropriate. */ \ 979 inst_code (*calibrate)( \ 980 struct _inst *p, \ 981 inst_cal_type *calt, /* Calibration type to do/remaining */ \ 982 inst_cal_cond *calc, /* Current condition/desired condition */ \ 983 inst_calc_id_type *idtype, /* Condition identifier type */ \ 984 char id[CALIDLEN]); /* Condition identifier (ie. white */ \ 985 /* reference ID, filter ID, message string, */ \ 986 /* etc.) */ \ 987 \ 988 /* Measure a display update, and instrument reaction time. It is */ \ 989 /* assumed that a white to black change will be made to the */ \ 990 /* displayed color during this call, and this is used to measure */ \ 991 /* the time it took for the update to be noticed by the instrument, */ \ 992 /* up to 1.0 second. */ \ 993 /* The instrument reaction time accounts for the time between */ \ 994 /* when the measure function is called and the samples actually being */ \ 995 /* taken. This value may be negative if there is a filter delay. */ \ 996 /* The method white_change() should be called with init=1 before */ \ 997 /* calling meas_delay, and then with init=0 during the meas_delay() */ \ 998 /* call to timestamp the transition. */ \ 999 /* Note that a default instmsec will be returned even on error. */ \ 1000 inst_code (*meas_delay)( \ 1001 struct _inst *p, \ 1002 int *dispmsec, /* Return display update delay in msec */ \ 1003 int *instmsec); /* Return instrument reaction time in msec */ \ 1004 \ 1005 /* Call used by other thread to timestamp the patch transition. */ \ 1006 inst_code (*white_change)( \ 1007 struct _inst *p, \ 1008 int init); /* nz to init time stamp, z to mark transition */ \ 1009 \ 1010 /* Return the last calibrated refresh rate in Hz. Returns: */ \ 1011 /* (Available if cap2 & inst2_get_refresh_rate) */ \ 1012 /* inst_unsupported - if this instrument doesn't suport a refresh mode */ \ 1013 /* or is unable to retrieve the refresh rate */ \ 1014 /* inst_needs_cal - if the refresh rate value is not valid */ \ 1015 /* inst_misread - if no refresh rate could be determined */ \ 1016 /* inst_ok - on returning a valid reading */ \ 1017 inst_code (*get_refr_rate)( \ 1018 struct _inst *p, \ 1019 double *ref_rate); /* Return the Hz */ \ 1020 \ 1021 /* Set the calibrated refresh rate in Hz. */ \ 1022 /* (Available if cap2 & inst2_set_refresh_rate) */ \ 1023 /* Set refresh rate to 0.0 to mark it as invalid */ \ 1024 /* Rates outside the range 5.0 to 150.0 Hz will return an error */ \ 1025 /* Note that not all instruments that can return a refresh rate, */ \ 1026 /* will permit one to be set (ie., DTP92) */ \ 1027 inst_code (*set_refr_rate)( \ 1028 struct _inst *p, \ 1029 double ref_rate); /* Rate in Hz */ \ 1030 \ 1031 /* Insert a compensation filter in the instrument readings */ \ 1032 /* This is typically needed if an adapter is being used, that alters */ \ 1033 /* the spectrum of the light reaching the instrument */ \ 1034 /* Not fully implemented across all instrument types (spectrolino only ?) */ \ 1035 /* To remove the filter, pass NULL for the filter filename */ \ 1036 inst_code (*comp_filter)( \ 1037 struct _inst *p, \ 1038 char *filtername); /* File containing compensating filter */ \ 1039 \ 1040 /* Insert a colorimetric correction matrix in the instrument XYZ readings */ \ 1041 /* This is only valid for colorimetric instruments, and can only be */ \ 1042 /* applied over a base calibration display type. Setting a display */ \ 1043 /* type will clear the matrix. */ \ 1044 /* To clear the matrix, pass NULL for the matrix */ \ 1045 inst_code (*col_cor_mat)( \ 1046 struct _inst *p, \ 1047 disptech dtech, /* Use disptech_unknown if not known */ \ 1048 int cbid, /* Calibration display type base ID, needed 1 if unknown */\ 1049 double mtx[3][3]); /* XYZ matrix */ \ 1050 \ 1051 /* Use a Colorimeter Calibration Spectral Set (ccss) to set the */ \ 1052 /* instrumen calibration. This will affect emissive readings. */ \ 1053 /* An alternate observer may also be set, and this will affect both */ \ 1054 /* emissive and ambient readings. */ \ 1055 /* This is only valid for colorimetric instruments. */ \ 1056 /* To set calibration back to default, pass NULL for sets, and */ \ 1057 /* icxOT_default for the observer. */ \ 1058 inst_code (*col_cal_spec_set)( \ 1059 struct _inst *p, \ 1060 disptech dtech, /* Use disptech_unknown if not known */ \ 1061 xspect *sets, /* Set of sample spectra */ \ 1062 int no_sets); /* Number on set */ \ 1063 \ 1064 /* Supply a user interaction callback function. \ 1065 * This is called for one of three different purposes: \ 1066 * To signal that the instrument measurement has been triggered. \ 1067 * To poll for an abort while waiting to trigger. \ 1068 * To poll for a user abort during measurement. \ 1069 * \ 1070 * The callback function will have the purpose paramater appropriately. \ 1071 * \ 1072 * For inst_negcoms, the return value of inst_user_abort \ 1073 * will abort the communication negotiation. \ 1074 * \ 1075 * For inst_armed return value should be one of: \ 1076 * inst_ok to do nothing, inst_user_abort to abort the measurement, \ 1077 * or inst_user_trig to trigger the measurement. \ 1078 * \ 1079 * For inst_triggered, the return value of the callback is ignored. \ 1080 * \ 1081 * For inst_measuring the return value should be one of: \ 1082 * inst_ok to do nothing, inst_user_abort to abort the measurement. \ 1083 * \ 1084 * NULL can be set to disable the callback. \ 1085 */ \ 1086 void (*set_uicallback)(struct _inst *p, \ 1087 inst_code (*uicallback)(void *cntx, inst_ui_purp purp), \ 1088 void *cntx); \ 1089 \ 1090 /* Supply an aynchronous event callback function. \ 1091 * This is called from a different thread with the following possible events: \ 1092 * \ 1093 * inst_event_switch: Instrument measure/calibrate switch pressed \ 1094 * inst_event_mconf: The measurement configuration has changed (ie. sensor position) \ 1095 * inst_event_scan_ready: Ready for manual strip scan (i.e. issue audible prompt) \ 1096 * \ 1097 * NULL can be set to disable the callback. \ 1098 */ \ 1099 void (*set_event_callback)(struct _inst *p, \ 1100 void (*eventcallback)(void *cntx, inst_event_type event), \ 1101 void *cntx); \ 1102 \ 1103 /* Generic inst error codes interpretation */ \ 1104 char * (*inst_interp_error)(struct _inst *p, inst_code ec); \ 1105 \ 1106 /* Instrument specific error codes interpretation */ \ 1107 char * (*interp_error)(struct _inst *p, int ec); \ 1108 \ 1109 /* Convert instrument specific inst_wrong_config error to inst_config enum */ \ 1110 inst_config (*config_enum)(struct _inst *p, int ec); \ 1111 \ 1112 /* Return the last serial communication error code */ \ 1113 /* (This is used for deciding fallback/retry strategies) */ \ 1114 int (*last_scomerr)(struct _inst *p); \ 1115 \ 1116 /* Destroy ourselves */ \ 1117 void (*del)(struct _inst *p); \ 1118 1119 /* The base object type */ 1120 struct _inst { 1121 INST_OBJ_BASE 1122 }; typedef struct _inst inst; 1123 1124 /* Virtual constructor. */ 1125 /* Return NULL for unknown instrument, */ 1126 /* or serial instrument if nocoms == 0. */ 1127 /* (Doesn't copy icompaths log!) */ 1128 /* If uicallback is provided, it will be set in the resulting inst */ 1129 extern inst *new_inst( 1130 icompath *path, /* Device path this instrument */ 1131 int nocoms, /* Don't open if communications are needed to establish inst type */ 1132 a1log *log, /* Log to use */ 1133 inst_code (*uicallback)(void *cntx, inst_ui_purp purp), /* optional uicallback */ 1134 void *cntx /* Context for callback */ 1135 ); 1136 1137 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 1138 /* Implementation functions used by instrument drivers */ 1139 /* (Client code should not call these) */ 1140 1141 /* Get a status or set or get an option (default implementation) */ 1142 inst_code inst_get_set_opt_def( 1143 inst *p, 1144 inst_opt_type m, /* Option type */ 1145 va_list args); /* Option parameters */ 1146 1147 /* - - - - - - - - - - - - - - - - - - -- */ 1148 1149 /* Create the display type list */ 1150 inst_code inst_creat_disptype_list(inst *p, 1151 int *pndtlist, /* Number in returned list */ 1152 inst_disptypesel **pdtlist, /* Returned list */ 1153 inst_disptypesel *sdtlist, /* Static list */ 1154 int doccss, /* Add installed ccss files */ 1155 int doccmx /* Add matching installed ccmx files */ 1156 ); 1157 1158 /* Free a display type list */ 1159 void inst_del_disptype_list(inst_disptypesel *list, int no); 1160 1161 /* - - - - - - - - - - - - - - - - - - -- */ 1162 1163 /* Issue an inst_event_scan_ready event after a delay */ 1164 void issue_scan_ready(inst *p, int delay); 1165 1166 /* - - - - - - - - - - - - - - - - - - -- */ 1167 /* CCMX support - ccmx instrument proxy */ 1168 1169 typedef struct { 1170 char *path; /* Path to the file */ 1171 char *desc; /* Technology + display description */ 1172 disptech dtech; /* Display Technology enumeration (optional if disp) */ 1173 int cc_cbid; /* Calibration display type base ID required */ 1174 int refr; /* Refresh mode flag */ 1175 char *sel; /* UI selector characters (may be NULL) */ 1176 int oem; /* nz if oem origin */ 1177 double mat[3][3]; /* The matrix values */ 1178 } iccmx; 1179 1180 /* return a list of installed ccmx files. */ 1181 /* if itype != instUnknown, return those that match the given instrument. */ 1182 /* The list is sorted by description and terminated by a NULL entry. */ 1183 /* If no is != NULL, return the number in the list */ 1184 /* Return NULL and -1 if there is a malloc error */ 1185 iccmx *list_iccmx(instType itype, int *no); 1186 1187 /* Free up a iccmx list */ 1188 void free_iccmx(iccmx *list); 1189 1190 /* - - - - - - - - - - - - - - - - - - -- */ 1191 /* CCSS support - ccss instrument proxy */ 1192 1193 typedef struct { 1194 char *path; /* Path to the file */ 1195 char *desc; /* Technology + display description */ 1196 disptech dtech; /* Display Technology enumeration (optional if disp) */ 1197 int refr; /* Refresh mode flag */ 1198 char *sel; /* UI selector characters (may be NULL) */ 1199 int oem; /* nz if oem origin */ 1200 xspect *sets; /* Set of sample spectra */ 1201 int no_sets; /* Number on set */ 1202 } iccss; 1203 1204 /* return a list of installed ccss files. */ 1205 /* The list is sorted by description and terminated by a NULL entry. */ 1206 /* If no is != NULL, return the number in the list */ 1207 /* Return NULL and -1 if there is a malloc error */ 1208 iccss *list_iccss(int *no); 1209 1210 /* Free up a iccss list */ 1211 void free_iccss(iccss *list); 1212 1213 /* - - - - - - - - - - - - - - - - - - -- */ 1214 1215 #ifdef __cplusplus 1216 } 1217 #endif 1218 1219 1220 #define INST_H 1221 #endif /* INST_H */ 1222