2 * "$Id: imagetoraster.c 4767 2005-10-10 19:23:23Z mike $"
4 * Image file to raster filter for the Common UNIX Printing System (CUPS).
6 * Copyright 1993-2005 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 * exec_code() - Execute PostScript setpagedevice commands as
31 * format_CMY() - Convert image data to CMY.
32 * format_CMYK() - Convert image data to CMYK.
33 * format_K() - Convert image data to black.
34 * format_KCMY() - Convert image data to KCMY.
35 * format_KCMYcm() - Convert image data to KCMYcm.
36 * format_RGBA() - Convert image data to RGBA/RGBW.
37 * format_W() - Convert image data to luminance.
38 * format_YMC() - Convert image data to YMC.
39 * format_YMCK() - Convert image data to YMCK.
40 * make_lut() - Make a lookup table given gamma and brightness values.
44 * Include necessary headers...
48 #include "image-private.h"
58 int Flip
= 0, /* Flip/mirror pages */
59 XPosition
= 0, /* Horizontal position on page */
60 YPosition
= 0, /* Vertical position on page */
61 Collate
= 0, /* Collate copies? */
62 Copies
= 1; /* Number of copies */
63 int Floyd16x16
[16][16] = /* Traditional Floyd ordered dither */
65 { 0, 128, 32, 160, 8, 136, 40, 168,
66 2, 130, 34, 162, 10, 138, 42, 170 },
67 { 192, 64, 224, 96, 200, 72, 232, 104,
68 194, 66, 226, 98, 202, 74, 234, 106 },
69 { 48, 176, 16, 144, 56, 184, 24, 152,
70 50, 178, 18, 146, 58, 186, 26, 154 },
71 { 240, 112, 208, 80, 248, 120, 216, 88,
72 242, 114, 210, 82, 250, 122, 218, 90 },
73 { 12, 140, 44, 172, 4, 132, 36, 164,
74 14, 142, 46, 174, 6, 134, 38, 166 },
75 { 204, 76, 236, 108, 196, 68, 228, 100,
76 206, 78, 238, 110, 198, 70, 230, 102 },
77 { 60, 188, 28, 156, 52, 180, 20, 148,
78 62, 190, 30, 158, 54, 182, 22, 150 },
79 { 252, 124, 220, 92, 244, 116, 212, 84,
80 254, 126, 222, 94, 246, 118, 214, 86 },
81 { 3, 131, 35, 163, 11, 139, 43, 171,
82 1, 129, 33, 161, 9, 137, 41, 169 },
83 { 195, 67, 227, 99, 203, 75, 235, 107,
84 193, 65, 225, 97, 201, 73, 233, 105 },
85 { 51, 179, 19, 147, 59, 187, 27, 155,
86 49, 177, 17, 145, 57, 185, 25, 153 },
87 { 243, 115, 211, 83, 251, 123, 219, 91,
88 241, 113, 209, 81, 249, 121, 217, 89 },
89 { 15, 143, 47, 175, 7, 135, 39, 167,
90 13, 141, 45, 173, 5, 133, 37, 165 },
91 { 207, 79, 239, 111, 199, 71, 231, 103,
92 205, 77, 237, 109, 197, 69, 229, 101 },
93 { 63, 191, 31, 159, 55, 183, 23, 151,
94 61, 189, 29, 157, 53, 181, 21, 149 },
95 { 254, 127, 223, 95, 247, 119, 215, 87,
96 253, 125, 221, 93, 245, 117, 213, 85 }
100 { 0, 32, 8, 40, 2, 34, 10, 42 },
101 { 48, 16, 56, 24, 50, 18, 58, 26 },
102 { 12, 44, 4, 36, 14, 46, 6, 38 },
103 { 60, 28, 52, 20, 62, 30, 54, 22 },
104 { 3, 35, 11, 43, 1, 33, 9, 41 },
105 { 51, 19, 59, 27, 49, 17, 57, 25 },
106 { 15, 47, 7, 39, 13, 45, 5, 37 },
107 { 63, 31, 55, 23, 61, 29, 53, 21 }
117 cups_ib_t OnPixels
[256], /* On-pixel LUT */
118 OffPixels
[256]; /* Off-pixel LUT */
119 int Planes
[] = /* Number of planes for each colorspace */
121 1, /* CUPS_CSPACE_W */
122 3, /* CUPS_CSPACE_RGB */
123 4, /* CUPS_CSPACE_RGBA */
124 1, /* CUPS_CSPACE_K */
125 3, /* CUPS_CSPACE_CMY */
126 3, /* CUPS_CSPACE_YMC */
127 4, /* CUPS_CSPACE_CMYK */
128 4, /* CUPS_CSPACE_YMCK */
129 4, /* CUPS_CSPACE_KCMY */
130 6, /* CUPS_CSPACE_KCMYcm */
131 4, /* CUPS_CSPACE_GMCK */
132 4, /* CUPS_CSPACE_GMCS */
133 1, /* CUPS_CSPACE_WHITE */
134 1, /* CUPS_CSPACE_GOLD */
135 1, /* CUPS_CSPACE_SILVER */
136 3, /* CUPS_CSPACE_CIEXYZ */
137 3, /* CUPS_CSPACE_CIELab */
138 4, /* CUPS_CSPACE_RGBW */
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 0, /* ... reserved ... */
153 3, /* CUPS_CSPACE_ICC1 */
154 3, /* CUPS_CSPACE_ICC2 */
155 3, /* CUPS_CSPACE_ICC3 */
156 3, /* CUPS_CSPACE_ICC4 */
157 3, /* CUPS_CSPACE_ICC5 */
158 3, /* CUPS_CSPACE_ICC6 */
159 3, /* CUPS_CSPACE_ICC7 */
160 3, /* CUPS_CSPACE_ICC8 */
161 3, /* CUPS_CSPACE_ICC9 */
162 3, /* CUPS_CSPACE_ICCA */
163 3, /* CUPS_CSPACE_ICCB */
164 3, /* CUPS_CSPACE_ICCC */
165 3, /* CUPS_CSPACE_ICCD */
166 3, /* CUPS_CSPACE_ICCE */
167 3 /* CUPS_CSPACE_ICCF */
175 static void exec_code(cups_page_header2_t
*header
, const char *code
);
176 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
);
177 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
);
178 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
);
179 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
);
180 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
);
181 #define format_RGB format_CMY
182 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
);
183 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
);
184 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
);
185 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
);
186 static void make_lut(cups_ib_t
*, int, float, float);
190 * 'main()' - Main entry...
193 int /* O - Exit status */
194 main(int argc
, /* I - Number of command-line arguments */
195 char *argv
[]) /* I - Command-line arguments */
197 int i
; /* Looping var */
198 cups_image_t
*img
; /* Image to print */
199 float xprint
, /* Printable area */
201 xinches
, /* Total size in inches */
203 float xsize
, /* Total size in points */
207 float aspect
; /* Aspect ratio */
208 int xpages
, /* # x pages */
209 ypages
, /* # y pages */
210 xpage
, /* Current x page */
211 ypage
, /* Current y page */
212 xtemp
, /* Bitmap width in pixels */
213 ytemp
, /* Bitmap height in pixels */
214 page
; /* Current page number */
215 int x0
, y0
, /* Corners of the page in image coords */
217 ppd_file_t
*ppd
; /* PPD file */
218 ppd_choice_t
*choice
, /* PPD option choice */
219 **choices
; /* List of marked choices */
220 int count
; /* Number of marked choices */
221 char *resolution
, /* Output resolution */
222 *media_type
; /* Media type */
223 ppd_profile_t
*profile
; /* Color profile */
224 ppd_profile_t userprofile
; /* User-specified profile */
225 cups_raster_t
*ras
; /* Raster stream */
226 cups_page_header2_t header
; /* Page header */
227 int num_options
; /* Number of print options */
228 cups_option_t
*options
; /* Print options */
229 const char *val
; /* Option value */
230 int slowcollate
, /* Collate copies the slow way */
231 slowcopies
; /* Make copies the "slow" way? */
232 float g
; /* Gamma correction value */
233 float b
; /* Brightness factor */
234 float zoom
; /* Zoom facter */
235 int xppi
, yppi
; /* Pixels-per-inch */
236 int hue
, sat
; /* Hue and saturation adjustment */
237 cups_izoom_t
*z
; /* Image zoom buffer */
238 cups_iztype_t zoom_type
; /* Image zoom type */
239 int primary
, /* Primary image colorspace */
240 secondary
; /* Secondary image colorspace */
241 cups_ib_t
*row
, /* Current row */
243 *r1
; /* Bottom row */
244 int y
, /* Current Y coordinate on page */
245 iy
, /* Current Y coordinate in image */
246 last_iy
, /* Previous Y coordinate in image */
247 yerr0
, /* Top Y error value */
248 yerr1
, /* Bottom Y error value */
249 blank
; /* Blank value */
250 cups_ib_t lut
[256]; /* Gamma/brightness LUT */
251 int plane
, /* Current color plane */
252 num_planes
; /* Number of color planes */
253 char filename
[1024]; /* Name of file to print */
257 * Make sure status messages are not buffered...
260 setbuf(stderr
, NULL
);
263 * Check command-line...
266 if (argc
< 6 || argc
> 7)
268 fputs("ERROR: imagetoraster job-id user title copies options [file]\n", stderr
);
272 fprintf(stderr
, "INFO: %s %s %s %s %s %s %s\n", argv
[0], argv
[1], argv
[2],
273 argv
[3], argv
[4], argv
[5], argv
[6] ? argv
[6] : "(null)");
276 * See if we need to use the imagetops and pstoraster filters instead...
280 num_options
= cupsParseOptions(argv
[5], 0, &options
);
282 if (getenv("CLASSIFICATION") ||
283 cupsGetOption("page-label", num_options
, options
))
286 * Yes, fork a copy of pstoraster and then transfer control to imagetops...
289 int mypipes
[2]; /* New pipes for imagetops | pstoraster */
290 int pid
; /* PID of pstoraster */
293 cupsFreeOptions(num_options
, options
);
297 perror("ERROR: Unable to create pipes for imagetops | pstoraster");
301 if ((pid
= fork()) == 0)
304 * Child process for pstoraster... Assign new pipe input to pstoraster...
312 execlp("pstoraster", argv
[0], argv
[1], argv
[2], argv
[3], argv
[4], argv
[5],
314 perror("ERROR: Unable to exec pstoraster");
323 perror("ERROR: Unable to fork pstoraster");
328 * Update stdout so it points at the new pstoraster...
337 * Run imagetops to get the classification or page labelling that was
341 execlp("imagetops", argv
[0], argv
[1], argv
[2], argv
[3], argv
[4], argv
[5],
343 perror("ERROR: Unable to exec imagetops");
348 * Copy stdin as needed...
353 int fd
; /* File to write to */
354 char buffer
[8192]; /* Buffer to read into */
355 int bytes
; /* # of bytes to read */
358 if ((fd
= cupsTempFd(filename
, sizeof(filename
))) < 0)
360 perror("ERROR: Unable to copy image file");
364 fprintf(stderr
, "DEBUG: imagetoraster - copying to temp print file \"%s\"\n",
367 while ((bytes
= fread(buffer
, 1, sizeof(buffer
), stdin
)) > 0)
368 write(fd
, buffer
, bytes
);
373 strlcpy(filename
, argv
[6], sizeof(filename
));
376 * Process command-line options and write the prolog...
387 Copies
= atoi(argv
[4]);
389 ppd
= SetCommonOptions(num_options
, options
, 0);
391 if ((val
= cupsGetOption("multiple-document-handling", num_options
, options
)) != NULL
)
394 * This IPP attribute is unnecessarily complicated...
396 * single-document, separate-documents-collated-copies, and
397 * single-document-new-sheet all require collated copies.
399 * separate-documents-collated-copies allows for uncollated copies.
402 Collate
= strcasecmp(val
, "separate-documents-collated-copies") != 0;
405 if ((val
= cupsGetOption("Collate", num_options
, options
)) != NULL
&&
406 strcasecmp(val
, "True") == 0)
409 if ((val
= cupsGetOption("gamma", num_options
, options
)) != NULL
)
410 g
= atoi(val
) * 0.001f
;
412 if ((val
= cupsGetOption("brightness", num_options
, options
)) != NULL
)
413 b
= atoi(val
) * 0.01f
;
415 if ((val
= cupsGetOption("scaling", num_options
, options
)) != NULL
)
416 zoom
= atoi(val
) * 0.01;
418 if ((val
= cupsGetOption("ppi", num_options
, options
)) != NULL
)
419 if (sscanf(val
, "%dx%d", &xppi
, &yppi
) < 2)
422 if ((val
= cupsGetOption("position", num_options
, options
)) != NULL
)
424 if (strcasecmp(val
, "center") == 0)
429 else if (strcasecmp(val
, "top") == 0)
434 else if (strcasecmp(val
, "left") == 0)
439 else if (strcasecmp(val
, "right") == 0)
444 else if (strcasecmp(val
, "top-left") == 0)
449 else if (strcasecmp(val
, "top-right") == 0)
454 else if (strcasecmp(val
, "bottom") == 0)
459 else if (strcasecmp(val
, "bottom-left") == 0)
464 else if (strcasecmp(val
, "bottom-right") == 0)
471 if ((val
= cupsGetOption("saturation", num_options
, options
)) != NULL
)
474 if ((val
= cupsGetOption("hue", num_options
, options
)) != NULL
)
477 if ((val
= cupsGetOption("mirror", num_options
, options
)) != NULL
&&
478 strcasecmp(val
, "True") == 0)
482 * Set the needed options in the page header...
485 memset(&header
, 0, sizeof(header
));
486 header
.HWResolution
[0] = 100;
487 header
.HWResolution
[1] = 100;
488 header
.cupsBitsPerColor
= 1;
489 header
.cupsColorOrder
= CUPS_ORDER_CHUNKED
;
490 header
.cupsColorSpace
= CUPS_CSPACE_K
;
492 if (ppd
&& ppd
->patches
)
493 exec_code(&header
, ppd
->patches
);
495 if ((count
= ppdCollect(ppd
, PPD_ORDER_DOCUMENT
, &choices
)) > 0)
496 for (i
= 0; i
< count
; i
++)
497 exec_code(&header
, choices
[i
]->code
);
499 if ((count
= ppdCollect(ppd
, PPD_ORDER_ANY
, &choices
)) > 0)
500 for (i
= 0; i
< count
; i
++)
501 exec_code(&header
, choices
[i
]->code
);
503 if ((count
= ppdCollect(ppd
, PPD_ORDER_PROLOG
, &choices
)) > 0)
504 for (i
= 0; i
< count
; i
++)
505 exec_code(&header
, choices
[i
]->code
);
507 if ((count
= ppdCollect(ppd
, PPD_ORDER_PAGE
, &choices
)) > 0)
508 for (i
= 0; i
< count
; i
++)
509 exec_code(&header
, choices
[i
]->code
);
512 * Get the media type and resolution that have been chosen...
515 if ((choice
= ppdFindMarkedChoice(ppd
, "MediaType")) != NULL
)
516 media_type
= choice
->choice
;
520 if ((choice
= ppdFindMarkedChoice(ppd
, "Resolution")) != NULL
)
521 resolution
= choice
->choice
;
526 * Choose the appropriate colorspace...
529 switch (header
.cupsColorSpace
)
532 primary
= CUPS_IMAGE_WHITE
;
533 secondary
= CUPS_IMAGE_WHITE
;
534 header
.cupsBitsPerPixel
= header
.cupsBitsPerColor
;
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
;
545 * Ensure that colorimetric colorspaces use at least 8 bits per
549 if (header
.cupsColorSpace
>= CUPS_CSPACE_CIEXYZ
&&
550 header
.cupsBitsPerColor
< 8)
551 header
.cupsBitsPerColor
= 8;
553 if (header
.cupsColorOrder
== CUPS_ORDER_CHUNKED
)
555 if (header
.cupsBitsPerColor
>= 8)
556 header
.cupsBitsPerPixel
= header
.cupsBitsPerColor
* 3;
558 header
.cupsBitsPerPixel
= header
.cupsBitsPerColor
* 4;
561 header
.cupsBitsPerPixel
= header
.cupsBitsPerColor
;
565 case CUPS_CSPACE_WHITE
:
566 case CUPS_CSPACE_GOLD
:
567 case CUPS_CSPACE_SILVER
:
568 primary
= CUPS_IMAGE_BLACK
;
569 secondary
= CUPS_IMAGE_BLACK
;
570 header
.cupsBitsPerPixel
= header
.cupsBitsPerColor
;
573 case CUPS_CSPACE_CMYK
:
574 case CUPS_CSPACE_YMCK
:
575 case CUPS_CSPACE_KCMY
:
576 case CUPS_CSPACE_GMCK
:
577 case CUPS_CSPACE_GMCS
:
578 primary
= CUPS_IMAGE_CMYK
;
579 secondary
= CUPS_IMAGE_CMYK
;
581 if (header
.cupsColorOrder
== CUPS_ORDER_CHUNKED
)
582 header
.cupsBitsPerPixel
= header
.cupsBitsPerColor
* 4;
584 header
.cupsBitsPerPixel
= header
.cupsBitsPerColor
;
587 case CUPS_CSPACE_CMY
:
588 case CUPS_CSPACE_YMC
:
589 primary
= CUPS_IMAGE_CMY
;
590 secondary
= CUPS_IMAGE_CMY
;
592 if (header
.cupsColorOrder
== CUPS_ORDER_CHUNKED
)
594 if (header
.cupsBitsPerColor
>= 8)
595 header
.cupsBitsPerPixel
= 24;
597 header
.cupsBitsPerPixel
= header
.cupsBitsPerColor
* 4;
600 header
.cupsBitsPerPixel
= header
.cupsBitsPerColor
;
603 case CUPS_CSPACE_KCMYcm
:
604 if (header
.cupsBitsPerPixel
== 1)
606 primary
= CUPS_IMAGE_CMY
;
607 secondary
= CUPS_IMAGE_CMY
;
609 if (header
.cupsColorOrder
== CUPS_ORDER_CHUNKED
)
610 header
.cupsBitsPerPixel
= 8;
612 header
.cupsBitsPerPixel
= 1;
616 primary
= CUPS_IMAGE_CMYK
;
617 secondary
= CUPS_IMAGE_CMYK
;
619 if (header
.cupsColorOrder
== CUPS_ORDER_CHUNKED
)
620 header
.cupsBitsPerPixel
= header
.cupsBitsPerColor
* 4;
622 header
.cupsBitsPerPixel
= header
.cupsBitsPerColor
;
628 * Find a color profile matching the current options...
631 if ((val
= cupsGetOption("profile", num_options
, options
)) != NULL
)
633 profile
= &userprofile
;
634 sscanf(val
, "%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f",
635 &(userprofile
.density
), &(userprofile
.gamma
),
636 userprofile
.matrix
[0] + 0, userprofile
.matrix
[0] + 1,
637 userprofile
.matrix
[0] + 2,
638 userprofile
.matrix
[1] + 0, userprofile
.matrix
[1] + 1,
639 userprofile
.matrix
[1] + 2,
640 userprofile
.matrix
[2] + 0, userprofile
.matrix
[2] + 1,
641 userprofile
.matrix
[2] + 2);
643 userprofile
.density
*= 0.001f
;
644 userprofile
.gamma
*= 0.001f
;
645 userprofile
.matrix
[0][0] *= 0.001f
;
646 userprofile
.matrix
[0][1] *= 0.001f
;
647 userprofile
.matrix
[0][2] *= 0.001f
;
648 userprofile
.matrix
[1][0] *= 0.001f
;
649 userprofile
.matrix
[1][1] *= 0.001f
;
650 userprofile
.matrix
[1][2] *= 0.001f
;
651 userprofile
.matrix
[2][0] *= 0.001f
;
652 userprofile
.matrix
[2][1] *= 0.001f
;
653 userprofile
.matrix
[2][2] *= 0.001f
;
655 else if (ppd
!= NULL
)
657 fprintf(stderr
, "DEBUG: Searching for profile \"%s/%s\"...\n",
658 resolution
, media_type
);
660 for (i
= 0, profile
= ppd
->profiles
; i
< ppd
->num_profiles
; i
++, profile
++)
662 fprintf(stderr
, "DEBUG: \"%s/%s\" = ", profile
->resolution
,
663 profile
->media_type
);
665 if ((strcmp(profile
->resolution
, resolution
) == 0 ||
666 profile
->resolution
[0] == '-') &&
667 (strcmp(profile
->media_type
, media_type
) == 0 ||
668 profile
->media_type
[0] == '-'))
670 fputs("MATCH!\n", stderr
);
674 fputs("no.\n", stderr
);
678 * If we found a color profile, use it!
681 if (i
>= ppd
->num_profiles
)
688 cupsImageSetProfile(profile
->density
, profile
->gamma
, profile
->matrix
);
690 cupsImageSetRasterColorSpace(header
.cupsColorSpace
);
693 * Create a gamma/brightness LUT...
696 make_lut(lut
, primary
, g
, b
);
699 * Open the input image to print...
702 fputs("INFO: Loading image file...\n", stderr
);
704 img
= cupsImageOpen(filename
, primary
, secondary
, sat
, hue
, lut
);
711 fputs("ERROR: Unable to open image file for printing!\n", stderr
);
717 * Scale as necessary...
720 if (zoom
== 0.0 && xppi
== 0)
729 fprintf(stderr
, "DEBUG: Before scaling: xppi=%d, yppi=%d, zoom=%.2f\n",
735 * Scale the image as neccesary to match the desired pixels-per-inch.
740 xprint
= (PageTop
- PageBottom
) / 72.0;
741 yprint
= (PageRight
- PageLeft
) / 72.0;
745 xprint
= (PageRight
- PageLeft
) / 72.0;
746 yprint
= (PageTop
- PageBottom
) / 72.0;
749 fprintf(stderr
, "DEBUG: Before scaling: xprint=%.1f, yprint=%.1f\n",
752 xinches
= (float)img
->xsize
/ (float)xppi
;
753 yinches
= (float)img
->ysize
/ (float)yppi
;
755 fprintf(stderr
, "DEBUG: Image size is %.1f x %.1f inches...\n",
758 if ((val
= cupsGetOption("natural-scaling", num_options
, options
)) != NULL
)
760 xinches
= xinches
* atoi(val
) / 100;
761 yinches
= yinches
* atoi(val
) / 100;
764 if (cupsGetOption("orientation-requested", num_options
, options
) == NULL
&&
765 cupsGetOption("landscape", num_options
, options
) == NULL
)
768 * Rotate the image if it will fit landscape but not portrait...
771 fputs("DEBUG: Auto orientation...\n", stderr
);
773 if ((xinches
> xprint
|| yinches
> yprint
) &&
774 xinches
<= yprint
&& yinches
<= xprint
)
777 * Rotate the image as needed...
780 fputs("DEBUG: Using landscape orientation...\n", stderr
);
782 Orientation
= (Orientation
+ 1) & 3;
792 * Scale percentage of page size...
795 xprint
= (PageRight
- PageLeft
) / 72.0;
796 yprint
= (PageTop
- PageBottom
) / 72.0;
797 aspect
= (float)img
->yppi
/ (float)img
->xppi
;
799 fprintf(stderr
, "DEBUG: Before scaling: xprint=%.1f, yprint=%.1f\n",
802 fprintf(stderr
, "DEBUG: img->xppi = %d, img->yppi = %d, aspect = %f\n",
803 img
->xppi
, img
->yppi
, aspect
);
805 xsize
= xprint
* zoom
;
806 ysize
= xsize
* img
->ysize
/ img
->xsize
/ aspect
;
808 if (ysize
> (yprint
* zoom
))
810 ysize
= yprint
* zoom
;
811 xsize
= ysize
* img
->xsize
* aspect
/ img
->ysize
;
814 xsize2
= yprint
* zoom
;
815 ysize2
= xsize2
* img
->ysize
/ img
->xsize
/ aspect
;
817 if (ysize2
> (xprint
* zoom
))
819 ysize2
= xprint
* zoom
;
820 xsize2
= ysize2
* img
->xsize
* aspect
/ img
->ysize
;
823 fprintf(stderr
, "DEBUG: Portrait size is %.2f x %.2f inches\n", xsize
, ysize
);
824 fprintf(stderr
, "DEBUG: Landscape size is %.2f x %.2f inches\n", xsize2
, ysize2
);
826 if (cupsGetOption("orientation-requested", num_options
, options
) == NULL
&&
827 cupsGetOption("landscape", num_options
, options
) == NULL
)
830 * Choose the rotation with the largest area, but prefer
831 * portrait if they are equal...
834 fputs("DEBUG: Auto orientation...\n", stderr
);
836 if ((xsize
* ysize
) < (xsize2
* xsize2
))
839 * Do landscape orientation...
842 fputs("DEBUG: Using landscape orientation...\n", stderr
);
847 xprint
= (PageTop
- PageBottom
) / 72.0;
848 yprint
= (PageRight
- PageLeft
) / 72.0;
853 * Do portrait orientation...
856 fputs("DEBUG: Using portrait orientation...\n", stderr
);
863 else if (Orientation
& 1)
865 fputs("DEBUG: Using landscape orientation...\n", stderr
);
869 xprint
= (PageTop
- PageBottom
) / 72.0;
870 yprint
= (PageRight
- PageLeft
) / 72.0;
874 fputs("DEBUG: Using portrait orientation...\n", stderr
);
878 xprint
= (PageRight
- PageLeft
) / 72.0;
879 yprint
= (PageTop
- PageBottom
) / 72.0;
884 * Compute the number of pages to print and the size of the image on each
888 xpages
= ceil(xinches
/ xprint
);
889 ypages
= ceil(yinches
/ yprint
);
891 xprint
= xinches
/ xpages
;
892 yprint
= yinches
/ ypages
;
894 fprintf(stderr
, "DEBUG: xpages = %dx%.2fin, ypages = %dx%.2fin\n",
895 xpages
, xprint
, ypages
, yprint
);
898 * Compute the bitmap size...
901 if ((choice
= ppdFindMarkedChoice(ppd
, "PageSize")) != NULL
&&
902 strcasecmp(choice
->choice
, "Custom") == 0)
904 float width
, /* New width in points */
905 length
; /* New length in points */
909 * Use the correct width and length for the current orientation...
914 width
= yprint
* 72.0;
915 length
= xprint
* 72.0;
919 width
= xprint
* 72.0;
920 length
= yprint
* 72.0;
924 * Add margins to page size...
927 width
+= ppd
->custom_margins
[0] + ppd
->custom_margins
[2];
928 length
+= ppd
->custom_margins
[1] + ppd
->custom_margins
[3];
931 * Enforce minimums...
934 if (width
< ppd
->custom_min
[0])
935 width
= ppd
->custom_min
[0];
937 if (length
< ppd
->custom_min
[1])
938 length
= ppd
->custom_min
[1];
940 fprintf(stderr
, "DEBUG: Updated custom page size to %.2f x %.2f inches...\n",
941 width
/ 72.0, length
/ 72.0);
944 * Set the new custom size...
947 header
.PageSize
[0] = width
+ 0.5;
948 header
.PageSize
[1] = length
+ 0.5;
951 * Update page variables...
956 PageLeft
= ppd
->custom_margins
[0];
957 PageRight
= width
- ppd
->custom_margins
[2];
958 PageBottom
= ppd
->custom_margins
[1];
959 PageTop
= length
- ppd
->custom_margins
[3];
962 * Remove margins from page size...
965 width
-= ppd
->custom_margins
[0] + ppd
->custom_margins
[2];
966 length
-= ppd
->custom_margins
[1] + ppd
->custom_margins
[3];
969 * Set the bitmap size...
972 header
.cupsWidth
= width
* header
.HWResolution
[0] / 72.0;
973 header
.cupsHeight
= length
* header
.HWResolution
[1] / 72.0;
977 header
.cupsWidth
= (PageRight
- PageLeft
) * header
.HWResolution
[0] / 72.0;
978 header
.cupsHeight
= (PageTop
- PageBottom
) * header
.HWResolution
[1] / 72.0;
979 header
.PageSize
[0] = PageWidth
;
980 header
.PageSize
[1] = PageLength
;
983 header
.Margins
[0] = PageLeft
;
984 header
.Margins
[1] = PageBottom
;
986 fprintf(stderr
, "DEBUG: PageSize = [%d %d]\n", header
.PageSize
[0],
995 header
.ImagingBoundingBox
[0] = PageLeft
;
996 header
.ImagingBoundingBox
[2] = PageLeft
+ xprint
* 72;
999 header
.ImagingBoundingBox
[0] = (PageRight
+ PageLeft
- xprint
* 72) / 2;
1000 header
.ImagingBoundingBox
[2] = (PageRight
+ PageLeft
+ xprint
* 72) / 2;
1003 header
.ImagingBoundingBox
[0] = PageRight
- xprint
* 72;
1004 header
.ImagingBoundingBox
[2] = PageRight
;
1011 header
.ImagingBoundingBox
[1] = PageBottom
;
1012 header
.ImagingBoundingBox
[3] = PageBottom
+ yprint
* 72;
1015 header
.ImagingBoundingBox
[1] = (PageTop
+ PageBottom
- yprint
* 72) / 2;
1016 header
.ImagingBoundingBox
[3] = (PageTop
+ PageBottom
+ yprint
* 72) / 2;
1019 header
.ImagingBoundingBox
[1] = PageTop
- yprint
* 72;
1020 header
.ImagingBoundingBox
[3] = PageTop
;
1029 header
.ImagingBoundingBox
[0] = PageBottom
;
1030 header
.ImagingBoundingBox
[2] = PageBottom
+ yprint
* 72;
1033 header
.ImagingBoundingBox
[0] = (PageTop
+ PageBottom
- yprint
* 72) / 2;
1034 header
.ImagingBoundingBox
[2] = (PageTop
+ PageBottom
+ yprint
* 72) / 2;
1037 header
.ImagingBoundingBox
[0] = PageTop
- yprint
* 72;
1038 header
.ImagingBoundingBox
[2] = PageTop
;
1045 header
.ImagingBoundingBox
[1] = PageLeft
;
1046 header
.ImagingBoundingBox
[3] = PageLeft
+ xprint
* 72;
1049 header
.ImagingBoundingBox
[1] = (PageRight
+ PageLeft
- xprint
* 72) / 2;
1050 header
.ImagingBoundingBox
[3] = (PageRight
+ PageLeft
+ xprint
* 72) / 2;
1053 header
.ImagingBoundingBox
[1] = PageRight
- xprint
* 72;
1054 header
.ImagingBoundingBox
[3] = PageRight
;
1063 header
.ImagingBoundingBox
[0] = PageLeft
;
1064 header
.ImagingBoundingBox
[2] = PageLeft
+ xprint
* 72;
1067 header
.ImagingBoundingBox
[0] = (PageRight
+ PageLeft
- xprint
* 72) / 2;
1068 header
.ImagingBoundingBox
[2] = (PageRight
+ PageLeft
+ xprint
* 72) / 2;
1071 header
.ImagingBoundingBox
[0] = PageRight
- xprint
* 72;
1072 header
.ImagingBoundingBox
[2] = PageRight
;
1079 header
.ImagingBoundingBox
[1] = PageBottom
;
1080 header
.ImagingBoundingBox
[3] = PageBottom
+ yprint
* 72;
1083 header
.ImagingBoundingBox
[1] = (PageTop
+ PageBottom
- yprint
* 72) / 2;
1084 header
.ImagingBoundingBox
[3] = (PageTop
+ PageBottom
+ yprint
* 72) / 2;
1087 header
.ImagingBoundingBox
[1] = PageTop
- yprint
* 72;
1088 header
.ImagingBoundingBox
[3] = PageTop
;
1097 header
.ImagingBoundingBox
[0] = PageBottom
;
1098 header
.ImagingBoundingBox
[2] = PageBottom
+ yprint
* 72;
1101 header
.ImagingBoundingBox
[0] = (PageTop
+ PageBottom
- yprint
* 72) / 2;
1102 header
.ImagingBoundingBox
[2] = (PageTop
+ PageBottom
+ yprint
* 72) / 2;
1105 header
.ImagingBoundingBox
[0] = PageTop
- yprint
* 72;
1106 header
.ImagingBoundingBox
[2] = PageTop
;
1113 header
.ImagingBoundingBox
[1] = PageLeft
;
1114 header
.ImagingBoundingBox
[3] = PageLeft
+ xprint
* 72;
1117 header
.ImagingBoundingBox
[1] = (PageRight
+ PageLeft
- xprint
* 72) / 2;
1118 header
.ImagingBoundingBox
[3] = (PageRight
+ PageLeft
+ xprint
* 72) / 2;
1121 header
.ImagingBoundingBox
[1] = PageRight
- xprint
* 72;
1122 header
.ImagingBoundingBox
[3] = PageRight
;
1128 switch (header
.cupsColorOrder
)
1131 header
.cupsBytesPerLine
= (header
.cupsBitsPerPixel
*
1132 header
.cupsWidth
+ 7) / 8;
1136 case CUPS_ORDER_BANDED
:
1137 if (header
.cupsColorSpace
== CUPS_CSPACE_KCMYcm
&&
1138 header
.cupsBitsPerColor
> 1)
1139 header
.cupsBytesPerLine
= (header
.cupsBitsPerPixel
*
1140 header
.cupsWidth
+ 7) / 8 * 4;
1142 header
.cupsBytesPerLine
= (header
.cupsBitsPerPixel
*
1143 header
.cupsWidth
+ 7) / 8 *
1144 Planes
[header
.cupsColorSpace
];
1148 case CUPS_ORDER_PLANAR
:
1149 header
.cupsBytesPerLine
= (header
.cupsBitsPerPixel
*
1150 header
.cupsWidth
+ 7) / 8;
1151 num_planes
= Planes
[header
.cupsColorSpace
];
1155 if (header
.cupsBitsPerColor
>= 8)
1156 zoom_type
= CUPS_IZOOM_NORMAL
;
1158 zoom_type
= CUPS_IZOOM_FAST
;
1161 * See if we need to collate, and if so how we need to do it...
1164 if (xpages
== 1 && ypages
== 1)
1167 slowcollate
= Collate
&& ppdFindOption(ppd
, "Collate") == NULL
;
1169 slowcopies
= ppd
->manual_copies
;
1173 if (Copies
> 1 && !slowcollate
&& !slowcopies
)
1175 header
.Collate
= (cups_bool_t
)Collate
;
1176 header
.NumCopies
= Copies
;
1181 header
.NumCopies
= 1;
1184 * Create the dithering lookup tables...
1188 OnPixels
[255] = 0xff;
1189 OffPixels
[0] = 0x00;
1190 OffPixels
[255] = 0xff;
1192 switch (header
.cupsBitsPerColor
)
1195 for (i
= 1; i
< 255; i
++)
1197 OnPixels
[i
] = 0x55 * (i
/ 85 + 1);
1198 OffPixels
[i
] = 0x55 * (i
/ 64);
1202 for (i
= 1; i
< 255; i
++)
1204 OnPixels
[i
] = 17 * (i
/ 17 + 1);
1205 OffPixels
[i
] = 17 * (i
/ 16);
1208 OnPixels
[255] = OffPixels
[255] = 0xff;
1213 * Output the pages...
1216 fprintf(stderr
, "DEBUG: cupsWidth = %d\n", header
.cupsWidth
);
1217 fprintf(stderr
, "DEBUG: cupsHeight = %d\n", header
.cupsHeight
);
1218 fprintf(stderr
, "DEBUG: cupsBitsPerColor = %d\n", header
.cupsBitsPerColor
);
1219 fprintf(stderr
, "DEBUG: cupsBitsPerPixel = %d\n", header
.cupsBitsPerPixel
);
1220 fprintf(stderr
, "DEBUG: cupsBytesPerLine = %d\n", header
.cupsBytesPerLine
);
1221 fprintf(stderr
, "DEBUG: cupsColorOrder = %d\n", header
.cupsColorOrder
);
1222 fprintf(stderr
, "DEBUG: cupsColorSpace = %d\n", header
.cupsColorSpace
);
1223 fprintf(stderr
, "DEBUG: img->colorspace = %d\n", img
->colorspace
);
1225 row
= malloc(2 * header
.cupsBytesPerLine
);
1226 ras
= cupsRasterOpen(1, CUPS_RASTER_WRITE
);
1227 blank
= img
->colorspace
< 0 ? 0 : ~0;
1229 for (i
= 0, page
= 1; i
< Copies
; i
++)
1230 for (xpage
= 0; xpage
< xpages
; xpage
++)
1231 for (ypage
= 0; ypage
< ypages
; ypage
++, page
++)
1233 fprintf(stderr
, "INFO: Formatting page %d...\n", page
);
1235 if (Orientation
& 1)
1237 x0
= img
->xsize
* ypage
/ ypages
;
1238 x1
= img
->xsize
* (ypage
+ 1) / ypages
- 1;
1239 y0
= img
->ysize
* xpage
/ xpages
;
1240 y1
= img
->ysize
* (xpage
+ 1) / xpages
- 1;
1242 xtemp
= header
.HWResolution
[0] * yprint
;
1243 ytemp
= header
.HWResolution
[1] * xprint
;
1247 x0
= img
->xsize
* xpage
/ xpages
;
1248 x1
= img
->xsize
* (xpage
+ 1) / xpages
- 1;
1249 y0
= img
->ysize
* ypage
/ ypages
;
1250 y1
= img
->ysize
* (ypage
+ 1) / ypages
- 1;
1252 xtemp
= header
.HWResolution
[0] * xprint
;
1253 ytemp
= header
.HWResolution
[1] * yprint
;
1256 cupsRasterWriteHeader2(ras
, &header
);
1258 for (plane
= 0; plane
< num_planes
; plane
++)
1261 * Initialize the image "zoom" engine...
1265 z
= cupsImageZoomNew(img
, x0
, y0
, x1
, y1
, -xtemp
, ytemp
,
1266 Orientation
& 1, zoom_type
);
1268 z
= cupsImageZoomNew(img
, x0
, y0
, x1
, y1
, xtemp
, ytemp
,
1269 Orientation
& 1, zoom_type
);
1272 * Write leading blank space as needed...
1275 if (header
.cupsHeight
> z
->ysize
&& YPosition
<= 0)
1277 memset(row
, blank
, header
.cupsBytesPerLine
);
1279 y
= header
.cupsHeight
- z
->ysize
;
1285 if (cupsRasterWritePixels(ras
, row
, header
.cupsBytesPerLine
) <
1286 header
.cupsBytesPerLine
)
1288 fputs("ERROR: Unable to write raster data to driver!\n", stderr
);
1289 cupsImageClose(img
);
1296 * Then write image data...
1299 for (y
= z
->ysize
, yerr0
= 0, yerr1
= z
->ysize
, iy
= 0, last_iy
= -2;
1305 if (zoom_type
!= CUPS_IZOOM_FAST
&& (iy
- last_iy
) > 1)
1306 cupsImageZoomFill(z
, iy
);
1308 cupsImageZoomFill(z
, iy
+ z
->yincr
);
1314 * Format this line of raster data for the printer...
1317 memset(row
, blank
, header
.cupsBytesPerLine
);
1319 r0
= z
->rows
[z
->row
];
1320 r1
= z
->rows
[1 - z
->row
];
1322 switch (header
.cupsColorSpace
)
1324 case CUPS_CSPACE_W
:
1325 format_W(&header
, row
, y
, plane
, z
->xsize
, z
->ysize
,
1326 yerr0
, yerr1
, r0
, r1
);
1329 case CUPS_CSPACE_RGB
:
1330 format_RGB(&header
, row
, y
, plane
, z
->xsize
, z
->ysize
,
1331 yerr0
, yerr1
, r0
, r1
);
1333 case CUPS_CSPACE_RGBA
:
1334 case CUPS_CSPACE_RGBW
:
1335 format_RGBA(&header
, row
, y
, plane
, z
->xsize
, z
->ysize
,
1336 yerr0
, yerr1
, r0
, r1
);
1338 case CUPS_CSPACE_K
:
1339 case CUPS_CSPACE_WHITE
:
1340 case CUPS_CSPACE_GOLD
:
1341 case CUPS_CSPACE_SILVER
:
1342 format_K(&header
, row
, y
, plane
, z
->xsize
, z
->ysize
,
1343 yerr0
, yerr1
, r0
, r1
);
1345 case CUPS_CSPACE_CMY
:
1346 format_CMY(&header
, row
, y
, plane
, z
->xsize
, z
->ysize
,
1347 yerr0
, yerr1
, r0
, r1
);
1349 case CUPS_CSPACE_YMC
:
1350 format_YMC(&header
, row
, y
, plane
, z
->xsize
, z
->ysize
,
1351 yerr0
, yerr1
, r0
, r1
);
1353 case CUPS_CSPACE_CMYK
:
1354 format_CMYK(&header
, row
, y
, plane
, z
->xsize
, z
->ysize
,
1355 yerr0
, yerr1
, r0
, r1
);
1357 case CUPS_CSPACE_YMCK
:
1358 case CUPS_CSPACE_GMCK
:
1359 case CUPS_CSPACE_GMCS
:
1360 format_YMCK(&header
, row
, y
, plane
, z
->xsize
, z
->ysize
,
1361 yerr0
, yerr1
, r0
, r1
);
1363 case CUPS_CSPACE_KCMY
:
1364 format_KCMY(&header
, row
, y
, plane
, z
->xsize
, z
->ysize
,
1365 yerr0
, yerr1
, r0
, r1
);
1367 case CUPS_CSPACE_KCMYcm
:
1368 format_KCMYcm(&header
, row
, y
, plane
, z
->xsize
, z
->ysize
,
1369 yerr0
, yerr1
, r0
, r1
);
1374 * Write the raster data to the driver...
1377 if (cupsRasterWritePixels(ras
, row
, header
.cupsBytesPerLine
) <
1378 header
.cupsBytesPerLine
)
1380 fputs("ERROR: Unable to write raster data to driver!\n", stderr
);
1381 cupsImageClose(img
);
1386 * Compute the next scanline in the image...
1401 * Write trailing blank space as needed...
1404 if (header
.cupsHeight
> z
->ysize
&& YPosition
>= 0)
1406 memset(row
, blank
, header
.cupsBytesPerLine
);
1408 y
= header
.cupsHeight
- z
->ysize
;
1414 if (cupsRasterWritePixels(ras
, row
, header
.cupsBytesPerLine
) <
1415 header
.cupsBytesPerLine
)
1417 fputs("ERROR: Unable to write raster data to driver!\n", stderr
);
1418 cupsImageClose(img
);
1425 * Free memory used for the "zoom" engine...
1428 cupsImageZoomDelete(z
);
1437 cupsRasterClose(ras
);
1438 cupsImageClose(img
);
1446 * 'exec_code()' - Execute PostScript setpagedevice commands as appropriate.
1450 exec_code(cups_page_header2_t
*header
, /* I - Page header */
1451 const char *code
) /* I - Option choice to execute */
1453 char *ptr
, /* Pointer into name/value string */
1454 name
[255], /* Name of pagedevice entry */
1455 value
[1024]; /* Value of pagedevice entry */
1458 for (; *code
!= '\0';)
1461 * Search for the start of a dictionary name...
1464 while (*code
!= '/' && *code
!= '\0')
1475 for (ptr
= name
; isalnum(*code
& 255) && (ptr
- name
) < (sizeof(name
) - 1);)
1480 * The parse the value as needed...
1483 while (isspace(*code
& 255))
1492 * Read array of values...
1497 *code
!= ']' && *code
!= '\0' &&
1498 (ptr
- value
) < (sizeof(value
) - 1);)
1502 else if (*code
== '(')
1505 * Read string value...
1510 *code
!= ')' && *code
!= '\0' &&
1511 (ptr
- value
) < (sizeof(value
) - 1);)
1515 if (isdigit(*code
& 255))
1516 *ptr
++ = (char)strtol(code
, (char **)&code
, 8);
1525 else if (isdigit(*code
& 255) || *code
== '-')
1528 * Read single number...
1532 (isdigit(*code
& 255) || *code
== '-') &&
1533 (ptr
- value
) < (sizeof(value
) - 1);)
1540 * Read a single name...
1544 (isalnum(*code
& 255) || *code
== '_') &&
1545 (ptr
- value
) < (sizeof(value
) - 1);)
1551 * Assign the value as needed...
1554 if (!strcmp(name
, "MediaClass"))
1555 strlcpy(header
->MediaClass
, value
, sizeof(header
->MediaClass
));
1556 else if (!strcmp(name
, "MediaColor"))
1557 strlcpy(header
->MediaColor
, value
, sizeof(header
->MediaColor
));
1558 else if (!strcmp(name
, "MediaType"))
1559 strlcpy(header
->MediaType
, value
, sizeof(header
->MediaType
));
1560 else if (!strcmp(name
, "OutputType"))
1561 strlcpy(header
->OutputType
, value
, sizeof(header
->OutputType
));
1562 else if (!strcmp(name
, "AdvanceDistance"))
1563 header
->AdvanceDistance
= atoi(value
);
1564 else if (!strcmp(name
, "AdvanceMedia"))
1565 header
->AdvanceMedia
= atoi(value
);
1566 else if (!strcmp(name
, "Collate"))
1567 header
->Collate
= !strcmp(value
, "true");
1568 else if (!strcmp(name
, "CutMedia"))
1569 header
->CutMedia
= (cups_cut_t
)atoi(value
);
1570 else if (!strcmp(name
, "Duplex"))
1571 header
->Duplex
= !strcmp(value
, "true");
1572 else if (!strcmp(name
, "HWResolution"))
1573 sscanf(value
, "%d%d", header
->HWResolution
+ 0, header
->HWResolution
+ 1);
1574 else if (!strcmp(name
, "InsertSheet"))
1575 header
->InsertSheet
= !strcmp(value
, "true");
1576 else if (!strcmp(name
, "Jog"))
1577 header
->Jog
= atoi(value
);
1578 else if (!strcmp(name
, "LeadingEdge"))
1579 header
->LeadingEdge
= atoi(value
);
1580 else if (!strcmp(name
, "Margins"))
1581 sscanf(value
, "%d%d", header
->Margins
+ 0, header
->Margins
+ 1);
1582 else if (!strcmp(name
, "ManualFeed"))
1583 header
->ManualFeed
= !strcmp(value
, "true");
1584 else if (!strcmp(name
, "cupsMediaPosition") || /* Compatibility */
1585 !strcmp(name
, "MediaPosition"))
1586 header
->MediaPosition
= atoi(value
);
1587 else if (!strcmp(name
, "MediaWeight"))
1588 header
->MediaWeight
= atoi(value
);
1589 else if (!strcmp(name
, "MirrorPrint"))
1590 header
->MirrorPrint
= !strcmp(value
, "true");
1591 else if (!strcmp(name
, "NegativePrint"))
1592 header
->NegativePrint
= !strcmp(value
, "true");
1593 else if (!strcmp(name
, "Orientation"))
1594 header
->Orientation
= atoi(value
);
1595 else if (!strcmp(name
, "OutputFaceUp"))
1596 header
->OutputFaceUp
= !strcmp(value
, "true");
1597 else if (!strcmp(name
, "Separations"))
1598 header
->Separations
= !strcmp(value
, "true");
1599 else if (!strcmp(name
, "TraySwitch"))
1600 header
->TraySwitch
= !strcmp(value
, "true");
1601 else if (!strcmp(name
, "Tumble"))
1602 header
->Tumble
= !strcmp(value
, "true");
1603 else if (!strcmp(name
, "cupsMediaType"))
1604 header
->cupsMediaType
= atoi(value
);
1605 else if (!strcmp(name
, "cupsBitsPerColor"))
1606 header
->cupsBitsPerColor
= atoi(value
);
1607 else if (!strcmp(name
, "cupsColorOrder"))
1608 header
->cupsColorOrder
= (cups_order_t
)atoi(value
);
1609 else if (!strcmp(name
, "cupsColorSpace"))
1610 header
->cupsColorSpace
= (cups_cspace_t
)atoi(value
);
1611 else if (!strcmp(name
, "cupsCompression"))
1612 header
->cupsCompression
= atoi(value
);
1613 else if (!strcmp(name
, "cupsRowCount"))
1614 header
->cupsRowCount
= atoi(value
);
1615 else if (!strcmp(name
, "cupsRowFeed"))
1616 header
->cupsRowFeed
= atoi(value
);
1617 else if (!strcmp(name
, "cupsRowStep"))
1618 header
->cupsRowStep
= atoi(value
);
1624 * 'format_CMY()' - Convert image data to CMY.
1628 format_CMY(cups_page_header2_t
*header
, /* I - Page header */
1629 unsigned char *row
, /* IO - Bitmap data for device */
1630 int y
, /* I - Current row */
1631 int z
, /* I - Current plane */
1632 int xsize
, /* I - Width of image data */
1633 int ysize
, /* I - Height of image data */
1634 int yerr0
, /* I - Top Y error */
1635 int yerr1
, /* I - Bottom Y error */
1636 cups_ib_t
*r0
, /* I - Primary image data */
1637 cups_ib_t
*r1
) /* I - Image data for interpolation */
1639 cups_ib_t
*ptr
, /* Pointer into row */
1640 *cptr
, /* Pointer into cyan */
1641 *mptr
, /* Pointer into magenta */
1642 *yptr
, /* Pointer into yellow */
1643 bitmask
; /* Current mask for pixel */
1644 int bitoffset
; /* Current offset in line */
1645 int bandwidth
; /* Width of a color band */
1646 int x
, /* Current X coordinate on page */
1647 *dither
; /* Pointer into dither array */
1656 bitoffset
= header
->cupsBitsPerPixel
* ((header
->cupsWidth
- xsize
) / 2);
1659 bitoffset
= header
->cupsBitsPerPixel
* (header
->cupsWidth
- xsize
);
1663 ptr
= row
+ bitoffset
/ 8;
1664 bandwidth
= header
->cupsBytesPerLine
/ 3;
1666 switch (header
->cupsColorOrder
)
1668 case CUPS_ORDER_CHUNKED
:
1669 switch (header
->cupsBitsPerColor
)
1672 bitmask
= 64 >> (bitoffset
& 7);
1673 dither
= Floyd16x16
[y
& 15];
1675 for (x
= xsize
; x
> 0; x
--)
1677 if (*r0
++ > dither
[x
& 15])
1681 if (*r0
++ > dither
[x
& 15])
1685 if (*r0
++ > dither
[x
& 15])
1699 dither
= Floyd8x8
[y
& 7];
1701 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
1703 if ((r0
[0] & 63) > dither
[x
& 7])
1704 *ptr
^= (0x30 & OnPixels
[r0
[0]]);
1706 *ptr
^= (0x30 & OffPixels
[r0
[0]]);
1708 if ((r0
[1] & 63) > dither
[x
& 7])
1709 *ptr
^= (0x0c & OnPixels
[r0
[1]]);
1711 *ptr
^= (0x0c & OffPixels
[r0
[1]]);
1713 if ((r0
[2] & 63) > dither
[x
& 7])
1714 *ptr
++ ^= (0x03 & OnPixels
[r0
[2]]);
1716 *ptr
++ ^= (0x03 & OffPixels
[r0
[2]]);
1721 dither
= Floyd4x4
[y
& 3];
1723 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
1725 if ((r0
[0] & 15) > dither
[x
& 3])
1726 *ptr
++ ^= (0x0f & OnPixels
[r0
[0]]);
1728 *ptr
++ ^= (0x0f & OffPixels
[r0
[0]]);
1730 if ((r0
[1] & 15) > dither
[x
& 3])
1731 *ptr
^= (0xf0 & OnPixels
[r0
[1]]);
1733 *ptr
^= (0xf0 & OffPixels
[r0
[1]]);
1735 if ((r0
[2] & 15) > dither
[x
& 3])
1736 *ptr
++ ^= (0x0f & OnPixels
[r0
[2]]);
1738 *ptr
++ ^= (0x0f & OffPixels
[r0
[2]]);
1743 for (x
= xsize
* 3; x
> 0; x
--, r0
++, r1
++)
1747 *ptr
++ = (*r0
* yerr0
+ *r1
* yerr1
) / ysize
;
1752 case CUPS_ORDER_BANDED
:
1754 mptr
= ptr
+ bandwidth
;
1755 yptr
= ptr
+ 2 * bandwidth
;
1757 switch (header
->cupsBitsPerColor
)
1760 bitmask
= 0x80 >> (bitoffset
& 7);
1761 dither
= Floyd16x16
[y
& 15];
1763 for (x
= xsize
; x
> 0; x
--)
1765 if (*r0
++ > dither
[x
& 15])
1767 if (*r0
++ > dither
[x
& 15])
1769 if (*r0
++ > dither
[x
& 15])
1785 bitmask
= 0xc0 >> (bitoffset
& 7);
1786 dither
= Floyd8x8
[y
& 7];
1788 for (x
= xsize
; x
> 0; x
--)
1790 if ((*r0
& 63) > dither
[x
& 7])
1791 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
1793 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
1795 if ((*r0
& 63) > dither
[x
& 7])
1796 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
1798 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
1800 if ((*r0
& 63) > dither
[x
& 7])
1801 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
1803 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
1819 bitmask
= 0xf0 >> (bitoffset
& 7);
1820 dither
= Floyd4x4
[y
& 3];
1822 for (x
= xsize
; x
> 0; x
--)
1824 if ((*r0
& 15) > dither
[x
& 3])
1825 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
1827 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
1829 if ((*r0
& 15) > dither
[x
& 3])
1830 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
1832 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
1834 if ((*r0
& 15) > dither
[x
& 3])
1835 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
1837 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
1839 if (bitmask
== 0xf0)
1853 for (x
= xsize
; x
> 0; x
--, r0
+= 3, r1
+= 3)
1858 *cptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
1863 *mptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
1868 *yptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
1874 case CUPS_ORDER_PLANAR
:
1875 switch (header
->cupsBitsPerColor
)
1878 bitmask
= 0x80 >> (bitoffset
& 7);
1879 dither
= Floyd16x16
[y
& 15];
1884 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
1886 if (r0
[0] > dither
[x
& 15])
1900 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
1902 if (r0
[1] > dither
[x
& 15])
1916 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
1918 if (r0
[2] > dither
[x
& 15])
1934 bitmask
= 0xc0 >> (bitoffset
& 7);
1935 dither
= Floyd8x8
[y
& 7];
1938 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
1940 if ((*r0
& 63) > dither
[x
& 7])
1941 *ptr
^= (bitmask
& OnPixels
[*r0
]);
1943 *ptr
^= (bitmask
& OffPixels
[*r0
]);
1957 bitmask
= 0xf0 >> (bitoffset
& 7);
1958 dither
= Floyd4x4
[y
& 3];
1961 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
1963 if ((*r0
& 15) > dither
[x
& 3])
1964 *ptr
^= (bitmask
& OnPixels
[*r0
]);
1966 *ptr
^= (bitmask
& OffPixels
[*r0
]);
1968 if (bitmask
== 0xf0)
1983 for (x
= xsize
; x
> 0; x
--, r0
+= 3, r1
+= 3)
1988 *ptr
++ = (*r0
* yerr0
+ *r1
* yerr1
) / ysize
;
1998 * 'format_CMYK()' - Convert image data to CMYK.
2002 format_CMYK(cups_page_header2_t
*header
, /* I - Page header */
2003 unsigned char *row
, /* IO - Bitmap data for device */
2004 int y
, /* I - Current row */
2005 int z
, /* I - Current plane */
2006 int xsize
, /* I - Width of image data */
2007 int ysize
, /* I - Height of image data */
2008 int yerr0
, /* I - Top Y error */
2009 int yerr1
, /* I - Bottom Y error */
2010 cups_ib_t
*r0
, /* I - Primary image data */
2011 cups_ib_t
*r1
) /* I - Image data for interpolation */
2013 cups_ib_t
*ptr
, /* Pointer into row */
2014 *cptr
, /* Pointer into cyan */
2015 *mptr
, /* Pointer into magenta */
2016 *yptr
, /* Pointer into yellow */
2017 *kptr
, /* Pointer into black */
2018 bitmask
; /* Current mask for pixel */
2019 int bitoffset
; /* Current offset in line */
2020 int bandwidth
; /* Width of a color band */
2021 int x
, /* Current X coordinate on page */
2022 *dither
; /* Pointer into dither array */
2031 bitoffset
= header
->cupsBitsPerPixel
* ((header
->cupsWidth
- xsize
) / 2);
2034 bitoffset
= header
->cupsBitsPerPixel
* (header
->cupsWidth
- xsize
);
2038 ptr
= row
+ bitoffset
/ 8;
2039 bandwidth
= header
->cupsBytesPerLine
/ 4;
2041 switch (header
->cupsColorOrder
)
2043 case CUPS_ORDER_CHUNKED
:
2044 switch (header
->cupsBitsPerColor
)
2047 bitmask
= 128 >> (bitoffset
& 7);
2048 dither
= Floyd16x16
[y
& 15];
2050 for (x
= xsize
; x
> 0; x
--)
2052 if (*r0
++ > dither
[x
& 15])
2056 if (*r0
++ > dither
[x
& 15])
2060 if (*r0
++ > dither
[x
& 15])
2064 if (*r0
++ > dither
[x
& 15])
2078 dither
= Floyd8x8
[y
& 7];
2080 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
2082 if ((r0
[0] & 63) > dither
[x
& 7])
2083 *ptr
^= (0xc0 & OnPixels
[r0
[0]]);
2085 *ptr
^= (0xc0 & OffPixels
[r0
[0]]);
2087 if ((r0
[1] & 63) > dither
[x
& 7])
2088 *ptr
^= (0x30 & OnPixels
[r0
[1]]);
2090 *ptr
^= (0x30 & OffPixels
[r0
[1]]);
2092 if ((r0
[2] & 63) > dither
[x
& 7])
2093 *ptr
^= (0x0c & OnPixels
[r0
[2]]);
2095 *ptr
^= (0x0c & OffPixels
[r0
[2]]);
2097 if ((r0
[3] & 63) > dither
[x
& 7])
2098 *ptr
++ ^= (0x03 & OnPixels
[r0
[3]]);
2100 *ptr
++ ^= (0x03 & OffPixels
[r0
[3]]);
2105 dither
= Floyd4x4
[y
& 3];
2107 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
2109 if ((r0
[0] & 15) > dither
[x
& 3])
2110 *ptr
^= (0xf0 & OnPixels
[r0
[0]]);
2112 *ptr
^= (0xf0 & OffPixels
[r0
[0]]);
2114 if ((r0
[1] & 15) > dither
[x
& 3])
2115 *ptr
++ ^= (0x0f & OnPixels
[r0
[1]]);
2117 *ptr
++ ^= (0x0f & OffPixels
[r0
[1]]);
2119 if ((r0
[2] & 15) > dither
[x
& 3])
2120 *ptr
^= (0xf0 & OnPixels
[r0
[2]]);
2122 *ptr
^= (0xf0 & OffPixels
[r0
[2]]);
2124 if ((r0
[3] & 15) > dither
[x
& 3])
2125 *ptr
++ ^= (0x0f & OnPixels
[r0
[3]]);
2127 *ptr
++ ^= (0x0f & OffPixels
[r0
[3]]);
2132 for (x
= xsize
* 4; x
> 0; x
--, r0
++, r1
++)
2136 *ptr
++ = (*r0
* yerr0
+ *r1
* yerr1
) / ysize
;
2141 case CUPS_ORDER_BANDED
:
2143 mptr
= ptr
+ bandwidth
;
2144 yptr
= ptr
+ 2 * bandwidth
;
2145 kptr
= ptr
+ 3 * bandwidth
;
2147 switch (header
->cupsBitsPerColor
)
2150 bitmask
= 0x80 >> (bitoffset
& 7);
2151 dither
= Floyd16x16
[y
& 15];
2153 for (x
= xsize
; x
> 0; x
--)
2155 if (*r0
++ > dither
[x
& 15])
2157 if (*r0
++ > dither
[x
& 15])
2159 if (*r0
++ > dither
[x
& 15])
2161 if (*r0
++ > dither
[x
& 15])
2178 bitmask
= 0xc0 >> (bitoffset
& 7);
2179 dither
= Floyd8x8
[y
& 7];
2181 for (x
= xsize
; x
> 0; x
--)
2183 if ((*r0
& 63) > dither
[x
& 7])
2184 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
2186 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
2188 if ((*r0
& 63) > dither
[x
& 7])
2189 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
2191 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
2193 if ((*r0
& 63) > dither
[x
& 7])
2194 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
2196 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
2198 if ((*r0
& 63) > dither
[x
& 7])
2199 *kptr
^= (bitmask
& OnPixels
[*r0
++]);
2201 *kptr
^= (bitmask
& OffPixels
[*r0
++]);
2218 bitmask
= 0xf0 >> (bitoffset
& 7);
2219 dither
= Floyd4x4
[y
& 3];
2221 for (x
= xsize
; x
> 0; x
--)
2223 if ((*r0
& 15) > dither
[x
& 3])
2224 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
2226 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
2228 if ((*r0
& 15) > dither
[x
& 3])
2229 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
2231 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
2233 if ((*r0
& 15) > dither
[x
& 3])
2234 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
2236 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
2238 if ((*r0
& 15) > dither
[x
& 3])
2239 *kptr
^= (bitmask
& OnPixels
[*r0
++]);
2241 *kptr
^= (bitmask
& OffPixels
[*r0
++]);
2243 if (bitmask
== 0xf0)
2258 for (x
= xsize
; x
> 0; x
--, r0
+= 4, r1
+= 4)
2263 *cptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
2268 *mptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
2273 *yptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
2278 *kptr
++ = (r0
[3] * yerr0
+ r1
[3] * yerr1
) / ysize
;
2284 case CUPS_ORDER_PLANAR
:
2285 switch (header
->cupsBitsPerColor
)
2288 bitmask
= 0x80 >> (bitoffset
& 7);
2289 dither
= Floyd16x16
[y
& 15];
2292 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
2294 if (*r0
> dither
[x
& 15])
2308 bitmask
= 0xc0 >> (bitoffset
& 7);
2309 dither
= Floyd8x8
[y
& 7];
2312 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
2314 if ((*r0
& 63) > dither
[x
& 7])
2315 *ptr
^= (bitmask
& OnPixels
[*r0
]);
2317 *ptr
^= (bitmask
& OffPixels
[*r0
]);
2331 bitmask
= 0xf0 >> (bitoffset
& 7);
2332 dither
= Floyd4x4
[y
& 3];
2335 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
2337 if ((*r0
& 15) > dither
[x
& 3])
2338 *ptr
^= (bitmask
& OnPixels
[*r0
]);
2340 *ptr
^= (bitmask
& OffPixels
[*r0
]);
2342 if (bitmask
== 0xf0)
2357 for (x
= xsize
; x
> 0; x
--, r0
+= 4, r1
+= 4)
2362 *ptr
++ = (*r0
* yerr0
+ *r1
* yerr1
) / ysize
;
2372 * 'format_K()' - Convert image data to black.
2376 format_K(cups_page_header2_t
*header
, /* I - Page header */
2377 unsigned char *row
, /* IO - Bitmap data for device */
2378 int y
, /* I - Current row */
2379 int z
, /* I - Current plane */
2380 int xsize
, /* I - Width of image data */
2381 int ysize
, /* I - Height of image data */
2382 int yerr0
, /* I - Top Y error */
2383 int yerr1
, /* I - Bottom Y error */
2384 cups_ib_t
*r0
, /* I - Primary image data */
2385 cups_ib_t
*r1
) /* I - Image data for interpolation */
2387 cups_ib_t
*ptr
, /* Pointer into row */
2388 bitmask
; /* Current mask for pixel */
2389 int bitoffset
; /* Current offset in line */
2390 int x
, /* Current X coordinate on page */
2391 *dither
; /* Pointer into dither array */
2402 bitoffset
= header
->cupsBitsPerPixel
* ((header
->cupsWidth
- xsize
) / 2);
2405 bitoffset
= header
->cupsBitsPerPixel
* (header
->cupsWidth
- xsize
);
2409 ptr
= row
+ bitoffset
/ 8;
2411 switch (header
->cupsBitsPerColor
)
2414 bitmask
= 0x80 >> (bitoffset
& 7);
2415 dither
= Floyd16x16
[y
& 15];
2417 for (x
= xsize
; x
> 0; x
--)
2419 if (*r0
++ > dither
[x
& 15])
2433 bitmask
= 0xc0 >> (bitoffset
& 7);
2434 dither
= Floyd8x8
[y
& 7];
2436 for (x
= xsize
; x
> 0; x
--)
2438 if ((*r0
& 63) > dither
[x
& 7])
2439 *ptr
^= (bitmask
& OnPixels
[*r0
++]);
2441 *ptr
^= (bitmask
& OffPixels
[*r0
++]);
2455 bitmask
= 0xf0 >> (bitoffset
& 7);
2456 dither
= Floyd4x4
[y
& 3];
2458 for (x
= xsize
; x
> 0; x
--)
2460 if ((*r0
& 15) > dither
[x
& 3])
2461 *ptr
^= (bitmask
& OnPixels
[*r0
++]);
2463 *ptr
^= (bitmask
& OffPixels
[*r0
++]);
2465 if (bitmask
== 0xf0)
2477 for (x
= xsize
; x
> 0; x
--, r0
++, r1
++)
2482 *ptr
++ = (*r0
* yerr0
+ *r1
* yerr1
) / ysize
;
2490 * 'format_KCMY()' - Convert image data to KCMY.
2494 format_KCMY(cups_page_header2_t
*header
, /* I - Page header */
2495 unsigned char *row
, /* IO - Bitmap data for device */
2496 int y
, /* I - Current row */
2497 int z
, /* I - Current plane */
2498 int xsize
, /* I - Width of image data */
2499 int ysize
, /* I - Height of image data */
2500 int yerr0
, /* I - Top Y error */
2501 int yerr1
, /* I - Bottom Y error */
2502 cups_ib_t
*r0
, /* I - Primary image data */
2503 cups_ib_t
*r1
) /* I - Image data for interpolation */
2505 cups_ib_t
*ptr
, /* Pointer into row */
2506 *cptr
, /* Pointer into cyan */
2507 *mptr
, /* Pointer into magenta */
2508 *yptr
, /* Pointer into yellow */
2509 *kptr
, /* Pointer into black */
2510 bitmask
; /* Current mask for pixel */
2511 int bitoffset
; /* Current offset in line */
2512 int bandwidth
; /* Width of a color band */
2513 int x
, /* Current X coordinate on page */
2514 *dither
; /* Pointer into dither array */
2523 bitoffset
= header
->cupsBitsPerPixel
* ((header
->cupsWidth
- xsize
) / 2);
2526 bitoffset
= header
->cupsBitsPerPixel
* (header
->cupsWidth
- xsize
);
2530 ptr
= row
+ bitoffset
/ 8;
2531 bandwidth
= header
->cupsBytesPerLine
/ 4;
2533 switch (header
->cupsColorOrder
)
2535 case CUPS_ORDER_CHUNKED
:
2536 switch (header
->cupsBitsPerColor
)
2539 bitmask
= 128 >> (bitoffset
& 7);
2540 dither
= Floyd16x16
[y
& 15];
2542 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
2544 if (r0
[3] > dither
[x
& 15])
2548 if (r0
[0] > dither
[x
& 15])
2552 if (r0
[1] > dither
[x
& 15])
2556 if (r0
[2] > dither
[x
& 15])
2570 dither
= Floyd8x8
[y
& 7];
2572 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
2574 if ((r0
[3] & 63) > dither
[x
& 7])
2575 *ptr
^= (0xc0 & OnPixels
[r0
[3]]);
2577 *ptr
^= (0xc0 & OffPixels
[r0
[3]]);
2579 if ((r0
[0] & 63) > dither
[x
& 7])
2580 *ptr
^= (0x30 & OnPixels
[r0
[0]]);
2582 *ptr
^= (0x30 & OffPixels
[r0
[0]]);
2584 if ((r0
[1] & 63) > dither
[x
& 7])
2585 *ptr
^= (0x0c & OnPixels
[r0
[1]]);
2587 *ptr
^= (0x0c & OffPixels
[r0
[1]]);
2589 if ((r0
[2] & 63) > dither
[x
& 7])
2590 *ptr
++ ^= (0x03 & OnPixels
[r0
[2]]);
2592 *ptr
++ ^= (0x03 & OffPixels
[r0
[2]]);
2597 dither
= Floyd4x4
[y
& 3];
2599 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
2601 if ((r0
[3] & 15) > dither
[x
& 3])
2602 *ptr
^= (0xf0 & OnPixels
[r0
[3]]);
2604 *ptr
^= (0xf0 & OffPixels
[r0
[3]]);
2606 if ((r0
[0] & 15) > dither
[x
& 3])
2607 *ptr
++ ^= (0x0f & OnPixels
[r0
[0]]);
2609 *ptr
++ ^= (0x0f & OffPixels
[r0
[0]]);
2611 if ((r0
[1] & 15) > dither
[x
& 3])
2612 *ptr
^= (0xf0 & OnPixels
[r0
[1]]);
2614 *ptr
^= (0xf0 & OffPixels
[r0
[1]]);
2616 if ((r0
[2] & 15) > dither
[x
& 3])
2617 *ptr
++ ^= (0x0f & OnPixels
[r0
[2]]);
2619 *ptr
++ ^= (0x0f & OffPixels
[r0
[2]]);
2624 for (x
= xsize
; x
> 0; x
--, r0
+= 4, r1
+= 4)
2629 *ptr
++ = (r0
[3] * yerr0
+ r1
[3] * yerr1
) / ysize
;
2634 *ptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
2639 *ptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
2644 *ptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
2650 case CUPS_ORDER_BANDED
:
2652 cptr
= ptr
+ bandwidth
;
2653 mptr
= ptr
+ 2 * bandwidth
;
2654 yptr
= ptr
+ 3 * bandwidth
;
2656 switch (header
->cupsBitsPerColor
)
2659 bitmask
= 0x80 >> (bitoffset
& 7);
2660 dither
= Floyd16x16
[y
& 15];
2662 for (x
= xsize
; x
> 0; x
--)
2664 if (*r0
++ > dither
[x
& 15])
2666 if (*r0
++ > dither
[x
& 15])
2668 if (*r0
++ > dither
[x
& 15])
2670 if (*r0
++ > dither
[x
& 15])
2687 bitmask
= 0xc0 >> (bitoffset
& 7);
2688 dither
= Floyd8x8
[y
& 7];
2690 for (x
= xsize
; x
> 0; x
--)
2692 if ((*r0
& 63) > dither
[x
& 7])
2693 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
2695 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
2697 if ((*r0
& 63) > dither
[x
& 7])
2698 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
2700 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
2702 if ((*r0
& 63) > dither
[x
& 7])
2703 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
2705 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
2707 if ((*r0
& 63) > dither
[x
& 7])
2708 *kptr
^= (bitmask
& OnPixels
[*r0
++]);
2710 *kptr
^= (bitmask
& OffPixels
[*r0
++]);
2727 bitmask
= 0xf0 >> (bitoffset
& 7);
2728 dither
= Floyd4x4
[y
& 3];
2730 for (x
= xsize
; x
> 0; x
--)
2732 if ((*r0
& 15) > dither
[x
& 3])
2733 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
2735 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
2737 if ((*r0
& 15) > dither
[x
& 3])
2738 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
2740 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
2742 if ((*r0
& 15) > dither
[x
& 3])
2743 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
2745 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
2747 if ((*r0
& 15) > dither
[x
& 3])
2748 *kptr
^= (bitmask
& OnPixels
[*r0
++]);
2750 *kptr
^= (bitmask
& OffPixels
[*r0
++]);
2752 if (bitmask
== 0xf0)
2767 for (x
= xsize
; x
> 0; x
--, r0
+= 4, r1
+= 4)
2772 *cptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
2777 *mptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
2782 *yptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
2787 *kptr
++ = (r0
[3] * yerr0
+ r1
[3] * yerr1
) / ysize
;
2793 case CUPS_ORDER_PLANAR
:
2794 switch (header
->cupsBitsPerColor
)
2797 bitmask
= 0x80 >> (bitoffset
& 7);
2798 dither
= Floyd16x16
[y
& 15];
2804 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
2806 if (*r0
> dither
[x
& 15])
2820 bitmask
= 0xc0 >> (bitoffset
& 7);
2821 dither
= Floyd8x8
[y
& 7];
2827 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
2829 if ((*r0
& 63) > dither
[x
& 7])
2830 *ptr
^= (bitmask
& OnPixels
[*r0
]);
2832 *ptr
^= (bitmask
& OffPixels
[*r0
]);
2846 bitmask
= 0xf0 >> (bitoffset
& 7);
2847 dither
= Floyd4x4
[y
& 3];
2853 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
2855 if ((*r0
& 15) > dither
[x
& 3])
2856 *ptr
^= (bitmask
& OnPixels
[*r0
]);
2858 *ptr
^= (bitmask
& OffPixels
[*r0
]);
2860 if (bitmask
== 0xf0)
2883 for (x
= xsize
; x
> 0; x
--, r0
+= 4, r1
+= 4)
2888 *ptr
++ = (*r0
* yerr0
+ *r1
* yerr1
) / ysize
;
2898 * 'format_KCMYcm()' - Convert image data to KCMYcm.
2902 format_KCMYcm(cups_page_header2_t
*header
,/* I - Page header */
2903 unsigned char *row
, /* IO - Bitmap data for device */
2904 int y
, /* I - Current row */
2905 int z
, /* I - Current plane */
2906 int xsize
,/* I - Width of image data */
2907 int ysize
,/* I - Height of image data */
2908 int yerr0
,/* I - Top Y error */
2909 int yerr1
,/* I - Bottom Y error */
2910 cups_ib_t
*r0
, /* I - Primary image data */
2911 cups_ib_t
*r1
) /* I - Image data for interpolation */
2913 int pc
, pm
, py
, pk
; /* Cyan, magenta, yellow, and black values */
2914 cups_ib_t
*ptr
, /* Pointer into row */
2915 *cptr
, /* Pointer into cyan */
2916 *mptr
, /* Pointer into magenta */
2917 *yptr
, /* Pointer into yellow */
2918 *kptr
, /* Pointer into black */
2919 *lcptr
, /* Pointer into light cyan */
2920 *lmptr
, /* Pointer into light magenta */
2921 bitmask
; /* Current mask for pixel */
2922 int bitoffset
; /* Current offset in line */
2923 int bandwidth
; /* Width of a color band */
2924 int x
, /* Current X coordinate on page */
2925 *dither
; /* Pointer into dither array */
2934 bitoffset
= header
->cupsBitsPerPixel
* ((header
->cupsWidth
- xsize
) / 2);
2937 bitoffset
= header
->cupsBitsPerPixel
* (header
->cupsWidth
- xsize
);
2941 ptr
= row
+ bitoffset
/ 8;
2942 if (header
->cupsBitsPerColor
== 1)
2943 bandwidth
= header
->cupsBytesPerLine
/ 6;
2945 bandwidth
= header
->cupsBytesPerLine
/ 4;
2947 switch (header
->cupsColorOrder
)
2949 case CUPS_ORDER_CHUNKED
:
2950 switch (header
->cupsBitsPerColor
)
2953 dither
= Floyd16x16
[y
& 15];
2955 for (x
= xsize
; x
> 0; x
--)
2957 pc
= *r0
++ > dither
[x
& 15];
2958 pm
= *r0
++ > dither
[x
& 15];
2959 py
= *r0
++ > dither
[x
& 15];
2960 pk
= *r0
++ > dither
[x
& 15];
2963 *ptr
++ ^= 32; /* Black */
2965 *ptr
++ ^= 17; /* Blue (cyan + light magenta) */
2967 *ptr
++ ^= 6; /* Green (light cyan + yellow) */
2969 *ptr
++ ^= 12; /* Red (magenta + yellow) */
2980 for (x
= xsize
; x
> 0; x
--, r0
+= 4, r1
+= 4)
2985 *ptr
++ = (r0
[3] * yerr0
+ r1
[3] * yerr1
) / ysize
;
2990 *ptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
2995 *ptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
3000 *ptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
3006 case CUPS_ORDER_BANDED
:
3008 cptr
= ptr
+ bandwidth
;
3009 mptr
= ptr
+ 2 * bandwidth
;
3010 yptr
= ptr
+ 3 * bandwidth
;
3011 lcptr
= ptr
+ 4 * bandwidth
;
3012 lmptr
= ptr
+ 5 * bandwidth
;
3014 switch (header
->cupsBitsPerColor
)
3017 bitmask
= 0x80 >> (bitoffset
& 7);
3018 dither
= Floyd16x16
[y
& 15];
3020 for (x
= xsize
; x
> 0; x
--)
3022 pc
= *r0
++ > dither
[x
& 15];
3023 pm
= *r0
++ > dither
[x
& 15];
3024 py
= *r0
++ > dither
[x
& 15];
3025 pk
= *r0
++ > dither
[x
& 15];
3028 *kptr
^= bitmask
; /* Black */
3031 *cptr
^= bitmask
; /* Blue (cyan + light magenta) */
3036 *lcptr
^= bitmask
; /* Green (light cyan + yellow) */
3041 *mptr
^= bitmask
; /* Red (magenta + yellow) */
3067 for (x
= xsize
; x
> 0; x
--, r0
+= 4, r1
+= 4)
3072 *cptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
3077 *mptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
3082 *yptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
3087 *kptr
++ = (r0
[3] * yerr0
+ r1
[3] * yerr1
) / ysize
;
3093 case CUPS_ORDER_PLANAR
:
3094 switch (header
->cupsBitsPerColor
)
3097 bitmask
= 0x80 >> (bitoffset
& 7);
3098 dither
= Floyd16x16
[y
& 15];
3103 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
3105 if (r0
[3] > dither
[x
& 15])
3119 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
3121 if (r0
[0] > dither
[x
& 15] &&
3122 r0
[2] < dither
[x
& 15])
3136 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
3138 if (r0
[1] > dither
[x
& 15] &&
3139 (r0
[0] < dither
[x
& 15] ||
3140 r0
[2] > dither
[x
& 15]))
3154 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
3156 if (r0
[2] > dither
[x
& 15] &&
3157 (r0
[0] < dither
[x
& 15] ||
3158 r0
[1] < dither
[x
& 15]))
3172 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
3174 if (r0
[0] > dither
[x
& 15] &&
3175 r0
[2] > dither
[x
& 15])
3189 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
3191 if (r0
[0] > dither
[x
& 15] &&
3192 r0
[1] > dither
[x
& 15] &&
3193 r0
[2] < dither
[x
& 15])
3220 for (x
= xsize
; x
> 0; x
--, r0
+= 4, r1
+= 4)
3225 *ptr
++ = (*r0
* yerr0
+ *r1
* yerr1
) / ysize
;
3235 * 'format_RGBA()' - Convert image data to RGBA/RGBW.
3239 format_RGBA(cups_page_header2_t
*header
, /* I - Page header */
3240 unsigned char *row
, /* IO - Bitmap data for device */
3241 int y
, /* I - Current row */
3242 int z
, /* I - Current plane */
3243 int xsize
, /* I - Width of image data */
3244 int ysize
, /* I - Height of image data */
3245 int yerr0
, /* I - Top Y error */
3246 int yerr1
, /* I - Bottom Y error */
3247 cups_ib_t
*r0
, /* I - Primary image data */
3248 cups_ib_t
*r1
) /* I - Image data for interpolation */
3250 cups_ib_t
*ptr
, /* Pointer into row */
3251 *cptr
, /* Pointer into cyan */
3252 *mptr
, /* Pointer into magenta */
3253 *yptr
, /* Pointer into yellow */
3254 bitmask
; /* Current mask for pixel */
3255 int bitoffset
; /* Current offset in line */
3256 int bandwidth
; /* Width of a color band */
3257 int x
, /* Current X coordinate on page */
3258 *dither
; /* Pointer into dither array */
3267 bitoffset
= header
->cupsBitsPerPixel
* ((header
->cupsWidth
- xsize
) / 2);
3270 bitoffset
= header
->cupsBitsPerPixel
* (header
->cupsWidth
- xsize
);
3274 ptr
= row
+ bitoffset
/ 8;
3275 bandwidth
= header
->cupsBytesPerLine
/ 4;
3277 switch (header
->cupsColorOrder
)
3279 case CUPS_ORDER_CHUNKED
:
3280 switch (header
->cupsBitsPerColor
)
3283 bitmask
= 128 >> (bitoffset
& 7);
3284 dither
= Floyd16x16
[y
& 15];
3286 for (x
= xsize
; x
> 0; x
--)
3288 if (*r0
++ > dither
[x
& 15])
3292 if (*r0
++ > dither
[x
& 15])
3296 if (*r0
++ > dither
[x
& 15])
3313 dither
= Floyd8x8
[y
& 7];
3315 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3317 if ((r0
[0] & 63) > dither
[x
& 7])
3318 *ptr
^= (0xc0 & OnPixels
[r0
[0]]);
3320 *ptr
^= (0xc0 & OffPixels
[r0
[0]]);
3322 if ((r0
[1] & 63) > dither
[x
& 7])
3323 *ptr
^= (0x30 & OnPixels
[r0
[1]]);
3325 *ptr
^= (0x30 & OffPixels
[r0
[1]]);
3327 if ((r0
[2] & 63) > dither
[x
& 7])
3328 *ptr
^= (0x0c & OnPixels
[r0
[2]]);
3330 *ptr
^= (0x0c & OffPixels
[r0
[2]]);
3337 dither
= Floyd4x4
[y
& 3];
3339 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3341 if ((r0
[0] & 15) > dither
[x
& 3])
3342 *ptr
^= (0xf0 & OnPixels
[r0
[0]]);
3344 *ptr
^= (0xf0 & OffPixels
[r0
[0]]);
3346 if ((r0
[1] & 15) > dither
[x
& 3])
3347 *ptr
++ ^= (0x0f & OnPixels
[r0
[1]]);
3349 *ptr
++ ^= (0x0f & OffPixels
[r0
[1]]);
3351 if ((r0
[2] & 15) > dither
[x
& 3])
3352 *ptr
^= (0xf0 & OnPixels
[r0
[2]]);
3354 *ptr
^= (0xf0 & OffPixels
[r0
[2]]);
3361 for (x
= xsize
; x
> 0; x
--, r0
+= 3, r1
+= 3)
3366 *ptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
3371 *ptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
3376 *ptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
3384 case CUPS_ORDER_BANDED
:
3386 mptr
= ptr
+ bandwidth
;
3387 yptr
= ptr
+ 2 * bandwidth
;
3389 memset(ptr
+ 3 * bandwidth
, 255, bandwidth
);
3391 switch (header
->cupsBitsPerColor
)
3394 bitmask
= 0x80 >> (bitoffset
& 7);
3395 dither
= Floyd16x16
[y
& 15];
3397 for (x
= xsize
; x
> 0; x
--)
3399 if (*r0
++ > dither
[x
& 15])
3401 if (*r0
++ > dither
[x
& 15])
3403 if (*r0
++ > dither
[x
& 15])
3419 bitmask
= 0xc0 >> (bitoffset
& 7);
3420 dither
= Floyd8x8
[y
& 7];
3422 for (x
= xsize
; x
> 0; x
--)
3424 if ((*r0
& 63) > dither
[x
& 7])
3425 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
3427 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
3429 if ((*r0
& 63) > dither
[x
& 7])
3430 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
3432 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
3434 if ((*r0
& 63) > dither
[x
& 7])
3435 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
3437 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
3453 bitmask
= 0xf0 >> (bitoffset
& 7);
3454 dither
= Floyd4x4
[y
& 3];
3456 for (x
= xsize
; x
> 0; x
--)
3458 if ((*r0
& 15) > dither
[x
& 3])
3459 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
3461 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
3463 if ((*r0
& 15) > dither
[x
& 3])
3464 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
3466 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
3468 if ((*r0
& 15) > dither
[x
& 3])
3469 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
3471 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
3473 if (bitmask
== 0xf0)
3487 for (x
= xsize
; x
> 0; x
--, r0
+= 3, r1
+= 3)
3492 *cptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
3497 *mptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
3502 *yptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
3508 case CUPS_ORDER_PLANAR
:
3511 memset(row
, 255, header
->cupsBytesPerLine
);
3515 switch (header
->cupsBitsPerColor
)
3518 bitmask
= 0x80 >> (bitoffset
& 7);
3519 dither
= Floyd16x16
[y
& 15];
3524 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3526 if (r0
[0] > dither
[x
& 15])
3540 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3542 if (r0
[1] > dither
[x
& 15])
3556 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3558 if (r0
[2] > dither
[x
& 15])
3574 bitmask
= 0xc0 >> (bitoffset
& 7);
3575 dither
= Floyd8x8
[y
& 7];
3578 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3580 if ((*r0
& 63) > dither
[x
& 7])
3581 *ptr
^= (bitmask
& OnPixels
[*r0
]);
3583 *ptr
^= (bitmask
& OffPixels
[*r0
]);
3597 bitmask
= 0xf0 >> (bitoffset
& 7);
3598 dither
= Floyd4x4
[y
& 3];
3601 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3603 if ((*r0
& 15) > dither
[x
& 3])
3604 *ptr
^= (bitmask
& OnPixels
[*r0
]);
3606 *ptr
^= (bitmask
& OffPixels
[*r0
]);
3608 if (bitmask
== 0xf0)
3623 for (x
= xsize
; x
> 0; x
--, r0
+= 3, r1
+= 3)
3628 *ptr
++ = (*r0
* yerr0
+ *r1
* yerr1
) / ysize
;
3638 * 'format_W()' - Convert image data to luminance.
3642 format_W(cups_page_header2_t
*header
, /* I - Page header */
3643 unsigned char *row
, /* IO - Bitmap data for device */
3644 int y
, /* I - Current row */
3645 int z
, /* I - Current plane */
3646 int xsize
, /* I - Width of image data */
3647 int ysize
, /* I - Height of image data */
3648 int yerr0
, /* I - Top Y error */
3649 int yerr1
, /* I - Bottom Y error */
3650 cups_ib_t
*r0
, /* I - Primary image data */
3651 cups_ib_t
*r1
) /* I - Image data for interpolation */
3653 cups_ib_t
*ptr
, /* Pointer into row */
3654 bitmask
; /* Current mask for pixel */
3655 int bitoffset
; /* Current offset in line */
3656 int x
, /* Current X coordinate on page */
3657 *dither
; /* Pointer into dither array */
3668 bitoffset
= header
->cupsBitsPerPixel
* ((header
->cupsWidth
- xsize
) / 2);
3671 bitoffset
= header
->cupsBitsPerPixel
* (header
->cupsWidth
- xsize
);
3675 ptr
= row
+ bitoffset
/ 8;
3677 switch (header
->cupsBitsPerColor
)
3680 bitmask
= 0x80 >> (bitoffset
& 7);
3681 dither
= Floyd16x16
[y
& 15];
3683 for (x
= xsize
; x
> 0; x
--)
3685 if (*r0
++ > dither
[x
& 15])
3699 bitmask
= 0xc0 >> (bitoffset
& 7);
3700 dither
= Floyd8x8
[y
& 7];
3702 for (x
= xsize
; x
> 0; x
--)
3704 if ((*r0
& 63) > dither
[x
& 7])
3705 *ptr
^= (bitmask
& OnPixels
[*r0
++]);
3707 *ptr
^= (bitmask
& OffPixels
[*r0
++]);
3721 bitmask
= 0xf0 >> (bitoffset
& 7);
3722 dither
= Floyd4x4
[y
& 3];
3724 for (x
= xsize
; x
> 0; x
--)
3726 if ((*r0
& 15) > dither
[x
& 3])
3727 *ptr
^= (bitmask
& OnPixels
[*r0
++]);
3729 *ptr
^= (bitmask
& OffPixels
[*r0
++]);
3731 if (bitmask
== 0xf0)
3743 for (x
= xsize
; x
> 0; x
--, r0
++, r1
++)
3748 *ptr
++ = (*r0
* yerr0
+ *r1
* yerr1
) / ysize
;
3756 * 'format_YMC()' - Convert image data to YMC.
3760 format_YMC(cups_page_header2_t
*header
, /* I - Page header */
3761 unsigned char *row
, /* IO - Bitmap data for device */
3762 int y
, /* I - Current row */
3763 int z
, /* I - Current plane */
3764 int xsize
, /* I - Width of image data */
3765 int ysize
, /* I - Height of image data */
3766 int yerr0
, /* I - Top Y error */
3767 int yerr1
, /* I - Bottom Y error */
3768 cups_ib_t
*r0
, /* I - Primary image data */
3769 cups_ib_t
*r1
) /* I - Image data for interpolation */
3771 cups_ib_t
*ptr
, /* Pointer into row */
3772 *cptr
, /* Pointer into cyan */
3773 *mptr
, /* Pointer into magenta */
3774 *yptr
, /* Pointer into yellow */
3775 bitmask
; /* Current mask for pixel */
3776 int bitoffset
; /* Current offset in line */
3777 int bandwidth
; /* Width of a color band */
3778 int x
, /* Current X coordinate on page */
3779 *dither
; /* Pointer into dither array */
3788 bitoffset
= header
->cupsBitsPerPixel
* ((header
->cupsWidth
- xsize
) / 2);
3791 bitoffset
= header
->cupsBitsPerPixel
* (header
->cupsWidth
- xsize
);
3795 ptr
= row
+ bitoffset
/ 8;
3796 bandwidth
= header
->cupsBytesPerLine
/ 3;
3798 switch (header
->cupsColorOrder
)
3800 case CUPS_ORDER_CHUNKED
:
3801 switch (header
->cupsBitsPerColor
)
3804 bitmask
= 64 >> (bitoffset
& 7);
3805 dither
= Floyd16x16
[y
& 15];
3807 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3809 if (r0
[2] > dither
[x
& 15])
3813 if (r0
[1] > dither
[x
& 15])
3817 if (r0
[0] > dither
[x
& 15])
3831 dither
= Floyd8x8
[y
& 7];
3833 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3835 if ((r0
[2] & 63) > dither
[x
& 7])
3836 *ptr
^= (0x30 & OnPixels
[r0
[2]]);
3838 *ptr
^= (0x30 & OffPixels
[r0
[2]]);
3840 if ((r0
[1] & 63) > dither
[x
& 7])
3841 *ptr
^= (0x0c & OnPixels
[r0
[1]]);
3843 *ptr
^= (0x0c & OffPixels
[r0
[1]]);
3845 if ((r0
[0] & 63) > dither
[x
& 7])
3846 *ptr
++ ^= (0x03 & OnPixels
[r0
[0]]);
3848 *ptr
++ ^= (0x03 & OffPixels
[r0
[0]]);
3853 dither
= Floyd4x4
[y
& 3];
3855 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3857 if ((r0
[2] & 15) > dither
[x
& 3])
3858 *ptr
++ ^= (0x0f & OnPixels
[r0
[2]]);
3860 *ptr
++ ^= (0x0f & OffPixels
[r0
[2]]);
3862 if ((r0
[1] & 15) > dither
[x
& 3])
3863 *ptr
^= (0xf0 & OnPixels
[r0
[1]]);
3865 *ptr
^= (0xf0 & OffPixels
[r0
[1]]);
3867 if ((r0
[0] & 15) > dither
[x
& 3])
3868 *ptr
++ ^= (0x0f & OnPixels
[r0
[0]]);
3870 *ptr
++ ^= (0x0f & OffPixels
[r0
[0]]);
3875 for (x
= xsize
; x
> 0; x
--, r0
+= 3, r1
+= 3)
3880 *ptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
3885 *ptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
3890 *ptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
3896 case CUPS_ORDER_BANDED
:
3898 mptr
= ptr
+ bandwidth
;
3899 cptr
= ptr
+ 2 * bandwidth
;
3901 switch (header
->cupsBitsPerColor
)
3904 bitmask
= 0x80 >> (bitoffset
& 7);
3905 dither
= Floyd16x16
[y
& 15];
3907 for (x
= xsize
; x
> 0; x
--)
3909 if (*r0
++ > dither
[x
& 15])
3911 if (*r0
++ > dither
[x
& 15])
3913 if (*r0
++ > dither
[x
& 15])
3929 bitmask
= 0xc0 >> (bitoffset
& 7);
3930 dither
= Floyd8x8
[y
& 7];
3932 for (x
= xsize
; x
> 0; x
--)
3934 if ((*r0
& 63) > dither
[x
& 7])
3935 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
3937 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
3939 if ((*r0
& 63) > dither
[x
& 7])
3940 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
3942 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
3944 if ((*r0
& 63) > dither
[x
& 7])
3945 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
3947 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
3963 bitmask
= 0xf0 >> (bitoffset
& 7);
3964 dither
= Floyd4x4
[y
& 3];
3966 for (x
= xsize
; x
> 0; x
--)
3968 if ((*r0
& 15) > dither
[x
& 3])
3969 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
3971 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
3973 if ((*r0
& 15) > dither
[x
& 3])
3974 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
3976 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
3978 if ((*r0
& 15) > dither
[x
& 3])
3979 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
3981 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
3983 if (bitmask
== 0xf0)
3997 for (x
= xsize
; x
> 0; x
--, r0
+= 3, r1
+= 3)
4002 *cptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
4007 *mptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
4012 *yptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
4018 case CUPS_ORDER_PLANAR
:
4019 switch (header
->cupsBitsPerColor
)
4022 bitmask
= 0x80 >> (bitoffset
& 7);
4023 dither
= Floyd16x16
[y
& 15];
4028 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
4030 if (r0
[0] > dither
[x
& 15])
4044 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
4046 if (r0
[1] > dither
[x
& 15])
4060 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
4062 if (r0
[2] > dither
[x
& 15])
4078 bitmask
= 0xc0 >> (bitoffset
& 7);
4079 dither
= Floyd8x8
[y
& 7];
4083 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
4085 if ((*r0
& 63) > dither
[x
& 7])
4086 *ptr
^= (bitmask
& OnPixels
[*r0
]);
4088 *ptr
^= (bitmask
& OffPixels
[*r0
]);
4102 bitmask
= 0xf0 >> (bitoffset
& 7);
4103 dither
= Floyd4x4
[y
& 3];
4107 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
4109 if ((*r0
& 15) > dither
[x
& 3])
4110 *ptr
^= (bitmask
& OnPixels
[*r0
]);
4112 *ptr
^= (bitmask
& OffPixels
[*r0
]);
4114 if (bitmask
== 0xf0)
4130 for (x
= xsize
; x
> 0; x
--, r0
+= 3, r1
+= 3)
4135 *ptr
++ = (*r0
* yerr0
+ *r1
* yerr1
) / ysize
;
4145 * 'format_YMCK()' - Convert image data to YMCK.
4149 format_YMCK(cups_page_header2_t
*header
, /* I - Page header */
4150 unsigned char *row
, /* IO - Bitmap data for device */
4151 int y
, /* I - Current row */
4152 int z
, /* I - Current plane */
4153 int xsize
, /* I - Width of image data */
4154 int ysize
, /* I - Height of image data */
4155 int yerr0
, /* I - Top Y error */
4156 int yerr1
, /* I - Bottom Y error */
4157 cups_ib_t
*r0
, /* I - Primary image data */
4158 cups_ib_t
*r1
) /* I - Image data for interpolation */
4160 cups_ib_t
*ptr
, /* Pointer into row */
4161 *cptr
, /* Pointer into cyan */
4162 *mptr
, /* Pointer into magenta */
4163 *yptr
, /* Pointer into yellow */
4164 *kptr
, /* Pointer into black */
4165 bitmask
; /* Current mask for pixel */
4166 int bitoffset
; /* Current offset in line */
4167 int bandwidth
; /* Width of a color band */
4168 int x
, /* Current X coordinate on page */
4169 *dither
; /* Pointer into dither array */
4178 bitoffset
= header
->cupsBitsPerPixel
* ((header
->cupsWidth
- xsize
) / 2);
4181 bitoffset
= header
->cupsBitsPerPixel
* (header
->cupsWidth
- xsize
);
4185 ptr
= row
+ bitoffset
/ 8;
4186 bandwidth
= header
->cupsBytesPerLine
/ 4;
4188 switch (header
->cupsColorOrder
)
4190 case CUPS_ORDER_CHUNKED
:
4191 switch (header
->cupsBitsPerColor
)
4194 bitmask
= 128 >> (bitoffset
& 7);
4195 dither
= Floyd16x16
[y
& 15];
4197 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
4199 if (r0
[2] > dither
[x
& 15])
4203 if (r0
[1] > dither
[x
& 15])
4207 if (r0
[0] > dither
[x
& 15])
4211 if (r0
[3] > dither
[x
& 15])
4226 dither
= Floyd8x8
[y
& 7];
4228 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
4230 if ((r0
[2] & 63) > dither
[x
& 7])
4231 *ptr
^= (0xc0 & OnPixels
[r0
[2]]);
4233 *ptr
^= (0xc0 & OffPixels
[r0
[2]]);
4235 if ((r0
[1] & 63) > dither
[x
& 7])
4236 *ptr
^= (0x30 & OnPixels
[r0
[1]]);
4238 *ptr
^= (0x30 & OffPixels
[r0
[1]]);
4240 if ((r0
[0] & 63) > dither
[x
& 7])
4241 *ptr
^= (0x0c & OnPixels
[r0
[0]]);
4243 *ptr
^= (0x0c & OffPixels
[r0
[0]]);
4245 if ((r0
[3] & 63) > dither
[x
& 7])
4246 *ptr
++ ^= (0x03 & OnPixels
[r0
[3]]);
4248 *ptr
++ ^= (0x03 & OffPixels
[r0
[3]]);
4253 dither
= Floyd4x4
[y
& 3];
4255 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
4257 if ((r0
[2] & 15) > dither
[x
& 3])
4258 *ptr
^= (0xf0 & OnPixels
[r0
[2]]);
4260 *ptr
^= (0xf0 & OffPixels
[r0
[2]]);
4262 if ((r0
[1] & 15) > dither
[x
& 3])
4263 *ptr
++ ^= (0x0f & OnPixels
[r0
[1]]);
4265 *ptr
++ ^= (0x0f & OffPixels
[r0
[1]]);
4267 if ((r0
[0] & 15) > dither
[x
& 3])
4268 *ptr
^= (0xf0 & OnPixels
[r0
[0]]);
4270 *ptr
^= (0xf0 & OffPixels
[r0
[0]]);
4272 if ((r0
[3] & 15) > dither
[x
& 3])
4273 *ptr
++ ^= (0x0f & OnPixels
[r0
[3]]);
4275 *ptr
++ ^= (0x0f & OffPixels
[r0
[3]]);
4280 for (x
= xsize
; x
> 0; x
--, r0
+= 4, r1
+= 4)
4285 *ptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
4290 *ptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
4295 *ptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
4300 *ptr
++ = (r0
[3] * yerr0
+ r1
[3] * yerr1
) / ysize
;
4306 case CUPS_ORDER_BANDED
:
4308 mptr
= ptr
+ bandwidth
;
4309 cptr
= ptr
+ 2 * bandwidth
;
4310 kptr
= ptr
+ 3 * bandwidth
;
4312 switch (header
->cupsBitsPerColor
)
4315 bitmask
= 0x80 >> (bitoffset
& 7);
4316 dither
= Floyd16x16
[y
& 15];
4318 for (x
= xsize
; x
> 0; x
--)
4320 if (*r0
++ > dither
[x
& 15])
4322 if (*r0
++ > dither
[x
& 15])
4324 if (*r0
++ > dither
[x
& 15])
4326 if (*r0
++ > dither
[x
& 15])
4344 bitmask
= 0xc0 >> (bitoffset
& 7);
4345 dither
= Floyd8x8
[y
& 7];
4347 for (x
= xsize
; x
> 0; x
--)
4349 if ((*r0
& 63) > dither
[x
& 7])
4350 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
4352 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
4354 if ((*r0
& 63) > dither
[x
& 7])
4355 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
4357 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
4359 if ((*r0
& 63) > dither
[x
& 7])
4360 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
4362 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
4364 if ((*r0
& 63) > dither
[x
& 7])
4365 *kptr
^= (bitmask
& OnPixels
[*r0
++]);
4367 *kptr
^= (bitmask
& OffPixels
[*r0
++]);
4384 bitmask
= 0xf0 >> (bitoffset
& 7);
4385 dither
= Floyd4x4
[y
& 3];
4387 for (x
= xsize
; x
> 0; x
--)
4389 if ((*r0
& 15) > dither
[x
& 3])
4390 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
4392 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
4394 if ((*r0
& 15) > dither
[x
& 3])
4395 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
4397 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
4399 if ((*r0
& 15) > dither
[x
& 3])
4400 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
4402 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
4404 if ((*r0
& 15) > dither
[x
& 3])
4405 *kptr
^= (bitmask
& OnPixels
[*r0
++]);
4407 *kptr
^= (bitmask
& OffPixels
[*r0
++]);
4409 if (bitmask
== 0xf0)
4424 for (x
= xsize
; x
> 0; x
--, r0
+= 4, r1
+= 4)
4429 *cptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
4434 *mptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
4439 *yptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
4444 *kptr
++ = (r0
[3] * yerr0
+ r1
[3] * yerr1
) / ysize
;
4450 case CUPS_ORDER_PLANAR
:
4451 switch (header
->cupsBitsPerColor
)
4454 bitmask
= 0x80 >> (bitoffset
& 7);
4455 dither
= Floyd16x16
[y
& 15];
4462 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
4464 if (*r0
> dither
[x
& 15])
4478 bitmask
= 0xc0 >> (bitoffset
& 7);
4479 dither
= Floyd8x8
[y
& 7];
4485 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
4487 if ((*r0
& 63) > dither
[x
& 7])
4488 *ptr
^= (bitmask
& OnPixels
[*r0
]);
4490 *ptr
^= (bitmask
& OffPixels
[*r0
]);
4504 bitmask
= 0xf0 >> (bitoffset
& 7);
4505 dither
= Floyd4x4
[y
& 3];
4511 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
4513 if ((*r0
& 15) > dither
[x
& 3])
4514 *ptr
^= (bitmask
& OnPixels
[*r0
]);
4516 *ptr
^= (bitmask
& OffPixels
[*r0
]);
4518 if (bitmask
== 0xf0)
4541 for (x
= xsize
; x
> 0; x
--, r0
+= 4, r1
+= 4)
4546 *ptr
++ = (*r0
* yerr0
+ *r1
* yerr1
) / ysize
;
4556 * 'make_lut()' - Make a lookup table given gamma and brightness values.
4560 make_lut(cups_ib_t
*lut
, /* I - Lookup table */
4561 int colorspace
, /* I - Colorspace */
4562 float g
, /* I - Image gamma */
4563 float b
) /* I - Image brightness */
4565 int i
; /* Looping var */
4566 int v
; /* Current value */
4572 for (i
= 0; i
< 256; i
++)
4575 v
= 255.0 * b
* (1.0 - pow(1.0 - (float)i
/ 255.0, g
)) + 0.5;
4577 v
= 255.0 * (1.0 - b
* (1.0 - pow((float)i
/ 255.0, g
))) + 0.5;
4590 * End of "$Id: imagetoraster.c 4767 2005-10-10 19:23:23Z mike $".