2 * "$Id: imagetoraster.c 7306 2008-02-15 00:52:38Z 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 7306 2008-02-15 00:52:38Z mike $".