Feature: targen -u (Structured JSON Progress Output) #11

Merged
gronod merged 1 commits from feature/targen-json-progress into main 2026-08-21 21:52:02 +01:00
5 changed files with 75 additions and 1 deletions
+8
View File
@@ -17,6 +17,8 @@
<p><span style="font-family: monospace;">targen [options] <i>outfile</i><br>
<a href="#v">-v [level]</a> &nbsp;&nbsp;&nbsp;Verbose mode [optional
verbose level, 1..n]<br>
<a href="#u">-u</a> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Emit
structured JSON progress events to stdout<br>
<a href="#d">-d col_comb</a> &nbsp;&nbsp;choose colorant combination
from the following:<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;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.<br>
<br>
<a name="u"></a> The <b>-u</b> flag causes structured JSON progress events
to be emitted to <tt>stdout</tt> 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.<br>
<br>
<a name="d"></a> The <b>-d</b> 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
+17 -1
View File
@@ -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)
+20
View File
@@ -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 <iperf.h>
#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);
+28
View File
@@ -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);
+2
View File
@@ -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 */