libgimpprint API Reference: src/main/color-conversions.c Source File

Main Page | Modules | Alphabetical List | Data Structures | File List | Data Fields | Globals | Related Pages

# src/main/color-conversions.c

Go to the documentation of this file.

    00001 /*
    00002  * "$Id: color-conversions_8c-source.html,v 1.1.1.2 2004/12/22 23:48:56 jlovell Exp $"
    00003  *
    00004  *   Gimp-Print color management module - traditional Gimp-Print algorithm.
    00005  *
    00006  *   Copyright 1997-2000 Michael Sweet (mike@easysw.com) and
    00007  *      Robert Krawitz (rlk@alum.mit.edu)
    00008  *
    00009  *   This program is free software; you can redistribute it and/or modify it
    00010  *   under the terms of the GNU General Public License as published by the Free
    00011  *   Software Foundation; either version 2 of the License, or (at your option)
    00012  *   any later version.
    00013  *
    00014  *   This program is distributed in the hope that it will be useful, but
    00015  *   WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
    00016  *   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    00017  *   for more details.
    00018  *
    00019  *   You should have received a copy of the GNU General Public License
    00020  *   along with this program; if not, write to the Free Software
    00021  *   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
    00022  */
    00023
    00024 /*
    00025  * This file must include only standard C header files.  The core code must
    00026  * compile on generic platforms that don't support glib, gimp, gtk, etc.
    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  * RGB to grayscale luminance constants...
    00049  */
    00050
    00051 #define LUM_RED         31
    00052 #define LUM_GREEN       61
    00053 #define LUM_BLUE        8
    00054
    00055 /* rgb/hsl conversions taken from Gimp common/autostretch_hsv.c */
    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)  /* Suggested by Eugene Anikin <eugene@anikin.com> */
    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                 s *= isadj * sisadj;
    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               /*                  s *= sqrt(isadj); */
    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); /* 1 or 257 */
    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  * 'rgb_to_rgb()' - Convert rgb image data to RGB.
    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  * 'gray_to_rgb()' - Convert gray image data to RGB.
    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 }