682 lines
27 KiB
C
682 lines
27 KiB
C
#ifndef RSPL_H
|
|
#define RSPL_H
|
|
|
|
/*
|
|
* Argyll Color Management System
|
|
* Multi-dimensional regularized spline data structure
|
|
*
|
|
* Author: Graeme W. Gill
|
|
* Date: 2000/10/29
|
|
*
|
|
* Copyright 1996 - 2004 Graeme W. Gill
|
|
* All rights reserved.
|
|
*
|
|
* This material is licenced under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 :-
|
|
* see the License.txt file for licencing details.
|
|
*/
|
|
|
|
#include "numsup.h"
|
|
|
|
/** Configuration **/
|
|
|
|
#undef CHECK_NNLU /* [und] Check nn lookup results against exaustive searches */
|
|
/* as well as other asserts. */
|
|
|
|
/** General Limits **/
|
|
|
|
#define MXDI 10 /* Maximum input dimensionality */
|
|
#define MXDO 10 /* Maximum output dimensionality (Is not fully tested!!!) */
|
|
#define LOG2MXDI 4 /* log2 MXDI */
|
|
#define DEF2MXDI 16 /* Default allocation size for 2^di (di=4) */
|
|
#define POW2MXDI 1024 /* 2 ^ MXDI */
|
|
#define DEF3MXDI 81 /* Default allocation size for 3^di (di=4) */
|
|
#define POW3MXDI 59049 /* 3 ^ MXDI */
|
|
#define HACOMPS ((POW3MXDI + 2 * MXDI + 1)/2) /* Maximum number of array components */
|
|
/* 295255 - not used ? */
|
|
|
|
#if MXDI > MXDO /* Maximum of either DI or DO */
|
|
# define MXDIDO MXDI
|
|
#else
|
|
# define MXDIDO MXDO
|
|
#endif
|
|
|
|
/* RESTRICTED SIZE Limits, used for reverse and spline */
|
|
|
|
#define MXRI 4 /* Maximum input dimensionality */
|
|
#define MXRO 10 /* Maximum output dimensionality (Is not fully tested!!!) */
|
|
#define LOG2MXRI 2 /* log2 MXRI */
|
|
#define POW2MXRI 16 /* 2 ^ MXRI */
|
|
#define POW3MXRI 81 /* 3 ^ MXRI */
|
|
#define POW2MXRO 1024 /* 2 ^ MXRO */
|
|
|
|
#if MXRI > MXRO /* Maximum of either RI or RO */
|
|
# define MXRIRO MXRI
|
|
#else
|
|
# define MXRIRO MXRO
|
|
#endif
|
|
|
|
|
|
/** Definitions **/
|
|
|
|
/* General data point position/value structure */
|
|
/* This is mean't to be compatible with color structure */
|
|
/* when MXDI and MXDO == 4 */
|
|
typedef double datai[MXDI];
|
|
typedef double datao[MXDO];
|
|
typedef float dati[MXDI];
|
|
typedef float dato[MXDO];
|
|
|
|
/* Restricted size versions */
|
|
typedef double ratai[MXRI];
|
|
typedef double ratao[MXRO];
|
|
typedef float rati[MXRI];
|
|
typedef float rato[MXRO];
|
|
|
|
/* Interface coordinate value */
|
|
typedef struct {
|
|
double p[MXDI]; /* coordinate position */
|
|
double v[MXDO]; /* function values */
|
|
} co;
|
|
|
|
/* Interface coordinate value + weighting */
|
|
typedef struct {
|
|
double p[MXDI]; /* coordinate position */
|
|
double v[MXDO]; /* function values */
|
|
double w; /* Weight to give this point, nominally 1.0 */
|
|
} cow;
|
|
|
|
/* Interface coordinate value + per out component weighting */
|
|
typedef struct {
|
|
double p[MXDI]; /* coordinate position */
|
|
double v[MXDO]; /* function values */
|
|
double w[MXDO]; /* Weight to give this point, nominally 1.0 */
|
|
} coww;
|
|
|
|
/* Scattered data Per data point data (internal) */
|
|
struct _rpnts {
|
|
double p[MXDI]; /* Data position [di] */
|
|
double v[MXDO]; /* Data value [fdi] */
|
|
double k[MXDO]; /* Weight factor (nominally 1.0, less for lower confidence data point) */
|
|
// double fe; /* Fit error in output pass (ausm) */
|
|
}; typedef struct _rpnts rpnts;
|
|
|
|
/* Hermite interpolation magic data */
|
|
typedef struct {
|
|
int p; /* The parameter power combination */
|
|
int i; /* The surrounding cube vertex index */
|
|
int j; /* The dimension combination */
|
|
float wgt;
|
|
} magic_data;
|
|
|
|
#include "rev.h" /* Reverse interpolation defintions */
|
|
#include "gam.h" /* Gamut defintions */
|
|
|
|
/* Sub-fit itteration information */
|
|
typedef struct {
|
|
int niters; /* Number of multigrid itterations needed */
|
|
int **ires; /* Resolution for each itteration and dimension */
|
|
void **mgtmps[MXDO]; /* Store pointers to re-usable mgtmp when incremental */
|
|
/* (These don't seem to be used anymore. was incremental removed ?) */
|
|
} it_info;
|
|
|
|
/* Structure for final resolution multi-dimensional regularized spline data */
|
|
struct _rspl {
|
|
|
|
/* Global rspl state */
|
|
int debug; /* 0 = no debug */
|
|
int verbose; /* 0 = no verbose */
|
|
double smooth; /* Smoothness factor */
|
|
double avgdev[MXDO];
|
|
/* Average Deviation of function values as proportion of function range. */
|
|
int symdom; /* 0 = non-symetric smoothness with different grid resolutions, */
|
|
/* 1 = symetric smoothness with different grid resolutions, */
|
|
|
|
int di; /* Input dimensionality */
|
|
int fdi; /* Output function dimensionality */
|
|
|
|
/* Weak default function related information */
|
|
double weak; /* Weak total weighting, nominal = 1.0 */
|
|
void *dfctx; /* Opaque function context */
|
|
void (*dfunc)(void *cbntx, double *out, double *in);
|
|
/* Function to set from */
|
|
|
|
/* Scattered Data point related information */
|
|
int ausm; /* Automatic smoothing enabled flag. */
|
|
struct {
|
|
int no; /* Number of data points in array */
|
|
rpnts *a; /* Array of data points */
|
|
datao vl, vw; /* Data value low/width - not used */
|
|
datao va; /* Data value averages */
|
|
// double fea; /* Fit error average */
|
|
} d;
|
|
|
|
it_info ii; /* Main itteration information for final rspl */
|
|
|
|
it_info as_ii; /* Automatic smoothing pre-fit itteration info */
|
|
it_info asm_ii; /* Automatic smoothing map itteration info */
|
|
|
|
/* Grid points data */
|
|
struct {
|
|
int res[MXDI]; /* Single dimension grid resolution for each axis */
|
|
int bres, brix; /* Biggest resolution and its index */
|
|
double mres; /* Geometric mean res[] */
|
|
int no; /* Total number of points in grid = res[0] * res[1] * .. res[di-1] */
|
|
datai l,h,w; /* Grid low, high, grid cell width */
|
|
/* This is used to map from the input domain to the grid */
|
|
|
|
datao fmin, fmax; /* Min & max values of grid output (function) variables */
|
|
int fminx[MXDO], fmaxx[MXDO]; /* Grid indexes of points that set min/max output values */
|
|
double fscale; /* Overall magnitude of output values */
|
|
double *ipos[MXDI]; /* Optional relative grid cell position for each input dim cell, */
|
|
/* gres[] entries per dimension. Allows for the possibility of */
|
|
/* a non-uniform grid spacing, by adjusting the curvature evaluation */
|
|
/* appropriately. */
|
|
int fminmax_valid; /* Min/max/scale cached values valid flag. */
|
|
int limitv_cached; /* Flag: Ink limit values have been set in the grid array */
|
|
|
|
#define G_XTRA 3 /* Extra floats per grid point */
|
|
float *alloc; /* Grid points allocated address */
|
|
float *a; /* Grid point flags + data */
|
|
/* Array is res[] ^ di entries float[fdi+G_XTRA], offset by G_XTRA */
|
|
/* (But is expanded when spline interpolaton is active) */
|
|
/* float[-1] contains the ink limit function value, L_UNINIT if not initd */
|
|
/* float[-2] contains the edge flag values, 3 bits per in dim. */
|
|
/* float[-3] contains the touched flag generation count. */
|
|
/* (k value for non-linear fit would be another entry.) */
|
|
/* Flag values are 3 bits for each dimension. Bits 1,0 form */
|
|
/* 2 bit distance from edge: 0 for on edge of grid, */
|
|
/* 1 for next row, 2 for 3rd row and beyond. If bit 2 is set, */
|
|
/* then we are on the lower edge. This limits di to 10 or less, */
|
|
/* with the two MS bits spare. */
|
|
int pss; /* Grid point structure size = fdi+G_XTRA */
|
|
|
|
/* Uninitialised limit value */
|
|
#define L_UNINIT ((float)-1e38)
|
|
|
|
#define FL_BITS 3 /* flag bits per dimension */
|
|
/* Macros to access flags. Arguments are a pointer to base grid point and */
|
|
/* Flag value is distance from edge in bottom 2 bits, values 0, 1 or 2 maximum. */
|
|
/* bit 2 is set if the distance is to the lower edge. ie: */
|
|
/* 0 = at top edge */
|
|
/* 1 = next to top edge */
|
|
/* 2, 6 = not at or next to any edge */
|
|
/* 4 = at bottom edge */
|
|
/* 5 = next to bottom edge */
|
|
#define FLV(fp) (*((unsigned int *)((fp)-2)))
|
|
/* Init the flag values to 0 */
|
|
#define I_FL(fp) (FLV(fp) = 0)
|
|
/* Return 3 bit flag data */
|
|
#define G_FL(fp,di) ((FLV(fp) >> (3 * (di))) & 7)
|
|
/* Set 3 bit flag data */
|
|
#define S_FL(fp,di,v) (FLV(fp) = (FLV(fp) & ~(7 << (3 * (di)))) | (((v) & 7) << (3 * (di))))
|
|
|
|
/* Macro to access touched flag. Arguments are a pointer to base grid point. */
|
|
#define TOUCHF(fp) (*((unsigned int *)((fp)-3)))
|
|
|
|
/* Grid array offset lookups - in floats */
|
|
int ci[MXDI]; /* Grid coordinate increments for each dimension */
|
|
int fci[MXDI]; /* Grid coordinate increments for each dimension in floats */
|
|
int *hi; /* 2^di Combination offset for sequence through cube. */
|
|
int a_hi[DEF2MXDI]; /* Default allocation for *hi */
|
|
int *fhi; /* Combination offset for sequence through cube of */
|
|
/* 2^di points, starting at base, in floats */
|
|
int a_fhi[DEF2MXDI];/* Default allocation for *hi */
|
|
|
|
unsigned int touch; /* Cell touched flag count */
|
|
} g;
|
|
|
|
|
|
/* Ink limit related information */
|
|
int limiten; /* Flag - limiting is enabled */
|
|
double (*limitf)(void *cntx, double *in); /* Optional input space qualifier function. */
|
|
void *lcntx; /* Context passed to limit() */
|
|
double limitv; /* Value not to be exceeded by limit() */
|
|
|
|
/* Hermite spline interpolation support */
|
|
struct {
|
|
magic_data *magic; /* Magic matrix - non-zero elements only, Non-NULL if splining */
|
|
int nm; /* number in magic data list */
|
|
int spline; /* Non-zero if spline data is present in g.a */
|
|
/* Changes from float g.a[res ^ di][fdi+G_XTRA], offset by G_XTRA, */
|
|
/* to float g.a[res ^ di][(2^di * fdi)+G_XTRA], offset by G_XTRA, */
|
|
} spline;
|
|
|
|
/* Gamut support */
|
|
gam_struct gam; /* See gam.h */
|
|
|
|
/* Reverse Interpolation support */
|
|
rev_struct rev; /* See rev.h */
|
|
|
|
/* Methods */
|
|
|
|
/* Free ourselves */
|
|
void (*del)(struct _rspl *ss);
|
|
|
|
/* Combination lags used by various functions */
|
|
#define RSPL_NOFLAGS 0x0000
|
|
#define RSPL_AUTOSMOOTH 0x0001 /* Automatically determin local optimal avgdev smoothing */
|
|
#define RSPL_SYMDOMAIN 0x0004 /* Maintain symetric smoothness with nonsym. resolution */
|
|
#define RSPL_SET_APXLS 0x0020 /* For set_rspl, adjust samples for aproximate least squares */
|
|
#define RSPL_FASTREVSETUP 0x0010 /* Do a fast reverse setup at the cost of subsequent speed */
|
|
#define RSPL_VERBOSE 0x8000 /* Turn on print progress messages */
|
|
#define RSPL_NOVERBOSE 0x4000 /* Turn off print progress messages */
|
|
|
|
/* Initialise from scattered data. */
|
|
/* Return non-zero if result is non-monotonic */
|
|
int
|
|
(*fit_rspl)(
|
|
struct _rspl *s, /* this */
|
|
int flags, /* Combination of flags */
|
|
co *d, /* Array holding position and function values of data points */
|
|
int ndp, /* Number of data points */
|
|
datai glow, /* Grid low scale - will expand to enclose data, NULL = default 0.0 */
|
|
datai ghigh, /* Grid high scale - will expand to enclose data, NULL = default 1.0 */
|
|
int gres[MXDI], /* Spline grid resolution, ncells = gres-1 */
|
|
datao vlow, /* Data value low normalize, NULL = default 0.0 */
|
|
datao vhigh, /* Data value high normalize - NULL = default 1.0 */
|
|
double smooth, /* Smoothing factor, 0.0 = default 1.0 */
|
|
double avgdev[MXDO],
|
|
/* Average Deviation of function values as proportion of function range, */
|
|
/* typical value 0.005 (aprox. = 0.564 times the standard deviation) */
|
|
/* NULL = default 0.005 */
|
|
double *ipos[MXDI] /* Optional relative grid cell position for each input dim cell, */
|
|
/* gres[] entries per dimension. Used to scale smoothness criteria */
|
|
);
|
|
|
|
/* Initialise from scattered data, with per point weighting. */
|
|
/* Return non-zero if result is non-monotonic */
|
|
int
|
|
(*fit_rspl_w)(
|
|
struct _rspl *s, /* this */
|
|
int flags, /* Combination of flags */
|
|
cow *d, /* Array holding position, function and weight values of data points */
|
|
int ndp, /* Number of data points */
|
|
datai glow, /* Grid low scale - will expand to enclose data, NULL = default 0.0 */
|
|
datai ghigh, /* Grid high scale - will expand to enclose data, NULL = default 1.0 */
|
|
int gres[MXDI], /* Spline grid resolution, ncells = gres-1 */
|
|
datao vlow, /* Data value low normalize, NULL = default 0.0 */
|
|
datao vhigh, /* Data value high normalize - NULL = default 1.0 */
|
|
double smooth, /* Smoothing factor, 0.0 = default 1.0 */
|
|
double avgdev[MXDO],
|
|
/* Average Deviation of function values as proportion of function range, */
|
|
/* typical value 0.005 (aprox. = 0.564 times the standard deviation) */
|
|
/* NULL = default 0.005 */
|
|
double *ipos[MXDI] /* Optional relative grid cell position for each input dim cell, */
|
|
/* gres[] entries per dimension. Used to scale smoothness criteria */
|
|
);
|
|
|
|
/* Initialise from scattered data, with per point individual out weighting. */
|
|
/* Return non-zero if result is non-monotonic */
|
|
int
|
|
(*fit_rspl_ww)(
|
|
struct _rspl *s, /* this */
|
|
int flags, /* Combination of flags */
|
|
coww *d, /* Array holding position, function and weight values of data points */
|
|
int ndp, /* Number of data points */
|
|
datai glow, /* Grid low scale - will expand to enclose data, NULL = default 0.0 */
|
|
datai ghigh, /* Grid high scale - will expand to enclose data, NULL = default 1.0 */
|
|
int gres[MXDI], /* Spline grid resolution, ncells = gres-1 */
|
|
datao vlow, /* Data value low normalize, NULL = default 0.0 */
|
|
datao vhigh, /* Data value high normalize - NULL = default 1.0 */
|
|
double smooth, /* Smoothing factor, 0.0 = default 1.0 */
|
|
double avgdev[MXDO],
|
|
/* Average Deviation of function values as proportion of function range, */
|
|
/* typical value 0.005 (aprox. = 0.564 times the standard deviation) */
|
|
/* NULL = default 0.005 */
|
|
double *ipos[MXDI] /* Optional relative grid cell position for each input dim cell, */
|
|
/* gres[] entries per dimension. Used to scale smoothness criteria */
|
|
);
|
|
|
|
/* Initialise from scattered data, with weak default function. */
|
|
/* Return non-zero if result is non-monotonic */
|
|
int
|
|
(*fit_rspl_df)(
|
|
struct _rspl *s, /* this */
|
|
int flags, /* Combination of flags */
|
|
co *d, /* Array holding position and function values of data points */
|
|
int ndp, /* Number of data points */
|
|
datai glow, /* Grid low scale - will expand to enclose data, NULL = default 0.0 */
|
|
datai ghigh, /* Grid high scale - will expand to enclose data, NULL = default 1.0 */
|
|
int gres[MXDI], /* Spline grid resolution, ncells = gres-1 */
|
|
datao vlow, /* Data value low normalize, NULL = default 0.0 */
|
|
datao vhigh, /* Data value high normalize - NULL = default 1.0 */
|
|
double smooth, /* Smoothing factor, 0.0 = default 1.0 */
|
|
double avgdev[MXDO],
|
|
/* Average Deviation of function values as proportion of function range, */
|
|
/* typical value 0.005 (aprox. = 0.564 times the standard deviation) */
|
|
/* NULL = default 0.005 */
|
|
double *ipos[MXDI],/* Optional relative grid cell position for each input dim cell, */
|
|
/* gres[] entries per dimension. Used to scale smoothness criteria */
|
|
double weak, /* Weak weighting, nominal = 1.0 */
|
|
void *cbntx, /* Opaque function context */
|
|
void (*func)(void *cbntx, double *out, double *in) /* Function to set from */
|
|
);
|
|
|
|
/* Initialise from scattered data, with per point weighting and weak default function. */
|
|
/* Return non-zero if result is non-monotonic */
|
|
int
|
|
(*fit_rspl_w_df)(
|
|
struct _rspl *s, /* this */
|
|
int flags, /* Combination of flags */
|
|
cow *d, /* Array holding position, function and weight values of data points */
|
|
int ndp, /* Number of data points */
|
|
datai glow, /* Grid low scale - will expand to enclose data, NULL = default 0.0 */
|
|
datai ghigh, /* Grid high scale - will expand to enclose data, NULL = default 1.0 */
|
|
int gres[MXDI], /* Spline grid resolution, ncells = gres-1 */
|
|
datao vlow, /* Data value low normalize, NULL = default 0.0 */
|
|
datao vhigh, /* Data value high normalize - NULL = default 1.0 */
|
|
double smooth, /* Smoothing factor, 0.0 = default 1.0 */
|
|
double avgdev[MXDO],
|
|
/* Average Deviation of function values as proportion of function range, */
|
|
/* typical value 0.005 (aprox. = 0.564 times the standard deviation) */
|
|
/* NULL = default 0.005 */
|
|
double *ipos[MXDI],/* Optional relative grid cell position for each input dim cell, */
|
|
/* gres[] entries per dimension. Used to scale smoothness criteria */
|
|
double weak, /* Weak weighting, nominal = 1.0 */
|
|
void *cbntx, /* Opaque function context */
|
|
void (*func)(void *cbntx, double *out, double *in) /* Function to set from */
|
|
);
|
|
|
|
/* Initialize the grid from a provided function. By default the grid */
|
|
/* values are set to exactly the value returned by func(), unless the */
|
|
/* RSPL_SET_APXLS flag is set, in which case an attempt is made to have */
|
|
/* the grid points represent a least squares aproximation to the underlying */
|
|
/* surface. */
|
|
/* Grid index values are supplied "under" in[] at *((int*)&in[-e-1]) */
|
|
/* Return non-monotonic status */
|
|
int
|
|
(*set_rspl)(
|
|
struct _rspl *s, /* this */
|
|
int flags, /* Combination of flags */
|
|
void *cbntx, /* Opaque function context */
|
|
void (*func)(void *cbntx, double *out, double *in), /* Function to set from */
|
|
datai glow, /* Grid low scale - will expand to enclose data, NULL = default 0.0 */
|
|
datai ghigh, /* Grid high scale - will expand to enclose data, NULL = default 1.0 */
|
|
int gres[MXDI], /* Spline grid resolution */
|
|
datao vlow, /* Data value low normalize, NULL = default 0.0 */
|
|
datao vhigh /* Data value high normalize - NULL = default 1.0 */
|
|
);
|
|
|
|
/* Re-set values from a function. Grid index values are supplied */
|
|
/* "under" in[] at *((int*)&iv[-e-1]) */
|
|
/* Return non-monotonic status. Clears all the reverse lookup information. */
|
|
/* It is assumed that the output range remains unchanged. */
|
|
/* Existing output values are supplied in out[] */
|
|
int
|
|
(*re_set_rspl)(
|
|
struct _rspl *s,/* this */
|
|
int flags, /* Combination of flags (not used) */
|
|
void *cbntx, /* Opaque function context */
|
|
void (*func)(void *cbntx, double *out, double *in) /* Function to set from */
|
|
);
|
|
|
|
/* Scan the rspl grid point locations and values. Grid index values are */
|
|
/* supplied "under" in[] at *((int*)&iv[-e-1]) */
|
|
/* Return non-monotonic status. */
|
|
void
|
|
(*scan_rspl)(
|
|
struct _rspl *s, /* this */
|
|
int flags, /* Combination of flags (not used) */
|
|
void *cbntx, /* Opaque function context */
|
|
void (*func)(void *cbntx, double *out, double *in) /* Function that gets given values */
|
|
);
|
|
|
|
/* Tune a single value. */
|
|
/* Return 0 on success, 1 if input clipping occured, 2 if output clipping occured */
|
|
int (*tune_value) (
|
|
struct _rspl *s, /* Pointer to Lut object */
|
|
co *p /* Target value */
|
|
);
|
|
|
|
/* Set values by multi-grid optimisation using the provided function. */
|
|
int (*opt_rspl)(
|
|
struct _rspl *s,/* this */
|
|
int flags, /* Combination of flags */
|
|
int tdi, /* Dimensionality of target data */
|
|
int adi, /* Additional grid point data allowance */
|
|
double **vdata, /* di^2 array of function, target and additional values to init */
|
|
/* array corners with. */
|
|
double (*func)(void *fdata, double *inout, double *surav, int first, double *cw),
|
|
/* Optimisation function */
|
|
void *fdata, /* Opaque data needed by function */
|
|
datai glow, /* Grid low scale - NULL = default 0.0 */
|
|
datai ghigh, /* Grid high scale - NULL = default 1.0 */
|
|
int gres[MXDI], /* Spline grid resolution */
|
|
datao vlow, /* Data value low normalize - NULL = default 0.0 */
|
|
datao vhigh /* Data value high normalize - NULL = default 1.0 */
|
|
);
|
|
|
|
/* Filter the existing values using the surrounding 3x3 cells. */
|
|
/* Grid index values are supplied "under" in[] */
|
|
void
|
|
(*filter_rspl)(
|
|
struct _rspl *s, /* this */
|
|
int flags, /* Combination of flags (not used) */
|
|
void *cbntx, /* Opaque function context */
|
|
void (*func)(void *cbntx, float **out, double *in, int cvi) /* Function to set from */
|
|
);
|
|
|
|
/* Do forward interpolation */
|
|
/* Return 0 if OK, 1 if input was clipped to grid */
|
|
int (*interp)(
|
|
struct _rspl *s, /* this */
|
|
co *p); /* Input and output values */
|
|
|
|
/* Do forward 1d interpolation of and return the value. */
|
|
double (*interp1)( /* Return value */
|
|
struct _rspl *s, /* this */
|
|
double in); /* Input value */
|
|
|
|
/* Do forward (partial) interpolation to allow input & output curves to be applied, */
|
|
/* and allow input delta E to be estimated from output delta E. */
|
|
/* Call with input value in p1[0].p[], */
|
|
/* In order smallest to largest weight: */
|
|
/* Return di+1 vertex values in p1[]].v[] and */
|
|
/* 0-1 sub-cell weight values as (p1[].p[0] - p1[].p[1]). */
|
|
/* Optionally in input channel order: */
|
|
/* Returns di+1 partial derivatives + base value in p2[].v[], */
|
|
/* with matching weight values for each in p2[].p[0] (last weight = 1)*/
|
|
/* Return 0 if OK, 1 if input was clipped to grid */
|
|
int (*part_interp)(
|
|
struct _rspl *s, /* this */
|
|
co *p1,
|
|
co *p2); /* optional - return partial derivatives for each input channel */
|
|
|
|
/* Do splined forward interpolation. RESTRICTED SIZE */
|
|
/* Return 0 if OK, 1 if input was clipped to grid */
|
|
int (*spline_interp)(
|
|
struct _rspl *s, /* this */
|
|
co *p); /* Input and output values */
|
|
|
|
|
|
/* ------------------------------- */
|
|
/* Create a surface gamut representation. */
|
|
/* Return NZ on error */
|
|
int (*comp_gamut)(struct _rspl *s,
|
|
double *cent, /* Optional center of gamut [fdi], default center of out range */
|
|
double *scale, /* Optional Scale of output values in vector to center [fdi] */
|
|
/* default 1.0 */
|
|
void (*outf)(void *cntxf, double *out, double *in), /* Optional rspl val -> output value */
|
|
void *cntxf, /* Context for function */
|
|
void (*outb)(void *cntxb, double *out, double *in), /* Optional output value -> rspl val */
|
|
void *cntxb /* Context for function */
|
|
);
|
|
|
|
/* ------------------------------- */
|
|
|
|
/* Set the ink limit information for any reverse interpolation. */
|
|
/* Calling this will clear the reverse interpolaton cache. */
|
|
void (*rev_set_limit)(
|
|
struct _rspl *s, /* this */
|
|
double (*limitf)(void *lcntx, double *in), /* Optional input space limit function. */
|
|
/* Function should evaluate in[0..di-1], and return a number */
|
|
/* that is not to exceed limitv. NULL if not used. */
|
|
void *lcntx, /* Context passed to limit() */
|
|
double limitv /* Value that limit() is not to exceed */
|
|
);
|
|
|
|
/* Get the ink limit information for any reverse interpolation. */
|
|
void (*rev_get_limit)(
|
|
struct _rspl *s, /* this */
|
|
double (**limitf)(void *lcntx, double *in),
|
|
/* Return pointer to function of NULL if not set */
|
|
void **lcntx, /* return context pointer */
|
|
double *limitv /* Return limit value */
|
|
);
|
|
|
|
/* Set the RSPL_NEARCLIP LCh weightings. */
|
|
/* Will only work with L*a*b* like output spaces. */
|
|
/* Calling this will clear the reverse interpolaton cache. */
|
|
void (*rev_set_lchw)(
|
|
struct _rspl *s, /* this */
|
|
double lchw[MXRO] /* Weighting */
|
|
);
|
|
|
|
/* Possible reverse hint flags */
|
|
#define RSPL_WILLCLIP 0x0001 /* Hint that clipping will be needed */
|
|
#define RSPL_EXACTAUX 0x0002 /* Hint that auxiliary target will be matched exactly */
|
|
#define RSPL_MAXAUX 0x0004 /* If not possible to match exactly, return the */
|
|
/* closest value larger than the target, rather than */
|
|
/* absolute closest. */
|
|
#define RSPL_AUXLOCUS 0x0008 /* Auxiliary target is proportion of locus, not */
|
|
/* absolute. Implies EXACTAUX hint. */
|
|
#define RSPL_NEARCLIP 0x0010 /* If clipping occurs, return the nearest solution, */
|
|
/* rather than the one in the clip direction. */
|
|
#define RSPL_NONNSETUP 0x0020 /* Sets RSPL_FASTREVSETUP flag, which avoids NN grid */
|
|
/* setup if this is the first call using RSPL_NEARCLIP. */
|
|
/* Return value masks */
|
|
#define RSPL_DIDCLIP 0x8000 /* If this bit is set, at least one soln. and clipping occured */
|
|
#define RSPL_NOSOLNS 0x7fff /* And return value with this mask to get number of solutions */
|
|
|
|
/* Do reverse interpolation given target output values and (optional) auxiliary target */
|
|
/* input values. Return number of results and clip flag. If return value == mxsoln, then */
|
|
/* there might be more results. RESTRICTED SIZE */
|
|
int (*rev_interp)(
|
|
struct _rspl *s, /* this */
|
|
int flags, /* Hint flag */
|
|
int mxsoln, /* Maximum number of solutions allowed for */
|
|
int *auxm, /* Array of di mask flags, !=0 for valid auxliaries (NULL if no aux) */
|
|
double cdir[MXRO], /* Clip vector direction and length - NULL if not used */
|
|
co *p); /* Given target output space value in cpp[0].v[] + */
|
|
/* target input space auxiliaries in cpp[0].p[], return */
|
|
/* input space solutions in cpp[0..retval-1].p[], and */
|
|
/* (possibly) clipped target values in cpp[0].v[] */
|
|
|
|
/* Do reverse search for the locus of the auxiliary input values given a target output. */
|
|
/* Return 1 on finding a valid solution, and 0 if no solutions are found. RESTRICTED SIZE */
|
|
int (*rev_locus)(
|
|
struct _rspl *s,/* this */
|
|
int *auxm, /* Array of di mask flags, !=0 for valid auxliaries (NULL if no aux) */
|
|
co *cpp, /* Input target value in cpp[0].v[] */
|
|
double min[MXRI],/* Return minimum auxiliary values */
|
|
double max[MXRI]); /* Return maximum auxiliary values */
|
|
|
|
/* Do reverse search for the auxiliary min/max ranges of the solution locus for the */
|
|
/* given target output values. RESTRICTED SIZE */
|
|
/* Return number of locus segments found, up to mxsoln. 0 will be returned if no solutions */
|
|
/* are found. */
|
|
int (*rev_locus_segs)(
|
|
struct _rspl *s,/* this */
|
|
int *auxm, /* Array of di mask flags, !=0 for valid auxliaries (NULL if no aux) */
|
|
co *cpp, /* Input value in cpp[0].v[] */
|
|
int mxsoln, /* Maximum number of solutions allowed for */
|
|
double min[][MXRI], /* Array of min[MXRI] to hold return segment minimum values. */
|
|
double max[][MXRI] /* Array of max[MXRI] to hold return segment maximum values. */
|
|
);
|
|
|
|
|
|
/* ------------------------------- */
|
|
|
|
/* Return the min and max of the input values valid in the grid */
|
|
void (*get_in_range)(
|
|
struct _rspl *s, /* this */
|
|
double *min, double *max); /* Return min/max values */
|
|
|
|
/* return the min and max of the output values contained in the grid */
|
|
void (*get_out_range)(
|
|
struct _rspl *s, /* this */
|
|
double *min, double *max); /* Return min/max values */
|
|
|
|
/* return the grid index of the grid values at the min & max output values */
|
|
void (*get_out_range_points)(struct _rspl *s, int *minp, int *maxp);
|
|
|
|
/* return the overall scale of the output values contained in the grid */
|
|
double (*get_out_scale)(struct _rspl *s);
|
|
|
|
/* return the next touched flag count value. */
|
|
/* Whenever this rolls over, all the flags in the grid array will be reset */
|
|
unsigned int (*get_next_touch)(
|
|
struct _rspl *s); /* this */
|
|
|
|
# define wvals ad##jw
|
|
|
|
/* Return a pointer to the resolution array */
|
|
int *(*get_res)(struct _rspl *s);
|
|
|
|
/* Return non-zero if this rspl can be */
|
|
/* used with Restricted Size functions. */
|
|
int (*within_restrictedsize)(
|
|
struct _rspl *s); /* this */
|
|
|
|
}; typedef struct _rspl rspl;
|
|
|
|
/* Create a new, empty rspl object */
|
|
rspl *new_rspl(int flags, int di, int fdi); /* Input and output dimensiality */
|
|
|
|
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
|
|
|
/* Utility functions */
|
|
|
|
/* The multi-dimensional access sequence is a distributed */
|
|
/* Gray code sequence, with direction reversal */
|
|
/* on every alternate power of 2 scale. */
|
|
/* It is intended to aid cache access locality in multi-dimensional */
|
|
/* regular sampling. It approximates the Hilbert curve sequence. */
|
|
|
|
/* Structure to hold sequencer info */
|
|
struct _rpsh {
|
|
int di; /* Dimensionality */
|
|
unsigned res[MXDI]; /* Resolution per coordinate */
|
|
unsigned bits[MXDI]; /* Bits per coordinate */
|
|
unsigned tbits; /* Total bits */
|
|
unsigned ix; /* Current binary index */
|
|
unsigned tmask; /* Total 2^n count mask */
|
|
unsigned count; /* Usable count */
|
|
}; typedef struct _rpsh rpsh;
|
|
|
|
/* Initialise, returns total usable count */
|
|
unsigned
|
|
rpsh_init(rpsh *p, int di, unsigned res[], int co[]);
|
|
|
|
/* Reset the counter */
|
|
void rpsh_reset(rpsh *p);
|
|
|
|
/* Increment pseudo-hilbert coordinates */
|
|
/* Return non-zero if count rolls over to 0 */
|
|
int rpsh_inc(rpsh *p, int co[]);
|
|
|
|
#endif /* RSPL_H */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|