diff options
Diffstat (limited to 'gamut/gamut.h')
-rw-r--r-- | gamut/gamut.h | 406 |
1 files changed, 406 insertions, 0 deletions
diff --git a/gamut/gamut.h b/gamut/gamut.h new file mode 100644 index 0000000..8f9f00e --- /dev/null +++ b/gamut/gamut.h @@ -0,0 +1,406 @@ +#ifndef GAMUT_H +#define GAMUT_H + +/* + * gamut + * + * Gamut support routines. + * + * Author: Graeme W. Gill + * Date: 9/3/2000 + * Version: 1.00 + * + * Copyright 2000-2006 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. + */ + + + +/* + Note that the input and output are expected to be Lab style + color coordinates, and that L->Z, a->X, b->Y. + +*/ + +#include "../h/llist.h" + +#define BSPDEPTH 100 /* Maximum BSP tree depth */ + +#define PFARNDIST 0.1 /* Positive (inwards) far "near" distance */ +#define NFARNDIST -200.0 /* Negative (outwards) far "near" distance */ +#define MFARNDIST PFARNDIST /* Minimum (absolute) of the two */ + +#define MAXGAMN 10 /* Maximum gamut point neighbors returned */ +#define NSLOTS 6 /* Number of maximum direction slots */ + +/* ------------------------------------ */ +#define NODE_STRUCT \ + int tag; /* Type of node, 1 = vertex, 2 = quad */ \ + double w, h; /* longitude width, latitude height of this box */ \ + double hc, vc; /* longitude center, latitude center of this box */ \ + +struct _gnode { + NODE_STRUCT +}; typedef struct _gnode gnode; + +/* ------------------------------------ */ +/* Vertex node */ +struct _gvert { + NODE_STRUCT + int rc; /* reference count */ + struct _gvert *ul; /* Unused list */ + + int n; /* Index number of vertex */ + int sn; /* Set Index number of vertex */ + int tn; /* Triangulated Index number of vertex */ + int f; /* Flag value */ +#define GVERT_NONE 0x0000 /* No flags */ +#define GVERT_SET 0x0001 /* Value has been set */ +#define GVERT_TRI 0x0002 /* Vertex has been added to triangulation (Exclsv with _INSIDE) */ +#define GVERT_INSIDE 0x0004 /* Vertex is inside the log hull (Exclusive with _TRI) */ +#define GVERT_ISOS 0x0008 /* Intersecting gamuts "outside other gamut" flag */ +#define GVERT_ESTP 0x0010 /* Non-fake establishment point */ +#define GVERT_FAKE 0x0020 /* Fake establishment point */ + int k0; /* k0 direction reference count */ + + double p[3]; /* Point in xyz rectangular coordinates, absolute */ + double r[3]; /* Radial coordinates */ + double lr0; /* log scaled r[0] */ + double sp[3]; /* Point mapped to surface of unit sphere, relative to center */ + double ch[3]; /* Point mapped for convex hull testing, relative to center */ + + int as; /* Assert checking flag, compdstgamut flag */ +}; typedef struct _gvert gvert; + +/* ------------------------------------ */ +/* Quadtree node */ +struct _gquad { + NODE_STRUCT + gnode *qt[4][NSLOTS]; + + /* Child nodes, NULL if none, */ + /* Nodes are ordered: */ + /* --------- */ + /* | 2 | 3 | */ + /* --------- */ + /* | 0 | 1 | */ + /* --------- */ + /* and each node contains NSLOTS slots. */ + /* If the quadtree recurses, the first slot containts another */ + /* quadtree, otherwise the slots contain pointers to the */ + /* four best verticies in the various directions. */ + +}; typedef struct _gquad gquad; + +/* ------------------------------------ */ + +/* Common base class of BSP nodes */ +#define BSP_STRUCT \ + int tag; /* Type of node, 1 = bsp node, 2 = triangle, 3 = list */ \ + double rs0, rs1; /* min/max radius squared from origin of all contained triangles */ + +struct _gbsp { + BSP_STRUCT +}; typedef struct _gbsp gbsp; + +/* ------------------------------------ */ + +/* A BSP tree decision node */ +struct _gbspn { + BSP_STRUCT + int n; /* Serial number */ + double pe[4]; /* Plane equation values (center relative) */ + struct _gbsp *po; /* Positive branch */ + struct _gbsp *ne; /* Negative branch */ +}; typedef struct _gbspn gbspn; + +/* ------------------------------------ */ + +/* A BSP tree triangle list node */ +struct _gbspl { + BSP_STRUCT + int n; /* Serial number */ + int nt; /* Number of triangles in the list */ + struct _gtri *t[]; /* List of triangles - allocated with struct */ +}; typedef struct _gbspl gbspl; + +/* ------------------------------------ */ + +/* A triangle in the surface mesh */ +struct _gtri { + BSP_STRUCT + int n; /* Serial number */ + struct _gvert *v[3]; /* Verticies in cw order */ + struct _gedge *e[3]; /* Edges v[n] - v[n+1] */ + int ei[3]; /* Index within edge structure of this triangle [0..1] */ + + double pe[4]; /* Vertex plane equation (absolute) */ + /* (The first three elements is the unit normal vector to the plane, */ + /* which points inwards) */ + double che[4]; /* convex hull testing triangle plane equation (relative) */ + double spe[4]; /* sphere mapped triangle plane equation (relative) */ + double ee[3][4]; /* sphere sp[] Edge triangle plane equations for opposite edge (relative) */ + + int sort; /* lookup: Plane sorting result for each try */ + int bsort; /* lookup: Current best tries sort */ + + unsigned int touch; /* nn: Per value touch count */ + double mix[2][3]; /* nn: Bounding box min and max */ + + double area; /* Area - computed by nssverts() */ + int ssverts; /* Number of stratified sampling verts needed - computed by nssverts() */ + + LINKSTRUCT(struct _gtri); /* Linked list structure */ +}; typedef struct _gtri gtri; + +/* ------------------------------------ */ + +/* An edge shared by two triangle in the mesh */ +struct _gedge { + int n; /* Serial number */ + struct _gvert *v[2]; /* Verticies of edge */ + struct _gtri *t[2]; /* Triangles edge is part of */ + int ti[2]; /* record of indexes of edge within the triangles [0..2]*/ + double re[4]; /* Radial edge plane equation (relative) */ + + int as; /* Assert checking flag */ + + LINKSTRUCT(struct _gedge); /* Linked list structure */ +}; typedef struct _gedge gedge; + +/* ------------------------------------ */ + +/* The gamut nearest neighbor search structure */ +struct _gnn { + struct _gamut *s; /* Base gamut object */ + int n; /* Number of points stored */ + gtri **sax[3 * 2]; /* Sorted axis pointers, one for each direction */ + unsigned int tbase; /* Touch base value for this pass */ + unsigned int ttarget; /* Touch target value for this pass */ +}; typedef struct _gnn gnn; + +/* ------------------------------------ */ + +/* A vector intersction point */ +struct _gispnt { + double ip[3]; /* Intersecion Point */ + double pv; /* Parameter value at intersection */ + int dir; /* Direction: 1 = into gamut, 0 = out or gamut */ + int edge; /* Edge: 2 = no isect, 1 = on edge, 0 = not on edge */ + gtri *tri; /* Pointer to intersection triangle */ +}; typedef struct _gispnt gispnt; + +/* Gamut object */ +struct _gamut { + +/* Private: */ + double sres; /* Surface triangle resolution */ + int isJab; /* nz if Jab CIECAM02 type space rather than L*a*b* */ + int isRast; /* nz if raster file point cloud, else colorspace */ + /* (This affects convex hull filtering) */ + double cent[3]; /* Gamut center for radial conversion. Default 50.0,0,0 */ + /* Must be same to compare radial values. */ + + int nv; /* Number of verticies used out of allocation */ + gvert *ul; /* Linked list of unused verticies */ + int na; /* Number of verticies allocated */ + int nsv; /* Number of verticies that have been set */ + int ntv; /* Number of verticies used in triangulation */ + gvert **verts; /* Pointers to allocated verticies */ + int read_inited; /* Flag set if gamut was initialised from a read */ + int lu_inited; /* Flag set if radial surface lookup is inited */ + int ne_inited; /* Flag set if nearest lookup is inited */ + int cu_inited; /* Flag set if cusp values inited and trustworthy */ + int nofilter; /* Flag, skip segmented maxima filtering */ + int no2pass; /* Flag, do only one pass of convex hull */ + int doingfake; /* Internal transient state */ + int pass; /* Pass number for multi-pass */ + double logpow; /* Convex hull compression power (default 0.25) */ + + gquad *tl, *tr; /* Top left and quadtree elements */ + + gtri *tris; /* Surface triangles linked list */ + gedge *edges; /* Edges between the triangles linked list */ + + gbsp *lutree; /* Lookup function BSP tree root */ + gnn *nns; /* nearest neighbor acceleration structure */ + + int cswbset; /* Flag to indicate that the cs white & black points are set */ + double cs_wp[3]; /* Color spaces white point */ + double cs_bp[3]; /* Color spaces black point */ + double cs_kp[3]; /* Color spaces K only black point */ + int gawbset; /* Flag to indicate that the gamut white & black points are set */ + double ga_wp[3]; /* Gamut white point */ + double ga_bp[3]; /* Gamut black point */ + double ga_kp[3]; /* Gamut K only black point */ + + int dcuspixs; /* Cusp we're up to */ + double dcusps[6][3];/* Entered cusp values to setcusps(, 3, ) */ + double cusps[6][3]; /* Cusp values for red, yellow, green, cyan, blue & magenta */ + /* if cu_inited nz */ + + double mx[3], mn[3]; /* Range covered by input points */ + + double xvra; /* Extra vertex ratio - set/used by nssverts() */ + int ssnverts; /* total ss verticies - set/used by nssverts() */ + int ssvertn; /* Number of verts created for current triangle */ + sobol *ss; /* Sibol ss generator currently being used */ + + gtri *nexttri; /* Context for getnexttri() */ + +/* Public: */ + /* Methods */ + void (*del)(struct _gamut *s); /* Free ourselves */ + + gvert *(*expand)(struct _gamut *s, double in[3]); /* Expand the gamut surface */ + + int (*getisjab)(struct _gamut *s); /* Return the isJab flag value */ + + int (*getisrast)(struct _gamut *s); /* Return the isRast flag value */ + + void (*setnofilt)(struct _gamut *s); /* Disable segmented maxima filtering */ + + void (*getcent)(struct _gamut *s, double *cent); /* Return the gamut center location */ + + void (*getrange)(struct _gamut *s, double *min, double *max); /* Return the gamut range */ + + double (*getsres)(struct _gamut *s); /* Return the surface resolution */ + + int (*compatible)(struct _gamut *s, struct _gamut *t); /* Return the nz if compatible gamuts */ + + int (*nrawverts)(struct _gamut *s); /* Return the number of raw verticies */ + + int (*getrawvert)(struct _gamut *s, double pos[3], int ix); + /* Return the raw verticies location */ + + int (*nraw0verts)(struct _gamut *s); /* Return the number of raw verticies in */ + /* the radial maxima direction*/ + + int (*getraw0vert)(struct _gamut *s, double pos[3], int ix); + /* Return the raw 0 direction verticies location */ + + int (*nverts)(struct _gamut *s); /* Return the number of surface verticies */ + + int (*getvert)(struct _gamut *s, double *rad, double pos[3], int ix); + /* Return the surface triangle verticies location and radius */ + /* start at 0, and returns value is next index or -1 if last */ + + int (*nssverts)(struct _gamut *s, double vpua); + /* Return the number of stratified sampling surface verticies, */ + /* for the given verticies per unit area parameter. */ + + int (*getssvert)(struct _gamut *s, double *rad, double pos[3], double norn[3], int ix); + /* Return the stratified sampling surface verticies */ + /* location and radius. nssverts() sets vpua */ + /* norm will contain the normal of the triangle */ + /* the point originates from. */ + + void (*startnexttri)(struct _gamut *s); /* Reset indexing through triangles for getnexttri() */ + + int (*getnexttri)(struct _gamut *s, int v[3]); + /* Return the next surface triange, nz on no more */ + /* Index v[] corresponds to order of getvert() */ + + double (*volume)(struct _gamut *s); + /* Return the total volume enclosed by the gamut */ + + int (*intersect)(struct _gamut *s, struct _gamut *s1, struct _gamut *s2); + /* Initialise this gamut with the intersection of the */ + /* the two given gamuts. */ + +#ifdef NEVER /* Deprecated */ + int (*expandbydiff)(struct _gamut *s, struct _gamut *s1, struct _gamut *s2, struct _gamut *s3, int docomp); + /* Initialise this gamut with a gamut which is s1 expanded */ + /* (but never reduced) by the distance from s2 to s3. */ + /* If docomp != 0, make gamut trace s3 if it's smaller than s1 */ +#endif + + int (*compdstgamut)(struct _gamut *s, struct _gamut *img, struct _gamut *src, + struct _gamut *dst, int docomp, int doexpp, struct _gamut *nedst, + void (*cvect)(void *cntx, double *p2, double *p1), void *cntx); + /* Initialise this gamut with a destination mapping gamut. */ + + double (*radial)(struct _gamut *s, double out[3], double in[3]); + /* return point on surface in same radial direction. */ + /* Return the radial radius to the surface point in */ + /* colorspace units. out[] may be NULL */ + + double (*nradial)(struct _gamut *s, double out[3], double in[3]); + /* return point on surface in same radial direction, */ + /* and normalised radial radius. This will be <= 1.0 if within */ + /* gamut, and > 1.0 if out of gamut. out[] may be NULL */ + + void (*nearest)(struct _gamut *s, double out[3], double in[3]); + /* return point on surface closest to input */ + + void (*nearest_tri)(struct _gamut *s, double out[3], double in[3], gtri **ctri); + /* return point on surface closest to input & triangle */ + + int (*vector_isect)(struct _gamut *s, double *p1, double *p2, double *min, double *max, + double *mint, double *maxt, + gtri **mntri, gtri **mxtri); + /* Compute the intersection of the vector p1->p2 with */ + /* the gamut surface. min is the intersection in the p1 direction, */ + /* max is intersection in the p2 direction. mint and maxt are */ + /* the parameter values at the two intersection points, a value of 0 */ + /* being at p1 and 1 being at p2. mintri and maxtri return the */ + /* intersection triangles. min, max, mint, maxt, */ + /* mintri & maxtri may be NULL */ + /* Return 0 if there is no intersection with the gamut. */ + + int (*vector_isectns)(struct _gamut *s, double *p1, double *p2, gispnt *lp, int ll); + /* Compute all the intersection pairs of the vector p1->p2 with */ + /* the gamut surface. lp points to an array of ll gispnt to be */ + /* filled in. If the list is too small, intersections will be */ + /* arbitrarily ignored. */ + /* Return the number of intersections set in list. Will be even. */ + /* These will all be in then out pairs in direction p1->p2. */ + + void (*setwb)(struct _gamut *s, double *wp, double *bp, double *kp); + /* Define the colorspaces white, black and K only black points. */ + /* May be NULL if unknown, and will be set to a default. */ + /* Same colorspace as gamut */ + + int (*getwb)(struct _gamut *s, double *cswp, double *csbp, double *cskp, + double *gawp, double *gabp, double *gakp); + /* Get the colorspace and gamut white, black and K only black points. */ + /* Return non-zero if not possible. Same colorspace as gamut */ + + void (*setcusps)(struct _gamut *s, int flag, double in[3]); /* Set potential cusp values. */ + /* flag == 0 = reset, */ + /* flag == 1 = add general point, */ + /* flag == 3 = add definite point, */ + /* flag == 2 = finish */ + + int (*getcusps)(struct _gamut *s, double cusps[6][3]); /* Get the cusp values for */ + /* red, yellow, green, cyan, */ + /* blue & magenta. Return */ + /* nz if no cusps available. */ + + /* Following return nz on error: */ + int (*write_vrml)(struct _gamut *s, char *filename, + int doaxes, int docusps); /* Write to a VRML .wrl file */ + int (*write_gam)(struct _gamut *s, char *filename); /* Write to a CGATS .gam file */ + int (*read_gam)(struct _gamut *s, char *filename); /* Read from a CGATS .gam file */ + + int (*write_trans_vrml)(struct _gamut *s, char *filename, /* Write transformed VRML .wrl */ + int doaxes, int docusps, void (*transform)(void *cntx, double out[3], double in[3]), /* with xform */ + void *cntx); + +}; typedef struct _gamut gamut; + +/* Creator */ +gamut *new_gamut(double sres, int isJab, int isRast); /* Surface resolution, 0.0 = default */ + +/* Utility */ +void gamut_rect2radial(gamut *s, double out[3], double in[3]); +void gamut_radial2rect(gamut *s, double out[3], double in[3]); +void gamut_Lab2RGB(double *in, double *out); +extern double gam_hues[2][7]; /* Generic Lab & Jab color hues in degrees */ + + +#endif /* GAMUT_H */ + |