00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifdef HAVE_CONFIG_H
00030 #include <config.h>
00031 #endif
00032 #include <gutenprint/gutenprint.h>
00033 #include "gutenprint-internal.h"
00034 #include <gutenprint/gutenprint-intl-internal.h>
00035 #include <gutenprint/curve-cache.h>
00036 #include <math.h>
00037 #ifdef HAVE_LIMITS_H
00038 #include <limits.h>
00039 #endif
00040 #include <string.h>
00041 #include "color-conversion.h"
00042
00043 #ifdef __GNUC__
00044 #define inline __inline__
00045 #endif
00046
00047
00048
00049
00050
00051 #define LUM_RED 31
00052 #define LUM_GREEN 61
00053 #define LUM_BLUE 8
00054
00055
00056
00057 #define FMAX(a, b) ((a) > (b) ? (a) : (b))
00058 #define FMIN(a, b) ((a) < (b) ? (a) : (b))
00059
00060 static inline void
00061 calc_rgb_to_hsl(unsigned short *rgb, double *hue, double *sat,
00062 double *lightness)
00063 {
00064 double red, green, blue;
00065 double h, s, l;
00066 double min, max;
00067 double delta;
00068 int maxval;
00069
00070 red = rgb[0] / 65535.0;
00071 green = rgb[1] / 65535.0;
00072 blue = rgb[2] / 65535.0;
00073
00074 if (red > green)
00075 {
00076 if (red > blue)
00077 {
00078 max = red;
00079 maxval = 0;
00080 }
00081 else
00082 {
00083 max = blue;
00084 maxval = 2;
00085 }
00086 min = FMIN(green, blue);
00087 }
00088 else
00089 {
00090 if (green > blue)
00091 {
00092 max = green;
00093 maxval = 1;
00094 }
00095 else
00096 {
00097 max = blue;
00098 maxval = 2;
00099 }
00100 min = FMIN(red, blue);
00101 }
00102
00103 l = (max + min) / 2.0;
00104 delta = max - min;
00105
00106 if (delta < .000001)
00107 {
00108 s = 0.0;
00109 h = 0.0;
00110 }
00111 else
00112 {
00113 if (l <= .5)
00114 s = delta / (max + min);
00115 else
00116 s = delta / (2 - max - min);
00117
00118 if (maxval == 0)
00119 h = (green - blue) / delta;
00120 else if (maxval == 1)
00121 h = 2 + (blue - red) / delta;
00122 else
00123 h = 4 + (red - green) / delta;
00124
00125 if (h < 0.0)
00126 h += 6.0;
00127 else if (h > 6.0)
00128 h -= 6.0;
00129 }
00130
00131 *hue = h;
00132 *sat = s;
00133 *lightness = l;
00134 }
00135
00136 static inline double
00137 hsl_value(double n1, double n2, double hue)
00138 {
00139 if (hue < 0)
00140 hue += 6.0;
00141 else if (hue > 6)
00142 hue -= 6.0;
00143 if (hue < 1.0)
00144 return (n1 + (n2 - n1) * hue);
00145 else if (hue < 3.0)
00146 return (n2);
00147 else if (hue < 4.0)
00148 return (n1 + (n2 - n1) * (4.0 - hue));
00149 else
00150 return (n1);
00151 }
00152
00153 static inline void
00154 calc_hsl_to_rgb(unsigned short *rgb, double h, double s, double l)
00155 {
00156 if (s < .0000001)
00157 {
00158 if (l > 1)
00159 l = 1;
00160 else if (l < 0)
00161 l = 0;
00162 rgb[0] = l * 65535;
00163 rgb[1] = l * 65535;
00164 rgb[2] = l * 65535;
00165 }
00166 else
00167 {
00168 double m1, m2;
00169 double h1, h2;
00170 h1 = h + 2;
00171 h2 = h - 2;
00172
00173 if (l < .5)
00174 m2 = l * (1 + s);
00175 else
00176 m2 = l + s - (l * s);
00177 m1 = (l * 2) - m2;
00178 rgb[0] = 65535 * hsl_value(m1, m2, h1);
00179 rgb[1] = 65535 * hsl_value(m1, m2, h);
00180 rgb[2] = 65535 * hsl_value(m1, m2, h2);
00181 }
00182 }
00183
00184 static inline double
00185 update_saturation(double sat, double adjust, double isat)
00186 {
00187 if (adjust < 1)
00188 sat *= adjust;
00189 else if (adjust > 1)
00190 {
00191 double s1 = sat * adjust;
00192 double s2 = 1.0 - ((1.0 - sat) * isat);
00193 sat = FMIN(s1, s2);
00194 }
00195 if (sat > 1)
00196 sat = 1.0;
00197 return sat;
00198 }
00199
00200 static inline double
00201 interpolate_value(const double *vec, double val)
00202 {
00203 double base = floor(val);
00204 double frac = val - base;
00205 int ibase = (int) base;
00206 double lval = vec[ibase];
00207 if (frac > 0)
00208 lval += (vec[ibase + 1] - lval) * frac;
00209 return lval;
00210 }
00211
00212 static inline void
00213 update_saturation_from_rgb(unsigned short *rgb,
00214 const unsigned short *brightness_lookup,
00215 double adjust, double isat, int do_usermap)
00216 {
00217 double h, s, l;
00218 calc_rgb_to_hsl(rgb, &h, &s, &l);
00219 if (do_usermap)
00220 {
00221 unsigned short ub = (unsigned short) (l * 65535);
00222 unsigned short val = brightness_lookup[ub];
00223 l = ((double) val) / 65535;
00224 if (val < ub)
00225 s = s * (65535 - ub) / (65535 - val);
00226 }
00227 s = update_saturation(s, adjust, isat);
00228 calc_hsl_to_rgb(rgb, h, s, l);
00229 }
00230
00231 static inline double
00232 adjust_hue(const double *hue_map, double hue, size_t points)
00233 {
00234 if (hue_map)
00235 {
00236 hue += interpolate_value(hue_map, hue * points / 6.0);
00237 if (hue < 0.0)
00238 hue += 6.0;
00239 else if (hue >= 6.0)
00240 hue -= 6.0;
00241 }
00242 return hue;
00243 }
00244
00245 static inline void
00246 adjust_hsl(unsigned short *rgbout, lut_t *lut, double ssat, double isat,
00247 int split_saturation)
00248 {
00249 const double *hue_map = CURVE_CACHE_FAST_DOUBLE(&(lut->hue_map));
00250 const double *lum_map = CURVE_CACHE_FAST_DOUBLE(&(lut->lum_map));
00251 const double *sat_map = CURVE_CACHE_FAST_DOUBLE(&(lut->sat_map));
00252 if ((split_saturation || lum_map || hue_map || sat_map) &&
00253 (rgbout[0] != rgbout[1] || rgbout[0] != rgbout[2]))
00254 {
00255 size_t hue_count = CURVE_CACHE_FAST_COUNT(&(lut->hue_map));
00256 size_t lum_count = CURVE_CACHE_FAST_COUNT(&(lut->lum_map));
00257 size_t sat_count = CURVE_CACHE_FAST_COUNT(&(lut->sat_map));
00258 double h, s, l;
00259 double oh;
00260 rgbout[0] ^= 65535;
00261 rgbout[1] ^= 65535;
00262 rgbout[2] ^= 65535;
00263 calc_rgb_to_hsl(rgbout, &h, &s, &l);
00264 s = update_saturation(s, ssat, isat);
00265 oh = h;
00266 h = adjust_hue(hue_map, h, hue_count);
00267 if (lut->lum_map.d_cache && l > 0.0001 && l < .9999)
00268 {
00269 double nh = oh * lum_count / 6.0;
00270 double oel = interpolate_value(lum_map,nh);
00271 double el = 1.0 + s*(oel-1.0);
00272 double sreflection = 0.560 - el/7.0;
00273 double isreflection = 1.0 - sreflection;
00274 double sadj = l - sreflection;
00275
00276 double lumshad;
00277 double lummid;
00278 double lumhigh;
00279 double weight;
00280 double g;
00281 double l2;
00282 double is,s2;
00283
00284 g=-4.0 + el * 5.0;
00285 lumhigh=g * l + (1.0 - g);
00286 lummid=lumshad=el * l;
00287 weight=pow(l,2.2);
00288 l2=lumshad + weight * (lumhigh-lumshad);
00289 weight=(2*pow(l,0.75)-1.0);
00290 weight*=weight;
00291 l2=lummid + weight * (l2-lummid);
00292
00293 s=pow(s,0.62+oel*0.3);
00294 l=l2;
00295
00296 if(sadj > 0)
00297 {
00298 double depth=s*(0.85-el*0.85);
00299 double sl=sadj/isreflection;
00300 weight=pow(1.0-sl,2.8*el+0.25)-0.40;
00301 s2=pow(0.5,-22*weight*weight);
00302 s-=depth*(s/s2);
00303 }
00304 }
00305 if (lut->sat_map.d_cache)
00306 {
00307 double nh = oh * sat_count / 6.0;
00308 double tmp = interpolate_value(sat_map, nh);
00309 if (tmp < .9999 || tmp > 1.0001)
00310 {
00311 s = update_saturation(s, tmp, tmp > 1.0 ? 1.0 / tmp : 1.0);
00312 }
00313 }
00314 calc_hsl_to_rgb(rgbout, h, s, l);
00315 rgbout[0] ^= 65535;
00316 rgbout[1] ^= 65535;
00317 rgbout[2] ^= 65535;
00318 }
00319 }
00320
00321 static inline void
00322 adjust_hsl_bright(unsigned short *rgbout, lut_t *lut, double ssat, double isat,
00323 int split_saturation)
00324 {
00325 const double *hue_map = CURVE_CACHE_FAST_DOUBLE(&(lut->hue_map));
00326 const double *lum_map = CURVE_CACHE_FAST_DOUBLE(&(lut->lum_map));
00327 if ((split_saturation || lum_map || hue_map) &&
00328 (rgbout[0] != rgbout[1] || rgbout[0] != rgbout[2]))
00329 {
00330 size_t hue_count = CURVE_CACHE_FAST_COUNT(&(lut->hue_map));
00331 size_t lum_count = CURVE_CACHE_FAST_COUNT(&(lut->lum_map));
00332 double h, s, l;
00333 rgbout[0] ^= 65535;
00334 rgbout[1] ^= 65535;
00335 rgbout[2] ^= 65535;
00336 calc_rgb_to_hsl(rgbout, &h, &s, &l);
00337 s = update_saturation(s, ssat, isat);
00338 h = adjust_hue(hue_map, h, hue_count);
00339 if (lum_map && l > 0.0001 && l < .9999)
00340 {
00341 double nh = h * lum_count / 6.0;
00342 double el = interpolate_value(lum_map, nh);
00343 el = 1.0 + (s * (el - 1.0));
00344 l = 1.0 - pow(1.0 - l, el);
00345 }
00346 calc_hsl_to_rgb(rgbout, h, s, l);
00347 rgbout[0] ^= 65535;
00348 rgbout[1] ^= 65535;
00349 rgbout[2] ^= 65535;
00350 }
00351 }
00352
00353 static inline void
00354 lookup_rgb(lut_t *lut, unsigned short *rgbout,
00355 const unsigned short *red, const unsigned short *green,
00356 const unsigned short *blue, unsigned steps)
00357 {
00358 if (steps == 65536)
00359 {
00360 rgbout[0] = red[rgbout[0]];
00361 rgbout[1] = green[rgbout[1]];
00362 rgbout[2] = blue[rgbout[2]];
00363 }
00364 else
00365 {
00366 rgbout[0] = red[rgbout[0] / 257];
00367 rgbout[1] = green[rgbout[1] / 257];
00368 rgbout[2] = blue[rgbout[2] / 257];
00369 }
00370 }
00371
00372 static inline int
00373 short_eq(const unsigned short *i1, const unsigned short *i2, size_t count)
00374 {
00375 #if 1
00376 int i;
00377 for (i = 0; i < count; i++)
00378 if (i1[i] != i2[i])
00379 return 0;
00380 return 1;
00381 #else
00382 return !memcmp(i1, i2, count * sizeof(unsigned short));
00383 #endif
00384 }
00385
00386 static inline void
00387 short_copy(unsigned short *out, const unsigned short *in, size_t count)
00388 {
00389 #if 1
00390 int i;
00391 for (i = 0; i < count; i++)
00392 out[i] = in[i];
00393 #else
00394 (void) memcpy(out, in, count * sizeof(unsigned short));
00395 #endif
00396 }
00397
00398 static unsigned
00399 generic_cmy_to_kcmy(const stp_vars_t *vars, const unsigned short *in,
00400 unsigned short *out)
00401 {
00402 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color"));
00403 int width = lut->image_width;
00404 int step = 65535 / (lut->steps - 1);
00405
00406 const unsigned short *gcr_lookup;
00407 const unsigned short *black_lookup;
00408 int i;
00409 int i0 = -1;
00410 int i1 = -1;
00411 int i2 = -1;
00412 unsigned short o0 = 0;
00413 unsigned short o1 = 0;
00414 unsigned short o2 = 0;
00415 unsigned short o3 = 0;
00416 unsigned short nz0 = 0;
00417 unsigned short nz1 = 0;
00418 unsigned short nz2 = 0;
00419 unsigned short nz3 = 0;
00420
00421 stp_curve_resample(stp_curve_cache_get_curve(&(lut->gcr_curve)), lut->steps);
00422 gcr_lookup = stp_curve_cache_get_ushort_data(&(lut->gcr_curve));
00423 stp_curve_resample(stp_curve_cache_get_curve
00424 (&(lut->channel_curves[CHANNEL_K])), lut->steps);
00425 black_lookup =
00426 stp_curve_cache_get_ushort_data(&(lut->channel_curves[CHANNEL_K]));
00427
00428 for (i = 0; i < width; i++, out += 4, in += 3)
00429 {
00430 if (i0 == in[0] && i1 == in[1] && i2 == in[2])
00431 {
00432 out[0] = o0;
00433 out[1] = o1;
00434 out[2] = o2;
00435 out[3] = o3;
00436 }
00437 else
00438 {
00439 int k;
00440 i0 = in[0];
00441 i1 = in[1];
00442 i2 = in[2];
00443 k = FMIN(i0, FMIN(i1, i2));
00444 out[0] = 0;
00445 out[1] = i0;
00446 out[2] = i1;
00447 out[3] = i2;
00448 if (k > 0)
00449 {
00450 int where, resid;
00451 int kk;
00452 if (lut->steps == 65536)
00453 kk = gcr_lookup[k];
00454 else
00455 {
00456 where = k / step;
00457 resid = k % step;
00458 kk = gcr_lookup[where];
00459 if (resid > 0)
00460 kk += (gcr_lookup[where + 1] - gcr_lookup[where]) * resid /
00461 step;
00462 }
00463 if (kk > k)
00464 kk = k;
00465 if (kk > 0)
00466 {
00467 if (lut->steps == 65536)
00468 out[0] = black_lookup[kk];
00469 else
00470 {
00471 int k_out;
00472 where = kk / step;
00473 resid = kk % step;
00474 k_out = black_lookup[where];
00475 if (resid > 0)
00476 k_out +=
00477 (black_lookup[where + 1] - black_lookup[where]) *
00478 resid / step;
00479 out[0] = k_out;
00480 }
00481 out[1] -= kk;
00482 out[2] -= kk;
00483 out[3] -= kk;
00484 }
00485 }
00486 o0 = out[0];
00487 o1 = out[1];
00488 o2 = out[2];
00489 o3 = out[3];
00490 nz0 |= o0;
00491 nz1 |= o1;
00492 nz2 |= o2;
00493 nz3 |= o3;
00494 }
00495 }
00496 return (nz0 ? 0 : 1) + (nz1 ? 0 : 2) + (nz2 ? 0 : 4) + (nz3 ? 0 : 8);
00497 }
00498
00499 static unsigned
00500 raw_cmy_to_kcmy(const stp_vars_t *vars, const unsigned short *in,
00501 unsigned short *out)
00502 {
00503 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color"));
00504 int width = lut->image_width;
00505
00506 int i;
00507 int j;
00508 unsigned short nz[4];
00509 unsigned retval = 0;
00510 const unsigned short *input_cache = NULL;
00511 const unsigned short *output_cache = NULL;
00512
00513 memset(nz, 0, sizeof(nz));
00514
00515 for (i = 0; i < width; i++, out += 4, in += 3)
00516 {
00517 if (input_cache && short_eq(input_cache, in, 3))
00518 short_copy(out, output_cache, 4);
00519 else
00520 {
00521 int c = in[0];
00522 int m = in[1];
00523 int y = in[2];
00524 int k = FMIN(c, FMIN(m, y));
00525 input_cache = in;
00526 out[0] = 0;
00527 for (j = 0; j < 3; j++)
00528 out[j + 1] = in[j];
00529 if (k > 0)
00530 {
00531 out[0] = k;
00532 out[1] -= k;
00533 out[2] -= k;
00534 out[3] -= k;
00535 }
00536 output_cache = out;
00537 for (j = 0; j < 4; j++)
00538 if (out[j])
00539 nz[j] = 1;
00540 }
00541 }
00542 for (j = 0; j < 4; j++)
00543 if (nz[j] == 0)
00544 retval |= (1 << j);
00545 return retval;
00546 }
00547
00548 #define GENERIC_COLOR_FUNC(fromname, toname) \
00549 static unsigned \
00550 fromname##_to_##toname(const stp_vars_t *vars, const unsigned char *in, \
00551 unsigned short *out) \
00552 { \
00553 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
00554 if (!lut->printed_colorfunc) \
00555 { \
00556 lut->printed_colorfunc = 1; \
00557 stp_dprintf(STP_DBG_COLORFUNC, vars, \
00558 "Colorfunc is %s_%d_to_%s, %s, %s, %d, %d\n", \
00559 #fromname, lut->channel_depth, #toname, \
00560 lut->input_color_description->name, \
00561 lut->output_color_description->name, \
00562 lut->steps, lut->invert_output); \
00563 } \
00564 if (lut->channel_depth == 8) \
00565 return fromname##_8_to_##toname(vars, in, out); \
00566 else \
00567 return fromname##_16_to_##toname(vars, in, out); \
00568 }
00569
00570 #define COLOR_TO_COLOR_FUNC(T, bits) \
00571 static unsigned \
00572 color_##bits##_to_color(const stp_vars_t *vars, const unsigned char *in, \
00573 unsigned short *out) \
00574 { \
00575 int i; \
00576 double isat = 1.0; \
00577 double ssat = stp_get_float_parameter(vars, "Saturation"); \
00578 double sbright = stp_get_float_parameter(vars, "Brightness"); \
00579 int i0 = -1; \
00580 int i1 = -1; \
00581 int i2 = -1; \
00582 unsigned short o0 = 0; \
00583 unsigned short o1 = 0; \
00584 unsigned short o2 = 0; \
00585 unsigned short nz0 = 0; \
00586 unsigned short nz1 = 0; \
00587 unsigned short nz2 = 0; \
00588 const unsigned short *red; \
00589 const unsigned short *green; \
00590 const unsigned short *blue; \
00591 const unsigned short *brightness; \
00592 const unsigned short *contrast; \
00593 const T *s_in = (const T *) in; \
00594 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
00595 int compute_saturation = ssat <= .99999 || ssat >= 1.00001; \
00596 int split_saturation = ssat > 1.4; \
00597 int bright_color_adjustment = 0; \
00598 int do_user_adjustment = 0; \
00599 if (lut->color_correction->correction == COLOR_CORRECTION_BRIGHT) \
00600 bright_color_adjustment = 1; \
00601 if (sbright != 1) \
00602 do_user_adjustment = 1; \
00603 compute_saturation |= do_user_adjustment; \
00604 \
00605 for (i = CHANNEL_C; i <= CHANNEL_Y; i++) \
00606 stp_curve_resample(stp_curve_cache_get_curve(&(lut->channel_curves[i])), \
00607 1 << bits); \
00608 stp_curve_resample \
00609 (stp_curve_cache_get_curve(&(lut->brightness_correction)), 65536); \
00610 stp_curve_resample \
00611 (stp_curve_cache_get_curve(&(lut->contrast_correction)), 1 << bits); \
00612 red = \
00613 stp_curve_cache_get_ushort_data(&(lut->channel_curves[CHANNEL_C])); \
00614 green = \
00615 stp_curve_cache_get_ushort_data(&(lut->channel_curves[CHANNEL_M])); \
00616 blue = \
00617 stp_curve_cache_get_ushort_data(&(lut->channel_curves[CHANNEL_Y])); \
00618 brightness= \
00619 stp_curve_cache_get_ushort_data(&(lut->brightness_correction)); \
00620 contrast = \
00621 stp_curve_cache_get_ushort_data(&(lut->contrast_correction)); \
00622 (void) stp_curve_cache_get_double_data(&(lut->hue_map)); \
00623 (void) stp_curve_cache_get_double_data(&(lut->lum_map)); \
00624 (void) stp_curve_cache_get_double_data(&(lut->sat_map)); \
00625 \
00626 if (split_saturation) \
00627 ssat = sqrt(ssat); \
00628 if (ssat > 1) \
00629 isat = 1.0 / ssat; \
00630 for (i = 0; i < lut->image_width; i++) \
00631 { \
00632 if (i0 == s_in[0] && i1 == s_in[1] && i2 == s_in[2]) \
00633 { \
00634 out[0] = o0; \
00635 out[1] = o1; \
00636 out[2] = o2; \
00637 } \
00638 else \
00639 { \
00640 i0 = s_in[0]; \
00641 i1 = s_in[1]; \
00642 i2 = s_in[2]; \
00643 out[0] = i0 * (65535u / (unsigned) ((1 << bits) - 1)); \
00644 out[1] = i1 * (65535u / (unsigned) ((1 << bits) - 1)); \
00645 out[2] = i2 * (65535u / (unsigned) ((1 << bits) - 1)); \
00646 lookup_rgb(lut, out, contrast, contrast, contrast, 1 << bits); \
00647 if ((compute_saturation)) \
00648 update_saturation_from_rgb(out, brightness, ssat, isat, \
00649 do_user_adjustment); \
00650 if (bright_color_adjustment) \
00651 adjust_hsl_bright(out, lut, ssat, isat, split_saturation); \
00652 else \
00653 adjust_hsl(out, lut, ssat, isat, split_saturation); \
00654 lookup_rgb(lut, out, red, green, blue, 1 << bits); \
00655 o0 = out[0]; \
00656 o1 = out[1]; \
00657 o2 = out[2]; \
00658 nz0 |= o0; \
00659 nz1 |= o1; \
00660 nz2 |= o2; \
00661 } \
00662 s_in += 3; \
00663 out += 3; \
00664 } \
00665 return (nz0 ? 0 : 1) + (nz1 ? 0 : 2) + (nz2 ? 0 : 4); \
00666 }
00667
00668 COLOR_TO_COLOR_FUNC(unsigned char, 8)
00669 COLOR_TO_COLOR_FUNC(unsigned short, 16)
00670 GENERIC_COLOR_FUNC(color, color)
00671
00672
00673
00674
00675
00676 #define FAST_COLOR_TO_COLOR_FUNC(T, bits) \
00677 static unsigned \
00678 color_##bits##_to_color_fast(const stp_vars_t *vars, const unsigned char *in, \
00679 unsigned short *out) \
00680 { \
00681 int i; \
00682 int i0 = -1; \
00683 int i1 = -1; \
00684 int i2 = -1; \
00685 int o0 = 0; \
00686 int o1 = 0; \
00687 int o2 = 0; \
00688 int nz0 = 0; \
00689 int nz1 = 0; \
00690 int nz2 = 0; \
00691 const T *s_in = (const T *) in; \
00692 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
00693 const unsigned short *red; \
00694 const unsigned short *green; \
00695 const unsigned short *blue; \
00696 const unsigned short *brightness; \
00697 const unsigned short *contrast; \
00698 double isat = 1.0; \
00699 double saturation = stp_get_float_parameter(vars, "Saturation"); \
00700 double sbright = stp_get_float_parameter(vars, "Brightness"); \
00701 int compute_saturation = saturation <= .99999 || saturation >= 1.00001; \
00702 int do_user_adjustment = 0; \
00703 if (sbright != 1) \
00704 do_user_adjustment = 1; \
00705 compute_saturation |= do_user_adjustment; \
00706 \
00707 for (i = CHANNEL_C; i <= CHANNEL_Y; i++) \
00708 stp_curve_resample(lut->channel_curves[i].curve, 65536); \
00709 stp_curve_resample \
00710 (stp_curve_cache_get_curve(&(lut->brightness_correction)), 65536); \
00711 stp_curve_resample \
00712 (stp_curve_cache_get_curve(&(lut->contrast_correction)), 1 << bits); \
00713 red = \
00714 stp_curve_cache_get_ushort_data(&(lut->channel_curves[CHANNEL_C])); \
00715 green = \
00716 stp_curve_cache_get_ushort_data(&(lut->channel_curves[CHANNEL_M])); \
00717 blue = \
00718 stp_curve_cache_get_ushort_data(&(lut->channel_curves[CHANNEL_Y])); \
00719 brightness= \
00720 stp_curve_cache_get_ushort_data(&(lut->brightness_correction)); \
00721 contrast = \
00722 stp_curve_cache_get_ushort_data(&(lut->contrast_correction)); \
00723 \
00724 if (saturation > 1) \
00725 isat = 1.0 / saturation; \
00726 for (i = 0; i < lut->image_width; i++) \
00727 { \
00728 if (i0 == s_in[0] && i1 == s_in[1] && i2 == s_in[2]) \
00729 { \
00730 out[0] = o0; \
00731 out[1] = o1; \
00732 out[2] = o2; \
00733 } \
00734 else \
00735 { \
00736 i0 = s_in[0]; \
00737 i1 = s_in[1]; \
00738 i2 = s_in[2]; \
00739 out[0] = contrast[s_in[0]]; \
00740 out[1] = contrast[s_in[1]]; \
00741 out[2] = contrast[s_in[2]]; \
00742 if ((compute_saturation)) \
00743 update_saturation_from_rgb(out, brightness, saturation, isat, 1); \
00744 out[0] = red[out[0]]; \
00745 out[1] = green[out[1]]; \
00746 out[2] = blue[out[2]]; \
00747 o0 = out[0]; \
00748 o1 = out[1]; \
00749 o2 = out[2]; \
00750 nz0 |= o0; \
00751 nz1 |= o1; \
00752 nz2 |= o2; \
00753 } \
00754 s_in += 3; \
00755 out += 3; \
00756 } \
00757 return (nz0 ? 0 : 1) + (nz1 ? 0 : 2) + (nz2 ? 0 : 4); \
00758 }
00759
00760 FAST_COLOR_TO_COLOR_FUNC(unsigned char, 8)
00761 FAST_COLOR_TO_COLOR_FUNC(unsigned short, 16)
00762 GENERIC_COLOR_FUNC(color, color_fast)
00763
00764 #define RAW_COLOR_TO_COLOR_FUNC(T, bits) \
00765 static unsigned \
00766 color_##bits##_to_color_raw(const stp_vars_t *vars, const unsigned char *in,\
00767 unsigned short *out) \
00768 { \
00769 int i; \
00770 int j; \
00771 int nz = 0; \
00772 const T *s_in = (const T *) in; \
00773 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
00774 unsigned mask = 0; \
00775 if (lut->invert_output) \
00776 mask = 0xffff; \
00777 \
00778 for (i = 0; i < lut->image_width; i++) \
00779 { \
00780 unsigned bit = 1; \
00781 for (j = 0; j < 3; j++, bit += bit) \
00782 { \
00783 out[j] = (s_in[j] * (65535 / ((1 << bits) - 1))) ^ mask; \
00784 if (out[j]) \
00785 nz |= bit; \
00786 } \
00787 s_in += 3; \
00788 out += 3; \
00789 } \
00790 return nz; \
00791 }
00792
00793 RAW_COLOR_TO_COLOR_FUNC(unsigned char, 8)
00794 RAW_COLOR_TO_COLOR_FUNC(unsigned short, 16)
00795 GENERIC_COLOR_FUNC(color, color_raw)
00796
00797
00798
00799
00800
00801 #define GRAY_TO_COLOR_FUNC(T, bits) \
00802 static unsigned \
00803 gray_##bits##_to_color(const stp_vars_t *vars, const unsigned char *in, \
00804 unsigned short *out) \
00805 { \
00806 int i; \
00807 int i0 = -1; \
00808 int o0 = 0; \
00809 int o1 = 0; \
00810 int o2 = 0; \
00811 int nz0 = 0; \
00812 int nz1 = 0; \
00813 int nz2 = 0; \
00814 const T *s_in = (const T *) in; \
00815 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
00816 const unsigned short *red; \
00817 const unsigned short *green; \
00818 const unsigned short *blue; \
00819 const unsigned short *user; \
00820 \
00821 for (i = CHANNEL_C; i <= CHANNEL_Y; i++) \
00822 stp_curve_resample(lut->channel_curves[i].curve, 65536); \
00823 stp_curve_resample \
00824 (stp_curve_cache_get_curve(&(lut->user_color_correction)), 1 << bits); \
00825 red = \
00826 stp_curve_cache_get_ushort_data(&(lut->channel_curves[CHANNEL_C])); \
00827 green = \
00828 stp_curve_cache_get_ushort_data(&(lut->channel_curves[CHANNEL_M])); \
00829 blue = \
00830 stp_curve_cache_get_ushort_data(&(lut->channel_curves[CHANNEL_Y])); \
00831 user = \
00832 stp_curve_cache_get_ushort_data(&(lut->user_color_correction)); \
00833 \
00834 for (i = 0; i < lut->image_width; i++) \
00835 { \
00836 if (i0 == s_in[0]) \
00837 { \
00838 out[0] = o0; \
00839 out[1] = o1; \
00840 out[2] = o2; \
00841 } \
00842 else \
00843 { \
00844 i0 = s_in[0]; \
00845 out[0] = red[user[s_in[0]]]; \
00846 out[1] = green[user[s_in[0]]]; \
00847 out[2] = blue[user[s_in[0]]]; \
00848 o0 = out[0]; \
00849 o1 = out[1]; \
00850 o2 = out[2]; \
00851 nz0 |= o0; \
00852 nz1 |= o1; \
00853 nz2 |= o2; \
00854 } \
00855 s_in += 1; \
00856 out += 3; \
00857 } \
00858 return (nz0 ? 0 : 1) + (nz1 ? 0 : 2) + (nz2 ? 0 : 4); \
00859 }
00860
00861 GRAY_TO_COLOR_FUNC(unsigned char, 8)
00862 GRAY_TO_COLOR_FUNC(unsigned short, 16)
00863 GENERIC_COLOR_FUNC(gray, color)
00864
00865 #define GRAY_TO_COLOR_RAW_FUNC(T, bits) \
00866 static unsigned \
00867 gray_##bits##_to_color_raw(const stp_vars_t *vars, const unsigned char *in,\
00868 unsigned short *out) \
00869 { \
00870 int i; \
00871 int nz = 7; \
00872 const T *s_in = (const T *) in; \
00873 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
00874 unsigned mask = 0; \
00875 if (lut->invert_output) \
00876 mask = 0xffff; \
00877 \
00878 for (i = 0; i < lut->image_width; i++) \
00879 { \
00880 unsigned outval = (s_in[0] * (65535 / (1 << bits))) ^ mask; \
00881 out[0] = outval; \
00882 out[1] = outval; \
00883 out[2] = outval; \
00884 if (outval) \
00885 nz = 0; \
00886 s_in++; \
00887 out += 3; \
00888 } \
00889 return nz; \
00890 }
00891
00892 GRAY_TO_COLOR_RAW_FUNC(unsigned char, 8)
00893 GRAY_TO_COLOR_RAW_FUNC(unsigned short, 16)
00894 GENERIC_COLOR_FUNC(gray, color_raw)
00895
00896 #define COLOR_TO_KCMY_FUNC(name, name2, name3, name4, bits) \
00897 static unsigned \
00898 name##_##bits##_to_##name2(const stp_vars_t *vars, const unsigned char *in, \
00899 unsigned short *out) \
00900 { \
00901 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
00902 size_t real_steps = lut->steps; \
00903 unsigned status; \
00904 if (!lut->cmy_tmp) \
00905 lut->cmy_tmp = stp_malloc(4 * 2 * lut->image_width); \
00906 name##_##bits##_to_##name3(vars, in, lut->cmy_tmp); \
00907 lut->steps = 65536; \
00908 status = name4##_cmy_to_kcmy(vars, lut->cmy_tmp, out); \
00909 lut->steps = real_steps; \
00910 return status; \
00911 }
00912
00913 COLOR_TO_KCMY_FUNC(gray, kcmy, color, generic, 8)
00914 COLOR_TO_KCMY_FUNC(gray, kcmy, color, generic, 16)
00915 GENERIC_COLOR_FUNC(gray, kcmy)
00916
00917 COLOR_TO_KCMY_FUNC(gray, kcmy_raw, color_raw, raw, 8)
00918 COLOR_TO_KCMY_FUNC(gray, kcmy_raw, color_raw, raw, 16)
00919 GENERIC_COLOR_FUNC(gray, kcmy_raw)
00920
00921 COLOR_TO_KCMY_FUNC(color, kcmy, color, generic, 8)
00922 COLOR_TO_KCMY_FUNC(color, kcmy, color, generic, 16)
00923 GENERIC_COLOR_FUNC(color, kcmy)
00924
00925 COLOR_TO_KCMY_FUNC(color, kcmy_fast, color_fast, generic, 8)
00926 COLOR_TO_KCMY_FUNC(color, kcmy_fast, color_fast, generic, 16)
00927 GENERIC_COLOR_FUNC(color, kcmy_fast)
00928
00929 COLOR_TO_KCMY_FUNC(color, kcmy_raw, color_raw, raw, 8)
00930 COLOR_TO_KCMY_FUNC(color, kcmy_raw, color_raw, raw, 16)
00931 GENERIC_COLOR_FUNC(color, kcmy_raw)
00932
00933
00934 #define COLOR_TO_KCMY_THRESHOLD_FUNC(T, name) \
00935 static unsigned \
00936 name##_to_kcmy_threshold(const stp_vars_t *vars, \
00937 const unsigned char *in, \
00938 unsigned short *out) \
00939 { \
00940 int i; \
00941 int z = 15; \
00942 const T *s_in = (const T *) in; \
00943 unsigned high_bit = ((1 << ((sizeof(T) * 8) - 1))); \
00944 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
00945 int width = lut->image_width; \
00946 unsigned mask = 0; \
00947 memset(out, 0, width * 4 * sizeof(unsigned short)); \
00948 if (lut->invert_output) \
00949 mask = (1 << (sizeof(T) * 8)) - 1; \
00950 \
00951 for (i = 0; i < width; i++, out += 4, s_in += 3) \
00952 { \
00953 unsigned c = s_in[0] ^ mask; \
00954 unsigned m = s_in[1] ^ mask; \
00955 unsigned y = s_in[2] ^ mask; \
00956 unsigned k = (c < m ? (c < y ? c : y) : (m < y ? m : y)); \
00957 if (k >= high_bit) \
00958 { \
00959 c -= k; \
00960 m -= k; \
00961 y -= k; \
00962 } \
00963 if (k >= high_bit) \
00964 { \
00965 z &= 0xe; \
00966 out[0] = 65535; \
00967 } \
00968 if (c >= high_bit) \
00969 { \
00970 z &= 0xd; \
00971 out[1] = 65535; \
00972 } \
00973 if (m >= high_bit) \
00974 { \
00975 z &= 0xb; \
00976 out[2] = 65535; \
00977 } \
00978 if (y >= high_bit) \
00979 { \
00980 z &= 0x7; \
00981 out[3] = 65535; \
00982 } \
00983 } \
00984 return z; \
00985 }
00986
00987 COLOR_TO_KCMY_THRESHOLD_FUNC(unsigned char, color_8)
00988 COLOR_TO_KCMY_THRESHOLD_FUNC(unsigned short, color_16)
00989 GENERIC_COLOR_FUNC(color, kcmy_threshold)
00990
00991 #define CMYK_TO_KCMY_THRESHOLD_FUNC(T, name) \
00992 static unsigned \
00993 name##_to_kcmy_threshold(const stp_vars_t *vars, \
00994 const unsigned char *in, \
00995 unsigned short *out) \
00996 { \
00997 int i; \
00998 int z = 15; \
00999 const T *s_in = (const T *) in; \
01000 unsigned desired_high_bit = 0; \
01001 unsigned high_bit = 1 << ((sizeof(T) * 8) - 1); \
01002 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
01003 int width = lut->image_width; \
01004 memset(out, 0, width * 4 * sizeof(unsigned short)); \
01005 if (!lut->invert_output) \
01006 desired_high_bit = high_bit; \
01007 \
01008 for (i = 0; i < width; i++, out += 4, s_in += 4) \
01009 { \
01010 if ((s_in[3] & high_bit) == desired_high_bit) \
01011 { \
01012 z &= 0xe; \
01013 out[0] = 65535; \
01014 } \
01015 if ((s_in[0] & high_bit) == desired_high_bit) \
01016 { \
01017 z &= 0xd; \
01018 out[1] = 65535; \
01019 } \
01020 if ((s_in[1] & high_bit) == desired_high_bit) \
01021 { \
01022 z &= 0xb; \
01023 out[2] = 65535; \
01024 } \
01025 if ((s_in[2] & high_bit) == desired_high_bit) \
01026 { \
01027 z &= 0x7; \
01028 out[3] = 65535; \
01029 } \
01030 } \
01031 return z; \
01032 }
01033
01034 CMYK_TO_KCMY_THRESHOLD_FUNC(unsigned char, cmyk_8)
01035 CMYK_TO_KCMY_THRESHOLD_FUNC(unsigned short, cmyk_16)
01036 GENERIC_COLOR_FUNC(cmyk, kcmy_threshold)
01037
01038 #define KCMY_TO_KCMY_THRESHOLD_FUNC(T, name) \
01039 static unsigned \
01040 name##_to_kcmy_threshold(const stp_vars_t *vars, \
01041 const unsigned char *in, \
01042 unsigned short *out) \
01043 { \
01044 int i; \
01045 int j; \
01046 unsigned nz[4]; \
01047 unsigned z = 0xf; \
01048 const T *s_in = (const T *) in; \
01049 unsigned desired_high_bit = 0; \
01050 unsigned high_bit = 1 << ((sizeof(T) * 8) - 1); \
01051 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
01052 int width = lut->image_width; \
01053 memset(out, 0, width * 4 * sizeof(unsigned short)); \
01054 if (!lut->invert_output) \
01055 desired_high_bit = high_bit; \
01056 for (i = 0; i < 4; i++) \
01057 nz[i] = z & ~(1 << i); \
01058 \
01059 for (i = 0; i < width; i++) \
01060 { \
01061 for (j = 0; j < 4; j++) \
01062 { \
01063 if ((*s_in++ & high_bit) == desired_high_bit) \
01064 { \
01065 z &= nz[j]; \
01066 *out = 65535; \
01067 } \
01068 out++; \
01069 } \
01070 } \
01071 return z; \
01072 }
01073
01074 KCMY_TO_KCMY_THRESHOLD_FUNC(unsigned char, kcmy_8)
01075 KCMY_TO_KCMY_THRESHOLD_FUNC(unsigned short, kcmy_16)
01076 GENERIC_COLOR_FUNC(kcmy, kcmy_threshold)
01077
01078 #define GRAY_TO_COLOR_THRESHOLD_FUNC(T, name, bits, channels) \
01079 static unsigned \
01080 gray_##bits##_to_##name##_threshold(const stp_vars_t *vars, \
01081 const unsigned char *in, \
01082 unsigned short *out) \
01083 { \
01084 int i; \
01085 int z = (1 << channels) - 1; \
01086 int desired_high_bit = 0; \
01087 unsigned high_bit = 1 << ((sizeof(T) * 8) - 1); \
01088 const T *s_in = (const T *) in; \
01089 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
01090 int width = lut->image_width; \
01091 memset(out, 0, width * channels * sizeof(unsigned short)); \
01092 if (!lut->invert_output) \
01093 desired_high_bit = high_bit; \
01094 \
01095 for (i = 0; i < width; i++, out += channels, s_in++) \
01096 { \
01097 if ((s_in[0] & high_bit) == desired_high_bit) \
01098 { \
01099 int j; \
01100 z = 0; \
01101 for (j = 0; j < channels; j++) \
01102 out[j] = 65535; \
01103 } \
01104 } \
01105 return z; \
01106 }
01107
01108
01109 GRAY_TO_COLOR_THRESHOLD_FUNC(unsigned char, color, 8, 3)
01110 GRAY_TO_COLOR_THRESHOLD_FUNC(unsigned short, color, 16, 3)
01111 GENERIC_COLOR_FUNC(gray, color_threshold)
01112
01113 GRAY_TO_COLOR_THRESHOLD_FUNC(unsigned char, kcmy, 8, 4)
01114 GRAY_TO_COLOR_THRESHOLD_FUNC(unsigned short, kcmy, 16, 4)
01115 GENERIC_COLOR_FUNC(gray, kcmy_threshold)
01116
01117 #define COLOR_TO_COLOR_THRESHOLD_FUNC(T, name) \
01118 static unsigned \
01119 name##_to_color_threshold(const stp_vars_t *vars, \
01120 const unsigned char *in, \
01121 unsigned short *out) \
01122 { \
01123 int i; \
01124 int z = 7; \
01125 int desired_high_bit = 0; \
01126 unsigned high_bit = ((1 << ((sizeof(T) * 8) - 1)) * 4); \
01127 const T *s_in = (const T *) in; \
01128 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
01129 int width = lut->image_width; \
01130 memset(out, 0, width * 3 * sizeof(unsigned short)); \
01131 if (!lut->invert_output) \
01132 desired_high_bit = high_bit; \
01133 \
01134 for (i = 0; i < width; i++, out += 3, s_in += 3) \
01135 { \
01136 if ((s_in[0] & high_bit) == desired_high_bit) \
01137 { \
01138 z &= 6; \
01139 out[0] = 65535; \
01140 } \
01141 if ((s_in[1] & high_bit) == desired_high_bit) \
01142 { \
01143 z &= 5; \
01144 out[1] = 65535; \
01145 } \
01146 if ((s_in[1] & high_bit) == desired_high_bit) \
01147 { \
01148 z &= 3; \
01149 out[2] = 65535; \
01150 } \
01151 } \
01152 return z; \
01153 }
01154
01155 COLOR_TO_COLOR_THRESHOLD_FUNC(unsigned char, color_8)
01156 COLOR_TO_COLOR_THRESHOLD_FUNC(unsigned short, color_16)
01157 GENERIC_COLOR_FUNC(color, color_threshold)
01158
01159 #define COLOR_TO_GRAY_THRESHOLD_FUNC(T, name, channels, max_channels) \
01160 static unsigned \
01161 name##_to_gray_threshold(const stp_vars_t *vars, \
01162 const unsigned char *in, \
01163 unsigned short *out) \
01164 { \
01165 int i; \
01166 int z = 1; \
01167 int desired_high_bit = 0; \
01168 unsigned high_bit = ((1 << ((sizeof(T) * 8) - 1))); \
01169 const T *s_in = (const T *) in; \
01170 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
01171 int width = lut->image_width; \
01172 memset(out, 0, width * sizeof(unsigned short)); \
01173 if (!lut->invert_output) \
01174 desired_high_bit = high_bit; \
01175 \
01176 for (i = 0; i < width; i++, out++, s_in += channels) \
01177 { \
01178 unsigned gval = \
01179 (max_channels - channels) * (1 << ((sizeof(T) * 8) - 1)); \
01180 int j; \
01181 for (j = 0; j < channels; j++) \
01182 gval += s_in[j]; \
01183 gval /= channels; \
01184 if ((gval & high_bit) == desired_high_bit) \
01185 { \
01186 out[0] = 65535; \
01187 z = 0; \
01188 } \
01189 } \
01190 return z; \
01191 }
01192
01193 COLOR_TO_GRAY_THRESHOLD_FUNC(unsigned char, cmyk_8, 4, 4)
01194 COLOR_TO_GRAY_THRESHOLD_FUNC(unsigned short, cmyk_16, 4, 4)
01195 GENERIC_COLOR_FUNC(cmyk, gray_threshold)
01196
01197 COLOR_TO_GRAY_THRESHOLD_FUNC(unsigned char, kcmy_8, 4, 4)
01198 COLOR_TO_GRAY_THRESHOLD_FUNC(unsigned short, kcmy_16, 4, 4)
01199 GENERIC_COLOR_FUNC(kcmy, gray_threshold)
01200
01201 COLOR_TO_GRAY_THRESHOLD_FUNC(unsigned char, color_8, 3, 3)
01202 COLOR_TO_GRAY_THRESHOLD_FUNC(unsigned short, color_16, 3, 3)
01203 GENERIC_COLOR_FUNC(color, gray_threshold)
01204
01205 COLOR_TO_GRAY_THRESHOLD_FUNC(unsigned char, gray_8, 1, 1)
01206 COLOR_TO_GRAY_THRESHOLD_FUNC(unsigned short, gray_16, 1, 1)
01207 GENERIC_COLOR_FUNC(gray, gray_threshold)
01208
01209 #define CMYK_TO_COLOR_FUNC(namein, name2, T, bits, offset) \
01210 static unsigned \
01211 namein##_##bits##_to_##name2(const stp_vars_t *vars, const unsigned char *in, \
01212 unsigned short *out) \
01213 { \
01214 int i; \
01215 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
01216 unsigned status; \
01217 size_t real_steps = lut->steps; \
01218 const T *s_in = (const T *) in; \
01219 unsigned short *tmp; \
01220 int width = lut->image_width; \
01221 unsigned mask = 0; \
01222 \
01223 if (!lut->cmy_tmp) \
01224 lut->cmy_tmp = stp_malloc(3 * 2 * lut->image_width); \
01225 tmp = lut->cmy_tmp; \
01226 memset(lut->cmy_tmp, 0, width * 3 * sizeof(unsigned short)); \
01227 if (lut->invert_output) \
01228 mask = 0xffff; \
01229 \
01230 for (i = 0; i < width; i++, tmp += 3, s_in += 4) \
01231 { \
01232 unsigned c = (s_in[0 + offset] + s_in[(3 + offset) % 4]) * \
01233 (65535 / ((1 << bits) - 1)); \
01234 unsigned m = (s_in[1 + offset] + s_in[(3 + offset) % 4]) * \
01235 (65535 / ((1 << bits) - 1)); \
01236 unsigned y = (s_in[2 + offset] + s_in[(3 + offset) % 4]) * \
01237 (65535 / ((1 << bits) - 1)); \
01238 if (c > 65535) \
01239 c = 65535; \
01240 if (m > 65535) \
01241 m = 65535; \
01242 if (y > 65535) \
01243 y = 65535; \
01244 tmp[0] = c ^ mask; \
01245 tmp[1] = m ^ mask; \
01246 tmp[2] = y ^ mask; \
01247 } \
01248 lut->steps = 65536; \
01249 status = \
01250 color_16_to_##name2(vars, (const unsigned char *) lut->cmy_tmp, out); \
01251 lut->steps = real_steps; \
01252 return status; \
01253 }
01254
01255 CMYK_TO_COLOR_FUNC(cmyk, color, unsigned char, 8, 0)
01256 CMYK_TO_COLOR_FUNC(cmyk, color, unsigned short, 16, 0)
01257 GENERIC_COLOR_FUNC(cmyk, color)
01258 CMYK_TO_COLOR_FUNC(kcmy, color, unsigned char, 8, 1)
01259 CMYK_TO_COLOR_FUNC(kcmy, color, unsigned short, 16, 1)
01260 GENERIC_COLOR_FUNC(kcmy, color)
01261 CMYK_TO_COLOR_FUNC(cmyk, color_threshold, unsigned char, 8, 0)
01262 CMYK_TO_COLOR_FUNC(cmyk, color_threshold, unsigned short, 16, 0)
01263 GENERIC_COLOR_FUNC(cmyk, color_threshold)
01264 CMYK_TO_COLOR_FUNC(kcmy, color_threshold, unsigned char, 8, 1)
01265 CMYK_TO_COLOR_FUNC(kcmy, color_threshold, unsigned short, 16, 1)
01266 GENERIC_COLOR_FUNC(kcmy, color_threshold)
01267 CMYK_TO_COLOR_FUNC(cmyk, color_fast, unsigned char, 8, 0)
01268 CMYK_TO_COLOR_FUNC(cmyk, color_fast, unsigned short, 16, 0)
01269 GENERIC_COLOR_FUNC(cmyk, color_fast)
01270 CMYK_TO_COLOR_FUNC(kcmy, color_fast, unsigned char, 8, 1)
01271 CMYK_TO_COLOR_FUNC(kcmy, color_fast, unsigned short, 16, 1)
01272 GENERIC_COLOR_FUNC(kcmy, color_fast)
01273 CMYK_TO_COLOR_FUNC(cmyk, color_raw, unsigned char, 8, 0)
01274 CMYK_TO_COLOR_FUNC(cmyk, color_raw, unsigned short, 16, 0)
01275 GENERIC_COLOR_FUNC(cmyk, color_raw)
01276 CMYK_TO_COLOR_FUNC(kcmy, color_raw, unsigned char, 8, 1)
01277 CMYK_TO_COLOR_FUNC(kcmy, color_raw, unsigned short, 16, 1)
01278 GENERIC_COLOR_FUNC(kcmy, color_raw)
01279
01280 #define CMYK_TO_KCMY_FUNC(T, size) \
01281 static unsigned \
01282 cmyk_##size##_to_kcmy(const stp_vars_t *vars, \
01283 const unsigned char *in, \
01284 unsigned short *out) \
01285 { \
01286 int i; \
01287 unsigned retval = 0; \
01288 int j; \
01289 int nz[4]; \
01290 const T *s_in = (const T *) in; \
01291 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
01292 const unsigned short *user; \
01293 const unsigned short *maps[4]; \
01294 \
01295 for (i = 0; i < 4; i++) \
01296 { \
01297 stp_curve_resample(lut->channel_curves[i].curve, 65536); \
01298 maps[i] = stp_curve_cache_get_ushort_data(&(lut->channel_curves[i])); \
01299 } \
01300 stp_curve_resample(lut->user_color_correction.curve, 1 << size); \
01301 user = stp_curve_cache_get_ushort_data(&(lut->user_color_correction)); \
01302 \
01303 memset(nz, 0, sizeof(nz)); \
01304 \
01305 for (i = 0; i < lut->image_width; i++, out += 4) \
01306 { \
01307 for (j = 0; j < 4; j++) \
01308 { \
01309 int outpos = (j + 1) & 3; \
01310 int inval = *s_in++; \
01311 nz[outpos] |= inval; \
01312 out[outpos] = maps[outpos][user[inval]]; \
01313 } \
01314 } \
01315 for (j = 0; j < 4; j++) \
01316 if (nz[j] == 0) \
01317 retval |= (1 << j); \
01318 return retval; \
01319 }
01320
01321 CMYK_TO_KCMY_FUNC(unsigned char, 8)
01322 CMYK_TO_KCMY_FUNC(unsigned short, 16)
01323 GENERIC_COLOR_FUNC(cmyk, kcmy)
01324
01325 #define KCMY_TO_KCMY_FUNC(T, size) \
01326 static unsigned \
01327 kcmy_##size##_to_kcmy(const stp_vars_t *vars, \
01328 const unsigned char *in, \
01329 unsigned short *out) \
01330 { \
01331 int i; \
01332 unsigned retval = 0; \
01333 int j; \
01334 int nz[4]; \
01335 const T *s_in = (const T *) in; \
01336 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
01337 const unsigned short *user; \
01338 const unsigned short *maps[4]; \
01339 \
01340 for (i = 0; i < 4; i++) \
01341 { \
01342 stp_curve_resample(lut->channel_curves[i].curve, 65536); \
01343 maps[i] = stp_curve_cache_get_ushort_data(&(lut->channel_curves[i])); \
01344 } \
01345 stp_curve_resample(lut->user_color_correction.curve, 1 << size); \
01346 user = stp_curve_cache_get_ushort_data(&(lut->user_color_correction)); \
01347 \
01348 memset(nz, 0, sizeof(nz)); \
01349 \
01350 for (i = 0; i < lut->image_width; i++, out += 4) \
01351 { \
01352 for (j = 0; j < 4; j++) \
01353 { \
01354 int inval = *s_in++; \
01355 nz[j] |= inval; \
01356 out[j] = maps[j][user[inval]]; \
01357 } \
01358 } \
01359 for (j = 0; j < 4; j++) \
01360 if (nz[j] == 0) \
01361 retval |= (1 << j); \
01362 return retval; \
01363 }
01364
01365 KCMY_TO_KCMY_FUNC(unsigned char, 8)
01366 KCMY_TO_KCMY_FUNC(unsigned short, 16)
01367 GENERIC_COLOR_FUNC(kcmy, kcmy)
01368
01369
01370 #define GRAY_TO_GRAY_FUNC(T, bits) \
01371 static unsigned \
01372 gray_##bits##_to_gray(const stp_vars_t *vars, \
01373 const unsigned char *in, \
01374 unsigned short *out) \
01375 { \
01376 int i; \
01377 int i0 = -1; \
01378 int o0 = 0; \
01379 int nz = 0; \
01380 const T *s_in = (const T *) in; \
01381 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
01382 int width = lut->image_width; \
01383 const unsigned short *composite; \
01384 const unsigned short *user; \
01385 \
01386 stp_curve_resample \
01387 (stp_curve_cache_get_curve(&(lut->channel_curves[CHANNEL_K])), 65536); \
01388 composite = \
01389 stp_curve_cache_get_ushort_data(&(lut->channel_curves[CHANNEL_K])); \
01390 stp_curve_resample(lut->user_color_correction.curve, 1 << bits); \
01391 user = stp_curve_cache_get_ushort_data(&(lut->user_color_correction)); \
01392 \
01393 memset(out, 0, width * sizeof(unsigned short)); \
01394 \
01395 for (i = 0; i < lut->image_width; i++) \
01396 { \
01397 if (i0 != s_in[0]) \
01398 { \
01399 i0 = s_in[0]; \
01400 o0 = composite[user[i0]]; \
01401 nz |= o0; \
01402 } \
01403 out[0] = o0; \
01404 s_in ++; \
01405 out ++; \
01406 } \
01407 return nz == 0; \
01408 }
01409
01410 GRAY_TO_GRAY_FUNC(unsigned char, 8)
01411 GRAY_TO_GRAY_FUNC(unsigned short, 16)
01412 GENERIC_COLOR_FUNC(gray, gray)
01413
01414 #define COLOR_TO_GRAY_FUNC(T, bits) \
01415 static unsigned \
01416 color_##bits##_to_gray(const stp_vars_t *vars, \
01417 const unsigned char *in, \
01418 unsigned short *out) \
01419 { \
01420 int i; \
01421 int i0 = -1; \
01422 int i1 = -1; \
01423 int i2 = -1; \
01424 int o0 = 0; \
01425 int nz = 0; \
01426 const T *s_in = (const T *) in; \
01427 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
01428 int l_red = LUM_RED; \
01429 int l_green = LUM_GREEN; \
01430 int l_blue = LUM_BLUE; \
01431 const unsigned short *composite; \
01432 const unsigned short *user; \
01433 \
01434 stp_curve_resample \
01435 (stp_curve_cache_get_curve(&(lut->channel_curves[CHANNEL_K])), 65536); \
01436 composite = \
01437 stp_curve_cache_get_ushort_data(&(lut->channel_curves[CHANNEL_K])); \
01438 stp_curve_resample(lut->user_color_correction.curve, 1 << bits); \
01439 user = stp_curve_cache_get_ushort_data(&(lut->user_color_correction)); \
01440 \
01441 if (lut->input_color_description->color_model == COLOR_BLACK) \
01442 { \
01443 l_red = (100 - l_red) / 2; \
01444 l_green = (100 - l_green) / 2; \
01445 l_blue = (100 - l_blue) / 2; \
01446 } \
01447 \
01448 for (i = 0; i < lut->image_width; i++) \
01449 { \
01450 if (i0 != s_in[0] || i1 != s_in[1] || i2 != s_in[2]) \
01451 { \
01452 i0 = s_in[0]; \
01453 i1 = s_in[1]; \
01454 i2 = s_in[2]; \
01455 o0 = \
01456 composite[user[(i0 * l_red + i1 * l_green + i2 * l_blue) / 100]]; \
01457 nz |= o0; \
01458 } \
01459 out[0] = o0; \
01460 s_in += 3; \
01461 out ++; \
01462 } \
01463 return nz == 0; \
01464 }
01465
01466 COLOR_TO_GRAY_FUNC(unsigned char, 8)
01467 COLOR_TO_GRAY_FUNC(unsigned short, 16)
01468 GENERIC_COLOR_FUNC(color, gray)
01469
01470
01471 #define CMYK_TO_GRAY_FUNC(T, bits) \
01472 static unsigned \
01473 cmyk_##bits##_to_gray(const stp_vars_t *vars, \
01474 const unsigned char *in, \
01475 unsigned short *out) \
01476 { \
01477 int i; \
01478 int i0 = -1; \
01479 int i1 = -1; \
01480 int i2 = -1; \
01481 int i3 = -4; \
01482 int o0 = 0; \
01483 int nz = 0; \
01484 const T *s_in = (const T *) in; \
01485 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
01486 int l_red = LUM_RED; \
01487 int l_green = LUM_GREEN; \
01488 int l_blue = LUM_BLUE; \
01489 int l_white = 0; \
01490 const unsigned short *composite; \
01491 const unsigned short *user; \
01492 \
01493 stp_curve_resample \
01494 (stp_curve_cache_get_curve(&(lut->channel_curves[CHANNEL_K])), 65536); \
01495 composite = \
01496 stp_curve_cache_get_ushort_data(&(lut->channel_curves[CHANNEL_K])); \
01497 stp_curve_resample(lut->user_color_correction.curve, 1 << bits); \
01498 user = stp_curve_cache_get_ushort_data(&(lut->user_color_correction)); \
01499 \
01500 if (lut->input_color_description->color_model == COLOR_BLACK) \
01501 { \
01502 l_red = (100 - l_red) / 3; \
01503 l_green = (100 - l_green) / 3; \
01504 l_blue = (100 - l_blue) / 3; \
01505 l_white = (100 - l_white) / 3; \
01506 } \
01507 \
01508 for (i = 0; i < lut->image_width; i++) \
01509 { \
01510 if (i0 != s_in[0] || i1 != s_in[1] || i2 != s_in[2] || i3 != s_in[3]) \
01511 { \
01512 i0 = s_in[0]; \
01513 i1 = s_in[1]; \
01514 i2 = s_in[2]; \
01515 i3 = s_in[3]; \
01516 o0 = composite[user[(i0 * l_red + i1 * l_green + \
01517 i2 * l_blue + i3 * l_white) / 100]]; \
01518 nz |= o0; \
01519 } \
01520 out[0] = o0; \
01521 s_in += 4; \
01522 out ++; \
01523 } \
01524 return nz ? 0 : 1; \
01525 }
01526
01527 CMYK_TO_GRAY_FUNC(unsigned char, 8)
01528 CMYK_TO_GRAY_FUNC(unsigned short, 16)
01529 GENERIC_COLOR_FUNC(cmyk, gray)
01530
01531 #define KCMY_TO_GRAY_FUNC(T, bits) \
01532 static unsigned \
01533 kcmy_##bits##_to_gray(const stp_vars_t *vars, \
01534 const unsigned char *in, \
01535 unsigned short *out) \
01536 { \
01537 int i; \
01538 int i0 = -1; \
01539 int i1 = -1; \
01540 int i2 = -1; \
01541 int i3 = -4; \
01542 int o0 = 0; \
01543 int nz = 0; \
01544 const T *s_in = (const T *) in; \
01545 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
01546 int l_red = LUM_RED; \
01547 int l_green = LUM_GREEN; \
01548 int l_blue = LUM_BLUE; \
01549 int l_white = 0; \
01550 const unsigned short *composite; \
01551 const unsigned short *user; \
01552 \
01553 stp_curve_resample \
01554 (stp_curve_cache_get_curve(&(lut->channel_curves[CHANNEL_K])), 65536); \
01555 composite = \
01556 stp_curve_cache_get_ushort_data(&(lut->channel_curves[CHANNEL_K])); \
01557 stp_curve_resample(lut->user_color_correction.curve, 1 << bits); \
01558 user = stp_curve_cache_get_ushort_data(&(lut->user_color_correction)); \
01559 \
01560 if (lut->input_color_description->color_model == COLOR_BLACK) \
01561 { \
01562 l_red = (100 - l_red) / 3; \
01563 l_green = (100 - l_green) / 3; \
01564 l_blue = (100 - l_blue) / 3; \
01565 l_white = (100 - l_white) / 3; \
01566 } \
01567 \
01568 for (i = 0; i < lut->image_width; i++) \
01569 { \
01570 if (i0 != s_in[0] || i1 != s_in[1] || i2 != s_in[2] || i3 != s_in[3]) \
01571 { \
01572 i0 = s_in[0]; \
01573 i1 = s_in[1]; \
01574 i2 = s_in[2]; \
01575 i3 = s_in[3]; \
01576 o0 = composite[user[(i0 * l_red + i1 * l_green + \
01577 i2 * l_blue + i3 * l_white) / 100]]; \
01578 nz |= o0; \
01579 } \
01580 out[0] = o0; \
01581 s_in += 4; \
01582 out ++; \
01583 } \
01584 return nz ? 0 : 1; \
01585 }
01586
01587 KCMY_TO_GRAY_FUNC(unsigned char, 8)
01588 KCMY_TO_GRAY_FUNC(unsigned short, 16)
01589 GENERIC_COLOR_FUNC(kcmy, gray)
01590
01591 #define GRAY_TO_GRAY_RAW_FUNC(T, bits) \
01592 static unsigned \
01593 gray_##bits##_to_gray_raw(const stp_vars_t *vars, \
01594 const unsigned char *in, \
01595 unsigned short *out) \
01596 { \
01597 int i; \
01598 int nz = 0; \
01599 const T *s_in = (const T *) in; \
01600 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
01601 int width = lut->image_width; \
01602 unsigned mask = 0; \
01603 if (lut->invert_output) \
01604 mask = 0xffff; \
01605 \
01606 memset(out, 0, width * sizeof(unsigned short)); \
01607 \
01608 for (i = 0; i < lut->image_width; i++) \
01609 { \
01610 out[0] = (s_in[0] * (65535 / ((1 << bits) - 1))) ^ mask; \
01611 nz |= out[0]; \
01612 s_in ++; \
01613 out ++; \
01614 } \
01615 return nz == 0; \
01616 }
01617
01618 GRAY_TO_GRAY_RAW_FUNC(unsigned char, 8)
01619 GRAY_TO_GRAY_RAW_FUNC(unsigned short, 16)
01620 GENERIC_COLOR_FUNC(gray, gray_raw)
01621
01622 #define COLOR_TO_GRAY_RAW_FUNC(T, bits, invertable, name2) \
01623 static unsigned \
01624 color_##bits##_to_gray_##name2(const stp_vars_t *vars, \
01625 const unsigned char *in, \
01626 unsigned short *out) \
01627 { \
01628 int i; \
01629 int i0 = -1; \
01630 int i1 = -1; \
01631 int i2 = -1; \
01632 int o0 = 0; \
01633 int nz = 0; \
01634 const T *s_in = (const T *) in; \
01635 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
01636 int l_red = LUM_RED; \
01637 int l_green = LUM_GREEN; \
01638 int l_blue = LUM_BLUE; \
01639 unsigned mask = 0; \
01640 if (lut->invert_output && invertable) \
01641 mask = 0xffff; \
01642 \
01643 if (lut->input_color_description->color_model == COLOR_BLACK) \
01644 { \
01645 l_red = (100 - l_red) / 2; \
01646 l_green = (100 - l_green) / 2; \
01647 l_blue = (100 - l_blue) / 2; \
01648 } \
01649 \
01650 for (i = 0; i < lut->image_width; i++) \
01651 { \
01652 if (i0 != s_in[0] || i1 != s_in[1] || i2 != s_in[2]) \
01653 { \
01654 i0 = s_in[0]; \
01655 i1 = s_in[1]; \
01656 i2 = s_in[2]; \
01657 o0 = (i0 * (65535 / ((1 << bits) - 1)) * l_red + \
01658 i1 * (65535 / ((1 << bits) - 1)) * l_green + \
01659 i2 * (65535 / ((1 << bits) - 1)) * l_blue) / 100; \
01660 o0 ^= mask; \
01661 nz |= o0; \
01662 } \
01663 out[0] = o0; \
01664 s_in += 3; \
01665 out ++; \
01666 } \
01667 return nz == 0; \
01668 }
01669
01670 COLOR_TO_GRAY_RAW_FUNC(unsigned char, 8, 1, raw)
01671 COLOR_TO_GRAY_RAW_FUNC(unsigned short, 16, 1, raw)
01672 GENERIC_COLOR_FUNC(color, gray_raw)
01673 COLOR_TO_GRAY_RAW_FUNC(unsigned char, 8, 0, noninvert)
01674 COLOR_TO_GRAY_RAW_FUNC(unsigned short, 16, 0, noninvert)
01675
01676
01677 #define CMYK_TO_GRAY_RAW_FUNC(T, bits, invertable, name2) \
01678 static unsigned \
01679 cmyk_##bits##_to_gray_##name2(const stp_vars_t *vars, \
01680 const unsigned char *in, \
01681 unsigned short *out) \
01682 { \
01683 int i; \
01684 int i0 = -1; \
01685 int i1 = -1; \
01686 int i2 = -1; \
01687 int i3 = -4; \
01688 int o0 = 0; \
01689 int nz = 0; \
01690 const T *s_in = (const T *) in; \
01691 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
01692 int l_red = LUM_RED; \
01693 int l_green = LUM_GREEN; \
01694 int l_blue = LUM_BLUE; \
01695 int l_white = 0; \
01696 unsigned mask = 0; \
01697 if (lut->invert_output && invertable) \
01698 mask = 0xffff; \
01699 \
01700 if (lut->input_color_description->color_model == COLOR_BLACK) \
01701 { \
01702 l_red = (100 - l_red) / 3; \
01703 l_green = (100 - l_green) / 3; \
01704 l_blue = (100 - l_blue) / 3; \
01705 l_white = (100 - l_white) / 3; \
01706 } \
01707 \
01708 for (i = 0; i < lut->image_width; i++) \
01709 { \
01710 if (i0 != s_in[0] || i1 != s_in[1] || i2 != s_in[2] || i3 != s_in[3]) \
01711 { \
01712 i0 = s_in[0]; \
01713 i1 = s_in[1]; \
01714 i2 = s_in[2]; \
01715 i3 = s_in[3]; \
01716 o0 = (i0 * (65535 / ((1 << bits) - 1)) * l_red + \
01717 i1 * (65535 / ((1 << bits) - 1)) * l_green + \
01718 i2 * (65535 / ((1 << bits) - 1)) * l_blue + \
01719 i3 * (65535 / ((1 << bits) - 1)) * l_white) / 100; \
01720 o0 ^= mask; \
01721 nz |= o0; \
01722 } \
01723 out[0] = o0; \
01724 s_in += 4; \
01725 out ++; \
01726 } \
01727 return nz ? 0 : 1; \
01728 }
01729
01730 CMYK_TO_GRAY_RAW_FUNC(unsigned char, 8, 1, raw)
01731 CMYK_TO_GRAY_RAW_FUNC(unsigned short, 16, 1, raw)
01732 GENERIC_COLOR_FUNC(cmyk, gray_raw)
01733 CMYK_TO_GRAY_RAW_FUNC(unsigned char, 8, 0, noninvert)
01734 CMYK_TO_GRAY_RAW_FUNC(unsigned short, 16, 0, noninvert)
01735
01736 #define KCMY_TO_GRAY_RAW_FUNC(T, bits, invertable, name2) \
01737 static unsigned \
01738 kcmy_##bits##_to_gray_##name2(const stp_vars_t *vars, \
01739 const unsigned char *in, \
01740 unsigned short *out) \
01741 { \
01742 int i; \
01743 int i0 = -1; \
01744 int i1 = -1; \
01745 int i2 = -1; \
01746 int i3 = -4; \
01747 int o0 = 0; \
01748 int nz = 0; \
01749 const T *s_in = (const T *) in; \
01750 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
01751 int l_red = LUM_RED; \
01752 int l_green = LUM_GREEN; \
01753 int l_blue = LUM_BLUE; \
01754 int l_white = 0; \
01755 unsigned mask = 0; \
01756 if (lut->invert_output && invertable) \
01757 mask = 0xffff; \
01758 \
01759 if (lut->input_color_description->color_model == COLOR_BLACK) \
01760 { \
01761 l_red = (100 - l_red) / 3; \
01762 l_green = (100 - l_green) / 3; \
01763 l_blue = (100 - l_blue) / 3; \
01764 l_white = (100 - l_white) / 3; \
01765 } \
01766 \
01767 for (i = 0; i < lut->image_width; i++) \
01768 { \
01769 if (i0 != s_in[0] || i1 != s_in[1] || i2 != s_in[2] || i3 != s_in[3]) \
01770 { \
01771 i0 = s_in[0]; \
01772 i1 = s_in[1]; \
01773 i2 = s_in[2]; \
01774 i3 = s_in[3]; \
01775 o0 = (i0 * (65535 / ((1 << bits) - 1)) * l_white + \
01776 i1 * (65535 / ((1 << bits) - 1)) * l_red + \
01777 i2 * (65535 / ((1 << bits) - 1)) * l_green + \
01778 i3 * (65535 / ((1 << bits) - 1)) * l_blue) / 100; \
01779 o0 ^= mask; \
01780 nz |= o0; \
01781 } \
01782 out[0] = o0; \
01783 s_in += 4; \
01784 out ++; \
01785 } \
01786 return nz ? 0 : 1; \
01787 }
01788
01789 KCMY_TO_GRAY_RAW_FUNC(unsigned char, 8, 1, raw)
01790 KCMY_TO_GRAY_RAW_FUNC(unsigned short, 16, 1, raw)
01791 GENERIC_COLOR_FUNC(kcmy, gray_raw)
01792 KCMY_TO_GRAY_RAW_FUNC(unsigned char, 8, 0, noninvert)
01793 KCMY_TO_GRAY_RAW_FUNC(unsigned short, 16, 0, noninvert)
01794
01795 #define CMYK_TO_KCMY_RAW_FUNC(T, bits) \
01796 static unsigned \
01797 cmyk_##bits##_to_kcmy_raw(const stp_vars_t *vars, \
01798 const unsigned char *in, \
01799 unsigned short *out) \
01800 { \
01801 int i; \
01802 int j; \
01803 int nz[4]; \
01804 unsigned retval = 0; \
01805 const T *s_in = (const T *) in; \
01806 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
01807 \
01808 memset(nz, 0, sizeof(nz)); \
01809 for (i = 0; i < lut->image_width; i++) \
01810 { \
01811 out[0] = s_in[3] * (65535 / ((1 << bits) - 1)); \
01812 out[1] = s_in[0] * (65535 / ((1 << bits) - 1)); \
01813 out[2] = s_in[1] * (65535 / ((1 << bits) - 1)); \
01814 out[3] = s_in[2] * (65535 / ((1 << bits) - 1)); \
01815 for (j = 0; j < 4; j++) \
01816 nz[j] |= out[j]; \
01817 s_in += 4; \
01818 out += 4; \
01819 } \
01820 for (j = 0; j < 4; j++) \
01821 if (nz[j] == 0) \
01822 retval |= (1 << j); \
01823 return retval; \
01824 }
01825
01826 CMYK_TO_KCMY_RAW_FUNC(unsigned char, 8)
01827 CMYK_TO_KCMY_RAW_FUNC(unsigned short, 16)
01828 GENERIC_COLOR_FUNC(cmyk, kcmy_raw)
01829
01830 #define KCMY_TO_KCMY_RAW_FUNC(T, bits) \
01831 static unsigned \
01832 kcmy_##bits##_to_kcmy_raw(const stp_vars_t *vars, \
01833 const unsigned char *in, \
01834 unsigned short *out) \
01835 { \
01836 int i; \
01837 int j; \
01838 int nz[4]; \
01839 unsigned retval = 0; \
01840 const T *s_in = (const T *) in; \
01841 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
01842 \
01843 memset(nz, 0, sizeof(nz)); \
01844 for (i = 0; i < lut->image_width; i++) \
01845 { \
01846 for (j = 0; j < 4; j++) \
01847 { \
01848 out[j] = s_in[j] * (65535 / ((1 << bits) - 1)); \
01849 nz[j] |= out[j]; \
01850 } \
01851 s_in += 4; \
01852 out += 4; \
01853 } \
01854 for (j = 0; j < 4; j++) \
01855 if (nz[j] == 0) \
01856 retval |= (1 << j); \
01857 return retval; \
01858 }
01859
01860 KCMY_TO_KCMY_RAW_FUNC(unsigned char, 8)
01861 KCMY_TO_KCMY_RAW_FUNC(unsigned short, 16)
01862 GENERIC_COLOR_FUNC(kcmy, kcmy_raw)
01863
01864 static unsigned
01865 generic_kcmy_to_cmykrb(const stp_vars_t *vars, const unsigned short *in,
01866 unsigned short *out)
01867 {
01868 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color"));
01869 unsigned short nz[6];
01870 int width = lut->image_width;
01871 const unsigned short *input_cache = NULL;
01872 const unsigned short *output_cache = NULL;
01873 int i, j;
01874 unsigned retval = 0;
01875
01876 memset(nz, 0, sizeof(nz));
01877
01878 for (i = 0; i < width; i++, out += 6, in += 4)
01879 {
01880 if (input_cache && short_eq(input_cache, in, 4))
01881 short_copy(out, output_cache, 6);
01882 else
01883 {
01884 int r = FMIN(in[2], in[3]);
01885 int b = FMIN(in[1], in[2]);
01886 int k = in[0];
01887 int excess_r = r - (b + k);
01888 int excess_b = b - (r + k);
01889 input_cache = in;
01890 for (j = 0; j < 4; j++)
01891 {
01892 out[j] = in[j];
01893 if (in[j])
01894 nz[j] = 1;
01895 }
01896 if (excess_r > 0)
01897 {
01898 out[2] -= excess_r;
01899 out[3] -= excess_r;
01900 out[4] = excess_r;
01901 out[5] = 0;
01902 nz[4] = 1;
01903 }
01904 else if (excess_b > 0)
01905 {
01906 out[1] -= excess_b;
01907 out[2] -= excess_b;
01908 out[4] = 0;
01909 out[5] = excess_b;
01910 nz[5] = 1;
01911 }
01912 else
01913 {
01914 out[4] = 0;
01915 out[5] = 0;
01916 }
01917 output_cache = out;
01918 }
01919 }
01920 for (j = 0; j < 6; j++)
01921 if (nz[j] == 0)
01922 retval |= (1 << j);
01923 return retval;
01924 }
01925
01926 static unsigned
01927 raw_kcmy_to_cmykrb(const stp_vars_t *vars, const unsigned short *in,
01928 unsigned short *out)
01929 {
01930 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color"));
01931 unsigned short nz[6];
01932 int width = lut->image_width;
01933 const unsigned short *input_cache = NULL;
01934 const unsigned short *output_cache = NULL;
01935 int i, j;
01936 unsigned retval = 0;
01937
01938 memset(nz, 0, sizeof(nz));
01939
01940 for (i = 0; i < width; i++, out += 6, in += 4)
01941 {
01942 if (input_cache && short_eq(input_cache, in, 4))
01943 short_copy(out, output_cache, 6);
01944 else
01945 {
01946 int r = FMIN(in[2], in[3]);
01947 int b = FMIN(in[1], in[2]);
01948 int k = in[0];
01949 int excess_r = r - (b + k);
01950 int excess_b = b - (r + k);
01951 input_cache = in;
01952 for (j = 0; j < 4; j++)
01953 {
01954 out[j] = in[j];
01955 if (in[j])
01956 nz[j] = 1;
01957 }
01958 if (excess_r > 0)
01959 {
01960 out[2] -= excess_r;
01961 out[3] -= excess_r;
01962 out[4] = excess_r;
01963 out[5] = 0;
01964 nz[4] = 1;
01965 }
01966 else if (excess_b > 0)
01967 {
01968 out[1] -= excess_b;
01969 out[2] -= excess_b;
01970 out[4] = 0;
01971 out[5] = excess_b;
01972 nz[5] = 1;
01973 }
01974 else
01975 {
01976 out[4] = 0;
01977 out[5] = 0;
01978 }
01979 output_cache = out;
01980 }
01981 }
01982 for (j = 0; j < 6; j++)
01983 if (nz[j] == 0)
01984 retval |= (1 << j);
01985 return retval;
01986 }
01987
01988 #define COLOR_TO_CMYKRB_FUNC(name, name2, name3, name4, bits) \
01989 static unsigned \
01990 name##_##bits##_to_##name2(const stp_vars_t *vars, const unsigned char *in, \
01991 unsigned short *out) \
01992 { \
01993 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
01994 size_t real_steps = lut->steps; \
01995 unsigned status; \
01996 if (!lut->cmyk_tmp) \
01997 lut->cmyk_tmp = stp_malloc(4 * 2 * lut->image_width); \
01998 name##_##bits##_to_##name3(vars, in, lut->cmyk_tmp); \
01999 lut->steps = 65536; \
02000 status = name4##_kcmy_to_cmykrb(vars, lut->cmyk_tmp, out); \
02001 lut->steps = real_steps; \
02002 return status; \
02003 }
02004
02005 COLOR_TO_CMYKRB_FUNC(gray, cmykrb, kcmy, generic, 8)
02006 COLOR_TO_CMYKRB_FUNC(gray, cmykrb, kcmy, generic, 16)
02007 GENERIC_COLOR_FUNC(gray, cmykrb)
02008 COLOR_TO_CMYKRB_FUNC(gray, cmykrb_threshold, kcmy_threshold, generic, 8)
02009 COLOR_TO_CMYKRB_FUNC(gray, cmykrb_threshold, kcmy_threshold, generic, 16)
02010 GENERIC_COLOR_FUNC(gray, cmykrb_threshold)
02011 COLOR_TO_CMYKRB_FUNC(gray, cmykrb_raw, kcmy_raw, raw, 8)
02012 COLOR_TO_CMYKRB_FUNC(gray, cmykrb_raw, kcmy_raw, raw, 16)
02013 GENERIC_COLOR_FUNC(gray, cmykrb_raw)
02014
02015 COLOR_TO_CMYKRB_FUNC(color, cmykrb, kcmy, generic, 8)
02016 COLOR_TO_CMYKRB_FUNC(color, cmykrb, kcmy, generic, 16)
02017 GENERIC_COLOR_FUNC(color, cmykrb)
02018 COLOR_TO_CMYKRB_FUNC(color, cmykrb_threshold, kcmy_threshold, generic, 8)
02019 COLOR_TO_CMYKRB_FUNC(color, cmykrb_threshold, kcmy_threshold, generic, 16)
02020 GENERIC_COLOR_FUNC(color, cmykrb_threshold)
02021 COLOR_TO_CMYKRB_FUNC(color, cmykrb_fast, kcmy, generic, 8)
02022 COLOR_TO_CMYKRB_FUNC(color, cmykrb_fast, kcmy, generic, 16)
02023 GENERIC_COLOR_FUNC(color, cmykrb_fast)
02024 COLOR_TO_CMYKRB_FUNC(color, cmykrb_raw, kcmy_raw, raw, 8)
02025 COLOR_TO_CMYKRB_FUNC(color, cmykrb_raw, kcmy_raw, raw, 16)
02026 GENERIC_COLOR_FUNC(color, cmykrb_raw)
02027
02028 COLOR_TO_CMYKRB_FUNC(cmyk, cmykrb, kcmy, generic, 8)
02029 COLOR_TO_CMYKRB_FUNC(cmyk, cmykrb, kcmy, generic, 16)
02030 GENERIC_COLOR_FUNC(cmyk, cmykrb)
02031 COLOR_TO_CMYKRB_FUNC(cmyk, cmykrb_threshold, kcmy_threshold, generic, 8)
02032 COLOR_TO_CMYKRB_FUNC(cmyk, cmykrb_threshold, kcmy_threshold, generic, 16)
02033 GENERIC_COLOR_FUNC(cmyk, cmykrb_threshold)
02034 COLOR_TO_CMYKRB_FUNC(cmyk, cmykrb_fast, kcmy, generic, 8)
02035 COLOR_TO_CMYKRB_FUNC(cmyk, cmykrb_fast, kcmy, generic, 16)
02036 GENERIC_COLOR_FUNC(cmyk, cmykrb_fast)
02037 COLOR_TO_CMYKRB_FUNC(cmyk, cmykrb_raw, kcmy_raw, raw, 8)
02038 COLOR_TO_CMYKRB_FUNC(cmyk, cmykrb_raw, kcmy_raw, raw, 16)
02039 GENERIC_COLOR_FUNC(cmyk, cmykrb_raw)
02040
02041 COLOR_TO_CMYKRB_FUNC(kcmy, cmykrb, kcmy, generic, 8)
02042 COLOR_TO_CMYKRB_FUNC(kcmy, cmykrb, kcmy, generic, 16)
02043 GENERIC_COLOR_FUNC(kcmy, cmykrb)
02044 COLOR_TO_CMYKRB_FUNC(kcmy, cmykrb_threshold, kcmy_threshold, generic, 8)
02045 COLOR_TO_CMYKRB_FUNC(kcmy, cmykrb_threshold, kcmy_threshold, generic, 16)
02046 GENERIC_COLOR_FUNC(kcmy, cmykrb_threshold)
02047 COLOR_TO_CMYKRB_FUNC(kcmy, cmykrb_fast, kcmy, generic, 8)
02048 COLOR_TO_CMYKRB_FUNC(kcmy, cmykrb_fast, kcmy, generic, 16)
02049 GENERIC_COLOR_FUNC(kcmy, cmykrb_fast)
02050 COLOR_TO_CMYKRB_FUNC(kcmy, cmykrb_raw, kcmy_raw, raw, 8)
02051 COLOR_TO_CMYKRB_FUNC(kcmy, cmykrb_raw, kcmy_raw, raw, 16)
02052 GENERIC_COLOR_FUNC(kcmy, cmykrb_raw)
02053
02054 #define DESATURATED_FUNC(name, name2, bits) \
02055 static unsigned \
02056 name##_##bits##_to_##name2##_desaturated(const stp_vars_t *vars, \
02057 const unsigned char *in, \
02058 unsigned short *out) \
02059 { \
02060 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
02061 size_t real_steps = lut->steps; \
02062 unsigned status; \
02063 if (!lut->gray_tmp) \
02064 lut->gray_tmp = stp_malloc(2 * lut->image_width); \
02065 name##_##bits##_to_gray_noninvert(vars, in, lut->gray_tmp); \
02066 lut->steps = 65536; \
02067 status = gray_16_to_##name2(vars, (unsigned char *) lut->gray_tmp, out); \
02068 lut->steps = real_steps; \
02069 return status; \
02070 }
02071
02072 DESATURATED_FUNC(color, color, 8)
02073 DESATURATED_FUNC(color, color, 16)
02074 GENERIC_COLOR_FUNC(color, color_desaturated)
02075 DESATURATED_FUNC(color, kcmy, 8)
02076 DESATURATED_FUNC(color, kcmy, 16)
02077 GENERIC_COLOR_FUNC(color, kcmy_desaturated)
02078 DESATURATED_FUNC(color, cmykrb, 8)
02079 DESATURATED_FUNC(color, cmykrb, 16)
02080 GENERIC_COLOR_FUNC(color, cmykrb_desaturated)
02081
02082 DESATURATED_FUNC(cmyk, color, 8)
02083 DESATURATED_FUNC(cmyk, color, 16)
02084 GENERIC_COLOR_FUNC(cmyk, color_desaturated)
02085 DESATURATED_FUNC(cmyk, kcmy, 8)
02086 DESATURATED_FUNC(cmyk, kcmy, 16)
02087 GENERIC_COLOR_FUNC(cmyk, kcmy_desaturated)
02088 DESATURATED_FUNC(cmyk, cmykrb, 8)
02089 DESATURATED_FUNC(cmyk, cmykrb, 16)
02090 GENERIC_COLOR_FUNC(cmyk, cmykrb_desaturated)
02091
02092 DESATURATED_FUNC(kcmy, color, 8)
02093 DESATURATED_FUNC(kcmy, color, 16)
02094 GENERIC_COLOR_FUNC(kcmy, color_desaturated)
02095 DESATURATED_FUNC(kcmy, kcmy, 8)
02096 DESATURATED_FUNC(kcmy, kcmy, 16)
02097 GENERIC_COLOR_FUNC(kcmy, kcmy_desaturated)
02098 DESATURATED_FUNC(kcmy, cmykrb, 8)
02099 DESATURATED_FUNC(kcmy, cmykrb, 16)
02100 GENERIC_COLOR_FUNC(kcmy, cmykrb_desaturated)
02101
02102 #define CMYK_DISPATCH(name) \
02103 static unsigned \
02104 CMYK_to_##name(const stp_vars_t *vars, const unsigned char *in, \
02105 unsigned short *out) \
02106 { \
02107 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
02108 if (lut->input_color_description->color_id == COLOR_ID_CMYK) \
02109 return cmyk_to_##name(vars, in, out); \
02110 else if (lut->input_color_description->color_id == COLOR_ID_KCMY) \
02111 return kcmy_to_##name(vars, in, out); \
02112 else \
02113 { \
02114 stp_eprintf(vars, "Bad dispatch to CMYK_to_%s: %d\n", #name, \
02115 lut->input_color_description->color_id); \
02116 return 0; \
02117 } \
02118 }
02119
02120 CMYK_DISPATCH(cmykrb)
02121 CMYK_DISPATCH(cmykrb_raw)
02122 CMYK_DISPATCH(cmykrb_fast)
02123 CMYK_DISPATCH(cmykrb_threshold)
02124 CMYK_DISPATCH(cmykrb_desaturated)
02125 CMYK_DISPATCH(color)
02126 CMYK_DISPATCH(color_raw)
02127 CMYK_DISPATCH(color_fast)
02128 CMYK_DISPATCH(color_threshold)
02129 CMYK_DISPATCH(color_desaturated)
02130 CMYK_DISPATCH(kcmy)
02131 CMYK_DISPATCH(kcmy_raw)
02132 CMYK_DISPATCH(kcmy_threshold)
02133 CMYK_DISPATCH(kcmy_desaturated)
02134 CMYK_DISPATCH(gray)
02135 CMYK_DISPATCH(gray_raw)
02136 CMYK_DISPATCH(gray_threshold)
02137
02138 #define RAW_TO_RAW_THRESHOLD_FUNC(T, name) \
02139 static unsigned \
02140 name##_to_raw_threshold(const stp_vars_t *vars, \
02141 const unsigned char *in, \
02142 unsigned short *out) \
02143 { \
02144 int i; \
02145 int j; \
02146 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
02147 unsigned nz[STP_CHANNEL_LIMIT]; \
02148 unsigned z = (1 << lut->out_channels) - 1; \
02149 const T *s_in = (const T *) in; \
02150 unsigned desired_high_bit = 0; \
02151 unsigned high_bit = 1 << ((sizeof(T) * 8) - 1); \
02152 int width = lut->image_width; \
02153 memset(out, 0, width * lut->out_channels * sizeof(unsigned short)); \
02154 if (!lut->invert_output) \
02155 desired_high_bit = high_bit; \
02156 for (i = 0; i < lut->out_channels; i++) \
02157 nz[i] = z & ~(1 << i); \
02158 \
02159 for (i = 0; i < width; i++) \
02160 { \
02161 for (j = 0; j < lut->out_channels; j++) \
02162 { \
02163 if ((*s_in++ & high_bit) == desired_high_bit) \
02164 { \
02165 z &= nz[j]; \
02166 *out = 65535; \
02167 } \
02168 out++; \
02169 } \
02170 } \
02171 return z; \
02172 }
02173
02174 RAW_TO_RAW_THRESHOLD_FUNC(unsigned char, raw_8)
02175 RAW_TO_RAW_THRESHOLD_FUNC(unsigned short, raw_16)
02176 GENERIC_COLOR_FUNC(raw, raw_threshold)
02177
02178 #define RAW_TO_RAW_FUNC(T, size) \
02179 static unsigned \
02180 raw_##size##_to_raw(const stp_vars_t *vars, \
02181 const unsigned char *in, \
02182 unsigned short *out) \
02183 { \
02184 int i; \
02185 unsigned retval = 0; \
02186 int j; \
02187 int nz[STP_CHANNEL_LIMIT]; \
02188 const T *s_in = (const T *) in; \
02189 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
02190 const unsigned short *maps[STP_CHANNEL_LIMIT]; \
02191 const unsigned short *user; \
02192 \
02193 for (i = 0; i < lut->out_channels; i++) \
02194 { \
02195 stp_curve_resample(lut->channel_curves[i].curve, 65536); \
02196 maps[i] = stp_curve_cache_get_ushort_data(&(lut->channel_curves[i])); \
02197 } \
02198 stp_curve_resample(lut->user_color_correction.curve, 1 << size); \
02199 user = stp_curve_cache_get_ushort_data(&(lut->user_color_correction)); \
02200 \
02201 memset(nz, 0, sizeof(nz)); \
02202 \
02203 for (i = 0; i < lut->image_width; i++, out += lut->out_channels) \
02204 { \
02205 for (j = 0; j < lut->out_channels; j++) \
02206 { \
02207 int inval = *s_in++; \
02208 nz[j] |= inval; \
02209 out[j] = maps[j][user[inval]]; \
02210 } \
02211 } \
02212 for (j = 0; j < lut->out_channels; j++) \
02213 if (nz[j] == 0) \
02214 retval |= (1 << j); \
02215 return retval; \
02216 }
02217
02218 RAW_TO_RAW_FUNC(unsigned char, 8)
02219 RAW_TO_RAW_FUNC(unsigned short, 16)
02220 GENERIC_COLOR_FUNC(raw, raw)
02221
02222
02223 #define RAW_TO_RAW_RAW_FUNC(T, bits) \
02224 static unsigned \
02225 raw_##bits##_to_raw_raw(const stp_vars_t *vars, \
02226 const unsigned char *in, \
02227 unsigned short *out) \
02228 { \
02229 int i; \
02230 int j; \
02231 int nz[STP_CHANNEL_LIMIT]; \
02232 unsigned retval = 0; \
02233 const T *s_in = (const T *) in; \
02234 lut_t *lut = (lut_t *)(stp_get_component_data(vars, "Color")); \
02235 int colors = lut->in_channels; \
02236 \
02237 memset(nz, 0, sizeof(nz)); \
02238 for (i = 0; i < lut->image_width; i++) \
02239 { \
02240 for (j = 0; j < colors; j++) \
02241 { \
02242 nz[j] |= s_in[j]; \
02243 out[j] = s_in[j] * (65535 / ((1 << bits) - 1)); \
02244 } \
02245 s_in += colors; \
02246 out += colors; \
02247 } \
02248 for (j = 0; j < colors; j++) \
02249 if (nz[j] == 0) \
02250 retval |= (1 << j); \
02251 return retval; \
02252 }
02253
02254 RAW_TO_RAW_RAW_FUNC(unsigned char, 8)
02255 RAW_TO_RAW_RAW_FUNC(unsigned short, 16)
02256 GENERIC_COLOR_FUNC(raw, raw_raw)
02257
02258
02259 #define CONVERSION_FUNCTION_WITH_FAST(from, to, from2) \
02260 static unsigned \
02261 generic_##from##_to_##to(const stp_vars_t *v, \
02262 const unsigned char *in, \
02263 unsigned short *out) \
02264 { \
02265 lut_t *lut = (lut_t *)(stp_get_component_data(v, "Color")); \
02266 switch (lut->color_correction->correction) \
02267 { \
02268 case COLOR_CORRECTION_UNCORRECTED: \
02269 return from2##_to_##to##_fast(v, in, out); \
02270 case COLOR_CORRECTION_ACCURATE: \
02271 case COLOR_CORRECTION_BRIGHT: \
02272 return from2##_to_##to(v, in, out); \
02273 case COLOR_CORRECTION_DESATURATED: \
02274 return from2##_to_##to##_desaturated(v, in, out); \
02275 case COLOR_CORRECTION_THRESHOLD: \
02276 case COLOR_CORRECTION_PREDITHERED: \
02277 return from2##_to_##to##_threshold(v, in, out); \
02278 case COLOR_CORRECTION_DENSITY: \
02279 case COLOR_CORRECTION_RAW: \
02280 return from2##_to_##to##_raw(v, in, out); \
02281 default: \
02282 return (unsigned) -1; \
02283 } \
02284 }
02285
02286 #define CONVERSION_FUNCTION_WITHOUT_FAST(from, to, from2) \
02287 static unsigned \
02288 generic_##from##_to_##to(const stp_vars_t *v, \
02289 const unsigned char *in, \
02290 unsigned short *out) \
02291 { \
02292 lut_t *lut = (lut_t *)(stp_get_component_data(v, "Color")); \
02293 switch (lut->color_correction->correction) \
02294 { \
02295 case COLOR_CORRECTION_UNCORRECTED: \
02296 case COLOR_CORRECTION_ACCURATE: \
02297 case COLOR_CORRECTION_BRIGHT: \
02298 return from2##_to_##to(v, in, out); \
02299 case COLOR_CORRECTION_DESATURATED: \
02300 return from2##_to_##to##_desaturated(v, in, out); \
02301 case COLOR_CORRECTION_THRESHOLD: \
02302 case COLOR_CORRECTION_PREDITHERED: \
02303 return from2##_to_##to##_threshold(v, in, out); \
02304 case COLOR_CORRECTION_DENSITY: \
02305 case COLOR_CORRECTION_RAW: \
02306 return from2##_to_##to##_raw(v, in, out); \
02307 default: \
02308 return (unsigned) -1; \
02309 } \
02310 }
02311
02312 #define CONVERSION_FUNCTION_WITHOUT_DESATURATED(from, to, from2) \
02313 static unsigned \
02314 generic_##from##_to_##to(const stp_vars_t *v, \
02315 const unsigned char *in, \
02316 unsigned short *out) \
02317 { \
02318 lut_t *lut = (lut_t *)(stp_get_component_data(v, "Color")); \
02319 switch (lut->color_correction->correction) \
02320 { \
02321 case COLOR_CORRECTION_UNCORRECTED: \
02322 case COLOR_CORRECTION_ACCURATE: \
02323 case COLOR_CORRECTION_BRIGHT: \
02324 case COLOR_CORRECTION_DESATURATED: \
02325 return from2##_to_##to(v, in, out); \
02326 case COLOR_CORRECTION_THRESHOLD: \
02327 case COLOR_CORRECTION_PREDITHERED: \
02328 return from2##_to_##to##_threshold(v, in, out); \
02329 case COLOR_CORRECTION_DENSITY: \
02330 case COLOR_CORRECTION_RAW: \
02331 return from2##_to_##to##_raw(v, in, out); \
02332 default: \
02333 return (unsigned) -1; \
02334 } \
02335 }
02336
02337 CONVERSION_FUNCTION_WITH_FAST(cmyk, color, CMYK)
02338 CONVERSION_FUNCTION_WITH_FAST(cmyk, cmykrb, CMYK)
02339 CONVERSION_FUNCTION_WITH_FAST(color, color, color)
02340 CONVERSION_FUNCTION_WITH_FAST(color, cmykrb, color)
02341 CONVERSION_FUNCTION_WITH_FAST(color, kcmy, color)
02342 CONVERSION_FUNCTION_WITHOUT_FAST(cmyk, kcmy, CMYK)
02343 CONVERSION_FUNCTION_WITHOUT_DESATURATED(cmyk, gray, CMYK)
02344 CONVERSION_FUNCTION_WITHOUT_DESATURATED(color, gray, color)
02345 CONVERSION_FUNCTION_WITHOUT_DESATURATED(gray, gray, gray)
02346 CONVERSION_FUNCTION_WITHOUT_DESATURATED(gray, color, gray)
02347 CONVERSION_FUNCTION_WITHOUT_DESATURATED(gray, kcmy, gray)
02348 CONVERSION_FUNCTION_WITHOUT_DESATURATED(gray, cmykrb, gray)
02349
02350 unsigned
02351 stpi_color_convert_to_gray(const stp_vars_t *v,
02352 const unsigned char *in,
02353 unsigned short *out)
02354 {
02355 lut_t *lut = (lut_t *)(stp_get_component_data(v, "Color"));
02356 switch (lut->input_color_description->color_id)
02357 {
02358 case COLOR_ID_GRAY:
02359 case COLOR_ID_WHITE:
02360 return generic_gray_to_gray(v, in, out);
02361 case COLOR_ID_RGB:
02362 case COLOR_ID_CMY:
02363 return generic_color_to_gray(v, in, out);
02364 case COLOR_ID_CMYK:
02365 case COLOR_ID_KCMY:
02366 return generic_cmyk_to_gray(v, in, out);
02367 default:
02368 return (unsigned) -1;
02369 }
02370 }
02371
02372 unsigned
02373 stpi_color_convert_to_color(const stp_vars_t *v,
02374 const unsigned char *in,
02375 unsigned short *out)
02376 {
02377 lut_t *lut = (lut_t *)(stp_get_component_data(v, "Color"));
02378 switch (lut->input_color_description->color_id)
02379 {
02380 case COLOR_ID_GRAY:
02381 case COLOR_ID_WHITE:
02382 return generic_gray_to_color(v, in, out);
02383 case COLOR_ID_RGB:
02384 case COLOR_ID_CMY:
02385 return generic_color_to_color(v, in, out);
02386 case COLOR_ID_CMYK:
02387 case COLOR_ID_KCMY:
02388 return generic_cmyk_to_color(v, in, out);
02389 default:
02390 return (unsigned) -1;
02391 }
02392 }
02393
02394 unsigned
02395 stpi_color_convert_to_kcmy(const stp_vars_t *v,
02396 const unsigned char *in,
02397 unsigned short *out)
02398 {
02399 lut_t *lut = (lut_t *)(stp_get_component_data(v, "Color"));
02400 switch (lut->input_color_description->color_id)
02401 {
02402 case COLOR_ID_GRAY:
02403 case COLOR_ID_WHITE:
02404 return generic_gray_to_kcmy(v, in, out);
02405 case COLOR_ID_RGB:
02406 case COLOR_ID_CMY:
02407 return generic_color_to_kcmy(v, in, out);
02408 case COLOR_ID_CMYK:
02409 case COLOR_ID_KCMY:
02410 return generic_cmyk_to_kcmy(v, in, out);
02411 default:
02412 return (unsigned) -1;
02413 }
02414 }
02415
02416 unsigned
02417 stpi_color_convert_to_cmykrb(const stp_vars_t *v,
02418 const unsigned char *in,
02419 unsigned short *out)
02420 {
02421 lut_t *lut = (lut_t *)(stp_get_component_data(v, "Color"));
02422 switch (lut->input_color_description->color_id)
02423 {
02424 case COLOR_ID_GRAY:
02425 case COLOR_ID_WHITE:
02426 return generic_gray_to_cmykrb(v, in, out);
02427 case COLOR_ID_RGB:
02428 case COLOR_ID_CMY:
02429 return generic_color_to_cmykrb(v, in, out);
02430 case COLOR_ID_CMYK:
02431 case COLOR_ID_KCMY:
02432 return generic_cmyk_to_cmykrb(v, in, out);
02433 default:
02434 return (unsigned) -1;
02435 }
02436 }
02437
02438 unsigned
02439 stpi_color_convert_raw(const stp_vars_t *v,
02440 const unsigned char *in,
02441 unsigned short *out)
02442 {
02443 lut_t *lut = (lut_t *)(stp_get_component_data(v, "Color"));
02444 switch (lut->color_correction->correction)
02445 {
02446 case COLOR_CORRECTION_THRESHOLD:
02447 case COLOR_CORRECTION_PREDITHERED:
02448 return raw_to_raw_threshold(v, in, out);
02449 case COLOR_CORRECTION_UNCORRECTED:
02450 case COLOR_CORRECTION_BRIGHT:
02451 case COLOR_CORRECTION_ACCURATE:
02452 case COLOR_CORRECTION_DESATURATED:
02453 return raw_to_raw(v, in, out);
02454 case COLOR_CORRECTION_RAW:
02455 case COLOR_CORRECTION_DEFAULT:
02456 case COLOR_CORRECTION_DENSITY:
02457 return raw_to_raw_raw(v, in, out);
02458 default:
02459 return (unsigned) -1;
02460 }
02461 }