diff --git a/doc/targen.html b/doc/targen.html
index abf6e46..76a602e 100755
--- a/doc/targen.html
+++ b/doc/targen.html
@@ -17,6 +17,8 @@
targen [options] outfile
-v [level] Verbose mode [optional
verbose level, 1..n]
+ -u Emit
+ structured JSON progress events to stdout
-d col_comb choose colorant combination
from the following:
0:
@@ -528,6 +530,12 @@ incremental
generating patch values. Extra diagnostics and verbosity may be available if
a parameter is provided with a value greater than 1.
+ The -u flag causes structured JSON progress events
+ to be emitted to stdout in real-time during patch generation (such
+ as during OFPS point seeding and iterative optimization). This facilitates
+ subprocess integration with graphical host applications without requiring
+ text regex parsing.
+
The -d parameter sets the colorspace the test
values will be generated in. Video gray space is assumed to be an additive
space, where a zero device value will be black, and a maximum device value
diff --git a/target/ifarp.c b/target/ifarp.c
index bf29722..5674151 100644
--- a/target/ifarp.c
+++ b/target/ifarp.c
@@ -72,6 +72,15 @@
#include "ifarp.h"
#include "sort.h" /* Heap sort */
+#ifdef STANDALONE_TEST
+int json_progress = 0;
+void emit_json_progress(const char *stage, int percent) {
+ if (!json_progress) return;
+ printf("{\"event\": \"progress\", \"stage\": \"%s\", \"percent\": %d}\n", stage, percent);
+ fflush(stdout);
+}
+#endif
+
#ifdef DEBUG
static void dump_image(ifarp *s, int pcp);
static void dump_image_final(ifarp *s, int pcp);
@@ -385,13 +394,20 @@ void *od /* context for Perceptual function */
if (verb)
printf("Full points:\n");
+ int last_pct = -1;
for (i = 0; s->np < s->inp; i += 17) {
i %= s->np;
new_node(s, i);
+ int pc = (int)(100.0 * s->np/s->inp + 0.5);
if (verb) {
- int pc = (int)(100.0 * s->np/s->inp + 0.5);
printf(" % 3d%%%c",pc,cr_char); fflush(stdout);
}
+ if (json_progress && s->inp > 0) {
+ if (pc != last_pct) {
+ last_pct = pc;
+ emit_json_progress("generating", pc);
+ }
+ }
}
if (verb)
diff --git a/target/ofps.c b/target/ofps.c
index 4cd37f3..5b5f46e 100644
--- a/target/ofps.c
+++ b/target/ofps.c
@@ -137,6 +137,15 @@
#include "rspl.h"
#include "ofps.h"
+#ifdef STANDALONE_TEST
+int json_progress = 0;
+void emit_json_progress(const char *stage, int percent) {
+ if (!json_progress) return;
+ printf("{\"event\": \"progress\", \"stage\": \"%s\", \"percent\": %d}\n", stage, percent);
+ fflush(stdout);
+}
+#endif
+
//#include
#undef DEBUG
@@ -5713,6 +5722,7 @@ ofps_seed(ofps *s) {
int dofixed = 0; /* Do a fixed point next */
int abortonfail = 0; /* Abort on failing to add fixed points (isn't always good ?) */
int nsp = 0; /* Number of surface points */
+ int last_pct = -1;
aat_atrav_t *aat_tr;
if (s->verb)
@@ -6071,6 +6081,13 @@ ofps_seed(ofps *s) {
printf("%cAdded %d/%d",cr_char,s->np,s->tinp); fflush(stdout);
j = 0;
}
+ if (json_progress && s->tinp > 0) {
+ int pct = (int)(100.0 * (i + 1) / s->tinp);
+ if (pct != last_pct) {
+ last_pct = pct;
+ emit_json_progress("seeding", pct);
+ }
+ }
#ifdef DUMP_STRUCTURE
printf("Done node %d\n",i);
dump_node_vtxs(s, 0);
@@ -7983,6 +8000,9 @@ ofps *s
#endif
s->l_mstime = msec_time();
}
+ if (json_progress && maxits > 0) {
+ emit_json_progress("optimising", (int)(100.0 * (s->optit + 1) / maxits));
+ }
#ifdef DUMP_STRUCTURE
dump_node_vtxs(s, 1);
diff --git a/target/targen.c b/target/targen.c
index fd7bd73..d18b30b 100644
--- a/target/targen.c
+++ b/target/targen.c
@@ -158,6 +158,14 @@
/* ---------------------------- */
+int json_progress = 0;
+
+void emit_json_progress(const char *stage, int percent) {
+ if (!json_progress) return;
+ printf("{\"event\": \"progress\", \"stage\": \"%s\", \"percent\": %d}\n", stage, percent);
+ fflush(stdout);
+}
+
static double spow(double v, double p) {
if (v < 0.0)
return -pow(-v, p);
@@ -979,6 +987,7 @@ usage(int level, char *diag, ...) {
fprintf(stderr,"\n");
}
fprintf(stderr," -v [level] Verbose mode [optional level 1..N]\n");
+ fprintf(stderr," -u Emit structured JSON progress events to stdout\n");
fprintf(stderr," -d col_comb choose colorant combination from the following:\n");
for (i = 0; ; i++) {
char *desc;
@@ -1171,6 +1180,11 @@ int main(int argc, char *argv[]) {
}
}
+ /* Emit structured JSON progress events to stdout */
+ else if (argv[fa][1] == 'u') {
+ json_progress = 1;
+ }
+
/* Select the ink enumeration */
else if (argv[fa][1] == 'd') {
fa = nfa;
@@ -2585,6 +2599,7 @@ int main(int argc, char *argv[]) {
/* Create more points up to fsteps */
if (verb)
printf("\n");
+ int last_pct = -1;
for (j = 0, i = fxno; i < fsteps;) {
int e;
double sum;
@@ -2643,6 +2658,13 @@ int main(int argc, char *argv[]) {
if (verb) {
printf("%cAdded %d/%d",cr_char,i+1,fxno); fflush(stdout);
}
+ if (json_progress && fsteps > 0) {
+ int pc = (int)(100.0 * (i + 1) / fsteps);
+ if (pc != last_pct) {
+ last_pct = pc;
+ emit_json_progress("generating", pc);
+ }
+ }
i++, j++;
}
if (verb)
@@ -3032,10 +3054,16 @@ int main(int argc, char *argv[]) {
printf("%c%2d%%",cr_char,(int)(100.0 * (chend-1 - noswapped)/(npat-1.0)));
fflush(stdout);
}
+ if (json_progress && npat > 1) {
+ int pc = (int)(100.0 * (chend-1 - noswapped)/(npat-1.0));
+ emit_json_progress("optimising", pc);
+ }
}
}
if (verb)
printf("%c%2d%%",cr_char,100); fflush(stdout);
+ if (json_progress)
+ emit_json_progress("optimising", 100);
}
if (verb)
printf("\nOptimised display response delay = %f sec.\n",udelay);
diff --git a/target/targen.h b/target/targen.h
index c99b551..3115cdf 100644
--- a/target/targen.h
+++ b/target/targen.h
@@ -26,6 +26,8 @@ struct _fxpos {
int eloc; /* if >= 0, cgats index, to even location */
}; typedef struct _fxpos fxpos;
+extern int json_progress;
+void emit_json_progress(const char *stage, int percent);
#define TARGEN_H
#endif /* TARGEN_H */