]>
git.ipfire.org Git - thirdparty/cups.git/blob - driver/cmyk.c
4 * CMYK color separation code for CUPS.
6 * Copyright 2007 by Apple Inc.
7 * Copyright 1993-2005 by Easy Software Products.
9 * These coded instructions, statements, and computer programs are the
10 * property of Apple Inc. and are protected by Federal copyright
11 * law. Distribution and use rights are outlined in the file "LICENSE.txt"
12 * which should have been included with this file. If this file is
13 * file is missing or damaged, see the license at "http://www.cups.org/".
17 * cupsCMYKDelete() - Delete a color separation.
18 * cupsCMYKDoBlack() - Do a black separation...
19 * cupsCMYKDoCMYK() - Do a CMYK separation...
20 * cupsCMYKDoGray() - Do a grayscale separation...
21 * cupsCMYKDoRGB() - Do an sRGB separation...
22 * cupsCMYKLoad() - Load a CMYK color profile from PPD attributes.
23 * cupsCMYKNew() - Create a new CMYK color separation.
24 * cupsCMYKSetBlack() - Set the transition range for CMY to black.
25 * cupsCMYKSetCurve() - Set a color transform curve using points.
26 * cupsCMYKSetGamma() - Set a color transform curve using gamma and
28 * cupsCMYKSetInkLimit() - Set the limit on the amount of ink.
29 * cupsCMYKSetLtDk() - Set light/dark ink transforms.
33 * Include necessary headers.
37 #include <cups/string.h>
41 * 'cupsCMYKDelete()' - Delete a color separation.
45 cupsCMYKDelete(cups_cmyk_t
*cmyk
) /* I - Color separation */
48 * Range check input...
58 free(cmyk
->channels
[0]);
64 * 'cupsCMYKDoBlack()' - Do a black separation...
68 cupsCMYKDoBlack(const cups_cmyk_t
*cmyk
,
69 /* I - Color separation */
70 const unsigned char *input
,
71 /* I - Input grayscale pixels */
73 /* O - Output Device-N pixels */
75 /* I - Number of pixels */
77 int k
; /* Current black value */
78 const short **channels
; /* Copy of channel LUTs */
79 const unsigned char *black_lut
, /* Black LUT */
80 *color_lut
; /* Color LUT */
81 int ink
, /* Amount of ink */
82 ink_limit
; /* Ink limit from separation */
86 * Range check input...
89 if (cmyk
== NULL
|| input
== NULL
|| output
== NULL
|| num_pixels
<= 0)
93 * Loop through it all...
96 channels
= (const short **)cmyk
->channels
;
97 black_lut
= cmyk
->black_lut
;
98 color_lut
= cmyk
->color_lut
;
99 ink_limit
= cmyk
->ink_limit
;
101 switch (cmyk
->num_channels
)
104 while (num_pixels
> 0)
107 * Get the input black value and then set the corresponding color
112 *output
++ = channels
[0][k
];
118 case 2 : /* Black, light black */
119 while (num_pixels
> 0)
122 * Get the input black value and then set the corresponding color
127 output
[0] = channels
[0][k
];
128 output
[1] = channels
[1][k
];
132 ink
= output
[0] + output
[1];
136 output
[0] = ink_limit
* output
[0] / ink
;
137 output
[1] = ink_limit
* output
[1] / ink
;
147 while (num_pixels
> 0)
150 * Get the input black value and then set the corresponding color
155 output
[0] = channels
[0][k
];
156 output
[1] = channels
[1][k
];
157 output
[2] = channels
[2][k
];
161 ink
= output
[0] + output
[1] + output
[2];
165 output
[0] = ink_limit
* output
[0] / ink
;
166 output
[1] = ink_limit
* output
[1] / ink
;
167 output
[2] = ink_limit
* output
[2] / ink
;
177 while (num_pixels
> 0)
180 * Get the input black value and then set the corresponding color
188 *output
++ = channels
[3][k
];
194 case 6 : /* CcMmYK */
195 while (num_pixels
> 0)
198 * Get the input black value and then set the corresponding color
208 *output
++ = channels
[5][k
];
214 case 7 : /* CcMmYKk */
215 while (num_pixels
> 0)
218 * Get the input black value and then set the corresponding color
228 output
[5] = channels
[5][k
];
229 output
[6] = channels
[6][k
];
233 ink
= output
[5] + output
[6];
237 output
[5] = ink_limit
* output
[5] / ink
;
238 output
[6] = ink_limit
* output
[6] / ink
;
251 * 'cupsCMYKDoCMYK()' - Do a CMYK separation...
255 cupsCMYKDoCMYK(const cups_cmyk_t
*cmyk
,
256 /* I - Color separation */
257 const unsigned char *input
,
258 /* I - Input grayscale pixels */
260 /* O - Output Device-N pixels */
262 /* I - Number of pixels */
264 int c
, /* Current cyan value */
265 m
, /* Current magenta value */
266 y
, /* Current yellow value */
267 k
; /* Current black value */
268 const short **channels
; /* Copy of channel LUTs */
269 const unsigned char *black_lut
, /* Black LUT */
270 *color_lut
; /* Color LUT */
271 int ink
, /* Amount of ink */
272 ink_limit
; /* Ink limit from separation */
276 * Range check input...
279 if (cmyk
== NULL
|| input
== NULL
|| output
== NULL
|| num_pixels
<= 0)
283 * Loop through it all...
286 channels
= (const short **)cmyk
->channels
;
287 black_lut
= cmyk
->black_lut
;
288 color_lut
= cmyk
->color_lut
;
289 ink_limit
= cmyk
->ink_limit
;
291 switch (cmyk
->num_channels
)
294 while (num_pixels
> 0)
297 * Get the input black value and then set the corresponding color
304 k
= *input
++ + (c
* 31 + m
* 61 + y
* 8) / 100;
307 *output
++ = channels
[0][k
];
309 *output
++ = channels
[0][255];
315 case 2 : /* Black, light black */
316 while (num_pixels
> 0)
319 * Get the input black value and then set the corresponding color
326 k
= *input
++ + (c
* 31 + m
* 61 + y
* 8) / 100;
330 output
[0] = channels
[0][k
];
331 output
[1] = channels
[1][k
];
335 output
[0] = channels
[0][255];
336 output
[1] = channels
[1][255];
341 ink
= output
[0] + output
[1];
345 output
[0] = ink_limit
* output
[0] / ink
;
346 output
[1] = ink_limit
* output
[1] / ink
;
356 while (num_pixels
> 0)
359 * Get the input black value and then set the corresponding color
372 output
[0] = channels
[0][c
];
374 output
[0] = channels
[0][255];
377 output
[1] = channels
[1][m
];
379 output
[1] = channels
[1][255];
382 output
[2] = channels
[2][y
];
384 output
[2] = channels
[2][255];
388 ink
= output
[0] + output
[1] + output
[2];
392 output
[0] = ink_limit
* output
[0] / ink
;
393 output
[1] = ink_limit
* output
[1] / ink
;
394 output
[2] = ink_limit
* output
[2] / ink
;
404 while (num_pixels
> 0)
407 * Get the input black value and then set the corresponding color
416 output
[0] = channels
[0][c
];
417 output
[1] = channels
[1][m
];
418 output
[2] = channels
[2][y
];
419 output
[3] = channels
[3][k
];
423 ink
= output
[0] + output
[1] + output
[2] + output
[3];
427 output
[0] = ink_limit
* output
[0] / ink
;
428 output
[1] = ink_limit
* output
[1] / ink
;
429 output
[2] = ink_limit
* output
[2] / ink
;
430 output
[3] = ink_limit
* output
[3] / ink
;
439 case 6 : /* CcMmYK */
440 while (num_pixels
> 0)
443 * Get the input black value and then set the corresponding color
452 output
[0] = channels
[0][c
];
453 output
[1] = channels
[1][c
];
454 output
[2] = channels
[2][m
];
455 output
[3] = channels
[3][m
];
456 output
[4] = channels
[4][y
];
457 output
[5] = channels
[5][k
];
461 ink
= output
[0] + output
[1] + output
[2] + output
[3] +
462 output
[4] + output
[5];
466 output
[0] = ink_limit
* output
[0] / ink
;
467 output
[1] = ink_limit
* output
[1] / ink
;
468 output
[2] = ink_limit
* output
[2] / ink
;
469 output
[3] = ink_limit
* output
[3] / ink
;
470 output
[4] = ink_limit
* output
[4] / ink
;
471 output
[5] = ink_limit
* output
[5] / ink
;
480 case 7 : /* CcMmYKk */
481 while (num_pixels
> 0)
484 * Get the input black value and then set the corresponding color
493 output
[0] = channels
[0][c
];
494 output
[1] = channels
[1][c
];
495 output
[2] = channels
[2][m
];
496 output
[3] = channels
[3][m
];
497 output
[4] = channels
[4][y
];
498 output
[5] = channels
[5][k
];
499 output
[6] = channels
[6][k
];
503 ink
= output
[0] + output
[1] + output
[2] + output
[3] +
504 output
[4] + output
[5] + output
[6];
508 output
[0] = ink_limit
* output
[0] / ink
;
509 output
[1] = ink_limit
* output
[1] / ink
;
510 output
[2] = ink_limit
* output
[2] / ink
;
511 output
[3] = ink_limit
* output
[3] / ink
;
512 output
[4] = ink_limit
* output
[4] / ink
;
513 output
[5] = ink_limit
* output
[5] / ink
;
514 output
[6] = ink_limit
* output
[6] / ink
;
527 * 'cupsCMYKDoGray()' - Do a grayscale separation...
531 cupsCMYKDoGray(const cups_cmyk_t
*cmyk
,
532 /* I - Color separation */
533 const unsigned char *input
,
534 /* I - Input grayscale pixels */
536 /* O - Output Device-N pixels */
538 /* I - Number of pixels */
540 int k
, /* Current black value */
541 kc
; /* Current black color value */
542 const short **channels
; /* Copy of channel LUTs */
543 const unsigned char *black_lut
, /* Black LUT */
544 *color_lut
; /* Color LUT */
545 int ink
, /* Amount of ink */
546 ink_limit
; /* Ink limit from separation */
550 * Range check input...
553 if (cmyk
== NULL
|| input
== NULL
|| output
== NULL
|| num_pixels
<= 0)
557 * Loop through it all...
560 channels
= (const short **)cmyk
->channels
;
561 black_lut
= cmyk
->black_lut
;
562 color_lut
= cmyk
->color_lut
;
563 ink_limit
= cmyk
->ink_limit
;
565 switch (cmyk
->num_channels
)
568 while (num_pixels
> 0)
571 * Get the input black value and then set the corresponding color
575 k
= cups_scmy_lut
[*input
++];
576 *output
++ = channels
[0][k
];
582 case 2 : /* Black, light black */
583 while (num_pixels
> 0)
586 * Get the input black value and then set the corresponding color
590 k
= cups_scmy_lut
[*input
++];
591 output
[0] = channels
[0][k
];
592 output
[1] = channels
[1][k
];
596 ink
= output
[0] + output
[1];
600 output
[0] = ink_limit
* output
[0] / ink
;
601 output
[1] = ink_limit
* output
[1] / ink
;
611 while (num_pixels
> 0)
614 * Get the input black value and then set the corresponding color
618 k
= cups_scmy_lut
[*input
++];
619 output
[0] = channels
[0][k
];
620 output
[1] = channels
[1][k
];
621 output
[2] = channels
[2][k
];
625 ink
= output
[0] + output
[1] + output
[2];
629 output
[0] = ink_limit
* output
[0] / ink
;
630 output
[1] = ink_limit
* output
[1] / ink
;
631 output
[2] = ink_limit
* output
[2] / ink
;
641 while (num_pixels
> 0)
644 * Get the input black value and then set the corresponding color
648 k
= cups_scmy_lut
[*input
++];
649 kc
= cmyk
->color_lut
[k
];
650 k
= cmyk
->black_lut
[k
];
651 output
[0] = channels
[0][kc
];
652 output
[1] = channels
[1][kc
];
653 output
[2] = channels
[2][kc
];
654 output
[3] = channels
[3][k
];
658 ink
= output
[0] + output
[1] + output
[2] + output
[3];
662 output
[0] = ink_limit
* output
[0] / ink
;
663 output
[1] = ink_limit
* output
[1] / ink
;
664 output
[2] = ink_limit
* output
[2] / ink
;
665 output
[3] = ink_limit
* output
[3] / ink
;
674 case 6 : /* CcMmYK */
675 while (num_pixels
> 0)
678 * Get the input black value and then set the corresponding color
682 k
= cups_scmy_lut
[*input
++];
683 kc
= cmyk
->color_lut
[k
];
684 k
= cmyk
->black_lut
[k
];
685 output
[0] = channels
[0][kc
];
686 output
[1] = channels
[1][kc
];
687 output
[2] = channels
[2][kc
];
688 output
[3] = channels
[3][kc
];
689 output
[4] = channels
[4][kc
];
690 output
[5] = channels
[5][k
];
694 ink
= output
[0] + output
[1] + output
[2] + output
[3] +
695 output
[4] + output
[5];
699 output
[0] = ink_limit
* output
[0] / ink
;
700 output
[1] = ink_limit
* output
[1] / ink
;
701 output
[2] = ink_limit
* output
[2] / ink
;
702 output
[3] = ink_limit
* output
[3] / ink
;
703 output
[4] = ink_limit
* output
[4] / ink
;
704 output
[5] = ink_limit
* output
[5] / ink
;
713 case 7 : /* CcMmYKk */
714 while (num_pixels
> 0)
717 * Get the input black value and then set the corresponding color
721 k
= cups_scmy_lut
[*input
++];
722 kc
= cmyk
->color_lut
[k
];
723 k
= cmyk
->black_lut
[k
];
724 output
[0] = channels
[0][kc
];
725 output
[1] = channels
[1][kc
];
726 output
[2] = channels
[2][kc
];
727 output
[3] = channels
[3][kc
];
728 output
[4] = channels
[4][kc
];
729 output
[5] = channels
[5][k
];
730 output
[6] = channels
[6][k
];
734 ink
= output
[0] + output
[1] + output
[2] + output
[3] +
735 output
[4] + output
[5] + output
[6];
739 output
[0] = ink_limit
* output
[0] / ink
;
740 output
[1] = ink_limit
* output
[1] / ink
;
741 output
[2] = ink_limit
* output
[2] / ink
;
742 output
[3] = ink_limit
* output
[3] / ink
;
743 output
[4] = ink_limit
* output
[4] / ink
;
744 output
[5] = ink_limit
* output
[5] / ink
;
745 output
[6] = ink_limit
* output
[6] / ink
;
758 * 'cupsCMYKDoRGB()' - Do an sRGB separation...
762 cupsCMYKDoRGB(const cups_cmyk_t
*cmyk
,
763 /* I - Color separation */
764 const unsigned char *input
,
765 /* I - Input grayscale pixels */
767 /* O - Output Device-N pixels */
769 /* I - Number of pixels */
771 int c
, /* Current cyan value */
772 m
, /* Current magenta value */
773 y
, /* Current yellow value */
774 k
, /* Current black value */
775 kc
, /* Current black color value */
776 km
; /* Maximum black value */
777 const short **channels
; /* Copy of channel LUTs */
778 const unsigned char *black_lut
, /* Black LUT */
779 *color_lut
; /* Color LUT */
780 int ink
, /* Amount of ink */
781 ink_limit
; /* Ink limit from separation */
785 * Range check input...
788 if (cmyk
== NULL
|| input
== NULL
|| output
== NULL
|| num_pixels
<= 0)
792 * Loop through it all...
795 channels
= (const short **)cmyk
->channels
;
796 black_lut
= cmyk
->black_lut
;
797 color_lut
= cmyk
->color_lut
;
798 ink_limit
= cmyk
->ink_limit
;
800 switch (cmyk
->num_channels
)
803 while (num_pixels
> 0)
806 * Get the input black value and then set the corresponding color
810 c
= cups_scmy_lut
[*input
++];
811 m
= cups_scmy_lut
[*input
++];
812 y
= cups_scmy_lut
[*input
++];
813 k
= (c
* 31 + m
* 61 + y
* 8) / 100;
815 *output
++ = channels
[0][k
];
821 case 2 : /* Black, light black */
822 while (num_pixels
> 0)
825 * Get the input black value and then set the corresponding color
829 c
= cups_scmy_lut
[*input
++];
830 m
= cups_scmy_lut
[*input
++];
831 y
= cups_scmy_lut
[*input
++];
832 k
= (c
* 31 + m
* 61 + y
* 8) / 100;
834 output
[0] = channels
[0][k
];
835 output
[1] = channels
[1][k
];
839 ink
= output
[0] + output
[1];
843 output
[0] = ink_limit
* output
[0] / ink
;
844 output
[1] = ink_limit
* output
[1] / ink
;
854 while (num_pixels
> 0)
857 * Get the input black value and then set the corresponding color
861 c
= cups_scmy_lut
[*input
++];
862 m
= cups_scmy_lut
[*input
++];
863 y
= cups_scmy_lut
[*input
++];
865 output
[0] = channels
[0][c
];
866 output
[1] = channels
[1][m
];
867 output
[2] = channels
[2][y
];
871 ink
= output
[0] + output
[1] + output
[2];
875 output
[0] = ink_limit
* output
[0] / ink
;
876 output
[1] = ink_limit
* output
[1] / ink
;
877 output
[2] = ink_limit
* output
[2] / ink
;
887 while (num_pixels
> 0)
890 * Get the input black value and then set the corresponding color
894 c
= cups_scmy_lut
[*input
++];
895 m
= cups_scmy_lut
[*input
++];
896 y
= cups_scmy_lut
[*input
++];
897 k
= min(c
, min(m
, y
));
899 if ((km
= max(c
, max(m
, y
))) > k
)
900 k
= k
* k
* k
/ (km
* km
);
902 kc
= cmyk
->color_lut
[k
] - k
;
903 k
= cmyk
->black_lut
[k
];
908 output
[0] = channels
[0][c
];
909 output
[1] = channels
[1][m
];
910 output
[2] = channels
[2][y
];
911 output
[3] = channels
[3][k
];
915 ink
= output
[0] + output
[1] + output
[2] + output
[3];
919 output
[0] = ink_limit
* output
[0] / ink
;
920 output
[1] = ink_limit
* output
[1] / ink
;
921 output
[2] = ink_limit
* output
[2] / ink
;
922 output
[3] = ink_limit
* output
[3] / ink
;
931 case 6 : /* CcMmYK */
932 while (num_pixels
> 0)
935 * Get the input black value and then set the corresponding color
939 c
= cups_scmy_lut
[*input
++];
940 m
= cups_scmy_lut
[*input
++];
941 y
= cups_scmy_lut
[*input
++];
942 k
= min(c
, min(m
, y
));
944 if ((km
= max(c
, max(m
, y
))) > k
)
945 k
= k
* k
* k
/ (km
* km
);
947 kc
= cmyk
->color_lut
[k
] - k
;
948 k
= cmyk
->black_lut
[k
];
953 output
[0] = channels
[0][c
];
954 output
[1] = channels
[1][c
];
955 output
[2] = channels
[2][m
];
956 output
[3] = channels
[3][m
];
957 output
[4] = channels
[4][y
];
958 output
[5] = channels
[5][k
];
962 ink
= output
[0] + output
[1] + output
[2] + output
[3] +
963 output
[4] + output
[5];
967 output
[0] = ink_limit
* output
[0] / ink
;
968 output
[1] = ink_limit
* output
[1] / ink
;
969 output
[2] = ink_limit
* output
[2] / ink
;
970 output
[3] = ink_limit
* output
[3] / ink
;
971 output
[4] = ink_limit
* output
[4] / ink
;
972 output
[5] = ink_limit
* output
[5] / ink
;
981 case 7 : /* CcMmYKk */
982 while (num_pixels
> 0)
985 * Get the input black value and then set the corresponding color
989 c
= cups_scmy_lut
[*input
++];
990 m
= cups_scmy_lut
[*input
++];
991 y
= cups_scmy_lut
[*input
++];
992 k
= min(c
, min(m
, y
));
994 if ((km
= max(c
, max(m
, y
))) > k
)
995 k
= k
* k
* k
/ (km
* km
);
997 kc
= cmyk
->color_lut
[k
] - k
;
998 k
= cmyk
->black_lut
[k
];
1003 output
[0] = channels
[0][c
];
1004 output
[1] = channels
[1][c
];
1005 output
[2] = channels
[2][m
];
1006 output
[3] = channels
[3][m
];
1007 output
[4] = channels
[4][y
];
1008 output
[5] = channels
[5][k
];
1009 output
[6] = channels
[6][k
];
1013 ink
= output
[0] + output
[1] + output
[2] + output
[3] +
1014 output
[4] + output
[5] + output
[6];
1016 if (ink
> ink_limit
)
1018 output
[0] = ink_limit
* output
[0] / ink
;
1019 output
[1] = ink_limit
* output
[1] / ink
;
1020 output
[2] = ink_limit
* output
[2] / ink
;
1021 output
[3] = ink_limit
* output
[3] / ink
;
1022 output
[4] = ink_limit
* output
[4] / ink
;
1023 output
[5] = ink_limit
* output
[5] / ink
;
1024 output
[6] = ink_limit
* output
[6] / ink
;
1037 * 'cupsCMYKLoad()' - Load a CMYK color profile from PPD attributes.
1040 cups_cmyk_t
* /* O - CMYK color separation */
1041 cupsCMYKLoad(ppd_file_t
*ppd
, /* I - PPD file */
1042 const char *colormodel
, /* I - ColorModel value */
1043 const char *media
, /* I - MediaType value */
1044 const char *resolution
) /* I - Resolution value */
1046 cups_cmyk_t
*cmyk
; /* CMYK color separation */
1047 char spec
[PPD_MAX_NAME
]; /* Profile name */
1048 ppd_attr_t
*attr
; /* Attribute from PPD file */
1049 int num_channels
; /* Number of color components */
1050 float gamval
, /* Gamma correction value */
1051 density
, /* Density value */
1052 light
, /* Light ink limit */
1053 dark
, /* Light ink cut-off */
1054 lower
, /* Start of black ink */
1055 upper
; /* End of color ink */
1056 int num_xypoints
; /* Number of X,Y points */
1057 float xypoints
[100 * 2], /* X,Y points */
1058 *xyptr
; /* Current X,Y point */
1062 * Range check input...
1065 if (ppd
== NULL
|| colormodel
== NULL
|| resolution
== NULL
|| media
== NULL
)
1069 * Find the following attributes:
1071 * cupsAllGamma - Set default curve using gamma + density
1072 * cupsAllXY - Set default curve using XY points
1073 * cupsBlackGamma - Set black curve using gamma + density
1074 * cupsBlackGeneration - Set black generation
1075 * cupsBlackLightDark - Set black light/dark transition
1076 * cupsBlackXY - Set black curve using XY points
1077 * cupsCyanGamma - Set cyan curve using gamma + density
1078 * cupsCyanLightDark - Set cyan light/dark transition
1079 * cupsCyanXY - Set cyan curve using XY points
1080 * cupsInkChannels - Set number of color channels
1081 * cupsInkLimit - Set total ink limit
1082 * cupsLightBlackGamma - Set light black curve using gamma + density
1083 * cupsLightBlackXY - Set light black curve using XY points
1084 * cupsLightCyanGamma - Set light cyan curve using gamma + density
1085 * cupsLightCyanXY - Set light cyan curve using XY points
1086 * cupsLightMagentaGamma - Set light magenta curve using gamma + density
1087 * cupsLightMagentaXY - Set light magenta curve using XY points
1088 * cupsMagentaGamma - Set magenta curve using gamma + density
1089 * cupsMagentaLightDark - Set magenta light/dark transition
1090 * cupsMagentaXY - Set magenta curve using XY points
1091 * cupsYellowGamma - Set yellow curve using gamma + density
1092 * cupsYellowXY - Set yellow curve using XY points
1094 * The only required attribute is cupsInkChannels.
1096 * The *XY attributes have precedence over the *Gamma attributes, and
1097 * the *Light* attributes have precedence over the corresponding
1098 * *LightDark* attributes.
1102 * Get the required cupsInkChannels attribute...
1105 if ((attr
= cupsFindAttr(ppd
, "cupsInkChannels", colormodel
, media
,
1106 resolution
, spec
, sizeof(spec
))) == NULL
)
1109 num_channels
= atoi(attr
->value
);
1111 if (num_channels
< 1 || num_channels
> 7 || num_channels
== 5)
1114 if ((cmyk
= cupsCMYKNew(num_channels
)) == NULL
)
1118 * Get the optional cupsInkLimit attribute...
1121 if ((attr
= cupsFindAttr(ppd
, "cupsInkLimit", colormodel
, media
,
1122 resolution
, spec
, sizeof(spec
))) != NULL
)
1123 cupsCMYKSetInkLimit(cmyk
, atof(attr
->value
));
1126 * Get the optional cupsBlackGeneration attribute...
1129 if ((attr
= cupsFindAttr(ppd
, "cupsBlackGeneration", colormodel
, media
,
1130 resolution
, spec
, sizeof(spec
))) != NULL
)
1132 if (sscanf(attr
->value
, "%f%f", &lower
, &upper
) == 2)
1133 cupsCMYKSetBlack(cmyk
, lower
, upper
);
1137 * Get the optional cupsBlackXY or cupsBlackGamma attributes...
1140 if (num_channels
!= 3)
1142 if ((attr
= cupsFindAttr(ppd
, "cupsBlackXY", colormodel
, media
,
1143 resolution
, spec
, sizeof(spec
))) != NULL
)
1145 for (num_xypoints
= 0, xyptr
= xypoints
;
1146 attr
!= NULL
&& attr
->value
!= NULL
&& num_xypoints
< 100;
1147 attr
= ppdFindNextAttr(ppd
, "cupsBlackXY", spec
))
1148 if (sscanf(attr
->value
, "%f%f", xyptr
, xyptr
+ 1) == 2)
1154 switch (num_channels
)
1158 cupsCMYKSetCurve(cmyk
, 0, num_xypoints
, xypoints
);
1161 cupsCMYKSetCurve(cmyk
, 3, num_xypoints
, xypoints
);
1165 cupsCMYKSetCurve(cmyk
, 5, num_xypoints
, xypoints
);
1169 else if ((attr
= cupsFindAttr(ppd
, "cupsBlackGamma", colormodel
,
1170 media
, resolution
, spec
,
1171 sizeof(spec
))) != NULL
)
1173 if (sscanf(attr
->value
, "%f%f", &gamval
, &density
) == 2)
1174 switch (num_channels
)
1178 cupsCMYKSetGamma(cmyk
, 0, gamval
, density
);
1181 cupsCMYKSetGamma(cmyk
, 3, gamval
, density
);
1185 cupsCMYKSetGamma(cmyk
, 5, gamval
, density
);
1189 else if ((attr
= cupsFindAttr(ppd
, "cupsAllXY", colormodel
, media
,
1190 resolution
, spec
, sizeof(spec
))) != NULL
)
1192 for (num_xypoints
= 0, xyptr
= xypoints
;
1193 attr
!= NULL
&& attr
->value
!= NULL
&& num_xypoints
< 100;
1194 attr
= ppdFindNextAttr(ppd
, "cupsAllXY", spec
))
1195 if (sscanf(attr
->value
, "%f%f", xyptr
, xyptr
+ 1) == 2)
1201 switch (num_channels
)
1205 cupsCMYKSetCurve(cmyk
, 0, num_xypoints
, xypoints
);
1208 cupsCMYKSetCurve(cmyk
, 3, num_xypoints
, xypoints
);
1212 cupsCMYKSetCurve(cmyk
, 5, num_xypoints
, xypoints
);
1216 else if ((attr
= cupsFindAttr(ppd
, "cupsAllGamma", colormodel
,
1217 media
, resolution
, spec
,
1218 sizeof(spec
))) != NULL
&&
1221 if (sscanf(attr
->value
, "%f%f", &gamval
, &density
) == 2)
1222 switch (num_channels
)
1226 cupsCMYKSetGamma(cmyk
, 0, gamval
, density
);
1229 cupsCMYKSetGamma(cmyk
, 3, gamval
, density
);
1233 cupsCMYKSetGamma(cmyk
, 5, gamval
, density
);
1239 if (num_channels
> 2)
1242 * Get the optional cupsCyanXY or cupsCyanGamma attributes...
1245 if ((attr
= cupsFindAttr(ppd
, "cupsCyanXY", colormodel
, media
,
1246 resolution
, spec
, sizeof(spec
))) != NULL
)
1248 for (num_xypoints
= 0, xyptr
= xypoints
;
1249 attr
!= NULL
&& attr
->value
!= NULL
&& num_xypoints
< 100;
1250 attr
= ppdFindNextAttr(ppd
, "cupsCyanXY", spec
))
1251 if (sscanf(attr
->value
, "%f%f", xyptr
, xyptr
+ 1) == 2)
1257 cupsCMYKSetCurve(cmyk
, 0, num_xypoints
, xypoints
);
1259 else if ((attr
= cupsFindAttr(ppd
, "cupsCyanGamma", colormodel
, media
,
1260 resolution
, spec
, sizeof(spec
))) != NULL
)
1262 if (sscanf(attr
->value
, "%f%f", &gamval
, &density
) == 2)
1263 cupsCMYKSetGamma(cmyk
, 0, gamval
, density
);
1265 else if ((attr
= cupsFindAttr(ppd
, "cupsAllXY", colormodel
, media
,
1266 resolution
, spec
, sizeof(spec
))) != NULL
)
1268 for (num_xypoints
= 0, xyptr
= xypoints
;
1269 attr
!= NULL
&& attr
->value
!= NULL
&& num_xypoints
< 100;
1270 attr
= ppdFindNextAttr(ppd
, "cupsAllXY", spec
))
1271 if (sscanf(attr
->value
, "%f%f", xyptr
, xyptr
+ 1) == 2)
1277 cupsCMYKSetCurve(cmyk
, 0, num_xypoints
, xypoints
);
1279 else if ((attr
= cupsFindAttr(ppd
, "cupsAllGamma", colormodel
, media
,
1280 resolution
, spec
, sizeof(spec
))) != NULL
)
1282 if (sscanf(attr
->value
, "%f%f", &gamval
, &density
) == 2)
1283 cupsCMYKSetGamma(cmyk
, 0, gamval
, density
);
1287 * Get the optional cupsMagentaXY or cupsMagentaGamma attributes...
1290 if ((attr
= cupsFindAttr(ppd
, "cupsMagentaXY", colormodel
, media
,
1291 resolution
, spec
, sizeof(spec
))) != NULL
)
1293 for (num_xypoints
= 0, xyptr
= xypoints
;
1294 attr
!= NULL
&& attr
->value
!= NULL
&& num_xypoints
< 100;
1295 attr
= ppdFindNextAttr(ppd
, "cupsMagentaXY", spec
))
1296 if (sscanf(attr
->value
, "%f%f", xyptr
, xyptr
+ 1) == 2)
1302 switch (num_channels
)
1306 cupsCMYKSetCurve(cmyk
, 1, num_xypoints
, xypoints
);
1310 cupsCMYKSetCurve(cmyk
, 2, num_xypoints
, xypoints
);
1314 else if ((attr
= cupsFindAttr(ppd
, "cupsMagentaGamma", colormodel
, media
,
1315 resolution
, spec
, sizeof(spec
))) != NULL
)
1317 if (sscanf(attr
->value
, "%f%f", &gamval
, &density
) == 2)
1318 switch (num_channels
)
1322 cupsCMYKSetGamma(cmyk
, 1, gamval
, density
);
1326 cupsCMYKSetGamma(cmyk
, 2, gamval
, density
);
1330 else if ((attr
= cupsFindAttr(ppd
, "cupsAllXY", colormodel
, media
,
1331 resolution
, spec
, sizeof(spec
))) != NULL
)
1333 for (num_xypoints
= 0, xyptr
= xypoints
;
1334 attr
!= NULL
&& attr
->value
!= NULL
&& num_xypoints
< 100;
1335 attr
= ppdFindNextAttr(ppd
, "cupsAllXY", spec
))
1336 if (sscanf(attr
->value
, "%f%f", xyptr
, xyptr
+ 1) == 2)
1342 switch (num_channels
)
1346 cupsCMYKSetCurve(cmyk
, 1, num_xypoints
, xypoints
);
1350 cupsCMYKSetCurve(cmyk
, 2, num_xypoints
, xypoints
);
1354 else if ((attr
= cupsFindAttr(ppd
, "cupsAllGamma", colormodel
, media
,
1355 resolution
, spec
, sizeof(spec
))) != NULL
)
1357 if (sscanf(attr
->value
, "%f%f", &gamval
, &density
) == 2)
1358 switch (num_channels
)
1362 cupsCMYKSetGamma(cmyk
, 1, gamval
, density
);
1366 cupsCMYKSetGamma(cmyk
, 2, gamval
, density
);
1372 * Get the optional cupsYellowXY or cupsYellowGamma attributes...
1375 if ((attr
= cupsFindAttr(ppd
, "cupsYellowXY", colormodel
, media
,
1376 resolution
, spec
, sizeof(spec
))) != NULL
)
1378 for (num_xypoints
= 0, xyptr
= xypoints
;
1379 attr
!= NULL
&& attr
->value
!= NULL
&& num_xypoints
< 100;
1380 attr
= ppdFindNextAttr(ppd
, "cupsYellowXY", spec
))
1381 if (sscanf(attr
->value
, "%f%f", xyptr
, xyptr
+ 1) == 2)
1387 switch (num_channels
)
1391 cupsCMYKSetCurve(cmyk
, 2, num_xypoints
, xypoints
);
1395 cupsCMYKSetCurve(cmyk
, 4, num_xypoints
, xypoints
);
1399 else if ((attr
= cupsFindAttr(ppd
, "cupsYellowGamma", colormodel
, media
,
1400 resolution
, spec
, sizeof(spec
))) != NULL
)
1402 if (sscanf(attr
->value
, "%f%f", &gamval
, &density
) == 2)
1403 switch (num_channels
)
1407 cupsCMYKSetGamma(cmyk
, 2, gamval
, density
);
1411 cupsCMYKSetGamma(cmyk
, 4, gamval
, density
);
1415 else if ((attr
= cupsFindAttr(ppd
, "cupsAllXY", colormodel
, media
,
1416 resolution
, spec
, sizeof(spec
))) != NULL
)
1418 for (num_xypoints
= 0, xyptr
= xypoints
;
1419 attr
!= NULL
&& attr
->value
!= NULL
&& num_xypoints
< 100;
1420 attr
= ppdFindNextAttr(ppd
, "cupsAllXY", spec
))
1421 if (sscanf(attr
->value
, "%f%f", xyptr
, xyptr
+ 1) == 2)
1427 switch (num_channels
)
1431 cupsCMYKSetCurve(cmyk
, 2, num_xypoints
, xypoints
);
1435 cupsCMYKSetCurve(cmyk
, 4, num_xypoints
, xypoints
);
1439 else if ((attr
= cupsFindAttr(ppd
, "cupsAllGamma", colormodel
, media
,
1440 resolution
, spec
, sizeof(spec
))) != NULL
)
1442 if (sscanf(attr
->value
, "%f%f", &gamval
, &density
) == 2)
1443 switch (num_channels
)
1447 cupsCMYKSetGamma(cmyk
, 2, gamval
, density
);
1451 cupsCMYKSetGamma(cmyk
, 4, gamval
, density
);
1458 * Get the optional cupsLightBlackXY, cupsLightBlackGamma, or
1459 * cupsBlackLtDk attributes...
1462 if (num_channels
== 2 || num_channels
== 7)
1464 if ((attr
= cupsFindAttr(ppd
, "cupsLightBlackXY", colormodel
, media
,
1465 resolution
, spec
, sizeof(spec
))) != NULL
)
1467 for (num_xypoints
= 0, xyptr
= xypoints
;
1468 attr
!= NULL
&& attr
->value
!= NULL
&& num_xypoints
< 100;
1469 attr
= ppdFindNextAttr(ppd
, "cupsLightBlackXY", spec
))
1470 if (sscanf(attr
->value
, "%f%f", xyptr
, xyptr
+ 1) == 2)
1476 switch (num_channels
)
1479 cupsCMYKSetCurve(cmyk
, 1, num_xypoints
, xypoints
);
1482 cupsCMYKSetCurve(cmyk
, 6, num_xypoints
, xypoints
);
1486 else if ((attr
= cupsFindAttr(ppd
, "cupsLightBlackGamma", colormodel
,
1487 media
, resolution
, spec
,
1488 sizeof(spec
))) != NULL
)
1490 if (sscanf(attr
->value
, "%f%f", &gamval
, &density
) == 2)
1491 switch (num_channels
)
1494 cupsCMYKSetGamma(cmyk
, 1, gamval
, density
);
1497 cupsCMYKSetGamma(cmyk
, 6, gamval
, density
);
1501 else if ((attr
= cupsFindAttr(ppd
, "cupsBlackLtDk", colormodel
, media
,
1502 resolution
, spec
, sizeof(spec
))) != NULL
)
1504 if (sscanf(attr
->value
, "%f%f", &light
, &dark
) == 2)
1505 switch (num_channels
)
1508 cupsCMYKSetLtDk(cmyk
, 0, light
, dark
);
1511 cupsCMYKSetLtDk(cmyk
, 5, light
, dark
);
1515 fprintf(stderr
, "ERROR: Bad cupsBlackLtDk value \"%s\"!\n",
1519 fprintf(stderr
, "WARNING: No light black attribute found for %s!\n",
1523 if (num_channels
>= 6)
1526 * Get the optional cupsLightCyanXY, cupsLightCyanGamma, or
1527 * cupsCyanLtDk attributes...
1530 if ((attr
= cupsFindAttr(ppd
, "cupsLightCyanXY", colormodel
, media
,
1531 resolution
, spec
, sizeof(spec
))) != NULL
)
1533 for (num_xypoints
= 0, xyptr
= xypoints
;
1534 attr
!= NULL
&& attr
->value
!= NULL
&& num_xypoints
< 100;
1535 attr
= ppdFindNextAttr(ppd
, "cupsLightCyanXY", spec
))
1536 if (sscanf(attr
->value
, "%f%f", xyptr
, xyptr
+ 1) == 2)
1542 cupsCMYKSetCurve(cmyk
, 1, num_xypoints
, xypoints
);
1544 else if ((attr
= cupsFindAttr(ppd
, "cupsLightCyanGamma", colormodel
,
1545 media
, resolution
, spec
,
1546 sizeof(spec
))) != NULL
)
1548 if (sscanf(attr
->value
, "%f%f", &gamval
, &density
) == 2)
1549 cupsCMYKSetGamma(cmyk
, 1, gamval
, density
);
1551 else if ((attr
= cupsFindAttr(ppd
, "cupsCyanLtDk", colormodel
, media
,
1552 resolution
, spec
, sizeof(spec
))) != NULL
)
1554 if (sscanf(attr
->value
, "%f%f", &light
, &dark
) == 2)
1555 cupsCMYKSetLtDk(cmyk
, 0, light
, dark
);
1557 fprintf(stderr
, "ERROR: Bad cupsCyanLtDk value \"%s\"!\n",
1561 fprintf(stderr
, "WARNING: No light cyan attribute found for %s!\n",
1565 * Get the optional cupsLightMagentaXY, cupsLightMagentaGamma, or
1566 * cupsMagentaLtDk attributes...
1569 if ((attr
= cupsFindAttr(ppd
, "cupsLightMagentaXY", colormodel
, media
,
1570 resolution
, spec
, sizeof(spec
))) != NULL
)
1572 for (num_xypoints
= 0, xyptr
= xypoints
;
1573 attr
!= NULL
&& attr
->value
!= NULL
&& num_xypoints
< 100;
1574 attr
= ppdFindNextAttr(ppd
, "cupsLightMagentaXY", spec
))
1575 if (sscanf(attr
->value
, "%f%f", xyptr
, xyptr
+ 1) == 2)
1581 cupsCMYKSetCurve(cmyk
, 3, num_xypoints
, xypoints
);
1583 else if ((attr
= cupsFindAttr(ppd
, "cupsLightMagentaGamma", colormodel
,
1584 media
, resolution
, spec
,
1585 sizeof(spec
))) != NULL
)
1587 if (sscanf(attr
->value
, "%f%f", &gamval
, &density
) == 2)
1588 cupsCMYKSetGamma(cmyk
, 3, gamval
, density
);
1590 else if ((attr
= cupsFindAttr(ppd
, "cupsMagentaLtDk", colormodel
, media
,
1591 resolution
, spec
, sizeof(spec
))) != NULL
)
1593 if (sscanf(attr
->value
, "%f%f", &light
, &dark
) == 2)
1594 cupsCMYKSetLtDk(cmyk
, 2, light
, dark
);
1596 fprintf(stderr
, "ERROR: Bad cupsMagentaLtDk value \"%s\"!\n",
1600 fprintf(stderr
, "WARNING: No light magenta attribute found for %s!\n",
1605 * Return the new profile...
1613 * 'cupsCMYKNew()' - Create a new CMYK color separation.
1616 cups_cmyk_t
* /* O - New CMYK separation or NULL */
1617 cupsCMYKNew(int num_channels
) /* I - Number of color components */
1619 cups_cmyk_t
*cmyk
; /* New color separation */
1620 int i
; /* Looping var */
1624 * Range-check the input...
1627 if (num_channels
< 1)
1631 * Allocate memory for the separation...
1634 if ((cmyk
= calloc(1, sizeof(cups_cmyk_t
))) == NULL
)
1638 * Allocate memory for the LUTs...
1641 cmyk
->num_channels
= num_channels
;
1643 if ((cmyk
->channels
[0] = calloc(num_channels
* 256, sizeof(short))) == NULL
)
1649 for (i
= 1; i
< num_channels
; i
++)
1650 cmyk
->channels
[i
] = cmyk
->channels
[0] + i
* 256;
1653 * Fill in the LUTs with unity transitions...
1656 for (i
= 0; i
< 256; i
++)
1657 cmyk
->black_lut
[i
] = i
;
1659 switch (num_channels
)
1663 for (i
= 0; i
< 256; i
++)
1665 cmyk
->channels
[0][i
] = CUPS_MAX_LUT
* i
/ 255;
1669 for (i
= 0; i
< 256; i
++)
1671 cmyk
->channels
[0][i
] = CUPS_MAX_LUT
* i
/ 255;
1672 cmyk
->channels
[1][i
] = CUPS_MAX_LUT
* i
/ 255;
1673 cmyk
->channels
[2][i
] = CUPS_MAX_LUT
* i
/ 255;
1677 for (i
= 0; i
< 256; i
++)
1679 cmyk
->channels
[0][i
] = CUPS_MAX_LUT
* i
/ 255;
1680 cmyk
->channels
[1][i
] = CUPS_MAX_LUT
* i
/ 255;
1681 cmyk
->channels
[2][i
] = CUPS_MAX_LUT
* i
/ 255;
1682 cmyk
->channels
[3][i
] = CUPS_MAX_LUT
* i
/ 255;
1685 case 6 : /* CcMmYK */
1686 case 7 : /* CcMmYKk */
1687 for (i
= 0; i
< 256; i
++)
1689 cmyk
->channels
[0][i
] = CUPS_MAX_LUT
* i
/ 255;
1690 cmyk
->channels
[2][i
] = CUPS_MAX_LUT
* i
/ 255;
1691 cmyk
->channels
[4][i
] = CUPS_MAX_LUT
* i
/ 255;
1692 cmyk
->channels
[5][i
] = CUPS_MAX_LUT
* i
/ 255;
1698 * Return the separation...
1706 * 'cupsCMYKSetBlack()' - Set the transition range for CMY to black.
1710 cupsCMYKSetBlack(cups_cmyk_t
*cmyk
, /* I - CMYK color separation */
1711 float lower
, /* I - No black ink */
1712 float upper
) /* I - Only black ink */
1714 int i
, /* Looping var */
1715 delta
, /* Difference between lower and upper */
1716 ilower
, /* Lower level from 0 to 255 */
1717 iupper
; /* Upper level from 0 to 255 */
1721 * Range check input...
1724 if (cmyk
== NULL
|| lower
< 0.0 || lower
> 1.0 || upper
< 0.0 || upper
> 1.0 ||
1729 * Convert lower and upper to integers from 0 to 255...
1732 ilower
= (int)(255.0 * lower
+ 0.5);
1733 iupper
= (int)(255.0 * upper
+ 0.5);
1734 delta
= iupper
- ilower
;
1737 * Generate the CMY-only data...
1740 for (i
= 0; i
< ilower
; i
++)
1742 cmyk
->black_lut
[i
] = 0;
1743 cmyk
->color_lut
[i
] = i
;
1747 * Then the transition data...
1750 for (; i
< iupper
; i
++)
1752 cmyk
->black_lut
[i
] = iupper
* (i
- ilower
) / delta
;
1753 cmyk
->color_lut
[i
] = ilower
- ilower
* (i
- ilower
) / delta
;
1757 * Then the K-only data...
1760 for (; i
< 256; i
++)
1762 cmyk
->black_lut
[i
] = i
;
1763 cmyk
->color_lut
[i
] = 0;
1766 fprintf(stderr
, "DEBUG: cupsCMYKSetBlack(cmyk, lower=%.3f, upper=%.3f)\n", lower
, upper
);
1768 for (i
= 0; i
< 256; i
+= 17)
1769 fprintf(stderr
, "DEBUG: %3d = %3dk + %3dc\n", i
,
1770 cmyk
->black_lut
[i
], cmyk
->color_lut
[i
]);
1775 * 'cupsCMYKSetCurve()' - Set a color transform curve using points.
1779 cupsCMYKSetCurve(cups_cmyk_t
*cmyk
, /* I - CMYK color separation */
1780 int channel
, /* I - Color channel */
1782 /* I - Number of X,Y points */
1783 const float *xypoints
) /* I - X,Y points */
1785 int i
; /* Looping var */
1786 int xstart
; /* Start position */
1787 int xend
; /* End position */
1788 int xdelta
; /* Difference in position */
1789 int ystart
; /* Start value */
1790 int yend
; /* End value */
1791 int ydelta
; /* Difference in value */
1795 * Range check input...
1798 if (cmyk
== NULL
|| channel
< 0 || channel
>= cmyk
->num_channels
||
1799 num_xypoints
< 1 || xypoints
== NULL
)
1803 * Initialize the lookup table for the specified channel...
1806 for (xstart
= xend
= 0, ystart
= yend
= 0;
1808 num_xypoints
--, xypoints
+= 2, xstart
= xend
, ystart
= yend
)
1810 xend
= (int)(255.0 * xypoints
[1] + 0.5);
1811 yend
= (int)(CUPS_MAX_LUT
* xypoints
[0] + 0.5);
1812 xdelta
= xend
- xstart
;
1813 ydelta
= yend
- ystart
;
1815 for (i
= xstart
; i
< xend
; i
++)
1816 cmyk
->channels
[channel
][i
] = ystart
+ ydelta
* (i
- xstart
) / xdelta
;
1820 * Initialize any trailing values to the maximum of the last data point...
1823 for (i
= xend
; i
< 256; i
++)
1824 cmyk
->channels
[channel
][i
] = yend
;
1826 fprintf(stderr
, "DEBUG: cupsCMYKSetXY(cmyk, channel=%d, num_xypoints=%d, "
1827 "xypoints=[%.3f %.3f %.3f %.3f ...])\n", channel
,
1828 num_xypoints
, xypoints
[0], xypoints
[1], xypoints
[2], xypoints
[3]);
1830 for (i
= 0; i
< 256; i
+= 17)
1831 fprintf(stderr
, "DEBUG: %3d = %4d\n", i
,
1832 cmyk
->channels
[channel
+ 0][i
]);
1837 * 'cupsCMYKSetGamma()' - Set a color transform curve using gamma and density.
1841 cupsCMYKSetGamma(cups_cmyk_t
*cmyk
, /* I - CMYK color separation */
1842 int channel
, /* I - Ink channel */
1843 float gamval
, /* I - Gamma correction */
1844 float density
) /* I - Maximum density */
1846 int i
; /* Looping var */
1850 * Range check input...
1853 if (cmyk
== NULL
|| channel
< 0 || channel
>= cmyk
->num_channels
||
1854 gamval
<= 0.0 || density
<= 0.0 || density
> 1.0)
1858 * Initialize the lookup table for the specified channel...
1861 for (i
= 0; i
< 256; i
++)
1862 cmyk
->channels
[channel
][i
] = (int)(density
* CUPS_MAX_LUT
*
1863 pow((float)i
/ 255.0, gamval
) + 0.5);
1865 fprintf(stderr
, "DEBUG: cupsCMYKSetGamma(cmyk, channel=%d, gamval=%.3f, "
1866 "density=%.3f)\n", channel
, gamval
, density
);
1868 for (i
= 0; i
< 256; i
+= 17)
1869 fprintf(stderr
, "DEBUG: %3d = %4d\n", i
,
1870 cmyk
->channels
[channel
+ 0][i
]);
1875 * 'cupsCMYKSetInkLimit()' - Set the limit on the amount of ink.
1879 cupsCMYKSetInkLimit(cups_cmyk_t
*cmyk
, /* I - CMYK color separation */
1880 float limit
) /* I - Limit of ink */
1882 if (!cmyk
|| limit
< 0.0)
1885 cmyk
->ink_limit
= limit
* CUPS_MAX_LUT
;
1890 * 'cupsCMYKSetLtDk()' - Set light/dark ink transforms.
1894 cupsCMYKSetLtDk(cups_cmyk_t
*cmyk
, /* I - CMYK color separation */
1895 int channel
, /* I - Dark ink channel (+1 for light) */
1896 float light
, /* I - Light ink only level */
1897 float dark
) /* I - Dark ink only level */
1899 int i
, /* Looping var */
1900 delta
, /* Difference between lower and upper */
1901 ilight
, /* Light level from 0 to 255 */
1902 idark
; /* Dark level from 0 to 255 */
1903 short lut
[256]; /* Original LUT data */
1907 * Range check input...
1910 if (cmyk
== NULL
|| light
< 0.0 || light
> 1.0 || dark
< 0.0 || dark
> 1.0 ||
1911 light
> dark
|| channel
< 0 || channel
> (cmyk
->num_channels
- 2))
1915 * Convert lower and upper to integers from 0 to 255...
1918 ilight
= (int)(255.0 * light
+ 0.5);
1919 idark
= (int)(255.0 * dark
+ 0.5);
1920 delta
= idark
- ilight
;
1923 * Copy the dark ink LUT...
1926 memcpy(lut
, cmyk
->channels
[channel
], sizeof(lut
));
1929 * Generate the light-only data...
1932 for (i
= 0; i
< ilight
; i
++)
1934 cmyk
->channels
[channel
+ 0][i
] = 0;
1935 cmyk
->channels
[channel
+ 1][i
] = CUPS_MAX_LUT
* i
/ ilight
;
1939 * Then the transition data...
1942 for (; i
< idark
; i
++)
1944 cmyk
->channels
[channel
+ 0][i
] = CUPS_MAX_LUT
* idark
* (i
- ilight
) /
1946 cmyk
->channels
[channel
+ 1][i
] = CUPS_MAX_LUT
- CUPS_MAX_LUT
*
1947 (i
- ilight
) / delta
;
1951 * Then the K-only data...
1954 for (; i
< 256; i
++)
1956 cmyk
->channels
[channel
+ 0][i
] = CUPS_MAX_LUT
* i
/ 255;
1957 cmyk
->channels
[channel
+ 1][i
] = 0;
1960 fprintf(stderr
, "DEBUG: cupsCMYKSetLtDk(cmyk, channel=%d, light=%.3f, "
1961 "dark=%.3f)\n", channel
, light
, dark
);
1963 for (i
= 0; i
< 256; i
+= 17)
1964 fprintf(stderr
, "DEBUG: %3d = %4dlt + %4ddk\n", i
,
1965 cmyk
->channels
[channel
+ 0][i
], cmyk
->channels
[channel
+ 1][i
]);