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.c,v 1.11 2004/07/24 02:07:21 rlk 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 }

Generated on Wed Aug 25 07:56:13 2004 for libgimpprint API Reference by doxygen 1.3.6