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