4
* Image file to raster filter for CUPS.
6
* Copyright 2007-2011 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 <cupsfilters/image-private.h>
50
int Flip = 0, /* Flip/mirror pages */
51
XPosition = 0, /* Horizontal position on page */
52
YPosition = 0, /* Vertical position on page */
53
Collate = 0, /* Collate copies? */
54
Copies = 1; /* Number of copies */
55
int Floyd16x16[16][16] = /* Traditional Floyd ordered dither */
57
{ 0, 128, 32, 160, 8, 136, 40, 168,
58
2, 130, 34, 162, 10, 138, 42, 170 },
59
{ 192, 64, 224, 96, 200, 72, 232, 104,
60
194, 66, 226, 98, 202, 74, 234, 106 },
61
{ 48, 176, 16, 144, 56, 184, 24, 152,
62
50, 178, 18, 146, 58, 186, 26, 154 },
63
{ 240, 112, 208, 80, 248, 120, 216, 88,
64
242, 114, 210, 82, 250, 122, 218, 90 },
65
{ 12, 140, 44, 172, 4, 132, 36, 164,
66
14, 142, 46, 174, 6, 134, 38, 166 },
67
{ 204, 76, 236, 108, 196, 68, 228, 100,
68
206, 78, 238, 110, 198, 70, 230, 102 },
69
{ 60, 188, 28, 156, 52, 180, 20, 148,
70
62, 190, 30, 158, 54, 182, 22, 150 },
71
{ 252, 124, 220, 92, 244, 116, 212, 84,
72
254, 126, 222, 94, 246, 118, 214, 86 },
73
{ 3, 131, 35, 163, 11, 139, 43, 171,
74
1, 129, 33, 161, 9, 137, 41, 169 },
75
{ 195, 67, 227, 99, 203, 75, 235, 107,
76
193, 65, 225, 97, 201, 73, 233, 105 },
77
{ 51, 179, 19, 147, 59, 187, 27, 155,
78
49, 177, 17, 145, 57, 185, 25, 153 },
79
{ 243, 115, 211, 83, 251, 123, 219, 91,
80
241, 113, 209, 81, 249, 121, 217, 89 },
81
{ 15, 143, 47, 175, 7, 135, 39, 167,
82
13, 141, 45, 173, 5, 133, 37, 165 },
83
{ 207, 79, 239, 111, 199, 71, 231, 103,
84
205, 77, 237, 109, 197, 69, 229, 101 },
85
{ 63, 191, 31, 159, 55, 183, 23, 151,
86
61, 189, 29, 157, 53, 181, 21, 149 },
87
{ 254, 127, 223, 95, 247, 119, 215, 87,
88
253, 125, 221, 93, 245, 117, 213, 85 }
92
{ 0, 32, 8, 40, 2, 34, 10, 42 },
93
{ 48, 16, 56, 24, 50, 18, 58, 26 },
94
{ 12, 44, 4, 36, 14, 46, 6, 38 },
95
{ 60, 28, 52, 20, 62, 30, 54, 22 },
96
{ 3, 35, 11, 43, 1, 33, 9, 41 },
97
{ 51, 19, 59, 27, 49, 17, 57, 25 },
98
{ 15, 47, 7, 39, 13, 45, 5, 37 },
99
{ 63, 31, 55, 23, 61, 29, 53, 21 }
109
cups_ib_t OnPixels[256], /* On-pixel LUT */
110
OffPixels[256]; /* Off-pixel LUT */
117
static void blank_line(cups_page_header2_t *header, unsigned char *row);
118
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);
119
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);
120
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);
121
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);
122
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);
123
#define format_RGB format_CMY
124
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);
125
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);
126
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);
127
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);
128
static void make_lut(cups_ib_t *, int, float, float);
129
static int raster_cb(cups_page_header2_t *header, int preferred_bits);
133
* 'main()' - Main entry...
136
int /* O - Exit status */
137
main(int argc, /* I - Number of command-line arguments */
138
char *argv[]) /* I - Command-line arguments */
140
int i; /* Looping var */
141
cups_image_t *img; /* Image to print */
142
float xprint, /* Printable area */
144
xinches, /* Total size in inches */
146
float xsize, /* Total size in points */
150
float aspect; /* Aspect ratio */
151
int xpages, /* # x pages */
152
ypages, /* # y pages */
153
xpage, /* Current x page */
154
ypage, /* Current y page */
155
xtemp, /* Bitmap width in pixels */
156
ytemp, /* Bitmap height in pixels */
157
page; /* Current page number */
158
int xc0, yc0, /* Corners of the page in image coords */
160
ppd_file_t *ppd; /* PPD file */
161
ppd_choice_t *choice; /* PPD option choice */
162
char *resolution, /* Output resolution */
163
*media_type; /* Media type */
164
ppd_profile_t *profile; /* Color profile */
165
ppd_profile_t userprofile; /* User-specified profile */
166
cups_raster_t *ras; /* Raster stream */
167
cups_page_header2_t header; /* Page header */
168
int num_options; /* Number of print options */
169
cups_option_t *options; /* Print options */
170
const char *val; /* Option value */
171
int slowcollate, /* Collate copies the slow way */
172
slowcopies; /* Make copies the "slow" way? */
173
float g; /* Gamma correction value */
174
float b; /* Brightness factor */
175
float zoom; /* Zoom facter */
176
int xppi, yppi; /* Pixels-per-inch */
177
int hue, sat; /* Hue and saturation adjustment */
178
cups_izoom_t *z; /* Image zoom buffer */
179
cups_iztype_t zoom_type; /* Image zoom type */
180
int primary, /* Primary image colorspace */
181
secondary; /* Secondary image colorspace */
182
cups_ib_t *row, /* Current row */
184
*r1; /* Bottom row */
185
int y, /* Current Y coordinate on page */
186
iy, /* Current Y coordinate in image */
187
last_iy, /* Previous Y coordinate in image */
188
yerr0, /* Top Y error value */
189
yerr1; /* Bottom Y error value */
190
cups_ib_t lut[256]; /* Gamma/brightness LUT */
191
int plane, /* Current color plane */
192
num_planes; /* Number of color planes */
193
char filename[1024]; /* Name of file to print */
197
* Make sure status messages are not buffered...
200
setbuf(stderr, NULL);
203
* Ignore broken pipe signals...
206
signal(SIGPIPE, SIG_IGN);
209
* Check command-line...
212
if (argc < 6 || argc > 7)
214
fprintf(stderr, "Usage: %s job-id user title copies options [file]\n",
220
* See if we need to use the imagetops and pstoraster filters instead...
224
num_options = cupsParseOptions(argv[5], 0, &options);
226
if (getenv("CLASSIFICATION") ||
227
cupsGetOption("page-label", num_options, options))
230
* Yes, fork a copy of pstoraster and then transfer control to imagetops...
233
int mypipes[2]; /* New pipes for imagetops | pstoraster */
234
int pid; /* PID of pstoraster */
237
cupsFreeOptions(num_options, options);
241
perror("ERROR: Unable to create pipes for filters");
245
if ((pid = fork()) == 0)
248
* Child process for pstoraster... Assign new pipe input to pstoraster...
255
execlp("pstoraster", argv[0], argv[1], argv[2], argv[3], argv[4], argv[5],
265
perror("ERROR: Unable to fork filter");
270
* Update stdout so it points at the new pstoraster...
278
* Run imagetops to get the classification or page labeling that was
282
execlp("imagetops", argv[0], argv[1], argv[2], argv[3], argv[4], argv[5],
288
* Copy stdin as needed...
293
int fd; /* File to write to */
294
char buffer[8192]; /* Buffer to read into */
295
int bytes; /* # of bytes to read */
298
if ((fd = cupsTempFd(filename, sizeof(filename))) < 0)
300
perror("ERROR: Unable to copy print file");
305
"DEBUG: imagetoraster - copying to temp print file \"%s\".\n",
308
while ((bytes = fread(buffer, 1, sizeof(buffer), stdin)) > 0)
309
write(fd, buffer, bytes);
315
strncpy(filename, argv[6], sizeof(filename) - 1);
316
filename[sizeof(filename) - 1] = '\0';
320
* Process command-line options and write the prolog...
331
Copies = atoi(argv[4]);
333
ppd = SetCommonOptions(num_options, options, 0);
335
if ((val = cupsGetOption("multiple-document-handling", num_options, options)) != NULL)
338
* This IPP attribute is unnecessarily complicated...
340
* single-document, separate-documents-collated-copies, and
341
* single-document-new-sheet all require collated copies.
343
* separate-documents-collated-copies allows for uncollated copies.
346
Collate = strcasecmp(val, "separate-documents-collated-copies") != 0;
349
if ((val = cupsGetOption("Collate", num_options, options)) != NULL &&
350
strcasecmp(val, "True") == 0)
353
if ((val = cupsGetOption("gamma", num_options, options)) != NULL)
356
* Get gamma value from 1 to 10000...
359
g = atoi(val) * 0.001f;
367
if ((val = cupsGetOption("brightness", num_options, options)) != NULL)
370
* Get brightness value from 10 to 1000.
373
b = atoi(val) * 0.01f;
381
if ((val = cupsGetOption("scaling", num_options, options)) != NULL)
382
zoom = atoi(val) * 0.01;
384
cupsGetOption("fit-to-page", num_options, options)) != NULL) ||
385
((val = cupsGetOption("fitplot", num_options, options)) != NULL))
387
if (!strcasecmp(val, "yes") || !strcasecmp(val, "on") ||
388
!strcasecmp(val, "true"))
393
else if ((val = cupsGetOption("natural-scaling", num_options, options)) != NULL)
396
if ((val = cupsGetOption("ppi", num_options, options)) != NULL)
398
if (sscanf(val, "%dx%d", &xppi, &yppi) < 2)
403
if ((val = cupsGetOption("position", num_options, options)) != NULL)
405
if (strcasecmp(val, "center") == 0)
410
else if (strcasecmp(val, "top") == 0)
415
else if (strcasecmp(val, "left") == 0)
420
else if (strcasecmp(val, "right") == 0)
425
else if (strcasecmp(val, "top-left") == 0)
430
else if (strcasecmp(val, "top-right") == 0)
435
else if (strcasecmp(val, "bottom") == 0)
440
else if (strcasecmp(val, "bottom-left") == 0)
445
else if (strcasecmp(val, "bottom-right") == 0)
452
if ((val = cupsGetOption("saturation", num_options, options)) != NULL)
455
if ((val = cupsGetOption("hue", num_options, options)) != NULL)
458
if ((choice = ppdFindMarkedChoice(ppd, "MirrorPrint")) != NULL)
460
val = choice->choice;
464
val = cupsGetOption("mirror", num_options, options);
466
if (val && (!strcasecmp(val, "true") || !strcasecmp(val, "on") ||
467
!strcasecmp(val, "yes")))
471
* Set the needed options in the page header...
474
if (cupsRasterInterpretPPD(&header, ppd, num_options, options, raster_cb))
476
fputs("ERROR: The page setup information was not valid.\n", stderr);
477
fprintf(stderr, "DEBUG: %s\n", cupsRasterErrorString());
482
* Get the media type and resolution that have been chosen...
485
if ((choice = ppdFindMarkedChoice(ppd, "MediaType")) != NULL)
486
media_type = choice->choice;
490
if ((choice = ppdFindMarkedChoice(ppd, "Resolution")) != NULL)
491
resolution = choice->choice;
496
* Choose the appropriate colorspace...
499
switch (header.cupsColorSpace)
502
case CUPS_CSPACE_SW :
503
if (header.cupsBitsPerColor >= 8)
505
primary = CUPS_IMAGE_WHITE;
506
secondary = CUPS_IMAGE_WHITE;
510
primary = CUPS_IMAGE_BLACK;
511
secondary = CUPS_IMAGE_BLACK;
516
case CUPS_CSPACE_RGB :
517
case CUPS_CSPACE_RGBA :
518
case CUPS_CSPACE_RGBW :
519
case CUPS_CSPACE_SRGB :
520
case CUPS_CSPACE_ADOBERGB :
521
if (header.cupsBitsPerColor >= 8)
523
primary = CUPS_IMAGE_RGB;
524
secondary = CUPS_IMAGE_RGB;
528
primary = CUPS_IMAGE_CMY;
529
secondary = CUPS_IMAGE_CMY;
534
case CUPS_CSPACE_WHITE :
535
case CUPS_CSPACE_GOLD :
536
case CUPS_CSPACE_SILVER :
537
primary = CUPS_IMAGE_BLACK;
538
secondary = CUPS_IMAGE_BLACK;
541
case CUPS_CSPACE_CMYK :
542
case CUPS_CSPACE_YMCK :
543
case CUPS_CSPACE_KCMY :
544
case CUPS_CSPACE_KCMYcm :
545
case CUPS_CSPACE_GMCK :
546
case CUPS_CSPACE_GMCS :
547
if (header.cupsBitsPerColor == 1)
549
primary = CUPS_IMAGE_CMY;
550
secondary = CUPS_IMAGE_CMY;
554
primary = CUPS_IMAGE_CMYK;
555
secondary = CUPS_IMAGE_CMYK;
559
case CUPS_CSPACE_CMY :
560
case CUPS_CSPACE_YMC :
561
primary = CUPS_IMAGE_CMY;
562
secondary = CUPS_IMAGE_CMY;
565
case CUPS_CSPACE_CIEXYZ :
566
case CUPS_CSPACE_CIELab :
567
case CUPS_CSPACE_ICC1 :
568
case CUPS_CSPACE_ICC2 :
569
case CUPS_CSPACE_ICC3 :
570
case CUPS_CSPACE_ICC4 :
571
case CUPS_CSPACE_ICC5 :
572
case CUPS_CSPACE_ICC6 :
573
case CUPS_CSPACE_ICC7 :
574
case CUPS_CSPACE_ICC8 :
575
case CUPS_CSPACE_ICC9 :
576
case CUPS_CSPACE_ICCA :
577
case CUPS_CSPACE_ICCB :
578
case CUPS_CSPACE_ICCC :
579
case CUPS_CSPACE_ICCD :
580
case CUPS_CSPACE_ICCE :
581
case CUPS_CSPACE_ICCF :
582
case CUPS_CSPACE_DEVICE1 :
583
case CUPS_CSPACE_DEVICE2 :
584
case CUPS_CSPACE_DEVICE3 :
585
case CUPS_CSPACE_DEVICE4 :
586
case CUPS_CSPACE_DEVICE5 :
587
case CUPS_CSPACE_DEVICE6 :
588
case CUPS_CSPACE_DEVICE7 :
589
case CUPS_CSPACE_DEVICE8 :
590
case CUPS_CSPACE_DEVICE9 :
591
case CUPS_CSPACE_DEVICEA :
592
case CUPS_CSPACE_DEVICEB :
593
case CUPS_CSPACE_DEVICEC :
594
case CUPS_CSPACE_DEVICED :
595
case CUPS_CSPACE_DEVICEE :
596
case CUPS_CSPACE_DEVICEF :
597
fprintf(stderr, "DEBUG: Colorspace %d not supported.\n",
598
header.cupsColorSpace);
604
* Find a color profile matching the current options...
607
if ((val = cupsGetOption("profile", num_options, options)) != NULL)
609
profile = &userprofile;
610
sscanf(val, "%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f",
611
&(userprofile.density), &(userprofile.gamma),
612
userprofile.matrix[0] + 0, userprofile.matrix[0] + 1,
613
userprofile.matrix[0] + 2,
614
userprofile.matrix[1] + 0, userprofile.matrix[1] + 1,
615
userprofile.matrix[1] + 2,
616
userprofile.matrix[2] + 0, userprofile.matrix[2] + 1,
617
userprofile.matrix[2] + 2);
619
userprofile.density *= 0.001f;
620
userprofile.gamma *= 0.001f;
621
userprofile.matrix[0][0] *= 0.001f;
622
userprofile.matrix[0][1] *= 0.001f;
623
userprofile.matrix[0][2] *= 0.001f;
624
userprofile.matrix[1][0] *= 0.001f;
625
userprofile.matrix[1][1] *= 0.001f;
626
userprofile.matrix[1][2] *= 0.001f;
627
userprofile.matrix[2][0] *= 0.001f;
628
userprofile.matrix[2][1] *= 0.001f;
629
userprofile.matrix[2][2] *= 0.001f;
631
else if (ppd != NULL)
633
fprintf(stderr, "DEBUG: Searching for profile \"%s/%s\"...\n",
634
resolution, media_type);
636
for (i = 0, profile = ppd->profiles; i < ppd->num_profiles; i ++, profile ++)
638
fprintf(stderr, "DEBUG: \"%s/%s\" = ", profile->resolution,
639
profile->media_type);
641
if ((strcmp(profile->resolution, resolution) == 0 ||
642
profile->resolution[0] == '-') &&
643
(strcmp(profile->media_type, media_type) == 0 ||
644
profile->media_type[0] == '-'))
646
fputs("MATCH\n", stderr);
650
fputs("no.\n", stderr);
654
* If we found a color profile, use it!
657
if (i >= ppd->num_profiles)
664
cupsImageSetProfile(profile->density, profile->gamma, profile->matrix);
666
cupsImageSetRasterColorSpace(header.cupsColorSpace);
669
* Create a gamma/brightness LUT...
672
make_lut(lut, primary, g, b);
675
* Open the input image to print...
678
fputs("INFO: Loading print file.\n", stderr);
680
if (header.cupsColorSpace == CUPS_CSPACE_CIEXYZ ||
681
header.cupsColorSpace == CUPS_CSPACE_CIELab ||
682
header.cupsColorSpace >= CUPS_CSPACE_ICC1)
683
img = cupsImageOpen(filename, primary, secondary, sat, hue, NULL);
685
img = cupsImageOpen(filename, primary, secondary, sat, hue, lut);
692
fputs("ERROR: The print file could not be opened.\n", stderr);
698
* Scale as necessary...
701
if (zoom == 0.0 && xppi == 0)
710
fprintf(stderr, "DEBUG: Before scaling: xppi=%d, yppi=%d, zoom=%.2f\n",
716
* Scale the image as neccesary to match the desired pixels-per-inch.
721
xprint = (PageTop - PageBottom) / 72.0;
722
yprint = (PageRight - PageLeft) / 72.0;
726
xprint = (PageRight - PageLeft) / 72.0;
727
yprint = (PageTop - PageBottom) / 72.0;
730
fprintf(stderr, "DEBUG: Before scaling: xprint=%.1f, yprint=%.1f\n",
733
xinches = (float)img->xsize / (float)xppi;
734
yinches = (float)img->ysize / (float)yppi;
736
fprintf(stderr, "DEBUG: Image size is %.1f x %.1f inches...\n",
739
if ((val = cupsGetOption("natural-scaling", num_options, options)) != NULL)
741
xinches = xinches * atoi(val) / 100;
742
yinches = yinches * atoi(val) / 100;
745
if (cupsGetOption("orientation-requested", num_options, options) == NULL &&
746
cupsGetOption("landscape", num_options, options) == NULL)
749
* Rotate the image if it will fit landscape but not portrait...
752
fputs("DEBUG: Auto orientation...\n", stderr);
754
if ((xinches > xprint || yinches > yprint) &&
755
xinches <= yprint && yinches <= xprint)
758
* Rotate the image as needed...
761
fputs("DEBUG: Using landscape orientation...\n", stderr);
763
Orientation = (Orientation + 1) & 3;
773
* Scale percentage of page size...
776
xprint = (PageRight - PageLeft) / 72.0;
777
yprint = (PageTop - PageBottom) / 72.0;
778
aspect = (float)img->yppi / (float)img->xppi;
780
fprintf(stderr, "DEBUG: Before scaling: xprint=%.1f, yprint=%.1f\n",
783
fprintf(stderr, "DEBUG: img->xppi = %d, img->yppi = %d, aspect = %f\n",
784
img->xppi, img->yppi, aspect);
786
xsize = xprint * zoom;
787
ysize = xsize * img->ysize / img->xsize / aspect;
789
if (ysize > (yprint * zoom))
791
ysize = yprint * zoom;
792
xsize = ysize * img->xsize * aspect / img->ysize;
795
xsize2 = yprint * zoom;
796
ysize2 = xsize2 * img->ysize / img->xsize / aspect;
798
if (ysize2 > (xprint * zoom))
800
ysize2 = xprint * zoom;
801
xsize2 = ysize2 * img->xsize * aspect / img->ysize;
804
fprintf(stderr, "DEBUG: Portrait size is %.2f x %.2f inches\n", xsize, ysize);
805
fprintf(stderr, "DEBUG: Landscape size is %.2f x %.2f inches\n", xsize2, ysize2);
807
if (cupsGetOption("orientation-requested", num_options, options) == NULL &&
808
cupsGetOption("landscape", num_options, options) == NULL)
811
* Choose the rotation with the largest area, but prefer
812
* portrait if they are equal...
815
fputs("DEBUG: Auto orientation...\n", stderr);
817
if ((xsize * ysize) < (xsize2 * xsize2))
820
* Do landscape orientation...
823
fputs("DEBUG: Using landscape orientation...\n", stderr);
828
xprint = (PageTop - PageBottom) / 72.0;
829
yprint = (PageRight - PageLeft) / 72.0;
834
* Do portrait orientation...
837
fputs("DEBUG: Using portrait orientation...\n", stderr);
844
else if (Orientation & 1)
846
fputs("DEBUG: Using landscape orientation...\n", stderr);
850
xprint = (PageTop - PageBottom) / 72.0;
851
yprint = (PageRight - PageLeft) / 72.0;
855
fputs("DEBUG: Using portrait orientation...\n", stderr);
859
xprint = (PageRight - PageLeft) / 72.0;
860
yprint = (PageTop - PageBottom) / 72.0;
865
* Compute the number of pages to print and the size of the image on each
869
xpages = ceil(xinches / xprint);
870
ypages = ceil(yinches / yprint);
872
xprint = xinches / xpages;
873
yprint = yinches / ypages;
875
fprintf(stderr, "DEBUG: xpages = %dx%.2fin, ypages = %dx%.2fin\n",
876
xpages, xprint, ypages, yprint);
879
* Compute the bitmap size...
882
if ((choice = ppdFindMarkedChoice(ppd, "PageSize")) != NULL &&
883
strcasecmp(choice->choice, "Custom") == 0)
885
float width, /* New width in points */
886
length; /* New length in points */
890
* Use the correct width and length for the current orientation...
895
width = yprint * 72.0;
896
length = xprint * 72.0;
900
width = xprint * 72.0;
901
length = yprint * 72.0;
905
* Add margins to page size...
908
width += ppd->custom_margins[0] + ppd->custom_margins[2];
909
length += ppd->custom_margins[1] + ppd->custom_margins[3];
912
* Enforce minimums...
915
if (width < ppd->custom_min[0])
916
width = ppd->custom_min[0];
918
if (length < ppd->custom_min[1])
919
length = ppd->custom_min[1];
921
fprintf(stderr, "DEBUG: Updated custom page size to %.2f x %.2f inches...\n",
922
width / 72.0, length / 72.0);
925
* Set the new custom size...
928
strcpy(header.cupsPageSizeName, "Custom");
930
header.cupsPageSize[0] = width + 0.5;
931
header.cupsPageSize[1] = length + 0.5;
932
header.PageSize[0] = width + 0.5;
933
header.PageSize[1] = length + 0.5;
936
* Update page variables...
941
PageLeft = ppd->custom_margins[0];
942
PageRight = width - ppd->custom_margins[2];
943
PageBottom = ppd->custom_margins[1];
944
PageTop = length - ppd->custom_margins[3];
947
* Remove margins from page size...
950
width -= ppd->custom_margins[0] + ppd->custom_margins[2];
951
length -= ppd->custom_margins[1] + ppd->custom_margins[3];
954
* Set the bitmap size...
957
header.cupsWidth = width * header.HWResolution[0] / 72.0;
958
header.cupsHeight = length * header.HWResolution[1] / 72.0;
960
header.cupsBytesPerLine = (header.cupsBitsPerPixel *
961
header.cupsWidth + 7) / 8;
963
if (header.cupsColorOrder == CUPS_ORDER_BANDED)
964
header.cupsBytesPerLine *= header.cupsNumColors;
967
header.Margins[0] = PageLeft;
968
header.Margins[1] = PageBottom;
970
fprintf(stderr, "DEBUG: PageSize = [%d %d]\n", header.PageSize[0],
979
header.cupsImagingBBox[0] = PageLeft;
980
header.cupsImagingBBox[2] = PageLeft + xprint * 72;
983
header.cupsImagingBBox[0] = (PageRight + PageLeft - xprint * 72) / 2;
984
header.cupsImagingBBox[2] = (PageRight + PageLeft + xprint * 72) / 2;
987
header.cupsImagingBBox[0] = PageRight - xprint * 72;
988
header.cupsImagingBBox[2] = PageRight;
995
header.cupsImagingBBox[1] = PageBottom;
996
header.cupsImagingBBox[3] = PageBottom + yprint * 72;
999
header.cupsImagingBBox[1] = (PageTop + PageBottom - yprint * 72) / 2;
1000
header.cupsImagingBBox[3] = (PageTop + PageBottom + yprint * 72) / 2;
1003
header.cupsImagingBBox[1] = PageTop - yprint * 72;
1004
header.cupsImagingBBox[3] = PageTop;
1013
header.cupsImagingBBox[0] = PageBottom;
1014
header.cupsImagingBBox[2] = PageBottom + yprint * 72;
1017
header.cupsImagingBBox[0] = (PageTop + PageBottom - yprint * 72) / 2;
1018
header.cupsImagingBBox[2] = (PageTop + PageBottom + yprint * 72) / 2;
1021
header.cupsImagingBBox[0] = PageTop - yprint * 72;
1022
header.cupsImagingBBox[2] = PageTop;
1029
header.cupsImagingBBox[1] = PageLeft;
1030
header.cupsImagingBBox[3] = PageLeft + xprint * 72;
1033
header.cupsImagingBBox[1] = (PageRight + PageLeft - xprint * 72) / 2;
1034
header.cupsImagingBBox[3] = (PageRight + PageLeft + xprint * 72) / 2;
1037
header.cupsImagingBBox[1] = PageRight - xprint * 72;
1038
header.cupsImagingBBox[3] = PageRight;
1047
header.cupsImagingBBox[0] = PageLeft;
1048
header.cupsImagingBBox[2] = PageLeft + xprint * 72;
1051
header.cupsImagingBBox[0] = (PageRight + PageLeft - xprint * 72) / 2;
1052
header.cupsImagingBBox[2] = (PageRight + PageLeft + xprint * 72) / 2;
1055
header.cupsImagingBBox[0] = PageRight - xprint * 72;
1056
header.cupsImagingBBox[2] = PageRight;
1063
header.cupsImagingBBox[1] = PageBottom;
1064
header.cupsImagingBBox[3] = PageBottom + yprint * 72;
1067
header.cupsImagingBBox[1] = (PageTop + PageBottom - yprint * 72) / 2;
1068
header.cupsImagingBBox[3] = (PageTop + PageBottom + yprint * 72) / 2;
1071
header.cupsImagingBBox[1] = PageTop - yprint * 72;
1072
header.cupsImagingBBox[3] = PageTop;
1081
header.cupsImagingBBox[0] = PageBottom;
1082
header.cupsImagingBBox[2] = PageBottom + yprint * 72;
1085
header.cupsImagingBBox[0] = (PageTop + PageBottom - yprint * 72) / 2;
1086
header.cupsImagingBBox[2] = (PageTop + PageBottom + yprint * 72) / 2;
1089
header.cupsImagingBBox[0] = PageTop - yprint * 72;
1090
header.cupsImagingBBox[2] = PageTop;
1097
header.cupsImagingBBox[1] = PageLeft;
1098
header.cupsImagingBBox[3] = PageLeft + xprint * 72;
1101
header.cupsImagingBBox[1] = (PageRight + PageLeft - xprint * 72) / 2;
1102
header.cupsImagingBBox[3] = (PageRight + PageLeft + xprint * 72) / 2;
1105
header.cupsImagingBBox[1] = PageRight - xprint * 72;
1106
header.cupsImagingBBox[3] = PageRight;
1112
header.ImagingBoundingBox[0] = header.cupsImagingBBox[0];
1113
header.ImagingBoundingBox[1] = header.cupsImagingBBox[1];
1114
header.ImagingBoundingBox[2] = header.cupsImagingBBox[2];
1115
header.ImagingBoundingBox[3] = header.cupsImagingBBox[3];
1117
if (header.cupsColorOrder == CUPS_ORDER_PLANAR)
1118
num_planes = header.cupsNumColors;
1122
if (header.cupsBitsPerColor >= 8)
1123
zoom_type = CUPS_IZOOM_NORMAL;
1125
zoom_type = CUPS_IZOOM_FAST;
1128
* See if we need to collate, and if so how we need to do it...
1131
if (xpages == 1 && ypages == 1)
1134
slowcollate = Collate && ppdFindOption(ppd, "Collate") == NULL;
1136
slowcopies = ppd->manual_copies;
1140
if (Copies > 1 && !slowcollate && !slowcopies)
1142
header.Collate = (cups_bool_t)Collate;
1143
header.NumCopies = Copies;
1148
header.NumCopies = 1;
1151
* Create the dithering lookup tables...
1155
OnPixels[255] = 0xff;
1156
OffPixels[0] = 0x00;
1157
OffPixels[255] = 0xff;
1159
switch (header.cupsBitsPerColor)
1162
for (i = 1; i < 255; i ++)
1164
OnPixels[i] = 0x55 * (i / 85 + 1);
1165
OffPixels[i] = 0x55 * (i / 64);
1169
for (i = 1; i < 255; i ++)
1171
OnPixels[i] = 17 * (i / 17 + 1);
1172
OffPixels[i] = 17 * (i / 16);
1178
* Output the pages...
1181
fprintf(stderr, "DEBUG: cupsWidth = %d\n", header.cupsWidth);
1182
fprintf(stderr, "DEBUG: cupsHeight = %d\n", header.cupsHeight);
1183
fprintf(stderr, "DEBUG: cupsBitsPerColor = %d\n", header.cupsBitsPerColor);
1184
fprintf(stderr, "DEBUG: cupsBitsPerPixel = %d\n", header.cupsBitsPerPixel);
1185
fprintf(stderr, "DEBUG: cupsBytesPerLine = %d\n", header.cupsBytesPerLine);
1186
fprintf(stderr, "DEBUG: cupsColorOrder = %d\n", header.cupsColorOrder);
1187
fprintf(stderr, "DEBUG: cupsColorSpace = %d\n", header.cupsColorSpace);
1188
fprintf(stderr, "DEBUG: img->colorspace = %d\n", img->colorspace);
1190
row = malloc(2 * header.cupsBytesPerLine);
1191
ras = cupsRasterOpen(1, CUPS_RASTER_WRITE);
1193
for (i = 0, page = 1; i < Copies; i ++)
1194
for (xpage = 0; xpage < xpages; xpage ++)
1195
for (ypage = 0; ypage < ypages; ypage ++, page ++)
1197
fprintf(stderr, "INFO: Formatting page %d.\n", page);
1199
if (Orientation & 1)
1201
xc0 = img->xsize * ypage / ypages;
1202
xc1 = img->xsize * (ypage + 1) / ypages - 1;
1203
yc0 = img->ysize * xpage / xpages;
1204
yc1 = img->ysize * (xpage + 1) / xpages - 1;
1206
xtemp = header.HWResolution[0] * yprint;
1207
ytemp = header.HWResolution[1] * xprint;
1211
xc0 = img->xsize * xpage / xpages;
1212
xc1 = img->xsize * (xpage + 1) / xpages - 1;
1213
yc0 = img->ysize * ypage / ypages;
1214
yc1 = img->ysize * (ypage + 1) / ypages - 1;
1216
xtemp = header.HWResolution[0] * xprint;
1217
ytemp = header.HWResolution[1] * yprint;
1220
cupsRasterWriteHeader2(ras, &header);
1222
for (plane = 0; plane < num_planes; plane ++)
1225
* Initialize the image "zoom" engine...
1229
z = _cupsImageZoomNew(img, xc0, yc0, xc1, yc1, -xtemp, ytemp,
1230
Orientation & 1, zoom_type);
1232
z = _cupsImageZoomNew(img, xc0, yc0, xc1, yc1, xtemp, ytemp,
1233
Orientation & 1, zoom_type);
1236
* Write leading blank space as needed...
1239
if (header.cupsHeight > z->ysize && YPosition <= 0)
1241
blank_line(&header, row);
1243
y = header.cupsHeight - z->ysize;
1247
fprintf(stderr, "DEBUG: Writing %d leading blank lines...\n", y);
1251
if (cupsRasterWritePixels(ras, row, header.cupsBytesPerLine) <
1252
header.cupsBytesPerLine)
1254
fputs("ERROR: Unable to send raster data to the driver.\n",
1256
cupsImageClose(img);
1263
* Then write image data...
1266
for (y = z->ysize, yerr0 = 0, yerr1 = z->ysize, iy = 0, last_iy = -2;
1272
if (zoom_type != CUPS_IZOOM_FAST && (iy - last_iy) > 1)
1273
_cupsImageZoomFill(z, iy);
1275
_cupsImageZoomFill(z, iy + z->yincr);
1281
* Format this line of raster data for the printer...
1284
blank_line(&header, row);
1286
r0 = z->rows[z->row];
1287
r1 = z->rows[1 - z->row];
1289
switch (header.cupsColorSpace)
1291
case CUPS_CSPACE_W :
1292
format_W(&header, row, y, plane, z->xsize, z->ysize,
1293
yerr0, yerr1, r0, r1);
1296
case CUPS_CSPACE_RGB :
1297
format_RGB(&header, row, y, plane, z->xsize, z->ysize,
1298
yerr0, yerr1, r0, r1);
1300
case CUPS_CSPACE_RGBA :
1301
case CUPS_CSPACE_RGBW :
1302
format_RGBA(&header, row, y, plane, z->xsize, z->ysize,
1303
yerr0, yerr1, r0, r1);
1305
case CUPS_CSPACE_K :
1306
case CUPS_CSPACE_WHITE :
1307
case CUPS_CSPACE_GOLD :
1308
case CUPS_CSPACE_SILVER :
1309
format_K(&header, row, y, plane, z->xsize, z->ysize,
1310
yerr0, yerr1, r0, r1);
1312
case CUPS_CSPACE_CMY :
1313
format_CMY(&header, row, y, plane, z->xsize, z->ysize,
1314
yerr0, yerr1, r0, r1);
1316
case CUPS_CSPACE_YMC :
1317
format_YMC(&header, row, y, plane, z->xsize, z->ysize,
1318
yerr0, yerr1, r0, r1);
1320
case CUPS_CSPACE_CMYK :
1321
format_CMYK(&header, row, y, plane, z->xsize, z->ysize,
1322
yerr0, yerr1, r0, r1);
1324
case CUPS_CSPACE_YMCK :
1325
case CUPS_CSPACE_GMCK :
1326
case CUPS_CSPACE_GMCS :
1327
format_YMCK(&header, row, y, plane, z->xsize, z->ysize,
1328
yerr0, yerr1, r0, r1);
1330
case CUPS_CSPACE_KCMYcm :
1331
if (header.cupsBitsPerColor == 1)
1333
format_KCMYcm(&header, row, y, plane, z->xsize, z->ysize,
1334
yerr0, yerr1, r0, r1);
1337
case CUPS_CSPACE_KCMY :
1338
format_KCMY(&header, row, y, plane, z->xsize, z->ysize,
1339
yerr0, yerr1, r0, r1);
1344
* Write the raster data to the driver...
1347
if (cupsRasterWritePixels(ras, row, header.cupsBytesPerLine) <
1348
header.cupsBytesPerLine)
1350
fputs("ERROR: Unable to send raster data to the driver.\n",
1352
cupsImageClose(img);
1357
* Compute the next scanline in the image...
1372
* Write trailing blank space as needed...
1375
if (header.cupsHeight > z->ysize && YPosition >= 0)
1377
blank_line(&header, row);
1379
y = header.cupsHeight - z->ysize;
1383
fprintf(stderr, "DEBUG: Writing %d trailing blank lines...\n", y);
1387
if (cupsRasterWritePixels(ras, row, header.cupsBytesPerLine) <
1388
header.cupsBytesPerLine)
1390
fputs("ERROR: Unable to send raster data to the driver.\n",
1392
cupsImageClose(img);
1399
* Free memory used for the "zoom" engine...
1402
_cupsImageZoomDelete(z);
1411
cupsRasterClose(ras);
1412
cupsImageClose(img);
1420
* 'blank_line()' - Clear a line buffer to the blank value...
1424
blank_line(cups_page_header2_t *header, /* I - Page header */
1425
unsigned char *row) /* I - Row buffer */
1427
int count; /* Remaining bytes */
1430
count = header->cupsBytesPerLine;
1432
switch (header->cupsColorSpace)
1434
case CUPS_CSPACE_CIEXYZ :
1444
case CUPS_CSPACE_CIELab :
1445
case CUPS_CSPACE_ICC1 :
1446
case CUPS_CSPACE_ICC2 :
1447
case CUPS_CSPACE_ICC3 :
1448
case CUPS_CSPACE_ICC4 :
1449
case CUPS_CSPACE_ICC5 :
1450
case CUPS_CSPACE_ICC6 :
1451
case CUPS_CSPACE_ICC7 :
1452
case CUPS_CSPACE_ICC8 :
1453
case CUPS_CSPACE_ICC9 :
1454
case CUPS_CSPACE_ICCA :
1455
case CUPS_CSPACE_ICCB :
1456
case CUPS_CSPACE_ICCC :
1457
case CUPS_CSPACE_ICCD :
1458
case CUPS_CSPACE_ICCE :
1459
case CUPS_CSPACE_ICCF :
1469
case CUPS_CSPACE_K :
1470
case CUPS_CSPACE_CMY :
1471
case CUPS_CSPACE_CMYK :
1472
case CUPS_CSPACE_YMC :
1473
case CUPS_CSPACE_YMCK :
1474
case CUPS_CSPACE_KCMY :
1475
case CUPS_CSPACE_KCMYcm :
1476
case CUPS_CSPACE_GMCK :
1477
case CUPS_CSPACE_GMCS :
1478
case CUPS_CSPACE_WHITE :
1479
case CUPS_CSPACE_GOLD :
1480
case CUPS_CSPACE_SILVER :
1481
memset(row, 0, count);
1485
memset(row, 255, count);
1492
* 'format_CMY()' - Convert image data to CMY.
1496
format_CMY(cups_page_header2_t *header, /* I - Page header */
1497
unsigned char *row, /* IO - Bitmap data for device */
1498
int y, /* I - Current row */
1499
int z, /* I - Current plane */
1500
int xsize, /* I - Width of image data */
1501
int ysize, /* I - Height of image data */
1502
int yerr0, /* I - Top Y error */
1503
int yerr1, /* I - Bottom Y error */
1504
cups_ib_t *r0, /* I - Primary image data */
1505
cups_ib_t *r1) /* I - Image data for interpolation */
1507
cups_ib_t *ptr, /* Pointer into row */
1508
*cptr, /* Pointer into cyan */
1509
*mptr, /* Pointer into magenta */
1510
*yptr, /* Pointer into yellow */
1511
bitmask; /* Current mask for pixel */
1512
int bitoffset; /* Current offset in line */
1513
int bandwidth; /* Width of a color band */
1514
int x, /* Current X coordinate on page */
1515
*dither; /* Pointer into dither array */
1524
bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2);
1527
bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize);
1531
ptr = row + bitoffset / 8;
1532
bandwidth = header->cupsBytesPerLine / 3;
1534
switch (header->cupsColorOrder)
1536
case CUPS_ORDER_CHUNKED :
1537
switch (header->cupsBitsPerColor)
1540
bitmask = 64 >> (bitoffset & 7);
1541
dither = Floyd16x16[y & 15];
1543
for (x = xsize ; x > 0; x --)
1545
if (*r0++ > dither[x & 15])
1549
if (*r0++ > dither[x & 15])
1553
if (*r0++ > dither[x & 15])
1567
dither = Floyd8x8[y & 7];
1569
for (x = xsize ; x > 0; x --, r0 += 3)
1571
if ((r0[0] & 63) > dither[x & 7])
1572
*ptr ^= (0x30 & OnPixels[r0[0]]);
1574
*ptr ^= (0x30 & OffPixels[r0[0]]);
1576
if ((r0[1] & 63) > dither[x & 7])
1577
*ptr ^= (0x0c & OnPixels[r0[1]]);
1579
*ptr ^= (0x0c & OffPixels[r0[1]]);
1581
if ((r0[2] & 63) > dither[x & 7])
1582
*ptr++ ^= (0x03 & OnPixels[r0[2]]);
1584
*ptr++ ^= (0x03 & OffPixels[r0[2]]);
1589
dither = Floyd4x4[y & 3];
1591
for (x = xsize ; x > 0; x --, r0 += 3)
1593
if ((r0[0] & 15) > dither[x & 3])
1594
*ptr++ ^= (0x0f & OnPixels[r0[0]]);
1596
*ptr++ ^= (0x0f & OffPixels[r0[0]]);
1598
if ((r0[1] & 15) > dither[x & 3])
1599
*ptr ^= (0xf0 & OnPixels[r0[1]]);
1601
*ptr ^= (0xf0 & OffPixels[r0[1]]);
1603
if ((r0[2] & 15) > dither[x & 3])
1604
*ptr++ ^= (0x0f & OnPixels[r0[2]]);
1606
*ptr++ ^= (0x0f & OffPixels[r0[2]]);
1611
for (x = xsize * 3; x > 0; x --, r0 ++, r1 ++)
1615
*ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize;
1620
case CUPS_ORDER_BANDED :
1622
mptr = ptr + bandwidth;
1623
yptr = ptr + 2 * bandwidth;
1625
switch (header->cupsBitsPerColor)
1628
bitmask = 0x80 >> (bitoffset & 7);
1629
dither = Floyd16x16[y & 15];
1631
for (x = xsize; x > 0; x --)
1633
if (*r0++ > dither[x & 15])
1635
if (*r0++ > dither[x & 15])
1637
if (*r0++ > dither[x & 15])
1653
bitmask = 0xc0 >> (bitoffset & 7);
1654
dither = Floyd8x8[y & 7];
1656
for (x = xsize; x > 0; x --)
1658
if ((*r0 & 63) > dither[x & 7])
1659
*cptr ^= (bitmask & OnPixels[*r0++]);
1661
*cptr ^= (bitmask & OffPixels[*r0++]);
1663
if ((*r0 & 63) > dither[x & 7])
1664
*mptr ^= (bitmask & OnPixels[*r0++]);
1666
*mptr ^= (bitmask & OffPixels[*r0++]);
1668
if ((*r0 & 63) > dither[x & 7])
1669
*yptr ^= (bitmask & OnPixels[*r0++]);
1671
*yptr ^= (bitmask & OffPixels[*r0++]);
1687
bitmask = 0xf0 >> (bitoffset & 7);
1688
dither = Floyd4x4[y & 3];
1690
for (x = xsize; x > 0; x --)
1692
if ((*r0 & 15) > dither[x & 3])
1693
*cptr ^= (bitmask & OnPixels[*r0++]);
1695
*cptr ^= (bitmask & OffPixels[*r0++]);
1697
if ((*r0 & 15) > dither[x & 3])
1698
*mptr ^= (bitmask & OnPixels[*r0++]);
1700
*mptr ^= (bitmask & OffPixels[*r0++]);
1702
if ((*r0 & 15) > dither[x & 3])
1703
*yptr ^= (bitmask & OnPixels[*r0++]);
1705
*yptr ^= (bitmask & OffPixels[*r0++]);
1707
if (bitmask == 0xf0)
1721
for (x = xsize; x > 0; x --, r0 += 3, r1 += 3)
1726
*cptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize;
1731
*mptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize;
1736
*yptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize;
1742
case CUPS_ORDER_PLANAR :
1743
switch (header->cupsBitsPerColor)
1746
bitmask = 0x80 >> (bitoffset & 7);
1747
dither = Floyd16x16[y & 15];
1752
for (x = xsize; x > 0; x --, r0 += 3)
1754
if (r0[0] > dither[x & 15])
1768
for (x = xsize; x > 0; x --, r0 += 3)
1770
if (r0[1] > dither[x & 15])
1784
for (x = xsize; x > 0; x --, r0 += 3)
1786
if (r0[2] > dither[x & 15])
1802
bitmask = 0xc0 >> (bitoffset & 7);
1803
dither = Floyd8x8[y & 7];
1806
for (x = xsize; x > 0; x --, r0 += 3)
1808
if ((*r0 & 63) > dither[x & 7])
1809
*ptr ^= (bitmask & OnPixels[*r0]);
1811
*ptr ^= (bitmask & OffPixels[*r0]);
1825
bitmask = 0xf0 >> (bitoffset & 7);
1826
dither = Floyd4x4[y & 3];
1829
for (x = xsize; x > 0; x --, r0 += 3)
1831
if ((*r0 & 15) > dither[x & 3])
1832
*ptr ^= (bitmask & OnPixels[*r0]);
1834
*ptr ^= (bitmask & OffPixels[*r0]);
1836
if (bitmask == 0xf0)
1851
for (x = xsize; x > 0; x --, r0 += 3, r1 += 3)
1856
*ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize;
1866
* 'format_CMYK()' - Convert image data to CMYK.
1870
format_CMYK(cups_page_header2_t *header,/* I - Page header */
1871
unsigned char *row, /* IO - Bitmap data for device */
1872
int y, /* I - Current row */
1873
int z, /* I - Current plane */
1874
int xsize, /* I - Width of image data */
1875
int ysize, /* I - Height of image data */
1876
int yerr0, /* I - Top Y error */
1877
int yerr1, /* I - Bottom Y error */
1878
cups_ib_t *r0, /* I - Primary image data */
1879
cups_ib_t *r1) /* I - Image data for interpolation */
1881
cups_ib_t *ptr, /* Pointer into row */
1882
*cptr, /* Pointer into cyan */
1883
*mptr, /* Pointer into magenta */
1884
*yptr, /* Pointer into yellow */
1885
*kptr, /* Pointer into black */
1886
bitmask; /* Current mask for pixel */
1887
int bitoffset; /* Current offset in line */
1888
int bandwidth; /* Width of a color band */
1889
int x, /* Current X coordinate on page */
1890
*dither; /* Pointer into dither array */
1891
int pc, pm, py; /* CMY pixels */
1900
bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2);
1903
bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize);
1907
ptr = row + bitoffset / 8;
1908
bandwidth = header->cupsBytesPerLine / 4;
1910
switch (header->cupsColorOrder)
1912
case CUPS_ORDER_CHUNKED :
1913
switch (header->cupsBitsPerColor)
1916
bitmask = 128 >> (bitoffset & 7);
1917
dither = Floyd16x16[y & 15];
1919
for (x = xsize ; x > 0; x --)
1921
pc = *r0++ > dither[x & 15];
1922
pm = *r0++ > dither[x & 15];
1923
py = *r0++ > dither[x & 15];
1956
dither = Floyd8x8[y & 7];
1958
for (x = xsize ; x > 0; x --, r0 += 4)
1960
if ((r0[0] & 63) > dither[x & 7])
1961
*ptr ^= (0xc0 & OnPixels[r0[0]]);
1963
*ptr ^= (0xc0 & OffPixels[r0[0]]);
1965
if ((r0[1] & 63) > dither[x & 7])
1966
*ptr ^= (0x30 & OnPixels[r0[1]]);
1968
*ptr ^= (0x30 & OffPixels[r0[1]]);
1970
if ((r0[2] & 63) > dither[x & 7])
1971
*ptr ^= (0x0c & OnPixels[r0[2]]);
1973
*ptr ^= (0x0c & OffPixels[r0[2]]);
1975
if ((r0[3] & 63) > dither[x & 7])
1976
*ptr++ ^= (0x03 & OnPixels[r0[3]]);
1978
*ptr++ ^= (0x03 & OffPixels[r0[3]]);
1983
dither = Floyd4x4[y & 3];
1985
for (x = xsize ; x > 0; x --, r0 += 4)
1987
if ((r0[0] & 15) > dither[x & 3])
1988
*ptr ^= (0xf0 & OnPixels[r0[0]]);
1990
*ptr ^= (0xf0 & OffPixels[r0[0]]);
1992
if ((r0[1] & 15) > dither[x & 3])
1993
*ptr++ ^= (0x0f & OnPixels[r0[1]]);
1995
*ptr++ ^= (0x0f & OffPixels[r0[1]]);
1997
if ((r0[2] & 15) > dither[x & 3])
1998
*ptr ^= (0xf0 & OnPixels[r0[2]]);
2000
*ptr ^= (0xf0 & OffPixels[r0[2]]);
2002
if ((r0[3] & 15) > dither[x & 3])
2003
*ptr++ ^= (0x0f & OnPixels[r0[3]]);
2005
*ptr++ ^= (0x0f & OffPixels[r0[3]]);
2010
for (x = xsize * 4; x > 0; x --, r0 ++, r1 ++)
2014
*ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize;
2019
case CUPS_ORDER_BANDED :
2021
mptr = ptr + bandwidth;
2022
yptr = ptr + 2 * bandwidth;
2023
kptr = ptr + 3 * bandwidth;
2025
switch (header->cupsBitsPerColor)
2028
bitmask = 0x80 >> (bitoffset & 7);
2029
dither = Floyd16x16[y & 15];
2031
for (x = xsize; x > 0; x --)
2033
pc = *r0++ > dither[x & 15];
2034
pm = *r0++ > dither[x & 15];
2035
py = *r0++ > dither[x & 15];
2063
bitmask = 0xc0 >> (bitoffset & 7);
2064
dither = Floyd8x8[y & 7];
2066
for (x = xsize; x > 0; x --)
2068
if ((*r0 & 63) > dither[x & 7])
2069
*cptr ^= (bitmask & OnPixels[*r0++]);
2071
*cptr ^= (bitmask & OffPixels[*r0++]);
2073
if ((*r0 & 63) > dither[x & 7])
2074
*mptr ^= (bitmask & OnPixels[*r0++]);
2076
*mptr ^= (bitmask & OffPixels[*r0++]);
2078
if ((*r0 & 63) > dither[x & 7])
2079
*yptr ^= (bitmask & OnPixels[*r0++]);
2081
*yptr ^= (bitmask & OffPixels[*r0++]);
2083
if ((*r0 & 63) > dither[x & 7])
2084
*kptr ^= (bitmask & OnPixels[*r0++]);
2086
*kptr ^= (bitmask & OffPixels[*r0++]);
2103
bitmask = 0xf0 >> (bitoffset & 7);
2104
dither = Floyd4x4[y & 3];
2106
for (x = xsize; x > 0; x --)
2108
if ((*r0 & 15) > dither[x & 3])
2109
*cptr ^= (bitmask & OnPixels[*r0++]);
2111
*cptr ^= (bitmask & OffPixels[*r0++]);
2113
if ((*r0 & 15) > dither[x & 3])
2114
*mptr ^= (bitmask & OnPixels[*r0++]);
2116
*mptr ^= (bitmask & OffPixels[*r0++]);
2118
if ((*r0 & 15) > dither[x & 3])
2119
*yptr ^= (bitmask & OnPixels[*r0++]);
2121
*yptr ^= (bitmask & OffPixels[*r0++]);
2123
if ((*r0 & 15) > dither[x & 3])
2124
*kptr ^= (bitmask & OnPixels[*r0++]);
2126
*kptr ^= (bitmask & OffPixels[*r0++]);
2128
if (bitmask == 0xf0)
2143
for (x = xsize; x > 0; x --, r0 += 4, r1 += 4)
2148
*cptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize;
2153
*mptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize;
2158
*yptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize;
2163
*kptr++ = (r0[3] * yerr0 + r1[3] * yerr1) / ysize;
2169
case CUPS_ORDER_PLANAR :
2170
switch (header->cupsBitsPerColor)
2173
bitmask = 0x80 >> (bitoffset & 7);
2174
dither = Floyd16x16[y & 15];
2176
for (x = xsize; x > 0; x --)
2178
pc = *r0++ > dither[x & 15];
2179
pm = *r0++ > dither[x & 15];
2180
py = *r0++ > dither[x & 15];
2182
if ((pc && pm && py && z == 3) ||
2183
(pc && z == 0) || (pm && z == 1) || (py && z == 2))
2197
bitmask = 0xc0 >> (bitoffset & 7);
2198
dither = Floyd8x8[y & 7];
2201
for (x = xsize; x > 0; x --, r0 += 4)
2203
if ((*r0 & 63) > dither[x & 7])
2204
*ptr ^= (bitmask & OnPixels[*r0]);
2206
*ptr ^= (bitmask & OffPixels[*r0]);
2220
bitmask = 0xf0 >> (bitoffset & 7);
2221
dither = Floyd4x4[y & 3];
2224
for (x = xsize; x > 0; x --, r0 += 4)
2226
if ((*r0 & 15) > dither[x & 3])
2227
*ptr ^= (bitmask & OnPixels[*r0]);
2229
*ptr ^= (bitmask & OffPixels[*r0]);
2231
if (bitmask == 0xf0)
2246
for (x = xsize; x > 0; x --, r0 += 4, r1 += 4)
2251
*ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize;
2261
* 'format_K()' - Convert image data to black.
2265
format_K(cups_page_header2_t *header, /* I - Page header */
2266
unsigned char *row, /* IO - Bitmap data for device */
2267
int y, /* I - Current row */
2268
int z, /* I - Current plane */
2269
int xsize, /* I - Width of image data */
2270
int ysize, /* I - Height of image data */
2271
int yerr0, /* I - Top Y error */
2272
int yerr1, /* I - Bottom Y error */
2273
cups_ib_t *r0, /* I - Primary image data */
2274
cups_ib_t *r1) /* I - Image data for interpolation */
2276
cups_ib_t *ptr, /* Pointer into row */
2277
bitmask; /* Current mask for pixel */
2278
int bitoffset; /* Current offset in line */
2279
int x, /* Current X coordinate on page */
2280
*dither; /* Pointer into dither array */
2291
bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2);
2294
bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize);
2298
ptr = row + bitoffset / 8;
2300
switch (header->cupsBitsPerColor)
2303
bitmask = 0x80 >> (bitoffset & 7);
2304
dither = Floyd16x16[y & 15];
2306
for (x = xsize; x > 0; x --)
2308
if (*r0++ > dither[x & 15])
2322
bitmask = 0xc0 >> (bitoffset & 7);
2323
dither = Floyd8x8[y & 7];
2325
for (x = xsize; x > 0; x --)
2327
if ((*r0 & 63) > dither[x & 7])
2328
*ptr ^= (bitmask & OnPixels[*r0++]);
2330
*ptr ^= (bitmask & OffPixels[*r0++]);
2344
bitmask = 0xf0 >> (bitoffset & 7);
2345
dither = Floyd4x4[y & 3];
2347
for (x = xsize; x > 0; x --)
2349
if ((*r0 & 15) > dither[x & 3])
2350
*ptr ^= (bitmask & OnPixels[*r0++]);
2352
*ptr ^= (bitmask & OffPixels[*r0++]);
2354
if (bitmask == 0xf0)
2366
for (x = xsize; x > 0; x --, r0 ++, r1 ++)
2371
*ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize;
2379
* 'format_KCMY()' - Convert image data to KCMY.
2383
format_KCMY(cups_page_header2_t *header,/* I - Page header */
2384
unsigned char *row, /* IO - Bitmap data for device */
2385
int y, /* I - Current row */
2386
int z, /* I - Current plane */
2387
int xsize, /* I - Width of image data */
2388
int ysize, /* I - Height of image data */
2389
int yerr0, /* I - Top Y error */
2390
int yerr1, /* I - Bottom Y error */
2391
cups_ib_t *r0, /* I - Primary image data */
2392
cups_ib_t *r1) /* I - Image data for interpolation */
2394
cups_ib_t *ptr, /* Pointer into row */
2395
*cptr, /* Pointer into cyan */
2396
*mptr, /* Pointer into magenta */
2397
*yptr, /* Pointer into yellow */
2398
*kptr, /* Pointer into black */
2399
bitmask; /* Current mask for pixel */
2400
int bitoffset; /* Current offset in line */
2401
int bandwidth; /* Width of a color band */
2402
int x, /* Current X coordinate on page */
2403
*dither; /* Pointer into dither array */
2404
int pc, pm, py; /* CMY pixels */
2413
bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2);
2416
bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize);
2420
ptr = row + bitoffset / 8;
2421
bandwidth = header->cupsBytesPerLine / 4;
2423
switch (header->cupsColorOrder)
2425
case CUPS_ORDER_CHUNKED :
2426
switch (header->cupsBitsPerColor)
2429
bitmask = 128 >> (bitoffset & 7);
2430
dither = Floyd16x16[y & 15];
2432
for (x = xsize ; x > 0; x --)
2434
pc = *r0++ > dither[x & 15];
2435
pm = *r0++ > dither[x & 15];
2436
py = *r0++ > dither[x & 15];
2469
dither = Floyd8x8[y & 7];
2471
for (x = xsize ; x > 0; x --, r0 += 4)
2473
if ((r0[3] & 63) > dither[x & 7])
2474
*ptr ^= (0xc0 & OnPixels[r0[3]]);
2476
*ptr ^= (0xc0 & OffPixels[r0[3]]);
2478
if ((r0[0] & 63) > dither[x & 7])
2479
*ptr ^= (0x30 & OnPixels[r0[0]]);
2481
*ptr ^= (0x30 & OffPixels[r0[0]]);
2483
if ((r0[1] & 63) > dither[x & 7])
2484
*ptr ^= (0x0c & OnPixels[r0[1]]);
2486
*ptr ^= (0x0c & OffPixels[r0[1]]);
2488
if ((r0[2] & 63) > dither[x & 7])
2489
*ptr++ ^= (0x03 & OnPixels[r0[2]]);
2491
*ptr++ ^= (0x03 & OffPixels[r0[2]]);
2496
dither = Floyd4x4[y & 3];
2498
for (x = xsize ; x > 0; x --, r0 += 4)
2500
if ((r0[3] & 15) > dither[x & 3])
2501
*ptr ^= (0xf0 & OnPixels[r0[3]]);
2503
*ptr ^= (0xf0 & OffPixels[r0[3]]);
2505
if ((r0[0] & 15) > dither[x & 3])
2506
*ptr++ ^= (0x0f & OnPixels[r0[0]]);
2508
*ptr++ ^= (0x0f & OffPixels[r0[0]]);
2510
if ((r0[1] & 15) > dither[x & 3])
2511
*ptr ^= (0xf0 & OnPixels[r0[1]]);
2513
*ptr ^= (0xf0 & OffPixels[r0[1]]);
2515
if ((r0[2] & 15) > dither[x & 3])
2516
*ptr++ ^= (0x0f & OnPixels[r0[2]]);
2518
*ptr++ ^= (0x0f & OffPixels[r0[2]]);
2523
for (x = xsize; x > 0; x --, r0 += 4, r1 += 4)
2528
*ptr++ = (r0[3] * yerr0 + r1[3] * yerr1) / ysize;
2533
*ptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize;
2538
*ptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize;
2543
*ptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize;
2549
case CUPS_ORDER_BANDED :
2551
cptr = ptr + bandwidth;
2552
mptr = ptr + 2 * bandwidth;
2553
yptr = ptr + 3 * bandwidth;
2555
switch (header->cupsBitsPerColor)
2558
bitmask = 0x80 >> (bitoffset & 7);
2559
dither = Floyd16x16[y & 15];
2561
for (x = xsize; x > 0; x --)
2563
pc = *r0++ > dither[x & 15];
2564
pm = *r0++ > dither[x & 15];
2565
py = *r0++ > dither[x & 15];
2593
bitmask = 0xc0 >> (bitoffset & 7);
2594
dither = Floyd8x8[y & 7];
2596
for (x = xsize; x > 0; x --)
2598
if ((*r0 & 63) > dither[x & 7])
2599
*cptr ^= (bitmask & OnPixels[*r0++]);
2601
*cptr ^= (bitmask & OffPixels[*r0++]);
2603
if ((*r0 & 63) > dither[x & 7])
2604
*mptr ^= (bitmask & OnPixels[*r0++]);
2606
*mptr ^= (bitmask & OffPixels[*r0++]);
2608
if ((*r0 & 63) > dither[x & 7])
2609
*yptr ^= (bitmask & OnPixels[*r0++]);
2611
*yptr ^= (bitmask & OffPixels[*r0++]);
2613
if ((*r0 & 63) > dither[x & 7])
2614
*kptr ^= (bitmask & OnPixels[*r0++]);
2616
*kptr ^= (bitmask & OffPixels[*r0++]);
2633
bitmask = 0xf0 >> (bitoffset & 7);
2634
dither = Floyd4x4[y & 3];
2636
for (x = xsize; x > 0; x --)
2638
if ((*r0 & 15) > dither[x & 3])
2639
*cptr ^= (bitmask & OnPixels[*r0++]);
2641
*cptr ^= (bitmask & OffPixels[*r0++]);
2643
if ((*r0 & 15) > dither[x & 3])
2644
*mptr ^= (bitmask & OnPixels[*r0++]);
2646
*mptr ^= (bitmask & OffPixels[*r0++]);
2648
if ((*r0 & 15) > dither[x & 3])
2649
*yptr ^= (bitmask & OnPixels[*r0++]);
2651
*yptr ^= (bitmask & OffPixels[*r0++]);
2653
if ((*r0 & 15) > dither[x & 3])
2654
*kptr ^= (bitmask & OnPixels[*r0++]);
2656
*kptr ^= (bitmask & OffPixels[*r0++]);
2658
if (bitmask == 0xf0)
2673
for (x = xsize; x > 0; x --, r0 += 4, r1 += 4)
2678
*cptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize;
2683
*mptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize;
2688
*yptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize;
2693
*kptr++ = (r0[3] * yerr0 + r1[3] * yerr1) / ysize;
2699
case CUPS_ORDER_PLANAR :
2700
switch (header->cupsBitsPerColor)
2703
bitmask = 0x80 >> (bitoffset & 7);
2704
dither = Floyd16x16[y & 15];
2706
for (x = xsize; x > 0; x --)
2708
pc = *r0++ > dither[x & 15];
2709
pm = *r0++ > dither[x & 15];
2710
py = *r0++ > dither[x & 15];
2712
if ((pc && pm && py && z == 0) ||
2713
(pc && z == 1) || (pm && z == 2) || (py && z == 3))
2727
bitmask = 0xc0 >> (bitoffset & 7);
2728
dither = Floyd8x8[y & 7];
2734
for (x = xsize; x > 0; x --, r0 += 4)
2736
if ((*r0 & 63) > dither[x & 7])
2737
*ptr ^= (bitmask & OnPixels[*r0]);
2739
*ptr ^= (bitmask & OffPixels[*r0]);
2753
bitmask = 0xf0 >> (bitoffset & 7);
2754
dither = Floyd4x4[y & 3];
2760
for (x = xsize; x > 0; x --, r0 += 4)
2762
if ((*r0 & 15) > dither[x & 3])
2763
*ptr ^= (bitmask & OnPixels[*r0]);
2765
*ptr ^= (bitmask & OffPixels[*r0]);
2767
if (bitmask == 0xf0)
2790
for (x = xsize; x > 0; x --, r0 += 4, r1 += 4)
2795
*ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize;
2805
* 'format_KCMYcm()' - Convert image data to KCMYcm.
2810
cups_page_header2_t *header, /* I - Page header */
2811
unsigned char *row, /* IO - Bitmap data for device */
2812
int y, /* I - Current row */
2813
int z, /* I - Current plane */
2814
int xsize, /* I - Width of image data */
2815
int ysize, /* I - Height of image data */
2816
int yerr0, /* I - Top Y error */
2817
int yerr1, /* I - Bottom Y error */
2818
cups_ib_t *r0, /* I - Primary image data */
2819
cups_ib_t *r1) /* I - Image data for interpolation */
2821
int pc, pm, py, pk; /* Cyan, magenta, yellow, and black values */
2822
cups_ib_t *ptr, /* Pointer into row */
2823
*cptr, /* Pointer into cyan */
2824
*mptr, /* Pointer into magenta */
2825
*yptr, /* Pointer into yellow */
2826
*kptr, /* Pointer into black */
2827
*lcptr, /* Pointer into light cyan */
2828
*lmptr, /* Pointer into light magenta */
2829
bitmask; /* Current mask for pixel */
2830
int bitoffset; /* Current offset in line */
2831
int bandwidth; /* Width of a color band */
2832
int x, /* Current X coordinate on page */
2833
*dither; /* Pointer into dither array */
2842
bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2);
2845
bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize);
2849
ptr = row + bitoffset / 8;
2850
bandwidth = header->cupsBytesPerLine / 6;
2852
switch (header->cupsColorOrder)
2854
case CUPS_ORDER_CHUNKED :
2855
dither = Floyd16x16[y & 15];
2857
for (x = xsize ; x > 0; x --)
2859
pc = *r0++ > dither[x & 15];
2860
pm = *r0++ > dither[x & 15];
2861
py = *r0++ > dither[x & 15];
2862
pk = pc && pm && py;
2865
*ptr++ ^= 32; /* Black */
2867
*ptr++ ^= 17; /* Blue (cyan + light magenta) */
2869
*ptr++ ^= 6; /* Green (light cyan + yellow) */
2871
*ptr++ ^= 12; /* Red (magenta + yellow) */
2883
case CUPS_ORDER_BANDED :
2885
cptr = ptr + bandwidth;
2886
mptr = ptr + 2 * bandwidth;
2887
yptr = ptr + 3 * bandwidth;
2888
lcptr = ptr + 4 * bandwidth;
2889
lmptr = ptr + 5 * bandwidth;
2891
bitmask = 0x80 >> (bitoffset & 7);
2892
dither = Floyd16x16[y & 15];
2894
for (x = xsize; x > 0; x --)
2896
pc = *r0++ > dither[x & 15];
2897
pm = *r0++ > dither[x & 15];
2898
py = *r0++ > dither[x & 15];
2899
pk = pc && pm && py;
2902
*kptr ^= bitmask; /* Black */
2905
*cptr ^= bitmask; /* Blue (cyan + light magenta) */
2910
*lcptr ^= bitmask; /* Green (light cyan + yellow) */
2915
*mptr ^= bitmask; /* Red (magenta + yellow) */
2940
case CUPS_ORDER_PLANAR :
2941
bitmask = 0x80 >> (bitoffset & 7);
2942
dither = Floyd16x16[y & 15];
2944
for (x = xsize; x > 0; x --)
2946
pc = *r0++ > dither[x & 15];
2947
pm = *r0++ > dither[x & 15];
2948
py = *r0++ > dither[x & 15];
2949
pk = pc && pm && py;
2953
else if (pc && pm && (z == 1 || z == 5))
2954
*ptr ^= bitmask; /* Blue (cyan + light magenta) */
2955
else if (pc && py && (z == 3 || z == 4))
2956
*ptr ^= bitmask; /* Green (light cyan + yellow) */
2957
else if (pm && py && (z == 2 || z == 3))
2958
*ptr ^= bitmask; /* Red (magenta + yellow) */
2959
else if (pc && z == 1)
2961
else if (pm && z == 2)
2963
else if (py && z == 3)
2980
* 'format_RGBA()' - Convert image data to RGBA/RGBW.
2984
format_RGBA(cups_page_header2_t *header,/* I - Page header */
2985
unsigned char *row, /* IO - Bitmap data for device */
2986
int y, /* I - Current row */
2987
int z, /* I - Current plane */
2988
int xsize, /* I - Width of image data */
2989
int ysize, /* I - Height of image data */
2990
int yerr0, /* I - Top Y error */
2991
int yerr1, /* I - Bottom Y error */
2992
cups_ib_t *r0, /* I - Primary image data */
2993
cups_ib_t *r1) /* I - Image data for interpolation */
2995
cups_ib_t *ptr, /* Pointer into row */
2996
*cptr, /* Pointer into cyan */
2997
*mptr, /* Pointer into magenta */
2998
*yptr, /* Pointer into yellow */
2999
bitmask; /* Current mask for pixel */
3000
int bitoffset; /* Current offset in line */
3001
int bandwidth; /* Width of a color band */
3002
int x, /* Current X coordinate on page */
3003
*dither; /* Pointer into dither array */
3012
bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2);
3015
bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize);
3019
ptr = row + bitoffset / 8;
3020
bandwidth = header->cupsBytesPerLine / 4;
3022
switch (header->cupsColorOrder)
3024
case CUPS_ORDER_CHUNKED :
3025
switch (header->cupsBitsPerColor)
3028
bitmask = 128 >> (bitoffset & 7);
3029
dither = Floyd16x16[y & 15];
3031
for (x = xsize ; x > 0; x --)
3033
if (*r0++ > dither[x & 15])
3037
if (*r0++ > dither[x & 15])
3041
if (*r0++ > dither[x & 15])
3055
dither = Floyd8x8[y & 7];
3057
for (x = xsize ; x > 0; x --, r0 += 3)
3059
if ((r0[0] & 63) > dither[x & 7])
3060
*ptr ^= (0xc0 & OnPixels[r0[0]]);
3062
*ptr ^= (0xc0 & OffPixels[r0[0]]);
3064
if ((r0[1] & 63) > dither[x & 7])
3065
*ptr ^= (0x30 & OnPixels[r0[1]]);
3067
*ptr ^= (0x30 & OffPixels[r0[1]]);
3069
if ((r0[2] & 63) > dither[x & 7])
3070
*ptr ^= (0x0c & OnPixels[r0[2]]);
3072
*ptr ^= (0x0c & OffPixels[r0[2]]);
3079
dither = Floyd4x4[y & 3];
3081
for (x = xsize ; x > 0; x --, r0 += 3)
3083
if ((r0[0] & 15) > dither[x & 3])
3084
*ptr ^= (0xf0 & OnPixels[r0[0]]);
3086
*ptr ^= (0xf0 & OffPixels[r0[0]]);
3088
if ((r0[1] & 15) > dither[x & 3])
3089
*ptr++ ^= (0x0f & OnPixels[r0[1]]);
3091
*ptr++ ^= (0x0f & OffPixels[r0[1]]);
3093
if ((r0[2] & 15) > dither[x & 3])
3094
*ptr ^= (0xf0 & OnPixels[r0[2]]);
3096
*ptr ^= (0xf0 & OffPixels[r0[2]]);
3103
for (x = xsize; x > 0; x --, r0 += 3, r1 += 3)
3108
*ptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize;
3113
*ptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize;
3118
*ptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize;
3126
case CUPS_ORDER_BANDED :
3128
mptr = ptr + bandwidth;
3129
yptr = ptr + 2 * bandwidth;
3131
memset(ptr + 3 * bandwidth, 255, bandwidth);
3133
switch (header->cupsBitsPerColor)
3136
bitmask = 0x80 >> (bitoffset & 7);
3137
dither = Floyd16x16[y & 15];
3139
for (x = xsize; x > 0; x --)
3141
if (*r0++ > dither[x & 15])
3143
if (*r0++ > dither[x & 15])
3145
if (*r0++ > dither[x & 15])
3161
bitmask = 0xc0 >> (bitoffset & 7);
3162
dither = Floyd8x8[y & 7];
3164
for (x = xsize; x > 0; x --)
3166
if ((*r0 & 63) > dither[x & 7])
3167
*cptr ^= (bitmask & OnPixels[*r0++]);
3169
*cptr ^= (bitmask & OffPixels[*r0++]);
3171
if ((*r0 & 63) > dither[x & 7])
3172
*mptr ^= (bitmask & OnPixels[*r0++]);
3174
*mptr ^= (bitmask & OffPixels[*r0++]);
3176
if ((*r0 & 63) > dither[x & 7])
3177
*yptr ^= (bitmask & OnPixels[*r0++]);
3179
*yptr ^= (bitmask & OffPixels[*r0++]);
3195
bitmask = 0xf0 >> (bitoffset & 7);
3196
dither = Floyd4x4[y & 3];
3198
for (x = xsize; x > 0; x --)
3200
if ((*r0 & 15) > dither[x & 3])
3201
*cptr ^= (bitmask & OnPixels[*r0++]);
3203
*cptr ^= (bitmask & OffPixels[*r0++]);
3205
if ((*r0 & 15) > dither[x & 3])
3206
*mptr ^= (bitmask & OnPixels[*r0++]);
3208
*mptr ^= (bitmask & OffPixels[*r0++]);
3210
if ((*r0 & 15) > dither[x & 3])
3211
*yptr ^= (bitmask & OnPixels[*r0++]);
3213
*yptr ^= (bitmask & OffPixels[*r0++]);
3215
if (bitmask == 0xf0)
3229
for (x = xsize; x > 0; x --, r0 += 3, r1 += 3)
3234
*cptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize;
3239
*mptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize;
3244
*yptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize;
3250
case CUPS_ORDER_PLANAR :
3253
memset(row, 255, header->cupsBytesPerLine);
3257
switch (header->cupsBitsPerColor)
3260
bitmask = 0x80 >> (bitoffset & 7);
3261
dither = Floyd16x16[y & 15];
3266
for (x = xsize; x > 0; x --, r0 += 3)
3268
if (r0[0] > dither[x & 15])
3282
for (x = xsize; x > 0; x --, r0 += 3)
3284
if (r0[1] > dither[x & 15])
3298
for (x = xsize; x > 0; x --, r0 += 3)
3300
if (r0[2] > dither[x & 15])
3316
bitmask = 0xc0 >> (bitoffset & 7);
3317
dither = Floyd8x8[y & 7];
3320
for (x = xsize; x > 0; x --, r0 += 3)
3322
if ((*r0 & 63) > dither[x & 7])
3323
*ptr ^= (bitmask & OnPixels[*r0]);
3325
*ptr ^= (bitmask & OffPixels[*r0]);
3339
bitmask = 0xf0 >> (bitoffset & 7);
3340
dither = Floyd4x4[y & 3];
3343
for (x = xsize; x > 0; x --, r0 += 3)
3345
if ((*r0 & 15) > dither[x & 3])
3346
*ptr ^= (bitmask & OnPixels[*r0]);
3348
*ptr ^= (bitmask & OffPixels[*r0]);
3350
if (bitmask == 0xf0)
3365
for (x = xsize; x > 0; x --, r0 += 3, r1 += 3)
3370
*ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize;
3380
* 'format_W()' - Convert image data to luminance.
3384
format_W(cups_page_header2_t *header, /* I - Page header */
3385
unsigned char *row, /* IO - Bitmap data for device */
3386
int y, /* I - Current row */
3387
int z, /* I - Current plane */
3388
int xsize, /* I - Width of image data */
3389
int ysize, /* I - Height of image data */
3390
int yerr0, /* I - Top Y error */
3391
int yerr1, /* I - Bottom Y error */
3392
cups_ib_t *r0, /* I - Primary image data */
3393
cups_ib_t *r1) /* I - Image data for interpolation */
3395
cups_ib_t *ptr, /* Pointer into row */
3396
bitmask; /* Current mask for pixel */
3397
int bitoffset; /* Current offset in line */
3398
int x, /* Current X coordinate on page */
3399
*dither; /* Pointer into dither array */
3410
bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2);
3413
bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize);
3417
ptr = row + bitoffset / 8;
3419
switch (header->cupsBitsPerColor)
3422
bitmask = 0x80 >> (bitoffset & 7);
3423
dither = Floyd16x16[y & 15];
3425
for (x = xsize; x > 0; x --)
3427
if (*r0++ > dither[x & 15])
3441
bitmask = 0xc0 >> (bitoffset & 7);
3442
dither = Floyd8x8[y & 7];
3444
for (x = xsize; x > 0; x --)
3446
if ((*r0 & 63) > dither[x & 7])
3447
*ptr ^= (bitmask & OnPixels[*r0++]);
3449
*ptr ^= (bitmask & OffPixels[*r0++]);
3463
bitmask = 0xf0 >> (bitoffset & 7);
3464
dither = Floyd4x4[y & 3];
3466
for (x = xsize; x > 0; x --)
3468
if ((*r0 & 15) > dither[x & 3])
3469
*ptr ^= (bitmask & OnPixels[*r0++]);
3471
*ptr ^= (bitmask & OffPixels[*r0++]);
3473
if (bitmask == 0xf0)
3485
for (x = xsize; x > 0; x --, r0 ++, r1 ++)
3490
*ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize;
3498
* 'format_YMC()' - Convert image data to YMC.
3502
format_YMC(cups_page_header2_t *header, /* I - Page header */
3503
unsigned char *row, /* IO - Bitmap data for device */
3504
int y, /* I - Current row */
3505
int z, /* I - Current plane */
3506
int xsize, /* I - Width of image data */
3507
int ysize, /* I - Height of image data */
3508
int yerr0, /* I - Top Y error */
3509
int yerr1, /* I - Bottom Y error */
3510
cups_ib_t *r0, /* I - Primary image data */
3511
cups_ib_t *r1) /* I - Image data for interpolation */
3513
cups_ib_t *ptr, /* Pointer into row */
3514
*cptr, /* Pointer into cyan */
3515
*mptr, /* Pointer into magenta */
3516
*yptr, /* Pointer into yellow */
3517
bitmask; /* Current mask for pixel */
3518
int bitoffset; /* Current offset in line */
3519
int bandwidth; /* Width of a color band */
3520
int x, /* Current X coordinate on page */
3521
*dither; /* Pointer into dither array */
3530
bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2);
3533
bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize);
3537
ptr = row + bitoffset / 8;
3538
bandwidth = header->cupsBytesPerLine / 3;
3540
switch (header->cupsColorOrder)
3542
case CUPS_ORDER_CHUNKED :
3543
switch (header->cupsBitsPerColor)
3546
bitmask = 64 >> (bitoffset & 7);
3547
dither = Floyd16x16[y & 15];
3549
for (x = xsize ; x > 0; x --, r0 += 3)
3551
if (r0[2] > dither[x & 15])
3555
if (r0[1] > dither[x & 15])
3559
if (r0[0] > dither[x & 15])
3573
dither = Floyd8x8[y & 7];
3575
for (x = xsize ; x > 0; x --, r0 += 3)
3577
if ((r0[2] & 63) > dither[x & 7])
3578
*ptr ^= (0x30 & OnPixels[r0[2]]);
3580
*ptr ^= (0x30 & OffPixels[r0[2]]);
3582
if ((r0[1] & 63) > dither[x & 7])
3583
*ptr ^= (0x0c & OnPixels[r0[1]]);
3585
*ptr ^= (0x0c & OffPixels[r0[1]]);
3587
if ((r0[0] & 63) > dither[x & 7])
3588
*ptr++ ^= (0x03 & OnPixels[r0[0]]);
3590
*ptr++ ^= (0x03 & OffPixels[r0[0]]);
3595
dither = Floyd4x4[y & 3];
3597
for (x = xsize ; x > 0; x --, r0 += 3)
3599
if ((r0[2] & 15) > dither[x & 3])
3600
*ptr++ ^= (0x0f & OnPixels[r0[2]]);
3602
*ptr++ ^= (0x0f & OffPixels[r0[2]]);
3604
if ((r0[1] & 15) > dither[x & 3])
3605
*ptr ^= (0xf0 & OnPixels[r0[1]]);
3607
*ptr ^= (0xf0 & OffPixels[r0[1]]);
3609
if ((r0[0] & 15) > dither[x & 3])
3610
*ptr++ ^= (0x0f & OnPixels[r0[0]]);
3612
*ptr++ ^= (0x0f & OffPixels[r0[0]]);
3617
for (x = xsize; x > 0; x --, r0 += 3, r1 += 3)
3622
*ptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize;
3627
*ptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize;
3632
*ptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize;
3638
case CUPS_ORDER_BANDED :
3640
mptr = ptr + bandwidth;
3641
cptr = ptr + 2 * bandwidth;
3643
switch (header->cupsBitsPerColor)
3646
bitmask = 0x80 >> (bitoffset & 7);
3647
dither = Floyd16x16[y & 15];
3649
for (x = xsize; x > 0; x --)
3651
if (*r0++ > dither[x & 15])
3653
if (*r0++ > dither[x & 15])
3655
if (*r0++ > dither[x & 15])
3671
bitmask = 0xc0 >> (bitoffset & 7);
3672
dither = Floyd8x8[y & 7];
3674
for (x = xsize; x > 0; x --)
3676
if ((*r0 & 63) > dither[x & 7])
3677
*cptr ^= (bitmask & OnPixels[*r0++]);
3679
*cptr ^= (bitmask & OffPixels[*r0++]);
3681
if ((*r0 & 63) > dither[x & 7])
3682
*mptr ^= (bitmask & OnPixels[*r0++]);
3684
*mptr ^= (bitmask & OffPixels[*r0++]);
3686
if ((*r0 & 63) > dither[x & 7])
3687
*yptr ^= (bitmask & OnPixels[*r0++]);
3689
*yptr ^= (bitmask & OffPixels[*r0++]);
3705
bitmask = 0xf0 >> (bitoffset & 7);
3706
dither = Floyd4x4[y & 3];
3708
for (x = xsize; x > 0; x --)
3710
if ((*r0 & 15) > dither[x & 3])
3711
*cptr ^= (bitmask & OnPixels[*r0++]);
3713
*cptr ^= (bitmask & OffPixels[*r0++]);
3715
if ((*r0 & 15) > dither[x & 3])
3716
*mptr ^= (bitmask & OnPixels[*r0++]);
3718
*mptr ^= (bitmask & OffPixels[*r0++]);
3720
if ((*r0 & 15) > dither[x & 3])
3721
*yptr ^= (bitmask & OnPixels[*r0++]);
3723
*yptr ^= (bitmask & OffPixels[*r0++]);
3725
if (bitmask == 0xf0)
3739
for (x = xsize; x > 0; x --, r0 += 3, r1 += 3)
3744
*cptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize;
3749
*mptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize;
3754
*yptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize;
3760
case CUPS_ORDER_PLANAR :
3761
switch (header->cupsBitsPerColor)
3764
bitmask = 0x80 >> (bitoffset & 7);
3765
dither = Floyd16x16[y & 15];
3770
for (x = xsize; x > 0; x --, r0 += 3)
3772
if (r0[0] > dither[x & 15])
3786
for (x = xsize; x > 0; x --, r0 += 3)
3788
if (r0[1] > dither[x & 15])
3802
for (x = xsize; x > 0; x --, r0 += 3)
3804
if (r0[2] > dither[x & 15])
3820
bitmask = 0xc0 >> (bitoffset & 7);
3821
dither = Floyd8x8[y & 7];
3825
for (x = xsize; x > 0; x --, r0 += 3)
3827
if ((*r0 & 63) > dither[x & 7])
3828
*ptr ^= (bitmask & OnPixels[*r0]);
3830
*ptr ^= (bitmask & OffPixels[*r0]);
3844
bitmask = 0xf0 >> (bitoffset & 7);
3845
dither = Floyd4x4[y & 3];
3849
for (x = xsize; x > 0; x --, r0 += 3)
3851
if ((*r0 & 15) > dither[x & 3])
3852
*ptr ^= (bitmask & OnPixels[*r0]);
3854
*ptr ^= (bitmask & OffPixels[*r0]);
3856
if (bitmask == 0xf0)
3872
for (x = xsize; x > 0; x --, r0 += 3, r1 += 3)
3877
*ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize;
3887
* 'format_YMCK()' - Convert image data to YMCK.
3891
format_YMCK(cups_page_header2_t *header,/* I - Page header */
3892
unsigned char *row, /* IO - Bitmap data for device */
3893
int y, /* I - Current row */
3894
int z, /* I - Current plane */
3895
int xsize, /* I - Width of image data */
3896
int ysize, /* I - Height of image data */
3897
int yerr0, /* I - Top Y error */
3898
int yerr1, /* I - Bottom Y error */
3899
cups_ib_t *r0, /* I - Primary image data */
3900
cups_ib_t *r1) /* I - Image data for interpolation */
3902
cups_ib_t *ptr, /* Pointer into row */
3903
*cptr, /* Pointer into cyan */
3904
*mptr, /* Pointer into magenta */
3905
*yptr, /* Pointer into yellow */
3906
*kptr, /* Pointer into black */
3907
bitmask; /* Current mask for pixel */
3908
int bitoffset; /* Current offset in line */
3909
int bandwidth; /* Width of a color band */
3910
int x, /* Current X coordinate on page */
3911
*dither; /* Pointer into dither array */
3912
int pc, pm, py; /* CMY pixels */
3921
bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2);
3924
bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize);
3928
ptr = row + bitoffset / 8;
3929
bandwidth = header->cupsBytesPerLine / 4;
3931
switch (header->cupsColorOrder)
3933
case CUPS_ORDER_CHUNKED :
3934
switch (header->cupsBitsPerColor)
3937
bitmask = 128 >> (bitoffset & 7);
3938
dither = Floyd16x16[y & 15];
3940
for (x = xsize ; x > 0; x --)
3942
pc = *r0++ > dither[x & 15];
3943
pm = *r0++ > dither[x & 15];
3944
py = *r0++ > dither[x & 15];
3978
dither = Floyd8x8[y & 7];
3980
for (x = xsize ; x > 0; x --, r0 += 4)
3982
if ((r0[2] & 63) > dither[x & 7])
3983
*ptr ^= (0xc0 & OnPixels[r0[2]]);
3985
*ptr ^= (0xc0 & OffPixels[r0[2]]);
3987
if ((r0[1] & 63) > dither[x & 7])
3988
*ptr ^= (0x30 & OnPixels[r0[1]]);
3990
*ptr ^= (0x30 & OffPixels[r0[1]]);
3992
if ((r0[0] & 63) > dither[x & 7])
3993
*ptr ^= (0x0c & OnPixels[r0[0]]);
3995
*ptr ^= (0x0c & OffPixels[r0[0]]);
3997
if ((r0[3] & 63) > dither[x & 7])
3998
*ptr++ ^= (0x03 & OnPixels[r0[3]]);
4000
*ptr++ ^= (0x03 & OffPixels[r0[3]]);
4005
dither = Floyd4x4[y & 3];
4007
for (x = xsize ; x > 0; x --, r0 += 4)
4009
if ((r0[2] & 15) > dither[x & 3])
4010
*ptr ^= (0xf0 & OnPixels[r0[2]]);
4012
*ptr ^= (0xf0 & OffPixels[r0[2]]);
4014
if ((r0[1] & 15) > dither[x & 3])
4015
*ptr++ ^= (0x0f & OnPixels[r0[1]]);
4017
*ptr++ ^= (0x0f & OffPixels[r0[1]]);
4019
if ((r0[0] & 15) > dither[x & 3])
4020
*ptr ^= (0xf0 & OnPixels[r0[0]]);
4022
*ptr ^= (0xf0 & OffPixels[r0[0]]);
4024
if ((r0[3] & 15) > dither[x & 3])
4025
*ptr++ ^= (0x0f & OnPixels[r0[3]]);
4027
*ptr++ ^= (0x0f & OffPixels[r0[3]]);
4032
for (x = xsize; x > 0; x --, r0 += 4, r1 += 4)
4037
*ptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize;
4042
*ptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize;
4047
*ptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize;
4052
*ptr++ = (r0[3] * yerr0 + r1[3] * yerr1) / ysize;
4058
case CUPS_ORDER_BANDED :
4060
mptr = ptr + bandwidth;
4061
cptr = ptr + 2 * bandwidth;
4062
kptr = ptr + 3 * bandwidth;
4064
switch (header->cupsBitsPerColor)
4067
bitmask = 0x80 >> (bitoffset & 7);
4068
dither = Floyd16x16[y & 15];
4070
for (x = xsize; x > 0; x --)
4072
pc = *r0++ > dither[x & 15];
4073
pm = *r0++ > dither[x & 15];
4074
py = *r0++ > dither[x & 15];
4103
bitmask = 0xc0 >> (bitoffset & 7);
4104
dither = Floyd8x8[y & 7];
4106
for (x = xsize; x > 0; x --)
4108
if ((*r0 & 63) > dither[x & 7])
4109
*cptr ^= (bitmask & OnPixels[*r0++]);
4111
*cptr ^= (bitmask & OffPixels[*r0++]);
4113
if ((*r0 & 63) > dither[x & 7])
4114
*mptr ^= (bitmask & OnPixels[*r0++]);
4116
*mptr ^= (bitmask & OffPixels[*r0++]);
4118
if ((*r0 & 63) > dither[x & 7])
4119
*yptr ^= (bitmask & OnPixels[*r0++]);
4121
*yptr ^= (bitmask & OffPixels[*r0++]);
4123
if ((*r0 & 63) > dither[x & 7])
4124
*kptr ^= (bitmask & OnPixels[*r0++]);
4126
*kptr ^= (bitmask & OffPixels[*r0++]);
4143
bitmask = 0xf0 >> (bitoffset & 7);
4144
dither = Floyd4x4[y & 3];
4146
for (x = xsize; x > 0; x --)
4148
if ((*r0 & 15) > dither[x & 3])
4149
*cptr ^= (bitmask & OnPixels[*r0++]);
4151
*cptr ^= (bitmask & OffPixels[*r0++]);
4153
if ((*r0 & 15) > dither[x & 3])
4154
*mptr ^= (bitmask & OnPixels[*r0++]);
4156
*mptr ^= (bitmask & OffPixels[*r0++]);
4158
if ((*r0 & 15) > dither[x & 3])
4159
*yptr ^= (bitmask & OnPixels[*r0++]);
4161
*yptr ^= (bitmask & OffPixels[*r0++]);
4163
if ((*r0 & 15) > dither[x & 3])
4164
*kptr ^= (bitmask & OnPixels[*r0++]);
4166
*kptr ^= (bitmask & OffPixels[*r0++]);
4168
if (bitmask == 0xf0)
4183
for (x = xsize; x > 0; x --, r0 += 4, r1 += 4)
4188
*cptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize;
4193
*mptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize;
4198
*yptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize;
4203
*kptr++ = (r0[3] * yerr0 + r1[3] * yerr1) / ysize;
4209
case CUPS_ORDER_PLANAR :
4210
switch (header->cupsBitsPerColor)
4213
bitmask = 0x80 >> (bitoffset & 7);
4214
dither = Floyd16x16[y & 15];
4216
for (x = xsize; x > 0; x --)
4218
pc = *r0++ > dither[x & 15];
4219
pm = *r0++ > dither[x & 15];
4220
py = *r0++ > dither[x & 15];
4222
if ((pc && pm && py && z == 3) ||
4223
(pc && z == 2) || (pm && z == 1) || (py && z == 0))
4237
bitmask = 0xc0 >> (bitoffset & 7);
4238
dither = Floyd8x8[y & 7];
4244
for (x = xsize; x > 0; x --, r0 += 4)
4246
if ((*r0 & 63) > dither[x & 7])
4247
*ptr ^= (bitmask & OnPixels[*r0]);
4249
*ptr ^= (bitmask & OffPixels[*r0]);
4263
bitmask = 0xf0 >> (bitoffset & 7);
4264
dither = Floyd4x4[y & 3];
4270
for (x = xsize; x > 0; x --, r0 += 4)
4272
if ((*r0 & 15) > dither[x & 3])
4273
*ptr ^= (bitmask & OnPixels[*r0]);
4275
*ptr ^= (bitmask & OffPixels[*r0]);
4277
if (bitmask == 0xf0)
4300
for (x = xsize; x > 0; x --, r0 += 4, r1 += 4)
4305
*ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize;
4315
* 'make_lut()' - Make a lookup table given gamma and brightness values.
4319
make_lut(cups_ib_t *lut, /* I - Lookup table */
4320
int colorspace, /* I - Colorspace */
4321
float g, /* I - Image gamma */
4322
float b) /* I - Image brightness */
4324
int i; /* Looping var */
4325
int v; /* Current value */
4331
for (i = 0; i < 256; i ++)
4334
v = 255.0 * b * (1.0 - pow(1.0 - (float)i / 255.0, g)) + 0.5;
4336
v = 255.0 * (1.0 - b * (1.0 - pow((float)i / 255.0, g))) + 0.5;
4349
* 'raster_cb()' - Validate the page header.
4352
static int /* O - 0 if OK, -1 if not */
4354
cups_page_header2_t *header, /* IO - Raster header */
4355
int preferred_bits) /* I - Preferred bits per color */
4358
* Ensure that colorimetric colorspaces use at least 8 bits per
4362
if ((header->cupsColorSpace == CUPS_CSPACE_CIEXYZ ||
4363
header->cupsColorSpace == CUPS_CSPACE_CIELab ||
4364
header->cupsColorSpace >= CUPS_CSPACE_ICC1) &&
4365
header->cupsBitsPerColor < 8)
4366
header->cupsBitsPerColor = 8;