From 22f703cab05b7cd368f4de9e03991b7664dc5022 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Mon, 1 Sep 2014 13:56:46 +0200 Subject: Initial import of argyll version 1.5.1-8 --- spectro/inst.h | 999 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 999 insertions(+) create mode 100644 spectro/inst.h (limited to 'spectro/inst.h') diff --git a/spectro/inst.h b/spectro/inst.h new file mode 100644 index 0000000..5b5d710 --- /dev/null +++ b/spectro/inst.h @@ -0,0 +1,999 @@ + +#ifndef INST_H + + /* instlib API definition. */ + + /* See spotread.c, chartread.c, illumread.c & ccxxmake.c for examples of */ + /* the API usage. */ + + /* Abstract base class for common color instrument interface */ + /* and other common instrument stuff. */ + +/* + * Argyll Color Correction System + * + * Author: Graeme W. Gill + * Date: 15/3/2001 + * + * Copyright 2001 - 2013 Graeme W. Gill + * All rights reserved. + * + * This material is licenced under the GNU GENERAL PUBLIC LICENSE Version 2 or later :- + * see the License2.txt file for licencing details. + * + */ + +/* + If you make use of the instrument driver code here, please note + that it is the author(s) of the code who take responsibility + for its operation. Any problems or queries regarding driving + instruments with the Argyll drivers, should be directed to + the Argyll's author(s), and not to any other party. + + If there is some instrument feature or function that you + would like supported here, it is recommended that you + contact Argyll's author(s) first, rather than attempt to + modify the software yourself, if you don't have firm knowledge + of the instrument communicate protocols. There is a chance + that an instrument could be damaged by an incautious command + sequence, and the instrument companies generally cannot and + will not support developers that they have not qualified + and agreed to support. + */ + +#include "insttypes.h" /* libinst Includes this functionality */ +#include "icoms.h" /* libinst Includes this functionality */ +#include "conv.h" + +#ifdef __cplusplus + extern "C" { +#endif + +/* ------------------------------------------------- */ +/* aprox. debug level guide: + + 1,2 Applications, internal errors + 2,3 High level instrument drivers + 4,5 High level instrument communications + 6,7 High level serial/USB communications + 8,9 Low level serial/USB communications + +*/ + +/* ------------------------------------------------- */ +/* Structure for holding an instrument patch reading */ + +#define ICOM_MAX_LOC_LEN 10 + +/* Type of measurement result */ +typedef enum { /* XYZ units, spectral units */ + inst_mrt_none = 0, /* Not set */ + inst_mrt_emission = 1, /* cd/m^2, mW/m^2/nm */ + inst_mrt_ambient = 2, /* Lux/3.1415926 ?? */ + inst_mrt_emission_flash = 3, /* cd/m^2.s, mW/m^2/nm.s*/ + inst_mrt_ambient_flash = 4, /* Lux/3.1415926/s ?? */ + inst_mrt_reflective = 5, /* %, %/nm */ + inst_mrt_transmissive = 6 /* %, %/nm */ +} inst_meas_type; + +struct _ipatch { + char loc[ICOM_MAX_LOC_LEN]; /* patch location */ + + inst_meas_type mtype; /* Measurement type */ + + int XYZ_v; /* XYZ valid */ + double XYZ[3]; /* XYZ values */ + + xspect sp; /* Spectrum. sp.spec_n > 0 if valid */ + /* Reflectance/Transmittance 0.0 .. 100.0%, norm = 100.0 */ + /* or mW/nm/m^2, norm = 1.0, etc. */ + + double duration; /* Apparent total duration in seconds (flash measurement) */ + /* Typicall limited to sampling rate of instrument. */ + +}; typedef struct _ipatch ipatch; + +/* ---------------------------------------- */ +/* Instrument interface abstract base class */ + +/* Abstract return codes in ms byte. */ +/* Instrument dependant codes in ls byte. */ +/* Note :- update inst_interp_error() in inst.c if anything here is changed. */ +/* and also check all the instrument specific XXX_interp_code() routines too. */ +typedef enum { + inst_ok = 0x0000, + inst_notify = 0x0100, /* A Notification */ + inst_warning = 0x0200, /* A Warning */ + inst_no_coms = 0x0300, /* init_coms() hasn't been called yet */ + inst_no_init = 0x0400, /* init_inst() hasn't been called yet */ + inst_unsupported = 0x0500, /* Unsupported function */ + inst_internal_error = 0x0600, /* Internal software error */ + inst_coms_fail = 0x0700, /* Communication failure */ + inst_unknown_model = 0x0800, /* Not the expected instrument */ + inst_protocol_error = 0x0900, /* Read or Write protocol error */ + inst_user_abort = 0x0A00, /* User hit escape */ + inst_user_trig = 0x0C00, /* User hit trigger key */ + inst_misread = 0x0E00, /* Bad reading, or strip misread */ + inst_nonesaved = 0x0F00, /* No saved data to read */ + inst_nochmatch = 0x1000, /* Chart doesn't match */ + inst_needs_cal = 0x1100, /* Instrument needs calibration, and read retried */ + inst_cal_setup = 0x1200, /* Calibration retry with correct setup is needed */ + inst_wrong_config = 0x1300, /* Retry with correct inst. config./sensor posn. needed */ + inst_unexpected_reply = 0x1400, /* Unexpected Reply */ + inst_wrong_setup = 0x1500, /* Setup is wrong or conflicting */ + inst_hardware_fail = 0x1600, /* Hardware failure */ + inst_bad_parameter = 0x1700, /* Bad parameter value */ + inst_other_error = 0x1800, /* Some other error */ + inst_mask = 0xff00, /* inst_code mask value */ + inst_imask = 0x00ff /* instrument specific mask value */ +} inst_code; + +/* Instrument capabilities & modes */ +/* Note that due to the binary combinations, capabilities is not definititive */ +/* as to valid modes. check_mode() is definitive. */ +typedef enum { + inst_mode_none = 0x00000000, /* No capability or mode */ + + /* Mode of light measurement */ + inst_mode_reflection = 0x00000001, /* General reflection mode */ + inst_mode_s_reflection = 0x00000002, /* General saved reflection mode */ + inst_mode_transmission = 0x00000004, /* General transmission mode */ + inst_mode_emission = 0x00000008, /* General emission mode */ + inst_mode_illum_mask = 0x0000000f, /* Mask of sample illumination sub mode */ + + /* Access mode of measurement */ + inst_mode_spot = 0x00000010, /* General spot measurement mode */ + inst_mode_strip = 0x00000020, /* General strip measurement mode */ + inst_mode_xy = 0x00000040, /* General X-Y measurement mode */ + inst_mode_chart = 0x00000080, /* General chart measurement mode */ + inst_mode_ambient = 0x00000100, /* General ambient measurement mode */ + inst_mode_ambient_flash = 0x00000200, /* General ambient flash measurement mode */ + inst_mode_tele = 0x00000400, /* General telephoto measurement mode */ + // Hmm. Should there be a tele_flash mode ???? + inst_mode_sub_mask = 0x000007f0, /* Mask of sub-mode */ + + /* Basic mode */ + inst_mode_basic_mask = inst_mode_illum_mask | inst_mode_sub_mask, + +/* + possible UV modes: + + Do the reflective measurement with UV rather than normal illuminant + [ Should this be reflectivity against 'A', or absolute ?? ] + (ie. spot, strip, xy or chart). inst_mode_ref_uv + + Do a white & UV measurement at the start of each strip reading. + Return result with special call after each strip read. + inst_mode_ref_uv_strip_1 + + Do a dual white & UV measurement + [ Can do in one hit for spot, but how should two strip passes be handled ? + ie. two separate strip reads of phase 1 & then 2 ? ] + (ie. spot, strip, xy or chart). inst_mode_ref_uv_2pass + + Get normal illuminant spectrum. + + Get UV spectrum. + + get_meas_illum_spectrum(mode); + */ + + /* Extra dependent modes */ + inst_mode_emis_nonadaptive = 0x00000800, /* Emissom Non-adaptive mode */ + inst_mode_ref_uv = 0x00001000, /* Ultra Violet measurement mode */ + inst_mode_emis_refresh_ovd = 0x00002000, /* Emissom Refresh mode override */ + inst_mode_emis_norefresh_ovd = 0x00006000, /* Emissom Non-refresh mode override */ + inst_mode_dep_extra_mask = 0x00007800, /* Mask of measurement modifiers */ + + /* Extra independent modes */ + inst_mode_colorimeter = 0x00004000, /* Colorimetric mode */ + inst_mode_spectral = 0x00008000, /* Spectral mode */ + inst_mode_highres = 0x00010000, /* High Resolution Spectral mode */ + inst_mode_extra_mask = 0x0001c000, /* Mask of extra modes */ + + /* Configured for calibration & capable of returning it from inst_mode_calibration */ + inst_mode_calibration = 0x80000000, /* Configured for calibration */ + + /* Combined operating modes (from above): */ + /* These mode capabilities are also use to set the mode */ + /* Test for a mode should be IMODETST(flags, mode) */ + inst_mode_ref_spot = inst_mode_spot /* Reflection spot measurement mode */ + | inst_mode_reflection, + inst_mode_ref_strip = inst_mode_strip /* Reflection strip measurement mode */ + | inst_mode_reflection, + inst_mode_ref_xy = inst_mode_xy /* Reflection X-Y measurement mode */ + | inst_mode_reflection, + inst_mode_ref_chart = inst_mode_chart /* Reflection Chart measurement mode */ + | inst_mode_reflection, + + inst_mode_s_ref_spot = inst_mode_spot /* Saved reflection spot measurement mode */ + | inst_mode_s_reflection, + inst_mode_s_ref_strip = inst_mode_strip /* Saved reflection strip measurement mode */ + | inst_mode_s_reflection, + inst_mode_s_ref_xy = inst_mode_xy /* Saved reflection X-Y measurement mode */ + | inst_mode_s_reflection, + inst_mode_s_ref_chart = inst_mode_chart /* Saved reflection Chart measurement mode */ + | inst_mode_s_reflection, + + inst_mode_trans_spot = inst_mode_spot /* Transmission spot measurement mode */ + | inst_mode_transmission, + inst_mode_trans_strip = inst_mode_strip /* Transmission strip measurement mode */ + | inst_mode_transmission, + inst_mode_trans_xy = inst_mode_xy /* Transmission X-Y measurement mode */ + | inst_mode_transmission, + inst_mode_trans_chart = inst_mode_chart /* Transmission chart measurement mode */ + | inst_mode_transmission, + + inst_mode_emis_spot = inst_mode_spot /* Spot emission measurement mode */ + | inst_mode_emission, + inst_mode_emis_tele = inst_mode_tele /* Telephoto emission measurement mode */ + | inst_mode_emission, + inst_mode_emis_ambient = inst_mode_ambient /* Ambient emission measurement mode */ + | inst_mode_emission, + inst_mode_emis_ambient_flash = inst_mode_ambient_flash /* Ambient emission flash measurement */ + | inst_mode_emission, + + inst_mode_emis_strip = inst_mode_strip /* Strip emission measurement mode */ + | inst_mode_emission, + + inst_mode_measurement_mask = inst_mode_illum_mask /* Mask of exclusive measurement modes */ + | inst_mode_sub_mask + | inst_mode_dep_extra_mask +} inst_mode; + +/* Test for a specific mode */ +#define IMODETST(mbits, mode) (((mbits) & (mode)) == (mode)) + +/* Test for a specific mode in capability and mode */ +#define IMODETST2(mcap, mbits, mode) (IMODETST(mcap, mode) && IMODETST(mbits, mode)) + +/* Instrument capabilities 2 */ +/* (Available capabilities may be mode dependent) */ +typedef enum { + inst2_none = 0x00000000, /* No capabilities */ + + inst2_xy_holdrel = 0x00000001, /* Needs paper hold/release between each sheet */ + inst2_xy_locate = 0x00000002, /* Needs user to locate patch locations */ + inst2_xy_position = 0x00000004, /* Can be positioned at a given location */ + + inst2_meas_disp_update = 0x00000010, /* Is able to measure display update delay */ + inst2_refresh_rate = 0x00000020, /* Is able to retrieve the calibrated refresh rate */ + + inst2_prog_trig = 0x00000100, /* Progromatic trigger measure capability */ + inst2_user_trig = 0x00000200, /* User trigger measure capability */ + inst2_switch_trig = 0x00000400, /* Inst. switch trigger measure capability */ + inst2_user_switch_trig = 0x00000800, /* User or switch trigger measure capability */ + + inst2_bidi_scan = 0x00001000, /* Try and recognise patches scanned from either dir. */ + inst2_cal_using_switch = 0x00002000, /* DTP22 special - use switch triggered calibration */ + inst2_has_scan_toll = 0x00004000, /* Instrument will honour modified scan tollerance */ + inst2_no_feedback = 0x00008000, /* Instrument doesn't give any user feedback */ + + inst2_has_leds = 0x00200000, /* Instrument has some user viewable indicator LEDs */ + inst2_has_sensmode = 0x00400000, /* Instrument can report it's sensors mode */ + + inst2_has_battery = 0x00800000, /* Instrument is battery powered */ + + inst2_disptype = 0x01000000, /* Has a display type selector */ + inst2_ccmx = 0x02000000, /* Colorimeter Correction Matrix capability */ + inst2_ccss = 0x04000000, /* Colorimeter Cal. Spectral Set capability */ + + inst2_ambient_mono = 0x08000000, /* The ambient measurement is monochrome */ + + inst2_emis_refr_meas = 0x10000000, /* Has an emissive refresh rate measurement func. */ + +} inst2_capability; + +/* Instrument capabilities 3 (room for expansion) */ +/* (Available capabilities may be mode dependent) */ +typedef enum { + inst3_none = 0x00000000, /* No capabilities */ + +} inst3_capability; + +typedef enum { + inst_dtflags_none = 0x0000, /* no flags */ + inst_dtflags_default = 0x0001, /* default display type */ + inst_dtflags_ccss = 0x0002, /* ccss */ + inst_dtflags_ccmx = 0x0004, /* ccmx */ + inst_dtflags_end = 0x8000 /* end marker */ + +} inst_dtflags; + +#define INST_DTYPE_SEL_LEN 10 +#define INST_DTYPE_DESC_LEN 100 + +/* Structure used to return display type selection information */ +typedef struct _inst_disptypesel { + + /* Public: */ + inst_dtflags flags; /* Attribute flags */ + int cbid; /* Calibration base ID. NZ if valid ccmx calibration base. */ + /* Should remain constant between releases */ + char sel[INST_DTYPE_SEL_LEN]; /* String of selector characters */ + char desc[INST_DTYPE_DESC_LEN]; /* Textural description */ + int refr; /* Refresh mode flag */ + + /* Private: */ + int ix; /* Internal index, */ + + // Stuff for ccss & ccmx + char *path; /* Path to ccss or ccmx */ + double mat[3][3]; /* ccmx matrix */ + xspect *sets; /* ccss set of sample spectra */ + int no_sets; /* ccs number of sets */ + +} inst_disptypesel; + +/* Instrument options for get_set_opt() */ +typedef enum { + inst_opt_unknown = 0x0000, /* Option not specified */ + + inst_stat_saved_readings = 0x0001, /* Return status of saved reading values */ + /* [1 argument type *inst_stat_savdrd] */ + inst_stat_s_spot = 0x0002, /* Return number of saved spot readings */ + /* [1 argument type *int] */ + inst_stat_s_strip = 0x0003, /* Return saved strip details */ + /* [args: int *no_patches, int *no_rows */ + /* int *pat_per_row] */ + inst_stat_s_xy = 0x0004, /* Return saved strip details */ + /* [args: int *no_sheets, int *no_patches, */ + /* int *no_rows, int *pat_per_row] */ + inst_stat_s_chart = 0x0005, /* Return number saved chart details */ + /* [args: int *no_patches, int *no_rows */ + /* int *pat_per_row, int *chart_id, */ + /* int *missing_row ] */ + + inst_stat_battery = 0x0006, /* Return charged status of battery */ + /* [1 argument type *double : range 0.0 - 1.0 ] */ + + inst_stat_get_filter = 0x0007, /* Get a filter configuration */ + /* [1 argument type *inst_opt_filter ] */ + + inst_opt_initcalib = 0x0008, /* Enable initial calibration (default) [No args] */ + inst_opt_noinitcalib = 0x0009, /* Disable initial calibration if < losecs since last */ /* opened, or losecs == 0 [int losecs] */ + + inst_opt_set_ccss_obs = 0x000A, /* Set the observer used with ccss device types */ + /* Only takes effect after inst_opt_set_disp_type */ + /* or col_cal_spec_set() */ + /* [args: icxObserverType obType,*/ + /* xspect custObserver[3] */ + + inst_opt_get_dtinfo = 0x000C, /* Get current display type information */ + /* [args: int *refrmode,*/ + /* int *cbid] */ + + inst_opt_set_filter = 0x000D, /* Set a filter configuration */ + /* [1 argument type inst_opt_filter] */ + + inst_opt_trig_prog = 0x000E, /* Trigger progromatically [No args] */ + inst_opt_trig_user = 0x000F, /* Trigger from user via uicallback [No args] */ + inst_opt_trig_switch = 0x0010, /* Trigger using instrument switch [No args] */ + inst_opt_trig_user_switch = 0x0011, /* Trigger from user via uicallback or switch (def) [No args] */ + + inst_opt_highres = 0x0012, /* Enable high resolution spectral mode */ + inst_opt_stdres = 0x0013, /* Revert to standard resolution spectral mode */ + + inst_opt_scan_toll = 0x0014, /* Modify the patch scan recognition tollnce [double] */ + + inst_opt_get_gen_ledmask = 0x0015, /* Get the bitmask for general indication LEDs [*int] */ + /* (More specialized indicator masks go here) */ + inst_opt_set_led_state = 0x0016, /* Set the current LED state. 0 = off, 1 == on [int] */ + inst_opt_get_led_state = 0x0017, /* Get the current LED state. 0 = off, 1 == on [*int] */ + inst_opt_get_pulse_ledmask = 0x0018, /* Get the bitmask for pulseable ind. LEDs [*int] */ + inst_opt_set_led_pulse_state= 0x0019, /* Set the current LED state. [double period_in_secs, */ + /* double on_time_prop, double trans_time_prop] */ + inst_opt_get_led_pulse_state= 0x001A /* Get the current pulse LED state. [*double period, */ + +} inst_opt_type; + +/* Optional filter fitted to instrument (for inst_opt_set_filter) */ +typedef enum { + inst_opt_filter_unknown = 0xffff, /* Unspecified filter */ + inst_opt_filter_none = 0x0000, /* No filters fitted */ + inst_opt_filter_pol = 0x0001, /* Polarising filter */ + inst_opt_filter_D65 = 0x0002, /* D65 Illuminant filter */ + inst_opt_filter_UVCut = 0x0004, /* U.V. Cut filter */ + inst_opt_filter_Custom = 0x0008 /* Custom Filter */ +} inst_opt_filter; + +/* Off-line pending readings available (status) */ +typedef enum { + inst_stat_savdrd_none = 0x00, /* No saved readings */ + inst_stat_savdrd_spot = 0x01, /* There are saved spot readings available */ + inst_stat_savdrd_strip = 0x02, /* There are saved strip readings available */ + inst_stat_savdrd_xy = 0x04, /* There are saved page readings available */ + inst_stat_savdrd_chart = 0x08 /* There are saved chart readings available */ +} inst_stat_savdrd; + +/* Type of calibration needed/available/requested - corresponds to capabilities */ +/* [ inst_calt_trans_vwhite is "variable" white transmission calibration, needed */ +/* where transmission mode is being emulated. ] */ +typedef enum { + /* Response to needs_calibration() */ + inst_calt_none = 0x00000000, /* No calibration or unknown */ + + /* Psudo-calibration types */ + inst_calt_all = 0x00000001, /* Do required non-deferable cals for mode, but also */ + /* do all possible calibrations for all other modes */ + /* using the calibration conditions. This may be slow */ + /* Hmm. We don't have an "calt_all_needed" - do all needed cals of all possible modes. */ + /* This might be more useful than inst_calt_all ? */ + inst_calt_needed = 0x00000002, /* Do all required non-deferable cals for c.m. */ + inst_calt_available = 0x00000003, /* Do all available non-deferable cals for c.m. */ + + /* Specific type of calibration - corresponds to capabilities */ + inst_calt_wavelength = 0x00000010, /* Wavelength calibration using refl. cal. surface */ + inst_calt_ref_white = 0x00000020, /* Reflective white/emissive dark calibration */ + inst_calt_ref_dark = 0x00000040, /* Reflective dark calibration (in dark) */ + inst_calt_emis_offset = 0x00000080, /* Emissive offset/black calibration (dark surface) */ + inst_calt_emis_ratio = 0x00000100, /* Emissive ratio calibration */ + inst_calt_em_dark = 0x00000200, /* Emissive dark calibration (in dark) */ + inst_calt_trans_white = 0x00000400, /* Transmissive white reference calibration */ + inst_calt_trans_vwhite = 0x00000800, /* Transmissive variable white reference calibration */ + inst_calt_trans_dark = 0x00001000, /* Transmissive dark reference calibration */ + + inst_calt_n_dfrble_mask = 0x0000fff0, /* Mask of non-deferrable calibrations */ + + /* Calibrations that might be deferred until measurement */ + inst_calt_emis_int_time = 0x00100000, /* Emissive measurement range (integration time) */ + inst_calt_ref_freq = 0x00200000, /* Display refresh frequency calibration */ + + inst_calt_dfrble_mask = 0x00f00000, /* Mask of deferrable calibrations */ + + inst_calt_all_mask = 0x00f0fff0, /* Mask of all specific calibrations */ + + inst_calt_ap_flag = 0x80000000 /* Implementation flag indicating do all possible */ + +} inst_cal_type; + +/* Calibration conditions. */ +/* This is how the instrument communicates to the calling program */ +/* about how to facilitate a calibration, or what it's current measurement */ +/* configuration provides. */ +/* [There is no provission for explictly indicating calibrations that can be */ +/* performed automatically and transparently by the instrument - for instance */ +/* in the case of the spectroscan, since the required condition can be obtained */ +/* without the users interaction. ] */ +typedef enum { + inst_calc_none = 0x00000000, /* Not suitable for calibration */ + inst_calc_unknown = 0xffffffff, /* Unknown calibration setup */ + + /* uop means that user has to trigger the within instrument */ + /* calibration using its "front panel" or other direct keys */ + inst_calc_uop_ref_white = 0x00000001, /* user operated reflective white calibration */ + inst_calc_uop_trans_white = 0x00000002, /* user operated tranmissive white calibration */ + inst_calc_uop_trans_dark = 0x00000003, /* user operated tranmissive dark calibration */ + inst_calc_uop_mask = 0x0000000F, /* user operated calibration mask */ + + /* Man means that the user has to manualy configure the instrument */ + /* to be on the correct reference for the software triggered cal. */ + inst_calc_man_ref_white = 0x00000010, /* place instrument on reflective white reference */ + inst_calc_man_ref_whitek = 0x00000020, /* click instrument on reflective white reference */ + inst_calc_man_ref_dark = 0x00000030, /* place instrument in dark, not close to anything */ + inst_calc_man_em_dark = 0x00000040, /* place cap on instrument, put on dark surface or white ref. */ + inst_calc_man_am_dark = 0x00000050, /* Place cap over ambient sensor (wl calib capable) */ + inst_calc_man_cal_smode = 0x00000060, /* Put instrument sensor in calibration position */ + + inst_calc_man_trans_white = 0x00000070, /* place instrument on transmissive white reference */ + inst_calc_man_trans_dark = 0x00000080, /* place instrument on transmissive dark reference */ + inst_calc_man_man_mask = 0x000000F0, /* user configured calibration mask */ + + inst_calc_emis_white = 0x00000100, /* Provide a white test patch */ + inst_calc_emis_grey = 0x00000200, /* Provide a grey test patch */ + inst_calc_emis_grey_darker = 0x00000300, /* Provide a darker grey test patch */ + inst_calc_emis_grey_ligher = 0x00000400, /* Provide a darker grey test patch */ + inst_calc_emis_mask = 0x00000F00, /* Emmissive/display provided reference patch */ + + inst_calc_change_filter = 0x00010000, /* Filter needs changing on device - see id[] */ + inst_calc_message = 0x00020000 /* Issue a message. - see id[] */ +} inst_cal_cond; + +/* Clamping state */ +typedef enum { + instNoClamp = 0, /* Don't clamp XYZ/Lab to +ve */ + instClamp = 1, /* Clamp XYZ/Lab to +ve */ +} instClamping; + +/* User interaction callback function purpose */ +typedef enum { + inst_negcoms, /* Negotiating communications */ + inst_triggered, /* Measurement has been triggered by switch or user (not progromatic) */ + inst_armed, /* Armed and waiting for a measurement trigger */ + inst_measuring /* Busy measuring */ +} inst_ui_purp; + +/* Asynchronous event callback type */ +typedef enum { + inst_event_switch, /* Instrument measure/calibrate switch pressed */ + inst_event_mconf /* Change in measurement configuration (ie. sensor position) */ +} inst_event_type; + +/* Instrument configuration/sensor position*/ +typedef enum { + inst_conf_unknown, + inst_conf_projector, + inst_conf_surface, + inst_conf_emission, + inst_conf_calibration, + inst_conf_ambient +} inst_config; + +/* Off-line pending readings available (status) */ +#define CALIDLEN 200 /* Maxumum length of calibration tile ID string */ + +/* Color instrument interface base object */ +/* Note that some methods work after creation, while many */ +/* will return an error if communications hasn't been established and */ +/* the instrument initialised. Some may change their response before and */ +/* after initialisation. */ +#define INST_OBJ_BASE \ + \ + a1log *log; /* Pointer to debug & error logging class */ \ + instType itype; /* Instrument type determined by driver */ \ + icoms *icom; /* Instrument coms object */ \ + int gotcoms; /* Coms established flag */ \ + int inited; /* Instrument open and initialized flag */ \ + double cal_gy_level; /* Display calibration test window state */ \ + int cal_gy_count; /* Display calibration test window state */ \ + inst_code (*uicallback)(void *cntx, inst_ui_purp purp); \ + void *uic_cntx; /* User interaction callback function */ \ + void (*eventcallback)(void *cntx, inst_event_type event); \ + void *event_cntx; /* Event callback function */ \ + \ + /* Establish communications at the indicated baud rate. */ \ + /* (Serial parameters are ignored for USB instrument) */ \ + /* Timout in to seconds, and return non-zero error code */ \ + inst_code (*init_coms)( \ + struct _inst *p, \ + baud_rate br, /* Baud rate */ \ + flow_control fc, /* Flow control */ \ + double tout); /* Timeout */ \ + \ + /* Initialise or re-initialise the INST */ \ + /* return non-zero on an error, with inst error code */ \ + inst_code (*init_inst)( \ + struct _inst *p); \ + \ + /* Return the instrument type */ \ + /* (this could concievably change after init_inst()) */ \ + /* Can be called before init */ \ + instType (*get_itype)( \ + struct _inst *p); \ + \ + /* Return the instrument serial number. */ \ + /* (This will be an empty string if there is no serial no) */ \ + char *(*get_serial_no)( \ + struct _inst *p); \ + \ + /* Return the avilable instrument modes and capabilities. */ \ + /* Can be called before init, but may be different to */ \ + /* what's returned after initilisation. */ \ + /* Note that these may change with the mode. */ \ + /* Arguments may be NULL */ \ + void (*capabilities)(struct _inst *p, \ + inst_mode *cap1, \ + inst2_capability *cap2, \ + inst3_capability *cap3); \ + \ + /* Return current or given configuration available measurement modes. */ \ + /* Most instruments have only one detectable configuration. */ \ + /* If conf_ix == NULL or *conf_ix is an invalid configuration index, */ \ + /* then the current configuration modes are returned. */ \ + /* Otherwise the given configuration index is returned. */ \ + /* The i1d3 has 2, the Munki has 4, one being calibration. */ \ + /* *cconds is valid if *mmodes = inst_mode_calibration */ \ + inst_code (*meas_config)(struct _inst *p, \ + inst_mode *mmodes, /* Return all the valid measurement modes */ \ + /* for the current configuration */ \ + inst_cal_cond *cconds, /* Return the valid calibration conditions */ \ + int *conf_ix); /* Request mode for given configuration, and */ \ + /* return the index of the configuration returned */ \ + \ + /* Check that the particular device measurement mode is valid, */ \ + /* since it's not possible to be 100% sure from capabilities */ \ + inst_code (*check_mode)( \ + struct _inst *p, \ + inst_mode m); /* Requested mode */ \ + \ + /* Set the device measurement mode */ \ + /* Note that this may change the capabilities. */ \ + inst_code (*set_mode)( \ + struct _inst *p, \ + inst_mode m); /* Requested mode */ \ + \ + /* Return array of display type selectors */ \ + inst_code (*get_disptypesel)( \ + struct _inst *p, \ + int *no_selectors, /* Return number of display types */ \ + inst_disptypesel **sels,/* Return the array of display types */ \ + int allconfig, /* nz to return list for all configs, not just current. */ \ + int recreate); /* nz to re-check for new ccmx & ccss files */ \ + \ + /* Set the display type. index is into the inst_disptypesel[] returned */ \ + /* returned by get_disptypesel(). clears col_cor_mat() */ \ + inst_code (*set_disptype)( \ + struct _inst *p, \ + int index); \ + \ + /* Get a status or get or set an option */ \ + /* option state. */ \ + /* Some options can be set before init */ \ + /* See inst_opt_type typedef for list of mode types */ \ + inst_code (*get_set_opt)( \ + struct _inst *p, \ + inst_opt_type m, /* Requested option mode */ \ + ...); /* Option parameters */ \ + \ + /* Read a full test chart composed of multiple sheets */ \ + /* DOESN'T use the trigger mode */ \ + /* Return the inst error code */ \ + inst_code (*read_chart)( \ + struct _inst *p, \ + int npatch, /* Total patches/values in chart */ \ + int pich, /* Passes (rows) in chart */ \ + int sip, /* Steps in each pass (patches in each row) */ \ + int *pis, /* Passes in each strip (rows in each sheet) */ \ + int chid, /* Chart ID number */ \ + ipatch *vals); /* Pointer to array of values */ \ + \ + \ + /* For an xy instrument, release the paper */ \ + /* (if cap has inst_xy_holdrel) */ \ + /* Return the inst error code */ \ + inst_code (*xy_sheet_release)( \ + struct _inst *p); \ + \ + /* For an xy instrument, hold the paper */ \ + /* (if cap has inst_xy_holdrel) */ \ + /* Return the inst error code */ \ + inst_code (*xy_sheet_hold)( \ + struct _inst *p); \ + \ + /* For an xy instrument, allow the user to locate a point */ \ + /* (if cap has inst_xy_locate) */ \ + /* Return the inst error code */ \ + inst_code (*xy_locate_start)( \ + struct _inst *p); \ + \ + /* For an xy instrument, read back the location */ \ + /* (if cap has inst_xy_locate) */ \ + /* Return the inst error code */ \ + inst_code (*xy_get_location)( \ + struct _inst *p, \ + double *x, double *y); \ + \ + /* For an xy instrument, end allowing the user to locate a point */ \ + /* (if cap has inst_xy_locate) */ \ + /* Return the inst error code */ \ + inst_code (*xy_locate_end)( \ + struct _inst *p); \ + \ + /* For an xy instrument, move the measurement point */ \ + /* (if cap has inst_xy_position) */ \ + /* Return the inst error code */ \ + inst_code (*xy_position)( \ + struct _inst *p, \ + int measure, /* nz for measure point, z for locate point */ \ + double x, double y); \ + \ + /* For an xy instrument, try and clear the table after an abort */ \ + /* Return the inst error code */ \ + inst_code (*xy_clear)( \ + struct _inst *p); \ + \ + /* Read a sheet full of patches using xy mode */ \ + /* DOESN'T use the trigger mode */ \ + /* Return the inst error code */ \ + inst_code (*read_xy)( \ + struct _inst *p, \ + int pis, /* Passes in strips (letters in sheet) */ \ + int sip, /* Steps in pass (numbers in sheet) */ \ + int npatch, /* Total patches in strip (skip in last pass) */ \ + char *pname, /* Starting pass name (' A' to 'ZZ') */ \ + char *sname, /* Starting step name (' 1' to '99') */ \ + double ox, double oy, /* Origin of first patch */ \ + double ax, double ay, /* pass increment */ \ + double aax, double aay, /* pass offset for odd patches */ \ + double px, double py, /* step/patch increment */ \ + ipatch *vals); /* Pointer to array of values */ \ + \ + \ + /* Read a set of strips (applicable to strip reader) */ \ + /* Obeys the trigger mode set, and may return user trigger code */ \ + /* (to hint that a user command may be available) */ \ + /* Return the inst error code */ \ + inst_code (*read_strip)( \ + struct _inst *p, \ + char *name, /* Strip name (up to 7 chars) */ \ + int npatch, /* Number of patches in each pass */ \ + char *pname, /* Pass name (3 chars) */ \ + int sguide, /* Guide number (decrements by 5) */ \ + double pwid, /* Patch width in mm (For DTP20/DTP41) */ \ + double gwid, /* Gap width in mm (For DTP20/DTP41) */ \ + double twid, /* Trailer width in mm (For DTP41T) */ \ + ipatch *vals); /* Pointer to array of values */ \ + \ + \ + /* Read a single sample (applicable to spot instruments) */ \ + /* Obeys the trigger mode set, and may return user trigger code */ \ + /* Values are in XYZ 0..100 for reflective transmissive, */ \ + /* aXYZ in cd/m^2 for emissive, amd Lux/3.1415926 for ambient. */ \ + /* Spectral will be analogous to the XYZ. */ \ + /* By default values may be -ve due to noise (depending on instrument) */ \ + /* Return the inst error code */ \ + inst_code (*read_sample)( \ + struct _inst *p, \ + char *name, /* Patch identifier (up to 7 chars) */ \ + ipatch *val, /* Pointer to value to be returned */ \ + instClamping clamp); /* NZ to clamp XYZ to be +ve */ \ + \ + /* Measure the emissive refresh rate in Hz. */ \ + /* (Available if cap2 & inst2_emis_refr_meas) */ \ + /* Returns: */ \ + /* inst_unsupported - if this instrument doesn't suport this measuremet */ \ + /* or not in an emissive measurement mode */ \ + /* inst_misread - if no refresh rate could be determined */ \ + /* inst_ok - on returning a valid reading */ \ + inst_code (*read_refrate)( \ + struct _inst *p, \ + double *ref_rate); /* Return the Hz */ \ + \ + /* Determine if a calibration is needed. Returns inst_calt_none if not */ \ + /* or unknown, or a mask of the needed calibrations. */ \ + /* This call checks if calibrations are invalid or have timed out. */ \ + /* With the exception of instruments with automated calibration */ \ + /* (ie. SpectroScan), an instrument will typically */ \ + /* not check for calibration timout any other way. */ \ + /* [What's returned is the same as get_n_a_cals() [ needed_calibrations.] */\ + inst_cal_type (*needs_calibration)( \ + struct _inst *p); \ + \ + /* Return combined mask of needed and available inst_cal_type's */ \ + /* for the current mode. */ \ + inst_code (*get_n_a_cals)( \ + struct _inst *p, \ + inst_cal_type *needed_calibrations, \ + inst_cal_type *available_calibrations); \ + \ + /* Request an instrument calibration. */ \ + /* This is use if the user decides they want to do a calibration */ \ + /* in anticipation of a calibration (needs_calibration()) to avoid */ \ + /* requiring one during measurement, or in response to measuring */ \ + /* returning inst_needs_cal before retrying the measurement, */ \ + /* or to do one or more re-calibrations. */ \ + \ + /* *calt should contain the mask of calibrations to be performed, */ \ + /* with *calc set to the current calibration condition. */ \ + /* Alternately, one of the psudo-calibration types inst_calt_all, */ \ + /* inst_calt_needed or inst_calt_available can be used, */ \ + /* and/or the *calc of inst_calc_none to get calibrate() */ \ + /* to determine the required calibration types and conditions. */ \ + /* (The corresponding calibration types will be used & returned. */ \ + \ + /* If no error is returned to the first call to calibrate() with */ \ + /* then the instrument was capable of calibrating without user or */ \ + /* application intervention. If on the other hand calibrate() returns */ \ + /* inst_cal_setup, then the appropriate action indicated by the value */ \ + /* returned in *calc should be taken by the user or application, */ \ + /* before retrying calibration() with the current setup indicated */ \ + /* by *calc. If more than one calibration type is requested, then */ \ + /* several retries may be needed with different calibration conditions. */ \ + /* Each call to calibrate() will update *calt to reflect the remaining */ \ + /* calibration to be performed. calibrate() returns inst_ok when no */ \ + /* more calibrations remain. */ \ + \ + /* DOESN'T use the trigger mode */ \ + /* Return inst_unsupported if *calt is not appropriate, */ \ + /* inst_cal_setup if *calc is not appropriate. */ \ + inst_code (*calibrate)( \ + struct _inst *p, \ + inst_cal_type *calt, /* Calibration type to do/remaining */ \ + inst_cal_cond *calc, /* Current condition/desired condition */ \ + char id[CALIDLEN]); /* Condition identifier (ie. white */ \ + /* reference ID, filter ID) */ \ + \ + /* Measure a display update delay. It is assumed that a */ \ + /* White to black change has been made to the displayed color, */ \ + /* and this will measure the time it took for the update to */ \ + /* be noticed by the instrument, up to 1.0 seconds. */ \ + /* inst_misread will be returned on failure to find a transition to black. */ \ + inst_code (*meas_delay)( \ + struct _inst *p, \ + int *msecdelay); /* Return the number of msec */ \ + \ + /* Return the last calibrated refresh rate in Hz. Returns: */ \ + /* inst_unsupported - if this instrument doesn't suport a refresh mode */ \ + /* or is unable to retrieve the refresh rate */ \ + /* inst_needs_cal - if the refresh rate value is not valid */ \ + /* inst_misread - if no refresh rate could be determined */ \ + /* inst_ok - on returning a valid reading */ \ + inst_code (*get_refr_rate)( \ + struct _inst *p, \ + double *ref_rate); /* Return the Hz */ \ + \ + /* Set the calibrated refresh rate in Hz. */ \ + /* Set refresh rate to 0.0 to mark it as invalid */ \ + /* Rates outside the range 5.0 to 150.0 Hz will return an error */ \ + /* Note that not all instruments that can return a refresh rate, */ \ + /* will permit one to be set (ie., DTP92) */ \ + inst_code (*set_refr_rate)( \ + struct _inst *p, \ + double ref_rate); /* Rate in Hz */ \ + \ + /* Insert a compensation filter in the instrument readings */ \ + /* This is typically needed if an adapter is being used, that alters */ \ + /* the spectrum of the light reaching the instrument */ \ + /* To remove the filter, pass NULL for the filter filename */ \ + inst_code (*comp_filter)( \ + struct _inst *p, \ + char *filtername); /* File containing compensating filter */ \ + \ + /* Insert a colorimetric correction matrix in the instrument XYZ readings */ \ + /* This is only valid for colorimetric instruments, and can only be */ \ + /* applied over a base calibration display type. Setting a display */ \ + /* type will clear the matrix. */ \ + /* To clear the matrix, pass NULL for the matrix */ \ + inst_code (*col_cor_mat)( \ + struct _inst *p, \ + double mtx[3][3]); /* XYZ matrix */ \ + \ + /* Use a Colorimeter Calibration Spectral Set (ccss) to set the */ \ + /* instrumen calibration. This will affect emissive readings. */ \ + /* An alternate observer may also be set, and this will affect both */ \ + /* emissive and ambient readings. */ \ + /* This is only valid for colorimetric instruments. */ \ + /* To set calibration back to default, pass NULL for sets, and */ \ + /* icxOT_default for the observer. */ \ + inst_code (*col_cal_spec_set)( \ + struct _inst *p, \ + xspect *sets, /* Set of sample spectra */ \ + int no_sets); /* Number on set */ \ + \ + /* Supply a user interaction callback function. \ + * This is called for one of three different purposes: \ + * To signal that the instrument measurement has been triggered. \ + * To poll for a abort while waiting to trigger. \ + * To poll for a user abort during measurement. \ + * \ + * The callback function will have the purpose paramater appropriately. \ + * \ + * For inst_negcoms, the return value of inst_user_abort \ + * will abort the communication negotiation \ + * \ + * For inst_triggered, the return value of the callback is ignored. \ + * \ + * For inst_armed return value should be one of: \ + * inst_ok to do nothing, inst_user_abort to abort the measurement, \ + * or inst_user_trig to trigger the measurement. \ + * \ + * For inst_measuring the return value should be one of: \ + * inst_ok to do nothing, inst_user_abort to abort the measurement. \ + * \ + * NULL can be set to disable the callback. \ + */ \ + void (*set_uicallback)(struct _inst *p, \ + inst_code (*uicallback)(void *cntx, inst_ui_purp purp), \ + void *cntx); \ + \ + /* Supply an aynchronous event callback function. \ + * This is called from a thread with the following possible events: \ + * \ + * inst_event_switch: Instrument measure/calibrate switch pressed \ + * inst_event_mconf: The measurement configuration has changed (ie. sensor position) \ + * \ + * NULL can be set to disable the callback. \ + */ \ + void (*set_event_callback)(struct _inst *p, \ + void (*eventcallback)(void *cntx, inst_event_type event), \ + void *cntx); \ + \ + /* Generic inst error codes interpretation */ \ + char * (*inst_interp_error)(struct _inst *p, inst_code ec); \ + \ + /* Instrument specific error codes interpretation */ \ + char * (*interp_error)(struct _inst *p, int ec); \ + \ + /* Convert instrument specific inst_wrong_config error to inst_config enum */ \ + inst_config (*config_enum)(struct _inst *p, int ec); \ + \ + /* Return the last serial communication error code */ \ + /* (This is used for deciding fallback/retry strategies) */ \ + int (*last_scomerr)(struct _inst *p); \ + \ + /* Destroy ourselves */ \ + void (*del)(struct _inst *p); \ + +/* The base object type */ +struct _inst { + INST_OBJ_BASE + }; typedef struct _inst inst; + +/* Virtual constructor. */ +/* Return NULL for unknown instrument, */ +/* or serial instrument if nocoms == 0. */ +/* (Doesn't copy icompaths log!) */ +/* If uicallback is provided, it will be set in the resulting inst */ +extern inst *new_inst( + icompath *path, /* Device path this instrument */ + int nocoms, /* Don't open if communications are needed to establish inst type */ + a1log *log, /* Log to use */ + inst_code (*uicallback)(void *cntx, inst_ui_purp purp), /* optional uicallback */ + void *cntx /* Context for callback */ +); + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +/* Implementation functions used by drivers */ + +/* Get a status or set or get an option (default implementation) */ +inst_code inst_get_set_opt_def( +inst *p, +inst_opt_type m, /* Option type */ +va_list args); /* Option parameters */ + +/* - - - - - - - - - - - - - - - - - - -- */ + +/* Create the display type list */ +inst_code inst_creat_disptype_list(inst *p, +int *pndtlist, /* Number in returned list */ +inst_disptypesel **pdtlist, /* Returned list */ +inst_disptypesel *sdtlist, /* Static list */ +int doccss, /* Add installed ccss files */ +int doccmx /* Add matching installed ccmx files */ +); + +/* Free a display type list */ +void inst_del_disptype_list(inst_disptypesel *list, int no); + + +/* - - - - - - - - - - - - - - - - - - -- */ +/* CCMX support */ + +typedef struct { + char *path; /* Path to the file */ + char *desc; /* Technology + display description */ + int cbid; /* Calibration display type base ID */ + int refr; /* Refresh mode flag */ + char *sel; /* UI selector characters (may be NULL) */ + double mat[3][3]; /* The matrix values */ +} iccmx; + +/* return a list of installed ccmx files. */ +/* if inst != NULL, return those that match the given instrument. */ +/* The list is sorted by description and terminated by a NULL entry. */ +/* If no is != NULL, return the number in the list */ +/* Return NULL and -1 if there is a malloc error */ +iccmx *list_iccmx(char *inst, int *no); + +/* Free up a iccmx list */ +void free_iccmx(iccmx *list); + +/* - - - - - - - - - - - - - - - - - - -- */ +/* CCSS support */ + +typedef struct { + char *path; /* Path to the file */ + char *desc; /* Technology + display description */ + int refr; /* Refresh mode flag */ + char *sel; /* UI selector characters (may be NULL) */ + xspect *sets; /* Set of sample spectra */ + int no_sets; /* Number on set */ +} iccss; + +/* return a list of installed ccss files. */ +/* The list is sorted by description and terminated by a NULL entry. */ +/* If no is != NULL, return the number in the list */ +/* Return NULL and -1 if there is a malloc error */ +iccss *list_iccss(int *no); + +/* Free up a iccss list */ +void free_iccss(iccss *list); + +/* - - - - - - - - - - - - - - - - - - -- */ + +#ifdef __cplusplus + } +#endif + +#define INST_H +#endif /* INST_H */ -- cgit v1.2.3