Feature: profcheck -u (Structured JSON Delta E Report) #12

Merged
gronod merged 1 commits from feature/profcheck-json-report into main 2026-08-21 21:52:06 +01:00
2 changed files with 32 additions and 2 deletions
+8
View File
@@ -22,6 +22,8 @@
1), 2 to print each DE</span></small><small><span 1), 2 to print each DE</span></small><small><span
style="font-family: monospace;"></span><br style="font-family: style="font-family: monospace;"></span><br style="font-family:
monospace;"> monospace;">
<span style="font-family: monospace;">&nbsp;-u&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Emit
structured JSON Delta E report to stdout</span><br style="font-family: monospace;">
<span style="font-family: monospace;">&nbsp;-c&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="font-family: monospace;">&nbsp;-c&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp; &nbsp;&nbsp;
Show Show
@@ -233,6 +235,12 @@ Sort
be</b><i> .ti3 PCS values</i><br> be</b><i> .ti3 PCS values</i><br>
<br> <br>
The <b>-u</b> flag causes the final delta E check report to be
emitted to <tt>stdout</tt> in structured JSON format (e.g.,
<tt>{"event": "report", "peak_de2000": 2.34, "avg_de2000": 0.51, "rms": 0.61}</tt>).
This facilitates subprocess integration and mathematical extraction of error
metrics without parsing human-readable text.<br>
<br>
The <b>-c</b> option causes the differences between the test values The <b>-c</b> option causes the differences between the test values
and the profile prediction of the color for each device value to be and the profile prediction of the color for each device value to be
displayed in CIE94 delta E, rather than plain L*a*b* delta E. CIE94 displayed in CIE94 delta E, rather than plain L*a*b* delta E. CIE94
+24 -2
View File
@@ -55,6 +55,7 @@ usage(void) {
fprintf(stderr,"Author: Graeme W. Gill, licensed under the AGPL Version 3\n"); fprintf(stderr,"Author: Graeme W. Gill, licensed under the AGPL Version 3\n");
fprintf(stderr,"usage: profcheck [-options] data.ti3 iccprofile.icm\n"); fprintf(stderr,"usage: profcheck [-options] data.ti3 iccprofile.icm\n");
fprintf(stderr," -v [level] Verbosity level (default 1), 2 to print each DE\n"); fprintf(stderr," -v [level] Verbosity level (default 1), 2 to print each DE\n");
fprintf(stderr," -u Emit structured JSON Delta E report to stdout\n");
fprintf(stderr," -c Show CIE94 delta E values\n"); fprintf(stderr," -c Show CIE94 delta E values\n");
fprintf(stderr," -k Show CIEDE2000 delta E values\n"); fprintf(stderr," -k Show CIEDE2000 delta E values\n");
fprintf(stderr," -w create %s visualisation (iccprofile%s)\n",vrml_format(),vrml_ext()); fprintf(stderr," -w create %s visualisation (iccprofile%s)\n",vrml_format(),vrml_ext());
@@ -105,6 +106,7 @@ typedef struct {
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
int fa,nfa; /* current argument we're looking at */ int fa,nfa; /* current argument we're looking at */
int verb = 0; int verb = 0;
int json_report = 0;
int cie94 = 0; int cie94 = 0;
int cie2k = 0; int cie2k = 0;
int dovrml = 0; int dovrml = 0;
@@ -187,6 +189,11 @@ int main(int argc, char *argv[]) {
} }
} }
/* JSON Delta E report */
else if (argv[fa][1] == 'u') {
json_report = 1;
}
/* VRML/X3D */ /* VRML/X3D */
else if (argv[fa][1] == 'w') else if (argv[fa][1] == 'w')
dovrml = 1; dovrml = 1;
@@ -1246,8 +1253,23 @@ int main(int argc, char *argv[]) {
wrl->make_lines_vc(wrl, 0, 0.0); wrl->make_lines_vc(wrl, 0, 0.0);
wrl->del(wrl); wrl->del(wrl);
} }
printf("Profile check complete, errors%s: max. = %f, avg. = %f, RMS = %f\n", if (json_report) {
cie2k ? "(CIEDE2000)" : cie94 ? " (CIE94)" : "", merr, aerr/nsamps, sqrt(rerr/nsamps)); if (cie2k) {
printf("{\"event\": \"report\", \"peak_de2000\": %.2f, \"avg_de2000\": %.2f, \"rms\": %.2f}\n",
merr, aerr/nsamps, sqrt(rerr/nsamps));
} else if (cie94) {
printf("{\"event\": \"report\", \"peak_de94\": %.2f, \"avg_de94\": %.2f, \"rms\": %.2f}\n",
merr, aerr/nsamps, sqrt(rerr/nsamps));
} else {
printf("{\"event\": \"report\", \"peak_de\": %.2f, \"avg_de\": %.2f, \"rms\": %.2f}\n",
merr, aerr/nsamps, sqrt(rerr/nsamps));
}
fflush(stdout);
}
if (verb || !json_report) {
printf("Profile check complete, errors%s: max. = %f, avg. = %f, RMS = %f\n",
cie2k ? "(CIEDE2000)" : cie94 ? " (CIE94)" : "", merr, aerr/nsamps, sqrt(rerr/nsamps));
}
/* ------------------------------- */ /* ------------------------------- */
/* If we want sort by target value */ /* If we want sort by target value */