Coverage Report

Created: 2025-06-24 07:01

/src/ghostpdl/cups/gdevcups.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 *
3
 *   GNU Ghostscript raster output driver for the Common UNIX Printing
4
 *   System (CUPS).
5
 *
6
 *   Copyright 1993-2006 by Easy Software Products.
7
 *
8
 *   These coded instructions, statements, and computer programs are the
9
 *   property of Easy Software Products and are protected by Federal
10
 *   copyright law.  Distribution and use rights are outlined in the file
11
 *   "LICENSE.txt" which should have been included with this file.  If this
12
 *   file is missing or damaged please contact Easy Software Products
13
 *   at:
14
 *
15
 *       Attn: CUPS Licensing Information
16
 *       Easy Software Products
17
 *       44141 Airport View Drive, Suite 204
18
 *       Hollywood, Maryland 20636 USA
19
 *
20
 *       Voice: (301) 373-9600
21
 *       EMail: cups-info@cups.org
22
 *         WWW: http://www.cups.org/
23
 *
24
 *   This code and any derivative of it may be used and distributed
25
 *   freely under the terms of the GNU General Public License when
26
 *   used with GNU Ghostscript or its derivatives.  Use of the code
27
 *   (or any derivative of it) with software other than GNU
28
 *   GhostScript (or its derivatives) is governed by the CUPS license
29
 *   agreement.
30
 *
31
 * Contents:
32
 *
33
 *   cups_close()            - Close the output file.
34
 *   cups_decode_color()     - Decode a color value.
35
 *   cups_encode_color()     - Encode a color value.
36
 *   cups_get_color_comp_index()
37
 *                           - Color component to index
38
 *   cups_get_color_mapping_procs()
39
 *                           - Get the list of color mapping procedures.
40
 *   cups_get_matrix()       - Generate the default page matrix.
41
 *   cups_get_params()       - Get pagedevice parameters.
42
 *   cups_get_space_params() - Get space parameters from the RIP_CACHE env var.
43
 *   cups_map_cielab()       - Map CIE Lab transformation...
44
 *   cups_map_cmyk()         - Map a CMYK color value to device colors.
45
 *   cups_map_gray()         - Map a grayscale value to device colors.
46
 *   cups_map_rgb()          - Map a RGB color value to device colors.
47
 *   cups_map_cmyk_color()   - Map a CMYK color to a color index.
48
 *   cups_map_color_rgb()    - Map a color index to an RGB color.
49
 *   cups_map_rgb_color()    - Map an RGB color to a color index.  We map the
50
 *                             RGB color to the output colorspace & bits (we
51
 *                             figure out the format when we output a page).
52
 *   cups_open()             - Open the output file and initialize things.
53
 *   cups_print_pages()      - Send one or more pages to the output file.
54
 *   cups_put_params()       - Set pagedevice parameters.
55
 *   cups_set_color_info()   - Set the color information structure based on
56
 *                             the required output.
57
 *   cups_sync_output()      - Keep the user informed of our status...
58
 *   cups_print_chunked()    - Print a page of chunked pixels.
59
 *   cups_print_banded()     - Print a page of banded pixels.
60
 *   cups_print_planar()     - Print a page of planar pixels.
61
 */
62
63
/* prevent gp.h redefining fopen */
64
0
#define sprintf sprintf
65
66
/*
67
 * Include necessary headers...
68
 */
69
70
#include "std.h"                /* to stop stdlib.h redefining types */
71
#include "gdevprn.h"
72
#include "gsparam.h"
73
#include "gxdevsop.h"
74
#include "arch.h"
75
#include "gsicc_manage.h"
76
77
#include <stdlib.h>
78
#include <ctype.h>
79
80
#ifdef __GNUC__
81
#pragma GCC diagnostic push
82
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
83
#endif
84
85
/* Recent cups releases on OSX pull in printf in a header file
86
   so we need to allow it. This may well end up being required
87
   on other platforms, too.
88
 */
89
#ifdef __APPLE__
90
#undef printf
91
#define printf printf
92
#endif
93
94
#include <cups/raster.h>
95
#include <cups/ppd.h>
96
#include <math.h>
97
98
/* the extremely noisy DEBUG2 messages are now dependent on CUPS_DEBUG2 */
99
/* this can be enabled during the 'make' or by uncommenting the following */
100
/* #define CUPS_DEBUG2 */
101
102
#undef private
103
#define private
104
105
#ifdef WIN32
106
#define cbrt(arg) pow(arg, 1.0/3)
107
#define strcasecmp _stricmp
108
#define strncasecmp _strnicmp
109
#endif
110
111
/* This should go into gdevprn.h, or, better yet, gdevprn should
112
   acquire an API for changing resolution. */
113
int gdev_prn_maybe_realloc_memory(gx_device_printer *pdev,
114
                                  gdev_space_params *old_space,
115
                                  int old_width, int old_height,
116
                                  bool old_page_uses_transparency);
117
118
/* Strings for cups_put/get_params */
119
static const char * const cups_Integer_strings[] =
120
{
121
  "cupsInteger0",
122
  "cupsInteger1",
123
  "cupsInteger2",
124
  "cupsInteger3",
125
  "cupsInteger4",
126
  "cupsInteger5",
127
  "cupsInteger6",
128
  "cupsInteger7",
129
  "cupsInteger8",
130
  "cupsInteger9",
131
  "cupsInteger10",
132
  "cupsInteger11",
133
  "cupsInteger12",
134
  "cupsInteger13",
135
  "cupsInteger14",
136
  "cupsInteger15",
137
  NULL
138
};
139
140
static const char * const cups_Real_strings[] =
141
{
142
  "cupsReal0",
143
  "cupsReal1",
144
  "cupsReal2",
145
  "cupsReal3",
146
  "cupsReal4",
147
  "cupsReal5",
148
  "cupsReal6",
149
  "cupsReal7",
150
  "cupsReal8",
151
  "cupsReal9",
152
  "cupsReal10",
153
  "cupsReal11",
154
  "cupsReal12",
155
  "cupsReal13",
156
  "cupsReal14",
157
  "cupsReal15",
158
  NULL
159
};
160
161
static const char * const cups_String_strings[] =
162
{
163
  "cupsString0",
164
  "cupsString1",
165
  "cupsString2",
166
  "cupsString3",
167
  "cupsString4",
168
  "cupsString5",
169
  "cupsString6",
170
  "cupsString7",
171
  "cupsString8",
172
  "cupsString9",
173
  "cupsString10",
174
  "cupsString11",
175
  "cupsString12",
176
  "cupsString13",
177
  "cupsString14",
178
  "cupsString15",
179
  NULL
180
};
181
182
/*
183
 * Check if we are compiling against CUPS 1.2.  If so, enable
184
 * certain extended attributes and use a different page header
185
 * structure and write function...
186
 */
187
188
#ifdef CUPS_RASTER_SYNCv1
189
#  define cups_page_header_t cups_page_header2_t
190
33.2k
#  define cupsRasterWriteHeader cupsRasterWriteHeader2
191
#else
192
/* The RGBW, SW, SRGB, and ADOBERGB colorspaces is not defined until
193
   CUPS 1.2... */
194
#  define CUPS_CSPACE_RGBW 17
195
#  define CUPS_CSPACE_SW 18
196
#  define CUPS_CSPACE_SRGB 19
197
#  define CUPS_CSPACE_ADOBERGB 20
198
#endif /* CUPS_RASTER_SYNCv1 */
199
200
#if !defined(CUPS_RASTER_WRITE_PWG)
201
0
    #define CUPS_RASTER_WRITE_PWG 3
202
#endif
203
204
/*
205
 * CIE XYZ color constants...
206
 */
207
208
5.33M
#define D65_X (0.412453 + 0.357580 + 0.180423)
209
15.9M
#define D65_Y (0.212671 + 0.715160 + 0.072169)
210
5.33M
#define D65_Z (0.019334 + 0.119193 + 0.950227)
211
212
213
/*
214
 * Size of a tile in pixels...
215
 */
216
217
0
#define CUPS_TILE_SIZE  256
218
219
220
/*
221
 * Size of profile LUTs...
222
 */
223
224
#ifdef dev_t_proc_encode_color
225
12.6G
#  define CUPS_MAX_VALUE  frac_1
226
#else
227
#  define CUPS_MAX_VALUE  gx_max_color_value
228
#endif /* dev_t_proc_encode_color */
229
230
231
/*
232
 * Macros...
233
 */
234
235
#define x_dpi   (pdev->HWResolution[0])
236
#define y_dpi   (pdev->HWResolution[1])
237
53.3G
#define cups    ((gx_device_cups *)pdev)
238
239
/*
240
 * Macros from <macros.h>; we can't include <macros.h> because it also
241
 * defines DEBUG, one of our flags to insert various debugging code.
242
 */
243
244
#ifndef max
245
#  define max(a,b)  ((a)<(b) ? (b) : (a))
246
#endif /* !max */
247
248
#ifndef min
249
#  define min(a,b)  ((a)>(b) ? (b) : (a))
250
#endif /* !min */
251
252
#ifndef abs
253
#  define abs(x)  ((x)>=0 ? (x) : -(x))
254
#endif /* !abs */
255
256
257
/*
258
 * Procedures
259
 */
260
261
private dev_proc_close_device(cups_close);
262
private dev_proc_get_initial_matrix(cups_get_matrix);
263
private int cups_get_params(gx_device *, gs_param_list *);
264
private dev_proc_open_device(cups_open);
265
private dev_proc_output_page(cups_output_page);
266
private int cups_print_pages(gx_device_printer *, gp_file *, int);
267
private int cups_put_params(gx_device *, gs_param_list *);
268
private int cups_set_color_info(gx_device *);
269
private dev_proc_sync_output(cups_sync_output);
270
private prn_dev_proc_get_space_params(cups_get_space_params);
271
private int cups_spec_op(gx_device *dev_, int op, void *data, int datasize);
272
273
#ifdef dev_t_proc_encode_color
274
private cm_map_proc_gray(cups_map_gray);
275
private cm_map_proc_rgb(cups_map_rgb);
276
private cm_map_proc_cmyk(cups_map_cmyk);
277
private dev_proc_decode_color(cups_decode_color);
278
private dev_proc_encode_color(cups_encode_color);
279
private dev_proc_get_color_comp_index(cups_get_color_comp_index);
280
private dev_proc_get_color_mapping_procs(cups_get_color_mapping_procs);
281
282
static const gx_cm_color_map_procs cups_color_mapping_procs =
283
{
284
  cups_map_gray,
285
  cups_map_rgb,
286
  cups_map_cmyk
287
};
288
#else
289
private dev_proc_map_cmyk_color(cups_map_cmyk_color);
290
private dev_proc_map_color_rgb(cups_map_color_rgb);
291
private dev_proc_map_rgb_color(cups_map_rgb_color);
292
#endif /* dev_t_proc_encode_color */
293
294
295
/*
296
 * The device descriptors...
297
 */
298
299
typedef struct gx_device_cups_s
300
{
301
  gx_device_common;     /* Standard GhostScript device stuff */
302
  gx_prn_device_common;     /* Standard printer device stuff */
303
  int     page;   /* Page number */
304
  cups_raster_t   *stream;  /* Raster stream */
305
  cups_page_header_t  header;   /* PostScript page device info */
306
  int     landscape;  /* Non-zero if this is landscape */
307
  int     lastpage;
308
  int     HaveProfile;  /* Has a color profile been defined? */
309
  char      *Profile; /* Current simple color profile string */
310
  ppd_file_t    *PPD;   /* PPD file for this device */
311
  unsigned char   RevLower1[16];  /* Lower 1-bit reversal table */
312
  unsigned char   RevUpper1[16];  /* Upper 1-bit reversal table */
313
  unsigned char   RevLower2[16];  /* Lower 2-bit reversal table */
314
  unsigned char   RevUpper2[16];  /* Upper 2-bit reversal table */
315
#ifdef GX_COLOR_INDEX_TYPE
316
  gx_color_value  DecodeLUT[65536];/* Output color to RGB value LUT */
317
#else
318
  gx_color_value  DecodeLUT[256]; /* Output color to RGB value LUT */
319
#endif /* GX_COLOR_INDEX_TYPE */
320
  unsigned short  EncodeLUT[gx_max_color_value + 1];/* RGB value to output color LUT */
321
  int     Density[CUPS_MAX_VALUE + 1];/* Density LUT */
322
  int     Matrix[3][3][CUPS_MAX_VALUE + 1];/* Color transform matrix LUT */
323
  int                   user_icc;
324
  int                   cupsRasterVersion;
325
  char                  cupsBackSideOrientation[64];
326
  int                   cupsBackSideFlipMargins;
327
  int                   cupsManualCopies;
328
  char                  pageSizeRequested[64];
329
330
  /* Used by cups_put_params(): */
331
} gx_device_cups;
332
333
static void
334
cups_initialize_device_procs(gx_device *dev)
335
39.2k
{
336
39.2k
    set_dev_proc(dev, open_device, cups_open);
337
39.2k
    set_dev_proc(dev, get_initial_matrix, cups_get_matrix);
338
39.2k
    set_dev_proc(dev, sync_output, cups_sync_output);
339
39.2k
    set_dev_proc(dev, output_page, cups_output_page);
340
39.2k
    set_dev_proc(dev, close_device, cups_close);
341
39.2k
#ifdef dev_t_proc_encode_color
342
39.2k
    set_dev_proc(dev, get_color_mapping_procs, cups_get_color_mapping_procs);
343
39.2k
    set_dev_proc(dev, get_color_comp_index, cups_get_color_comp_index);
344
39.2k
    set_dev_proc(dev, encode_color, cups_encode_color);
345
39.2k
    set_dev_proc(dev, decode_color, cups_decode_color);
346
#else
347
    set_dev_proc(dev, map_rgb_color, cups_map_rgb_color);
348
    set_dev_proc(dev, map_color_rgb, cups_map_color_rgb);
349
    set_dev_proc(dev, map_cmyk_color, cups_map_cmyk_color);
350
#endif
351
39.2k
    set_dev_proc(dev, get_params, cups_get_params);
352
39.2k
    set_dev_proc(dev, put_params, cups_put_params);
353
39.2k
    set_dev_proc(dev, get_page_device, gx_page_device_get_page_device);
354
39.2k
    set_dev_proc(dev, dev_spec_op, cups_spec_op);
355
39.2k
}
356
357
#define prn_device_body_copies(dtype, init, dname, w10, h10, xdpi, ydpi, lo, to, lm, bm, rm, tm, ncomp, depth, mg, mc, dg, dc, print_pages)\
358
  std_device_full_body_type(dtype, init, dname, &st_device_printer,\
359
    (int)((long)(w10) * (xdpi) / 10),\
360
    (int)((long)(h10) * (ydpi) / 10),\
361
    xdpi, ydpi,\
362
    ncomp, depth, mg, mc, dg, dc,\
363
    -(lo) * (xdpi), -(to) * (ydpi),\
364
    (lm) * 72.0, (bm) * 72.0,\
365
    (rm) * 72.0, (tm) * 72.0\
366
  ),\
367
  prn_device_body_copies_rest_(print_pages)
368
369
370
371
#ifdef CUPS_RASTER_SYNCv1
372
#define RASTER_SYNCv1_ENTRIES \
373
    ,\
374
    1,                                  /* cupsNumColors */\
375
    1.0,                                /* cupsBorderlessScalingFactor */\
376
    { 612.0, 792.0 },                   /* cupsPageSize */\
377
    { 0.0, 0.0, 612.0, 792.0 },         /* cupsImagingBBox */\
378
    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* cupsInteger */\
379
    { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,\
380
      0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }, /* cupsReal */\
381
    { "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" },\
382
                                        /* cupsString */\
383
    "",                                 /* cupsMarkerType */\
384
    "",                                 /* cupsRenderingIntent */\
385
    ""                                  /* cupsPageSizeName */
386
#else
387
#define RASTER_SYNCv1_ENTRIES
388
#endif /* CUPS_RASTER_SYNCv1 */
389
390
#define gs_xxx_device(dname, mediaclass)\
391
  prn_device_body_copies(gx_device_cups,/* type */\
392
                         cups_initialize_device_procs,/* init */\
393
       dname,   /* device name */\
394
       85,    /* initial width */\
395
       110,   /* initial height */\
396
       100,   /* initial x resolution */\
397
       100,   /* initial y resolution */\
398
                         0,   /* initial left offset */\
399
       0,   /* initial top offset */\
400
       0,   /* initial left margin */\
401
       0,   /* initial bottom margin */\
402
       0,   /* initial right margin */\
403
       0,   /* initial top margin */\
404
       1,   /* number of color components */\
405
       1,   /* number of color bits */\
406
       1,   /* maximum gray value */\
407
       0,   /* maximum color value */\
408
       2,   /* number of gray values */\
409
       0,   /* number of color values */\
410
       cups_print_pages),\
411
          /* print procedure */\
412
  0,          /* page */\
413
  NULL,         /* stream */\
414
  {         /* header */\
415
    mediaclass,       /* MediaClass */\
416
    "",         /* MediaColor */\
417
    "",         /* MediaType */\
418
    "",         /* OutputType */\
419
    0,          /* AdvanceDistance */\
420
    CUPS_ADVANCE_NONE,      /* AdvanceMedia */\
421
    CUPS_FALSE,       /* Collate */\
422
    CUPS_CUT_NONE,      /* CutMedia */\
423
    CUPS_FALSE,       /* Duplex */\
424
    { 100, 100 },     /* HWResolution */\
425
    { 0, 0, 612, 792 },     /* ImagingBoundingBox */\
426
    CUPS_FALSE,       /* InsertSheet */\
427
    CUPS_JOG_NONE,      /* Jog */\
428
    CUPS_EDGE_TOP,      /* LeadingEdge */\
429
    { 0, 0 },       /* Margins */\
430
    CUPS_FALSE,       /* ManualFeed */\
431
    0,          /* MediaPosition */\
432
    0,          /* MediaWeight */\
433
    CUPS_FALSE,       /* MirrorPrint */\
434
    CUPS_FALSE,       /* NegativePrint */\
435
    1,          /* NumCopies */\
436
    CUPS_ORIENT_0,      /* Orientation */\
437
    CUPS_FALSE,       /* OutputFaceUp */\
438
    { 612, 792 },     /* PageSize */\
439
    CUPS_FALSE,       /* Separations */\
440
    CUPS_FALSE,       /* TraySwitch */\
441
    CUPS_FALSE,       /* Tumble */\
442
    850,        /* cupsWidth */\
443
    1100,       /* cupsHeight */\
444
    0,          /* cupsMediaType */\
445
    1,          /* cupsBitsPerColor */\
446
    1,          /* cupsBitsPerPixel */\
447
    107,        /* cupsBytesPerLine */\
448
    CUPS_ORDER_CHUNKED,     /* cupsColorOrder */\
449
    CUPS_CSPACE_K,      /* cupsColorSpace */\
450
    0,          /* cupsCompression */\
451
    0,          /* cupsRowCount */\
452
    0,          /* cupsRowFeed */\
453
    0         /* cupsRowStep */\
454
    RASTER_SYNCv1_ENTRIES, /* See above */\
455
  },\
456
  0,                                    /* landscape */\
457
  0,                                    /* lastpage */\
458
  0,                                    /* HaveProfile */\
459
  NULL,                                 /* Profile */\
460
  NULL,                                 /* PPD */\
461
  { 0x00, 0x08, 0x04, 0x0c, 0x02, 0x0a, 0x06, 0x0e,\
462
    0x01, 0x09, 0x05, 0x0d, 0x03, 0x0b, 0x07, 0x0f },/* RevLower1 */\
463
  { 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,\
464
    0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0 },/* RevUpper1 */\
465
  { 0x00, 0x04, 0x08, 0x0c, 0x01, 0x05, 0x09, 0x0d,\
466
    0x02, 0x06, 0x0a, 0x0e, 0x03, 0x07, 0x0b, 0x0f },/* RevLower2 */\
467
  { 0x00, 0x40, 0x80, 0xc0, 0x10, 0x50, 0x90, 0xd0,\
468
    0x20, 0x60, 0xa0, 0xe0, 0x30, 0x70, 0xb0, 0xf0 },/* RevUpper2 */\
469
  {0x00},                                  /* DecodeLUT */\
470
  {0x00},                                  /* EncodeLUT */\
471
  {0x00},                                  /* Density */\
472
  {{{0x00},{0x00},{0x00}},\
473
   {{0x00},{0x00},{0x00}},\
474
   {{0x00},{0x00},{0x00}}},                /* Matrix */\
475
  0,                                       /* user_icc */\
476
  3,                                     /* cupsRasterVersion */\
477
  "Normal",                                /* cupsBackSideOrientation */\
478
  0,                                       /* cupsBackSideFlipMargins */\
479
  0,                                       /* cupsManualCopies */\
480
  ""                                     /* pageSizeRequested */
481
482
gx_device_cups  gs_cups_device = { gs_xxx_device("cups", "") };
483
gx_device_cups  gs_pwgraster_device = { gs_xxx_device("pwgraster",
484
                  "PwgRaster") };
485
#if defined(CUPS_RASTER_HAVE_APPLERASTER)
486
gx_device_cups  gs_appleraster_device = { gs_xxx_device("appleraster",
487
              "PwgRaster") };
488
gx_device_cups  gs_urf_device = { gs_xxx_device("urf",
489
            "PwgRaster") };
490
#endif
491
492
/*
493
 * Local functions...
494
 */
495
496
static double cups_map_cielab(double, double);
497
static int  cups_print_chunked(gx_device_printer *, unsigned char *,
498
                       unsigned char *, int);
499
static int  cups_print_banded(gx_device_printer *, unsigned char *,
500
                      unsigned char *, int);
501
static int  cups_print_planar(gx_device_printer *, unsigned char *,
502
                      unsigned char *, int);
503
504
/*static void cups_set_margins(gx_device *);*/
505
506
507
/*
508
 * 'cups_close()' - Close the output file.
509
 */
510
511
private int
512
cups_close(gx_device *pdev)   /* I - Device info */
513
39.2k
{
514
#ifdef CUPS_DEBUG2
515
  dmprintf1(pdev->memory, "DEBUG2: cups_close(%p)\n", pdev);
516
#endif /* CUPS_DEBUG2 */
517
518
39.2k
  dmprintf(pdev->memory, "INFO: Rendering completed\n");
519
520
39.2k
  if (cups->stream != NULL)
521
19.1k
  {
522
19.1k
    cupsRasterClose(cups->stream);
523
19.1k
    cups->stream = NULL;
524
19.1k
  }
525
526
#if 0 /* Can't do this here because put_params() might close the device */
527
  if (cups->PPD != NULL)
528
  {
529
    ppdClose(cups->PPD);
530
    cups->PPD = NULL;
531
  }
532
533
  if (cups->Profile != NULL)
534
  {
535
    free(cups->Profile);
536
    cups->Profile = NULL;
537
  }
538
#endif /* 0 */
539
540
39.2k
  return (gdev_prn_close(pdev));
541
39.2k
}
542
543
544
#ifdef dev_t_proc_encode_color
545
/*
546
 * 'cups_decode_color()' - Decode a color value.
547
 */
548
549
private int       /* O - Status (0 = OK) */
550
cups_decode_color(gx_device      *pdev, /* I - Device info */
551
                  gx_color_index ci,  /* I - Color index */
552
                  gx_color_value *cv) /* O - Colors */
553
0
{
554
0
  int     i;    /* Looping var */
555
0
  int     shift;    /* Bits to shift */
556
0
  int     mask;   /* Bits to mask */
557
558
559
0
  if (cups->header.cupsColorSpace == CUPS_CSPACE_KCMYcm &&
560
0
      cups->header.cupsBitsPerColor == 1)
561
0
  {
562
   /*
563
    * KCMYcm data is represented internally by Ghostscript as CMYK...
564
    */
565
566
0
    cv[0] = (ci & 0x20) ? frac_1 : frac_0;
567
0
    cv[1] = (ci & 0x12) ? frac_1 : frac_0;
568
0
    cv[2] = (ci & 0x09) ? frac_1 : frac_0;
569
0
    cv[3] = (ci & 0x04) ? frac_1 : frac_0;
570
0
  }
571
0
  else
572
0
  {
573
0
    shift = cups->header.cupsBitsPerColor;
574
0
    mask  = (1 << shift) - 1;
575
576
0
    for (i = cups->color_info.num_components - 1; i > 0; i --, ci >>= shift)
577
0
      cv[i] = cups->DecodeLUT[ci & mask];
578
579
0
    cv[0] = cups->DecodeLUT[ci & mask];
580
0
  }
581
582
0
  return (0);
583
0
}
584
585
586
/*
587
 * 'cups_encode_color()' - Encode a color value.
588
 */
589
590
private gx_color_index      /* O - Color index */
591
cups_encode_color(gx_device            *pdev,
592
          /* I - Device info */
593
                  const gx_color_value *cv)
594
          /* I - Colors */
595
1.36G
{
596
1.36G
  int     i;    /* Looping var */
597
1.36G
  gx_color_index  ci;   /* Color index */
598
1.36G
  int     shift;    /* Bits to shift */
599
600
601
 /*
602
  * Encode the color index...
603
  */
604
605
1.36G
  shift = cups->header.cupsBitsPerColor;
606
607
1.36G
  for (ci = cups->EncodeLUT[cv[0]], i = 1;
608
4.09G
       i < cups->color_info.num_components;
609
2.72G
       i ++)
610
2.72G
    ci = (ci << shift) | cups->EncodeLUT[cv[i]];
611
612
#ifdef CUPS_DEBUG2
613
  dmprintf2(pdev->memory, "DEBUG2: cv[0]=%d -> %llx\n", cv[0], ci);
614
#endif /* CUPS_DEBUG2 */
615
616
 /*
617
  * Handle 6-color output...
618
  */
619
620
1.36G
  if (cups->header.cupsColorSpace == CUPS_CSPACE_KCMYcm &&
621
1.36G
      cups->header.cupsBitsPerColor == 1)
622
27.8k
  {
623
   /*
624
    * Welcome to hackville, where we map CMYK data to the
625
    * light inks in draft mode...  Map blue to light magenta and
626
    * cyan and green to light cyan and yellow...
627
    */
628
629
27.8k
    ci <<= 2;       /* Leave room for light inks */
630
631
27.8k
    if (ci == 0x18)      /* Blue */
632
36
      ci = 0x11;      /* == cyan + light magenta */
633
27.8k
    else if (ci == 0x14)    /* Green */
634
20
      ci = 0x06;     /* == light cyan + yellow */
635
27.8k
  }
636
637
  /* The entire manner that cups does its color mapping needs some serious
638
     rework.  In the case of the output RGBW color space, it takes a source
639
     CMYK value which gs maps to RGB, cups then maps the RGB to CMYK and then
640
     from there to RGBW and finally it does an encode.  Unfortunately, the
641
     number of color values for RGBW is 3 since it is using an RGB ICC profile
642
     this means that the W mapping value from cups is lost in cmap_rgb_direct
643
     So here we ensure that the W is always set to on (else we end up with a
644
     blue background cast).  The ideal way
645
     to fix this is to move some of these odd color spaces of cups to the
646
     separation device model ensuring that things are handled properly. */
647
1.36G
  if (cups->header.cupsColorSpace == CUPS_CSPACE_RGBW) {
648
10.4k
      ci = (ci << shift) | cups->EncodeLUT[gx_max_color_value];
649
10.4k
  }
650
651
 /*
652
  * Range check the return value...
653
  */
654
655
1.36G
  if (ci == gx_no_color_index)
656
0
    ci --;
657
658
 /*
659
  * Return the color index...
660
  */
661
662
1.36G
  return (ci);
663
1.36G
}
664
665
/*
666
 * 'cups_get_color_comp_index()' - Color component to index
667
 */
668
669
#define compare_color_names(pname, name_size, name_str) \
670
7.06M
    (name_size == (int)strlen(name_str) && strncasecmp(pname, name_str, name_size) == 0)
671
672
int                                     /* O - Index of the named color in
673
             the color space */
674
cups_get_color_comp_index(gx_device * pdev, const char * pname,
675
        int name_size, int component_type)
676
1.50M
{
677
1.50M
  switch (cups->header.cupsColorSpace)
678
1.50M
  {
679
7.39k
    case CUPS_CSPACE_K :
680
7.39k
        if (compare_color_names(pname, name_size, "Black") ||
681
7.39k
      compare_color_names(pname, name_size, "Gray") ||
682
7.39k
      compare_color_names(pname, name_size, "Grey"))
683
1.05k
      return 0;
684
6.33k
  else
685
6.33k
      return -1; /* Indicate that the component name is "unknown" */
686
0
        break;
687
129k
    case CUPS_CSPACE_W :
688
135k
    case CUPS_CSPACE_SW :
689
163k
    case CUPS_CSPACE_WHITE :
690
163k
        if (compare_color_names(pname, name_size, "White") ||
691
163k
      compare_color_names(pname, name_size, "Luminance") ||
692
163k
      compare_color_names(pname, name_size, "Gray") ||
693
163k
      compare_color_names(pname, name_size, "Grey"))
694
23.4k
      return 0;
695
140k
  else
696
140k
      return -1;
697
0
        break;
698
7.31k
    case CUPS_CSPACE_RGBA :
699
7.31k
        if (compare_color_names(pname, name_size, "Alpha") ||
700
7.31k
      compare_color_names(pname, name_size, "Transparent") ||
701
7.31k
      compare_color_names(pname, name_size, "Transparency"))
702
0
      return 3;
703
        /* fall through */
704
22.1k
    case CUPS_CSPACE_RGBW :
705
22.1k
        if (compare_color_names(pname, name_size, "Red"))
706
4.42k
      return 0;
707
17.6k
  if (compare_color_names(pname, name_size, "Green"))
708
4.42k
      return 1;
709
13.2k
  if (compare_color_names(pname, name_size, "Blue"))
710
4.42k
            return 2;
711
8.84k
  if (compare_color_names(pname, name_size, "White"))
712
0
            return 3;
713
8.84k
  else
714
8.84k
      return -1;
715
0
        break;
716
528k
    case CUPS_CSPACE_RGB :
717
531k
    case CUPS_CSPACE_SRGB :
718
574k
    case CUPS_CSPACE_ADOBERGB :
719
574k
        if (compare_color_names(pname, name_size, "Red"))
720
112k
      return 0;
721
461k
  if (compare_color_names(pname, name_size, "Green"))
722
112k
      return 1;
723
348k
  if (compare_color_names(pname, name_size, "Blue"))
724
112k
            return 2;
725
235k
        break;
726
235k
    case CUPS_CSPACE_CMYK :
727
43.0k
#  ifdef CUPS_RASTER_HAVE_COLORIMETRIC
728
43.0k
    case CUPS_CSPACE_CIEXYZ :
729
43.0k
    case CUPS_CSPACE_CIELab :
730
43.0k
    case CUPS_CSPACE_ICC1 :
731
43.0k
    case CUPS_CSPACE_ICC2 :
732
43.0k
    case CUPS_CSPACE_ICC3 :
733
43.0k
    case CUPS_CSPACE_ICC4 :
734
43.0k
    case CUPS_CSPACE_ICC5 :
735
43.0k
    case CUPS_CSPACE_ICC6 :
736
43.0k
    case CUPS_CSPACE_ICC7 :
737
43.0k
    case CUPS_CSPACE_ICC8 :
738
43.0k
    case CUPS_CSPACE_ICC9 :
739
43.0k
    case CUPS_CSPACE_ICCA :
740
43.0k
    case CUPS_CSPACE_ICCB :
741
43.0k
    case CUPS_CSPACE_ICCC :
742
43.0k
    case CUPS_CSPACE_ICCD :
743
43.0k
    case CUPS_CSPACE_ICCE :
744
43.0k
    case CUPS_CSPACE_ICCF :
745
43.0k
#  endif /* CUPS_RASTER_HAVE_COLORIMETRIC */
746
43.0k
        if (compare_color_names(pname, name_size, "Black"))
747
15.3k
      return 3;
748
        /* fall through */
749
32.9k
    case CUPS_CSPACE_CMY :
750
32.9k
        if (compare_color_names(pname, name_size, "Cyan"))
751
5.18k
      return 0;
752
27.7k
  if (compare_color_names(pname, name_size, "Magenta"))
753
5.18k
      return 1;
754
22.5k
  if (compare_color_names(pname, name_size, "Yellow"))
755
5.18k
      return 2;
756
17.3k
  else
757
17.3k
      return -1;
758
0
        break;
759
120k
    case CUPS_CSPACE_GMCS :
760
120k
        if (compare_color_names(pname, name_size, "Silver") ||
761
120k
      compare_color_names(pname, name_size, "Silver Foil"))
762
0
      return 3;
763
        /* fall through */
764
406k
    case CUPS_CSPACE_GMCK :
765
406k
        if (compare_color_names(pname, name_size, "Gold") ||
766
406k
      compare_color_names(pname, name_size, "Gold Foil"))
767
0
      return 0;
768
        /* fall through */
769
430k
    case CUPS_CSPACE_YMCK :
770
430k
        if (compare_color_names(pname, name_size, "Black"))
771
146k
      return 3;
772
        /* fall through */
773
287k
    case CUPS_CSPACE_YMC :
774
287k
  if (compare_color_names(pname, name_size, "Yellow"))
775
60.3k
      return 0;
776
226k
  if (compare_color_names(pname, name_size, "Magenta"))
777
60.3k
      return 1;
778
166k
        if (compare_color_names(pname, name_size, "Cyan"))
779
60.3k
      return 2;
780
105k
  else
781
105k
      return -1;
782
0
        break;
783
152k
    case CUPS_CSPACE_KCMYcm :
784
152k
        if (compare_color_names(pname, name_size, "Light Cyan") ||
785
152k
      compare_color_names(pname, name_size, "Photo Cyan"))
786
0
      return 4;
787
152k
        if (compare_color_names(pname, name_size, "Light Magenta") ||
788
152k
      compare_color_names(pname, name_size, "Photo Magenta"))
789
0
      return 5;
790
192k
    case CUPS_CSPACE_KCMY :
791
192k
        if (compare_color_names(pname, name_size, "Black"))
792
64.3k
      return 0;
793
128k
        if (compare_color_names(pname, name_size, "Cyan"))
794
28.0k
      return 1;
795
100k
  if (compare_color_names(pname, name_size, "Magenta"))
796
28.0k
      return 2;
797
72.3k
  if (compare_color_names(pname, name_size, "Yellow"))
798
28.0k
      return 3;
799
44.2k
  else
800
44.2k
      return -1;
801
0
        break;
802
41.3k
    case CUPS_CSPACE_GOLD :
803
41.3k
        if (compare_color_names(pname, name_size, "Gold") ||
804
41.3k
      compare_color_names(pname, name_size, "Gold Foil"))
805
0
      return 0;
806
41.3k
  else
807
41.3k
      return -1;
808
0
        break;
809
24.4k
    case CUPS_CSPACE_SILVER :
810
24.4k
        if (compare_color_names(pname, name_size, "Silver") ||
811
24.4k
      compare_color_names(pname, name_size, "Silver Foil"))
812
0
      return 0;
813
24.4k
  else
814
24.4k
      return -1;
815
0
        break;
816
0
    default:
817
0
        break;
818
1.50M
  }
819
235k
  return -1;
820
1.50M
}
821
822
/*
823
 * 'cups_get_color_mapping_procs()' - Get the list of color mapping procedures.
824
 */
825
826
private const gx_cm_color_map_procs * /* O - List of device procedures */
827
cups_get_color_mapping_procs(const gx_device *pdev, const gx_device **tdev)
828
          /* I - Device info */
829
258M
{
830
258M
  *tdev = pdev;
831
258M
  return (&cups_color_mapping_procs);
832
258M
}
833
#endif /* dev_t_proc_encode_color */
834
835
836
/*
837
 * 'cups_get_matrix()' - Generate the default page matrix.
838
 */
839
840
private void
841
cups_get_matrix(gx_device *pdev,  /* I - Device info */
842
                gs_matrix *pmat)  /* O - Physical transform matrix */
843
82.4M
{
844
#ifdef CUPS_DEBUG2
845
  dmprintf2(pdev->memory, "DEBUG2: cups_get_matrix(%p, %p)\n", pdev, pmat);
846
#endif /* CUPS_DEBUG2 */
847
848
 /*
849
  * Set the raster width and height...
850
  */
851
852
82.4M
  cups->header.cupsWidth  = cups->width;
853
82.4M
  cups->header.cupsHeight = cups->height;
854
855
 /*
856
  * Set the transform matrix...
857
  */
858
859
82.4M
  if (cups->landscape)
860
0
  {
861
   /*
862
    * Do landscape orientation...
863
    */
864
#ifdef CUPS_DEBUG2
865
    dprintf("DEBUG2: Landscape matrix: XX=0 XY=+1 YX=+1 YY=0\n");
866
#endif /* CUPS_DEBUG2 */
867
0
    pmat->xx = 0.0;
868
0
    pmat->xy = (float)cups->header.HWResolution[1] / 72.0;
869
0
    pmat->yx = (float)cups->header.HWResolution[0] / 72.0;
870
0
    pmat->yy = 0.0;
871
0
    pmat->tx = -(float)cups->header.HWResolution[0] * pdev->HWMargins[1] / 72.0;
872
0
    pmat->ty = -(float)cups->header.HWResolution[1] * pdev->HWMargins[0] / 72.0;
873
0
  }
874
82.4M
  else
875
82.4M
  {
876
   /*
877
    * Do portrait orientation...
878
    */
879
#ifdef CUPS_DEBUG2
880
    dmprintf(pdev->memory, "DEBUG2: Portrait matrix: XX=+1 XY=0 YX=0 YY=-1\n");
881
#endif /* CUPS_DEBUG2 */
882
82.4M
    pmat->xx = (float)cups->header.HWResolution[0] / 72.0;
883
82.4M
    pmat->xy = 0.0;
884
82.4M
    pmat->yx = 0.0;
885
82.4M
    pmat->yy = -(float)cups->header.HWResolution[1] / 72.0;
886
82.4M
    pmat->tx = -(float)cups->header.HWResolution[0] * pdev->HWMargins[0] / 72.0;
887
82.4M
    pmat->ty = (float)cups->header.HWResolution[1] *
888
82.4M
               ((float)cups->header.PageSize[1] - pdev->HWMargins[3]) / 72.0;
889
82.4M
  }
890
891
82.4M
#ifdef CUPS_RASTER_SYNCv1
892
82.4M
  if (cups->header.cupsBorderlessScalingFactor > 1.0)
893
0
  {
894
0
    pmat->xx *= cups->header.cupsBorderlessScalingFactor;
895
0
    pmat->xy *= cups->header.cupsBorderlessScalingFactor;
896
0
    pmat->yx *= cups->header.cupsBorderlessScalingFactor;
897
0
    pmat->yy *= cups->header.cupsBorderlessScalingFactor;
898
0
    pmat->tx *= cups->header.cupsBorderlessScalingFactor;
899
0
    pmat->ty *= cups->header.cupsBorderlessScalingFactor;
900
0
  }
901
82.4M
#endif /* CUPS_RASTER_SYNCv1 */
902
903
#ifdef CUPS_DEBUG2
904
  dmprintf2(pdev->memory, "DEBUG2: width = %d, height = %d\n", cups->header.cupsWidth,
905
            cups->header.cupsHeight);
906
  dmprintf4(pdev->memory, "DEBUG2: PageSize = [ %d %d ], HWResolution = [ %d %d ]\n",
907
            cups->header.PageSize[0], cups->header.PageSize[1],
908
            cups->header.HWResolution[0], cups->header.HWResolution[1]);
909
  dmprintf4(pdev->memory, "DEBUG2: HWMargins = [ %.3f %.3f %.3f %.3f ]\n",
910
            pdev->HWMargins[0], pdev->HWMargins[1], pdev->HWMargins[2],
911
            pdev->HWMargins[3]);
912
  dmprintf6(pdev->memory, "DEBUG2: matrix = [ %.3f %.3f %.3f %.3f %.3f %.3f ]\n",
913
            pmat->xx, pmat->xy, pmat->yx, pmat->yy, pmat->tx, pmat->ty);
914
#endif /* CUPS_DEBUG2 */
915
82.4M
}
916
917
918
/*
919
 * 'cups_get_params()' - Get pagedevice parameters.
920
 */
921
922
private int       /* O - Error status */
923
cups_get_params(gx_device     *pdev,  /* I - Device info */
924
                gs_param_list *plist) /* I - Parameter list */
925
1.19M
{
926
1.19M
  int     code;   /* Return code */
927
1.19M
  gs_param_string s;    /* Temporary string value */
928
1.19M
  bool      b;    /* Temporary boolean value */
929
1.19M
#ifdef CUPS_RASTER_SYNCv1
930
1.19M
  int     i;    /* Looping var */
931
1.19M
#endif /* CUPS_RASTER_SYNCv1 */
932
933
934
#ifdef CUPS_DEBUG2
935
  dmprintf2(pdev->memory, "DEBUG2: cups_get_params(%p, %p)\n", pdev, plist);
936
#endif /* CUPS_DEBUG2 */
937
938
 /*
939
  * First process the "standard" page device parameters...
940
  */
941
942
#ifdef CUPS_DEBUG2
943
  dmprintf(pdev->memory, "DEBUG2: before gdev_prn_get_params()\n");
944
#endif /* CUPS_DEBUG2 */
945
946
1.19M
  if ((code = gdev_prn_get_params(pdev, plist)) < 0)
947
0
    goto done;
948
949
#ifdef CUPS_DEBUG2
950
  dmprintf(pdev->memory, "DEBUG2: after gdev_prn_get_params()\n");
951
#endif /* CUPS_DEBUG2 */
952
953
 /*
954
  * Then write the CUPS parameters...
955
  */
956
957
1.19M
  param_string_from_transient_string(s, cups->header.MediaClass);
958
1.19M
  if ((code = param_write_string(plist, "MediaClass", &s)) < 0)
959
0
    goto done;
960
961
1.19M
  param_string_from_transient_string(s, cups->header.MediaColor);
962
1.19M
  if ((code = param_write_string(plist, "MediaColor", &s)) < 0)
963
0
    goto done;
964
965
1.19M
  param_string_from_transient_string(s, cups->header.MediaType);
966
1.19M
  if ((code = param_write_string(plist, "MediaType", &s)) < 0)
967
0
    goto done;
968
969
1.19M
  param_string_from_transient_string(s, cups->header.OutputType);
970
1.19M
  if ((code = param_write_string(plist, "OutputType", &s)) < 0)
971
0
    goto done;
972
973
1.19M
  if ((code = param_write_int(plist, "AdvanceDistance",
974
1.19M
                              (int *)&(cups->header.AdvanceDistance))) < 0)
975
0
    goto done;
976
977
1.19M
  if ((code = param_write_int(plist, "AdvanceMedia",
978
1.19M
                              (int *)&(cups->header.AdvanceMedia))) < 0)
979
0
    goto done;
980
981
1.19M
  b = cups->header.Collate;
982
1.19M
  if ((code = param_write_bool(plist, "Collate", &b)) < 0)
983
0
    goto done;
984
985
1.19M
  if ((code = param_write_int(plist, "CutMedia",
986
1.19M
                              (int *)&(cups->header.CutMedia))) < 0)
987
0
    goto done;
988
989
1.19M
  b = cups->header.Duplex;
990
1.19M
  if ((code = param_write_bool(plist, "Duplex", &b)) < 0)
991
0
    goto done;
992
993
1.19M
  b = cups->header.InsertSheet;
994
1.19M
  if ((code = param_write_bool(plist, "InsertSheet", &b)) < 0)
995
0
    goto done;
996
997
1.19M
  if ((code = param_write_int(plist, "Jog",
998
1.19M
                              (int *)&(cups->header.Jog))) < 0)
999
0
    goto done;
1000
1001
1.19M
  b = cups->header.ManualFeed;
1002
1.19M
  if ((code = param_write_bool(plist, "ManualFeed", &b)) < 0)
1003
0
    goto done;
1004
1005
1.19M
  if ((code = param_write_int(plist, "MediaPosition",
1006
1.19M
                              (int *)&(cups->header.MediaPosition))) < 0)
1007
0
    goto done;
1008
1009
1.19M
  if ((code = param_write_int(plist, "MediaWeight",
1010
1.19M
                              (int *)&(cups->header.MediaWeight))) < 0)
1011
0
    goto done;
1012
1013
1.19M
  b = cups->header.MirrorPrint;
1014
1.19M
  if ((code = param_write_bool(plist, "MirrorPrint", &b)) < 0)
1015
0
    goto done;
1016
1017
1.19M
  b = cups->header.NegativePrint;
1018
1.19M
  if ((code = param_write_bool(plist, "NegativePrint", &b)) < 0)
1019
0
    goto done;
1020
1021
1.19M
  b = cups->header.OutputFaceUp;
1022
1.19M
  if ((code = param_write_bool(plist, "OutputFaceUp", &b)) < 0)
1023
0
    goto done;
1024
1025
1.19M
  b = cups->header.Separations;
1026
1.19M
  if ((code = param_write_bool(plist, "Separations", &b)) < 0)
1027
0
    goto done;
1028
1029
1.19M
  b = cups->header.TraySwitch;
1030
1.19M
  if ((code = param_write_bool(plist, "TraySwitch", &b)) < 0)
1031
0
    goto done;
1032
1033
1.19M
  b = cups->header.Tumble;
1034
1.19M
  if ((code = param_write_bool(plist, "Tumble", &b)) < 0)
1035
0
    goto done;
1036
1037
#if 0 /* Don't include read-only parameters... */
1038
  if ((code = param_write_int(plist, "cupsWidth",
1039
                              (int *)&(cups->header.cupsWidth))) < 0)
1040
    goto done;
1041
1042
  if ((code = param_write_int(plist, "cupsHeight",
1043
                              (int *)&(cups->header.cupsHeight))) < 0)
1044
    goto done;
1045
1046
  if ((code = param_write_int(plist, "cupsBitsPerPixel",
1047
                              (int *)&(cups->header.cupsBitsPerPixel))) < 0)
1048
    goto done;
1049
1050
  if ((code = param_write_int(plist, "cupsBytesPerLine",
1051
                              (int *)&(cups->header.cupsBytesPerLine))) < 0)
1052
    goto done;
1053
#endif /* 0 */
1054
1055
1.19M
  if ((code = param_write_int(plist, "cupsMediaType",
1056
1.19M
                              (int *)&(cups->header.cupsMediaType))) < 0)
1057
0
    goto done;
1058
1059
1.19M
  if ((code = param_write_int(plist, "cupsBitsPerColor",
1060
1.19M
                              (int *)&(cups->header.cupsBitsPerColor))) < 0)
1061
0
    goto done;
1062
1063
1.19M
  if ((code = param_write_int(plist, "cupsColorOrder",
1064
1.19M
                              (int *)&(cups->header.cupsColorOrder))) < 0)
1065
0
    goto done;
1066
1067
1.19M
  if ((code = param_write_int(plist, "cupsColorSpace",
1068
1.19M
                              (int *)&(cups->header.cupsColorSpace))) < 0)
1069
0
    goto done;
1070
1071
1.19M
  if ((code = param_write_int(plist, "cupsCompression",
1072
1.19M
                              (int *)&(cups->header.cupsCompression))) < 0)
1073
0
    goto done;
1074
1075
1.19M
  if ((code = param_write_int(plist, "cupsRowCount",
1076
1.19M
                              (int *)&(cups->header.cupsRowCount))) < 0)
1077
0
    goto done;
1078
1079
1.19M
  if ((code = param_write_int(plist, "cupsRowFeed",
1080
1.19M
                              (int *)&(cups->header.cupsRowFeed))) < 0)
1081
0
    goto done;
1082
1083
1.19M
  if ((code = param_write_int(plist, "cupsRowStep",
1084
1.19M
                              (int *)&(cups->header.cupsRowStep))) < 0)
1085
0
    goto done;
1086
1087
1.19M
#ifdef CUPS_RASTER_SYNCv1
1088
#if 0 /* Don't include read-only parameters... */
1089
  if ((code = param_write_int(plist, "cupsNumColors",
1090
                              (int *)&(cups->header.cupsNumColors))) < 0)
1091
    goto done;
1092
#endif /* 0 */
1093
1094
1.19M
  if ((code = param_write_float(plist, "cupsBorderlessScalingFactor",
1095
1.19M
                          &(cups->header.cupsBorderlessScalingFactor))) < 0)
1096
0
    goto done;
1097
1098
20.2M
  for (i = 0; cups_Integer_strings[i] != NULL; i ++)
1099
19.0M
  {
1100
19.0M
    if ((code = param_write_int(plist, cups_Integer_strings[i],
1101
19.0M
                          (int *)(cups->header.cupsInteger + i))) < 0)
1102
0
      goto done;
1103
19.0M
  }
1104
1105
20.2M
  for (i = 0; cups_Real_strings[i] != NULL; i ++)
1106
19.0M
  {
1107
19.0M
    if ((code = param_write_float(plist, cups_Real_strings[i],
1108
19.0M
                            cups->header.cupsReal + i)) < 0)
1109
0
      goto done;
1110
19.0M
  }
1111
1112
20.2M
  for (i = 0; cups_String_strings[i] != NULL; i ++)
1113
19.0M
  {
1114
19.0M
    param_string_from_transient_string(s, cups->header.cupsString[i]);
1115
19.0M
    if ((code = param_write_string(plist, cups_String_strings[i], &s)) < 0)
1116
0
      goto done;
1117
19.0M
  }
1118
1119
1.19M
  param_string_from_transient_string(s, cups->header.cupsMarkerType);
1120
1.19M
  if ((code = param_write_string(plist, "cupsMarkerType", &s)) < 0)
1121
0
    goto done;
1122
1123
1.19M
  param_string_from_transient_string(s, cups->header.cupsRenderingIntent);
1124
1.19M
  if ((code = param_write_string(plist, "cupsRenderingIntent", &s)) < 0)
1125
0
    goto done;
1126
1127
1.19M
  param_string_from_transient_string(s, cups->header.cupsPageSizeName);
1128
1.19M
  if ((code = param_write_string(plist, "cupsPageSizeName", &s)) < 0)
1129
0
    goto done;
1130
1.19M
#endif /* CUPS_RASTER_SYNCv1 */
1131
1132
 /*
1133
  * Variables for PPD-less use only. If these settings are defined in the
1134
  * PPD file, the PPD file's definitions get priority.
1135
  */
1136
1137
1.19M
  if ((code = param_write_int(plist, "cupsRasterVersion",
1138
1.19M
            (int *)&(cups->cupsRasterVersion))) < 0)
1139
0
    goto done;
1140
1141
1.19M
  param_string_from_transient_string(s, cups->cupsBackSideOrientation);
1142
1.19M
  if ((code = param_write_string(plist, "cupsBackSideOrientation", &s)) < 0)
1143
0
    goto done;
1144
1145
1.19M
  b = cups->cupsBackSideFlipMargins;
1146
1.19M
  if ((code = param_write_bool(plist, "cupsBackSideFlipMargins", &b)) < 0)
1147
0
    goto done;
1148
1149
1.19M
  b = cups->cupsManualCopies;
1150
1.19M
  if ((code = param_write_bool(plist, "cupsManualCopies", &b)) < 0)
1151
0
    goto done;
1152
1153
1.19M
done:
1154
1155
#ifdef CUPS_DEBUG2
1156
  dmprintf(pdev->memory, "DEBUG2: Leaving cups_get_params()\n");
1157
#endif /* CUPS_DEBUG2 */
1158
1159
1.19M
  return code;
1160
1.19M
}
1161
1162
1163
/*
1164
 * 'cups_get_space_params()' - Get space parameters from the RIP_CACHE env var.
1165
 */
1166
1167
void
1168
cups_get_space_params(const gx_device_printer *pdev,
1169
          /* I - Printer device */
1170
                            gdev_space_params *space_params)
1171
          /* O - Space parameters */
1172
95.3k
{
1173
95.3k
  float cache_size;     /* Size of tile cache in bytes */
1174
95.3k
  char  *cache_env,     /* Cache size environment variable */
1175
95.3k
  cache_units[255];   /* Cache size units */
1176
1177
1178
#ifdef CUPS_DEBUG2
1179
  dmprintf2(pdev->memory, "DEBUG2: cups_get_space_params(%p, %p)\n", pdev, space_params);
1180
#endif /* CUPS_DEBUG2 */
1181
1182
95.3k
  if ((cache_env = getenv("RIP_MAX_CACHE")) != NULL)
1183
0
  {
1184
0
    switch (sscanf(cache_env, "%f%254s", &cache_size, cache_units))
1185
0
    {
1186
0
      case 0 :
1187
0
          return;
1188
0
      case 1 :
1189
0
          cache_size *= 4 * CUPS_TILE_SIZE * CUPS_TILE_SIZE;
1190
0
    break;
1191
0
      case 2 :
1192
0
          if (tolower(cache_units[0]) == 'g')
1193
0
      cache_size *= 1024 * 1024 * 1024;
1194
0
          else if (tolower(cache_units[0]) == 'm')
1195
0
      cache_size *= 1024 * 1024;
1196
0
    else if (tolower(cache_units[0]) == 'k')
1197
0
      cache_size *= 1024;
1198
0
    else if (tolower(cache_units[0]) == 't')
1199
0
      cache_size *= 4 * CUPS_TILE_SIZE * CUPS_TILE_SIZE;
1200
0
    break;
1201
0
    }
1202
0
  }
1203
95.3k
  else
1204
95.3k
    return;
1205
1206
0
  if (cache_size == 0)
1207
0
    return;
1208
1209
#ifdef CUPS_DEBUG2
1210
  dmprintf1(pdev->memory, "DEBUG2: cache_size = %.0f\n", cache_size);
1211
#endif /* CUPS_DEBUG2 */
1212
1213
0
  space_params->MaxBitmap   = (long)cache_size;
1214
0
  space_params->BufferSpace = (long)cache_size;
1215
0
}
1216
1217
1218
/*
1219
 * 'cups_map_cielab()' - Map CIE Lab transformation...
1220
 */
1221
1222
static double       /* O - Adjusted color value */
1223
cups_map_cielab(double x,   /* I - Raw color value */
1224
                double xn)    /* I - Whitepoint color value */
1225
21.3M
{
1226
21.3M
  double x_xn;        /* Fraction of whitepoint */
1227
1228
1229
21.3M
  x_xn = x / xn;
1230
1231
21.3M
  if (x_xn > 0.008856)
1232
11.1M
    return (cbrt(x_xn));
1233
10.1M
  else
1234
10.1M
    return (7.787 * x_xn + 16.0 / 116.0);
1235
21.3M
}
1236
1237
1238
#ifdef dev_t_proc_encode_color
1239
/*
1240
 * 'cups_map_cmyk()' - Map a CMYK color value to device colors.
1241
 */
1242
1243
private void
1244
cups_map_cmyk(const gx_device *pdev,    /* I - Device info */
1245
              frac      c,    /* I - Cyan value */
1246
        frac      m,    /* I - Magenta value */
1247
        frac      y,    /* I - Yellow value */
1248
        frac      k,    /* I - Black value */
1249
        frac      *out)   /* O - Device colors */
1250
258M
{
1251
258M
  int c0 = 0, c1 = 0,
1252
258M
        c2 = 0, c3 = 0;     /* Temporary color values */
1253
258M
  float rr, rg, rb,     /* Real RGB colors */
1254
258M
  ciex, ciey, ciez,   /* CIE XYZ colors */
1255
258M
  ciey_yn,      /* Normalized luminance */
1256
258M
  ciel, ciea, cieb;   /* CIE Lab colors */
1257
1258
1259
#ifdef CUPS_DEBUG2
1260
  dmprintf6(pdev->memory, "DEBUG2: cups_map_cmyk(%p, %d, %d, %d, %d, %p)\n",
1261
            pdev, c, m, y, k, out);
1262
#endif /* CUPS_DEBUG2 */
1263
1264
 /*
1265
  * Convert the CMYK color to the destination colorspace...
1266
  */
1267
1268
258M
  switch (cups->header.cupsColorSpace)
1269
258M
  {
1270
258k
    case CUPS_CSPACE_W :
1271
261k
    case CUPS_CSPACE_SW :
1272
261k
        c0 = (c * 31 + m * 61 + y * 8) / 100 + k;
1273
1274
261k
  if (c0 < 0)
1275
0
    c0 = 0;
1276
261k
  else if (c0 > frac_1)
1277
0
    c0 = frac_1;
1278
261k
  out[0] = frac_1 - (frac)cups->Density[c0];
1279
261k
        break;
1280
1281
4.51k
    case CUPS_CSPACE_RGBA :
1282
4.51k
        out[3] = frac_1;
1283
1284
250M
    case CUPS_CSPACE_RGB :
1285
250M
    case CUPS_CSPACE_SRGB :
1286
252M
    case CUPS_CSPACE_ADOBERGB :
1287
252M
    case CUPS_CSPACE_RGBW :
1288
252M
        c0 = c + k;
1289
252M
        c1 = m + k;
1290
252M
        c2 = y + k;
1291
252M
        if (cups->header.cupsColorSpace == CUPS_CSPACE_RGBW) {
1292
9.72k
    if ((k >= frac_1 - 1) ||
1293
9.72k
        ((c0 >= frac_1) && (c1 >= frac_1) && (c2 >= frac_1))) {
1294
6.36k
      c0 = frac_1;
1295
6.36k
      c1 = frac_1;
1296
6.36k
      c2 = frac_1;
1297
6.36k
      c3 = frac_1;
1298
6.36k
    } else
1299
3.36k
      c3 = 0;
1300
9.72k
  }
1301
1302
252M
        if (c0 < 0)
1303
0
    c0 = 0;
1304
252M
  else if (c0 > frac_1)
1305
0
    c0 = frac_1;
1306
252M
  out[0] = frac_1 - (frac)cups->Density[c0];
1307
1308
252M
        if (c1 < 0)
1309
0
    c1 = 0;
1310
252M
  else if (c1 > frac_1)
1311
0
    c1 = frac_1;
1312
252M
  out[1] = frac_1 - (frac)cups->Density[c1];
1313
1314
252M
        if (c2 < 0)
1315
0
    c2 = 0;
1316
252M
  else if (c2 > frac_1)
1317
0
    c2 = frac_1;
1318
252M
  out[2] = frac_1 - (frac)cups->Density[c2];
1319
1320
252M
        if (cups->header.cupsColorSpace == CUPS_CSPACE_RGBW) {
1321
9.72k
    if (c3 == 0)
1322
3.36k
      out[3] = frac_1;
1323
6.36k
    else if (c3 == frac_1)
1324
6.36k
      out[3] = 0;
1325
9.72k
  }
1326
252M
        break;
1327
1328
47.6k
    default :
1329
52.1k
    case CUPS_CSPACE_K :
1330
52.1k
        c0 = (c * 31 + m * 61 + y * 8) / 100 + k;
1331
1332
52.1k
  if (c0 < 0)
1333
0
    out[0] = 0;
1334
52.1k
  else if (c0 > frac_1)
1335
0
    out[0] = (frac)cups->Density[frac_1];
1336
52.1k
  else
1337
52.1k
    out[0] = (frac)cups->Density[c0];
1338
52.1k
        break;
1339
1340
66.2k
    case CUPS_CSPACE_CMY :
1341
66.2k
        c0 = c + k;
1342
66.2k
  c1 = m + k;
1343
66.2k
  c2 = y + k;
1344
1345
66.2k
        if (c0 < 0)
1346
0
    out[0] = 0;
1347
66.2k
  else if (c0 > frac_1)
1348
0
    out[0] = (frac)cups->Density[frac_1];
1349
66.2k
  else
1350
66.2k
    out[0] = (frac)cups->Density[c0];
1351
1352
66.2k
        if (c1 < 0)
1353
0
    out[1] = 0;
1354
66.2k
  else if (c1 > frac_1)
1355
0
    out[1] = (frac)cups->Density[frac_1];
1356
66.2k
  else
1357
66.2k
    out[1] = (frac)cups->Density[c1];
1358
1359
66.2k
        if (c2 < 0)
1360
0
    out[2] = 0;
1361
66.2k
  else if (c2 > frac_1)
1362
0
    out[2] = (frac)cups->Density[frac_1];
1363
66.2k
  else
1364
66.2k
    out[2] = (frac)cups->Density[c2];
1365
66.2k
        break;
1366
1367
3.58k
    case CUPS_CSPACE_YMC :
1368
3.58k
        c0 = y + k;
1369
3.58k
  c1 = m + k;
1370
3.58k
  c2 = c + k;
1371
1372
3.58k
        if (c0 < 0)
1373
0
    out[0] = 0;
1374
3.58k
  else if (c0 > frac_1)
1375
0
    out[0] = (frac)cups->Density[frac_1];
1376
3.58k
  else
1377
3.58k
    out[0] = (frac)cups->Density[c0];
1378
1379
3.58k
        if (c1 < 0)
1380
0
    out[1] = 0;
1381
3.58k
  else if (c1 > frac_1)
1382
0
    out[1] = (frac)cups->Density[frac_1];
1383
3.58k
  else
1384
3.58k
    out[1] = (frac)cups->Density[c1];
1385
1386
3.58k
        if (c2 < 0)
1387
0
    out[2] = 0;
1388
3.58k
  else if (c2 > frac_1)
1389
0
    out[2] = (frac)cups->Density[frac_1];
1390
3.58k
  else
1391
3.58k
    out[2] = (frac)cups->Density[c2];
1392
3.58k
        break;
1393
1394
278k
    case CUPS_CSPACE_CMYK :
1395
278k
        if (c < 0)
1396
0
    out[0] = 0;
1397
278k
  else if (c > frac_1)
1398
0
    out[0] = (frac)cups->Density[frac_1];
1399
278k
  else
1400
278k
    out[0] = (frac)cups->Density[c];
1401
1402
278k
        if (m < 0)
1403
0
    out[1] = 0;
1404
278k
  else if (m > frac_1)
1405
0
    out[1] = (frac)cups->Density[frac_1];
1406
278k
  else
1407
278k
    out[1] = (frac)cups->Density[m];
1408
1409
278k
        if (y < 0)
1410
0
    out[2] = 0;
1411
278k
  else if (y > frac_1)
1412
0
    out[2] = (frac)cups->Density[frac_1];
1413
278k
  else
1414
278k
    out[2] = (frac)cups->Density[y];
1415
1416
278k
        if (k < 0)
1417
0
    out[3] = 0;
1418
278k
  else if (k > frac_1)
1419
0
    out[3] = (frac)cups->Density[frac_1];
1420
278k
  else
1421
278k
    out[3] = (frac)cups->Density[k];
1422
278k
        break;
1423
1424
6.89k
    case CUPS_CSPACE_YMCK :
1425
137k
    case CUPS_CSPACE_GMCK :
1426
151k
    case CUPS_CSPACE_GMCS :
1427
151k
        if (y < 0)
1428
0
    out[0] = 0;
1429
151k
  else if (y > frac_1)
1430
0
    out[0] = (frac)cups->Density[frac_1];
1431
151k
  else
1432
151k
    out[0] = (frac)cups->Density[y];
1433
1434
151k
        if (m < 0)
1435
0
    out[1] = 0;
1436
151k
  else if (m > frac_1)
1437
0
    out[1] = (frac)cups->Density[frac_1];
1438
151k
  else
1439
151k
    out[1] = (frac)cups->Density[m];
1440
1441
151k
        if (c < 0)
1442
0
    out[2] = 0;
1443
151k
  else if (c > frac_1)
1444
0
    out[2] = (frac)cups->Density[frac_1];
1445
151k
  else
1446
151k
    out[2] = (frac)cups->Density[c];
1447
1448
151k
        if (k < 0)
1449
0
    out[3] = 0;
1450
151k
  else if (k > frac_1)
1451
0
    out[3] = (frac)cups->Density[frac_1];
1452
151k
  else
1453
151k
    out[3] = (frac)cups->Density[k];
1454
151k
        break;
1455
1456
27.0k
    case CUPS_CSPACE_KCMYcm :
1457
38.3k
    case CUPS_CSPACE_KCMY :
1458
38.3k
        if (k < 0)
1459
0
    out[0] = 0;
1460
38.3k
  else if (k > frac_1)
1461
0
    out[0] = (frac)cups->Density[frac_1];
1462
38.3k
  else
1463
38.3k
    out[0] = (frac)cups->Density[k];
1464
1465
38.3k
        if (c < 0)
1466
0
    out[1] = 0;
1467
38.3k
  else if (c > frac_1)
1468
0
    out[1] = (frac)cups->Density[frac_1];
1469
38.3k
  else
1470
38.3k
    out[1] = (frac)cups->Density[c];
1471
1472
38.3k
        if (m < 0)
1473
0
    out[2] = 0;
1474
38.3k
  else if (m > frac_1)
1475
0
    out[2] = (frac)cups->Density[frac_1];
1476
38.3k
  else
1477
38.3k
    out[2] = (frac)cups->Density[m];
1478
1479
38.3k
        if (y < 0)
1480
0
    out[3] = 0;
1481
38.3k
  else if (y > frac_1)
1482
0
    out[3] = (frac)cups->Density[frac_1];
1483
38.3k
  else
1484
38.3k
    out[3] = (frac)cups->Density[y];
1485
38.3k
        break;
1486
1487
0
#  ifdef CUPS_RASTER_HAVE_COLORIMETRIC
1488
0
    case CUPS_CSPACE_CIEXYZ :
1489
1.66k
    case CUPS_CSPACE_CIELab :
1490
3.65M
    case CUPS_CSPACE_ICC1 :
1491
3.65M
    case CUPS_CSPACE_ICC2 :
1492
3.66M
    case CUPS_CSPACE_ICC3 :
1493
3.67M
    case CUPS_CSPACE_ICC4 :
1494
3.74M
    case CUPS_CSPACE_ICC5 :
1495
5.28M
    case CUPS_CSPACE_ICC6 :
1496
5.28M
    case CUPS_CSPACE_ICC7 :
1497
5.28M
    case CUPS_CSPACE_ICC8 :
1498
5.29M
    case CUPS_CSPACE_ICC9 :
1499
5.30M
    case CUPS_CSPACE_ICCA :
1500
5.30M
    case CUPS_CSPACE_ICCB :
1501
5.30M
    case CUPS_CSPACE_ICCC :
1502
5.30M
    case CUPS_CSPACE_ICCD :
1503
5.31M
    case CUPS_CSPACE_ICCE :
1504
5.33M
    case CUPS_CSPACE_ICCF :
1505
       /*
1506
        * Convert CMYK to sRGB...
1507
  */
1508
1509
5.33M
        c0 = frac_1 - c - k;
1510
5.33M
  c1 = frac_1 - m - k;
1511
5.33M
  c2 = frac_1 - y - k;
1512
1513
5.33M
        if (c0 < 0)
1514
0
    c0 = 0;
1515
1516
5.33M
        if (c1 < 0)
1517
0
    c1 = 0;
1518
1519
5.33M
        if (c2 < 0)
1520
0
    c2 = 0;
1521
1522
       /*
1523
        * Convert sRGB to linear RGB...
1524
  */
1525
1526
5.33M
  rr = pow(((double)c0 / (double)frac_1 + 0.055) / 1.055, 2.4);
1527
5.33M
  rg = pow(((double)c1 / (double)frac_1 + 0.055) / 1.055, 2.4);
1528
5.33M
  rb = pow(((double)c2 / (double)frac_1 + 0.055) / 1.055, 2.4);
1529
1530
       /*
1531
        * Convert to CIE XYZ...
1532
  */
1533
1534
5.33M
  ciex = 0.412453 * rr + 0.357580 * rg + 0.180423 * rb;
1535
5.33M
  ciey = 0.212671 * rr + 0.715160 * rg + 0.072169 * rb;
1536
5.33M
  ciez = 0.019334 * rr + 0.119193 * rg + 0.950227 * rb;
1537
1538
5.33M
        if (cups->header.cupsColorSpace == CUPS_CSPACE_CIEXYZ)
1539
0
  {
1540
   /*
1541
    * Convert to an integer XYZ color value...
1542
    */
1543
1544
0
          if (cups->header.cupsBitsPerColor == 8)
1545
0
    {
1546
0
      if (ciex <= 0.0f)
1547
0
        c0 = 0;
1548
0
      else if (ciex < 1.1)
1549
0
        c0 = (int)(ciex * 231.8181 + 0.5);
1550
0
      else
1551
0
        c0 = 255;
1552
1553
0
      if (ciey <= 0.0f)
1554
0
        c1 = 0;
1555
0
      else if (ciey < 1.1)
1556
0
        c1 = (int)(ciey * 231.8181 + 0.5);
1557
0
      else
1558
0
        c1 = 255;
1559
1560
0
      if (ciez <= 0.0f)
1561
0
        c2 = 0;
1562
0
      else if (ciez < 1.1)
1563
0
        c2 = (int)(ciez * 231.8181 + 0.5);
1564
0
      else
1565
0
        c2 = 255;
1566
0
    }
1567
0
    else
1568
0
    {
1569
0
      if (ciex <= 0.0f)
1570
0
        c0 = 0;
1571
0
      else if (ciex < 1.1)
1572
0
        c0 = (int)(ciex * 59577.2727 + 0.5);
1573
0
      else
1574
0
        c0 = 65535;
1575
1576
0
      if (ciey <= 0.0f)
1577
0
        c1 = 0;
1578
0
      else if (ciey < 1.1)
1579
0
        c1 = (int)(ciey * 59577.2727 + 0.5);
1580
0
      else
1581
0
        c1 = 65535;
1582
1583
0
      if (ciez <= 0.0f)
1584
0
        c2 = 0;
1585
0
      else if (ciez < 1.1)
1586
0
        c2 = (int)(ciez * 59577.2727 + 0.5);
1587
0
      else
1588
0
        c2 = 65535;
1589
0
    }
1590
0
  }
1591
5.33M
  else
1592
5.33M
  {
1593
   /*
1594
    * Convert CIE XYZ to Lab...
1595
    */
1596
1597
5.33M
    ciey_yn = ciey / D65_Y;
1598
1599
5.33M
    if (ciey_yn > 0.008856)
1600
2.78M
      ciel = 116 * cbrt(ciey_yn) - 16;
1601
2.54M
    else
1602
2.54M
      ciel = 903.3 * ciey_yn;
1603
1604
5.33M
    ciea = 500 * (cups_map_cielab(ciex, D65_X) -
1605
5.33M
                  cups_map_cielab(ciey, D65_Y));
1606
5.33M
    cieb = 200 * (cups_map_cielab(ciey, D65_Y) -
1607
5.33M
                  cups_map_cielab(ciez, D65_Z));
1608
1609
5.33M
          if (cups->header.cupsBitsPerColor == 8)
1610
5.33M
    {
1611
           /*
1612
      * Scale the L value and bias the a and b values by 128
1613
      * so that all values are in the range of 0 to 255.
1614
      */
1615
1616
5.33M
      ciel = ciel * 2.55 + 0.5;
1617
5.33M
      ciea += 128.5;
1618
5.33M
      cieb += 128.5;
1619
1620
5.33M
      if (ciel <= 0.0)
1621
0
        c0 = 0;
1622
5.33M
      else if (ciel < 255.0)
1623
2.89M
        c0 = (int)ciel;
1624
2.43M
      else
1625
2.43M
        c0 = 255;
1626
1627
5.33M
      if (ciea <= 0.0)
1628
0
        c1 = 0;
1629
5.33M
      else if (ciea < 255.0)
1630
5.33M
        c1 = (int)ciea;
1631
0
      else
1632
0
        c1 = 255;
1633
1634
5.33M
      if (cieb <= 0.0)
1635
0
        c2 = 0;
1636
5.33M
      else if (cieb < 255.0)
1637
5.33M
        c2 = (int)cieb;
1638
0
      else
1639
0
        c2 = 255;
1640
5.33M
          }
1641
0
    else
1642
0
    {
1643
     /*
1644
      * Scale the L value and bias the a and b values by 128 so that all
1645
      * numbers are from 0 to 65535.
1646
      */
1647
1648
0
      ciel = ciel * 655.35 + 0.5;
1649
0
      ciea = (ciea + 128.0) * 256.0 + 0.5;
1650
0
      cieb = (cieb + 128.0) * 256.0 + 0.5;
1651
1652
     /*
1653
      * Output 16-bit values...
1654
      */
1655
1656
0
      if (ciel <= 0.0)
1657
0
        c0 = 0;
1658
0
      else if (ciel < 65535.0)
1659
0
        c0 = (int)ciel;
1660
0
      else
1661
0
        c0 = 65535;
1662
1663
0
      if (ciea <= 0.0)
1664
0
        c1 = 0;
1665
0
      else if (ciea < 65535.0)
1666
0
        c1 = (int)ciea;
1667
0
      else
1668
0
        c1 = 65535;
1669
1670
0
      if (cieb <= 0.0)
1671
0
        c2 = 0;
1672
0
      else if (cieb < 65535.0)
1673
0
        c2 = (int)cieb;
1674
0
      else
1675
0
        c2 = 65535;
1676
0
    }
1677
5.33M
  }
1678
1679
5.33M
        out[0] = cups->DecodeLUT[c0];
1680
5.33M
        out[1] = cups->DecodeLUT[c1];
1681
5.33M
        out[2] = cups->DecodeLUT[c2];
1682
5.33M
        break;
1683
258M
#  endif /* CUPS_RASTER_HAVE_COLORIMETRIC */
1684
258M
  }
1685
1686
#ifdef CUPS_DEBUG2
1687
  switch (cups->color_info.num_components)
1688
  {
1689
    default :
1690
    case 1 :
1691
        dmprintf1(pdev->memory, "DEBUG2:   \\=== COLOR %d\n", out[0]);
1692
  break;
1693
1694
    case 3 :
1695
        dmprintf3(pdev->memory, "DEBUG2:   \\=== COLOR %d, %d, %d\n",
1696
                  out[0], out[1], out[2]);
1697
  break;
1698
1699
    case 4 :
1700
        dmprintf4(pdev->memory, "DEBUG2:   \\=== COLOR %d, %d, %d, %d\n",
1701
                  out[0], out[1], out[2], out[3]);
1702
  break;
1703
  }
1704
#endif /* CUPS_DEBUG2 */
1705
258M
}
1706
1707
1708
/*
1709
 * 'cups_map_gray()' - Map a grayscale value to device colors.
1710
 */
1711
1712
private void
1713
cups_map_gray(const gx_device *pdev,    /* I - Device info */
1714
              frac      g,    /* I - Grayscale value */
1715
        frac      *out)   /* O - Device colors */
1716
346k
{
1717
#ifdef CUPS_DEBUG22
1718
  dmprintf3(pdev->memory, "DEBUG2: cups_map_gray(%p, %d, %p)\n",
1719
            pdev, g, out);
1720
#endif /* CUPS_DEBUG22 */
1721
1722
 /*
1723
  * Just use the CMYK mapper...
1724
  */
1725
1726
346k
  cups_map_cmyk(pdev, 0, 0, 0, frac_1 - g, out);
1727
346k
}
1728
1729
1730
/*
1731
 * 'cups_map_rgb()' - Map a RGB color value to device colors.
1732
 */
1733
1734
private void
1735
cups_map_rgb(const gx_device             *pdev,
1736
          /* I - Device info */
1737
             const gs_gstate        *pgs,/* I - Device state */
1738
             frac                  r, /* I - Red value */
1739
       frac                  g, /* I - Green value */
1740
       frac                  b, /* I - Blue value */
1741
       frac                  *out)/* O - Device colors */
1742
257M
{
1743
257M
  frac    c, m, y, k;   /* CMYK values */
1744
257M
  frac    mk;     /* Maximum K value */
1745
257M
  int   tc, tm, ty;   /* Temporary color values */
1746
1747
1748
#ifdef CUPS_DEBUG2
1749
  dmprintf6(pdev->memory, "DEBUG2: cups_map_rgb(%p, %p, %d, %d, %d, %p)\n",
1750
            pdev, pgs, r, g, b, out);
1751
#endif /* CUPS_DEBUG2 */
1752
1753
 /*
1754
  * Compute CMYK values...
1755
  */
1756
1757
257M
  c = frac_1 - r;
1758
257M
  m = frac_1 - g;
1759
257M
  y = frac_1 - b;
1760
257M
  k = min(c, min(m, y));
1761
1762
257M
  if ((mk = max(c, max(m, y))) > k)
1763
141M
    k = (int)((float)k * (float)k * (float)k / ((float)mk * (float)mk));
1764
1765
257M
  c -= k;
1766
257M
  m -= k;
1767
257M
  y -= k;
1768
1769
 /*
1770
  * Do color correction as needed...
1771
  */
1772
1773
257M
  if (cups->HaveProfile)
1774
0
  {
1775
   /*
1776
    * Color correct CMY...
1777
    */
1778
1779
0
    tc = cups->Matrix[0][0][c] +
1780
0
         cups->Matrix[0][1][m] +
1781
0
   cups->Matrix[0][2][y];
1782
0
    tm = cups->Matrix[1][0][c] +
1783
0
         cups->Matrix[1][1][m] +
1784
0
   cups->Matrix[1][2][y];
1785
0
    ty = cups->Matrix[2][0][c] +
1786
0
         cups->Matrix[2][1][m] +
1787
0
   cups->Matrix[2][2][y];
1788
1789
0
    if (tc < 0)
1790
0
      c = 0;
1791
0
    else if (tc > frac_1)
1792
0
      c = frac_1;
1793
0
    else
1794
0
      c = (frac)tc;
1795
1796
0
    if (tm < 0)
1797
0
      m = 0;
1798
0
    else if (tm > frac_1)
1799
0
      m = frac_1;
1800
0
    else
1801
0
      m = (frac)tm;
1802
1803
0
    if (ty < 0)
1804
0
      y = 0;
1805
0
    else if (ty > frac_1)
1806
0
      y = frac_1;
1807
0
    else
1808
0
      y = (frac)ty;
1809
0
  }
1810
1811
 /*
1812
  * Use the CMYK mapping function to produce the device colors...
1813
  */
1814
1815
257M
  cups_map_cmyk(pdev, c, m, y, k, out);
1816
257M
}
1817
#else
1818
/*
1819
 * 'cups_map_cmyk_color()' - Map a CMYK color to a color index.
1820
 *
1821
 * This function is only called when a 4 or 6 color colorspace is
1822
 * selected for output.  CMYK colors are *not* corrected but *are*
1823
 * density adjusted.
1824
 */
1825
1826
private gx_color_index      /* O - Color index */
1827
cups_map_cmyk_color(gx_device      *pdev,
1828
          /* I - Device info */
1829
                    const gx_color_value cv[4])/* I - CMYK color values */
1830
{
1831
  gx_color_index  i;    /* Temporary index */
1832
  gx_color_value  c, m, y, k;
1833
  gx_color_value  ic, im, iy, ik; /* Integral CMYK values */
1834
1835
  c = cv[0];
1836
  m = cv[1];
1837
  y = cv[2];
1838
  k = cv[3];
1839
1840
#ifdef CUPS_DEBUG2
1841
  dmprintf5(pdev->memory, "DEBUG2: cups_map_cmyk_color(%p, %d, %d, %d, %d)\n",
1842
            pdev, c, m, y, k);
1843
#endif /* CUPS_DEBUG2 */
1844
1845
 /*
1846
  * Setup the color info data as needed...
1847
  */
1848
1849
  if (pdev->color_info.num_components == 0) {
1850
    if (cups_set_color_info(pdev) < 0)
1851
      return(gx_no_color_index);
1852
  }
1853
1854
 /*
1855
  * Density correct...
1856
  */
1857
1858
  if (cups->HaveProfile)
1859
  {
1860
    c = cups->Density[c];
1861
    m = cups->Density[m];
1862
    y = cups->Density[y];
1863
    k = cups->Density[k];
1864
  }
1865
1866
  ic = cups->EncodeLUT[c];
1867
  im = cups->EncodeLUT[m];
1868
  iy = cups->EncodeLUT[y];
1869
  ik = cups->EncodeLUT[k];
1870
1871
 /*
1872
  * Convert the CMYK color to a color index...
1873
  */
1874
1875
  switch (cups->header.cupsColorSpace)
1876
  {
1877
    default :
1878
        switch (cups->header.cupsBitsPerColor)
1879
        {
1880
          default :
1881
              i = (((((ic << 1) | im) << 1) | iy) << 1) | ik;
1882
              break;
1883
          case 2 :
1884
              i = (((((ic << 2) | im) << 2) | iy) << 2) | ik;
1885
              break;
1886
          case 4 :
1887
              i = (((((ic << 4) | im) << 4) | iy) << 4) | ik;
1888
              break;
1889
          case 8 :
1890
              i = (((((ic << 8) | im) << 8) | iy) << 8) | ik;
1891
              break;
1892
#ifdef GX_COLOR_INDEX_TYPE
1893
    case 16 :
1894
        i = (((((ic << 16) | im) << 16) | iy) << 16) | ik;
1895
        break;
1896
#endif /* GX_COLOR_INDEX_TYPE */
1897
        }
1898
        break;
1899
1900
    case CUPS_CSPACE_YMCK :
1901
    case CUPS_CSPACE_GMCK :
1902
    case CUPS_CSPACE_GMCS :
1903
        switch (cups->header.cupsBitsPerColor)
1904
        {
1905
          default :
1906
              i = (((((iy << 1) | im) << 1) | ic) << 1) | ik;
1907
              break;
1908
          case 2 :
1909
              i = (((((iy << 2) | im) << 2) | ic) << 2) | ik;
1910
              break;
1911
          case 4 :
1912
              i = (((((iy << 4) | im) << 4) | ic) << 4) | ik;
1913
              break;
1914
          case 8 :
1915
              i = (((((iy << 8) | im) << 8) | ic) << 8) | ik;
1916
              break;
1917
#ifdef GX_COLOR_INDEX_TYPE
1918
    case 16 :
1919
        i = (((((iy << 16) | im) << 16) | ic) << 16) | ik;
1920
        break;
1921
#endif /* GX_COLOR_INDEX_TYPE */
1922
        }
1923
        break;
1924
1925
    case CUPS_CSPACE_KCMYcm :
1926
        if (cups->header.cupsBitsPerColor == 1)
1927
  {
1928
    if (ik)
1929
      i = 32;
1930
    else
1931
      i = 0;
1932
1933
    if (ic && im)
1934
      i |= 17;
1935
    else if (ic && iy)
1936
      i |= 6;
1937
    else if (im && iy)
1938
      i |= 12;
1939
    else if (ic)
1940
      i |= 16;
1941
    else if (im)
1942
      i |= 8;
1943
    else if (iy)
1944
      i |= 4;
1945
    break;
1946
  }
1947
1948
    case CUPS_CSPACE_KCMY :
1949
        switch (cups->header.cupsBitsPerColor)
1950
        {
1951
          default :
1952
              i = (((((ik << 1) | ic) << 1) | im) << 1) | iy;
1953
              break;
1954
          case 2 :
1955
              i = (((((ik << 2) | ic) << 2) | im) << 2) | iy;
1956
              break;
1957
          case 4 :
1958
              i = (((((ik << 4) | ic) << 4) | im) << 4) | iy;
1959
              break;
1960
          case 8 :
1961
              i = (((((ik << 8) | ic) << 8) | im) << 8) | iy;
1962
              break;
1963
#ifdef GX_COLOR_INDEX_TYPE
1964
    case 16 :
1965
        i = (((((ik << 16) | ic) << 16) | im) << 16) | iy;
1966
        break;
1967
#endif /* GX_COLOR_INDEX_TYPE */
1968
        }
1969
        break;
1970
  }
1971
1972
#ifdef CUPS_DEBUG2
1973
  dmprintf9(pdev->memory, "DEBUG2: CMYK (%d,%d,%d,%d) -> CMYK %08x (%d,%d,%d,%d)\n",
1974
            c, m, y, k, (unsigned)i, ic, im, iy, ik);
1975
#endif /* CUPS_DEBUG2 */
1976
1977
 /*
1978
  * Make sure we don't get a CMYK color of 255, 255, 255, 255...
1979
  */
1980
1981
  if (i == gx_no_color_index)
1982
    i --;
1983
1984
  return (i);
1985
}
1986
1987
1988
/*
1989
 * 'cups_map_color_rgb()' - Map a color index to an RGB color.
1990
 */
1991
1992
private int
1993
cups_map_color_rgb(gx_device      *pdev,/* I - Device info */
1994
                   gx_color_index color,/* I - Color index */
1995
       gx_color_value prgb[3])
1996
          /* O - RGB values */
1997
{
1998
  unsigned char   c0, c1, c2, c3; /* Color index components */
1999
  gx_color_value  c, m, y, k, divk; /* Colors, Black & divisor */
2000
2001
2002
#ifdef CUPS_DEBUG2
2003
  dmprintf3(pdev->memory, "DEBUG2: cups_map_color_rgb(%p, %d, %p)\n", pdev,
2004
            (unsigned)color, prgb);
2005
#endif /* CUPS_DEBUG2 */
2006
2007
 /*
2008
  * Setup the color info data as needed...
2009
  */
2010
2011
  if (pdev->color_info.num_components == 0) {
2012
    if (cups_set_color_info(pdev) < 0)
2013
      return(gx_no_color_index);
2014
  }
2015
2016
#ifdef CUPS_DEBUG2
2017
  dmprintf1(pdev->memory, "DEBUG2: COLOR %08x = ", (unsigned)color);
2018
#endif /* CUPS_DEBUG2 */
2019
2020
 /*
2021
  * Extract the color components from the color index...
2022
  */
2023
2024
  switch (cups->header.cupsBitsPerColor)
2025
  {
2026
    default :
2027
        c3 = color & 1;
2028
        color >>= 1;
2029
        c2 = color & 1;
2030
        color >>= 1;
2031
        c1 = color & 1;
2032
        color >>= 1;
2033
        c0 = color;
2034
        break;
2035
    case 2 :
2036
        c3 = color & 3;
2037
        color >>= 2;
2038
        c2 = color & 3;
2039
        color >>= 2;
2040
        c1 = color & 3;
2041
        color >>= 2;
2042
        c0 = color;
2043
        break;
2044
    case 4 :
2045
        c3 = color & 15;
2046
        color >>= 4;
2047
        c2 = color & 15;
2048
        color >>= 4;
2049
        c1 = color & 15;
2050
        color >>= 4;
2051
        c0 = color;
2052
        break;
2053
    case 8 :
2054
        c3 = color & 255;
2055
        color >>= 8;
2056
        c2 = color & 255;
2057
        color >>= 8;
2058
        c1 = color & 255;
2059
        color >>= 8;
2060
        c0 = color;
2061
        break;
2062
#ifdef GX_COLOR_INDEX_TYPE
2063
    case 16 :
2064
        c3 = color & 0xffff;
2065
        color >>= 16;
2066
        c2 = color & 0xffff;
2067
        color >>= 16;
2068
        c1 = color & 0xffff;
2069
        color >>= 16;
2070
        c0 = color;
2071
        break;
2072
#endif /* GX_COLOR_INDEX_TYPE */
2073
  }
2074
2075
 /*
2076
  * Convert the color components to RGB...
2077
  */
2078
2079
  switch (cups->header.cupsColorSpace)
2080
  {
2081
    case CUPS_CSPACE_K :
2082
    case CUPS_CSPACE_WHITE :
2083
    case CUPS_CSPACE_GOLD :
2084
    case CUPS_CSPACE_SILVER :
2085
        prgb[0] =
2086
        prgb[1] =
2087
        prgb[2] = cups->DecodeLUT[c3];
2088
        break;
2089
2090
    case CUPS_CSPACE_W :
2091
    case CUPS_CSPACE_SW :
2092
        prgb[0] =
2093
        prgb[1] =
2094
        prgb[2] = cups->DecodeLUT[c3];
2095
        break;
2096
2097
    case CUPS_CSPACE_RGB :
2098
    case CUPS_CSPACE_SRGB :
2099
    case CUPS_CSPACE_ADOBERGB :
2100
        prgb[0] = cups->DecodeLUT[c1];
2101
        prgb[1] = cups->DecodeLUT[c2];
2102
        prgb[2] = cups->DecodeLUT[c3];
2103
        break;
2104
2105
    case CUPS_CSPACE_RGBA :
2106
        prgb[0] = cups->DecodeLUT[c0];
2107
        prgb[1] = cups->DecodeLUT[c1];
2108
        prgb[2] = cups->DecodeLUT[c2];
2109
        break;
2110
2111
    case CUPS_CSPACE_CMY :
2112
        prgb[0] = cups->DecodeLUT[c1];
2113
        prgb[1] = cups->DecodeLUT[c2];
2114
        prgb[2] = cups->DecodeLUT[c3];
2115
        break;
2116
2117
    case CUPS_CSPACE_YMC :
2118
        prgb[0] = cups->DecodeLUT[c3];
2119
        prgb[1] = cups->DecodeLUT[c2];
2120
        prgb[2] = cups->DecodeLUT[c1];
2121
        break;
2122
2123
    case CUPS_CSPACE_KCMY :
2124
    case CUPS_CSPACE_KCMYcm :
2125
        k    = cups->DecodeLUT[c0];
2126
        divk = gx_max_color_value - k;
2127
        if (divk == 0)
2128
        {
2129
          prgb[0] = 0;
2130
          prgb[1] = 0;
2131
          prgb[2] = 0;
2132
        }
2133
        else
2134
        {
2135
          prgb[0] = gx_max_color_value + divk -
2136
                    gx_max_color_value * c1 / divk;
2137
          prgb[1] = gx_max_color_value + divk -
2138
                    gx_max_color_value * c2 / divk;
2139
          prgb[2] = gx_max_color_value + divk -
2140
                    gx_max_color_value * c3 / divk;
2141
        }
2142
        break;
2143
2144
    case CUPS_CSPACE_RGBW :
2145
       /*
2146
        * cups->DecodeLUT actually maps to RGBW, not CMYK...
2147
  */
2148
2149
        if (c3 == 0) {
2150
    c = 0;
2151
    m = 0;
2152
    y = 0;
2153
  } else {
2154
    c = cups->DecodeLUT[c0];
2155
    m = cups->DecodeLUT[c1];
2156
    y = cups->DecodeLUT[c2];
2157
  }
2158
2159
        if (c > gx_max_color_value)
2160
    prgb[0] = gx_max_color_value;
2161
  else if (c < 0)
2162
          prgb[0] = 0;
2163
        else
2164
    prgb[0] = c;
2165
2166
        if (m > gx_max_color_value)
2167
    prgb[1] = gx_max_color_value;
2168
        else if (m < 0)
2169
          prgb[1] = 0;
2170
  else
2171
    prgb[1] = m;
2172
2173
        if (y > gx_max_color_value)
2174
    prgb[2] = gx_max_color_value;
2175
  else if (y < 0)
2176
          prgb[2] = 0;
2177
        else
2178
    prgb[2] = y;
2179
        break;
2180
2181
    case CUPS_CSPACE_CMYK :
2182
        k    = cups->DecodeLUT[c3];
2183
        divk = gx_max_color_value - k;
2184
        if (divk == 0)
2185
        {
2186
          prgb[0] = 0;
2187
          prgb[1] = 0;
2188
          prgb[2] = 0;
2189
        }
2190
        else
2191
        {
2192
          prgb[0] = gx_max_color_value + divk -
2193
                    gx_max_color_value * c0 / divk;
2194
          prgb[1] = gx_max_color_value + divk -
2195
                    gx_max_color_value * c1 / divk;
2196
          prgb[2] = gx_max_color_value + divk -
2197
                    gx_max_color_value * c2 / divk;
2198
        }
2199
        break;
2200
2201
    case CUPS_CSPACE_YMCK :
2202
    case CUPS_CSPACE_GMCK :
2203
    case CUPS_CSPACE_GMCS :
2204
        k    = cups->DecodeLUT[c3];
2205
        divk = gx_max_color_value - k;
2206
        if (divk == 0)
2207
        {
2208
          prgb[0] = 0;
2209
          prgb[1] = 0;
2210
          prgb[2] = 0;
2211
        }
2212
        else
2213
        {
2214
          prgb[0] = gx_max_color_value + divk -
2215
                    gx_max_color_value * c2 / divk;
2216
          prgb[1] = gx_max_color_value + divk -
2217
                    gx_max_color_value * c1 / divk;
2218
          prgb[2] = gx_max_color_value + divk -
2219
                    gx_max_color_value * c0 / divk;
2220
        }
2221
        break;
2222
2223
#  ifdef CUPS_RASTER_HAVE_COLORIMETRIC
2224
    case CUPS_CSPACE_CIEXYZ :
2225
    case CUPS_CSPACE_CIELab :
2226
    case CUPS_CSPACE_ICC1 :
2227
    case CUPS_CSPACE_ICC2 :
2228
    case CUPS_CSPACE_ICC3 :
2229
    case CUPS_CSPACE_ICC4 :
2230
    case CUPS_CSPACE_ICC5 :
2231
    case CUPS_CSPACE_ICC6 :
2232
    case CUPS_CSPACE_ICC7 :
2233
    case CUPS_CSPACE_ICC8 :
2234
    case CUPS_CSPACE_ICC9 :
2235
    case CUPS_CSPACE_ICCA :
2236
    case CUPS_CSPACE_ICCB :
2237
    case CUPS_CSPACE_ICCC :
2238
    case CUPS_CSPACE_ICCD :
2239
    case CUPS_CSPACE_ICCE :
2240
    case CUPS_CSPACE_ICCF :
2241
        break;
2242
#  endif /* CUPS_RASTER_HAVE_COLORIMETRIC */
2243
  }
2244
2245
#ifdef CUPS_DEBUG2
2246
  dmprintf3(pdev->memory, "DEBUG2: RGB values: %d,%d,%d\n",
2247
            prgb[0], prgb[1], prgb[2]);
2248
#endif /* CUPS_DEBUG2 */
2249
2250
  return (0);
2251
}
2252
2253
2254
/*
2255
 * 'cups_map_rgb_color()' - Map an RGB color to a color index.  We map the
2256
 *                          RGB color to the output colorspace & bits (we
2257
 *                          figure out the format when we output a page).
2258
 */
2259
2260
private gx_color_index      /* O - Color index */
2261
cups_map_rgb_color(gx_device      *pdev,/* I - Device info */
2262
                   const gx_color_value cv[3])/* I - RGB color values */
2263
{
2264
  gx_color_index  i;    /* Temporary index */
2265
  gx_color_value        r, g, b;
2266
  gx_color_value  ic, im, iy, ik; /* Integral CMYK values */
2267
  gx_color_value  mk;   /* Maximum K value */
2268
  int     tc, tm, ty; /* Temporary color values */
2269
  float     rr, rg, rb, /* Real RGB colors */
2270
      ciex, ciey, ciez,
2271
          /* CIE XYZ colors */
2272
      ciey_yn,  /* Normalized luminance */
2273
      ciel, ciea, cieb;
2274
          /* CIE Lab colors */
2275
2276
  r = cv[0];
2277
  g = cv[1];
2278
  b = cv[2];
2279
2280
#ifdef CUPS_DEBUG2
2281
  dmprintf4(pdev->memory, "DEBUG2: cups_map_rgb_color(%p, %d, %d, %d)\n",
2282
            pdev, r, g, b);
2283
#endif /* CUPS_DEBUG2 */
2284
2285
 /*
2286
  * Setup the color info data as needed...
2287
  */
2288
2289
  if (pdev->color_info.num_components == 0) {
2290
    if (cups_set_color_info(pdev) < 0)
2291
        return(gx_no_color_index);
2292
  }
2293
2294
 /*
2295
  * Do color correction as needed...
2296
  */
2297
2298
  if (cups->HaveProfile)
2299
  {
2300
   /*
2301
    * Compute CMYK values...
2302
    */
2303
2304
    ic = gx_max_color_value - r;
2305
    im = gx_max_color_value - g;
2306
    iy = gx_max_color_value - b;
2307
    ik = min(ic, min(im, iy));
2308
2309
    if ((mk = max(ic, max(im, iy))) > ik)
2310
      ik = (int)((float)ik * (float)ik * (float)ik / ((float)mk * (float)mk));
2311
2312
    ic -= ik;
2313
    im -= ik;
2314
    iy -= ik;
2315
2316
   /*
2317
    * Color correct CMY...
2318
    */
2319
2320
    tc = cups->Matrix[0][0][ic] +
2321
         cups->Matrix[0][1][im] +
2322
   cups->Matrix[0][2][iy] +
2323
   ik;
2324
    tm = cups->Matrix[1][0][ic] +
2325
         cups->Matrix[1][1][im] +
2326
   cups->Matrix[1][2][iy] +
2327
   ik;
2328
    ty = cups->Matrix[2][0][ic] +
2329
         cups->Matrix[2][1][im] +
2330
   cups->Matrix[2][2][iy] +
2331
   ik;
2332
2333
   /*
2334
    * Density correct combined CMYK...
2335
    */
2336
2337
    if (tc < 0)
2338
      r = gx_max_color_value;
2339
    else if (tc > gx_max_color_value)
2340
      r = gx_max_color_value - cups->Density[gx_max_color_value];
2341
    else
2342
      r = gx_max_color_value - cups->Density[tc];
2343
2344
    if (tm < 0)
2345
      g = gx_max_color_value;
2346
    else if (tm > gx_max_color_value)
2347
      g = gx_max_color_value - cups->Density[gx_max_color_value];
2348
    else
2349
      g = gx_max_color_value - cups->Density[tm];
2350
2351
    if (ty < 0)
2352
      b = gx_max_color_value;
2353
    else if (ty > gx_max_color_value)
2354
      b = gx_max_color_value - cups->Density[gx_max_color_value];
2355
    else
2356
      b = gx_max_color_value - cups->Density[ty];
2357
  }
2358
2359
 /*
2360
  * Convert the RGB color to a color index...
2361
  */
2362
2363
  switch (cups->header.cupsColorSpace)
2364
  {
2365
    case CUPS_CSPACE_W :
2366
    case CUPS_CSPACE_SW :
2367
        i = cups->EncodeLUT[(r * 31 + g * 61 + b * 8) / 100];
2368
        break;
2369
2370
    case CUPS_CSPACE_RGB :
2371
    case CUPS_CSPACE_SRGB :
2372
    case CUPS_CSPACE_ADOBERGB :
2373
        ic = cups->EncodeLUT[r];
2374
        im = cups->EncodeLUT[g];
2375
        iy = cups->EncodeLUT[b];
2376
2377
        switch (cups->header.cupsBitsPerColor)
2378
        {
2379
          default :
2380
              i = (((ic << 1) | im) << 1) | iy;
2381
              break;
2382
          case 2 :
2383
              i = (((ic << 2) | im) << 2) | iy;
2384
              break;
2385
          case 4 :
2386
              i = (((ic << 4) | im) << 4) | iy;
2387
              break;
2388
          case 8 :
2389
              i = (((ic << 8) | im) << 8) | iy;
2390
              break;
2391
#ifdef GX_COLOR_INDEX_TYPE
2392
    case 16 :
2393
        i = (((ic << 16) | im) << 16) | iy;
2394
        break;
2395
#endif /* GX_COLOR_INDEX_TYPE */
2396
        }
2397
        break;
2398
2399
    case CUPS_CSPACE_RGBW :
2400
        if (!r && !g && !b)
2401
  {
2402
   /*
2403
    * Map black to W...
2404
    */
2405
2406
          switch (cups->header.cupsBitsPerColor)
2407
          {
2408
            default :
2409
          i = 0x00;
2410
          break;
2411
            case 2 :
2412
          i = 0x00;
2413
          break;
2414
            case 4 :
2415
          i = 0x0000;
2416
          break;
2417
            case 8 :
2418
          i = 0x00000000;
2419
          break;
2420
#ifdef GX_COLOR_INDEX_TYPE
2421
      case 16 :
2422
    i = 0x0000000000000000;
2423
    break;
2424
#endif /* GX_COLOR_INDEX_TYPE */
2425
          }
2426
    break;
2427
  }
2428
2429
    case CUPS_CSPACE_RGBA :
2430
        ic = cups->EncodeLUT[r];
2431
        im = cups->EncodeLUT[g];
2432
        iy = cups->EncodeLUT[b];
2433
2434
        switch (cups->header.cupsBitsPerColor)
2435
        {
2436
          default :
2437
              i = (((((ic << 1) | im) << 1) | iy) << 1) | 0x01;
2438
              break;
2439
          case 2 :
2440
              i = (((((ic << 2) | im) << 2) | iy) << 2) | 0x03;
2441
              break;
2442
          case 4 :
2443
              i = (((((ic << 4) | im) << 4) | iy) << 4) | 0x0f;
2444
              break;
2445
          case 8 :
2446
              i = (((((ic << 8) | im) << 8) | iy) << 8) | 0xff;
2447
              break;
2448
#ifdef GX_COLOR_INDEX_TYPE
2449
    case 16 :
2450
        i = (((((ic << 16) | im) << 16) | iy) << 16) | 0xffff;
2451
        break;
2452
#endif /* GX_COLOR_INDEX_TYPE */
2453
        }
2454
        break;
2455
2456
    default :
2457
        i = cups->EncodeLUT[gx_max_color_value - (r * 31 + g * 61 + b * 8) / 100];
2458
        break;
2459
2460
    case CUPS_CSPACE_CMY :
2461
        ic = cups->EncodeLUT[gx_max_color_value - r];
2462
        im = cups->EncodeLUT[gx_max_color_value - g];
2463
        iy = cups->EncodeLUT[gx_max_color_value - b];
2464
2465
        switch (cups->header.cupsBitsPerColor)
2466
        {
2467
          default :
2468
              i = (((ic << 1) | im) << 1) | iy;
2469
              break;
2470
          case 2 :
2471
              i = (((ic << 2) | im) << 2) | iy;
2472
              break;
2473
          case 4 :
2474
              i = (((ic << 4) | im) << 4) | iy;
2475
              break;
2476
          case 8 :
2477
              i = (((ic << 8) | im) << 8) | iy;
2478
              break;
2479
#ifdef GX_COLOR_INDEX_TYPE
2480
    case 16 :
2481
        i = (((ic << 16) | im) << 16) | iy;
2482
        break;
2483
#endif /* GX_COLOR_INDEX_TYPE */
2484
        }
2485
        break;
2486
2487
    case CUPS_CSPACE_YMC :
2488
        ic = cups->EncodeLUT[gx_max_color_value - r];
2489
        im = cups->EncodeLUT[gx_max_color_value - g];
2490
        iy = cups->EncodeLUT[gx_max_color_value - b];
2491
2492
        switch (cups->header.cupsBitsPerColor)
2493
        {
2494
          default :
2495
              i = (((iy << 1) | im) << 1) | ic;
2496
              break;
2497
          case 2 :
2498
              i = (((iy << 2) | im) << 2) | ic;
2499
              break;
2500
          case 4 :
2501
              i = (((iy << 4) | im) << 4) | ic;
2502
              break;
2503
          case 8 :
2504
              i = (((iy << 8) | im) << 8) | ic;
2505
              break;
2506
        }
2507
        break;
2508
2509
    case CUPS_CSPACE_CMYK :
2510
  ic = gx_max_color_value - r;
2511
  im = gx_max_color_value - g;
2512
  iy = gx_max_color_value - b;
2513
        ik = min(ic, min(im, iy));
2514
2515
  if ((mk = max(ic, max(im, iy))) > ik)
2516
    ik = (int)((float)ik * (float)ik * (float)ik /
2517
               ((float)mk * (float)mk));
2518
2519
        ic = cups->EncodeLUT[ic - ik];
2520
        im = cups->EncodeLUT[im - ik];
2521
        iy = cups->EncodeLUT[iy - ik];
2522
        ik = cups->EncodeLUT[ik];
2523
2524
        switch (cups->header.cupsBitsPerColor)
2525
        {
2526
          default :
2527
              i = (((((ic << 1) | im) << 1) | iy) << 1) | ik;
2528
              break;
2529
          case 2 :
2530
              i = (((((ic << 2) | im) << 2) | iy) << 2) | ik;
2531
              break;
2532
          case 4 :
2533
              i = (((((ic << 4) | im) << 4) | iy) << 4) | ik;
2534
              break;
2535
          case 8 :
2536
              i = (((((ic << 8) | im) << 8) | iy) << 8) | ik;
2537
              break;
2538
#ifdef GX_COLOR_INDEX_TYPE
2539
    case 16 :
2540
        i = (((((ic << 16) | im) << 16) | iy) << 16) | ik;
2541
        break;
2542
#endif /* GX_COLOR_INDEX_TYPE */
2543
        }
2544
2545
#ifdef CUPS_DEBUG2
2546
        dmprintf8(pdev->memory, "DEBUG2: CMY (%d,%d,%d) -> CMYK %08x (%d,%d,%d,%d)\n",
2547
                  r, g, b, (unsigned)i, ic, im, iy, ik);
2548
#endif /* CUPS_DEBUG2 */
2549
        break;
2550
2551
    case CUPS_CSPACE_YMCK :
2552
    case CUPS_CSPACE_GMCK :
2553
    case CUPS_CSPACE_GMCS :
2554
  ic = gx_max_color_value - r;
2555
  im = gx_max_color_value - g;
2556
  iy = gx_max_color_value - b;
2557
        ik = min(ic, min(im, iy));
2558
2559
  if ((mk = max(ic, max(im, iy))) > ik)
2560
    ik = (int)((float)ik * (float)ik * (float)ik /
2561
               ((float)mk * (float)mk));
2562
2563
        ic = cups->EncodeLUT[ic - ik];
2564
        im = cups->EncodeLUT[im - ik];
2565
        iy = cups->EncodeLUT[iy - ik];
2566
        ik = cups->EncodeLUT[ik];
2567
2568
        switch (cups->header.cupsBitsPerColor)
2569
        {
2570
          default :
2571
              i = (((((iy << 1) | im) << 1) | ic) << 1) | ik;
2572
              break;
2573
          case 2 :
2574
              i = (((((iy << 2) | im) << 2) | ic) << 2) | ik;
2575
              break;
2576
          case 4 :
2577
              i = (((((iy << 4) | im) << 4) | ic) << 4) | ik;
2578
              break;
2579
          case 8 :
2580
              i = (((((iy << 8) | im) << 8) | ic) << 8) | ik;
2581
              break;
2582
#ifdef GX_COLOR_INDEX_TYPE
2583
    case 16 :
2584
        i = (((((iy << 16) | im) << 16) | ic) << 16) | ik;
2585
        break;
2586
#endif /* GX_COLOR_INDEX_TYPE */
2587
        }
2588
        break;
2589
2590
    case CUPS_CSPACE_KCMYcm :
2591
        if (cups->header.cupsBitsPerColor == 1)
2592
  {
2593
    ic = gx_max_color_value - r;
2594
    im = gx_max_color_value - g;
2595
    iy = gx_max_color_value - b;
2596
          ik = min(ic, min(im, iy));
2597
2598
    if ((mk = max(ic, max(im, iy))) > ik)
2599
      ik = (int)((float)ik * (float)ik * (float)ik /
2600
                 ((float)mk * (float)mk));
2601
2602
          ic = cups->EncodeLUT[ic - ik];
2603
          im = cups->EncodeLUT[im - ik];
2604
          iy = cups->EncodeLUT[iy - ik];
2605
          ik = cups->EncodeLUT[ik];
2606
    if (ik)
2607
      i = 32;
2608
    else if (ic && im)
2609
      i = 17;
2610
    else if (ic && iy)
2611
      i = 6;
2612
    else if (im && iy)
2613
      i = 12;
2614
    else if (ic)
2615
      i = 16;
2616
    else if (im)
2617
      i = 8;
2618
    else if (iy)
2619
      i = 4;
2620
    else
2621
      i = 0;
2622
    break;
2623
  }
2624
2625
    case CUPS_CSPACE_KCMY :
2626
  ic = gx_max_color_value - r;
2627
  im = gx_max_color_value - g;
2628
  iy = gx_max_color_value - b;
2629
        ik = min(ic, min(im, iy));
2630
2631
  if ((mk = max(ic, max(im, iy))) > ik)
2632
    ik = (int)((float)ik * (float)ik * (float)ik /
2633
               ((float)mk * (float)mk));
2634
2635
        ic = cups->EncodeLUT[ic - ik];
2636
        im = cups->EncodeLUT[im - ik];
2637
        iy = cups->EncodeLUT[iy - ik];
2638
        ik = cups->EncodeLUT[ik];
2639
2640
        switch (cups->header.cupsBitsPerColor)
2641
        {
2642
          default :
2643
              i = (((((ik << 1) | ic) << 1) | im) << 1) | iy;
2644
              break;
2645
          case 2 :
2646
              i = (((((ik << 2) | ic) << 2) | im) << 2) | iy;
2647
              break;
2648
          case 4 :
2649
              i = (((((ik << 4) | ic) << 4) | im) << 4) | iy;
2650
              break;
2651
          case 8 :
2652
              i = (((((ik << 8) | ic) << 8) | im) << 8) | iy;
2653
              break;
2654
#ifdef GX_COLOR_INDEX_TYPE
2655
    case 16 :
2656
        i = (((((ik << 16) | ic) << 16) | im) << 16) | iy;
2657
        break;
2658
#endif /* GX_COLOR_INDEX_TYPE */
2659
        }
2660
        break;
2661
2662
#  ifdef CUPS_RASTER_HAVE_COLORIMETRIC
2663
    case CUPS_CSPACE_CIEXYZ :
2664
    case CUPS_CSPACE_CIELab :
2665
    case CUPS_CSPACE_ICC1 :
2666
    case CUPS_CSPACE_ICC2 :
2667
    case CUPS_CSPACE_ICC3 :
2668
    case CUPS_CSPACE_ICC4 :
2669
    case CUPS_CSPACE_ICC5 :
2670
    case CUPS_CSPACE_ICC6 :
2671
    case CUPS_CSPACE_ICC7 :
2672
    case CUPS_CSPACE_ICC8 :
2673
    case CUPS_CSPACE_ICC9 :
2674
    case CUPS_CSPACE_ICCA :
2675
    case CUPS_CSPACE_ICCB :
2676
    case CUPS_CSPACE_ICCC :
2677
    case CUPS_CSPACE_ICCD :
2678
    case CUPS_CSPACE_ICCE :
2679
    case CUPS_CSPACE_ICCF :
2680
       /*
2681
        * Convert sRGB to linear RGB...
2682
  */
2683
2684
  rr = pow(((double)r / (double)gx_max_color_value + 0.055) / 1.055, 2.4);
2685
  rg = pow(((double)g / (double)gx_max_color_value + 0.055) / 1.055, 2.4);
2686
  rb = pow(((double)b / (double)gx_max_color_value + 0.055) / 1.055, 2.4);
2687
2688
       /*
2689
        * Convert to CIE XYZ...
2690
  */
2691
2692
  ciex = 0.412453 * rr + 0.357580 * rg + 0.180423 * rb;
2693
  ciey = 0.212671 * rr + 0.715160 * rg + 0.072169 * rb;
2694
  ciez = 0.019334 * rr + 0.119193 * rg + 0.950227 * rb;
2695
2696
        if (cups->header.cupsColorSpace == CUPS_CSPACE_CIEXYZ)
2697
  {
2698
   /*
2699
    * Convert to an integer XYZ color value...
2700
    */
2701
2702
          if (ciex > 1.1)
2703
      ic = 255;
2704
    else if (ciex > 0.0)
2705
      ic = (int)(ciex / 1.1 * 255.0 + 0.5);
2706
    else
2707
      ic = 0;
2708
2709
          if (ciey > 1.1)
2710
      im = 255;
2711
    else if (ciey > 0.0)
2712
      im = (int)(ciey / 1.1 * 255.0 + 0.5);
2713
    else
2714
      im = 0;
2715
2716
          if (ciez > 1.1)
2717
      iy = 255;
2718
    else if (ciez > 0.0)
2719
      iy = (int)(ciez / 1.1 * 255.0 + 0.5);
2720
    else
2721
      iy = 0;
2722
  }
2723
  else
2724
  {
2725
   /*
2726
    * Convert CIE XYZ to Lab...
2727
    */
2728
2729
    ciey_yn = ciey / D65_Y;
2730
2731
    if (ciey_yn > 0.008856)
2732
      ciel = 116 * cbrt(ciey_yn) - 16;
2733
    else
2734
      ciel = 903.3 * ciey_yn;
2735
2736
    ciea = 500 * (cups_map_cielab(ciex, D65_X) -
2737
                  cups_map_cielab(ciey, D65_Y));
2738
    cieb = 200 * (cups_map_cielab(ciey, D65_Y) -
2739
                  cups_map_cielab(ciez, D65_Z));
2740
2741
         /*
2742
    * Scale the L value and bias the a and b values by 128
2743
    * so that all values are in the range of 0 to 255.
2744
    */
2745
2746
    ciel = ciel * 2.55 + 0.5;
2747
    ciea += 128.5;
2748
    cieb += 128.5;
2749
2750
         /*
2751
    * Convert to 8-bit values...
2752
    */
2753
2754
          if (ciel < 0.0)
2755
      ic = 0;
2756
    else if (ciel < 255.0)
2757
      ic = (int)ciel;
2758
    else
2759
      ic = 255;
2760
2761
          if (ciea < 0.0)
2762
      im = 0;
2763
    else if (ciea < 255.0)
2764
      im = (int)ciea;
2765
    else
2766
      im = 255;
2767
2768
          if (cieb < 0.0)
2769
      iy = 0;
2770
    else if (cieb < 255.0)
2771
      iy = (int)cieb;
2772
    else
2773
      iy = 255;
2774
  }
2775
2776
       /*
2777
        * Put the final color value together...
2778
  */
2779
2780
        switch (cups->header.cupsBitsPerColor)
2781
        {
2782
          default :
2783
              i = (((ic << 1) | im) << 1) | iy;
2784
              break;
2785
          case 2 :
2786
              i = (((ic << 2) | im) << 2) | iy;
2787
              break;
2788
          case 4 :
2789
              i = (((ic << 4) | im) << 4) | iy;
2790
              break;
2791
          case 8 :
2792
              i = (((ic << 8) | im) << 8) | iy;
2793
              break;
2794
#ifdef GX_COLOR_INDEX_TYPE
2795
    case 16 :
2796
        i = (((ic << 16) | im) << 16) | iy;
2797
        break;
2798
#endif /* GX_COLOR_INDEX_TYPE */
2799
        }
2800
        break;
2801
#  endif /* CUPS_RASTER_HAVE_COLORIMETRIC */
2802
  }
2803
2804
#ifdef CUPS_DEBUG2
2805
  dmprintf4(pdev->memory, "DEBUG2: RGB %d,%d,%d = %08x\n",
2806
            r, g, b, (unsigned)i);
2807
#endif /* CUPS_DEBUG2 */
2808
2809
  return (i);
2810
}
2811
#endif /* dev_t_proc_encode_color */
2812
2813
2814
/*
2815
 * 'cups_open()' - Open the output file and initialize things.
2816
 */
2817
2818
private int       /* O - Error status */
2819
cups_open(gx_device *pdev)    /* I - Device info */
2820
39.2k
{
2821
39.2k
  int code;       /* Return status */
2822
2823
#ifdef CUPS_DEBUG2
2824
  dmprintf1(pdev->memory, "DEBUG2: cups_open(%p)\n", pdev);
2825
#endif /* CUPS_DEBUG2 */
2826
2827
39.2k
  dmprintf(pdev->memory, "INFO: Start rendering...\n");
2828
39.2k
  cups->printer_procs.get_space_params = cups_get_space_params;
2829
2830
39.2k
  if (cups->page == 0)
2831
39.2k
  {
2832
39.2k
    dmprintf(pdev->memory, "INFO: Processing page 1...\n");
2833
39.2k
    cups->page = 1;
2834
39.2k
  }
2835
2836
39.2k
  if ((code = cups_set_color_info(pdev)) < 0) {
2837
0
    return(code);
2838
0
  }
2839
2840
  /* Establish the default LeadingEdge in the cups header */
2841
39.2k
  cups->header.LeadingEdge = (cups_edge_t)(pdev->LeadingEdge & LEADINGEDGE_MASK);
2842
2843
39.2k
  if ((code = gdev_prn_open(pdev)) != 0)
2844
0
    return(code);
2845
2846
39.2k
  if (cups->PPD == NULL)
2847
39.2k
    cups->PPD = ppdOpenFile(getenv("PPD"));
2848
2849
39.2k
  if (cups->pageSizeRequested[0] == '\0') {
2850
39.2k
    (void) snprintf(cups->pageSizeRequested, sizeof(cups->pageSizeRequested), "%s", cups->header.cupsPageSizeName);
2851
#ifdef CUPS_DEBUG
2852
    dmprintf1(pdev->memory, "DEBUG: Page size requested: %s\n",
2853
        cups->header.cupsPageSizeName);
2854
#endif /* CUPS_DEBUG */
2855
39.2k
  }
2856
2857
39.2k
  return (0);
2858
39.2k
}
2859
2860
2861
/*
2862
 * 'cups_output_page()' - Send one or more pages to the output file.
2863
 * The changes to the cups->page are done here for background printing
2864
 * but testing shows some regressions, so BGPrint is not used for now.
2865
 */
2866
2867
private int       /* O - 0 if everything is OK */
2868
cups_output_page(gx_device *pdev, int num_copies, int flush)
2869
33.2k
{
2870
33.2k
  int   code = 0;   /* Error code */
2871
2872
  /* FIXME: We would like to support BGPrint=true and call gdev_prn_bg_output_page */
2873
  /* but there must still be other things that prevent this. */
2874
33.2k
  if ((code = gdev_prn_output_page(pdev, num_copies, flush)) < 0)
2875
1
      return code;
2876
2877
33.2k
  cups->page ++;
2878
33.2k
  dmprintf1(pdev->memory, "INFO: Processing page %d...\n", cups->page);
2879
2880
33.2k
  return (0);
2881
33.2k
}
2882
2883
2884
/*
2885
 * 'cups_print_pages()' - Send one or more pages to the output file.
2886
 */
2887
2888
private int       /* O - 0 if everything is OK */
2889
cups_print_pages(gx_device_printer *pdev,
2890
          /* I - Device info */
2891
                 gp_file           *fp, /* I - Output file */
2892
     int               num_copies)
2893
          /* I - Number of copies */
2894
33.2k
{
2895
33.2k
  int   code = 0;   /* Error code */
2896
33.2k
  int   copy;     /* Copy number */
2897
33.2k
  int   srcbytes;   /* Byte width of scanline */
2898
33.2k
  unsigned char *src,     /* Scanline data */
2899
33.2k
    *dst;     /* Bitmap data */
2900
33.2k
  ppd_attr_t    *RasterVersion = NULL;  /* CUPS Raster version read from PPD
2901
             file */
2902
2903
33.2k
  (void)fp; /* reference unused file pointer to prevent compiler warning */
2904
2905
#ifdef CUPS_DEBUG2
2906
  dmprintf3(pdev->memory, "DEBUG2: cups_print_pages(%p, %p, %d)\n", pdev, fp,
2907
            num_copies);
2908
#endif /* CUPS_DEBUG2 */
2909
2910
 /*
2911
  * Figure out the number of bytes per line...
2912
  */
2913
2914
33.2k
  switch (cups->header.cupsColorOrder)
2915
33.2k
  {
2916
33.2k
    case CUPS_ORDER_CHUNKED :
2917
33.2k
        cups->header.cupsBytesPerLine = (cups->header.cupsBitsPerPixel *
2918
33.2k
                                   cups->header.cupsWidth + 7) / 8;
2919
33.2k
        break;
2920
2921
0
    case CUPS_ORDER_BANDED :
2922
0
        if (cups->header.cupsColorSpace == CUPS_CSPACE_KCMYcm &&
2923
0
      cups->header.cupsBitsPerColor == 1)
2924
0
          cups->header.cupsBytesPerLine = (cups->header.cupsBitsPerColor *
2925
0
                                           cups->header.cupsWidth + 7) / 8 * 6;
2926
0
        else
2927
0
          cups->header.cupsBytesPerLine = (cups->header.cupsBitsPerColor *
2928
0
                                           cups->header.cupsWidth + 7) / 8 *
2929
0
                  cups->color_info.num_components;
2930
0
        break;
2931
2932
0
    case CUPS_ORDER_PLANAR :
2933
0
        cups->header.cupsBytesPerLine = (cups->header.cupsBitsPerColor *
2934
0
                                   cups->header.cupsWidth + 7) / 8;
2935
0
        break;
2936
33.2k
  }
2937
2938
 /*
2939
  * Compute the width of a scanline and allocate input/output buffers...
2940
  */
2941
2942
33.2k
  srcbytes = gdev_prn_raster(pdev);
2943
2944
#ifdef CUPS_DEBUG2
2945
  dmprintf4(pdev->memory, "DEBUG2: cupsBitsPerPixel = %d, cupsWidth = %d, cupsBytesPerLine = %d, srcbytes = %d\n",
2946
            cups->header.cupsBitsPerPixel, cups->header.cupsWidth,
2947
            cups->header.cupsBytesPerLine, srcbytes);
2948
#endif /* CUPS_DEBUG2 */
2949
2950
33.2k
  src = (unsigned char *)gs_malloc(pdev->memory->non_gc_memory, srcbytes, 1, "cups_print_pages");
2951
2952
33.2k
  if (src == NULL)  /* can't allocate input buffer */
2953
0
    return_error(gs_error_VMerror);
2954
2955
33.2k
  memset(src, 0, srcbytes);
2956
2957
 /*
2958
  * Need an output buffer, too...
2959
  */
2960
2961
33.2k
  dst = (unsigned char *)gs_malloc(pdev->memory->non_gc_memory, cups->header.cupsBytesPerLine, 2,
2962
33.2k
                                   "cups_print_pages");
2963
2964
33.2k
  if (dst == NULL)  /* can't allocate working area */
2965
0
    return_error(gs_error_VMerror);
2966
2967
33.2k
  memset(dst, 0, 2 * cups->header.cupsBytesPerLine);
2968
2969
 /*
2970
  * See if the stream has been initialized yet...
2971
  */
2972
2973
33.2k
  if (cups->stream == NULL)
2974
19.1k
  {
2975
19.1k
    RasterVersion = ppdFindAttr(cups->PPD, "cupsRasterVersion", NULL);
2976
19.1k
    if (RasterVersion) {
2977
#ifdef CUPS_DEBUG2
2978
      dmprintf1(pdev->memory, "DEBUG2: cupsRasterVersion = %s\n",
2979
                RasterVersion->value);
2980
#endif /* CUPS_DEBUG2 */
2981
0
      cups->cupsRasterVersion = atoi(RasterVersion->value);
2982
0
      if ((cups->cupsRasterVersion != 2) &&
2983
0
    (cups->cupsRasterVersion != 3)) {
2984
0
        dmprintf1(pdev->memory, "ERROR: Unsupported CUPS Raster Version: %s",
2985
0
                  RasterVersion->value);
2986
0
  return_error(gs_error_unknownerror);
2987
0
      }
2988
0
    }
2989
    /* NOTE: PWG Raster output is only available with shared CUPS CUPS and
2990
       CUPS image libraries as the built-in libraries of Ghostscript do not
2991
       contain the new code needed for PWG Raster output. This conditional
2992
       is a temporary workaround for the time being until up-to-date CUPS
2993
       libraries get included. */
2994
19.1k
    if ((cups->stream = cupsRasterOpen(fileno(gp_get_file(cups->file)),
2995
19.1k
#if defined(CUPS_RASTER_HAVE_PWGRASTER)
2996
19.1k
                                       (strcasecmp(cups->header.MediaClass,
2997
19.1k
               "PwgRaster") == 0 ?
2998
0
#if defined(CUPS_RASTER_HAVE_APPLERASTER)
2999
0
          (!strcmp(cups->dname, "appleraster") ||
3000
0
           !strcmp(cups->dname, "urf") ?
3001
0
           CUPS_RASTER_WRITE_APPLE :
3002
0
           CUPS_RASTER_WRITE_PWG) :
3003
#else
3004
          CUPS_RASTER_WRITE_PWG :
3005
#endif
3006
19.1k
          (cups->cupsRasterVersion == 3 ?
3007
19.1k
           CUPS_RASTER_WRITE :
3008
19.1k
           CUPS_RASTER_WRITE_COMPRESSED)))) ==
3009
19.1k
  NULL)
3010
#else
3011
                                       (cups->cupsRasterVersion == 3 ?
3012
          CUPS_RASTER_WRITE :
3013
          CUPS_RASTER_WRITE_COMPRESSED))) == NULL)
3014
#endif
3015
0
    {
3016
0
      perror("ERROR: Unable to open raster stream - ");
3017
0
      return_error(gs_error_ioerror);
3018
0
    }
3019
19.1k
  }
3020
3021
 /*
3022
  * Output a page of graphics...
3023
  */
3024
3025
33.2k
  if (num_copies < 1)
3026
0
    num_copies = 1;
3027
3028
33.2k
  if ((cups->PPD == NULL && !cups->cupsManualCopies) ||
3029
33.2k
      (cups->PPD != NULL && !cups->PPD->manual_copies))
3030
33.2k
  {
3031
33.2k
    cups->header.NumCopies = num_copies;
3032
33.2k
    num_copies = 1;
3033
33.2k
  }
3034
3035
#ifdef CUPS_DEBUG
3036
  dmprintf3(pdev->memory, "DEBUG2: cupsWidth = %d, cupsHeight = %d, cupsBytesPerLine = %d\n",
3037
            cups->header.cupsWidth, cups->header.cupsHeight,
3038
            cups->header.cupsBytesPerLine);
3039
#endif /* CUPS_DEBUG */
3040
3041
66.5k
  for (copy = num_copies; copy > 0; copy --)
3042
33.2k
  {
3043
33.2k
    cupsRasterWriteHeader(cups->stream, &(cups->header));
3044
3045
33.2k
    if (pdev->color_info.num_components == 1)
3046
2.43k
      code = cups_print_chunked(pdev, src, dst, srcbytes);
3047
30.8k
    else
3048
30.8k
      switch (cups->header.cupsColorOrder)
3049
30.8k
      {
3050
30.8k
  case CUPS_ORDER_CHUNKED :
3051
30.8k
            code = cups_print_chunked(pdev, src, dst, srcbytes);
3052
30.8k
      break;
3053
0
  case CUPS_ORDER_BANDED :
3054
0
            code = cups_print_banded(pdev, src, dst, srcbytes);
3055
0
      break;
3056
0
  case CUPS_ORDER_PLANAR :
3057
0
            code = cups_print_planar(pdev, src, dst, srcbytes);
3058
0
      break;
3059
30.8k
      }
3060
33.2k
    if (code < 0)
3061
1
      break;
3062
33.2k
  }
3063
3064
 /*
3065
  * Free temporary storage and return...
3066
  */
3067
3068
33.2k
  gs_free(pdev->memory->non_gc_memory, (char *)src, srcbytes, 1, "cups_print_pages");
3069
33.2k
  gs_free(pdev->memory->non_gc_memory, (char *)dst, cups->header.cupsBytesPerLine, 1, "cups_print_pages");
3070
3071
33.2k
 return (code);
3072
33.2k
}
3073
3074
3075
/*
3076
 * 'cups_put_params()' - Set pagedevice parameters.
3077
 */
3078
3079
private int       /* O - Error status */
3080
cups_put_params(gx_device     *pdev,  /* I - Device info */
3081
                gs_param_list *plist) /* I - Parameter list */
3082
348k
{
3083
348k
  int     i;    /* Looping var */
3084
348k
  float     mediasize[2]; /* Physical size of print */
3085
348k
  float     margins[4]; /* Physical margins of print */
3086
348k
  float     cups_mediasize[2]; /* Media size to use in Raster */
3087
348k
  float     cups_margins[4]; /* Margins to use in Raster */
3088
348k
  ppd_size_t    *size;    /* Page size */
3089
348k
  int     code;   /* Error code */
3090
348k
  int     intval;   /* Integer value */
3091
348k
  bool      boolval;  /* Boolean value */
3092
348k
  float     floatval; /* Floating point value */
3093
348k
  gs_param_string stringval;  /* String value */
3094
348k
  gs_param_float_array  arrayval; /* Float array value */
3095
348k
  int     margins_set;  /* Were the margins set? */
3096
348k
  int     size_set; /* Was the size set? */
3097
348k
  int     color_set;  /* Were the color attrs set? */
3098
348k
  gdev_space_params sp_old;         /* Space parameter data */
3099
348k
  int     width,    /* New width of page */
3100
348k
                        height,   /* New height of page */
3101
348k
                        width_old = 0,  /* Previous width of page */
3102
348k
                        height_old = 0; /* Previous height of page */
3103
348k
  bool                  transp_old = 0; /* Previous transparency usage state */
3104
348k
  ppd_attr_t            *backside = NULL,
3105
348k
                        *backsiderequiresflippedmargins = NULL;
3106
348k
  float                 swap;
3107
348k
  int                   xflip = 0,
3108
348k
                        yflip = 0;
3109
348k
  int                   found = 0;
3110
348k
  long                  best_score = -1,
3111
348k
                        score = 0;
3112
348k
  ppd_size_t            *best_size = NULL;
3113
348k
  int                   size_matched = 0,
3114
348k
                        margins_matched = 0,
3115
348k
                        imageable_area_matched = 0;
3116
#ifdef CUPS_DEBUG
3117
  int                   name_requested_matched = 0;
3118
#endif
3119
348k
  float long_edge_mismatch, short_edge_mismatch;
3120
348k
  gs_param_string icc_pro_dummy;
3121
348k
  int old_cmps = cups->color_info.num_components;
3122
348k
  int old_depth = cups->color_info.depth;
3123
348k
#ifdef CUPS_RASTER_SYNCv1
3124
348k
  float     sf;   /* cupsBorderlessScalingFactor */
3125
348k
#endif /* CUPS_RASTER_SYNCv1 */
3126
3127
#ifdef CUPS_DEBUG
3128
  dmprintf2(pdev->memory, "DEBUG2: cups_put_params(%p, %p)\n", pdev, plist);
3129
#endif /* CUPS_DEBUG */
3130
3131
 /*
3132
  * Process other options for CUPS...
3133
  */
3134
3135
348k
#define stringoption(name, sname) \
3136
8.00M
  if ((code = param_read_string(plist, sname, &stringval)) < 0) \
3137
8.00M
  { \
3138
0
    dmprintf1(pdev->memory, "ERROR: Error setting %s...\n", sname);        \
3139
0
    param_signal_error(plist, sname, code); \
3140
0
    goto done; \
3141
0
  } \
3142
8.00M
  else if (code == 0) \
3143
8.00M
  { \
3144
480k
    strncpy(cups->header.name, (const char *)(stringval.data),  \
3145
480k
            stringval.size); \
3146
480k
    cups->header.name[stringval.size] = '\0'; \
3147
480k
  }
3148
3149
348k
#define intoption(name, sname, type) \
3150
11.1M
  if ((code = param_read_int(plist, sname, &intval)) < 0) \
3151
11.1M
  { \
3152
0
    dmprintf1(pdev->memory, "ERROR: Error setting %s ...\n", sname); \
3153
0
    param_signal_error(plist, sname, code); \
3154
0
    goto done; \
3155
0
  } \
3156
11.1M
  else if (code == 0) \
3157
11.1M
  { \
3158
705k
    cups->header.name = (type)intval; \
3159
705k
  }
3160
3161
348k
#define floatoption(name, sname) \
3162
5.91M
  if ((code = param_read_float(plist, sname, &floatval)) < 0) \
3163
5.91M
  { \
3164
0
    dmprintf1(pdev->memory, "ERROR: Error setting %s ...\n", sname); \
3165
0
    param_signal_error(plist, sname, code); \
3166
0
    goto done; \
3167
0
  } \
3168
5.91M
  else if (code == 0) \
3169
5.91M
  { \
3170
355k
    cups->header.name = (float)floatval; \
3171
355k
  }
3172
3173
348k
#define booloption(name, sname) \
3174
3.48M
  if ((code = param_read_bool(plist, sname, &boolval)) < 0) \
3175
3.48M
  { \
3176
0
    if ((code = param_read_null(plist, sname)) < 0) \
3177
0
    { \
3178
0
      dmprintf1(pdev->memory, "ERROR: Error setting %s ...\n", sname); \
3179
0
      param_signal_error(plist, sname, code); \
3180
0
      goto done; \
3181
0
    } \
3182
0
    if (code == 0) \
3183
0
      cups->header.name = CUPS_FALSE; \
3184
0
  } \
3185
3.48M
  else if (code == 0) \
3186
3.48M
  { \
3187
208k
    cups->header.name = (cups_bool_t)boolval; \
3188
208k
  }
3189
3190
348k
#define arrayoption(name, sname, count) \
3191
696k
  if ((code = param_read_float_array(plist, sname, &arrayval)) < 0) \
3192
696k
  { \
3193
0
    if ((code = param_read_null(plist, sname)) < 0) \
3194
0
    { \
3195
0
      dmprintf1(pdev->memory, "ERROR: Error setting %s...\n", sname); \
3196
0
      param_signal_error(plist, sname, code); \
3197
0
      goto done; \
3198
0
    } \
3199
0
    if (code == 0) \
3200
0
    { \
3201
0
      for (i = 0; i < count; i ++) \
3202
0
  cups->header.name[i] = 0; \
3203
0
    } \
3204
0
  } \
3205
696k
  else if (code == 0) \
3206
696k
  { \
3207
62.6k
    for (i = 0; i < count; i ++) { \
3208
41.7k
      cups->header.name[i] = (unsigned)(arrayval.data[i]); \
3209
41.7k
    } \
3210
20.8k
  }
3211
3212
348k
  sp_old = ((gx_device_printer *)pdev)->space_params;
3213
348k
  width_old = pdev->width;
3214
348k
  height_old = pdev->height;
3215
348k
  transp_old = cups->page_uses_transparency;
3216
348k
  size_set    = param_read_float_array(plist, ".MediaSize", &arrayval) == 0 ||
3217
348k
                param_read_float_array(plist, "PageSize", &arrayval) == 0;
3218
348k
  margins_set = param_read_float_array(plist, "Margins", &arrayval) == 0;
3219
348k
  color_set   = param_read_int(plist, "cupsColorSpace", &intval) == 0 ||
3220
348k
                param_read_int(plist, "cupsBitsPerColor", &intval) == 0;
3221
3222
348k
  if (!cups->user_icc) {
3223
316k
      cups->user_icc = param_read_string(plist, "OutputICCProfile", &icc_pro_dummy) == 0;
3224
316k
  }
3225
3226
  /* We also recompute page size and margins if we simply get onto a new
3227
     page without necessarily having a page size change in the PostScript
3228
     code, as for some printers margins have to be flipped on the back sides of
3229
     the sheets (even pages) when printing duplex */
3230
348k
  if (cups->page != cups->lastpage) {
3231
52.0k
    size_set = 1;
3232
52.0k
    cups->lastpage = cups->page;
3233
52.0k
  }
3234
3235
348k
  stringoption(MediaClass, "MediaClass")
3236
348k
  stringoption(MediaColor, "MediaColor")
3237
348k
  stringoption(MediaType, "MediaType")
3238
348k
  stringoption(OutputType, "OutputType")
3239
348k
  intoption(AdvanceDistance, "AdvanceDistance", unsigned)
3240
348k
  intoption(AdvanceMedia, "AdvanceMedia", cups_adv_t)
3241
348k
  booloption(Collate, "Collate")
3242
348k
  intoption(CutMedia, "CutMedia", cups_cut_t)
3243
348k
  booloption(Duplex, "Duplex")
3244
348k
  arrayoption(ImagingBoundingBox, "ImagingBoundingBox", 4)
3245
348k
  booloption(InsertSheet, "InsertSheet")
3246
348k
  intoption(Jog, "Jog", cups_jog_t)
3247
348k
  arrayoption(Margins, "Margins", 2)
3248
348k
  booloption(ManualFeed, "ManualFeed")
3249
348k
  intoption(MediaPosition, "cupsMediaPosition", unsigned) /* Compatibility */
3250
348k
  intoption(MediaPosition, "MediaPosition", unsigned)
3251
348k
  intoption(MediaWeight, "MediaWeight", unsigned)
3252
348k
  booloption(MirrorPrint, "MirrorPrint")
3253
348k
  booloption(NegativePrint, "NegativePrint")
3254
348k
  intoption(Orientation, "Orientation", cups_orient_t)
3255
348k
  booloption(OutputFaceUp, "OutputFaceUp")
3256
348k
  booloption(Separations, "Separations")
3257
348k
  booloption(TraySwitch, "TraySwitch")
3258
348k
  booloption(Tumble, "Tumble")
3259
348k
  intoption(cupsMediaType, "cupsMediaType", unsigned)
3260
348k
  intoption(cupsBitsPerColor, "cupsBitsPerColor", unsigned)
3261
348k
  intoption(cupsColorOrder, "cupsColorOrder", cups_order_t)
3262
348k
  intoption(cupsColorSpace, "cupsColorSpace", cups_cspace_t)
3263
348k
  intoption(cupsCompression, "cupsCompression", unsigned)
3264
348k
  intoption(cupsRowCount, "cupsRowCount", unsigned)
3265
348k
  intoption(cupsRowFeed, "cupsRowFeed", unsigned)
3266
348k
  intoption(cupsRowStep, "cupsRowStep", unsigned)
3267
3268
348k
#ifdef GX_COLOR_INDEX_TYPE
3269
 /*
3270
  * Support cupsPreferredBitsPerColor - basically, allows you to
3271
  * request 16-bits per color in a backwards-compatible way...
3272
  */
3273
3274
348k
  if (!param_read_int(plist, "cupsPreferredBitsPerColor", &intval))
3275
0
    if (intval > cups->header.cupsBitsPerColor && intval <= 16)
3276
0
      cups->header.cupsBitsPerColor = intval;
3277
348k
#endif /* GX_COLOR_INDEX_TYPE */
3278
3279
348k
#ifdef CUPS_RASTER_SYNCv1
3280
348k
  floatoption(cupsBorderlessScalingFactor, "cupsBorderlessScalingFactor");
3281
3282
5.91M
  for (i = 0; cups_Integer_strings[i] != NULL; i ++)
3283
5.56M
  {
3284
5.56M
    intoption(cupsInteger[i], cups_Integer_strings[i], unsigned)
3285
5.56M
  }
3286
3287
5.91M
  for (i = 0; cups_Real_strings[i] != NULL; i ++)
3288
5.56M
  {
3289
5.56M
    floatoption(cupsReal[i], cups_Real_strings[i])
3290
5.56M
  }
3291
3292
5.91M
  for (i = 0; cups_String_strings[i] != NULL; i ++)
3293
5.56M
  {
3294
5.56M
    stringoption(cupsString[i], cups_String_strings[i])
3295
5.56M
  }
3296
3297
348k
  stringoption(cupsMarkerType, "cupsMarkerType");
3298
348k
  stringoption(cupsRenderingIntent, "cupsRenderingIntent");
3299
348k
  stringoption(cupsPageSizeName, "cupsPageSizeName");
3300
348k
#endif /* CUPS_RASTER_SYNCv1 */
3301
3302
348k
  if ((code = param_read_string(plist, "cupsProfile", &stringval)) < 0)
3303
0
  {
3304
0
    param_signal_error(plist, "cupsProfile", code);
3305
0
    goto done;
3306
0
  }
3307
348k
  else if (code == 0)
3308
0
  {
3309
0
    if (cups->Profile != NULL)
3310
0
      free(cups->Profile);
3311
3312
0
    cups->Profile = strdup((char *)stringval.data);
3313
0
  }
3314
3315
348k
  if ((code = cups_set_color_info(pdev)) < 0) {
3316
20
      goto done;
3317
20
  }
3318
3319
 /*
3320
  * Variables for PPD-less use only. If these settings are defined in the
3321
  * PPD file, the PPD file's definitions get priority.
3322
  */
3323
3324
348k
  if ((code = param_read_int(plist, "cupsRasterVersion", &intval)) < 0)
3325
0
  {
3326
0
    dmprintf1(pdev->memory, "ERROR: Error setting %s ...\n",
3327
0
        "cupsRasterVersion");
3328
0
    param_signal_error(plist, "cupsRasterVersion", code); \
3329
0
    goto done;
3330
0
  }
3331
348k
  else if (code == 0)
3332
20.8k
    cups->cupsRasterVersion = (int)intval;
3333
3334
348k
  if ((code = param_read_string(plist, "cupsBackSideOrientation",
3335
348k
        &stringval)) < 0)
3336
0
  {
3337
0
    dmprintf1(pdev->memory, "ERROR: Error setting %s...\n",
3338
0
        "cupsBackSideOrientation");
3339
0
    param_signal_error(plist, "cupsBackSideOrientation", code);
3340
0
    goto done;
3341
0
  }
3342
348k
  else if (code == 0)
3343
20.8k
  {
3344
20.8k
    intval = min(sizeof(cups->cupsBackSideOrientation) - 1, stringval.size);
3345
20.8k
    strncpy(cups->cupsBackSideOrientation, (const char *)(stringval.data),
3346
20.8k
      intval);
3347
20.8k
    cups->cupsBackSideOrientation[intval] = '\0';
3348
20.8k
  }
3349
3350
348k
  if ((code = param_read_bool(plist, "cupsBackSideFlipMargins",
3351
348k
            &boolval)) < 0)
3352
0
  {
3353
0
    if ((code = param_read_null(plist, "cupsBackSideFlipMargins")) < 0)
3354
0
    {
3355
0
      dmprintf1(pdev->memory, "ERROR: Error setting %s ...\n",
3356
0
    "cupsBackSideFlipMargins");
3357
0
      param_signal_error(plist, "cupsBackSideFlipMargins", code);
3358
0
      goto done;
3359
0
    }
3360
0
    if (code == 0)
3361
0
      cups->cupsBackSideFlipMargins = CUPS_FALSE;
3362
0
  }
3363
348k
  else if (code == 0)
3364
20.8k
    cups->cupsBackSideFlipMargins = (cups_bool_t)boolval;
3365
3366
348k
  if ((code = param_read_bool(plist, "cupsManualCopies",
3367
348k
            &boolval)) < 0)
3368
0
  {
3369
0
    if ((code = param_read_null(plist, "cupsManualCopies")) < 0)
3370
0
    {
3371
0
      dmprintf1(pdev->memory, "ERROR: Error setting %s ...\n",
3372
0
    "cupsManualCopies");
3373
0
      param_signal_error(plist, "cupsManualCopies", code);
3374
0
      goto done;
3375
0
    }
3376
0
    if (code == 0)
3377
0
      cups->cupsManualCopies = CUPS_FALSE;
3378
0
  }
3379
348k
  else if (code == 0)
3380
20.8k
    cups->cupsManualCopies = (cups_bool_t)boolval;
3381
3382
  /*
3383
  * Then process standard page device options...
3384
  */
3385
3386
348k
  if ((code = gdev_prn_put_params(pdev, plist)) < 0)
3387
94
    goto done;
3388
3389
347k
  cups->header.LeadingEdge = (cups_edge_t)(pdev->LeadingEdge & LEADINGEDGE_MASK);
3390
3391
  /* If cups_set_color_info() changed the color model of the device we want to
3392
   * force the raster memory to be recreated/reinitialized
3393
   */
3394
347k
  if (cups->color_info.num_components != old_cmps || cups->color_info.depth != old_depth) {
3395
35.7k
      width_old = 0;
3396
35.7k
      height_old = 0;
3397
35.7k
  }
3398
312k
  else {
3399
  /* pdev->width/height may have been changed by the call to
3400
   * gdev_prn_put_params()
3401
   */
3402
312k
     width_old = pdev->width;
3403
312k
     height_old = pdev->height;
3404
312k
  }
3405
 /*
3406
  * Update margins/sizes as needed...
3407
  */
3408
3409
347k
  if (size_set)
3410
250k
  {
3411
   /*
3412
    * Compute the page margins...
3413
    */
3414
3415
#ifdef CUPS_DEBUG
3416
    dmprintf2(pdev->memory, "DEBUG: Updating PageSize to [%.0f %.0f]...\n",
3417
              cups->MediaSize[0], cups->MediaSize[1]);
3418
#endif /* CUPS_DEBUG */
3419
3420
250k
    memset(margins, 0, sizeof(margins));
3421
3422
250k
    cups->landscape = 0;
3423
3424
250k
    if (cups->PPD != NULL)
3425
0
    {
3426
#ifdef CUPS_DEBUG
3427
      dmprintf1(pdev->memory, "DEBUG2: cups->header.Duplex = %d\n", cups->header.Duplex);
3428
      dmprintf1(pdev->memory, "DEBUG2: cups->header.Tumble = %d\n", cups->header.Tumble);
3429
      dmprintf1(pdev->memory, "DEBUG2: cups->page = %d\n", cups->page);
3430
      dmprintf1(pdev->memory, "DEBUG2: cups->PPD = %p\n", cups->PPD);
3431
#endif /* CUPS_DEBUG */
3432
3433
0
      backside = ppdFindAttr(cups->PPD, "cupsBackSide", NULL);
3434
0
      if (backside) {
3435
#ifdef CUPS_DEBUG
3436
        dmprintf1(pdev->memory, "DEBUG2: cupsBackSide = %s\n", backside->value);
3437
#endif /* CUPS_DEBUG */
3438
0
  cups->PPD->flip_duplex = 0;
3439
0
      }
3440
#ifdef CUPS_DEBUG
3441
      dmprintf1(pdev->memory, "DEBUG2: cups->PPD->flip_duplex = %d\n", cups->PPD->flip_duplex);
3442
#endif /* CUPS_DEBUG */
3443
3444
0
      backsiderequiresflippedmargins =
3445
0
  ppdFindAttr(cups->PPD, "APDuplexRequiresFlippedMargin", NULL);
3446
#ifdef CUPS_DEBUG
3447
      if (backsiderequiresflippedmargins)
3448
        dmprintf1(pdev->memory, "DEBUG2: APDuplexRequiresFlippedMargin = %s\n",
3449
                  backsiderequiresflippedmargins->value);
3450
#endif /* CUPS_DEBUG */
3451
3452
0
      if (cups->header.Duplex &&
3453
0
    (cups->header.Tumble &&
3454
0
     (backside && !strcasecmp(backside->value, "Flipped"))) &&
3455
0
    !(cups->page & 1))
3456
0
      {
3457
0
  xflip = 1;
3458
0
  if (backsiderequiresflippedmargins &&
3459
0
      !strcasecmp(backsiderequiresflippedmargins->value, "False")) {
3460
#ifdef CUPS_DEBUG
3461
          dmprintf(pdev->memory, "DEBUG2: (1) Flip: X=1 Y=0\n");
3462
#endif /* CUPS_DEBUG */
3463
0
    yflip = 0;
3464
0
  } else {
3465
#ifdef CUPS_DEBUG
3466
          dmprintf(pdev->memory, "DEBUG2: (1) Flip: X=1 Y=1\n");
3467
#endif /* CUPS_DEBUG */
3468
0
    yflip = 1;
3469
0
  }
3470
0
      }
3471
0
      else if (cups->header.Duplex &&
3472
0
         (!cups->header.Tumble &&
3473
0
    (backside && !strcasecmp(backside->value, "Flipped"))) &&
3474
0
         !(cups->page & 1))
3475
0
      {
3476
0
  xflip = 0;
3477
0
  if (backsiderequiresflippedmargins &&
3478
0
      !strcasecmp(backsiderequiresflippedmargins->value, "False")) {
3479
#ifdef CUPS_DEBUG
3480
          dmprintf(pdev->memory, "DEBUG2: (2) Flip: X=0 Y=1\n");
3481
#endif /* CUPS_DEBUG */
3482
0
    yflip = 1;
3483
0
  } else {
3484
#ifdef CUPS_DEBUG
3485
          dmprintf(pdev->memory, "DEBUG2: (2) Flip: X=0 Y=0\n");
3486
#endif /* CUPS_DEBUG */
3487
0
    yflip = 0;
3488
0
  }
3489
0
      }
3490
0
      else if (cups->header.Duplex &&
3491
0
         ((!cups->header.Tumble &&
3492
0
     (cups->PPD->flip_duplex ||
3493
0
      (backside && !strcasecmp(backside->value, "Rotated")))) ||
3494
0
    (cups->header.Tumble &&
3495
0
     (backside && !strcasecmp(backside->value, "ManualTumble")))) &&
3496
0
         !(cups->page & 1))
3497
0
      {
3498
0
  xflip = 1;
3499
0
  if (backsiderequiresflippedmargins &&
3500
0
      !strcasecmp(backsiderequiresflippedmargins->value, "True")) {
3501
#ifdef CUPS_DEBUG
3502
          dmprintf(pdev->memory, "DEBUG2: (3) Flip: X=1 Y=0\n");
3503
#endif /* CUPS_DEBUG */
3504
0
    yflip = 0;
3505
0
  } else {
3506
#ifdef CUPS_DEBUG
3507
          dmprintf(pdev->memory, "DEBUG2: (3) Flip: X=1 Y=1\n");
3508
#endif /* CUPS_DEBUG */
3509
0
    yflip = 1;
3510
0
  }
3511
0
      }
3512
0
      else
3513
0
      {
3514
#ifdef CUPS_DEBUG
3515
        dmprintf(pdev->memory, "DEBUG2: (4) Flip: X=0 Y=0\n");
3516
#endif /* CUPS_DEBUG */
3517
0
  xflip = 0;
3518
0
  yflip = 0;
3519
0
      }
3520
3521
     /*
3522
      * Find the matching page size...
3523
      */
3524
3525
0
#define LONG_EDGE_LENGTH_MATCH_LIMIT  0.01
3526
0
#define SHORT_EDGE_LENGTH_MATCH_LIMIT 0.01
3527
0
#define PAGESIZE_SCORE_SIZE_MARGINS   2
3528
0
#define PAGESIZE_SCORE_SIZE           1
3529
3530
0
      best_score = -1;
3531
0
      best_size = NULL;
3532
      /* Match against the PPD's page size only if the page size name does
3533
   not suggest that we use a custom page size */
3534
0
      if (strncasecmp(cups->header.cupsPageSizeName, "Custom", 6) != 0 ||
3535
0
    (cups->header.cupsPageSizeName[6] != '\0' &&
3536
0
     cups->header.cupsPageSizeName[6] != '.'))
3537
0
      {
3538
0
#ifdef CUPS_RASTER_SYNCv1
3539
       /*
3540
  * Chack whether cupsPageSizeName has a valid value
3541
  */
3542
3543
0
  if (strlen(cups->header.cupsPageSizeName) != 0) {
3544
0
    found = 0;
3545
0
    for (i = cups->PPD->num_sizes, size = cups->PPD->sizes;
3546
0
         i > 0;
3547
0
         i --, size ++)
3548
0
      if (strcasecmp(cups->header.cupsPageSizeName, size->name) == 0) {
3549
0
        found = 1;
3550
0
        break;
3551
0
      }
3552
0
    if (found == 0) cups->header.cupsPageSizeName[0] = '\0';
3553
0
  }
3554
#ifdef CUPS_DEBUG
3555
  dmprintf1(pdev->memory, "DEBUG2: cups->header.cupsPageSizeName = %s\n",
3556
      cups->header.cupsPageSizeName);
3557
#endif /* CUPS_DEBUG */
3558
0
#endif /* CUPS_RASTER_SYNCv1 */
3559
3560
0
  for (i = cups->PPD->num_sizes, size = cups->PPD->sizes;
3561
0
       i > 0;
3562
0
       i --, size ++)
3563
0
        {
3564
0
    if (size->length == 0 || size->width == 0) continue;
3565
3566
0
    score = 0;
3567
0
    size_matched = 0;
3568
0
    margins_matched = 0;
3569
0
    imageable_area_matched = 0;
3570
#ifdef CUPS_DEBUG
3571
    name_requested_matched = 0;
3572
#endif
3573
3574
0
    long_edge_mismatch =
3575
0
      fabs(cups->MediaSize[1] - size->length)/size->length +
3576
0
      LONG_EDGE_LENGTH_MATCH_LIMIT / 100;
3577
0
    short_edge_mismatch =
3578
0
      fabs(cups->MediaSize[0] - size->width)/size->width +
3579
0
      SHORT_EDGE_LENGTH_MATCH_LIMIT / 100;
3580
0
    if (size->length < size->width)
3581
0
    {
3582
0
      swap = long_edge_mismatch;
3583
0
      long_edge_mismatch = short_edge_mismatch;
3584
0
      short_edge_mismatch = swap;
3585
0
    }
3586
3587
0
    if (long_edge_mismatch < LONG_EDGE_LENGTH_MATCH_LIMIT &&
3588
0
        short_edge_mismatch < SHORT_EDGE_LENGTH_MATCH_LIMIT)
3589
0
    {
3590
0
      size_matched = 1;
3591
      /* If two sizes match within the limits, take the one with less
3592
         mismatch */
3593
0
      score = (long)(9999.0 -
3594
0
         long_edge_mismatch * short_edge_mismatch * 9999.0 /
3595
0
         LONG_EDGE_LENGTH_MATCH_LIMIT /
3596
0
         SHORT_EDGE_LENGTH_MATCH_LIMIT);
3597
0
      if (score < 0) score = 0;
3598
      /* We check whether all 4 margins match with the margin info
3599
         of the page size in the PPD. Here we check also for swapped
3600
         left/right and top/bottom margins as the cups->HWMargins
3601
         info can be from the previous page and there the margins
3602
         can be swapped due to duplex printing requirements */
3603
0
      if (!margins_set ||
3604
0
    (((fabs(cups->HWMargins[0] - size->left) < 1.0 &&
3605
0
       fabs(cups->HWMargins[2] - size->width + size->right) < 1.0) ||
3606
0
      (fabs(cups->HWMargins[0] - size->width + size->right) < 1.0 &&
3607
0
       fabs(cups->HWMargins[2] - size->left) < 1.0)) &&
3608
0
     ((fabs(cups->HWMargins[1] - size->bottom) < 1.0 &&
3609
0
       fabs(cups->HWMargins[3] - size->length + size->top) < 1.0) ||
3610
0
      (fabs(cups->HWMargins[1] - size->length + size->top) < 1.0 &&
3611
0
       fabs(cups->HWMargins[3] - size->bottom) < 1.0))))
3612
0
        margins_matched = 1;
3613
0
    } else {
3614
      /* Compare the dimensions of the imageable area against the
3615
         the input page size */
3616
0
      long_edge_mismatch =
3617
0
        fabs(cups->MediaSize[1] - size->top + size->bottom)/size->length +
3618
0
        LONG_EDGE_LENGTH_MATCH_LIMIT / 100;
3619
0
      short_edge_mismatch =
3620
0
        fabs(cups->MediaSize[0] - size->right + size->left)/size->width +
3621
0
        SHORT_EDGE_LENGTH_MATCH_LIMIT / 100;
3622
0
      if (size->length < size->width)
3623
0
      {
3624
0
        swap = long_edge_mismatch;
3625
0
        long_edge_mismatch = short_edge_mismatch;
3626
0
        short_edge_mismatch = swap;
3627
0
      }
3628
3629
0
      if (long_edge_mismatch < LONG_EDGE_LENGTH_MATCH_LIMIT &&
3630
0
    short_edge_mismatch < SHORT_EDGE_LENGTH_MATCH_LIMIT)
3631
0
      {
3632
0
        imageable_area_matched = 1;
3633
        /* If two sizes match within the limits, take the one with less
3634
     mismatch */
3635
0
        score = (long)(4999.0 -
3636
0
           long_edge_mismatch * short_edge_mismatch * 4999.0 /
3637
0
           LONG_EDGE_LENGTH_MATCH_LIMIT /
3638
0
           SHORT_EDGE_LENGTH_MATCH_LIMIT);
3639
0
        if (score < 0) score = 0;
3640
0
      }
3641
0
    }
3642
3643
0
    if (margins_matched)
3644
0
      score += PAGESIZE_SCORE_SIZE_MARGINS * 10000;
3645
0
    else if (size_matched)
3646
0
      score += PAGESIZE_SCORE_SIZE * 10000;
3647
3648
0
    if (size_matched || imageable_area_matched) {
3649
0
      if (!strcasecmp(cups->pageSizeRequested, size->name))
3650
0
      {
3651
#ifdef CUPS_DEBUG
3652
        name_requested_matched = 1;
3653
#endif
3654
0
      }
3655
0
      else
3656
0
        score -= 1000;
3657
0
    }
3658
3659
0
    if (score > best_score)
3660
0
    {
3661
0
      best_score = score;
3662
0
      if (score > 0)
3663
0
        best_size = size;
3664
0
    }
3665
#ifdef CUPS_DEBUG
3666
    dmprintf1(pdev->memory, "DEBUG2: Checking against PPD page size (portrait): %s\n",
3667
        size->name);
3668
    dmprintf2(pdev->memory, "DEBUG2:    Width: %.2f; Height: %.2f\n",
3669
        size->width, size->length);
3670
    dmprintf4(pdev->memory, "DEBUG2:    Margins: Left: %.2f; Right: %.2f; Top: %.2f; Bottom: %.2f\n",
3671
        size->left, size->right, size->top, size->bottom);
3672
    dmprintf4(pdev->memory, "DEBUG2:    Size mismatch: Long Edge (%.3f): %.5f; Short Edge (%.3f): %.5f\n",
3673
        LONG_EDGE_LENGTH_MATCH_LIMIT, long_edge_mismatch,
3674
        SHORT_EDGE_LENGTH_MATCH_LIMIT, short_edge_mismatch);
3675
    dmprintf4(pdev->memory, "DEBUG2:    Match: Size: %d; Margins: %d; Imageable Area: %d; Name requested: %d\n",
3676
        size_matched, margins_matched, imageable_area_matched,
3677
        name_requested_matched);
3678
    dmprintf2(pdev->memory, "DEBUG2:    Score: %ld; Best Score: %ld\n",
3679
        score, best_score);
3680
#endif /* CUPS_DEBUG */
3681
0
  }
3682
3683
0
  if (best_size)
3684
0
  {
3685
   /*
3686
    * Standard size...
3687
    */
3688
3689
#ifdef CUPS_DEBUG
3690
    dmprintf1(pdev->memory, "DEBUG: size = %s\n", best_size->name);
3691
#endif /* CUPS_DEBUG */
3692
3693
0
    mediasize[0] = best_size->width;
3694
0
    mediasize[1] = best_size->length;
3695
3696
0
    cups->landscape = 0;
3697
3698
0
#ifdef CUPS_RASTER_SYNCv1
3699
0
    strncpy(cups->header.cupsPageSizeName, best_size->name,
3700
0
      sizeof(cups->header.cupsPageSizeName));
3701
0
    cups->header.cupsPageSizeName[sizeof(cups->header.cupsPageSizeName) - 1] =
3702
0
      '\0';
3703
3704
0
    if (strcasecmp(cups->header.MediaClass, "PwgRaster") != 0)
3705
0
    {
3706
0
#endif
3707
0
      margins[0] = best_size->left / 72.0;
3708
0
      margins[1] = best_size->bottom / 72.0;
3709
0
      margins[2] = (best_size->width - best_size->right) / 72.0;
3710
0
      margins[3] = (best_size->length - best_size->top) / 72.0;
3711
0
      if (xflip == 1)
3712
0
      {
3713
0
        swap = margins[0]; margins[0] = margins[2]; margins[2] = swap;
3714
0
      }
3715
0
      if (yflip == 1)
3716
0
      {
3717
0
        swap = margins[1]; margins[1] = margins[3]; margins[3] = swap;
3718
0
      }
3719
0
#ifdef CUPS_RASTER_SYNCv1
3720
0
    }
3721
0
    else
3722
0
    {
3723
0
      margins[0] = 0.0;
3724
0
      margins[1] = 0.0;
3725
0
      margins[2] = 0.0;
3726
0
      margins[3] = 0.0;
3727
0
    }
3728
0
#endif
3729
0
  }
3730
0
  else
3731
0
  {
3732
   /*
3733
    * No matching portrait size; look for a matching size in
3734
    * landscape orientation...
3735
    */
3736
3737
0
    best_score = -1;
3738
0
    best_size = NULL;
3739
0
    for (i = cups->PPD->num_sizes, size = cups->PPD->sizes;
3740
0
         i > 0;
3741
0
         i --, size ++)
3742
0
    {
3743
0
      if (size->length == 0 || size->width == 0) continue;
3744
3745
0
      score = 0;
3746
0
      size_matched = 0;
3747
0
      margins_matched = 0;
3748
0
      imageable_area_matched = 0;
3749
#ifdef CUPS_DEBUG
3750
      name_requested_matched = 0;
3751
#endif
3752
3753
0
      long_edge_mismatch =
3754
0
        fabs(cups->MediaSize[0] - size->length)/size->length +
3755
0
        LONG_EDGE_LENGTH_MATCH_LIMIT / 100;
3756
0
      short_edge_mismatch =
3757
0
        fabs(cups->MediaSize[1] - size->width)/size->width +
3758
0
        SHORT_EDGE_LENGTH_MATCH_LIMIT / 100;
3759
0
      if (size->length < size->width)
3760
0
      {
3761
0
        swap = long_edge_mismatch;
3762
0
        long_edge_mismatch = short_edge_mismatch;
3763
0
        short_edge_mismatch = swap;
3764
0
      }
3765
3766
0
      if (long_edge_mismatch < LONG_EDGE_LENGTH_MATCH_LIMIT &&
3767
0
    short_edge_mismatch < SHORT_EDGE_LENGTH_MATCH_LIMIT)
3768
0
      {
3769
0
        size_matched = 1;
3770
        /* If two sizes match within the limits, take the one with less
3771
     mismatch */
3772
0
        score = (long)(9999.0 -
3773
0
           long_edge_mismatch * short_edge_mismatch * 9999.0 /
3774
0
           LONG_EDGE_LENGTH_MATCH_LIMIT /
3775
0
           SHORT_EDGE_LENGTH_MATCH_LIMIT);
3776
0
        if (score < 0) score = 0;
3777
        /* We check whether all 4 margins match with the margin info
3778
     of the page size in the PPD. Here we check also for swapped
3779
     left/right and top/bottom margins as the cups->HWMargins
3780
     info can be from the previous page and there the margins
3781
     can be swapped due to duplex printing requirements */
3782
0
        if (!margins_set ||
3783
0
      (((fabs(cups->HWMargins[1] - size->left) < 1.0 &&
3784
0
         fabs(cups->HWMargins[3] - size->width + size->right) < 1.0)||
3785
0
        (fabs(cups->HWMargins[1] - size->width + size->right) < 1.0 &&
3786
0
         fabs(cups->HWMargins[3] - size->left) < 1.0)) &&
3787
0
       ((fabs(cups->HWMargins[0] - size->bottom) < 1.0 &&
3788
0
         fabs(cups->HWMargins[2] - size->length + size->top) < 1.0) ||
3789
0
        (fabs(cups->HWMargins[0] - size->length + size->top) < 1.0 &&
3790
0
         fabs(cups->HWMargins[2] - size->bottom) < 1.0))))
3791
0
    margins_matched = 1;
3792
0
      } else {
3793
        /* Compare the dimensions of the imageable area against the
3794
     the input page size */
3795
0
        long_edge_mismatch =
3796
0
    fabs(cups->MediaSize[0] - size->top + size->bottom)/size->length +
3797
0
    LONG_EDGE_LENGTH_MATCH_LIMIT / 100;
3798
0
        short_edge_mismatch =
3799
0
    fabs(cups->MediaSize[1] - size->right + size->left)/size->width +
3800
0
    SHORT_EDGE_LENGTH_MATCH_LIMIT / 100;
3801
0
        if (size->length < size->width)
3802
0
        {
3803
0
    swap = long_edge_mismatch;
3804
0
    long_edge_mismatch = short_edge_mismatch;
3805
0
    short_edge_mismatch = swap;
3806
0
        }
3807
3808
0
        if (long_edge_mismatch < LONG_EDGE_LENGTH_MATCH_LIMIT &&
3809
0
      short_edge_mismatch < SHORT_EDGE_LENGTH_MATCH_LIMIT)
3810
0
        {
3811
0
    imageable_area_matched = 1;
3812
    /* If two sizes match within the limits, take the one with less
3813
       mismatch */
3814
0
    score = (long)(4999.0 -
3815
0
             long_edge_mismatch * short_edge_mismatch * 4999.0 /
3816
0
             LONG_EDGE_LENGTH_MATCH_LIMIT /
3817
0
             SHORT_EDGE_LENGTH_MATCH_LIMIT);
3818
0
    if (score < 0) score = 0;
3819
0
        }
3820
0
      }
3821
3822
0
      if (margins_matched)
3823
0
        score += PAGESIZE_SCORE_SIZE_MARGINS * 10000;
3824
0
      else if (size_matched)
3825
0
        score += PAGESIZE_SCORE_SIZE * 10000;
3826
3827
0
      if (size_matched || imageable_area_matched) {
3828
0
        if (!strcasecmp(cups->pageSizeRequested, size->name))
3829
0
        {
3830
#ifdef CUPS_DEBUG
3831
    name_requested_matched = 1;
3832
#endif
3833
0
        }
3834
0
        else
3835
0
    score -= 1000;
3836
0
      }
3837
3838
0
      if (score > best_score)
3839
0
      {
3840
0
        best_score = score;
3841
0
        if (score > 0)
3842
0
    best_size = size;
3843
0
      }
3844
#ifdef CUPS_DEBUG
3845
      dmprintf1(pdev->memory, "DEBUG2: Checking against PPD page size (landscape): %s\n",
3846
          size->name);
3847
      dmprintf2(pdev->memory, "DEBUG2:    Width: %.2f; Height: %.2f\n",
3848
          size->width, size->length);
3849
      dmprintf4(pdev->memory, "DEBUG2:    Margins: Left: %.2f; Right: %.2f; Top: %.2f; Bottom: %.2f\n",
3850
          size->left, size->right, size->top, size->bottom);
3851
      dmprintf4(pdev->memory, "DEBUG2:    Size mismatch: Long Edge (%.3f): %.5f; Short Edge (%.3f): %.5f\n",
3852
          LONG_EDGE_LENGTH_MATCH_LIMIT, long_edge_mismatch,
3853
          SHORT_EDGE_LENGTH_MATCH_LIMIT, short_edge_mismatch);
3854
      dmprintf4(pdev->memory, "DEBUG2:    Match: Size: %d; Margins: %d; Imageable Area: %d; Name requested: %d\n",
3855
          size_matched, margins_matched, imageable_area_matched,
3856
          name_requested_matched);
3857
      dmprintf2(pdev->memory, "DEBUG2:    Score: %ld; Best Score: %ld\n",
3858
          score, best_score);
3859
#endif /* CUPS_DEBUG */
3860
0
    }
3861
3862
0
    if (best_size)
3863
0
    {
3864
     /*
3865
      * Standard size in landscape orientation...
3866
      */
3867
3868
#ifdef CUPS_DEBUG
3869
      dmprintf1(pdev->memory, "DEBUG: landscape size = %s\n", best_size->name);
3870
#endif /* CUPS_DEBUG */
3871
3872
0
      mediasize[0] = best_size->length;
3873
0
      mediasize[1] = best_size->width;
3874
3875
0
      cups->landscape = 1;
3876
3877
0
#ifdef CUPS_RASTER_SYNCv1
3878
0
      strncpy(cups->header.cupsPageSizeName, best_size->name,
3879
0
        sizeof(cups->header.cupsPageSizeName));
3880
0
      cups->header.cupsPageSizeName[sizeof(cups->header.cupsPageSizeName) - 1] =
3881
0
        '\0';
3882
3883
0
      if (strcasecmp(cups->header.MediaClass, "PwgRaster") != 0)
3884
0
      {
3885
0
#endif
3886
0
        margins[0] = (best_size->length - best_size->top) / 72.0;
3887
0
        margins[1] = best_size->left / 72.0;
3888
0
        margins[2] = best_size->bottom / 72.0;
3889
0
        margins[3] = (best_size->width - best_size->right) / 72.0;
3890
0
        if (xflip == 1)
3891
0
        {
3892
0
    swap = margins[1]; margins[1] = margins[3]; margins[3] = swap;
3893
0
        }
3894
0
        if (yflip == 1)
3895
0
        {
3896
0
    swap = margins[0]; margins[0] = margins[2]; margins[2] = swap;
3897
0
        }
3898
0
#ifdef CUPS_RASTER_SYNCv1
3899
0
      }
3900
0
      else
3901
0
      {
3902
0
        margins[0] = 0.0;
3903
0
        margins[1] = 0.0;
3904
0
        margins[2] = 0.0;
3905
0
        margins[3] = 0.0;
3906
0
      }
3907
0
#endif
3908
0
    }
3909
0
  }
3910
0
      }
3911
3912
0
      if (!best_size)
3913
0
      {
3914
       /*
3915
  * Custom size...
3916
  */
3917
3918
#ifdef CUPS_DEBUG
3919
  dmprintf(pdev->memory, "DEBUG: size = Custom\n");
3920
#endif /* CUPS_DEBUG */
3921
3922
0
#ifdef CUPS_RASTER_SYNCv1
3923
0
  snprintf(cups->header.cupsPageSizeName,
3924
0
     sizeof(cups->header.cupsPageSizeName),
3925
0
     "Custom.%.2fx%.2f",
3926
0
     cups->MediaSize[0], cups->MediaSize[1]);
3927
0
#endif
3928
3929
  /* Rotate page if it only fits into the printer's dimensions
3930
     when rotated */
3931
0
  if (((cups->MediaSize[0] > cups->PPD->custom_max[0]) ||
3932
0
       (cups->MediaSize[1] > cups->PPD->custom_max[1])) &&
3933
0
      ((cups->MediaSize[0] <= cups->PPD->custom_max[1]) &&
3934
0
       (cups->MediaSize[1] <= cups->PPD->custom_max[0]))) {
3935
    /* Rotate */
3936
0
    mediasize[0] = cups->MediaSize[1];
3937
0
    mediasize[1] = cups->MediaSize[0];
3938
3939
0
    cups->landscape = 1;
3940
3941
0
#ifdef CUPS_RASTER_SYNCv1
3942
0
    if (strcasecmp(cups->header.MediaClass, "PwgRaster") != 0)
3943
0
    {
3944
0
#endif
3945
0
      margins[0] = cups->PPD->custom_margins[3] / 72.0;
3946
0
      margins[1] = cups->PPD->custom_margins[0] / 72.0;
3947
0
      margins[2] = cups->PPD->custom_margins[1] / 72.0;
3948
0
      margins[3] = cups->PPD->custom_margins[2] / 72.0;
3949
0
      if (xflip == 1)
3950
0
      {
3951
0
        swap = margins[1]; margins[1] = margins[3]; margins[3] = swap;
3952
0
      }
3953
0
      if (yflip == 1)
3954
0
      {
3955
0
        swap = margins[0]; margins[0] = margins[2]; margins[2] = swap;
3956
0
      }
3957
0
#ifdef CUPS_RASTER_SYNCv1
3958
0
    }
3959
0
    else
3960
0
    {
3961
0
      margins[0] = 0.0;
3962
0
      margins[1] = 0.0;
3963
0
      margins[2] = 0.0;
3964
0
      margins[3] = 0.0;
3965
0
    }
3966
0
#endif
3967
0
  }
3968
0
  else
3969
0
  {
3970
    /* Do not rotate */
3971
0
    mediasize[0] = cups->MediaSize[0];
3972
0
    mediasize[1] = cups->MediaSize[1];
3973
3974
0
    cups->landscape = 0;
3975
3976
0
#ifdef CUPS_RASTER_SYNCv1
3977
0
    if (strcasecmp(cups->header.MediaClass, "PwgRaster") != 0)
3978
0
    {
3979
0
#endif
3980
0
      for (i = 0; i < 4; i ++)
3981
0
        margins[i] = cups->PPD->custom_margins[i] / 72.0;
3982
0
      if (xflip == 1)
3983
0
      {
3984
0
        swap = margins[0]; margins[0] = margins[2]; margins[2] = swap;
3985
0
      }
3986
0
      if (yflip == 1)
3987
0
      {
3988
0
        swap = margins[1]; margins[1] = margins[3]; margins[3] = swap;
3989
0
      }
3990
0
#ifdef CUPS_RASTER_SYNCv1
3991
0
    }
3992
0
    else
3993
0
    {
3994
0
      margins[0] = 0.0;
3995
0
      margins[1] = 0.0;
3996
0
      margins[2] = 0.0;
3997
0
      margins[3] = 0.0;
3998
0
    }
3999
0
#endif
4000
0
  }
4001
0
      }
4002
4003
#ifdef CUPS_DEBUG
4004
      dmprintf4(pdev->memory, "DEBUG: margins[] = [ %f %f %f %f ]\n",
4005
                margins[0], margins[1], margins[2], margins[3]);
4006
#endif /* CUPS_DEBUG */
4007
0
    }
4008
250k
    else
4009
250k
    {
4010
      /* No PPD file available */
4011
#ifdef CUPS_DEBUG
4012
      dmprintf1(pdev->memory, "DEBUG2: cups->header.Duplex = %d\n", cups->header.Duplex);
4013
      dmprintf1(pdev->memory, "DEBUG2: cups->header.Tumble = %d\n", cups->header.Tumble);
4014
      dmprintf1(pdev->memory, "DEBUG2: cups->page = %d\n", cups->page);
4015
#endif /* CUPS_DEBUG */
4016
4017
#ifdef CUPS_DEBUG
4018
      dmprintf1(pdev->memory, "DEBUG2: cupsBackSideOrientation = %s\n",
4019
    cups->cupsBackSideOrientation);
4020
#endif /* CUPS_DEBUG */
4021
4022
#ifdef CUPS_DEBUG
4023
      if (cups->cupsBackSideFlipMargins)
4024
        dmprintf0(pdev->memory, "DEBUG2: Duplex requires flipped margins\n");
4025
#endif /* CUPS_DEBUG */
4026
4027
250k
      if (cups->header.Duplex &&
4028
250k
    (cups->header.Tumble &&
4029
0
     (!strcasecmp(cups->cupsBackSideOrientation, "Flipped"))) &&
4030
250k
    !(cups->page & 1))
4031
0
      {
4032
0
  xflip = 1;
4033
0
  if (!cups->cupsBackSideFlipMargins) {
4034
#ifdef CUPS_DEBUG
4035
          dmprintf(pdev->memory, "DEBUG2: (1) Flip: X=1 Y=0\n");
4036
#endif /* CUPS_DEBUG */
4037
0
    yflip = 0;
4038
0
  } else {
4039
#ifdef CUPS_DEBUG
4040
          dmprintf(pdev->memory, "DEBUG2: (1) Flip: X=1 Y=1\n");
4041
#endif /* CUPS_DEBUG */
4042
0
    yflip = 1;
4043
0
  }
4044
0
      }
4045
250k
      else if (cups->header.Duplex &&
4046
250k
         (!cups->header.Tumble &&
4047
0
    (!strcasecmp(cups->cupsBackSideOrientation, "Flipped"))) &&
4048
250k
         !(cups->page & 1))
4049
0
      {
4050
0
  xflip = 0;
4051
0
  if (!cups->cupsBackSideFlipMargins) {
4052
#ifdef CUPS_DEBUG
4053
          dmprintf(pdev->memory, "DEBUG2: (2) Flip: X=0 Y=1\n");
4054
#endif /* CUPS_DEBUG */
4055
0
    yflip = 1;
4056
0
  } else {
4057
#ifdef CUPS_DEBUG
4058
          dmprintf(pdev->memory, "DEBUG2: (2) Flip: X=0 Y=0\n");
4059
#endif /* CUPS_DEBUG */
4060
0
    yflip = 0;
4061
0
  }
4062
0
      }
4063
250k
      else if (cups->header.Duplex &&
4064
250k
         ((!cups->header.Tumble &&
4065
0
     (!strcasecmp(cups->cupsBackSideOrientation, "Rotated"))) ||
4066
0
    (cups->header.Tumble &&
4067
0
     (!strcasecmp(cups->cupsBackSideOrientation, "ManualTumble")))) &&
4068
250k
         !(cups->page & 1))
4069
0
      {
4070
0
  xflip = 1;
4071
0
  if (cups->cupsBackSideFlipMargins) {
4072
#ifdef CUPS_DEBUG
4073
          dmprintf(pdev->memory, "DEBUG2: (3) Flip: X=1 Y=0\n");
4074
#endif /* CUPS_DEBUG */
4075
0
    yflip = 0;
4076
0
  } else {
4077
#ifdef CUPS_DEBUG
4078
          dmprintf(pdev->memory, "DEBUG2: (3) Flip: X=1 Y=1\n");
4079
#endif /* CUPS_DEBUG */
4080
0
    yflip = 1;
4081
0
  }
4082
0
      }
4083
250k
      else
4084
250k
      {
4085
#ifdef CUPS_DEBUG
4086
        dmprintf(pdev->memory, "DEBUG2: (4) Flip: X=0 Y=0\n");
4087
#endif /* CUPS_DEBUG */
4088
250k
  xflip = 0;
4089
250k
  yflip = 0;
4090
250k
      }
4091
250k
      mediasize[0] = cups->MediaSize[0];
4092
250k
      mediasize[1] = cups->MediaSize[1];
4093
250k
#ifdef CUPS_RASTER_SYNCv1
4094
250k
      if (strcasecmp(cups->header.MediaClass, "PwgRaster") != 0)
4095
250k
      {
4096
250k
#endif
4097
  /* If we do not have a PPD file, make sure that margins given via the
4098
     input file or via something like
4099
     "-c '<</.HWMargins[12 12 12 12] /Margins[0 0]>>setpagedevice'"
4100
     on the command line are conserved */
4101
250k
  margins[0] = pdev->HWMargins[0] / 72.0;
4102
250k
  margins[1] = pdev->HWMargins[1] / 72.0;
4103
250k
  margins[2] = pdev->HWMargins[2] / 72.0;
4104
250k
  margins[3] = pdev->HWMargins[3] / 72.0;
4105
250k
  if (xflip == 1)
4106
0
  {
4107
0
    swap = margins[0]; margins[0] = margins[2]; margins[2] = swap;
4108
0
  }
4109
250k
  if (yflip == 1)
4110
0
  {
4111
0
    swap = margins[1]; margins[1] = margins[3]; margins[3] = swap;
4112
0
  }
4113
250k
#ifdef CUPS_RASTER_SYNCv1
4114
250k
      }
4115
0
      else
4116
0
      {
4117
0
  margins[0] = 0.0;
4118
0
  margins[1] = 0.0;
4119
0
  margins[2] = 0.0;
4120
0
  margins[3] = 0.0;
4121
0
      }
4122
250k
#endif
4123
250k
    }
4124
4125
   /*
4126
    * Set the media size and margins to update the bitmap size...
4127
    */
4128
4129
752k
    for (i = 0; i < 2; i ++)
4130
501k
      cups_mediasize[i] = mediasize[i];
4131
1.25M
    for (i = 0; i < 4; i ++)
4132
1.00M
      cups_margins[i] = margins[i] * 72.0;
4133
250k
    if (best_score > 0 && best_score < 5000) {
4134
#ifdef CUPS_DEBUG
4135
      dmputs(pdev->memory, "DEBUG: Imageable area fit!\n");
4136
#endif /* CUPS_DEBUG */
4137
      /* Page size matched by imageable area */
4138
0
      for (i = 0; i < 2; i ++)
4139
0
  mediasize[i] = cups->MediaSize[i];
4140
0
      for (i = 0; i < 4; i ++)
4141
0
  margins[i] = 0.0;
4142
0
    }
4143
250k
    gx_device_set_media_size(pdev, mediasize[0], mediasize[1]);
4144
250k
    gx_device_set_margins(pdev, margins, false);
4145
250k
  } else {
4146
    /* No size change, use the current size in CUPS Raster header */
4147
291k
    for (i = 0; i < 2; i ++)
4148
194k
      cups_mediasize[i] = pdev->MediaSize[i];
4149
485k
    for (i = 0; i < 4; i ++)
4150
388k
      cups_margins[i] = pdev->HWMargins[i];
4151
97.1k
  }
4152
4153
 /*
4154
  * Reallocate memory if the size or color depth was changed...
4155
  */
4156
4157
347k
  if (color_set || size_set)
4158
290k
  {
4159
   /*
4160
    * Make sure the page image is the correct size - current Ghostscript
4161
    * does not keep track of the margins in the bitmap size...
4162
    */
4163
4164
290k
    if (cups->landscape)
4165
0
    {
4166
0
      width  = (int)((pdev->MediaSize[1] - pdev->HWMargins[1] - pdev->HWMargins[3]) *
4167
0
                     pdev->HWResolution[0] / 72.0f + 0.499f);
4168
0
      height = (int)((pdev->MediaSize[0] - pdev->HWMargins[0] - pdev->HWMargins[2]) *
4169
0
                     pdev->HWResolution[1] / 72.0f + 0.499f);
4170
0
    }
4171
290k
    else
4172
290k
    {
4173
290k
      width  = (int)((pdev->MediaSize[0] - pdev->HWMargins[0] - pdev->HWMargins[2]) *
4174
290k
                     pdev->HWResolution[0] / 72.0f + 0.499f);
4175
290k
      height = (int)((pdev->MediaSize[1] - pdev->HWMargins[1] - pdev->HWMargins[3]) *
4176
290k
                     pdev->HWResolution[1] / 72.0f + 0.499f);
4177
290k
    }
4178
4179
290k
    if (width <= 0 || height <= 0) {
4180
2
      dmprintf(pdev->memory, "ERROR: page margins overlap\n");
4181
2
      return_error(gs_error_rangecheck);
4182
2
    }
4183
4184
290k
#ifdef CUPS_RASTER_SYNCv1
4185
290k
    if (cups->header.cupsBorderlessScalingFactor > 1.0)
4186
0
    {
4187
0
      width  = (int)(width * cups->header.cupsBorderlessScalingFactor);
4188
0
      height = (int)(height * cups->header.cupsBorderlessScalingFactor);
4189
0
    }
4190
290k
#endif /* CUPS_RASTER_SYNCv1 */
4191
4192
290k
    pdev->width  = width;
4193
290k
    pdev->height = height;
4194
4195
   /*
4196
    * Don't reallocate memory unless the device has been opened...
4197
    * Also reallocate only if the size has actually changed...
4198
    */
4199
4200
290k
    if (pdev->is_open)
4201
250k
    {
4202
4203
     /*
4204
      * Device is open and size has changed, so reallocate...
4205
      */
4206
4207
#ifdef CUPS_DEBUG
4208
      dmprintf4(pdev->memory, "DEBUG2: Reallocating memory, [%.0f %.0f] = %dx%d pixels...\n",
4209
                pdev->MediaSize[0], pdev->MediaSize[1], width, height);
4210
#endif /* CUPS_DEBUG */
4211
4212
250k
      if ((code = gdev_prn_maybe_realloc_memory((gx_device_printer *)pdev,
4213
250k
                                                &sp_old,
4214
250k
            width_old, height_old,
4215
250k
            transp_old))
4216
250k
    < 0)
4217
0
        goto done;
4218
#ifdef CUPS_DEBUG
4219
      dmprintf4(pdev->memory, "DEBUG2: Reallocated memory, [%.0f %.0f] = %dx%d pixels...\n",
4220
                pdev->MediaSize[0], pdev->MediaSize[1], width, height);
4221
#endif /* CUPS_DEBUG */
4222
250k
    }
4223
39.2k
    else
4224
39.2k
    {
4225
     /*
4226
      * Device isn't yet open, so just save the new width and height...
4227
      */
4228
4229
#ifdef CUPS_DEBUG
4230
      dmprintf4(pdev->memory, "DEBUG: Setting initial media size, [%.0f %.0f] = %dx%d pixels...\n",
4231
                pdev->MediaSize[0], pdev->MediaSize[1], width, height);
4232
#endif /* CUPS_DEBUG */
4233
4234
39.2k
      pdev->width  = width;
4235
39.2k
      pdev->height = height;
4236
39.2k
    }
4237
290k
  }
4238
4239
 /*
4240
  * Set CUPS raster header values...
4241
  */
4242
4243
347k
  cups->header.HWResolution[0] = (unsigned int)pdev->HWResolution[0];
4244
347k
  cups->header.HWResolution[1] = (unsigned int)pdev->HWResolution[1];
4245
4246
347k
#ifdef CUPS_RASTER_SYNCv1
4247
4248
347k
  if (cups->landscape)
4249
0
  {
4250
0
    cups->header.cupsPageSize[0] = cups_mediasize[1];
4251
0
    cups->header.cupsPageSize[1] = cups_mediasize[0];
4252
4253
0
    if ((sf = cups->header.cupsBorderlessScalingFactor) < 1.0)
4254
0
      sf = 1.0;
4255
4256
0
    cups->header.PageSize[0] = (unsigned int)((cups_mediasize[1] * sf) + 0.5);
4257
0
    cups->header.PageSize[1] = (unsigned int)((cups_mediasize[0] * sf) + 0.5);
4258
4259
0
    if (strcasecmp(cups->header.MediaClass, "PwgRaster") != 0)
4260
0
    {
4261
0
      cups->header.Margins[0] = (unsigned int)((cups_margins[1] * sf) + 0.5);
4262
0
      cups->header.Margins[1] = (unsigned int)((cups_margins[2] * sf) + 0.5);
4263
0
      cups->header.ImagingBoundingBox[0] =
4264
0
                                (unsigned int)((cups_margins[1] * sf) + 0.5);
4265
0
      cups->header.ImagingBoundingBox[1] =
4266
0
                                (unsigned int)((cups_margins[2] * sf) + 0.5);
4267
0
      cups->header.ImagingBoundingBox[2] =
4268
0
                                (unsigned int)(((cups_mediasize[1] -
4269
0
                                                 cups_margins[3]) * sf) + 0.5);
4270
0
      cups->header.ImagingBoundingBox[3] =
4271
0
                                (unsigned int)(((cups_mediasize[0] -
4272
0
                                                 cups_margins[0]) * sf) + 0.5);
4273
0
      cups->header.cupsImagingBBox[0] = cups_margins[1];
4274
0
      cups->header.cupsImagingBBox[1] = cups_margins[2];
4275
0
      cups->header.cupsImagingBBox[2] = cups_mediasize[1] - cups_margins[3];
4276
0
      cups->header.cupsImagingBBox[3] = cups_mediasize[0] - cups_margins[0];
4277
0
    }
4278
0
    else
4279
0
    {
4280
0
      for (i = 0; i < 2; i ++)
4281
0
  cups->header.Margins[i] = 0;
4282
0
      for (i = 0; i < 4; i ++)
4283
0
      {
4284
0
  cups->header.ImagingBoundingBox[i] = 0;
4285
0
  cups->header.cupsImagingBBox[i] = 0.0;
4286
0
      }
4287
0
    }
4288
0
  }
4289
347k
  else
4290
347k
  {
4291
347k
    cups->header.cupsPageSize[0] = cups_mediasize[0];
4292
347k
    cups->header.cupsPageSize[1] = cups_mediasize[1];
4293
4294
347k
    if ((sf = cups->header.cupsBorderlessScalingFactor) < 1.0)
4295
0
      sf = 1.0;
4296
4297
347k
    cups->header.PageSize[0] = (unsigned int)((cups_mediasize[0] * sf) + 0.5);
4298
347k
    cups->header.PageSize[1] = (unsigned int)((cups_mediasize[1] * sf) + 0.5);
4299
4300
347k
    if (strcasecmp(cups->header.MediaClass, "PwgRaster") != 0)
4301
347k
    {
4302
347k
      cups->header.Margins[0] = (cups_margins[0] * sf) + 0.5;
4303
347k
      cups->header.Margins[1] = (cups_margins[1] * sf) + 0.5;
4304
347k
      cups->header.ImagingBoundingBox[0] =
4305
347k
                               (unsigned int)((cups_margins[0] * sf) + 0.5);
4306
347k
      cups->header.ImagingBoundingBox[1] =
4307
347k
                               (unsigned int)((cups_margins[1] * sf) + 0.5);
4308
347k
      cups->header.ImagingBoundingBox[2] =
4309
347k
                               (unsigned int)(((cups_mediasize[0] -
4310
347k
                                                cups_margins[2]) * sf) + 0.5);
4311
347k
      cups->header.ImagingBoundingBox[3] =
4312
347k
                               (unsigned int)(((cups_mediasize[1] -
4313
347k
                                                cups_margins[3]) * sf) + 0.5);
4314
347k
      cups->header.cupsImagingBBox[0] = cups_margins[0];
4315
347k
      cups->header.cupsImagingBBox[1] = cups_margins[1];
4316
347k
      cups->header.cupsImagingBBox[2] = cups_mediasize[0] - cups_margins[2];
4317
347k
      cups->header.cupsImagingBBox[3] = cups_mediasize[1] - cups_margins[3];
4318
347k
    }
4319
0
    else
4320
0
    {
4321
0
      for (i = 0; i < 2; i ++)
4322
0
  cups->header.Margins[i] = 0;
4323
0
      for (i = 0; i < 4; i ++)
4324
0
      {
4325
0
  cups->header.ImagingBoundingBox[i] = 0;
4326
0
  cups->header.cupsImagingBBox[i] = 0.0;
4327
0
      }
4328
0
    }
4329
347k
  }
4330
4331
#else
4332
4333
  if (cups->landscape)
4334
  {
4335
    cups->header.PageSize[0] = cups_mediasize[1] + 0.5;
4336
    cups->header.PageSize[1] = cups_mediasize[0] + 0.5;
4337
4338
    if (strcasecmp(cups->header.MediaClass, "PwgRaster") != 0)
4339
    {
4340
      cups->header.Margins[0] = (cups_margins[1]) + 0.5;
4341
      cups->header.Margins[1] = (cups_margins[2]) + 0.5;
4342
      cups->header.ImagingBoundingBox[0] = (cups_margins[1]) + 0.5;
4343
      cups->header.ImagingBoundingBox[1] = (cups_margins[0]) + 0.5;
4344
      cups->header.ImagingBoundingBox[2] = (cups_mediasize[1] -
4345
              cups_margins[3]) + 0.5;
4346
      cups->header.ImagingBoundingBox[3] = (cups_mediasize[0] -
4347
              cups_margins[2]) + 0.5;
4348
    }
4349
    else
4350
    {
4351
      for (i = 0; i < 2; i ++)
4352
  cups->header.Margins[i] = 0;
4353
      for (i = 0; i < 4; i ++)
4354
  cups->header.ImagingBoundingBox[i] = 0;
4355
    }
4356
  }
4357
  else
4358
  {
4359
    cups->header.PageSize[0] = cups_mediasize[0] + 0.5;
4360
    cups->header.PageSize[1] = cups_mediasize[1] + 0.5;
4361
4362
    if (strcasecmp(cups->header.MediaClass, "PwgRaster") != 0)
4363
    {
4364
      cups->header.Margins[0] = (cups_margins[0]) + 0.5;
4365
      cups->header.Margins[1] = (cups_margins[1]) + 0.5;
4366
      cups->header.ImagingBoundingBox[0] = (cups_margins[0]) + 0.5;
4367
      cups->header.ImagingBoundingBox[1] = (cups_margins[3]) + 0.5;
4368
      cups->header.ImagingBoundingBox[2] = (cups_mediasize[0] -
4369
              cups_margins[2]) + 0.5;
4370
      cups->header.ImagingBoundingBox[3] = (cups_mediasize[1] -
4371
              cups_margins[1]) + 0.5;
4372
    }
4373
    else
4374
    {
4375
      for (i = 0; i < 2; i ++)
4376
  cups->header.Margins[i] = 0;
4377
      for (i = 0; i < 4; i ++)
4378
  cups->header.ImagingBoundingBox[i] = 0;
4379
    }
4380
  }
4381
4382
#endif /* CUPS_RASTER_SYNCv1 */
4383
347k
  cups->header.cupsWidth  = cups->width;
4384
347k
  cups->header.cupsHeight = cups->height;
4385
4386
#ifdef CUPS_DEBUG
4387
  if (size_set) {
4388
    dmprintf2(pdev->memory, "DEBUG2: mediasize = [ %.3f %.3f ]\n",
4389
              mediasize[0], mediasize[1]);
4390
    dmprintf4(pdev->memory, "DEBUG2: margins = [ %.3f %.3f %.3f %.3f ]\n",
4391
              margins[0], margins[1], margins[2], margins[3]);
4392
  }
4393
  dmprintf2(pdev->memory, "DEBUG2: cups_mediasize = [ %.3f %.3f ]\n",
4394
      cups_mediasize[0], cups_mediasize[1]);
4395
  dmprintf4(pdev->memory, "DEBUG2: cups_margins = [ %.3f %.3f %.3f %.3f ]\n",
4396
      cups_margins[0], cups_margins[1], cups_margins[2], cups_margins[3]);
4397
  dmprintf1(pdev->memory, "DEBUG2: ppd = %p\n", cups->PPD);
4398
  dmprintf2(pdev->memory, "DEBUG2: PageSize = [ %.3f %.3f ]\n",
4399
            pdev->MediaSize[0], pdev->MediaSize[1]);
4400
  dmprintf2(pdev->memory, "DEBUG2: HWResolution = [ %.3f %.3f ]\n",
4401
            pdev->HWResolution[0], pdev->HWResolution[1]);
4402
  dmprintf2(pdev->memory, "DEBUG2: width = %d, height = %d\n",
4403
            pdev->width, pdev->height);
4404
  dmprintf4(pdev->memory, "DEBUG2: HWMargins = [ %.3f %.3f %.3f %.3f ]\n",
4405
            pdev->HWMargins[0], pdev->HWMargins[1],
4406
            pdev->HWMargins[2], pdev->HWMargins[3]);
4407
  dmprintf2(pdev->memory, "DEBUG2: cups->header.cupsWidth = %d, cups->header.cupsHeight = %d\n",
4408
            cups->header.cupsWidth, cups->header.cupsHeight);
4409
  dmprintf2(pdev->memory, "DEBUG2: cups->header.PageSize[0] = %d, cups->header.PageSize[1] = %d\n",
4410
            cups->header.PageSize[0], cups->header.PageSize[1]);
4411
  dmprintf4(pdev->memory, "DEBUG2: cups->header.ImagingBoundingBox = [ %d %d %d %d ]\n",
4412
            cups->header.ImagingBoundingBox[0],
4413
      cups->header.ImagingBoundingBox[1],
4414
            cups->header.ImagingBoundingBox[2],
4415
      cups->header.ImagingBoundingBox[3]);
4416
#ifdef CUPS_RASTER_SYNCv1
4417
  dmprintf2(pdev->memory, "DEBUG2: cups->header.cupsPageSize[0] = %.3f, cups->header.cupsPageSize[1] = %.3f\n",
4418
            cups->header.cupsPageSize[0], cups->header.cupsPageSize[1]);
4419
  dmprintf4(pdev->memory, "DEBUG2: cups->header.cupsImagingBBox = [ %.3f %.3f %.3f %.3f ]\n",
4420
            cups->header.cupsImagingBBox[0], cups->header.cupsImagingBBox[1],
4421
            cups->header.cupsImagingBBox[2], cups->header.cupsImagingBBox[3]);
4422
  dmprintf1(pdev->memory, "DEBUG2: cups->header.cupsBorderlessScalingFactor = %.3f\n",
4423
            cups->header.cupsBorderlessScalingFactor);
4424
#endif /* CUPS_RASTER_SYNCv1 */
4425
#endif /* CUPS_DEBUG */
4426
4427
348k
done:
4428
348k
  return code;
4429
347k
}
4430
4431
/*
4432
 * 'cups_set_color_info()' - Set the color information structure based on
4433
 *                           the required output.
4434
 */
4435
4436
private int
4437
cups_set_color_info(gx_device *pdev)  /* I - Device info */
4438
387k
{
4439
387k
  int   i, j, k;    /* Looping vars */
4440
387k
  int   max_lut;    /* Maximum LUT value */
4441
387k
  float   d, g;     /* Density and gamma correction */
4442
387k
  float   m[3][3];    /* Color correction matrix */
4443
387k
  char    resolution[41];   /* Resolution string */
4444
387k
  ppd_profile_t *profile;   /* Color profile information */
4445
387k
  int           code = 0;
4446
4447
#ifdef CUPS_DEBUG
4448
  dmprintf1(pdev->memory, "DEBUG2: cups_set_color_info(%p)\n", pdev);
4449
#endif /* CUPS_DEBUG */
4450
4451
#ifndef GX_COLOR_INDEX_TYPE
4452
  if (cups->header.cupsBitsPerColor > 8)
4453
    cups->header.cupsBitsPerColor = 8;
4454
#endif /* !GX_COLOR_INDEX_TYPE */
4455
4456
387k
  switch (cups->header.cupsColorSpace)
4457
387k
  {
4458
17
    default :
4459
21.6k
    case CUPS_CSPACE_W :
4460
22.5k
    case CUPS_CSPACE_SW :
4461
65.8k
    case CUPS_CSPACE_K :
4462
70.4k
    case CUPS_CSPACE_WHITE :
4463
76.4k
    case CUPS_CSPACE_GOLD :
4464
79.6k
    case CUPS_CSPACE_SILVER :
4465
79.6k
#ifdef CUPS_RASTER_SYNCv1
4466
79.6k
  cups->header.cupsNumColors      = 1;
4467
79.6k
#endif /* CUPS_RASTER_SYNCv1 */
4468
79.6k
        cups->header.cupsBitsPerPixel   = cups->header.cupsBitsPerColor;
4469
79.6k
        cups->color_info.depth          = cups->header.cupsBitsPerPixel;
4470
79.6k
        cups->color_info.num_components = 1;
4471
79.6k
        cups->color_info.dither_grays = 1L << cups->header.cupsBitsPerColor;
4472
79.6k
        cups->color_info.dither_colors = 1L << cups->header.cupsBitsPerColor;
4473
79.6k
        cups->color_info.max_gray = cups->color_info.dither_grays - 1;
4474
79.6k
        cups->color_info.max_color = cups->color_info.dither_grays - 1;
4475
79.6k
        break;
4476
4477
788
    case CUPS_CSPACE_CMY :
4478
1.36k
    case CUPS_CSPACE_YMC :
4479
159k
    case CUPS_CSPACE_RGB :
4480
159k
    case CUPS_CSPACE_SRGB :
4481
171k
    case CUPS_CSPACE_ADOBERGB :
4482
171k
#ifdef CUPS_RASTER_SYNCv1
4483
171k
  cups->header.cupsNumColors      = 3;
4484
171k
#endif /* CUPS_RASTER_SYNCv1 */
4485
171k
        if (cups->header.cupsColorOrder != CUPS_ORDER_CHUNKED)
4486
0
          cups->header.cupsBitsPerPixel = cups->header.cupsBitsPerColor;
4487
171k
  else if (cups->header.cupsBitsPerColor < 8)
4488
171k
    cups->header.cupsBitsPerPixel = 4 * cups->header.cupsBitsPerColor;
4489
0
  else
4490
0
    cups->header.cupsBitsPerPixel = 3 * cups->header.cupsBitsPerColor;
4491
4492
171k
  if (cups->header.cupsBitsPerColor < 8)
4493
171k
    cups->color_info.depth = 4 * cups->header.cupsBitsPerColor;
4494
0
  else
4495
0
    cups->color_info.depth = 3 * cups->header.cupsBitsPerColor;
4496
4497
171k
        cups->color_info.num_components = 3;
4498
171k
        break;
4499
4500
8.54k
    case CUPS_CSPACE_KCMYcm :
4501
8.54k
        if (cups->header.cupsBitsPerColor == 1)
4502
8.54k
  {
4503
8.54k
#ifdef CUPS_RASTER_SYNCv1
4504
8.54k
    cups->header.cupsNumColors      = 6;
4505
8.54k
#endif /* CUPS_RASTER_SYNCv1 */
4506
8.54k
    cups->header.cupsBitsPerPixel   = 8;
4507
8.54k
    cups->color_info.depth          = 8;
4508
8.54k
    cups->color_info.num_components = 4;
4509
8.54k
    break;
4510
8.54k
  }
4511
4512
1.69k
    case CUPS_CSPACE_RGBA :
4513
4.94k
    case CUPS_CSPACE_RGBW :
4514
4.94k
#ifdef CUPS_RASTER_SYNCv1
4515
4.94k
        cups->header.cupsNumColors = 4;
4516
4.94k
#endif /* CUPS_RASTER_SYNCv1 */
4517
4.94k
        if (cups->header.cupsColorOrder != CUPS_ORDER_CHUNKED)
4518
0
            cups->header.cupsBitsPerPixel = cups->header.cupsBitsPerColor;
4519
4.94k
        else
4520
4.94k
            cups->header.cupsBitsPerPixel = 4 * cups->header.cupsBitsPerColor;
4521
4522
4.94k
        cups->color_info.depth = 4 * cups->header.cupsBitsPerColor;
4523
4.94k
        cups->color_info.num_components = 3;
4524
4.94k
        break;
4525
4526
3.76k
    case CUPS_CSPACE_CMYK :
4527
6.04k
    case CUPS_CSPACE_YMCK :
4528
9.24k
    case CUPS_CSPACE_KCMY :
4529
32.0k
    case CUPS_CSPACE_GMCK :
4530
34.9k
    case CUPS_CSPACE_GMCS :
4531
34.9k
#ifdef CUPS_RASTER_SYNCv1
4532
34.9k
  cups->header.cupsNumColors = 4;
4533
34.9k
#endif /* CUPS_RASTER_SYNCv1 */
4534
34.9k
        if (cups->header.cupsColorOrder != CUPS_ORDER_CHUNKED)
4535
0
            cups->header.cupsBitsPerPixel = cups->header.cupsBitsPerColor;
4536
34.9k
      else
4537
34.9k
        cups->header.cupsBitsPerPixel = 4 * cups->header.cupsBitsPerColor;
4538
4539
34.9k
        cups->color_info.depth          = 4 * cups->header.cupsBitsPerColor;
4540
34.9k
        cups->color_info.num_components = 4;
4541
34.9k
        break;
4542
4543
0
#ifdef CUPS_RASTER_HAVE_COLORIMETRIC
4544
3
    case CUPS_CSPACE_CIEXYZ :
4545
631
    case CUPS_CSPACE_CIELab :
4546
48.2k
    case CUPS_CSPACE_ICC1 :
4547
49.1k
    case CUPS_CSPACE_ICC2 :
4548
51.9k
    case CUPS_CSPACE_ICC3 :
4549
55.0k
    case CUPS_CSPACE_ICC4 :
4550
69.6k
    case CUPS_CSPACE_ICC5 :
4551
77.2k
    case CUPS_CSPACE_ICC6 :
4552
78.0k
    case CUPS_CSPACE_ICC7 :
4553
78.6k
    case CUPS_CSPACE_ICC8 :
4554
81.5k
    case CUPS_CSPACE_ICC9 :
4555
82.5k
    case CUPS_CSPACE_ICCA :
4556
83.3k
    case CUPS_CSPACE_ICCB :
4557
83.9k
    case CUPS_CSPACE_ICCC :
4558
84.7k
    case CUPS_CSPACE_ICCD :
4559
86.6k
    case CUPS_CSPACE_ICCE :
4560
87.4k
    case CUPS_CSPACE_ICCF :
4561
       /*
4562
  * Colorimetric color spaces currently are implemented as 24-bit
4563
  * mapping to XYZ or Lab, which are then converted as needed to
4564
  * the final representation...
4565
  *
4566
  * This code enforces a minimum output depth of 8 bits per
4567
  * component...
4568
  */
4569
4570
87.4k
#ifdef CUPS_RASTER_SYNCv1
4571
87.4k
  cups->header.cupsNumColors = 3;
4572
87.4k
#endif /* CUPS_RASTER_SYNCv1 */
4573
4574
87.4k
  if (cups->header.cupsBitsPerColor < 8)
4575
7.99k
          cups->header.cupsBitsPerColor = 8;
4576
4577
87.4k
  if (cups->header.cupsColorOrder != CUPS_ORDER_CHUNKED)
4578
0
          cups->header.cupsBitsPerPixel = cups->header.cupsBitsPerColor;
4579
87.4k
  else
4580
87.4k
          cups->header.cupsBitsPerPixel = 3 * cups->header.cupsBitsPerColor;
4581
4582
87.4k
  cups->color_info.depth          = 24;
4583
87.4k
  cups->color_info.num_components = 3;
4584
87.4k
  break;
4585
387k
#endif /* CUPS_RASTER_HAVE_COLORIMETRIC */
4586
387k
  }
4587
4588
387k
#ifdef dev_t_proc_encode_color
4589
387k
  switch (cups->header.cupsColorSpace)
4590
387k
  {
4591
264k
    default :
4592
264k
        cups->color_info.gray_index = GX_CINFO_COMP_NO_INDEX;
4593
264k
  break;
4594
4595
21.5k
    case CUPS_CSPACE_W :
4596
22.5k
    case CUPS_CSPACE_SW :
4597
27.1k
    case CUPS_CSPACE_WHITE :
4598
70.4k
    case CUPS_CSPACE_K :
4599
76.4k
    case CUPS_CSPACE_GOLD :
4600
79.6k
    case CUPS_CSPACE_SILVER :
4601
88.2k
    case CUPS_CSPACE_KCMYcm :
4602
91.4k
    case CUPS_CSPACE_KCMY :
4603
91.4k
        cups->color_info.gray_index = 0;
4604
91.4k
  break;
4605
4606
3.76k
    case CUPS_CSPACE_CMYK :
4607
6.04k
    case CUPS_CSPACE_YMCK :
4608
28.8k
    case CUPS_CSPACE_GMCK :
4609
31.7k
    case CUPS_CSPACE_GMCS :
4610
31.7k
        cups->color_info.gray_index = 3;
4611
31.7k
  break;
4612
387k
  }
4613
4614
387k
  switch (cups->header.cupsColorSpace)
4615
387k
  {
4616
17
    default :
4617
3.26k
    case CUPS_CSPACE_RGBW :
4618
24.8k
    case CUPS_CSPACE_W :
4619
25.8k
    case CUPS_CSPACE_SW :
4620
30.4k
    case CUPS_CSPACE_WHITE :
4621
188k
    case CUPS_CSPACE_RGB :
4622
188k
    case CUPS_CSPACE_CMY:
4623
189k
    case CUPS_CSPACE_YMC:
4624
190k
    case CUPS_CSPACE_SRGB :
4625
202k
    case CUPS_CSPACE_ADOBERGB :
4626
203k
    case CUPS_CSPACE_RGBA :
4627
203k
#  ifdef CUPS_RASTER_HAVE_COLORIMETRIC
4628
203k
    case CUPS_CSPACE_CIEXYZ :
4629
204k
    case CUPS_CSPACE_CIELab :
4630
252k
    case CUPS_CSPACE_ICC1 :
4631
253k
    case CUPS_CSPACE_ICC2 :
4632
255k
    case CUPS_CSPACE_ICC3 :
4633
258k
    case CUPS_CSPACE_ICC4 :
4634
273k
    case CUPS_CSPACE_ICC5 :
4635
281k
    case CUPS_CSPACE_ICC6 :
4636
281k
    case CUPS_CSPACE_ICC7 :
4637
282k
    case CUPS_CSPACE_ICC8 :
4638
285k
    case CUPS_CSPACE_ICC9 :
4639
286k
    case CUPS_CSPACE_ICCA :
4640
287k
    case CUPS_CSPACE_ICCB :
4641
287k
    case CUPS_CSPACE_ICCC :
4642
288k
    case CUPS_CSPACE_ICCD :
4643
290k
    case CUPS_CSPACE_ICCE :
4644
291k
    case CUPS_CSPACE_ICCF :
4645
291k
#  endif /* CUPS_RASTER_HAVE_COLORIMETRIC */
4646
291k
        cups->color_info.polarity = GX_CINFO_POLARITY_ADDITIVE;
4647
291k
        break;
4648
4649
43.2k
    case CUPS_CSPACE_K :
4650
49.2k
    case CUPS_CSPACE_GOLD :
4651
52.4k
    case CUPS_CSPACE_SILVER :
4652
61.0k
    case CUPS_CSPACE_KCMYcm :
4653
64.8k
    case CUPS_CSPACE_CMYK :
4654
67.0k
    case CUPS_CSPACE_YMCK :
4655
70.2k
    case CUPS_CSPACE_KCMY :
4656
93.1k
    case CUPS_CSPACE_GMCK :
4657
95.9k
    case CUPS_CSPACE_GMCS :
4658
95.9k
        cups->color_info.polarity = GX_CINFO_POLARITY_SUBTRACTIVE;
4659
95.9k
        break;
4660
387k
  }
4661
4662
387k
  cups->color_info.separable_and_linear = GX_CINFO_SEP_LIN_NONE;
4663
387k
#endif /* dev_t_proc_encode_color */
4664
4665
387k
  i       = cups->header.cupsBitsPerColor;
4666
387k
  max_lut = (1 << i) - 1;
4667
4668
387k
  switch (cups->color_info.num_components)
4669
387k
  {
4670
0
    default :
4671
79.6k
    case 1 :
4672
79.6k
  cups->color_info.max_gray      = max_lut;
4673
79.6k
  cups->color_info.max_color     = 0;
4674
79.6k
  cups->color_info.dither_grays  = max_lut + 1;
4675
79.6k
  cups->color_info.dither_colors = 0;
4676
79.6k
        break;
4677
4678
264k
    case 3 :
4679
264k
  cups->color_info.max_gray      = 0;
4680
264k
  cups->color_info.max_color     = max_lut;
4681
264k
  cups->color_info.dither_grays  = 0;
4682
264k
  cups->color_info.dither_colors = max_lut + 1;
4683
264k
  break;
4684
4685
43.5k
    case 4 :
4686
43.5k
  cups->color_info.max_gray      = max_lut;
4687
43.5k
  cups->color_info.max_color     = max_lut;
4688
43.5k
  cups->color_info.dither_grays  = max_lut + 1;
4689
43.5k
  cups->color_info.dither_colors = max_lut + 1;
4690
43.5k
  break;
4691
387k
  }
4692
4693
 /*
4694
  * Enable/disable CMYK color support...
4695
  */
4696
4697
387k
#ifdef dev_t_proc_encode_color
4698
387k
  cups->color_info.max_components = cups->color_info.num_components;
4699
387k
#endif /* dev_t_proc_encode_color */
4700
4701
 /*
4702
  * Tell Ghostscript to forget any colors it has cached...
4703
  */
4704
4705
387k
  gx_device_decache_colors(pdev);
4706
4707
 /*
4708
  * Compute the lookup tables...
4709
  */
4710
4711
25.3G
  for (i = 0; i <= gx_max_color_value; i ++)
4712
25.3G
  {
4713
25.3G
    j = (max_lut * i + gx_max_color_value / 2) / gx_max_color_value;
4714
4715
25.3G
#if !ARCH_IS_BIG_ENDIAN
4716
25.3G
    if (max_lut > 255)
4717
0
      j = ((j & 255) << 8) | ((j >> 8) & 255);
4718
25.3G
#endif /* !ARCH_IS_BIG_ENDIAN */
4719
4720
25.3G
    cups->EncodeLUT[i] = j;
4721
4722
#ifdef CUPS_DEBUG2
4723
    if (i == 0 || cups->EncodeLUT[i] != cups->EncodeLUT[i - 1])
4724
      dmprintf2(pdev->memory, "DEBUG2: cups->EncodeLUT[%d] = %d\n", i,
4725
                (int)cups->EncodeLUT[i]);
4726
#endif /* CUPS_DEBUG2 */
4727
25.3G
  }
4728
4729
#ifdef CUPS_DEBUG2
4730
  dmprintf1(pdev->memory, "DEBUG2: cups->EncodeLUT[0] = %d\n", (int)cups->EncodeLUT[0]);
4731
  dmprintf2(pdev->memory, "DEBUG2: cups->EncodeLUT[%d] = %d\n", gx_max_color_value,
4732
            (int)cups->EncodeLUT[gx_max_color_value]);
4733
#endif /* CUPS_DEBUG2 */
4734
4735
633k
  for (i = 0; i < cups->color_info.dither_grays; i ++) {
4736
246k
    j = i;
4737
246k
#if !ARCH_IS_BIG_ENDIAN
4738
246k
    if (max_lut > 255)
4739
0
      j = ((j & 255) << 8) | ((j >> 8) & 255);
4740
246k
#endif /* !ARCH_IS_BIG_ENDIAN */
4741
246k
    cups->DecodeLUT[i] = gx_max_color_value * j / max_lut;
4742
246k
  }
4743
4744
#ifdef CUPS_DEBUG
4745
  dmprintf2(pdev->memory, "DEBUG: num_components = %d, depth = %d\n",
4746
            cups->color_info.num_components, cups->color_info.depth);
4747
  dmprintf2(pdev->memory, "DEBUG: cupsColorSpace = %d, cupsColorOrder = %d\n",
4748
            cups->header.cupsColorSpace, cups->header.cupsColorOrder);
4749
  dmprintf2(pdev->memory, "DEBUG: cupsBitsPerPixel = %d, cupsBitsPerColor = %d\n",
4750
            cups->header.cupsBitsPerPixel, cups->header.cupsBitsPerColor);
4751
  dmprintf2(pdev->memory, "DEBUG: max_gray = %d, dither_grays = %d\n",
4752
            cups->color_info.max_gray, cups->color_info.dither_grays);
4753
  dmprintf2(pdev->memory, "DEBUG: max_color = %d, dither_colors = %d\n",
4754
            cups->color_info.max_color, cups->color_info.dither_colors);
4755
#endif /* CUPS_DEBUG */
4756
4757
 /*
4758
  * Set the color profile as needed...
4759
  */
4760
4761
387k
  cups->HaveProfile = 0;
4762
4763
387k
#ifdef dev_t_proc_encode_color
4764
387k
  if (cups->Profile)
4765
#else
4766
  if (cups->Profile && cups->header.cupsBitsPerColor == 8)
4767
#endif /* dev_t_proc_encode_color */
4768
0
  {
4769
#ifdef CUPS_DEBUG
4770
    dmprintf1(pdev->memory, "DEBUG: Using user-defined profile \"%s\"...\n", cups->Profile);
4771
#endif /* CUPS_DEBUG */
4772
4773
0
    if (sscanf(cups->Profile, "%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f", &d, &g,
4774
0
               m[0] + 0, m[0] + 1, m[0] + 2,
4775
0
               m[1] + 0, m[1] + 1, m[1] + 2,
4776
0
               m[2] + 0, m[2] + 1, m[2] + 2) != 11)
4777
0
      dmprintf(pdev->memory, "ERROR: User-defined profile does not contain 11 integers!\n");
4778
0
    else
4779
0
    {
4780
0
      cups->HaveProfile = 1;
4781
4782
0
      d       *= 0.001f;
4783
0
      g       *= 0.001f;
4784
0
      m[0][0] *= 0.001f;
4785
0
      m[0][1] *= 0.001f;
4786
0
      m[0][2] *= 0.001f;
4787
0
      m[1][0] *= 0.001f;
4788
0
      m[1][1] *= 0.001f;
4789
0
      m[1][2] *= 0.001f;
4790
0
      m[2][0] *= 0.001f;
4791
0
      m[2][1] *= 0.001f;
4792
0
      m[2][2] *= 0.001f;
4793
0
    }
4794
0
  }
4795
387k
#ifdef dev_t_proc_encode_color
4796
387k
  else if (cups->PPD)
4797
#else
4798
  else if (cups->PPD && cups->header.cupsBitsPerColor == 8)
4799
#endif /* dev_t_proc_encode_color */
4800
0
  {
4801
   /*
4802
    * Find the appropriate color profile...
4803
    */
4804
4805
0
    if (pdev->HWResolution[0] != pdev->HWResolution[1])
4806
0
      sprintf(resolution, "%.0fx%.0fdpi", pdev->HWResolution[0],
4807
0
              pdev->HWResolution[1]);
4808
0
    else
4809
0
      sprintf(resolution, "%.0fdpi", pdev->HWResolution[0]);
4810
4811
0
    for (i = 0, profile = cups->PPD->profiles;
4812
0
         i < cups->PPD->num_profiles;
4813
0
   i ++, profile ++)
4814
0
      if ((strcmp(profile->resolution, resolution) == 0 ||
4815
0
           profile->resolution[0] == '-') &&
4816
0
          (strcmp(profile->media_type, cups->header.MediaType) == 0 ||
4817
0
           profile->media_type[0] == '-'))
4818
0
  break;
4819
4820
   /*
4821
    * If we found a color profile, use it!
4822
    */
4823
4824
0
    if (i < cups->PPD->num_profiles)
4825
0
    {
4826
#ifdef CUPS_DEBUG
4827
      dmprintf(pdev->memory, "DEBUG: Using color profile in PPD file!\n");
4828
#endif /* CUPS_DEBUG */
4829
4830
0
      cups->HaveProfile = 1;
4831
4832
0
      d = profile->density;
4833
0
      g = profile->gamma;
4834
4835
0
      memcpy(m, profile->matrix, sizeof(m));
4836
0
    }
4837
0
  }
4838
4839
387k
  if (cups->HaveProfile)
4840
0
  {
4841
0
    for (i = 0; i < 3; i ++)
4842
0
      for (j = 0; j < 3; j ++)
4843
0
  for (k = 0; k <= CUPS_MAX_VALUE; k ++)
4844
0
  {
4845
0
          cups->Matrix[i][j][k] = (int)((float)k * m[i][j] + 0.5);
4846
4847
#ifdef CUPS_DEBUG
4848
          if ((k & 4095) == 0)
4849
            dmprintf4(pdev->memory, "DEBUG2: cups->Matrix[%d][%d][%d] = %d\n",
4850
                      i, j, k, cups->Matrix[i][j][k]);
4851
#endif /* CUPS_DEBUG */
4852
0
        }
4853
4854
4855
0
    for (k = 0; k <= CUPS_MAX_VALUE; k ++)
4856
0
    {
4857
0
      cups->Density[k] = (int)((float)CUPS_MAX_VALUE * d *
4858
0
                       pow((float)k / (float)CUPS_MAX_VALUE, g) +
4859
0
           0.5);
4860
4861
#ifdef CUPS_DEBUG
4862
      if ((k & 4095) == 0)
4863
        dmprintf2(pdev->memory, "DEBUG2: cups->Density[%d] = %d\n", k, cups->Density[k]);
4864
#endif /* CUPS_DEBUG */
4865
0
    }
4866
0
  }
4867
387k
  else
4868
387k
  {
4869
12.6G
    for (k = 0; k <= CUPS_MAX_VALUE; k ++)
4870
12.6G
      cups->Density[k] = k;
4871
387k
  }
4872
387k
  if (!cups->user_icc) {
4873
    /* Set up the ICC profile for ghostscript to use based upon the color space.
4874
       This is different than the PPD profile above which appears to be some sort
4875
       of matrix based TRC profile */
4876
337k
    switch (cups->header.cupsColorSpace)
4877
337k
    {
4878
17
      default :
4879
3.06k
      case CUPS_CSPACE_RGBW :
4880
132k
      case CUPS_CSPACE_RGB :
4881
133k
      case CUPS_CSPACE_SRGB :
4882
137k
      case CUPS_CSPACE_ADOBERGB :
4883
139k
      case CUPS_CSPACE_RGBA :
4884
140k
      case CUPS_CSPACE_CMY :
4885
140k
      case CUPS_CSPACE_YMC :
4886
140k
#    ifdef CUPS_RASTER_HAVE_COLORIMETRIC
4887
141k
      case CUPS_CSPACE_CIELab :
4888
185k
      case CUPS_CSPACE_ICC1 :
4889
186k
      case CUPS_CSPACE_ICC2 :
4890
189k
      case CUPS_CSPACE_ICC3 :
4891
191k
      case CUPS_CSPACE_ICC4 :
4892
206k
      case CUPS_CSPACE_ICC5 :
4893
212k
      case CUPS_CSPACE_ICC6 :
4894
213k
      case CUPS_CSPACE_ICC7 :
4895
213k
      case CUPS_CSPACE_ICC8 :
4896
216k
      case CUPS_CSPACE_ICC9 :
4897
217k
      case CUPS_CSPACE_ICCA :
4898
218k
      case CUPS_CSPACE_ICCB :
4899
218k
      case CUPS_CSPACE_ICCC :
4900
219k
      case CUPS_CSPACE_ICCD :
4901
221k
      case CUPS_CSPACE_ICCE :
4902
222k
      case CUPS_CSPACE_ICCF :
4903
222k
#    endif /* CUPS_RASTER_HAVE_COLORIMETRIC */
4904
222k
        if (!pdev->icc_struct || (pdev->icc_struct &&
4905
222k
             pdev->icc_struct->device_profile[gsDEFAULTPROFILE]->data_cs != gsRGB)) {
4906
4907
33.3k
          if (pdev->icc_struct) {
4908
33.3k
              rc_decrement(pdev->icc_struct, "cups_set_color_info");
4909
33.3k
          }
4910
33.3k
          pdev->icc_struct = gsicc_new_device_profile_array(pdev);
4911
4912
33.3k
          code = gsicc_set_device_profile(pdev, pdev->memory,
4913
33.3k
              (char *)DEFAULT_RGB_ICC, gsDEFAULTPROFILE);
4914
33.3k
          }
4915
222k
        break;
4916
4917
18.2k
      case CUPS_CSPACE_W :
4918
19.1k
      case CUPS_CSPACE_SW :
4919
22.8k
      case CUPS_CSPACE_WHITE :
4920
65.9k
      case CUPS_CSPACE_K :
4921
71.7k
      case CUPS_CSPACE_GOLD :
4922
74.2k
      case CUPS_CSPACE_SILVER :
4923
74.2k
        if (!pdev->icc_struct || (pdev->icc_struct &&
4924
39.2k
             pdev->icc_struct->device_profile[gsDEFAULTPROFILE]->data_cs != gsGRAY)) {
4925
4926
39.2k
          if (pdev->icc_struct) {
4927
0
              rc_decrement(pdev->icc_struct, "cups_set_color_info");
4928
0
          }
4929
39.2k
          pdev->icc_struct = gsicc_new_device_profile_array(pdev);
4930
4931
39.2k
          code = gsicc_set_device_profile(pdev, pdev->memory->non_gc_memory,
4932
39.2k
              (char *)DEFAULT_GRAY_ICC, gsDEFAULTPROFILE);
4933
39.2k
        }
4934
74.2k
        break;
4935
8.41k
      case CUPS_CSPACE_KCMYcm :
4936
8.41k
#    ifdef CUPS_RASTER_HAVE_COLORIMETRIC
4937
8.41k
      case CUPS_CSPACE_CIEXYZ :
4938
8.41k
#endif
4939
12.1k
      case CUPS_CSPACE_CMYK :
4940
14.3k
      case CUPS_CSPACE_YMCK :
4941
17.4k
      case CUPS_CSPACE_KCMY :
4942
38.8k
      case CUPS_CSPACE_GMCK :
4943
41.6k
      case CUPS_CSPACE_GMCS :
4944
41.6k
        if (!pdev->icc_struct || (pdev->icc_struct &&
4945
41.6k
             pdev->icc_struct->device_profile[gsDEFAULTPROFILE]->data_cs != gsCMYK)) {
4946
4947
2.44k
          if (pdev->icc_struct) {
4948
2.44k
              rc_decrement(pdev->icc_struct, "cups_set_color_info");
4949
2.44k
          }
4950
2.44k
          pdev->icc_struct = gsicc_new_device_profile_array(pdev);
4951
4952
2.44k
          code = gsicc_set_device_profile(pdev, pdev->memory,
4953
2.44k
              (char *)DEFAULT_CMYK_ICC, gsDEFAULTPROFILE);
4954
2.44k
          }
4955
41.6k
        break;
4956
337k
    }
4957
337k
  }
4958
387k
  return(code);
4959
387k
}
4960
4961
/*
4962
 * 'cups_sync_output()' - Keep the user informed of our status...
4963
 */
4964
4965
private int       /* O - Error status */
4966
cups_sync_output(gx_device *pdev) /* I - Device info */
4967
0
{
4968
0
  dmprintf1(pdev->memory, "INFO: Processing page %d...\n", cups->page);
4969
4970
0
  return (0);
4971
0
}
4972
4973
4974
/*
4975
 * 'cups_print_chunked()' - Print a page of chunked pixels.
4976
 */
4977
4978
static int
4979
cups_print_chunked(gx_device_printer *pdev,
4980
          /* I - Printer device */
4981
                   unsigned char     *src,
4982
          /* I - Scanline buffer */
4983
       unsigned char     *dst,
4984
          /* I - Bitmap buffer */
4985
       int               srcbytes)
4986
          /* I - Number of bytes in src */
4987
33.2k
{
4988
33.2k
  int   y;      /* Looping var */
4989
33.2k
  unsigned char *srcptr,    /* Pointer to data */
4990
33.2k
    *dstptr;    /* Pointer to bits */
4991
33.2k
  int   count;      /* Count for loop */
4992
33.2k
  int   xflip,      /* Flip scanline? */
4993
#ifdef CUPS_DEBUG
4994
                yflip,      /* Reverse scanline order? */
4995
#endif
4996
33.2k
                ystart, yend, ystep;    /* Loop control for scanline order */
4997
33.2k
  ppd_attr_t    *backside = NULL;
4998
33.2k
  const char    *backside_str = "Normal";
4999
33.2k
  int           flip_duplex = 0;
5000
5001
#ifdef CUPS_DEBUG
5002
  dmprintf1(pdev->memory, "DEBUG2: cups->header.Duplex = %d\n", cups->header.Duplex);
5003
  dmprintf1(pdev->memory, "DEBUG2: cups->header.Tumble = %d\n", cups->header.Tumble);
5004
  dmprintf1(pdev->memory, "DEBUG2: cups->page = %d\n", cups->page);
5005
  dmprintf1(pdev->memory, "DEBUG2: cups->PPD = %p\n", cups->PPD);
5006
#endif /* CUPS_DEBUG */
5007
5008
33.2k
  if (cups->PPD) {
5009
0
    backside = ppdFindAttr(cups->PPD, "cupsBackSide", NULL);
5010
0
    if (backside) {
5011
0
      backside_str = backside->value;
5012
0
      cups->PPD->flip_duplex = 0;
5013
0
    }
5014
0
    flip_duplex = cups->PPD->flip_duplex;
5015
0
  }
5016
33.2k
  else
5017
33.2k
    backside_str = cups->cupsBackSideOrientation;
5018
#ifdef CUPS_DEBUG
5019
  dmprintf1(pdev->memory, "DEBUG2: Back side orientation: %s\n", backside_str);
5020
#endif /* CUPS_DEBUG */
5021
33.2k
  if (cups->header.Duplex &&
5022
33.2k
      ((!cups->header.Tumble &&
5023
0
  (flip_duplex ||
5024
0
   (!strcasecmp(backside_str, "Rotated")))) ||
5025
0
       (cups->header.Tumble &&
5026
0
  ((!strcasecmp(backside_str, "Flipped") ||
5027
0
    !strcasecmp(backside_str, "ManualTumble"))))) &&
5028
33.2k
      !(cups->page & 1))
5029
0
    xflip = 1;
5030
33.2k
  else
5031
33.2k
    xflip = 0;
5032
33.2k
  if (cups->header.Duplex &&
5033
33.2k
      ((!cups->header.Tumble &&
5034
0
  (flip_duplex ||
5035
0
   ((!strcasecmp(backside_str, "Flipped") ||
5036
0
     !strcasecmp(backside_str, "Rotated"))))) ||
5037
0
       (cups->header.Tumble &&
5038
0
  (!strcasecmp(backside_str, "ManualTumble")))) &&
5039
33.2k
      !(cups->page & 1)) {
5040
#ifdef CUPS_DEBUG
5041
    yflip = 1;
5042
#endif
5043
0
    ystart = cups->height - 1;
5044
0
    yend = -1;
5045
0
    ystep = -1;
5046
33.2k
  } else {
5047
#ifdef CUPS_DEBUG
5048
    yflip = 0;
5049
#endif
5050
33.2k
    ystart = 0;
5051
33.2k
    yend = cups->height;
5052
33.2k
    ystep = 1;
5053
33.2k
  }
5054
5055
#ifdef CUPS_DEBUG
5056
  dmprintf3(pdev->memory, "DEBUG: cups_print_chunked: xflip = %d, yflip = %d, height = %d\n",
5057
            xflip, yflip, cups->height);
5058
#endif /* CUPS_DEBUG */
5059
5060
 /*
5061
  * Loop through the page bitmap and write chunked pixels, reversing as
5062
  * needed...
5063
  */
5064
78.8M
  for (y = ystart; y != yend; y += ystep)
5065
78.7M
  {
5066
   /*
5067
    * Grab the scanline data...
5068
    */
5069
5070
78.7M
    if (gdev_prn_get_bits((gx_device_printer *)pdev, y, src, &srcptr) < 0)
5071
1
    {
5072
1
      dmprintf1(pdev->memory, "ERROR: Unable to get scanline %d!\n", y);
5073
1
      return_error(gs_error_unknownerror);
5074
1
    }
5075
5076
78.7M
    if (xflip)
5077
0
    {
5078
     /*
5079
      * Flip the raster data before writing it...
5080
      */
5081
5082
0
      if (srcptr[0] == 0 && memcmp(srcptr, srcptr + 1, srcbytes - 1) == 0)
5083
0
  memset(dst, 0, cups->header.cupsBytesPerLine);
5084
0
      else
5085
0
      {
5086
0
        dstptr = dst;
5087
0
  count  = srcbytes;
5088
5089
0
  switch (cups->color_info.depth)
5090
0
  {
5091
0
          case 1 : /* B&W bitmap */
5092
0
        for (srcptr += srcbytes - 1;
5093
0
             count > 0;
5094
0
       count --, srcptr --, dstptr ++)
5095
0
        {
5096
0
          *dstptr = cups->RevUpper1[*srcptr & 15] |
5097
0
              cups->RevLower1[*srcptr >> 4];
5098
0
              }
5099
0
        break;
5100
5101
0
    case 2 : /* 2-bit W/K image */
5102
0
        for (srcptr += srcbytes - 1;
5103
0
             count > 0;
5104
0
       count --, srcptr --, dstptr ++)
5105
0
        {
5106
0
          *dstptr = cups->RevUpper2[*srcptr & 15] |
5107
0
              cups->RevLower2[*srcptr >> 4];
5108
0
              }
5109
0
        break;
5110
5111
0
    case 4 : /* 1-bit RGB/CMY/CMYK bitmap or 4-bit W/K image */
5112
0
        for (srcptr += srcbytes - 1;
5113
0
             count > 0;
5114
0
       count --, srcptr --, dstptr ++)
5115
0
          *dstptr = (*srcptr >> 4) | (*srcptr << 4);
5116
0
        break;
5117
5118
0
          case 8 : /* 2-bit RGB/CMY/CMYK or 8-bit W/K image */
5119
0
        for (srcptr += srcbytes - 1;
5120
0
             count > 0;
5121
0
       count --, srcptr --, dstptr ++)
5122
0
          *dstptr = *srcptr;
5123
0
        break;
5124
5125
0
          case 16 : /* 4-bit RGB/CMY/CMYK or 16-bit W/K image */
5126
0
        for (srcptr += srcbytes - 2;
5127
0
             count > 0;
5128
0
       count -= 2, srcptr -= 2, dstptr += 2)
5129
0
        {
5130
0
          dstptr[0] = srcptr[0];
5131
0
          dstptr[1] = srcptr[1];
5132
0
              }
5133
0
        break;
5134
5135
0
          case 24 : /* 8-bit RGB or CMY image */
5136
0
        for (srcptr += srcbytes - 3;
5137
0
             count > 0;
5138
0
       count -= 3, srcptr -= 3, dstptr += 3)
5139
0
        {
5140
0
          dstptr[0] = srcptr[0];
5141
0
          dstptr[1] = srcptr[1];
5142
0
          dstptr[2] = srcptr[2];
5143
0
              }
5144
0
        break;
5145
5146
0
          case 32 : /* 8-bit CMYK image */
5147
0
        for (srcptr += srcbytes - 4;
5148
0
             count > 0;
5149
0
       count -= 4, srcptr -= 4, dstptr += 4)
5150
0
        {
5151
0
          dstptr[0] = srcptr[0];
5152
0
          dstptr[1] = srcptr[1];
5153
0
          dstptr[2] = srcptr[2];
5154
0
          dstptr[3] = srcptr[3];
5155
0
              }
5156
0
        break;
5157
5158
0
          case 48 : /* 16-bit RGB or CMY image */
5159
0
        for (srcptr += srcbytes - 6;
5160
0
             count > 0;
5161
0
       count -= 6, srcptr -= 6, dstptr += 6)
5162
0
        {
5163
0
          dstptr[0] = srcptr[0];
5164
0
          dstptr[1] = srcptr[1];
5165
0
          dstptr[2] = srcptr[2];
5166
0
          dstptr[3] = srcptr[3];
5167
0
          dstptr[4] = srcptr[4];
5168
0
          dstptr[5] = srcptr[5];
5169
0
              }
5170
0
        break;
5171
5172
0
          case 64 : /* 16-bit CMYK image */
5173
0
        for (srcptr += srcbytes - 8;
5174
0
             count > 0;
5175
0
       count -= 8, srcptr -= 8, dstptr += 8)
5176
0
        {
5177
0
          dstptr[0] = srcptr[0];
5178
0
          dstptr[1] = srcptr[1];
5179
0
          dstptr[2] = srcptr[2];
5180
0
          dstptr[3] = srcptr[3];
5181
0
          dstptr[4] = srcptr[4];
5182
0
          dstptr[5] = srcptr[5];
5183
0
          dstptr[6] = srcptr[6];
5184
0
          dstptr[7] = srcptr[7];
5185
0
              }
5186
0
        break;
5187
0
        }
5188
0
      }
5189
5190
     /*
5191
      * Write the bitmap data to the raster stream...
5192
      */
5193
5194
0
      cupsRasterWritePixels(cups->stream, dst, cups->header.cupsBytesPerLine);
5195
0
    }
5196
78.7M
    else
5197
78.7M
    {
5198
     /*
5199
      * Write the scanline data to the raster stream...
5200
      */
5201
5202
78.7M
      cupsRasterWritePixels(cups->stream, srcptr, cups->header.cupsBytesPerLine);
5203
78.7M
    }
5204
78.7M
  }
5205
33.2k
  return (0);
5206
33.2k
}
5207
5208
5209
/*
5210
 * 'cups_print_banded()' - Print a page of banded pixels.
5211
 */
5212
5213
static int
5214
cups_print_banded(gx_device_printer *pdev,
5215
          /* I - Printer device */
5216
                  unsigned char     *src,
5217
          /* I - Scanline buffer */
5218
      unsigned char     *dst,
5219
          /* I - Bitmap buffer */
5220
      int               srcbytes)
5221
          /* I - Number of bytes in src */
5222
0
{
5223
0
  int   x;      /* Looping var */
5224
0
  int   y;      /* Looping var */
5225
0
  int   bandbytes;    /* Bytes per band */
5226
0
  unsigned char bit;      /* Current bit */
5227
0
  unsigned char temp;     /* Temporary variable */
5228
0
  unsigned char *srcptr;    /* Pointer to data */
5229
0
  unsigned char *cptr, *mptr, *yptr,  /* Pointer to components */
5230
0
    *kptr, *lcptr, *lmptr;  /* ... */
5231
0
  int   xflip,      /* Flip scanline? */
5232
#ifdef CUPS_DEBUG
5233
                yflip,      /* Reverse scanline order? */
5234
#endif
5235
0
                ystart, yend, ystep;    /* Loop control for scanline order */
5236
0
  ppd_attr_t    *backside = NULL;
5237
0
  const char     *backside_str = "Normal";
5238
0
  int           flip_duplex = 0;
5239
5240
5241
#ifdef CUPS_DEBUG
5242
  dmprintf1(pdev->memory, "DEBUG2: cups->header.Duplex = %d\n", cups->header.Duplex);
5243
  dmprintf1(pdev->memory, "DEBUG2: cups->header.Tumble = %d\n", cups->header.Tumble);
5244
  dmprintf1(pdev->memory, "DEBUG2: cups->page = %d\n", cups->page);
5245
  dmprintf1(pdev->memory, "DEBUG2: cups->PPD = %p\n", cups->PPD);
5246
#endif /* CUPS_DEBUG */
5247
5248
0
  if (cups->PPD) {
5249
0
    backside = ppdFindAttr(cups->PPD, "cupsBackSide", NULL);
5250
0
    if (backside) {
5251
0
      backside_str = backside->value;
5252
0
      cups->PPD->flip_duplex = 0;
5253
0
    }
5254
0
    flip_duplex = cups->PPD->flip_duplex;
5255
0
  }
5256
0
  else
5257
0
    backside_str = cups->cupsBackSideOrientation;
5258
#ifdef CUPS_DEBUG
5259
  dmprintf1(pdev->memory, "DEBUG2: Back side orientation: %s\n", backside_str);
5260
#endif /* CUPS_DEBUG */
5261
0
  if (cups->header.Duplex &&
5262
0
      ((!cups->header.Tumble &&
5263
0
  (flip_duplex ||
5264
0
   (!strcasecmp(backside_str, "Rotated")))) ||
5265
0
       (cups->header.Tumble &&
5266
0
  ((!strcasecmp(backside_str, "Flipped") ||
5267
0
    !strcasecmp(backside_str, "ManualTumble"))))) &&
5268
0
      !(cups->page & 1))
5269
0
    xflip = 1;
5270
0
  else
5271
0
    xflip = 0;
5272
0
  if (cups->header.Duplex &&
5273
0
      ((!cups->header.Tumble &&
5274
0
  (flip_duplex ||
5275
0
   ((!strcasecmp(backside_str, "Flipped") ||
5276
0
     !strcasecmp(backside_str, "Rotated"))))) ||
5277
0
       (cups->header.Tumble &&
5278
0
  (!strcasecmp(backside_str, "ManualTumble")))) &&
5279
0
      !(cups->page & 1)) {
5280
#ifdef CUPS_DEBUG
5281
    yflip = 1;
5282
#endif
5283
0
    ystart = cups->height - 1;
5284
0
    yend = -1;
5285
0
    ystep = -1;
5286
0
  } else {
5287
#ifdef CUPS_DEBUG
5288
    yflip = 0;
5289
#endif
5290
0
    ystart = 0;
5291
0
    yend = cups->height;
5292
0
    ystep = 1;
5293
0
  }
5294
5295
#ifdef CUPS_DEBUG
5296
  dmprintf3(pdev->memory, "DEBUG: cups_print_chunked: xflip = %d, yflip = %d, height = %d\n",
5297
            xflip, yflip, cups->height);
5298
#endif /* CUPS_DEBUG */
5299
5300
 /*
5301
  * Loop through the page bitmap and write banded pixels...  We have
5302
  * to separate each chunked color as needed...
5303
  */
5304
5305
0
#ifdef CUPS_RASTER_SYNCv1
5306
0
  bandbytes = cups->header.cupsBytesPerLine / cups->header.cupsNumColors;
5307
#else
5308
  if (cups->header.cupsColorSpace == CUPS_CSPACE_KCMYcm &&
5309
      cups->header.cupsBitsPerColor == 1)
5310
    bandbytes = cups->header.cupsBytesPerLine / 6;
5311
  else
5312
    bandbytes = cups->header.cupsBytesPerLine / cups->color_info.num_components;
5313
#endif /* CUPS_RASTER_SYNCv1 */
5314
5315
0
  for (y = ystart; y != yend; y += ystep)
5316
0
  {
5317
   /*
5318
    * Grab the scanline data...
5319
    */
5320
5321
0
    if (gdev_prn_get_bits((gx_device_printer *)pdev, y, src, &srcptr) < 0)
5322
0
    {
5323
0
      dmprintf1(pdev->memory, "ERROR: Unable to get scanline %d!\n", y);
5324
0
      return_error(gs_error_unknownerror);
5325
0
    }
5326
5327
   /*
5328
    * Separate the chunked colors into their components...
5329
    */
5330
5331
0
    if (srcptr[0] == 0 && memcmp(srcptr, srcptr + 1, srcbytes - 1) == 0)
5332
0
      memset(dst, 0, cups->header.cupsBytesPerLine);
5333
0
    else
5334
0
    {
5335
0
      if (xflip)
5336
0
        cptr = dst + bandbytes - 1;
5337
0
      else
5338
0
        cptr = dst;
5339
5340
0
      mptr  = cptr + bandbytes;
5341
0
      yptr  = mptr + bandbytes;
5342
0
      kptr  = yptr + bandbytes;
5343
0
      lcptr = kptr + bandbytes;
5344
0
      lmptr = lcptr + bandbytes;
5345
5346
0
      switch (cups->header.cupsBitsPerColor)
5347
0
      {
5348
0
  default :
5349
0
            memset(dst, 0, cups->header.cupsBytesPerLine);
5350
5351
0
            switch (cups->header.cupsColorSpace)
5352
0
      {
5353
0
        default :
5354
0
            for (x = cups->width, bit = xflip ? 1 << (x & 7) : 128;
5355
0
           x > 0;
5356
0
           x --, srcptr ++)
5357
0
      {
5358
0
        if (*srcptr & 0x40)
5359
0
          *cptr |= bit;
5360
0
        if (*srcptr & 0x20)
5361
0
          *mptr |= bit;
5362
0
        if (*srcptr & 0x10)
5363
0
          *yptr |= bit;
5364
5365
0
                    if (xflip)
5366
0
        {
5367
0
          if (bit < 128)
5368
0
      bit <<= 1;
5369
0
          else
5370
0
          {
5371
0
      cptr --;
5372
0
      mptr --;
5373
0
      yptr --;
5374
0
      bit = 1;
5375
0
          }
5376
0
        }
5377
0
        else
5378
0
          bit >>= 1;
5379
5380
0
        x --;
5381
0
        if (x == 0)
5382
0
          break;
5383
5384
0
        if (*srcptr & 0x4)
5385
0
          *cptr |= bit;
5386
0
        if (*srcptr & 0x2)
5387
0
          *mptr |= bit;
5388
0
        if (*srcptr & 0x1)
5389
0
          *yptr |= bit;
5390
5391
0
                    if (xflip)
5392
0
        {
5393
0
          if (bit < 128)
5394
0
      bit <<= 1;
5395
0
          else
5396
0
          {
5397
0
      cptr --;
5398
0
      mptr --;
5399
0
      yptr --;
5400
0
      bit = 1;
5401
0
          }
5402
0
        }
5403
0
        else if (bit > 1)
5404
0
          bit >>= 1;
5405
0
        else
5406
0
        {
5407
0
          cptr ++;
5408
0
          mptr ++;
5409
0
          yptr ++;
5410
0
          bit = 128;
5411
0
        }
5412
0
      }
5413
0
            break;
5414
0
        case CUPS_CSPACE_GMCK :
5415
0
        case CUPS_CSPACE_GMCS :
5416
0
        case CUPS_CSPACE_RGBA :
5417
0
        case CUPS_CSPACE_RGBW :
5418
0
        case CUPS_CSPACE_CMYK :
5419
0
        case CUPS_CSPACE_YMCK :
5420
0
        case CUPS_CSPACE_KCMY :
5421
0
            for (x = cups->width, bit = xflip ? 1 << (x & 7) : 128;
5422
0
           x > 0;
5423
0
           x --, srcptr ++)
5424
0
      {
5425
0
        if (*srcptr & 0x80)
5426
0
          *cptr |= bit;
5427
0
        if (*srcptr & 0x40)
5428
0
          *mptr |= bit;
5429
0
        if (*srcptr & 0x20)
5430
0
          *yptr |= bit;
5431
0
        if (*srcptr & 0x10)
5432
0
          *kptr |= bit;
5433
5434
0
                    if (xflip)
5435
0
        {
5436
0
          if (bit < 128)
5437
0
      bit <<= 1;
5438
0
          else
5439
0
          {
5440
0
      cptr --;
5441
0
      mptr --;
5442
0
      yptr --;
5443
0
      kptr --;
5444
0
      bit = 1;
5445
0
          }
5446
0
        }
5447
0
        else
5448
0
          bit >>= 1;
5449
5450
0
        x --;
5451
0
        if (x == 0)
5452
0
          break;
5453
5454
0
        if (*srcptr & 0x8)
5455
0
          *cptr |= bit;
5456
0
        if (*srcptr & 0x4)
5457
0
          *mptr |= bit;
5458
0
        if (*srcptr & 0x2)
5459
0
          *yptr |= bit;
5460
0
        if (*srcptr & 0x1)
5461
0
          *kptr |= bit;
5462
5463
0
                    if (xflip)
5464
0
        {
5465
0
          if (bit < 128)
5466
0
      bit <<= 1;
5467
0
          else
5468
0
          {
5469
0
      cptr --;
5470
0
      mptr --;
5471
0
      yptr --;
5472
0
      kptr --;
5473
0
      bit = 1;
5474
0
          }
5475
0
        }
5476
0
        else if (bit > 1)
5477
0
          bit >>= 1;
5478
0
        else
5479
0
        {
5480
0
          cptr ++;
5481
0
          mptr ++;
5482
0
          yptr ++;
5483
0
          kptr ++;
5484
0
          bit = 128;
5485
0
        }
5486
0
      }
5487
0
            break;
5488
0
        case CUPS_CSPACE_KCMYcm :
5489
0
            for (x = cups->width, bit = xflip ? 1 << (x & 7) : 128;
5490
0
           x > 0;
5491
0
           x --, srcptr ++)
5492
0
      {
5493
                   /*
5494
                    * Note: Because of the way the pointers are setup,
5495
                    *       the following code is correct even though
5496
                    *       the names don't match...
5497
                    */
5498
5499
0
        if (*srcptr & 0x20)
5500
0
          *cptr |= bit;
5501
0
        if (*srcptr & 0x10)
5502
0
          *mptr |= bit;
5503
0
        if (*srcptr & 0x08)
5504
0
          *yptr |= bit;
5505
0
        if (*srcptr & 0x04)
5506
0
          *kptr |= bit;
5507
0
        if (*srcptr & 0x02)
5508
0
          *lcptr |= bit;
5509
0
        if (*srcptr & 0x01)
5510
0
          *lmptr |= bit;
5511
5512
0
                    if (xflip)
5513
0
        {
5514
0
          if (bit < 128)
5515
0
      bit <<= 1;
5516
0
          else
5517
0
          {
5518
0
      cptr --;
5519
0
      mptr --;
5520
0
      yptr --;
5521
0
      kptr --;
5522
0
      lcptr --;
5523
0
      lmptr --;
5524
0
      bit = 1;
5525
0
          }
5526
0
        }
5527
0
        else if (bit > 1)
5528
0
          bit >>= 1;
5529
0
        else
5530
0
        {
5531
0
          cptr ++;
5532
0
          mptr ++;
5533
0
          yptr ++;
5534
0
          kptr ++;
5535
0
          lcptr ++;
5536
0
          lmptr ++;
5537
0
          bit = 128;
5538
0
        }
5539
0
      }
5540
0
            break;
5541
0
      }
5542
0
            break;
5543
5544
0
  case 2 :
5545
0
            memset(dst, 0, cups->header.cupsBytesPerLine);
5546
5547
0
            switch (cups->header.cupsColorSpace)
5548
0
      {
5549
0
        default :
5550
0
            for (x = cups->width, bit = xflip ? 3 << (2 * (x & 3)) : 0xc0;
5551
0
           x > 0;
5552
0
           x --, srcptr ++)
5553
0
        switch (bit)
5554
0
        {
5555
0
          case 0xc0 :
5556
0
        if ((temp = *srcptr & 0x30) != 0)
5557
0
          *cptr |= temp << 2;
5558
0
        if ((temp = *srcptr & 0x0c) != 0)
5559
0
          *mptr |= temp << 4;
5560
0
        if ((temp = *srcptr & 0x03) != 0)
5561
0
          *yptr |= temp << 6;
5562
5563
0
                          if (xflip)
5564
0
        {
5565
0
          bit = 0x03;
5566
0
          cptr --;
5567
0
          mptr --;
5568
0
          yptr --;
5569
0
        }
5570
0
        else
5571
0
          bit = 0x30;
5572
0
        break;
5573
0
          case 0x30 :
5574
0
        if ((temp = *srcptr & 0x30) != 0)
5575
0
          *cptr |= temp;
5576
0
        if ((temp = *srcptr & 0x0c) != 0)
5577
0
          *mptr |= temp << 2;
5578
0
        if ((temp = *srcptr & 0x03) != 0)
5579
0
          *yptr |= temp << 4;
5580
5581
0
        if (xflip)
5582
0
          bit = 0xc0;
5583
0
        else
5584
0
          bit = 0x0c;
5585
0
        break;
5586
0
          case 0x0c :
5587
0
        if ((temp = *srcptr & 0x30) != 0)
5588
0
          *cptr |= temp >> 2;
5589
0
        if ((temp = *srcptr & 0x0c) != 0)
5590
0
          *mptr |= temp;
5591
0
        if ((temp = *srcptr & 0x03) != 0)
5592
0
          *yptr |= temp << 2;
5593
5594
0
        if (xflip)
5595
0
          bit = 0x30;
5596
0
        else
5597
0
          bit = 0x03;
5598
0
        break;
5599
0
          case 0x03 :
5600
0
        if ((temp = *srcptr & 0x30) != 0)
5601
0
          *cptr |= temp >> 4;
5602
0
        if ((temp = *srcptr & 0x0c) != 0)
5603
0
          *mptr |= temp >> 2;
5604
0
        if ((temp = *srcptr & 0x03) != 0)
5605
0
          *yptr |= temp;
5606
5607
0
        if (xflip)
5608
0
          bit = 0x0c;
5609
0
        else
5610
0
        {
5611
0
          bit = 0xc0;
5612
0
          cptr ++;
5613
0
          mptr ++;
5614
0
          yptr ++;
5615
0
        }
5616
0
        break;
5617
0
                    }
5618
0
            break;
5619
0
        case CUPS_CSPACE_GMCK :
5620
0
        case CUPS_CSPACE_GMCS :
5621
0
        case CUPS_CSPACE_RGBA :
5622
0
        case CUPS_CSPACE_RGBW :
5623
0
        case CUPS_CSPACE_CMYK :
5624
0
        case CUPS_CSPACE_YMCK :
5625
0
        case CUPS_CSPACE_KCMY :
5626
0
        case CUPS_CSPACE_KCMYcm :
5627
0
            for (x = cups->width, bit = xflip ? 3 << (2 * (x & 3)) : 0xc0;
5628
0
           x > 0;
5629
0
           x --, srcptr ++)
5630
0
        switch (bit)
5631
0
        {
5632
0
          case 0xc0 :
5633
0
              if ((temp = *srcptr & 0xc0) != 0)
5634
0
          *cptr |= temp;
5635
0
        if ((temp = *srcptr & 0x30) != 0)
5636
0
          *mptr |= temp << 2;
5637
0
        if ((temp = *srcptr & 0x0c) != 0)
5638
0
          *yptr |= temp << 4;
5639
0
        if ((temp = *srcptr & 0x03) != 0)
5640
0
          *kptr |= temp << 6;
5641
5642
0
                          if (xflip)
5643
0
        {
5644
0
          bit = 0x03;
5645
0
          cptr --;
5646
0
          mptr --;
5647
0
          yptr --;
5648
0
          kptr --;
5649
0
        }
5650
0
        else
5651
0
          bit = 0x30;
5652
0
        break;
5653
0
          case 0x30 :
5654
0
              if ((temp = *srcptr & 0xc0) != 0)
5655
0
          *cptr |= temp >> 2;
5656
0
        if ((temp = *srcptr & 0x30) != 0)
5657
0
          *mptr |= temp;
5658
0
        if ((temp = *srcptr & 0x0c) != 0)
5659
0
          *yptr |= temp << 2;
5660
0
        if ((temp = *srcptr & 0x03) != 0)
5661
0
          *kptr |= temp << 4;
5662
5663
0
        if (xflip)
5664
0
          bit = 0xc0;
5665
0
        else
5666
0
          bit = 0x0c;
5667
0
        break;
5668
0
          case 0x0c :
5669
0
              if ((temp = *srcptr & 0xc0) != 0)
5670
0
          *cptr |= temp >> 4;
5671
0
        if ((temp = *srcptr & 0x30) != 0)
5672
0
          *mptr |= temp >> 2;
5673
0
        if ((temp = *srcptr & 0x0c) != 0)
5674
0
          *yptr |= temp;
5675
0
        if ((temp = *srcptr & 0x03) != 0)
5676
0
          *kptr |= temp << 2;
5677
5678
0
        if (xflip)
5679
0
          bit = 0x30;
5680
0
        else
5681
0
          bit = 0x03;
5682
0
        break;
5683
0
          case 0x03 :
5684
0
              if ((temp = *srcptr & 0xc0) != 0)
5685
0
          *cptr |= temp >> 6;
5686
0
        if ((temp = *srcptr & 0x30) != 0)
5687
0
          *mptr |= temp >> 4;
5688
0
        if ((temp = *srcptr & 0x0c) != 0)
5689
0
          *yptr |= temp >> 2;
5690
0
        if ((temp = *srcptr & 0x03) != 0)
5691
0
          *kptr |= temp;
5692
5693
0
        if (xflip)
5694
0
          bit = 0x0c;
5695
0
        else
5696
0
        {
5697
0
          bit = 0xc0;
5698
0
          cptr ++;
5699
0
          mptr ++;
5700
0
          yptr ++;
5701
0
          kptr ++;
5702
0
        }
5703
0
        break;
5704
0
                    }
5705
0
            break;
5706
0
      }
5707
0
            break;
5708
5709
0
  case 4 :
5710
0
            memset(dst, 0, cups->header.cupsBytesPerLine);
5711
5712
0
            switch (cups->header.cupsColorSpace)
5713
0
      {
5714
0
        default :
5715
0
            for (x = cups->width, bit = xflip && (x & 1) ? 0xf0 : 0x0f;
5716
0
           x > 0;
5717
0
           x --, srcptr += 2)
5718
0
        switch (bit)
5719
0
        {
5720
0
          case 0xf0 :
5721
0
        if ((temp = srcptr[0] & 0x0f) != 0)
5722
0
          *cptr |= temp << 4;
5723
0
        if ((temp = srcptr[1] & 0xf0) != 0)
5724
0
          *mptr |= temp;
5725
0
        if ((temp = srcptr[1] & 0x0f) != 0)
5726
0
          *yptr |= temp << 4;
5727
5728
0
        bit = 0x0f;
5729
5730
0
                          if (xflip)
5731
0
        {
5732
0
          cptr --;
5733
0
          mptr --;
5734
0
          yptr --;
5735
0
        }
5736
0
        break;
5737
0
          case 0x0f :
5738
0
        if ((temp = srcptr[0] & 0x0f) != 0)
5739
0
          *cptr |= temp;
5740
0
        if ((temp = srcptr[1] & 0xf0) != 0)
5741
0
          *mptr |= temp >> 4;
5742
0
        if ((temp = srcptr[1] & 0x0f) != 0)
5743
0
          *yptr |= temp;
5744
5745
0
        bit = 0xf0;
5746
5747
0
                          if (!xflip)
5748
0
        {
5749
0
          cptr ++;
5750
0
          mptr ++;
5751
0
          yptr ++;
5752
0
        }
5753
0
        break;
5754
0
                    }
5755
0
            break;
5756
0
        case CUPS_CSPACE_GMCK :
5757
0
        case CUPS_CSPACE_GMCS :
5758
0
        case CUPS_CSPACE_RGBA :
5759
0
        case CUPS_CSPACE_RGBW :
5760
0
        case CUPS_CSPACE_CMYK :
5761
0
        case CUPS_CSPACE_YMCK :
5762
0
        case CUPS_CSPACE_KCMY :
5763
0
        case CUPS_CSPACE_KCMYcm :
5764
0
            for (x = cups->width, bit = xflip && (x & 1) ? 0xf0 : 0x0f;
5765
0
           x > 0;
5766
0
           x --, srcptr += 2)
5767
0
        switch (bit)
5768
0
        {
5769
0
          case 0xf0 :
5770
0
              if ((temp = srcptr[0] & 0xf0) != 0)
5771
0
          *cptr |= temp;
5772
0
        if ((temp = srcptr[0] & 0x0f) != 0)
5773
0
          *mptr |= temp << 4;
5774
0
        if ((temp = srcptr[1] & 0xf0) != 0)
5775
0
          *yptr |= temp;
5776
0
        if ((temp = srcptr[1] & 0x0f) != 0)
5777
0
          *kptr |= temp << 4;
5778
5779
0
        bit = 0x0f;
5780
5781
0
                          if (xflip)
5782
0
        {
5783
0
          cptr --;
5784
0
          mptr --;
5785
0
          yptr --;
5786
0
          kptr --;
5787
0
        }
5788
0
        break;
5789
0
          case 0x0f :
5790
0
              if ((temp = srcptr[0] & 0xf0) != 0)
5791
0
          *cptr |= temp >> 4;
5792
0
        if ((temp = srcptr[0] & 0x0f) != 0)
5793
0
          *mptr |= temp;
5794
0
        if ((temp = srcptr[1] & 0xf0) != 0)
5795
0
          *yptr |= temp >> 4;
5796
0
        if ((temp = srcptr[1] & 0x0f) != 0)
5797
0
          *kptr |= temp;
5798
5799
0
        bit = 0xf0;
5800
5801
0
                          if (!xflip)
5802
0
        {
5803
0
          cptr ++;
5804
0
          mptr ++;
5805
0
          yptr ++;
5806
0
          kptr ++;
5807
0
        }
5808
0
        break;
5809
0
                    }
5810
0
            break;
5811
0
      }
5812
0
            break;
5813
5814
0
  case 8 :
5815
0
            switch (cups->header.cupsColorSpace)
5816
0
      {
5817
0
        default :
5818
0
            if (xflip)
5819
0
              for (x = cups->width; x > 0; x --)
5820
0
        {
5821
0
          *cptr-- = *srcptr++;
5822
0
          *mptr-- = *srcptr++;
5823
0
          *yptr-- = *srcptr++;
5824
0
        }
5825
0
      else
5826
0
              for (x = cups->width; x > 0; x --)
5827
0
        {
5828
0
          *cptr++ = *srcptr++;
5829
0
          *mptr++ = *srcptr++;
5830
0
          *yptr++ = *srcptr++;
5831
0
        }
5832
0
            break;
5833
0
        case CUPS_CSPACE_GMCK :
5834
0
        case CUPS_CSPACE_GMCS :
5835
0
        case CUPS_CSPACE_RGBA :
5836
0
        case CUPS_CSPACE_RGBW :
5837
0
        case CUPS_CSPACE_CMYK :
5838
0
        case CUPS_CSPACE_YMCK :
5839
0
        case CUPS_CSPACE_KCMY :
5840
0
        case CUPS_CSPACE_KCMYcm :
5841
0
            if (xflip)
5842
0
              for (x = cups->width; x > 0; x --)
5843
0
        {
5844
0
          *cptr-- = *srcptr++;
5845
0
          *mptr-- = *srcptr++;
5846
0
          *yptr-- = *srcptr++;
5847
0
          *kptr-- = *srcptr++;
5848
0
        }
5849
0
      else
5850
0
              for (x = cups->width; x > 0; x --)
5851
0
        {
5852
0
          *cptr++ = *srcptr++;
5853
0
          *mptr++ = *srcptr++;
5854
0
          *yptr++ = *srcptr++;
5855
0
          *kptr++ = *srcptr++;
5856
0
        }
5857
0
            break;
5858
0
      }
5859
0
            break;
5860
5861
0
  case 16 :
5862
0
            switch (cups->header.cupsColorSpace)
5863
0
      {
5864
0
        default :
5865
0
            if (xflip)
5866
0
              for (x = cups->width; x > 0; x --, srcptr += 6)
5867
0
        {
5868
0
          *cptr-- = srcptr[1];
5869
0
          *cptr-- = srcptr[0];
5870
0
          *mptr-- = srcptr[3];
5871
0
          *mptr-- = srcptr[2];
5872
0
          *yptr-- = srcptr[5];
5873
0
          *yptr-- = srcptr[4];
5874
0
        }
5875
0
      else
5876
0
              for (x = cups->width; x > 0; x --)
5877
0
        {
5878
0
          *cptr++ = *srcptr++;
5879
0
          *cptr++ = *srcptr++;
5880
0
          *mptr++ = *srcptr++;
5881
0
          *mptr++ = *srcptr++;
5882
0
          *yptr++ = *srcptr++;
5883
0
          *yptr++ = *srcptr++;
5884
0
        }
5885
0
            break;
5886
0
        case CUPS_CSPACE_GMCK :
5887
0
        case CUPS_CSPACE_GMCS :
5888
0
        case CUPS_CSPACE_RGBA :
5889
0
        case CUPS_CSPACE_RGBW :
5890
0
        case CUPS_CSPACE_CMYK :
5891
0
        case CUPS_CSPACE_YMCK :
5892
0
        case CUPS_CSPACE_KCMY :
5893
0
        case CUPS_CSPACE_KCMYcm :
5894
0
            if (xflip)
5895
0
              for (x = cups->width; x > 0; x --, srcptr += 8)
5896
0
        {
5897
0
          *cptr-- = srcptr[1];
5898
0
          *cptr-- = srcptr[0];
5899
0
          *mptr-- = srcptr[3];
5900
0
          *mptr-- = srcptr[2];
5901
0
          *yptr-- = srcptr[5];
5902
0
          *yptr-- = srcptr[4];
5903
0
          *kptr-- = srcptr[7];
5904
0
          *kptr-- = srcptr[6];
5905
0
        }
5906
0
      else
5907
0
              for (x = cups->width; x > 0; x --)
5908
0
        {
5909
0
          *cptr++ = *srcptr++;
5910
0
          *cptr++ = *srcptr++;
5911
0
          *mptr++ = *srcptr++;
5912
0
          *mptr++ = *srcptr++;
5913
0
          *yptr++ = *srcptr++;
5914
0
          *yptr++ = *srcptr++;
5915
0
          *kptr++ = *srcptr++;
5916
0
          *kptr++ = *srcptr++;
5917
0
        }
5918
0
            break;
5919
0
      }
5920
0
            break;
5921
0
      }
5922
0
    }
5923
5924
   /*
5925
    * Write the bitmap data to the raster stream...
5926
    */
5927
5928
0
    cupsRasterWritePixels(cups->stream, dst, cups->header.cupsBytesPerLine);
5929
0
  }
5930
0
  return (0);
5931
0
}
5932
5933
5934
/*
5935
 * 'cups_print_planar()' - Print a page of planar pixels.
5936
 */
5937
5938
static int
5939
cups_print_planar(gx_device_printer *pdev,
5940
          /* I - Printer device */
5941
                  unsigned char     *src,
5942
          /* I - Scanline buffer */
5943
      unsigned char     *dst,
5944
          /* I - Bitmap buffer */
5945
      int               srcbytes)
5946
          /* I - Number of bytes in src */
5947
0
{
5948
0
  int   x;      /* Looping var */
5949
0
  int   y;      /* Looping var */
5950
0
  unsigned char z;      /* Looping var */
5951
0
  unsigned char srcbit;     /* Current source bit */
5952
0
  unsigned char dstbit;     /* Current destination bit */
5953
0
  unsigned char temp;     /* Temporary variable */
5954
0
  unsigned char *srcptr;    /* Pointer to data */
5955
0
  unsigned char *dstptr;    /* Pointer to bitmap */
5956
5957
5958
 /**** NOTE: Currently planar output doesn't support flipped duplex!!! ****/
5959
5960
 /*
5961
  * Loop through the page bitmap and write planar pixels...  We have
5962
  * to separate each chunked color as needed...
5963
  */
5964
5965
0
  for (z = 0; z < pdev->color_info.num_components; z ++)
5966
0
    for (y = 0; y < cups->height; y ++)
5967
0
    {
5968
     /*
5969
      * Grab the scanline data...
5970
      */
5971
5972
0
      if (gdev_prn_get_bits((gx_device_printer *)pdev, y, src, &srcptr) < 0)
5973
0
      {
5974
0
        dmprintf1(pdev->memory, "ERROR: Unable to get scanline %d!\n", y);
5975
0
  return_error(gs_error_unknownerror);
5976
0
      }
5977
5978
     /*
5979
      * Pull the individual color planes out of the pixels...
5980
      */
5981
5982
0
      if (srcptr[0] == 0 && memcmp(srcptr, srcptr + 1, srcbytes - 1) == 0)
5983
0
  memset(dst, 0, cups->header.cupsBytesPerLine);
5984
0
      else
5985
0
  switch (cups->header.cupsBitsPerColor)
5986
0
  {
5987
0
          default :
5988
0
        memset(dst, 0, cups->header.cupsBytesPerLine);
5989
5990
0
        switch (cups->header.cupsColorSpace)
5991
0
        {
5992
0
    default :
5993
0
              for (dstptr = dst, x = cups->width, srcbit = 64 >> z,
5994
0
                 dstbit = 128;
5995
0
       x > 0;
5996
0
       x --)
5997
0
        {
5998
0
          if (*srcptr & srcbit)
5999
0
      *dstptr |= dstbit;
6000
6001
0
                      if (srcbit >= 16)
6002
0
      srcbit >>= 4;
6003
0
          else
6004
0
          {
6005
0
      srcbit = 64 >> z;
6006
0
      srcptr ++;
6007
0
          }
6008
6009
0
                      if (dstbit > 1)
6010
0
      dstbit >>= 1;
6011
0
          else
6012
0
          {
6013
0
      dstbit = 128;
6014
0
      dstptr ++;
6015
0
          }
6016
0
        }
6017
0
              break;
6018
0
    case CUPS_CSPACE_GMCK :
6019
0
    case CUPS_CSPACE_GMCS :
6020
0
    case CUPS_CSPACE_RGBA :
6021
0
    case CUPS_CSPACE_RGBW :
6022
0
    case CUPS_CSPACE_CMYK :
6023
0
    case CUPS_CSPACE_YMCK :
6024
0
    case CUPS_CSPACE_KCMY :
6025
0
              for (dstptr = dst, x = cups->width, srcbit = 128 >> z,
6026
0
                 dstbit = 128;
6027
0
       x > 0;
6028
0
       x --)
6029
0
        {
6030
0
          if (*srcptr & srcbit)
6031
0
      *dstptr |= dstbit;
6032
6033
0
                      if (srcbit >= 16)
6034
0
      srcbit >>= 4;
6035
0
          else
6036
0
          {
6037
0
      srcbit = 128 >> z;
6038
0
      srcptr ++;
6039
0
          }
6040
6041
0
                      if (dstbit > 1)
6042
0
      dstbit >>= 1;
6043
0
          else
6044
0
          {
6045
0
      dstbit = 128;
6046
0
      dstptr ++;
6047
0
          }
6048
0
        }
6049
0
              break;
6050
0
    case CUPS_CSPACE_KCMYcm :
6051
0
              for (dstptr = dst, x = cups->width, srcbit = 32 >> z,
6052
0
                 dstbit = 128;
6053
0
       x > 0;
6054
0
       x --, srcptr ++)
6055
0
        {
6056
0
          if (*srcptr & srcbit)
6057
0
      *dstptr |= dstbit;
6058
6059
0
                      if (dstbit > 1)
6060
0
      dstbit >>= 1;
6061
0
          else
6062
0
          {
6063
0
      dstbit = 128;
6064
0
      dstptr ++;
6065
0
          }
6066
0
        }
6067
0
              break;
6068
0
              }
6069
0
        break;
6070
6071
0
    case 2 :
6072
0
        memset(dst, 0, cups->header.cupsBytesPerLine);
6073
6074
0
        switch (cups->header.cupsColorSpace)
6075
0
        {
6076
0
    default :
6077
0
              for (dstptr = dst, x = cups->width, srcbit = 48 >> (z * 2),
6078
0
                 dstbit = 0xc0;
6079
0
       x > 0;
6080
0
       x --, srcptr ++)
6081
0
        {
6082
0
          if ((temp = *srcptr & srcbit) != 0)
6083
0
          {
6084
0
      if (srcbit == dstbit)
6085
0
              *dstptr |= temp;
6086
0
            else
6087
0
      {
6088
0
              switch (srcbit)
6089
0
        {
6090
0
          case 0x30 :
6091
0
        temp >>= 4;
6092
0
        break;
6093
0
          case 0x0c :
6094
0
        temp >>= 2;
6095
0
        break;
6096
0
                          }
6097
6098
0
              switch (dstbit)
6099
0
        {
6100
0
          case 0xc0 :
6101
0
        *dstptr |= temp << 6;
6102
0
        break;
6103
0
          case 0x30 :
6104
0
        *dstptr |= temp << 4;
6105
0
        break;
6106
0
          case 0x0c :
6107
0
        *dstptr |= temp << 2;
6108
0
        break;
6109
0
          case 0x03 :
6110
0
        *dstptr |= temp;
6111
0
        break;
6112
0
                          }
6113
0
      }
6114
0
          }
6115
6116
0
          if (dstbit > 0x03)
6117
0
      dstbit >>= 2;
6118
0
          else
6119
0
          {
6120
0
      dstbit = 0xc0;
6121
0
      dstptr ++;
6122
0
          }
6123
0
        }
6124
0
              break;
6125
0
    case CUPS_CSPACE_GMCK :
6126
0
    case CUPS_CSPACE_GMCS :
6127
0
    case CUPS_CSPACE_RGBA :
6128
0
    case CUPS_CSPACE_RGBW :
6129
0
    case CUPS_CSPACE_CMYK :
6130
0
    case CUPS_CSPACE_YMCK :
6131
0
    case CUPS_CSPACE_KCMY :
6132
0
    case CUPS_CSPACE_KCMYcm :
6133
0
              for (dstptr = dst, x = cups->width, srcbit = 192 >> (z * 2),
6134
0
                 dstbit = 0xc0;
6135
0
       x > 0;
6136
0
       x --, srcptr ++)
6137
0
        {
6138
0
          if ((temp = *srcptr & srcbit) != 0)
6139
0
          {
6140
0
      if (srcbit == dstbit)
6141
0
              *dstptr |= temp;
6142
0
            else
6143
0
      {
6144
0
              switch (srcbit)
6145
0
        {
6146
0
          case 0xc0 :
6147
0
        temp >>= 6;
6148
0
        break;
6149
0
          case 0x30 :
6150
0
        temp >>= 4;
6151
0
        break;
6152
0
          case 0x0c :
6153
0
        temp >>= 2;
6154
0
        break;
6155
0
                          }
6156
6157
0
              switch (dstbit)
6158
0
        {
6159
0
          case 0xc0 :
6160
0
        *dstptr |= temp << 6;
6161
0
        break;
6162
0
          case 0x30 :
6163
0
        *dstptr |= temp << 4;
6164
0
        break;
6165
0
          case 0x0c :
6166
0
        *dstptr |= temp << 2;
6167
0
        break;
6168
0
          case 0x03 :
6169
0
        *dstptr |= temp;
6170
0
        break;
6171
0
                          }
6172
0
      }
6173
0
          }
6174
6175
0
          if (dstbit > 0x03)
6176
0
      dstbit >>= 2;
6177
0
          else
6178
0
          {
6179
0
      dstbit = 0xc0;
6180
0
      dstptr ++;
6181
0
          }
6182
0
        }
6183
0
              break;
6184
0
              }
6185
0
        break;
6186
6187
0
    case 4 :
6188
0
        memset(dst, 0, cups->header.cupsBytesPerLine);
6189
6190
0
        switch (cups->header.cupsColorSpace)
6191
0
        {
6192
0
    default :
6193
0
              if (z > 0)
6194
0
          srcptr ++;
6195
6196
0
        if (z == 1)
6197
0
          srcbit = 0xf0;
6198
0
        else
6199
0
          srcbit = 0x0f;
6200
6201
0
              for (dstptr = dst, x = cups->width, dstbit = 0xf0;
6202
0
       x > 0;
6203
0
       x --, srcptr += 2)
6204
0
        {
6205
0
          if ((temp = *srcptr & srcbit) != 0)
6206
0
          {
6207
0
      if (srcbit == dstbit)
6208
0
              *dstptr |= temp;
6209
0
            else
6210
0
      {
6211
0
              if (srcbit == 0xf0)
6212
0
                      temp >>= 4;
6213
6214
0
              if (dstbit == 0xf0)
6215
0
            *dstptr |= temp << 4;
6216
0
        else
6217
0
          *dstptr |= temp;
6218
0
      }
6219
0
          }
6220
6221
0
          if (dstbit == 0xf0)
6222
0
      dstbit = 0x0f;
6223
0
          else
6224
0
          {
6225
0
      dstbit = 0xf0;
6226
0
      dstptr ++;
6227
0
          }
6228
0
        }
6229
0
              break;
6230
0
    case CUPS_CSPACE_GMCK :
6231
0
    case CUPS_CSPACE_GMCS :
6232
0
    case CUPS_CSPACE_RGBA :
6233
0
    case CUPS_CSPACE_RGBW :
6234
0
    case CUPS_CSPACE_CMYK :
6235
0
    case CUPS_CSPACE_YMCK :
6236
0
    case CUPS_CSPACE_KCMY :
6237
0
    case CUPS_CSPACE_KCMYcm :
6238
0
              if (z > 1)
6239
0
          srcptr ++;
6240
6241
0
        if (z & 1)
6242
0
          srcbit = 0x0f;
6243
0
        else
6244
0
          srcbit = 0xf0;
6245
6246
0
              for (dstptr = dst, x = cups->width, dstbit = 0xf0;
6247
0
       x > 0;
6248
0
       x --, srcptr += 2)
6249
0
        {
6250
0
          if ((temp = *srcptr & srcbit) != 0)
6251
0
          {
6252
0
      if (srcbit == dstbit)
6253
0
              *dstptr |= temp;
6254
0
            else
6255
0
      {
6256
0
              if (srcbit == 0xf0)
6257
0
                      temp >>= 4;
6258
6259
0
              if (dstbit == 0xf0)
6260
0
            *dstptr |= temp << 4;
6261
0
        else
6262
0
          *dstptr |= temp;
6263
0
      }
6264
0
          }
6265
6266
0
          if (dstbit == 0xf0)
6267
0
      dstbit = 0x0f;
6268
0
          else
6269
0
          {
6270
0
      dstbit = 0xf0;
6271
0
      dstptr ++;
6272
0
          }
6273
0
        }
6274
0
              break;
6275
0
              }
6276
0
        break;
6277
6278
0
    case 8 :
6279
0
        for (srcptr += z, dstptr = dst, x = cups->header.cupsBytesPerLine;
6280
0
             x > 0;
6281
0
       srcptr += pdev->color_info.num_components, x --)
6282
0
    *dstptr++ = *srcptr;
6283
0
        break;
6284
6285
0
    case 16 :
6286
0
        for (srcptr += 2 * z, dstptr = dst, x = cups->header.cupsBytesPerLine;
6287
0
             x > 0;
6288
0
       srcptr += 2 * pdev->color_info.num_components, x --)
6289
0
              {
6290
0
    *dstptr++ = srcptr[0];
6291
0
    *dstptr++ = srcptr[1];
6292
0
        }
6293
0
        break;
6294
0
  }
6295
6296
     /*
6297
      * Write the bitmap data to the raster stream...
6298
      */
6299
6300
0
      cupsRasterWritePixels(cups->stream, dst, cups->header.cupsBytesPerLine);
6301
0
    }
6302
0
  return (0);
6303
0
}
6304
6305
private int
6306
cups_spec_op(gx_device *dev_, int op, void *data, int datasize)
6307
87.7M
{
6308
87.7M
    return gx_default_dev_spec_op(dev_, op, data, datasize);
6309
87.7M
}
6310
6311
#ifdef __GNUC__
6312
#pragma GCC diagnostic pop
6313
#endif
6314
/*
6315
 */