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

color-conversions.c

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

Generated on Thu Feb 10 19:29:30 2005 for libgutenprint API Reference by  doxygen 1.4.1