Coverage Report

Created: 2025-06-10 07:19

/src/ghostpdl/base/gxcht.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2001-2023 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,
8
   modified or distributed except as expressly authorized under the terms
9
   of the license contained in the file LICENSE in this distribution.
10
11
   Refer to licensing information at http://www.artifex.com or contact
12
   Artifex Software, Inc.,  39 Mesa Street, Suite 108A, San Francisco,
13
   CA 94129, USA, for further information.
14
*/
15
16
17
/* Color halftone rendering for Ghostscript imaging library */
18
#include "memory_.h"
19
#include "gx.h"
20
#include "gserrors.h"
21
#include "gsutil.h"   /* for id generation */
22
#include "gxarith.h"
23
#include "gxfixed.h"
24
#include "gxmatrix.h"
25
#include "gxdevice.h"
26
#include "gxcmap.h"
27
#include "gxdcolor.h"
28
#include "gxgstate.h"
29
#include "gzht.h"
30
#include "gsserial.h"
31
#include "gxdevsop.h"
32
33
/* Define whether to force use of the slow code, for testing. */
34
#define USE_SLOW_CODE 0
35
36
/* Define the size of the tile buffer allocated on the stack. */
37
0
#define tile_longs_LARGE 256
38
#define tile_longs_SMALL 64
39
#if ARCH_SMALL_MEMORY
40
#  define tile_longs_allocated tile_longs_SMALL
41
#  define tile_longs tile_longs_SMALL
42
#else
43
#  define tile_longs_allocated tile_longs_LARGE
44
#  ifdef DEBUG
45
#    define tile_longs\
46
       (gs_debug_c('.') ? tile_longs_SMALL : tile_longs_LARGE)
47
#  else
48
0
#    define tile_longs tile_longs_LARGE
49
#  endif
50
#endif
51
52
/* Define the colored halftone device color type. */
53
gs_private_st_ptrs1(st_dc_ht_colored, gx_device_color, "dc_ht_colored",
54
    dc_ht_colored_enum_ptrs, dc_ht_colored_reloc_ptrs, colors.colored.c_ht);
55
static dev_color_proc_save_dc(gx_dc_ht_colored_save_dc);
56
static dev_color_proc_get_dev_halftone(gx_dc_ht_colored_get_dev_halftone);
57
static dev_color_proc_load(gx_dc_ht_colored_load);
58
static dev_color_proc_fill_rectangle(gx_dc_ht_colored_fill_rectangle);
59
static dev_color_proc_equal(gx_dc_ht_colored_equal);
60
static dev_color_proc_write(gx_dc_ht_colored_write);
61
static dev_color_proc_read(gx_dc_ht_colored_read);
62
const gx_device_color_type_t gx_dc_type_data_ht_colored = {
63
    &st_dc_ht_colored,
64
    gx_dc_ht_colored_save_dc, gx_dc_ht_colored_get_dev_halftone,
65
    gx_dc_ht_get_phase,
66
    gx_dc_ht_colored_load, gx_dc_ht_colored_fill_rectangle,
67
    gx_dc_default_fill_masked, gx_dc_ht_colored_equal,
68
    gx_dc_ht_colored_write, gx_dc_ht_colored_read,
69
    gx_dc_ht_colored_get_nonzero_comps
70
};
71
#undef gx_dc_type_ht_colored
72
const gx_device_color_type_t *const gx_dc_type_ht_colored =
73
    &gx_dc_type_data_ht_colored;
74
0
#define gx_dc_type_ht_colored (&gx_dc_type_data_ht_colored)
75
76
/* save information about the operand device color */
77
static void
78
gx_dc_ht_colored_save_dc(const gx_device_color * pdevc,
79
                         gx_device_color_saved * psdc)
80
0
{
81
0
    psdc->type = pdevc->type;
82
0
    memcpy( psdc->colors.colored.c_base,
83
0
            pdevc->colors.colored.c_base,
84
0
            sizeof(psdc->colors.colored.c_base) );
85
0
    memcpy( psdc->colors.colored.c_level,
86
0
            pdevc->colors.colored.c_level,
87
0
            sizeof(psdc->colors.colored.c_base) );
88
0
    psdc->phase = pdevc->phase;
89
0
}
90
91
/* get the halftone used for the operand device color */
92
static const gx_device_halftone *
93
gx_dc_ht_colored_get_dev_halftone(const gx_device_color * pdevc)
94
0
{
95
0
    return pdevc->colors.colored.c_ht;
96
0
}
97
98
/* Compare two colored halftones for equality. */
99
static bool
100
gx_dc_ht_colored_equal(const gx_device_color * pdevc1,
101
                       const gx_device_color * pdevc2)
102
0
{
103
0
    uint num_comp = pdevc1->colors.colored.num_components;
104
105
0
    if (pdevc2->type != pdevc1->type ||
106
0
        pdevc1->colors.colored.c_ht != pdevc2->colors.colored.c_ht ||
107
0
        pdevc1->phase.x != pdevc2->phase.x ||
108
0
        pdevc1->phase.y != pdevc2->phase.y ||
109
0
        num_comp != pdevc2->colors.colored.num_components
110
0
        )
111
0
        return false;
112
0
    return
113
0
        !memcmp(pdevc1->colors.colored.c_base,
114
0
                pdevc2->colors.colored.c_base,
115
0
                num_comp * sizeof(pdevc1->colors.colored.c_base[0])) &&
116
0
        !memcmp(pdevc1->colors.colored.c_level,
117
0
                pdevc2->colors.colored.c_level,
118
0
                num_comp * sizeof(pdevc1->colors.colored.c_level[0]));
119
0
}
120
121
/*
122
 * Flags to indicate the pieces of a colored halftone that are included
123
 * in its string representation. The first byte of the string holds this
124
 * set of flags.
125
 *
126
 * The case alpha = gx_max_color_value is by far the most common, so
127
 * special treatment is provided for this case.
128
 *
129
 * The halftone is never transmitted as part of a device color, so there
130
 * is no flag for it.
131
 */
132
enum {
133
   dc_ht_colored_has_base = 0x01,
134
   dc_ht_colored_has_level = 0x02,
135
   dc_ht_colored_has_phase_x = 0x04,
136
   dc_ht_colored_has_phase_y = 0x08,
137
};
138
139
/*
140
 * Serialize a device color that uses a traditional colored halftone.
141
 *
142
 * The number of components of a device color must match that of the
143
 * process color model, so it is not transmitted.
144
 *
145
 * The most common situation in which this routine is used is for 1-bit
146
 * per component devices. In that case, base[i] will always be 0 or 1,
147
 * and thus may be fit in a single bit.
148
 *
149
 * In many situations, one or more of the color component intensity
150
 * levels will be 0. The plane_mask field identifies those components
151
 * where this is not the case. By tansmitting the plane_mask, only those
152
 * components with non-zero levels need be transmitted.
153
 *
154
 * The case alpha = gx_max_color_value is by far the most common, so
155
 * special treatment is provided for this case.
156
 *
157
 *
158
 * Operands:
159
 *
160
 *  pdevc       pointer to device color to be serialized
161
 *
162
 *  psdc        pointer ot saved version of last serialized color (for
163
 *              this band)
164
 *
165
 *  dev         pointer to the current device, used to retrieve process
166
 *              color model information
167
 *
168
 *  pdata       pointer to buffer in which to write the data
169
 *
170
 *  psize       pointer to a location that, on entry, contains the size of
171
 *              the buffer pointed to by pdata; on return, the size of
172
 *              the data required or actually used will be written here.
173
 *
174
 * Returns:
175
 *  1, with *psize set to 0, if *psdc and *pdevc represent the same color
176
 *
177
 *  0, with *psize set to the amount of data written, if everything OK
178
 *
179
 *  gs_error_rangecheck, with *psize set to the size of buffer required,
180
 *  if *psize was not large enough
181
 *
182
 *  < 0, != gs_error_rangecheck, in the event of some other error
183
 *  (currently none); in this case *psize is not changed.
184
 */
185
static int
186
gx_dc_ht_colored_write(
187
    const gx_device_color *         pdevc,
188
    const gx_device_color_saved *   psdc0,
189
    const gx_device *               dev,
190
    int64_t         offset,
191
    byte *                          pdata,
192
    uint *                          psize )
193
0
{
194
0
    int                             req_size = 1;
195
0
    int                             flag_bits = 0;
196
0
    int                             num_comps = dev->color_info.num_components;
197
0
    int                             depth = dev->color_info.depth;
198
0
    gx_color_index                  plane_mask = pdevc->colors.colored.plane_mask;
199
0
    const gx_device_color_saved *   psdc = psdc0;
200
0
    byte *                          pdata0 = pdata;
201
202
0
    if (offset != 0)
203
0
        return_error(gs_error_unregistered); /* Not implemented yet. */
204
205
    /* sanity check */
206
0
    if (pdevc->colors.colored.num_components != num_comps)
207
0
        return_error(gs_error_unregistered); /* Must not happen. */
208
209
    /* check if saved color is of the same type */
210
0
    if (psdc != 0 && psdc->type != pdevc->type)
211
0
        psdc = 0;
212
213
    /* calculate the size required */
214
0
    if ( psdc == 0                                                         ||
215
0
         memcmp( pdevc->colors.colored.c_base,
216
0
                 psdc->colors.colored.c_base,
217
0
                 num_comps * sizeof(pdevc->colors.colored.c_base[0]) ) != 0  ) {
218
0
        flag_bits |= dc_ht_colored_has_base;
219
0
        if (num_comps == depth)     /* 1 bit / component */
220
0
            req_size += (num_comps + 7) >> 3;
221
0
        else
222
0
            req_size += num_comps * sizeof(pdevc->colors.colored.c_base[0]);
223
0
    }
224
225
0
    plane_mask = pdevc->colors.colored.plane_mask;
226
0
    if ( psdc == NULL                                                       ||
227
0
         memcmp( pdevc->colors.colored.c_level,
228
0
                 psdc->colors.colored.c_level,
229
0
                 num_comps * sizeof(pdevc->colors.colored.c_level[0]) ) != 0  ) {
230
0
        gx_color_index  comp_bit;
231
0
        int             i;
232
0
        uint            tmp_mask;
233
234
0
        flag_bits |= dc_ht_colored_has_level;
235
0
        if (num_comps > 8 * sizeof(uint)) {
236
0
            tmp_mask = (uint)plane_mask;
237
0
            req_size += enc_u_sizew(tmp_mask);
238
0
            tmp_mask = (uint)((plane_mask >> (8*sizeof(uint)-1)) >> 1);
239
0
            req_size += enc_u_sizew(tmp_mask);
240
0
        } else {
241
0
            tmp_mask = (uint)plane_mask;
242
0
            req_size += enc_u_sizew(tmp_mask);
243
0
        }
244
0
        for (i = 0, comp_bit = 0x1; i < num_comps; i++, comp_bit <<= 1) {
245
0
            if ((plane_mask & comp_bit) != 0)
246
0
                req_size += enc_u_sizew(pdevc->colors.colored.c_level[i]);
247
0
        }
248
0
    }
249
250
0
    if (psdc == NULL || psdc->phase.x != pdevc->phase.x)
251
0
        flag_bits |= dc_ht_colored_has_phase_x, req_size += enc_u_sizew(pdevc->phase.x);
252
0
    if (psdc == NULL || psdc->phase.y != pdevc->phase.y)
253
0
        flag_bits |= dc_ht_colored_has_phase_y, req_size += enc_u_sizew(pdevc->phase.y);
254
255
    /* see if there is anything to do */
256
0
    if (flag_bits == 0) {
257
0
        *psize = 0;
258
0
        return 1;
259
0
    }
260
261
    /* see if enough space is available */
262
0
    if (req_size > *psize) {
263
0
        *psize = req_size;
264
0
        return_error(gs_error_rangecheck);
265
0
    }
266
267
    /* write out the flag byte */
268
0
    *pdata++ = (byte)flag_bits;
269
270
    /* write out such other parts of the device color as required */
271
0
    if ((flag_bits & dc_ht_colored_has_base) != 0) {
272
0
        if (num_comps == depth) {
273
0
            gx_color_index  base_mask = 0;
274
0
            int             num_bytes = (num_comps + 7) >> 3;
275
0
            int             i;
276
277
0
            for (i = 0; i < num_comps; i++) {
278
0
                if (pdevc->colors.colored.c_base[i] != 0)
279
0
                    base_mask |= (gx_color_index)1 << i;
280
0
            }
281
0
            for (i = 0; i < num_bytes; i++, base_mask >>= 8)
282
0
                *pdata++ = (byte)base_mask;
283
0
        } else {
284
0
            memcpy( pdata,
285
0
                    pdevc->colors.colored.c_base,
286
0
                    num_comps * sizeof(pdevc->colors.colored.c_base[0]) );
287
0
            pdata += num_comps * sizeof(pdevc->colors.colored.c_base[0]);
288
0
        }
289
0
    }
290
291
0
    if ((flag_bits & dc_ht_colored_has_level) != 0) {
292
0
        gx_color_index  code_bit;
293
0
        int             i;
294
0
        uint            tmp_mask;
295
296
0
        if (num_comps > 8 * sizeof(uint)) {
297
0
            tmp_mask = (uint)plane_mask;
298
0
            enc_u_putw(tmp_mask, pdata);
299
0
            tmp_mask = (uint)((plane_mask >> (8*sizeof(uint)-1))>>1);
300
0
            enc_u_putw(tmp_mask, pdata);
301
0
        } else {
302
0
            tmp_mask = (uint)plane_mask;
303
0
            enc_u_putw(tmp_mask, pdata);
304
0
        }
305
0
        for (i = 0, code_bit = 0x1; i < num_comps; i++, code_bit <<= 1) {
306
0
            if ((plane_mask & code_bit) != 0)
307
0
                enc_u_putw(pdevc->colors.colored.c_level[i], pdata);
308
0
        }
309
0
    }
310
311
0
    if ((flag_bits & dc_ht_colored_has_phase_x) != 0) {
312
0
        enc_u_putw(pdevc->phase.x, pdata);
313
0
    }
314
0
    if ((flag_bits & dc_ht_colored_has_phase_x) != 0) {
315
0
        enc_u_putw(pdevc->phase.y, pdata);
316
0
    }
317
318
0
    *psize = pdata - pdata0;
319
0
    return 0;
320
0
}
321
322
/*
323
 * Reconstruct a device color from its serial representation.
324
 *
325
 * Operands:
326
 *
327
 *  pdevc       pointer to the location in which to write the
328
 *              reconstructed device color
329
 *
330
 *  pgs         pointer to the current gs_gstate (to access the
331
 *              current halftone)
332
 *
333
 *  prior_devc  pointer to the current device color (this is provided
334
 *              separately because the device color is not part of the
335
 *              gs_gstate)
336
 *
337
 *  dev         pointer to the current device, used to retrieve process
338
 *              color model information
339
 *
340
 *  pdata       pointer to the buffer to be read
341
 *
342
 *  size        size of the buffer to be read; this should be large
343
 *              enough to hold the entire color description
344
 *
345
 *  mem         pointer to the memory to be used for allocations
346
 *              (ignored here)
347
 *
348
 * Returns:
349
 *
350
 *  # of bytes read if everthing OK, < 0 in the event of an error
351
 */
352
static int
353
gx_dc_ht_colored_read(
354
    gx_device_color *       pdevc,
355
    const gs_gstate *       pgs,
356
    const gx_device_color * prior_devc,
357
    const gx_device *       dev,
358
    int64_t                 offset,
359
    const byte *            pdata,
360
    uint                    size,
361
    gs_memory_t *           mem,        /* ignored */
362
    int                     x0,
363
    int                     y0)
364
0
{
365
0
    gx_device_color         devc;
366
0
    int                     num_comps = dev->color_info.num_components;
367
0
    int                     depth = dev->color_info.depth;
368
0
    const byte *            pdata0 = pdata;
369
0
    int                     flag_bits;
370
371
0
    if (offset != 0)
372
0
        return_error(gs_error_unregistered); /* Not implemented yet. */
373
374
    /* if prior information is available, use it */
375
0
    if (prior_devc != 0 && prior_devc->type == gx_dc_type_ht_colored)
376
0
        devc = *prior_devc;
377
0
    else
378
0
        memset(&devc, 0, sizeof(devc));   /* clear pointers */
379
0
    devc.type = gx_dc_type_ht_colored;
380
381
    /* the number of components is determined by the color model */
382
0
    devc.colors.colored.num_components = num_comps;
383
0
    devc.colors.colored.c_ht = pgs->dev_ht[HT_OBJTYPE_DEFAULT];
384
385
    /*
386
     * Verify that we have at least the flag bits. For performance
387
     * reasons, the routines that convert serialized representations
388
     * of integers do not check buffer size. Hence, in many cases below,
389
     * only a very rough check is made to verify that we have not
390
     * exhausted the buffer. This should not cause a problem in
391
     * practice.
392
     */
393
0
    if (size == 0)
394
0
        return_error(gs_error_rangecheck);
395
0
    size--;
396
0
    flag_bits = *pdata++;
397
398
    /* read the other components provided */
399
0
    if ((flag_bits & dc_ht_colored_has_base) != 0) {
400
0
        if (depth == num_comps) {
401
0
            gx_color_index  base_mask = 0;
402
0
            int             num_bytes = (num_comps + 7) >> 3;
403
0
            int             i, shift = 0;
404
405
0
            if (size < num_bytes)
406
0
                return_error(gs_error_rangecheck);
407
0
            size -= num_bytes;
408
0
            for (i = 0; i < num_bytes; i++, shift += 8)
409
0
                base_mask |= (gx_color_index)(*pdata++) << shift;
410
0
            for (i = 0; i < num_comps; i++, base_mask >>= 1)
411
0
                devc.colors.colored.c_base[i] = base_mask & 0x1;
412
0
        } else {
413
0
            if (size < num_comps)
414
0
                return_error(gs_error_rangecheck);
415
0
            size -= num_comps;
416
0
            memcpy(devc.colors.colored.c_base, pdata, num_comps);
417
0
            pdata += num_comps;
418
0
        }
419
0
    }
420
421
0
    if ((flag_bits & dc_ht_colored_has_level) != 0) {
422
0
        const byte *    pdata_start = pdata;
423
0
        gx_color_index  plane_mask;
424
0
        uint            tmp_mask;
425
0
        int             i;
426
427
0
        if (size < 1)
428
0
            return_error(gs_error_rangecheck);
429
430
0
        if (num_comps > 8 * sizeof(uint)) {
431
0
            enc_u_getw(tmp_mask, pdata);
432
0
            plane_mask = (gx_color_index)tmp_mask;
433
0
            enc_u_getw(tmp_mask, pdata);
434
0
            plane_mask = (((gx_color_index)tmp_mask)<<(8 * sizeof(uint)-1))<<1;
435
0
        } else {
436
0
            enc_u_getw(tmp_mask, pdata);
437
0
            plane_mask = (gx_color_index)tmp_mask;
438
0
        }
439
0
        devc.colors.colored.plane_mask = plane_mask;
440
0
        for (i = 0; i < num_comps; i++, plane_mask >>= 1) {
441
0
            if ((plane_mask & 0x1) != 0) {
442
0
                if (size - (pdata - pdata_start) < 1)
443
0
                    return_error(gs_error_rangecheck);
444
0
                enc_u_getw(devc.colors.colored.c_level[i], pdata);
445
0
            } else
446
0
                devc.colors.colored.c_level[i] = 0;
447
0
        }
448
0
        size -= pdata - pdata_start;
449
0
    }
450
451
0
    if ((flag_bits & dc_ht_colored_has_phase_x) != 0) {
452
0
        enc_u_getw(devc.phase.x, pdata);
453
0
        devc.phase.x += x0;
454
0
    }
455
0
    if ((flag_bits & dc_ht_colored_has_phase_y) != 0) {
456
0
        enc_u_getw(devc.phase.y, pdata);
457
0
        devc.phase.y += y0;
458
0
    }
459
460
    /* everything looks OK */
461
0
    *pdevc = devc;
462
0
    return pdata - pdata0;
463
0
}
464
465
/*
466
 * Get the nonzero components of a coloredhalftone. This is used to
467
 * distinguish components that are given zero intensity due to halftoning
468
 * from those for which the original color intensity was in fact zero.
469
 *
470
 * An original component intensity of zero will yield a c_base value of
471
 * 0 and a c_level of 0. The plane_mask field already contains the latter
472
 * information, so we need only add those components for which c_base is
473
 * non-zero.
474
 */
475
int
476
gx_dc_ht_colored_get_nonzero_comps(
477
    const gx_device_color * pdevc,
478
    const gx_device *       dev_ignored,
479
    gx_color_index *        pcomp_bits )
480
0
{
481
0
    int                     i, ncomps =  pdevc->colors.colored.num_components;
482
0
    gx_color_index          comp_bits = pdevc->colors.colored.plane_mask;
483
484
0
    for (i = 0; i < ncomps; i++) {
485
0
        if (pdevc->colors.colored.c_base[i] != 0)
486
0
            comp_bits |= ((gx_color_index)1) << i;
487
0
    }
488
0
    *pcomp_bits = comp_bits;
489
490
0
    return 0;
491
0
}
492
493
/*
494
 * Define an abbreviation for a heavily used value: the maximum number of
495
 * of device colorants (device colors).
496
 */
497
#define MAX_DCC GX_DEVICE_COLOR_MAX_COMPONENTS
498
/*
499
 * Define a size for the "colors" array.  For less than 5 colors, there are
500
 * 2**n values stored (for a maximum of 16 values).  For 5 or more colors, we
501
 * only store 2 values per color so the array size can be 2 * MAX_DCC.  Use which
502
 * ever is larger for the array size.
503
 */
504
#define MAX_DCC_16 (2 * MAX_DCC < 16 ? 16 : 2 * MAX_DCC)
505
506
/* Forward references. */
507
/* Use a typedef to attempt to work around overly picky compilers. */
508
typedef gx_color_value gx_color_value_array[MAX_DCC];
509
typedef struct color_values_pair_s {
510
    gx_color_value_array values[2];
511
} color_values_pair_t;
512
#define SET_HT_COLORS_PROC(proc)\
513
0
  int proc(\
514
0
              color_values_pair_t *pvp,\
515
0
              gx_color_index colors[MAX_DCC_16],\
516
0
              const gx_const_strip_bitmap *sbits[MAX_DCC],\
517
0
              const gx_device_color *pdevc,\
518
0
              gx_device *dev,\
519
0
              gx_ht_cache *caches[MAX_DCC],\
520
0
              int nplanes\
521
0
              )
522
523
static SET_HT_COLORS_PROC(set_ht_colors_le_4);
524
static SET_HT_COLORS_PROC(set_cmyk_1bit_colors);
525
static SET_HT_COLORS_PROC(set_ht_colors_gt_4);
526
527
#define SET_COLOR_HT_PROC(proc)\
528
0
  void proc(\
529
0
                byte *dest_data, /* the output tile */\
530
0
                uint dest_raster, /* ibid. */\
531
0
                int px, /* the initial phase of the output tile */\
532
0
                int py,\
533
0
                int w,  /* how much of the tile to set */\
534
0
                int h,\
535
0
                int depth,  /* depth of tile (4, 8, 16, 24, 32) */\
536
0
                int special,  /* >0 means special 1-bit CMYK */\
537
0
                int nplanes,\
538
0
                gx_color_index plane_mask,  /* which planes are halftoned */\
539
0
                gx_device *dev,   /* in case we are mapping lazily */\
540
0
                const color_values_pair_t *pvp, /* color values ditto */\
541
0
                gx_color_index colors[MAX_DCC_16],  /* the actual colors for the tile, */\
542
0
                                /* actually [nplanes] */\
543
0
                const gx_const_strip_bitmap * sbits[MAX_DCC_16] /* the bitmaps for the planes, */\
544
0
                                /* actually [nplanes] */\
545
0
                )
546
547
static SET_COLOR_HT_PROC(set_color_ht_le_4);
548
static SET_COLOR_HT_PROC(set_color_ht_gt_4);
549
550
/* Prepare to use a colored halftone, by loading the default cache. */
551
static int
552
gx_dc_ht_colored_load(gx_device_color * pdevc, const gs_gstate * pgs,
553
                      gx_device * ignore_dev, gs_color_select_t select)
554
0
{
555
    /* TO_DO_DEVICEN */
556
557
0
    return 0;
558
0
}
559
560
/* Fill a rectangle with a colored halftone. */
561
/* Note that we treat this as "texture" for RasterOp. */
562
static int
563
gx_dc_ht_colored_fill_rectangle(const gx_device_color * pdevc,
564
                                int x, int y, int w, int h,
565
                                gx_device * dev, gs_logical_operation_t lop,
566
                                const gx_rop_source_t * source)
567
0
{
568
0
#if defined(PACIFY_VALGRIND) || defined(MEMENTO)
569
0
    ulong tbits[tile_longs_allocated] = { 0 };
570
#else
571
    ulong tbits[tile_longs_allocated];
572
#endif
573
0
    const uint tile_bytes = tile_longs * size_of(long);
574
0
    gx_strip_bitmap tiles;
575
0
    gx_rop_source_t no_source;
576
0
    const gx_device_halftone *pdht = pdevc->colors.colored.c_ht;
577
0
    int depth = dev->color_info.depth;
578
0
    int nplanes = dev->color_info.num_components;
579
580
0
    SET_HT_COLORS_PROC((*set_ht_colors)) =
581
0
        (
582
#if USE_SLOW_CODE
583
         set_ht_colors_gt_4
584
#else
585
0
         (dev_proc(dev, dev_spec_op)(dev, gxdso_is_std_cmyk_1bit, NULL, 0) > 0) ?
586
0
            set_cmyk_1bit_colors :
587
0
            nplanes <= 4 ? set_ht_colors_le_4 :
588
0
                          set_ht_colors_gt_4
589
0
#endif
590
0
         );
591
0
    SET_COLOR_HT_PROC((*set_color_ht)) =
592
0
        (
593
0
#if !USE_SLOW_CODE
594
0
         !(pdevc->colors.colored.plane_mask & ~(gx_color_index)15) &&
595
0
          set_ht_colors != set_ht_colors_gt_4 ?
596
0
           set_color_ht_le_4 :
597
0
#endif
598
0
         set_color_ht_gt_4);
599
0
    color_values_pair_t vp;
600
0
    gx_color_index colors[MAX_DCC_16];
601
0
    const gx_const_strip_bitmap *sbits[MAX_DCC];
602
0
    gx_ht_cache *caches[MAX_DCC];
603
0
    int special;
604
0
    int code = 0;
605
0
    int raster;
606
0
    uint size_x;
607
0
    int dw, dh;
608
0
    int lw = pdht->lcm_width, lh = pdht->lcm_height;
609
0
    bool no_rop;
610
0
    int i;
611
0
    int origx, origy;
612
613
    /* This routine cannot build 3bit chunky halftones, as 3 bit
614
     * things don't pack nicely into bytes or words. Accordingly
615
     * treat 3 bit things as 4 bit things. This is appropriate when
616
     * generating halftones for planar. */
617
0
    if (depth == 3)
618
0
        depth = 4;
619
620
0
    if (w <= 0 || h <= 0)
621
0
        return 0;
622
0
    origx = x;
623
0
    origy = y;
624
0
    if ((w | h) >= 16) {
625
        /* It's worth taking the trouble to check the clipping box. */
626
0
        gs_fixed_rect cbox;
627
0
        int t;
628
629
0
        dev_proc(dev, get_clipping_box)(dev, &cbox);
630
0
        if ((t = fixed2int(cbox.p.x)) > x) {
631
0
            if ((w += x - t) <= 0)
632
0
                return 0;
633
0
            x = t;
634
0
        }
635
0
        if ((t = fixed2int(cbox.p.y)) > y) {
636
0
            if ((h += y - t) <= 0)
637
0
                return 0;
638
0
            y = t;
639
0
        }
640
0
        if ((t = fixed2int(cbox.q.x)) < x + w)
641
0
            if ((w = t - x) <= 0)
642
0
                return 0;
643
0
        if ((t = fixed2int(cbox.q.y)) < y + h)
644
0
            if ((h = t - y) <= 0)
645
0
                return 0;
646
0
    }
647
    /* Colored halftone patterns are unconditionally opaque. */
648
0
    lop &= ~lop_T_transparent;
649
0
    if (pdht->components == 0) {
650
0
        caches[0] = caches[1] = caches[2] = caches[3] = pdht->order.cache;
651
0
        for (i = 4; i < nplanes; ++i)
652
0
            caches[i] = pdht->order.cache;
653
0
    } else {
654
0
        gx_ht_order_component *pocs = pdht->components;
655
656
0
        for (i = 0; i < nplanes; ++i)
657
0
            caches[i] = pocs[i].corder.cache;
658
0
    }
659
0
    special = set_ht_colors(&vp, colors, sbits, pdevc, dev, caches, nplanes);
660
0
    no_rop = source == NULL && lop_no_S_is_T(lop);
661
0
    if ((!no_rop) && (source == NULL))
662
0
        set_rop_no_source(source, no_source, dev);
663
664
    /*
665
     * If the LCM of the plane cell sizes is smaller than the rectangle
666
     * being filled, compute a single tile and let strip_tile_rectangle
667
     * do the replication.
668
     */
669
0
    if ((w > lw || h > lh) &&
670
0
        (raster = bitmap_raster(lw * depth)) <= tile_bytes / lh
671
0
        ) {
672
        /*
673
         * The only reason we need to do fit_fill here is that if the
674
         * device is a clipper, the caller might be counting on it to do
675
         * all necessary clipping.  Actually, we should clip against the
676
         * device's clipping box, not the default....
677
         */
678
0
        fit_fill(dev, x, y, w, h);
679
        /* Check to make sure we still have a big rectangle. */
680
0
        if (w > lw || h > lh) {
681
0
            tiles.data = (byte *)tbits;
682
0
            tiles.raster = raster;
683
0
            tiles.rep_width = tiles.size.x = lw;
684
0
            tiles.rep_height = tiles.size.y = lh;
685
0
            tiles.id = gs_next_ids(pdht->rc.memory, 1);
686
0
            tiles.rep_shift = tiles.shift = 0;
687
0
            tiles.num_planes = 1;
688
0
            set_color_ht((byte *)tbits, raster, 0, 0, lw, lh, depth,
689
0
                         special, nplanes, pdevc->colors.colored.plane_mask,
690
0
                         dev, &vp, colors, sbits);
691
0
            if (no_rop)
692
0
                return (*dev_proc(dev, strip_tile_rectangle)) (dev, &tiles,
693
0
                                                               x, y, w, h,
694
0
                                                               gx_no_color_index,
695
0
                                                               gx_no_color_index,
696
0
                                                               pdevc->phase.x,
697
0
                                                               pdevc->phase.y);
698
0
            return (*dev_proc(dev, strip_copy_rop2))
699
0
                               (dev,
700
0
                                source->sdata + (y - origy) * source->sraster,
701
0
                                source->sourcex + (x - origx),
702
0
                                source->sraster, source->id,
703
0
                                (source->use_scolors ? source->scolors : NULL),
704
0
                                &tiles, NULL,
705
0
                                x, y, w, h,
706
0
                                pdevc->phase.x, pdevc->phase.y, lop,
707
0
                                source->planar_height);
708
0
        }
709
0
    }
710
0
    size_x = w * depth;
711
0
    raster = bitmap_raster(size_x);
712
0
    if (raster > tile_bytes) {
713
        /*
714
         * We can't even do an entire line at once.  See above for
715
         * why we do the X equivalent of fit_fill here.
716
         */
717
0
        if (x < 0)
718
0
            w += x, x = 0;
719
0
        if (x > dev->width - w)
720
0
            w = dev->width - x;
721
0
        if (w <= 0)
722
0
            return 0;
723
0
        size_x = w * depth;
724
0
        raster = bitmap_raster(size_x);
725
0
        if (raster > tile_bytes) {
726
            /* We'll have to do a partial line. */
727
0
            dw = tile_bytes * 8 / depth;
728
0
            size_x = dw * depth;
729
0
            raster = bitmap_raster(size_x);
730
0
            dh = 1;
731
0
            goto fit;
732
0
        }
733
0
    }
734
    /* Do as many lines as will fit. */
735
0
    dw = w;
736
0
    dh = tile_bytes / raster;
737
0
    if (dh > h)
738
0
        dh = h;
739
0
fit:        /* Now the tile will definitely fit. */
740
0
    if (!no_rop) {
741
0
        tiles.data = (byte *)tbits;
742
0
        tiles.id = gx_no_bitmap_id;
743
0
        tiles.raster = raster;
744
0
        tiles.rep_width = tiles.size.x = size_x / depth;
745
0
        tiles.rep_shift = tiles.shift = 0;
746
0
        tiles.num_planes = 1;
747
0
    }
748
0
    while (w) {
749
0
        int cy = y, ch = dh, left = h;
750
751
0
        for (;;) {
752
0
            set_color_ht((byte *)tbits, raster,
753
0
                         x + pdevc->phase.x, cy + pdevc->phase.y,
754
0
                         dw, ch, depth, special, nplanes,
755
0
                         pdevc->colors.colored.plane_mask,
756
0
                         dev, &vp, colors, sbits);
757
0
            if (no_rop) {
758
0
                code = (*dev_proc(dev, copy_color))
759
0
                    (dev, (byte *)tbits, 0, raster, gx_no_bitmap_id,
760
0
                     x, cy, dw, ch);
761
0
            } else {
762
0
                tiles.rep_height = tiles.size.y = ch;
763
0
                code = (*dev_proc(dev, strip_copy_rop2))
764
0
                          (dev, source->sdata + source->sraster * (cy-origy),
765
0
                           source->sourcex + (x - origx),
766
0
                           source->sraster,
767
0
                           source->id,
768
0
                           (source->use_scolors ? source->scolors : NULL),
769
0
                           &tiles, NULL, x, cy, dw, ch, 0, 0, lop,
770
0
                           source->planar_height);
771
0
            }
772
0
            if (code < 0)
773
0
                return code;
774
0
            if (!(left -= ch))
775
0
                break;
776
0
            cy += ch;
777
0
            if (ch > left)
778
0
                ch = left;
779
0
        }
780
0
        if (!(w -= dw))
781
0
            break;
782
0
        x += dw;
783
0
        if (dw > w)
784
0
            dw = w;
785
0
    }
786
0
    return code;
787
0
}
788
789
/* ---------------- Color table setup ---------------- */
790
791
/*
792
 * We could cache this if we had a place to store it.  Even a 1-element
793
 * cache would help performance substantially.
794
 *   Key: device + c_base/c_level of device color
795
 *   Value: colors table
796
 */
797
798
/*
799
 * We construct color halftone tiles out of multiple "planes".
800
 * Each plane specifies halftoning for one component (R/G/B, C/M/Y/K,
801
 * or DeviceN components).
802
 */
803
804
static const struct {
805
    ulong pad;      /* to get bytes aligned properly */
806
    byte bytes[sizeof(ulong) * 8];  /* 8 is arbitrary */
807
} ht_no_bitmap_data = { 0 };
808
static const gx_const_strip_bitmap ht_no_bitmap = {
809
    &ht_no_bitmap_data.bytes[0], sizeof(ulong),
810
    {sizeof(ulong) * 8, sizeof(ht_no_bitmap_data.bytes) / sizeof(ulong)},
811
    gx_no_bitmap_id, 1, 1, 0, 0
812
};
813
814
/* Set the color value(s) and halftone mask for one plane. */
815
static inline void set_plane_color(int i, color_values_pair_t *pvp, const gx_device_color * pdc,
816
    const gx_const_strip_bitmap * sbits[MAX_DCC], gx_ht_cache * caches[MAX_DCC],
817
    gx_color_value max_color, bool invert)
818
0
{
819
0
    uint q = pdc->colors.colored.c_base[i];
820
0
    uint r = pdc->colors.colored.c_level[i];
821
822
0
    pvp->values[0][i] = fractional_color(q, max_color);
823
0
    if (r == 0)
824
0
        pvp->values[1][i] = pvp->values[0][i], sbits[i] = &ht_no_bitmap;
825
0
    else if (!invert) {
826
0
        pvp->values[1][i] = fractional_color(q + 1, max_color);
827
0
        sbits[i] = (const gx_const_strip_bitmap *) &gx_render_ht(caches[i], r)->tiles;
828
0
    } else {
829
0
        const gx_device_halftone *pdht = pdc->colors.colored.c_ht;
830
0
        int nlevels =
831
0
            (pdht->components ? pdht->components[i].corder.num_levels : pdht->order.num_levels);
832
0
        pvp->values[1][i] = pvp->values[0][i];
833
0
        pvp->values[0][i] = fractional_color(q + 1, max_color);
834
0
        sbits[i] = (const gx_const_strip_bitmap *) &gx_render_ht(caches[i], nlevels - r)->tiles;
835
0
    }
836
0
}
837
838
/* Set up the colors and the individual plane halftone bitmaps. */
839
static int
840
set_ht_colors_le_4(color_values_pair_t *pvp /* only used internally */,
841
                   gx_color_index colors[MAX_DCC_16] /* 16 used */,
842
                   const gx_const_strip_bitmap * sbits[MAX_DCC],
843
                   const gx_device_color * pdc, gx_device * dev,
844
                   gx_ht_cache * caches[MAX_DCC], int nplanes)
845
0
{
846
0
    gx_color_value max_color = dev->color_info.dither_colors - 1;
847
0
    gx_color_value cvalues[4];
848
    /*
849
     * NB: the halftone orders are all set up for an additive color space.
850
     *     To make these work with a subtractive device space such as CMYK,
851
     *     it is necessary to invert both the color level and the color
852
     *     pair. Note that if the original color was provided an additive
853
     *     space, this will reverse (in an approximate sense) the color
854
     *     conversion performed to express the color in the device space.
855
     */
856
0
    bool invert = dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE;
857
858
0
    set_plane_color(0, pvp, pdc, sbits, caches, max_color, invert);
859
0
    if (nplanes >= 2) {
860
0
        set_plane_color(1, pvp, pdc, sbits, caches, max_color, invert);
861
0
    }
862
0
    if (nplanes >= 3) {
863
0
        set_plane_color(2, pvp, pdc, sbits, caches, max_color, invert);
864
0
    }
865
0
    if (nplanes == 3) {
866
0
#define M(i)\
867
0
  cvalues[0] = pvp->values[(i) & 1][0];\
868
0
  cvalues[1] = pvp->values[((i) & 2) >> 1][1];\
869
0
  cvalues[2] = pvp->values[(i) >> 2][2];\
870
0
  colors[i] = dev_proc(dev, encode_color)(dev, cvalues);
871
872
0
            M(0); M(1); M(2); M(3); M(4); M(5); M(6); M(7);
873
0
#undef M
874
0
    } else if (nplanes > 3){
875
0
        set_plane_color(3, pvp, pdc, sbits, caches, max_color, invert);
876
0
        if (nplanes > 4) {
877
            /*
878
             * Set colors for any planes beyond the 4th.  Since this code
879
             * only handles the case of at most 4 active planes, we know
880
             * that any further planes are constant.
881
             */
882
            /****** DOESN'T MAP COLORS RIGHT, DOESN'T HANDLE ALPHA ******/
883
0
            int pi;
884
885
0
            for (pi = 4; pi < nplanes; ++pi) {
886
0
                pvp->values[1][pi] = pvp->values[0][pi] =
887
0
                    fractional_color(pdc->colors.colored.c_base[pi], max_color);
888
0
                sbits[pi] = &ht_no_bitmap;
889
0
            }
890
0
        }
891
        /*
892
         * For CMYK output, especially if the input was RGB, it's
893
         * common for one or more of the components to be zero.
894
         * Each zero component can cut the cost of color mapping in
895
         * half, so it's worth doing a little checking here.
896
         */
897
0
#define M(i)\
898
0
    cvalues[0] = pvp->values[(i) & 1][0];\
899
0
    cvalues[1] = pvp->values[((i) & 2) >> 1][1];\
900
0
    cvalues[2] = pvp->values[((i) & 4) >> 2][2];\
901
0
    cvalues[3] = pvp->values[(i) >> 3][3];\
902
0
    colors[i] = dev_proc(dev, encode_color)(dev, cvalues)
903
904
      /* We know that plane_mask <= 15. */
905
0
        switch ((int)pdc->colors.colored.plane_mask) {
906
0
            case 15:
907
0
                M(15); M(14); M(13); M(12);
908
0
                M(11); M(10); M(9); M(8);
909
0
            case 7:
910
0
                M(7); M(6); M(5); M(4);
911
0
c3:     case 3:
912
0
                M(3); M(2);
913
0
c1:     case 1:
914
0
                M(1);
915
0
                break;
916
0
            case 14:
917
0
                M(14); M(12); M(10); M(8);
918
0
            case 6:
919
0
                M(6); M(4);
920
0
c2:     case 2:
921
0
                M(2);
922
0
                break;
923
0
            case 13:
924
0
                M(13); M(12); M(9); M(8);
925
0
            case 5:
926
0
                M(5); M(4);
927
0
                goto c1;
928
0
            case 12:
929
0
                M(12); M(8);
930
0
            case 4:
931
0
                M(4);
932
0
                break;
933
0
            case 11:
934
0
                M(11); M(10); M(9); M(8);
935
0
                goto c3;
936
0
            case 10:
937
0
                M(10); M(8);
938
0
                goto c2;
939
0
            case 9:
940
0
                M(9); M(8);
941
0
                goto c1;
942
0
            case 8:
943
0
                M(8);
944
0
                break;
945
0
            case 0:;
946
0
        }
947
0
        M(0);
948
949
0
#undef M
950
0
    }
951
0
    return 0;
952
0
}
953
954
/* Set up colors using the standard 1-bit CMYK mapping. */
955
static int
956
set_cmyk_1bit_colors(color_values_pair_t *ignore_pvp,
957
                     gx_color_index colors[MAX_DCC_16] /*2 used*/,
958
                     const gx_const_strip_bitmap * sbits[MAX_DCC /*4 used*/],
959
                     const gx_device_color * pdc, gx_device * dev,
960
                     gx_ht_cache * caches[MAX_DCC /*4 used*/],
961
                     int nplanes /*4*/)
962
0
{
963
0
    const gx_device_halftone *pdht = pdc->colors.colored.c_ht;
964
    /*
965
     * By reversing the order of the planes, we make the pixel values
966
     * line up with the color indices.  Then instead of a lookup, we
967
     * can compute the pixels directly using a Boolean function.
968
     *
969
     * We compute each output bit
970
     *   out[i] = (in[i] & mask1) | (~in[i] & mask0)
971
     * We store the two masks in colors[0] and colors[1], since the
972
     * colors array is otherwise unused in this case.  We duplicate
973
     * the values in all the nibbles so we can do several pixels at a time.
974
     */
975
0
    bits32 mask0 = 0, mask1 = 0;
976
0
#define SET_PLANE_COLOR_CMYK(i, mask)\
977
0
  BEGIN\
978
0
    uint r = pdc->colors.colored.c_level[i];\
979
0
\
980
0
    if (r == 0) {\
981
0
        if (pdc->colors.colored.c_base[i])\
982
0
            mask0 |= mask, mask1 |= mask;\
983
0
        sbits[3 - i] = &ht_no_bitmap;\
984
0
    } else {\
985
0
        int nlevels =\
986
0
            (pdht->components ?\
987
0
             pdht->components[i].corder.num_levels :\
988
0
             pdht->order.num_levels);\
989
0
\
990
0
        mask0 |= mask;\
991
0
        sbits[3 - i] = (const gx_const_strip_bitmap *)\
992
0
            &gx_render_ht(caches[i], nlevels - r)->tiles;\
993
0
    }\
994
0
  END
995
         /* Suppress a compiler warning about signed/unsigned constants. */
996
0
    SET_PLANE_COLOR_CMYK(0, /*0x88888888*/ (bits32)~0x77777777);
997
0
    SET_PLANE_COLOR_CMYK(1, 0x44444444);
998
0
    SET_PLANE_COLOR_CMYK(2, 0x22222222);
999
0
    SET_PLANE_COLOR_CMYK(3, 0x11111111);
1000
1001
0
#undef SET_PLANE_COLOR_CMYK
1002
0
    {
1003
0
        gx_ht_cache *ctemp;
1004
1005
0
        ctemp = caches[0], caches[0] = caches[3], caches[3] = ctemp;
1006
0
        ctemp = caches[1], caches[1] = caches[2], caches[2] = ctemp;
1007
0
    }
1008
0
    colors[0] = mask0;
1009
0
    colors[1] = mask1;
1010
0
    return 1;
1011
0
}
1012
1013
/*
1014
 * Set up colors for >4 planes.  In this case, we assume that the color
1015
 * component values are "separable".  (That we can form a gx_color_index value
1016
 * for a color by a bit wise or of the gx_color_index values of the individual
1017
 * components.)
1018
 */
1019
static int
1020
set_ht_colors_gt_4(color_values_pair_t *pvp,
1021
                   gx_color_index colors[MAX_DCC_16 /* 2 * nplanes */],
1022
                   const gx_const_strip_bitmap * sbits[MAX_DCC],
1023
                   const gx_device_color * pdc, gx_device * dev,
1024
                   gx_ht_cache * caches[MAX_DCC], int nplanes)
1025
0
{
1026
0
    gx_color_value max_color = dev->color_info.dither_colors - 1;
1027
0
    bool invert = dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE;
1028
0
    gx_color_index plane_mask = pdc->colors.colored.plane_mask;
1029
0
    int i;
1030
0
    gx_color_value cv[MAX_DCC] = {0};
1031
1032
    /* Set the color values and halftone caches. */
1033
0
    for (i = 0; i < nplanes; ++i) {
1034
0
        if ((plane_mask >> i) & 1)
1035
0
            set_plane_color(i, pvp, pdc, sbits, caches, max_color, invert);
1036
0
        else {
1037
0
            pvp->values[1][i] = pvp->values[0][i] =
1038
0
                fractional_color(pdc->colors.colored.c_base[i], max_color);
1039
0
            sbits[i] = &ht_no_bitmap;
1040
0
        }
1041
0
    }
1042
    /*
1043
     * Determine a gs_color_index value for each pair of component values.
1044
     * We assume that an overall index value can be formed from the
1045
     * bitwise or of each component.  We calculate a value for both
1046
     * the high and low value of each component.  These are stored
1047
     * in adjacent locations in 'colors'.
1048
     */
1049
0
    for (i = 0; i < nplanes; i++ ) {
1050
0
        cv[i] = pvp->values[0][i];
1051
0
        colors[2 * i] = dev_proc(dev, encode_color)(dev, cv);
1052
        /* We only need both values for components being halftoned */
1053
0
        if ((plane_mask >> i) & 1) {
1054
0
            cv[i] = pvp->values[1][i];
1055
0
            colors[2 * i + 1] = dev_proc(dev, encode_color)(dev, cv);
1056
0
        }
1057
0
        cv[i] = 0;
1058
0
    }
1059
1060
0
    return 0;
1061
0
}
1062
1063
/* ---------------- Color rendering ---------------- */
1064
1065
/* Define the bookkeeping structure for each plane of halftone rendering. */
1066
typedef struct tile_cursor_s {
1067
    int tile_shift;   /* X shift per copy of tile */
1068
    int xoffset;
1069
    int xshift;
1070
    uint xbytes;
1071
    int xbits;
1072
    const byte *row;
1073
    const byte *tdata;
1074
    uint raster;
1075
    const byte *data;
1076
    int bit_shift;
1077
} tile_cursor_t;
1078
1079
/*
1080
 * Initialize one plane cursor, including setting up for the first row
1081
 * (data and bit_shift).
1082
 */
1083
static void
1084
init_tile_cursor(int i, tile_cursor_t *ptc, const gx_const_strip_bitmap *btile,
1085
                 int endx, int lasty)
1086
0
{
1087
0
    int tw = btile->size.x;
1088
0
    int bx = ((ptc->tile_shift = btile->shift) == 0 ? endx :
1089
0
              endx + lasty / btile->size.y * ptc->tile_shift) % tw;
1090
0
    int by = lasty % btile->size.y;
1091
1092
0
    ptc->xoffset = bx >> 3;
1093
0
    ptc->xshift = 8 - (bx & 7);
1094
0
    ptc->xbytes = (tw - 1) >> 3;
1095
0
    ptc->xbits = ((tw - 1) & 7) + 1;
1096
0
    ptc->tdata = btile->data;
1097
0
    ptc->raster = btile->raster;
1098
0
    ptc->row = ptc->tdata + by * (int)ptc->raster;
1099
0
    ptc->data = ptc->row + ptc->xoffset;
1100
0
    ptc->bit_shift = ptc->xshift;
1101
0
    if_debug6('h', "[h]plane %d: size=%d,%d shift=%d bx=%d by=%d\n",
1102
0
              i, tw, btile->size.y, btile->shift, bx, by);
1103
0
}
1104
1105
/* Step a cursor to the next row. */
1106
static void
1107
wrap_shifted_cursor(tile_cursor_t *ptc, const gx_const_strip_bitmap *psbit)
1108
0
{
1109
0
    ptc->row += ptc->raster * (psbit->size.y - 1);
1110
0
    if (ptc->tile_shift) {
1111
0
        if ((ptc->xshift += ptc->tile_shift) >= 8) {
1112
0
            if ((ptc->xoffset -= ptc->xshift >> 3) < 0) {
1113
                /* wrap around in X */
1114
0
                int bx = (ptc->xoffset << 3) + 8 - (ptc->xshift & 7) +
1115
0
                    psbit->size.x;
1116
1117
0
                ptc->xoffset = bx >> 3;
1118
0
                ptc->xshift = 8 - (bx & 7);
1119
0
            } else
1120
0
                ptc->xshift &= 7;
1121
0
        }
1122
0
    }
1123
0
}
1124
#define STEP_ROW(c, i)\
1125
0
  BEGIN\
1126
0
    if (c.row > c.tdata)\
1127
0
      c.row -= c.raster;\
1128
0
    else { /* wrap around to end of tile */\
1129
0
        wrap_shifted_cursor(&c, sbits[i]);\
1130
0
    }\
1131
0
    c.data = c.row + c.xoffset;\
1132
0
    c.bit_shift = c.xshift;\
1133
0
  END
1134
1135
/* Define a table for expanding 8x1 bits to 8x4. */
1136
static const bits32 expand_8x1_to_8x4[256] = {
1137
#define X16(c)\
1138
  c+0, c+1, c+0x10, c+0x11, c+0x100, c+0x101, c+0x110, c+0x111,\
1139
  c+0x1000, c+0x1001, c+0x1010, c+0x1011, c+0x1100, c+0x1101, c+0x1110, c+0x1111
1140
    X16(0x00000000), X16(0x00010000), X16(0x00100000), X16(0x00110000),
1141
    X16(0x01000000), X16(0x01010000), X16(0x01100000), X16(0x01110000),
1142
    X16(0x10000000), X16(0x10010000), X16(0x10100000), X16(0x10110000),
1143
    X16(0x11000000), X16(0x11010000), X16(0x11100000), X16(0x11110000)
1144
#undef X16
1145
};
1146
1147
/*
1148
 * Render the combined halftone for nplanes <= 4.
1149
 */
1150
static void
1151
set_color_ht_le_4(byte *dest_data, uint dest_raster, int px, int py,
1152
                  int w, int h, int depth, int special, int nplanes,
1153
                  gx_color_index plane_mask, gx_device *ignore_dev,
1154
                  const color_values_pair_t *ignore_pvp,
1155
                  gx_color_index colors[MAX_DCC_16],
1156
                  const gx_const_strip_bitmap * sbits[MAX_DCC_16])
1157
0
{
1158
    /*
1159
     * Note that the planes are specified in the order RGB or CMYK, but
1160
     * the indices used for the internal colors array are BGR or KYMC,
1161
     * except for the special 1-bit CMYK case.
1162
     */
1163
0
    int x, y;
1164
0
    tile_cursor_t cursor[MAX_DCC];
1165
0
    int dbytes = depth >> 3;
1166
0
    byte *dest_row =
1167
0
        dest_data + dest_raster * (h - 1) + (w * depth) / 8;
1168
1169
0
    if (special > 0) {
1170
        /* Planes are in reverse order. */
1171
0
        plane_mask =
1172
0
            "\000\010\004\014\002\012\006\016\001\011\005\015\003\013\007\017"[plane_mask];
1173
0
    }
1174
0
    if_debug6('h',
1175
0
              "[h]color_ht_le_4: x=%d y=%d w=%d h=%d plane_mask=0x%lu depth=%d\n",
1176
0
              px, py, w, h, (ulong)plane_mask, depth);
1177
1178
    /* Do one-time cursor initialization. */
1179
0
    {
1180
0
        int endx = w + px;
1181
0
        int lasty = h - 1 + py;
1182
1183
0
        if (plane_mask & 1)
1184
0
            init_tile_cursor(0, &cursor[0], sbits[0], endx, lasty);
1185
0
        if (plane_mask & 2)
1186
0
            init_tile_cursor(1, &cursor[1], sbits[1], endx, lasty);
1187
0
        if (plane_mask & 4)
1188
0
            init_tile_cursor(2, &cursor[2], sbits[2], endx, lasty);
1189
0
        if (plane_mask & 8)
1190
0
            init_tile_cursor(3, &cursor[3], sbits[3], endx, lasty);
1191
0
    }
1192
1193
    /* Now compute the actual tile. */
1194
0
    for (y = h; ; dest_row -= dest_raster) {
1195
0
        byte *dest = dest_row;
1196
1197
0
        --y;
1198
0
        for (x = w; x > 0;) {
1199
0
            bits32 indices;
1200
0
            int nx, i;
1201
0
            register uint bits;
1202
1203
/* Get the next byte's worth of bits.  Note that there may be */
1204
/* excess bits set beyond the 8th. */
1205
0
#define NEXT_BITS(c)\
1206
0
  BEGIN\
1207
0
    if (c.data > c.row) {\
1208
0
      bits = ((c.data[-1] << 8) | *c.data) >> c.bit_shift;\
1209
0
      c.data--;\
1210
0
    } else {\
1211
0
      bits = *c.data >> c.bit_shift;\
1212
0
      c.data += c.xbytes;\
1213
0
      if ((c.bit_shift -= c.xbits) < 0) {\
1214
0
        bits |= *c.data << -c.bit_shift;\
1215
0
        c.bit_shift += 8;\
1216
0
      } else {\
1217
0
        bits |= ((c.data[-1] << 8) | *c.data) >> c.bit_shift;\
1218
0
        c.data--;\
1219
0
      }\
1220
0
    }\
1221
0
  END
1222
0
            if (plane_mask & 1) {
1223
0
                NEXT_BITS(cursor[0]);
1224
0
                indices = expand_8x1_to_8x4[bits & 0xff];
1225
0
            } else
1226
0
                indices = 0;
1227
0
            if (plane_mask & 2) {
1228
0
                NEXT_BITS(cursor[1]);
1229
0
                indices |= expand_8x1_to_8x4[bits & 0xff] << 1;
1230
0
            }
1231
0
            if (plane_mask & 4) {
1232
0
                NEXT_BITS(cursor[2]);
1233
0
                indices |= expand_8x1_to_8x4[bits & 0xff] << 2;
1234
0
            }
1235
0
            if (plane_mask & 8) {
1236
0
                NEXT_BITS(cursor[3]);
1237
0
                indices |= expand_8x1_to_8x4[bits & 0xff] << 3;
1238
0
            }
1239
0
#undef NEXT_BITS
1240
0
            nx = min(x, 8); /* 1 <= nx <= 8 */
1241
0
            x -= nx;
1242
0
            switch (dbytes) {
1243
0
                case 0: /* 4 */
1244
0
                    if (special > 0) {
1245
                        /* Special 1-bit CMYK. */
1246
                        /* Compute all the pixels at once! */
1247
0
                        indices =
1248
0
                            (indices & colors[1]) | (~indices & colors[0]);
1249
0
                        i = nx;
1250
0
                        if ((x + nx) & 1) {
1251
                            /* First pixel is even nibble. */
1252
0
                            *dest = (*dest & 0xf) +
1253
0
                                ((indices & 0xf) << 4);
1254
0
                            indices >>= 4;
1255
0
                            --i;
1256
0
                        }
1257
                        /* Now 0 <= i <= 8. */
1258
0
                        for (; (i -= 2) >= 0; indices >>= 8)
1259
0
                            *--dest = (byte)indices;
1260
                        /* Check for final odd nibble. */
1261
0
                        if (i & 1)
1262
0
                            *--dest = indices & 0xf;
1263
0
                    } else {
1264
                        /* Other 4-bit pixel */
1265
0
                        i = nx;
1266
0
                        if ((x + nx) & 1) {
1267
                            /* First pixel is even nibble. */
1268
0
                            *dest = (*dest & 0xf) +
1269
0
                                ((byte)colors[indices & 0xf] << 4);
1270
0
                            indices >>= 4;
1271
0
                            --i;
1272
0
                        }
1273
                        /* Now 0 <= i <= 8. */
1274
0
                        for (; (i -= 2) >= 0; indices >>= 8)
1275
0
                            *--dest =
1276
0
                                (byte)colors[indices & 0xf] +
1277
0
                                ((byte)colors[(indices >> 4) & 0xf]
1278
0
                                 << 4);
1279
                        /* Check for final odd nibble. */
1280
0
                        if (i & 1)
1281
0
                            *--dest = (byte)colors[indices & 0xf];
1282
0
                    }
1283
0
                    break;
1284
0
                case 4: /* 32 */
1285
0
                    for (i = nx; --i >= 0; indices >>= 4) {
1286
0
                        bits32 tcolor = (bits32)colors[indices & 0xf];
1287
1288
0
                        dest -= 4;
1289
0
                        dest[3] = (byte)tcolor;
1290
0
                        dest[2] = (byte)(tcolor >> 8);
1291
0
                        tcolor >>= 16;
1292
0
                        dest[1] = (byte)tcolor;
1293
0
                        dest[0] = (byte)(tcolor >> 8);
1294
0
                    }
1295
0
                    break;
1296
0
                case 3: /* 24 */
1297
0
                    for (i = nx; --i >= 0; indices >>= 4) {
1298
0
                        bits32 tcolor = (bits32)colors[indices & 0xf];
1299
1300
0
                        dest -= 3;
1301
0
                        dest[2] = (byte) tcolor;
1302
0
                        dest[1] = (byte)(tcolor >> 8);
1303
0
                        dest[0] = (byte)(tcolor >> 16);
1304
0
                    }
1305
0
                    break;
1306
0
                case 2: /* 16 */
1307
0
                    for (i = nx; --i >= 0; indices >>= 4) {
1308
0
                        uint tcolor =
1309
0
                            (uint)colors[indices & 0xf];
1310
1311
0
                        dest -= 2;
1312
0
                        dest[1] = (byte)tcolor;
1313
0
                        dest[0] = (byte)(tcolor >> 8);
1314
0
                    }
1315
0
                    break;
1316
0
                case 1: /* 8 */
1317
0
                    for (i = nx; --i >= 0; indices >>= 4)
1318
0
                        *--dest = (byte)colors[indices & 0xf];
1319
0
                    break;
1320
0
            }
1321
0
        }
1322
0
        if (y == 0)
1323
0
            break;
1324
1325
0
        if (plane_mask & 1)
1326
0
            STEP_ROW(cursor[0], 0);
1327
0
        if (plane_mask & 2)
1328
0
            STEP_ROW(cursor[1], 1);
1329
0
        if (plane_mask & 4)
1330
0
            STEP_ROW(cursor[2], 2);
1331
0
        if (plane_mask & 8)
1332
0
            STEP_ROW(cursor[3], 3);
1333
0
    }
1334
0
}
1335
1336
/*
1337
 * Render the combined halftone for nplanes > 4.  This routine assumes
1338
 * that we can form a gx_color_index value by the bitwise or index values
1339
 * for each of the individual components.
1340
 */
1341
static void
1342
set_color_ht_gt_4(byte *dest_data, uint dest_raster, int px, int py,
1343
                  int w, int h, int depth, int special, int num_planes,
1344
                  gx_color_index plane_mask, gx_device *dev,
1345
                  const color_values_pair_t *pvp,
1346
                  gx_color_index colors[MAX_DCC_16],
1347
                  const gx_const_strip_bitmap * sbits[MAX_DCC_16])
1348
0
{
1349
0
    int x, y;
1350
0
    tile_cursor_t cursor[MAX_DCC];
1351
0
    int dbytes = depth >> 3;
1352
0
    byte *dest_row =
1353
0
        dest_data + dest_raster * (h - 1) + (w * depth) / 8;
1354
0
    int pmin, pmax;
1355
0
    gx_color_index base_color = 0;
1356
1357
    /* Compute the range of active planes. */
1358
0
    if (plane_mask == 0)
1359
0
        pmin = 0, pmax = -1;
1360
0
    else {
1361
0
        for (pmin = 0; !((plane_mask >> pmin) & 1); )
1362
0
            ++pmin;
1363
0
        for (pmax = 0; (plane_mask >> pmax) > 1; )
1364
0
            ++pmax;
1365
0
    }
1366
0
    if_debug6('h',
1367
0
              "[h]color_ht_gt_4: x=%d y=%d w=%d h=%d plane_mask=0x%lu depth=%d\n",
1368
0
              px, py, w, h, (ulong)plane_mask, depth);
1369
1370
    /* Do one-time cursor initialization. */
1371
0
    {
1372
0
        int endx = w + px;
1373
0
        int lasty = h - 1 + py;
1374
0
        int i;
1375
1376
0
        for (i = pmin; i <= pmax; ++i)
1377
0
            if ((plane_mask >> i) & 1)
1378
0
                init_tile_cursor(i, &cursor[i], sbits[i], endx, lasty);
1379
0
    }
1380
1381
    /* Pre-load the color value for the non halftoning planes. */
1382
0
    {
1383
0
        int i;
1384
1385
0
        for (i = 0; i < num_planes; ++i)
1386
0
            if ((~plane_mask >> i) & 1)
1387
0
                base_color |= colors[2 * i];
1388
0
    }
1389
1390
    /* Now compute the actual tile. */
1391
0
    for (y = h; ; dest_row -= dest_raster) {
1392
0
        byte *dest = dest_row;
1393
0
        int i;
1394
1395
0
        --y;
1396
0
        for (x = w; x > 0;) {
1397
0
            gx_color_index tcolor = base_color;
1398
1399
0
            for (i = pmin; i <= pmax; ++i)
1400
0
                if ((plane_mask >> i) & 1) {
1401
                    /* Get the next bit from an individual mask. */
1402
0
                    tile_cursor_t *ptc = &cursor[i];
1403
0
                    byte tile_bit;
1404
1405
0
b:        if (ptc->bit_shift < 8)
1406
0
                        tile_bit = *ptc->data >> ptc->bit_shift++;
1407
0
                    else if (ptc->data > ptc->row) {
1408
0
                        tile_bit = *--(ptc->data);
1409
0
                        ptc->bit_shift = 1;
1410
0
                    } else {
1411
                        /* Wrap around. */
1412
0
                        ptc->data += ptc->xbytes;
1413
0
                        ptc->bit_shift = 8 - ptc->xbits;
1414
0
                        goto b;
1415
0
                    }
1416
0
                    tcolor |= colors[2 * i + (tile_bit & 1)];
1417
0
                }
1418
0
            --x;
1419
0
            switch (dbytes) {
1420
0
                case 0: /* 4 -- might be 2, but we don't support this */
1421
0
                    if (x & 1) { /* odd nibble */
1422
0
                        *--dest = (byte)tcolor;
1423
0
                    } else { /* even nibble */
1424
0
                        *dest = (*dest & 0xf) + ((byte)tcolor << 4);
1425
0
                    }
1426
0
                    break;
1427
0
                case 4: /* 32 */
1428
0
                    dest[-4] = (byte)(tcolor >> 24);
1429
0
                case 3: /* 24 */
1430
0
                    dest[-3] = (byte)(tcolor >> 16);
1431
0
                case 2: /* 16 */
1432
0
                    dest[-2] = (byte)(tcolor >> 8);
1433
0
                case 1: /* 8 */
1434
0
                    dest[-1] = (byte)tcolor;
1435
0
                    dest -= dbytes;
1436
0
                    break;
1437
0
            }
1438
0
        }
1439
0
        if (y == 0)
1440
0
            break;
1441
0
        for (i = pmin; i <= pmax; ++i)
1442
0
            if ((plane_mask >> i) & 1)
1443
0
                STEP_ROW(cursor[i], i);
1444
0
    }
1445
0
}