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

« back to all changes in this revision

Viewing changes to base/gdevdgbr.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
/* $Id: gdevdgbr.c 8250 2007-09-25 13:31:24Z giles $ */
 
14
/* Default implementation of device get_bits[_rectangle] */
 
15
#include "memory_.h"
 
16
#include "gx.h"
 
17
#include "gserrors.h"
 
18
#include "gxdevice.h"
 
19
#include "gxdevmem.h"
 
20
#include "gxgetbit.h"
 
21
#include "gxlum.h"
 
22
#include "gdevmem.h"
 
23
 
 
24
int
 
25
gx_no_get_bits(gx_device * dev, int y, byte * data, byte ** actual_data)
 
26
{
 
27
    return_error(gs_error_unknownerror);
 
28
}
 
29
int
 
30
gx_default_get_bits(gx_device * dev, int y, byte * data, byte ** actual_data)
 
31
{       /*
 
32
         * Hand off to get_bits_rectangle, being careful to avoid a
 
33
         * possible recursion loop.
 
34
         */
 
35
    dev_proc_get_bits((*save_get_bits)) = dev_proc(dev, get_bits);
 
36
    gs_int_rect rect;
 
37
    gs_get_bits_params_t params;
 
38
    int code;
 
39
 
 
40
    rect.p.x = 0, rect.p.y = y;
 
41
    rect.q.x = dev->width, rect.q.y = y + 1;
 
42
    params.options =
 
43
        (actual_data ? GB_RETURN_POINTER : 0) | GB_RETURN_COPY |
 
44
        (GB_ALIGN_STANDARD | GB_OFFSET_0 | GB_RASTER_STANDARD |
 
45
    /* No depth specified, we always use native colors. */
 
46
         GB_PACKING_CHUNKY | GB_COLORS_NATIVE | GB_ALPHA_NONE);
 
47
    params.x_offset = 0;
 
48
    params.raster = bitmap_raster(dev->width * dev->color_info.depth);
 
49
    params.data[0] = data;
 
50
    set_dev_proc(dev, get_bits, gx_no_get_bits);
 
51
    code = (*dev_proc(dev, get_bits_rectangle))
 
52
        (dev, &rect, &params, NULL);
 
53
    if (actual_data)
 
54
        *actual_data = params.data[0];
 
55
    set_dev_proc(dev, get_bits, save_get_bits);
 
56
    return code;
 
57
}
 
58
 
 
59
/*
 
60
 * Determine whether we can satisfy a request by simply using the stored
 
61
 * representation.  dev is used only for color_info.{num_components, depth}.
 
62
 */
 
63
static bool
 
64
requested_includes_stored(const gx_device *dev,
 
65
                          const gs_get_bits_params_t *requested,
 
66
                          const gs_get_bits_params_t *stored)
 
67
{
 
68
    gs_get_bits_options_t both = requested->options & stored->options;
 
69
 
 
70
    if (!(both & GB_PACKING_ALL))
 
71
        return false;
 
72
    if (stored->options & GB_SELECT_PLANES) {
 
73
        /*
 
74
         * The device only provides a subset of the planes.
 
75
         * Make sure it provides all the requested ones.
 
76
         */
 
77
        int i;
 
78
        int n = (stored->options & GB_PACKING_BIT_PLANAR ?
 
79
                 dev->color_info.depth : dev->color_info.num_components);
 
80
 
 
81
        if (!(requested->options & GB_SELECT_PLANES) ||
 
82
            !(both & (GB_PACKING_PLANAR || GB_PACKING_BIT_PLANAR))
 
83
            )
 
84
            return false;
 
85
        for (i = 0; i < n; ++i)
 
86
            if (requested->data[i] && !stored->data[i])
 
87
                return false;
 
88
    }
 
89
    if (both & GB_COLORS_NATIVE)
 
90
        return true;
 
91
    if (both & GB_COLORS_STANDARD_ALL) {
 
92
        if ((both & GB_ALPHA_ALL) && (both & GB_DEPTH_ALL))
 
93
            return true;
 
94
    }
 
95
    return false;
 
96
}
 
97
 
 
98
/*
 
99
 * Try to implement get_bits_rectangle by returning a pointer.
 
100
 * Note that dev is used only for computing the default raster
 
101
 * and for color_info.depth.
 
102
 * This routine does not check x or h for validity.
 
103
 */
 
104
int
 
105
gx_get_bits_return_pointer(gx_device * dev, int x, int h,
 
106
                           gs_get_bits_params_t *params,
 
107
                           const gs_get_bits_params_t *stored,
 
108
                           byte * stored_base)
 
109
{
 
110
    gs_get_bits_options_t options = params->options;
 
111
    gs_get_bits_options_t both = options & stored->options;
 
112
 
 
113
    if (!(options & GB_RETURN_POINTER) ||
 
114
        !requested_includes_stored(dev, params, stored)
 
115
        )
 
116
        return -1;
 
117
    /*
 
118
     * See whether we can return the bits in place.  Note that even if
 
119
     * OFFSET_ANY isn't set, x_offset and x don't have to be equal: their
 
120
     * bit offsets only have to match modulo align_bitmap_mod * 8 (to
 
121
     * preserve alignment) if ALIGN_ANY isn't set, or mod 8 (since
 
122
     * byte alignment is always required) if ALIGN_ANY is set.
 
123
     */
 
124
    {
 
125
        int depth = dev->color_info.depth;
 
126
        /*
 
127
         * For PLANAR devices, we assume that each plane consists of
 
128
         * depth/num_components bits.  This is wrong in general, but if
 
129
         * the device wants something else, it should implement
 
130
         * get_bits_rectangle itself.
 
131
         */
 
132
        uint dev_raster =
 
133
            (both & GB_PACKING_CHUNKY ?
 
134
               gx_device_raster(dev, true) :
 
135
             both & GB_PACKING_PLANAR ?
 
136
               bitmap_raster(dev->color_info.depth /
 
137
                             dev->color_info.num_components * dev->width) :
 
138
             both & GB_PACKING_BIT_PLANAR ?
 
139
               bitmap_raster(dev->width) :
 
140
             0 /* not possible */);
 
141
        uint raster =
 
142
            (options & (GB_RASTER_STANDARD | GB_RASTER_ANY) ? dev_raster :
 
143
             params->raster);
 
144
        byte *base;
 
145
 
 
146
        if (h <= 1 || raster == dev_raster) {
 
147
            int x_offset =
 
148
                (options & GB_OFFSET_ANY ? x :
 
149
                 options & GB_OFFSET_0 ? 0 : params->x_offset);
 
150
 
 
151
            if (x_offset == x) {
 
152
                base = stored_base;
 
153
                params->x_offset = x;
 
154
            } else {
 
155
                uint align_mod =
 
156
                    (options & GB_ALIGN_ANY ? 8 : align_bitmap_mod * 8);
 
157
                int bit_offset = x - x_offset;
 
158
                int bytes;
 
159
 
 
160
                if (bit_offset & (align_mod - 1))
 
161
                    return -1;  /* can't align */
 
162
                if (depth & (depth - 1)) {
 
163
                    /* step = lcm(depth, align_mod) */
 
164
                    int step = depth / igcd(depth, align_mod) * align_mod;
 
165
 
 
166
                    bytes = bit_offset / step * step;
 
167
                } else {
 
168
                    /* Use a faster algorithm if depth is a power of 2. */
 
169
                    bytes = bit_offset & (-depth & -(int)align_mod);
 
170
                }
 
171
                base = stored_base + arith_rshift(bytes, 3);
 
172
                params->x_offset = (bit_offset - bytes) / depth;
 
173
            }
 
174
            params->options =
 
175
                GB_ALIGN_STANDARD | GB_RETURN_POINTER | GB_RASTER_STANDARD |
 
176
                (stored->options & ~GB_PACKING_ALL) /*see below for PACKING*/ |
 
177
                (params->x_offset == 0 ? GB_OFFSET_0 : GB_OFFSET_SPECIFIED);
 
178
            if (both & GB_PACKING_CHUNKY) {
 
179
                params->options |= GB_PACKING_CHUNKY;
 
180
                params->data[0] = base;
 
181
            } else {
 
182
                int n =
 
183
                    (stored->options & GB_PACKING_BIT_PLANAR ?
 
184
                       (params->options |= GB_PACKING_BIT_PLANAR,
 
185
                        dev->color_info.depth) :
 
186
                       (params->options |= GB_PACKING_PLANAR,
 
187
                        dev->color_info.num_components));
 
188
                int i;
 
189
 
 
190
                for (i = 0; i < n; ++i)
 
191
                    if (!(both & GB_SELECT_PLANES) || stored->data[i] != 0) {
 
192
                        params->data[i] = base;
 
193
                        base += dev_raster * dev->height;
 
194
                    }
 
195
            }
 
196
            return 0;
 
197
        }
 
198
    }
 
199
    return -1;
 
200
}
 
201
 
 
202
/*
 
203
 * Implement gx_get_bits_copy (see below) for the case of converting
 
204
 * 4-bit CMYK to 24-bit RGB with standard mapping, used heavily by PCL.
 
205
 */
 
206
static void
 
207
gx_get_bits_copy_cmyk_1bit(byte *dest_line, uint dest_raster,
 
208
                           const byte *src_line, uint src_raster,
 
209
                           int src_bit, int w, int h)
 
210
{
 
211
    for (; h > 0; dest_line += dest_raster, src_line += src_raster, --h) {
 
212
        const byte *src = src_line;
 
213
        byte *dest = dest_line;
 
214
        bool hi = (src_bit & 4) != 0;  /* last nibble processed was hi */
 
215
        int i;
 
216
 
 
217
        for (i = w; i > 0; dest += 3, --i) {
 
218
            uint pixel =
 
219
                ((hi = !hi)? *src >> 4 : *src++ & 0xf);
 
220
 
 
221
            if (pixel & 1)
 
222
                dest[0] = dest[1] = dest[2] = 0;
 
223
            else {
 
224
                dest[0] = (byte)((pixel >> 3) - 1);
 
225
                dest[1] = (byte)(((pixel >> 2) & 1) - 1);
 
226
                dest[2] = (byte)(((pixel >> 1) & 1) - 1);
 
227
            }
 
228
        }
 
229
    }
 
230
}
 
231
 
 
232
/*
 
233
 * Convert pixels between representations, primarily for get_bits_rectangle.
 
234
 * stored indicates how the data are actually stored, and includes:
 
235
 *      - one option from the GB_PACKING group;
 
236
 *      - if h > 1, one option from the GB_RASTER group;
 
237
 *      - optionally (and normally), GB_COLORS_NATIVE;
 
238
 *      - optionally, one option each from the GB_COLORS_STANDARD, GB_DEPTH,
 
239
 *      and GB_ALPHA groups.
 
240
 * Note that dev is used only for color mapping.  This routine assumes that
 
241
 * the stored data are aligned.
 
242
 *
 
243
 * Note: this routine does not check x, w, h for validity.
 
244
 *
 
245
 * The code for converting between standard and native colors has been
 
246
 * factored out into single-use procedures strictly for readability.
 
247
 * A good optimizing compiler would compile them in-line.
 
248
 */
 
249
static int
 
250
    gx_get_bits_std_to_native(gx_device * dev, int x, int w, int h,
 
251
                                  gs_get_bits_params_t * params,
 
252
                              const gs_get_bits_params_t *stored,
 
253
                              const byte * src_base, uint dev_raster,
 
254
                              int x_offset, uint raster),
 
255
    gx_get_bits_native_to_std(gx_device * dev, int x, int w, int h,
 
256
                              gs_get_bits_params_t * params,
 
257
                              const gs_get_bits_params_t *stored,
 
258
                              const byte * src_base, uint dev_raster,
 
259
                              int x_offset, uint raster, uint std_raster);
 
260
int
 
261
gx_get_bits_copy(gx_device * dev, int x, int w, int h,
 
262
                 gs_get_bits_params_t * params,
 
263
                 const gs_get_bits_params_t *stored,
 
264
                 const byte * src_base, uint dev_raster)
 
265
{
 
266
    gs_get_bits_options_t options = params->options;
 
267
    gs_get_bits_options_t stored_options = stored->options;
 
268
    int x_offset = (options & GB_OFFSET_0 ? 0 : params->x_offset);
 
269
    int depth = dev->color_info.depth;
 
270
    int bit_x = x * depth;
 
271
    const byte *src = src_base;
 
272
    /*
 
273
     * If the stored representation matches a requested representation,
 
274
     * we can copy the data without any transformations.
 
275
     */
 
276
    bool direct_copy = requested_includes_stored(dev, params, stored);
 
277
    int code = 0;
 
278
 
 
279
    /*
 
280
     * The request must include either GB_PACKING_CHUNKY or
 
281
     * GB_PACKING_PLANAR + GB_SELECT_PLANES, GB_RETURN_COPY,
 
282
     * and an offset and raster specification.  In the planar case,
 
283
     * the request must include GB_ALIGN_STANDARD, the stored
 
284
     * representation must include GB_PACKING_CHUNKY, and both must
 
285
     * include GB_COLORS_NATIVE.
 
286
     */
 
287
    if ((~options & GB_RETURN_COPY) ||
 
288
        !(options & (GB_OFFSET_0 | GB_OFFSET_SPECIFIED)) ||
 
289
        !(options & (GB_RASTER_STANDARD | GB_RASTER_SPECIFIED))
 
290
        )
 
291
        return_error(gs_error_rangecheck);
 
292
    if (options & GB_PACKING_CHUNKY) {
 
293
        byte *data = params->data[0];
 
294
        int end_bit = (x_offset + w) * depth;
 
295
        uint std_raster =
 
296
            (options & GB_ALIGN_STANDARD ? bitmap_raster(end_bit) :
 
297
             (end_bit + 7) >> 3);
 
298
        uint raster =
 
299
            (options & GB_RASTER_STANDARD ? std_raster : params->raster);
 
300
        int dest_bit_x = x_offset * depth;
 
301
        int skew = bit_x - dest_bit_x;
 
302
 
 
303
        /*
 
304
         * If the bit positions line up, use bytes_copy_rectangle.
 
305
         * Since bytes_copy_rectangle doesn't require alignment,
 
306
         * the bit positions only have to match within a byte,
 
307
         * not within align_bitmap_mod bytes.
 
308
         */
 
309
        if (!(skew & 7) && direct_copy) {
 
310
            int bit_w = w * depth;
 
311
 
 
312
            bytes_copy_rectangle(data + (dest_bit_x >> 3), raster,
 
313
                                 src + (bit_x >> 3), dev_raster,
 
314
                              ((bit_x + bit_w + 7) >> 3) - (bit_x >> 3), h);
 
315
        } else if (direct_copy) {
 
316
            /*
 
317
             * Use the logic already in mem_mono_copy_mono to copy the
 
318
             * bits to the destination.  We do this one line at a time,
 
319
             * to avoid having to allocate a line pointer table.
 
320
             */
 
321
            gx_device_memory tdev;
 
322
            byte *line_ptr = data;
 
323
            int bit_w = w * depth;
 
324
 
 
325
            tdev.line_ptrs = &tdev.base;
 
326
            for (; h > 0; line_ptr += raster, src += dev_raster, --h) {
 
327
                /* Make sure the destination is aligned. */
 
328
                int align = ALIGNMENT_MOD(line_ptr, align_bitmap_mod);
 
329
 
 
330
                tdev.base = line_ptr - align;
 
331
                /* set up parameters required by copy_mono's fit_copy */
 
332
                tdev.width = dest_bit_x + (align << 3) + bit_w;
 
333
                tdev.height = 1;
 
334
                (*dev_proc(&mem_mono_device, copy_mono))
 
335
                    ((gx_device *) & tdev, src, bit_x, dev_raster, gx_no_bitmap_id,
 
336
                     dest_bit_x + (align << 3), 0, bit_w, 1,
 
337
                     (gx_color_index) 0, (gx_color_index) 1);
 
338
            }
 
339
        } else if (options & ~stored_options & GB_COLORS_NATIVE) {
 
340
            /* Convert standard colors to native. */
 
341
            code = gx_get_bits_std_to_native(dev, x, w, h, params, stored,
 
342
                                             src_base, dev_raster,
 
343
                                             x_offset, raster);
 
344
            options = params->options;
 
345
        } else {
 
346
            /* Convert native colors to standard. */
 
347
            code = gx_get_bits_native_to_std(dev, x, w, h, params, stored,
 
348
                                             src_base, dev_raster,
 
349
                                             x_offset, raster, std_raster);
 
350
            options = params->options;
 
351
        }
 
352
        params->options =
 
353
            (options & (GB_COLORS_ALL | GB_ALPHA_ALL)) | GB_PACKING_CHUNKY |
 
354
            (options & GB_COLORS_NATIVE ? 0 : options & GB_DEPTH_ALL) |
 
355
            (options & GB_ALIGN_STANDARD ? GB_ALIGN_STANDARD : GB_ALIGN_ANY) |
 
356
            GB_RETURN_COPY |
 
357
            (x_offset == 0 ? GB_OFFSET_0 : GB_OFFSET_SPECIFIED) |
 
358
            (raster == std_raster ? GB_RASTER_STANDARD : GB_RASTER_SPECIFIED);
 
359
    } else if (!(~options &
 
360
                 (GB_PACKING_PLANAR | GB_SELECT_PLANES | GB_ALIGN_STANDARD)) &&
 
361
               (stored_options & GB_PACKING_CHUNKY) &&
 
362
               ((options & stored_options) & GB_COLORS_NATIVE)
 
363
               ) {
 
364
        int num_planes = dev->color_info.num_components;
 
365
        int dest_depth = depth / num_planes;
 
366
        bits_plane_t source, dest;
 
367
        int plane = -1;
 
368
        int i;
 
369
 
 
370
        /* Make sure only one plane is being requested. */
 
371
        for (i = 0; i < num_planes; ++i)
 
372
            if (params->data[i] != 0) {
 
373
                if (plane >= 0)
 
374
                    return_error(gs_error_rangecheck); /* > 1 plane */
 
375
                plane = i;
 
376
            }
 
377
        source.data.read = src_base;
 
378
        source.raster = dev_raster;
 
379
        source.depth = depth;
 
380
        source.x = x;
 
381
        dest.data.write = params->data[plane];
 
382
        dest.raster =
 
383
            (options & GB_RASTER_STANDARD ?
 
384
             bitmap_raster((x_offset + w) * dest_depth) : params->raster);
 
385
        dest.depth = dest_depth;
 
386
        dest.x = x_offset;
 
387
        return bits_extract_plane(&dest, &source,
 
388
                                  (num_planes - 1 - plane) * dest_depth,
 
389
                                  w, h);
 
390
    } else
 
391
        return_error(gs_error_rangecheck);
 
392
    return code;
 
393
}
 
394
 
 
395
/*
 
396
 * Convert standard colors to native.  Note that the source
 
397
 * may have depths other than 8 bits per component.
 
398
 */
 
399
static int
 
400
gx_get_bits_std_to_native(gx_device * dev, int x, int w, int h,
 
401
                          gs_get_bits_params_t * params,
 
402
                          const gs_get_bits_params_t *stored,
 
403
                          const byte * src_base, uint dev_raster,
 
404
                          int x_offset, uint raster)
 
405
{
 
406
    int depth = dev->color_info.depth;
 
407
    int dest_bit_offset = x_offset * depth;
 
408
    byte *dest_line = params->data[0] + (dest_bit_offset >> 3);
 
409
    int ncolors =
 
410
        (stored->options & GB_COLORS_RGB ? 3 :
 
411
         stored->options & GB_COLORS_CMYK ? 4 :
 
412
         stored->options & GB_COLORS_GRAY ? 1 : -1);
 
413
    int ncomp = ncolors +
 
414
        ((stored->options & (GB_ALPHA_FIRST | GB_ALPHA_LAST)) != 0);
 
415
    int src_depth = GB_OPTIONS_DEPTH(stored->options);
 
416
    int src_bit_offset = x * src_depth * ncomp;
 
417
    const byte *src_line = src_base + (src_bit_offset >> 3);
 
418
    gx_color_value src_max = (1 << src_depth) - 1;
 
419
#define v2cv(value) ((ulong)(value) * gx_max_color_value / src_max)
 
420
    gx_color_value alpha_default = src_max;
 
421
 
 
422
    params->options &= ~GB_COLORS_ALL | GB_COLORS_NATIVE;
 
423
    for (; h > 0; dest_line += raster, src_line += dev_raster, --h) {
 
424
        int i;
 
425
 
 
426
        sample_load_declare_setup(src, sbit, src_line,
 
427
                                  src_bit_offset & 7, src_depth);
 
428
        sample_store_declare_setup(dest, dbit, dbyte, dest_line,
 
429
                                   dest_bit_offset & 7, depth);
 
430
 
 
431
#define v2frac(value) ((long)(value) * frac_1 / src_max)
 
432
 
 
433
        for (i = 0; i < w; ++i) {
 
434
            int j;
 
435
            frac sc[4], dc[GX_DEVICE_COLOR_MAX_COMPONENTS];
 
436
            gx_color_value v[GX_DEVICE_COLOR_MAX_COMPONENTS], va = alpha_default;
 
437
            gx_color_index pixel;
 
438
            bool do_alpha = false;
 
439
            const gx_cm_color_map_procs * map_procs;
 
440
 
 
441
            map_procs = dev_proc(dev, get_color_mapping_procs)(dev);
 
442
 
 
443
            /* Fetch the source data. */
 
444
            if (stored->options & GB_ALPHA_FIRST) {
 
445
                sample_load_next16(va, src, sbit, src_depth);
 
446
                va = v2cv(va);
 
447
                do_alpha = true;
 
448
            }
 
449
            for (j = 0; j < ncolors; ++j) {
 
450
                gx_color_value vj;
 
451
 
 
452
                sample_load_next16(vj, src, sbit, src_depth);
 
453
                sc[j] = v2frac(vj);
 
454
            }
 
455
            if (stored->options & GB_ALPHA_LAST) {
 
456
                sample_load_next16(va, src, sbit, src_depth);
 
457
                va = v2cv(va);
 
458
                do_alpha = true;
 
459
            }
 
460
 
 
461
            /* Convert and store the pixel value. */
 
462
            if (do_alpha) {
 
463
                for (j = 0; j < ncolors; j++)
 
464
                    v[j] = frac2cv(sc[j]);
 
465
                if (ncolors == 1)
 
466
                    v[2] = v[1] = v[0];
 
467
                pixel = dev_proc(dev, map_rgb_alpha_color)
 
468
                    (dev, v[0], v[1], v[2], va);
 
469
            } else {
 
470
 
 
471
                switch (ncolors) {
 
472
                case 1:
 
473
                    map_procs->map_gray(dev, sc[0], dc);
 
474
                    break;
 
475
                case 3:
 
476
                    map_procs->map_rgb(dev, 0, sc[0], sc[1], sc[2], dc);
 
477
                    break;
 
478
                case 4:
 
479
                    map_procs->map_cmyk(dev, sc[0], sc[1], sc[2], sc[3], dc);
 
480
                    break;
 
481
                default:
 
482
                    return_error(gs_error_rangecheck);
 
483
                }
 
484
 
 
485
                for (j = 0; j < dev->color_info.num_components; j++)
 
486
                    v[j] = frac2cv(dc[j]);
 
487
 
 
488
                pixel = dev_proc(dev, encode_color)(dev, v);
 
489
            }
 
490
            sample_store_next_any(pixel, dest, dbit, depth, dbyte);
 
491
        }
 
492
        sample_store_flush(dest, dbit, depth, dbyte);
 
493
    }
 
494
    return 0;
 
495
}
 
496
 
 
497
/*
 
498
 * Convert native colors to standard.  Only GB_DEPTH_8 is supported.
 
499
 */
 
500
static int
 
501
gx_get_bits_native_to_std(gx_device * dev, int x, int w, int h,
 
502
                          gs_get_bits_params_t * params,
 
503
                          const gs_get_bits_params_t *stored,
 
504
                          const byte * src_base, uint dev_raster,
 
505
                          int x_offset, uint raster, uint std_raster)
 
506
{
 
507
    int depth = dev->color_info.depth;
 
508
    int src_bit_offset = x * depth;
 
509
    const byte *src_line = src_base + (src_bit_offset >> 3);
 
510
    gs_get_bits_options_t options = params->options;
 
511
    int ncomp =
 
512
        (options & (GB_ALPHA_FIRST | GB_ALPHA_LAST) ? 4 : 3);
 
513
    byte *dest_line = params->data[0] + x_offset * ncomp;
 
514
    byte *mapped[16];
 
515
    int dest_bytes;
 
516
    int i;
 
517
 
 
518
    if (!(options & GB_DEPTH_8)) {
 
519
        /*
 
520
         * We don't support general depths yet, or conversion between
 
521
         * different formats.  Punt.
 
522
         */
 
523
        return_error(gs_error_rangecheck);
 
524
    }
 
525
 
 
526
    /* Pick the representation that's most likely to be useful. */
 
527
    if (options & GB_COLORS_RGB)
 
528
        params->options = options &= ~GB_COLORS_STANDARD_ALL | GB_COLORS_RGB,
 
529
            dest_bytes = 3;
 
530
    else if (options & GB_COLORS_CMYK)
 
531
        params->options = options &= ~GB_COLORS_STANDARD_ALL | GB_COLORS_CMYK,
 
532
            dest_bytes = 4;
 
533
    else if (options & GB_COLORS_GRAY)
 
534
        params->options = options &= ~GB_COLORS_STANDARD_ALL | GB_COLORS_GRAY,
 
535
            dest_bytes = 1;
 
536
    else
 
537
        return_error(gs_error_rangecheck);
 
538
    /* Recompute the destination raster based on the color space. */
 
539
    if (options & GB_RASTER_STANDARD) {
 
540
        uint end_byte = (x_offset + w) * dest_bytes;
 
541
 
 
542
        raster = std_raster =
 
543
            (options & GB_ALIGN_STANDARD ?
 
544
             bitmap_raster(end_byte << 3) : end_byte);
 
545
    }
 
546
    /* Check for the one special case we care about. */
 
547
    if (((options & (GB_COLORS_RGB | GB_ALPHA_FIRST | GB_ALPHA_LAST))
 
548
           == GB_COLORS_RGB) &&
 
549
        dev_proc(dev, map_color_rgb) == cmyk_1bit_map_color_rgb) {
 
550
        gx_get_bits_copy_cmyk_1bit(dest_line, raster,
 
551
                                   src_line, dev_raster,
 
552
                                   src_bit_offset & 7, w, h);
 
553
        return 0;
 
554
    }
 
555
    if (options & (GB_ALPHA_FIRST | GB_ALPHA_LAST))
 
556
        ++dest_bytes;
 
557
    /* Clear the color translation cache. */
 
558
    for (i = (depth > 4 ? 16 : 1 << depth); --i >= 0; )
 
559
        mapped[i] = 0;
 
560
    for (; h > 0; dest_line += raster, src_line += dev_raster, --h) {
 
561
        sample_load_declare_setup(src, bit, src_line,
 
562
                                  src_bit_offset & 7, depth);
 
563
        byte *dest = dest_line;
 
564
 
 
565
        for (i = 0; i < w; ++i) {
 
566
            gx_color_index pixel = 0;
 
567
            gx_color_value rgba[4];
 
568
 
 
569
            sample_load_next_any(pixel, src, bit, depth);
 
570
            if (pixel < 16) {
 
571
                if (mapped[pixel]) {
 
572
                    /* Use the value from the cache. */
 
573
                    memcpy(dest, mapped[pixel], dest_bytes);
 
574
                    dest += dest_bytes;
 
575
                    continue;
 
576
                }
 
577
                mapped[pixel] = dest;
 
578
            }
 
579
            (*dev_proc(dev, map_color_rgb_alpha)) (dev, pixel, rgba);
 
580
            if (options & GB_ALPHA_FIRST)
 
581
                *dest++ = gx_color_value_to_byte(rgba[3]);
 
582
            /* Convert to the requested color space. */
 
583
            if (options & GB_COLORS_RGB) {
 
584
                dest[0] = gx_color_value_to_byte(rgba[0]);
 
585
                dest[1] = gx_color_value_to_byte(rgba[1]);
 
586
                dest[2] = gx_color_value_to_byte(rgba[2]);
 
587
                dest += 3;
 
588
            } else if (options & GB_COLORS_CMYK) {
 
589
                /* Use the standard RGB to CMYK algorithm, */
 
590
                /* with maximum black generation and undercolor removal. */
 
591
                gx_color_value white = max(rgba[0], max(rgba[1], rgba[2]));
 
592
 
 
593
                dest[0] = gx_color_value_to_byte(white - rgba[0]);
 
594
                dest[1] = gx_color_value_to_byte(white - rgba[1]);
 
595
                dest[2] = gx_color_value_to_byte(white - rgba[2]);
 
596
                dest[3] = gx_color_value_to_byte(gx_max_color_value - white);
 
597
                dest += 4;
 
598
            } else {    /* GB_COLORS_GRAY */
 
599
                /* Use the standard RGB to Gray algorithm. */
 
600
                *dest++ = gx_color_value_to_byte(
 
601
                                ((rgba[0] * (ulong) lum_red_weight) +
 
602
                                 (rgba[1] * (ulong) lum_green_weight) +
 
603
                                 (rgba[2] * (ulong) lum_blue_weight) +
 
604
                                   (lum_all_weights / 2))
 
605
                                / lum_all_weights);
 
606
            }
 
607
            if (options & GB_ALPHA_LAST)
 
608
                *dest++ = gx_color_value_to_byte(rgba[3]);
 
609
        }
 
610
    }
 
611
    return 0;
 
612
}
 
613
 
 
614
/* ------ Default implementations of get_bits_rectangle ------ */
 
615
 
 
616
int
 
617
gx_no_get_bits_rectangle(gx_device * dev, const gs_int_rect * prect,
 
618
                       gs_get_bits_params_t * params, gs_int_rect ** unread)
 
619
{
 
620
    return_error(gs_error_unknownerror);
 
621
}
 
622
 
 
623
int
 
624
gx_default_get_bits_rectangle(gx_device * dev, const gs_int_rect * prect,
 
625
                       gs_get_bits_params_t * params, gs_int_rect ** unread)
 
626
{
 
627
    dev_proc_get_bits_rectangle((*save_get_bits_rectangle)) =
 
628
        dev_proc(dev, get_bits_rectangle);
 
629
    int depth = dev->color_info.depth;
 
630
    uint min_raster = (dev->width * depth + 7) >> 3;
 
631
    gs_get_bits_options_t options = params->options;
 
632
    int code;
 
633
 
 
634
    /* Avoid a recursion loop. */
 
635
    set_dev_proc(dev, get_bits_rectangle, gx_no_get_bits_rectangle);
 
636
    /*
 
637
     * If the parameters are right, try to call get_bits directly.  Note
 
638
     * that this may fail if a device only implements get_bits_rectangle
 
639
     * (not get_bits) for a limited set of options.  Note also that this
 
640
     * must handle the case of the recursive call from within
 
641
     * get_bits_rectangle (see below): because of this, and only because
 
642
     * of this, it must handle partial scan lines.
 
643
     */
 
644
    if (prect->q.y == prect->p.y + 1 &&
 
645
        !(~options &
 
646
          (GB_RETURN_COPY | GB_PACKING_CHUNKY | GB_COLORS_NATIVE)) &&
 
647
        (options & (GB_ALIGN_STANDARD | GB_ALIGN_ANY)) &&
 
648
        ((options & (GB_OFFSET_0 | GB_OFFSET_ANY)) ||
 
649
         ((options & GB_OFFSET_SPECIFIED) && params->x_offset == 0)) &&
 
650
        ((options & (GB_RASTER_STANDARD | GB_RASTER_ANY)) ||
 
651
         ((options & GB_RASTER_SPECIFIED) &&
 
652
          params->raster >= min_raster)) &&
 
653
        unread == NULL
 
654
        ) {
 
655
        byte *data = params->data[0];
 
656
        byte *row = data;
 
657
 
 
658
        if (!(prect->p.x == 0 && prect->q.x == dev->width)) {
 
659
            /* Allocate an intermediate row buffer. */
 
660
            row = gs_alloc_bytes(dev->memory, min_raster,
 
661
                                 "gx_default_get_bits_rectangle");
 
662
 
 
663
            if (row == 0) {
 
664
                code = gs_note_error(gs_error_VMerror);
 
665
                goto ret;
 
666
            }
 
667
        }
 
668
        code = (*dev_proc(dev, get_bits)) (dev, prect->p.y, row,
 
669
                (params->options & GB_RETURN_POINTER) ? &params->data[0]
 
670
                                                      : NULL );
 
671
        if (code >= 0) {
 
672
            if (row != data) {
 
673
                if (prect->p.x == 0 && params->data[0] != row
 
674
                    && params->options & GB_RETURN_POINTER) {
 
675
                    /*
 
676
                     * get_bits returned an appropriate pointer: we can
 
677
                     * avoid doing any copying.
 
678
                     */
 
679
                    DO_NOTHING;
 
680
                } else {
 
681
                    /* Copy the partial row into the supplied buffer. */
 
682
                    int width_bits = (prect->q.x - prect->p.x) * depth;
 
683
                    gx_device_memory tdev;
 
684
 
 
685
                    tdev.width = width_bits;
 
686
                    tdev.height = 1;
 
687
                    tdev.line_ptrs = &tdev.base;
 
688
                    tdev.base = data;
 
689
                    code = (*dev_proc(&mem_mono_device, copy_mono))
 
690
                        ((gx_device *) & tdev, row, prect->p.x * depth,
 
691
                         min_raster, gx_no_bitmap_id, 0, 0, width_bits, 1,
 
692
                         (gx_color_index) 0, (gx_color_index) 1);
 
693
                    params->data[0] = data;
 
694
                }
 
695
                gs_free_object(dev->memory, row,
 
696
                               "gx_default_get_bits_rectangle");
 
697
            }
 
698
            params->options =
 
699
                GB_ALIGN_STANDARD | GB_OFFSET_0 | GB_PACKING_CHUNKY |
 
700
                GB_ALPHA_NONE | GB_COLORS_NATIVE | GB_RASTER_STANDARD |
 
701
                (params->data[0] == data ? GB_RETURN_COPY : GB_RETURN_POINTER);
 
702
            goto ret;
 
703
        }
 
704
    } {
 
705
        /* Do the transfer row-by-row using a buffer. */
 
706
        int x = prect->p.x, w = prect->q.x - x;
 
707
        int bits_per_pixel = depth;
 
708
        byte *row;
 
709
 
 
710
        if (options & GB_COLORS_STANDARD_ALL) {
 
711
            /*
 
712
             * Make sure the row buffer can hold the standard color
 
713
             * representation, in case the device decides to use it.
 
714
             */
 
715
            int bpc = GB_OPTIONS_MAX_DEPTH(options);
 
716
            int nc =
 
717
            (options & GB_COLORS_CMYK ? 4 :
 
718
             options & GB_COLORS_RGB ? 3 : 1) +
 
719
            (options & (GB_ALPHA_ALL - GB_ALPHA_NONE) ? 1 : 0);
 
720
            int bpp = bpc * nc;
 
721
 
 
722
            if (bpp > bits_per_pixel)
 
723
                bits_per_pixel = bpp;
 
724
        }
 
725
        row = gs_alloc_bytes(dev->memory, (bits_per_pixel * w + 7) >> 3,
 
726
                             "gx_default_get_bits_rectangle");
 
727
        if (row == 0) {
 
728
            code = gs_note_error(gs_error_VMerror);
 
729
        } else {
 
730
            uint dev_raster = gx_device_raster(dev, true);
 
731
            uint raster =
 
732
            (options & GB_RASTER_SPECIFIED ? params->raster :
 
733
             options & GB_ALIGN_STANDARD ? bitmap_raster(depth * w) :
 
734
             (depth * w + 7) >> 3);
 
735
            gs_int_rect rect;
 
736
            gs_get_bits_params_t copy_params;
 
737
            gs_get_bits_options_t copy_options =
 
738
                (GB_ALIGN_STANDARD | GB_ALIGN_ANY) |
 
739
                (GB_RETURN_COPY | GB_RETURN_POINTER) |
 
740
                (GB_OFFSET_0 | GB_OFFSET_ANY) |
 
741
                (GB_RASTER_STANDARD | GB_RASTER_ANY) | GB_PACKING_CHUNKY |
 
742
                GB_COLORS_NATIVE | (options & (GB_DEPTH_ALL | GB_COLORS_ALL)) |
 
743
                GB_ALPHA_ALL;
 
744
            byte *dest = params->data[0];
 
745
            int y;
 
746
 
 
747
            rect.p.x = x, rect.q.x = x + w;
 
748
            code = 0;
 
749
            for (y = prect->p.y; y < prect->q.y; ++y) {
 
750
                rect.p.y = y, rect.q.y = y + 1;
 
751
                copy_params.options = copy_options;
 
752
                copy_params.data[0] = row;
 
753
                code = (*save_get_bits_rectangle)
 
754
                    (dev, &rect, &copy_params, NULL);
 
755
                if (code < 0)
 
756
                    break;
 
757
                if (copy_params.options & GB_OFFSET_0)
 
758
                    copy_params.x_offset = 0;
 
759
                params->data[0] = dest + (y - prect->p.y) * raster;
 
760
                code = gx_get_bits_copy(dev, copy_params.x_offset, w, 1,
 
761
                                        params, &copy_params,
 
762
                                        copy_params.data[0], dev_raster);
 
763
                if (code < 0)
 
764
                    break;
 
765
            }
 
766
            gs_free_object(dev->memory, row, "gx_default_get_bits_rectangle");
 
767
            params->data[0] = dest;
 
768
        }
 
769
    }
 
770
  ret:set_dev_proc(dev, get_bits_rectangle, save_get_bits_rectangle);
 
771
    return (code < 0 ? code : 0);
 
772
}
 
773
 
 
774