]> git.ipfire.org Git - thirdparty/cups.git/blob - filter/imagetoraster.c
Load cups into easysw/current.
[thirdparty/cups.git] / filter / imagetoraster.c
1 /*
2 * "$Id: imagetoraster.c 5191 2006-02-27 02:47:56Z mike $"
3 *
4 * Image file to raster filter for the Common UNIX Printing System (CUPS).
5 *
6 * Copyright 1993-2006 by Easy Software Products.
7 *
8 * These coded instructions, statements, and computer programs are the
9 * property of Easy Software Products and are protected by Federal
10 * copyright law. Distribution and use rights are outlined in the file
11 * "LICENSE.txt" which should have been included with this file. If this
12 * file is missing or damaged please contact Easy Software Products
13 * at:
14 *
15 * Attn: CUPS Licensing Information
16 * Easy Software Products
17 * 44141 Airport View Drive, Suite 204
18 * Hollywood, Maryland 20636 USA
19 *
20 * Voice: (301) 373-9600
21 * EMail: cups-info@cups.org
22 * WWW: http://www.cups.org
23 *
24 * This file is subject to the Apple OS-Developed Software exception.
25 *
26 * Contents:
27 *
28 * main() - Main entry...
29 * exec_code() - Execute PostScript setpagedevice commands as
30 * appropriate.
31 * format_CMY() - Convert image data to CMY.
32 * format_CMYK() - Convert image data to CMYK.
33 * format_K() - Convert image data to black.
34 * format_KCMY() - Convert image data to KCMY.
35 * format_KCMYcm() - Convert image data to KCMYcm.
36 * format_RGBA() - Convert image data to RGBA/RGBW.
37 * format_W() - Convert image data to luminance.
38 * format_YMC() - Convert image data to YMC.
39 * format_YMCK() - Convert image data to YMCK.
40 * make_lut() - Make a lookup table given gamma and brightness values.
41 */
42
43 /*
44 * Include necessary headers...
45 */
46
47 #include "common.h"
48 #include "image-private.h"
49 #include "raster.h"
50 #include <unistd.h>
51 #include <math.h>
52
53
54 /*
55 * Globals...
56 */
57
58 int Flip = 0, /* Flip/mirror pages */
59 XPosition = 0, /* Horizontal position on page */
60 YPosition = 0, /* Vertical position on page */
61 Collate = 0, /* Collate copies? */
62 Copies = 1; /* Number of copies */
63 int Floyd16xc16[16][16] = /* Traditional Floyd ordered dither */
64 {
65 { 0, 128, 32, 160, 8, 136, 40, 168,
66 2, 130, 34, 162, 10, 138, 42, 170 },
67 { 192, 64, 224, 96, 200, 72, 232, 104,
68 194, 66, 226, 98, 202, 74, 234, 106 },
69 { 48, 176, 16, 144, 56, 184, 24, 152,
70 50, 178, 18, 146, 58, 186, 26, 154 },
71 { 240, 112, 208, 80, 248, 120, 216, 88,
72 242, 114, 210, 82, 250, 122, 218, 90 },
73 { 12, 140, 44, 172, 4, 132, 36, 164,
74 14, 142, 46, 174, 6, 134, 38, 166 },
75 { 204, 76, 236, 108, 196, 68, 228, 100,
76 206, 78, 238, 110, 198, 70, 230, 102 },
77 { 60, 188, 28, 156, 52, 180, 20, 148,
78 62, 190, 30, 158, 54, 182, 22, 150 },
79 { 252, 124, 220, 92, 244, 116, 212, 84,
80 254, 126, 222, 94, 246, 118, 214, 86 },
81 { 3, 131, 35, 163, 11, 139, 43, 171,
82 1, 129, 33, 161, 9, 137, 41, 169 },
83 { 195, 67, 227, 99, 203, 75, 235, 107,
84 193, 65, 225, 97, 201, 73, 233, 105 },
85 { 51, 179, 19, 147, 59, 187, 27, 155,
86 49, 177, 17, 145, 57, 185, 25, 153 },
87 { 243, 115, 211, 83, 251, 123, 219, 91,
88 241, 113, 209, 81, 249, 121, 217, 89 },
89 { 15, 143, 47, 175, 7, 135, 39, 167,
90 13, 141, 45, 173, 5, 133, 37, 165 },
91 { 207, 79, 239, 111, 199, 71, 231, 103,
92 205, 77, 237, 109, 197, 69, 229, 101 },
93 { 63, 191, 31, 159, 55, 183, 23, 151,
94 61, 189, 29, 157, 53, 181, 21, 149 },
95 { 254, 127, 223, 95, 247, 119, 215, 87,
96 253, 125, 221, 93, 245, 117, 213, 85 }
97 };
98 int Floyd8x8[8][8] =
99 {
100 { 0, 32, 8, 40, 2, 34, 10, 42 },
101 { 48, 16, 56, 24, 50, 18, 58, 26 },
102 { 12, 44, 4, 36, 14, 46, 6, 38 },
103 { 60, 28, 52, 20, 62, 30, 54, 22 },
104 { 3, 35, 11, 43, 1, 33, 9, 41 },
105 { 51, 19, 59, 27, 49, 17, 57, 25 },
106 { 15, 47, 7, 39, 13, 45, 5, 37 },
107 { 63, 31, 55, 23, 61, 29, 53, 21 }
108 };
109 int Floyd4x4[4][4] =
110 {
111 { 0, 8, 2, 10 },
112 { 12, 4, 14, 6 },
113 { 3, 11, 1, 9 },
114 { 15, 7, 13, 5 }
115 };
116
117 cups_ib_t OnPixels[256], /* On-pixel LUT */
118 OffPixels[256]; /* Off-pixel LUT */
119 int Planes[] = /* Number of planes for each colorspace */
120 {
121 1, /* CUPS_CSPACE_W */
122 3, /* CUPS_CSPACE_RGB */
123 4, /* CUPS_CSPACE_RGBA */
124 1, /* CUPS_CSPACE_K */
125 3, /* CUPS_CSPACE_CMY */
126 3, /* CUPS_CSPACE_YMC */
127 4, /* CUPS_CSPACE_CMYK */
128 4, /* CUPS_CSPACE_YMCK */
129 4, /* CUPS_CSPACE_KCMY */
130 6, /* CUPS_CSPACE_KCMYcm */
131 4, /* CUPS_CSPACE_GMCK */
132 4, /* CUPS_CSPACE_GMCS */
133 1, /* CUPS_CSPACE_WHITE */
134 1, /* CUPS_CSPACE_GOLD */
135 1, /* CUPS_CSPACE_SILVER */
136 3, /* CUPS_CSPACE_CIEXYZ */
137 3, /* CUPS_CSPACE_CIELab */
138 4, /* CUPS_CSPACE_RGBW */
139 0, /* ... reserved ... */
140 0, /* ... reserved ... */
141 0, /* ... reserved ... */
142 0, /* ... reserved ... */
143 0, /* ... reserved ... */
144 0, /* ... reserved ... */
145 0, /* ... reserved ... */
146 0, /* ... reserved ... */
147 0, /* ... reserved ... */
148 0, /* ... reserved ... */
149 0, /* ... reserved ... */
150 0, /* ... reserved ... */
151 0, /* ... reserved ... */
152 0, /* ... reserved ... */
153 3, /* CUPS_CSPACE_ICC1 */
154 3, /* CUPS_CSPACE_ICC2 */
155 3, /* CUPS_CSPACE_ICC3 */
156 3, /* CUPS_CSPACE_ICC4 */
157 3, /* CUPS_CSPACE_ICC5 */
158 3, /* CUPS_CSPACE_ICC6 */
159 3, /* CUPS_CSPACE_ICC7 */
160 3, /* CUPS_CSPACE_ICC8 */
161 3, /* CUPS_CSPACE_ICC9 */
162 3, /* CUPS_CSPACE_ICCA */
163 3, /* CUPS_CSPACE_ICCB */
164 3, /* CUPS_CSPACE_ICCC */
165 3, /* CUPS_CSPACE_ICCD */
166 3, /* CUPS_CSPACE_ICCE */
167 3 /* CUPS_CSPACE_ICCF */
168 };
169
170
171 /*
172 * Local functions...
173 */
174
175 static void exec_code(cups_page_header2_t *header, const char *code);
176 static void format_CMY(cups_page_header2_t *header, unsigned char *row, int y, int z, int xsize, int ysize, int yerr0, int yerr1, cups_ib_t *r0, cups_ib_t *r1);
177 static void format_CMYK(cups_page_header2_t *header, unsigned char *row, int y, int z, int xsize, int ysize, int yerr0, int yerr1, cups_ib_t *r0, cups_ib_t *r1);
178 static void format_K(cups_page_header2_t *header, unsigned char *row, int y, int z, int xsize, int ysize, int yerr0, int yerr1, cups_ib_t *r0, cups_ib_t *r1);
179 static void format_KCMYcm(cups_page_header2_t *header, unsigned char *row, int y, int z, int xsize, int ysize, int yerr0, int yerr1, cups_ib_t *r0, cups_ib_t *r1);
180 static void format_KCMY(cups_page_header2_t *header, unsigned char *row, int y, int z, int xsize, int ysize, int yerr0, int yerr1, cups_ib_t *r0, cups_ib_t *r1);
181 #define format_RGB format_CMY
182 static void format_RGBA(cups_page_header2_t *header, unsigned char *row, int y, int z, int xsize, int ysize, int yerr0, int yerr1, cups_ib_t *r0, cups_ib_t *r1);
183 static void format_W(cups_page_header2_t *header, unsigned char *row, int y, int z, int xsize, int ysize, int yerr0, int yerr1, cups_ib_t *r0, cups_ib_t *r1);
184 static void format_YMC(cups_page_header2_t *header, unsigned char *row, int y, int z, int xsize, int ysize, int yerr0, int yerr1, cups_ib_t *r0, cups_ib_t *r1);
185 static void format_YMCK(cups_page_header2_t *header, unsigned char *row, int y, int z, int xsize, int ysize, int yerr0, int yerr1, cups_ib_t *r0, cups_ib_t *r1);
186 static void make_lut(cups_ib_t *, int, float, float);
187
188
189 /*
190 * 'main()' - Main entry...
191 */
192
193 int /* O - Exit status */
194 main(int argc, /* I - Number of command-line arguments */
195 char *argv[]) /* I - Command-line arguments */
196 {
197 int i; /* Looping var */
198 cups_image_t *img; /* Image to print */
199 float xprint, /* Printable area */
200 yprint,
201 xinches, /* Total size in inches */
202 yinches;
203 float xsize, /* Total size in points */
204 ysize,
205 xsize2,
206 ysize2;
207 float aspect; /* Aspect ratio */
208 int xpages, /* # x pages */
209 ypages, /* # y pages */
210 xpage, /* Current x page */
211 ypage, /* Current y page */
212 xtemp, /* Bitmap width in pixels */
213 ytemp, /* Bitmap height in pixels */
214 page; /* Current page number */
215 int xc0, yc0, /* Corners of the page in image coords */
216 xc1, yc1;
217 ppd_file_t *ppd; /* PPD file */
218 ppd_choice_t *choice, /* PPD option choice */
219 **choices; /* List of marked choices */
220 int count; /* Number of marked choices */
221 char *resolution, /* Output resolution */
222 *media_type; /* Media type */
223 ppd_profile_t *profile; /* Color profile */
224 ppd_profile_t userprofile; /* User-specified profile */
225 cups_raster_t *ras; /* Raster stream */
226 cups_page_header2_t header; /* Page header */
227 int num_options; /* Number of print options */
228 cups_option_t *options; /* Print options */
229 const char *val; /* Option value */
230 int slowcollate, /* Collate copies the slow way */
231 slowcopies; /* Make copies the "slow" way? */
232 float g; /* Gamma correction value */
233 float b; /* Brightness factor */
234 float zoom; /* Zoom facter */
235 int xppi, yppi; /* Pixels-per-inch */
236 int hue, sat; /* Hue and saturation adjustment */
237 cups_izoom_t *z; /* Image zoom buffer */
238 cups_iztype_t zoom_type; /* Image zoom type */
239 int primary, /* Primary image colorspace */
240 secondary; /* Secondary image colorspace */
241 cups_ib_t *row, /* Current row */
242 *r0, /* Top row */
243 *r1; /* Bottom row */
244 int y, /* Current Y coordinate on page */
245 iy, /* Current Y coordinate in image */
246 last_iy, /* Previous Y coordinate in image */
247 yerr0, /* Top Y error value */
248 yerr1, /* Bottom Y error value */
249 blank; /* Blank value */
250 cups_ib_t lut[256]; /* Gamma/brightness LUT */
251 int plane, /* Current color plane */
252 num_planes; /* Number of color planes */
253 char filename[1024]; /* Name of file to print */
254
255
256 /*
257 * Make sure status messages are not buffered...
258 */
259
260 setbuf(stderr, NULL);
261
262 /*
263 * Check command-line...
264 */
265
266 if (argc < 6 || argc > 7)
267 {
268 fputs("ERROR: imagetoraster job-id user title copies options [file]\n", stderr);
269 return (1);
270 }
271
272 fprintf(stderr, "INFO: %s %s %s %s %s %s %s\n", argv[0], argv[1], argv[2],
273 argv[3], argv[4], argv[5], argv[6] ? argv[6] : "(null)");
274
275 /*
276 * See if we need to use the imagetops and pstoraster filters instead...
277 */
278
279 options = NULL;
280 num_options = cupsParseOptions(argv[5], 0, &options);
281
282 if (getenv("CLASSIFICATION") ||
283 cupsGetOption("page-label", num_options, options))
284 {
285 /*
286 * Yes, fork a copy of pstoraster and then transfer control to imagetops...
287 */
288
289 int mypipes[2]; /* New pipes for imagetops | pstoraster */
290 int pid; /* PID of pstoraster */
291
292
293 cupsFreeOptions(num_options, options);
294
295 if (pipe(mypipes))
296 {
297 perror("ERROR: Unable to create pipes for imagetops | pstoraster");
298 return (errno);
299 }
300
301 if ((pid = fork()) == 0)
302 {
303 /*
304 * Child process for pstoraster... Assign new pipe input to pstoraster...
305 */
306
307 close(0);
308 dup(mypipes[0]);
309 close(mypipes[0]);
310 close(mypipes[1]);
311
312 execlp("pstoraster", argv[0], argv[1], argv[2], argv[3], argv[4], argv[5],
313 NULL);
314 perror("ERROR: Unable to exec pstoraster");
315 return (errno);
316 }
317 else if (pid < 0)
318 {
319 /*
320 * Error!
321 */
322
323 perror("ERROR: Unable to fork pstoraster");
324 return (errno);
325 }
326
327 /*
328 * Update stdout so it points at the new pstoraster...
329 */
330
331 close(1);
332 dup(mypipes[1]);
333 close(mypipes[0]);
334 close(mypipes[1]);
335
336 /*
337 * Run imagetops to get the classification or page labelling that was
338 * requested...
339 */
340
341 execlp("imagetops", argv[0], argv[1], argv[2], argv[3], argv[4], argv[5],
342 argv[6], NULL);
343 perror("ERROR: Unable to exec imagetops");
344 return (errno);
345 }
346
347 /*
348 * Copy stdin as needed...
349 */
350
351 if (argc == 6)
352 {
353 int fd; /* File to write to */
354 char buffer[8192]; /* Buffer to read into */
355 int bytes; /* # of bytes to read */
356
357
358 if ((fd = cupsTempFd(filename, sizeof(filename))) < 0)
359 {
360 perror("ERROR: Unable to copy image file");
361 return (1);
362 }
363
364 fprintf(stderr, "DEBUG: imagetoraster - copying to temp print file \"%s\"\n",
365 filename);
366
367 while ((bytes = fread(buffer, 1, sizeof(buffer), stdin)) > 0)
368 write(fd, buffer, bytes);
369
370 close(fd);
371 }
372 else
373 strlcpy(filename, argv[6], sizeof(filename));
374
375 /*
376 * Process command-line options and write the prolog...
377 */
378
379 zoom = 0.0;
380 xppi = 0;
381 yppi = 0;
382 hue = 0;
383 sat = 100;
384 g = 1.0;
385 b = 1.0;
386
387 Copies = atoi(argv[4]);
388
389 ppd = SetCommonOptions(num_options, options, 0);
390
391 if ((val = cupsGetOption("multiple-document-handling", num_options, options)) != NULL)
392 {
393 /*
394 * This IPP attribute is unnecessarily complicated...
395 *
396 * single-document, separate-documents-collated-copies, and
397 * single-document-new-sheet all require collated copies.
398 *
399 * separate-documents-collated-copies allows for uncollated copies.
400 */
401
402 Collate = strcasecmp(val, "separate-documents-collated-copies") != 0;
403 }
404
405 if ((val = cupsGetOption("Collate", num_options, options)) != NULL &&
406 strcasecmp(val, "True") == 0)
407 Collate = 1;
408
409 if ((val = cupsGetOption("gamma", num_options, options)) != NULL)
410 {
411 /*
412 * Get gamma value from 1 to 10000...
413 */
414
415 g = atoi(val) * 0.001f;
416
417 if (g < 0.001f)
418 g = 0.001f;
419 else if (g > 10.0f)
420 g = 10.0f;
421 }
422
423 if ((val = cupsGetOption("brightness", num_options, options)) != NULL)
424 {
425 /*
426 * Get brightness value from 10 to 1000.
427 */
428
429 b = atoi(val) * 0.01f;
430
431 if (b < 0.1f)
432 b = 0.1f;
433 else if (b > 10.0f)
434 b = 10.0f;
435 }
436
437 if ((val = cupsGetOption("scaling", num_options, options)) != NULL)
438 zoom = atoi(val) * 0.01;
439 else if (cupsGetOption("fitplot", num_options, options))
440 zoom = 1.0;
441
442 if ((val = cupsGetOption("ppi", num_options, options)) != NULL)
443 if (sscanf(val, "%dx%d", &xppi, &yppi) < 2)
444 yppi = xppi;
445
446 if ((val = cupsGetOption("position", num_options, options)) != NULL)
447 {
448 if (strcasecmp(val, "center") == 0)
449 {
450 XPosition = 0;
451 YPosition = 0;
452 }
453 else if (strcasecmp(val, "top") == 0)
454 {
455 XPosition = 0;
456 YPosition = 1;
457 }
458 else if (strcasecmp(val, "left") == 0)
459 {
460 XPosition = -1;
461 YPosition = 0;
462 }
463 else if (strcasecmp(val, "right") == 0)
464 {
465 XPosition = 1;
466 YPosition = 0;
467 }
468 else if (strcasecmp(val, "top-left") == 0)
469 {
470 XPosition = -1;
471 YPosition = 1;
472 }
473 else if (strcasecmp(val, "top-right") == 0)
474 {
475 XPosition = 1;
476 YPosition = 1;
477 }
478 else if (strcasecmp(val, "bottom") == 0)
479 {
480 XPosition = 0;
481 YPosition = -1;
482 }
483 else if (strcasecmp(val, "bottom-left") == 0)
484 {
485 XPosition = -1;
486 YPosition = -1;
487 }
488 else if (strcasecmp(val, "bottom-right") == 0)
489 {
490 XPosition = 1;
491 YPosition = -1;
492 }
493 }
494
495 if ((val = cupsGetOption("saturation", num_options, options)) != NULL)
496 sat = atoi(val);
497
498 if ((val = cupsGetOption("hue", num_options, options)) != NULL)
499 hue = atoi(val);
500
501 if ((val = cupsGetOption("mirror", num_options, options)) != NULL &&
502 strcasecmp(val, "True") == 0)
503 Flip = 1;
504
505 /*
506 * Set the needed options in the page header...
507 */
508
509 memset(&header, 0, sizeof(header));
510 header.HWResolution[0] = 100;
511 header.HWResolution[1] = 100;
512 header.cupsBitsPerColor = 1;
513 header.cupsColorOrder = CUPS_ORDER_CHUNKED;
514 header.cupsColorSpace = CUPS_CSPACE_K;
515
516 if (ppd && ppd->patches)
517 exec_code(&header, ppd->patches);
518
519 if ((count = ppdCollect(ppd, PPD_ORDER_DOCUMENT, &choices)) > 0)
520 for (i = 0; i < count; i ++)
521 exec_code(&header, choices[i]->code);
522
523 if ((count = ppdCollect(ppd, PPD_ORDER_ANY, &choices)) > 0)
524 for (i = 0; i < count; i ++)
525 exec_code(&header, choices[i]->code);
526
527 if ((count = ppdCollect(ppd, PPD_ORDER_PROLOG, &choices)) > 0)
528 for (i = 0; i < count; i ++)
529 exec_code(&header, choices[i]->code);
530
531 if ((count = ppdCollect(ppd, PPD_ORDER_PAGE, &choices)) > 0)
532 for (i = 0; i < count; i ++)
533 exec_code(&header, choices[i]->code);
534
535 /*
536 * Get the media type and resolution that have been chosen...
537 */
538
539 if ((choice = ppdFindMarkedChoice(ppd, "MediaType")) != NULL)
540 media_type = choice->choice;
541 else
542 media_type = "";
543
544 if ((choice = ppdFindMarkedChoice(ppd, "Resolution")) != NULL)
545 resolution = choice->choice;
546 else
547 resolution = "";
548
549 /*
550 * Choose the appropriate colorspace...
551 */
552
553 switch (header.cupsColorSpace)
554 {
555 case CUPS_CSPACE_W :
556 primary = CUPS_IMAGE_WHITE;
557 secondary = CUPS_IMAGE_WHITE;
558 header.cupsBitsPerPixel = header.cupsBitsPerColor;
559 break;
560
561 default :
562 case CUPS_CSPACE_RGB :
563 case CUPS_CSPACE_RGBA :
564 case CUPS_CSPACE_RGBW :
565 primary = CUPS_IMAGE_RGB;
566 secondary = CUPS_IMAGE_RGB;
567
568 /*
569 * Ensure that colorimetric colorspaces use at least 8 bits per
570 * component...
571 */
572
573 if (header.cupsColorSpace >= CUPS_CSPACE_CIEXYZ &&
574 header.cupsBitsPerColor < 8)
575 header.cupsBitsPerColor = 8;
576
577 if (header.cupsColorOrder == CUPS_ORDER_CHUNKED)
578 {
579 if (header.cupsBitsPerColor >= 8)
580 header.cupsBitsPerPixel = header.cupsBitsPerColor * 3;
581 else
582 header.cupsBitsPerPixel = header.cupsBitsPerColor * 4;
583 }
584 else
585 header.cupsBitsPerPixel = header.cupsBitsPerColor;
586 break;
587
588 case CUPS_CSPACE_K :
589 case CUPS_CSPACE_WHITE :
590 case CUPS_CSPACE_GOLD :
591 case CUPS_CSPACE_SILVER :
592 primary = CUPS_IMAGE_BLACK;
593 secondary = CUPS_IMAGE_BLACK;
594 header.cupsBitsPerPixel = header.cupsBitsPerColor;
595 break;
596
597 case CUPS_CSPACE_CMYK :
598 case CUPS_CSPACE_YMCK :
599 case CUPS_CSPACE_KCMY :
600 case CUPS_CSPACE_GMCK :
601 case CUPS_CSPACE_GMCS :
602 primary = CUPS_IMAGE_CMYK;
603 secondary = CUPS_IMAGE_CMYK;
604
605 if (header.cupsColorOrder == CUPS_ORDER_CHUNKED)
606 header.cupsBitsPerPixel = header.cupsBitsPerColor * 4;
607 else
608 header.cupsBitsPerPixel = header.cupsBitsPerColor;
609 break;
610
611 case CUPS_CSPACE_CMY :
612 case CUPS_CSPACE_YMC :
613 primary = CUPS_IMAGE_CMY;
614 secondary = CUPS_IMAGE_CMY;
615
616 if (header.cupsColorOrder == CUPS_ORDER_CHUNKED)
617 {
618 if (header.cupsBitsPerColor >= 8)
619 header.cupsBitsPerPixel = 24;
620 else
621 header.cupsBitsPerPixel = header.cupsBitsPerColor * 4;
622 }
623 else
624 header.cupsBitsPerPixel = header.cupsBitsPerColor;
625 break;
626
627 case CUPS_CSPACE_KCMYcm :
628 if (header.cupsBitsPerPixel == 1)
629 {
630 primary = CUPS_IMAGE_CMY;
631 secondary = CUPS_IMAGE_CMY;
632
633 if (header.cupsColorOrder == CUPS_ORDER_CHUNKED)
634 header.cupsBitsPerPixel = 8;
635 else
636 header.cupsBitsPerPixel = 1;
637 }
638 else
639 {
640 primary = CUPS_IMAGE_CMYK;
641 secondary = CUPS_IMAGE_CMYK;
642
643 if (header.cupsColorOrder == CUPS_ORDER_CHUNKED)
644 header.cupsBitsPerPixel = header.cupsBitsPerColor * 4;
645 else
646 header.cupsBitsPerPixel = header.cupsBitsPerColor;
647 }
648 break;
649 }
650
651 /*
652 * Find a color profile matching the current options...
653 */
654
655 if ((val = cupsGetOption("profile", num_options, options)) != NULL)
656 {
657 profile = &userprofile;
658 sscanf(val, "%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f",
659 &(userprofile.density), &(userprofile.gamma),
660 userprofile.matrix[0] + 0, userprofile.matrix[0] + 1,
661 userprofile.matrix[0] + 2,
662 userprofile.matrix[1] + 0, userprofile.matrix[1] + 1,
663 userprofile.matrix[1] + 2,
664 userprofile.matrix[2] + 0, userprofile.matrix[2] + 1,
665 userprofile.matrix[2] + 2);
666
667 userprofile.density *= 0.001f;
668 userprofile.gamma *= 0.001f;
669 userprofile.matrix[0][0] *= 0.001f;
670 userprofile.matrix[0][1] *= 0.001f;
671 userprofile.matrix[0][2] *= 0.001f;
672 userprofile.matrix[1][0] *= 0.001f;
673 userprofile.matrix[1][1] *= 0.001f;
674 userprofile.matrix[1][2] *= 0.001f;
675 userprofile.matrix[2][0] *= 0.001f;
676 userprofile.matrix[2][1] *= 0.001f;
677 userprofile.matrix[2][2] *= 0.001f;
678 }
679 else if (ppd != NULL)
680 {
681 fprintf(stderr, "DEBUG: Searching for profile \"%s/%s\"...\n",
682 resolution, media_type);
683
684 for (i = 0, profile = ppd->profiles; i < ppd->num_profiles; i ++, profile ++)
685 {
686 fprintf(stderr, "DEBUG: \"%s/%s\" = ", profile->resolution,
687 profile->media_type);
688
689 if ((strcmp(profile->resolution, resolution) == 0 ||
690 profile->resolution[0] == '-') &&
691 (strcmp(profile->media_type, media_type) == 0 ||
692 profile->media_type[0] == '-'))
693 {
694 fputs("MATCH!\n", stderr);
695 break;
696 }
697 else
698 fputs("no.\n", stderr);
699 }
700
701 /*
702 * If we found a color profile, use it!
703 */
704
705 if (i >= ppd->num_profiles)
706 profile = NULL;
707 }
708 else
709 profile = NULL;
710
711 if (profile)
712 cupsImageSetProfile(profile->density, profile->gamma, profile->matrix);
713
714 cupsImageSetRasterColorSpace(header.cupsColorSpace);
715
716 /*
717 * Create a gamma/brightness LUT...
718 */
719
720 make_lut(lut, primary, g, b);
721
722 /*
723 * Open the input image to print...
724 */
725
726 fputs("INFO: Loading image file...\n", stderr);
727
728 img = cupsImageOpen(filename, primary, secondary, sat, hue, lut);
729
730 if (argc == 6)
731 unlink(filename);
732
733 if (img == NULL)
734 {
735 fputs("ERROR: Unable to open image file for printing!\n", stderr);
736 ppdClose(ppd);
737 return (1);
738 }
739
740 /*
741 * Scale as necessary...
742 */
743
744 if (zoom == 0.0 && xppi == 0)
745 {
746 xppi = img->xppi;
747 yppi = img->yppi;
748 }
749
750 if (yppi == 0)
751 yppi = xppi;
752
753 fprintf(stderr, "DEBUG: Before scaling: xppi=%d, yppi=%d, zoom=%.2f\n",
754 xppi, yppi, zoom);
755
756 if (xppi > 0)
757 {
758 /*
759 * Scale the image as neccesary to match the desired pixels-per-inch.
760 */
761
762 if (Orientation & 1)
763 {
764 xprint = (PageTop - PageBottom) / 72.0;
765 yprint = (PageRight - PageLeft) / 72.0;
766 }
767 else
768 {
769 xprint = (PageRight - PageLeft) / 72.0;
770 yprint = (PageTop - PageBottom) / 72.0;
771 }
772
773 fprintf(stderr, "DEBUG: Before scaling: xprint=%.1f, yprint=%.1f\n",
774 xprint, yprint);
775
776 xinches = (float)img->xsize / (float)xppi;
777 yinches = (float)img->ysize / (float)yppi;
778
779 fprintf(stderr, "DEBUG: Image size is %.1f x %.1f inches...\n",
780 xinches, yinches);
781
782 if ((val = cupsGetOption("natural-scaling", num_options, options)) != NULL)
783 {
784 xinches = xinches * atoi(val) / 100;
785 yinches = yinches * atoi(val) / 100;
786 }
787
788 if (cupsGetOption("orientation-requested", num_options, options) == NULL &&
789 cupsGetOption("landscape", num_options, options) == NULL)
790 {
791 /*
792 * Rotate the image if it will fit landscape but not portrait...
793 */
794
795 fputs("DEBUG: Auto orientation...\n", stderr);
796
797 if ((xinches > xprint || yinches > yprint) &&
798 xinches <= yprint && yinches <= xprint)
799 {
800 /*
801 * Rotate the image as needed...
802 */
803
804 fputs("DEBUG: Using landscape orientation...\n", stderr);
805
806 Orientation = (Orientation + 1) & 3;
807 xsize = yprint;
808 yprint = xprint;
809 xprint = xsize;
810 }
811 }
812 }
813 else
814 {
815 /*
816 * Scale percentage of page size...
817 */
818
819 xprint = (PageRight - PageLeft) / 72.0;
820 yprint = (PageTop - PageBottom) / 72.0;
821 aspect = (float)img->yppi / (float)img->xppi;
822
823 fprintf(stderr, "DEBUG: Before scaling: xprint=%.1f, yprint=%.1f\n",
824 xprint, yprint);
825
826 fprintf(stderr, "DEBUG: img->xppi = %d, img->yppi = %d, aspect = %f\n",
827 img->xppi, img->yppi, aspect);
828
829 xsize = xprint * zoom;
830 ysize = xsize * img->ysize / img->xsize / aspect;
831
832 if (ysize > (yprint * zoom))
833 {
834 ysize = yprint * zoom;
835 xsize = ysize * img->xsize * aspect / img->ysize;
836 }
837
838 xsize2 = yprint * zoom;
839 ysize2 = xsize2 * img->ysize / img->xsize / aspect;
840
841 if (ysize2 > (xprint * zoom))
842 {
843 ysize2 = xprint * zoom;
844 xsize2 = ysize2 * img->xsize * aspect / img->ysize;
845 }
846
847 fprintf(stderr, "DEBUG: Portrait size is %.2f x %.2f inches\n", xsize, ysize);
848 fprintf(stderr, "DEBUG: Landscape size is %.2f x %.2f inches\n", xsize2, ysize2);
849
850 if (cupsGetOption("orientation-requested", num_options, options) == NULL &&
851 cupsGetOption("landscape", num_options, options) == NULL)
852 {
853 /*
854 * Choose the rotation with the largest area, but prefer
855 * portrait if they are equal...
856 */
857
858 fputs("DEBUG: Auto orientation...\n", stderr);
859
860 if ((xsize * ysize) < (xsize2 * xsize2))
861 {
862 /*
863 * Do landscape orientation...
864 */
865
866 fputs("DEBUG: Using landscape orientation...\n", stderr);
867
868 Orientation = 1;
869 xinches = xsize2;
870 yinches = ysize2;
871 xprint = (PageTop - PageBottom) / 72.0;
872 yprint = (PageRight - PageLeft) / 72.0;
873 }
874 else
875 {
876 /*
877 * Do portrait orientation...
878 */
879
880 fputs("DEBUG: Using portrait orientation...\n", stderr);
881
882 Orientation = 0;
883 xinches = xsize;
884 yinches = ysize;
885 }
886 }
887 else if (Orientation & 1)
888 {
889 fputs("DEBUG: Using landscape orientation...\n", stderr);
890
891 xinches = xsize2;
892 yinches = ysize2;
893 xprint = (PageTop - PageBottom) / 72.0;
894 yprint = (PageRight - PageLeft) / 72.0;
895 }
896 else
897 {
898 fputs("DEBUG: Using portrait orientation...\n", stderr);
899
900 xinches = xsize;
901 yinches = ysize;
902 xprint = (PageRight - PageLeft) / 72.0;
903 yprint = (PageTop - PageBottom) / 72.0;
904 }
905 }
906
907 /*
908 * Compute the number of pages to print and the size of the image on each
909 * page...
910 */
911
912 xpages = ceil(xinches / xprint);
913 ypages = ceil(yinches / yprint);
914
915 xprint = xinches / xpages;
916 yprint = yinches / ypages;
917
918 fprintf(stderr, "DEBUG: xpages = %dx%.2fin, ypages = %dx%.2fin\n",
919 xpages, xprint, ypages, yprint);
920
921 /*
922 * Compute the bitmap size...
923 */
924
925 if ((choice = ppdFindMarkedChoice(ppd, "PageSize")) != NULL &&
926 strcasecmp(choice->choice, "Custom") == 0)
927 {
928 float width, /* New width in points */
929 length; /* New length in points */
930
931
932 /*
933 * Use the correct width and length for the current orientation...
934 */
935
936 if (Orientation & 1)
937 {
938 width = yprint * 72.0;
939 length = xprint * 72.0;
940 }
941 else
942 {
943 width = xprint * 72.0;
944 length = yprint * 72.0;
945 }
946
947 /*
948 * Add margins to page size...
949 */
950
951 width += ppd->custom_margins[0] + ppd->custom_margins[2];
952 length += ppd->custom_margins[1] + ppd->custom_margins[3];
953
954 /*
955 * Enforce minimums...
956 */
957
958 if (width < ppd->custom_min[0])
959 width = ppd->custom_min[0];
960
961 if (length < ppd->custom_min[1])
962 length = ppd->custom_min[1];
963
964 fprintf(stderr, "DEBUG: Updated custom page size to %.2f x %.2f inches...\n",
965 width / 72.0, length / 72.0);
966
967 /*
968 * Set the new custom size...
969 */
970
971 header.PageSize[0] = width + 0.5;
972 header.PageSize[1] = length + 0.5;
973
974 /*
975 * Update page variables...
976 */
977
978 PageWidth = width;
979 PageLength = length;
980 PageLeft = ppd->custom_margins[0];
981 PageRight = width - ppd->custom_margins[2];
982 PageBottom = ppd->custom_margins[1];
983 PageTop = length - ppd->custom_margins[3];
984
985 /*
986 * Remove margins from page size...
987 */
988
989 width -= ppd->custom_margins[0] + ppd->custom_margins[2];
990 length -= ppd->custom_margins[1] + ppd->custom_margins[3];
991
992 /*
993 * Set the bitmap size...
994 */
995
996 header.cupsWidth = width * header.HWResolution[0] / 72.0;
997 header.cupsHeight = length * header.HWResolution[1] / 72.0;
998 }
999 else
1000 {
1001 header.cupsWidth = (PageRight - PageLeft) * header.HWResolution[0] / 72.0;
1002 header.cupsHeight = (PageTop - PageBottom) * header.HWResolution[1] / 72.0;
1003 header.PageSize[0] = PageWidth;
1004 header.PageSize[1] = PageLength;
1005 }
1006
1007 header.Margins[0] = PageLeft;
1008 header.Margins[1] = PageBottom;
1009
1010 fprintf(stderr, "DEBUG: PageSize = [%d %d]\n", header.PageSize[0],
1011 header.PageSize[1]);
1012
1013 switch (Orientation)
1014 {
1015 default :
1016 switch (XPosition)
1017 {
1018 case -1 :
1019 header.ImagingBoundingBox[0] = PageLeft;
1020 header.ImagingBoundingBox[2] = PageLeft + xprint * 72;
1021 break;
1022 default :
1023 header.ImagingBoundingBox[0] = (PageRight + PageLeft - xprint * 72) / 2;
1024 header.ImagingBoundingBox[2] = (PageRight + PageLeft + xprint * 72) / 2;
1025 break;
1026 case 1 :
1027 header.ImagingBoundingBox[0] = PageRight - xprint * 72;
1028 header.ImagingBoundingBox[2] = PageRight;
1029 break;
1030 }
1031
1032 switch (YPosition)
1033 {
1034 case -1 :
1035 header.ImagingBoundingBox[1] = PageBottom;
1036 header.ImagingBoundingBox[3] = PageBottom + yprint * 72;
1037 break;
1038 default :
1039 header.ImagingBoundingBox[1] = (PageTop + PageBottom - yprint * 72) / 2;
1040 header.ImagingBoundingBox[3] = (PageTop + PageBottom + yprint * 72) / 2;
1041 break;
1042 case 1 :
1043 header.ImagingBoundingBox[1] = PageTop - yprint * 72;
1044 header.ImagingBoundingBox[3] = PageTop;
1045 break;
1046 }
1047 break;
1048
1049 case 1 :
1050 switch (XPosition)
1051 {
1052 case -1 :
1053 header.ImagingBoundingBox[0] = PageBottom;
1054 header.ImagingBoundingBox[2] = PageBottom + yprint * 72;
1055 break;
1056 default :
1057 header.ImagingBoundingBox[0] = (PageTop + PageBottom - yprint * 72) / 2;
1058 header.ImagingBoundingBox[2] = (PageTop + PageBottom + yprint * 72) / 2;
1059 break;
1060 case 1 :
1061 header.ImagingBoundingBox[0] = PageTop - yprint * 72;
1062 header.ImagingBoundingBox[2] = PageTop;
1063 break;
1064 }
1065
1066 switch (YPosition)
1067 {
1068 case -1 :
1069 header.ImagingBoundingBox[1] = PageLeft;
1070 header.ImagingBoundingBox[3] = PageLeft + xprint * 72;
1071 break;
1072 default :
1073 header.ImagingBoundingBox[1] = (PageRight + PageLeft - xprint * 72) / 2;
1074 header.ImagingBoundingBox[3] = (PageRight + PageLeft + xprint * 72) / 2;
1075 break;
1076 case 1 :
1077 header.ImagingBoundingBox[1] = PageRight - xprint * 72;
1078 header.ImagingBoundingBox[3] = PageRight;
1079 break;
1080 }
1081 break;
1082
1083 case 2 :
1084 switch (XPosition)
1085 {
1086 case 1 :
1087 header.ImagingBoundingBox[0] = PageLeft;
1088 header.ImagingBoundingBox[2] = PageLeft + xprint * 72;
1089 break;
1090 default :
1091 header.ImagingBoundingBox[0] = (PageRight + PageLeft - xprint * 72) / 2;
1092 header.ImagingBoundingBox[2] = (PageRight + PageLeft + xprint * 72) / 2;
1093 break;
1094 case -1 :
1095 header.ImagingBoundingBox[0] = PageRight - xprint * 72;
1096 header.ImagingBoundingBox[2] = PageRight;
1097 break;
1098 }
1099
1100 switch (YPosition)
1101 {
1102 case 1 :
1103 header.ImagingBoundingBox[1] = PageBottom;
1104 header.ImagingBoundingBox[3] = PageBottom + yprint * 72;
1105 break;
1106 default :
1107 header.ImagingBoundingBox[1] = (PageTop + PageBottom - yprint * 72) / 2;
1108 header.ImagingBoundingBox[3] = (PageTop + PageBottom + yprint * 72) / 2;
1109 break;
1110 case -1 :
1111 header.ImagingBoundingBox[1] = PageTop - yprint * 72;
1112 header.ImagingBoundingBox[3] = PageTop;
1113 break;
1114 }
1115 break;
1116
1117 case 3 :
1118 switch (XPosition)
1119 {
1120 case 1 :
1121 header.ImagingBoundingBox[0] = PageBottom;
1122 header.ImagingBoundingBox[2] = PageBottom + yprint * 72;
1123 break;
1124 default :
1125 header.ImagingBoundingBox[0] = (PageTop + PageBottom - yprint * 72) / 2;
1126 header.ImagingBoundingBox[2] = (PageTop + PageBottom + yprint * 72) / 2;
1127 break;
1128 case -1 :
1129 header.ImagingBoundingBox[0] = PageTop - yprint * 72;
1130 header.ImagingBoundingBox[2] = PageTop;
1131 break;
1132 }
1133
1134 switch (YPosition)
1135 {
1136 case 1 :
1137 header.ImagingBoundingBox[1] = PageLeft;
1138 header.ImagingBoundingBox[3] = PageLeft + xprint * 72;
1139 break;
1140 default :
1141 header.ImagingBoundingBox[1] = (PageRight + PageLeft - xprint * 72) / 2;
1142 header.ImagingBoundingBox[3] = (PageRight + PageLeft + xprint * 72) / 2;
1143 break;
1144 case -1 :
1145 header.ImagingBoundingBox[1] = PageRight - xprint * 72;
1146 header.ImagingBoundingBox[3] = PageRight;
1147 break;
1148 }
1149 break;
1150 }
1151
1152 switch (header.cupsColorOrder)
1153 {
1154 default :
1155 header.cupsBytesPerLine = (header.cupsBitsPerPixel *
1156 header.cupsWidth + 7) / 8;
1157 num_planes = 1;
1158 break;
1159
1160 case CUPS_ORDER_BANDED :
1161 if (header.cupsColorSpace == CUPS_CSPACE_KCMYcm &&
1162 header.cupsBitsPerColor > 1)
1163 header.cupsBytesPerLine = (header.cupsBitsPerPixel *
1164 header.cupsWidth + 7) / 8 * 4;
1165 else
1166 header.cupsBytesPerLine = (header.cupsBitsPerPixel *
1167 header.cupsWidth + 7) / 8 *
1168 Planes[header.cupsColorSpace];
1169 num_planes = 1;
1170 break;
1171
1172 case CUPS_ORDER_PLANAR :
1173 header.cupsBytesPerLine = (header.cupsBitsPerPixel *
1174 header.cupsWidth + 7) / 8;
1175 num_planes = Planes[header.cupsColorSpace];
1176 break;
1177 }
1178
1179 if (header.cupsBitsPerColor >= 8)
1180 zoom_type = CUPS_IZOOM_NORMAL;
1181 else
1182 zoom_type = CUPS_IZOOM_FAST;
1183
1184 /*
1185 * See if we need to collate, and if so how we need to do it...
1186 */
1187
1188 if (xpages == 1 && ypages == 1)
1189 Collate = 0;
1190
1191 slowcollate = Collate && ppdFindOption(ppd, "Collate") == NULL;
1192 if (ppd != NULL)
1193 slowcopies = ppd->manual_copies;
1194 else
1195 slowcopies = 1;
1196
1197 if (Copies > 1 && !slowcollate && !slowcopies)
1198 {
1199 header.Collate = (cups_bool_t)Collate;
1200 header.NumCopies = Copies;
1201
1202 Copies = 1;
1203 }
1204 else
1205 header.NumCopies = 1;
1206
1207 /*
1208 * Create the dithering lookup tables...
1209 */
1210
1211 OnPixels[0] = 0x00;
1212 OnPixels[255] = 0xff;
1213 OffPixels[0] = 0x00;
1214 OffPixels[255] = 0xff;
1215
1216 switch (header.cupsBitsPerColor)
1217 {
1218 case 2 :
1219 for (i = 1; i < 255; i ++)
1220 {
1221 OnPixels[i] = 0x55 * (i / 85 + 1);
1222 OffPixels[i] = 0x55 * (i / 64);
1223 }
1224 break;
1225 case 4 :
1226 for (i = 1; i < 255; i ++)
1227 {
1228 OnPixels[i] = 17 * (i / 17 + 1);
1229 OffPixels[i] = 17 * (i / 16);
1230 }
1231
1232 OnPixels[255] = OffPixels[255] = 0xff;
1233 break;
1234 }
1235
1236 /*
1237 * Output the pages...
1238 */
1239
1240 fprintf(stderr, "DEBUG: cupsWidth = %d\n", header.cupsWidth);
1241 fprintf(stderr, "DEBUG: cupsHeight = %d\n", header.cupsHeight);
1242 fprintf(stderr, "DEBUG: cupsBitsPerColor = %d\n", header.cupsBitsPerColor);
1243 fprintf(stderr, "DEBUG: cupsBitsPerPixel = %d\n", header.cupsBitsPerPixel);
1244 fprintf(stderr, "DEBUG: cupsBytesPerLine = %d\n", header.cupsBytesPerLine);
1245 fprintf(stderr, "DEBUG: cupsColorOrder = %d\n", header.cupsColorOrder);
1246 fprintf(stderr, "DEBUG: cupsColorSpace = %d\n", header.cupsColorSpace);
1247 fprintf(stderr, "DEBUG: img->colorspace = %d\n", img->colorspace);
1248
1249 row = malloc(2 * header.cupsBytesPerLine);
1250 ras = cupsRasterOpen(1, CUPS_RASTER_WRITE);
1251 blank = img->colorspace < 0 ? 0 : ~0;
1252
1253 for (i = 0, page = 1; i < Copies; i ++)
1254 for (xpage = 0; xpage < xpages; xpage ++)
1255 for (ypage = 0; ypage < ypages; ypage ++, page ++)
1256 {
1257 fprintf(stderr, "INFO: Formatting page %d...\n", page);
1258
1259 if (Orientation & 1)
1260 {
1261 xc0 = img->xsize * ypage / ypages;
1262 xc1 = img->xsize * (ypage + 1) / ypages - 1;
1263 yc0 = img->ysize * xpage / xpages;
1264 yc1 = img->ysize * (xpage + 1) / xpages - 1;
1265
1266 xtemp = header.HWResolution[0] * yprint;
1267 ytemp = header.HWResolution[1] * xprint;
1268 }
1269 else
1270 {
1271 xc0 = img->xsize * xpage / xpages;
1272 xc1 = img->xsize * (xpage + 1) / xpages - 1;
1273 yc0 = img->ysize * ypage / ypages;
1274 yc1 = img->ysize * (ypage + 1) / ypages - 1;
1275
1276 xtemp = header.HWResolution[0] * xprint;
1277 ytemp = header.HWResolution[1] * yprint;
1278 }
1279
1280 cupsRasterWriteHeader2(ras, &header);
1281
1282 for (plane = 0; plane < num_planes; plane ++)
1283 {
1284 /*
1285 * Initialize the image "zoom" engine...
1286 */
1287
1288 if (Flip)
1289 z = _cupsImageZoomNew(img, xc0, yc0, xc1, yc1, -xtemp, ytemp,
1290 Orientation & 1, zoom_type);
1291 else
1292 z = _cupsImageZoomNew(img, xc0, yc0, xc1, yc1, xtemp, ytemp,
1293 Orientation & 1, zoom_type);
1294
1295 /*
1296 * Write leading blank space as needed...
1297 */
1298
1299 if (header.cupsHeight > z->ysize && YPosition <= 0)
1300 {
1301 memset(row, blank, header.cupsBytesPerLine);
1302
1303 y = header.cupsHeight - z->ysize;
1304 if (YPosition == 0)
1305 y /= 2;
1306
1307 for (; y > 0; y --)
1308 {
1309 if (cupsRasterWritePixels(ras, row, header.cupsBytesPerLine) <
1310 header.cupsBytesPerLine)
1311 {
1312 fputs("ERROR: Unable to write raster data to driver!\n", stderr);
1313 cupsImageClose(img);
1314 exit(1);
1315 }
1316 }
1317 }
1318
1319 /*
1320 * Then write image data...
1321 */
1322
1323 for (y = z->ysize, yerr0 = 0, yerr1 = z->ysize, iy = 0, last_iy = -2;
1324 y > 0;
1325 y --)
1326 {
1327 if (iy != last_iy)
1328 {
1329 if (zoom_type != CUPS_IZOOM_FAST && (iy - last_iy) > 1)
1330 _cupsImageZoomFill(z, iy);
1331
1332 _cupsImageZoomFill(z, iy + z->yincr);
1333
1334 last_iy = iy;
1335 }
1336
1337 /*
1338 * Format this line of raster data for the printer...
1339 */
1340
1341 memset(row, blank, header.cupsBytesPerLine);
1342
1343 r0 = z->rows[z->row];
1344 r1 = z->rows[1 - z->row];
1345
1346 switch (header.cupsColorSpace)
1347 {
1348 case CUPS_CSPACE_W :
1349 format_W(&header, row, y, plane, z->xsize, z->ysize,
1350 yerr0, yerr1, r0, r1);
1351 break;
1352 default :
1353 case CUPS_CSPACE_RGB :
1354 format_RGB(&header, row, y, plane, z->xsize, z->ysize,
1355 yerr0, yerr1, r0, r1);
1356 break;
1357 case CUPS_CSPACE_RGBA :
1358 case CUPS_CSPACE_RGBW :
1359 format_RGBA(&header, row, y, plane, z->xsize, z->ysize,
1360 yerr0, yerr1, r0, r1);
1361 break;
1362 case CUPS_CSPACE_K :
1363 case CUPS_CSPACE_WHITE :
1364 case CUPS_CSPACE_GOLD :
1365 case CUPS_CSPACE_SILVER :
1366 format_K(&header, row, y, plane, z->xsize, z->ysize,
1367 yerr0, yerr1, r0, r1);
1368 break;
1369 case CUPS_CSPACE_CMY :
1370 format_CMY(&header, row, y, plane, z->xsize, z->ysize,
1371 yerr0, yerr1, r0, r1);
1372 break;
1373 case CUPS_CSPACE_YMC :
1374 format_YMC(&header, row, y, plane, z->xsize, z->ysize,
1375 yerr0, yerr1, r0, r1);
1376 break;
1377 case CUPS_CSPACE_CMYK :
1378 format_CMYK(&header, row, y, plane, z->xsize, z->ysize,
1379 yerr0, yerr1, r0, r1);
1380 break;
1381 case CUPS_CSPACE_YMCK :
1382 case CUPS_CSPACE_GMCK :
1383 case CUPS_CSPACE_GMCS :
1384 format_YMCK(&header, row, y, plane, z->xsize, z->ysize,
1385 yerr0, yerr1, r0, r1);
1386 break;
1387 case CUPS_CSPACE_KCMY :
1388 format_KCMY(&header, row, y, plane, z->xsize, z->ysize,
1389 yerr0, yerr1, r0, r1);
1390 break;
1391 case CUPS_CSPACE_KCMYcm :
1392 format_KCMYcm(&header, row, y, plane, z->xsize, z->ysize,
1393 yerr0, yerr1, r0, r1);
1394 break;
1395 }
1396
1397 /*
1398 * Write the raster data to the driver...
1399 */
1400
1401 if (cupsRasterWritePixels(ras, row, header.cupsBytesPerLine) <
1402 header.cupsBytesPerLine)
1403 {
1404 fputs("ERROR: Unable to write raster data to driver!\n", stderr);
1405 cupsImageClose(img);
1406 exit(1);
1407 }
1408
1409 /*
1410 * Compute the next scanline in the image...
1411 */
1412
1413 iy += z->ystep;
1414 yerr0 += z->ymod;
1415 yerr1 -= z->ymod;
1416 if (yerr1 <= 0)
1417 {
1418 yerr0 -= z->ysize;
1419 yerr1 += z->ysize;
1420 iy += z->yincr;
1421 }
1422 }
1423
1424 /*
1425 * Write trailing blank space as needed...
1426 */
1427
1428 if (header.cupsHeight > z->ysize && YPosition >= 0)
1429 {
1430 memset(row, blank, header.cupsBytesPerLine);
1431
1432 y = header.cupsHeight - z->ysize;
1433 if (YPosition == 0)
1434 y = y - y / 2;
1435
1436 for (; y > 0; y --)
1437 {
1438 if (cupsRasterWritePixels(ras, row, header.cupsBytesPerLine) <
1439 header.cupsBytesPerLine)
1440 {
1441 fputs("ERROR: Unable to write raster data to driver!\n", stderr);
1442 cupsImageClose(img);
1443 exit(1);
1444 }
1445 }
1446 }
1447
1448 /*
1449 * Free memory used for the "zoom" engine...
1450 */
1451
1452 _cupsImageZoomDelete(z);
1453 }
1454 }
1455
1456 /*
1457 * Close files...
1458 */
1459
1460 free(row);
1461 cupsRasterClose(ras);
1462 cupsImageClose(img);
1463 ppdClose(ppd);
1464
1465 return (0);
1466 }
1467
1468
1469 /*
1470 * 'exec_code()' - Execute PostScript setpagedevice commands as appropriate.
1471 */
1472
1473 static void
1474 exec_code(cups_page_header2_t *header, /* I - Page header */
1475 const char *code) /* I - Option choice to execute */
1476 {
1477 char *ptr, /* Pointer into name/value string */
1478 name[255], /* Name of pagedevice entry */
1479 value[1024]; /* Value of pagedevice entry */
1480
1481
1482 for (; *code != '\0';)
1483 {
1484 /*
1485 * Search for the start of a dictionary name...
1486 */
1487
1488 while (*code != '/' && *code != '\0')
1489 code ++;
1490
1491 if (*code == '\0')
1492 break;
1493
1494 /*
1495 * Get the name...
1496 */
1497
1498 code ++;
1499 for (ptr = name; isalnum(*code & 255) && (ptr - name) < (sizeof(name) - 1);)
1500 *ptr++ = *code++;
1501 *ptr = '\0';
1502
1503 /*
1504 * The parse the value as needed...
1505 */
1506
1507 while (isspace(*code & 255))
1508 code ++;
1509
1510 if (*code == '\0')
1511 break;
1512
1513 if (*code == '[')
1514 {
1515 /*
1516 * Read array of values...
1517 */
1518
1519 code ++;
1520 for (ptr = value;
1521 *code != ']' && *code != '\0' &&
1522 (ptr - value) < (sizeof(value) - 1);)
1523 *ptr++ = *code++;
1524 *ptr = '\0';
1525 }
1526 else if (*code == '(')
1527 {
1528 /*
1529 * Read string value...
1530 */
1531
1532 code ++;
1533 for (ptr = value;
1534 *code != ')' && *code != '\0' &&
1535 (ptr - value) < (sizeof(value) - 1);)
1536 if (*code == '\\')
1537 {
1538 code ++;
1539 if (isdigit(*code & 255))
1540 *ptr++ = (char)strtol(code, (char **)&code, 8);
1541 else
1542 *ptr++ = *code++;
1543 }
1544 else
1545 *ptr++ = *code++;
1546
1547 *ptr = '\0';
1548 }
1549 else if (isdigit(*code & 255) || *code == '-')
1550 {
1551 /*
1552 * Read single number...
1553 */
1554
1555 for (ptr = value;
1556 (isdigit(*code & 255) || *code == '-') &&
1557 (ptr - value) < (sizeof(value) - 1);)
1558 *ptr++ = *code++;
1559 *ptr = '\0';
1560 }
1561 else
1562 {
1563 /*
1564 * Read a single name...
1565 */
1566
1567 for (ptr = value;
1568 (isalnum(*code & 255) || *code == '_') &&
1569 (ptr - value) < (sizeof(value) - 1);)
1570 *ptr++ = *code++;
1571 *ptr = '\0';
1572 }
1573
1574 /*
1575 * Assign the value as needed...
1576 */
1577
1578 if (!strcmp(name, "MediaClass"))
1579 strlcpy(header->MediaClass, value, sizeof(header->MediaClass));
1580 else if (!strcmp(name, "MediaColor"))
1581 strlcpy(header->MediaColor, value, sizeof(header->MediaColor));
1582 else if (!strcmp(name, "MediaType"))
1583 strlcpy(header->MediaType, value, sizeof(header->MediaType));
1584 else if (!strcmp(name, "OutputType"))
1585 strlcpy(header->OutputType, value, sizeof(header->OutputType));
1586 else if (!strcmp(name, "AdvanceDistance"))
1587 header->AdvanceDistance = atoi(value);
1588 else if (!strcmp(name, "AdvanceMedia"))
1589 header->AdvanceMedia = atoi(value);
1590 else if (!strcmp(name, "Collate"))
1591 header->Collate = !strcmp(value, "true");
1592 else if (!strcmp(name, "CutMedia"))
1593 header->CutMedia = (cups_cut_t)atoi(value);
1594 else if (!strcmp(name, "Duplex"))
1595 header->Duplex = !strcmp(value, "true");
1596 else if (!strcmp(name, "HWResolution"))
1597 sscanf(value, "%d%d", header->HWResolution + 0, header->HWResolution + 1);
1598 else if (!strcmp(name, "InsertSheet"))
1599 header->InsertSheet = !strcmp(value, "true");
1600 else if (!strcmp(name, "Jog"))
1601 header->Jog = atoi(value);
1602 else if (!strcmp(name, "LeadingEdge"))
1603 header->LeadingEdge = atoi(value);
1604 else if (!strcmp(name, "Margins"))
1605 sscanf(value, "%d%d", header->Margins + 0, header->Margins + 1);
1606 else if (!strcmp(name, "ManualFeed"))
1607 header->ManualFeed = !strcmp(value, "true");
1608 else if (!strcmp(name, "cupsMediaPosition") || /* Compatibility */
1609 !strcmp(name, "MediaPosition"))
1610 header->MediaPosition = atoi(value);
1611 else if (!strcmp(name, "MediaWeight"))
1612 header->MediaWeight = atoi(value);
1613 else if (!strcmp(name, "MirrorPrint"))
1614 header->MirrorPrint = !strcmp(value, "true");
1615 else if (!strcmp(name, "NegativePrint"))
1616 header->NegativePrint = !strcmp(value, "true");
1617 else if (!strcmp(name, "Orientation"))
1618 header->Orientation = atoi(value);
1619 else if (!strcmp(name, "OutputFaceUp"))
1620 header->OutputFaceUp = !strcmp(value, "true");
1621 else if (!strcmp(name, "Separations"))
1622 header->Separations = !strcmp(value, "true");
1623 else if (!strcmp(name, "TraySwitch"))
1624 header->TraySwitch = !strcmp(value, "true");
1625 else if (!strcmp(name, "Tumble"))
1626 header->Tumble = !strcmp(value, "true");
1627 else if (!strcmp(name, "cupsMediaType"))
1628 header->cupsMediaType = atoi(value);
1629 else if (!strcmp(name, "cupsBitsPerColor"))
1630 header->cupsBitsPerColor = atoi(value);
1631 else if (!strcmp(name, "cupsColorOrder"))
1632 header->cupsColorOrder = (cups_order_t)atoi(value);
1633 else if (!strcmp(name, "cupsColorSpace"))
1634 header->cupsColorSpace = (cups_cspace_t)atoi(value);
1635 else if (!strcmp(name, "cupsCompression"))
1636 header->cupsCompression = atoi(value);
1637 else if (!strcmp(name, "cupsRowCount"))
1638 header->cupsRowCount = atoi(value);
1639 else if (!strcmp(name, "cupsRowFeed"))
1640 header->cupsRowFeed = atoi(value);
1641 else if (!strcmp(name, "cupsRowStep"))
1642 header->cupsRowStep = atoi(value);
1643 }
1644 }
1645
1646
1647 /*
1648 * 'format_CMY()' - Convert image data to CMY.
1649 */
1650
1651 static void
1652 format_CMY(cups_page_header2_t *header, /* I - Page header */
1653 unsigned char *row, /* IO - Bitmap data for device */
1654 int y, /* I - Current row */
1655 int z, /* I - Current plane */
1656 int xsize, /* I - Width of image data */
1657 int ysize, /* I - Height of image data */
1658 int yerr0, /* I - Top Y error */
1659 int yerr1, /* I - Bottom Y error */
1660 cups_ib_t *r0, /* I - Primary image data */
1661 cups_ib_t *r1) /* I - Image data for interpolation */
1662 {
1663 cups_ib_t *ptr, /* Pointer into row */
1664 *cptr, /* Pointer into cyan */
1665 *mptr, /* Pointer into magenta */
1666 *yptr, /* Pointer into yellow */
1667 bitmask; /* Current mask for pixel */
1668 int bitoffset; /* Current offset in line */
1669 int bandwidth; /* Width of a color band */
1670 int x, /* Current X coordinate on page */
1671 *dither; /* Pointer into dither array */
1672
1673
1674 switch (XPosition)
1675 {
1676 case -1 :
1677 bitoffset = 0;
1678 break;
1679 default :
1680 bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2);
1681 break;
1682 case 1 :
1683 bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize);
1684 break;
1685 }
1686
1687 ptr = row + bitoffset / 8;
1688 bandwidth = header->cupsBytesPerLine / 3;
1689
1690 switch (header->cupsColorOrder)
1691 {
1692 case CUPS_ORDER_CHUNKED :
1693 switch (header->cupsBitsPerColor)
1694 {
1695 case 1 :
1696 bitmask = 64 >> (bitoffset & 7);
1697 dither = Floyd16xc16[y & 15];
1698
1699 for (x = xsize ; x > 0; x --)
1700 {
1701 if (*r0++ > dither[x & 15])
1702 *ptr ^= bitmask;
1703 bitmask >>= 1;
1704
1705 if (*r0++ > dither[x & 15])
1706 *ptr ^= bitmask;
1707 bitmask >>= 1;
1708
1709 if (*r0++ > dither[x & 15])
1710 *ptr ^= bitmask;
1711
1712 if (bitmask > 1)
1713 bitmask >>= 2;
1714 else
1715 {
1716 bitmask = 64;
1717 ptr ++;
1718 }
1719 }
1720 break;
1721
1722 case 2 :
1723 dither = Floyd8x8[y & 7];
1724
1725 for (x = xsize ; x > 0; x --, r0 += 3)
1726 {
1727 if ((r0[0] & 63) > dither[x & 7])
1728 *ptr ^= (0x30 & OnPixels[r0[0]]);
1729 else
1730 *ptr ^= (0x30 & OffPixels[r0[0]]);
1731
1732 if ((r0[1] & 63) > dither[x & 7])
1733 *ptr ^= (0x0c & OnPixels[r0[1]]);
1734 else
1735 *ptr ^= (0x0c & OffPixels[r0[1]]);
1736
1737 if ((r0[2] & 63) > dither[x & 7])
1738 *ptr++ ^= (0x03 & OnPixels[r0[2]]);
1739 else
1740 *ptr++ ^= (0x03 & OffPixels[r0[2]]);
1741 }
1742 break;
1743
1744 case 4 :
1745 dither = Floyd4x4[y & 3];
1746
1747 for (x = xsize ; x > 0; x --, r0 += 3)
1748 {
1749 if ((r0[0] & 15) > dither[x & 3])
1750 *ptr++ ^= (0x0f & OnPixels[r0[0]]);
1751 else
1752 *ptr++ ^= (0x0f & OffPixels[r0[0]]);
1753
1754 if ((r0[1] & 15) > dither[x & 3])
1755 *ptr ^= (0xf0 & OnPixels[r0[1]]);
1756 else
1757 *ptr ^= (0xf0 & OffPixels[r0[1]]);
1758
1759 if ((r0[2] & 15) > dither[x & 3])
1760 *ptr++ ^= (0x0f & OnPixels[r0[2]]);
1761 else
1762 *ptr++ ^= (0x0f & OffPixels[r0[2]]);
1763 }
1764 break;
1765
1766 case 8 :
1767 for (x = xsize * 3; x > 0; x --, r0 ++, r1 ++)
1768 if (*r0 == *r1)
1769 *ptr++ = *r0;
1770 else
1771 *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize;
1772 break;
1773 }
1774 break;
1775
1776 case CUPS_ORDER_BANDED :
1777 cptr = ptr;
1778 mptr = ptr + bandwidth;
1779 yptr = ptr + 2 * bandwidth;
1780
1781 switch (header->cupsBitsPerColor)
1782 {
1783 case 1 :
1784 bitmask = 0x80 >> (bitoffset & 7);
1785 dither = Floyd16xc16[y & 15];
1786
1787 for (x = xsize; x > 0; x --)
1788 {
1789 if (*r0++ > dither[x & 15])
1790 *cptr ^= bitmask;
1791 if (*r0++ > dither[x & 15])
1792 *mptr ^= bitmask;
1793 if (*r0++ > dither[x & 15])
1794 *yptr ^= bitmask;
1795
1796 if (bitmask > 1)
1797 bitmask >>= 1;
1798 else
1799 {
1800 bitmask = 0x80;
1801 cptr ++;
1802 mptr ++;
1803 yptr ++;
1804 }
1805 }
1806 break;
1807
1808 case 2 :
1809 bitmask = 0x0 >> (bitoffset & 7);
1810 dither = Floyd8x8[y & 7];
1811
1812 for (x = xsize; x > 0; x --)
1813 {
1814 if ((*r0 & 63) > dither[x & 7])
1815 *cptr ^= (bitmask & OnPixels[*r0++]);
1816 else
1817 *cptr ^= (bitmask & OffPixels[*r0++]);
1818
1819 if ((*r0 & 63) > dither[x & 7])
1820 *mptr ^= (bitmask & OnPixels[*r0++]);
1821 else
1822 *mptr ^= (bitmask & OffPixels[*r0++]);
1823
1824 if ((*r0 & 63) > dither[x & 7])
1825 *yptr ^= (bitmask & OnPixels[*r0++]);
1826 else
1827 *yptr ^= (bitmask & OffPixels[*r0++]);
1828
1829 if (bitmask > 3)
1830 bitmask >>= 2;
1831 else
1832 {
1833 bitmask = 0x0;
1834
1835 cptr ++;
1836 mptr ++;
1837 yptr ++;
1838 }
1839 }
1840 break;
1841
1842 case 4 :
1843 bitmask = 0xf0 >> (bitoffset & 7);
1844 dither = Floyd4x4[y & 3];
1845
1846 for (x = xsize; x > 0; x --)
1847 {
1848 if ((*r0 & 15) > dither[x & 3])
1849 *cptr ^= (bitmask & OnPixels[*r0++]);
1850 else
1851 *cptr ^= (bitmask & OffPixels[*r0++]);
1852
1853 if ((*r0 & 15) > dither[x & 3])
1854 *mptr ^= (bitmask & OnPixels[*r0++]);
1855 else
1856 *mptr ^= (bitmask & OffPixels[*r0++]);
1857
1858 if ((*r0 & 15) > dither[x & 3])
1859 *yptr ^= (bitmask & OnPixels[*r0++]);
1860 else
1861 *yptr ^= (bitmask & OffPixels[*r0++]);
1862
1863 if (bitmask == 0xf0)
1864 bitmask = 0x0f;
1865 else
1866 {
1867 bitmask = 0xf0;
1868
1869 cptr ++;
1870 mptr ++;
1871 yptr ++;
1872 }
1873 }
1874 break;
1875
1876 case 8 :
1877 for (x = xsize; x > 0; x --, r0 += 3, r1 += 3)
1878 {
1879 if (r0[0] == r1[0])
1880 *cptr++ = r0[0];
1881 else
1882 *cptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize;
1883
1884 if (r0[1] == r1[1])
1885 *mptr++ = r0[1];
1886 else
1887 *mptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize;
1888
1889 if (r0[2] == r1[2])
1890 *yptr++ = r0[2];
1891 else
1892 *yptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize;
1893 }
1894 break;
1895 }
1896 break;
1897
1898 case CUPS_ORDER_PLANAR :
1899 switch (header->cupsBitsPerColor)
1900 {
1901 case 1 :
1902 bitmask = 0x80 >> (bitoffset & 7);
1903 dither = Floyd16xc16[y & 15];
1904
1905 switch (z)
1906 {
1907 case 0 :
1908 for (x = xsize; x > 0; x --, r0 += 3)
1909 {
1910 if (r0[0] > dither[x & 15])
1911 *ptr ^= bitmask;
1912
1913 if (bitmask > 1)
1914 bitmask >>= 1;
1915 else
1916 {
1917 bitmask = 0x80;
1918 ptr ++;
1919 }
1920 }
1921 break;
1922
1923 case 1 :
1924 for (x = xsize; x > 0; x --, r0 += 3)
1925 {
1926 if (r0[1] > dither[x & 15])
1927 *ptr ^= bitmask;
1928
1929 if (bitmask > 1)
1930 bitmask >>= 1;
1931 else
1932 {
1933 bitmask = 0x80;
1934 ptr ++;
1935 }
1936 }
1937 break;
1938
1939 case 2 :
1940 for (x = xsize; x > 0; x --, r0 += 3)
1941 {
1942 if (r0[2] > dither[x & 15])
1943 *ptr ^= bitmask;
1944
1945 if (bitmask > 1)
1946 bitmask >>= 1;
1947 else
1948 {
1949 bitmask = 0x80;
1950 ptr ++;
1951 }
1952 }
1953 break;
1954 }
1955 break;
1956
1957 case 2 :
1958 bitmask = 0x0 >> (bitoffset & 7);
1959 dither = Floyd8x8[y & 7];
1960 r0 += z;
1961
1962 for (x = xsize; x > 0; x --, r0 += 3)
1963 {
1964 if ((*r0 & 63) > dither[x & 7])
1965 *ptr ^= (bitmask & OnPixels[*r0]);
1966 else
1967 *ptr ^= (bitmask & OffPixels[*r0]);
1968
1969 if (bitmask > 3)
1970 bitmask >>= 2;
1971 else
1972 {
1973 bitmask = 0x0;
1974
1975 ptr ++;
1976 }
1977 }
1978 break;
1979
1980 case 4 :
1981 bitmask = 0xf0 >> (bitoffset & 7);
1982 dither = Floyd4x4[y & 3];
1983 r0 += z;
1984
1985 for (x = xsize; x > 0; x --, r0 += 3)
1986 {
1987 if ((*r0 & 15) > dither[x & 3])
1988 *ptr ^= (bitmask & OnPixels[*r0]);
1989 else
1990 *ptr ^= (bitmask & OffPixels[*r0]);
1991
1992 if (bitmask == 0xf0)
1993 bitmask = 0x0f;
1994 else
1995 {
1996 bitmask = 0xf0;
1997
1998 ptr ++;
1999 }
2000 }
2001 break;
2002
2003 case 8 :
2004 r0 += z;
2005 r1 += z;
2006
2007 for (x = xsize; x > 0; x --, r0 += 3, r1 += 3)
2008 {
2009 if (*r0 == *r1)
2010 *ptr++ = *r0;
2011 else
2012 *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize;
2013 }
2014 break;
2015 }
2016 break;
2017 }
2018 }
2019
2020
2021 /*
2022 * 'format_CMYK()' - Convert image data to CMYK.
2023 */
2024
2025 static void
2026 format_CMYK(cups_page_header2_t *header, /* I - Page header */
2027 unsigned char *row, /* IO - Bitmap data for device */
2028 int y, /* I - Current row */
2029 int z, /* I - Current plane */
2030 int xsize, /* I - Width of image data */
2031 int ysize, /* I - Height of image data */
2032 int yerr0, /* I - Top Y error */
2033 int yerr1, /* I - Bottom Y error */
2034 cups_ib_t *r0, /* I - Primary image data */
2035 cups_ib_t *r1) /* I - Image data for interpolation */
2036 {
2037 cups_ib_t *ptr, /* Pointer into row */
2038 *cptr, /* Pointer into cyan */
2039 *mptr, /* Pointer into magenta */
2040 *yptr, /* Pointer into yellow */
2041 *kptr, /* Pointer into black */
2042 bitmask; /* Current mask for pixel */
2043 int bitoffset; /* Current offset in line */
2044 int bandwidth; /* Width of a color band */
2045 int x, /* Current X coordinate on page */
2046 *dither; /* Pointer into dither array */
2047
2048
2049 switch (XPosition)
2050 {
2051 case -1 :
2052 bitoffset = 0;
2053 break;
2054 default :
2055 bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2);
2056 break;
2057 case 1 :
2058 bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize);
2059 break;
2060 }
2061
2062 ptr = row + bitoffset / 8;
2063 bandwidth = header->cupsBytesPerLine / 4;
2064
2065 switch (header->cupsColorOrder)
2066 {
2067 case CUPS_ORDER_CHUNKED :
2068 switch (header->cupsBitsPerColor)
2069 {
2070 case 1 :
2071 bitmask = 128 >> (bitoffset & 7);
2072 dither = Floyd16xc16[y & 15];
2073
2074 for (x = xsize ; x > 0; x --)
2075 {
2076 if (*r0++ > dither[x & 15])
2077 *ptr ^= bitmask;
2078 bitmask >>= 1;
2079
2080 if (*r0++ > dither[x & 15])
2081 *ptr ^= bitmask;
2082 bitmask >>= 1;
2083
2084 if (*r0++ > dither[x & 15])
2085 *ptr ^= bitmask;
2086 bitmask >>= 1;
2087
2088 if (*r0++ > dither[x & 15])
2089 *ptr ^= bitmask;
2090
2091 if (bitmask > 1)
2092 bitmask >>= 1;
2093 else
2094 {
2095 bitmask = 128;
2096 ptr ++;
2097 }
2098 }
2099 break;
2100
2101 case 2 :
2102 dither = Floyd8x8[y & 7];
2103
2104 for (x = xsize ; x > 0; x --, r0 += 4)
2105 {
2106 if ((r0[0] & 63) > dither[x & 7])
2107 *ptr ^= (0x0 & OnPixels[r0[0]]);
2108 else
2109 *ptr ^= (0x0 & OffPixels[r0[0]]);
2110
2111 if ((r0[1] & 63) > dither[x & 7])
2112 *ptr ^= (0x30 & OnPixels[r0[1]]);
2113 else
2114 *ptr ^= (0x30 & OffPixels[r0[1]]);
2115
2116 if ((r0[2] & 63) > dither[x & 7])
2117 *ptr ^= (0x0c & OnPixels[r0[2]]);
2118 else
2119 *ptr ^= (0x0c & OffPixels[r0[2]]);
2120
2121 if ((r0[3] & 63) > dither[x & 7])
2122 *ptr++ ^= (0x03 & OnPixels[r0[3]]);
2123 else
2124 *ptr++ ^= (0x03 & OffPixels[r0[3]]);
2125 }
2126 break;
2127
2128 case 4 :
2129 dither = Floyd4x4[y & 3];
2130
2131 for (x = xsize ; x > 0; x --, r0 += 4)
2132 {
2133 if ((r0[0] & 15) > dither[x & 3])
2134 *ptr ^= (0xf0 & OnPixels[r0[0]]);
2135 else
2136 *ptr ^= (0xf0 & OffPixels[r0[0]]);
2137
2138 if ((r0[1] & 15) > dither[x & 3])
2139 *ptr++ ^= (0x0f & OnPixels[r0[1]]);
2140 else
2141 *ptr++ ^= (0x0f & OffPixels[r0[1]]);
2142
2143 if ((r0[2] & 15) > dither[x & 3])
2144 *ptr ^= (0xf0 & OnPixels[r0[2]]);
2145 else
2146 *ptr ^= (0xf0 & OffPixels[r0[2]]);
2147
2148 if ((r0[3] & 15) > dither[x & 3])
2149 *ptr++ ^= (0x0f & OnPixels[r0[3]]);
2150 else
2151 *ptr++ ^= (0x0f & OffPixels[r0[3]]);
2152 }
2153 break;
2154
2155 case 8 :
2156 for (x = xsize * 4; x > 0; x --, r0 ++, r1 ++)
2157 if (*r0 == *r1)
2158 *ptr++ = *r0;
2159 else
2160 *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize;
2161 break;
2162 }
2163 break;
2164
2165 case CUPS_ORDER_BANDED :
2166 cptr = ptr;
2167 mptr = ptr + bandwidth;
2168 yptr = ptr + 2 * bandwidth;
2169 kptr = ptr + 3 * bandwidth;
2170
2171 switch (header->cupsBitsPerColor)
2172 {
2173 case 1 :
2174 bitmask = 0x80 >> (bitoffset & 7);
2175 dither = Floyd16xc16[y & 15];
2176
2177 for (x = xsize; x > 0; x --)
2178 {
2179 if (*r0++ > dither[x & 15])
2180 *cptr ^= bitmask;
2181 if (*r0++ > dither[x & 15])
2182 *mptr ^= bitmask;
2183 if (*r0++ > dither[x & 15])
2184 *yptr ^= bitmask;
2185 if (*r0++ > dither[x & 15])
2186 *kptr ^= bitmask;
2187
2188 if (bitmask > 1)
2189 bitmask >>= 1;
2190 else
2191 {
2192 bitmask = 0x80;
2193 cptr ++;
2194 mptr ++;
2195 yptr ++;
2196 kptr ++;
2197 }
2198 }
2199 break;
2200
2201 case 2 :
2202 bitmask = 0x0 >> (bitoffset & 7);
2203 dither = Floyd8x8[y & 7];
2204
2205 for (x = xsize; x > 0; x --)
2206 {
2207 if ((*r0 & 63) > dither[x & 7])
2208 *cptr ^= (bitmask & OnPixels[*r0++]);
2209 else
2210 *cptr ^= (bitmask & OffPixels[*r0++]);
2211
2212 if ((*r0 & 63) > dither[x & 7])
2213 *mptr ^= (bitmask & OnPixels[*r0++]);
2214 else
2215 *mptr ^= (bitmask & OffPixels[*r0++]);
2216
2217 if ((*r0 & 63) > dither[x & 7])
2218 *yptr ^= (bitmask & OnPixels[*r0++]);
2219 else
2220 *yptr ^= (bitmask & OffPixels[*r0++]);
2221
2222 if ((*r0 & 63) > dither[x & 7])
2223 *kptr ^= (bitmask & OnPixels[*r0++]);
2224 else
2225 *kptr ^= (bitmask & OffPixels[*r0++]);
2226
2227 if (bitmask > 3)
2228 bitmask >>= 2;
2229 else
2230 {
2231 bitmask = 0x0;
2232
2233 cptr ++;
2234 mptr ++;
2235 yptr ++;
2236 kptr ++;
2237 }
2238 }
2239 break;
2240
2241 case 4 :
2242 bitmask = 0xf0 >> (bitoffset & 7);
2243 dither = Floyd4x4[y & 3];
2244
2245 for (x = xsize; x > 0; x --)
2246 {
2247 if ((*r0 & 15) > dither[x & 3])
2248 *cptr ^= (bitmask & OnPixels[*r0++]);
2249 else
2250 *cptr ^= (bitmask & OffPixels[*r0++]);
2251
2252 if ((*r0 & 15) > dither[x & 3])
2253 *mptr ^= (bitmask & OnPixels[*r0++]);
2254 else
2255 *mptr ^= (bitmask & OffPixels[*r0++]);
2256
2257 if ((*r0 & 15) > dither[x & 3])
2258 *yptr ^= (bitmask & OnPixels[*r0++]);
2259 else
2260 *yptr ^= (bitmask & OffPixels[*r0++]);
2261
2262 if ((*r0 & 15) > dither[x & 3])
2263 *kptr ^= (bitmask & OnPixels[*r0++]);
2264 else
2265 *kptr ^= (bitmask & OffPixels[*r0++]);
2266
2267 if (bitmask == 0xf0)
2268 bitmask = 0x0f;
2269 else
2270 {
2271 bitmask = 0xf0;
2272
2273 cptr ++;
2274 mptr ++;
2275 yptr ++;
2276 kptr ++;
2277 }
2278 }
2279 break;
2280
2281 case 8 :
2282 for (x = xsize; x > 0; x --, r0 += 4, r1 += 4)
2283 {
2284 if (r0[0] == r1[0])
2285 *cptr++ = r0[0];
2286 else
2287 *cptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize;
2288
2289 if (r0[1] == r1[1])
2290 *mptr++ = r0[1];
2291 else
2292 *mptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize;
2293
2294 if (r0[2] == r1[2])
2295 *yptr++ = r0[2];
2296 else
2297 *yptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize;
2298
2299 if (r0[3] == r1[3])
2300 *kptr++ = r0[3];
2301 else
2302 *kptr++ = (r0[3] * yerr0 + r1[3] * yerr1) / ysize;
2303 }
2304 break;
2305 }
2306 break;
2307
2308 case CUPS_ORDER_PLANAR :
2309 switch (header->cupsBitsPerColor)
2310 {
2311 case 1 :
2312 bitmask = 0x80 >> (bitoffset & 7);
2313 dither = Floyd16xc16[y & 15];
2314 r0 += z;
2315
2316 for (x = xsize; x > 0; x --, r0 += 4)
2317 {
2318 if (*r0 > dither[x & 15])
2319 *ptr ^= bitmask;
2320
2321 if (bitmask > 1)
2322 bitmask >>= 1;
2323 else
2324 {
2325 bitmask = 0x80;
2326 ptr ++;
2327 }
2328 }
2329 break;
2330
2331 case 2 :
2332 bitmask = 0x0 >> (bitoffset & 7);
2333 dither = Floyd8x8[y & 7];
2334 r0 += z;
2335
2336 for (x = xsize; x > 0; x --, r0 += 4)
2337 {
2338 if ((*r0 & 63) > dither[x & 7])
2339 *ptr ^= (bitmask & OnPixels[*r0]);
2340 else
2341 *ptr ^= (bitmask & OffPixels[*r0]);
2342
2343 if (bitmask > 3)
2344 bitmask >>= 2;
2345 else
2346 {
2347 bitmask = 0x0;
2348
2349 ptr ++;
2350 }
2351 }
2352 break;
2353
2354 case 4 :
2355 bitmask = 0xf0 >> (bitoffset & 7);
2356 dither = Floyd4x4[y & 3];
2357 r0 += z;
2358
2359 for (x = xsize; x > 0; x --, r0 += 4)
2360 {
2361 if ((*r0 & 15) > dither[x & 3])
2362 *ptr ^= (bitmask & OnPixels[*r0]);
2363 else
2364 *ptr ^= (bitmask & OffPixels[*r0]);
2365
2366 if (bitmask == 0xf0)
2367 bitmask = 0x0f;
2368 else
2369 {
2370 bitmask = 0xf0;
2371
2372 ptr ++;
2373 }
2374 }
2375 break;
2376
2377 case 8 :
2378 r0 += z;
2379 r1 += z;
2380
2381 for (x = xsize; x > 0; x --, r0 += 4, r1 += 4)
2382 {
2383 if (*r0 == *r1)
2384 *ptr++ = *r0;
2385 else
2386 *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize;
2387 }
2388 break;
2389 }
2390 break;
2391 }
2392 }
2393
2394
2395 /*
2396 * 'format_K()' - Convert image data to black.
2397 */
2398
2399 static void
2400 format_K(cups_page_header2_t *header, /* I - Page header */
2401 unsigned char *row, /* IO - Bitmap data for device */
2402 int y, /* I - Current row */
2403 int z, /* I - Current plane */
2404 int xsize, /* I - Width of image data */
2405 int ysize, /* I - Height of image data */
2406 int yerr0, /* I - Top Y error */
2407 int yerr1, /* I - Bottom Y error */
2408 cups_ib_t *r0, /* I - Primary image data */
2409 cups_ib_t *r1) /* I - Image data for interpolation */
2410 {
2411 cups_ib_t *ptr, /* Pointer into row */
2412 bitmask; /* Current mask for pixel */
2413 int bitoffset; /* Current offset in line */
2414 int x, /* Current X coordinate on page */
2415 *dither; /* Pointer into dither array */
2416
2417
2418 (void)z;
2419
2420 switch (XPosition)
2421 {
2422 case -1 :
2423 bitoffset = 0;
2424 break;
2425 default :
2426 bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2);
2427 break;
2428 case 1 :
2429 bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize);
2430 break;
2431 }
2432
2433 ptr = row + bitoffset / 8;
2434
2435 switch (header->cupsBitsPerColor)
2436 {
2437 case 1 :
2438 bitmask = 0x80 >> (bitoffset & 7);
2439 dither = Floyd16xc16[y & 15];
2440
2441 for (x = xsize; x > 0; x --)
2442 {
2443 if (*r0++ > dither[x & 15])
2444 *ptr ^= bitmask;
2445
2446 if (bitmask > 1)
2447 bitmask >>= 1;
2448 else
2449 {
2450 bitmask = 0x80;
2451 ptr ++;
2452 }
2453 }
2454 break;
2455
2456 case 2 :
2457 bitmask = 0x0 >> (bitoffset & 7);
2458 dither = Floyd8x8[y & 7];
2459
2460 for (x = xsize; x > 0; x --)
2461 {
2462 if ((*r0 & 63) > dither[x & 7])
2463 *ptr ^= (bitmask & OnPixels[*r0++]);
2464 else
2465 *ptr ^= (bitmask & OffPixels[*r0++]);
2466
2467 if (bitmask > 3)
2468 bitmask >>= 2;
2469 else
2470 {
2471 bitmask = 0x0;
2472
2473 ptr ++;
2474 }
2475 }
2476 break;
2477
2478 case 4 :
2479 bitmask = 0xf0 >> (bitoffset & 7);
2480 dither = Floyd4x4[y & 3];
2481
2482 for (x = xsize; x > 0; x --)
2483 {
2484 if ((*r0 & 15) > dither[x & 3])
2485 *ptr ^= (bitmask & OnPixels[*r0++]);
2486 else
2487 *ptr ^= (bitmask & OffPixels[*r0++]);
2488
2489 if (bitmask == 0xf0)
2490 bitmask = 0x0f;
2491 else
2492 {
2493 bitmask = 0xf0;
2494
2495 ptr ++;
2496 }
2497 }
2498 break;
2499
2500 case 8 :
2501 for (x = xsize; x > 0; x --, r0 ++, r1 ++)
2502 {
2503 if (*r0 == *r1)
2504 *ptr++ = *r0;
2505 else
2506 *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize;
2507 }
2508 break;
2509 }
2510 }
2511
2512
2513 /*
2514 * 'format_KCMY()' - Convert image data to KCMY.
2515 */
2516
2517 static void
2518 format_KCMY(cups_page_header2_t *header, /* I - Page header */
2519 unsigned char *row, /* IO - Bitmap data for device */
2520 int y, /* I - Current row */
2521 int z, /* I - Current plane */
2522 int xsize, /* I - Width of image data */
2523 int ysize, /* I - Height of image data */
2524 int yerr0, /* I - Top Y error */
2525 int yerr1, /* I - Bottom Y error */
2526 cups_ib_t *r0, /* I - Primary image data */
2527 cups_ib_t *r1) /* I - Image data for interpolation */
2528 {
2529 cups_ib_t *ptr, /* Pointer into row */
2530 *cptr, /* Pointer into cyan */
2531 *mptr, /* Pointer into magenta */
2532 *yptr, /* Pointer into yellow */
2533 *kptr, /* Pointer into black */
2534 bitmask; /* Current mask for pixel */
2535 int bitoffset; /* Current offset in line */
2536 int bandwidth; /* Width of a color band */
2537 int x, /* Current X coordinate on page */
2538 *dither; /* Pointer into dither array */
2539
2540
2541 switch (XPosition)
2542 {
2543 case -1 :
2544 bitoffset = 0;
2545 break;
2546 default :
2547 bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2);
2548 break;
2549 case 1 :
2550 bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize);
2551 break;
2552 }
2553
2554 ptr = row + bitoffset / 8;
2555 bandwidth = header->cupsBytesPerLine / 4;
2556
2557 switch (header->cupsColorOrder)
2558 {
2559 case CUPS_ORDER_CHUNKED :
2560 switch (header->cupsBitsPerColor)
2561 {
2562 case 1 :
2563 bitmask = 128 >> (bitoffset & 7);
2564 dither = Floyd16xc16[y & 15];
2565
2566 for (x = xsize ; x > 0; x --, r0 += 4)
2567 {
2568 if (r0[3] > dither[x & 15])
2569 *ptr ^= bitmask;
2570 bitmask >>= 1;
2571
2572 if (r0[0] > dither[x & 15])
2573 *ptr ^= bitmask;
2574 bitmask >>= 1;
2575
2576 if (r0[1] > dither[x & 15])
2577 *ptr ^= bitmask;
2578 bitmask >>= 1;
2579
2580 if (r0[2] > dither[x & 15])
2581 *ptr ^= bitmask;
2582
2583 if (bitmask > 1)
2584 bitmask >>= 1;
2585 else
2586 {
2587 bitmask = 128;
2588 ptr ++;
2589 }
2590 }
2591 break;
2592
2593 case 2 :
2594 dither = Floyd8x8[y & 7];
2595
2596 for (x = xsize ; x > 0; x --, r0 += 4)
2597 {
2598 if ((r0[3] & 63) > dither[x & 7])
2599 *ptr ^= (0x0 & OnPixels[r0[3]]);
2600 else
2601 *ptr ^= (0x0 & OffPixels[r0[3]]);
2602
2603 if ((r0[0] & 63) > dither[x & 7])
2604 *ptr ^= (0x30 & OnPixels[r0[0]]);
2605 else
2606 *ptr ^= (0x30 & OffPixels[r0[0]]);
2607
2608 if ((r0[1] & 63) > dither[x & 7])
2609 *ptr ^= (0x0c & OnPixels[r0[1]]);
2610 else
2611 *ptr ^= (0x0c & OffPixels[r0[1]]);
2612
2613 if ((r0[2] & 63) > dither[x & 7])
2614 *ptr++ ^= (0x03 & OnPixels[r0[2]]);
2615 else
2616 *ptr++ ^= (0x03 & OffPixels[r0[2]]);
2617 }
2618 break;
2619
2620 case 4 :
2621 dither = Floyd4x4[y & 3];
2622
2623 for (x = xsize ; x > 0; x --, r0 += 4)
2624 {
2625 if ((r0[3] & 15) > dither[x & 3])
2626 *ptr ^= (0xf0 & OnPixels[r0[3]]);
2627 else
2628 *ptr ^= (0xf0 & OffPixels[r0[3]]);
2629
2630 if ((r0[0] & 15) > dither[x & 3])
2631 *ptr++ ^= (0x0f & OnPixels[r0[0]]);
2632 else
2633 *ptr++ ^= (0x0f & OffPixels[r0[0]]);
2634
2635 if ((r0[1] & 15) > dither[x & 3])
2636 *ptr ^= (0xf0 & OnPixels[r0[1]]);
2637 else
2638 *ptr ^= (0xf0 & OffPixels[r0[1]]);
2639
2640 if ((r0[2] & 15) > dither[x & 3])
2641 *ptr++ ^= (0x0f & OnPixels[r0[2]]);
2642 else
2643 *ptr++ ^= (0x0f & OffPixels[r0[2]]);
2644 }
2645 break;
2646
2647 case 8 :
2648 for (x = xsize; x > 0; x --, r0 += 4, r1 += 4)
2649 {
2650 if (r0[3] == r1[3])
2651 *ptr++ = r0[3];
2652 else
2653 *ptr++ = (r0[3] * yerr0 + r1[3] * yerr1) / ysize;
2654
2655 if (r0[0] == r1[0])
2656 *ptr++ = r0[0];
2657 else
2658 *ptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize;
2659
2660 if (r0[1] == r1[1])
2661 *ptr++ = r0[1];
2662 else
2663 *ptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize;
2664
2665 if (r0[2] == r1[2])
2666 *ptr++ = r0[2];
2667 else
2668 *ptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize;
2669 }
2670 break;
2671 }
2672 break;
2673
2674 case CUPS_ORDER_BANDED :
2675 kptr = ptr;
2676 cptr = ptr + bandwidth;
2677 mptr = ptr + 2 * bandwidth;
2678 yptr = ptr + 3 * bandwidth;
2679
2680 switch (header->cupsBitsPerColor)
2681 {
2682 case 1 :
2683 bitmask = 0x80 >> (bitoffset & 7);
2684 dither = Floyd16xc16[y & 15];
2685
2686 for (x = xsize; x > 0; x --)
2687 {
2688 if (*r0++ > dither[x & 15])
2689 *cptr ^= bitmask;
2690 if (*r0++ > dither[x & 15])
2691 *mptr ^= bitmask;
2692 if (*r0++ > dither[x & 15])
2693 *yptr ^= bitmask;
2694 if (*r0++ > dither[x & 15])
2695 *kptr ^= bitmask;
2696
2697 if (bitmask > 1)
2698 bitmask >>= 1;
2699 else
2700 {
2701 bitmask = 0x80;
2702 cptr ++;
2703 mptr ++;
2704 yptr ++;
2705 kptr ++;
2706 }
2707 }
2708 break;
2709
2710 case 2 :
2711 bitmask = 0x0 >> (bitoffset & 7);
2712 dither = Floyd8x8[y & 7];
2713
2714 for (x = xsize; x > 0; x --)
2715 {
2716 if ((*r0 & 63) > dither[x & 7])
2717 *cptr ^= (bitmask & OnPixels[*r0++]);
2718 else
2719 *cptr ^= (bitmask & OffPixels[*r0++]);
2720
2721 if ((*r0 & 63) > dither[x & 7])
2722 *mptr ^= (bitmask & OnPixels[*r0++]);
2723 else
2724 *mptr ^= (bitmask & OffPixels[*r0++]);
2725
2726 if ((*r0 & 63) > dither[x & 7])
2727 *yptr ^= (bitmask & OnPixels[*r0++]);
2728 else
2729 *yptr ^= (bitmask & OffPixels[*r0++]);
2730
2731 if ((*r0 & 63) > dither[x & 7])
2732 *kptr ^= (bitmask & OnPixels[*r0++]);
2733 else
2734 *kptr ^= (bitmask & OffPixels[*r0++]);
2735
2736 if (bitmask > 3)
2737 bitmask >>= 2;
2738 else
2739 {
2740 bitmask = 0x0;
2741
2742 cptr ++;
2743 mptr ++;
2744 yptr ++;
2745 kptr ++;
2746 }
2747 }
2748 break;
2749
2750 case 4 :
2751 bitmask = 0xf0 >> (bitoffset & 7);
2752 dither = Floyd4x4[y & 3];
2753
2754 for (x = xsize; x > 0; x --)
2755 {
2756 if ((*r0 & 15) > dither[x & 3])
2757 *cptr ^= (bitmask & OnPixels[*r0++]);
2758 else
2759 *cptr ^= (bitmask & OffPixels[*r0++]);
2760
2761 if ((*r0 & 15) > dither[x & 3])
2762 *mptr ^= (bitmask & OnPixels[*r0++]);
2763 else
2764 *mptr ^= (bitmask & OffPixels[*r0++]);
2765
2766 if ((*r0 & 15) > dither[x & 3])
2767 *yptr ^= (bitmask & OnPixels[*r0++]);
2768 else
2769 *yptr ^= (bitmask & OffPixels[*r0++]);
2770
2771 if ((*r0 & 15) > dither[x & 3])
2772 *kptr ^= (bitmask & OnPixels[*r0++]);
2773 else
2774 *kptr ^= (bitmask & OffPixels[*r0++]);
2775
2776 if (bitmask == 0xf0)
2777 bitmask = 0x0f;
2778 else
2779 {
2780 bitmask = 0xf0;
2781
2782 cptr ++;
2783 mptr ++;
2784 yptr ++;
2785 kptr ++;
2786 }
2787 }
2788 break;
2789
2790 case 8 :
2791 for (x = xsize; x > 0; x --, r0 += 4, r1 += 4)
2792 {
2793 if (r0[0] == r1[0])
2794 *cptr++ = r0[0];
2795 else
2796 *cptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize;
2797
2798 if (r0[1] == r1[1])
2799 *mptr++ = r0[1];
2800 else
2801 *mptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize;
2802
2803 if (r0[2] == r1[2])
2804 *yptr++ = r0[2];
2805 else
2806 *yptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize;
2807
2808 if (r0[3] == r1[3])
2809 *kptr++ = r0[3];
2810 else
2811 *kptr++ = (r0[3] * yerr0 + r1[3] * yerr1) / ysize;
2812 }
2813 break;
2814 }
2815 break;
2816
2817 case CUPS_ORDER_PLANAR :
2818 switch (header->cupsBitsPerColor)
2819 {
2820 case 1 :
2821 bitmask = 0x80 >> (bitoffset & 7);
2822 dither = Floyd16xc16[y & 15];
2823 if (z == 0)
2824 r0 += 3;
2825 else
2826 r0 += z - 1;
2827
2828 for (x = xsize; x > 0; x --, r0 += 4)
2829 {
2830 if (*r0 > dither[x & 15])
2831 *ptr ^= bitmask;
2832
2833 if (bitmask > 1)
2834 bitmask >>= 1;
2835 else
2836 {
2837 bitmask = 0x80;
2838 ptr ++;
2839 }
2840 }
2841 break;
2842
2843 case 2 :
2844 bitmask = 0x0 >> (bitoffset & 7);
2845 dither = Floyd8x8[y & 7];
2846 if (z == 0)
2847 r0 += 3;
2848 else
2849 r0 += z - 1;
2850
2851 for (x = xsize; x > 0; x --, r0 += 4)
2852 {
2853 if ((*r0 & 63) > dither[x & 7])
2854 *ptr ^= (bitmask & OnPixels[*r0]);
2855 else
2856 *ptr ^= (bitmask & OffPixels[*r0]);
2857
2858 if (bitmask > 3)
2859 bitmask >>= 2;
2860 else
2861 {
2862 bitmask = 0x0;
2863
2864 ptr ++;
2865 }
2866 }
2867 break;
2868
2869 case 4 :
2870 bitmask = 0xf0 >> (bitoffset & 7);
2871 dither = Floyd4x4[y & 3];
2872 if (z == 0)
2873 r0 += 3;
2874 else
2875 r0 += z - 1;
2876
2877 for (x = xsize; x > 0; x --, r0 += 4)
2878 {
2879 if ((*r0 & 15) > dither[x & 3])
2880 *ptr ^= (bitmask & OnPixels[*r0]);
2881 else
2882 *ptr ^= (bitmask & OffPixels[*r0]);
2883
2884 if (bitmask == 0xf0)
2885 bitmask = 0x0f;
2886 else
2887 {
2888 bitmask = 0xf0;
2889
2890 ptr ++;
2891 }
2892 }
2893 break;
2894
2895 case 8 :
2896 if (z == 0)
2897 {
2898 r0 += 3;
2899 r1 += 3;
2900 }
2901 else
2902 {
2903 r0 += z - 1;
2904 r1 += z - 1;
2905 }
2906
2907 for (x = xsize; x > 0; x --, r0 += 4, r1 += 4)
2908 {
2909 if (*r0 == *r1)
2910 *ptr++ = *r0;
2911 else
2912 *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize;
2913 }
2914 break;
2915 }
2916 break;
2917 }
2918 }
2919
2920
2921 /*
2922 * 'format_KCMYcm()' - Convert image data to KCMYcm.
2923 */
2924
2925 static void
2926 format_KCMYcm(cups_page_header2_t *header,/* I - Page header */
2927 unsigned char *row, /* IO - Bitmap data for device */
2928 int y, /* I - Current row */
2929 int z, /* I - Current plane */
2930 int xsize,/* I - Width of image data */
2931 int ysize,/* I - Height of image data */
2932 int yerr0,/* I - Top Y error */
2933 int yerr1,/* I - Bottom Y error */
2934 cups_ib_t *r0, /* I - Primary image data */
2935 cups_ib_t *r1) /* I - Image data for interpolation */
2936 {
2937 int pc, pm, py, pk; /* Cyan, magenta, yellow, and black values */
2938 cups_ib_t *ptr, /* Pointer into row */
2939 *cptr, /* Pointer into cyan */
2940 *mptr, /* Pointer into magenta */
2941 *yptr, /* Pointer into yellow */
2942 *kptr, /* Pointer into black */
2943 *lcptr, /* Pointer into light cyan */
2944 *lmptr, /* Pointer into light magenta */
2945 bitmask; /* Current mask for pixel */
2946 int bitoffset; /* Current offset in line */
2947 int bandwidth; /* Width of a color band */
2948 int x, /* Current X coordinate on page */
2949 *dither; /* Pointer into dither array */
2950
2951
2952 switch (XPosition)
2953 {
2954 case -1 :
2955 bitoffset = 0;
2956 break;
2957 default :
2958 bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2);
2959 break;
2960 case 1 :
2961 bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize);
2962 break;
2963 }
2964
2965 ptr = row + bitoffset / 8;
2966 if (header->cupsBitsPerColor == 1)
2967 bandwidth = header->cupsBytesPerLine / 6;
2968 else
2969 bandwidth = header->cupsBytesPerLine / 4;
2970
2971 switch (header->cupsColorOrder)
2972 {
2973 case CUPS_ORDER_CHUNKED :
2974 switch (header->cupsBitsPerColor)
2975 {
2976 case 1 :
2977 dither = Floyd16xc16[y & 15];
2978
2979 for (x = xsize ; x > 0; x --)
2980 {
2981 pc = *r0++ > dither[x & 15];
2982 pm = *r0++ > dither[x & 15];
2983 py = *r0++ > dither[x & 15];
2984 pk = *r0++ > dither[x & 15];
2985
2986 if (pk)
2987 *ptr++ ^= 32; /* Black */
2988 else if (pc && pm)
2989 *ptr++ ^= 17; /* Blue (cyan + light magenta) */
2990 else if (pc && py)
2991 *ptr++ ^= 6; /* Green (light cyan + yellow) */
2992 else if (pm && py)
2993 *ptr++ ^= 12; /* Red (magenta + yellow) */
2994 else if (pc)
2995 *ptr++ ^= 16;
2996 else if (pm)
2997 *ptr++ ^= 8;
2998 else if (py)
2999 *ptr++ ^= 4;
3000 }
3001 break;
3002
3003 case 8 :
3004 for (x = xsize; x > 0; x --, r0 += 4, r1 += 4)
3005 {
3006 if (r0[3] == r1[3])
3007 *ptr++ = r0[3];
3008 else
3009 *ptr++ = (r0[3] * yerr0 + r1[3] * yerr1) / ysize;
3010
3011 if (r0[0] == r1[0])
3012 *ptr++ = r0[0];
3013 else
3014 *ptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize;
3015
3016 if (r0[1] == r1[1])
3017 *ptr++ = r0[1];
3018 else
3019 *ptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize;
3020
3021 if (r0[2] == r1[2])
3022 *ptr++ = r0[2];
3023 else
3024 *ptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize;
3025 }
3026 break;
3027 }
3028 break;
3029
3030 case CUPS_ORDER_BANDED :
3031 kptr = ptr;
3032 cptr = ptr + bandwidth;
3033 mptr = ptr + 2 * bandwidth;
3034 yptr = ptr + 3 * bandwidth;
3035 lcptr = ptr + 4 * bandwidth;
3036 lmptr = ptr + 5 * bandwidth;
3037
3038 switch (header->cupsBitsPerColor)
3039 {
3040 case 1 :
3041 bitmask = 0x80 >> (bitoffset & 7);
3042 dither = Floyd16xc16[y & 15];
3043
3044 for (x = xsize; x > 0; x --)
3045 {
3046 pc = *r0++ > dither[x & 15];
3047 pm = *r0++ > dither[x & 15];
3048 py = *r0++ > dither[x & 15];
3049 pk = *r0++ > dither[x & 15];
3050
3051 if (pk)
3052 *kptr ^= bitmask; /* Black */
3053 else if (pc && pm)
3054 {
3055 *cptr ^= bitmask; /* Blue (cyan + light magenta) */
3056 *lmptr ^= bitmask;
3057 }
3058 else if (pc && py)
3059 {
3060 *lcptr ^= bitmask; /* Green (light cyan + yellow) */
3061 *yptr ^= bitmask;
3062 }
3063 else if (pm && py)
3064 {
3065 *mptr ^= bitmask; /* Red (magenta + yellow) */
3066 *yptr ^= bitmask;
3067 }
3068 else if (pc)
3069 *cptr ^= bitmask;
3070 else if (pm)
3071 *mptr ^= bitmask;
3072 else if (py)
3073 *yptr ^= bitmask;
3074
3075 if (bitmask > 1)
3076 bitmask >>= 1;
3077 else
3078 {
3079 bitmask = 0x80;
3080 cptr ++;
3081 mptr ++;
3082 yptr ++;
3083 kptr ++;
3084 lcptr ++;
3085 lmptr ++;
3086 }
3087 }
3088 break;
3089
3090 case 8 :
3091 for (x = xsize; x > 0; x --, r0 += 4, r1 += 4)
3092 {
3093 if (r0[0] == r1[0])
3094 *cptr++ = r0[0];
3095 else
3096 *cptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize;
3097
3098 if (r0[1] == r1[1])
3099 *mptr++ = r0[1];
3100 else
3101 *mptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize;
3102
3103 if (r0[2] == r1[2])
3104 *yptr++ = r0[2];
3105 else
3106 *yptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize;
3107
3108 if (r0[3] == r1[3])
3109 *kptr++ = r0[3];
3110 else
3111 *kptr++ = (r0[3] * yerr0 + r1[3] * yerr1) / ysize;
3112 }
3113 break;
3114 }
3115 break;
3116
3117 case CUPS_ORDER_PLANAR :
3118 switch (header->cupsBitsPerColor)
3119 {
3120 case 1 :
3121 bitmask = 0x80 >> (bitoffset & 7);
3122 dither = Floyd16xc16[y & 15];
3123
3124 switch (z)
3125 {
3126 case 0 :
3127 for (x = xsize; x > 0; x --, r0 += 4)
3128 {
3129 if (r0[3] > dither[x & 15])
3130 *ptr ^= bitmask;
3131
3132 if (bitmask > 1)
3133 bitmask >>= 1;
3134 else
3135 {
3136 bitmask = 0x80;
3137 ptr ++;
3138 }
3139 }
3140 break;
3141
3142 case 1 :
3143 for (x = xsize; x > 0; x --, r0 += 4)
3144 {
3145 if (r0[0] > dither[x & 15] &&
3146 r0[2] < dither[x & 15])
3147 *ptr ^= bitmask;
3148
3149 if (bitmask > 1)
3150 bitmask >>= 1;
3151 else
3152 {
3153 bitmask = 0x80;
3154 ptr ++;
3155 }
3156 }
3157 break;
3158
3159 case 2 :
3160 for (x = xsize; x > 0; x --, r0 += 4)
3161 {
3162 if (r0[1] > dither[x & 15] &&
3163 (r0[0] < dither[x & 15] ||
3164 r0[2] > dither[x & 15]))
3165 *ptr ^= bitmask;
3166
3167 if (bitmask > 1)
3168 bitmask >>= 1;
3169 else
3170 {
3171 bitmask = 0x80;
3172 ptr ++;
3173 }
3174 }
3175 break;
3176
3177 case 3 :
3178 for (x = xsize; x > 0; x --, r0 += 4)
3179 {
3180 if (r0[2] > dither[x & 15] &&
3181 (r0[0] < dither[x & 15] ||
3182 r0[1] < dither[x & 15]))
3183 *ptr ^= bitmask;
3184
3185 if (bitmask > 1)
3186 bitmask >>= 1;
3187 else
3188 {
3189 bitmask = 0x80;
3190 ptr ++;
3191 }
3192 }
3193 break;
3194
3195 case 4 :
3196 for (x = xsize; x > 0; x --, r0 += 4)
3197 {
3198 if (r0[0] > dither[x & 15] &&
3199 r0[2] > dither[x & 15])
3200 *ptr ^= bitmask;
3201
3202 if (bitmask > 1)
3203 bitmask >>= 1;
3204 else
3205 {
3206 bitmask = 0x80;
3207 ptr ++;
3208 }
3209 }
3210 break;
3211
3212 case 5 :
3213 for (x = xsize; x > 0; x --, r0 += 4)
3214 {
3215 if (r0[0] > dither[x & 15] &&
3216 r0[1] > dither[x & 15] &&
3217 r0[2] < dither[x & 15])
3218 *ptr ^= bitmask;
3219
3220 if (bitmask > 1)
3221 bitmask >>= 1;
3222 else
3223 {
3224 bitmask = 0x80;
3225 ptr ++;
3226 }
3227 }
3228 break;
3229 }
3230 break;
3231
3232 case 8 :
3233 if (z == 0)
3234 {
3235 r0 += 3;
3236 r1 += 3;
3237 }
3238 else
3239 {
3240 r0 += z - 1;
3241 r1 += z - 1;
3242 }
3243
3244 for (x = xsize; x > 0; x --, r0 += 4, r1 += 4)
3245 {
3246 if (*r0 == *r1)
3247 *ptr++ = *r0;
3248 else
3249 *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize;
3250 }
3251 break;
3252 }
3253 break;
3254 }
3255 }
3256
3257
3258 /*
3259 * 'format_RGBA()' - Convert image data to RGBA/RGBW.
3260 */
3261
3262 static void
3263 format_RGBA(cups_page_header2_t *header, /* I - Page header */
3264 unsigned char *row, /* IO - Bitmap data for device */
3265 int y, /* I - Current row */
3266 int z, /* I - Current plane */
3267 int xsize, /* I - Width of image data */
3268 int ysize, /* I - Height of image data */
3269 int yerr0, /* I - Top Y error */
3270 int yerr1, /* I - Bottom Y error */
3271 cups_ib_t *r0, /* I - Primary image data */
3272 cups_ib_t *r1) /* I - Image data for interpolation */
3273 {
3274 cups_ib_t *ptr, /* Pointer into row */
3275 *cptr, /* Pointer into cyan */
3276 *mptr, /* Pointer into magenta */
3277 *yptr, /* Pointer into yellow */
3278 bitmask; /* Current mask for pixel */
3279 int bitoffset; /* Current offset in line */
3280 int bandwidth; /* Width of a color band */
3281 int x, /* Current X coordinate on page */
3282 *dither; /* Pointer into dither array */
3283
3284
3285 switch (XPosition)
3286 {
3287 case -1 :
3288 bitoffset = 0;
3289 break;
3290 default :
3291 bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2);
3292 break;
3293 case 1 :
3294 bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize);
3295 break;
3296 }
3297
3298 ptr = row + bitoffset / 8;
3299 bandwidth = header->cupsBytesPerLine / 4;
3300
3301 switch (header->cupsColorOrder)
3302 {
3303 case CUPS_ORDER_CHUNKED :
3304 switch (header->cupsBitsPerColor)
3305 {
3306 case 1 :
3307 bitmask = 128 >> (bitoffset & 7);
3308 dither = Floyd16xc16[y & 15];
3309
3310 for (x = xsize ; x > 0; x --)
3311 {
3312 if (*r0++ > dither[x & 15])
3313 *ptr ^= bitmask;
3314 bitmask >>= 1;
3315
3316 if (*r0++ > dither[x & 15])
3317 *ptr ^= bitmask;
3318 bitmask >>= 1;
3319
3320 if (*r0++ > dither[x & 15])
3321 *ptr ^= bitmask;
3322
3323 if (bitmask > 2)
3324 {
3325 *ptr ^= 16;
3326 bitmask >>= 2;
3327 }
3328 else
3329 {
3330 bitmask = 128;
3331 *ptr++ ^= 1;
3332 }
3333 }
3334 break;
3335
3336 case 2 :
3337 dither = Floyd8x8[y & 7];
3338
3339 for (x = xsize ; x > 0; x --, r0 += 3)
3340 {
3341 if ((r0[0] & 63) > dither[x & 7])
3342 *ptr ^= (0x0 & OnPixels[r0[0]]);
3343 else
3344 *ptr ^= (0x0 & OffPixels[r0[0]]);
3345
3346 if ((r0[1] & 63) > dither[x & 7])
3347 *ptr ^= (0x30 & OnPixels[r0[1]]);
3348 else
3349 *ptr ^= (0x30 & OffPixels[r0[1]]);
3350
3351 if ((r0[2] & 63) > dither[x & 7])
3352 *ptr ^= (0x0c & OnPixels[r0[2]]);
3353 else
3354 *ptr ^= (0x0c & OffPixels[r0[2]]);
3355
3356 *ptr++ ^= 0x03;
3357 }
3358 break;
3359
3360 case 4 :
3361 dither = Floyd4x4[y & 3];
3362
3363 for (x = xsize ; x > 0; x --, r0 += 3)
3364 {
3365 if ((r0[0] & 15) > dither[x & 3])
3366 *ptr ^= (0xf0 & OnPixels[r0[0]]);
3367 else
3368 *ptr ^= (0xf0 & OffPixels[r0[0]]);
3369
3370 if ((r0[1] & 15) > dither[x & 3])
3371 *ptr++ ^= (0x0f & OnPixels[r0[1]]);
3372 else
3373 *ptr++ ^= (0x0f & OffPixels[r0[1]]);
3374
3375 if ((r0[2] & 15) > dither[x & 3])
3376 *ptr ^= (0xf0 & OnPixels[r0[2]]);
3377 else
3378 *ptr ^= (0xf0 & OffPixels[r0[2]]);
3379
3380 *ptr++ ^= 0x0f;
3381 }
3382 break;
3383
3384 case 8 :
3385 for (x = xsize; x > 0; x --, r0 += 3, r1 += 3)
3386 {
3387 if (r0[0] == r1[0])
3388 *ptr++ = r0[0];
3389 else
3390 *ptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize;
3391
3392 if (r0[1] == r1[1])
3393 *ptr++ = r0[1];
3394 else
3395 *ptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize;
3396
3397 if (r0[2] == r1[2])
3398 *ptr++ = r0[2];
3399 else
3400 *ptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize;
3401
3402 *ptr++ = 255;
3403 }
3404 break;
3405 }
3406 break;
3407
3408 case CUPS_ORDER_BANDED :
3409 cptr = ptr;
3410 mptr = ptr + bandwidth;
3411 yptr = ptr + 2 * bandwidth;
3412
3413 memset(ptr + 3 * bandwidth, 255, bandwidth);
3414
3415 switch (header->cupsBitsPerColor)
3416 {
3417 case 1 :
3418 bitmask = 0x80 >> (bitoffset & 7);
3419 dither = Floyd16xc16[y & 15];
3420
3421 for (x = xsize; x > 0; x --)
3422 {
3423 if (*r0++ > dither[x & 15])
3424 *cptr ^= bitmask;
3425 if (*r0++ > dither[x & 15])
3426 *mptr ^= bitmask;
3427 if (*r0++ > dither[x & 15])
3428 *yptr ^= bitmask;
3429
3430 if (bitmask > 1)
3431 bitmask >>= 1;
3432 else
3433 {
3434 bitmask = 0x80;
3435 cptr ++;
3436 mptr ++;
3437 yptr ++;
3438 }
3439 }
3440 break;
3441
3442 case 2 :
3443 bitmask = 0x0 >> (bitoffset & 7);
3444 dither = Floyd8x8[y & 7];
3445
3446 for (x = xsize; x > 0; x --)
3447 {
3448 if ((*r0 & 63) > dither[x & 7])
3449 *cptr ^= (bitmask & OnPixels[*r0++]);
3450 else
3451 *cptr ^= (bitmask & OffPixels[*r0++]);
3452
3453 if ((*r0 & 63) > dither[x & 7])
3454 *mptr ^= (bitmask & OnPixels[*r0++]);
3455 else
3456 *mptr ^= (bitmask & OffPixels[*r0++]);
3457
3458 if ((*r0 & 63) > dither[x & 7])
3459 *yptr ^= (bitmask & OnPixels[*r0++]);
3460 else
3461 *yptr ^= (bitmask & OffPixels[*r0++]);
3462
3463 if (bitmask > 3)
3464 bitmask >>= 2;
3465 else
3466 {
3467 bitmask = 0x0;
3468
3469 cptr ++;
3470 mptr ++;
3471 yptr ++;
3472 }
3473 }
3474 break;
3475
3476 case 4 :
3477 bitmask = 0xf0 >> (bitoffset & 7);
3478 dither = Floyd4x4[y & 3];
3479
3480 for (x = xsize; x > 0; x --)
3481 {
3482 if ((*r0 & 15) > dither[x & 3])
3483 *cptr ^= (bitmask & OnPixels[*r0++]);
3484 else
3485 *cptr ^= (bitmask & OffPixels[*r0++]);
3486
3487 if ((*r0 & 15) > dither[x & 3])
3488 *mptr ^= (bitmask & OnPixels[*r0++]);
3489 else
3490 *mptr ^= (bitmask & OffPixels[*r0++]);
3491
3492 if ((*r0 & 15) > dither[x & 3])
3493 *yptr ^= (bitmask & OnPixels[*r0++]);
3494 else
3495 *yptr ^= (bitmask & OffPixels[*r0++]);
3496
3497 if (bitmask == 0xf0)
3498 bitmask = 0x0f;
3499 else
3500 {
3501 bitmask = 0xf0;
3502
3503 cptr ++;
3504 mptr ++;
3505 yptr ++;
3506 }
3507 }
3508 break;
3509
3510 case 8 :
3511 for (x = xsize; x > 0; x --, r0 += 3, r1 += 3)
3512 {
3513 if (r0[0] == r1[0])
3514 *cptr++ = r0[0];
3515 else
3516 *cptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize;
3517
3518 if (r0[1] == r1[1])
3519 *mptr++ = r0[1];
3520 else
3521 *mptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize;
3522
3523 if (r0[2] == r1[2])
3524 *yptr++ = r0[2];
3525 else
3526 *yptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize;
3527 }
3528 break;
3529 }
3530 break;
3531
3532 case CUPS_ORDER_PLANAR :
3533 if (z == 3)
3534 {
3535 memset(row, 255, header->cupsBytesPerLine);
3536 break;
3537 }
3538
3539 switch (header->cupsBitsPerColor)
3540 {
3541 case 1 :
3542 bitmask = 0x80 >> (bitoffset & 7);
3543 dither = Floyd16xc16[y & 15];
3544
3545 switch (z)
3546 {
3547 case 0 :
3548 for (x = xsize; x > 0; x --, r0 += 3)
3549 {
3550 if (r0[0] > dither[x & 15])
3551 *ptr ^= bitmask;
3552
3553 if (bitmask > 1)
3554 bitmask >>= 1;
3555 else
3556 {
3557 bitmask = 0x80;
3558 ptr ++;
3559 }
3560 }
3561 break;
3562
3563 case 1 :
3564 for (x = xsize; x > 0; x --, r0 += 3)
3565 {
3566 if (r0[1] > dither[x & 15])
3567 *ptr ^= bitmask;
3568
3569 if (bitmask > 1)
3570 bitmask >>= 1;
3571 else
3572 {
3573 bitmask = 0x80;
3574 ptr ++;
3575 }
3576 }
3577 break;
3578
3579 case 2 :
3580 for (x = xsize; x > 0; x --, r0 += 3)
3581 {
3582 if (r0[2] > dither[x & 15])
3583 *ptr ^= bitmask;
3584
3585 if (bitmask > 1)
3586 bitmask >>= 1;
3587 else
3588 {
3589 bitmask = 0x80;
3590 ptr ++;
3591 }
3592 }
3593 break;
3594 }
3595 break;
3596
3597 case 2 :
3598 bitmask = 0x0 >> (bitoffset & 7);
3599 dither = Floyd8x8[y & 7];
3600 r0 += z;
3601
3602 for (x = xsize; x > 0; x --, r0 += 3)
3603 {
3604 if ((*r0 & 63) > dither[x & 7])
3605 *ptr ^= (bitmask & OnPixels[*r0]);
3606 else
3607 *ptr ^= (bitmask & OffPixels[*r0]);
3608
3609 if (bitmask > 3)
3610 bitmask >>= 2;
3611 else
3612 {
3613 bitmask = 0x0;
3614
3615 ptr ++;
3616 }
3617 }
3618 break;
3619
3620 case 4 :
3621 bitmask = 0xf0 >> (bitoffset & 7);
3622 dither = Floyd4x4[y & 3];
3623 r0 += z;
3624
3625 for (x = xsize; x > 0; x --, r0 += 3)
3626 {
3627 if ((*r0 & 15) > dither[x & 3])
3628 *ptr ^= (bitmask & OnPixels[*r0]);
3629 else
3630 *ptr ^= (bitmask & OffPixels[*r0]);
3631
3632 if (bitmask == 0xf0)
3633 bitmask = 0x0f;
3634 else
3635 {
3636 bitmask = 0xf0;
3637
3638 ptr ++;
3639 }
3640 }
3641 break;
3642
3643 case 8 :
3644 r0 += z;
3645 r1 += z;
3646
3647 for (x = xsize; x > 0; x --, r0 += 3, r1 += 3)
3648 {
3649 if (*r0 == *r1)
3650 *ptr++ = *r0;
3651 else
3652 *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize;
3653 }
3654 break;
3655 }
3656 break;
3657 }
3658 }
3659
3660
3661 /*
3662 * 'format_W()' - Convert image data to luminance.
3663 */
3664
3665 static void
3666 format_W(cups_page_header2_t *header, /* I - Page header */
3667 unsigned char *row, /* IO - Bitmap data for device */
3668 int y, /* I - Current row */
3669 int z, /* I - Current plane */
3670 int xsize, /* I - Width of image data */
3671 int ysize, /* I - Height of image data */
3672 int yerr0, /* I - Top Y error */
3673 int yerr1, /* I - Bottom Y error */
3674 cups_ib_t *r0, /* I - Primary image data */
3675 cups_ib_t *r1) /* I - Image data for interpolation */
3676 {
3677 cups_ib_t *ptr, /* Pointer into row */
3678 bitmask; /* Current mask for pixel */
3679 int bitoffset; /* Current offset in line */
3680 int x, /* Current X coordinate on page */
3681 *dither; /* Pointer into dither array */
3682
3683
3684 (void)z;
3685
3686 switch (XPosition)
3687 {
3688 case -1 :
3689 bitoffset = 0;
3690 break;
3691 default :
3692 bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2);
3693 break;
3694 case 1 :
3695 bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize);
3696 break;
3697 }
3698
3699 ptr = row + bitoffset / 8;
3700
3701 switch (header->cupsBitsPerColor)
3702 {
3703 case 1 :
3704 bitmask = 0x80 >> (bitoffset & 7);
3705 dither = Floyd16xc16[y & 15];
3706
3707 for (x = xsize; x > 0; x --)
3708 {
3709 if (*r0++ > dither[x & 15])
3710 *ptr ^= bitmask;
3711
3712 if (bitmask > 1)
3713 bitmask >>= 1;
3714 else
3715 {
3716 bitmask = 0x80;
3717 ptr ++;
3718 }
3719 }
3720 break;
3721
3722 case 2 :
3723 bitmask = 0x0 >> (bitoffset & 7);
3724 dither = Floyd8x8[y & 7];
3725
3726 for (x = xsize; x > 0; x --)
3727 {
3728 if ((*r0 & 63) > dither[x & 7])
3729 *ptr ^= (bitmask & OnPixels[*r0++]);
3730 else
3731 *ptr ^= (bitmask & OffPixels[*r0++]);
3732
3733 if (bitmask > 3)
3734 bitmask >>= 2;
3735 else
3736 {
3737 bitmask = 0x0;
3738
3739 ptr ++;
3740 }
3741 }
3742 break;
3743
3744 case 4 :
3745 bitmask = 0xf0 >> (bitoffset & 7);
3746 dither = Floyd4x4[y & 3];
3747
3748 for (x = xsize; x > 0; x --)
3749 {
3750 if ((*r0 & 15) > dither[x & 3])
3751 *ptr ^= (bitmask & OnPixels[*r0++]);
3752 else
3753 *ptr ^= (bitmask & OffPixels[*r0++]);
3754
3755 if (bitmask == 0xf0)
3756 bitmask = 0x0f;
3757 else
3758 {
3759 bitmask = 0xf0;
3760
3761 ptr ++;
3762 }
3763 }
3764 break;
3765
3766 case 8 :
3767 for (x = xsize; x > 0; x --, r0 ++, r1 ++)
3768 {
3769 if (*r0 == *r1)
3770 *ptr++ = *r0;
3771 else
3772 *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize;
3773 }
3774 break;
3775 }
3776 }
3777
3778
3779 /*
3780 * 'format_YMC()' - Convert image data to YMC.
3781 */
3782
3783 static void
3784 format_YMC(cups_page_header2_t *header, /* I - Page header */
3785 unsigned char *row, /* IO - Bitmap data for device */
3786 int y, /* I - Current row */
3787 int z, /* I - Current plane */
3788 int xsize, /* I - Width of image data */
3789 int ysize, /* I - Height of image data */
3790 int yerr0, /* I - Top Y error */
3791 int yerr1, /* I - Bottom Y error */
3792 cups_ib_t *r0, /* I - Primary image data */
3793 cups_ib_t *r1) /* I - Image data for interpolation */
3794 {
3795 cups_ib_t *ptr, /* Pointer into row */
3796 *cptr, /* Pointer into cyan */
3797 *mptr, /* Pointer into magenta */
3798 *yptr, /* Pointer into yellow */
3799 bitmask; /* Current mask for pixel */
3800 int bitoffset; /* Current offset in line */
3801 int bandwidth; /* Width of a color band */
3802 int x, /* Current X coordinate on page */
3803 *dither; /* Pointer into dither array */
3804
3805
3806 switch (XPosition)
3807 {
3808 case -1 :
3809 bitoffset = 0;
3810 break;
3811 default :
3812 bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2);
3813 break;
3814 case 1 :
3815 bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize);
3816 break;
3817 }
3818
3819 ptr = row + bitoffset / 8;
3820 bandwidth = header->cupsBytesPerLine / 3;
3821
3822 switch (header->cupsColorOrder)
3823 {
3824 case CUPS_ORDER_CHUNKED :
3825 switch (header->cupsBitsPerColor)
3826 {
3827 case 1 :
3828 bitmask = 64 >> (bitoffset & 7);
3829 dither = Floyd16xc16[y & 15];
3830
3831 for (x = xsize ; x > 0; x --, r0 += 3)
3832 {
3833 if (r0[2] > dither[x & 15])
3834 *ptr ^= bitmask;
3835 bitmask >>= 1;
3836
3837 if (r0[1] > dither[x & 15])
3838 *ptr ^= bitmask;
3839 bitmask >>= 1;
3840
3841 if (r0[0] > dither[x & 15])
3842 *ptr ^= bitmask;
3843
3844 if (bitmask > 1)
3845 bitmask >>= 2;
3846 else
3847 {
3848 bitmask = 64;
3849 ptr ++;
3850 }
3851 }
3852 break;
3853
3854 case 2 :
3855 dither = Floyd8x8[y & 7];
3856
3857 for (x = xsize ; x > 0; x --, r0 += 3)
3858 {
3859 if ((r0[2] & 63) > dither[x & 7])
3860 *ptr ^= (0x30 & OnPixels[r0[2]]);
3861 else
3862 *ptr ^= (0x30 & OffPixels[r0[2]]);
3863
3864 if ((r0[1] & 63) > dither[x & 7])
3865 *ptr ^= (0x0c & OnPixels[r0[1]]);
3866 else
3867 *ptr ^= (0x0c & OffPixels[r0[1]]);
3868
3869 if ((r0[0] & 63) > dither[x & 7])
3870 *ptr++ ^= (0x03 & OnPixels[r0[0]]);
3871 else
3872 *ptr++ ^= (0x03 & OffPixels[r0[0]]);
3873 }
3874 break;
3875
3876 case 4 :
3877 dither = Floyd4x4[y & 3];
3878
3879 for (x = xsize ; x > 0; x --, r0 += 3)
3880 {
3881 if ((r0[2] & 15) > dither[x & 3])
3882 *ptr++ ^= (0x0f & OnPixels[r0[2]]);
3883 else
3884 *ptr++ ^= (0x0f & OffPixels[r0[2]]);
3885
3886 if ((r0[1] & 15) > dither[x & 3])
3887 *ptr ^= (0xf0 & OnPixels[r0[1]]);
3888 else
3889 *ptr ^= (0xf0 & OffPixels[r0[1]]);
3890
3891 if ((r0[0] & 15) > dither[x & 3])
3892 *ptr++ ^= (0x0f & OnPixels[r0[0]]);
3893 else
3894 *ptr++ ^= (0x0f & OffPixels[r0[0]]);
3895 }
3896 break;
3897
3898 case 8 :
3899 for (x = xsize; x > 0; x --, r0 += 3, r1 += 3)
3900 {
3901 if (r0[2] == r1[2])
3902 *ptr++ = r0[2];
3903 else
3904 *ptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize;
3905
3906 if (r0[1] == r1[1])
3907 *ptr++ = r0[1];
3908 else
3909 *ptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize;
3910
3911 if (r0[0] == r1[0])
3912 *ptr++ = r0[0];
3913 else
3914 *ptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize;
3915 }
3916 break;
3917 }
3918 break;
3919
3920 case CUPS_ORDER_BANDED :
3921 yptr = ptr;
3922 mptr = ptr + bandwidth;
3923 cptr = ptr + 2 * bandwidth;
3924
3925 switch (header->cupsBitsPerColor)
3926 {
3927 case 1 :
3928 bitmask = 0x80 >> (bitoffset & 7);
3929 dither = Floyd16xc16[y & 15];
3930
3931 for (x = xsize; x > 0; x --)
3932 {
3933 if (*r0++ > dither[x & 15])
3934 *cptr ^= bitmask;
3935 if (*r0++ > dither[x & 15])
3936 *mptr ^= bitmask;
3937 if (*r0++ > dither[x & 15])
3938 *yptr ^= bitmask;
3939
3940 if (bitmask > 1)
3941 bitmask >>= 1;
3942 else
3943 {
3944 bitmask = 0x80;
3945 cptr ++;
3946 mptr ++;
3947 yptr ++;
3948 }
3949 }
3950 break;
3951
3952 case 2 :
3953 bitmask = 0x0 >> (bitoffset & 7);
3954 dither = Floyd8x8[y & 7];
3955
3956 for (x = xsize; x > 0; x --)
3957 {
3958 if ((*r0 & 63) > dither[x & 7])
3959 *cptr ^= (bitmask & OnPixels[*r0++]);
3960 else
3961 *cptr ^= (bitmask & OffPixels[*r0++]);
3962
3963 if ((*r0 & 63) > dither[x & 7])
3964 *mptr ^= (bitmask & OnPixels[*r0++]);
3965 else
3966 *mptr ^= (bitmask & OffPixels[*r0++]);
3967
3968 if ((*r0 & 63) > dither[x & 7])
3969 *yptr ^= (bitmask & OnPixels[*r0++]);
3970 else
3971 *yptr ^= (bitmask & OffPixels[*r0++]);
3972
3973 if (bitmask > 3)
3974 bitmask >>= 2;
3975 else
3976 {
3977 bitmask = 0x0;
3978
3979 cptr ++;
3980 mptr ++;
3981 yptr ++;
3982 }
3983 }
3984 break;
3985
3986 case 4 :
3987 bitmask = 0xf0 >> (bitoffset & 7);
3988 dither = Floyd4x4[y & 3];
3989
3990 for (x = xsize; x > 0; x --)
3991 {
3992 if ((*r0 & 15) > dither[x & 3])
3993 *cptr ^= (bitmask & OnPixels[*r0++]);
3994 else
3995 *cptr ^= (bitmask & OffPixels[*r0++]);
3996
3997 if ((*r0 & 15) > dither[x & 3])
3998 *mptr ^= (bitmask & OnPixels[*r0++]);
3999 else
4000 *mptr ^= (bitmask & OffPixels[*r0++]);
4001
4002 if ((*r0 & 15) > dither[x & 3])
4003 *yptr ^= (bitmask & OnPixels[*r0++]);
4004 else
4005 *yptr ^= (bitmask & OffPixels[*r0++]);
4006
4007 if (bitmask == 0xf0)
4008 bitmask = 0x0f;
4009 else
4010 {
4011 bitmask = 0xf0;
4012
4013 cptr ++;
4014 mptr ++;
4015 yptr ++;
4016 }
4017 }
4018 break;
4019
4020 case 8 :
4021 for (x = xsize; x > 0; x --, r0 += 3, r1 += 3)
4022 {
4023 if (r0[0] == r1[0])
4024 *cptr++ = r0[0];
4025 else
4026 *cptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize;
4027
4028 if (r0[1] == r1[1])
4029 *mptr++ = r0[1];
4030 else
4031 *mptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize;
4032
4033 if (r0[2] == r1[2])
4034 *yptr++ = r0[2];
4035 else
4036 *yptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize;
4037 }
4038 break;
4039 }
4040 break;
4041
4042 case CUPS_ORDER_PLANAR :
4043 switch (header->cupsBitsPerColor)
4044 {
4045 case 1 :
4046 bitmask = 0x80 >> (bitoffset & 7);
4047 dither = Floyd16xc16[y & 15];
4048
4049 switch (z)
4050 {
4051 case 2 :
4052 for (x = xsize; x > 0; x --, r0 += 3)
4053 {
4054 if (r0[0] > dither[x & 15])
4055 *ptr ^= bitmask;
4056
4057 if (bitmask > 1)
4058 bitmask >>= 1;
4059 else
4060 {
4061 bitmask = 0x80;
4062 ptr ++;
4063 }
4064 }
4065 break;
4066
4067 case 1 :
4068 for (x = xsize; x > 0; x --, r0 += 3)
4069 {
4070 if (r0[1] > dither[x & 15])
4071 *ptr ^= bitmask;
4072
4073 if (bitmask > 1)
4074 bitmask >>= 1;
4075 else
4076 {
4077 bitmask = 0x80;
4078 ptr ++;
4079 }
4080 }
4081 break;
4082
4083 case 0 :
4084 for (x = xsize; x > 0; x --, r0 += 3)
4085 {
4086 if (r0[2] > dither[x & 15])
4087 *ptr ^= bitmask;
4088
4089 if (bitmask > 1)
4090 bitmask >>= 1;
4091 else
4092 {
4093 bitmask = 0x80;
4094 ptr ++;
4095 }
4096 }
4097 break;
4098 }
4099 break;
4100
4101 case 2 :
4102 bitmask = 0x0 >> (bitoffset & 7);
4103 dither = Floyd8x8[y & 7];
4104 z = 2 - z;
4105 r0 += z;
4106
4107 for (x = xsize; x > 0; x --, r0 += 3)
4108 {
4109 if ((*r0 & 63) > dither[x & 7])
4110 *ptr ^= (bitmask & OnPixels[*r0]);
4111 else
4112 *ptr ^= (bitmask & OffPixels[*r0]);
4113
4114 if (bitmask > 3)
4115 bitmask >>= 2;
4116 else
4117 {
4118 bitmask = 0x0;
4119
4120 ptr ++;
4121 }
4122 }
4123 break;
4124
4125 case 4 :
4126 bitmask = 0xf0 >> (bitoffset & 7);
4127 dither = Floyd4x4[y & 3];
4128 z = 2 - z;
4129 r0 += z;
4130
4131 for (x = xsize; x > 0; x --, r0 += 3)
4132 {
4133 if ((*r0 & 15) > dither[x & 3])
4134 *ptr ^= (bitmask & OnPixels[*r0]);
4135 else
4136 *ptr ^= (bitmask & OffPixels[*r0]);
4137
4138 if (bitmask == 0xf0)
4139 bitmask = 0x0f;
4140 else
4141 {
4142 bitmask = 0xf0;
4143
4144 ptr ++;
4145 }
4146 }
4147 break;
4148
4149 case 8 :
4150 z = 2 - z;
4151 r0 += z;
4152 r1 += z;
4153
4154 for (x = xsize; x > 0; x --, r0 += 3, r1 += 3)
4155 {
4156 if (*r0 == *r1)
4157 *ptr++ = *r0;
4158 else
4159 *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize;
4160 }
4161 break;
4162 }
4163 break;
4164 }
4165 }
4166
4167
4168 /*
4169 * 'format_YMCK()' - Convert image data to YMCK.
4170 */
4171
4172 static void
4173 format_YMCK(cups_page_header2_t *header, /* I - Page header */
4174 unsigned char *row, /* IO - Bitmap data for device */
4175 int y, /* I - Current row */
4176 int z, /* I - Current plane */
4177 int xsize, /* I - Width of image data */
4178 int ysize, /* I - Height of image data */
4179 int yerr0, /* I - Top Y error */
4180 int yerr1, /* I - Bottom Y error */
4181 cups_ib_t *r0, /* I - Primary image data */
4182 cups_ib_t *r1) /* I - Image data for interpolation */
4183 {
4184 cups_ib_t *ptr, /* Pointer into row */
4185 *cptr, /* Pointer into cyan */
4186 *mptr, /* Pointer into magenta */
4187 *yptr, /* Pointer into yellow */
4188 *kptr, /* Pointer into black */
4189 bitmask; /* Current mask for pixel */
4190 int bitoffset; /* Current offset in line */
4191 int bandwidth; /* Width of a color band */
4192 int x, /* Current X coordinate on page */
4193 *dither; /* Pointer into dither array */
4194
4195
4196 switch (XPosition)
4197 {
4198 case -1 :
4199 bitoffset = 0;
4200 break;
4201 default :
4202 bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2);
4203 break;
4204 case 1 :
4205 bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize);
4206 break;
4207 }
4208
4209 ptr = row + bitoffset / 8;
4210 bandwidth = header->cupsBytesPerLine / 4;
4211
4212 switch (header->cupsColorOrder)
4213 {
4214 case CUPS_ORDER_CHUNKED :
4215 switch (header->cupsBitsPerColor)
4216 {
4217 case 1 :
4218 bitmask = 128 >> (bitoffset & 7);
4219 dither = Floyd16xc16[y & 15];
4220
4221 for (x = xsize ; x > 0; x --, r0 += 4)
4222 {
4223 if (r0[2] > dither[x & 15])
4224 *ptr ^= bitmask;
4225 bitmask >>= 1;
4226
4227 if (r0[1] > dither[x & 15])
4228 *ptr ^= bitmask;
4229 bitmask >>= 1;
4230
4231 if (r0[0] > dither[x & 15])
4232 *ptr ^= bitmask;
4233 bitmask >>= 1;
4234
4235 if (r0[3] > dither[x & 15])
4236 *ptr ^= bitmask;
4237
4238 if (bitmask > 1)
4239 bitmask >>= 1;
4240 else
4241 {
4242 bitmask = 128;
4243
4244 ptr ++;
4245 }
4246 }
4247 break;
4248
4249 case 2 :
4250 dither = Floyd8x8[y & 7];
4251
4252 for (x = xsize ; x > 0; x --, r0 += 4)
4253 {
4254 if ((r0[2] & 63) > dither[x & 7])
4255 *ptr ^= (0x0 & OnPixels[r0[2]]);
4256 else
4257 *ptr ^= (0x0 & OffPixels[r0[2]]);
4258
4259 if ((r0[1] & 63) > dither[x & 7])
4260 *ptr ^= (0x30 & OnPixels[r0[1]]);
4261 else
4262 *ptr ^= (0x30 & OffPixels[r0[1]]);
4263
4264 if ((r0[0] & 63) > dither[x & 7])
4265 *ptr ^= (0x0c & OnPixels[r0[0]]);
4266 else
4267 *ptr ^= (0x0c & OffPixels[r0[0]]);
4268
4269 if ((r0[3] & 63) > dither[x & 7])
4270 *ptr++ ^= (0x03 & OnPixels[r0[3]]);
4271 else
4272 *ptr++ ^= (0x03 & OffPixels[r0[3]]);
4273 }
4274 break;
4275
4276 case 4 :
4277 dither = Floyd4x4[y & 3];
4278
4279 for (x = xsize ; x > 0; x --, r0 += 4)
4280 {
4281 if ((r0[2] & 15) > dither[x & 3])
4282 *ptr ^= (0xf0 & OnPixels[r0[2]]);
4283 else
4284 *ptr ^= (0xf0 & OffPixels[r0[2]]);
4285
4286 if ((r0[1] & 15) > dither[x & 3])
4287 *ptr++ ^= (0x0f & OnPixels[r0[1]]);
4288 else
4289 *ptr++ ^= (0x0f & OffPixels[r0[1]]);
4290
4291 if ((r0[0] & 15) > dither[x & 3])
4292 *ptr ^= (0xf0 & OnPixels[r0[0]]);
4293 else
4294 *ptr ^= (0xf0 & OffPixels[r0[0]]);
4295
4296 if ((r0[3] & 15) > dither[x & 3])
4297 *ptr++ ^= (0x0f & OnPixels[r0[3]]);
4298 else
4299 *ptr++ ^= (0x0f & OffPixels[r0[3]]);
4300 }
4301 break;
4302
4303 case 8 :
4304 for (x = xsize; x > 0; x --, r0 += 4, r1 += 4)
4305 {
4306 if (r0[2] == r1[2])
4307 *ptr++ = r0[2];
4308 else
4309 *ptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize;
4310
4311 if (r0[1] == r1[1])
4312 *ptr++ = r0[1];
4313 else
4314 *ptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize;
4315
4316 if (r0[0] == r1[0])
4317 *ptr++ = r0[0];
4318 else
4319 *ptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize;
4320
4321 if (r0[3] == r1[3])
4322 *ptr++ = r0[3];
4323 else
4324 *ptr++ = (r0[3] * yerr0 + r1[3] * yerr1) / ysize;
4325 }
4326 break;
4327 }
4328 break;
4329
4330 case CUPS_ORDER_BANDED :
4331 yptr = ptr;
4332 mptr = ptr + bandwidth;
4333 cptr = ptr + 2 * bandwidth;
4334 kptr = ptr + 3 * bandwidth;
4335
4336 switch (header->cupsBitsPerColor)
4337 {
4338 case 1 :
4339 bitmask = 0x80 >> (bitoffset & 7);
4340 dither = Floyd16xc16[y & 15];
4341
4342 for (x = xsize; x > 0; x --)
4343 {
4344 if (*r0++ > dither[x & 15])
4345 *cptr ^= bitmask;
4346 if (*r0++ > dither[x & 15])
4347 *mptr ^= bitmask;
4348 if (*r0++ > dither[x & 15])
4349 *yptr ^= bitmask;
4350 if (*r0++ > dither[x & 15])
4351 *kptr ^= bitmask;
4352
4353 if (bitmask > 1)
4354 bitmask >>= 1;
4355 else
4356 {
4357 bitmask = 0x80;
4358
4359 cptr ++;
4360 mptr ++;
4361 yptr ++;
4362 kptr ++;
4363 }
4364 }
4365 break;
4366
4367 case 2 :
4368 bitmask = 0x0 >> (bitoffset & 7);
4369 dither = Floyd8x8[y & 7];
4370
4371 for (x = xsize; x > 0; x --)
4372 {
4373 if ((*r0 & 63) > dither[x & 7])
4374 *cptr ^= (bitmask & OnPixels[*r0++]);
4375 else
4376 *cptr ^= (bitmask & OffPixels[*r0++]);
4377
4378 if ((*r0 & 63) > dither[x & 7])
4379 *mptr ^= (bitmask & OnPixels[*r0++]);
4380 else
4381 *mptr ^= (bitmask & OffPixels[*r0++]);
4382
4383 if ((*r0 & 63) > dither[x & 7])
4384 *yptr ^= (bitmask & OnPixels[*r0++]);
4385 else
4386 *yptr ^= (bitmask & OffPixels[*r0++]);
4387
4388 if ((*r0 & 63) > dither[x & 7])
4389 *kptr ^= (bitmask & OnPixels[*r0++]);
4390 else
4391 *kptr ^= (bitmask & OffPixels[*r0++]);
4392
4393 if (bitmask > 3)
4394 bitmask >>= 2;
4395 else
4396 {
4397 bitmask = 0x0;
4398
4399 cptr ++;
4400 mptr ++;
4401 yptr ++;
4402 kptr ++;
4403 }
4404 }
4405 break;
4406
4407 case 4 :
4408 bitmask = 0xf0 >> (bitoffset & 7);
4409 dither = Floyd4x4[y & 3];
4410
4411 for (x = xsize; x > 0; x --)
4412 {
4413 if ((*r0 & 15) > dither[x & 3])
4414 *cptr ^= (bitmask & OnPixels[*r0++]);
4415 else
4416 *cptr ^= (bitmask & OffPixels[*r0++]);
4417
4418 if ((*r0 & 15) > dither[x & 3])
4419 *mptr ^= (bitmask & OnPixels[*r0++]);
4420 else
4421 *mptr ^= (bitmask & OffPixels[*r0++]);
4422
4423 if ((*r0 & 15) > dither[x & 3])
4424 *yptr ^= (bitmask & OnPixels[*r0++]);
4425 else
4426 *yptr ^= (bitmask & OffPixels[*r0++]);
4427
4428 if ((*r0 & 15) > dither[x & 3])
4429 *kptr ^= (bitmask & OnPixels[*r0++]);
4430 else
4431 *kptr ^= (bitmask & OffPixels[*r0++]);
4432
4433 if (bitmask == 0xf0)
4434 bitmask = 0x0f;
4435 else
4436 {
4437 bitmask = 0xf0;
4438
4439 cptr ++;
4440 mptr ++;
4441 yptr ++;
4442 kptr ++;
4443 }
4444 }
4445 break;
4446
4447 case 8 :
4448 for (x = xsize; x > 0; x --, r0 += 4, r1 += 4)
4449 {
4450 if (r0[0] == r1[0])
4451 *cptr++ = r0[0];
4452 else
4453 *cptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize;
4454
4455 if (r0[1] == r1[1])
4456 *mptr++ = r0[1];
4457 else
4458 *mptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize;
4459
4460 if (r0[2] == r1[2])
4461 *yptr++ = r0[2];
4462 else
4463 *yptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize;
4464
4465 if (r0[3] == r1[3])
4466 *kptr++ = r0[3];
4467 else
4468 *kptr++ = (r0[3] * yerr0 + r1[3] * yerr1) / ysize;
4469 }
4470 break;
4471 }
4472 break;
4473
4474 case CUPS_ORDER_PLANAR :
4475 switch (header->cupsBitsPerColor)
4476 {
4477 case 1 :
4478 bitmask = 0x80 >> (bitoffset & 7);
4479 dither = Floyd16xc16[y & 15];
4480
4481 if (z < 3)
4482 r0 += 2 - z;
4483 else
4484 r0 += z;
4485
4486 for (x = xsize; x > 0; x --, r0 += 4)
4487 {
4488 if (*r0 > dither[x & 15])
4489 *ptr ^= bitmask;
4490
4491 if (bitmask > 1)
4492 bitmask >>= 1;
4493 else
4494 {
4495 bitmask = 0x80;
4496 ptr ++;
4497 }
4498 }
4499 break;
4500
4501 case 2 :
4502 bitmask = 0x0 >> (bitoffset & 7);
4503 dither = Floyd8x8[y & 7];
4504 if (z == 3)
4505 r0 += 3;
4506 else
4507 r0 += 2 - z;
4508
4509 for (x = xsize; x > 0; x --, r0 += 4)
4510 {
4511 if ((*r0 & 63) > dither[x & 7])
4512 *ptr ^= (bitmask & OnPixels[*r0]);
4513 else
4514 *ptr ^= (bitmask & OffPixels[*r0]);
4515
4516 if (bitmask > 3)
4517 bitmask >>= 2;
4518 else
4519 {
4520 bitmask = 0x0;
4521
4522 ptr ++;
4523 }
4524 }
4525 break;
4526
4527 case 4 :
4528 bitmask = 0xf0 >> (bitoffset & 7);
4529 dither = Floyd4x4[y & 3];
4530 if (z == 3)
4531 r0 += 3;
4532 else
4533 r0 += 2 - z;
4534
4535 for (x = xsize; x > 0; x --, r0 += 4)
4536 {
4537 if ((*r0 & 15) > dither[x & 3])
4538 *ptr ^= (bitmask & OnPixels[*r0]);
4539 else
4540 *ptr ^= (bitmask & OffPixels[*r0]);
4541
4542 if (bitmask == 0xf0)
4543 bitmask = 0x0f;
4544 else
4545 {
4546 bitmask = 0xf0;
4547
4548 ptr ++;
4549 }
4550 }
4551 break;
4552
4553 case 8 :
4554 if (z == 3)
4555 {
4556 r0 += 3;
4557 r1 += 3;
4558 }
4559 else
4560 {
4561 r0 += 2 - z;
4562 r1 += 2 - z;
4563 }
4564
4565 for (x = xsize; x > 0; x --, r0 += 4, r1 += 4)
4566 {
4567 if (*r0 == *r1)
4568 *ptr++ = *r0;
4569 else
4570 *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize;
4571 }
4572 break;
4573 }
4574 break;
4575 }
4576 }
4577
4578
4579 /*
4580 * 'make_lut()' - Make a lookup table given gamma and brightness values.
4581 */
4582
4583 static void
4584 make_lut(cups_ib_t *lut, /* I - Lookup table */
4585 int colorspace, /* I - Colorspace */
4586 float g, /* I - Image gamma */
4587 float b) /* I - Image brightness */
4588 {
4589 int i; /* Looping var */
4590 int v; /* Current value */
4591
4592
4593 g = 1.0 / g;
4594 b = 1.0 / b;
4595
4596 for (i = 0; i < 256; i ++)
4597 {
4598 if (colorspace < 0)
4599 v = 255.0 * b * (1.0 - pow(1.0 - (float)i / 255.0, g)) + 0.5;
4600 else
4601 v = 255.0 * (1.0 - b * (1.0 - pow((float)i / 255.0, g))) + 0.5;
4602
4603 if (v < 0)
4604 *lut++ = 0;
4605 else if (v > 255)
4606 *lut++ = 255;
4607 else
4608 *lut++ = v;
4609 }
4610 }
4611
4612
4613 /*
4614 * End of "$Id: imagetoraster.c 5191 2006-02-27 02:47:56Z mike $".
4615 */