]> git.ipfire.org Git - thirdparty/cups.git/blob - driver/testcmyk.c
Merge changes from CUPS 1.5.1-r9875.
[thirdparty/cups.git] / driver / testcmyk.c
1 /*
2 * "$Id$"
3 *
4 * Test the CMYK color separation code for CUPS.
5 *
6 * Copyright 2007-2010 by Apple Inc.
7 * Copyright 1993-2006 by Easy Software Products, All Rights Reserved.
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 * test_gray() - Test grayscale separations...
18 * test_rgb() - Test color separations...
19 * main() - Do color separation tests.
20 */
21
22 /*
23 * Include necessary headers.
24 */
25
26 #include <cups/string-private.h>
27 #include "driver.h"
28 #include <sys/stat.h>
29
30
31 void test_gray(int num_comps, const char *basename);
32 void test_rgb(int num_comps, const char *basename);
33
34
35 /*
36 * 'main()' - Do color separation tests.
37 */
38
39 int /* O - Exit status */
40 main(int argc, /* I - Number of command-line arguments */
41 char *argv[]) /* I - Command-line arguments */
42 {
43 /*
44 * Make the test directory...
45 */
46
47 mkdir("test", 0755);
48
49 /*
50 * Run tests for K, Kk, CMY, CMYK, CcMmYK, and CcMmYKk separations...
51 */
52
53 test_rgb(1, "test/K-rgb");
54 test_rgb(2, "test/Kk-rgb");
55 test_rgb(3, "test/CMY-rgb");
56 test_rgb(4, "test/CMYK-rgb");
57 test_rgb(6, "test/CcMmYK-rgb");
58 test_rgb(7, "test/CcMmYKk-rgb");
59
60 test_gray(1, "test/K-gray");
61 test_gray(2, "test/Kk-gray");
62 test_gray(3, "test/CMY-gray");
63 test_gray(4, "test/CMYK-gray");
64 test_gray(6, "test/CcMmYK-gray");
65 test_gray(7, "test/CcMmYKk-gray");
66
67 /*
68 * Return with no errors...
69 */
70
71 return (0);
72 }
73
74
75 /*
76 * 'test_gray()' - Test grayscale separations...
77 */
78
79 void
80 test_gray(int num_comps, /* I - Number of components */
81 const char *basename) /* I - Base filename of output */
82 {
83 int i; /* Looping var */
84 char filename[255]; /* Output filename */
85 char line[255]; /* Line from PGM file */
86 int width, height; /* Width and height of test image */
87 int x, y; /* Current coordinate in image */
88 int r, g, b; /* Current RGB color */
89 unsigned char input[7000]; /* Line to separate */
90 short output[48000], /* Output separation data */
91 *outptr; /* Pointer in output */
92 FILE *in; /* Input PPM file */
93 FILE *out[CUPS_MAX_CHAN];
94 /* Output PGM files */
95 FILE *comp; /* Composite output */
96 cups_cmyk_t *cmyk; /* Color separation */
97
98
99 /*
100 * Open the test image...
101 */
102
103 in = fopen("image.pgm", "rb");
104 while (fgets(line, sizeof(line), in) != NULL)
105 if (isdigit(line[0]))
106 break;
107
108 sscanf(line, "%d%d", &width, &height);
109
110 fgets(line, sizeof(line), in);
111
112 /*
113 * Create the color separation...
114 */
115
116 cmyk = cupsCMYKNew(num_comps);
117
118 switch (num_comps)
119 {
120 case 2 : /* Kk */
121 cupsCMYKSetLtDk(cmyk, 0, 0.5, 1.0);
122 break;
123
124 case 4 :
125 cupsCMYKSetGamma(cmyk, 2, 1.0, 0.9);
126 cupsCMYKSetBlack(cmyk, 0.5, 1.0);
127 break;
128
129 case 6 : /* CcMmYK */
130 cupsCMYKSetLtDk(cmyk, 0, 0.5, 1.0);
131 cupsCMYKSetLtDk(cmyk, 2, 0.5, 1.0);
132 cupsCMYKSetGamma(cmyk, 4, 1.0, 0.9);
133 cupsCMYKSetBlack(cmyk, 0.5, 1.0);
134 break;
135
136 case 7 : /* CcMmYKk */
137 cupsCMYKSetLtDk(cmyk, 0, 0.5, 1.0);
138 cupsCMYKSetLtDk(cmyk, 2, 0.5, 1.0);
139 cupsCMYKSetGamma(cmyk, 4, 1.0, 0.9);
140 cupsCMYKSetLtDk(cmyk, 5, 0.5, 1.0);
141 break;
142 }
143
144 /*
145 * Open the color separation files...
146 */
147
148 for (i = 0; i < num_comps; i ++)
149 {
150 sprintf(filename, "%s%d.pgm", basename, i);
151 out[i] = fopen(filename, "wb");
152
153 fprintf(out[i], "P5\n%d %d 255\n", width, height);
154 }
155
156 sprintf(filename, "%s.ppm", basename);
157 comp = fopen(filename, "wb");
158
159 fprintf(comp, "P6\n%d %d 255\n", width, height);
160
161 /*
162 * Read the image and do the separations...
163 */
164
165 for (y = 0; y < height; y ++)
166 {
167 fread(input, width, 1, in);
168
169 cupsCMYKDoGray(cmyk, input, output, width);
170
171 for (x = 0, outptr = output; x < width; x ++, outptr += num_comps)
172 {
173 for (i = 0; i < num_comps; i ++)
174 putc(255 - 255 * outptr[i] / 4095, out[i]);
175
176 r = 4095;
177 g = 4095;
178 b = 4095;
179
180 switch (num_comps)
181 {
182 case 1 :
183 r -= outptr[0];
184 g -= outptr[0];
185 b -= outptr[0];
186 break;
187 case 2 :
188 r -= outptr[0];
189 g -= outptr[0];
190 b -= outptr[0];
191
192 r -= outptr[1] / 2;
193 g -= outptr[1] / 2;
194 b -= outptr[1] / 2;
195 break;
196 case 3 :
197 r -= outptr[0];
198 g -= outptr[1];
199 b -= outptr[2];
200 break;
201 case 4 :
202 r -= outptr[0];
203 g -= outptr[1];
204 b -= outptr[2];
205
206 r -= outptr[3];
207 g -= outptr[3];
208 b -= outptr[3];
209 break;
210 case 6 :
211 r -= outptr[0] + outptr[1] / 2;
212 g -= outptr[2] + outptr[3] / 3;
213 b -= outptr[4];
214
215 r -= outptr[5];
216 g -= outptr[5];
217 b -= outptr[5];
218 break;
219 case 7 :
220 r -= outptr[0] + outptr[1] / 2;
221 g -= outptr[2] + outptr[3] / 3;
222 b -= outptr[4];
223
224 r -= outptr[5] + outptr[6] / 2;
225 g -= outptr[5] + outptr[6] / 2;
226 b -= outptr[5] + outptr[6] / 2;
227 break;
228 }
229
230 if (r < 0)
231 putc(0, comp);
232 else
233 putc(255 * r / 4095, comp);
234
235 if (g < 0)
236 putc(0, comp);
237 else
238 putc(255 * g / 4095, comp);
239
240 if (b < 0)
241 putc(0, comp);
242 else
243 putc(255 * b / 4095, comp);
244 }
245 }
246
247 for (i = 0; i < num_comps; i ++)
248 fclose(out[i]);
249
250 fclose(comp);
251 fclose(in);
252
253 cupsCMYKDelete(cmyk);
254 }
255
256
257 /*
258 * 'test_rgb()' - Test color separations...
259 */
260
261 void
262 test_rgb(int num_comps, /* I - Number of components */
263 const char *basename) /* I - Base filename of output */
264 {
265 int i; /* Looping var */
266 char filename[255]; /* Output filename */
267 char line[255]; /* Line from PPM file */
268 int width, height; /* Width and height of test image */
269 int x, y; /* Current coordinate in image */
270 int r, g, b; /* Current RGB color */
271 unsigned char input[7000]; /* Line to separate */
272 short output[48000], /* Output separation data */
273 *outptr; /* Pointer in output */
274 FILE *in; /* Input PPM file */
275 FILE *out[CUPS_MAX_CHAN];
276 /* Output PGM files */
277 FILE *comp; /* Composite output */
278 cups_cmyk_t *cmyk; /* Color separation */
279
280
281 /*
282 * Open the test image...
283 */
284
285 in = fopen("image.ppm", "rb");
286 while (fgets(line, sizeof(line), in) != NULL)
287 if (isdigit(line[0]))
288 break;
289
290 sscanf(line, "%d%d", &width, &height);
291
292 fgets(line, sizeof(line), in);
293
294 /*
295 * Create the color separation...
296 */
297
298 cmyk = cupsCMYKNew(num_comps);
299
300 cupsCMYKSetBlack(cmyk, 0.5, 1.0);
301
302 switch (num_comps)
303 {
304 case 2 : /* Kk */
305 cupsCMYKSetLtDk(cmyk, 0, 0.5, 1.0);
306 break;
307 case 6 : /* CcMmYK */
308 cupsCMYKSetGamma(cmyk, 0, 1.0, 0.8);
309 cupsCMYKSetLtDk(cmyk, 0, 0.5, 1.0);
310 cupsCMYKSetGamma(cmyk, 2, 1.0, 0.8);
311 cupsCMYKSetLtDk(cmyk, 2, 0.5, 1.0);
312 break;
313 case 7 : /* CcMmYKk */
314 cupsCMYKSetGamma(cmyk, 0, 1.0, 0.8);
315 cupsCMYKSetLtDk(cmyk, 0, 0.5, 1.0);
316 cupsCMYKSetGamma(cmyk, 2, 1.0, 0.8);
317 cupsCMYKSetLtDk(cmyk, 2, 0.5, 1.0);
318 cupsCMYKSetLtDk(cmyk, 5, 0.5, 1.0);
319 break;
320 }
321
322 /*
323 * Open the color separation files...
324 */
325
326 for (i = 0; i < num_comps; i ++)
327 {
328 sprintf(filename, "%s%d.pgm", basename, i);
329 out[i] = fopen(filename, "wb");
330
331 fprintf(out[i], "P5\n%d %d 255\n", width, height);
332 }
333
334 sprintf(filename, "%s.ppm", basename);
335 comp = fopen(filename, "wb");
336
337 fprintf(comp, "P6\n%d %d 255\n", width, height);
338
339 /*
340 * Read the image and do the separations...
341 */
342
343 for (y = 0; y < height; y ++)
344 {
345 fread(input, width, 3, in);
346
347 cupsCMYKDoRGB(cmyk, input, output, width);
348
349 for (x = 0, outptr = output; x < width; x ++, outptr += num_comps)
350 {
351 for (i = 0; i < num_comps; i ++)
352 putc(255 - 255 * outptr[i] / 4095, out[i]);
353
354 r = 4095;
355 g = 4095;
356 b = 4095;
357
358 switch (num_comps)
359 {
360 case 1 :
361 r -= outptr[0];
362 g -= outptr[0];
363 b -= outptr[0];
364 break;
365 case 2 :
366 r -= outptr[0];
367 g -= outptr[0];
368 b -= outptr[0];
369
370 r -= outptr[1] / 2;
371 g -= outptr[1] / 2;
372 b -= outptr[1] / 2;
373 break;
374 case 3 :
375 r -= outptr[0];
376 g -= outptr[1];
377 b -= outptr[2];
378 break;
379 case 4 :
380 r -= outptr[0];
381 g -= outptr[1];
382 b -= outptr[2];
383
384 r -= outptr[3];
385 g -= outptr[3];
386 b -= outptr[3];
387 break;
388 case 6 :
389 r -= outptr[0] + outptr[1] / 2;
390 g -= outptr[2] + outptr[3] / 3;
391 b -= outptr[4];
392
393 r -= outptr[5];
394 g -= outptr[5];
395 b -= outptr[5];
396 break;
397 case 7 :
398 r -= outptr[0] + outptr[1] / 2;
399 g -= outptr[2] + outptr[3] / 3;
400 b -= outptr[4];
401
402 r -= outptr[5] + outptr[6] / 2;
403 g -= outptr[5] + outptr[6] / 2;
404 b -= outptr[5] + outptr[6] / 2;
405 break;
406 }
407
408 if (r < 0)
409 putc(0, comp);
410 else
411 putc(255 * r / 4095, comp);
412
413 if (g < 0)
414 putc(0, comp);
415 else
416 putc(255 * g / 4095, comp);
417
418 if (b < 0)
419 putc(0, comp);
420 else
421 putc(255 * b / 4095, comp);
422 }
423 }
424
425 for (i = 0; i < num_comps; i ++)
426 fclose(out[i]);
427
428 fclose(comp);
429 fclose(in);
430
431 cupsCMYKDelete(cmyk);
432 }
433
434
435 /*
436 * End of "$Id$".
437 */