summaryrefslogtreecommitdiff
path: root/driver/cmyk.c
diff options
context:
space:
mode:
Diffstat (limited to 'driver/cmyk.c')
-rw-r--r--driver/cmyk.c1955
1 files changed, 0 insertions, 1955 deletions
diff --git a/driver/cmyk.c b/driver/cmyk.c
deleted file mode 100644
index 757584b9..00000000
--- a/driver/cmyk.c
+++ /dev/null
@@ -1,1955 +0,0 @@
-/*
- * "$Id: cmyk.c 9042 2010-03-24 00:45:34Z mike $"
- *
- * CMYK color separation code for CUPS.
- *
- * Copyright 2007-2010 by Apple Inc.
- * Copyright 1993-2005 by Easy Software Products.
- *
- * These coded instructions, statements, and computer programs are the
- * property of Apple Inc. and are protected by Federal copyright
- * law. Distribution and use rights are outlined in the file "LICENSE.txt"
- * which should have been included with this file. If this file is
- * file is missing or damaged, see the license at "http://www.cups.org/".
- *
- * Contents:
- *
- * cupsCMYKDelete() - Delete a color separation.
- * cupsCMYKDoBlack() - Do a black separation...
- * cupsCMYKDoCMYK() - Do a CMYK separation...
- * cupsCMYKDoGray() - Do a grayscale separation...
- * cupsCMYKDoRGB() - Do an sRGB separation...
- * cupsCMYKLoad() - Load a CMYK color profile from PPD attributes.
- * cupsCMYKNew() - Create a new CMYK color separation.
- * cupsCMYKSetBlack() - Set the transition range for CMY to black.
- * cupsCMYKSetCurve() - Set a color transform curve using points.
- * cupsCMYKSetGamma() - Set a color transform curve using gamma and
- * density.
- * cupsCMYKSetInkLimit() - Set the limit on the amount of ink.
- * cupsCMYKSetLtDk() - Set light/dark ink transforms.
- */
-
-/*
- * Include necessary headers.
- */
-
-#include "driver.h"
-#include <cups/string-private.h>
-
-
-/*
- * 'cupsCMYKDelete()' - Delete a color separation.
- */
-
-void
-cupsCMYKDelete(cups_cmyk_t *cmyk) /* I - Color separation */
-{
- /*
- * Range check input...
- */
-
- if (cmyk == NULL)
- return;
-
- /*
- * Free memory used...
- */
-
- free(cmyk->channels[0]);
- free(cmyk);
-}
-
-
-/*
- * 'cupsCMYKDoBlack()' - Do a black separation...
- */
-
-void
-cupsCMYKDoBlack(const cups_cmyk_t *cmyk,
- /* I - Color separation */
- const unsigned char *input,
- /* I - Input grayscale pixels */
- short *output,
- /* O - Output Device-N pixels */
- int num_pixels)
- /* I - Number of pixels */
-{
- int k; /* Current black value */
- const short **channels; /* Copy of channel LUTs */
- int ink, /* Amount of ink */
- ink_limit; /* Ink limit from separation */
-
-
- /*
- * Range check input...
- */
-
- if (cmyk == NULL || input == NULL || output == NULL || num_pixels <= 0)
- return;
-
- /*
- * Loop through it all...
- */
-
- channels = (const short **)cmyk->channels;
- ink_limit = cmyk->ink_limit;
-
- switch (cmyk->num_channels)
- {
- case 1 : /* Black */
- while (num_pixels > 0)
- {
- /*
- * Get the input black value and then set the corresponding color
- * channel values...
- */
-
- k = *input++;
- *output++ = channels[0][k];
-
- num_pixels --;
- }
- break;
-
- case 2 : /* Black, light black */
- while (num_pixels > 0)
- {
- /*
- * Get the input black value and then set the corresponding color
- * channel values...
- */
-
- k = *input++;
- output[0] = channels[0][k];
- output[1] = channels[1][k];
-
- if (ink_limit)
- {
- ink = output[0] + output[1];
-
- if (ink > ink_limit)
- {
- output[0] = ink_limit * output[0] / ink;
- output[1] = ink_limit * output[1] / ink;
- }
- }
-
- output += 2;
- num_pixels --;
- }
- break;
-
- case 3 : /* CMY */
- while (num_pixels > 0)
- {
- /*
- * Get the input black value and then set the corresponding color
- * channel values...
- */
-
- k = *input++;
- output[0] = channels[0][k];
- output[1] = channels[1][k];
- output[2] = channels[2][k];
-
- if (ink_limit)
- {
- ink = output[0] + output[1] + output[2];
-
- if (ink > ink_limit)
- {
- output[0] = ink_limit * output[0] / ink;
- output[1] = ink_limit * output[1] / ink;
- output[2] = ink_limit * output[2] / ink;
- }
- }
-
- output += 3;
- num_pixels --;
- }
- break;
-
- case 4 : /* CMYK */
- while (num_pixels > 0)
- {
- /*
- * Get the input black value and then set the corresponding color
- * channel values...
- */
-
- k = *input++;
- *output++ = 0;
- *output++ = 0;
- *output++ = 0;
- *output++ = channels[3][k];
-
- num_pixels --;
- }
- break;
-
- case 6 : /* CcMmYK */
- while (num_pixels > 0)
- {
- /*
- * Get the input black value and then set the corresponding color
- * channel values...
- */
-
- k = *input++;
- *output++ = 0;
- *output++ = 0;
- *output++ = 0;
- *output++ = 0;
- *output++ = 0;
- *output++ = channels[5][k];
-
- num_pixels --;
- }
- break;
-
- case 7 : /* CcMmYKk */
- while (num_pixels > 0)
- {
- /*
- * Get the input black value and then set the corresponding color
- * channel values...
- */
-
- k = *input++;
- output[0] = 0;
- output[1] = 0;
- output[2] = 0;
- output[3] = 0;
- output[4] = 0;
- output[5] = channels[5][k];
- output[6] = channels[6][k];
-
- if (ink_limit)
- {
- ink = output[5] + output[6];
-
- if (ink > ink_limit)
- {
- output[5] = ink_limit * output[5] / ink;
- output[6] = ink_limit * output[6] / ink;
- }
- }
-
- output += 7;
- num_pixels --;
- }
- break;
- }
-}
-
-
-/*
- * 'cupsCMYKDoCMYK()' - Do a CMYK separation...
- */
-
-void
-cupsCMYKDoCMYK(const cups_cmyk_t *cmyk,
- /* I - Color separation */
- const unsigned char *input,
- /* I - Input grayscale pixels */
- short *output,
- /* O - Output Device-N pixels */
- int num_pixels)
- /* I - Number of pixels */
-{
- int c, /* Current cyan value */
- m, /* Current magenta value */
- y, /* Current yellow value */
- k; /* Current black value */
- const short **channels; /* Copy of channel LUTs */
- int ink, /* Amount of ink */
- ink_limit; /* Ink limit from separation */
-
-
- /*
- * Range check input...
- */
-
- if (cmyk == NULL || input == NULL || output == NULL || num_pixels <= 0)
- return;
-
- /*
- * Loop through it all...
- */
-
- channels = (const short **)cmyk->channels;
- ink_limit = cmyk->ink_limit;
-
- switch (cmyk->num_channels)
- {
- case 1 : /* Black */
- while (num_pixels > 0)
- {
- /*
- * Get the input black value and then set the corresponding color
- * channel values...
- */
-
- c = *input++;
- m = *input++;
- y = *input++;
- k = *input++ + (c * 31 + m * 61 + y * 8) / 100;
-
- if (k < 255)
- *output++ = channels[0][k];
- else
- *output++ = channels[0][255];
-
- num_pixels --;
- }
- break;
-
- case 2 : /* Black, light black */
- while (num_pixels > 0)
- {
- /*
- * Get the input black value and then set the corresponding color
- * channel values...
- */
-
- c = *input++;
- m = *input++;
- y = *input++;
- k = *input++ + (c * 31 + m * 61 + y * 8) / 100;
-
- if (k < 255)
- {
- output[0] = channels[0][k];
- output[1] = channels[1][k];
- }
- else
- {
- output[0] = channels[0][255];
- output[1] = channels[1][255];
- }
-
- if (ink_limit)
- {
- ink = output[0] + output[1];
-
- if (ink > ink_limit)
- {
- output[0] = ink_limit * output[0] / ink;
- output[1] = ink_limit * output[1] / ink;
- }
- }
-
- output += 2;
- num_pixels --;
- }
- break;
-
- case 3 : /* CMY */
- while (num_pixels > 0)
- {
- /*
- * Get the input black value and then set the corresponding color
- * channel values...
- */
-
- c = *input++;
- m = *input++;
- y = *input++;
- k = *input++;
- c += k;
- m += k;
- y += k;
-
- if (c < 255)
- output[0] = channels[0][c];
- else
- output[0] = channels[0][255];
-
- if (m < 255)
- output[1] = channels[1][m];
- else
- output[1] = channels[1][255];
-
- if (y < 255)
- output[2] = channels[2][y];
- else
- output[2] = channels[2][255];
-
- if (ink_limit)
- {
- ink = output[0] + output[1] + output[2];
-
- if (ink > ink_limit)
- {
- output[0] = ink_limit * output[0] / ink;
- output[1] = ink_limit * output[1] / ink;
- output[2] = ink_limit * output[2] / ink;
- }
- }
-
- output += 3;
- num_pixels --;
- }
- break;
-
- case 4 : /* CMYK */
- while (num_pixels > 0)
- {
- /*
- * Get the input black value and then set the corresponding color
- * channel values...
- */
-
- c = *input++;
- m = *input++;
- y = *input++;
- k = *input++;
-
- output[0] = channels[0][c];
- output[1] = channels[1][m];
- output[2] = channels[2][y];
- output[3] = channels[3][k];
-
- if (ink_limit)
- {
- ink = output[0] + output[1] + output[2] + output[3];
-
- if (ink > ink_limit)
- {
- output[0] = ink_limit * output[0] / ink;
- output[1] = ink_limit * output[1] / ink;
- output[2] = ink_limit * output[2] / ink;
- output[3] = ink_limit * output[3] / ink;
- }
- }
-
- output += 4;
- num_pixels --;
- }
- break;
-
- case 6 : /* CcMmYK */
- while (num_pixels > 0)
- {
- /*
- * Get the input black value and then set the corresponding color
- * channel values...
- */
-
- c = *input++;
- m = *input++;
- y = *input++;
- k = *input++;
-
- output[0] = channels[0][c];
- output[1] = channels[1][c];
- output[2] = channels[2][m];
- output[3] = channels[3][m];
- output[4] = channels[4][y];
- output[5] = channels[5][k];
-
- if (ink_limit)
- {
- ink = output[0] + output[1] + output[2] + output[3] +
- output[4] + output[5];
-
- if (ink > ink_limit)
- {
- output[0] = ink_limit * output[0] / ink;
- output[1] = ink_limit * output[1] / ink;
- output[2] = ink_limit * output[2] / ink;
- output[3] = ink_limit * output[3] / ink;
- output[4] = ink_limit * output[4] / ink;
- output[5] = ink_limit * output[5] / ink;
- }
- }
-
- output += 6;
- num_pixels --;
- }
- break;
-
- case 7 : /* CcMmYKk */
- while (num_pixels > 0)
- {
- /*
- * Get the input black value and then set the corresponding color
- * channel values...
- */
-
- c = *input++;
- m = *input++;
- y = *input++;
- k = *input++;
-
- output[0] = channels[0][c];
- output[1] = channels[1][c];
- output[2] = channels[2][m];
- output[3] = channels[3][m];
- output[4] = channels[4][y];
- output[5] = channels[5][k];
- output[6] = channels[6][k];
-
- if (ink_limit)
- {
- ink = output[0] + output[1] + output[2] + output[3] +
- output[4] + output[5] + output[6];
-
- if (ink > ink_limit)
- {
- output[0] = ink_limit * output[0] / ink;
- output[1] = ink_limit * output[1] / ink;
- output[2] = ink_limit * output[2] / ink;
- output[3] = ink_limit * output[3] / ink;
- output[4] = ink_limit * output[4] / ink;
- output[5] = ink_limit * output[5] / ink;
- output[6] = ink_limit * output[6] / ink;
- }
- }
-
- output += 7;
- num_pixels --;
- }
- break;
- }
-}
-
-
-/*
- * 'cupsCMYKDoGray()' - Do a grayscale separation...
- */
-
-void
-cupsCMYKDoGray(const cups_cmyk_t *cmyk,
- /* I - Color separation */
- const unsigned char *input,
- /* I - Input grayscale pixels */
- short *output,
- /* O - Output Device-N pixels */
- int num_pixels)
- /* I - Number of pixels */
-{
- int k, /* Current black value */
- kc; /* Current black color value */
- const short **channels; /* Copy of channel LUTs */
- int ink, /* Amount of ink */
- ink_limit; /* Ink limit from separation */
-
-
- /*
- * Range check input...
- */
-
- if (cmyk == NULL || input == NULL || output == NULL || num_pixels <= 0)
- return;
-
- /*
- * Loop through it all...
- */
-
- channels = (const short **)cmyk->channels;
- ink_limit = cmyk->ink_limit;
-
- switch (cmyk->num_channels)
- {
- case 1 : /* Black */
- while (num_pixels > 0)
- {
- /*
- * Get the input black value and then set the corresponding color
- * channel values...
- */
-
- k = cups_scmy_lut[*input++];
- *output++ = channels[0][k];
-
- num_pixels --;
- }
- break;
-
- case 2 : /* Black, light black */
- while (num_pixels > 0)
- {
- /*
- * Get the input black value and then set the corresponding color
- * channel values...
- */
-
- k = cups_scmy_lut[*input++];
- output[0] = channels[0][k];
- output[1] = channels[1][k];
-
- if (ink_limit)
- {
- ink = output[0] + output[1];
-
- if (ink > ink_limit)
- {
- output[0] = ink_limit * output[0] / ink;
- output[1] = ink_limit * output[1] / ink;
- }
- }
-
- output += 2;
- num_pixels --;
- }
- break;
-
- case 3 : /* CMY */
- while (num_pixels > 0)
- {
- /*
- * Get the input black value and then set the corresponding color
- * channel values...
- */
-
- k = cups_scmy_lut[*input++];
- output[0] = channels[0][k];
- output[1] = channels[1][k];
- output[2] = channels[2][k];
-
- if (ink_limit)
- {
- ink = output[0] + output[1] + output[2];
-
- if (ink > ink_limit)
- {
- output[0] = ink_limit * output[0] / ink;
- output[1] = ink_limit * output[1] / ink;
- output[2] = ink_limit * output[2] / ink;
- }
- }
-
- output += 3;
- num_pixels --;
- }
- break;
-
- case 4 : /* CMYK */
- while (num_pixels > 0)
- {
- /*
- * Get the input black value and then set the corresponding color
- * channel values...
- */
-
- k = cups_scmy_lut[*input++];
- kc = cmyk->color_lut[k];
- k = cmyk->black_lut[k];
- output[0] = channels[0][kc];
- output[1] = channels[1][kc];
- output[2] = channels[2][kc];
- output[3] = channels[3][k];
-
- if (ink_limit)
- {
- ink = output[0] + output[1] + output[2] + output[3];
-
- if (ink > ink_limit)
- {
- output[0] = ink_limit * output[0] / ink;
- output[1] = ink_limit * output[1] / ink;
- output[2] = ink_limit * output[2] / ink;
- output[3] = ink_limit * output[3] / ink;
- }
- }
-
- output += 4;
- num_pixels --;
- }
- break;
-
- case 6 : /* CcMmYK */
- while (num_pixels > 0)
- {
- /*
- * Get the input black value and then set the corresponding color
- * channel values...
- */
-
- k = cups_scmy_lut[*input++];
- kc = cmyk->color_lut[k];
- k = cmyk->black_lut[k];
- output[0] = channels[0][kc];
- output[1] = channels[1][kc];
- output[2] = channels[2][kc];
- output[3] = channels[3][kc];
- output[4] = channels[4][kc];
- output[5] = channels[5][k];
-
- if (ink_limit)
- {
- ink = output[0] + output[1] + output[2] + output[3] +
- output[4] + output[5];
-
- if (ink > ink_limit)
- {
- output[0] = ink_limit * output[0] / ink;
- output[1] = ink_limit * output[1] / ink;
- output[2] = ink_limit * output[2] / ink;
- output[3] = ink_limit * output[3] / ink;
- output[4] = ink_limit * output[4] / ink;
- output[5] = ink_limit * output[5] / ink;
- }
- }
-
- output += 6;
- num_pixels --;
- }
- break;
-
- case 7 : /* CcMmYKk */
- while (num_pixels > 0)
- {
- /*
- * Get the input black value and then set the corresponding color
- * channel values...
- */
-
- k = cups_scmy_lut[*input++];
- kc = cmyk->color_lut[k];
- k = cmyk->black_lut[k];
- output[0] = channels[0][kc];
- output[1] = channels[1][kc];
- output[2] = channels[2][kc];
- output[3] = channels[3][kc];
- output[4] = channels[4][kc];
- output[5] = channels[5][k];
- output[6] = channels[6][k];
-
- if (ink_limit)
- {
- ink = output[0] + output[1] + output[2] + output[3] +
- output[4] + output[5] + output[6];
-
- if (ink > ink_limit)
- {
- output[0] = ink_limit * output[0] / ink;
- output[1] = ink_limit * output[1] / ink;
- output[2] = ink_limit * output[2] / ink;
- output[3] = ink_limit * output[3] / ink;
- output[4] = ink_limit * output[4] / ink;
- output[5] = ink_limit * output[5] / ink;
- output[6] = ink_limit * output[6] / ink;
- }
- }
-
- output += 7;
- num_pixels --;
- }
- break;
- }
-}
-
-
-/*
- * 'cupsCMYKDoRGB()' - Do an sRGB separation...
- */
-
-void
-cupsCMYKDoRGB(const cups_cmyk_t *cmyk,
- /* I - Color separation */
- const unsigned char *input,
- /* I - Input grayscale pixels */
- short *output,
- /* O - Output Device-N pixels */
- int num_pixels)
- /* I - Number of pixels */
-{
- int c, /* Current cyan value */
- m, /* Current magenta value */
- y, /* Current yellow value */
- k, /* Current black value */
- kc, /* Current black color value */
- km; /* Maximum black value */
- const short **channels; /* Copy of channel LUTs */
- int ink, /* Amount of ink */
- ink_limit; /* Ink limit from separation */
-
-
- /*
- * Range check input...
- */
-
- if (cmyk == NULL || input == NULL || output == NULL || num_pixels <= 0)
- return;
-
- /*
- * Loop through it all...
- */
-
- channels = (const short **)cmyk->channels;
- ink_limit = cmyk->ink_limit;
-
- switch (cmyk->num_channels)
- {
- case 1 : /* Black */
- while (num_pixels > 0)
- {
- /*
- * Get the input black value and then set the corresponding color
- * channel values...
- */
-
- c = cups_scmy_lut[*input++];
- m = cups_scmy_lut[*input++];
- y = cups_scmy_lut[*input++];
- k = (c * 31 + m * 61 + y * 8) / 100;
-
- *output++ = channels[0][k];
-
- num_pixels --;
- }
- break;
-
- case 2 : /* Black, light black */
- while (num_pixels > 0)
- {
- /*
- * Get the input black value and then set the corresponding color
- * channel values...
- */
-
- c = cups_scmy_lut[*input++];
- m = cups_scmy_lut[*input++];
- y = cups_scmy_lut[*input++];
- k = (c * 31 + m * 61 + y * 8) / 100;
-
- output[0] = channels[0][k];
- output[1] = channels[1][k];
-
- if (ink_limit)
- {
- ink = output[0] + output[1];
-
- if (ink > ink_limit)
- {
- output[0] = ink_limit * output[0] / ink;
- output[1] = ink_limit * output[1] / ink;
- }
- }
-
- output += 2;
- num_pixels --;
- }
- break;
-
- case 3 : /* CMY */
- while (num_pixels > 0)
- {
- /*
- * Get the input black value and then set the corresponding color
- * channel values...
- */
-
- c = cups_scmy_lut[*input++];
- m = cups_scmy_lut[*input++];
- y = cups_scmy_lut[*input++];
-
- output[0] = channels[0][c];
- output[1] = channels[1][m];
- output[2] = channels[2][y];
-
- if (ink_limit)
- {
- ink = output[0] + output[1] + output[2];
-
- if (ink > ink_limit)
- {
- output[0] = ink_limit * output[0] / ink;
- output[1] = ink_limit * output[1] / ink;
- output[2] = ink_limit * output[2] / ink;
- }
- }
-
- output += 3;
- num_pixels --;
- }
- break;
-
- case 4 : /* CMYK */
- while (num_pixels > 0)
- {
- /*
- * Get the input black value and then set the corresponding color
- * channel values...
- */
-
- c = cups_scmy_lut[*input++];
- m = cups_scmy_lut[*input++];
- y = cups_scmy_lut[*input++];
- k = min(c, min(m, y));
-
- if ((km = max(c, max(m, y))) > k)
- k = k * k * k / (km * km);
-
- kc = cmyk->color_lut[k] - k;
- k = cmyk->black_lut[k];
- c += kc;
- m += kc;
- y += kc;
-
- output[0] = channels[0][c];
- output[1] = channels[1][m];
- output[2] = channels[2][y];
- output[3] = channels[3][k];
-
- if (ink_limit)
- {
- ink = output[0] + output[1] + output[2] + output[3];
-
- if (ink > ink_limit)
- {
- output[0] = ink_limit * output[0] / ink;
- output[1] = ink_limit * output[1] / ink;
- output[2] = ink_limit * output[2] / ink;
- output[3] = ink_limit * output[3] / ink;
- }
- }
-
- output += 4;
- num_pixels --;
- }
- break;
-
- case 6 : /* CcMmYK */
- while (num_pixels > 0)
- {
- /*
- * Get the input black value and then set the corresponding color
- * channel values...
- */
-
- c = cups_scmy_lut[*input++];
- m = cups_scmy_lut[*input++];
- y = cups_scmy_lut[*input++];
- k = min(c, min(m, y));
-
- if ((km = max(c, max(m, y))) > k)
- k = k * k * k / (km * km);
-
- kc = cmyk->color_lut[k] - k;
- k = cmyk->black_lut[k];
- c += kc;
- m += kc;
- y += kc;
-
- output[0] = channels[0][c];
- output[1] = channels[1][c];
- output[2] = channels[2][m];
- output[3] = channels[3][m];
- output[4] = channels[4][y];
- output[5] = channels[5][k];
-
- if (ink_limit)
- {
- ink = output[0] + output[1] + output[2] + output[3] +
- output[4] + output[5];
-
- if (ink > ink_limit)
- {
- output[0] = ink_limit * output[0] / ink;
- output[1] = ink_limit * output[1] / ink;
- output[2] = ink_limit * output[2] / ink;
- output[3] = ink_limit * output[3] / ink;
- output[4] = ink_limit * output[4] / ink;
- output[5] = ink_limit * output[5] / ink;
- }
- }
-
- output += 6;
- num_pixels --;
- }
- break;
-
- case 7 : /* CcMmYKk */
- while (num_pixels > 0)
- {
- /*
- * Get the input black value and then set the corresponding color
- * channel values...
- */
-
- c = cups_scmy_lut[*input++];
- m = cups_scmy_lut[*input++];
- y = cups_scmy_lut[*input++];
- k = min(c, min(m, y));
-
- if ((km = max(c, max(m, y))) > k)
- k = k * k * k / (km * km);
-
- kc = cmyk->color_lut[k] - k;
- k = cmyk->black_lut[k];
- c += kc;
- m += kc;
- y += kc;
-
- output[0] = channels[0][c];
- output[1] = channels[1][c];
- output[2] = channels[2][m];
- output[3] = channels[3][m];
- output[4] = channels[4][y];
- output[5] = channels[5][k];
- output[6] = channels[6][k];
-
- if (ink_limit)
- {
- ink = output[0] + output[1] + output[2] + output[3] +
- output[4] + output[5] + output[6];
-
- if (ink > ink_limit)
- {
- output[0] = ink_limit * output[0] / ink;
- output[1] = ink_limit * output[1] / ink;
- output[2] = ink_limit * output[2] / ink;
- output[3] = ink_limit * output[3] / ink;
- output[4] = ink_limit * output[4] / ink;
- output[5] = ink_limit * output[5] / ink;
- output[6] = ink_limit * output[6] / ink;
- }
- }
-
- output += 7;
- num_pixels --;
- }
- break;
- }
-}
-
-
-/*
- * 'cupsCMYKLoad()' - Load a CMYK color profile from PPD attributes.
- */
-
-cups_cmyk_t * /* O - CMYK color separation */
-cupsCMYKLoad(ppd_file_t *ppd, /* I - PPD file */
- const char *colormodel, /* I - ColorModel value */
- const char *media, /* I - MediaType value */
- const char *resolution) /* I - Resolution value */
-{
- cups_cmyk_t *cmyk; /* CMYK color separation */
- char spec[PPD_MAX_NAME]; /* Profile name */
- ppd_attr_t *attr; /* Attribute from PPD file */
- int num_channels; /* Number of color components */
- float gamval, /* Gamma correction value */
- density, /* Density value */
- light, /* Light ink limit */
- dark, /* Light ink cut-off */
- lower, /* Start of black ink */
- upper; /* End of color ink */
- int num_xypoints; /* Number of X,Y points */
- float xypoints[100 * 2], /* X,Y points */
- *xyptr; /* Current X,Y point */
-
-
- /*
- * Range check input...
- */
-
- if (ppd == NULL || colormodel == NULL || resolution == NULL || media == NULL)
- return (NULL);
-
- /*
- * Find the following attributes:
- *
- * cupsAllGamma - Set default curve using gamma + density
- * cupsAllXY - Set default curve using XY points
- * cupsBlackGamma - Set black curve using gamma + density
- * cupsBlackGeneration - Set black generation
- * cupsBlackLightDark - Set black light/dark transition
- * cupsBlackXY - Set black curve using XY points
- * cupsCyanGamma - Set cyan curve using gamma + density
- * cupsCyanLightDark - Set cyan light/dark transition
- * cupsCyanXY - Set cyan curve using XY points
- * cupsInkChannels - Set number of color channels
- * cupsInkLimit - Set total ink limit
- * cupsLightBlackGamma - Set light black curve using gamma + density
- * cupsLightBlackXY - Set light black curve using XY points
- * cupsLightCyanGamma - Set light cyan curve using gamma + density
- * cupsLightCyanXY - Set light cyan curve using XY points
- * cupsLightMagentaGamma - Set light magenta curve using gamma + density
- * cupsLightMagentaXY - Set light magenta curve using XY points
- * cupsMagentaGamma - Set magenta curve using gamma + density
- * cupsMagentaLightDark - Set magenta light/dark transition
- * cupsMagentaXY - Set magenta curve using XY points
- * cupsYellowGamma - Set yellow curve using gamma + density
- * cupsYellowXY - Set yellow curve using XY points
- *
- * The only required attribute is cupsInkChannels.
- *
- * The *XY attributes have precedence over the *Gamma attributes, and
- * the *Light* attributes have precedence over the corresponding
- * *LightDark* attributes.
- */
-
- /*
- * Get the required cupsInkChannels attribute...
- */
-
- if ((attr = cupsFindAttr(ppd, "cupsInkChannels", colormodel, media,
- resolution, spec, sizeof(spec))) == NULL)
- return (NULL);
-
- num_channels = atoi(attr->value);
-
- if (num_channels < 1 || num_channels > 7 || num_channels == 5)
- return (NULL);
-
- if ((cmyk = cupsCMYKNew(num_channels)) == NULL)
- return (NULL);
-
- /*
- * Get the optional cupsInkLimit attribute...
- */
-
- if ((attr = cupsFindAttr(ppd, "cupsInkLimit", colormodel, media,
- resolution, spec, sizeof(spec))) != NULL)
- cupsCMYKSetInkLimit(cmyk, atof(attr->value));
-
- /*
- * Get the optional cupsBlackGeneration attribute...
- */
-
- if ((attr = cupsFindAttr(ppd, "cupsBlackGeneration", colormodel, media,
- resolution, spec, sizeof(spec))) != NULL)
- {
- if (sscanf(attr->value, "%f%f", &lower, &upper) == 2)
- cupsCMYKSetBlack(cmyk, lower, upper);
- }
-
- /*
- * Get the optional cupsBlackXY or cupsBlackGamma attributes...
- */
-
- if (num_channels != 3)
- {
- if ((attr = cupsFindAttr(ppd, "cupsBlackXY", colormodel, media,
- resolution, spec, sizeof(spec))) != NULL)
- {
- for (num_xypoints = 0, xyptr = xypoints;
- attr != NULL && attr->value != NULL && num_xypoints < 100;
- attr = ppdFindNextAttr(ppd, "cupsBlackXY", spec))
- if (sscanf(attr->value, "%f%f", xyptr, xyptr + 1) == 2)
- {
- num_xypoints ++;
- xyptr += 2;
- }
-
- switch (num_channels)
- {
- case 1 :
- case 2 :
- cupsCMYKSetCurve(cmyk, 0, num_xypoints, xypoints);
- break;
- case 4 :
- cupsCMYKSetCurve(cmyk, 3, num_xypoints, xypoints);
- break;
- case 6 :
- case 7 :
- cupsCMYKSetCurve(cmyk, 5, num_xypoints, xypoints);
- break;
- }
- }
- else if ((attr = cupsFindAttr(ppd, "cupsBlackGamma", colormodel,
- media, resolution, spec,
- sizeof(spec))) != NULL)
- {
- if (sscanf(attr->value, "%f%f", &gamval, &density) == 2)
- switch (num_channels)
- {
- case 1 :
- case 2 :
- cupsCMYKSetGamma(cmyk, 0, gamval, density);
- break;
- case 4 :
- cupsCMYKSetGamma(cmyk, 3, gamval, density);
- break;
- case 6 :
- case 7 :
- cupsCMYKSetGamma(cmyk, 5, gamval, density);
- break;
- }
- }
- else if ((attr = cupsFindAttr(ppd, "cupsAllXY", colormodel, media,
- resolution, spec, sizeof(spec))) != NULL)
- {
- for (num_xypoints = 0, xyptr = xypoints;
- attr != NULL && attr->value != NULL && num_xypoints < 100;
- attr = ppdFindNextAttr(ppd, "cupsAllXY", spec))
- if (sscanf(attr->value, "%f%f", xyptr, xyptr + 1) == 2)
- {
- num_xypoints ++;
- xyptr += 2;
- }
-
- switch (num_channels)
- {
- case 1 :
- case 2 :
- cupsCMYKSetCurve(cmyk, 0, num_xypoints, xypoints);
- break;
- case 4 :
- cupsCMYKSetCurve(cmyk, 3, num_xypoints, xypoints);
- break;
- case 6 :
- case 7 :
- cupsCMYKSetCurve(cmyk, 5, num_xypoints, xypoints);
- break;
- }
- }
- else if ((attr = cupsFindAttr(ppd, "cupsAllGamma", colormodel,
- media, resolution, spec,
- sizeof(spec))) != NULL &&
- num_channels != 3)
- {
- if (sscanf(attr->value, "%f%f", &gamval, &density) == 2)
- switch (num_channels)
- {
- case 1 :
- case 2 :
- cupsCMYKSetGamma(cmyk, 0, gamval, density);
- break;
- case 4 :
- cupsCMYKSetGamma(cmyk, 3, gamval, density);
- break;
- case 6 :
- case 7 :
- cupsCMYKSetGamma(cmyk, 5, gamval, density);
- break;
- }
- }
- }
-
- if (num_channels > 2)
- {
- /*
- * Get the optional cupsCyanXY or cupsCyanGamma attributes...
- */
-
- if ((attr = cupsFindAttr(ppd, "cupsCyanXY", colormodel, media,
- resolution, spec, sizeof(spec))) != NULL)
- {
- for (num_xypoints = 0, xyptr = xypoints;
- attr != NULL && attr->value != NULL && num_xypoints < 100;
- attr = ppdFindNextAttr(ppd, "cupsCyanXY", spec))
- if (sscanf(attr->value, "%f%f", xyptr, xyptr + 1) == 2)
- {
- num_xypoints ++;
- xyptr += 2;
- }
-
- cupsCMYKSetCurve(cmyk, 0, num_xypoints, xypoints);
- }
- else if ((attr = cupsFindAttr(ppd, "cupsCyanGamma", colormodel, media,
- resolution, spec, sizeof(spec))) != NULL)
- {
- if (sscanf(attr->value, "%f%f", &gamval, &density) == 2)
- cupsCMYKSetGamma(cmyk, 0, gamval, density);
- }
- else if ((attr = cupsFindAttr(ppd, "cupsAllXY", colormodel, media,
- resolution, spec, sizeof(spec))) != NULL)
- {
- for (num_xypoints = 0, xyptr = xypoints;
- attr != NULL && attr->value != NULL && num_xypoints < 100;
- attr = ppdFindNextAttr(ppd, "cupsAllXY", spec))
- if (sscanf(attr->value, "%f%f", xyptr, xyptr + 1) == 2)
- {
- num_xypoints ++;
- xyptr += 2;
- }
-
- cupsCMYKSetCurve(cmyk, 0, num_xypoints, xypoints);
- }
- else if ((attr = cupsFindAttr(ppd, "cupsAllGamma", colormodel, media,
- resolution, spec, sizeof(spec))) != NULL)
- {
- if (sscanf(attr->value, "%f%f", &gamval, &density) == 2)
- cupsCMYKSetGamma(cmyk, 0, gamval, density);
- }
-
- /*
- * Get the optional cupsMagentaXY or cupsMagentaGamma attributes...
- */
-
- if ((attr = cupsFindAttr(ppd, "cupsMagentaXY", colormodel, media,
- resolution, spec, sizeof(spec))) != NULL)
- {
- for (num_xypoints = 0, xyptr = xypoints;
- attr != NULL && attr->value != NULL && num_xypoints < 100;
- attr = ppdFindNextAttr(ppd, "cupsMagentaXY", spec))
- if (sscanf(attr->value, "%f%f", xyptr, xyptr + 1) == 2)
- {
- num_xypoints ++;
- xyptr += 2;
- }
-
- switch (num_channels)
- {
- case 3 :
- case 4 :
- cupsCMYKSetCurve(cmyk, 1, num_xypoints, xypoints);
- break;
- case 6 :
- case 7 :
- cupsCMYKSetCurve(cmyk, 2, num_xypoints, xypoints);
- break;
- }
- }
- else if ((attr = cupsFindAttr(ppd, "cupsMagentaGamma", colormodel, media,
- resolution, spec, sizeof(spec))) != NULL)
- {
- if (sscanf(attr->value, "%f%f", &gamval, &density) == 2)
- switch (num_channels)
- {
- case 3 :
- case 4 :
- cupsCMYKSetGamma(cmyk, 1, gamval, density);
- break;
- case 6 :
- case 7 :
- cupsCMYKSetGamma(cmyk, 2, gamval, density);
- break;
- }
- }
- else if ((attr = cupsFindAttr(ppd, "cupsAllXY", colormodel, media,
- resolution, spec, sizeof(spec))) != NULL)
- {
- for (num_xypoints = 0, xyptr = xypoints;
- attr != NULL && attr->value != NULL && num_xypoints < 100;
- attr = ppdFindNextAttr(ppd, "cupsAllXY", spec))
- if (sscanf(attr->value, "%f%f", xyptr, xyptr + 1) == 2)
- {
- num_xypoints ++;
- xyptr += 2;
- }
-
- switch (num_channels)
- {
- case 3 :
- case 4 :
- cupsCMYKSetCurve(cmyk, 1, num_xypoints, xypoints);
- break;
- case 6 :
- case 7 :
- cupsCMYKSetCurve(cmyk, 2, num_xypoints, xypoints);
- break;
- }
- }
- else if ((attr = cupsFindAttr(ppd, "cupsAllGamma", colormodel, media,
- resolution, spec, sizeof(spec))) != NULL)
- {
- if (sscanf(attr->value, "%f%f", &gamval, &density) == 2)
- switch (num_channels)
- {
- case 3 :
- case 4 :
- cupsCMYKSetGamma(cmyk, 1, gamval, density);
- break;
- case 6 :
- case 7 :
- cupsCMYKSetGamma(cmyk, 2, gamval, density);
- break;
- }
- }
-
- /*
- * Get the optional cupsYellowXY or cupsYellowGamma attributes...
- */
-
- if ((attr = cupsFindAttr(ppd, "cupsYellowXY", colormodel, media,
- resolution, spec, sizeof(spec))) != NULL)
- {
- for (num_xypoints = 0, xyptr = xypoints;
- attr != NULL && attr->value != NULL && num_xypoints < 100;
- attr = ppdFindNextAttr(ppd, "cupsYellowXY", spec))
- if (sscanf(attr->value, "%f%f", xyptr, xyptr + 1) == 2)
- {
- num_xypoints ++;
- xyptr += 2;
- }
-
- switch (num_channels)
- {
- case 3 :
- case 4 :
- cupsCMYKSetCurve(cmyk, 2, num_xypoints, xypoints);
- break;
- case 6 :
- case 7 :
- cupsCMYKSetCurve(cmyk, 4, num_xypoints, xypoints);
- break;
- }
- }
- else if ((attr = cupsFindAttr(ppd, "cupsYellowGamma", colormodel, media,
- resolution, spec, sizeof(spec))) != NULL)
- {
- if (sscanf(attr->value, "%f%f", &gamval, &density) == 2)
- switch (num_channels)
- {
- case 3 :
- case 4 :
- cupsCMYKSetGamma(cmyk, 2, gamval, density);
- break;
- case 6 :
- case 7 :
- cupsCMYKSetGamma(cmyk, 4, gamval, density);
- break;
- }
- }
- else if ((attr = cupsFindAttr(ppd, "cupsAllXY", colormodel, media,
- resolution, spec, sizeof(spec))) != NULL)
- {
- for (num_xypoints = 0, xyptr = xypoints;
- attr != NULL && attr->value != NULL && num_xypoints < 100;
- attr = ppdFindNextAttr(ppd, "cupsAllXY", spec))
- if (sscanf(attr->value, "%f%f", xyptr, xyptr + 1) == 2)
- {
- num_xypoints ++;
- xyptr += 2;
- }
-
- switch (num_channels)
- {
- case 3 :
- case 4 :
- cupsCMYKSetCurve(cmyk, 2, num_xypoints, xypoints);
- break;
- case 6 :
- case 7 :
- cupsCMYKSetCurve(cmyk, 4, num_xypoints, xypoints);
- break;
- }
- }
- else if ((attr = cupsFindAttr(ppd, "cupsAllGamma", colormodel, media,
- resolution, spec, sizeof(spec))) != NULL)
- {
- if (sscanf(attr->value, "%f%f", &gamval, &density) == 2)
- switch (num_channels)
- {
- case 3 :
- case 4 :
- cupsCMYKSetGamma(cmyk, 2, gamval, density);
- break;
- case 6 :
- case 7 :
- cupsCMYKSetGamma(cmyk, 4, gamval, density);
- break;
- }
- }
- }
-
- /*
- * Get the optional cupsLightBlackXY, cupsLightBlackGamma, or
- * cupsBlackLtDk attributes...
- */
-
- if (num_channels == 2 || num_channels == 7)
- {
- if ((attr = cupsFindAttr(ppd, "cupsLightBlackXY", colormodel, media,
- resolution, spec, sizeof(spec))) != NULL)
- {
- for (num_xypoints = 0, xyptr = xypoints;
- attr != NULL && attr->value != NULL && num_xypoints < 100;
- attr = ppdFindNextAttr(ppd, "cupsLightBlackXY", spec))
- if (sscanf(attr->value, "%f%f", xyptr, xyptr + 1) == 2)
- {
- num_xypoints ++;
- xyptr += 2;
- }
-
- switch (num_channels)
- {
- case 2 :
- cupsCMYKSetCurve(cmyk, 1, num_xypoints, xypoints);
- break;
- case 7 :
- cupsCMYKSetCurve(cmyk, 6, num_xypoints, xypoints);
- break;
- }
- }
- else if ((attr = cupsFindAttr(ppd, "cupsLightBlackGamma", colormodel,
- media, resolution, spec,
- sizeof(spec))) != NULL)
- {
- if (sscanf(attr->value, "%f%f", &gamval, &density) == 2)
- switch (num_channels)
- {
- case 2 :
- cupsCMYKSetGamma(cmyk, 1, gamval, density);
- break;
- case 7 :
- cupsCMYKSetGamma(cmyk, 6, gamval, density);
- break;
- }
- }
- else if ((attr = cupsFindAttr(ppd, "cupsBlackLtDk", colormodel, media,
- resolution, spec, sizeof(spec))) != NULL)
- {
- if (sscanf(attr->value, "%f%f", &light, &dark) == 2)
- switch (num_channels)
- {
- case 2 :
- cupsCMYKSetLtDk(cmyk, 0, light, dark);
- break;
- case 7 :
- cupsCMYKSetLtDk(cmyk, 5, light, dark);
- break;
- }
- else
- fprintf(stderr, "ERROR: Bad cupsBlackLtDk value \"%s\"!\n",
- attr->value);
- }
- else
- fprintf(stderr, "WARNING: No light black attribute found for %s!\n",
- spec);
- }
-
- if (num_channels >= 6)
- {
- /*
- * Get the optional cupsLightCyanXY, cupsLightCyanGamma, or
- * cupsCyanLtDk attributes...
- */
-
- if ((attr = cupsFindAttr(ppd, "cupsLightCyanXY", colormodel, media,
- resolution, spec, sizeof(spec))) != NULL)
- {
- for (num_xypoints = 0, xyptr = xypoints;
- attr != NULL && attr->value != NULL && num_xypoints < 100;
- attr = ppdFindNextAttr(ppd, "cupsLightCyanXY", spec))
- if (sscanf(attr->value, "%f%f", xyptr, xyptr + 1) == 2)
- {
- num_xypoints ++;
- xyptr += 2;
- }
-
- cupsCMYKSetCurve(cmyk, 1, num_xypoints, xypoints);
- }
- else if ((attr = cupsFindAttr(ppd, "cupsLightCyanGamma", colormodel,
- media, resolution, spec,
- sizeof(spec))) != NULL)
- {
- if (sscanf(attr->value, "%f%f", &gamval, &density) == 2)
- cupsCMYKSetGamma(cmyk, 1, gamval, density);
- }
- else if ((attr = cupsFindAttr(ppd, "cupsCyanLtDk", colormodel, media,
- resolution, spec, sizeof(spec))) != NULL)
- {
- if (sscanf(attr->value, "%f%f", &light, &dark) == 2)
- cupsCMYKSetLtDk(cmyk, 0, light, dark);
- else
- fprintf(stderr, "ERROR: Bad cupsCyanLtDk value \"%s\"!\n",
- attr->value);
- }
- else
- fprintf(stderr, "WARNING: No light cyan attribute found for %s!\n",
- spec);
-
- /*
- * Get the optional cupsLightMagentaXY, cupsLightMagentaGamma, or
- * cupsMagentaLtDk attributes...
- */
-
- if ((attr = cupsFindAttr(ppd, "cupsLightMagentaXY", colormodel, media,
- resolution, spec, sizeof(spec))) != NULL)
- {
- for (num_xypoints = 0, xyptr = xypoints;
- attr != NULL && attr->value != NULL && num_xypoints < 100;
- attr = ppdFindNextAttr(ppd, "cupsLightMagentaXY", spec))
- if (sscanf(attr->value, "%f%f", xyptr, xyptr + 1) == 2)
- {
- num_xypoints ++;
- xyptr += 2;
- }
-
- cupsCMYKSetCurve(cmyk, 3, num_xypoints, xypoints);
- }
- else if ((attr = cupsFindAttr(ppd, "cupsLightMagentaGamma", colormodel,
- media, resolution, spec,
- sizeof(spec))) != NULL)
- {
- if (sscanf(attr->value, "%f%f", &gamval, &density) == 2)
- cupsCMYKSetGamma(cmyk, 3, gamval, density);
- }
- else if ((attr = cupsFindAttr(ppd, "cupsMagentaLtDk", colormodel, media,
- resolution, spec, sizeof(spec))) != NULL)
- {
- if (sscanf(attr->value, "%f%f", &light, &dark) == 2)
- cupsCMYKSetLtDk(cmyk, 2, light, dark);
- else
- fprintf(stderr, "ERROR: Bad cupsMagentaLtDk value \"%s\"!\n",
- attr->value);
- }
- else
- fprintf(stderr, "WARNING: No light magenta attribute found for %s!\n",
- spec);
- }
-
- /*
- * Return the new profile...
- */
-
- return (cmyk);
-}
-
-
-/*
- * 'cupsCMYKNew()' - Create a new CMYK color separation.
- */
-
-cups_cmyk_t * /* O - New CMYK separation or NULL */
-cupsCMYKNew(int num_channels) /* I - Number of color components */
-{
- cups_cmyk_t *cmyk; /* New color separation */
- int i; /* Looping var */
-
-
- /*
- * Range-check the input...
- */
-
- if (num_channels < 1)
- return (NULL);
-
- /*
- * Allocate memory for the separation...
- */
-
- if ((cmyk = calloc(1, sizeof(cups_cmyk_t))) == NULL)
- return (NULL);
-
- /*
- * Allocate memory for the LUTs...
- */
-
- cmyk->num_channels = num_channels;
-
- if ((cmyk->channels[0] = calloc(num_channels * 256, sizeof(short))) == NULL)
- {
- free(cmyk);
- return (NULL);
- }
-
- for (i = 1; i < num_channels; i ++)
- cmyk->channels[i] = cmyk->channels[0] + i * 256;
-
- /*
- * Fill in the LUTs with unity transitions...
- */
-
- for (i = 0; i < 256; i ++)
- cmyk->black_lut[i] = i;
-
- switch (num_channels)
- {
- case 1 : /* K */
- case 2 : /* Kk */
- for (i = 0; i < 256; i ++)
- {
- cmyk->channels[0][i] = CUPS_MAX_LUT * i / 255;
- }
- break;
- case 3 : /* CMY */
- for (i = 0; i < 256; i ++)
- {
- cmyk->channels[0][i] = CUPS_MAX_LUT * i / 255;
- cmyk->channels[1][i] = CUPS_MAX_LUT * i / 255;
- cmyk->channels[2][i] = CUPS_MAX_LUT * i / 255;
- }
- break;
- case 4 : /* CMYK */
- for (i = 0; i < 256; i ++)
- {
- cmyk->channels[0][i] = CUPS_MAX_LUT * i / 255;
- cmyk->channels[1][i] = CUPS_MAX_LUT * i / 255;
- cmyk->channels[2][i] = CUPS_MAX_LUT * i / 255;
- cmyk->channels[3][i] = CUPS_MAX_LUT * i / 255;
- }
- break;
- case 6 : /* CcMmYK */
- case 7 : /* CcMmYKk */
- for (i = 0; i < 256; i ++)
- {
- cmyk->channels[0][i] = CUPS_MAX_LUT * i / 255;
- cmyk->channels[2][i] = CUPS_MAX_LUT * i / 255;
- cmyk->channels[4][i] = CUPS_MAX_LUT * i / 255;
- cmyk->channels[5][i] = CUPS_MAX_LUT * i / 255;
- }
- break;
- }
-
- /*
- * Return the separation...
- */
-
- return (cmyk);
-}
-
-
-/*
- * 'cupsCMYKSetBlack()' - Set the transition range for CMY to black.
- */
-
-void
-cupsCMYKSetBlack(cups_cmyk_t *cmyk, /* I - CMYK color separation */
- float lower, /* I - No black ink */
- float upper) /* I - Only black ink */
-{
- int i, /* Looping var */
- delta, /* Difference between lower and upper */
- ilower, /* Lower level from 0 to 255 */
- iupper; /* Upper level from 0 to 255 */
-
-
- /*
- * Range check input...
- */
-
- if (cmyk == NULL || lower < 0.0 || lower > 1.0 || upper < 0.0 || upper > 1.0 ||
- lower > upper)
- return;
-
- /*
- * Convert lower and upper to integers from 0 to 255...
- */
-
- ilower = (int)(255.0 * lower + 0.5);
- iupper = (int)(255.0 * upper + 0.5);
- delta = iupper - ilower;
-
- /*
- * Generate the CMY-only data...
- */
-
- for (i = 0; i < ilower; i ++)
- {
- cmyk->black_lut[i] = 0;
- cmyk->color_lut[i] = i;
- }
-
- /*
- * Then the transition data...
- */
-
- for (; i < iupper; i ++)
- {
- cmyk->black_lut[i] = iupper * (i - ilower) / delta;
- cmyk->color_lut[i] = ilower - ilower * (i - ilower) / delta;
- }
-
- /*
- * Then the K-only data...
- */
-
- for (; i < 256; i ++)
- {
- cmyk->black_lut[i] = i;
- cmyk->color_lut[i] = 0;
- }
-
- fprintf(stderr, "DEBUG: cupsCMYKSetBlack(cmyk, lower=%.3f, upper=%.3f)\n", lower, upper);
-
- for (i = 0; i < 256; i += 17)
- fprintf(stderr, "DEBUG: %3d = %3dk + %3dc\n", i,
- cmyk->black_lut[i], cmyk->color_lut[i]);
-}
-
-
-/*
- * 'cupsCMYKSetCurve()' - Set a color transform curve using points.
- */
-
-void
-cupsCMYKSetCurve(cups_cmyk_t *cmyk, /* I - CMYK color separation */
- int channel, /* I - Color channel */
- int num_xypoints,
- /* I - Number of X,Y points */
- const float *xypoints) /* I - X,Y points */
-{
- int i; /* Looping var */
- int xstart; /* Start position */
- int xend; /* End position */
- int xdelta; /* Difference in position */
- int ystart; /* Start value */
- int yend; /* End value */
- int ydelta; /* Difference in value */
-
-
- /*
- * Range check input...
- */
-
- if (cmyk == NULL || channel < 0 || channel >= cmyk->num_channels ||
- num_xypoints < 1 || xypoints == NULL)
- return;
-
- /*
- * Initialize the lookup table for the specified channel...
- */
-
- for (xstart = xend = 0, ystart = yend = 0;
- num_xypoints > 0;
- num_xypoints --, xypoints += 2, xstart = xend, ystart = yend)
- {
- xend = (int)(255.0 * xypoints[1] + 0.5);
- yend = (int)(CUPS_MAX_LUT * xypoints[0] + 0.5);
- xdelta = xend - xstart;
- ydelta = yend - ystart;
-
- for (i = xstart; i < xend; i ++)
- cmyk->channels[channel][i] = ystart + ydelta * (i - xstart) / xdelta;
- }
-
- /*
- * Initialize any trailing values to the maximum of the last data point...
- */
-
- for (i = xend; i < 256; i ++)
- cmyk->channels[channel][i] = yend;
-
- fprintf(stderr, "DEBUG: cupsCMYKSetXY(cmyk, channel=%d, num_xypoints=%d, "
- "xypoints=[%.3f %.3f %.3f %.3f ...])\n", channel,
- num_xypoints, xypoints[0], xypoints[1], xypoints[2], xypoints[3]);
-
- for (i = 0; i < 256; i += 17)
- fprintf(stderr, "DEBUG: %3d = %4d\n", i,
- cmyk->channels[channel + 0][i]);
-}
-
-
-/*
- * 'cupsCMYKSetGamma()' - Set a color transform curve using gamma and density.
- */
-
-void
-cupsCMYKSetGamma(cups_cmyk_t *cmyk, /* I - CMYK color separation */
- int channel, /* I - Ink channel */
- float gamval, /* I - Gamma correction */
- float density) /* I - Maximum density */
-{
- int i; /* Looping var */
-
-
- /*
- * Range check input...
- */
-
- if (cmyk == NULL || channel < 0 || channel >= cmyk->num_channels ||
- gamval <= 0.0 || density <= 0.0 || density > 1.0)
- return;
-
- /*
- * Initialize the lookup table for the specified channel...
- */
-
- for (i = 0; i < 256; i ++)
- cmyk->channels[channel][i] = (int)(density * CUPS_MAX_LUT *
- pow((float)i / 255.0, gamval) + 0.5);
-
- fprintf(stderr, "DEBUG: cupsCMYKSetGamma(cmyk, channel=%d, gamval=%.3f, "
- "density=%.3f)\n", channel, gamval, density);
-
- for (i = 0; i < 256; i += 17)
- fprintf(stderr, "DEBUG: %3d = %4d\n", i,
- cmyk->channels[channel + 0][i]);
-}
-
-
-/*
- * 'cupsCMYKSetInkLimit()' - Set the limit on the amount of ink.
- */
-
-void
-cupsCMYKSetInkLimit(cups_cmyk_t *cmyk, /* I - CMYK color separation */
- float limit) /* I - Limit of ink */
-{
- if (!cmyk || limit < 0.0)
- return;
-
- cmyk->ink_limit = limit * CUPS_MAX_LUT;
-}
-
-
-/*
- * 'cupsCMYKSetLtDk()' - Set light/dark ink transforms.
- */
-
-void
-cupsCMYKSetLtDk(cups_cmyk_t *cmyk, /* I - CMYK color separation */
- int channel, /* I - Dark ink channel (+1 for light) */
- float light, /* I - Light ink only level */
- float dark) /* I - Dark ink only level */
-{
- int i, /* Looping var */
- delta, /* Difference between lower and upper */
- ilight, /* Light level from 0 to 255 */
- idark; /* Dark level from 0 to 255 */
- short lut[256]; /* Original LUT data */
-
-
- /*
- * Range check input...
- */
-
- if (cmyk == NULL || light < 0.0 || light > 1.0 || dark < 0.0 || dark > 1.0 ||
- light > dark || channel < 0 || channel > (cmyk->num_channels - 2))
- return;
-
- /*
- * Convert lower and upper to integers from 0 to 255...
- */
-
- ilight = (int)(255.0 * light + 0.5);
- idark = (int)(255.0 * dark + 0.5);
- delta = idark - ilight;
-
- /*
- * Copy the dark ink LUT...
- */
-
- memcpy(lut, cmyk->channels[channel], sizeof(lut));
-
- /*
- * Generate the light-only data...
- */
-
- for (i = 0; i < ilight; i ++)
- {
- cmyk->channels[channel + 0][i] = 0;
- cmyk->channels[channel + 1][i] = CUPS_MAX_LUT * i / ilight;
- }
-
- /*
- * Then the transition data...
- */
-
- for (; i < idark; i ++)
- {
- cmyk->channels[channel + 0][i] = CUPS_MAX_LUT * idark * (i - ilight) /
- delta / 255;
- cmyk->channels[channel + 1][i] = CUPS_MAX_LUT - CUPS_MAX_LUT *
- (i - ilight) / delta;
- }
-
- /*
- * Then the K-only data...
- */
-
- for (; i < 256; i ++)
- {
- cmyk->channels[channel + 0][i] = CUPS_MAX_LUT * i / 255;
- cmyk->channels[channel + 1][i] = 0;
- }
-
- fprintf(stderr, "DEBUG: cupsCMYKSetLtDk(cmyk, channel=%d, light=%.3f, "
- "dark=%.3f)\n", channel, light, dark);
-
- for (i = 0; i < 256; i += 17)
- fprintf(stderr, "DEBUG: %3d = %4dlt + %4ddk\n", i,
- cmyk->channels[channel + 0][i], cmyk->channels[channel + 1][i]);
-}
-
-
-/*
- * End of "$Id: cmyk.c 9042 2010-03-24 00:45:34Z mike $".
- */