summaryrefslogtreecommitdiff
path: root/gamut/gamut.h
diff options
context:
space:
mode:
Diffstat (limited to 'gamut/gamut.h')
-rw-r--r--gamut/gamut.h406
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 */
+