2 * "$Id: imagetoraster.c 7306 2008-02-15 00:52:38Z mike $"
4 * Image file to raster filter for CUPS.
6 * Copyright 2007-2010 by Apple Inc.
7 * Copyright 1993-2007 by Easy Software Products.
9 * These coded instructions, statements, and computer programs are the
10 * property of Apple Inc. and are protected by Federal copyright
11 * law. Distribution and use rights are outlined in the file "LICENSE.txt"
12 * which should have been included with this file. If this file is
13 * file is missing or damaged, see the license at "http://www.cups.org/".
15 * This file is subject to the Apple OS-Developed Software exception.
19 * main() - Main entry...
20 * blank_line() - Clear a line buffer to the blank value...
21 * format_CMY() - Convert image data to CMY.
22 * format_CMYK() - Convert image data to CMYK.
23 * format_K() - Convert image data to black.
24 * format_KCMY() - Convert image data to KCMY.
25 * format_KCMYcm() - Convert image data to KCMYcm.
26 * format_RGBA() - Convert image data to RGBA/RGBW.
27 * format_W() - Convert image data to luminance.
28 * format_YMC() - Convert image data to YMC.
29 * format_YMCK() - Convert image data to YMCK.
30 * make_lut() - Make a lookup table given gamma and brightness values.
31 * raster_cb() - Validate the page header.
35 * Include necessary headers...
39 #include "image-private.h"
42 #include <cups/language-private.h>
49 int Flip
= 0, /* Flip/mirror pages */
50 XPosition
= 0, /* Horizontal position on page */
51 YPosition
= 0, /* Vertical position on page */
52 Collate
= 0, /* Collate copies? */
53 Copies
= 1; /* Number of copies */
54 int Floyd16x16
[16][16] = /* Traditional Floyd ordered dither */
56 { 0, 128, 32, 160, 8, 136, 40, 168,
57 2, 130, 34, 162, 10, 138, 42, 170 },
58 { 192, 64, 224, 96, 200, 72, 232, 104,
59 194, 66, 226, 98, 202, 74, 234, 106 },
60 { 48, 176, 16, 144, 56, 184, 24, 152,
61 50, 178, 18, 146, 58, 186, 26, 154 },
62 { 240, 112, 208, 80, 248, 120, 216, 88,
63 242, 114, 210, 82, 250, 122, 218, 90 },
64 { 12, 140, 44, 172, 4, 132, 36, 164,
65 14, 142, 46, 174, 6, 134, 38, 166 },
66 { 204, 76, 236, 108, 196, 68, 228, 100,
67 206, 78, 238, 110, 198, 70, 230, 102 },
68 { 60, 188, 28, 156, 52, 180, 20, 148,
69 62, 190, 30, 158, 54, 182, 22, 150 },
70 { 252, 124, 220, 92, 244, 116, 212, 84,
71 254, 126, 222, 94, 246, 118, 214, 86 },
72 { 3, 131, 35, 163, 11, 139, 43, 171,
73 1, 129, 33, 161, 9, 137, 41, 169 },
74 { 195, 67, 227, 99, 203, 75, 235, 107,
75 193, 65, 225, 97, 201, 73, 233, 105 },
76 { 51, 179, 19, 147, 59, 187, 27, 155,
77 49, 177, 17, 145, 57, 185, 25, 153 },
78 { 243, 115, 211, 83, 251, 123, 219, 91,
79 241, 113, 209, 81, 249, 121, 217, 89 },
80 { 15, 143, 47, 175, 7, 135, 39, 167,
81 13, 141, 45, 173, 5, 133, 37, 165 },
82 { 207, 79, 239, 111, 199, 71, 231, 103,
83 205, 77, 237, 109, 197, 69, 229, 101 },
84 { 63, 191, 31, 159, 55, 183, 23, 151,
85 61, 189, 29, 157, 53, 181, 21, 149 },
86 { 254, 127, 223, 95, 247, 119, 215, 87,
87 253, 125, 221, 93, 245, 117, 213, 85 }
91 { 0, 32, 8, 40, 2, 34, 10, 42 },
92 { 48, 16, 56, 24, 50, 18, 58, 26 },
93 { 12, 44, 4, 36, 14, 46, 6, 38 },
94 { 60, 28, 52, 20, 62, 30, 54, 22 },
95 { 3, 35, 11, 43, 1, 33, 9, 41 },
96 { 51, 19, 59, 27, 49, 17, 57, 25 },
97 { 15, 47, 7, 39, 13, 45, 5, 37 },
98 { 63, 31, 55, 23, 61, 29, 53, 21 }
108 cups_ib_t OnPixels
[256], /* On-pixel LUT */
109 OffPixels
[256]; /* Off-pixel LUT */
116 static void blank_line(cups_page_header2_t
*header
, unsigned char *row
);
117 static void format_CMY(cups_page_header2_t
*header
, unsigned char *row
, int y
, int z
, int xsize
, int ysize
, int yerr0
, int yerr1
, cups_ib_t
*r0
, cups_ib_t
*r1
);
118 static void format_CMYK(cups_page_header2_t
*header
, unsigned char *row
, int y
, int z
, int xsize
, int ysize
, int yerr0
, int yerr1
, cups_ib_t
*r0
, cups_ib_t
*r1
);
119 static void format_K(cups_page_header2_t
*header
, unsigned char *row
, int y
, int z
, int xsize
, int ysize
, int yerr0
, int yerr1
, cups_ib_t
*r0
, cups_ib_t
*r1
);
120 static void format_KCMYcm(cups_page_header2_t
*header
, unsigned char *row
, int y
, int z
, int xsize
, int ysize
, int yerr0
, int yerr1
, cups_ib_t
*r0
, cups_ib_t
*r1
);
121 static void format_KCMY(cups_page_header2_t
*header
, unsigned char *row
, int y
, int z
, int xsize
, int ysize
, int yerr0
, int yerr1
, cups_ib_t
*r0
, cups_ib_t
*r1
);
122 #define format_RGB format_CMY
123 static void format_RGBA(cups_page_header2_t
*header
, unsigned char *row
, int y
, int z
, int xsize
, int ysize
, int yerr0
, int yerr1
, cups_ib_t
*r0
, cups_ib_t
*r1
);
124 static void format_W(cups_page_header2_t
*header
, unsigned char *row
, int y
, int z
, int xsize
, int ysize
, int yerr0
, int yerr1
, cups_ib_t
*r0
, cups_ib_t
*r1
);
125 static void format_YMC(cups_page_header2_t
*header
, unsigned char *row
, int y
, int z
, int xsize
, int ysize
, int yerr0
, int yerr1
, cups_ib_t
*r0
, cups_ib_t
*r1
);
126 static void format_YMCK(cups_page_header2_t
*header
, unsigned char *row
, int y
, int z
, int xsize
, int ysize
, int yerr0
, int yerr1
, cups_ib_t
*r0
, cups_ib_t
*r1
);
127 static void make_lut(cups_ib_t
*, int, float, float);
128 static int raster_cb(cups_page_header2_t
*header
, int preferred_bits
);
132 * 'main()' - Main entry...
135 int /* O - Exit status */
136 main(int argc
, /* I - Number of command-line arguments */
137 char *argv
[]) /* I - Command-line arguments */
139 int i
; /* Looping var */
140 cups_image_t
*img
; /* Image to print */
141 float xprint
, /* Printable area */
143 xinches
, /* Total size in inches */
145 float xsize
, /* Total size in points */
149 float aspect
; /* Aspect ratio */
150 int xpages
, /* # x pages */
151 ypages
, /* # y pages */
152 xpage
, /* Current x page */
153 ypage
, /* Current y page */
154 xtemp
, /* Bitmap width in pixels */
155 ytemp
, /* Bitmap height in pixels */
156 page
; /* Current page number */
157 int xc0
, yc0
, /* Corners of the page in image coords */
159 ppd_file_t
*ppd
; /* PPD file */
160 ppd_choice_t
*choice
; /* PPD option choice */
161 char *resolution
, /* Output resolution */
162 *media_type
; /* Media type */
163 ppd_profile_t
*profile
; /* Color profile */
164 ppd_profile_t userprofile
; /* User-specified profile */
165 cups_raster_t
*ras
; /* Raster stream */
166 cups_page_header2_t header
; /* Page header */
167 int num_options
; /* Number of print options */
168 cups_option_t
*options
; /* Print options */
169 const char *val
; /* Option value */
170 int slowcollate
, /* Collate copies the slow way */
171 slowcopies
; /* Make copies the "slow" way? */
172 float g
; /* Gamma correction value */
173 float b
; /* Brightness factor */
174 float zoom
; /* Zoom facter */
175 int xppi
, yppi
; /* Pixels-per-inch */
176 int hue
, sat
; /* Hue and saturation adjustment */
177 cups_izoom_t
*z
; /* Image zoom buffer */
178 cups_iztype_t zoom_type
; /* Image zoom type */
179 int primary
, /* Primary image colorspace */
180 secondary
; /* Secondary image colorspace */
181 cups_ib_t
*row
, /* Current row */
183 *r1
; /* Bottom row */
184 int y
, /* Current Y coordinate on page */
185 iy
, /* Current Y coordinate in image */
186 last_iy
, /* Previous Y coordinate in image */
187 yerr0
, /* Top Y error value */
188 yerr1
; /* Bottom Y error value */
189 cups_ib_t lut
[256]; /* Gamma/brightness LUT */
190 int plane
, /* Current color plane */
191 num_planes
; /* Number of color planes */
192 char filename
[1024]; /* Name of file to print */
196 * Make sure status messages are not buffered...
199 setbuf(stderr
, NULL
);
202 * Check command-line...
205 if (argc
< 6 || argc
> 7)
207 fprintf(stderr
, _("Usage: %s job-id user title copies options [file]\n"),
213 * See if we need to use the imagetops and pstoraster filters instead...
217 num_options
= cupsParseOptions(argv
[5], 0, &options
);
219 if (getenv("CLASSIFICATION") ||
220 cupsGetOption("page-label", num_options
, options
))
223 * Yes, fork a copy of pstoraster and then transfer control to imagetops...
226 int mypipes
[2]; /* New pipes for imagetops | pstoraster */
227 int pid
; /* PID of pstoraster */
230 cupsFreeOptions(num_options
, options
);
234 perror("ERROR: Unable to create pipes for imagetops | pstoraster");
238 if ((pid
= fork()) == 0)
241 * Child process for pstoraster... Assign new pipe input to pstoraster...
248 execlp("pstoraster", argv
[0], argv
[1], argv
[2], argv
[3], argv
[4], argv
[5],
250 perror("ERROR: Unable to exec pstoraster");
259 perror("ERROR: Unable to fork pstoraster");
264 * Update stdout so it points at the new pstoraster...
272 * Run imagetops to get the classification or page labelling that was
276 execlp("imagetops", argv
[0], argv
[1], argv
[2], argv
[3], argv
[4], argv
[5],
278 perror("ERROR: Unable to exec imagetops");
283 * Copy stdin as needed...
288 int fd
; /* File to write to */
289 char buffer
[8192]; /* Buffer to read into */
290 int bytes
; /* # of bytes to read */
293 if ((fd
= cupsTempFd(filename
, sizeof(filename
))) < 0)
295 perror("ERROR: Unable to copy image file");
299 fprintf(stderr
, "DEBUG: imagetoraster - copying to temp print file \"%s\"\n",
302 while ((bytes
= fread(buffer
, 1, sizeof(buffer
), stdin
)) > 0)
303 write(fd
, buffer
, bytes
);
308 strlcpy(filename
, argv
[6], sizeof(filename
));
311 * Process command-line options and write the prolog...
322 Copies
= atoi(argv
[4]);
324 ppd
= SetCommonOptions(num_options
, options
, 0);
326 if ((val
= cupsGetOption("multiple-document-handling", num_options
, options
)) != NULL
)
329 * This IPP attribute is unnecessarily complicated...
331 * single-document, separate-documents-collated-copies, and
332 * single-document-new-sheet all require collated copies.
334 * separate-documents-collated-copies allows for uncollated copies.
337 Collate
= strcasecmp(val
, "separate-documents-collated-copies") != 0;
340 if ((val
= cupsGetOption("Collate", num_options
, options
)) != NULL
&&
341 strcasecmp(val
, "True") == 0)
344 if ((val
= cupsGetOption("gamma", num_options
, options
)) != NULL
)
347 * Get gamma value from 1 to 10000...
350 g
= atoi(val
) * 0.001f
;
358 if ((val
= cupsGetOption("brightness", num_options
, options
)) != NULL
)
361 * Get brightness value from 10 to 1000.
364 b
= atoi(val
) * 0.01f
;
372 if ((val
= cupsGetOption("scaling", num_options
, options
)) != NULL
)
373 zoom
= atoi(val
) * 0.01;
374 else if ((val
= cupsGetOption("fitplot", num_options
, options
)) != NULL
&&
375 !strcasecmp(val
, "true"))
377 else if ((val
= cupsGetOption("fit-to-page", num_options
, options
)) != NULL
&&
378 !strcasecmp(val
, "true"))
381 if ((val
= cupsGetOption("ppi", num_options
, options
)) != NULL
)
382 if (sscanf(val
, "%dx%d", &xppi
, &yppi
) < 2)
385 if ((val
= cupsGetOption("position", num_options
, options
)) != NULL
)
387 if (strcasecmp(val
, "center") == 0)
392 else if (strcasecmp(val
, "top") == 0)
397 else if (strcasecmp(val
, "left") == 0)
402 else if (strcasecmp(val
, "right") == 0)
407 else if (strcasecmp(val
, "top-left") == 0)
412 else if (strcasecmp(val
, "top-right") == 0)
417 else if (strcasecmp(val
, "bottom") == 0)
422 else if (strcasecmp(val
, "bottom-left") == 0)
427 else if (strcasecmp(val
, "bottom-right") == 0)
434 if ((val
= cupsGetOption("saturation", num_options
, options
)) != NULL
)
437 if ((val
= cupsGetOption("hue", num_options
, options
)) != NULL
)
440 if ((choice
= ppdFindMarkedChoice(ppd
, "MirrorPrint")) != NULL
)
442 val
= choice
->choice
;
446 val
= cupsGetOption("mirror", num_options
, options
);
448 if (val
&& (!strcasecmp(val
, "true") || !strcasecmp(val
, "on") ||
449 !strcasecmp(val
, "yes")))
453 * Set the needed options in the page header...
456 if (cupsRasterInterpretPPD(&header
, ppd
, num_options
, options
, raster_cb
))
458 _cupsLangPuts(stderr
, _("ERROR: The page setup information was not valid.\n"));
459 fprintf(stderr
, "DEBUG: %s\n", cupsRasterErrorString());
464 * Get the media type and resolution that have been chosen...
467 if ((choice
= ppdFindMarkedChoice(ppd
, "MediaType")) != NULL
)
468 media_type
= choice
->choice
;
472 if ((choice
= ppdFindMarkedChoice(ppd
, "Resolution")) != NULL
)
473 resolution
= choice
->choice
;
478 * Choose the appropriate colorspace...
481 switch (header
.cupsColorSpace
)
484 case CUPS_CSPACE_SW
:
485 if (header
.cupsBitsPerColor
>= 8)
487 primary
= CUPS_IMAGE_WHITE
;
488 secondary
= CUPS_IMAGE_WHITE
;
492 primary
= CUPS_IMAGE_BLACK
;
493 secondary
= CUPS_IMAGE_BLACK
;
497 case CUPS_CSPACE_RGB
:
498 case CUPS_CSPACE_RGBA
:
499 case CUPS_CSPACE_RGBW
:
500 case CUPS_CSPACE_SRGB
:
501 case CUPS_CSPACE_ADOBERGB
:
502 if (header
.cupsBitsPerColor
>= 8)
504 primary
= CUPS_IMAGE_RGB
;
505 secondary
= CUPS_IMAGE_RGB
;
509 primary
= CUPS_IMAGE_CMY
;
510 secondary
= CUPS_IMAGE_CMY
;
515 case CUPS_CSPACE_WHITE
:
516 case CUPS_CSPACE_GOLD
:
517 case CUPS_CSPACE_SILVER
:
518 primary
= CUPS_IMAGE_BLACK
;
519 secondary
= CUPS_IMAGE_BLACK
;
522 case CUPS_CSPACE_CMYK
:
523 case CUPS_CSPACE_YMCK
:
524 case CUPS_CSPACE_KCMY
:
525 case CUPS_CSPACE_KCMYcm
:
526 case CUPS_CSPACE_GMCK
:
527 case CUPS_CSPACE_GMCS
:
528 if (header
.cupsBitsPerColor
== 1)
530 primary
= CUPS_IMAGE_CMY
;
531 secondary
= CUPS_IMAGE_CMY
;
535 primary
= CUPS_IMAGE_CMYK
;
536 secondary
= CUPS_IMAGE_CMYK
;
540 case CUPS_CSPACE_CMY
:
541 case CUPS_CSPACE_YMC
:
542 primary
= CUPS_IMAGE_CMY
;
543 secondary
= CUPS_IMAGE_CMY
;
546 case CUPS_CSPACE_CIEXYZ
:
547 case CUPS_CSPACE_CIELab
:
548 case CUPS_CSPACE_ICC1
:
549 case CUPS_CSPACE_ICC2
:
550 case CUPS_CSPACE_ICC3
:
551 case CUPS_CSPACE_ICC4
:
552 case CUPS_CSPACE_ICC5
:
553 case CUPS_CSPACE_ICC6
:
554 case CUPS_CSPACE_ICC7
:
555 case CUPS_CSPACE_ICC8
:
556 case CUPS_CSPACE_ICC9
:
557 case CUPS_CSPACE_ICCA
:
558 case CUPS_CSPACE_ICCB
:
559 case CUPS_CSPACE_ICCC
:
560 case CUPS_CSPACE_ICCD
:
561 case CUPS_CSPACE_ICCE
:
562 case CUPS_CSPACE_ICCF
:
563 case CUPS_CSPACE_DEVICE1
:
564 case CUPS_CSPACE_DEVICE2
:
565 case CUPS_CSPACE_DEVICE3
:
566 case CUPS_CSPACE_DEVICE4
:
567 case CUPS_CSPACE_DEVICE5
:
568 case CUPS_CSPACE_DEVICE6
:
569 case CUPS_CSPACE_DEVICE7
:
570 case CUPS_CSPACE_DEVICE8
:
571 case CUPS_CSPACE_DEVICE9
:
572 case CUPS_CSPACE_DEVICEA
:
573 case CUPS_CSPACE_DEVICEB
:
574 case CUPS_CSPACE_DEVICEC
:
575 case CUPS_CSPACE_DEVICED
:
576 case CUPS_CSPACE_DEVICEE
:
577 case CUPS_CSPACE_DEVICEF
:
578 fprintf(stderr
, "ERROR: Colorspace %d not supported.\n",
579 header
.cupsColorSpace
);
585 * Find a color profile matching the current options...
588 if ((val
= cupsGetOption("profile", num_options
, options
)) != NULL
)
590 profile
= &userprofile
;
591 sscanf(val
, "%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f",
592 &(userprofile
.density
), &(userprofile
.gamma
),
593 userprofile
.matrix
[0] + 0, userprofile
.matrix
[0] + 1,
594 userprofile
.matrix
[0] + 2,
595 userprofile
.matrix
[1] + 0, userprofile
.matrix
[1] + 1,
596 userprofile
.matrix
[1] + 2,
597 userprofile
.matrix
[2] + 0, userprofile
.matrix
[2] + 1,
598 userprofile
.matrix
[2] + 2);
600 userprofile
.density
*= 0.001f
;
601 userprofile
.gamma
*= 0.001f
;
602 userprofile
.matrix
[0][0] *= 0.001f
;
603 userprofile
.matrix
[0][1] *= 0.001f
;
604 userprofile
.matrix
[0][2] *= 0.001f
;
605 userprofile
.matrix
[1][0] *= 0.001f
;
606 userprofile
.matrix
[1][1] *= 0.001f
;
607 userprofile
.matrix
[1][2] *= 0.001f
;
608 userprofile
.matrix
[2][0] *= 0.001f
;
609 userprofile
.matrix
[2][1] *= 0.001f
;
610 userprofile
.matrix
[2][2] *= 0.001f
;
612 else if (ppd
!= NULL
)
614 fprintf(stderr
, "DEBUG: Searching for profile \"%s/%s\"...\n",
615 resolution
, media_type
);
617 for (i
= 0, profile
= ppd
->profiles
; i
< ppd
->num_profiles
; i
++, profile
++)
619 fprintf(stderr
, "DEBUG: \"%s/%s\" = ", profile
->resolution
,
620 profile
->media_type
);
622 if ((strcmp(profile
->resolution
, resolution
) == 0 ||
623 profile
->resolution
[0] == '-') &&
624 (strcmp(profile
->media_type
, media_type
) == 0 ||
625 profile
->media_type
[0] == '-'))
627 fputs("MATCH\n", stderr
);
631 fputs("no.\n", stderr
);
635 * If we found a color profile, use it!
638 if (i
>= ppd
->num_profiles
)
645 cupsImageSetProfile(profile
->density
, profile
->gamma
, profile
->matrix
);
647 cupsImageSetRasterColorSpace(header
.cupsColorSpace
);
650 * Create a gamma/brightness LUT...
653 make_lut(lut
, primary
, g
, b
);
656 * Open the input image to print...
659 _cupsLangPuts(stderr
, _("INFO: Loading image file...\n"));
661 if (header
.cupsColorSpace
== CUPS_CSPACE_CIEXYZ
||
662 header
.cupsColorSpace
== CUPS_CSPACE_CIELab
||
663 header
.cupsColorSpace
>= CUPS_CSPACE_ICC1
)
664 img
= cupsImageOpen(filename
, primary
, secondary
, sat
, hue
, NULL
);
666 img
= cupsImageOpen(filename
, primary
, secondary
, sat
, hue
, lut
);
673 _cupsLangPuts(stderr
, _("ERROR: The image file to print could not be opened.\n"));
679 * Scale as necessary...
682 if (zoom
== 0.0 && xppi
== 0)
691 fprintf(stderr
, "DEBUG: Before scaling: xppi=%d, yppi=%d, zoom=%.2f\n",
697 * Scale the image as neccesary to match the desired pixels-per-inch.
702 xprint
= (PageTop
- PageBottom
) / 72.0;
703 yprint
= (PageRight
- PageLeft
) / 72.0;
707 xprint
= (PageRight
- PageLeft
) / 72.0;
708 yprint
= (PageTop
- PageBottom
) / 72.0;
711 fprintf(stderr
, "DEBUG: Before scaling: xprint=%.1f, yprint=%.1f\n",
714 xinches
= (float)img
->xsize
/ (float)xppi
;
715 yinches
= (float)img
->ysize
/ (float)yppi
;
717 fprintf(stderr
, "DEBUG: Image size is %.1f x %.1f inches...\n",
720 if ((val
= cupsGetOption("natural-scaling", num_options
, options
)) != NULL
)
722 xinches
= xinches
* atoi(val
) / 100;
723 yinches
= yinches
* atoi(val
) / 100;
726 if (cupsGetOption("orientation-requested", num_options
, options
) == NULL
&&
727 cupsGetOption("landscape", num_options
, options
) == NULL
)
730 * Rotate the image if it will fit landscape but not portrait...
733 fputs("DEBUG: Auto orientation...\n", stderr
);
735 if ((xinches
> xprint
|| yinches
> yprint
) &&
736 xinches
<= yprint
&& yinches
<= xprint
)
739 * Rotate the image as needed...
742 fputs("DEBUG: Using landscape orientation...\n", stderr
);
744 Orientation
= (Orientation
+ 1) & 3;
754 * Scale percentage of page size...
757 xprint
= (PageRight
- PageLeft
) / 72.0;
758 yprint
= (PageTop
- PageBottom
) / 72.0;
759 aspect
= (float)img
->yppi
/ (float)img
->xppi
;
761 fprintf(stderr
, "DEBUG: Before scaling: xprint=%.1f, yprint=%.1f\n",
764 fprintf(stderr
, "DEBUG: img->xppi = %d, img->yppi = %d, aspect = %f\n",
765 img
->xppi
, img
->yppi
, aspect
);
767 xsize
= xprint
* zoom
;
768 ysize
= xsize
* img
->ysize
/ img
->xsize
/ aspect
;
770 if (ysize
> (yprint
* zoom
))
772 ysize
= yprint
* zoom
;
773 xsize
= ysize
* img
->xsize
* aspect
/ img
->ysize
;
776 xsize2
= yprint
* zoom
;
777 ysize2
= xsize2
* img
->ysize
/ img
->xsize
/ aspect
;
779 if (ysize2
> (xprint
* zoom
))
781 ysize2
= xprint
* zoom
;
782 xsize2
= ysize2
* img
->xsize
* aspect
/ img
->ysize
;
785 fprintf(stderr
, "DEBUG: Portrait size is %.2f x %.2f inches\n", xsize
, ysize
);
786 fprintf(stderr
, "DEBUG: Landscape size is %.2f x %.2f inches\n", xsize2
, ysize2
);
788 if (cupsGetOption("orientation-requested", num_options
, options
) == NULL
&&
789 cupsGetOption("landscape", num_options
, options
) == NULL
)
792 * Choose the rotation with the largest area, but prefer
793 * portrait if they are equal...
796 fputs("DEBUG: Auto orientation...\n", stderr
);
798 if ((xsize
* ysize
) < (xsize2
* xsize2
))
801 * Do landscape orientation...
804 fputs("DEBUG: Using landscape orientation...\n", stderr
);
809 xprint
= (PageTop
- PageBottom
) / 72.0;
810 yprint
= (PageRight
- PageLeft
) / 72.0;
815 * Do portrait orientation...
818 fputs("DEBUG: Using portrait orientation...\n", stderr
);
825 else if (Orientation
& 1)
827 fputs("DEBUG: Using landscape orientation...\n", stderr
);
831 xprint
= (PageTop
- PageBottom
) / 72.0;
832 yprint
= (PageRight
- PageLeft
) / 72.0;
836 fputs("DEBUG: Using portrait orientation...\n", stderr
);
840 xprint
= (PageRight
- PageLeft
) / 72.0;
841 yprint
= (PageTop
- PageBottom
) / 72.0;
846 * Compute the number of pages to print and the size of the image on each
850 xpages
= ceil(xinches
/ xprint
);
851 ypages
= ceil(yinches
/ yprint
);
853 xprint
= xinches
/ xpages
;
854 yprint
= yinches
/ ypages
;
856 fprintf(stderr
, "DEBUG: xpages = %dx%.2fin, ypages = %dx%.2fin\n",
857 xpages
, xprint
, ypages
, yprint
);
860 * Compute the bitmap size...
863 if ((choice
= ppdFindMarkedChoice(ppd
, "PageSize")) != NULL
&&
864 strcasecmp(choice
->choice
, "Custom") == 0)
866 float width
, /* New width in points */
867 length
; /* New length in points */
871 * Use the correct width and length for the current orientation...
876 width
= yprint
* 72.0;
877 length
= xprint
* 72.0;
881 width
= xprint
* 72.0;
882 length
= yprint
* 72.0;
886 * Add margins to page size...
889 width
+= ppd
->custom_margins
[0] + ppd
->custom_margins
[2];
890 length
+= ppd
->custom_margins
[1] + ppd
->custom_margins
[3];
893 * Enforce minimums...
896 if (width
< ppd
->custom_min
[0])
897 width
= ppd
->custom_min
[0];
899 if (length
< ppd
->custom_min
[1])
900 length
= ppd
->custom_min
[1];
902 fprintf(stderr
, "DEBUG: Updated custom page size to %.2f x %.2f inches...\n",
903 width
/ 72.0, length
/ 72.0);
906 * Set the new custom size...
909 strcpy(header
.cupsPageSizeName
, "Custom");
911 header
.cupsPageSize
[0] = width
+ 0.5;
912 header
.cupsPageSize
[1] = length
+ 0.5;
913 header
.PageSize
[0] = width
+ 0.5;
914 header
.PageSize
[1] = length
+ 0.5;
917 * Update page variables...
922 PageLeft
= ppd
->custom_margins
[0];
923 PageRight
= width
- ppd
->custom_margins
[2];
924 PageBottom
= ppd
->custom_margins
[1];
925 PageTop
= length
- ppd
->custom_margins
[3];
928 * Remove margins from page size...
931 width
-= ppd
->custom_margins
[0] + ppd
->custom_margins
[2];
932 length
-= ppd
->custom_margins
[1] + ppd
->custom_margins
[3];
935 * Set the bitmap size...
938 header
.cupsWidth
= width
* header
.HWResolution
[0] / 72.0;
939 header
.cupsHeight
= length
* header
.HWResolution
[1] / 72.0;
941 header
.cupsBytesPerLine
= (header
.cupsBitsPerPixel
*
942 header
.cupsWidth
+ 7) / 8;
944 if (header
.cupsColorOrder
== CUPS_ORDER_BANDED
)
945 header
.cupsBytesPerLine
*= header
.cupsNumColors
;
948 header
.Margins
[0] = PageLeft
;
949 header
.Margins
[1] = PageBottom
;
951 fprintf(stderr
, "DEBUG: PageSize = [%d %d]\n", header
.PageSize
[0],
960 header
.cupsImagingBBox
[0] = PageLeft
;
961 header
.cupsImagingBBox
[2] = PageLeft
+ xprint
* 72;
964 header
.cupsImagingBBox
[0] = (PageRight
+ PageLeft
- xprint
* 72) / 2;
965 header
.cupsImagingBBox
[2] = (PageRight
+ PageLeft
+ xprint
* 72) / 2;
968 header
.cupsImagingBBox
[0] = PageRight
- xprint
* 72;
969 header
.cupsImagingBBox
[2] = PageRight
;
976 header
.cupsImagingBBox
[1] = PageBottom
;
977 header
.cupsImagingBBox
[3] = PageBottom
+ yprint
* 72;
980 header
.cupsImagingBBox
[1] = (PageTop
+ PageBottom
- yprint
* 72) / 2;
981 header
.cupsImagingBBox
[3] = (PageTop
+ PageBottom
+ yprint
* 72) / 2;
984 header
.cupsImagingBBox
[1] = PageTop
- yprint
* 72;
985 header
.cupsImagingBBox
[3] = PageTop
;
994 header
.cupsImagingBBox
[0] = PageBottom
;
995 header
.cupsImagingBBox
[2] = PageBottom
+ yprint
* 72;
998 header
.cupsImagingBBox
[0] = (PageTop
+ PageBottom
- yprint
* 72) / 2;
999 header
.cupsImagingBBox
[2] = (PageTop
+ PageBottom
+ yprint
* 72) / 2;
1002 header
.cupsImagingBBox
[0] = PageTop
- yprint
* 72;
1003 header
.cupsImagingBBox
[2] = PageTop
;
1010 header
.cupsImagingBBox
[1] = PageLeft
;
1011 header
.cupsImagingBBox
[3] = PageLeft
+ xprint
* 72;
1014 header
.cupsImagingBBox
[1] = (PageRight
+ PageLeft
- xprint
* 72) / 2;
1015 header
.cupsImagingBBox
[3] = (PageRight
+ PageLeft
+ xprint
* 72) / 2;
1018 header
.cupsImagingBBox
[1] = PageRight
- xprint
* 72;
1019 header
.cupsImagingBBox
[3] = PageRight
;
1028 header
.cupsImagingBBox
[0] = PageLeft
;
1029 header
.cupsImagingBBox
[2] = PageLeft
+ xprint
* 72;
1032 header
.cupsImagingBBox
[0] = (PageRight
+ PageLeft
- xprint
* 72) / 2;
1033 header
.cupsImagingBBox
[2] = (PageRight
+ PageLeft
+ xprint
* 72) / 2;
1036 header
.cupsImagingBBox
[0] = PageRight
- xprint
* 72;
1037 header
.cupsImagingBBox
[2] = PageRight
;
1044 header
.cupsImagingBBox
[1] = PageBottom
;
1045 header
.cupsImagingBBox
[3] = PageBottom
+ yprint
* 72;
1048 header
.cupsImagingBBox
[1] = (PageTop
+ PageBottom
- yprint
* 72) / 2;
1049 header
.cupsImagingBBox
[3] = (PageTop
+ PageBottom
+ yprint
* 72) / 2;
1052 header
.cupsImagingBBox
[1] = PageTop
- yprint
* 72;
1053 header
.cupsImagingBBox
[3] = PageTop
;
1062 header
.cupsImagingBBox
[0] = PageBottom
;
1063 header
.cupsImagingBBox
[2] = PageBottom
+ yprint
* 72;
1066 header
.cupsImagingBBox
[0] = (PageTop
+ PageBottom
- yprint
* 72) / 2;
1067 header
.cupsImagingBBox
[2] = (PageTop
+ PageBottom
+ yprint
* 72) / 2;
1070 header
.cupsImagingBBox
[0] = PageTop
- yprint
* 72;
1071 header
.cupsImagingBBox
[2] = PageTop
;
1078 header
.cupsImagingBBox
[1] = PageLeft
;
1079 header
.cupsImagingBBox
[3] = PageLeft
+ xprint
* 72;
1082 header
.cupsImagingBBox
[1] = (PageRight
+ PageLeft
- xprint
* 72) / 2;
1083 header
.cupsImagingBBox
[3] = (PageRight
+ PageLeft
+ xprint
* 72) / 2;
1086 header
.cupsImagingBBox
[1] = PageRight
- xprint
* 72;
1087 header
.cupsImagingBBox
[3] = PageRight
;
1093 header
.ImagingBoundingBox
[0] = header
.cupsImagingBBox
[0];
1094 header
.ImagingBoundingBox
[1] = header
.cupsImagingBBox
[1];
1095 header
.ImagingBoundingBox
[2] = header
.cupsImagingBBox
[2];
1096 header
.ImagingBoundingBox
[3] = header
.cupsImagingBBox
[3];
1098 if (header
.cupsColorOrder
== CUPS_ORDER_PLANAR
)
1099 num_planes
= header
.cupsNumColors
;
1103 if (header
.cupsBitsPerColor
>= 8)
1104 zoom_type
= CUPS_IZOOM_NORMAL
;
1106 zoom_type
= CUPS_IZOOM_FAST
;
1109 * See if we need to collate, and if so how we need to do it...
1112 if (xpages
== 1 && ypages
== 1)
1115 slowcollate
= Collate
&& ppdFindOption(ppd
, "Collate") == NULL
;
1117 slowcopies
= ppd
->manual_copies
;
1121 if (Copies
> 1 && !slowcollate
&& !slowcopies
)
1123 header
.Collate
= (cups_bool_t
)Collate
;
1124 header
.NumCopies
= Copies
;
1129 header
.NumCopies
= 1;
1132 * Create the dithering lookup tables...
1136 OnPixels
[255] = 0xff;
1137 OffPixels
[0] = 0x00;
1138 OffPixels
[255] = 0xff;
1140 switch (header
.cupsBitsPerColor
)
1143 for (i
= 1; i
< 255; i
++)
1145 OnPixels
[i
] = 0x55 * (i
/ 85 + 1);
1146 OffPixels
[i
] = 0x55 * (i
/ 64);
1150 for (i
= 1; i
< 255; i
++)
1152 OnPixels
[i
] = 17 * (i
/ 17 + 1);
1153 OffPixels
[i
] = 17 * (i
/ 16);
1159 * Output the pages...
1162 fprintf(stderr
, "DEBUG: cupsWidth = %d\n", header
.cupsWidth
);
1163 fprintf(stderr
, "DEBUG: cupsHeight = %d\n", header
.cupsHeight
);
1164 fprintf(stderr
, "DEBUG: cupsBitsPerColor = %d\n", header
.cupsBitsPerColor
);
1165 fprintf(stderr
, "DEBUG: cupsBitsPerPixel = %d\n", header
.cupsBitsPerPixel
);
1166 fprintf(stderr
, "DEBUG: cupsBytesPerLine = %d\n", header
.cupsBytesPerLine
);
1167 fprintf(stderr
, "DEBUG: cupsColorOrder = %d\n", header
.cupsColorOrder
);
1168 fprintf(stderr
, "DEBUG: cupsColorSpace = %d\n", header
.cupsColorSpace
);
1169 fprintf(stderr
, "DEBUG: img->colorspace = %d\n", img
->colorspace
);
1171 row
= malloc(2 * header
.cupsBytesPerLine
);
1172 ras
= cupsRasterOpen(1, CUPS_RASTER_WRITE
);
1174 for (i
= 0, page
= 1; i
< Copies
; i
++)
1175 for (xpage
= 0; xpage
< xpages
; xpage
++)
1176 for (ypage
= 0; ypage
< ypages
; ypage
++, page
++)
1178 fprintf(stderr
, _("INFO: Formatting page %d...\n"), page
);
1180 if (Orientation
& 1)
1182 xc0
= img
->xsize
* ypage
/ ypages
;
1183 xc1
= img
->xsize
* (ypage
+ 1) / ypages
- 1;
1184 yc0
= img
->ysize
* xpage
/ xpages
;
1185 yc1
= img
->ysize
* (xpage
+ 1) / xpages
- 1;
1187 xtemp
= header
.HWResolution
[0] * yprint
;
1188 ytemp
= header
.HWResolution
[1] * xprint
;
1192 xc0
= img
->xsize
* xpage
/ xpages
;
1193 xc1
= img
->xsize
* (xpage
+ 1) / xpages
- 1;
1194 yc0
= img
->ysize
* ypage
/ ypages
;
1195 yc1
= img
->ysize
* (ypage
+ 1) / ypages
- 1;
1197 xtemp
= header
.HWResolution
[0] * xprint
;
1198 ytemp
= header
.HWResolution
[1] * yprint
;
1201 cupsRasterWriteHeader2(ras
, &header
);
1203 for (plane
= 0; plane
< num_planes
; plane
++)
1206 * Initialize the image "zoom" engine...
1210 z
= _cupsImageZoomNew(img
, xc0
, yc0
, xc1
, yc1
, -xtemp
, ytemp
,
1211 Orientation
& 1, zoom_type
);
1213 z
= _cupsImageZoomNew(img
, xc0
, yc0
, xc1
, yc1
, xtemp
, ytemp
,
1214 Orientation
& 1, zoom_type
);
1217 * Write leading blank space as needed...
1220 if (header
.cupsHeight
> z
->ysize
&& YPosition
<= 0)
1222 blank_line(&header
, row
);
1224 y
= header
.cupsHeight
- z
->ysize
;
1228 fprintf(stderr
, "DEBUG: Writing %d leading blank lines...\n", y
);
1232 if (cupsRasterWritePixels(ras
, row
, header
.cupsBytesPerLine
) <
1233 header
.cupsBytesPerLine
)
1235 _cupsLangPuts(stderr
,
1236 _("ERROR: The raster data could not be written "
1237 "to the driver.\n"));
1238 cupsImageClose(img
);
1245 * Then write image data...
1248 for (y
= z
->ysize
, yerr0
= 0, yerr1
= z
->ysize
, iy
= 0, last_iy
= -2;
1254 if (zoom_type
!= CUPS_IZOOM_FAST
&& (iy
- last_iy
) > 1)
1255 _cupsImageZoomFill(z
, iy
);
1257 _cupsImageZoomFill(z
, iy
+ z
->yincr
);
1263 * Format this line of raster data for the printer...
1266 blank_line(&header
, row
);
1268 r0
= z
->rows
[z
->row
];
1269 r1
= z
->rows
[1 - z
->row
];
1271 switch (header
.cupsColorSpace
)
1273 case CUPS_CSPACE_W
:
1274 format_W(&header
, row
, y
, plane
, z
->xsize
, z
->ysize
,
1275 yerr0
, yerr1
, r0
, r1
);
1278 case CUPS_CSPACE_RGB
:
1279 format_RGB(&header
, row
, y
, plane
, z
->xsize
, z
->ysize
,
1280 yerr0
, yerr1
, r0
, r1
);
1282 case CUPS_CSPACE_RGBA
:
1283 case CUPS_CSPACE_RGBW
:
1284 format_RGBA(&header
, row
, y
, plane
, z
->xsize
, z
->ysize
,
1285 yerr0
, yerr1
, r0
, r1
);
1287 case CUPS_CSPACE_K
:
1288 case CUPS_CSPACE_WHITE
:
1289 case CUPS_CSPACE_GOLD
:
1290 case CUPS_CSPACE_SILVER
:
1291 format_K(&header
, row
, y
, plane
, z
->xsize
, z
->ysize
,
1292 yerr0
, yerr1
, r0
, r1
);
1294 case CUPS_CSPACE_CMY
:
1295 format_CMY(&header
, row
, y
, plane
, z
->xsize
, z
->ysize
,
1296 yerr0
, yerr1
, r0
, r1
);
1298 case CUPS_CSPACE_YMC
:
1299 format_YMC(&header
, row
, y
, plane
, z
->xsize
, z
->ysize
,
1300 yerr0
, yerr1
, r0
, r1
);
1302 case CUPS_CSPACE_CMYK
:
1303 format_CMYK(&header
, row
, y
, plane
, z
->xsize
, z
->ysize
,
1304 yerr0
, yerr1
, r0
, r1
);
1306 case CUPS_CSPACE_YMCK
:
1307 case CUPS_CSPACE_GMCK
:
1308 case CUPS_CSPACE_GMCS
:
1309 format_YMCK(&header
, row
, y
, plane
, z
->xsize
, z
->ysize
,
1310 yerr0
, yerr1
, r0
, r1
);
1312 case CUPS_CSPACE_KCMYcm
:
1313 if (header
.cupsBitsPerColor
== 1)
1315 format_KCMYcm(&header
, row
, y
, plane
, z
->xsize
, z
->ysize
,
1316 yerr0
, yerr1
, r0
, r1
);
1319 case CUPS_CSPACE_KCMY
:
1320 format_KCMY(&header
, row
, y
, plane
, z
->xsize
, z
->ysize
,
1321 yerr0
, yerr1
, r0
, r1
);
1326 * Write the raster data to the driver...
1329 if (cupsRasterWritePixels(ras
, row
, header
.cupsBytesPerLine
) <
1330 header
.cupsBytesPerLine
)
1332 _cupsLangPuts(stderr
,
1333 _("ERROR: The raster data could not be written to "
1335 cupsImageClose(img
);
1340 * Compute the next scanline in the image...
1355 * Write trailing blank space as needed...
1358 if (header
.cupsHeight
> z
->ysize
&& YPosition
>= 0)
1360 blank_line(&header
, row
);
1362 y
= header
.cupsHeight
- z
->ysize
;
1366 fprintf(stderr
, "DEBUG: Writing %d trailing blank lines...\n", y
);
1370 if (cupsRasterWritePixels(ras
, row
, header
.cupsBytesPerLine
) <
1371 header
.cupsBytesPerLine
)
1373 _cupsLangPuts(stderr
,
1374 _("ERROR: The raster data could not be written "
1375 "to the driver.\n"));
1376 cupsImageClose(img
);
1383 * Free memory used for the "zoom" engine...
1386 _cupsImageZoomDelete(z
);
1395 cupsRasterClose(ras
);
1396 cupsImageClose(img
);
1404 * 'blank_line()' - Clear a line buffer to the blank value...
1408 blank_line(cups_page_header2_t
*header
, /* I - Page header */
1409 unsigned char *row
) /* I - Row buffer */
1411 int count
; /* Remaining bytes */
1414 count
= header
->cupsBytesPerLine
;
1416 switch (header
->cupsColorSpace
)
1418 case CUPS_CSPACE_CIEXYZ
:
1428 case CUPS_CSPACE_CIELab
:
1429 case CUPS_CSPACE_ICC1
:
1430 case CUPS_CSPACE_ICC2
:
1431 case CUPS_CSPACE_ICC3
:
1432 case CUPS_CSPACE_ICC4
:
1433 case CUPS_CSPACE_ICC5
:
1434 case CUPS_CSPACE_ICC6
:
1435 case CUPS_CSPACE_ICC7
:
1436 case CUPS_CSPACE_ICC8
:
1437 case CUPS_CSPACE_ICC9
:
1438 case CUPS_CSPACE_ICCA
:
1439 case CUPS_CSPACE_ICCB
:
1440 case CUPS_CSPACE_ICCC
:
1441 case CUPS_CSPACE_ICCD
:
1442 case CUPS_CSPACE_ICCE
:
1443 case CUPS_CSPACE_ICCF
:
1453 case CUPS_CSPACE_K
:
1454 case CUPS_CSPACE_CMY
:
1455 case CUPS_CSPACE_CMYK
:
1456 case CUPS_CSPACE_YMC
:
1457 case CUPS_CSPACE_YMCK
:
1458 case CUPS_CSPACE_KCMY
:
1459 case CUPS_CSPACE_KCMYcm
:
1460 case CUPS_CSPACE_GMCK
:
1461 case CUPS_CSPACE_GMCS
:
1462 case CUPS_CSPACE_WHITE
:
1463 case CUPS_CSPACE_GOLD
:
1464 case CUPS_CSPACE_SILVER
:
1465 memset(row
, 0, count
);
1469 memset(row
, 255, count
);
1476 * 'format_CMY()' - Convert image data to CMY.
1480 format_CMY(cups_page_header2_t
*header
, /* I - Page header */
1481 unsigned char *row
, /* IO - Bitmap data for device */
1482 int y
, /* I - Current row */
1483 int z
, /* I - Current plane */
1484 int xsize
, /* I - Width of image data */
1485 int ysize
, /* I - Height of image data */
1486 int yerr0
, /* I - Top Y error */
1487 int yerr1
, /* I - Bottom Y error */
1488 cups_ib_t
*r0
, /* I - Primary image data */
1489 cups_ib_t
*r1
) /* I - Image data for interpolation */
1491 cups_ib_t
*ptr
, /* Pointer into row */
1492 *cptr
, /* Pointer into cyan */
1493 *mptr
, /* Pointer into magenta */
1494 *yptr
, /* Pointer into yellow */
1495 bitmask
; /* Current mask for pixel */
1496 int bitoffset
; /* Current offset in line */
1497 int bandwidth
; /* Width of a color band */
1498 int x
, /* Current X coordinate on page */
1499 *dither
; /* Pointer into dither array */
1508 bitoffset
= header
->cupsBitsPerPixel
* ((header
->cupsWidth
- xsize
) / 2);
1511 bitoffset
= header
->cupsBitsPerPixel
* (header
->cupsWidth
- xsize
);
1515 ptr
= row
+ bitoffset
/ 8;
1516 bandwidth
= header
->cupsBytesPerLine
/ 3;
1518 switch (header
->cupsColorOrder
)
1520 case CUPS_ORDER_CHUNKED
:
1521 switch (header
->cupsBitsPerColor
)
1524 bitmask
= 64 >> (bitoffset
& 7);
1525 dither
= Floyd16x16
[y
& 15];
1527 for (x
= xsize
; x
> 0; x
--)
1529 if (*r0
++ > dither
[x
& 15])
1533 if (*r0
++ > dither
[x
& 15])
1537 if (*r0
++ > dither
[x
& 15])
1551 dither
= Floyd8x8
[y
& 7];
1553 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
1555 if ((r0
[0] & 63) > dither
[x
& 7])
1556 *ptr
^= (0x30 & OnPixels
[r0
[0]]);
1558 *ptr
^= (0x30 & OffPixels
[r0
[0]]);
1560 if ((r0
[1] & 63) > dither
[x
& 7])
1561 *ptr
^= (0x0c & OnPixels
[r0
[1]]);
1563 *ptr
^= (0x0c & OffPixels
[r0
[1]]);
1565 if ((r0
[2] & 63) > dither
[x
& 7])
1566 *ptr
++ ^= (0x03 & OnPixels
[r0
[2]]);
1568 *ptr
++ ^= (0x03 & OffPixels
[r0
[2]]);
1573 dither
= Floyd4x4
[y
& 3];
1575 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
1577 if ((r0
[0] & 15) > dither
[x
& 3])
1578 *ptr
++ ^= (0x0f & OnPixels
[r0
[0]]);
1580 *ptr
++ ^= (0x0f & OffPixels
[r0
[0]]);
1582 if ((r0
[1] & 15) > dither
[x
& 3])
1583 *ptr
^= (0xf0 & OnPixels
[r0
[1]]);
1585 *ptr
^= (0xf0 & OffPixels
[r0
[1]]);
1587 if ((r0
[2] & 15) > dither
[x
& 3])
1588 *ptr
++ ^= (0x0f & OnPixels
[r0
[2]]);
1590 *ptr
++ ^= (0x0f & OffPixels
[r0
[2]]);
1595 for (x
= xsize
* 3; x
> 0; x
--, r0
++, r1
++)
1599 *ptr
++ = (*r0
* yerr0
+ *r1
* yerr1
) / ysize
;
1604 case CUPS_ORDER_BANDED
:
1606 mptr
= ptr
+ bandwidth
;
1607 yptr
= ptr
+ 2 * bandwidth
;
1609 switch (header
->cupsBitsPerColor
)
1612 bitmask
= 0x80 >> (bitoffset
& 7);
1613 dither
= Floyd16x16
[y
& 15];
1615 for (x
= xsize
; x
> 0; x
--)
1617 if (*r0
++ > dither
[x
& 15])
1619 if (*r0
++ > dither
[x
& 15])
1621 if (*r0
++ > dither
[x
& 15])
1637 bitmask
= 0xc0 >> (bitoffset
& 7);
1638 dither
= Floyd8x8
[y
& 7];
1640 for (x
= xsize
; x
> 0; x
--)
1642 if ((*r0
& 63) > dither
[x
& 7])
1643 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
1645 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
1647 if ((*r0
& 63) > dither
[x
& 7])
1648 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
1650 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
1652 if ((*r0
& 63) > dither
[x
& 7])
1653 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
1655 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
1671 bitmask
= 0xf0 >> (bitoffset
& 7);
1672 dither
= Floyd4x4
[y
& 3];
1674 for (x
= xsize
; x
> 0; x
--)
1676 if ((*r0
& 15) > dither
[x
& 3])
1677 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
1679 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
1681 if ((*r0
& 15) > dither
[x
& 3])
1682 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
1684 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
1686 if ((*r0
& 15) > dither
[x
& 3])
1687 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
1689 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
1691 if (bitmask
== 0xf0)
1705 for (x
= xsize
; x
> 0; x
--, r0
+= 3, r1
+= 3)
1710 *cptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
1715 *mptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
1720 *yptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
1726 case CUPS_ORDER_PLANAR
:
1727 switch (header
->cupsBitsPerColor
)
1730 bitmask
= 0x80 >> (bitoffset
& 7);
1731 dither
= Floyd16x16
[y
& 15];
1736 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
1738 if (r0
[0] > dither
[x
& 15])
1752 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
1754 if (r0
[1] > dither
[x
& 15])
1768 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
1770 if (r0
[2] > dither
[x
& 15])
1786 bitmask
= 0xc0 >> (bitoffset
& 7);
1787 dither
= Floyd8x8
[y
& 7];
1790 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
1792 if ((*r0
& 63) > dither
[x
& 7])
1793 *ptr
^= (bitmask
& OnPixels
[*r0
]);
1795 *ptr
^= (bitmask
& OffPixels
[*r0
]);
1809 bitmask
= 0xf0 >> (bitoffset
& 7);
1810 dither
= Floyd4x4
[y
& 3];
1813 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
1815 if ((*r0
& 15) > dither
[x
& 3])
1816 *ptr
^= (bitmask
& OnPixels
[*r0
]);
1818 *ptr
^= (bitmask
& OffPixels
[*r0
]);
1820 if (bitmask
== 0xf0)
1835 for (x
= xsize
; x
> 0; x
--, r0
+= 3, r1
+= 3)
1840 *ptr
++ = (*r0
* yerr0
+ *r1
* yerr1
) / ysize
;
1850 * 'format_CMYK()' - Convert image data to CMYK.
1854 format_CMYK(cups_page_header2_t
*header
,/* I - Page header */
1855 unsigned char *row
, /* IO - Bitmap data for device */
1856 int y
, /* I - Current row */
1857 int z
, /* I - Current plane */
1858 int xsize
, /* I - Width of image data */
1859 int ysize
, /* I - Height of image data */
1860 int yerr0
, /* I - Top Y error */
1861 int yerr1
, /* I - Bottom Y error */
1862 cups_ib_t
*r0
, /* I - Primary image data */
1863 cups_ib_t
*r1
) /* I - Image data for interpolation */
1865 cups_ib_t
*ptr
, /* Pointer into row */
1866 *cptr
, /* Pointer into cyan */
1867 *mptr
, /* Pointer into magenta */
1868 *yptr
, /* Pointer into yellow */
1869 *kptr
, /* Pointer into black */
1870 bitmask
; /* Current mask for pixel */
1871 int bitoffset
; /* Current offset in line */
1872 int bandwidth
; /* Width of a color band */
1873 int x
, /* Current X coordinate on page */
1874 *dither
; /* Pointer into dither array */
1875 int pc
, pm
, py
; /* CMY pixels */
1884 bitoffset
= header
->cupsBitsPerPixel
* ((header
->cupsWidth
- xsize
) / 2);
1887 bitoffset
= header
->cupsBitsPerPixel
* (header
->cupsWidth
- xsize
);
1891 ptr
= row
+ bitoffset
/ 8;
1892 bandwidth
= header
->cupsBytesPerLine
/ 4;
1894 switch (header
->cupsColorOrder
)
1896 case CUPS_ORDER_CHUNKED
:
1897 switch (header
->cupsBitsPerColor
)
1900 bitmask
= 128 >> (bitoffset
& 7);
1901 dither
= Floyd16x16
[y
& 15];
1903 for (x
= xsize
; x
> 0; x
--)
1905 pc
= *r0
++ > dither
[x
& 15];
1906 pm
= *r0
++ > dither
[x
& 15];
1907 py
= *r0
++ > dither
[x
& 15];
1940 dither
= Floyd8x8
[y
& 7];
1942 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
1944 if ((r0
[0] & 63) > dither
[x
& 7])
1945 *ptr
^= (0xc0 & OnPixels
[r0
[0]]);
1947 *ptr
^= (0xc0 & OffPixels
[r0
[0]]);
1949 if ((r0
[1] & 63) > dither
[x
& 7])
1950 *ptr
^= (0x30 & OnPixels
[r0
[1]]);
1952 *ptr
^= (0x30 & OffPixels
[r0
[1]]);
1954 if ((r0
[2] & 63) > dither
[x
& 7])
1955 *ptr
^= (0x0c & OnPixels
[r0
[2]]);
1957 *ptr
^= (0x0c & OffPixels
[r0
[2]]);
1959 if ((r0
[3] & 63) > dither
[x
& 7])
1960 *ptr
++ ^= (0x03 & OnPixels
[r0
[3]]);
1962 *ptr
++ ^= (0x03 & OffPixels
[r0
[3]]);
1967 dither
= Floyd4x4
[y
& 3];
1969 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
1971 if ((r0
[0] & 15) > dither
[x
& 3])
1972 *ptr
^= (0xf0 & OnPixels
[r0
[0]]);
1974 *ptr
^= (0xf0 & OffPixels
[r0
[0]]);
1976 if ((r0
[1] & 15) > dither
[x
& 3])
1977 *ptr
++ ^= (0x0f & OnPixels
[r0
[1]]);
1979 *ptr
++ ^= (0x0f & OffPixels
[r0
[1]]);
1981 if ((r0
[2] & 15) > dither
[x
& 3])
1982 *ptr
^= (0xf0 & OnPixels
[r0
[2]]);
1984 *ptr
^= (0xf0 & OffPixels
[r0
[2]]);
1986 if ((r0
[3] & 15) > dither
[x
& 3])
1987 *ptr
++ ^= (0x0f & OnPixels
[r0
[3]]);
1989 *ptr
++ ^= (0x0f & OffPixels
[r0
[3]]);
1994 for (x
= xsize
* 4; x
> 0; x
--, r0
++, r1
++)
1998 *ptr
++ = (*r0
* yerr0
+ *r1
* yerr1
) / ysize
;
2003 case CUPS_ORDER_BANDED
:
2005 mptr
= ptr
+ bandwidth
;
2006 yptr
= ptr
+ 2 * bandwidth
;
2007 kptr
= ptr
+ 3 * bandwidth
;
2009 switch (header
->cupsBitsPerColor
)
2012 bitmask
= 0x80 >> (bitoffset
& 7);
2013 dither
= Floyd16x16
[y
& 15];
2015 for (x
= xsize
; x
> 0; x
--)
2017 pc
= *r0
++ > dither
[x
& 15];
2018 pm
= *r0
++ > dither
[x
& 15];
2019 py
= *r0
++ > dither
[x
& 15];
2047 bitmask
= 0xc0 >> (bitoffset
& 7);
2048 dither
= Floyd8x8
[y
& 7];
2050 for (x
= xsize
; x
> 0; x
--)
2052 if ((*r0
& 63) > dither
[x
& 7])
2053 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
2055 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
2057 if ((*r0
& 63) > dither
[x
& 7])
2058 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
2060 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
2062 if ((*r0
& 63) > dither
[x
& 7])
2063 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
2065 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
2067 if ((*r0
& 63) > dither
[x
& 7])
2068 *kptr
^= (bitmask
& OnPixels
[*r0
++]);
2070 *kptr
^= (bitmask
& OffPixels
[*r0
++]);
2087 bitmask
= 0xf0 >> (bitoffset
& 7);
2088 dither
= Floyd4x4
[y
& 3];
2090 for (x
= xsize
; x
> 0; x
--)
2092 if ((*r0
& 15) > dither
[x
& 3])
2093 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
2095 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
2097 if ((*r0
& 15) > dither
[x
& 3])
2098 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
2100 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
2102 if ((*r0
& 15) > dither
[x
& 3])
2103 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
2105 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
2107 if ((*r0
& 15) > dither
[x
& 3])
2108 *kptr
^= (bitmask
& OnPixels
[*r0
++]);
2110 *kptr
^= (bitmask
& OffPixels
[*r0
++]);
2112 if (bitmask
== 0xf0)
2127 for (x
= xsize
; x
> 0; x
--, r0
+= 4, r1
+= 4)
2132 *cptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
2137 *mptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
2142 *yptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
2147 *kptr
++ = (r0
[3] * yerr0
+ r1
[3] * yerr1
) / ysize
;
2153 case CUPS_ORDER_PLANAR
:
2154 switch (header
->cupsBitsPerColor
)
2157 bitmask
= 0x80 >> (bitoffset
& 7);
2158 dither
= Floyd16x16
[y
& 15];
2160 for (x
= xsize
; x
> 0; x
--)
2162 pc
= *r0
++ > dither
[x
& 15];
2163 pm
= *r0
++ > dither
[x
& 15];
2164 py
= *r0
++ > dither
[x
& 15];
2166 if ((pc
&& pm
&& py
&& z
== 3) ||
2167 (pc
&& z
== 0) || (pm
&& z
== 1) || (py
&& z
== 2))
2181 bitmask
= 0xc0 >> (bitoffset
& 7);
2182 dither
= Floyd8x8
[y
& 7];
2185 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
2187 if ((*r0
& 63) > dither
[x
& 7])
2188 *ptr
^= (bitmask
& OnPixels
[*r0
]);
2190 *ptr
^= (bitmask
& OffPixels
[*r0
]);
2204 bitmask
= 0xf0 >> (bitoffset
& 7);
2205 dither
= Floyd4x4
[y
& 3];
2208 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
2210 if ((*r0
& 15) > dither
[x
& 3])
2211 *ptr
^= (bitmask
& OnPixels
[*r0
]);
2213 *ptr
^= (bitmask
& OffPixels
[*r0
]);
2215 if (bitmask
== 0xf0)
2230 for (x
= xsize
; x
> 0; x
--, r0
+= 4, r1
+= 4)
2235 *ptr
++ = (*r0
* yerr0
+ *r1
* yerr1
) / ysize
;
2245 * 'format_K()' - Convert image data to black.
2249 format_K(cups_page_header2_t
*header
, /* I - Page header */
2250 unsigned char *row
, /* IO - Bitmap data for device */
2251 int y
, /* I - Current row */
2252 int z
, /* I - Current plane */
2253 int xsize
, /* I - Width of image data */
2254 int ysize
, /* I - Height of image data */
2255 int yerr0
, /* I - Top Y error */
2256 int yerr1
, /* I - Bottom Y error */
2257 cups_ib_t
*r0
, /* I - Primary image data */
2258 cups_ib_t
*r1
) /* I - Image data for interpolation */
2260 cups_ib_t
*ptr
, /* Pointer into row */
2261 bitmask
; /* Current mask for pixel */
2262 int bitoffset
; /* Current offset in line */
2263 int x
, /* Current X coordinate on page */
2264 *dither
; /* Pointer into dither array */
2275 bitoffset
= header
->cupsBitsPerPixel
* ((header
->cupsWidth
- xsize
) / 2);
2278 bitoffset
= header
->cupsBitsPerPixel
* (header
->cupsWidth
- xsize
);
2282 ptr
= row
+ bitoffset
/ 8;
2284 switch (header
->cupsBitsPerColor
)
2287 bitmask
= 0x80 >> (bitoffset
& 7);
2288 dither
= Floyd16x16
[y
& 15];
2290 for (x
= xsize
; x
> 0; x
--)
2292 if (*r0
++ > dither
[x
& 15])
2306 bitmask
= 0xc0 >> (bitoffset
& 7);
2307 dither
= Floyd8x8
[y
& 7];
2309 for (x
= xsize
; x
> 0; x
--)
2311 if ((*r0
& 63) > dither
[x
& 7])
2312 *ptr
^= (bitmask
& OnPixels
[*r0
++]);
2314 *ptr
^= (bitmask
& OffPixels
[*r0
++]);
2328 bitmask
= 0xf0 >> (bitoffset
& 7);
2329 dither
= Floyd4x4
[y
& 3];
2331 for (x
= xsize
; x
> 0; x
--)
2333 if ((*r0
& 15) > dither
[x
& 3])
2334 *ptr
^= (bitmask
& OnPixels
[*r0
++]);
2336 *ptr
^= (bitmask
& OffPixels
[*r0
++]);
2338 if (bitmask
== 0xf0)
2350 for (x
= xsize
; x
> 0; x
--, r0
++, r1
++)
2355 *ptr
++ = (*r0
* yerr0
+ *r1
* yerr1
) / ysize
;
2363 * 'format_KCMY()' - Convert image data to KCMY.
2367 format_KCMY(cups_page_header2_t
*header
,/* I - Page header */
2368 unsigned char *row
, /* IO - Bitmap data for device */
2369 int y
, /* I - Current row */
2370 int z
, /* I - Current plane */
2371 int xsize
, /* I - Width of image data */
2372 int ysize
, /* I - Height of image data */
2373 int yerr0
, /* I - Top Y error */
2374 int yerr1
, /* I - Bottom Y error */
2375 cups_ib_t
*r0
, /* I - Primary image data */
2376 cups_ib_t
*r1
) /* I - Image data for interpolation */
2378 cups_ib_t
*ptr
, /* Pointer into row */
2379 *cptr
, /* Pointer into cyan */
2380 *mptr
, /* Pointer into magenta */
2381 *yptr
, /* Pointer into yellow */
2382 *kptr
, /* Pointer into black */
2383 bitmask
; /* Current mask for pixel */
2384 int bitoffset
; /* Current offset in line */
2385 int bandwidth
; /* Width of a color band */
2386 int x
, /* Current X coordinate on page */
2387 *dither
; /* Pointer into dither array */
2388 int pc
, pm
, py
; /* CMY pixels */
2397 bitoffset
= header
->cupsBitsPerPixel
* ((header
->cupsWidth
- xsize
) / 2);
2400 bitoffset
= header
->cupsBitsPerPixel
* (header
->cupsWidth
- xsize
);
2404 ptr
= row
+ bitoffset
/ 8;
2405 bandwidth
= header
->cupsBytesPerLine
/ 4;
2407 switch (header
->cupsColorOrder
)
2409 case CUPS_ORDER_CHUNKED
:
2410 switch (header
->cupsBitsPerColor
)
2413 bitmask
= 128 >> (bitoffset
& 7);
2414 dither
= Floyd16x16
[y
& 15];
2416 for (x
= xsize
; x
> 0; x
--)
2418 pc
= *r0
++ > dither
[x
& 15];
2419 pm
= *r0
++ > dither
[x
& 15];
2420 py
= *r0
++ > dither
[x
& 15];
2453 dither
= Floyd8x8
[y
& 7];
2455 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
2457 if ((r0
[3] & 63) > dither
[x
& 7])
2458 *ptr
^= (0xc0 & OnPixels
[r0
[3]]);
2460 *ptr
^= (0xc0 & OffPixels
[r0
[3]]);
2462 if ((r0
[0] & 63) > dither
[x
& 7])
2463 *ptr
^= (0x30 & OnPixels
[r0
[0]]);
2465 *ptr
^= (0x30 & OffPixels
[r0
[0]]);
2467 if ((r0
[1] & 63) > dither
[x
& 7])
2468 *ptr
^= (0x0c & OnPixels
[r0
[1]]);
2470 *ptr
^= (0x0c & OffPixels
[r0
[1]]);
2472 if ((r0
[2] & 63) > dither
[x
& 7])
2473 *ptr
++ ^= (0x03 & OnPixels
[r0
[2]]);
2475 *ptr
++ ^= (0x03 & OffPixels
[r0
[2]]);
2480 dither
= Floyd4x4
[y
& 3];
2482 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
2484 if ((r0
[3] & 15) > dither
[x
& 3])
2485 *ptr
^= (0xf0 & OnPixels
[r0
[3]]);
2487 *ptr
^= (0xf0 & OffPixels
[r0
[3]]);
2489 if ((r0
[0] & 15) > dither
[x
& 3])
2490 *ptr
++ ^= (0x0f & OnPixels
[r0
[0]]);
2492 *ptr
++ ^= (0x0f & OffPixels
[r0
[0]]);
2494 if ((r0
[1] & 15) > dither
[x
& 3])
2495 *ptr
^= (0xf0 & OnPixels
[r0
[1]]);
2497 *ptr
^= (0xf0 & OffPixels
[r0
[1]]);
2499 if ((r0
[2] & 15) > dither
[x
& 3])
2500 *ptr
++ ^= (0x0f & OnPixels
[r0
[2]]);
2502 *ptr
++ ^= (0x0f & OffPixels
[r0
[2]]);
2507 for (x
= xsize
; x
> 0; x
--, r0
+= 4, r1
+= 4)
2512 *ptr
++ = (r0
[3] * yerr0
+ r1
[3] * yerr1
) / ysize
;
2517 *ptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
2522 *ptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
2527 *ptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
2533 case CUPS_ORDER_BANDED
:
2535 cptr
= ptr
+ bandwidth
;
2536 mptr
= ptr
+ 2 * bandwidth
;
2537 yptr
= ptr
+ 3 * bandwidth
;
2539 switch (header
->cupsBitsPerColor
)
2542 bitmask
= 0x80 >> (bitoffset
& 7);
2543 dither
= Floyd16x16
[y
& 15];
2545 for (x
= xsize
; x
> 0; x
--)
2547 pc
= *r0
++ > dither
[x
& 15];
2548 pm
= *r0
++ > dither
[x
& 15];
2549 py
= *r0
++ > dither
[x
& 15];
2577 bitmask
= 0xc0 >> (bitoffset
& 7);
2578 dither
= Floyd8x8
[y
& 7];
2580 for (x
= xsize
; x
> 0; x
--)
2582 if ((*r0
& 63) > dither
[x
& 7])
2583 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
2585 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
2587 if ((*r0
& 63) > dither
[x
& 7])
2588 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
2590 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
2592 if ((*r0
& 63) > dither
[x
& 7])
2593 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
2595 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
2597 if ((*r0
& 63) > dither
[x
& 7])
2598 *kptr
^= (bitmask
& OnPixels
[*r0
++]);
2600 *kptr
^= (bitmask
& OffPixels
[*r0
++]);
2617 bitmask
= 0xf0 >> (bitoffset
& 7);
2618 dither
= Floyd4x4
[y
& 3];
2620 for (x
= xsize
; x
> 0; x
--)
2622 if ((*r0
& 15) > dither
[x
& 3])
2623 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
2625 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
2627 if ((*r0
& 15) > dither
[x
& 3])
2628 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
2630 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
2632 if ((*r0
& 15) > dither
[x
& 3])
2633 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
2635 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
2637 if ((*r0
& 15) > dither
[x
& 3])
2638 *kptr
^= (bitmask
& OnPixels
[*r0
++]);
2640 *kptr
^= (bitmask
& OffPixels
[*r0
++]);
2642 if (bitmask
== 0xf0)
2657 for (x
= xsize
; x
> 0; x
--, r0
+= 4, r1
+= 4)
2662 *cptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
2667 *mptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
2672 *yptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
2677 *kptr
++ = (r0
[3] * yerr0
+ r1
[3] * yerr1
) / ysize
;
2683 case CUPS_ORDER_PLANAR
:
2684 switch (header
->cupsBitsPerColor
)
2687 bitmask
= 0x80 >> (bitoffset
& 7);
2688 dither
= Floyd16x16
[y
& 15];
2690 for (x
= xsize
; x
> 0; x
--)
2692 pc
= *r0
++ > dither
[x
& 15];
2693 pm
= *r0
++ > dither
[x
& 15];
2694 py
= *r0
++ > dither
[x
& 15];
2696 if ((pc
&& pm
&& py
&& z
== 0) ||
2697 (pc
&& z
== 1) || (pm
&& z
== 2) || (py
&& z
== 3))
2711 bitmask
= 0xc0 >> (bitoffset
& 7);
2712 dither
= Floyd8x8
[y
& 7];
2718 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
2720 if ((*r0
& 63) > dither
[x
& 7])
2721 *ptr
^= (bitmask
& OnPixels
[*r0
]);
2723 *ptr
^= (bitmask
& OffPixels
[*r0
]);
2737 bitmask
= 0xf0 >> (bitoffset
& 7);
2738 dither
= Floyd4x4
[y
& 3];
2744 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
2746 if ((*r0
& 15) > dither
[x
& 3])
2747 *ptr
^= (bitmask
& OnPixels
[*r0
]);
2749 *ptr
^= (bitmask
& OffPixels
[*r0
]);
2751 if (bitmask
== 0xf0)
2774 for (x
= xsize
; x
> 0; x
--, r0
+= 4, r1
+= 4)
2779 *ptr
++ = (*r0
* yerr0
+ *r1
* yerr1
) / ysize
;
2789 * 'format_KCMYcm()' - Convert image data to KCMYcm.
2794 cups_page_header2_t
*header
, /* I - Page header */
2795 unsigned char *row
, /* IO - Bitmap data for device */
2796 int y
, /* I - Current row */
2797 int z
, /* I - Current plane */
2798 int xsize
, /* I - Width of image data */
2799 int ysize
, /* I - Height of image data */
2800 int yerr0
, /* I - Top Y error */
2801 int yerr1
, /* I - Bottom Y error */
2802 cups_ib_t
*r0
, /* I - Primary image data */
2803 cups_ib_t
*r1
) /* I - Image data for interpolation */
2805 int pc
, pm
, py
, pk
; /* Cyan, magenta, yellow, and black values */
2806 cups_ib_t
*ptr
, /* Pointer into row */
2807 *cptr
, /* Pointer into cyan */
2808 *mptr
, /* Pointer into magenta */
2809 *yptr
, /* Pointer into yellow */
2810 *kptr
, /* Pointer into black */
2811 *lcptr
, /* Pointer into light cyan */
2812 *lmptr
, /* Pointer into light magenta */
2813 bitmask
; /* Current mask for pixel */
2814 int bitoffset
; /* Current offset in line */
2815 int bandwidth
; /* Width of a color band */
2816 int x
, /* Current X coordinate on page */
2817 *dither
; /* Pointer into dither array */
2826 bitoffset
= header
->cupsBitsPerPixel
* ((header
->cupsWidth
- xsize
) / 2);
2829 bitoffset
= header
->cupsBitsPerPixel
* (header
->cupsWidth
- xsize
);
2833 ptr
= row
+ bitoffset
/ 8;
2834 bandwidth
= header
->cupsBytesPerLine
/ 6;
2836 switch (header
->cupsColorOrder
)
2838 case CUPS_ORDER_CHUNKED
:
2839 dither
= Floyd16x16
[y
& 15];
2841 for (x
= xsize
; x
> 0; x
--)
2843 pc
= *r0
++ > dither
[x
& 15];
2844 pm
= *r0
++ > dither
[x
& 15];
2845 py
= *r0
++ > dither
[x
& 15];
2846 pk
= pc
&& pm
&& py
;
2849 *ptr
++ ^= 32; /* Black */
2851 *ptr
++ ^= 17; /* Blue (cyan + light magenta) */
2853 *ptr
++ ^= 6; /* Green (light cyan + yellow) */
2855 *ptr
++ ^= 12; /* Red (magenta + yellow) */
2867 case CUPS_ORDER_BANDED
:
2869 cptr
= ptr
+ bandwidth
;
2870 mptr
= ptr
+ 2 * bandwidth
;
2871 yptr
= ptr
+ 3 * bandwidth
;
2872 lcptr
= ptr
+ 4 * bandwidth
;
2873 lmptr
= ptr
+ 5 * bandwidth
;
2875 bitmask
= 0x80 >> (bitoffset
& 7);
2876 dither
= Floyd16x16
[y
& 15];
2878 for (x
= xsize
; x
> 0; x
--)
2880 pc
= *r0
++ > dither
[x
& 15];
2881 pm
= *r0
++ > dither
[x
& 15];
2882 py
= *r0
++ > dither
[x
& 15];
2883 pk
= pc
&& pm
&& py
;
2886 *kptr
^= bitmask
; /* Black */
2889 *cptr
^= bitmask
; /* Blue (cyan + light magenta) */
2894 *lcptr
^= bitmask
; /* Green (light cyan + yellow) */
2899 *mptr
^= bitmask
; /* Red (magenta + yellow) */
2924 case CUPS_ORDER_PLANAR
:
2925 bitmask
= 0x80 >> (bitoffset
& 7);
2926 dither
= Floyd16x16
[y
& 15];
2928 for (x
= xsize
; x
> 0; x
--)
2930 pc
= *r0
++ > dither
[x
& 15];
2931 pm
= *r0
++ > dither
[x
& 15];
2932 py
= *r0
++ > dither
[x
& 15];
2933 pk
= pc
&& pm
&& py
;
2937 else if (pc
&& pm
&& (z
== 1 || z
== 5))
2938 *ptr
^= bitmask
; /* Blue (cyan + light magenta) */
2939 else if (pc
&& py
&& (z
== 3 || z
== 4))
2940 *ptr
^= bitmask
; /* Green (light cyan + yellow) */
2941 else if (pm
&& py
&& (z
== 2 || z
== 3))
2942 *ptr
^= bitmask
; /* Red (magenta + yellow) */
2943 else if (pc
&& z
== 1)
2945 else if (pm
&& z
== 2)
2947 else if (py
&& z
== 3)
2964 * 'format_RGBA()' - Convert image data to RGBA/RGBW.
2968 format_RGBA(cups_page_header2_t
*header
,/* I - Page header */
2969 unsigned char *row
, /* IO - Bitmap data for device */
2970 int y
, /* I - Current row */
2971 int z
, /* I - Current plane */
2972 int xsize
, /* I - Width of image data */
2973 int ysize
, /* I - Height of image data */
2974 int yerr0
, /* I - Top Y error */
2975 int yerr1
, /* I - Bottom Y error */
2976 cups_ib_t
*r0
, /* I - Primary image data */
2977 cups_ib_t
*r1
) /* I - Image data for interpolation */
2979 cups_ib_t
*ptr
, /* Pointer into row */
2980 *cptr
, /* Pointer into cyan */
2981 *mptr
, /* Pointer into magenta */
2982 *yptr
, /* Pointer into yellow */
2983 bitmask
; /* Current mask for pixel */
2984 int bitoffset
; /* Current offset in line */
2985 int bandwidth
; /* Width of a color band */
2986 int x
, /* Current X coordinate on page */
2987 *dither
; /* Pointer into dither array */
2996 bitoffset
= header
->cupsBitsPerPixel
* ((header
->cupsWidth
- xsize
) / 2);
2999 bitoffset
= header
->cupsBitsPerPixel
* (header
->cupsWidth
- xsize
);
3003 ptr
= row
+ bitoffset
/ 8;
3004 bandwidth
= header
->cupsBytesPerLine
/ 4;
3006 switch (header
->cupsColorOrder
)
3008 case CUPS_ORDER_CHUNKED
:
3009 switch (header
->cupsBitsPerColor
)
3012 bitmask
= 128 >> (bitoffset
& 7);
3013 dither
= Floyd16x16
[y
& 15];
3015 for (x
= xsize
; x
> 0; x
--)
3017 if (*r0
++ > dither
[x
& 15])
3021 if (*r0
++ > dither
[x
& 15])
3025 if (*r0
++ > dither
[x
& 15])
3039 dither
= Floyd8x8
[y
& 7];
3041 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3043 if ((r0
[0] & 63) > dither
[x
& 7])
3044 *ptr
^= (0xc0 & OnPixels
[r0
[0]]);
3046 *ptr
^= (0xc0 & OffPixels
[r0
[0]]);
3048 if ((r0
[1] & 63) > dither
[x
& 7])
3049 *ptr
^= (0x30 & OnPixels
[r0
[1]]);
3051 *ptr
^= (0x30 & OffPixels
[r0
[1]]);
3053 if ((r0
[2] & 63) > dither
[x
& 7])
3054 *ptr
^= (0x0c & OnPixels
[r0
[2]]);
3056 *ptr
^= (0x0c & OffPixels
[r0
[2]]);
3063 dither
= Floyd4x4
[y
& 3];
3065 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3067 if ((r0
[0] & 15) > dither
[x
& 3])
3068 *ptr
^= (0xf0 & OnPixels
[r0
[0]]);
3070 *ptr
^= (0xf0 & OffPixels
[r0
[0]]);
3072 if ((r0
[1] & 15) > dither
[x
& 3])
3073 *ptr
++ ^= (0x0f & OnPixels
[r0
[1]]);
3075 *ptr
++ ^= (0x0f & OffPixels
[r0
[1]]);
3077 if ((r0
[2] & 15) > dither
[x
& 3])
3078 *ptr
^= (0xf0 & OnPixels
[r0
[2]]);
3080 *ptr
^= (0xf0 & OffPixels
[r0
[2]]);
3087 for (x
= xsize
; x
> 0; x
--, r0
+= 3, r1
+= 3)
3092 *ptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
3097 *ptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
3102 *ptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
3110 case CUPS_ORDER_BANDED
:
3112 mptr
= ptr
+ bandwidth
;
3113 yptr
= ptr
+ 2 * bandwidth
;
3115 memset(ptr
+ 3 * bandwidth
, 255, bandwidth
);
3117 switch (header
->cupsBitsPerColor
)
3120 bitmask
= 0x80 >> (bitoffset
& 7);
3121 dither
= Floyd16x16
[y
& 15];
3123 for (x
= xsize
; x
> 0; x
--)
3125 if (*r0
++ > dither
[x
& 15])
3127 if (*r0
++ > dither
[x
& 15])
3129 if (*r0
++ > dither
[x
& 15])
3145 bitmask
= 0xc0 >> (bitoffset
& 7);
3146 dither
= Floyd8x8
[y
& 7];
3148 for (x
= xsize
; x
> 0; x
--)
3150 if ((*r0
& 63) > dither
[x
& 7])
3151 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
3153 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
3155 if ((*r0
& 63) > dither
[x
& 7])
3156 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
3158 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
3160 if ((*r0
& 63) > dither
[x
& 7])
3161 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
3163 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
3179 bitmask
= 0xf0 >> (bitoffset
& 7);
3180 dither
= Floyd4x4
[y
& 3];
3182 for (x
= xsize
; x
> 0; x
--)
3184 if ((*r0
& 15) > dither
[x
& 3])
3185 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
3187 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
3189 if ((*r0
& 15) > dither
[x
& 3])
3190 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
3192 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
3194 if ((*r0
& 15) > dither
[x
& 3])
3195 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
3197 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
3199 if (bitmask
== 0xf0)
3213 for (x
= xsize
; x
> 0; x
--, r0
+= 3, r1
+= 3)
3218 *cptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
3223 *mptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
3228 *yptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
3234 case CUPS_ORDER_PLANAR
:
3237 memset(row
, 255, header
->cupsBytesPerLine
);
3241 switch (header
->cupsBitsPerColor
)
3244 bitmask
= 0x80 >> (bitoffset
& 7);
3245 dither
= Floyd16x16
[y
& 15];
3250 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3252 if (r0
[0] > dither
[x
& 15])
3266 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3268 if (r0
[1] > dither
[x
& 15])
3282 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3284 if (r0
[2] > dither
[x
& 15])
3300 bitmask
= 0xc0 >> (bitoffset
& 7);
3301 dither
= Floyd8x8
[y
& 7];
3304 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3306 if ((*r0
& 63) > dither
[x
& 7])
3307 *ptr
^= (bitmask
& OnPixels
[*r0
]);
3309 *ptr
^= (bitmask
& OffPixels
[*r0
]);
3323 bitmask
= 0xf0 >> (bitoffset
& 7);
3324 dither
= Floyd4x4
[y
& 3];
3327 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3329 if ((*r0
& 15) > dither
[x
& 3])
3330 *ptr
^= (bitmask
& OnPixels
[*r0
]);
3332 *ptr
^= (bitmask
& OffPixels
[*r0
]);
3334 if (bitmask
== 0xf0)
3349 for (x
= xsize
; x
> 0; x
--, r0
+= 3, r1
+= 3)
3354 *ptr
++ = (*r0
* yerr0
+ *r1
* yerr1
) / ysize
;
3364 * 'format_W()' - Convert image data to luminance.
3368 format_W(cups_page_header2_t
*header
, /* I - Page header */
3369 unsigned char *row
, /* IO - Bitmap data for device */
3370 int y
, /* I - Current row */
3371 int z
, /* I - Current plane */
3372 int xsize
, /* I - Width of image data */
3373 int ysize
, /* I - Height of image data */
3374 int yerr0
, /* I - Top Y error */
3375 int yerr1
, /* I - Bottom Y error */
3376 cups_ib_t
*r0
, /* I - Primary image data */
3377 cups_ib_t
*r1
) /* I - Image data for interpolation */
3379 cups_ib_t
*ptr
, /* Pointer into row */
3380 bitmask
; /* Current mask for pixel */
3381 int bitoffset
; /* Current offset in line */
3382 int x
, /* Current X coordinate on page */
3383 *dither
; /* Pointer into dither array */
3394 bitoffset
= header
->cupsBitsPerPixel
* ((header
->cupsWidth
- xsize
) / 2);
3397 bitoffset
= header
->cupsBitsPerPixel
* (header
->cupsWidth
- xsize
);
3401 ptr
= row
+ bitoffset
/ 8;
3403 switch (header
->cupsBitsPerColor
)
3406 bitmask
= 0x80 >> (bitoffset
& 7);
3407 dither
= Floyd16x16
[y
& 15];
3409 for (x
= xsize
; x
> 0; x
--)
3411 if (*r0
++ > dither
[x
& 15])
3425 bitmask
= 0xc0 >> (bitoffset
& 7);
3426 dither
= Floyd8x8
[y
& 7];
3428 for (x
= xsize
; x
> 0; x
--)
3430 if ((*r0
& 63) > dither
[x
& 7])
3431 *ptr
^= (bitmask
& OnPixels
[*r0
++]);
3433 *ptr
^= (bitmask
& OffPixels
[*r0
++]);
3447 bitmask
= 0xf0 >> (bitoffset
& 7);
3448 dither
= Floyd4x4
[y
& 3];
3450 for (x
= xsize
; x
> 0; x
--)
3452 if ((*r0
& 15) > dither
[x
& 3])
3453 *ptr
^= (bitmask
& OnPixels
[*r0
++]);
3455 *ptr
^= (bitmask
& OffPixels
[*r0
++]);
3457 if (bitmask
== 0xf0)
3469 for (x
= xsize
; x
> 0; x
--, r0
++, r1
++)
3474 *ptr
++ = (*r0
* yerr0
+ *r1
* yerr1
) / ysize
;
3482 * 'format_YMC()' - Convert image data to YMC.
3486 format_YMC(cups_page_header2_t
*header
, /* I - Page header */
3487 unsigned char *row
, /* IO - Bitmap data for device */
3488 int y
, /* I - Current row */
3489 int z
, /* I - Current plane */
3490 int xsize
, /* I - Width of image data */
3491 int ysize
, /* I - Height of image data */
3492 int yerr0
, /* I - Top Y error */
3493 int yerr1
, /* I - Bottom Y error */
3494 cups_ib_t
*r0
, /* I - Primary image data */
3495 cups_ib_t
*r1
) /* I - Image data for interpolation */
3497 cups_ib_t
*ptr
, /* Pointer into row */
3498 *cptr
, /* Pointer into cyan */
3499 *mptr
, /* Pointer into magenta */
3500 *yptr
, /* Pointer into yellow */
3501 bitmask
; /* Current mask for pixel */
3502 int bitoffset
; /* Current offset in line */
3503 int bandwidth
; /* Width of a color band */
3504 int x
, /* Current X coordinate on page */
3505 *dither
; /* Pointer into dither array */
3514 bitoffset
= header
->cupsBitsPerPixel
* ((header
->cupsWidth
- xsize
) / 2);
3517 bitoffset
= header
->cupsBitsPerPixel
* (header
->cupsWidth
- xsize
);
3521 ptr
= row
+ bitoffset
/ 8;
3522 bandwidth
= header
->cupsBytesPerLine
/ 3;
3524 switch (header
->cupsColorOrder
)
3526 case CUPS_ORDER_CHUNKED
:
3527 switch (header
->cupsBitsPerColor
)
3530 bitmask
= 64 >> (bitoffset
& 7);
3531 dither
= Floyd16x16
[y
& 15];
3533 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3535 if (r0
[2] > dither
[x
& 15])
3539 if (r0
[1] > dither
[x
& 15])
3543 if (r0
[0] > dither
[x
& 15])
3557 dither
= Floyd8x8
[y
& 7];
3559 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3561 if ((r0
[2] & 63) > dither
[x
& 7])
3562 *ptr
^= (0x30 & OnPixels
[r0
[2]]);
3564 *ptr
^= (0x30 & OffPixels
[r0
[2]]);
3566 if ((r0
[1] & 63) > dither
[x
& 7])
3567 *ptr
^= (0x0c & OnPixels
[r0
[1]]);
3569 *ptr
^= (0x0c & OffPixels
[r0
[1]]);
3571 if ((r0
[0] & 63) > dither
[x
& 7])
3572 *ptr
++ ^= (0x03 & OnPixels
[r0
[0]]);
3574 *ptr
++ ^= (0x03 & OffPixels
[r0
[0]]);
3579 dither
= Floyd4x4
[y
& 3];
3581 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3583 if ((r0
[2] & 15) > dither
[x
& 3])
3584 *ptr
++ ^= (0x0f & OnPixels
[r0
[2]]);
3586 *ptr
++ ^= (0x0f & OffPixels
[r0
[2]]);
3588 if ((r0
[1] & 15) > dither
[x
& 3])
3589 *ptr
^= (0xf0 & OnPixels
[r0
[1]]);
3591 *ptr
^= (0xf0 & OffPixels
[r0
[1]]);
3593 if ((r0
[0] & 15) > dither
[x
& 3])
3594 *ptr
++ ^= (0x0f & OnPixels
[r0
[0]]);
3596 *ptr
++ ^= (0x0f & OffPixels
[r0
[0]]);
3601 for (x
= xsize
; x
> 0; x
--, r0
+= 3, r1
+= 3)
3606 *ptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
3611 *ptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
3616 *ptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
3622 case CUPS_ORDER_BANDED
:
3624 mptr
= ptr
+ bandwidth
;
3625 cptr
= ptr
+ 2 * bandwidth
;
3627 switch (header
->cupsBitsPerColor
)
3630 bitmask
= 0x80 >> (bitoffset
& 7);
3631 dither
= Floyd16x16
[y
& 15];
3633 for (x
= xsize
; x
> 0; x
--)
3635 if (*r0
++ > dither
[x
& 15])
3637 if (*r0
++ > dither
[x
& 15])
3639 if (*r0
++ > dither
[x
& 15])
3655 bitmask
= 0xc0 >> (bitoffset
& 7);
3656 dither
= Floyd8x8
[y
& 7];
3658 for (x
= xsize
; x
> 0; x
--)
3660 if ((*r0
& 63) > dither
[x
& 7])
3661 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
3663 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
3665 if ((*r0
& 63) > dither
[x
& 7])
3666 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
3668 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
3670 if ((*r0
& 63) > dither
[x
& 7])
3671 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
3673 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
3689 bitmask
= 0xf0 >> (bitoffset
& 7);
3690 dither
= Floyd4x4
[y
& 3];
3692 for (x
= xsize
; x
> 0; x
--)
3694 if ((*r0
& 15) > dither
[x
& 3])
3695 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
3697 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
3699 if ((*r0
& 15) > dither
[x
& 3])
3700 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
3702 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
3704 if ((*r0
& 15) > dither
[x
& 3])
3705 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
3707 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
3709 if (bitmask
== 0xf0)
3723 for (x
= xsize
; x
> 0; x
--, r0
+= 3, r1
+= 3)
3728 *cptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
3733 *mptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
3738 *yptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
3744 case CUPS_ORDER_PLANAR
:
3745 switch (header
->cupsBitsPerColor
)
3748 bitmask
= 0x80 >> (bitoffset
& 7);
3749 dither
= Floyd16x16
[y
& 15];
3754 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3756 if (r0
[0] > dither
[x
& 15])
3770 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3772 if (r0
[1] > dither
[x
& 15])
3786 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3788 if (r0
[2] > dither
[x
& 15])
3804 bitmask
= 0xc0 >> (bitoffset
& 7);
3805 dither
= Floyd8x8
[y
& 7];
3809 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3811 if ((*r0
& 63) > dither
[x
& 7])
3812 *ptr
^= (bitmask
& OnPixels
[*r0
]);
3814 *ptr
^= (bitmask
& OffPixels
[*r0
]);
3828 bitmask
= 0xf0 >> (bitoffset
& 7);
3829 dither
= Floyd4x4
[y
& 3];
3833 for (x
= xsize
; x
> 0; x
--, r0
+= 3)
3835 if ((*r0
& 15) > dither
[x
& 3])
3836 *ptr
^= (bitmask
& OnPixels
[*r0
]);
3838 *ptr
^= (bitmask
& OffPixels
[*r0
]);
3840 if (bitmask
== 0xf0)
3856 for (x
= xsize
; x
> 0; x
--, r0
+= 3, r1
+= 3)
3861 *ptr
++ = (*r0
* yerr0
+ *r1
* yerr1
) / ysize
;
3871 * 'format_YMCK()' - Convert image data to YMCK.
3875 format_YMCK(cups_page_header2_t
*header
,/* I - Page header */
3876 unsigned char *row
, /* IO - Bitmap data for device */
3877 int y
, /* I - Current row */
3878 int z
, /* I - Current plane */
3879 int xsize
, /* I - Width of image data */
3880 int ysize
, /* I - Height of image data */
3881 int yerr0
, /* I - Top Y error */
3882 int yerr1
, /* I - Bottom Y error */
3883 cups_ib_t
*r0
, /* I - Primary image data */
3884 cups_ib_t
*r1
) /* I - Image data for interpolation */
3886 cups_ib_t
*ptr
, /* Pointer into row */
3887 *cptr
, /* Pointer into cyan */
3888 *mptr
, /* Pointer into magenta */
3889 *yptr
, /* Pointer into yellow */
3890 *kptr
, /* Pointer into black */
3891 bitmask
; /* Current mask for pixel */
3892 int bitoffset
; /* Current offset in line */
3893 int bandwidth
; /* Width of a color band */
3894 int x
, /* Current X coordinate on page */
3895 *dither
; /* Pointer into dither array */
3896 int pc
, pm
, py
; /* CMY pixels */
3905 bitoffset
= header
->cupsBitsPerPixel
* ((header
->cupsWidth
- xsize
) / 2);
3908 bitoffset
= header
->cupsBitsPerPixel
* (header
->cupsWidth
- xsize
);
3912 ptr
= row
+ bitoffset
/ 8;
3913 bandwidth
= header
->cupsBytesPerLine
/ 4;
3915 switch (header
->cupsColorOrder
)
3917 case CUPS_ORDER_CHUNKED
:
3918 switch (header
->cupsBitsPerColor
)
3921 bitmask
= 128 >> (bitoffset
& 7);
3922 dither
= Floyd16x16
[y
& 15];
3924 for (x
= xsize
; x
> 0; x
--)
3926 pc
= *r0
++ > dither
[x
& 15];
3927 pm
= *r0
++ > dither
[x
& 15];
3928 py
= *r0
++ > dither
[x
& 15];
3962 dither
= Floyd8x8
[y
& 7];
3964 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
3966 if ((r0
[2] & 63) > dither
[x
& 7])
3967 *ptr
^= (0xc0 & OnPixels
[r0
[2]]);
3969 *ptr
^= (0xc0 & OffPixels
[r0
[2]]);
3971 if ((r0
[1] & 63) > dither
[x
& 7])
3972 *ptr
^= (0x30 & OnPixels
[r0
[1]]);
3974 *ptr
^= (0x30 & OffPixels
[r0
[1]]);
3976 if ((r0
[0] & 63) > dither
[x
& 7])
3977 *ptr
^= (0x0c & OnPixels
[r0
[0]]);
3979 *ptr
^= (0x0c & OffPixels
[r0
[0]]);
3981 if ((r0
[3] & 63) > dither
[x
& 7])
3982 *ptr
++ ^= (0x03 & OnPixels
[r0
[3]]);
3984 *ptr
++ ^= (0x03 & OffPixels
[r0
[3]]);
3989 dither
= Floyd4x4
[y
& 3];
3991 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
3993 if ((r0
[2] & 15) > dither
[x
& 3])
3994 *ptr
^= (0xf0 & OnPixels
[r0
[2]]);
3996 *ptr
^= (0xf0 & OffPixels
[r0
[2]]);
3998 if ((r0
[1] & 15) > dither
[x
& 3])
3999 *ptr
++ ^= (0x0f & OnPixels
[r0
[1]]);
4001 *ptr
++ ^= (0x0f & OffPixels
[r0
[1]]);
4003 if ((r0
[0] & 15) > dither
[x
& 3])
4004 *ptr
^= (0xf0 & OnPixels
[r0
[0]]);
4006 *ptr
^= (0xf0 & OffPixels
[r0
[0]]);
4008 if ((r0
[3] & 15) > dither
[x
& 3])
4009 *ptr
++ ^= (0x0f & OnPixels
[r0
[3]]);
4011 *ptr
++ ^= (0x0f & OffPixels
[r0
[3]]);
4016 for (x
= xsize
; x
> 0; x
--, r0
+= 4, r1
+= 4)
4021 *ptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
4026 *ptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
4031 *ptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
4036 *ptr
++ = (r0
[3] * yerr0
+ r1
[3] * yerr1
) / ysize
;
4042 case CUPS_ORDER_BANDED
:
4044 mptr
= ptr
+ bandwidth
;
4045 cptr
= ptr
+ 2 * bandwidth
;
4046 kptr
= ptr
+ 3 * bandwidth
;
4048 switch (header
->cupsBitsPerColor
)
4051 bitmask
= 0x80 >> (bitoffset
& 7);
4052 dither
= Floyd16x16
[y
& 15];
4054 for (x
= xsize
; x
> 0; x
--)
4056 pc
= *r0
++ > dither
[x
& 15];
4057 pm
= *r0
++ > dither
[x
& 15];
4058 py
= *r0
++ > dither
[x
& 15];
4087 bitmask
= 0xc0 >> (bitoffset
& 7);
4088 dither
= Floyd8x8
[y
& 7];
4090 for (x
= xsize
; x
> 0; x
--)
4092 if ((*r0
& 63) > dither
[x
& 7])
4093 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
4095 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
4097 if ((*r0
& 63) > dither
[x
& 7])
4098 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
4100 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
4102 if ((*r0
& 63) > dither
[x
& 7])
4103 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
4105 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
4107 if ((*r0
& 63) > dither
[x
& 7])
4108 *kptr
^= (bitmask
& OnPixels
[*r0
++]);
4110 *kptr
^= (bitmask
& OffPixels
[*r0
++]);
4127 bitmask
= 0xf0 >> (bitoffset
& 7);
4128 dither
= Floyd4x4
[y
& 3];
4130 for (x
= xsize
; x
> 0; x
--)
4132 if ((*r0
& 15) > dither
[x
& 3])
4133 *cptr
^= (bitmask
& OnPixels
[*r0
++]);
4135 *cptr
^= (bitmask
& OffPixels
[*r0
++]);
4137 if ((*r0
& 15) > dither
[x
& 3])
4138 *mptr
^= (bitmask
& OnPixels
[*r0
++]);
4140 *mptr
^= (bitmask
& OffPixels
[*r0
++]);
4142 if ((*r0
& 15) > dither
[x
& 3])
4143 *yptr
^= (bitmask
& OnPixels
[*r0
++]);
4145 *yptr
^= (bitmask
& OffPixels
[*r0
++]);
4147 if ((*r0
& 15) > dither
[x
& 3])
4148 *kptr
^= (bitmask
& OnPixels
[*r0
++]);
4150 *kptr
^= (bitmask
& OffPixels
[*r0
++]);
4152 if (bitmask
== 0xf0)
4167 for (x
= xsize
; x
> 0; x
--, r0
+= 4, r1
+= 4)
4172 *cptr
++ = (r0
[0] * yerr0
+ r1
[0] * yerr1
) / ysize
;
4177 *mptr
++ = (r0
[1] * yerr0
+ r1
[1] * yerr1
) / ysize
;
4182 *yptr
++ = (r0
[2] * yerr0
+ r1
[2] * yerr1
) / ysize
;
4187 *kptr
++ = (r0
[3] * yerr0
+ r1
[3] * yerr1
) / ysize
;
4193 case CUPS_ORDER_PLANAR
:
4194 switch (header
->cupsBitsPerColor
)
4197 bitmask
= 0x80 >> (bitoffset
& 7);
4198 dither
= Floyd16x16
[y
& 15];
4200 for (x
= xsize
; x
> 0; x
--)
4202 pc
= *r0
++ > dither
[x
& 15];
4203 pm
= *r0
++ > dither
[x
& 15];
4204 py
= *r0
++ > dither
[x
& 15];
4206 if ((pc
&& pm
&& py
&& z
== 3) ||
4207 (pc
&& z
== 2) || (pm
&& z
== 1) || (py
&& z
== 0))
4221 bitmask
= 0xc0 >> (bitoffset
& 7);
4222 dither
= Floyd8x8
[y
& 7];
4228 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
4230 if ((*r0
& 63) > dither
[x
& 7])
4231 *ptr
^= (bitmask
& OnPixels
[*r0
]);
4233 *ptr
^= (bitmask
& OffPixels
[*r0
]);
4247 bitmask
= 0xf0 >> (bitoffset
& 7);
4248 dither
= Floyd4x4
[y
& 3];
4254 for (x
= xsize
; x
> 0; x
--, r0
+= 4)
4256 if ((*r0
& 15) > dither
[x
& 3])
4257 *ptr
^= (bitmask
& OnPixels
[*r0
]);
4259 *ptr
^= (bitmask
& OffPixels
[*r0
]);
4261 if (bitmask
== 0xf0)
4284 for (x
= xsize
; x
> 0; x
--, r0
+= 4, r1
+= 4)
4289 *ptr
++ = (*r0
* yerr0
+ *r1
* yerr1
) / ysize
;
4299 * 'make_lut()' - Make a lookup table given gamma and brightness values.
4303 make_lut(cups_ib_t
*lut
, /* I - Lookup table */
4304 int colorspace
, /* I - Colorspace */
4305 float g
, /* I - Image gamma */
4306 float b
) /* I - Image brightness */
4308 int i
; /* Looping var */
4309 int v
; /* Current value */
4315 for (i
= 0; i
< 256; i
++)
4318 v
= 255.0 * b
* (1.0 - pow(1.0 - (float)i
/ 255.0, g
)) + 0.5;
4320 v
= 255.0 * (1.0 - b
* (1.0 - pow((float)i
/ 255.0, g
))) + 0.5;
4333 * 'raster_cb()' - Validate the page header.
4336 static int /* O - 0 if OK, -1 if not */
4338 cups_page_header2_t
*header
, /* IO - Raster header */
4339 int preferred_bits
) /* I - Preferred bits per color */
4342 * Ensure that colorimetric colorspaces use at least 8 bits per
4346 if ((header
->cupsColorSpace
== CUPS_CSPACE_CIEXYZ
||
4347 header
->cupsColorSpace
== CUPS_CSPACE_CIELab
||
4348 header
->cupsColorSpace
>= CUPS_CSPACE_ICC1
) &&
4349 header
->cupsBitsPerColor
< 8)
4350 header
->cupsBitsPerColor
= 8;
4357 * End of "$Id: imagetoraster.c 7306 2008-02-15 00:52:38Z mike $".