549 lines
22 KiB
C
549 lines
22 KiB
C
#ifndef RSPL_REV_H
|
|
#define RSPL_REV_H
|
|
|
|
/*
|
|
* Argyll Color Management System
|
|
* Multi-dimensional regularized spline data structure
|
|
*
|
|
* Reverse interpolation support code.
|
|
*
|
|
* Author: Graeme W. Gill
|
|
* Date: 30/1/00
|
|
*
|
|
* Copyright 1999 - 2008 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.
|
|
*
|
|
* Latest simplex/linear equation version.
|
|
*/
|
|
|
|
#undef STATS /* Collect and print reverse cach stats */
|
|
|
|
/* Data structures used by reverse lookup code. */
|
|
/* Note that the reverse lookup code only supports a more limited */
|
|
/* dimension range than the general rspl code. */
|
|
|
|
/*
|
|
* Note on simplex parameter space.
|
|
*
|
|
* Simplex interpolation is normaly done in Baricentric space, where there
|
|
* is one more baricentric coordinate than dimensions, and the sum of all
|
|
* the baricentric coordinates must be 1.
|
|
*
|
|
* To simplify things, we work in a "Simplex parameter" space, in which
|
|
* there are only dimension parameters, and each directly corresponds
|
|
* with a cartesian coordinate, but the parameter order corresponds with
|
|
* the baricentric order.
|
|
*
|
|
* For example, given cartesian sub-coordinates D0, D1, D2
|
|
* into a (3D) forward interpolation cube, these should be sorted
|
|
* from smallest to largest, thereby choosing a particular
|
|
* simplex within a cube, and allowing a correspondence to
|
|
* the parameter coordinates, ie:
|
|
*
|
|
* D2 D0 D1 Smallest -> Largest cartesian sort
|
|
* P0 P1 P2 Corresponding Parameter coordinates
|
|
*
|
|
* B0 = P0 Conversion to Baricentric weighting/coordinates
|
|
* B1 = P1 - P0
|
|
* B2 = P2 - P1
|
|
* B3 = 1 - P2
|
|
*
|
|
* The 4 (tetrahedron) vertex values directly correspond to Baricentric
|
|
* weighting/coordinates, giving the usual interpolation equation of:
|
|
*
|
|
* VV0 * B0
|
|
* + VV1 * B1
|
|
* + VV2 * B2
|
|
* + VV3 * B3
|
|
*
|
|
* Reversing the Parameter -> Baricentric equations gives the
|
|
* following interpolation equation using Parameter coordinates:
|
|
*
|
|
* (VV0 - VV1) * P0
|
|
* + (VV1 - VV2) * P1
|
|
* + (VV2 - VV3) * P2
|
|
* + VV3
|
|
*
|
|
* Note that within the simplex, 0 <= P0 && P0 <= P1 && P1 <= P2 && P2 <= 1
|
|
*
|
|
* It is this which is used in rev.c for solving the reverse
|
|
* interpolation problem.
|
|
*/
|
|
|
|
/* - - - - - - - - - - - - - - - - - - - - - */
|
|
/* Group size information for nn LCh weighted quick accept/reject testing */
|
|
typedef struct {
|
|
double bcent[MXRO]; /* Group center location in output space */
|
|
double brad; /* Output value bounding shere radius */
|
|
double bradsq; /* Output value bounding shere radius squared */
|
|
|
|
double maxDlc; /* Maximum members weighted delta LC (+extra dims) squared */
|
|
double maxDh; /* Maximum members delta h squared */
|
|
double maxDh_; /* Maximum members delta h (not squared) */
|
|
double sratio; /* Minimum members C ratio to Gc squared */
|
|
double bratio; /* Maximum members C ratio to Gc squared */
|
|
double Wsratio; /* Minimum members C ratio to Gc squared - pre-weighted */
|
|
double Wbratio; /* Maximum members C ratio to Gc squared - pre-weighted */
|
|
double Gc; /* Group center Chrominance squared */
|
|
double Gc_; /* Group center Chrominance (not squared) */
|
|
} nn_grp;
|
|
|
|
/* - - - - - - - - - - - - - - - - - - - - - */
|
|
/* A structure to hold per simplex coordinate and vertex mapping for ssxinfo. */
|
|
/* This is relative to the construction cube. A face sub-simplex */
|
|
/* that is common between cubes, will have a different psxinfo */
|
|
/* depending on which cube created it. */
|
|
typedef struct {
|
|
int face; /* Flag, nz if simplex lies on cube surface */
|
|
int icomb[MXDI]; /* icomb[] specifies the equation to convert simplex space */
|
|
/* coordinates back into cartesian space. */
|
|
/* Index by Absolute[di] -> Simplex Parameter[sdi], */
|
|
/* -1 == value 0, -2 == value 1 */
|
|
/* Note that many Abs can map to one Param to form a sum. */
|
|
int offs[MXDI+1]; /* Offsets to simplex vertices within cube == bit per dim */
|
|
int goffs[MXDI+1]; /* Offsets to simplex vertices within grid */
|
|
int foffs[MXDI+1]; /* Fwd grid floating offsets to simplex vertices from cube base */
|
|
int pmino[MXDI], pmaxo[MXDI]; /* Cube verticy offsets to setup simplex pmin[] and */
|
|
/* pmax[] bounding box pointers. */
|
|
} psxinfo;
|
|
|
|
/* Sub simplexes of a cube information structure */
|
|
typedef struct {
|
|
int sdi; /* Sub-simplex dimensionality */
|
|
int nospx; /* Number of sub-simplexs per cube */
|
|
psxinfo *spxi; /* Per sub-simplex info array, NULL if not initialised */
|
|
} ssxinfo;
|
|
|
|
/* - - - - - - - - - - - - - - - - - - - - - */
|
|
/* NOTE :- This should really be re-arranged to be per-sub-simplex caching, */
|
|
/* rather than fxcell caching. Rather than stash the simplex info in the fxcells, */
|
|
/* create a separate cache or some other way of sharing the common simplexes. */
|
|
/* The code that ignores common face simplexes in fxcells could then be removed (?). */
|
|
|
|
/* Simplex definition. Each top level fwd interpolation cell, */
|
|
/* is decomposed into sub-simplexes. Sub-simplexes are of equal or */
|
|
/* lower dimensionality (ie. faces, edges, vertices) to the cube. */
|
|
struct _simplex {
|
|
int refcount; /* reference count */
|
|
struct _rspl *s; /* Pointer to parent rspl */
|
|
int ix; /* Construction Fwd cell index */
|
|
int si; /* Diagnostic - simplex number within level */
|
|
int sdi; /* Sub-simplex dimensionality */
|
|
int efdi; /* Effective fdi. This will be = fdi for a non clip */
|
|
/* plane simplex, and fdi+1 for a clip plane simplex. */
|
|
/* The DOF (Degress of freedom) within this simplex = sdi - efdi */
|
|
|
|
psxinfo *psxi; /* Generic per simplex info (construction cube relative) */
|
|
int vix[MXRI+1]; /* fwd cell vertex indexes of this simplex [sdi+1] */
|
|
/* This is a universal identification of this simplex. */
|
|
struct _simplex *hlink; /* Link to other cells with this hash */
|
|
unsigned int touch; /* Last touch count. */
|
|
short flags; /* Various flags */
|
|
|
|
#define SPLX_CLIPSX 0x01 /* This is a clip plane simplex */
|
|
|
|
#define SPLX_FLAG_1 0x04 /* v, linmin/max initialised */
|
|
#define SPLX_FLAG_2 0x08 /* lu/svd initialised */
|
|
#define SPLX_FLAG_2F 0x10 /* lu/svd init. failed */
|
|
#define SPLX_FLAG_4 0x20 /* locus found */
|
|
#define SPLX_FLAG_5 0x40 /* auxiliary lu/svd initialised */
|
|
#define SPLX_FLAG_5F 0x80 /* auxiliary lu/svd init. failed */
|
|
|
|
#define SPLX_FLAGS (SPLX_FLAG_1 | SPLX_FLAG_2 | SPLX_FLAG_2F \
|
|
| SPLX_FLAG_4 | SPLX_FLAG_5 | SPLX_FLAG_5F)
|
|
|
|
double v[MXRI+1][MXRO+1]; /* Simplex Vertex values */
|
|
/* v[0..sdi][0..fdi-1] are the output interpolation values */
|
|
/* v[0..sdi][fdi] are the ink limit interpolation values */
|
|
|
|
/* Baricentric vv[x][y] = (v[y][x] - v[y+1][x]) */
|
|
/* and vv[x][sdi] = v[sdi][x] */
|
|
|
|
/* Note that #num indicates appropriate flag number */
|
|
/* and *num indicates a validator */
|
|
|
|
double p0[MXRI]; /* Simplex base position = construction cube p[0] */
|
|
double pmin[MXRI]; /* Simplex vertex input space min and */
|
|
double pmax[MXRI]; /* max values [di] */
|
|
|
|
double min[MXRO+1], max[MXRO+1]; /* Simplex vertex output space [fdi+1] and */
|
|
/* ink limit bounding values at minmax[fdi] */
|
|
|
|
/* If sdi == efdi, this holds the LU decomposition, */
|
|
/* else this holds the SVD and solution locus info */
|
|
|
|
char *aloc2; /* Memory allocation for #2 & #4 */
|
|
|
|
/* double **d_u; LU decomp of vv, U[0..efdi-1][0..sdi-1] #2 */
|
|
/* int *d_w; LU decomp of vv, W[0..sdi-1] #2 */
|
|
|
|
double **d_u; /* SVD decomp of vv, U[0..efdi-1][0..sdi-1] #2 */
|
|
double *d_w; /* SVD decomp of vv, W[0..sdi-1] #2 */
|
|
double **d_v; /* SVD decomp of vv, V[0..sdi-1][0..sdi-1] #2 */
|
|
|
|
/* Degrees of freedom = dof = sdi - efdi */
|
|
double **lo_l; /* Locus coefficients, [0..sdi-1][0..dof-1] #2 */
|
|
|
|
double *lo_xb; /* RHS used to compute lo_bd [0..efdi-1] *4 */
|
|
double *lo_bd; /* Locus base solution, [0..sdi-1] #4 */
|
|
|
|
unsigned auxbm; /* aux bitmap mask for ax_lu and ax_svd *5 */
|
|
int aaux; /* naux count for allocation *5 */
|
|
int naux; /* naux for calculation (may be < aaux ?) *5 */
|
|
|
|
/* if (sdi-efdi = dof) == naux this holds LU of lo_l */
|
|
/* else this holds the SVD of lo_l */
|
|
|
|
char *aloc5; /* Memory allocation for #5 */
|
|
|
|
/* double **ax_u; LU decomp of lo_l #5 */
|
|
/* int *ax_w; Pivot record for ax_lu decomp #5 */
|
|
|
|
double **ax_u; /* SVD decomp of lo_l, U[0..naux-1][0..dof-1] #5 */
|
|
double *ax_w; /* SVD decomp of lo_l, W[0..dof-1] #5 */
|
|
double **ax_v; /* SVD decomp of lo_l, V[0..dof-1][0..dof-1] #5 */
|
|
|
|
}; typedef struct _simplex simplex;
|
|
|
|
/* A candidate search (fwd) fxcell (cell cache entry structure) */
|
|
struct _fxcell {
|
|
struct _rspl *s; /* Pointer to parent rspl */
|
|
|
|
/* Cache information */
|
|
int ix; /* Corresponding fwd cell index */
|
|
struct _fxcell *hlink; /* Link to other cells with this hash */
|
|
struct _fxcell *mrudown;/* Links to next most recently used fxcell */
|
|
struct _fxcell *mruup;
|
|
int refcount; /* Reference count */
|
|
int flags; /* Non-zero if the fxcell has been initialised */
|
|
#define CELL_FLAG_1 0x01 /* Basic initialisation, including nn_grp */
|
|
#define CELL_FLAG_2 0x02 /* Simplex information initialised */
|
|
|
|
/* Use information */
|
|
double sort; /* Sort key */
|
|
double limmin, limmax; /* limit() min/max for this fxcell */
|
|
|
|
/* Quick nn distance information */
|
|
nn_grp g;
|
|
|
|
// double bcent[MXRO]; /* Output value bounding shere center */
|
|
// double brad; /* Output value bounding shere radius */
|
|
// double bradsq; /* Output value bounding shere radius squared */
|
|
// double wbrad; /* Output value weighted bounding shere radius */
|
|
|
|
double p[POW2MXRI][MXRI]; /* Vertex input positions for this cube. */
|
|
/* Copied to x->pmin/pmax[] & ink limit */
|
|
|
|
double v[POW2MXRI][MXRO+1]; /* Vertex data for this cube. Copied to x->v[] */
|
|
/* v[][fdi] is the ink limit values, if relevant */
|
|
|
|
simplex **sx[MXRI+1]; /* Lists of simplexes that make up this fxcell. */
|
|
/* Each list indexed by the non-limited simplex */
|
|
/* dimensionality (similar to sspxi[]) */
|
|
/* Each list will be NULL if it hasn't been created yet */
|
|
int sxno[MXRI+1]; /* Corresponding count of each list */
|
|
|
|
}; typedef struct _fxcell fxcell;
|
|
|
|
/* surface bxcell sl status */
|
|
typedef enum {
|
|
bx_uninit = 0, /* sl is not initialised */
|
|
bx_filled = 1, /* sl has been filled with initial fwd cell vertexes */
|
|
bx_rethinnd = 2, /* sl vertexes need to be re-thinned */
|
|
bx_thinned = 3, /* sl vertexes have been thinned */
|
|
bx_conv = 4 /* sl vertexes have been converted to fwd cell indexes */
|
|
} bxstat;
|
|
|
|
/* Structure to hold bwd cell information for surface list, and also */
|
|
/* for seed fill bwd cell propogation. (Cells on surface will have two */
|
|
/* of these) */
|
|
struct _bxcell{
|
|
int ix; /* nnrev[] index of this bwd cell */
|
|
int gc[MXRO]; /* coordinate of this bwd cell */
|
|
nn_grp g; /* Group nn calculation info */
|
|
struct _bxcell *ss; /* bwd surface cell to start search from */
|
|
double sdist; /* Est. wtd distance from this cell to ss */
|
|
int tix; /* target rev[] index being filled (visited check) */
|
|
|
|
bxstat status; /* State of sl list */
|
|
int *sl; /* fwd vertex seed list for surface bxcells */
|
|
/* or cell list after conversion to cells */
|
|
int *dl; /* deleted fwd vertex list for this bxcell */
|
|
|
|
int *scell; /* If non-NULL, this is a (non-surface) */
|
|
/* seeding super bxcell, and scell contains */
|
|
/* the list of bxcells covered */
|
|
|
|
struct _bxcell *slist; /* Linked list of all surface bxcells */
|
|
struct _bxcell *hlink; /* Linked list of surface bxcells with same ix hash */
|
|
struct _bxcell *xlist; /* Linked list of surface exploration search region */
|
|
double emin; /* estimated minimum wtd distance of this cell in current search */
|
|
struct _bxcell *tlist; /* Linked list of solution surface cells for current search. */
|
|
|
|
struct _bxcell *flist; /* Linked list for nnrev[] fill seeds */
|
|
|
|
double cc; /* Distance of group from gamut center */
|
|
double dw; /* Delta width from ocent of furthest point */
|
|
struct _bxcell *wlist; /* Linked list for shadow bxcells during thinning */
|
|
|
|
int debug; /* debug flag - for VRML tagging */
|
|
}; typedef struct _bxcell bxcell;
|
|
|
|
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
|
|
|
|
|
/* Enough space is needed to cache all the fxcells/simplexes */
|
|
/* for a full aux. locus, or the query will be processed in */
|
|
/* several "chunks" and will be slower. */
|
|
/* This sets the basic memory usage of the rev code. */
|
|
|
|
#define REV_ACC_GRES_MUL 2.0 /* 2.0 Reverse accelleration grid resolution */
|
|
/* multiplier over fwd grid resolution */
|
|
#define REV_ACC_GRES_LIMIT 43 /* Reverse accelln. grid resolution limit before env. mult. */
|
|
#define REV_MAX_MEM_RATIO 0.3 /* 0.3 Proportion of first 1G of Ram to use */
|
|
#define REV_MAX_MEM_RATIO2 0.4 /* 0.4 Proportion of rest of Ram to use */
|
|
/* rev as a fraction of the System RAM. */
|
|
#define HASH_FILL_RATIO 3 /* 3 Ratio of entries to hash size */
|
|
|
|
/* The structure where fxcells and simplexes are allocated and cached. */
|
|
|
|
/* Holds the fxcell and simplex match cache specific information */
|
|
typedef struct {
|
|
struct _rspl *s; /* Pointer to parent rspl */
|
|
int nacells; /* Number of allocated cells */
|
|
int nunlocked; /* Number of unlocked cells that could be freed */
|
|
int cell_hash_size; /* Current size of cell hash list */
|
|
fxcell **hashtop; /* Top of hash list [cell_hash_size] */
|
|
fxcell *mrutop, *mrubot; /* Top and bottom pointers of mru list */
|
|
/* that tracks allocated fxcells */
|
|
|
|
int spx_hash_size; /* Current size of shared face simplex hash list */
|
|
simplex **spxhashtop; /* Shared face simplex hash index list */
|
|
int nspx; /* Number of simplexes in hash list */
|
|
} revcache;
|
|
|
|
/* common search information */
|
|
/* Type of (internal) reverse search */
|
|
enum ops {
|
|
exact = 0, /* Search for all input values that exactly map to given output value */
|
|
clipv = 1, /* Search for input values that map to outermost solution along a vector */
|
|
clipn = 2, /* Search for input values that map to closest solution */
|
|
auxil = 3, /* Search for input values that map to given output, and closest to auxiliary target */
|
|
locus = 4 }; /* Return range of auxiliary values that contains solution */
|
|
|
|
/* + possible exact with clip */
|
|
|
|
/* Structure to hold clip line state information */
|
|
typedef struct {
|
|
struct _rspl *s; /* Pointer to parent rspl */
|
|
double st[MXRO]; /* start of line - reverse grid base value */
|
|
double de[MXRO]; /* direction of line */
|
|
int di[MXRO]; /* incerement in line direction */
|
|
int ci[MXRO]; /* current rev grid coordinate */
|
|
double t; /* Parameter 0.0 - 1.0, line finished if t > 1.0 */
|
|
} line;
|
|
|
|
|
|
/* Structure to hold aux value of an intersection of a */
|
|
/* solution locus with a sub-simplex. Used when asegs flag is set */
|
|
typedef struct {
|
|
double xval; /* Auxiliary value */
|
|
int nv; /* Number of vertices valid */
|
|
int vix[MXRI+1]; /* Verticy indexes of sub-simplex involved */
|
|
} axisec;
|
|
|
|
/* -------------------------------------------- */
|
|
/* Information needed/cached for reverse lookup */
|
|
struct _schbase {
|
|
struct _rspl *s; /* Pointer to parent rspl */
|
|
|
|
int flags; /* Hint flags */
|
|
enum ops op; /* Type of reverse search operation */
|
|
int ixc; /* Cube index of corner that holds maximum input values */
|
|
|
|
int snsdi, ensdi; /* Start and end extra sub-simplex dimensionality */
|
|
int (*setsort)(struct _schbase *b, fxcell *c); /* Function to triage & set cube sort index */
|
|
int (*check)(struct _schbase *b, fxcell *c); /* Function to recheck cube worth keeping */
|
|
int (*compute)(struct _schbase *b, simplex *x); /* Function to compute a simplex solution */
|
|
|
|
double v[MXRO+1]; /* Target output value, + ink limit */
|
|
double av[MXRI]; /* Target auxiliary values */
|
|
int auxm[MXRI]; /* aux mask flags */
|
|
unsigned auxbm; /* aux bitmap mask */
|
|
int naux; /* Number of auxiliary target input values */
|
|
int auxi[MXRI]; /* aux list of auxiliary target input values */
|
|
double idist; /* best input distance auxiliary target found (smaller is better) */
|
|
int iabove; /* Number of auxiliaries at or above zero */
|
|
|
|
int canvecclip; /* Non-zero if vector clip direction usable */
|
|
double cdir[MXRO]; /* Clip vector direction and length wrt. v[] */
|
|
double ncdir[MXRO]; /* Normalised clip vector */
|
|
double **cla; /* Clip vector LHS implicit equation matrix [fdi][fdi+1] (inc. ink tgt.) */
|
|
double clb[MXRO+1]; /* Clip vector RHS implicit equation vector [fdi+1] (inc. ink tgt.) */
|
|
double cdist; /* Best clip locus distance found (aim is min +ve) :- weighted for nn */
|
|
int iclip; /* NZ if result is above (disabled) ink limit */
|
|
|
|
int mxsoln; /* Maximum number of solutions that we want */
|
|
int nsoln; /* Current number of solutions found */
|
|
co *cpp; /* Store solutions here */
|
|
|
|
int lxi; /* Locus search axiliary index */
|
|
double min, max; /* current extreme locus values for locus search */
|
|
int asegs; /* flag - find all search segments */
|
|
int axisln; /* Number of elements used in axisl[] */
|
|
int axislz; /* Space allocated to axisl[] */
|
|
axisec *axisl; /* Auxiliary intersections */
|
|
|
|
int lclistz; /* Allocated space to fxcell sort list */
|
|
fxcell **lclist; /* Sorted list of pointers to candidate fxcells */
|
|
|
|
int pauxcell; /* Indexe of previous call solution fxcell, -1 if not relevant */
|
|
int plmaxcell; /* Indexe of previous call solution fxcell, -1 if not relevant */
|
|
int plmincell; /* Indexe of previous call solution fxcell, -1 if not relevant */
|
|
|
|
int lsxfilt; /* Allocated space of simplex filter list */
|
|
char *sxfilt; /* Flag for simplexes that should be in an fxcell */
|
|
|
|
int rix; /* Diagnostic - rev[] or nnrev[] index for this point */
|
|
|
|
}; typedef struct _schbase schbase;
|
|
|
|
/* ----------------------------------------- */
|
|
|
|
#ifdef STATS
|
|
struct _stats {
|
|
int searchcalls;/* Number of top level searches */
|
|
int csearched; /* Cells searched */
|
|
int ssearched; /* Simplexes searched */
|
|
int sinited; /* Simplexes initialised to base level */
|
|
int sinited2a; /* Simplexes initialised to 2nd level with LU */
|
|
int sinited2b; /* Simplexes initialised to 2nd level with SVD */
|
|
int sinited4i; /* Simplexes invalidated at 4th level */
|
|
int sinited4; /* Simplexes initialised to 4th level */
|
|
int sinited5i; /* Simplexes invalidated at 5th level */
|
|
int sinited5a; /* Simplexes initialised to 5th level with LU */
|
|
int sinited5b; /* Simplexes initialised to 5th level with SVD */
|
|
int chits; /* Cells hit in cache */
|
|
int cmiss; /* Cells misses in cache */
|
|
}; typedef struct _stats stats;
|
|
#endif /* STATS */
|
|
|
|
/* ----------------------------------------- */
|
|
/* Reverse info stored in main rspl function */
|
|
struct _rev_struct {
|
|
|
|
/* First section, basic information that doesn't change */
|
|
/* Has been initialised if inited != 0 */
|
|
|
|
int inited; /* Non-zero if first section has been initialised */
|
|
/* All other sections depend on this. */
|
|
int fastsetup; /* Flag - NZ if fast setup at cost of slow throughput */
|
|
|
|
int probxyz; /* Flag - NZ - guess if XYZ for VRML diagnostics use */
|
|
|
|
int lchweighted; /* Non-zero if nearest search is LCh weighted */
|
|
double lchw[MXRO]; /* LCh nearest weighting */
|
|
double lchw_sq[MXRO]; /* LCh nearest weighting squared */
|
|
double lchw_chsq; /* lchw_sq[1] - lchw_sq[2] */
|
|
|
|
struct _rev_struct *next; /* Linked list of global instances sharing memory */
|
|
size_t max_sz; /* Maximum size permitted */
|
|
size_t sz; /* Total memory current allocated by rev */
|
|
|
|
#ifdef NEVER
|
|
int thissz, lastsz; /* Debug reporting */
|
|
#endif
|
|
|
|
/* Reverse grid lookup information */
|
|
int res; /* Reverse grid resolution == ncells on a side */
|
|
int no; /* Total number of points in reverse grid = rev.ares ^ fdi */
|
|
int coi[MXRO]; /* Coordinate increments for each dimension */
|
|
int hoi[1 << MXRO]; /* Coordinate increments for progress through cube */
|
|
datao gl,gh,gw; /* Reverse grid low, high, grid bwd cell width */
|
|
|
|
/* Second section, accelleration information that changes with ink limit. */
|
|
int rev_valid; /* nz if this information in rev[] and nnrev[] is valid */
|
|
int **rev; /* Exact reverse lookup starting list. */
|
|
int **nnrev; /* Nearest reverse lookup starting list. */
|
|
/* These lists are of fwd grid base indexes. */
|
|
/* [0] is allocation length */
|
|
/* [1] is the next free entry index (length + 3, not counting -1) */
|
|
/* [2] is index into share lists, -1 if not shared. */
|
|
/* Then follows cube indexes */
|
|
/* Last entry is marked with -1 */
|
|
|
|
double ocent[MXRO]; /* rev cell gamut "center" point for thinning and shadow testing. */
|
|
|
|
int surflin_en; /* Flag set when suflin is enabled */
|
|
struct _rspl *surflin; /* gamut surface linearization transform used by logcomp() */
|
|
double linoff[MXRO]; /* ocent offset after surflin mapping */
|
|
|
|
bxcell *surflist; /* Linked list of rev[] bwd cells that contain gamut surface fwd cells. */
|
|
/* Used to speed up fill_nncell() when rev.fastsetup is set, else NULL */
|
|
int surf_hash_size; /* Current size of bxcell hash list */
|
|
bxcell **surfhash; /* bxcell hash index list */
|
|
|
|
int **sharelist; /* Array of pointers to shared (fwd grid list sharer) records. */
|
|
/* Each record is same format as rev[]/nnrev[], except */
|
|
/* [2] is used to detect scanning the same list. */
|
|
int sharellen; /* Size of sharelist */
|
|
int sharelaloc; /* Allocation size of sharelist */
|
|
|
|
/* Third section */
|
|
revcache *cache; /* Where fxcells and simplexes are allocated and cached */
|
|
/* Sub-dimension simplex information */
|
|
ssxinfo sspxi[MXRI+1];/* One per sub dimenstionality at offset sdi */
|
|
|
|
/* Fourth section */
|
|
/* Has been initialise if sb != NULL */
|
|
schbase *sb; /* Structure holding calculated per-search call information */
|
|
|
|
unsigned int stouch; /* Simplex touch count to avoid searching shared simplexs twice */
|
|
#ifdef STATS
|
|
stats st[5]; /* Set of stats info indexed by enum ops */
|
|
#endif /* STATS */
|
|
|
|
int primsecwarn; /* Not primary or secondary warning has been issued */
|
|
|
|
#ifdef CHECK_NNLU
|
|
int cknn_no; /* Number checked */
|
|
double cknn_we; /* Worst DE */
|
|
int cknn_noerrs; /* Number not as good as closet vertex */
|
|
int cknn_nobsb; /* Number not as good as second closest vertex */
|
|
int cknn_nonis; /* Number not in surface */
|
|
#endif /* CHECK_NNLU */
|
|
|
|
}; typedef struct _rev_struct rev_struct;
|
|
|
|
|
|
/* ------------------------------------ */
|
|
/* Utility functions used by other parts of rspl implementation */
|
|
|
|
/* Initialise a static sub-simplex verticy information table */
|
|
void rspl_init_ssimplex_info(struct _rspl *s, /* RSPL object */
|
|
ssxinfo *xip, /* Pointer to sub-simplex info structure to init. */
|
|
int sdi); /* Sub-simplex dimensionality (range 0 - di) */
|
|
|
|
/* Free the given sub-simplex verticy information */
|
|
void rspl_free_ssimplex_info(struct _rspl *s,
|
|
ssxinfo *xip); /* Pointer to sub-simplex info structure */
|
|
|
|
#endif /* RSPL_REV_H */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|