Main Page   Modules   Alphabetical List   Data Structures   File List   Data Fields   Globals  

src/main/color-conversions.c

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

Generated on Wed May 12 20:21:28 2004 for libgimpprint API Reference by doxygen1.2.17