2 * "$Id: gdevcups.c,v 1.48 2002/01/02 17:59:09 mike Exp $"
4 * GNU Ghostscript raster output driver for the Common UNIX Printing
7 * Copyright 1993-2002 by Easy Software Products.
9 * These coded instructions, statements, and computer programs are the
10 * property of Easy Software Products and are protected by Federal
11 * copyright law. Distribution and use rights are outlined in the file
12 * "LICENSE.txt" which should have been included with this file. If this
13 * file is missing or damaged please contact Easy Software Products
16 * Attn: CUPS Licensing Information
17 * Easy Software Products
18 * 44141 Airport View Drive, Suite 204
19 * Hollywood, Maryland 20636-3111 USA
21 * Voice: (301) 373-9603
22 * EMail: cups-info@cups.org
23 * WWW: http://www.cups.org
25 * This code and any derivative of it may be used and distributed
26 * freely under the terms of the GNU General Public License when
27 * used with GNU Ghostscript or its derivatives. Use of the code
28 * (or any derivative of it) with software other than GNU
29 * GhostScript (or its derivatives) is governed by the CUPS license
34 * cups_close() - Close the output file.
35 * cups_get_matrix() - Generate the default page matrix.
36 * cups_get_params() - Get pagedevice parameters.
37 * cups_map_color_rgb() - Map a color index to an RGB color.
38 * cups_map_rgb_color() - Map an RGB color to a color index. We map the
39 * RGB color to the output colorspace & bits (we
40 * figure out the format when we output a page).
41 * cups_open() - Open the output file and initialize things.
42 * cups_print_pages() - Send one or more pages to the output file.
43 * cups_put_params() - Set pagedevice parameters.
44 * cups_set_color_info() - Set the color information structure based on
45 * the required output.
46 * cups_print_chunked() - Print a page of chunked pixels.
47 * cups_print_banded() - Print a page of banded pixels.
48 * cups_print_planar() - Print a page of planar pixels.
52 * Include necessary headers...
55 #include "std.h" /* to stop stdlib.h redefining types */
61 #include <filter/raster.h>
73 extern const char *cupsProfile
;
80 #define x_dpi (pdev->HWResolution[0])
81 #define y_dpi (pdev->HWResolution[1])
82 #define cups ((gx_device_cups *)pdev)
85 * Macros from <macros.h>; we can't include <macros.h> because it also
86 * defines DEBUG, one of our flags to insert various debugging code.
90 # define max(a,b) ((a)<(b) ? (b) : (a))
94 # define min(a,b) ((a)>(b) ? (b) : (a))
98 # define abs(x) ((x)>=0 ? (x) : -(x))
106 private dev_proc_close_device(cups_close
);
107 private dev_proc_get_initial_matrix(cups_get_matrix
);
108 private int cups_get_params(gx_device
*, gs_param_list
*);
109 private dev_proc_map_cmyk_color(cups_map_cmyk_color
);
110 private dev_proc_map_color_rgb(cups_map_color_rgb
);
111 private dev_proc_map_rgb_color(cups_map_rgb_color
);
112 private dev_proc_open_device(cups_open
);
113 private int cups_print_pages(gx_device_printer
*, FILE *, int);
114 private int cups_put_params(gx_device
*, gs_param_list
*);
115 private void cups_set_color_info(gx_device
*);
116 private dev_proc_sync_output(cups_sync_output
);
119 * The device descriptors...
122 typedef struct gx_device_cups_s
124 gx_device_common
; /* Standard GhostScript device stuff */
125 gx_prn_device_common
; /* Standard printer device stuff */
126 int page
; /* Page number */
127 cups_raster_t
*stream
; /* Raster stream */
128 ppd_file_t
*ppd
; /* PPD file for this printer */
129 cups_page_header_t header
; /* PostScript page device info */
132 private gx_device_procs cups_procs
=
137 gdev_prn_output_page
,
141 NULL
, /* fill_rectangle */
142 NULL
, /* tile_rectangle */
143 NULL
, /* copy_mono */
144 NULL
, /* copy_color */
145 NULL
, /* draw_line */
149 NULL
, /* map_cmyk_color */
150 NULL
, /* get_xfont_procs */
151 NULL
, /* get_xfont_device */
152 NULL
, /* map_rgb_alpha_color */
153 gx_page_device_get_page_device
,
154 NULL
, /* get_alpha_bits */
155 NULL
, /* copy_alpha */
158 NULL
, /* fill_path */
159 NULL
, /* stroke_path */
160 NULL
, /* fill_mask */
161 NULL
, /* fill_trapezoid */
162 NULL
, /* fill_parallelogram */
163 NULL
, /* fill_triangle */
164 NULL
, /* draw_thin_line */
165 NULL
, /* begin_image */
166 NULL
, /* image_data */
167 NULL
, /* end_image */
168 NULL
, /* strip_tile_rectangle */
169 NULL
/* strip_copy_rop */
172 gx_device_cups gs_cups_device
=
174 prn_device_body_copies(gx_device_cups
, cups_procs
, "cups", 85, 110, 100, 100,
175 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, cups_print_pages
),
184 0, /* AdvanceDistance */
185 CUPS_ADVANCE_NONE
, /* AdvanceMedia */
186 CUPS_FALSE
, /* Collate */
187 CUPS_CUT_NONE
, /* CutMedia */
188 CUPS_FALSE
, /* Duplex */
189 { 100, 100 }, /* HWResolution */
190 { 0, 0, 612, 792 }, /* ImagingBoundingBox */
191 CUPS_FALSE
, /* InsertSheet */
192 CUPS_JOG_NONE
, /* Jog */
193 CUPS_EDGE_TOP
, /* LeadingEdge */
194 { 0, 0 }, /* Margins */
195 CUPS_FALSE
, /* ManualFeed */
196 0, /* MediaPosition */
198 CUPS_FALSE
, /* MirrorPrint */
199 CUPS_FALSE
, /* NegativePrint */
201 CUPS_ORIENT_0
, /* Orientation */
202 CUPS_FALSE
, /* OutputFaceUp */
203 { 612, 792 }, /* PageSize */
204 CUPS_FALSE
, /* Separations */
205 CUPS_FALSE
, /* TraySwitch */
206 CUPS_FALSE
, /* Tumble */
208 1100, /* cupsHeight */
209 0, /* cupsMediaType */
210 1, /* cupsBitsPerColor */
211 1, /* cupsBitsPerPixel */
212 107, /* cupsBytesPerLine */
213 CUPS_ORDER_CHUNKED
, /* cupsColorOrder */
214 CUPS_CSPACE_K
, /* cupsColorSpace */
215 0, /* cupsCompression */
216 0, /* cupsRowCount */
223 * Color lookup tables...
226 static gx_color_value lut_color_rgb
[256];
227 static unsigned char lut_rgb_color
[gx_max_color_value
+ 1];
228 static int cupsHaveProfile
= 0;
229 static int cupsMatrix
[3][3][gx_max_color_value
+ 1];
230 static int cupsDensity
[gx_max_color_value
+ 1];
231 static unsigned char rev_lower1
[16] =
233 0x00, 0x08, 0x04, 0x0c, 0x02, 0x0a, 0x06, 0x0e,
234 0x01, 0x09, 0x05, 0x0d, 0x03, 0x0b, 0x07, 0x0f
238 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
239 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0
241 rev_lower2
[16] = /* 2-bit colors */
243 0x00, 0x04, 0x08, 0x0c, 0x01, 0x05, 0x09, 0x0d,
244 0x02, 0x06, 0x0a, 0x0e, 0x03, 0x07, 0x0b, 0x0f
246 rev_upper2
[16] = /* 2-bit colors */
248 0x00, 0x40, 0x80, 0xc0, 0x10, 0x50, 0x90, 0xd0,
249 0x20, 0x60, 0xa0, 0xe0, 0x30, 0x70, 0xb0, 0xf0
257 static void cups_print_chunked(gx_device_printer
*, unsigned char *,
258 unsigned char *, int);
259 static void cups_print_banded(gx_device_printer
*, unsigned char *,
260 unsigned char *, int);
261 static void cups_print_planar(gx_device_printer
*, unsigned char *,
262 unsigned char *, int);
264 /*static void cups_set_margins(gx_device *);*/
268 * 'cups_close()' - Close the output file.
272 cups_close(gx_device
*pdev
) /* I - Device info */
275 fprintf(stderr
, "DEBUG: cups_close(%p)\n", pdev
);
278 if (cups
->stream
!= NULL
)
280 cupsRasterClose(cups
->stream
);
284 #if 0 /* Can't do this here because put_params() might close the device */
285 if (cups
->ppd
!= NULL
)
292 return (gdev_prn_close(pdev
));
297 * 'cups_get_matrix()' - Generate the default page matrix.
301 cups_get_matrix(gx_device
*pdev
, /* I - Device info */
302 gs_matrix
*pmat
) /* O - Physical transform matrix */
305 fprintf(stderr
, "DEBUG: cups_get_matrix(%p, %p)\n", pdev
, pmat
);
309 * Set the raster width and height...
312 cups
->header
.cupsWidth
= cups
->width
;
313 cups
->header
.cupsHeight
= cups
->height
;
316 * Set the transform matrix...
319 fprintf(stderr
, "DEBUG: cups->header.Duplex = %d\n", cups
->header
.Duplex
);
320 fprintf(stderr
, "DEBUG: cups->page = %d\n", cups
->page
);
323 fprintf(stderr
, "DEBUG: cups->ppd = %p\n", cups
->ppd
);
324 fprintf(stderr
, "DEBUG: cups->ppd->flip_duplex = %d\n", cups
->ppd
->flip_duplex
);
327 if (cups
->header
.Duplex
&& !cups
->header
.Tumble
&&
328 cups
->ppd
&& cups
->ppd
->flip_duplex
&& !(cups
->page
& 1))
330 pmat
->xx
= (float)cups
->header
.HWResolution
[0] / 72.0;
333 pmat
->yy
= (float)cups
->header
.HWResolution
[1] / 72.0;
334 pmat
->tx
= -(float)cups
->header
.HWResolution
[0] * pdev
->HWMargins
[2] / 72.0;
335 pmat
->ty
= -(float)cups
->header
.HWResolution
[1] * pdev
->HWMargins
[3] / 72.0;
339 pmat
->xx
= (float)cups
->header
.HWResolution
[0] / 72.0;
342 pmat
->yy
= -(float)cups
->header
.HWResolution
[1] / 72.0;
343 pmat
->tx
= -(float)cups
->header
.HWResolution
[0] * pdev
->HWMargins
[0] / 72.0;
344 pmat
->ty
= (float)cups
->header
.HWResolution
[1] *
345 ((float)cups
->header
.PageSize
[1] - pdev
->HWMargins
[3]) / 72.0;
348 fprintf(stderr
, "DEBUG: width = %d, height = %d\n", cups
->width
,
350 fprintf(stderr
, "DEBUG: PageSize = [ %d %d ], HWResolution = [ %d %d ]\n",
351 cups
->header
.PageSize
[0], cups
->header
.PageSize
[1],
352 cups
->header
.HWResolution
[0], cups
->header
.HWResolution
[1]);
353 fprintf(stderr
, "DEBUG: HWMargins = [ %.3f %.3f %.3f %.3f ]\n",
354 pdev
->HWMargins
[0], pdev
->HWMargins
[1], pdev
->HWMargins
[2],
356 fprintf(stderr
, "DEBUG: matrix = [ %.3f %.3f %.3f %.3f %.3f %.3f ]\n",
357 pmat
->xx
, pmat
->xy
, pmat
->yx
, pmat
->yy
, pmat
->tx
, pmat
->ty
);
362 * 'cups_get_params()' - Get pagedevice parameters.
365 private int /* O - Error status */
366 cups_get_params(gx_device
*pdev
, /* I - Device info */
367 gs_param_list
*plist
) /* I - Parameter list */
369 int code
; /* Return code */
370 gs_param_string s
; /* Temporary string value */
371 bool b
; /* Temporary boolean value */
375 fprintf(stderr
, "DEBUG: cups_get_params(%p, %p)\n", pdev
, plist
);
379 * First process the "standard" page device parameters...
383 fputs("DEBUG: before gdev_prn_get_params()\n", stderr
);
386 if ((code
= gdev_prn_get_params(pdev
, plist
)) < 0)
390 fputs("DEBUG: after gdev_prn_get_params()\n", stderr
);
394 * Then write the CUPS parameters...
398 fputs("DEBUG: MediaClass\n", stderr
);
401 param_string_from_string(s
, cups
->header
.MediaClass
);
402 if ((code
= param_write_string(plist
, "MediaClass", &s
)) < 0)
406 fputs("DEBUG: AdvanceDistance\n", stderr
);
409 if ((code
= param_write_int(plist
, "AdvanceDistance",
410 (int *)&(cups
->header
.AdvanceDistance
))) < 0)
414 fputs("DEBUG: AdvanceDistance\n", stderr
);
417 if ((code
= param_write_int(plist
, "AdvanceMedia",
418 (int *)&(cups
->header
.AdvanceMedia
))) < 0)
422 fputs("DEBUG: Collate\n", stderr
);
425 b
= cups
->header
.Collate
;
426 if ((code
= param_write_bool(plist
, "Collate", &b
)) < 0)
430 fputs("DEBUG: CutMedia\n", stderr
);
433 if ((code
= param_write_int(plist
, "CutMedia",
434 (int *)&(cups
->header
.CutMedia
))) < 0)
438 fputs("DEBUG: InsertSheet\n", stderr
);
441 b
= cups
->header
.InsertSheet
;
442 if ((code
= param_write_bool(plist
, "InsertSheet", &b
)) < 0)
446 fputs("DEBUG: Jog\n", stderr
);
449 if ((code
= param_write_int(plist
, "Jog",
450 (int *)&(cups
->header
.Jog
))) < 0)
454 fputs("DEBUG: LeadingEdge\n", stderr
);
457 if ((code
= param_write_int(plist
, "LeadingEdge",
458 (int *)&(cups
->header
.LeadingEdge
))) < 0)
462 fputs("DEBUG: ManualFeed\n", stderr
);
465 b
= cups
->header
.ManualFeed
;
466 if ((code
= param_write_bool(plist
, "ManualFeed", &b
)) < 0)
470 fputs("DEBUG: MediaPosition\n", stderr
);
473 if ((code
= param_write_int(plist
, "MediaPosition",
474 (int *)&(cups
->header
.MediaPosition
))) < 0)
478 fputs("DEBUG: MirrorPrint\n", stderr
);
481 b
= cups
->header
.MirrorPrint
;
482 if ((code
= param_write_bool(plist
, "MirrorPrint", &b
)) < 0)
486 fputs("DEBUG: NegativePrint\n", stderr
);
489 b
= cups
->header
.NegativePrint
;
490 if ((code
= param_write_bool(plist
, "NegativePrint", &b
)) < 0)
494 fputs("DEBUG: OutputFaceUp\n", stderr
);
497 b
= cups
->header
.OutputFaceUp
;
498 if ((code
= param_write_bool(plist
, "OutputFaceUp", &b
)) < 0)
502 fputs("DEBUG: Separations\n", stderr
);
505 b
= cups
->header
.Separations
;
506 if ((code
= param_write_bool(plist
, "Separations", &b
)) < 0)
510 fputs("DEBUG: TraySwitch\n", stderr
);
513 b
= cups
->header
.TraySwitch
;
514 if ((code
= param_write_bool(plist
, "TraySwitch", &b
)) < 0)
518 fputs("DEBUG: Tumble\n", stderr
);
521 b
= cups
->header
.Tumble
;
522 if ((code
= param_write_bool(plist
, "Tumble", &b
)) < 0)
526 fputs("DEBUG: cupsWidth\n", stderr
);
529 if ((code
= param_write_int(plist
, "cupsWidth",
530 (int *)&(cups
->header
.cupsWidth
))) < 0)
534 fputs("DEBUG: cupsHeight\n", stderr
);
537 if ((code
= param_write_int(plist
, "cupsHeight",
538 (int *)&(cups
->header
.cupsHeight
))) < 0)
542 fputs("DEBUG: cupsMediaType\n", stderr
);
545 if ((code
= param_write_int(plist
, "cupsMediaType",
546 (int *)&(cups
->header
.cupsMediaType
))) < 0)
550 fputs("DEBUG: cupsBitsPerColor\n", stderr
);
553 if ((code
= param_write_int(plist
, "cupsBitsPerColor",
554 (int *)&(cups
->header
.cupsBitsPerColor
))) < 0)
558 fputs("DEBUG: cupsBitsPerPixel\n", stderr
);
561 if ((code
= param_write_int(plist
, "cupsBitsPerPixel",
562 (int *)&(cups
->header
.cupsBitsPerPixel
))) < 0)
566 fputs("DEBUG: cupsBytesPerLine\n", stderr
);
569 if ((code
= param_write_int(plist
, "cupsBytesPerLine",
570 (int *)&(cups
->header
.cupsBytesPerLine
))) < 0)
574 fputs("DEBUG: cupsColorOrder\n", stderr
);
577 if ((code
= param_write_int(plist
, "cupsColorOrder",
578 (int *)&(cups
->header
.cupsColorOrder
))) < 0)
582 fputs("DEBUG: cupsColorSpace\n", stderr
);
585 if ((code
= param_write_int(plist
, "cupsColorSpace",
586 (int *)&(cups
->header
.cupsColorSpace
))) < 0)
590 fputs("DEBUG: cupsCompression\n", stderr
);
593 if ((code
= param_write_int(plist
, "cupsCompression",
594 (int *)&(cups
->header
.cupsCompression
))) < 0)
598 fputs("DEBUG: cupsRowCount\n", stderr
);
601 if ((code
= param_write_int(plist
, "cupsRowCount",
602 (int *)&(cups
->header
.cupsRowCount
))) < 0)
606 fputs("DEBUG: cupsRowFeed\n", stderr
);
609 if ((code
= param_write_int(plist
, "cupsRowFeed",
610 (int *)&(cups
->header
.cupsRowFeed
))) < 0)
614 fputs("DEBUG: cupsRowStep\n", stderr
);
617 if ((code
= param_write_int(plist
, "cupsRowStep",
618 (int *)&(cups
->header
.cupsRowStep
))) < 0)
622 fputs("DEBUG: Leaving cups_get_params()\n", stderr
);
630 * 'cups_map_cmyk_color()' - Map a CMYK color to a color index.
632 * This function is only called when a 4 or 6 color colorspace is
633 * selected for output. CMYK colors are *not* corrected but *are*
637 private gx_color_index
/* O - Color index */
638 cups_map_cmyk_color(gx_device
*pdev
, /* I - Device info */
639 gx_color_value c
, /* I - Cyan value */
640 gx_color_value m
, /* I - Magenta value */
641 gx_color_value y
, /* I - Yellow value */
642 gx_color_value k
) /* I - Black value */
644 gx_color_index i
; /* Temporary index */
645 gx_color_value ic
, im
, iy
, ik
; /* Integral CMYK values */
649 fprintf(stderr
, "DEBUG: cups_map_cmyk_color(%p, %d, %d, %d, %d)\n", pdev
,
654 * Setup the color info data as needed...
657 if (pdev
->color_info
.num_components
== 0)
658 cups_set_color_info(pdev
);
669 ic
= lut_rgb_color
[c
];
670 im
= lut_rgb_color
[m
];
671 iy
= lut_rgb_color
[y
];
672 ik
= lut_rgb_color
[k
];
675 * Convert the CMYK color to a color index...
678 switch (cups
->header
.cupsColorSpace
)
681 switch (cups
->header
.cupsBitsPerColor
)
684 i
= (((((ic
<< 1) | im
) << 1) | iy
) << 1) | ik
;
687 i
= (((((ic
<< 2) | im
) << 2) | iy
) << 2) | ik
;
690 i
= (((((ic
<< 4) | im
) << 4) | iy
) << 4) | ik
;
693 i
= (((((ic
<< 8) | im
) << 8) | iy
) << 8) | ik
;
698 case CUPS_CSPACE_YMCK
:
699 case CUPS_CSPACE_GMCK
:
700 case CUPS_CSPACE_GMCS
:
701 switch (cups
->header
.cupsBitsPerColor
)
704 i
= (((((iy
<< 1) | im
) << 1) | ic
) << 1) | ik
;
707 i
= (((((iy
<< 2) | im
) << 2) | ic
) << 2) | ik
;
710 i
= (((((iy
<< 4) | im
) << 4) | ic
) << 4) | ik
;
713 i
= (((((iy
<< 8) | im
) << 8) | ic
) << 8) | ik
;
718 case CUPS_CSPACE_KCMYcm
:
719 if (cups
->header
.cupsBitsPerColor
== 1)
741 case CUPS_CSPACE_KCMY
:
742 switch (cups
->header
.cupsBitsPerColor
)
745 i
= (((((ik
<< 1) | ic
) << 1) | im
) << 1) | iy
;
748 i
= (((((ik
<< 2) | ic
) << 2) | im
) << 2) | iy
;
751 i
= (((((ik
<< 4) | ic
) << 4) | im
) << 4) | iy
;
754 i
= (((((ik
<< 8) | ic
) << 8) | im
) << 8) | iy
;
760 if (gs_log_errors
> 1)
761 fprintf(stderr
, "DEBUG: CMYK (%d,%d,%d,%d) -> CMYK %8x (%d,%d,%d,%d)\n",
762 c
, m
, y
, k
, i
, ic
, im
, iy
, ik
);
769 * 'cups_map_color_rgb()' - Map a color index to an RGB color.
773 cups_map_color_rgb(gx_device
*pdev
, /* I - Device info */
774 gx_color_index color
, /* I - Color index */
775 gx_color_value prgb
[3]) /* O - RGB values */
777 unsigned char c0
, c1
, c2
, c3
; /* Color index components */
778 gx_color_value k
, divk
; /* Black & divisor */
782 fprintf(stderr
, "DEBUG: cups_map_color_rgb(%p, %d, %8x)\n", pdev
,
787 * Setup the color info data as needed...
790 if (pdev
->color_info
.num_components
== 0)
791 cups_set_color_info(pdev
);
794 fprintf(stderr
, "DEBUG: COLOR %8x = ", color
);
798 * Extract the color components from the color index...
801 switch (cups
->header
.cupsBitsPerColor
)
842 * Convert the color components to RGB...
845 switch (cups
->header
.cupsColorSpace
)
848 case CUPS_CSPACE_WHITE
:
849 case CUPS_CSPACE_GOLD
:
850 case CUPS_CSPACE_SILVER
:
853 prgb
[2] = lut_color_rgb
[c3
];
859 prgb
[2] = lut_color_rgb
[c3
];
862 case CUPS_CSPACE_RGB
:
863 prgb
[0] = lut_color_rgb
[c1
];
864 prgb
[1] = lut_color_rgb
[c2
];
865 prgb
[2] = lut_color_rgb
[c3
];
868 case CUPS_CSPACE_RGBA
:
869 prgb
[0] = lut_color_rgb
[c0
];
870 prgb
[1] = lut_color_rgb
[c1
];
871 prgb
[2] = lut_color_rgb
[c2
];
874 case CUPS_CSPACE_CMY
:
875 prgb
[0] = lut_color_rgb
[c1
];
876 prgb
[1] = lut_color_rgb
[c2
];
877 prgb
[2] = lut_color_rgb
[c3
];
880 case CUPS_CSPACE_YMC
:
881 prgb
[0] = lut_color_rgb
[c3
];
882 prgb
[1] = lut_color_rgb
[c2
];
883 prgb
[2] = lut_color_rgb
[c1
];
886 case CUPS_CSPACE_KCMY
:
887 case CUPS_CSPACE_KCMYcm
:
888 k
= lut_color_rgb
[c0
];
889 divk
= gx_max_color_value
- k
;
898 prgb
[0] = gx_max_color_value
+ divk
-
899 gx_max_color_value
* c1
/ divk
;
900 prgb
[1] = gx_max_color_value
+ divk
-
901 gx_max_color_value
* c2
/ divk
;
902 prgb
[2] = gx_max_color_value
+ divk
-
903 gx_max_color_value
* c3
/ divk
;
907 case CUPS_CSPACE_CMYK
:
908 k
= lut_color_rgb
[c3
];
909 divk
= gx_max_color_value
- k
;
918 prgb
[0] = gx_max_color_value
+ divk
-
919 gx_max_color_value
* c0
/ divk
;
920 prgb
[1] = gx_max_color_value
+ divk
-
921 gx_max_color_value
* c1
/ divk
;
922 prgb
[2] = gx_max_color_value
+ divk
-
923 gx_max_color_value
* c2
/ divk
;
927 case CUPS_CSPACE_YMCK
:
928 case CUPS_CSPACE_GMCK
:
929 case CUPS_CSPACE_GMCS
:
930 k
= lut_color_rgb
[c3
];
931 divk
= gx_max_color_value
- k
;
940 prgb
[0] = gx_max_color_value
+ divk
-
941 gx_max_color_value
* c2
/ divk
;
942 prgb
[1] = gx_max_color_value
+ divk
-
943 gx_max_color_value
* c1
/ divk
;
944 prgb
[2] = gx_max_color_value
+ divk
-
945 gx_max_color_value
* c0
/ divk
;
951 fprintf(stderr
, "%d,%d,%d\n", prgb
[0], prgb
[1], prgb
[2]);
959 * 'cups_map_rgb_color()' - Map an RGB color to a color index. We map the
960 * RGB color to the output colorspace & bits (we
961 * figure out the format when we output a page).
964 private gx_color_index
/* O - Color index */
965 cups_map_rgb_color(gx_device
*pdev
, /* I - Device info */
966 gx_color_value r
, /* I - Red value */
967 gx_color_value g
, /* I - Green value */
968 gx_color_value b
) /* I - Blue value */
970 gx_color_index i
; /* Temporary index */
971 gx_color_value ic
, im
, iy
, ik
; /* Integral CMYK values */
972 gx_color_value mk
; /* Maximum K value */
973 int tc
, tm
, ty
; /* Temporary color values */
977 fprintf(stderr
, "DEBUG: cups_map_rgb_color(%p, %d, %d, %d)\n", pdev
, r
, g
, b
);
981 * Setup the color info data as needed...
984 if (pdev
->color_info
.num_components
== 0)
985 cups_set_color_info(pdev
);
988 * Do color correction as needed...
994 * Compute CMYK values...
997 ic
= gx_max_color_value
- r
;
998 im
= gx_max_color_value
- g
;
999 iy
= gx_max_color_value
- b
;
1000 ik
= min(ic
, min(im
, iy
));
1002 if ((mk
= max(ic
, max(im
, iy
))) > ik
)
1003 ik
= (int)((float)ik
* (float)ik
* (float)ik
/ ((float)mk
* (float)mk
));
1010 * Color correct CMY...
1013 tc
= cupsMatrix
[0][0][ic
] +
1014 cupsMatrix
[0][1][im
] +
1015 cupsMatrix
[0][2][iy
] +
1017 tm
= cupsMatrix
[1][0][ic
] +
1018 cupsMatrix
[1][1][im
] +
1019 cupsMatrix
[1][2][iy
] +
1021 ty
= cupsMatrix
[2][0][ic
] +
1022 cupsMatrix
[2][1][im
] +
1023 cupsMatrix
[2][2][iy
] +
1027 * Density correct combined CMYK...
1031 r
= gx_max_color_value
;
1032 else if (tc
> gx_max_color_value
)
1033 r
= gx_max_color_value
- cupsDensity
[gx_max_color_value
];
1035 r
= gx_max_color_value
- cupsDensity
[tc
];
1038 g
= gx_max_color_value
;
1039 else if (tm
> gx_max_color_value
)
1040 g
= gx_max_color_value
- cupsDensity
[gx_max_color_value
];
1042 g
= gx_max_color_value
- cupsDensity
[tm
];
1045 b
= gx_max_color_value
;
1046 else if (ty
> gx_max_color_value
)
1047 b
= gx_max_color_value
- cupsDensity
[gx_max_color_value
];
1049 b
= gx_max_color_value
- cupsDensity
[ty
];
1053 * Convert the RGB color to a color index...
1056 switch (cups
->header
.cupsColorSpace
)
1058 case CUPS_CSPACE_W
:
1059 i
= lut_rgb_color
[(r
* 31 + g
* 61 + b
* 8) / 100];
1062 case CUPS_CSPACE_RGB
:
1063 ic
= lut_rgb_color
[r
];
1064 im
= lut_rgb_color
[g
];
1065 iy
= lut_rgb_color
[b
];
1067 switch (cups
->header
.cupsBitsPerColor
)
1070 i
= (((ic
<< 1) | im
) << 1) | iy
;
1073 i
= (((ic
<< 2) | im
) << 2) | iy
;
1076 i
= (((ic
<< 4) | im
) << 4) | iy
;
1079 i
= (((ic
<< 8) | im
) << 8) | iy
;
1084 case CUPS_CSPACE_RGBA
:
1085 ic
= lut_rgb_color
[r
];
1086 im
= lut_rgb_color
[g
];
1087 iy
= lut_rgb_color
[b
];
1089 switch (cups
->header
.cupsBitsPerColor
)
1092 i
= (((((ic
<< 1) | im
) << 1) | iy
) << 1) | 0x01;
1095 i
= (((((ic
<< 2) | im
) << 2) | iy
) << 2) | 0x03;
1098 i
= (((((ic
<< 4) | im
) << 4) | iy
) << 4) | 0x0f;
1101 i
= (((((ic
<< 8) | im
) << 8) | iy
) << 8) | 0xff;
1107 i
= lut_rgb_color
[gx_max_color_value
- (r
* 31 + g
* 61 + b
* 8) / 100];
1110 case CUPS_CSPACE_CMY
:
1111 ic
= lut_rgb_color
[gx_max_color_value
- r
];
1112 im
= lut_rgb_color
[gx_max_color_value
- g
];
1113 iy
= lut_rgb_color
[gx_max_color_value
- b
];
1115 switch (cups
->header
.cupsBitsPerColor
)
1118 i
= (((ic
<< 1) | im
) << 1) | iy
;
1121 i
= (((ic
<< 2) | im
) << 2) | iy
;
1124 i
= (((ic
<< 4) | im
) << 4) | iy
;
1127 i
= (((ic
<< 8) | im
) << 8) | iy
;
1132 case CUPS_CSPACE_YMC
:
1133 ic
= lut_rgb_color
[gx_max_color_value
- r
];
1134 im
= lut_rgb_color
[gx_max_color_value
- g
];
1135 iy
= lut_rgb_color
[gx_max_color_value
- b
];
1137 switch (cups
->header
.cupsBitsPerColor
)
1140 i
= (((iy
<< 1) | im
) << 1) | ic
;
1143 i
= (((iy
<< 2) | im
) << 2) | ic
;
1146 i
= (((iy
<< 4) | im
) << 4) | ic
;
1149 i
= (((iy
<< 8) | im
) << 8) | ic
;
1154 case CUPS_CSPACE_CMYK
:
1155 ic
= gx_max_color_value
- r
;
1156 im
= gx_max_color_value
- g
;
1157 iy
= gx_max_color_value
- b
;
1158 ik
= min(ic
, min(im
, iy
));
1160 if ((mk
= max(ic
, max(im
, iy
))) > ik
)
1161 ik
= (int)((float)ik
* (float)ik
* (float)ik
/
1162 ((float)mk
* (float)mk
));
1164 ic
= lut_rgb_color
[ic
- ik
];
1165 im
= lut_rgb_color
[im
- ik
];
1166 iy
= lut_rgb_color
[iy
- ik
];
1167 ik
= lut_rgb_color
[ik
];
1169 switch (cups
->header
.cupsBitsPerColor
)
1172 i
= (((((ic
<< 1) | im
) << 1) | iy
) << 1) | ik
;
1175 i
= (((((ic
<< 2) | im
) << 2) | iy
) << 2) | ik
;
1178 i
= (((((ic
<< 4) | im
) << 4) | iy
) << 4) | ik
;
1181 i
= (((((ic
<< 8) | im
) << 8) | iy
) << 8) | ik
;
1185 if (gs_log_errors
> 1)
1186 fprintf(stderr
, "DEBUG: CMY (%d,%d,%d) -> CMYK %8x (%d,%d,%d,%d)\n",
1187 r
, g
, b
, i
, ic
, im
, iy
, ik
);
1190 case CUPS_CSPACE_YMCK
:
1191 case CUPS_CSPACE_GMCK
:
1192 case CUPS_CSPACE_GMCS
:
1193 ic
= gx_max_color_value
- r
;
1194 im
= gx_max_color_value
- g
;
1195 iy
= gx_max_color_value
- b
;
1196 ik
= min(ic
, min(im
, iy
));
1198 if ((mk
= max(ic
, max(im
, iy
))) > ik
)
1199 ik
= (int)((float)ik
* (float)ik
* (float)ik
/
1200 ((float)mk
* (float)mk
));
1202 ic
= lut_rgb_color
[ic
- ik
];
1203 im
= lut_rgb_color
[im
- ik
];
1204 iy
= lut_rgb_color
[iy
- ik
];
1205 ik
= lut_rgb_color
[ik
];
1207 switch (cups
->header
.cupsBitsPerColor
)
1210 i
= (((((iy
<< 1) | im
) << 1) | ic
) << 1) | ik
;
1213 i
= (((((iy
<< 2) | im
) << 2) | ic
) << 2) | ik
;
1216 i
= (((((iy
<< 4) | im
) << 4) | ic
) << 4) | ik
;
1219 i
= (((((iy
<< 8) | im
) << 8) | ic
) << 8) | ik
;
1224 case CUPS_CSPACE_KCMYcm
:
1225 if (cups
->header
.cupsBitsPerColor
== 1)
1227 ic
= gx_max_color_value
- r
;
1228 im
= gx_max_color_value
- g
;
1229 iy
= gx_max_color_value
- b
;
1230 ik
= min(ic
, min(im
, iy
));
1232 if ((mk
= max(ic
, max(im
, iy
))) > ik
)
1233 ik
= (int)((float)ik
* (float)ik
* (float)ik
/
1234 ((float)mk
* (float)mk
));
1236 ic
= lut_rgb_color
[ic
- ik
];
1237 im
= lut_rgb_color
[im
- ik
];
1238 iy
= lut_rgb_color
[iy
- ik
];
1239 ik
= lut_rgb_color
[ik
];
1259 case CUPS_CSPACE_KCMY
:
1260 ic
= gx_max_color_value
- r
;
1261 im
= gx_max_color_value
- g
;
1262 iy
= gx_max_color_value
- b
;
1263 ik
= min(ic
, min(im
, iy
));
1265 if ((mk
= max(ic
, max(im
, iy
))) > ik
)
1266 ik
= (int)((float)ik
* (float)ik
* (float)ik
/
1267 ((float)mk
* (float)mk
));
1269 ic
= lut_rgb_color
[ic
- ik
];
1270 im
= lut_rgb_color
[im
- ik
];
1271 iy
= lut_rgb_color
[iy
- ik
];
1272 ik
= lut_rgb_color
[ik
];
1274 switch (cups
->header
.cupsBitsPerColor
)
1277 i
= (((((ik
<< 1) | ic
) << 1) | im
) << 1) | iy
;
1280 i
= (((((ik
<< 2) | ic
) << 2) | im
) << 2) | iy
;
1283 i
= (((((ik
<< 4) | ic
) << 4) | im
) << 4) | iy
;
1286 i
= (((((ik
<< 8) | ic
) << 8) | im
) << 8) | iy
;
1293 fprintf(stderr
, "DEBUG: RGB %d,%d,%d = %8x\n", r
, g
, b
, i
);
1301 * 'cups_open()' - Open the output file and initialize things.
1304 private int /* O - Error status */
1305 cups_open(gx_device
*pdev
) /* I - Device info */
1307 int code
; /* Return status */
1311 fprintf(stderr
, "DEBUG: cups_open(%p)\n", pdev
);
1314 if (cups
->page
== 0)
1316 fputs("INFO: Processing page 1...\n", stderr
);
1320 if (pdev
->color_info
.num_components
== 0)
1321 cups_set_color_info(pdev
);
1323 if ((code
= gdev_prn_open(pdev
)) != 0)
1326 if (cups
->ppd
== NULL
)
1327 cups
->ppd
= ppdOpenFile(getenv("PPD"));
1334 * 'cups_print_pages()' - Send one or more pages to the output file.
1337 private int /* O - 0 if everything is OK */
1338 cups_print_pages(gx_device_printer
*pdev
, /* I - Device info */
1339 FILE *fp
, /* I - Output file */
1340 int num_copies
) /* I - Number of copies */
1342 int copy
; /* Copy number */
1343 int srcbytes
; /* Byte width of scanline */
1344 unsigned char *src
, /* Scanline data */
1345 *dst
; /* Bitmap data */
1348 (void)fp
; /* reference unused file pointer to prevent compiler warning */
1351 fprintf(stderr
, "DEBUG: cups_print_pages(%p, %p, %d)\n", pdev
, fp
,
1356 * Figure out the number of bytes per line...
1359 switch (cups
->header
.cupsColorOrder
)
1361 case CUPS_ORDER_CHUNKED
:
1362 cups
->header
.cupsBytesPerLine
= (cups
->header
.cupsBitsPerPixel
*
1363 cups
->header
.cupsWidth
+ 7) / 8;
1366 case CUPS_ORDER_BANDED
:
1367 if (cups
->header
.cupsColorSpace
== CUPS_CSPACE_KCMYcm
&&
1368 cups
->header
.cupsBitsPerColor
== 1)
1369 cups
->header
.cupsBytesPerLine
= (cups
->header
.cupsBitsPerColor
*
1370 cups
->header
.cupsWidth
+ 7) / 8 * 6;
1372 cups
->header
.cupsBytesPerLine
= (cups
->header
.cupsBitsPerColor
*
1373 cups
->header
.cupsWidth
+ 7) / 8 *
1374 cups
->color_info
.num_components
;
1377 case CUPS_ORDER_PLANAR
:
1378 cups
->header
.cupsBytesPerLine
= (cups
->header
.cupsBitsPerColor
*
1379 cups
->header
.cupsWidth
+ 7) / 8;
1384 * Compute the width of a scanline and allocate input/output buffers...
1387 srcbytes
= gdev_prn_raster(pdev
);
1390 fprintf(stderr
, "DEBUG: cupsBitsPerPixel = %d, cupsWidth = %d, cupsBytesPerLine = %d, srcbytes = %d\n",
1391 cups
->header
.cupsBitsPerPixel
, cups
->header
.cupsWidth
,
1392 cups
->header
.cupsBytesPerLine
, srcbytes
);
1395 src
= (unsigned char *)gs_malloc(srcbytes
, 1, "cups_print_pages");
1397 if (src
== NULL
) /* can't allocate input buffer */
1398 return_error(gs_error_VMerror
);
1401 * Need an output buffer, too...
1404 dst
= (unsigned char *)gs_malloc(cups
->header
.cupsBytesPerLine
, 2,
1405 "cups_print_pages");
1407 if (dst
== NULL
) /* can't allocate working area */
1408 return_error(gs_error_VMerror
);
1411 * See if the stream has been initialized yet...
1414 if (cups
->stream
== NULL
)
1416 if ((cups
->stream
= cupsRasterOpen(1, CUPS_RASTER_WRITE
)) == NULL
)
1418 perror("ERROR: Unable to open raster stream - ");
1424 * Output a page of graphics...
1430 if (cups
->ppd
!= NULL
&& !cups
->ppd
->manual_copies
)
1432 cups
->header
.NumCopies
= num_copies
;
1437 fprintf(stderr
, "DEBUG: cupsWidth = %d, cupsHeight = %d, cupsBytesPerLine = %d\n",
1438 cups
->header
.cupsWidth
, cups
->header
.cupsHeight
,
1439 cups
->header
.cupsBytesPerLine
);
1442 for (copy
= num_copies
; copy
> 0; copy
--)
1444 cupsRasterWriteHeader(cups
->stream
, &(cups
->header
));
1446 if (pdev
->color_info
.num_components
== 1)
1447 cups_print_chunked(pdev
, src
, dst
, srcbytes
);
1449 switch (cups
->header
.cupsColorOrder
)
1451 case CUPS_ORDER_CHUNKED
:
1452 cups_print_chunked(pdev
, src
, dst
, srcbytes
);
1454 case CUPS_ORDER_BANDED
:
1455 cups_print_banded(pdev
, src
, dst
, srcbytes
);
1457 case CUPS_ORDER_PLANAR
:
1458 cups_print_planar(pdev
, src
, dst
, srcbytes
);
1464 * Free temporary storage and return...
1467 gs_free((char *)src
, srcbytes
, 1, "cups_print_pages");
1468 gs_free((char *)dst
, cups
->header
.cupsBytesPerLine
, 1, "cups_print_pages");
1471 fprintf(stderr
, "INFO: Processing page %d...\n", cups
->page
);
1478 * 'cups_put_params()' - Set pagedevice parameters.
1481 private int /* O - Error status */
1482 cups_put_params(gx_device
*pdev
, /* I - Device info */
1483 gs_param_list
*plist
) /* I - Parameter list */
1485 int i
; /* Looping var */
1486 float margins
[4]; /* Physical margins of print */
1487 ppd_size_t
*size
; /* Page size */
1488 int code
; /* Error code */
1489 int intval
; /* Integer value */
1490 bool boolval
; /* Boolean value */
1491 float floatval
; /* Floating point value */
1492 gs_param_string stringval
; /* String value */
1493 gs_param_float_array arrayval
; /* Float array value */
1494 int old_depth
; /* Old color depth */
1495 int size_set
; /* Was the size set? */
1496 gdev_prn_space_params sp
; /* Space parameter data */
1500 fprintf(stderr
, "DEBUG: cups_put_params(%p, %p)\n", pdev
, plist
);
1504 * Process other options for CUPS...
1507 #define stringoption(name, sname) \
1508 if ((code = param_read_string(plist, sname, &stringval)) < 0) \
1510 param_signal_error(plist, sname, code); \
1513 else if (code == 0) \
1515 strncpy(cups->header.name, (const char *)stringval.data, \
1517 cups->header.name[stringval.size] = '\0'; \
1520 #define intoption(name, sname, type) \
1521 if ((code = param_read_int(plist, sname, &intval)) < 0) \
1523 param_signal_error(plist, sname, code); \
1526 else if (code == 0) \
1528 fprintf(stderr, "DEBUG: Setting %s to %d...\n", sname, intval); \
1529 cups->header.name = (type)intval; \
1532 #define floatoption(name, sname) \
1533 if ((code = param_read_float(plist, sname, &floatval)) < 0) \
1535 param_signal_error(plist, sname, code); \
1538 else if (code == 0) \
1539 cups->header.name = (unsigned)floatval;
1541 #define booloption(name, sname) \
1542 if ((code = param_read_bool(plist, sname, &boolval)) < 0) \
1544 if ((code = param_read_null(plist, sname)) < 0) \
1546 param_signal_error(plist, sname, code); \
1550 cups->header.name = CUPS_FALSE; \
1552 else if (code == 0) \
1553 cups->header.name = (cups_bool_t)boolval;
1555 #define arrayoption(name, sname, count) \
1556 if ((code = param_read_float_array(plist, sname, &arrayval)) < 0) \
1558 if ((code = param_read_null(plist, sname)) < 0) \
1560 param_signal_error(plist, sname, code); \
1564 for (i = 0; i < count; i ++) \
1565 cups->header.name[i] = 0; \
1567 else if (code == 0) \
1569 for (i = 0; i < count; i ++) \
1570 cups->header.name[i] = (unsigned)arrayval.data[i]; \
1573 old_depth
= pdev
->color_info
.depth
;
1574 size_set
= param_read_float_array(plist
, "PageSize", &arrayval
) == 0;
1576 stringoption(MediaClass
, "MediaClass")
1577 stringoption(MediaColor
, "MediaColor")
1578 stringoption(MediaType
, "MediaType")
1579 stringoption(OutputType
, "OutputType")
1580 floatoption(AdvanceDistance
, "AdvanceDistance")
1581 intoption(AdvanceMedia
, "AdvanceMedia", cups_adv_t
)
1582 booloption(Collate
, "Collate")
1583 intoption(CutMedia
, "CutMedia", cups_cut_t
)
1584 booloption(Duplex
, "Duplex")
1585 arrayoption(ImagingBoundingBox
, "ImagingBoundingBox", 4)
1586 booloption(InsertSheet
, "InsertSheet")
1587 intoption(Jog
, "Jog", cups_jog_t
)
1588 intoption(LeadingEdge
, "LeadingEdge", cups_edge_t
)
1589 arrayoption(Margins
, "Margins", 2)
1590 booloption(ManualFeed
, "ManualFeed")
1591 intoption(MediaPosition
, "cupsMediaPosition", unsigned) /* Compatibility */
1592 intoption(MediaPosition
, "MediaPosition", unsigned)
1593 floatoption(MediaWeight
, "MediaWeight")
1594 booloption(MirrorPrint
, "MirrorPrint")
1595 booloption(NegativePrint
, "NegativePrint")
1596 intoption(NumCopies
, "NumCopies", unsigned)
1597 intoption(Orientation
, "Orientation", cups_orient_t
)
1598 booloption(OutputFaceUp
, "OutputFaceUp")
1599 booloption(Separations
, "Separations")
1600 booloption(TraySwitch
, "TraySwitch")
1601 booloption(Tumble
, "Tumble")
1602 intoption(cupsMediaType
, "cupsMediaType", unsigned)
1603 intoption(cupsBitsPerColor
, "cupsBitsPerColor", unsigned)
1604 intoption(cupsColorOrder
, "cupsColorOrder", cups_order_t
)
1605 intoption(cupsColorSpace
, "cupsColorSpace", cups_cspace_t
)
1606 intoption(cupsCompression
, "cupsCompression", unsigned)
1607 intoption(cupsRowCount
, "cupsRowCount", unsigned)
1608 intoption(cupsRowFeed
, "cupsRowFeed", unsigned)
1609 intoption(cupsRowStep
, "cupsRowStep", unsigned)
1611 cups_set_color_info(pdev
);
1614 * Compute the page margins...
1617 if (cups
->ppd
!= NULL
)
1620 * Pull the margins from the first size entry; since the margins are not
1621 * like the bounding box we have to adjust the top and right values
1625 for (i
= cups
->ppd
->num_sizes
, size
= cups
->ppd
->sizes
;
1628 if ((fabs(cups
->PageSize
[1] - size
->length
) < 18.0 &&
1629 fabs(cups
->PageSize
[0] - size
->width
) < 18.0) ||
1630 (fabs(cups
->PageSize
[0] - size
->length
) < 18.0 &&
1631 fabs(cups
->PageSize
[1] - size
->width
) < 18.0))
1634 if (i
== 0 && !cups
->ppd
->variable_sizes
)
1637 size
= cups
->ppd
->sizes
;
1646 fprintf(stderr
, "DEBUG: size = %s\n", size
->name
);
1648 margins
[0] = size
->left
/ 72.0;
1649 margins
[1] = size
->bottom
/ 72.0;
1650 margins
[2] = (size
->width
- size
->right
) / 72.0;
1651 margins
[3] = (size
->length
- size
->top
) / 72.0;
1659 fputs("DEBUG: size = Custom\n", stderr
);
1661 for (i
= 0; i
< 4; i
++)
1662 margins
[i
] = cups
->ppd
->custom_margins
[i
] / 72.0;
1665 fprintf(stderr
, "DEBUG: margins[] = [ %f %f %f %f ]\n",
1666 margins
[0], margins
[1], margins
[2], margins
[3]);
1671 * Set default margins of 0.0...
1674 memset(margins
, 0, sizeof(margins
));
1678 * Set the margins to update the bitmap size...
1681 gx_device_set_margins(pdev
, margins
, false);
1684 * Then process standard page device options...
1687 if ((code
= gdev_prn_put_params(pdev
, plist
)) < 0)
1690 cups
->header
.HWResolution
[0] = pdev
->HWResolution
[0];
1691 cups
->header
.HWResolution
[1] = pdev
->HWResolution
[1];
1693 cups
->header
.PageSize
[0] = pdev
->PageSize
[0];
1694 cups
->header
.PageSize
[1] = pdev
->PageSize
[1];
1697 * Reallocate memory if the size or color depth was changed...
1700 if (old_depth
!= pdev
->color_info
.depth
|| size_set
)
1702 fputs("DEBUG: Reallocating memory...\n", stderr
);
1703 sp
= ((gx_device_printer
*)pdev
)->space_params
;
1705 if ((code
= gdev_prn_reallocate_memory(pdev
, &sp
, pdev
->width
,
1711 fprintf(stderr
, "DEBUG: ppd = %8x\n", cups
->ppd
);
1712 fprintf(stderr
, "DEBUG: PageSize = [ %.3f %.3f ]\n",
1713 pdev
->PageSize
[0], pdev
->PageSize
[1]);
1714 fprintf(stderr
, "DEBUG: margins = [ %.3f %.3f %.3f %.3f ]\n",
1715 margins
[0], margins
[1], margins
[2], margins
[3]);
1716 fprintf(stderr
, "DEBUG: HWResolution = [ %.3f %.3f ]\n",
1717 pdev
->HWResolution
[0], pdev
->HWResolution
[1]);
1718 fprintf(stderr
, "DEBUG: width = %d, height = %d\n",
1719 pdev
->width
, pdev
->height
);
1720 fprintf(stderr
, "DEBUG: HWMargins = [ %.3f %.3f %.3f %.3f ]\n",
1721 pdev
->HWMargins
[0], pdev
->HWMargins
[1],
1722 pdev
->HWMargins
[2], pdev
->HWMargins
[3]);
1730 * 'cups_set_color_info()' - Set the color information structure based on
1731 * the required output.
1735 cups_set_color_info(gx_device
*pdev
) /* I - Device info */
1737 int i
, j
, k
; /* Looping vars */
1738 float d
, g
; /* Density and gamma correction */
1739 float m
[3][3]; /* Color correction matrix */
1740 char resolution
[41]; /* Resolution string */
1741 ppd_profile_t
*profile
; /* Color profile information */
1745 fprintf(stderr
, "DEBUG: cups_set_color_info(%p)\n", pdev
);
1748 switch (cups
->header
.cupsColorSpace
)
1751 case CUPS_CSPACE_W
:
1752 case CUPS_CSPACE_K
:
1753 case CUPS_CSPACE_WHITE
:
1754 case CUPS_CSPACE_GOLD
:
1755 case CUPS_CSPACE_SILVER
:
1756 cups
->header
.cupsBitsPerPixel
= cups
->header
.cupsBitsPerColor
;
1757 cups
->color_info
.depth
= cups
->header
.cupsBitsPerPixel
;
1758 cups
->color_info
.num_components
= 1;
1761 case CUPS_CSPACE_CMY
:
1762 case CUPS_CSPACE_YMC
:
1763 case CUPS_CSPACE_RGB
:
1764 if (cups
->header
.cupsColorOrder
!= CUPS_ORDER_CHUNKED
)
1765 cups
->header
.cupsBitsPerPixel
= cups
->header
.cupsBitsPerColor
;
1766 else if (cups
->header
.cupsBitsPerColor
< 8)
1767 cups
->header
.cupsBitsPerPixel
= 4 * cups
->header
.cupsBitsPerColor
;
1769 cups
->header
.cupsBitsPerPixel
= 3 * cups
->header
.cupsBitsPerColor
;
1771 if (cups
->header
.cupsBitsPerColor
< 8)
1772 cups
->color_info
.depth
= 4 * cups
->header
.cupsBitsPerColor
;
1774 cups
->color_info
.depth
= 3 * cups
->header
.cupsBitsPerColor
;
1776 cups
->color_info
.num_components
= 3;
1779 case CUPS_CSPACE_KCMYcm
:
1780 if (cups
->header
.cupsBitsPerColor
== 1)
1782 cups
->header
.cupsBitsPerPixel
= 8;
1783 cups
->color_info
.depth
= 8;
1784 cups
->color_info
.num_components
= 4;
1788 case CUPS_CSPACE_CMYK
:
1789 case CUPS_CSPACE_YMCK
:
1790 case CUPS_CSPACE_KCMY
:
1791 case CUPS_CSPACE_GMCK
:
1792 case CUPS_CSPACE_GMCS
:
1793 if (cups
->header
.cupsColorOrder
!= CUPS_ORDER_CHUNKED
)
1794 cups
->header
.cupsBitsPerPixel
= cups
->header
.cupsBitsPerColor
;
1796 cups
->header
.cupsBitsPerPixel
= 4 * cups
->header
.cupsBitsPerColor
;
1798 cups
->color_info
.depth
= 4 * cups
->header
.cupsBitsPerColor
;
1799 cups
->color_info
.num_components
= 4;
1803 if (cups
->color_info
.num_components
> 1)
1805 cups
->color_info
.max_gray
= (1 << cups
->header
.cupsBitsPerColor
) - 1;
1806 cups
->color_info
.max_color
= (1 << cups
->header
.cupsBitsPerColor
) - 1;
1807 cups
->color_info
.dither_grays
= (1 << cups
->header
.cupsBitsPerColor
);
1808 cups
->color_info
.dither_colors
= (1 << cups
->header
.cupsBitsPerColor
);
1812 cups
->color_info
.max_gray
= (1 << cups
->header
.cupsBitsPerColor
) - 1;
1813 cups
->color_info
.max_color
= 0;
1814 cups
->color_info
.dither_grays
= (1 << cups
->header
.cupsBitsPerColor
);
1815 cups
->color_info
.dither_colors
= 0;
1819 * Enable/disable CMYK color support...
1822 if (cups
->color_info
.num_components
== 4)
1823 cups
->procs
.map_cmyk_color
= cups_map_cmyk_color
;
1825 cups
->procs
.map_cmyk_color
= NULL
;
1828 * Compute the lookup tables...
1831 for (i
= 0; i
<= gx_max_color_value
; i
++)
1832 lut_rgb_color
[i
] = cups
->color_info
.max_gray
* i
/ gx_max_color_value
;
1834 for (i
= 0; i
< cups
->color_info
.dither_grays
; i
++)
1835 lut_color_rgb
[i
] = gx_max_color_value
* i
/ cups
->color_info
.max_gray
;
1838 fprintf(stderr
, "DEBUG: num_components = %d, depth = %d\n",
1839 cups
->color_info
.num_components
, cups
->color_info
.depth
);
1840 fprintf(stderr
, "DEBUG: cupsColorSpace = %d, cupsColorOrder = %d\n",
1841 cups
->header
.cupsColorSpace
, cups
->header
.cupsColorOrder
);
1842 fprintf(stderr
, "DEBUG: cupsBitsPerPixel = %d, cupsBitsPerColor = %d\n",
1843 cups
->header
.cupsBitsPerPixel
, cups
->header
.cupsBitsPerColor
);
1844 fprintf(stderr
, "DEBUG: max_gray = %d, dither_grays = %d\n",
1845 cups
->color_info
.max_gray
, cups
->color_info
.dither_grays
);
1846 fprintf(stderr
, "DEBUG: max_color = %d, dither_colors = %d\n",
1847 cups
->color_info
.max_color
, cups
->color_info
.dither_colors
);
1851 * Set the color profile as needed...
1854 cupsHaveProfile
= 0;
1856 if (cupsProfile
&& cups
->header
.cupsBitsPerColor
== 8)
1858 fprintf(stderr
, "DEBUG: Using user-defined profile \"%s\"...\n", cupsProfile
);
1860 if (sscanf(cupsProfile
, "%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f", &d
, &g
,
1861 m
[0] + 0, m
[0] + 1, m
[0] + 2,
1862 m
[1] + 0, m
[1] + 1, m
[1] + 2,
1863 m
[2] + 0, m
[2] + 1, m
[2] + 2) != 11)
1864 fputs("DEBUG: User-defined profile does not contain 11 integers!\n", stderr
);
1867 cupsHaveProfile
= 1;
1882 else if (cups
->ppd
!= NULL
&& cups
->header
.cupsBitsPerColor
== 8)
1885 * Find the appropriate color profile...
1888 if (pdev
->HWResolution
[0] != pdev
->HWResolution
[1])
1889 sprintf(resolution
, "%.0fx%.0fdpi", pdev
->HWResolution
[0],
1890 pdev
->HWResolution
[1]);
1892 sprintf(resolution
, "%.0fdpi", pdev
->HWResolution
[0]);
1894 for (i
= 0, profile
= cups
->ppd
->profiles
;
1895 i
< cups
->ppd
->num_profiles
;
1897 if ((strcmp(profile
->resolution
, resolution
) == 0 ||
1898 profile
->resolution
[0] == '-') &&
1899 (strcmp(profile
->media_type
, cups
->header
.MediaType
) == 0 ||
1900 profile
->media_type
[0] == '-'))
1904 * If we found a color profile, use it!
1907 if (i
< cups
->ppd
->num_profiles
)
1910 fputs("DEBUG: Using color profile!\n", stderr
);
1913 cupsHaveProfile
= 1;
1915 d
= profile
->density
;
1918 memcpy(m
, profile
->matrix
, sizeof(m
));
1922 if (cupsHaveProfile
)
1924 for (i
= 0; i
< 3; i
++)
1925 for (j
= 0; j
< 3; j
++)
1926 for (k
= 0; k
<= gx_max_color_value
; k
++)
1928 cupsMatrix
[i
][j
][k
] = (int)((float)k
* m
[i
][j
] + 0.5);
1931 if ((k
& 4095) == 0)
1932 fprintf(stderr
, "DEBUG: cupsMatrix[%d][%d][%d] = %d\n",
1933 i
, j
, k
, cupsMatrix
[i
][j
][k
]);
1938 for (k
= 0; k
<= gx_max_color_value
; k
++)
1940 cupsDensity
[k
] = (int)((float)gx_max_color_value
* d
*
1941 pow((float)k
/ (float)gx_max_color_value
, g
) +
1945 if ((k
& 4095) == 0)
1946 fprintf(stderr
, "DEBUG: cupsDensity[%d] = %d\n", k
, cupsDensity
[k
]);
1954 * 'cups_sync_output()' - Keep the user informed of our status...
1957 private int /* O - Error status */
1958 cups_sync_output(gx_device
*pdev
) /* I - Device info */
1960 fprintf(stderr
, "INFO: Processing page %d...\n", cups
->page
);
1967 * 'cups_print_chunked()' - Print a page of chunked pixels.
1971 cups_print_chunked(gx_device_printer
*pdev
, /* I - Printer device */
1972 unsigned char *src
, /* I - Scanline buffer */
1973 unsigned char *dst
, /* I - Bitmap buffer */
1974 int srcbytes
) /* I - Number of bytes in src */
1976 int y
; /* Looping var */
1977 unsigned char *srcptr
, /* Pointer to data */
1978 *dstptr
; /* Pointer to bits */
1979 int count
; /* Count for loop */
1980 int flip
; /* Flip scanline? */
1983 if (cups
->header
.Duplex
&& !cups
->header
.Tumble
&&
1984 cups
->ppd
&& cups
->ppd
->flip_duplex
&& !(cups
->page
& 1))
1989 fprintf(stderr
, "DEBUG: cups_print_chunked - flip = %d\n", flip
);
1992 * Loop through the page bitmap and write chunked pixels, reversing as
1996 for (y
= 0; y
< cups
->height
; y
++)
1999 * Grab the scanline data...
2002 if (gdev_prn_get_bits((gx_device_printer
*)pdev
, y
, src
, &srcptr
) < 0)
2004 fprintf(stderr
, "ERROR: Unable to get scanline %d!\n", y
);
2011 * Flip the raster data before writing it...
2014 if (srcptr
[0] == 0 && memcmp(srcptr
, srcptr
+ 1, srcbytes
- 1) == 0)
2015 memset(dst
, 0, cups
->header
.cupsBytesPerLine
);
2021 switch (cups
->color_info
.depth
)
2023 case 1 : /* B&W bitmap */
2024 for (srcptr
+= srcbytes
- 1;
2026 count
--, srcptr
--, dstptr
++)
2028 *dstptr
= rev_upper1
[*srcptr
& 15] |
2029 rev_lower1
[*srcptr
>> 4];
2033 case 2 : /* 2-bit grayscale */
2034 for (srcptr
+= srcbytes
- 1;
2036 count
--, srcptr
--, dstptr
++)
2038 *dstptr
= rev_upper2
[*srcptr
& 15] |
2039 rev_lower2
[*srcptr
>> 4];
2043 case 4 : /* 4-bit grayscale, or RGB, CMY, or CMYK bitmap */
2044 for (srcptr
+= srcbytes
- 1;
2046 count
--, srcptr
--, dstptr
++)
2047 *dstptr
= (*srcptr
>> 4) | (*srcptr
<< 4);
2050 case 8 : /* 8-bit grayscale, or 2-bit RGB, CMY, or CMYK image */
2051 for (srcptr
+= srcbytes
- 1;
2053 count
--, srcptr
--, dstptr
++)
2057 case 16 : /* 4-bit RGB, CMY or CMYK image */
2058 for (srcptr
+= srcbytes
- 2;
2060 count
-= 2, srcptr
-= 2, dstptr
+= 2)
2062 dstptr
[0] = srcptr
[0];
2063 dstptr
[1] = srcptr
[1];
2067 case 24 : /* 8-bit RGB or CMY image */
2068 for (srcptr
+= srcbytes
- 3;
2070 count
-= 3, srcptr
-= 3, dstptr
+= 3)
2072 dstptr
[0] = srcptr
[0];
2073 dstptr
[1] = srcptr
[1];
2074 dstptr
[2] = srcptr
[2];
2078 case 32 : /* 4-bit RGB, CMY or CMYK bitmap */
2079 for (srcptr
+= srcbytes
- 4;
2081 count
-= 4, srcptr
-= 4, dstptr
+= 4)
2083 dstptr
[0] = srcptr
[0];
2084 dstptr
[1] = srcptr
[1];
2085 dstptr
[2] = srcptr
[2];
2086 dstptr
[3] = srcptr
[3];
2093 * Write the bitmap data to the raster stream...
2096 cupsRasterWritePixels(cups
->stream
, dst
, cups
->header
.cupsBytesPerLine
);
2101 * Write the scanline data to the raster stream...
2104 cupsRasterWritePixels(cups
->stream
, srcptr
, cups
->header
.cupsBytesPerLine
);
2111 * 'cups_print_banded()' - Print a page of banded pixels.
2115 cups_print_banded(gx_device_printer
*pdev
, /* I - Printer device */
2116 unsigned char *src
, /* I - Scanline buffer */
2117 unsigned char *dst
, /* I - Bitmap buffer */
2118 int srcbytes
) /* I - Number of bytes in src */
2120 int x
; /* Looping var */
2121 int y
; /* Looping var */
2122 int bandbytes
; /* Bytes per band */
2123 unsigned char bit
; /* Current bit */
2124 unsigned char temp
; /* Temporary variable */
2125 unsigned char *srcptr
; /* Pointer to data */
2126 unsigned char *cptr
, *mptr
, *yptr
, *kptr
; /* Pointer to components */
2127 unsigned char *lcptr
, *lmptr
; /* ... */
2128 int flip
; /* Flip scanline? */
2131 if (cups
->header
.Duplex
&& !cups
->header
.Tumble
&&
2132 cups
->ppd
&& cups
->ppd
->flip_duplex
&& !(cups
->page
& 1))
2137 fprintf(stderr
, "DEBUG: cups_print_banded - flip = %d\n", flip
);
2140 * Loop through the page bitmap and write banded pixels... We have
2141 * to separate each chunked color as needed...
2144 bandbytes
= (cups
->header
.cupsWidth
* cups
->header
.cupsBitsPerColor
+ 7) / 8;
2146 for (y
= 0; y
< cups
->height
; y
++)
2149 * Grab the scanline data...
2152 if (gdev_prn_get_bits((gx_device_printer
*)pdev
, y
, src
, &srcptr
) < 0)
2154 fprintf(stderr
, "ERROR: Unable to get scanline %d!\n", y
);
2159 * Separate the chunked colors into their components...
2162 if (srcptr
[0] == 0 && memcmp(srcptr
, srcptr
+ 1, srcbytes
- 1) == 0)
2163 memset(dst
, 0, cups
->header
.cupsBytesPerLine
);
2167 cptr
= dst
+ bandbytes
- 1;
2171 mptr
= cptr
+ bandbytes
;
2172 yptr
= mptr
+ bandbytes
;
2173 kptr
= yptr
+ bandbytes
;
2174 lcptr
= yptr
+ bandbytes
;
2175 lmptr
= lcptr
+ bandbytes
;
2177 switch (cups
->header
.cupsBitsPerColor
)
2180 memset(dst
, 0, cups
->header
.cupsBytesPerLine
);
2182 switch (cups
->header
.cupsColorSpace
)
2185 for (x
= cups
->width
, bit
= flip
? 1 << (x
& 7) : 128;
2245 case CUPS_CSPACE_GMCK
:
2246 case CUPS_CSPACE_GMCS
:
2247 case CUPS_CSPACE_RGBA
:
2248 case CUPS_CSPACE_CMYK
:
2249 case CUPS_CSPACE_YMCK
:
2250 case CUPS_CSPACE_KCMY
:
2251 for (x
= cups
->width
, bit
= flip
? 1 << (x
& 7) : 128;
2318 case CUPS_CSPACE_KCMYcm
:
2319 for (x
= cups
->width
, bit
= flip
? 1 << (x
& 7) : 128;
2324 * Note: Because of the way the pointers are setup,
2325 * the following code is correct even though
2326 * the names don't match...
2375 memset(dst
, 0, cups
->header
.cupsBytesPerLine
);
2377 switch (cups
->header
.cupsColorSpace
)
2380 for (x
= cups
->width
, bit
= flip
? 3 << (2 * (x
& 3)) : 0xc0;
2386 if ((temp
= *srcptr
& 0x30) != 0)
2388 if ((temp
= *srcptr
& 0x0c) != 0)
2390 if ((temp
= *srcptr
& 0x03) != 0)
2404 if ((temp
= *srcptr
& 0x30) != 0)
2406 if ((temp
= *srcptr
& 0x0c) != 0)
2408 if ((temp
= *srcptr
& 0x03) != 0)
2417 if ((temp
= *srcptr
& 0x30) != 0)
2419 if ((temp
= *srcptr
& 0x0c) != 0)
2421 if ((temp
= *srcptr
& 0x03) != 0)
2430 if ((temp
= *srcptr
& 0x30) != 0)
2432 if ((temp
= *srcptr
& 0x0c) != 0)
2434 if ((temp
= *srcptr
& 0x03) != 0)
2449 case CUPS_CSPACE_GMCK
:
2450 case CUPS_CSPACE_GMCS
:
2451 case CUPS_CSPACE_RGBA
:
2452 case CUPS_CSPACE_CMYK
:
2453 case CUPS_CSPACE_YMCK
:
2454 case CUPS_CSPACE_KCMY
:
2455 case CUPS_CSPACE_KCMYcm
:
2456 for (x
= cups
->width
, bit
= flip
? 3 << (2 * (x
& 3)) : 0xc0;
2462 if ((temp
= *srcptr
& 0xc0) != 0)
2464 if ((temp
= *srcptr
& 0x30) != 0)
2466 if ((temp
= *srcptr
& 0x0c) != 0)
2468 if ((temp
= *srcptr
& 0x03) != 0)
2483 if ((temp
= *srcptr
& 0xc0) != 0)
2485 if ((temp
= *srcptr
& 0x30) != 0)
2487 if ((temp
= *srcptr
& 0x0c) != 0)
2489 if ((temp
= *srcptr
& 0x03) != 0)
2498 if ((temp
= *srcptr
& 0xc0) != 0)
2500 if ((temp
= *srcptr
& 0x30) != 0)
2502 if ((temp
= *srcptr
& 0x0c) != 0)
2504 if ((temp
= *srcptr
& 0x03) != 0)
2513 if ((temp
= *srcptr
& 0xc0) != 0)
2515 if ((temp
= *srcptr
& 0x30) != 0)
2517 if ((temp
= *srcptr
& 0x0c) != 0)
2519 if ((temp
= *srcptr
& 0x03) != 0)
2539 memset(dst
, 0, cups
->header
.cupsBytesPerLine
);
2541 switch (cups
->header
.cupsColorSpace
)
2544 for (x
= cups
->width
, bit
= flip
&& (x
& 1) ? 0xf0 : 0x0f;
2550 if ((temp
= srcptr
[0] & 0x0f) != 0)
2552 if ((temp
= srcptr
[1] & 0xf0) != 0)
2554 if ((temp
= srcptr
[1] & 0x0f) != 0)
2567 if ((temp
= srcptr
[0] & 0x0f) != 0)
2569 if ((temp
= srcptr
[1] & 0xf0) != 0)
2571 if ((temp
= srcptr
[1] & 0x0f) != 0)
2585 case CUPS_CSPACE_GMCK
:
2586 case CUPS_CSPACE_GMCS
:
2587 case CUPS_CSPACE_RGBA
:
2588 case CUPS_CSPACE_CMYK
:
2589 case CUPS_CSPACE_YMCK
:
2590 case CUPS_CSPACE_KCMY
:
2591 case CUPS_CSPACE_KCMYcm
:
2592 for (x
= cups
->width
, bit
= flip
&& (x
& 1) ? 0xf0 : 0x0f;
2598 if ((temp
= srcptr
[0] & 0xf0) != 0)
2600 if ((temp
= srcptr
[0] & 0x0f) != 0)
2602 if ((temp
= srcptr
[1] & 0xf0) != 0)
2604 if ((temp
= srcptr
[1] & 0x0f) != 0)
2618 if ((temp
= srcptr
[0] & 0xf0) != 0)
2620 if ((temp
= srcptr
[0] & 0x0f) != 0)
2622 if ((temp
= srcptr
[1] & 0xf0) != 0)
2624 if ((temp
= srcptr
[1] & 0x0f) != 0)
2643 switch (cups
->header
.cupsColorSpace
)
2647 for (x
= cups
->width
; x
> 0; x
--)
2649 *cptr
-- = *srcptr
++;
2650 *mptr
-- = *srcptr
++;
2651 *yptr
-- = *srcptr
++;
2654 for (x
= cups
->width
; x
> 0; x
--)
2656 *cptr
++ = *srcptr
++;
2657 *mptr
++ = *srcptr
++;
2658 *yptr
++ = *srcptr
++;
2661 case CUPS_CSPACE_GMCK
:
2662 case CUPS_CSPACE_GMCS
:
2663 case CUPS_CSPACE_RGBA
:
2664 case CUPS_CSPACE_CMYK
:
2665 case CUPS_CSPACE_YMCK
:
2666 case CUPS_CSPACE_KCMY
:
2667 case CUPS_CSPACE_KCMYcm
:
2669 for (x
= cups
->width
; x
> 0; x
--)
2671 *cptr
-- = *srcptr
++;
2672 *mptr
-- = *srcptr
++;
2673 *yptr
-- = *srcptr
++;
2674 *kptr
-- = *srcptr
++;
2677 for (x
= cups
->width
; x
> 0; x
--)
2679 *cptr
++ = *srcptr
++;
2680 *mptr
++ = *srcptr
++;
2681 *yptr
++ = *srcptr
++;
2682 *kptr
++ = *srcptr
++;
2691 * Write the bitmap data to the raster stream...
2694 cupsRasterWritePixels(cups
->stream
, dst
, cups
->header
.cupsBytesPerLine
);
2700 * 'cups_print_planar()' - Print a page of planar pixels.
2704 cups_print_planar(gx_device_printer
*pdev
, /* I - Printer device */
2705 unsigned char *src
, /* I - Scanline buffer */
2706 unsigned char *dst
, /* I - Bitmap buffer */
2707 int srcbytes
) /* I - Number of bytes in src */
2709 int x
; /* Looping var */
2710 int y
; /* Looping var */
2711 int z
; /* Looping var */
2712 unsigned char srcbit
; /* Current source bit */
2713 unsigned char dstbit
; /* Current destination bit */
2714 unsigned char temp
; /* Temporary variable */
2715 unsigned char *srcptr
; /* Pointer to data */
2716 unsigned char *dstptr
; /* Pointer to bitmap */
2719 /**** NOTE: Currently planar output doesn't support flipped duplex!!! ****/
2722 * Loop through the page bitmap and write planar pixels... We have
2723 * to separate each chunked color as needed...
2726 for (z
= 0; z
< pdev
->color_info
.num_components
; z
++)
2727 for (y
= 0; y
< cups
->height
; y
++)
2730 * Grab the scanline data...
2733 if (gdev_prn_get_bits((gx_device_printer
*)pdev
, y
, src
, &srcptr
) < 0)
2735 fprintf(stderr
, "ERROR: Unable to get scanline %d!\n", y
);
2740 * Pull the individual color planes out of the pixels...
2743 if (srcptr
[0] == 0 && memcmp(srcptr
, srcptr
+ 1, srcbytes
- 1) == 0)
2744 memset(dst
, 0, cups
->header
.cupsBytesPerLine
);
2746 switch (cups
->header
.cupsBitsPerColor
)
2749 memset(dst
, 0, cups
->header
.cupsBytesPerLine
);
2751 switch (cups
->header
.cupsColorSpace
)
2754 for (dstptr
= dst
, x
= cups
->width
, srcbit
= 64 >> z
,
2759 if (*srcptr
& srcbit
)
2779 case CUPS_CSPACE_GMCK
:
2780 case CUPS_CSPACE_GMCS
:
2781 case CUPS_CSPACE_RGBA
:
2782 case CUPS_CSPACE_CMYK
:
2783 case CUPS_CSPACE_YMCK
:
2784 case CUPS_CSPACE_KCMY
:
2785 for (dstptr
= dst
, x
= cups
->width
, srcbit
= 128 >> z
,
2790 if (*srcptr
& srcbit
)
2810 case CUPS_CSPACE_KCMYcm
:
2811 for (dstptr
= dst
, x
= cups
->width
, srcbit
= 32 >> z
,
2816 if (*srcptr
& srcbit
)
2832 memset(dst
, 0, cups
->header
.cupsBytesPerLine
);
2834 switch (cups
->header
.cupsColorSpace
)
2837 for (dstptr
= dst
, x
= cups
->width
, srcbit
= 48 >> (z
* 2),
2842 if ((temp
= *srcptr
& srcbit
) != 0)
2844 if (srcbit
== dstbit
)
2861 *dstptr
|= temp
<< 6;
2864 *dstptr
|= temp
<< 4;
2867 *dstptr
|= temp
<< 2;
2885 case CUPS_CSPACE_GMCK
:
2886 case CUPS_CSPACE_GMCS
:
2887 case CUPS_CSPACE_RGBA
:
2888 case CUPS_CSPACE_CMYK
:
2889 case CUPS_CSPACE_YMCK
:
2890 case CUPS_CSPACE_KCMY
:
2891 case CUPS_CSPACE_KCMYcm
:
2892 for (dstptr
= dst
, x
= cups
->width
, srcbit
= 192 >> (z
* 2),
2897 if ((temp
= *srcptr
& srcbit
) != 0)
2899 if (srcbit
== dstbit
)
2919 *dstptr
|= temp
<< 6;
2922 *dstptr
|= temp
<< 4;
2925 *dstptr
|= temp
<< 2;
2947 memset(dst
, 0, cups
->header
.cupsBytesPerLine
);
2949 switch (cups
->header
.cupsColorSpace
)
2960 for (dstptr
= dst
, x
= cups
->width
, dstbit
= 0xf0;
2964 if ((temp
= *srcptr
& srcbit
) != 0)
2966 if (srcbit
== dstbit
)
2974 *dstptr
|= temp
<< 4;
2989 case CUPS_CSPACE_GMCK
:
2990 case CUPS_CSPACE_GMCS
:
2991 case CUPS_CSPACE_RGBA
:
2992 case CUPS_CSPACE_CMYK
:
2993 case CUPS_CSPACE_YMCK
:
2994 case CUPS_CSPACE_KCMY
:
2995 case CUPS_CSPACE_KCMYcm
:
3004 for (dstptr
= dst
, x
= cups
->width
, dstbit
= 0xf0;
3008 if ((temp
= *srcptr
& srcbit
) != 0)
3010 if (srcbit
== dstbit
)
3018 *dstptr
|= temp
<< 4;
3037 for (srcptr
+= z
, dstptr
= dst
, x
= cups
->header
.cupsBytesPerLine
;
3039 srcptr
+= pdev
->color_info
.num_components
, x
--)
3040 *dstptr
++ = *srcptr
;
3045 * Write the bitmap data to the raster stream...
3048 cupsRasterWritePixels(cups
->stream
, dst
, cups
->header
.cupsBytesPerLine
);
3054 * End of "$Id: gdevcups.c,v 1.48 2002/01/02 17:59:09 mike Exp $".