]> git.ipfire.org Git - thirdparty/cups.git/blob - driver/lut.c
Merge changes from CUPS 1.4svn-r7874.
[thirdparty/cups.git] / driver / lut.c
1 /*
2 * "$Id$"
3 *
4 * Lookup table routines for CUPS.
5 *
6 * Copyright 2007 by Apple Inc.
7 * Copyright 1993-2005 by Easy Software Products.
8 *
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/".
14 *
15 * Contents:
16 *
17 * cupsLutDelete() - Free the memory used by a lookup table.
18 * cupsLutLoad() - Load a LUT from a PPD file.
19 * cupsLutNew() - Make a lookup table from a list of pixel values.
20 */
21
22 /*
23 * Include necessary headers.
24 */
25
26 #include "driver.h"
27 #include <math.h>
28
29
30 /*
31 * 'cupsLutDelete()' - Free the memory used by a lookup table.
32 */
33
34 void
35 cupsLutDelete(cups_lut_t *lut) /* I - Lookup table to free */
36 {
37 if (lut != NULL)
38 free(lut);
39 }
40
41
42 /*
43 * 'cupsLutLoad()' - Load a LUT from a PPD file.
44 */
45
46 cups_lut_t * /* O - New lookup table */
47 cupsLutLoad(ppd_file_t *ppd, /* I - PPD file */
48 const char *colormodel, /* I - Color model */
49 const char *media, /* I - Media type */
50 const char *resolution, /* I - Resolution */
51 const char *ink) /* I - Ink name */
52 {
53 char name[PPD_MAX_NAME], /* Attribute name */
54 spec[PPD_MAX_NAME]; /* Attribute spec */
55 ppd_attr_t *attr; /* Attribute */
56 int nvals; /* Number of values */
57 float vals[4]; /* Values */
58
59
60 /*
61 * Range check input...
62 */
63
64 if (!ppd || !colormodel || !media || !resolution || !ink)
65 return (NULL);
66
67 /*
68 * Try to find the LUT values...
69 */
70
71 snprintf(name, sizeof(name), "cups%sDither", ink);
72
73 if ((attr = cupsFindAttr(ppd, name, colormodel, media, resolution, spec,
74 sizeof(spec))) == NULL)
75 attr = cupsFindAttr(ppd, "cupsAllDither", colormodel, media,
76 resolution, spec, sizeof(spec));
77
78 if (!attr)
79 return (NULL);
80
81 vals[0] = 0.0;
82 vals[1] = 0.0;
83 vals[2] = 0.0;
84 vals[3] = 0.0;
85 nvals = sscanf(attr->value, "%f%f%f", vals + 1, vals + 2, vals + 3) + 1;
86
87 fprintf(stderr, "DEBUG: Loaded LUT %s from PPD with values [%.3f %.3f %.3f %.3f]\n",
88 name, vals[0], vals[1], vals[2], vals[3]);
89
90 return (cupsLutNew(nvals, vals));
91 }
92
93
94 /*
95 * 'cupsLutNew()' - Make a lookup table from a list of pixel values.
96 *
97 * Returns a pointer to the lookup table on success, NULL on failure.
98 */
99
100 cups_lut_t * /* O - New lookup table */
101 cupsLutNew(int num_values, /* I - Number of values */
102 const float *values) /* I - Lookup table values */
103 {
104 int pixel; /* Pixel value */
105 cups_lut_t *lut; /* Lookup table */
106 int start, /* Start value */
107 end, /* End value */
108 maxval; /* Maximum value */
109
110
111 /*
112 * Range check...
113 */
114
115 if (!num_values || !values)
116 return (NULL);
117
118 /*
119 * Allocate memory for the lookup table...
120 */
121
122 if ((lut = (cups_lut_t *)calloc((CUPS_MAX_LUT + 1),
123 sizeof(cups_lut_t))) == NULL)
124 return (NULL);
125
126 /*
127 * Generate the dither lookup table. The pixel values are roughly
128 * defined by a piecewise linear curve that has an intensity value
129 * at each output pixel. This isn't perfectly accurate, but it's
130 * close enough for jazz.
131 */
132
133 maxval = CUPS_MAX_LUT / values[num_values - 1];
134
135 for (start = 0; start <= CUPS_MAX_LUT; start ++)
136 lut[start].intensity = start * maxval / CUPS_MAX_LUT;
137
138 for (pixel = 0; pixel < num_values; pixel ++)
139 {
140 /*
141 * Select start and end values for this pixel...
142 */
143
144 if (pixel == 0)
145 start = 0;
146 else
147 start = (int)(0.5 * maxval * (values[pixel - 1] +
148 values[pixel])) + 1;
149
150 if (start < 0)
151 start = 0;
152 else if (start > CUPS_MAX_LUT)
153 start = CUPS_MAX_LUT;
154
155 if (pixel == (num_values - 1))
156 end = CUPS_MAX_LUT;
157 else
158 end = (int)(0.5 * maxval * (values[pixel] + values[pixel + 1]));
159
160 if (end < 0)
161 end = 0;
162 else if (end > CUPS_MAX_LUT)
163 end = CUPS_MAX_LUT;
164
165 if (start == end)
166 break;
167
168 /*
169 * Generate lookup values and errors for each pixel.
170 */
171
172 while (start <= end)
173 {
174 lut[start].pixel = pixel;
175 if (start == 0)
176 lut[0].error = 0;
177 else
178 lut[start].error = start - maxval * values[pixel];
179
180 start ++;
181 }
182 }
183
184 /*
185 * Show the lookup table...
186 */
187
188 for (start = 0; start <= CUPS_MAX_LUT; start += CUPS_MAX_LUT / 15)
189 fprintf(stderr, "DEBUG: %d = %d/%d/%d\n", start, lut[start].intensity,
190 lut[start].pixel, lut[start].error);
191
192 /*
193 * Return the lookup table...
194 */
195
196 return (lut);
197 }
198
199
200 /*
201 * End of "$Id$".
202 */