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