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