2 * "$Id: imagetoraster.c 5099 2006-02-13 02:46:10Z 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 * 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 Floyd16xc16
[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 xc0
, yc0
, /* 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
)
412 * Get gamma value from 1 to 10000...
415 g
= atoi(val
) * 0.001f
;
423 if ((val
= cupsGetOption("brightness", num_options
, options
)) != NULL
)
426 * Get brightness value from 10 to 1000.
429 b
= atoi(val
) * 0.01f
;
437 if ((val
= cupsGetOption("scaling", num_options
, options
)) != NULL
)
438 zoom
= atoi(val
) * 0.01;
439 else if (cupsGetOption("fitplot", num_options
, options
))
442 if ((val
= cupsGetOption("ppi", num_options
, options
)) != NULL
)
443 if (sscanf(val
, "%dx%d", &xppi
, &yppi
) < 2)
446 if ((val
= cupsGetOption("position", num_options
, options
)) != NULL
)
448 if (strcasecmp(val
, "center") == 0)
453 else if (strcasecmp(val
, "top") == 0)
458 else if (strcasecmp(val
, "left") == 0)
463 else if (strcasecmp(val
, "right") == 0)
468 else if (strcasecmp(val
, "top-left") == 0)
473 else if (strcasecmp(val
, "top-right") == 0)
478 else if (strcasecmp(val
, "bottom") == 0)
483 else if (strcasecmp(val
, "bottom-left") == 0)
488 else if (strcasecmp(val
, "bottom-right") == 0)
495 if ((val
= cupsGetOption("saturation", num_options
, options
)) != NULL
)
498 if ((val
= cupsGetOption("hue", num_options
, options
)) != NULL
)
501 if ((val
= cupsGetOption("mirror", num_options
, options
)) != NULL
&&
502 strcasecmp(val
, "True") == 0)
506 * Set the needed options in the page header...
509 memset(&header
, 0, sizeof(header
));
510 header
.HWResolution
[0] = 100;
511 header
.HWResolution
[1] = 100;
512 header
.cupsBitsPerColor
= 1;
513 header
.cupsColorOrder
= CUPS_ORDER_CHUNKED
;
514 header
.cupsColorSpace
= CUPS_CSPACE_K
;
516 if (ppd
&& ppd
->patches
)
517 exec_code(&header
, ppd
->patches
);
519 if ((count
= ppdCollect(ppd
, PPD_ORDER_DOCUMENT
, &choices
)) > 0)
520 for (i
= 0; i
< count
; i
++)
521 exec_code(&header
, choices
[i
]->code
);
523 if ((count
= ppdCollect(ppd
, PPD_ORDER_ANY
, &choices
)) > 0)
524 for (i
= 0; i
< count
; i
++)
525 exec_code(&header
, choices
[i
]->code
);
527 if ((count
= ppdCollect(ppd
, PPD_ORDER_PROLOG
, &choices
)) > 0)
528 for (i
= 0; i
< count
; i
++)
529 exec_code(&header
, choices
[i
]->code
);
531 if ((count
= ppdCollect(ppd
, PPD_ORDER_PAGE
, &choices
)) > 0)
532 for (i
= 0; i
< count
; i
++)
533 exec_code(&header
, choices
[i
]->code
);
536 * Get the media type and resolution that have been chosen...
539 if ((choice
= ppdFindMarkedChoice(ppd
, "MediaType")) != NULL
)
540 media_type
= choice
->choice
;
544 if ((choice
= ppdFindMarkedChoice(ppd
, "Resolution")) != NULL
)
545 resolution
= choice
->choice
;
550 * Choose the appropriate colorspace...
553 switch (header
.cupsColorSpace
)
556 primary
= CUPS_IMAGE_WHITE
;
557 secondary
= CUPS_IMAGE_WHITE
;
558 header
.cupsBitsPerPixel
= header
.cupsBitsPerColor
;
562 case CUPS_CSPACE_RGB
:
563 case CUPS_CSPACE_RGBA
:
564 case CUPS_CSPACE_RGBW
:
565 primary
= CUPS_IMAGE_RGB
;
566 secondary
= CUPS_IMAGE_RGB
;
569 * Ensure that colorimetric colorspaces use at least 8 bits per
573 if (header
.cupsColorSpace
>= CUPS_CSPACE_CIEXYZ
&&
574 header
.cupsBitsPerColor
< 8)
575 header
.cupsBitsPerColor
= 8;
577 if (header
.cupsColorOrder
== CUPS_ORDER_CHUNKED
)
579 if (header
.cupsBitsPerColor
>= 8)
580 header
.cupsBitsPerPixel
= header
.cupsBitsPerColor
* 3;
582 header
.cupsBitsPerPixel
= header
.cupsBitsPerColor
* 4;
585 header
.cupsBitsPerPixel
= header
.cupsBitsPerColor
;
589 case CUPS_CSPACE_WHITE
:
590 case CUPS_CSPACE_GOLD
:
591 case CUPS_CSPACE_SILVER
:
592 primary
= CUPS_IMAGE_BLACK
;
593 secondary
= CUPS_IMAGE_BLACK
;
594 header
.cupsBitsPerPixel
= header
.cupsBitsPerColor
;
597 case CUPS_CSPACE_CMYK
:
598 case CUPS_CSPACE_YMCK
:
599 case CUPS_CSPACE_KCMY
:
600 case CUPS_CSPACE_GMCK
:
601 case CUPS_CSPACE_GMCS
:
602 primary
= CUPS_IMAGE_CMYK
;
603 secondary
= CUPS_IMAGE_CMYK
;
605 if (header
.cupsColorOrder
== CUPS_ORDER_CHUNKED
)
606 header
.cupsBitsPerPixel
= header
.cupsBitsPerColor
* 4;
608 header
.cupsBitsPerPixel
= header
.cupsBitsPerColor
;
611 case CUPS_CSPACE_CMY
:
612 case CUPS_CSPACE_YMC
:
613 primary
= CUPS_IMAGE_CMY
;
614 secondary
= CUPS_IMAGE_CMY
;
616 if (header
.cupsColorOrder
== CUPS_ORDER_CHUNKED
)
618 if (header
.cupsBitsPerColor
>= 8)
619 header
.cupsBitsPerPixel
= 24;
621 header
.cupsBitsPerPixel
= header
.cupsBitsPerColor
* 4;
624 header
.cupsBitsPerPixel
= header
.cupsBitsPerColor
;
627 case CUPS_CSPACE_KCMYcm
:
628 if (header
.cupsBitsPerPixel
== 1)
630 primary
= CUPS_IMAGE_CMY
;
631 secondary
= CUPS_IMAGE_CMY
;
633 if (header
.cupsColorOrder
== CUPS_ORDER_CHUNKED
)
634 header
.cupsBitsPerPixel
= 8;
636 header
.cupsBitsPerPixel
= 1;
640 primary
= CUPS_IMAGE_CMYK
;
641 secondary
= CUPS_IMAGE_CMYK
;
643 if (header
.cupsColorOrder
== CUPS_ORDER_CHUNKED
)
644 header
.cupsBitsPerPixel
= header
.cupsBitsPerColor
* 4;
646 header
.cupsBitsPerPixel
= header
.cupsBitsPerColor
;
652 * Find a color profile matching the current options...
655 if ((val
= cupsGetOption("profile", num_options
, options
)) != NULL
)
657 profile
= &userprofile
;
658 sscanf(val
, "%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f",
659 &(userprofile
.density
), &(userprofile
.gamma
),
660 userprofile
.matrix
[0] + 0, userprofile
.matrix
[0] + 1,
661 userprofile
.matrix
[0] + 2,
662 userprofile
.matrix
[1] + 0, userprofile
.matrix
[1] + 1,
663 userprofile
.matrix
[1] + 2,
664 userprofile
.matrix
[2] + 0, userprofile
.matrix
[2] + 1,
665 userprofile
.matrix
[2] + 2);
667 userprofile
.density
*= 0.001f
;
668 userprofile
.gamma
*= 0.001f
;
669 userprofile
.matrix
[0][0] *= 0.001f
;
670 userprofile
.matrix
[0][1] *= 0.001f
;
671 userprofile
.matrix
[0][2] *= 0.001f
;
672 userprofile
.matrix
[1][0] *= 0.001f
;
673 userprofile
.matrix
[1][1] *= 0.001f
;
674 userprofile
.matrix
[1][2] *= 0.001f
;
675 userprofile
.matrix
[2][0] *= 0.001f
;
676 userprofile
.matrix
[2][1] *= 0.001f
;
677 userprofile
.matrix
[2][2] *= 0.001f
;
679 else if (ppd
!= NULL
)
681 fprintf(stderr
, "DEBUG: Searching for profile \"%s/%s\"...\n",
682 resolution
, media_type
);
684 for (i
= 0, profile
= ppd
->profiles
; i
< ppd
->num_profiles
; i
++, profile
++)
686 fprintf(stderr
, "DEBUG: \"%s/%s\" = ", profile
->resolution
,
687 profile
->media_type
);
689 if ((strcmp(profile
->resolution
, resolution
) == 0 ||
690 profile
->resolution
[0] == '-') &&
691 (strcmp(profile
->media_type
, media_type
) == 0 ||
692 profile
->media_type
[0] == '-'))
694 fputs("MATCH!\n", stderr
);
698 fputs("no.\n", stderr
);
702 * If we found a color profile, use it!
705 if (i
>= ppd
->num_profiles
)
712 cupsImageSetProfile(profile
->density
, profile
->gamma
, profile
->matrix
);
714 cupsImageSetRasterColorSpace(header
.cupsColorSpace
);
717 * Create a gamma/brightness LUT...
720 make_lut(lut
, primary
, g
, b
);
723 * Open the input image to print...
726 fputs("INFO: Loading image file...\n", stderr
);
728 img
= cupsImageOpen(filename
, primary
, secondary
, sat
, hue
, lut
);
735 fputs("ERROR: Unable to open image file for printing!\n", stderr
);
741 * Scale as necessary...
744 if (zoom
== 0.0 && xppi
== 0)
753 fprintf(stderr
, "DEBUG: Before scaling: xppi=%d, yppi=%d, zoom=%.2f\n",
759 * Scale the image as neccesary to match the desired pixels-per-inch.
764 xprint
= (PageTop
- PageBottom
) / 72.0;
765 yprint
= (PageRight
- PageLeft
) / 72.0;
769 xprint
= (PageRight
- PageLeft
) / 72.0;
770 yprint
= (PageTop
- PageBottom
) / 72.0;
773 fprintf(stderr
, "DEBUG: Before scaling: xprint=%.1f, yprint=%.1f\n",
776 xinches
= (float)img
->xsize
/ (float)xppi
;
777 yinches
= (float)img
->ysize
/ (float)yppi
;
779 fprintf(stderr
, "DEBUG: Image size is %.1f x %.1f inches...\n",
782 if ((val
= cupsGetOption("natural-scaling", num_options
, options
)) != NULL
)
784 xinches
= xinches
* atoi(val
) / 100;
785 yinches
= yinches
* atoi(val
) / 100;
788 if (cupsGetOption("orientation-requested", num_options
, options
) == NULL
&&
789 cupsGetOption("landscape", num_options
, options
) == NULL
)
792 * Rotate the image if it will fit landscape but not portrait...
795 fputs("DEBUG: Auto orientation...\n", stderr
);
797 if ((xinches
> xprint
|| yinches
> yprint
) &&
798 xinches
<= yprint
&& yinches
<= xprint
)
801 * Rotate the image as needed...
804 fputs("DEBUG: Using landscape orientation...\n", stderr
);
806 Orientation
= (Orientation
+ 1) & 3;
816 * Scale percentage of page size...
819 xprint
= (PageRight
- PageLeft
) / 72.0;
820 yprint
= (PageTop
- PageBottom
) / 72.0;
821 aspect
= (float)img
->yppi
/ (float)img
->xppi
;
823 fprintf(stderr
, "DEBUG: Before scaling: xprint=%.1f, yprint=%.1f\n",
826 fprintf(stderr
, "DEBUG: img->xppi = %d, img->yppi = %d, aspect = %f\n",
827 img
->xppi
, img
->yppi
, aspect
);
829 xsize
= xprint
* zoom
;
830 ysize
= xsize
* img
->ysize
/ img
->xsize
/ aspect
;
832 if (ysize
> (yprint
* zoom
))
834 ysize
= yprint
* zoom
;
835 xsize
= ysize
* img
->xsize
* aspect
/ img
->ysize
;
838 xsize2
= yprint
* zoom
;
839 ysize2
= xsize2
* img
->ysize
/ img
->xsize
/ aspect
;
841 if (ysize2
> (xprint
* zoom
))
843 ysize2
= xprint
* zoom
;
844 xsize2
= ysize2
* img
->xsize
* aspect
/ img
->ysize
;
847 fprintf(stderr
, "DEBUG: Portrait size is %.2f x %.2f inches\n", xsize
, ysize
);
848 fprintf(stderr
, "DEBUG: Landscape size is %.2f x %.2f inches\n", xsize2
, ysize2
);
850 if (cupsGetOption("orientation-requested", num_options
, options
) == NULL
&&
851 cupsGetOption("landscape", num_options
, options
) == NULL
)
854 * Choose the rotation with the largest area, but prefer
855 * portrait if they are equal...
858 fputs("DEBUG: Auto orientation...\n", stderr
);
860 if ((xsize
* ysize
) < (xsize2
* xsize2
))
863 * Do landscape orientation...
866 fputs("DEBUG: Using landscape orientation...\n", stderr
);
871 xprint
= (PageTop
- PageBottom
) / 72.0;
872 yprint
= (PageRight
- PageLeft
) / 72.0;
877 * Do portrait orientation...
880 fputs("DEBUG: Using portrait orientation...\n", stderr
);
887 else if (Orientation
& 1)
889 fputs("DEBUG: Using landscape orientation...\n", stderr
);
893 xprint
= (PageTop
- PageBottom
) / 72.0;
894 yprint
= (PageRight
- PageLeft
) / 72.0;
898 fputs("DEBUG: Using portrait orientation...\n", stderr
);
902 xprint
= (PageRight
- PageLeft
) / 72.0;
903 yprint
= (PageTop
- PageBottom
) / 72.0;
908 * Compute the number of pages to print and the size of the image on each
912 xpages
= ceil(xinches
/ xprint
);
913 ypages
= ceil(yinches
/ yprint
);
915 xprint
= xinches
/ xpages
;
916 yprint
= yinches
/ ypages
;
918 fprintf(stderr
, "DEBUG: xpages = %dx%.2fin, ypages = %dx%.2fin\n",
919 xpages
, xprint
, ypages
, yprint
);
922 * Compute the bitmap size...
925 if ((choice
= ppdFindMarkedChoice(ppd
, "PageSize")) != NULL
&&
926 strcasecmp(choice
->choice
, "Custom") == 0)
928 float width
, /* New width in points */
929 length
; /* New length in points */
933 * Use the correct width and length for the current orientation...
938 width
= yprint
* 72.0;
939 length
= xprint
* 72.0;
943 width
= xprint
* 72.0;
944 length
= yprint
* 72.0;
948 * Add margins to page size...
951 width
+= ppd
->custom_margins
[0] + ppd
->custom_margins
[2];
952 length
+= ppd
->custom_margins
[1] + ppd
->custom_margins
[3];
955 * Enforce minimums...
958 if (width
< ppd
->custom_min
[0])
959 width
= ppd
->custom_min
[0];
961 if (length
< ppd
->custom_min
[1])
962 length
= ppd
->custom_min
[1];
964 fprintf(stderr
, "DEBUG: Updated custom page size to %.2f x %.2f inches...\n",
965 width
/ 72.0, length
/ 72.0);
968 * Set the new custom size...
971 header
.PageSize
[0] = width
+ 0.5;
972 header
.PageSize
[1] = length
+ 0.5;
975 * Update page variables...
980 PageLeft
= ppd
->custom_margins
[0];
981 PageRight
= width
- ppd
->custom_margins
[2];
982 PageBottom
= ppd
->custom_margins
[1];
983 PageTop
= length
- ppd
->custom_margins
[3];
986 * Remove margins from page size...
989 width
-= ppd
->custom_margins
[0] + ppd
->custom_margins
[2];
990 length
-= ppd
->custom_margins
[1] + ppd
->custom_margins
[3];
993 * Set the bitmap size...
996 header
.cupsWidth
= width
* header
.HWResolution
[0] / 72.0;
997 header
.cupsHeight
= length
* header
.HWResolution
[1] / 72.0;
1001 header
.cupsWidth
= (PageRight
- PageLeft
) * header
.HWResolution
[0] / 72.0;
1002 header
.cupsHeight
= (PageTop
- PageBottom
) * header
.HWResolution
[1] / 72.0;
1003 header
.PageSize
[0] = PageWidth
;
1004 header
.PageSize
[1] = PageLength
;
1007 header
.Margins
[0] = PageLeft
;
1008 header
.Margins
[1] = PageBottom
;
1010 fprintf(stderr
, "DEBUG: PageSize = [%d %d]\n", header
.PageSize
[0],
1011 header
.PageSize
[1]);
1013 switch (Orientation
)
1019 header
.ImagingBoundingBox
[0] = PageLeft
;
1020 header
.ImagingBoundingBox
[2] = PageLeft
+ xprint
* 72;
1023 header
.ImagingBoundingBox
[0] = (PageRight
+ PageLeft
- xprint
* 72) / 2;
1024 header
.ImagingBoundingBox
[2] = (PageRight
+ PageLeft
+ xprint
* 72) / 2;
1027 header
.ImagingBoundingBox
[0] = PageRight
- xprint
* 72;
1028 header
.ImagingBoundingBox
[2] = PageRight
;
1035 header
.ImagingBoundingBox
[1] = PageBottom
;
1036 header
.ImagingBoundingBox
[3] = PageBottom
+ yprint
* 72;
1039 header
.ImagingBoundingBox
[1] = (PageTop
+ PageBottom
- yprint
* 72) / 2;
1040 header
.ImagingBoundingBox
[3] = (PageTop
+ PageBottom
+ yprint
* 72) / 2;
1043 header
.ImagingBoundingBox
[1] = PageTop
- yprint
* 72;
1044 header
.ImagingBoundingBox
[3] = PageTop
;
1053 header
.ImagingBoundingBox
[0] = PageBottom
;
1054 header
.ImagingBoundingBox
[2] = PageBottom
+ yprint
* 72;
1057 header
.ImagingBoundingBox
[0] = (PageTop
+ PageBottom
- yprint
* 72) / 2;
1058 header
.ImagingBoundingBox
[2] = (PageTop
+ PageBottom
+ yprint
* 72) / 2;
1061 header
.ImagingBoundingBox
[0] = PageTop
- yprint
* 72;
1062 header
.ImagingBoundingBox
[2] = PageTop
;
1069 header
.ImagingBoundingBox
[1] = PageLeft
;
1070 header
.ImagingBoundingBox
[3] = PageLeft
+ xprint
* 72;
1073 header
.ImagingBoundingBox
[1] = (PageRight
+ PageLeft
- xprint
* 72) / 2;
1074 header
.ImagingBoundingBox
[3] = (PageRight
+ PageLeft
+ xprint
* 72) / 2;
1077 header
.ImagingBoundingBox
[1] = PageRight
- xprint
* 72;
1078 header
.ImagingBoundingBox
[3] = PageRight
;
1087 header
.ImagingBoundingBox
[0] = PageLeft
;
1088 header
.ImagingBoundingBox
[2] = PageLeft
+ xprint
* 72;
1091 header
.ImagingBoundingBox
[0] = (PageRight
+ PageLeft
- xprint
* 72) / 2;
1092 header
.ImagingBoundingBox
[2] = (PageRight
+ PageLeft
+ xprint
* 72) / 2;
1095 header
.ImagingBoundingBox
[0] = PageRight
- xprint
* 72;
1096 header
.ImagingBoundingBox
[2] = PageRight
;
1103 header
.ImagingBoundingBox
[1] = PageBottom
;
1104 header
.ImagingBoundingBox
[3] = PageBottom
+ yprint
* 72;
1107 header
.ImagingBoundingBox
[1] = (PageTop
+ PageBottom
- yprint
* 72) / 2;
1108 header
.ImagingBoundingBox
[3] = (PageTop
+ PageBottom
+ yprint
* 72) / 2;
1111 header
.ImagingBoundingBox
[1] = PageTop
- yprint
* 72;
1112 header
.ImagingBoundingBox
[3] = PageTop
;
1121 header
.ImagingBoundingBox
[0] = PageBottom
;
1122 header
.ImagingBoundingBox
[2] = PageBottom
+ yprint
* 72;
1125 header
.ImagingBoundingBox
[0] = (PageTop
+ PageBottom
- yprint
* 72) / 2;
1126 header
.ImagingBoundingBox
[2] = (PageTop
+ PageBottom
+ yprint
* 72) / 2;
1129 header
.ImagingBoundingBox
[0] = PageTop
- yprint
* 72;
1130 header
.ImagingBoundingBox
[2] = PageTop
;
1137 header
.ImagingBoundingBox
[1] = PageLeft
;
1138 header
.ImagingBoundingBox
[3] = PageLeft
+ xprint
* 72;
1141 header
.ImagingBoundingBox
[1] = (PageRight
+ PageLeft
- xprint
* 72) / 2;
1142 header
.ImagingBoundingBox
[3] = (PageRight
+ PageLeft
+ xprint
* 72) / 2;
1145 header
.ImagingBoundingBox
[1] = PageRight
- xprint
* 72;
1146 header
.ImagingBoundingBox
[3] = PageRight
;
1152 switch (header
.cupsColorOrder
)
1155 header
.cupsBytesPerLine
= (header
.cupsBitsPerPixel
*
1156 header
.cupsWidth
+ 7) / 8;
1160 case CUPS_ORDER_BANDED
:
1161 if (header
.cupsColorSpace
== CUPS_CSPACE_KCMYcm
&&
1162 header
.cupsBitsPerColor
> 1)
1163 header
.cupsBytesPerLine
= (header
.cupsBitsPerPixel
*
1164 header
.cupsWidth
+ 7) / 8 * 4;
1166 header
.cupsBytesPerLine
= (header
.cupsBitsPerPixel
*
1167 header
.cupsWidth
+ 7) / 8 *
1168 Planes
[header
.cupsColorSpace
];
1172 case CUPS_ORDER_PLANAR
:
1173 header
.cupsBytesPerLine
= (header
.cupsBitsPerPixel
*
1174 header
.cupsWidth
+ 7) / 8;
1175 num_planes
= Planes
[header
.cupsColorSpace
];
1179 if (header
.cupsBitsPerColor
>= 8)
1180 zoom_type
= CUPS_IZOOM_NORMAL
;
1182 zoom_type
= CUPS_IZOOM_FAST
;
1185 * See if we need to collate, and if so how we need to do it...
1188 if (xpages
== 1 && ypages
== 1)
1191 slowcollate
= Collate
&& ppdFindOption(ppd
, "Collate") == NULL
;
1193 slowcopies
= ppd
->manual_copies
;
1197 if (Copies
> 1 && !slowcollate
&& !slowcopies
)
1199 header
.Collate
= (cups_bool_t
)Collate
;
1200 header
.NumCopies
= Copies
;
1205 header
.NumCopies
= 1;
1208 * Create the dithering lookup tables...
1212 OnPixels
[255] = 0xff;
1213 OffPixels
[0] = 0x00;
1214 OffPixels
[255] = 0xff;
1216 switch (header
.cupsBitsPerColor
)
1219 for (i
= 1; i
< 255; i
++)
1221 OnPixels
[i
] = 0x55 * (i
/ 85 + 1);
1222 OffPixels
[i
] = 0x55 * (i
/ 64);
1226 for (i
= 1; i
< 255; i
++)
1228 OnPixels
[i
] = 17 * (i
/ 17 + 1);
1229 OffPixels
[i
] = 17 * (i
/ 16);
1232 OnPixels
[255] = OffPixels
[255] = 0xff;
1237 * Output the pages...
1240 fprintf(stderr
, "DEBUG: cupsWidth = %d\n", header
.cupsWidth
);
1241 fprintf(stderr
, "DEBUG: cupsHeight = %d\n", header
.cupsHeight
);
1242 fprintf(stderr
, "DEBUG: cupsBitsPerColor = %d\n", header
.cupsBitsPerColor
);
1243 fprintf(stderr
, "DEBUG: cupsBitsPerPixel = %d\n", header
.cupsBitsPerPixel
);
1244 fprintf(stderr
, "DEBUG: cupsBytesPerLine = %d\n", header
.cupsBytesPerLine
);
1245 fprintf(stderr
, "DEBUG: cupsColorOrder = %d\n", header
.cupsColorOrder
);
1246 fprintf(stderr
, "DEBUG: cupsColorSpace = %d\n", header
.cupsColorSpace
);
1247 fprintf(stderr
, "DEBUG: img->colorspace = %d\n", img
->colorspace
);
1249 row
= malloc(2 * header
.cupsBytesPerLine
);
1250 ras
= cupsRasterOpen(1, CUPS_RASTER_WRITE
);
1251 blank
= img
->colorspace
< 0 ? 0 : ~0;
1253 for (i
= 0, page
= 1; i
< Copies
; i
++)
1254 for (xpage
= 0; xpage
< xpages
; xpage
++)
1255 for (ypage
= 0; ypage
< ypages
; ypage
++, page
++)
1257 fprintf(stderr
, "INFO: Formatting page %d...\n", page
);
1259 if (Orientation
& 1)
1261 xc0
= img
->xsize
* ypage
/ ypages
;
1262 xc1
= img
->xsize
* (ypage
+ 1) / ypages
- 1;
1263 yc0
= img
->ysize
* xpage
/ xpages
;
1264 yc1
= img
->ysize
* (xpage
+ 1) / xpages
- 1;
1266 xtemp
= header
.HWResolution
[0] * yprint
;
1267 ytemp
= header
.HWResolution
[1] * xprint
;
1271 xc0
= img
->xsize
* xpage
/ xpages
;
1272 xc1
= img
->xsize
* (xpage
+ 1) / xpages
- 1;
1273 yc0
= img
->ysize
* ypage
/ ypages
;
1274 yc1
= img
->ysize
* (ypage
+ 1) / ypages
- 1;
1276 xtemp
= header
.HWResolution
[0] * xprint
;
1277 ytemp
= header
.HWResolution
[1] * yprint
;
1280 cupsRasterWriteHeader2(ras
, &header
);
1282 for (plane
= 0; plane
< num_planes
; plane
++)
1285 * Initialize the image "zoom" engine...
1289 z
= cupsImageZoomNew(img
, xc0
, yc0
, xc1
, yc1
, -xtemp
, ytemp
,
1290 Orientation
& 1, zoom_type
);
1292 z
= cupsImageZoomNew(img
, xc0
, yc0
, xc1
, yc1
, xtemp
, ytemp
,
1293 Orientation
& 1, zoom_type
);
1296 * Write leading blank space as needed...
1299 if (header
.cupsHeight
> z
->ysize
&& YPosition
<= 0)
1301 memset(row
, blank
, header
.cupsBytesPerLine
);
1303 y
= header
.cupsHeight
- z
->ysize
;
1309 if (cupsRasterWritePixels(ras
, row
, header
.cupsBytesPerLine
) <
1310 header
.cupsBytesPerLine
)
1312 fputs("ERROR: Unable to write raster data to driver!\n", stderr
);
1313 cupsImageClose(img
);
1320 * Then write image data...
1323 for (y
= z
->ysize
, yerr0
= 0, yerr1
= z
->ysize
, iy
= 0, last_iy
= -2;
1329 if (zoom_type
!= CUPS_IZOOM_FAST
&& (iy
- last_iy
) > 1)
1330 cupsImageZoomFill(z
, iy
);
1332 cupsImageZoomFill(z
, iy
+ z
->yincr
);
1338 * Format this line of raster data for the printer...
1341 memset(row
, blank
, header
.cupsBytesPerLine
);
1343 r0
= z
->rows
[z
->row
];
1344 r1
= z
->rows
[1 - z
->row
];
1346 switch (header
.cupsColorSpace
)
1348 case CUPS_CSPACE_W
:
1349 format_W(&header
, row
, y
, plane
, z
->xsize
, z
->ysize
,
1350 yerr0
, yerr1
, r0
, r1
);
1353 case CUPS_CSPACE_RGB
:
1354 format_RGB(&header
, row
, y
, plane
, z
->xsize
, z
->ysize
,
1355 yerr0
, yerr1
, r0
, r1
);
1357 case CUPS_CSPACE_RGBA
:
1358 case CUPS_CSPACE_RGBW
:
1359 format_RGBA(&header
, row
, y
, plane
, z
->xsize
, z
->ysize
,
1360 yerr0
, yerr1
, r0
, r1
);
1362 case CUPS_CSPACE_K
:
1363 case CUPS_CSPACE_WHITE
:
1364 case CUPS_CSPACE_GOLD
:
1365 case CUPS_CSPACE_SILVER
:
1366 format_K(&header
, row
, y
, plane
, z
->xsize
, z
->ysize
,
1367 yerr0
, yerr1
, r0
, r1
);
1369 case CUPS_CSPACE_CMY
:
1370 format_CMY(&header
, row
, y
, plane
, z
->xsize
, z
->ysize
,
1371 yerr0
, yerr1
, r0
, r1
);
1373 case CUPS_CSPACE_YMC
:
1374 format_YMC(&header
, row
, y
, plane
, z
->xsize
, z
->ysize
,
1375 yerr0
, yerr1
, r0
, r1
);
1377 case CUPS_CSPACE_CMYK
:
1378 format_CMYK(&header
, row
, y
, plane
, z
->xsize
, z
->ysize
,
1379 yerr0
, yerr1
, r0
, r1
);
1381 case CUPS_CSPACE_YMCK
:
1382 case CUPS_CSPACE_GMCK
:
1383 case CUPS_CSPACE_GMCS
:
1384 format_YMCK(&header
, row
, y
, plane
, z
->xsize
, z
->ysize
,
1385 yerr0
, yerr1
, r0
, r1
);
1387 case CUPS_CSPACE_KCMY
:
1388 format_KCMY(&header
, row
, y
, plane
, z
->xsize
, z
->ysize
,
1389 yerr0
, yerr1
, r0
, r1
);
1391 case CUPS_CSPACE_KCMYcm
:
1392 format_KCMYcm(&header
, row
, y
, plane
, z
->xsize
, z
->ysize
,
1393 yerr0
, yerr1
, r0
, r1
);
1398 * Write the raster data to the driver...
1401 if (cupsRasterWritePixels(ras
, row
, header
.cupsBytesPerLine
) <
1402 header
.cupsBytesPerLine
)
1404 fputs("ERROR: Unable to write raster data to driver!\n", stderr
);
1405 cupsImageClose(img
);
1410 * Compute the next scanline in the image...
1425 * Write trailing blank space as needed...
1428 if (header
.cupsHeight
> z
->ysize
&& YPosition
>= 0)
1430 memset(row
, blank
, header
.cupsBytesPerLine
);
1432 y
= header
.cupsHeight
- z
->ysize
;
1438 if (cupsRasterWritePixels(ras
, row
, header
.cupsBytesPerLine
) <
1439 header
.cupsBytesPerLine
)
1441 fputs("ERROR: Unable to write raster data to driver!\n", stderr
);
1442 cupsImageClose(img
);
1449 * Free memory used for the "zoom" engine...
1452 cupsImageZoomDelete(z
);
1461 cupsRasterClose(ras
);
1462 cupsImageClose(img
);
1470 * 'exec_code()' - Execute PostScript setpagedevice commands as appropriate.
1474 exec_code(cups_page_header2_t
*header
, /* I - Page header */
1475 const char *code
) /* I - Option choice to execute */
1477 char *ptr
, /* Pointer into name/value string */
1478 name
[255], /* Name of pagedevice entry */
1479 value
[1024]; /* Value of pagedevice entry */
1482 for (; *code
!= '\0';)
1485 * Search for the start of a dictionary name...
1488 while (*code
!= '/' && *code
!= '\0')
1499 for (ptr
= name
; isalnum(*code
& 255) && (ptr
- name
) < (sizeof(name
) - 1);)
1504 * The parse the value as needed...
1507 while (isspace(*code
& 255))
1516 * Read array of values...
1521 *code
!= ']' && *code
!= '\0' &&
1522 (ptr
- value
) < (sizeof(value
) - 1);)
1526 else if (*code
== '(')
1529 * Read string value...
1534 *code
!= ')' && *code
!= '\0' &&
1535 (ptr
- value
) < (sizeof(value
) - 1);)
1539 if (isdigit(*code
& 255))
1540 *ptr
++ = (char)strtol(code
, (char **)&code
, 8);
1549 else if (isdigit(*code
& 255) || *code
== '-')
1552 * Read single number...
1556 (isdigit(*code
& 255) || *code
== '-') &&
1557 (ptr
- value
) < (sizeof(value
) - 1);)
1564 * Read a single name...
1568 (isalnum(*code
& 255) || *code
== '_') &&
1569 (ptr
- value
) < (sizeof(value
) - 1);)
1575 * Assign the value as needed...
1578 if (!strcmp(name
, "MediaClass"))
1579 strlcpy(header
->MediaClass
, value
, sizeof(header
->MediaClass
));
1580 else if (!strcmp(name
, "MediaColor"))
1581 strlcpy(header
->MediaColor
, value
, sizeof(header
->MediaColor
));
1582 else if (!strcmp(name
, "MediaType"))
1583 strlcpy(header
->MediaType
, value
, sizeof(header
->MediaType
));
1584 else if (!strcmp(name
, "OutputType"))
1585 strlcpy(header
->OutputType
, value
, sizeof(header
->OutputType
));
1586 else if (!strcmp(name
, "AdvanceDistance"))
1587 header
->AdvanceDistance
= atoi(value
);
1588 else if (!strcmp(name
, "AdvanceMedia"))
1589 header
->AdvanceMedia
= atoi(value
);
1590 else if (!strcmp(name
, "Collate"))
1591 header
->Collate
= !strcmp(value
, "true");
1592 else if (!strcmp(name
, "CutMedia"))
1593 header
->CutMedia
= (cups_cut_t
)atoi(value
);
1594 else if (!strcmp(name
, "Duplex"))
1595 header
->Duplex
= !strcmp(value
, "true");
1596 else if (!strcmp(name
, "HWResolution"))
1597 sscanf(value
, "%d%d", header
->HWResolution
+ 0, header
->HWResolution
+ 1);
1598 else if (!strcmp(name
, "InsertSheet"))
1599 header
->InsertSheet
= !strcmp(value
, "true");
1600 else if (!strcmp(name
, "Jog"))
1601 header
->Jog
= atoi(value
);
1602 else if (!strcmp(name
, "LeadingEdge"))
1603 header
->LeadingEdge
= atoi(value
);
1604 else if (!strcmp(name
, "Margins"))
1605 sscanf(value
, "%d%d", header
->Margins
+ 0, header
->Margins
+ 1);
1606 else if (!strcmp(name
, "ManualFeed"))
1607 header
->ManualFeed
= !strcmp(value
, "true");
1608 else if (!strcmp(name
, "cupsMediaPosition") || /* Compatibility */
1609 !strcmp(name
, "MediaPosition"))
1610 header
->MediaPosition
= atoi(value
);
1611 else if (!strcmp(name
, "MediaWeight"))
1612 header
->MediaWeight
= atoi(value
);
1613 else if (!strcmp(name
, "MirrorPrint"))
1614 header
->MirrorPrint
= !strcmp(value
, "true");
1615 else if (!strcmp(name
, "NegativePrint"))
1616 header
->NegativePrint
= !strcmp(value
, "true");
1617 else if (!strcmp(name
, "Orientation"))
1618 header
->Orientation
= atoi(value
);
1619 else if (!strcmp(name
, "OutputFaceUp"))
1620 header
->OutputFaceUp
= !strcmp(value
, "true");
1621 else if (!strcmp(name
, "Separations"))
1622 header
->Separations
= !strcmp(value
, "true");
1623 else if (!strcmp(name
, "TraySwitch"))
1624 header
->TraySwitch
= !strcmp(value
, "true");
1625 else if (!strcmp(name
, "Tumble"))
1626 header
->Tumble
= !strcmp(value
, "true");
1627 else if (!strcmp(name
, "cupsMediaType"))
1628 header
->cupsMediaType
= atoi(value
);
1629 else if (!strcmp(name
, "cupsBitsPerColor"))
1630 header
->cupsBitsPerColor
= atoi(value
);
1631 else if (!strcmp(name
, "cupsColorOrder"))
1632 header
->cupsColorOrder
= (cups_order_t
)atoi(value
);
1633 else if (!strcmp(name
, "cupsColorSpace"))
1634 header
->cupsColorSpace
= (cups_cspace_t
)atoi(value
);
1635 else if (!strcmp(name
, "cupsCompression"))
1636 header
->cupsCompression
= atoi(value
);
1637 else if (!strcmp(name
, "cupsRowCount"))
1638 header
->cupsRowCount
= atoi(value
);
1639 else if (!strcmp(name
, "cupsRowFeed"))
1640 header
->cupsRowFeed
= atoi(value
);
1641 else if (!strcmp(name
, "cupsRowStep"))
1642 header
->cupsRowStep
= atoi(value
);
1648 * 'format_CMY()' - Convert image data to CMY.
1652 format_CMY(cups_page_header2_t
*header
, /* I - Page header */
1653 unsigned char *row
, /* IO - Bitmap data for device */
1654 int y
, /* I - Current row */
1655 int z
, /* I - Current plane */
1656 int xsize
, /* I - Width of image data */
1657 int ysize
, /* I - Height of image data */
1658 int yerr0
, /* I - Top Y error */
1659 int yerr1
, /* I - Bottom Y error */
1660 cups_ib_t
*r0
, /* I - Primary image data */
1661 cups_ib_t
*r1
) /* I - Image data for interpolation */
1663 cups_ib_t
*ptr
, /* Pointer into row */
1664 *cptr
, /* Pointer into cyan */
1665 *mptr
, /* Pointer into magenta */
1666 *yptr
, /* Pointer into yellow */
1667 bitmask
; /* Current mask for pixel */
1668 int bitoffset
; /* Current offset in line */
1669 int bandwidth
; /* Width of a color band */
1670 int x
, /* Current X coordinate on page */
1671 *dither
; /* Pointer into dither array */
1680 bitoffset
= header
->cupsBitsPerPixel
* ((header
->cupsWidth
- xsize
) / 2);
1683 bitoffset
= header
->cupsBitsPerPixel
* (header
->cupsWidth
- xsize
);
1687 ptr
= row
+ bitoffset
/ 8;
1688 bandwidth
= header
->cupsBytesPerLine
/ 3;
1690 switch (header
->cupsColorOrder
)
1692 case CUPS_ORDER_CHUNKED
:
1693 switch (header
->cupsBitsPerColor
)
1696 bitmask
= 64 >> (bitoffset
& 7);
1697 dither
= Floyd16xc16
[y
& 15];
1699 for (x
= xsize
; x
> 0; x
--)
1701 if (*r0
++ > dither
[x
& 15])
1705 if (*r0
++ > dither
[x
& 15])
1709 if (*r0
++ > dither
[x
& 15])
1723 dither
= Floyd8x8
[y
& 7];
1725 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
1727 if ((r0
[0] & 63) > dither
[x
& 7])
1728 *ptr
^= (0x30 & OnPixels
[r0
[0]]);
1730 *ptr
^= (0x30 & OffPixels
[r0
[0]]);
1732 if ((r0
[1] & 63) > dither
[x
& 7])
1733 *ptr
^= (0x0c & OnPixels
[r0
[1]]);
1735 *ptr
^= (0x0c & OffPixels
[r0
[1]]);
1737 if ((r0
[2] & 63) > dither
[x
& 7])
1738 *ptr
++ ^= (0x03 & OnPixels
[r0
[2]]);
1740 *ptr
++ ^= (0x03 & OffPixels
[r0
[2]]);
1745 dither
= Floyd4x4
[y
& 3];
1747 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
1749 if ((r0
[0] & 15) > dither
[x
& 3])
1750 *ptr
++ ^= (0x0f & OnPixels
[r0
[0]]);
1752 *ptr
++ ^= (0x0f & OffPixels
[r0
[0]]);
1754 if ((r0
[1] & 15) > dither
[x
& 3])
1755 *ptr
^= (0xf0 & OnPixels
[r0
[1]]);
1757 *ptr
^= (0xf0 & OffPixels
[r0
[1]]);
1759 if ((r0
[2] & 15) > dither
[x
& 3])
1760 *ptr
++ ^= (0x0f & OnPixels
[r0
[2]]);
1762 *ptr
++ ^= (0x0f & OffPixels
[r0
[2]]);
1767 for (x
= xsize
* 3; x
> 0; x
--, r0
++, r1
++)
1771 *ptr
++ = (*r0
* yerr0
+ *r1
* yerr1
) / ysize
;
1776 case CUPS_ORDER_BANDED
:
1778 mptr
= ptr
+ bandwidth
;
1779 yptr
= ptr
+ 2 * bandwidth
;
1781 switch (header
->cupsBitsPerColor
)
1784 bitmask
= 0x80 >> (bitoffset
& 7);
1785 dither
= Floyd16xc16
[y
& 15];
1787 for (x
= xsize
; x
> 0; x
--)
1789 if (*r0
++ > dither
[x
& 15])
1791 if (*r0
++ > dither
[x
& 15])
1793 if (*r0
++ > dither
[x
& 15])
1809 bitmask
= 0x0 >> (bitoffset
& 7);
1810 dither
= Floyd8x8
[y
& 7];
1812 for (x
= xsize
; x
> 0; x
--)
1814 if ((*r0
& 63) > dither
[x
& 7])
1815 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
1817 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
1819 if ((*r0
& 63) > dither
[x
& 7])
1820 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
1822 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
1824 if ((*r0
& 63) > dither
[x
& 7])
1825 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
1827 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
1843 bitmask
= 0xf0 >> (bitoffset
& 7);
1844 dither
= Floyd4x4
[y
& 3];
1846 for (x
= xsize
; x
> 0; x
--)
1848 if ((*r0
& 15) > dither
[x
& 3])
1849 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
1851 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
1853 if ((*r0
& 15) > dither
[x
& 3])
1854 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
1856 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
1858 if ((*r0
& 15) > dither
[x
& 3])
1859 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
1861 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
1863 if (bitmask
== 0xf0)
1877 for (x
= xsize
; x
> 0; x
--, r0
+= 3, r1
+= 3)
1882 *cptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
1887 *mptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
1892 *yptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
1898 case CUPS_ORDER_PLANAR
:
1899 switch (header
->cupsBitsPerColor
)
1902 bitmask
= 0x80 >> (bitoffset
& 7);
1903 dither
= Floyd16xc16
[y
& 15];
1908 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
1910 if (r0
[0] > dither
[x
& 15])
1924 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
1926 if (r0
[1] > dither
[x
& 15])
1940 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
1942 if (r0
[2] > dither
[x
& 15])
1958 bitmask
= 0x0 >> (bitoffset
& 7);
1959 dither
= Floyd8x8
[y
& 7];
1962 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
1964 if ((*r0
& 63) > dither
[x
& 7])
1965 *ptr
^= (bitmask
& OnPixels
[*r0
]);
1967 *ptr
^= (bitmask
& OffPixels
[*r0
]);
1981 bitmask
= 0xf0 >> (bitoffset
& 7);
1982 dither
= Floyd4x4
[y
& 3];
1985 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
1987 if ((*r0
& 15) > dither
[x
& 3])
1988 *ptr
^= (bitmask
& OnPixels
[*r0
]);
1990 *ptr
^= (bitmask
& OffPixels
[*r0
]);
1992 if (bitmask
== 0xf0)
2007 for (x
= xsize
; x
> 0; x
--, r0
+= 3, r1
+= 3)
2012 *ptr
++ = (*r0
* yerr0
+ *r1
* yerr1
) / ysize
;
2022 * 'format_CMYK()' - Convert image data to CMYK.
2026 format_CMYK(cups_page_header2_t
*header
, /* I - Page header */
2027 unsigned char *row
, /* IO - Bitmap data for device */
2028 int y
, /* I - Current row */
2029 int z
, /* I - Current plane */
2030 int xsize
, /* I - Width of image data */
2031 int ysize
, /* I - Height of image data */
2032 int yerr0
, /* I - Top Y error */
2033 int yerr1
, /* I - Bottom Y error */
2034 cups_ib_t
*r0
, /* I - Primary image data */
2035 cups_ib_t
*r1
) /* I - Image data for interpolation */
2037 cups_ib_t
*ptr
, /* Pointer into row */
2038 *cptr
, /* Pointer into cyan */
2039 *mptr
, /* Pointer into magenta */
2040 *yptr
, /* Pointer into yellow */
2041 *kptr
, /* Pointer into black */
2042 bitmask
; /* Current mask for pixel */
2043 int bitoffset
; /* Current offset in line */
2044 int bandwidth
; /* Width of a color band */
2045 int x
, /* Current X coordinate on page */
2046 *dither
; /* Pointer into dither array */
2055 bitoffset
= header
->cupsBitsPerPixel
* ((header
->cupsWidth
- xsize
) / 2);
2058 bitoffset
= header
->cupsBitsPerPixel
* (header
->cupsWidth
- xsize
);
2062 ptr
= row
+ bitoffset
/ 8;
2063 bandwidth
= header
->cupsBytesPerLine
/ 4;
2065 switch (header
->cupsColorOrder
)
2067 case CUPS_ORDER_CHUNKED
:
2068 switch (header
->cupsBitsPerColor
)
2071 bitmask
= 128 >> (bitoffset
& 7);
2072 dither
= Floyd16xc16
[y
& 15];
2074 for (x
= xsize
; x
> 0; x
--)
2076 if (*r0
++ > dither
[x
& 15])
2080 if (*r0
++ > dither
[x
& 15])
2084 if (*r0
++ > dither
[x
& 15])
2088 if (*r0
++ > dither
[x
& 15])
2102 dither
= Floyd8x8
[y
& 7];
2104 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
2106 if ((r0
[0] & 63) > dither
[x
& 7])
2107 *ptr
^= (0x0 & OnPixels
[r0
[0]]);
2109 *ptr
^= (0x0 & OffPixels
[r0
[0]]);
2111 if ((r0
[1] & 63) > dither
[x
& 7])
2112 *ptr
^= (0x30 & OnPixels
[r0
[1]]);
2114 *ptr
^= (0x30 & OffPixels
[r0
[1]]);
2116 if ((r0
[2] & 63) > dither
[x
& 7])
2117 *ptr
^= (0x0c & OnPixels
[r0
[2]]);
2119 *ptr
^= (0x0c & OffPixels
[r0
[2]]);
2121 if ((r0
[3] & 63) > dither
[x
& 7])
2122 *ptr
++ ^= (0x03 & OnPixels
[r0
[3]]);
2124 *ptr
++ ^= (0x03 & OffPixels
[r0
[3]]);
2129 dither
= Floyd4x4
[y
& 3];
2131 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
2133 if ((r0
[0] & 15) > dither
[x
& 3])
2134 *ptr
^= (0xf0 & OnPixels
[r0
[0]]);
2136 *ptr
^= (0xf0 & OffPixels
[r0
[0]]);
2138 if ((r0
[1] & 15) > dither
[x
& 3])
2139 *ptr
++ ^= (0x0f & OnPixels
[r0
[1]]);
2141 *ptr
++ ^= (0x0f & OffPixels
[r0
[1]]);
2143 if ((r0
[2] & 15) > dither
[x
& 3])
2144 *ptr
^= (0xf0 & OnPixels
[r0
[2]]);
2146 *ptr
^= (0xf0 & OffPixels
[r0
[2]]);
2148 if ((r0
[3] & 15) > dither
[x
& 3])
2149 *ptr
++ ^= (0x0f & OnPixels
[r0
[3]]);
2151 *ptr
++ ^= (0x0f & OffPixels
[r0
[3]]);
2156 for (x
= xsize
* 4; x
> 0; x
--, r0
++, r1
++)
2160 *ptr
++ = (*r0
* yerr0
+ *r1
* yerr1
) / ysize
;
2165 case CUPS_ORDER_BANDED
:
2167 mptr
= ptr
+ bandwidth
;
2168 yptr
= ptr
+ 2 * bandwidth
;
2169 kptr
= ptr
+ 3 * bandwidth
;
2171 switch (header
->cupsBitsPerColor
)
2174 bitmask
= 0x80 >> (bitoffset
& 7);
2175 dither
= Floyd16xc16
[y
& 15];
2177 for (x
= xsize
; x
> 0; x
--)
2179 if (*r0
++ > dither
[x
& 15])
2181 if (*r0
++ > dither
[x
& 15])
2183 if (*r0
++ > dither
[x
& 15])
2185 if (*r0
++ > dither
[x
& 15])
2202 bitmask
= 0x0 >> (bitoffset
& 7);
2203 dither
= Floyd8x8
[y
& 7];
2205 for (x
= xsize
; x
> 0; x
--)
2207 if ((*r0
& 63) > dither
[x
& 7])
2208 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
2210 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
2212 if ((*r0
& 63) > dither
[x
& 7])
2213 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
2215 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
2217 if ((*r0
& 63) > dither
[x
& 7])
2218 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
2220 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
2222 if ((*r0
& 63) > dither
[x
& 7])
2223 *kptr
^= (bitmask
& OnPixels
[*r0
++]);
2225 *kptr
^= (bitmask
& OffPixels
[*r0
++]);
2242 bitmask
= 0xf0 >> (bitoffset
& 7);
2243 dither
= Floyd4x4
[y
& 3];
2245 for (x
= xsize
; x
> 0; x
--)
2247 if ((*r0
& 15) > dither
[x
& 3])
2248 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
2250 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
2252 if ((*r0
& 15) > dither
[x
& 3])
2253 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
2255 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
2257 if ((*r0
& 15) > dither
[x
& 3])
2258 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
2260 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
2262 if ((*r0
& 15) > dither
[x
& 3])
2263 *kptr
^= (bitmask
& OnPixels
[*r0
++]);
2265 *kptr
^= (bitmask
& OffPixels
[*r0
++]);
2267 if (bitmask
== 0xf0)
2282 for (x
= xsize
; x
> 0; x
--, r0
+= 4, r1
+= 4)
2287 *cptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
2292 *mptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
2297 *yptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
2302 *kptr
++ = (r0
[3] * yerr0
+ r1
[3] * yerr1
) / ysize
;
2308 case CUPS_ORDER_PLANAR
:
2309 switch (header
->cupsBitsPerColor
)
2312 bitmask
= 0x80 >> (bitoffset
& 7);
2313 dither
= Floyd16xc16
[y
& 15];
2316 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
2318 if (*r0
> dither
[x
& 15])
2332 bitmask
= 0x0 >> (bitoffset
& 7);
2333 dither
= Floyd8x8
[y
& 7];
2336 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
2338 if ((*r0
& 63) > dither
[x
& 7])
2339 *ptr
^= (bitmask
& OnPixels
[*r0
]);
2341 *ptr
^= (bitmask
& OffPixels
[*r0
]);
2355 bitmask
= 0xf0 >> (bitoffset
& 7);
2356 dither
= Floyd4x4
[y
& 3];
2359 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
2361 if ((*r0
& 15) > dither
[x
& 3])
2362 *ptr
^= (bitmask
& OnPixels
[*r0
]);
2364 *ptr
^= (bitmask
& OffPixels
[*r0
]);
2366 if (bitmask
== 0xf0)
2381 for (x
= xsize
; x
> 0; x
--, r0
+= 4, r1
+= 4)
2386 *ptr
++ = (*r0
* yerr0
+ *r1
* yerr1
) / ysize
;
2396 * 'format_K()' - Convert image data to black.
2400 format_K(cups_page_header2_t
*header
, /* I - Page header */
2401 unsigned char *row
, /* IO - Bitmap data for device */
2402 int y
, /* I - Current row */
2403 int z
, /* I - Current plane */
2404 int xsize
, /* I - Width of image data */
2405 int ysize
, /* I - Height of image data */
2406 int yerr0
, /* I - Top Y error */
2407 int yerr1
, /* I - Bottom Y error */
2408 cups_ib_t
*r0
, /* I - Primary image data */
2409 cups_ib_t
*r1
) /* I - Image data for interpolation */
2411 cups_ib_t
*ptr
, /* Pointer into row */
2412 bitmask
; /* Current mask for pixel */
2413 int bitoffset
; /* Current offset in line */
2414 int x
, /* Current X coordinate on page */
2415 *dither
; /* Pointer into dither array */
2426 bitoffset
= header
->cupsBitsPerPixel
* ((header
->cupsWidth
- xsize
) / 2);
2429 bitoffset
= header
->cupsBitsPerPixel
* (header
->cupsWidth
- xsize
);
2433 ptr
= row
+ bitoffset
/ 8;
2435 switch (header
->cupsBitsPerColor
)
2438 bitmask
= 0x80 >> (bitoffset
& 7);
2439 dither
= Floyd16xc16
[y
& 15];
2441 for (x
= xsize
; x
> 0; x
--)
2443 if (*r0
++ > dither
[x
& 15])
2457 bitmask
= 0x0 >> (bitoffset
& 7);
2458 dither
= Floyd8x8
[y
& 7];
2460 for (x
= xsize
; x
> 0; x
--)
2462 if ((*r0
& 63) > dither
[x
& 7])
2463 *ptr
^= (bitmask
& OnPixels
[*r0
++]);
2465 *ptr
^= (bitmask
& OffPixels
[*r0
++]);
2479 bitmask
= 0xf0 >> (bitoffset
& 7);
2480 dither
= Floyd4x4
[y
& 3];
2482 for (x
= xsize
; x
> 0; x
--)
2484 if ((*r0
& 15) > dither
[x
& 3])
2485 *ptr
^= (bitmask
& OnPixels
[*r0
++]);
2487 *ptr
^= (bitmask
& OffPixels
[*r0
++]);
2489 if (bitmask
== 0xf0)
2501 for (x
= xsize
; x
> 0; x
--, r0
++, r1
++)
2506 *ptr
++ = (*r0
* yerr0
+ *r1
* yerr1
) / ysize
;
2514 * 'format_KCMY()' - Convert image data to KCMY.
2518 format_KCMY(cups_page_header2_t
*header
, /* I - Page header */
2519 unsigned char *row
, /* IO - Bitmap data for device */
2520 int y
, /* I - Current row */
2521 int z
, /* I - Current plane */
2522 int xsize
, /* I - Width of image data */
2523 int ysize
, /* I - Height of image data */
2524 int yerr0
, /* I - Top Y error */
2525 int yerr1
, /* I - Bottom Y error */
2526 cups_ib_t
*r0
, /* I - Primary image data */
2527 cups_ib_t
*r1
) /* I - Image data for interpolation */
2529 cups_ib_t
*ptr
, /* Pointer into row */
2530 *cptr
, /* Pointer into cyan */
2531 *mptr
, /* Pointer into magenta */
2532 *yptr
, /* Pointer into yellow */
2533 *kptr
, /* Pointer into black */
2534 bitmask
; /* Current mask for pixel */
2535 int bitoffset
; /* Current offset in line */
2536 int bandwidth
; /* Width of a color band */
2537 int x
, /* Current X coordinate on page */
2538 *dither
; /* Pointer into dither array */
2547 bitoffset
= header
->cupsBitsPerPixel
* ((header
->cupsWidth
- xsize
) / 2);
2550 bitoffset
= header
->cupsBitsPerPixel
* (header
->cupsWidth
- xsize
);
2554 ptr
= row
+ bitoffset
/ 8;
2555 bandwidth
= header
->cupsBytesPerLine
/ 4;
2557 switch (header
->cupsColorOrder
)
2559 case CUPS_ORDER_CHUNKED
:
2560 switch (header
->cupsBitsPerColor
)
2563 bitmask
= 128 >> (bitoffset
& 7);
2564 dither
= Floyd16xc16
[y
& 15];
2566 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
2568 if (r0
[3] > dither
[x
& 15])
2572 if (r0
[0] > dither
[x
& 15])
2576 if (r0
[1] > dither
[x
& 15])
2580 if (r0
[2] > dither
[x
& 15])
2594 dither
= Floyd8x8
[y
& 7];
2596 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
2598 if ((r0
[3] & 63) > dither
[x
& 7])
2599 *ptr
^= (0x0 & OnPixels
[r0
[3]]);
2601 *ptr
^= (0x0 & OffPixels
[r0
[3]]);
2603 if ((r0
[0] & 63) > dither
[x
& 7])
2604 *ptr
^= (0x30 & OnPixels
[r0
[0]]);
2606 *ptr
^= (0x30 & OffPixels
[r0
[0]]);
2608 if ((r0
[1] & 63) > dither
[x
& 7])
2609 *ptr
^= (0x0c & OnPixels
[r0
[1]]);
2611 *ptr
^= (0x0c & OffPixels
[r0
[1]]);
2613 if ((r0
[2] & 63) > dither
[x
& 7])
2614 *ptr
++ ^= (0x03 & OnPixels
[r0
[2]]);
2616 *ptr
++ ^= (0x03 & OffPixels
[r0
[2]]);
2621 dither
= Floyd4x4
[y
& 3];
2623 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
2625 if ((r0
[3] & 15) > dither
[x
& 3])
2626 *ptr
^= (0xf0 & OnPixels
[r0
[3]]);
2628 *ptr
^= (0xf0 & OffPixels
[r0
[3]]);
2630 if ((r0
[0] & 15) > dither
[x
& 3])
2631 *ptr
++ ^= (0x0f & OnPixels
[r0
[0]]);
2633 *ptr
++ ^= (0x0f & OffPixels
[r0
[0]]);
2635 if ((r0
[1] & 15) > dither
[x
& 3])
2636 *ptr
^= (0xf0 & OnPixels
[r0
[1]]);
2638 *ptr
^= (0xf0 & OffPixels
[r0
[1]]);
2640 if ((r0
[2] & 15) > dither
[x
& 3])
2641 *ptr
++ ^= (0x0f & OnPixels
[r0
[2]]);
2643 *ptr
++ ^= (0x0f & OffPixels
[r0
[2]]);
2648 for (x
= xsize
; x
> 0; x
--, r0
+= 4, r1
+= 4)
2653 *ptr
++ = (r0
[3] * yerr0
+ r1
[3] * yerr1
) / ysize
;
2658 *ptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
2663 *ptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
2668 *ptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
2674 case CUPS_ORDER_BANDED
:
2676 cptr
= ptr
+ bandwidth
;
2677 mptr
= ptr
+ 2 * bandwidth
;
2678 yptr
= ptr
+ 3 * bandwidth
;
2680 switch (header
->cupsBitsPerColor
)
2683 bitmask
= 0x80 >> (bitoffset
& 7);
2684 dither
= Floyd16xc16
[y
& 15];
2686 for (x
= xsize
; x
> 0; x
--)
2688 if (*r0
++ > dither
[x
& 15])
2690 if (*r0
++ > dither
[x
& 15])
2692 if (*r0
++ > dither
[x
& 15])
2694 if (*r0
++ > dither
[x
& 15])
2711 bitmask
= 0x0 >> (bitoffset
& 7);
2712 dither
= Floyd8x8
[y
& 7];
2714 for (x
= xsize
; x
> 0; x
--)
2716 if ((*r0
& 63) > dither
[x
& 7])
2717 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
2719 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
2721 if ((*r0
& 63) > dither
[x
& 7])
2722 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
2724 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
2726 if ((*r0
& 63) > dither
[x
& 7])
2727 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
2729 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
2731 if ((*r0
& 63) > dither
[x
& 7])
2732 *kptr
^= (bitmask
& OnPixels
[*r0
++]);
2734 *kptr
^= (bitmask
& OffPixels
[*r0
++]);
2751 bitmask
= 0xf0 >> (bitoffset
& 7);
2752 dither
= Floyd4x4
[y
& 3];
2754 for (x
= xsize
; x
> 0; x
--)
2756 if ((*r0
& 15) > dither
[x
& 3])
2757 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
2759 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
2761 if ((*r0
& 15) > dither
[x
& 3])
2762 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
2764 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
2766 if ((*r0
& 15) > dither
[x
& 3])
2767 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
2769 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
2771 if ((*r0
& 15) > dither
[x
& 3])
2772 *kptr
^= (bitmask
& OnPixels
[*r0
++]);
2774 *kptr
^= (bitmask
& OffPixels
[*r0
++]);
2776 if (bitmask
== 0xf0)
2791 for (x
= xsize
; x
> 0; x
--, r0
+= 4, r1
+= 4)
2796 *cptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
2801 *mptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
2806 *yptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
2811 *kptr
++ = (r0
[3] * yerr0
+ r1
[3] * yerr1
) / ysize
;
2817 case CUPS_ORDER_PLANAR
:
2818 switch (header
->cupsBitsPerColor
)
2821 bitmask
= 0x80 >> (bitoffset
& 7);
2822 dither
= Floyd16xc16
[y
& 15];
2828 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
2830 if (*r0
> dither
[x
& 15])
2844 bitmask
= 0x0 >> (bitoffset
& 7);
2845 dither
= Floyd8x8
[y
& 7];
2851 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
2853 if ((*r0
& 63) > dither
[x
& 7])
2854 *ptr
^= (bitmask
& OnPixels
[*r0
]);
2856 *ptr
^= (bitmask
& OffPixels
[*r0
]);
2870 bitmask
= 0xf0 >> (bitoffset
& 7);
2871 dither
= Floyd4x4
[y
& 3];
2877 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
2879 if ((*r0
& 15) > dither
[x
& 3])
2880 *ptr
^= (bitmask
& OnPixels
[*r0
]);
2882 *ptr
^= (bitmask
& OffPixels
[*r0
]);
2884 if (bitmask
== 0xf0)
2907 for (x
= xsize
; x
> 0; x
--, r0
+= 4, r1
+= 4)
2912 *ptr
++ = (*r0
* yerr0
+ *r1
* yerr1
) / ysize
;
2922 * 'format_KCMYcm()' - Convert image data to KCMYcm.
2926 format_KCMYcm(cups_page_header2_t
*header
,/* I - Page header */
2927 unsigned char *row
, /* IO - Bitmap data for device */
2928 int y
, /* I - Current row */
2929 int z
, /* I - Current plane */
2930 int xsize
,/* I - Width of image data */
2931 int ysize
,/* I - Height of image data */
2932 int yerr0
,/* I - Top Y error */
2933 int yerr1
,/* I - Bottom Y error */
2934 cups_ib_t
*r0
, /* I - Primary image data */
2935 cups_ib_t
*r1
) /* I - Image data for interpolation */
2937 int pc
, pm
, py
, pk
; /* Cyan, magenta, yellow, and black values */
2938 cups_ib_t
*ptr
, /* Pointer into row */
2939 *cptr
, /* Pointer into cyan */
2940 *mptr
, /* Pointer into magenta */
2941 *yptr
, /* Pointer into yellow */
2942 *kptr
, /* Pointer into black */
2943 *lcptr
, /* Pointer into light cyan */
2944 *lmptr
, /* Pointer into light magenta */
2945 bitmask
; /* Current mask for pixel */
2946 int bitoffset
; /* Current offset in line */
2947 int bandwidth
; /* Width of a color band */
2948 int x
, /* Current X coordinate on page */
2949 *dither
; /* Pointer into dither array */
2958 bitoffset
= header
->cupsBitsPerPixel
* ((header
->cupsWidth
- xsize
) / 2);
2961 bitoffset
= header
->cupsBitsPerPixel
* (header
->cupsWidth
- xsize
);
2965 ptr
= row
+ bitoffset
/ 8;
2966 if (header
->cupsBitsPerColor
== 1)
2967 bandwidth
= header
->cupsBytesPerLine
/ 6;
2969 bandwidth
= header
->cupsBytesPerLine
/ 4;
2971 switch (header
->cupsColorOrder
)
2973 case CUPS_ORDER_CHUNKED
:
2974 switch (header
->cupsBitsPerColor
)
2977 dither
= Floyd16xc16
[y
& 15];
2979 for (x
= xsize
; x
> 0; x
--)
2981 pc
= *r0
++ > dither
[x
& 15];
2982 pm
= *r0
++ > dither
[x
& 15];
2983 py
= *r0
++ > dither
[x
& 15];
2984 pk
= *r0
++ > dither
[x
& 15];
2987 *ptr
++ ^= 32; /* Black */
2989 *ptr
++ ^= 17; /* Blue (cyan + light magenta) */
2991 *ptr
++ ^= 6; /* Green (light cyan + yellow) */
2993 *ptr
++ ^= 12; /* Red (magenta + yellow) */
3004 for (x
= xsize
; x
> 0; x
--, r0
+= 4, r1
+= 4)
3009 *ptr
++ = (r0
[3] * yerr0
+ r1
[3] * yerr1
) / ysize
;
3014 *ptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
3019 *ptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
3024 *ptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
3030 case CUPS_ORDER_BANDED
:
3032 cptr
= ptr
+ bandwidth
;
3033 mptr
= ptr
+ 2 * bandwidth
;
3034 yptr
= ptr
+ 3 * bandwidth
;
3035 lcptr
= ptr
+ 4 * bandwidth
;
3036 lmptr
= ptr
+ 5 * bandwidth
;
3038 switch (header
->cupsBitsPerColor
)
3041 bitmask
= 0x80 >> (bitoffset
& 7);
3042 dither
= Floyd16xc16
[y
& 15];
3044 for (x
= xsize
; x
> 0; x
--)
3046 pc
= *r0
++ > dither
[x
& 15];
3047 pm
= *r0
++ > dither
[x
& 15];
3048 py
= *r0
++ > dither
[x
& 15];
3049 pk
= *r0
++ > dither
[x
& 15];
3052 *kptr
^= bitmask
; /* Black */
3055 *cptr
^= bitmask
; /* Blue (cyan + light magenta) */
3060 *lcptr
^= bitmask
; /* Green (light cyan + yellow) */
3065 *mptr
^= bitmask
; /* Red (magenta + yellow) */
3091 for (x
= xsize
; x
> 0; x
--, r0
+= 4, r1
+= 4)
3096 *cptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
3101 *mptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
3106 *yptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
3111 *kptr
++ = (r0
[3] * yerr0
+ r1
[3] * yerr1
) / ysize
;
3117 case CUPS_ORDER_PLANAR
:
3118 switch (header
->cupsBitsPerColor
)
3121 bitmask
= 0x80 >> (bitoffset
& 7);
3122 dither
= Floyd16xc16
[y
& 15];
3127 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
3129 if (r0
[3] > dither
[x
& 15])
3143 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
3145 if (r0
[0] > dither
[x
& 15] &&
3146 r0
[2] < dither
[x
& 15])
3160 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
3162 if (r0
[1] > dither
[x
& 15] &&
3163 (r0
[0] < dither
[x
& 15] ||
3164 r0
[2] > dither
[x
& 15]))
3178 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
3180 if (r0
[2] > dither
[x
& 15] &&
3181 (r0
[0] < dither
[x
& 15] ||
3182 r0
[1] < dither
[x
& 15]))
3196 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
3198 if (r0
[0] > dither
[x
& 15] &&
3199 r0
[2] > dither
[x
& 15])
3213 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
3215 if (r0
[0] > dither
[x
& 15] &&
3216 r0
[1] > dither
[x
& 15] &&
3217 r0
[2] < dither
[x
& 15])
3244 for (x
= xsize
; x
> 0; x
--, r0
+= 4, r1
+= 4)
3249 *ptr
++ = (*r0
* yerr0
+ *r1
* yerr1
) / ysize
;
3259 * 'format_RGBA()' - Convert image data to RGBA/RGBW.
3263 format_RGBA(cups_page_header2_t
*header
, /* I - Page header */
3264 unsigned char *row
, /* IO - Bitmap data for device */
3265 int y
, /* I - Current row */
3266 int z
, /* I - Current plane */
3267 int xsize
, /* I - Width of image data */
3268 int ysize
, /* I - Height of image data */
3269 int yerr0
, /* I - Top Y error */
3270 int yerr1
, /* I - Bottom Y error */
3271 cups_ib_t
*r0
, /* I - Primary image data */
3272 cups_ib_t
*r1
) /* I - Image data for interpolation */
3274 cups_ib_t
*ptr
, /* Pointer into row */
3275 *cptr
, /* Pointer into cyan */
3276 *mptr
, /* Pointer into magenta */
3277 *yptr
, /* Pointer into yellow */
3278 bitmask
; /* Current mask for pixel */
3279 int bitoffset
; /* Current offset in line */
3280 int bandwidth
; /* Width of a color band */
3281 int x
, /* Current X coordinate on page */
3282 *dither
; /* Pointer into dither array */
3291 bitoffset
= header
->cupsBitsPerPixel
* ((header
->cupsWidth
- xsize
) / 2);
3294 bitoffset
= header
->cupsBitsPerPixel
* (header
->cupsWidth
- xsize
);
3298 ptr
= row
+ bitoffset
/ 8;
3299 bandwidth
= header
->cupsBytesPerLine
/ 4;
3301 switch (header
->cupsColorOrder
)
3303 case CUPS_ORDER_CHUNKED
:
3304 switch (header
->cupsBitsPerColor
)
3307 bitmask
= 128 >> (bitoffset
& 7);
3308 dither
= Floyd16xc16
[y
& 15];
3310 for (x
= xsize
; x
> 0; x
--)
3312 if (*r0
++ > dither
[x
& 15])
3316 if (*r0
++ > dither
[x
& 15])
3320 if (*r0
++ > dither
[x
& 15])
3337 dither
= Floyd8x8
[y
& 7];
3339 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3341 if ((r0
[0] & 63) > dither
[x
& 7])
3342 *ptr
^= (0x0 & OnPixels
[r0
[0]]);
3344 *ptr
^= (0x0 & OffPixels
[r0
[0]]);
3346 if ((r0
[1] & 63) > dither
[x
& 7])
3347 *ptr
^= (0x30 & OnPixels
[r0
[1]]);
3349 *ptr
^= (0x30 & OffPixels
[r0
[1]]);
3351 if ((r0
[2] & 63) > dither
[x
& 7])
3352 *ptr
^= (0x0c & OnPixels
[r0
[2]]);
3354 *ptr
^= (0x0c & OffPixels
[r0
[2]]);
3361 dither
= Floyd4x4
[y
& 3];
3363 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3365 if ((r0
[0] & 15) > dither
[x
& 3])
3366 *ptr
^= (0xf0 & OnPixels
[r0
[0]]);
3368 *ptr
^= (0xf0 & OffPixels
[r0
[0]]);
3370 if ((r0
[1] & 15) > dither
[x
& 3])
3371 *ptr
++ ^= (0x0f & OnPixels
[r0
[1]]);
3373 *ptr
++ ^= (0x0f & OffPixels
[r0
[1]]);
3375 if ((r0
[2] & 15) > dither
[x
& 3])
3376 *ptr
^= (0xf0 & OnPixels
[r0
[2]]);
3378 *ptr
^= (0xf0 & OffPixels
[r0
[2]]);
3385 for (x
= xsize
; x
> 0; x
--, r0
+= 3, r1
+= 3)
3390 *ptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
3395 *ptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
3400 *ptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
3408 case CUPS_ORDER_BANDED
:
3410 mptr
= ptr
+ bandwidth
;
3411 yptr
= ptr
+ 2 * bandwidth
;
3413 memset(ptr
+ 3 * bandwidth
, 255, bandwidth
);
3415 switch (header
->cupsBitsPerColor
)
3418 bitmask
= 0x80 >> (bitoffset
& 7);
3419 dither
= Floyd16xc16
[y
& 15];
3421 for (x
= xsize
; x
> 0; x
--)
3423 if (*r0
++ > dither
[x
& 15])
3425 if (*r0
++ > dither
[x
& 15])
3427 if (*r0
++ > dither
[x
& 15])
3443 bitmask
= 0x0 >> (bitoffset
& 7);
3444 dither
= Floyd8x8
[y
& 7];
3446 for (x
= xsize
; x
> 0; x
--)
3448 if ((*r0
& 63) > dither
[x
& 7])
3449 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
3451 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
3453 if ((*r0
& 63) > dither
[x
& 7])
3454 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
3456 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
3458 if ((*r0
& 63) > dither
[x
& 7])
3459 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
3461 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
3477 bitmask
= 0xf0 >> (bitoffset
& 7);
3478 dither
= Floyd4x4
[y
& 3];
3480 for (x
= xsize
; x
> 0; x
--)
3482 if ((*r0
& 15) > dither
[x
& 3])
3483 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
3485 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
3487 if ((*r0
& 15) > dither
[x
& 3])
3488 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
3490 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
3492 if ((*r0
& 15) > dither
[x
& 3])
3493 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
3495 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
3497 if (bitmask
== 0xf0)
3511 for (x
= xsize
; x
> 0; x
--, r0
+= 3, r1
+= 3)
3516 *cptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
3521 *mptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
3526 *yptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
3532 case CUPS_ORDER_PLANAR
:
3535 memset(row
, 255, header
->cupsBytesPerLine
);
3539 switch (header
->cupsBitsPerColor
)
3542 bitmask
= 0x80 >> (bitoffset
& 7);
3543 dither
= Floyd16xc16
[y
& 15];
3548 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3550 if (r0
[0] > dither
[x
& 15])
3564 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3566 if (r0
[1] > dither
[x
& 15])
3580 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3582 if (r0
[2] > dither
[x
& 15])
3598 bitmask
= 0x0 >> (bitoffset
& 7);
3599 dither
= Floyd8x8
[y
& 7];
3602 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3604 if ((*r0
& 63) > dither
[x
& 7])
3605 *ptr
^= (bitmask
& OnPixels
[*r0
]);
3607 *ptr
^= (bitmask
& OffPixels
[*r0
]);
3621 bitmask
= 0xf0 >> (bitoffset
& 7);
3622 dither
= Floyd4x4
[y
& 3];
3625 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3627 if ((*r0
& 15) > dither
[x
& 3])
3628 *ptr
^= (bitmask
& OnPixels
[*r0
]);
3630 *ptr
^= (bitmask
& OffPixels
[*r0
]);
3632 if (bitmask
== 0xf0)
3647 for (x
= xsize
; x
> 0; x
--, r0
+= 3, r1
+= 3)
3652 *ptr
++ = (*r0
* yerr0
+ *r1
* yerr1
) / ysize
;
3662 * 'format_W()' - Convert image data to luminance.
3666 format_W(cups_page_header2_t
*header
, /* I - Page header */
3667 unsigned char *row
, /* IO - Bitmap data for device */
3668 int y
, /* I - Current row */
3669 int z
, /* I - Current plane */
3670 int xsize
, /* I - Width of image data */
3671 int ysize
, /* I - Height of image data */
3672 int yerr0
, /* I - Top Y error */
3673 int yerr1
, /* I - Bottom Y error */
3674 cups_ib_t
*r0
, /* I - Primary image data */
3675 cups_ib_t
*r1
) /* I - Image data for interpolation */
3677 cups_ib_t
*ptr
, /* Pointer into row */
3678 bitmask
; /* Current mask for pixel */
3679 int bitoffset
; /* Current offset in line */
3680 int x
, /* Current X coordinate on page */
3681 *dither
; /* Pointer into dither array */
3692 bitoffset
= header
->cupsBitsPerPixel
* ((header
->cupsWidth
- xsize
) / 2);
3695 bitoffset
= header
->cupsBitsPerPixel
* (header
->cupsWidth
- xsize
);
3699 ptr
= row
+ bitoffset
/ 8;
3701 switch (header
->cupsBitsPerColor
)
3704 bitmask
= 0x80 >> (bitoffset
& 7);
3705 dither
= Floyd16xc16
[y
& 15];
3707 for (x
= xsize
; x
> 0; x
--)
3709 if (*r0
++ > dither
[x
& 15])
3723 bitmask
= 0x0 >> (bitoffset
& 7);
3724 dither
= Floyd8x8
[y
& 7];
3726 for (x
= xsize
; x
> 0; x
--)
3728 if ((*r0
& 63) > dither
[x
& 7])
3729 *ptr
^= (bitmask
& OnPixels
[*r0
++]);
3731 *ptr
^= (bitmask
& OffPixels
[*r0
++]);
3745 bitmask
= 0xf0 >> (bitoffset
& 7);
3746 dither
= Floyd4x4
[y
& 3];
3748 for (x
= xsize
; x
> 0; x
--)
3750 if ((*r0
& 15) > dither
[x
& 3])
3751 *ptr
^= (bitmask
& OnPixels
[*r0
++]);
3753 *ptr
^= (bitmask
& OffPixels
[*r0
++]);
3755 if (bitmask
== 0xf0)
3767 for (x
= xsize
; x
> 0; x
--, r0
++, r1
++)
3772 *ptr
++ = (*r0
* yerr0
+ *r1
* yerr1
) / ysize
;
3780 * 'format_YMC()' - Convert image data to YMC.
3784 format_YMC(cups_page_header2_t
*header
, /* I - Page header */
3785 unsigned char *row
, /* IO - Bitmap data for device */
3786 int y
, /* I - Current row */
3787 int z
, /* I - Current plane */
3788 int xsize
, /* I - Width of image data */
3789 int ysize
, /* I - Height of image data */
3790 int yerr0
, /* I - Top Y error */
3791 int yerr1
, /* I - Bottom Y error */
3792 cups_ib_t
*r0
, /* I - Primary image data */
3793 cups_ib_t
*r1
) /* I - Image data for interpolation */
3795 cups_ib_t
*ptr
, /* Pointer into row */
3796 *cptr
, /* Pointer into cyan */
3797 *mptr
, /* Pointer into magenta */
3798 *yptr
, /* Pointer into yellow */
3799 bitmask
; /* Current mask for pixel */
3800 int bitoffset
; /* Current offset in line */
3801 int bandwidth
; /* Width of a color band */
3802 int x
, /* Current X coordinate on page */
3803 *dither
; /* Pointer into dither array */
3812 bitoffset
= header
->cupsBitsPerPixel
* ((header
->cupsWidth
- xsize
) / 2);
3815 bitoffset
= header
->cupsBitsPerPixel
* (header
->cupsWidth
- xsize
);
3819 ptr
= row
+ bitoffset
/ 8;
3820 bandwidth
= header
->cupsBytesPerLine
/ 3;
3822 switch (header
->cupsColorOrder
)
3824 case CUPS_ORDER_CHUNKED
:
3825 switch (header
->cupsBitsPerColor
)
3828 bitmask
= 64 >> (bitoffset
& 7);
3829 dither
= Floyd16xc16
[y
& 15];
3831 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3833 if (r0
[2] > dither
[x
& 15])
3837 if (r0
[1] > dither
[x
& 15])
3841 if (r0
[0] > dither
[x
& 15])
3855 dither
= Floyd8x8
[y
& 7];
3857 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3859 if ((r0
[2] & 63) > dither
[x
& 7])
3860 *ptr
^= (0x30 & OnPixels
[r0
[2]]);
3862 *ptr
^= (0x30 & OffPixels
[r0
[2]]);
3864 if ((r0
[1] & 63) > dither
[x
& 7])
3865 *ptr
^= (0x0c & OnPixels
[r0
[1]]);
3867 *ptr
^= (0x0c & OffPixels
[r0
[1]]);
3869 if ((r0
[0] & 63) > dither
[x
& 7])
3870 *ptr
++ ^= (0x03 & OnPixels
[r0
[0]]);
3872 *ptr
++ ^= (0x03 & OffPixels
[r0
[0]]);
3877 dither
= Floyd4x4
[y
& 3];
3879 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3881 if ((r0
[2] & 15) > dither
[x
& 3])
3882 *ptr
++ ^= (0x0f & OnPixels
[r0
[2]]);
3884 *ptr
++ ^= (0x0f & OffPixels
[r0
[2]]);
3886 if ((r0
[1] & 15) > dither
[x
& 3])
3887 *ptr
^= (0xf0 & OnPixels
[r0
[1]]);
3889 *ptr
^= (0xf0 & OffPixels
[r0
[1]]);
3891 if ((r0
[0] & 15) > dither
[x
& 3])
3892 *ptr
++ ^= (0x0f & OnPixels
[r0
[0]]);
3894 *ptr
++ ^= (0x0f & OffPixels
[r0
[0]]);
3899 for (x
= xsize
; x
> 0; x
--, r0
+= 3, r1
+= 3)
3904 *ptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
3909 *ptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
3914 *ptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
3920 case CUPS_ORDER_BANDED
:
3922 mptr
= ptr
+ bandwidth
;
3923 cptr
= ptr
+ 2 * bandwidth
;
3925 switch (header
->cupsBitsPerColor
)
3928 bitmask
= 0x80 >> (bitoffset
& 7);
3929 dither
= Floyd16xc16
[y
& 15];
3931 for (x
= xsize
; x
> 0; x
--)
3933 if (*r0
++ > dither
[x
& 15])
3935 if (*r0
++ > dither
[x
& 15])
3937 if (*r0
++ > dither
[x
& 15])
3953 bitmask
= 0x0 >> (bitoffset
& 7);
3954 dither
= Floyd8x8
[y
& 7];
3956 for (x
= xsize
; x
> 0; x
--)
3958 if ((*r0
& 63) > dither
[x
& 7])
3959 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
3961 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
3963 if ((*r0
& 63) > dither
[x
& 7])
3964 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
3966 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
3968 if ((*r0
& 63) > dither
[x
& 7])
3969 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
3971 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
3987 bitmask
= 0xf0 >> (bitoffset
& 7);
3988 dither
= Floyd4x4
[y
& 3];
3990 for (x
= xsize
; x
> 0; x
--)
3992 if ((*r0
& 15) > dither
[x
& 3])
3993 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
3995 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
3997 if ((*r0
& 15) > dither
[x
& 3])
3998 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
4000 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
4002 if ((*r0
& 15) > dither
[x
& 3])
4003 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
4005 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
4007 if (bitmask
== 0xf0)
4021 for (x
= xsize
; x
> 0; x
--, r0
+= 3, r1
+= 3)
4026 *cptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
4031 *mptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
4036 *yptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
4042 case CUPS_ORDER_PLANAR
:
4043 switch (header
->cupsBitsPerColor
)
4046 bitmask
= 0x80 >> (bitoffset
& 7);
4047 dither
= Floyd16xc16
[y
& 15];
4052 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
4054 if (r0
[0] > dither
[x
& 15])
4068 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
4070 if (r0
[1] > dither
[x
& 15])
4084 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
4086 if (r0
[2] > dither
[x
& 15])
4102 bitmask
= 0x0 >> (bitoffset
& 7);
4103 dither
= Floyd8x8
[y
& 7];
4107 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
4109 if ((*r0
& 63) > dither
[x
& 7])
4110 *ptr
^= (bitmask
& OnPixels
[*r0
]);
4112 *ptr
^= (bitmask
& OffPixels
[*r0
]);
4126 bitmask
= 0xf0 >> (bitoffset
& 7);
4127 dither
= Floyd4x4
[y
& 3];
4131 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
4133 if ((*r0
& 15) > dither
[x
& 3])
4134 *ptr
^= (bitmask
& OnPixels
[*r0
]);
4136 *ptr
^= (bitmask
& OffPixels
[*r0
]);
4138 if (bitmask
== 0xf0)
4154 for (x
= xsize
; x
> 0; x
--, r0
+= 3, r1
+= 3)
4159 *ptr
++ = (*r0
* yerr0
+ *r1
* yerr1
) / ysize
;
4169 * 'format_YMCK()' - Convert image data to YMCK.
4173 format_YMCK(cups_page_header2_t
*header
, /* I - Page header */
4174 unsigned char *row
, /* IO - Bitmap data for device */
4175 int y
, /* I - Current row */
4176 int z
, /* I - Current plane */
4177 int xsize
, /* I - Width of image data */
4178 int ysize
, /* I - Height of image data */
4179 int yerr0
, /* I - Top Y error */
4180 int yerr1
, /* I - Bottom Y error */
4181 cups_ib_t
*r0
, /* I - Primary image data */
4182 cups_ib_t
*r1
) /* I - Image data for interpolation */
4184 cups_ib_t
*ptr
, /* Pointer into row */
4185 *cptr
, /* Pointer into cyan */
4186 *mptr
, /* Pointer into magenta */
4187 *yptr
, /* Pointer into yellow */
4188 *kptr
, /* Pointer into black */
4189 bitmask
; /* Current mask for pixel */
4190 int bitoffset
; /* Current offset in line */
4191 int bandwidth
; /* Width of a color band */
4192 int x
, /* Current X coordinate on page */
4193 *dither
; /* Pointer into dither array */
4202 bitoffset
= header
->cupsBitsPerPixel
* ((header
->cupsWidth
- xsize
) / 2);
4205 bitoffset
= header
->cupsBitsPerPixel
* (header
->cupsWidth
- xsize
);
4209 ptr
= row
+ bitoffset
/ 8;
4210 bandwidth
= header
->cupsBytesPerLine
/ 4;
4212 switch (header
->cupsColorOrder
)
4214 case CUPS_ORDER_CHUNKED
:
4215 switch (header
->cupsBitsPerColor
)
4218 bitmask
= 128 >> (bitoffset
& 7);
4219 dither
= Floyd16xc16
[y
& 15];
4221 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
4223 if (r0
[2] > dither
[x
& 15])
4227 if (r0
[1] > dither
[x
& 15])
4231 if (r0
[0] > dither
[x
& 15])
4235 if (r0
[3] > dither
[x
& 15])
4250 dither
= Floyd8x8
[y
& 7];
4252 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
4254 if ((r0
[2] & 63) > dither
[x
& 7])
4255 *ptr
^= (0x0 & OnPixels
[r0
[2]]);
4257 *ptr
^= (0x0 & OffPixels
[r0
[2]]);
4259 if ((r0
[1] & 63) > dither
[x
& 7])
4260 *ptr
^= (0x30 & OnPixels
[r0
[1]]);
4262 *ptr
^= (0x30 & OffPixels
[r0
[1]]);
4264 if ((r0
[0] & 63) > dither
[x
& 7])
4265 *ptr
^= (0x0c & OnPixels
[r0
[0]]);
4267 *ptr
^= (0x0c & OffPixels
[r0
[0]]);
4269 if ((r0
[3] & 63) > dither
[x
& 7])
4270 *ptr
++ ^= (0x03 & OnPixels
[r0
[3]]);
4272 *ptr
++ ^= (0x03 & OffPixels
[r0
[3]]);
4277 dither
= Floyd4x4
[y
& 3];
4279 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
4281 if ((r0
[2] & 15) > dither
[x
& 3])
4282 *ptr
^= (0xf0 & OnPixels
[r0
[2]]);
4284 *ptr
^= (0xf0 & OffPixels
[r0
[2]]);
4286 if ((r0
[1] & 15) > dither
[x
& 3])
4287 *ptr
++ ^= (0x0f & OnPixels
[r0
[1]]);
4289 *ptr
++ ^= (0x0f & OffPixels
[r0
[1]]);
4291 if ((r0
[0] & 15) > dither
[x
& 3])
4292 *ptr
^= (0xf0 & OnPixels
[r0
[0]]);
4294 *ptr
^= (0xf0 & OffPixels
[r0
[0]]);
4296 if ((r0
[3] & 15) > dither
[x
& 3])
4297 *ptr
++ ^= (0x0f & OnPixels
[r0
[3]]);
4299 *ptr
++ ^= (0x0f & OffPixels
[r0
[3]]);
4304 for (x
= xsize
; x
> 0; x
--, r0
+= 4, r1
+= 4)
4309 *ptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
4314 *ptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
4319 *ptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
4324 *ptr
++ = (r0
[3] * yerr0
+ r1
[3] * yerr1
) / ysize
;
4330 case CUPS_ORDER_BANDED
:
4332 mptr
= ptr
+ bandwidth
;
4333 cptr
= ptr
+ 2 * bandwidth
;
4334 kptr
= ptr
+ 3 * bandwidth
;
4336 switch (header
->cupsBitsPerColor
)
4339 bitmask
= 0x80 >> (bitoffset
& 7);
4340 dither
= Floyd16xc16
[y
& 15];
4342 for (x
= xsize
; x
> 0; x
--)
4344 if (*r0
++ > dither
[x
& 15])
4346 if (*r0
++ > dither
[x
& 15])
4348 if (*r0
++ > dither
[x
& 15])
4350 if (*r0
++ > dither
[x
& 15])
4368 bitmask
= 0x0 >> (bitoffset
& 7);
4369 dither
= Floyd8x8
[y
& 7];
4371 for (x
= xsize
; x
> 0; x
--)
4373 if ((*r0
& 63) > dither
[x
& 7])
4374 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
4376 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
4378 if ((*r0
& 63) > dither
[x
& 7])
4379 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
4381 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
4383 if ((*r0
& 63) > dither
[x
& 7])
4384 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
4386 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
4388 if ((*r0
& 63) > dither
[x
& 7])
4389 *kptr
^= (bitmask
& OnPixels
[*r0
++]);
4391 *kptr
^= (bitmask
& OffPixels
[*r0
++]);
4408 bitmask
= 0xf0 >> (bitoffset
& 7);
4409 dither
= Floyd4x4
[y
& 3];
4411 for (x
= xsize
; x
> 0; x
--)
4413 if ((*r0
& 15) > dither
[x
& 3])
4414 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
4416 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
4418 if ((*r0
& 15) > dither
[x
& 3])
4419 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
4421 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
4423 if ((*r0
& 15) > dither
[x
& 3])
4424 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
4426 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
4428 if ((*r0
& 15) > dither
[x
& 3])
4429 *kptr
^= (bitmask
& OnPixels
[*r0
++]);
4431 *kptr
^= (bitmask
& OffPixels
[*r0
++]);
4433 if (bitmask
== 0xf0)
4448 for (x
= xsize
; x
> 0; x
--, r0
+= 4, r1
+= 4)
4453 *cptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
4458 *mptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
4463 *yptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
4468 *kptr
++ = (r0
[3] * yerr0
+ r1
[3] * yerr1
) / ysize
;
4474 case CUPS_ORDER_PLANAR
:
4475 switch (header
->cupsBitsPerColor
)
4478 bitmask
= 0x80 >> (bitoffset
& 7);
4479 dither
= Floyd16xc16
[y
& 15];
4486 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
4488 if (*r0
> dither
[x
& 15])
4502 bitmask
= 0x0 >> (bitoffset
& 7);
4503 dither
= Floyd8x8
[y
& 7];
4509 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
4511 if ((*r0
& 63) > dither
[x
& 7])
4512 *ptr
^= (bitmask
& OnPixels
[*r0
]);
4514 *ptr
^= (bitmask
& OffPixels
[*r0
]);
4528 bitmask
= 0xf0 >> (bitoffset
& 7);
4529 dither
= Floyd4x4
[y
& 3];
4535 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
4537 if ((*r0
& 15) > dither
[x
& 3])
4538 *ptr
^= (bitmask
& OnPixels
[*r0
]);
4540 *ptr
^= (bitmask
& OffPixels
[*r0
]);
4542 if (bitmask
== 0xf0)
4565 for (x
= xsize
; x
> 0; x
--, r0
+= 4, r1
+= 4)
4570 *ptr
++ = (*r0
* yerr0
+ *r1
* yerr1
) / ysize
;
4580 * 'make_lut()' - Make a lookup table given gamma and brightness values.
4584 make_lut(cups_ib_t
*lut
, /* I - Lookup table */
4585 int colorspace
, /* I - Colorspace */
4586 float g
, /* I - Image gamma */
4587 float b
) /* I - Image brightness */
4589 int i
; /* Looping var */
4590 int v
; /* Current value */
4596 for (i
= 0; i
< 256; i
++)
4599 v
= 255.0 * b
* (1.0 - pow(1.0 - (float)i
/ 255.0, g
)) + 0.5;
4601 v
= 255.0 * (1.0 - b
* (1.0 - pow((float)i
/ 255.0, g
))) + 0.5;
4614 * End of "$Id: imagetoraster.c 5099 2006-02-13 02:46:10Z mike $".