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

src/main/print-color-new.c

Go to the documentation of this file.
00001 /*
00002  * "$Id: print-color.c,v 1.101 2003/10/17 03:02:20 rlk Exp $"
00003  *
00004  *   Gimp-Print color management module - traditional Gimp-Print algorithm.
00005  *
00006  *   Copyright 1997-2000 Michael Sweet (mike@easysw.com) and
00007  *      Robert Krawitz (rlk@alum.mit.edu)
00008  *
00009  *   This program is free software; you can redistribute it and/or modify it
00010  *   under the terms of the GNU General Public License as published by the Free
00011  *   Software Foundation; either version 2 of the License, or (at your option)
00012  *   any later version.
00013  *
00014  *   This program is distributed in the hope that it will be useful, but
00015  *   WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
00016  *   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00017  *   for more details.
00018  *
00019  *   You should have received a copy of the GNU General Public License
00020  *   along with this program; if not, write to the Free Software
00021  *   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00022  */
00023 
00024 /*
00025  * This file must include only standard C header files.  The core code must
00026  * compile on generic platforms that don't support glib, gimp, gtk, etc.
00027  */
00028 
00029 #ifdef HAVE_CONFIG_H
00030 #include <config.h>
00031 #endif
00032 #include <gimp-print/gimp-print.h>
00033 #include "gimp-print-internal.h"
00034 #include <gimp-print/gimp-print-intl-internal.h>
00035 #include <math.h>
00036 #ifdef HAVE_LIMITS_H
00037 #include <limits.h>
00038 #endif
00039 #include <string.h>
00040 #include "module.h"
00041 #include "xml.h"
00042 
00043 #ifdef __GNUC__
00044 #define inline __inline__
00045 #endif
00046 
00047 /* Color conversion function */
00048 typedef unsigned (*stp_convert_t)(stp_const_vars_t vars,
00049                                   const unsigned char *in,
00050                                   unsigned short *out);
00051 
00052 static void initialize_gcr_curve(stp_const_vars_t vars);
00053 
00054 
00055 typedef struct
00056 {
00057   unsigned steps;
00058   unsigned char *in_data;
00059   int image_bpp;
00060   int image_width;
00061   int out_channels;
00062   int channels_are_initialized;
00063   int input_color_model;
00064   int output_color_model;
00065   int output_type;
00066   stp_convert_t colorfunc;
00067   stp_curve_t composite;
00068   stp_curve_t black;
00069   stp_curve_t cyan;
00070   stp_curve_t magenta;
00071   stp_curve_t yellow;
00072   stp_curve_t hue_map;
00073   stp_curve_t lum_map;
00074   stp_curve_t sat_map;
00075   stp_curve_t gcr_curve;
00076   unsigned short *cmy_tmp;
00077   unsigned short *cmyk_lut;
00078   int linear_contrast_adjustment;
00079   double print_gamma;
00080   double app_gamma;
00081   double screen_gamma;
00082   double brightness;
00083   double contrast;
00084 } lut_t;
00085 
00086 typedef struct
00087 {
00088   const stp_parameter_t param;
00089   double min;
00090   double max;
00091   double defval;
00092   int color_only;
00093 } float_param_t;
00094 
00095 static const float_param_t float_parameters[] =
00096 {
00097   {
00098     {
00099       "ColorCorrection", N_("Color Correction"),
00100       N_("Color correction to be applied"),
00101       STP_PARAMETER_TYPE_STRING_LIST, STP_PARAMETER_CLASS_OUTPUT,
00102       STP_PARAMETER_LEVEL_ADVANCED, 1, 1, -1, 1
00103     }, 0.0, 0.0, 0.0, 0
00104   },
00105   {
00106     {
00107       "Brightness", N_("Brightness"),
00108       N_("Brightness of the print (0 is solid black, 2 is solid white)"),
00109       STP_PARAMETER_TYPE_DOUBLE, STP_PARAMETER_CLASS_OUTPUT,
00110       STP_PARAMETER_LEVEL_BASIC, 1, 1, -1, 1
00111     }, 0.0, 2.0, 1.0, 0
00112   },
00113   {
00114     {
00115       "Contrast", N_("Contrast"),
00116       N_("Contrast of the print (0 is solid gray)"),
00117       STP_PARAMETER_TYPE_DOUBLE, STP_PARAMETER_CLASS_OUTPUT,
00118       STP_PARAMETER_LEVEL_BASIC, 1, 1, -1, 1
00119     }, 0.0, 4.0, 1.0, 0
00120   },
00121   {
00122     {
00123       "LinearContrast", N_("Linear Contrast Adjustment"),
00124       N_("Use linear vs. fixed end point contrast adjustment"),
00125       STP_PARAMETER_TYPE_BOOLEAN, STP_PARAMETER_CLASS_OUTPUT,
00126       STP_PARAMETER_LEVEL_ADVANCED3, 1, 1, -1, 1
00127     }, 0.0, 0.0, 0.0, 0
00128   },
00129   {
00130     {
00131       "Gamma", N_("Gamma"),
00132       N_("Adjust the gamma of the print. Larger values will "
00133          "produce a generally brighter print, while smaller "
00134          "values will produce a generally darker print. "
00135          "Black and white will remain the same, unlike with "
00136          "the brightness adjustment."),
00137       STP_PARAMETER_TYPE_DOUBLE, STP_PARAMETER_CLASS_OUTPUT,
00138       STP_PARAMETER_LEVEL_BASIC, 1, 1, -1, 1
00139     }, 0.1, 4.0, 1.0, 0
00140   },
00141   {
00142     {
00143       "AppGamma", N_("AppGamma"),
00144       N_("Gamma value assumed by application"),
00145       STP_PARAMETER_TYPE_DOUBLE, STP_PARAMETER_CLASS_OUTPUT,
00146       STP_PARAMETER_LEVEL_ADVANCED5, 0, 1, -1, 1
00147     }, 0.1, 4.0, 1.0, 0
00148   },
00149   {
00150     {
00151       "CyanGamma", N_("Cyan"),
00152       N_("Adjust the cyan gamma"),
00153       STP_PARAMETER_TYPE_DOUBLE, STP_PARAMETER_CLASS_OUTPUT,
00154       STP_PARAMETER_LEVEL_ADVANCED1, 1, 1, 1, 1
00155     }, 0.0, 4.0, 1.0, 1
00156   },
00157   {
00158     {
00159       "MagentaGamma", N_("Magenta"),
00160       N_("Adjust the magenta gamma"),
00161       STP_PARAMETER_TYPE_DOUBLE, STP_PARAMETER_CLASS_OUTPUT,
00162       STP_PARAMETER_LEVEL_ADVANCED1, 1, 1, 2, 1
00163     }, 0.0, 4.0, 1.0, 1
00164   },
00165   {
00166     {
00167       "YellowGamma", N_("Yellow"),
00168       N_("Adjust the yellow gamma"),
00169       STP_PARAMETER_TYPE_DOUBLE, STP_PARAMETER_CLASS_OUTPUT,
00170       STP_PARAMETER_LEVEL_ADVANCED1, 1, 1, 3, 1
00171     }, 0.0, 4.0, 1.0, 1
00172   },
00173   {
00174     {
00175       "Saturation", N_("Saturation"),
00176       N_("Adjust the saturation (color balance) of the print\n"
00177          "Use zero saturation to produce grayscale output "
00178          "using color and black inks"),
00179       STP_PARAMETER_TYPE_DOUBLE, STP_PARAMETER_CLASS_OUTPUT,
00180       STP_PARAMETER_LEVEL_BASIC, 1, 1, -1, 1
00181     }, 0.0, 9.0, 1.0, 1
00182   },
00183   /* Need to think this through a bit more -- rlk 20030712 */
00184   {
00185     {
00186       "InkLimit", N_("Ink Limit"),
00187       N_("Limit the total ink printed to the page"),
00188       STP_PARAMETER_TYPE_DOUBLE, STP_PARAMETER_CLASS_OUTPUT,
00189       STP_PARAMETER_LEVEL_ADVANCED4, 0, 1, -1, 0
00190     }, 0.0, 32.0, 32.0, 1
00191   },
00192   {
00193     {
00194       "BlackGamma", N_("GCR Transition"),
00195       N_("Adjust the gray component transition rate"),
00196       STP_PARAMETER_TYPE_DOUBLE, STP_PARAMETER_CLASS_OUTPUT,
00197       STP_PARAMETER_LEVEL_ADVANCED4, 0, 1, 0, 1
00198     }, 0.0, 1.0, 1.0, 1
00199   },
00200   {
00201     {
00202       "GCRLower", N_("GCR Lower Bound"),
00203       N_("Lower bound of gray component reduction"),
00204       STP_PARAMETER_TYPE_DOUBLE, STP_PARAMETER_CLASS_OUTPUT,
00205       STP_PARAMETER_LEVEL_ADVANCED4, 0, 1, 0, 1
00206     }, 0.0, 1.0, 0.2, 1
00207   },
00208   {
00209     {
00210       "GCRUpper", N_("GCR Upper Bound"),
00211       N_("Upper bound of gray component reduction"),
00212       STP_PARAMETER_TYPE_DOUBLE, STP_PARAMETER_CLASS_OUTPUT,
00213       STP_PARAMETER_LEVEL_ADVANCED4, 0, 1, 0, 1
00214     }, 0.0, 5.0, 0.5, 1
00215   },
00216 };
00217 
00218 static const int float_parameter_count =
00219 sizeof(float_parameters) / sizeof(float_param_t);
00220 
00221 typedef struct
00222 {
00223   stp_parameter_t param;
00224   stp_curve_t *defval;
00225   int color_only;
00226   int hsl_only;
00227 } curve_param_t;
00228 
00229 static int standard_curves_initialized = 0;
00230 
00231 static stp_curve_t hue_map_bounds = NULL;
00232 static stp_curve_t lum_map_bounds = NULL;
00233 static stp_curve_t sat_map_bounds = NULL;
00234 static stp_curve_t color_curve_bounds = NULL;
00235 static stp_curve_t gcr_curve_bounds = NULL;
00236 
00237 static curve_param_t curve_parameters[] =
00238 {
00239   {
00240     {
00241       "CompositeCurve", N_("Composite Curve"),
00242       N_("Composite (Grayscale) curve"),
00243       STP_PARAMETER_TYPE_CURVE, STP_PARAMETER_CLASS_OUTPUT,
00244       STP_PARAMETER_LEVEL_ADVANCED2, 0, 1, -1, 1
00245     }, &color_curve_bounds, 0, 0
00246   },
00247   {
00248     {
00249       "CyanCurve", N_("Cyan Curve"),
00250       N_("Cyan curve"),
00251       STP_PARAMETER_TYPE_CURVE, STP_PARAMETER_CLASS_OUTPUT,
00252       STP_PARAMETER_LEVEL_ADVANCED2, 0, 1, 1, 1
00253     }, &color_curve_bounds, 1, 0
00254   },
00255   {
00256     {
00257       "MagentaCurve", N_("Magenta Curve"),
00258       N_("Magenta curve"),
00259       STP_PARAMETER_TYPE_CURVE, STP_PARAMETER_CLASS_OUTPUT,
00260       STP_PARAMETER_LEVEL_ADVANCED2, 0, 1, 2, 1
00261     }, &color_curve_bounds, 1, 0
00262   },
00263   {
00264     {
00265       "YellowCurve", N_("Yellow Curve"),
00266       N_("Yellow curve"),
00267       STP_PARAMETER_TYPE_CURVE, STP_PARAMETER_CLASS_OUTPUT,
00268       STP_PARAMETER_LEVEL_ADVANCED2, 0, 1, 3, 1
00269     }, &color_curve_bounds, 1, 0
00270   },
00271   {
00272     {
00273       "BlackCurve", N_("Black Curve"),
00274       N_("Black curve"),
00275       STP_PARAMETER_TYPE_CURVE, STP_PARAMETER_CLASS_OUTPUT,
00276       STP_PARAMETER_LEVEL_ADVANCED2, 0, 1, 0, 1
00277     }, &color_curve_bounds, 1, 0
00278   },
00279   {
00280     {
00281       "HueMap", N_("Hue Map"),
00282       N_("Hue adjustment curve"),
00283       STP_PARAMETER_TYPE_CURVE, STP_PARAMETER_CLASS_OUTPUT,
00284       STP_PARAMETER_LEVEL_ADVANCED3, 0, 1, -1, 1
00285     }, &hue_map_bounds, 1, 1
00286   },
00287   {
00288     {
00289       "SatMap", N_("Saturation Map"),
00290       N_("Saturation adjustment curve"),
00291       STP_PARAMETER_TYPE_CURVE, STP_PARAMETER_CLASS_OUTPUT,
00292       STP_PARAMETER_LEVEL_ADVANCED3, 0, 1, -1, 1
00293     }, &sat_map_bounds, 1, 1
00294   },
00295   {
00296     {
00297       "LumMap", N_("Luminosity Map"),
00298       N_("Luminosity adjustment curve"),
00299       STP_PARAMETER_TYPE_CURVE, STP_PARAMETER_CLASS_OUTPUT,
00300       STP_PARAMETER_LEVEL_ADVANCED3, 0, 1, -1, 1
00301     }, &lum_map_bounds, 1, 1
00302   },
00303   {
00304     {
00305       "GCRCurve", N_("Gray Component Reduction"),
00306       N_("Gray component reduction curve"),
00307       STP_PARAMETER_TYPE_CURVE, STP_PARAMETER_CLASS_OUTPUT,
00308       STP_PARAMETER_LEVEL_ADVANCED3, 0, 1, 0, 1
00309     }, &gcr_curve_bounds, 1, 0
00310   },
00311 };
00312 
00313 static const int curve_parameter_count =
00314 sizeof(curve_parameters) / sizeof(curve_param_t);
00315 
00316 static stp_curve_t compute_gcr_curve(stp_const_vars_t vars);
00317 
00318 /*
00319  * RGB to grayscale luminance constants...
00320  */
00321 
00322 #define LUM_RED         31
00323 #define LUM_GREEN       61
00324 #define LUM_BLUE        8
00325 
00326 /* rgb/hsl conversions taken from Gimp common/autostretch_hsv.c */
00327 
00328 #define FMAX(a, b) ((a) > (b) ? (a) : (b))
00329 #define FMIN(a, b) ((a) < (b) ? (a) : (b))
00330 
00331 
00332 
00333 static inline void
00334 calc_rgb_to_hsl(unsigned short *rgb, double *hue, double *sat,
00335                 double *lightness)
00336 {
00337   double red, green, blue;
00338   double h, s, l;
00339   double min, max;
00340   double delta;
00341   int maxval;
00342 
00343   red   = rgb[0] / 65535.0;
00344   green = rgb[1] / 65535.0;
00345   blue  = rgb[2] / 65535.0;
00346 
00347   if (red > green)
00348     {
00349       if (red > blue)
00350         {
00351           max = red;
00352           maxval = 0;
00353         }
00354       else
00355         {
00356           max = blue;
00357           maxval = 2;
00358         }
00359       min = FMIN(green, blue);
00360     }
00361   else
00362     {
00363       if (green > blue)
00364         {
00365           max = green;
00366           maxval = 1;
00367         }
00368       else
00369         {
00370           max = blue;
00371           maxval = 2;
00372         }
00373       min = FMIN(red, blue);
00374     }
00375 
00376   l = (max + min) / 2.0;
00377   delta = max - min;
00378 
00379   if (delta < .000001)  /* Suggested by Eugene Anikin <eugene@anikin.com> */
00380     {
00381       s = 0.0;
00382       h = 0.0;
00383     }
00384   else
00385     {
00386       if (l <= .5)
00387         s = delta / (max + min);
00388       else
00389         s = delta / (2 - max - min);
00390 
00391       if (maxval == 0)
00392         h = (green - blue) / delta;
00393       else if (maxval == 1)
00394         h = 2 + (blue - red) / delta;
00395       else
00396         h = 4 + (red - green) / delta;
00397 
00398       if (h < 0.0)
00399         h += 6.0;
00400       else if (h > 6.0)
00401         h -= 6.0;
00402     }
00403 
00404   *hue = h;
00405   *sat = s;
00406   *lightness = l;
00407 }
00408 
00409 static inline double
00410 hsl_value(double n1, double n2, double hue)
00411 {
00412   if (hue < 0)
00413     hue += 6.0;
00414   else if (hue > 6)
00415     hue -= 6.0;
00416   if (hue < 1.0)
00417     return (n1 + (n2 - n1) * hue);
00418   else if (hue < 3.0)
00419     return (n2);
00420   else if (hue < 4.0)
00421     return (n1 + (n2 - n1) * (4.0 - hue));
00422   else
00423     return (n1);
00424 }
00425 
00426 static inline void
00427 calc_hsl_to_rgb(unsigned short *rgb, double h, double s, double l)
00428 {
00429   if (s < .0000001)
00430     {
00431       if (l > 1)
00432         l = 1;
00433       else if (l < 0)
00434         l = 0;
00435       rgb[0] = l * 65535;
00436       rgb[1] = l * 65535;
00437       rgb[2] = l * 65535;
00438     }
00439   else
00440     {
00441       double m1, m2;
00442       double h1, h2;
00443       h1 = h + 2;
00444       h2 = h - 2;
00445 
00446       if (l < .5)
00447         m2 = l * (1 + s);
00448       else
00449         m2 = l + s - (l * s);
00450       m1 = (l * 2) - m2;
00451       rgb[0] = 65535 * hsl_value(m1, m2, h1);
00452       rgb[1] = 65535 * hsl_value(m1, m2, h);
00453       rgb[2] = 65535 * hsl_value(m1, m2, h2);
00454     }
00455 }
00456 
00457 static inline double
00458 update_saturation(double sat, double adjust, double isat)
00459 {
00460   if (adjust < 1)
00461     sat *= adjust;
00462   else
00463     {
00464       double s1 = sat * adjust;
00465       double s2 = 1.0 - ((1.0 - adjust) * isat);
00466       sat = FMIN(s1, s2);
00467     }
00468   if (sat > 1)
00469     sat = 1.0;
00470   return sat;
00471 }
00472 
00473 static inline void
00474 update_saturation_from_rgb(unsigned short *rgb, double adjust, double isat)
00475 {
00476   double h, s, l;
00477   calc_rgb_to_hsl(rgb, &h, &s, &l);
00478   s = update_saturation(s, adjust, isat);
00479   calc_hsl_to_rgb(rgb, h, s, l);
00480 }
00481 
00482 static inline double
00483 adjust_hue(stp_curve_t hue_map, double hue, size_t points)
00484 {
00485   if (hue_map)
00486     {
00487       double adjust;
00488       if (stp_curve_interpolate_value(hue_map, hue * points / 6.0, &adjust))
00489         {
00490           hue += adjust;
00491           if (hue < 0.0)
00492             hue += 6.0;
00493           else if (hue >= 6.0)
00494             hue -= 6.0;
00495         }
00496     }
00497   return hue;
00498 }
00499 
00500 static inline void
00501 adjust_hsl(unsigned short *rgbout, lut_t *lut, double ssat,
00502            double isat, size_t h_points, size_t s_points, size_t l_points,
00503            int split_saturation)
00504 {
00505   if ((split_saturation || lut->hue_map || lut->lum_map ||
00506        lut->sat_map) &&
00507       (rgbout[0] != rgbout[1] || rgbout[0] != rgbout[2]))
00508     {
00509       double h, s, l;
00510       rgbout[0] ^= 65535;
00511       rgbout[1] ^= 65535;
00512       rgbout[2] ^= 65535;
00513       calc_rgb_to_hsl(rgbout, &h, &s, &l);
00514       s = update_saturation(s, ssat, isat);
00515       h = adjust_hue(lut->hue_map, h, h_points);
00516       if (lut->lum_map && l > 0.0001 && l < .9999)
00517         {
00518           double nh = h * l_points / 6.0;
00519           double el;
00520           if (stp_curve_interpolate_value(lut->lum_map, nh, &el))
00521             {
00522               double sreflection = .8 - ((1.0 - el) / 1.3) ;
00523               double isreflection = 1.0 - sreflection;
00524               double sadj = l - sreflection;
00525               double isadj = 1;
00526               double sisadj = 1;
00527               if (sadj > 0)
00528                 {
00529                   isadj = (1.0 / isreflection) * (isreflection - sadj);
00530                   sisadj = sqrt(isadj);
00531 /*
00532                   s *= isadj * sisadj;
00533 */
00534                   s *= sqrt(isadj * sisadj);
00535                 }
00536               if (el < .9999)
00537                 {
00538                   double es = s;
00539                   es = 1 - es;
00540                   es *= es * es;
00541                   es = 1 - es;
00542                   el = 1.0 + (es * (el - 1.0));
00543                   l *= el;
00544                 }
00545               else if (el > 1.0001)
00546                 l = 1.0 - pow(1.0 - l, el);
00547               if (sadj > 0)
00548                 {
00549 /*                s *= sqrt(isadj); */
00550                   l = 1.0 - ((1.0 - l) * sqrt(sqrt(sisadj)));
00551                 }
00552             }
00553         }
00554       if (lut->sat_map)
00555         {
00556           double tmp;
00557           double nh = h * s_points / 6.0;
00558           if (stp_curve_interpolate_value(lut->sat_map, nh, &tmp) &&
00559               (tmp < .9999 || tmp > 1.0001))
00560             {
00561               s = update_saturation(s, tmp, tmp > 1.0 ? 1.0 / tmp : 1.0);
00562             }
00563         }
00564       calc_hsl_to_rgb(rgbout, h, s, l);
00565       rgbout[0] ^= 65535;
00566       rgbout[1] ^= 65535;
00567       rgbout[2] ^= 65535;
00568     }
00569 }
00570 
00571 static inline void
00572 adjust_hsl_bright(unsigned short *rgbout, lut_t *lut, double ssat,
00573            double isat, size_t h_points, size_t s_points, size_t l_points,
00574            int split_saturation)
00575 {
00576   if ((split_saturation || lut->hue_map || lut->lum_map) &&
00577       (rgbout[0] != rgbout[1] || rgbout[0] != rgbout[2]))
00578     {
00579       double h, s, l;
00580       rgbout[0] ^= 65535;
00581       rgbout[1] ^= 65535;
00582       rgbout[2] ^= 65535;
00583       calc_rgb_to_hsl(rgbout, &h, &s, &l);
00584       s = update_saturation(s, ssat, isat);
00585       h = adjust_hue(lut->hue_map, h, h_points);
00586       if (lut->lum_map && l > 0.0001 && l < .9999)
00587         {
00588           double nh = h * l_points / 6.0;
00589           double el;
00590           if (stp_curve_interpolate_value(lut->lum_map, nh, &el))
00591             {
00592               el = 1.0 + (s * (el - 1.0));
00593               l = 1.0 - pow(1.0 - l, el);
00594             }
00595         }
00596       calc_hsl_to_rgb(rgbout, h, s, l);
00597       rgbout[0] ^= 65535;
00598       rgbout[1] ^= 65535;
00599       rgbout[2] ^= 65535;
00600     }
00601 }
00602 
00603 static inline void
00604 lookup_rgb(lut_t *lut, unsigned short *rgbout,
00605            const unsigned short *red, const unsigned short *green,
00606            const unsigned short *blue)
00607 {
00608   if (lut->steps == 65536)
00609     {
00610       rgbout[0] = red[rgbout[0]];
00611       rgbout[1] = green[rgbout[1]];
00612       rgbout[2] = blue[rgbout[2]];
00613     }
00614   else
00615     {
00616       rgbout[0] = red[rgbout[0] / 256];
00617       rgbout[1] = green[rgbout[1] / 256];
00618       rgbout[2] = blue[rgbout[2] / 256];
00619     }
00620 }
00621 
00622 static unsigned
00623 generic_cmy_to_kcmy(stp_const_vars_t vars, const unsigned short *in,
00624                     unsigned short *out)
00625 {
00626   lut_t *lut = (lut_t *)(stpi_get_component_data(vars, "Color"));
00627   int width = lut->image_width;
00628   int step = 65535 / (lut->steps - 1); /* 1 or 257 */
00629 
00630   const unsigned short *gcr_lookup;
00631   const unsigned short *black_lookup;
00632   size_t points;
00633   int i;
00634   int j;
00635   int nz[4];
00636   unsigned retval = 0;
00637 
00638   initialize_gcr_curve(vars);
00639   gcr_lookup = stp_curve_get_ushort_data(lut->gcr_curve, &points);
00640   stp_curve_resample(lut->black, lut->steps);
00641   black_lookup = stp_curve_get_ushort_data(lut->black, &points);
00642   memset(nz, 0, sizeof(nz));
00643 
00644   for (i = 0; i < width; i++, out += 4, in += 3)
00645     {
00646       int c = in[0];
00647       int m = in[1];
00648       int y = in[2];
00649       int k = FMIN(c, FMIN(m, y));
00650       for (j = 0; j < 3; j++)
00651         out[j + 1] = in[j];
00652       if (k == 0)
00653         out[0] = 0;
00654       else
00655         {
00656           int where, resid;
00657           int kk;
00658           if (lut->steps == 65536)
00659             kk = gcr_lookup[k];
00660           else
00661             {
00662               where = k / step;
00663               resid = k % step;
00664               if (resid == 0)
00665                 kk = gcr_lookup[where];
00666               else
00667                 kk = gcr_lookup[where] +
00668                   (gcr_lookup[where + 1] - gcr_lookup[where]) * resid / step;
00669             }
00670           if (kk > k)
00671             kk = k;
00672           if (lut->steps == 65536)
00673             out[0] = black_lookup[kk];
00674           else
00675             {
00676               where = kk / step;
00677               resid = kk % step;
00678               if (resid)
00679                 out[0] = black_lookup[where] +
00680                   (black_lookup[where + 1] - black_lookup[where]) * resid /
00681                   step;
00682               else
00683                 out[0] = black_lookup[where];
00684             }
00685           for (j = 1; j < 4; j++)
00686             out[j] -= kk;
00687         }
00688       for (j = 0; j < 4; j++)
00689         nz[j] |= out[j];
00690     }
00691   for (j = 0; j < 4; j++)
00692     if (nz[j] == 0)
00693       retval |= (1 << j);
00694   return retval;
00695 }
00696 
00697 /*
00698  * 'rgb_to_rgb()' - Convert rgb image data to RGB.
00699  */
00700 
00701 #define RGB_TO_RGB_FUNC(T, bits)                                              \
00702 static unsigned                                                               \
00703 rgb_##bits##_to_rgb(stp_const_vars_t vars, const unsigned char *in,           \
00704                    unsigned short *out)                                       \
00705 {                                                                             \
00706   int i;                                                                      \
00707   double isat = 1.0;                                                          \
00708   double ssat = stp_get_float_parameter(vars, "Saturation");                  \
00709   size_t count;                                                               \
00710   int i0 = -1;                                                                \
00711   int i1 = -1;                                                                \
00712   int i2 = -1;                                                                \
00713   int o0 = 0;                                                                 \
00714   int o1 = 0;                                                                 \
00715   int o2 = 0;                                                                 \
00716   int nz0 = 0;                                                                \
00717   int nz1 = 0;                                                                \
00718   int nz2 = 0;                                                                \
00719   const T *s_in = (const T *) in;                                             \
00720   lut_t *lut = (lut_t *)(stpi_get_component_data(vars, "Color"));             \
00721   int compute_saturation = ssat <= .99999 || ssat >= 1.00001;                 \
00722   int split_saturation = ssat > 1.4;                                          \
00723   const unsigned short *red =                                                 \
00724     stp_curve_get_ushort_data(lut->cyan, &count);                             \
00725   const unsigned short *green =                                               \
00726     stp_curve_get_ushort_data(lut->magenta, &count);                          \
00727   const unsigned short *blue =                                                \
00728     stp_curve_get_ushort_data(lut->yellow, &count);                           \
00729   size_t h_points = 0;                                                        \
00730   size_t l_points = 0;                                                        \
00731   size_t s_points = 0;                                                        \
00732   int bright_color_adjustment = 0;                                            \
00733                                                                               \
00734   if (strcmp(stp_get_string_parameter(vars, "ColorCorrection"),               \
00735              "Bright") == 0)                                                  \
00736     bright_color_adjustment = 1;                                              \
00737                                                                               \
00738   if (lut->hue_map)                                                           \
00739     h_points = stp_curve_count_points(lut->hue_map);                          \
00740   if (lut->lum_map)                                                           \
00741     l_points = stp_curve_count_points(lut->lum_map);                          \
00742   if (lut->sat_map)                                                           \
00743     s_points = stp_curve_count_points(lut->sat_map);                          \
00744                                                                               \
00745   if (split_saturation)                                                       \
00746     ssat = sqrt(ssat);                                                        \
00747   if (ssat > 1)                                                               \
00748     isat = 1.0 / ssat;                                                        \
00749   for (i = 0; i < lut->image_width; i++)                                      \
00750     {                                                                         \
00751       if (i0 == s_in[0] && i1 == s_in[1] && i2 == s_in[2])                    \
00752         {                                                                     \
00753           out[0] = o0;                                                        \
00754           out[1] = o1;                                                        \
00755           out[2] = o2;                                                        \
00756         }                                                                     \
00757       else                                                                    \
00758         {                                                                     \
00759           i0 = s_in[0];                                                       \
00760           i1 = s_in[1];                                                       \
00761           i2 = s_in[2];                                                       \
00762           out[0] = i0 * (65535u / (unsigned) ((1 << bits) - 1));              \
00763           out[1] = i1 * (65535u / (unsigned) ((1 << bits) - 1));              \
00764           out[2] = i2 * (65535u / (unsigned) ((1 << bits) - 1));              \
00765           if ((compute_saturation) && (out[0] != out[1] || out[0] != out[2])) \
00766             update_saturation_from_rgb(out, ssat, isat);                      \
00767           if (bright_color_adjustment)                                        \
00768             adjust_hsl_bright(out, lut, ssat, isat, h_points,                 \
00769                               s_points, l_points, split_saturation);          \
00770           else                                                                \
00771             adjust_hsl(out, lut, ssat, isat, h_points,                        \
00772                        s_points, l_points, split_saturation);                 \
00773           lookup_rgb(lut, out, red, green, blue);                             \
00774           o0 = out[0];                                                        \
00775           o1 = out[1];                                                        \
00776           o2 = out[2];                                                        \
00777           nz0 |= o0;                                                          \
00778           nz1 |= o1;                                                          \
00779           nz2 |= o2;                                                          \
00780         }                                                                     \
00781       s_in += 3;                                                              \
00782       out += 3;                                                               \
00783     }                                                                         \
00784   return (nz0 ? 1 : 0) +  (nz1 ? 2 : 0) +  (nz2 ? 4 : 0);                     \
00785 }
00786 
00787 RGB_TO_RGB_FUNC(unsigned char, 8)
00788 RGB_TO_RGB_FUNC(unsigned short, 16)
00789 
00790 /*
00791  * 'rgb_to_rgb()' - Convert rgb image data to RGB.
00792  */
00793 
00794 #define FAST_RGB_TO_RGB_FUNC(T, bits)                                    \
00795 static unsigned                                                          \
00796 fast_rgb_##bits##_to_rgb(stp_const_vars_t vars, const unsigned char *in, \
00797                        unsigned short *out)                              \
00798 {                                                                        \
00799   int i;                                                                 \
00800   int i0 = -1;                                                           \
00801   int i1 = -1;                                                           \
00802   int i2 = -1;                                                           \
00803   int o0 = 0;                                                            \
00804   int o1 = 0;                                                            \
00805   int o2 = 0;                                                            \
00806   int nz0 = 0;                                                           \
00807   int nz1 = 0;                                                           \
00808   int nz2 = 0;                                                           \
00809   const T *s_in = (const T *) in;                                        \
00810   lut_t *lut = (lut_t *)(stpi_get_component_data(vars, "Color"));        \
00811   size_t count;                                                          \
00812   const unsigned short *red;                                             \
00813   const unsigned short *green;                                           \
00814   const unsigned short *blue;                                            \
00815   double isat = 1.0;                                                     \
00816   double saturation = stp_get_float_parameter(vars, "Saturation");       \
00817                                                                          \
00818   stp_curve_resample(lut->cyan, 1 << bits);                              \
00819   stp_curve_resample(lut->magenta, 1 << bits);                           \
00820   stp_curve_resample(lut->yellow, 1 << bits);                            \
00821   red = stp_curve_get_ushort_data(lut->cyan, &count);                    \
00822   green = stp_curve_get_ushort_data(lut->magenta, &count);               \
00823   blue = stp_curve_get_ushort_data(lut->yellow, &count);                 \
00824                                                                          \
00825   if (saturation > 1)                                                    \
00826     isat = 1.0 / saturation;                                             \
00827   for (i = 0; i < lut->image_width; i++)                                 \
00828     {                                                                    \
00829       if (i0 == s_in[0] && i1 == s_in[1] && i2 == s_in[2])               \
00830         {                                                                \
00831           out[0] = o0;                                                   \
00832           out[1] = o1;                                                   \
00833           out[2] = o2;                                                   \
00834         }                                                                \
00835       else                                                               \
00836         {                                                                \
00837           i0 = s_in[0];                                                  \
00838           i1 = s_in[1];                                                  \
00839           i2 = s_in[2];                                                  \
00840           out[0] = red[s_in[0]];                                         \
00841           out[1] = green[s_in[1]];                                       \
00842           out[2] = blue[s_in[2]];                                        \
00843           if (saturation != 1.0)                                         \
00844             update_saturation_from_rgb(out, saturation, isat);           \
00845           o0 = out[0];                                                   \
00846           o1 = out[1];                                                   \
00847           o2 = out[2];                                                   \
00848           nz0 |= o0;                                                     \
00849           nz1 |= o1;                                                     \
00850           nz2 |= o2;                                                     \
00851         }                                                                \
00852       s_in += 3;                                                         \
00853       out += 3;                                                          \
00854     }                                                                    \
00855   return (nz0 ? 1 : 0) +  (nz1 ? 2 : 0) +  (nz2 ? 4 : 0);                \
00856 }
00857 
00858 FAST_RGB_TO_RGB_FUNC(unsigned char, 8)
00859 FAST_RGB_TO_RGB_FUNC(unsigned short, 16)
00860 
00861 /*
00862  * 'gray_to_rgb()' - Convert gray image data to RGB.
00863  */
00864 
00865 #define GRAY_TO_RGB_FUNC(T, bits)                                       \
00866 static unsigned                                                         \
00867 gray_##bits##_to_rgb(stp_const_vars_t vars, const unsigned char *in,    \
00868                    unsigned short *out)                                 \
00869 {                                                                       \
00870   int i;                                                                \
00871   int i0 = -1;                                                          \
00872   int o0 = 0;                                                           \
00873   int o1 = 0;                                                           \
00874   int o2 = 0;                                                           \
00875   int nz0 = 0;                                                          \
00876   int nz1 = 0;                                                          \
00877   int nz2 = 0;                                                          \
00878   const T *s_in = (const T *) in;                                       \
00879   lut_t *lut = (lut_t *)(stpi_get_component_data(vars, "Color"));       \
00880   size_t count;                                                         \
00881   const unsigned short *red;                                            \
00882   const unsigned short *green;                                          \
00883   const unsigned short *blue;                                           \
00884                                                                         \
00885   stp_curve_resample(lut->cyan, 1 << bits);                             \
00886   stp_curve_resample(lut->magenta, 1 << bits);                          \
00887   stp_curve_resample(lut->yellow, 1 << bits);                           \
00888   red = stp_curve_get_ushort_data(lut->cyan, &count);                   \
00889   green = stp_curve_get_ushort_data(lut->magenta, &count);              \
00890   blue = stp_curve_get_ushort_data(lut->yellow, &count);                \
00891                                                                         \
00892   for (i = 0; i < lut->image_width; i++)                                \
00893     {                                                                   \
00894       if (i0 == s_in[0])                                                \
00895         {                                                               \
00896           out[0] = o0;                                                  \
00897           out[1] = o1;                                                  \
00898           out[2] = o2;                                                  \
00899         }                                                               \
00900       else                                                              \
00901         {                                                               \
00902           i0 = s_in[0];                                                 \
00903           out[0] = red[s_in[0]];                                        \
00904           out[1] = green[s_in[0]];                                      \
00905           out[2] = blue[s_in[0]];                                       \
00906           o0 = out[0];                                                  \
00907           o1 = out[1];                                                  \
00908           o2 = out[2];                                                  \
00909           nz0 |= o0;                                                    \
00910           nz1 |= o1;                                                    \
00911           nz2 |= o2;                                                    \
00912         }                                                               \
00913       s_in += 1;                                                        \
00914       out += 3;                                                         \
00915     }                                                                   \
00916   return (nz0 ? 1 : 0) +  (nz1 ? 2 : 0) +  (nz2 ? 4 : 0);               \
00917 }
00918 
00919 GRAY_TO_RGB_FUNC(unsigned char, 8)
00920 GRAY_TO_RGB_FUNC(unsigned short, 16)
00921 
00922 #define RGB_TO_KCMY_FUNC(name, bits)                                    \
00923 static unsigned                                                         \
00924 name##_##bits##_to_kcmy(stp_const_vars_t vars, const unsigned char *in, \
00925                         unsigned short *out)                            \
00926 {                                                                       \
00927   lut_t *lut = (lut_t *)(stpi_get_component_data(vars, "Color"));       \
00928   if (!lut->cmy_tmp)                                                    \
00929     lut->cmy_tmp = stpi_malloc(4 * 2 * lut->image_width);               \
00930   name##_##bits##_to_rgb(vars, in, lut->cmy_tmp);                       \
00931   return generic_cmy_to_kcmy(vars, lut->cmy_tmp, out);                  \
00932 }
00933 
00934 RGB_TO_KCMY_FUNC(gray, 8)
00935 RGB_TO_KCMY_FUNC(rgb, 8)
00936 RGB_TO_KCMY_FUNC(fast_rgb, 8)
00937 RGB_TO_KCMY_FUNC(gray, 16)
00938 RGB_TO_KCMY_FUNC(rgb, 16)
00939 RGB_TO_KCMY_FUNC(fast_rgb, 16)
00940 
00941 #define RGB_TO_KCMY_LINE_ART_FUNC(T, name)                              \
00942 static unsigned                                                         \
00943 name##_to_kcmy_line_art(stp_const_vars_t vars,                          \
00944                         const unsigned char *in,                        \
00945                         unsigned short *out)                            \
00946 {                                                                       \
00947   int i;                                                                \
00948   int z = 15;                                                           \
00949   const T *s_in = (const T *) in;                                       \
00950   unsigned high_bit = ((1 << ((sizeof(T) * 8) - 1)));                   \
00951   lut_t *lut = (lut_t *)(stpi_get_component_data(vars, "Color"));       \
00952   int width = lut->image_width;                                         \
00953   unsigned mask = 0;                                                    \
00954   memset(out, 0, width * 4 * sizeof(unsigned short));                   \
00955   if (lut->output_color_model != lut->input_color_model)                \
00956     mask = (1 << (sizeof(T) * 8)) - 1;                                  \
00957                                                                         \
00958   for (i = 0; i < width; i++, out += 4, s_in += 3)                      \
00959     {                                                                   \
00960       unsigned c = s_in[0] ^ mask;                                      \
00961       unsigned m = s_in[1] ^ mask;                                      \
00962       unsigned y = s_in[2] ^ mask;                                      \
00963       unsigned k = (c < m ? (c < y ? c : y) : (m < y ? m : y));         \
00964       if (k >= high_bit)                                                \
00965         {                                                               \
00966           c -= k;                                                       \
00967           m -= k;                                                       \
00968           y -= k;                                                       \
00969         }                                                               \
00970       if (k >= high_bit)                                                \
00971         {                                                               \
00972           z &= 0xe;                                                     \
00973           out[0] = 65535;                                               \
00974         }                                                               \
00975       if (c >= high_bit)                                                \
00976         {                                                               \
00977           z &= 0xd;                                                     \
00978           out[1] = 65535;                                               \
00979         }                                                               \
00980       if (m >= high_bit)                                                \
00981         {                                                               \
00982           z &= 0xb;                                                     \
00983           out[2] = 65535;                                               \
00984         }                                                               \
00985       if (y >= high_bit)                                                \
00986         {                                                               \
00987           z &= 0x7;                                                     \
00988           out[3] = 65535;                                               \
00989         }                                                               \
00990     }                                                                   \
00991   return z;                                                             \
00992 }
00993 
00994 RGB_TO_KCMY_LINE_ART_FUNC(unsigned char, rgb_8)
00995 RGB_TO_KCMY_LINE_ART_FUNC(unsigned short, rgb_16)
00996 
00997 #define CMYK_TO_KCMY_LINE_ART_FUNC(T, name)                             \
00998 static unsigned                                                         \
00999 name##_to_kcmy_line_art(stp_const_vars_t vars,                          \
01000                         const unsigned char *in,                        \
01001                         unsigned short *out)                            \
01002 {                                                                       \
01003   int i;                                                                \
01004   int z = 15;                                                           \
01005   const T *s_in = (const T *) in;                                       \
01006   unsigned desired_high_bit = 0;                                        \
01007   unsigned high_bit = 1 << ((sizeof(T) * 8) - 1);                       \
01008   lut_t *lut = (lut_t *)(stpi_get_component_data(vars, "Color"));       \
01009   int width = lut->image_width;                                         \
01010   memset(out, 0, width * 4 * sizeof(unsigned short));                   \
01011   if (lut->output_color_model == lut->input_color_model)                \
01012     desired_high_bit = high_bit;                                        \
01013                                                                         \
01014   for (i = 0; i < width; i++, out += 4, s_in += 4)                      \
01015     {                                                                   \
01016       if ((s_in[3] & high_bit) == desired_high_bit)                     \
01017         {                                                               \
01018           z &= 0xe;                                                     \
01019           out[0] = 65535;                                               \
01020         }                                                               \
01021       if ((s_in[0] & high_bit) == desired_high_bit)                     \
01022         {                                                               \
01023           z &= 0xd;                                                     \
01024           out[1] = 65535;                                               \
01025         }                                                               \
01026       if ((s_in[1] & high_bit) == desired_high_bit)                     \
01027         {                                                               \
01028           z &= 0xb;                                                     \
01029           out[2] = 65535;                                               \
01030         }                                                               \
01031       if ((s_in[2] & high_bit) == desired_high_bit)                     \
01032         {                                                               \
01033           z &= 0x7;                                                     \
01034           out[3] = 65535;                                               \
01035         }                                                               \
01036     }                                                                   \
01037   return z;                                                             \
01038 }
01039 
01040 CMYK_TO_KCMY_LINE_ART_FUNC(unsigned char, cmyk_8)
01041 CMYK_TO_KCMY_LINE_ART_FUNC(unsigned short, cmyk_16)
01042 
01043 #define GRAY_TO_COLOR_LINE_ART_FUNC(T, name, bits, channels)            \
01044 static unsigned                                                         \
01045 gray_##bits##_to_##name##_line_art(stp_const_vars_t vars,               \
01046                                    const unsigned char *in,             \
01047                                    unsigned short *out)                 \
01048 {                                                                       \
01049   int i;                                                                \
01050   int z = (1 << channels) - 1;                                          \
01051   int desired_high_bit = 0;                                             \
01052   unsigned high_bit = 1 << ((sizeof(T) * 8) - 1);                       \
01053   const T *s_in = (const T *) in;                                       \
01054   lut_t *lut = (lut_t *)(stpi_get_component_data(vars, "Color"));       \
01055   int width = lut->image_width;                                         \
01056   memset(out, 0, width * channels * sizeof(unsigned short));            \
01057   if (lut->output_color_model == lut->input_color_model)                \
01058     desired_high_bit = high_bit;                                        \
01059                                                                         \
01060   for (i = 0; i < width; i++, out += channels, s_in++)                  \
01061     {                                                                   \
01062       if ((s_in[0] & high_bit) == desired_high_bit)                     \
01063         {                                                               \
01064           int j;                                                        \
01065           z = 0;                                                        \
01066           for (j = 0; j < channels; j++)                                \
01067             out[j] = 65535;                                             \
01068         }                                                               \
01069     }                                                                   \
01070   return z;                                                             \
01071 }
01072 
01073 GRAY_TO_COLOR_LINE_ART_FUNC(unsigned char, rgb, 8, 3)
01074 GRAY_TO_COLOR_LINE_ART_FUNC(unsigned short, rgb, 16, 3)
01075 GRAY_TO_COLOR_LINE_ART_FUNC(unsigned char, kcmy, 8, 4)
01076 GRAY_TO_COLOR_LINE_ART_FUNC(unsigned short, kcmy, 16, 4)
01077 
01078 #define RGB_TO_RGB_LINE_ART_FUNC(T, name)                               \
01079 static unsigned                                                         \
01080 name##_to_rgb_line_art(stp_const_vars_t vars,                           \
01081                        const unsigned char *in,                         \
01082                        unsigned short *out)                             \
01083 {                                                                       \
01084   int i;                                                                \
01085   int z = 7;                                                            \
01086   int desired_high_bit = 0;                                             \
01087   unsigned high_bit = ((1 << ((sizeof(T) * 8) - 1)) * 4);               \
01088   const T *s_in = (const T *) in;                                       \
01089   lut_t *lut = (lut_t *)(stpi_get_component_data(vars, "Color"));       \
01090   int width = lut->image_width;                                         \
01091   memset(out, 0, width * 3 * sizeof(unsigned short));                   \
01092   if (lut->input_color_model == lut->output_color_model)                \
01093     desired_high_bit = high_bit;                                        \
01094                                                                         \
01095   for (i = 0; i < width; i++, out += 3, s_in += 3)                      \
01096     {                                                                   \
01097       if ((s_in[0] & high_bit) == desired_high_bit)                     \
01098         {                                                               \
01099           z &= 6;                                                       \
01100           out[0] = 65535;                                               \
01101         }                                                               \
01102       if ((s_in[1] & high_bit) == desired_high_bit)                     \
01103         {                                                               \
01104           z &= 5;                                                       \
01105           out[1] = 65535;                                               \
01106         }                                                               \
01107       if ((s_in[1] & high_bit) == desired_high_bit)                     \
01108         {                                                               \
01109           z &= 3;                                                       \
01110           out[2] = 65535;                                               \
01111         }                                                               \
01112     }                                                                   \
01113   return z;                                                             \
01114 }
01115 
01116 RGB_TO_RGB_LINE_ART_FUNC(unsigned char, rgb_8)
01117 RGB_TO_RGB_LINE_ART_FUNC(unsigned short, rgb_16)
01118 
01119 #define COLOR_TO_GRAY_LINE_ART_FUNC(T, name, channels, max_channels)    \
01120 static unsigned                                                         \
01121 name##_to_gray_line_art(stp_const_vars_t vars,                          \
01122                         const unsigned char *in,                        \
01123                         unsigned short *out)                            \
01124 {                                                                       \
01125   int i;                                                                \
01126   int z = 1;                                                            \
01127   int desired_high_bit = 0;                                             \
01128   unsigned high_bit = ((1 << ((sizeof(T) * 8) - 1)) * max_channels);    \
01129   const T *s_in = (const T *) in;                                       \
01130   lut_t *lut = (lut_t *)(stpi_get_component_data(vars, "Color"));       \
01131   int width = lut->image_width;                                         \
01132   memset(out, 0, width * sizeof(unsigned short));                       \
01133   if (lut->output_color_model == lut->input_color_model)                \
01134     desired_high_bit = high_bit;                                        \
01135                                                                         \
01136   for (i = 0; i < width; i++, out++, s_in += channels)                  \
01137     {                                                                   \
01138       unsigned gval =                                                   \
01139         (max_channels - channels) * (1 << ((sizeof(T) * 8) - 1));       \
01140       int j;                                                            \
01141       for (j = 0; j < channels; j++)                                    \
01142         gval += s_in[j];                                                \
01143       if ((gval & high_bit) == desired_high_bit)                        \
01144         {                                                               \
01145           out[0] = 65535;                                               \
01146           z = 0;                                                        \
01147         }                                                               \
01148     }                                                                   \
01149   return z;                                                             \
01150 }
01151 
01152 COLOR_TO_GRAY_LINE_ART_FUNC(unsigned char, cmyk_8, 4, 4)
01153 COLOR_TO_GRAY_LINE_ART_FUNC(unsigned short, cmyk_16, 4, 4)
01154 COLOR_TO_GRAY_LINE_ART_FUNC(unsigned char, color_8, 3, 4)
01155 COLOR_TO_GRAY_LINE_ART_FUNC(unsigned short, color_16, 3, 4)
01156 COLOR_TO_GRAY_LINE_ART_FUNC(unsigned char, gray_8, 1, 1)
01157 COLOR_TO_GRAY_LINE_ART_FUNC(unsigned short, gray_16, 1, 1)
01158 
01159 #define CMYK_TO_KCMY_FUNC(T, size)                                      \
01160 static unsigned                                                         \
01161 cmyk_##size##_to_kcmy(stp_const_vars_t vars,                            \
01162                       const unsigned char *in,                          \
01163                       unsigned short *out)                              \
01164 {                                                                       \
01165   int i;                                                                \
01166   unsigned retval = 0;                                                  \
01167   int j;                                                                \
01168   int nz[4];                                                            \
01169   const T *s_in = (const T *) in;                                       \
01170   lut_t *lut = (lut_t *)(stpi_get_component_data(vars, "Color"));       \
01171                                                                         \
01172   memset(nz, 0, sizeof(nz));                                            \
01173                                                                         \
01174   for (i = 0; i < lut->image_width; i++, out += 4)                      \
01175     {                                                                   \
01176       for (j = 0; j < 4; j++)                                           \
01177         {                                                               \
01178           int outpos = (j + 1) & 3;                                     \
01179           int inval = *s_in++;                                          \
01180           nz[outpos] |= j;                                              \
01181           out[outpos] = lut->cmyk_lut[inval];                           \
01182         }                                                               \
01183     }                                                                   \
01184   for (j = 0; j < 4; j++)                                               \
01185     if (nz[j] == 0)                                                     \
01186       retval |= (1 << j);                                               \
01187   return retval;                                                        \
01188 }
01189 
01190 CMYK_TO_KCMY_FUNC(unsigned char, 8)
01191 CMYK_TO_KCMY_FUNC(unsigned short, 16)
01192 
01193 /*
01194  * 'gray_to_gray()' - Convert grayscale image data to grayscale (brightness
01195  *                    adjusted).
01196  */
01197 
01198 
01199 #define GRAY_TO_GRAY_FUNC(T, bits)                                      \
01200 static unsigned                                                         \
01201 gray_##bits##_to_gray(stp_const_vars_t vars,                            \
01202                       const unsigned char *in,                          \
01203                       unsigned short *out)                              \
01204 {                                                                       \
01205   int i;                                                                \
01206   int i0 = -1;                                                          \
01207   int o0 = 0;                                                           \
01208   int nz = 0;                                                           \
01209   const T *s_in = (const T *) in;                                       \
01210   lut_t *lut = (lut_t *)(stpi_get_component_data(vars, "Color"));       \
01211   int width = lut->image_width;                                         \
01212   size_t count;                                                         \
01213   const unsigned short *composite;                                      \
01214                                                                         \
01215   stp_curve_resample(lut->composite, 1 << bits);                        \
01216   composite = stp_curve_get_ushort_data(lut->composite, &count);        \
01217                                                                         \
01218   memset(out, 0, width * sizeof(unsigned short));                       \
01219                                                                         \
01220   for (i = 0; i < lut->image_width; i++)                                \
01221     {                                                                   \
01222       if (i0 != s_in[0])                                                \
01223         {                                                               \
01224           i0 = s_in[0];                                                 \
01225           o0 = composite[i0];                                           \
01226           nz |= o0;                                                     \
01227         }                                                               \
01228       out[0] = o0;                                                      \
01229       s_in ++;                                                          \
01230       out ++;                                                           \
01231     }                                                                   \
01232   return nz == 0;                                                       \
01233 }
01234 
01235 GRAY_TO_GRAY_FUNC(unsigned char, 8)
01236 GRAY_TO_GRAY_FUNC(unsigned short, 16)
01237 
01238 /*
01239  * 'rgb_to_gray()' - Convert RGB image data to grayscale.
01240  */
01241 
01242 #define COLOR_TO_GRAY_FUNC(T, bits)                                        \
01243 static unsigned                                                            \
01244 color_##bits##_to_gray(stp_const_vars_t vars,                              \
01245                        const unsigned char *in,                            \
01246                        unsigned short *out)                                \
01247 {                                                                          \
01248   int i;                                                                   \
01249   int i0 = -1;                                                             \
01250   int i1 = -1;                                                             \
01251   int i2 = -1;                                                             \
01252   int o0 = 0;                                                              \
01253   int nz = 0;                                                              \
01254   const T *s_in = (const T *) in;                                          \
01255   lut_t *lut = (lut_t *)(stpi_get_component_data(vars, "Color"));          \
01256   size_t count;                                                            \
01257   const unsigned short *composite;                                         \
01258   int l_red = LUM_RED;                                                     \
01259   int l_green = LUM_GREEN;                                                 \
01260   int l_blue = LUM_BLUE;                                                   \
01261                                                                            \
01262   stp_curve_resample(lut->composite, 1 << bits);                           \
01263   composite = stp_curve_get_ushort_data(lut->composite, &count);           \
01264                                                                            \
01265   if (lut->input_color_model == COLOR_MODEL_CMY)                           \
01266     {                                                                      \
01267       l_red = 100 - l_red;                                                 \
01268       l_green = 100 - l_green;                                             \
01269       l_blue = 100 - l_blue;                                               \
01270     }                                                                      \
01271                                                                            \
01272   for (i = 0; i < lut->image_width; i++)                                   \
01273     {                                                                      \
01274       if (i0 != s_in[0] || i1 != s_in[1] || i2 != s_in[2])                 \
01275         {                                                                  \
01276           i0 = s_in[0];                                                    \
01277           i1 = s_in[1];                                                    \
01278           i2 = s_in[2];                                                    \
01279           o0 = composite[(i0 * l_red + i1 * l_green + i2 * l_blue) / 100]; \
01280           nz |= o0;                                                        \
01281         }                                                                  \
01282       out[0] = o0;                                                         \
01283       s_in += 3;                                                           \
01284       out ++;                                                              \
01285     }                                                                      \
01286   return nz == 0;                                                          \
01287 }
01288 
01289 COLOR_TO_GRAY_FUNC(unsigned char, 8)
01290 COLOR_TO_GRAY_FUNC(unsigned short, 16)
01291 
01292 
01293 #define CMYK_TO_GRAY_FUNC(T, size)                                      \
01294 static unsigned                                                         \
01295 cmyk_##size##_to_gray(stp_const_vars_t vars,                            \
01296                       const unsigned char *in,                          \
01297                       unsigned short *out)                              \
01298 {                                                                       \
01299   int i;                                                                \
01300   int j;                                                                \
01301   int nz = 0;                                                           \
01302   const T *s_in = (const T *) in;                                       \
01303   lut_t *lut = (lut_t *)(stpi_get_component_data(vars, "Color"));       \
01304                                                                         \
01305   for (i = 0; i < lut->image_width; i++, s_in += 4, out ++)             \
01306     {                                                                   \
01307       for (j = 0; j < 4; j++)                                           \
01308         {                                                               \
01309           nz |= s_in[0];                                                \
01310           out[0] = lut->cmyk_lut[s_in[0]];                              \
01311         }                                                               \
01312     }                                                                   \
01313   return nz ? 1 : 0;                                                    \
01314 }
01315 
01316 CMYK_TO_GRAY_FUNC(unsigned char, 8)
01317 CMYK_TO_GRAY_FUNC(unsigned short, 16)
01318 
01319 static unsigned
01320 cmyk_16_to_gray_raw(stp_const_vars_t vars, const unsigned char *in,
01321                     unsigned short *out)
01322 {
01323   int i;
01324   int nz[4];
01325   const unsigned short *usin = (const unsigned short *) in;
01326   lut_t *lut = (lut_t *)(stpi_get_component_data(vars, "Color"));
01327 
01328   memset(nz, 0, sizeof(nz));
01329   for (i = 0; i < lut->image_width; i++)
01330     {
01331       nz[0] |= usin[0];
01332       out[0] = usin[0];
01333       usin += 4;
01334       out += 1;
01335     }
01336   return nz[0] ? 1 : 0;
01337 }
01338 
01339 static unsigned
01340 cmyk_16_to_kcmy_raw(stp_const_vars_t vars, const unsigned char *in,
01341                     unsigned short *out)
01342 {
01343   int i;
01344   int j;
01345   unsigned retval = 0;
01346   int nz[4];
01347   const unsigned short *usin = (const unsigned short *) in;
01348   lut_t *lut = (lut_t *)(stpi_get_component_data(vars, "Color"));
01349 
01350   memset(nz, 0, sizeof(nz));
01351   for (i = 0; i < lut->image_width; i++)
01352     {
01353       out[0] = usin[3];
01354       out[1] = usin[0];
01355       out[2] = usin[1];
01356       out[3] = usin[2];
01357       for (j = 0; j < 4; j++)
01358         nz[j] |= out[j];
01359       usin += 4;
01360       out += 4;
01361     }
01362   for (j = 0; j < 4; j++)
01363     if (nz[j] == 0)
01364       retval |= (1 << j);
01365   return retval;
01366 }
01367 
01368 static unsigned
01369 raw_to_raw(stp_const_vars_t vars, const unsigned char *in,
01370            unsigned short *out)
01371 {
01372   int i;
01373   int j;
01374   unsigned retval = 0;
01375   int nz[STP_CHANNEL_LIMIT];
01376   int colors;
01377   const unsigned short *usin = (const unsigned short *) in;
01378   lut_t *lut = (lut_t *)(stpi_get_component_data(vars, "Color"));
01379   colors = lut->image_bpp / 2;
01380 
01381   memset(nz, 0, sizeof(nz));
01382   for (i = 0; i < lut->image_width; i++)
01383     {
01384       for (j = 0; j < colors; j++)
01385         {
01386           nz[j] |= usin[j];
01387           out[j] = usin[j];
01388         }
01389       usin += colors;
01390       out += colors;
01391     }
01392   for (j = 0; j < colors; j++)
01393     if (nz[j] == 0)
01394       retval |= (1 << j);
01395   return retval;
01396 }
01397 
01398 
01399 static void
01400 initialize_channels(stp_vars_t v, stp_image_t *image)
01401 {
01402   lut_t *lut = (lut_t *)(stpi_get_component_data(v, "Color"));
01403   if (stp_check_float_parameter(v, "InkLimit", STP_PARAMETER_ACTIVE))
01404     stpi_channel_set_ink_limit(v, stp_get_float_parameter(v, "InkLimit"));
01405   stpi_channel_initialize(v, image, lut->out_channels);
01406   lut->channels_are_initialized = 1;
01407 }
01408 
01409 static int
01410 stpi_color_traditional_get_row(stp_vars_t v,
01411                                stp_image_t *image,
01412                                int row,
01413                                unsigned *zero_mask)
01414 {
01415   const lut_t *lut = (const lut_t *)(stpi_get_component_data(v, "Color"));
01416   unsigned zero;
01417   if (stpi_image_get_row(image, lut->in_data,
01418                          lut->image_width * lut->image_bpp, row)
01419       != STP_IMAGE_STATUS_OK)
01420     return 2;
01421   if (!lut->channels_are_initialized)
01422     initialize_channels(v, image);
01423   zero = (lut->colorfunc)(v, lut->in_data, stpi_channel_get_input(v));
01424   if (zero_mask)
01425     *zero_mask = zero;
01426   stpi_channel_convert(v, zero_mask);
01427   return 0;
01428 }
01429 
01430 static lut_t *
01431 allocate_lut(void)
01432 {
01433   lut_t *ret = stpi_malloc(sizeof(lut_t));
01434   ret->composite = stp_curve_create(STP_CURVE_WRAP_NONE);
01435   ret->black = stp_curve_create(STP_CURVE_WRAP_NONE);
01436   ret->cyan = stp_curve_create(STP_CURVE_WRAP_NONE);
01437   ret->magenta = stp_curve_create(STP_CURVE_WRAP_NONE);
01438   ret->yellow = stp_curve_create(STP_CURVE_WRAP_NONE);
01439   stp_curve_set_bounds(ret->composite, 0, 65535);
01440   stp_curve_set_bounds(ret->black, 0, 65535);
01441   stp_curve_set_bounds(ret->cyan, 0, 65535);
01442   stp_curve_set_bounds(ret->magenta, 0, 65535);
01443   stp_curve_set_bounds(ret->yellow, 0, 65535);
01444   ret->hue_map = NULL;
01445   ret->lum_map = NULL;
01446   ret->sat_map = NULL;
01447   ret->gcr_curve = NULL;
01448   ret->steps = 0;
01449   ret->image_bpp = 0;
01450   ret->image_width = 0;
01451   ret->in_data = NULL;
01452   ret->colorfunc = NULL;
01453   ret->cmy_tmp = NULL;
01454   ret->cmyk_lut = NULL;
01455   ret->channels_are_initialized = 0;
01456   return ret;
01457 }
01458 
01459 static void *
01460 copy_lut(void *vlut)
01461 {
01462   const lut_t *src = (const lut_t *)vlut;
01463   lut_t *dest;
01464   if (!src)
01465     return NULL;
01466   dest = allocate_lut();
01467   dest->composite = stp_curve_create_copy(src->composite);
01468   dest->cyan = stp_curve_create_copy(src->cyan);
01469   dest->magenta = stp_curve_create_copy(src->magenta);
01470   dest->yellow = stp_curve_create_copy(src->yellow);
01471   if (src->hue_map)
01472     dest->hue_map = stp_curve_create_copy(src->hue_map);
01473   if (src->lum_map)
01474     dest->lum_map = stp_curve_create_copy(src->lum_map);
01475   if (src->sat_map)
01476     dest->sat_map = stp_curve_create_copy(src->sat_map);
01477   if (src->gcr_curve)
01478     dest->gcr_curve = stp_curve_create_copy(src->gcr_curve);
01479   dest->steps = src->steps;
01480   dest->colorfunc = src->colorfunc;
01481   dest->image_bpp = src->image_bpp;
01482   dest->image_width = src->image_width;
01483   dest->input_color_model = src->input_color_model;
01484   dest->output_color_model = src->output_color_model;
01485   dest->cmy_tmp = NULL;         /* Don't copy working storage */
01486   if (src->in_data)
01487     {
01488       dest->in_data = stpi_malloc(src->image_width * src->image_bpp);
01489       memset(dest->in_data, 0, src->image_width * src->image_bpp);
01490     }
01491   else
01492     dest->in_data = NULL;
01493   return dest;
01494 }
01495 
01496 static void
01497 free_lut(void *vlut)
01498 {
01499   lut_t *lut = (lut_t *)vlut;
01500   if (lut->composite)
01501     stp_curve_free(lut->composite);
01502   if (lut->black)
01503     stp_curve_free(lut->black);
01504   if (lut->cyan)
01505     stp_curve_free(lut->cyan);
01506   if (lut->magenta)
01507     stp_curve_free(lut->magenta);
01508   if (lut->yellow)
01509     stp_curve_free(lut->yellow);
01510   if (lut->hue_map)
01511     stp_curve_free(lut->hue_map);
01512   if (lut->lum_map)
01513     stp_curve_free(lut->lum_map);
01514   if (lut->sat_map)
01515     stp_curve_free(lut->sat_map);
01516   if (lut->gcr_curve)
01517     stp_curve_free(lut->gcr_curve);
01518   SAFE_FREE(lut->in_data);
01519   SAFE_FREE(lut->cmy_tmp);
01520   SAFE_FREE(lut->cmyk_lut);
01521   memset(lut, 0, sizeof(lut_t));
01522   stpi_free(lut);
01523 }
01524 
01525 static stp_curve_t
01526 compute_gcr_curve(stp_const_vars_t vars)
01527 {
01528   stp_curve_t curve;
01529   lut_t *lut = (lut_t *)(stpi_get_component_data(vars, "Color"));
01530   double k_lower = 0.0;
01531   double k_upper = 1.0;
01532   double k_gamma = 1.0;
01533   double i_k_gamma = 1.0;
01534   double *tmp_data = stpi_malloc(sizeof(double) * lut->steps);
01535   int i;
01536 
01537   if (stp_check_float_parameter(vars, "GCRUpper", STP_PARAMETER_DEFAULTED))
01538     k_upper = stp_get_float_parameter(vars, "GCRUpper");
01539   if (stp_check_float_parameter(vars, "GCRLower", STP_PARAMETER_DEFAULTED))
01540     k_lower = stp_get_float_parameter(vars, "GCRLower");
01541   if (stp_check_float_parameter(vars, "BlackGamma", STP_PARAMETER_DEFAULTED))
01542     k_gamma = stp_get_float_parameter(vars, "BlackGamma");
01543   k_upper *= lut->steps;
01544   k_lower *= lut->steps;
01545 
01546   if (k_lower > lut->steps)
01547     k_lower = lut->steps;
01548   if (k_upper < k_lower)
01549     k_upper = k_lower + 1;
01550   i_k_gamma = 1.0 / k_gamma;
01551 
01552   for (i = 0; i < k_lower; i ++)
01553     tmp_data[i] = 0;
01554   if (k_upper < lut->steps)
01555     {
01556       for (i = ceil(k_lower); i < k_upper; i ++)
01557         {
01558           double where = (i - k_lower) / (k_upper - k_lower);
01559           double g1 = pow(where, i_k_gamma);
01560           double g2 = 1.0 - pow(1.0 - where, k_gamma);
01561           double value = (g1 > g2 ? g1 : g2);
01562           tmp_data[i] = 65535.0 * k_upper * value / (double) (lut->steps - 1);
01563           tmp_data[i] = floor(tmp_data[i] + .5);
01564         }
01565       for (i = ceil(k_upper); i < lut->steps; i ++)
01566         tmp_data[i] = 65535.0 * i / (double) (lut->steps - 1);
01567     }
01568   else if (k_lower < lut->steps)
01569     for (i = ceil(k_lower); i < lut->steps; i ++)
01570       {
01571         double where = (i - k_lower) / (k_upper - k_lower);
01572         double g1 = pow(where, i_k_gamma);
01573         double g2 = 1.0 - pow(1.0 - where, k_gamma);
01574         double value = (g1 > g2 ? g1 : g2);
01575         tmp_data[i] = 65535.0 * lut->steps * value / (double) (lut->steps - 1);
01576         tmp_data[i] = floor(tmp_data[i] + .5);
01577       }
01578   curve = stp_curve_create(STP_CURVE_WRAP_NONE);
01579   stp_curve_set_bounds(curve, 0, 65535);
01580   if (! stp_curve_set_data(curve, lut->steps, tmp_data))
01581     {
01582       stpi_eprintf(vars, "set curve data failed!\n");
01583       stpi_abort();
01584     }
01585   stpi_free(tmp_data);
01586   return curve;
01587 }
01588 
01589 static stp_curve_t
01590 compute_a_curve(stp_curve_t curve, double c_gamma, lut_t *lut)
01591 {
01592   double *tmp = stpi_malloc(sizeof(double) * lut->steps);
01593   double pivot = .25;
01594   double ipivot = 1.0 - pivot;
01595   double xcontrast = pow(lut->contrast, lut->contrast);
01596   double xgamma = pow(pivot, lut->screen_gamma);
01597   int i;
01598   int isteps = lut->steps;
01599   if (isteps > 256)
01600     isteps = 256;
01601   for (i = 0; i < isteps; i ++)
01602     {
01603       double temp_pixel, pixel;
01604       pixel = (double) i / (double) (isteps - 1);
01605 
01606       if (lut->input_color_model == COLOR_MODEL_CMY)
01607         pixel = 1.0 - pixel;
01608 
01609       /*
01610        * First, correct contrast
01611        */
01612       if (pixel >= .5)
01613         temp_pixel = 1.0 - pixel;
01614       else
01615         temp_pixel = pixel;
01616       if (lut->contrast > 3.99999)
01617         {
01618           if (temp_pixel < .5)
01619             temp_pixel = 0;
01620           else
01621             temp_pixel = 1;
01622         }
01623       if (temp_pixel <= .000001 && lut->contrast <= .0001)
01624         temp_pixel = .5;
01625       else if (temp_pixel > 1)
01626         temp_pixel = .5 * pow(2 * temp_pixel, xcontrast);
01627       else if (temp_pixel < 1)
01628         {
01629           if (lut->linear_contrast_adjustment)
01630             temp_pixel = 0.5 -
01631               ((0.5 - .5 * pow(2 * temp_pixel, lut->contrast)) * lut->contrast);
01632           else
01633             temp_pixel = 0.5 -
01634               ((0.5 - .5 * pow(2 * temp_pixel, lut->contrast)));
01635         }
01636       if (temp_pixel > .5)
01637         temp_pixel = .5;
01638       else if (temp_pixel < 0)
01639         temp_pixel = 0;
01640       if (pixel < .5)
01641         pixel = temp_pixel;
01642       else
01643         pixel = 1 - temp_pixel;
01644 
01645       /*
01646        * Second, do brightness
01647        */
01648       if (lut->brightness < 1)
01649         pixel = pixel * lut->brightness;
01650       else
01651         pixel = 1 - ((1 - pixel) * (2 - lut->brightness));
01652 
01653       /*
01654        * Third, correct for the screen gamma
01655        */
01656 
01657       pixel = 1.0 -
01658         (1.0 / (1.0 - xgamma)) *
01659         (pow(pivot + ipivot * pixel, lut->screen_gamma) - xgamma);
01660 
01661       /*
01662        * Third, fix up cyan, magenta, yellow values
01663        */
01664       if (pixel < 0.0)
01665         pixel = 0.0;
01666       else if (pixel > 1.0)
01667         pixel = 1.0;
01668 
01669       if (pixel > .9999 && c_gamma < .00001)
01670         pixel = 0;
01671       else
01672         pixel = 1 - pow(1 - pixel, c_gamma);
01673 
01674       /*
01675        * Finally, fix up print gamma and scale
01676        */
01677 
01678       pixel = 65535 * pow(pixel, lut->print_gamma);     /* was + 0.5 here */
01679       if (lut->output_color_model == COLOR_MODEL_RGB)
01680         pixel = 65535 - pixel;
01681 
01682       if (pixel <= 0.0)
01683         tmp[i] = 0;
01684       else if (pixel >= 65535.0)
01685         tmp[i] = 65535;
01686       else
01687         tmp[i] = (pixel);
01688       tmp[i] = floor(tmp[i] + 0.5);                     /* rounding is done here */
01689     }
01690   stp_curve_set_data(curve, isteps, tmp);
01691   if (isteps != lut->steps)
01692     stp_curve_resample(curve, lut->steps);
01693   stpi_free(tmp);
01694   return curve;
01695 }
01696 
01697 static void
01698 invert_curve(stp_curve_t curve, int in_model, int out_model)
01699 {
01700   double lo, hi;
01701   int i;
01702   size_t count;
01703   const double *data = stp_curve_get_data(curve, &count);
01704   double f_gamma = stp_curve_get_gamma(curve);
01705   double *tmp_data;
01706 
01707   stp_curve_get_bounds(curve, &lo, &hi);
01708 
01709   if (f_gamma)
01710     stp_curve_set_gamma(curve, -f_gamma);
01711   else
01712     {
01713       tmp_data = stpi_malloc(sizeof(double) * count);
01714       for (i = 0; i < count; i++)
01715         tmp_data[i] = data[count - i - 1];
01716       stp_curve_set_data(curve, count, tmp_data);
01717       stpi_free(tmp_data);
01718     }
01719   if (in_model == out_model)
01720     {
01721       stp_curve_rescale(curve, -1, STP_CURVE_COMPOSE_MULTIPLY,
01722                         STP_CURVE_BOUNDS_RESCALE);
01723       stp_curve_rescale(curve, lo + hi, STP_CURVE_COMPOSE_ADD,
01724                         STP_CURVE_BOUNDS_RESCALE);
01725     }
01726 }
01727 
01728 static void
01729 compute_one_lut(stp_curve_t lut_curve, stp_const_curve_t curve,
01730                 double density, lut_t *lut)
01731 {
01732   if (curve)
01733     {
01734       stp_curve_copy(lut_curve, curve);
01735       invert_curve(lut_curve, lut->input_color_model, lut->output_color_model);
01736       stp_curve_rescale(lut_curve, 65535.0, STP_CURVE_COMPOSE_MULTIPLY,
01737                         STP_CURVE_BOUNDS_RESCALE);
01738       stp_curve_resample(lut_curve, lut->steps);
01739     }
01740   else
01741     {
01742       compute_a_curve(lut_curve, density, lut);
01743     }
01744 }
01745 
01746 static void
01747 initialize_cmyk_lut(stp_const_vars_t vars, size_t count)
01748 {
01749   lut_t *lut = (lut_t *)(stpi_get_component_data(vars, "Color"));
01750   if (!lut->cmyk_lut)
01751     {
01752       int i;
01753       double print_gamma = stp_get_float_parameter(vars, "Gamma");
01754       lut->cmyk_lut = stpi_malloc(sizeof(unsigned short) * 256);
01755 
01756       for (i = 0; i < count; i ++)
01757         lut->cmyk_lut[i] =
01758           (65535.0 * pow((double)i / (double) (count - 1), print_gamma)) + 0.5;
01759     }
01760 }
01761 
01762 static void
01763 initialize_gcr_curve(stp_const_vars_t vars)
01764 {
01765   lut_t *lut = (lut_t *)(stpi_get_component_data(vars, "Color"));
01766   if (!lut->gcr_curve)
01767     {
01768       if (stp_check_curve_parameter(vars, "GCRCurve", STP_PARAMETER_DEFAULTED))
01769         {
01770           double data;
01771           size_t count;
01772           int i;
01773           lut->gcr_curve =
01774             stp_curve_create_copy(stp_get_curve_parameter(vars, "GCRCurve"));
01775           stp_curve_resample(lut->gcr_curve, lut->steps);
01776           count = stp_curve_count_points(lut->gcr_curve);
01777           stp_curve_set_bounds(lut->gcr_curve, 0.0, 65535.0);
01778           for (i = 0; i < count; i++)
01779             {
01780               stp_curve_get_point(lut->gcr_curve, i, &data);
01781               data = 65535.0 * data * (double) i / (count - 1);
01782               stp_curve_set_point(lut->gcr_curve, i, data);
01783             }
01784         }
01785       else
01786         lut->gcr_curve = compute_gcr_curve(vars);
01787     }
01788 }
01789 
01790 static void
01791 initialize_composite_curve(stp_const_vars_t v, size_t count)
01792 {
01793   lut_t *lut = (lut_t *)(stpi_get_component_data(v, "Color"));
01794   if (!lut->composite)
01795     {
01796       stp_const_curve_t composite_curve = NULL;
01797       if (stp_get_curve_parameter_active(v, "CompositeCurve") >=
01798           stp_get_float_parameter_active(v, "Gamma"))
01799         composite_curve = stp_get_curve_parameter(v, "CompositeCurve");
01800       compute_one_lut(lut->composite, composite_curve, 1.0, lut);
01801     }
01802 }
01803 
01804 static void
01805 initialize_nothing(stp_const_vars_t v, size_t count)
01806 {
01807 }
01808 
01809 static void
01810 initialize_color_curves(stp_const_vars_t v, size_t count)
01811 {
01812   lut_t *lut = (lut_t *)(stpi_get_component_data(v, "Color"));
01813   if (!lut->cyan)
01814     {
01815       stp_const_curve_t cyan_curve = NULL;
01816       stp_const_curve_t magenta_curve = NULL;
01817       stp_const_curve_t yellow_curve = NULL;
01818       double cyan = 1.0;
01819       double magenta = 1.0;
01820       double yellow = 1.0;
01821       stp_const_curve_t hue = NULL;
01822       stp_const_curve_t lum = NULL;
01823       stp_const_curve_t sat = NULL;
01824       stp_const_curve_t black_curve = NULL;
01825 
01826       if (stp_check_float_parameter(v, "CyanGamma", STP_PARAMETER_DEFAULTED))
01827         cyan = stp_get_float_parameter(v, "CyanGamma");
01828       if (stp_check_float_parameter(v, "MagentaGamma", STP_PARAMETER_DEFAULTED))
01829         magenta = stp_get_float_parameter(v, "MagentaGamma");
01830       if (stp_check_float_parameter(v, "YellowGamma", STP_PARAMETER_DEFAULTED))
01831         yellow = stp_get_float_parameter(v, "YellowGamma");
01832 
01833       if (stp_check_curve_parameter(v, "HueMap", STP_PARAMETER_DEFAULTED))
01834         hue = stp_get_curve_parameter(v, "HueMap");
01835       if (stp_check_curve_parameter(v, "LumMap", STP_PARAMETER_DEFAULTED))
01836         lum = stp_get_curve_parameter(v, "LumMap");
01837       if (stp_check_curve_parameter(v, "SatMap", STP_PARAMETER_DEFAULTED))
01838         sat = stp_get_curve_parameter(v, "SatMap");
01839       if (stp_get_curve_parameter_active(v, "CyanCurve") >=
01840           stp_get_float_parameter_active(v, "Cyan"))
01841         cyan_curve = stp_get_curve_parameter(v, "CyanCurve");
01842       if (stp_get_curve_parameter_active(v, "MagentaCurve") >=
01843           stp_get_float_parameter_active(v, "Magenta"))
01844         magenta_curve = stp_get_curve_parameter(v, "MagentaCurve");
01845       if (stp_get_curve_parameter_active(v, "YellowCurve") >=
01846           stp_get_float_parameter_active(v, "Yellow"))
01847         yellow_curve = stp_get_curve_parameter(v, "YellowCurve");
01848       if (stp_check_curve_parameter(v, "BlackCurve", STP_PARAMETER_DEFAULTED))
01849         black_curve = stp_get_curve_parameter(v, "BlackCurve");
01850       /*
01851        * TODO check that these are wraparound curves and all that
01852        */
01853       if (hue)
01854         lut->hue_map = stp_curve_create_copy(hue);
01855       if (lum)
01856         lut->lum_map = stp_curve_create_copy(lum);
01857       if (sat)
01858         lut->sat_map = stp_curve_create_copy(sat);
01859       if (black_curve)
01860         stp_curve_copy(lut->black, black_curve);
01861       else
01862         stp_curve_copy(lut->black, color_curve_bounds);
01863       stp_curve_rescale(lut->black, 65535.0, STP_CURVE_COMPOSE_MULTIPLY,
01864                         STP_CURVE_BOUNDS_RESCALE);
01865       stp_curve_resample(lut->black, count);
01866 
01867       compute_one_lut(lut->cyan, cyan_curve, cyan, lut);
01868       compute_one_lut(lut->magenta, magenta_curve, magenta, lut);
01869       compute_one_lut(lut->yellow, yellow_curve, yellow, lut);
01870     }
01871 }
01872 
01873 static void
01874 stpi_compute_lut(stp_vars_t v, size_t steps)
01875 {
01876   lut_t *lut = allocate_lut();
01877 
01878   lut->input_color_model = stp_get_input_color_model(v);
01879   lut->output_color_model = stpi_get_output_color_model(v);
01880   lut->output_type = stp_get_output_type(v);
01881   lut->steps = steps;
01882   lut->linear_contrast_adjustment = 0;
01883   lut->print_gamma = 1.0;
01884   lut->app_gamma = 1.0;
01885   lut->contrast = 1.0;
01886   lut->brightness = 1.0;
01887 
01888   if (stp_check_boolean_parameter(v, "LinearContrast", STP_PARAMETER_DEFAULTED))
01889     lut->linear_contrast_adjustment =
01890       stp_get_boolean_parameter(v, "LinearContrast");
01891   if (stp_check_float_parameter(v, "Gamma", STP_PARAMETER_DEFAULTED))
01892     lut->print_gamma = stp_get_float_parameter(v, "Gamma");
01893   if (stp_check_float_parameter(v, "Contrast", STP_PARAMETER_DEFAULTED))
01894     lut->contrast = stp_get_float_parameter(v, "Contrast");
01895   if (stp_check_float_parameter(v, "Brightness", STP_PARAMETER_DEFAULTED))
01896     lut->brightness = stp_get_float_parameter(v, "Brightness");
01897 
01898   if (stp_check_float_parameter(v, "AppGamma", STP_PARAMETER_ACTIVE))
01899     lut->app_gamma = stp_get_float_parameter(v, "AppGamma");
01900   lut->screen_gamma = lut->app_gamma / 4.0; /* "Empirical" */
01901   lut->steps = steps;
01902   stpi_allocate_component_data(v, "Color", copy_lut, free_lut, lut);
01903 
01904   stpi_dprintf(STPI_DBG_LUT, v, "stpi_compute_lut\n");
01905   stpi_dprintf(STPI_DBG_LUT, v, " print_gamma %.3f\n", lut->print_gamma);
01906   stpi_dprintf(STPI_DBG_LUT, v, " contrast %.3f\n", lut->contrast);
01907   stpi_dprintf(STPI_DBG_LUT, v, " brightness %.3f\n", lut->brightness);
01908   stpi_dprintf(STPI_DBG_LUT, v, " screen_gamma %.3f\n", lut->screen_gamma);
01909 }
01910 
01911 #define SET_COLORFUNC(cfunc, initfunc)                                       \
01912 if (!cfunc)                                                                  \
01913   stpi_erprintf("No colorfunc chosen ");                                     \
01914 stpi_dprintf(STPI_DBG_COLORFUNC, v,                                          \
01915              "at line %d stp_choose_colorfunc(type %d bpp %d) ==> %s, %d\n", \
01916              __LINE__, lut->output_type, image_bpp, #cfunc,          \
01917              lut->out_channels);                                             \
01918 lut->colorfunc = cfunc;                                                      \
01919 if (initfunc)                                                                \
01920   (initfunc)(v, steps);                                                      \
01921 break
01922 
01923 static void
01924 setup_cmyk_output(stp_vars_t v, stp_image_t *image, size_t steps,
01925                   int itype)
01926 {
01927   lut_t *lut = (lut_t *)(stpi_get_component_data(v, "Color"));
01928   int image_bpp = stpi_image_bpp(image);
01929   switch (image_bpp)
01930     {
01931     case 1:
01932       switch (itype)
01933         {
01934         case 3:
01935           SET_COLORFUNC(gray_8_to_kcmy_line_art, initialize_nothing);
01936         case 2:
01937         case 1:
01938         case 0:
01939           SET_COLORFUNC(gray_8_to_kcmy, initialize_color_curves);
01940         default:
01941           SET_COLORFUNC(NULL, initialize_nothing);
01942         }
01943       break;
01944     case 2:
01945       switch (itype)
01946         {
01947         case 3:
01948           SET_COLORFUNC(gray_16_to_kcmy_line_art, initialize_nothing);
01949         case 2:
01950         case 1:
01951         case 0:
01952           SET_COLORFUNC(gray_16_to_kcmy, initialize_color_curves);
01953         default:
01954           SET_COLORFUNC(NULL, initialize_nothing);
01955         }
01956       break;
01957     case 3:
01958       switch (itype)
01959         {
01960         case 3:
01961           SET_COLORFUNC(rgb_8_to_kcmy_line_art, initialize_nothing);
01962         case 2:
01963         case 1:
01964           SET_COLORFUNC(rgb_8_to_kcmy, initialize_color_curves);
01965         case 0:
01966           SET_COLORFUNC(fast_rgb_8_to_kcmy, initialize_color_curves);
01967         default:
01968           SET_COLORFUNC(NULL, initialize_nothing);
01969         }
01970       break;
01971     case 6:
01972       switch (itype)
01973         {
01974         case 3:
01975           SET_COLORFUNC(rgb_16_to_kcmy_line_art, initialize_nothing);
01976         case 2:
01977         case 1:
01978           SET_COLORFUNC(rgb_16_to_kcmy, initialize_color_curves);
01979         case 0:
01980           SET_COLORFUNC(fast_rgb_16_to_kcmy, initialize_color_curves);
01981         default:
01982           SET_COLORFUNC(NULL, initialize_nothing);
01983         }
01984       break;
01985     case 4:
01986       switch (itype)
01987         {
01988         case 3:
01989           SET_COLORFUNC(cmyk_8_to_kcmy_line_art, initialize_nothing);
01990         case 2:
01991         case 1:
01992         case 0:
01993           SET_COLORFUNC(cmyk_8_to_kcmy, initialize_cmyk_lut);
01994         default:
01995           SET_COLORFUNC(NULL, initialize_nothing);
01996         }
01997       break;
01998     case 8:
01999       switch (itype)
02000         {
02001         case 3:
02002           SET_COLORFUNC(cmyk_16_to_kcmy_line_art, initialize_nothing);
02003         case 2:
02004         case 1:
02005         case 0:
02006           SET_COLORFUNC(cmyk_16_to_kcmy_raw, initialize_nothing);
02007         default:
02008           SET_COLORFUNC(NULL, initialize_nothing);
02009         }
02010       break;
02011     default:
02012       SET_COLORFUNC(NULL, initialize_nothing);
02013     }
02014 }  
02015 
02016 static void
02017 setup_color_output(stp_vars_t v, stp_image_t *image, size_t steps,
02018                    int itype)
02019 {
02020   lut_t *lut = (lut_t *)(stpi_get_component_data(v, "Color"));
02021   int image_bpp = stpi_image_bpp(image);
02022   switch (image_bpp)
02023     {
02024     case 1:
02025       switch (itype)
02026         {
02027         case 3:
02028           SET_COLORFUNC(gray_8_to_rgb_line_art, initialize_nothing);
02029         case 2:
02030         case 1:
02031         case 0:
02032           SET_COLORFUNC(gray_8_to_rgb, initialize_color_curves);
02033         default:
02034           SET_COLORFUNC(NULL, initialize_nothing);
02035         }
02036       break;
02037     case 2:
02038       switch (itype)
02039         {
02040         case 3:
02041           SET_COLORFUNC(gray_16_to_rgb_line_art, initialize_nothing);
02042         case 2:
02043         case 1:
02044         case 0:
02045           SET_COLORFUNC(gray_16_to_rgb, initialize_color_curves);
02046         default:
02047           SET_COLORFUNC(NULL, initialize_nothing);
02048         }
02049       break;
02050     case 3:
02051       switch (itype)
02052         {
02053         case 3:
02054           SET_COLORFUNC(rgb_8_to_rgb_line_art, initialize_nothing);
02055         case 2:
02056         case 1:
02057           SET_COLORFUNC(rgb_16_to_rgb, initialize_color_curves);
02058         case 0:
02059           SET_COLORFUNC(fast_rgb_16_to_rgb, initialize_color_curves);
02060         default:
02061           SET_COLORFUNC(NULL, initialize_nothing);
02062         }
02063       break;
02064     case 6:
02065       switch (itype)
02066         {
02067         case 3:
02068           SET_COLORFUNC(rgb_16_to_rgb_line_art, initialize_nothing);
02069         case 2:
02070         case 1:
02071           SET_COLORFUNC(rgb_16_to_rgb, initialize_color_curves);
02072         case 0:
02073           SET_COLORFUNC(fast_rgb_16_to_rgb, initialize_color_curves);
02074         default:
02075           SET_COLORFUNC(NULL, initialize_nothing);
02076         }
02077       break;
02078     default:
02079       SET_COLORFUNC(NULL, initialize_nothing);
02080     }
02081 }
02082 
02083 static void
02084 setup_gray_output(stp_vars_t v, stp_image_t *image, size_t steps,
02085                   int itype)
02086 {
02087   lut_t *lut = (lut_t *)(stpi_get_component_data(v, "Color"));
02088   int image_bpp = stpi_image_bpp(image);
02089   if (itype == 3)
02090     {
02091       switch (image_bpp)
02092         {
02093         case 1:
02094           SET_COLORFUNC(gray_8_to_gray_line_art, initialize_nothing);
02095         case 2:
02096           SET_COLORFUNC(gray_16_to_gray_line_art, initialize_nothing);
02097         case 3:
02098           SET_COLORFUNC(color_8_to_gray_line_art, initialize_nothing);
02099         case 6:
02100           SET_COLORFUNC(color_16_to_gray_line_art, initialize_nothing);
02101         case 4:
02102           SET_COLORFUNC(cmyk_8_to_gray_line_art, initialize_nothing);
02103         case 8:
02104           SET_COLORFUNC(cmyk_16_to_gray_line_art, initialize_nothing);
02105         default:
02106           SET_COLORFUNC(NULL, initialize_nothing);
02107         }
02108     }
02109   else if (itype >= 0 && itype <= 2)
02110     {
02111       switch (image_bpp)
02112         {
02113         case 1:
02114           SET_COLORFUNC(gray_8_to_gray, initialize_composite_curve);
02115         case 2:
02116           SET_COLORFUNC(gray_16_to_gray, initialize_composite_curve);
02117         case 3:
02118           SET_COLORFUNC(color_8_to_gray, initialize_composite_curve);
02119         case 6:
02120           SET_COLORFUNC(color_16_to_gray, initialize_composite_curve);
02121         case 4:
02122           SET_COLORFUNC(cmyk_8_to_gray, initialize_composite_curve);
02123         case 8:
02124           SET_COLORFUNC(cmyk_16_to_gray, initialize_composite_curve);
02125         default:
02126           SET_COLORFUNC(NULL, initialize_nothing);
02127         }
02128     }
02129   else
02130     {
02131       do
02132         {
02133           SET_COLORFUNC(NULL, initialize_nothing);
02134         }
02135       while (0);
02136     }
02137 }
02138 
02139 static int
02140 stpi_color_traditional_init(stp_vars_t v,
02141                             stp_image_t *image,
02142                             size_t steps)
02143 {
02144   const char *image_type = stp_get_string_parameter(v, "ImageType");
02145   const char *color_correction = stp_get_string_parameter(v, "ColorCorrection");
02146   int itype = 0;
02147   int image_bpp = stpi_image_bpp(image);
02148   lut_t *lut;
02149   if (steps != 256 && steps != 65536)
02150     return -1;
02151 
02152   stpi_compute_lut(v, steps);
02153   lut = (lut_t *)(stpi_get_component_data(v, "Color"));
02154   lut->image_bpp = image_bpp;
02155   lut->image_width = stpi_image_width(image);
02156   if (image_type && strcmp(image_type, "None") != 0)
02157     {
02158       if (strcmp(image_type, "Text") == 0)
02159         itype = 3;
02160       else
02161         itype = 2;
02162     }
02163   else if (color_correction)
02164     {
02165       if (strcmp(color_correction, "Uncorrected") == 0)
02166         itype = 0;
02167       else if (strcmp(color_correction, "Bright") == 0)
02168         itype = 1;
02169       else if (strcmp(color_correction, "Accurate") == 0)
02170         itype = 2;
02171       else if (strcmp(color_correction, "None") == 0)
02172         itype = 2;
02173       else if (strcmp(color_correction, "Threshold") == 0)
02174         itype = 3;
02175     }
02176   switch (lut->output_type)
02177     {
02178     case OUTPUT_RAW_CMYK:
02179       lut->out_channels = 4;
02180       setup_cmyk_output(v, image, steps, itype);
02181       break;
02182     case OUTPUT_COLOR:
02183       lut->out_channels = 3;
02184       setup_color_output(v, image, steps, itype);
02185       break;
02186     case OUTPUT_RAW_PRINTER:
02187       if ((image_bpp & 1) || image_bpp < 2 || image_bpp > 64)
02188         {
02189           SET_COLORFUNC(NULL, initialize_nothing);
02190         }
02191       lut->out_channels = image_bpp / 2;
02192       SET_COLORFUNC(raw_to_raw, initialize_nothing);
02193     case OUTPUT_GRAY:
02194       lut->out_channels = 1;
02195       setup_gray_output(v, image, steps, itype);
02196       break;
02197     default:
02198       SET_COLORFUNC(NULL, initialize_nothing);
02199     }
02200   lut->in_data = stpi_malloc(stpi_image_width(image) * image_bpp);
02201   memset(lut->in_data, 0, stpi_image_width(image) * image_bpp);
02202   return lut->out_channels;
02203 }
02204 
02205 static void
02206 initialize_standard_curves(void)
02207 {
02208   if (!standard_curves_initialized)
02209     {
02210       int i;
02211       hue_map_bounds = stp_curve_create_from_string
02212         ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
02213          "<gimp-print>\n"
02214          "<curve wrap=\"wrap\" type=\"linear\" gamma=\"0\">\n"
02215          "<sequence count=\"2\" lower-bound=\"-6\" upper-bound=\"6\">\n"
02216          "0 0\n"
02217          "</sequence>\n"
02218          "</curve>\n"
02219          "</gimp-print>");
02220       lum_map_bounds = stp_curve_create_from_string
02221         ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
02222          "<gimp-print>\n"
02223          "<curve wrap=\"wrap\" type=\"linear\" gamma=\"0\">\n"
02224          "<sequence count=\"2\" lower-bound=\"0\" upper-bound=\"4\">\n"
02225          "1 1\n"
02226          "</sequence>\n"
02227          "</curve>\n"
02228          "</gimp-print>");
02229       sat_map_bounds = stp_curve_create_from_string
02230         ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
02231          "<gimp-print>\n"
02232          "<curve wrap=\"wrap\" type=\"linear\" gamma=\"0\">\n"
02233          "<sequence count=\"2\" lower-bound=\"0\" upper-bound=\"4\">\n"
02234          "1 1\n"
02235          "</sequence>\n"
02236          "</curve>\n"
02237          "</gimp-print>");
02238       color_curve_bounds = stp_curve_create_from_string
02239         ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
02240          "<gimp-print>\n"
02241          "<curve wrap=\"nowrap\" type=\"linear\" gamma=\"1.0\">\n"
02242          "<sequence count=\"0\" lower-bound=\"0\" upper-bound=\"1\">\n"
02243          "</sequence>\n"
02244          "</curve>\n"
02245          "</gimp-print>");
02246       gcr_curve_bounds = stp_curve_create_from_string
02247         ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
02248          "<gimp-print>\n"
02249          "<curve wrap=\"nowrap\" type=\"linear\" gamma=\"0.0\">\n"
02250          "<sequence count=\"2\" lower-bound=\"0\" upper-bound=\"1\">\n"
02251          "1 1\n"
02252          "</sequence>\n"
02253          "</curve>\n"
02254          "</gimp-print>");
02255       for (i = 0; i < curve_parameter_count; i++)
02256         curve_parameters[i].param.deflt.curve =
02257          *(curve_parameters[i].defval);
02258       standard_curves_initialized = 1;
02259     }
02260 }
02261 
02262 static stp_parameter_list_t
02263 stpi_color_traditional_list_parameters(stp_const_vars_t v)
02264 {
02265   stpi_list_t *ret = stp_parameter_list_create();
02266   int i;
02267   initialize_standard_curves();
02268   for (i = 0; i < float_parameter_count; i++)
02269     stp_parameter_list_add_param(ret, &(float_parameters[i].param));
02270   for (i = 0; i < curve_parameter_count; i++)
02271     stp_parameter_list_add_param(ret, &(curve_parameters[i].param));
02272   return ret;
02273 }
02274 
02275 static void
02276 stpi_color_traditional_describe_parameter(stp_const_vars_t v,
02277                                           const char *name,
02278                                           stp_parameter_t *description)
02279 {
02280   int i;
02281   description->p_type = STP_PARAMETER_TYPE_INVALID;
02282   initialize_standard_curves();
02283   if (name == NULL)
02284     return;
02285   for (i = 0; i < float_parameter_count; i++)
02286     {
02287       const float_param_t *param = &(float_parameters[i]);
02288       if (strcmp(name, param->param.name) == 0)
02289         {
02290           stpi_fill_parameter_settings(description, &(param->param));
02291           if (param->color_only && stp_get_output_type(v) == OUTPUT_GRAY)
02292             description->is_active = 0;
02293           if (stp_check_string_parameter(v, "ImageType", STP_PARAMETER_ACTIVE) &&
02294               strcmp(stp_get_string_parameter(v, "ImageType"), "None") != 0 &&
02295               description->p_level > STP_PARAMETER_LEVEL_BASIC)
02296             description->is_active = 0;
02297           switch (param->param.p_type)
02298             {
02299             case STP_PARAMETER_TYPE_BOOLEAN:
02300               description->deflt.boolean = (int) param->defval;
02301             case STP_PARAMETER_TYPE_DOUBLE:
02302               description->bounds.dbl.upper = param->max;
02303               description->bounds.dbl.lower = param->min;
02304               description->deflt.dbl = param->defval;
02305               if (strcmp(name, "InkLimit") == 0)
02306                 {
02307                   stp_parameter_t ink_limit_desc;
02308                   stp_describe_parameter(v, "InkChannels", &ink_limit_desc);
02309                   if (ink_limit_desc.p_type == STP_PARAMETER_TYPE_INT)
02310                     {
02311                       if (ink_limit_desc.deflt.integer > 1)
02312                         {
02313                           description->bounds.dbl.upper =
02314                             ink_limit_desc.deflt.integer;
02315                           description->deflt.dbl =
02316                             ink_limit_desc.deflt.integer;
02317                         }
02318                       else
02319                         description->is_active = 0;
02320                     }
02321                   stp_parameter_description_free(&ink_limit_desc);
02322                 }
02323               break;
02324             case STP_PARAMETER_TYPE_STRING_LIST:
02325               if (!strcmp(param->param.name, "ColorCorrection"))
02326                 {
02327                   description->bounds.str = stp_string_list_create();
02328                   stp_string_list_add_string
02329                     (description->bounds.str, "None", _("Default"));
02330                   stp_string_list_add_string
02331                     (description->bounds.str, "Accurate", _("High Accuracy"));
02332                   stp_string_list_add_string
02333                     (description->bounds.str, "Bright", _("Bright"));
02334                   stp_string_list_add_string
02335                     (description->bounds.str, "Threshold", _("Threshold"));
02336                   stp_string_list_add_string
02337                     (description->bounds.str, "Uncorrected", _("Uncorrected"));
02338                   description->deflt.str = "None";
02339                 }
02340               break;
02341             default:
02342               break;
02343             }
02344           return;
02345         }
02346     }
02347   for (i = 0; i < curve_parameter_count; i++)
02348     {
02349       curve_param_t *param = &(curve_parameters[i]);
02350       if (strcmp(name, param->param.name) == 0)
02351         {
02352           description->is_active = 1;
02353           stpi_fill_parameter_settings(description, &(param->param));
02354           if (param->color_only && stp_get_output_type(v) == OUTPUT_GRAY)
02355             description->is_active = 0;
02356           if (stp_check_string_parameter(v, "ImageType", STP_PARAMETER_ACTIVE) &&
02357               strcmp(stp_get_string_parameter(v, "ImageType"), "None") != 0 &&
02358               description->p_level > STP_PARAMETER_LEVEL_BASIC)
02359             description->is_active = 0;
02360           if (param->hsl_only &&
02361               stp_check_string_parameter(v, "ColorCorrection",
02362                                          STP_PARAMETER_DEFAULTED) &&
02363               strcmp(stp_get_string_parameter(v, "ColorCorrection"),
02364                      "Uncorrected") == 0)
02365             description->is_active = 0;
02366           switch (param->param.p_type)
02367             {
02368             case STP_PARAMETER_TYPE_CURVE:
02369               description->deflt.curve = *(param->defval);
02370               description->bounds.curve =
02371                 stp_curve_create_copy(*(param->defval));
02372               break;
02373             default:
02374               break;
02375             }
02376           return;
02377         }
02378     }
02379 }
02380 
02381 
02382 static const stpi_colorfuncs_t stpi_color_traditional_colorfuncs =
02383 {
02384   &stpi_color_traditional_init,
02385   &stpi_color_traditional_get_row,
02386   &stpi_color_traditional_list_parameters,
02387   &stpi_color_traditional_describe_parameter
02388 };
02389 
02390 static const stpi_internal_color_t stpi_color_traditional_module_data =
02391   {
02392     COOKIE_COLOR,
02393     "traditional",
02394     N_("Traditional Gimp-Print color conversion"),
02395     &stpi_color_traditional_colorfuncs
02396   };
02397 
02398 
02399 static int
02400 color_traditional_module_init(void)
02401 {
02402   return stpi_color_register(&stpi_color_traditional_module_data);
02403 }
02404 
02405 
02406 static int
02407 color_traditional_module_exit(void)
02408 {
02409   return stpi_color_unregister(&stpi_color_traditional_module_data);
02410 }
02411 
02412 
02413 /* Module header */
02414 #define stpi_module_version color_traditional_LTX_stpi_module_version
02415 #define stpi_module_data color_traditional_LTX_stpi_module_data
02416 
02417 stpi_module_version_t stpi_module_version = {0, 0};
02418 
02419 stpi_module_t stpi_module_data =
02420   {
02421     "traditional",
02422     VERSION,
02423     "Traditional Gimp-Print color conversion",
02424     STPI_MODULE_CLASS_COLOR,
02425     NULL,
02426     color_traditional_module_init,
02427     color_traditional_module_exit,
02428     (void *) &stpi_color_traditional_module_data
02429   };

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