/** # Adaptive Ray caster This program sends pixel coordinates to stdout, reads the correspoding RGB codes from `stdin`, and writes a ppm image to `stderr`. */ #include "utils.h" scalar ref[], r[], g[], b[], * rgb = {r, g, b}; void refine_ref (Point point, scalar s) { foreach_child() s[] = nodata; } int maxlevel = 9; double tol = 5; int main(int argc, char ** argv) { if (argc > 1) maxlevel = atoi(argv[1]); if (argc > 2) tol = atof(argv[2]); int Ni = 1 << maxlevel; init_grid (1 << (maxlevel - 2)); ref.refine = refine_ref; foreach() ref[] = nodata; int count = 1; while (count > 0) { count = 0; foreach(reduction(+:count)) if (ref[] == nodata) count++; fwrite (&count, 1, sizeof(int), stdout); fflush (stdout); int s = sizeof(double); if (count > 0) { foreach_leaf() { //Z-order sequence if (ref[] == nodata) { fwrite (&x, s, 1, stdout); fwrite (&y, s, 1, stdout); } } fflush (stdout); foreach_leaf() { //Identical Z-order sequence if (ref[] == nodata) { for (scalar s in rgb) { unsigned char c; read (STDIN_FILENO, &c, 1); s[] = c; } } ref[] = 0.; } boundary (rgb); int d = min (depth() + 1, maxlevel); while(adapt_wavelet ({r,g,b}, (double[]){tol, tol, tol}, d, 99).nf); } } fprintf (stderr, "P6\n%d %d\n%d\n", Ni, Ni, 255); for (int j = 0; j < Ni; j++) { double yp = L0 - (j + 0.5)*L0/Ni; for (int i = 0; i < Ni; i++) { double xp = X0 + (i + 0.5)*L0/Ni; unsigned char px[3]; Point point = locate (xp, yp); if (level == maxlevel) { px[0] = r[]; px[1] = g[]; px[2] = b[]; } else { px[0] = interpolate_linear (point, (struct _interpolate){r, xp, yp}); px[1] = interpolate_linear (point, (struct _interpolate){g, xp, yp}); px[2] = interpolate_linear (point, (struct _interpolate){b, xp, yp}); } fwrite (px, 1, 3, stderr); } } fflush (stderr); }