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