summaryrefslogtreecommitdiff
path: root/rspl/t3ddf.c
diff options
context:
space:
mode:
authorJörg Frings-Fürst <debian@jff-webhosting.net>2014-09-01 13:56:46 +0200
committerJörg Frings-Fürst <debian@jff-webhosting.net>2014-09-01 13:56:46 +0200
commit22f703cab05b7cd368f4de9e03991b7664dc5022 (patch)
tree6f4d50beaa42328e24b1c6b56b6ec059e4ef21a5 /rspl/t3ddf.c
Initial import of argyll version 1.5.1-8debian/1.5.1-8
Diffstat (limited to 'rspl/t3ddf.c')
-rw-r--r--rspl/t3ddf.c570
1 files changed, 570 insertions, 0 deletions
diff --git a/rspl/t3ddf.c b/rspl/t3ddf.c
new file mode 100644
index 0000000..b0e7d18
--- /dev/null
+++ b/rspl/t3ddf.c
@@ -0,0 +1,570 @@
+/************************************************/
+/* Test RSPL in 3D with weak default function */
+/************************************************/
+
+/* Author: Graeme Gill
+ * Date: 20/11/2005
+ * Derived from cmatch.c
+ * Copyright 1995, 2005 Graeme W. Gill
+ *
+ * This material is licenced under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 :-
+ * see the License.txt file for licencing details.
+ */
+
+
+#define DEBUG
+#define DETAILED
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <math.h>
+#include "rspl.h"
+#include "tiffio.h"
+#include "plot.h"
+
+#ifdef NEVER
+#define INTERP spline_interp
+#else
+#define INTERP interp
+#endif
+
+#ifdef NEVER
+FILE *verbose_out = stdout;
+int verbose_level = 6; /* Current verbosity level */
+ /* 0 = none */
+ /* !0 = diagnostics */
+#endif /* NEVER */
+
+#define PLOTRES 256
+#define WIDTH 400 /* Raster size */
+#define HEIGHT 400
+
+#define MAX_ITS 500
+#define IT_TOL 0.0005
+#define GRES0 33 /* Default rspl resolutions */
+#define GRES1 33
+#define GRES2 33
+#undef NEVER
+#define ALWAYS
+
+/* two correction points along x = y = 0.5 */
+co test_points1[] = {
+// {{ 0.5, 0.5, 0.325 },{ 0.4 }}, /* 0 */
+// {{ 0.5, 0.5, 0.625 },{ 0.70 }} /* 1 */
+
+ {{ 0.4, 0.4, 0.325 },{ 0.5 }}, /* 0 */
+ {{ 0.4, 0.4, 0.625 },{ 0.8 }}, /* 1 */
+ {{ 0.5, 0.4, 0.325 },{ 0.5 }}, /* 0 */
+ {{ 0.5, 0.4, 0.625 },{ 0.8 }}, /* 1 */
+ {{ 0.6, 0.4, 0.325 },{ 0.5 }}, /* 0 */
+ {{ 0.6, 0.4, 0.625 },{ 0.8 }}, /* 1 */
+
+ {{ 0.4, 0.5, 0.325 },{ 0.5 }}, /* 0 */
+ {{ 0.4, 0.5, 0.625 },{ 0.8 }}, /* 1 */
+ {{ 0.5, 0.5, 0.325 },{ 0.5 }}, /* 0 */
+ {{ 0.5, 0.5, 0.625 },{ 0.8 }}, /* 1 */
+ {{ 0.6, 0.5, 0.325 },{ 0.5 }}, /* 0 */
+ {{ 0.6, 0.5, 0.625 },{ 0.8 }}, /* 1 */
+
+ {{ 0.4, 0.6, 0.325 },{ 0.5 }}, /* 0 */
+ {{ 0.4, 0.6, 0.625 },{ 0.8 }}, /* 1 */
+ {{ 0.5, 0.6, 0.325 },{ 0.5 }}, /* 0 */
+ {{ 0.5, 0.6, 0.625 },{ 0.8 }}, /* 1 */
+ {{ 0.6, 0.6, 0.325 },{ 0.5 }}, /* 0 */
+ {{ 0.6, 0.6, 0.625 },{ 0.8 }} /* 1 */
+};
+
+#ifdef NEVER
+#ifdef __STDC__
+#include <stdarg.h>
+void error(char *fmt, ...), warning(char *fmt, ...), verbose(int level, char *fmt, ...);
+#else
+#include <varargs.h>
+void error(), warning(), verbose();
+#endif
+#endif /* NEVER */
+
+void write_rgb_tiff(char *name, int width, int height, unsigned char *data);
+
+/* Weak default function */
+/* Linear along z, independent of x & y */
+static void wfunc(void *cbntx, double *out, double *in) {
+ out[0] = in[2];
+}
+
+void usage(void) {
+ fprintf(stderr,"Test 3D rspl interpolation with weak default function\n");
+ fprintf(stderr,"Author: Graeme W. Gill\n");
+ fprintf(stderr,"usage: t2d [options]\n");
+ fprintf(stderr," -t n Test set:\n");
+ fprintf(stderr," * 1 = two points along x & y\n");
+ fprintf(stderr," -w wweight Set weak default function weight (default 1.0)\n");
+ fprintf(stderr," -r resx,resy,resz Set grid resolutions (def %d %d %d)\n",GRES0,GRES1,GRES2);
+ fprintf(stderr," -h Test half scale resolution too\n");
+ fprintf(stderr," -q Test quarter scale resolution too\n");
+ fprintf(stderr," -x Use extra fitting\n");
+ fprintf(stderr," -s Test symetric smoothness (set asymetric -r !)\n");
+ fprintf(stderr," -s Test symetric smoothness\n");
+ fprintf(stderr," -p plot 4 slices, xy = 0.5, yz = 0.5, xz = 0.5, x=y=z\n");
+ exit(1);
+}
+
+int main(int argc, char *argv[]) {
+ int fa,nfa; /* argument we're looking at */
+ rspl *rss; /* Regularized spline structure */
+ rspl *rss2 = NULL; /* Regularized spline structure at half/quarter resolution */
+ datai low,high;
+ int gres[MXDI];
+ int gres2[MXDI];
+ double avgdev[MXDO];
+ co *test_points = test_points1;
+ int npoints = sizeof(test_points1)/sizeof(co);
+ double wweight = 1.0;
+ int twopass = 0;
+ int extra = 0;
+ int dosym = 0;
+ int doplot = 0;
+ int doh = 0;
+ int doq = 0;
+ int rsv;
+ int flags = RSPL_NOFLAGS;
+
+ low[0] = 0.0;
+ low[1] = 0.0;
+ low[2] = 0.0;
+ high[0] = 1.0;
+ high[1] = 1.0;
+ high[2] = 1.0;
+ gres[0] = GRES0;
+ gres[1] = GRES1;
+ gres[2] = GRES2;
+ avgdev[0] = 0.0;
+ avgdev[1] = 0.0;
+ avgdev[2] = 0.0;
+
+ /* Process the arguments */
+ for(fa = 1;fa < argc;fa++) {
+ nfa = fa; /* skip to nfa if next argument is used */
+ if (argv[fa][0] == '-') { /* Look for any flags */
+ char *na = NULL; /* next argument after flag, null if none */
+
+ if (argv[fa][2] != '\000')
+ na = &argv[fa][2]; /* next is directly after flag */
+ else {
+ if ((fa+1) < argc) {
+ if (argv[fa+1][0] != '-') {
+ nfa = fa + 1;
+ na = argv[nfa]; /* next is seperate non-flag argument */
+ }
+ }
+ }
+
+ if (argv[fa][1] == '?')
+ usage();
+
+ /* test set */
+ else if (argv[fa][1] == 't' || argv[fa][1] == 'T') {
+ int ix;
+ fa = nfa;
+ if (na == NULL) usage();
+ ix = atoi(na);
+ switch (ix) {
+ case 1:
+ test_points = test_points1;
+ npoints = sizeof(test_points1)/sizeof(co);
+ break;
+ default:
+ usage();
+ }
+
+ } else if (argv[fa][1] == 'w' || argv[fa][1] == 'W') {
+ fa = nfa;
+ if (na == NULL) usage();
+ wweight = atof(na);
+
+ } else if (argv[fa][1] == 'r' || argv[fa][1] == 'R') {
+ fa = nfa;
+ if (na == NULL) usage();
+ if (sscanf(na, " %d,%d,%d ", &gres[0], &gres[1], &gres[2]) != 2)
+ usage();
+
+ } else if (argv[fa][1] == 'h' || argv[fa][1] == 'H') {
+ doh = 1;
+
+ } else if (argv[fa][1] == 'q' || argv[fa][1] == 'Q') {
+ doh = 1;
+ doq = 1;
+
+ } else if (argv[fa][1] == 'p' || argv[fa][1] == 'P') {
+ doplot = 1;
+
+ } else if (argv[fa][1] == 's' || argv[fa][1] == 'S') {
+ dosym = 1;
+
+ } else if (argv[fa][1] == 'x' || argv[fa][1] == 'X') {
+ extra = 1;
+
+ } else if (argv[fa][1] == 's') {
+ dosym = 1;
+
+ } else
+ usage();
+ } else
+ break;
+ }
+
+
+ if (twopass)
+ flags |= RSPL_2PASSSMTH;
+
+ if (extra)
+ flags |= RSPL_EXTRAFIT2;
+
+ if (dosym)
+ flags |= RSPL_SYMDOMAIN;
+
+ /* Create the object */
+ rss = new_rspl(RSPL_NOFLAGS, 3, 1);
+
+ /* Fit to scattered data */
+ rss->fit_rspl_df(rss,
+ flags, /* Non-mon and clip flags */
+ test_points, /* Test points */
+ npoints, /* Number of test points */
+ low, high, gres, /* Low, high, resolution of grid */
+ low, high, /* Default data scale */
+ 1.0, /* Smoothing */
+ avgdev, /* Average Deviation */
+ NULL, /* iwidth */
+ wweight, /* weak function weight */
+ NULL, /* No context */
+ wfunc /* Weak function */
+ );
+ if (doh) {
+
+ if (doq) {
+ gres2[0] = gres[0]/4;
+ gres2[1] = gres[1]/4;
+ gres2[2] = gres[2]/4;
+ } else {
+ gres2[0] = gres[0]/2;
+ gres2[1] = gres[1]/2;
+ gres2[2] = gres[2]/2;
+ }
+
+ rss2 = new_rspl(RSPL_NOFLAGS, 3, 1);
+
+ /* Fit to scattered data */
+ rss2->fit_rspl_df(rss2,
+ flags, /* Non-mon and clip flags */
+ test_points, /* Test points */
+ npoints, /* Number of test points */
+ low, high, gres2, /* Low, high, resolution of grid */
+ low, high, /* Default data scale */
+ 1.0, /* Smoothing */
+ avgdev, /* Average Deviation */
+ NULL, /* iwidth */
+ wweight, /* weak function weight */
+ NULL, /* No context */
+ wfunc /* Weak function */
+ );
+ }
+
+ /* Test the interpolation with a slice in 2D */
+ for (rsv = 0; rsv <= doh; rsv++) {
+ double z[2][2] = { { 0.1, 0.5 }, { 0.5, 0.9 } };
+ double x1 = -0.2;
+ double x2 = 1.2;
+ double y1 = -0.2;
+ double y2 = 1.2;
+ double min = -0.0;
+ double max = 1.0;
+ rspl *rs;
+ unsigned char pa[HEIGHT][WIDTH][3];
+ co tco; /* Test point */
+ double sx,sy;
+ int i,j,k;
+
+ if (rsv == 0)
+ rs = rss;
+ else
+ rs = rss2;
+
+ sx = (x2 - x1)/(double)WIDTH;
+ sy = (y2 - y1)/(double)HEIGHT;
+
+ for (j=0; j < HEIGHT; j++) {
+ double jj = j/(HEIGHT-1.0);
+ tco.p[1] = (double)((HEIGHT-1) - j) * sy + y1;
+ for (i = 0; i < WIDTH; i++) {
+ double ii = j/(HEIGHT-1.0);
+ tco.p[0] = (double)i * sx + x1;
+
+ tco.p[2] = (1.0-ii) * (1.0-jj) * z[0][0]
+ + (1.0-ii) * jj * z[0][1]
+ + ii * (1.0-jj) * z[1][0]
+ + ii * jj * z[1][1];
+
+ if (rs->INTERP(rs, &tco)) {
+ pa[j][i][0] = 0; /* Out of bounds in green */
+ pa[j][i][1] = 100;
+ pa[j][i][2] = 0;
+ } else {
+ int m;
+ /* printf("%d %d, %f %f returned %f\n",i,j,tco.p[0],tco.p[1],tco.v[0]); */
+ m = (int)((255.0 * (tco.v[0] - min)/(max - min)) + 0.5);
+ if (m < 0) {
+ pa[j][i][0] = 20; /* Dark blue */
+ pa[j][i][1] = 20;
+ pa[j][i][2] = 50;
+ } else if (m > 255) {
+ pa[j][i][0] = 230; /* Light blue */
+ pa[j][i][1] = 230;
+ pa[j][i][2] = 255;
+ } else {
+ pa[j][i][0] = m; /* Level in grey */
+ pa[j][i][1] = m;
+ pa[j][i][2] = m;
+ }
+ }
+ }
+ }
+
+ /* Mark verticies in red */
+ for(k = 0; k < npoints; k++) {
+ j = (int)((HEIGHT * (y2 - test_points[k].p[1])/(y2 - y1)) + 0.5);
+ i = (int)((WIDTH * (test_points[k].p[0] - x1)/(x2 - x1)) + 0.5);
+ pa[j][i][0] = 255;
+ pa[j][i][1] = 0;
+ pa[j][i][2] = 0;
+ }
+ write_rgb_tiff(rsv == 0 ? "t3d.tif" : "t3dh.tif" ,WIDTH,HEIGHT,(unsigned char *)pa);
+ }
+
+ /* Plot out 4 slices */
+ if (doplot) {
+ int slice;
+
+ for (slice = 0; slice < 4; slice++) {
+ co tp; /* Test point */
+ double x[PLOTRES];
+ double ya[PLOTRES];
+ double yb[PLOTRES];
+ double xx,yy,zz;
+ double x1,x2,y1,y2,z1,z2;
+ double sx,sy,sz;
+ int i,n;
+
+ /* Set up slice to plot */
+ if (slice == 0) {
+ x1 = 0.5; y1 = 0.5, z1 = 0.0;
+ x2 = 0.5; y2 = 0.5, z2 = 1.0;
+ printf("Plot along z at x = y = 0.5\n");
+ n = PLOTRES;
+ } else if (slice == 1) {
+ x1 = 0.0; y1 = 0.5, z1 = 0.5;
+ x2 = 1.0; y2 = 0.5, z2 = 0.5;
+ printf("Plot along x at y = z = 0.5\n");
+ n = PLOTRES;
+ } else if (slice == 2) {
+ x1 = 0.5; y1 = 0.0, z1 = 0.5;
+ x2 = 0.5; y2 = 1.0, z2 = 0.5;
+ printf("Plot along y at x = z = 0.5\n");
+ n = PLOTRES;
+ } else {
+ x1 = 0.0; y1 = 0.0, z1 = 0.0;
+ x2 = 1.0; y2 = 1.0, z2 = 1.0;
+ printf("Plot along x = y = z\n");
+ n = PLOTRES;
+ }
+
+ sx = (x2 - x1)/n;
+ sy = (y2 - y1)/n;
+ sz = (z2 - z1)/n;
+
+ xx = x1;
+ yy = y1;
+ zz = z1;
+ for (i = 0; i < n; i++) {
+ double vv = i/(n-1.0);
+ x[i] = vv;
+ tp.p[0] = xx;
+ tp.p[1] = yy;
+ tp.p[2] = zz;
+
+ if (rss->INTERP(rss, &tp))
+ tp.v[0] = -0.1;
+ ya[i] = tp.v[0];
+
+ if (doh) {
+ if (rss2->INTERP(rss2, &tp))
+ tp.v[0] = -0.1;
+ yb[i] = tp.v[0];
+ }
+
+ xx += sx;
+ yy += sy;
+ zz += sz;
+ }
+
+ /* Plot the result */
+ if (doh)
+ do_plot(x,ya,yb,NULL,n);
+ else
+ do_plot(x,ya,NULL,NULL,n);
+ }
+ }
+
+ /* Report the fit */
+ {
+ co tco; /* Test point */
+ int k;
+ double avg = 0;
+ double max = 0.0;
+
+ for(k = 0; k < npoints; k++) {
+ double err;
+ tco.p[0] = test_points[k].p[0];
+ tco.p[1] = test_points[k].p[1];
+ tco.p[2] = test_points[k].p[2];
+ rss->INTERP(rss, &tco);
+
+ err = tco.v[0] - test_points[k].v[0];
+ err = fabs(err);
+
+ avg += err;
+ if (err > max)
+ max = err;
+ }
+ avg /= (double)npoints;
+ printf("Max error %f%%, average %f%%\n",100.0 * max, 100.0 * avg);
+ }
+ return 0;
+}
+
+/* ---------------------- */
+/* Tiff diagnostic output */
+
+void
+write_rgb_tiff(
+char *name,
+int width,
+int height,
+unsigned char *data
+) {
+ int y;
+ unsigned char *dp;
+ TIFF *tif;
+
+ if ((tif = TIFFOpen(name, "w")) == NULL) {
+ fprintf(stderr,"Failed to open output TIFF file '%s'\n",name);
+ exit (-1);
+ }
+
+ TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, width);
+ TIFFSetField(tif, TIFFTAG_IMAGELENGTH, height);
+ TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
+ TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 3);
+ TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8);
+ TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
+ TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
+ TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
+
+ for (dp = data, y = 0; y < height; y++, dp += 3 * width) {
+ if (TIFFWriteScanline(tif, (tdata_t)dp, y, 0) < 0) {
+ fprintf(stderr,"WriteScanline Failed at line %d\n",y);
+ exit (-1);
+ }
+ }
+ (void) TIFFClose(tif);
+}
+
+#ifdef NEVER
+/******************************************************************/
+/* Error/debug output routines */
+/******************************************************************/
+
+/* Basic printf type error() and warning() routines */
+
+#ifdef __STDC__
+void
+error(char *fmt, ...)
+#else
+void
+error(va_alist)
+va_dcl
+#endif
+{
+ va_list args;
+#ifndef __STDC__
+ char *fmt;
+#endif
+
+ fprintf(stderr,"cmatch: Error - ");
+#ifdef __STDC__
+ va_start(args, fmt);
+#else
+ va_start(args);
+ fmt = va_arg(args, char *);
+#endif
+ vfprintf(stderr, fmt, args);
+ va_end(args);
+ fprintf(stderr, "\n");
+ fflush(stdout);
+ exit (-1);
+}
+
+#ifdef __STDC__
+void
+warning(char *fmt, ...)
+#else
+void
+warning(va_alist)
+va_dcl
+#endif
+{
+ va_list args;
+#ifndef __STDC__
+ char *fmt;
+#endif
+
+ fprintf(stderr,"cmatch: Warning - ");
+#ifdef __STDC__
+ va_start(args, fmt);
+#else
+ va_start(args);
+ fmt = va_arg(args, char *);
+#endif
+ vfprintf(stderr, fmt, args);
+ va_end(args);
+ fprintf(stderr, "\n");
+}
+
+#ifdef __STDC__
+void
+verbose(int level, char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+#else
+verbose(va_alist)
+va_dcl
+{
+ va_list args;
+ int level;
+ char *fmt;
+ va_start(args);
+ level = va_arg(args, int);
+ fmt = va_arg(args, char *);
+#endif
+ if (verbose_level >= level)
+ {
+ fprintf(verbose_out,"cmatch: ");
+ vfprintf(verbose_out, fmt, args);
+ fprintf(verbose_out, "\n");
+ fflush(verbose_out);
+ }
+ va_end(args);
+}
+#endif /* NEVER */