~ubuntu-branches/ubuntu/trusty/cups-filters/trusty-proposed

« back to all changes in this revision

Viewing changes to .pc/support-for-pwgraster-output-with-ppd.patch/filter/imagetoraster.c

  • Committer: Package Import Robot
  • Author(s): Till Kamppeter
  • Date: 2014-10-27 16:21:06 UTC
  • Revision ID: package-import@ubuntu.com-20141027162106-2acjs0wsluf8htg3
Tags: 1.0.52-0ubuntu1.3
* Added full support for the IPP Everywhere standard for driverless
  printing (LP: #1386241):
  - Added ippusbxd (Support for IPP-over-USB printers) generating the
    new binary package cups-filters-ippusbxd.
  - Added rastertopdf filter. This filter allows PWG Raster as input
    format for a CUPS queue. This is needed to make shared CUPS printers
    fully emulating IPP Everywhere printers (all other requirements are
    fulfilled by CUPS itself).
  - rastertopdf-mime-convs.patch: Added conversion rule for rastertopdf
    filter.
  - add-ipp-everywhere-ppd.patch: Added PPD file for a generic IPP
    Everywhere printer (on-the-fly generation via cupsfilters.drv).
  - support-for-pwgraster-output-with-ppd.patch: Support for PWG-Raster
    output selected via keyword in the PPD file.
  - pdftoraster-cspace-18-19-20.patch: pdftoraster: Support for output
    in the color spaces 18 (CUPS_CSPACE_SW, sGray), 19 (CUPS_CSPACE_SRGB,
    sRGB), and 20 (CUPS_CSPACE_ADOBERGB, Adobe RGB). No color management
    appropriate to these color spaces is added yet.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * "$Id$"
 
3
 *
 
4
 *   Image file to raster filter for CUPS.
 
5
 *
 
6
 *   Copyright 2007-2011 by Apple Inc.
 
7
 *   Copyright 1993-2007 by Easy Software Products.
 
8
 *
 
9
 *   These coded instructions, statements, and computer programs are the
 
10
 *   property of Apple Inc. and are protected by Federal copyright
 
11
 *   law.  Distribution and use rights are outlined in the file "LICENSE.txt"
 
12
 *   which should have been included with this file.  If this file is
 
13
 *   file is missing or damaged, see the license at "http://www.cups.org/".
 
14
 *
 
15
 *   This file is subject to the Apple OS-Developed Software exception.
 
16
 *
 
17
 * Contents:
 
18
 *
 
19
 *   main()          - Main entry...
 
20
 *   blank_line()    - Clear a line buffer to the blank value...
 
21
 *   format_CMY()    - Convert image data to CMY.
 
22
 *   format_CMYK()   - Convert image data to CMYK.
 
23
 *   format_K()      - Convert image data to black.
 
24
 *   format_KCMY()   - Convert image data to KCMY.
 
25
 *   format_KCMYcm() - Convert image data to KCMYcm.
 
26
 *   format_RGBA()   - Convert image data to RGBA/RGBW.
 
27
 *   format_W()      - Convert image data to luminance.
 
28
 *   format_YMC()    - Convert image data to YMC.
 
29
 *   format_YMCK()   - Convert image data to YMCK.
 
30
 *   make_lut()      - Make a lookup table given gamma and brightness values.
 
31
 *   raster_cb()     - Validate the page header.
 
32
 */
 
33
 
 
34
/*
 
35
 * Include necessary headers...
 
36
 */
 
37
 
 
38
#include "common.h"
 
39
#include <cupsfilters/image-private.h>
 
40
#include <unistd.h>
 
41
#include <math.h>
 
42
#include <signal.h>
 
43
#include <string.h>
 
44
 
 
45
 
 
46
/*
 
47
 * Globals...
 
48
 */
 
49
 
 
50
int     Flip = 0,                       /* Flip/mirror pages */
 
51
        XPosition = 0,                  /* Horizontal position on page */
 
52
        YPosition = 0,                  /* Vertical position on page */
 
53
        Collate = 0,                    /* Collate copies? */
 
54
        Copies = 1;                     /* Number of copies */
 
55
int     Floyd16x16[16][16] =            /* Traditional Floyd ordered dither */
 
56
        {
 
57
          { 0,   128, 32,  160, 8,   136, 40,  168,
 
58
            2,   130, 34,  162, 10,  138, 42,  170 },
 
59
          { 192, 64,  224, 96,  200, 72,  232, 104,
 
60
            194, 66,  226, 98,  202, 74,  234, 106 },
 
61
          { 48,  176, 16,  144, 56,  184, 24,  152,
 
62
            50,  178, 18,  146, 58,  186, 26,  154 },
 
63
          { 240, 112, 208, 80,  248, 120, 216, 88,
 
64
            242, 114, 210, 82,  250, 122, 218, 90 },
 
65
          { 12,  140, 44,  172, 4,   132, 36,  164,
 
66
            14,  142, 46,  174, 6,   134, 38,  166 },
 
67
          { 204, 76,  236, 108, 196, 68,  228, 100,
 
68
            206, 78,  238, 110, 198, 70,  230, 102 },
 
69
          { 60,  188, 28,  156, 52,  180, 20,  148,
 
70
            62,  190, 30,  158, 54,  182, 22,  150 },
 
71
          { 252, 124, 220, 92,  244, 116, 212, 84,
 
72
            254, 126, 222, 94,  246, 118, 214, 86 },
 
73
          { 3,   131, 35,  163, 11,  139, 43,  171,
 
74
            1,   129, 33,  161, 9,   137, 41,  169 },
 
75
          { 195, 67,  227, 99,  203, 75,  235, 107,
 
76
            193, 65,  225, 97,  201, 73,  233, 105 },
 
77
          { 51,  179, 19,  147, 59,  187, 27,  155,
 
78
            49,  177, 17,  145, 57,  185, 25,  153 },
 
79
          { 243, 115, 211, 83,  251, 123, 219, 91,
 
80
            241, 113, 209, 81,  249, 121, 217, 89 },
 
81
          { 15,  143, 47,  175, 7,   135, 39,  167,
 
82
            13,  141, 45,  173, 5,   133, 37,  165 },
 
83
          { 207, 79,  239, 111, 199, 71,  231, 103,
 
84
            205, 77,  237, 109, 197, 69,  229, 101 },
 
85
          { 63,  191, 31,  159, 55,  183, 23,  151,
 
86
            61,  189, 29,  157, 53,  181, 21,  149 },
 
87
          { 254, 127, 223, 95,  247, 119, 215, 87,
 
88
            253, 125, 221, 93,  245, 117, 213, 85 }
 
89
        };
 
90
int     Floyd8x8[8][8] =
 
91
        {
 
92
          {  0, 32,  8, 40,  2, 34, 10, 42 },
 
93
          { 48, 16, 56, 24, 50, 18, 58, 26 },
 
94
          { 12, 44,  4, 36, 14, 46,  6, 38 },
 
95
          { 60, 28, 52, 20, 62, 30, 54, 22 },
 
96
          {  3, 35, 11, 43,  1, 33,  9, 41 },
 
97
          { 51, 19, 59, 27, 49, 17, 57, 25 },
 
98
          { 15, 47,  7, 39, 13, 45,  5, 37 },
 
99
          { 63, 31, 55, 23, 61, 29, 53, 21 }
 
100
        };
 
101
int     Floyd4x4[4][4] =
 
102
        {
 
103
          {  0,  8,  2, 10 },
 
104
          { 12,  4, 14,  6 },
 
105
          {  3, 11,  1,  9 },
 
106
          { 15,  7, 13,  5 }
 
107
        };
 
108
 
 
109
cups_ib_t       OnPixels[256],          /* On-pixel LUT */
 
110
                OffPixels[256];         /* Off-pixel LUT */
 
111
 
 
112
 
 
113
/*
 
114
 * Local functions...
 
115
 */
 
116
 
 
117
static void     blank_line(cups_page_header2_t *header, unsigned char *row);
 
118
static void     format_CMY(cups_page_header2_t *header, unsigned char *row, int y, int z, int xsize, int ysize, int yerr0, int yerr1, cups_ib_t *r0, cups_ib_t *r1);
 
119
static void     format_CMYK(cups_page_header2_t *header, unsigned char *row, int y, int z, int xsize, int ysize, int yerr0, int yerr1, cups_ib_t *r0, cups_ib_t *r1);
 
120
static void     format_K(cups_page_header2_t *header, unsigned char *row, int y, int z, int xsize, int ysize, int yerr0, int yerr1, cups_ib_t *r0, cups_ib_t *r1);
 
121
static void     format_KCMYcm(cups_page_header2_t *header, unsigned char *row, int y, int z, int xsize, int ysize, int yerr0, int yerr1, cups_ib_t *r0, cups_ib_t *r1);
 
122
static void     format_KCMY(cups_page_header2_t *header, unsigned char *row, int y, int z, int xsize, int ysize, int yerr0, int yerr1, cups_ib_t *r0, cups_ib_t *r1);
 
123
#define         format_RGB format_CMY
 
124
static void     format_RGBA(cups_page_header2_t *header, unsigned char *row, int y, int z, int xsize, int ysize, int yerr0, int yerr1, cups_ib_t *r0, cups_ib_t *r1);
 
125
static void     format_W(cups_page_header2_t *header, unsigned char *row, int y, int z, int xsize, int ysize, int yerr0, int yerr1, cups_ib_t *r0, cups_ib_t *r1);
 
126
static void     format_YMC(cups_page_header2_t *header, unsigned char *row, int y, int z, int xsize, int ysize, int yerr0, int yerr1, cups_ib_t *r0, cups_ib_t *r1);
 
127
static void     format_YMCK(cups_page_header2_t *header, unsigned char *row, int y, int z, int xsize, int ysize, int yerr0, int yerr1, cups_ib_t *r0, cups_ib_t *r1);
 
128
static void     make_lut(cups_ib_t *, int, float, float);
 
129
static int      raster_cb(cups_page_header2_t *header, int preferred_bits);
 
130
 
 
131
 
 
132
/*
 
133
 * 'main()' - Main entry...
 
134
 */
 
135
 
 
136
int                                     /* O - Exit status */
 
137
main(int  argc,                         /* I - Number of command-line arguments */
 
138
     char *argv[])                      /* I - Command-line arguments */
 
139
{
 
140
  int                   i;              /* Looping var */
 
141
  cups_image_t          *img;           /* Image to print */
 
142
  float                 xprint,         /* Printable area */
 
143
                        yprint,
 
144
                        xinches,        /* Total size in inches */
 
145
                        yinches;
 
146
  float                 xsize,          /* Total size in points */
 
147
                        ysize,
 
148
                        xsize2,
 
149
                        ysize2;
 
150
  float                 aspect;         /* Aspect ratio */
 
151
  int                   xpages,         /* # x pages */
 
152
                        ypages,         /* # y pages */
 
153
                        xpage,          /* Current x page */
 
154
                        ypage,          /* Current y page */
 
155
                        xtemp,          /* Bitmap width in pixels */
 
156
                        ytemp,          /* Bitmap height in pixels */
 
157
                        page;           /* Current page number */
 
158
  int                   xc0, yc0,       /* Corners of the page in image coords */
 
159
                        xc1, yc1;
 
160
  ppd_file_t            *ppd;           /* PPD file */
 
161
  ppd_choice_t          *choice;        /* PPD option choice */
 
162
  char                  *resolution,    /* Output resolution */
 
163
                        *media_type;    /* Media type */
 
164
  ppd_profile_t         *profile;       /* Color profile */
 
165
  ppd_profile_t         userprofile;    /* User-specified profile */
 
166
  cups_raster_t         *ras;           /* Raster stream */
 
167
  cups_page_header2_t   header;         /* Page header */
 
168
  int                   num_options;    /* Number of print options */
 
169
  cups_option_t         *options;       /* Print options */
 
170
  const char            *val;           /* Option value */
 
171
  int                   slowcollate,    /* Collate copies the slow way */
 
172
                        slowcopies;     /* Make copies the "slow" way? */
 
173
  float                 g;              /* Gamma correction value */
 
174
  float                 b;              /* Brightness factor */
 
175
  float                 zoom;           /* Zoom facter */
 
176
  int                   xppi, yppi;     /* Pixels-per-inch */
 
177
  int                   hue, sat;       /* Hue and saturation adjustment */
 
178
  cups_izoom_t          *z;             /* Image zoom buffer */
 
179
  cups_iztype_t         zoom_type;      /* Image zoom type */
 
180
  int                   primary,        /* Primary image colorspace */
 
181
                        secondary;      /* Secondary image colorspace */
 
182
  cups_ib_t             *row,           /* Current row */
 
183
                        *r0,            /* Top row */
 
184
                        *r1;            /* Bottom row */
 
185
  int                   y,              /* Current Y coordinate on page */
 
186
                        iy,             /* Current Y coordinate in image */
 
187
                        last_iy,        /* Previous Y coordinate in image */
 
188
                        yerr0,          /* Top Y error value */
 
189
                        yerr1;          /* Bottom Y error value */
 
190
  cups_ib_t             lut[256];       /* Gamma/brightness LUT */
 
191
  int                   plane,          /* Current color plane */
 
192
                        num_planes;     /* Number of color planes */
 
193
  char                  filename[1024]; /* Name of file to print */
 
194
 
 
195
 
 
196
 /*
 
197
  * Make sure status messages are not buffered...
 
198
  */
 
199
 
 
200
  setbuf(stderr, NULL);
 
201
 
 
202
 /*
 
203
  * Ignore broken pipe signals...
 
204
  */
 
205
 
 
206
  signal(SIGPIPE, SIG_IGN);
 
207
 
 
208
 /*
 
209
  * Check command-line...
 
210
  */
 
211
 
 
212
  if (argc < 6 || argc > 7)
 
213
  {
 
214
    fprintf(stderr, "Usage: %s job-id user title copies options [file]\n",
 
215
            argv[0]);
 
216
    return (1);
 
217
  }
 
218
 
 
219
 /*
 
220
  * See if we need to use the imagetops and pstoraster filters instead...
 
221
  */
 
222
 
 
223
  options     = NULL;
 
224
  num_options = cupsParseOptions(argv[5], 0, &options);
 
225
 
 
226
  if (getenv("CLASSIFICATION") ||
 
227
      cupsGetOption("page-label", num_options, options))
 
228
  {
 
229
   /*
 
230
    * Yes, fork a copy of pstoraster and then transfer control to imagetops...
 
231
    */
 
232
 
 
233
    int mypipes[2];             /* New pipes for imagetops | pstoraster */
 
234
    int pid;                    /* PID of pstoraster */
 
235
 
 
236
 
 
237
    cupsFreeOptions(num_options, options);
 
238
 
 
239
    if (pipe(mypipes))
 
240
    {
 
241
      perror("ERROR: Unable to create pipes for filters");
 
242
      return (errno);
 
243
    }
 
244
 
 
245
    if ((pid = fork()) == 0)
 
246
    {
 
247
     /*
 
248
      * Child process for pstoraster...  Assign new pipe input to pstoraster...
 
249
      */
 
250
 
 
251
      dup2(mypipes[0], 0);
 
252
      close(mypipes[0]);
 
253
      close(mypipes[1]);
 
254
 
 
255
      execlp("pstoraster", argv[0], argv[1], argv[2], argv[3], argv[4], argv[5],
 
256
             NULL);
 
257
      return (errno);
 
258
    }
 
259
    else if (pid < 0)
 
260
    {
 
261
     /*
 
262
      * Error!
 
263
      */
 
264
 
 
265
      perror("ERROR: Unable to fork filter");
 
266
      return (errno);
 
267
    }
 
268
 
 
269
   /*
 
270
    * Update stdout so it points at the new pstoraster...
 
271
    */
 
272
 
 
273
    dup2(mypipes[1], 1);
 
274
    close(mypipes[0]);
 
275
    close(mypipes[1]);
 
276
 
 
277
   /*
 
278
    * Run imagetops to get the classification or page labeling that was
 
279
    * requested...
 
280
    */
 
281
 
 
282
    execlp("imagetops", argv[0], argv[1], argv[2], argv[3], argv[4], argv[5],
 
283
           argv[6], NULL);
 
284
    return (errno);
 
285
  }
 
286
 
 
287
 /*
 
288
  * Copy stdin as needed...
 
289
  */
 
290
 
 
291
  if (argc == 6)
 
292
  {
 
293
    int         fd;             /* File to write to */
 
294
    char        buffer[8192];   /* Buffer to read into */
 
295
    int         bytes;          /* # of bytes to read */
 
296
 
 
297
 
 
298
    if ((fd = cupsTempFd(filename, sizeof(filename))) < 0)
 
299
    {
 
300
      perror("ERROR: Unable to copy print file");
 
301
      return (1);
 
302
    }
 
303
 
 
304
    fprintf(stderr,
 
305
            "DEBUG: imagetoraster - copying to temp print file \"%s\".\n",
 
306
            filename);
 
307
 
 
308
    while ((bytes = fread(buffer, 1, sizeof(buffer), stdin)) > 0)
 
309
      write(fd, buffer, bytes);
 
310
 
 
311
    close(fd);
 
312
  }
 
313
  else
 
314
  {
 
315
    strncpy(filename, argv[6], sizeof(filename) - 1);
 
316
    filename[sizeof(filename) - 1] = '\0';
 
317
  }
 
318
 
 
319
 /*
 
320
  * Process command-line options and write the prolog...
 
321
  */
 
322
 
 
323
  zoom = 1.0;
 
324
  xppi = 0;
 
325
  yppi = 0;
 
326
  hue  = 0;
 
327
  sat  = 100;
 
328
  g    = 1.0;
 
329
  b    = 1.0;
 
330
 
 
331
  Copies = atoi(argv[4]);
 
332
 
 
333
  ppd = SetCommonOptions(num_options, options, 0);
 
334
 
 
335
  if ((val = cupsGetOption("multiple-document-handling", num_options, options)) != NULL)
 
336
  {
 
337
   /*
 
338
    * This IPP attribute is unnecessarily complicated...
 
339
    *
 
340
    *   single-document, separate-documents-collated-copies, and
 
341
    *   single-document-new-sheet all require collated copies.
 
342
    *
 
343
    *   separate-documents-collated-copies allows for uncollated copies.
 
344
    */
 
345
 
 
346
    Collate = strcasecmp(val, "separate-documents-collated-copies") != 0;
 
347
  }
 
348
 
 
349
  if ((val = cupsGetOption("Collate", num_options, options)) != NULL &&
 
350
      strcasecmp(val, "True") == 0)
 
351
    Collate = 1;
 
352
 
 
353
  if ((val = cupsGetOption("gamma", num_options, options)) != NULL)
 
354
  {
 
355
   /*
 
356
    * Get gamma value from 1 to 10000...
 
357
    */
 
358
 
 
359
    g = atoi(val) * 0.001f;
 
360
 
 
361
    if (g < 0.001f)
 
362
      g = 0.001f;
 
363
    else if (g > 10.0f)
 
364
      g = 10.0f;
 
365
  }
 
366
 
 
367
  if ((val = cupsGetOption("brightness", num_options, options)) != NULL)
 
368
  {
 
369
   /*
 
370
    * Get brightness value from 10 to 1000.
 
371
    */
 
372
 
 
373
    b = atoi(val) * 0.01f;
 
374
 
 
375
    if (b < 0.1f)
 
376
      b = 0.1f;
 
377
    else if (b > 10.0f)
 
378
      b = 10.0f;
 
379
  }
 
380
 
 
381
  if ((val = cupsGetOption("scaling", num_options, options)) != NULL)
 
382
    zoom = atoi(val) * 0.01;
 
383
  else if (((val =
 
384
             cupsGetOption("fit-to-page", num_options, options)) != NULL) ||
 
385
           ((val = cupsGetOption("fitplot", num_options, options)) != NULL))
 
386
  {
 
387
    if (!strcasecmp(val, "yes") || !strcasecmp(val, "on") ||
 
388
        !strcasecmp(val, "true"))
 
389
      zoom = 1.0;
 
390
    else
 
391
      zoom = 0.0;
 
392
  }
 
393
  else if ((val = cupsGetOption("natural-scaling", num_options, options)) != NULL)
 
394
    zoom = 0.0;
 
395
 
 
396
  if ((val = cupsGetOption("ppi", num_options, options)) != NULL)
 
397
  {
 
398
    if (sscanf(val, "%dx%d", &xppi, &yppi) < 2)
 
399
      yppi = xppi;
 
400
    zoom = 0.0;
 
401
  }
 
402
 
 
403
  if ((val = cupsGetOption("position", num_options, options)) != NULL)
 
404
  {
 
405
    if (strcasecmp(val, "center") == 0)
 
406
    {
 
407
      XPosition = 0;
 
408
      YPosition = 0;
 
409
    }
 
410
    else if (strcasecmp(val, "top") == 0)
 
411
    {
 
412
      XPosition = 0;
 
413
      YPosition = 1;
 
414
    }
 
415
    else if (strcasecmp(val, "left") == 0)
 
416
    {
 
417
      XPosition = -1;
 
418
      YPosition = 0;
 
419
    }
 
420
    else if (strcasecmp(val, "right") == 0)
 
421
    {
 
422
      XPosition = 1;
 
423
      YPosition = 0;
 
424
    }
 
425
    else if (strcasecmp(val, "top-left") == 0)
 
426
    {
 
427
      XPosition = -1;
 
428
      YPosition = 1;
 
429
    }
 
430
    else if (strcasecmp(val, "top-right") == 0)
 
431
    {
 
432
      XPosition = 1;
 
433
      YPosition = 1;
 
434
    }
 
435
    else if (strcasecmp(val, "bottom") == 0)
 
436
    {
 
437
      XPosition = 0;
 
438
      YPosition = -1;
 
439
    }
 
440
    else if (strcasecmp(val, "bottom-left") == 0)
 
441
    {
 
442
      XPosition = -1;
 
443
      YPosition = -1;
 
444
    }
 
445
    else if (strcasecmp(val, "bottom-right") == 0)
 
446
    {
 
447
      XPosition = 1;
 
448
      YPosition = -1;
 
449
    }
 
450
  }
 
451
 
 
452
  if ((val = cupsGetOption("saturation", num_options, options)) != NULL)
 
453
    sat = atoi(val);
 
454
 
 
455
  if ((val = cupsGetOption("hue", num_options, options)) != NULL)
 
456
    hue = atoi(val);
 
457
 
 
458
  if ((choice = ppdFindMarkedChoice(ppd, "MirrorPrint")) != NULL)
 
459
  {
 
460
    val = choice->choice;
 
461
    choice->marked = 0;
 
462
  }
 
463
  else
 
464
    val = cupsGetOption("mirror", num_options, options);
 
465
 
 
466
  if (val && (!strcasecmp(val, "true") || !strcasecmp(val, "on") ||
 
467
              !strcasecmp(val, "yes")))
 
468
    Flip = 1;
 
469
 
 
470
 /*
 
471
  * Set the needed options in the page header...
 
472
  */
 
473
 
 
474
  if (cupsRasterInterpretPPD(&header, ppd, num_options, options, raster_cb))
 
475
  {
 
476
    fputs("ERROR: The page setup information was not valid.\n", stderr);
 
477
    fprintf(stderr, "DEBUG: %s\n", cupsRasterErrorString());
 
478
    return (1);
 
479
  }
 
480
 
 
481
 /*
 
482
  * Get the media type and resolution that have been chosen...
 
483
  */
 
484
 
 
485
  if ((choice = ppdFindMarkedChoice(ppd, "MediaType")) != NULL)
 
486
    media_type = choice->choice;
 
487
  else
 
488
    media_type = "";
 
489
 
 
490
  if ((choice = ppdFindMarkedChoice(ppd, "Resolution")) != NULL)
 
491
    resolution = choice->choice;
 
492
  else
 
493
    resolution = "";
 
494
 
 
495
 /*
 
496
  * Choose the appropriate colorspace...
 
497
  */
 
498
 
 
499
  switch (header.cupsColorSpace)
 
500
  {
 
501
    case CUPS_CSPACE_W :
 
502
    case CUPS_CSPACE_SW :
 
503
        if (header.cupsBitsPerColor >= 8)
 
504
        {
 
505
          primary   = CUPS_IMAGE_WHITE;
 
506
          secondary = CUPS_IMAGE_WHITE;
 
507
        }
 
508
        else
 
509
        {
 
510
          primary   = CUPS_IMAGE_BLACK;
 
511
          secondary = CUPS_IMAGE_BLACK;
 
512
        }
 
513
        break;
 
514
 
 
515
    default :
 
516
    case CUPS_CSPACE_RGB :
 
517
    case CUPS_CSPACE_RGBA :
 
518
    case CUPS_CSPACE_RGBW :
 
519
    case CUPS_CSPACE_SRGB :
 
520
    case CUPS_CSPACE_ADOBERGB :
 
521
        if (header.cupsBitsPerColor >= 8)
 
522
        {
 
523
          primary   = CUPS_IMAGE_RGB;
 
524
          secondary = CUPS_IMAGE_RGB;
 
525
        }
 
526
        else
 
527
        {
 
528
          primary   = CUPS_IMAGE_CMY;
 
529
          secondary = CUPS_IMAGE_CMY;
 
530
        }
 
531
        break;
 
532
 
 
533
    case CUPS_CSPACE_K :
 
534
    case CUPS_CSPACE_WHITE :
 
535
    case CUPS_CSPACE_GOLD :
 
536
    case CUPS_CSPACE_SILVER :
 
537
        primary   = CUPS_IMAGE_BLACK;
 
538
        secondary = CUPS_IMAGE_BLACK;
 
539
        break;
 
540
 
 
541
    case CUPS_CSPACE_CMYK :
 
542
    case CUPS_CSPACE_YMCK :
 
543
    case CUPS_CSPACE_KCMY :
 
544
    case CUPS_CSPACE_KCMYcm :
 
545
    case CUPS_CSPACE_GMCK :
 
546
    case CUPS_CSPACE_GMCS :
 
547
        if (header.cupsBitsPerColor == 1)
 
548
        {
 
549
          primary   = CUPS_IMAGE_CMY;
 
550
          secondary = CUPS_IMAGE_CMY;
 
551
        }
 
552
        else
 
553
        {
 
554
          primary   = CUPS_IMAGE_CMYK;
 
555
          secondary = CUPS_IMAGE_CMYK;
 
556
        }
 
557
        break;
 
558
 
 
559
    case CUPS_CSPACE_CMY :
 
560
    case CUPS_CSPACE_YMC :
 
561
        primary   = CUPS_IMAGE_CMY;
 
562
        secondary = CUPS_IMAGE_CMY;
 
563
        break;
 
564
 
 
565
    case CUPS_CSPACE_CIEXYZ :
 
566
    case CUPS_CSPACE_CIELab :
 
567
    case CUPS_CSPACE_ICC1 :
 
568
    case CUPS_CSPACE_ICC2 :
 
569
    case CUPS_CSPACE_ICC3 :
 
570
    case CUPS_CSPACE_ICC4 :
 
571
    case CUPS_CSPACE_ICC5 :
 
572
    case CUPS_CSPACE_ICC6 :
 
573
    case CUPS_CSPACE_ICC7 :
 
574
    case CUPS_CSPACE_ICC8 :
 
575
    case CUPS_CSPACE_ICC9 :
 
576
    case CUPS_CSPACE_ICCA :
 
577
    case CUPS_CSPACE_ICCB :
 
578
    case CUPS_CSPACE_ICCC :
 
579
    case CUPS_CSPACE_ICCD :
 
580
    case CUPS_CSPACE_ICCE :
 
581
    case CUPS_CSPACE_ICCF :
 
582
    case CUPS_CSPACE_DEVICE1 :
 
583
    case CUPS_CSPACE_DEVICE2 :
 
584
    case CUPS_CSPACE_DEVICE3 :
 
585
    case CUPS_CSPACE_DEVICE4 :
 
586
    case CUPS_CSPACE_DEVICE5 :
 
587
    case CUPS_CSPACE_DEVICE6 :
 
588
    case CUPS_CSPACE_DEVICE7 :
 
589
    case CUPS_CSPACE_DEVICE8 :
 
590
    case CUPS_CSPACE_DEVICE9 :
 
591
    case CUPS_CSPACE_DEVICEA :
 
592
    case CUPS_CSPACE_DEVICEB :
 
593
    case CUPS_CSPACE_DEVICEC :
 
594
    case CUPS_CSPACE_DEVICED :
 
595
    case CUPS_CSPACE_DEVICEE :
 
596
    case CUPS_CSPACE_DEVICEF :
 
597
        fprintf(stderr, "DEBUG: Colorspace %d not supported.\n",
 
598
                header.cupsColorSpace);
 
599
        exit(1);
 
600
        break;
 
601
  }
 
602
 
 
603
 /*
 
604
  * Find a color profile matching the current options...
 
605
  */
 
606
 
 
607
  if ((val = cupsGetOption("profile", num_options, options)) != NULL)
 
608
  {
 
609
    profile = &userprofile;
 
610
    sscanf(val, "%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f",
 
611
           &(userprofile.density), &(userprofile.gamma),
 
612
           userprofile.matrix[0] + 0, userprofile.matrix[0] + 1,
 
613
           userprofile.matrix[0] + 2,
 
614
           userprofile.matrix[1] + 0, userprofile.matrix[1] + 1,
 
615
           userprofile.matrix[1] + 2,
 
616
           userprofile.matrix[2] + 0, userprofile.matrix[2] + 1,
 
617
           userprofile.matrix[2] + 2);
 
618
 
 
619
    userprofile.density      *= 0.001f;
 
620
    userprofile.gamma        *= 0.001f;
 
621
    userprofile.matrix[0][0] *= 0.001f;
 
622
    userprofile.matrix[0][1] *= 0.001f;
 
623
    userprofile.matrix[0][2] *= 0.001f;
 
624
    userprofile.matrix[1][0] *= 0.001f;
 
625
    userprofile.matrix[1][1] *= 0.001f;
 
626
    userprofile.matrix[1][2] *= 0.001f;
 
627
    userprofile.matrix[2][0] *= 0.001f;
 
628
    userprofile.matrix[2][1] *= 0.001f;
 
629
    userprofile.matrix[2][2] *= 0.001f;
 
630
  }
 
631
  else if (ppd != NULL)
 
632
  {
 
633
    fprintf(stderr, "DEBUG: Searching for profile \"%s/%s\"...\n",
 
634
            resolution, media_type);
 
635
 
 
636
    for (i = 0, profile = ppd->profiles; i < ppd->num_profiles; i ++, profile ++)
 
637
    {
 
638
      fprintf(stderr, "DEBUG: \"%s/%s\" = ", profile->resolution,
 
639
              profile->media_type);
 
640
 
 
641
      if ((strcmp(profile->resolution, resolution) == 0 ||
 
642
           profile->resolution[0] == '-') &&
 
643
          (strcmp(profile->media_type, media_type) == 0 ||
 
644
           profile->media_type[0] == '-'))
 
645
      {
 
646
        fputs("MATCH\n", stderr);
 
647
        break;
 
648
      }
 
649
      else
 
650
        fputs("no.\n", stderr);
 
651
    }
 
652
 
 
653
   /*
 
654
    * If we found a color profile, use it!
 
655
    */
 
656
 
 
657
    if (i >= ppd->num_profiles)
 
658
      profile = NULL;
 
659
  }
 
660
  else
 
661
    profile = NULL;
 
662
 
 
663
  if (profile)
 
664
    cupsImageSetProfile(profile->density, profile->gamma, profile->matrix);
 
665
 
 
666
  cupsImageSetRasterColorSpace(header.cupsColorSpace);
 
667
 
 
668
 /*
 
669
  * Create a gamma/brightness LUT...
 
670
  */
 
671
 
 
672
  make_lut(lut, primary, g, b);
 
673
 
 
674
 /*
 
675
  * Open the input image to print...
 
676
  */
 
677
 
 
678
  fputs("INFO: Loading print file.\n", stderr);
 
679
 
 
680
  if (header.cupsColorSpace == CUPS_CSPACE_CIEXYZ ||
 
681
      header.cupsColorSpace == CUPS_CSPACE_CIELab ||
 
682
      header.cupsColorSpace >= CUPS_CSPACE_ICC1)
 
683
    img = cupsImageOpen(filename, primary, secondary, sat, hue, NULL);
 
684
  else
 
685
    img = cupsImageOpen(filename, primary, secondary, sat, hue, lut);
 
686
 
 
687
  if (argc == 6)
 
688
    unlink(filename);
 
689
 
 
690
  if (img == NULL)
 
691
  {
 
692
    fputs("ERROR: The print file could not be opened.\n", stderr);
 
693
    ppdClose(ppd);
 
694
    return (1);
 
695
  }
 
696
 
 
697
 /*
 
698
  * Scale as necessary...
 
699
  */
 
700
 
 
701
  if (zoom == 0.0 && xppi == 0)
 
702
  {
 
703
    xppi = img->xppi;
 
704
    yppi = img->yppi;
 
705
  }
 
706
 
 
707
  if (yppi == 0)
 
708
    yppi = xppi;
 
709
 
 
710
  fprintf(stderr, "DEBUG: Before scaling: xppi=%d, yppi=%d, zoom=%.2f\n",
 
711
          xppi, yppi, zoom);
 
712
 
 
713
  if (xppi > 0)
 
714
  {
 
715
   /*
 
716
    * Scale the image as neccesary to match the desired pixels-per-inch.
 
717
    */
 
718
 
 
719
    if (Orientation & 1)
 
720
    {
 
721
      xprint = (PageTop - PageBottom) / 72.0;
 
722
      yprint = (PageRight - PageLeft) / 72.0;
 
723
    }
 
724
    else
 
725
    {
 
726
      xprint = (PageRight - PageLeft) / 72.0;
 
727
      yprint = (PageTop - PageBottom) / 72.0;
 
728
    }
 
729
 
 
730
    fprintf(stderr, "DEBUG: Before scaling: xprint=%.1f, yprint=%.1f\n",
 
731
            xprint, yprint);
 
732
 
 
733
    xinches = (float)img->xsize / (float)xppi;
 
734
    yinches = (float)img->ysize / (float)yppi;
 
735
 
 
736
    fprintf(stderr, "DEBUG: Image size is %.1f x %.1f inches...\n",
 
737
            xinches, yinches);
 
738
 
 
739
    if ((val = cupsGetOption("natural-scaling", num_options, options)) != NULL)
 
740
    {
 
741
      xinches = xinches * atoi(val) / 100;
 
742
      yinches = yinches * atoi(val) / 100;
 
743
    }
 
744
 
 
745
    if (cupsGetOption("orientation-requested", num_options, options) == NULL &&
 
746
        cupsGetOption("landscape", num_options, options) == NULL)
 
747
    {
 
748
     /*
 
749
      * Rotate the image if it will fit landscape but not portrait...
 
750
      */
 
751
 
 
752
      fputs("DEBUG: Auto orientation...\n", stderr);
 
753
 
 
754
      if ((xinches > xprint || yinches > yprint) &&
 
755
          xinches <= yprint && yinches <= xprint)
 
756
      {
 
757
       /*
 
758
        * Rotate the image as needed...
 
759
        */
 
760
 
 
761
        fputs("DEBUG: Using landscape orientation...\n", stderr);
 
762
 
 
763
        Orientation = (Orientation + 1) & 3;
 
764
        xsize       = yprint;
 
765
        yprint      = xprint;
 
766
        xprint      = xsize;
 
767
      }
 
768
    }
 
769
  }
 
770
  else
 
771
  {
 
772
   /*
 
773
    * Scale percentage of page size...
 
774
    */
 
775
 
 
776
    xprint = (PageRight - PageLeft) / 72.0;
 
777
    yprint = (PageTop - PageBottom) / 72.0;
 
778
    aspect = (float)img->yppi / (float)img->xppi;
 
779
 
 
780
    fprintf(stderr, "DEBUG: Before scaling: xprint=%.1f, yprint=%.1f\n",
 
781
            xprint, yprint);
 
782
 
 
783
    fprintf(stderr, "DEBUG: img->xppi = %d, img->yppi = %d, aspect = %f\n",
 
784
            img->xppi, img->yppi, aspect);
 
785
 
 
786
    xsize = xprint * zoom;
 
787
    ysize = xsize * img->ysize / img->xsize / aspect;
 
788
 
 
789
    if (ysize > (yprint * zoom))
 
790
    {
 
791
      ysize = yprint * zoom;
 
792
      xsize = ysize * img->xsize * aspect / img->ysize;
 
793
    }
 
794
 
 
795
    xsize2 = yprint * zoom;
 
796
    ysize2 = xsize2 * img->ysize / img->xsize / aspect;
 
797
 
 
798
    if (ysize2 > (xprint * zoom))
 
799
    {
 
800
      ysize2 = xprint * zoom;
 
801
      xsize2 = ysize2 * img->xsize * aspect / img->ysize;
 
802
    }
 
803
 
 
804
    fprintf(stderr, "DEBUG: Portrait size is %.2f x %.2f inches\n", xsize, ysize);
 
805
    fprintf(stderr, "DEBUG: Landscape size is %.2f x %.2f inches\n", xsize2, ysize2);
 
806
 
 
807
    if (cupsGetOption("orientation-requested", num_options, options) == NULL &&
 
808
        cupsGetOption("landscape", num_options, options) == NULL)
 
809
    {
 
810
     /*
 
811
      * Choose the rotation with the largest area, but prefer
 
812
      * portrait if they are equal...
 
813
      */
 
814
 
 
815
      fputs("DEBUG: Auto orientation...\n", stderr);
 
816
 
 
817
      if ((xsize * ysize) < (xsize2 * xsize2))
 
818
      {
 
819
       /*
 
820
        * Do landscape orientation...
 
821
        */
 
822
 
 
823
        fputs("DEBUG: Using landscape orientation...\n", stderr);
 
824
 
 
825
        Orientation = 1;
 
826
        xinches     = xsize2;
 
827
        yinches     = ysize2;
 
828
        xprint      = (PageTop - PageBottom) / 72.0;
 
829
        yprint      = (PageRight - PageLeft) / 72.0;
 
830
      }
 
831
      else
 
832
      {
 
833
       /*
 
834
        * Do portrait orientation...
 
835
        */
 
836
 
 
837
        fputs("DEBUG: Using portrait orientation...\n", stderr);
 
838
 
 
839
        Orientation = 0;
 
840
        xinches     = xsize;
 
841
        yinches     = ysize;
 
842
      }
 
843
    }
 
844
    else if (Orientation & 1)
 
845
    {
 
846
      fputs("DEBUG: Using landscape orientation...\n", stderr);
 
847
 
 
848
      xinches     = xsize2;
 
849
      yinches     = ysize2;
 
850
      xprint      = (PageTop - PageBottom) / 72.0;
 
851
      yprint      = (PageRight - PageLeft) / 72.0;
 
852
    }
 
853
    else
 
854
    {
 
855
      fputs("DEBUG: Using portrait orientation...\n", stderr);
 
856
 
 
857
      xinches     = xsize;
 
858
      yinches     = ysize;
 
859
      xprint      = (PageRight - PageLeft) / 72.0;
 
860
      yprint      = (PageTop - PageBottom) / 72.0;
 
861
    }
 
862
  }
 
863
 
 
864
 /*
 
865
  * Compute the number of pages to print and the size of the image on each
 
866
  * page...
 
867
  */
 
868
 
 
869
  xpages = ceil(xinches / xprint);
 
870
  ypages = ceil(yinches / yprint);
 
871
 
 
872
  xprint = xinches / xpages;
 
873
  yprint = yinches / ypages;
 
874
 
 
875
  fprintf(stderr, "DEBUG: xpages = %dx%.2fin, ypages = %dx%.2fin\n",
 
876
          xpages, xprint, ypages, yprint);
 
877
 
 
878
 /*
 
879
  * Compute the bitmap size...
 
880
  */
 
881
 
 
882
  if ((choice = ppdFindMarkedChoice(ppd, "PageSize")) != NULL &&
 
883
      strcasecmp(choice->choice, "Custom") == 0)
 
884
  {
 
885
    float       width,          /* New width in points */
 
886
                length;         /* New length in points */
 
887
 
 
888
 
 
889
   /*
 
890
    * Use the correct width and length for the current orientation...
 
891
    */
 
892
 
 
893
    if (Orientation & 1)
 
894
    {
 
895
      width  = yprint * 72.0;
 
896
      length = xprint * 72.0;
 
897
    }
 
898
    else
 
899
    {
 
900
      width  = xprint * 72.0;
 
901
      length = yprint * 72.0;
 
902
    }
 
903
 
 
904
   /*
 
905
    * Add margins to page size...
 
906
    */
 
907
 
 
908
    width  += ppd->custom_margins[0] + ppd->custom_margins[2];
 
909
    length += ppd->custom_margins[1] + ppd->custom_margins[3];
 
910
 
 
911
   /*
 
912
    * Enforce minimums...
 
913
    */
 
914
 
 
915
    if (width < ppd->custom_min[0])
 
916
      width = ppd->custom_min[0];
 
917
 
 
918
    if (length < ppd->custom_min[1])
 
919
      length = ppd->custom_min[1];
 
920
 
 
921
    fprintf(stderr, "DEBUG: Updated custom page size to %.2f x %.2f inches...\n",
 
922
            width / 72.0, length / 72.0);
 
923
 
 
924
   /*
 
925
    * Set the new custom size...
 
926
    */
 
927
 
 
928
    strcpy(header.cupsPageSizeName, "Custom");
 
929
 
 
930
    header.cupsPageSize[0] = width + 0.5;
 
931
    header.cupsPageSize[1] = length + 0.5;
 
932
    header.PageSize[0]     = width + 0.5;
 
933
    header.PageSize[1]     = length + 0.5;
 
934
 
 
935
   /*
 
936
    * Update page variables...
 
937
    */
 
938
 
 
939
    PageWidth  = width;
 
940
    PageLength = length;
 
941
    PageLeft   = ppd->custom_margins[0];
 
942
    PageRight  = width - ppd->custom_margins[2];
 
943
    PageBottom = ppd->custom_margins[1];
 
944
    PageTop    = length - ppd->custom_margins[3];
 
945
 
 
946
   /*
 
947
    * Remove margins from page size...
 
948
    */
 
949
 
 
950
    width  -= ppd->custom_margins[0] + ppd->custom_margins[2];
 
951
    length -= ppd->custom_margins[1] + ppd->custom_margins[3];
 
952
 
 
953
   /*
 
954
    * Set the bitmap size...
 
955
    */
 
956
 
 
957
    header.cupsWidth  = width * header.HWResolution[0] / 72.0;
 
958
    header.cupsHeight = length * header.HWResolution[1] / 72.0;
 
959
 
 
960
    header.cupsBytesPerLine = (header.cupsBitsPerPixel *
 
961
                               header.cupsWidth + 7) / 8;
 
962
 
 
963
    if (header.cupsColorOrder == CUPS_ORDER_BANDED)
 
964
      header.cupsBytesPerLine *= header.cupsNumColors;
 
965
  }
 
966
 
 
967
  header.Margins[0] = PageLeft;
 
968
  header.Margins[1] = PageBottom;
 
969
 
 
970
  fprintf(stderr, "DEBUG: PageSize = [%d %d]\n", header.PageSize[0],
 
971
          header.PageSize[1]);
 
972
 
 
973
  switch (Orientation)
 
974
  {
 
975
    default :
 
976
        switch (XPosition)
 
977
        {
 
978
          case -1 :
 
979
              header.cupsImagingBBox[0] = PageLeft;
 
980
              header.cupsImagingBBox[2] = PageLeft + xprint * 72;
 
981
              break;
 
982
          default :
 
983
              header.cupsImagingBBox[0] = (PageRight + PageLeft - xprint * 72) / 2;
 
984
              header.cupsImagingBBox[2] = (PageRight + PageLeft + xprint * 72) / 2;
 
985
              break;
 
986
          case 1 :
 
987
              header.cupsImagingBBox[0] = PageRight - xprint * 72;
 
988
              header.cupsImagingBBox[2] = PageRight;
 
989
              break;
 
990
        }
 
991
 
 
992
        switch (YPosition)
 
993
        {
 
994
          case -1 :
 
995
              header.cupsImagingBBox[1] = PageBottom;
 
996
              header.cupsImagingBBox[3] = PageBottom + yprint * 72;
 
997
              break;
 
998
          default :
 
999
              header.cupsImagingBBox[1] = (PageTop + PageBottom - yprint * 72) / 2;
 
1000
              header.cupsImagingBBox[3] = (PageTop + PageBottom + yprint * 72) / 2;
 
1001
              break;
 
1002
          case 1 :
 
1003
              header.cupsImagingBBox[1] = PageTop - yprint * 72;
 
1004
              header.cupsImagingBBox[3] = PageTop;
 
1005
              break;
 
1006
        }
 
1007
        break;
 
1008
 
 
1009
    case 1 :
 
1010
        switch (XPosition)
 
1011
        {
 
1012
          case -1 :
 
1013
              header.cupsImagingBBox[0] = PageBottom;
 
1014
              header.cupsImagingBBox[2] = PageBottom + yprint * 72;
 
1015
              break;
 
1016
          default :
 
1017
              header.cupsImagingBBox[0] = (PageTop + PageBottom - yprint * 72) / 2;
 
1018
              header.cupsImagingBBox[2] = (PageTop + PageBottom + yprint * 72) / 2;
 
1019
              break;
 
1020
          case 1 :
 
1021
              header.cupsImagingBBox[0] = PageTop - yprint * 72;
 
1022
              header.cupsImagingBBox[2] = PageTop;
 
1023
              break;
 
1024
        }
 
1025
 
 
1026
        switch (YPosition)
 
1027
        {
 
1028
          case -1 :
 
1029
              header.cupsImagingBBox[1] = PageLeft;
 
1030
              header.cupsImagingBBox[3] = PageLeft + xprint * 72;
 
1031
              break;
 
1032
          default :
 
1033
              header.cupsImagingBBox[1] = (PageRight + PageLeft - xprint * 72) / 2;
 
1034
              header.cupsImagingBBox[3] = (PageRight + PageLeft + xprint * 72) / 2;
 
1035
              break;
 
1036
          case 1 :
 
1037
              header.cupsImagingBBox[1] = PageRight - xprint * 72;
 
1038
              header.cupsImagingBBox[3] = PageRight;
 
1039
              break;
 
1040
        }
 
1041
        break;
 
1042
 
 
1043
    case 2 :
 
1044
        switch (XPosition)
 
1045
        {
 
1046
          case 1 :
 
1047
              header.cupsImagingBBox[0] = PageLeft;
 
1048
              header.cupsImagingBBox[2] = PageLeft + xprint * 72;
 
1049
              break;
 
1050
          default :
 
1051
              header.cupsImagingBBox[0] = (PageRight + PageLeft - xprint * 72) / 2;
 
1052
              header.cupsImagingBBox[2] = (PageRight + PageLeft + xprint * 72) / 2;
 
1053
              break;
 
1054
          case -1 :
 
1055
              header.cupsImagingBBox[0] = PageRight - xprint * 72;
 
1056
              header.cupsImagingBBox[2] = PageRight;
 
1057
              break;
 
1058
        }
 
1059
 
 
1060
        switch (YPosition)
 
1061
        {
 
1062
          case 1 :
 
1063
              header.cupsImagingBBox[1] = PageBottom;
 
1064
              header.cupsImagingBBox[3] = PageBottom + yprint * 72;
 
1065
              break;
 
1066
          default :
 
1067
              header.cupsImagingBBox[1] = (PageTop + PageBottom - yprint * 72) / 2;
 
1068
              header.cupsImagingBBox[3] = (PageTop + PageBottom + yprint * 72) / 2;
 
1069
              break;
 
1070
          case -1 :
 
1071
              header.cupsImagingBBox[1] = PageTop - yprint * 72;
 
1072
              header.cupsImagingBBox[3] = PageTop;
 
1073
              break;
 
1074
        }
 
1075
        break;
 
1076
 
 
1077
    case 3 :
 
1078
        switch (XPosition)
 
1079
        {
 
1080
          case 1 :
 
1081
              header.cupsImagingBBox[0] = PageBottom;
 
1082
              header.cupsImagingBBox[2] = PageBottom + yprint * 72;
 
1083
              break;
 
1084
          default :
 
1085
              header.cupsImagingBBox[0] = (PageTop + PageBottom - yprint * 72) / 2;
 
1086
              header.cupsImagingBBox[2] = (PageTop + PageBottom + yprint * 72) / 2;
 
1087
              break;
 
1088
          case -1 :
 
1089
              header.cupsImagingBBox[0] = PageTop - yprint * 72;
 
1090
              header.cupsImagingBBox[2] = PageTop;
 
1091
              break;
 
1092
        }
 
1093
 
 
1094
        switch (YPosition)
 
1095
        {
 
1096
          case 1 :
 
1097
              header.cupsImagingBBox[1] = PageLeft;
 
1098
              header.cupsImagingBBox[3] = PageLeft + xprint * 72;
 
1099
              break;
 
1100
          default :
 
1101
              header.cupsImagingBBox[1] = (PageRight + PageLeft - xprint * 72) / 2;
 
1102
              header.cupsImagingBBox[3] = (PageRight + PageLeft + xprint * 72) / 2;
 
1103
              break;
 
1104
          case -1 :
 
1105
              header.cupsImagingBBox[1] = PageRight - xprint * 72;
 
1106
              header.cupsImagingBBox[3] = PageRight;
 
1107
              break;
 
1108
        }
 
1109
        break;
 
1110
  }
 
1111
 
 
1112
  header.ImagingBoundingBox[0] = header.cupsImagingBBox[0];
 
1113
  header.ImagingBoundingBox[1] = header.cupsImagingBBox[1];
 
1114
  header.ImagingBoundingBox[2] = header.cupsImagingBBox[2];
 
1115
  header.ImagingBoundingBox[3] = header.cupsImagingBBox[3];
 
1116
 
 
1117
  if (header.cupsColorOrder == CUPS_ORDER_PLANAR)
 
1118
    num_planes = header.cupsNumColors;
 
1119
  else
 
1120
    num_planes = 1;
 
1121
 
 
1122
  if (header.cupsBitsPerColor >= 8)
 
1123
    zoom_type = CUPS_IZOOM_NORMAL;
 
1124
  else
 
1125
    zoom_type = CUPS_IZOOM_FAST;
 
1126
 
 
1127
 /*
 
1128
  * See if we need to collate, and if so how we need to do it...
 
1129
  */
 
1130
 
 
1131
  if (xpages == 1 && ypages == 1)
 
1132
    Collate = 0;
 
1133
 
 
1134
  slowcollate = Collate && ppdFindOption(ppd, "Collate") == NULL;
 
1135
  if (ppd != NULL)
 
1136
    slowcopies = ppd->manual_copies;
 
1137
  else
 
1138
    slowcopies = 1;
 
1139
 
 
1140
  if (Copies > 1 && !slowcollate && !slowcopies)
 
1141
  {
 
1142
    header.Collate   = (cups_bool_t)Collate;
 
1143
    header.NumCopies = Copies;
 
1144
 
 
1145
    Copies = 1;
 
1146
  }
 
1147
  else
 
1148
    header.NumCopies = 1;
 
1149
 
 
1150
 /*
 
1151
  * Create the dithering lookup tables...
 
1152
  */
 
1153
 
 
1154
  OnPixels[0]    = 0x00;
 
1155
  OnPixels[255]  = 0xff;
 
1156
  OffPixels[0]   = 0x00;
 
1157
  OffPixels[255] = 0xff;
 
1158
 
 
1159
  switch (header.cupsBitsPerColor)
 
1160
  {
 
1161
    case 2 :
 
1162
        for (i = 1; i < 255; i ++)
 
1163
        {
 
1164
          OnPixels[i]  = 0x55 * (i / 85 + 1);
 
1165
          OffPixels[i] = 0x55 * (i / 64);
 
1166
        }
 
1167
        break;
 
1168
    case 4 :
 
1169
        for (i = 1; i < 255; i ++)
 
1170
        {
 
1171
          OnPixels[i]  = 17 * (i / 17 + 1);
 
1172
          OffPixels[i] = 17 * (i / 16);
 
1173
        }
 
1174
        break;
 
1175
  }
 
1176
 
 
1177
 /*
 
1178
  * Output the pages...
 
1179
  */
 
1180
 
 
1181
  fprintf(stderr, "DEBUG: cupsWidth = %d\n", header.cupsWidth);
 
1182
  fprintf(stderr, "DEBUG: cupsHeight = %d\n", header.cupsHeight);
 
1183
  fprintf(stderr, "DEBUG: cupsBitsPerColor = %d\n", header.cupsBitsPerColor);
 
1184
  fprintf(stderr, "DEBUG: cupsBitsPerPixel = %d\n", header.cupsBitsPerPixel);
 
1185
  fprintf(stderr, "DEBUG: cupsBytesPerLine = %d\n", header.cupsBytesPerLine);
 
1186
  fprintf(stderr, "DEBUG: cupsColorOrder = %d\n", header.cupsColorOrder);
 
1187
  fprintf(stderr, "DEBUG: cupsColorSpace = %d\n", header.cupsColorSpace);
 
1188
  fprintf(stderr, "DEBUG: img->colorspace = %d\n", img->colorspace);
 
1189
 
 
1190
  row = malloc(2 * header.cupsBytesPerLine);
 
1191
  ras = cupsRasterOpen(1, CUPS_RASTER_WRITE);
 
1192
 
 
1193
  for (i = 0, page = 1; i < Copies; i ++)
 
1194
    for (xpage = 0; xpage < xpages; xpage ++)
 
1195
      for (ypage = 0; ypage < ypages; ypage ++, page ++)
 
1196
      {
 
1197
        fprintf(stderr, "INFO: Formatting page %d.\n", page);
 
1198
 
 
1199
        if (Orientation & 1)
 
1200
        {
 
1201
          xc0    = img->xsize * ypage / ypages;
 
1202
          xc1    = img->xsize * (ypage + 1) / ypages - 1;
 
1203
          yc0    = img->ysize * xpage / xpages;
 
1204
          yc1    = img->ysize * (xpage + 1) / xpages - 1;
 
1205
 
 
1206
          xtemp = header.HWResolution[0] * yprint;
 
1207
          ytemp = header.HWResolution[1] * xprint;
 
1208
        }
 
1209
        else
 
1210
        {
 
1211
          xc0    = img->xsize * xpage / xpages;
 
1212
          xc1    = img->xsize * (xpage + 1) / xpages - 1;
 
1213
          yc0    = img->ysize * ypage / ypages;
 
1214
          yc1    = img->ysize * (ypage + 1) / ypages - 1;
 
1215
 
 
1216
          xtemp = header.HWResolution[0] * xprint;
 
1217
          ytemp = header.HWResolution[1] * yprint;
 
1218
        }
 
1219
 
 
1220
        cupsRasterWriteHeader2(ras, &header);
 
1221
 
 
1222
        for (plane = 0; plane < num_planes; plane ++)
 
1223
        {
 
1224
         /*
 
1225
          * Initialize the image "zoom" engine...
 
1226
          */
 
1227
 
 
1228
          if (Flip)
 
1229
            z = _cupsImageZoomNew(img, xc0, yc0, xc1, yc1, -xtemp, ytemp,
 
1230
                                  Orientation & 1, zoom_type);
 
1231
          else
 
1232
            z = _cupsImageZoomNew(img, xc0, yc0, xc1, yc1, xtemp, ytemp,
 
1233
                                  Orientation & 1, zoom_type);
 
1234
 
 
1235
         /*
 
1236
          * Write leading blank space as needed...
 
1237
          */
 
1238
 
 
1239
          if (header.cupsHeight > z->ysize && YPosition <= 0)
 
1240
          {
 
1241
            blank_line(&header, row);
 
1242
 
 
1243
            y = header.cupsHeight - z->ysize;
 
1244
            if (YPosition == 0)
 
1245
              y /= 2;
 
1246
 
 
1247
            fprintf(stderr, "DEBUG: Writing %d leading blank lines...\n", y);
 
1248
 
 
1249
            for (; y > 0; y --)
 
1250
            {
 
1251
              if (cupsRasterWritePixels(ras, row, header.cupsBytesPerLine) <
 
1252
                      header.cupsBytesPerLine)
 
1253
              {
 
1254
                fputs("ERROR: Unable to send raster data to the driver.\n",
 
1255
                      stderr);
 
1256
                cupsImageClose(img);
 
1257
                exit(1);
 
1258
              }
 
1259
            }
 
1260
          }
 
1261
 
 
1262
         /*
 
1263
          * Then write image data...
 
1264
          */
 
1265
 
 
1266
          for (y = z->ysize, yerr0 = 0, yerr1 = z->ysize, iy = 0, last_iy = -2;
 
1267
               y > 0;
 
1268
               y --)
 
1269
          {
 
1270
            if (iy != last_iy)
 
1271
            {
 
1272
              if (zoom_type != CUPS_IZOOM_FAST && (iy - last_iy) > 1)
 
1273
                _cupsImageZoomFill(z, iy);
 
1274
 
 
1275
              _cupsImageZoomFill(z, iy + z->yincr);
 
1276
 
 
1277
              last_iy = iy;
 
1278
            }
 
1279
 
 
1280
           /*
 
1281
            * Format this line of raster data for the printer...
 
1282
            */
 
1283
 
 
1284
            blank_line(&header, row);
 
1285
 
 
1286
            r0 = z->rows[z->row];
 
1287
            r1 = z->rows[1 - z->row];
 
1288
 
 
1289
            switch (header.cupsColorSpace)
 
1290
            {
 
1291
              case CUPS_CSPACE_W :
 
1292
                  format_W(&header, row, y, plane, z->xsize, z->ysize,
 
1293
                           yerr0, yerr1, r0, r1);
 
1294
                  break;
 
1295
              default :
 
1296
              case CUPS_CSPACE_RGB :
 
1297
                  format_RGB(&header, row, y, plane, z->xsize, z->ysize,
 
1298
                             yerr0, yerr1, r0, r1);
 
1299
                  break;
 
1300
              case CUPS_CSPACE_RGBA :
 
1301
              case CUPS_CSPACE_RGBW :
 
1302
                  format_RGBA(&header, row, y, plane, z->xsize, z->ysize,
 
1303
                              yerr0, yerr1, r0, r1);
 
1304
                  break;
 
1305
              case CUPS_CSPACE_K :
 
1306
              case CUPS_CSPACE_WHITE :
 
1307
              case CUPS_CSPACE_GOLD :
 
1308
              case CUPS_CSPACE_SILVER :
 
1309
                  format_K(&header, row, y, plane, z->xsize, z->ysize,
 
1310
                           yerr0, yerr1, r0, r1);
 
1311
                  break;
 
1312
              case CUPS_CSPACE_CMY :
 
1313
                  format_CMY(&header, row, y, plane, z->xsize, z->ysize,
 
1314
                             yerr0, yerr1, r0, r1);
 
1315
                  break;
 
1316
              case CUPS_CSPACE_YMC :
 
1317
                  format_YMC(&header, row, y, plane, z->xsize, z->ysize,
 
1318
                             yerr0, yerr1, r0, r1);
 
1319
                  break;
 
1320
              case CUPS_CSPACE_CMYK :
 
1321
                  format_CMYK(&header, row, y, plane, z->xsize, z->ysize,
 
1322
                              yerr0, yerr1, r0, r1);
 
1323
                  break;
 
1324
              case CUPS_CSPACE_YMCK :
 
1325
              case CUPS_CSPACE_GMCK :
 
1326
              case CUPS_CSPACE_GMCS :
 
1327
                  format_YMCK(&header, row, y, plane, z->xsize, z->ysize,
 
1328
                              yerr0, yerr1, r0, r1);
 
1329
                  break;
 
1330
              case CUPS_CSPACE_KCMYcm :
 
1331
                  if (header.cupsBitsPerColor == 1)
 
1332
                  {
 
1333
                    format_KCMYcm(&header, row, y, plane, z->xsize, z->ysize,
 
1334
                                  yerr0, yerr1, r0, r1);
 
1335
                    break;
 
1336
                  }
 
1337
              case CUPS_CSPACE_KCMY :
 
1338
                  format_KCMY(&header, row, y, plane, z->xsize, z->ysize,
 
1339
                              yerr0, yerr1, r0, r1);
 
1340
                  break;
 
1341
            }
 
1342
 
 
1343
           /*
 
1344
            * Write the raster data to the driver...
 
1345
            */
 
1346
 
 
1347
            if (cupsRasterWritePixels(ras, row, header.cupsBytesPerLine) <
 
1348
                                      header.cupsBytesPerLine)
 
1349
            {
 
1350
              fputs("ERROR: Unable to send raster data to the driver.\n",
 
1351
                    stderr);
 
1352
              cupsImageClose(img);
 
1353
              exit(1);
 
1354
            }
 
1355
 
 
1356
           /*
 
1357
            * Compute the next scanline in the image...
 
1358
            */
 
1359
 
 
1360
            iy    += z->ystep;
 
1361
            yerr0 += z->ymod;
 
1362
            yerr1 -= z->ymod;
 
1363
            if (yerr1 <= 0)
 
1364
            {
 
1365
              yerr0 -= z->ysize;
 
1366
              yerr1 += z->ysize;
 
1367
              iy    += z->yincr;
 
1368
            }
 
1369
          }
 
1370
 
 
1371
         /*
 
1372
          * Write trailing blank space as needed...
 
1373
          */
 
1374
 
 
1375
          if (header.cupsHeight > z->ysize && YPosition >= 0)
 
1376
          {
 
1377
            blank_line(&header, row);
 
1378
 
 
1379
            y = header.cupsHeight - z->ysize;
 
1380
            if (YPosition == 0)
 
1381
              y = y - y / 2;
 
1382
 
 
1383
            fprintf(stderr, "DEBUG: Writing %d trailing blank lines...\n", y);
 
1384
 
 
1385
            for (; y > 0; y --)
 
1386
            {
 
1387
              if (cupsRasterWritePixels(ras, row, header.cupsBytesPerLine) <
 
1388
                      header.cupsBytesPerLine)
 
1389
              {
 
1390
                fputs("ERROR: Unable to send raster data to the driver.\n",
 
1391
                      stderr);
 
1392
                cupsImageClose(img);
 
1393
                exit(1);
 
1394
              }
 
1395
            }
 
1396
          }
 
1397
 
 
1398
         /*
 
1399
          * Free memory used for the "zoom" engine...
 
1400
          */
 
1401
 
 
1402
          _cupsImageZoomDelete(z);
 
1403
        }
 
1404
      }
 
1405
 
 
1406
 /*
 
1407
  * Close files...
 
1408
  */
 
1409
 
 
1410
  free(row);
 
1411
  cupsRasterClose(ras);
 
1412
  cupsImageClose(img);
 
1413
  ppdClose(ppd);
 
1414
 
 
1415
  return (0);
 
1416
}
 
1417
 
 
1418
 
 
1419
/*
 
1420
 * 'blank_line()' - Clear a line buffer to the blank value...
 
1421
 */
 
1422
 
 
1423
static void
 
1424
blank_line(cups_page_header2_t *header, /* I - Page header */
 
1425
           unsigned char       *row)    /* I - Row buffer */
 
1426
{
 
1427
  int   count;                          /* Remaining bytes */
 
1428
 
 
1429
 
 
1430
  count = header->cupsBytesPerLine;
 
1431
 
 
1432
  switch (header->cupsColorSpace)
 
1433
  {
 
1434
    case CUPS_CSPACE_CIEXYZ :
 
1435
        while (count > 2)
 
1436
        {
 
1437
          *row++ = 242;
 
1438
          *row++ = 255;
 
1439
          *row++ = 255;
 
1440
          count -= 3;
 
1441
        }
 
1442
        break;
 
1443
 
 
1444
    case CUPS_CSPACE_CIELab :
 
1445
    case CUPS_CSPACE_ICC1 :
 
1446
    case CUPS_CSPACE_ICC2 :
 
1447
    case CUPS_CSPACE_ICC3 :
 
1448
    case CUPS_CSPACE_ICC4 :
 
1449
    case CUPS_CSPACE_ICC5 :
 
1450
    case CUPS_CSPACE_ICC6 :
 
1451
    case CUPS_CSPACE_ICC7 :
 
1452
    case CUPS_CSPACE_ICC8 :
 
1453
    case CUPS_CSPACE_ICC9 :
 
1454
    case CUPS_CSPACE_ICCA :
 
1455
    case CUPS_CSPACE_ICCB :
 
1456
    case CUPS_CSPACE_ICCC :
 
1457
    case CUPS_CSPACE_ICCD :
 
1458
    case CUPS_CSPACE_ICCE :
 
1459
    case CUPS_CSPACE_ICCF :
 
1460
        while (count > 2)
 
1461
        {
 
1462
          *row++ = 255;
 
1463
          *row++ = 128;
 
1464
          *row++ = 128;
 
1465
          count -= 3;
 
1466
        }
 
1467
        break;
 
1468
 
 
1469
    case CUPS_CSPACE_K :
 
1470
    case CUPS_CSPACE_CMY :
 
1471
    case CUPS_CSPACE_CMYK :
 
1472
    case CUPS_CSPACE_YMC :
 
1473
    case CUPS_CSPACE_YMCK :
 
1474
    case CUPS_CSPACE_KCMY :
 
1475
    case CUPS_CSPACE_KCMYcm :
 
1476
    case CUPS_CSPACE_GMCK :
 
1477
    case CUPS_CSPACE_GMCS :
 
1478
    case CUPS_CSPACE_WHITE :
 
1479
    case CUPS_CSPACE_GOLD :
 
1480
    case CUPS_CSPACE_SILVER :
 
1481
        memset(row, 0, count);
 
1482
        break;
 
1483
 
 
1484
    default :
 
1485
        memset(row, 255, count);
 
1486
        break;
 
1487
  }
 
1488
}
 
1489
 
 
1490
 
 
1491
/*
 
1492
 * 'format_CMY()' - Convert image data to CMY.
 
1493
 */
 
1494
 
 
1495
static void
 
1496
format_CMY(cups_page_header2_t *header, /* I - Page header */
 
1497
            unsigned char      *row,    /* IO - Bitmap data for device */
 
1498
            int                y,       /* I - Current row */
 
1499
            int                z,       /* I - Current plane */
 
1500
            int                xsize,   /* I - Width of image data */
 
1501
            int                ysize,   /* I - Height of image data */
 
1502
            int                yerr0,   /* I - Top Y error */
 
1503
            int                yerr1,   /* I - Bottom Y error */
 
1504
            cups_ib_t          *r0,     /* I - Primary image data */
 
1505
            cups_ib_t          *r1)     /* I - Image data for interpolation */
 
1506
{
 
1507
  cups_ib_t     *ptr,                   /* Pointer into row */
 
1508
                *cptr,                  /* Pointer into cyan */
 
1509
                *mptr,                  /* Pointer into magenta */
 
1510
                *yptr,                  /* Pointer into yellow */
 
1511
                bitmask;                /* Current mask for pixel */
 
1512
  int           bitoffset;              /* Current offset in line */
 
1513
  int           bandwidth;              /* Width of a color band */
 
1514
  int           x,                      /* Current X coordinate on page */
 
1515
                *dither;                /* Pointer into dither array */
 
1516
 
 
1517
 
 
1518
  switch (XPosition)
 
1519
  {
 
1520
    case -1 :
 
1521
        bitoffset = 0;
 
1522
        break;
 
1523
    default :
 
1524
        bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2);
 
1525
        break;
 
1526
    case 1 :
 
1527
        bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize);
 
1528
        break;
 
1529
  }
 
1530
 
 
1531
  ptr       = row + bitoffset / 8;
 
1532
  bandwidth = header->cupsBytesPerLine / 3;
 
1533
 
 
1534
  switch (header->cupsColorOrder)
 
1535
  {
 
1536
    case CUPS_ORDER_CHUNKED :
 
1537
        switch (header->cupsBitsPerColor)
 
1538
        {
 
1539
          case 1 :
 
1540
              bitmask = 64 >> (bitoffset & 7);
 
1541
              dither  = Floyd16x16[y & 15];
 
1542
 
 
1543
              for (x = xsize ; x > 0; x --)
 
1544
              {
 
1545
                if (*r0++ > dither[x & 15])
 
1546
                  *ptr ^= bitmask;
 
1547
                bitmask >>= 1;
 
1548
 
 
1549
                if (*r0++ > dither[x & 15])
 
1550
                  *ptr ^= bitmask;
 
1551
                bitmask >>= 1;
 
1552
 
 
1553
                if (*r0++ > dither[x & 15])
 
1554
                  *ptr ^= bitmask;
 
1555
 
 
1556
                if (bitmask > 1)
 
1557
                  bitmask >>= 2;
 
1558
                else
 
1559
                {
 
1560
                  bitmask = 64;
 
1561
                  ptr ++;
 
1562
                }
 
1563
              }
 
1564
              break;
 
1565
 
 
1566
          case 2 :
 
1567
              dither = Floyd8x8[y & 7];
 
1568
 
 
1569
              for (x = xsize ; x > 0; x --, r0 += 3)
 
1570
              {
 
1571
                if ((r0[0] & 63) > dither[x & 7])
 
1572
                  *ptr ^= (0x30 & OnPixels[r0[0]]);
 
1573
                else
 
1574
                  *ptr ^= (0x30 & OffPixels[r0[0]]);
 
1575
 
 
1576
                if ((r0[1] & 63) > dither[x & 7])
 
1577
                  *ptr ^= (0x0c & OnPixels[r0[1]]);
 
1578
                else
 
1579
                  *ptr ^= (0x0c & OffPixels[r0[1]]);
 
1580
 
 
1581
                if ((r0[2] & 63) > dither[x & 7])
 
1582
                  *ptr++ ^= (0x03 & OnPixels[r0[2]]);
 
1583
                else
 
1584
                  *ptr++ ^= (0x03 & OffPixels[r0[2]]);
 
1585
              }
 
1586
              break;
 
1587
 
 
1588
          case 4 :
 
1589
              dither = Floyd4x4[y & 3];
 
1590
 
 
1591
              for (x = xsize ; x > 0; x --, r0 += 3)
 
1592
              {
 
1593
                if ((r0[0] & 15) > dither[x & 3])
 
1594
                  *ptr++ ^= (0x0f & OnPixels[r0[0]]);
 
1595
                else
 
1596
                  *ptr++ ^= (0x0f & OffPixels[r0[0]]);
 
1597
 
 
1598
                if ((r0[1] & 15) > dither[x & 3])
 
1599
                  *ptr ^= (0xf0 & OnPixels[r0[1]]);
 
1600
                else
 
1601
                  *ptr ^= (0xf0 & OffPixels[r0[1]]);
 
1602
 
 
1603
                if ((r0[2] & 15) > dither[x & 3])
 
1604
                  *ptr++ ^= (0x0f & OnPixels[r0[2]]);
 
1605
                else
 
1606
                  *ptr++ ^= (0x0f & OffPixels[r0[2]]);
 
1607
              }
 
1608
              break;
 
1609
 
 
1610
          case 8 :
 
1611
              for (x = xsize  * 3; x > 0; x --, r0 ++, r1 ++)
 
1612
                if (*r0 == *r1)
 
1613
                  *ptr++ = *r0;
 
1614
                else
 
1615
                  *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize;
 
1616
              break;
 
1617
        }
 
1618
        break;
 
1619
 
 
1620
    case CUPS_ORDER_BANDED :
 
1621
        cptr = ptr;
 
1622
        mptr = ptr + bandwidth;
 
1623
        yptr = ptr + 2 * bandwidth;
 
1624
 
 
1625
        switch (header->cupsBitsPerColor)
 
1626
        {
 
1627
          case 1 :
 
1628
              bitmask = 0x80 >> (bitoffset & 7);
 
1629
              dither  = Floyd16x16[y & 15];
 
1630
 
 
1631
              for (x = xsize; x > 0; x --)
 
1632
              {
 
1633
                if (*r0++ > dither[x & 15])
 
1634
                  *cptr ^= bitmask;
 
1635
                if (*r0++ > dither[x & 15])
 
1636
                  *mptr ^= bitmask;
 
1637
                if (*r0++ > dither[x & 15])
 
1638
                  *yptr ^= bitmask;
 
1639
 
 
1640
                if (bitmask > 1)
 
1641
                  bitmask >>= 1;
 
1642
                else
 
1643
                {
 
1644
                  bitmask = 0x80;
 
1645
                  cptr ++;
 
1646
                  mptr ++;
 
1647
                  yptr ++;
 
1648
                }
 
1649
              }
 
1650
              break;
 
1651
 
 
1652
          case 2 :
 
1653
              bitmask = 0xc0 >> (bitoffset & 7);
 
1654
              dither  = Floyd8x8[y & 7];
 
1655
 
 
1656
              for (x = xsize; x > 0; x --)
 
1657
              {
 
1658
                if ((*r0 & 63) > dither[x & 7])
 
1659
                  *cptr ^= (bitmask & OnPixels[*r0++]);
 
1660
                else
 
1661
                  *cptr ^= (bitmask & OffPixels[*r0++]);
 
1662
 
 
1663
                if ((*r0 & 63) > dither[x & 7])
 
1664
                  *mptr ^= (bitmask & OnPixels[*r0++]);
 
1665
                else
 
1666
                  *mptr ^= (bitmask & OffPixels[*r0++]);
 
1667
 
 
1668
                if ((*r0 & 63) > dither[x & 7])
 
1669
                  *yptr ^= (bitmask & OnPixels[*r0++]);
 
1670
                else
 
1671
                  *yptr ^= (bitmask & OffPixels[*r0++]);
 
1672
 
 
1673
                if (bitmask > 3)
 
1674
                  bitmask >>= 2;
 
1675
                else
 
1676
                {
 
1677
                  bitmask = 0xc0;
 
1678
 
 
1679
                  cptr ++;
 
1680
                  mptr ++;
 
1681
                  yptr ++;
 
1682
                }
 
1683
              }
 
1684
              break;
 
1685
 
 
1686
          case 4 :
 
1687
              bitmask = 0xf0 >> (bitoffset & 7);
 
1688
              dither  = Floyd4x4[y & 3];
 
1689
 
 
1690
              for (x = xsize; x > 0; x --)
 
1691
              {
 
1692
                if ((*r0 & 15) > dither[x & 3])
 
1693
                  *cptr ^= (bitmask & OnPixels[*r0++]);
 
1694
                else
 
1695
                  *cptr ^= (bitmask & OffPixels[*r0++]);
 
1696
 
 
1697
                if ((*r0 & 15) > dither[x & 3])
 
1698
                  *mptr ^= (bitmask & OnPixels[*r0++]);
 
1699
                else
 
1700
                  *mptr ^= (bitmask & OffPixels[*r0++]);
 
1701
 
 
1702
                if ((*r0 & 15) > dither[x & 3])
 
1703
                  *yptr ^= (bitmask & OnPixels[*r0++]);
 
1704
                else
 
1705
                  *yptr ^= (bitmask & OffPixels[*r0++]);
 
1706
 
 
1707
                if (bitmask == 0xf0)
 
1708
                  bitmask = 0x0f;
 
1709
                else
 
1710
                {
 
1711
                  bitmask = 0xf0;
 
1712
 
 
1713
                  cptr ++;
 
1714
                  mptr ++;
 
1715
                  yptr ++;
 
1716
                }
 
1717
              }
 
1718
              break;
 
1719
 
 
1720
          case 8 :
 
1721
              for (x = xsize; x > 0; x --, r0 += 3, r1 += 3)
 
1722
              {
 
1723
                if (r0[0] == r1[0])
 
1724
                  *cptr++ = r0[0];
 
1725
                else
 
1726
                  *cptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize;
 
1727
 
 
1728
                if (r0[1] == r1[1])
 
1729
                  *mptr++ = r0[1];
 
1730
                else
 
1731
                  *mptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize;
 
1732
 
 
1733
                if (r0[2] == r1[2])
 
1734
                  *yptr++ = r0[2];
 
1735
                else
 
1736
                  *yptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize;
 
1737
              }
 
1738
              break;
 
1739
        }
 
1740
        break;
 
1741
 
 
1742
    case CUPS_ORDER_PLANAR :
 
1743
        switch (header->cupsBitsPerColor)
 
1744
        {
 
1745
          case 1 :
 
1746
              bitmask = 0x80 >> (bitoffset & 7);
 
1747
              dither  = Floyd16x16[y & 15];
 
1748
 
 
1749
              switch (z)
 
1750
              {
 
1751
                case 0 :
 
1752
                    for (x = xsize; x > 0; x --, r0 += 3)
 
1753
                    {
 
1754
                      if (r0[0] > dither[x & 15])
 
1755
                        *ptr ^= bitmask;
 
1756
 
 
1757
                      if (bitmask > 1)
 
1758
                        bitmask >>= 1;
 
1759
                      else
 
1760
                      {
 
1761
                        bitmask = 0x80;
 
1762
                        ptr ++;
 
1763
                      }
 
1764
                    }
 
1765
                    break;
 
1766
 
 
1767
                case 1 :
 
1768
                    for (x = xsize; x > 0; x --, r0 += 3)
 
1769
                    {
 
1770
                      if (r0[1] > dither[x & 15])
 
1771
                        *ptr ^= bitmask;
 
1772
 
 
1773
                      if (bitmask > 1)
 
1774
                        bitmask >>= 1;
 
1775
                      else
 
1776
                      {
 
1777
                        bitmask = 0x80;
 
1778
                        ptr ++;
 
1779
                      }
 
1780
                    }
 
1781
                    break;
 
1782
 
 
1783
                case 2 :
 
1784
                    for (x = xsize; x > 0; x --, r0 += 3)
 
1785
                    {
 
1786
                      if (r0[2] > dither[x & 15])
 
1787
                        *ptr ^= bitmask;
 
1788
 
 
1789
                      if (bitmask > 1)
 
1790
                        bitmask >>= 1;
 
1791
                      else
 
1792
                      {
 
1793
                        bitmask = 0x80;
 
1794
                        ptr ++;
 
1795
                      }
 
1796
                    }
 
1797
                    break;
 
1798
              }
 
1799
              break;
 
1800
 
 
1801
          case 2 :
 
1802
              bitmask = 0xc0 >> (bitoffset & 7);
 
1803
              dither  = Floyd8x8[y & 7];
 
1804
              r0 += z;
 
1805
 
 
1806
              for (x = xsize; x > 0; x --, r0 += 3)
 
1807
              {
 
1808
                if ((*r0 & 63) > dither[x & 7])
 
1809
                  *ptr ^= (bitmask & OnPixels[*r0]);
 
1810
                else
 
1811
                  *ptr ^= (bitmask & OffPixels[*r0]);
 
1812
 
 
1813
                if (bitmask > 3)
 
1814
                  bitmask >>= 2;
 
1815
                else
 
1816
                {
 
1817
                  bitmask = 0xc0;
 
1818
 
 
1819
                  ptr ++;
 
1820
                }
 
1821
              }
 
1822
              break;
 
1823
 
 
1824
          case 4 :
 
1825
              bitmask = 0xf0 >> (bitoffset & 7);
 
1826
              dither  = Floyd4x4[y & 3];
 
1827
              r0 += z;
 
1828
 
 
1829
              for (x = xsize; x > 0; x --, r0 += 3)
 
1830
              {
 
1831
                if ((*r0 & 15) > dither[x & 3])
 
1832
                  *ptr ^= (bitmask & OnPixels[*r0]);
 
1833
                else
 
1834
                  *ptr ^= (bitmask & OffPixels[*r0]);
 
1835
 
 
1836
                if (bitmask == 0xf0)
 
1837
                  bitmask = 0x0f;
 
1838
                else
 
1839
                {
 
1840
                  bitmask = 0xf0;
 
1841
 
 
1842
                  ptr ++;
 
1843
                }
 
1844
              }
 
1845
              break;
 
1846
 
 
1847
          case 8 :
 
1848
              r0 += z;
 
1849
              r1 += z;
 
1850
 
 
1851
              for (x = xsize; x > 0; x --, r0 += 3, r1 += 3)
 
1852
              {
 
1853
                if (*r0 == *r1)
 
1854
                  *ptr++ = *r0;
 
1855
                else
 
1856
                  *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize;
 
1857
              }
 
1858
              break;
 
1859
        }
 
1860
        break;
 
1861
  }
 
1862
}
 
1863
 
 
1864
 
 
1865
/*
 
1866
 * 'format_CMYK()' - Convert image data to CMYK.
 
1867
 */
 
1868
 
 
1869
static void
 
1870
format_CMYK(cups_page_header2_t *header,/* I - Page header */
 
1871
            unsigned char       *row,   /* IO - Bitmap data for device */
 
1872
            int                 y,      /* I - Current row */
 
1873
            int                 z,      /* I - Current plane */
 
1874
            int                 xsize,  /* I - Width of image data */
 
1875
            int                 ysize,  /* I - Height of image data */
 
1876
            int                 yerr0,  /* I - Top Y error */
 
1877
            int                 yerr1,  /* I - Bottom Y error */
 
1878
            cups_ib_t           *r0,    /* I - Primary image data */
 
1879
            cups_ib_t           *r1)    /* I - Image data for interpolation */
 
1880
{
 
1881
  cups_ib_t     *ptr,                   /* Pointer into row */
 
1882
                *cptr,                  /* Pointer into cyan */
 
1883
                *mptr,                  /* Pointer into magenta */
 
1884
                *yptr,                  /* Pointer into yellow */
 
1885
                *kptr,                  /* Pointer into black */
 
1886
                bitmask;                /* Current mask for pixel */
 
1887
  int           bitoffset;              /* Current offset in line */
 
1888
  int           bandwidth;              /* Width of a color band */
 
1889
  int           x,                      /* Current X coordinate on page */
 
1890
                *dither;                /* Pointer into dither array */
 
1891
  int           pc, pm, py;             /* CMY pixels */
 
1892
 
 
1893
 
 
1894
  switch (XPosition)
 
1895
  {
 
1896
    case -1 :
 
1897
        bitoffset = 0;
 
1898
        break;
 
1899
    default :
 
1900
        bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2);
 
1901
        break;
 
1902
    case 1 :
 
1903
        bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize);
 
1904
        break;
 
1905
  }
 
1906
 
 
1907
  ptr       = row + bitoffset / 8;
 
1908
  bandwidth = header->cupsBytesPerLine / 4;
 
1909
 
 
1910
  switch (header->cupsColorOrder)
 
1911
  {
 
1912
    case CUPS_ORDER_CHUNKED :
 
1913
        switch (header->cupsBitsPerColor)
 
1914
        {
 
1915
          case 1 :
 
1916
              bitmask = 128 >> (bitoffset & 7);
 
1917
              dither  = Floyd16x16[y & 15];
 
1918
 
 
1919
              for (x = xsize ; x > 0; x --)
 
1920
              {
 
1921
                pc = *r0++ > dither[x & 15];
 
1922
                pm = *r0++ > dither[x & 15];
 
1923
                py = *r0++ > dither[x & 15];
 
1924
 
 
1925
                if (pc && pm && py)
 
1926
                {
 
1927
                  bitmask >>= 3;
 
1928
                  *ptr ^= bitmask;
 
1929
                }
 
1930
                else
 
1931
                {
 
1932
                  if (pc)
 
1933
                    *ptr ^= bitmask;
 
1934
                  bitmask >>= 1;
 
1935
 
 
1936
                  if (pm)
 
1937
                    *ptr ^= bitmask;
 
1938
                  bitmask >>= 1;
 
1939
 
 
1940
                  if (py)
 
1941
                    *ptr ^= bitmask;
 
1942
                  bitmask >>= 1;
 
1943
                }
 
1944
 
 
1945
                if (bitmask > 1)
 
1946
                  bitmask >>= 1;
 
1947
                else
 
1948
                {
 
1949
                  bitmask = 128;
 
1950
                  ptr ++;
 
1951
                }
 
1952
              }
 
1953
              break;
 
1954
 
 
1955
          case 2 :
 
1956
              dither = Floyd8x8[y & 7];
 
1957
 
 
1958
              for (x = xsize ; x > 0; x --, r0 += 4)
 
1959
              {
 
1960
                if ((r0[0] & 63) > dither[x & 7])
 
1961
                  *ptr ^= (0xc0 & OnPixels[r0[0]]);
 
1962
                else
 
1963
                  *ptr ^= (0xc0 & OffPixels[r0[0]]);
 
1964
 
 
1965
                if ((r0[1] & 63) > dither[x & 7])
 
1966
                  *ptr ^= (0x30 & OnPixels[r0[1]]);
 
1967
                else
 
1968
                  *ptr ^= (0x30 & OffPixels[r0[1]]);
 
1969
 
 
1970
                if ((r0[2] & 63) > dither[x & 7])
 
1971
                  *ptr ^= (0x0c & OnPixels[r0[2]]);
 
1972
                else
 
1973
                  *ptr ^= (0x0c & OffPixels[r0[2]]);
 
1974
 
 
1975
                if ((r0[3] & 63) > dither[x & 7])
 
1976
                  *ptr++ ^= (0x03 & OnPixels[r0[3]]);
 
1977
                else
 
1978
                  *ptr++ ^= (0x03 & OffPixels[r0[3]]);
 
1979
              }
 
1980
              break;
 
1981
 
 
1982
          case 4 :
 
1983
              dither = Floyd4x4[y & 3];
 
1984
 
 
1985
              for (x = xsize ; x > 0; x --, r0 += 4)
 
1986
              {
 
1987
                if ((r0[0] & 15) > dither[x & 3])
 
1988
                  *ptr ^= (0xf0 & OnPixels[r0[0]]);
 
1989
                else
 
1990
                  *ptr ^= (0xf0 & OffPixels[r0[0]]);
 
1991
 
 
1992
                if ((r0[1] & 15) > dither[x & 3])
 
1993
                  *ptr++ ^= (0x0f & OnPixels[r0[1]]);
 
1994
                else
 
1995
                  *ptr++ ^= (0x0f & OffPixels[r0[1]]);
 
1996
 
 
1997
                if ((r0[2] & 15) > dither[x & 3])
 
1998
                  *ptr ^= (0xf0 & OnPixels[r0[2]]);
 
1999
                else
 
2000
                  *ptr ^= (0xf0 & OffPixels[r0[2]]);
 
2001
 
 
2002
                if ((r0[3] & 15) > dither[x & 3])
 
2003
                  *ptr++ ^= (0x0f & OnPixels[r0[3]]);
 
2004
                else
 
2005
                  *ptr++ ^= (0x0f & OffPixels[r0[3]]);
 
2006
              }
 
2007
              break;
 
2008
 
 
2009
          case 8 :
 
2010
              for (x = xsize  * 4; x > 0; x --, r0 ++, r1 ++)
 
2011
                if (*r0 == *r1)
 
2012
                  *ptr++ = *r0;
 
2013
                else
 
2014
                  *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize;
 
2015
              break;
 
2016
        }
 
2017
        break;
 
2018
 
 
2019
    case CUPS_ORDER_BANDED :
 
2020
        cptr = ptr;
 
2021
        mptr = ptr + bandwidth;
 
2022
        yptr = ptr + 2 * bandwidth;
 
2023
        kptr = ptr + 3 * bandwidth;
 
2024
 
 
2025
        switch (header->cupsBitsPerColor)
 
2026
        {
 
2027
          case 1 :
 
2028
              bitmask = 0x80 >> (bitoffset & 7);
 
2029
              dither  = Floyd16x16[y & 15];
 
2030
 
 
2031
              for (x = xsize; x > 0; x --)
 
2032
              {
 
2033
                pc = *r0++ > dither[x & 15];
 
2034
                pm = *r0++ > dither[x & 15];
 
2035
                py = *r0++ > dither[x & 15];
 
2036
 
 
2037
                if (pc && pm && py)
 
2038
                  *kptr ^= bitmask;
 
2039
                else
 
2040
                {
 
2041
                  if (pc)
 
2042
                    *cptr ^= bitmask;
 
2043
                  if (pm)
 
2044
                    *mptr ^= bitmask;
 
2045
                  if (py)
 
2046
                    *yptr ^= bitmask;
 
2047
                }
 
2048
 
 
2049
                if (bitmask > 1)
 
2050
                  bitmask >>= 1;
 
2051
                else
 
2052
                {
 
2053
                  bitmask = 0x80;
 
2054
                  cptr ++;
 
2055
                  mptr ++;
 
2056
                  yptr ++;
 
2057
                  kptr ++;
 
2058
                }
 
2059
              }
 
2060
              break;
 
2061
 
 
2062
          case 2 :
 
2063
              bitmask = 0xc0 >> (bitoffset & 7);
 
2064
              dither  = Floyd8x8[y & 7];
 
2065
 
 
2066
              for (x = xsize; x > 0; x --)
 
2067
              {
 
2068
                if ((*r0 & 63) > dither[x & 7])
 
2069
                  *cptr ^= (bitmask & OnPixels[*r0++]);
 
2070
                else
 
2071
                  *cptr ^= (bitmask & OffPixels[*r0++]);
 
2072
 
 
2073
                if ((*r0 & 63) > dither[x & 7])
 
2074
                  *mptr ^= (bitmask & OnPixels[*r0++]);
 
2075
                else
 
2076
                  *mptr ^= (bitmask & OffPixels[*r0++]);
 
2077
 
 
2078
                if ((*r0 & 63) > dither[x & 7])
 
2079
                  *yptr ^= (bitmask & OnPixels[*r0++]);
 
2080
                else
 
2081
                  *yptr ^= (bitmask & OffPixels[*r0++]);
 
2082
 
 
2083
                if ((*r0 & 63) > dither[x & 7])
 
2084
                  *kptr ^= (bitmask & OnPixels[*r0++]);
 
2085
                else
 
2086
                  *kptr ^= (bitmask & OffPixels[*r0++]);
 
2087
 
 
2088
                if (bitmask > 3)
 
2089
                  bitmask >>= 2;
 
2090
                else
 
2091
                {
 
2092
                  bitmask = 0xc0;
 
2093
 
 
2094
                  cptr ++;
 
2095
                  mptr ++;
 
2096
                  yptr ++;
 
2097
                  kptr ++;
 
2098
                }
 
2099
              }
 
2100
              break;
 
2101
 
 
2102
          case 4 :
 
2103
              bitmask = 0xf0 >> (bitoffset & 7);
 
2104
              dither  = Floyd4x4[y & 3];
 
2105
 
 
2106
              for (x = xsize; x > 0; x --)
 
2107
              {
 
2108
                if ((*r0 & 15) > dither[x & 3])
 
2109
                  *cptr ^= (bitmask & OnPixels[*r0++]);
 
2110
                else
 
2111
                  *cptr ^= (bitmask & OffPixels[*r0++]);
 
2112
 
 
2113
                if ((*r0 & 15) > dither[x & 3])
 
2114
                  *mptr ^= (bitmask & OnPixels[*r0++]);
 
2115
                else
 
2116
                  *mptr ^= (bitmask & OffPixels[*r0++]);
 
2117
 
 
2118
                if ((*r0 & 15) > dither[x & 3])
 
2119
                  *yptr ^= (bitmask & OnPixels[*r0++]);
 
2120
                else
 
2121
                  *yptr ^= (bitmask & OffPixels[*r0++]);
 
2122
 
 
2123
                if ((*r0 & 15) > dither[x & 3])
 
2124
                  *kptr ^= (bitmask & OnPixels[*r0++]);
 
2125
                else
 
2126
                  *kptr ^= (bitmask & OffPixels[*r0++]);
 
2127
 
 
2128
                if (bitmask == 0xf0)
 
2129
                  bitmask = 0x0f;
 
2130
                else
 
2131
                {
 
2132
                  bitmask = 0xf0;
 
2133
 
 
2134
                  cptr ++;
 
2135
                  mptr ++;
 
2136
                  yptr ++;
 
2137
                  kptr ++;
 
2138
                }
 
2139
              }
 
2140
              break;
 
2141
 
 
2142
          case 8 :
 
2143
              for (x = xsize; x > 0; x --, r0 += 4, r1 += 4)
 
2144
              {
 
2145
                if (r0[0] == r1[0])
 
2146
                  *cptr++ = r0[0];
 
2147
                else
 
2148
                  *cptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize;
 
2149
 
 
2150
                if (r0[1] == r1[1])
 
2151
                  *mptr++ = r0[1];
 
2152
                else
 
2153
                  *mptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize;
 
2154
 
 
2155
                if (r0[2] == r1[2])
 
2156
                  *yptr++ = r0[2];
 
2157
                else
 
2158
                  *yptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize;
 
2159
 
 
2160
                if (r0[3] == r1[3])
 
2161
                  *kptr++ = r0[3];
 
2162
                else
 
2163
                  *kptr++ = (r0[3] * yerr0 + r1[3] * yerr1) / ysize;
 
2164
              }
 
2165
              break;
 
2166
        }
 
2167
        break;
 
2168
 
 
2169
    case CUPS_ORDER_PLANAR :
 
2170
        switch (header->cupsBitsPerColor)
 
2171
        {
 
2172
          case 1 :
 
2173
              bitmask = 0x80 >> (bitoffset & 7);
 
2174
              dither  = Floyd16x16[y & 15];
 
2175
 
 
2176
              for (x = xsize; x > 0; x --)
 
2177
              {
 
2178
                pc = *r0++ > dither[x & 15];
 
2179
                pm = *r0++ > dither[x & 15];
 
2180
                py = *r0++ > dither[x & 15];
 
2181
 
 
2182
                if ((pc && pm && py && z == 3) ||
 
2183
                    (pc && z == 0) || (pm && z == 1) || (py && z == 2))
 
2184
                  *ptr ^= bitmask;
 
2185
 
 
2186
                if (bitmask > 1)
 
2187
                  bitmask >>= 1;
 
2188
                else
 
2189
                {
 
2190
                  bitmask = 0x80;
 
2191
                  ptr ++;
 
2192
                }
 
2193
              }
 
2194
              break;
 
2195
 
 
2196
          case 2 :
 
2197
              bitmask = 0xc0 >> (bitoffset & 7);
 
2198
              dither  = Floyd8x8[y & 7];
 
2199
              r0      += z;
 
2200
 
 
2201
              for (x = xsize; x > 0; x --, r0 += 4)
 
2202
              {
 
2203
                if ((*r0 & 63) > dither[x & 7])
 
2204
                  *ptr ^= (bitmask & OnPixels[*r0]);
 
2205
                else
 
2206
                  *ptr ^= (bitmask & OffPixels[*r0]);
 
2207
 
 
2208
                if (bitmask > 3)
 
2209
                  bitmask >>= 2;
 
2210
                else
 
2211
                {
 
2212
                  bitmask = 0xc0;
 
2213
 
 
2214
                  ptr ++;
 
2215
                }
 
2216
              }
 
2217
              break;
 
2218
 
 
2219
          case 4 :
 
2220
              bitmask = 0xf0 >> (bitoffset & 7);
 
2221
              dither  = Floyd4x4[y & 3];
 
2222
              r0 += z;
 
2223
 
 
2224
              for (x = xsize; x > 0; x --, r0 += 4)
 
2225
              {
 
2226
                if ((*r0 & 15) > dither[x & 3])
 
2227
                  *ptr ^= (bitmask & OnPixels[*r0]);
 
2228
                else
 
2229
                  *ptr ^= (bitmask & OffPixels[*r0]);
 
2230
 
 
2231
                if (bitmask == 0xf0)
 
2232
                  bitmask = 0x0f;
 
2233
                else
 
2234
                {
 
2235
                  bitmask = 0xf0;
 
2236
 
 
2237
                  ptr ++;
 
2238
                }
 
2239
              }
 
2240
              break;
 
2241
 
 
2242
          case 8 :
 
2243
              r0 += z;
 
2244
              r1 += z;
 
2245
 
 
2246
              for (x = xsize; x > 0; x --, r0 += 4, r1 += 4)
 
2247
              {
 
2248
                if (*r0 == *r1)
 
2249
                  *ptr++ = *r0;
 
2250
                else
 
2251
                  *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize;
 
2252
              }
 
2253
              break;
 
2254
        }
 
2255
        break;
 
2256
  }
 
2257
}
 
2258
 
 
2259
 
 
2260
/*
 
2261
 * 'format_K()' - Convert image data to black.
 
2262
 */
 
2263
 
 
2264
static void
 
2265
format_K(cups_page_header2_t *header,   /* I - Page header */
 
2266
         unsigned char       *row,      /* IO - Bitmap data for device */
 
2267
         int                 y,         /* I - Current row */
 
2268
         int                 z,         /* I - Current plane */
 
2269
         int                 xsize,     /* I - Width of image data */
 
2270
         int                 ysize,     /* I - Height of image data */
 
2271
         int                 yerr0,     /* I - Top Y error */
 
2272
         int                 yerr1,     /* I - Bottom Y error */
 
2273
         cups_ib_t           *r0,       /* I - Primary image data */
 
2274
         cups_ib_t           *r1)       /* I - Image data for interpolation */
 
2275
{
 
2276
  cups_ib_t     *ptr,                   /* Pointer into row */
 
2277
                bitmask;                /* Current mask for pixel */
 
2278
  int           bitoffset;              /* Current offset in line */
 
2279
  int           x,                      /* Current X coordinate on page */
 
2280
                *dither;                /* Pointer into dither array */
 
2281
 
 
2282
 
 
2283
  (void)z;
 
2284
 
 
2285
  switch (XPosition)
 
2286
  {
 
2287
    case -1 :
 
2288
        bitoffset = 0;
 
2289
        break;
 
2290
    default :
 
2291
        bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2);
 
2292
        break;
 
2293
    case 1 :
 
2294
        bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize);
 
2295
        break;
 
2296
  }
 
2297
 
 
2298
  ptr = row + bitoffset / 8;
 
2299
 
 
2300
  switch (header->cupsBitsPerColor)
 
2301
  {
 
2302
    case 1 :
 
2303
        bitmask = 0x80 >> (bitoffset & 7);
 
2304
        dither  = Floyd16x16[y & 15];
 
2305
 
 
2306
        for (x = xsize; x > 0; x --)
 
2307
        {
 
2308
          if (*r0++ > dither[x & 15])
 
2309
            *ptr ^= bitmask;
 
2310
 
 
2311
          if (bitmask > 1)
 
2312
            bitmask >>= 1;
 
2313
          else
 
2314
          {
 
2315
            bitmask = 0x80;
 
2316
            ptr ++;
 
2317
          }
 
2318
        }
 
2319
        break;
 
2320
 
 
2321
    case 2 :
 
2322
        bitmask = 0xc0 >> (bitoffset & 7);
 
2323
        dither  = Floyd8x8[y & 7];
 
2324
 
 
2325
        for (x = xsize; x > 0; x --)
 
2326
        {
 
2327
          if ((*r0 & 63) > dither[x & 7])
 
2328
            *ptr ^= (bitmask & OnPixels[*r0++]);
 
2329
          else
 
2330
            *ptr ^= (bitmask & OffPixels[*r0++]);
 
2331
 
 
2332
          if (bitmask > 3)
 
2333
            bitmask >>= 2;
 
2334
          else
 
2335
          {
 
2336
            bitmask = 0xc0;
 
2337
 
 
2338
            ptr ++;
 
2339
          }
 
2340
        }
 
2341
        break;
 
2342
 
 
2343
    case 4 :
 
2344
        bitmask = 0xf0 >> (bitoffset & 7);
 
2345
        dither  = Floyd4x4[y & 3];
 
2346
 
 
2347
        for (x = xsize; x > 0; x --)
 
2348
        {
 
2349
          if ((*r0 & 15) > dither[x & 3])
 
2350
            *ptr ^= (bitmask & OnPixels[*r0++]);
 
2351
          else
 
2352
            *ptr ^= (bitmask & OffPixels[*r0++]);
 
2353
 
 
2354
          if (bitmask == 0xf0)
 
2355
            bitmask = 0x0f;
 
2356
          else
 
2357
          {
 
2358
            bitmask = 0xf0;
 
2359
 
 
2360
            ptr ++;
 
2361
          }
 
2362
        }
 
2363
        break;
 
2364
 
 
2365
    case 8 :
 
2366
        for (x = xsize; x > 0; x --, r0 ++, r1 ++)
 
2367
        {
 
2368
          if (*r0 == *r1)
 
2369
            *ptr++ = *r0;
 
2370
          else
 
2371
            *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize;
 
2372
        }
 
2373
        break;
 
2374
  }
 
2375
}
 
2376
 
 
2377
 
 
2378
/*
 
2379
 * 'format_KCMY()' - Convert image data to KCMY.
 
2380
 */
 
2381
 
 
2382
static void
 
2383
format_KCMY(cups_page_header2_t *header,/* I - Page header */
 
2384
            unsigned char       *row,   /* IO - Bitmap data for device */
 
2385
            int                 y,      /* I - Current row */
 
2386
            int                 z,      /* I - Current plane */
 
2387
            int                 xsize,  /* I - Width of image data */
 
2388
            int                 ysize,  /* I - Height of image data */
 
2389
            int                 yerr0,  /* I - Top Y error */
 
2390
            int                 yerr1,  /* I - Bottom Y error */
 
2391
            cups_ib_t           *r0,    /* I - Primary image data */
 
2392
            cups_ib_t           *r1)    /* I - Image data for interpolation */
 
2393
{
 
2394
  cups_ib_t     *ptr,                   /* Pointer into row */
 
2395
                *cptr,                  /* Pointer into cyan */
 
2396
                *mptr,                  /* Pointer into magenta */
 
2397
                *yptr,                  /* Pointer into yellow */
 
2398
                *kptr,                  /* Pointer into black */
 
2399
                bitmask;                /* Current mask for pixel */
 
2400
  int           bitoffset;              /* Current offset in line */
 
2401
  int           bandwidth;              /* Width of a color band */
 
2402
  int           x,                      /* Current X coordinate on page */
 
2403
                *dither;                /* Pointer into dither array */
 
2404
  int           pc, pm, py;             /* CMY pixels */
 
2405
 
 
2406
 
 
2407
  switch (XPosition)
 
2408
  {
 
2409
    case -1 :
 
2410
        bitoffset = 0;
 
2411
        break;
 
2412
    default :
 
2413
        bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2);
 
2414
        break;
 
2415
    case 1 :
 
2416
        bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize);
 
2417
        break;
 
2418
  }
 
2419
 
 
2420
  ptr       = row + bitoffset / 8;
 
2421
  bandwidth = header->cupsBytesPerLine / 4;
 
2422
 
 
2423
  switch (header->cupsColorOrder)
 
2424
  {
 
2425
    case CUPS_ORDER_CHUNKED :
 
2426
        switch (header->cupsBitsPerColor)
 
2427
        {
 
2428
          case 1 :
 
2429
              bitmask = 128 >> (bitoffset & 7);
 
2430
              dither  = Floyd16x16[y & 15];
 
2431
 
 
2432
              for (x = xsize ; x > 0; x --)
 
2433
              {
 
2434
                pc = *r0++ > dither[x & 15];
 
2435
                pm = *r0++ > dither[x & 15];
 
2436
                py = *r0++ > dither[x & 15];
 
2437
 
 
2438
                if (pc && pm && py)
 
2439
                {
 
2440
                  *ptr ^= bitmask;
 
2441
                  bitmask >>= 3;
 
2442
                }
 
2443
                else
 
2444
                {
 
2445
                  bitmask >>= 1;
 
2446
                  if (pc)
 
2447
                    *ptr ^= bitmask;
 
2448
 
 
2449
                  bitmask >>= 1;
 
2450
                  if (pm)
 
2451
                    *ptr ^= bitmask;
 
2452
 
 
2453
                  bitmask >>= 1;
 
2454
                  if (py)
 
2455
                    *ptr ^= bitmask;
 
2456
                }
 
2457
 
 
2458
                if (bitmask > 1)
 
2459
                  bitmask >>= 1;
 
2460
                else
 
2461
                {
 
2462
                  bitmask = 128;
 
2463
                  ptr ++;
 
2464
                }
 
2465
              }
 
2466
              break;
 
2467
 
 
2468
          case 2 :
 
2469
              dither = Floyd8x8[y & 7];
 
2470
 
 
2471
              for (x = xsize ; x > 0; x --, r0 += 4)
 
2472
              {
 
2473
                if ((r0[3] & 63) > dither[x & 7])
 
2474
                  *ptr ^= (0xc0 & OnPixels[r0[3]]);
 
2475
                else
 
2476
                  *ptr ^= (0xc0 & OffPixels[r0[3]]);
 
2477
 
 
2478
                if ((r0[0] & 63) > dither[x & 7])
 
2479
                  *ptr ^= (0x30 & OnPixels[r0[0]]);
 
2480
                else
 
2481
                  *ptr ^= (0x30 & OffPixels[r0[0]]);
 
2482
 
 
2483
                if ((r0[1] & 63) > dither[x & 7])
 
2484
                  *ptr ^= (0x0c & OnPixels[r0[1]]);
 
2485
                else
 
2486
                  *ptr ^= (0x0c & OffPixels[r0[1]]);
 
2487
 
 
2488
                if ((r0[2] & 63) > dither[x & 7])
 
2489
                  *ptr++ ^= (0x03 & OnPixels[r0[2]]);
 
2490
                else
 
2491
                  *ptr++ ^= (0x03 & OffPixels[r0[2]]);
 
2492
              }
 
2493
              break;
 
2494
 
 
2495
          case 4 :
 
2496
              dither = Floyd4x4[y & 3];
 
2497
 
 
2498
              for (x = xsize ; x > 0; x --, r0 += 4)
 
2499
              {
 
2500
                if ((r0[3] & 15) > dither[x & 3])
 
2501
                  *ptr ^= (0xf0 & OnPixels[r0[3]]);
 
2502
                else
 
2503
                  *ptr ^= (0xf0 & OffPixels[r0[3]]);
 
2504
 
 
2505
                if ((r0[0] & 15) > dither[x & 3])
 
2506
                  *ptr++ ^= (0x0f & OnPixels[r0[0]]);
 
2507
                else
 
2508
                  *ptr++ ^= (0x0f & OffPixels[r0[0]]);
 
2509
 
 
2510
                if ((r0[1] & 15) > dither[x & 3])
 
2511
                  *ptr ^= (0xf0 & OnPixels[r0[1]]);
 
2512
                else
 
2513
                  *ptr ^= (0xf0 & OffPixels[r0[1]]);
 
2514
 
 
2515
                if ((r0[2] & 15) > dither[x & 3])
 
2516
                  *ptr++ ^= (0x0f & OnPixels[r0[2]]);
 
2517
                else
 
2518
                  *ptr++ ^= (0x0f & OffPixels[r0[2]]);
 
2519
              }
 
2520
              break;
 
2521
 
 
2522
          case 8 :
 
2523
              for (x = xsize; x > 0; x --, r0 += 4, r1 += 4)
 
2524
              {
 
2525
                if (r0[3] == r1[3])
 
2526
                  *ptr++ = r0[3];
 
2527
                else
 
2528
                  *ptr++ = (r0[3] * yerr0 + r1[3] * yerr1) / ysize;
 
2529
 
 
2530
                if (r0[0] == r1[0])
 
2531
                  *ptr++ = r0[0];
 
2532
                else
 
2533
                  *ptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize;
 
2534
 
 
2535
                if (r0[1] == r1[1])
 
2536
                  *ptr++ = r0[1];
 
2537
                else
 
2538
                  *ptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize;
 
2539
 
 
2540
                if (r0[2] == r1[2])
 
2541
                  *ptr++ = r0[2];
 
2542
                else
 
2543
                  *ptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize;
 
2544
              }
 
2545
              break;
 
2546
        }
 
2547
        break;
 
2548
 
 
2549
    case CUPS_ORDER_BANDED :
 
2550
        kptr = ptr;
 
2551
        cptr = ptr + bandwidth;
 
2552
        mptr = ptr + 2 * bandwidth;
 
2553
        yptr = ptr + 3 * bandwidth;
 
2554
 
 
2555
        switch (header->cupsBitsPerColor)
 
2556
        {
 
2557
          case 1 :
 
2558
              bitmask = 0x80 >> (bitoffset & 7);
 
2559
              dither  = Floyd16x16[y & 15];
 
2560
 
 
2561
              for (x = xsize; x > 0; x --)
 
2562
              {
 
2563
                pc = *r0++ > dither[x & 15];
 
2564
                pm = *r0++ > dither[x & 15];
 
2565
                py = *r0++ > dither[x & 15];
 
2566
 
 
2567
                if (pc && pm && py)
 
2568
                  *kptr ^= bitmask;
 
2569
                else
 
2570
                {
 
2571
                  if (pc)
 
2572
                    *cptr ^= bitmask;
 
2573
                  if (pm)
 
2574
                    *mptr ^= bitmask;
 
2575
                  if (py)
 
2576
                    *yptr ^= bitmask;
 
2577
                }
 
2578
 
 
2579
                if (bitmask > 1)
 
2580
                  bitmask >>= 1;
 
2581
                else
 
2582
                {
 
2583
                  bitmask = 0x80;
 
2584
                  cptr ++;
 
2585
                  mptr ++;
 
2586
                  yptr ++;
 
2587
                  kptr ++;
 
2588
                }
 
2589
              }
 
2590
              break;
 
2591
 
 
2592
          case 2 :
 
2593
              bitmask = 0xc0 >> (bitoffset & 7);
 
2594
              dither  = Floyd8x8[y & 7];
 
2595
 
 
2596
              for (x = xsize; x > 0; x --)
 
2597
              {
 
2598
                if ((*r0 & 63) > dither[x & 7])
 
2599
                  *cptr ^= (bitmask & OnPixels[*r0++]);
 
2600
                else
 
2601
                  *cptr ^= (bitmask & OffPixels[*r0++]);
 
2602
 
 
2603
                if ((*r0 & 63) > dither[x & 7])
 
2604
                  *mptr ^= (bitmask & OnPixels[*r0++]);
 
2605
                else
 
2606
                  *mptr ^= (bitmask & OffPixels[*r0++]);
 
2607
 
 
2608
                if ((*r0 & 63) > dither[x & 7])
 
2609
                  *yptr ^= (bitmask & OnPixels[*r0++]);
 
2610
                else
 
2611
                  *yptr ^= (bitmask & OffPixels[*r0++]);
 
2612
 
 
2613
                if ((*r0 & 63) > dither[x & 7])
 
2614
                  *kptr ^= (bitmask & OnPixels[*r0++]);
 
2615
                else
 
2616
                  *kptr ^= (bitmask & OffPixels[*r0++]);
 
2617
 
 
2618
                if (bitmask > 3)
 
2619
                  bitmask >>= 2;
 
2620
                else
 
2621
                {
 
2622
                  bitmask = 0xc0;
 
2623
 
 
2624
                  cptr ++;
 
2625
                  mptr ++;
 
2626
                  yptr ++;
 
2627
                  kptr ++;
 
2628
                }
 
2629
              }
 
2630
              break;
 
2631
 
 
2632
          case 4 :
 
2633
              bitmask = 0xf0 >> (bitoffset & 7);
 
2634
              dither  = Floyd4x4[y & 3];
 
2635
 
 
2636
              for (x = xsize; x > 0; x --)
 
2637
              {
 
2638
                if ((*r0 & 15) > dither[x & 3])
 
2639
                  *cptr ^= (bitmask & OnPixels[*r0++]);
 
2640
                else
 
2641
                  *cptr ^= (bitmask & OffPixels[*r0++]);
 
2642
 
 
2643
                if ((*r0 & 15) > dither[x & 3])
 
2644
                  *mptr ^= (bitmask & OnPixels[*r0++]);
 
2645
                else
 
2646
                  *mptr ^= (bitmask & OffPixels[*r0++]);
 
2647
 
 
2648
                if ((*r0 & 15) > dither[x & 3])
 
2649
                  *yptr ^= (bitmask & OnPixels[*r0++]);
 
2650
                else
 
2651
                  *yptr ^= (bitmask & OffPixels[*r0++]);
 
2652
 
 
2653
                if ((*r0 & 15) > dither[x & 3])
 
2654
                  *kptr ^= (bitmask & OnPixels[*r0++]);
 
2655
                else
 
2656
                  *kptr ^= (bitmask & OffPixels[*r0++]);
 
2657
 
 
2658
                if (bitmask == 0xf0)
 
2659
                  bitmask = 0x0f;
 
2660
                else
 
2661
                {
 
2662
                  bitmask = 0xf0;
 
2663
 
 
2664
                  cptr ++;
 
2665
                  mptr ++;
 
2666
                  yptr ++;
 
2667
                  kptr ++;
 
2668
                }
 
2669
              }
 
2670
              break;
 
2671
 
 
2672
          case 8 :
 
2673
              for (x = xsize; x > 0; x --, r0 += 4, r1 += 4)
 
2674
              {
 
2675
                if (r0[0] == r1[0])
 
2676
                  *cptr++ = r0[0];
 
2677
                else
 
2678
                  *cptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize;
 
2679
 
 
2680
                if (r0[1] == r1[1])
 
2681
                  *mptr++ = r0[1];
 
2682
                else
 
2683
                  *mptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize;
 
2684
 
 
2685
                if (r0[2] == r1[2])
 
2686
                  *yptr++ = r0[2];
 
2687
                else
 
2688
                  *yptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize;
 
2689
 
 
2690
                if (r0[3] == r1[3])
 
2691
                  *kptr++ = r0[3];
 
2692
                else
 
2693
                  *kptr++ = (r0[3] * yerr0 + r1[3] * yerr1) / ysize;
 
2694
              }
 
2695
              break;
 
2696
        }
 
2697
        break;
 
2698
 
 
2699
    case CUPS_ORDER_PLANAR :
 
2700
        switch (header->cupsBitsPerColor)
 
2701
        {
 
2702
          case 1 :
 
2703
              bitmask = 0x80 >> (bitoffset & 7);
 
2704
              dither  = Floyd16x16[y & 15];
 
2705
 
 
2706
              for (x = xsize; x > 0; x --)
 
2707
              {
 
2708
                pc = *r0++ > dither[x & 15];
 
2709
                pm = *r0++ > dither[x & 15];
 
2710
                py = *r0++ > dither[x & 15];
 
2711
 
 
2712
                if ((pc && pm && py && z == 0) ||
 
2713
                    (pc && z == 1) || (pm && z == 2) || (py && z == 3))
 
2714
                  *ptr ^= bitmask;
 
2715
 
 
2716
                if (bitmask > 1)
 
2717
                  bitmask >>= 1;
 
2718
                else
 
2719
                {
 
2720
                  bitmask = 0x80;
 
2721
                  ptr ++;
 
2722
                }
 
2723
              }
 
2724
              break;
 
2725
 
 
2726
          case 2 :
 
2727
              bitmask = 0xc0 >> (bitoffset & 7);
 
2728
              dither  = Floyd8x8[y & 7];
 
2729
              if (z == 0)
 
2730
                r0 += 3;
 
2731
              else
 
2732
                r0 += z - 1;
 
2733
 
 
2734
              for (x = xsize; x > 0; x --, r0 += 4)
 
2735
              {
 
2736
                if ((*r0 & 63) > dither[x & 7])
 
2737
                  *ptr ^= (bitmask & OnPixels[*r0]);
 
2738
                else
 
2739
                  *ptr ^= (bitmask & OffPixels[*r0]);
 
2740
 
 
2741
                if (bitmask > 3)
 
2742
                  bitmask >>= 2;
 
2743
                else
 
2744
                {
 
2745
                  bitmask = 0xc0;
 
2746
 
 
2747
                  ptr ++;
 
2748
                }
 
2749
              }
 
2750
              break;
 
2751
 
 
2752
          case 4 :
 
2753
              bitmask = 0xf0 >> (bitoffset & 7);
 
2754
              dither  = Floyd4x4[y & 3];
 
2755
              if (z == 0)
 
2756
                r0 += 3;
 
2757
              else
 
2758
                r0 += z - 1;
 
2759
 
 
2760
              for (x = xsize; x > 0; x --, r0 += 4)
 
2761
              {
 
2762
                if ((*r0 & 15) > dither[x & 3])
 
2763
                  *ptr ^= (bitmask & OnPixels[*r0]);
 
2764
                else
 
2765
                  *ptr ^= (bitmask & OffPixels[*r0]);
 
2766
 
 
2767
                if (bitmask == 0xf0)
 
2768
                  bitmask = 0x0f;
 
2769
                else
 
2770
                {
 
2771
                  bitmask = 0xf0;
 
2772
 
 
2773
                  ptr ++;
 
2774
                }
 
2775
              }
 
2776
              break;
 
2777
 
 
2778
          case 8 :
 
2779
              if (z == 0)
 
2780
              {
 
2781
                r0 += 3;
 
2782
                r1 += 3;
 
2783
              }
 
2784
              else
 
2785
              {
 
2786
                r0 += z - 1;
 
2787
                r1 += z - 1;
 
2788
              }
 
2789
 
 
2790
              for (x = xsize; x > 0; x --, r0 += 4, r1 += 4)
 
2791
              {
 
2792
                if (*r0 == *r1)
 
2793
                  *ptr++ = *r0;
 
2794
                else
 
2795
                  *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize;
 
2796
              }
 
2797
              break;
 
2798
        }
 
2799
        break;
 
2800
  }
 
2801
}
 
2802
 
 
2803
 
 
2804
/*
 
2805
 * 'format_KCMYcm()' - Convert image data to KCMYcm.
 
2806
 */
 
2807
 
 
2808
static void
 
2809
format_KCMYcm(
 
2810
    cups_page_header2_t *header,        /* I - Page header */
 
2811
    unsigned char       *row,           /* IO - Bitmap data for device */
 
2812
    int                 y,              /* I - Current row */
 
2813
    int                 z,              /* I - Current plane */
 
2814
    int                 xsize,          /* I - Width of image data */
 
2815
    int                 ysize,          /* I - Height of image data */
 
2816
    int                 yerr0,          /* I - Top Y error */
 
2817
    int                 yerr1,          /* I - Bottom Y error */
 
2818
    cups_ib_t           *r0,            /* I - Primary image data */
 
2819
    cups_ib_t           *r1)            /* I - Image data for interpolation */
 
2820
{
 
2821
  int           pc, pm, py, pk;         /* Cyan, magenta, yellow, and black values */
 
2822
  cups_ib_t     *ptr,                   /* Pointer into row */
 
2823
                *cptr,                  /* Pointer into cyan */
 
2824
                *mptr,                  /* Pointer into magenta */
 
2825
                *yptr,                  /* Pointer into yellow */
 
2826
                *kptr,                  /* Pointer into black */
 
2827
                *lcptr,                 /* Pointer into light cyan */
 
2828
                *lmptr,                 /* Pointer into light magenta */
 
2829
                bitmask;                /* Current mask for pixel */
 
2830
  int           bitoffset;              /* Current offset in line */
 
2831
  int           bandwidth;              /* Width of a color band */
 
2832
  int           x,                      /* Current X coordinate on page */
 
2833
                *dither;                /* Pointer into dither array */
 
2834
 
 
2835
 
 
2836
  switch (XPosition)
 
2837
  {
 
2838
    case -1 :
 
2839
        bitoffset = 0;
 
2840
        break;
 
2841
    default :
 
2842
        bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2);
 
2843
        break;
 
2844
    case 1 :
 
2845
        bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize);
 
2846
        break;
 
2847
  }
 
2848
 
 
2849
  ptr       = row + bitoffset / 8;
 
2850
  bandwidth = header->cupsBytesPerLine / 6;
 
2851
 
 
2852
  switch (header->cupsColorOrder)
 
2853
  {
 
2854
    case CUPS_ORDER_CHUNKED :
 
2855
        dither = Floyd16x16[y & 15];
 
2856
 
 
2857
        for (x = xsize ; x > 0; x --)
 
2858
        {
 
2859
          pc = *r0++ > dither[x & 15];
 
2860
          pm = *r0++ > dither[x & 15];
 
2861
          py = *r0++ > dither[x & 15];
 
2862
          pk = pc && pm && py;
 
2863
 
 
2864
          if (pk)
 
2865
            *ptr++ ^= 32;       /* Black */
 
2866
          else if (pc && pm)
 
2867
            *ptr++ ^= 17;       /* Blue (cyan + light magenta) */
 
2868
          else if (pc && py)
 
2869
            *ptr++ ^= 6;        /* Green (light cyan + yellow) */
 
2870
          else if (pm && py)
 
2871
            *ptr++ ^= 12;       /* Red (magenta + yellow) */
 
2872
          else if (pc)
 
2873
            *ptr++ ^= 16;
 
2874
          else if (pm)
 
2875
            *ptr++ ^= 8;
 
2876
          else if (py)
 
2877
            *ptr++ ^= 4;
 
2878
          else
 
2879
            ptr ++;
 
2880
        }
 
2881
        break;
 
2882
 
 
2883
    case CUPS_ORDER_BANDED :
 
2884
        kptr  = ptr;
 
2885
        cptr  = ptr + bandwidth;
 
2886
        mptr  = ptr + 2 * bandwidth;
 
2887
        yptr  = ptr + 3 * bandwidth;
 
2888
        lcptr = ptr + 4 * bandwidth;
 
2889
        lmptr = ptr + 5 * bandwidth;
 
2890
 
 
2891
        bitmask = 0x80 >> (bitoffset & 7);
 
2892
        dither  = Floyd16x16[y & 15];
 
2893
 
 
2894
        for (x = xsize; x > 0; x --)
 
2895
        {
 
2896
          pc = *r0++ > dither[x & 15];
 
2897
          pm = *r0++ > dither[x & 15];
 
2898
          py = *r0++ > dither[x & 15];
 
2899
          pk = pc && pm && py;
 
2900
 
 
2901
          if (pk)
 
2902
            *kptr ^= bitmask;   /* Black */
 
2903
          else if (pc && pm)
 
2904
          {
 
2905
            *cptr ^= bitmask;   /* Blue (cyan + light magenta) */
 
2906
            *lmptr ^= bitmask;
 
2907
          }
 
2908
          else if (pc && py)
 
2909
          {
 
2910
            *lcptr ^= bitmask;  /* Green (light cyan + yellow) */
 
2911
            *yptr  ^= bitmask;
 
2912
          }
 
2913
          else if (pm && py)
 
2914
          {
 
2915
            *mptr ^= bitmask;   /* Red (magenta + yellow) */
 
2916
            *yptr ^= bitmask;
 
2917
          }
 
2918
          else if (pc)
 
2919
            *cptr ^= bitmask;
 
2920
          else if (pm)
 
2921
            *mptr ^= bitmask;
 
2922
          else if (py)
 
2923
            *yptr ^= bitmask;
 
2924
 
 
2925
          if (bitmask > 1)
 
2926
            bitmask >>= 1;
 
2927
          else
 
2928
          {
 
2929
            bitmask = 0x80;
 
2930
            cptr ++;
 
2931
            mptr ++;
 
2932
            yptr ++;
 
2933
            kptr ++;
 
2934
            lcptr ++;
 
2935
            lmptr ++;
 
2936
          }
 
2937
        }
 
2938
        break;
 
2939
 
 
2940
    case CUPS_ORDER_PLANAR :
 
2941
        bitmask = 0x80 >> (bitoffset & 7);
 
2942
        dither  = Floyd16x16[y & 15];
 
2943
 
 
2944
        for (x = xsize; x > 0; x --)
 
2945
        {
 
2946
          pc = *r0++ > dither[x & 15];
 
2947
          pm = *r0++ > dither[x & 15];
 
2948
          py = *r0++ > dither[x & 15];
 
2949
          pk = pc && pm && py;
 
2950
 
 
2951
          if (pk && z == 0)
 
2952
            *ptr ^= bitmask;
 
2953
          else if (pc && pm && (z == 1 || z == 5))
 
2954
            *ptr ^= bitmask;    /* Blue (cyan + light magenta) */
 
2955
          else if (pc && py && (z == 3 || z == 4))
 
2956
            *ptr ^= bitmask;    /* Green (light cyan + yellow) */
 
2957
          else if (pm && py && (z == 2 || z == 3))
 
2958
            *ptr ^= bitmask;    /* Red (magenta + yellow) */
 
2959
          else if (pc && z == 1)
 
2960
            *ptr ^= bitmask;
 
2961
          else if (pm && z == 2)
 
2962
            *ptr ^= bitmask;
 
2963
          else if (py && z == 3)
 
2964
            *ptr ^= bitmask;
 
2965
 
 
2966
          if (bitmask > 1)
 
2967
            bitmask >>= 1;
 
2968
          else
 
2969
          {
 
2970
            bitmask = 0x80;
 
2971
            ptr ++;
 
2972
          }
 
2973
        }
 
2974
        break;
 
2975
  }
 
2976
}
 
2977
 
 
2978
 
 
2979
/*
 
2980
 * 'format_RGBA()' - Convert image data to RGBA/RGBW.
 
2981
 */
 
2982
 
 
2983
static void
 
2984
format_RGBA(cups_page_header2_t *header,/* I - Page header */
 
2985
            unsigned char       *row,   /* IO - Bitmap data for device */
 
2986
            int                 y,      /* I - Current row */
 
2987
            int                 z,      /* I - Current plane */
 
2988
            int                 xsize,  /* I - Width of image data */
 
2989
            int                 ysize,  /* I - Height of image data */
 
2990
            int                 yerr0,  /* I - Top Y error */
 
2991
            int                 yerr1,  /* I - Bottom Y error */
 
2992
            cups_ib_t           *r0,    /* I - Primary image data */
 
2993
            cups_ib_t           *r1)    /* I - Image data for interpolation */
 
2994
{
 
2995
  cups_ib_t     *ptr,                   /* Pointer into row */
 
2996
                *cptr,                  /* Pointer into cyan */
 
2997
                *mptr,                  /* Pointer into magenta */
 
2998
                *yptr,                  /* Pointer into yellow */
 
2999
                bitmask;                /* Current mask for pixel */
 
3000
  int           bitoffset;              /* Current offset in line */
 
3001
  int           bandwidth;              /* Width of a color band */
 
3002
  int           x,                      /* Current X coordinate on page */
 
3003
                *dither;                /* Pointer into dither array */
 
3004
 
 
3005
 
 
3006
  switch (XPosition)
 
3007
  {
 
3008
    case -1 :
 
3009
        bitoffset = 0;
 
3010
        break;
 
3011
    default :
 
3012
        bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2);
 
3013
        break;
 
3014
    case 1 :
 
3015
        bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize);
 
3016
        break;
 
3017
  }
 
3018
 
 
3019
  ptr       = row + bitoffset / 8;
 
3020
  bandwidth = header->cupsBytesPerLine / 4;
 
3021
 
 
3022
  switch (header->cupsColorOrder)
 
3023
  {
 
3024
    case CUPS_ORDER_CHUNKED :
 
3025
        switch (header->cupsBitsPerColor)
 
3026
        {
 
3027
          case 1 :
 
3028
              bitmask = 128 >> (bitoffset & 7);
 
3029
              dither  = Floyd16x16[y & 15];
 
3030
 
 
3031
              for (x = xsize ; x > 0; x --)
 
3032
              {
 
3033
                if (*r0++ > dither[x & 15])
 
3034
                  *ptr ^= bitmask;
 
3035
                bitmask >>= 1;
 
3036
 
 
3037
                if (*r0++ > dither[x & 15])
 
3038
                  *ptr ^= bitmask;
 
3039
                bitmask >>= 1;
 
3040
 
 
3041
                if (*r0++ > dither[x & 15])
 
3042
                  *ptr ^= bitmask;
 
3043
 
 
3044
                if (bitmask > 2)
 
3045
                  bitmask >>= 2;
 
3046
                else
 
3047
                {
 
3048
                  bitmask = 128;
 
3049
                  ptr ++;
 
3050
                }
 
3051
              }
 
3052
              break;
 
3053
 
 
3054
          case 2 :
 
3055
              dither = Floyd8x8[y & 7];
 
3056
 
 
3057
              for (x = xsize ; x > 0; x --, r0 += 3)
 
3058
              {
 
3059
                if ((r0[0] & 63) > dither[x & 7])
 
3060
                  *ptr ^= (0xc0 & OnPixels[r0[0]]);
 
3061
                else
 
3062
                  *ptr ^= (0xc0 & OffPixels[r0[0]]);
 
3063
 
 
3064
                if ((r0[1] & 63) > dither[x & 7])
 
3065
                  *ptr ^= (0x30 & OnPixels[r0[1]]);
 
3066
                else
 
3067
                  *ptr ^= (0x30 & OffPixels[r0[1]]);
 
3068
 
 
3069
                if ((r0[2] & 63) > dither[x & 7])
 
3070
                  *ptr ^= (0x0c & OnPixels[r0[2]]);
 
3071
                else
 
3072
                  *ptr ^= (0x0c & OffPixels[r0[2]]);
 
3073
 
 
3074
                ptr ++;
 
3075
              }
 
3076
              break;
 
3077
 
 
3078
          case 4 :
 
3079
              dither = Floyd4x4[y & 3];
 
3080
 
 
3081
              for (x = xsize ; x > 0; x --, r0 += 3)
 
3082
              {
 
3083
                if ((r0[0] & 15) > dither[x & 3])
 
3084
                  *ptr ^= (0xf0 & OnPixels[r0[0]]);
 
3085
                else
 
3086
                  *ptr ^= (0xf0 & OffPixels[r0[0]]);
 
3087
 
 
3088
                if ((r0[1] & 15) > dither[x & 3])
 
3089
                  *ptr++ ^= (0x0f & OnPixels[r0[1]]);
 
3090
                else
 
3091
                  *ptr++ ^= (0x0f & OffPixels[r0[1]]);
 
3092
 
 
3093
                if ((r0[2] & 15) > dither[x & 3])
 
3094
                  *ptr ^= (0xf0 & OnPixels[r0[2]]);
 
3095
                else
 
3096
                  *ptr ^= (0xf0 & OffPixels[r0[2]]);
 
3097
 
 
3098
                ptr ++;
 
3099
              }
 
3100
              break;
 
3101
 
 
3102
          case 8 :
 
3103
              for (x = xsize; x > 0; x --, r0 += 3, r1 += 3)
 
3104
              {
 
3105
                if (r0[0] == r1[0])
 
3106
                  *ptr++ = r0[0];
 
3107
                else
 
3108
                  *ptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize;
 
3109
 
 
3110
                if (r0[1] == r1[1])
 
3111
                  *ptr++ = r0[1];
 
3112
                else
 
3113
                  *ptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize;
 
3114
 
 
3115
                if (r0[2] == r1[2])
 
3116
                  *ptr++ = r0[2];
 
3117
                else
 
3118
                  *ptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize;
 
3119
 
 
3120
                ptr ++;
 
3121
              }
 
3122
              break;
 
3123
        }
 
3124
        break;
 
3125
 
 
3126
    case CUPS_ORDER_BANDED :
 
3127
        cptr = ptr;
 
3128
        mptr = ptr + bandwidth;
 
3129
        yptr = ptr + 2 * bandwidth;
 
3130
 
 
3131
        memset(ptr + 3 * bandwidth, 255, bandwidth);
 
3132
 
 
3133
        switch (header->cupsBitsPerColor)
 
3134
        {
 
3135
          case 1 :
 
3136
              bitmask = 0x80 >> (bitoffset & 7);
 
3137
              dither  = Floyd16x16[y & 15];
 
3138
 
 
3139
              for (x = xsize; x > 0; x --)
 
3140
              {
 
3141
                if (*r0++ > dither[x & 15])
 
3142
                  *cptr ^= bitmask;
 
3143
                if (*r0++ > dither[x & 15])
 
3144
                  *mptr ^= bitmask;
 
3145
                if (*r0++ > dither[x & 15])
 
3146
                  *yptr ^= bitmask;
 
3147
 
 
3148
                if (bitmask > 1)
 
3149
                  bitmask >>= 1;
 
3150
                else
 
3151
                {
 
3152
                  bitmask = 0x80;
 
3153
                  cptr ++;
 
3154
                  mptr ++;
 
3155
                  yptr ++;
 
3156
                }
 
3157
              }
 
3158
              break;
 
3159
 
 
3160
          case 2 :
 
3161
              bitmask = 0xc0 >> (bitoffset & 7);
 
3162
              dither  = Floyd8x8[y & 7];
 
3163
 
 
3164
              for (x = xsize; x > 0; x --)
 
3165
              {
 
3166
                if ((*r0 & 63) > dither[x & 7])
 
3167
                  *cptr ^= (bitmask & OnPixels[*r0++]);
 
3168
                else
 
3169
                  *cptr ^= (bitmask & OffPixels[*r0++]);
 
3170
 
 
3171
                if ((*r0 & 63) > dither[x & 7])
 
3172
                  *mptr ^= (bitmask & OnPixels[*r0++]);
 
3173
                else
 
3174
                  *mptr ^= (bitmask & OffPixels[*r0++]);
 
3175
 
 
3176
                if ((*r0 & 63) > dither[x & 7])
 
3177
                  *yptr ^= (bitmask & OnPixels[*r0++]);
 
3178
                else
 
3179
                  *yptr ^= (bitmask & OffPixels[*r0++]);
 
3180
 
 
3181
                if (bitmask > 3)
 
3182
                  bitmask >>= 2;
 
3183
                else
 
3184
                {
 
3185
                  bitmask = 0xc0;
 
3186
 
 
3187
                  cptr ++;
 
3188
                  mptr ++;
 
3189
                  yptr ++;
 
3190
                }
 
3191
              }
 
3192
              break;
 
3193
 
 
3194
          case 4 :
 
3195
              bitmask = 0xf0 >> (bitoffset & 7);
 
3196
              dither  = Floyd4x4[y & 3];
 
3197
 
 
3198
              for (x = xsize; x > 0; x --)
 
3199
              {
 
3200
                if ((*r0 & 15) > dither[x & 3])
 
3201
                  *cptr ^= (bitmask & OnPixels[*r0++]);
 
3202
                else
 
3203
                  *cptr ^= (bitmask & OffPixels[*r0++]);
 
3204
 
 
3205
                if ((*r0 & 15) > dither[x & 3])
 
3206
                  *mptr ^= (bitmask & OnPixels[*r0++]);
 
3207
                else
 
3208
                  *mptr ^= (bitmask & OffPixels[*r0++]);
 
3209
 
 
3210
                if ((*r0 & 15) > dither[x & 3])
 
3211
                  *yptr ^= (bitmask & OnPixels[*r0++]);
 
3212
                else
 
3213
                  *yptr ^= (bitmask & OffPixels[*r0++]);
 
3214
 
 
3215
                if (bitmask == 0xf0)
 
3216
                  bitmask = 0x0f;
 
3217
                else
 
3218
                {
 
3219
                  bitmask = 0xf0;
 
3220
 
 
3221
                  cptr ++;
 
3222
                  mptr ++;
 
3223
                  yptr ++;
 
3224
                }
 
3225
              }
 
3226
              break;
 
3227
 
 
3228
          case 8 :
 
3229
              for (x = xsize; x > 0; x --, r0 += 3, r1 += 3)
 
3230
              {
 
3231
                if (r0[0] == r1[0])
 
3232
                  *cptr++ = r0[0];
 
3233
                else
 
3234
                  *cptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize;
 
3235
 
 
3236
                if (r0[1] == r1[1])
 
3237
                  *mptr++ = r0[1];
 
3238
                else
 
3239
                  *mptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize;
 
3240
 
 
3241
                if (r0[2] == r1[2])
 
3242
                  *yptr++ = r0[2];
 
3243
                else
 
3244
                  *yptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize;
 
3245
              }
 
3246
              break;
 
3247
        }
 
3248
        break;
 
3249
 
 
3250
    case CUPS_ORDER_PLANAR :
 
3251
        if (z == 3)
 
3252
        {
 
3253
          memset(row, 255, header->cupsBytesPerLine);
 
3254
          break;
 
3255
        }
 
3256
 
 
3257
        switch (header->cupsBitsPerColor)
 
3258
        {
 
3259
          case 1 :
 
3260
              bitmask = 0x80 >> (bitoffset & 7);
 
3261
              dither  = Floyd16x16[y & 15];
 
3262
 
 
3263
              switch (z)
 
3264
              {
 
3265
                case 0 :
 
3266
                    for (x = xsize; x > 0; x --, r0 += 3)
 
3267
                    {
 
3268
                      if (r0[0] > dither[x & 15])
 
3269
                        *ptr ^= bitmask;
 
3270
 
 
3271
                      if (bitmask > 1)
 
3272
                        bitmask >>= 1;
 
3273
                      else
 
3274
                      {
 
3275
                        bitmask = 0x80;
 
3276
                        ptr ++;
 
3277
                      }
 
3278
                    }
 
3279
                    break;
 
3280
 
 
3281
                case 1 :
 
3282
                    for (x = xsize; x > 0; x --, r0 += 3)
 
3283
                    {
 
3284
                      if (r0[1] > dither[x & 15])
 
3285
                        *ptr ^= bitmask;
 
3286
 
 
3287
                      if (bitmask > 1)
 
3288
                        bitmask >>= 1;
 
3289
                      else
 
3290
                      {
 
3291
                        bitmask = 0x80;
 
3292
                        ptr ++;
 
3293
                      }
 
3294
                    }
 
3295
                    break;
 
3296
 
 
3297
                case 2 :
 
3298
                    for (x = xsize; x > 0; x --, r0 += 3)
 
3299
                    {
 
3300
                      if (r0[2] > dither[x & 15])
 
3301
                        *ptr ^= bitmask;
 
3302
 
 
3303
                      if (bitmask > 1)
 
3304
                        bitmask >>= 1;
 
3305
                      else
 
3306
                      {
 
3307
                        bitmask = 0x80;
 
3308
                        ptr ++;
 
3309
                      }
 
3310
                    }
 
3311
                    break;
 
3312
              }
 
3313
              break;
 
3314
 
 
3315
          case 2 :
 
3316
              bitmask = 0xc0 >> (bitoffset & 7);
 
3317
              dither  = Floyd8x8[y & 7];
 
3318
              r0 += z;
 
3319
 
 
3320
              for (x = xsize; x > 0; x --, r0 += 3)
 
3321
              {
 
3322
                if ((*r0 & 63) > dither[x & 7])
 
3323
                  *ptr ^= (bitmask & OnPixels[*r0]);
 
3324
                else
 
3325
                  *ptr ^= (bitmask & OffPixels[*r0]);
 
3326
 
 
3327
                if (bitmask > 3)
 
3328
                  bitmask >>= 2;
 
3329
                else
 
3330
                {
 
3331
                  bitmask = 0xc0;
 
3332
 
 
3333
                  ptr ++;
 
3334
                }
 
3335
              }
 
3336
              break;
 
3337
 
 
3338
          case 4 :
 
3339
              bitmask = 0xf0 >> (bitoffset & 7);
 
3340
              dither  = Floyd4x4[y & 3];
 
3341
              r0 += z;
 
3342
 
 
3343
              for (x = xsize; x > 0; x --, r0 += 3)
 
3344
              {
 
3345
                if ((*r0 & 15) > dither[x & 3])
 
3346
                  *ptr ^= (bitmask & OnPixels[*r0]);
 
3347
                else
 
3348
                  *ptr ^= (bitmask & OffPixels[*r0]);
 
3349
 
 
3350
                if (bitmask == 0xf0)
 
3351
                  bitmask = 0x0f;
 
3352
                else
 
3353
                {
 
3354
                  bitmask = 0xf0;
 
3355
 
 
3356
                  ptr ++;
 
3357
                }
 
3358
              }
 
3359
              break;
 
3360
 
 
3361
          case 8 :
 
3362
              r0 += z;
 
3363
              r1 += z;
 
3364
 
 
3365
              for (x = xsize; x > 0; x --, r0 += 3, r1 += 3)
 
3366
              {
 
3367
                if (*r0 == *r1)
 
3368
                  *ptr++ = *r0;
 
3369
                else
 
3370
                  *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize;
 
3371
              }
 
3372
              break;
 
3373
        }
 
3374
        break;
 
3375
  }
 
3376
}
 
3377
 
 
3378
 
 
3379
/*
 
3380
 * 'format_W()' - Convert image data to luminance.
 
3381
 */
 
3382
 
 
3383
static void
 
3384
format_W(cups_page_header2_t *header,   /* I - Page header */
 
3385
            unsigned char    *row,      /* IO - Bitmap data for device */
 
3386
            int              y,         /* I - Current row */
 
3387
            int              z,         /* I - Current plane */
 
3388
            int              xsize,     /* I - Width of image data */
 
3389
            int              ysize,     /* I - Height of image data */
 
3390
            int              yerr0,     /* I - Top Y error */
 
3391
            int              yerr1,     /* I - Bottom Y error */
 
3392
            cups_ib_t        *r0,       /* I - Primary image data */
 
3393
            cups_ib_t        *r1)       /* I - Image data for interpolation */
 
3394
{
 
3395
  cups_ib_t     *ptr,                   /* Pointer into row */
 
3396
                bitmask;                /* Current mask for pixel */
 
3397
  int           bitoffset;              /* Current offset in line */
 
3398
  int           x,                      /* Current X coordinate on page */
 
3399
                *dither;                /* Pointer into dither array */
 
3400
 
 
3401
 
 
3402
  (void)z;
 
3403
 
 
3404
  switch (XPosition)
 
3405
  {
 
3406
    case -1 :
 
3407
        bitoffset = 0;
 
3408
        break;
 
3409
    default :
 
3410
        bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2);
 
3411
        break;
 
3412
    case 1 :
 
3413
        bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize);
 
3414
        break;
 
3415
  }
 
3416
 
 
3417
  ptr = row + bitoffset / 8;
 
3418
 
 
3419
  switch (header->cupsBitsPerColor)
 
3420
  {
 
3421
    case 1 :
 
3422
        bitmask = 0x80 >> (bitoffset & 7);
 
3423
        dither  = Floyd16x16[y & 15];
 
3424
 
 
3425
        for (x = xsize; x > 0; x --)
 
3426
        {
 
3427
          if (*r0++ > dither[x & 15])
 
3428
            *ptr ^= bitmask;
 
3429
 
 
3430
          if (bitmask > 1)
 
3431
            bitmask >>= 1;
 
3432
          else
 
3433
          {
 
3434
            bitmask = 0x80;
 
3435
            ptr ++;
 
3436
          }
 
3437
        }
 
3438
        break;
 
3439
 
 
3440
    case 2 :
 
3441
        bitmask = 0xc0 >> (bitoffset & 7);
 
3442
        dither  = Floyd8x8[y & 7];
 
3443
 
 
3444
        for (x = xsize; x > 0; x --)
 
3445
        {
 
3446
          if ((*r0 & 63) > dither[x & 7])
 
3447
            *ptr ^= (bitmask & OnPixels[*r0++]);
 
3448
          else
 
3449
            *ptr ^= (bitmask & OffPixels[*r0++]);
 
3450
 
 
3451
          if (bitmask > 3)
 
3452
            bitmask >>= 2;
 
3453
          else
 
3454
          {
 
3455
            bitmask = 0xc0;
 
3456
 
 
3457
            ptr ++;
 
3458
          }
 
3459
        }
 
3460
        break;
 
3461
 
 
3462
    case 4 :
 
3463
        bitmask = 0xf0 >> (bitoffset & 7);
 
3464
        dither  = Floyd4x4[y & 3];
 
3465
 
 
3466
        for (x = xsize; x > 0; x --)
 
3467
        {
 
3468
          if ((*r0 & 15) > dither[x & 3])
 
3469
            *ptr ^= (bitmask & OnPixels[*r0++]);
 
3470
          else
 
3471
            *ptr ^= (bitmask & OffPixels[*r0++]);
 
3472
 
 
3473
          if (bitmask == 0xf0)
 
3474
            bitmask = 0x0f;
 
3475
          else
 
3476
          {
 
3477
            bitmask = 0xf0;
 
3478
 
 
3479
            ptr ++;
 
3480
          }
 
3481
        }
 
3482
        break;
 
3483
 
 
3484
    case 8 :
 
3485
        for (x = xsize; x > 0; x --, r0 ++, r1 ++)
 
3486
        {
 
3487
          if (*r0 == *r1)
 
3488
            *ptr++ = *r0;
 
3489
          else
 
3490
            *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize;
 
3491
        }
 
3492
        break;
 
3493
  }
 
3494
}
 
3495
 
 
3496
 
 
3497
/*
 
3498
 * 'format_YMC()' - Convert image data to YMC.
 
3499
 */
 
3500
 
 
3501
static void
 
3502
format_YMC(cups_page_header2_t *header, /* I - Page header */
 
3503
            unsigned char      *row,    /* IO - Bitmap data for device */
 
3504
            int                y,       /* I - Current row */
 
3505
            int                z,       /* I - Current plane */
 
3506
            int                xsize,   /* I - Width of image data */
 
3507
            int                ysize,   /* I - Height of image data */
 
3508
            int                yerr0,   /* I - Top Y error */
 
3509
            int                yerr1,   /* I - Bottom Y error */
 
3510
            cups_ib_t          *r0,     /* I - Primary image data */
 
3511
            cups_ib_t          *r1)     /* I - Image data for interpolation */
 
3512
{
 
3513
  cups_ib_t     *ptr,                   /* Pointer into row */
 
3514
                *cptr,                  /* Pointer into cyan */
 
3515
                *mptr,                  /* Pointer into magenta */
 
3516
                *yptr,                  /* Pointer into yellow */
 
3517
                bitmask;                /* Current mask for pixel */
 
3518
  int           bitoffset;              /* Current offset in line */
 
3519
  int           bandwidth;              /* Width of a color band */
 
3520
  int           x,                      /* Current X coordinate on page */
 
3521
                *dither;                /* Pointer into dither array */
 
3522
 
 
3523
 
 
3524
  switch (XPosition)
 
3525
  {
 
3526
    case -1 :
 
3527
        bitoffset = 0;
 
3528
        break;
 
3529
    default :
 
3530
        bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2);
 
3531
        break;
 
3532
    case 1 :
 
3533
        bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize);
 
3534
        break;
 
3535
  }
 
3536
 
 
3537
  ptr       = row + bitoffset / 8;
 
3538
  bandwidth = header->cupsBytesPerLine / 3;
 
3539
 
 
3540
  switch (header->cupsColorOrder)
 
3541
  {
 
3542
    case CUPS_ORDER_CHUNKED :
 
3543
        switch (header->cupsBitsPerColor)
 
3544
        {
 
3545
          case 1 :
 
3546
              bitmask = 64 >> (bitoffset & 7);
 
3547
              dither  = Floyd16x16[y & 15];
 
3548
 
 
3549
              for (x = xsize ; x > 0; x --, r0 += 3)
 
3550
              {
 
3551
                if (r0[2] > dither[x & 15])
 
3552
                  *ptr ^= bitmask;
 
3553
                bitmask >>= 1;
 
3554
 
 
3555
                if (r0[1] > dither[x & 15])
 
3556
                  *ptr ^= bitmask;
 
3557
                bitmask >>= 1;
 
3558
 
 
3559
                if (r0[0] > dither[x & 15])
 
3560
                  *ptr ^= bitmask;
 
3561
 
 
3562
                if (bitmask > 1)
 
3563
                  bitmask >>= 2;
 
3564
                else
 
3565
                {
 
3566
                  bitmask = 64;
 
3567
                  ptr ++;
 
3568
                }
 
3569
              }
 
3570
              break;
 
3571
 
 
3572
          case 2 :
 
3573
              dither = Floyd8x8[y & 7];
 
3574
 
 
3575
              for (x = xsize ; x > 0; x --, r0 += 3)
 
3576
              {
 
3577
                if ((r0[2] & 63) > dither[x & 7])
 
3578
                  *ptr ^= (0x30 & OnPixels[r0[2]]);
 
3579
                else
 
3580
                  *ptr ^= (0x30 & OffPixels[r0[2]]);
 
3581
 
 
3582
                if ((r0[1] & 63) > dither[x & 7])
 
3583
                  *ptr ^= (0x0c & OnPixels[r0[1]]);
 
3584
                else
 
3585
                  *ptr ^= (0x0c & OffPixels[r0[1]]);
 
3586
 
 
3587
                if ((r0[0] & 63) > dither[x & 7])
 
3588
                  *ptr++ ^= (0x03 & OnPixels[r0[0]]);
 
3589
                else
 
3590
                  *ptr++ ^= (0x03 & OffPixels[r0[0]]);
 
3591
              }
 
3592
              break;
 
3593
 
 
3594
          case 4 :
 
3595
              dither = Floyd4x4[y & 3];
 
3596
 
 
3597
              for (x = xsize ; x > 0; x --, r0 += 3)
 
3598
              {
 
3599
                if ((r0[2] & 15) > dither[x & 3])
 
3600
                  *ptr++ ^= (0x0f & OnPixels[r0[2]]);
 
3601
                else
 
3602
                  *ptr++ ^= (0x0f & OffPixels[r0[2]]);
 
3603
 
 
3604
                if ((r0[1] & 15) > dither[x & 3])
 
3605
                  *ptr ^= (0xf0 & OnPixels[r0[1]]);
 
3606
                else
 
3607
                  *ptr ^= (0xf0 & OffPixels[r0[1]]);
 
3608
 
 
3609
                if ((r0[0] & 15) > dither[x & 3])
 
3610
                  *ptr++ ^= (0x0f & OnPixels[r0[0]]);
 
3611
                else
 
3612
                  *ptr++ ^= (0x0f & OffPixels[r0[0]]);
 
3613
              }
 
3614
              break;
 
3615
 
 
3616
          case 8 :
 
3617
              for (x = xsize; x > 0; x --, r0 += 3, r1 += 3)
 
3618
              {
 
3619
                if (r0[2] == r1[2])
 
3620
                  *ptr++ = r0[2];
 
3621
                else
 
3622
                  *ptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize;
 
3623
 
 
3624
                if (r0[1] == r1[1])
 
3625
                  *ptr++ = r0[1];
 
3626
                else
 
3627
                  *ptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize;
 
3628
 
 
3629
                if (r0[0] == r1[0])
 
3630
                  *ptr++ = r0[0];
 
3631
                else
 
3632
                  *ptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize;
 
3633
              }
 
3634
              break;
 
3635
        }
 
3636
        break;
 
3637
 
 
3638
    case CUPS_ORDER_BANDED :
 
3639
        yptr = ptr;
 
3640
        mptr = ptr + bandwidth;
 
3641
        cptr = ptr + 2 * bandwidth;
 
3642
 
 
3643
        switch (header->cupsBitsPerColor)
 
3644
        {
 
3645
          case 1 :
 
3646
              bitmask = 0x80 >> (bitoffset & 7);
 
3647
              dither  = Floyd16x16[y & 15];
 
3648
 
 
3649
              for (x = xsize; x > 0; x --)
 
3650
              {
 
3651
                if (*r0++ > dither[x & 15])
 
3652
                  *cptr ^= bitmask;
 
3653
                if (*r0++ > dither[x & 15])
 
3654
                  *mptr ^= bitmask;
 
3655
                if (*r0++ > dither[x & 15])
 
3656
                  *yptr ^= bitmask;
 
3657
 
 
3658
                if (bitmask > 1)
 
3659
                  bitmask >>= 1;
 
3660
                else
 
3661
                {
 
3662
                  bitmask = 0x80;
 
3663
                  cptr ++;
 
3664
                  mptr ++;
 
3665
                  yptr ++;
 
3666
                }
 
3667
              }
 
3668
              break;
 
3669
 
 
3670
          case 2 :
 
3671
              bitmask = 0xc0 >> (bitoffset & 7);
 
3672
              dither  = Floyd8x8[y & 7];
 
3673
 
 
3674
              for (x = xsize; x > 0; x --)
 
3675
              {
 
3676
                if ((*r0 & 63) > dither[x & 7])
 
3677
                  *cptr ^= (bitmask & OnPixels[*r0++]);
 
3678
                else
 
3679
                  *cptr ^= (bitmask & OffPixels[*r0++]);
 
3680
 
 
3681
                if ((*r0 & 63) > dither[x & 7])
 
3682
                  *mptr ^= (bitmask & OnPixels[*r0++]);
 
3683
                else
 
3684
                  *mptr ^= (bitmask & OffPixels[*r0++]);
 
3685
 
 
3686
                if ((*r0 & 63) > dither[x & 7])
 
3687
                  *yptr ^= (bitmask & OnPixels[*r0++]);
 
3688
                else
 
3689
                  *yptr ^= (bitmask & OffPixels[*r0++]);
 
3690
 
 
3691
                if (bitmask > 3)
 
3692
                  bitmask >>= 2;
 
3693
                else
 
3694
                {
 
3695
                  bitmask = 0xc0;
 
3696
 
 
3697
                  cptr ++;
 
3698
                  mptr ++;
 
3699
                  yptr ++;
 
3700
                }
 
3701
              }
 
3702
              break;
 
3703
 
 
3704
          case 4 :
 
3705
              bitmask = 0xf0 >> (bitoffset & 7);
 
3706
              dither  = Floyd4x4[y & 3];
 
3707
 
 
3708
              for (x = xsize; x > 0; x --)
 
3709
              {
 
3710
                if ((*r0 & 15) > dither[x & 3])
 
3711
                  *cptr ^= (bitmask & OnPixels[*r0++]);
 
3712
                else
 
3713
                  *cptr ^= (bitmask & OffPixels[*r0++]);
 
3714
 
 
3715
                if ((*r0 & 15) > dither[x & 3])
 
3716
                  *mptr ^= (bitmask & OnPixels[*r0++]);
 
3717
                else
 
3718
                  *mptr ^= (bitmask & OffPixels[*r0++]);
 
3719
 
 
3720
                if ((*r0 & 15) > dither[x & 3])
 
3721
                  *yptr ^= (bitmask & OnPixels[*r0++]);
 
3722
                else
 
3723
                  *yptr ^= (bitmask & OffPixels[*r0++]);
 
3724
 
 
3725
                if (bitmask == 0xf0)
 
3726
                  bitmask = 0x0f;
 
3727
                else
 
3728
                {
 
3729
                  bitmask = 0xf0;
 
3730
 
 
3731
                  cptr ++;
 
3732
                  mptr ++;
 
3733
                  yptr ++;
 
3734
                }
 
3735
              }
 
3736
              break;
 
3737
 
 
3738
          case 8 :
 
3739
              for (x = xsize; x > 0; x --, r0 += 3, r1 += 3)
 
3740
              {
 
3741
                if (r0[0] == r1[0])
 
3742
                  *cptr++ = r0[0];
 
3743
                else
 
3744
                  *cptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize;
 
3745
 
 
3746
                if (r0[1] == r1[1])
 
3747
                  *mptr++ = r0[1];
 
3748
                else
 
3749
                  *mptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize;
 
3750
 
 
3751
                if (r0[2] == r1[2])
 
3752
                  *yptr++ = r0[2];
 
3753
                else
 
3754
                  *yptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize;
 
3755
              }
 
3756
              break;
 
3757
        }
 
3758
        break;
 
3759
 
 
3760
    case CUPS_ORDER_PLANAR :
 
3761
        switch (header->cupsBitsPerColor)
 
3762
        {
 
3763
          case 1 :
 
3764
              bitmask = 0x80 >> (bitoffset & 7);
 
3765
              dither  = Floyd16x16[y & 15];
 
3766
 
 
3767
              switch (z)
 
3768
              {
 
3769
                case 2 :
 
3770
                    for (x = xsize; x > 0; x --, r0 += 3)
 
3771
                    {
 
3772
                      if (r0[0] > dither[x & 15])
 
3773
                        *ptr ^= bitmask;
 
3774
 
 
3775
                      if (bitmask > 1)
 
3776
                        bitmask >>= 1;
 
3777
                      else
 
3778
                      {
 
3779
                        bitmask = 0x80;
 
3780
                        ptr ++;
 
3781
                      }
 
3782
                    }
 
3783
                    break;
 
3784
 
 
3785
                case 1 :
 
3786
                    for (x = xsize; x > 0; x --, r0 += 3)
 
3787
                    {
 
3788
                      if (r0[1] > dither[x & 15])
 
3789
                        *ptr ^= bitmask;
 
3790
 
 
3791
                      if (bitmask > 1)
 
3792
                        bitmask >>= 1;
 
3793
                      else
 
3794
                      {
 
3795
                        bitmask = 0x80;
 
3796
                        ptr ++;
 
3797
                      }
 
3798
                    }
 
3799
                    break;
 
3800
 
 
3801
                case 0 :
 
3802
                    for (x = xsize; x > 0; x --, r0 += 3)
 
3803
                    {
 
3804
                      if (r0[2] > dither[x & 15])
 
3805
                        *ptr ^= bitmask;
 
3806
 
 
3807
                      if (bitmask > 1)
 
3808
                        bitmask >>= 1;
 
3809
                      else
 
3810
                      {
 
3811
                        bitmask = 0x80;
 
3812
                        ptr ++;
 
3813
                      }
 
3814
                    }
 
3815
                    break;
 
3816
              }
 
3817
              break;
 
3818
 
 
3819
          case 2 :
 
3820
              bitmask = 0xc0 >> (bitoffset & 7);
 
3821
              dither  = Floyd8x8[y & 7];
 
3822
              z       = 2 - z;
 
3823
              r0      += z;
 
3824
 
 
3825
              for (x = xsize; x > 0; x --, r0 += 3)
 
3826
              {
 
3827
                if ((*r0 & 63) > dither[x & 7])
 
3828
                  *ptr ^= (bitmask & OnPixels[*r0]);
 
3829
                else
 
3830
                  *ptr ^= (bitmask & OffPixels[*r0]);
 
3831
 
 
3832
                if (bitmask > 3)
 
3833
                  bitmask >>= 2;
 
3834
                else
 
3835
                {
 
3836
                  bitmask = 0xc0;
 
3837
 
 
3838
                  ptr ++;
 
3839
                }
 
3840
              }
 
3841
              break;
 
3842
 
 
3843
          case 4 :
 
3844
              bitmask = 0xf0 >> (bitoffset & 7);
 
3845
              dither  = Floyd4x4[y & 3];
 
3846
              z       = 2 - z;
 
3847
              r0      += z;
 
3848
 
 
3849
              for (x = xsize; x > 0; x --, r0 += 3)
 
3850
              {
 
3851
                if ((*r0 & 15) > dither[x & 3])
 
3852
                  *ptr ^= (bitmask & OnPixels[*r0]);
 
3853
                else
 
3854
                  *ptr ^= (bitmask & OffPixels[*r0]);
 
3855
 
 
3856
                if (bitmask == 0xf0)
 
3857
                  bitmask = 0x0f;
 
3858
                else
 
3859
                {
 
3860
                  bitmask = 0xf0;
 
3861
 
 
3862
                  ptr ++;
 
3863
                }
 
3864
              }
 
3865
              break;
 
3866
 
 
3867
          case 8 :
 
3868
              z  = 2 - z;
 
3869
              r0 += z;
 
3870
              r1 += z;
 
3871
 
 
3872
              for (x = xsize; x > 0; x --, r0 += 3, r1 += 3)
 
3873
              {
 
3874
                if (*r0 == *r1)
 
3875
                  *ptr++ = *r0;
 
3876
                else
 
3877
                  *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize;
 
3878
              }
 
3879
              break;
 
3880
        }
 
3881
        break;
 
3882
  }
 
3883
}
 
3884
 
 
3885
 
 
3886
/*
 
3887
 * 'format_YMCK()' - Convert image data to YMCK.
 
3888
 */
 
3889
 
 
3890
static void
 
3891
format_YMCK(cups_page_header2_t *header,/* I - Page header */
 
3892
            unsigned char       *row,   /* IO - Bitmap data for device */
 
3893
            int                 y,      /* I - Current row */
 
3894
            int                 z,      /* I - Current plane */
 
3895
            int                 xsize,  /* I - Width of image data */
 
3896
            int                 ysize,  /* I - Height of image data */
 
3897
            int                 yerr0,  /* I - Top Y error */
 
3898
            int                 yerr1,  /* I - Bottom Y error */
 
3899
            cups_ib_t           *r0,    /* I - Primary image data */
 
3900
            cups_ib_t           *r1)    /* I - Image data for interpolation */
 
3901
{
 
3902
  cups_ib_t     *ptr,                   /* Pointer into row */
 
3903
                *cptr,                  /* Pointer into cyan */
 
3904
                *mptr,                  /* Pointer into magenta */
 
3905
                *yptr,                  /* Pointer into yellow */
 
3906
                *kptr,                  /* Pointer into black */
 
3907
                bitmask;                /* Current mask for pixel */
 
3908
  int           bitoffset;              /* Current offset in line */
 
3909
  int           bandwidth;              /* Width of a color band */
 
3910
  int           x,                      /* Current X coordinate on page */
 
3911
                *dither;                /* Pointer into dither array */
 
3912
  int           pc, pm, py;             /* CMY pixels */
 
3913
 
 
3914
 
 
3915
  switch (XPosition)
 
3916
  {
 
3917
    case -1 :
 
3918
        bitoffset = 0;
 
3919
        break;
 
3920
    default :
 
3921
        bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2);
 
3922
        break;
 
3923
    case 1 :
 
3924
        bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize);
 
3925
        break;
 
3926
  }
 
3927
 
 
3928
  ptr       = row + bitoffset / 8;
 
3929
  bandwidth = header->cupsBytesPerLine / 4;
 
3930
 
 
3931
  switch (header->cupsColorOrder)
 
3932
  {
 
3933
    case CUPS_ORDER_CHUNKED :
 
3934
        switch (header->cupsBitsPerColor)
 
3935
        {
 
3936
          case 1 :
 
3937
              bitmask = 128 >> (bitoffset & 7);
 
3938
              dither  = Floyd16x16[y & 15];
 
3939
 
 
3940
              for (x = xsize ; x > 0; x --)
 
3941
              {
 
3942
                pc = *r0++ > dither[x & 15];
 
3943
                pm = *r0++ > dither[x & 15];
 
3944
                py = *r0++ > dither[x & 15];
 
3945
 
 
3946
                if (pc && pm && py)
 
3947
                {
 
3948
                  bitmask >>= 3;
 
3949
                  *ptr ^= bitmask;
 
3950
                }
 
3951
                else
 
3952
                {
 
3953
                  if (py)
 
3954
                    *ptr ^= bitmask;
 
3955
                  bitmask >>= 1;
 
3956
 
 
3957
                  if (pm)
 
3958
                    *ptr ^= bitmask;
 
3959
                  bitmask >>= 1;
 
3960
 
 
3961
                  if (pc)
 
3962
                    *ptr ^= bitmask;
 
3963
                  bitmask >>= 1;
 
3964
                }
 
3965
 
 
3966
                if (bitmask > 1)
 
3967
                  bitmask >>= 1;
 
3968
                else
 
3969
                {
 
3970
                  bitmask = 128;
 
3971
 
 
3972
                  ptr ++;
 
3973
                }
 
3974
              }
 
3975
              break;
 
3976
 
 
3977
          case 2 :
 
3978
              dither = Floyd8x8[y & 7];
 
3979
 
 
3980
              for (x = xsize ; x > 0; x --, r0 += 4)
 
3981
              {
 
3982
                if ((r0[2] & 63) > dither[x & 7])
 
3983
                  *ptr ^= (0xc0 & OnPixels[r0[2]]);
 
3984
                else
 
3985
                  *ptr ^= (0xc0 & OffPixels[r0[2]]);
 
3986
 
 
3987
                if ((r0[1] & 63) > dither[x & 7])
 
3988
                  *ptr ^= (0x30 & OnPixels[r0[1]]);
 
3989
                else
 
3990
                  *ptr ^= (0x30 & OffPixels[r0[1]]);
 
3991
 
 
3992
                if ((r0[0] & 63) > dither[x & 7])
 
3993
                  *ptr ^= (0x0c & OnPixels[r0[0]]);
 
3994
                else
 
3995
                  *ptr ^= (0x0c & OffPixels[r0[0]]);
 
3996
 
 
3997
                if ((r0[3] & 63) > dither[x & 7])
 
3998
                  *ptr++ ^= (0x03 & OnPixels[r0[3]]);
 
3999
                else
 
4000
                  *ptr++ ^= (0x03 & OffPixels[r0[3]]);
 
4001
              }
 
4002
              break;
 
4003
 
 
4004
          case 4 :
 
4005
              dither = Floyd4x4[y & 3];
 
4006
 
 
4007
              for (x = xsize ; x > 0; x --, r0 += 4)
 
4008
              {
 
4009
                if ((r0[2] & 15) > dither[x & 3])
 
4010
                  *ptr ^= (0xf0 & OnPixels[r0[2]]);
 
4011
                else
 
4012
                  *ptr ^= (0xf0 & OffPixels[r0[2]]);
 
4013
 
 
4014
                if ((r0[1] & 15) > dither[x & 3])
 
4015
                  *ptr++ ^= (0x0f & OnPixels[r0[1]]);
 
4016
                else
 
4017
                  *ptr++ ^= (0x0f & OffPixels[r0[1]]);
 
4018
 
 
4019
                if ((r0[0] & 15) > dither[x & 3])
 
4020
                  *ptr ^= (0xf0 & OnPixels[r0[0]]);
 
4021
                else
 
4022
                  *ptr ^= (0xf0 & OffPixels[r0[0]]);
 
4023
 
 
4024
                if ((r0[3] & 15) > dither[x & 3])
 
4025
                  *ptr++ ^= (0x0f & OnPixels[r0[3]]);
 
4026
                else
 
4027
                  *ptr++ ^= (0x0f & OffPixels[r0[3]]);
 
4028
              }
 
4029
              break;
 
4030
 
 
4031
          case 8 :
 
4032
              for (x = xsize; x > 0; x --, r0 += 4, r1 += 4)
 
4033
              {
 
4034
                if (r0[2] == r1[2])
 
4035
                  *ptr++ = r0[2];
 
4036
                else
 
4037
                  *ptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize;
 
4038
 
 
4039
                if (r0[1] == r1[1])
 
4040
                  *ptr++ = r0[1];
 
4041
                else
 
4042
                  *ptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize;
 
4043
 
 
4044
                if (r0[0] == r1[0])
 
4045
                  *ptr++ = r0[0];
 
4046
                else
 
4047
                  *ptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize;
 
4048
 
 
4049
                if (r0[3] == r1[3])
 
4050
                  *ptr++ = r0[3];
 
4051
                else
 
4052
                  *ptr++ = (r0[3] * yerr0 + r1[3] * yerr1) / ysize;
 
4053
              }
 
4054
              break;
 
4055
        }
 
4056
        break;
 
4057
 
 
4058
    case CUPS_ORDER_BANDED :
 
4059
        yptr = ptr;
 
4060
        mptr = ptr + bandwidth;
 
4061
        cptr = ptr + 2 * bandwidth;
 
4062
        kptr = ptr + 3 * bandwidth;
 
4063
 
 
4064
        switch (header->cupsBitsPerColor)
 
4065
        {
 
4066
          case 1 :
 
4067
              bitmask = 0x80 >> (bitoffset & 7);
 
4068
              dither  = Floyd16x16[y & 15];
 
4069
 
 
4070
              for (x = xsize; x > 0; x --)
 
4071
              {
 
4072
                pc = *r0++ > dither[x & 15];
 
4073
                pm = *r0++ > dither[x & 15];
 
4074
                py = *r0++ > dither[x & 15];
 
4075
 
 
4076
                if (pc && pm && py)
 
4077
                  *kptr ^= bitmask;
 
4078
                else
 
4079
                {
 
4080
                  if (pc)
 
4081
                    *cptr ^= bitmask;
 
4082
                  if (pm)
 
4083
                    *mptr ^= bitmask;
 
4084
                  if (py)
 
4085
                    *yptr ^= bitmask;
 
4086
                }
 
4087
 
 
4088
                if (bitmask > 1)
 
4089
                  bitmask >>= 1;
 
4090
                else
 
4091
                {
 
4092
                  bitmask = 0x80;
 
4093
 
 
4094
                  cptr ++;
 
4095
                  mptr ++;
 
4096
                  yptr ++;
 
4097
                  kptr ++;
 
4098
                }
 
4099
              }
 
4100
              break;
 
4101
 
 
4102
          case 2 :
 
4103
              bitmask = 0xc0 >> (bitoffset & 7);
 
4104
              dither  = Floyd8x8[y & 7];
 
4105
 
 
4106
              for (x = xsize; x > 0; x --)
 
4107
              {
 
4108
                if ((*r0 & 63) > dither[x & 7])
 
4109
                  *cptr ^= (bitmask & OnPixels[*r0++]);
 
4110
                else
 
4111
                  *cptr ^= (bitmask & OffPixels[*r0++]);
 
4112
 
 
4113
                if ((*r0 & 63) > dither[x & 7])
 
4114
                  *mptr ^= (bitmask & OnPixels[*r0++]);
 
4115
                else
 
4116
                  *mptr ^= (bitmask & OffPixels[*r0++]);
 
4117
 
 
4118
                if ((*r0 & 63) > dither[x & 7])
 
4119
                  *yptr ^= (bitmask & OnPixels[*r0++]);
 
4120
                else
 
4121
                  *yptr ^= (bitmask & OffPixels[*r0++]);
 
4122
 
 
4123
                if ((*r0 & 63) > dither[x & 7])
 
4124
                  *kptr ^= (bitmask & OnPixels[*r0++]);
 
4125
                else
 
4126
                  *kptr ^= (bitmask & OffPixels[*r0++]);
 
4127
 
 
4128
                if (bitmask > 3)
 
4129
                  bitmask >>= 2;
 
4130
                else
 
4131
                {
 
4132
                  bitmask = 0xc0;
 
4133
 
 
4134
                  cptr ++;
 
4135
                  mptr ++;
 
4136
                  yptr ++;
 
4137
                  kptr ++;
 
4138
                }
 
4139
              }
 
4140
              break;
 
4141
 
 
4142
          case 4 :
 
4143
              bitmask = 0xf0 >> (bitoffset & 7);
 
4144
              dither  = Floyd4x4[y & 3];
 
4145
 
 
4146
              for (x = xsize; x > 0; x --)
 
4147
              {
 
4148
                if ((*r0 & 15) > dither[x & 3])
 
4149
                  *cptr ^= (bitmask & OnPixels[*r0++]);
 
4150
                else
 
4151
                  *cptr ^= (bitmask & OffPixels[*r0++]);
 
4152
 
 
4153
                if ((*r0 & 15) > dither[x & 3])
 
4154
                  *mptr ^= (bitmask & OnPixels[*r0++]);
 
4155
                else
 
4156
                  *mptr ^= (bitmask & OffPixels[*r0++]);
 
4157
 
 
4158
                if ((*r0 & 15) > dither[x & 3])
 
4159
                  *yptr ^= (bitmask & OnPixels[*r0++]);
 
4160
                else
 
4161
                  *yptr ^= (bitmask & OffPixels[*r0++]);
 
4162
 
 
4163
                if ((*r0 & 15) > dither[x & 3])
 
4164
                  *kptr ^= (bitmask & OnPixels[*r0++]);
 
4165
                else
 
4166
                  *kptr ^= (bitmask & OffPixels[*r0++]);
 
4167
 
 
4168
                if (bitmask == 0xf0)
 
4169
                  bitmask = 0x0f;
 
4170
                else
 
4171
                {
 
4172
                  bitmask = 0xf0;
 
4173
 
 
4174
                  cptr ++;
 
4175
                  mptr ++;
 
4176
                  yptr ++;
 
4177
                  kptr ++;
 
4178
                }
 
4179
              }
 
4180
              break;
 
4181
 
 
4182
          case 8 :
 
4183
              for (x = xsize; x > 0; x --, r0 += 4, r1 += 4)
 
4184
              {
 
4185
                if (r0[0] == r1[0])
 
4186
                  *cptr++ = r0[0];
 
4187
                else
 
4188
                  *cptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize;
 
4189
 
 
4190
                if (r0[1] == r1[1])
 
4191
                  *mptr++ = r0[1];
 
4192
                else
 
4193
                  *mptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize;
 
4194
 
 
4195
                if (r0[2] == r1[2])
 
4196
                  *yptr++ = r0[2];
 
4197
                else
 
4198
                  *yptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize;
 
4199
 
 
4200
                if (r0[3] == r1[3])
 
4201
                  *kptr++ = r0[3];
 
4202
                else
 
4203
                  *kptr++ = (r0[3] * yerr0 + r1[3] * yerr1) / ysize;
 
4204
              }
 
4205
              break;
 
4206
        }
 
4207
        break;
 
4208
 
 
4209
    case CUPS_ORDER_PLANAR :
 
4210
        switch (header->cupsBitsPerColor)
 
4211
        {
 
4212
          case 1 :
 
4213
              bitmask = 0x80 >> (bitoffset & 7);
 
4214
              dither  = Floyd16x16[y & 15];
 
4215
 
 
4216
              for (x = xsize; x > 0; x --)
 
4217
              {
 
4218
                pc = *r0++ > dither[x & 15];
 
4219
                pm = *r0++ > dither[x & 15];
 
4220
                py = *r0++ > dither[x & 15];
 
4221
 
 
4222
                if ((pc && pm && py && z == 3) ||
 
4223
                    (pc && z == 2) || (pm && z == 1) || (py && z == 0))
 
4224
                  *ptr ^= bitmask;
 
4225
 
 
4226
                if (bitmask > 1)
 
4227
                  bitmask >>= 1;
 
4228
                else
 
4229
                {
 
4230
                  bitmask = 0x80;
 
4231
                  ptr ++;
 
4232
                }
 
4233
              }
 
4234
              break;
 
4235
 
 
4236
          case 2 :
 
4237
              bitmask = 0xc0 >> (bitoffset & 7);
 
4238
              dither  = Floyd8x8[y & 7];
 
4239
              if (z == 3)
 
4240
                r0 += 3;
 
4241
              else
 
4242
                r0 += 2 - z;
 
4243
 
 
4244
              for (x = xsize; x > 0; x --, r0 += 4)
 
4245
              {
 
4246
                if ((*r0 & 63) > dither[x & 7])
 
4247
                  *ptr ^= (bitmask & OnPixels[*r0]);
 
4248
                else
 
4249
                  *ptr ^= (bitmask & OffPixels[*r0]);
 
4250
 
 
4251
                if (bitmask > 3)
 
4252
                  bitmask >>= 2;
 
4253
                else
 
4254
                {
 
4255
                  bitmask = 0xc0;
 
4256
 
 
4257
                  ptr ++;
 
4258
                }
 
4259
              }
 
4260
              break;
 
4261
 
 
4262
          case 4 :
 
4263
              bitmask = 0xf0 >> (bitoffset & 7);
 
4264
              dither  = Floyd4x4[y & 3];
 
4265
              if (z == 3)
 
4266
                r0 += 3;
 
4267
              else
 
4268
                r0 += 2 - z;
 
4269
 
 
4270
              for (x = xsize; x > 0; x --, r0 += 4)
 
4271
              {
 
4272
                if ((*r0 & 15) > dither[x & 3])
 
4273
                  *ptr ^= (bitmask & OnPixels[*r0]);
 
4274
                else
 
4275
                  *ptr ^= (bitmask & OffPixels[*r0]);
 
4276
 
 
4277
                if (bitmask == 0xf0)
 
4278
                  bitmask = 0x0f;
 
4279
                else
 
4280
                {
 
4281
                  bitmask = 0xf0;
 
4282
 
 
4283
                  ptr ++;
 
4284
                }
 
4285
              }
 
4286
              break;
 
4287
 
 
4288
          case 8 :
 
4289
              if (z == 3)
 
4290
              {
 
4291
                r0 += 3;
 
4292
                r1 += 3;
 
4293
              }
 
4294
              else
 
4295
              {
 
4296
                r0 += 2 - z;
 
4297
                r1 += 2 - z;
 
4298
              }
 
4299
 
 
4300
              for (x = xsize; x > 0; x --, r0 += 4, r1 += 4)
 
4301
              {
 
4302
                if (*r0 == *r1)
 
4303
                  *ptr++ = *r0;
 
4304
                else
 
4305
                  *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize;
 
4306
              }
 
4307
              break;
 
4308
        }
 
4309
        break;
 
4310
  }
 
4311
}
 
4312
 
 
4313
 
 
4314
/*
 
4315
 * 'make_lut()' - Make a lookup table given gamma and brightness values.
 
4316
 */
 
4317
 
 
4318
static void
 
4319
make_lut(cups_ib_t  *lut,               /* I - Lookup table */
 
4320
         int        colorspace,         /* I - Colorspace */
 
4321
         float      g,                  /* I - Image gamma */
 
4322
         float      b)                  /* I - Image brightness */
 
4323
{
 
4324
  int   i;                              /* Looping var */
 
4325
  int   v;                              /* Current value */
 
4326
 
 
4327
 
 
4328
  g = 1.0 / g;
 
4329
  b = 1.0 / b;
 
4330
 
 
4331
  for (i = 0; i < 256; i ++)
 
4332
  {
 
4333
    if (colorspace < 0)
 
4334
      v = 255.0 * b * (1.0 - pow(1.0 - (float)i / 255.0, g)) + 0.5;
 
4335
    else
 
4336
      v = 255.0 * (1.0 - b * (1.0 - pow((float)i / 255.0, g))) + 0.5;
 
4337
 
 
4338
    if (v < 0)
 
4339
      *lut++ = 0;
 
4340
    else if (v > 255)
 
4341
      *lut++ = 255;
 
4342
    else
 
4343
      *lut++ = v;
 
4344
  }
 
4345
}
 
4346
 
 
4347
 
 
4348
/*
 
4349
 * 'raster_cb()' - Validate the page header.
 
4350
 */
 
4351
 
 
4352
static int                              /* O - 0 if OK, -1 if not */
 
4353
raster_cb(
 
4354
    cups_page_header2_t *header,        /* IO - Raster header */
 
4355
    int                 preferred_bits) /* I  - Preferred bits per color */
 
4356
{
 
4357
 /*
 
4358
  * Ensure that colorimetric colorspaces use at least 8 bits per
 
4359
  * component...
 
4360
  */
 
4361
 
 
4362
  if ((header->cupsColorSpace == CUPS_CSPACE_CIEXYZ ||
 
4363
       header->cupsColorSpace == CUPS_CSPACE_CIELab ||
 
4364
       header->cupsColorSpace >= CUPS_CSPACE_ICC1) &&
 
4365
      header->cupsBitsPerColor < 8)
 
4366
    header->cupsBitsPerColor = 8;
 
4367
 
 
4368
  return (0);
 
4369
}
 
4370
 
 
4371
 
 
4372
/*
 
4373
 * End of "$Id$".
 
4374
 */