From eba183807ae70715f7d7116b58eb6504fa7ce62c Mon Sep 17 00:00:00 2001 From: Gandalf Date: Fri, 21 Aug 2026 20:32:58 +0100 Subject: [PATCH] feat(target): add -u flag to targen for structured JSON progress output (fixes #2) --- doc/targen.html | 8 ++++++++ target/ifarp.c | 18 +++++++++++++++++- target/ofps.c | 20 ++++++++++++++++++++ target/targen.c | 28 ++++++++++++++++++++++++++++ target/targen.h | 2 ++ 5 files changed, 75 insertions(+), 1 deletion(-) 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 */ -- 2.39.5