2 * "$Id: imagetoraster.c 7306 2008-02-15 00:52:38Z mike $"
4 * Image file to raster filter for the Common UNIX Printing System (CUPS).
6 * Copyright 2007-2008 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/i18n.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 fprintf(stderr
, _("Usage: %s job-id user title copies options [file]\n"),
213 * See if we need to use the imagetops and pstoraster filters instead...
217 num_options
= cupsParseOptions(argv
[5], 0, &options
);
219 if (getenv("CLASSIFICATION") ||
220 cupsGetOption("page-label", num_options
, options
))
223 * Yes, fork a copy of pstoraster and then transfer control to imagetops...
226 int mypipes
[2]; /* New pipes for imagetops | pstoraster */
227 int pid
; /* PID of pstoraster */
230 cupsFreeOptions(num_options
, options
);
234 perror("ERROR: Unable to create pipes for imagetops | pstoraster");
238 if ((pid
= fork()) == 0)
241 * 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],
251 perror("ERROR: Unable to exec pstoraster");
260 perror("ERROR: Unable to fork pstoraster");
265 * Update stdout so it points at the new pstoraster...
274 * Run imagetops to get the classification or page labelling that was
278 execlp("imagetops", argv
[0], argv
[1], argv
[2], argv
[3], argv
[4], argv
[5],
280 perror("ERROR: Unable to exec imagetops");
285 * Copy stdin as needed...
290 int fd
; /* File to write to */
291 char buffer
[8192]; /* Buffer to read into */
292 int bytes
; /* # of bytes to read */
295 if ((fd
= cupsTempFd(filename
, sizeof(filename
))) < 0)
297 perror("ERROR: Unable to copy image file");
301 fprintf(stderr
, "DEBUG: imagetoraster - copying to temp print file \"%s\"\n",
304 while ((bytes
= fread(buffer
, 1, sizeof(buffer
), stdin
)) > 0)
305 write(fd
, buffer
, bytes
);
310 strlcpy(filename
, argv
[6], sizeof(filename
));
313 * Process command-line options and write the prolog...
324 Copies
= atoi(argv
[4]);
326 ppd
= SetCommonOptions(num_options
, options
, 0);
328 if ((val
= cupsGetOption("multiple-document-handling", num_options
, options
)) != NULL
)
331 * This IPP attribute is unnecessarily complicated...
333 * single-document, separate-documents-collated-copies, and
334 * single-document-new-sheet all require collated copies.
336 * separate-documents-collated-copies allows for uncollated copies.
339 Collate
= strcasecmp(val
, "separate-documents-collated-copies") != 0;
342 if ((val
= cupsGetOption("Collate", num_options
, options
)) != NULL
&&
343 strcasecmp(val
, "True") == 0)
346 if ((val
= cupsGetOption("gamma", num_options
, options
)) != NULL
)
349 * Get gamma value from 1 to 10000...
352 g
= atoi(val
) * 0.001f
;
360 if ((val
= cupsGetOption("brightness", num_options
, options
)) != NULL
)
363 * Get brightness value from 10 to 1000.
366 b
= atoi(val
) * 0.01f
;
374 if ((val
= cupsGetOption("scaling", num_options
, options
)) != NULL
)
375 zoom
= atoi(val
) * 0.01;
376 else if ((val
= cupsGetOption("fitplot", num_options
, options
)) != NULL
&&
377 !strcasecmp(val
, "true"))
379 else if ((val
= cupsGetOption("fit-to-page", num_options
, options
)) != NULL
&&
380 !strcasecmp(val
, "true"))
383 if ((val
= cupsGetOption("ppi", num_options
, options
)) != NULL
)
384 if (sscanf(val
, "%dx%d", &xppi
, &yppi
) < 2)
387 if ((val
= cupsGetOption("position", num_options
, options
)) != NULL
)
389 if (strcasecmp(val
, "center") == 0)
394 else if (strcasecmp(val
, "top") == 0)
399 else if (strcasecmp(val
, "left") == 0)
404 else if (strcasecmp(val
, "right") == 0)
409 else if (strcasecmp(val
, "top-left") == 0)
414 else if (strcasecmp(val
, "top-right") == 0)
419 else if (strcasecmp(val
, "bottom") == 0)
424 else if (strcasecmp(val
, "bottom-left") == 0)
429 else if (strcasecmp(val
, "bottom-right") == 0)
436 if ((val
= cupsGetOption("saturation", num_options
, options
)) != NULL
)
439 if ((val
= cupsGetOption("hue", num_options
, options
)) != NULL
)
442 if ((choice
= ppdFindMarkedChoice(ppd
, "MirrorPrint")) != NULL
)
444 val
= choice
->choice
;
448 val
= cupsGetOption("mirror", num_options
, options
);
450 if (val
&& (!strcasecmp(val
, "true") || !strcasecmp(val
, "on") ||
451 !strcasecmp(val
, "yes")))
455 * Set the needed options in the page header...
458 if (cupsRasterInterpretPPD(&header
, ppd
, num_options
, options
, raster_cb
))
460 fputs(_("ERROR: Bad page setup!\n"), stderr
);
461 fprintf(stderr
, "DEBUG: %s\n", cupsRasterErrorString());
466 * Get the media type and resolution that have been chosen...
469 if ((choice
= ppdFindMarkedChoice(ppd
, "MediaType")) != NULL
)
470 media_type
= choice
->choice
;
474 if ((choice
= ppdFindMarkedChoice(ppd
, "Resolution")) != NULL
)
475 resolution
= choice
->choice
;
480 * Choose the appropriate colorspace...
483 switch (header
.cupsColorSpace
)
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
;
499 case CUPS_CSPACE_RGB
:
500 case CUPS_CSPACE_RGBA
:
501 case CUPS_CSPACE_RGBW
:
502 if (header
.cupsBitsPerColor
>= 8)
504 primary
= CUPS_IMAGE_RGB
;
505 secondary
= CUPS_IMAGE_RGB
;
509 primary
= CUPS_IMAGE_CMY
;
510 secondary
= CUPS_IMAGE_CMY
;
515 case CUPS_CSPACE_WHITE
:
516 case CUPS_CSPACE_GOLD
:
517 case CUPS_CSPACE_SILVER
:
518 primary
= CUPS_IMAGE_BLACK
;
519 secondary
= CUPS_IMAGE_BLACK
;
522 case CUPS_CSPACE_CMYK
:
523 case CUPS_CSPACE_YMCK
:
524 case CUPS_CSPACE_KCMY
:
525 case CUPS_CSPACE_KCMYcm
:
526 case CUPS_CSPACE_GMCK
:
527 case CUPS_CSPACE_GMCS
:
528 if (header
.cupsBitsPerColor
== 1)
530 primary
= CUPS_IMAGE_CMY
;
531 secondary
= CUPS_IMAGE_CMY
;
535 primary
= CUPS_IMAGE_CMYK
;
536 secondary
= CUPS_IMAGE_CMYK
;
540 case CUPS_CSPACE_CMY
:
541 case CUPS_CSPACE_YMC
:
542 primary
= CUPS_IMAGE_CMY
;
543 secondary
= CUPS_IMAGE_CMY
;
549 * Find a color profile matching the current options...
552 if ((val
= cupsGetOption("profile", num_options
, options
)) != NULL
)
554 profile
= &userprofile
;
555 sscanf(val
, "%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f",
556 &(userprofile
.density
), &(userprofile
.gamma
),
557 userprofile
.matrix
[0] + 0, userprofile
.matrix
[0] + 1,
558 userprofile
.matrix
[0] + 2,
559 userprofile
.matrix
[1] + 0, userprofile
.matrix
[1] + 1,
560 userprofile
.matrix
[1] + 2,
561 userprofile
.matrix
[2] + 0, userprofile
.matrix
[2] + 1,
562 userprofile
.matrix
[2] + 2);
564 userprofile
.density
*= 0.001f
;
565 userprofile
.gamma
*= 0.001f
;
566 userprofile
.matrix
[0][0] *= 0.001f
;
567 userprofile
.matrix
[0][1] *= 0.001f
;
568 userprofile
.matrix
[0][2] *= 0.001f
;
569 userprofile
.matrix
[1][0] *= 0.001f
;
570 userprofile
.matrix
[1][1] *= 0.001f
;
571 userprofile
.matrix
[1][2] *= 0.001f
;
572 userprofile
.matrix
[2][0] *= 0.001f
;
573 userprofile
.matrix
[2][1] *= 0.001f
;
574 userprofile
.matrix
[2][2] *= 0.001f
;
576 else if (ppd
!= NULL
)
578 fprintf(stderr
, "DEBUG: Searching for profile \"%s/%s\"...\n",
579 resolution
, media_type
);
581 for (i
= 0, profile
= ppd
->profiles
; i
< ppd
->num_profiles
; i
++, profile
++)
583 fprintf(stderr
, "DEBUG: \"%s/%s\" = ", profile
->resolution
,
584 profile
->media_type
);
586 if ((strcmp(profile
->resolution
, resolution
) == 0 ||
587 profile
->resolution
[0] == '-') &&
588 (strcmp(profile
->media_type
, media_type
) == 0 ||
589 profile
->media_type
[0] == '-'))
591 fputs("MATCH!\n", stderr
);
595 fputs("no.\n", stderr
);
599 * If we found a color profile, use it!
602 if (i
>= ppd
->num_profiles
)
609 cupsImageSetProfile(profile
->density
, profile
->gamma
, profile
->matrix
);
611 cupsImageSetRasterColorSpace(header
.cupsColorSpace
);
614 * Create a gamma/brightness LUT...
617 make_lut(lut
, primary
, g
, b
);
620 * Open the input image to print...
623 fputs(_("INFO: Loading image file...\n"), stderr
);
625 if (header
.cupsColorSpace
== CUPS_CSPACE_CIEXYZ
||
626 header
.cupsColorSpace
== CUPS_CSPACE_CIELab
||
627 header
.cupsColorSpace
>= CUPS_CSPACE_ICC1
)
628 img
= cupsImageOpen(filename
, primary
, secondary
, sat
, hue
, NULL
);
630 img
= cupsImageOpen(filename
, primary
, secondary
, sat
, hue
, lut
);
637 fputs(_("ERROR: Unable to open image file for printing!\n"), stderr
);
643 * Scale as necessary...
646 if (zoom
== 0.0 && xppi
== 0)
655 fprintf(stderr
, "DEBUG: Before scaling: xppi=%d, yppi=%d, zoom=%.2f\n",
661 * Scale the image as neccesary to match the desired pixels-per-inch.
666 xprint
= (PageTop
- PageBottom
) / 72.0;
667 yprint
= (PageRight
- PageLeft
) / 72.0;
671 xprint
= (PageRight
- PageLeft
) / 72.0;
672 yprint
= (PageTop
- PageBottom
) / 72.0;
675 fprintf(stderr
, "DEBUG: Before scaling: xprint=%.1f, yprint=%.1f\n",
678 xinches
= (float)img
->xsize
/ (float)xppi
;
679 yinches
= (float)img
->ysize
/ (float)yppi
;
681 fprintf(stderr
, "DEBUG: Image size is %.1f x %.1f inches...\n",
684 if ((val
= cupsGetOption("natural-scaling", num_options
, options
)) != NULL
)
686 xinches
= xinches
* atoi(val
) / 100;
687 yinches
= yinches
* atoi(val
) / 100;
690 if (cupsGetOption("orientation-requested", num_options
, options
) == NULL
&&
691 cupsGetOption("landscape", num_options
, options
) == NULL
)
694 * Rotate the image if it will fit landscape but not portrait...
697 fputs("DEBUG: Auto orientation...\n", stderr
);
699 if ((xinches
> xprint
|| yinches
> yprint
) &&
700 xinches
<= yprint
&& yinches
<= xprint
)
703 * Rotate the image as needed...
706 fputs("DEBUG: Using landscape orientation...\n", stderr
);
708 Orientation
= (Orientation
+ 1) & 3;
718 * Scale percentage of page size...
721 xprint
= (PageRight
- PageLeft
) / 72.0;
722 yprint
= (PageTop
- PageBottom
) / 72.0;
723 aspect
= (float)img
->yppi
/ (float)img
->xppi
;
725 fprintf(stderr
, "DEBUG: Before scaling: xprint=%.1f, yprint=%.1f\n",
728 fprintf(stderr
, "DEBUG: img->xppi = %d, img->yppi = %d, aspect = %f\n",
729 img
->xppi
, img
->yppi
, aspect
);
731 xsize
= xprint
* zoom
;
732 ysize
= xsize
* img
->ysize
/ img
->xsize
/ aspect
;
734 if (ysize
> (yprint
* zoom
))
736 ysize
= yprint
* zoom
;
737 xsize
= ysize
* img
->xsize
* aspect
/ img
->ysize
;
740 xsize2
= yprint
* zoom
;
741 ysize2
= xsize2
* img
->ysize
/ img
->xsize
/ aspect
;
743 if (ysize2
> (xprint
* zoom
))
745 ysize2
= xprint
* zoom
;
746 xsize2
= ysize2
* img
->xsize
* aspect
/ img
->ysize
;
749 fprintf(stderr
, "DEBUG: Portrait size is %.2f x %.2f inches\n", xsize
, ysize
);
750 fprintf(stderr
, "DEBUG: Landscape size is %.2f x %.2f inches\n", xsize2
, ysize2
);
752 if (cupsGetOption("orientation-requested", num_options
, options
) == NULL
&&
753 cupsGetOption("landscape", num_options
, options
) == NULL
)
756 * Choose the rotation with the largest area, but prefer
757 * portrait if they are equal...
760 fputs("DEBUG: Auto orientation...\n", stderr
);
762 if ((xsize
* ysize
) < (xsize2
* xsize2
))
765 * Do landscape orientation...
768 fputs("DEBUG: Using landscape orientation...\n", stderr
);
773 xprint
= (PageTop
- PageBottom
) / 72.0;
774 yprint
= (PageRight
- PageLeft
) / 72.0;
779 * Do portrait orientation...
782 fputs("DEBUG: Using portrait orientation...\n", stderr
);
789 else if (Orientation
& 1)
791 fputs("DEBUG: Using landscape orientation...\n", stderr
);
795 xprint
= (PageTop
- PageBottom
) / 72.0;
796 yprint
= (PageRight
- PageLeft
) / 72.0;
800 fputs("DEBUG: Using portrait orientation...\n", stderr
);
804 xprint
= (PageRight
- PageLeft
) / 72.0;
805 yprint
= (PageTop
- PageBottom
) / 72.0;
810 * Compute the number of pages to print and the size of the image on each
814 xpages
= ceil(xinches
/ xprint
);
815 ypages
= ceil(yinches
/ yprint
);
817 xprint
= xinches
/ xpages
;
818 yprint
= yinches
/ ypages
;
820 fprintf(stderr
, "DEBUG: xpages = %dx%.2fin, ypages = %dx%.2fin\n",
821 xpages
, xprint
, ypages
, yprint
);
824 * Compute the bitmap size...
827 if ((choice
= ppdFindMarkedChoice(ppd
, "PageSize")) != NULL
&&
828 strcasecmp(choice
->choice
, "Custom") == 0)
830 float width
, /* New width in points */
831 length
; /* New length in points */
835 * Use the correct width and length for the current orientation...
840 width
= yprint
* 72.0;
841 length
= xprint
* 72.0;
845 width
= xprint
* 72.0;
846 length
= yprint
* 72.0;
850 * Add margins to page size...
853 width
+= ppd
->custom_margins
[0] + ppd
->custom_margins
[2];
854 length
+= ppd
->custom_margins
[1] + ppd
->custom_margins
[3];
857 * Enforce minimums...
860 if (width
< ppd
->custom_min
[0])
861 width
= ppd
->custom_min
[0];
863 if (length
< ppd
->custom_min
[1])
864 length
= ppd
->custom_min
[1];
866 fprintf(stderr
, "DEBUG: Updated custom page size to %.2f x %.2f inches...\n",
867 width
/ 72.0, length
/ 72.0);
870 * Set the new custom size...
873 strcpy(header
.cupsPageSizeName
, "Custom");
875 header
.cupsPageSize
[0] = width
+ 0.5;
876 header
.cupsPageSize
[1] = length
+ 0.5;
877 header
.PageSize
[0] = width
+ 0.5;
878 header
.PageSize
[1] = length
+ 0.5;
881 * Update page variables...
886 PageLeft
= ppd
->custom_margins
[0];
887 PageRight
= width
- ppd
->custom_margins
[2];
888 PageBottom
= ppd
->custom_margins
[1];
889 PageTop
= length
- ppd
->custom_margins
[3];
892 * Remove margins from page size...
895 width
-= ppd
->custom_margins
[0] + ppd
->custom_margins
[2];
896 length
-= ppd
->custom_margins
[1] + ppd
->custom_margins
[3];
899 * Set the bitmap size...
902 header
.cupsWidth
= width
* header
.HWResolution
[0] / 72.0;
903 header
.cupsHeight
= length
* header
.HWResolution
[1] / 72.0;
905 header
.cupsBytesPerLine
= (header
.cupsBitsPerPixel
*
906 header
.cupsWidth
+ 7) / 8;
908 if (header
.cupsColorOrder
== CUPS_ORDER_BANDED
)
909 header
.cupsBytesPerLine
*= header
.cupsNumColors
;
912 header
.Margins
[0] = PageLeft
;
913 header
.Margins
[1] = PageBottom
;
915 fprintf(stderr
, "DEBUG: PageSize = [%d %d]\n", header
.PageSize
[0],
924 header
.cupsImagingBBox
[0] = PageLeft
;
925 header
.cupsImagingBBox
[2] = PageLeft
+ xprint
* 72;
928 header
.cupsImagingBBox
[0] = (PageRight
+ PageLeft
- xprint
* 72) / 2;
929 header
.cupsImagingBBox
[2] = (PageRight
+ PageLeft
+ xprint
* 72) / 2;
932 header
.cupsImagingBBox
[0] = PageRight
- xprint
* 72;
933 header
.cupsImagingBBox
[2] = PageRight
;
940 header
.cupsImagingBBox
[1] = PageBottom
;
941 header
.cupsImagingBBox
[3] = PageBottom
+ yprint
* 72;
944 header
.cupsImagingBBox
[1] = (PageTop
+ PageBottom
- yprint
* 72) / 2;
945 header
.cupsImagingBBox
[3] = (PageTop
+ PageBottom
+ yprint
* 72) / 2;
948 header
.cupsImagingBBox
[1] = PageTop
- yprint
* 72;
949 header
.cupsImagingBBox
[3] = PageTop
;
958 header
.cupsImagingBBox
[0] = PageBottom
;
959 header
.cupsImagingBBox
[2] = PageBottom
+ yprint
* 72;
962 header
.cupsImagingBBox
[0] = (PageTop
+ PageBottom
- yprint
* 72) / 2;
963 header
.cupsImagingBBox
[2] = (PageTop
+ PageBottom
+ yprint
* 72) / 2;
966 header
.cupsImagingBBox
[0] = PageTop
- yprint
* 72;
967 header
.cupsImagingBBox
[2] = PageTop
;
974 header
.cupsImagingBBox
[1] = PageLeft
;
975 header
.cupsImagingBBox
[3] = PageLeft
+ xprint
* 72;
978 header
.cupsImagingBBox
[1] = (PageRight
+ PageLeft
- xprint
* 72) / 2;
979 header
.cupsImagingBBox
[3] = (PageRight
+ PageLeft
+ xprint
* 72) / 2;
982 header
.cupsImagingBBox
[1] = PageRight
- xprint
* 72;
983 header
.cupsImagingBBox
[3] = PageRight
;
992 header
.cupsImagingBBox
[0] = PageLeft
;
993 header
.cupsImagingBBox
[2] = PageLeft
+ xprint
* 72;
996 header
.cupsImagingBBox
[0] = (PageRight
+ PageLeft
- xprint
* 72) / 2;
997 header
.cupsImagingBBox
[2] = (PageRight
+ PageLeft
+ xprint
* 72) / 2;
1000 header
.cupsImagingBBox
[0] = PageRight
- xprint
* 72;
1001 header
.cupsImagingBBox
[2] = PageRight
;
1008 header
.cupsImagingBBox
[1] = PageBottom
;
1009 header
.cupsImagingBBox
[3] = PageBottom
+ yprint
* 72;
1012 header
.cupsImagingBBox
[1] = (PageTop
+ PageBottom
- yprint
* 72) / 2;
1013 header
.cupsImagingBBox
[3] = (PageTop
+ PageBottom
+ yprint
* 72) / 2;
1016 header
.cupsImagingBBox
[1] = PageTop
- yprint
* 72;
1017 header
.cupsImagingBBox
[3] = PageTop
;
1026 header
.cupsImagingBBox
[0] = PageBottom
;
1027 header
.cupsImagingBBox
[2] = PageBottom
+ yprint
* 72;
1030 header
.cupsImagingBBox
[0] = (PageTop
+ PageBottom
- yprint
* 72) / 2;
1031 header
.cupsImagingBBox
[2] = (PageTop
+ PageBottom
+ yprint
* 72) / 2;
1034 header
.cupsImagingBBox
[0] = PageTop
- yprint
* 72;
1035 header
.cupsImagingBBox
[2] = PageTop
;
1042 header
.cupsImagingBBox
[1] = PageLeft
;
1043 header
.cupsImagingBBox
[3] = PageLeft
+ xprint
* 72;
1046 header
.cupsImagingBBox
[1] = (PageRight
+ PageLeft
- xprint
* 72) / 2;
1047 header
.cupsImagingBBox
[3] = (PageRight
+ PageLeft
+ xprint
* 72) / 2;
1050 header
.cupsImagingBBox
[1] = PageRight
- xprint
* 72;
1051 header
.cupsImagingBBox
[3] = PageRight
;
1057 header
.ImagingBoundingBox
[0] = header
.cupsImagingBBox
[0];
1058 header
.ImagingBoundingBox
[1] = header
.cupsImagingBBox
[1];
1059 header
.ImagingBoundingBox
[2] = header
.cupsImagingBBox
[2];
1060 header
.ImagingBoundingBox
[3] = header
.cupsImagingBBox
[3];
1062 if (header
.cupsColorOrder
== CUPS_ORDER_PLANAR
)
1063 num_planes
= header
.cupsNumColors
;
1067 if (header
.cupsBitsPerColor
>= 8)
1068 zoom_type
= CUPS_IZOOM_NORMAL
;
1070 zoom_type
= CUPS_IZOOM_FAST
;
1073 * See if we need to collate, and if so how we need to do it...
1076 if (xpages
== 1 && ypages
== 1)
1079 slowcollate
= Collate
&& ppdFindOption(ppd
, "Collate") == NULL
;
1081 slowcopies
= ppd
->manual_copies
;
1085 if (Copies
> 1 && !slowcollate
&& !slowcopies
)
1087 header
.Collate
= (cups_bool_t
)Collate
;
1088 header
.NumCopies
= Copies
;
1093 header
.NumCopies
= 1;
1096 * Create the dithering lookup tables...
1100 OnPixels
[255] = 0xff;
1101 OffPixels
[0] = 0x00;
1102 OffPixels
[255] = 0xff;
1104 switch (header
.cupsBitsPerColor
)
1107 for (i
= 1; i
< 255; i
++)
1109 OnPixels
[i
] = 0x55 * (i
/ 85 + 1);
1110 OffPixels
[i
] = 0x55 * (i
/ 64);
1114 for (i
= 1; i
< 255; i
++)
1116 OnPixels
[i
] = 17 * (i
/ 17 + 1);
1117 OffPixels
[i
] = 17 * (i
/ 16);
1123 * Output the pages...
1126 fprintf(stderr
, "DEBUG: cupsWidth = %d\n", header
.cupsWidth
);
1127 fprintf(stderr
, "DEBUG: cupsHeight = %d\n", header
.cupsHeight
);
1128 fprintf(stderr
, "DEBUG: cupsBitsPerColor = %d\n", header
.cupsBitsPerColor
);
1129 fprintf(stderr
, "DEBUG: cupsBitsPerPixel = %d\n", header
.cupsBitsPerPixel
);
1130 fprintf(stderr
, "DEBUG: cupsBytesPerLine = %d\n", header
.cupsBytesPerLine
);
1131 fprintf(stderr
, "DEBUG: cupsColorOrder = %d\n", header
.cupsColorOrder
);
1132 fprintf(stderr
, "DEBUG: cupsColorSpace = %d\n", header
.cupsColorSpace
);
1133 fprintf(stderr
, "DEBUG: img->colorspace = %d\n", img
->colorspace
);
1135 row
= malloc(2 * header
.cupsBytesPerLine
);
1136 ras
= cupsRasterOpen(1, CUPS_RASTER_WRITE
);
1138 for (i
= 0, page
= 1; i
< Copies
; i
++)
1139 for (xpage
= 0; xpage
< xpages
; xpage
++)
1140 for (ypage
= 0; ypage
< ypages
; ypage
++, page
++)
1142 fprintf(stderr
, _("INFO: Formatting page %d...\n"), page
);
1144 if (Orientation
& 1)
1146 xc0
= img
->xsize
* ypage
/ ypages
;
1147 xc1
= img
->xsize
* (ypage
+ 1) / ypages
- 1;
1148 yc0
= img
->ysize
* xpage
/ xpages
;
1149 yc1
= img
->ysize
* (xpage
+ 1) / xpages
- 1;
1151 xtemp
= header
.HWResolution
[0] * yprint
;
1152 ytemp
= header
.HWResolution
[1] * xprint
;
1156 xc0
= img
->xsize
* xpage
/ xpages
;
1157 xc1
= img
->xsize
* (xpage
+ 1) / xpages
- 1;
1158 yc0
= img
->ysize
* ypage
/ ypages
;
1159 yc1
= img
->ysize
* (ypage
+ 1) / ypages
- 1;
1161 xtemp
= header
.HWResolution
[0] * xprint
;
1162 ytemp
= header
.HWResolution
[1] * yprint
;
1165 cupsRasterWriteHeader2(ras
, &header
);
1167 for (plane
= 0; plane
< num_planes
; plane
++)
1170 * Initialize the image "zoom" engine...
1174 z
= _cupsImageZoomNew(img
, xc0
, yc0
, xc1
, yc1
, -xtemp
, ytemp
,
1175 Orientation
& 1, zoom_type
);
1177 z
= _cupsImageZoomNew(img
, xc0
, yc0
, xc1
, yc1
, xtemp
, ytemp
,
1178 Orientation
& 1, zoom_type
);
1181 * Write leading blank space as needed...
1184 if (header
.cupsHeight
> z
->ysize
&& YPosition
<= 0)
1186 blank_line(&header
, row
);
1188 y
= header
.cupsHeight
- z
->ysize
;
1192 fprintf(stderr
, "DEBUG: Writing %d leading blank lines...\n", y
);
1196 if (cupsRasterWritePixels(ras
, row
, header
.cupsBytesPerLine
) <
1197 header
.cupsBytesPerLine
)
1199 fputs(_("ERROR: Unable to write raster data to driver!\n"),
1201 cupsImageClose(img
);
1208 * Then write image data...
1211 for (y
= z
->ysize
, yerr0
= 0, yerr1
= z
->ysize
, iy
= 0, last_iy
= -2;
1217 if (zoom_type
!= CUPS_IZOOM_FAST
&& (iy
- last_iy
) > 1)
1218 _cupsImageZoomFill(z
, iy
);
1220 _cupsImageZoomFill(z
, iy
+ z
->yincr
);
1226 * Format this line of raster data for the printer...
1229 blank_line(&header
, row
);
1231 r0
= z
->rows
[z
->row
];
1232 r1
= z
->rows
[1 - z
->row
];
1234 switch (header
.cupsColorSpace
)
1236 case CUPS_CSPACE_W
:
1237 format_W(&header
, row
, y
, plane
, z
->xsize
, z
->ysize
,
1238 yerr0
, yerr1
, r0
, r1
);
1241 case CUPS_CSPACE_RGB
:
1242 format_RGB(&header
, row
, y
, plane
, z
->xsize
, z
->ysize
,
1243 yerr0
, yerr1
, r0
, r1
);
1245 case CUPS_CSPACE_RGBA
:
1246 case CUPS_CSPACE_RGBW
:
1247 format_RGBA(&header
, row
, y
, plane
, z
->xsize
, z
->ysize
,
1248 yerr0
, yerr1
, r0
, r1
);
1250 case CUPS_CSPACE_K
:
1251 case CUPS_CSPACE_WHITE
:
1252 case CUPS_CSPACE_GOLD
:
1253 case CUPS_CSPACE_SILVER
:
1254 format_K(&header
, row
, y
, plane
, z
->xsize
, z
->ysize
,
1255 yerr0
, yerr1
, r0
, r1
);
1257 case CUPS_CSPACE_CMY
:
1258 format_CMY(&header
, row
, y
, plane
, z
->xsize
, z
->ysize
,
1259 yerr0
, yerr1
, r0
, r1
);
1261 case CUPS_CSPACE_YMC
:
1262 format_YMC(&header
, row
, y
, plane
, z
->xsize
, z
->ysize
,
1263 yerr0
, yerr1
, r0
, r1
);
1265 case CUPS_CSPACE_CMYK
:
1266 format_CMYK(&header
, row
, y
, plane
, z
->xsize
, z
->ysize
,
1267 yerr0
, yerr1
, r0
, r1
);
1269 case CUPS_CSPACE_YMCK
:
1270 case CUPS_CSPACE_GMCK
:
1271 case CUPS_CSPACE_GMCS
:
1272 format_YMCK(&header
, row
, y
, plane
, z
->xsize
, z
->ysize
,
1273 yerr0
, yerr1
, r0
, r1
);
1275 case CUPS_CSPACE_KCMYcm
:
1276 if (header
.cupsBitsPerColor
== 1)
1278 format_KCMYcm(&header
, row
, y
, plane
, z
->xsize
, z
->ysize
,
1279 yerr0
, yerr1
, r0
, r1
);
1282 case CUPS_CSPACE_KCMY
:
1283 format_KCMY(&header
, row
, y
, plane
, z
->xsize
, z
->ysize
,
1284 yerr0
, yerr1
, r0
, r1
);
1289 * Write the raster data to the driver...
1292 if (cupsRasterWritePixels(ras
, row
, header
.cupsBytesPerLine
) <
1293 header
.cupsBytesPerLine
)
1295 fputs(_("ERROR: Unable to write raster data to driver!\n"),
1297 cupsImageClose(img
);
1302 * Compute the next scanline in the image...
1317 * Write trailing blank space as needed...
1320 if (header
.cupsHeight
> z
->ysize
&& YPosition
>= 0)
1322 blank_line(&header
, row
);
1324 y
= header
.cupsHeight
- z
->ysize
;
1328 fprintf(stderr
, "DEBUG: Writing %d trailing blank lines...\n", y
);
1332 if (cupsRasterWritePixels(ras
, row
, header
.cupsBytesPerLine
) <
1333 header
.cupsBytesPerLine
)
1335 fputs(_("ERROR: Unable to write raster data to driver!\n"),
1337 cupsImageClose(img
);
1344 * Free memory used for the "zoom" engine...
1347 _cupsImageZoomDelete(z
);
1356 cupsRasterClose(ras
);
1357 cupsImageClose(img
);
1365 * 'blank_line()' - Clear a line buffer to the blank value...
1369 blank_line(cups_page_header2_t
*header
, /* I - Page header */
1370 unsigned char *row
) /* I - Row buffer */
1372 int count
; /* Remaining bytes */
1375 count
= header
->cupsBytesPerLine
;
1377 switch (header
->cupsColorSpace
)
1379 case CUPS_CSPACE_CIEXYZ
:
1389 case CUPS_CSPACE_CIELab
:
1390 case CUPS_CSPACE_ICC1
:
1391 case CUPS_CSPACE_ICC2
:
1392 case CUPS_CSPACE_ICC3
:
1393 case CUPS_CSPACE_ICC4
:
1394 case CUPS_CSPACE_ICC5
:
1395 case CUPS_CSPACE_ICC6
:
1396 case CUPS_CSPACE_ICC7
:
1397 case CUPS_CSPACE_ICC8
:
1398 case CUPS_CSPACE_ICC9
:
1399 case CUPS_CSPACE_ICCA
:
1400 case CUPS_CSPACE_ICCB
:
1401 case CUPS_CSPACE_ICCC
:
1402 case CUPS_CSPACE_ICCD
:
1403 case CUPS_CSPACE_ICCE
:
1404 case CUPS_CSPACE_ICCF
:
1414 case CUPS_CSPACE_K
:
1415 case CUPS_CSPACE_CMY
:
1416 case CUPS_CSPACE_CMYK
:
1417 case CUPS_CSPACE_YMC
:
1418 case CUPS_CSPACE_YMCK
:
1419 case CUPS_CSPACE_KCMY
:
1420 case CUPS_CSPACE_KCMYcm
:
1421 case CUPS_CSPACE_GMCK
:
1422 case CUPS_CSPACE_GMCS
:
1423 case CUPS_CSPACE_WHITE
:
1424 case CUPS_CSPACE_GOLD
:
1425 case CUPS_CSPACE_SILVER
:
1426 memset(row
, 0, count
);
1430 memset(row
, 255, count
);
1437 * 'format_CMY()' - Convert image data to CMY.
1441 format_CMY(cups_page_header2_t
*header
, /* I - Page header */
1442 unsigned char *row
, /* IO - Bitmap data for device */
1443 int y
, /* I - Current row */
1444 int z
, /* I - Current plane */
1445 int xsize
, /* I - Width of image data */
1446 int ysize
, /* I - Height of image data */
1447 int yerr0
, /* I - Top Y error */
1448 int yerr1
, /* I - Bottom Y error */
1449 cups_ib_t
*r0
, /* I - Primary image data */
1450 cups_ib_t
*r1
) /* I - Image data for interpolation */
1452 cups_ib_t
*ptr
, /* Pointer into row */
1453 *cptr
, /* Pointer into cyan */
1454 *mptr
, /* Pointer into magenta */
1455 *yptr
, /* Pointer into yellow */
1456 bitmask
; /* Current mask for pixel */
1457 int bitoffset
; /* Current offset in line */
1458 int bandwidth
; /* Width of a color band */
1459 int x
, /* Current X coordinate on page */
1460 *dither
; /* Pointer into dither array */
1469 bitoffset
= header
->cupsBitsPerPixel
* ((header
->cupsWidth
- xsize
) / 2);
1472 bitoffset
= header
->cupsBitsPerPixel
* (header
->cupsWidth
- xsize
);
1476 ptr
= row
+ bitoffset
/ 8;
1477 bandwidth
= header
->cupsBytesPerLine
/ 3;
1479 switch (header
->cupsColorOrder
)
1481 case CUPS_ORDER_CHUNKED
:
1482 switch (header
->cupsBitsPerColor
)
1485 bitmask
= 64 >> (bitoffset
& 7);
1486 dither
= Floyd16x16
[y
& 15];
1488 for (x
= xsize
; x
> 0; x
--)
1490 if (*r0
++ > dither
[x
& 15])
1494 if (*r0
++ > dither
[x
& 15])
1498 if (*r0
++ > dither
[x
& 15])
1512 dither
= Floyd8x8
[y
& 7];
1514 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
1516 if ((r0
[0] & 63) > dither
[x
& 7])
1517 *ptr
^= (0x30 & OnPixels
[r0
[0]]);
1519 *ptr
^= (0x30 & OffPixels
[r0
[0]]);
1521 if ((r0
[1] & 63) > dither
[x
& 7])
1522 *ptr
^= (0x0c & OnPixels
[r0
[1]]);
1524 *ptr
^= (0x0c & OffPixels
[r0
[1]]);
1526 if ((r0
[2] & 63) > dither
[x
& 7])
1527 *ptr
++ ^= (0x03 & OnPixels
[r0
[2]]);
1529 *ptr
++ ^= (0x03 & OffPixels
[r0
[2]]);
1534 dither
= Floyd4x4
[y
& 3];
1536 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
1538 if ((r0
[0] & 15) > dither
[x
& 3])
1539 *ptr
++ ^= (0x0f & OnPixels
[r0
[0]]);
1541 *ptr
++ ^= (0x0f & OffPixels
[r0
[0]]);
1543 if ((r0
[1] & 15) > dither
[x
& 3])
1544 *ptr
^= (0xf0 & OnPixels
[r0
[1]]);
1546 *ptr
^= (0xf0 & OffPixels
[r0
[1]]);
1548 if ((r0
[2] & 15) > dither
[x
& 3])
1549 *ptr
++ ^= (0x0f & OnPixels
[r0
[2]]);
1551 *ptr
++ ^= (0x0f & OffPixels
[r0
[2]]);
1556 for (x
= xsize
* 3; x
> 0; x
--, r0
++, r1
++)
1560 *ptr
++ = (*r0
* yerr0
+ *r1
* yerr1
) / ysize
;
1565 case CUPS_ORDER_BANDED
:
1567 mptr
= ptr
+ bandwidth
;
1568 yptr
= ptr
+ 2 * bandwidth
;
1570 switch (header
->cupsBitsPerColor
)
1573 bitmask
= 0x80 >> (bitoffset
& 7);
1574 dither
= Floyd16x16
[y
& 15];
1576 for (x
= xsize
; x
> 0; x
--)
1578 if (*r0
++ > dither
[x
& 15])
1580 if (*r0
++ > dither
[x
& 15])
1582 if (*r0
++ > dither
[x
& 15])
1598 bitmask
= 0xc0 >> (bitoffset
& 7);
1599 dither
= Floyd8x8
[y
& 7];
1601 for (x
= xsize
; x
> 0; x
--)
1603 if ((*r0
& 63) > dither
[x
& 7])
1604 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
1606 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
1608 if ((*r0
& 63) > dither
[x
& 7])
1609 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
1611 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
1613 if ((*r0
& 63) > dither
[x
& 7])
1614 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
1616 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
1632 bitmask
= 0xf0 >> (bitoffset
& 7);
1633 dither
= Floyd4x4
[y
& 3];
1635 for (x
= xsize
; x
> 0; x
--)
1637 if ((*r0
& 15) > dither
[x
& 3])
1638 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
1640 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
1642 if ((*r0
& 15) > dither
[x
& 3])
1643 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
1645 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
1647 if ((*r0
& 15) > dither
[x
& 3])
1648 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
1650 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
1652 if (bitmask
== 0xf0)
1666 for (x
= xsize
; x
> 0; x
--, r0
+= 3, r1
+= 3)
1671 *cptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
1676 *mptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
1681 *yptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
1687 case CUPS_ORDER_PLANAR
:
1688 switch (header
->cupsBitsPerColor
)
1691 bitmask
= 0x80 >> (bitoffset
& 7);
1692 dither
= Floyd16x16
[y
& 15];
1697 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
1699 if (r0
[0] > dither
[x
& 15])
1713 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
1715 if (r0
[1] > dither
[x
& 15])
1729 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
1731 if (r0
[2] > dither
[x
& 15])
1747 bitmask
= 0xc0 >> (bitoffset
& 7);
1748 dither
= Floyd8x8
[y
& 7];
1751 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
1753 if ((*r0
& 63) > dither
[x
& 7])
1754 *ptr
^= (bitmask
& OnPixels
[*r0
]);
1756 *ptr
^= (bitmask
& OffPixels
[*r0
]);
1770 bitmask
= 0xf0 >> (bitoffset
& 7);
1771 dither
= Floyd4x4
[y
& 3];
1774 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
1776 if ((*r0
& 15) > dither
[x
& 3])
1777 *ptr
^= (bitmask
& OnPixels
[*r0
]);
1779 *ptr
^= (bitmask
& OffPixels
[*r0
]);
1781 if (bitmask
== 0xf0)
1796 for (x
= xsize
; x
> 0; x
--, r0
+= 3, r1
+= 3)
1801 *ptr
++ = (*r0
* yerr0
+ *r1
* yerr1
) / ysize
;
1811 * 'format_CMYK()' - Convert image data to CMYK.
1815 format_CMYK(cups_page_header2_t
*header
,/* I - Page header */
1816 unsigned char *row
, /* IO - Bitmap data for device */
1817 int y
, /* I - Current row */
1818 int z
, /* I - Current plane */
1819 int xsize
, /* I - Width of image data */
1820 int ysize
, /* I - Height of image data */
1821 int yerr0
, /* I - Top Y error */
1822 int yerr1
, /* I - Bottom Y error */
1823 cups_ib_t
*r0
, /* I - Primary image data */
1824 cups_ib_t
*r1
) /* I - Image data for interpolation */
1826 cups_ib_t
*ptr
, /* Pointer into row */
1827 *cptr
, /* Pointer into cyan */
1828 *mptr
, /* Pointer into magenta */
1829 *yptr
, /* Pointer into yellow */
1830 *kptr
, /* Pointer into black */
1831 bitmask
; /* Current mask for pixel */
1832 int bitoffset
; /* Current offset in line */
1833 int bandwidth
; /* Width of a color band */
1834 int x
, /* Current X coordinate on page */
1835 *dither
; /* Pointer into dither array */
1836 int pc
, pm
, py
; /* CMY pixels */
1845 bitoffset
= header
->cupsBitsPerPixel
* ((header
->cupsWidth
- xsize
) / 2);
1848 bitoffset
= header
->cupsBitsPerPixel
* (header
->cupsWidth
- xsize
);
1852 ptr
= row
+ bitoffset
/ 8;
1853 bandwidth
= header
->cupsBytesPerLine
/ 4;
1855 switch (header
->cupsColorOrder
)
1857 case CUPS_ORDER_CHUNKED
:
1858 switch (header
->cupsBitsPerColor
)
1861 bitmask
= 128 >> (bitoffset
& 7);
1862 dither
= Floyd16x16
[y
& 15];
1864 for (x
= xsize
; x
> 0; x
--)
1866 pc
= *r0
++ > dither
[x
& 15];
1867 pm
= *r0
++ > dither
[x
& 15];
1868 py
= *r0
++ > dither
[x
& 15];
1901 dither
= Floyd8x8
[y
& 7];
1903 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
1905 if ((r0
[0] & 63) > dither
[x
& 7])
1906 *ptr
^= (0xc0 & OnPixels
[r0
[0]]);
1908 *ptr
^= (0xc0 & OffPixels
[r0
[0]]);
1910 if ((r0
[1] & 63) > dither
[x
& 7])
1911 *ptr
^= (0x30 & OnPixels
[r0
[1]]);
1913 *ptr
^= (0x30 & OffPixels
[r0
[1]]);
1915 if ((r0
[2] & 63) > dither
[x
& 7])
1916 *ptr
^= (0x0c & OnPixels
[r0
[2]]);
1918 *ptr
^= (0x0c & OffPixels
[r0
[2]]);
1920 if ((r0
[3] & 63) > dither
[x
& 7])
1921 *ptr
++ ^= (0x03 & OnPixels
[r0
[3]]);
1923 *ptr
++ ^= (0x03 & OffPixels
[r0
[3]]);
1928 dither
= Floyd4x4
[y
& 3];
1930 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
1932 if ((r0
[0] & 15) > dither
[x
& 3])
1933 *ptr
^= (0xf0 & OnPixels
[r0
[0]]);
1935 *ptr
^= (0xf0 & OffPixels
[r0
[0]]);
1937 if ((r0
[1] & 15) > dither
[x
& 3])
1938 *ptr
++ ^= (0x0f & OnPixels
[r0
[1]]);
1940 *ptr
++ ^= (0x0f & OffPixels
[r0
[1]]);
1942 if ((r0
[2] & 15) > dither
[x
& 3])
1943 *ptr
^= (0xf0 & OnPixels
[r0
[2]]);
1945 *ptr
^= (0xf0 & OffPixels
[r0
[2]]);
1947 if ((r0
[3] & 15) > dither
[x
& 3])
1948 *ptr
++ ^= (0x0f & OnPixels
[r0
[3]]);
1950 *ptr
++ ^= (0x0f & OffPixels
[r0
[3]]);
1955 for (x
= xsize
* 4; x
> 0; x
--, r0
++, r1
++)
1959 *ptr
++ = (*r0
* yerr0
+ *r1
* yerr1
) / ysize
;
1964 case CUPS_ORDER_BANDED
:
1966 mptr
= ptr
+ bandwidth
;
1967 yptr
= ptr
+ 2 * bandwidth
;
1968 kptr
= ptr
+ 3 * bandwidth
;
1970 switch (header
->cupsBitsPerColor
)
1973 bitmask
= 0x80 >> (bitoffset
& 7);
1974 dither
= Floyd16x16
[y
& 15];
1976 for (x
= xsize
; x
> 0; x
--)
1978 pc
= *r0
++ > dither
[x
& 15];
1979 pm
= *r0
++ > dither
[x
& 15];
1980 py
= *r0
++ > dither
[x
& 15];
2008 bitmask
= 0xc0 >> (bitoffset
& 7);
2009 dither
= Floyd8x8
[y
& 7];
2011 for (x
= xsize
; x
> 0; x
--)
2013 if ((*r0
& 63) > dither
[x
& 7])
2014 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
2016 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
2018 if ((*r0
& 63) > dither
[x
& 7])
2019 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
2021 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
2023 if ((*r0
& 63) > dither
[x
& 7])
2024 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
2026 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
2028 if ((*r0
& 63) > dither
[x
& 7])
2029 *kptr
^= (bitmask
& OnPixels
[*r0
++]);
2031 *kptr
^= (bitmask
& OffPixels
[*r0
++]);
2048 bitmask
= 0xf0 >> (bitoffset
& 7);
2049 dither
= Floyd4x4
[y
& 3];
2051 for (x
= xsize
; x
> 0; x
--)
2053 if ((*r0
& 15) > dither
[x
& 3])
2054 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
2056 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
2058 if ((*r0
& 15) > dither
[x
& 3])
2059 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
2061 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
2063 if ((*r0
& 15) > dither
[x
& 3])
2064 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
2066 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
2068 if ((*r0
& 15) > dither
[x
& 3])
2069 *kptr
^= (bitmask
& OnPixels
[*r0
++]);
2071 *kptr
^= (bitmask
& OffPixels
[*r0
++]);
2073 if (bitmask
== 0xf0)
2088 for (x
= xsize
; x
> 0; x
--, r0
+= 4, r1
+= 4)
2093 *cptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
2098 *mptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
2103 *yptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
2108 *kptr
++ = (r0
[3] * yerr0
+ r1
[3] * yerr1
) / ysize
;
2114 case CUPS_ORDER_PLANAR
:
2115 switch (header
->cupsBitsPerColor
)
2118 bitmask
= 0x80 >> (bitoffset
& 7);
2119 dither
= Floyd16x16
[y
& 15];
2121 for (x
= xsize
; x
> 0; x
--)
2123 pc
= *r0
++ > dither
[x
& 15];
2124 pm
= *r0
++ > dither
[x
& 15];
2125 py
= *r0
++ > dither
[x
& 15];
2127 if ((pc
&& pm
&& py
&& z
== 3) ||
2128 (pc
&& z
== 0) || (pm
&& z
== 1) || (py
&& z
== 2))
2142 bitmask
= 0xc0 >> (bitoffset
& 7);
2143 dither
= Floyd8x8
[y
& 7];
2146 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
2148 if ((*r0
& 63) > dither
[x
& 7])
2149 *ptr
^= (bitmask
& OnPixels
[*r0
]);
2151 *ptr
^= (bitmask
& OffPixels
[*r0
]);
2165 bitmask
= 0xf0 >> (bitoffset
& 7);
2166 dither
= Floyd4x4
[y
& 3];
2169 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
2171 if ((*r0
& 15) > dither
[x
& 3])
2172 *ptr
^= (bitmask
& OnPixels
[*r0
]);
2174 *ptr
^= (bitmask
& OffPixels
[*r0
]);
2176 if (bitmask
== 0xf0)
2191 for (x
= xsize
; x
> 0; x
--, r0
+= 4, r1
+= 4)
2196 *ptr
++ = (*r0
* yerr0
+ *r1
* yerr1
) / ysize
;
2206 * 'format_K()' - Convert image data to black.
2210 format_K(cups_page_header2_t
*header
, /* I - Page header */
2211 unsigned char *row
, /* IO - Bitmap data for device */
2212 int y
, /* I - Current row */
2213 int z
, /* I - Current plane */
2214 int xsize
, /* I - Width of image data */
2215 int ysize
, /* I - Height of image data */
2216 int yerr0
, /* I - Top Y error */
2217 int yerr1
, /* I - Bottom Y error */
2218 cups_ib_t
*r0
, /* I - Primary image data */
2219 cups_ib_t
*r1
) /* I - Image data for interpolation */
2221 cups_ib_t
*ptr
, /* Pointer into row */
2222 bitmask
; /* Current mask for pixel */
2223 int bitoffset
; /* Current offset in line */
2224 int x
, /* Current X coordinate on page */
2225 *dither
; /* Pointer into dither array */
2236 bitoffset
= header
->cupsBitsPerPixel
* ((header
->cupsWidth
- xsize
) / 2);
2239 bitoffset
= header
->cupsBitsPerPixel
* (header
->cupsWidth
- xsize
);
2243 ptr
= row
+ bitoffset
/ 8;
2245 switch (header
->cupsBitsPerColor
)
2248 bitmask
= 0x80 >> (bitoffset
& 7);
2249 dither
= Floyd16x16
[y
& 15];
2251 for (x
= xsize
; x
> 0; x
--)
2253 if (*r0
++ > dither
[x
& 15])
2267 bitmask
= 0xc0 >> (bitoffset
& 7);
2268 dither
= Floyd8x8
[y
& 7];
2270 for (x
= xsize
; x
> 0; x
--)
2272 if ((*r0
& 63) > dither
[x
& 7])
2273 *ptr
^= (bitmask
& OnPixels
[*r0
++]);
2275 *ptr
^= (bitmask
& OffPixels
[*r0
++]);
2289 bitmask
= 0xf0 >> (bitoffset
& 7);
2290 dither
= Floyd4x4
[y
& 3];
2292 for (x
= xsize
; x
> 0; x
--)
2294 if ((*r0
& 15) > dither
[x
& 3])
2295 *ptr
^= (bitmask
& OnPixels
[*r0
++]);
2297 *ptr
^= (bitmask
& OffPixels
[*r0
++]);
2299 if (bitmask
== 0xf0)
2311 for (x
= xsize
; x
> 0; x
--, r0
++, r1
++)
2316 *ptr
++ = (*r0
* yerr0
+ *r1
* yerr1
) / ysize
;
2324 * 'format_KCMY()' - Convert image data to KCMY.
2328 format_KCMY(cups_page_header2_t
*header
,/* I - Page header */
2329 unsigned char *row
, /* IO - Bitmap data for device */
2330 int y
, /* I - Current row */
2331 int z
, /* I - Current plane */
2332 int xsize
, /* I - Width of image data */
2333 int ysize
, /* I - Height of image data */
2334 int yerr0
, /* I - Top Y error */
2335 int yerr1
, /* I - Bottom Y error */
2336 cups_ib_t
*r0
, /* I - Primary image data */
2337 cups_ib_t
*r1
) /* I - Image data for interpolation */
2339 cups_ib_t
*ptr
, /* Pointer into row */
2340 *cptr
, /* Pointer into cyan */
2341 *mptr
, /* Pointer into magenta */
2342 *yptr
, /* Pointer into yellow */
2343 *kptr
, /* Pointer into black */
2344 bitmask
; /* Current mask for pixel */
2345 int bitoffset
; /* Current offset in line */
2346 int bandwidth
; /* Width of a color band */
2347 int x
, /* Current X coordinate on page */
2348 *dither
; /* Pointer into dither array */
2349 int pc
, pm
, py
; /* CMY pixels */
2358 bitoffset
= header
->cupsBitsPerPixel
* ((header
->cupsWidth
- xsize
) / 2);
2361 bitoffset
= header
->cupsBitsPerPixel
* (header
->cupsWidth
- xsize
);
2365 ptr
= row
+ bitoffset
/ 8;
2366 bandwidth
= header
->cupsBytesPerLine
/ 4;
2368 switch (header
->cupsColorOrder
)
2370 case CUPS_ORDER_CHUNKED
:
2371 switch (header
->cupsBitsPerColor
)
2374 bitmask
= 128 >> (bitoffset
& 7);
2375 dither
= Floyd16x16
[y
& 15];
2377 for (x
= xsize
; x
> 0; x
--)
2379 pc
= *r0
++ > dither
[x
& 15];
2380 pm
= *r0
++ > dither
[x
& 15];
2381 py
= *r0
++ > dither
[x
& 15];
2414 dither
= Floyd8x8
[y
& 7];
2416 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
2418 if ((r0
[3] & 63) > dither
[x
& 7])
2419 *ptr
^= (0xc0 & OnPixels
[r0
[3]]);
2421 *ptr
^= (0xc0 & OffPixels
[r0
[3]]);
2423 if ((r0
[0] & 63) > dither
[x
& 7])
2424 *ptr
^= (0x30 & OnPixels
[r0
[0]]);
2426 *ptr
^= (0x30 & OffPixels
[r0
[0]]);
2428 if ((r0
[1] & 63) > dither
[x
& 7])
2429 *ptr
^= (0x0c & OnPixels
[r0
[1]]);
2431 *ptr
^= (0x0c & OffPixels
[r0
[1]]);
2433 if ((r0
[2] & 63) > dither
[x
& 7])
2434 *ptr
++ ^= (0x03 & OnPixels
[r0
[2]]);
2436 *ptr
++ ^= (0x03 & OffPixels
[r0
[2]]);
2441 dither
= Floyd4x4
[y
& 3];
2443 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
2445 if ((r0
[3] & 15) > dither
[x
& 3])
2446 *ptr
^= (0xf0 & OnPixels
[r0
[3]]);
2448 *ptr
^= (0xf0 & OffPixels
[r0
[3]]);
2450 if ((r0
[0] & 15) > dither
[x
& 3])
2451 *ptr
++ ^= (0x0f & OnPixels
[r0
[0]]);
2453 *ptr
++ ^= (0x0f & OffPixels
[r0
[0]]);
2455 if ((r0
[1] & 15) > dither
[x
& 3])
2456 *ptr
^= (0xf0 & OnPixels
[r0
[1]]);
2458 *ptr
^= (0xf0 & OffPixels
[r0
[1]]);
2460 if ((r0
[2] & 15) > dither
[x
& 3])
2461 *ptr
++ ^= (0x0f & OnPixels
[r0
[2]]);
2463 *ptr
++ ^= (0x0f & OffPixels
[r0
[2]]);
2468 for (x
= xsize
; x
> 0; x
--, r0
+= 4, r1
+= 4)
2473 *ptr
++ = (r0
[3] * yerr0
+ r1
[3] * yerr1
) / ysize
;
2478 *ptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
2483 *ptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
2488 *ptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
2494 case CUPS_ORDER_BANDED
:
2496 cptr
= ptr
+ bandwidth
;
2497 mptr
= ptr
+ 2 * bandwidth
;
2498 yptr
= ptr
+ 3 * bandwidth
;
2500 switch (header
->cupsBitsPerColor
)
2503 bitmask
= 0x80 >> (bitoffset
& 7);
2504 dither
= Floyd16x16
[y
& 15];
2506 for (x
= xsize
; x
> 0; x
--)
2508 pc
= *r0
++ > dither
[x
& 15];
2509 pm
= *r0
++ > dither
[x
& 15];
2510 py
= *r0
++ > dither
[x
& 15];
2538 bitmask
= 0xc0 >> (bitoffset
& 7);
2539 dither
= Floyd8x8
[y
& 7];
2541 for (x
= xsize
; x
> 0; x
--)
2543 if ((*r0
& 63) > dither
[x
& 7])
2544 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
2546 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
2548 if ((*r0
& 63) > dither
[x
& 7])
2549 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
2551 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
2553 if ((*r0
& 63) > dither
[x
& 7])
2554 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
2556 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
2558 if ((*r0
& 63) > dither
[x
& 7])
2559 *kptr
^= (bitmask
& OnPixels
[*r0
++]);
2561 *kptr
^= (bitmask
& OffPixels
[*r0
++]);
2578 bitmask
= 0xf0 >> (bitoffset
& 7);
2579 dither
= Floyd4x4
[y
& 3];
2581 for (x
= xsize
; x
> 0; x
--)
2583 if ((*r0
& 15) > dither
[x
& 3])
2584 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
2586 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
2588 if ((*r0
& 15) > dither
[x
& 3])
2589 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
2591 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
2593 if ((*r0
& 15) > dither
[x
& 3])
2594 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
2596 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
2598 if ((*r0
& 15) > dither
[x
& 3])
2599 *kptr
^= (bitmask
& OnPixels
[*r0
++]);
2601 *kptr
^= (bitmask
& OffPixels
[*r0
++]);
2603 if (bitmask
== 0xf0)
2618 for (x
= xsize
; x
> 0; x
--, r0
+= 4, r1
+= 4)
2623 *cptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
2628 *mptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
2633 *yptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
2638 *kptr
++ = (r0
[3] * yerr0
+ r1
[3] * yerr1
) / ysize
;
2644 case CUPS_ORDER_PLANAR
:
2645 switch (header
->cupsBitsPerColor
)
2648 bitmask
= 0x80 >> (bitoffset
& 7);
2649 dither
= Floyd16x16
[y
& 15];
2651 for (x
= xsize
; x
> 0; x
--)
2653 pc
= *r0
++ > dither
[x
& 15];
2654 pm
= *r0
++ > dither
[x
& 15];
2655 py
= *r0
++ > dither
[x
& 15];
2657 if ((pc
&& pm
&& py
&& z
== 0) ||
2658 (pc
&& z
== 1) || (pm
&& z
== 2) || (py
&& z
== 3))
2672 bitmask
= 0xc0 >> (bitoffset
& 7);
2673 dither
= Floyd8x8
[y
& 7];
2679 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
2681 if ((*r0
& 63) > dither
[x
& 7])
2682 *ptr
^= (bitmask
& OnPixels
[*r0
]);
2684 *ptr
^= (bitmask
& OffPixels
[*r0
]);
2698 bitmask
= 0xf0 >> (bitoffset
& 7);
2699 dither
= Floyd4x4
[y
& 3];
2705 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
2707 if ((*r0
& 15) > dither
[x
& 3])
2708 *ptr
^= (bitmask
& OnPixels
[*r0
]);
2710 *ptr
^= (bitmask
& OffPixels
[*r0
]);
2712 if (bitmask
== 0xf0)
2735 for (x
= xsize
; x
> 0; x
--, r0
+= 4, r1
+= 4)
2740 *ptr
++ = (*r0
* yerr0
+ *r1
* yerr1
) / ysize
;
2750 * 'format_KCMYcm()' - Convert image data to KCMYcm.
2755 cups_page_header2_t
*header
, /* I - Page header */
2756 unsigned char *row
, /* IO - Bitmap data for device */
2757 int y
, /* I - Current row */
2758 int z
, /* I - Current plane */
2759 int xsize
, /* I - Width of image data */
2760 int ysize
, /* I - Height of image data */
2761 int yerr0
, /* I - Top Y error */
2762 int yerr1
, /* I - Bottom Y error */
2763 cups_ib_t
*r0
, /* I - Primary image data */
2764 cups_ib_t
*r1
) /* I - Image data for interpolation */
2766 int pc
, pm
, py
, pk
; /* Cyan, magenta, yellow, and black values */
2767 cups_ib_t
*ptr
, /* Pointer into row */
2768 *cptr
, /* Pointer into cyan */
2769 *mptr
, /* Pointer into magenta */
2770 *yptr
, /* Pointer into yellow */
2771 *kptr
, /* Pointer into black */
2772 *lcptr
, /* Pointer into light cyan */
2773 *lmptr
, /* Pointer into light magenta */
2774 bitmask
; /* Current mask for pixel */
2775 int bitoffset
; /* Current offset in line */
2776 int bandwidth
; /* Width of a color band */
2777 int x
, /* Current X coordinate on page */
2778 *dither
; /* Pointer into dither array */
2787 bitoffset
= header
->cupsBitsPerPixel
* ((header
->cupsWidth
- xsize
) / 2);
2790 bitoffset
= header
->cupsBitsPerPixel
* (header
->cupsWidth
- xsize
);
2794 ptr
= row
+ bitoffset
/ 8;
2795 bandwidth
= header
->cupsBytesPerLine
/ 6;
2797 switch (header
->cupsColorOrder
)
2799 case CUPS_ORDER_CHUNKED
:
2800 dither
= Floyd16x16
[y
& 15];
2802 for (x
= xsize
; x
> 0; x
--)
2804 pc
= *r0
++ > dither
[x
& 15];
2805 pm
= *r0
++ > dither
[x
& 15];
2806 py
= *r0
++ > dither
[x
& 15];
2807 pk
= pc
&& pm
&& py
;
2810 *ptr
++ ^= 32; /* Black */
2812 *ptr
++ ^= 17; /* Blue (cyan + light magenta) */
2814 *ptr
++ ^= 6; /* Green (light cyan + yellow) */
2816 *ptr
++ ^= 12; /* Red (magenta + yellow) */
2828 case CUPS_ORDER_BANDED
:
2830 cptr
= ptr
+ bandwidth
;
2831 mptr
= ptr
+ 2 * bandwidth
;
2832 yptr
= ptr
+ 3 * bandwidth
;
2833 lcptr
= ptr
+ 4 * bandwidth
;
2834 lmptr
= ptr
+ 5 * bandwidth
;
2836 bitmask
= 0x80 >> (bitoffset
& 7);
2837 dither
= Floyd16x16
[y
& 15];
2839 for (x
= xsize
; x
> 0; x
--)
2841 pc
= *r0
++ > dither
[x
& 15];
2842 pm
= *r0
++ > dither
[x
& 15];
2843 py
= *r0
++ > dither
[x
& 15];
2844 pk
= pc
&& pm
&& py
;
2847 *kptr
^= bitmask
; /* Black */
2850 *cptr
^= bitmask
; /* Blue (cyan + light magenta) */
2855 *lcptr
^= bitmask
; /* Green (light cyan + yellow) */
2860 *mptr
^= bitmask
; /* Red (magenta + yellow) */
2885 case CUPS_ORDER_PLANAR
:
2886 bitmask
= 0x80 >> (bitoffset
& 7);
2887 dither
= Floyd16x16
[y
& 15];
2889 for (x
= xsize
; x
> 0; x
--)
2891 pc
= *r0
++ > dither
[x
& 15];
2892 pm
= *r0
++ > dither
[x
& 15];
2893 py
= *r0
++ > dither
[x
& 15];
2894 pk
= pc
&& pm
&& py
;
2898 else if (pc
&& pm
&& (z
== 1 || z
== 5))
2899 *ptr
^= bitmask
; /* Blue (cyan + light magenta) */
2900 else if (pc
&& py
&& (z
== 3 || z
== 4))
2901 *ptr
^= bitmask
; /* Green (light cyan + yellow) */
2902 else if (pm
&& py
&& (z
== 2 || z
== 3))
2903 *ptr
^= bitmask
; /* Red (magenta + yellow) */
2904 else if (pc
&& z
== 1)
2906 else if (pm
&& z
== 2)
2908 else if (py
&& z
== 3)
2925 * 'format_RGBA()' - Convert image data to RGBA/RGBW.
2929 format_RGBA(cups_page_header2_t
*header
,/* I - Page header */
2930 unsigned char *row
, /* IO - Bitmap data for device */
2931 int y
, /* I - Current row */
2932 int z
, /* I - Current plane */
2933 int xsize
, /* I - Width of image data */
2934 int ysize
, /* I - Height of image data */
2935 int yerr0
, /* I - Top Y error */
2936 int yerr1
, /* I - Bottom Y error */
2937 cups_ib_t
*r0
, /* I - Primary image data */
2938 cups_ib_t
*r1
) /* I - Image data for interpolation */
2940 cups_ib_t
*ptr
, /* Pointer into row */
2941 *cptr
, /* Pointer into cyan */
2942 *mptr
, /* Pointer into magenta */
2943 *yptr
, /* Pointer into yellow */
2944 bitmask
; /* Current mask for pixel */
2945 int bitoffset
; /* Current offset in line */
2946 int bandwidth
; /* Width of a color band */
2947 int x
, /* Current X coordinate on page */
2948 *dither
; /* Pointer into dither array */
2957 bitoffset
= header
->cupsBitsPerPixel
* ((header
->cupsWidth
- xsize
) / 2);
2960 bitoffset
= header
->cupsBitsPerPixel
* (header
->cupsWidth
- xsize
);
2964 ptr
= row
+ bitoffset
/ 8;
2965 bandwidth
= header
->cupsBytesPerLine
/ 4;
2967 switch (header
->cupsColorOrder
)
2969 case CUPS_ORDER_CHUNKED
:
2970 switch (header
->cupsBitsPerColor
)
2973 bitmask
= 128 >> (bitoffset
& 7);
2974 dither
= Floyd16x16
[y
& 15];
2976 for (x
= xsize
; x
> 0; x
--)
2978 if (*r0
++ > dither
[x
& 15])
2982 if (*r0
++ > dither
[x
& 15])
2986 if (*r0
++ > dither
[x
& 15])
3000 dither
= Floyd8x8
[y
& 7];
3002 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3004 if ((r0
[0] & 63) > dither
[x
& 7])
3005 *ptr
^= (0xc0 & OnPixels
[r0
[0]]);
3007 *ptr
^= (0xc0 & OffPixels
[r0
[0]]);
3009 if ((r0
[1] & 63) > dither
[x
& 7])
3010 *ptr
^= (0x30 & OnPixels
[r0
[1]]);
3012 *ptr
^= (0x30 & OffPixels
[r0
[1]]);
3014 if ((r0
[2] & 63) > dither
[x
& 7])
3015 *ptr
^= (0x0c & OnPixels
[r0
[2]]);
3017 *ptr
^= (0x0c & OffPixels
[r0
[2]]);
3024 dither
= Floyd4x4
[y
& 3];
3026 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3028 if ((r0
[0] & 15) > dither
[x
& 3])
3029 *ptr
^= (0xf0 & OnPixels
[r0
[0]]);
3031 *ptr
^= (0xf0 & OffPixels
[r0
[0]]);
3033 if ((r0
[1] & 15) > dither
[x
& 3])
3034 *ptr
++ ^= (0x0f & OnPixels
[r0
[1]]);
3036 *ptr
++ ^= (0x0f & OffPixels
[r0
[1]]);
3038 if ((r0
[2] & 15) > dither
[x
& 3])
3039 *ptr
^= (0xf0 & OnPixels
[r0
[2]]);
3041 *ptr
^= (0xf0 & OffPixels
[r0
[2]]);
3048 for (x
= xsize
; x
> 0; x
--, r0
+= 3, r1
+= 3)
3053 *ptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
3058 *ptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
3063 *ptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
3071 case CUPS_ORDER_BANDED
:
3073 mptr
= ptr
+ bandwidth
;
3074 yptr
= ptr
+ 2 * bandwidth
;
3076 memset(ptr
+ 3 * bandwidth
, 255, bandwidth
);
3078 switch (header
->cupsBitsPerColor
)
3081 bitmask
= 0x80 >> (bitoffset
& 7);
3082 dither
= Floyd16x16
[y
& 15];
3084 for (x
= xsize
; x
> 0; x
--)
3086 if (*r0
++ > dither
[x
& 15])
3088 if (*r0
++ > dither
[x
& 15])
3090 if (*r0
++ > dither
[x
& 15])
3106 bitmask
= 0xc0 >> (bitoffset
& 7);
3107 dither
= Floyd8x8
[y
& 7];
3109 for (x
= xsize
; x
> 0; x
--)
3111 if ((*r0
& 63) > dither
[x
& 7])
3112 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
3114 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
3116 if ((*r0
& 63) > dither
[x
& 7])
3117 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
3119 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
3121 if ((*r0
& 63) > dither
[x
& 7])
3122 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
3124 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
3140 bitmask
= 0xf0 >> (bitoffset
& 7);
3141 dither
= Floyd4x4
[y
& 3];
3143 for (x
= xsize
; x
> 0; x
--)
3145 if ((*r0
& 15) > dither
[x
& 3])
3146 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
3148 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
3150 if ((*r0
& 15) > dither
[x
& 3])
3151 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
3153 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
3155 if ((*r0
& 15) > dither
[x
& 3])
3156 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
3158 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
3160 if (bitmask
== 0xf0)
3174 for (x
= xsize
; x
> 0; x
--, r0
+= 3, r1
+= 3)
3179 *cptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
3184 *mptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
3189 *yptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
3195 case CUPS_ORDER_PLANAR
:
3198 memset(row
, 255, header
->cupsBytesPerLine
);
3202 switch (header
->cupsBitsPerColor
)
3205 bitmask
= 0x80 >> (bitoffset
& 7);
3206 dither
= Floyd16x16
[y
& 15];
3211 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3213 if (r0
[0] > dither
[x
& 15])
3227 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3229 if (r0
[1] > dither
[x
& 15])
3243 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3245 if (r0
[2] > dither
[x
& 15])
3261 bitmask
= 0xc0 >> (bitoffset
& 7);
3262 dither
= Floyd8x8
[y
& 7];
3265 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3267 if ((*r0
& 63) > dither
[x
& 7])
3268 *ptr
^= (bitmask
& OnPixels
[*r0
]);
3270 *ptr
^= (bitmask
& OffPixels
[*r0
]);
3284 bitmask
= 0xf0 >> (bitoffset
& 7);
3285 dither
= Floyd4x4
[y
& 3];
3288 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3290 if ((*r0
& 15) > dither
[x
& 3])
3291 *ptr
^= (bitmask
& OnPixels
[*r0
]);
3293 *ptr
^= (bitmask
& OffPixels
[*r0
]);
3295 if (bitmask
== 0xf0)
3310 for (x
= xsize
; x
> 0; x
--, r0
+= 3, r1
+= 3)
3315 *ptr
++ = (*r0
* yerr0
+ *r1
* yerr1
) / ysize
;
3325 * 'format_W()' - Convert image data to luminance.
3329 format_W(cups_page_header2_t
*header
, /* I - Page header */
3330 unsigned char *row
, /* IO - Bitmap data for device */
3331 int y
, /* I - Current row */
3332 int z
, /* I - Current plane */
3333 int xsize
, /* I - Width of image data */
3334 int ysize
, /* I - Height of image data */
3335 int yerr0
, /* I - Top Y error */
3336 int yerr1
, /* I - Bottom Y error */
3337 cups_ib_t
*r0
, /* I - Primary image data */
3338 cups_ib_t
*r1
) /* I - Image data for interpolation */
3340 cups_ib_t
*ptr
, /* Pointer into row */
3341 bitmask
; /* Current mask for pixel */
3342 int bitoffset
; /* Current offset in line */
3343 int x
, /* Current X coordinate on page */
3344 *dither
; /* Pointer into dither array */
3355 bitoffset
= header
->cupsBitsPerPixel
* ((header
->cupsWidth
- xsize
) / 2);
3358 bitoffset
= header
->cupsBitsPerPixel
* (header
->cupsWidth
- xsize
);
3362 ptr
= row
+ bitoffset
/ 8;
3364 switch (header
->cupsBitsPerColor
)
3367 bitmask
= 0x80 >> (bitoffset
& 7);
3368 dither
= Floyd16x16
[y
& 15];
3370 for (x
= xsize
; x
> 0; x
--)
3372 if (*r0
++ > dither
[x
& 15])
3386 bitmask
= 0xc0 >> (bitoffset
& 7);
3387 dither
= Floyd8x8
[y
& 7];
3389 for (x
= xsize
; x
> 0; x
--)
3391 if ((*r0
& 63) > dither
[x
& 7])
3392 *ptr
^= (bitmask
& OnPixels
[*r0
++]);
3394 *ptr
^= (bitmask
& OffPixels
[*r0
++]);
3408 bitmask
= 0xf0 >> (bitoffset
& 7);
3409 dither
= Floyd4x4
[y
& 3];
3411 for (x
= xsize
; x
> 0; x
--)
3413 if ((*r0
& 15) > dither
[x
& 3])
3414 *ptr
^= (bitmask
& OnPixels
[*r0
++]);
3416 *ptr
^= (bitmask
& OffPixels
[*r0
++]);
3418 if (bitmask
== 0xf0)
3430 for (x
= xsize
; x
> 0; x
--, r0
++, r1
++)
3435 *ptr
++ = (*r0
* yerr0
+ *r1
* yerr1
) / ysize
;
3443 * 'format_YMC()' - Convert image data to YMC.
3447 format_YMC(cups_page_header2_t
*header
, /* I - Page header */
3448 unsigned char *row
, /* IO - Bitmap data for device */
3449 int y
, /* I - Current row */
3450 int z
, /* I - Current plane */
3451 int xsize
, /* I - Width of image data */
3452 int ysize
, /* I - Height of image data */
3453 int yerr0
, /* I - Top Y error */
3454 int yerr1
, /* I - Bottom Y error */
3455 cups_ib_t
*r0
, /* I - Primary image data */
3456 cups_ib_t
*r1
) /* I - Image data for interpolation */
3458 cups_ib_t
*ptr
, /* Pointer into row */
3459 *cptr
, /* Pointer into cyan */
3460 *mptr
, /* Pointer into magenta */
3461 *yptr
, /* Pointer into yellow */
3462 bitmask
; /* Current mask for pixel */
3463 int bitoffset
; /* Current offset in line */
3464 int bandwidth
; /* Width of a color band */
3465 int x
, /* Current X coordinate on page */
3466 *dither
; /* Pointer into dither array */
3475 bitoffset
= header
->cupsBitsPerPixel
* ((header
->cupsWidth
- xsize
) / 2);
3478 bitoffset
= header
->cupsBitsPerPixel
* (header
->cupsWidth
- xsize
);
3482 ptr
= row
+ bitoffset
/ 8;
3483 bandwidth
= header
->cupsBytesPerLine
/ 3;
3485 switch (header
->cupsColorOrder
)
3487 case CUPS_ORDER_CHUNKED
:
3488 switch (header
->cupsBitsPerColor
)
3491 bitmask
= 64 >> (bitoffset
& 7);
3492 dither
= Floyd16x16
[y
& 15];
3494 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3496 if (r0
[2] > dither
[x
& 15])
3500 if (r0
[1] > dither
[x
& 15])
3504 if (r0
[0] > dither
[x
& 15])
3518 dither
= Floyd8x8
[y
& 7];
3520 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3522 if ((r0
[2] & 63) > dither
[x
& 7])
3523 *ptr
^= (0x30 & OnPixels
[r0
[2]]);
3525 *ptr
^= (0x30 & OffPixels
[r0
[2]]);
3527 if ((r0
[1] & 63) > dither
[x
& 7])
3528 *ptr
^= (0x0c & OnPixels
[r0
[1]]);
3530 *ptr
^= (0x0c & OffPixels
[r0
[1]]);
3532 if ((r0
[0] & 63) > dither
[x
& 7])
3533 *ptr
++ ^= (0x03 & OnPixels
[r0
[0]]);
3535 *ptr
++ ^= (0x03 & OffPixels
[r0
[0]]);
3540 dither
= Floyd4x4
[y
& 3];
3542 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3544 if ((r0
[2] & 15) > dither
[x
& 3])
3545 *ptr
++ ^= (0x0f & OnPixels
[r0
[2]]);
3547 *ptr
++ ^= (0x0f & OffPixels
[r0
[2]]);
3549 if ((r0
[1] & 15) > dither
[x
& 3])
3550 *ptr
^= (0xf0 & OnPixels
[r0
[1]]);
3552 *ptr
^= (0xf0 & OffPixels
[r0
[1]]);
3554 if ((r0
[0] & 15) > dither
[x
& 3])
3555 *ptr
++ ^= (0x0f & OnPixels
[r0
[0]]);
3557 *ptr
++ ^= (0x0f & OffPixels
[r0
[0]]);
3562 for (x
= xsize
; x
> 0; x
--, r0
+= 3, r1
+= 3)
3567 *ptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
3572 *ptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
3577 *ptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
3583 case CUPS_ORDER_BANDED
:
3585 mptr
= ptr
+ bandwidth
;
3586 cptr
= ptr
+ 2 * bandwidth
;
3588 switch (header
->cupsBitsPerColor
)
3591 bitmask
= 0x80 >> (bitoffset
& 7);
3592 dither
= Floyd16x16
[y
& 15];
3594 for (x
= xsize
; x
> 0; x
--)
3596 if (*r0
++ > dither
[x
& 15])
3598 if (*r0
++ > dither
[x
& 15])
3600 if (*r0
++ > dither
[x
& 15])
3616 bitmask
= 0xc0 >> (bitoffset
& 7);
3617 dither
= Floyd8x8
[y
& 7];
3619 for (x
= xsize
; x
> 0; x
--)
3621 if ((*r0
& 63) > dither
[x
& 7])
3622 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
3624 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
3626 if ((*r0
& 63) > dither
[x
& 7])
3627 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
3629 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
3631 if ((*r0
& 63) > dither
[x
& 7])
3632 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
3634 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
3650 bitmask
= 0xf0 >> (bitoffset
& 7);
3651 dither
= Floyd4x4
[y
& 3];
3653 for (x
= xsize
; x
> 0; x
--)
3655 if ((*r0
& 15) > dither
[x
& 3])
3656 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
3658 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
3660 if ((*r0
& 15) > dither
[x
& 3])
3661 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
3663 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
3665 if ((*r0
& 15) > dither
[x
& 3])
3666 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
3668 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
3670 if (bitmask
== 0xf0)
3684 for (x
= xsize
; x
> 0; x
--, r0
+= 3, r1
+= 3)
3689 *cptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
3694 *mptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
3699 *yptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
3705 case CUPS_ORDER_PLANAR
:
3706 switch (header
->cupsBitsPerColor
)
3709 bitmask
= 0x80 >> (bitoffset
& 7);
3710 dither
= Floyd16x16
[y
& 15];
3715 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3717 if (r0
[0] > dither
[x
& 15])
3731 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3733 if (r0
[1] > dither
[x
& 15])
3747 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3749 if (r0
[2] > dither
[x
& 15])
3765 bitmask
= 0xc0 >> (bitoffset
& 7);
3766 dither
= Floyd8x8
[y
& 7];
3770 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3772 if ((*r0
& 63) > dither
[x
& 7])
3773 *ptr
^= (bitmask
& OnPixels
[*r0
]);
3775 *ptr
^= (bitmask
& OffPixels
[*r0
]);
3789 bitmask
= 0xf0 >> (bitoffset
& 7);
3790 dither
= Floyd4x4
[y
& 3];
3794 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3796 if ((*r0
& 15) > dither
[x
& 3])
3797 *ptr
^= (bitmask
& OnPixels
[*r0
]);
3799 *ptr
^= (bitmask
& OffPixels
[*r0
]);
3801 if (bitmask
== 0xf0)
3817 for (x
= xsize
; x
> 0; x
--, r0
+= 3, r1
+= 3)
3822 *ptr
++ = (*r0
* yerr0
+ *r1
* yerr1
) / ysize
;
3832 * 'format_YMCK()' - Convert image data to YMCK.
3836 format_YMCK(cups_page_header2_t
*header
,/* I - Page header */
3837 unsigned char *row
, /* IO - Bitmap data for device */
3838 int y
, /* I - Current row */
3839 int z
, /* I - Current plane */
3840 int xsize
, /* I - Width of image data */
3841 int ysize
, /* I - Height of image data */
3842 int yerr0
, /* I - Top Y error */
3843 int yerr1
, /* I - Bottom Y error */
3844 cups_ib_t
*r0
, /* I - Primary image data */
3845 cups_ib_t
*r1
) /* I - Image data for interpolation */
3847 cups_ib_t
*ptr
, /* Pointer into row */
3848 *cptr
, /* Pointer into cyan */
3849 *mptr
, /* Pointer into magenta */
3850 *yptr
, /* Pointer into yellow */
3851 *kptr
, /* Pointer into black */
3852 bitmask
; /* Current mask for pixel */
3853 int bitoffset
; /* Current offset in line */
3854 int bandwidth
; /* Width of a color band */
3855 int x
, /* Current X coordinate on page */
3856 *dither
; /* Pointer into dither array */
3857 int pc
, pm
, py
; /* CMY pixels */
3866 bitoffset
= header
->cupsBitsPerPixel
* ((header
->cupsWidth
- xsize
) / 2);
3869 bitoffset
= header
->cupsBitsPerPixel
* (header
->cupsWidth
- xsize
);
3873 ptr
= row
+ bitoffset
/ 8;
3874 bandwidth
= header
->cupsBytesPerLine
/ 4;
3876 switch (header
->cupsColorOrder
)
3878 case CUPS_ORDER_CHUNKED
:
3879 switch (header
->cupsBitsPerColor
)
3882 bitmask
= 128 >> (bitoffset
& 7);
3883 dither
= Floyd16x16
[y
& 15];
3885 for (x
= xsize
; x
> 0; x
--)
3887 pc
= *r0
++ > dither
[x
& 15];
3888 pm
= *r0
++ > dither
[x
& 15];
3889 py
= *r0
++ > dither
[x
& 15];
3923 dither
= Floyd8x8
[y
& 7];
3925 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
3927 if ((r0
[2] & 63) > dither
[x
& 7])
3928 *ptr
^= (0xc0 & OnPixels
[r0
[2]]);
3930 *ptr
^= (0xc0 & OffPixels
[r0
[2]]);
3932 if ((r0
[1] & 63) > dither
[x
& 7])
3933 *ptr
^= (0x30 & OnPixels
[r0
[1]]);
3935 *ptr
^= (0x30 & OffPixels
[r0
[1]]);
3937 if ((r0
[0] & 63) > dither
[x
& 7])
3938 *ptr
^= (0x0c & OnPixels
[r0
[0]]);
3940 *ptr
^= (0x0c & OffPixels
[r0
[0]]);
3942 if ((r0
[3] & 63) > dither
[x
& 7])
3943 *ptr
++ ^= (0x03 & OnPixels
[r0
[3]]);
3945 *ptr
++ ^= (0x03 & OffPixels
[r0
[3]]);
3950 dither
= Floyd4x4
[y
& 3];
3952 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
3954 if ((r0
[2] & 15) > dither
[x
& 3])
3955 *ptr
^= (0xf0 & OnPixels
[r0
[2]]);
3957 *ptr
^= (0xf0 & OffPixels
[r0
[2]]);
3959 if ((r0
[1] & 15) > dither
[x
& 3])
3960 *ptr
++ ^= (0x0f & OnPixels
[r0
[1]]);
3962 *ptr
++ ^= (0x0f & OffPixels
[r0
[1]]);
3964 if ((r0
[0] & 15) > dither
[x
& 3])
3965 *ptr
^= (0xf0 & OnPixels
[r0
[0]]);
3967 *ptr
^= (0xf0 & OffPixels
[r0
[0]]);
3969 if ((r0
[3] & 15) > dither
[x
& 3])
3970 *ptr
++ ^= (0x0f & OnPixels
[r0
[3]]);
3972 *ptr
++ ^= (0x0f & OffPixels
[r0
[3]]);
3977 for (x
= xsize
; x
> 0; x
--, r0
+= 4, r1
+= 4)
3982 *ptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
3987 *ptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
3992 *ptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
3997 *ptr
++ = (r0
[3] * yerr0
+ r1
[3] * yerr1
) / ysize
;
4003 case CUPS_ORDER_BANDED
:
4005 mptr
= ptr
+ bandwidth
;
4006 cptr
= ptr
+ 2 * bandwidth
;
4007 kptr
= ptr
+ 3 * bandwidth
;
4009 switch (header
->cupsBitsPerColor
)
4012 bitmask
= 0x80 >> (bitoffset
& 7);
4013 dither
= Floyd16x16
[y
& 15];
4015 for (x
= xsize
; x
> 0; x
--)
4017 pc
= *r0
++ > dither
[x
& 15];
4018 pm
= *r0
++ > dither
[x
& 15];
4019 py
= *r0
++ > dither
[x
& 15];
4048 bitmask
= 0xc0 >> (bitoffset
& 7);
4049 dither
= Floyd8x8
[y
& 7];
4051 for (x
= xsize
; x
> 0; x
--)
4053 if ((*r0
& 63) > dither
[x
& 7])
4054 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
4056 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
4058 if ((*r0
& 63) > dither
[x
& 7])
4059 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
4061 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
4063 if ((*r0
& 63) > dither
[x
& 7])
4064 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
4066 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
4068 if ((*r0
& 63) > dither
[x
& 7])
4069 *kptr
^= (bitmask
& OnPixels
[*r0
++]);
4071 *kptr
^= (bitmask
& OffPixels
[*r0
++]);
4088 bitmask
= 0xf0 >> (bitoffset
& 7);
4089 dither
= Floyd4x4
[y
& 3];
4091 for (x
= xsize
; x
> 0; x
--)
4093 if ((*r0
& 15) > dither
[x
& 3])
4094 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
4096 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
4098 if ((*r0
& 15) > dither
[x
& 3])
4099 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
4101 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
4103 if ((*r0
& 15) > dither
[x
& 3])
4104 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
4106 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
4108 if ((*r0
& 15) > dither
[x
& 3])
4109 *kptr
^= (bitmask
& OnPixels
[*r0
++]);
4111 *kptr
^= (bitmask
& OffPixels
[*r0
++]);
4113 if (bitmask
== 0xf0)
4128 for (x
= xsize
; x
> 0; x
--, r0
+= 4, r1
+= 4)
4133 *cptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
4138 *mptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
4143 *yptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
4148 *kptr
++ = (r0
[3] * yerr0
+ r1
[3] * yerr1
) / ysize
;
4154 case CUPS_ORDER_PLANAR
:
4155 switch (header
->cupsBitsPerColor
)
4158 bitmask
= 0x80 >> (bitoffset
& 7);
4159 dither
= Floyd16x16
[y
& 15];
4161 for (x
= xsize
; x
> 0; x
--)
4163 pc
= *r0
++ > dither
[x
& 15];
4164 pm
= *r0
++ > dither
[x
& 15];
4165 py
= *r0
++ > dither
[x
& 15];
4167 if ((pc
&& pm
&& py
&& z
== 3) ||
4168 (pc
&& z
== 2) || (pm
&& z
== 1) || (py
&& z
== 0))
4182 bitmask
= 0xc0 >> (bitoffset
& 7);
4183 dither
= Floyd8x8
[y
& 7];
4189 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
4191 if ((*r0
& 63) > dither
[x
& 7])
4192 *ptr
^= (bitmask
& OnPixels
[*r0
]);
4194 *ptr
^= (bitmask
& OffPixels
[*r0
]);
4208 bitmask
= 0xf0 >> (bitoffset
& 7);
4209 dither
= Floyd4x4
[y
& 3];
4215 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
4217 if ((*r0
& 15) > dither
[x
& 3])
4218 *ptr
^= (bitmask
& OnPixels
[*r0
]);
4220 *ptr
^= (bitmask
& OffPixels
[*r0
]);
4222 if (bitmask
== 0xf0)
4245 for (x
= xsize
; x
> 0; x
--, r0
+= 4, r1
+= 4)
4250 *ptr
++ = (*r0
* yerr0
+ *r1
* yerr1
) / ysize
;
4260 * 'make_lut()' - Make a lookup table given gamma and brightness values.
4264 make_lut(cups_ib_t
*lut
, /* I - Lookup table */
4265 int colorspace
, /* I - Colorspace */
4266 float g
, /* I - Image gamma */
4267 float b
) /* I - Image brightness */
4269 int i
; /* Looping var */
4270 int v
; /* Current value */
4276 for (i
= 0; i
< 256; i
++)
4279 v
= 255.0 * b
* (1.0 - pow(1.0 - (float)i
/ 255.0, g
)) + 0.5;
4281 v
= 255.0 * (1.0 - b
* (1.0 - pow((float)i
/ 255.0, g
))) + 0.5;
4294 * 'raster_cb()' - Validate the page header.
4297 static int /* O - 0 if OK, -1 if not */
4299 cups_page_header2_t
*header
, /* IO - Raster header */
4300 int preferred_bits
) /* I - Preferred bits per color */
4303 * Ensure that colorimetric colorspaces use at least 8 bits per
4307 if ((header
->cupsColorSpace
== CUPS_CSPACE_CIEXYZ
||
4308 header
->cupsColorSpace
== CUPS_CSPACE_CIELab
||
4309 header
->cupsColorSpace
>= CUPS_CSPACE_ICC1
) &&
4310 header
->cupsBitsPerColor
< 8)
4311 header
->cupsBitsPerColor
= 8;
4318 * End of "$Id: imagetoraster.c 7306 2008-02-15 00:52:38Z mike $".