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
style="font-family: monospace;"></span><br style="font-family:
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;
&nbsp;&nbsp;
Show
@@ -233,6 +235,12 @@ Sort
be</b><i> .ti3 PCS values</i><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
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
+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,"usage: profcheck [-options] data.ti3 iccprofile.icm\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," -k Show CIEDE2000 delta E values\n");
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 fa,nfa; /* current argument we're looking at */
int verb = 0;
int json_report = 0;
int cie94 = 0;
int cie2k = 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 */
else if (argv[fa][1] == 'w')
dovrml = 1;
@@ -1246,8 +1253,23 @@ int main(int argc, char *argv[]) {
wrl->make_lines_vc(wrl, 0, 0.0);
wrl->del(wrl);
}
printf("Profile check complete, errors%s: max. = %f, avg. = %f, RMS = %f\n",
cie2k ? "(CIEDE2000)" : cie94 ? " (CIE94)" : "", merr, aerr/nsamps, sqrt(rerr/nsamps));
if (json_report) {
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 */