1
/* Copyright (C) 2001-2006 Artifex Software, Inc.
4
This software is provided AS-IS with no warranty, either express or
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.
14
/* $Id: gxoprect.c 8250 2007-09-25 13:31:24Z giles $ */
15
/* generic (very slow) overprint fill rectangle implementation */
20
#include "gsutil.h" /* for gs_next_ids */
29
* Unpack a scanline for a depth < 8. In this case we know the depth is
30
* divisor of 8 and thus a power of 2, which implies that 8 / depth is
35
gx_color_index * destp,
42
int i = 0, shift = 8 - depth, p_per_byte = 8 / depth;
44
/* exit early if nothing to do */
48
/* skip over src_offset */
49
if (src_offset >= p_per_byte) {
50
srcp += src_offset / p_per_byte;
51
src_offset &= (p_per_byte - 1);
54
buff = *srcp++ << (src_offset * depth);
59
/* process the interesting part of the scanline */
60
for (; i < width; i++, buff <<= depth) {
61
if ((i & (p_per_byte - 1)) == 0)
63
*destp++ = buff >> shift;
68
* Pack a scanline for a depth of < 8. Note that data prior to dest_offset
69
* and any data beyond the width must be left undisturbed.
73
const gx_color_index * srcp,
80
int i = 0, p_per_byte = 8 / depth;
82
/* exit early if nothing to do */
86
/* skip over dest_offset */
87
if (dest_offset >= p_per_byte) {
88
destp += dest_offset / p_per_byte;
89
dest_offset &= (p_per_byte - 1);
91
if (dest_offset > 0) {
92
buff = *destp++ >> (8 - dest_offset * depth);
97
/* process the interesting part of the scanline */
98
for (; i < width; i++) {
99
buff = (buff << depth) | *srcp++;
100
if ((i & (p_per_byte - 1)) == p_per_byte - 1)
103
if ((i &= (p_per_byte - 1)) != 0) {
104
int shift = depth * (p_per_byte - i);
105
int mask = (1 << shift) - 1;
107
*destp = (*destp & mask) | (buff << shift);
112
* Unpack a scanline for a depth >= 8. In this case, the depth must be
117
gx_color_index * destp,
123
gx_color_index buff = 0;
124
int i, j, bytes_per_p = depth >> 3;
126
/* skip over src_offset */
127
srcp += src_offset * bytes_per_p;
129
/* process the interesting part of the scanline */
130
width *= bytes_per_p;
131
for (i = 0, j = 0; i < width; i++) {
132
buff = (buff << 8) | *srcp++;
133
if (++j == bytes_per_p) {
142
* Pack a scanline for depth >= 8.
146
const gx_color_index * srcp,
152
gx_color_index buff = 0;
153
int i, j, bytes_per_p = depth >> 3;
154
int shift = depth - 8;
156
/* skip over dest_offset */
157
destp += dest_offset;
159
/* process the interesting part of the scanline */
160
width *= bytes_per_p;
161
for (i = 0, j = bytes_per_p - 1; i < width; i++, buff <<= 8) {
162
if (++j == bytes_per_p) {
166
*destp++ = buff >> shift;
172
* Perform the fill rectangle operation for a non-separable color encoding
173
* that requires overprint support. This situation requires that colors be
174
* decoded, modified, and re-encoded. These steps must be performed per
175
* output pixel, so there is no hope of achieving good performance.
176
* Consequently, only minimal performance optimizations are applied below.
178
* The overprint device structure is known only in gsovr.c, and thus is not
179
* available here. The required information from the overprint device is,
180
* therefore, provided via explicit operands. The device operand points to
181
* the target of the overprint compositor device, not the compositor device
182
* itself. The drawn_comps bit array and the memory descriptor pointer are
183
* also provided explicitly as operands.
185
* Returns 0 on success, < 0 in the event of an error.
188
gx_overprint_generic_fill_rectangle(
190
gx_color_index drawn_comps,
195
gx_color_index color,
198
gx_color_value src_cvals[GX_DEVICE_COLOR_MAX_COMPONENTS];
199
gx_color_index * pcolor_buff = 0;
201
gs_get_bits_params_t gb_params;
203
int depth = tdev->color_info.depth;
204
int bit_x, start_x, end_x, raster, code;
205
void (*unpack_proc)( gx_color_index *,
208
void (*pack_proc)( const gx_color_index *,
212
fit_fill(tdev, x, y, w, h);
214
start_x = bit_x & ~(8 * align_bitmap_mod - 1);
215
end_x = bit_x + w * depth;
217
/* select the appropriate pack/unpack routines */
219
unpack_proc = unpack_scanline_ge8;
220
pack_proc = pack_scanline_ge8;
222
unpack_proc = unpack_scanline_lt8;
223
pack_proc = pack_scanline_lt8;
226
/* decode the source color */
227
if ((code = dev_proc(tdev, decode_color)(tdev, color, src_cvals)) < 0)
230
/* allocate space for a scanline of color indices */
231
pcolor_buff = (gx_color_index *)
233
w * arch_sizeof_color_index,
234
"overprint generic fill rectangle" );
235
if (pcolor_buff == 0)
236
return gs_note_error(gs_error_VMerror);
238
/* allocate a buffer for the returned data */
239
raster = bitmap_raster(end_x - start_x);
240
gb_buff = gs_alloc_bytes(mem, raster, "overprint generic fill rectangle");
244
"overprint generic fill rectangle" );
245
return gs_note_error(gs_error_VMerror);
249
* Initialize the get_bits parameters. The selection of options is
250
* based on the following logic:
252
* - Overprint is only defined with respect to components of the
253
* process color model, so the retrieved information must be kept
254
* in that color model. The gx_bitmap_format_t bitfield regards
255
* this as the native color space.
257
* - Overprinting and alpha compositing don't mix, so there is no
258
* reason to retrieve the alpha information.
260
* - Data should be returned in the depth of the process color
261
* model. Though this depth could be specified explicitly, there
262
* is little reason to do so.
264
* - Though overprint is much more easily implemented with planar
265
* data, there is no planar version of the copy_color method to
266
* send the modified data back to device. Hence, we must retrieve
267
* data in chunky form.
269
* - It is not possible to modify the raster data "in place", as
270
* doing so would bypass any other forwarding devices currently
271
* in the device "stack" (e.g.: a bounding box device). Hence,
272
* we must work with a copy of the data, which is passed to the
273
* copy_color method at the end of fill_rectangle operation.
275
* - Though we only require data for those planes that will not be
276
* modified, there is no benefit to returning less than the full
277
* data for each pixel if the color encoding is not separable.
278
* Since this routine will be used only for encodings that are
279
* not separable, we might as well ask for full information.
281
* - Though no particular alignment and offset are required, it is
282
* useful to make the copy operation as fast as possible. Ideally
283
* we would calculate an offset so that the data achieves optimal
284
* alignment. Alas, some of the devices work much more slowly if
285
* anything but GB_OFFSET_0 is specified, so that is what we use.
287
gb_params.options = GB_COLORS_NATIVE
294
| GB_RASTER_STANDARD;
295
gb_params.x_offset = 0; /* for consistency */
296
gb_params.data[0] = gb_buff;
297
gb_params.raster = raster;
302
/* process each scanline separately */
303
while (h-- > 0 && code >= 0) {
304
gx_color_index * cp = pcolor_buff;
309
code = dev_proc(tdev, get_bits_rectangle)( tdev,
315
unpack_proc(pcolor_buff, gb_buff, 0, w, depth);
316
for (i = 0; i < w; i++, cp++) {
317
gx_color_index comps;
319
gx_color_value dest_cvals[GX_DEVICE_COLOR_MAX_COMPONENTS];
321
if ((code = dev_proc(tdev, decode_color)(tdev, *cp, dest_cvals)) < 0)
323
for (j = 0, comps = drawn_comps; comps != 0; ++j, comps >>= 1) {
324
if ((comps & 0x1) != 0)
325
dest_cvals[j] = src_cvals[j];
327
*cp = dev_proc(tdev, encode_color)(tdev, dest_cvals);
329
pack_proc(pcolor_buff, gb_buff, 0, w, depth);
330
code = dev_proc(tdev, copy_color)( tdev,
340
"overprint generic fill rectangle" );
343
"overprint generic fill rectangle" );
351
* Replication of 2 and 4 bit patterns to fill a mem_mono_chunk.
353
static mono_fill_chunk fill_pat_2[4] = {
354
mono_fill_make_pattern(0x00), mono_fill_make_pattern(0x55),
355
mono_fill_make_pattern(0xaa), mono_fill_make_pattern(0xff)
358
static mono_fill_chunk fill_pat_4[16] = {
359
mono_fill_make_pattern(0x00), mono_fill_make_pattern(0x11),
360
mono_fill_make_pattern(0x22), mono_fill_make_pattern(0x33),
361
mono_fill_make_pattern(0x44), mono_fill_make_pattern(0x55),
362
mono_fill_make_pattern(0x66), mono_fill_make_pattern(0x77),
363
mono_fill_make_pattern(0x88), mono_fill_make_pattern(0x99),
364
mono_fill_make_pattern(0xaa), mono_fill_make_pattern(0xbb),
365
mono_fill_make_pattern(0xcc), mono_fill_make_pattern(0xdd),
366
mono_fill_make_pattern(0xee), mono_fill_make_pattern(0xff)
370
* Replicate a color or mask as required to fill a mem_mono_fill_chunk.
371
* This is possible if (8 * sizeof(mono_fill_chunk)) % depth == 0.
372
* Since sizeof(mono_fill_chunk) is a power of 2, this will be the case
373
* if depth is a power of 2 and depth <= 8 * sizeof(mono_fill_chunk).
375
static mono_fill_chunk
376
replicate_color(int depth, mono_fill_chunk color)
381
color = (mono_fill_chunk)(-(int)color); break;
384
color = fill_pat_2[color]; break;
387
color = fill_pat_4[color]; break;
390
color= mono_fill_make_pattern(color); break;
392
#if mono_fill_chunk_bytes > 2
394
color = (color << 16) | color;
397
#if mono_fill_chunk_bytes > 4
399
color = (color << 32) | color;
409
* Perform the fill rectangle operation for a separable color encoding
410
* that requires overprint support.
412
* This is handled via two separate cases. If
414
* (8 * sizeof(mono_fill_chunk)) % tdev->color_info.depth = 0,
416
* then is possible to work via the masked analog of the bits_fill_rectangle
417
* procedure, bits_fill_rectangle_masked. This requires that both the
418
* color and component mask be replicated sufficiently to fill the
419
* mono_fill_chunk. The somewhat elaborate set-up aside, the resulting
420
* algorithm is about as efficient as can be achieved when using
421
* get_bits_rectangle. More efficient algorithms require overprint to be
422
* implemented in the target device itself.
424
* If the condition is not satisfied, a simple byte-wise algorithm is
425
* used. This requires minimal setup but is not efficient, as it works in
426
* units that are too small. More efficient methods are possible in this
427
* case, but the required setup for a general depth is excessive (even
428
* with the restriction that depth % 8 = 0). Hence, efficiency for these
429
* cases is better addressed by direct implementation of overprint for
432
* For both cases, the color and retain_mask values passed to this
433
* procedure are expected to be already swapped as required for a byte-
434
* oriented bitmap. This consideration affects only little-endian
435
* machines. For those machines, if depth > 9 the color passed to these
436
* two procedures will not be the same as that passed to
437
* gx_overprint_generic_fill_rectangle.
439
* Returns 0 on success, < 0 in the event of an error.
442
gx_overprint_sep_fill_rectangle_1(
444
gx_color_index retain_mask, /* already swapped */
449
gx_color_index color, /* already swapped */
453
gs_get_bits_params_t gb_params;
455
int code = 0, bit_w, depth = tdev->color_info.depth;
457
mono_fill_chunk rep_color, rep_mask;
459
fit_fill(tdev, x, y, w, h);
462
/* set up replicated color and retain mask */
463
if (depth < 8 * sizeof(mono_fill_chunk)) {
464
rep_color = replicate_color(depth, (mono_fill_chunk)color);
465
rep_mask = replicate_color(depth, (mono_fill_chunk)retain_mask);
467
rep_color = (mono_fill_chunk)color;
468
rep_mask = (mono_fill_chunk)retain_mask;
471
/* allocate a buffer for the returned data */
472
raster = bitmap_raster(w * depth);
473
gb_buff = gs_alloc_bytes(mem, raster, "overprint sep fill rectangle 1");
475
return gs_note_error(gs_error_VMerror);
478
* Initialize the get_bits parameters. The selection of options is
479
* the same as that for gx_overprint_generic_fill_rectangle (above).
481
gb_params.options = GB_COLORS_NATIVE
488
| GB_RASTER_STANDARD;
489
gb_params.x_offset = 0; /* for consistency */
490
gb_params.data[0] = gb_buff;
491
gb_params.raster = raster;
496
/* process each scanline separately */
497
while (h-- > 0 && code >= 0) {
500
code = dev_proc(tdev, get_bits_rectangle)( tdev,
506
bits_fill_rectangle_masked( gb_buff,
513
code = dev_proc(tdev, copy_color)( tdev,
523
"overprint generic fill rectangle" );
530
gx_overprint_sep_fill_rectangle_2(
532
gx_color_index retain_mask, /* already swapped */
537
gx_color_index color, /* already swapped */
541
gs_get_bits_params_t gb_params;
543
int code = 0, byte_w, raster;
544
int byte_depth = tdev->color_info.depth >> 3;
548
fit_fill(tdev, x, y, w, h);
549
byte_w = w * byte_depth;
551
/* set up color and retain mask pointers */
552
pcolor = (byte *)&color;
553
pmask = (byte *)&retain_mask;
554
#if arch_is_big_endian
555
pcolor += arch_sizeof_color_index - byte_depth;
556
pmask += arch_sizeof_color_index - byte_depth;
559
/* allocate a buffer for the returned data */
560
raster = bitmap_raster(w * (byte_depth << 3));
561
gb_buff = gs_alloc_bytes(mem, raster, "overprint sep fill rectangle 2");
563
return gs_note_error(gs_error_VMerror);
566
* Initialize the get_bits parameters. The selection of options is
567
* the same as that for gx_overprint_generic_fill_rectangle (above).
569
gb_params.options = GB_COLORS_NATIVE
576
| GB_RASTER_STANDARD;
577
gb_params.x_offset = 0; /* for consistency */
578
gb_params.data[0] = gb_buff;
579
gb_params.raster = raster;
584
/* process each scanline separately */
585
while (h-- > 0 && code >= 0) {
591
code = dev_proc(tdev, get_bits_rectangle)( tdev,
597
for (i = 0, j = 0; i < byte_w; i++, cp++) {
598
*cp = (*cp & pmask[j]) | pcolor[j];
599
if (++j == byte_depth)
602
code = dev_proc(tdev, copy_color)( tdev,
612
"overprint generic fill rectangle" );