2 * "$Id: imagetoraster.c 5485 2006-05-02 23:59:56Z mike $"
4 * Image file to raster filter for the Common UNIX Printing System (CUPS).
6 * Copyright 1993-2006 by Easy Software Products.
8 * These coded instructions, statements, and computer programs are the
9 * property of Easy Software Products and are protected by Federal
10 * copyright law. Distribution and use rights are outlined in the file
11 * "LICENSE.txt" which should have been included with this file. If this
12 * file is missing or damaged please contact Easy Software Products
15 * Attn: CUPS Licensing Information
16 * Easy Software Products
17 * 44141 Airport View Drive, Suite 204
18 * Hollywood, Maryland 20636 USA
20 * Voice: (301) 373-9600
21 * EMail: cups-info@cups.org
22 * WWW: http://www.cups.org
24 * This file is subject to the Apple OS-Developed Software exception.
28 * main() - Main entry...
29 * format_CMY() - Convert image data to CMY.
30 * format_CMYK() - Convert image data to CMYK.
31 * format_K() - Convert image data to black.
32 * format_KCMY() - Convert image data to KCMY.
33 * format_KCMYcm() - Convert image data to KCMYcm.
34 * format_RGBA() - Convert image data to RGBA/RGBW.
35 * format_W() - Convert image data to luminance.
36 * format_YMC() - Convert image data to YMC.
37 * format_YMCK() - Convert image data to YMCK.
38 * make_lut() - Make a lookup table given gamma and brightness values.
39 * raster_cb() - Validate the page header.
43 * Include necessary headers...
47 #include "image-private.h"
57 int Flip
= 0, /* Flip/mirror pages */
58 XPosition
= 0, /* Horizontal position on page */
59 YPosition
= 0, /* Vertical position on page */
60 Collate
= 0, /* Collate copies? */
61 Copies
= 1; /* Number of copies */
62 int Floyd16xc16
[16][16] = /* Traditional Floyd ordered dither */
64 { 0, 128, 32, 160, 8, 136, 40, 168,
65 2, 130, 34, 162, 10, 138, 42, 170 },
66 { 192, 64, 224, 96, 200, 72, 232, 104,
67 194, 66, 226, 98, 202, 74, 234, 106 },
68 { 48, 176, 16, 144, 56, 184, 24, 152,
69 50, 178, 18, 146, 58, 186, 26, 154 },
70 { 240, 112, 208, 80, 248, 120, 216, 88,
71 242, 114, 210, 82, 250, 122, 218, 90 },
72 { 12, 140, 44, 172, 4, 132, 36, 164,
73 14, 142, 46, 174, 6, 134, 38, 166 },
74 { 204, 76, 236, 108, 196, 68, 228, 100,
75 206, 78, 238, 110, 198, 70, 230, 102 },
76 { 60, 188, 28, 156, 52, 180, 20, 148,
77 62, 190, 30, 158, 54, 182, 22, 150 },
78 { 252, 124, 220, 92, 244, 116, 212, 84,
79 254, 126, 222, 94, 246, 118, 214, 86 },
80 { 3, 131, 35, 163, 11, 139, 43, 171,
81 1, 129, 33, 161, 9, 137, 41, 169 },
82 { 195, 67, 227, 99, 203, 75, 235, 107,
83 193, 65, 225, 97, 201, 73, 233, 105 },
84 { 51, 179, 19, 147, 59, 187, 27, 155,
85 49, 177, 17, 145, 57, 185, 25, 153 },
86 { 243, 115, 211, 83, 251, 123, 219, 91,
87 241, 113, 209, 81, 249, 121, 217, 89 },
88 { 15, 143, 47, 175, 7, 135, 39, 167,
89 13, 141, 45, 173, 5, 133, 37, 165 },
90 { 207, 79, 239, 111, 199, 71, 231, 103,
91 205, 77, 237, 109, 197, 69, 229, 101 },
92 { 63, 191, 31, 159, 55, 183, 23, 151,
93 61, 189, 29, 157, 53, 181, 21, 149 },
94 { 254, 127, 223, 95, 247, 119, 215, 87,
95 253, 125, 221, 93, 245, 117, 213, 85 }
99 { 0, 32, 8, 40, 2, 34, 10, 42 },
100 { 48, 16, 56, 24, 50, 18, 58, 26 },
101 { 12, 44, 4, 36, 14, 46, 6, 38 },
102 { 60, 28, 52, 20, 62, 30, 54, 22 },
103 { 3, 35, 11, 43, 1, 33, 9, 41 },
104 { 51, 19, 59, 27, 49, 17, 57, 25 },
105 { 15, 47, 7, 39, 13, 45, 5, 37 },
106 { 63, 31, 55, 23, 61, 29, 53, 21 }
116 cups_ib_t OnPixels
[256], /* On-pixel LUT */
117 OffPixels
[256]; /* Off-pixel LUT */
118 int Planes
[] = /* Number of planes for each colorspace */
120 1, /* CUPS_CSPACE_W */
121 3, /* CUPS_CSPACE_RGB */
122 4, /* CUPS_CSPACE_RGBA */
123 1, /* CUPS_CSPACE_K */
124 3, /* CUPS_CSPACE_CMY */
125 3, /* CUPS_CSPACE_YMC */
126 4, /* CUPS_CSPACE_CMYK */
127 4, /* CUPS_CSPACE_YMCK */
128 4, /* CUPS_CSPACE_KCMY */
129 6, /* CUPS_CSPACE_KCMYcm */
130 4, /* CUPS_CSPACE_GMCK */
131 4, /* CUPS_CSPACE_GMCS */
132 1, /* CUPS_CSPACE_WHITE */
133 1, /* CUPS_CSPACE_GOLD */
134 1, /* CUPS_CSPACE_SILVER */
135 3, /* CUPS_CSPACE_CIEXYZ */
136 3, /* CUPS_CSPACE_CIELab */
137 4, /* CUPS_CSPACE_RGBW */
138 0, /* ... reserved ... */
139 0, /* ... reserved ... */
140 0, /* ... reserved ... */
141 0, /* ... reserved ... */
142 0, /* ... reserved ... */
143 0, /* ... reserved ... */
144 0, /* ... reserved ... */
145 0, /* ... reserved ... */
146 0, /* ... reserved ... */
147 0, /* ... reserved ... */
148 0, /* ... reserved ... */
149 0, /* ... reserved ... */
150 0, /* ... reserved ... */
151 0, /* ... reserved ... */
152 3, /* CUPS_CSPACE_ICC1 */
153 3, /* CUPS_CSPACE_ICC2 */
154 3, /* CUPS_CSPACE_ICC3 */
155 3, /* CUPS_CSPACE_ICC4 */
156 3, /* CUPS_CSPACE_ICC5 */
157 3, /* CUPS_CSPACE_ICC6 */
158 3, /* CUPS_CSPACE_ICC7 */
159 3, /* CUPS_CSPACE_ICC8 */
160 3, /* CUPS_CSPACE_ICC9 */
161 3, /* CUPS_CSPACE_ICCA */
162 3, /* CUPS_CSPACE_ICCB */
163 3, /* CUPS_CSPACE_ICCC */
164 3, /* CUPS_CSPACE_ICCD */
165 3, /* CUPS_CSPACE_ICCE */
166 3 /* CUPS_CSPACE_ICCF */
174 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
);
175 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
);
176 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
);
177 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
);
178 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
);
179 #define format_RGB format_CMY
180 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
);
181 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
);
182 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
);
183 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
);
184 static void make_lut(cups_ib_t
*, int, float, float);
185 static int raster_cb(cups_page_header2_t
*header
, int preferred_bits
);
189 * 'main()' - Main entry...
192 int /* O - Exit status */
193 main(int argc
, /* I - Number of command-line arguments */
194 char *argv
[]) /* I - Command-line arguments */
196 int i
; /* Looping var */
197 cups_image_t
*img
; /* Image to print */
198 float xprint
, /* Printable area */
200 xinches
, /* Total size in inches */
202 float xsize
, /* Total size in points */
206 float aspect
; /* Aspect ratio */
207 int xpages
, /* # x pages */
208 ypages
, /* # y pages */
209 xpage
, /* Current x page */
210 ypage
, /* Current y page */
211 xtemp
, /* Bitmap width in pixels */
212 ytemp
, /* Bitmap height in pixels */
213 page
; /* Current page number */
214 int xc0
, yc0
, /* Corners of the page in image coords */
216 ppd_file_t
*ppd
; /* PPD file */
217 ppd_choice_t
*choice
; /* PPD option choice */
218 char *resolution
, /* Output resolution */
219 *media_type
; /* Media type */
220 ppd_profile_t
*profile
; /* Color profile */
221 ppd_profile_t userprofile
; /* User-specified profile */
222 cups_raster_t
*ras
; /* Raster stream */
223 cups_page_header2_t header
; /* Page header */
224 int num_options
; /* Number of print options */
225 cups_option_t
*options
; /* Print options */
226 const char *val
; /* Option value */
227 int slowcollate
, /* Collate copies the slow way */
228 slowcopies
; /* Make copies the "slow" way? */
229 float g
; /* Gamma correction value */
230 float b
; /* Brightness factor */
231 float zoom
; /* Zoom facter */
232 int xppi
, yppi
; /* Pixels-per-inch */
233 int hue
, sat
; /* Hue and saturation adjustment */
234 cups_izoom_t
*z
; /* Image zoom buffer */
235 cups_iztype_t zoom_type
; /* Image zoom type */
236 int primary
, /* Primary image colorspace */
237 secondary
; /* Secondary image colorspace */
238 cups_ib_t
*row
, /* Current row */
240 *r1
; /* Bottom row */
241 int y
, /* Current Y coordinate on page */
242 iy
, /* Current Y coordinate in image */
243 last_iy
, /* Previous Y coordinate in image */
244 yerr0
, /* Top Y error value */
245 yerr1
, /* Bottom Y error value */
246 blank
; /* Blank value */
247 cups_ib_t lut
[256]; /* Gamma/brightness LUT */
248 int plane
, /* Current color plane */
249 num_planes
; /* Number of color planes */
250 char filename
[1024]; /* Name of file to print */
254 * Make sure status messages are not buffered...
257 setbuf(stderr
, NULL
);
260 * Check command-line...
263 if (argc
< 6 || argc
> 7)
265 fputs("ERROR: imagetoraster job-id user title copies options [file]\n", stderr
);
269 fprintf(stderr
, "INFO: %s %s %s %s %s %s %s\n", argv
[0], argv
[1], argv
[2],
270 argv
[3], argv
[4], argv
[5], argv
[6] ? argv
[6] : "(null)");
273 * See if we need to use the imagetops and pstoraster filters instead...
277 num_options
= cupsParseOptions(argv
[5], 0, &options
);
279 if (getenv("CLASSIFICATION") ||
280 cupsGetOption("page-label", num_options
, options
))
283 * Yes, fork a copy of pstoraster and then transfer control to imagetops...
286 int mypipes
[2]; /* New pipes for imagetops | pstoraster */
287 int pid
; /* PID of pstoraster */
290 cupsFreeOptions(num_options
, options
);
294 perror("ERROR: Unable to create pipes for imagetops | pstoraster");
298 if ((pid
= fork()) == 0)
301 * Child process for pstoraster... Assign new pipe input to pstoraster...
309 execlp("pstoraster", argv
[0], argv
[1], argv
[2], argv
[3], argv
[4], argv
[5],
311 perror("ERROR: Unable to exec pstoraster");
320 perror("ERROR: Unable to fork pstoraster");
325 * Update stdout so it points at the new pstoraster...
334 * Run imagetops to get the classification or page labelling that was
338 execlp("imagetops", argv
[0], argv
[1], argv
[2], argv
[3], argv
[4], argv
[5],
340 perror("ERROR: Unable to exec imagetops");
345 * Copy stdin as needed...
350 int fd
; /* File to write to */
351 char buffer
[8192]; /* Buffer to read into */
352 int bytes
; /* # of bytes to read */
355 if ((fd
= cupsTempFd(filename
, sizeof(filename
))) < 0)
357 perror("ERROR: Unable to copy image file");
361 fprintf(stderr
, "DEBUG: imagetoraster - copying to temp print file \"%s\"\n",
364 while ((bytes
= fread(buffer
, 1, sizeof(buffer
), stdin
)) > 0)
365 write(fd
, buffer
, bytes
);
370 strlcpy(filename
, argv
[6], sizeof(filename
));
373 * Process command-line options and write the prolog...
384 Copies
= atoi(argv
[4]);
386 ppd
= SetCommonOptions(num_options
, options
, 0);
388 if ((val
= cupsGetOption("multiple-document-handling", num_options
, options
)) != NULL
)
391 * This IPP attribute is unnecessarily complicated...
393 * single-document, separate-documents-collated-copies, and
394 * single-document-new-sheet all require collated copies.
396 * separate-documents-collated-copies allows for uncollated copies.
399 Collate
= strcasecmp(val
, "separate-documents-collated-copies") != 0;
402 if ((val
= cupsGetOption("Collate", num_options
, options
)) != NULL
&&
403 strcasecmp(val
, "True") == 0)
406 if ((val
= cupsGetOption("gamma", num_options
, options
)) != NULL
)
409 * Get gamma value from 1 to 10000...
412 g
= atoi(val
) * 0.001f
;
420 if ((val
= cupsGetOption("brightness", num_options
, options
)) != NULL
)
423 * Get brightness value from 10 to 1000.
426 b
= atoi(val
) * 0.01f
;
434 if ((val
= cupsGetOption("scaling", num_options
, options
)) != NULL
)
435 zoom
= atoi(val
) * 0.01;
436 else if (cupsGetOption("fitplot", num_options
, options
))
439 if ((val
= cupsGetOption("ppi", num_options
, options
)) != NULL
)
440 if (sscanf(val
, "%dx%d", &xppi
, &yppi
) < 2)
443 if ((val
= cupsGetOption("position", num_options
, options
)) != NULL
)
445 if (strcasecmp(val
, "center") == 0)
450 else if (strcasecmp(val
, "top") == 0)
455 else if (strcasecmp(val
, "left") == 0)
460 else if (strcasecmp(val
, "right") == 0)
465 else if (strcasecmp(val
, "top-left") == 0)
470 else if (strcasecmp(val
, "top-right") == 0)
475 else if (strcasecmp(val
, "bottom") == 0)
480 else if (strcasecmp(val
, "bottom-left") == 0)
485 else if (strcasecmp(val
, "bottom-right") == 0)
492 if ((val
= cupsGetOption("saturation", num_options
, options
)) != NULL
)
495 if ((val
= cupsGetOption("hue", num_options
, options
)) != NULL
)
498 if ((val
= cupsGetOption("mirror", num_options
, options
)) != NULL
&&
499 strcasecmp(val
, "True") == 0)
503 * Set the needed options in the page header...
506 if (cupsRasterInterpretPPD(&header
, ppd
, num_options
, options
, raster_cb
))
508 fputs("ERROR: Bad page setup!\n", stderr
);
513 * Get the media type and resolution that have been chosen...
516 if ((choice
= ppdFindMarkedChoice(ppd
, "MediaType")) != NULL
)
517 media_type
= choice
->choice
;
521 if ((choice
= ppdFindMarkedChoice(ppd
, "Resolution")) != NULL
)
522 resolution
= choice
->choice
;
527 * Choose the appropriate colorspace...
530 switch (header
.cupsColorSpace
)
533 primary
= CUPS_IMAGE_WHITE
;
534 secondary
= CUPS_IMAGE_WHITE
;
538 case CUPS_CSPACE_RGB
:
539 case CUPS_CSPACE_RGBA
:
540 case CUPS_CSPACE_RGBW
:
541 primary
= CUPS_IMAGE_RGB
;
542 secondary
= CUPS_IMAGE_RGB
;
546 case CUPS_CSPACE_WHITE
:
547 case CUPS_CSPACE_GOLD
:
548 case CUPS_CSPACE_SILVER
:
549 primary
= CUPS_IMAGE_BLACK
;
550 secondary
= CUPS_IMAGE_BLACK
;
553 case CUPS_CSPACE_CMYK
:
554 case CUPS_CSPACE_YMCK
:
555 case CUPS_CSPACE_KCMY
:
556 case CUPS_CSPACE_GMCK
:
557 case CUPS_CSPACE_GMCS
:
558 primary
= CUPS_IMAGE_CMYK
;
559 secondary
= CUPS_IMAGE_CMYK
;
562 case CUPS_CSPACE_CMY
:
563 case CUPS_CSPACE_YMC
:
564 primary
= CUPS_IMAGE_CMY
;
565 secondary
= CUPS_IMAGE_CMY
;
568 case CUPS_CSPACE_KCMYcm
:
569 if (header
.cupsBitsPerPixel
== 1)
571 primary
= CUPS_IMAGE_CMY
;
572 secondary
= CUPS_IMAGE_CMY
;
576 primary
= CUPS_IMAGE_CMYK
;
577 secondary
= CUPS_IMAGE_CMYK
;
583 * Find a color profile matching the current options...
586 if ((val
= cupsGetOption("profile", num_options
, options
)) != NULL
)
588 profile
= &userprofile
;
589 sscanf(val
, "%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f",
590 &(userprofile
.density
), &(userprofile
.gamma
),
591 userprofile
.matrix
[0] + 0, userprofile
.matrix
[0] + 1,
592 userprofile
.matrix
[0] + 2,
593 userprofile
.matrix
[1] + 0, userprofile
.matrix
[1] + 1,
594 userprofile
.matrix
[1] + 2,
595 userprofile
.matrix
[2] + 0, userprofile
.matrix
[2] + 1,
596 userprofile
.matrix
[2] + 2);
598 userprofile
.density
*= 0.001f
;
599 userprofile
.gamma
*= 0.001f
;
600 userprofile
.matrix
[0][0] *= 0.001f
;
601 userprofile
.matrix
[0][1] *= 0.001f
;
602 userprofile
.matrix
[0][2] *= 0.001f
;
603 userprofile
.matrix
[1][0] *= 0.001f
;
604 userprofile
.matrix
[1][1] *= 0.001f
;
605 userprofile
.matrix
[1][2] *= 0.001f
;
606 userprofile
.matrix
[2][0] *= 0.001f
;
607 userprofile
.matrix
[2][1] *= 0.001f
;
608 userprofile
.matrix
[2][2] *= 0.001f
;
610 else if (ppd
!= NULL
)
612 fprintf(stderr
, "DEBUG: Searching for profile \"%s/%s\"...\n",
613 resolution
, media_type
);
615 for (i
= 0, profile
= ppd
->profiles
; i
< ppd
->num_profiles
; i
++, profile
++)
617 fprintf(stderr
, "DEBUG: \"%s/%s\" = ", profile
->resolution
,
618 profile
->media_type
);
620 if ((strcmp(profile
->resolution
, resolution
) == 0 ||
621 profile
->resolution
[0] == '-') &&
622 (strcmp(profile
->media_type
, media_type
) == 0 ||
623 profile
->media_type
[0] == '-'))
625 fputs("MATCH!\n", stderr
);
629 fputs("no.\n", stderr
);
633 * If we found a color profile, use it!
636 if (i
>= ppd
->num_profiles
)
643 cupsImageSetProfile(profile
->density
, profile
->gamma
, profile
->matrix
);
645 cupsImageSetRasterColorSpace(header
.cupsColorSpace
);
648 * Create a gamma/brightness LUT...
651 make_lut(lut
, primary
, g
, b
);
654 * Open the input image to print...
657 fputs("INFO: Loading image file...\n", stderr
);
659 img
= cupsImageOpen(filename
, primary
, secondary
, sat
, hue
, lut
);
666 fputs("ERROR: Unable to open image file for printing!\n", stderr
);
672 * Scale as necessary...
675 if (zoom
== 0.0 && xppi
== 0)
684 fprintf(stderr
, "DEBUG: Before scaling: xppi=%d, yppi=%d, zoom=%.2f\n",
690 * Scale the image as neccesary to match the desired pixels-per-inch.
695 xprint
= (PageTop
- PageBottom
) / 72.0;
696 yprint
= (PageRight
- PageLeft
) / 72.0;
700 xprint
= (PageRight
- PageLeft
) / 72.0;
701 yprint
= (PageTop
- PageBottom
) / 72.0;
704 fprintf(stderr
, "DEBUG: Before scaling: xprint=%.1f, yprint=%.1f\n",
707 xinches
= (float)img
->xsize
/ (float)xppi
;
708 yinches
= (float)img
->ysize
/ (float)yppi
;
710 fprintf(stderr
, "DEBUG: Image size is %.1f x %.1f inches...\n",
713 if ((val
= cupsGetOption("natural-scaling", num_options
, options
)) != NULL
)
715 xinches
= xinches
* atoi(val
) / 100;
716 yinches
= yinches
* atoi(val
) / 100;
719 if (cupsGetOption("orientation-requested", num_options
, options
) == NULL
&&
720 cupsGetOption("landscape", num_options
, options
) == NULL
)
723 * Rotate the image if it will fit landscape but not portrait...
726 fputs("DEBUG: Auto orientation...\n", stderr
);
728 if ((xinches
> xprint
|| yinches
> yprint
) &&
729 xinches
<= yprint
&& yinches
<= xprint
)
732 * Rotate the image as needed...
735 fputs("DEBUG: Using landscape orientation...\n", stderr
);
737 Orientation
= (Orientation
+ 1) & 3;
747 * Scale percentage of page size...
750 xprint
= (PageRight
- PageLeft
) / 72.0;
751 yprint
= (PageTop
- PageBottom
) / 72.0;
752 aspect
= (float)img
->yppi
/ (float)img
->xppi
;
754 fprintf(stderr
, "DEBUG: Before scaling: xprint=%.1f, yprint=%.1f\n",
757 fprintf(stderr
, "DEBUG: img->xppi = %d, img->yppi = %d, aspect = %f\n",
758 img
->xppi
, img
->yppi
, aspect
);
760 xsize
= xprint
* zoom
;
761 ysize
= xsize
* img
->ysize
/ img
->xsize
/ aspect
;
763 if (ysize
> (yprint
* zoom
))
765 ysize
= yprint
* zoom
;
766 xsize
= ysize
* img
->xsize
* aspect
/ img
->ysize
;
769 xsize2
= yprint
* zoom
;
770 ysize2
= xsize2
* img
->ysize
/ img
->xsize
/ aspect
;
772 if (ysize2
> (xprint
* zoom
))
774 ysize2
= xprint
* zoom
;
775 xsize2
= ysize2
* img
->xsize
* aspect
/ img
->ysize
;
778 fprintf(stderr
, "DEBUG: Portrait size is %.2f x %.2f inches\n", xsize
, ysize
);
779 fprintf(stderr
, "DEBUG: Landscape size is %.2f x %.2f inches\n", xsize2
, ysize2
);
781 if (cupsGetOption("orientation-requested", num_options
, options
) == NULL
&&
782 cupsGetOption("landscape", num_options
, options
) == NULL
)
785 * Choose the rotation with the largest area, but prefer
786 * portrait if they are equal...
789 fputs("DEBUG: Auto orientation...\n", stderr
);
791 if ((xsize
* ysize
) < (xsize2
* xsize2
))
794 * Do landscape orientation...
797 fputs("DEBUG: Using landscape orientation...\n", stderr
);
802 xprint
= (PageTop
- PageBottom
) / 72.0;
803 yprint
= (PageRight
- PageLeft
) / 72.0;
808 * Do portrait orientation...
811 fputs("DEBUG: Using portrait orientation...\n", stderr
);
818 else if (Orientation
& 1)
820 fputs("DEBUG: Using landscape orientation...\n", stderr
);
824 xprint
= (PageTop
- PageBottom
) / 72.0;
825 yprint
= (PageRight
- PageLeft
) / 72.0;
829 fputs("DEBUG: Using portrait orientation...\n", stderr
);
833 xprint
= (PageRight
- PageLeft
) / 72.0;
834 yprint
= (PageTop
- PageBottom
) / 72.0;
839 * Compute the number of pages to print and the size of the image on each
843 xpages
= ceil(xinches
/ xprint
);
844 ypages
= ceil(yinches
/ yprint
);
846 xprint
= xinches
/ xpages
;
847 yprint
= yinches
/ ypages
;
849 fprintf(stderr
, "DEBUG: xpages = %dx%.2fin, ypages = %dx%.2fin\n",
850 xpages
, xprint
, ypages
, yprint
);
853 * Compute the bitmap size...
856 if ((choice
= ppdFindMarkedChoice(ppd
, "PageSize")) != NULL
&&
857 strcasecmp(choice
->choice
, "Custom") == 0)
859 float width
, /* New width in points */
860 length
; /* New length in points */
864 * Use the correct width and length for the current orientation...
869 width
= yprint
* 72.0;
870 length
= xprint
* 72.0;
874 width
= xprint
* 72.0;
875 length
= yprint
* 72.0;
879 * Add margins to page size...
882 width
+= ppd
->custom_margins
[0] + ppd
->custom_margins
[2];
883 length
+= ppd
->custom_margins
[1] + ppd
->custom_margins
[3];
886 * Enforce minimums...
889 if (width
< ppd
->custom_min
[0])
890 width
= ppd
->custom_min
[0];
892 if (length
< ppd
->custom_min
[1])
893 length
= ppd
->custom_min
[1];
895 fprintf(stderr
, "DEBUG: Updated custom page size to %.2f x %.2f inches...\n",
896 width
/ 72.0, length
/ 72.0);
899 * Set the new custom size...
902 header
.PageSize
[0] = width
+ 0.5;
903 header
.PageSize
[1] = length
+ 0.5;
906 * Update page variables...
911 PageLeft
= ppd
->custom_margins
[0];
912 PageRight
= width
- ppd
->custom_margins
[2];
913 PageBottom
= ppd
->custom_margins
[1];
914 PageTop
= length
- ppd
->custom_margins
[3];
917 * Remove margins from page size...
920 width
-= ppd
->custom_margins
[0] + ppd
->custom_margins
[2];
921 length
-= ppd
->custom_margins
[1] + ppd
->custom_margins
[3];
924 * Set the bitmap size...
927 header
.cupsWidth
= width
* header
.HWResolution
[0] / 72.0;
928 header
.cupsHeight
= length
* header
.HWResolution
[1] / 72.0;
932 header
.cupsWidth
= (PageRight
- PageLeft
) * header
.HWResolution
[0] / 72.0;
933 header
.cupsHeight
= (PageTop
- PageBottom
) * header
.HWResolution
[1] / 72.0;
934 header
.PageSize
[0] = PageWidth
;
935 header
.PageSize
[1] = PageLength
;
938 header
.Margins
[0] = PageLeft
;
939 header
.Margins
[1] = PageBottom
;
941 fprintf(stderr
, "DEBUG: PageSize = [%d %d]\n", header
.PageSize
[0],
950 header
.ImagingBoundingBox
[0] = PageLeft
;
951 header
.ImagingBoundingBox
[2] = PageLeft
+ xprint
* 72;
954 header
.ImagingBoundingBox
[0] = (PageRight
+ PageLeft
- xprint
* 72) / 2;
955 header
.ImagingBoundingBox
[2] = (PageRight
+ PageLeft
+ xprint
* 72) / 2;
958 header
.ImagingBoundingBox
[0] = PageRight
- xprint
* 72;
959 header
.ImagingBoundingBox
[2] = PageRight
;
966 header
.ImagingBoundingBox
[1] = PageBottom
;
967 header
.ImagingBoundingBox
[3] = PageBottom
+ yprint
* 72;
970 header
.ImagingBoundingBox
[1] = (PageTop
+ PageBottom
- yprint
* 72) / 2;
971 header
.ImagingBoundingBox
[3] = (PageTop
+ PageBottom
+ yprint
* 72) / 2;
974 header
.ImagingBoundingBox
[1] = PageTop
- yprint
* 72;
975 header
.ImagingBoundingBox
[3] = PageTop
;
984 header
.ImagingBoundingBox
[0] = PageBottom
;
985 header
.ImagingBoundingBox
[2] = PageBottom
+ yprint
* 72;
988 header
.ImagingBoundingBox
[0] = (PageTop
+ PageBottom
- yprint
* 72) / 2;
989 header
.ImagingBoundingBox
[2] = (PageTop
+ PageBottom
+ yprint
* 72) / 2;
992 header
.ImagingBoundingBox
[0] = PageTop
- yprint
* 72;
993 header
.ImagingBoundingBox
[2] = PageTop
;
1000 header
.ImagingBoundingBox
[1] = PageLeft
;
1001 header
.ImagingBoundingBox
[3] = PageLeft
+ xprint
* 72;
1004 header
.ImagingBoundingBox
[1] = (PageRight
+ PageLeft
- xprint
* 72) / 2;
1005 header
.ImagingBoundingBox
[3] = (PageRight
+ PageLeft
+ xprint
* 72) / 2;
1008 header
.ImagingBoundingBox
[1] = PageRight
- xprint
* 72;
1009 header
.ImagingBoundingBox
[3] = PageRight
;
1018 header
.ImagingBoundingBox
[0] = PageLeft
;
1019 header
.ImagingBoundingBox
[2] = PageLeft
+ xprint
* 72;
1022 header
.ImagingBoundingBox
[0] = (PageRight
+ PageLeft
- xprint
* 72) / 2;
1023 header
.ImagingBoundingBox
[2] = (PageRight
+ PageLeft
+ xprint
* 72) / 2;
1026 header
.ImagingBoundingBox
[0] = PageRight
- xprint
* 72;
1027 header
.ImagingBoundingBox
[2] = PageRight
;
1034 header
.ImagingBoundingBox
[1] = PageBottom
;
1035 header
.ImagingBoundingBox
[3] = PageBottom
+ yprint
* 72;
1038 header
.ImagingBoundingBox
[1] = (PageTop
+ PageBottom
- yprint
* 72) / 2;
1039 header
.ImagingBoundingBox
[3] = (PageTop
+ PageBottom
+ yprint
* 72) / 2;
1042 header
.ImagingBoundingBox
[1] = PageTop
- yprint
* 72;
1043 header
.ImagingBoundingBox
[3] = PageTop
;
1052 header
.ImagingBoundingBox
[0] = PageBottom
;
1053 header
.ImagingBoundingBox
[2] = PageBottom
+ yprint
* 72;
1056 header
.ImagingBoundingBox
[0] = (PageTop
+ PageBottom
- yprint
* 72) / 2;
1057 header
.ImagingBoundingBox
[2] = (PageTop
+ PageBottom
+ yprint
* 72) / 2;
1060 header
.ImagingBoundingBox
[0] = PageTop
- yprint
* 72;
1061 header
.ImagingBoundingBox
[2] = PageTop
;
1068 header
.ImagingBoundingBox
[1] = PageLeft
;
1069 header
.ImagingBoundingBox
[3] = PageLeft
+ xprint
* 72;
1072 header
.ImagingBoundingBox
[1] = (PageRight
+ PageLeft
- xprint
* 72) / 2;
1073 header
.ImagingBoundingBox
[3] = (PageRight
+ PageLeft
+ xprint
* 72) / 2;
1076 header
.ImagingBoundingBox
[1] = PageRight
- xprint
* 72;
1077 header
.ImagingBoundingBox
[3] = PageRight
;
1083 switch (header
.cupsColorOrder
)
1086 header
.cupsBytesPerLine
= (header
.cupsBitsPerPixel
*
1087 header
.cupsWidth
+ 7) / 8;
1091 case CUPS_ORDER_BANDED
:
1092 if (header
.cupsColorSpace
== CUPS_CSPACE_KCMYcm
&&
1093 header
.cupsBitsPerColor
> 1)
1094 header
.cupsBytesPerLine
= (header
.cupsBitsPerPixel
*
1095 header
.cupsWidth
+ 7) / 8 * 4;
1097 header
.cupsBytesPerLine
= (header
.cupsBitsPerPixel
*
1098 header
.cupsWidth
+ 7) / 8 *
1099 Planes
[header
.cupsColorSpace
];
1103 case CUPS_ORDER_PLANAR
:
1104 header
.cupsBytesPerLine
= (header
.cupsBitsPerPixel
*
1105 header
.cupsWidth
+ 7) / 8;
1106 num_planes
= Planes
[header
.cupsColorSpace
];
1110 if (header
.cupsBitsPerColor
>= 8)
1111 zoom_type
= CUPS_IZOOM_NORMAL
;
1113 zoom_type
= CUPS_IZOOM_FAST
;
1116 * See if we need to collate, and if so how we need to do it...
1119 if (xpages
== 1 && ypages
== 1)
1122 slowcollate
= Collate
&& ppdFindOption(ppd
, "Collate") == NULL
;
1124 slowcopies
= ppd
->manual_copies
;
1128 if (Copies
> 1 && !slowcollate
&& !slowcopies
)
1130 header
.Collate
= (cups_bool_t
)Collate
;
1131 header
.NumCopies
= Copies
;
1136 header
.NumCopies
= 1;
1139 * Create the dithering lookup tables...
1143 OnPixels
[255] = 0xff;
1144 OffPixels
[0] = 0x00;
1145 OffPixels
[255] = 0xff;
1147 switch (header
.cupsBitsPerColor
)
1150 for (i
= 1; i
< 255; i
++)
1152 OnPixels
[i
] = 0x55 * (i
/ 85 + 1);
1153 OffPixels
[i
] = 0x55 * (i
/ 64);
1157 for (i
= 1; i
< 255; i
++)
1159 OnPixels
[i
] = 17 * (i
/ 17 + 1);
1160 OffPixels
[i
] = 17 * (i
/ 16);
1163 OnPixels
[255] = OffPixels
[255] = 0xff;
1168 * Output the pages...
1171 fprintf(stderr
, "DEBUG: cupsWidth = %d\n", header
.cupsWidth
);
1172 fprintf(stderr
, "DEBUG: cupsHeight = %d\n", header
.cupsHeight
);
1173 fprintf(stderr
, "DEBUG: cupsBitsPerColor = %d\n", header
.cupsBitsPerColor
);
1174 fprintf(stderr
, "DEBUG: cupsBitsPerPixel = %d\n", header
.cupsBitsPerPixel
);
1175 fprintf(stderr
, "DEBUG: cupsBytesPerLine = %d\n", header
.cupsBytesPerLine
);
1176 fprintf(stderr
, "DEBUG: cupsColorOrder = %d\n", header
.cupsColorOrder
);
1177 fprintf(stderr
, "DEBUG: cupsColorSpace = %d\n", header
.cupsColorSpace
);
1178 fprintf(stderr
, "DEBUG: img->colorspace = %d\n", img
->colorspace
);
1180 row
= malloc(2 * header
.cupsBytesPerLine
);
1181 ras
= cupsRasterOpen(1, CUPS_RASTER_WRITE
);
1182 blank
= img
->colorspace
< 0 ? 0 : ~0;
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 fprintf(stderr
, "INFO: Formatting page %d...\n", 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 memset(row
, blank
, header
.cupsBytesPerLine
);
1234 y
= header
.cupsHeight
- z
->ysize
;
1240 if (cupsRasterWritePixels(ras
, row
, header
.cupsBytesPerLine
) <
1241 header
.cupsBytesPerLine
)
1243 fputs("ERROR: Unable to write raster data to driver!\n", stderr
);
1244 cupsImageClose(img
);
1251 * Then write image data...
1254 for (y
= z
->ysize
, yerr0
= 0, yerr1
= z
->ysize
, iy
= 0, last_iy
= -2;
1260 if (zoom_type
!= CUPS_IZOOM_FAST
&& (iy
- last_iy
) > 1)
1261 _cupsImageZoomFill(z
, iy
);
1263 _cupsImageZoomFill(z
, iy
+ z
->yincr
);
1269 * Format this line of raster data for the printer...
1272 memset(row
, blank
, header
.cupsBytesPerLine
);
1274 r0
= z
->rows
[z
->row
];
1275 r1
= z
->rows
[1 - z
->row
];
1277 switch (header
.cupsColorSpace
)
1279 case CUPS_CSPACE_W
:
1280 format_W(&header
, row
, y
, plane
, z
->xsize
, z
->ysize
,
1281 yerr0
, yerr1
, r0
, r1
);
1284 case CUPS_CSPACE_RGB
:
1285 format_RGB(&header
, row
, y
, plane
, z
->xsize
, z
->ysize
,
1286 yerr0
, yerr1
, r0
, r1
);
1288 case CUPS_CSPACE_RGBA
:
1289 case CUPS_CSPACE_RGBW
:
1290 format_RGBA(&header
, row
, y
, plane
, z
->xsize
, z
->ysize
,
1291 yerr0
, yerr1
, r0
, r1
);
1293 case CUPS_CSPACE_K
:
1294 case CUPS_CSPACE_WHITE
:
1295 case CUPS_CSPACE_GOLD
:
1296 case CUPS_CSPACE_SILVER
:
1297 format_K(&header
, row
, y
, plane
, z
->xsize
, z
->ysize
,
1298 yerr0
, yerr1
, r0
, r1
);
1300 case CUPS_CSPACE_CMY
:
1301 format_CMY(&header
, row
, y
, plane
, z
->xsize
, z
->ysize
,
1302 yerr0
, yerr1
, r0
, r1
);
1304 case CUPS_CSPACE_YMC
:
1305 format_YMC(&header
, row
, y
, plane
, z
->xsize
, z
->ysize
,
1306 yerr0
, yerr1
, r0
, r1
);
1308 case CUPS_CSPACE_CMYK
:
1309 format_CMYK(&header
, row
, y
, plane
, z
->xsize
, z
->ysize
,
1310 yerr0
, yerr1
, r0
, r1
);
1312 case CUPS_CSPACE_YMCK
:
1313 case CUPS_CSPACE_GMCK
:
1314 case CUPS_CSPACE_GMCS
:
1315 format_YMCK(&header
, row
, y
, plane
, z
->xsize
, z
->ysize
,
1316 yerr0
, yerr1
, r0
, r1
);
1318 case CUPS_CSPACE_KCMY
:
1319 format_KCMY(&header
, row
, y
, plane
, z
->xsize
, z
->ysize
,
1320 yerr0
, yerr1
, r0
, r1
);
1322 case CUPS_CSPACE_KCMYcm
:
1323 format_KCMYcm(&header
, row
, y
, plane
, z
->xsize
, z
->ysize
,
1324 yerr0
, yerr1
, r0
, r1
);
1329 * Write the raster data to the driver...
1332 if (cupsRasterWritePixels(ras
, row
, header
.cupsBytesPerLine
) <
1333 header
.cupsBytesPerLine
)
1335 fputs("ERROR: Unable to write raster data to driver!\n", stderr
);
1336 cupsImageClose(img
);
1341 * Compute the next scanline in the image...
1356 * Write trailing blank space as needed...
1359 if (header
.cupsHeight
> z
->ysize
&& YPosition
>= 0)
1361 memset(row
, blank
, header
.cupsBytesPerLine
);
1363 y
= header
.cupsHeight
- z
->ysize
;
1369 if (cupsRasterWritePixels(ras
, row
, header
.cupsBytesPerLine
) <
1370 header
.cupsBytesPerLine
)
1372 fputs("ERROR: Unable to write raster data to driver!\n", stderr
);
1373 cupsImageClose(img
);
1380 * Free memory used for the "zoom" engine...
1383 _cupsImageZoomDelete(z
);
1392 cupsRasterClose(ras
);
1393 cupsImageClose(img
);
1401 * 'format_CMY()' - Convert image data to CMY.
1405 format_CMY(cups_page_header2_t
*header
, /* I - Page header */
1406 unsigned char *row
, /* IO - Bitmap data for device */
1407 int y
, /* I - Current row */
1408 int z
, /* I - Current plane */
1409 int xsize
, /* I - Width of image data */
1410 int ysize
, /* I - Height of image data */
1411 int yerr0
, /* I - Top Y error */
1412 int yerr1
, /* I - Bottom Y error */
1413 cups_ib_t
*r0
, /* I - Primary image data */
1414 cups_ib_t
*r1
) /* I - Image data for interpolation */
1416 cups_ib_t
*ptr
, /* Pointer into row */
1417 *cptr
, /* Pointer into cyan */
1418 *mptr
, /* Pointer into magenta */
1419 *yptr
, /* Pointer into yellow */
1420 bitmask
; /* Current mask for pixel */
1421 int bitoffset
; /* Current offset in line */
1422 int bandwidth
; /* Width of a color band */
1423 int x
, /* Current X coordinate on page */
1424 *dither
; /* Pointer into dither array */
1433 bitoffset
= header
->cupsBitsPerPixel
* ((header
->cupsWidth
- xsize
) / 2);
1436 bitoffset
= header
->cupsBitsPerPixel
* (header
->cupsWidth
- xsize
);
1440 ptr
= row
+ bitoffset
/ 8;
1441 bandwidth
= header
->cupsBytesPerLine
/ 3;
1443 switch (header
->cupsColorOrder
)
1445 case CUPS_ORDER_CHUNKED
:
1446 switch (header
->cupsBitsPerColor
)
1449 bitmask
= 64 >> (bitoffset
& 7);
1450 dither
= Floyd16xc16
[y
& 15];
1452 for (x
= xsize
; x
> 0; x
--)
1454 if (*r0
++ > dither
[x
& 15])
1458 if (*r0
++ > dither
[x
& 15])
1462 if (*r0
++ > dither
[x
& 15])
1476 dither
= Floyd8x8
[y
& 7];
1478 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
1480 if ((r0
[0] & 63) > dither
[x
& 7])
1481 *ptr
^= (0x30 & OnPixels
[r0
[0]]);
1483 *ptr
^= (0x30 & OffPixels
[r0
[0]]);
1485 if ((r0
[1] & 63) > dither
[x
& 7])
1486 *ptr
^= (0x0c & OnPixels
[r0
[1]]);
1488 *ptr
^= (0x0c & OffPixels
[r0
[1]]);
1490 if ((r0
[2] & 63) > dither
[x
& 7])
1491 *ptr
++ ^= (0x03 & OnPixels
[r0
[2]]);
1493 *ptr
++ ^= (0x03 & OffPixels
[r0
[2]]);
1498 dither
= Floyd4x4
[y
& 3];
1500 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
1502 if ((r0
[0] & 15) > dither
[x
& 3])
1503 *ptr
++ ^= (0x0f & OnPixels
[r0
[0]]);
1505 *ptr
++ ^= (0x0f & OffPixels
[r0
[0]]);
1507 if ((r0
[1] & 15) > dither
[x
& 3])
1508 *ptr
^= (0xf0 & OnPixels
[r0
[1]]);
1510 *ptr
^= (0xf0 & OffPixels
[r0
[1]]);
1512 if ((r0
[2] & 15) > dither
[x
& 3])
1513 *ptr
++ ^= (0x0f & OnPixels
[r0
[2]]);
1515 *ptr
++ ^= (0x0f & OffPixels
[r0
[2]]);
1520 for (x
= xsize
* 3; x
> 0; x
--, r0
++, r1
++)
1524 *ptr
++ = (*r0
* yerr0
+ *r1
* yerr1
) / ysize
;
1529 case CUPS_ORDER_BANDED
:
1531 mptr
= ptr
+ bandwidth
;
1532 yptr
= ptr
+ 2 * bandwidth
;
1534 switch (header
->cupsBitsPerColor
)
1537 bitmask
= 0x80 >> (bitoffset
& 7);
1538 dither
= Floyd16xc16
[y
& 15];
1540 for (x
= xsize
; x
> 0; x
--)
1542 if (*r0
++ > dither
[x
& 15])
1544 if (*r0
++ > dither
[x
& 15])
1546 if (*r0
++ > dither
[x
& 15])
1562 bitmask
= 0x0 >> (bitoffset
& 7);
1563 dither
= Floyd8x8
[y
& 7];
1565 for (x
= xsize
; x
> 0; x
--)
1567 if ((*r0
& 63) > dither
[x
& 7])
1568 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
1570 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
1572 if ((*r0
& 63) > dither
[x
& 7])
1573 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
1575 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
1577 if ((*r0
& 63) > dither
[x
& 7])
1578 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
1580 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
1596 bitmask
= 0xf0 >> (bitoffset
& 7);
1597 dither
= Floyd4x4
[y
& 3];
1599 for (x
= xsize
; x
> 0; x
--)
1601 if ((*r0
& 15) > dither
[x
& 3])
1602 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
1604 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
1606 if ((*r0
& 15) > dither
[x
& 3])
1607 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
1609 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
1611 if ((*r0
& 15) > dither
[x
& 3])
1612 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
1614 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
1616 if (bitmask
== 0xf0)
1630 for (x
= xsize
; x
> 0; x
--, r0
+= 3, r1
+= 3)
1635 *cptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
1640 *mptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
1645 *yptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
1651 case CUPS_ORDER_PLANAR
:
1652 switch (header
->cupsBitsPerColor
)
1655 bitmask
= 0x80 >> (bitoffset
& 7);
1656 dither
= Floyd16xc16
[y
& 15];
1661 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
1663 if (r0
[0] > dither
[x
& 15])
1677 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
1679 if (r0
[1] > dither
[x
& 15])
1693 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
1695 if (r0
[2] > dither
[x
& 15])
1711 bitmask
= 0x0 >> (bitoffset
& 7);
1712 dither
= Floyd8x8
[y
& 7];
1715 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
1717 if ((*r0
& 63) > dither
[x
& 7])
1718 *ptr
^= (bitmask
& OnPixels
[*r0
]);
1720 *ptr
^= (bitmask
& OffPixels
[*r0
]);
1734 bitmask
= 0xf0 >> (bitoffset
& 7);
1735 dither
= Floyd4x4
[y
& 3];
1738 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
1740 if ((*r0
& 15) > dither
[x
& 3])
1741 *ptr
^= (bitmask
& OnPixels
[*r0
]);
1743 *ptr
^= (bitmask
& OffPixels
[*r0
]);
1745 if (bitmask
== 0xf0)
1760 for (x
= xsize
; x
> 0; x
--, r0
+= 3, r1
+= 3)
1765 *ptr
++ = (*r0
* yerr0
+ *r1
* yerr1
) / ysize
;
1775 * 'format_CMYK()' - Convert image data to CMYK.
1779 format_CMYK(cups_page_header2_t
*header
,/* I - Page header */
1780 unsigned char *row
, /* IO - Bitmap data for device */
1781 int y
, /* I - Current row */
1782 int z
, /* I - Current plane */
1783 int xsize
, /* I - Width of image data */
1784 int ysize
, /* I - Height of image data */
1785 int yerr0
, /* I - Top Y error */
1786 int yerr1
, /* I - Bottom Y error */
1787 cups_ib_t
*r0
, /* I - Primary image data */
1788 cups_ib_t
*r1
) /* I - Image data for interpolation */
1790 cups_ib_t
*ptr
, /* Pointer into row */
1791 *cptr
, /* Pointer into cyan */
1792 *mptr
, /* Pointer into magenta */
1793 *yptr
, /* Pointer into yellow */
1794 *kptr
, /* Pointer into black */
1795 bitmask
; /* Current mask for pixel */
1796 int bitoffset
; /* Current offset in line */
1797 int bandwidth
; /* Width of a color band */
1798 int x
, /* Current X coordinate on page */
1799 *dither
; /* Pointer into dither array */
1808 bitoffset
= header
->cupsBitsPerPixel
* ((header
->cupsWidth
- xsize
) / 2);
1811 bitoffset
= header
->cupsBitsPerPixel
* (header
->cupsWidth
- xsize
);
1815 ptr
= row
+ bitoffset
/ 8;
1816 bandwidth
= header
->cupsBytesPerLine
/ 4;
1818 switch (header
->cupsColorOrder
)
1820 case CUPS_ORDER_CHUNKED
:
1821 switch (header
->cupsBitsPerColor
)
1824 bitmask
= 128 >> (bitoffset
& 7);
1825 dither
= Floyd16xc16
[y
& 15];
1827 for (x
= xsize
; x
> 0; x
--)
1829 if (*r0
++ > dither
[x
& 15])
1833 if (*r0
++ > dither
[x
& 15])
1837 if (*r0
++ > dither
[x
& 15])
1841 if (*r0
++ > dither
[x
& 15])
1855 dither
= Floyd8x8
[y
& 7];
1857 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
1859 if ((r0
[0] & 63) > dither
[x
& 7])
1860 *ptr
^= (0x0 & OnPixels
[r0
[0]]);
1862 *ptr
^= (0x0 & OffPixels
[r0
[0]]);
1864 if ((r0
[1] & 63) > dither
[x
& 7])
1865 *ptr
^= (0x30 & OnPixels
[r0
[1]]);
1867 *ptr
^= (0x30 & OffPixels
[r0
[1]]);
1869 if ((r0
[2] & 63) > dither
[x
& 7])
1870 *ptr
^= (0x0c & OnPixels
[r0
[2]]);
1872 *ptr
^= (0x0c & OffPixels
[r0
[2]]);
1874 if ((r0
[3] & 63) > dither
[x
& 7])
1875 *ptr
++ ^= (0x03 & OnPixels
[r0
[3]]);
1877 *ptr
++ ^= (0x03 & OffPixels
[r0
[3]]);
1882 dither
= Floyd4x4
[y
& 3];
1884 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
1886 if ((r0
[0] & 15) > dither
[x
& 3])
1887 *ptr
^= (0xf0 & OnPixels
[r0
[0]]);
1889 *ptr
^= (0xf0 & OffPixels
[r0
[0]]);
1891 if ((r0
[1] & 15) > dither
[x
& 3])
1892 *ptr
++ ^= (0x0f & OnPixels
[r0
[1]]);
1894 *ptr
++ ^= (0x0f & OffPixels
[r0
[1]]);
1896 if ((r0
[2] & 15) > dither
[x
& 3])
1897 *ptr
^= (0xf0 & OnPixels
[r0
[2]]);
1899 *ptr
^= (0xf0 & OffPixels
[r0
[2]]);
1901 if ((r0
[3] & 15) > dither
[x
& 3])
1902 *ptr
++ ^= (0x0f & OnPixels
[r0
[3]]);
1904 *ptr
++ ^= (0x0f & OffPixels
[r0
[3]]);
1909 for (x
= xsize
* 4; x
> 0; x
--, r0
++, r1
++)
1913 *ptr
++ = (*r0
* yerr0
+ *r1
* yerr1
) / ysize
;
1918 case CUPS_ORDER_BANDED
:
1920 mptr
= ptr
+ bandwidth
;
1921 yptr
= ptr
+ 2 * bandwidth
;
1922 kptr
= ptr
+ 3 * bandwidth
;
1924 switch (header
->cupsBitsPerColor
)
1927 bitmask
= 0x80 >> (bitoffset
& 7);
1928 dither
= Floyd16xc16
[y
& 15];
1930 for (x
= xsize
; x
> 0; x
--)
1932 if (*r0
++ > dither
[x
& 15])
1934 if (*r0
++ > dither
[x
& 15])
1936 if (*r0
++ > dither
[x
& 15])
1938 if (*r0
++ > dither
[x
& 15])
1955 bitmask
= 0x0 >> (bitoffset
& 7);
1956 dither
= Floyd8x8
[y
& 7];
1958 for (x
= xsize
; x
> 0; x
--)
1960 if ((*r0
& 63) > dither
[x
& 7])
1961 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
1963 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
1965 if ((*r0
& 63) > dither
[x
& 7])
1966 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
1968 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
1970 if ((*r0
& 63) > dither
[x
& 7])
1971 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
1973 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
1975 if ((*r0
& 63) > dither
[x
& 7])
1976 *kptr
^= (bitmask
& OnPixels
[*r0
++]);
1978 *kptr
^= (bitmask
& OffPixels
[*r0
++]);
1995 bitmask
= 0xf0 >> (bitoffset
& 7);
1996 dither
= Floyd4x4
[y
& 3];
1998 for (x
= xsize
; x
> 0; x
--)
2000 if ((*r0
& 15) > dither
[x
& 3])
2001 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
2003 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
2005 if ((*r0
& 15) > dither
[x
& 3])
2006 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
2008 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
2010 if ((*r0
& 15) > dither
[x
& 3])
2011 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
2013 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
2015 if ((*r0
& 15) > dither
[x
& 3])
2016 *kptr
^= (bitmask
& OnPixels
[*r0
++]);
2018 *kptr
^= (bitmask
& OffPixels
[*r0
++]);
2020 if (bitmask
== 0xf0)
2035 for (x
= xsize
; x
> 0; x
--, r0
+= 4, r1
+= 4)
2040 *cptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
2045 *mptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
2050 *yptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
2055 *kptr
++ = (r0
[3] * yerr0
+ r1
[3] * yerr1
) / ysize
;
2061 case CUPS_ORDER_PLANAR
:
2062 switch (header
->cupsBitsPerColor
)
2065 bitmask
= 0x80 >> (bitoffset
& 7);
2066 dither
= Floyd16xc16
[y
& 15];
2069 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
2071 if (*r0
> dither
[x
& 15])
2085 bitmask
= 0x0 >> (bitoffset
& 7);
2086 dither
= Floyd8x8
[y
& 7];
2089 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
2091 if ((*r0
& 63) > dither
[x
& 7])
2092 *ptr
^= (bitmask
& OnPixels
[*r0
]);
2094 *ptr
^= (bitmask
& OffPixels
[*r0
]);
2108 bitmask
= 0xf0 >> (bitoffset
& 7);
2109 dither
= Floyd4x4
[y
& 3];
2112 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
2114 if ((*r0
& 15) > dither
[x
& 3])
2115 *ptr
^= (bitmask
& OnPixels
[*r0
]);
2117 *ptr
^= (bitmask
& OffPixels
[*r0
]);
2119 if (bitmask
== 0xf0)
2134 for (x
= xsize
; x
> 0; x
--, r0
+= 4, r1
+= 4)
2139 *ptr
++ = (*r0
* yerr0
+ *r1
* yerr1
) / ysize
;
2149 * 'format_K()' - Convert image data to black.
2153 format_K(cups_page_header2_t
*header
, /* I - Page header */
2154 unsigned char *row
, /* IO - Bitmap data for device */
2155 int y
, /* I - Current row */
2156 int z
, /* I - Current plane */
2157 int xsize
, /* I - Width of image data */
2158 int ysize
, /* I - Height of image data */
2159 int yerr0
, /* I - Top Y error */
2160 int yerr1
, /* I - Bottom Y error */
2161 cups_ib_t
*r0
, /* I - Primary image data */
2162 cups_ib_t
*r1
) /* I - Image data for interpolation */
2164 cups_ib_t
*ptr
, /* Pointer into row */
2165 bitmask
; /* Current mask for pixel */
2166 int bitoffset
; /* Current offset in line */
2167 int x
, /* Current X coordinate on page */
2168 *dither
; /* Pointer into dither array */
2179 bitoffset
= header
->cupsBitsPerPixel
* ((header
->cupsWidth
- xsize
) / 2);
2182 bitoffset
= header
->cupsBitsPerPixel
* (header
->cupsWidth
- xsize
);
2186 ptr
= row
+ bitoffset
/ 8;
2188 switch (header
->cupsBitsPerColor
)
2191 bitmask
= 0x80 >> (bitoffset
& 7);
2192 dither
= Floyd16xc16
[y
& 15];
2194 for (x
= xsize
; x
> 0; x
--)
2196 if (*r0
++ > dither
[x
& 15])
2210 bitmask
= 0x0 >> (bitoffset
& 7);
2211 dither
= Floyd8x8
[y
& 7];
2213 for (x
= xsize
; x
> 0; x
--)
2215 if ((*r0
& 63) > dither
[x
& 7])
2216 *ptr
^= (bitmask
& OnPixels
[*r0
++]);
2218 *ptr
^= (bitmask
& OffPixels
[*r0
++]);
2232 bitmask
= 0xf0 >> (bitoffset
& 7);
2233 dither
= Floyd4x4
[y
& 3];
2235 for (x
= xsize
; x
> 0; x
--)
2237 if ((*r0
& 15) > dither
[x
& 3])
2238 *ptr
^= (bitmask
& OnPixels
[*r0
++]);
2240 *ptr
^= (bitmask
& OffPixels
[*r0
++]);
2242 if (bitmask
== 0xf0)
2254 for (x
= xsize
; x
> 0; x
--, r0
++, r1
++)
2259 *ptr
++ = (*r0
* yerr0
+ *r1
* yerr1
) / ysize
;
2267 * 'format_KCMY()' - Convert image data to KCMY.
2271 format_KCMY(cups_page_header2_t
*header
,/* I - Page header */
2272 unsigned char *row
, /* IO - Bitmap data for device */
2273 int y
, /* I - Current row */
2274 int z
, /* I - Current plane */
2275 int xsize
, /* I - Width of image data */
2276 int ysize
, /* I - Height of image data */
2277 int yerr0
, /* I - Top Y error */
2278 int yerr1
, /* I - Bottom Y error */
2279 cups_ib_t
*r0
, /* I - Primary image data */
2280 cups_ib_t
*r1
) /* I - Image data for interpolation */
2282 cups_ib_t
*ptr
, /* Pointer into row */
2283 *cptr
, /* Pointer into cyan */
2284 *mptr
, /* Pointer into magenta */
2285 *yptr
, /* Pointer into yellow */
2286 *kptr
, /* Pointer into black */
2287 bitmask
; /* Current mask for pixel */
2288 int bitoffset
; /* Current offset in line */
2289 int bandwidth
; /* Width of a color band */
2290 int x
, /* Current X coordinate on page */
2291 *dither
; /* Pointer into dither array */
2300 bitoffset
= header
->cupsBitsPerPixel
* ((header
->cupsWidth
- xsize
) / 2);
2303 bitoffset
= header
->cupsBitsPerPixel
* (header
->cupsWidth
- xsize
);
2307 ptr
= row
+ bitoffset
/ 8;
2308 bandwidth
= header
->cupsBytesPerLine
/ 4;
2310 switch (header
->cupsColorOrder
)
2312 case CUPS_ORDER_CHUNKED
:
2313 switch (header
->cupsBitsPerColor
)
2316 bitmask
= 128 >> (bitoffset
& 7);
2317 dither
= Floyd16xc16
[y
& 15];
2319 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
2321 if (r0
[3] > dither
[x
& 15])
2325 if (r0
[0] > dither
[x
& 15])
2329 if (r0
[1] > dither
[x
& 15])
2333 if (r0
[2] > dither
[x
& 15])
2347 dither
= Floyd8x8
[y
& 7];
2349 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
2351 if ((r0
[3] & 63) > dither
[x
& 7])
2352 *ptr
^= (0x0 & OnPixels
[r0
[3]]);
2354 *ptr
^= (0x0 & OffPixels
[r0
[3]]);
2356 if ((r0
[0] & 63) > dither
[x
& 7])
2357 *ptr
^= (0x30 & OnPixels
[r0
[0]]);
2359 *ptr
^= (0x30 & OffPixels
[r0
[0]]);
2361 if ((r0
[1] & 63) > dither
[x
& 7])
2362 *ptr
^= (0x0c & OnPixels
[r0
[1]]);
2364 *ptr
^= (0x0c & OffPixels
[r0
[1]]);
2366 if ((r0
[2] & 63) > dither
[x
& 7])
2367 *ptr
++ ^= (0x03 & OnPixels
[r0
[2]]);
2369 *ptr
++ ^= (0x03 & OffPixels
[r0
[2]]);
2374 dither
= Floyd4x4
[y
& 3];
2376 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
2378 if ((r0
[3] & 15) > dither
[x
& 3])
2379 *ptr
^= (0xf0 & OnPixels
[r0
[3]]);
2381 *ptr
^= (0xf0 & OffPixels
[r0
[3]]);
2383 if ((r0
[0] & 15) > dither
[x
& 3])
2384 *ptr
++ ^= (0x0f & OnPixels
[r0
[0]]);
2386 *ptr
++ ^= (0x0f & OffPixels
[r0
[0]]);
2388 if ((r0
[1] & 15) > dither
[x
& 3])
2389 *ptr
^= (0xf0 & OnPixels
[r0
[1]]);
2391 *ptr
^= (0xf0 & OffPixels
[r0
[1]]);
2393 if ((r0
[2] & 15) > dither
[x
& 3])
2394 *ptr
++ ^= (0x0f & OnPixels
[r0
[2]]);
2396 *ptr
++ ^= (0x0f & OffPixels
[r0
[2]]);
2401 for (x
= xsize
; x
> 0; x
--, r0
+= 4, r1
+= 4)
2406 *ptr
++ = (r0
[3] * yerr0
+ r1
[3] * yerr1
) / ysize
;
2411 *ptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
2416 *ptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
2421 *ptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
2427 case CUPS_ORDER_BANDED
:
2429 cptr
= ptr
+ bandwidth
;
2430 mptr
= ptr
+ 2 * bandwidth
;
2431 yptr
= ptr
+ 3 * bandwidth
;
2433 switch (header
->cupsBitsPerColor
)
2436 bitmask
= 0x80 >> (bitoffset
& 7);
2437 dither
= Floyd16xc16
[y
& 15];
2439 for (x
= xsize
; x
> 0; x
--)
2441 if (*r0
++ > dither
[x
& 15])
2443 if (*r0
++ > dither
[x
& 15])
2445 if (*r0
++ > dither
[x
& 15])
2447 if (*r0
++ > dither
[x
& 15])
2464 bitmask
= 0x0 >> (bitoffset
& 7);
2465 dither
= Floyd8x8
[y
& 7];
2467 for (x
= xsize
; x
> 0; x
--)
2469 if ((*r0
& 63) > dither
[x
& 7])
2470 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
2472 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
2474 if ((*r0
& 63) > dither
[x
& 7])
2475 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
2477 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
2479 if ((*r0
& 63) > dither
[x
& 7])
2480 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
2482 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
2484 if ((*r0
& 63) > dither
[x
& 7])
2485 *kptr
^= (bitmask
& OnPixels
[*r0
++]);
2487 *kptr
^= (bitmask
& OffPixels
[*r0
++]);
2504 bitmask
= 0xf0 >> (bitoffset
& 7);
2505 dither
= Floyd4x4
[y
& 3];
2507 for (x
= xsize
; x
> 0; x
--)
2509 if ((*r0
& 15) > dither
[x
& 3])
2510 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
2512 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
2514 if ((*r0
& 15) > dither
[x
& 3])
2515 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
2517 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
2519 if ((*r0
& 15) > dither
[x
& 3])
2520 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
2522 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
2524 if ((*r0
& 15) > dither
[x
& 3])
2525 *kptr
^= (bitmask
& OnPixels
[*r0
++]);
2527 *kptr
^= (bitmask
& OffPixels
[*r0
++]);
2529 if (bitmask
== 0xf0)
2544 for (x
= xsize
; x
> 0; x
--, r0
+= 4, r1
+= 4)
2549 *cptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
2554 *mptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
2559 *yptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
2564 *kptr
++ = (r0
[3] * yerr0
+ r1
[3] * yerr1
) / ysize
;
2570 case CUPS_ORDER_PLANAR
:
2571 switch (header
->cupsBitsPerColor
)
2574 bitmask
= 0x80 >> (bitoffset
& 7);
2575 dither
= Floyd16xc16
[y
& 15];
2581 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
2583 if (*r0
> dither
[x
& 15])
2597 bitmask
= 0x0 >> (bitoffset
& 7);
2598 dither
= Floyd8x8
[y
& 7];
2604 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
2606 if ((*r0
& 63) > dither
[x
& 7])
2607 *ptr
^= (bitmask
& OnPixels
[*r0
]);
2609 *ptr
^= (bitmask
& OffPixels
[*r0
]);
2623 bitmask
= 0xf0 >> (bitoffset
& 7);
2624 dither
= Floyd4x4
[y
& 3];
2630 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
2632 if ((*r0
& 15) > dither
[x
& 3])
2633 *ptr
^= (bitmask
& OnPixels
[*r0
]);
2635 *ptr
^= (bitmask
& OffPixels
[*r0
]);
2637 if (bitmask
== 0xf0)
2660 for (x
= xsize
; x
> 0; x
--, r0
+= 4, r1
+= 4)
2665 *ptr
++ = (*r0
* yerr0
+ *r1
* yerr1
) / ysize
;
2675 * 'format_KCMYcm()' - Convert image data to KCMYcm.
2680 cups_page_header2_t
*header
, /* I - Page header */
2681 unsigned char *row
, /* IO - Bitmap data for device */
2682 int y
, /* I - Current row */
2683 int z
, /* I - Current plane */
2684 int xsize
, /* I - Width of image data */
2685 int ysize
, /* I - Height of image data */
2686 int yerr0
, /* I - Top Y error */
2687 int yerr1
, /* I - Bottom Y error */
2688 cups_ib_t
*r0
, /* I - Primary image data */
2689 cups_ib_t
*r1
) /* I - Image data for interpolation */
2691 int pc
, pm
, py
, pk
; /* Cyan, magenta, yellow, and black values */
2692 cups_ib_t
*ptr
, /* Pointer into row */
2693 *cptr
, /* Pointer into cyan */
2694 *mptr
, /* Pointer into magenta */
2695 *yptr
, /* Pointer into yellow */
2696 *kptr
, /* Pointer into black */
2697 *lcptr
, /* Pointer into light cyan */
2698 *lmptr
, /* Pointer into light magenta */
2699 bitmask
; /* Current mask for pixel */
2700 int bitoffset
; /* Current offset in line */
2701 int bandwidth
; /* Width of a color band */
2702 int x
, /* Current X coordinate on page */
2703 *dither
; /* Pointer into dither array */
2712 bitoffset
= header
->cupsBitsPerPixel
* ((header
->cupsWidth
- xsize
) / 2);
2715 bitoffset
= header
->cupsBitsPerPixel
* (header
->cupsWidth
- xsize
);
2719 ptr
= row
+ bitoffset
/ 8;
2720 if (header
->cupsBitsPerColor
== 1)
2721 bandwidth
= header
->cupsBytesPerLine
/ 6;
2723 bandwidth
= header
->cupsBytesPerLine
/ 4;
2725 switch (header
->cupsColorOrder
)
2727 case CUPS_ORDER_CHUNKED
:
2728 switch (header
->cupsBitsPerColor
)
2731 dither
= Floyd16xc16
[y
& 15];
2733 for (x
= xsize
; x
> 0; x
--)
2735 pc
= *r0
++ > dither
[x
& 15];
2736 pm
= *r0
++ > dither
[x
& 15];
2737 py
= *r0
++ > dither
[x
& 15];
2738 pk
= *r0
++ > dither
[x
& 15];
2741 *ptr
++ ^= 32; /* Black */
2743 *ptr
++ ^= 17; /* Blue (cyan + light magenta) */
2745 *ptr
++ ^= 6; /* Green (light cyan + yellow) */
2747 *ptr
++ ^= 12; /* Red (magenta + yellow) */
2758 for (x
= xsize
; x
> 0; x
--, r0
+= 4, r1
+= 4)
2763 *ptr
++ = (r0
[3] * yerr0
+ r1
[3] * yerr1
) / ysize
;
2768 *ptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
2773 *ptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
2778 *ptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
2784 case CUPS_ORDER_BANDED
:
2786 cptr
= ptr
+ bandwidth
;
2787 mptr
= ptr
+ 2 * bandwidth
;
2788 yptr
= ptr
+ 3 * bandwidth
;
2789 lcptr
= ptr
+ 4 * bandwidth
;
2790 lmptr
= ptr
+ 5 * bandwidth
;
2792 switch (header
->cupsBitsPerColor
)
2795 bitmask
= 0x80 >> (bitoffset
& 7);
2796 dither
= Floyd16xc16
[y
& 15];
2798 for (x
= xsize
; x
> 0; x
--)
2800 pc
= *r0
++ > dither
[x
& 15];
2801 pm
= *r0
++ > dither
[x
& 15];
2802 py
= *r0
++ > dither
[x
& 15];
2803 pk
= *r0
++ > dither
[x
& 15];
2806 *kptr
^= bitmask
; /* Black */
2809 *cptr
^= bitmask
; /* Blue (cyan + light magenta) */
2814 *lcptr
^= bitmask
; /* Green (light cyan + yellow) */
2819 *mptr
^= bitmask
; /* Red (magenta + yellow) */
2845 for (x
= xsize
; x
> 0; x
--, r0
+= 4, r1
+= 4)
2850 *cptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
2855 *mptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
2860 *yptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
2865 *kptr
++ = (r0
[3] * yerr0
+ r1
[3] * yerr1
) / ysize
;
2871 case CUPS_ORDER_PLANAR
:
2872 switch (header
->cupsBitsPerColor
)
2875 bitmask
= 0x80 >> (bitoffset
& 7);
2876 dither
= Floyd16xc16
[y
& 15];
2881 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
2883 if (r0
[3] > dither
[x
& 15])
2897 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
2899 if (r0
[0] > dither
[x
& 15] &&
2900 r0
[2] < dither
[x
& 15])
2914 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
2916 if (r0
[1] > dither
[x
& 15] &&
2917 (r0
[0] < dither
[x
& 15] ||
2918 r0
[2] > dither
[x
& 15]))
2932 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
2934 if (r0
[2] > dither
[x
& 15] &&
2935 (r0
[0] < dither
[x
& 15] ||
2936 r0
[1] < dither
[x
& 15]))
2950 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
2952 if (r0
[0] > dither
[x
& 15] &&
2953 r0
[2] > dither
[x
& 15])
2967 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
2969 if (r0
[0] > dither
[x
& 15] &&
2970 r0
[1] > dither
[x
& 15] &&
2971 r0
[2] < dither
[x
& 15])
2998 for (x
= xsize
; x
> 0; x
--, r0
+= 4, r1
+= 4)
3003 *ptr
++ = (*r0
* yerr0
+ *r1
* yerr1
) / ysize
;
3013 * 'format_RGBA()' - Convert image data to RGBA/RGBW.
3017 format_RGBA(cups_page_header2_t
*header
,/* I - Page header */
3018 unsigned char *row
, /* IO - Bitmap data for device */
3019 int y
, /* I - Current row */
3020 int z
, /* I - Current plane */
3021 int xsize
, /* I - Width of image data */
3022 int ysize
, /* I - Height of image data */
3023 int yerr0
, /* I - Top Y error */
3024 int yerr1
, /* I - Bottom Y error */
3025 cups_ib_t
*r0
, /* I - Primary image data */
3026 cups_ib_t
*r1
) /* I - Image data for interpolation */
3028 cups_ib_t
*ptr
, /* Pointer into row */
3029 *cptr
, /* Pointer into cyan */
3030 *mptr
, /* Pointer into magenta */
3031 *yptr
, /* Pointer into yellow */
3032 bitmask
; /* Current mask for pixel */
3033 int bitoffset
; /* Current offset in line */
3034 int bandwidth
; /* Width of a color band */
3035 int x
, /* Current X coordinate on page */
3036 *dither
; /* Pointer into dither array */
3045 bitoffset
= header
->cupsBitsPerPixel
* ((header
->cupsWidth
- xsize
) / 2);
3048 bitoffset
= header
->cupsBitsPerPixel
* (header
->cupsWidth
- xsize
);
3052 ptr
= row
+ bitoffset
/ 8;
3053 bandwidth
= header
->cupsBytesPerLine
/ 4;
3055 switch (header
->cupsColorOrder
)
3057 case CUPS_ORDER_CHUNKED
:
3058 switch (header
->cupsBitsPerColor
)
3061 bitmask
= 128 >> (bitoffset
& 7);
3062 dither
= Floyd16xc16
[y
& 15];
3064 for (x
= xsize
; x
> 0; x
--)
3066 if (*r0
++ > dither
[x
& 15])
3070 if (*r0
++ > dither
[x
& 15])
3074 if (*r0
++ > dither
[x
& 15])
3091 dither
= Floyd8x8
[y
& 7];
3093 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3095 if ((r0
[0] & 63) > dither
[x
& 7])
3096 *ptr
^= (0x0 & OnPixels
[r0
[0]]);
3098 *ptr
^= (0x0 & OffPixels
[r0
[0]]);
3100 if ((r0
[1] & 63) > dither
[x
& 7])
3101 *ptr
^= (0x30 & OnPixels
[r0
[1]]);
3103 *ptr
^= (0x30 & OffPixels
[r0
[1]]);
3105 if ((r0
[2] & 63) > dither
[x
& 7])
3106 *ptr
^= (0x0c & OnPixels
[r0
[2]]);
3108 *ptr
^= (0x0c & OffPixels
[r0
[2]]);
3115 dither
= Floyd4x4
[y
& 3];
3117 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3119 if ((r0
[0] & 15) > dither
[x
& 3])
3120 *ptr
^= (0xf0 & OnPixels
[r0
[0]]);
3122 *ptr
^= (0xf0 & OffPixels
[r0
[0]]);
3124 if ((r0
[1] & 15) > dither
[x
& 3])
3125 *ptr
++ ^= (0x0f & OnPixels
[r0
[1]]);
3127 *ptr
++ ^= (0x0f & OffPixels
[r0
[1]]);
3129 if ((r0
[2] & 15) > dither
[x
& 3])
3130 *ptr
^= (0xf0 & OnPixels
[r0
[2]]);
3132 *ptr
^= (0xf0 & OffPixels
[r0
[2]]);
3139 for (x
= xsize
; x
> 0; x
--, r0
+= 3, r1
+= 3)
3144 *ptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
3149 *ptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
3154 *ptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
3162 case CUPS_ORDER_BANDED
:
3164 mptr
= ptr
+ bandwidth
;
3165 yptr
= ptr
+ 2 * bandwidth
;
3167 memset(ptr
+ 3 * bandwidth
, 255, bandwidth
);
3169 switch (header
->cupsBitsPerColor
)
3172 bitmask
= 0x80 >> (bitoffset
& 7);
3173 dither
= Floyd16xc16
[y
& 15];
3175 for (x
= xsize
; x
> 0; x
--)
3177 if (*r0
++ > dither
[x
& 15])
3179 if (*r0
++ > dither
[x
& 15])
3181 if (*r0
++ > dither
[x
& 15])
3197 bitmask
= 0x0 >> (bitoffset
& 7);
3198 dither
= Floyd8x8
[y
& 7];
3200 for (x
= xsize
; x
> 0; x
--)
3202 if ((*r0
& 63) > dither
[x
& 7])
3203 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
3205 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
3207 if ((*r0
& 63) > dither
[x
& 7])
3208 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
3210 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
3212 if ((*r0
& 63) > dither
[x
& 7])
3213 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
3215 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
3231 bitmask
= 0xf0 >> (bitoffset
& 7);
3232 dither
= Floyd4x4
[y
& 3];
3234 for (x
= xsize
; x
> 0; x
--)
3236 if ((*r0
& 15) > dither
[x
& 3])
3237 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
3239 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
3241 if ((*r0
& 15) > dither
[x
& 3])
3242 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
3244 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
3246 if ((*r0
& 15) > dither
[x
& 3])
3247 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
3249 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
3251 if (bitmask
== 0xf0)
3265 for (x
= xsize
; x
> 0; x
--, r0
+= 3, r1
+= 3)
3270 *cptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
3275 *mptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
3280 *yptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
3286 case CUPS_ORDER_PLANAR
:
3289 memset(row
, 255, header
->cupsBytesPerLine
);
3293 switch (header
->cupsBitsPerColor
)
3296 bitmask
= 0x80 >> (bitoffset
& 7);
3297 dither
= Floyd16xc16
[y
& 15];
3302 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3304 if (r0
[0] > dither
[x
& 15])
3318 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3320 if (r0
[1] > dither
[x
& 15])
3334 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3336 if (r0
[2] > dither
[x
& 15])
3352 bitmask
= 0x0 >> (bitoffset
& 7);
3353 dither
= Floyd8x8
[y
& 7];
3356 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3358 if ((*r0
& 63) > dither
[x
& 7])
3359 *ptr
^= (bitmask
& OnPixels
[*r0
]);
3361 *ptr
^= (bitmask
& OffPixels
[*r0
]);
3375 bitmask
= 0xf0 >> (bitoffset
& 7);
3376 dither
= Floyd4x4
[y
& 3];
3379 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3381 if ((*r0
& 15) > dither
[x
& 3])
3382 *ptr
^= (bitmask
& OnPixels
[*r0
]);
3384 *ptr
^= (bitmask
& OffPixels
[*r0
]);
3386 if (bitmask
== 0xf0)
3401 for (x
= xsize
; x
> 0; x
--, r0
+= 3, r1
+= 3)
3406 *ptr
++ = (*r0
* yerr0
+ *r1
* yerr1
) / ysize
;
3416 * 'format_W()' - Convert image data to luminance.
3420 format_W(cups_page_header2_t
*header
, /* I - Page header */
3421 unsigned char *row
, /* IO - Bitmap data for device */
3422 int y
, /* I - Current row */
3423 int z
, /* I - Current plane */
3424 int xsize
, /* I - Width of image data */
3425 int ysize
, /* I - Height of image data */
3426 int yerr0
, /* I - Top Y error */
3427 int yerr1
, /* I - Bottom Y error */
3428 cups_ib_t
*r0
, /* I - Primary image data */
3429 cups_ib_t
*r1
) /* I - Image data for interpolation */
3431 cups_ib_t
*ptr
, /* Pointer into row */
3432 bitmask
; /* Current mask for pixel */
3433 int bitoffset
; /* Current offset in line */
3434 int x
, /* Current X coordinate on page */
3435 *dither
; /* Pointer into dither array */
3446 bitoffset
= header
->cupsBitsPerPixel
* ((header
->cupsWidth
- xsize
) / 2);
3449 bitoffset
= header
->cupsBitsPerPixel
* (header
->cupsWidth
- xsize
);
3453 ptr
= row
+ bitoffset
/ 8;
3455 switch (header
->cupsBitsPerColor
)
3458 bitmask
= 0x80 >> (bitoffset
& 7);
3459 dither
= Floyd16xc16
[y
& 15];
3461 for (x
= xsize
; x
> 0; x
--)
3463 if (*r0
++ > dither
[x
& 15])
3477 bitmask
= 0x0 >> (bitoffset
& 7);
3478 dither
= Floyd8x8
[y
& 7];
3480 for (x
= xsize
; x
> 0; x
--)
3482 if ((*r0
& 63) > dither
[x
& 7])
3483 *ptr
^= (bitmask
& OnPixels
[*r0
++]);
3485 *ptr
^= (bitmask
& OffPixels
[*r0
++]);
3499 bitmask
= 0xf0 >> (bitoffset
& 7);
3500 dither
= Floyd4x4
[y
& 3];
3502 for (x
= xsize
; x
> 0; x
--)
3504 if ((*r0
& 15) > dither
[x
& 3])
3505 *ptr
^= (bitmask
& OnPixels
[*r0
++]);
3507 *ptr
^= (bitmask
& OffPixels
[*r0
++]);
3509 if (bitmask
== 0xf0)
3521 for (x
= xsize
; x
> 0; x
--, r0
++, r1
++)
3526 *ptr
++ = (*r0
* yerr0
+ *r1
* yerr1
) / ysize
;
3534 * 'format_YMC()' - Convert image data to YMC.
3538 format_YMC(cups_page_header2_t
*header
, /* I - Page header */
3539 unsigned char *row
, /* IO - Bitmap data for device */
3540 int y
, /* I - Current row */
3541 int z
, /* I - Current plane */
3542 int xsize
, /* I - Width of image data */
3543 int ysize
, /* I - Height of image data */
3544 int yerr0
, /* I - Top Y error */
3545 int yerr1
, /* I - Bottom Y error */
3546 cups_ib_t
*r0
, /* I - Primary image data */
3547 cups_ib_t
*r1
) /* I - Image data for interpolation */
3549 cups_ib_t
*ptr
, /* Pointer into row */
3550 *cptr
, /* Pointer into cyan */
3551 *mptr
, /* Pointer into magenta */
3552 *yptr
, /* Pointer into yellow */
3553 bitmask
; /* Current mask for pixel */
3554 int bitoffset
; /* Current offset in line */
3555 int bandwidth
; /* Width of a color band */
3556 int x
, /* Current X coordinate on page */
3557 *dither
; /* Pointer into dither array */
3566 bitoffset
= header
->cupsBitsPerPixel
* ((header
->cupsWidth
- xsize
) / 2);
3569 bitoffset
= header
->cupsBitsPerPixel
* (header
->cupsWidth
- xsize
);
3573 ptr
= row
+ bitoffset
/ 8;
3574 bandwidth
= header
->cupsBytesPerLine
/ 3;
3576 switch (header
->cupsColorOrder
)
3578 case CUPS_ORDER_CHUNKED
:
3579 switch (header
->cupsBitsPerColor
)
3582 bitmask
= 64 >> (bitoffset
& 7);
3583 dither
= Floyd16xc16
[y
& 15];
3585 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3587 if (r0
[2] > dither
[x
& 15])
3591 if (r0
[1] > dither
[x
& 15])
3595 if (r0
[0] > dither
[x
& 15])
3609 dither
= Floyd8x8
[y
& 7];
3611 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3613 if ((r0
[2] & 63) > dither
[x
& 7])
3614 *ptr
^= (0x30 & OnPixels
[r0
[2]]);
3616 *ptr
^= (0x30 & OffPixels
[r0
[2]]);
3618 if ((r0
[1] & 63) > dither
[x
& 7])
3619 *ptr
^= (0x0c & OnPixels
[r0
[1]]);
3621 *ptr
^= (0x0c & OffPixels
[r0
[1]]);
3623 if ((r0
[0] & 63) > dither
[x
& 7])
3624 *ptr
++ ^= (0x03 & OnPixels
[r0
[0]]);
3626 *ptr
++ ^= (0x03 & OffPixels
[r0
[0]]);
3631 dither
= Floyd4x4
[y
& 3];
3633 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3635 if ((r0
[2] & 15) > dither
[x
& 3])
3636 *ptr
++ ^= (0x0f & OnPixels
[r0
[2]]);
3638 *ptr
++ ^= (0x0f & OffPixels
[r0
[2]]);
3640 if ((r0
[1] & 15) > dither
[x
& 3])
3641 *ptr
^= (0xf0 & OnPixels
[r0
[1]]);
3643 *ptr
^= (0xf0 & OffPixels
[r0
[1]]);
3645 if ((r0
[0] & 15) > dither
[x
& 3])
3646 *ptr
++ ^= (0x0f & OnPixels
[r0
[0]]);
3648 *ptr
++ ^= (0x0f & OffPixels
[r0
[0]]);
3653 for (x
= xsize
; x
> 0; x
--, r0
+= 3, r1
+= 3)
3658 *ptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
3663 *ptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
3668 *ptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
3674 case CUPS_ORDER_BANDED
:
3676 mptr
= ptr
+ bandwidth
;
3677 cptr
= ptr
+ 2 * bandwidth
;
3679 switch (header
->cupsBitsPerColor
)
3682 bitmask
= 0x80 >> (bitoffset
& 7);
3683 dither
= Floyd16xc16
[y
& 15];
3685 for (x
= xsize
; x
> 0; x
--)
3687 if (*r0
++ > dither
[x
& 15])
3689 if (*r0
++ > dither
[x
& 15])
3691 if (*r0
++ > dither
[x
& 15])
3707 bitmask
= 0x0 >> (bitoffset
& 7);
3708 dither
= Floyd8x8
[y
& 7];
3710 for (x
= xsize
; x
> 0; x
--)
3712 if ((*r0
& 63) > dither
[x
& 7])
3713 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
3715 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
3717 if ((*r0
& 63) > dither
[x
& 7])
3718 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
3720 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
3722 if ((*r0
& 63) > dither
[x
& 7])
3723 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
3725 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
3741 bitmask
= 0xf0 >> (bitoffset
& 7);
3742 dither
= Floyd4x4
[y
& 3];
3744 for (x
= xsize
; x
> 0; x
--)
3746 if ((*r0
& 15) > dither
[x
& 3])
3747 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
3749 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
3751 if ((*r0
& 15) > dither
[x
& 3])
3752 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
3754 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
3756 if ((*r0
& 15) > dither
[x
& 3])
3757 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
3759 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
3761 if (bitmask
== 0xf0)
3775 for (x
= xsize
; x
> 0; x
--, r0
+= 3, r1
+= 3)
3780 *cptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
3785 *mptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
3790 *yptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
3796 case CUPS_ORDER_PLANAR
:
3797 switch (header
->cupsBitsPerColor
)
3800 bitmask
= 0x80 >> (bitoffset
& 7);
3801 dither
= Floyd16xc16
[y
& 15];
3806 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3808 if (r0
[0] > dither
[x
& 15])
3822 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3824 if (r0
[1] > dither
[x
& 15])
3838 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3840 if (r0
[2] > dither
[x
& 15])
3856 bitmask
= 0x0 >> (bitoffset
& 7);
3857 dither
= Floyd8x8
[y
& 7];
3861 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3863 if ((*r0
& 63) > dither
[x
& 7])
3864 *ptr
^= (bitmask
& OnPixels
[*r0
]);
3866 *ptr
^= (bitmask
& OffPixels
[*r0
]);
3880 bitmask
= 0xf0 >> (bitoffset
& 7);
3881 dither
= Floyd4x4
[y
& 3];
3885 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3887 if ((*r0
& 15) > dither
[x
& 3])
3888 *ptr
^= (bitmask
& OnPixels
[*r0
]);
3890 *ptr
^= (bitmask
& OffPixels
[*r0
]);
3892 if (bitmask
== 0xf0)
3908 for (x
= xsize
; x
> 0; x
--, r0
+= 3, r1
+= 3)
3913 *ptr
++ = (*r0
* yerr0
+ *r1
* yerr1
) / ysize
;
3923 * 'format_YMCK()' - Convert image data to YMCK.
3927 format_YMCK(cups_page_header2_t
*header
,/* I - Page header */
3928 unsigned char *row
, /* IO - Bitmap data for device */
3929 int y
, /* I - Current row */
3930 int z
, /* I - Current plane */
3931 int xsize
, /* I - Width of image data */
3932 int ysize
, /* I - Height of image data */
3933 int yerr0
, /* I - Top Y error */
3934 int yerr1
, /* I - Bottom Y error */
3935 cups_ib_t
*r0
, /* I - Primary image data */
3936 cups_ib_t
*r1
) /* I - Image data for interpolation */
3938 cups_ib_t
*ptr
, /* Pointer into row */
3939 *cptr
, /* Pointer into cyan */
3940 *mptr
, /* Pointer into magenta */
3941 *yptr
, /* Pointer into yellow */
3942 *kptr
, /* Pointer into black */
3943 bitmask
; /* Current mask for pixel */
3944 int bitoffset
; /* Current offset in line */
3945 int bandwidth
; /* Width of a color band */
3946 int x
, /* Current X coordinate on page */
3947 *dither
; /* Pointer into dither array */
3956 bitoffset
= header
->cupsBitsPerPixel
* ((header
->cupsWidth
- xsize
) / 2);
3959 bitoffset
= header
->cupsBitsPerPixel
* (header
->cupsWidth
- xsize
);
3963 ptr
= row
+ bitoffset
/ 8;
3964 bandwidth
= header
->cupsBytesPerLine
/ 4;
3966 switch (header
->cupsColorOrder
)
3968 case CUPS_ORDER_CHUNKED
:
3969 switch (header
->cupsBitsPerColor
)
3972 bitmask
= 128 >> (bitoffset
& 7);
3973 dither
= Floyd16xc16
[y
& 15];
3975 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
3977 if (r0
[2] > dither
[x
& 15])
3981 if (r0
[1] > dither
[x
& 15])
3985 if (r0
[0] > dither
[x
& 15])
3989 if (r0
[3] > dither
[x
& 15])
4004 dither
= Floyd8x8
[y
& 7];
4006 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
4008 if ((r0
[2] & 63) > dither
[x
& 7])
4009 *ptr
^= (0x0 & OnPixels
[r0
[2]]);
4011 *ptr
^= (0x0 & OffPixels
[r0
[2]]);
4013 if ((r0
[1] & 63) > dither
[x
& 7])
4014 *ptr
^= (0x30 & OnPixels
[r0
[1]]);
4016 *ptr
^= (0x30 & OffPixels
[r0
[1]]);
4018 if ((r0
[0] & 63) > dither
[x
& 7])
4019 *ptr
^= (0x0c & OnPixels
[r0
[0]]);
4021 *ptr
^= (0x0c & OffPixels
[r0
[0]]);
4023 if ((r0
[3] & 63) > dither
[x
& 7])
4024 *ptr
++ ^= (0x03 & OnPixels
[r0
[3]]);
4026 *ptr
++ ^= (0x03 & OffPixels
[r0
[3]]);
4031 dither
= Floyd4x4
[y
& 3];
4033 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
4035 if ((r0
[2] & 15) > dither
[x
& 3])
4036 *ptr
^= (0xf0 & OnPixels
[r0
[2]]);
4038 *ptr
^= (0xf0 & OffPixels
[r0
[2]]);
4040 if ((r0
[1] & 15) > dither
[x
& 3])
4041 *ptr
++ ^= (0x0f & OnPixels
[r0
[1]]);
4043 *ptr
++ ^= (0x0f & OffPixels
[r0
[1]]);
4045 if ((r0
[0] & 15) > dither
[x
& 3])
4046 *ptr
^= (0xf0 & OnPixels
[r0
[0]]);
4048 *ptr
^= (0xf0 & OffPixels
[r0
[0]]);
4050 if ((r0
[3] & 15) > dither
[x
& 3])
4051 *ptr
++ ^= (0x0f & OnPixels
[r0
[3]]);
4053 *ptr
++ ^= (0x0f & OffPixels
[r0
[3]]);
4058 for (x
= xsize
; x
> 0; x
--, r0
+= 4, r1
+= 4)
4063 *ptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
4068 *ptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
4073 *ptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
4078 *ptr
++ = (r0
[3] * yerr0
+ r1
[3] * yerr1
) / ysize
;
4084 case CUPS_ORDER_BANDED
:
4086 mptr
= ptr
+ bandwidth
;
4087 cptr
= ptr
+ 2 * bandwidth
;
4088 kptr
= ptr
+ 3 * bandwidth
;
4090 switch (header
->cupsBitsPerColor
)
4093 bitmask
= 0x80 >> (bitoffset
& 7);
4094 dither
= Floyd16xc16
[y
& 15];
4096 for (x
= xsize
; x
> 0; x
--)
4098 if (*r0
++ > dither
[x
& 15])
4100 if (*r0
++ > dither
[x
& 15])
4102 if (*r0
++ > dither
[x
& 15])
4104 if (*r0
++ > dither
[x
& 15])
4122 bitmask
= 0x0 >> (bitoffset
& 7);
4123 dither
= Floyd8x8
[y
& 7];
4125 for (x
= xsize
; x
> 0; x
--)
4127 if ((*r0
& 63) > dither
[x
& 7])
4128 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
4130 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
4132 if ((*r0
& 63) > dither
[x
& 7])
4133 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
4135 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
4137 if ((*r0
& 63) > dither
[x
& 7])
4138 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
4140 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
4142 if ((*r0
& 63) > dither
[x
& 7])
4143 *kptr
^= (bitmask
& OnPixels
[*r0
++]);
4145 *kptr
^= (bitmask
& OffPixels
[*r0
++]);
4162 bitmask
= 0xf0 >> (bitoffset
& 7);
4163 dither
= Floyd4x4
[y
& 3];
4165 for (x
= xsize
; x
> 0; x
--)
4167 if ((*r0
& 15) > dither
[x
& 3])
4168 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
4170 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
4172 if ((*r0
& 15) > dither
[x
& 3])
4173 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
4175 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
4177 if ((*r0
& 15) > dither
[x
& 3])
4178 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
4180 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
4182 if ((*r0
& 15) > dither
[x
& 3])
4183 *kptr
^= (bitmask
& OnPixels
[*r0
++]);
4185 *kptr
^= (bitmask
& OffPixels
[*r0
++]);
4187 if (bitmask
== 0xf0)
4202 for (x
= xsize
; x
> 0; x
--, r0
+= 4, r1
+= 4)
4207 *cptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
4212 *mptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
4217 *yptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
4222 *kptr
++ = (r0
[3] * yerr0
+ r1
[3] * yerr1
) / ysize
;
4228 case CUPS_ORDER_PLANAR
:
4229 switch (header
->cupsBitsPerColor
)
4232 bitmask
= 0x80 >> (bitoffset
& 7);
4233 dither
= Floyd16xc16
[y
& 15];
4240 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
4242 if (*r0
> dither
[x
& 15])
4256 bitmask
= 0x0 >> (bitoffset
& 7);
4257 dither
= Floyd8x8
[y
& 7];
4263 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
4265 if ((*r0
& 63) > dither
[x
& 7])
4266 *ptr
^= (bitmask
& OnPixels
[*r0
]);
4268 *ptr
^= (bitmask
& OffPixels
[*r0
]);
4282 bitmask
= 0xf0 >> (bitoffset
& 7);
4283 dither
= Floyd4x4
[y
& 3];
4289 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
4291 if ((*r0
& 15) > dither
[x
& 3])
4292 *ptr
^= (bitmask
& OnPixels
[*r0
]);
4294 *ptr
^= (bitmask
& OffPixels
[*r0
]);
4296 if (bitmask
== 0xf0)
4319 for (x
= xsize
; x
> 0; x
--, r0
+= 4, r1
+= 4)
4324 *ptr
++ = (*r0
* yerr0
+ *r1
* yerr1
) / ysize
;
4334 * 'make_lut()' - Make a lookup table given gamma and brightness values.
4338 make_lut(cups_ib_t
*lut
, /* I - Lookup table */
4339 int colorspace
, /* I - Colorspace */
4340 float g
, /* I - Image gamma */
4341 float b
) /* I - Image brightness */
4343 int i
; /* Looping var */
4344 int v
; /* Current value */
4350 for (i
= 0; i
< 256; i
++)
4353 v
= 255.0 * b
* (1.0 - pow(1.0 - (float)i
/ 255.0, g
)) + 0.5;
4355 v
= 255.0 * (1.0 - b
* (1.0 - pow((float)i
/ 255.0, g
))) + 0.5;
4368 * 'raster_cb()' - Validate the page header.
4371 static int /* O - 0 if OK, -1 if not */
4373 cups_page_header2_t
*header
, /* IO - Raster header */
4374 int preferred_bits
) /* I - Preferred bits per color */
4377 * Ensure that colorimetric colorspaces use at least 8 bits per
4381 if ((header
->cupsColorSpace
== CUPS_CSPACE_CIEXYZ
||
4382 header
->cupsColorSpace
== CUPS_CSPACE_CIELab
||
4383 header
->cupsColorSpace
>= CUPS_CSPACE_ICC1
) &&
4384 header
->cupsBitsPerColor
< 8)
4385 header
->cupsBitsPerColor
= 8;
4392 * End of "$Id: imagetoraster.c 5485 2006-05-02 23:59:56Z mike $".