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