summaryrefslogtreecommitdiff
path: root/target/ppoint.h
blob: 2a4bc52e4c5eded4c8e2f0eaf5f6661923bc2d5a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134

#ifndef PPOINT_H

/* 
 * Argyll Color Correction System
 *
 * Perceptually distributed point class
 *
 * Author: Graeme W. Gill
 * Date:   16/10/96
 *
 * 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.
 */

#define MXPD 4			/* Maximum ppoint dimentionality */
#define POW2MXPD 16		/* 2 ^ MXPD */
#define POW3MXPD 81		/* 3 ^ MXPD */
#define MXNP (MXPD + 1 + 20)	/* Maximum near points */

/* tuning parameters */
#define WPOINTS 20		/* Points returned per group */
#define FPOINTS 5000	/* Number of far points to track - more is better. */
#define OPOINTS  250	/* Number of optimsed far points to use - more is slower */
#define DDMIX 0.75		/* Device distance to perceptual ratio in distance computation */
#define DWEIGHT 0.05	/* Distance factor weight added to maximum error in opt func */
#define CLOSED 0.05		/* Too close criteria */

/* A sample point node */
struct _node {
	int    fx;			/* nz if point is fixed */
	double p[MXPD];		/* Device coordinate position */
	double v[MXPD];		/* Subjective value (Labk) */
}; typedef struct _node node;

/* Main perceptual point object */
struct _ppoint {
/* private: */
	int di;			/* Point dimensionality */
	double ilimit;	/* Ink limit - limit on sum of p[] */
	int fnp;		/* Number of existing fixed points in list */
	int tinp;		/* target number of total points in list */

	node *list;		/* tinp list of points */
	int np;			/* Number of points currently in list */

	/* Perceptual function handed in */
	void (*percept)(void *od, double *out, double *in);
	void *od;		/* Opaque data for perceptual point */
	
	/* Progressive interpolation grid */
	rspl *g;

	/* Perceptual distance map */
	rspl *pd;

	/* Candidate far point starting values */
	co fp[FPOINTS];		/* Candidate points */
	int nfp;			/* Current number in fp[] */
	int wfp;			/* Index of current worst far point */
	double wfpd;		/* worst far point distance */ 
	co fwfp[FPOINTS];	/* Working space for find_worst() */

	/* Other info */
	int rix;			/* Next read index */
//	double mn,mx,av;	/* Perceptual distance stats */
	
/* public: */
	/* return non-zero if the perceptual point is within the device gammut */
	int (*pig)(struct _ppoint *s, double *p);

	/* Initialise, ready to read out all the points */
	void (*reset)(struct _ppoint *s);

	/* Read the next set of non-fixed points values */
	/* return non-zero when no more points */
	int (*read)(struct _ppoint *s, double *p, double *f);

	/* Calculate and print stats */
	void (*stats)(struct _ppoint *s);

	/* Destroy ourselves */
	void (*del)(struct _ppoint *s);

	}; typedef struct _ppoint ppoint;


/* Constructor */
extern ppoint *new_ppoint(int di, double ilimit, int npoints,
	fxpos *fxlist, int fxno, 
	void (*percept)(void *od, double *out, double *in), void *od);

/* ------------------------------------------------------- */
/* Macros for a di dimensional counter */
/* Declare the counter name nn, dimensions di, & count */

#define DCOUNT(nn, di, start, reset, count) 				\
	int nn[MXPD];	/* counter value */						\
	int nn##_di = (di);		/* Number of dimensions */		\
	int nn##_stt = (start);	/* start count value */			\
	int nn##_rst = (reset);	/* reset on carry value */		\
	int nn##_res = (count);	/* last count +1 */				\
	int nn##_e				/* dimension index */

/* Set the counter value to 0 */
#define DC_INIT(nn) 								\
{													\
	for (nn##_e = 0; nn##_e < nn##_di; nn##_e++)	\
		nn[nn##_e] = nn##_stt;						\
	nn##_e = 0;										\
}

/* Increment the counter value */
#define DC_INC(nn)									\
{													\
	for (nn##_e = 0; nn##_e < nn##_di; nn##_e++) {	\
		nn[nn##_e]++;								\
		if (nn[nn##_e] < nn##_res)					\
			break;	/* No carry */					\
		nn[nn##_e] = nn##_rst;						\
	}												\
}

/* After increment, expression is TRUE if counter is done */
#define DC_DONE(nn)									\
	(nn##_e >= nn##_di)
	
/* ------------------------------------------------------- */

#define PPOINT_H
#endif /* PPOINT_H */