Coverage Report

Created: 2025-06-10 06:56

/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.05M
  BEGIN\
91
1.05M
    if ( *p < 0x80 ) var = *p++;\
92
1.05M
    else { const byte *_cbp; var = cmd_get_w(p, &_cbp); p = _cbp; }\
93
1.05M
  END
94
95
static long
96
cmd_get_w(const byte * p, const byte ** rp)
97
235k
{
98
235k
    int val = *p++ & 0x7f;
99
235k
    int shift = 7;
100
101
236k
    for (; val |= (int)(*p & 0x7f) << shift, *p++ > 0x7f; shift += 7);
102
235k
    *rp = p;
103
235k
    return val;
104
235k
}
105
106
/* Get a variable-length fractional operand. */
107
#define cmd_getfrac(var, p)\
108
1.20k
  BEGIN\
109
1.20k
    if ( !(*p & 1) ) var = (*p++) << 24;\
110
1.20k
    else { const byte *_cbp; var = cmd_get_frac31(p, &_cbp); p = _cbp; }\
111
1.20k
  END
112
static frac31
113
cmd_get_frac31(const byte * p, const byte ** rp)
114
184
{
115
184
    frac31 val = (*p++ & 0xFE) << 24;
116
184
    int shift = 24 - 7;
117
118
336
    for (; val |= (frac31)(*p & 0xFE) << shift, *p++ & 1; shift -= 7);
119
184
    *rp = p;
120
184
    return val;
121
184
}
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
101k
{
144
101k
    pcb->end = end;
145
101k
    pcb->warn_limit = pcb->data + (pcb->size - cmd_largest_size + 1);
146
101k
    if ( pcb->warn_limit > pcb->end )
147
3.46k
        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
101k
}
151
152
static inline void
153
advance_buffer(command_buf_t *pcb, const byte *cbp)
154
98.1k
{
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
98.1k
    memmove(pcb->data, cbp, pcb->end - cbp);
161
98.1k
}
162
163
static inline void
164
next_is_skip(command_buf_t *pcb)
165
116
{
166
#ifdef DEBUG
167
    stream_state *st = pcb->s->state;
168
169
    offset_map_next_data_out_of_band(st);
170
#endif
171
116
}
172
173
/* Read more data into a command buffer. */
174
static int
175
top_up_cbuf(command_buf_t *pcb, const byte **pcbp)
176
106k
{
177
106k
    uint nread;
178
106k
    const byte *cbp = *pcbp;
179
106k
    byte *cb_top = pcb->data + (pcb->end - cbp);
180
181
106k
    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
106k
    if (seofp(pcb->s)) {
187
        /* Can't use offset_map, because s_close resets s->state. Don't top up. */
188
8.22k
        pcb->end_status = pcb->s->end_status;
189
8.22k
        return 0;
190
8.22k
    }
191
98.1k
    advance_buffer(pcb, cbp);
192
98.1k
    nread = pcb->end - cb_top;
193
98.1k
    pcb->end_status = sgets(pcb->s, cb_top, nread, &nread);
194
98.1k
    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
98.1k
    set_cb_end(pcb, cb_top + nread);
206
98.1k
    process_interrupts(pcb->s->memory);
207
98.1k
    *pcbp = pcb->data;
208
98.1k
    return 0;
209
98.1k
}
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
4.23k
{
217
4.23k
    if (pcb->end - cbp >= rsize) {
218
4.14k
        memmove(ptr, cbp, rsize);
219
4.14k
        return cbp + rsize;
220
4.14k
    } else {
221
83
        uint cleft = pcb->end - cbp;
222
83
        uint rleft = rsize - cleft;
223
224
83
        memmove(ptr, cbp, cleft);
225
83
        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
83
        return pcb->end;
234
83
    }
235
4.23k
}
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
11.2k
{
241
11.2k
    memcpy(pvar, cbp, var_size);
242
11.2k
    return cbp + var_size;
243
11.2k
}
244
#define cmd_get_value(var, cbp)\
245
11.2k
  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
310k
{
304
310k
    if (*ppcomp_last == NULL) {
305
33.7k
        pcomp->prev = pcomp->next = NULL;
306
33.7k
        *ppcomp_last = *ppcomp_first = pcomp;
307
276k
    } else {
308
276k
        (*ppcomp_last)->next = pcomp;
309
276k
        pcomp->prev = *ppcomp_last;
310
276k
        pcomp->next = NULL;
311
276k
        *ppcomp_last = pcomp;
312
276k
    }
313
310k
}
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
310k
{
350
310k
    if (*ppcomp_last == *ppcomp_first) {
351
33.7k
        if (*ppcomp_last == pcomp) {
352
33.7k
            *ppcomp_last = *ppcomp_first = NULL;
353
33.7k
            return 0;
354
33.7k
        } else
355
0
            return_error(gs_error_unregistered); /* Must not happen. */
356
276k
    } else {
357
276k
        gs_composite_t *pcomp_next = pcomp->next, *pcomp_prev = pcomp->prev;
358
359
276k
        if (*ppcomp_last == pcomp)
360
7.44k
            *ppcomp_last = pcomp->prev;
361
268k
        else
362
268k
            pcomp_next->prev = pcomp_prev;
363
276k
        if (*ppcomp_first == pcomp)
364
268k
            *ppcomp_first = pcomp->next;
365
7.44k
        else
366
7.44k
            pcomp_prev->next = pcomp_next;
367
276k
        pcomp->next = pcomp->prev = NULL;
368
276k
        return 0;
369
276k
    }
370
310k
}
371
372
static inline void
373
free_compositor(gs_composite_t *pcomp, gs_memory_t *mem)
374
11.1k
{
375
11.1k
    gs_free_object(mem, pcomp, "free_compositor");
376
11.1k
}
377
378
static inline bool
379
is_null_compositor_op(const byte *cbp, int *length)
380
172k
{
381
172k
    if (cbp[0] == cmd_opv_end_run) {
382
141k
        *length = 1;
383
141k
        return true;
384
141k
    }
385
30.2k
    return false;
386
172k
}
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
30.1k
{
393
329k
    while (pcomp_from != NULL) {
394
298k
        gs_composite_t *pcomp = pcomp_from;
395
298k
        int code;
396
397
298k
        pcomp_from = pcomp->next;
398
298k
        code = dequeue_compositor(ppcomp_first, ppcomp_last, pcomp);
399
298k
        if (code < 0)
400
0
            return code;
401
298k
        pcomp->idle |= idle;
402
298k
        code = apply_composite(cdev, pgs, mem, pcomp, x0, y0, target); /* Releases the compositor. */
403
298k
        if (code < 0)
404
0
            return code;
405
298k
        *tdev = *target;
406
298k
    }
407
30.1k
    return 0;
408
30.1k
}
409
410
static void
411
mark_as_idle(gs_composite_t *pcomp_start, gs_composite_t *pcomp_end)
412
567
{
413
567
    gs_composite_t *pcomp = pcomp_start;
414
415
1.20k
    while (pcomp != NULL) {
416
1.20k
        pcomp->idle = true;
417
1.20k
        if (pcomp == pcomp_end)
418
567
            break;
419
634
        pcomp = pcomp->next;
420
634
    }
421
567
}
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
61
{
428
61
    gs_composite_t *pcomp;
429
430
328
    do {
431
328
        int code;
432
433
328
        pcomp = *ppcomp_last;
434
328
        if (pcomp == NULL)
435
0
            return 0;
436
328
        dequeue_compositor(ppcomp_first, ppcomp_last, *ppcomp_last);
437
328
        code = pcomp->type->procs.adjust_ctm(pcomp, x0, y0, pgs);
438
328
        if (code < 0)
439
0
            return code;
440
328
        free_compositor(pcomp, mem);
441
328
    } while (pcomp != pcomp_from);
442
61
    return 0;
443
61
}
444
445
static int
446
read_set_misc_map(byte cb, command_buf_t *pcb, gs_gstate *pgs, gs_memory_t *mem)
447
3.86k
{
448
3.86k
    const byte *cbp = pcb->ptr;
449
3.86k
    frac *mdata;
450
3.86k
    int *pcomp_num;
451
3.86k
    uint count = 0;   /* quiet compiler */
452
3.86k
    cmd_map_contents cont =
453
3.86k
        (cmd_map_contents)(cb & 0x30) >> 4;
454
3.86k
    int code;
455
456
3.86k
    code = cmd_select_map(cb & 0xf, cont,
457
3.86k
                          pgs,
458
3.86k
                          &pcomp_num,
459
3.86k
                          &mdata, &count, mem);
460
461
3.86k
    if (code < 0)
462
0
        return code;
463
    /* Get component number if relevant */
464
3.86k
    if (pcomp_num == NULL)
465
3.85k
        cbp++;
466
6
    else {
467
6
        *pcomp_num = (int) *cbp++;
468
6
        if_debug1m('L', mem, " comp_num=%d", *pcomp_num);
469
6
    }
470
3.86k
    if (cont == cmd_map_other) {
471
2.77k
        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
2.77k
    }
485
    /* Recompute the effective transfer, */
486
    /* in case this was a transfer map. */
487
3.86k
    gx_gstate_set_effective_xfer(pgs);
488
3.86k
    pcb->ptr = cbp;
489
3.86k
    return 0;
490
3.86k
}
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
3.46k
{
516
3.46k
    byte *cbuf_storage;
517
3.46k
    command_buf_t cbuf;
518
    /* data_bits is for short copy_* bits and copy_* compressed, */
519
    /* must be aligned */
520
3.46k
    byte *data_bits = 0;
521
3.46k
    const byte *cbp;
522
3.46k
    int dev_depth;              /* May vary due to compositing devices */
523
3.46k
    int dev_depth_bytes;
524
3.46k
    int odd_delta_shift;
525
3.46k
    int num_zero_bytes;
526
3.46k
    gx_device *tdev;
527
3.46k
    gx_clist_state state;
528
3.46k
    gx_color_index *set_colors;
529
3.46k
    gx_device_color *set_dev_colors;
530
3.46k
    tile_slot *state_slot;
531
3.46k
    gx_strip_bitmap state_tile; /* parameters for reading tiles */
532
3.46k
    tile_slot tile_bits;        /* parameters of current tile */
533
3.46k
    gs_int_point tile_phase;
534
3.46k
    gx_path path;
535
3.46k
    bool in_path;
536
3.46k
    gs_fixed_point ppos;
537
3.46k
    gx_clip_path clip_path;
538
3.46k
    bool use_clip;
539
3.46k
    gx_clip_path *pcpath;
540
3.46k
    gx_device_cpath_accum clip_accum;
541
3.46k
    gs_fixed_rect target_box;
542
3.46k
    struct _cas {
543
3.46k
        bool lop_enabled;
544
3.46k
        gx_device_color dcolor;
545
3.46k
        gs_fixed_point fa_save;
546
3.46k
    } clip_save;
547
3.46k
    bool in_clip = false;
548
3.46k
    gs_gstate gs_gstate;
549
3.46k
    gx_device_color fill_color = { 0 };
550
3.46k
    gx_device_color stroke_color = { 0 };
551
3.46k
    float dash_pattern[cmd_max_dash];
552
3.46k
    gx_fill_params fill_params;
553
3.46k
    gx_stroke_params stroke_params;
554
#ifdef DEBUG
555
    gs_halftone_type halftone_type;
556
#endif
557
3.46k
    union im_ {
558
3.46k
        gs_image_common_t c;
559
3.46k
        gs_data_image_t d;
560
3.46k
        gs_image1_t i1;
561
3.46k
        gs_image4_t i4;
562
3.46k
    } image;
563
3.46k
    gs_int_rect image_rect;
564
3.46k
    gs_color_space *pcs = NULL;
565
3.46k
    gx_image_enum_common_t *image_info;
566
3.46k
    gx_image_plane_t planes[32];
567
3.46k
    uint data_height;
568
3.46k
    uint data_size;
569
3.46k
    byte *data_on_heap;
570
3.46k
    fixed vs[6];
571
3.46k
    segment_notes notes;
572
3.46k
    int data_x;
573
3.46k
    int code = 0;
574
3.46k
    ht_buff_t  ht_buff;
575
3.46k
    gx_device *const orig_target = target;
576
3.46k
    gx_device_clip clipper_dev;
577
3.46k
    bool clipper_dev_open = false;
578
3.46k
    patch_fill_state_t pfs;
579
3.46k
    int op = 0;
580
3.46k
    int plane_height = 0;
581
582
#ifdef DEBUG
583
    stream_state *st = s->state; /* Save because s_close resets s->state. */
584
#endif
585
3.46k
    gs_composite_t *pcomp_first = NULL, *pcomp_last = NULL;
586
3.46k
    tile_slot bits;             /* parameters for reading bits */
587
588
    /* pad the cbuf data area a bit (just in case) */
589
3.46k
    if ((cbuf_storage = gs_alloc_bytes(mem, cbuf_size + sizeof(double),
590
3.46k
                               "clist_playback_band(cbuf_storage)")) == NULL) {
591
0
        return_error(gs_error_VMerror);
592
0
    }
593
3.46k
    cbuf.data = (byte *)cbuf_storage;
594
3.46k
    cbuf.size = cbuf_size;
595
3.46k
    cbuf.s = s;
596
3.46k
    cbuf.end_status = 0;
597
3.46k
    set_cb_end(&cbuf, cbuf.data + cbuf.size);
598
3.46k
    cbp = cbuf.end;
599
600
3.46k
    pfs.dev = NULL; /* Indicate "not initialized". */
601
3.46k
    memset(&ht_buff, 0, sizeof(ht_buff));
602
603
    /* The following initializations are to quiet gcc warnings. */
604
3.46k
    memset(&bits, 0, sizeof(bits));
605
3.46k
    memset(&tile_bits, 0, sizeof(tile_bits));
606
3.46k
    memset(&clip_save, 0, sizeof(clip_save));
607
3.46k
    memset(&state_slot, 0, sizeof(state_slot));
608
3.46k
    ppos.x = ppos.y = 0;
609
610
3.46k
in:                             /* Initialize for a new page. */
611
3.46k
    tdev = target;
612
3.46k
    set_colors = state.colors;
613
3.46k
    set_dev_colors = state.tile_color_devn;
614
3.46k
    use_clip = false;
615
3.46k
    pcpath = NULL;
616
3.46k
    if (clipper_dev_open)
617
0
        gx_destroy_clip_device_on_stack(&clipper_dev);
618
3.46k
    clipper_dev_open = false;
619
3.46k
    notes = sn_none;
620
3.46k
    data_x = 0;
621
3.46k
    {
622
3.46k
        static const gx_clist_state cls_initial = { cls_initial_values };
623
624
3.46k
        state = cls_initial;
625
3.46k
    }
626
3.46k
    state_tile.id = gx_no_bitmap_id;
627
3.46k
    state_tile.shift = state_tile.rep_shift = 0;
628
3.46k
    state_tile.size.x = state_tile.size.y = 0;
629
3.46k
    state_tile.num_planes = 1;
630
3.46k
    tile_phase.x = x0;
631
3.46k
    tile_phase.y = y0;
632
3.46k
    gx_path_init_local(&path, mem);
633
3.46k
    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
3.46k
    {
639
3.46k
        gs_fixed_rect cbox;
640
641
3.46k
        gx_cpath_init_local(&clip_path, mem);
642
3.46k
        cbox.p.x = 0;
643
3.46k
        cbox.p.y = 0;
644
3.46k
        cbox.q.x = cdev->width;
645
3.46k
        cbox.q.y = cdev->height;
646
3.46k
        gx_cpath_from_rectangle(&clip_path, &cbox);
647
3.46k
    }
648
3.46k
    if (target != 0)
649
3.46k
        (*dev_proc(target, get_clipping_box))(target, &target_box);
650
3.46k
    memset(&gs_gstate, 0, sizeof(gs_gstate));
651
3.46k
    GS_STATE_INIT_VALUES_CLIST((&gs_gstate));
652
3.46k
    code = gs_gstate_initialize(&gs_gstate, mem);
653
3.46k
    if (code < 0)
654
0
        goto out;
655
3.46k
    gs_gstate.device = tdev;
656
3.46k
    gs_gstate.view_clip = NULL; /* Avoid issues in pdf14 fill stroke */
657
3.46k
    gs_gstate.clip_path = &clip_path;
658
3.46k
    pcs = gs_cspace_new_DeviceGray(mem);
659
3.46k
    if (pcs == NULL) {
660
0
        code = gs_note_error(gs_error_VMerror);
661
0
        goto out;
662
0
    }
663
3.46k
    code = pcs->type->install_cspace(pcs, &gs_gstate);
664
3.46k
    if (code < 0) {
665
0
        rc_decrement(pcs, "clist_playback_band");
666
0
        goto out;
667
0
    }
668
3.46k
    gs_gstate.color[0].color_space = pcs; /* we already have one ref */
669
3.46k
    gs_gstate.color[1].color_space = pcs;
670
3.46k
    rc_increment_cs(pcs); /* increment for second ref */
671
    /* Initialize client color and device color */
672
3.46k
    gs_gstate.color[0].ccolor =
673
3.46k
        gs_alloc_struct(mem, gs_client_color, &st_client_color, "clist_playback_band");
674
3.46k
    gs_gstate.color[1].ccolor =
675
3.46k
        gs_alloc_struct(mem, gs_client_color, &st_client_color, "clist_playback_band");
676
3.46k
    gs_gstate.color[0].dev_color =
677
3.46k
        gs_alloc_struct(mem, gx_device_color, &st_device_color, "clist_playback_band");
678
3.46k
    gs_gstate.color[1].dev_color =
679
3.46k
        gs_alloc_struct(mem, gx_device_color, &st_device_color, "clist_playback_band");
680
3.46k
    if (gs_gstate.color[0].ccolor == 0 || gs_gstate.color[0].dev_color == 0 ||
681
3.46k
        gs_gstate.color[1].ccolor == 0 || gs_gstate.color[1].dev_color == 0
682
3.46k
        ) {
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
3.46k
    gs_gstate.color[0].color_space->pclient_color_space_data =
692
3.46k
        pcs->pclient_color_space_data;
693
3.46k
    cs_full_init_color(gs_gstate.color[0].ccolor, pcs);
694
3.46k
    gx_unset_dev_color(&gs_gstate);
695
696
3.46k
    gs_gstate.color[1].color_space->pclient_color_space_data =
697
3.46k
        pcs->pclient_color_space_data;
698
3.46k
    cs_full_init_color(gs_gstate.color[1].ccolor, pcs);
699
3.46k
    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
3.46k
    rc_decrement(gs_gstate.icc_link_cache,"clist_playback_band");
704
3.46k
    gs_gstate.icc_link_cache = cdev->icc_cache_cl;
705
    /* Need to lock during the increment of the link cache */
706
3.46k
    gx_monitor_enter(cdev->icc_cache_cl->lock);
707
3.46k
    rc_increment(cdev->icc_cache_cl);
708
3.46k
    gx_monitor_leave(cdev->icc_cache_cl->lock); /* let everyone run */
709
3.46k
    if (code < 0)
710
0
        goto out;
711
712
3.46k
    gs_gstate.line_params.dash.pattern = dash_pattern;
713
3.46k
    if (tdev != 0) {
714
3.46k
        gx_set_cmap_procs(&gs_gstate, tdev);
715
3.46k
    }
716
3.46k
    gx_gstate_setscreenphase(&gs_gstate, -x0, -y0, gs_color_select_all);
717
#ifdef DEBUG
718
    halftone_type = ht_type_none;
719
#endif
720
3.46k
    fill_color.ccolor_valid = false;
721
3.46k
    color_unset(&fill_color);
722
3.46k
    data_bits = gs_alloc_bytes(mem, data_bits_size,
723
3.46k
                               "clist_playback_band(data_bits)");
724
3.46k
    if (data_bits == 0) {
725
0
        code = gs_note_error(gs_error_VMerror);
726
0
        goto out;
727
0
    }
728
940k
    while (code >= 0) {
729
940k
        int compress;
730
940k
        int depth = 0x7badf00d; /* Initialize against indeterminizm. */
731
940k
        int raster = 0x7badf00d; /* Initialize against indeterminizm. */
732
940k
        byte *source = NULL;  /* Initialize against indeterminizm. */
733
940k
        gx_color_index colors[2];
734
940k
        gx_color_index *pcolor;
735
940k
        gx_device_color *pdcolor = NULL;
736
940k
        gs_logical_operation_t log_op;
737
738
        /* Make sure the buffer contains a full command. */
739
940k
        if (cbp >= cbuf.warn_limit) {
740
4.17k
            if (cbuf.end_status < 0) {  /* End of file or error. */
741
10
                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
4.16k
            } else {
747
4.16k
                code = top_up_cbuf(&cbuf, &cbp);
748
4.16k
                if (code < 0)
749
0
                    goto top_up_failed;
750
4.16k
            }
751
4.17k
        }
752
940k
        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
940k
        switch (op >> 4) {
762
57.3k
            case cmd_op_misc >> 4:
763
57.3k
                switch (op) {
764
43.3k
                    case cmd_opv_end_run:
765
43.3k
                        if_debug0m('L', mem, "\n");
766
43.3k
                        continue;
767
0
                    case cmd_opv_set_tile_size:
768
0
                        cbuf.ptr = cbp;
769
0
                        code = read_set_tile_size(&cbuf, &tile_bits,
770
0
                                    gx_device_is_pattern_clist((gx_device *)cdev));
771
0
                        cbp = cbuf.ptr;
772
0
                        if (code < 0)
773
0
                            goto out;
774
0
                        continue;
775
0
                    case cmd_opv_set_tile_phase:
776
0
                        cmd_getw(state.tile_phase.x, cbp);
777
0
                        cmd_getw(state.tile_phase.y, cbp);
778
0
                        if_debug2m('L', mem, " (%d,%d)\n",
779
0
                                   state.tile_phase.x,
780
0
                                   state.tile_phase.y);
781
0
                        goto set_tile_phase;
782
215
                    case cmd_opv_set_screen_phaseT:
783
215
                        cmd_getw(state.screen_phase[gs_color_select_texture].x, cbp);
784
215
                        cmd_getw(state.screen_phase[gs_color_select_texture].y, cbp);
785
215
                        if_debug2m('L', mem, " (%d,%d)\n",
786
215
                                   state.screen_phase[0].x,
787
215
                                   state.screen_phase[gs_color_select_texture].y);
788
215
                        gx_gstate_setscreenphase(&gs_gstate,
789
215
                                                 state.screen_phase[gs_color_select_texture].x - x0,
790
215
                                                 state.screen_phase[gs_color_select_texture].y - y0,
791
215
                                                 gs_color_select_texture);
792
215
                        continue;
793
0
                    case cmd_opv_set_screen_phaseS:
794
0
                        cmd_getw(state.screen_phase[gs_color_select_source].x, cbp);
795
0
                        cmd_getw(state.screen_phase[gs_color_select_source].y, cbp);
796
0
                        if_debug2m('L', mem, " (%d,%d)\n",
797
0
                                   state.screen_phase[gs_color_select_source].x,
798
0
                                   state.screen_phase[gs_color_select_source].y);
799
0
                        gx_gstate_setscreenphase(&gs_gstate,
800
0
                                                 state.screen_phase[gs_color_select_source].x - x0,
801
0
                                                 state.screen_phase[gs_color_select_source].y - y0,
802
0
                                                 gs_color_select_source);
803
0
                        continue;
804
0
                    case cmd_opv_set_tile_bits:
805
0
                        bits = tile_bits;
806
0
                        compress = 0;
807
3.16k
                      stb:
808
3.16k
                        cbuf.ptr = cbp;
809
3.16k
                        code = read_set_bits(&cbuf, &bits, compress,
810
3.16k
                                             &state, &state_tile, &state_slot,
811
3.16k
                                             cdev, mem);
812
3.16k
                        cbp = cbuf.ptr;
813
3.16k
                        if (code < 0)
814
0
                            goto out;
815
3.16k
                        goto stp;
816
3.16k
                    case cmd_opv_set_bits:
817
3.16k
do_opv_set_bits:
818
3.16k
                        compress = *cbp & 3;
819
3.16k
                        bits.head.depth = *cbp++ >> 2;
820
3.16k
                        cmd_getw(bits.width, cbp);
821
3.16k
                        cmd_getw(bits.height, cbp);
822
3.16k
                        if (op == cmd_opv_set_bits_planar)
823
3.16k
                            cmd_getw(bits.num_planes, cbp);
824
3.16k
                        else
825
3.16k
                            bits.num_planes = 1;
826
3.16k
                        if_debug5m('L', mem, " compress=%d depth=%d size=(%d,%d) planes=%d",
827
3.16k
                                   compress, bits.head.depth,
828
3.16k
                                   bits.width, bits.height, bits.num_planes);
829
3.16k
                        bits.raster =
830
3.16k
                            bitmap_raster(bits.width * bits.head.depth);
831
3.16k
                        bits.x_reps = bits.y_reps = 1;
832
3.16k
                        bits.shift = bits.rep_shift = 0;
833
3.16k
                        goto stb;
834
0
                    case cmd_opv_set_tile_color:
835
0
                        set_colors = state.tile_colors;
836
0
                        if_debug0m('L', mem, "\n");
837
0
                        continue;
838
6.95k
                    case cmd_opv_set_misc:
839
6.95k
                        {
840
6.95k
                            uint cb = *cbp++;
841
842
6.95k
                            switch (cb >> 6) {
843
3.41k
                                case cmd_set_misc_lop >> 6:
844
3.41k
                                    cmd_getw(state.lop, cbp);
845
3.41k
                                    state.lop = (state.lop << 6) + (cb & 0x3f);
846
3.41k
                                    if_debug1m('L', mem, " lop=0x%x\n", state.lop);
847
3.41k
                                    if (state.lop_enabled)
848
3.30k
                                        gs_gstate.log_op = state.lop;
849
3.41k
                                    break;
850
0
                                case cmd_set_misc_data_x >> 6:
851
0
                                    if (cb & 0x20)
852
0
                                        cmd_getw(data_x, cbp);
853
0
                                    else
854
0
                                        data_x = 0;
855
0
                                    data_x = (data_x << 5) + (cb & 0x1f);
856
0
                                    if_debug1m('L', mem, " data_x=%d\n", data_x);
857
0
                                    break;
858
3.54k
                                case cmd_set_misc_map >> 6:
859
3.54k
                                    cbuf.ptr = cbp;
860
3.54k
                                    code = read_set_misc_map(cb, &cbuf, &gs_gstate, mem);
861
3.54k
                                    if (code < 0)
862
0
                                        goto out;
863
3.54k
                                    cbp = cbuf.ptr;
864
3.54k
                                    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
6.95k
                            }
885
6.95k
                        }
886
6.95k
                        continue;
887
6.95k
                    case cmd_opv_enable_lop:
888
110
                        state.lop_enabled = true;
889
110
                        gs_gstate.log_op = state.lop;
890
110
                        if_debug0m('L', mem, "\n");
891
110
                        continue;
892
87
                    case cmd_opv_disable_lop:
893
87
                        state.lop_enabled = false;
894
87
                        gs_gstate.log_op = lop_default;
895
87
                        if_debug0m('L', mem, "\n");
896
87
                        continue;
897
3.46k
                    case cmd_opv_end_page:
898
3.46k
                        if_debug0m('L', mem, "\n");
899
                        /*
900
                         * Do end-of-page cleanup, then reinitialize if
901
                         * there are more pages to come.
902
                         */
903
3.46k
                        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
57.3k
                }
979
                /*NOTREACHED */
980
0
            case cmd_op_set_color0 >> 4:
981
0
                pcolor = &set_colors[0];
982
0
                goto set_color;
983
0
            case cmd_op_set_color1 >> 4:
984
0
                pcolor = &set_colors[1];
985
0
              set_color:set_colors = state.colors;
986
                /*
987
                 * We have a special case for gx_no_color_index. If the low
988
                 * order 4 bits are "cmd_no_color_index" then we really
989
                 * have a value of gx_no_color_index.  Otherwise the these
990
                 * bits indicate the number of low order zero bytes in the
991
                 * value.  See comments for cmd_put_color() in gxclutil.c.
992
                 */
993
0
                num_zero_bytes = op & 0x0f;
994
995
0
                if (num_zero_bytes == cmd_no_color_index)
996
0
                    *pcolor = gx_no_color_index;
997
0
                else {
998
0
                    gx_color_index color = 0;
999
1000
0
                    dev_depth = (tdev->color_info.depth < 8*sizeof(gx_color_index) ?
1001
0
                                 tdev->color_info.depth : 8*sizeof(gx_color_index));
1002
0
                    dev_depth_bytes = (dev_depth + 7) >> 3;
1003
0
                    switch (dev_depth_bytes - num_zero_bytes) {
1004
0
                        case 8:
1005
0
                            color = (gx_color_index) * cbp++;
1006
0
                        case 7:
1007
0
                            color = (color << 8) | (gx_color_index) * cbp++;
1008
0
                        case 6:
1009
0
                            color = (color << 8) | (gx_color_index) * cbp++;
1010
0
                        case 5:
1011
0
                            color = (color << 8) | (gx_color_index) * cbp++;
1012
0
                        case 4:
1013
0
                            color = (color << 8) | (gx_color_index) * cbp++;
1014
0
                        case 3:
1015
0
                            color = (color << 8) | (gx_color_index) * cbp++;
1016
0
                        case 2:
1017
0
                            color = (color << 8) | (gx_color_index) * cbp++;
1018
0
                        case 1:
1019
0
                            color = (color << 8) | (gx_color_index) * cbp++;
1020
0
                        default:
1021
0
                            break;
1022
0
                    }
1023
0
                    color <<= num_zero_bytes * 8;
1024
0
                    *pcolor = color;
1025
0
                }
1026
0
                if (sizeof(*pcolor) <= sizeof(ulong))
1027
0
                    if_debug1m('L', mem, " 0x%lx\n", (ulong)*pcolor);
1028
0
                else
1029
0
                    if_debug2m('L', mem, " 0x%8lx%08lx\n",
1030
0
                               (ulong)(*pcolor >> 8*(sizeof(*pcolor) - sizeof(ulong))), (ulong)*pcolor);
1031
0
                continue;
1032
4.51k
            case cmd_op_fill_rect >> 4:
1033
4.51k
            case cmd_op_tile_rect >> 4:
1034
4.51k
                cbp = cmd_read_rect(op, &state.rect, cbp);
1035
4.51k
                break;
1036
8
            case cmd_op_fill_rect_short >> 4:
1037
8
            case cmd_op_tile_rect_short >> 4:
1038
8
                state.rect.x += *cbp + cmd_min_short;
1039
8
                state.rect.width += cbp[1] + cmd_min_short;
1040
8
                if (op & 0xf) {
1041
4
                    state.rect.height += (op & 0xf) + cmd_min_dxy_tiny;
1042
4
                    cbp += 2;
1043
4
                } else {
1044
4
                    state.rect.y += cbp[2] + cmd_min_short;
1045
4
                    state.rect.height += cbp[3] + cmd_min_short;
1046
4
                    cbp += 4;
1047
4
                }
1048
8
                break;
1049
311
            case cmd_op_fill_rect_tiny >> 4:
1050
311
            case cmd_op_tile_rect_tiny >> 4:
1051
311
                if (op & 8)
1052
0
                    state.rect.x += state.rect.width;
1053
311
                else {
1054
311
                    int txy = *cbp++;
1055
1056
311
                    state.rect.x += (txy >> 4) + cmd_min_dxy_tiny;
1057
311
                    state.rect.y += (txy & 0xf) + cmd_min_dxy_tiny;
1058
311
                }
1059
311
                state.rect.width += (op & 7) + cmd_min_dw_tiny;
1060
311
                break;
1061
5.23k
            case cmd_op_copy_mono_planes >> 4:
1062
5.23k
                cmd_getw(plane_height, cbp);
1063
5.23k
                if (plane_height == 0) {
1064
                    /* We are doing a copy mono */
1065
5.23k
                    depth = 1;
1066
5.23k
                } else {
1067
0
                    depth = tdev->color_info.depth;
1068
0
                }
1069
5.23k
                if_debug1m('L', mem, " plane_height=0x%x", plane_height);
1070
5.23k
                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
5.23k
              copy:cmd_getw(state.rect.x, cbp);
1079
5.23k
                cmd_getw(state.rect.y, cbp);
1080
5.23k
                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
5.23k
                    depth = state_slot->head.depth;
1091
5.23k
                    state.rect.width = state_slot->width;
1092
5.23k
                    state.rect.height = state_slot->height;
1093
5.23k
                    if (state.rect.y + state.rect.height > cdev->height)
1094
0
                        state.rect.height = cdev->height - state.rect.y; /* clamp as writer did */
1095
5.23k
                    raster = state_slot->raster;
1096
5.23k
                    source = (byte *) (state_slot + 1);
1097
5.23k
                } else {        /* Read width, height, bits. */
1098
                    /* depth was set already. */
1099
0
                    uint width_bits, width_bytes;
1100
0
                    uint bytes;
1101
0
                    uchar planes = 1;
1102
0
                    uint plane_depth = depth;
1103
0
                    uint pln;
1104
0
                    byte compression = op & 3;
1105
0
                    uint out_bytes;
1106
1107
0
                    cmd_getw(state.rect.width, cbp);
1108
0
                    cmd_getw(state.rect.height, cbp);
1109
0
                    if (plane_height != 0) {
1110
0
                        planes = tdev->color_info.num_components;
1111
0
                        plane_depth /= planes;
1112
0
                    }
1113
0
                    width_bits = state.rect.width * plane_depth;
1114
0
                    bytes = clist_bitmap_bytes(width_bits,
1115
0
                                               state.rect.height,
1116
0
                                               op & 3, &width_bytes,
1117
0
                                               (uint *)&raster);
1118
0
                    if (planes > 1) {
1119
0
                        out_bytes = raster * state.rect.height;
1120
0
                        plane_height = state.rect.height;
1121
0
                    } else {
1122
0
                        out_bytes = bytes;
1123
0
                    }
1124
                    /* copy_mono and copy_color/alpha */
1125
                    /* ensure that the bits will fit in a single buffer, */
1126
                    /* even after decompression if compressed. */
1127
#ifdef DEBUG
1128
                    if (planes * out_bytes > data_bits_size) {
1129
                        mlprintf6(mem, "bitmap size exceeds buffer!  width=%d raster=%d height=%d\n    file pos %"PRId64" buf pos %d/%d\n",
1130
                                  state.rect.width, raster,
1131
                                  state.rect.height,
1132
                                  stell(s), (int)(cbp - cbuf.data),
1133
                                  (int)(cbuf.end - cbuf.data));
1134
                        code = gs_note_error(gs_error_ioerror);
1135
                        goto out;
1136
                    }
1137
#endif
1138
0
                    for (pln = 0; pln < planes; pln++) {
1139
0
                        byte *plane_bits = data_bits + pln * plane_height * raster;
1140
1141
                        /* Fill the cbuf if needed to get the data for the plane */
1142
0
                        if (cbp + out_bytes >= cbuf.warn_limit) {
1143
0
                            code = top_up_cbuf(&cbuf, &cbp);
1144
0
                            if (code < 0)
1145
0
                                goto top_up_failed;
1146
0
                        }
1147
0
                        if (pln)
1148
0
                            compression = *cbp++;
1149
1150
0
                        if (compression == cmd_compress_const) {
1151
0
                            cbp = cmd_read_data(&cbuf, plane_bits, 1, cbp);
1152
0
                            if (width_bytes > 0 && state.rect.height > 0)
1153
0
                                memset(plane_bits+1, *plane_bits, width_bytes * state.rect.height - 1);
1154
0
                            if (pln == 0)
1155
0
                                source = data_bits;
1156
1157
0
                        } else if (compression) {       /* Decompress the image data. */
1158
0
                            stream_cursor_read r;
1159
0
                            stream_cursor_write w;
1160
1161
                            /* We don't know the data length a priori, */
1162
                            /* so to be conservative, we read */
1163
                            /* the uncompressed size. */
1164
0
                            uint cleft = cbuf.end - cbp;
1165
1166
0
                            if (cleft < bytes  && !cbuf.end_status) {
1167
0
                                uint nread = cbuf_size - cleft;
1168
1169
0
                                advance_buffer(&cbuf, cbp);
1170
0
                                cbuf.end_status = sgets(s, cbuf.data + cleft, nread, &nread);
1171
0
                                set_cb_end(&cbuf, cbuf.data + cleft + nread);
1172
0
                                cbp = cbuf.data;
1173
0
                            }
1174
0
                            r.ptr = cbp - 1;
1175
0
                            r.limit = cbuf.end - 1;
1176
0
                            w.ptr = plane_bits - 1;
1177
0
                            w.limit = w.ptr + data_bits_size;
1178
0
                            switch (compression) {
1179
0
                                case cmd_compress_rle:
1180
0
                                    {
1181
0
                                        stream_RLD_state sstate;
1182
1183
0
                                        clist_rld_init(&sstate);
1184
                                        /* The process procedure can't fail. */
1185
0
                                        (*s_RLD_template.process)
1186
0
                                            ((stream_state *)&sstate, &r, &w, true);
1187
0
                                    }
1188
0
                                    break;
1189
0
                                case cmd_compress_cfe:
1190
0
                                    {
1191
0
                                        stream_CFD_state sstate;
1192
1193
0
                                        clist_cfd_init(&sstate,
1194
0
                                        width_bytes << 3 /*state.rect.width */ ,
1195
0
                                                       state.rect.height, mem);
1196
                                        /* The process procedure can't fail. */
1197
0
                                        (*s_CFD_template.process)
1198
0
                                            ((stream_state *)&sstate, &r, &w, true);
1199
0
                                        (*s_CFD_template.release)
1200
0
                                            ((stream_state *)&sstate);
1201
0
                                    }
1202
0
                                    break;
1203
0
                                default:
1204
0
                                    goto bad_op;
1205
0
                            }
1206
0
                            cbp = r.ptr + 1;
1207
0
                            if (pln == 0)
1208
0
                                source = data_bits;
1209
0
                        } else if ((state.rect.height > 1 && width_bytes != raster) ||
1210
0
                                   (plane_height != 0)) {
1211
0
                            cbp = cmd_read_short_bits(&cbuf, plane_bits, bytes, width_bytes,
1212
0
                                                      state.rect.height, raster, cbp);
1213
0
                            if (pln == 0)
1214
0
                                source = data_bits;
1215
0
                        } else {
1216
                            /* Never used for planar data */
1217
0
                            cbp = cmd_read_data(&cbuf, cbuf.data, bytes, cbp);
1218
0
                            source = cbuf.data;
1219
0
                        }
1220
0
                    }
1221
#ifdef DEBUG
1222
                    if (gs_debug_c('L')) {
1223
                        dmprintf2(mem, " depth=%d, data_x=%d\n",
1224
                                  depth, data_x);
1225
                        cmd_print_bits(mem, source, state.rect.width,
1226
                                       state.rect.height, raster);
1227
                    }
1228
#endif
1229
0
                }
1230
5.23k
                break;
1231
5.23k
            case cmd_op_delta_tile_index >> 4:
1232
614
                state.tile_index += (int)(op & 0xf) - 8;
1233
614
                goto sti;
1234
577
            case cmd_op_set_tile_index >> 4:
1235
577
                state.tile_index =
1236
577
                    ((op & 0xf) << 8) + *cbp++;
1237
1.19k
              sti:state_slot =
1238
1.19k
                    (tile_slot *) (cdev->cache_chunk->data +
1239
1.19k
                                 cdev->tile_table[state.tile_index].offset);
1240
1.19k
                if_debug2m('L', mem, " index=%u offset=%lu\n",
1241
1.19k
                           state.tile_index,
1242
1.19k
                           cdev->tile_table[state.tile_index].offset);
1243
1.19k
                state_tile.data = (byte *) (state_slot + 1);
1244
4.35k
              stp:state_tile.size.x = state_slot->width;
1245
4.35k
                state_tile.size.y = state_slot->height;
1246
4.35k
                state_tile.raster = state_slot->raster;
1247
4.35k
                state_tile.rep_width = state_tile.size.x /
1248
4.35k
                    state_slot->x_reps;
1249
4.35k
                state_tile.rep_height = state_tile.size.y /
1250
4.35k
                    state_slot->y_reps;
1251
4.35k
                state_tile.rep_shift = state_slot->rep_shift;
1252
4.35k
                state_tile.shift = state_slot->shift;
1253
4.35k
                state_tile.id = state_slot->id;
1254
4.35k
                state_tile.num_planes = state_slot->num_planes;
1255
4.35k
set_tile_phase:
1256
4.35k
                if (state_tile.size.x)
1257
4.35k
                    tile_phase.x =
1258
4.35k
                        (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
4.35k
                if (state_tile.size.y) {
1264
4.35k
                    int full_height;
1265
1266
4.35k
                    if (state_tile.shift == 0)
1267
4.35k
                        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
4.35k
                    tile_phase.y = (state.tile_phase.y + y0) % full_height;
1274
4.35k
                }
1275
4.35k
                continue;
1276
694k
            case cmd_op_misc2 >> 4:
1277
694k
                switch (op) {
1278
0
                    case cmd_opv_set_bits_planar:
1279
0
                        goto do_opv_set_bits;
1280
3.09k
                    case cmd_opv_set_fill_adjust:
1281
3.09k
                        cmd_get_value(gs_gstate.fill_adjust.x, cbp);
1282
3.09k
                        cmd_get_value(gs_gstate.fill_adjust.y, cbp);
1283
3.09k
                        if_debug2m('L', mem, " (%g,%g)\n",
1284
3.09k
                                   fixed2float(gs_gstate.fill_adjust.x),
1285
3.09k
                                   fixed2float(gs_gstate.fill_adjust.y));
1286
3.09k
                        continue;
1287
1.32k
                    case cmd_opv_set_ctm:
1288
1.32k
                        {
1289
1.32k
                            gs_matrix mat;
1290
1291
1.32k
                            cbp = cmd_read_matrix(&mat, cbp);
1292
1.32k
                            if_debug6m('L', mem, " [%g %g %g %g %g %g]\n",
1293
1.32k
                                       mat.xx, mat.xy, mat.yx, mat.yy,
1294
1.32k
                                       mat.tx, mat.ty);
1295
1.32k
                            mat.tx -= x0;
1296
1.32k
                            mat.ty -= y0;
1297
1.32k
                            gs_gstate_setmatrix(&gs_gstate, &mat);
1298
1.32k
                        }
1299
1.32k
                        continue;
1300
4.43k
                    case cmd_opv_set_misc2:
1301
4.43k
                        cbuf.ptr = cbp;
1302
4.43k
                        code = read_set_misc2(&cbuf, &gs_gstate, &notes);
1303
4.43k
                        cbp = cbuf.ptr;
1304
4.43k
                        if (code < 0)
1305
0
                            goto out;
1306
4.43k
                        continue;
1307
4.43k
                    case cmd_opv_set_dash:
1308
342
                        {
1309
342
                            int nb = *cbp++;
1310
342
                            int n = nb & 0x3f;
1311
342
                            float dot_length, offset;
1312
1313
342
                            cmd_get_value(dot_length, cbp);
1314
342
                            cmd_get_value(offset, cbp);
1315
342
                            memcpy(dash_pattern, cbp, n * sizeof(float));
1316
1317
342
                            gx_set_dash(&gs_gstate.line_params.dash,
1318
342
                                        dash_pattern, n, offset,
1319
342
                                        NULL);
1320
342
                            gx_set_dash_adapt(&gs_gstate.line_params.dash,
1321
342
                                              (nb & 0x80) != 0);
1322
342
                            gx_set_dot_length(&gs_gstate.line_params,
1323
342
                                              dot_length,
1324
342
                                              (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
342
                            cbp += n * sizeof(float);
1339
342
                        }
1340
342
                        break;
1341
0
                    case cmd_opv_enable_clip:
1342
0
                        pcpath = (use_clip ? &clip_path : NULL);
1343
0
                        if (pcpath) {
1344
0
                            code = gx_cpath_ensure_path_list(pcpath);
1345
0
                            if (code < 0)
1346
0
                                goto out;
1347
0
                        }
1348
0
                        if (clipper_dev_open)
1349
0
                            gx_destroy_clip_device_on_stack(&clipper_dev);
1350
0
                        clipper_dev_open = false;
1351
0
                        if_debug0m('L', mem, "\n");
1352
0
                        break;
1353
0
                    case cmd_opv_disable_clip:
1354
0
                        pcpath = NULL;
1355
0
                        if (clipper_dev_open)
1356
0
                            gx_destroy_clip_device_on_stack(&clipper_dev);
1357
0
                        clipper_dev_open = false;
1358
0
                        if_debug0m('L', mem, "\n");
1359
0
                        break;
1360
4.80k
                    case cmd_opv_begin_clip:
1361
4.80k
                        pcpath = NULL;
1362
4.80k
                        if (clipper_dev_open)
1363
0
                            gx_destroy_clip_device_on_stack(&clipper_dev);
1364
4.80k
                        clipper_dev_open = false;
1365
4.80k
                        in_clip = true;
1366
4.80k
                        if_debug0m('L', mem, "\n");
1367
4.80k
                        code = gx_cpath_reset(&clip_path);
1368
4.80k
                        if (code < 0)
1369
0
                            goto out;
1370
4.80k
                        gx_cpath_accum_begin(&clip_accum, mem, false);
1371
4.80k
                        gx_cpath_accum_set_cbox(&clip_accum,
1372
4.80k
                                                &target_box);
1373
4.80k
                        tdev = (gx_device *)&clip_accum;
1374
4.80k
                        clip_save.lop_enabled = state.lop_enabled;
1375
4.80k
                        clip_save.dcolor = fill_color;
1376
4.80k
                        clip_save.fa_save.x = gs_gstate.fill_adjust.x;
1377
4.80k
                        clip_save.fa_save.y = gs_gstate.fill_adjust.y;
1378
4.80k
                        cmd_getw(gs_gstate.fill_adjust.x, cbp);
1379
4.80k
                        cmd_getw(gs_gstate.fill_adjust.y, cbp);
1380
                        /* temporarily set a solid color */
1381
4.80k
                        color_set_pure(&fill_color, (gx_color_index)1);
1382
4.80k
                        state.lop_enabled = false;
1383
4.80k
                        gs_gstate.log_op = lop_default;
1384
4.80k
                        break;
1385
4.80k
                    case cmd_opv_end_clip:
1386
4.80k
                        if_debug0m('L', mem, "\n");
1387
4.80k
                        gx_cpath_accum_end(&clip_accum, &clip_path);
1388
4.80k
                        tdev = target;
1389
                        /*
1390
                         * If the entire band falls within the clip
1391
                         * path, no clipping is needed.
1392
                         */
1393
4.80k
                        {
1394
4.80k
                            gs_fixed_rect cbox;
1395
1396
4.80k
                            gx_cpath_inner_box(&clip_path, &cbox);
1397
4.80k
                            use_clip =
1398
4.80k
                                !(cbox.p.x <= target_box.p.x &&
1399
4.80k
                                  cbox.q.x >= target_box.q.x &&
1400
4.80k
                                  cbox.p.y <= target_box.p.y &&
1401
4.80k
                                  cbox.q.y >= target_box.q.y);
1402
4.80k
                        }
1403
4.80k
                        pcpath = (use_clip ? &clip_path : NULL);
1404
4.80k
                        if (pcpath) {
1405
3.70k
                            code = gx_cpath_ensure_path_list(pcpath);
1406
3.70k
                            if (code < 0)
1407
0
                                goto out;
1408
3.70k
                        }
1409
4.80k
                        if (clipper_dev_open)
1410
0
                            gx_destroy_clip_device_on_stack(&clipper_dev);
1411
4.80k
                        clipper_dev_open = false;
1412
4.80k
                        state.lop_enabled = clip_save.lop_enabled;
1413
4.80k
                        gs_gstate.log_op =
1414
4.80k
                            (state.lop_enabled ? state.lop :
1415
4.80k
                             lop_default);
1416
4.80k
                        fill_color = clip_save.dcolor;
1417
                        /* restore the fill_adjust if it was changed by begin_clip */
1418
4.80k
                        gs_gstate.fill_adjust.x = clip_save.fa_save.x;
1419
4.80k
                        gs_gstate.fill_adjust.y = clip_save.fa_save.y;
1420
4.80k
                        in_clip = false;
1421
4.80k
                        break;
1422
60
                    case cmd_opv_set_color_space:
1423
60
                        cbuf.ptr = cbp;
1424
60
                        code = read_set_color_space(&cbuf, &gs_gstate, cdev, mem);
1425
60
                        pcs = gs_gstate.color[0].color_space;
1426
60
                        cbp = cbuf.ptr;
1427
60
                        if (code < 0) {
1428
0
                            if (code == gs_error_rangecheck)
1429
0
                                goto bad_op;
1430
0
                            goto out;
1431
0
                        }
1432
60
                        break;
1433
246k
                    case cmd_op_fill_rect_hl:
1434
246k
                        {
1435
246k
                            gs_fixed_rect rect_hl;
1436
1437
246k
                            cbp = cmd_read_rect(op & 0xf0, &state.rect, cbp);
1438
246k
                            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
246k
                            if_debug4m('L', mem, " x=%d y=%d w=%d h=%d\n",
1444
246k
                                       state.rect.x, state.rect.y,
1445
246k
                                       state.rect.width,state.rect.height);
1446
246k
                            rect_hl.p.x = int2fixed(state.rect.x - x0);
1447
246k
                            rect_hl.p.y = int2fixed(state.rect.y - y0);
1448
246k
                            rect_hl.q.x = int2fixed(state.rect.width) + rect_hl.p.x;
1449
246k
                            rect_hl.q.y = int2fixed(state.rect.height) + rect_hl.p.y;
1450
246k
                            code = dev_proc(tdev, fill_rectangle_hl_color) (tdev,
1451
246k
                                                        &rect_hl, NULL,
1452
246k
                                                        &fill_color, NULL);
1453
246k
                        }
1454
0
                        continue;
1455
60
                    case cmd_opv_begin_image_rect:
1456
60
                        cbuf.ptr = cbp;
1457
60
                        code = read_begin_image(&cbuf, &image.c, pcs);
1458
60
                        cbp = cbuf.ptr;
1459
60
                        if (code < 0)
1460
0
                            goto out;
1461
60
                        {
1462
60
                            uint diff;
1463
1464
60
                            cmd_getw(image_rect.p.x, cbp);
1465
60
                            cmd_getw(image_rect.p.y, cbp);
1466
60
                            cmd_getw(diff, cbp);
1467
60
                            image_rect.q.x = image.d.Width - diff;
1468
60
                            cmd_getw(diff, cbp);
1469
60
                            image_rect.q.y = image.d.Height - diff;
1470
60
                            if_debug4m('L', mem, " rect=(%d,%d),(%d,%d)",
1471
60
                                       image_rect.p.x, image_rect.p.y,
1472
60
                                       image_rect.q.x, image_rect.q.y);
1473
60
                        }
1474
60
                        goto ibegin;
1475
0
                    case cmd_opv_begin_image:
1476
0
                        cbuf.ptr = cbp;
1477
0
                        code = read_begin_image(&cbuf, &image.c, pcs);
1478
0
                        cbp = cbuf.ptr;
1479
0
                        if (code < 0)
1480
0
                            goto out;
1481
0
                        image_rect.p.x = 0;
1482
0
                        image_rect.p.y = 0;
1483
0
                        image_rect.q.x = image.d.Width;
1484
0
                        image_rect.q.y = image.d.Height;
1485
0
                        if_debug2m('L', mem, " size=(%d,%d)",
1486
0
                                  image.d.Width, image.d.Height);
1487
60
ibegin:                 if_debug0m('L', mem, "\n");
1488
60
                        {
1489
                            /* Processing an image operation */
1490
60
                            dev_proc(tdev, set_graphics_type_tag)(tdev, GS_IMAGE_TAG);/* FIXME: what about text bitmaps? */
1491
60
                            image.i4.override_in_smask = 0;
1492
60
                            code = (*dev_proc(tdev, begin_typed_image))
1493
60
                                (tdev, &gs_gstate, NULL,
1494
60
                                 (const gs_image_common_t *)&image,
1495
60
                                 &image_rect, &fill_color, pcpath, mem,
1496
60
                                 &image_info);
1497
60
                        }
1498
60
                        if (code < 0)
1499
0
                            goto out;
1500
60
                        break;
1501
60
                    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.44k
                    case cmd_opv_image_data:
1537
1.44k
                        cmd_getw(data_height, cbp);
1538
1.44k
                        if (data_height == 0) {
1539
60
                            if_debug0m('L', mem, " done image\n");
1540
60
                            code = gx_image_end(image_info, true);
1541
60
                            if (code < 0)
1542
0
                                goto out;
1543
60
                            continue;
1544
60
                        }
1545
1.38k
                        {
1546
1.38k
                            uint bytes_per_plane;
1547
1.38k
                            int plane;
1548
1549
1.38k
                            cmd_getw(bytes_per_plane, cbp);
1550
1.38k
                            if_debug2m('L', mem, " height=%u raster=%u\n",
1551
1.38k
                                       data_height, bytes_per_plane);
1552
1.38k
                            for (plane = 0;
1553
2.76k
                                 plane < image_info->num_planes;
1554
1.38k
                                 ++plane
1555
1.38k
                                 ) {
1556
1.38k
                                planes[plane].data_x = data_x;
1557
1.38k
                                planes[plane].raster = bytes_per_plane;
1558
1.38k
                            }
1559
1.38k
                        }
1560
1.38k
idata:                  data_size = 0;
1561
1.38k
                        {
1562
1.38k
                            int plane;
1563
1564
2.76k
                            for (plane = 0; plane < image_info->num_planes;
1565
1.38k
                                 ++plane)
1566
1.38k
                                data_size += planes[plane].raster;
1567
1.38k
                        }
1568
1.38k
                        data_size *= data_height;
1569
1.38k
                        data_on_heap = 0;
1570
1.38k
                        if (cbuf.end - cbp < data_size) {
1571
544
                            code = top_up_cbuf(&cbuf, &cbp);
1572
544
                            if (code < 0)
1573
0
                                goto top_up_failed;
1574
544
                        }
1575
1.38k
                        if (cbuf.end - cbp >= data_size) {
1576
1.26k
                            planes[0].data = cbp;
1577
1.26k
                            cbp += data_size;
1578
1.26k
                        } else {
1579
116
                            uint cleft = cbuf.end - cbp;
1580
116
                            uint rleft = data_size - cleft;
1581
116
                            byte *rdata;
1582
1583
116
                            if (data_size > cbuf.end - cbuf.data) {
1584
                                /* Allocate a separate buffer. */
1585
116
                                rdata = data_on_heap =
1586
116
                                    gs_alloc_bytes(mem, data_size,
1587
116
                                                   "clist image_data");
1588
116
                                if (rdata == 0) {
1589
0
                                    code = gs_note_error(gs_error_VMerror);
1590
0
                                    goto out;
1591
0
                                }
1592
116
                            } else
1593
0
                                rdata = cbuf.data;
1594
116
                            memmove(rdata, cbp, cleft);
1595
116
                            if (data_on_heap)
1596
116
                                next_is_skip(&cbuf);
1597
116
                            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
116
                            planes[0].data = rdata;
1602
116
                            cbp = cbuf.end;     /* force refill */
1603
116
                        }
1604
1.38k
                        {
1605
1.38k
                            int plane;
1606
1.38k
                            const byte *data = planes[0].data;
1607
1608
1.38k
                            for (plane = 0;
1609
2.76k
                                 plane < image_info->num_planes;
1610
1.38k
                                 ++plane
1611
1.38k
                                 ) {
1612
1.38k
                                if (planes[plane].raster == 0)
1613
0
                                    planes[plane].data = 0;
1614
1.38k
                                else {
1615
1.38k
                                    planes[plane].data = data;
1616
1.38k
                                    data += planes[plane].raster *
1617
1.38k
                                        data_height;
1618
1.38k
                                }
1619
1.38k
                            }
1620
1.38k
                        }
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
1.38k
                        code = gx_image_plane_data(image_info, planes,
1637
1.38k
                                                   data_height);
1638
1.38k
                        if (code < 0)
1639
0
                            gx_image_end(image_info, false);
1640
1.38k
                        if (data_on_heap)
1641
116
                            gs_free_object(mem, data_on_heap,
1642
1.38k
                                           "clist image_data");
1643
1.38k
                        data_x = 0;
1644
1.38k
                        if (code < 0)
1645
0
                            goto out;
1646
1.38k
                        continue;
1647
427k
                    case cmd_opv_extend:
1648
427k
                        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
29.9k
                            case cmd_opv_ext_composite:
1663
29.9k
                                if_debug0m('L', mem, " ext_composite\n");
1664
29.9k
                                cbuf.ptr = cbp;
1665
                                /*
1666
                                 * The screen phase may have been changed during
1667
                                 * the processing of masked images.
1668
                                 */
1669
29.9k
                                gx_gstate_setscreenphase(&gs_gstate,
1670
29.9k
                                            -x0, -y0, gs_color_select_all);
1671
29.9k
                                cbp -= 2; /* Step back to simplify the cycle invariant below. */
1672
482k
                                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
482k
                                    int len;
1678
1679
482k
                                    if (cbp >= cbuf.warn_limit) {
1680
10
                                        code = top_up_cbuf(&cbuf, &cbp);
1681
10
                                        if (code < 0)
1682
0
                                            goto out;
1683
10
                                    }
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
482k
                                    if (cbp[0] == cmd_opv_extend && cbp[1] == cmd_opv_ext_composite) {
1694
310k
                                        gs_composite_t *pcomp, *pcomp_opening;
1695
310k
                                        gs_compositor_closing_state closing_state;
1696
1697
310k
                                        cbuf.ptr = cbp += 2;
1698
310k
                                        code = read_composite(&cbuf, mem, &pcomp);
1699
310k
                                        if (code < 0)
1700
0
                                            goto out;
1701
310k
                                        cbp = cbuf.ptr;
1702
310k
                                        if (pcomp == NULL)
1703
0
                                            continue;
1704
310k
                                        if (gs_is_pdf14trans_compositor(pcomp) &&
1705
310k
                                            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
310k
                                        pcomp_opening = pcomp_last;
1712
310k
                                        closing_state = pcomp->type->procs.is_closing(pcomp, &pcomp_opening, tdev);
1713
310k
                                        switch(closing_state)
1714
310k
                                        {
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
298k
                                        case COMP_ENQUEUE:
1721
                                            /* Enqueue. */
1722
298k
                                            enqueue_compositor(&pcomp_first, &pcomp_last, pcomp);
1723
298k
                                            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
236
                                        case COMP_EXEC_QUEUE:
1733
                                            /* The opening command was executed. Execute the queue. */
1734
236
                                            enqueue_compositor(&pcomp_first, &pcomp_last, pcomp);
1735
236
                                            code = execute_compositor_queue(cdev, &target, &tdev,
1736
236
                                                &gs_gstate, &pcomp_first, &pcomp_last, pcomp_first, x0, y0, mem, false);
1737
236
                                            if (code < 0)
1738
0
                                                goto out;
1739
236
                                            break;
1740
236
                                        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
10.8k
                                        case COMP_REPLACE_CURR:
1749
                                            /* Replace specific compositor. */
1750
10.8k
                                            code = dequeue_compositor(&pcomp_first, &pcomp_last, pcomp_opening);
1751
10.8k
                                            if (code < 0)
1752
0
                                                goto out;
1753
10.8k
                                            enqueue_compositor(&pcomp_first, &pcomp_last, pcomp);
1754
10.8k
                                            free_compositor(pcomp_opening, mem);
1755
10.8k
                                            break;
1756
61
                                        case COMP_DROP_QUEUE:
1757
                                            /* Annihilate the last compositors. */
1758
61
                                            enqueue_compositor(&pcomp_first, &pcomp_last, pcomp);
1759
61
                                            code = drop_compositor_queue(&pcomp_first, &pcomp_last, pcomp_opening, mem, x0, y0, &gs_gstate);
1760
61
                                            if (code < 0)
1761
0
                                                goto out;
1762
61
                                            break;
1763
567
                                        case COMP_MARK_IDLE:
1764
                                            /* Mark as idle. */
1765
567
                                            enqueue_compositor(&pcomp_first, &pcomp_last, pcomp);
1766
567
                                            mark_as_idle(pcomp_opening, pcomp);
1767
310k
                                        }
1768
310k
                                    } else if (is_null_compositor_op(cbp, &len)) {
1769
141k
                                        cbuf.ptr = cbp += len;
1770
141k
                                    } else if (cbp[0] == cmd_opv_end_page) {
1771
                                        /* End page, drop the queue. */
1772
631
                                        code = execute_compositor_queue(cdev, &target, &tdev,
1773
631
                                                &gs_gstate, &pcomp_first, &pcomp_last, pcomp_first, x0, y0, mem, true);
1774
631
                                        if (code < 0)
1775
0
                                            goto out;
1776
631
                                        break;
1777
29.6k
                                    } else if (pcomp_last != NULL &&
1778
29.6k
                                            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
318
                                        uint cb;
1787
1788
318
                                        switch (*cbp++) {
1789
0
                                            case cmd_opv_extend:
1790
0
                                                switch (*cbp++) {
1791
0
                                                    case cmd_opv_ext_put_halftone:
1792
0
                                                        {
1793
0
                                                            uint    ht_size;
1794
1795
0
                                                            enc_u_getw(ht_size, cbp);
1796
0
                                                            code = read_alloc_ht_buff(&ht_buff, ht_size, mem);
1797
0
                                                            if (code < 0)
1798
0
                                                                goto out;
1799
0
                                                        }
1800
0
                                                        break;
1801
0
                                                    case cmd_opv_ext_put_ht_seg:
1802
0
                                                        cbuf.ptr = cbp;
1803
0
                                                        code = read_ht_segment(&ht_buff, &cbuf,
1804
0
                                                                               &gs_gstate, tdev,
1805
0
                                                                               mem);
1806
0
                                                        cbp = cbuf.ptr;
1807
0
                                                        if (code < 0)
1808
0
                                                            goto out;
1809
0
                                                        break;
1810
0
                                                    default:
1811
0
                                                        code = gs_note_error(gs_error_unregistered); /* Must not happen. */
1812
0
                                                        goto out;
1813
0
                                                }
1814
0
                                                break;
1815
318
                                            case cmd_opv_set_misc:
1816
318
                                                cb = *cbp++;
1817
318
                                                switch (cb >> 6) {
1818
318
                                                    case cmd_set_misc_map >> 6:
1819
318
                                                        cbuf.ptr = cbp;
1820
318
                                                        code = read_set_misc_map(cb, &cbuf, &gs_gstate, mem);
1821
318
                                                        if (code < 0)
1822
0
                                                            goto out;
1823
318
                                                        cbp = cbuf.ptr;
1824
318
                                                        break;
1825
0
                                                    default:
1826
0
                                                        code = gs_note_error(gs_error_unregistered); /* Must not happen. */
1827
0
                                                        goto out;
1828
318
                                                }
1829
318
                                                break;
1830
318
                                            default:
1831
0
                                                code = gs_note_error(gs_error_unregistered); /* Must not happen. */
1832
0
                                                goto out;
1833
318
                                        }
1834
29.3k
                                    } else {
1835
                                        /* A drawing command, execute entire queue. */
1836
29.3k
                                        code = execute_compositor_queue(cdev, &target, &tdev,
1837
29.3k
                                            &gs_gstate, &pcomp_first, &pcomp_last, pcomp_first, x0, y0, mem, false);
1838
29.3k
                                        if (code < 0)
1839
0
                                            goto out;
1840
29.3k
                                        break;
1841
29.3k
                                    }
1842
482k
                                }
1843
29.9k
                                if (pcomp_last != NULL) {
1844
0
                                    code = gs_note_error(gs_error_unregistered);
1845
0
                                    goto out;
1846
0
                                }
1847
29.9k
                                break;
1848
29.9k
                            case cmd_opv_ext_put_halftone:
1849
2
                                {
1850
2
                                    uint    ht_size;
1851
1852
2
                                    if_debug0m('L', mem, " ext_put_halftone\n");
1853
2
                                    enc_u_getw(ht_size, cbp);
1854
2
                                    code = read_alloc_ht_buff(&ht_buff, ht_size, mem);
1855
2
                                    if (code < 0)
1856
0
                                        goto out;
1857
2
                                }
1858
2
                                break;
1859
2
                            case cmd_opv_ext_put_ht_seg:
1860
2
                                if_debug0m('L', mem, " ext_put_ht_seg\n");
1861
2
                                cbuf.ptr = cbp;
1862
2
                                code = read_ht_segment(&ht_buff, &cbuf,
1863
2
                                                       &gs_gstate, tdev,
1864
2
                                                       mem);
1865
2
                                cbp = cbuf.ptr;
1866
2
                                if (code < 0)
1867
0
                                    goto out;
1868
2
                                break;
1869
2
                            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
374k
                            case cmd_opv_ext_put_fill_dcolor:
1892
374k
                                pdcolor = &fill_color;
1893
374k
                                goto load_dcolor;
1894
23.2k
                            case cmd_opv_ext_put_stroke_dcolor:
1895
23.2k
                                pdcolor = &stroke_color;
1896
23.2k
                                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
397k
                    load_dcolor:{
1903
397k
                                    uint    color_size;
1904
397k
                                    int left, offset, l;
1905
397k
                                    const gx_device_color_type_t *  pdct;
1906
397k
                                    byte type_and_flag = *cbp++;
1907
397k
                                    byte is_continuation = type_and_flag & 0x80;
1908
1909
397k
                                    if_debug0m('L', mem, " cmd_opv_ext_put_drawing_color\n");
1910
397k
                                    pdct = gx_get_dc_type_from_index(type_and_flag & 0x7F);
1911
397k
                                    if (pdct == 0) {
1912
0
                                        code = gs_note_error(gs_error_rangecheck);
1913
0
                                        goto out;
1914
0
                                    }
1915
397k
                                    offset = 0;
1916
397k
                                    if (is_continuation)
1917
397k
                                        enc_u_getw(offset, cbp);
1918
397k
                                    enc_u_getw(color_size, cbp);
1919
397k
                                    left = color_size;
1920
397k
                                    if (!left) {
1921
                                        /* We still need to call pdct->read because it may change dev_color.type -
1922
                                           see gx_dc_null_read.*/
1923
664
                                        code = pdct->read(pdcolor, &gs_gstate,
1924
664
                                                          pdcolor, tdev, offset,
1925
664
                                                          cbp, 0, mem, x0, y0);
1926
664
                                        if (code < 0)
1927
0
                                            goto out;
1928
664
                                    }
1929
877k
                                    while (left) {
1930
480k
                                        if (cbuf.warn_limit - cbp < (int)left) {  /* cbp can be past warn_limit */
1931
92.6k
                                            code = top_up_cbuf(&cbuf, &cbp);
1932
92.6k
                                            if (code < 0)
1933
0
                                                goto top_up_failed;
1934
92.6k
                                        }
1935
480k
                                        l = min(left, cbuf.end - cbp);
1936
480k
                                        code = pdct->read(pdcolor, &gs_gstate,
1937
480k
                                                          pdcolor, tdev, offset,
1938
480k
                                                          cbp, l, mem, x0, y0);
1939
480k
                                        if (code < 0)
1940
0
                                            goto out;
1941
480k
                                        l = code;
1942
480k
                                        cbp += l;
1943
480k
                                        offset += l;
1944
480k
                                        left -= l;
1945
480k
                                    }
1946
397k
                                    code = gx_color_load(pdcolor, &gs_gstate,
1947
397k
                                                         tdev);
1948
397k
                                    if (code < 0)
1949
0
                                        goto out;
1950
397k
                                }
1951
397k
                                break;
1952
397k
                            default:
1953
0
                                goto bad_op;
1954
427k
                        }
1955
427k
                        break;
1956
427k
                    default:
1957
0
                        goto bad_op;
1958
694k
                }
1959
437k
                continue;
1960
437k
            case cmd_op_segment >> 4:
1961
44.0k
                {
1962
44.0k
                    int i;
1963
44.0k
                    static const byte op_num_operands[] = {
1964
44.0k
                        cmd_segment_op_num_operands_values
1965
44.0k
                    };
1966
44.0k
                  rgapto:
1967
44.0k
                    if (!in_path) {
1968
6.34k
                        ppos.x = int2fixed(state.rect.x);
1969
6.34k
                        ppos.y = int2fixed(state.rect.y);
1970
6.34k
                        if_debug2m('L', mem, " (%d,%d)", state.rect.x,
1971
6.34k
                                   state.rect.y);
1972
6.34k
                        notes = sn_none;
1973
6.34k
                        in_path = true;
1974
6.34k
                    }
1975
127k
                    for (i = 0; i < op_num_operands[op & 0xf]; ++i) {
1976
83.7k
                        fixed v;
1977
83.7k
                        int b = *cbp;
1978
1979
83.7k
                        switch (b >> 5) {
1980
13.9k
                            case 0:
1981
26.4k
                            case 1:
1982
26.4k
                                vs[i++] =
1983
26.4k
                                    ((fixed) ((b ^ 0x20) - 0x20) << 13) +
1984
26.4k
                                    ((int)cbp[1] << 5) + (cbp[2] >> 3);
1985
26.4k
                                if_debug1m('L', mem, " %g", fixed2float(vs[i - 1]));
1986
26.4k
                                cbp += 2;
1987
26.4k
                                v = (int)((*cbp & 7) ^ 4) - 4;
1988
26.4k
                                break;
1989
17.1k
                            case 2:
1990
33.8k
                            case 3:
1991
33.8k
                                v = (b ^ 0x60) - 0x20;
1992
33.8k
                                break;
1993
3.50k
                            case 4:
1994
6.39k
                            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
6.39k
                                v = (((b ^ 0xa0) - 0x20) << 8) + (int)*++cbp;
2003
6.39k
                                break;
2004
12.6k
                            case 6:
2005
12.6k
                                v = (b ^ 0xd0) - 0x10;
2006
12.6k
                                vs[i] =
2007
12.6k
                                    ((v << 8) + cbp[1]) << (_fixed_shift - 2);
2008
12.6k
                                if_debug1m('L', mem, " %g", fixed2float(vs[i]));
2009
12.6k
                                cbp += 2;
2010
12.6k
                                continue;
2011
4.46k
                            default /*case 7 */ :
2012
4.46k
                                v = (int)(*++cbp ^ 0x80) - 0x80;
2013
8.93k
                                for (b = 0; b < sizeof(fixed) - 3; ++b)
2014
4.46k
                                    v = (v << 8) + *++cbp;
2015
4.46k
                                break;
2016
83.7k
                        }
2017
71.1k
                        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
71.1k
                        vs[i] = (v << 16) + (uint) (cbp[-2] << 8) + cbp[-1];
2022
71.1k
                        if_debug1m('L', mem, " %g", fixed2float(vs[i]));
2023
71.1k
                    }
2024
44.0k
                    if_debug0m('L', mem, "\n");
2025
44.0k
                    code = clist_decode_segment(&path, op, vs, &ppos,
2026
44.0k
                                                x0, y0, notes);
2027
44.0k
                    if (code < 0)
2028
0
                        goto out;
2029
44.0k
                }
2030
44.0k
                continue;
2031
132k
            case cmd_op_path >> 4:
2032
132k
                if (op == cmd_opv_rgapto)
2033
0
                    goto rgapto;
2034
132k
                else if (op == cmd_opv_lock_pattern) {
2035
0
                    gs_id id;
2036
0
                    int lock = *cbp++;
2037
0
                    cmd_get_value(id, cbp);
2038
0
                    if_debug2m('L', mem, "id=0x%lx, lock=%d\n", id, lock);
2039
                    /* We currently lock the pattern in all the bands, even in ones
2040
                     * where we haven't used the pattern. This can cause the following
2041
                     * call to return with 'undefined' because the pattern is not
2042
                     * found. Just swallow this error and continue. */
2043
0
                    code = gx_pattern_cache_entry_set_lock(&gs_gstate, id, lock);
2044
0
                    if (code == gs_error_undefined)
2045
0
                        code = 0;
2046
0
                    if (code < 0)
2047
0
                        goto out;
2048
0
                    continue;
2049
132k
                } else {
2050
132k
                    gx_path fpath;
2051
132k
                    gx_path *ppath = &path;
2052
2053
132k
                    if_debug0m('L', mem, "\n");
2054
                    /* if in clip, flatten path first */
2055
132k
                    if (in_clip) {
2056
2.32k
                        gx_path_init_local(&fpath, mem);
2057
2.32k
                        code = gx_path_add_flattened_accurate(&path, &fpath,
2058
2.32k
                                             gs_currentflat_inline(&gs_gstate),
2059
2.32k
                                             gs_gstate.accurate_curves);
2060
2.32k
                        if (code < 0)
2061
0
                            goto out;
2062
2.32k
                        ppath = &fpath;
2063
2.32k
                    }
2064
132k
                    switch (op) {
2065
108k
                        case cmd_opv_fill:
2066
108k
                            fill_params.rule = gx_rule_winding_number;
2067
108k
                            goto fill;
2068
498
                        case cmd_opv_eofill:
2069
498
                            fill_params.rule = gx_rule_even_odd;
2070
109k
                        fill:
2071
109k
                            fill_params.adjust = gs_gstate.fill_adjust;
2072
109k
                            fill_params.flatness = gs_gstate.flatness;
2073
109k
                            code = (*dev_proc(tdev, fill_path))(tdev, &gs_gstate, ppath,
2074
109k
                                                                &fill_params, &fill_color, pcpath);
2075
109k
                            break;
2076
3.70k
                        case cmd_opv_fill_stroke:
2077
3.70k
                            fill_params.rule = gx_rule_winding_number;
2078
3.70k
                            goto fill_stroke;
2079
9
                        case cmd_opv_eofill_stroke:
2080
9
                            fill_params.rule = gx_rule_even_odd;
2081
3.71k
                        fill_stroke:
2082
3.71k
                            fill_params.adjust = gs_gstate.fill_adjust;
2083
3.71k
                            fill_params.flatness = gs_gstate.flatness;
2084
3.71k
                            stroke_params.flatness = gs_gstate.flatness;
2085
3.71k
                            stroke_params.traditional = false;
2086
3.71k
                            code = (*dev_proc(tdev, fill_stroke_path))(tdev, &gs_gstate, ppath,
2087
3.71k
                                                                &fill_params, &fill_color,
2088
3.71k
                                                                &stroke_params, &stroke_color, pcpath);
2089
3.71k
                            break;
2090
19.5k
                        case cmd_opv_stroke:
2091
19.5k
                            stroke_params.flatness = gs_gstate.flatness;
2092
19.5k
                            stroke_params.traditional = false;
2093
19.5k
                            code = (*dev_proc(tdev, stroke_path))
2094
19.5k
                                                       (tdev, &gs_gstate,
2095
19.5k
                                                       ppath, &stroke_params,
2096
19.5k
                                                       &stroke_color, pcpath);
2097
19.5k
                            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
81
                        case cmd_opv_fill_trapezoid:
2103
81
                            {
2104
81
                                gs_fixed_edge left, right;
2105
81
                                fixed ybot, ytop;
2106
81
                                int options, swap_axes, wh;
2107
81
                                fixed x0f;
2108
81
                                fixed y0f;
2109
81
                                gx_device *ttdev = tdev;
2110
2111
81
                                if (pcpath != NULL && !clipper_dev_open) {
2112
0
                                    gx_make_clip_device_on_stack(&clipper_dev, pcpath, tdev);
2113
0
                                    clipper_dev_open = true;
2114
0
                                }
2115
81
                                if (clipper_dev_open)
2116
0
                                    ttdev = (gx_device *)&clipper_dev;
2117
                                /* Note that if we have transparency present, the clipper device may need to have
2118
                                   its color information updated to be synced up with the target device.
2119
                                   This can occur if we had fills of a path first with a transparency mask to get
2120
                                   an XPS opacity followed by a fill with a transparency group. This occurs in
2121
                                   the XPS gradient code */
2122
81
                                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
81
                                cmd_getw(left.start.x, cbp);
2132
81
                                cmd_getw(left.start.y, cbp);
2133
81
                                cmd_getw(left.end.x, cbp);
2134
81
                                cmd_getw(left.end.y, cbp);
2135
81
                                cmd_getw(right.start.x, cbp);
2136
81
                                cmd_getw(right.start.y, cbp);
2137
81
                                cmd_getw(right.end.x, cbp);
2138
81
                                cmd_getw(right.end.y, cbp);
2139
81
                                cmd_getw(options, cbp);
2140
81
                                if (!(options & 4)) {
2141
67
                                    cmd_getw(ybot, cbp);
2142
67
                                    cmd_getw(ytop, cbp);
2143
67
                                } else
2144
14
                                    ytop = ybot = 0; /* Unused, but quiet gcc warning. */
2145
81
                                swap_axes = options & 1;
2146
81
                                wh = swap_axes ? tdev->width : tdev->height;
2147
81
                                x0f = int2fixed(swap_axes ? y0 : x0);
2148
81
                                y0f = int2fixed(swap_axes ? x0 : y0);
2149
81
                                left.start.x -= x0f;
2150
81
                                left.start.y -= y0f;
2151
81
                                left.end.x -= x0f;
2152
81
                                left.end.y -= y0f;
2153
81
                                right.start.x -= x0f;
2154
81
                                right.start.y -= y0f;
2155
81
                                right.end.x -= x0f;
2156
81
                                right.end.y -= y0f;
2157
81
                                if (options & 2) {
2158
53
                                    uchar num_components = tdev->color_info.num_components;
2159
53
                                    frac31 c[4][GX_DEVICE_COLOR_MAX_COMPONENTS], *cc[4];
2160
53
                                    byte colors_mask, i, j, m = 1;
2161
53
                                    gs_fill_attributes fa;
2162
53
                                    gs_fixed_rect clip;
2163
53
                                    fixed hh = int2fixed(swap_axes ? target->width : target->height);
2164
2165
53
                                    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
53
                                    cmd_getw(clip.p.x, cbp);
2171
53
                                    cmd_getw(clip.p.y, cbp);
2172
53
                                    cmd_getw(clip.q.x, cbp);
2173
53
                                    cmd_getw(clip.q.y, cbp);
2174
53
                                    clip.p.x -= x0f;
2175
53
                                    clip.p.y -= y0f;
2176
53
                                    clip.q.x -= x0f;
2177
53
                                    clip.q.y -= y0f;
2178
53
                                    if (clip.p.y < 0)
2179
0
                                        clip.p.y = 0;
2180
53
                                    if (clip.q.y > hh)
2181
26
                                        clip.q.y = hh;
2182
53
                                    fa.clip = &clip;
2183
53
                                    fa.swap_axes = swap_axes;
2184
53
                                    fa.ht = NULL;
2185
53
                                    fa.lop = lop_default; /* fgixme: gs_gstate.log_op; */
2186
53
                                    fa.ystart = ybot - y0f;
2187
53
                                    fa.yend = ytop - y0f;
2188
53
                                    cmd_getw(colors_mask, cbp);
2189
265
                                    for (i = 0; i < 4; i++, m <<= 1) {
2190
212
                                        if (colors_mask & m) {
2191
120
                                            if (cbuf.end - cbp < num_components * cmd_max_intsize(sizeof(frac31))) {
2192
2
                                                code = top_up_cbuf(&cbuf, &cbp);
2193
2
                                                if (code < 0)
2194
0
                                                    goto top_up_failed;
2195
2
                                            }
2196
120
                                            cc[i] = c[i];
2197
720
                                            for (j = 0; j < num_components; j++)
2198
600
                                                cmd_getfrac(c[i][j], cbp);
2199
120
                                        } else
2200
92
                                            cc[i] = NULL;
2201
212
                                    }
2202
53
                                    if (options & 4) {
2203
14
#                                       if 1 /* Disable to debug gx_fill_triangle_small. */
2204
14
                                        code = dev_proc(ttdev, fill_linear_color_triangle)(ttdev, &fa,
2205
14
                                                        &left.start, &left.end, &right.start,
2206
14
                                                        cc[0], cc[1], cc[2]);
2207
#                                       else
2208
                                        code = 0;
2209
#                                       endif
2210
14
                                        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
39
                                    } else {
2225
39
                                        code = dev_proc(ttdev, fill_linear_color_trapezoid)(ttdev, &fa,
2226
39
                                                        &left.start, &left.end, &right.start, &right.end,
2227
39
                                                        cc[0], cc[1], cc[2], cc[3]);
2228
39
                                        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
39
                                    }
2238
53
                                } else
2239
28
                                    code = gx_default_fill_trapezoid(ttdev, &left, &right,
2240
28
                                        max(ybot - y0f, fixed_half),
2241
28
                                        min(ytop - y0f, int2fixed(wh)), swap_axes,
2242
28
                                        &fill_color, gs_gstate.log_op);
2243
81
                            }
2244
81
                           break;
2245
81
                        default:
2246
0
                            goto bad_op;
2247
132k
                    }
2248
132k
                    if (ppath != &path)
2249
2.32k
                        gx_path_free(ppath, "clist_render_band");
2250
132k
                }
2251
132k
                if (in_path) {  /* path might be empty! */
2252
6.34k
                    state.rect.x = fixed2int_var(ppos.x);
2253
6.34k
                    state.rect.y = fixed2int_var(ppos.y);
2254
6.34k
                    in_path = false;
2255
6.34k
                }
2256
132k
                gx_path_free(&path, "clist_render_band");
2257
132k
                gx_path_init_local(&path, mem);
2258
132k
                if (code < 0)
2259
0
                    goto out;
2260
132k
                continue;
2261
132k
            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
940k
        }
2277
940k
        if_debug4m('L', mem, " x=%d y=%d w=%d h=%d\n",
2278
10.0k
                  state.rect.x, state.rect.y, state.rect.width,
2279
10.0k
                  state.rect.height);
2280
10.0k
        switch (op >> 4) {
2281
4.51k
            case cmd_op_fill_rect >> 4:
2282
4.51k
                if (state.rect.width == 0 && state.rect.height == 0 &&
2283
4.51k
                    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
3.46k
                    code = (dev_proc(tdev, fillpage) == NULL ? 0 :
2287
3.46k
                            (*dev_proc(tdev, fillpage))(tdev, &gs_gstate,
2288
3.46k
                                                        &fill_color));
2289
3.46k
                    break;
2290
3.46k
                }
2291
1.06k
            case cmd_op_fill_rect_short >> 4:
2292
1.37k
            case cmd_op_fill_rect_tiny >> 4:
2293
1.37k
                if (!state.lop_enabled) {
2294
1.37k
                    code = (*dev_proc(tdev, fill_rectangle))
2295
1.37k
                        (tdev, state.rect.x - x0, state.rect.y - y0,
2296
1.37k
                         state.rect.width, state.rect.height,
2297
1.37k
                         state.colors[1]);
2298
1.37k
                    break;
2299
1.37k
                }
2300
0
                source = NULL;
2301
0
                data_x = 0;
2302
0
                raster = 0;
2303
0
                colors[0] = colors[1] = state.colors[1];
2304
0
                log_op = state.lop;
2305
0
                pcolor = colors;
2306
0
         do_rop:code = (*dev_proc(tdev, strip_copy_rop2))
2307
0
                                (tdev, source, data_x, raster, gx_no_bitmap_id,
2308
0
                                 pcolor, &state_tile,
2309
0
                                 (state.tile_colors[0] == gx_no_color_index &&
2310
0
                                  state.tile_colors[1] == gx_no_color_index ?
2311
0
                                  NULL : state.tile_colors),
2312
0
                                 state.rect.x - x0, state.rect.y - y0,
2313
0
                                 state.rect.width - data_x, state.rect.height,
2314
0
                                 tile_phase.x, tile_phase.y, log_op,
2315
0
                                 plane_height);
2316
0
                     plane_height = 0;
2317
0
                data_x = 0;
2318
0
                break;
2319
0
            case cmd_op_tile_rect >> 4:
2320
0
                if (state.rect.width == 0 && state.rect.height == 0 &&
2321
0
                    state.rect.x == 0 && state.rect.y == 0) {
2322
0
                    code = (*dev_proc(tdev, fillpage))(tdev, &gs_gstate, &fill_color);
2323
0
                    break;
2324
0
                }
2325
0
            case cmd_op_tile_rect_short >> 4:
2326
0
            case cmd_op_tile_rect_tiny >> 4:
2327
                /* Currently we don't use lop with strip_tile_rectangle. */
2328
0
                code = (*dev_proc(tdev, strip_tile_rectangle))
2329
0
                    (tdev, &state_tile,
2330
0
                     state.rect.x - x0, state.rect.y - y0,
2331
0
                     state.rect.width, state.rect.height,
2332
0
                     state.tile_colors[0], state.tile_colors[1],
2333
0
                     tile_phase.x, tile_phase.y);
2334
0
                break;
2335
5.23k
            case cmd_op_copy_mono_planes >> 4:
2336
5.23k
                if (state.lop_enabled) {
2337
0
                    pcolor = state.colors;
2338
0
                    log_op = state.lop;
2339
0
                    goto do_rop;
2340
0
                }
2341
5.23k
                if ((op & cmd_copy_use_tile) || pcpath != NULL) {       /*
2342
                                                                         * This call of copy_mono originated as a call
2343
                                                                         * of fill_mask.
2344
                                                                         */
2345
5.23k
                    code = gx_image_fill_masked
2346
5.23k
                        (tdev, source, data_x, raster, gx_no_bitmap_id,
2347
5.23k
                         state.rect.x - x0, state.rect.y - y0,
2348
5.23k
                         state.rect.width - data_x, state.rect.height,
2349
5.23k
                         &fill_color, 1, gs_gstate.log_op, pcpath);
2350
5.23k
                } else {
2351
0
                    if (plane_height == 0) {
2352
0
                        code = (*dev_proc(tdev, copy_mono))
2353
0
                             (tdev, source, data_x, raster, gx_no_bitmap_id,
2354
0
                              state.rect.x - x0, state.rect.y - y0,
2355
0
                              state.rect.width - data_x, state.rect.height,
2356
0
                              state.colors[0], state.colors[1]);
2357
0
                    } else {
2358
0
                        code = (*dev_proc(tdev, copy_planes))
2359
0
                             (tdev, source, data_x, raster, gx_no_bitmap_id,
2360
0
                              state.rect.x - x0, state.rect.y - y0,
2361
0
                              state.rect.width - data_x, state.rect.height,
2362
0
                              plane_height);
2363
0
                    }
2364
0
                }
2365
5.23k
                plane_height = 0;
2366
5.23k
                data_x = 0;
2367
5.23k
                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
10.0k
        }
2401
10.0k
    }
2402
    /* Clean up before we exit. */
2403
3.46k
  out:
2404
3.46k
    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
3.46k
    ht_buff.ht_size = 0;
2410
3.46k
    ht_buff.read_size = 0;
2411
2412
3.46k
    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
3.46k
    gx_cpath_free(&clip_path, "clist_render_band exit");
2419
3.46k
    gx_path_free(&path, "clist_render_band exit");
2420
3.46k
    if (gs_gstate.pattern_cache != NULL) {
2421
34
        gx_pattern_cache_free(gs_gstate.pattern_cache);
2422
34
        gs_gstate.pattern_cache = NULL;
2423
34
    }
2424
    /* Free the client color and device colors allocated upon entry */
2425
3.46k
    gs_free_object(mem, gs_gstate.color[0].ccolor, "clist_playback_band");
2426
3.46k
    gs_free_object(mem, gs_gstate.color[1].ccolor, "clist_playback_band");
2427
3.46k
    gs_free_object(mem, gs_gstate.color[0].dev_color, "clist_playback_band");
2428
3.46k
    gs_free_object(mem, gs_gstate.color[1].dev_color, "clist_playback_band");
2429
3.46k
    gs_gstate.color[0].ccolor = gs_gstate.color[1].ccolor = NULL;
2430
3.46k
    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
3.46k
    gx_monitor_enter(cdev->icc_cache_cl->lock);
2435
3.46k
    gs_gstate_release(&gs_gstate);
2436
3.46k
    gx_monitor_leave(cdev->icc_cache_cl->lock); /* done with increment, let everyone run */
2437
3.46k
    gs_free_object(mem, data_bits, "clist_playback_band(data_bits)");
2438
3.46k
    if (target != orig_target) {
2439
595
        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
595
        } else {
2448
            /* Ref count was 1. close the device and then free it */
2449
595
            if (target->is_open)
2450
62
                dev_proc(target, close_device)(target);
2451
595
            gs_free_object(target->memory, target, "gxclrast discard compositor");
2452
595
        }
2453
595
        target = orig_target;
2454
595
    }
2455
3.46k
    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
3.46k
    if ((playback_action != playback_action_setup &&
2470
3.46k
        (cbp < cbuf.end || !seofp(s)) && (op != cmd_opv_end_page) )
2471
3.46k
        )
2472
0
        goto in;
2473
3.46k
    if (pfs.dev != NULL)
2474
0
        term_patch_fill_state(&pfs);
2475
3.46k
    rc_decrement(gs_gstate.color[0].color_space, "clist_playback_band");
2476
3.46k
    rc_decrement(gs_gstate.color[1].color_space, "clist_playback_band");
2477
3.46k
    gs_free_object(mem, cbuf_storage, "clist_playback_band(cbuf_storage)");
2478
3.46k
    gx_cpath_free(&clip_path, "clist_playback_band");
2479
3.46k
    if (pcpath != &clip_path)
2480
3.14k
        gx_cpath_free(pcpath, "clist_playback_band");
2481
3.46k
    if (clipper_dev_open)
2482
0
        gx_destroy_clip_device_on_stack(&clipper_dev);
2483
3.46k
    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
3.46k
}
2492
2493
/* ---------------- Individual commands ---------------- */
2494
2495
/*
2496
 * These single-use procedures implement a few large individual commands,
2497
 * primarily for readability but also to avoid overflowing compilers'
2498
 * optimization limits.  They all take the command buffer as their first
2499
 * parameter (pcb), assume that the current buffer pointer is in pcb->ptr,
2500
 * and update it there.
2501
 */
2502
2503
static int
2504
read_set_tile_size(command_buf_t *pcb, tile_slot *bits, bool for_pattern)
2505
0
{
2506
0
    const byte *cbp = pcb->ptr;
2507
0
    uint rep_width, rep_height;
2508
0
    uint pdepth;
2509
0
    byte bd = *cbp++;
2510
2511
0
    bits->head.depth = cmd_code_to_depth(bd);
2512
0
    if (for_pattern)
2513
0
        cmd_getw(bits->id, cbp);
2514
0
    cmd_getw(rep_width, cbp);
2515
0
    cmd_getw(rep_height, cbp);
2516
0
    if (bd & 0x20) {
2517
0
        cmd_getw(bits->x_reps, cbp);
2518
0
        bits->width = rep_width * bits->x_reps;
2519
0
    } else {
2520
0
        bits->x_reps = 1;
2521
0
        bits->width = rep_width;
2522
0
    }
2523
0
    if (bd & 0x40) {
2524
0
        cmd_getw(bits->y_reps, cbp);
2525
0
        bits->height = rep_height * bits->y_reps;
2526
0
    } else {
2527
0
        bits->y_reps = 1;
2528
0
        bits->height = rep_height;
2529
0
    }
2530
0
    if (bd & 0x80)
2531
0
        cmd_getw(bits->rep_shift, cbp);
2532
0
    else
2533
0
        bits->rep_shift = 0;
2534
0
    if (bd & 0x10)
2535
0
        bits->num_planes = *cbp++;
2536
0
    else
2537
0
        bits->num_planes = 1;
2538
0
    if_debug7('L', " depth=%d size=(%d,%d), rep_size=(%d,%d), rep_shift=%d, num_planes=%d\n",
2539
0
              bits->head.depth, bits->width,
2540
0
              bits->height, rep_width,
2541
0
              rep_height, bits->rep_shift, bits->num_planes);
2542
0
    bits->shift =
2543
0
        (bits->rep_shift == 0 ? 0 :
2544
0
         (bits->rep_shift * (bits->height / rep_height)) % rep_width);
2545
0
    pdepth = bits->head.depth;
2546
0
    if (bits->num_planes != 1)
2547
0
        pdepth /= bits->num_planes;
2548
0
    bits->raster = bitmap_raster(bits->width * pdepth);
2549
0
    pcb->ptr = cbp;
2550
0
    return 0;
2551
0
}
2552
2553
static int
2554
read_set_bits(command_buf_t *pcb, tile_slot *bits, int compress,
2555
              gx_clist_state *pcls, gx_strip_bitmap *tile, tile_slot **pslot,
2556
              gx_device_clist_reader *cdev, gs_memory_t *mem)
2557
3.16k
{
2558
3.16k
    const byte *cbp = pcb->ptr;
2559
3.16k
    uint rep_width = bits->width / bits->x_reps;
2560
3.16k
    uint rep_height = bits->height / bits->y_reps;
2561
3.16k
    uint index;
2562
3.16k
    ulong offset;
2563
3.16k
    uint width_bits;
2564
3.16k
    uint width_bytes;
2565
3.16k
    uint raster;
2566
3.16k
    uint bytes;
2567
3.16k
    byte *data;
2568
3.16k
    tile_slot *slot;
2569
3.16k
    uint depth = bits->head.depth;
2570
2571
3.16k
    if (bits->num_planes != 1)
2572
0
        depth /= bits->num_planes;
2573
3.16k
    width_bits = rep_width * depth;
2574
2575
3.16k
    bytes = clist_bitmap_bytes(width_bits, rep_height * bits->num_planes,
2576
3.16k
                               compress |
2577
3.16k
                               (rep_width < bits->width ?
2578
3.16k
                                decompress_spread : 0) |
2579
3.16k
                               decompress_elsewhere,
2580
3.16k
                               &width_bytes,
2581
3.16k
                               (uint *)&raster);
2582
2583
3.16k
    cmd_getw(index, cbp);
2584
3.16k
    cmd_getw(offset, cbp);
2585
3.16k
    if_debug2m('L', mem, " index=%d offset=%lu\n", index, offset);
2586
3.16k
    pcls->tile_index = index;
2587
3.16k
    cdev->tile_table[pcls->tile_index].offset = offset;
2588
3.16k
    slot = (tile_slot *)(cdev->cache_chunk->data + offset);
2589
3.16k
    *pslot = slot;
2590
3.16k
    *slot = *bits;
2591
3.16k
    tile->data = data = (byte *)(slot + 1);
2592
#ifdef DEBUG
2593
    slot->index = pcls->tile_index;
2594
#endif
2595
3.16k
    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
3.16k
    } 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
1.70k
        stream_cursor_read r;
2605
1.70k
        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
1.70k
        uint cleft = pcb->end - cbp;
2611
2612
1.70k
        if (cleft < bytes && !pcb->end_status) {
2613
0
            uint nread = cbuf_size - cleft;
2614
2615
0
            advance_buffer(pcb, cbp);
2616
0
            pcb->end_status = sgets(pcb->s, pcb->data + cleft, nread, &nread);
2617
0
            set_cb_end(pcb, pcb->data + cleft + nread);
2618
0
            cbp = pcb->data;
2619
0
        }
2620
1.70k
        r.ptr = cbp - 1;
2621
1.70k
        r.limit = pcb->end - 1;
2622
1.70k
        w.ptr = data - 1;
2623
1.70k
        w.limit = w.ptr + bytes;
2624
1.70k
        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
1.70k
        case cmd_compress_cfe:
2635
1.70k
            {
2636
1.70k
                stream_CFD_state sstate;
2637
2638
1.70k
                clist_cfd_init(&sstate,
2639
1.70k
                               width_bytes << 3 /*width_bits */ ,
2640
1.70k
                               rep_height, mem);
2641
1.70k
                (*s_CFD_template.process)
2642
1.70k
                    ((stream_state *)&sstate, &r, &w, true);
2643
1.70k
                (*s_CFD_template.release)
2644
1.70k
                    ((stream_state *)&sstate);
2645
1.70k
            }
2646
1.70k
            break;
2647
0
        default:
2648
0
            return_error(gs_error_unregistered);
2649
1.70k
        }
2650
1.70k
        cbp = r.ptr + 1;
2651
1.70k
    } else if (rep_height * bits->num_planes > 1 && width_bytes != bits->raster) {
2652
1.46k
        cbp = cmd_read_short_bits(pcb, data, bytes,
2653
1.46k
                                  width_bytes, rep_height * bits->num_planes,
2654
1.46k
                                  bits->raster, cbp);
2655
1.46k
    } else {
2656
1
        cbp = cmd_read_data(pcb, data, bytes, cbp);
2657
1
    }
2658
3.16k
    if (bits->width > rep_width)
2659
0
        bits_replicate_horizontally(data,
2660
0
                                    rep_width * depth, rep_height * bits->num_planes,
2661
0
                                    bits->raster,
2662
0
                                    bits->width * depth,
2663
0
                                    bits->raster);
2664
3.16k
    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
3.16k
    pcb->ptr = cbp;
2673
3.16k
    return 0;
2674
3.16k
}
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
2
{
2680
    /* free the existing buffer, if any (usually none) */
2681
2
    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
2
    if (ht_size > cbuf_ht_seg_max_size) {
2691
0
        pht_buff->pbuff = gs_alloc_bytes(mem, ht_size, "read_alloc_ht_buff");
2692
0
        if (pht_buff->pbuff == 0)
2693
0
            return_error(gs_error_VMerror);
2694
0
    }
2695
2
    pht_buff->ht_size = ht_size;
2696
2
    pht_buff->read_size = 0;
2697
2
    pht_buff->pcurr = pht_buff->pbuff;
2698
2
    return 0;
2699
2
}
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
2
{
2710
2
    const byte *                cbp = pcb->ptr;
2711
2
    const byte *                pbuff = 0;
2712
2
    uint                        ht_size = pht_buff->ht_size, seg_size;
2713
2
    int                         code = 0;
2714
2715
    /* get the segment size; refill command buffer if necessary */
2716
2
    enc_u_getw(seg_size, cbp);
2717
2
    if (pcb->warn_limit - cbp < (int)seg_size) { /* cbp can be past warn_limit */
2718
0
        code = top_up_cbuf(pcb, &cbp);
2719
0
        if (code < 0)
2720
0
            return code;
2721
0
        if (pcb->end - cbp < (int)seg_size) {
2722
0
            emprintf(mem, " *** ht segment size doesn't fit in buffer ***\n");
2723
0
            return_error(gs_error_unknownerror);
2724
0
        }
2725
0
    }
2726
2727
2
    if (pht_buff->pbuff == 0) {
2728
        /* if not separate buffer, must be only one segment */
2729
2
        if (seg_size != ht_size)
2730
0
            return_error(gs_error_unknownerror);
2731
2
        pbuff = cbp;
2732
2
    } else {
2733
0
        if (seg_size + pht_buff->read_size > pht_buff->ht_size)
2734
0
            return_error(gs_error_unknownerror);
2735
0
        memcpy(pht_buff->pcurr, cbp, seg_size);
2736
0
        pht_buff->pcurr += seg_size;
2737
0
        if ((pht_buff->read_size += seg_size) == ht_size)
2738
0
            pbuff = pht_buff->pbuff;
2739
0
    }
2740
2741
    /* if everything has been read, convert back to a halftone */
2742
2
    if (pbuff != 0) {
2743
2
        code = gx_ht_read_and_install(pgs, dev, pbuff, ht_size, mem);
2744
2745
        /* release any buffered information */
2746
2
        if (pht_buff->pbuff != 0) {
2747
0
            gs_free_object(mem, pht_buff->pbuff, "read_alloc_ht_buff");
2748
0
            pht_buff->pbuff = 0;
2749
0
            pht_buff->pcurr = 0;
2750
0
        }
2751
2
        pht_buff->ht_size = 0;
2752
2
        pht_buff->read_size = 0;
2753
2
    }
2754
2755
    /* update the command buffer ponter */
2756
2
    pcb->ptr = cbp + seg_size;
2757
2758
2
    return code;
2759
2
}
2760
2761
static int
2762
read_set_misc2(command_buf_t *pcb, gs_gstate *pgs, segment_notes *pnotes)
2763
4.43k
{
2764
4.43k
    const byte *cbp = pcb->ptr;
2765
4.43k
    uint mask, cb;
2766
2767
4.43k
    if_debug0m('L', pgs->memory, "\n");
2768
4.43k
    cmd_getw(mask, cbp);
2769
4.43k
    if (mask & cap_join_known) {
2770
332
        cb = *cbp++;
2771
332
        pgs->line_params.start_cap = (gs_line_cap)((cb >> 3) & 7);
2772
332
        pgs->line_params.join = (gs_line_join)(cb & 7);
2773
332
        if_debug2m('L', pgs->memory, "[L]      start_cap=%d join=%d\n",
2774
332
                   pgs->line_params.start_cap, pgs->line_params.join);
2775
332
        cb = *cbp++;
2776
332
        pgs->line_params.end_cap = (gs_line_cap)((cb >> 3) & 7);
2777
332
        pgs->line_params.dash_cap = (gs_line_cap)(cb & 7);
2778
332
        if_debug2m('L', pgs->memory, "[L]      end_cap=%d dash_cap=%d\n",
2779
332
                   pgs->line_params.end_cap, pgs->line_params.dash_cap);
2780
332
    }
2781
4.43k
    if (mask & cj_ac_sa_known) {
2782
742
        cb = *cbp++;
2783
742
        pgs->line_params.curve_join = ((cb >> 2) & 7) - 1;
2784
742
        pgs->accurate_curves = (cb & 2) != 0;
2785
742
        pgs->stroke_adjust = cb & 1;
2786
742
        if_debug3m('L', pgs->memory, "[L]      CJ=%d AC=%d SA=%d\n",
2787
742
                   pgs->line_params.curve_join, pgs->accurate_curves,
2788
742
                   pgs->stroke_adjust);
2789
742
    }
2790
4.43k
    if (mask & flatness_known) {
2791
3.22k
        cmd_get_value(pgs->flatness, cbp);
2792
3.22k
        if_debug1m('L', pgs->memory, "[L]      flatness=%g\n", pgs->flatness);
2793
3.22k
    }
2794
4.43k
    if (mask & line_width_known) {
2795
710
        float width;
2796
2797
710
        cmd_get_value(width, cbp);
2798
710
        if_debug1m('L', pgs->memory, "[L]      line_width=%g\n", width);
2799
710
        gx_set_line_width(&pgs->line_params, width);
2800
710
    }
2801
4.43k
    if (mask & miter_limit_known) {
2802
60
        float limit;
2803
2804
60
        cmd_get_value(limit, cbp);
2805
60
        if_debug1m('L', pgs->memory, "[L]      miter_limit=%g\n", limit);
2806
60
        gx_set_miter_limit(&pgs->line_params, limit);
2807
60
    }
2808
4.43k
    if (mask & op_bm_tk_known) {
2809
1.56k
        cb = *cbp++;
2810
1.56k
        pgs->blend_mode = cb >> 3;
2811
1.56k
        pgs->text_knockout = cb & 1;
2812
        /* the following usually have no effect; see gxclpath.c */
2813
1.56k
        cb = *cbp++;
2814
1.56k
        pgs->overprint_mode = (cb >> 2) & 1;
2815
1.56k
        pgs->stroke_overprint = (cb >> 1) & 1;
2816
1.56k
        pgs->overprint = cb & 1;
2817
1.56k
        cb = *cbp++;
2818
1.56k
        pgs->renderingintent = cb;
2819
1.56k
        if_debug6m('L', pgs->memory, "[L]      BM=%d TK=%d OPM=%d OP=%d op=%d RI=%d\n",
2820
1.56k
                   pgs->blend_mode, pgs->text_knockout, pgs->overprint_mode,
2821
1.56k
                   pgs->stroke_overprint, pgs->overprint, pgs->renderingintent);
2822
1.56k
    }
2823
4.43k
    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
4.43k
    if (mask & ais_known) {
2829
99
        cmd_get_value(pgs->alphaisshape, cbp);
2830
99
        if_debug1m('L', pgs->memory, "[L]      alphaisshape=%d\n", pgs->alphaisshape);
2831
99
    }
2832
4.43k
    if (mask & stroke_alpha_known) {
2833
124
        cmd_get_value(pgs->strokeconstantalpha, cbp);
2834
124
        if_debug1m('L', pgs->memory, "[L]      strokeconstantalpha=%g\n", pgs->strokeconstantalpha);
2835
124
    }
2836
4.43k
    if (mask & fill_alpha_known) {
2837
155
        cmd_get_value(pgs->fillconstantalpha, cbp);
2838
155
        if_debug1m('L', pgs->memory, "[L]      fillconstantalpha=%u\n", (uint)(pgs->fillconstantalpha));
2839
155
    }
2840
4.43k
    pcb->ptr = cbp;
2841
4.43k
    return 0;
2842
4.43k
}
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
60
{
2848
60
    const byte *cbp = pcb->ptr;
2849
60
    byte b = *cbp++;
2850
60
    int index = b >> 4;
2851
60
    gs_color_space *pcs;
2852
60
    int code = 0;
2853
60
    cmm_profile_t *picc_profile;
2854
60
    clist_icc_color_t icc_information;
2855
2856
60
    if_debug3m('L', mem, " %d%s%s\n", index,
2857
60
               (b & 8 ? " (indexed)" : ""),
2858
60
               (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
60
    memcpy(&icc_information, cbp, sizeof(clist_icc_color_t));
2864
60
    cbp = cbp + sizeof(clist_icc_color_t);
2865
60
    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
60
    case gs_color_space_index_ICC:
2876
        /* build the color space object */
2877
60
        code = gs_cspace_build_ICC(&pcs, NULL, mem);
2878
        /* Don't bother getting the ICC stuff from the clist yet */
2879
60
        picc_profile = gsicc_profile_new(NULL, cdev->memory, NULL, 0);
2880
60
        if (picc_profile == NULL)
2881
0
            return gs_rethrow(-1, "Failed to find ICC profile during clist read");
2882
60
        picc_profile->num_comps = icc_information.icc_num_components;
2883
60
        picc_profile->hashcode = icc_information.icc_hash;
2884
60
        picc_profile->hash_is_valid = true;
2885
60
        picc_profile->islab = icc_information.is_lab;
2886
60
        picc_profile->default_match = icc_information.default_match;
2887
60
        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
60
        picc_profile->dev = (gx_device*) cdev;
2893
        /* Assign it to the colorspace */
2894
60
        code = gsicc_set_gscs_profile(pcs, picc_profile, mem);
2895
        /* And we no longer need our reference to the profile */
2896
60
        gsicc_adjust_profile_rc(picc_profile, -1, "read_set_color_space");
2897
60
        break;
2898
0
    default:
2899
0
        code = gs_note_error(gs_error_rangecheck);      /* others are NYI */
2900
0
        goto out;
2901
60
    }
2902
2903
60
    if (pcs == NULL) {
2904
0
        code = gs_note_error(gs_error_VMerror);
2905
0
        goto out;
2906
0
    }
2907
2908
60
    if (b & 8) {
2909
0
        bool use_proc = (b & 4) != 0;
2910
0
        int hival;
2911
0
        int num_values;
2912
0
        byte *data;
2913
0
        uint data_size;
2914
0
        gs_color_space *pcs_indexed;
2915
2916
0
        pcs_indexed = gs_cspace_alloc(mem, &gs_color_space_type_Indexed);
2917
0
        if (pcs_indexed == 0) {
2918
0
            rc_decrement_cs(pcs, "read_set_color_space");
2919
0
            code = gs_note_error(gs_error_VMerror);
2920
0
            goto out;
2921
0
        }
2922
0
        pcs_indexed->base_space = pcs;
2923
0
        pcs = pcs_indexed;
2924
0
        pcs->params.indexed.use_proc = 0;
2925
0
        pcs->params.indexed.lookup.table.data = 0;
2926
0
        pcs->params.indexed.lookup.table.size = 0;
2927
0
        cmd_getw(hival, cbp);
2928
0
        pcs->params.indexed.n_comps = gs_color_space_num_components(pcs->base_space);
2929
0
        num_values = (hival + 1) * pcs->params.indexed.n_comps;
2930
0
        if (use_proc) {
2931
0
            gs_indexed_map *map;
2932
2933
0
            code = alloc_indexed_map(&map, num_values, mem, "indexed map");
2934
0
            if (code < 0) {
2935
0
                rc_decrement_cs(pcs, "read_set_color_space");
2936
0
                goto out;
2937
0
            }
2938
0
            map->proc.lookup_index = lookup_indexed_map;
2939
0
            pcs->params.indexed.lookup.map = map;
2940
0
            data = (byte *)map->values;
2941
0
            data_size = num_values * sizeof(map->values[0]);
2942
0
        } else {
2943
0
            byte *table = gs_alloc_string(mem, num_values, "color_space indexed table");
2944
2945
0
            if (table == 0) {
2946
0
                code = gs_note_error(gs_error_VMerror);
2947
0
                rc_decrement_cs(pcs, "read_set_color_space");
2948
0
                goto out;
2949
0
            }
2950
0
            pcs->params.indexed.lookup.table.data = table;
2951
0
            pcs->params.indexed.lookup.table.size = num_values;
2952
0
            data = table;
2953
0
            data_size = num_values;
2954
0
        }
2955
0
        cbp = cmd_read_data(pcb, data, data_size, cbp);
2956
0
        pcs->params.indexed.hival = hival;
2957
0
        pcs->params.indexed.use_proc = use_proc;
2958
0
    }
2959
2960
    /* Release reference to old color space before installing new one. */
2961
60
    if (pgs->color[0].color_space != NULL)
2962
60
        rc_decrement_only_cs(pgs->color[0].color_space, "read_set_color_space");
2963
60
    pgs->color[0].color_space = pcs;
2964
60
out:
2965
60
    pcb->ptr = cbp;
2966
60
    return code;
2967
60
}
2968
2969
static int
2970
read_begin_image(command_buf_t *pcb, gs_image_common_t *pic,
2971
                 gs_color_space *pcs)
2972
60
{
2973
60
    uint index = *(pcb->ptr)++;
2974
60
    const gx_image_type_t *image_type = gx_image_type_table[index];
2975
60
    stream s;
2976
60
    int code;
2977
2978
    /* This is sloppy, but we don't have enough information to do better. */
2979
60
    code = top_up_cbuf(pcb, &pcb->ptr);
2980
60
    if (code < 0)
2981
0
        return code;
2982
60
    s_init(&s, NULL);
2983
60
    sread_string(&s, pcb->ptr, pcb->end - pcb->ptr);
2984
60
    code = image_type->sget(pic, &s, pcs);
2985
60
    pcb->ptr = sbufptr(&s);
2986
60
    pic->imagematrices_are_untrustworthy = 0;
2987
60
    return code;
2988
60
}
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
310k
{
3086
310k
    const byte *                cbp = pcb->ptr;
3087
310k
    int                         comp_id = 0, code = 0;
3088
310k
    const gs_composite_type_t * pcomp_type = 0;
3089
3090
    /* fill the command buffer (see comment above) */
3091
310k
    if (pcb->end - cbp < MAX_CLIST_COMPOSITOR_SIZE + sizeof(comp_id)) {
3092
8.96k
        code = top_up_cbuf(pcb, &cbp);
3093
8.96k
        if (code < 0)
3094
0
            return code;
3095
8.96k
    }
3096
3097
    /* find the appropriate compositor method vector */
3098
310k
    comp_id = *cbp++;
3099
310k
    if ((pcomp_type = gs_find_compositor(comp_id)) == 0)
3100
0
        return_error(gs_error_unknownerror);
3101
3102
    /* de-serialize the compositor */
3103
310k
    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
310k
    if ( code > MAX_CLIST_COMPOSITOR_SIZE )
3107
0
        return_error(gs_error_rangecheck);
3108
3109
310k
    if (code > 0)
3110
310k
        cbp += code;
3111
310k
    pcb->ptr = cbp;
3112
310k
    return code;
3113
310k
}
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
298k
{
3119
298k
    gx_device *tdev = *ptarget;
3120
298k
    int code;
3121
3122
298k
    code = pcomp->type->procs.adjust_ctm(pcomp, x0, y0, pgs);
3123
298k
    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
298k
    code = dev_proc(tdev, composite)(tdev, &tdev, pcomp, pgs, mem, (gx_device*) cdev);
3130
298k
    if (code == 1) {
3131
        /* A new compositor was created that wrapped tdev. This should
3132
         * be our new target. */
3133
595
        *ptarget = tdev;
3134
595
        code = 0;
3135
595
    }
3136
298k
    if (code < 0)
3137
0
        goto exit;
3138
3139
    /* Perform any updates for the clist device required */
3140
298k
    code = pcomp->type->procs.clist_compositor_read_update(pcomp,
3141
298k
                                        (gx_device *)cdev, tdev, pgs, mem);
3142
298k
exit:
3143
    /* free the compositor object */
3144
298k
    gs_free_object(mem, pcomp, "read_composite");
3145
3146
298k
    return code;
3147
298k
}
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
1.46k
{
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
1.46k
    cbp = cmd_read_data(pcb, data, tot_bytes, cbp);
3166
3167
    /* if needed, adjust buffer contents for dest raster > width_bytes */
3168
1.46k
    if (width_bytes < raster) {
3169
1.46k
        const byte *pdata = data /*src*/ + width_bytes * height;
3170
1.46k
        byte *udata = data /*dest*/ + height * raster;
3171
3172
28.6k
        while (--height > 0) { /* don't need to move the first line to itself */
3173
27.2k
            udata -= raster, pdata -= width_bytes;
3174
27.2k
            switch (width_bytes) {
3175
0
                default:
3176
0
                    memmove(udata, pdata, width_bytes);
3177
0
                    break;
3178
0
                case 6:
3179
0
                    udata[5] = pdata[5];
3180
0
                case 5:
3181
0
                    udata[4] = pdata[4];
3182
41
                case 4:
3183
41
                    udata[3] = pdata[3];
3184
2.60k
                case 3:
3185
2.60k
                    udata[2] = pdata[2];
3186
18.3k
                case 2:
3187
18.3k
                    udata[1] = pdata[1];
3188
27.2k
                case 1:
3189
27.2k
                    udata[0] = pdata[0];
3190
27.2k
                case 0:;            /* shouldn't happen */
3191
27.2k
            }
3192
27.2k
        }
3193
1.46k
    }
3194
1.46k
    return cbp;
3195
1.46k
}
3196
3197
/* Read a rectangle. */
3198
static const byte *
3199
cmd_read_rect(int op, gx_cmd_rect * prect, const byte * cbp)
3200
251k
{
3201
251k
    cmd_getw(prect->x, cbp);
3202
251k
    if (op & 0xf)
3203
132
        prect->y += ((op >> 2) & 3) - 2;
3204
251k
    else {
3205
251k
        cmd_getw(prect->y, cbp);
3206
251k
    }
3207
251k
    cmd_getw(prect->width, cbp);
3208
251k
    if (op & 0xf)
3209
132
        prect->height += (op & 3) - 2;
3210
251k
    else {
3211
251k
        cmd_getw(prect->height, cbp);
3212
251k
    }
3213
251k
    return cbp;
3214
251k
}
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
3.86k
{
3232
3.86k
    gx_transfer_map *map;
3233
3.86k
    gx_transfer_map **pmap;
3234
3.86k
    const char *cname;
3235
3236
3.86k
    *pcomp_num = NULL;          /* Only used for color transfer maps */
3237
3.86k
    switch (map_index) {
3238
1.09k
        case cmd_map_transfer:
3239
1.09k
            if_debug0m('L', mem, " transfer");
3240
1.09k
            rc_unshare_struct(pgs->set_transfer.gray, gx_transfer_map,
3241
1.09k
                &st_transfer_map, mem, return_error(gs_error_VMerror),
3242
1.09k
                "cmd_select_map(default_transfer)");
3243
1.09k
            map = pgs->set_transfer.gray;
3244
            /* Release all current maps */
3245
1.09k
            rc_decrement(pgs->set_transfer.red, "cmd_select_map(red)");
3246
1.09k
            pgs->set_transfer.red = NULL;
3247
1.09k
            pgs->set_transfer.red_component_num = -1;
3248
1.09k
            rc_decrement(pgs->set_transfer.green, "cmd_select_map(green)");
3249
1.09k
            pgs->set_transfer.green = NULL;
3250
1.09k
            pgs->set_transfer.green_component_num = -1;
3251
1.09k
            rc_decrement(pgs->set_transfer.blue, "cmd_select_map(blue)");
3252
1.09k
            pgs->set_transfer.blue = NULL;
3253
1.09k
            pgs->set_transfer.blue_component_num = -1;
3254
1.09k
            goto transfer2;
3255
2
        case cmd_map_transfer_0:
3256
2
            pmap = &pgs->set_transfer.red;
3257
2
            *pcomp_num = &pgs->set_transfer.red_component_num;
3258
2
            goto transfer1;
3259
2
        case cmd_map_transfer_1:
3260
2
            pmap = &pgs->set_transfer.green;
3261
2
            *pcomp_num = &pgs->set_transfer.green_component_num;
3262
2
            goto transfer1;
3263
2
        case cmd_map_transfer_2:
3264
2
            pmap = &pgs->set_transfer.blue;
3265
2
            *pcomp_num = &pgs->set_transfer.blue_component_num;
3266
2
            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
6
transfer1:  if_debug1m('L', mem, " transfer[%d]", (int)(map_index - cmd_map_transfer_0));
3271
6
            rc_unshare_struct(*pmap, gx_transfer_map, &st_transfer_map, mem,
3272
6
                return_error(gs_error_VMerror), "cmd_select_map(transfer)");
3273
6
            map = *pmap;
3274
3275
1.09k
transfer2:  if (cont != cmd_map_other) {
3276
1.09k
                gx_set_identity_transfer(map);
3277
1.09k
                *pmdata = 0;
3278
1.09k
                *pcount = 0;
3279
1.09k
                return 0;
3280
1.09k
            }
3281
8
            break;
3282
1.38k
        case cmd_map_black_generation:
3283
1.38k
            if_debug0m('L', mem, " black generation");
3284
1.38k
            pmap = &pgs->black_generation;
3285
1.38k
            cname = "cmd_select_map(black generation)";
3286
1.38k
            goto alloc;
3287
1.38k
        case cmd_map_undercolor_removal:
3288
1.38k
            if_debug0m('L', mem, " undercolor removal");
3289
1.38k
            pmap = &pgs->undercolor_removal;
3290
1.38k
            cname = "cmd_select_map(undercolor removal)";
3291
2.76k
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
2.76k
            rc_unshare_struct(*pmap, gx_transfer_map, &st_transfer_map,
3299
2.76k
                              mem, return_error(gs_error_VMerror), cname);
3300
2.76k
            map = *pmap;
3301
2.76k
            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
2.76k
            break;
3308
2.76k
        default:
3309
0
            *pmdata = 0;
3310
0
            return 0;
3311
3.86k
    }
3312
2.77k
    map->proc = gs_mapped_transfer;
3313
2.77k
    *pmdata = map->values;
3314
2.77k
    *pcount = sizeof(map->values);
3315
2.77k
    return 0;
3316
3.86k
}
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
44.0k
{
3401
44.0k
    fixed px = ppos->x - int2fixed(x0);
3402
44.0k
    fixed py = ppos->y - int2fixed(y0);
3403
44.0k
    int code;
3404
3405
62.1k
#define A vs[0]
3406
49.4k
#define B vs[1]
3407
44.0k
#define C vs[2]
3408
44.0k
#define D vs[3]
3409
44.0k
#define E vs[4]
3410
44.0k
#define F vs[5]
3411
3412
44.0k
    switch (op) {
3413
7.01k
        case cmd_opv_rmoveto:
3414
7.01k
            code = gx_path_add_point(ppath, px += A, py += B);
3415
7.01k
            break;
3416
8.49k
        case cmd_opv_rlineto:
3417
8.49k
            code = gx_path_add_line_notes(ppath, px += A, py += B, notes);
3418
8.49k
            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
3.75k
        case cmd_opv_hlineto:
3423
3.75k
            code = gx_path_add_line_notes(ppath, px += A, py, notes);
3424
3.75k
            break;
3425
9.72k
        case cmd_opv_vlineto:
3426
9.72k
            code = gx_path_add_line_notes(ppath, px, py += A, notes);
3427
9.72k
            break;
3428
1.22k
        case cmd_opv_rmlineto:
3429
1.22k
            if ((code = gx_path_add_point(ppath, px += A, py += B)) < 0)
3430
0
                break;
3431
1.22k
            code = gx_path_add_line_notes(ppath, px += C, py += D, notes);
3432
1.22k
            break;
3433
365
        case cmd_opv_rm2lineto:
3434
365
            if ((code = gx_path_add_point(ppath, px += A, py += B)) < 0 ||
3435
365
                (code = gx_path_add_line_notes(ppath, px += C, py += D,
3436
365
                                               notes)) < 0
3437
365
                )
3438
0
                break;
3439
365
            code = gx_path_add_line_notes(ppath, px += E, py += F, notes);
3440
365
            break;
3441
274
        case cmd_opv_rm3lineto:
3442
274
            if ((code = gx_path_add_point(ppath, px += A, py += B)) < 0 ||
3443
274
                (code = gx_path_add_line_notes(ppath, px += C, py += D,
3444
274
                                               notes)) < 0 ||
3445
274
                (code = gx_path_add_line_notes(ppath, px += E, py += F,
3446
274
                                               notes)) < 0
3447
274
                )
3448
0
                break;
3449
274
            code = gx_path_add_line_notes(ppath, px -= C, py -= D, notes);
3450
274
            break;
3451
8.00k
        case cmd_opv_rrcurveto: /* a b c d e f => a b a+c b+d a+c+e b+d+f */
3452
8.02k
rrc:        E += (C += A);
3453
8.02k
            F += (D += B);
3454
10.9k
curve:      code = gx_path_add_curve_notes(ppath, px + A, py + B,
3455
10.9k
                                           px + C, py + D,
3456
10.9k
                                           px + E, py + F, notes);
3457
10.9k
            px += E, py += F;
3458
10.9k
            break;
3459
766
        case cmd_opv_hvcurveto: /* a b c d => a 0 a+b c a+b c+d */
3460
766
hvc:        F = C + D, D = C, E = C = A + B, B = 0;
3461
766
            goto curve;
3462
730
        case cmd_opv_vhcurveto: /* a b c d => 0 a b a+c b+d a+c */
3463
2.12k
vhc:        E = B + D, F = D = A + C, C = B, B = A, A = 0;
3464
2.12k
            goto curve;
3465
31
        case cmd_opv_nrcurveto: /* a b c d => 0 0 a b a+c b+d */
3466
31
            F = B + D, E = A + C, D = B, C = A, B = A = 0;
3467
31
            goto curve;
3468
31
        case cmd_opv_rncurveto: /* a b c d => a b a+c b+d a+c b+d */
3469
31
            F = D += B, E = C += A;
3470
31
            goto curve;
3471
1.39k
        case cmd_opv_vqcurveto: /* a b => VH a b TS(a,b) TS(b,a) */
3472
1.39k
            if ((A ^ B) < 0)
3473
34
                C = -B, D = -A;
3474
1.35k
            else
3475
1.35k
                C = B, D = A;
3476
1.39k
            goto vhc;
3477
0
        case cmd_opv_hqcurveto: /* a b => HV a TS(a,b) b TS(b,a) */
3478
0
            if ((A ^ B) < 0)
3479
0
                D = -A, C = B, B = -B;
3480
0
            else
3481
0
                D = A, C = B;
3482
0
            goto hvc;
3483
22
        case cmd_opv_scurveto: /* (a b c d e f) => */
3484
22
            {
3485
22
                fixed a = A, b = B;
3486
3487
                /* See gxclpath.h for details on the following. */
3488
22
                if (A == 0) {
3489
                    /* Previous curve was vh or vv */
3490
21
                    A = E - C, B = D - F, C = C - a, D = b - D, E = a, F = -b;
3491
21
                } else {
3492
                    /* Previous curve was hv or hh */
3493
1
                    A = C - E, B = F - D, C = a - C, D = D - b, E = -a, F = b;
3494
1
                }
3495
22
            }
3496
22
            goto rrc;
3497
2.22k
        case cmd_opv_closepath:
3498
2.22k
            if ((code = gx_path_close_subpath(ppath)) < 0)
3499
2.22k
                return code;;
3500
2.22k
            if ((code = gx_path_current_point(ppath, (gs_fixed_point *) vs)) < 0)
3501
2.22k
                return code;;
3502
2.22k
            px = A, py = B;
3503
2.22k
            break;
3504
0
        default:
3505
0
            return_error(gs_error_rangecheck);
3506
44.0k
    }
3507
44.0k
#undef A
3508
44.0k
#undef B
3509
44.0k
#undef C
3510
44.0k
#undef D
3511
44.0k
#undef E
3512
44.0k
#undef F
3513
44.0k
    ppos->x = px + int2fixed(x0);
3514
44.0k
    ppos->y = py + int2fixed(y0);
3515
44.0k
    return code;
3516
44.0k
}
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
}