1 /*
2 *
3 * Gimp-Print color management module - traditional Gimp-Print algorithm.
4 *
5 * Copyright 1997-2000 Michael Sweet (mike@easysw.com) and
6 * Robert Krawitz (rlk@alum.mit.edu)
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the Free
10 * Software Foundation; either version 2 of the License, or (at your option)
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 * for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>.
20 */
21
22 /*
23 * This file must include only standard C header files. The core code must
24 * compile on generic platforms that don't support glib, gimp, gtk, etc.
25 */
26
27 #ifdef HAVE_CONFIG_H
28 #include <config.h>
29 #endif
30 #include <gutenprint/gutenprint.h>
31 #include "gutenprint-internal.h"
32 #include <gutenprint/gutenprint-intl-internal.h>
33 #include <gutenprint/curve-cache.h>
34 #include <math.h>
35 #ifdef HAVE_LIMITS_H
36 #include <limits.h>
37 #endif
38 #include <string.h>
39 #include "color-conversion.h"
40
41 #ifdef __GNUC__
42 #define inline __inline__
43 // There's no reason to inline the main loop with the dispatch
44 // functions only to fail inlining of calls from the inner loop.
45 // Also, inlining the main loop makes it hard to debug because we lose
46 // context of which print function is called.
47 #define NOINLINE __attribute__ ((noinline))
48 #else
49 $define NOINLINE
50 #endif
51
52 #define CFUNC static unsigned NOINLINE
53
54 /*
55 * RGB to grayscale luminance constants...
56 */
57
58 #define LUM_RED 31
59 #define LUM_GREEN 61
60 #define LUM_BLUE 8
61
62 /* rgb/hsl conversions taken from Gimp common/autostretch_hsv.c */
63
64 #define FMAX(a, b) ((a) > (b) ? (a) : (b))
65 #define FMIN(a, b) ((a) < (b) ? (a) : (b))
66
67 #define MAXB(bits) ((1 << (bits)) - 1)
68
69 static inline void
calc_rgb_to_hsl(unsigned short * rgb,double * hue,double * sat,double * lightness)70 calc_rgb_to_hsl(unsigned short *rgb, double *hue, double *sat,
71 double *lightness)
72 {
73 double red, green, blue;
74 double h, s, l;
75 double min, max;
76 double delta;
77 int maxval;
78
79 red = rgb[0] / 65535.0;
80 green = rgb[1] / 65535.0;
81 blue = rgb[2] / 65535.0;
82
83 if (red > green)
84 {
85 if (red > blue)
86 {
87 max = red;
88 maxval = 0;
89 }
90 else
91 {
92 max = blue;
93 maxval = 2;
94 }
95 min = FMIN(green, blue);
96 }
97 else
98 {
99 if (green > blue)
100 {
101 max = green;
102 maxval = 1;
103 }
104 else
105 {
106 max = blue;
107 maxval = 2;
108 }
109 min = FMIN(red, blue);
110 }
111
112 l = (max + min) / 2.0;
113 delta = max - min;
114
115 if (delta < .000001) /* Suggested by Eugene Anikin <eugene@anikin.com> */
116 {
117 s = 0.0;
118 h = 0.0;
119 }
120 else
121 {
122 if (l <= .5)
123 s = delta / (max + min);
124 else
125 s = delta / (2 - max - min);
126
127 if (maxval == 0)
128 h = (green - blue) / delta;
129 else if (maxval == 1)
130 h = 2 + (blue - red) / delta;
131 else
132 h = 4 + (red - green) / delta;
133
134 if (h < 0.0)
135 h += 6.0;
136 else if (h > 6.0)
137 h -= 6.0;
138 }
139
140 *hue = h;
141 *sat = s;
142 *lightness = l;
143 }
144
145 static inline double
hsl_value(double n1,double n2,double hue)146 hsl_value(double n1, double n2, double hue)
147 {
148 if (hue < 0)
149 hue += 6.0;
150 else if (hue > 6)
151 hue -= 6.0;
152 if (hue < 1.0)
153 return (n1 + (n2 - n1) * hue);
154 else if (hue < 3.0)
155 return (n2);
156 else if (hue < 4.0)
157 return (n1 + (n2 - n1) * (4.0 - hue));
158 else
159 return (n1);
160 }
161
162 static inline void
calc_hsl_to_rgb(unsigned short * rgb,double h,double s,double l)163 calc_hsl_to_rgb(unsigned short *rgb, double h, double s, double l)
164 {
165 if (s < .0000001)
166 {
167 if (l > 1)
168 l = 1;
169 else if (l < 0)
170 l = 0;
171 rgb[0] = l * 65535;
172 rgb[1] = l * 65535;
173 rgb[2] = l * 65535;
174 }
175 else
176 {
177 double m1, m2;
178 double h1, h2;
179 h1 = h + 2;
180 h2 = h - 2;
181
182 if (l < .5)
183 m2 = l * (1 + s);
184 else
185 m2 = l + s - (l * s);
186 m1 = (l * 2) - m2;
187 rgb[0] = 65535 * hsl_value(m1, m2, h1);
188 rgb[1] = 65535 * hsl_value(m1, m2, h);
189 rgb[2] = 65535 * hsl_value(m1, m2, h2);
190 }
191 }
192
193 static inline double
update_saturation(double sat,double adjust,double isat,int bright_colors)194 update_saturation(double sat, double adjust, double isat, int bright_colors)
195 {
196 if (bright_colors || adjust < 1)
197 sat *= adjust;
198 else if (adjust > 1)
199 {
200 double s1 = sat * adjust;
201 double s2 = 1.0 - ((1.0 - sat) * isat);
202 sat = FMIN(s1, s2);
203 }
204 if (sat > 1)
205 sat = 1.0;
206 return sat;
207 }
208
209 static inline double
interpolate_value(const double * vec,double val)210 interpolate_value(const double *vec, double val)
211 {
212 double base = (double)((int)(val));
213 double frac = val - base;
214 int ibase = (int) base;
215 double lval = vec[ibase];
216 if (frac > 0)
217 lval += (vec[ibase + 1] - lval) * frac;
218 return lval;
219 }
220
221 static inline void
update_saturation_from_rgb(unsigned short * rgb,const unsigned short * brightness_lookup,double adjust,double isat,int do_usermap)222 update_saturation_from_rgb(unsigned short *rgb,
223 const unsigned short *brightness_lookup,
224 double adjust, double isat, int do_usermap)
225 {
226 double h, s, l;
227 calc_rgb_to_hsl(rgb, &h, &s, &l);
228 if (do_usermap)
229 {
230 unsigned short ub = (unsigned short) (l * 65535);
231 unsigned short val = brightness_lookup[ub];
232 l = ((double) val) / 65535;
233 if (val < ub)
234 s = s * (65535 - ub) / (65535 - val);
235 }
236 s = update_saturation(s, adjust, isat, 0);
237 calc_hsl_to_rgb(rgb, h, s, l);
238 }
239
240 static inline double
adjust_hue(const double * hue_map,double hue,size_t points)241 adjust_hue(const double *hue_map, double hue, size_t points)
242 {
243 if (hue_map)
244 {
245 hue += interpolate_value(hue_map, hue * points / 6.0);
246 if (hue < 0.0)
247 hue += 6.0;
248 else if (hue >= 6.0)
249 hue -= 6.0;
250 }
251 return hue;
252 }
253
254 static inline void
adjust_hsl(unsigned short * rgbout,lut_t * lut,double ssat,double isat,int split_saturation,int adjust_hue_only,int bright_colors)255 adjust_hsl(unsigned short *rgbout, lut_t *lut, double ssat, double isat,
256 int split_saturation, int adjust_hue_only, int bright_colors)
257 {
258 const double *hue_map = CURVE_CACHE_FAST_DOUBLE(&(lut->hue_map));
259 const double *lum_map = CURVE_CACHE_FAST_DOUBLE(&(lut->lum_map));
260 const double *sat_map = CURVE_CACHE_FAST_DOUBLE(&(lut->sat_map));
261 size_t hue_count = CURVE_CACHE_FAST_COUNT(&(lut->hue_map));
262 size_t lum_count = CURVE_CACHE_FAST_COUNT(&(lut->lum_map));
263 size_t sat_count = CURVE_CACHE_FAST_COUNT(&(lut->sat_map));
264 double h, s, l;
265 double oh;
266 rgbout[0] ^= 65535;
267 rgbout[1] ^= 65535;
268 rgbout[2] ^= 65535;
269 calc_rgb_to_hsl(rgbout, &h, &s, &l);
270 s = update_saturation(s, ssat, isat, 0);
271 if (!adjust_hue_only && lut->sat_map.d_cache)
272 {
273 double nh = h * sat_count / 6.0;
274 double tmp = interpolate_value(sat_map, nh);
275 if (tmp < .9999 || tmp > 1.0001)
276 s = update_saturation(s, tmp, tmp > 1.0 ? 1.0 / tmp : 1.0,
277 bright_colors);
278 }
279 oh = h;
280 h = adjust_hue(hue_map, h, hue_count);
281 calc_hsl_to_rgb(rgbout, h, s, l);
282
283 if (!adjust_hue_only && s > 0.00001)
284 {
285 /*
286 * Perform luminosity adjustment only on color component.
287 * This way the luminosity of the gray component won't be affected.
288 * We'll add the gray back at the end.
289 */
290
291 unsigned gray = FMIN(rgbout[0], FMIN(rgbout[1], rgbout[2]));
292 int i;
293 /*
294 * Scale the components by the amount of color left.
295 * This way the luminosity calculations will come out right.
296 */
297 if (gray > 0)
298 for (i = 0; i < 3; i++)
299 rgbout[i] = (rgbout[i] - gray) * 65535.0 / (65535 - gray);
300
301 if (lut->lum_map.d_cache)
302 {
303 calc_rgb_to_hsl(rgbout, &h, &s, &l);
304 if (lut->lum_map.d_cache && l > 0.00001 && l < .99999)
305 {
306 double nh = oh * lum_count / 6.0;
307 double oel = interpolate_value(lum_map,nh);
308 if (oel <= 1)
309 l *= oel;
310 else
311 {
312 double g1 = pow(l, 1.0 / oel);
313 double g2 = 1.0 - pow(1.0 - l, oel);
314 l = FMIN(g1, g2);
315 }
316 calc_hsl_to_rgb(rgbout, h, s, l);
317 }
318 }
319 if (gray > 0)
320 for (i = 0; i < 3; i++)
321 rgbout[i] = gray + (rgbout[i] * (65535 - gray) / 65535.0);
322 }
323
324 rgbout[0] ^= 65535;
325 rgbout[1] ^= 65535;
326 rgbout[2] ^= 65535;
327 }
328
329 #define GENERIC_COLOR_FUNC(fromname, toname) \
330 CFUNC \
331 fromname##_to_##toname(const stp_vars_t *vars, const unsigned char *in, \
332 unsigned short *out) \
333 { \
334 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
335 if (!lut->printed_colorfunc) \
336 { \
337 lut->printed_colorfunc = 1; \
338 stp_dprintf(STP_DBG_COLORFUNC, vars, \
339 "Colorfunc is %s_%d_to_%s, %s, %s, %d, %d\n", \
340 #fromname, lut->channel_depth, #toname, \
341 lut->input_color_description->name, \
342 lut->output_color_description->name, \
343 lut->steps, lut->invert_output); \
344 } \
345 if (lut->channel_depth == 8) \
346 return fromname##_8_to_##toname(vars, in, out); \
347 else \
348 return fromname##_16_to_##toname(vars, in, out); \
349 }
350
351 #define BD(bits) (65535u / (unsigned) MAXB(bits))
352
353 #define COLOR_TO_COLOR_FUNC(T, bits) \
354 CFUNC \
355 color_##bits##_to_color(const stp_vars_t *vars, const unsigned char *in, \
356 unsigned short *out) \
357 { \
358 int i; \
359 double isat = 1.0; \
360 double ssat = stp_get_float_parameter(vars, "Saturation"); \
361 double sbright = stp_get_float_parameter(vars, "Brightness"); \
362 int i0 = -1; \
363 int i1 = -1; \
364 int i2 = -1; \
365 unsigned short o0 = 0; \
366 unsigned short o1 = 0; \
367 unsigned short o2 = 0; \
368 unsigned short nz0 = 0; \
369 unsigned short nz1 = 0; \
370 unsigned short nz2 = 0; \
371 const unsigned short *red; \
372 const unsigned short *green; \
373 const unsigned short *blue; \
374 const unsigned short *brightness; \
375 const unsigned short *contrast; \
376 const T *s_in = (const T *) in; \
377 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
378 int compute_saturation = ssat <= .99999 || ssat >= 1.00001; \
379 int split_saturation = ssat > 1.4; \
380 int bright_color_adjustment = 0; \
381 int hue_only_color_adjustment = 0; \
382 int do_user_adjustment = 0; \
383 if (lut->color_correction->correction == COLOR_CORRECTION_BRIGHT) \
384 bright_color_adjustment = 1; \
385 if (lut->color_correction->correction == COLOR_CORRECTION_HUE) \
386 hue_only_color_adjustment = 1; \
387 if (sbright != 1) \
388 do_user_adjustment = 1; \
389 compute_saturation |= do_user_adjustment; \
390 \
391 for (i = CHANNEL_C; i <= CHANNEL_Y; i++) \
392 stp_curve_resample(stp_curve_cache_get_curve(&(lut->channel_curves[i])), \
393 1 << bits); \
394 stp_curve_resample \
395 (stp_curve_cache_get_curve(&(lut->brightness_correction)), 65536); \
396 stp_curve_resample \
397 (stp_curve_cache_get_curve(&(lut->contrast_correction)), 1 << bits); \
398 red = \
399 stp_curve_cache_get_ushort_data(&(lut->channel_curves[CHANNEL_C])); \
400 green = \
401 stp_curve_cache_get_ushort_data(&(lut->channel_curves[CHANNEL_M])); \
402 blue = \
403 stp_curve_cache_get_ushort_data(&(lut->channel_curves[CHANNEL_Y])); \
404 brightness= \
405 stp_curve_cache_get_ushort_data(&(lut->brightness_correction)); \
406 contrast = \
407 stp_curve_cache_get_ushort_data(&(lut->contrast_correction)); \
408 (void) stp_curve_cache_get_double_data(&(lut->hue_map)); \
409 (void) stp_curve_cache_get_double_data(&(lut->lum_map)); \
410 (void) stp_curve_cache_get_double_data(&(lut->sat_map)); \
411 const double *hue_map = CURVE_CACHE_FAST_DOUBLE(&(lut->hue_map)); \
412 const double *lum_map = CURVE_CACHE_FAST_DOUBLE(&(lut->lum_map)); \
413 const double *sat_map = CURVE_CACHE_FAST_DOUBLE(&(lut->sat_map)); \
414 \
415 if (split_saturation) \
416 ssat = sqrt(ssat); \
417 if (ssat > 1) \
418 isat = 1.0 / ssat; \
419 for (i = 0; i < lut->image_width; i++) \
420 { \
421 if (i0 == s_in[0] && i1 == s_in[1] && i2 == s_in[2]) \
422 { \
423 out[0] = o0; \
424 out[1] = o1; \
425 out[2] = o2; \
426 } \
427 else \
428 { \
429 i0 = s_in[0]; \
430 i1 = s_in[1]; \
431 i2 = s_in[2]; \
432 out[0] = contrast[i0]; \
433 out[1] = contrast[i1]; \
434 out[2] = contrast[i2]; \
435 if ((compute_saturation)) \
436 update_saturation_from_rgb(out, brightness, ssat, isat, \
437 do_user_adjustment); \
438 if ((split_saturation || lum_map || hue_map || sat_map) && \
439 (out[0] != out[1] || out[0] != out[2])) \
440 adjust_hsl(out, lut, ssat, isat, split_saturation, \
441 hue_only_color_adjustment, bright_color_adjustment); \
442 out[0] = red[out[0] / BD(bits)]; \
443 out[1] = green[out[1] / BD(bits)]; \
444 out[2] = blue[out[2] / BD(bits)]; \
445 o0 = out[0]; \
446 o1 = out[1]; \
447 o2 = out[2]; \
448 nz0 |= o0; \
449 nz1 |= o1; \
450 nz2 |= o2; \
451 } \
452 s_in += 3; \
453 out += 3; \
454 } \
455 return (nz0 ? 0 : 1) + (nz1 ? 0 : 2) + (nz2 ? 0 : 4); \
456 }
457
458 COLOR_TO_COLOR_FUNC(unsigned char, 8) // color_8_to_color
459 COLOR_TO_COLOR_FUNC(unsigned short, 16) // color_16_to_color
GENERIC_COLOR_FUNC(color,color)460 GENERIC_COLOR_FUNC(color, color)
461
462 #define COLOR_TO_KCMY_FUNC(T, bits) \
463 CFUNC \
464 color_##bits##_to_kcmy(const stp_vars_t *vars, const unsigned char *in, \
465 unsigned short *out) \
466 { \
467 int i; \
468 double isat = 1.0; \
469 double ssat = stp_get_float_parameter(vars, "Saturation"); \
470 double sbright = stp_get_float_parameter(vars, "Brightness"); \
471 union { \
472 unsigned short nz[4]; \
473 unsigned long long nzl; \
474 } nzx; \
475 unsigned retval = 0; \
476 const unsigned short *red; \
477 const unsigned short *green; \
478 const unsigned short *blue; \
479 const unsigned short *brightness; \
480 const unsigned short *contrast; \
481 const T *s_in = (const T *) in; \
482 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
483 int compute_saturation = ssat <= .99999 || ssat >= 1.00001; \
484 int split_saturation = ssat > 1.4; \
485 int bright_color_adjustment = 0; \
486 int hue_only_color_adjustment = 0; \
487 int do_user_adjustment = 0; \
488 if (lut->color_correction->correction == COLOR_CORRECTION_BRIGHT) \
489 bright_color_adjustment = 1; \
490 if (lut->color_correction->correction == COLOR_CORRECTION_HUE) \
491 hue_only_color_adjustment = 1; \
492 if (sbright != 1) \
493 do_user_adjustment = 1; \
494 compute_saturation |= do_user_adjustment; \
495 nzx.nzl = 0ull; \
496 \
497 for (i = CHANNEL_C; i <= CHANNEL_Y; i++) \
498 stp_curve_resample(stp_curve_cache_get_curve(&(lut->channel_curves[i])), \
499 1 << bits); \
500 stp_curve_resample \
501 (stp_curve_cache_get_curve(&(lut->brightness_correction)), 65536); \
502 stp_curve_resample \
503 (stp_curve_cache_get_curve(&(lut->contrast_correction)), 1 << bits); \
504 red = \
505 stp_curve_cache_get_ushort_data(&(lut->channel_curves[CHANNEL_C])); \
506 green = \
507 stp_curve_cache_get_ushort_data(&(lut->channel_curves[CHANNEL_M])); \
508 blue = \
509 stp_curve_cache_get_ushort_data(&(lut->channel_curves[CHANNEL_Y])); \
510 brightness= \
511 stp_curve_cache_get_ushort_data(&(lut->brightness_correction)); \
512 contrast = \
513 stp_curve_cache_get_ushort_data(&(lut->contrast_correction)); \
514 (void) stp_curve_cache_get_double_data(&(lut->hue_map)); \
515 (void) stp_curve_cache_get_double_data(&(lut->lum_map)); \
516 (void) stp_curve_cache_get_double_data(&(lut->sat_map)); \
517 const double *hue_map = CURVE_CACHE_FAST_DOUBLE(&(lut->hue_map)); \
518 const double *lum_map = CURVE_CACHE_FAST_DOUBLE(&(lut->lum_map)); \
519 const double *sat_map = CURVE_CACHE_FAST_DOUBLE(&(lut->sat_map)); \
520 \
521 if (split_saturation) \
522 ssat = sqrt(ssat); \
523 if (ssat > 1) \
524 isat = 1.0 / ssat; \
525 for (i = 0; i < lut->image_width; i++, out += 4, s_in += 3) \
526 { \
527 out[1] = contrast[s_in[0]]; \
528 out[2] = contrast[s_in[1]]; \
529 out[3] = contrast[s_in[2]]; \
530 if ((compute_saturation)) \
531 update_saturation_from_rgb(out + 1, brightness, ssat, isat, \
532 do_user_adjustment); \
533 if ((split_saturation || lum_map || hue_map || sat_map) && \
534 (out[1] != out[2] || out[1] != out[3])) \
535 adjust_hsl(out + 1, lut, ssat, isat, split_saturation, \
536 hue_only_color_adjustment, bright_color_adjustment); \
537 out[1] = red[out[1] / BD(bits)]; \
538 out[2] = green[out[2] / BD(bits)]; \
539 out[3] = blue[out[3] / BD(bits)]; \
540 out[0] = FMIN(out[1], FMIN(out[2], out[3])); \
541 out[1] -= out[0]; \
542 out[2] -= out[0]; \
543 out[3] -= out[0]; \
544 nzx.nzl |= *(unsigned long long *) out; \
545 } \
546 for (i = 0; i < 4; i++) \
547 if (nzx.nz[i] == 0) \
548 retval |= (1 << i); \
549 return retval; \
550 }
551
552 COLOR_TO_KCMY_FUNC(unsigned char, 8) // color_8_to_kcmy
553 COLOR_TO_KCMY_FUNC(unsigned short, 16) // color_16_to_kcmy
554 GENERIC_COLOR_FUNC(color, kcmy)
555
556 /*
557 * 'rgb_to_rgb()' - Convert rgb image data to RGB.
558 */
559
560 #define FAST_COLOR_TO_COLOR_FUNC(T, bits) \
561 CFUNC \
562 color_##bits##_to_color_fast(const stp_vars_t *vars, const unsigned char *in, \
563 unsigned short *out) \
564 { \
565 int i; \
566 int i0 = -1; \
567 int i1 = -1; \
568 int i2 = -1; \
569 int o0 = 0; \
570 int o1 = 0; \
571 int o2 = 0; \
572 int nz0 = 0; \
573 int nz1 = 0; \
574 int nz2 = 0; \
575 const T *s_in = (const T *) in; \
576 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
577 const unsigned short *red; \
578 const unsigned short *green; \
579 const unsigned short *blue; \
580 const unsigned short *brightness; \
581 const unsigned short *contrast; \
582 double isat = 1.0; \
583 double saturation = stp_get_float_parameter(vars, "Saturation"); \
584 double sbright = stp_get_float_parameter(vars, "Brightness"); \
585 int compute_saturation = saturation <= .99999 || saturation >= 1.00001; \
586 int do_user_adjustment = 0; \
587 if (sbright != 1) \
588 do_user_adjustment = 1; \
589 compute_saturation |= do_user_adjustment; \
590 \
591 for (i = CHANNEL_C; i <= CHANNEL_Y; i++) \
592 stp_curve_resample(lut->channel_curves[i].curve, 65536); \
593 stp_curve_resample \
594 (stp_curve_cache_get_curve(&(lut->brightness_correction)), 65536); \
595 stp_curve_resample \
596 (stp_curve_cache_get_curve(&(lut->contrast_correction)), 1 << bits); \
597 red = \
598 stp_curve_cache_get_ushort_data(&(lut->channel_curves[CHANNEL_C])); \
599 green = \
600 stp_curve_cache_get_ushort_data(&(lut->channel_curves[CHANNEL_M])); \
601 blue = \
602 stp_curve_cache_get_ushort_data(&(lut->channel_curves[CHANNEL_Y])); \
603 brightness= \
604 stp_curve_cache_get_ushort_data(&(lut->brightness_correction)); \
605 contrast = \
606 stp_curve_cache_get_ushort_data(&(lut->contrast_correction)); \
607 \
608 if (saturation > 1) \
609 isat = 1.0 / saturation; \
610 for (i = 0; i < lut->image_width; i++) \
611 { \
612 if (i0 == s_in[0] && i1 == s_in[1] && i2 == s_in[2]) \
613 { \
614 out[0] = o0; \
615 out[1] = o1; \
616 out[2] = o2; \
617 } \
618 else \
619 { \
620 i0 = s_in[0]; \
621 i1 = s_in[1]; \
622 i2 = s_in[2]; \
623 out[0] = contrast[s_in[0]]; \
624 out[1] = contrast[s_in[1]]; \
625 out[2] = contrast[s_in[2]]; \
626 if ((compute_saturation)) \
627 update_saturation_from_rgb(out, brightness, saturation, isat, 1); \
628 out[0] = red[out[0]]; \
629 out[1] = green[out[1]]; \
630 out[2] = blue[out[2]]; \
631 o0 = out[0]; \
632 o1 = out[1]; \
633 o2 = out[2]; \
634 nz0 |= o0; \
635 nz1 |= o1; \
636 nz2 |= o2; \
637 } \
638 s_in += 3; \
639 out += 3; \
640 } \
641 return (nz0 ? 0 : 1) + (nz1 ? 0 : 2) + (nz2 ? 0 : 4); \
642 }
643
644 FAST_COLOR_TO_COLOR_FUNC(unsigned char, 8) // color_8_to_color_fast
645 FAST_COLOR_TO_COLOR_FUNC(unsigned short, 16) // color_16_to_color_fast
646 GENERIC_COLOR_FUNC(color, color_fast)
647
648 #define FAST_COLOR_TO_KCMY_FUNC(T, bits) \
649 CFUNC \
650 color_##bits##_to_kcmy_fast(const stp_vars_t *vars, const unsigned char *in, \
651 unsigned short *out) \
652 { \
653 int i; \
654 union { \
655 unsigned short nz[4]; \
656 unsigned long long nzl; \
657 } nzx; \
658 unsigned retval = 0; \
659 unsigned short c, m, y, k; \
660 const T *s_in = (const T *) in; \
661 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
662 const unsigned short *red; \
663 const unsigned short *green; \
664 const unsigned short *blue; \
665 const unsigned short *brightness; \
666 const unsigned short *contrast; \
667 double isat = 1.0; \
668 double saturation = stp_get_float_parameter(vars, "Saturation"); \
669 double sbright = stp_get_float_parameter(vars, "Brightness"); \
670 int compute_saturation = saturation <= .99999 || saturation >= 1.00001; \
671 int do_user_adjustment = 0; \
672 if (sbright != 1) \
673 do_user_adjustment = 1; \
674 compute_saturation |= do_user_adjustment; \
675 nzx.nzl = 0ull; \
676 \
677 for (i = CHANNEL_C; i <= CHANNEL_Y; i++) \
678 stp_curve_resample(lut->channel_curves[i].curve, 65536); \
679 stp_curve_resample \
680 (stp_curve_cache_get_curve(&(lut->brightness_correction)), 65536); \
681 stp_curve_resample \
682 (stp_curve_cache_get_curve(&(lut->contrast_correction)), 1 << bits); \
683 red = \
684 stp_curve_cache_get_ushort_data(&(lut->channel_curves[CHANNEL_C])); \
685 green = \
686 stp_curve_cache_get_ushort_data(&(lut->channel_curves[CHANNEL_M])); \
687 blue = \
688 stp_curve_cache_get_ushort_data(&(lut->channel_curves[CHANNEL_Y])); \
689 brightness= \
690 stp_curve_cache_get_ushort_data(&(lut->brightness_correction)); \
691 contrast = \
692 stp_curve_cache_get_ushort_data(&(lut->contrast_correction)); \
693 \
694 if (saturation > 1) \
695 isat = 1.0 / saturation; \
696 for (i = 0; i < lut->image_width; i++, out += 4, s_in += 3) \
697 { \
698 c = contrast[s_in[0]]; \
699 m = contrast[s_in[1]]; \
700 y = contrast[s_in[2]]; \
701 if (compute_saturation) \
702 { \
703 unsigned short tmp[3]; \
704 tmp[0] = c; \
705 tmp[1] = m; \
706 tmp[2] = y; \
707 update_saturation_from_rgb(tmp, brightness, saturation, \
708 isat, 1); \
709 c = tmp[0]; \
710 m = tmp[1]; \
711 y = tmp[2]; \
712 } \
713 c = red[c]; \
714 m = green[m]; \
715 y = blue[y]; \
716 k = FMIN(c, FMIN(m, y)); \
717 out[0] = k; \
718 out[1] = c - k; \
719 out[2] = m - k; \
720 out[3] = y - k; \
721 nzx.nzl |= *(unsigned long long *) out; \
722 } \
723 for (i = 0; i < 4; i++) \
724 if (nzx.nz[i] == 0) \
725 retval |= (1 << i); \
726 return retval; \
727 }
728
729 FAST_COLOR_TO_KCMY_FUNC(unsigned char, 8) // color_8_to_kcmy_fast
730 FAST_COLOR_TO_KCMY_FUNC(unsigned short, 16) // color_16_to_color_fast
731 GENERIC_COLOR_FUNC(color, kcmy_fast)
732
733 #define RAW_COLOR_TO_COLOR_FUNC(T, bits) \
734 CFUNC \
735 color_##bits##_to_color_raw(const stp_vars_t *vars, const unsigned char *in,\
736 unsigned short *out) \
737 { \
738 int i; \
739 int j; \
740 int nz = 0; \
741 const T *s_in = (const T *) in; \
742 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
743 unsigned mask = 0; \
744 if (lut->invert_output) \
745 mask = 0xffff; \
746 \
747 for (i = 0; i < lut->image_width; i++) \
748 { \
749 unsigned bit = 1; \
750 for (j = 0; j < 3; j++, bit += bit) \
751 { \
752 out[j] = (s_in[j] * (65535 / ((1 << bits) - 1))) ^ mask; \
753 if (out[j]) \
754 nz |= bit; \
755 } \
756 s_in += 3; \
757 out += 3; \
758 } \
759 return nz; \
760 }
761
762 RAW_COLOR_TO_COLOR_FUNC(unsigned char, 8) // color_8_to_color_raw
763 RAW_COLOR_TO_COLOR_FUNC(unsigned short, 16) // color_16_to_color_raw
764 GENERIC_COLOR_FUNC(color, color_raw)
765
766 #define RAW_COLOR_TO_KCMY_FUNC(T, bits) \
767 CFUNC \
768 color_##bits##_to_kcmy_raw(const stp_vars_t *vars, const unsigned char *in, \
769 unsigned short *out) \
770 { \
771 int i; \
772 union { \
773 unsigned short nz[4]; \
774 unsigned long long nzl; \
775 } nzx; \
776 unsigned retval = 0; \
777 const T *s_in = (const T *) in; \
778 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
779 unsigned mask = 0; \
780 if (lut->invert_output) \
781 mask = 0xffff; \
782 nzx.nzl = 0ull; \
783 \
784 for (i = 0; i < lut->image_width; i++, out += 4, s_in += 3) \
785 { \
786 unsigned c = (s_in[0] * BD(bits)) ^ mask; \
787 unsigned m = (s_in[1] * BD(bits)) ^ mask; \
788 unsigned y = (s_in[2] * BD(bits)) ^ mask; \
789 unsigned k = FMIN(c, FMIN(m, y)); \
790 out[0] = k; \
791 out[1] = c - k; \
792 out[2] = m - k; \
793 out[3] = y - k; \
794 nzx.nzl |= *(unsigned long long *) out; \
795 } \
796 for (i = 0; i < 4; i++) \
797 if (nzx.nz[i] == 0) \
798 retval |= (1 << i); \
799 return retval; \
800 }
801
802 RAW_COLOR_TO_KCMY_FUNC(unsigned char, 8) // color_8_to_kcmy_raw
803 RAW_COLOR_TO_KCMY_FUNC(unsigned short, 16) // color_16_to_kcmy_raw
804 GENERIC_COLOR_FUNC(color, kcmy_raw)
805
806 /*
807 * 'gray_to_rgb()' - Convert gray image data to RGB.
808 */
809
810 #define GRAY_TO_COLOR_FUNC(T, bits) \
811 CFUNC \
812 gray_##bits##_to_color(const stp_vars_t *vars, const unsigned char *in, \
813 unsigned short *out) \
814 { \
815 int i; \
816 int i0 = -1; \
817 int o0 = 0; \
818 int o1 = 0; \
819 int o2 = 0; \
820 int nz0 = 0; \
821 int nz1 = 0; \
822 int nz2 = 0; \
823 const T *s_in = (const T *) in; \
824 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
825 const unsigned short *red; \
826 const unsigned short *green; \
827 const unsigned short *blue; \
828 const unsigned short *user; \
829 \
830 for (i = CHANNEL_C; i <= CHANNEL_Y; i++) \
831 stp_curve_resample(lut->channel_curves[i].curve, 65536); \
832 stp_curve_resample \
833 (stp_curve_cache_get_curve(&(lut->user_color_correction)), 1 << bits); \
834 red = \
835 stp_curve_cache_get_ushort_data(&(lut->channel_curves[CHANNEL_C])); \
836 green = \
837 stp_curve_cache_get_ushort_data(&(lut->channel_curves[CHANNEL_M])); \
838 blue = \
839 stp_curve_cache_get_ushort_data(&(lut->channel_curves[CHANNEL_Y])); \
840 user = \
841 stp_curve_cache_get_ushort_data(&(lut->user_color_correction)); \
842 \
843 for (i = 0; i < lut->image_width; i++) \
844 { \
845 if (i0 == s_in[0]) \
846 { \
847 out[0] = o0; \
848 out[1] = o1; \
849 out[2] = o2; \
850 } \
851 else \
852 { \
853 i0 = s_in[0]; \
854 out[0] = red[user[s_in[0]]]; \
855 out[1] = green[user[s_in[0]]]; \
856 out[2] = blue[user[s_in[0]]]; \
857 o0 = out[0]; \
858 o1 = out[1]; \
859 o2 = out[2]; \
860 nz0 |= o0; \
861 nz1 |= o1; \
862 nz2 |= o2; \
863 } \
864 s_in += 1; \
865 out += 3; \
866 } \
867 return (nz0 ? 0 : 1) + (nz1 ? 0 : 2) + (nz2 ? 0 : 4); \
868 }
869
870 GRAY_TO_COLOR_FUNC(unsigned char, 8) // gray_8_to_color
871 GRAY_TO_COLOR_FUNC(unsigned short, 16) // gray_16_to_color
872 GENERIC_COLOR_FUNC(gray, color)
873
874 #define GRAY_TO_KCMY_FUNC(T, bits) \
875 CFUNC \
876 gray_##bits##_to_kcmy(const stp_vars_t *vars, const unsigned char *in, \
877 unsigned short *out) \
878 { \
879 int i; \
880 union { \
881 unsigned short nz[4]; \
882 unsigned long long nzl; \
883 } nzx; \
884 unsigned retval = 0; \
885 const T *s_in = (const T *) in; \
886 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
887 const unsigned short *red; \
888 const unsigned short *green; \
889 const unsigned short *blue; \
890 const unsigned short *user; \
891 \
892 for (i = CHANNEL_C; i <= CHANNEL_Y; i++) \
893 stp_curve_resample(lut->channel_curves[i].curve, 65536); \
894 stp_curve_resample \
895 (stp_curve_cache_get_curve(&(lut->user_color_correction)), 1 << bits); \
896 red = \
897 stp_curve_cache_get_ushort_data(&(lut->channel_curves[CHANNEL_C])); \
898 green = \
899 stp_curve_cache_get_ushort_data(&(lut->channel_curves[CHANNEL_M])); \
900 blue = \
901 stp_curve_cache_get_ushort_data(&(lut->channel_curves[CHANNEL_Y])); \
902 user = \
903 stp_curve_cache_get_ushort_data(&(lut->user_color_correction)); \
904 \
905 for (i = 0; i < lut->image_width; i++, out += 4, s_in++) \
906 { \
907 out[1] = red[user[s_in[0]]]; \
908 out[2] = green[user[s_in[0]]]; \
909 out[3] = blue[user[s_in[0]]]; \
910 out[0] = FMIN(out[1], FMIN(out[2], out[3])); \
911 out[1] -= out[0]; \
912 out[2] -= out[0]; \
913 out[3] -= out[0]; \
914 nzx.nzl |= *(unsigned long long *) out; \
915 } \
916 for (i = 0; i < 4; i++) \
917 if (nzx.nz[i] == 0) \
918 retval |= (1 << i); \
919 return retval; \
920 }
921
922 GRAY_TO_KCMY_FUNC(unsigned char, 8) // gray_8_to_kcmy
923 GRAY_TO_KCMY_FUNC(unsigned short, 16) // gray_16_to_kcmy
924 GENERIC_COLOR_FUNC(gray, kcmy)
925
926 #define GRAY_TO_COLOR_RAW_FUNC(T, bits) \
927 CFUNC \
928 gray_##bits##_to_color_raw(const stp_vars_t *vars, const unsigned char *in,\
929 unsigned short *out) \
930 { \
931 int i; \
932 int nz = 7; \
933 const T *s_in = (const T *) in; \
934 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
935 unsigned mask = 0; \
936 if (lut->invert_output) \
937 mask = 0xffff; \
938 \
939 for (i = 0; i < lut->image_width; i++) \
940 { \
941 unsigned outval = (s_in[0] * (65535 / (1 << bits))) ^ mask; \
942 out[0] = outval; \
943 out[1] = outval; \
944 out[2] = outval; \
945 if (outval) \
946 nz = 0; \
947 s_in++; \
948 out += 3; \
949 } \
950 return nz; \
951 }
952
953 GRAY_TO_COLOR_RAW_FUNC(unsigned char, 8) // gray_8_to_color_raw
954 GRAY_TO_COLOR_RAW_FUNC(unsigned short, 16) // gray_16_to_color_raw
955 GENERIC_COLOR_FUNC(gray, color_raw)
956
957 #define GRAY_TO_KCMY_RAW_FUNC(T, bits) \
958 CFUNC \
959 gray_##bits##_to_kcmy_raw(const stp_vars_t *vars, const unsigned char *in, \
960 unsigned short *out) \
961 { \
962 int i; \
963 int nz = 7; \
964 const T *s_in = (const T *) in; \
965 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
966 unsigned mask = 0; \
967 if (lut->invert_output) \
968 mask = 0xffff; \
969 \
970 for (i = 0; i < lut->image_width; i++, out += 4, s_in++) \
971 { \
972 unsigned outval = (s_in[0] * (65535 / (1 << bits))) ^ mask; \
973 out[0] = outval; \
974 out[1] = 0; \
975 out[2] = 0; \
976 out[3] = 0; \
977 if (outval) \
978 nz = 0; \
979 } \
980 return nz; \
981 }
982
983 GRAY_TO_KCMY_RAW_FUNC(unsigned char, 8) // gray_8_to_kcmy_raw
984 GRAY_TO_KCMY_RAW_FUNC(unsigned short, 16) // gray_16_to_kcmy_raw
985 GENERIC_COLOR_FUNC(gray, kcmy_raw)
986
987 #define COLOR_TO_KCMY_THRESHOLD_FUNC(T, name) \
988 CFUNC \
989 name##_to_kcmy_threshold(const stp_vars_t *vars, \
990 const unsigned char *in, \
991 unsigned short *out) \
992 { \
993 int i; \
994 int z = 15; \
995 const T *s_in = (const T *) in; \
996 unsigned high_bit = ((1 << ((sizeof(T) * 8) - 1))); \
997 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
998 int width = lut->image_width; \
999 unsigned mask = 0; \
1000 memset(out, 0, width * 4 * sizeof(unsigned short)); \
1001 if (lut->invert_output) \
1002 mask = (1 << (sizeof(T) * 8)) - 1; \
1003 \
1004 for (i = 0; i < width; i++, out += 4, s_in += 3) \
1005 { \
1006 unsigned c = s_in[0] ^ mask; \
1007 unsigned m = s_in[1] ^ mask; \
1008 unsigned y = s_in[2] ^ mask; \
1009 unsigned k = (c < m ? (c < y ? c : y) : (m < y ? m : y)); \
1010 if (k >= high_bit) \
1011 { \
1012 c -= k; \
1013 m -= k; \
1014 y -= k; \
1015 } \
1016 if (k >= high_bit) \
1017 { \
1018 z &= 0xe; \
1019 out[0] = 65535; \
1020 } \
1021 if (c >= high_bit) \
1022 { \
1023 z &= 0xd; \
1024 out[1] = 65535; \
1025 } \
1026 if (m >= high_bit) \
1027 { \
1028 z &= 0xb; \
1029 out[2] = 65535; \
1030 } \
1031 if (y >= high_bit) \
1032 { \
1033 z &= 0x7; \
1034 out[3] = 65535; \
1035 } \
1036 } \
1037 return z; \
1038 }
1039
1040 COLOR_TO_KCMY_THRESHOLD_FUNC(unsigned char, color_8) // color_8_to_kcmy_threshold
1041 COLOR_TO_KCMY_THRESHOLD_FUNC(unsigned short, color_16) // color_16_to_kcmy_threshold
1042 GENERIC_COLOR_FUNC(color, kcmy_threshold)
1043
1044 #define CMYK_TO_KCMY_THRESHOLD_FUNC(T, name) \
1045 CFUNC \
1046 name##_to_kcmy_threshold(const stp_vars_t *vars, \
1047 const unsigned char *in, \
1048 unsigned short *out) \
1049 { \
1050 int i; \
1051 int z = 15; \
1052 const T *s_in = (const T *) in; \
1053 unsigned desired_high_bit = 0; \
1054 unsigned high_bit = 1 << ((sizeof(T) * 8) - 1); \
1055 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
1056 int width = lut->image_width; \
1057 memset(out, 0, width * 4 * sizeof(unsigned short)); \
1058 if (!lut->invert_output) \
1059 desired_high_bit = high_bit; \
1060 \
1061 for (i = 0; i < width; i++, out += 4, s_in += 4) \
1062 { \
1063 if ((s_in[3] & high_bit) == desired_high_bit) \
1064 { \
1065 z &= 0xe; \
1066 out[0] = 65535; \
1067 } \
1068 if ((s_in[0] & high_bit) == desired_high_bit) \
1069 { \
1070 z &= 0xd; \
1071 out[1] = 65535; \
1072 } \
1073 if ((s_in[1] & high_bit) == desired_high_bit) \
1074 { \
1075 z &= 0xb; \
1076 out[2] = 65535; \
1077 } \
1078 if ((s_in[2] & high_bit) == desired_high_bit) \
1079 { \
1080 z &= 0x7; \
1081 out[3] = 65535; \
1082 } \
1083 } \
1084 return z; \
1085 }
1086
1087 CMYK_TO_KCMY_THRESHOLD_FUNC(unsigned char, cmyk_8) // cmyk_8_to_kcmy_threshold
1088 CMYK_TO_KCMY_THRESHOLD_FUNC(unsigned short, cmyk_16) // cmyk_16_to_kcmy_threshodl
1089 GENERIC_COLOR_FUNC(cmyk, kcmy_threshold)
1090
1091 #define KCMY_TO_KCMY_THRESHOLD_FUNC(T, name) \
1092 CFUNC \
1093 name##_to_kcmy_threshold(const stp_vars_t *vars, \
1094 const unsigned char *in, \
1095 unsigned short *out) \
1096 { \
1097 int i; \
1098 int j; \
1099 unsigned nz[4]; \
1100 unsigned z = 0xf; \
1101 const T *s_in = (const T *) in; \
1102 unsigned desired_high_bit = 0; \
1103 unsigned high_bit = 1 << ((sizeof(T) * 8) - 1); \
1104 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
1105 int width = lut->image_width; \
1106 memset(out, 0, width * 4 * sizeof(unsigned short)); \
1107 if (!lut->invert_output) \
1108 desired_high_bit = high_bit; \
1109 for (i = 0; i < 4; i++) \
1110 nz[i] = z & ~(1 << i); \
1111 \
1112 for (i = 0; i < width; i++) \
1113 { \
1114 for (j = 0; j < 4; j++) \
1115 { \
1116 if ((*s_in++ & high_bit) == desired_high_bit) \
1117 { \
1118 z &= nz[j]; \
1119 *out = 65535; \
1120 } \
1121 out++; \
1122 } \
1123 } \
1124 return z; \
1125 }
1126
1127 KCMY_TO_KCMY_THRESHOLD_FUNC(unsigned char, kcmy_8) // kcmy_8_to_kcmy_threshold
1128 KCMY_TO_KCMY_THRESHOLD_FUNC(unsigned short, kcmy_16) // kcmy_8_to_kcmy_threshold
1129 GENERIC_COLOR_FUNC(kcmy, kcmy_threshold)
1130
1131 #define GRAY_TO_COLOR_THRESHOLD_FUNC(T, name, bits, channels) \
1132 CFUNC \
1133 gray_##bits##_to_##name##_threshold(const stp_vars_t *vars, \
1134 const unsigned char *in, \
1135 unsigned short *out) \
1136 { \
1137 int i; \
1138 int z = (1 << channels) - 1; \
1139 int desired_high_bit = 0; \
1140 unsigned high_bit = 1 << ((sizeof(T) * 8) - 1); \
1141 const T *s_in = (const T *) in; \
1142 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
1143 int width = lut->image_width; \
1144 memset(out, 0, width * channels * sizeof(unsigned short)); \
1145 if (!lut->invert_output) \
1146 desired_high_bit = high_bit; \
1147 \
1148 for (i = 0; i < width; i++, out += channels, s_in++) \
1149 { \
1150 if ((s_in[0] & high_bit) == desired_high_bit) \
1151 { \
1152 int j; \
1153 z = 0; \
1154 for (j = 0; j < channels; j++) \
1155 out[j] = 65535; \
1156 } \
1157 } \
1158 return z; \
1159 }
1160
1161
1162 GRAY_TO_COLOR_THRESHOLD_FUNC(unsigned char, color, 8, 3) // gray_8_to_color_threshold
1163 GRAY_TO_COLOR_THRESHOLD_FUNC(unsigned short, color, 16, 3) // gray_16_to_color_threshold
1164 GENERIC_COLOR_FUNC(gray, color_threshold)
1165
1166 GRAY_TO_COLOR_THRESHOLD_FUNC(unsigned char, kcmy, 8, 4) // gray_8_to_kcmy_threshold
1167 GRAY_TO_COLOR_THRESHOLD_FUNC(unsigned short, kcmy, 16, 4) // gray_16_to_kcmy_threshold
1168 GENERIC_COLOR_FUNC(gray, kcmy_threshold)
1169
1170 #define COLOR_TO_COLOR_THRESHOLD_FUNC(T, name) \
1171 CFUNC \
1172 name##_to_color_threshold(const stp_vars_t *vars, \
1173 const unsigned char *in, \
1174 unsigned short *out) \
1175 { \
1176 int i; \
1177 int z = 7; \
1178 int desired_high_bit = 0; \
1179 unsigned high_bit = ((1 << ((sizeof(T) * 8) - 1)) * 4); \
1180 const T *s_in = (const T *) in; \
1181 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
1182 int width = lut->image_width; \
1183 memset(out, 0, width * 3 * sizeof(unsigned short)); \
1184 if (!lut->invert_output) \
1185 desired_high_bit = high_bit; \
1186 \
1187 for (i = 0; i < width; i++, out += 3, s_in += 3) \
1188 { \
1189 if ((s_in[0] & high_bit) == desired_high_bit) \
1190 { \
1191 z &= 6; \
1192 out[0] = 65535; \
1193 } \
1194 if ((s_in[1] & high_bit) == desired_high_bit) \
1195 { \
1196 z &= 5; \
1197 out[1] = 65535; \
1198 } \
1199 if ((s_in[1] & high_bit) == desired_high_bit) \
1200 { \
1201 z &= 3; \
1202 out[2] = 65535; \
1203 } \
1204 } \
1205 return z; \
1206 }
1207
1208 COLOR_TO_COLOR_THRESHOLD_FUNC(unsigned char, color_8) // color_8_to_color_threshold
1209 COLOR_TO_COLOR_THRESHOLD_FUNC(unsigned short, color_16) // color_8_to_color_threshold
1210 GENERIC_COLOR_FUNC(color, color_threshold)
1211
1212 #define COLOR_TO_GRAY_THRESHOLD_FUNC(T, name, channels, max_channels) \
1213 CFUNC \
1214 name##_to_gray_threshold(const stp_vars_t *vars, \
1215 const unsigned char *in, \
1216 unsigned short *out) \
1217 { \
1218 int i; \
1219 int z = 1; \
1220 int desired_high_bit = 0; \
1221 unsigned high_bit = ((1 << ((sizeof(T) * 8) - 1))); \
1222 const T *s_in = (const T *) in; \
1223 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
1224 int width = lut->image_width; \
1225 memset(out, 0, width * sizeof(unsigned short)); \
1226 if (!lut->invert_output) \
1227 desired_high_bit = high_bit; \
1228 \
1229 for (i = 0; i < width; i++, out++, s_in += channels) \
1230 { \
1231 unsigned gval = \
1232 (max_channels - channels) * (1 << ((sizeof(T) * 8) - 1)); \
1233 int j; \
1234 for (j = 0; j < channels; j++) \
1235 gval += s_in[j]; \
1236 gval /= channels; \
1237 if ((gval & high_bit) == desired_high_bit) \
1238 { \
1239 out[0] = 65535; \
1240 z = 0; \
1241 } \
1242 } \
1243 return z; \
1244 }
1245
1246 COLOR_TO_GRAY_THRESHOLD_FUNC(unsigned char, cmyk_8, 4, 4) // cmyk_8_to_gray_threshold
1247 COLOR_TO_GRAY_THRESHOLD_FUNC(unsigned short, cmyk_16, 4, 4) // cmyk_16_to_gray_threshold
1248 GENERIC_COLOR_FUNC(cmyk, gray_threshold)
1249
1250 COLOR_TO_GRAY_THRESHOLD_FUNC(unsigned char, kcmy_8, 4, 4) // kcmy_8_to_gray_threshold
1251 COLOR_TO_GRAY_THRESHOLD_FUNC(unsigned short, kcmy_16, 4, 4) // kcmy_16_to_gray_threshold
1252 GENERIC_COLOR_FUNC(kcmy, gray_threshold)
1253
1254 COLOR_TO_GRAY_THRESHOLD_FUNC(unsigned char, color_8, 3, 3) // color_8_to_gray_threshold
1255 COLOR_TO_GRAY_THRESHOLD_FUNC(unsigned short, color_16, 3, 3) // color_16_to_gray_threshold
1256 GENERIC_COLOR_FUNC(color, gray_threshold)
1257
1258 COLOR_TO_GRAY_THRESHOLD_FUNC(unsigned char, gray_8, 1, 1) // gray_8_to_gray_threshold
1259 COLOR_TO_GRAY_THRESHOLD_FUNC(unsigned short, gray_16, 1, 1) // gray_16_to_gray_threshold
1260 GENERIC_COLOR_FUNC(gray, gray_threshold)
1261
1262 #define CMYK_TO_COLOR_FUNC(namein, name2, T, bits, offset) \
1263 static unsigned \
1264 namein##_##bits##_to_##name2(const stp_vars_t *vars, const unsigned char *in, \
1265 unsigned short *out) \
1266 { \
1267 int i; \
1268 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
1269 unsigned status; \
1270 size_t real_steps = lut->steps; \
1271 const T *s_in = (const T *) in; \
1272 unsigned short *tmp; \
1273 int width = lut->image_width; \
1274 \
1275 if (!lut->cmy_tmp) \
1276 lut->cmy_tmp = stp_malloc(3 * 2 * lut->image_width); \
1277 tmp = lut->cmy_tmp; \
1278 memset(lut->cmy_tmp, 0, width * 3 * sizeof(unsigned short)); \
1279 \
1280 for (i = 0; i < width; i++, tmp += 3, s_in += 4) \
1281 { \
1282 unsigned c = (s_in[0 + offset] + s_in[(3 + offset) % 4]) * \
1283 (65535 / MAXB(bits)); \
1284 unsigned m = (s_in[1 + offset] + s_in[(3 + offset) % 4]) * \
1285 (65535 / MAXB(bits)); \
1286 unsigned y = (s_in[2 + offset] + s_in[(3 + offset) % 4]) * \
1287 (65535 / MAXB(bits)); \
1288 if (c > MAXB(16)) \
1289 c = MAXB(16); \
1290 if (m > MAXB(16)) \
1291 m = MAXB(16); \
1292 if (y > MAXB(16)) \
1293 y = MAXB(16); \
1294 tmp[0] = c; \
1295 tmp[1] = m; \
1296 tmp[2] = y; \
1297 } \
1298 lut->steps = 65536; \
1299 status = \
1300 color_16_to_##name2(vars, (const unsigned char *) lut->cmy_tmp, out); \
1301 lut->steps = real_steps; \
1302 return status; \
1303 }
1304
1305 CMYK_TO_COLOR_FUNC(cmyk, color, unsigned char, 8, 0) // cmyk_8_to_color
1306 CMYK_TO_COLOR_FUNC(cmyk, color, unsigned short, 16, 0) // cmyk_16_to_color
1307 GENERIC_COLOR_FUNC(cmyk, color)
1308 CMYK_TO_COLOR_FUNC(kcmy, color, unsigned char, 8, 1) // kcmy_8_to_color
1309 CMYK_TO_COLOR_FUNC(kcmy, color, unsigned short, 16, 1) // kcmy_16_to_color
1310 GENERIC_COLOR_FUNC(kcmy, color)
1311 CMYK_TO_COLOR_FUNC(cmyk, color_threshold, unsigned char, 8, 0) // cmyk_8_to_color_threshold
1312 CMYK_TO_COLOR_FUNC(cmyk, color_threshold, unsigned short, 16, 0) // cmyk_16_to_color_threshold
1313 GENERIC_COLOR_FUNC(cmyk, color_threshold)
1314 CMYK_TO_COLOR_FUNC(kcmy, color_threshold, unsigned char, 8, 1) // kcmy_8_to_color_threshold
1315 CMYK_TO_COLOR_FUNC(kcmy, color_threshold, unsigned short, 16, 1) // kcmy_16_to_color_threshold
1316 GENERIC_COLOR_FUNC(kcmy, color_threshold)
1317 CMYK_TO_COLOR_FUNC(cmyk, color_fast, unsigned char, 8, 0) // cmyk_8_to_color_fast
1318 CMYK_TO_COLOR_FUNC(cmyk, color_fast, unsigned short, 16, 0) // cmyk_16_to_color_fast
1319 GENERIC_COLOR_FUNC(cmyk, color_fast)
1320 CMYK_TO_COLOR_FUNC(kcmy, color_fast, unsigned char, 8, 1) // kcmy_8_to_color_fast
1321 CMYK_TO_COLOR_FUNC(kcmy, color_fast, unsigned short, 16, 1) // kcmy_16_to_color_fast
1322 GENERIC_COLOR_FUNC(kcmy, color_fast)
1323 CMYK_TO_COLOR_FUNC(cmyk, color_raw, unsigned char, 8, 0) // cmyk_8_to_color_raw
1324 CMYK_TO_COLOR_FUNC(cmyk, color_raw, unsigned short, 16, 0) // cmyk_16_to_color_raw
1325 GENERIC_COLOR_FUNC(cmyk, color_raw)
1326 CMYK_TO_COLOR_FUNC(kcmy, color_raw, unsigned char, 8, 1) // kcmy_8_to_color_raw
1327 CMYK_TO_COLOR_FUNC(kcmy, color_raw, unsigned short, 16, 1) // kcmy_16_to_color_raw
1328 GENERIC_COLOR_FUNC(kcmy, color_raw)
1329
1330 #define CMYK_TO_KCMY_FUNC(T, size) \
1331 CFUNC \
1332 cmyk_##size##_to_kcmy(const stp_vars_t *vars, \
1333 const unsigned char *in, \
1334 unsigned short *out) \
1335 { \
1336 int i; \
1337 unsigned retval = 0; \
1338 int j; \
1339 int nz[4]; \
1340 const T *s_in = (const T *) in; \
1341 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
1342 const unsigned short *user; \
1343 const unsigned short *maps[4]; \
1344 \
1345 for (i = 0; i < 4; i++) \
1346 { \
1347 stp_curve_resample(lut->channel_curves[i].curve, 65536); \
1348 maps[i] = stp_curve_cache_get_ushort_data(&(lut->channel_curves[i])); \
1349 } \
1350 stp_curve_resample(lut->user_color_correction.curve, 1 << size); \
1351 user = stp_curve_cache_get_ushort_data(&(lut->user_color_correction)); \
1352 \
1353 memset(nz, 0, sizeof(nz)); \
1354 \
1355 for (i = 0; i < lut->image_width; i++, out += 4) \
1356 { \
1357 for (j = 0; j < 4; j++) \
1358 { \
1359 int outpos = (j + 1) & 3; \
1360 int inval = *s_in++; \
1361 nz[outpos] |= inval; \
1362 out[outpos] = maps[outpos][user[inval]]; \
1363 } \
1364 } \
1365 for (j = 0; j < 4; j++) \
1366 if (nz[j] == 0) \
1367 retval |= (1 << j); \
1368 return retval; \
1369 }
1370
1371 CMYK_TO_KCMY_FUNC(unsigned char, 8) // cmyk_8_to_kcmy
1372 CMYK_TO_KCMY_FUNC(unsigned short, 16) // cmyk_16_to_kcmy
1373 GENERIC_COLOR_FUNC(cmyk, kcmy)
1374
1375 #define KCMY_TO_KCMY_FUNC(T, size) \
1376 CFUNC \
1377 kcmy_##size##_to_kcmy(const stp_vars_t *vars, \
1378 const unsigned char *in, \
1379 unsigned short *out) \
1380 { \
1381 int i; \
1382 unsigned retval = 0; \
1383 int j; \
1384 int nz[4]; \
1385 const T *s_in = (const T *) in; \
1386 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
1387 const unsigned short *user; \
1388 const unsigned short *maps[4]; \
1389 \
1390 for (i = 0; i < 4; i++) \
1391 { \
1392 stp_curve_resample(lut->channel_curves[i].curve, 65536); \
1393 maps[i] = stp_curve_cache_get_ushort_data(&(lut->channel_curves[i])); \
1394 } \
1395 stp_curve_resample(lut->user_color_correction.curve, 1 << size); \
1396 user = stp_curve_cache_get_ushort_data(&(lut->user_color_correction)); \
1397 \
1398 memset(nz, 0, sizeof(nz)); \
1399 \
1400 for (i = 0; i < lut->image_width; i++, out += 4) \
1401 { \
1402 for (j = 0; j < 4; j++) \
1403 { \
1404 int inval = *s_in++; \
1405 nz[j] |= inval; \
1406 out[j] = maps[j][user[inval]]; \
1407 } \
1408 } \
1409 for (j = 0; j < 4; j++) \
1410 if (nz[j] == 0) \
1411 retval |= (1 << j); \
1412 return retval; \
1413 }
1414
1415 KCMY_TO_KCMY_FUNC(unsigned char, 8) // kcmy_8_to_kcmy
1416 KCMY_TO_KCMY_FUNC(unsigned short, 16) // kcmy_16_to_kcmy
1417 GENERIC_COLOR_FUNC(kcmy, kcmy)
1418
1419
1420 #define GRAY_TO_GRAY_FUNC(T, bits) \
1421 CFUNC \
1422 gray_##bits##_to_gray(const stp_vars_t *vars, \
1423 const unsigned char *in, \
1424 unsigned short *out) \
1425 { \
1426 int i; \
1427 int i0 = -1; \
1428 int o0 = 0; \
1429 int nz = 0; \
1430 const T *s_in = (const T *) in; \
1431 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
1432 int width = lut->image_width; \
1433 const unsigned short *composite; \
1434 const unsigned short *user; \
1435 \
1436 stp_curve_resample \
1437 (stp_curve_cache_get_curve(&(lut->channel_curves[CHANNEL_K])), 65536); \
1438 composite = \
1439 stp_curve_cache_get_ushort_data(&(lut->channel_curves[CHANNEL_K])); \
1440 stp_curve_resample(lut->user_color_correction.curve, 1 << bits); \
1441 user = stp_curve_cache_get_ushort_data(&(lut->user_color_correction)); \
1442 \
1443 memset(out, 0, width * sizeof(unsigned short)); \
1444 \
1445 for (i = 0; i < lut->image_width; i++) \
1446 { \
1447 if (i0 != s_in[0]) \
1448 { \
1449 i0 = s_in[0]; \
1450 o0 = composite[user[i0]]; \
1451 nz |= o0; \
1452 } \
1453 out[0] = o0; \
1454 s_in ++; \
1455 out ++; \
1456 } \
1457 return nz == 0; \
1458 }
1459
1460 GRAY_TO_GRAY_FUNC(unsigned char, 8) // gray_8_to_gray
1461 GRAY_TO_GRAY_FUNC(unsigned short, 16) // gray_16_to_gray
1462 GENERIC_COLOR_FUNC(gray, gray)
1463
1464 #define COLOR_TO_GRAY_FUNC(T, bits) \
1465 CFUNC \
1466 color_##bits##_to_gray(const stp_vars_t *vars, \
1467 const unsigned char *in, \
1468 unsigned short *out) \
1469 { \
1470 int i; \
1471 int i0 = -1; \
1472 int i1 = -1; \
1473 int i2 = -1; \
1474 int o0 = 0; \
1475 int nz = 0; \
1476 const T *s_in = (const T *) in; \
1477 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
1478 int l_red = LUM_RED; \
1479 int l_green = LUM_GREEN; \
1480 int l_blue = LUM_BLUE; \
1481 const unsigned short *composite; \
1482 const unsigned short *user; \
1483 \
1484 stp_curve_resample \
1485 (stp_curve_cache_get_curve(&(lut->channel_curves[CHANNEL_K])), 65536); \
1486 composite = \
1487 stp_curve_cache_get_ushort_data(&(lut->channel_curves[CHANNEL_K])); \
1488 stp_curve_resample(lut->user_color_correction.curve, 1 << bits); \
1489 user = stp_curve_cache_get_ushort_data(&(lut->user_color_correction)); \
1490 \
1491 if (lut->input_color_description->color_model == COLOR_BLACK) \
1492 { \
1493 l_red = (100 - l_red) / 2; \
1494 l_green = (100 - l_green) / 2; \
1495 l_blue = (100 - l_blue) / 2; \
1496 } \
1497 \
1498 for (i = 0; i < lut->image_width; i++) \
1499 { \
1500 if (i0 != s_in[0] || i1 != s_in[1] || i2 != s_in[2]) \
1501 { \
1502 i0 = s_in[0]; \
1503 i1 = s_in[1]; \
1504 i2 = s_in[2]; \
1505 o0 = \
1506 composite[user[(i0 * l_red + i1 * l_green + i2 * l_blue) / 100]]; \
1507 nz |= o0; \
1508 } \
1509 out[0] = o0; \
1510 s_in += 3; \
1511 out ++; \
1512 } \
1513 return nz == 0; \
1514 }
1515
1516 COLOR_TO_GRAY_FUNC(unsigned char, 8) // color_8_to_gray
1517 COLOR_TO_GRAY_FUNC(unsigned short, 16) // color_16_to_gray
1518 GENERIC_COLOR_FUNC(color, gray)
1519
1520
1521 #define CMYK_TO_GRAY_FUNC(T, bits) \
1522 CFUNC \
1523 cmyk_##bits##_to_gray(const stp_vars_t *vars, \
1524 const unsigned char *in, \
1525 unsigned short *out) \
1526 { \
1527 int i; \
1528 int i0 = -1; \
1529 int i1 = -1; \
1530 int i2 = -1; \
1531 int i3 = -4; \
1532 int o0 = 0; \
1533 int nz = 0; \
1534 const T *s_in = (const T *) in; \
1535 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
1536 int l_red = LUM_RED; \
1537 int l_green = LUM_GREEN; \
1538 int l_blue = LUM_BLUE; \
1539 int l_white = 0; \
1540 const unsigned short *composite; \
1541 const unsigned short *user; \
1542 \
1543 stp_curve_resample \
1544 (stp_curve_cache_get_curve(&(lut->channel_curves[CHANNEL_K])), 65536); \
1545 composite = \
1546 stp_curve_cache_get_ushort_data(&(lut->channel_curves[CHANNEL_K])); \
1547 stp_curve_resample(lut->user_color_correction.curve, 1 << bits); \
1548 user = stp_curve_cache_get_ushort_data(&(lut->user_color_correction)); \
1549 \
1550 if (lut->input_color_description->color_model == COLOR_BLACK) \
1551 { \
1552 l_red = (100 - l_red) / 3; \
1553 l_green = (100 - l_green) / 3; \
1554 l_blue = (100 - l_blue) / 3; \
1555 l_white = (100 - l_white) / 3; \
1556 } \
1557 \
1558 for (i = 0; i < lut->image_width; i++) \
1559 { \
1560 if (i0 != s_in[0] || i1 != s_in[1] || i2 != s_in[2] || i3 != s_in[3]) \
1561 { \
1562 i0 = s_in[0]; \
1563 i1 = s_in[1]; \
1564 i2 = s_in[2]; \
1565 i3 = s_in[3]; \
1566 o0 = composite[user[(i0 * l_red + i1 * l_green + \
1567 i2 * l_blue + i3 * l_white) / 100]]; \
1568 nz |= o0; \
1569 } \
1570 out[0] = o0; \
1571 s_in += 4; \
1572 out ++; \
1573 } \
1574 return nz ? 0 : 1; \
1575 }
1576
1577 CMYK_TO_GRAY_FUNC(unsigned char, 8) // cmyk_8_to_gray
1578 CMYK_TO_GRAY_FUNC(unsigned short, 16) // cmyk_16_to_gray
1579 GENERIC_COLOR_FUNC(cmyk, gray)
1580
1581 #define KCMY_TO_GRAY_FUNC(T, bits) \
1582 CFUNC \
1583 kcmy_##bits##_to_gray(const stp_vars_t *vars, \
1584 const unsigned char *in, \
1585 unsigned short *out) \
1586 { \
1587 int i; \
1588 int i0 = -1; \
1589 int i1 = -1; \
1590 int i2 = -1; \
1591 int i3 = -4; \
1592 int o0 = 0; \
1593 int nz = 0; \
1594 const T *s_in = (const T *) in; \
1595 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
1596 int l_red = LUM_RED; \
1597 int l_green = LUM_GREEN; \
1598 int l_blue = LUM_BLUE; \
1599 int l_white = 0; \
1600 const unsigned short *composite; \
1601 const unsigned short *user; \
1602 \
1603 stp_curve_resample \
1604 (stp_curve_cache_get_curve(&(lut->channel_curves[CHANNEL_K])), 65536); \
1605 composite = \
1606 stp_curve_cache_get_ushort_data(&(lut->channel_curves[CHANNEL_K])); \
1607 stp_curve_resample(lut->user_color_correction.curve, 1 << bits); \
1608 user = stp_curve_cache_get_ushort_data(&(lut->user_color_correction)); \
1609 \
1610 if (lut->input_color_description->color_model == COLOR_BLACK) \
1611 { \
1612 l_red = (100 - l_red) / 3; \
1613 l_green = (100 - l_green) / 3; \
1614 l_blue = (100 - l_blue) / 3; \
1615 l_white = (100 - l_white) / 3; \
1616 } \
1617 \
1618 for (i = 0; i < lut->image_width; i++) \
1619 { \
1620 if (i0 != s_in[0] || i1 != s_in[1] || i2 != s_in[2] || i3 != s_in[3]) \
1621 { \
1622 i0 = s_in[0]; \
1623 i1 = s_in[1]; \
1624 i2 = s_in[2]; \
1625 i3 = s_in[3]; \
1626 o0 = composite[user[(i0 * l_red + i1 * l_green + \
1627 i2 * l_blue + i3 * l_white) / 100]]; \
1628 nz |= o0; \
1629 } \
1630 out[0] = o0; \
1631 s_in += 4; \
1632 out ++; \
1633 } \
1634 return nz ? 0 : 1; \
1635 }
1636
1637 KCMY_TO_GRAY_FUNC(unsigned char, 8) // kcmy_8_to_gray
1638 KCMY_TO_GRAY_FUNC(unsigned short, 16) // kcmy_16_to_gray
1639 GENERIC_COLOR_FUNC(kcmy, gray)
1640
1641 #define GRAY_TO_GRAY_RAW_FUNC(T, bits) \
1642 CFUNC \
1643 gray_##bits##_to_gray_raw(const stp_vars_t *vars, \
1644 const unsigned char *in, \
1645 unsigned short *out) \
1646 { \
1647 int i; \
1648 int nz = 0; \
1649 const T *s_in = (const T *) in; \
1650 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
1651 int width = lut->image_width; \
1652 unsigned mask = 0; \
1653 if (lut->invert_output) \
1654 mask = 0xffff; \
1655 \
1656 memset(out, 0, width * sizeof(unsigned short)); \
1657 \
1658 for (i = 0; i < lut->image_width; i++) \
1659 { \
1660 out[0] = (s_in[0] * (65535 / ((1 << bits) - 1))) ^ mask; \
1661 nz |= out[0]; \
1662 s_in ++; \
1663 out ++; \
1664 } \
1665 return nz == 0; \
1666 }
1667
1668 GRAY_TO_GRAY_RAW_FUNC(unsigned char, 8) // gray_8_to_gray_raw
1669 GRAY_TO_GRAY_RAW_FUNC(unsigned short, 16) // gray_16_to_gray_raw
1670 GENERIC_COLOR_FUNC(gray, gray_raw)
1671
1672 #define COLOR_TO_GRAY_RAW_FUNC(T, bits, invertable, name2) \
1673 CFUNC \
1674 color_##bits##_to_gray_##name2(const stp_vars_t *vars, \
1675 const unsigned char *in, \
1676 unsigned short *out) \
1677 { \
1678 int i; \
1679 int i0 = -1; \
1680 int i1 = -1; \
1681 int i2 = -1; \
1682 int o0 = 0; \
1683 int nz = 0; \
1684 const T *s_in = (const T *) in; \
1685 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
1686 int l_red = LUM_RED; \
1687 int l_green = LUM_GREEN; \
1688 int l_blue = LUM_BLUE; \
1689 unsigned mask = 0; \
1690 if (lut->invert_output && invertable) \
1691 mask = 0xffff; \
1692 \
1693 if (lut->input_color_description->color_model == COLOR_BLACK) \
1694 { \
1695 l_red = (100 - l_red) / 2; \
1696 l_green = (100 - l_green) / 2; \
1697 l_blue = (100 - l_blue) / 2; \
1698 } \
1699 \
1700 for (i = 0; i < lut->image_width; i++) \
1701 { \
1702 if (i0 != s_in[0] || i1 != s_in[1] || i2 != s_in[2]) \
1703 { \
1704 i0 = s_in[0]; \
1705 i1 = s_in[1]; \
1706 i2 = s_in[2]; \
1707 o0 = (i0 * (65535 / ((1 << bits) - 1)) * l_red + \
1708 i1 * (65535 / ((1 << bits) - 1)) * l_green + \
1709 i2 * (65535 / ((1 << bits) - 1)) * l_blue) / 100; \
1710 o0 ^= mask; \
1711 nz |= o0; \
1712 } \
1713 out[0] = o0; \
1714 s_in += 3; \
1715 out ++; \
1716 } \
1717 return nz == 0; \
1718 }
1719
1720 COLOR_TO_GRAY_RAW_FUNC(unsigned char, 8, 1, raw) // color_8_to_gray_raw
1721 COLOR_TO_GRAY_RAW_FUNC(unsigned short, 16, 1, raw) // color_16_to_gray_raw
1722 GENERIC_COLOR_FUNC(color, gray_raw)
1723 COLOR_TO_GRAY_RAW_FUNC(unsigned char, 8, 0, noninvert) // color_8_to_gray_noninvert
1724 COLOR_TO_GRAY_RAW_FUNC(unsigned short, 16, 0, noninvert) // color_16_to_gray_noninvert
1725 // GENERIC_COLOR_FUNC(color, gray_noninvert)
1726
1727
1728 #define CMYK_TO_GRAY_RAW_FUNC(T, bits, invertable, name2) \
1729 CFUNC \
1730 cmyk_##bits##_to_gray_##name2(const stp_vars_t *vars, \
1731 const unsigned char *in, \
1732 unsigned short *out) \
1733 { \
1734 int i; \
1735 int i0 = -1; \
1736 int i1 = -1; \
1737 int i2 = -1; \
1738 int i3 = -4; \
1739 int o0 = 0; \
1740 int nz = 0; \
1741 const T *s_in = (const T *) in; \
1742 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
1743 int l_red = LUM_RED; \
1744 int l_green = LUM_GREEN; \
1745 int l_blue = LUM_BLUE; \
1746 int l_white = 0; \
1747 unsigned mask = 0; \
1748 if (lut->invert_output && invertable) \
1749 mask = 0xffff; \
1750 \
1751 if (lut->input_color_description->color_model == COLOR_BLACK) \
1752 { \
1753 l_red = (100 - l_red) / 3; \
1754 l_green = (100 - l_green) / 3; \
1755 l_blue = (100 - l_blue) / 3; \
1756 l_white = (100 - l_white) / 3; \
1757 } \
1758 \
1759 for (i = 0; i < lut->image_width; i++) \
1760 { \
1761 if (i0 != s_in[0] || i1 != s_in[1] || i2 != s_in[2] || i3 != s_in[3]) \
1762 { \
1763 i0 = s_in[0]; \
1764 i1 = s_in[1]; \
1765 i2 = s_in[2]; \
1766 i3 = s_in[3]; \
1767 o0 = (i0 * (65535 / ((1 << bits) - 1)) * l_red + \
1768 i1 * (65535 / ((1 << bits) - 1)) * l_green + \
1769 i2 * (65535 / ((1 << bits) - 1)) * l_blue + \
1770 i3 * (65535 / ((1 << bits) - 1)) * l_white) / 100; \
1771 o0 ^= mask; \
1772 nz |= o0; \
1773 } \
1774 out[0] = o0; \
1775 s_in += 4; \
1776 out ++; \
1777 } \
1778 return nz ? 0 : 1; \
1779 }
1780
1781 CMYK_TO_GRAY_RAW_FUNC(unsigned char, 8, 1, raw) // cmyk_8_to_gray_raw
1782 CMYK_TO_GRAY_RAW_FUNC(unsigned short, 16, 1, raw) // cmyk_16_to_gray_raw
1783 GENERIC_COLOR_FUNC(cmyk, gray_raw)
1784 CMYK_TO_GRAY_RAW_FUNC(unsigned char, 8, 0, noninvert) // cmyk_8_to_gray_noninvert
1785 CMYK_TO_GRAY_RAW_FUNC(unsigned short, 16, 0, noninvert) // cmyk_16_to_gray_noninvert
1786 // GENERIC_COLOR_FUNC(cmyk, gray_noninvert)
1787
1788 #define KCMY_TO_GRAY_RAW_FUNC(T, bits, invertable, name2) \
1789 CFUNC \
1790 kcmy_##bits##_to_gray_##name2(const stp_vars_t *vars, \
1791 const unsigned char *in, \
1792 unsigned short *out) \
1793 { \
1794 int i; \
1795 int i0 = -1; \
1796 int i1 = -1; \
1797 int i2 = -1; \
1798 int i3 = -4; \
1799 int o0 = 0; \
1800 int nz = 0; \
1801 const T *s_in = (const T *) in; \
1802 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
1803 int l_red = LUM_RED; \
1804 int l_green = LUM_GREEN; \
1805 int l_blue = LUM_BLUE; \
1806 int l_white = 0; \
1807 unsigned mask = 0; \
1808 if (lut->invert_output && invertable) \
1809 mask = 0xffff; \
1810 \
1811 if (lut->input_color_description->color_model == COLOR_BLACK) \
1812 { \
1813 l_red = (100 - l_red) / 3; \
1814 l_green = (100 - l_green) / 3; \
1815 l_blue = (100 - l_blue) / 3; \
1816 l_white = (100 - l_white) / 3; \
1817 } \
1818 \
1819 for (i = 0; i < lut->image_width; i++) \
1820 { \
1821 if (i0 != s_in[0] || i1 != s_in[1] || i2 != s_in[2] || i3 != s_in[3]) \
1822 { \
1823 i0 = s_in[0]; \
1824 i1 = s_in[1]; \
1825 i2 = s_in[2]; \
1826 i3 = s_in[3]; \
1827 o0 = (i0 * (65535 / ((1 << bits) - 1)) * l_white + \
1828 i1 * (65535 / ((1 << bits) - 1)) * l_red + \
1829 i2 * (65535 / ((1 << bits) - 1)) * l_green + \
1830 i3 * (65535 / ((1 << bits) - 1)) * l_blue) / 100; \
1831 o0 ^= mask; \
1832 nz |= o0; \
1833 } \
1834 out[0] = o0; \
1835 s_in += 4; \
1836 out ++; \
1837 } \
1838 return nz ? 0 : 1; \
1839 }
1840
1841 KCMY_TO_GRAY_RAW_FUNC(unsigned char, 8, 1, raw) // kcmy_8_to_gray_raw
1842 KCMY_TO_GRAY_RAW_FUNC(unsigned short, 16, 1, raw) // kcmy_16_to_gray_raw
1843 GENERIC_COLOR_FUNC(kcmy, gray_raw)
1844 KCMY_TO_GRAY_RAW_FUNC(unsigned char, 8, 0, noninvert) // kcmy_8_to_gray_noninvert
1845 KCMY_TO_GRAY_RAW_FUNC(unsigned short, 16, 0, noninvert) // kcmy_16_to_gray_noninvert
1846 // GENERIC_COLOR_FUNC(kcmy, gray_noninvert)
1847
1848 #define CMYK_TO_KCMY_RAW_FUNC(T, bits) \
1849 CFUNC \
1850 cmyk_##bits##_to_kcmy_raw(const stp_vars_t *vars, \
1851 const unsigned char *in, \
1852 unsigned short *out) \
1853 { \
1854 int i; \
1855 int j; \
1856 int nz[4]; \
1857 unsigned retval = 0; \
1858 const T *s_in = (const T *) in; \
1859 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
1860 \
1861 memset(nz, 0, sizeof(nz)); \
1862 for (i = 0; i < lut->image_width; i++) \
1863 { \
1864 out[0] = s_in[3] * (65535 / ((1 << bits) - 1)); \
1865 out[1] = s_in[0] * (65535 / ((1 << bits) - 1)); \
1866 out[2] = s_in[1] * (65535 / ((1 << bits) - 1)); \
1867 out[3] = s_in[2] * (65535 / ((1 << bits) - 1)); \
1868 for (j = 0; j < 4; j++) \
1869 nz[j] |= out[j]; \
1870 s_in += 4; \
1871 out += 4; \
1872 } \
1873 for (j = 0; j < 4; j++) \
1874 if (nz[j] == 0) \
1875 retval |= (1 << j); \
1876 return retval; \
1877 }
1878
1879 CMYK_TO_KCMY_RAW_FUNC(unsigned char, 8) // cmyk_8_to_kcmy_raw
1880 CMYK_TO_KCMY_RAW_FUNC(unsigned short, 16) // cmyk_16_to_kcmy_raw
1881 GENERIC_COLOR_FUNC(cmyk, kcmy_raw)
1882
1883 #define KCMY_TO_KCMY_RAW_FUNC(T, bits) \
1884 CFUNC \
1885 kcmy_##bits##_to_kcmy_raw(const stp_vars_t *vars, \
1886 const unsigned char *in, \
1887 unsigned short *out) \
1888 { \
1889 int i; \
1890 int j; \
1891 int nz[4]; \
1892 unsigned retval = 0; \
1893 const T *s_in = (const T *) in; \
1894 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
1895 \
1896 memset(nz, 0, sizeof(nz)); \
1897 for (i = 0; i < lut->image_width; i++) \
1898 { \
1899 for (j = 0; j < 4; j++) \
1900 { \
1901 out[j] = s_in[j] * (65535 / ((1 << bits) - 1)); \
1902 nz[j] |= out[j]; \
1903 } \
1904 s_in += 4; \
1905 out += 4; \
1906 } \
1907 for (j = 0; j < 4; j++) \
1908 if (nz[j] == 0) \
1909 retval |= (1 << j); \
1910 return retval; \
1911 }
1912
1913 KCMY_TO_KCMY_RAW_FUNC(unsigned char, 8) // kcmy_8_to_kcmy_raw
1914 KCMY_TO_KCMY_RAW_FUNC(unsigned short, 16) // kcmy_16_to_kcmy_raw
1915 GENERIC_COLOR_FUNC(kcmy, kcmy_raw)
1916
1917 #define DESATURATED_FUNC(name, name2, bits) \
1918 CFUNC \
1919 name##_##bits##_to_##name2##_desaturated(const stp_vars_t *vars, \
1920 const unsigned char *in, \
1921 unsigned short *out) \
1922 { \
1923 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
1924 size_t real_steps = lut->steps; \
1925 unsigned status; \
1926 if (!lut->gray_tmp) \
1927 lut->gray_tmp = stp_malloc(2 * lut->image_width); \
1928 name##_##bits##_to_gray_noninvert(vars, in, lut->gray_tmp); \
1929 lut->steps = 65536; \
1930 status = gray_16_to_##name2(vars, (unsigned char *) lut->gray_tmp, out); \
1931 lut->steps = real_steps; \
1932 return status; \
1933 }
1934
1935 DESATURATED_FUNC(color, color, 8) // color_8_to_color_desaturated
1936 DESATURATED_FUNC(color, color, 16) // color_16_to_color_desaturated
1937 GENERIC_COLOR_FUNC(color, color_desaturated)
1938 DESATURATED_FUNC(color, kcmy, 8) // color_8_to_kcmy_desaturated
1939 DESATURATED_FUNC(color, kcmy, 16) // color_8_to_kcmy_desaturated
1940 GENERIC_COLOR_FUNC(color, kcmy_desaturated)
1941
1942 DESATURATED_FUNC(cmyk, color, 8) // cmyk_8_to_color_desaturated
1943 DESATURATED_FUNC(cmyk, color, 16) // cmyk_16_to_color_desaturated
1944 GENERIC_COLOR_FUNC(cmyk, color_desaturated)
1945 DESATURATED_FUNC(cmyk, kcmy, 8) // cmyk_8_to_kcmy_desaturated
1946 DESATURATED_FUNC(cmyk, kcmy, 16) // cmyk_16_to_kcmy_desaturated
1947 GENERIC_COLOR_FUNC(cmyk, kcmy_desaturated)
1948
1949 DESATURATED_FUNC(kcmy, color, 8) // kcmy_8_to_color_desaturated
1950 DESATURATED_FUNC(kcmy, color, 16) // kcmy_16_to_kcmy_desaturated
1951 GENERIC_COLOR_FUNC(kcmy, color_desaturated)
1952 DESATURATED_FUNC(kcmy, kcmy, 8) // kcmy_8_to_color_desaturated
1953 DESATURATED_FUNC(kcmy, kcmy, 16) // kcmy_16_to_kcmy_desaturated
1954 GENERIC_COLOR_FUNC(kcmy, kcmy_desaturated)
1955
1956 #define CMYK_DISPATCH(name) \
1957 CFUNC \
1958 CMYK_to_##name(const stp_vars_t *vars, const unsigned char *in, \
1959 unsigned short *out) \
1960 { \
1961 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
1962 if (lut->input_color_description->color_id == COLOR_ID_CMYK) \
1963 return cmyk_to_##name(vars, in, out); \
1964 else if (lut->input_color_description->color_id == COLOR_ID_KCMY) \
1965 return kcmy_to_##name(vars, in, out); \
1966 else \
1967 { \
1968 stp_eprintf(vars, "Bad dispatch to CMYK_to_%s: %d\n", #name, \
1969 lut->input_color_description->color_id); \
1970 return 0; \
1971 } \
1972 }
1973
1974 CMYK_DISPATCH(color) /* CMYK_to_color */
1975 CMYK_DISPATCH(color_raw) /* CMYK_to_color_raw */
1976 CMYK_DISPATCH(color_fast) /* CMYK_to_color_fast */
1977 CMYK_DISPATCH(color_threshold) /* CMYK_to_color_threshold */
1978 CMYK_DISPATCH(color_desaturated) /* CMYK_to_color_desaturated */
1979 CMYK_DISPATCH(kcmy) /* CMYK_to_kcmy */
1980 CMYK_DISPATCH(kcmy_raw) /* CMYK_to_kcmy_raw */
1981 CMYK_DISPATCH(kcmy_threshold) /* CMYK_to_kcmy_threshold */
1982 CMYK_DISPATCH(kcmy_desaturated) /* CMYK_to_kcmy_desaturated */
1983 CMYK_DISPATCH(gray) /* CMYK_to_gray */
1984 CMYK_DISPATCH(gray_raw) /* CMYK_to_gray_raw */
1985 CMYK_DISPATCH(gray_threshold) /* CMYK_to_gray_threshold */
1986
1987 #define RAW_TO_RAW_THRESHOLD_FUNC(T, name) \
1988 CFUNC \
1989 name##_to_raw_threshold(const stp_vars_t *vars, \
1990 const unsigned char *in, \
1991 unsigned short *out) \
1992 { \
1993 int i; \
1994 int j; \
1995 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
1996 unsigned nz[STP_CHANNEL_LIMIT]; \
1997 unsigned z = (1 << lut->out_channels) - 1; \
1998 const T *s_in = (const T *) in; \
1999 unsigned desired_high_bit = 0; \
2000 unsigned high_bit = 1 << ((sizeof(T) * 8) - 1); \
2001 int width = lut->image_width; \
2002 memset(out, 0, width * lut->out_channels * sizeof(unsigned short)); \
2003 if (!lut->invert_output) \
2004 desired_high_bit = high_bit; \
2005 for (i = 0; i < lut->out_channels; i++) \
2006 nz[i] = z & ~(1 << i); \
2007 \
2008 for (i = 0; i < width; i++) \
2009 { \
2010 for (j = 0; j < lut->out_channels; j++) \
2011 { \
2012 if ((*s_in++ & high_bit) == desired_high_bit) \
2013 { \
2014 z &= nz[j]; \
2015 *out = 65535; \
2016 } \
2017 out++; \
2018 } \
2019 } \
2020 return z; \
2021 }
2022
2023 RAW_TO_RAW_THRESHOLD_FUNC(unsigned char, raw_8) // raw_8_to_raw_threshold
2024 RAW_TO_RAW_THRESHOLD_FUNC(unsigned short, raw_16) // raw_16_to_raw_threshold
2025 GENERIC_COLOR_FUNC(raw, raw_threshold)
2026
2027 #define RAW_TO_RAW_FUNC(T, size) \
2028 CFUNC \
2029 raw_##size##_to_raw(const stp_vars_t *vars, \
2030 const unsigned char *in, \
2031 unsigned short *out) \
2032 { \
2033 int i; \
2034 unsigned retval = 0; \
2035 int j; \
2036 int nz[STP_CHANNEL_LIMIT]; \
2037 const T *s_in = (const T *) in; \
2038 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
2039 const unsigned short *maps[STP_CHANNEL_LIMIT]; \
2040 const unsigned short *user; \
2041 \
2042 for (i = 0; i < lut->out_channels; i++) \
2043 { \
2044 stp_curve_resample(lut->channel_curves[i].curve, 65536); \
2045 maps[i] = stp_curve_cache_get_ushort_data(&(lut->channel_curves[i])); \
2046 } \
2047 stp_curve_resample(lut->user_color_correction.curve, 1 << size); \
2048 user = stp_curve_cache_get_ushort_data(&(lut->user_color_correction)); \
2049 \
2050 memset(nz, 0, sizeof(nz)); \
2051 \
2052 for (i = 0; i < lut->image_width; i++, out += lut->out_channels) \
2053 { \
2054 for (j = 0; j < lut->out_channels; j++) \
2055 { \
2056 int inval = *s_in++; \
2057 nz[j] |= inval; \
2058 out[j] = maps[j][user[inval]]; \
2059 } \
2060 } \
2061 for (j = 0; j < lut->out_channels; j++) \
2062 if (nz[j] == 0) \
2063 retval |= (1 << j); \
2064 return retval; \
2065 }
2066
2067 RAW_TO_RAW_FUNC(unsigned char, 8) // raw_8_to_raw
2068 RAW_TO_RAW_FUNC(unsigned short, 16) // raw_8_to_raw
2069 GENERIC_COLOR_FUNC(raw, raw)
2070
2071
2072 #define RAW_TO_RAW_RAW_FUNC(T, bits) \
2073 CFUNC \
2074 raw_##bits##_to_raw_raw(const stp_vars_t *vars, \
2075 const unsigned char *in, \
2076 unsigned short *out) \
2077 { \
2078 int i; \
2079 int j; \
2080 int nz[STP_CHANNEL_LIMIT]; \
2081 unsigned retval = 0; \
2082 const T *s_in = (const T *) in; \
2083 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
2084 int colors = lut->in_channels; \
2085 \
2086 memset(nz, 0, sizeof(nz)); \
2087 for (i = 0; i < lut->image_width; i++) \
2088 { \
2089 for (j = 0; j < colors; j++) \
2090 { \
2091 nz[j] |= s_in[j]; \
2092 out[j] = s_in[j] * (65535 / ((1 << bits) - 1)); \
2093 } \
2094 s_in += colors; \
2095 out += colors; \
2096 } \
2097 for (j = 0; j < colors; j++) \
2098 if (nz[j] == 0) \
2099 retval |= (1 << j); \
2100 return retval; \
2101 }
2102
2103 RAW_TO_RAW_RAW_FUNC(unsigned char, 8) // raw_8_to_raw_raw
2104 RAW_TO_RAW_RAW_FUNC(unsigned short, 16) // raw_16_to_raw_raw
2105 GENERIC_COLOR_FUNC(raw, raw_raw)
2106
2107
2108 #define CONVERSION_FUNCTION_WITH_FAST(from, to, from2) \
2109 CFUNC \
2110 generic_##from##_to_##to(const stp_vars_t *v, \
2111 const unsigned char *in, \
2112 unsigned short *out) \
2113 { \
2114 lut_t *lut = (lut_t *)(stp_get_component_data(v, "Color")); \
2115 switch (lut->color_correction->correction) \
2116 { \
2117 case COLOR_CORRECTION_UNCORRECTED: \
2118 stp_dprintf(STP_DBG_COLORFUNC, v, \
2119 "Colorfunc: %s_to_%s_fast\n", #from2, #to); \
2120 return from2##_to_##to##_fast(v, in, out); \
2121 case COLOR_CORRECTION_ACCURATE: \
2122 case COLOR_CORRECTION_BRIGHT: \
2123 case COLOR_CORRECTION_HUE: \
2124 stp_dprintf(STP_DBG_COLORFUNC, v, \
2125 "Colorfunc: %s_to_%s\n", #from2, #to); \
2126 return from2##_to_##to(v, in, out); \
2127 case COLOR_CORRECTION_DESATURATED: \
2128 stp_dprintf(STP_DBG_COLORFUNC, v, \
2129 "Colorfunc: %s_to_%s_desaturated\n", #from2, #to); \
2130 return from2##_to_##to##_desaturated(v, in, out); \
2131 case COLOR_CORRECTION_THRESHOLD: \
2132 case COLOR_CORRECTION_PREDITHERED: \
2133 stp_dprintf(STP_DBG_COLORFUNC, v, \
2134 "Colorfunc: %s_to_%s_threshold\n", #from2, #to); \
2135 return from2##_to_##to##_threshold(v, in, out); \
2136 case COLOR_CORRECTION_DENSITY: \
2137 case COLOR_CORRECTION_RAW: \
2138 stp_dprintf(STP_DBG_COLORFUNC, v, \
2139 "Colorfunc: %s_to_%s_raw\n", #from2, #to); \
2140 return from2##_to_##to##_raw(v, in, out); \
2141 default: \
2142 return (unsigned) -1; \
2143 } \
2144 }
2145
2146 #define CONVERSION_FUNCTION_WITHOUT_FAST(from, to, from2) \
2147 CFUNC \
2148 generic_##from##_to_##to(const stp_vars_t *v, \
2149 const unsigned char *in, \
2150 unsigned short *out) \
2151 { \
2152 lut_t *lut = (lut_t *)(stp_get_component_data(v, "Color")); \
2153 switch (lut->color_correction->correction) \
2154 { \
2155 case COLOR_CORRECTION_UNCORRECTED: \
2156 case COLOR_CORRECTION_ACCURATE: \
2157 case COLOR_CORRECTION_BRIGHT: \
2158 case COLOR_CORRECTION_HUE: \
2159 stp_dprintf(STP_DBG_COLORFUNC, v, \
2160 "Colorfunc: %s_to_%s\n", #from2, #to); \
2161 return from2##_to_##to(v, in, out); \
2162 case COLOR_CORRECTION_DESATURATED: \
2163 stp_dprintf(STP_DBG_COLORFUNC, v, \
2164 "Colorfunc: %s_to_%s_desaturated\n", #from2, #to); \
2165 return from2##_to_##to##_desaturated(v, in, out); \
2166 case COLOR_CORRECTION_THRESHOLD: \
2167 case COLOR_CORRECTION_PREDITHERED: \
2168 stp_dprintf(STP_DBG_COLORFUNC, v, \
2169 "Colorfunc: %s_to_%s_threshold\n", #from2, #to); \
2170 return from2##_to_##to##_threshold(v, in, out); \
2171 case COLOR_CORRECTION_DENSITY: \
2172 case COLOR_CORRECTION_RAW: \
2173 stp_dprintf(STP_DBG_COLORFUNC, v, \
2174 "Colorfunc: %s_to_%s_raw\n", #from2, #to); \
2175 return from2##_to_##to##_raw(v, in, out); \
2176 default: \
2177 return (unsigned) -1; \
2178 } \
2179 }
2180
2181 #define CONVERSION_FUNCTION_WITHOUT_DESATURATED(from, to, from2) \
2182 CFUNC \
2183 generic_##from##_to_##to(const stp_vars_t *v, \
2184 const unsigned char *in, \
2185 unsigned short *out) \
2186 { \
2187 lut_t *lut = (lut_t *)(stp_get_component_data(v, "Color")); \
2188 switch (lut->color_correction->correction) \
2189 { \
2190 case COLOR_CORRECTION_UNCORRECTED: \
2191 case COLOR_CORRECTION_ACCURATE: \
2192 case COLOR_CORRECTION_BRIGHT: \
2193 case COLOR_CORRECTION_HUE: \
2194 case COLOR_CORRECTION_DESATURATED: \
2195 stp_dprintf(STP_DBG_COLORFUNC, v, \
2196 "Colorfunc: %s_to_%s\n", #from2, #to); \
2197 return from2##_to_##to(v, in, out); \
2198 case COLOR_CORRECTION_THRESHOLD: \
2199 case COLOR_CORRECTION_PREDITHERED: \
2200 stp_dprintf(STP_DBG_COLORFUNC, v, \
2201 "Colorfunc: %s_to_%s_threshold\n", #from2, #to); \
2202 return from2##_to_##to##_threshold(v, in, out); \
2203 case COLOR_CORRECTION_DENSITY: \
2204 case COLOR_CORRECTION_RAW: \
2205 stp_dprintf(STP_DBG_COLORFUNC, v, \
2206 "Colorfunc: %s_to_%s_raw\n", #from2, #to); \
2207 return from2##_to_##to##_raw(v, in, out); \
2208 default: \
2209 return (unsigned) -1; \
2210 } \
2211 }
2212
2213 CONVERSION_FUNCTION_WITH_FAST(cmyk, color, CMYK) // generic_cmyk_to_color
2214 CONVERSION_FUNCTION_WITH_FAST(color, color, color) // generic_color_to_color
2215 CONVERSION_FUNCTION_WITH_FAST(color, kcmy, color) // generic_color_to_kcmy
2216 CONVERSION_FUNCTION_WITHOUT_FAST(cmyk, kcmy, CMYK) // generic_cmyk_to_kcmy
2217 CONVERSION_FUNCTION_WITHOUT_DESATURATED(cmyk, gray, CMYK) // generic_cmyk_to_gray
2218 CONVERSION_FUNCTION_WITHOUT_DESATURATED(color, gray, color) // generic_color_to_gray
2219 CONVERSION_FUNCTION_WITHOUT_DESATURATED(gray, gray, gray) // generic_gray_to_gray
2220 CONVERSION_FUNCTION_WITHOUT_DESATURATED(gray, color, gray) // generic_gray_to_color
2221 CONVERSION_FUNCTION_WITHOUT_DESATURATED(gray, kcmy, gray) // generic_gray_to_kcmy
2222
2223 unsigned
2224 stpi_color_convert_to_gray(const stp_vars_t *v,
2225 const unsigned char *in,
2226 unsigned short *out)
2227 {
2228 lut_t *lut = (lut_t *)(stp_get_component_data(v, "Color"));
2229 switch (lut->input_color_description->color_id)
2230 {
2231 case COLOR_ID_GRAY:
2232 case COLOR_ID_WHITE:
2233 return generic_gray_to_gray(v, in, out);
2234 case COLOR_ID_RGB:
2235 case COLOR_ID_CMY:
2236 return generic_color_to_gray(v, in, out);
2237 case COLOR_ID_CMYK:
2238 case COLOR_ID_KCMY:
2239 return generic_cmyk_to_gray(v, in, out);
2240 default:
2241 return (unsigned) -1;
2242 }
2243 }
2244
2245 unsigned
stpi_color_convert_to_color(const stp_vars_t * v,const unsigned char * in,unsigned short * out)2246 stpi_color_convert_to_color(const stp_vars_t *v,
2247 const unsigned char *in,
2248 unsigned short *out)
2249 {
2250 lut_t *lut = (lut_t *)(stp_get_component_data(v, "Color"));
2251 switch (lut->input_color_description->color_id)
2252 {
2253 case COLOR_ID_GRAY:
2254 case COLOR_ID_WHITE:
2255 return generic_gray_to_color(v, in, out);
2256 case COLOR_ID_RGB:
2257 case COLOR_ID_CMY:
2258 return generic_color_to_color(v, in, out);
2259 case COLOR_ID_CMYK:
2260 case COLOR_ID_KCMY:
2261 return generic_cmyk_to_color(v, in, out);
2262 default:
2263 return (unsigned) -1;
2264 }
2265 }
2266
2267 unsigned
stpi_color_convert_to_kcmy(const stp_vars_t * v,const unsigned char * in,unsigned short * out)2268 stpi_color_convert_to_kcmy(const stp_vars_t *v,
2269 const unsigned char *in,
2270 unsigned short *out)
2271 {
2272 lut_t *lut = (lut_t *)(stp_get_component_data(v, "Color"));
2273 switch (lut->input_color_description->color_id)
2274 {
2275 case COLOR_ID_GRAY:
2276 case COLOR_ID_WHITE:
2277 return generic_gray_to_kcmy(v, in, out);
2278 case COLOR_ID_RGB:
2279 case COLOR_ID_CMY:
2280 return generic_color_to_kcmy(v, in, out);
2281 case COLOR_ID_CMYK:
2282 case COLOR_ID_KCMY:
2283 return generic_cmyk_to_kcmy(v, in, out);
2284 default:
2285 return (unsigned) -1;
2286 }
2287 }
2288
2289 unsigned
stpi_color_convert_raw(const stp_vars_t * v,const unsigned char * in,unsigned short * out)2290 stpi_color_convert_raw(const stp_vars_t *v,
2291 const unsigned char *in,
2292 unsigned short *out)
2293 {
2294 lut_t *lut = (lut_t *)(stp_get_component_data(v, "Color"));
2295 switch (lut->color_correction->correction)
2296 {
2297 case COLOR_CORRECTION_THRESHOLD:
2298 case COLOR_CORRECTION_PREDITHERED:
2299 stp_dprintf(STP_DBG_COLORFUNC, v, "Colorfunc: raw_to_raw_threshold\n");
2300 return raw_to_raw_threshold(v, in, out);
2301 case COLOR_CORRECTION_UNCORRECTED:
2302 case COLOR_CORRECTION_BRIGHT:
2303 case COLOR_CORRECTION_HUE:
2304 case COLOR_CORRECTION_ACCURATE:
2305 case COLOR_CORRECTION_DESATURATED:
2306 stp_dprintf(STP_DBG_COLORFUNC, v, "Colorfunc: raw_to_raw_desaturated\n");
2307 return raw_to_raw(v, in, out);
2308 case COLOR_CORRECTION_RAW:
2309 case COLOR_CORRECTION_DEFAULT:
2310 case COLOR_CORRECTION_DENSITY:
2311 stp_dprintf(STP_DBG_COLORFUNC, v, "Colorfunc: raw_to_raw_raw\n");
2312 return raw_to_raw_raw(v, in, out);
2313 default:
2314 return (unsigned) -1;
2315 }
2316 }
2317