Coverage Report

Created: 2025-06-10 06:58

/src/ghostpdl/base/gxclrast.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2001-2025 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
/* Command list interpreter/rasterizer */
18
#include "memory_.h"
19
#include "gx.h"
20
#include "gp.h"                 /* for gp_fmode_rb */
21
#include "gpcheck.h"
22
#include "gserrors.h"
23
#include "gscdefs.h"            /* for image type table */
24
#include "gsbitops.h"
25
#include "gsparams.h"
26
#include "gsstate.h"            /* (should only be gs_gstate) */
27
#include "gstrans.h"    /* for gs_is_pdf14trans_compositor */
28
#include "gxdcolor.h"
29
#include "gxdevice.h"
30
#include "gscoord.h"            /* requires gsmatrix.h */
31
#include "gsdevice.h"           /* for gs_deviceinitialmatrix */
32
#include "gsiparm4.h"
33
#include "gxdevmem.h"           /* must precede gxcldev.h */
34
#include "gxcldev.h"
35
#include "gxclpath.h"
36
#include "gxcmap.h"
37
#include "gxcolor2.h"
38
#include "gxcspace.h"           /* for gs_color_space_type */
39
#include "gxdhtres.h"
40
#include "gxgetbit.h"
41
#include "gxpaint.h"            /* for gx_fill/stroke_params */
42
#include "gxpcolor.h"
43
#include "gxhttile.h"
44
#include "gxiparam.h"
45
#include "gximask.h"
46
#include "gzpath.h"
47
#include "gzcpath.h"
48
#include "gzacpath.h"
49
#include "stream.h"
50
#include "strimpl.h"
51
#include "gxcomp.h"
52
#include "gsserial.h"
53
#include "gxdhtserial.h"
54
#include "gzht.h"
55
#include "gxshade.h"
56
#include "gxshade4.h"
57
#include "gsicc_manage.h"
58
#include "gsicc.h"
59
60
extern_gx_device_halftone_list();
61
extern_gx_image_type_table();
62
63
/* We need color space types for constructing temporary color spaces. */
64
extern const gs_color_space_type gs_color_space_type_Indexed;
65
66
/* Print a bitmap for tracing */
67
#ifdef DEBUG
68
static void
69
cmd_print_bits(gs_memory_t *mem, const byte * data, int width, int height, int raster)
70
{
71
    int i, j;
72
73
    dmlprintf3(mem, "[L]width=%d, height=%d, raster=%d\n",
74
              width, height, raster);
75
    for (i = 0; i < height; i++) {
76
        const byte *row = data + i * raster;
77
78
        dmlprintf(mem, "[L]");
79
        for (j = 0; j < raster; j++)
80
            dmprintf1(mem, " %02x", row[j]);
81
        dmputc(mem, '\n');
82
    }
83
}
84
#else
85
#  define cmd_print_bits(mem, data, width, height, raster) DO_NOTHING
86
#endif
87
88
/* Get a variable-length integer operand. */
89
#define cmd_getw(var, p)\
90
0
  BEGIN\
91
0
    if ( *p < 0x80 ) var = *p++;\
92
0
    else { const byte *_cbp; var = cmd_get_w(p, &_cbp); p = _cbp; }\
93
0
  END
94
95
static long
96
cmd_get_w(const byte * p, const byte ** rp)
97
0
{
98
0
    int val = *p++ & 0x7f;
99
0
    int shift = 7;
100
101
0
    for (; val |= (int)(*p & 0x7f) << shift, *p++ > 0x7f; shift += 7);
102
0
    *rp = p;
103
0
    return val;
104
0
}
105
106
/* Get a variable-length fractional operand. */
107
#define cmd_getfrac(var, p)\
108
0
  BEGIN\
109
0
    if ( !(*p & 1) ) var = (*p++) << 24;\
110
0
    else { const byte *_cbp; var = cmd_get_frac31(p, &_cbp); p = _cbp; }\
111
0
  END
112
static frac31
113
cmd_get_frac31(const byte * p, const byte ** rp)
114
0
{
115
0
    frac31 val = (*p++ & 0xFE) << 24;
116
0
    int shift = 24 - 7;
117
118
0
    for (; val |= (frac31)(*p & 0xFE) << shift, *p++ & 1; shift -= 7);
119
0
    *rp = p;
120
0
    return val;
121
0
}
122
123
/*
124
 * Define the structure for keeping track of the command reading buffer.
125
 *
126
 * The ptr member is only used for passing the current pointer to, and
127
 * receiving an updated pointer from, commands implemented as separate
128
 * procedures: normally it is kept in a register.
129
 */
130
typedef struct command_buf_s {
131
    byte *data;                 /* actual buffer, guaranteed aligned */
132
    uint size;
133
    const byte *ptr;            /* next byte to be read (see above) */
134
    const byte *warn_limit;     /* refill warning point */
135
    const byte *end;            /* byte just beyond valid data */
136
    stream *s;                  /* for refilling buffer */
137
    int end_status;
138
} command_buf_t;
139
140
/* Set the end of a command buffer. */
141
static void
142
set_cb_end(command_buf_t *pcb, const byte *end)
143
0
{
144
0
    pcb->end = end;
145
0
    pcb->warn_limit = pcb->data + (pcb->size - cmd_largest_size + 1);
146
0
    if ( pcb->warn_limit > pcb->end )
147
0
        pcb->warn_limit = pcb->end;     /**** This is dangerous. Other places ****/
148
                                        /**** assume that the limit is a soft ****/
149
                                        /**** limit and should check 'end'    ****/
150
0
}
151
152
static inline void
153
advance_buffer(command_buf_t *pcb, const byte *cbp)
154
0
{
155
#ifdef DEBUG
156
    stream_state *st = pcb->s->state;
157
158
    top_up_offset_map(st, pcb->data, cbp, pcb->end);
159
#endif
160
0
    memmove(pcb->data, cbp, pcb->end - cbp);
161
0
}
162
163
static inline void
164
next_is_skip(command_buf_t *pcb)
165
0
{
166
#ifdef DEBUG
167
    stream_state *st = pcb->s->state;
168
169
    offset_map_next_data_out_of_band(st);
170
#endif
171
0
}
172
173
/* Read more data into a command buffer. */
174
static int
175
top_up_cbuf(command_buf_t *pcb, const byte **pcbp)
176
0
{
177
0
    uint nread;
178
0
    const byte *cbp = *pcbp;
179
0
    byte *cb_top = pcb->data + (pcb->end - cbp);
180
181
0
    if (cbp < pcb->data || cbp > pcb->end) {
182
0
        errprintf(pcb->s->memory, "Clist I/O error: cbp outside of buffer\n");
183
0
        return (gs_error_ioerror);
184
0
    }
185
186
0
    if (seofp(pcb->s)) {
187
        /* Can't use offset_map, because s_close resets s->state. Don't top up. */
188
0
        pcb->end_status = pcb->s->end_status;
189
0
        return 0;
190
0
    }
191
0
    advance_buffer(pcb, cbp);
192
0
    nread = pcb->end - cb_top;
193
0
    pcb->end_status = sgets(pcb->s, cb_top, nread, &nread);
194
0
    if ( nread == 0 ) {
195
        /* No data for this band at all. */
196
0
        if (cb_top >= pcb->end) {
197
            /* should not happen */
198
0
            *pcbp = pcb->data;
199
0
            pcb->data[0] = cmd_opv_end_run;
200
0
            return_error(gs_error_ioerror);
201
0
        }
202
0
        *cb_top = cmd_opv_end_run;
203
0
        nread = 1;
204
0
    }
205
0
    set_cb_end(pcb, cb_top + nread);
206
0
    process_interrupts(pcb->s->memory);
207
0
    *pcbp = pcb->data;
208
0
    return 0;
209
0
}
210
211
/* Read data from the command buffer and stream. */
212
/* From the command_buffer pcb, read rsize bytes to ptr, starting from cbp.
213
 * Return the new value for pcb->ptr. */
214
static const byte *
215
cmd_read_data(command_buf_t *pcb, byte *ptr, uint rsize, const byte *cbp)
216
0
{
217
0
    if (pcb->end - cbp >= rsize) {
218
0
        memmove(ptr, cbp, rsize);
219
0
        return cbp + rsize;
220
0
    } else {
221
0
        uint cleft = pcb->end - cbp;
222
0
        uint rleft = rsize - cleft;
223
224
0
        memmove(ptr, cbp, cleft);
225
0
        sgets(pcb->s, ptr + cleft, rleft, &rleft);
226
#ifdef DEBUG
227
        {
228
            stream_state *st = pcb->s->state;
229
230
            adjust_offset_map_for_skipped_data(st, (uint)(pcb->end - pcb->data), rleft);
231
        }
232
#endif
233
0
        return pcb->end;
234
0
    }
235
0
}
236
237
/* Read a fixed-size value from the command buffer. */
238
static inline const byte *
239
cmd_copy_value(void *pvar, int var_size, const byte *cbp)
240
0
{
241
0
    memcpy(pvar, cbp, var_size);
242
0
    return cbp + var_size;
243
0
}
244
#define cmd_get_value(var, cbp)\
245
0
  cbp = cmd_copy_value(&var, sizeof(var), cbp)
246
247
/*
248
 * Define a buffer structure to hold a serialized halftone. This is
249
 * used only if the serialized halftone is too large to fit into
250
 * the command buffer.
251
 */
252
typedef struct ht_buff_s {
253
    uint    ht_size, read_size;
254
    byte *  pcurr;
255
    byte *  pbuff;
256
} ht_buff_t;
257
258
/*
259
 * Render one band to a specified target device.  Note that if
260
 * action == setup, target may be 0.
261
 */
262
static int read_set_tile_size(command_buf_t *pcb, tile_slot *bits, bool for_pattern);
263
static int read_set_bits(command_buf_t *pcb, tile_slot *bits,
264
                          int compress, gx_clist_state *pcls,
265
                          gx_strip_bitmap *tile, tile_slot **pslot,
266
                          gx_device_clist_reader *cdev, gs_memory_t *mem);
267
static int read_set_misc2(command_buf_t *pcb, gs_gstate *pgs,
268
                           segment_notes *pnotes);
269
static int read_set_color_space(command_buf_t *pcb, gs_gstate *pgs,
270
                                 gx_device_clist_reader *cdev, gs_memory_t *mem);
271
static int read_begin_image(command_buf_t *pcb, gs_image_common_t *pic,
272
                             gs_color_space *pcs);
273
static int read_put_params(command_buf_t *pcb, gs_gstate *pgs,
274
                            gx_device_clist_reader *cdev,
275
                            gs_memory_t *mem);
276
static int read_composite(command_buf_t *pcb, gs_memory_t *mem, gs_composite_t **ppcomp);
277
static int apply_composite(gx_device_clist_reader *cdev, gs_gstate *pgs,
278
                                   gs_memory_t *mem, gs_composite_t *pcomp,
279
                                   int x0, int y0, gx_device **ptarget);
280
static int read_alloc_ht_buff(ht_buff_t *, uint, gs_memory_t *);
281
static int read_ht_segment(ht_buff_t *, command_buf_t *, gs_gstate *,
282
                            gx_device *, gs_memory_t *);
283
284
static const byte *cmd_read_rect(int, gx_cmd_rect *, const byte *);
285
static const byte *cmd_read_short_bits(command_buf_t *pcb, byte *data, int tot_bytes,
286
                                        int width_bytes, int height,
287
                                        uint raster, const byte *cbp);
288
static int cmd_select_map(cmd_map_index, cmd_map_contents,
289
                           gs_gstate *, int **,
290
                           frac **, uint *, gs_memory_t *);
291
static int cmd_create_dev_ht(gx_device_halftone **, gs_memory_t *);
292
static int cmd_resize_halftone(gx_device_halftone **, uint,
293
                                gs_memory_t *);
294
static int clist_decode_segment(gx_path *, int, fixed[6],
295
                                 gs_fixed_point *, int, int,
296
                                 segment_notes);
297
static int clist_do_polyfill(gx_device *, gx_path *,
298
                              const gx_drawing_color *,
299
                              gs_logical_operation_t);
300
301
static inline void
302
enqueue_compositor(gs_composite_t **ppcomp_first, gs_composite_t **ppcomp_last, gs_composite_t *pcomp)
303
0
{
304
0
    if (*ppcomp_last == NULL) {
305
0
        pcomp->prev = pcomp->next = NULL;
306
0
        *ppcomp_last = *ppcomp_first = pcomp;
307
0
    } else {
308
0
        (*ppcomp_last)->next = pcomp;
309
0
        pcomp->prev = *ppcomp_last;
310
0
        pcomp->next = NULL;
311
0
        *ppcomp_last = pcomp;
312
0
    }
313
0
}
314
315
#if 0 /* Appears unused - keep for a while. */
316
static inline gs_composite_t *
317
dequeue_last_compositor(gs_composite_t **ppcomp_first, gs_composite_t **ppcomp_last)
318
{
319
    gs_composite_t *pcomp = *ppcomp_last;
320
321
    if (*ppcomp_first == *ppcomp_last)
322
        *ppcomp_first = *ppcomp_last = NULL;
323
    else {
324
        *ppcomp_last = (*ppcomp_last)->prev;
325
        pcomp->prev = NULL;
326
        (*ppcomp_last)->next = NULL;
327
    }
328
    return pcomp;
329
}
330
331
static inline gs_composite_t *
332
dequeue_first_compositor(gs_composite_t **ppcomp_first, gs_composite_t **ppcomp_last)
333
{
334
    gs_composite_t *pcomp = *ppcomp_first;
335
336
    if (*ppcomp_first == *ppcomp_last)
337
        *ppcomp_first = *ppcomp_last = NULL;
338
    else {
339
        *ppcomp_first = (*ppcomp_first)->next;
340
        pcomp->next = NULL;
341
        (*ppcomp_last)->prev = NULL;
342
    }
343
    return pcomp;
344
}
345
#endif
346
347
static inline int
348
dequeue_compositor(gs_composite_t **ppcomp_first, gs_composite_t **ppcomp_last, gs_composite_t *pcomp)
349
0
{
350
0
    if (*ppcomp_last == *ppcomp_first) {
351
0
        if (*ppcomp_last == pcomp) {
352
0
            *ppcomp_last = *ppcomp_first = NULL;
353
0
            return 0;
354
0
        } else
355
0
            return_error(gs_error_unregistered); /* Must not happen. */
356
0
    } else {
357
0
        gs_composite_t *pcomp_next = pcomp->next, *pcomp_prev = pcomp->prev;
358
359
0
        if (*ppcomp_last == pcomp)
360
0
            *ppcomp_last = pcomp->prev;
361
0
        else
362
0
            pcomp_next->prev = pcomp_prev;
363
0
        if (*ppcomp_first == pcomp)
364
0
            *ppcomp_first = pcomp->next;
365
0
        else
366
0
            pcomp_prev->next = pcomp_next;
367
0
        pcomp->next = pcomp->prev = NULL;
368
0
        return 0;
369
0
    }
370
0
}
371
372
static inline void
373
free_compositor(gs_composite_t *pcomp, gs_memory_t *mem)
374
0
{
375
0
    gs_free_object(mem, pcomp, "free_compositor");
376
0
}
377
378
static inline bool
379
is_null_compositor_op(const byte *cbp, int *length)
380
0
{
381
0
    if (cbp[0] == cmd_opv_end_run) {
382
0
        *length = 1;
383
0
        return true;
384
0
    }
385
0
    return false;
386
0
}
387
388
static int
389
execute_compositor_queue(gx_device_clist_reader *cdev, gx_device **target, gx_device **tdev, gs_gstate *pgs,
390
                         gs_composite_t **ppcomp_first, gs_composite_t **ppcomp_last, gs_composite_t *pcomp_from,
391
                         int x0, int y0, gs_memory_t *mem, bool idle)
392
0
{
393
0
    while (pcomp_from != NULL) {
394
0
        gs_composite_t *pcomp = pcomp_from;
395
0
        int code;
396
397
0
        pcomp_from = pcomp->next;
398
0
        code = dequeue_compositor(ppcomp_first, ppcomp_last, pcomp);
399
0
        if (code < 0)
400
0
            return code;
401
0
        pcomp->idle |= idle;
402
0
        code = apply_composite(cdev, pgs, mem, pcomp, x0, y0, target); /* Releases the compositor. */
403
0
        if (code < 0)
404
0
            return code;
405
0
        *tdev = *target;
406
0
    }
407
0
    return 0;
408
0
}
409
410
static void
411
mark_as_idle(gs_composite_t *pcomp_start, gs_composite_t *pcomp_end)
412
0
{
413
0
    gs_composite_t *pcomp = pcomp_start;
414
415
0
    while (pcomp != NULL) {
416
0
        pcomp->idle = true;
417
0
        if (pcomp == pcomp_end)
418
0
            break;
419
0
        pcomp = pcomp->next;
420
0
    }
421
0
}
422
423
static inline int
424
drop_compositor_queue(gs_composite_t **ppcomp_first, gs_composite_t **ppcomp_last,
425
                      gs_composite_t *pcomp_from, gs_memory_t *mem, int x0, int y0,
426
                      gs_gstate *pgs)
427
0
{
428
0
    gs_composite_t *pcomp;
429
430
0
    do {
431
0
        int code;
432
433
0
        pcomp = *ppcomp_last;
434
0
        if (pcomp == NULL)
435
0
            return 0;
436
0
        dequeue_compositor(ppcomp_first, ppcomp_last, *ppcomp_last);
437
0
        code = pcomp->type->procs.adjust_ctm(pcomp, x0, y0, pgs);
438
0
        if (code < 0)
439
0
            return code;
440
0
        free_compositor(pcomp, mem);
441
0
    } while (pcomp != pcomp_from);
442
0
    return 0;
443
0
}
444
445
static int
446
read_set_misc_map(byte cb, command_buf_t *pcb, gs_gstate *pgs, gs_memory_t *mem)
447
0
{
448
0
    const byte *cbp = pcb->ptr;
449
0
    frac *mdata;
450
0
    int *pcomp_num;
451
0
    uint count = 0;   /* quiet compiler */
452
0
    cmd_map_contents cont =
453
0
        (cmd_map_contents)(cb & 0x30) >> 4;
454
0
    int code;
455
456
0
    code = cmd_select_map(cb & 0xf, cont,
457
0
                          pgs,
458
0
                          &pcomp_num,
459
0
                          &mdata, &count, mem);
460
461
0
    if (code < 0)
462
0
        return code;
463
    /* Get component number if relevant */
464
0
    if (pcomp_num == NULL)
465
0
        cbp++;
466
0
    else {
467
0
        *pcomp_num = (int) *cbp++;
468
0
        if_debug1m('L', mem, " comp_num=%d", *pcomp_num);
469
0
    }
470
0
    if (cont == cmd_map_other) {
471
0
        cbp = cmd_read_data(pcb, (byte *)mdata, count, cbp);
472
473
#ifdef DEBUG
474
        if (gs_debug_c('L')) {
475
            uint i;
476
477
            for (i = 0; i < count / sizeof(*mdata); ++i)
478
                dmprintf1(mem, " 0x%04x", mdata[i]);
479
            dmputc(mem, '\n');
480
        }
481
    } else {
482
        if_debug0m('L', mem, " none\n");
483
#endif
484
0
    }
485
    /* Recompute the effective transfer, */
486
    /* in case this was a transfer map. */
487
0
    gx_gstate_set_effective_xfer(pgs);
488
0
    pcb->ptr = cbp;
489
0
    return 0;
490
0
}
491
492
#ifdef DEBUG
493
void clist_debug_op(gs_memory_t *mem, const unsigned char *cbp)
494
{
495
    unsigned char op = *cbp++;
496
    const char *const *sub = cmd_sub_op_names[op >> 4];
497
    if (op == cmd_opv_extend) {
498
        unsigned char op2 = *cbp;
499
        if (cmd_extend_op_names[op2])
500
            dmlprintf1(mem, " %s", cmd_extend_op_names[op2]);
501
        else
502
            dmlprintf1(mem, " ?0x%02x?", (int)op2);
503
    } else if (sub)
504
        dmlprintf1(mem, " %s", sub[op & 0xf]);
505
    else
506
        dmlprintf2(mem, " %s %d", cmd_op_names[op >> 4], op & 0xf);
507
}
508
#endif
509
510
int
511
clist_playback_band(clist_playback_action playback_action, /* lgtm [cpp/use-of-goto] */
512
                    gx_device_clist_reader *cdev, stream *s,
513
                    gx_device *target, int x0, int y0,
514
                    gs_memory_t * mem)
515
0
{
516
0
    byte *cbuf_storage;
517
0
    command_buf_t cbuf;
518
    /* data_bits is for short copy_* bits and copy_* compressed, */
519
    /* must be aligned */
520
0
    byte *data_bits = 0;
521
0
    const byte *cbp;
522
0
    int dev_depth;              /* May vary due to compositing devices */
523
0
    int dev_depth_bytes;
524
0
    int odd_delta_shift;
525
0
    int num_zero_bytes;
526
0
    gx_device *tdev;
527
0
    gx_clist_state state;
528
0
    gx_color_index *set_colors;
529
0
    gx_device_color *set_dev_colors;
530
0
    tile_slot *state_slot;
531
0
    gx_strip_bitmap state_tile; /* parameters for reading tiles */
532
0
    tile_slot tile_bits;        /* parameters of current tile */
533
0
    gs_int_point tile_phase;
534
0
    gx_path path;
535
0
    bool in_path;
536
0
    gs_fixed_point ppos;
537
0
    gx_clip_path clip_path;
538
0
    bool use_clip;
539
0
    gx_clip_path *pcpath;
540
0
    gx_device_cpath_accum clip_accum;
541
0
    gs_fixed_rect target_box;
542
0
    struct _cas {
543
0
        bool lop_enabled;
544
0
        gx_device_color dcolor;
545
0
        gs_fixed_point fa_save;
546
0
    } clip_save;
547
0
    bool in_clip = false;
548
0
    gs_gstate gs_gstate;
549
0
    gx_device_color fill_color = { 0 };
550
0
    gx_device_color stroke_color = { 0 };
551
0
    float dash_pattern[cmd_max_dash];
552
0
    gx_fill_params fill_params;
553
0
    gx_stroke_params stroke_params;
554
#ifdef DEBUG
555
    gs_halftone_type halftone_type;
556
#endif
557
0
    union im_ {
558
0
        gs_image_common_t c;
559
0
        gs_data_image_t d;
560
0
        gs_image1_t i1;
561
0
        gs_image4_t i4;
562
0
    } image;
563
0
    gs_int_rect image_rect;
564
0
    gs_color_space *pcs = NULL;
565
0
    gx_image_enum_common_t *image_info;
566
0
    gx_image_plane_t planes[32];
567
0
    uint data_height;
568
0
    uint data_size;
569
0
    byte *data_on_heap;
570
0
    fixed vs[6];
571
0
    segment_notes notes;
572
0
    int data_x;
573
0
    int code = 0;
574
0
    ht_buff_t  ht_buff;
575
0
    gx_device *const orig_target = target;
576
0
    gx_device_clip clipper_dev;
577
0
    bool clipper_dev_open = false;
578
0
    patch_fill_state_t pfs;
579
0
    int op = 0;
580
0
    int plane_height = 0;
581
582
#ifdef DEBUG
583
    stream_state *st = s->state; /* Save because s_close resets s->state. */
584
#endif
585
0
    gs_composite_t *pcomp_first = NULL, *pcomp_last = NULL;
586
0
    tile_slot bits;             /* parameters for reading bits */
587
588
    /* pad the cbuf data area a bit (just in case) */
589
0
    if ((cbuf_storage = gs_alloc_bytes(mem, cbuf_size + sizeof(double),
590
0
                               "clist_playback_band(cbuf_storage)")) == NULL) {
591
0
        return_error(gs_error_VMerror);
592
0
    }
593
0
    cbuf.data = (byte *)cbuf_storage;
594
0
    cbuf.size = cbuf_size;
595
0
    cbuf.s = s;
596
0
    cbuf.end_status = 0;
597
0
    set_cb_end(&cbuf, cbuf.data + cbuf.size);
598
0
    cbp = cbuf.end;
599
600
0
    pfs.dev = NULL; /* Indicate "not initialized". */
601
0
    memset(&ht_buff, 0, sizeof(ht_buff));
602
603
    /* The following initializations are to quiet gcc warnings. */
604
0
    memset(&bits, 0, sizeof(bits));
605
0
    memset(&tile_bits, 0, sizeof(tile_bits));
606
0
    memset(&clip_save, 0, sizeof(clip_save));
607
0
    memset(&state_slot, 0, sizeof(state_slot));
608
0
    ppos.x = ppos.y = 0;
609
610
0
in:                             /* Initialize for a new page. */
611
0
    tdev = target;
612
0
    set_colors = state.colors;
613
0
    set_dev_colors = state.tile_color_devn;
614
0
    use_clip = false;
615
0
    pcpath = NULL;
616
0
    if (clipper_dev_open)
617
0
        gx_destroy_clip_device_on_stack(&clipper_dev);
618
0
    clipper_dev_open = false;
619
0
    notes = sn_none;
620
0
    data_x = 0;
621
0
    {
622
0
        static const gx_clist_state cls_initial = { cls_initial_values };
623
624
0
        state = cls_initial;
625
0
    }
626
0
    state_tile.id = gx_no_bitmap_id;
627
0
    state_tile.shift = state_tile.rep_shift = 0;
628
0
    state_tile.size.x = state_tile.size.y = 0;
629
0
    state_tile.num_planes = 1;
630
0
    tile_phase.x = x0;
631
0
    tile_phase.y = y0;
632
0
    gx_path_init_local(&path, mem);
633
0
    in_path = false;
634
    /*
635
     * Initialize the clipping region to the full page.
636
     * (Since we also initialize use_clip to false, this is arbitrary.)
637
     */
638
0
    {
639
0
        gs_fixed_rect cbox;
640
641
0
        gx_cpath_init_local(&clip_path, mem);
642
0
        cbox.p.x = 0;
643
0
        cbox.p.y = 0;
644
0
        cbox.q.x = cdev->width;
645
0
        cbox.q.y = cdev->height;
646
0
        gx_cpath_from_rectangle(&clip_path, &cbox);
647
0
    }
648
0
    if (target != 0)
649
0
        (*dev_proc(target, get_clipping_box))(target, &target_box);
650
0
    memset(&gs_gstate, 0, sizeof(gs_gstate));
651
0
    GS_STATE_INIT_VALUES_CLIST((&gs_gstate));
652
0
    code = gs_gstate_initialize(&gs_gstate, mem);
653
0
    if (code < 0)
654
0
        goto out;
655
0
    gs_gstate.device = tdev;
656
0
    gs_gstate.view_clip = NULL; /* Avoid issues in pdf14 fill stroke */
657
0
    gs_gstate.clip_path = &clip_path;
658
0
    pcs = gs_cspace_new_DeviceGray(mem);
659
0
    if (pcs == NULL) {
660
0
        code = gs_note_error(gs_error_VMerror);
661
0
        goto out;
662
0
    }
663
0
    code = pcs->type->install_cspace(pcs, &gs_gstate);
664
0
    if (code < 0) {
665
0
        rc_decrement(pcs, "clist_playback_band");
666
0
        goto out;
667
0
    }
668
0
    gs_gstate.color[0].color_space = pcs; /* we already have one ref */
669
0
    gs_gstate.color[1].color_space = pcs;
670
0
    rc_increment_cs(pcs); /* increment for second ref */
671
    /* Initialize client color and device color */
672
0
    gs_gstate.color[0].ccolor =
673
0
        gs_alloc_struct(mem, gs_client_color, &st_client_color, "clist_playback_band");
674
0
    gs_gstate.color[1].ccolor =
675
0
        gs_alloc_struct(mem, gs_client_color, &st_client_color, "clist_playback_band");
676
0
    gs_gstate.color[0].dev_color =
677
0
        gs_alloc_struct(mem, gx_device_color, &st_device_color, "clist_playback_band");
678
0
    gs_gstate.color[1].dev_color =
679
0
        gs_alloc_struct(mem, gx_device_color, &st_device_color, "clist_playback_band");
680
0
    if (gs_gstate.color[0].ccolor == 0 || gs_gstate.color[0].dev_color == 0 ||
681
0
        gs_gstate.color[1].ccolor == 0 || gs_gstate.color[1].dev_color == 0
682
0
        ) {
683
0
        gs_free_object(mem, gs_gstate.color[0].ccolor, "clist_playback_band");
684
0
        gs_free_object(mem, gs_gstate.color[1].ccolor, "clist_playback_band");
685
0
        gs_free_object(mem, gs_gstate.color[0].dev_color, "clist_playback_band");
686
0
        gs_free_object(mem, gs_gstate.color[1].dev_color, "clist_playback_band");
687
0
        if (clipper_dev_open)
688
0
            gx_destroy_clip_device_on_stack(&clipper_dev);
689
0
        return_error(gs_error_VMerror);
690
0
    }
691
0
    gs_gstate.color[0].color_space->pclient_color_space_data =
692
0
        pcs->pclient_color_space_data;
693
0
    cs_full_init_color(gs_gstate.color[0].ccolor, pcs);
694
0
    gx_unset_dev_color(&gs_gstate);
695
696
0
    gs_gstate.color[1].color_space->pclient_color_space_data =
697
0
        pcs->pclient_color_space_data;
698
0
    cs_full_init_color(gs_gstate.color[1].ccolor, pcs);
699
0
    gx_unset_dev_color(&gs_gstate);
700
701
    /* Remove the ICC link cache and replace with the device link cache
702
       so that we share the cache across bands */
703
0
    rc_decrement(gs_gstate.icc_link_cache,"clist_playback_band");
704
0
    gs_gstate.icc_link_cache = cdev->icc_cache_cl;
705
    /* Need to lock during the increment of the link cache */
706
0
    gx_monitor_enter(cdev->icc_cache_cl->lock);
707
0
    rc_increment(cdev->icc_cache_cl);
708
0
    gx_monitor_leave(cdev->icc_cache_cl->lock); /* let everyone run */
709
0
    if (code < 0)
710
0
        goto out;
711
712
0
    gs_gstate.line_params.dash.pattern = dash_pattern;
713
0
    if (tdev != 0) {
714
0
        gx_set_cmap_procs(&gs_gstate, tdev);
715
0
    }
716
0
    gx_gstate_setscreenphase(&gs_gstate, -x0, -y0, gs_color_select_all);
717
#ifdef DEBUG
718
    halftone_type = ht_type_none;
719
#endif
720
0
    fill_color.ccolor_valid = false;
721
0
    color_unset(&fill_color);
722
0
    data_bits = gs_alloc_bytes(mem, data_bits_size,
723
0
                               "clist_playback_band(data_bits)");
724
0
    if (data_bits == 0) {
725
0
        code = gs_note_error(gs_error_VMerror);
726
0
        goto out;
727
0
    }
728
0
    while (code >= 0) {
729
0
        int compress;
730
0
        int depth = 0x7badf00d; /* Initialize against indeterminizm. */
731
0
        int raster = 0x7badf00d; /* Initialize against indeterminizm. */
732
0
        byte *source = NULL;  /* Initialize against indeterminizm. */
733
0
        gx_color_index colors[2];
734
0
        gx_color_index *pcolor;
735
0
        gx_device_color *pdcolor = NULL;
736
0
        gs_logical_operation_t log_op;
737
738
        /* Make sure the buffer contains a full command. */
739
0
        if (cbp >= cbuf.warn_limit) {
740
0
            if (cbuf.end_status < 0) {  /* End of file or error. */
741
0
                if (cbp >= cbuf.end) {
742
0
                    code = (cbuf.end_status == EOFC ? 0 :
743
0
                            gs_note_error(gs_error_ioerror));
744
0
                    break;
745
0
                }
746
0
            } else {
747
0
                code = top_up_cbuf(&cbuf, &cbp);
748
0
                if (code < 0)
749
0
                    goto top_up_failed;
750
0
            }
751
0
        }
752
0
        op = *cbp++;
753
#ifdef DEBUG
754
        if (gs_debug_c('L')) {
755
            int64_t offset = clist_file_offset(st, cbp - 1 - cbuf.data);
756
757
            dmlprintf1(mem, "[L] %"PRIu64":", offset);
758
            clist_debug_op(mem, cbp-1);
759
        }
760
#endif
761
0
        switch (op >> 4) {
762
0
            case cmd_op_misc >> 4:
763
0
                switch (op) {
764
0
                    case cmd_opv_end_run:
765
0
                        if_debug0m('L', mem, "\n");
766
0
                        continue;
767
0
                    case cmd_opv_set_tile_size:
768
0
                        cbuf.ptr = cbp;
769
0
                        code = read_set_tile_size(&cbuf, &tile_bits,
770
0
                                    gx_device_is_pattern_clist((gx_device *)cdev));
771
0
                        cbp = cbuf.ptr;
772
0
                        if (code < 0)
773
0
                            goto out;
774
0
                        continue;
775
0
                    case cmd_opv_set_tile_phase:
776
0
                        cmd_getw(state.tile_phase.x, cbp);
777
0
                        cmd_getw(state.tile_phase.y, cbp);
778
0
                        if_debug2m('L', mem, " (%d,%d)\n",
779
0
                                   state.tile_phase.x,
780
0
                                   state.tile_phase.y);
781
0
                        goto set_tile_phase;
782
0
                    case cmd_opv_set_screen_phaseT:
783
0
                        cmd_getw(state.screen_phase[gs_color_select_texture].x, cbp);
784
0
                        cmd_getw(state.screen_phase[gs_color_select_texture].y, cbp);
785
0
                        if_debug2m('L', mem, " (%d,%d)\n",
786
0
                                   state.screen_phase[0].x,
787
0
                                   state.screen_phase[gs_color_select_texture].y);
788
0
                        gx_gstate_setscreenphase(&gs_gstate,
789
0
                                                 state.screen_phase[gs_color_select_texture].x - x0,
790
0
                                                 state.screen_phase[gs_color_select_texture].y - y0,
791
0
                                                 gs_color_select_texture);
792
0
                        continue;
793
0
                    case cmd_opv_set_screen_phaseS:
794
0
                        cmd_getw(state.screen_phase[gs_color_select_source].x, cbp);
795
0
                        cmd_getw(state.screen_phase[gs_color_select_source].y, cbp);
796
0
                        if_debug2m('L', mem, " (%d,%d)\n",
797
0
                                   state.screen_phase[gs_color_select_source].x,
798
0
                                   state.screen_phase[gs_color_select_source].y);
799
0
                        gx_gstate_setscreenphase(&gs_gstate,
800
0
                                                 state.screen_phase[gs_color_select_source].x - x0,
801
0
                                                 state.screen_phase[gs_color_select_source].y - y0,
802
0
                                                 gs_color_select_source);
803
0
                        continue;
804
0
                    case cmd_opv_set_tile_bits:
805
0
                        bits = tile_bits;
806
0
                        compress = 0;
807
0
                      stb:
808
0
                        cbuf.ptr = cbp;
809
0
                        code = read_set_bits(&cbuf, &bits, compress,
810
0
                                             &state, &state_tile, &state_slot,
811
0
                                             cdev, mem);
812
0
                        cbp = cbuf.ptr;
813
0
                        if (code < 0)
814
0
                            goto out;
815
0
                        goto stp;
816
0
                    case cmd_opv_set_bits:
817
0
do_opv_set_bits:
818
0
                        compress = *cbp & 3;
819
0
                        bits.head.depth = *cbp++ >> 2;
820
0
                        cmd_getw(bits.width, cbp);
821
0
                        cmd_getw(bits.height, cbp);
822
0
                        if (op == cmd_opv_set_bits_planar)
823
0
                            cmd_getw(bits.num_planes, cbp);
824
0
                        else
825
0
                            bits.num_planes = 1;
826
0
                        if_debug5m('L', mem, " compress=%d depth=%d size=(%d,%d) planes=%d",
827
0
                                   compress, bits.head.depth,
828
0
                                   bits.width, bits.height, bits.num_planes);
829
0
                        bits.raster =
830
0
                            bitmap_raster(bits.width * bits.head.depth);
831
0
                        bits.x_reps = bits.y_reps = 1;
832
0
                        bits.shift = bits.rep_shift = 0;
833
0
                        goto stb;
834
0
                    case cmd_opv_set_tile_color:
835
0
                        set_colors = state.tile_colors;
836
0
                        if_debug0m('L', mem, "\n");
837
0
                        continue;
838
0
                    case cmd_opv_set_misc:
839
0
                        {
840
0
                            uint cb = *cbp++;
841
842
0
                            switch (cb >> 6) {
843
0
                                case cmd_set_misc_lop >> 6:
844
0
                                    cmd_getw(state.lop, cbp);
845
0
                                    state.lop = (state.lop << 6) + (cb & 0x3f);
846
0
                                    if_debug1m('L', mem, " lop=0x%x\n", state.lop);
847
0
                                    if (state.lop_enabled)
848
0
                                        gs_gstate.log_op = state.lop;
849
0
                                    break;
850
0
                                case cmd_set_misc_data_x >> 6:
851
0
                                    if (cb & 0x20)
852
0
                                        cmd_getw(data_x, cbp);
853
0
                                    else
854
0
                                        data_x = 0;
855
0
                                    data_x = (data_x << 5) + (cb & 0x1f);
856
0
                                    if_debug1m('L', mem, " data_x=%d\n", data_x);
857
0
                                    break;
858
0
                                case cmd_set_misc_map >> 6:
859
0
                                    cbuf.ptr = cbp;
860
0
                                    code = read_set_misc_map(cb, &cbuf, &gs_gstate, mem);
861
0
                                    if (code < 0)
862
0
                                        goto out;
863
0
                                    cbp = cbuf.ptr;
864
0
                                    break;
865
0
                                case cmd_set_misc_halftone >> 6: {
866
0
                                    uint num_comp;
867
#ifdef DEBUG
868
                                    halftone_type = cb & 0x3f;
869
#endif
870
0
                                    cmd_getw(num_comp, cbp);
871
#ifdef DEBUG
872
                                    if_debug2m('L', mem, " halftone type=%d num_comp=%u\n",
873
                                               halftone_type, num_comp);
874
#endif
875
0
                                    code = cmd_resize_halftone(
876
0
                                                        &gs_gstate.dev_ht[HT_OBJTYPE_DEFAULT],
877
0
                                                        num_comp, mem);
878
0
                                    if (code < 0)
879
0
                                        goto out;
880
0
                                    break;
881
0
                                }
882
0
                                default:
883
0
                                    goto bad_op;
884
0
                            }
885
0
                        }
886
0
                        continue;
887
0
                    case cmd_opv_enable_lop:
888
0
                        state.lop_enabled = true;
889
0
                        gs_gstate.log_op = state.lop;
890
0
                        if_debug0m('L', mem, "\n");
891
0
                        continue;
892
0
                    case cmd_opv_disable_lop:
893
0
                        state.lop_enabled = false;
894
0
                        gs_gstate.log_op = lop_default;
895
0
                        if_debug0m('L', mem, "\n");
896
0
                        continue;
897
0
                    case cmd_opv_end_page:
898
0
                        if_debug0m('L', mem, "\n");
899
                        /*
900
                         * Do end-of-page cleanup, then reinitialize if
901
                         * there are more pages to come.
902
                         */
903
0
                        goto out;
904
0
                    case cmd_opv_delta_color0:
905
0
                        pcolor = &set_colors[0];
906
0
                        goto delta2_c;
907
0
                    case cmd_opv_delta_color1:
908
0
                        pcolor = &set_colors[1];
909
0
                      delta2_c:set_colors = state.colors;
910
                        /* See comments for cmd_put_color() in gxclutil.c. */
911
0
                        {
912
0
                            gx_color_index delta = 0;
913
0
                            uint data;
914
915
0
                            dev_depth = (tdev->color_info.depth <= 8*sizeof(gx_color_index) ?
916
0
                                         tdev->color_info.depth : 8*sizeof(gx_color_index));
917
0
                            dev_depth_bytes = (dev_depth + 7) >> 3;
918
0
                            switch (dev_depth_bytes) {
919
                                /* For cases with an even number of bytes */
920
0
                                case 8:
921
0
                                    data = *cbp++;
922
0
                                    delta = (((gx_color_index)
923
0
                                        ((data & 0xf0) << 4) + (data & 0x0f)) << 24) << 24;
924
                                    /* fall through */
925
0
                                case 6:
926
0
                                    data = *cbp++;
927
0
                                    delta |= (((gx_color_index)
928
0
                                        ((data & 0xf0) << 4) + (data & 0x0f)) << 16) << 16;
929
                                    /* fall through */
930
0
                                case 4:
931
0
                                    data = *cbp++;
932
0
                                    delta |= ((gx_color_index)
933
0
                                        ((data & 0xf0) << 4) + (data & 0x0f)) << 16;
934
                                    /* fall through */
935
0
                                case 2:
936
0
                                    data = *cbp++;
937
0
                                    delta |= ((gx_color_index)
938
0
                                        ((data & 0xf0) << 4) + (data & 0x0f));
939
0
                                    break;
940
                                /* For cases with an odd number of bytes */
941
0
                                case 7:
942
0
                                    data = *cbp++;
943
0
                                    delta = ((gx_color_index)
944
0
                                        ((data & 0xf0) << 4) + (data & 0x0f)) << 16;
945
                                    /* fall through */
946
0
                                case 5:
947
0
                                    data = *cbp++;
948
0
                                    delta |= ((gx_color_index)
949
0
                                        ((data & 0xf0) << 4) + (data & 0x0f));
950
                                    /* fall through */
951
0
                                case 3:
952
0
                                    data = *cbp++;
953
0
                                    odd_delta_shift = (dev_depth_bytes - 3) * 8;
954
0
                                    delta |= ((gx_color_index)
955
0
                                        ((data & 0xe0) << 3) + (data & 0x1f)) << odd_delta_shift;
956
0
                                    data = *cbp++;
957
0
                                    delta |= ((gx_color_index) ((data & 0xf8) << 2) + (data & 0x07))
958
0
                                                        << (odd_delta_shift + 11);
959
0
                            }
960
0
                            *pcolor += delta - cmd_delta_offsets[dev_depth_bytes];
961
0
                        }
962
0
                        if (sizeof(*pcolor) <= sizeof(ulong))
963
0
                            if_debug1m('L', mem, " 0x%lx\n", (ulong)*pcolor);
964
0
                        else
965
0
                            if_debug2m('L', mem, " 0x%8lx%08lx\n",
966
0
                                       (ulong)(*pcolor >> 8*(sizeof(*pcolor) - sizeof(ulong))), (ulong)*pcolor);
967
0
                        continue;
968
0
                    case cmd_opv_set_copy_color:
969
0
                        state.color_is_alpha = 0;
970
0
                        if_debug0m('L', mem, "\n");
971
0
                        continue;
972
0
                    case cmd_opv_set_copy_alpha:
973
0
                        state.color_is_alpha = 1;
974
0
                        if_debug0m('L', mem, "\n");
975
0
                        continue;
976
0
                    default:
977
0
                        goto bad_op;
978
0
                }
979
                /*NOTREACHED */
980
0
            case cmd_op_set_color0 >> 4:
981
0
                pcolor = &set_colors[0];
982
0
                goto set_color;
983
0
            case cmd_op_set_color1 >> 4:
984
0
                pcolor = &set_colors[1];
985
0
              set_color:set_colors = state.colors;
986
                /*
987
                 * We have a special case for gx_no_color_index. If the low
988
                 * order 4 bits are "cmd_no_color_index" then we really
989
                 * have a value of gx_no_color_index.  Otherwise the these
990
                 * bits indicate the number of low order zero bytes in the
991
                 * value.  See comments for cmd_put_color() in gxclutil.c.
992
                 */
993
0
                num_zero_bytes = op & 0x0f;
994
995
0
                if (num_zero_bytes == cmd_no_color_index)
996
0
                    *pcolor = gx_no_color_index;
997
0
                else {
998
0
                    gx_color_index color = 0;
999
1000
0
                    dev_depth = (tdev->color_info.depth < 8*sizeof(gx_color_index) ?
1001
0
                                 tdev->color_info.depth : 8*sizeof(gx_color_index));
1002
0
                    dev_depth_bytes = (dev_depth + 7) >> 3;
1003
0
                    switch (dev_depth_bytes - num_zero_bytes) {
1004
0
                        case 8:
1005
0
                            color = (gx_color_index) * cbp++;
1006
0
                        case 7:
1007
0
                            color = (color << 8) | (gx_color_index) * cbp++;
1008
0
                        case 6:
1009
0
                            color = (color << 8) | (gx_color_index) * cbp++;
1010
0
                        case 5:
1011
0
                            color = (color << 8) | (gx_color_index) * cbp++;
1012
0
                        case 4:
1013
0
                            color = (color << 8) | (gx_color_index) * cbp++;
1014
0
                        case 3:
1015
0
                            color = (color << 8) | (gx_color_index) * cbp++;
1016
0
                        case 2:
1017
0
                            color = (color << 8) | (gx_color_index) * cbp++;
1018
0
                        case 1:
1019
0
                            color = (color << 8) | (gx_color_index) * cbp++;
1020
0
                        default:
1021
0
                            break;
1022
0
                    }
1023
0
                    color <<= num_zero_bytes * 8;
1024
0
                    *pcolor = color;
1025
0
                }
1026
0
                if (sizeof(*pcolor) <= sizeof(ulong))
1027
0
                    if_debug1m('L', mem, " 0x%lx\n", (ulong)*pcolor);
1028
0
                else
1029
0
                    if_debug2m('L', mem, " 0x%8lx%08lx\n",
1030
0
                               (ulong)(*pcolor >> 8*(sizeof(*pcolor) - sizeof(ulong))), (ulong)*pcolor);
1031
0
                continue;
1032
0
            case cmd_op_fill_rect >> 4:
1033
0
            case cmd_op_tile_rect >> 4:
1034
0
                cbp = cmd_read_rect(op, &state.rect, cbp);
1035
0
                break;
1036
0
            case cmd_op_fill_rect_short >> 4:
1037
0
            case cmd_op_tile_rect_short >> 4:
1038
0
                state.rect.x += *cbp + cmd_min_short;
1039
0
                state.rect.width += cbp[1] + cmd_min_short;
1040
0
                if (op & 0xf) {
1041
0
                    state.rect.height += (op & 0xf) + cmd_min_dxy_tiny;
1042
0
                    cbp += 2;
1043
0
                } else {
1044
0
                    state.rect.y += cbp[2] + cmd_min_short;
1045
0
                    state.rect.height += cbp[3] + cmd_min_short;
1046
0
                    cbp += 4;
1047
0
                }
1048
0
                break;
1049
0
            case cmd_op_fill_rect_tiny >> 4:
1050
0
            case cmd_op_tile_rect_tiny >> 4:
1051
0
                if (op & 8)
1052
0
                    state.rect.x += state.rect.width;
1053
0
                else {
1054
0
                    int txy = *cbp++;
1055
1056
0
                    state.rect.x += (txy >> 4) + cmd_min_dxy_tiny;
1057
0
                    state.rect.y += (txy & 0xf) + cmd_min_dxy_tiny;
1058
0
                }
1059
0
                state.rect.width += (op & 7) + cmd_min_dw_tiny;
1060
0
                break;
1061
0
            case cmd_op_copy_mono_planes >> 4:
1062
0
                cmd_getw(plane_height, cbp);
1063
0
                if (plane_height == 0) {
1064
                    /* We are doing a copy mono */
1065
0
                    depth = 1;
1066
0
                } else {
1067
0
                    depth = tdev->color_info.depth;
1068
0
                }
1069
0
                if_debug1m('L', mem, " plane_height=0x%x", plane_height);
1070
0
                goto copy;
1071
0
            case cmd_op_copy_color_alpha >> 4:
1072
0
                if (state.color_is_alpha) {
1073
0
                    if (!(op & 8))
1074
0
                        depth = *cbp++;
1075
0
                } else
1076
0
                    depth = tdev->color_info.depth;
1077
0
                plane_height = 0;
1078
0
              copy:cmd_getw(state.rect.x, cbp);
1079
0
                cmd_getw(state.rect.y, cbp);
1080
0
                if (op & cmd_copy_use_tile) {   /* Use the current "tile". */
1081
#ifdef DEBUG
1082
                    if (state_slot->index != state.tile_index) {
1083
                        mlprintf2(mem, "state_slot->index = %d, state.tile_index = %d!\n",
1084
                                  state_slot->index,
1085
                                  state.tile_index);
1086
                        code = gs_note_error(gs_error_ioerror);
1087
                        goto out;
1088
                    }
1089
#endif
1090
0
                    depth = state_slot->head.depth;
1091
0
                    state.rect.width = state_slot->width;
1092
0
                    state.rect.height = state_slot->height;
1093
0
                    if (state.rect.y + state.rect.height > cdev->height)
1094
0
                        state.rect.height = cdev->height - state.rect.y; /* clamp as writer did */
1095
0
                    raster = state_slot->raster;
1096
0
                    source = (byte *) (state_slot + 1);
1097
0
                } else {        /* Read width, height, bits. */
1098
                    /* depth was set already. */
1099
0
                    uint width_bits, width_bytes;
1100
0
                    uint bytes;
1101
0
                    uchar planes = 1;
1102
0
                    uint plane_depth = depth;
1103
0
                    uint pln;
1104
0
                    byte compression = op & 3;
1105
0
                    uint out_bytes;
1106
1107
0
                    cmd_getw(state.rect.width, cbp);
1108
0
                    cmd_getw(state.rect.height, cbp);
1109
0
                    if (plane_height != 0) {
1110
0
                        planes = tdev->color_info.num_components;
1111
0
                        plane_depth /= planes;
1112
0
                    }
1113
0
                    width_bits = state.rect.width * plane_depth;
1114
0
                    bytes = clist_bitmap_bytes(width_bits,
1115
0
                                               state.rect.height,
1116
0
                                               op & 3, &width_bytes,
1117
0
                                               (uint *)&raster);
1118
0
                    if (planes > 1) {
1119
0
                        out_bytes = raster * state.rect.height;
1120
0
                        plane_height = state.rect.height;
1121
0
                    } else {
1122
0
                        out_bytes = bytes;
1123
0
                    }
1124
                    /* copy_mono and copy_color/alpha */
1125
                    /* ensure that the bits will fit in a single buffer, */
1126
                    /* even after decompression if compressed. */
1127
#ifdef DEBUG
1128
                    if (planes * out_bytes > data_bits_size) {
1129
                        mlprintf6(mem, "bitmap size exceeds buffer!  width=%d raster=%d height=%d\n    file pos %"PRId64" buf pos %d/%d\n",
1130
                                  state.rect.width, raster,
1131
                                  state.rect.height,
1132
                                  stell(s), (int)(cbp - cbuf.data),
1133
                                  (int)(cbuf.end - cbuf.data));
1134
                        code = gs_note_error(gs_error_ioerror);
1135
                        goto out;
1136
                    }
1137
#endif
1138
0
                    for (pln = 0; pln < planes; pln++) {
1139
0
                        byte *plane_bits = data_bits + pln * plane_height * raster;
1140
1141
                        /* Fill the cbuf if needed to get the data for the plane */
1142
0
                        if (cbp + out_bytes >= cbuf.warn_limit) {
1143
0
                            code = top_up_cbuf(&cbuf, &cbp);
1144
0
                            if (code < 0)
1145
0
                                goto top_up_failed;
1146
0
                        }
1147
0
                        if (pln)
1148
0
                            compression = *cbp++;
1149
1150
0
                        if (compression == cmd_compress_const) {
1151
0
                            cbp = cmd_read_data(&cbuf, plane_bits, 1, cbp);
1152
0
                            if (width_bytes > 0 && state.rect.height > 0)
1153
0
                                memset(plane_bits+1, *plane_bits, width_bytes * state.rect.height - 1);
1154
0
                            if (pln == 0)
1155
0
                                source = data_bits;
1156
1157
0
                        } else if (compression) {       /* Decompress the image data. */
1158
0
                            stream_cursor_read r;
1159
0
                            stream_cursor_write w;
1160
1161
                            /* We don't know the data length a priori, */
1162
                            /* so to be conservative, we read */
1163
                            /* the uncompressed size. */
1164
0
                            uint cleft = cbuf.end - cbp;
1165
1166
0
                            if (cleft < bytes  && !cbuf.end_status) {
1167
0
                                uint nread = cbuf_size - cleft;
1168
1169
0
                                advance_buffer(&cbuf, cbp);
1170
0
                                cbuf.end_status = sgets(s, cbuf.data + cleft, nread, &nread);
1171
0
                                set_cb_end(&cbuf, cbuf.data + cleft + nread);
1172
0
                                cbp = cbuf.data;
1173
0
                            }
1174
0
                            r.ptr = cbp - 1;
1175
0
                            r.limit = cbuf.end - 1;
1176
0
                            w.ptr = plane_bits - 1;
1177
0
                            w.limit = w.ptr + data_bits_size;
1178
0
                            switch (compression) {
1179
0
                                case cmd_compress_rle:
1180
0
                                    {
1181
0
                                        stream_RLD_state sstate;
1182
1183
0
                                        clist_rld_init(&sstate);
1184
                                        /* The process procedure can't fail. */
1185
0
                                        (*s_RLD_template.process)
1186
0
                                            ((stream_state *)&sstate, &r, &w, true);
1187
0
                                    }
1188
0
                                    break;
1189
0
                                case cmd_compress_cfe:
1190
0
                                    {
1191
0
                                        stream_CFD_state sstate;
1192
1193
0
                                        clist_cfd_init(&sstate,
1194
0
                                        width_bytes << 3 /*state.rect.width */ ,
1195
0
                                                       state.rect.height, mem);
1196
                                        /* The process procedure can't fail. */
1197
0
                                        (*s_CFD_template.process)
1198
0
                                            ((stream_state *)&sstate, &r, &w, true);
1199
0
                                        (*s_CFD_template.release)
1200
0
                                            ((stream_state *)&sstate);
1201
0
                                    }
1202
0
                                    break;
1203
0
                                default:
1204
0
                                    goto bad_op;
1205
0
                            }
1206
0
                            cbp = r.ptr + 1;
1207
0
                            if (pln == 0)
1208
0
                                source = data_bits;
1209
0
                        } else if ((state.rect.height > 1 && width_bytes != raster) ||
1210
0
                                   (plane_height != 0)) {
1211
0
                            cbp = cmd_read_short_bits(&cbuf, plane_bits, bytes, width_bytes,
1212
0
                                                      state.rect.height, raster, cbp);
1213
0
                            if (pln == 0)
1214
0
                                source = data_bits;
1215
0
                        } else {
1216
                            /* Never used for planar data */
1217
0
                            cbp = cmd_read_data(&cbuf, cbuf.data, bytes, cbp);
1218
0
                            source = cbuf.data;
1219
0
                        }
1220
0
                    }
1221
#ifdef DEBUG
1222
                    if (gs_debug_c('L')) {
1223
                        dmprintf2(mem, " depth=%d, data_x=%d\n",
1224
                                  depth, data_x);
1225
                        cmd_print_bits(mem, source, state.rect.width,
1226
                                       state.rect.height, raster);
1227
                    }
1228
#endif
1229
0
                }
1230
0
                break;
1231
0
            case cmd_op_delta_tile_index >> 4:
1232
0
                state.tile_index += (int)(op & 0xf) - 8;
1233
0
                goto sti;
1234
0
            case cmd_op_set_tile_index >> 4:
1235
0
                state.tile_index =
1236
0
                    ((op & 0xf) << 8) + *cbp++;
1237
0
              sti:state_slot =
1238
0
                    (tile_slot *) (cdev->cache_chunk->data +
1239
0
                                 cdev->tile_table[state.tile_index].offset);
1240
0
                if_debug2m('L', mem, " index=%u offset=%lu\n",
1241
0
                           state.tile_index,
1242
0
                           cdev->tile_table[state.tile_index].offset);
1243
0
                state_tile.data = (byte *) (state_slot + 1);
1244
0
              stp:state_tile.size.x = state_slot->width;
1245
0
                state_tile.size.y = state_slot->height;
1246
0
                state_tile.raster = state_slot->raster;
1247
0
                state_tile.rep_width = state_tile.size.x /
1248
0
                    state_slot->x_reps;
1249
0
                state_tile.rep_height = state_tile.size.y /
1250
0
                    state_slot->y_reps;
1251
0
                state_tile.rep_shift = state_slot->rep_shift;
1252
0
                state_tile.shift = state_slot->shift;
1253
0
                state_tile.id = state_slot->id;
1254
0
                state_tile.num_planes = state_slot->num_planes;
1255
0
set_tile_phase:
1256
0
                if (state_tile.size.x)
1257
0
                    tile_phase.x =
1258
0
                        (state.tile_phase.x + x0) % state_tile.size.x;
1259
                /*
1260
                 * The true tile height for shifted tiles is not
1261
                 * size.y: see gxbitmap.h for the computation.
1262
                 */
1263
0
                if (state_tile.size.y) {
1264
0
                    int full_height;
1265
1266
0
                    if (state_tile.shift == 0)
1267
0
                        full_height = state_tile.size.y;
1268
0
                    else
1269
0
                        full_height = state_tile.rep_height *
1270
0
                                    (state_tile.rep_width /
1271
0
                                     igcd(state_tile.rep_shift,
1272
0
                                          state_tile.rep_width));
1273
0
                    tile_phase.y = (state.tile_phase.y + y0) % full_height;
1274
0
                }
1275
0
                continue;
1276
0
            case cmd_op_misc2 >> 4:
1277
0
                switch (op) {
1278
0
                    case cmd_opv_set_bits_planar:
1279
0
                        goto do_opv_set_bits;
1280
0
                    case cmd_opv_set_fill_adjust:
1281
0
                        cmd_get_value(gs_gstate.fill_adjust.x, cbp);
1282
0
                        cmd_get_value(gs_gstate.fill_adjust.y, cbp);
1283
0
                        if_debug2m('L', mem, " (%g,%g)\n",
1284
0
                                   fixed2float(gs_gstate.fill_adjust.x),
1285
0
                                   fixed2float(gs_gstate.fill_adjust.y));
1286
0
                        continue;
1287
0
                    case cmd_opv_set_ctm:
1288
0
                        {
1289
0
                            gs_matrix mat;
1290
1291
0
                            cbp = cmd_read_matrix(&mat, cbp);
1292
0
                            if_debug6m('L', mem, " [%g %g %g %g %g %g]\n",
1293
0
                                       mat.xx, mat.xy, mat.yx, mat.yy,
1294
0
                                       mat.tx, mat.ty);
1295
0
                            mat.tx -= x0;
1296
0
                            mat.ty -= y0;
1297
0
                            gs_gstate_setmatrix(&gs_gstate, &mat);
1298
0
                        }
1299
0
                        continue;
1300
0
                    case cmd_opv_set_misc2:
1301
0
                        cbuf.ptr = cbp;
1302
0
                        code = read_set_misc2(&cbuf, &gs_gstate, &notes);
1303
0
                        cbp = cbuf.ptr;
1304
0
                        if (code < 0)
1305
0
                            goto out;
1306
0
                        continue;
1307
0
                    case cmd_opv_set_dash:
1308
0
                        {
1309
0
                            int nb = *cbp++;
1310
0
                            int n = nb & 0x3f;
1311
0
                            float dot_length, offset;
1312
1313
0
                            cmd_get_value(dot_length, cbp);
1314
0
                            cmd_get_value(offset, cbp);
1315
0
                            memcpy(dash_pattern, cbp, n * sizeof(float));
1316
1317
0
                            gx_set_dash(&gs_gstate.line_params.dash,
1318
0
                                        dash_pattern, n, offset,
1319
0
                                        NULL);
1320
0
                            gx_set_dash_adapt(&gs_gstate.line_params.dash,
1321
0
                                              (nb & 0x80) != 0);
1322
0
                            gx_set_dot_length(&gs_gstate.line_params,
1323
0
                                              dot_length,
1324
0
                                              (nb & 0x40) != 0);
1325
#ifdef DEBUG
1326
                            if (gs_debug_c('L')) {
1327
                                int i;
1328
1329
                                dmprintf4(mem, " dot=%g(mode %d) adapt=%d offset=%g [",
1330
                                         dot_length,
1331
                                         (nb & 0x40) != 0,
1332
                                         (nb & 0x80) != 0, offset);
1333
                                for (i = 0; i < n; ++i)
1334
                                    dmprintf1(mem, "%g ", dash_pattern[i]);
1335
                                dmputs(mem, "]\n");
1336
                            }
1337
#endif
1338
0
                            cbp += n * sizeof(float);
1339
0
                        }
1340
0
                        break;
1341
0
                    case cmd_opv_enable_clip:
1342
0
                        pcpath = (use_clip ? &clip_path : NULL);
1343
0
                        if (pcpath) {
1344
0
                            code = gx_cpath_ensure_path_list(pcpath);
1345
0
                            if (code < 0)
1346
0
                                goto out;
1347
0
                        }
1348
0
                        if (clipper_dev_open)
1349
0
                            gx_destroy_clip_device_on_stack(&clipper_dev);
1350
0
                        clipper_dev_open = false;
1351
0
                        if_debug0m('L', mem, "\n");
1352
0
                        break;
1353
0
                    case cmd_opv_disable_clip:
1354
0
                        pcpath = NULL;
1355
0
                        if (clipper_dev_open)
1356
0
                            gx_destroy_clip_device_on_stack(&clipper_dev);
1357
0
                        clipper_dev_open = false;
1358
0
                        if_debug0m('L', mem, "\n");
1359
0
                        break;
1360
0
                    case cmd_opv_begin_clip:
1361
0
                        pcpath = NULL;
1362
0
                        if (clipper_dev_open)
1363
0
                            gx_destroy_clip_device_on_stack(&clipper_dev);
1364
0
                        clipper_dev_open = false;
1365
0
                        in_clip = true;
1366
0
                        if_debug0m('L', mem, "\n");
1367
0
                        code = gx_cpath_reset(&clip_path);
1368
0
                        if (code < 0)
1369
0
                            goto out;
1370
0
                        gx_cpath_accum_begin(&clip_accum, mem, false);
1371
0
                        gx_cpath_accum_set_cbox(&clip_accum,
1372
0
                                                &target_box);
1373
0
                        tdev = (gx_device *)&clip_accum;
1374
0
                        clip_save.lop_enabled = state.lop_enabled;
1375
0
                        clip_save.dcolor = fill_color;
1376
0
                        clip_save.fa_save.x = gs_gstate.fill_adjust.x;
1377
0
                        clip_save.fa_save.y = gs_gstate.fill_adjust.y;
1378
0
                        cmd_getw(gs_gstate.fill_adjust.x, cbp);
1379
0
                        cmd_getw(gs_gstate.fill_adjust.y, cbp);
1380
                        /* temporarily set a solid color */
1381
0
                        color_set_pure(&fill_color, (gx_color_index)1);
1382
0
                        state.lop_enabled = false;
1383
0
                        gs_gstate.log_op = lop_default;
1384
0
                        break;
1385
0
                    case cmd_opv_end_clip:
1386
0
                        if_debug0m('L', mem, "\n");
1387
0
                        gx_cpath_accum_end(&clip_accum, &clip_path);
1388
0
                        tdev = target;
1389
                        /*
1390
                         * If the entire band falls within the clip
1391
                         * path, no clipping is needed.
1392
                         */
1393
0
                        {
1394
0
                            gs_fixed_rect cbox;
1395
1396
0
                            gx_cpath_inner_box(&clip_path, &cbox);
1397
0
                            use_clip =
1398
0
                                !(cbox.p.x <= target_box.p.x &&
1399
0
                                  cbox.q.x >= target_box.q.x &&
1400
0
                                  cbox.p.y <= target_box.p.y &&
1401
0
                                  cbox.q.y >= target_box.q.y);
1402
0
                        }
1403
0
                        pcpath = (use_clip ? &clip_path : NULL);
1404
0
                        if (pcpath) {
1405
0
                            code = gx_cpath_ensure_path_list(pcpath);
1406
0
                            if (code < 0)
1407
0
                                goto out;
1408
0
                        }
1409
0
                        if (clipper_dev_open)
1410
0
                            gx_destroy_clip_device_on_stack(&clipper_dev);
1411
0
                        clipper_dev_open = false;
1412
0
                        state.lop_enabled = clip_save.lop_enabled;
1413
0
                        gs_gstate.log_op =
1414
0
                            (state.lop_enabled ? state.lop :
1415
0
                             lop_default);
1416
0
                        fill_color = clip_save.dcolor;
1417
                        /* restore the fill_adjust if it was changed by begin_clip */
1418
0
                        gs_gstate.fill_adjust.x = clip_save.fa_save.x;
1419
0
                        gs_gstate.fill_adjust.y = clip_save.fa_save.y;
1420
0
                        in_clip = false;
1421
0
                        break;
1422
0
                    case cmd_opv_set_color_space:
1423
0
                        cbuf.ptr = cbp;
1424
0
                        code = read_set_color_space(&cbuf, &gs_gstate, cdev, mem);
1425
0
                        pcs = gs_gstate.color[0].color_space;
1426
0
                        cbp = cbuf.ptr;
1427
0
                        if (code < 0) {
1428
0
                            if (code == gs_error_rangecheck)
1429
0
                                goto bad_op;
1430
0
                            goto out;
1431
0
                        }
1432
0
                        break;
1433
0
                    case cmd_op_fill_rect_hl:
1434
0
                        {
1435
0
                            gs_fixed_rect rect_hl;
1436
1437
0
                            cbp = cmd_read_rect(op & 0xf0, &state.rect, cbp);
1438
0
                            if (fill_color.type != gx_dc_type_devn) {
1439
0
                                if_debug0m('L', mem, "hl rect fill without devn color\n");
1440
0
                                code = gs_note_error(gs_error_typecheck);
1441
0
                                goto out;
1442
0
                            }
1443
0
                            if_debug4m('L', mem, " x=%d y=%d w=%d h=%d\n",
1444
0
                                       state.rect.x, state.rect.y,
1445
0
                                       state.rect.width,state.rect.height);
1446
0
                            rect_hl.p.x = int2fixed(state.rect.x - x0);
1447
0
                            rect_hl.p.y = int2fixed(state.rect.y - y0);
1448
0
                            rect_hl.q.x = int2fixed(state.rect.width) + rect_hl.p.x;
1449
0
                            rect_hl.q.y = int2fixed(state.rect.height) + rect_hl.p.y;
1450
0
                            code = dev_proc(tdev, fill_rectangle_hl_color) (tdev,
1451
0
                                                        &rect_hl, NULL,
1452
0
                                                        &fill_color, NULL);
1453
0
                        }
1454
0
                        continue;
1455
0
                    case cmd_opv_begin_image_rect:
1456
0
                        cbuf.ptr = cbp;
1457
0
                        code = read_begin_image(&cbuf, &image.c, pcs);
1458
0
                        cbp = cbuf.ptr;
1459
0
                        if (code < 0)
1460
0
                            goto out;
1461
0
                        {
1462
0
                            uint diff;
1463
1464
0
                            cmd_getw(image_rect.p.x, cbp);
1465
0
                            cmd_getw(image_rect.p.y, cbp);
1466
0
                            cmd_getw(diff, cbp);
1467
0
                            image_rect.q.x = image.d.Width - diff;
1468
0
                            cmd_getw(diff, cbp);
1469
0
                            image_rect.q.y = image.d.Height - diff;
1470
0
                            if_debug4m('L', mem, " rect=(%d,%d),(%d,%d)",
1471
0
                                       image_rect.p.x, image_rect.p.y,
1472
0
                                       image_rect.q.x, image_rect.q.y);
1473
0
                        }
1474
0
                        goto ibegin;
1475
0
                    case cmd_opv_begin_image:
1476
0
                        cbuf.ptr = cbp;
1477
0
                        code = read_begin_image(&cbuf, &image.c, pcs);
1478
0
                        cbp = cbuf.ptr;
1479
0
                        if (code < 0)
1480
0
                            goto out;
1481
0
                        image_rect.p.x = 0;
1482
0
                        image_rect.p.y = 0;
1483
0
                        image_rect.q.x = image.d.Width;
1484
0
                        image_rect.q.y = image.d.Height;
1485
0
                        if_debug2m('L', mem, " size=(%d,%d)",
1486
0
                                  image.d.Width, image.d.Height);
1487
0
ibegin:                 if_debug0m('L', mem, "\n");
1488
0
                        {
1489
                            /* Processing an image operation */
1490
0
                            dev_proc(tdev, set_graphics_type_tag)(tdev, GS_IMAGE_TAG);/* FIXME: what about text bitmaps? */
1491
0
                            image.i4.override_in_smask = 0;
1492
0
                            code = (*dev_proc(tdev, begin_typed_image))
1493
0
                                (tdev, &gs_gstate, NULL,
1494
0
                                 (const gs_image_common_t *)&image,
1495
0
                                 &image_rect, &fill_color, pcpath, mem,
1496
0
                                 &image_info);
1497
0
                        }
1498
0
                        if (code < 0)
1499
0
                            goto out;
1500
0
                        break;
1501
0
                    case cmd_opv_image_plane_data:
1502
0
                        cmd_getw(data_height, cbp);
1503
0
                        if (data_height == 0) {
1504
0
                            if_debug0m('L', mem, " done image\n");
1505
0
                            code = gx_image_end(image_info, true);
1506
0
                            if (code < 0)
1507
0
                                goto out;
1508
0
                            continue;
1509
0
                        }
1510
0
                        {
1511
0
                            uint flags;
1512
0
                            int plane;
1513
0
                            uint raster1 = 0xbaadf00d; /* Initialize against indeterminizm. */
1514
1515
0
                            cmd_getw(flags, cbp);
1516
0
                            for (plane = 0;
1517
0
                                 plane < image_info->num_planes;
1518
0
                                 ++plane, flags >>= 1) {
1519
0
                                if (flags & 1) {
1520
0
                                    if (cbuf.end - cbp <
1521
0
                                        2 * cmd_max_intsize(sizeof(uint))) {
1522
0
                                        code = top_up_cbuf(&cbuf, &cbp);
1523
0
                                        if (code < 0)
1524
0
                                            goto top_up_failed;
1525
0
                                    }
1526
0
                                    cmd_getw(planes[plane].raster, cbp);
1527
0
                                    if ((raster1 = planes[plane].raster) != 0)
1528
0
                                        cmd_getw(data_x, cbp);
1529
0
                                } else {
1530
0
                                    planes[plane].raster = raster1;
1531
0
                                }
1532
0
                                planes[plane].data_x = data_x;
1533
0
                            }
1534
0
                        }
1535
0
                        goto idata;
1536
0
                    case cmd_opv_image_data:
1537
0
                        cmd_getw(data_height, cbp);
1538
0
                        if (data_height == 0) {
1539
0
                            if_debug0m('L', mem, " done image\n");
1540
0
                            code = gx_image_end(image_info, true);
1541
0
                            if (code < 0)
1542
0
                                goto out;
1543
0
                            continue;
1544
0
                        }
1545
0
                        {
1546
0
                            uint bytes_per_plane;
1547
0
                            int plane;
1548
1549
0
                            cmd_getw(bytes_per_plane, cbp);
1550
0
                            if_debug2m('L', mem, " height=%u raster=%u\n",
1551
0
                                       data_height, bytes_per_plane);
1552
0
                            for (plane = 0;
1553
0
                                 plane < image_info->num_planes;
1554
0
                                 ++plane
1555
0
                                 ) {
1556
0
                                planes[plane].data_x = data_x;
1557
0
                                planes[plane].raster = bytes_per_plane;
1558
0
                            }
1559
0
                        }
1560
0
idata:                  data_size = 0;
1561
0
                        {
1562
0
                            int plane;
1563
1564
0
                            for (plane = 0; plane < image_info->num_planes;
1565
0
                                 ++plane)
1566
0
                                data_size += planes[plane].raster;
1567
0
                        }
1568
0
                        data_size *= data_height;
1569
0
                        data_on_heap = 0;
1570
0
                        if (cbuf.end - cbp < data_size) {
1571
0
                            code = top_up_cbuf(&cbuf, &cbp);
1572
0
                            if (code < 0)
1573
0
                                goto top_up_failed;
1574
0
                        }
1575
0
                        if (cbuf.end - cbp >= data_size) {
1576
0
                            planes[0].data = cbp;
1577
0
                            cbp += data_size;
1578
0
                        } else {
1579
0
                            uint cleft = cbuf.end - cbp;
1580
0
                            uint rleft = data_size - cleft;
1581
0
                            byte *rdata;
1582
1583
0
                            if (data_size > cbuf.end - cbuf.data) {
1584
                                /* Allocate a separate buffer. */
1585
0
                                rdata = data_on_heap =
1586
0
                                    gs_alloc_bytes(mem, data_size,
1587
0
                                                   "clist image_data");
1588
0
                                if (rdata == 0) {
1589
0
                                    code = gs_note_error(gs_error_VMerror);
1590
0
                                    goto out;
1591
0
                                }
1592
0
                            } else
1593
0
                                rdata = cbuf.data;
1594
0
                            memmove(rdata, cbp, cleft);
1595
0
                            if (data_on_heap)
1596
0
                                next_is_skip(&cbuf);
1597
0
                            if (sgets(s, rdata + cleft, rleft, &rleft) < 0) {
1598
0
                                code = gs_note_error(gs_error_unregistered); /* Must not happen. */
1599
0
                                goto out;
1600
0
                            }
1601
0
                            planes[0].data = rdata;
1602
0
                            cbp = cbuf.end;     /* force refill */
1603
0
                        }
1604
0
                        {
1605
0
                            int plane;
1606
0
                            const byte *data = planes[0].data;
1607
1608
0
                            for (plane = 0;
1609
0
                                 plane < image_info->num_planes;
1610
0
                                 ++plane
1611
0
                                 ) {
1612
0
                                if (planes[plane].raster == 0)
1613
0
                                    planes[plane].data = 0;
1614
0
                                else {
1615
0
                                    planes[plane].data = data;
1616
0
                                    data += planes[plane].raster *
1617
0
                                        data_height;
1618
0
                                }
1619
0
                            }
1620
0
                        }
1621
#ifdef DEBUG
1622
                        if (gs_debug_c('L')) {
1623
                            int plane;
1624
1625
                            for (plane = 0; plane < image_info->num_planes;
1626
                                 ++plane)
1627
                                if (planes[plane].data != 0)
1628
                                    cmd_print_bits(mem,
1629
                                                   planes[plane].data,
1630
                                                   image_rect.q.x -
1631
                                                   image_rect.p.x,
1632
                                                   data_height,
1633
                                                   planes[plane].raster);
1634
                        }
1635
#endif
1636
0
                        code = gx_image_plane_data(image_info, planes,
1637
0
                                                   data_height);
1638
0
                        if (code < 0)
1639
0
                            gx_image_end(image_info, false);
1640
0
                        if (data_on_heap)
1641
0
                            gs_free_object(mem, data_on_heap,
1642
0
                                           "clist image_data");
1643
0
                        data_x = 0;
1644
0
                        if (code < 0)
1645
0
                            goto out;
1646
0
                        continue;
1647
0
                    case cmd_opv_extend:
1648
0
                        switch (*cbp++) {
1649
0
                            case cmd_opv_ext_put_params:
1650
0
                                if_debug0m('L', mem, "put_params\n");
1651
0
                                cbuf.ptr = cbp;
1652
0
                                code = read_put_params(&cbuf, &gs_gstate,
1653
0
                                                        cdev, mem);
1654
0
                                cbp = cbuf.ptr;
1655
0
                                if (code > 0)
1656
0
                                    break; /* empty list */
1657
0
                                if (code < 0)
1658
0
                                    goto out;
1659
0
                                if (playback_action == playback_action_setup)
1660
0
                                    goto out;
1661
0
                                break;
1662
0
                            case cmd_opv_ext_composite:
1663
0
                                if_debug0m('L', mem, " ext_composite\n");
1664
0
                                cbuf.ptr = cbp;
1665
                                /*
1666
                                 * The screen phase may have been changed during
1667
                                 * the processing of masked images.
1668
                                 */
1669
0
                                gx_gstate_setscreenphase(&gs_gstate,
1670
0
                                            -x0, -y0, gs_color_select_all);
1671
0
                                cbp -= 2; /* Step back to simplify the cycle invariant below. */
1672
0
                                for (;;) {
1673
                                    /* This internal loop looks ahead for compositor commands and
1674
                                       copies them into a temporary queue. Compositors, which do not paint something,
1675
                                       are marked as idle and later executed with a reduced functionality
1676
                                       for reducing time and memory expense. */
1677
0
                                    int len;
1678
1679
0
                                    if (cbp >= cbuf.warn_limit) {
1680
0
                                        code = top_up_cbuf(&cbuf, &cbp);
1681
0
                                        if (code < 0)
1682
0
                                            goto out;
1683
0
                                    }
1684
#ifdef DEBUG
1685
                                    if (gs_debug_c('L')) {
1686
                                       long offset = (long)clist_file_offset(st, cbp - cbuf.data);
1687
1688
                                       dmlprintf1(mem, "[L]  %ld:", offset);
1689
                                       clist_debug_op(mem, cbp);
1690
                                       dmlprintf(mem, "\n");
1691
                                    }
1692
#endif
1693
0
                                    if (cbp[0] == cmd_opv_extend && cbp[1] == cmd_opv_ext_composite) {
1694
0
                                        gs_composite_t *pcomp, *pcomp_opening;
1695
0
                                        gs_compositor_closing_state closing_state;
1696
1697
0
                                        cbuf.ptr = cbp += 2;
1698
0
                                        code = read_composite(&cbuf, mem, &pcomp);
1699
0
                                        if (code < 0)
1700
0
                                            goto out;
1701
0
                                        cbp = cbuf.ptr;
1702
0
                                        if (pcomp == NULL)
1703
0
                                            continue;
1704
0
                                        if (gs_is_pdf14trans_compositor(pcomp) &&
1705
0
                                            playback_action == playback_action_render_no_pdf14) {
1706
                                            /* free the compositor object */
1707
0
                                            gs_free_object(mem, pcomp, "read_composite");
1708
0
                                            pcomp = NULL;
1709
0
                                            continue;
1710
0
                                        }
1711
0
                                        pcomp_opening = pcomp_last;
1712
0
                                        closing_state = pcomp->type->procs.is_closing(pcomp, &pcomp_opening, tdev);
1713
0
                                        switch(closing_state)
1714
0
                                        {
1715
0
                                        default:
1716
0
                                            code = (int)closing_state;
1717
0
                                            if (code >= 0)
1718
0
                                                code = gs_note_error(gs_error_unregistered); /* Must not happen. */
1719
0
                                            goto out;
1720
0
                                        case COMP_ENQUEUE:
1721
                                            /* Enqueue. */
1722
0
                                            enqueue_compositor(&pcomp_first, &pcomp_last, pcomp);
1723
0
                                            break;
1724
0
                                        case COMP_EXEC_IDLE:
1725
                                            /* Execute idle. */
1726
0
                                            enqueue_compositor(&pcomp_first, &pcomp_last, pcomp);
1727
0
                                            code = execute_compositor_queue(cdev, &target, &tdev,
1728
0
                                                &gs_gstate, &pcomp_first, &pcomp_last, pcomp_opening, x0, y0, mem, true);
1729
0
                                            if (code < 0)
1730
0
                                                goto out;
1731
0
                                            break;
1732
0
                                        case COMP_EXEC_QUEUE:
1733
                                            /* The opening command was executed. Execute the queue. */
1734
0
                                            enqueue_compositor(&pcomp_first, &pcomp_last, pcomp);
1735
0
                                            code = execute_compositor_queue(cdev, &target, &tdev,
1736
0
                                                &gs_gstate, &pcomp_first, &pcomp_last, pcomp_first, x0, y0, mem, false);
1737
0
                                            if (code < 0)
1738
0
                                                goto out;
1739
0
                                            break;
1740
0
                                        case COMP_REPLACE_PREV:
1741
                                            /* Replace last compositors. */
1742
0
                                            code = execute_compositor_queue(cdev, &target, &tdev,
1743
0
                                                &gs_gstate, &pcomp_first, &pcomp_last, pcomp_opening, x0, y0, mem, true);
1744
0
                                            if (code < 0)
1745
0
                                                goto out;
1746
0
                                            enqueue_compositor(&pcomp_first, &pcomp_last, pcomp);
1747
0
                                            break;
1748
0
                                        case COMP_REPLACE_CURR:
1749
                                            /* Replace specific compositor. */
1750
0
                                            code = dequeue_compositor(&pcomp_first, &pcomp_last, pcomp_opening);
1751
0
                                            if (code < 0)
1752
0
                                                goto out;
1753
0
                                            enqueue_compositor(&pcomp_first, &pcomp_last, pcomp);
1754
0
                                            free_compositor(pcomp_opening, mem);
1755
0
                                            break;
1756
0
                                        case COMP_DROP_QUEUE:
1757
                                            /* Annihilate the last compositors. */
1758
0
                                            enqueue_compositor(&pcomp_first, &pcomp_last, pcomp);
1759
0
                                            code = drop_compositor_queue(&pcomp_first, &pcomp_last, pcomp_opening, mem, x0, y0, &gs_gstate);
1760
0
                                            if (code < 0)
1761
0
                                                goto out;
1762
0
                                            break;
1763
0
                                        case COMP_MARK_IDLE:
1764
                                            /* Mark as idle. */
1765
0
                                            enqueue_compositor(&pcomp_first, &pcomp_last, pcomp);
1766
0
                                            mark_as_idle(pcomp_opening, pcomp);
1767
0
                                        }
1768
0
                                    } else if (is_null_compositor_op(cbp, &len)) {
1769
0
                                        cbuf.ptr = cbp += len;
1770
0
                                    } else if (cbp[0] == cmd_opv_end_page) {
1771
                                        /* End page, drop the queue. */
1772
0
                                        code = execute_compositor_queue(cdev, &target, &tdev,
1773
0
                                                &gs_gstate, &pcomp_first, &pcomp_last, pcomp_first, x0, y0, mem, true);
1774
0
                                        if (code < 0)
1775
0
                                            goto out;
1776
0
                                        break;
1777
0
                                    } else if (pcomp_last != NULL &&
1778
0
                                            pcomp_last->type->procs.is_friendly(pcomp_last, cbp[0], cbp[1])) {
1779
                                        /* Immediately execute friendly commands
1780
                                           inside the compositor lookahead loop.
1781
                                           Currently there are few friendly commands for the pdf14 compositor only
1782
                                           due to the logic defined in c_pdf14trans_is_friendly.
1783
                                           This code duplicates some code portions from the main loop,
1784
                                           but we have no better idea with no slowdown to the main loop.
1785
                                         */
1786
0
                                        uint cb;
1787
1788
0
                                        switch (*cbp++) {
1789
0
                                            case cmd_opv_extend:
1790
0
                                                switch (*cbp++) {
1791
0
                                                    case cmd_opv_ext_put_halftone:
1792
0
                                                        {
1793
0
                                                            uint    ht_size;
1794
1795
0
                                                            enc_u_getw(ht_size, cbp);
1796
0
                                                            code = read_alloc_ht_buff(&ht_buff, ht_size, mem);
1797
0
                                                            if (code < 0)
1798
0
                                                                goto out;
1799
0
                                                        }
1800
0
                                                        break;
1801
0
                                                    case cmd_opv_ext_put_ht_seg:
1802
0
                                                        cbuf.ptr = cbp;
1803
0
                                                        code = read_ht_segment(&ht_buff, &cbuf,
1804
0
                                                                               &gs_gstate, tdev,
1805
0
                                                                               mem);
1806
0
                                                        cbp = cbuf.ptr;
1807
0
                                                        if (code < 0)
1808
0
                                                            goto out;
1809
0
                                                        break;
1810
0
                                                    default:
1811
0
                                                        code = gs_note_error(gs_error_unregistered); /* Must not happen. */
1812
0
                                                        goto out;
1813
0
                                                }
1814
0
                                                break;
1815
0
                                            case cmd_opv_set_misc:
1816
0
                                                cb = *cbp++;
1817
0
                                                switch (cb >> 6) {
1818
0
                                                    case cmd_set_misc_map >> 6:
1819
0
                                                        cbuf.ptr = cbp;
1820
0
                                                        code = read_set_misc_map(cb, &cbuf, &gs_gstate, mem);
1821
0
                                                        if (code < 0)
1822
0
                                                            goto out;
1823
0
                                                        cbp = cbuf.ptr;
1824
0
                                                        break;
1825
0
                                                    default:
1826
0
                                                        code = gs_note_error(gs_error_unregistered); /* Must not happen. */
1827
0
                                                        goto out;
1828
0
                                                }
1829
0
                                                break;
1830
0
                                            default:
1831
0
                                                code = gs_note_error(gs_error_unregistered); /* Must not happen. */
1832
0
                                                goto out;
1833
0
                                        }
1834
0
                                    } else {
1835
                                        /* A drawing command, execute entire queue. */
1836
0
                                        code = execute_compositor_queue(cdev, &target, &tdev,
1837
0
                                            &gs_gstate, &pcomp_first, &pcomp_last, pcomp_first, x0, y0, mem, false);
1838
0
                                        if (code < 0)
1839
0
                                            goto out;
1840
0
                                        break;
1841
0
                                    }
1842
0
                                }
1843
0
                                if (pcomp_last != NULL) {
1844
0
                                    code = gs_note_error(gs_error_unregistered);
1845
0
                                    goto out;
1846
0
                                }
1847
0
                                break;
1848
0
                            case cmd_opv_ext_put_halftone:
1849
0
                                {
1850
0
                                    uint    ht_size;
1851
1852
0
                                    if_debug0m('L', mem, " ext_put_halftone\n");
1853
0
                                    enc_u_getw(ht_size, cbp);
1854
0
                                    code = read_alloc_ht_buff(&ht_buff, ht_size, mem);
1855
0
                                    if (code < 0)
1856
0
                                        goto out;
1857
0
                                }
1858
0
                                break;
1859
0
                            case cmd_opv_ext_put_ht_seg:
1860
0
                                if_debug0m('L', mem, " ext_put_ht_seg\n");
1861
0
                                cbuf.ptr = cbp;
1862
0
                                code = read_ht_segment(&ht_buff, &cbuf,
1863
0
                                                       &gs_gstate, tdev,
1864
0
                                                       mem);
1865
0
                                cbp = cbuf.ptr;
1866
0
                                if (code < 0)
1867
0
                                    goto out;
1868
0
                                break;
1869
0
                            case cmd_opv_ext_set_color_is_devn:
1870
0
                                state.color_is_devn = true;
1871
0
                                if_debug0m('L', mem, " ext_set_color_is_devn\n");
1872
0
                                break;
1873
0
                            case cmd_opv_ext_unset_color_is_devn:
1874
0
                                state.color_is_devn = false;
1875
0
                                if_debug0m('L', mem, " ext_unset_color_is_devn\n");
1876
0
                                break;
1877
0
                            case cmd_opv_ext_tile_rect_hl:
1878
                                /* Strip tile with devn colors */
1879
0
                                cbp = cmd_read_rect(op & 0xf0, &state.rect, cbp);
1880
0
                                if_debug4m('L', mem, " x=%d y=%d w=%d h=%d\n",
1881
0
                                           state.rect.x, state.rect.y,
1882
0
                                           state.rect.width,state.rect.height);
1883
0
                                code = (*dev_proc(tdev, strip_tile_rect_devn))
1884
0
                                    (tdev, &state_tile,
1885
0
                                     state.rect.x - x0, state.rect.y - y0,
1886
0
                                     state.rect.width, state.rect.height,
1887
0
                                     &(state.tile_color_devn[0]),
1888
0
                                     &(state.tile_color_devn[1]),
1889
0
                                     tile_phase.x, tile_phase.y);
1890
0
                                break;
1891
0
                            case cmd_opv_ext_put_fill_dcolor:
1892
0
                                pdcolor = &fill_color;
1893
0
                                goto load_dcolor;
1894
0
                            case cmd_opv_ext_put_stroke_dcolor:
1895
0
                                pdcolor = &stroke_color;
1896
0
                                goto load_dcolor;
1897
0
                            case cmd_opv_ext_put_tile_devn_color0:
1898
0
                                pdcolor = &set_dev_colors[0];
1899
0
                                goto load_dcolor;
1900
0
                            case cmd_opv_ext_put_tile_devn_color1:
1901
0
                                pdcolor = &set_dev_colors[1];
1902
0
                    load_dcolor:{
1903
0
                                    uint    color_size;
1904
0
                                    int left, offset, l;
1905
0
                                    const gx_device_color_type_t *  pdct;
1906
0
                                    byte type_and_flag = *cbp++;
1907
0
                                    byte is_continuation = type_and_flag & 0x80;
1908
1909
0
                                    if_debug0m('L', mem, " cmd_opv_ext_put_drawing_color\n");
1910
0
                                    pdct = gx_get_dc_type_from_index(type_and_flag & 0x7F);
1911
0
                                    if (pdct == 0) {
1912
0
                                        code = gs_note_error(gs_error_rangecheck);
1913
0
                                        goto out;
1914
0
                                    }
1915
0
                                    offset = 0;
1916
0
                                    if (is_continuation)
1917
0
                                        enc_u_getw(offset, cbp);
1918
0
                                    enc_u_getw(color_size, cbp);
1919
0
                                    left = color_size;
1920
0
                                    if (!left) {
1921
                                        /* We still need to call pdct->read because it may change dev_color.type -
1922
                                           see gx_dc_null_read.*/
1923
0
                                        code = pdct->read(pdcolor, &gs_gstate,
1924
0
                                                          pdcolor, tdev, offset,
1925
0
                                                          cbp, 0, mem, x0, y0);
1926
0
                                        if (code < 0)
1927
0
                                            goto out;
1928
0
                                    }
1929
0
                                    while (left) {
1930
0
                                        if (cbuf.warn_limit - cbp < (int)left) {  /* cbp can be past warn_limit */
1931
0
                                            code = top_up_cbuf(&cbuf, &cbp);
1932
0
                                            if (code < 0)
1933
0
                                                goto top_up_failed;
1934
0
                                        }
1935
0
                                        l = min(left, cbuf.end - cbp);
1936
0
                                        code = pdct->read(pdcolor, &gs_gstate,
1937
0
                                                          pdcolor, tdev, offset,
1938
0
                                                          cbp, l, mem, x0, y0);
1939
0
                                        if (code < 0)
1940
0
                                            goto out;
1941
0
                                        l = code;
1942
0
                                        cbp += l;
1943
0
                                        offset += l;
1944
0
                                        left -= l;
1945
0
                                    }
1946
0
                                    code = gx_color_load(pdcolor, &gs_gstate,
1947
0
                                                         tdev);
1948
0
                                    if (code < 0)
1949
0
                                        goto out;
1950
0
                                }
1951
0
                                break;
1952
0
                            default:
1953
0
                                goto bad_op;
1954
0
                        }
1955
0
                        break;
1956
0
                    default:
1957
0
                        goto bad_op;
1958
0
                }
1959
0
                continue;
1960
0
            case cmd_op_segment >> 4:
1961
0
                {
1962
0
                    int i;
1963
0
                    static const byte op_num_operands[] = {
1964
0
                        cmd_segment_op_num_operands_values
1965
0
                    };
1966
0
                  rgapto:
1967
0
                    if (!in_path) {
1968
0
                        ppos.x = int2fixed(state.rect.x);
1969
0
                        ppos.y = int2fixed(state.rect.y);
1970
0
                        if_debug2m('L', mem, " (%d,%d)", state.rect.x,
1971
0
                                   state.rect.y);
1972
0
                        notes = sn_none;
1973
0
                        in_path = true;
1974
0
                    }
1975
0
                    for (i = 0; i < op_num_operands[op & 0xf]; ++i) {
1976
0
                        fixed v;
1977
0
                        int b = *cbp;
1978
1979
0
                        switch (b >> 5) {
1980
0
                            case 0:
1981
0
                            case 1:
1982
0
                                vs[i++] =
1983
0
                                    ((fixed) ((b ^ 0x20) - 0x20) << 13) +
1984
0
                                    ((int)cbp[1] << 5) + (cbp[2] >> 3);
1985
0
                                if_debug1m('L', mem, " %g", fixed2float(vs[i - 1]));
1986
0
                                cbp += 2;
1987
0
                                v = (int)((*cbp & 7) ^ 4) - 4;
1988
0
                                break;
1989
0
                            case 2:
1990
0
                            case 3:
1991
0
                                v = (b ^ 0x60) - 0x20;
1992
0
                                break;
1993
0
                            case 4:
1994
0
                            case 5:
1995
                                /*
1996
                                 * Without the following cast, C's
1997
                                 * brain-damaged coercion rules cause the
1998
                                 * result to be considered unsigned, and not
1999
                                 * sign-extended on machines where
2000
                                 * sizeof(long) > sizeof(int).
2001
                                 */
2002
0
                                v = (((b ^ 0xa0) - 0x20) << 8) + (int)*++cbp;
2003
0
                                break;
2004
0
                            case 6:
2005
0
                                v = (b ^ 0xd0) - 0x10;
2006
0
                                vs[i] =
2007
0
                                    ((v << 8) + cbp[1]) << (_fixed_shift - 2);
2008
0
                                if_debug1m('L', mem, " %g", fixed2float(vs[i]));
2009
0
                                cbp += 2;
2010
0
                                continue;
2011
0
                            default /*case 7 */ :
2012
0
                                v = (int)(*++cbp ^ 0x80) - 0x80;
2013
0
                                for (b = 0; b < sizeof(fixed) - 3; ++b)
2014
0
                                    v = (v << 8) + *++cbp;
2015
0
                                break;
2016
0
                        }
2017
0
                        cbp += 3;
2018
                        /* Absent the cast in the next statement, */
2019
                        /* the Borland C++ 4.5 compiler incorrectly */
2020
                        /* sign-extends the result of the shift. */
2021
0
                        vs[i] = (v << 16) + (uint) (cbp[-2] << 8) + cbp[-1];
2022
0
                        if_debug1m('L', mem, " %g", fixed2float(vs[i]));
2023
0
                    }
2024
0
                    if_debug0m('L', mem, "\n");
2025
0
                    code = clist_decode_segment(&path, op, vs, &ppos,
2026
0
                                                x0, y0, notes);
2027
0
                    if (code < 0)
2028
0
                        goto out;
2029
0
                }
2030
0
                continue;
2031
0
            case cmd_op_path >> 4:
2032
0
                if (op == cmd_opv_rgapto)
2033
0
                    goto rgapto;
2034
0
                else if (op == cmd_opv_lock_pattern) {
2035
0
                    gs_id id;
2036
0
                    int lock = *cbp++;
2037
0
                    cmd_get_value(id, cbp);
2038
0
                    if_debug2m('L', mem, "id=0x%lx, lock=%d\n", id, lock);
2039
                    /* We currently lock the pattern in all the bands, even in ones
2040
                     * where we haven't used the pattern. This can cause the following
2041
                     * call to return with 'undefined' because the pattern is not
2042
                     * found. Just swallow this error and continue. */
2043
0
                    code = gx_pattern_cache_entry_set_lock(&gs_gstate, id, lock);
2044
0
                    if (code == gs_error_undefined)
2045
0
                        code = 0;
2046
0
                    if (code < 0)
2047
0
                        goto out;
2048
0
                    continue;
2049
0
                } else {
2050
0
                    gx_path fpath;
2051
0
                    gx_path *ppath = &path;
2052
2053
0
                    if_debug0m('L', mem, "\n");
2054
                    /* if in clip, flatten path first */
2055
0
                    if (in_clip) {
2056
0
                        gx_path_init_local(&fpath, mem);
2057
0
                        code = gx_path_add_flattened_accurate(&path, &fpath,
2058
0
                                             gs_currentflat_inline(&gs_gstate),
2059
0
                                             gs_gstate.accurate_curves);
2060
0
                        if (code < 0)
2061
0
                            goto out;
2062
0
                        ppath = &fpath;
2063
0
                    }
2064
0
                    switch (op) {
2065
0
                        case cmd_opv_fill:
2066
0
                            fill_params.rule = gx_rule_winding_number;
2067
0
                            goto fill;
2068
0
                        case cmd_opv_eofill:
2069
0
                            fill_params.rule = gx_rule_even_odd;
2070
0
                        fill:
2071
0
                            fill_params.adjust = gs_gstate.fill_adjust;
2072
0
                            fill_params.flatness = gs_gstate.flatness;
2073
0
                            code = (*dev_proc(tdev, fill_path))(tdev, &gs_gstate, ppath,
2074
0
                                                                &fill_params, &fill_color, pcpath);
2075
0
                            break;
2076
0
                        case cmd_opv_fill_stroke:
2077
0
                            fill_params.rule = gx_rule_winding_number;
2078
0
                            goto fill_stroke;
2079
0
                        case cmd_opv_eofill_stroke:
2080
0
                            fill_params.rule = gx_rule_even_odd;
2081
0
                        fill_stroke:
2082
0
                            fill_params.adjust = gs_gstate.fill_adjust;
2083
0
                            fill_params.flatness = gs_gstate.flatness;
2084
0
                            stroke_params.flatness = gs_gstate.flatness;
2085
0
                            stroke_params.traditional = false;
2086
0
                            code = (*dev_proc(tdev, fill_stroke_path))(tdev, &gs_gstate, ppath,
2087
0
                                                                &fill_params, &fill_color,
2088
0
                                                                &stroke_params, &stroke_color, pcpath);
2089
0
                            break;
2090
0
                        case cmd_opv_stroke:
2091
0
                            stroke_params.flatness = gs_gstate.flatness;
2092
0
                            stroke_params.traditional = false;
2093
0
                            code = (*dev_proc(tdev, stroke_path))
2094
0
                                                       (tdev, &gs_gstate,
2095
0
                                                       ppath, &stroke_params,
2096
0
                                                       &stroke_color, pcpath);
2097
0
                            break;
2098
0
                        case cmd_opv_polyfill:
2099
0
                            code = clist_do_polyfill(tdev, ppath, &fill_color,
2100
0
                                                     gs_gstate.log_op);
2101
0
                            break;
2102
0
                        case cmd_opv_fill_trapezoid:
2103
0
                            {
2104
0
                                gs_fixed_edge left, right;
2105
0
                                fixed ybot, ytop;
2106
0
                                int options, swap_axes, wh;
2107
0
                                fixed x0f;
2108
0
                                fixed y0f;
2109
0
                                gx_device *ttdev = tdev;
2110
2111
0
                                if (pcpath != NULL && !clipper_dev_open) {
2112
0
                                    gx_make_clip_device_on_stack(&clipper_dev, pcpath, tdev);
2113
0
                                    clipper_dev_open = true;
2114
0
                                }
2115
0
                                if (clipper_dev_open)
2116
0
                                    ttdev = (gx_device *)&clipper_dev;
2117
                                /* Note that if we have transparency present, the clipper device may need to have
2118
                                   its color information updated to be synced up with the target device.
2119
                                   This can occur if we had fills of a path first with a transparency mask to get
2120
                                   an XPS opacity followed by a fill with a transparency group. This occurs in
2121
                                   the XPS gradient code */
2122
0
                                if (tdev->color_info.num_components != ttdev->color_info.num_components){
2123
                                    /* Reset the clipper device color information. Only worry about
2124
                                       the information that is used in the trap code */
2125
0
                                    ttdev->color_info.num_components = tdev->color_info.num_components;
2126
0
                                    ttdev->color_info.depth = tdev->color_info.depth;
2127
0
                                    ttdev->color_info.polarity = tdev->color_info.polarity;
2128
0
                                    memcpy(&(ttdev->color_info.comp_bits),&(tdev->color_info.comp_bits),GX_DEVICE_COLOR_MAX_COMPONENTS);
2129
0
                                    memcpy(&(ttdev->color_info.comp_shift),&(tdev->color_info.comp_shift),GX_DEVICE_COLOR_MAX_COMPONENTS);
2130
0
                                }
2131
0
                                cmd_getw(left.start.x, cbp);
2132
0
                                cmd_getw(left.start.y, cbp);
2133
0
                                cmd_getw(left.end.x, cbp);
2134
0
                                cmd_getw(left.end.y, cbp);
2135
0
                                cmd_getw(right.start.x, cbp);
2136
0
                                cmd_getw(right.start.y, cbp);
2137
0
                                cmd_getw(right.end.x, cbp);
2138
0
                                cmd_getw(right.end.y, cbp);
2139
0
                                cmd_getw(options, cbp);
2140
0
                                if (!(options & 4)) {
2141
0
                                    cmd_getw(ybot, cbp);
2142
0
                                    cmd_getw(ytop, cbp);
2143
0
                                } else
2144
0
                                    ytop = ybot = 0; /* Unused, but quiet gcc warning. */
2145
0
                                swap_axes = options & 1;
2146
0
                                wh = swap_axes ? tdev->width : tdev->height;
2147
0
                                x0f = int2fixed(swap_axes ? y0 : x0);
2148
0
                                y0f = int2fixed(swap_axes ? x0 : y0);
2149
0
                                left.start.x -= x0f;
2150
0
                                left.start.y -= y0f;
2151
0
                                left.end.x -= x0f;
2152
0
                                left.end.y -= y0f;
2153
0
                                right.start.x -= x0f;
2154
0
                                right.start.y -= y0f;
2155
0
                                right.end.x -= x0f;
2156
0
                                right.end.y -= y0f;
2157
0
                                if (options & 2) {
2158
0
                                    uchar num_components = tdev->color_info.num_components;
2159
0
                                    frac31 c[4][GX_DEVICE_COLOR_MAX_COMPONENTS], *cc[4];
2160
0
                                    byte colors_mask, i, j, m = 1;
2161
0
                                    gs_fill_attributes fa;
2162
0
                                    gs_fixed_rect clip;
2163
0
                                    fixed hh = int2fixed(swap_axes ? target->width : target->height);
2164
2165
0
                                    if (cbuf.end - cbp < 5 * cmd_max_intsize(sizeof(frac31))) {
2166
0
                                        code = top_up_cbuf(&cbuf, &cbp);
2167
0
                                        if (code < 0)
2168
0
                                            goto top_up_failed;
2169
0
                                    }
2170
0
                                    cmd_getw(clip.p.x, cbp);
2171
0
                                    cmd_getw(clip.p.y, cbp);
2172
0
                                    cmd_getw(clip.q.x, cbp);
2173
0
                                    cmd_getw(clip.q.y, cbp);
2174
0
                                    clip.p.x -= x0f;
2175
0
                                    clip.p.y -= y0f;
2176
0
                                    clip.q.x -= x0f;
2177
0
                                    clip.q.y -= y0f;
2178
0
                                    if (clip.p.y < 0)
2179
0
                                        clip.p.y = 0;
2180
0
                                    if (clip.q.y > hh)
2181
0
                                        clip.q.y = hh;
2182
0
                                    fa.clip = &clip;
2183
0
                                    fa.swap_axes = swap_axes;
2184
0
                                    fa.ht = NULL;
2185
0
                                    fa.lop = lop_default; /* fgixme: gs_gstate.log_op; */
2186
0
                                    fa.ystart = ybot - y0f;
2187
0
                                    fa.yend = ytop - y0f;
2188
0
                                    cmd_getw(colors_mask, cbp);
2189
0
                                    for (i = 0; i < 4; i++, m <<= 1) {
2190
0
                                        if (colors_mask & m) {
2191
0
                                            if (cbuf.end - cbp < num_components * cmd_max_intsize(sizeof(frac31))) {
2192
0
                                                code = top_up_cbuf(&cbuf, &cbp);
2193
0
                                                if (code < 0)
2194
0
                                                    goto top_up_failed;
2195
0
                                            }
2196
0
                                            cc[i] = c[i];
2197
0
                                            for (j = 0; j < num_components; j++)
2198
0
                                                cmd_getfrac(c[i][j], cbp);
2199
0
                                        } else
2200
0
                                            cc[i] = NULL;
2201
0
                                    }
2202
0
                                    if (options & 4) {
2203
0
#                                       if 1 /* Disable to debug gx_fill_triangle_small. */
2204
0
                                        code = dev_proc(ttdev, fill_linear_color_triangle)(ttdev, &fa,
2205
0
                                                        &left.start, &left.end, &right.start,
2206
0
                                                        cc[0], cc[1], cc[2]);
2207
#                                       else
2208
                                        code = 0;
2209
#                                       endif
2210
0
                                        if (code == 0) {
2211
                                            /* The target device didn't fill the trapezoid and
2212
                                               requests a decomposition. Subdivide into smaller triangles : */
2213
0
                                            if (pfs.dev == NULL)
2214
0
                                                code = gx_init_patch_fill_state_for_clist(tdev, &pfs, mem);
2215
0
                                            if (code >= 0) {
2216
0
                                                pfs.dev = ttdev;
2217
0
                                                pfs.rect = clip; /* fixme: eliminate 'clip'. */
2218
0
                                                fa.pfs = &pfs;
2219
0
                                                code = gx_fill_triangle_small(ttdev, &fa,
2220
0
                                                            &left.start, &left.end, &right.start,
2221
0
                                                            cc[0], cc[1], cc[2]);
2222
0
                                            }
2223
0
                                        }
2224
0
                                    } else {
2225
0
                                        code = dev_proc(ttdev, fill_linear_color_trapezoid)(ttdev, &fa,
2226
0
                                                        &left.start, &left.end, &right.start, &right.end,
2227
0
                                                        cc[0], cc[1], cc[2], cc[3]);
2228
0
                                        if (code == 0) {
2229
                                            /* Fixme : The target device didn't fill the trapezoid and
2230
                                               requests a decomposition.
2231
                                               Currently we never call it with 4 colors (see gxshade6.c)
2232
                                               and 2 colors must not return 0 - see comment to
2233
                                               dev_t_proc_fill_linear_color_trapezoid in gxdevcli.c .
2234
                                               Must not happen. */
2235
0
                                            code = gs_note_error(gs_error_unregistered);
2236
0
                                        }
2237
0
                                    }
2238
0
                                } else
2239
0
                                    code = gx_default_fill_trapezoid(ttdev, &left, &right,
2240
0
                                        max(ybot - y0f, fixed_half),
2241
0
                                        min(ytop - y0f, int2fixed(wh)), swap_axes,
2242
0
                                        &fill_color, gs_gstate.log_op);
2243
0
                            }
2244
0
                           break;
2245
0
                        default:
2246
0
                            goto bad_op;
2247
0
                    }
2248
0
                    if (ppath != &path)
2249
0
                        gx_path_free(ppath, "clist_render_band");
2250
0
                }
2251
0
                if (in_path) {  /* path might be empty! */
2252
0
                    state.rect.x = fixed2int_var(ppos.x);
2253
0
                    state.rect.y = fixed2int_var(ppos.y);
2254
0
                    in_path = false;
2255
0
                }
2256
0
                gx_path_free(&path, "clist_render_band");
2257
0
                gx_path_init_local(&path, mem);
2258
0
                if (code < 0)
2259
0
                    goto out;
2260
0
                continue;
2261
0
            default:
2262
0
              bad_op:mlprintf5(mem, "Bad op %02x band y0 = %d file pos %"PRId64" buf pos %d/%d\n",
2263
0
                 op, y0, stell(s), (int)(cbp - cbuf.data), (int)(cbuf.end - cbuf.data));
2264
0
                {
2265
0
                    const byte *pp;
2266
2267
0
                    for (pp = cbuf.data; pp < cbuf.end; pp += 10) {
2268
0
                        dmlprintf1(mem, "%4d:", (int)(pp - cbuf.data));
2269
0
                        dmprintf10(mem, " %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
2270
0
                                  pp[0], pp[1], pp[2], pp[3], pp[4],
2271
0
                                  pp[5], pp[6], pp[7], pp[8], pp[9]);
2272
0
                    }
2273
0
                }
2274
0
                code = gs_note_error(gs_error_Fatal);
2275
0
                goto out;
2276
0
        }
2277
0
        if_debug4m('L', mem, " x=%d y=%d w=%d h=%d\n",
2278
0
                  state.rect.x, state.rect.y, state.rect.width,
2279
0
                  state.rect.height);
2280
0
        switch (op >> 4) {
2281
0
            case cmd_op_fill_rect >> 4:
2282
0
                if (state.rect.width == 0 && state.rect.height == 0 &&
2283
0
                    state.rect.x == 0 && state.rect.y == 0) {
2284
                    /* FIXME: This test should be unnecessary. Bug 692076
2285
                     * is open pending a proper fix. */
2286
0
                    code = (dev_proc(tdev, fillpage) == NULL ? 0 :
2287
0
                            (*dev_proc(tdev, fillpage))(tdev, &gs_gstate,
2288
0
                                                        &fill_color));
2289
0
                    break;
2290
0
                }
2291
0
            case cmd_op_fill_rect_short >> 4:
2292
0
            case cmd_op_fill_rect_tiny >> 4:
2293
0
                if (!state.lop_enabled) {
2294
0
                    code = (*dev_proc(tdev, fill_rectangle))
2295
0
                        (tdev, state.rect.x - x0, state.rect.y - y0,
2296
0
                         state.rect.width, state.rect.height,
2297
0
                         state.colors[1]);
2298
0
                    break;
2299
0
                }
2300
0
                source = NULL;
2301
0
                data_x = 0;
2302
0
                raster = 0;
2303
0
                colors[0] = colors[1] = state.colors[1];
2304
0
                log_op = state.lop;
2305
0
                pcolor = colors;
2306
0
         do_rop:code = (*dev_proc(tdev, strip_copy_rop2))
2307
0
                                (tdev, source, data_x, raster, gx_no_bitmap_id,
2308
0
                                 pcolor, &state_tile,
2309
0
                                 (state.tile_colors[0] == gx_no_color_index &&
2310
0
                                  state.tile_colors[1] == gx_no_color_index ?
2311
0
                                  NULL : state.tile_colors),
2312
0
                                 state.rect.x - x0, state.rect.y - y0,
2313
0
                                 state.rect.width - data_x, state.rect.height,
2314
0
                                 tile_phase.x, tile_phase.y, log_op,
2315
0
                                 plane_height);
2316
0
                     plane_height = 0;
2317
0
                data_x = 0;
2318
0
                break;
2319
0
            case cmd_op_tile_rect >> 4:
2320
0
                if (state.rect.width == 0 && state.rect.height == 0 &&
2321
0
                    state.rect.x == 0 && state.rect.y == 0) {
2322
0
                    code = (*dev_proc(tdev, fillpage))(tdev, &gs_gstate, &fill_color);
2323
0
                    break;
2324
0
                }
2325
0
            case cmd_op_tile_rect_short >> 4:
2326
0
            case cmd_op_tile_rect_tiny >> 4:
2327
                /* Currently we don't use lop with strip_tile_rectangle. */
2328
0
                code = (*dev_proc(tdev, strip_tile_rectangle))
2329
0
                    (tdev, &state_tile,
2330
0
                     state.rect.x - x0, state.rect.y - y0,
2331
0
                     state.rect.width, state.rect.height,
2332
0
                     state.tile_colors[0], state.tile_colors[1],
2333
0
                     tile_phase.x, tile_phase.y);
2334
0
                break;
2335
0
            case cmd_op_copy_mono_planes >> 4:
2336
0
                if (state.lop_enabled) {
2337
0
                    pcolor = state.colors;
2338
0
                    log_op = state.lop;
2339
0
                    goto do_rop;
2340
0
                }
2341
0
                if ((op & cmd_copy_use_tile) || pcpath != NULL) {       /*
2342
                                                                         * This call of copy_mono originated as a call
2343
                                                                         * of fill_mask.
2344
                                                                         */
2345
0
                    code = gx_image_fill_masked
2346
0
                        (tdev, source, data_x, raster, gx_no_bitmap_id,
2347
0
                         state.rect.x - x0, state.rect.y - y0,
2348
0
                         state.rect.width - data_x, state.rect.height,
2349
0
                         &fill_color, 1, gs_gstate.log_op, pcpath);
2350
0
                } else {
2351
0
                    if (plane_height == 0) {
2352
0
                        code = (*dev_proc(tdev, copy_mono))
2353
0
                             (tdev, source, data_x, raster, gx_no_bitmap_id,
2354
0
                              state.rect.x - x0, state.rect.y - y0,
2355
0
                              state.rect.width - data_x, state.rect.height,
2356
0
                              state.colors[0], state.colors[1]);
2357
0
                    } else {
2358
0
                        code = (*dev_proc(tdev, copy_planes))
2359
0
                             (tdev, source, data_x, raster, gx_no_bitmap_id,
2360
0
                              state.rect.x - x0, state.rect.y - y0,
2361
0
                              state.rect.width - data_x, state.rect.height,
2362
0
                              plane_height);
2363
0
                    }
2364
0
                }
2365
0
                plane_height = 0;
2366
0
                data_x = 0;
2367
0
                break;
2368
0
            case cmd_op_copy_color_alpha >> 4:
2369
0
                if (state.color_is_alpha) {
2370
/****** CAN'T DO ROP WITH ALPHA ******/
2371
0
                    if (state.color_is_devn &&
2372
0
                        dev_proc(tdev, copy_alpha_hl_color) != gx_default_no_copy_alpha_hl_color) { /* FIXME */
2373
0
                        code = (*dev_proc(tdev, copy_alpha_hl_color))
2374
0
                            (tdev, source, data_x, raster, gx_no_bitmap_id,
2375
0
                             state.rect.x - x0, state.rect.y - y0,
2376
0
                             state.rect.width - data_x, state.rect.height,
2377
0
                             &fill_color, depth);
2378
0
                    } else {
2379
0
                        code = (*dev_proc(tdev, copy_alpha))
2380
0
                            (tdev, source, data_x, raster, gx_no_bitmap_id,
2381
0
                             state.rect.x - x0, state.rect.y - y0,
2382
0
                             state.rect.width - data_x, state.rect.height,
2383
0
                             state.colors[1], depth);
2384
0
                    }
2385
0
                } else {
2386
0
                    if (state.lop_enabled) {
2387
0
                        pcolor = NULL;
2388
0
                        log_op = state.lop;
2389
0
                        goto do_rop;
2390
0
                    }
2391
0
                    code = (*dev_proc(tdev, copy_color))
2392
0
                        (tdev, source, data_x, raster, gx_no_bitmap_id,
2393
0
                         state.rect.x - x0, state.rect.y - y0,
2394
0
                         state.rect.width - data_x, state.rect.height);
2395
0
                }
2396
0
                data_x = 0;
2397
0
                break;
2398
0
            default:            /* can't happen */
2399
0
                goto bad_op;
2400
0
        }
2401
0
    }
2402
    /* Clean up before we exit. */
2403
0
  out:
2404
0
    if (ht_buff.pbuff != 0) {
2405
0
        gs_free_object(mem, ht_buff.pbuff, "clist_playback_band(ht_buff)");
2406
0
        ht_buff.pbuff = 0;
2407
0
        ht_buff.pcurr = 0;
2408
0
    }
2409
0
    ht_buff.ht_size = 0;
2410
0
    ht_buff.read_size = 0;
2411
2412
0
    if (pcomp_last != NULL) {
2413
0
        int code1 = drop_compositor_queue(&pcomp_first, &pcomp_last, NULL, mem, x0, y0, &gs_gstate);
2414
2415
0
        if (code == 0)
2416
0
            code = code1;
2417
0
    }
2418
0
    gx_cpath_free(&clip_path, "clist_render_band exit");
2419
0
    gx_path_free(&path, "clist_render_band exit");
2420
0
    if (gs_gstate.pattern_cache != NULL) {
2421
0
        gx_pattern_cache_free(gs_gstate.pattern_cache);
2422
0
        gs_gstate.pattern_cache = NULL;
2423
0
    }
2424
    /* Free the client color and device colors allocated upon entry */
2425
0
    gs_free_object(mem, gs_gstate.color[0].ccolor, "clist_playback_band");
2426
0
    gs_free_object(mem, gs_gstate.color[1].ccolor, "clist_playback_band");
2427
0
    gs_free_object(mem, gs_gstate.color[0].dev_color, "clist_playback_band");
2428
0
    gs_free_object(mem, gs_gstate.color[1].dev_color, "clist_playback_band");
2429
0
    gs_gstate.color[0].ccolor = gs_gstate.color[1].ccolor = NULL;
2430
0
    gs_gstate.color[0].dev_color = gs_gstate.color[1].dev_color = NULL;
2431
2432
    /* The imager state release will decrement the icc link cache.  To avoid
2433
       race conditions lock the cache */
2434
0
    gx_monitor_enter(cdev->icc_cache_cl->lock);
2435
0
    gs_gstate_release(&gs_gstate);
2436
0
    gx_monitor_leave(cdev->icc_cache_cl->lock); /* done with increment, let everyone run */
2437
0
    gs_free_object(mem, data_bits, "clist_playback_band(data_bits)");
2438
0
    if (target != orig_target) {
2439
0
        if (target->rc.ref_count != 1) {
2440
            /* This can occur if we are coming from a pattern clist that
2441
               includes transparency.  In this case, we do not want to
2442
               free the compositor since it is really the main target that
2443
               we are tiling into.  i.e. the tile itself does not have
2444
               a pdf14 device, but rather we push a trans group, draw and
2445
               then pop the group to properly blend */
2446
0
            rc_decrement(target, "gxclrast(target compositor)");
2447
0
        } else {
2448
            /* Ref count was 1. close the device and then free it */
2449
0
            if (target->is_open)
2450
0
                dev_proc(target, close_device)(target);
2451
0
            gs_free_object(target->memory, target, "gxclrast discard compositor");
2452
0
        }
2453
0
        target = orig_target;
2454
0
    }
2455
0
    if (code < 0) {
2456
0
        if (pfs.dev != NULL)
2457
0
            term_patch_fill_state(&pfs);
2458
0
        rc_decrement(gs_gstate.color[0].color_space, "clist_playback_band");
2459
0
        rc_decrement(gs_gstate.color[1].color_space, "clist_playback_band");
2460
0
        gs_free_object(mem, cbuf_storage, "clist_playback_band(cbuf_storage)");
2461
0
        gx_cpath_free(&clip_path, "clist_playback_band");
2462
0
        if (pcpath != &clip_path)
2463
0
            gx_cpath_free(pcpath, "clist_playback_band");
2464
0
        if (clipper_dev_open)
2465
0
            gx_destroy_clip_device_on_stack(&clipper_dev);
2466
0
        return_error(code);
2467
0
    }
2468
    /* Check whether we have more pages to process. */
2469
0
    if ((playback_action != playback_action_setup &&
2470
0
        (cbp < cbuf.end || !seofp(s)) && (op != cmd_opv_end_page) )
2471
0
        )
2472
0
        goto in;
2473
0
    if (pfs.dev != NULL)
2474
0
        term_patch_fill_state(&pfs);
2475
0
    rc_decrement(gs_gstate.color[0].color_space, "clist_playback_band");
2476
0
    rc_decrement(gs_gstate.color[1].color_space, "clist_playback_band");
2477
0
    gs_free_object(mem, cbuf_storage, "clist_playback_band(cbuf_storage)");
2478
0
    gx_cpath_free(&clip_path, "clist_playback_band");
2479
0
    if (pcpath != &clip_path)
2480
0
        gx_cpath_free(pcpath, "clist_playback_band");
2481
0
    if (clipper_dev_open)
2482
0
        gx_destroy_clip_device_on_stack(&clipper_dev);
2483
0
    return code;
2484
0
top_up_failed:
2485
0
    gx_cpath_free(&clip_path, "clist_playback_band");
2486
0
    if (pcpath != &clip_path)
2487
0
        gx_cpath_free(pcpath, "clist_playback_band");
2488
0
    if (clipper_dev_open)
2489
0
        gx_destroy_clip_device_on_stack(&clipper_dev);
2490
0
    return code;
2491
0
}
2492
2493
/* ---------------- Individual commands ---------------- */
2494
2495
/*
2496
 * These single-use procedures implement a few large individual commands,
2497
 * primarily for readability but also to avoid overflowing compilers'
2498
 * optimization limits.  They all take the command buffer as their first
2499
 * parameter (pcb), assume that the current buffer pointer is in pcb->ptr,
2500
 * and update it there.
2501
 */
2502
2503
static int
2504
read_set_tile_size(command_buf_t *pcb, tile_slot *bits, bool for_pattern)
2505
0
{
2506
0
    const byte *cbp = pcb->ptr;
2507
0
    uint rep_width, rep_height;
2508
0
    uint pdepth;
2509
0
    byte bd = *cbp++;
2510
2511
0
    bits->head.depth = cmd_code_to_depth(bd);
2512
0
    if (for_pattern)
2513
0
        cmd_getw(bits->id, cbp);
2514
0
    cmd_getw(rep_width, cbp);
2515
0
    cmd_getw(rep_height, cbp);
2516
0
    if (bd & 0x20) {
2517
0
        cmd_getw(bits->x_reps, cbp);
2518
0
        bits->width = rep_width * bits->x_reps;
2519
0
    } else {
2520
0
        bits->x_reps = 1;
2521
0
        bits->width = rep_width;
2522
0
    }
2523
0
    if (bd & 0x40) {
2524
0
        cmd_getw(bits->y_reps, cbp);
2525
0
        bits->height = rep_height * bits->y_reps;
2526
0
    } else {
2527
0
        bits->y_reps = 1;
2528
0
        bits->height = rep_height;
2529
0
    }
2530
0
    if (bd & 0x80)
2531
0
        cmd_getw(bits->rep_shift, cbp);
2532
0
    else
2533
0
        bits->rep_shift = 0;
2534
0
    if (bd & 0x10)
2535
0
        bits->num_planes = *cbp++;
2536
0
    else
2537
0
        bits->num_planes = 1;
2538
0
    if_debug7('L', " depth=%d size=(%d,%d), rep_size=(%d,%d), rep_shift=%d, num_planes=%d\n",
2539
0
              bits->head.depth, bits->width,
2540
0
              bits->height, rep_width,
2541
0
              rep_height, bits->rep_shift, bits->num_planes);
2542
0
    bits->shift =
2543
0
        (bits->rep_shift == 0 ? 0 :
2544
0
         (bits->rep_shift * (bits->height / rep_height)) % rep_width);
2545
0
    pdepth = bits->head.depth;
2546
0
    if (bits->num_planes != 1)
2547
0
        pdepth /= bits->num_planes;
2548
0
    bits->raster = bitmap_raster(bits->width * pdepth);
2549
0
    pcb->ptr = cbp;
2550
0
    return 0;
2551
0
}
2552
2553
static int
2554
read_set_bits(command_buf_t *pcb, tile_slot *bits, int compress,
2555
              gx_clist_state *pcls, gx_strip_bitmap *tile, tile_slot **pslot,
2556
              gx_device_clist_reader *cdev, gs_memory_t *mem)
2557
0
{
2558
0
    const byte *cbp = pcb->ptr;
2559
0
    uint rep_width = bits->width / bits->x_reps;
2560
0
    uint rep_height = bits->height / bits->y_reps;
2561
0
    uint index;
2562
0
    ulong offset;
2563
0
    uint width_bits;
2564
0
    uint width_bytes;
2565
0
    uint raster;
2566
0
    uint bytes;
2567
0
    byte *data;
2568
0
    tile_slot *slot;
2569
0
    uint depth = bits->head.depth;
2570
2571
0
    if (bits->num_planes != 1)
2572
0
        depth /= bits->num_planes;
2573
0
    width_bits = rep_width * depth;
2574
2575
0
    bytes = clist_bitmap_bytes(width_bits, rep_height * bits->num_planes,
2576
0
                               compress |
2577
0
                               (rep_width < bits->width ?
2578
0
                                decompress_spread : 0) |
2579
0
                               decompress_elsewhere,
2580
0
                               &width_bytes,
2581
0
                               (uint *)&raster);
2582
2583
0
    cmd_getw(index, cbp);
2584
0
    cmd_getw(offset, cbp);
2585
0
    if_debug2m('L', mem, " index=%d offset=%lu\n", index, offset);
2586
0
    pcls->tile_index = index;
2587
0
    cdev->tile_table[pcls->tile_index].offset = offset;
2588
0
    slot = (tile_slot *)(cdev->cache_chunk->data + offset);
2589
0
    *pslot = slot;
2590
0
    *slot = *bits;
2591
0
    tile->data = data = (byte *)(slot + 1);
2592
#ifdef DEBUG
2593
    slot->index = pcls->tile_index;
2594
#endif
2595
0
    if (compress == cmd_compress_const) {
2596
0
        cbp = cmd_read_data(pcb, data, 1, cbp);
2597
0
        if (width_bytes > 0 && rep_height > 0)
2598
0
            memset(data+1, *data, width_bytes * rep_height - 1);
2599
0
    } else if (compress) {
2600
        /*
2601
         * Decompress the image data.  We'd like to share this code with the
2602
         * similar code in copy_*, but right now we don't see how.
2603
         */
2604
0
        stream_cursor_read r;
2605
0
        stream_cursor_write w;
2606
        /*
2607
         * We don't know the data length a priori, so to be conservative, we
2608
         * read the uncompressed size.
2609
         */
2610
0
        uint cleft = pcb->end - cbp;
2611
2612
0
        if (cleft < bytes && !pcb->end_status) {
2613
0
            uint nread = cbuf_size - cleft;
2614
2615
0
            advance_buffer(pcb, cbp);
2616
0
            pcb->end_status = sgets(pcb->s, pcb->data + cleft, nread, &nread);
2617
0
            set_cb_end(pcb, pcb->data + cleft + nread);
2618
0
            cbp = pcb->data;
2619
0
        }
2620
0
        r.ptr = cbp - 1;
2621
0
        r.limit = pcb->end - 1;
2622
0
        w.ptr = data - 1;
2623
0
        w.limit = w.ptr + bytes;
2624
0
        switch (compress) {
2625
0
        case cmd_compress_rle:
2626
0
            {
2627
0
                stream_RLD_state sstate;
2628
2629
0
                clist_rld_init(&sstate);
2630
0
                (*s_RLD_template.process)
2631
0
                    ((stream_state *)&sstate, &r, &w, true);
2632
0
            }
2633
0
            break;
2634
0
        case cmd_compress_cfe:
2635
0
            {
2636
0
                stream_CFD_state sstate;
2637
2638
0
                clist_cfd_init(&sstate,
2639
0
                               width_bytes << 3 /*width_bits */ ,
2640
0
                               rep_height, mem);
2641
0
                (*s_CFD_template.process)
2642
0
                    ((stream_state *)&sstate, &r, &w, true);
2643
0
                (*s_CFD_template.release)
2644
0
                    ((stream_state *)&sstate);
2645
0
            }
2646
0
            break;
2647
0
        default:
2648
0
            return_error(gs_error_unregistered);
2649
0
        }
2650
0
        cbp = r.ptr + 1;
2651
0
    } else if (rep_height * bits->num_planes > 1 && width_bytes != bits->raster) {
2652
0
        cbp = cmd_read_short_bits(pcb, data, bytes,
2653
0
                                  width_bytes, rep_height * bits->num_planes,
2654
0
                                  bits->raster, cbp);
2655
0
    } else {
2656
0
        cbp = cmd_read_data(pcb, data, bytes, cbp);
2657
0
    }
2658
0
    if (bits->width > rep_width)
2659
0
        bits_replicate_horizontally(data,
2660
0
                                    rep_width * depth, rep_height * bits->num_planes,
2661
0
                                    bits->raster,
2662
0
                                    bits->width * depth,
2663
0
                                    bits->raster);
2664
0
    if (bits->height > rep_height)
2665
0
        bits_replicate_vertically(data,
2666
0
                                  rep_height, bits->raster,
2667
0
                                  bits->height);
2668
#ifdef DEBUG
2669
    if (gs_debug_c('L'))
2670
        cmd_print_bits(mem, data, bits->width, bits->height, bits->raster);
2671
#endif
2672
0
    pcb->ptr = cbp;
2673
0
    return 0;
2674
0
}
2675
2676
/* if necessary, allocate a buffer to hold a serialized halftone */
2677
static int
2678
read_alloc_ht_buff(ht_buff_t * pht_buff, uint ht_size, gs_memory_t * mem)
2679
0
{
2680
    /* free the existing buffer, if any (usually none) */
2681
0
    if (pht_buff->pbuff != 0) {
2682
0
        gs_free_object(mem, pht_buff->pbuff, "read_alloc_ht_buff");
2683
0
        pht_buff->pbuff = 0;
2684
0
    }
2685
2686
    /*
2687
     * If the serialized halftone fits in the command buffer, no
2688
     * additional buffer is required.
2689
     */
2690
0
    if (ht_size > cbuf_ht_seg_max_size) {
2691
0
        pht_buff->pbuff = gs_alloc_bytes(mem, ht_size, "read_alloc_ht_buff");
2692
0
        if (pht_buff->pbuff == 0)
2693
0
            return_error(gs_error_VMerror);
2694
0
    }
2695
0
    pht_buff->ht_size = ht_size;
2696
0
    pht_buff->read_size = 0;
2697
0
    pht_buff->pcurr = pht_buff->pbuff;
2698
0
    return 0;
2699
0
}
2700
2701
/* read a halftone segment; if it is the final segment, build the halftone */
2702
static int
2703
read_ht_segment(
2704
    ht_buff_t *                 pht_buff,
2705
    command_buf_t *             pcb,
2706
    gs_gstate *           pgs,
2707
    gx_device *                 dev,
2708
    gs_memory_t *               mem )
2709
0
{
2710
0
    const byte *                cbp = pcb->ptr;
2711
0
    const byte *                pbuff = 0;
2712
0
    uint                        ht_size = pht_buff->ht_size, seg_size;
2713
0
    int                         code = 0;
2714
2715
    /* get the segment size; refill command buffer if necessary */
2716
0
    enc_u_getw(seg_size, cbp);
2717
0
    if (pcb->warn_limit - cbp < (int)seg_size) { /* cbp can be past warn_limit */
2718
0
        code = top_up_cbuf(pcb, &cbp);
2719
0
        if (code < 0)
2720
0
            return code;
2721
0
        if (pcb->end - cbp < (int)seg_size) {
2722
0
            emprintf(mem, " *** ht segment size doesn't fit in buffer ***\n");
2723
0
            return_error(gs_error_unknownerror);
2724
0
        }
2725
0
    }
2726
2727
0
    if (pht_buff->pbuff == 0) {
2728
        /* if not separate buffer, must be only one segment */
2729
0
        if (seg_size != ht_size)
2730
0
            return_error(gs_error_unknownerror);
2731
0
        pbuff = cbp;
2732
0
    } else {
2733
0
        if (seg_size + pht_buff->read_size > pht_buff->ht_size)
2734
0
            return_error(gs_error_unknownerror);
2735
0
        memcpy(pht_buff->pcurr, cbp, seg_size);
2736
0
        pht_buff->pcurr += seg_size;
2737
0
        if ((pht_buff->read_size += seg_size) == ht_size)
2738
0
            pbuff = pht_buff->pbuff;
2739
0
    }
2740
2741
    /* if everything has been read, convert back to a halftone */
2742
0
    if (pbuff != 0) {
2743
0
        code = gx_ht_read_and_install(pgs, dev, pbuff, ht_size, mem);
2744
2745
        /* release any buffered information */
2746
0
        if (pht_buff->pbuff != 0) {
2747
0
            gs_free_object(mem, pht_buff->pbuff, "read_alloc_ht_buff");
2748
0
            pht_buff->pbuff = 0;
2749
0
            pht_buff->pcurr = 0;
2750
0
        }
2751
0
        pht_buff->ht_size = 0;
2752
0
        pht_buff->read_size = 0;
2753
0
    }
2754
2755
    /* update the command buffer ponter */
2756
0
    pcb->ptr = cbp + seg_size;
2757
2758
0
    return code;
2759
0
}
2760
2761
static int
2762
read_set_misc2(command_buf_t *pcb, gs_gstate *pgs, segment_notes *pnotes)
2763
0
{
2764
0
    const byte *cbp = pcb->ptr;
2765
0
    uint mask, cb;
2766
2767
0
    if_debug0m('L', pgs->memory, "\n");
2768
0
    cmd_getw(mask, cbp);
2769
0
    if (mask & cap_join_known) {
2770
0
        cb = *cbp++;
2771
0
        pgs->line_params.start_cap = (gs_line_cap)((cb >> 3) & 7);
2772
0
        pgs->line_params.join = (gs_line_join)(cb & 7);
2773
0
        if_debug2m('L', pgs->memory, "[L]      start_cap=%d join=%d\n",
2774
0
                   pgs->line_params.start_cap, pgs->line_params.join);
2775
0
        cb = *cbp++;
2776
0
        pgs->line_params.end_cap = (gs_line_cap)((cb >> 3) & 7);
2777
0
        pgs->line_params.dash_cap = (gs_line_cap)(cb & 7);
2778
0
        if_debug2m('L', pgs->memory, "[L]      end_cap=%d dash_cap=%d\n",
2779
0
                   pgs->line_params.end_cap, pgs->line_params.dash_cap);
2780
0
    }
2781
0
    if (mask & cj_ac_sa_known) {
2782
0
        cb = *cbp++;
2783
0
        pgs->line_params.curve_join = ((cb >> 2) & 7) - 1;
2784
0
        pgs->accurate_curves = (cb & 2) != 0;
2785
0
        pgs->stroke_adjust = cb & 1;
2786
0
        if_debug3m('L', pgs->memory, "[L]      CJ=%d AC=%d SA=%d\n",
2787
0
                   pgs->line_params.curve_join, pgs->accurate_curves,
2788
0
                   pgs->stroke_adjust);
2789
0
    }
2790
0
    if (mask & flatness_known) {
2791
0
        cmd_get_value(pgs->flatness, cbp);
2792
0
        if_debug1m('L', pgs->memory, "[L]      flatness=%g\n", pgs->flatness);
2793
0
    }
2794
0
    if (mask & line_width_known) {
2795
0
        float width;
2796
2797
0
        cmd_get_value(width, cbp);
2798
0
        if_debug1m('L', pgs->memory, "[L]      line_width=%g\n", width);
2799
0
        gx_set_line_width(&pgs->line_params, width);
2800
0
    }
2801
0
    if (mask & miter_limit_known) {
2802
0
        float limit;
2803
2804
0
        cmd_get_value(limit, cbp);
2805
0
        if_debug1m('L', pgs->memory, "[L]      miter_limit=%g\n", limit);
2806
0
        gx_set_miter_limit(&pgs->line_params, limit);
2807
0
    }
2808
0
    if (mask & op_bm_tk_known) {
2809
0
        cb = *cbp++;
2810
0
        pgs->blend_mode = cb >> 3;
2811
0
        pgs->text_knockout = cb & 1;
2812
        /* the following usually have no effect; see gxclpath.c */
2813
0
        cb = *cbp++;
2814
0
        pgs->overprint_mode = (cb >> 2) & 1;
2815
0
        pgs->stroke_overprint = (cb >> 1) & 1;
2816
0
        pgs->overprint = cb & 1;
2817
0
        cb = *cbp++;
2818
0
        pgs->renderingintent = cb;
2819
0
        if_debug6m('L', pgs->memory, "[L]      BM=%d TK=%d OPM=%d OP=%d op=%d RI=%d\n",
2820
0
                   pgs->blend_mode, pgs->text_knockout, pgs->overprint_mode,
2821
0
                   pgs->stroke_overprint, pgs->overprint, pgs->renderingintent);
2822
0
    }
2823
0
    if (mask & segment_notes_known) {
2824
0
        cb = *cbp++;
2825
0
        *pnotes = (segment_notes)(cb & 0x3f);
2826
0
        if_debug1m('L', pgs->memory, "[L]      notes=%d\n", *pnotes);
2827
0
    }
2828
0
    if (mask & ais_known) {
2829
0
        cmd_get_value(pgs->alphaisshape, cbp);
2830
0
        if_debug1m('L', pgs->memory, "[L]      alphaisshape=%d\n", pgs->alphaisshape);
2831
0
    }
2832
0
    if (mask & stroke_alpha_known) {
2833
0
        cmd_get_value(pgs->strokeconstantalpha, cbp);
2834
0
        if_debug1m('L', pgs->memory, "[L]      strokeconstantalpha=%g\n", pgs->strokeconstantalpha);
2835
0
    }
2836
0
    if (mask & fill_alpha_known) {
2837
0
        cmd_get_value(pgs->fillconstantalpha, cbp);
2838
0
        if_debug1m('L', pgs->memory, "[L]      fillconstantalpha=%u\n", (uint)(pgs->fillconstantalpha));
2839
0
    }
2840
0
    pcb->ptr = cbp;
2841
0
    return 0;
2842
0
}
2843
2844
static int
2845
read_set_color_space(command_buf_t *pcb, gs_gstate *pgs,
2846
                     gx_device_clist_reader *cdev, gs_memory_t *mem)
2847
0
{
2848
0
    const byte *cbp = pcb->ptr;
2849
0
    byte b = *cbp++;
2850
0
    int index = b >> 4;
2851
0
    gs_color_space *pcs;
2852
0
    int code = 0;
2853
0
    cmm_profile_t *picc_profile;
2854
0
    clist_icc_color_t icc_information;
2855
2856
0
    if_debug3m('L', mem, " %d%s%s\n", index,
2857
0
               (b & 8 ? " (indexed)" : ""),
2858
0
               (b & 4 ? "(proc)" : ""));
2859
    /* They all store the ICC information.  Even if it is NULL
2860
       it is used in the ICC case to avoid reading from the
2861
       serialized profile data which is stored elsewhere in the
2862
       clist.  Hence we avoid jumping around in the file. */
2863
0
    memcpy(&icc_information, cbp, sizeof(clist_icc_color_t));
2864
0
    cbp = cbp + sizeof(clist_icc_color_t);
2865
0
    switch (index) {
2866
0
    case gs_color_space_index_DeviceGray:
2867
0
        pcs = gs_cspace_new_DeviceGray(mem);
2868
0
        break;
2869
0
    case gs_color_space_index_DeviceRGB:
2870
0
        pcs = gs_cspace_new_DeviceRGB(mem);
2871
0
        break;
2872
0
    case gs_color_space_index_DeviceCMYK:
2873
0
        pcs = gs_cspace_new_DeviceCMYK(mem);
2874
0
        break;
2875
0
    case gs_color_space_index_ICC:
2876
        /* build the color space object */
2877
0
        code = gs_cspace_build_ICC(&pcs, NULL, mem);
2878
        /* Don't bother getting the ICC stuff from the clist yet */
2879
0
        picc_profile = gsicc_profile_new(NULL, cdev->memory, NULL, 0);
2880
0
        if (picc_profile == NULL)
2881
0
            return gs_rethrow(-1, "Failed to find ICC profile during clist read");
2882
0
        picc_profile->num_comps = icc_information.icc_num_components;
2883
0
        picc_profile->hashcode = icc_information.icc_hash;
2884
0
        picc_profile->hash_is_valid = true;
2885
0
        picc_profile->islab = icc_information.is_lab;
2886
0
        picc_profile->default_match = icc_information.default_match;
2887
0
        picc_profile->data_cs = icc_information.data_cs;
2888
        /* Store the clist reader address in the profile
2889
           structure so that we can get to the buffer
2890
           data if we really neeed it.  Ideally, we
2891
           will use a cached link and only access this once. */
2892
0
        picc_profile->dev = (gx_device*) cdev;
2893
        /* Assign it to the colorspace */
2894
0
        code = gsicc_set_gscs_profile(pcs, picc_profile, mem);
2895
        /* And we no longer need our reference to the profile */
2896
0
        gsicc_adjust_profile_rc(picc_profile, -1, "read_set_color_space");
2897
0
        break;
2898
0
    default:
2899
0
        code = gs_note_error(gs_error_rangecheck);      /* others are NYI */
2900
0
        goto out;
2901
0
    }
2902
2903
0
    if (pcs == NULL) {
2904
0
        code = gs_note_error(gs_error_VMerror);
2905
0
        goto out;
2906
0
    }
2907
2908
0
    if (b & 8) {
2909
0
        bool use_proc = (b & 4) != 0;
2910
0
        int hival;
2911
0
        int num_values;
2912
0
        byte *data;
2913
0
        uint data_size;
2914
0
        gs_color_space *pcs_indexed;
2915
2916
0
        pcs_indexed = gs_cspace_alloc(mem, &gs_color_space_type_Indexed);
2917
0
        if (pcs_indexed == 0) {
2918
0
            rc_decrement_cs(pcs, "read_set_color_space");
2919
0
            code = gs_note_error(gs_error_VMerror);
2920
0
            goto out;
2921
0
        }
2922
0
        pcs_indexed->base_space = pcs;
2923
0
        pcs = pcs_indexed;
2924
0
        pcs->params.indexed.use_proc = 0;
2925
0
        pcs->params.indexed.lookup.table.data = 0;
2926
0
        pcs->params.indexed.lookup.table.size = 0;
2927
0
        cmd_getw(hival, cbp);
2928
0
        pcs->params.indexed.n_comps = gs_color_space_num_components(pcs->base_space);
2929
0
        num_values = (hival + 1) * pcs->params.indexed.n_comps;
2930
0
        if (use_proc) {
2931
0
            gs_indexed_map *map;
2932
2933
0
            code = alloc_indexed_map(&map, num_values, mem, "indexed map");
2934
0
            if (code < 0) {
2935
0
                rc_decrement_cs(pcs, "read_set_color_space");
2936
0
                goto out;
2937
0
            }
2938
0
            map->proc.lookup_index = lookup_indexed_map;
2939
0
            pcs->params.indexed.lookup.map = map;
2940
0
            data = (byte *)map->values;
2941
0
            data_size = num_values * sizeof(map->values[0]);
2942
0
        } else {
2943
0
            byte *table = gs_alloc_string(mem, num_values, "color_space indexed table");
2944
2945
0
            if (table == 0) {
2946
0
                code = gs_note_error(gs_error_VMerror);
2947
0
                rc_decrement_cs(pcs, "read_set_color_space");
2948
0
                goto out;
2949
0
            }
2950
0
            pcs->params.indexed.lookup.table.data = table;
2951
0
            pcs->params.indexed.lookup.table.size = num_values;
2952
0
            data = table;
2953
0
            data_size = num_values;
2954
0
        }
2955
0
        cbp = cmd_read_data(pcb, data, data_size, cbp);
2956
0
        pcs->params.indexed.hival = hival;
2957
0
        pcs->params.indexed.use_proc = use_proc;
2958
0
    }
2959
2960
    /* Release reference to old color space before installing new one. */
2961
0
    if (pgs->color[0].color_space != NULL)
2962
0
        rc_decrement_only_cs(pgs->color[0].color_space, "read_set_color_space");
2963
0
    pgs->color[0].color_space = pcs;
2964
0
out:
2965
0
    pcb->ptr = cbp;
2966
0
    return code;
2967
0
}
2968
2969
static int
2970
read_begin_image(command_buf_t *pcb, gs_image_common_t *pic,
2971
                 gs_color_space *pcs)
2972
0
{
2973
0
    uint index = *(pcb->ptr)++;
2974
0
    const gx_image_type_t *image_type = gx_image_type_table[index];
2975
0
    stream s;
2976
0
    int code;
2977
2978
    /* This is sloppy, but we don't have enough information to do better. */
2979
0
    code = top_up_cbuf(pcb, &pcb->ptr);
2980
0
    if (code < 0)
2981
0
        return code;
2982
0
    s_init(&s, NULL);
2983
0
    sread_string(&s, pcb->ptr, pcb->end - pcb->ptr);
2984
0
    code = image_type->sget(pic, &s, pcs);
2985
0
    pcb->ptr = sbufptr(&s);
2986
0
    pic->imagematrices_are_untrustworthy = 0;
2987
0
    return code;
2988
0
}
2989
2990
static int
2991
read_put_params(command_buf_t *pcb, gs_gstate *pgs,
2992
                gx_device_clist_reader *cdev, gs_memory_t *mem)
2993
0
{
2994
0
    const byte *cbp = pcb->ptr;
2995
0
    gs_c_param_list param_list;
2996
0
    uint cleft;
2997
0
    uint rleft;
2998
0
    bool alloc_data_on_heap = false;
2999
0
    byte *param_buf;
3000
0
    uint param_length;
3001
0
    int code;
3002
3003
0
    cmd_get_value(param_length, cbp);
3004
0
    if_debug1m('L', mem, " length=%d\n", param_length);
3005
0
    if (param_length == 0) {
3006
0
        code = 1;               /* empty list */
3007
0
        goto out;
3008
0
    }
3009
3010
    /* Make sure entire serialized param list is in cbuf */
3011
    /* + force void* alignment */
3012
0
    code = top_up_cbuf(pcb, &cbp);
3013
0
    if (code < 0)
3014
0
        return code;
3015
0
    if (pcb->end - cbp >= param_length) {
3016
0
        param_buf = (byte *)cbp;
3017
0
        cbp += param_length;
3018
0
    } else {
3019
        /* NOTE: param_buf must be maximally aligned */
3020
0
        param_buf = gs_alloc_bytes(mem, param_length,
3021
0
                                   "clist put_params");
3022
0
        if (param_buf == 0) {
3023
0
            code = gs_note_error(gs_error_VMerror);
3024
0
            goto out;
3025
0
        }
3026
0
        alloc_data_on_heap = true;
3027
0
        cleft = pcb->end - cbp;
3028
0
        rleft = param_length - cleft;
3029
0
        memmove(param_buf, cbp, cleft);
3030
0
        next_is_skip(pcb);
3031
0
        pcb->end_status = sgets(pcb->s, param_buf + cleft, rleft, &rleft);
3032
0
        cbp = pcb->end;  /* force refill */
3033
0
    }
3034
3035
    /*
3036
     * Create a gs_c_param_list & expand into it.
3037
     * NB that gs_c_param_list doesn't copy objects into
3038
     * it, but rather keeps *pointers* to what's passed.
3039
     * That's OK because the serialized format keeps enough
3040
     * space to hold expanded versions of the structures,
3041
     * but this means we cannot deallocate source buffer
3042
     * until the gs_c_param_list is deleted.
3043
     */
3044
0
    gs_c_param_list_write(&param_list, mem);
3045
0
    code = gs_param_list_unserialize
3046
0
        ( (gs_param_list *)&param_list, param_buf );
3047
0
    if (code >= 0 && code != param_length)
3048
0
        code = gs_error_unknownerror;  /* must match */
3049
0
    if (code >= 0) {
3050
0
        gs_c_param_list_read(&param_list);
3051
0
        code = gs_gstate_putdeviceparams(pgs, (gx_device *)cdev,
3052
0
                                         (gs_param_list *)&param_list);
3053
0
    }
3054
0
    gs_c_param_list_release(&param_list);
3055
0
    if (alloc_data_on_heap)
3056
0
        gs_free_object(mem, param_buf, "clist put_params");
3057
3058
0
out:
3059
0
    pcb->ptr = cbp;
3060
0
    return code;
3061
0
}
3062
3063
/*
3064
 * Read a "composite" command, and execute the command.
3065
 *
3066
 * This code assumes that a the largest create compositor command,
3067
 * including the compositor name size, is smaller than the data buffer
3068
 * size. This assumption is inherent in the basic design of the coding
3069
 * and the de-serializer interface, as no length field is provided.
3070
 *
3071
 * At the time of this writing, no compositor violates this assumption.
3072
 * The largest composite is currently 1275 bytes, while the command
3073
 * data buffer is 4096 bytes.
3074
 *
3075
 * In the event that this assumption is violated, a change in the encoding
3076
 * would be called for.
3077
 *
3078
 * See comment in gdevp14.c c_pdf14trans_read PDF14_BEGIN_TRANS_MASK case.
3079
 */
3080
extern_gs_find_compositor();
3081
3082
static int
3083
read_composite(
3084
    command_buf_t *pcb,  gs_memory_t *mem, gs_composite_t **ppcomp)
3085
0
{
3086
0
    const byte *                cbp = pcb->ptr;
3087
0
    int                         comp_id = 0, code = 0;
3088
0
    const gs_composite_type_t * pcomp_type = 0;
3089
3090
    /* fill the command buffer (see comment above) */
3091
0
    if (pcb->end - cbp < MAX_CLIST_COMPOSITOR_SIZE + sizeof(comp_id)) {
3092
0
        code = top_up_cbuf(pcb, &cbp);
3093
0
        if (code < 0)
3094
0
            return code;
3095
0
    }
3096
3097
    /* find the appropriate compositor method vector */
3098
0
    comp_id = *cbp++;
3099
0
    if ((pcomp_type = gs_find_compositor(comp_id)) == 0)
3100
0
        return_error(gs_error_unknownerror);
3101
3102
    /* de-serialize the compositor */
3103
0
    code = pcomp_type->procs.read(ppcomp, cbp, pcb->end - cbp, mem);
3104
3105
    /* If we read more than the maximum expected, return a rangecheck error */
3106
0
    if ( code > MAX_CLIST_COMPOSITOR_SIZE )
3107
0
        return_error(gs_error_rangecheck);
3108
3109
0
    if (code > 0)
3110
0
        cbp += code;
3111
0
    pcb->ptr = cbp;
3112
0
    return code;
3113
0
}
3114
3115
static int apply_composite(gx_device_clist_reader *cdev, gs_gstate *pgs,
3116
                                   gs_memory_t *mem, gs_composite_t *pcomp,
3117
                                   int x0, int y0, gx_device **ptarget)
3118
0
{
3119
0
    gx_device *tdev = *ptarget;
3120
0
    int code;
3121
3122
0
    code = pcomp->type->procs.adjust_ctm(pcomp, x0, y0, pgs);
3123
0
    if (code < 0)
3124
0
        goto exit;
3125
    /*
3126
     * Apply the compositor to the target device; note that this may
3127
     * change the target device.
3128
     */
3129
0
    code = dev_proc(tdev, composite)(tdev, &tdev, pcomp, pgs, mem, (gx_device*) cdev);
3130
0
    if (code == 1) {
3131
        /* A new compositor was created that wrapped tdev. This should
3132
         * be our new target. */
3133
0
        *ptarget = tdev;
3134
0
        code = 0;
3135
0
    }
3136
0
    if (code < 0)
3137
0
        goto exit;
3138
3139
    /* Perform any updates for the clist device required */
3140
0
    code = pcomp->type->procs.clist_compositor_read_update(pcomp,
3141
0
                                        (gx_device *)cdev, tdev, pgs, mem);
3142
0
exit:
3143
    /* free the compositor object */
3144
0
    gs_free_object(mem, pcomp, "read_composite");
3145
3146
0
    return code;
3147
0
}
3148
3149
/* ---------------- Utilities ---------------- */
3150
3151
/* Read and unpack a short bitmap */
3152
/*
3153
 * The 'raster' in the dest buffer may be larger than the 'width_bytes'
3154
 * in the src, so after reading we memmove data down to the proper
3155
 * alignment from the last line backwards.
3156
 * THIS RELIES on width_bytes <= raster to work.
3157
 */
3158
static const byte *
3159
cmd_read_short_bits(command_buf_t *pcb, byte *data, int tot_bytes,
3160
                    int width_bytes, int height, uint raster, const byte *cbp)
3161
0
{
3162
    /* Note the following may read from the file past the end of the buffer */
3163
    /* leaving cbp at pcb->end. No further reading using cbp can be done    */
3164
    /* without top_up_cbuf to reload the buffer.                            */
3165
0
    cbp = cmd_read_data(pcb, data, tot_bytes, cbp);
3166
3167
    /* if needed, adjust buffer contents for dest raster > width_bytes */
3168
0
    if (width_bytes < raster) {
3169
0
        const byte *pdata = data /*src*/ + width_bytes * height;
3170
0
        byte *udata = data /*dest*/ + height * raster;
3171
3172
0
        while (--height > 0) { /* don't need to move the first line to itself */
3173
0
            udata -= raster, pdata -= width_bytes;
3174
0
            switch (width_bytes) {
3175
0
                default:
3176
0
                    memmove(udata, pdata, width_bytes);
3177
0
                    break;
3178
0
                case 6:
3179
0
                    udata[5] = pdata[5];
3180
0
                case 5:
3181
0
                    udata[4] = pdata[4];
3182
0
                case 4:
3183
0
                    udata[3] = pdata[3];
3184
0
                case 3:
3185
0
                    udata[2] = pdata[2];
3186
0
                case 2:
3187
0
                    udata[1] = pdata[1];
3188
0
                case 1:
3189
0
                    udata[0] = pdata[0];
3190
0
                case 0:;            /* shouldn't happen */
3191
0
            }
3192
0
        }
3193
0
    }
3194
0
    return cbp;
3195
0
}
3196
3197
/* Read a rectangle. */
3198
static const byte *
3199
cmd_read_rect(int op, gx_cmd_rect * prect, const byte * cbp)
3200
0
{
3201
0
    cmd_getw(prect->x, cbp);
3202
0
    if (op & 0xf)
3203
0
        prect->y += ((op >> 2) & 3) - 2;
3204
0
    else {
3205
0
        cmd_getw(prect->y, cbp);
3206
0
    }
3207
0
    cmd_getw(prect->width, cbp);
3208
0
    if (op & 0xf)
3209
0
        prect->height += (op & 3) - 2;
3210
0
    else {
3211
0
        cmd_getw(prect->height, cbp);
3212
0
    }
3213
0
    return cbp;
3214
0
}
3215
3216
/*
3217
 * Select a map for loading with data.
3218
 *
3219
 * This routine has three outputs:
3220
 *   *pmdata - points to the map data.
3221
 *   *pcomp_num - points to a component number if the map is a transfer
3222
 *               map which has been set via the setcolortransfer operator.
3223
 *               A. value of NULL indicates that no component number is to
3224
 *               be sent for this map.
3225
 *   *pcount - the size of the map (in bytes).
3226
 */
3227
static int
3228
cmd_select_map(cmd_map_index map_index, cmd_map_contents cont,
3229
               gs_gstate * pgs, int ** pcomp_num, frac ** pmdata,
3230
               uint * pcount, gs_memory_t * mem)
3231
0
{
3232
0
    gx_transfer_map *map;
3233
0
    gx_transfer_map **pmap;
3234
0
    const char *cname;
3235
3236
0
    *pcomp_num = NULL;          /* Only used for color transfer maps */
3237
0
    switch (map_index) {
3238
0
        case cmd_map_transfer:
3239
0
            if_debug0m('L', mem, " transfer");
3240
0
            rc_unshare_struct(pgs->set_transfer.gray, gx_transfer_map,
3241
0
                &st_transfer_map, mem, return_error(gs_error_VMerror),
3242
0
                "cmd_select_map(default_transfer)");
3243
0
            map = pgs->set_transfer.gray;
3244
            /* Release all current maps */
3245
0
            rc_decrement(pgs->set_transfer.red, "cmd_select_map(red)");
3246
0
            pgs->set_transfer.red = NULL;
3247
0
            pgs->set_transfer.red_component_num = -1;
3248
0
            rc_decrement(pgs->set_transfer.green, "cmd_select_map(green)");
3249
0
            pgs->set_transfer.green = NULL;
3250
0
            pgs->set_transfer.green_component_num = -1;
3251
0
            rc_decrement(pgs->set_transfer.blue, "cmd_select_map(blue)");
3252
0
            pgs->set_transfer.blue = NULL;
3253
0
            pgs->set_transfer.blue_component_num = -1;
3254
0
            goto transfer2;
3255
0
        case cmd_map_transfer_0:
3256
0
            pmap = &pgs->set_transfer.red;
3257
0
            *pcomp_num = &pgs->set_transfer.red_component_num;
3258
0
            goto transfer1;
3259
0
        case cmd_map_transfer_1:
3260
0
            pmap = &pgs->set_transfer.green;
3261
0
            *pcomp_num = &pgs->set_transfer.green_component_num;
3262
0
            goto transfer1;
3263
0
        case cmd_map_transfer_2:
3264
0
            pmap = &pgs->set_transfer.blue;
3265
0
            *pcomp_num = &pgs->set_transfer.blue_component_num;
3266
0
            goto transfer1;
3267
0
        case cmd_map_transfer_3:
3268
0
            pmap = &pgs->set_transfer.gray;
3269
0
            *pcomp_num = &pgs->set_transfer.gray_component_num;
3270
0
transfer1:  if_debug1m('L', mem, " transfer[%d]", (int)(map_index - cmd_map_transfer_0));
3271
0
            rc_unshare_struct(*pmap, gx_transfer_map, &st_transfer_map, mem,
3272
0
                return_error(gs_error_VMerror), "cmd_select_map(transfer)");
3273
0
            map = *pmap;
3274
3275
0
transfer2:  if (cont != cmd_map_other) {
3276
0
                gx_set_identity_transfer(map);
3277
0
                *pmdata = 0;
3278
0
                *pcount = 0;
3279
0
                return 0;
3280
0
            }
3281
0
            break;
3282
0
        case cmd_map_black_generation:
3283
0
            if_debug0m('L', mem, " black generation");
3284
0
            pmap = &pgs->black_generation;
3285
0
            cname = "cmd_select_map(black generation)";
3286
0
            goto alloc;
3287
0
        case cmd_map_undercolor_removal:
3288
0
            if_debug0m('L', mem, " undercolor removal");
3289
0
            pmap = &pgs->undercolor_removal;
3290
0
            cname = "cmd_select_map(undercolor removal)";
3291
0
alloc:      if (cont == cmd_map_none) {
3292
0
                rc_decrement(*pmap, cname);
3293
0
                *pmap = 0;
3294
0
                *pmdata = 0;
3295
0
                *pcount = 0;
3296
0
                return 0;
3297
0
            }
3298
0
            rc_unshare_struct(*pmap, gx_transfer_map, &st_transfer_map,
3299
0
                              mem, return_error(gs_error_VMerror), cname);
3300
0
            map = *pmap;
3301
0
            if (cont == cmd_map_identity) {
3302
0
                gx_set_identity_transfer(map);
3303
0
                *pmdata = 0;
3304
0
                *pcount = 0;
3305
0
                return 0;
3306
0
            }
3307
0
            break;
3308
0
        default:
3309
0
            *pmdata = 0;
3310
0
            return 0;
3311
0
    }
3312
0
    map->proc = gs_mapped_transfer;
3313
0
    *pmdata = map->values;
3314
0
    *pcount = sizeof(map->values);
3315
0
    return 0;
3316
0
}
3317
3318
/* Create a device halftone for the imager if necessary. */
3319
static int
3320
cmd_create_dev_ht(gx_device_halftone **ppdht, gs_memory_t *mem)
3321
0
{
3322
0
    gx_device_halftone *pdht = *ppdht;
3323
3324
0
    if (pdht == 0) {
3325
0
        rc_header rc;
3326
3327
0
        rc_alloc_struct_1(pdht, gx_device_halftone, &st_device_halftone, mem,
3328
0
                          return_error(gs_error_VMerror),
3329
0
                          "cmd_create_dev_ht");
3330
0
        rc = pdht->rc;
3331
0
        memset(pdht, 0, sizeof(*pdht));
3332
0
        pdht->rc = rc;
3333
0
        *ppdht = pdht;
3334
0
    }
3335
0
    return 0;
3336
0
}
3337
3338
/* Resize the halftone components array if necessary. */
3339
static int
3340
cmd_resize_halftone(gx_device_halftone **ppdht, uint num_comp,
3341
                    gs_memory_t * mem)
3342
0
{
3343
0
    int code = cmd_create_dev_ht(ppdht, mem);
3344
0
    gx_device_halftone *pdht = *ppdht;
3345
3346
0
    if (code < 0)
3347
0
        return code;
3348
0
    if (num_comp != pdht->num_comp) {
3349
0
        gx_ht_order_component *pcomp;
3350
3351
        /*
3352
         * We must be careful not to shrink or free the components array
3353
         * before releasing any relevant elements.
3354
         */
3355
0
        if (num_comp < pdht->num_comp) {
3356
0
            uint i;
3357
3358
            /* Don't release the default order. */
3359
0
            for (i = pdht->num_comp; i-- > num_comp;)
3360
0
                if (pdht->components[i].corder.bit_data != pdht->order.bit_data)
3361
0
                    gx_ht_order_release(&pdht->components[i].corder, mem, true);
3362
0
            if (num_comp == 0) {
3363
0
                gs_free_object(mem, pdht->components, "cmd_resize_halftone");
3364
0
                pcomp = 0;
3365
0
            } else {
3366
0
                pcomp = gs_resize_object(mem, pdht->components, num_comp,
3367
0
                                         "cmd_resize_halftone");
3368
0
                if (pcomp == 0) {
3369
0
                    pdht->num_comp = num_comp;  /* attempt consistency */
3370
0
                    return_error(gs_error_VMerror);
3371
0
                }
3372
0
            }
3373
0
        } else {
3374
            /* num_comp > pdht->num_comp */
3375
0
            if (pdht->num_comp == 0)
3376
0
                pcomp = gs_alloc_struct_array(mem, num_comp,
3377
0
                                              gx_ht_order_component,
3378
0
                                              &st_ht_order_component_element,
3379
0
                                              "cmd_resize_halftone");
3380
0
            else
3381
0
                pcomp = gs_resize_object(mem, pdht->components, num_comp,
3382
0
                                         "cmd_resize_halftone");
3383
0
            if (pcomp == 0)
3384
0
                return_error(gs_error_VMerror);
3385
0
            memset(&pcomp[pdht->num_comp], 0,
3386
0
                   sizeof(*pcomp) * (num_comp - pdht->num_comp));
3387
0
        }
3388
0
        pdht->num_comp = num_comp;
3389
0
        pdht->components = pcomp;
3390
0
    }
3391
0
    return 0;
3392
0
}
3393
3394
/* ------ Path operations ------ */
3395
3396
/* Decode a path segment. */
3397
static int
3398
clist_decode_segment(gx_path * ppath, int op, fixed vs[6],
3399
                 gs_fixed_point * ppos, int x0, int y0, segment_notes notes)
3400
0
{
3401
0
    fixed px = ppos->x - int2fixed(x0);
3402
0
    fixed py = ppos->y - int2fixed(y0);
3403
0
    int code;
3404
3405
0
#define A vs[0]
3406
0
#define B vs[1]
3407
0
#define C vs[2]
3408
0
#define D vs[3]
3409
0
#define E vs[4]
3410
0
#define F vs[5]
3411
3412
0
    switch (op) {
3413
0
        case cmd_opv_rmoveto:
3414
0
            code = gx_path_add_point(ppath, px += A, py += B);
3415
0
            break;
3416
0
        case cmd_opv_rlineto:
3417
0
            code = gx_path_add_line_notes(ppath, px += A, py += B, notes);
3418
0
            break;
3419
0
        case cmd_opv_rgapto:
3420
0
            code = gx_path_add_gap_notes(ppath, px += A, py += B, notes);
3421
0
            break;
3422
0
        case cmd_opv_hlineto:
3423
0
            code = gx_path_add_line_notes(ppath, px += A, py, notes);
3424
0
            break;
3425
0
        case cmd_opv_vlineto:
3426
0
            code = gx_path_add_line_notes(ppath, px, py += A, notes);
3427
0
            break;
3428
0
        case cmd_opv_rmlineto:
3429
0
            if ((code = gx_path_add_point(ppath, px += A, py += B)) < 0)
3430
0
                break;
3431
0
            code = gx_path_add_line_notes(ppath, px += C, py += D, notes);
3432
0
            break;
3433
0
        case cmd_opv_rm2lineto:
3434
0
            if ((code = gx_path_add_point(ppath, px += A, py += B)) < 0 ||
3435
0
                (code = gx_path_add_line_notes(ppath, px += C, py += D,
3436
0
                                               notes)) < 0
3437
0
                )
3438
0
                break;
3439
0
            code = gx_path_add_line_notes(ppath, px += E, py += F, notes);
3440
0
            break;
3441
0
        case cmd_opv_rm3lineto:
3442
0
            if ((code = gx_path_add_point(ppath, px += A, py += B)) < 0 ||
3443
0
                (code = gx_path_add_line_notes(ppath, px += C, py += D,
3444
0
                                               notes)) < 0 ||
3445
0
                (code = gx_path_add_line_notes(ppath, px += E, py += F,
3446
0
                                               notes)) < 0
3447
0
                )
3448
0
                break;
3449
0
            code = gx_path_add_line_notes(ppath, px -= C, py -= D, notes);
3450
0
            break;
3451
0
        case cmd_opv_rrcurveto: /* a b c d e f => a b a+c b+d a+c+e b+d+f */
3452
0
rrc:        E += (C += A);
3453
0
            F += (D += B);
3454
0
curve:      code = gx_path_add_curve_notes(ppath, px + A, py + B,
3455
0
                                           px + C, py + D,
3456
0
                                           px + E, py + F, notes);
3457
0
            px += E, py += F;
3458
0
            break;
3459
0
        case cmd_opv_hvcurveto: /* a b c d => a 0 a+b c a+b c+d */
3460
0
hvc:        F = C + D, D = C, E = C = A + B, B = 0;
3461
0
            goto curve;
3462
0
        case cmd_opv_vhcurveto: /* a b c d => 0 a b a+c b+d a+c */
3463
0
vhc:        E = B + D, F = D = A + C, C = B, B = A, A = 0;
3464
0
            goto curve;
3465
0
        case cmd_opv_nrcurveto: /* a b c d => 0 0 a b a+c b+d */
3466
0
            F = B + D, E = A + C, D = B, C = A, B = A = 0;
3467
0
            goto curve;
3468
0
        case cmd_opv_rncurveto: /* a b c d => a b a+c b+d a+c b+d */
3469
0
            F = D += B, E = C += A;
3470
0
            goto curve;
3471
0
        case cmd_opv_vqcurveto: /* a b => VH a b TS(a,b) TS(b,a) */
3472
0
            if ((A ^ B) < 0)
3473
0
                C = -B, D = -A;
3474
0
            else
3475
0
                C = B, D = A;
3476
0
            goto vhc;
3477
0
        case cmd_opv_hqcurveto: /* a b => HV a TS(a,b) b TS(b,a) */
3478
0
            if ((A ^ B) < 0)
3479
0
                D = -A, C = B, B = -B;
3480
0
            else
3481
0
                D = A, C = B;
3482
0
            goto hvc;
3483
0
        case cmd_opv_scurveto: /* (a b c d e f) => */
3484
0
            {
3485
0
                fixed a = A, b = B;
3486
3487
                /* See gxclpath.h for details on the following. */
3488
0
                if (A == 0) {
3489
                    /* Previous curve was vh or vv */
3490
0
                    A = E - C, B = D - F, C = C - a, D = b - D, E = a, F = -b;
3491
0
                } else {
3492
                    /* Previous curve was hv or hh */
3493
0
                    A = C - E, B = F - D, C = a - C, D = D - b, E = -a, F = b;
3494
0
                }
3495
0
            }
3496
0
            goto rrc;
3497
0
        case cmd_opv_closepath:
3498
0
            if ((code = gx_path_close_subpath(ppath)) < 0)
3499
0
                return code;;
3500
0
            if ((code = gx_path_current_point(ppath, (gs_fixed_point *) vs)) < 0)
3501
0
                return code;;
3502
0
            px = A, py = B;
3503
0
            break;
3504
0
        default:
3505
0
            return_error(gs_error_rangecheck);
3506
0
    }
3507
0
#undef A
3508
0
#undef B
3509
0
#undef C
3510
0
#undef D
3511
0
#undef E
3512
0
#undef F
3513
0
    ppos->x = px + int2fixed(x0);
3514
0
    ppos->y = py + int2fixed(y0);
3515
0
    return code;
3516
0
}
3517
3518
/*
3519
 * Execute a polyfill -- either a fill_parallelogram or a fill_triangle.
3520
 *
3521
 * Note that degenerate parallelograms or triangles may collapse into
3522
 * a single line or point.  We must check for this so we don't try to
3523
 * access non-existent segments.
3524
 */
3525
static int
3526
clist_do_polyfill(gx_device *dev, gx_path *ppath,
3527
                  const gx_drawing_color *pdcolor,
3528
                  gs_logical_operation_t lop)
3529
0
{
3530
0
    const subpath *psub = ppath->first_subpath;
3531
0
    const segment *pseg1;
3532
0
    const segment *pseg2;
3533
0
    int code;
3534
3535
0
    if (psub && (pseg1 = psub->next) != 0 && (pseg2 = pseg1->next) != 0) {
3536
0
        fixed px = psub->pt.x, py = psub->pt.y;
3537
0
        fixed ax = pseg1->pt.x - px, ay = pseg1->pt.y - py;
3538
0
        fixed bx, by;
3539
        /*
3540
         * We take advantage of the fact that the parameter lists for
3541
         * fill_parallelogram and fill_triangle are identical.
3542
         */
3543
0
        dev_proc_fill_parallelogram((*fill));
3544
3545
        /* close_path of 3 point triangle adds 4th point, detected here.*/
3546
        /* close_path on parallelogram adds 5th point also ignored. */
3547
0
        if (pseg2->next && !(px == pseg2->next->pt.x && py == pseg2->next->pt.y)) {
3548
            /* Parallelogram */
3549
0
            fill = dev_proc(dev, fill_parallelogram);
3550
0
            bx = pseg2->pt.x - pseg1->pt.x;
3551
0
            by = pseg2->pt.y - pseg1->pt.y;
3552
0
        } else {
3553
            /* Triangle */
3554
0
            fill = dev_proc(dev, fill_triangle);
3555
0
            bx = pseg2->pt.x - px;
3556
0
            by = pseg2->pt.y - py;
3557
0
        }
3558
0
        code = fill(dev, px, py, ax, ay, bx, by, pdcolor, lop);
3559
0
    } else
3560
0
        code = 0;
3561
0
    gx_path_new(ppath);
3562
0
    return code;
3563
0
}