Coverage Report

Created: 2025-06-10 06:49

/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
1.09M
  BEGIN\
91
1.09M
    if ( *p < 0x80 ) var = *p++;\
92
1.09M
    else { const byte *_cbp; var = cmd_get_w(p, &_cbp); p = _cbp; }\
93
1.09M
  END
94
95
static long
96
cmd_get_w(const byte * p, const byte ** rp)
97
333k
{
98
333k
    int val = *p++ & 0x7f;
99
333k
    int shift = 7;
100
101
362k
    for (; val |= (int)(*p & 0x7f) << shift, *p++ > 0x7f; shift += 7);
102
333k
    *rp = p;
103
333k
    return val;
104
333k
}
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
1.33M
{
144
1.33M
    pcb->end = end;
145
1.33M
    pcb->warn_limit = pcb->data + (pcb->size - cmd_largest_size + 1);
146
1.33M
    if ( pcb->warn_limit > pcb->end )
147
101k
        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
1.33M
}
151
152
static inline void
153
advance_buffer(command_buf_t *pcb, const byte *cbp)
154
1.23M
{
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
1.23M
    memmove(pcb->data, cbp, pcb->end - cbp);
161
1.23M
}
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
1.27M
{
177
1.27M
    uint nread;
178
1.27M
    const byte *cbp = *pcbp;
179
1.27M
    byte *cb_top = pcb->data + (pcb->end - cbp);
180
181
1.27M
    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
1.27M
    if (seofp(pcb->s)) {
187
        /* Can't use offset_map, because s_close resets s->state. Don't top up. */
188
41.1k
        pcb->end_status = pcb->s->end_status;
189
41.1k
        return 0;
190
41.1k
    }
191
1.23M
    advance_buffer(pcb, cbp);
192
1.23M
    nread = pcb->end - cb_top;
193
1.23M
    pcb->end_status = sgets(pcb->s, cb_top, nread, &nread);
194
1.23M
    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
1.23M
    set_cb_end(pcb, cb_top + nread);
206
1.23M
    process_interrupts(pcb->s->memory);
207
1.23M
    *pcbp = pcb->data;
208
1.23M
    return 0;
209
1.23M
}
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
50.7k
{
217
50.7k
    if (pcb->end - cbp >= rsize) {
218
50.5k
        memmove(ptr, cbp, rsize);
219
50.5k
        return cbp + rsize;
220
50.5k
    } else {
221
253
        uint cleft = pcb->end - cbp;
222
253
        uint rleft = rsize - cleft;
223
224
253
        memmove(ptr, cbp, cleft);
225
253
        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
253
        return pcb->end;
234
253
    }
235
50.7k
}
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
14.7k
{
241
14.7k
    memcpy(pvar, cbp, var_size);
242
14.7k
    return cbp + var_size;
243
14.7k
}
244
#define cmd_get_value(var, cbp)\
245
14.7k
  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
111k
{
304
111k
    if (*ppcomp_last == NULL) {
305
99.2k
        pcomp->prev = pcomp->next = NULL;
306
99.2k
        *ppcomp_last = *ppcomp_first = pcomp;
307
99.2k
    } else {
308
12.4k
        (*ppcomp_last)->next = pcomp;
309
12.4k
        pcomp->prev = *ppcomp_last;
310
12.4k
        pcomp->next = NULL;
311
12.4k
        *ppcomp_last = pcomp;
312
12.4k
    }
313
111k
}
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
111k
{
350
111k
    if (*ppcomp_last == *ppcomp_first) {
351
99.2k
        if (*ppcomp_last == pcomp) {
352
99.2k
            *ppcomp_last = *ppcomp_first = NULL;
353
99.2k
            return 0;
354
99.2k
        } else
355
0
            return_error(gs_error_unregistered); /* Must not happen. */
356
99.2k
    } else {
357
12.4k
        gs_composite_t *pcomp_next = pcomp->next, *pcomp_prev = pcomp->prev;
358
359
12.4k
        if (*ppcomp_last == pcomp)
360
4.97k
            *ppcomp_last = pcomp->prev;
361
7.49k
        else
362
7.49k
            pcomp_next->prev = pcomp_prev;
363
12.4k
        if (*ppcomp_first == pcomp)
364
7.49k
            *ppcomp_first = pcomp->next;
365
4.97k
        else
366
4.97k
            pcomp_prev->next = pcomp_next;
367
12.4k
        pcomp->next = pcomp->prev = NULL;
368
12.4k
        return 0;
369
12.4k
    }
370
111k
}
371
372
static inline void
373
free_compositor(gs_composite_t *pcomp, gs_memory_t *mem)
374
90.9k
{
375
90.9k
    gs_free_object(mem, pcomp, "free_compositor");
376
90.9k
}
377
378
static inline bool
379
is_null_compositor_op(const byte *cbp, int *length)
380
111k
{
381
111k
    if (cbp[0] == cmd_opv_end_run) {
382
94.0k
        *length = 1;
383
94.0k
        return true;
384
94.0k
    }
385
17.3k
    return false;
386
111k
}
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
15.4k
{
393
36.1k
    while (pcomp_from != NULL) {
394
20.6k
        gs_composite_t *pcomp = pcomp_from;
395
20.6k
        int code;
396
397
20.6k
        pcomp_from = pcomp->next;
398
20.6k
        code = dequeue_compositor(ppcomp_first, ppcomp_last, pcomp);
399
20.6k
        if (code < 0)
400
0
            return code;
401
20.6k
        pcomp->idle |= idle;
402
20.6k
        code = apply_composite(cdev, pgs, mem, pcomp, x0, y0, target); /* Releases the compositor. */
403
20.6k
        if (code < 0)
404
0
            return code;
405
20.6k
        *tdev = *target;
406
20.6k
    }
407
15.4k
    return 0;
408
15.4k
}
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
955
{
428
955
    gs_composite_t *pcomp;
429
430
3.17k
    do {
431
3.17k
        int code;
432
433
3.17k
        pcomp = *ppcomp_last;
434
3.17k
        if (pcomp == NULL)
435
0
            return 0;
436
3.17k
        dequeue_compositor(ppcomp_first, ppcomp_last, *ppcomp_last);
437
3.17k
        code = pcomp->type->procs.adjust_ctm(pcomp, x0, y0, pgs);
438
3.17k
        if (code < 0)
439
0
            return code;
440
3.17k
        free_compositor(pcomp, mem);
441
3.17k
    } while (pcomp != pcomp_from);
442
955
    return 0;
443
955
}
444
445
static int
446
read_set_misc_map(byte cb, command_buf_t *pcb, gs_gstate *pgs, gs_memory_t *mem)
447
19.9k
{
448
19.9k
    const byte *cbp = pcb->ptr;
449
19.9k
    frac *mdata;
450
19.9k
    int *pcomp_num;
451
19.9k
    uint count = 0;   /* quiet compiler */
452
19.9k
    cmd_map_contents cont =
453
19.9k
        (cmd_map_contents)(cb & 0x30) >> 4;
454
19.9k
    int code;
455
456
19.9k
    code = cmd_select_map(cb & 0xf, cont,
457
19.9k
                          pgs,
458
19.9k
                          &pcomp_num,
459
19.9k
                          &mdata, &count, mem);
460
461
19.9k
    if (code < 0)
462
0
        return code;
463
    /* Get component number if relevant */
464
19.9k
    if (pcomp_num == NULL)
465
19.9k
        cbp++;
466
0
    else {
467
0
        *pcomp_num = (int) *cbp++;
468
0
        if_debug1m('L', mem, " comp_num=%d", *pcomp_num);
469
0
    }
470
19.9k
    if (cont == cmd_map_other) {
471
17.0k
        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
17.0k
    }
485
    /* Recompute the effective transfer, */
486
    /* in case this was a transfer map. */
487
19.9k
    gx_gstate_set_effective_xfer(pgs);
488
19.9k
    pcb->ptr = cbp;
489
19.9k
    return 0;
490
19.9k
}
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
101k
{
516
101k
    byte *cbuf_storage;
517
101k
    command_buf_t cbuf;
518
    /* data_bits is for short copy_* bits and copy_* compressed, */
519
    /* must be aligned */
520
101k
    byte *data_bits = 0;
521
101k
    const byte *cbp;
522
101k
    int dev_depth;              /* May vary due to compositing devices */
523
101k
    int dev_depth_bytes;
524
101k
    int odd_delta_shift;
525
101k
    int num_zero_bytes;
526
101k
    gx_device *tdev;
527
101k
    gx_clist_state state;
528
101k
    gx_color_index *set_colors;
529
101k
    gx_device_color *set_dev_colors;
530
101k
    tile_slot *state_slot;
531
101k
    gx_strip_bitmap state_tile; /* parameters for reading tiles */
532
101k
    tile_slot tile_bits;        /* parameters of current tile */
533
101k
    gs_int_point tile_phase;
534
101k
    gx_path path;
535
101k
    bool in_path;
536
101k
    gs_fixed_point ppos;
537
101k
    gx_clip_path clip_path;
538
101k
    bool use_clip;
539
101k
    gx_clip_path *pcpath;
540
101k
    gx_device_cpath_accum clip_accum;
541
101k
    gs_fixed_rect target_box;
542
101k
    struct _cas {
543
101k
        bool lop_enabled;
544
101k
        gx_device_color dcolor;
545
101k
        gs_fixed_point fa_save;
546
101k
    } clip_save;
547
101k
    bool in_clip = false;
548
101k
    gs_gstate gs_gstate;
549
101k
    gx_device_color fill_color = { 0 };
550
101k
    gx_device_color stroke_color = { 0 };
551
101k
    float dash_pattern[cmd_max_dash];
552
101k
    gx_fill_params fill_params;
553
101k
    gx_stroke_params stroke_params;
554
#ifdef DEBUG
555
    gs_halftone_type halftone_type;
556
#endif
557
101k
    union im_ {
558
101k
        gs_image_common_t c;
559
101k
        gs_data_image_t d;
560
101k
        gs_image1_t i1;
561
101k
        gs_image4_t i4;
562
101k
    } image;
563
101k
    gs_int_rect image_rect;
564
101k
    gs_color_space *pcs = NULL;
565
101k
    gx_image_enum_common_t *image_info;
566
101k
    gx_image_plane_t planes[32];
567
101k
    uint data_height;
568
101k
    uint data_size;
569
101k
    byte *data_on_heap;
570
101k
    fixed vs[6];
571
101k
    segment_notes notes;
572
101k
    int data_x;
573
101k
    int code = 0;
574
101k
    ht_buff_t  ht_buff;
575
101k
    gx_device *const orig_target = target;
576
101k
    gx_device_clip clipper_dev;
577
101k
    bool clipper_dev_open = false;
578
101k
    patch_fill_state_t pfs;
579
101k
    int op = 0;
580
101k
    int plane_height = 0;
581
582
#ifdef DEBUG
583
    stream_state *st = s->state; /* Save because s_close resets s->state. */
584
#endif
585
101k
    gs_composite_t *pcomp_first = NULL, *pcomp_last = NULL;
586
101k
    tile_slot bits;             /* parameters for reading bits */
587
588
    /* pad the cbuf data area a bit (just in case) */
589
101k
    if ((cbuf_storage = gs_alloc_bytes(mem, cbuf_size + sizeof(double),
590
101k
                               "clist_playback_band(cbuf_storage)")) == NULL) {
591
0
        return_error(gs_error_VMerror);
592
0
    }
593
101k
    cbuf.data = (byte *)cbuf_storage;
594
101k
    cbuf.size = cbuf_size;
595
101k
    cbuf.s = s;
596
101k
    cbuf.end_status = 0;
597
101k
    set_cb_end(&cbuf, cbuf.data + cbuf.size);
598
101k
    cbp = cbuf.end;
599
600
101k
    pfs.dev = NULL; /* Indicate "not initialized". */
601
101k
    memset(&ht_buff, 0, sizeof(ht_buff));
602
603
    /* The following initializations are to quiet gcc warnings. */
604
101k
    memset(&bits, 0, sizeof(bits));
605
101k
    memset(&tile_bits, 0, sizeof(tile_bits));
606
101k
    memset(&clip_save, 0, sizeof(clip_save));
607
101k
    memset(&state_slot, 0, sizeof(state_slot));
608
101k
    ppos.x = ppos.y = 0;
609
610
101k
in:                             /* Initialize for a new page. */
611
101k
    tdev = target;
612
101k
    set_colors = state.colors;
613
101k
    set_dev_colors = state.tile_color_devn;
614
101k
    use_clip = false;
615
101k
    pcpath = NULL;
616
101k
    if (clipper_dev_open)
617
0
        gx_destroy_clip_device_on_stack(&clipper_dev);
618
101k
    clipper_dev_open = false;
619
101k
    notes = sn_none;
620
101k
    data_x = 0;
621
101k
    {
622
101k
        static const gx_clist_state cls_initial = { cls_initial_values };
623
624
101k
        state = cls_initial;
625
101k
    }
626
101k
    state_tile.id = gx_no_bitmap_id;
627
101k
    state_tile.shift = state_tile.rep_shift = 0;
628
101k
    state_tile.size.x = state_tile.size.y = 0;
629
101k
    state_tile.num_planes = 1;
630
101k
    tile_phase.x = x0;
631
101k
    tile_phase.y = y0;
632
101k
    gx_path_init_local(&path, mem);
633
101k
    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
101k
    {
639
101k
        gs_fixed_rect cbox;
640
641
101k
        gx_cpath_init_local(&clip_path, mem);
642
101k
        cbox.p.x = 0;
643
101k
        cbox.p.y = 0;
644
101k
        cbox.q.x = cdev->width;
645
101k
        cbox.q.y = cdev->height;
646
101k
        gx_cpath_from_rectangle(&clip_path, &cbox);
647
101k
    }
648
101k
    if (target != 0)
649
101k
        (*dev_proc(target, get_clipping_box))(target, &target_box);
650
101k
    memset(&gs_gstate, 0, sizeof(gs_gstate));
651
101k
    GS_STATE_INIT_VALUES_CLIST((&gs_gstate));
652
101k
    code = gs_gstate_initialize(&gs_gstate, mem);
653
101k
    if (code < 0)
654
0
        goto out;
655
101k
    gs_gstate.device = tdev;
656
101k
    gs_gstate.view_clip = NULL; /* Avoid issues in pdf14 fill stroke */
657
101k
    gs_gstate.clip_path = &clip_path;
658
101k
    pcs = gs_cspace_new_DeviceGray(mem);
659
101k
    if (pcs == NULL) {
660
0
        code = gs_note_error(gs_error_VMerror);
661
0
        goto out;
662
0
    }
663
101k
    code = pcs->type->install_cspace(pcs, &gs_gstate);
664
101k
    if (code < 0) {
665
0
        rc_decrement(pcs, "clist_playback_band");
666
0
        goto out;
667
0
    }
668
101k
    gs_gstate.color[0].color_space = pcs; /* we already have one ref */
669
101k
    gs_gstate.color[1].color_space = pcs;
670
101k
    rc_increment_cs(pcs); /* increment for second ref */
671
    /* Initialize client color and device color */
672
101k
    gs_gstate.color[0].ccolor =
673
101k
        gs_alloc_struct(mem, gs_client_color, &st_client_color, "clist_playback_band");
674
101k
    gs_gstate.color[1].ccolor =
675
101k
        gs_alloc_struct(mem, gs_client_color, &st_client_color, "clist_playback_band");
676
101k
    gs_gstate.color[0].dev_color =
677
101k
        gs_alloc_struct(mem, gx_device_color, &st_device_color, "clist_playback_band");
678
101k
    gs_gstate.color[1].dev_color =
679
101k
        gs_alloc_struct(mem, gx_device_color, &st_device_color, "clist_playback_band");
680
101k
    if (gs_gstate.color[0].ccolor == 0 || gs_gstate.color[0].dev_color == 0 ||
681
101k
        gs_gstate.color[1].ccolor == 0 || gs_gstate.color[1].dev_color == 0
682
101k
        ) {
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
101k
    gs_gstate.color[0].color_space->pclient_color_space_data =
692
101k
        pcs->pclient_color_space_data;
693
101k
    cs_full_init_color(gs_gstate.color[0].ccolor, pcs);
694
101k
    gx_unset_dev_color(&gs_gstate);
695
696
101k
    gs_gstate.color[1].color_space->pclient_color_space_data =
697
101k
        pcs->pclient_color_space_data;
698
101k
    cs_full_init_color(gs_gstate.color[1].ccolor, pcs);
699
101k
    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
101k
    rc_decrement(gs_gstate.icc_link_cache,"clist_playback_band");
704
101k
    gs_gstate.icc_link_cache = cdev->icc_cache_cl;
705
    /* Need to lock during the increment of the link cache */
706
101k
    gx_monitor_enter(cdev->icc_cache_cl->lock);
707
101k
    rc_increment(cdev->icc_cache_cl);
708
101k
    gx_monitor_leave(cdev->icc_cache_cl->lock); /* let everyone run */
709
101k
    if (code < 0)
710
0
        goto out;
711
712
101k
    gs_gstate.line_params.dash.pattern = dash_pattern;
713
101k
    if (tdev != 0) {
714
101k
        gx_set_cmap_procs(&gs_gstate, tdev);
715
101k
    }
716
101k
    gx_gstate_setscreenphase(&gs_gstate, -x0, -y0, gs_color_select_all);
717
#ifdef DEBUG
718
    halftone_type = ht_type_none;
719
#endif
720
101k
    fill_color.ccolor_valid = false;
721
101k
    color_unset(&fill_color);
722
101k
    data_bits = gs_alloc_bytes(mem, data_bits_size,
723
101k
                               "clist_playback_band(data_bits)");
724
101k
    if (data_bits == 0) {
725
0
        code = gs_note_error(gs_error_VMerror);
726
0
        goto out;
727
0
    }
728
1.97M
    while (code >= 0) {
729
1.97M
        int compress;
730
1.97M
        int depth = 0x7badf00d; /* Initialize against indeterminizm. */
731
1.97M
        int raster = 0x7badf00d; /* Initialize against indeterminizm. */
732
1.97M
        byte *source = NULL;  /* Initialize against indeterminizm. */
733
1.97M
        gx_color_index colors[2];
734
1.97M
        gx_color_index *pcolor;
735
1.97M
        gx_device_color *pdcolor = NULL;
736
1.97M
        gs_logical_operation_t log_op;
737
738
        /* Make sure the buffer contains a full command. */
739
1.97M
        if (cbp >= cbuf.warn_limit) {
740
103k
            if (cbuf.end_status < 0) {  /* End of file or error. */
741
26
                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
103k
            } else {
747
103k
                code = top_up_cbuf(&cbuf, &cbp);
748
103k
                if (code < 0)
749
0
                    goto top_up_failed;
750
103k
            }
751
103k
        }
752
1.97M
        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
1.97M
        switch (op >> 4) {
762
313k
            case cmd_op_misc >> 4:
763
313k
                switch (op) {
764
154k
                    case cmd_opv_end_run:
765
154k
                        if_debug0m('L', mem, "\n");
766
154k
                        continue;
767
1
                    case cmd_opv_set_tile_size:
768
1
                        cbuf.ptr = cbp;
769
1
                        code = read_set_tile_size(&cbuf, &tile_bits,
770
1
                                    gx_device_is_pattern_clist((gx_device *)cdev));
771
1
                        cbp = cbuf.ptr;
772
1
                        if (code < 0)
773
0
                            goto out;
774
1
                        continue;
775
1
                    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
1.00k
                    case cmd_opv_set_screen_phaseT:
783
1.00k
                        cmd_getw(state.screen_phase[gs_color_select_texture].x, cbp);
784
1.00k
                        cmd_getw(state.screen_phase[gs_color_select_texture].y, cbp);
785
1.00k
                        if_debug2m('L', mem, " (%d,%d)\n",
786
1.00k
                                   state.screen_phase[0].x,
787
1.00k
                                   state.screen_phase[gs_color_select_texture].y);
788
1.00k
                        gx_gstate_setscreenphase(&gs_gstate,
789
1.00k
                                                 state.screen_phase[gs_color_select_texture].x - x0,
790
1.00k
                                                 state.screen_phase[gs_color_select_texture].y - y0,
791
1.00k
                                                 gs_color_select_texture);
792
1.00k
                        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
2
                    case cmd_opv_set_tile_bits:
805
2
                        bits = tile_bits;
806
2
                        compress = 0;
807
38.4k
                      stb:
808
38.4k
                        cbuf.ptr = cbp;
809
38.4k
                        code = read_set_bits(&cbuf, &bits, compress,
810
38.4k
                                             &state, &state_tile, &state_slot,
811
38.4k
                                             cdev, mem);
812
38.4k
                        cbp = cbuf.ptr;
813
38.4k
                        if (code < 0)
814
0
                            goto out;
815
38.4k
                        goto stp;
816
38.4k
                    case cmd_opv_set_bits:
817
38.4k
do_opv_set_bits:
818
38.4k
                        compress = *cbp & 3;
819
38.4k
                        bits.head.depth = *cbp++ >> 2;
820
38.4k
                        cmd_getw(bits.width, cbp);
821
38.4k
                        cmd_getw(bits.height, cbp);
822
38.4k
                        if (op == cmd_opv_set_bits_planar)
823
38.4k
                            cmd_getw(bits.num_planes, cbp);
824
38.4k
                        else
825
38.4k
                            bits.num_planes = 1;
826
38.4k
                        if_debug5m('L', mem, " compress=%d depth=%d size=(%d,%d) planes=%d",
827
38.4k
                                   compress, bits.head.depth,
828
38.4k
                                   bits.width, bits.height, bits.num_planes);
829
38.4k
                        bits.raster =
830
38.4k
                            bitmap_raster(bits.width * bits.head.depth);
831
38.4k
                        bits.x_reps = bits.y_reps = 1;
832
38.4k
                        bits.shift = bits.rep_shift = 0;
833
38.4k
                        goto stb;
834
2
                    case cmd_opv_set_tile_color:
835
2
                        set_colors = state.tile_colors;
836
2
                        if_debug0m('L', mem, "\n");
837
2
                        continue;
838
17.7k
                    case cmd_opv_set_misc:
839
17.7k
                        {
840
17.7k
                            uint cb = *cbp++;
841
842
17.7k
                            switch (cb >> 6) {
843
532
                                case cmd_set_misc_lop >> 6:
844
532
                                    cmd_getw(state.lop, cbp);
845
532
                                    state.lop = (state.lop << 6) + (cb & 0x3f);
846
532
                                    if_debug1m('L', mem, " lop=0x%x\n", state.lop);
847
532
                                    if (state.lop_enabled)
848
0
                                        gs_gstate.log_op = state.lop;
849
532
                                    break;
850
113
                                case cmd_set_misc_data_x >> 6:
851
113
                                    if (cb & 0x20)
852
113
                                        cmd_getw(data_x, cbp);
853
113
                                    else
854
113
                                        data_x = 0;
855
113
                                    data_x = (data_x << 5) + (cb & 0x1f);
856
113
                                    if_debug1m('L', mem, " data_x=%d\n", data_x);
857
113
                                    break;
858
17.0k
                                case cmd_set_misc_map >> 6:
859
17.0k
                                    cbuf.ptr = cbp;
860
17.0k
                                    code = read_set_misc_map(cb, &cbuf, &gs_gstate, mem);
861
17.0k
                                    if (code < 0)
862
0
                                        goto out;
863
17.0k
                                    cbp = cbuf.ptr;
864
17.0k
                                    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
17.7k
                            }
885
17.7k
                        }
886
17.7k
                        continue;
887
17.7k
                    case cmd_opv_enable_lop:
888
532
                        state.lop_enabled = true;
889
532
                        gs_gstate.log_op = state.lop;
890
532
                        if_debug0m('L', mem, "\n");
891
532
                        continue;
892
13
                    case cmd_opv_disable_lop:
893
13
                        state.lop_enabled = false;
894
13
                        gs_gstate.log_op = lop_default;
895
13
                        if_debug0m('L', mem, "\n");
896
13
                        continue;
897
101k
                    case cmd_opv_end_page:
898
101k
                        if_debug0m('L', mem, "\n");
899
                        /*
900
                         * Do end-of-page cleanup, then reinitialize if
901
                         * there are more pages to come.
902
                         */
903
101k
                        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
313k
                }
979
                /*NOTREACHED */
980
1
            case cmd_op_set_color0 >> 4:
981
1
                pcolor = &set_colors[0];
982
1
                goto set_color;
983
290
            case cmd_op_set_color1 >> 4:
984
290
                pcolor = &set_colors[1];
985
291
              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
291
                num_zero_bytes = op & 0x0f;
994
995
291
                if (num_zero_bytes == cmd_no_color_index)
996
0
                    *pcolor = gx_no_color_index;
997
291
                else {
998
291
                    gx_color_index color = 0;
999
1000
291
                    dev_depth = (tdev->color_info.depth < 8*sizeof(gx_color_index) ?
1001
291
                                 tdev->color_info.depth : 8*sizeof(gx_color_index));
1002
291
                    dev_depth_bytes = (dev_depth + 7) >> 3;
1003
291
                    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
32
                        case 1:
1019
32
                            color = (color << 8) | (gx_color_index) * cbp++;
1020
291
                        default:
1021
291
                            break;
1022
291
                    }
1023
291
                    color <<= num_zero_bytes * 8;
1024
291
                    *pcolor = color;
1025
291
                }
1026
291
                if (sizeof(*pcolor) <= sizeof(ulong))
1027
291
                    if_debug1m('L', mem, " 0x%lx\n", (ulong)*pcolor);
1028
0
                else
1029
291
                    if_debug2m('L', mem, " 0x%8lx%08lx\n",
1030
291
                               (ulong)(*pcolor >> 8*(sizeof(*pcolor) - sizeof(ulong))), (ulong)*pcolor);
1031
291
                continue;
1032
154k
            case cmd_op_fill_rect >> 4:
1033
154k
            case cmd_op_tile_rect >> 4:
1034
154k
                cbp = cmd_read_rect(op, &state.rect, cbp);
1035
154k
                break;
1036
203k
            case cmd_op_fill_rect_short >> 4:
1037
203k
            case cmd_op_tile_rect_short >> 4:
1038
203k
                state.rect.x += *cbp + cmd_min_short;
1039
203k
                state.rect.width += cbp[1] + cmd_min_short;
1040
203k
                if (op & 0xf) {
1041
773
                    state.rect.height += (op & 0xf) + cmd_min_dxy_tiny;
1042
773
                    cbp += 2;
1043
203k
                } else {
1044
203k
                    state.rect.y += cbp[2] + cmd_min_short;
1045
203k
                    state.rect.height += cbp[3] + cmd_min_short;
1046
203k
                    cbp += 4;
1047
203k
                }
1048
203k
                break;
1049
82.6k
            case cmd_op_fill_rect_tiny >> 4:
1050
82.6k
            case cmd_op_tile_rect_tiny >> 4:
1051
82.6k
                if (op & 8)
1052
8
                    state.rect.x += state.rect.width;
1053
82.6k
                else {
1054
82.6k
                    int txy = *cbp++;
1055
1056
82.6k
                    state.rect.x += (txy >> 4) + cmd_min_dxy_tiny;
1057
82.6k
                    state.rect.y += (txy & 0xf) + cmd_min_dxy_tiny;
1058
82.6k
                }
1059
82.6k
                state.rect.width += (op & 7) + cmd_min_dw_tiny;
1060
82.6k
                break;
1061
94.3k
            case cmd_op_copy_mono_planes >> 4:
1062
94.3k
                cmd_getw(plane_height, cbp);
1063
94.3k
                if (plane_height == 0) {
1064
                    /* We are doing a copy mono */
1065
94.3k
                    depth = 1;
1066
94.3k
                } else {
1067
0
                    depth = tdev->color_info.depth;
1068
0
                }
1069
94.3k
                if_debug1m('L', mem, " plane_height=0x%x", plane_height);
1070
94.3k
                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
94.3k
              copy:cmd_getw(state.rect.x, cbp);
1079
94.3k
                cmd_getw(state.rect.y, cbp);
1080
94.3k
                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
93.1k
                    depth = state_slot->head.depth;
1091
93.1k
                    state.rect.width = state_slot->width;
1092
93.1k
                    state.rect.height = state_slot->height;
1093
93.1k
                    if (state.rect.y + state.rect.height > cdev->height)
1094
988
                        state.rect.height = cdev->height - state.rect.y; /* clamp as writer did */
1095
93.1k
                    raster = state_slot->raster;
1096
93.1k
                    source = (byte *) (state_slot + 1);
1097
93.1k
                } else {        /* Read width, height, bits. */
1098
                    /* depth was set already. */
1099
1.17k
                    uint width_bits, width_bytes;
1100
1.17k
                    uint bytes;
1101
1.17k
                    uchar planes = 1;
1102
1.17k
                    uint plane_depth = depth;
1103
1.17k
                    uint pln;
1104
1.17k
                    byte compression = op & 3;
1105
1.17k
                    uint out_bytes;
1106
1107
1.17k
                    cmd_getw(state.rect.width, cbp);
1108
1.17k
                    cmd_getw(state.rect.height, cbp);
1109
1.17k
                    if (plane_height != 0) {
1110
0
                        planes = tdev->color_info.num_components;
1111
0
                        plane_depth /= planes;
1112
0
                    }
1113
1.17k
                    width_bits = state.rect.width * plane_depth;
1114
1.17k
                    bytes = clist_bitmap_bytes(width_bits,
1115
1.17k
                                               state.rect.height,
1116
1.17k
                                               op & 3, &width_bytes,
1117
1.17k
                                               (uint *)&raster);
1118
1.17k
                    if (planes > 1) {
1119
0
                        out_bytes = raster * state.rect.height;
1120
0
                        plane_height = state.rect.height;
1121
1.17k
                    } else {
1122
1.17k
                        out_bytes = bytes;
1123
1.17k
                    }
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
2.34k
                    for (pln = 0; pln < planes; pln++) {
1139
1.17k
                        byte *plane_bits = data_bits + pln * plane_height * raster;
1140
1141
                        /* Fill the cbuf if needed to get the data for the plane */
1142
1.17k
                        if (cbp + out_bytes >= cbuf.warn_limit) {
1143
26
                            code = top_up_cbuf(&cbuf, &cbp);
1144
26
                            if (code < 0)
1145
0
                                goto top_up_failed;
1146
26
                        }
1147
1.17k
                        if (pln)
1148
0
                            compression = *cbp++;
1149
1150
1.17k
                        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
1.17k
                        } 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
1.17k
                        } else if ((state.rect.height > 1 && width_bytes != raster) ||
1210
1.17k
                                   (plane_height != 0)) {
1211
26
                            cbp = cmd_read_short_bits(&cbuf, plane_bits, bytes, width_bytes,
1212
26
                                                      state.rect.height, raster, cbp);
1213
26
                            if (pln == 0)
1214
26
                                source = data_bits;
1215
1.14k
                        } else {
1216
                            /* Never used for planar data */
1217
1.14k
                            cbp = cmd_read_data(&cbuf, cbuf.data, bytes, cbp);
1218
1.14k
                            source = cbuf.data;
1219
1.14k
                        }
1220
1.17k
                    }
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
1.17k
                }
1230
94.3k
                break;
1231
94.3k
            case cmd_op_delta_tile_index >> 4:
1232
25.4k
                state.tile_index += (int)(op & 0xf) - 8;
1233
25.4k
                goto sti;
1234
25.4k
            case cmd_op_set_tile_index >> 4:
1235
25.4k
                state.tile_index =
1236
25.4k
                    ((op & 0xf) << 8) + *cbp++;
1237
50.9k
              sti:state_slot =
1238
50.9k
                    (tile_slot *) (cdev->cache_chunk->data +
1239
50.9k
                                 cdev->tile_table[state.tile_index].offset);
1240
50.9k
                if_debug2m('L', mem, " index=%u offset=%lu\n",
1241
50.9k
                           state.tile_index,
1242
50.9k
                           cdev->tile_table[state.tile_index].offset);
1243
50.9k
                state_tile.data = (byte *) (state_slot + 1);
1244
89.4k
              stp:state_tile.size.x = state_slot->width;
1245
89.4k
                state_tile.size.y = state_slot->height;
1246
89.4k
                state_tile.raster = state_slot->raster;
1247
89.4k
                state_tile.rep_width = state_tile.size.x /
1248
89.4k
                    state_slot->x_reps;
1249
89.4k
                state_tile.rep_height = state_tile.size.y /
1250
89.4k
                    state_slot->y_reps;
1251
89.4k
                state_tile.rep_shift = state_slot->rep_shift;
1252
89.4k
                state_tile.shift = state_slot->shift;
1253
89.4k
                state_tile.id = state_slot->id;
1254
89.4k
                state_tile.num_planes = state_slot->num_planes;
1255
89.4k
set_tile_phase:
1256
89.4k
                if (state_tile.size.x)
1257
89.4k
                    tile_phase.x =
1258
89.4k
                        (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
89.4k
                if (state_tile.size.y) {
1264
89.4k
                    int full_height;
1265
1266
89.4k
                    if (state_tile.shift == 0)
1267
89.4k
                        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
89.4k
                    tile_phase.y = (state.tile_phase.y + y0) % full_height;
1274
89.4k
                }
1275
89.4k
                continue;
1276
292k
            case cmd_op_misc2 >> 4:
1277
292k
                switch (op) {
1278
0
                    case cmd_opv_set_bits_planar:
1279
0
                        goto do_opv_set_bits;
1280
248
                    case cmd_opv_set_fill_adjust:
1281
248
                        cmd_get_value(gs_gstate.fill_adjust.x, cbp);
1282
248
                        cmd_get_value(gs_gstate.fill_adjust.y, cbp);
1283
248
                        if_debug2m('L', mem, " (%g,%g)\n",
1284
248
                                   fixed2float(gs_gstate.fill_adjust.x),
1285
248
                                   fixed2float(gs_gstate.fill_adjust.y));
1286
248
                        continue;
1287
13.3k
                    case cmd_opv_set_ctm:
1288
13.3k
                        {
1289
13.3k
                            gs_matrix mat;
1290
1291
13.3k
                            cbp = cmd_read_matrix(&mat, cbp);
1292
13.3k
                            if_debug6m('L', mem, " [%g %g %g %g %g %g]\n",
1293
13.3k
                                       mat.xx, mat.xy, mat.yx, mat.yy,
1294
13.3k
                                       mat.tx, mat.ty);
1295
13.3k
                            mat.tx -= x0;
1296
13.3k
                            mat.ty -= y0;
1297
13.3k
                            gs_gstate_setmatrix(&gs_gstate, &mat);
1298
13.3k
                        }
1299
13.3k
                        continue;
1300
22.1k
                    case cmd_opv_set_misc2:
1301
22.1k
                        cbuf.ptr = cbp;
1302
22.1k
                        code = read_set_misc2(&cbuf, &gs_gstate, &notes);
1303
22.1k
                        cbp = cbuf.ptr;
1304
22.1k
                        if (code < 0)
1305
0
                            goto out;
1306
22.1k
                        continue;
1307
22.1k
                    case cmd_opv_set_dash:
1308
12
                        {
1309
12
                            int nb = *cbp++;
1310
12
                            int n = nb & 0x3f;
1311
12
                            float dot_length, offset;
1312
1313
12
                            cmd_get_value(dot_length, cbp);
1314
12
                            cmd_get_value(offset, cbp);
1315
12
                            memcpy(dash_pattern, cbp, n * sizeof(float));
1316
1317
12
                            gx_set_dash(&gs_gstate.line_params.dash,
1318
12
                                        dash_pattern, n, offset,
1319
12
                                        NULL);
1320
12
                            gx_set_dash_adapt(&gs_gstate.line_params.dash,
1321
12
                                              (nb & 0x80) != 0);
1322
12
                            gx_set_dot_length(&gs_gstate.line_params,
1323
12
                                              dot_length,
1324
12
                                              (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
12
                            cbp += n * sizeof(float);
1339
12
                        }
1340
12
                        break;
1341
263
                    case cmd_opv_enable_clip:
1342
263
                        pcpath = (use_clip ? &clip_path : NULL);
1343
263
                        if (pcpath) {
1344
0
                            code = gx_cpath_ensure_path_list(pcpath);
1345
0
                            if (code < 0)
1346
0
                                goto out;
1347
0
                        }
1348
263
                        if (clipper_dev_open)
1349
0
                            gx_destroy_clip_device_on_stack(&clipper_dev);
1350
263
                        clipper_dev_open = false;
1351
263
                        if_debug0m('L', mem, "\n");
1352
263
                        break;
1353
331
                    case cmd_opv_disable_clip:
1354
331
                        pcpath = NULL;
1355
331
                        if (clipper_dev_open)
1356
0
                            gx_destroy_clip_device_on_stack(&clipper_dev);
1357
331
                        clipper_dev_open = false;
1358
331
                        if_debug0m('L', mem, "\n");
1359
331
                        break;
1360
27.8k
                    case cmd_opv_begin_clip:
1361
27.8k
                        pcpath = NULL;
1362
27.8k
                        if (clipper_dev_open)
1363
2
                            gx_destroy_clip_device_on_stack(&clipper_dev);
1364
27.8k
                        clipper_dev_open = false;
1365
27.8k
                        in_clip = true;
1366
27.8k
                        if_debug0m('L', mem, "\n");
1367
27.8k
                        code = gx_cpath_reset(&clip_path);
1368
27.8k
                        if (code < 0)
1369
0
                            goto out;
1370
27.8k
                        gx_cpath_accum_begin(&clip_accum, mem, false);
1371
27.8k
                        gx_cpath_accum_set_cbox(&clip_accum,
1372
27.8k
                                                &target_box);
1373
27.8k
                        tdev = (gx_device *)&clip_accum;
1374
27.8k
                        clip_save.lop_enabled = state.lop_enabled;
1375
27.8k
                        clip_save.dcolor = fill_color;
1376
27.8k
                        clip_save.fa_save.x = gs_gstate.fill_adjust.x;
1377
27.8k
                        clip_save.fa_save.y = gs_gstate.fill_adjust.y;
1378
27.8k
                        cmd_getw(gs_gstate.fill_adjust.x, cbp);
1379
27.8k
                        cmd_getw(gs_gstate.fill_adjust.y, cbp);
1380
                        /* temporarily set a solid color */
1381
27.8k
                        color_set_pure(&fill_color, (gx_color_index)1);
1382
27.8k
                        state.lop_enabled = false;
1383
27.8k
                        gs_gstate.log_op = lop_default;
1384
27.8k
                        break;
1385
27.8k
                    case cmd_opv_end_clip:
1386
27.8k
                        if_debug0m('L', mem, "\n");
1387
27.8k
                        gx_cpath_accum_end(&clip_accum, &clip_path);
1388
27.8k
                        tdev = target;
1389
                        /*
1390
                         * If the entire band falls within the clip
1391
                         * path, no clipping is needed.
1392
                         */
1393
27.8k
                        {
1394
27.8k
                            gs_fixed_rect cbox;
1395
1396
27.8k
                            gx_cpath_inner_box(&clip_path, &cbox);
1397
27.8k
                            use_clip =
1398
27.8k
                                !(cbox.p.x <= target_box.p.x &&
1399
27.8k
                                  cbox.q.x >= target_box.q.x &&
1400
27.8k
                                  cbox.p.y <= target_box.p.y &&
1401
27.8k
                                  cbox.q.y >= target_box.q.y);
1402
27.8k
                        }
1403
27.8k
                        pcpath = (use_clip ? &clip_path : NULL);
1404
27.8k
                        if (pcpath) {
1405
9.42k
                            code = gx_cpath_ensure_path_list(pcpath);
1406
9.42k
                            if (code < 0)
1407
0
                                goto out;
1408
9.42k
                        }
1409
27.8k
                        if (clipper_dev_open)
1410
0
                            gx_destroy_clip_device_on_stack(&clipper_dev);
1411
27.8k
                        clipper_dev_open = false;
1412
27.8k
                        state.lop_enabled = clip_save.lop_enabled;
1413
27.8k
                        gs_gstate.log_op =
1414
27.8k
                            (state.lop_enabled ? state.lop :
1415
27.8k
                             lop_default);
1416
27.8k
                        fill_color = clip_save.dcolor;
1417
                        /* restore the fill_adjust if it was changed by begin_clip */
1418
27.8k
                        gs_gstate.fill_adjust.x = clip_save.fa_save.x;
1419
27.8k
                        gs_gstate.fill_adjust.y = clip_save.fa_save.y;
1420
27.8k
                        in_clip = false;
1421
27.8k
                        break;
1422
648
                    case cmd_opv_set_color_space:
1423
648
                        cbuf.ptr = cbp;
1424
648
                        code = read_set_color_space(&cbuf, &gs_gstate, cdev, mem);
1425
648
                        pcs = gs_gstate.color[0].color_space;
1426
648
                        cbp = cbuf.ptr;
1427
648
                        if (code < 0) {
1428
0
                            if (code == gs_error_rangecheck)
1429
0
                                goto bad_op;
1430
0
                            goto out;
1431
0
                        }
1432
648
                        break;
1433
648
                    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
635
                    case cmd_opv_begin_image_rect:
1456
635
                        cbuf.ptr = cbp;
1457
635
                        code = read_begin_image(&cbuf, &image.c, pcs);
1458
635
                        cbp = cbuf.ptr;
1459
635
                        if (code < 0)
1460
0
                            goto out;
1461
635
                        {
1462
635
                            uint diff;
1463
1464
635
                            cmd_getw(image_rect.p.x, cbp);
1465
635
                            cmd_getw(image_rect.p.y, cbp);
1466
635
                            cmd_getw(diff, cbp);
1467
635
                            image_rect.q.x = image.d.Width - diff;
1468
635
                            cmd_getw(diff, cbp);
1469
635
                            image_rect.q.y = image.d.Height - diff;
1470
635
                            if_debug4m('L', mem, " rect=(%d,%d),(%d,%d)",
1471
635
                                       image_rect.p.x, image_rect.p.y,
1472
635
                                       image_rect.q.x, image_rect.q.y);
1473
635
                        }
1474
635
                        goto ibegin;
1475
22
                    case cmd_opv_begin_image:
1476
22
                        cbuf.ptr = cbp;
1477
22
                        code = read_begin_image(&cbuf, &image.c, pcs);
1478
22
                        cbp = cbuf.ptr;
1479
22
                        if (code < 0)
1480
0
                            goto out;
1481
22
                        image_rect.p.x = 0;
1482
22
                        image_rect.p.y = 0;
1483
22
                        image_rect.q.x = image.d.Width;
1484
22
                        image_rect.q.y = image.d.Height;
1485
22
                        if_debug2m('L', mem, " size=(%d,%d)",
1486
22
                                  image.d.Width, image.d.Height);
1487
657
ibegin:                 if_debug0m('L', mem, "\n");
1488
657
                        {
1489
                            /* Processing an image operation */
1490
657
                            dev_proc(tdev, set_graphics_type_tag)(tdev, GS_IMAGE_TAG);/* FIXME: what about text bitmaps? */
1491
657
                            image.i4.override_in_smask = 0;
1492
657
                            code = (*dev_proc(tdev, begin_typed_image))
1493
657
                                (tdev, &gs_gstate, NULL,
1494
657
                                 (const gs_image_common_t *)&image,
1495
657
                                 &image_rect, &fill_color, pcpath, mem,
1496
657
                                 &image_info);
1497
657
                        }
1498
657
                        if (code < 0)
1499
0
                            goto out;
1500
657
                        break;
1501
657
                    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
1.33k
                    case cmd_opv_image_data:
1537
1.33k
                        cmd_getw(data_height, cbp);
1538
1.33k
                        if (data_height == 0) {
1539
657
                            if_debug0m('L', mem, " done image\n");
1540
657
                            code = gx_image_end(image_info, true);
1541
657
                            if (code < 0)
1542
0
                                goto out;
1543
657
                            continue;
1544
657
                        }
1545
681
                        {
1546
681
                            uint bytes_per_plane;
1547
681
                            int plane;
1548
1549
681
                            cmd_getw(bytes_per_plane, cbp);
1550
681
                            if_debug2m('L', mem, " height=%u raster=%u\n",
1551
681
                                       data_height, bytes_per_plane);
1552
681
                            for (plane = 0;
1553
1.36k
                                 plane < image_info->num_planes;
1554
681
                                 ++plane
1555
681
                                 ) {
1556
681
                                planes[plane].data_x = data_x;
1557
681
                                planes[plane].raster = bytes_per_plane;
1558
681
                            }
1559
681
                        }
1560
681
idata:                  data_size = 0;
1561
681
                        {
1562
681
                            int plane;
1563
1564
1.36k
                            for (plane = 0; plane < image_info->num_planes;
1565
681
                                 ++plane)
1566
681
                                data_size += planes[plane].raster;
1567
681
                        }
1568
681
                        data_size *= data_height;
1569
681
                        data_on_heap = 0;
1570
681
                        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
681
                        if (cbuf.end - cbp >= data_size) {
1576
681
                            planes[0].data = cbp;
1577
681
                            cbp += data_size;
1578
681
                        } 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
681
                        {
1605
681
                            int plane;
1606
681
                            const byte *data = planes[0].data;
1607
1608
681
                            for (plane = 0;
1609
1.36k
                                 plane < image_info->num_planes;
1610
681
                                 ++plane
1611
681
                                 ) {
1612
681
                                if (planes[plane].raster == 0)
1613
0
                                    planes[plane].data = 0;
1614
681
                                else {
1615
681
                                    planes[plane].data = data;
1616
681
                                    data += planes[plane].raster *
1617
681
                                        data_height;
1618
681
                                }
1619
681
                            }
1620
681
                        }
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
681
                        code = gx_image_plane_data(image_info, planes,
1637
681
                                                   data_height);
1638
681
                        if (code < 0)
1639
0
                            gx_image_end(image_info, false);
1640
681
                        if (data_on_heap)
1641
0
                            gs_free_object(mem, data_on_heap,
1642
681
                                           "clist image_data");
1643
681
                        data_x = 0;
1644
681
                        if (code < 0)
1645
0
                            goto out;
1646
681
                        continue;
1647
197k
                    case cmd_opv_extend:
1648
197k
                        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
14.1k
                            case cmd_opv_ext_composite:
1663
14.1k
                                if_debug0m('L', mem, " ext_composite\n");
1664
14.1k
                                cbuf.ptr = cbp;
1665
                                /*
1666
                                 * The screen phase may have been changed during
1667
                                 * the processing of masked images.
1668
                                 */
1669
14.1k
                                gx_gstate_setscreenphase(&gs_gstate,
1670
14.1k
                                            -x0, -y0, gs_color_select_all);
1671
14.1k
                                cbp -= 2; /* Step back to simplify the cycle invariant below. */
1672
223k
                                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
223k
                                    int len;
1678
1679
223k
                                    if (cbp >= cbuf.warn_limit) {
1680
21
                                        code = top_up_cbuf(&cbuf, &cbp);
1681
21
                                        if (code < 0)
1682
0
                                            goto out;
1683
21
                                    }
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
223k
                                    if (cbp[0] == cmd_opv_extend && cbp[1] == cmd_opv_ext_composite) {
1694
111k
                                        gs_composite_t *pcomp, *pcomp_opening;
1695
111k
                                        gs_compositor_closing_state closing_state;
1696
1697
111k
                                        cbuf.ptr = cbp += 2;
1698
111k
                                        code = read_composite(&cbuf, mem, &pcomp);
1699
111k
                                        if (code < 0)
1700
0
                                            goto out;
1701
111k
                                        cbp = cbuf.ptr;
1702
111k
                                        if (pcomp == NULL)
1703
0
                                            continue;
1704
111k
                                        if (gs_is_pdf14trans_compositor(pcomp) &&
1705
111k
                                            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
111k
                                        pcomp_opening = pcomp_last;
1712
111k
                                        closing_state = pcomp->type->procs.is_closing(pcomp, &pcomp_opening, tdev);
1713
111k
                                        switch(closing_state)
1714
111k
                                        {
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
21.5k
                                        case COMP_ENQUEUE:
1721
                                            /* Enqueue. */
1722
21.5k
                                            enqueue_compositor(&pcomp_first, &pcomp_last, pcomp);
1723
21.5k
                                            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
1.33k
                                        case COMP_EXEC_QUEUE:
1733
                                            /* The opening command was executed. Execute the queue. */
1734
1.33k
                                            enqueue_compositor(&pcomp_first, &pcomp_last, pcomp);
1735
1.33k
                                            code = execute_compositor_queue(cdev, &target, &tdev,
1736
1.33k
                                                &gs_gstate, &pcomp_first, &pcomp_last, pcomp_first, x0, y0, mem, false);
1737
1.33k
                                            if (code < 0)
1738
0
                                                goto out;
1739
1.33k
                                            break;
1740
1.33k
                                        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
87.8k
                                        case COMP_REPLACE_CURR:
1749
                                            /* Replace specific compositor. */
1750
87.8k
                                            code = dequeue_compositor(&pcomp_first, &pcomp_last, pcomp_opening);
1751
87.8k
                                            if (code < 0)
1752
0
                                                goto out;
1753
87.8k
                                            enqueue_compositor(&pcomp_first, &pcomp_last, pcomp);
1754
87.8k
                                            free_compositor(pcomp_opening, mem);
1755
87.8k
                                            break;
1756
955
                                        case COMP_DROP_QUEUE:
1757
                                            /* Annihilate the last compositors. */
1758
955
                                            enqueue_compositor(&pcomp_first, &pcomp_last, pcomp);
1759
955
                                            code = drop_compositor_queue(&pcomp_first, &pcomp_last, pcomp_opening, mem, x0, y0, &gs_gstate);
1760
955
                                            if (code < 0)
1761
0
                                                goto out;
1762
955
                                            break;
1763
955
                                        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
111k
                                        }
1768
111k
                                    } else if (is_null_compositor_op(cbp, &len)) {
1769
94.0k
                                        cbuf.ptr = cbp += len;
1770
94.0k
                                    } else if (cbp[0] == cmd_opv_end_page) {
1771
                                        /* End page, drop the queue. */
1772
5.37k
                                        code = execute_compositor_queue(cdev, &target, &tdev,
1773
5.37k
                                                &gs_gstate, &pcomp_first, &pcomp_last, pcomp_first, x0, y0, mem, true);
1774
5.37k
                                        if (code < 0)
1775
0
                                            goto out;
1776
5.37k
                                        break;
1777
11.9k
                                    } else if (pcomp_last != NULL &&
1778
11.9k
                                            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
3.23k
                                        uint cb;
1787
1788
3.23k
                                        switch (*cbp++) {
1789
368
                                            case cmd_opv_extend:
1790
368
                                                switch (*cbp++) {
1791
184
                                                    case cmd_opv_ext_put_halftone:
1792
184
                                                        {
1793
184
                                                            uint    ht_size;
1794
1795
184
                                                            enc_u_getw(ht_size, cbp);
1796
184
                                                            code = read_alloc_ht_buff(&ht_buff, ht_size, mem);
1797
184
                                                            if (code < 0)
1798
0
                                                                goto out;
1799
184
                                                        }
1800
184
                                                        break;
1801
184
                                                    case cmd_opv_ext_put_ht_seg:
1802
184
                                                        cbuf.ptr = cbp;
1803
184
                                                        code = read_ht_segment(&ht_buff, &cbuf,
1804
184
                                                                               &gs_gstate, tdev,
1805
184
                                                                               mem);
1806
184
                                                        cbp = cbuf.ptr;
1807
184
                                                        if (code < 0)
1808
0
                                                            goto out;
1809
184
                                                        break;
1810
184
                                                    default:
1811
0
                                                        code = gs_note_error(gs_error_unregistered); /* Must not happen. */
1812
0
                                                        goto out;
1813
368
                                                }
1814
368
                                                break;
1815
2.86k
                                            case cmd_opv_set_misc:
1816
2.86k
                                                cb = *cbp++;
1817
2.86k
                                                switch (cb >> 6) {
1818
2.86k
                                                    case cmd_set_misc_map >> 6:
1819
2.86k
                                                        cbuf.ptr = cbp;
1820
2.86k
                                                        code = read_set_misc_map(cb, &cbuf, &gs_gstate, mem);
1821
2.86k
                                                        if (code < 0)
1822
0
                                                            goto out;
1823
2.86k
                                                        cbp = cbuf.ptr;
1824
2.86k
                                                        break;
1825
0
                                                    default:
1826
0
                                                        code = gs_note_error(gs_error_unregistered); /* Must not happen. */
1827
0
                                                        goto out;
1828
2.86k
                                                }
1829
2.86k
                                                break;
1830
2.86k
                                            default:
1831
0
                                                code = gs_note_error(gs_error_unregistered); /* Must not happen. */
1832
0
                                                goto out;
1833
3.23k
                                        }
1834
8.75k
                                    } else {
1835
                                        /* A drawing command, execute entire queue. */
1836
8.75k
                                        code = execute_compositor_queue(cdev, &target, &tdev,
1837
8.75k
                                            &gs_gstate, &pcomp_first, &pcomp_last, pcomp_first, x0, y0, mem, false);
1838
8.75k
                                        if (code < 0)
1839
0
                                            goto out;
1840
8.75k
                                        break;
1841
8.75k
                                    }
1842
223k
                                }
1843
14.1k
                                if (pcomp_last != NULL) {
1844
0
                                    code = gs_note_error(gs_error_unregistered);
1845
0
                                    goto out;
1846
0
                                }
1847
14.1k
                                break;
1848
14.1k
                            case cmd_opv_ext_put_halftone:
1849
3.71k
                                {
1850
3.71k
                                    uint    ht_size;
1851
1852
3.71k
                                    if_debug0m('L', mem, " ext_put_halftone\n");
1853
3.71k
                                    enc_u_getw(ht_size, cbp);
1854
3.71k
                                    code = read_alloc_ht_buff(&ht_buff, ht_size, mem);
1855
3.71k
                                    if (code < 0)
1856
0
                                        goto out;
1857
3.71k
                                }
1858
3.71k
                                break;
1859
4.05k
                            case cmd_opv_ext_put_ht_seg:
1860
4.05k
                                if_debug0m('L', mem, " ext_put_ht_seg\n");
1861
4.05k
                                cbuf.ptr = cbp;
1862
4.05k
                                code = read_ht_segment(&ht_buff, &cbuf,
1863
4.05k
                                                       &gs_gstate, tdev,
1864
4.05k
                                                       mem);
1865
4.05k
                                cbp = cbuf.ptr;
1866
4.05k
                                if (code < 0)
1867
0
                                    goto out;
1868
4.05k
                                break;
1869
4.05k
                            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
162k
                            case cmd_opv_ext_put_fill_dcolor:
1892
162k
                                pdcolor = &fill_color;
1893
162k
                                goto load_dcolor;
1894
13.0k
                            case cmd_opv_ext_put_stroke_dcolor:
1895
13.0k
                                pdcolor = &stroke_color;
1896
13.0k
                                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
175k
                    load_dcolor:{
1903
175k
                                    uint    color_size;
1904
175k
                                    int left, offset, l;
1905
175k
                                    const gx_device_color_type_t *  pdct;
1906
175k
                                    byte type_and_flag = *cbp++;
1907
175k
                                    byte is_continuation = type_and_flag & 0x80;
1908
1909
175k
                                    if_debug0m('L', mem, " cmd_opv_ext_put_drawing_color\n");
1910
175k
                                    pdct = gx_get_dc_type_from_index(type_and_flag & 0x7F);
1911
175k
                                    if (pdct == 0) {
1912
0
                                        code = gs_note_error(gs_error_rangecheck);
1913
0
                                        goto out;
1914
0
                                    }
1915
175k
                                    offset = 0;
1916
175k
                                    if (is_continuation)
1917
175k
                                        enc_u_getw(offset, cbp);
1918
175k
                                    enc_u_getw(color_size, cbp);
1919
175k
                                    left = color_size;
1920
175k
                                    if (!left) {
1921
                                        /* We still need to call pdct->read because it may change dev_color.type -
1922
                                           see gx_dc_null_read.*/
1923
902
                                        code = pdct->read(pdcolor, &gs_gstate,
1924
902
                                                          pdcolor, tdev, offset,
1925
902
                                                          cbp, 0, mem, x0, y0);
1926
902
                                        if (code < 0)
1927
0
                                            goto out;
1928
902
                                    }
1929
1.42M
                                    while (left) {
1930
1.25M
                                        if (cbuf.warn_limit - cbp < (int)left) {  /* cbp can be past warn_limit */
1931
1.12M
                                            code = top_up_cbuf(&cbuf, &cbp);
1932
1.12M
                                            if (code < 0)
1933
0
                                                goto top_up_failed;
1934
1.12M
                                        }
1935
1.25M
                                        l = min(left, cbuf.end - cbp);
1936
1.25M
                                        code = pdct->read(pdcolor, &gs_gstate,
1937
1.25M
                                                          pdcolor, tdev, offset,
1938
1.25M
                                                          cbp, l, mem, x0, y0);
1939
1.25M
                                        if (code < 0)
1940
0
                                            goto out;
1941
1.25M
                                        l = code;
1942
1.25M
                                        cbp += l;
1943
1.25M
                                        offset += l;
1944
1.25M
                                        left -= l;
1945
1.25M
                                    }
1946
175k
                                    code = gx_color_load(pdcolor, &gs_gstate,
1947
175k
                                                         tdev);
1948
175k
                                    if (code < 0)
1949
0
                                        goto out;
1950
175k
                                }
1951
175k
                                break;
1952
175k
                            default:
1953
0
                                goto bad_op;
1954
197k
                        }
1955
197k
                        break;
1956
197k
                    default:
1957
0
                        goto bad_op;
1958
292k
                }
1959
255k
                continue;
1960
697k
            case cmd_op_segment >> 4:
1961
697k
                {
1962
697k
                    int i;
1963
697k
                    static const byte op_num_operands[] = {
1964
697k
                        cmd_segment_op_num_operands_values
1965
697k
                    };
1966
697k
                  rgapto:
1967
697k
                    if (!in_path) {
1968
74.7k
                        ppos.x = int2fixed(state.rect.x);
1969
74.7k
                        ppos.y = int2fixed(state.rect.y);
1970
74.7k
                        if_debug2m('L', mem, " (%d,%d)", state.rect.x,
1971
74.7k
                                   state.rect.y);
1972
74.7k
                        notes = sn_none;
1973
74.7k
                        in_path = true;
1974
74.7k
                    }
1975
2.71M
                    for (i = 0; i < op_num_operands[op & 0xf]; ++i) {
1976
2.01M
                        fixed v;
1977
2.01M
                        int b = *cbp;
1978
1979
2.01M
                        switch (b >> 5) {
1980
114k
                            case 0:
1981
223k
                            case 1:
1982
223k
                                vs[i++] =
1983
223k
                                    ((fixed) ((b ^ 0x20) - 0x20) << 13) +
1984
223k
                                    ((int)cbp[1] << 5) + (cbp[2] >> 3);
1985
223k
                                if_debug1m('L', mem, " %g", fixed2float(vs[i - 1]));
1986
223k
                                cbp += 2;
1987
223k
                                v = (int)((*cbp & 7) ^ 4) - 4;
1988
223k
                                break;
1989
449k
                            case 2:
1990
861k
                            case 3:
1991
861k
                                v = (b ^ 0x60) - 0x20;
1992
861k
                                break;
1993
365k
                            case 4:
1994
738k
                            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
738k
                                v = (((b ^ 0xa0) - 0x20) << 8) + (int)*++cbp;
2003
738k
                                break;
2004
173k
                            case 6:
2005
173k
                                v = (b ^ 0xd0) - 0x10;
2006
173k
                                vs[i] =
2007
173k
                                    ((v << 8) + cbp[1]) << (_fixed_shift - 2);
2008
173k
                                if_debug1m('L', mem, " %g", fixed2float(vs[i]));
2009
173k
                                cbp += 2;
2010
173k
                                continue;
2011
21.2k
                            default /*case 7 */ :
2012
21.2k
                                v = (int)(*++cbp ^ 0x80) - 0x80;
2013
42.4k
                                for (b = 0; b < sizeof(fixed) - 3; ++b)
2014
21.2k
                                    v = (v << 8) + *++cbp;
2015
21.2k
                                break;
2016
2.01M
                        }
2017
1.84M
                        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
1.84M
                        vs[i] = (v << 16) + (uint) (cbp[-2] << 8) + cbp[-1];
2022
1.84M
                        if_debug1m('L', mem, " %g", fixed2float(vs[i]));
2023
1.84M
                    }
2024
697k
                    if_debug0m('L', mem, "\n");
2025
697k
                    code = clist_decode_segment(&path, op, vs, &ppos,
2026
697k
                                                x0, y0, notes);
2027
697k
                    if (code < 0)
2028
0
                        goto out;
2029
697k
                }
2030
697k
                continue;
2031
697k
            case cmd_op_path >> 4:
2032
85.4k
                if (op == cmd_opv_rgapto)
2033
0
                    goto rgapto;
2034
85.4k
                else if (op == cmd_opv_lock_pattern) {
2035
6
                    gs_id id;
2036
6
                    int lock = *cbp++;
2037
6
                    cmd_get_value(id, cbp);
2038
6
                    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
6
                    code = gx_pattern_cache_entry_set_lock(&gs_gstate, id, lock);
2044
6
                    if (code == gs_error_undefined)
2045
0
                        code = 0;
2046
6
                    if (code < 0)
2047
0
                        goto out;
2048
6
                    continue;
2049
85.4k
                } else {
2050
85.4k
                    gx_path fpath;
2051
85.4k
                    gx_path *ppath = &path;
2052
2053
85.4k
                    if_debug0m('L', mem, "\n");
2054
                    /* if in clip, flatten path first */
2055
85.4k
                    if (in_clip) {
2056
2.44k
                        gx_path_init_local(&fpath, mem);
2057
2.44k
                        code = gx_path_add_flattened_accurate(&path, &fpath,
2058
2.44k
                                             gs_currentflat_inline(&gs_gstate),
2059
2.44k
                                             gs_gstate.accurate_curves);
2060
2.44k
                        if (code < 0)
2061
0
                            goto out;
2062
2.44k
                        ppath = &fpath;
2063
2.44k
                    }
2064
85.4k
                    switch (op) {
2065
54.6k
                        case cmd_opv_fill:
2066
54.6k
                            fill_params.rule = gx_rule_winding_number;
2067
54.6k
                            goto fill;
2068
1.31k
                        case cmd_opv_eofill:
2069
1.31k
                            fill_params.rule = gx_rule_even_odd;
2070
56.0k
                        fill:
2071
56.0k
                            fill_params.adjust = gs_gstate.fill_adjust;
2072
56.0k
                            fill_params.flatness = gs_gstate.flatness;
2073
56.0k
                            code = (*dev_proc(tdev, fill_path))(tdev, &gs_gstate, ppath,
2074
56.0k
                                                                &fill_params, &fill_color, pcpath);
2075
56.0k
                            break;
2076
1.97k
                        case cmd_opv_fill_stroke:
2077
1.97k
                            fill_params.rule = gx_rule_winding_number;
2078
1.97k
                            goto fill_stroke;
2079
2
                        case cmd_opv_eofill_stroke:
2080
2
                            fill_params.rule = gx_rule_even_odd;
2081
1.97k
                        fill_stroke:
2082
1.97k
                            fill_params.adjust = gs_gstate.fill_adjust;
2083
1.97k
                            fill_params.flatness = gs_gstate.flatness;
2084
1.97k
                            stroke_params.flatness = gs_gstate.flatness;
2085
1.97k
                            stroke_params.traditional = false;
2086
1.97k
                            code = (*dev_proc(tdev, fill_stroke_path))(tdev, &gs_gstate, ppath,
2087
1.97k
                                                                &fill_params, &fill_color,
2088
1.97k
                                                                &stroke_params, &stroke_color, pcpath);
2089
1.97k
                            break;
2090
26.9k
                        case cmd_opv_stroke:
2091
26.9k
                            stroke_params.flatness = gs_gstate.flatness;
2092
26.9k
                            stroke_params.traditional = false;
2093
26.9k
                            code = (*dev_proc(tdev, stroke_path))
2094
26.9k
                                                       (tdev, &gs_gstate,
2095
26.9k
                                                       ppath, &stroke_params,
2096
26.9k
                                                       &stroke_color, pcpath);
2097
26.9k
                            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
552
                        case cmd_opv_fill_trapezoid:
2103
552
                            {
2104
552
                                gs_fixed_edge left, right;
2105
552
                                fixed ybot, ytop;
2106
552
                                int options, swap_axes, wh;
2107
552
                                fixed x0f;
2108
552
                                fixed y0f;
2109
552
                                gx_device *ttdev = tdev;
2110
2111
552
                                if (pcpath != NULL && !clipper_dev_open) {
2112
2
                                    gx_make_clip_device_on_stack(&clipper_dev, pcpath, tdev);
2113
2
                                    clipper_dev_open = true;
2114
2
                                }
2115
552
                                if (clipper_dev_open)
2116
552
                                    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
552
                                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
552
                                cmd_getw(left.start.x, cbp);
2132
552
                                cmd_getw(left.start.y, cbp);
2133
552
                                cmd_getw(left.end.x, cbp);
2134
552
                                cmd_getw(left.end.y, cbp);
2135
552
                                cmd_getw(right.start.x, cbp);
2136
552
                                cmd_getw(right.start.y, cbp);
2137
552
                                cmd_getw(right.end.x, cbp);
2138
552
                                cmd_getw(right.end.y, cbp);
2139
552
                                cmd_getw(options, cbp);
2140
552
                                if (!(options & 4)) {
2141
552
                                    cmd_getw(ybot, cbp);
2142
552
                                    cmd_getw(ytop, cbp);
2143
552
                                } else
2144
0
                                    ytop = ybot = 0; /* Unused, but quiet gcc warning. */
2145
552
                                swap_axes = options & 1;
2146
552
                                wh = swap_axes ? tdev->width : tdev->height;
2147
552
                                x0f = int2fixed(swap_axes ? y0 : x0);
2148
552
                                y0f = int2fixed(swap_axes ? x0 : y0);
2149
552
                                left.start.x -= x0f;
2150
552
                                left.start.y -= y0f;
2151
552
                                left.end.x -= x0f;
2152
552
                                left.end.y -= y0f;
2153
552
                                right.start.x -= x0f;
2154
552
                                right.start.y -= y0f;
2155
552
                                right.end.x -= x0f;
2156
552
                                right.end.y -= y0f;
2157
552
                                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
552
                                    code = gx_default_fill_trapezoid(ttdev, &left, &right,
2240
552
                                        max(ybot - y0f, fixed_half),
2241
552
                                        min(ytop - y0f, int2fixed(wh)), swap_axes,
2242
552
                                        &fill_color, gs_gstate.log_op);
2243
552
                            }
2244
552
                           break;
2245
552
                        default:
2246
0
                            goto bad_op;
2247
85.4k
                    }
2248
85.4k
                    if (ppath != &path)
2249
2.44k
                        gx_path_free(ppath, "clist_render_band");
2250
85.4k
                }
2251
85.4k
                if (in_path) {  /* path might be empty! */
2252
74.7k
                    state.rect.x = fixed2int_var(ppos.x);
2253
74.7k
                    state.rect.y = fixed2int_var(ppos.y);
2254
74.7k
                    in_path = false;
2255
74.7k
                }
2256
85.4k
                gx_path_free(&path, "clist_render_band");
2257
85.4k
                gx_path_init_local(&path, mem);
2258
85.4k
                if (code < 0)
2259
0
                    goto out;
2260
85.4k
                continue;
2261
85.4k
            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
1.97M
        }
2277
1.97M
        if_debug4m('L', mem, " x=%d y=%d w=%d h=%d\n",
2278
535k
                  state.rect.x, state.rect.y, state.rect.width,
2279
535k
                  state.rect.height);
2280
535k
        switch (op >> 4) {
2281
154k
            case cmd_op_fill_rect >> 4:
2282
154k
                if (state.rect.width == 0 && state.rect.height == 0 &&
2283
154k
                    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
101k
                    code = (dev_proc(tdev, fillpage) == NULL ? 0 :
2287
101k
                            (*dev_proc(tdev, fillpage))(tdev, &gs_gstate,
2288
101k
                                                        &fill_color));
2289
101k
                    break;
2290
101k
                }
2291
256k
            case cmd_op_fill_rect_short >> 4:
2292
339k
            case cmd_op_fill_rect_tiny >> 4:
2293
339k
                if (!state.lop_enabled) {
2294
339k
                    code = (*dev_proc(tdev, fill_rectangle))
2295
339k
                        (tdev, state.rect.x - x0, state.rect.y - y0,
2296
339k
                         state.rect.width, state.rect.height,
2297
339k
                         state.colors[1]);
2298
339k
                    break;
2299
339k
                }
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
1
            case cmd_op_tile_rect >> 4:
2320
1
                if (state.rect.width == 0 && state.rect.height == 0 &&
2321
1
                    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
182
            case cmd_op_tile_rect_short >> 4:
2326
190
            case cmd_op_tile_rect_tiny >> 4:
2327
                /* Currently we don't use lop with strip_tile_rectangle. */
2328
190
                code = (*dev_proc(tdev, strip_tile_rectangle))
2329
190
                    (tdev, &state_tile,
2330
190
                     state.rect.x - x0, state.rect.y - y0,
2331
190
                     state.rect.width, state.rect.height,
2332
190
                     state.tile_colors[0], state.tile_colors[1],
2333
190
                     tile_phase.x, tile_phase.y);
2334
190
                break;
2335
94.3k
            case cmd_op_copy_mono_planes >> 4:
2336
94.3k
                if (state.lop_enabled) {
2337
0
                    pcolor = state.colors;
2338
0
                    log_op = state.lop;
2339
0
                    goto do_rop;
2340
0
                }
2341
94.3k
                if ((op & cmd_copy_use_tile) || pcpath != NULL) {       /*
2342
                                                                         * This call of copy_mono originated as a call
2343
                                                                         * of fill_mask.
2344
                                                                         */
2345
93.1k
                    code = gx_image_fill_masked
2346
93.1k
                        (tdev, source, data_x, raster, gx_no_bitmap_id,
2347
93.1k
                         state.rect.x - x0, state.rect.y - y0,
2348
93.1k
                         state.rect.width - data_x, state.rect.height,
2349
93.1k
                         &fill_color, 1, gs_gstate.log_op, pcpath);
2350
93.1k
                } else {
2351
1.17k
                    if (plane_height == 0) {
2352
1.17k
                        code = (*dev_proc(tdev, copy_mono))
2353
1.17k
                             (tdev, source, data_x, raster, gx_no_bitmap_id,
2354
1.17k
                              state.rect.x - x0, state.rect.y - y0,
2355
1.17k
                              state.rect.width - data_x, state.rect.height,
2356
1.17k
                              state.colors[0], state.colors[1]);
2357
1.17k
                    } 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
1.17k
                }
2365
94.3k
                plane_height = 0;
2366
94.3k
                data_x = 0;
2367
94.3k
                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
535k
        }
2401
535k
    }
2402
    /* Clean up before we exit. */
2403
101k
  out:
2404
101k
    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
101k
    ht_buff.ht_size = 0;
2410
101k
    ht_buff.read_size = 0;
2411
2412
101k
    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
101k
    gx_cpath_free(&clip_path, "clist_render_band exit");
2419
101k
    gx_path_free(&path, "clist_render_band exit");
2420
101k
    if (gs_gstate.pattern_cache != NULL) {
2421
1.01k
        gx_pattern_cache_free(gs_gstate.pattern_cache);
2422
1.01k
        gs_gstate.pattern_cache = NULL;
2423
1.01k
    }
2424
    /* Free the client color and device colors allocated upon entry */
2425
101k
    gs_free_object(mem, gs_gstate.color[0].ccolor, "clist_playback_band");
2426
101k
    gs_free_object(mem, gs_gstate.color[1].ccolor, "clist_playback_band");
2427
101k
    gs_free_object(mem, gs_gstate.color[0].dev_color, "clist_playback_band");
2428
101k
    gs_free_object(mem, gs_gstate.color[1].dev_color, "clist_playback_band");
2429
101k
    gs_gstate.color[0].ccolor = gs_gstate.color[1].ccolor = NULL;
2430
101k
    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
101k
    gx_monitor_enter(cdev->icc_cache_cl->lock);
2435
101k
    gs_gstate_release(&gs_gstate);
2436
101k
    gx_monitor_leave(cdev->icc_cache_cl->lock); /* done with increment, let everyone run */
2437
101k
    gs_free_object(mem, data_bits, "clist_playback_band(data_bits)");
2438
101k
    if (target != orig_target) {
2439
4.45k
        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
4.45k
        } else {
2448
            /* Ref count was 1. close the device and then free it */
2449
4.45k
            if (target->is_open)
2450
0
                dev_proc(target, close_device)(target);
2451
4.45k
            gs_free_object(target->memory, target, "gxclrast discard compositor");
2452
4.45k
        }
2453
4.45k
        target = orig_target;
2454
4.45k
    }
2455
101k
    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
101k
    if ((playback_action != playback_action_setup &&
2470
101k
        (cbp < cbuf.end || !seofp(s)) && (op != cmd_opv_end_page) )
2471
101k
        )
2472
0
        goto in;
2473
101k
    if (pfs.dev != NULL)
2474
0
        term_patch_fill_state(&pfs);
2475
101k
    rc_decrement(gs_gstate.color[0].color_space, "clist_playback_band");
2476
101k
    rc_decrement(gs_gstate.color[1].color_space, "clist_playback_band");
2477
101k
    gs_free_object(mem, cbuf_storage, "clist_playback_band(cbuf_storage)");
2478
101k
    gx_cpath_free(&clip_path, "clist_playback_band");
2479
101k
    if (pcpath != &clip_path)
2480
96.6k
        gx_cpath_free(pcpath, "clist_playback_band");
2481
101k
    if (clipper_dev_open)
2482
0
        gx_destroy_clip_device_on_stack(&clipper_dev);
2483
101k
    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
101k
}
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
1
{
2506
1
    const byte *cbp = pcb->ptr;
2507
1
    uint rep_width, rep_height;
2508
1
    uint pdepth;
2509
1
    byte bd = *cbp++;
2510
2511
1
    bits->head.depth = cmd_code_to_depth(bd);
2512
1
    if (for_pattern)
2513
1
        cmd_getw(bits->id, cbp);
2514
1
    cmd_getw(rep_width, cbp);
2515
1
    cmd_getw(rep_height, cbp);
2516
1
    if (bd & 0x20) {
2517
1
        cmd_getw(bits->x_reps, cbp);
2518
1
        bits->width = rep_width * bits->x_reps;
2519
1
    } else {
2520
0
        bits->x_reps = 1;
2521
0
        bits->width = rep_width;
2522
0
    }
2523
1
    if (bd & 0x40) {
2524
0
        cmd_getw(bits->y_reps, cbp);
2525
0
        bits->height = rep_height * bits->y_reps;
2526
1
    } else {
2527
1
        bits->y_reps = 1;
2528
1
        bits->height = rep_height;
2529
1
    }
2530
1
    if (bd & 0x80)
2531
1
        cmd_getw(bits->rep_shift, cbp);
2532
1
    else
2533
1
        bits->rep_shift = 0;
2534
1
    if (bd & 0x10)
2535
0
        bits->num_planes = *cbp++;
2536
1
    else
2537
1
        bits->num_planes = 1;
2538
1
    if_debug7('L', " depth=%d size=(%d,%d), rep_size=(%d,%d), rep_shift=%d, num_planes=%d\n",
2539
1
              bits->head.depth, bits->width,
2540
1
              bits->height, rep_width,
2541
1
              rep_height, bits->rep_shift, bits->num_planes);
2542
1
    bits->shift =
2543
1
        (bits->rep_shift == 0 ? 0 :
2544
1
         (bits->rep_shift * (bits->height / rep_height)) % rep_width);
2545
1
    pdepth = bits->head.depth;
2546
1
    if (bits->num_planes != 1)
2547
0
        pdepth /= bits->num_planes;
2548
1
    bits->raster = bitmap_raster(bits->width * pdepth);
2549
1
    pcb->ptr = cbp;
2550
1
    return 0;
2551
1
}
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
38.4k
{
2558
38.4k
    const byte *cbp = pcb->ptr;
2559
38.4k
    uint rep_width = bits->width / bits->x_reps;
2560
38.4k
    uint rep_height = bits->height / bits->y_reps;
2561
38.4k
    uint index;
2562
38.4k
    ulong offset;
2563
38.4k
    uint width_bits;
2564
38.4k
    uint width_bytes;
2565
38.4k
    uint raster;
2566
38.4k
    uint bytes;
2567
38.4k
    byte *data;
2568
38.4k
    tile_slot *slot;
2569
38.4k
    uint depth = bits->head.depth;
2570
2571
38.4k
    if (bits->num_planes != 1)
2572
0
        depth /= bits->num_planes;
2573
38.4k
    width_bits = rep_width * depth;
2574
2575
38.4k
    bytes = clist_bitmap_bytes(width_bits, rep_height * bits->num_planes,
2576
38.4k
                               compress |
2577
38.4k
                               (rep_width < bits->width ?
2578
38.4k
                                decompress_spread : 0) |
2579
38.4k
                               decompress_elsewhere,
2580
38.4k
                               &width_bytes,
2581
38.4k
                               (uint *)&raster);
2582
2583
38.4k
    cmd_getw(index, cbp);
2584
38.4k
    cmd_getw(offset, cbp);
2585
38.4k
    if_debug2m('L', mem, " index=%d offset=%lu\n", index, offset);
2586
38.4k
    pcls->tile_index = index;
2587
38.4k
    cdev->tile_table[pcls->tile_index].offset = offset;
2588
38.4k
    slot = (tile_slot *)(cdev->cache_chunk->data + offset);
2589
38.4k
    *pslot = slot;
2590
38.4k
    *slot = *bits;
2591
38.4k
    tile->data = data = (byte *)(slot + 1);
2592
#ifdef DEBUG
2593
    slot->index = pcls->tile_index;
2594
#endif
2595
38.4k
    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
38.4k
    } 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
6.39k
        stream_cursor_read r;
2605
6.39k
        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
6.39k
        uint cleft = pcb->end - cbp;
2611
2612
6.39k
        if (cleft < bytes && !pcb->end_status) {
2613
6
            uint nread = cbuf_size - cleft;
2614
2615
6
            advance_buffer(pcb, cbp);
2616
6
            pcb->end_status = sgets(pcb->s, pcb->data + cleft, nread, &nread);
2617
6
            set_cb_end(pcb, pcb->data + cleft + nread);
2618
6
            cbp = pcb->data;
2619
6
        }
2620
6.39k
        r.ptr = cbp - 1;
2621
6.39k
        r.limit = pcb->end - 1;
2622
6.39k
        w.ptr = data - 1;
2623
6.39k
        w.limit = w.ptr + bytes;
2624
6.39k
        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
6.39k
        case cmd_compress_cfe:
2635
6.39k
            {
2636
6.39k
                stream_CFD_state sstate;
2637
2638
6.39k
                clist_cfd_init(&sstate,
2639
6.39k
                               width_bytes << 3 /*width_bits */ ,
2640
6.39k
                               rep_height, mem);
2641
6.39k
                (*s_CFD_template.process)
2642
6.39k
                    ((stream_state *)&sstate, &r, &w, true);
2643
6.39k
                (*s_CFD_template.release)
2644
6.39k
                    ((stream_state *)&sstate);
2645
6.39k
            }
2646
6.39k
            break;
2647
0
        default:
2648
0
            return_error(gs_error_unregistered);
2649
6.39k
        }
2650
6.39k
        cbp = r.ptr + 1;
2651
32.0k
    } else if (rep_height * bits->num_planes > 1 && width_bytes != bits->raster) {
2652
31.6k
        cbp = cmd_read_short_bits(pcb, data, bytes,
2653
31.6k
                                  width_bytes, rep_height * bits->num_planes,
2654
31.6k
                                  bits->raster, cbp);
2655
31.6k
    } else {
2656
348
        cbp = cmd_read_data(pcb, data, bytes, cbp);
2657
348
    }
2658
38.4k
    if (bits->width > rep_width)
2659
2
        bits_replicate_horizontally(data,
2660
2
                                    rep_width * depth, rep_height * bits->num_planes,
2661
2
                                    bits->raster,
2662
2
                                    bits->width * depth,
2663
2
                                    bits->raster);
2664
38.4k
    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
38.4k
    pcb->ptr = cbp;
2673
38.4k
    return 0;
2674
38.4k
}
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
3.89k
{
2680
    /* free the existing buffer, if any (usually none) */
2681
3.89k
    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
3.89k
    if (ht_size > cbuf_ht_seg_max_size) {
2691
338
        pht_buff->pbuff = gs_alloc_bytes(mem, ht_size, "read_alloc_ht_buff");
2692
338
        if (pht_buff->pbuff == 0)
2693
0
            return_error(gs_error_VMerror);
2694
338
    }
2695
3.89k
    pht_buff->ht_size = ht_size;
2696
3.89k
    pht_buff->read_size = 0;
2697
3.89k
    pht_buff->pcurr = pht_buff->pbuff;
2698
3.89k
    return 0;
2699
3.89k
}
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
4.23k
{
2710
4.23k
    const byte *                cbp = pcb->ptr;
2711
4.23k
    const byte *                pbuff = 0;
2712
4.23k
    uint                        ht_size = pht_buff->ht_size, seg_size;
2713
4.23k
    int                         code = 0;
2714
2715
    /* get the segment size; refill command buffer if necessary */
2716
4.23k
    enc_u_getw(seg_size, cbp);
2717
4.23k
    if (pcb->warn_limit - cbp < (int)seg_size) { /* cbp can be past warn_limit */
2718
342
        code = top_up_cbuf(pcb, &cbp);
2719
342
        if (code < 0)
2720
0
            return code;
2721
342
        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
342
    }
2726
2727
4.23k
    if (pht_buff->pbuff == 0) {
2728
        /* if not separate buffer, must be only one segment */
2729
3.55k
        if (seg_size != ht_size)
2730
0
            return_error(gs_error_unknownerror);
2731
3.55k
        pbuff = cbp;
2732
3.55k
    } else {
2733
676
        if (seg_size + pht_buff->read_size > pht_buff->ht_size)
2734
0
            return_error(gs_error_unknownerror);
2735
676
        memcpy(pht_buff->pcurr, cbp, seg_size);
2736
676
        pht_buff->pcurr += seg_size;
2737
676
        if ((pht_buff->read_size += seg_size) == ht_size)
2738
338
            pbuff = pht_buff->pbuff;
2739
676
    }
2740
2741
    /* if everything has been read, convert back to a halftone */
2742
4.23k
    if (pbuff != 0) {
2743
3.89k
        code = gx_ht_read_and_install(pgs, dev, pbuff, ht_size, mem);
2744
2745
        /* release any buffered information */
2746
3.89k
        if (pht_buff->pbuff != 0) {
2747
338
            gs_free_object(mem, pht_buff->pbuff, "read_alloc_ht_buff");
2748
338
            pht_buff->pbuff = 0;
2749
338
            pht_buff->pcurr = 0;
2750
338
        }
2751
3.89k
        pht_buff->ht_size = 0;
2752
3.89k
        pht_buff->read_size = 0;
2753
3.89k
    }
2754
2755
    /* update the command buffer ponter */
2756
4.23k
    pcb->ptr = cbp + seg_size;
2757
2758
4.23k
    return code;
2759
4.23k
}
2760
2761
static int
2762
read_set_misc2(command_buf_t *pcb, gs_gstate *pgs, segment_notes *pnotes)
2763
22.1k
{
2764
22.1k
    const byte *cbp = pcb->ptr;
2765
22.1k
    uint mask, cb;
2766
2767
22.1k
    if_debug0m('L', pgs->memory, "\n");
2768
22.1k
    cmd_getw(mask, cbp);
2769
22.1k
    if (mask & cap_join_known) {
2770
7.49k
        cb = *cbp++;
2771
7.49k
        pgs->line_params.start_cap = (gs_line_cap)((cb >> 3) & 7);
2772
7.49k
        pgs->line_params.join = (gs_line_join)(cb & 7);
2773
7.49k
        if_debug2m('L', pgs->memory, "[L]      start_cap=%d join=%d\n",
2774
7.49k
                   pgs->line_params.start_cap, pgs->line_params.join);
2775
7.49k
        cb = *cbp++;
2776
7.49k
        pgs->line_params.end_cap = (gs_line_cap)((cb >> 3) & 7);
2777
7.49k
        pgs->line_params.dash_cap = (gs_line_cap)(cb & 7);
2778
7.49k
        if_debug2m('L', pgs->memory, "[L]      end_cap=%d dash_cap=%d\n",
2779
7.49k
                   pgs->line_params.end_cap, pgs->line_params.dash_cap);
2780
7.49k
    }
2781
22.1k
    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
22.1k
    if (mask & flatness_known) {
2791
192
        cmd_get_value(pgs->flatness, cbp);
2792
192
        if_debug1m('L', pgs->memory, "[L]      flatness=%g\n", pgs->flatness);
2793
192
    }
2794
22.1k
    if (mask & line_width_known) {
2795
13.8k
        float width;
2796
2797
13.8k
        cmd_get_value(width, cbp);
2798
13.8k
        if_debug1m('L', pgs->memory, "[L]      line_width=%g\n", width);
2799
13.8k
        gx_set_line_width(&pgs->line_params, width);
2800
13.8k
    }
2801
22.1k
    if (mask & miter_limit_known) {
2802
105
        float limit;
2803
2804
105
        cmd_get_value(limit, cbp);
2805
105
        if_debug1m('L', pgs->memory, "[L]      miter_limit=%g\n", limit);
2806
105
        gx_set_miter_limit(&pgs->line_params, limit);
2807
105
    }
2808
22.1k
    if (mask & op_bm_tk_known) {
2809
19.2k
        cb = *cbp++;
2810
19.2k
        pgs->blend_mode = cb >> 3;
2811
19.2k
        pgs->text_knockout = cb & 1;
2812
        /* the following usually have no effect; see gxclpath.c */
2813
19.2k
        cb = *cbp++;
2814
19.2k
        pgs->overprint_mode = (cb >> 2) & 1;
2815
19.2k
        pgs->stroke_overprint = (cb >> 1) & 1;
2816
19.2k
        pgs->overprint = cb & 1;
2817
19.2k
        cb = *cbp++;
2818
19.2k
        pgs->renderingintent = cb;
2819
19.2k
        if_debug6m('L', pgs->memory, "[L]      BM=%d TK=%d OPM=%d OP=%d op=%d RI=%d\n",
2820
19.2k
                   pgs->blend_mode, pgs->text_knockout, pgs->overprint_mode,
2821
19.2k
                   pgs->stroke_overprint, pgs->overprint, pgs->renderingintent);
2822
19.2k
    }
2823
22.1k
    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
22.1k
    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
22.1k
    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
22.1k
    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
22.1k
    pcb->ptr = cbp;
2841
22.1k
    return 0;
2842
22.1k
}
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
648
{
2848
648
    const byte *cbp = pcb->ptr;
2849
648
    byte b = *cbp++;
2850
648
    int index = b >> 4;
2851
648
    gs_color_space *pcs;
2852
648
    int code = 0;
2853
648
    cmm_profile_t *picc_profile;
2854
648
    clist_icc_color_t icc_information;
2855
2856
648
    if_debug3m('L', mem, " %d%s%s\n", index,
2857
648
               (b & 8 ? " (indexed)" : ""),
2858
648
               (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
648
    memcpy(&icc_information, cbp, sizeof(clist_icc_color_t));
2864
648
    cbp = cbp + sizeof(clist_icc_color_t);
2865
648
    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
648
    case gs_color_space_index_ICC:
2876
        /* build the color space object */
2877
648
        code = gs_cspace_build_ICC(&pcs, NULL, mem);
2878
        /* Don't bother getting the ICC stuff from the clist yet */
2879
648
        picc_profile = gsicc_profile_new(NULL, cdev->memory, NULL, 0);
2880
648
        if (picc_profile == NULL)
2881
0
            return gs_rethrow(-1, "Failed to find ICC profile during clist read");
2882
648
        picc_profile->num_comps = icc_information.icc_num_components;
2883
648
        picc_profile->hashcode = icc_information.icc_hash;
2884
648
        picc_profile->hash_is_valid = true;
2885
648
        picc_profile->islab = icc_information.is_lab;
2886
648
        picc_profile->default_match = icc_information.default_match;
2887
648
        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
648
        picc_profile->dev = (gx_device*) cdev;
2893
        /* Assign it to the colorspace */
2894
648
        code = gsicc_set_gscs_profile(pcs, picc_profile, mem);
2895
        /* And we no longer need our reference to the profile */
2896
648
        gsicc_adjust_profile_rc(picc_profile, -1, "read_set_color_space");
2897
648
        break;
2898
0
    default:
2899
0
        code = gs_note_error(gs_error_rangecheck);      /* others are NYI */
2900
0
        goto out;
2901
648
    }
2902
2903
648
    if (pcs == NULL) {
2904
0
        code = gs_note_error(gs_error_VMerror);
2905
0
        goto out;
2906
0
    }
2907
2908
648
    if (b & 8) {
2909
500
        bool use_proc = (b & 4) != 0;
2910
500
        int hival;
2911
500
        int num_values;
2912
500
        byte *data;
2913
500
        uint data_size;
2914
500
        gs_color_space *pcs_indexed;
2915
2916
500
        pcs_indexed = gs_cspace_alloc(mem, &gs_color_space_type_Indexed);
2917
500
        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
500
        pcs_indexed->base_space = pcs;
2923
500
        pcs = pcs_indexed;
2924
500
        pcs->params.indexed.use_proc = 0;
2925
500
        pcs->params.indexed.lookup.table.data = 0;
2926
500
        pcs->params.indexed.lookup.table.size = 0;
2927
500
        cmd_getw(hival, cbp);
2928
500
        pcs->params.indexed.n_comps = gs_color_space_num_components(pcs->base_space);
2929
500
        num_values = (hival + 1) * pcs->params.indexed.n_comps;
2930
500
        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
500
        } else {
2943
500
            byte *table = gs_alloc_string(mem, num_values, "color_space indexed table");
2944
2945
500
            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
500
            pcs->params.indexed.lookup.table.data = table;
2951
500
            pcs->params.indexed.lookup.table.size = num_values;
2952
500
            data = table;
2953
500
            data_size = num_values;
2954
500
        }
2955
500
        cbp = cmd_read_data(pcb, data, data_size, cbp);
2956
500
        pcs->params.indexed.hival = hival;
2957
500
        pcs->params.indexed.use_proc = use_proc;
2958
500
    }
2959
2960
    /* Release reference to old color space before installing new one. */
2961
648
    if (pgs->color[0].color_space != NULL)
2962
648
        rc_decrement_only_cs(pgs->color[0].color_space, "read_set_color_space");
2963
648
    pgs->color[0].color_space = pcs;
2964
648
out:
2965
648
    pcb->ptr = cbp;
2966
648
    return code;
2967
648
}
2968
2969
static int
2970
read_begin_image(command_buf_t *pcb, gs_image_common_t *pic,
2971
                 gs_color_space *pcs)
2972
657
{
2973
657
    uint index = *(pcb->ptr)++;
2974
657
    const gx_image_type_t *image_type = gx_image_type_table[index];
2975
657
    stream s;
2976
657
    int code;
2977
2978
    /* This is sloppy, but we don't have enough information to do better. */
2979
657
    code = top_up_cbuf(pcb, &pcb->ptr);
2980
657
    if (code < 0)
2981
0
        return code;
2982
657
    s_init(&s, NULL);
2983
657
    sread_string(&s, pcb->ptr, pcb->end - pcb->ptr);
2984
657
    code = image_type->sget(pic, &s, pcs);
2985
657
    pcb->ptr = sbufptr(&s);
2986
657
    pic->imagematrices_are_untrustworthy = 0;
2987
657
    return code;
2988
657
}
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
111k
{
3086
111k
    const byte *                cbp = pcb->ptr;
3087
111k
    int                         comp_id = 0, code = 0;
3088
111k
    const gs_composite_type_t * pcomp_type = 0;
3089
3090
    /* fill the command buffer (see comment above) */
3091
111k
    if (pcb->end - cbp < MAX_CLIST_COMPOSITOR_SIZE + sizeof(comp_id)) {
3092
40.5k
        code = top_up_cbuf(pcb, &cbp);
3093
40.5k
        if (code < 0)
3094
0
            return code;
3095
40.5k
    }
3096
3097
    /* find the appropriate compositor method vector */
3098
111k
    comp_id = *cbp++;
3099
111k
    if ((pcomp_type = gs_find_compositor(comp_id)) == 0)
3100
0
        return_error(gs_error_unknownerror);
3101
3102
    /* de-serialize the compositor */
3103
111k
    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
111k
    if ( code > MAX_CLIST_COMPOSITOR_SIZE )
3107
0
        return_error(gs_error_rangecheck);
3108
3109
111k
    if (code > 0)
3110
111k
        cbp += code;
3111
111k
    pcb->ptr = cbp;
3112
111k
    return code;
3113
111k
}
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
20.6k
{
3119
20.6k
    gx_device *tdev = *ptarget;
3120
20.6k
    int code;
3121
3122
20.6k
    code = pcomp->type->procs.adjust_ctm(pcomp, x0, y0, pgs);
3123
20.6k
    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
20.6k
    code = dev_proc(tdev, composite)(tdev, &tdev, pcomp, pgs, mem, (gx_device*) cdev);
3130
20.6k
    if (code == 1) {
3131
        /* A new compositor was created that wrapped tdev. This should
3132
         * be our new target. */
3133
4.45k
        *ptarget = tdev;
3134
4.45k
        code = 0;
3135
4.45k
    }
3136
20.6k
    if (code < 0)
3137
0
        goto exit;
3138
3139
    /* Perform any updates for the clist device required */
3140
20.6k
    code = pcomp->type->procs.clist_compositor_read_update(pcomp,
3141
20.6k
                                        (gx_device *)cdev, tdev, pgs, mem);
3142
20.6k
exit:
3143
    /* free the compositor object */
3144
20.6k
    gs_free_object(mem, pcomp, "read_composite");
3145
3146
20.6k
    return code;
3147
20.6k
}
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
31.7k
{
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
31.7k
    cbp = cmd_read_data(pcb, data, tot_bytes, cbp);
3166
3167
    /* if needed, adjust buffer contents for dest raster > width_bytes */
3168
31.7k
    if (width_bytes < raster) {
3169
31.7k
        const byte *pdata = data /*src*/ + width_bytes * height;
3170
31.7k
        byte *udata = data /*dest*/ + height * raster;
3171
3172
514k
        while (--height > 0) { /* don't need to move the first line to itself */
3173
482k
            udata -= raster, pdata -= width_bytes;
3174
482k
            switch (width_bytes) {
3175
0
                default:
3176
0
                    memmove(udata, pdata, width_bytes);
3177
0
                    break;
3178
27
                case 6:
3179
27
                    udata[5] = pdata[5];
3180
1.21k
                case 5:
3181
1.21k
                    udata[4] = pdata[4];
3182
1.52k
                case 4:
3183
1.52k
                    udata[3] = pdata[3];
3184
43.9k
                case 3:
3185
43.9k
                    udata[2] = pdata[2];
3186
384k
                case 2:
3187
384k
                    udata[1] = pdata[1];
3188
482k
                case 1:
3189
482k
                    udata[0] = pdata[0];
3190
482k
                case 0:;            /* shouldn't happen */
3191
482k
            }
3192
482k
        }
3193
31.7k
    }
3194
31.7k
    return cbp;
3195
31.7k
}
3196
3197
/* Read a rectangle. */
3198
static const byte *
3199
cmd_read_rect(int op, gx_cmd_rect * prect, const byte * cbp)
3200
154k
{
3201
154k
    cmd_getw(prect->x, cbp);
3202
154k
    if (op & 0xf)
3203
26.6k
        prect->y += ((op >> 2) & 3) - 2;
3204
127k
    else {
3205
127k
        cmd_getw(prect->y, cbp);
3206
127k
    }
3207
154k
    cmd_getw(prect->width, cbp);
3208
154k
    if (op & 0xf)
3209
26.6k
        prect->height += (op & 3) - 2;
3210
127k
    else {
3211
127k
        cmd_getw(prect->height, cbp);
3212
127k
    }
3213
154k
    return cbp;
3214
154k
}
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
19.9k
{
3232
19.9k
    gx_transfer_map *map;
3233
19.9k
    gx_transfer_map **pmap;
3234
19.9k
    const char *cname;
3235
3236
19.9k
    *pcomp_num = NULL;          /* Only used for color transfer maps */
3237
19.9k
    switch (map_index) {
3238
6.64k
        case cmd_map_transfer:
3239
6.64k
            if_debug0m('L', mem, " transfer");
3240
6.64k
            rc_unshare_struct(pgs->set_transfer.gray, gx_transfer_map,
3241
6.64k
                &st_transfer_map, mem, return_error(gs_error_VMerror),
3242
6.64k
                "cmd_select_map(default_transfer)");
3243
6.64k
            map = pgs->set_transfer.gray;
3244
            /* Release all current maps */
3245
6.64k
            rc_decrement(pgs->set_transfer.red, "cmd_select_map(red)");
3246
6.64k
            pgs->set_transfer.red = NULL;
3247
6.64k
            pgs->set_transfer.red_component_num = -1;
3248
6.64k
            rc_decrement(pgs->set_transfer.green, "cmd_select_map(green)");
3249
6.64k
            pgs->set_transfer.green = NULL;
3250
6.64k
            pgs->set_transfer.green_component_num = -1;
3251
6.64k
            rc_decrement(pgs->set_transfer.blue, "cmd_select_map(blue)");
3252
6.64k
            pgs->set_transfer.blue = NULL;
3253
6.64k
            pgs->set_transfer.blue_component_num = -1;
3254
6.64k
            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
6.64k
transfer2:  if (cont != cmd_map_other) {
3276
2.87k
                gx_set_identity_transfer(map);
3277
2.87k
                *pmdata = 0;
3278
2.87k
                *pcount = 0;
3279
2.87k
                return 0;
3280
2.87k
            }
3281
3.77k
            break;
3282
6.64k
        case cmd_map_black_generation:
3283
6.64k
            if_debug0m('L', mem, " black generation");
3284
6.64k
            pmap = &pgs->black_generation;
3285
6.64k
            cname = "cmd_select_map(black generation)";
3286
6.64k
            goto alloc;
3287
6.64k
        case cmd_map_undercolor_removal:
3288
6.64k
            if_debug0m('L', mem, " undercolor removal");
3289
6.64k
            pmap = &pgs->undercolor_removal;
3290
6.64k
            cname = "cmd_select_map(undercolor removal)";
3291
13.2k
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
13.2k
            rc_unshare_struct(*pmap, gx_transfer_map, &st_transfer_map,
3299
13.2k
                              mem, return_error(gs_error_VMerror), cname);
3300
13.2k
            map = *pmap;
3301
13.2k
            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
13.2k
            break;
3308
13.2k
        default:
3309
0
            *pmdata = 0;
3310
0
            return 0;
3311
19.9k
    }
3312
17.0k
    map->proc = gs_mapped_transfer;
3313
17.0k
    *pmdata = map->values;
3314
17.0k
    *pcount = sizeof(map->values);
3315
17.0k
    return 0;
3316
19.9k
}
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
697k
{
3401
697k
    fixed px = ppos->x - int2fixed(x0);
3402
697k
    fixed py = ppos->y - int2fixed(y0);
3403
697k
    int code;
3404
3405
981k
#define A vs[0]
3406
838k
#define B vs[1]
3407
697k
#define C vs[2]
3408
697k
#define D vs[3]
3409
843k
#define E vs[4]
3410
843k
#define F vs[5]
3411
3412
697k
    switch (op) {
3413
80.4k
        case cmd_opv_rmoveto:
3414
80.4k
            code = gx_path_add_point(ppath, px += A, py += B);
3415
80.4k
            break;
3416
87.6k
        case cmd_opv_rlineto:
3417
87.6k
            code = gx_path_add_line_notes(ppath, px += A, py += B, notes);
3418
87.6k
            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
108k
        case cmd_opv_hlineto:
3423
108k
            code = gx_path_add_line_notes(ppath, px += A, py, notes);
3424
108k
            break;
3425
40.3k
        case cmd_opv_vlineto:
3426
40.3k
            code = gx_path_add_line_notes(ppath, px, py += A, notes);
3427
40.3k
            break;
3428
13.7k
        case cmd_opv_rmlineto:
3429
13.7k
            if ((code = gx_path_add_point(ppath, px += A, py += B)) < 0)
3430
0
                break;
3431
13.7k
            code = gx_path_add_line_notes(ppath, px += C, py += D, notes);
3432
13.7k
            break;
3433
7.98k
        case cmd_opv_rm2lineto:
3434
7.98k
            if ((code = gx_path_add_point(ppath, px += A, py += B)) < 0 ||
3435
7.98k
                (code = gx_path_add_line_notes(ppath, px += C, py += D,
3436
7.98k
                                               notes)) < 0
3437
7.98k
                )
3438
0
                break;
3439
7.98k
            code = gx_path_add_line_notes(ppath, px += E, py += F, notes);
3440
7.98k
            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
269k
        case cmd_opv_rrcurveto: /* a b c d e f => a b a+c b+d a+c+e b+d+f */
3452
269k
rrc:        E += (C += A);
3453
269k
            F += (D += B);
3454
278k
curve:      code = gx_path_add_curve_notes(ppath, px + A, py + B,
3455
278k
                                           px + C, py + D,
3456
278k
                                           px + E, py + F, notes);
3457
278k
            px += E, py += F;
3458
278k
            break;
3459
5.57k
        case cmd_opv_hvcurveto: /* a b c d => a 0 a+b c a+b c+d */
3460
5.57k
hvc:        F = C + D, D = C, E = C = A + B, B = 0;
3461
5.57k
            goto curve;
3462
2.51k
        case cmd_opv_vhcurveto: /* a b c d => 0 a b a+c b+d a+c */
3463
2.51k
vhc:        E = B + D, F = D = A + C, C = B, B = A, A = 0;
3464
2.51k
            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
582
        case cmd_opv_rncurveto: /* a b c d => a b a+c b+d a+c b+d */
3469
582
            F = D += B, E = C += A;
3470
582
            goto curve;
3471
4
        case cmd_opv_vqcurveto: /* a b => VH a b TS(a,b) TS(b,a) */
3472
4
            if ((A ^ B) < 0)
3473
4
                C = -B, D = -A;
3474
0
            else
3475
0
                C = B, D = A;
3476
4
            goto vhc;
3477
2
        case cmd_opv_hqcurveto: /* a b => HV a TS(a,b) b TS(b,a) */
3478
2
            if ((A ^ B) < 0)
3479
2
                D = -A, C = B, B = -B;
3480
0
            else
3481
0
                D = A, C = B;
3482
2
            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
80.5k
        case cmd_opv_closepath:
3498
80.5k
            if ((code = gx_path_close_subpath(ppath)) < 0)
3499
80.5k
                return code;;
3500
80.5k
            if ((code = gx_path_current_point(ppath, (gs_fixed_point *) vs)) < 0)
3501
80.5k
                return code;;
3502
80.5k
            px = A, py = B;
3503
80.5k
            break;
3504
0
        default:
3505
0
            return_error(gs_error_rangecheck);
3506
697k
    }
3507
697k
#undef A
3508
697k
#undef B
3509
697k
#undef C
3510
697k
#undef D
3511
697k
#undef E
3512
697k
#undef F
3513
697k
    ppos->x = px + int2fixed(x0);
3514
697k
    ppos->y = py + int2fixed(y0);
3515
697k
    return code;
3516
697k
}
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
}