2 * "$Id: imagetoraster.c 9808 2011-05-26 12:03:28Z mike $"
4 * Image file to raster filter for CUPS.
6 * Copyright 2007-2011 by Apple Inc.
7 * Copyright 1993-2007 by Easy Software Products.
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/".
15 * This file is subject to the Apple OS-Developed Software exception.
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.
35 * Include necessary headers...
39 #include "image-private.h"
42 #include <cups/language-private.h>
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 */
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 }
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 }
109 cups_ib_t OnPixels[256], /* On-pixel LUT */
110 OffPixels[256]; /* Off-pixel LUT */
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);
133 * 'main()' - Main entry...
136 int /* O - Exit status */
137 main(int argc, /* I - Number of command-line arguments */
138 char *argv[]) /* I - Command-line arguments */
140 int i; /* Looping var */
141 cups_image_t *img; /* Image to print */
142 float xprint, /* Printable area */
144 xinches, /* Total size in inches */
146 float xsize, /* Total size in points */
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 */
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 */
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 */
197 * Make sure status messages are not buffered...
200 setbuf(stderr, NULL);
203 * Ignore broken pipe signals...
206 signal(SIGPIPE, SIG_IGN);
209 * Check command-line...
212 if (argc < 6 || argc > 7)
214 _cupsLangPrintf(stderr,
215 _("Usage: %s job-id user title copies options file"),
221 * See if we need to use the imagetops and pstoraster filters instead...
225 num_options = cupsParseOptions(argv[5], 0, &options);
227 if (getenv("CLASSIFICATION") ||
228 cupsGetOption("page-label", num_options, options))
231 * Yes, fork a copy of pstoraster and then transfer control to imagetops...
234 int mypipes[2]; /* New pipes for imagetops | pstoraster */
235 int pid; /* PID of pstoraster */
238 cupsFreeOptions(num_options, options);
242 _cupsLangPrintError("ERROR", _("Unable to create pipes for filters"));
246 if ((pid = fork()) == 0)
249 * Child process for pstoraster... Assign new pipe input to pstoraster...
256 execlp("pstoraster", argv[0], argv[1], argv[2], argv[3], argv[4], argv[5],
266 _cupsLangPrintError("ERROR", _("Unable to fork filter"));
271 * Update stdout so it points at the new pstoraster...
279 * Run imagetops to get the classification or page labeling that was
283 execlp("imagetops", argv[0], argv[1], argv[2], argv[3], argv[4], argv[5],
289 * Copy stdin as needed...
294 int fd; /* File to write to */
295 char buffer[8192]; /* Buffer to read into */
296 int bytes; /* # of bytes to read */
299 if ((fd = cupsTempFd(filename, sizeof(filename))) < 0)
301 _cupsLangPrintError("ERROR", _("Unable to copy print file"));
306 "DEBUG: imagetoraster - copying to temp print file \"%s\".\n",
309 while ((bytes = fread(buffer, 1, sizeof(buffer), stdin)) > 0)
310 write(fd, buffer, bytes);
315 strlcpy(filename, argv[6], sizeof(filename));
318 * Process command-line options and write the prolog...
329 Copies = atoi(argv[4]);
331 ppd = SetCommonOptions(num_options, options, 0);
333 if ((val = cupsGetOption("multiple-document-handling", num_options, options)) != NULL)
336 * This IPP attribute is unnecessarily complicated...
338 * single-document, separate-documents-collated-copies, and
339 * single-document-new-sheet all require collated copies.
341 * separate-documents-collated-copies allows for uncollated copies.
344 Collate = _cups_strcasecmp(val, "separate-documents-collated-copies") != 0;
347 if ((val = cupsGetOption("Collate", num_options, options)) != NULL &&
348 _cups_strcasecmp(val, "True") == 0)
351 if ((val = cupsGetOption("gamma", num_options, options)) != NULL)
354 * Get gamma value from 1 to 10000...
357 g = atoi(val) * 0.001f;
365 if ((val = cupsGetOption("brightness", num_options, options)) != NULL)
368 * Get brightness value from 10 to 1000.
371 b = atoi(val) * 0.01f;
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"))
384 else if ((val = cupsGetOption("fit-to-page", num_options, options)) != NULL &&
385 !_cups_strcasecmp(val, "true"))
388 if ((val = cupsGetOption("ppi", num_options, options)) != NULL)
389 if (sscanf(val, "%dx%d", &xppi, &yppi) < 2)
392 if ((val = cupsGetOption("position", num_options, options)) != NULL)
394 if (_cups_strcasecmp(val, "center") == 0)
399 else if (_cups_strcasecmp(val, "top") == 0)
404 else if (_cups_strcasecmp(val, "left") == 0)
409 else if (_cups_strcasecmp(val, "right") == 0)
414 else if (_cups_strcasecmp(val, "top-left") == 0)
419 else if (_cups_strcasecmp(val, "top-right") == 0)
424 else if (_cups_strcasecmp(val, "bottom") == 0)
429 else if (_cups_strcasecmp(val, "bottom-left") == 0)
434 else if (_cups_strcasecmp(val, "bottom-right") == 0)
441 if ((val = cupsGetOption("saturation", num_options, options)) != NULL)
444 if ((val = cupsGetOption("hue", num_options, options)) != NULL)
447 if ((choice = ppdFindMarkedChoice(ppd, "MirrorPrint")) != NULL)
449 val = choice->choice;
453 val = cupsGetOption("mirror", num_options, options);
455 if (val && (!_cups_strcasecmp(val, "true") || !_cups_strcasecmp(val, "on") ||
456 !_cups_strcasecmp(val, "yes")))
460 * Set the needed options in the page header...
463 if (cupsRasterInterpretPPD(&header, ppd, num_options, options, raster_cb))
465 _cupsLangPrintFilter(stderr, "ERROR",
466 _("The page setup information was not valid."));
467 fprintf(stderr, "DEBUG: %s\n", cupsRasterErrorString());
472 * Get the media type and resolution that have been chosen...
475 if ((choice = ppdFindMarkedChoice(ppd, "MediaType")) != NULL)
476 media_type = choice->choice;
480 if ((choice = ppdFindMarkedChoice(ppd, "Resolution")) != NULL)
481 resolution = choice->choice;
486 * Choose the appropriate colorspace...
489 switch (header.cupsColorSpace)
492 case CUPS_CSPACE_SW :
493 if (header.cupsBitsPerColor >= 8)
495 primary = CUPS_IMAGE_WHITE;
496 secondary = CUPS_IMAGE_WHITE;
500 primary = CUPS_IMAGE_BLACK;
501 secondary = CUPS_IMAGE_BLACK;
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)
513 primary = CUPS_IMAGE_RGB;
514 secondary = CUPS_IMAGE_RGB;
518 primary = CUPS_IMAGE_CMY;
519 secondary = CUPS_IMAGE_CMY;
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;
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)
539 primary = CUPS_IMAGE_CMY;
540 secondary = CUPS_IMAGE_CMY;
544 primary = CUPS_IMAGE_CMYK;
545 secondary = CUPS_IMAGE_CMYK;
549 case CUPS_CSPACE_CMY :
550 case CUPS_CSPACE_YMC :
551 primary = CUPS_IMAGE_CMY;
552 secondary = CUPS_IMAGE_CMY;
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);
594 * Find a color profile matching the current options...
597 if ((val = cupsGetOption("profile", num_options, options)) != NULL)
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);
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;
621 else if (ppd != NULL)
623 fprintf(stderr, "DEBUG: Searching for profile \"%s/%s\"...\n",
624 resolution, media_type);
626 for (i = 0, profile = ppd->profiles; i < ppd->num_profiles; i ++, profile ++)
628 fprintf(stderr, "DEBUG: \"%s/%s\" = ", profile->resolution,
629 profile->media_type);
631 if ((strcmp(profile->resolution, resolution) == 0 ||
632 profile->resolution[0] == '-') &&
633 (strcmp(profile->media_type, media_type) == 0 ||
634 profile->media_type[0] == '-'))
636 fputs("MATCH\n", stderr);
640 fputs("no.\n", stderr);
644 * If we found a color profile, use it!
647 if (i >= ppd->num_profiles)
654 cupsImageSetProfile(profile->density, profile->gamma, profile->matrix);
656 cupsImageSetRasterColorSpace(header.cupsColorSpace);
659 * Create a gamma/brightness LUT...
662 make_lut(lut, primary, g, b);
665 * Open the input image to print...
668 _cupsLangPrintFilter(stderr, "INFO", _("Loading print file."));
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);
675 img = cupsImageOpen(filename, primary, secondary, sat, hue, lut);
682 _cupsLangPrintFilter(stderr, "ERROR",
683 _("The print file could not be opened."));
689 * Scale as necessary...
692 if (zoom == 0.0 && xppi == 0)
701 fprintf(stderr, "DEBUG: Before scaling: xppi=%d, yppi=%d, zoom=%.2f\n",
707 * Scale the image as neccesary to match the desired pixels-per-inch.
712 xprint = (PageTop - PageBottom) / 72.0;
713 yprint = (PageRight - PageLeft) / 72.0;
717 xprint = (PageRight - PageLeft) / 72.0;
718 yprint = (PageTop - PageBottom) / 72.0;
721 fprintf(stderr, "DEBUG: Before scaling: xprint=%.1f, yprint=%.1f\n",
724 xinches = (float)img->xsize / (float)xppi;
725 yinches = (float)img->ysize / (float)yppi;
727 fprintf(stderr, "DEBUG: Image size is %.1f x %.1f inches...\n",
730 if ((val = cupsGetOption("natural-scaling", num_options, options)) != NULL)
732 xinches = xinches * atoi(val) / 100;
733 yinches = yinches * atoi(val) / 100;
736 if (cupsGetOption("orientation-requested", num_options, options) == NULL &&
737 cupsGetOption("landscape", num_options, options) == NULL)
740 * Rotate the image if it will fit landscape but not portrait...
743 fputs("DEBUG: Auto orientation...\n", stderr);
745 if ((xinches > xprint || yinches > yprint) &&
746 xinches <= yprint && yinches <= xprint)
749 * Rotate the image as needed...
752 fputs("DEBUG: Using landscape orientation...\n", stderr);
754 Orientation = (Orientation + 1) & 3;
764 * Scale percentage of page size...
767 xprint = (PageRight - PageLeft) / 72.0;
768 yprint = (PageTop - PageBottom) / 72.0;
769 aspect = (float)img->yppi / (float)img->xppi;
771 fprintf(stderr, "DEBUG: Before scaling: xprint=%.1f, yprint=%.1f\n",
774 fprintf(stderr, "DEBUG: img->xppi = %d, img->yppi = %d, aspect = %f\n",
775 img->xppi, img->yppi, aspect);
777 xsize = xprint * zoom;
778 ysize = xsize * img->ysize / img->xsize / aspect;
780 if (ysize > (yprint * zoom))
782 ysize = yprint * zoom;
783 xsize = ysize * img->xsize * aspect / img->ysize;
786 xsize2 = yprint * zoom;
787 ysize2 = xsize2 * img->ysize / img->xsize / aspect;
789 if (ysize2 > (xprint * zoom))
791 ysize2 = xprint * zoom;
792 xsize2 = ysize2 * img->xsize * aspect / img->ysize;
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);
798 if (cupsGetOption("orientation-requested", num_options, options) == NULL &&
799 cupsGetOption("landscape", num_options, options) == NULL)
802 * Choose the rotation with the largest area, but prefer
803 * portrait if they are equal...
806 fputs("DEBUG: Auto orientation...\n", stderr);
808 if ((xsize * ysize) < (xsize2 * xsize2))
811 * Do landscape orientation...
814 fputs("DEBUG: Using landscape orientation...\n", stderr);
819 xprint = (PageTop - PageBottom) / 72.0;
820 yprint = (PageRight - PageLeft) / 72.0;
825 * Do portrait orientation...
828 fputs("DEBUG: Using portrait orientation...\n", stderr);
835 else if (Orientation & 1)
837 fputs("DEBUG: Using landscape orientation...\n", stderr);
841 xprint = (PageTop - PageBottom) / 72.0;
842 yprint = (PageRight - PageLeft) / 72.0;
846 fputs("DEBUG: Using portrait orientation...\n", stderr);
850 xprint = (PageRight - PageLeft) / 72.0;
851 yprint = (PageTop - PageBottom) / 72.0;
856 * Compute the number of pages to print and the size of the image on each
860 xpages = ceil(xinches / xprint);
861 ypages = ceil(yinches / yprint);
863 xprint = xinches / xpages;
864 yprint = yinches / ypages;
866 fprintf(stderr, "DEBUG: xpages = %dx%.2fin, ypages = %dx%.2fin\n",
867 xpages, xprint, ypages, yprint);
870 * Compute the bitmap size...
873 if ((choice = ppdFindMarkedChoice(ppd, "PageSize")) != NULL &&
874 _cups_strcasecmp(choice->choice, "Custom") == 0)
876 float width, /* New width in points */
877 length; /* New length in points */
881 * Use the correct width and length for the current orientation...
886 width = yprint * 72.0;
887 length = xprint * 72.0;
891 width = xprint * 72.0;
892 length = yprint * 72.0;
896 * Add margins to page size...
899 width += ppd->custom_margins[0] + ppd->custom_margins[2];
900 length += ppd->custom_margins[1] + ppd->custom_margins[3];
903 * Enforce minimums...
906 if (width < ppd->custom_min[0])
907 width = ppd->custom_min[0];
909 if (length < ppd->custom_min[1])
910 length = ppd->custom_min[1];
912 fprintf(stderr, "DEBUG: Updated custom page size to %.2f x %.2f inches...\n",
913 width / 72.0, length / 72.0);
916 * Set the new custom size...
919 strcpy(header.cupsPageSizeName, "Custom");
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;
927 * Update page variables...
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];
938 * Remove margins from page size...
941 width -= ppd->custom_margins[0] + ppd->custom_margins[2];
942 length -= ppd->custom_margins[1] + ppd->custom_margins[3];
945 * Set the bitmap size...
948 header.cupsWidth = width * header.HWResolution[0] / 72.0;
949 header.cupsHeight = length * header.HWResolution[1] / 72.0;
951 header.cupsBytesPerLine = (header.cupsBitsPerPixel *
952 header.cupsWidth + 7) / 8;
954 if (header.cupsColorOrder == CUPS_ORDER_BANDED)
955 header.cupsBytesPerLine *= header.cupsNumColors;
958 header.Margins[0] = PageLeft;
959 header.Margins[1] = PageBottom;
961 fprintf(stderr, "DEBUG: PageSize = [%d %d]\n", header.PageSize[0],
970 header.cupsImagingBBox[0] = PageLeft;
971 header.cupsImagingBBox[2] = PageLeft + xprint * 72;
974 header.cupsImagingBBox[0] = (PageRight + PageLeft - xprint * 72) / 2;
975 header.cupsImagingBBox[2] = (PageRight + PageLeft + xprint * 72) / 2;
978 header.cupsImagingBBox[0] = PageRight - xprint * 72;
979 header.cupsImagingBBox[2] = PageRight;
986 header.cupsImagingBBox[1] = PageBottom;
987 header.cupsImagingBBox[3] = PageBottom + yprint * 72;
990 header.cupsImagingBBox[1] = (PageTop + PageBottom - yprint * 72) / 2;
991 header.cupsImagingBBox[3] = (PageTop + PageBottom + yprint * 72) / 2;
994 header.cupsImagingBBox[1] = PageTop - yprint * 72;
995 header.cupsImagingBBox[3] = PageTop;
1004 header.cupsImagingBBox[0] = PageBottom;
1005 header.cupsImagingBBox[2] = PageBottom + yprint * 72;
1008 header.cupsImagingBBox[0] = (PageTop + PageBottom - yprint * 72) / 2;
1009 header.cupsImagingBBox[2] = (PageTop + PageBottom + yprint * 72) / 2;
1012 header.cupsImagingBBox[0] = PageTop - yprint * 72;
1013 header.cupsImagingBBox[2] = PageTop;
1020 header.cupsImagingBBox[1] = PageLeft;
1021 header.cupsImagingBBox[3] = PageLeft + xprint * 72;
1024 header.cupsImagingBBox[1] = (PageRight + PageLeft - xprint * 72) / 2;
1025 header.cupsImagingBBox[3] = (PageRight + PageLeft + xprint * 72) / 2;
1028 header.cupsImagingBBox[1] = PageRight - xprint * 72;
1029 header.cupsImagingBBox[3] = PageRight;
1038 header.cupsImagingBBox[0] = PageLeft;
1039 header.cupsImagingBBox[2] = PageLeft + xprint * 72;
1042 header.cupsImagingBBox[0] = (PageRight + PageLeft - xprint * 72) / 2;
1043 header.cupsImagingBBox[2] = (PageRight + PageLeft + xprint * 72) / 2;
1046 header.cupsImagingBBox[0] = PageRight - xprint * 72;
1047 header.cupsImagingBBox[2] = PageRight;
1054 header.cupsImagingBBox[1] = PageBottom;
1055 header.cupsImagingBBox[3] = PageBottom + yprint * 72;
1058 header.cupsImagingBBox[1] = (PageTop + PageBottom - yprint * 72) / 2;
1059 header.cupsImagingBBox[3] = (PageTop + PageBottom + yprint * 72) / 2;
1062 header.cupsImagingBBox[1] = PageTop - yprint * 72;
1063 header.cupsImagingBBox[3] = PageTop;
1072 header.cupsImagingBBox[0] = PageBottom;
1073 header.cupsImagingBBox[2] = PageBottom + yprint * 72;
1076 header.cupsImagingBBox[0] = (PageTop + PageBottom - yprint * 72) / 2;
1077 header.cupsImagingBBox[2] = (PageTop + PageBottom + yprint * 72) / 2;
1080 header.cupsImagingBBox[0] = PageTop - yprint * 72;
1081 header.cupsImagingBBox[2] = PageTop;
1088 header.cupsImagingBBox[1] = PageLeft;
1089 header.cupsImagingBBox[3] = PageLeft + xprint * 72;
1092 header.cupsImagingBBox[1] = (PageRight + PageLeft - xprint * 72) / 2;
1093 header.cupsImagingBBox[3] = (PageRight + PageLeft + xprint * 72) / 2;
1096 header.cupsImagingBBox[1] = PageRight - xprint * 72;
1097 header.cupsImagingBBox[3] = PageRight;
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];
1108 if (header.cupsColorOrder == CUPS_ORDER_PLANAR)
1109 num_planes = header.cupsNumColors;
1113 if (header.cupsBitsPerColor >= 8)
1114 zoom_type = CUPS_IZOOM_NORMAL;
1116 zoom_type = CUPS_IZOOM_FAST;
1119 * See if we need to collate, and if so how we need to do it...
1122 if (xpages == 1 && ypages == 1)
1125 slowcollate = Collate && ppdFindOption(ppd, "Collate") == NULL;
1127 slowcopies = ppd->manual_copies;
1131 if (Copies > 1 && !slowcollate && !slowcopies)
1133 header.Collate = (cups_bool_t)Collate;
1134 header.NumCopies = Copies;
1139 header.NumCopies = 1;
1142 * Create the dithering lookup tables...
1146 OnPixels[255] = 0xff;
1147 OffPixels[0] = 0x00;
1148 OffPixels[255] = 0xff;
1150 switch (header.cupsBitsPerColor)
1153 for (i = 1; i < 255; i ++)
1155 OnPixels[i] = 0x55 * (i / 85 + 1);
1156 OffPixels[i] = 0x55 * (i / 64);
1160 for (i = 1; i < 255; i ++)
1162 OnPixels[i] = 17 * (i / 17 + 1);
1163 OffPixels[i] = 17 * (i / 16);
1169 * Output the pages...
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);
1181 row = malloc(2 * header.cupsBytesPerLine);
1182 ras = cupsRasterOpen(1, CUPS_RASTER_WRITE);
1184 for (i = 0, page = 1; i < Copies; i ++)
1185 for (xpage = 0; xpage < xpages; xpage ++)
1186 for (ypage = 0; ypage < ypages; ypage ++, page ++)
1188 _cupsLangPrintFilter(stderr, "INFO", _("Formatting page %d."), page);
1190 if (Orientation & 1)
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;
1197 xtemp = header.HWResolution[0] * yprint;
1198 ytemp = header.HWResolution[1] * xprint;
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;
1207 xtemp = header.HWResolution[0] * xprint;
1208 ytemp = header.HWResolution[1] * yprint;
1211 cupsRasterWriteHeader2(ras, &header);
1213 for (plane = 0; plane < num_planes; plane ++)
1216 * Initialize the image "zoom" engine...
1220 z = _cupsImageZoomNew(img, xc0, yc0, xc1, yc1, -xtemp, ytemp,
1221 Orientation & 1, zoom_type);
1223 z = _cupsImageZoomNew(img, xc0, yc0, xc1, yc1, xtemp, ytemp,
1224 Orientation & 1, zoom_type);
1227 * Write leading blank space as needed...
1230 if (header.cupsHeight > z->ysize && YPosition <= 0)
1232 blank_line(&header, row);
1234 y = header.cupsHeight - z->ysize;
1238 fprintf(stderr, "DEBUG: Writing %d leading blank lines...\n", y);
1242 if (cupsRasterWritePixels(ras, row, header.cupsBytesPerLine) <
1243 header.cupsBytesPerLine)
1245 _cupsLangPrintFilter(stderr, "ERROR",
1246 _("Unable to send raster data to the "
1248 cupsImageClose(img);
1255 * Then write image data...
1258 for (y = z->ysize, yerr0 = 0, yerr1 = z->ysize, iy = 0, last_iy = -2;
1264 if (zoom_type != CUPS_IZOOM_FAST && (iy - last_iy) > 1)
1265 _cupsImageZoomFill(z, iy);
1267 _cupsImageZoomFill(z, iy + z->yincr);
1273 * Format this line of raster data for the printer...
1276 blank_line(&header, row);
1278 r0 = z->rows[z->row];
1279 r1 = z->rows[1 - z->row];
1281 switch (header.cupsColorSpace)
1283 case CUPS_CSPACE_W :
1284 format_W(&header, row, y, plane, z->xsize, z->ysize,
1285 yerr0, yerr1, r0, r1);
1288 case CUPS_CSPACE_RGB :
1289 format_RGB(&header, row, y, plane, z->xsize, z->ysize,
1290 yerr0, yerr1, r0, r1);
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);
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);
1304 case CUPS_CSPACE_CMY :
1305 format_CMY(&header, row, y, plane, z->xsize, z->ysize,
1306 yerr0, yerr1, r0, r1);
1308 case CUPS_CSPACE_YMC :
1309 format_YMC(&header, row, y, plane, z->xsize, z->ysize,
1310 yerr0, yerr1, r0, r1);
1312 case CUPS_CSPACE_CMYK :
1313 format_CMYK(&header, row, y, plane, z->xsize, z->ysize,
1314 yerr0, yerr1, r0, r1);
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);
1322 case CUPS_CSPACE_KCMYcm :
1323 if (header.cupsBitsPerColor == 1)
1325 format_KCMYcm(&header, row, y, plane, z->xsize, z->ysize,
1326 yerr0, yerr1, r0, r1);
1329 case CUPS_CSPACE_KCMY :
1330 format_KCMY(&header, row, y, plane, z->xsize, z->ysize,
1331 yerr0, yerr1, r0, r1);
1336 * Write the raster data to the driver...
1339 if (cupsRasterWritePixels(ras, row, header.cupsBytesPerLine) <
1340 header.cupsBytesPerLine)
1342 _cupsLangPrintFilter(stderr, "ERROR",
1343 _("Unable to send raster data to the "
1345 cupsImageClose(img);
1350 * Compute the next scanline in the image...
1365 * Write trailing blank space as needed...
1368 if (header.cupsHeight > z->ysize && YPosition >= 0)
1370 blank_line(&header, row);
1372 y = header.cupsHeight - z->ysize;
1376 fprintf(stderr, "DEBUG: Writing %d trailing blank lines...\n", y);
1380 if (cupsRasterWritePixels(ras, row, header.cupsBytesPerLine) <
1381 header.cupsBytesPerLine)
1383 _cupsLangPrintFilter(stderr, "ERROR",
1384 _("Unable to send raster data to the "
1386 cupsImageClose(img);
1393 * Free memory used for the "zoom" engine...
1396 _cupsImageZoomDelete(z);
1405 cupsRasterClose(ras);
1406 cupsImageClose(img);
1414 * 'blank_line()' - Clear a line buffer to the blank value...
1418 blank_line(cups_page_header2_t *header, /* I - Page header */
1419 unsigned char *row) /* I - Row buffer */
1421 int count; /* Remaining bytes */
1424 count = header->cupsBytesPerLine;
1426 switch (header->cupsColorSpace)
1428 case CUPS_CSPACE_CIEXYZ :
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 :
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);
1479 memset(row, 255, count);
1486 * 'format_CMY()' - Convert image data to CMY.
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 */
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 */
1518 bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2);
1521 bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize);
1525 ptr = row + bitoffset / 8;
1526 bandwidth = header->cupsBytesPerLine / 3;
1528 switch (header->cupsColorOrder)
1530 case CUPS_ORDER_CHUNKED :
1531 switch (header->cupsBitsPerColor)
1534 bitmask = 64 >> (bitoffset & 7);
1535 dither = Floyd16x16[y & 15];
1537 for (x = xsize ; x > 0; x --)
1539 if (*r0++ > dither[x & 15])
1543 if (*r0++ > dither[x & 15])
1547 if (*r0++ > dither[x & 15])
1561 dither = Floyd8x8[y & 7];
1563 for (x = xsize ; x > 0; x --, r0 += 3)
1565 if ((r0[0] & 63) > dither[x & 7])
1566 *ptr ^= (0x30 & OnPixels[r0[0]]);
1568 *ptr ^= (0x30 & OffPixels[r0[0]]);
1570 if ((r0[1] & 63) > dither[x & 7])
1571 *ptr ^= (0x0c & OnPixels[r0[1]]);
1573 *ptr ^= (0x0c & OffPixels[r0[1]]);
1575 if ((r0[2] & 63) > dither[x & 7])
1576 *ptr++ ^= (0x03 & OnPixels[r0[2]]);
1578 *ptr++ ^= (0x03 & OffPixels[r0[2]]);
1583 dither = Floyd4x4[y & 3];
1585 for (x = xsize ; x > 0; x --, r0 += 3)
1587 if ((r0[0] & 15) > dither[x & 3])
1588 *ptr++ ^= (0x0f & OnPixels[r0[0]]);
1590 *ptr++ ^= (0x0f & OffPixels[r0[0]]);
1592 if ((r0[1] & 15) > dither[x & 3])
1593 *ptr ^= (0xf0 & OnPixels[r0[1]]);
1595 *ptr ^= (0xf0 & OffPixels[r0[1]]);
1597 if ((r0[2] & 15) > dither[x & 3])
1598 *ptr++ ^= (0x0f & OnPixels[r0[2]]);
1600 *ptr++ ^= (0x0f & OffPixels[r0[2]]);
1605 for (x = xsize * 3; x > 0; x --, r0 ++, r1 ++)
1609 *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize;
1614 case CUPS_ORDER_BANDED :
1616 mptr = ptr + bandwidth;
1617 yptr = ptr + 2 * bandwidth;
1619 switch (header->cupsBitsPerColor)
1622 bitmask = 0x80 >> (bitoffset & 7);
1623 dither = Floyd16x16[y & 15];
1625 for (x = xsize; x > 0; x --)
1627 if (*r0++ > dither[x & 15])
1629 if (*r0++ > dither[x & 15])
1631 if (*r0++ > dither[x & 15])
1647 bitmask = 0xc0 >> (bitoffset & 7);
1648 dither = Floyd8x8[y & 7];
1650 for (x = xsize; x > 0; x --)
1652 if ((*r0 & 63) > dither[x & 7])
1653 *cptr ^= (bitmask & OnPixels[*r0++]);
1655 *cptr ^= (bitmask & OffPixels[*r0++]);
1657 if ((*r0 & 63) > dither[x & 7])
1658 *mptr ^= (bitmask & OnPixels[*r0++]);
1660 *mptr ^= (bitmask & OffPixels[*r0++]);
1662 if ((*r0 & 63) > dither[x & 7])
1663 *yptr ^= (bitmask & OnPixels[*r0++]);
1665 *yptr ^= (bitmask & OffPixels[*r0++]);
1681 bitmask = 0xf0 >> (bitoffset & 7);
1682 dither = Floyd4x4[y & 3];
1684 for (x = xsize; x > 0; x --)
1686 if ((*r0 & 15) > dither[x & 3])
1687 *cptr ^= (bitmask & OnPixels[*r0++]);
1689 *cptr ^= (bitmask & OffPixels[*r0++]);
1691 if ((*r0 & 15) > dither[x & 3])
1692 *mptr ^= (bitmask & OnPixels[*r0++]);
1694 *mptr ^= (bitmask & OffPixels[*r0++]);
1696 if ((*r0 & 15) > dither[x & 3])
1697 *yptr ^= (bitmask & OnPixels[*r0++]);
1699 *yptr ^= (bitmask & OffPixels[*r0++]);
1701 if (bitmask == 0xf0)
1715 for (x = xsize; x > 0; x --, r0 += 3, r1 += 3)
1720 *cptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize;
1725 *mptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize;
1730 *yptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize;
1736 case CUPS_ORDER_PLANAR :
1737 switch (header->cupsBitsPerColor)
1740 bitmask = 0x80 >> (bitoffset & 7);
1741 dither = Floyd16x16[y & 15];
1746 for (x = xsize; x > 0; x --, r0 += 3)
1748 if (r0[0] > dither[x & 15])
1762 for (x = xsize; x > 0; x --, r0 += 3)
1764 if (r0[1] > dither[x & 15])
1778 for (x = xsize; x > 0; x --, r0 += 3)
1780 if (r0[2] > dither[x & 15])
1796 bitmask = 0xc0 >> (bitoffset & 7);
1797 dither = Floyd8x8[y & 7];
1800 for (x = xsize; x > 0; x --, r0 += 3)
1802 if ((*r0 & 63) > dither[x & 7])
1803 *ptr ^= (bitmask & OnPixels[*r0]);
1805 *ptr ^= (bitmask & OffPixels[*r0]);
1819 bitmask = 0xf0 >> (bitoffset & 7);
1820 dither = Floyd4x4[y & 3];
1823 for (x = xsize; x > 0; x --, r0 += 3)
1825 if ((*r0 & 15) > dither[x & 3])
1826 *ptr ^= (bitmask & OnPixels[*r0]);
1828 *ptr ^= (bitmask & OffPixels[*r0]);
1830 if (bitmask == 0xf0)
1845 for (x = xsize; x > 0; x --, r0 += 3, r1 += 3)
1850 *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize;
1860 * 'format_CMYK()' - Convert image data to CMYK.
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 */
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 */
1894 bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2);
1897 bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize);
1901 ptr = row + bitoffset / 8;
1902 bandwidth = header->cupsBytesPerLine / 4;
1904 switch (header->cupsColorOrder)
1906 case CUPS_ORDER_CHUNKED :
1907 switch (header->cupsBitsPerColor)
1910 bitmask = 128 >> (bitoffset & 7);
1911 dither = Floyd16x16[y & 15];
1913 for (x = xsize ; x > 0; x --)
1915 pc = *r0++ > dither[x & 15];
1916 pm = *r0++ > dither[x & 15];
1917 py = *r0++ > dither[x & 15];
1950 dither = Floyd8x8[y & 7];
1952 for (x = xsize ; x > 0; x --, r0 += 4)
1954 if ((r0[0] & 63) > dither[x & 7])
1955 *ptr ^= (0xc0 & OnPixels[r0[0]]);
1957 *ptr ^= (0xc0 & OffPixels[r0[0]]);
1959 if ((r0[1] & 63) > dither[x & 7])
1960 *ptr ^= (0x30 & OnPixels[r0[1]]);
1962 *ptr ^= (0x30 & OffPixels[r0[1]]);
1964 if ((r0[2] & 63) > dither[x & 7])
1965 *ptr ^= (0x0c & OnPixels[r0[2]]);
1967 *ptr ^= (0x0c & OffPixels[r0[2]]);
1969 if ((r0[3] & 63) > dither[x & 7])
1970 *ptr++ ^= (0x03 & OnPixels[r0[3]]);
1972 *ptr++ ^= (0x03 & OffPixels[r0[3]]);
1977 dither = Floyd4x4[y & 3];
1979 for (x = xsize ; x > 0; x --, r0 += 4)
1981 if ((r0[0] & 15) > dither[x & 3])
1982 *ptr ^= (0xf0 & OnPixels[r0[0]]);
1984 *ptr ^= (0xf0 & OffPixels[r0[0]]);
1986 if ((r0[1] & 15) > dither[x & 3])
1987 *ptr++ ^= (0x0f & OnPixels[r0[1]]);
1989 *ptr++ ^= (0x0f & OffPixels[r0[1]]);
1991 if ((r0[2] & 15) > dither[x & 3])
1992 *ptr ^= (0xf0 & OnPixels[r0[2]]);
1994 *ptr ^= (0xf0 & OffPixels[r0[2]]);
1996 if ((r0[3] & 15) > dither[x & 3])
1997 *ptr++ ^= (0x0f & OnPixels[r0[3]]);
1999 *ptr++ ^= (0x0f & OffPixels[r0[3]]);
2004 for (x = xsize * 4; x > 0; x --, r0 ++, r1 ++)
2008 *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize;
2013 case CUPS_ORDER_BANDED :
2015 mptr = ptr + bandwidth;
2016 yptr = ptr + 2 * bandwidth;
2017 kptr = ptr + 3 * bandwidth;
2019 switch (header->cupsBitsPerColor)
2022 bitmask = 0x80 >> (bitoffset & 7);
2023 dither = Floyd16x16[y & 15];
2025 for (x = xsize; x > 0; x --)
2027 pc = *r0++ > dither[x & 15];
2028 pm = *r0++ > dither[x & 15];
2029 py = *r0++ > dither[x & 15];
2057 bitmask = 0xc0 >> (bitoffset & 7);
2058 dither = Floyd8x8[y & 7];
2060 for (x = xsize; x > 0; x --)
2062 if ((*r0 & 63) > dither[x & 7])
2063 *cptr ^= (bitmask & OnPixels[*r0++]);
2065 *cptr ^= (bitmask & OffPixels[*r0++]);
2067 if ((*r0 & 63) > dither[x & 7])
2068 *mptr ^= (bitmask & OnPixels[*r0++]);
2070 *mptr ^= (bitmask & OffPixels[*r0++]);
2072 if ((*r0 & 63) > dither[x & 7])
2073 *yptr ^= (bitmask & OnPixels[*r0++]);
2075 *yptr ^= (bitmask & OffPixels[*r0++]);
2077 if ((*r0 & 63) > dither[x & 7])
2078 *kptr ^= (bitmask & OnPixels[*r0++]);
2080 *kptr ^= (bitmask & OffPixels[*r0++]);
2097 bitmask = 0xf0 >> (bitoffset & 7);
2098 dither = Floyd4x4[y & 3];
2100 for (x = xsize; x > 0; x --)
2102 if ((*r0 & 15) > dither[x & 3])
2103 *cptr ^= (bitmask & OnPixels[*r0++]);
2105 *cptr ^= (bitmask & OffPixels[*r0++]);
2107 if ((*r0 & 15) > dither[x & 3])
2108 *mptr ^= (bitmask & OnPixels[*r0++]);
2110 *mptr ^= (bitmask & OffPixels[*r0++]);
2112 if ((*r0 & 15) > dither[x & 3])
2113 *yptr ^= (bitmask & OnPixels[*r0++]);
2115 *yptr ^= (bitmask & OffPixels[*r0++]);
2117 if ((*r0 & 15) > dither[x & 3])
2118 *kptr ^= (bitmask & OnPixels[*r0++]);
2120 *kptr ^= (bitmask & OffPixels[*r0++]);
2122 if (bitmask == 0xf0)
2137 for (x = xsize; x > 0; x --, r0 += 4, r1 += 4)
2142 *cptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize;
2147 *mptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize;
2152 *yptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize;
2157 *kptr++ = (r0[3] * yerr0 + r1[3] * yerr1) / ysize;
2163 case CUPS_ORDER_PLANAR :
2164 switch (header->cupsBitsPerColor)
2167 bitmask = 0x80 >> (bitoffset & 7);
2168 dither = Floyd16x16[y & 15];
2170 for (x = xsize; x > 0; x --)
2172 pc = *r0++ > dither[x & 15];
2173 pm = *r0++ > dither[x & 15];
2174 py = *r0++ > dither[x & 15];
2176 if ((pc && pm && py && z == 3) ||
2177 (pc && z == 0) || (pm && z == 1) || (py && z == 2))
2191 bitmask = 0xc0 >> (bitoffset & 7);
2192 dither = Floyd8x8[y & 7];
2195 for (x = xsize; x > 0; x --, r0 += 4)
2197 if ((*r0 & 63) > dither[x & 7])
2198 *ptr ^= (bitmask & OnPixels[*r0]);
2200 *ptr ^= (bitmask & OffPixels[*r0]);
2214 bitmask = 0xf0 >> (bitoffset & 7);
2215 dither = Floyd4x4[y & 3];
2218 for (x = xsize; x > 0; x --, r0 += 4)
2220 if ((*r0 & 15) > dither[x & 3])
2221 *ptr ^= (bitmask & OnPixels[*r0]);
2223 *ptr ^= (bitmask & OffPixels[*r0]);
2225 if (bitmask == 0xf0)
2240 for (x = xsize; x > 0; x --, r0 += 4, r1 += 4)
2245 *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize;
2255 * 'format_K()' - Convert image data to black.
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 */
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 */
2285 bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2);
2288 bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize);
2292 ptr = row + bitoffset / 8;
2294 switch (header->cupsBitsPerColor)
2297 bitmask = 0x80 >> (bitoffset & 7);
2298 dither = Floyd16x16[y & 15];
2300 for (x = xsize; x > 0; x --)
2302 if (*r0++ > dither[x & 15])
2316 bitmask = 0xc0 >> (bitoffset & 7);
2317 dither = Floyd8x8[y & 7];
2319 for (x = xsize; x > 0; x --)
2321 if ((*r0 & 63) > dither[x & 7])
2322 *ptr ^= (bitmask & OnPixels[*r0++]);
2324 *ptr ^= (bitmask & OffPixels[*r0++]);
2338 bitmask = 0xf0 >> (bitoffset & 7);
2339 dither = Floyd4x4[y & 3];
2341 for (x = xsize; x > 0; x --)
2343 if ((*r0 & 15) > dither[x & 3])
2344 *ptr ^= (bitmask & OnPixels[*r0++]);
2346 *ptr ^= (bitmask & OffPixels[*r0++]);
2348 if (bitmask == 0xf0)
2360 for (x = xsize; x > 0; x --, r0 ++, r1 ++)
2365 *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize;
2373 * 'format_KCMY()' - Convert image data to KCMY.
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 */
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 */
2407 bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2);
2410 bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize);
2414 ptr = row + bitoffset / 8;
2415 bandwidth = header->cupsBytesPerLine / 4;
2417 switch (header->cupsColorOrder)
2419 case CUPS_ORDER_CHUNKED :
2420 switch (header->cupsBitsPerColor)
2423 bitmask = 128 >> (bitoffset & 7);
2424 dither = Floyd16x16[y & 15];
2426 for (x = xsize ; x > 0; x --)
2428 pc = *r0++ > dither[x & 15];
2429 pm = *r0++ > dither[x & 15];
2430 py = *r0++ > dither[x & 15];
2463 dither = Floyd8x8[y & 7];
2465 for (x = xsize ; x > 0; x --, r0 += 4)
2467 if ((r0[3] & 63) > dither[x & 7])
2468 *ptr ^= (0xc0 & OnPixels[r0[3]]);
2470 *ptr ^= (0xc0 & OffPixels[r0[3]]);
2472 if ((r0[0] & 63) > dither[x & 7])
2473 *ptr ^= (0x30 & OnPixels[r0[0]]);
2475 *ptr ^= (0x30 & OffPixels[r0[0]]);
2477 if ((r0[1] & 63) > dither[x & 7])
2478 *ptr ^= (0x0c & OnPixels[r0[1]]);
2480 *ptr ^= (0x0c & OffPixels[r0[1]]);
2482 if ((r0[2] & 63) > dither[x & 7])
2483 *ptr++ ^= (0x03 & OnPixels[r0[2]]);
2485 *ptr++ ^= (0x03 & OffPixels[r0[2]]);
2490 dither = Floyd4x4[y & 3];
2492 for (x = xsize ; x > 0; x --, r0 += 4)
2494 if ((r0[3] & 15) > dither[x & 3])
2495 *ptr ^= (0xf0 & OnPixels[r0[3]]);
2497 *ptr ^= (0xf0 & OffPixels[r0[3]]);
2499 if ((r0[0] & 15) > dither[x & 3])
2500 *ptr++ ^= (0x0f & OnPixels[r0[0]]);
2502 *ptr++ ^= (0x0f & OffPixels[r0[0]]);
2504 if ((r0[1] & 15) > dither[x & 3])
2505 *ptr ^= (0xf0 & OnPixels[r0[1]]);
2507 *ptr ^= (0xf0 & OffPixels[r0[1]]);
2509 if ((r0[2] & 15) > dither[x & 3])
2510 *ptr++ ^= (0x0f & OnPixels[r0[2]]);
2512 *ptr++ ^= (0x0f & OffPixels[r0[2]]);
2517 for (x = xsize; x > 0; x --, r0 += 4, r1 += 4)
2522 *ptr++ = (r0[3] * yerr0 + r1[3] * yerr1) / ysize;
2527 *ptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize;
2532 *ptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize;
2537 *ptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize;
2543 case CUPS_ORDER_BANDED :
2545 cptr = ptr + bandwidth;
2546 mptr = ptr + 2 * bandwidth;
2547 yptr = ptr + 3 * bandwidth;
2549 switch (header->cupsBitsPerColor)
2552 bitmask = 0x80 >> (bitoffset & 7);
2553 dither = Floyd16x16[y & 15];
2555 for (x = xsize; x > 0; x --)
2557 pc = *r0++ > dither[x & 15];
2558 pm = *r0++ > dither[x & 15];
2559 py = *r0++ > dither[x & 15];
2587 bitmask = 0xc0 >> (bitoffset & 7);
2588 dither = Floyd8x8[y & 7];
2590 for (x = xsize; x > 0; x --)
2592 if ((*r0 & 63) > dither[x & 7])
2593 *cptr ^= (bitmask & OnPixels[*r0++]);
2595 *cptr ^= (bitmask & OffPixels[*r0++]);
2597 if ((*r0 & 63) > dither[x & 7])
2598 *mptr ^= (bitmask & OnPixels[*r0++]);
2600 *mptr ^= (bitmask & OffPixels[*r0++]);
2602 if ((*r0 & 63) > dither[x & 7])
2603 *yptr ^= (bitmask & OnPixels[*r0++]);
2605 *yptr ^= (bitmask & OffPixels[*r0++]);
2607 if ((*r0 & 63) > dither[x & 7])
2608 *kptr ^= (bitmask & OnPixels[*r0++]);
2610 *kptr ^= (bitmask & OffPixels[*r0++]);
2627 bitmask = 0xf0 >> (bitoffset & 7);
2628 dither = Floyd4x4[y & 3];
2630 for (x = xsize; x > 0; x --)
2632 if ((*r0 & 15) > dither[x & 3])
2633 *cptr ^= (bitmask & OnPixels[*r0++]);
2635 *cptr ^= (bitmask & OffPixels[*r0++]);
2637 if ((*r0 & 15) > dither[x & 3])
2638 *mptr ^= (bitmask & OnPixels[*r0++]);
2640 *mptr ^= (bitmask & OffPixels[*r0++]);
2642 if ((*r0 & 15) > dither[x & 3])
2643 *yptr ^= (bitmask & OnPixels[*r0++]);
2645 *yptr ^= (bitmask & OffPixels[*r0++]);
2647 if ((*r0 & 15) > dither[x & 3])
2648 *kptr ^= (bitmask & OnPixels[*r0++]);
2650 *kptr ^= (bitmask & OffPixels[*r0++]);
2652 if (bitmask == 0xf0)
2667 for (x = xsize; x > 0; x --, r0 += 4, r1 += 4)
2672 *cptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize;
2677 *mptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize;
2682 *yptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize;
2687 *kptr++ = (r0[3] * yerr0 + r1[3] * yerr1) / ysize;
2693 case CUPS_ORDER_PLANAR :
2694 switch (header->cupsBitsPerColor)
2697 bitmask = 0x80 >> (bitoffset & 7);
2698 dither = Floyd16x16[y & 15];
2700 for (x = xsize; x > 0; x --)
2702 pc = *r0++ > dither[x & 15];
2703 pm = *r0++ > dither[x & 15];
2704 py = *r0++ > dither[x & 15];
2706 if ((pc && pm && py && z == 0) ||
2707 (pc && z == 1) || (pm && z == 2) || (py && z == 3))
2721 bitmask = 0xc0 >> (bitoffset & 7);
2722 dither = Floyd8x8[y & 7];
2728 for (x = xsize; x > 0; x --, r0 += 4)
2730 if ((*r0 & 63) > dither[x & 7])
2731 *ptr ^= (bitmask & OnPixels[*r0]);
2733 *ptr ^= (bitmask & OffPixels[*r0]);
2747 bitmask = 0xf0 >> (bitoffset & 7);
2748 dither = Floyd4x4[y & 3];
2754 for (x = xsize; x > 0; x --, r0 += 4)
2756 if ((*r0 & 15) > dither[x & 3])
2757 *ptr ^= (bitmask & OnPixels[*r0]);
2759 *ptr ^= (bitmask & OffPixels[*r0]);
2761 if (bitmask == 0xf0)
2784 for (x = xsize; x > 0; x --, r0 += 4, r1 += 4)
2789 *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize;
2799 * 'format_KCMYcm()' - Convert image data to 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 */
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 */
2836 bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2);
2839 bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize);
2843 ptr = row + bitoffset / 8;
2844 bandwidth = header->cupsBytesPerLine / 6;
2846 switch (header->cupsColorOrder)
2848 case CUPS_ORDER_CHUNKED :
2849 dither = Floyd16x16[y & 15];
2851 for (x = xsize ; x > 0; x --)
2853 pc = *r0++ > dither[x & 15];
2854 pm = *r0++ > dither[x & 15];
2855 py = *r0++ > dither[x & 15];
2856 pk = pc && pm && py;
2859 *ptr++ ^= 32; /* Black */
2861 *ptr++ ^= 17; /* Blue (cyan + light magenta) */
2863 *ptr++ ^= 6; /* Green (light cyan + yellow) */
2865 *ptr++ ^= 12; /* Red (magenta + yellow) */
2877 case CUPS_ORDER_BANDED :
2879 cptr = ptr + bandwidth;
2880 mptr = ptr + 2 * bandwidth;
2881 yptr = ptr + 3 * bandwidth;
2882 lcptr = ptr + 4 * bandwidth;
2883 lmptr = ptr + 5 * bandwidth;
2885 bitmask = 0x80 >> (bitoffset & 7);
2886 dither = Floyd16x16[y & 15];
2888 for (x = xsize; x > 0; x --)
2890 pc = *r0++ > dither[x & 15];
2891 pm = *r0++ > dither[x & 15];
2892 py = *r0++ > dither[x & 15];
2893 pk = pc && pm && py;
2896 *kptr ^= bitmask; /* Black */
2899 *cptr ^= bitmask; /* Blue (cyan + light magenta) */
2904 *lcptr ^= bitmask; /* Green (light cyan + yellow) */
2909 *mptr ^= bitmask; /* Red (magenta + yellow) */
2934 case CUPS_ORDER_PLANAR :
2935 bitmask = 0x80 >> (bitoffset & 7);
2936 dither = Floyd16x16[y & 15];
2938 for (x = xsize; x > 0; x --)
2940 pc = *r0++ > dither[x & 15];
2941 pm = *r0++ > dither[x & 15];
2942 py = *r0++ > dither[x & 15];
2943 pk = pc && pm && py;
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)
2955 else if (pm && z == 2)
2957 else if (py && z == 3)
2974 * 'format_RGBA()' - Convert image data to RGBA/RGBW.
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 */
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 */
3006 bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2);
3009 bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize);
3013 ptr = row + bitoffset / 8;
3014 bandwidth = header->cupsBytesPerLine / 4;
3016 switch (header->cupsColorOrder)
3018 case CUPS_ORDER_CHUNKED :
3019 switch (header->cupsBitsPerColor)
3022 bitmask = 128 >> (bitoffset & 7);
3023 dither = Floyd16x16[y & 15];
3025 for (x = xsize ; x > 0; x --)
3027 if (*r0++ > dither[x & 15])
3031 if (*r0++ > dither[x & 15])
3035 if (*r0++ > dither[x & 15])
3049 dither = Floyd8x8[y & 7];
3051 for (x = xsize ; x > 0; x --, r0 += 3)
3053 if ((r0[0] & 63) > dither[x & 7])
3054 *ptr ^= (0xc0 & OnPixels[r0[0]]);
3056 *ptr ^= (0xc0 & OffPixels[r0[0]]);
3058 if ((r0[1] & 63) > dither[x & 7])
3059 *ptr ^= (0x30 & OnPixels[r0[1]]);
3061 *ptr ^= (0x30 & OffPixels[r0[1]]);
3063 if ((r0[2] & 63) > dither[x & 7])
3064 *ptr ^= (0x0c & OnPixels[r0[2]]);
3066 *ptr ^= (0x0c & OffPixels[r0[2]]);
3073 dither = Floyd4x4[y & 3];
3075 for (x = xsize ; x > 0; x --, r0 += 3)
3077 if ((r0[0] & 15) > dither[x & 3])
3078 *ptr ^= (0xf0 & OnPixels[r0[0]]);
3080 *ptr ^= (0xf0 & OffPixels[r0[0]]);
3082 if ((r0[1] & 15) > dither[x & 3])
3083 *ptr++ ^= (0x0f & OnPixels[r0[1]]);
3085 *ptr++ ^= (0x0f & OffPixels[r0[1]]);
3087 if ((r0[2] & 15) > dither[x & 3])
3088 *ptr ^= (0xf0 & OnPixels[r0[2]]);
3090 *ptr ^= (0xf0 & OffPixels[r0[2]]);
3097 for (x = xsize; x > 0; x --, r0 += 3, r1 += 3)
3102 *ptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize;
3107 *ptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize;
3112 *ptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize;
3120 case CUPS_ORDER_BANDED :
3122 mptr = ptr + bandwidth;
3123 yptr = ptr + 2 * bandwidth;
3125 memset(ptr + 3 * bandwidth, 255, bandwidth);
3127 switch (header->cupsBitsPerColor)
3130 bitmask = 0x80 >> (bitoffset & 7);
3131 dither = Floyd16x16[y & 15];
3133 for (x = xsize; x > 0; x --)
3135 if (*r0++ > dither[x & 15])
3137 if (*r0++ > dither[x & 15])
3139 if (*r0++ > dither[x & 15])
3155 bitmask = 0xc0 >> (bitoffset & 7);
3156 dither = Floyd8x8[y & 7];
3158 for (x = xsize; x > 0; x --)
3160 if ((*r0 & 63) > dither[x & 7])
3161 *cptr ^= (bitmask & OnPixels[*r0++]);
3163 *cptr ^= (bitmask & OffPixels[*r0++]);
3165 if ((*r0 & 63) > dither[x & 7])
3166 *mptr ^= (bitmask & OnPixels[*r0++]);
3168 *mptr ^= (bitmask & OffPixels[*r0++]);
3170 if ((*r0 & 63) > dither[x & 7])
3171 *yptr ^= (bitmask & OnPixels[*r0++]);
3173 *yptr ^= (bitmask & OffPixels[*r0++]);
3189 bitmask = 0xf0 >> (bitoffset & 7);
3190 dither = Floyd4x4[y & 3];
3192 for (x = xsize; x > 0; x --)
3194 if ((*r0 & 15) > dither[x & 3])
3195 *cptr ^= (bitmask & OnPixels[*r0++]);
3197 *cptr ^= (bitmask & OffPixels[*r0++]);
3199 if ((*r0 & 15) > dither[x & 3])
3200 *mptr ^= (bitmask & OnPixels[*r0++]);
3202 *mptr ^= (bitmask & OffPixels[*r0++]);
3204 if ((*r0 & 15) > dither[x & 3])
3205 *yptr ^= (bitmask & OnPixels[*r0++]);
3207 *yptr ^= (bitmask & OffPixels[*r0++]);
3209 if (bitmask == 0xf0)
3223 for (x = xsize; x > 0; x --, r0 += 3, r1 += 3)
3228 *cptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize;
3233 *mptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize;
3238 *yptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize;
3244 case CUPS_ORDER_PLANAR :
3247 memset(row, 255, header->cupsBytesPerLine);
3251 switch (header->cupsBitsPerColor)
3254 bitmask = 0x80 >> (bitoffset & 7);
3255 dither = Floyd16x16[y & 15];
3260 for (x = xsize; x > 0; x --, r0 += 3)
3262 if (r0[0] > dither[x & 15])
3276 for (x = xsize; x > 0; x --, r0 += 3)
3278 if (r0[1] > dither[x & 15])
3292 for (x = xsize; x > 0; x --, r0 += 3)
3294 if (r0[2] > dither[x & 15])
3310 bitmask = 0xc0 >> (bitoffset & 7);
3311 dither = Floyd8x8[y & 7];
3314 for (x = xsize; x > 0; x --, r0 += 3)
3316 if ((*r0 & 63) > dither[x & 7])
3317 *ptr ^= (bitmask & OnPixels[*r0]);
3319 *ptr ^= (bitmask & OffPixels[*r0]);
3333 bitmask = 0xf0 >> (bitoffset & 7);
3334 dither = Floyd4x4[y & 3];
3337 for (x = xsize; x > 0; x --, r0 += 3)
3339 if ((*r0 & 15) > dither[x & 3])
3340 *ptr ^= (bitmask & OnPixels[*r0]);
3342 *ptr ^= (bitmask & OffPixels[*r0]);
3344 if (bitmask == 0xf0)
3359 for (x = xsize; x > 0; x --, r0 += 3, r1 += 3)
3364 *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize;
3374 * 'format_W()' - Convert image data to luminance.
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 */
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 */
3404 bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2);
3407 bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize);
3411 ptr = row + bitoffset / 8;
3413 switch (header->cupsBitsPerColor)
3416 bitmask = 0x80 >> (bitoffset & 7);
3417 dither = Floyd16x16[y & 15];
3419 for (x = xsize; x > 0; x --)
3421 if (*r0++ > dither[x & 15])
3435 bitmask = 0xc0 >> (bitoffset & 7);
3436 dither = Floyd8x8[y & 7];
3438 for (x = xsize; x > 0; x --)
3440 if ((*r0 & 63) > dither[x & 7])
3441 *ptr ^= (bitmask & OnPixels[*r0++]);
3443 *ptr ^= (bitmask & OffPixels[*r0++]);
3457 bitmask = 0xf0 >> (bitoffset & 7);
3458 dither = Floyd4x4[y & 3];
3460 for (x = xsize; x > 0; x --)
3462 if ((*r0 & 15) > dither[x & 3])
3463 *ptr ^= (bitmask & OnPixels[*r0++]);
3465 *ptr ^= (bitmask & OffPixels[*r0++]);
3467 if (bitmask == 0xf0)
3479 for (x = xsize; x > 0; x --, r0 ++, r1 ++)
3484 *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize;
3492 * 'format_YMC()' - Convert image data to YMC.
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 */
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 */
3524 bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2);
3527 bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize);
3531 ptr = row + bitoffset / 8;
3532 bandwidth = header->cupsBytesPerLine / 3;
3534 switch (header->cupsColorOrder)
3536 case CUPS_ORDER_CHUNKED :
3537 switch (header->cupsBitsPerColor)
3540 bitmask = 64 >> (bitoffset & 7);
3541 dither = Floyd16x16[y & 15];
3543 for (x = xsize ; x > 0; x --, r0 += 3)
3545 if (r0[2] > dither[x & 15])
3549 if (r0[1] > dither[x & 15])
3553 if (r0[0] > dither[x & 15])
3567 dither = Floyd8x8[y & 7];
3569 for (x = xsize ; x > 0; x --, r0 += 3)
3571 if ((r0[2] & 63) > dither[x & 7])
3572 *ptr ^= (0x30 & OnPixels[r0[2]]);
3574 *ptr ^= (0x30 & OffPixels[r0[2]]);
3576 if ((r0[1] & 63) > dither[x & 7])
3577 *ptr ^= (0x0c & OnPixels[r0[1]]);
3579 *ptr ^= (0x0c & OffPixels[r0[1]]);
3581 if ((r0[0] & 63) > dither[x & 7])
3582 *ptr++ ^= (0x03 & OnPixels[r0[0]]);
3584 *ptr++ ^= (0x03 & OffPixels[r0[0]]);
3589 dither = Floyd4x4[y & 3];
3591 for (x = xsize ; x > 0; x --, r0 += 3)
3593 if ((r0[2] & 15) > dither[x & 3])
3594 *ptr++ ^= (0x0f & OnPixels[r0[2]]);
3596 *ptr++ ^= (0x0f & OffPixels[r0[2]]);
3598 if ((r0[1] & 15) > dither[x & 3])
3599 *ptr ^= (0xf0 & OnPixels[r0[1]]);
3601 *ptr ^= (0xf0 & OffPixels[r0[1]]);
3603 if ((r0[0] & 15) > dither[x & 3])
3604 *ptr++ ^= (0x0f & OnPixels[r0[0]]);
3606 *ptr++ ^= (0x0f & OffPixels[r0[0]]);
3611 for (x = xsize; x > 0; x --, r0 += 3, r1 += 3)
3616 *ptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize;
3621 *ptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize;
3626 *ptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize;
3632 case CUPS_ORDER_BANDED :
3634 mptr = ptr + bandwidth;
3635 cptr = ptr + 2 * bandwidth;
3637 switch (header->cupsBitsPerColor)
3640 bitmask = 0x80 >> (bitoffset & 7);
3641 dither = Floyd16x16[y & 15];
3643 for (x = xsize; x > 0; x --)
3645 if (*r0++ > dither[x & 15])
3647 if (*r0++ > dither[x & 15])
3649 if (*r0++ > dither[x & 15])
3665 bitmask = 0xc0 >> (bitoffset & 7);
3666 dither = Floyd8x8[y & 7];
3668 for (x = xsize; x > 0; x --)
3670 if ((*r0 & 63) > dither[x & 7])
3671 *cptr ^= (bitmask & OnPixels[*r0++]);
3673 *cptr ^= (bitmask & OffPixels[*r0++]);
3675 if ((*r0 & 63) > dither[x & 7])
3676 *mptr ^= (bitmask & OnPixels[*r0++]);
3678 *mptr ^= (bitmask & OffPixels[*r0++]);
3680 if ((*r0 & 63) > dither[x & 7])
3681 *yptr ^= (bitmask & OnPixels[*r0++]);
3683 *yptr ^= (bitmask & OffPixels[*r0++]);
3699 bitmask = 0xf0 >> (bitoffset & 7);
3700 dither = Floyd4x4[y & 3];
3702 for (x = xsize; x > 0; x --)
3704 if ((*r0 & 15) > dither[x & 3])
3705 *cptr ^= (bitmask & OnPixels[*r0++]);
3707 *cptr ^= (bitmask & OffPixels[*r0++]);
3709 if ((*r0 & 15) > dither[x & 3])
3710 *mptr ^= (bitmask & OnPixels[*r0++]);
3712 *mptr ^= (bitmask & OffPixels[*r0++]);
3714 if ((*r0 & 15) > dither[x & 3])
3715 *yptr ^= (bitmask & OnPixels[*r0++]);
3717 *yptr ^= (bitmask & OffPixels[*r0++]);
3719 if (bitmask == 0xf0)
3733 for (x = xsize; x > 0; x --, r0 += 3, r1 += 3)
3738 *cptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize;
3743 *mptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize;
3748 *yptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize;
3754 case CUPS_ORDER_PLANAR :
3755 switch (header->cupsBitsPerColor)
3758 bitmask = 0x80 >> (bitoffset & 7);
3759 dither = Floyd16x16[y & 15];
3764 for (x = xsize; x > 0; x --, r0 += 3)
3766 if (r0[0] > dither[x & 15])
3780 for (x = xsize; x > 0; x --, r0 += 3)
3782 if (r0[1] > dither[x & 15])
3796 for (x = xsize; x > 0; x --, r0 += 3)
3798 if (r0[2] > dither[x & 15])
3814 bitmask = 0xc0 >> (bitoffset & 7);
3815 dither = Floyd8x8[y & 7];
3819 for (x = xsize; x > 0; x --, r0 += 3)
3821 if ((*r0 & 63) > dither[x & 7])
3822 *ptr ^= (bitmask & OnPixels[*r0]);
3824 *ptr ^= (bitmask & OffPixels[*r0]);
3838 bitmask = 0xf0 >> (bitoffset & 7);
3839 dither = Floyd4x4[y & 3];
3843 for (x = xsize; x > 0; x --, r0 += 3)
3845 if ((*r0 & 15) > dither[x & 3])
3846 *ptr ^= (bitmask & OnPixels[*r0]);
3848 *ptr ^= (bitmask & OffPixels[*r0]);
3850 if (bitmask == 0xf0)
3866 for (x = xsize; x > 0; x --, r0 += 3, r1 += 3)
3871 *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize;
3881 * 'format_YMCK()' - Convert image data to YMCK.
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 */
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 */
3915 bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2);
3918 bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize);
3922 ptr = row + bitoffset / 8;
3923 bandwidth = header->cupsBytesPerLine / 4;
3925 switch (header->cupsColorOrder)
3927 case CUPS_ORDER_CHUNKED :
3928 switch (header->cupsBitsPerColor)
3931 bitmask = 128 >> (bitoffset & 7);
3932 dither = Floyd16x16[y & 15];
3934 for (x = xsize ; x > 0; x --)
3936 pc = *r0++ > dither[x & 15];
3937 pm = *r0++ > dither[x & 15];
3938 py = *r0++ > dither[x & 15];
3972 dither = Floyd8x8[y & 7];
3974 for (x = xsize ; x > 0; x --, r0 += 4)
3976 if ((r0[2] & 63) > dither[x & 7])
3977 *ptr ^= (0xc0 & OnPixels[r0[2]]);
3979 *ptr ^= (0xc0 & OffPixels[r0[2]]);
3981 if ((r0[1] & 63) > dither[x & 7])
3982 *ptr ^= (0x30 & OnPixels[r0[1]]);
3984 *ptr ^= (0x30 & OffPixels[r0[1]]);
3986 if ((r0[0] & 63) > dither[x & 7])
3987 *ptr ^= (0x0c & OnPixels[r0[0]]);
3989 *ptr ^= (0x0c & OffPixels[r0[0]]);
3991 if ((r0[3] & 63) > dither[x & 7])
3992 *ptr++ ^= (0x03 & OnPixels[r0[3]]);
3994 *ptr++ ^= (0x03 & OffPixels[r0[3]]);
3999 dither = Floyd4x4[y & 3];
4001 for (x = xsize ; x > 0; x --, r0 += 4)
4003 if ((r0[2] & 15) > dither[x & 3])
4004 *ptr ^= (0xf0 & OnPixels[r0[2]]);
4006 *ptr ^= (0xf0 & OffPixels[r0[2]]);
4008 if ((r0[1] & 15) > dither[x & 3])
4009 *ptr++ ^= (0x0f & OnPixels[r0[1]]);
4011 *ptr++ ^= (0x0f & OffPixels[r0[1]]);
4013 if ((r0[0] & 15) > dither[x & 3])
4014 *ptr ^= (0xf0 & OnPixels[r0[0]]);
4016 *ptr ^= (0xf0 & OffPixels[r0[0]]);
4018 if ((r0[3] & 15) > dither[x & 3])
4019 *ptr++ ^= (0x0f & OnPixels[r0[3]]);
4021 *ptr++ ^= (0x0f & OffPixels[r0[3]]);
4026 for (x = xsize; x > 0; x --, r0 += 4, r1 += 4)
4031 *ptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize;
4036 *ptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize;
4041 *ptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize;
4046 *ptr++ = (r0[3] * yerr0 + r1[3] * yerr1) / ysize;
4052 case CUPS_ORDER_BANDED :
4054 mptr = ptr + bandwidth;
4055 cptr = ptr + 2 * bandwidth;
4056 kptr = ptr + 3 * bandwidth;
4058 switch (header->cupsBitsPerColor)
4061 bitmask = 0x80 >> (bitoffset & 7);
4062 dither = Floyd16x16[y & 15];
4064 for (x = xsize; x > 0; x --)
4066 pc = *r0++ > dither[x & 15];
4067 pm = *r0++ > dither[x & 15];
4068 py = *r0++ > dither[x & 15];
4097 bitmask = 0xc0 >> (bitoffset & 7);
4098 dither = Floyd8x8[y & 7];
4100 for (x = xsize; x > 0; x --)
4102 if ((*r0 & 63) > dither[x & 7])
4103 *cptr ^= (bitmask & OnPixels[*r0++]);
4105 *cptr ^= (bitmask & OffPixels[*r0++]);
4107 if ((*r0 & 63) > dither[x & 7])
4108 *mptr ^= (bitmask & OnPixels[*r0++]);
4110 *mptr ^= (bitmask & OffPixels[*r0++]);
4112 if ((*r0 & 63) > dither[x & 7])
4113 *yptr ^= (bitmask & OnPixels[*r0++]);
4115 *yptr ^= (bitmask & OffPixels[*r0++]);
4117 if ((*r0 & 63) > dither[x & 7])
4118 *kptr ^= (bitmask & OnPixels[*r0++]);
4120 *kptr ^= (bitmask & OffPixels[*r0++]);
4137 bitmask = 0xf0 >> (bitoffset & 7);
4138 dither = Floyd4x4[y & 3];
4140 for (x = xsize; x > 0; x --)
4142 if ((*r0 & 15) > dither[x & 3])
4143 *cptr ^= (bitmask & OnPixels[*r0++]);
4145 *cptr ^= (bitmask & OffPixels[*r0++]);
4147 if ((*r0 & 15) > dither[x & 3])
4148 *mptr ^= (bitmask & OnPixels[*r0++]);
4150 *mptr ^= (bitmask & OffPixels[*r0++]);
4152 if ((*r0 & 15) > dither[x & 3])
4153 *yptr ^= (bitmask & OnPixels[*r0++]);
4155 *yptr ^= (bitmask & OffPixels[*r0++]);
4157 if ((*r0 & 15) > dither[x & 3])
4158 *kptr ^= (bitmask & OnPixels[*r0++]);
4160 *kptr ^= (bitmask & OffPixels[*r0++]);
4162 if (bitmask == 0xf0)
4177 for (x = xsize; x > 0; x --, r0 += 4, r1 += 4)
4182 *cptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize;
4187 *mptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize;
4192 *yptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize;
4197 *kptr++ = (r0[3] * yerr0 + r1[3] * yerr1) / ysize;
4203 case CUPS_ORDER_PLANAR :
4204 switch (header->cupsBitsPerColor)
4207 bitmask = 0x80 >> (bitoffset & 7);
4208 dither = Floyd16x16[y & 15];
4210 for (x = xsize; x > 0; x --)
4212 pc = *r0++ > dither[x & 15];
4213 pm = *r0++ > dither[x & 15];
4214 py = *r0++ > dither[x & 15];
4216 if ((pc && pm && py && z == 3) ||
4217 (pc && z == 2) || (pm && z == 1) || (py && z == 0))
4231 bitmask = 0xc0 >> (bitoffset & 7);
4232 dither = Floyd8x8[y & 7];
4238 for (x = xsize; x > 0; x --, r0 += 4)
4240 if ((*r0 & 63) > dither[x & 7])
4241 *ptr ^= (bitmask & OnPixels[*r0]);
4243 *ptr ^= (bitmask & OffPixels[*r0]);
4257 bitmask = 0xf0 >> (bitoffset & 7);
4258 dither = Floyd4x4[y & 3];
4264 for (x = xsize; x > 0; x --, r0 += 4)
4266 if ((*r0 & 15) > dither[x & 3])
4267 *ptr ^= (bitmask & OnPixels[*r0]);
4269 *ptr ^= (bitmask & OffPixels[*r0]);
4271 if (bitmask == 0xf0)
4294 for (x = xsize; x > 0; x --, r0 += 4, r1 += 4)
4299 *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize;
4309 * 'make_lut()' - Make a lookup table given gamma and brightness values.
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 */
4318 int i; /* Looping var */
4319 int v; /* Current value */
4325 for (i = 0; i < 256; i ++)
4328 v = 255.0 * b * (1.0 - pow(1.0 - (float)i / 255.0, g)) + 0.5;
4330 v = 255.0 * (1.0 - b * (1.0 - pow((float)i / 255.0, g))) + 0.5;
4343 * 'raster_cb()' - Validate the page header.
4346 static int /* O - 0 if OK, -1 if not */
4348 cups_page_header2_t *header, /* IO - Raster header */
4349 int preferred_bits) /* I - Preferred bits per color */
4352 * Ensure that colorimetric colorspaces use at least 8 bits per
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;
4367 * End of "$Id: imagetoraster.c 9808 2011-05-26 12:03:28Z mike $".