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