Coverage Report

Created: 2025-06-10 06:59

/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
9.18M
  BEGIN\
91
9.18M
    if ( *p < 0x80 ) var = *p++;\
92
9.18M
    else { const byte *_cbp; var = cmd_get_w(p, &_cbp); p = _cbp; }\
93
9.18M
  END
94
95
static long
96
cmd_get_w(const byte * p, const byte ** rp)
97
4.81M
{
98
4.81M
    int val = *p++ & 0x7f;
99
4.81M
    int shift = 7;
100
101
5.22M
    for (; val |= (int)(*p & 0x7f) << shift, *p++ > 0x7f; shift += 7);
102
4.81M
    *rp = p;
103
4.81M
    return val;
104
4.81M
}
105
106
/* Get a variable-length fractional operand. */
107
#define cmd_getfrac(var, p)\
108
0
  BEGIN\
109
0
    if ( !(*p & 1) ) var = (*p++) << 24;\
110
0
    else { const byte *_cbp; var = cmd_get_frac31(p, &_cbp); p = _cbp; }\
111
0
  END
112
static frac31
113
cmd_get_frac31(const byte * p, const byte ** rp)
114
0
{
115
0
    frac31 val = (*p++ & 0xFE) << 24;
116
0
    int shift = 24 - 7;
117
118
0
    for (; val |= (frac31)(*p & 0xFE) << shift, *p++ & 1; shift -= 7);
119
0
    *rp = p;
120
0
    return val;
121
0
}
122
123
/*
124
 * Define the structure for keeping track of the command reading buffer.
125
 *
126
 * The ptr member is only used for passing the current pointer to, and
127
 * receiving an updated pointer from, commands implemented as separate
128
 * procedures: normally it is kept in a register.
129
 */
130
typedef struct command_buf_s {
131
    byte *data;                 /* actual buffer, guaranteed aligned */
132
    uint size;
133
    const byte *ptr;            /* next byte to be read (see above) */
134
    const byte *warn_limit;     /* refill warning point */
135
    const byte *end;            /* byte just beyond valid data */
136
    stream *s;                  /* for refilling buffer */
137
    int end_status;
138
} command_buf_t;
139
140
/* Set the end of a command buffer. */
141
static void
142
set_cb_end(command_buf_t *pcb, const byte *end)
143
1.50M
{
144
1.50M
    pcb->end = end;
145
1.50M
    pcb->warn_limit = pcb->data + (pcb->size - cmd_largest_size + 1);
146
1.50M
    if ( pcb->warn_limit > pcb->end )
147
125k
        pcb->warn_limit = pcb->end;     /**** This is dangerous. Other places ****/
148
                                        /**** assume that the limit is a soft ****/
149
                                        /**** limit and should check 'end'    ****/
150
1.50M
}
151
152
static inline void
153
advance_buffer(command_buf_t *pcb, const byte *cbp)
154
1.38M
{
155
#ifdef DEBUG
156
    stream_state *st = pcb->s->state;
157
158
    top_up_offset_map(st, pcb->data, cbp, pcb->end);
159
#endif
160
1.38M
    memmove(pcb->data, cbp, pcb->end - cbp);
161
1.38M
}
162
163
static inline void
164
next_is_skip(command_buf_t *pcb)
165
0
{
166
#ifdef DEBUG
167
    stream_state *st = pcb->s->state;
168
169
    offset_map_next_data_out_of_band(st);
170
#endif
171
0
}
172
173
/* Read more data into a command buffer. */
174
static int
175
top_up_cbuf(command_buf_t *pcb, const byte **pcbp)
176
2.32M
{
177
2.32M
    uint nread;
178
2.32M
    const byte *cbp = *pcbp;
179
2.32M
    byte *cb_top = pcb->data + (pcb->end - cbp);
180
181
2.32M
    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
2.32M
    if (seofp(pcb->s)) {
187
        /* Can't use offset_map, because s_close resets s->state. Don't top up. */
188
946k
        pcb->end_status = pcb->s->end_status;
189
946k
        return 0;
190
946k
    }
191
1.38M
    advance_buffer(pcb, cbp);
192
1.38M
    nread = pcb->end - cb_top;
193
1.38M
    pcb->end_status = sgets(pcb->s, cb_top, nread, &nread);
194
1.38M
    if ( nread == 0 ) {
195
        /* No data for this band at all. */
196
6
        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
6
        *cb_top = cmd_opv_end_run;
203
6
        nread = 1;
204
6
    }
205
1.38M
    set_cb_end(pcb, cb_top + nread);
206
1.38M
    process_interrupts(pcb->s->memory);
207
1.38M
    *pcbp = pcb->data;
208
1.38M
    return 0;
209
1.38M
}
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
913k
{
217
913k
    if (pcb->end - cbp >= rsize) {
218
911k
        memmove(ptr, cbp, rsize);
219
911k
        return cbp + rsize;
220
911k
    } else {
221
1.83k
        uint cleft = pcb->end - cbp;
222
1.83k
        uint rleft = rsize - cleft;
223
224
1.83k
        memmove(ptr, cbp, cleft);
225
1.83k
        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
1.83k
        return pcb->end;
234
1.83k
    }
235
913k
}
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
144k
{
241
144k
    memcpy(pvar, cbp, var_size);
242
144k
    return cbp + var_size;
243
144k
}
244
#define cmd_get_value(var, cbp)\
245
144k
  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
6.89M
{
304
6.89M
    if (*ppcomp_last == NULL) {
305
816k
        pcomp->prev = pcomp->next = NULL;
306
816k
        *ppcomp_last = *ppcomp_first = pcomp;
307
6.08M
    } else {
308
6.08M
        (*ppcomp_last)->next = pcomp;
309
6.08M
        pcomp->prev = *ppcomp_last;
310
6.08M
        pcomp->next = NULL;
311
6.08M
        *ppcomp_last = pcomp;
312
6.08M
    }
313
6.89M
}
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
6.89M
{
350
6.89M
    if (*ppcomp_last == *ppcomp_first) {
351
816k
        if (*ppcomp_last == pcomp) {
352
816k
            *ppcomp_last = *ppcomp_first = NULL;
353
816k
            return 0;
354
816k
        } else
355
0
            return_error(gs_error_unregistered); /* Must not happen. */
356
6.08M
    } else {
357
6.08M
        gs_composite_t *pcomp_next = pcomp->next, *pcomp_prev = pcomp->prev;
358
359
6.08M
        if (*ppcomp_last == pcomp)
360
559k
            *ppcomp_last = pcomp->prev;
361
5.52M
        else
362
5.52M
            pcomp_next->prev = pcomp_prev;
363
6.08M
        if (*ppcomp_first == pcomp)
364
5.52M
            *ppcomp_first = pcomp->next;
365
559k
        else
366
559k
            pcomp_prev->next = pcomp_next;
367
6.08M
        pcomp->next = pcomp->prev = NULL;
368
6.08M
        return 0;
369
6.08M
    }
370
6.89M
}
371
372
static inline void
373
free_compositor(gs_composite_t *pcomp, gs_memory_t *mem)
374
919k
{
375
919k
    gs_free_object(mem, pcomp, "free_compositor");
376
919k
}
377
378
static inline bool
379
is_null_compositor_op(const byte *cbp, int *length)
380
4.58M
{
381
4.58M
    if (cbp[0] == cmd_opv_end_run) {
382
4.04M
        *length = 1;
383
4.04M
        return true;
384
4.04M
    }
385
537k
    return false;
386
4.58M
}
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
581k
{
393
6.55M
    while (pcomp_from != NULL) {
394
5.97M
        gs_composite_t *pcomp = pcomp_from;
395
5.97M
        int code;
396
397
5.97M
        pcomp_from = pcomp->next;
398
5.97M
        code = dequeue_compositor(ppcomp_first, ppcomp_last, pcomp);
399
5.97M
        if (code < 0)
400
0
            return code;
401
5.97M
        pcomp->idle |= idle;
402
5.97M
        code = apply_composite(cdev, pgs, mem, pcomp, x0, y0, target); /* Releases the compositor. */
403
5.97M
        if (code < 0)
404
2
            return code;
405
5.97M
        *tdev = *target;
406
5.97M
    }
407
581k
    return 0;
408
581k
}
409
410
static void
411
mark_as_idle(gs_composite_t *pcomp_start, gs_composite_t *pcomp_end)
412
95.2k
{
413
95.2k
    gs_composite_t *pcomp = pcomp_start;
414
415
207k
    while (pcomp != NULL) {
416
207k
        pcomp->idle = true;
417
207k
        if (pcomp == pcomp_end)
418
95.2k
            break;
419
111k
        pcomp = pcomp->next;
420
111k
    }
421
95.2k
}
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
56
{
428
56
    gs_composite_t *pcomp;
429
430
280
    do {
431
280
        int code;
432
433
280
        pcomp = *ppcomp_last;
434
280
        if (pcomp == NULL)
435
0
            return 0;
436
280
        dequeue_compositor(ppcomp_first, ppcomp_last, *ppcomp_last);
437
280
        code = pcomp->type->procs.adjust_ctm(pcomp, x0, y0, pgs);
438
280
        if (code < 0)
439
0
            return code;
440
280
        free_compositor(pcomp, mem);
441
280
    } while (pcomp != pcomp_from);
442
56
    return 0;
443
56
}
444
445
static int
446
read_set_misc_map(byte cb, command_buf_t *pcb, gs_gstate *pgs, gs_memory_t *mem)
447
374k
{
448
374k
    const byte *cbp = pcb->ptr;
449
374k
    frac *mdata;
450
374k
    int *pcomp_num;
451
374k
    uint count = 0;   /* quiet compiler */
452
374k
    cmd_map_contents cont =
453
374k
        (cmd_map_contents)(cb & 0x30) >> 4;
454
374k
    int code;
455
456
374k
    code = cmd_select_map(cb & 0xf, cont,
457
374k
                          pgs,
458
374k
                          &pcomp_num,
459
374k
                          &mdata, &count, mem);
460
461
374k
    if (code < 0)
462
0
        return code;
463
    /* Get component number if relevant */
464
374k
    if (pcomp_num == NULL)
465
374k
        cbp++;
466
0
    else {
467
0
        *pcomp_num = (int) *cbp++;
468
0
        if_debug1m('L', mem, " comp_num=%d", *pcomp_num);
469
0
    }
470
374k
    if (cont == cmd_map_other) {
471
249k
        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
249k
    }
485
    /* Recompute the effective transfer, */
486
    /* in case this was a transfer map. */
487
374k
    gx_gstate_set_effective_xfer(pgs);
488
374k
    pcb->ptr = cbp;
489
374k
    return 0;
490
374k
}
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
126k
{
516
126k
    byte *cbuf_storage;
517
126k
    command_buf_t cbuf;
518
    /* data_bits is for short copy_* bits and copy_* compressed, */
519
    /* must be aligned */
520
126k
    byte *data_bits = 0;
521
126k
    const byte *cbp;
522
126k
    int dev_depth;              /* May vary due to compositing devices */
523
126k
    int dev_depth_bytes;
524
126k
    int odd_delta_shift;
525
126k
    int num_zero_bytes;
526
126k
    gx_device *tdev;
527
126k
    gx_clist_state state;
528
126k
    gx_color_index *set_colors;
529
126k
    gx_device_color *set_dev_colors;
530
126k
    tile_slot *state_slot;
531
126k
    gx_strip_bitmap state_tile; /* parameters for reading tiles */
532
126k
    tile_slot tile_bits;        /* parameters of current tile */
533
126k
    gs_int_point tile_phase;
534
126k
    gx_path path;
535
126k
    bool in_path;
536
126k
    gs_fixed_point ppos;
537
126k
    gx_clip_path clip_path;
538
126k
    bool use_clip;
539
126k
    gx_clip_path *pcpath;
540
126k
    gx_device_cpath_accum clip_accum;
541
126k
    gs_fixed_rect target_box;
542
126k
    struct _cas {
543
126k
        bool lop_enabled;
544
126k
        gx_device_color dcolor;
545
126k
        gs_fixed_point fa_save;
546
126k
    } clip_save;
547
126k
    bool in_clip = false;
548
126k
    gs_gstate gs_gstate;
549
126k
    gx_device_color fill_color = { 0 };
550
126k
    gx_device_color stroke_color = { 0 };
551
126k
    float dash_pattern[cmd_max_dash];
552
126k
    gx_fill_params fill_params;
553
126k
    gx_stroke_params stroke_params;
554
#ifdef DEBUG
555
    gs_halftone_type halftone_type;
556
#endif
557
126k
    union im_ {
558
126k
        gs_image_common_t c;
559
126k
        gs_data_image_t d;
560
126k
        gs_image1_t i1;
561
126k
        gs_image4_t i4;
562
126k
    } image;
563
126k
    gs_int_rect image_rect;
564
126k
    gs_color_space *pcs = NULL;
565
126k
    gx_image_enum_common_t *image_info;
566
126k
    gx_image_plane_t planes[32];
567
126k
    uint data_height;
568
126k
    uint data_size;
569
126k
    byte *data_on_heap;
570
126k
    fixed vs[6];
571
126k
    segment_notes notes;
572
126k
    int data_x;
573
126k
    int code = 0;
574
126k
    ht_buff_t  ht_buff;
575
126k
    gx_device *const orig_target = target;
576
126k
    gx_device_clip clipper_dev;
577
126k
    bool clipper_dev_open = false;
578
126k
    patch_fill_state_t pfs;
579
126k
    int op = 0;
580
126k
    int plane_height = 0;
581
582
#ifdef DEBUG
583
    stream_state *st = s->state; /* Save because s_close resets s->state. */
584
#endif
585
126k
    gs_composite_t *pcomp_first = NULL, *pcomp_last = NULL;
586
126k
    tile_slot bits;             /* parameters for reading bits */
587
588
    /* pad the cbuf data area a bit (just in case) */
589
126k
    if ((cbuf_storage = gs_alloc_bytes(mem, cbuf_size + sizeof(double),
590
126k
                               "clist_playback_band(cbuf_storage)")) == NULL) {
591
0
        return_error(gs_error_VMerror);
592
0
    }
593
126k
    cbuf.data = (byte *)cbuf_storage;
594
126k
    cbuf.size = cbuf_size;
595
126k
    cbuf.s = s;
596
126k
    cbuf.end_status = 0;
597
126k
    set_cb_end(&cbuf, cbuf.data + cbuf.size);
598
126k
    cbp = cbuf.end;
599
600
126k
    pfs.dev = NULL; /* Indicate "not initialized". */
601
126k
    memset(&ht_buff, 0, sizeof(ht_buff));
602
603
    /* The following initializations are to quiet gcc warnings. */
604
126k
    memset(&bits, 0, sizeof(bits));
605
126k
    memset(&tile_bits, 0, sizeof(tile_bits));
606
126k
    memset(&clip_save, 0, sizeof(clip_save));
607
126k
    memset(&state_slot, 0, sizeof(state_slot));
608
126k
    ppos.x = ppos.y = 0;
609
610
126k
in:                             /* Initialize for a new page. */
611
126k
    tdev = target;
612
126k
    set_colors = state.colors;
613
126k
    set_dev_colors = state.tile_color_devn;
614
126k
    use_clip = false;
615
126k
    pcpath = NULL;
616
126k
    if (clipper_dev_open)
617
0
        gx_destroy_clip_device_on_stack(&clipper_dev);
618
126k
    clipper_dev_open = false;
619
126k
    notes = sn_none;
620
126k
    data_x = 0;
621
126k
    {
622
126k
        static const gx_clist_state cls_initial = { cls_initial_values };
623
624
126k
        state = cls_initial;
625
126k
    }
626
126k
    state_tile.id = gx_no_bitmap_id;
627
126k
    state_tile.shift = state_tile.rep_shift = 0;
628
126k
    state_tile.size.x = state_tile.size.y = 0;
629
126k
    state_tile.num_planes = 1;
630
126k
    tile_phase.x = x0;
631
126k
    tile_phase.y = y0;
632
126k
    gx_path_init_local(&path, mem);
633
126k
    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
126k
    {
639
126k
        gs_fixed_rect cbox;
640
641
126k
        gx_cpath_init_local(&clip_path, mem);
642
126k
        cbox.p.x = 0;
643
126k
        cbox.p.y = 0;
644
126k
        cbox.q.x = cdev->width;
645
126k
        cbox.q.y = cdev->height;
646
126k
        gx_cpath_from_rectangle(&clip_path, &cbox);
647
126k
    }
648
126k
    if (target != 0)
649
126k
        (*dev_proc(target, get_clipping_box))(target, &target_box);
650
126k
    memset(&gs_gstate, 0, sizeof(gs_gstate));
651
126k
    GS_STATE_INIT_VALUES_CLIST((&gs_gstate));
652
126k
    code = gs_gstate_initialize(&gs_gstate, mem);
653
126k
    if (code < 0)
654
0
        goto out;
655
126k
    gs_gstate.device = tdev;
656
126k
    gs_gstate.view_clip = NULL; /* Avoid issues in pdf14 fill stroke */
657
126k
    gs_gstate.clip_path = &clip_path;
658
126k
    pcs = gs_cspace_new_DeviceGray(mem);
659
126k
    if (pcs == NULL) {
660
0
        code = gs_note_error(gs_error_VMerror);
661
0
        goto out;
662
0
    }
663
126k
    code = pcs->type->install_cspace(pcs, &gs_gstate);
664
126k
    if (code < 0) {
665
0
        rc_decrement(pcs, "clist_playback_band");
666
0
        goto out;
667
0
    }
668
126k
    gs_gstate.color[0].color_space = pcs; /* we already have one ref */
669
126k
    gs_gstate.color[1].color_space = pcs;
670
126k
    rc_increment_cs(pcs); /* increment for second ref */
671
    /* Initialize client color and device color */
672
126k
    gs_gstate.color[0].ccolor =
673
126k
        gs_alloc_struct(mem, gs_client_color, &st_client_color, "clist_playback_band");
674
126k
    gs_gstate.color[1].ccolor =
675
126k
        gs_alloc_struct(mem, gs_client_color, &st_client_color, "clist_playback_band");
676
126k
    gs_gstate.color[0].dev_color =
677
126k
        gs_alloc_struct(mem, gx_device_color, &st_device_color, "clist_playback_band");
678
126k
    gs_gstate.color[1].dev_color =
679
126k
        gs_alloc_struct(mem, gx_device_color, &st_device_color, "clist_playback_band");
680
126k
    if (gs_gstate.color[0].ccolor == 0 || gs_gstate.color[0].dev_color == 0 ||
681
126k
        gs_gstate.color[1].ccolor == 0 || gs_gstate.color[1].dev_color == 0
682
126k
        ) {
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
126k
    gs_gstate.color[0].color_space->pclient_color_space_data =
692
126k
        pcs->pclient_color_space_data;
693
126k
    cs_full_init_color(gs_gstate.color[0].ccolor, pcs);
694
126k
    gx_unset_dev_color(&gs_gstate);
695
696
126k
    gs_gstate.color[1].color_space->pclient_color_space_data =
697
126k
        pcs->pclient_color_space_data;
698
126k
    cs_full_init_color(gs_gstate.color[1].ccolor, pcs);
699
126k
    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
126k
    rc_decrement(gs_gstate.icc_link_cache,"clist_playback_band");
704
126k
    gs_gstate.icc_link_cache = cdev->icc_cache_cl;
705
    /* Need to lock during the increment of the link cache */
706
126k
    gx_monitor_enter(cdev->icc_cache_cl->lock);
707
126k
    rc_increment(cdev->icc_cache_cl);
708
126k
    gx_monitor_leave(cdev->icc_cache_cl->lock); /* let everyone run */
709
126k
    if (code < 0)
710
0
        goto out;
711
712
126k
    gs_gstate.line_params.dash.pattern = dash_pattern;
713
126k
    if (tdev != 0) {
714
126k
        gx_set_cmap_procs(&gs_gstate, tdev);
715
126k
    }
716
126k
    gx_gstate_setscreenphase(&gs_gstate, -x0, -y0, gs_color_select_all);
717
#ifdef DEBUG
718
    halftone_type = ht_type_none;
719
#endif
720
126k
    fill_color.ccolor_valid = false;
721
126k
    color_unset(&fill_color);
722
126k
    data_bits = gs_alloc_bytes(mem, data_bits_size,
723
126k
                               "clist_playback_band(data_bits)");
724
126k
    if (data_bits == 0) {
725
0
        code = gs_note_error(gs_error_VMerror);
726
0
        goto out;
727
0
    }
728
23.4M
    while (code >= 0) {
729
23.4M
        int compress;
730
23.4M
        int depth = 0x7badf00d; /* Initialize against indeterminizm. */
731
23.4M
        int raster = 0x7badf00d; /* Initialize against indeterminizm. */
732
23.4M
        byte *source = NULL;  /* Initialize against indeterminizm. */
733
23.4M
        gx_color_index colors[2];
734
23.4M
        gx_color_index *pcolor;
735
23.4M
        gx_device_color *pdcolor = NULL;
736
23.4M
        gs_logical_operation_t log_op;
737
738
        /* Make sure the buffer contains a full command. */
739
23.4M
        if (cbp >= cbuf.warn_limit) {
740
141k
            if (cbuf.end_status < 0) {  /* End of file or error. */
741
1.25k
                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
139k
            } else {
747
139k
                code = top_up_cbuf(&cbuf, &cbp);
748
139k
                if (code < 0)
749
0
                    goto top_up_failed;
750
139k
            }
751
141k
        }
752
23.4M
        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
23.4M
        switch (op >> 4) {
762
6.75M
            case cmd_op_misc >> 4:
763
6.75M
                switch (op) {
764
404k
                    case cmd_opv_end_run:
765
404k
                        if_debug0m('L', mem, "\n");
766
404k
                        continue;
767
3
                    case cmd_opv_set_tile_size:
768
3
                        cbuf.ptr = cbp;
769
3
                        code = read_set_tile_size(&cbuf, &tile_bits,
770
3
                                    gx_device_is_pattern_clist((gx_device *)cdev));
771
3
                        cbp = cbuf.ptr;
772
3
                        if (code < 0)
773
0
                            goto out;
774
3
                        continue;
775
27
                    case cmd_opv_set_tile_phase:
776
27
                        cmd_getw(state.tile_phase.x, cbp);
777
27
                        cmd_getw(state.tile_phase.y, cbp);
778
27
                        if_debug2m('L', mem, " (%d,%d)\n",
779
27
                                   state.tile_phase.x,
780
27
                                   state.tile_phase.y);
781
27
                        goto set_tile_phase;
782
2.52k
                    case cmd_opv_set_screen_phaseT:
783
2.52k
                        cmd_getw(state.screen_phase[gs_color_select_texture].x, cbp);
784
2.52k
                        cmd_getw(state.screen_phase[gs_color_select_texture].y, cbp);
785
2.52k
                        if_debug2m('L', mem, " (%d,%d)\n",
786
2.52k
                                   state.screen_phase[0].x,
787
2.52k
                                   state.screen_phase[gs_color_select_texture].y);
788
2.52k
                        gx_gstate_setscreenphase(&gs_gstate,
789
2.52k
                                                 state.screen_phase[gs_color_select_texture].x - x0,
790
2.52k
                                                 state.screen_phase[gs_color_select_texture].y - y0,
791
2.52k
                                                 gs_color_select_texture);
792
2.52k
                        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
3
                    case cmd_opv_set_tile_bits:
805
3
                        bits = tile_bits;
806
3
                        compress = 0;
807
659k
                      stb:
808
659k
                        cbuf.ptr = cbp;
809
659k
                        code = read_set_bits(&cbuf, &bits, compress,
810
659k
                                             &state, &state_tile, &state_slot,
811
659k
                                             cdev, mem);
812
659k
                        cbp = cbuf.ptr;
813
659k
                        if (code < 0)
814
0
                            goto out;
815
659k
                        goto stp;
816
659k
                    case cmd_opv_set_bits:
817
659k
do_opv_set_bits:
818
659k
                        compress = *cbp & 3;
819
659k
                        bits.head.depth = *cbp++ >> 2;
820
659k
                        cmd_getw(bits.width, cbp);
821
659k
                        cmd_getw(bits.height, cbp);
822
659k
                        if (op == cmd_opv_set_bits_planar)
823
659k
                            cmd_getw(bits.num_planes, cbp);
824
659k
                        else
825
659k
                            bits.num_planes = 1;
826
659k
                        if_debug5m('L', mem, " compress=%d depth=%d size=(%d,%d) planes=%d",
827
659k
                                   compress, bits.head.depth,
828
659k
                                   bits.width, bits.height, bits.num_planes);
829
659k
                        bits.raster =
830
659k
                            bitmap_raster(bits.width * bits.head.depth);
831
659k
                        bits.x_reps = bits.y_reps = 1;
832
659k
                        bits.shift = bits.rep_shift = 0;
833
659k
                        goto stb;
834
3
                    case cmd_opv_set_tile_color:
835
3
                        set_colors = state.tile_colors;
836
3
                        if_debug0m('L', mem, "\n");
837
3
                        continue;
838
385k
                    case cmd_opv_set_misc:
839
385k
                        {
840
385k
                            uint cb = *cbp++;
841
842
385k
                            switch (cb >> 6) {
843
30.7k
                                case cmd_set_misc_lop >> 6:
844
30.7k
                                    cmd_getw(state.lop, cbp);
845
30.7k
                                    state.lop = (state.lop << 6) + (cb & 0x3f);
846
30.7k
                                    if_debug1m('L', mem, " lop=0x%x\n", state.lop);
847
30.7k
                                    if (state.lop_enabled)
848
11.0k
                                        gs_gstate.log_op = state.lop;
849
30.7k
                                    break;
850
1.98k
                                case cmd_set_misc_data_x >> 6:
851
1.98k
                                    if (cb & 0x20)
852
1.98k
                                        cmd_getw(data_x, cbp);
853
1.98k
                                    else
854
1.98k
                                        data_x = 0;
855
1.98k
                                    data_x = (data_x << 5) + (cb & 0x1f);
856
1.98k
                                    if_debug1m('L', mem, " data_x=%d\n", data_x);
857
1.98k
                                    break;
858
352k
                                case cmd_set_misc_map >> 6:
859
352k
                                    cbuf.ptr = cbp;
860
352k
                                    code = read_set_misc_map(cb, &cbuf, &gs_gstate, mem);
861
352k
                                    if (code < 0)
862
0
                                        goto out;
863
352k
                                    cbp = cbuf.ptr;
864
352k
                                    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
385k
                            }
885
385k
                        }
886
385k
                        continue;
887
385k
                    case cmd_opv_enable_lop:
888
19.7k
                        state.lop_enabled = true;
889
19.7k
                        gs_gstate.log_op = state.lop;
890
19.7k
                        if_debug0m('L', mem, "\n");
891
19.7k
                        continue;
892
14.7k
                    case cmd_opv_disable_lop:
893
14.7k
                        state.lop_enabled = false;
894
14.7k
                        gs_gstate.log_op = lop_default;
895
14.7k
                        if_debug0m('L', mem, "\n");
896
14.7k
                        continue;
897
126k
                    case cmd_opv_end_page:
898
126k
                        if_debug0m('L', mem, "\n");
899
                        /*
900
                         * Do end-of-page cleanup, then reinitialize if
901
                         * there are more pages to come.
902
                         */
903
126k
                        goto out;
904
0
                    case cmd_opv_delta_color0:
905
0
                        pcolor = &set_colors[0];
906
0
                        goto delta2_c;
907
5.14M
                    case cmd_opv_delta_color1:
908
5.14M
                        pcolor = &set_colors[1];
909
5.14M
                      delta2_c:set_colors = state.colors;
910
                        /* See comments for cmd_put_color() in gxclutil.c. */
911
5.14M
                        {
912
5.14M
                            gx_color_index delta = 0;
913
5.14M
                            uint data;
914
915
5.14M
                            dev_depth = (tdev->color_info.depth <= 8*sizeof(gx_color_index) ?
916
5.14M
                                         tdev->color_info.depth : 8*sizeof(gx_color_index));
917
5.14M
                            dev_depth_bytes = (dev_depth + 7) >> 3;
918
5.14M
                            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
4.16M
                                case 4:
931
4.16M
                                    data = *cbp++;
932
4.16M
                                    delta |= ((gx_color_index)
933
4.16M
                                        ((data & 0xf0) << 4) + (data & 0x0f)) << 16;
934
                                    /* fall through */
935
4.16M
                                case 2:
936
4.16M
                                    data = *cbp++;
937
4.16M
                                    delta |= ((gx_color_index)
938
4.16M
                                        ((data & 0xf0) << 4) + (data & 0x0f));
939
4.16M
                                    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
980k
                                case 3:
952
980k
                                    data = *cbp++;
953
980k
                                    odd_delta_shift = (dev_depth_bytes - 3) * 8;
954
980k
                                    delta |= ((gx_color_index)
955
980k
                                        ((data & 0xe0) << 3) + (data & 0x1f)) << odd_delta_shift;
956
980k
                                    data = *cbp++;
957
980k
                                    delta |= ((gx_color_index) ((data & 0xf8) << 2) + (data & 0x07))
958
980k
                                                        << (odd_delta_shift + 11);
959
5.14M
                            }
960
5.14M
                            *pcolor += delta - cmd_delta_offsets[dev_depth_bytes];
961
5.14M
                        }
962
5.14M
                        if (sizeof(*pcolor) <= sizeof(ulong))
963
5.14M
                            if_debug1m('L', mem, " 0x%lx\n", (ulong)*pcolor);
964
0
                        else
965
5.14M
                            if_debug2m('L', mem, " 0x%8lx%08lx\n",
966
5.14M
                                       (ulong)(*pcolor >> 8*(sizeof(*pcolor) - sizeof(ulong))), (ulong)*pcolor);
967
5.14M
                        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
6.75M
                }
979
                /*NOTREACHED */
980
119
            case cmd_op_set_color0 >> 4:
981
119
                pcolor = &set_colors[0];
982
119
                goto set_color;
983
1.98M
            case cmd_op_set_color1 >> 4:
984
1.98M
                pcolor = &set_colors[1];
985
1.98M
              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
1.98M
                num_zero_bytes = op & 0x0f;
994
995
1.98M
                if (num_zero_bytes == cmd_no_color_index)
996
0
                    *pcolor = gx_no_color_index;
997
1.98M
                else {
998
1.98M
                    gx_color_index color = 0;
999
1000
1.98M
                    dev_depth = (tdev->color_info.depth < 8*sizeof(gx_color_index) ?
1001
1.98M
                                 tdev->color_info.depth : 8*sizeof(gx_color_index));
1002
1.98M
                    dev_depth_bytes = (dev_depth + 7) >> 3;
1003
1.98M
                    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
327k
                        case 4:
1013
327k
                            color = (color << 8) | (gx_color_index) * cbp++;
1014
618k
                        case 3:
1015
618k
                            color = (color << 8) | (gx_color_index) * cbp++;
1016
792k
                        case 2:
1017
792k
                            color = (color << 8) | (gx_color_index) * cbp++;
1018
1.84M
                        case 1:
1019
1.84M
                            color = (color << 8) | (gx_color_index) * cbp++;
1020
1.98M
                        default:
1021
1.98M
                            break;
1022
1.98M
                    }
1023
1.98M
                    color <<= num_zero_bytes * 8;
1024
1.98M
                    *pcolor = color;
1025
1.98M
                }
1026
1.98M
                if (sizeof(*pcolor) <= sizeof(ulong))
1027
1.98M
                    if_debug1m('L', mem, " 0x%lx\n", (ulong)*pcolor);
1028
0
                else
1029
1.98M
                    if_debug2m('L', mem, " 0x%8lx%08lx\n",
1030
1.98M
                               (ulong)(*pcolor >> 8*(sizeof(*pcolor) - sizeof(ulong))), (ulong)*pcolor);
1031
1.98M
                continue;
1032
312k
            case cmd_op_fill_rect >> 4:
1033
312k
            case cmd_op_tile_rect >> 4:
1034
312k
                cbp = cmd_read_rect(op, &state.rect, cbp);
1035
312k
                break;
1036
556k
            case cmd_op_fill_rect_short >> 4:
1037
557k
            case cmd_op_tile_rect_short >> 4:
1038
557k
                state.rect.x += *cbp + cmd_min_short;
1039
557k
                state.rect.width += cbp[1] + cmd_min_short;
1040
557k
                if (op & 0xf) {
1041
196k
                    state.rect.height += (op & 0xf) + cmd_min_dxy_tiny;
1042
196k
                    cbp += 2;
1043
360k
                } else {
1044
360k
                    state.rect.y += cbp[2] + cmd_min_short;
1045
360k
                    state.rect.height += cbp[3] + cmd_min_short;
1046
360k
                    cbp += 4;
1047
360k
                }
1048
557k
                break;
1049
8.02M
            case cmd_op_fill_rect_tiny >> 4:
1050
8.02M
            case cmd_op_tile_rect_tiny >> 4:
1051
8.02M
                if (op & 8)
1052
5.80M
                    state.rect.x += state.rect.width;
1053
2.21M
                else {
1054
2.21M
                    int txy = *cbp++;
1055
1056
2.21M
                    state.rect.x += (txy >> 4) + cmd_min_dxy_tiny;
1057
2.21M
                    state.rect.y += (txy & 0xf) + cmd_min_dxy_tiny;
1058
2.21M
                }
1059
8.02M
                state.rect.width += (op & 7) + cmd_min_dw_tiny;
1060
8.02M
                break;
1061
1.43M
            case cmd_op_copy_mono_planes >> 4:
1062
1.43M
                cmd_getw(plane_height, cbp);
1063
1.43M
                if (plane_height == 0) {
1064
                    /* We are doing a copy mono */
1065
1.43M
                    depth = 1;
1066
1.43M
                } else {
1067
0
                    depth = tdev->color_info.depth;
1068
0
                }
1069
1.43M
                if_debug1m('L', mem, " plane_height=0x%x", plane_height);
1070
1.43M
                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
1.43M
              copy:cmd_getw(state.rect.x, cbp);
1079
1.43M
                cmd_getw(state.rect.y, cbp);
1080
1.43M
                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
1.43M
                    depth = state_slot->head.depth;
1091
1.43M
                    state.rect.width = state_slot->width;
1092
1.43M
                    state.rect.height = state_slot->height;
1093
1.43M
                    if (state.rect.y + state.rect.height > cdev->height)
1094
1.90k
                        state.rect.height = cdev->height - state.rect.y; /* clamp as writer did */
1095
1.43M
                    raster = state_slot->raster;
1096
1.43M
                    source = (byte *) (state_slot + 1);
1097
1.43M
                } else {        /* Read width, height, bits. */
1098
                    /* depth was set already. */
1099
3.56k
                    uint width_bits, width_bytes;
1100
3.56k
                    uint bytes;
1101
3.56k
                    uchar planes = 1;
1102
3.56k
                    uint plane_depth = depth;
1103
3.56k
                    uint pln;
1104
3.56k
                    byte compression = op & 3;
1105
3.56k
                    uint out_bytes;
1106
1107
3.56k
                    cmd_getw(state.rect.width, cbp);
1108
3.56k
                    cmd_getw(state.rect.height, cbp);
1109
3.56k
                    if (plane_height != 0) {
1110
0
                        planes = tdev->color_info.num_components;
1111
0
                        plane_depth /= planes;
1112
0
                    }
1113
3.56k
                    width_bits = state.rect.width * plane_depth;
1114
3.56k
                    bytes = clist_bitmap_bytes(width_bits,
1115
3.56k
                                               state.rect.height,
1116
3.56k
                                               op & 3, &width_bytes,
1117
3.56k
                                               (uint *)&raster);
1118
3.56k
                    if (planes > 1) {
1119
0
                        out_bytes = raster * state.rect.height;
1120
0
                        plane_height = state.rect.height;
1121
3.56k
                    } else {
1122
3.56k
                        out_bytes = bytes;
1123
3.56k
                    }
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
7.12k
                    for (pln = 0; pln < planes; pln++) {
1139
3.56k
                        byte *plane_bits = data_bits + pln * plane_height * raster;
1140
1141
                        /* Fill the cbuf if needed to get the data for the plane */
1142
3.56k
                        if (cbp + out_bytes >= cbuf.warn_limit) {
1143
5
                            code = top_up_cbuf(&cbuf, &cbp);
1144
5
                            if (code < 0)
1145
0
                                goto top_up_failed;
1146
5
                        }
1147
3.56k
                        if (pln)
1148
0
                            compression = *cbp++;
1149
1150
3.56k
                        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
3.56k
                        } 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
3.56k
                        } else if ((state.rect.height > 1 && width_bytes != raster) ||
1210
3.56k
                                   (plane_height != 0)) {
1211
797
                            cbp = cmd_read_short_bits(&cbuf, plane_bits, bytes, width_bytes,
1212
797
                                                      state.rect.height, raster, cbp);
1213
797
                            if (pln == 0)
1214
797
                                source = data_bits;
1215
2.76k
                        } else {
1216
                            /* Never used for planar data */
1217
2.76k
                            cbp = cmd_read_data(&cbuf, cbuf.data, bytes, cbp);
1218
2.76k
                            source = cbuf.data;
1219
2.76k
                        }
1220
3.56k
                    }
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
3.56k
                }
1230
1.43M
                break;
1231
1.43M
            case cmd_op_delta_tile_index >> 4:
1232
267k
                state.tile_index += (int)(op & 0xf) - 8;
1233
267k
                goto sti;
1234
459k
            case cmd_op_set_tile_index >> 4:
1235
459k
                state.tile_index =
1236
459k
                    ((op & 0xf) << 8) + *cbp++;
1237
726k
              sti:state_slot =
1238
726k
                    (tile_slot *) (cdev->cache_chunk->data +
1239
726k
                                 cdev->tile_table[state.tile_index].offset);
1240
726k
                if_debug2m('L', mem, " index=%u offset=%lu\n",
1241
726k
                           state.tile_index,
1242
726k
                           cdev->tile_table[state.tile_index].offset);
1243
726k
                state_tile.data = (byte *) (state_slot + 1);
1244
1.38M
              stp:state_tile.size.x = state_slot->width;
1245
1.38M
                state_tile.size.y = state_slot->height;
1246
1.38M
                state_tile.raster = state_slot->raster;
1247
1.38M
                state_tile.rep_width = state_tile.size.x /
1248
1.38M
                    state_slot->x_reps;
1249
1.38M
                state_tile.rep_height = state_tile.size.y /
1250
1.38M
                    state_slot->y_reps;
1251
1.38M
                state_tile.rep_shift = state_slot->rep_shift;
1252
1.38M
                state_tile.shift = state_slot->shift;
1253
1.38M
                state_tile.id = state_slot->id;
1254
1.38M
                state_tile.num_planes = state_slot->num_planes;
1255
1.38M
set_tile_phase:
1256
1.38M
                if (state_tile.size.x)
1257
1.38M
                    tile_phase.x =
1258
1.38M
                        (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
1.38M
                if (state_tile.size.y) {
1264
1.38M
                    int full_height;
1265
1266
1.38M
                    if (state_tile.shift == 0)
1267
1.38M
                        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
1.38M
                    tile_phase.y = (state.tile_phase.y + y0) % full_height;
1274
1.38M
                }
1275
1.38M
                continue;
1276
1.94M
            case cmd_op_misc2 >> 4:
1277
1.94M
                switch (op) {
1278
0
                    case cmd_opv_set_bits_planar:
1279
0
                        goto do_opv_set_bits;
1280
1.11k
                    case cmd_opv_set_fill_adjust:
1281
1.11k
                        cmd_get_value(gs_gstate.fill_adjust.x, cbp);
1282
1.11k
                        cmd_get_value(gs_gstate.fill_adjust.y, cbp);
1283
1.11k
                        if_debug2m('L', mem, " (%g,%g)\n",
1284
1.11k
                                   fixed2float(gs_gstate.fill_adjust.x),
1285
1.11k
                                   fixed2float(gs_gstate.fill_adjust.y));
1286
1.11k
                        continue;
1287
156k
                    case cmd_opv_set_ctm:
1288
156k
                        {
1289
156k
                            gs_matrix mat;
1290
1291
156k
                            cbp = cmd_read_matrix(&mat, cbp);
1292
156k
                            if_debug6m('L', mem, " [%g %g %g %g %g %g]\n",
1293
156k
                                       mat.xx, mat.xy, mat.yx, mat.yy,
1294
156k
                                       mat.tx, mat.ty);
1295
156k
                            mat.tx -= x0;
1296
156k
                            mat.ty -= y0;
1297
156k
                            gs_gstate_setmatrix(&gs_gstate, &mat);
1298
156k
                        }
1299
156k
                        continue;
1300
98.5k
                    case cmd_opv_set_misc2:
1301
98.5k
                        cbuf.ptr = cbp;
1302
98.5k
                        code = read_set_misc2(&cbuf, &gs_gstate, &notes);
1303
98.5k
                        cbp = cbuf.ptr;
1304
98.5k
                        if (code < 0)
1305
0
                            goto out;
1306
98.5k
                        continue;
1307
98.5k
                    case cmd_opv_set_dash:
1308
12.7k
                        {
1309
12.7k
                            int nb = *cbp++;
1310
12.7k
                            int n = nb & 0x3f;
1311
12.7k
                            float dot_length, offset;
1312
1313
12.7k
                            cmd_get_value(dot_length, cbp);
1314
12.7k
                            cmd_get_value(offset, cbp);
1315
12.7k
                            memcpy(dash_pattern, cbp, n * sizeof(float));
1316
1317
12.7k
                            gx_set_dash(&gs_gstate.line_params.dash,
1318
12.7k
                                        dash_pattern, n, offset,
1319
12.7k
                                        NULL);
1320
12.7k
                            gx_set_dash_adapt(&gs_gstate.line_params.dash,
1321
12.7k
                                              (nb & 0x80) != 0);
1322
12.7k
                            gx_set_dot_length(&gs_gstate.line_params,
1323
12.7k
                                              dot_length,
1324
12.7k
                                              (nb & 0x40) != 0);
1325
#ifdef DEBUG
1326
                            if (gs_debug_c('L')) {
1327
                                int i;
1328
1329
                                dmprintf4(mem, " dot=%g(mode %d) adapt=%d offset=%g [",
1330
                                         dot_length,
1331
                                         (nb & 0x40) != 0,
1332
                                         (nb & 0x80) != 0, offset);
1333
                                for (i = 0; i < n; ++i)
1334
                                    dmprintf1(mem, "%g ", dash_pattern[i]);
1335
                                dmputs(mem, "]\n");
1336
                            }
1337
#endif
1338
12.7k
                            cbp += n * sizeof(float);
1339
12.7k
                        }
1340
12.7k
                        break;
1341
34
                    case cmd_opv_enable_clip:
1342
34
                        pcpath = (use_clip ? &clip_path : NULL);
1343
34
                        if (pcpath) {
1344
32
                            code = gx_cpath_ensure_path_list(pcpath);
1345
32
                            if (code < 0)
1346
0
                                goto out;
1347
32
                        }
1348
34
                        if (clipper_dev_open)
1349
0
                            gx_destroy_clip_device_on_stack(&clipper_dev);
1350
34
                        clipper_dev_open = false;
1351
34
                        if_debug0m('L', mem, "\n");
1352
34
                        break;
1353
539
                    case cmd_opv_disable_clip:
1354
539
                        pcpath = NULL;
1355
539
                        if (clipper_dev_open)
1356
0
                            gx_destroy_clip_device_on_stack(&clipper_dev);
1357
539
                        clipper_dev_open = false;
1358
539
                        if_debug0m('L', mem, "\n");
1359
539
                        break;
1360
268k
                    case cmd_opv_begin_clip:
1361
268k
                        pcpath = NULL;
1362
268k
                        if (clipper_dev_open)
1363
0
                            gx_destroy_clip_device_on_stack(&clipper_dev);
1364
268k
                        clipper_dev_open = false;
1365
268k
                        in_clip = true;
1366
268k
                        if_debug0m('L', mem, "\n");
1367
268k
                        code = gx_cpath_reset(&clip_path);
1368
268k
                        if (code < 0)
1369
0
                            goto out;
1370
268k
                        gx_cpath_accum_begin(&clip_accum, mem, false);
1371
268k
                        gx_cpath_accum_set_cbox(&clip_accum,
1372
268k
                                                &target_box);
1373
268k
                        tdev = (gx_device *)&clip_accum;
1374
268k
                        clip_save.lop_enabled = state.lop_enabled;
1375
268k
                        clip_save.dcolor = fill_color;
1376
268k
                        clip_save.fa_save.x = gs_gstate.fill_adjust.x;
1377
268k
                        clip_save.fa_save.y = gs_gstate.fill_adjust.y;
1378
268k
                        cmd_getw(gs_gstate.fill_adjust.x, cbp);
1379
268k
                        cmd_getw(gs_gstate.fill_adjust.y, cbp);
1380
                        /* temporarily set a solid color */
1381
268k
                        color_set_pure(&fill_color, (gx_color_index)1);
1382
268k
                        state.lop_enabled = false;
1383
268k
                        gs_gstate.log_op = lop_default;
1384
268k
                        break;
1385
268k
                    case cmd_opv_end_clip:
1386
268k
                        if_debug0m('L', mem, "\n");
1387
268k
                        gx_cpath_accum_end(&clip_accum, &clip_path);
1388
268k
                        tdev = target;
1389
                        /*
1390
                         * If the entire band falls within the clip
1391
                         * path, no clipping is needed.
1392
                         */
1393
268k
                        {
1394
268k
                            gs_fixed_rect cbox;
1395
1396
268k
                            gx_cpath_inner_box(&clip_path, &cbox);
1397
268k
                            use_clip =
1398
268k
                                !(cbox.p.x <= target_box.p.x &&
1399
268k
                                  cbox.q.x >= target_box.q.x &&
1400
268k
                                  cbox.p.y <= target_box.p.y &&
1401
268k
                                  cbox.q.y >= target_box.q.y);
1402
268k
                        }
1403
268k
                        pcpath = (use_clip ? &clip_path : NULL);
1404
268k
                        if (pcpath) {
1405
172k
                            code = gx_cpath_ensure_path_list(pcpath);
1406
172k
                            if (code < 0)
1407
0
                                goto out;
1408
172k
                        }
1409
268k
                        if (clipper_dev_open)
1410
0
                            gx_destroy_clip_device_on_stack(&clipper_dev);
1411
268k
                        clipper_dev_open = false;
1412
268k
                        state.lop_enabled = clip_save.lop_enabled;
1413
268k
                        gs_gstate.log_op =
1414
268k
                            (state.lop_enabled ? state.lop :
1415
268k
                             lop_default);
1416
268k
                        fill_color = clip_save.dcolor;
1417
                        /* restore the fill_adjust if it was changed by begin_clip */
1418
268k
                        gs_gstate.fill_adjust.x = clip_save.fa_save.x;
1419
268k
                        gs_gstate.fill_adjust.y = clip_save.fa_save.y;
1420
268k
                        in_clip = false;
1421
268k
                        break;
1422
31.9k
                    case cmd_opv_set_color_space:
1423
31.9k
                        cbuf.ptr = cbp;
1424
31.9k
                        code = read_set_color_space(&cbuf, &gs_gstate, cdev, mem);
1425
31.9k
                        pcs = gs_gstate.color[0].color_space;
1426
31.9k
                        cbp = cbuf.ptr;
1427
31.9k
                        if (code < 0) {
1428
0
                            if (code == gs_error_rangecheck)
1429
0
                                goto bad_op;
1430
0
                            goto out;
1431
0
                        }
1432
31.9k
                        break;
1433
31.9k
                    case cmd_op_fill_rect_hl:
1434
0
                        {
1435
0
                            gs_fixed_rect rect_hl;
1436
1437
0
                            cbp = cmd_read_rect(op & 0xf0, &state.rect, cbp);
1438
0
                            if (fill_color.type != gx_dc_type_devn) {
1439
0
                                if_debug0m('L', mem, "hl rect fill without devn color\n");
1440
0
                                code = gs_note_error(gs_error_typecheck);
1441
0
                                goto out;
1442
0
                            }
1443
0
                            if_debug4m('L', mem, " x=%d y=%d w=%d h=%d\n",
1444
0
                                       state.rect.x, state.rect.y,
1445
0
                                       state.rect.width,state.rect.height);
1446
0
                            rect_hl.p.x = int2fixed(state.rect.x - x0);
1447
0
                            rect_hl.p.y = int2fixed(state.rect.y - y0);
1448
0
                            rect_hl.q.x = int2fixed(state.rect.width) + rect_hl.p.x;
1449
0
                            rect_hl.q.y = int2fixed(state.rect.height) + rect_hl.p.y;
1450
0
                            code = dev_proc(tdev, fill_rectangle_hl_color) (tdev,
1451
0
                                                        &rect_hl, NULL,
1452
0
                                                        &fill_color, NULL);
1453
0
                        }
1454
0
                        continue;
1455
31.9k
                    case cmd_opv_begin_image_rect:
1456
31.9k
                        cbuf.ptr = cbp;
1457
31.9k
                        code = read_begin_image(&cbuf, &image.c, pcs);
1458
31.9k
                        cbp = cbuf.ptr;
1459
31.9k
                        if (code < 0)
1460
0
                            goto out;
1461
31.9k
                        {
1462
31.9k
                            uint diff;
1463
1464
31.9k
                            cmd_getw(image_rect.p.x, cbp);
1465
31.9k
                            cmd_getw(image_rect.p.y, cbp);
1466
31.9k
                            cmd_getw(diff, cbp);
1467
31.9k
                            image_rect.q.x = image.d.Width - diff;
1468
31.9k
                            cmd_getw(diff, cbp);
1469
31.9k
                            image_rect.q.y = image.d.Height - diff;
1470
31.9k
                            if_debug4m('L', mem, " rect=(%d,%d),(%d,%d)",
1471
31.9k
                                       image_rect.p.x, image_rect.p.y,
1472
31.9k
                                       image_rect.q.x, image_rect.q.y);
1473
31.9k
                        }
1474
31.9k
                        goto ibegin;
1475
15
                    case cmd_opv_begin_image:
1476
15
                        cbuf.ptr = cbp;
1477
15
                        code = read_begin_image(&cbuf, &image.c, pcs);
1478
15
                        cbp = cbuf.ptr;
1479
15
                        if (code < 0)
1480
0
                            goto out;
1481
15
                        image_rect.p.x = 0;
1482
15
                        image_rect.p.y = 0;
1483
15
                        image_rect.q.x = image.d.Width;
1484
15
                        image_rect.q.y = image.d.Height;
1485
15
                        if_debug2m('L', mem, " size=(%d,%d)",
1486
15
                                  image.d.Width, image.d.Height);
1487
31.9k
ibegin:                 if_debug0m('L', mem, "\n");
1488
31.9k
                        {
1489
                            /* Processing an image operation */
1490
31.9k
                            dev_proc(tdev, set_graphics_type_tag)(tdev, GS_IMAGE_TAG);/* FIXME: what about text bitmaps? */
1491
31.9k
                            image.i4.override_in_smask = 0;
1492
31.9k
                            code = (*dev_proc(tdev, begin_typed_image))
1493
31.9k
                                (tdev, &gs_gstate, NULL,
1494
31.9k
                                 (const gs_image_common_t *)&image,
1495
31.9k
                                 &image_rect, &fill_color, pcpath, mem,
1496
31.9k
                                 &image_info);
1497
31.9k
                        }
1498
31.9k
                        if (code < 0)
1499
0
                            goto out;
1500
31.9k
                        break;
1501
31.9k
                    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
170k
                    case cmd_opv_image_data:
1537
170k
                        cmd_getw(data_height, cbp);
1538
170k
                        if (data_height == 0) {
1539
31.9k
                            if_debug0m('L', mem, " done image\n");
1540
31.9k
                            code = gx_image_end(image_info, true);
1541
31.9k
                            if (code < 0)
1542
0
                                goto out;
1543
31.9k
                            continue;
1544
31.9k
                        }
1545
138k
                        {
1546
138k
                            uint bytes_per_plane;
1547
138k
                            int plane;
1548
1549
138k
                            cmd_getw(bytes_per_plane, cbp);
1550
138k
                            if_debug2m('L', mem, " height=%u raster=%u\n",
1551
138k
                                       data_height, bytes_per_plane);
1552
138k
                            for (plane = 0;
1553
277k
                                 plane < image_info->num_planes;
1554
138k
                                 ++plane
1555
138k
                                 ) {
1556
138k
                                planes[plane].data_x = data_x;
1557
138k
                                planes[plane].raster = bytes_per_plane;
1558
138k
                            }
1559
138k
                        }
1560
138k
idata:                  data_size = 0;
1561
138k
                        {
1562
138k
                            int plane;
1563
1564
277k
                            for (plane = 0; plane < image_info->num_planes;
1565
138k
                                 ++plane)
1566
138k
                                data_size += planes[plane].raster;
1567
138k
                        }
1568
138k
                        data_size *= data_height;
1569
138k
                        data_on_heap = 0;
1570
138k
                        if (cbuf.end - cbp < data_size) {
1571
19.2k
                            code = top_up_cbuf(&cbuf, &cbp);
1572
19.2k
                            if (code < 0)
1573
0
                                goto top_up_failed;
1574
19.2k
                        }
1575
138k
                        if (cbuf.end - cbp >= data_size) {
1576
138k
                            planes[0].data = cbp;
1577
138k
                            cbp += data_size;
1578
138k
                        } else {
1579
0
                            uint cleft = cbuf.end - cbp;
1580
0
                            uint rleft = data_size - cleft;
1581
0
                            byte *rdata;
1582
1583
0
                            if (data_size > cbuf.end - cbuf.data) {
1584
                                /* Allocate a separate buffer. */
1585
0
                                rdata = data_on_heap =
1586
0
                                    gs_alloc_bytes(mem, data_size,
1587
0
                                                   "clist image_data");
1588
0
                                if (rdata == 0) {
1589
0
                                    code = gs_note_error(gs_error_VMerror);
1590
0
                                    goto out;
1591
0
                                }
1592
0
                            } else
1593
0
                                rdata = cbuf.data;
1594
0
                            memmove(rdata, cbp, cleft);
1595
0
                            if (data_on_heap)
1596
0
                                next_is_skip(&cbuf);
1597
0
                            if (sgets(s, rdata + cleft, rleft, &rleft) < 0) {
1598
0
                                code = gs_note_error(gs_error_unregistered); /* Must not happen. */
1599
0
                                goto out;
1600
0
                            }
1601
0
                            planes[0].data = rdata;
1602
0
                            cbp = cbuf.end;     /* force refill */
1603
0
                        }
1604
138k
                        {
1605
138k
                            int plane;
1606
138k
                            const byte *data = planes[0].data;
1607
1608
138k
                            for (plane = 0;
1609
277k
                                 plane < image_info->num_planes;
1610
138k
                                 ++plane
1611
138k
                                 ) {
1612
138k
                                if (planes[plane].raster == 0)
1613
0
                                    planes[plane].data = 0;
1614
138k
                                else {
1615
138k
                                    planes[plane].data = data;
1616
138k
                                    data += planes[plane].raster *
1617
138k
                                        data_height;
1618
138k
                                }
1619
138k
                            }
1620
138k
                        }
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
138k
                        code = gx_image_plane_data(image_info, planes,
1637
138k
                                                   data_height);
1638
138k
                        if (code < 0)
1639
0
                            gx_image_end(image_info, false);
1640
138k
                        if (data_on_heap)
1641
0
                            gs_free_object(mem, data_on_heap,
1642
138k
                                           "clist image_data");
1643
138k
                        data_x = 0;
1644
138k
                        if (code < 0)
1645
0
                            goto out;
1646
138k
                        continue;
1647
904k
                    case cmd_opv_extend:
1648
904k
                        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
515k
                            case cmd_opv_ext_composite:
1663
515k
                                if_debug0m('L', mem, " ext_composite\n");
1664
515k
                                cbuf.ptr = cbp;
1665
                                /*
1666
                                 * The screen phase may have been changed during
1667
                                 * the processing of masked images.
1668
                                 */
1669
515k
                                gx_gstate_setscreenphase(&gs_gstate,
1670
515k
                                            -x0, -y0, gs_color_select_all);
1671
515k
                                cbp -= 2; /* Step back to simplify the cycle invariant below. */
1672
12.2M
                                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
12.2M
                                    int len;
1678
1679
12.2M
                                    if (cbp >= cbuf.warn_limit) {
1680
3.18k
                                        code = top_up_cbuf(&cbuf, &cbp);
1681
3.18k
                                        if (code < 0)
1682
0
                                            goto out;
1683
3.18k
                                    }
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
12.2M
                                    if (cbp[0] == cmd_opv_extend && cbp[1] == cmd_opv_ext_composite) {
1694
7.62M
                                        gs_composite_t *pcomp, *pcomp_opening;
1695
7.62M
                                        gs_compositor_closing_state closing_state;
1696
1697
7.62M
                                        cbuf.ptr = cbp += 2;
1698
7.62M
                                        code = read_composite(&cbuf, mem, &pcomp);
1699
7.62M
                                        if (code < 0)
1700
0
                                            goto out;
1701
7.62M
                                        cbp = cbuf.ptr;
1702
7.62M
                                        if (pcomp == NULL)
1703
0
                                            continue;
1704
7.62M
                                        if (gs_is_pdf14trans_compositor(pcomp) &&
1705
7.62M
                                            playback_action == playback_action_render_no_pdf14) {
1706
                                            /* free the compositor object */
1707
728k
                                            gs_free_object(mem, pcomp, "read_composite");
1708
728k
                                            pcomp = NULL;
1709
728k
                                            continue;
1710
728k
                                        }
1711
6.89M
                                        pcomp_opening = pcomp_last;
1712
6.89M
                                        closing_state = pcomp->type->procs.is_closing(pcomp, &pcomp_opening, tdev);
1713
6.89M
                                        switch(closing_state)
1714
6.89M
                                        {
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
5.81M
                                        case COMP_ENQUEUE:
1721
                                            /* Enqueue. */
1722
5.81M
                                            enqueue_compositor(&pcomp_first, &pcomp_last, pcomp);
1723
5.81M
                                            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
66.0k
                                        case COMP_EXEC_QUEUE:
1733
                                            /* The opening command was executed. Execute the queue. */
1734
66.0k
                                            enqueue_compositor(&pcomp_first, &pcomp_last, pcomp);
1735
66.0k
                                            code = execute_compositor_queue(cdev, &target, &tdev,
1736
66.0k
                                                &gs_gstate, &pcomp_first, &pcomp_last, pcomp_first, x0, y0, mem, false);
1737
66.0k
                                            if (code < 0)
1738
0
                                                goto out;
1739
66.0k
                                            break;
1740
66.0k
                                        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
918k
                                        case COMP_REPLACE_CURR:
1749
                                            /* Replace specific compositor. */
1750
918k
                                            code = dequeue_compositor(&pcomp_first, &pcomp_last, pcomp_opening);
1751
918k
                                            if (code < 0)
1752
0
                                                goto out;
1753
918k
                                            enqueue_compositor(&pcomp_first, &pcomp_last, pcomp);
1754
918k
                                            free_compositor(pcomp_opening, mem);
1755
918k
                                            break;
1756
56
                                        case COMP_DROP_QUEUE:
1757
                                            /* Annihilate the last compositors. */
1758
56
                                            enqueue_compositor(&pcomp_first, &pcomp_last, pcomp);
1759
56
                                            code = drop_compositor_queue(&pcomp_first, &pcomp_last, pcomp_opening, mem, x0, y0, &gs_gstate);
1760
56
                                            if (code < 0)
1761
0
                                                goto out;
1762
56
                                            break;
1763
95.2k
                                        case COMP_MARK_IDLE:
1764
                                            /* Mark as idle. */
1765
95.2k
                                            enqueue_compositor(&pcomp_first, &pcomp_last, pcomp);
1766
95.2k
                                            mark_as_idle(pcomp_opening, pcomp);
1767
6.89M
                                        }
1768
6.89M
                                    } else if (is_null_compositor_op(cbp, &len)) {
1769
4.04M
                                        cbuf.ptr = cbp += len;
1770
4.04M
                                    } else if (cbp[0] == cmd_opv_end_page) {
1771
                                        /* End page, drop the queue. */
1772
124k
                                        code = execute_compositor_queue(cdev, &target, &tdev,
1773
124k
                                                &gs_gstate, &pcomp_first, &pcomp_last, pcomp_first, x0, y0, mem, true);
1774
124k
                                        if (code < 0)
1775
2
                                            goto out;
1776
124k
                                        break;
1777
412k
                                    } else if (pcomp_last != NULL &&
1778
412k
                                            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
21.9k
                                        uint cb;
1787
1788
21.9k
                                        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
21.9k
                                            case cmd_opv_set_misc:
1816
21.9k
                                                cb = *cbp++;
1817
21.9k
                                                switch (cb >> 6) {
1818
21.9k
                                                    case cmd_set_misc_map >> 6:
1819
21.9k
                                                        cbuf.ptr = cbp;
1820
21.9k
                                                        code = read_set_misc_map(cb, &cbuf, &gs_gstate, mem);
1821
21.9k
                                                        if (code < 0)
1822
0
                                                            goto out;
1823
21.9k
                                                        cbp = cbuf.ptr;
1824
21.9k
                                                        break;
1825
0
                                                    default:
1826
0
                                                        code = gs_note_error(gs_error_unregistered); /* Must not happen. */
1827
0
                                                        goto out;
1828
21.9k
                                                }
1829
21.9k
                                                break;
1830
21.9k
                                            default:
1831
0
                                                code = gs_note_error(gs_error_unregistered); /* Must not happen. */
1832
0
                                                goto out;
1833
21.9k
                                        }
1834
390k
                                    } else {
1835
                                        /* A drawing command, execute entire queue. */
1836
390k
                                        code = execute_compositor_queue(cdev, &target, &tdev,
1837
390k
                                            &gs_gstate, &pcomp_first, &pcomp_last, pcomp_first, x0, y0, mem, false);
1838
390k
                                        if (code < 0)
1839
0
                                            goto out;
1840
390k
                                        break;
1841
390k
                                    }
1842
12.2M
                                }
1843
515k
                                if (pcomp_last != NULL) {
1844
0
                                    code = gs_note_error(gs_error_unregistered);
1845
0
                                    goto out;
1846
0
                                }
1847
515k
                                break;
1848
515k
                            case cmd_opv_ext_put_halftone:
1849
0
                                {
1850
0
                                    uint    ht_size;
1851
1852
0
                                    if_debug0m('L', mem, " ext_put_halftone\n");
1853
0
                                    enc_u_getw(ht_size, cbp);
1854
0
                                    code = read_alloc_ht_buff(&ht_buff, ht_size, mem);
1855
0
                                    if (code < 0)
1856
0
                                        goto out;
1857
0
                                }
1858
0
                                break;
1859
0
                            case cmd_opv_ext_put_ht_seg:
1860
0
                                if_debug0m('L', mem, " ext_put_ht_seg\n");
1861
0
                                cbuf.ptr = cbp;
1862
0
                                code = read_ht_segment(&ht_buff, &cbuf,
1863
0
                                                       &gs_gstate, tdev,
1864
0
                                                       mem);
1865
0
                                cbp = cbuf.ptr;
1866
0
                                if (code < 0)
1867
0
                                    goto out;
1868
0
                                break;
1869
0
                            case cmd_opv_ext_set_color_is_devn:
1870
0
                                state.color_is_devn = true;
1871
0
                                if_debug0m('L', mem, " ext_set_color_is_devn\n");
1872
0
                                break;
1873
0
                            case cmd_opv_ext_unset_color_is_devn:
1874
0
                                state.color_is_devn = false;
1875
0
                                if_debug0m('L', mem, " ext_unset_color_is_devn\n");
1876
0
                                break;
1877
0
                            case cmd_opv_ext_tile_rect_hl:
1878
                                /* Strip tile with devn colors */
1879
0
                                cbp = cmd_read_rect(op & 0xf0, &state.rect, cbp);
1880
0
                                if_debug4m('L', mem, " x=%d y=%d w=%d h=%d\n",
1881
0
                                           state.rect.x, state.rect.y,
1882
0
                                           state.rect.width,state.rect.height);
1883
0
                                code = (*dev_proc(tdev, strip_tile_rect_devn))
1884
0
                                    (tdev, &state_tile,
1885
0
                                     state.rect.x - x0, state.rect.y - y0,
1886
0
                                     state.rect.width, state.rect.height,
1887
0
                                     &(state.tile_color_devn[0]),
1888
0
                                     &(state.tile_color_devn[1]),
1889
0
                                     tile_phase.x, tile_phase.y);
1890
0
                                break;
1891
343k
                            case cmd_opv_ext_put_fill_dcolor:
1892
343k
                                pdcolor = &fill_color;
1893
343k
                                goto load_dcolor;
1894
44.9k
                            case cmd_opv_ext_put_stroke_dcolor:
1895
44.9k
                                pdcolor = &stroke_color;
1896
44.9k
                                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
388k
                    load_dcolor:{
1903
388k
                                    uint    color_size;
1904
388k
                                    int left, offset, l;
1905
388k
                                    const gx_device_color_type_t *  pdct;
1906
388k
                                    byte type_and_flag = *cbp++;
1907
388k
                                    byte is_continuation = type_and_flag & 0x80;
1908
1909
388k
                                    if_debug0m('L', mem, " cmd_opv_ext_put_drawing_color\n");
1910
388k
                                    pdct = gx_get_dc_type_from_index(type_and_flag & 0x7F);
1911
388k
                                    if (pdct == 0) {
1912
0
                                        code = gs_note_error(gs_error_rangecheck);
1913
0
                                        goto out;
1914
0
                                    }
1915
388k
                                    offset = 0;
1916
388k
                                    if (is_continuation)
1917
388k
                                        enc_u_getw(offset, cbp);
1918
388k
                                    enc_u_getw(color_size, cbp);
1919
388k
                                    left = color_size;
1920
388k
                                    if (!left) {
1921
                                        /* We still need to call pdct->read because it may change dev_color.type -
1922
                                           see gx_dc_null_read.*/
1923
53.4k
                                        code = pdct->read(pdcolor, &gs_gstate,
1924
53.4k
                                                          pdcolor, tdev, offset,
1925
53.4k
                                                          cbp, 0, mem, x0, y0);
1926
53.4k
                                        if (code < 0)
1927
0
                                            goto out;
1928
53.4k
                                    }
1929
1.85M
                                    while (left) {
1930
1.46M
                                        if (cbuf.warn_limit - cbp < (int)left) {  /* cbp can be past warn_limit */
1931
1.17M
                                            code = top_up_cbuf(&cbuf, &cbp);
1932
1.17M
                                            if (code < 0)
1933
0
                                                goto top_up_failed;
1934
1.17M
                                        }
1935
1.46M
                                        l = min(left, cbuf.end - cbp);
1936
1.46M
                                        code = pdct->read(pdcolor, &gs_gstate,
1937
1.46M
                                                          pdcolor, tdev, offset,
1938
1.46M
                                                          cbp, l, mem, x0, y0);
1939
1.46M
                                        if (code < 0)
1940
0
                                            goto out;
1941
1.46M
                                        l = code;
1942
1.46M
                                        cbp += l;
1943
1.46M
                                        offset += l;
1944
1.46M
                                        left -= l;
1945
1.46M
                                    }
1946
388k
                                    code = gx_color_load(pdcolor, &gs_gstate,
1947
388k
                                                         tdev);
1948
388k
                                    if (code < 0)
1949
0
                                        goto out;
1950
388k
                                }
1951
388k
                                break;
1952
388k
                            default:
1953
0
                                goto bad_op;
1954
904k
                        }
1955
904k
                        break;
1956
904k
                    default:
1957
0
                        goto bad_op;
1958
1.94M
                }
1959
1.51M
                continue;
1960
1.51M
            case cmd_op_segment >> 4:
1961
1.30M
                {
1962
1.30M
                    int i;
1963
1.30M
                    static const byte op_num_operands[] = {
1964
1.30M
                        cmd_segment_op_num_operands_values
1965
1.30M
                    };
1966
1.30M
                  rgapto:
1967
1.30M
                    if (!in_path) {
1968
256k
                        ppos.x = int2fixed(state.rect.x);
1969
256k
                        ppos.y = int2fixed(state.rect.y);
1970
256k
                        if_debug2m('L', mem, " (%d,%d)", state.rect.x,
1971
256k
                                   state.rect.y);
1972
256k
                        notes = sn_none;
1973
256k
                        in_path = true;
1974
256k
                    }
1975
2.91M
                    for (i = 0; i < op_num_operands[op & 0xf]; ++i) {
1976
1.60M
                        fixed v;
1977
1.60M
                        int b = *cbp;
1978
1979
1.60M
                        switch (b >> 5) {
1980
234k
                            case 0:
1981
438k
                            case 1:
1982
438k
                                vs[i++] =
1983
438k
                                    ((fixed) ((b ^ 0x20) - 0x20) << 13) +
1984
438k
                                    ((int)cbp[1] << 5) + (cbp[2] >> 3);
1985
438k
                                if_debug1m('L', mem, " %g", fixed2float(vs[i - 1]));
1986
438k
                                cbp += 2;
1987
438k
                                v = (int)((*cbp & 7) ^ 4) - 4;
1988
438k
                                break;
1989
515k
                            case 2:
1990
963k
                            case 3:
1991
963k
                                v = (b ^ 0x60) - 0x20;
1992
963k
                                break;
1993
9.67k
                            case 4:
1994
20.0k
                            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
20.0k
                                v = (((b ^ 0xa0) - 0x20) << 8) + (int)*++cbp;
2003
20.0k
                                break;
2004
170k
                            case 6:
2005
170k
                                v = (b ^ 0xd0) - 0x10;
2006
170k
                                vs[i] =
2007
170k
                                    ((v << 8) + cbp[1]) << (_fixed_shift - 2);
2008
170k
                                if_debug1m('L', mem, " %g", fixed2float(vs[i]));
2009
170k
                                cbp += 2;
2010
170k
                                continue;
2011
11.7k
                            default /*case 7 */ :
2012
11.7k
                                v = (int)(*++cbp ^ 0x80) - 0x80;
2013
23.4k
                                for (b = 0; b < sizeof(fixed) - 3; ++b)
2014
11.7k
                                    v = (v << 8) + *++cbp;
2015
11.7k
                                break;
2016
1.60M
                        }
2017
1.43M
                        cbp += 3;
2018
                        /* Absent the cast in the next statement, */
2019
                        /* the Borland C++ 4.5 compiler incorrectly */
2020
                        /* sign-extends the result of the shift. */
2021
1.43M
                        vs[i] = (v << 16) + (uint) (cbp[-2] << 8) + cbp[-1];
2022
1.43M
                        if_debug1m('L', mem, " %g", fixed2float(vs[i]));
2023
1.43M
                    }
2024
1.30M
                    if_debug0m('L', mem, "\n");
2025
1.30M
                    code = clist_decode_segment(&path, op, vs, &ppos,
2026
1.30M
                                                x0, y0, notes);
2027
1.30M
                    if (code < 0)
2028
0
                        goto out;
2029
1.30M
                }
2030
1.30M
                continue;
2031
1.30M
            case cmd_op_path >> 4:
2032
394k
                if (op == cmd_opv_rgapto)
2033
0
                    goto rgapto;
2034
394k
                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
394k
                } else {
2050
394k
                    gx_path fpath;
2051
394k
                    gx_path *ppath = &path;
2052
2053
394k
                    if_debug0m('L', mem, "\n");
2054
                    /* if in clip, flatten path first */
2055
394k
                    if (in_clip) {
2056
91.1k
                        gx_path_init_local(&fpath, mem);
2057
91.1k
                        code = gx_path_add_flattened_accurate(&path, &fpath,
2058
91.1k
                                             gs_currentflat_inline(&gs_gstate),
2059
91.1k
                                             gs_gstate.accurate_curves);
2060
91.1k
                        if (code < 0)
2061
0
                            goto out;
2062
91.1k
                        ppath = &fpath;
2063
91.1k
                    }
2064
394k
                    switch (op) {
2065
231k
                        case cmd_opv_fill:
2066
231k
                            fill_params.rule = gx_rule_winding_number;
2067
231k
                            goto fill;
2068
10.4k
                        case cmd_opv_eofill:
2069
10.4k
                            fill_params.rule = gx_rule_even_odd;
2070
241k
                        fill:
2071
241k
                            fill_params.adjust = gs_gstate.fill_adjust;
2072
241k
                            fill_params.flatness = gs_gstate.flatness;
2073
241k
                            code = (*dev_proc(tdev, fill_path))(tdev, &gs_gstate, ppath,
2074
241k
                                                                &fill_params, &fill_color, pcpath);
2075
241k
                            break;
2076
9.55k
                        case cmd_opv_fill_stroke:
2077
9.55k
                            fill_params.rule = gx_rule_winding_number;
2078
9.55k
                            goto fill_stroke;
2079
1.11k
                        case cmd_opv_eofill_stroke:
2080
1.11k
                            fill_params.rule = gx_rule_even_odd;
2081
10.6k
                        fill_stroke:
2082
10.6k
                            fill_params.adjust = gs_gstate.fill_adjust;
2083
10.6k
                            fill_params.flatness = gs_gstate.flatness;
2084
10.6k
                            stroke_params.flatness = gs_gstate.flatness;
2085
10.6k
                            stroke_params.traditional = false;
2086
10.6k
                            code = (*dev_proc(tdev, fill_stroke_path))(tdev, &gs_gstate, ppath,
2087
10.6k
                                                                &fill_params, &fill_color,
2088
10.6k
                                                                &stroke_params, &stroke_color, pcpath);
2089
10.6k
                            break;
2090
142k
                        case cmd_opv_stroke:
2091
142k
                            stroke_params.flatness = gs_gstate.flatness;
2092
142k
                            stroke_params.traditional = false;
2093
142k
                            code = (*dev_proc(tdev, stroke_path))
2094
142k
                                                       (tdev, &gs_gstate,
2095
142k
                                                       ppath, &stroke_params,
2096
142k
                                                       &stroke_color, pcpath);
2097
142k
                            break;
2098
200
                        case cmd_opv_polyfill:
2099
200
                            code = clist_do_polyfill(tdev, ppath, &fill_color,
2100
200
                                                     gs_gstate.log_op);
2101
200
                            break;
2102
0
                        case cmd_opv_fill_trapezoid:
2103
0
                            {
2104
0
                                gs_fixed_edge left, right;
2105
0
                                fixed ybot, ytop;
2106
0
                                int options, swap_axes, wh;
2107
0
                                fixed x0f;
2108
0
                                fixed y0f;
2109
0
                                gx_device *ttdev = tdev;
2110
2111
0
                                if (pcpath != NULL && !clipper_dev_open) {
2112
0
                                    gx_make_clip_device_on_stack(&clipper_dev, pcpath, tdev);
2113
0
                                    clipper_dev_open = true;
2114
0
                                }
2115
0
                                if (clipper_dev_open)
2116
0
                                    ttdev = (gx_device *)&clipper_dev;
2117
                                /* Note that if we have transparency present, the clipper device may need to have
2118
                                   its color information updated to be synced up with the target device.
2119
                                   This can occur if we had fills of a path first with a transparency mask to get
2120
                                   an XPS opacity followed by a fill with a transparency group. This occurs in
2121
                                   the XPS gradient code */
2122
0
                                if (tdev->color_info.num_components != ttdev->color_info.num_components){
2123
                                    /* Reset the clipper device color information. Only worry about
2124
                                       the information that is used in the trap code */
2125
0
                                    ttdev->color_info.num_components = tdev->color_info.num_components;
2126
0
                                    ttdev->color_info.depth = tdev->color_info.depth;
2127
0
                                    ttdev->color_info.polarity = tdev->color_info.polarity;
2128
0
                                    memcpy(&(ttdev->color_info.comp_bits),&(tdev->color_info.comp_bits),GX_DEVICE_COLOR_MAX_COMPONENTS);
2129
0
                                    memcpy(&(ttdev->color_info.comp_shift),&(tdev->color_info.comp_shift),GX_DEVICE_COLOR_MAX_COMPONENTS);
2130
0
                                }
2131
0
                                cmd_getw(left.start.x, cbp);
2132
0
                                cmd_getw(left.start.y, cbp);
2133
0
                                cmd_getw(left.end.x, cbp);
2134
0
                                cmd_getw(left.end.y, cbp);
2135
0
                                cmd_getw(right.start.x, cbp);
2136
0
                                cmd_getw(right.start.y, cbp);
2137
0
                                cmd_getw(right.end.x, cbp);
2138
0
                                cmd_getw(right.end.y, cbp);
2139
0
                                cmd_getw(options, cbp);
2140
0
                                if (!(options & 4)) {
2141
0
                                    cmd_getw(ybot, cbp);
2142
0
                                    cmd_getw(ytop, cbp);
2143
0
                                } else
2144
0
                                    ytop = ybot = 0; /* Unused, but quiet gcc warning. */
2145
0
                                swap_axes = options & 1;
2146
0
                                wh = swap_axes ? tdev->width : tdev->height;
2147
0
                                x0f = int2fixed(swap_axes ? y0 : x0);
2148
0
                                y0f = int2fixed(swap_axes ? x0 : y0);
2149
0
                                left.start.x -= x0f;
2150
0
                                left.start.y -= y0f;
2151
0
                                left.end.x -= x0f;
2152
0
                                left.end.y -= y0f;
2153
0
                                right.start.x -= x0f;
2154
0
                                right.start.y -= y0f;
2155
0
                                right.end.x -= x0f;
2156
0
                                right.end.y -= y0f;
2157
0
                                if (options & 2) {
2158
0
                                    uchar num_components = tdev->color_info.num_components;
2159
0
                                    frac31 c[4][GX_DEVICE_COLOR_MAX_COMPONENTS], *cc[4];
2160
0
                                    byte colors_mask, i, j, m = 1;
2161
0
                                    gs_fill_attributes fa;
2162
0
                                    gs_fixed_rect clip;
2163
0
                                    fixed hh = int2fixed(swap_axes ? target->width : target->height);
2164
2165
0
                                    if (cbuf.end - cbp < 5 * cmd_max_intsize(sizeof(frac31))) {
2166
0
                                        code = top_up_cbuf(&cbuf, &cbp);
2167
0
                                        if (code < 0)
2168
0
                                            goto top_up_failed;
2169
0
                                    }
2170
0
                                    cmd_getw(clip.p.x, cbp);
2171
0
                                    cmd_getw(clip.p.y, cbp);
2172
0
                                    cmd_getw(clip.q.x, cbp);
2173
0
                                    cmd_getw(clip.q.y, cbp);
2174
0
                                    clip.p.x -= x0f;
2175
0
                                    clip.p.y -= y0f;
2176
0
                                    clip.q.x -= x0f;
2177
0
                                    clip.q.y -= y0f;
2178
0
                                    if (clip.p.y < 0)
2179
0
                                        clip.p.y = 0;
2180
0
                                    if (clip.q.y > hh)
2181
0
                                        clip.q.y = hh;
2182
0
                                    fa.clip = &clip;
2183
0
                                    fa.swap_axes = swap_axes;
2184
0
                                    fa.ht = NULL;
2185
0
                                    fa.lop = lop_default; /* fgixme: gs_gstate.log_op; */
2186
0
                                    fa.ystart = ybot - y0f;
2187
0
                                    fa.yend = ytop - y0f;
2188
0
                                    cmd_getw(colors_mask, cbp);
2189
0
                                    for (i = 0; i < 4; i++, m <<= 1) {
2190
0
                                        if (colors_mask & m) {
2191
0
                                            if (cbuf.end - cbp < num_components * cmd_max_intsize(sizeof(frac31))) {
2192
0
                                                code = top_up_cbuf(&cbuf, &cbp);
2193
0
                                                if (code < 0)
2194
0
                                                    goto top_up_failed;
2195
0
                                            }
2196
0
                                            cc[i] = c[i];
2197
0
                                            for (j = 0; j < num_components; j++)
2198
0
                                                cmd_getfrac(c[i][j], cbp);
2199
0
                                        } else
2200
0
                                            cc[i] = NULL;
2201
0
                                    }
2202
0
                                    if (options & 4) {
2203
0
#                                       if 1 /* Disable to debug gx_fill_triangle_small. */
2204
0
                                        code = dev_proc(ttdev, fill_linear_color_triangle)(ttdev, &fa,
2205
0
                                                        &left.start, &left.end, &right.start,
2206
0
                                                        cc[0], cc[1], cc[2]);
2207
#                                       else
2208
                                        code = 0;
2209
#                                       endif
2210
0
                                        if (code == 0) {
2211
                                            /* The target device didn't fill the trapezoid and
2212
                                               requests a decomposition. Subdivide into smaller triangles : */
2213
0
                                            if (pfs.dev == NULL)
2214
0
                                                code = gx_init_patch_fill_state_for_clist(tdev, &pfs, mem);
2215
0
                                            if (code >= 0) {
2216
0
                                                pfs.dev = ttdev;
2217
0
                                                pfs.rect = clip; /* fixme: eliminate 'clip'. */
2218
0
                                                fa.pfs = &pfs;
2219
0
                                                code = gx_fill_triangle_small(ttdev, &fa,
2220
0
                                                            &left.start, &left.end, &right.start,
2221
0
                                                            cc[0], cc[1], cc[2]);
2222
0
                                            }
2223
0
                                        }
2224
0
                                    } else {
2225
0
                                        code = dev_proc(ttdev, fill_linear_color_trapezoid)(ttdev, &fa,
2226
0
                                                        &left.start, &left.end, &right.start, &right.end,
2227
0
                                                        cc[0], cc[1], cc[2], cc[3]);
2228
0
                                        if (code == 0) {
2229
                                            /* Fixme : The target device didn't fill the trapezoid and
2230
                                               requests a decomposition.
2231
                                               Currently we never call it with 4 colors (see gxshade6.c)
2232
                                               and 2 colors must not return 0 - see comment to
2233
                                               dev_t_proc_fill_linear_color_trapezoid in gxdevcli.c .
2234
                                               Must not happen. */
2235
0
                                            code = gs_note_error(gs_error_unregistered);
2236
0
                                        }
2237
0
                                    }
2238
0
                                } else
2239
0
                                    code = gx_default_fill_trapezoid(ttdev, &left, &right,
2240
0
                                        max(ybot - y0f, fixed_half),
2241
0
                                        min(ytop - y0f, int2fixed(wh)), swap_axes,
2242
0
                                        &fill_color, gs_gstate.log_op);
2243
0
                            }
2244
0
                           break;
2245
0
                        default:
2246
0
                            goto bad_op;
2247
394k
                    }
2248
394k
                    if (ppath != &path)
2249
91.1k
                        gx_path_free(ppath, "clist_render_band");
2250
394k
                }
2251
394k
                if (in_path) {  /* path might be empty! */
2252
256k
                    state.rect.x = fixed2int_var(ppos.x);
2253
256k
                    state.rect.y = fixed2int_var(ppos.y);
2254
256k
                    in_path = false;
2255
256k
                }
2256
394k
                gx_path_free(&path, "clist_render_band");
2257
394k
                gx_path_init_local(&path, mem);
2258
394k
                if (code < 0)
2259
0
                    goto out;
2260
394k
                continue;
2261
394k
            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
23.4M
        }
2277
23.4M
        if_debug4m('L', mem, " x=%d y=%d w=%d h=%d\n",
2278
10.3M
                  state.rect.x, state.rect.y, state.rect.width,
2279
10.3M
                  state.rect.height);
2280
10.3M
        switch (op >> 4) {
2281
312k
            case cmd_op_fill_rect >> 4:
2282
312k
                if (state.rect.width == 0 && state.rect.height == 0 &&
2283
312k
                    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
123k
                    code = (dev_proc(tdev, fillpage) == NULL ? 0 :
2287
123k
                            (*dev_proc(tdev, fillpage))(tdev, &gs_gstate,
2288
123k
                                                        &fill_color));
2289
123k
                    break;
2290
123k
                }
2291
745k
            case cmd_op_fill_rect_short >> 4:
2292
8.76M
            case cmd_op_fill_rect_tiny >> 4:
2293
8.76M
                if (!state.lop_enabled) {
2294
8.76M
                    code = (*dev_proc(tdev, fill_rectangle))
2295
8.76M
                        (tdev, state.rect.x - x0, state.rect.y - y0,
2296
8.76M
                         state.rect.width, state.rect.height,
2297
8.76M
                         state.colors[1]);
2298
8.76M
                    break;
2299
8.76M
                }
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
4
            case cmd_op_tile_rect >> 4:
2320
4
                if (state.rect.width == 0 && state.rect.height == 0 &&
2321
4
                    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
167
            case cmd_op_tile_rect_short >> 4:
2326
167
            case cmd_op_tile_rect_tiny >> 4:
2327
                /* Currently we don't use lop with strip_tile_rectangle. */
2328
167
                code = (*dev_proc(tdev, strip_tile_rectangle))
2329
167
                    (tdev, &state_tile,
2330
167
                     state.rect.x - x0, state.rect.y - y0,
2331
167
                     state.rect.width, state.rect.height,
2332
167
                     state.tile_colors[0], state.tile_colors[1],
2333
167
                     tile_phase.x, tile_phase.y);
2334
167
                break;
2335
1.43M
            case cmd_op_copy_mono_planes >> 4:
2336
1.43M
                if (state.lop_enabled) {
2337
0
                    pcolor = state.colors;
2338
0
                    log_op = state.lop;
2339
0
                    goto do_rop;
2340
0
                }
2341
1.43M
                if ((op & cmd_copy_use_tile) || pcpath != NULL) {       /*
2342
                                                                         * This call of copy_mono originated as a call
2343
                                                                         * of fill_mask.
2344
                                                                         */
2345
1.43M
                    code = gx_image_fill_masked
2346
1.43M
                        (tdev, source, data_x, raster, gx_no_bitmap_id,
2347
1.43M
                         state.rect.x - x0, state.rect.y - y0,
2348
1.43M
                         state.rect.width - data_x, state.rect.height,
2349
1.43M
                         &fill_color, 1, gs_gstate.log_op, pcpath);
2350
1.43M
                } else {
2351
3.56k
                    if (plane_height == 0) {
2352
3.56k
                        code = (*dev_proc(tdev, copy_mono))
2353
3.56k
                             (tdev, source, data_x, raster, gx_no_bitmap_id,
2354
3.56k
                              state.rect.x - x0, state.rect.y - y0,
2355
3.56k
                              state.rect.width - data_x, state.rect.height,
2356
3.56k
                              state.colors[0], state.colors[1]);
2357
3.56k
                    } 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
3.56k
                }
2365
1.43M
                plane_height = 0;
2366
1.43M
                data_x = 0;
2367
1.43M
                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.3M
        }
2401
10.3M
    }
2402
    /* Clean up before we exit. */
2403
126k
  out:
2404
126k
    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
126k
    ht_buff.ht_size = 0;
2410
126k
    ht_buff.read_size = 0;
2411
2412
126k
    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
126k
    gx_cpath_free(&clip_path, "clist_render_band exit");
2419
126k
    gx_path_free(&path, "clist_render_band exit");
2420
126k
    if (gs_gstate.pattern_cache != NULL) {
2421
3.18k
        gx_pattern_cache_free(gs_gstate.pattern_cache);
2422
3.18k
        gs_gstate.pattern_cache = NULL;
2423
3.18k
    }
2424
    /* Free the client color and device colors allocated upon entry */
2425
126k
    gs_free_object(mem, gs_gstate.color[0].ccolor, "clist_playback_band");
2426
126k
    gs_free_object(mem, gs_gstate.color[1].ccolor, "clist_playback_band");
2427
126k
    gs_free_object(mem, gs_gstate.color[0].dev_color, "clist_playback_band");
2428
126k
    gs_free_object(mem, gs_gstate.color[1].dev_color, "clist_playback_band");
2429
126k
    gs_gstate.color[0].ccolor = gs_gstate.color[1].ccolor = NULL;
2430
126k
    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
126k
    gx_monitor_enter(cdev->icc_cache_cl->lock);
2435
126k
    gs_gstate_release(&gs_gstate);
2436
126k
    gx_monitor_leave(cdev->icc_cache_cl->lock); /* done with increment, let everyone run */
2437
126k
    gs_free_object(mem, data_bits, "clist_playback_band(data_bits)");
2438
126k
    if (target != orig_target) {
2439
69.1k
        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
69.1k
        } else {
2448
            /* Ref count was 1. close the device and then free it */
2449
69.1k
            if (target->is_open)
2450
0
                dev_proc(target, close_device)(target);
2451
69.1k
            gs_free_object(target->memory, target, "gxclrast discard compositor");
2452
69.1k
        }
2453
69.1k
        target = orig_target;
2454
69.1k
    }
2455
126k
    if (code < 0) {
2456
2
        if (pfs.dev != NULL)
2457
0
            term_patch_fill_state(&pfs);
2458
2
        rc_decrement(gs_gstate.color[0].color_space, "clist_playback_band");
2459
2
        rc_decrement(gs_gstate.color[1].color_space, "clist_playback_band");
2460
2
        gs_free_object(mem, cbuf_storage, "clist_playback_band(cbuf_storage)");
2461
2
        gx_cpath_free(&clip_path, "clist_playback_band");
2462
2
        if (pcpath != &clip_path)
2463
2
            gx_cpath_free(pcpath, "clist_playback_band");
2464
2
        if (clipper_dev_open)
2465
0
            gx_destroy_clip_device_on_stack(&clipper_dev);
2466
2
        return_error(code);
2467
2
    }
2468
    /* Check whether we have more pages to process. */
2469
126k
    if ((playback_action != playback_action_setup &&
2470
126k
        (cbp < cbuf.end || !seofp(s)) && (op != cmd_opv_end_page) )
2471
126k
        )
2472
0
        goto in;
2473
126k
    if (pfs.dev != NULL)
2474
0
        term_patch_fill_state(&pfs);
2475
126k
    rc_decrement(gs_gstate.color[0].color_space, "clist_playback_band");
2476
126k
    rc_decrement(gs_gstate.color[1].color_space, "clist_playback_band");
2477
126k
    gs_free_object(mem, cbuf_storage, "clist_playback_band(cbuf_storage)");
2478
126k
    gx_cpath_free(&clip_path, "clist_playback_band");
2479
126k
    if (pcpath != &clip_path)
2480
106k
        gx_cpath_free(pcpath, "clist_playback_band");
2481
126k
    if (clipper_dev_open)
2482
0
        gx_destroy_clip_device_on_stack(&clipper_dev);
2483
126k
    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
126k
}
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
3
{
2506
3
    const byte *cbp = pcb->ptr;
2507
3
    uint rep_width, rep_height;
2508
3
    uint pdepth;
2509
3
    byte bd = *cbp++;
2510
2511
3
    bits->head.depth = cmd_code_to_depth(bd);
2512
3
    if (for_pattern)
2513
3
        cmd_getw(bits->id, cbp);
2514
3
    cmd_getw(rep_width, cbp);
2515
3
    cmd_getw(rep_height, cbp);
2516
3
    if (bd & 0x20) {
2517
3
        cmd_getw(bits->x_reps, cbp);
2518
3
        bits->width = rep_width * bits->x_reps;
2519
3
    } else {
2520
0
        bits->x_reps = 1;
2521
0
        bits->width = rep_width;
2522
0
    }
2523
3
    if (bd & 0x40) {
2524
0
        cmd_getw(bits->y_reps, cbp);
2525
0
        bits->height = rep_height * bits->y_reps;
2526
3
    } else {
2527
3
        bits->y_reps = 1;
2528
3
        bits->height = rep_height;
2529
3
    }
2530
3
    if (bd & 0x80)
2531
3
        cmd_getw(bits->rep_shift, cbp);
2532
3
    else
2533
3
        bits->rep_shift = 0;
2534
3
    if (bd & 0x10)
2535
0
        bits->num_planes = *cbp++;
2536
3
    else
2537
3
        bits->num_planes = 1;
2538
3
    if_debug7('L', " depth=%d size=(%d,%d), rep_size=(%d,%d), rep_shift=%d, num_planes=%d\n",
2539
3
              bits->head.depth, bits->width,
2540
3
              bits->height, rep_width,
2541
3
              rep_height, bits->rep_shift, bits->num_planes);
2542
3
    bits->shift =
2543
3
        (bits->rep_shift == 0 ? 0 :
2544
3
         (bits->rep_shift * (bits->height / rep_height)) % rep_width);
2545
3
    pdepth = bits->head.depth;
2546
3
    if (bits->num_planes != 1)
2547
0
        pdepth /= bits->num_planes;
2548
3
    bits->raster = bitmap_raster(bits->width * pdepth);
2549
3
    pcb->ptr = cbp;
2550
3
    return 0;
2551
3
}
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
659k
{
2558
659k
    const byte *cbp = pcb->ptr;
2559
659k
    uint rep_width = bits->width / bits->x_reps;
2560
659k
    uint rep_height = bits->height / bits->y_reps;
2561
659k
    uint index;
2562
659k
    ulong offset;
2563
659k
    uint width_bits;
2564
659k
    uint width_bytes;
2565
659k
    uint raster;
2566
659k
    uint bytes;
2567
659k
    byte *data;
2568
659k
    tile_slot *slot;
2569
659k
    uint depth = bits->head.depth;
2570
2571
659k
    if (bits->num_planes != 1)
2572
0
        depth /= bits->num_planes;
2573
659k
    width_bits = rep_width * depth;
2574
2575
659k
    bytes = clist_bitmap_bytes(width_bits, rep_height * bits->num_planes,
2576
659k
                               compress |
2577
659k
                               (rep_width < bits->width ?
2578
659k
                                decompress_spread : 0) |
2579
659k
                               decompress_elsewhere,
2580
659k
                               &width_bytes,
2581
659k
                               (uint *)&raster);
2582
2583
659k
    cmd_getw(index, cbp);
2584
659k
    cmd_getw(offset, cbp);
2585
659k
    if_debug2m('L', mem, " index=%d offset=%lu\n", index, offset);
2586
659k
    pcls->tile_index = index;
2587
659k
    cdev->tile_table[pcls->tile_index].offset = offset;
2588
659k
    slot = (tile_slot *)(cdev->cache_chunk->data + offset);
2589
659k
    *pslot = slot;
2590
659k
    *slot = *bits;
2591
659k
    tile->data = data = (byte *)(slot + 1);
2592
#ifdef DEBUG
2593
    slot->index = pcls->tile_index;
2594
#endif
2595
659k
    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
659k
    } else if (compress) {
2600
        /*
2601
         * Decompress the image data.  We'd like to share this code with the
2602
         * similar code in copy_*, but right now we don't see how.
2603
         */
2604
0
        stream_cursor_read r;
2605
0
        stream_cursor_write w;
2606
        /*
2607
         * We don't know the data length a priori, so to be conservative, we
2608
         * read the uncompressed size.
2609
         */
2610
0
        uint cleft = pcb->end - cbp;
2611
2612
0
        if (cleft < bytes && !pcb->end_status) {
2613
0
            uint nread = cbuf_size - cleft;
2614
2615
0
            advance_buffer(pcb, cbp);
2616
0
            pcb->end_status = sgets(pcb->s, pcb->data + cleft, nread, &nread);
2617
0
            set_cb_end(pcb, pcb->data + cleft + nread);
2618
0
            cbp = pcb->data;
2619
0
        }
2620
0
        r.ptr = cbp - 1;
2621
0
        r.limit = pcb->end - 1;
2622
0
        w.ptr = data - 1;
2623
0
        w.limit = w.ptr + bytes;
2624
0
        switch (compress) {
2625
0
        case cmd_compress_rle:
2626
0
            {
2627
0
                stream_RLD_state sstate;
2628
2629
0
                clist_rld_init(&sstate);
2630
0
                (*s_RLD_template.process)
2631
0
                    ((stream_state *)&sstate, &r, &w, true);
2632
0
            }
2633
0
            break;
2634
0
        case cmd_compress_cfe:
2635
0
            {
2636
0
                stream_CFD_state sstate;
2637
2638
0
                clist_cfd_init(&sstate,
2639
0
                               width_bytes << 3 /*width_bits */ ,
2640
0
                               rep_height, mem);
2641
0
                (*s_CFD_template.process)
2642
0
                    ((stream_state *)&sstate, &r, &w, true);
2643
0
                (*s_CFD_template.release)
2644
0
                    ((stream_state *)&sstate);
2645
0
            }
2646
0
            break;
2647
0
        default:
2648
0
            return_error(gs_error_unregistered);
2649
0
        }
2650
0
        cbp = r.ptr + 1;
2651
659k
    } else if (rep_height * bits->num_planes > 1 && width_bytes != bits->raster) {
2652
653k
        cbp = cmd_read_short_bits(pcb, data, bytes,
2653
653k
                                  width_bytes, rep_height * bits->num_planes,
2654
653k
                                  bits->raster, cbp);
2655
653k
    } else {
2656
5.56k
        cbp = cmd_read_data(pcb, data, bytes, cbp);
2657
5.56k
    }
2658
659k
    if (bits->width > rep_width)
2659
3
        bits_replicate_horizontally(data,
2660
3
                                    rep_width * depth, rep_height * bits->num_planes,
2661
3
                                    bits->raster,
2662
3
                                    bits->width * depth,
2663
3
                                    bits->raster);
2664
659k
    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
659k
    pcb->ptr = cbp;
2673
659k
    return 0;
2674
659k
}
2675
2676
/* if necessary, allocate a buffer to hold a serialized halftone */
2677
static int
2678
read_alloc_ht_buff(ht_buff_t * pht_buff, uint ht_size, gs_memory_t * mem)
2679
0
{
2680
    /* free the existing buffer, if any (usually none) */
2681
0
    if (pht_buff->pbuff != 0) {
2682
0
        gs_free_object(mem, pht_buff->pbuff, "read_alloc_ht_buff");
2683
0
        pht_buff->pbuff = 0;
2684
0
    }
2685
2686
    /*
2687
     * If the serialized halftone fits in the command buffer, no
2688
     * additional buffer is required.
2689
     */
2690
0
    if (ht_size > cbuf_ht_seg_max_size) {
2691
0
        pht_buff->pbuff = gs_alloc_bytes(mem, ht_size, "read_alloc_ht_buff");
2692
0
        if (pht_buff->pbuff == 0)
2693
0
            return_error(gs_error_VMerror);
2694
0
    }
2695
0
    pht_buff->ht_size = ht_size;
2696
0
    pht_buff->read_size = 0;
2697
0
    pht_buff->pcurr = pht_buff->pbuff;
2698
0
    return 0;
2699
0
}
2700
2701
/* read a halftone segment; if it is the final segment, build the halftone */
2702
static int
2703
read_ht_segment(
2704
    ht_buff_t *                 pht_buff,
2705
    command_buf_t *             pcb,
2706
    gs_gstate *           pgs,
2707
    gx_device *                 dev,
2708
    gs_memory_t *               mem )
2709
0
{
2710
0
    const byte *                cbp = pcb->ptr;
2711
0
    const byte *                pbuff = 0;
2712
0
    uint                        ht_size = pht_buff->ht_size, seg_size;
2713
0
    int                         code = 0;
2714
2715
    /* get the segment size; refill command buffer if necessary */
2716
0
    enc_u_getw(seg_size, cbp);
2717
0
    if (pcb->warn_limit - cbp < (int)seg_size) { /* cbp can be past warn_limit */
2718
0
        code = top_up_cbuf(pcb, &cbp);
2719
0
        if (code < 0)
2720
0
            return code;
2721
0
        if (pcb->end - cbp < (int)seg_size) {
2722
0
            emprintf(mem, " *** ht segment size doesn't fit in buffer ***\n");
2723
0
            return_error(gs_error_unknownerror);
2724
0
        }
2725
0
    }
2726
2727
0
    if (pht_buff->pbuff == 0) {
2728
        /* if not separate buffer, must be only one segment */
2729
0
        if (seg_size != ht_size)
2730
0
            return_error(gs_error_unknownerror);
2731
0
        pbuff = cbp;
2732
0
    } else {
2733
0
        if (seg_size + pht_buff->read_size > pht_buff->ht_size)
2734
0
            return_error(gs_error_unknownerror);
2735
0
        memcpy(pht_buff->pcurr, cbp, seg_size);
2736
0
        pht_buff->pcurr += seg_size;
2737
0
        if ((pht_buff->read_size += seg_size) == ht_size)
2738
0
            pbuff = pht_buff->pbuff;
2739
0
    }
2740
2741
    /* if everything has been read, convert back to a halftone */
2742
0
    if (pbuff != 0) {
2743
0
        code = gx_ht_read_and_install(pgs, dev, pbuff, ht_size, mem);
2744
2745
        /* release any buffered information */
2746
0
        if (pht_buff->pbuff != 0) {
2747
0
            gs_free_object(mem, pht_buff->pbuff, "read_alloc_ht_buff");
2748
0
            pht_buff->pbuff = 0;
2749
0
            pht_buff->pcurr = 0;
2750
0
        }
2751
0
        pht_buff->ht_size = 0;
2752
0
        pht_buff->read_size = 0;
2753
0
    }
2754
2755
    /* update the command buffer ponter */
2756
0
    pcb->ptr = cbp + seg_size;
2757
2758
0
    return code;
2759
0
}
2760
2761
static int
2762
read_set_misc2(command_buf_t *pcb, gs_gstate *pgs, segment_notes *pnotes)
2763
98.5k
{
2764
98.5k
    const byte *cbp = pcb->ptr;
2765
98.5k
    uint mask, cb;
2766
2767
98.5k
    if_debug0m('L', pgs->memory, "\n");
2768
98.5k
    cmd_getw(mask, cbp);
2769
98.5k
    if (mask & cap_join_known) {
2770
13.5k
        cb = *cbp++;
2771
13.5k
        pgs->line_params.start_cap = (gs_line_cap)((cb >> 3) & 7);
2772
13.5k
        pgs->line_params.join = (gs_line_join)(cb & 7);
2773
13.5k
        if_debug2m('L', pgs->memory, "[L]      start_cap=%d join=%d\n",
2774
13.5k
                   pgs->line_params.start_cap, pgs->line_params.join);
2775
13.5k
        cb = *cbp++;
2776
13.5k
        pgs->line_params.end_cap = (gs_line_cap)((cb >> 3) & 7);
2777
13.5k
        pgs->line_params.dash_cap = (gs_line_cap)(cb & 7);
2778
13.5k
        if_debug2m('L', pgs->memory, "[L]      end_cap=%d dash_cap=%d\n",
2779
13.5k
                   pgs->line_params.end_cap, pgs->line_params.dash_cap);
2780
13.5k
    }
2781
98.5k
    if (mask & cj_ac_sa_known) {
2782
4.54k
        cb = *cbp++;
2783
4.54k
        pgs->line_params.curve_join = ((cb >> 2) & 7) - 1;
2784
4.54k
        pgs->accurate_curves = (cb & 2) != 0;
2785
4.54k
        pgs->stroke_adjust = cb & 1;
2786
4.54k
        if_debug3m('L', pgs->memory, "[L]      CJ=%d AC=%d SA=%d\n",
2787
4.54k
                   pgs->line_params.curve_join, pgs->accurate_curves,
2788
4.54k
                   pgs->stroke_adjust);
2789
4.54k
    }
2790
98.5k
    if (mask & flatness_known) {
2791
2.21k
        cmd_get_value(pgs->flatness, cbp);
2792
2.21k
        if_debug1m('L', pgs->memory, "[L]      flatness=%g\n", pgs->flatness);
2793
2.21k
    }
2794
98.5k
    if (mask & line_width_known) {
2795
35.4k
        float width;
2796
2797
35.4k
        cmd_get_value(width, cbp);
2798
35.4k
        if_debug1m('L', pgs->memory, "[L]      line_width=%g\n", width);
2799
35.4k
        gx_set_line_width(&pgs->line_params, width);
2800
35.4k
    }
2801
98.5k
    if (mask & miter_limit_known) {
2802
917
        float limit;
2803
2804
917
        cmd_get_value(limit, cbp);
2805
917
        if_debug1m('L', pgs->memory, "[L]      miter_limit=%g\n", limit);
2806
917
        gx_set_miter_limit(&pgs->line_params, limit);
2807
917
    }
2808
98.5k
    if (mask & op_bm_tk_known) {
2809
52.9k
        cb = *cbp++;
2810
52.9k
        pgs->blend_mode = cb >> 3;
2811
52.9k
        pgs->text_knockout = cb & 1;
2812
        /* the following usually have no effect; see gxclpath.c */
2813
52.9k
        cb = *cbp++;
2814
52.9k
        pgs->overprint_mode = (cb >> 2) & 1;
2815
52.9k
        pgs->stroke_overprint = (cb >> 1) & 1;
2816
52.9k
        pgs->overprint = cb & 1;
2817
52.9k
        cb = *cbp++;
2818
52.9k
        pgs->renderingintent = cb;
2819
52.9k
        if_debug6m('L', pgs->memory, "[L]      BM=%d TK=%d OPM=%d OP=%d op=%d RI=%d\n",
2820
52.9k
                   pgs->blend_mode, pgs->text_knockout, pgs->overprint_mode,
2821
52.9k
                   pgs->stroke_overprint, pgs->overprint, pgs->renderingintent);
2822
52.9k
    }
2823
98.5k
    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
98.5k
    if (mask & ais_known) {
2829
2.47k
        cmd_get_value(pgs->alphaisshape, cbp);
2830
2.47k
        if_debug1m('L', pgs->memory, "[L]      alphaisshape=%d\n", pgs->alphaisshape);
2831
2.47k
    }
2832
98.5k
    if (mask & stroke_alpha_known) {
2833
37.5k
        cmd_get_value(pgs->strokeconstantalpha, cbp);
2834
37.5k
        if_debug1m('L', pgs->memory, "[L]      strokeconstantalpha=%g\n", pgs->strokeconstantalpha);
2835
37.5k
    }
2836
98.5k
    if (mask & fill_alpha_known) {
2837
38.3k
        cmd_get_value(pgs->fillconstantalpha, cbp);
2838
38.3k
        if_debug1m('L', pgs->memory, "[L]      fillconstantalpha=%u\n", (uint)(pgs->fillconstantalpha));
2839
38.3k
    }
2840
98.5k
    pcb->ptr = cbp;
2841
98.5k
    return 0;
2842
98.5k
}
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
31.9k
{
2848
31.9k
    const byte *cbp = pcb->ptr;
2849
31.9k
    byte b = *cbp++;
2850
31.9k
    int index = b >> 4;
2851
31.9k
    gs_color_space *pcs;
2852
31.9k
    int code = 0;
2853
31.9k
    cmm_profile_t *picc_profile;
2854
31.9k
    clist_icc_color_t icc_information;
2855
2856
31.9k
    if_debug3m('L', mem, " %d%s%s\n", index,
2857
31.9k
               (b & 8 ? " (indexed)" : ""),
2858
31.9k
               (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
31.9k
    memcpy(&icc_information, cbp, sizeof(clist_icc_color_t));
2864
31.9k
    cbp = cbp + sizeof(clist_icc_color_t);
2865
31.9k
    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
31.9k
    case gs_color_space_index_ICC:
2876
        /* build the color space object */
2877
31.9k
        code = gs_cspace_build_ICC(&pcs, NULL, mem);
2878
        /* Don't bother getting the ICC stuff from the clist yet */
2879
31.9k
        picc_profile = gsicc_profile_new(NULL, cdev->memory, NULL, 0);
2880
31.9k
        if (picc_profile == NULL)
2881
0
            return gs_rethrow(-1, "Failed to find ICC profile during clist read");
2882
31.9k
        picc_profile->num_comps = icc_information.icc_num_components;
2883
31.9k
        picc_profile->hashcode = icc_information.icc_hash;
2884
31.9k
        picc_profile->hash_is_valid = true;
2885
31.9k
        picc_profile->islab = icc_information.is_lab;
2886
31.9k
        picc_profile->default_match = icc_information.default_match;
2887
31.9k
        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
31.9k
        picc_profile->dev = (gx_device*) cdev;
2893
        /* Assign it to the colorspace */
2894
31.9k
        code = gsicc_set_gscs_profile(pcs, picc_profile, mem);
2895
        /* And we no longer need our reference to the profile */
2896
31.9k
        gsicc_adjust_profile_rc(picc_profile, -1, "read_set_color_space");
2897
31.9k
        break;
2898
0
    default:
2899
0
        code = gs_note_error(gs_error_rangecheck);      /* others are NYI */
2900
0
        goto out;
2901
31.9k
    }
2902
2903
31.9k
    if (pcs == NULL) {
2904
0
        code = gs_note_error(gs_error_VMerror);
2905
0
        goto out;
2906
0
    }
2907
2908
31.9k
    if (b & 8) {
2909
1.19k
        bool use_proc = (b & 4) != 0;
2910
1.19k
        int hival;
2911
1.19k
        int num_values;
2912
1.19k
        byte *data;
2913
1.19k
        uint data_size;
2914
1.19k
        gs_color_space *pcs_indexed;
2915
2916
1.19k
        pcs_indexed = gs_cspace_alloc(mem, &gs_color_space_type_Indexed);
2917
1.19k
        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
1.19k
        pcs_indexed->base_space = pcs;
2923
1.19k
        pcs = pcs_indexed;
2924
1.19k
        pcs->params.indexed.use_proc = 0;
2925
1.19k
        pcs->params.indexed.lookup.table.data = 0;
2926
1.19k
        pcs->params.indexed.lookup.table.size = 0;
2927
1.19k
        cmd_getw(hival, cbp);
2928
1.19k
        pcs->params.indexed.n_comps = gs_color_space_num_components(pcs->base_space);
2929
1.19k
        num_values = (hival + 1) * pcs->params.indexed.n_comps;
2930
1.19k
        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
1.19k
        } else {
2943
1.19k
            byte *table = gs_alloc_string(mem, num_values, "color_space indexed table");
2944
2945
1.19k
            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
1.19k
            pcs->params.indexed.lookup.table.data = table;
2951
1.19k
            pcs->params.indexed.lookup.table.size = num_values;
2952
1.19k
            data = table;
2953
1.19k
            data_size = num_values;
2954
1.19k
        }
2955
1.19k
        cbp = cmd_read_data(pcb, data, data_size, cbp);
2956
1.19k
        pcs->params.indexed.hival = hival;
2957
1.19k
        pcs->params.indexed.use_proc = use_proc;
2958
1.19k
    }
2959
2960
    /* Release reference to old color space before installing new one. */
2961
31.9k
    if (pgs->color[0].color_space != NULL)
2962
31.9k
        rc_decrement_only_cs(pgs->color[0].color_space, "read_set_color_space");
2963
31.9k
    pgs->color[0].color_space = pcs;
2964
31.9k
out:
2965
31.9k
    pcb->ptr = cbp;
2966
31.9k
    return code;
2967
31.9k
}
2968
2969
static int
2970
read_begin_image(command_buf_t *pcb, gs_image_common_t *pic,
2971
                 gs_color_space *pcs)
2972
31.9k
{
2973
31.9k
    uint index = *(pcb->ptr)++;
2974
31.9k
    const gx_image_type_t *image_type = gx_image_type_table[index];
2975
31.9k
    stream s;
2976
31.9k
    int code;
2977
2978
    /* This is sloppy, but we don't have enough information to do better. */
2979
31.9k
    code = top_up_cbuf(pcb, &pcb->ptr);
2980
31.9k
    if (code < 0)
2981
0
        return code;
2982
31.9k
    s_init(&s, NULL);
2983
31.9k
    sread_string(&s, pcb->ptr, pcb->end - pcb->ptr);
2984
31.9k
    code = image_type->sget(pic, &s, pcs);
2985
31.9k
    pcb->ptr = sbufptr(&s);
2986
31.9k
    pic->imagematrices_are_untrustworthy = 0;
2987
31.9k
    return code;
2988
31.9k
}
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
7.62M
{
3086
7.62M
    const byte *                cbp = pcb->ptr;
3087
7.62M
    int                         comp_id = 0, code = 0;
3088
7.62M
    const gs_composite_type_t * pcomp_type = 0;
3089
3090
    /* fill the command buffer (see comment above) */
3091
7.62M
    if (pcb->end - cbp < MAX_CLIST_COMPOSITOR_SIZE + sizeof(comp_id)) {
3092
960k
        code = top_up_cbuf(pcb, &cbp);
3093
960k
        if (code < 0)
3094
0
            return code;
3095
960k
    }
3096
3097
    /* find the appropriate compositor method vector */
3098
7.62M
    comp_id = *cbp++;
3099
7.62M
    if ((pcomp_type = gs_find_compositor(comp_id)) == 0)
3100
0
        return_error(gs_error_unknownerror);
3101
3102
    /* de-serialize the compositor */
3103
7.62M
    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
7.62M
    if ( code > MAX_CLIST_COMPOSITOR_SIZE )
3107
0
        return_error(gs_error_rangecheck);
3108
3109
7.62M
    if (code > 0)
3110
7.62M
        cbp += code;
3111
7.62M
    pcb->ptr = cbp;
3112
7.62M
    return code;
3113
7.62M
}
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
5.97M
{
3119
5.97M
    gx_device *tdev = *ptarget;
3120
5.97M
    int code;
3121
3122
5.97M
    code = pcomp->type->procs.adjust_ctm(pcomp, x0, y0, pgs);
3123
5.97M
    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
5.97M
    code = dev_proc(tdev, composite)(tdev, &tdev, pcomp, pgs, mem, (gx_device*) cdev);
3130
5.97M
    if (code == 1) {
3131
        /* A new compositor was created that wrapped tdev. This should
3132
         * be our new target. */
3133
69.1k
        *ptarget = tdev;
3134
69.1k
        code = 0;
3135
69.1k
    }
3136
5.97M
    if (code < 0)
3137
2
        goto exit;
3138
3139
    /* Perform any updates for the clist device required */
3140
5.97M
    code = pcomp->type->procs.clist_compositor_read_update(pcomp,
3141
5.97M
                                        (gx_device *)cdev, tdev, pgs, mem);
3142
5.97M
exit:
3143
    /* free the compositor object */
3144
5.97M
    gs_free_object(mem, pcomp, "read_composite");
3145
3146
5.97M
    return code;
3147
5.97M
}
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
654k
{
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
654k
    cbp = cmd_read_data(pcb, data, tot_bytes, cbp);
3166
3167
    /* if needed, adjust buffer contents for dest raster > width_bytes */
3168
654k
    if (width_bytes < raster) {
3169
654k
        const byte *pdata = data /*src*/ + width_bytes * height;
3170
654k
        byte *udata = data /*dest*/ + height * raster;
3171
3172
11.0M
        while (--height > 0) { /* don't need to move the first line to itself */
3173
10.4M
            udata -= raster, pdata -= width_bytes;
3174
10.4M
            switch (width_bytes) {
3175
0
                default:
3176
0
                    memmove(udata, pdata, width_bytes);
3177
0
                    break;
3178
73.2k
                case 6:
3179
73.2k
                    udata[5] = pdata[5];
3180
226k
                case 5:
3181
226k
                    udata[4] = pdata[4];
3182
857k
                case 4:
3183
857k
                    udata[3] = pdata[3];
3184
2.92M
                case 3:
3185
2.92M
                    udata[2] = pdata[2];
3186
8.55M
                case 2:
3187
8.55M
                    udata[1] = pdata[1];
3188
10.4M
                case 1:
3189
10.4M
                    udata[0] = pdata[0];
3190
10.4M
                case 0:;            /* shouldn't happen */
3191
10.4M
            }
3192
10.4M
        }
3193
654k
    }
3194
654k
    return cbp;
3195
654k
}
3196
3197
/* Read a rectangle. */
3198
static const byte *
3199
cmd_read_rect(int op, gx_cmd_rect * prect, const byte * cbp)
3200
312k
{
3201
312k
    cmd_getw(prect->x, cbp);
3202
312k
    if (op & 0xf)
3203
64.0k
        prect->y += ((op >> 2) & 3) - 2;
3204
248k
    else {
3205
248k
        cmd_getw(prect->y, cbp);
3206
248k
    }
3207
312k
    cmd_getw(prect->width, cbp);
3208
312k
    if (op & 0xf)
3209
64.0k
        prect->height += (op & 3) - 2;
3210
248k
    else {
3211
248k
        cmd_getw(prect->height, cbp);
3212
248k
    }
3213
312k
    return cbp;
3214
312k
}
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
374k
{
3232
374k
    gx_transfer_map *map;
3233
374k
    gx_transfer_map **pmap;
3234
374k
    const char *cname;
3235
3236
374k
    *pcomp_num = NULL;          /* Only used for color transfer maps */
3237
374k
    switch (map_index) {
3238
124k
        case cmd_map_transfer:
3239
124k
            if_debug0m('L', mem, " transfer");
3240
124k
            rc_unshare_struct(pgs->set_transfer.gray, gx_transfer_map,
3241
124k
                &st_transfer_map, mem, return_error(gs_error_VMerror),
3242
124k
                "cmd_select_map(default_transfer)");
3243
124k
            map = pgs->set_transfer.gray;
3244
            /* Release all current maps */
3245
124k
            rc_decrement(pgs->set_transfer.red, "cmd_select_map(red)");
3246
124k
            pgs->set_transfer.red = NULL;
3247
124k
            pgs->set_transfer.red_component_num = -1;
3248
124k
            rc_decrement(pgs->set_transfer.green, "cmd_select_map(green)");
3249
124k
            pgs->set_transfer.green = NULL;
3250
124k
            pgs->set_transfer.green_component_num = -1;
3251
124k
            rc_decrement(pgs->set_transfer.blue, "cmd_select_map(blue)");
3252
124k
            pgs->set_transfer.blue = NULL;
3253
124k
            pgs->set_transfer.blue_component_num = -1;
3254
124k
            goto transfer2;
3255
0
        case cmd_map_transfer_0:
3256
0
            pmap = &pgs->set_transfer.red;
3257
0
            *pcomp_num = &pgs->set_transfer.red_component_num;
3258
0
            goto transfer1;
3259
0
        case cmd_map_transfer_1:
3260
0
            pmap = &pgs->set_transfer.green;
3261
0
            *pcomp_num = &pgs->set_transfer.green_component_num;
3262
0
            goto transfer1;
3263
0
        case cmd_map_transfer_2:
3264
0
            pmap = &pgs->set_transfer.blue;
3265
0
            *pcomp_num = &pgs->set_transfer.blue_component_num;
3266
0
            goto transfer1;
3267
0
        case cmd_map_transfer_3:
3268
0
            pmap = &pgs->set_transfer.gray;
3269
0
            *pcomp_num = &pgs->set_transfer.gray_component_num;
3270
0
transfer1:  if_debug1m('L', mem, " transfer[%d]", (int)(map_index - cmd_map_transfer_0));
3271
0
            rc_unshare_struct(*pmap, gx_transfer_map, &st_transfer_map, mem,
3272
0
                return_error(gs_error_VMerror), "cmd_select_map(transfer)");
3273
0
            map = *pmap;
3274
3275
124k
transfer2:  if (cont != cmd_map_other) {
3276
124k
                gx_set_identity_transfer(map);
3277
124k
                *pmdata = 0;
3278
124k
                *pcount = 0;
3279
124k
                return 0;
3280
124k
            }
3281
0
            break;
3282
124k
        case cmd_map_black_generation:
3283
124k
            if_debug0m('L', mem, " black generation");
3284
124k
            pmap = &pgs->black_generation;
3285
124k
            cname = "cmd_select_map(black generation)";
3286
124k
            goto alloc;
3287
124k
        case cmd_map_undercolor_removal:
3288
124k
            if_debug0m('L', mem, " undercolor removal");
3289
124k
            pmap = &pgs->undercolor_removal;
3290
124k
            cname = "cmd_select_map(undercolor removal)";
3291
249k
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
249k
            rc_unshare_struct(*pmap, gx_transfer_map, &st_transfer_map,
3299
249k
                              mem, return_error(gs_error_VMerror), cname);
3300
249k
            map = *pmap;
3301
249k
            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
249k
            break;
3308
249k
        default:
3309
0
            *pmdata = 0;
3310
0
            return 0;
3311
374k
    }
3312
249k
    map->proc = gs_mapped_transfer;
3313
249k
    *pmdata = map->values;
3314
249k
    *pcount = sizeof(map->values);
3315
249k
    return 0;
3316
374k
}
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
1.30M
{
3401
1.30M
    fixed px = ppos->x - int2fixed(x0);
3402
1.30M
    fixed py = ppos->y - int2fixed(y0);
3403
1.30M
    int code;
3404
3405
1.43M
#define A vs[0]
3406
1.30M
#define B vs[1]
3407
1.30M
#define C vs[2]
3408
1.30M
#define D vs[3]
3409
1.30M
#define E vs[4]
3410
1.30M
#define F vs[5]
3411
3412
1.30M
    switch (op) {
3413
282k
        case cmd_opv_rmoveto:
3414
282k
            code = gx_path_add_point(ppath, px += A, py += B);
3415
282k
            break;
3416
91.3k
        case cmd_opv_rlineto:
3417
91.3k
            code = gx_path_add_line_notes(ppath, px += A, py += B, notes);
3418
91.3k
            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
290k
        case cmd_opv_hlineto:
3423
290k
            code = gx_path_add_line_notes(ppath, px += A, py, notes);
3424
290k
            break;
3425
459k
        case cmd_opv_vlineto:
3426
459k
            code = gx_path_add_line_notes(ppath, px, py += A, notes);
3427
459k
            break;
3428
9.22k
        case cmd_opv_rmlineto:
3429
9.22k
            if ((code = gx_path_add_point(ppath, px += A, py += B)) < 0)
3430
0
                break;
3431
9.22k
            code = gx_path_add_line_notes(ppath, px += C, py += D, notes);
3432
9.22k
            break;
3433
9.30k
        case cmd_opv_rm2lineto:
3434
9.30k
            if ((code = gx_path_add_point(ppath, px += A, py += B)) < 0 ||
3435
9.30k
                (code = gx_path_add_line_notes(ppath, px += C, py += D,
3436
9.30k
                                               notes)) < 0
3437
9.30k
                )
3438
0
                break;
3439
9.30k
            code = gx_path_add_line_notes(ppath, px += E, py += F, notes);
3440
9.30k
            break;
3441
153
        case cmd_opv_rm3lineto:
3442
153
            if ((code = gx_path_add_point(ppath, px += A, py += B)) < 0 ||
3443
153
                (code = gx_path_add_line_notes(ppath, px += C, py += D,
3444
153
                                               notes)) < 0 ||
3445
153
                (code = gx_path_add_line_notes(ppath, px += E, py += F,
3446
153
                                               notes)) < 0
3447
153
                )
3448
0
                break;
3449
153
            code = gx_path_add_line_notes(ppath, px -= C, py -= D, notes);
3450
153
            break;
3451
55.9k
        case cmd_opv_rrcurveto: /* a b c d e f => a b a+c b+d a+c+e b+d+f */
3452
56.8k
rrc:        E += (C += A);
3453
56.8k
            F += (D += B);
3454
88.0k
curve:      code = gx_path_add_curve_notes(ppath, px + A, py + B,
3455
88.0k
                                           px + C, py + D,
3456
88.0k
                                           px + E, py + F, notes);
3457
88.0k
            px += E, py += F;
3458
88.0k
            break;
3459
12.1k
        case cmd_opv_hvcurveto: /* a b c d => a 0 a+b c a+b c+d */
3460
14.3k
hvc:        F = C + D, D = C, E = C = A + B, B = 0;
3461
14.3k
            goto curve;
3462
14.3k
        case cmd_opv_vhcurveto: /* a b c d => 0 a b a+c b+d a+c */
3463
16.2k
vhc:        E = B + D, F = D = A + C, C = B, B = A, A = 0;
3464
16.2k
            goto curve;
3465
229
        case cmd_opv_nrcurveto: /* a b c d => 0 0 a b a+c b+d */
3466
229
            F = B + D, E = A + C, D = B, C = A, B = A = 0;
3467
229
            goto curve;
3468
393
        case cmd_opv_rncurveto: /* a b c d => a b a+c b+d a+c b+d */
3469
393
            F = D += B, E = C += A;
3470
393
            goto curve;
3471
1.89k
        case cmd_opv_vqcurveto: /* a b => VH a b TS(a,b) TS(b,a) */
3472
1.89k
            if ((A ^ B) < 0)
3473
480
                C = -B, D = -A;
3474
1.41k
            else
3475
1.41k
                C = B, D = A;
3476
1.89k
            goto vhc;
3477
2.19k
        case cmd_opv_hqcurveto: /* a b => HV a TS(a,b) b TS(b,a) */
3478
2.19k
            if ((A ^ B) < 0)
3479
363
                D = -A, C = B, B = -B;
3480
1.82k
            else
3481
1.82k
                D = A, C = B;
3482
2.19k
            goto hvc;
3483
908
        case cmd_opv_scurveto: /* (a b c d e f) => */
3484
908
            {
3485
908
                fixed a = A, b = B;
3486
3487
                /* See gxclpath.h for details on the following. */
3488
908
                if (A == 0) {
3489
                    /* Previous curve was vh or vv */
3490
873
                    A = E - C, B = D - F, C = C - a, D = b - D, E = a, F = -b;
3491
873
                } else {
3492
                    /* Previous curve was hv or hh */
3493
35
                    A = C - E, B = F - D, C = a - C, D = D - b, E = -a, F = b;
3494
35
                }
3495
908
            }
3496
908
            goto rrc;
3497
75.0k
        case cmd_opv_closepath:
3498
75.0k
            if ((code = gx_path_close_subpath(ppath)) < 0)
3499
75.0k
                return code;;
3500
75.0k
            if ((code = gx_path_current_point(ppath, (gs_fixed_point *) vs)) < 0)
3501
75.0k
                return code;;
3502
75.0k
            px = A, py = B;
3503
75.0k
            break;
3504
0
        default:
3505
0
            return_error(gs_error_rangecheck);
3506
1.30M
    }
3507
1.30M
#undef A
3508
1.30M
#undef B
3509
1.30M
#undef C
3510
1.30M
#undef D
3511
1.30M
#undef E
3512
1.30M
#undef F
3513
1.30M
    ppos->x = px + int2fixed(x0);
3514
1.30M
    ppos->y = py + int2fixed(y0);
3515
1.30M
    return code;
3516
1.30M
}
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
200
{
3530
200
    const subpath *psub = ppath->first_subpath;
3531
200
    const segment *pseg1;
3532
200
    const segment *pseg2;
3533
200
    int code;
3534
3535
200
    if (psub && (pseg1 = psub->next) != 0 && (pseg2 = pseg1->next) != 0) {
3536
200
        fixed px = psub->pt.x, py = psub->pt.y;
3537
200
        fixed ax = pseg1->pt.x - px, ay = pseg1->pt.y - py;
3538
200
        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
200
        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
200
        if (pseg2->next && !(px == pseg2->next->pt.x && py == pseg2->next->pt.y)) {
3548
            /* Parallelogram */
3549
200
            fill = dev_proc(dev, fill_parallelogram);
3550
200
            bx = pseg2->pt.x - pseg1->pt.x;
3551
200
            by = pseg2->pt.y - pseg1->pt.y;
3552
200
        } 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
200
        code = fill(dev, px, py, ax, ay, bx, by, pdcolor, lop);
3559
200
    } else
3560
0
        code = 0;
3561
200
    gx_path_new(ppath);
3562
200
    return code;
3563
200
}