~ubuntu-branches/ubuntu/jaunty/ghostscript/jaunty-updates

« back to all changes in this revision

Viewing changes to src/gdevbit.c

  • Committer: Bazaar Package Importer
  • Author(s): Till Kamppeter
  • Date: 2009-01-20 16:40:45 UTC
  • mfrom: (1.1.10 upstream)
  • Revision ID: james.westby@ubuntu.com-20090120164045-lnfhi0n30o5lwhwa
Tags: 8.64.dfsg.1~svn9377-0ubuntu1
* New upstream release (SVN rev 9377)
   o Fixes many bugs concerning PDF rendering, to make the PDF printing
     workflow correctly working.
   o Fixes long-standing bugs in many drivers, like input paper tray and
     duplex options not working for the built-in PCL 4, 5, 5c, 5e, and
     6/XL drivers, PDF input not working for bjc600, bjc800, and cups
     output devices, several options not working and uninitialized
     memory with cups output device.
   o Merged nearly all patches of the Ubuntu and Debian packages upstream.
   o Fixes LP: #317810, LP: #314439, LP: #314018.
* debian/patches/03_libpaper_support.dpatch,
  debian/patches/11_gs-cjk_font_glyph_handling_fix.dpatch,
  debian/patches/12_gs-cjk_vertical_writing_metrics_fix.dpatch,
  debian/patches/13_gs-cjk_cjkps_examples.dpatch,
  debian/patches/20_bbox_segv_fix.dpatch,
  debian/patches/21_brother_7x0_gdi_fix.dpatch,
  debian/patches/22_epsn_margin_workaround.dpatch,
  debian/patches/24_gs_man_fix.dpatch,
  debian/patches/25_toolbin_insecure_tmp_usage_fix.dpatch,
  debian/patches/26_assorted_script_fixes.dpatch,
  debian/patches/29_gs_css_fix.dpatch,
  debian/patches/30_ps2pdf_man_improvement.dpatch,
  debian/patches/31_fix-gc-sigbus.dpatch,
  debian/patches/34_ftbfs-on-hurd-fix.dpatch,
  debian/patches/35_disable_libcairo.dpatch,
  debian/patches/38_pxl-duplex.dpatch,
  debian/patches/39_pxl-resolution.dpatch,
  debian/patches/42_gs-init-ps-delaybind-fix.dpatch,
  debian/patches/45_bjc600-bjc800-pdf-input.dpatch,
  debian/patches/48_cups-output-device-pdf-duplex-uninitialized-memory-fix.dpatch,
  debian/patches/50_lips4-floating-point-exception.dpatch,
  debian/patches/52_cups-device-logging.dpatch,
  debian/patches/55_pcl-input-slot-fix.dpatch,
  debian/patches/57_pxl-input-slot-fix.dpatch,
  debian/patches/60_pxl-cups-driver-pdf.dpatch,
  debian/patches/62_onebitcmyk-pdf.dpatch,
  debian/patches/65_too-big-temp-files-1.dpatch,
  debian/patches/67_too-big-temp-files-2.dpatch,
  debian/patches/70_take-into-account-data-in-stream-buffer-before-refill.dpatch:
  Removed, applied upstream.
* debian/patches/01_docdir_fix_for_debian.dpatch,
  debian/patches/02_gs_man_fix_debian.dpatch,
  debian/patches/01_docdir-fix-for-debian.dpatch,
  debian/patches/02_docdir-fix-for-debian.dpatch: Renamed patches to
  make merging with Debian easier.
* debian/patches/32_improve-handling-of-media-size-changes-from-gv.dpatch, 
  debian/patches/33_bad-params-to-xinitimage-on-large-bitmaps.dpatch:
  regenerated for new source directory structure.
* debian/rules: Corrected paths to remove cidfmap (it is in Resource/Init/
  in GS 8.64) and to install headers (source paths are psi/ and base/ now).
* debian/rules: Remove all fontmaps, as DeFoMa replaces them.
* debian/local/pdftoraster/pdftoraster.c,
  debian/local/pdftoraster/pdftoraster.convs, debian/rules: Removed
  added pdftoraster filter and use the one which comes with Ghostscript.
* debian/ghostscript.links: s/8.63/8.64/

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (C) 2001-2006 Artifex Software, Inc.
2
 
   All Rights Reserved.
3
 
  
4
 
   This software is provided AS-IS with no warranty, either express or
5
 
   implied.
6
 
 
7
 
   This software is distributed under license and may not be copied, modified
8
 
   or distributed except as expressly authorized under the terms of that
9
 
   license.  Refer to licensing information at http://www.artifex.com/
10
 
   or contact Artifex Software, Inc.,  7 Mt. Lassen Drive - Suite A-134,
11
 
   San Rafael, CA  94903, U.S.A., +1(415)492-9861, for further information.
12
 
*/
13
 
 
14
 
/* $Id: gdevbit.c 8790 2008-06-09 07:33:57Z leonardo $ */
15
 
/* "Plain bits" devices to measure rendering time. */
16
 
 
17
 
#include "math_.h"
18
 
#include "gdevprn.h"
19
 
#include "gsparam.h"
20
 
#include "gscrd.h"
21
 
#include "gscrdp.h"
22
 
#include "gxlum.h"
23
 
#include "gxdcconv.h"
24
 
#include "gdevdcrd.h"
25
 
#include "gsutil.h" /* for bittags hack */
26
 
 
27
 
/* Define the device parameters. */
28
 
#ifndef X_DPI
29
 
#  define X_DPI 72
30
 
#endif
31
 
#ifndef Y_DPI
32
 
#  define Y_DPI 72
33
 
#endif
34
 
 
35
 
/* The device descriptor */
36
 
static dev_proc_get_color_mapping_procs(bittag_get_color_mapping_procs);
37
 
static dev_proc_map_rgb_color(bittag_rgb_map_rgb_color);
38
 
static dev_proc_map_color_rgb(bittag_map_color_rgb);
39
 
static dev_proc_put_params(bittag_put_params);
40
 
static dev_proc_map_rgb_color(bit_mono_map_color);
41
 
#if 0 /* unused */
42
 
static dev_proc_map_rgb_color(bit_forcemono_map_rgb_color);
43
 
#endif
44
 
static dev_proc_map_color_rgb(bit_map_color_rgb);
45
 
static dev_proc_map_cmyk_color(bit_map_cmyk_color);
46
 
static dev_proc_get_params(bit_get_params);
47
 
static dev_proc_put_params(bit_put_params);
48
 
static dev_proc_print_page(bit_print_page);
49
 
 
50
 
#define bit_procs(encode_color)\
51
 
{       gdev_prn_open,\
52
 
        gx_default_get_initial_matrix,\
53
 
        NULL,   /* sync_output */\
54
 
        gdev_prn_output_page,\
55
 
        gdev_prn_close,\
56
 
        encode_color,   /* map_rgb_color */\
57
 
        bit_map_color_rgb,      /* map_color_rgb */\
58
 
        NULL,   /* fill_rectangle */\
59
 
        NULL,   /* tile_rectangle */\
60
 
        NULL,   /* copy_mono */\
61
 
        NULL,   /* copy_color */\
62
 
        NULL,   /* draw_line */\
63
 
        NULL,   /* get_bits */\
64
 
        bit_get_params,\
65
 
        bit_put_params,\
66
 
        encode_color,   /* map_cmyk_color */\
67
 
        NULL,   /* get_xfont_procs */\
68
 
        NULL,   /* get_xfont_device */\
69
 
        NULL,   /* map_rgb_alpha_color */\
70
 
        gx_page_device_get_page_device, /* get_page_device */\
71
 
        NULL,   /* get_alpha_bits */\
72
 
        NULL,   /* copy_alpha */\
73
 
        NULL,   /* get_band */\
74
 
        NULL,   /* copy_rop */\
75
 
        NULL,   /* fill_path */\
76
 
        NULL,   /* stroke_path */\
77
 
        NULL,   /* fill_mask */\
78
 
        NULL,   /* fill_trapezoid */\
79
 
        NULL,   /* fill_parallelogram */\
80
 
        NULL,   /* fill_triangle */\
81
 
        NULL,   /* draw_thin_line */\
82
 
        NULL,   /* begin_image */\
83
 
        NULL,   /* image_data */\
84
 
        NULL,   /* end_image */\
85
 
        NULL,   /* strip_tile_rectangle */\
86
 
        NULL,   /* strip_copy_rop */\
87
 
        NULL,   /* get_clipping_box */\
88
 
        NULL,   /* begin_typed_image */\
89
 
        NULL,   /* get_bits_rectangle */\
90
 
        NULL,   /* map_color_rgb_alpha */\
91
 
        NULL,   /* create_compositor */\
92
 
        NULL,   /* get_hardware_params */\
93
 
        NULL,   /* text_begin */\
94
 
        NULL,   /* finish_copydevice */\
95
 
        NULL,   /* begin_transparency_group */\
96
 
        NULL,   /* end_transparency_group */\
97
 
        NULL,   /* begin_transparency_mask */\
98
 
        NULL,   /* end_transparency_mask */\
99
 
        NULL,   /* discard_transparency_layer */\
100
 
        NULL,   /* get_color_mapping_procs */\
101
 
        NULL,   /* get_color_comp_index */\
102
 
        encode_color,           /* encode_color */\
103
 
        bit_map_color_rgb       /* decode_color */\
104
 
}
105
 
 
106
 
/*
107
 
 * The following macro is used in get_params and put_params to determine the
108
 
 * num_components for the current device. It works using the device name
109
 
 * character after "bit" which is either '\0', 'r', or 'c'. Any new devices
110
 
 * that are added to this module must modify this macro to return the
111
 
 * correct num_components. This is needed to support the ForceMono
112
 
 * parameter, which alters dev->num_components.
113
 
 */
114
 
#define REAL_NUM_COMPONENTS(dev) (dev->dname[3] == 'c' ? 4 : \
115
 
                                  dev->dname[3] == 'r' ? 3 : 1)
116
 
 
117
 
static const gx_device_procs bitmono_procs =
118
 
bit_procs(bit_mono_map_color);
119
 
const gx_device_printer gs_bit_device =
120
 
{prn_device_body(gx_device_printer, bitmono_procs, "bit",
121
 
                 DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
122
 
                 X_DPI, Y_DPI,
123
 
                 0, 0, 0, 0,    /* margins */
124
 
                 1, 1, 1, 0, 2, 1, bit_print_page)
125
 
};
126
 
 
127
 
static const gx_device_procs bitrgb_procs =
128
 
bit_procs(gx_default_rgb_map_rgb_color);
129
 
const gx_device_printer gs_bitrgb_device =
130
 
{prn_device_body(gx_device_printer, bitrgb_procs, "bitrgb",
131
 
                 DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
132
 
                 X_DPI, Y_DPI,
133
 
                 0, 0, 0, 0,    /* margins */
134
 
                 3, 4, 1, 1, 2, 2, bit_print_page)
135
 
};
136
 
 
137
 
static const gx_device_procs bitcmyk_procs =
138
 
bit_procs(bit_map_cmyk_color);
139
 
const gx_device_printer gs_bitcmyk_device =
140
 
{prn_device_body(gx_device_printer, bitcmyk_procs, "bitcmyk",
141
 
                 DEFAULT_WIDTH_10THS, DEFAULT_HEIGHT_10THS,
142
 
                 X_DPI, Y_DPI,
143
 
                 0, 0, 0, 0,    /* margins */
144
 
                 4, 4, 1, 1, 2, 2, bit_print_page)
145
 
};
146
 
 
147
 
static const gx_device_procs bitrgbtags_procs =
148
 
    { 
149
 
        gdev_prn_open,                        /* open_device */
150
 
        gx_default_get_initial_matrix,        /* initial_matrix */
151
 
        ((void *)0),                        /* sync_output */
152
 
        gdev_prn_output_page,                 /* output page */
153
 
        gdev_prn_close,                       /* close_device */
154
 
        bittag_rgb_map_rgb_color,             /* map rgb color */
155
 
        bittag_map_color_rgb,                 /* map color rgb */
156
 
        ((void *)0),                        /* fill_rectangle */
157
 
        ((void *)0),                        /* tile rectangle */
158
 
        ((void *)0),                        /* copy mono */
159
 
        ((void *)0),                        /* copy color */
160
 
        ((void *)0),                        /* obsolete draw line */
161
 
        ((void *)0),                        /* get_bits */
162
 
        gdev_prn_get_params,                  /* get params */
163
 
        bittag_put_params,                    /* put params */
164
 
        bittag_rgb_map_rgb_color,             /* map_cmyk_color */
165
 
        ((void *)0),                        /* get_xfonts */
166
 
        ((void *)0),                        /* get_xfont_device */
167
 
        ((void *)0),                        /* map_rgb_alpha_color */
168
 
        gx_page_device_get_page_device,       /* get_page_device */
169
 
        ((void *)0),                        /* get_alpha_bits */
170
 
        ((void *)0),                        /* copy_alpha */
171
 
        ((void *)0),                        /* get_band */
172
 
        ((void *)0),                        /* copy_rop */
173
 
        ((void *)0),                       /* fill_path */
174
 
        ((void *)0),                       /* stroke_path */
175
 
        ((void *)0),                       /* fill_mask */
176
 
        ((void *)0),                        /* fill_trapezoid */
177
 
        ((void *)0),                        /* fill_parallelogram */
178
 
        ((void *)0),                        /* fill_triangle */
179
 
        ((void *)0),                        /* draw_thin_line */
180
 
        ((void *)0),                        /* begin_image */
181
 
        ((void *)0),                        /* image_data */
182
 
        ((void *)0),                        /* end_image */
183
 
        ((void *)0),                        /* strip_tile_rectangle */
184
 
        ((void *)0),                        /* strip_copy_rop */
185
 
        ((void *)0),                        /* get_clipping_box */
186
 
        ((void *)0),                        /* begin_typed_image */
187
 
        ((void *)0),                        /* get_bits_rectangle */
188
 
        ((void *)0),                        /* map_color_rgb_alpha */
189
 
        ((void *)0),                       /* create_compositor */
190
 
        ((void *)0),                       /* get_hardware_params */
191
 
        ((void *)0),                       /* text_begin */
192
 
        ((void *)0),                       /* finish_copydevice */
193
 
        ((void *)0),                       /* begin_transparency_group */
194
 
        ((void *)0),                       /* end_transparency_group */
195
 
        ((void *)0),                       /* begin_transparency_mask */
196
 
        ((void *)0),                       /* end_transparency_mask */
197
 
        ((void *)0),                       /* discard_transparency_layer */
198
 
        bittag_get_color_mapping_procs,      /* get_color_mapping_procs */
199
 
        ((void *)0),                       /* get_color_comp_index */
200
 
        bittag_rgb_map_rgb_color,            /* encode_color */
201
 
        bittag_map_color_rgb                 /* decode_color */
202
 
    };
203
 
 
204
 
const gx_device_printer gs_bitrgbtags_device =
205
 
    {
206
 
        sizeof(gx_device_printer),
207
 
        &bitrgbtags_procs,
208
 
        "bitrgbtags",
209
 
        0 ,                             /* memory */
210
 
        &st_device_printer,
211
 
        0 ,                             /* stype_is_dynamic */
212
 
        0 ,                             /* finalize */
213
 
        { 0 } ,                         /* rc header */
214
 
        0 ,                             /* retained */
215
 
        0 ,                             /* is open */
216
 
        0,                              /* max_fill_band */
217
 
        {                               /* color infor */
218
 
            4,                          /* max_components */
219
 
            4,                          /* num_components */
220
 
            GX_CINFO_POLARITY_ADDITIVE, /* polarity */
221
 
            32,                         /* depth */                        
222
 
            GX_CINFO_COMP_NO_INDEX,     /* gray index */
223
 
            255 ,                         /* max_gray */
224
 
            255 ,                         /* max_colors */
225
 
            256 ,                         /* dither grays */
226
 
            256 ,                         /* dither colors */
227
 
            { 1, 1 } ,                  /* antialiasing */
228
 
            GX_CINFO_UNKNOWN_SEP_LIN,   /* sep and linear */
229
 
            { 0 } ,                     /* comp shift */
230
 
            { 0 } ,                     /* comp bits */
231
 
            { 0 } ,                     /* comp mask */
232
 
            ( "DeviceRGB" ),            /* color model name */
233
 
            GX_CINFO_OPMODE_UNKNOWN ,   /* overprint mode */
234
 
            0                           /* process comps */
235
 
        },
236
 
        { 
237
 
            ((gx_color_index)(~0)),
238
 
            ((gx_color_index)(~0)) 
239
 
        },
240
 
        (int)((float)(85) * (X_DPI) / 10 + 0.5),
241
 
        (int)((float)(110) * (Y_DPI) / 10 + 0.5),
242
 
        0,
243
 
        { 
244
 
            (float)(((((int)((float)(85) * (X_DPI) / 10 + 0.5)) * 72.0 + 0.5) - 0.5) / (X_DPI)) ,
245
 
            (float)(((((int)((float)(110) * (Y_DPI) / 10 + 0.5)) * 72.0 + 0.5) - 0.5) / (Y_DPI)) },
246
 
        {
247
 
            0,
248
 
            0,
249
 
            0,
250
 
            0 
251
 
        } ,
252
 
        0 ,
253
 
        { X_DPI, Y_DPI } ,
254
 
        { X_DPI, Y_DPI },
255
 
        {(float)(-(0) * (X_DPI)),
256
 
         (float)(-(0) * (Y_DPI))},
257
 
        {(float)((0) * 72.0),
258
 
         (float)((0) * 72.0),
259
 
         (float)((0) * 72.0),
260
 
         (float)((0) * 72.0)},
261
 
        0 ,
262
 
        0 ,
263
 
        1 ,
264
 
        0 ,
265
 
        0 ,
266
 
        0 ,
267
 
        0 ,
268
 
        0,
269
 
        0,
270
 
        {false},
271
 
        { 
272
 
            gx_default_install,
273
 
            gx_default_begin_page,
274
 
            gx_default_end_page
275
 
        },
276
 
        { 0 },
277
 
        { 0 },
278
 
        { bit_print_page,
279
 
          gx_default_print_page_copies,
280
 
          { gx_default_create_buf_device,
281
 
            gx_default_size_buf_device,
282
 
            gx_default_setup_buf_device,
283
 
            gx_default_destroy_buf_device },
284
 
          gx_default_get_space_params,
285
 
          gx_default_start_render_thread,
286
 
          gx_default_open_render_device,
287
 
          gx_default_close_render_device,
288
 
          gx_default_buffer_page },
289
 
        { 
290
 
            PRN_MAX_BITMAP,
291
 
            PRN_BUFFER_SPACE,
292
 
            { 0, 0, 0 },
293
 
            0 ,
294
 
            BandingAlways },
295
 
        { 0 },
296
 
        0 ,
297
 
        0 ,
298
 
        0 ,
299
 
        -1,
300
 
        0 ,
301
 
        0,
302
 
        0,
303
 
        0,
304
 
        0,
305
 
        0,
306
 
        0,
307
 
        0,
308
 
        0 ,
309
 
        0,
310
 
        0,
311
 
        0
312
 
    };
313
 
 
314
 
static void
315
 
cmyk_cs_to_rgb_cm(gx_device * dev, frac c, frac m, frac y, frac k, frac out[])
316
 
{
317
 
    color_cmyk_to_rgb(c, m, y, k, NULL, out);
318
 
};
319
 
 
320
 
static void
321
 
private_rgb_cs_to_rgb_cm(gx_device * dev, const gs_imager_state *pis,
322
 
                                  frac r, frac g, frac b, frac out[])
323
 
{
324
 
    out[0] = r;
325
 
    out[1] = g;
326
 
    out[2] = b;
327
 
}
328
 
 
329
 
static void
330
 
gray_cs_to_rgb_cm(gx_device * dev, frac gray, frac out[])
331
 
{
332
 
    out[0] = out[1] = out[2] = gray;
333
 
}
334
 
 
335
 
 
336
 
static const gx_cm_color_map_procs bittag_DeviceRGB_procs = {
337
 
    gray_cs_to_rgb_cm, private_rgb_cs_to_rgb_cm, cmyk_cs_to_rgb_cm
338
 
};
339
 
 
340
 
static const gx_cm_color_map_procs *
341
 
bittag_get_color_mapping_procs(const gx_device *dev)
342
 
{
343
 
    return &bittag_DeviceRGB_procs;
344
 
}
345
 
 
346
 
static gx_color_index
347
 
bittag_rgb_map_rgb_color(gx_device * dev, const gx_color_value cv[])
348
 
{
349
 
    return
350
 
        ((cv[2]) >> ((sizeof(gx_color_value) * 8) - 8)) +
351
 
        ((uint) ((cv[1]) >> ((sizeof(gx_color_value) * 8) - 8)) << 8) +
352
 
        ((ulong) ((cv[0]) >> ((sizeof(gx_color_value) * 8) - 8)) << 16) +
353
 
        ((ulong)gs_current_object_tag() << 24);
354
 
}
355
 
 
356
 
static int
357
 
bittag_map_color_rgb(gx_device * dev, gx_color_index color, gx_color_value cv[4])
358
 
{
359
 
    int depth = 24;
360
 
    int ncomp = 3;
361
 
    int bpc = depth / ncomp;
362
 
    uint mask = (1 << bpc) - 1;
363
 
 
364
 
#define cvalue(c) ((gx_color_value)((ulong)(c) * gx_max_color_value / mask))
365
 
 
366
 
    gx_color_index cshift = color;
367
 
    cv[2] = cvalue(cshift & mask);
368
 
    cshift >>= bpc;
369
 
    cv[1] = cvalue(cshift & mask);
370
 
    cshift >>= bpc;
371
 
    cv[0] = cvalue(cshift & mask);
372
 
    return 0;
373
 
#undef cvalue
374
 
}
375
 
 
376
 
/* Map gray to color. */
377
 
/* Note that 1-bit monochrome is a special case. */
378
 
static gx_color_index
379
 
bit_mono_map_color(gx_device * dev, const gx_color_value cv[])
380
 
{
381
 
    int bpc = dev->color_info.depth;
382
 
    int drop = sizeof(gx_color_value) * 8 - bpc;
383
 
    gx_color_value gray = cv[0];
384
 
 
385
 
    return (bpc == 1 ? gx_max_color_value - gray : gray) >> drop;
386
 
}
387
 
 
388
 
#if 0 /* unused */
389
 
/* Map RGB to gray shade. */
390
 
/* Only used in CMYK mode when put_params has set ForceMono=1 */
391
 
static gx_color_index
392
 
bit_forcemono_map_rgb_color(gx_device * dev, const gx_color_value cv[])
393
 
{
394
 
    gx_color_value color;
395
 
    int bpc = dev->color_info.depth / 4;        /* This function is used in CMYK mode */
396
 
    int drop = sizeof(gx_color_value) * 8 - bpc;
397
 
    gx_color_value gray, red, green, blue;
398
 
    red = cv[0]; green = cv[1]; blue = cv[2];
399
 
    gray = red;
400
 
    if ((red != green) || (green != blue))
401
 
        gray = (red * (unsigned long)lum_red_weight +
402
 
             green * (unsigned long)lum_green_weight +
403
 
             blue * (unsigned long)lum_blue_weight +
404
 
             (lum_all_weights / 2))
405
 
                / lum_all_weights;
406
 
 
407
 
    color = (gx_max_color_value - gray) >> drop;        /* color is in K channel */
408
 
    return color;
409
 
}
410
 
#endif
411
 
 
412
 
/* Map color to RGB.  This has 3 separate cases, but since it is rarely */
413
 
/* used, we do a case test rather than providing 3 separate routines. */
414
 
static int
415
 
bit_map_color_rgb(gx_device * dev, gx_color_index color, gx_color_value cv[4])
416
 
{
417
 
    int depth = dev->color_info.depth;
418
 
    int ncomp = REAL_NUM_COMPONENTS(dev);
419
 
    int bpc = depth / ncomp;
420
 
    uint mask = (1 << bpc) - 1;
421
 
 
422
 
#define cvalue(c) ((gx_color_value)((ulong)(c) * gx_max_color_value / mask))
423
 
 
424
 
    switch (ncomp) {
425
 
        case 1:         /* gray */
426
 
            cv[0] =
427
 
                (depth == 1 ? (color ? 0 : gx_max_color_value) :
428
 
                 cvalue(color));
429
 
            break;
430
 
        case 3:         /* RGB */
431
 
            {
432
 
                gx_color_index cshift = color;
433
 
 
434
 
                cv[2] = cvalue(cshift & mask);
435
 
                cshift >>= bpc;
436
 
                cv[1] = cvalue(cshift & mask);
437
 
                cv[0] = cvalue(cshift >> bpc);
438
 
            }
439
 
            break;
440
 
        case 4:         /* CMYK */
441
 
            /* Map CMYK back to RGB. */
442
 
            {
443
 
                gx_color_index cshift = color;
444
 
                uint c, m, y, k;
445
 
 
446
 
                k = cshift & mask;
447
 
                cshift >>= bpc;
448
 
                y = cshift & mask;
449
 
                cshift >>= bpc;
450
 
                m = cshift & mask;
451
 
                c = cshift >> bpc;
452
 
                /* We use our improved conversion rule.... */
453
 
                cv[0] = cvalue((mask - c) * (mask - k) / mask);
454
 
                cv[1] = cvalue((mask - m) * (mask - k) / mask);
455
 
                cv[2] = cvalue((mask - y) * (mask - k) / mask);
456
 
            }
457
 
            break;
458
 
    }
459
 
    return 0;
460
 
#undef cvalue
461
 
}
462
 
 
463
 
/* Map CMYK to color. */
464
 
static gx_color_index
465
 
bit_map_cmyk_color(gx_device * dev, const gx_color_value cv[])
466
 
{
467
 
    int bpc = dev->color_info.depth / 4;
468
 
    int drop = sizeof(gx_color_value) * 8 - bpc;
469
 
    gx_color_index color =
470
 
    (((((((gx_color_index) cv[0] >> drop) << bpc) +
471
 
        (cv[1] >> drop)) << bpc) +
472
 
      (cv[2] >> drop)) << bpc) +
473
 
    (cv[3] >> drop);
474
 
 
475
 
    return (color == gx_no_color_index ? color ^ 1 : color);
476
 
}
477
 
 
478
 
static int
479
 
bittag_put_params(gx_device * pdev, gs_param_list * plist)
480
 
{
481
 
    gs_enable_object_tagging();
482
 
    return gdev_prn_put_params(pdev, plist);
483
 
}
484
 
/* Get parameters.  We provide a default CRD. */
485
 
static int
486
 
bit_get_params(gx_device * pdev, gs_param_list * plist)
487
 
{
488
 
    int code, ecode;
489
 
    /*
490
 
     * The following is a hack to get the original num_components.
491
 
     * See comment above.
492
 
     */
493
 
    int real_ncomps = REAL_NUM_COMPONENTS(pdev);
494
 
    int ncomps = pdev->color_info.num_components;
495
 
    int forcemono = (ncomps == real_ncomps ? 0 : 1);
496
 
 
497
 
    /*
498
 
     * Temporarily set num_components back to the "real" value to avoid
499
 
     * confusing those that rely on it.
500
 
     */
501
 
    pdev->color_info.num_components = real_ncomps;
502
 
 
503
 
    ecode = gdev_prn_get_params(pdev, plist);
504
 
    code = sample_device_crd_get_params(pdev, plist, "CRDDefault");
505
 
    if (code < 0)
506
 
            ecode = code;
507
 
    if ((code = param_write_int(plist, "ForceMono", &forcemono)) < 0) {
508
 
        ecode = code;
509
 
    }
510
 
 
511
 
    /* Restore the working num_components */
512
 
    pdev->color_info.num_components = ncomps;
513
 
 
514
 
    return ecode;
515
 
}
516
 
 
517
 
/* Set parameters.  We allow setting the number of bits per component. */
518
 
/* Also, ForceMono=1 forces monochrome output from RGB/CMYK devices. */
519
 
static int
520
 
bit_put_params(gx_device * pdev, gs_param_list * plist)
521
 
{
522
 
    gx_device_color_info save_info;
523
 
    int ncomps = pdev->color_info.num_components;
524
 
    int real_ncomps = REAL_NUM_COMPONENTS(pdev);
525
 
    int bpc = pdev->color_info.depth / real_ncomps;
526
 
    int v;
527
 
    int ecode = 0;
528
 
    int code;
529
 
    static const byte depths[4][16] = {
530
 
        {1, 2, 0, 4, 8, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 16},
531
 
        {0},
532
 
        {4, 8, 0, 16, 16, 0, 0, 24, 0, 0, 0, 40, 0, 0, 0, 48},
533
 
        {4, 8, 0, 16, 32, 0, 0, 32, 0, 0, 0, 48, 0, 0, 0, 64}
534
 
    };
535
 
    const char *vname;
536
 
 
537
 
    /*
538
 
     * Temporarily set num_components back to the "real" value to avoid
539
 
     * confusing those that rely on it.
540
 
     */
541
 
    pdev->color_info.num_components = real_ncomps;
542
 
 
543
 
    if ((code = param_read_int(plist, (vname = "GrayValues"), &v)) != 1 ||
544
 
        (code = param_read_int(plist, (vname = "RedValues"), &v)) != 1 ||
545
 
        (code = param_read_int(plist, (vname = "GreenValues"), &v)) != 1 ||
546
 
        (code = param_read_int(plist, (vname = "BlueValues"), &v)) != 1
547
 
        ) {
548
 
        if (code < 0)
549
 
            ecode = code;
550
 
        else
551
 
            switch (v) {
552
 
                case   2: bpc = 1; break;
553
 
                case   4: bpc = 2; break;
554
 
                case  16: bpc = 4; break;
555
 
                case  32: bpc = 5; break;
556
 
                case 256: bpc = 8; break;
557
 
                case 4096: bpc = 12; break;
558
 
                case 65536: bpc = 16; break;
559
 
                default:
560
 
                    param_signal_error(plist, vname,
561
 
                                       ecode = gs_error_rangecheck);
562
 
            }
563
 
    }
564
 
 
565
 
    switch (code = param_read_int(plist, (vname = "ForceMono"), &v)) {
566
 
    case 0:
567
 
        if (v == 1) {
568
 
            ncomps = 1;
569
 
            break;
570
 
        }
571
 
        else if (v == 0) {
572
 
            ncomps = real_ncomps;
573
 
            break;
574
 
        }
575
 
        code = gs_error_rangecheck;
576
 
    default:
577
 
        ecode = code;
578
 
        param_signal_error(plist, vname, ecode);
579
 
    case 1:
580
 
        break;
581
 
    }
582
 
    if (ecode < 0)
583
 
        return ecode;
584
 
 
585
 
    /*
586
 
     * Save the color_info in case gdev_prn_put_params fails, and for
587
 
     * comparison.  Note that depth is computed from real_ncomps.
588
 
     */
589
 
    save_info = pdev->color_info;
590
 
    pdev->color_info.depth = depths[real_ncomps - 1][bpc - 1];
591
 
    pdev->color_info.max_gray = pdev->color_info.max_color =
592
 
        (pdev->color_info.dither_grays =
593
 
         pdev->color_info.dither_colors =
594
 
         (1 << bpc)) - 1;
595
 
    ecode = gdev_prn_put_params(pdev, plist);
596
 
    if (ecode < 0) {
597
 
        pdev->color_info = save_info;
598
 
        return ecode;
599
 
    }
600
 
    /* Now restore/change num_components. This is done after other      */
601
 
    /* processing since it is used in gx_default_put_params             */
602
 
    pdev->color_info.num_components = ncomps;
603
 
    if (pdev->color_info.depth != save_info.depth ||
604
 
        pdev->color_info.num_components != save_info.num_components
605
 
        ) {
606
 
        gs_closedevice(pdev);
607
 
    }
608
 
    /* Reset the map_cmyk_color procedure if appropriate. */
609
 
    if (dev_proc(pdev, map_cmyk_color) == cmyk_1bit_map_cmyk_color ||
610
 
        dev_proc(pdev, map_cmyk_color) == cmyk_8bit_map_cmyk_color ||
611
 
        dev_proc(pdev, map_cmyk_color) == bit_map_cmyk_color) {
612
 
        set_dev_proc(pdev, map_cmyk_color,
613
 
                     pdev->color_info.depth == 4 ? cmyk_1bit_map_cmyk_color :
614
 
                     pdev->color_info.depth == 32 ? cmyk_8bit_map_cmyk_color :
615
 
                     bit_map_cmyk_color);
616
 
    }
617
 
    /* Reset the sparable and linear shift, masks, bits. */
618
 
    set_linear_color_bits_mask_shift(pdev);
619
 
    pdev->color_info.separable_and_linear = GX_CINFO_SEP_LIN;
620
 
    return 0;
621
 
}
622
 
 
623
 
/* Send the page to the printer. */
624
 
static int
625
 
bit_print_page(gx_device_printer * pdev, FILE * prn_stream)
626
 
{                               /* Just dump the bits on the file. */
627
 
    /* If the file is 'nul', don't even do the writes. */
628
 
    int line_size = gdev_mem_bytes_per_scan_line((gx_device *) pdev);
629
 
    byte *in = gs_alloc_bytes(pdev->memory, line_size, "bit_print_page(in)");
630
 
    byte *data;
631
 
    int nul = !strcmp(pdev->fname, "nul") || !strcmp(pdev->fname, "/dev/null");
632
 
    int lnum = 0, bottom = pdev->height;
633
 
 
634
 
    if (in == 0)
635
 
        return_error(gs_error_VMerror);
636
 
    for (; lnum < bottom; ++lnum) {
637
 
        gdev_prn_get_bits(pdev, lnum, in, &data);
638
 
        if (!nul)
639
 
            fwrite(data, 1, line_size, prn_stream);
640
 
    }
641
 
    gs_free_object(pdev->memory, in, "bit_print_page(in)");
642
 
    return 0;
643
 
}