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