4 * Image file to raster filter for CUPS.
6 * Copyright 2007-2010 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>
49 int Flip
= 0, /* Flip/mirror pages */
50 XPosition
= 0, /* Horizontal position on page */
51 YPosition
= 0, /* Vertical position on page */
52 Collate
= 0, /* Collate copies? */
53 Copies
= 1; /* Number of copies */
54 int Floyd16x16
[16][16] = /* Traditional Floyd ordered dither */
56 { 0, 128, 32, 160, 8, 136, 40, 168,
57 2, 130, 34, 162, 10, 138, 42, 170 },
58 { 192, 64, 224, 96, 200, 72, 232, 104,
59 194, 66, 226, 98, 202, 74, 234, 106 },
60 { 48, 176, 16, 144, 56, 184, 24, 152,
61 50, 178, 18, 146, 58, 186, 26, 154 },
62 { 240, 112, 208, 80, 248, 120, 216, 88,
63 242, 114, 210, 82, 250, 122, 218, 90 },
64 { 12, 140, 44, 172, 4, 132, 36, 164,
65 14, 142, 46, 174, 6, 134, 38, 166 },
66 { 204, 76, 236, 108, 196, 68, 228, 100,
67 206, 78, 238, 110, 198, 70, 230, 102 },
68 { 60, 188, 28, 156, 52, 180, 20, 148,
69 62, 190, 30, 158, 54, 182, 22, 150 },
70 { 252, 124, 220, 92, 244, 116, 212, 84,
71 254, 126, 222, 94, 246, 118, 214, 86 },
72 { 3, 131, 35, 163, 11, 139, 43, 171,
73 1, 129, 33, 161, 9, 137, 41, 169 },
74 { 195, 67, 227, 99, 203, 75, 235, 107,
75 193, 65, 225, 97, 201, 73, 233, 105 },
76 { 51, 179, 19, 147, 59, 187, 27, 155,
77 49, 177, 17, 145, 57, 185, 25, 153 },
78 { 243, 115, 211, 83, 251, 123, 219, 91,
79 241, 113, 209, 81, 249, 121, 217, 89 },
80 { 15, 143, 47, 175, 7, 135, 39, 167,
81 13, 141, 45, 173, 5, 133, 37, 165 },
82 { 207, 79, 239, 111, 199, 71, 231, 103,
83 205, 77, 237, 109, 197, 69, 229, 101 },
84 { 63, 191, 31, 159, 55, 183, 23, 151,
85 61, 189, 29, 157, 53, 181, 21, 149 },
86 { 254, 127, 223, 95, 247, 119, 215, 87,
87 253, 125, 221, 93, 245, 117, 213, 85 }
91 { 0, 32, 8, 40, 2, 34, 10, 42 },
92 { 48, 16, 56, 24, 50, 18, 58, 26 },
93 { 12, 44, 4, 36, 14, 46, 6, 38 },
94 { 60, 28, 52, 20, 62, 30, 54, 22 },
95 { 3, 35, 11, 43, 1, 33, 9, 41 },
96 { 51, 19, 59, 27, 49, 17, 57, 25 },
97 { 15, 47, 7, 39, 13, 45, 5, 37 },
98 { 63, 31, 55, 23, 61, 29, 53, 21 }
108 cups_ib_t OnPixels
[256], /* On-pixel LUT */
109 OffPixels
[256]; /* Off-pixel LUT */
116 static void blank_line(cups_page_header2_t
*header
, unsigned char *row
);
117 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
);
118 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
);
119 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
);
120 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
);
121 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
);
122 #define format_RGB format_CMY
123 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
);
124 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
);
125 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
);
126 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
);
127 static void make_lut(cups_ib_t
*, int, float, float);
128 static int raster_cb(cups_page_header2_t
*header
, int preferred_bits
);
132 * 'main()' - Main entry...
135 int /* O - Exit status */
136 main(int argc
, /* I - Number of command-line arguments */
137 char *argv
[]) /* I - Command-line arguments */
139 int i
; /* Looping var */
140 cups_image_t
*img
; /* Image to print */
141 float xprint
, /* Printable area */
143 xinches
, /* Total size in inches */
145 float xsize
, /* Total size in points */
149 float aspect
; /* Aspect ratio */
150 int xpages
, /* # x pages */
151 ypages
, /* # y pages */
152 xpage
, /* Current x page */
153 ypage
, /* Current y page */
154 xtemp
, /* Bitmap width in pixels */
155 ytemp
, /* Bitmap height in pixels */
156 page
; /* Current page number */
157 int xc0
, yc0
, /* Corners of the page in image coords */
159 ppd_file_t
*ppd
; /* PPD file */
160 ppd_choice_t
*choice
; /* PPD option choice */
161 char *resolution
, /* Output resolution */
162 *media_type
; /* Media type */
163 ppd_profile_t
*profile
; /* Color profile */
164 ppd_profile_t userprofile
; /* User-specified profile */
165 cups_raster_t
*ras
; /* Raster stream */
166 cups_page_header2_t header
; /* Page header */
167 int num_options
; /* Number of print options */
168 cups_option_t
*options
; /* Print options */
169 const char *val
; /* Option value */
170 int slowcollate
, /* Collate copies the slow way */
171 slowcopies
; /* Make copies the "slow" way? */
172 float g
; /* Gamma correction value */
173 float b
; /* Brightness factor */
174 float zoom
; /* Zoom facter */
175 int xppi
, yppi
; /* Pixels-per-inch */
176 int hue
, sat
; /* Hue and saturation adjustment */
177 cups_izoom_t
*z
; /* Image zoom buffer */
178 cups_iztype_t zoom_type
; /* Image zoom type */
179 int primary
, /* Primary image colorspace */
180 secondary
; /* Secondary image colorspace */
181 cups_ib_t
*row
, /* Current row */
183 *r1
; /* Bottom row */
184 int y
, /* Current Y coordinate on page */
185 iy
, /* Current Y coordinate in image */
186 last_iy
, /* Previous Y coordinate in image */
187 yerr0
, /* Top Y error value */
188 yerr1
; /* Bottom Y error value */
189 cups_ib_t lut
[256]; /* Gamma/brightness LUT */
190 int plane
, /* Current color plane */
191 num_planes
; /* Number of color planes */
192 char filename
[1024]; /* Name of file to print */
196 * Make sure status messages are not buffered...
199 setbuf(stderr
, NULL
);
202 * Check command-line...
205 if (argc
< 6 || argc
> 7)
207 _cupsLangPrintf(stderr
,
208 _("Usage: %s job-id user title copies options file"),
214 * See if we need to use the imagetops and pstoraster filters instead...
218 num_options
= cupsParseOptions(argv
[5], 0, &options
);
220 if (getenv("CLASSIFICATION") ||
221 cupsGetOption("page-label", num_options
, options
))
224 * Yes, fork a copy of pstoraster and then transfer control to imagetops...
227 int mypipes
[2]; /* New pipes for imagetops | pstoraster */
228 int pid
; /* PID of pstoraster */
231 cupsFreeOptions(num_options
, options
);
235 _cupsLangPrintError("ERROR", _("Unable to create pipes for filters"));
239 if ((pid
= fork()) == 0)
242 * Child process for pstoraster... Assign new pipe input to pstoraster...
249 execlp("pstoraster", argv
[0], argv
[1], argv
[2], argv
[3], argv
[4], argv
[5],
259 _cupsLangPrintError("ERROR", _("Unable to fork filter"));
264 * Update stdout so it points at the new pstoraster...
272 * Run imagetops to get the classification or page labeling that was
276 execlp("imagetops", argv
[0], argv
[1], argv
[2], argv
[3], argv
[4], argv
[5],
282 * Copy stdin as needed...
287 int fd
; /* File to write to */
288 char buffer
[8192]; /* Buffer to read into */
289 int bytes
; /* # of bytes to read */
292 if ((fd
= cupsTempFd(filename
, sizeof(filename
))) < 0)
294 _cupsLangPrintError("ERROR", _("Unable to copy print file"));
299 "DEBUG: imagetoraster - copying to temp print file \"%s\".\n",
302 while ((bytes
= fread(buffer
, 1, sizeof(buffer
), stdin
)) > 0)
303 write(fd
, buffer
, bytes
);
308 strlcpy(filename
, argv
[6], sizeof(filename
));
311 * Process command-line options and write the prolog...
322 Copies
= atoi(argv
[4]);
324 ppd
= SetCommonOptions(num_options
, options
, 0);
326 if ((val
= cupsGetOption("multiple-document-handling", num_options
, options
)) != NULL
)
329 * This IPP attribute is unnecessarily complicated...
331 * single-document, separate-documents-collated-copies, and
332 * single-document-new-sheet all require collated copies.
334 * separate-documents-collated-copies allows for uncollated copies.
337 Collate
= strcasecmp(val
, "separate-documents-collated-copies") != 0;
340 if ((val
= cupsGetOption("Collate", num_options
, options
)) != NULL
&&
341 strcasecmp(val
, "True") == 0)
344 if ((val
= cupsGetOption("gamma", num_options
, options
)) != NULL
)
347 * Get gamma value from 1 to 10000...
350 g
= atoi(val
) * 0.001f
;
358 if ((val
= cupsGetOption("brightness", num_options
, options
)) != NULL
)
361 * Get brightness value from 10 to 1000.
364 b
= atoi(val
) * 0.01f
;
372 if ((val
= cupsGetOption("scaling", num_options
, options
)) != NULL
)
373 zoom
= atoi(val
) * 0.01;
374 else if ((val
= cupsGetOption("fitplot", num_options
, options
)) != NULL
&&
375 !strcasecmp(val
, "true"))
377 else if ((val
= cupsGetOption("fit-to-page", num_options
, options
)) != NULL
&&
378 !strcasecmp(val
, "true"))
381 if ((val
= cupsGetOption("ppi", num_options
, options
)) != NULL
)
382 if (sscanf(val
, "%dx%d", &xppi
, &yppi
) < 2)
385 if ((val
= cupsGetOption("position", num_options
, options
)) != NULL
)
387 if (strcasecmp(val
, "center") == 0)
392 else if (strcasecmp(val
, "top") == 0)
397 else if (strcasecmp(val
, "left") == 0)
402 else if (strcasecmp(val
, "right") == 0)
407 else if (strcasecmp(val
, "top-left") == 0)
412 else if (strcasecmp(val
, "top-right") == 0)
417 else if (strcasecmp(val
, "bottom") == 0)
422 else if (strcasecmp(val
, "bottom-left") == 0)
427 else if (strcasecmp(val
, "bottom-right") == 0)
434 if ((val
= cupsGetOption("saturation", num_options
, options
)) != NULL
)
437 if ((val
= cupsGetOption("hue", num_options
, options
)) != NULL
)
440 if ((choice
= ppdFindMarkedChoice(ppd
, "MirrorPrint")) != NULL
)
442 val
= choice
->choice
;
446 val
= cupsGetOption("mirror", num_options
, options
);
448 if (val
&& (!strcasecmp(val
, "true") || !strcasecmp(val
, "on") ||
449 !strcasecmp(val
, "yes")))
453 * Set the needed options in the page header...
456 if (cupsRasterInterpretPPD(&header
, ppd
, num_options
, options
, raster_cb
))
458 _cupsLangPrintFilter(stderr
, "ERROR",
459 _("The page setup information was not valid."));
460 fprintf(stderr
, "DEBUG: %s\n", cupsRasterErrorString());
465 * Get the media type and resolution that have been chosen...
468 if ((choice
= ppdFindMarkedChoice(ppd
, "MediaType")) != NULL
)
469 media_type
= choice
->choice
;
473 if ((choice
= ppdFindMarkedChoice(ppd
, "Resolution")) != NULL
)
474 resolution
= choice
->choice
;
479 * Choose the appropriate colorspace...
482 switch (header
.cupsColorSpace
)
485 case CUPS_CSPACE_SW
:
486 if (header
.cupsBitsPerColor
>= 8)
488 primary
= CUPS_IMAGE_WHITE
;
489 secondary
= CUPS_IMAGE_WHITE
;
493 primary
= CUPS_IMAGE_BLACK
;
494 secondary
= CUPS_IMAGE_BLACK
;
498 case CUPS_CSPACE_RGB
:
499 case CUPS_CSPACE_RGBA
:
500 case CUPS_CSPACE_RGBW
:
501 case CUPS_CSPACE_SRGB
:
502 case CUPS_CSPACE_ADOBERGB
:
503 if (header
.cupsBitsPerColor
>= 8)
505 primary
= CUPS_IMAGE_RGB
;
506 secondary
= CUPS_IMAGE_RGB
;
510 primary
= CUPS_IMAGE_CMY
;
511 secondary
= CUPS_IMAGE_CMY
;
516 case CUPS_CSPACE_WHITE
:
517 case CUPS_CSPACE_GOLD
:
518 case CUPS_CSPACE_SILVER
:
519 primary
= CUPS_IMAGE_BLACK
;
520 secondary
= CUPS_IMAGE_BLACK
;
523 case CUPS_CSPACE_CMYK
:
524 case CUPS_CSPACE_YMCK
:
525 case CUPS_CSPACE_KCMY
:
526 case CUPS_CSPACE_KCMYcm
:
527 case CUPS_CSPACE_GMCK
:
528 case CUPS_CSPACE_GMCS
:
529 if (header
.cupsBitsPerColor
== 1)
531 primary
= CUPS_IMAGE_CMY
;
532 secondary
= CUPS_IMAGE_CMY
;
536 primary
= CUPS_IMAGE_CMYK
;
537 secondary
= CUPS_IMAGE_CMYK
;
541 case CUPS_CSPACE_CMY
:
542 case CUPS_CSPACE_YMC
:
543 primary
= CUPS_IMAGE_CMY
;
544 secondary
= CUPS_IMAGE_CMY
;
547 case CUPS_CSPACE_CIEXYZ
:
548 case CUPS_CSPACE_CIELab
:
549 case CUPS_CSPACE_ICC1
:
550 case CUPS_CSPACE_ICC2
:
551 case CUPS_CSPACE_ICC3
:
552 case CUPS_CSPACE_ICC4
:
553 case CUPS_CSPACE_ICC5
:
554 case CUPS_CSPACE_ICC6
:
555 case CUPS_CSPACE_ICC7
:
556 case CUPS_CSPACE_ICC8
:
557 case CUPS_CSPACE_ICC9
:
558 case CUPS_CSPACE_ICCA
:
559 case CUPS_CSPACE_ICCB
:
560 case CUPS_CSPACE_ICCC
:
561 case CUPS_CSPACE_ICCD
:
562 case CUPS_CSPACE_ICCE
:
563 case CUPS_CSPACE_ICCF
:
564 case CUPS_CSPACE_DEVICE1
:
565 case CUPS_CSPACE_DEVICE2
:
566 case CUPS_CSPACE_DEVICE3
:
567 case CUPS_CSPACE_DEVICE4
:
568 case CUPS_CSPACE_DEVICE5
:
569 case CUPS_CSPACE_DEVICE6
:
570 case CUPS_CSPACE_DEVICE7
:
571 case CUPS_CSPACE_DEVICE8
:
572 case CUPS_CSPACE_DEVICE9
:
573 case CUPS_CSPACE_DEVICEA
:
574 case CUPS_CSPACE_DEVICEB
:
575 case CUPS_CSPACE_DEVICEC
:
576 case CUPS_CSPACE_DEVICED
:
577 case CUPS_CSPACE_DEVICEE
:
578 case CUPS_CSPACE_DEVICEF
:
579 fprintf(stderr
, "DEBUG: Colorspace %d not supported.\n",
580 header
.cupsColorSpace
);
586 * Find a color profile matching the current options...
589 if ((val
= cupsGetOption("profile", num_options
, options
)) != NULL
)
591 profile
= &userprofile
;
592 sscanf(val
, "%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f",
593 &(userprofile
.density
), &(userprofile
.gamma
),
594 userprofile
.matrix
[0] + 0, userprofile
.matrix
[0] + 1,
595 userprofile
.matrix
[0] + 2,
596 userprofile
.matrix
[1] + 0, userprofile
.matrix
[1] + 1,
597 userprofile
.matrix
[1] + 2,
598 userprofile
.matrix
[2] + 0, userprofile
.matrix
[2] + 1,
599 userprofile
.matrix
[2] + 2);
601 userprofile
.density
*= 0.001f
;
602 userprofile
.gamma
*= 0.001f
;
603 userprofile
.matrix
[0][0] *= 0.001f
;
604 userprofile
.matrix
[0][1] *= 0.001f
;
605 userprofile
.matrix
[0][2] *= 0.001f
;
606 userprofile
.matrix
[1][0] *= 0.001f
;
607 userprofile
.matrix
[1][1] *= 0.001f
;
608 userprofile
.matrix
[1][2] *= 0.001f
;
609 userprofile
.matrix
[2][0] *= 0.001f
;
610 userprofile
.matrix
[2][1] *= 0.001f
;
611 userprofile
.matrix
[2][2] *= 0.001f
;
613 else if (ppd
!= NULL
)
615 fprintf(stderr
, "DEBUG: Searching for profile \"%s/%s\"...\n",
616 resolution
, media_type
);
618 for (i
= 0, profile
= ppd
->profiles
; i
< ppd
->num_profiles
; i
++, profile
++)
620 fprintf(stderr
, "DEBUG: \"%s/%s\" = ", profile
->resolution
,
621 profile
->media_type
);
623 if ((strcmp(profile
->resolution
, resolution
) == 0 ||
624 profile
->resolution
[0] == '-') &&
625 (strcmp(profile
->media_type
, media_type
) == 0 ||
626 profile
->media_type
[0] == '-'))
628 fputs("MATCH\n", stderr
);
632 fputs("no.\n", stderr
);
636 * If we found a color profile, use it!
639 if (i
>= ppd
->num_profiles
)
646 cupsImageSetProfile(profile
->density
, profile
->gamma
, profile
->matrix
);
648 cupsImageSetRasterColorSpace(header
.cupsColorSpace
);
651 * Create a gamma/brightness LUT...
654 make_lut(lut
, primary
, g
, b
);
657 * Open the input image to print...
660 _cupsLangPrintFilter(stderr
, "INFO", _("Loading print file."));
662 if (header
.cupsColorSpace
== CUPS_CSPACE_CIEXYZ
||
663 header
.cupsColorSpace
== CUPS_CSPACE_CIELab
||
664 header
.cupsColorSpace
>= CUPS_CSPACE_ICC1
)
665 img
= cupsImageOpen(filename
, primary
, secondary
, sat
, hue
, NULL
);
667 img
= cupsImageOpen(filename
, primary
, secondary
, sat
, hue
, lut
);
674 _cupsLangPrintFilter(stderr
, "ERROR",
675 _("The print file could not be opened."));
681 * Scale as necessary...
684 if (zoom
== 0.0 && xppi
== 0)
693 fprintf(stderr
, "DEBUG: Before scaling: xppi=%d, yppi=%d, zoom=%.2f\n",
699 * Scale the image as neccesary to match the desired pixels-per-inch.
704 xprint
= (PageTop
- PageBottom
) / 72.0;
705 yprint
= (PageRight
- PageLeft
) / 72.0;
709 xprint
= (PageRight
- PageLeft
) / 72.0;
710 yprint
= (PageTop
- PageBottom
) / 72.0;
713 fprintf(stderr
, "DEBUG: Before scaling: xprint=%.1f, yprint=%.1f\n",
716 xinches
= (float)img
->xsize
/ (float)xppi
;
717 yinches
= (float)img
->ysize
/ (float)yppi
;
719 fprintf(stderr
, "DEBUG: Image size is %.1f x %.1f inches...\n",
722 if ((val
= cupsGetOption("natural-scaling", num_options
, options
)) != NULL
)
724 xinches
= xinches
* atoi(val
) / 100;
725 yinches
= yinches
* atoi(val
) / 100;
728 if (cupsGetOption("orientation-requested", num_options
, options
) == NULL
&&
729 cupsGetOption("landscape", num_options
, options
) == NULL
)
732 * Rotate the image if it will fit landscape but not portrait...
735 fputs("DEBUG: Auto orientation...\n", stderr
);
737 if ((xinches
> xprint
|| yinches
> yprint
) &&
738 xinches
<= yprint
&& yinches
<= xprint
)
741 * Rotate the image as needed...
744 fputs("DEBUG: Using landscape orientation...\n", stderr
);
746 Orientation
= (Orientation
+ 1) & 3;
756 * Scale percentage of page size...
759 xprint
= (PageRight
- PageLeft
) / 72.0;
760 yprint
= (PageTop
- PageBottom
) / 72.0;
761 aspect
= (float)img
->yppi
/ (float)img
->xppi
;
763 fprintf(stderr
, "DEBUG: Before scaling: xprint=%.1f, yprint=%.1f\n",
766 fprintf(stderr
, "DEBUG: img->xppi = %d, img->yppi = %d, aspect = %f\n",
767 img
->xppi
, img
->yppi
, aspect
);
769 xsize
= xprint
* zoom
;
770 ysize
= xsize
* img
->ysize
/ img
->xsize
/ aspect
;
772 if (ysize
> (yprint
* zoom
))
774 ysize
= yprint
* zoom
;
775 xsize
= ysize
* img
->xsize
* aspect
/ img
->ysize
;
778 xsize2
= yprint
* zoom
;
779 ysize2
= xsize2
* img
->ysize
/ img
->xsize
/ aspect
;
781 if (ysize2
> (xprint
* zoom
))
783 ysize2
= xprint
* zoom
;
784 xsize2
= ysize2
* img
->xsize
* aspect
/ img
->ysize
;
787 fprintf(stderr
, "DEBUG: Portrait size is %.2f x %.2f inches\n", xsize
, ysize
);
788 fprintf(stderr
, "DEBUG: Landscape size is %.2f x %.2f inches\n", xsize2
, ysize2
);
790 if (cupsGetOption("orientation-requested", num_options
, options
) == NULL
&&
791 cupsGetOption("landscape", num_options
, options
) == NULL
)
794 * Choose the rotation with the largest area, but prefer
795 * portrait if they are equal...
798 fputs("DEBUG: Auto orientation...\n", stderr
);
800 if ((xsize
* ysize
) < (xsize2
* xsize2
))
803 * Do landscape orientation...
806 fputs("DEBUG: Using landscape orientation...\n", stderr
);
811 xprint
= (PageTop
- PageBottom
) / 72.0;
812 yprint
= (PageRight
- PageLeft
) / 72.0;
817 * Do portrait orientation...
820 fputs("DEBUG: Using portrait orientation...\n", stderr
);
827 else if (Orientation
& 1)
829 fputs("DEBUG: Using landscape orientation...\n", stderr
);
833 xprint
= (PageTop
- PageBottom
) / 72.0;
834 yprint
= (PageRight
- PageLeft
) / 72.0;
838 fputs("DEBUG: Using portrait orientation...\n", stderr
);
842 xprint
= (PageRight
- PageLeft
) / 72.0;
843 yprint
= (PageTop
- PageBottom
) / 72.0;
848 * Compute the number of pages to print and the size of the image on each
852 xpages
= ceil(xinches
/ xprint
);
853 ypages
= ceil(yinches
/ yprint
);
855 xprint
= xinches
/ xpages
;
856 yprint
= yinches
/ ypages
;
858 fprintf(stderr
, "DEBUG: xpages = %dx%.2fin, ypages = %dx%.2fin\n",
859 xpages
, xprint
, ypages
, yprint
);
862 * Compute the bitmap size...
865 if ((choice
= ppdFindMarkedChoice(ppd
, "PageSize")) != NULL
&&
866 strcasecmp(choice
->choice
, "Custom") == 0)
868 float width
, /* New width in points */
869 length
; /* New length in points */
873 * Use the correct width and length for the current orientation...
878 width
= yprint
* 72.0;
879 length
= xprint
* 72.0;
883 width
= xprint
* 72.0;
884 length
= yprint
* 72.0;
888 * Add margins to page size...
891 width
+= ppd
->custom_margins
[0] + ppd
->custom_margins
[2];
892 length
+= ppd
->custom_margins
[1] + ppd
->custom_margins
[3];
895 * Enforce minimums...
898 if (width
< ppd
->custom_min
[0])
899 width
= ppd
->custom_min
[0];
901 if (length
< ppd
->custom_min
[1])
902 length
= ppd
->custom_min
[1];
904 fprintf(stderr
, "DEBUG: Updated custom page size to %.2f x %.2f inches...\n",
905 width
/ 72.0, length
/ 72.0);
908 * Set the new custom size...
911 strcpy(header
.cupsPageSizeName
, "Custom");
913 header
.cupsPageSize
[0] = width
+ 0.5;
914 header
.cupsPageSize
[1] = length
+ 0.5;
915 header
.PageSize
[0] = width
+ 0.5;
916 header
.PageSize
[1] = length
+ 0.5;
919 * Update page variables...
924 PageLeft
= ppd
->custom_margins
[0];
925 PageRight
= width
- ppd
->custom_margins
[2];
926 PageBottom
= ppd
->custom_margins
[1];
927 PageTop
= length
- ppd
->custom_margins
[3];
930 * Remove margins from page size...
933 width
-= ppd
->custom_margins
[0] + ppd
->custom_margins
[2];
934 length
-= ppd
->custom_margins
[1] + ppd
->custom_margins
[3];
937 * Set the bitmap size...
940 header
.cupsWidth
= width
* header
.HWResolution
[0] / 72.0;
941 header
.cupsHeight
= length
* header
.HWResolution
[1] / 72.0;
943 header
.cupsBytesPerLine
= (header
.cupsBitsPerPixel
*
944 header
.cupsWidth
+ 7) / 8;
946 if (header
.cupsColorOrder
== CUPS_ORDER_BANDED
)
947 header
.cupsBytesPerLine
*= header
.cupsNumColors
;
950 header
.Margins
[0] = PageLeft
;
951 header
.Margins
[1] = PageBottom
;
953 fprintf(stderr
, "DEBUG: PageSize = [%d %d]\n", header
.PageSize
[0],
962 header
.cupsImagingBBox
[0] = PageLeft
;
963 header
.cupsImagingBBox
[2] = PageLeft
+ xprint
* 72;
966 header
.cupsImagingBBox
[0] = (PageRight
+ PageLeft
- xprint
* 72) / 2;
967 header
.cupsImagingBBox
[2] = (PageRight
+ PageLeft
+ xprint
* 72) / 2;
970 header
.cupsImagingBBox
[0] = PageRight
- xprint
* 72;
971 header
.cupsImagingBBox
[2] = PageRight
;
978 header
.cupsImagingBBox
[1] = PageBottom
;
979 header
.cupsImagingBBox
[3] = PageBottom
+ yprint
* 72;
982 header
.cupsImagingBBox
[1] = (PageTop
+ PageBottom
- yprint
* 72) / 2;
983 header
.cupsImagingBBox
[3] = (PageTop
+ PageBottom
+ yprint
* 72) / 2;
986 header
.cupsImagingBBox
[1] = PageTop
- yprint
* 72;
987 header
.cupsImagingBBox
[3] = PageTop
;
996 header
.cupsImagingBBox
[0] = PageBottom
;
997 header
.cupsImagingBBox
[2] = PageBottom
+ yprint
* 72;
1000 header
.cupsImagingBBox
[0] = (PageTop
+ PageBottom
- yprint
* 72) / 2;
1001 header
.cupsImagingBBox
[2] = (PageTop
+ PageBottom
+ yprint
* 72) / 2;
1004 header
.cupsImagingBBox
[0] = PageTop
- yprint
* 72;
1005 header
.cupsImagingBBox
[2] = PageTop
;
1012 header
.cupsImagingBBox
[1] = PageLeft
;
1013 header
.cupsImagingBBox
[3] = PageLeft
+ xprint
* 72;
1016 header
.cupsImagingBBox
[1] = (PageRight
+ PageLeft
- xprint
* 72) / 2;
1017 header
.cupsImagingBBox
[3] = (PageRight
+ PageLeft
+ xprint
* 72) / 2;
1020 header
.cupsImagingBBox
[1] = PageRight
- xprint
* 72;
1021 header
.cupsImagingBBox
[3] = PageRight
;
1030 header
.cupsImagingBBox
[0] = PageLeft
;
1031 header
.cupsImagingBBox
[2] = PageLeft
+ xprint
* 72;
1034 header
.cupsImagingBBox
[0] = (PageRight
+ PageLeft
- xprint
* 72) / 2;
1035 header
.cupsImagingBBox
[2] = (PageRight
+ PageLeft
+ xprint
* 72) / 2;
1038 header
.cupsImagingBBox
[0] = PageRight
- xprint
* 72;
1039 header
.cupsImagingBBox
[2] = PageRight
;
1046 header
.cupsImagingBBox
[1] = PageBottom
;
1047 header
.cupsImagingBBox
[3] = PageBottom
+ yprint
* 72;
1050 header
.cupsImagingBBox
[1] = (PageTop
+ PageBottom
- yprint
* 72) / 2;
1051 header
.cupsImagingBBox
[3] = (PageTop
+ PageBottom
+ yprint
* 72) / 2;
1054 header
.cupsImagingBBox
[1] = PageTop
- yprint
* 72;
1055 header
.cupsImagingBBox
[3] = PageTop
;
1064 header
.cupsImagingBBox
[0] = PageBottom
;
1065 header
.cupsImagingBBox
[2] = PageBottom
+ yprint
* 72;
1068 header
.cupsImagingBBox
[0] = (PageTop
+ PageBottom
- yprint
* 72) / 2;
1069 header
.cupsImagingBBox
[2] = (PageTop
+ PageBottom
+ yprint
* 72) / 2;
1072 header
.cupsImagingBBox
[0] = PageTop
- yprint
* 72;
1073 header
.cupsImagingBBox
[2] = PageTop
;
1080 header
.cupsImagingBBox
[1] = PageLeft
;
1081 header
.cupsImagingBBox
[3] = PageLeft
+ xprint
* 72;
1084 header
.cupsImagingBBox
[1] = (PageRight
+ PageLeft
- xprint
* 72) / 2;
1085 header
.cupsImagingBBox
[3] = (PageRight
+ PageLeft
+ xprint
* 72) / 2;
1088 header
.cupsImagingBBox
[1] = PageRight
- xprint
* 72;
1089 header
.cupsImagingBBox
[3] = PageRight
;
1095 header
.ImagingBoundingBox
[0] = header
.cupsImagingBBox
[0];
1096 header
.ImagingBoundingBox
[1] = header
.cupsImagingBBox
[1];
1097 header
.ImagingBoundingBox
[2] = header
.cupsImagingBBox
[2];
1098 header
.ImagingBoundingBox
[3] = header
.cupsImagingBBox
[3];
1100 if (header
.cupsColorOrder
== CUPS_ORDER_PLANAR
)
1101 num_planes
= header
.cupsNumColors
;
1105 if (header
.cupsBitsPerColor
>= 8)
1106 zoom_type
= CUPS_IZOOM_NORMAL
;
1108 zoom_type
= CUPS_IZOOM_FAST
;
1111 * See if we need to collate, and if so how we need to do it...
1114 if (xpages
== 1 && ypages
== 1)
1117 slowcollate
= Collate
&& ppdFindOption(ppd
, "Collate") == NULL
;
1119 slowcopies
= ppd
->manual_copies
;
1123 if (Copies
> 1 && !slowcollate
&& !slowcopies
)
1125 header
.Collate
= (cups_bool_t
)Collate
;
1126 header
.NumCopies
= Copies
;
1131 header
.NumCopies
= 1;
1134 * Create the dithering lookup tables...
1138 OnPixels
[255] = 0xff;
1139 OffPixels
[0] = 0x00;
1140 OffPixels
[255] = 0xff;
1142 switch (header
.cupsBitsPerColor
)
1145 for (i
= 1; i
< 255; i
++)
1147 OnPixels
[i
] = 0x55 * (i
/ 85 + 1);
1148 OffPixels
[i
] = 0x55 * (i
/ 64);
1152 for (i
= 1; i
< 255; i
++)
1154 OnPixels
[i
] = 17 * (i
/ 17 + 1);
1155 OffPixels
[i
] = 17 * (i
/ 16);
1161 * Output the pages...
1164 fprintf(stderr
, "DEBUG: cupsWidth = %d\n", header
.cupsWidth
);
1165 fprintf(stderr
, "DEBUG: cupsHeight = %d\n", header
.cupsHeight
);
1166 fprintf(stderr
, "DEBUG: cupsBitsPerColor = %d\n", header
.cupsBitsPerColor
);
1167 fprintf(stderr
, "DEBUG: cupsBitsPerPixel = %d\n", header
.cupsBitsPerPixel
);
1168 fprintf(stderr
, "DEBUG: cupsBytesPerLine = %d\n", header
.cupsBytesPerLine
);
1169 fprintf(stderr
, "DEBUG: cupsColorOrder = %d\n", header
.cupsColorOrder
);
1170 fprintf(stderr
, "DEBUG: cupsColorSpace = %d\n", header
.cupsColorSpace
);
1171 fprintf(stderr
, "DEBUG: img->colorspace = %d\n", img
->colorspace
);
1173 row
= malloc(2 * header
.cupsBytesPerLine
);
1174 ras
= cupsRasterOpen(1, CUPS_RASTER_WRITE
);
1176 for (i
= 0, page
= 1; i
< Copies
; i
++)
1177 for (xpage
= 0; xpage
< xpages
; xpage
++)
1178 for (ypage
= 0; ypage
< ypages
; ypage
++, page
++)
1180 _cupsLangPrintFilter(stderr
, "INFO", _("Formatting page %d."), page
);
1182 if (Orientation
& 1)
1184 xc0
= img
->xsize
* ypage
/ ypages
;
1185 xc1
= img
->xsize
* (ypage
+ 1) / ypages
- 1;
1186 yc0
= img
->ysize
* xpage
/ xpages
;
1187 yc1
= img
->ysize
* (xpage
+ 1) / xpages
- 1;
1189 xtemp
= header
.HWResolution
[0] * yprint
;
1190 ytemp
= header
.HWResolution
[1] * xprint
;
1194 xc0
= img
->xsize
* xpage
/ xpages
;
1195 xc1
= img
->xsize
* (xpage
+ 1) / xpages
- 1;
1196 yc0
= img
->ysize
* ypage
/ ypages
;
1197 yc1
= img
->ysize
* (ypage
+ 1) / ypages
- 1;
1199 xtemp
= header
.HWResolution
[0] * xprint
;
1200 ytemp
= header
.HWResolution
[1] * yprint
;
1203 cupsRasterWriteHeader2(ras
, &header
);
1205 for (plane
= 0; plane
< num_planes
; plane
++)
1208 * Initialize the image "zoom" engine...
1212 z
= _cupsImageZoomNew(img
, xc0
, yc0
, xc1
, yc1
, -xtemp
, ytemp
,
1213 Orientation
& 1, zoom_type
);
1215 z
= _cupsImageZoomNew(img
, xc0
, yc0
, xc1
, yc1
, xtemp
, ytemp
,
1216 Orientation
& 1, zoom_type
);
1219 * Write leading blank space as needed...
1222 if (header
.cupsHeight
> z
->ysize
&& YPosition
<= 0)
1224 blank_line(&header
, row
);
1226 y
= header
.cupsHeight
- z
->ysize
;
1230 fprintf(stderr
, "DEBUG: Writing %d leading blank lines...\n", y
);
1234 if (cupsRasterWritePixels(ras
, row
, header
.cupsBytesPerLine
) <
1235 header
.cupsBytesPerLine
)
1237 _cupsLangPrintFilter(stderr
, "ERROR",
1238 _("Unable to send raster data to the "
1240 cupsImageClose(img
);
1247 * Then write image data...
1250 for (y
= z
->ysize
, yerr0
= 0, yerr1
= z
->ysize
, iy
= 0, last_iy
= -2;
1256 if (zoom_type
!= CUPS_IZOOM_FAST
&& (iy
- last_iy
) > 1)
1257 _cupsImageZoomFill(z
, iy
);
1259 _cupsImageZoomFill(z
, iy
+ z
->yincr
);
1265 * Format this line of raster data for the printer...
1268 blank_line(&header
, row
);
1270 r0
= z
->rows
[z
->row
];
1271 r1
= z
->rows
[1 - z
->row
];
1273 switch (header
.cupsColorSpace
)
1275 case CUPS_CSPACE_W
:
1276 format_W(&header
, row
, y
, plane
, z
->xsize
, z
->ysize
,
1277 yerr0
, yerr1
, r0
, r1
);
1280 case CUPS_CSPACE_RGB
:
1281 format_RGB(&header
, row
, y
, plane
, z
->xsize
, z
->ysize
,
1282 yerr0
, yerr1
, r0
, r1
);
1284 case CUPS_CSPACE_RGBA
:
1285 case CUPS_CSPACE_RGBW
:
1286 format_RGBA(&header
, row
, y
, plane
, z
->xsize
, z
->ysize
,
1287 yerr0
, yerr1
, r0
, r1
);
1289 case CUPS_CSPACE_K
:
1290 case CUPS_CSPACE_WHITE
:
1291 case CUPS_CSPACE_GOLD
:
1292 case CUPS_CSPACE_SILVER
:
1293 format_K(&header
, row
, y
, plane
, z
->xsize
, z
->ysize
,
1294 yerr0
, yerr1
, r0
, r1
);
1296 case CUPS_CSPACE_CMY
:
1297 format_CMY(&header
, row
, y
, plane
, z
->xsize
, z
->ysize
,
1298 yerr0
, yerr1
, r0
, r1
);
1300 case CUPS_CSPACE_YMC
:
1301 format_YMC(&header
, row
, y
, plane
, z
->xsize
, z
->ysize
,
1302 yerr0
, yerr1
, r0
, r1
);
1304 case CUPS_CSPACE_CMYK
:
1305 format_CMYK(&header
, row
, y
, plane
, z
->xsize
, z
->ysize
,
1306 yerr0
, yerr1
, r0
, r1
);
1308 case CUPS_CSPACE_YMCK
:
1309 case CUPS_CSPACE_GMCK
:
1310 case CUPS_CSPACE_GMCS
:
1311 format_YMCK(&header
, row
, y
, plane
, z
->xsize
, z
->ysize
,
1312 yerr0
, yerr1
, r0
, r1
);
1314 case CUPS_CSPACE_KCMYcm
:
1315 if (header
.cupsBitsPerColor
== 1)
1317 format_KCMYcm(&header
, row
, y
, plane
, z
->xsize
, z
->ysize
,
1318 yerr0
, yerr1
, r0
, r1
);
1321 case CUPS_CSPACE_KCMY
:
1322 format_KCMY(&header
, row
, y
, plane
, z
->xsize
, z
->ysize
,
1323 yerr0
, yerr1
, r0
, r1
);
1328 * Write the raster data to the driver...
1331 if (cupsRasterWritePixels(ras
, row
, header
.cupsBytesPerLine
) <
1332 header
.cupsBytesPerLine
)
1334 _cupsLangPrintFilter(stderr
, "ERROR",
1335 _("Unable to send raster data to the "
1337 cupsImageClose(img
);
1342 * Compute the next scanline in the image...
1357 * Write trailing blank space as needed...
1360 if (header
.cupsHeight
> z
->ysize
&& YPosition
>= 0)
1362 blank_line(&header
, row
);
1364 y
= header
.cupsHeight
- z
->ysize
;
1368 fprintf(stderr
, "DEBUG: Writing %d trailing blank lines...\n", y
);
1372 if (cupsRasterWritePixels(ras
, row
, header
.cupsBytesPerLine
) <
1373 header
.cupsBytesPerLine
)
1375 _cupsLangPrintFilter(stderr
, "ERROR",
1376 _("Unable to send raster data to the "
1378 cupsImageClose(img
);
1385 * Free memory used for the "zoom" engine...
1388 _cupsImageZoomDelete(z
);
1397 cupsRasterClose(ras
);
1398 cupsImageClose(img
);
1406 * 'blank_line()' - Clear a line buffer to the blank value...
1410 blank_line(cups_page_header2_t
*header
, /* I - Page header */
1411 unsigned char *row
) /* I - Row buffer */
1413 int count
; /* Remaining bytes */
1416 count
= header
->cupsBytesPerLine
;
1418 switch (header
->cupsColorSpace
)
1420 case CUPS_CSPACE_CIEXYZ
:
1430 case CUPS_CSPACE_CIELab
:
1431 case CUPS_CSPACE_ICC1
:
1432 case CUPS_CSPACE_ICC2
:
1433 case CUPS_CSPACE_ICC3
:
1434 case CUPS_CSPACE_ICC4
:
1435 case CUPS_CSPACE_ICC5
:
1436 case CUPS_CSPACE_ICC6
:
1437 case CUPS_CSPACE_ICC7
:
1438 case CUPS_CSPACE_ICC8
:
1439 case CUPS_CSPACE_ICC9
:
1440 case CUPS_CSPACE_ICCA
:
1441 case CUPS_CSPACE_ICCB
:
1442 case CUPS_CSPACE_ICCC
:
1443 case CUPS_CSPACE_ICCD
:
1444 case CUPS_CSPACE_ICCE
:
1445 case CUPS_CSPACE_ICCF
:
1455 case CUPS_CSPACE_K
:
1456 case CUPS_CSPACE_CMY
:
1457 case CUPS_CSPACE_CMYK
:
1458 case CUPS_CSPACE_YMC
:
1459 case CUPS_CSPACE_YMCK
:
1460 case CUPS_CSPACE_KCMY
:
1461 case CUPS_CSPACE_KCMYcm
:
1462 case CUPS_CSPACE_GMCK
:
1463 case CUPS_CSPACE_GMCS
:
1464 case CUPS_CSPACE_WHITE
:
1465 case CUPS_CSPACE_GOLD
:
1466 case CUPS_CSPACE_SILVER
:
1467 memset(row
, 0, count
);
1471 memset(row
, 255, count
);
1478 * 'format_CMY()' - Convert image data to CMY.
1482 format_CMY(cups_page_header2_t
*header
, /* I - Page header */
1483 unsigned char *row
, /* IO - Bitmap data for device */
1484 int y
, /* I - Current row */
1485 int z
, /* I - Current plane */
1486 int xsize
, /* I - Width of image data */
1487 int ysize
, /* I - Height of image data */
1488 int yerr0
, /* I - Top Y error */
1489 int yerr1
, /* I - Bottom Y error */
1490 cups_ib_t
*r0
, /* I - Primary image data */
1491 cups_ib_t
*r1
) /* I - Image data for interpolation */
1493 cups_ib_t
*ptr
, /* Pointer into row */
1494 *cptr
, /* Pointer into cyan */
1495 *mptr
, /* Pointer into magenta */
1496 *yptr
, /* Pointer into yellow */
1497 bitmask
; /* Current mask for pixel */
1498 int bitoffset
; /* Current offset in line */
1499 int bandwidth
; /* Width of a color band */
1500 int x
, /* Current X coordinate on page */
1501 *dither
; /* Pointer into dither array */
1510 bitoffset
= header
->cupsBitsPerPixel
* ((header
->cupsWidth
- xsize
) / 2);
1513 bitoffset
= header
->cupsBitsPerPixel
* (header
->cupsWidth
- xsize
);
1517 ptr
= row
+ bitoffset
/ 8;
1518 bandwidth
= header
->cupsBytesPerLine
/ 3;
1520 switch (header
->cupsColorOrder
)
1522 case CUPS_ORDER_CHUNKED
:
1523 switch (header
->cupsBitsPerColor
)
1526 bitmask
= 64 >> (bitoffset
& 7);
1527 dither
= Floyd16x16
[y
& 15];
1529 for (x
= xsize
; x
> 0; x
--)
1531 if (*r0
++ > dither
[x
& 15])
1535 if (*r0
++ > dither
[x
& 15])
1539 if (*r0
++ > dither
[x
& 15])
1553 dither
= Floyd8x8
[y
& 7];
1555 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
1557 if ((r0
[0] & 63) > dither
[x
& 7])
1558 *ptr
^= (0x30 & OnPixels
[r0
[0]]);
1560 *ptr
^= (0x30 & OffPixels
[r0
[0]]);
1562 if ((r0
[1] & 63) > dither
[x
& 7])
1563 *ptr
^= (0x0c & OnPixels
[r0
[1]]);
1565 *ptr
^= (0x0c & OffPixels
[r0
[1]]);
1567 if ((r0
[2] & 63) > dither
[x
& 7])
1568 *ptr
++ ^= (0x03 & OnPixels
[r0
[2]]);
1570 *ptr
++ ^= (0x03 & OffPixels
[r0
[2]]);
1575 dither
= Floyd4x4
[y
& 3];
1577 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
1579 if ((r0
[0] & 15) > dither
[x
& 3])
1580 *ptr
++ ^= (0x0f & OnPixels
[r0
[0]]);
1582 *ptr
++ ^= (0x0f & OffPixels
[r0
[0]]);
1584 if ((r0
[1] & 15) > dither
[x
& 3])
1585 *ptr
^= (0xf0 & OnPixels
[r0
[1]]);
1587 *ptr
^= (0xf0 & OffPixels
[r0
[1]]);
1589 if ((r0
[2] & 15) > dither
[x
& 3])
1590 *ptr
++ ^= (0x0f & OnPixels
[r0
[2]]);
1592 *ptr
++ ^= (0x0f & OffPixels
[r0
[2]]);
1597 for (x
= xsize
* 3; x
> 0; x
--, r0
++, r1
++)
1601 *ptr
++ = (*r0
* yerr0
+ *r1
* yerr1
) / ysize
;
1606 case CUPS_ORDER_BANDED
:
1608 mptr
= ptr
+ bandwidth
;
1609 yptr
= ptr
+ 2 * bandwidth
;
1611 switch (header
->cupsBitsPerColor
)
1614 bitmask
= 0x80 >> (bitoffset
& 7);
1615 dither
= Floyd16x16
[y
& 15];
1617 for (x
= xsize
; x
> 0; x
--)
1619 if (*r0
++ > dither
[x
& 15])
1621 if (*r0
++ > dither
[x
& 15])
1623 if (*r0
++ > dither
[x
& 15])
1639 bitmask
= 0xc0 >> (bitoffset
& 7);
1640 dither
= Floyd8x8
[y
& 7];
1642 for (x
= xsize
; x
> 0; x
--)
1644 if ((*r0
& 63) > dither
[x
& 7])
1645 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
1647 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
1649 if ((*r0
& 63) > dither
[x
& 7])
1650 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
1652 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
1654 if ((*r0
& 63) > dither
[x
& 7])
1655 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
1657 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
1673 bitmask
= 0xf0 >> (bitoffset
& 7);
1674 dither
= Floyd4x4
[y
& 3];
1676 for (x
= xsize
; x
> 0; x
--)
1678 if ((*r0
& 15) > dither
[x
& 3])
1679 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
1681 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
1683 if ((*r0
& 15) > dither
[x
& 3])
1684 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
1686 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
1688 if ((*r0
& 15) > dither
[x
& 3])
1689 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
1691 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
1693 if (bitmask
== 0xf0)
1707 for (x
= xsize
; x
> 0; x
--, r0
+= 3, r1
+= 3)
1712 *cptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
1717 *mptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
1722 *yptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
1728 case CUPS_ORDER_PLANAR
:
1729 switch (header
->cupsBitsPerColor
)
1732 bitmask
= 0x80 >> (bitoffset
& 7);
1733 dither
= Floyd16x16
[y
& 15];
1738 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
1740 if (r0
[0] > dither
[x
& 15])
1754 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
1756 if (r0
[1] > dither
[x
& 15])
1770 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
1772 if (r0
[2] > dither
[x
& 15])
1788 bitmask
= 0xc0 >> (bitoffset
& 7);
1789 dither
= Floyd8x8
[y
& 7];
1792 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
1794 if ((*r0
& 63) > dither
[x
& 7])
1795 *ptr
^= (bitmask
& OnPixels
[*r0
]);
1797 *ptr
^= (bitmask
& OffPixels
[*r0
]);
1811 bitmask
= 0xf0 >> (bitoffset
& 7);
1812 dither
= Floyd4x4
[y
& 3];
1815 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
1817 if ((*r0
& 15) > dither
[x
& 3])
1818 *ptr
^= (bitmask
& OnPixels
[*r0
]);
1820 *ptr
^= (bitmask
& OffPixels
[*r0
]);
1822 if (bitmask
== 0xf0)
1837 for (x
= xsize
; x
> 0; x
--, r0
+= 3, r1
+= 3)
1842 *ptr
++ = (*r0
* yerr0
+ *r1
* yerr1
) / ysize
;
1852 * 'format_CMYK()' - Convert image data to CMYK.
1856 format_CMYK(cups_page_header2_t
*header
,/* I - Page header */
1857 unsigned char *row
, /* IO - Bitmap data for device */
1858 int y
, /* I - Current row */
1859 int z
, /* I - Current plane */
1860 int xsize
, /* I - Width of image data */
1861 int ysize
, /* I - Height of image data */
1862 int yerr0
, /* I - Top Y error */
1863 int yerr1
, /* I - Bottom Y error */
1864 cups_ib_t
*r0
, /* I - Primary image data */
1865 cups_ib_t
*r1
) /* I - Image data for interpolation */
1867 cups_ib_t
*ptr
, /* Pointer into row */
1868 *cptr
, /* Pointer into cyan */
1869 *mptr
, /* Pointer into magenta */
1870 *yptr
, /* Pointer into yellow */
1871 *kptr
, /* Pointer into black */
1872 bitmask
; /* Current mask for pixel */
1873 int bitoffset
; /* Current offset in line */
1874 int bandwidth
; /* Width of a color band */
1875 int x
, /* Current X coordinate on page */
1876 *dither
; /* Pointer into dither array */
1877 int pc
, pm
, py
; /* CMY pixels */
1886 bitoffset
= header
->cupsBitsPerPixel
* ((header
->cupsWidth
- xsize
) / 2);
1889 bitoffset
= header
->cupsBitsPerPixel
* (header
->cupsWidth
- xsize
);
1893 ptr
= row
+ bitoffset
/ 8;
1894 bandwidth
= header
->cupsBytesPerLine
/ 4;
1896 switch (header
->cupsColorOrder
)
1898 case CUPS_ORDER_CHUNKED
:
1899 switch (header
->cupsBitsPerColor
)
1902 bitmask
= 128 >> (bitoffset
& 7);
1903 dither
= Floyd16x16
[y
& 15];
1905 for (x
= xsize
; x
> 0; x
--)
1907 pc
= *r0
++ > dither
[x
& 15];
1908 pm
= *r0
++ > dither
[x
& 15];
1909 py
= *r0
++ > dither
[x
& 15];
1942 dither
= Floyd8x8
[y
& 7];
1944 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
1946 if ((r0
[0] & 63) > dither
[x
& 7])
1947 *ptr
^= (0xc0 & OnPixels
[r0
[0]]);
1949 *ptr
^= (0xc0 & OffPixels
[r0
[0]]);
1951 if ((r0
[1] & 63) > dither
[x
& 7])
1952 *ptr
^= (0x30 & OnPixels
[r0
[1]]);
1954 *ptr
^= (0x30 & OffPixels
[r0
[1]]);
1956 if ((r0
[2] & 63) > dither
[x
& 7])
1957 *ptr
^= (0x0c & OnPixels
[r0
[2]]);
1959 *ptr
^= (0x0c & OffPixels
[r0
[2]]);
1961 if ((r0
[3] & 63) > dither
[x
& 7])
1962 *ptr
++ ^= (0x03 & OnPixels
[r0
[3]]);
1964 *ptr
++ ^= (0x03 & OffPixels
[r0
[3]]);
1969 dither
= Floyd4x4
[y
& 3];
1971 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
1973 if ((r0
[0] & 15) > dither
[x
& 3])
1974 *ptr
^= (0xf0 & OnPixels
[r0
[0]]);
1976 *ptr
^= (0xf0 & OffPixels
[r0
[0]]);
1978 if ((r0
[1] & 15) > dither
[x
& 3])
1979 *ptr
++ ^= (0x0f & OnPixels
[r0
[1]]);
1981 *ptr
++ ^= (0x0f & OffPixels
[r0
[1]]);
1983 if ((r0
[2] & 15) > dither
[x
& 3])
1984 *ptr
^= (0xf0 & OnPixels
[r0
[2]]);
1986 *ptr
^= (0xf0 & OffPixels
[r0
[2]]);
1988 if ((r0
[3] & 15) > dither
[x
& 3])
1989 *ptr
++ ^= (0x0f & OnPixels
[r0
[3]]);
1991 *ptr
++ ^= (0x0f & OffPixels
[r0
[3]]);
1996 for (x
= xsize
* 4; x
> 0; x
--, r0
++, r1
++)
2000 *ptr
++ = (*r0
* yerr0
+ *r1
* yerr1
) / ysize
;
2005 case CUPS_ORDER_BANDED
:
2007 mptr
= ptr
+ bandwidth
;
2008 yptr
= ptr
+ 2 * bandwidth
;
2009 kptr
= ptr
+ 3 * bandwidth
;
2011 switch (header
->cupsBitsPerColor
)
2014 bitmask
= 0x80 >> (bitoffset
& 7);
2015 dither
= Floyd16x16
[y
& 15];
2017 for (x
= xsize
; x
> 0; x
--)
2019 pc
= *r0
++ > dither
[x
& 15];
2020 pm
= *r0
++ > dither
[x
& 15];
2021 py
= *r0
++ > dither
[x
& 15];
2049 bitmask
= 0xc0 >> (bitoffset
& 7);
2050 dither
= Floyd8x8
[y
& 7];
2052 for (x
= xsize
; x
> 0; x
--)
2054 if ((*r0
& 63) > dither
[x
& 7])
2055 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
2057 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
2059 if ((*r0
& 63) > dither
[x
& 7])
2060 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
2062 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
2064 if ((*r0
& 63) > dither
[x
& 7])
2065 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
2067 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
2069 if ((*r0
& 63) > dither
[x
& 7])
2070 *kptr
^= (bitmask
& OnPixels
[*r0
++]);
2072 *kptr
^= (bitmask
& OffPixels
[*r0
++]);
2089 bitmask
= 0xf0 >> (bitoffset
& 7);
2090 dither
= Floyd4x4
[y
& 3];
2092 for (x
= xsize
; x
> 0; x
--)
2094 if ((*r0
& 15) > dither
[x
& 3])
2095 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
2097 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
2099 if ((*r0
& 15) > dither
[x
& 3])
2100 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
2102 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
2104 if ((*r0
& 15) > dither
[x
& 3])
2105 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
2107 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
2109 if ((*r0
& 15) > dither
[x
& 3])
2110 *kptr
^= (bitmask
& OnPixels
[*r0
++]);
2112 *kptr
^= (bitmask
& OffPixels
[*r0
++]);
2114 if (bitmask
== 0xf0)
2129 for (x
= xsize
; x
> 0; x
--, r0
+= 4, r1
+= 4)
2134 *cptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
2139 *mptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
2144 *yptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
2149 *kptr
++ = (r0
[3] * yerr0
+ r1
[3] * yerr1
) / ysize
;
2155 case CUPS_ORDER_PLANAR
:
2156 switch (header
->cupsBitsPerColor
)
2159 bitmask
= 0x80 >> (bitoffset
& 7);
2160 dither
= Floyd16x16
[y
& 15];
2162 for (x
= xsize
; x
> 0; x
--)
2164 pc
= *r0
++ > dither
[x
& 15];
2165 pm
= *r0
++ > dither
[x
& 15];
2166 py
= *r0
++ > dither
[x
& 15];
2168 if ((pc
&& pm
&& py
&& z
== 3) ||
2169 (pc
&& z
== 0) || (pm
&& z
== 1) || (py
&& z
== 2))
2183 bitmask
= 0xc0 >> (bitoffset
& 7);
2184 dither
= Floyd8x8
[y
& 7];
2187 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
2189 if ((*r0
& 63) > dither
[x
& 7])
2190 *ptr
^= (bitmask
& OnPixels
[*r0
]);
2192 *ptr
^= (bitmask
& OffPixels
[*r0
]);
2206 bitmask
= 0xf0 >> (bitoffset
& 7);
2207 dither
= Floyd4x4
[y
& 3];
2210 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
2212 if ((*r0
& 15) > dither
[x
& 3])
2213 *ptr
^= (bitmask
& OnPixels
[*r0
]);
2215 *ptr
^= (bitmask
& OffPixels
[*r0
]);
2217 if (bitmask
== 0xf0)
2232 for (x
= xsize
; x
> 0; x
--, r0
+= 4, r1
+= 4)
2237 *ptr
++ = (*r0
* yerr0
+ *r1
* yerr1
) / ysize
;
2247 * 'format_K()' - Convert image data to black.
2251 format_K(cups_page_header2_t
*header
, /* I - Page header */
2252 unsigned char *row
, /* IO - Bitmap data for device */
2253 int y
, /* I - Current row */
2254 int z
, /* I - Current plane */
2255 int xsize
, /* I - Width of image data */
2256 int ysize
, /* I - Height of image data */
2257 int yerr0
, /* I - Top Y error */
2258 int yerr1
, /* I - Bottom Y error */
2259 cups_ib_t
*r0
, /* I - Primary image data */
2260 cups_ib_t
*r1
) /* I - Image data for interpolation */
2262 cups_ib_t
*ptr
, /* Pointer into row */
2263 bitmask
; /* Current mask for pixel */
2264 int bitoffset
; /* Current offset in line */
2265 int x
, /* Current X coordinate on page */
2266 *dither
; /* Pointer into dither array */
2277 bitoffset
= header
->cupsBitsPerPixel
* ((header
->cupsWidth
- xsize
) / 2);
2280 bitoffset
= header
->cupsBitsPerPixel
* (header
->cupsWidth
- xsize
);
2284 ptr
= row
+ bitoffset
/ 8;
2286 switch (header
->cupsBitsPerColor
)
2289 bitmask
= 0x80 >> (bitoffset
& 7);
2290 dither
= Floyd16x16
[y
& 15];
2292 for (x
= xsize
; x
> 0; x
--)
2294 if (*r0
++ > dither
[x
& 15])
2308 bitmask
= 0xc0 >> (bitoffset
& 7);
2309 dither
= Floyd8x8
[y
& 7];
2311 for (x
= xsize
; x
> 0; x
--)
2313 if ((*r0
& 63) > dither
[x
& 7])
2314 *ptr
^= (bitmask
& OnPixels
[*r0
++]);
2316 *ptr
^= (bitmask
& OffPixels
[*r0
++]);
2330 bitmask
= 0xf0 >> (bitoffset
& 7);
2331 dither
= Floyd4x4
[y
& 3];
2333 for (x
= xsize
; x
> 0; x
--)
2335 if ((*r0
& 15) > dither
[x
& 3])
2336 *ptr
^= (bitmask
& OnPixels
[*r0
++]);
2338 *ptr
^= (bitmask
& OffPixels
[*r0
++]);
2340 if (bitmask
== 0xf0)
2352 for (x
= xsize
; x
> 0; x
--, r0
++, r1
++)
2357 *ptr
++ = (*r0
* yerr0
+ *r1
* yerr1
) / ysize
;
2365 * 'format_KCMY()' - Convert image data to KCMY.
2369 format_KCMY(cups_page_header2_t
*header
,/* I - Page header */
2370 unsigned char *row
, /* IO - Bitmap data for device */
2371 int y
, /* I - Current row */
2372 int z
, /* I - Current plane */
2373 int xsize
, /* I - Width of image data */
2374 int ysize
, /* I - Height of image data */
2375 int yerr0
, /* I - Top Y error */
2376 int yerr1
, /* I - Bottom Y error */
2377 cups_ib_t
*r0
, /* I - Primary image data */
2378 cups_ib_t
*r1
) /* I - Image data for interpolation */
2380 cups_ib_t
*ptr
, /* Pointer into row */
2381 *cptr
, /* Pointer into cyan */
2382 *mptr
, /* Pointer into magenta */
2383 *yptr
, /* Pointer into yellow */
2384 *kptr
, /* Pointer into black */
2385 bitmask
; /* Current mask for pixel */
2386 int bitoffset
; /* Current offset in line */
2387 int bandwidth
; /* Width of a color band */
2388 int x
, /* Current X coordinate on page */
2389 *dither
; /* Pointer into dither array */
2390 int pc
, pm
, py
; /* CMY pixels */
2399 bitoffset
= header
->cupsBitsPerPixel
* ((header
->cupsWidth
- xsize
) / 2);
2402 bitoffset
= header
->cupsBitsPerPixel
* (header
->cupsWidth
- xsize
);
2406 ptr
= row
+ bitoffset
/ 8;
2407 bandwidth
= header
->cupsBytesPerLine
/ 4;
2409 switch (header
->cupsColorOrder
)
2411 case CUPS_ORDER_CHUNKED
:
2412 switch (header
->cupsBitsPerColor
)
2415 bitmask
= 128 >> (bitoffset
& 7);
2416 dither
= Floyd16x16
[y
& 15];
2418 for (x
= xsize
; x
> 0; x
--)
2420 pc
= *r0
++ > dither
[x
& 15];
2421 pm
= *r0
++ > dither
[x
& 15];
2422 py
= *r0
++ > dither
[x
& 15];
2455 dither
= Floyd8x8
[y
& 7];
2457 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
2459 if ((r0
[3] & 63) > dither
[x
& 7])
2460 *ptr
^= (0xc0 & OnPixels
[r0
[3]]);
2462 *ptr
^= (0xc0 & OffPixels
[r0
[3]]);
2464 if ((r0
[0] & 63) > dither
[x
& 7])
2465 *ptr
^= (0x30 & OnPixels
[r0
[0]]);
2467 *ptr
^= (0x30 & OffPixels
[r0
[0]]);
2469 if ((r0
[1] & 63) > dither
[x
& 7])
2470 *ptr
^= (0x0c & OnPixels
[r0
[1]]);
2472 *ptr
^= (0x0c & OffPixels
[r0
[1]]);
2474 if ((r0
[2] & 63) > dither
[x
& 7])
2475 *ptr
++ ^= (0x03 & OnPixels
[r0
[2]]);
2477 *ptr
++ ^= (0x03 & OffPixels
[r0
[2]]);
2482 dither
= Floyd4x4
[y
& 3];
2484 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
2486 if ((r0
[3] & 15) > dither
[x
& 3])
2487 *ptr
^= (0xf0 & OnPixels
[r0
[3]]);
2489 *ptr
^= (0xf0 & OffPixels
[r0
[3]]);
2491 if ((r0
[0] & 15) > dither
[x
& 3])
2492 *ptr
++ ^= (0x0f & OnPixels
[r0
[0]]);
2494 *ptr
++ ^= (0x0f & OffPixels
[r0
[0]]);
2496 if ((r0
[1] & 15) > dither
[x
& 3])
2497 *ptr
^= (0xf0 & OnPixels
[r0
[1]]);
2499 *ptr
^= (0xf0 & OffPixels
[r0
[1]]);
2501 if ((r0
[2] & 15) > dither
[x
& 3])
2502 *ptr
++ ^= (0x0f & OnPixels
[r0
[2]]);
2504 *ptr
++ ^= (0x0f & OffPixels
[r0
[2]]);
2509 for (x
= xsize
; x
> 0; x
--, r0
+= 4, r1
+= 4)
2514 *ptr
++ = (r0
[3] * yerr0
+ r1
[3] * yerr1
) / ysize
;
2519 *ptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
2524 *ptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
2529 *ptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
2535 case CUPS_ORDER_BANDED
:
2537 cptr
= ptr
+ bandwidth
;
2538 mptr
= ptr
+ 2 * bandwidth
;
2539 yptr
= ptr
+ 3 * bandwidth
;
2541 switch (header
->cupsBitsPerColor
)
2544 bitmask
= 0x80 >> (bitoffset
& 7);
2545 dither
= Floyd16x16
[y
& 15];
2547 for (x
= xsize
; x
> 0; x
--)
2549 pc
= *r0
++ > dither
[x
& 15];
2550 pm
= *r0
++ > dither
[x
& 15];
2551 py
= *r0
++ > dither
[x
& 15];
2579 bitmask
= 0xc0 >> (bitoffset
& 7);
2580 dither
= Floyd8x8
[y
& 7];
2582 for (x
= xsize
; x
> 0; x
--)
2584 if ((*r0
& 63) > dither
[x
& 7])
2585 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
2587 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
2589 if ((*r0
& 63) > dither
[x
& 7])
2590 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
2592 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
2594 if ((*r0
& 63) > dither
[x
& 7])
2595 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
2597 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
2599 if ((*r0
& 63) > dither
[x
& 7])
2600 *kptr
^= (bitmask
& OnPixels
[*r0
++]);
2602 *kptr
^= (bitmask
& OffPixels
[*r0
++]);
2619 bitmask
= 0xf0 >> (bitoffset
& 7);
2620 dither
= Floyd4x4
[y
& 3];
2622 for (x
= xsize
; x
> 0; x
--)
2624 if ((*r0
& 15) > dither
[x
& 3])
2625 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
2627 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
2629 if ((*r0
& 15) > dither
[x
& 3])
2630 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
2632 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
2634 if ((*r0
& 15) > dither
[x
& 3])
2635 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
2637 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
2639 if ((*r0
& 15) > dither
[x
& 3])
2640 *kptr
^= (bitmask
& OnPixels
[*r0
++]);
2642 *kptr
^= (bitmask
& OffPixels
[*r0
++]);
2644 if (bitmask
== 0xf0)
2659 for (x
= xsize
; x
> 0; x
--, r0
+= 4, r1
+= 4)
2664 *cptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
2669 *mptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
2674 *yptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
2679 *kptr
++ = (r0
[3] * yerr0
+ r1
[3] * yerr1
) / ysize
;
2685 case CUPS_ORDER_PLANAR
:
2686 switch (header
->cupsBitsPerColor
)
2689 bitmask
= 0x80 >> (bitoffset
& 7);
2690 dither
= Floyd16x16
[y
& 15];
2692 for (x
= xsize
; x
> 0; x
--)
2694 pc
= *r0
++ > dither
[x
& 15];
2695 pm
= *r0
++ > dither
[x
& 15];
2696 py
= *r0
++ > dither
[x
& 15];
2698 if ((pc
&& pm
&& py
&& z
== 0) ||
2699 (pc
&& z
== 1) || (pm
&& z
== 2) || (py
&& z
== 3))
2713 bitmask
= 0xc0 >> (bitoffset
& 7);
2714 dither
= Floyd8x8
[y
& 7];
2720 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
2722 if ((*r0
& 63) > dither
[x
& 7])
2723 *ptr
^= (bitmask
& OnPixels
[*r0
]);
2725 *ptr
^= (bitmask
& OffPixels
[*r0
]);
2739 bitmask
= 0xf0 >> (bitoffset
& 7);
2740 dither
= Floyd4x4
[y
& 3];
2746 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
2748 if ((*r0
& 15) > dither
[x
& 3])
2749 *ptr
^= (bitmask
& OnPixels
[*r0
]);
2751 *ptr
^= (bitmask
& OffPixels
[*r0
]);
2753 if (bitmask
== 0xf0)
2776 for (x
= xsize
; x
> 0; x
--, r0
+= 4, r1
+= 4)
2781 *ptr
++ = (*r0
* yerr0
+ *r1
* yerr1
) / ysize
;
2791 * 'format_KCMYcm()' - Convert image data to KCMYcm.
2796 cups_page_header2_t
*header
, /* I - Page header */
2797 unsigned char *row
, /* IO - Bitmap data for device */
2798 int y
, /* I - Current row */
2799 int z
, /* I - Current plane */
2800 int xsize
, /* I - Width of image data */
2801 int ysize
, /* I - Height of image data */
2802 int yerr0
, /* I - Top Y error */
2803 int yerr1
, /* I - Bottom Y error */
2804 cups_ib_t
*r0
, /* I - Primary image data */
2805 cups_ib_t
*r1
) /* I - Image data for interpolation */
2807 int pc
, pm
, py
, pk
; /* Cyan, magenta, yellow, and black values */
2808 cups_ib_t
*ptr
, /* Pointer into row */
2809 *cptr
, /* Pointer into cyan */
2810 *mptr
, /* Pointer into magenta */
2811 *yptr
, /* Pointer into yellow */
2812 *kptr
, /* Pointer into black */
2813 *lcptr
, /* Pointer into light cyan */
2814 *lmptr
, /* Pointer into light magenta */
2815 bitmask
; /* Current mask for pixel */
2816 int bitoffset
; /* Current offset in line */
2817 int bandwidth
; /* Width of a color band */
2818 int x
, /* Current X coordinate on page */
2819 *dither
; /* Pointer into dither array */
2828 bitoffset
= header
->cupsBitsPerPixel
* ((header
->cupsWidth
- xsize
) / 2);
2831 bitoffset
= header
->cupsBitsPerPixel
* (header
->cupsWidth
- xsize
);
2835 ptr
= row
+ bitoffset
/ 8;
2836 bandwidth
= header
->cupsBytesPerLine
/ 6;
2838 switch (header
->cupsColorOrder
)
2840 case CUPS_ORDER_CHUNKED
:
2841 dither
= Floyd16x16
[y
& 15];
2843 for (x
= xsize
; x
> 0; x
--)
2845 pc
= *r0
++ > dither
[x
& 15];
2846 pm
= *r0
++ > dither
[x
& 15];
2847 py
= *r0
++ > dither
[x
& 15];
2848 pk
= pc
&& pm
&& py
;
2851 *ptr
++ ^= 32; /* Black */
2853 *ptr
++ ^= 17; /* Blue (cyan + light magenta) */
2855 *ptr
++ ^= 6; /* Green (light cyan + yellow) */
2857 *ptr
++ ^= 12; /* Red (magenta + yellow) */
2869 case CUPS_ORDER_BANDED
:
2871 cptr
= ptr
+ bandwidth
;
2872 mptr
= ptr
+ 2 * bandwidth
;
2873 yptr
= ptr
+ 3 * bandwidth
;
2874 lcptr
= ptr
+ 4 * bandwidth
;
2875 lmptr
= ptr
+ 5 * bandwidth
;
2877 bitmask
= 0x80 >> (bitoffset
& 7);
2878 dither
= Floyd16x16
[y
& 15];
2880 for (x
= xsize
; x
> 0; x
--)
2882 pc
= *r0
++ > dither
[x
& 15];
2883 pm
= *r0
++ > dither
[x
& 15];
2884 py
= *r0
++ > dither
[x
& 15];
2885 pk
= pc
&& pm
&& py
;
2888 *kptr
^= bitmask
; /* Black */
2891 *cptr
^= bitmask
; /* Blue (cyan + light magenta) */
2896 *lcptr
^= bitmask
; /* Green (light cyan + yellow) */
2901 *mptr
^= bitmask
; /* Red (magenta + yellow) */
2926 case CUPS_ORDER_PLANAR
:
2927 bitmask
= 0x80 >> (bitoffset
& 7);
2928 dither
= Floyd16x16
[y
& 15];
2930 for (x
= xsize
; x
> 0; x
--)
2932 pc
= *r0
++ > dither
[x
& 15];
2933 pm
= *r0
++ > dither
[x
& 15];
2934 py
= *r0
++ > dither
[x
& 15];
2935 pk
= pc
&& pm
&& py
;
2939 else if (pc
&& pm
&& (z
== 1 || z
== 5))
2940 *ptr
^= bitmask
; /* Blue (cyan + light magenta) */
2941 else if (pc
&& py
&& (z
== 3 || z
== 4))
2942 *ptr
^= bitmask
; /* Green (light cyan + yellow) */
2943 else if (pm
&& py
&& (z
== 2 || z
== 3))
2944 *ptr
^= bitmask
; /* Red (magenta + yellow) */
2945 else if (pc
&& z
== 1)
2947 else if (pm
&& z
== 2)
2949 else if (py
&& z
== 3)
2966 * 'format_RGBA()' - Convert image data to RGBA/RGBW.
2970 format_RGBA(cups_page_header2_t
*header
,/* I - Page header */
2971 unsigned char *row
, /* IO - Bitmap data for device */
2972 int y
, /* I - Current row */
2973 int z
, /* I - Current plane */
2974 int xsize
, /* I - Width of image data */
2975 int ysize
, /* I - Height of image data */
2976 int yerr0
, /* I - Top Y error */
2977 int yerr1
, /* I - Bottom Y error */
2978 cups_ib_t
*r0
, /* I - Primary image data */
2979 cups_ib_t
*r1
) /* I - Image data for interpolation */
2981 cups_ib_t
*ptr
, /* Pointer into row */
2982 *cptr
, /* Pointer into cyan */
2983 *mptr
, /* Pointer into magenta */
2984 *yptr
, /* Pointer into yellow */
2985 bitmask
; /* Current mask for pixel */
2986 int bitoffset
; /* Current offset in line */
2987 int bandwidth
; /* Width of a color band */
2988 int x
, /* Current X coordinate on page */
2989 *dither
; /* Pointer into dither array */
2998 bitoffset
= header
->cupsBitsPerPixel
* ((header
->cupsWidth
- xsize
) / 2);
3001 bitoffset
= header
->cupsBitsPerPixel
* (header
->cupsWidth
- xsize
);
3005 ptr
= row
+ bitoffset
/ 8;
3006 bandwidth
= header
->cupsBytesPerLine
/ 4;
3008 switch (header
->cupsColorOrder
)
3010 case CUPS_ORDER_CHUNKED
:
3011 switch (header
->cupsBitsPerColor
)
3014 bitmask
= 128 >> (bitoffset
& 7);
3015 dither
= Floyd16x16
[y
& 15];
3017 for (x
= xsize
; x
> 0; x
--)
3019 if (*r0
++ > dither
[x
& 15])
3023 if (*r0
++ > dither
[x
& 15])
3027 if (*r0
++ > dither
[x
& 15])
3041 dither
= Floyd8x8
[y
& 7];
3043 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3045 if ((r0
[0] & 63) > dither
[x
& 7])
3046 *ptr
^= (0xc0 & OnPixels
[r0
[0]]);
3048 *ptr
^= (0xc0 & OffPixels
[r0
[0]]);
3050 if ((r0
[1] & 63) > dither
[x
& 7])
3051 *ptr
^= (0x30 & OnPixels
[r0
[1]]);
3053 *ptr
^= (0x30 & OffPixels
[r0
[1]]);
3055 if ((r0
[2] & 63) > dither
[x
& 7])
3056 *ptr
^= (0x0c & OnPixels
[r0
[2]]);
3058 *ptr
^= (0x0c & OffPixels
[r0
[2]]);
3065 dither
= Floyd4x4
[y
& 3];
3067 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3069 if ((r0
[0] & 15) > dither
[x
& 3])
3070 *ptr
^= (0xf0 & OnPixels
[r0
[0]]);
3072 *ptr
^= (0xf0 & OffPixels
[r0
[0]]);
3074 if ((r0
[1] & 15) > dither
[x
& 3])
3075 *ptr
++ ^= (0x0f & OnPixels
[r0
[1]]);
3077 *ptr
++ ^= (0x0f & OffPixels
[r0
[1]]);
3079 if ((r0
[2] & 15) > dither
[x
& 3])
3080 *ptr
^= (0xf0 & OnPixels
[r0
[2]]);
3082 *ptr
^= (0xf0 & OffPixels
[r0
[2]]);
3089 for (x
= xsize
; x
> 0; x
--, r0
+= 3, r1
+= 3)
3094 *ptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
3099 *ptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
3104 *ptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
3112 case CUPS_ORDER_BANDED
:
3114 mptr
= ptr
+ bandwidth
;
3115 yptr
= ptr
+ 2 * bandwidth
;
3117 memset(ptr
+ 3 * bandwidth
, 255, bandwidth
);
3119 switch (header
->cupsBitsPerColor
)
3122 bitmask
= 0x80 >> (bitoffset
& 7);
3123 dither
= Floyd16x16
[y
& 15];
3125 for (x
= xsize
; x
> 0; x
--)
3127 if (*r0
++ > dither
[x
& 15])
3129 if (*r0
++ > dither
[x
& 15])
3131 if (*r0
++ > dither
[x
& 15])
3147 bitmask
= 0xc0 >> (bitoffset
& 7);
3148 dither
= Floyd8x8
[y
& 7];
3150 for (x
= xsize
; x
> 0; x
--)
3152 if ((*r0
& 63) > dither
[x
& 7])
3153 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
3155 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
3157 if ((*r0
& 63) > dither
[x
& 7])
3158 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
3160 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
3162 if ((*r0
& 63) > dither
[x
& 7])
3163 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
3165 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
3181 bitmask
= 0xf0 >> (bitoffset
& 7);
3182 dither
= Floyd4x4
[y
& 3];
3184 for (x
= xsize
; x
> 0; x
--)
3186 if ((*r0
& 15) > dither
[x
& 3])
3187 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
3189 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
3191 if ((*r0
& 15) > dither
[x
& 3])
3192 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
3194 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
3196 if ((*r0
& 15) > dither
[x
& 3])
3197 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
3199 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
3201 if (bitmask
== 0xf0)
3215 for (x
= xsize
; x
> 0; x
--, r0
+= 3, r1
+= 3)
3220 *cptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
3225 *mptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
3230 *yptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
3236 case CUPS_ORDER_PLANAR
:
3239 memset(row
, 255, header
->cupsBytesPerLine
);
3243 switch (header
->cupsBitsPerColor
)
3246 bitmask
= 0x80 >> (bitoffset
& 7);
3247 dither
= Floyd16x16
[y
& 15];
3252 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3254 if (r0
[0] > dither
[x
& 15])
3268 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3270 if (r0
[1] > dither
[x
& 15])
3284 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3286 if (r0
[2] > dither
[x
& 15])
3302 bitmask
= 0xc0 >> (bitoffset
& 7);
3303 dither
= Floyd8x8
[y
& 7];
3306 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3308 if ((*r0
& 63) > dither
[x
& 7])
3309 *ptr
^= (bitmask
& OnPixels
[*r0
]);
3311 *ptr
^= (bitmask
& OffPixels
[*r0
]);
3325 bitmask
= 0xf0 >> (bitoffset
& 7);
3326 dither
= Floyd4x4
[y
& 3];
3329 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3331 if ((*r0
& 15) > dither
[x
& 3])
3332 *ptr
^= (bitmask
& OnPixels
[*r0
]);
3334 *ptr
^= (bitmask
& OffPixels
[*r0
]);
3336 if (bitmask
== 0xf0)
3351 for (x
= xsize
; x
> 0; x
--, r0
+= 3, r1
+= 3)
3356 *ptr
++ = (*r0
* yerr0
+ *r1
* yerr1
) / ysize
;
3366 * 'format_W()' - Convert image data to luminance.
3370 format_W(cups_page_header2_t
*header
, /* I - Page header */
3371 unsigned char *row
, /* IO - Bitmap data for device */
3372 int y
, /* I - Current row */
3373 int z
, /* I - Current plane */
3374 int xsize
, /* I - Width of image data */
3375 int ysize
, /* I - Height of image data */
3376 int yerr0
, /* I - Top Y error */
3377 int yerr1
, /* I - Bottom Y error */
3378 cups_ib_t
*r0
, /* I - Primary image data */
3379 cups_ib_t
*r1
) /* I - Image data for interpolation */
3381 cups_ib_t
*ptr
, /* Pointer into row */
3382 bitmask
; /* Current mask for pixel */
3383 int bitoffset
; /* Current offset in line */
3384 int x
, /* Current X coordinate on page */
3385 *dither
; /* Pointer into dither array */
3396 bitoffset
= header
->cupsBitsPerPixel
* ((header
->cupsWidth
- xsize
) / 2);
3399 bitoffset
= header
->cupsBitsPerPixel
* (header
->cupsWidth
- xsize
);
3403 ptr
= row
+ bitoffset
/ 8;
3405 switch (header
->cupsBitsPerColor
)
3408 bitmask
= 0x80 >> (bitoffset
& 7);
3409 dither
= Floyd16x16
[y
& 15];
3411 for (x
= xsize
; x
> 0; x
--)
3413 if (*r0
++ > dither
[x
& 15])
3427 bitmask
= 0xc0 >> (bitoffset
& 7);
3428 dither
= Floyd8x8
[y
& 7];
3430 for (x
= xsize
; x
> 0; x
--)
3432 if ((*r0
& 63) > dither
[x
& 7])
3433 *ptr
^= (bitmask
& OnPixels
[*r0
++]);
3435 *ptr
^= (bitmask
& OffPixels
[*r0
++]);
3449 bitmask
= 0xf0 >> (bitoffset
& 7);
3450 dither
= Floyd4x4
[y
& 3];
3452 for (x
= xsize
; x
> 0; x
--)
3454 if ((*r0
& 15) > dither
[x
& 3])
3455 *ptr
^= (bitmask
& OnPixels
[*r0
++]);
3457 *ptr
^= (bitmask
& OffPixels
[*r0
++]);
3459 if (bitmask
== 0xf0)
3471 for (x
= xsize
; x
> 0; x
--, r0
++, r1
++)
3476 *ptr
++ = (*r0
* yerr0
+ *r1
* yerr1
) / ysize
;
3484 * 'format_YMC()' - Convert image data to YMC.
3488 format_YMC(cups_page_header2_t
*header
, /* I - Page header */
3489 unsigned char *row
, /* IO - Bitmap data for device */
3490 int y
, /* I - Current row */
3491 int z
, /* I - Current plane */
3492 int xsize
, /* I - Width of image data */
3493 int ysize
, /* I - Height of image data */
3494 int yerr0
, /* I - Top Y error */
3495 int yerr1
, /* I - Bottom Y error */
3496 cups_ib_t
*r0
, /* I - Primary image data */
3497 cups_ib_t
*r1
) /* I - Image data for interpolation */
3499 cups_ib_t
*ptr
, /* Pointer into row */
3500 *cptr
, /* Pointer into cyan */
3501 *mptr
, /* Pointer into magenta */
3502 *yptr
, /* Pointer into yellow */
3503 bitmask
; /* Current mask for pixel */
3504 int bitoffset
; /* Current offset in line */
3505 int bandwidth
; /* Width of a color band */
3506 int x
, /* Current X coordinate on page */
3507 *dither
; /* Pointer into dither array */
3516 bitoffset
= header
->cupsBitsPerPixel
* ((header
->cupsWidth
- xsize
) / 2);
3519 bitoffset
= header
->cupsBitsPerPixel
* (header
->cupsWidth
- xsize
);
3523 ptr
= row
+ bitoffset
/ 8;
3524 bandwidth
= header
->cupsBytesPerLine
/ 3;
3526 switch (header
->cupsColorOrder
)
3528 case CUPS_ORDER_CHUNKED
:
3529 switch (header
->cupsBitsPerColor
)
3532 bitmask
= 64 >> (bitoffset
& 7);
3533 dither
= Floyd16x16
[y
& 15];
3535 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3537 if (r0
[2] > dither
[x
& 15])
3541 if (r0
[1] > dither
[x
& 15])
3545 if (r0
[0] > dither
[x
& 15])
3559 dither
= Floyd8x8
[y
& 7];
3561 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3563 if ((r0
[2] & 63) > dither
[x
& 7])
3564 *ptr
^= (0x30 & OnPixels
[r0
[2]]);
3566 *ptr
^= (0x30 & OffPixels
[r0
[2]]);
3568 if ((r0
[1] & 63) > dither
[x
& 7])
3569 *ptr
^= (0x0c & OnPixels
[r0
[1]]);
3571 *ptr
^= (0x0c & OffPixels
[r0
[1]]);
3573 if ((r0
[0] & 63) > dither
[x
& 7])
3574 *ptr
++ ^= (0x03 & OnPixels
[r0
[0]]);
3576 *ptr
++ ^= (0x03 & OffPixels
[r0
[0]]);
3581 dither
= Floyd4x4
[y
& 3];
3583 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3585 if ((r0
[2] & 15) > dither
[x
& 3])
3586 *ptr
++ ^= (0x0f & OnPixels
[r0
[2]]);
3588 *ptr
++ ^= (0x0f & OffPixels
[r0
[2]]);
3590 if ((r0
[1] & 15) > dither
[x
& 3])
3591 *ptr
^= (0xf0 & OnPixels
[r0
[1]]);
3593 *ptr
^= (0xf0 & OffPixels
[r0
[1]]);
3595 if ((r0
[0] & 15) > dither
[x
& 3])
3596 *ptr
++ ^= (0x0f & OnPixels
[r0
[0]]);
3598 *ptr
++ ^= (0x0f & OffPixels
[r0
[0]]);
3603 for (x
= xsize
; x
> 0; x
--, r0
+= 3, r1
+= 3)
3608 *ptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
3613 *ptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
3618 *ptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
3624 case CUPS_ORDER_BANDED
:
3626 mptr
= ptr
+ bandwidth
;
3627 cptr
= ptr
+ 2 * bandwidth
;
3629 switch (header
->cupsBitsPerColor
)
3632 bitmask
= 0x80 >> (bitoffset
& 7);
3633 dither
= Floyd16x16
[y
& 15];
3635 for (x
= xsize
; x
> 0; x
--)
3637 if (*r0
++ > dither
[x
& 15])
3639 if (*r0
++ > dither
[x
& 15])
3641 if (*r0
++ > dither
[x
& 15])
3657 bitmask
= 0xc0 >> (bitoffset
& 7);
3658 dither
= Floyd8x8
[y
& 7];
3660 for (x
= xsize
; x
> 0; x
--)
3662 if ((*r0
& 63) > dither
[x
& 7])
3663 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
3665 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
3667 if ((*r0
& 63) > dither
[x
& 7])
3668 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
3670 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
3672 if ((*r0
& 63) > dither
[x
& 7])
3673 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
3675 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
3691 bitmask
= 0xf0 >> (bitoffset
& 7);
3692 dither
= Floyd4x4
[y
& 3];
3694 for (x
= xsize
; x
> 0; x
--)
3696 if ((*r0
& 15) > dither
[x
& 3])
3697 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
3699 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
3701 if ((*r0
& 15) > dither
[x
& 3])
3702 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
3704 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
3706 if ((*r0
& 15) > dither
[x
& 3])
3707 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
3709 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
3711 if (bitmask
== 0xf0)
3725 for (x
= xsize
; x
> 0; x
--, r0
+= 3, r1
+= 3)
3730 *cptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
3735 *mptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
3740 *yptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
3746 case CUPS_ORDER_PLANAR
:
3747 switch (header
->cupsBitsPerColor
)
3750 bitmask
= 0x80 >> (bitoffset
& 7);
3751 dither
= Floyd16x16
[y
& 15];
3756 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3758 if (r0
[0] > dither
[x
& 15])
3772 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3774 if (r0
[1] > dither
[x
& 15])
3788 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3790 if (r0
[2] > dither
[x
& 15])
3806 bitmask
= 0xc0 >> (bitoffset
& 7);
3807 dither
= Floyd8x8
[y
& 7];
3811 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3813 if ((*r0
& 63) > dither
[x
& 7])
3814 *ptr
^= (bitmask
& OnPixels
[*r0
]);
3816 *ptr
^= (bitmask
& OffPixels
[*r0
]);
3830 bitmask
= 0xf0 >> (bitoffset
& 7);
3831 dither
= Floyd4x4
[y
& 3];
3835 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3837 if ((*r0
& 15) > dither
[x
& 3])
3838 *ptr
^= (bitmask
& OnPixels
[*r0
]);
3840 *ptr
^= (bitmask
& OffPixels
[*r0
]);
3842 if (bitmask
== 0xf0)
3858 for (x
= xsize
; x
> 0; x
--, r0
+= 3, r1
+= 3)
3863 *ptr
++ = (*r0
* yerr0
+ *r1
* yerr1
) / ysize
;
3873 * 'format_YMCK()' - Convert image data to YMCK.
3877 format_YMCK(cups_page_header2_t
*header
,/* I - Page header */
3878 unsigned char *row
, /* IO - Bitmap data for device */
3879 int y
, /* I - Current row */
3880 int z
, /* I - Current plane */
3881 int xsize
, /* I - Width of image data */
3882 int ysize
, /* I - Height of image data */
3883 int yerr0
, /* I - Top Y error */
3884 int yerr1
, /* I - Bottom Y error */
3885 cups_ib_t
*r0
, /* I - Primary image data */
3886 cups_ib_t
*r1
) /* I - Image data for interpolation */
3888 cups_ib_t
*ptr
, /* Pointer into row */
3889 *cptr
, /* Pointer into cyan */
3890 *mptr
, /* Pointer into magenta */
3891 *yptr
, /* Pointer into yellow */
3892 *kptr
, /* Pointer into black */
3893 bitmask
; /* Current mask for pixel */
3894 int bitoffset
; /* Current offset in line */
3895 int bandwidth
; /* Width of a color band */
3896 int x
, /* Current X coordinate on page */
3897 *dither
; /* Pointer into dither array */
3898 int pc
, pm
, py
; /* CMY pixels */
3907 bitoffset
= header
->cupsBitsPerPixel
* ((header
->cupsWidth
- xsize
) / 2);
3910 bitoffset
= header
->cupsBitsPerPixel
* (header
->cupsWidth
- xsize
);
3914 ptr
= row
+ bitoffset
/ 8;
3915 bandwidth
= header
->cupsBytesPerLine
/ 4;
3917 switch (header
->cupsColorOrder
)
3919 case CUPS_ORDER_CHUNKED
:
3920 switch (header
->cupsBitsPerColor
)
3923 bitmask
= 128 >> (bitoffset
& 7);
3924 dither
= Floyd16x16
[y
& 15];
3926 for (x
= xsize
; x
> 0; x
--)
3928 pc
= *r0
++ > dither
[x
& 15];
3929 pm
= *r0
++ > dither
[x
& 15];
3930 py
= *r0
++ > dither
[x
& 15];
3964 dither
= Floyd8x8
[y
& 7];
3966 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
3968 if ((r0
[2] & 63) > dither
[x
& 7])
3969 *ptr
^= (0xc0 & OnPixels
[r0
[2]]);
3971 *ptr
^= (0xc0 & OffPixels
[r0
[2]]);
3973 if ((r0
[1] & 63) > dither
[x
& 7])
3974 *ptr
^= (0x30 & OnPixels
[r0
[1]]);
3976 *ptr
^= (0x30 & OffPixels
[r0
[1]]);
3978 if ((r0
[0] & 63) > dither
[x
& 7])
3979 *ptr
^= (0x0c & OnPixels
[r0
[0]]);
3981 *ptr
^= (0x0c & OffPixels
[r0
[0]]);
3983 if ((r0
[3] & 63) > dither
[x
& 7])
3984 *ptr
++ ^= (0x03 & OnPixels
[r0
[3]]);
3986 *ptr
++ ^= (0x03 & OffPixels
[r0
[3]]);
3991 dither
= Floyd4x4
[y
& 3];
3993 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
3995 if ((r0
[2] & 15) > dither
[x
& 3])
3996 *ptr
^= (0xf0 & OnPixels
[r0
[2]]);
3998 *ptr
^= (0xf0 & OffPixels
[r0
[2]]);
4000 if ((r0
[1] & 15) > dither
[x
& 3])
4001 *ptr
++ ^= (0x0f & OnPixels
[r0
[1]]);
4003 *ptr
++ ^= (0x0f & OffPixels
[r0
[1]]);
4005 if ((r0
[0] & 15) > dither
[x
& 3])
4006 *ptr
^= (0xf0 & OnPixels
[r0
[0]]);
4008 *ptr
^= (0xf0 & OffPixels
[r0
[0]]);
4010 if ((r0
[3] & 15) > dither
[x
& 3])
4011 *ptr
++ ^= (0x0f & OnPixels
[r0
[3]]);
4013 *ptr
++ ^= (0x0f & OffPixels
[r0
[3]]);
4018 for (x
= xsize
; x
> 0; x
--, r0
+= 4, r1
+= 4)
4023 *ptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
4028 *ptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
4033 *ptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
4038 *ptr
++ = (r0
[3] * yerr0
+ r1
[3] * yerr1
) / ysize
;
4044 case CUPS_ORDER_BANDED
:
4046 mptr
= ptr
+ bandwidth
;
4047 cptr
= ptr
+ 2 * bandwidth
;
4048 kptr
= ptr
+ 3 * bandwidth
;
4050 switch (header
->cupsBitsPerColor
)
4053 bitmask
= 0x80 >> (bitoffset
& 7);
4054 dither
= Floyd16x16
[y
& 15];
4056 for (x
= xsize
; x
> 0; x
--)
4058 pc
= *r0
++ > dither
[x
& 15];
4059 pm
= *r0
++ > dither
[x
& 15];
4060 py
= *r0
++ > dither
[x
& 15];
4089 bitmask
= 0xc0 >> (bitoffset
& 7);
4090 dither
= Floyd8x8
[y
& 7];
4092 for (x
= xsize
; x
> 0; x
--)
4094 if ((*r0
& 63) > dither
[x
& 7])
4095 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
4097 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
4099 if ((*r0
& 63) > dither
[x
& 7])
4100 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
4102 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
4104 if ((*r0
& 63) > dither
[x
& 7])
4105 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
4107 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
4109 if ((*r0
& 63) > dither
[x
& 7])
4110 *kptr
^= (bitmask
& OnPixels
[*r0
++]);
4112 *kptr
^= (bitmask
& OffPixels
[*r0
++]);
4129 bitmask
= 0xf0 >> (bitoffset
& 7);
4130 dither
= Floyd4x4
[y
& 3];
4132 for (x
= xsize
; x
> 0; x
--)
4134 if ((*r0
& 15) > dither
[x
& 3])
4135 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
4137 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
4139 if ((*r0
& 15) > dither
[x
& 3])
4140 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
4142 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
4144 if ((*r0
& 15) > dither
[x
& 3])
4145 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
4147 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
4149 if ((*r0
& 15) > dither
[x
& 3])
4150 *kptr
^= (bitmask
& OnPixels
[*r0
++]);
4152 *kptr
^= (bitmask
& OffPixels
[*r0
++]);
4154 if (bitmask
== 0xf0)
4169 for (x
= xsize
; x
> 0; x
--, r0
+= 4, r1
+= 4)
4174 *cptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
4179 *mptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
4184 *yptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
4189 *kptr
++ = (r0
[3] * yerr0
+ r1
[3] * yerr1
) / ysize
;
4195 case CUPS_ORDER_PLANAR
:
4196 switch (header
->cupsBitsPerColor
)
4199 bitmask
= 0x80 >> (bitoffset
& 7);
4200 dither
= Floyd16x16
[y
& 15];
4202 for (x
= xsize
; x
> 0; x
--)
4204 pc
= *r0
++ > dither
[x
& 15];
4205 pm
= *r0
++ > dither
[x
& 15];
4206 py
= *r0
++ > dither
[x
& 15];
4208 if ((pc
&& pm
&& py
&& z
== 3) ||
4209 (pc
&& z
== 2) || (pm
&& z
== 1) || (py
&& z
== 0))
4223 bitmask
= 0xc0 >> (bitoffset
& 7);
4224 dither
= Floyd8x8
[y
& 7];
4230 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
4232 if ((*r0
& 63) > dither
[x
& 7])
4233 *ptr
^= (bitmask
& OnPixels
[*r0
]);
4235 *ptr
^= (bitmask
& OffPixels
[*r0
]);
4249 bitmask
= 0xf0 >> (bitoffset
& 7);
4250 dither
= Floyd4x4
[y
& 3];
4256 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
4258 if ((*r0
& 15) > dither
[x
& 3])
4259 *ptr
^= (bitmask
& OnPixels
[*r0
]);
4261 *ptr
^= (bitmask
& OffPixels
[*r0
]);
4263 if (bitmask
== 0xf0)
4286 for (x
= xsize
; x
> 0; x
--, r0
+= 4, r1
+= 4)
4291 *ptr
++ = (*r0
* yerr0
+ *r1
* yerr1
) / ysize
;
4301 * 'make_lut()' - Make a lookup table given gamma and brightness values.
4305 make_lut(cups_ib_t
*lut
, /* I - Lookup table */
4306 int colorspace
, /* I - Colorspace */
4307 float g
, /* I - Image gamma */
4308 float b
) /* I - Image brightness */
4310 int i
; /* Looping var */
4311 int v
; /* Current value */
4317 for (i
= 0; i
< 256; i
++)
4320 v
= 255.0 * b
* (1.0 - pow(1.0 - (float)i
/ 255.0, g
)) + 0.5;
4322 v
= 255.0 * (1.0 - b
* (1.0 - pow((float)i
/ 255.0, g
))) + 0.5;
4335 * 'raster_cb()' - Validate the page header.
4338 static int /* O - 0 if OK, -1 if not */
4340 cups_page_header2_t
*header
, /* IO - Raster header */
4341 int preferred_bits
) /* I - Preferred bits per color */
4344 * Ensure that colorimetric colorspaces use at least 8 bits per
4348 if ((header
->cupsColorSpace
== CUPS_CSPACE_CIEXYZ
||
4349 header
->cupsColorSpace
== CUPS_CSPACE_CIELab
||
4350 header
->cupsColorSpace
>= CUPS_CSPACE_ICC1
) &&
4351 header
->cupsBitsPerColor
< 8)
4352 header
->cupsBitsPerColor
= 8;