3
* International Color Consortium color transform expanded support
5
* Author: Graeme W. Gill
9
* Copyright 2000 Graeme W. Gill
10
* All rights reserved.
11
* This material is licenced under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 :-
12
* see the License.txt file for licencing details.
17
* This class handles the creation of an optimised color separation.
18
* This is a middle layer that has a repertoire of ink separation
19
* rules that can be applied to suite the particular colorspace and
22
* !!! Under Development - not finished yet !!!
30
/* Return the separation given the pseudo-device values */
31
/* (Assumes that we have loaded or computed the separation into a */
32
/* separation object) */
33
static void xsep_lookup(
35
double out[MXDO], /* Actual device output (ie. CMYKOG) */
36
double in[MXDI] /* Pseudo device CMYx input */
41
for (i = 0; i < p->pdi; i++)
44
p->sep->interp(p->sep, &tc);
46
for (i = 0; i < p->ddi; i++)
61
#ifdef NEVER /* Not used yet */
63
/* The optimisation function passed to opt_rspl */
64
/* Returns value is the "error" for this point. */
65
static double optfunc(
67
double *inout, /* Pointers to fdi+pdi+adi values for the grid point being optimised. */
68
/* corresponding to */
69
double *surav, /* Pointers to fdi+pdi values which are the average of the */
70
/* neighbors of this grid point. Pointer will NULL if this */
71
/* is a surface grid point. */
72
int first, /* Flag, NZ if this is the first optimisation of this point. */
73
double cw /* The (grid resolution) curvature weighting factor */
75
xsep *p = (xsep *)fdata;
77
/* If first time at this grid resolution, compute needed locus extreme values */
78
/* and place them in the additional values allocation */
82
if (surav == NULL) { /* Must be a surface point */
83
/* Optimise to maximise distance along vector direction */
84
/* together with device value smoothness, inking rule */
85
/* targets and ink limit. */
87
/* Compute surface smoothness value */
89
} else { /* Must be an interior point */
90
/* Compute Lab target as mean of surrounding targets, */
91
/* and optimise towards it, together with device value */
92
/* smoothness, inking rule targets and ink limit. */
94
/* Compute interior smoothness value */
103
/* default target vectors (Labx) for CMYx input */
104
static double def_tvect[16][4] = {
105
{ 100.0, 0.0, 0.0, 100.0 }, /* 0 0 0 0 */
106
{ 50.0, -60.0, -100.0, 100.0 }, /* C 0 0 0 */
107
{ 50.0, 100.0, 0.0, 100.0 }, /* 0 M 0 0 */
108
{ 25.0, 60.0, -100.0, 100.0 }, /* C M 0 0 */
109
{ 90.0, 0.0, 100.0, 100.0 }, /* 0 0 Y 0 */
110
{ 50.0,-100.0, 60.0, 100.0 }, /* C 0 Y 0 */
111
{ 50.0, 100.0, 100.0, 100.0 }, /* 0 M Y 0 */
112
{ 0.0, 0.0, 0.0, 100.0 }, /* C M Y 0 */
113
{ 100.0, 0.0, 0.0, 0.0 }, /* 0 0 0 x */
114
{ 50.0, -60.0, -100.0, 0.0 }, /* C 0 0 x */
115
{ 50.0, 100.0, 0.0, 0.0 }, /* 0 M 0 x */
116
{ 25.0, 60.0, -100.0, 0.0 }, /* C M 0 x */
117
{ 90.0, 0.0, 100.0, 0.0 }, /* 0 0 Y x */
118
{ 50.0,-100.0, 60.0, 0.0 }, /* C 0 Y x */
119
{ 50.0, 100.0, 100.0, 0.0 }, /* 0 M Y x */
120
{ 0.0, 0.0, 0.0, 0.0 } /* C M Y x */
123
/* Create the optimised separation - return NULL on error */
124
/* We assume that we want to create a separation from pseudo-device */
125
/* channels CMY' to the real device channels. There may also be auxiliary */
126
/* channels that come after CMY' and Lab. The schident[] is used to align */
127
/* the pseudo chanels with their real counterparts. If there are no */
128
/* counterparts, then xsep will use a default. The schident[3] is assumed */
129
/* to be the chanel to use for the black (C+M+Y) chanel as an alternative */
130
/* to the C+M+Y direction. */
132
int pdi, /* pseudo device CMY'/CMYK', and target Lab/LabL (PCS) dimensions */
133
int ddi, /* Device Dimensions/Channels */
134
int (*dev2lab) (void *d2lcntx, double *out, double *in), /* Device to Lab callback */
135
void *d2lcntx, /* dev2lab callback context */
136
double (*dev2ink) (void *d2icntx, double *out, double *in), /* Device to ink callback */
137
/* Return 2 or 3 totals: Total ink, CMY sup. group, K sup. */
138
void *d2icntx, /* dev2ink callback context */
139
double totlimit, /* Value not to be exceeded by dev2ink() Total ink, 0.0 .. N.0 */
140
double smoothness, /* Device value smoothness, nominally 1.0 */
141
int schident[3], /* Standard channel ident for psudo CMY' chanels. */
142
/* -1 = no mapping else index of corresponding device channel. */
143
icxScat cat[MXDO] /* Device channel control and function category */
146
rspl *sep; /* Mapping we will create */
148
// double **vdata; /* pdi^2 array of function, target and additional values to init */
152
if (pdi != 3 && pdi != 4) {
156
if (ddi < 1 || ddi > MXDO) {
160
if ((p = (xsep *) calloc(1,sizeof(xsep))) == NULL)
163
p->lookup = xsep_lookup;
166
/* We need to setup the initial CMYx' colorant target vectors */
167
/* This will be from the device counterparts (ie. like CMYK), */
168
/* or using a default set of directions. */
170
for (i = 0; i < pdi; i++) {
172
break; /* Not all defined */
173
for (j = 0; j < i; j++)
174
if (schident[j] == schident[i])
175
break; /* Two are the same */
179
if (i < pdi) { /* Fall back on default */
180
for (i = 0; i < (1 << pdi); i++) {
181
vdatap[i] = def_tvect[i]; // ~~~99
186
/* !!! Stuff goes here !!! */
187
/* This will rely on the opt_rspl method of the rspl class */
189
/* Create the rspl that maps CMYx -> Device values */
190
if ((sep = new_rspl(RSPL_NOFLAGS, pdi, ddi)) == NULL) {
196
/* Set values by multi-grid optimisation using the provided function. */
197
/* The input values to the rspl are typically the CMY' or CMYx' color space. */
198
/* The output values are the device values */
199
/* The target values are typically Lab or Labx (vector dir on surface) */
200
/* The additional value are typically the device auxiliary chanel locus limits, */
201
/* computed on the first call at a given grid resolution. */
202
/* The func needs to compute the smoothness value, and weight it */
203
/* by the curvature value. */
206
int flags, /* Combination of flags */
207
int pdi, /* Dimensionality of target data (typically Lab or Labx) */
208
int adi, /* Additional grid point data allowance */
209
double **vdata, /* pdi^2 array of function, target and additional values to init */
210
/* array corners with. */
211
double (*func)(void *fdata, double *inout, double *surav, int first, double cw),
212
/* Optimisation function */
213
void *fdata, /* Opaque data needed by function */
214
datai glow, /* Grid low scale - NULL = default 0.0 */
215
datai ghigh, /* Grid high scale - NULL = default 1.0 */
216
int gres, /* Spline grid resolution */
217
datao vlow, /* Data value low normalize, NULL = default 0.0 */
218
datao vhigh /* Data value high normalize - NULL = default 1.0 */