From c0b89ac5bfb90835ef01573267020e42d4fe070c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Sun, 23 Aug 2015 12:17:05 +0200 Subject: Imported Upstream version 1.8.0 --- spectro/dispsup.c | 270 ++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 243 insertions(+), 27 deletions(-) mode change 100644 => 100755 spectro/dispsup.c (limited to 'spectro/dispsup.c') diff --git a/spectro/dispsup.c b/spectro/dispsup.c old mode 100644 new mode 100755 index 5751fed..57a598e --- a/spectro/dispsup.c +++ b/spectro/dispsup.c @@ -96,7 +96,7 @@ inst_code setup_display_calibrate( // dispwin *dw; /* Display window to display test patches on, NULL if none. */ a1logd(p->log,1,"setup_display_calibrate called with calc = 0x%x\n",calc); - switch (calc) { + switch (calc & inst_calc_cond_mask) { case inst_calc_none: /* Use this as a cleanup flag */ if (dwi->dw == NULL && dwi->_dw != NULL) { dwi->_dw->del(dwi->_dw); @@ -112,31 +112,31 @@ inst_code setup_display_calibrate( if (dwi->dw == NULL) { if (dwi->webdisp != 0) { if ((dwi->_dw = new_webwin(dwi->webdisp, dwi->hpatsize, dwi->vpatsize, - dwi->ho, dwi->vo, 0, 0, NULL, NULL, dwi->out_tvenc, dwi->blackbg, - p->log->verb, p->log->debug)) == NULL) { + dwi->ho, dwi->vo, 0, 0, NULL, NULL, dwi->out_tvenc, + dwi->fullscreen, p->log->verb, p->log->debug)) == NULL) { a1logd(p->log,1,"inst_handle_calibrate failed to create test window 0x%x\n",inst_other_error); return inst_other_error; } } else if (dwi->ccid != NULL) { if ((dwi->_dw = new_ccwin(dwi->ccid, dwi->hpatsize, dwi->vpatsize, - dwi->ho, dwi->vo, 0, 0, NULL, NULL, dwi->out_tvenc, dwi->blackbg, - p->log->verb, p->log->debug)) == NULL) { + dwi->ho, dwi->vo, 0, 0, NULL, NULL, dwi->out_tvenc, + dwi->fullscreen, 0, p->log->verb, p->log->debug)) == NULL) { a1logd(p->log,1,"inst_handle_calibrate failed to create test window 0x%x\n",inst_other_error); return inst_other_error; } #ifdef NT } else if (dwi->madvrdisp != 0) { if ((dwi->_dw = new_madvrwin(dwi->hpatsize, dwi->vpatsize, - dwi->ho, dwi->vo, 0, 0, NULL, NULL, dwi->out_tvenc, dwi->blackbg, - p->log->verb, p->log->debug)) == NULL) { + dwi->ho, dwi->vo, 0, 0, NULL, NULL, dwi->out_tvenc, + dwi->fullscreen, p->log->verb, p->log->debug)) == NULL) { a1logd(p->log,1,"inst_handle_calibrate failed to create test window 0x%x\n",inst_other_error); return inst_other_error; } #endif /* NT */ } else { if ((dwi->_dw = new_dispwin(dwi->disp, dwi->hpatsize, dwi->vpatsize, - dwi->ho, dwi->vo, 0, 0, NULL, NULL, dwi->out_tvenc, dwi->blackbg, - dwi->override, p->log->debug)) == NULL) { + dwi->ho, dwi->vo, 0, 0, NULL, NULL, dwi->out_tvenc, + dwi->fullscreen, dwi->override, p->log->debug)) == NULL) { a1logd(p->log,1,"inst_handle_calibrate failed to create test window 0x%x\n",inst_other_error); return inst_other_error; } @@ -157,22 +157,22 @@ inst_code setup_display_calibrate( dwi->dw->set_settling_delay(dwi->dw, tinfo->rise_time, tinfo->fall_time, -1.0); } - if (calc == inst_calc_emis_white) { + if ((calc & inst_calc_cond_mask) == inst_calc_emis_white) { p->cal_gy_level = 1.0; dwi->_dw->set_color(dwi->_dw, 1.0, 1.0, 1.0); - } else if (calc == inst_calc_emis_80pc) { + } else if ((calc & inst_calc_cond_mask) == inst_calc_emis_80pc) { p->cal_gy_level = 0.8; dwi->_dw->set_color(dwi->_dw, 0.8, 0.8, 0.8); } else { - if (calc == inst_calc_emis_grey) { + if ((calc & inst_calc_cond_mask) == inst_calc_emis_grey) { p->cal_gy_level = 0.6; p->cal_gy_count = 0; - } else if (calc == inst_calc_emis_grey_darker) { + } else if ((calc & inst_calc_cond_mask) == inst_calc_emis_grey_darker) { p->cal_gy_level *= 0.7; p->cal_gy_count++; - } else if (calc == inst_calc_emis_grey_ligher) { + } else if ((calc & inst_calc_cond_mask) == inst_calc_emis_grey_ligher) { p->cal_gy_level *= 1.4; if (p->cal_gy_level > 1.0) p->cal_gy_level = 1.0; @@ -216,7 +216,7 @@ ccast_id *ccid, /* non-NULL for ChromeCast */ int madvrdisp, /* NZ for MadVR display */ #endif int out_tvenc, /* 1 = use RGB Video Level encoding */ -int blackbg, /* NZ if whole screen should be filled with black */ +int fullscreen, /* NZ if whole screen should be filled with black */ int override, /* Override_redirect on X11 */ double hpatsize, /* Size of dispwin */ double vpatsize, @@ -243,7 +243,7 @@ a1log *log /* Verb, debug & error log */ #endif dwi.disp = disp; dwi.out_tvenc = out_tvenc; - dwi.blackbg = blackbg; + dwi.fullscreen = fullscreen; dwi.override = override; dwi.hpatsize = hpatsize; dwi.vpatsize = vpatsize; @@ -318,7 +318,7 @@ a1log *log /* Verb, debug & error log */ if (IMODETST(cap, inst_mode_spectral) && sdtype >= 0) dtype = sdtype; - /* Set the display type */ + /* Set the display type or calibration mode */ if (dtype != 0) { /* Given selection character */ if (cap2 & inst2_disptype) { int ix; @@ -1843,6 +1843,216 @@ static int disprd_fake_read_co(disprd *p, return 0; } +/* Use without a direct connect spectrometer by manual user input */ +/* Return nz on fail/abort - see duspsup.h */ +/* Use disprd_err() to interpret it */ +static int disprd_fake_read_manual(disprd *p, + col *cols, /* Array of patch colors to be tested */ + int npat, /* Number of patches to be tested */ + int spat, /* Start patch index for "verb", 0 if not used */ + int tpat, /* Total patch index for "verb", 0 if not used */ + int acr, /* If nz, do automatic final carriage return */ + int tc, /* If nz, termination key */ + instClamping clamp /* NZ if clamp XYZ/Lab to be +ve */ +) { + int patch, i, j; + int ttpat = tpat; + + if (ttpat < npat) + ttpat = npat; + + /* Continue until the user is done or quits */ + for (patch = 0;;) { + char buf[200], *bp = NULL, *ep = NULL; + char ch = 0; + int allread; + double rgb[3]; + int rv; + char *cmd; + FILE *fp; + + /* Check if all the patches have been read */ + for (allread = i = 0; i < npat; i++) { + if (cols[i].XYZ_v == 0) { + break; + } + } + if (i >= npat) + allread = 1; + + if (spat != 0 && tpat != 0) + a1logv(p->log, 1, "%cpatch %d of %d",cr_char,spat+patch,tpat); + + rgb[0] = cols[patch].r; + rgb[1] = cols[patch].g; + rgb[2] = cols[patch].b; + + /* If we have a test window, display the patch color */ + if (p->dw) { + inst_code rv; + p->dw->enable_update_delay(p->dw, 0); + if ((rv = p->dw->set_color(p->dw, rgb[0], rgb[1], rgb[2])) != 0) { + a1logd(p->log,1,"set_color() returned %d\n",rv); + return 3; + } + p->dw->enable_update_delay(p->dw, 1); + } + + /* If we have a RAMDAC, apply it to the requested color */ + if (p->cal[0][0] >= 0.0) { + double inputEnt_1 = (double)(p->ncal-1); + + for (j = 0; j < 3; j++) { + unsigned int ix; + double val, w; + + val = rgb[j] * inputEnt_1; + if (val < 0.0) { + val = 0.0; + } else if (val > inputEnt_1) { + val = inputEnt_1; + } + ix = (unsigned int)floor(val); /* Coordinate */ + if (ix > (p->ncal-2)) + ix = (p->ncal-2); + w = val - (double)ix; /* weight */ + val = p->cal[j][ix]; + rgb[j] = val + w * (p->cal[j][ix+1] - val); + } + } + + printf("\nReady to read patch %d of %d RGB %.1f %.1f %.1f%s\n", + spat+patch,tpat, rgb[0] * 255.0, rgb[1] * 255.0, rgb[2] * 255.0, + allread ? " (All patches read!)" : + cols[patch].XYZ_v ? " (Already read)" : ""); + + printf("Enter %s value (separated by spaces), or\n", + p->xtern == 1 ? "L*a*b*" : "XYZ"); + printf(" 'f' to move forward\n"); + printf(" 'b' to move back\n"); + printf(" 'd' when done, 'q' to abort : "); + fflush(stdout); + + /* Read in the next line from stdin. */ + if (fgets(buf, 200, stdin) == NULL) { + printf("Error - unrecognised input\n"); + continue; + } + /* Skip whitespace */ + for (bp = buf; *bp != '\000' && isspace(*bp); bp++) + ; + + ch = *bp; /* First character */ + if (ch == '\000') { + printf("Error - unrecognised input\n"); + continue; + } + + /* If it looks like a number */ + if (isdigit(ch) || ch == '-' || ch == '+' || ch == '.') { + + /* For each input number */ + for (i = 0; *bp != '\000' && i < 3; i++) { + char *tp, *nbp; + + /* Find the start of the number */ + while(*bp != '\000' && !isdigit(*bp) + && *bp != '-' && *bp != '+' && *bp != '.') + bp++; + if (!isdigit(*bp) && *bp != '-' && *bp != '+' && *bp != '.') + break; + + /* Find the end of the number */ + for (tp = bp+1; isdigit(*tp) || *tp == 'e' || *tp == 'E' + || *tp == '-' || *tp == '+' || *tp == '.'; tp++) + ; + if (*tp != '\000') + nbp = tp+1; + else + nbp = tp; + *tp = '\000'; + + /* Read the number */ + cols[patch].XYZ[i] = atof(bp); + + bp = nbp; + } + if (i < 3) { /* Didn't find 3 numbers */ + printf("Error - unrecognised input\n"); + continue; + } + if (p->xtern == 1) { + icmLab2XYZ(&icmD50, cols[patch].XYZ, cols[patch].XYZ); + cols[patch].XYZ[0] *= 100.0; + cols[patch].XYZ[1] *= 100.0; + cols[patch].XYZ[2] *= 100.0; + } + + if (clamp) + icmClamp3(cols[patch].XYZ, cols[patch].XYZ); + cols[patch].XYZ_v = 1; + cols[patch].mtype = inst_mrt_emission; + printf(" Got XYZ value %f %f %f\n",cols[patch].XYZ[0], cols[patch].XYZ[1], cols[patch].XYZ[2]); + /* Advance to next patch. */ + patch++; + if (patch >= npat) + patch = 0; + continue; + + /* Assume it's a command */ + } else if (ch == 'f' || ch == 'F') { + patch++; + if (patch >= npat) + patch = 0; + continue; + + } else if (ch == 'b' || ch == 'B') { + patch--; + if (patch < 0) + patch = npat-1; + continue; + + } else if (ch == 'd' || ch == 'D') { + for (allread = i = 0; i < npat; i++) { + if (cols[i].XYZ_v == 0) + break; + } + if (i >= npat) + allread = 1; + + if (allread) + break; + + /* Not all patches have been read */ + empty_con_chars(); + printf("\nDone ? - At least one unread patch (%d), Are you sure [y/n]: ", spat+i); + fflush(stdout); + if ((ch = next_con_char()) == 0x1b) { + printf("\n"); + return 1; + } + printf("\n"); + if (ch == 'y' || ch == 'Y') + break; + continue; + + } else if (ch == 'q' || ch == 'Q' || ch == 0x1b) { + empty_con_chars(); + printf("\nAbort ? - Are you sure ? [y/n]:"); fflush(stdout); + if ((ch = next_con_char()) == 'y' || ch == 'Y') { + printf("\n"); + return 1; + } + printf("\n"); + + } else { + printf("Error - unrecognised input '%c'\n",ch); + continue; + } + } + return 0; +} + /* Return a string describing the error code */ char *disprd_err(int en) { switch(en) { @@ -2008,7 +2218,7 @@ static int config_inst_displ(disprd *p) { if (IMODETST(cap, inst_mode_spectral) && p->sdtype >= 0) dtype = p->sdtype; - /* Set the display type */ + /* Set the display type or calibration mode */ if (dtype != 0) { if (cap2 & inst2_disptype) { int ix; @@ -2150,7 +2360,7 @@ double cal[3][MAX_CAL_ENT], /* Calibration (cal == NULL or cal[0][0] < 0.0 if no int ncal, /* Number of cal[] entries */ disppath *disp, /* Display to calibrate. NULL if fake and no dispwin */ int out_tvenc, /* 1 = use RGB Video Level encoding */ -int blackbg, /* NZ if whole screen should be filled with black */ +int fullscreen, /* NZ if whole screen should be filled with black */ int override, /* Override_redirect on X11 */ int webdisp, /* If nz, port number for web color display */ ccast_id *ccid, /* non-NULL for ChromeCast */ @@ -2160,6 +2370,8 @@ int madvrdisp, /* NZ for MadVR display */ char *ccallout, /* Shell callout on set color */ char *mcallout, /* Shell callout on measure color (forced fake) */ //char *scallout, /* Shell callout on results of measure color */ +int xtern, /* Use external (user supplied) values rather than instument read */ + /* 1 = Lab, 2 = XYZ */ double hpatsize, /* Size of dispwin */ double vpatsize, double ho, /* Horizontal offset */ @@ -2220,10 +2432,11 @@ a1log *log /* Verb, debug & error log */ p->noinitplace = noinitplace; p->highres = highres; p->refrate = refrate; - if (mcallout != NULL) + if (mcallout != NULL || xtern != 0) ipath = &icomFakeDevice; /* Force fake device */ p->mcallout = mcallout; // p->scallout = scallout; + p->xtern = xtern; p->ipath = ipath; p->br = baud_19200; p->fc = fc; @@ -2260,7 +2473,7 @@ a1log *log /* Verb, debug & error log */ p->fake_lu = NULL; /* See if there is a profile we should use as the fake device */ - if (p->mcallout == NULL && p->fake_name != NULL + if (p->mcallout == NULL && p->xtern == 0 && p->fake_name != NULL && (p->fake_fp = new_icmFileStd_name(p->fake_name,"r")) != NULL) { if ((p->fake_icc = new_icc()) != NULL) { if (p->fake_icc->read(p->fake_icc,p->fake_fp,0) == 0) { @@ -2282,6 +2495,9 @@ a1log *log /* Verb, debug & error log */ } else if (p->mcallout != NULL) { a1logv(p->log, 1, "Using shell callout '%s' rather than real device\n",p->mcallout); p->read = disprd_fake_read_co; + } else if (p->xtern != 0) { + a1logv(p->log, 1, "Using manual input rather than real device\n"); + p->read = disprd_fake_read_manual; } else p->read = disprd_fake_read; @@ -2357,7 +2573,7 @@ a1log *log /* Verb, debug & error log */ } } else if (ccid != NULL) { if ((p->dw = new_ccwin(ccid, hpatsize, vpatsize, ho, vo, 0, native, noramdac, nocm, - uout_tvenc, 0, p->log->verb, p->log->debug)) == NULL) { + uout_tvenc, 0, 0, p->log->verb, p->log->debug)) == NULL) { a1logd(log,1,"new_disprd failed because new_ccwin('%s') failed\n",ccid->name); p->del(p); if (errc != NULL) *errc = 3; @@ -2386,7 +2602,7 @@ a1log *log /* Verb, debug & error log */ uout_tvenc = 0; } - /* Open display window for positioning (no blackbg) */ + /* Open display window for positioning (no fullscreen) */ if ((p->dw = new_dispwin(disp, hpatsize, vpatsize, ho, vo, 0, native, noramdac, nocm, uout_tvenc, 0, override, p->log->debug)) == NULL) { a1logd(log,1,"new_disprd failed because new_dispwin failed\n"); @@ -2506,10 +2722,10 @@ a1log *log /* Verb, debug & error log */ printf("\n"); } - /* All except web disp can have a black backround when running tests */ - if (webdisp == 0 && blackbg) { + /* All except web disp can have a full screen black backround when running tests */ + if (webdisp == 0 && fullscreen) { - if (p->dw->set_bg(p->dw, blackbg)) { /* Have to re-create window */ + if (p->dw->set_fc(p->dw, fullscreen)) { /* Have to re-create window */ /* Close the positioning window */ if (p->dw != NULL) { @@ -2520,7 +2736,7 @@ a1log *log /* Verb, debug & error log */ /* Open display window again for measurement */ if ((p->dw = new_dispwin(disp, hpatsize, vpatsize, ho, vo, 0, native, noramdac, nocm, - uout_tvenc, blackbg, override, p->log->debug)) == NULL) { + uout_tvenc, fullscreen, override, p->log->debug)) == NULL) { a1logd(log,1,"new_disprd failed new_dispwin failed\n"); p->del(p); if (errc != NULL) *errc = 3; -- cgit v1.2.3