Coverage Report

Created: 2025-06-10 06:58

/src/ghostpdl/base/gxclrast.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2001-2025 Artifex Software, Inc.
2
   All Rights Reserved.
3
4
   This software is provided AS-IS with no warranty, either express or
5
   implied.
6
7
   This software is distributed under license and may not be copied,
8
   modified or distributed except as expressly authorized under the terms
9
   of the license contained in the file LICENSE in this distribution.
10
11
   Refer to licensing information at http://www.artifex.com or contact
12
   Artifex Software, Inc.,  39 Mesa Street, Suite 108A, San Francisco,
13
   CA 94129, USA, for further information.
14
*/
15
16
17
/* Command list interpreter/rasterizer */
18
#include "memory_.h"
19
#include "gx.h"
20
#include "gp.h"                 /* for gp_fmode_rb */
21
#include "gpcheck.h"
22
#include "gserrors.h"
23
#include "gscdefs.h"            /* for image type table */
24
#include "gsbitops.h"
25
#include "gsparams.h"
26
#include "gsstate.h"            /* (should only be gs_gstate) */
27
#include "gstrans.h"    /* for gs_is_pdf14trans_compositor */
28
#include "gxdcolor.h"
29
#include "gxdevice.h"
30
#include "gscoord.h"            /* requires gsmatrix.h */
31
#include "gsdevice.h"           /* for gs_deviceinitialmatrix */
32
#include "gsiparm4.h"
33
#include "gxdevmem.h"           /* must precede gxcldev.h */
34
#include "gxcldev.h"
35
#include "gxclpath.h"
36
#include "gxcmap.h"
37
#include "gxcolor2.h"
38
#include "gxcspace.h"           /* for gs_color_space_type */
39
#include "gxdhtres.h"
40
#include "gxgetbit.h"
41
#include "gxpaint.h"            /* for gx_fill/stroke_params */
42
#include "gxpcolor.h"
43
#include "gxhttile.h"
44
#include "gxiparam.h"
45
#include "gximask.h"
46
#include "gzpath.h"
47
#include "gzcpath.h"
48
#include "gzacpath.h"
49
#include "stream.h"
50
#include "strimpl.h"
51
#include "gxcomp.h"
52
#include "gsserial.h"
53
#include "gxdhtserial.h"
54
#include "gzht.h"
55
#include "gxshade.h"
56
#include "gxshade4.h"
57
#include "gsicc_manage.h"
58
#include "gsicc.h"
59
60
extern_gx_device_halftone_list();
61
extern_gx_image_type_table();
62
63
/* We need color space types for constructing temporary color spaces. */
64
extern const gs_color_space_type gs_color_space_type_Indexed;
65
66
/* Print a bitmap for tracing */
67
#ifdef DEBUG
68
static void
69
cmd_print_bits(gs_memory_t *mem, const byte * data, int width, int height, int raster)
70
{
71
    int i, j;
72
73
    dmlprintf3(mem, "[L]width=%d, height=%d, raster=%d\n",
74
              width, height, raster);
75
    for (i = 0; i < height; i++) {
76
        const byte *row = data + i * raster;
77
78
        dmlprintf(mem, "[L]");
79
        for (j = 0; j < raster; j++)
80
            dmprintf1(mem, " %02x", row[j]);
81
        dmputc(mem, '\n');
82
    }
83
}
84
#else
85
#  define cmd_print_bits(mem, data, width, height, raster) DO_NOTHING
86
#endif
87
88
/* Get a variable-length integer operand. */
89
#define cmd_getw(var, p)\
90
156M
  BEGIN\
91
156M
    if ( *p < 0x80 ) var = *p++;\
92
156M
    else { const byte *_cbp; var = cmd_get_w(p, &_cbp); p = _cbp; }\
93
156M
  END
94
95
static long
96
cmd_get_w(const byte * p, const byte ** rp)
97
128M
{
98
128M
    int val = *p++ & 0x7f;
99
128M
    int shift = 7;
100
101
248M
    for (; val |= (int)(*p & 0x7f) << shift, *p++ > 0x7f; shift += 7);
102
128M
    *rp = p;
103
128M
    return val;
104
128M
}
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
3.86M
{
144
3.86M
    pcb->end = end;
145
3.86M
    pcb->warn_limit = pcb->data + (pcb->size - cmd_largest_size + 1);
146
3.86M
    if ( pcb->warn_limit > pcb->end )
147
143k
        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
3.86M
}
151
152
static inline void
153
advance_buffer(command_buf_t *pcb, const byte *cbp)
154
3.72M
{
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
3.72M
    memmove(pcb->data, cbp, pcb->end - cbp);
161
3.72M
}
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
3.85M
{
177
3.85M
    uint nread;
178
3.85M
    const byte *cbp = *pcbp;
179
3.85M
    byte *cb_top = pcb->data + (pcb->end - cbp);
180
181
3.85M
    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
3.85M
    if (seofp(pcb->s)) {
187
        /* Can't use offset_map, because s_close resets s->state. Don't top up. */
188
128k
        pcb->end_status = pcb->s->end_status;
189
128k
        return 0;
190
128k
    }
191
3.72M
    advance_buffer(pcb, cbp);
192
3.72M
    nread = pcb->end - cb_top;
193
3.72M
    pcb->end_status = sgets(pcb->s, cb_top, nread, &nread);
194
3.72M
    if ( nread == 0 ) {
195
        /* No data for this band at all. */
196
0
        if (cb_top >= pcb->end) {
197
            /* should not happen */
198
0
            *pcbp = pcb->data;
199
0
            pcb->data[0] = cmd_opv_end_run;
200
0
            return_error(gs_error_ioerror);
201
0
        }
202
0
        *cb_top = cmd_opv_end_run;
203
0
        nread = 1;
204
0
    }
205
3.72M
    set_cb_end(pcb, cb_top + nread);
206
3.72M
    process_interrupts(pcb->s->memory);
207
3.72M
    *pcbp = pcb->data;
208
3.72M
    return 0;
209
3.72M
}
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
1.34M
{
217
1.34M
    if (pcb->end - cbp >= rsize) {
218
1.34M
        memmove(ptr, cbp, rsize);
219
1.34M
        return cbp + rsize;
220
1.34M
    } else {
221
221
        uint cleft = pcb->end - cbp;
222
221
        uint rleft = rsize - cleft;
223
224
221
        memmove(ptr, cbp, cleft);
225
221
        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
221
        return pcb->end;
234
221
    }
235
1.34M
}
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
256k
{
241
256k
    memcpy(pvar, cbp, var_size);
242
256k
    return cbp + var_size;
243
256k
}
244
#define cmd_get_value(var, cbp)\
245
256k
  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
2.23M
{
304
2.23M
    if (*ppcomp_last == NULL) {
305
578k
        pcomp->prev = pcomp->next = NULL;
306
578k
        *ppcomp_last = *ppcomp_first = pcomp;
307
1.65M
    } else {
308
1.65M
        (*ppcomp_last)->next = pcomp;
309
1.65M
        pcomp->prev = *ppcomp_last;
310
1.65M
        pcomp->next = NULL;
311
1.65M
        *ppcomp_last = pcomp;
312
1.65M
    }
313
2.23M
}
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
2.23M
{
350
2.23M
    if (*ppcomp_last == *ppcomp_first) {
351
578k
        if (*ppcomp_last == pcomp) {
352
578k
            *ppcomp_last = *ppcomp_first = NULL;
353
578k
            return 0;
354
578k
        } else
355
0
            return_error(gs_error_unregistered); /* Must not happen. */
356
1.65M
    } else {
357
1.65M
        gs_composite_t *pcomp_next = pcomp->next, *pcomp_prev = pcomp->prev;
358
359
1.65M
        if (*ppcomp_last == pcomp)
360
518k
            *ppcomp_last = pcomp->prev;
361
1.13M
        else
362
1.13M
            pcomp_next->prev = pcomp_prev;
363
1.65M
        if (*ppcomp_first == pcomp)
364
1.13M
            *ppcomp_first = pcomp->next;
365
518k
        else
366
518k
            pcomp_prev->next = pcomp_next;
367
1.65M
        pcomp->next = pcomp->prev = NULL;
368
1.65M
        return 0;
369
1.65M
    }
370
2.23M
}
371
372
static inline void
373
free_compositor(gs_composite_t *pcomp, gs_memory_t *mem)
374
784k
{
375
784k
    gs_free_object(mem, pcomp, "free_compositor");
376
784k
}
377
378
static inline bool
379
is_null_compositor_op(const byte *cbp, int *length)
380
1.74M
{
381
1.74M
    if (cbp[0] == cmd_opv_end_run) {
382
1.29M
        *length = 1;
383
1.29M
        return true;
384
1.29M
    }
385
453k
    return false;
386
1.74M
}
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
347k
{
393
1.79M
    while (pcomp_from != NULL) {
394
1.44M
        gs_composite_t *pcomp = pcomp_from;
395
1.44M
        int code;
396
397
1.44M
        pcomp_from = pcomp->next;
398
1.44M
        code = dequeue_compositor(ppcomp_first, ppcomp_last, pcomp);
399
1.44M
        if (code < 0)
400
0
            return code;
401
1.44M
        pcomp->idle |= idle;
402
1.44M
        code = apply_composite(cdev, pgs, mem, pcomp, x0, y0, target); /* Releases the compositor. */
403
1.44M
        if (code < 0)
404
0
            return code;
405
1.44M
        *tdev = *target;
406
1.44M
    }
407
347k
    return 0;
408
347k
}
409
410
static void
411
mark_as_idle(gs_composite_t *pcomp_start, gs_composite_t *pcomp_end)
412
102k
{
413
102k
    gs_composite_t *pcomp = pcomp_start;
414
415
224k
    while (pcomp != NULL) {
416
224k
        pcomp->idle = true;
417
224k
        if (pcomp == pcomp_end)
418
102k
            break;
419
121k
        pcomp = pcomp->next;
420
121k
    }
421
102k
}
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
15.5k
{
428
15.5k
    gs_composite_t *pcomp;
429
430
86.2k
    do {
431
86.2k
        int code;
432
433
86.2k
        pcomp = *ppcomp_last;
434
86.2k
        if (pcomp == NULL)
435
0
            return 0;
436
86.2k
        dequeue_compositor(ppcomp_first, ppcomp_last, *ppcomp_last);
437
86.2k
        code = pcomp->type->procs.adjust_ctm(pcomp, x0, y0, pgs);
438
86.2k
        if (code < 0)
439
0
            return code;
440
86.2k
        free_compositor(pcomp, mem);
441
86.2k
    } while (pcomp != pcomp_from);
442
15.5k
    return 0;
443
15.5k
}
444
445
static int
446
read_set_misc_map(byte cb, command_buf_t *pcb, gs_gstate *pgs, gs_memory_t *mem)
447
356k
{
448
356k
    const byte *cbp = pcb->ptr;
449
356k
    frac *mdata;
450
356k
    int *pcomp_num;
451
356k
    uint count = 0;   /* quiet compiler */
452
356k
    cmd_map_contents cont =
453
356k
        (cmd_map_contents)(cb & 0x30) >> 4;
454
356k
    int code;
455
456
356k
    code = cmd_select_map(cb & 0xf, cont,
457
356k
                          pgs,
458
356k
                          &pcomp_num,
459
356k
                          &mdata, &count, mem);
460
461
356k
    if (code < 0)
462
0
        return code;
463
    /* Get component number if relevant */
464
356k
    if (pcomp_num == NULL)
465
356k
        cbp++;
466
36
    else {
467
36
        *pcomp_num = (int) *cbp++;
468
36
        if_debug1m('L', mem, " comp_num=%d", *pcomp_num);
469
36
    }
470
356k
    if (cont == cmd_map_other) {
471
356k
        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
356k
    }
485
    /* Recompute the effective transfer, */
486
    /* in case this was a transfer map. */
487
356k
    gx_gstate_set_effective_xfer(pgs);
488
356k
    pcb->ptr = cbp;
489
356k
    return 0;
490
356k
}
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
144k
{
516
144k
    byte *cbuf_storage;
517
144k
    command_buf_t cbuf;
518
    /* data_bits is for short copy_* bits and copy_* compressed, */
519
    /* must be aligned */
520
144k
    byte *data_bits = 0;
521
144k
    const byte *cbp;
522
144k
    int dev_depth;              /* May vary due to compositing devices */
523
144k
    int dev_depth_bytes;
524
144k
    int odd_delta_shift;
525
144k
    int num_zero_bytes;
526
144k
    gx_device *tdev;
527
144k
    gx_clist_state state;
528
144k
    gx_color_index *set_colors;
529
144k
    gx_device_color *set_dev_colors;
530
144k
    tile_slot *state_slot;
531
144k
    gx_strip_bitmap state_tile; /* parameters for reading tiles */
532
144k
    tile_slot tile_bits;        /* parameters of current tile */
533
144k
    gs_int_point tile_phase;
534
144k
    gx_path path;
535
144k
    bool in_path;
536
144k
    gs_fixed_point ppos;
537
144k
    gx_clip_path clip_path;
538
144k
    bool use_clip;
539
144k
    gx_clip_path *pcpath;
540
144k
    gx_device_cpath_accum clip_accum;
541
144k
    gs_fixed_rect target_box;
542
144k
    struct _cas {
543
144k
        bool lop_enabled;
544
144k
        gx_device_color dcolor;
545
144k
        gs_fixed_point fa_save;
546
144k
    } clip_save;
547
144k
    bool in_clip = false;
548
144k
    gs_gstate gs_gstate;
549
144k
    gx_device_color fill_color = { 0 };
550
144k
    gx_device_color stroke_color = { 0 };
551
144k
    float dash_pattern[cmd_max_dash];
552
144k
    gx_fill_params fill_params;
553
144k
    gx_stroke_params stroke_params;
554
#ifdef DEBUG
555
    gs_halftone_type halftone_type;
556
#endif
557
144k
    union im_ {
558
144k
        gs_image_common_t c;
559
144k
        gs_data_image_t d;
560
144k
        gs_image1_t i1;
561
144k
        gs_image4_t i4;
562
144k
    } image;
563
144k
    gs_int_rect image_rect;
564
144k
    gs_color_space *pcs = NULL;
565
144k
    gx_image_enum_common_t *image_info;
566
144k
    gx_image_plane_t planes[32];
567
144k
    uint data_height;
568
144k
    uint data_size;
569
144k
    byte *data_on_heap;
570
144k
    fixed vs[6];
571
144k
    segment_notes notes;
572
144k
    int data_x;
573
144k
    int code = 0;
574
144k
    ht_buff_t  ht_buff;
575
144k
    gx_device *const orig_target = target;
576
144k
    gx_device_clip clipper_dev;
577
144k
    bool clipper_dev_open = false;
578
144k
    patch_fill_state_t pfs;
579
144k
    int op = 0;
580
144k
    int plane_height = 0;
581
582
#ifdef DEBUG
583
    stream_state *st = s->state; /* Save because s_close resets s->state. */
584
#endif
585
144k
    gs_composite_t *pcomp_first = NULL, *pcomp_last = NULL;
586
144k
    tile_slot bits;             /* parameters for reading bits */
587
588
    /* pad the cbuf data area a bit (just in case) */
589
144k
    if ((cbuf_storage = gs_alloc_bytes(mem, cbuf_size + sizeof(double),
590
144k
                               "clist_playback_band(cbuf_storage)")) == NULL) {
591
0
        return_error(gs_error_VMerror);
592
0
    }
593
144k
    cbuf.data = (byte *)cbuf_storage;
594
144k
    cbuf.size = cbuf_size;
595
144k
    cbuf.s = s;
596
144k
    cbuf.end_status = 0;
597
144k
    set_cb_end(&cbuf, cbuf.data + cbuf.size);
598
144k
    cbp = cbuf.end;
599
600
144k
    pfs.dev = NULL; /* Indicate "not initialized". */
601
144k
    memset(&ht_buff, 0, sizeof(ht_buff));
602
603
    /* The following initializations are to quiet gcc warnings. */
604
144k
    memset(&bits, 0, sizeof(bits));
605
144k
    memset(&tile_bits, 0, sizeof(tile_bits));
606
144k
    memset(&clip_save, 0, sizeof(clip_save));
607
144k
    memset(&state_slot, 0, sizeof(state_slot));
608
144k
    ppos.x = ppos.y = 0;
609
610
144k
in:                             /* Initialize for a new page. */
611
144k
    tdev = target;
612
144k
    set_colors = state.colors;
613
144k
    set_dev_colors = state.tile_color_devn;
614
144k
    use_clip = false;
615
144k
    pcpath = NULL;
616
144k
    if (clipper_dev_open)
617
0
        gx_destroy_clip_device_on_stack(&clipper_dev);
618
144k
    clipper_dev_open = false;
619
144k
    notes = sn_none;
620
144k
    data_x = 0;
621
144k
    {
622
144k
        static const gx_clist_state cls_initial = { cls_initial_values };
623
624
144k
        state = cls_initial;
625
144k
    }
626
144k
    state_tile.id = gx_no_bitmap_id;
627
144k
    state_tile.shift = state_tile.rep_shift = 0;
628
144k
    state_tile.size.x = state_tile.size.y = 0;
629
144k
    state_tile.num_planes = 1;
630
144k
    tile_phase.x = x0;
631
144k
    tile_phase.y = y0;
632
144k
    gx_path_init_local(&path, mem);
633
144k
    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
144k
    {
639
144k
        gs_fixed_rect cbox;
640
641
144k
        gx_cpath_init_local(&clip_path, mem);
642
144k
        cbox.p.x = 0;
643
144k
        cbox.p.y = 0;
644
144k
        cbox.q.x = cdev->width;
645
144k
        cbox.q.y = cdev->height;
646
144k
        gx_cpath_from_rectangle(&clip_path, &cbox);
647
144k
    }
648
144k
    if (target != 0)
649
144k
        (*dev_proc(target, get_clipping_box))(target, &target_box);
650
144k
    memset(&gs_gstate, 0, sizeof(gs_gstate));
651
144k
    GS_STATE_INIT_VALUES_CLIST((&gs_gstate));
652
144k
    code = gs_gstate_initialize(&gs_gstate, mem);
653
144k
    if (code < 0)
654
0
        goto out;
655
144k
    gs_gstate.device = tdev;
656
144k
    gs_gstate.view_clip = NULL; /* Avoid issues in pdf14 fill stroke */
657
144k
    gs_gstate.clip_path = &clip_path;
658
144k
    pcs = gs_cspace_new_DeviceGray(mem);
659
144k
    if (pcs == NULL) {
660
0
        code = gs_note_error(gs_error_VMerror);
661
0
        goto out;
662
0
    }
663
144k
    code = pcs->type->install_cspace(pcs, &gs_gstate);
664
144k
    if (code < 0) {
665
0
        rc_decrement(pcs, "clist_playback_band");
666
0
        goto out;
667
0
    }
668
144k
    gs_gstate.color[0].color_space = pcs; /* we already have one ref */
669
144k
    gs_gstate.color[1].color_space = pcs;
670
144k
    rc_increment_cs(pcs); /* increment for second ref */
671
    /* Initialize client color and device color */
672
144k
    gs_gstate.color[0].ccolor =
673
144k
        gs_alloc_struct(mem, gs_client_color, &st_client_color, "clist_playback_band");
674
144k
    gs_gstate.color[1].ccolor =
675
144k
        gs_alloc_struct(mem, gs_client_color, &st_client_color, "clist_playback_band");
676
144k
    gs_gstate.color[0].dev_color =
677
144k
        gs_alloc_struct(mem, gx_device_color, &st_device_color, "clist_playback_band");
678
144k
    gs_gstate.color[1].dev_color =
679
144k
        gs_alloc_struct(mem, gx_device_color, &st_device_color, "clist_playback_band");
680
144k
    if (gs_gstate.color[0].ccolor == 0 || gs_gstate.color[0].dev_color == 0 ||
681
144k
        gs_gstate.color[1].ccolor == 0 || gs_gstate.color[1].dev_color == 0
682
144k
        ) {
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
144k
    gs_gstate.color[0].color_space->pclient_color_space_data =
692
144k
        pcs->pclient_color_space_data;
693
144k
    cs_full_init_color(gs_gstate.color[0].ccolor, pcs);
694
144k
    gx_unset_dev_color(&gs_gstate);
695
696
144k
    gs_gstate.color[1].color_space->pclient_color_space_data =
697
144k
        pcs->pclient_color_space_data;
698
144k
    cs_full_init_color(gs_gstate.color[1].ccolor, pcs);
699
144k
    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
144k
    rc_decrement(gs_gstate.icc_link_cache,"clist_playback_band");
704
144k
    gs_gstate.icc_link_cache = cdev->icc_cache_cl;
705
    /* Need to lock during the increment of the link cache */
706
144k
    gx_monitor_enter(cdev->icc_cache_cl->lock);
707
144k
    rc_increment(cdev->icc_cache_cl);
708
144k
    gx_monitor_leave(cdev->icc_cache_cl->lock); /* let everyone run */
709
144k
    if (code < 0)
710
0
        goto out;
711
712
144k
    gs_gstate.line_params.dash.pattern = dash_pattern;
713
144k
    if (tdev != 0) {
714
144k
        gx_set_cmap_procs(&gs_gstate, tdev);
715
144k
    }
716
144k
    gx_gstate_setscreenphase(&gs_gstate, -x0, -y0, gs_color_select_all);
717
#ifdef DEBUG
718
    halftone_type = ht_type_none;
719
#endif
720
144k
    fill_color.ccolor_valid = false;
721
144k
    color_unset(&fill_color);
722
144k
    data_bits = gs_alloc_bytes(mem, data_bits_size,
723
144k
                               "clist_playback_band(data_bits)");
724
144k
    if (data_bits == 0) {
725
0
        code = gs_note_error(gs_error_VMerror);
726
0
        goto out;
727
0
    }
728
48.5M
    while (code >= 0) {
729
48.5M
        int compress;
730
48.5M
        int depth = 0x7badf00d; /* Initialize against indeterminizm. */
731
48.5M
        int raster = 0x7badf00d; /* Initialize against indeterminizm. */
732
48.5M
        byte *source = NULL;  /* Initialize against indeterminizm. */
733
48.5M
        gx_color_index colors[2];
734
48.5M
        gx_color_index *pcolor;
735
48.5M
        gx_device_color *pdcolor = NULL;
736
48.5M
        gs_logical_operation_t log_op;
737
738
        /* Make sure the buffer contains a full command. */
739
48.5M
        if (cbp >= cbuf.warn_limit) {
740
370k
            if (cbuf.end_status < 0) {  /* End of file or error. */
741
403
                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
369k
            } else {
747
369k
                code = top_up_cbuf(&cbuf, &cbp);
748
369k
                if (code < 0)
749
0
                    goto top_up_failed;
750
369k
            }
751
370k
        }
752
48.5M
        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
48.5M
        switch (op >> 4) {
762
1.22M
            case cmd_op_misc >> 4:
763
1.22M
                switch (op) {
764
416k
                    case cmd_opv_end_run:
765
416k
                        if_debug0m('L', mem, "\n");
766
416k
                        continue;
767
762
                    case cmd_opv_set_tile_size:
768
762
                        cbuf.ptr = cbp;
769
762
                        code = read_set_tile_size(&cbuf, &tile_bits,
770
762
                                    gx_device_is_pattern_clist((gx_device *)cdev));
771
762
                        cbp = cbuf.ptr;
772
762
                        if (code < 0)
773
0
                            goto out;
774
762
                        continue;
775
762
                    case cmd_opv_set_tile_phase:
776
40
                        cmd_getw(state.tile_phase.x, cbp);
777
40
                        cmd_getw(state.tile_phase.y, cbp);
778
40
                        if_debug2m('L', mem, " (%d,%d)\n",
779
40
                                   state.tile_phase.x,
780
40
                                   state.tile_phase.y);
781
40
                        goto set_tile_phase;
782
6.29k
                    case cmd_opv_set_screen_phaseT:
783
6.29k
                        cmd_getw(state.screen_phase[gs_color_select_texture].x, cbp);
784
6.29k
                        cmd_getw(state.screen_phase[gs_color_select_texture].y, cbp);
785
6.29k
                        if_debug2m('L', mem, " (%d,%d)\n",
786
6.29k
                                   state.screen_phase[0].x,
787
6.29k
                                   state.screen_phase[gs_color_select_texture].y);
788
6.29k
                        gx_gstate_setscreenphase(&gs_gstate,
789
6.29k
                                                 state.screen_phase[gs_color_select_texture].x - x0,
790
6.29k
                                                 state.screen_phase[gs_color_select_texture].y - y0,
791
6.29k
                                                 gs_color_select_texture);
792
6.29k
                        continue;
793
0
                    case cmd_opv_set_screen_phaseS:
794
0
                        cmd_getw(state.screen_phase[gs_color_select_source].x, cbp);
795
0
                        cmd_getw(state.screen_phase[gs_color_select_source].y, cbp);
796
0
                        if_debug2m('L', mem, " (%d,%d)\n",
797
0
                                   state.screen_phase[gs_color_select_source].x,
798
0
                                   state.screen_phase[gs_color_select_source].y);
799
0
                        gx_gstate_setscreenphase(&gs_gstate,
800
0
                                                 state.screen_phase[gs_color_select_source].x - x0,
801
0
                                                 state.screen_phase[gs_color_select_source].y - y0,
802
0
                                                 gs_color_select_source);
803
0
                        continue;
804
2.99k
                    case cmd_opv_set_tile_bits:
805
2.99k
                        bits = tile_bits;
806
2.99k
                        compress = 0;
807
208k
                      stb:
808
208k
                        cbuf.ptr = cbp;
809
208k
                        code = read_set_bits(&cbuf, &bits, compress,
810
208k
                                             &state, &state_tile, &state_slot,
811
208k
                                             cdev, mem);
812
208k
                        cbp = cbuf.ptr;
813
208k
                        if (code < 0)
814
0
                            goto out;
815
208k
                        goto stp;
816
208k
                    case cmd_opv_set_bits:
817
205k
do_opv_set_bits:
818
205k
                        compress = *cbp & 3;
819
205k
                        bits.head.depth = *cbp++ >> 2;
820
205k
                        cmd_getw(bits.width, cbp);
821
205k
                        cmd_getw(bits.height, cbp);
822
205k
                        if (op == cmd_opv_set_bits_planar)
823
205k
                            cmd_getw(bits.num_planes, cbp);
824
205k
                        else
825
205k
                            bits.num_planes = 1;
826
205k
                        if_debug5m('L', mem, " compress=%d depth=%d size=(%d,%d) planes=%d",
827
205k
                                   compress, bits.head.depth,
828
205k
                                   bits.width, bits.height, bits.num_planes);
829
205k
                        bits.raster =
830
205k
                            bitmap_raster(bits.width * bits.head.depth);
831
205k
                        bits.x_reps = bits.y_reps = 1;
832
205k
                        bits.shift = bits.rep_shift = 0;
833
205k
                        goto stb;
834
37.1k
                    case cmd_opv_set_tile_color:
835
37.1k
                        set_colors = state.tile_colors;
836
37.1k
                        if_debug0m('L', mem, "\n");
837
37.1k
                        continue;
838
397k
                    case cmd_opv_set_misc:
839
397k
                        {
840
397k
                            uint cb = *cbp++;
841
842
397k
                            switch (cb >> 6) {
843
34.7k
                                case cmd_set_misc_lop >> 6:
844
34.7k
                                    cmd_getw(state.lop, cbp);
845
34.7k
                                    state.lop = (state.lop << 6) + (cb & 0x3f);
846
34.7k
                                    if_debug1m('L', mem, " lop=0x%x\n", state.lop);
847
34.7k
                                    if (state.lop_enabled)
848
26.4k
                                        gs_gstate.log_op = state.lop;
849
34.7k
                                    break;
850
67.2k
                                case cmd_set_misc_data_x >> 6:
851
67.2k
                                    if (cb & 0x20)
852
67.2k
                                        cmd_getw(data_x, cbp);
853
67.2k
                                    else
854
67.2k
                                        data_x = 0;
855
67.2k
                                    data_x = (data_x << 5) + (cb & 0x1f);
856
67.2k
                                    if_debug1m('L', mem, " data_x=%d\n", data_x);
857
67.2k
                                    break;
858
295k
                                case cmd_set_misc_map >> 6:
859
295k
                                    cbuf.ptr = cbp;
860
295k
                                    code = read_set_misc_map(cb, &cbuf, &gs_gstate, mem);
861
295k
                                    if (code < 0)
862
0
                                        goto out;
863
295k
                                    cbp = cbuf.ptr;
864
295k
                                    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
397k
                            }
885
397k
                        }
886
397k
                        continue;
887
397k
                    case cmd_opv_enable_lop:
888
8.28k
                        state.lop_enabled = true;
889
8.28k
                        gs_gstate.log_op = state.lop;
890
8.28k
                        if_debug0m('L', mem, "\n");
891
8.28k
                        continue;
892
3.82k
                    case cmd_opv_disable_lop:
893
3.82k
                        state.lop_enabled = false;
894
3.82k
                        gs_gstate.log_op = lop_default;
895
3.82k
                        if_debug0m('L', mem, "\n");
896
3.82k
                        continue;
897
144k
                    case cmd_opv_end_page:
898
144k
                        if_debug0m('L', mem, "\n");
899
                        /*
900
                         * Do end-of-page cleanup, then reinitialize if
901
                         * there are more pages to come.
902
                         */
903
144k
                        goto out;
904
0
                    case cmd_opv_delta_color0:
905
0
                        pcolor = &set_colors[0];
906
0
                        goto delta2_c;
907
0
                    case cmd_opv_delta_color1:
908
0
                        pcolor = &set_colors[1];
909
0
                      delta2_c:set_colors = state.colors;
910
                        /* See comments for cmd_put_color() in gxclutil.c. */
911
0
                        {
912
0
                            gx_color_index delta = 0;
913
0
                            uint data;
914
915
0
                            dev_depth = (tdev->color_info.depth <= 8*sizeof(gx_color_index) ?
916
0
                                         tdev->color_info.depth : 8*sizeof(gx_color_index));
917
0
                            dev_depth_bytes = (dev_depth + 7) >> 3;
918
0
                            switch (dev_depth_bytes) {
919
                                /* For cases with an even number of bytes */
920
0
                                case 8:
921
0
                                    data = *cbp++;
922
0
                                    delta = (((gx_color_index)
923
0
                                        ((data & 0xf0) << 4) + (data & 0x0f)) << 24) << 24;
924
                                    /* fall through */
925
0
                                case 6:
926
0
                                    data = *cbp++;
927
0
                                    delta |= (((gx_color_index)
928
0
                                        ((data & 0xf0) << 4) + (data & 0x0f)) << 16) << 16;
929
                                    /* fall through */
930
0
                                case 4:
931
0
                                    data = *cbp++;
932
0
                                    delta |= ((gx_color_index)
933
0
                                        ((data & 0xf0) << 4) + (data & 0x0f)) << 16;
934
                                    /* fall through */
935
0
                                case 2:
936
0
                                    data = *cbp++;
937
0
                                    delta |= ((gx_color_index)
938
0
                                        ((data & 0xf0) << 4) + (data & 0x0f));
939
0
                                    break;
940
                                /* For cases with an odd number of bytes */
941
0
                                case 7:
942
0
                                    data = *cbp++;
943
0
                                    delta = ((gx_color_index)
944
0
                                        ((data & 0xf0) << 4) + (data & 0x0f)) << 16;
945
                                    /* fall through */
946
0
                                case 5:
947
0
                                    data = *cbp++;
948
0
                                    delta |= ((gx_color_index)
949
0
                                        ((data & 0xf0) << 4) + (data & 0x0f));
950
                                    /* fall through */
951
0
                                case 3:
952
0
                                    data = *cbp++;
953
0
                                    odd_delta_shift = (dev_depth_bytes - 3) * 8;
954
0
                                    delta |= ((gx_color_index)
955
0
                                        ((data & 0xe0) << 3) + (data & 0x1f)) << odd_delta_shift;
956
0
                                    data = *cbp++;
957
0
                                    delta |= ((gx_color_index) ((data & 0xf8) << 2) + (data & 0x07))
958
0
                                                        << (odd_delta_shift + 11);
959
0
                            }
960
0
                            *pcolor += delta - cmd_delta_offsets[dev_depth_bytes];
961
0
                        }
962
0
                        if (sizeof(*pcolor) <= sizeof(ulong))
963
0
                            if_debug1m('L', mem, " 0x%lx\n", (ulong)*pcolor);
964
0
                        else
965
0
                            if_debug2m('L', mem, " 0x%8lx%08lx\n",
966
0
                                       (ulong)(*pcolor >> 8*(sizeof(*pcolor) - sizeof(ulong))), (ulong)*pcolor);
967
0
                        continue;
968
0
                    case cmd_opv_set_copy_color:
969
0
                        state.color_is_alpha = 0;
970
0
                        if_debug0m('L', mem, "\n");
971
0
                        continue;
972
0
                    case cmd_opv_set_copy_alpha:
973
0
                        state.color_is_alpha = 1;
974
0
                        if_debug0m('L', mem, "\n");
975
0
                        continue;
976
0
                    default:
977
0
                        goto bad_op;
978
1.22M
                }
979
                /*NOTREACHED */
980
22.0k
            case cmd_op_set_color0 >> 4:
981
22.0k
                pcolor = &set_colors[0];
982
22.0k
                goto set_color;
983
18.5k
            case cmd_op_set_color1 >> 4:
984
18.5k
                pcolor = &set_colors[1];
985
40.5k
              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
40.5k
                num_zero_bytes = op & 0x0f;
994
995
40.5k
                if (num_zero_bytes == cmd_no_color_index)
996
0
                    *pcolor = gx_no_color_index;
997
40.5k
                else {
998
40.5k
                    gx_color_index color = 0;
999
1000
40.5k
                    dev_depth = (tdev->color_info.depth < 8*sizeof(gx_color_index) ?
1001
40.5k
                                 tdev->color_info.depth : 8*sizeof(gx_color_index));
1002
40.5k
                    dev_depth_bytes = (dev_depth + 7) >> 3;
1003
40.5k
                    switch (dev_depth_bytes - num_zero_bytes) {
1004
0
                        case 8:
1005
0
                            color = (gx_color_index) * cbp++;
1006
0
                        case 7:
1007
0
                            color = (color << 8) | (gx_color_index) * cbp++;
1008
0
                        case 6:
1009
0
                            color = (color << 8) | (gx_color_index) * cbp++;
1010
0
                        case 5:
1011
0
                            color = (color << 8) | (gx_color_index) * cbp++;
1012
0
                        case 4:
1013
0
                            color = (color << 8) | (gx_color_index) * cbp++;
1014
0
                        case 3:
1015
0
                            color = (color << 8) | (gx_color_index) * cbp++;
1016
0
                        case 2:
1017
0
                            color = (color << 8) | (gx_color_index) * cbp++;
1018
32.1k
                        case 1:
1019
32.1k
                            color = (color << 8) | (gx_color_index) * cbp++;
1020
40.5k
                        default:
1021
40.5k
                            break;
1022
40.5k
                    }
1023
40.5k
                    color <<= num_zero_bytes * 8;
1024
40.5k
                    *pcolor = color;
1025
40.5k
                }
1026
40.5k
                if (sizeof(*pcolor) <= sizeof(ulong))
1027
40.5k
                    if_debug1m('L', mem, " 0x%lx\n", (ulong)*pcolor);
1028
0
                else
1029
40.5k
                    if_debug2m('L', mem, " 0x%8lx%08lx\n",
1030
40.5k
                               (ulong)(*pcolor >> 8*(sizeof(*pcolor) - sizeof(ulong))), (ulong)*pcolor);
1031
40.5k
                continue;
1032
224k
            case cmd_op_fill_rect >> 4:
1033
239k
            case cmd_op_tile_rect >> 4:
1034
239k
                cbp = cmd_read_rect(op, &state.rect, cbp);
1035
239k
                break;
1036
33.9k
            case cmd_op_fill_rect_short >> 4:
1037
89.4k
            case cmd_op_tile_rect_short >> 4:
1038
89.4k
                state.rect.x += *cbp + cmd_min_short;
1039
89.4k
                state.rect.width += cbp[1] + cmd_min_short;
1040
89.4k
                if (op & 0xf) {
1041
62.9k
                    state.rect.height += (op & 0xf) + cmd_min_dxy_tiny;
1042
62.9k
                    cbp += 2;
1043
62.9k
                } else {
1044
26.4k
                    state.rect.y += cbp[2] + cmd_min_short;
1045
26.4k
                    state.rect.height += cbp[3] + cmd_min_short;
1046
26.4k
                    cbp += 4;
1047
26.4k
                }
1048
89.4k
                break;
1049
492k
            case cmd_op_fill_rect_tiny >> 4:
1050
574k
            case cmd_op_tile_rect_tiny >> 4:
1051
574k
                if (op & 8)
1052
80.7k
                    state.rect.x += state.rect.width;
1053
493k
                else {
1054
493k
                    int txy = *cbp++;
1055
1056
493k
                    state.rect.x += (txy >> 4) + cmd_min_dxy_tiny;
1057
493k
                    state.rect.y += (txy & 0xf) + cmd_min_dxy_tiny;
1058
493k
                }
1059
574k
                state.rect.width += (op & 7) + cmd_min_dw_tiny;
1060
574k
                break;
1061
665k
            case cmd_op_copy_mono_planes >> 4:
1062
665k
                cmd_getw(plane_height, cbp);
1063
665k
                if (plane_height == 0) {
1064
                    /* We are doing a copy mono */
1065
659k
                    depth = 1;
1066
659k
                } else {
1067
6.81k
                    depth = tdev->color_info.depth;
1068
6.81k
                }
1069
665k
                if_debug1m('L', mem, " plane_height=0x%x", plane_height);
1070
665k
                goto copy;
1071
796k
            case cmd_op_copy_color_alpha >> 4:
1072
796k
                if (state.color_is_alpha) {
1073
0
                    if (!(op & 8))
1074
0
                        depth = *cbp++;
1075
0
                } else
1076
796k
                    depth = tdev->color_info.depth;
1077
796k
                plane_height = 0;
1078
1.46M
              copy:cmd_getw(state.rect.x, cbp);
1079
1.46M
                cmd_getw(state.rect.y, cbp);
1080
1.46M
                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
649k
                    depth = state_slot->head.depth;
1091
649k
                    state.rect.width = state_slot->width;
1092
649k
                    state.rect.height = state_slot->height;
1093
649k
                    if (state.rect.y + state.rect.height > cdev->height)
1094
380
                        state.rect.height = cdev->height - state.rect.y; /* clamp as writer did */
1095
649k
                    raster = state_slot->raster;
1096
649k
                    source = (byte *) (state_slot + 1);
1097
813k
                } else {        /* Read width, height, bits. */
1098
                    /* depth was set already. */
1099
813k
                    uint width_bits, width_bytes;
1100
813k
                    uint bytes;
1101
813k
                    uchar planes = 1;
1102
813k
                    uint plane_depth = depth;
1103
813k
                    uint pln;
1104
813k
                    byte compression = op & 3;
1105
813k
                    uint out_bytes;
1106
1107
813k
                    cmd_getw(state.rect.width, cbp);
1108
813k
                    cmd_getw(state.rect.height, cbp);
1109
813k
                    if (plane_height != 0) {
1110
6.81k
                        planes = tdev->color_info.num_components;
1111
6.81k
                        plane_depth /= planes;
1112
6.81k
                    }
1113
813k
                    width_bits = state.rect.width * plane_depth;
1114
813k
                    bytes = clist_bitmap_bytes(width_bits,
1115
813k
                                               state.rect.height,
1116
813k
                                               op & 3, &width_bytes,
1117
813k
                                               (uint *)&raster);
1118
813k
                    if (planes > 1) {
1119
6.81k
                        out_bytes = raster * state.rect.height;
1120
6.81k
                        plane_height = state.rect.height;
1121
806k
                    } else {
1122
806k
                        out_bytes = bytes;
1123
806k
                    }
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
1.64M
                    for (pln = 0; pln < planes; pln++) {
1139
833k
                        byte *plane_bits = data_bits + pln * plane_height * raster;
1140
1141
                        /* Fill the cbuf if needed to get the data for the plane */
1142
833k
                        if (cbp + out_bytes >= cbuf.warn_limit) {
1143
7.01k
                            code = top_up_cbuf(&cbuf, &cbp);
1144
7.01k
                            if (code < 0)
1145
0
                                goto top_up_failed;
1146
7.01k
                        }
1147
833k
                        if (pln)
1148
20.4k
                            compression = *cbp++;
1149
1150
833k
                        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
833k
                        } 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
833k
                        } else if ((state.rect.height > 1 && width_bytes != raster) ||
1210
833k
                                   (plane_height != 0)) {
1211
39.6k
                            cbp = cmd_read_short_bits(&cbuf, plane_bits, bytes, width_bytes,
1212
39.6k
                                                      state.rect.height, raster, cbp);
1213
39.6k
                            if (pln == 0)
1214
19.1k
                                source = data_bits;
1215
794k
                        } else {
1216
                            /* Never used for planar data */
1217
794k
                            cbp = cmd_read_data(&cbuf, cbuf.data, bytes, cbp);
1218
794k
                            source = cbuf.data;
1219
794k
                        }
1220
833k
                    }
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
813k
                }
1230
1.46M
                break;
1231
1.46M
            case cmd_op_delta_tile_index >> 4:
1232
177k
                state.tile_index += (int)(op & 0xf) - 8;
1233
177k
                goto sti;
1234
270k
            case cmd_op_set_tile_index >> 4:
1235
270k
                state.tile_index =
1236
270k
                    ((op & 0xf) << 8) + *cbp++;
1237
447k
              sti:state_slot =
1238
447k
                    (tile_slot *) (cdev->cache_chunk->data +
1239
447k
                                 cdev->tile_table[state.tile_index].offset);
1240
447k
                if_debug2m('L', mem, " index=%u offset=%lu\n",
1241
447k
                           state.tile_index,
1242
447k
                           cdev->tile_table[state.tile_index].offset);
1243
447k
                state_tile.data = (byte *) (state_slot + 1);
1244
656k
              stp:state_tile.size.x = state_slot->width;
1245
656k
                state_tile.size.y = state_slot->height;
1246
656k
                state_tile.raster = state_slot->raster;
1247
656k
                state_tile.rep_width = state_tile.size.x /
1248
656k
                    state_slot->x_reps;
1249
656k
                state_tile.rep_height = state_tile.size.y /
1250
656k
                    state_slot->y_reps;
1251
656k
                state_tile.rep_shift = state_slot->rep_shift;
1252
656k
                state_tile.shift = state_slot->shift;
1253
656k
                state_tile.id = state_slot->id;
1254
656k
                state_tile.num_planes = state_slot->num_planes;
1255
656k
set_tile_phase:
1256
656k
                if (state_tile.size.x)
1257
656k
                    tile_phase.x =
1258
656k
                        (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
656k
                if (state_tile.size.y) {
1264
656k
                    int full_height;
1265
1266
656k
                    if (state_tile.shift == 0)
1267
656k
                        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
656k
                    tile_phase.y = (state.tile_phase.y + y0) % full_height;
1274
656k
                }
1275
656k
                continue;
1276
14.7M
            case cmd_op_misc2 >> 4:
1277
14.7M
                switch (op) {
1278
0
                    case cmd_opv_set_bits_planar:
1279
0
                        goto do_opv_set_bits;
1280
68.1k
                    case cmd_opv_set_fill_adjust:
1281
68.1k
                        cmd_get_value(gs_gstate.fill_adjust.x, cbp);
1282
68.1k
                        cmd_get_value(gs_gstate.fill_adjust.y, cbp);
1283
68.1k
                        if_debug2m('L', mem, " (%g,%g)\n",
1284
68.1k
                                   fixed2float(gs_gstate.fill_adjust.x),
1285
68.1k
                                   fixed2float(gs_gstate.fill_adjust.y));
1286
68.1k
                        continue;
1287
63.5k
                    case cmd_opv_set_ctm:
1288
63.5k
                        {
1289
63.5k
                            gs_matrix mat;
1290
1291
63.5k
                            cbp = cmd_read_matrix(&mat, cbp);
1292
63.5k
                            if_debug6m('L', mem, " [%g %g %g %g %g %g]\n",
1293
63.5k
                                       mat.xx, mat.xy, mat.yx, mat.yy,
1294
63.5k
                                       mat.tx, mat.ty);
1295
63.5k
                            mat.tx -= x0;
1296
63.5k
                            mat.ty -= y0;
1297
63.5k
                            gs_gstate_setmatrix(&gs_gstate, &mat);
1298
63.5k
                        }
1299
63.5k
                        continue;
1300
115k
                    case cmd_opv_set_misc2:
1301
115k
                        cbuf.ptr = cbp;
1302
115k
                        code = read_set_misc2(&cbuf, &gs_gstate, &notes);
1303
115k
                        cbp = cbuf.ptr;
1304
115k
                        if (code < 0)
1305
0
                            goto out;
1306
115k
                        continue;
1307
115k
                    case cmd_opv_set_dash:
1308
3.70k
                        {
1309
3.70k
                            int nb = *cbp++;
1310
3.70k
                            int n = nb & 0x3f;
1311
3.70k
                            float dot_length, offset;
1312
1313
3.70k
                            cmd_get_value(dot_length, cbp);
1314
3.70k
                            cmd_get_value(offset, cbp);
1315
3.70k
                            memcpy(dash_pattern, cbp, n * sizeof(float));
1316
1317
3.70k
                            gx_set_dash(&gs_gstate.line_params.dash,
1318
3.70k
                                        dash_pattern, n, offset,
1319
3.70k
                                        NULL);
1320
3.70k
                            gx_set_dash_adapt(&gs_gstate.line_params.dash,
1321
3.70k
                                              (nb & 0x80) != 0);
1322
3.70k
                            gx_set_dot_length(&gs_gstate.line_params,
1323
3.70k
                                              dot_length,
1324
3.70k
                                              (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
3.70k
                            cbp += n * sizeof(float);
1339
3.70k
                        }
1340
3.70k
                        break;
1341
333
                    case cmd_opv_enable_clip:
1342
333
                        pcpath = (use_clip ? &clip_path : NULL);
1343
333
                        if (pcpath) {
1344
4
                            code = gx_cpath_ensure_path_list(pcpath);
1345
4
                            if (code < 0)
1346
0
                                goto out;
1347
4
                        }
1348
333
                        if (clipper_dev_open)
1349
0
                            gx_destroy_clip_device_on_stack(&clipper_dev);
1350
333
                        clipper_dev_open = false;
1351
333
                        if_debug0m('L', mem, "\n");
1352
333
                        break;
1353
544
                    case cmd_opv_disable_clip:
1354
544
                        pcpath = NULL;
1355
544
                        if (clipper_dev_open)
1356
3
                            gx_destroy_clip_device_on_stack(&clipper_dev);
1357
544
                        clipper_dev_open = false;
1358
544
                        if_debug0m('L', mem, "\n");
1359
544
                        break;
1360
173k
                    case cmd_opv_begin_clip:
1361
173k
                        pcpath = NULL;
1362
173k
                        if (clipper_dev_open)
1363
218
                            gx_destroy_clip_device_on_stack(&clipper_dev);
1364
173k
                        clipper_dev_open = false;
1365
173k
                        in_clip = true;
1366
173k
                        if_debug0m('L', mem, "\n");
1367
173k
                        code = gx_cpath_reset(&clip_path);
1368
173k
                        if (code < 0)
1369
0
                            goto out;
1370
173k
                        gx_cpath_accum_begin(&clip_accum, mem, false);
1371
173k
                        gx_cpath_accum_set_cbox(&clip_accum,
1372
173k
                                                &target_box);
1373
173k
                        tdev = (gx_device *)&clip_accum;
1374
173k
                        clip_save.lop_enabled = state.lop_enabled;
1375
173k
                        clip_save.dcolor = fill_color;
1376
173k
                        clip_save.fa_save.x = gs_gstate.fill_adjust.x;
1377
173k
                        clip_save.fa_save.y = gs_gstate.fill_adjust.y;
1378
173k
                        cmd_getw(gs_gstate.fill_adjust.x, cbp);
1379
173k
                        cmd_getw(gs_gstate.fill_adjust.y, cbp);
1380
                        /* temporarily set a solid color */
1381
173k
                        color_set_pure(&fill_color, (gx_color_index)1);
1382
173k
                        state.lop_enabled = false;
1383
173k
                        gs_gstate.log_op = lop_default;
1384
173k
                        break;
1385
173k
                    case cmd_opv_end_clip:
1386
173k
                        if_debug0m('L', mem, "\n");
1387
173k
                        gx_cpath_accum_end(&clip_accum, &clip_path);
1388
173k
                        tdev = target;
1389
                        /*
1390
                         * If the entire band falls within the clip
1391
                         * path, no clipping is needed.
1392
                         */
1393
173k
                        {
1394
173k
                            gs_fixed_rect cbox;
1395
1396
173k
                            gx_cpath_inner_box(&clip_path, &cbox);
1397
173k
                            use_clip =
1398
173k
                                !(cbox.p.x <= target_box.p.x &&
1399
173k
                                  cbox.q.x >= target_box.q.x &&
1400
173k
                                  cbox.p.y <= target_box.p.y &&
1401
173k
                                  cbox.q.y >= target_box.q.y);
1402
173k
                        }
1403
173k
                        pcpath = (use_clip ? &clip_path : NULL);
1404
173k
                        if (pcpath) {
1405
99.5k
                            code = gx_cpath_ensure_path_list(pcpath);
1406
99.5k
                            if (code < 0)
1407
0
                                goto out;
1408
99.5k
                        }
1409
173k
                        if (clipper_dev_open)
1410
0
                            gx_destroy_clip_device_on_stack(&clipper_dev);
1411
173k
                        clipper_dev_open = false;
1412
173k
                        state.lop_enabled = clip_save.lop_enabled;
1413
173k
                        gs_gstate.log_op =
1414
173k
                            (state.lop_enabled ? state.lop :
1415
173k
                             lop_default);
1416
173k
                        fill_color = clip_save.dcolor;
1417
                        /* restore the fill_adjust if it was changed by begin_clip */
1418
173k
                        gs_gstate.fill_adjust.x = clip_save.fa_save.x;
1419
173k
                        gs_gstate.fill_adjust.y = clip_save.fa_save.y;
1420
173k
                        in_clip = false;
1421
173k
                        break;
1422
14.3k
                    case cmd_opv_set_color_space:
1423
14.3k
                        cbuf.ptr = cbp;
1424
14.3k
                        code = read_set_color_space(&cbuf, &gs_gstate, cdev, mem);
1425
14.3k
                        pcs = gs_gstate.color[0].color_space;
1426
14.3k
                        cbp = cbuf.ptr;
1427
14.3k
                        if (code < 0) {
1428
0
                            if (code == gs_error_rangecheck)
1429
0
                                goto bad_op;
1430
0
                            goto out;
1431
0
                        }
1432
14.3k
                        break;
1433
5.02M
                    case cmd_op_fill_rect_hl:
1434
5.02M
                        {
1435
5.02M
                            gs_fixed_rect rect_hl;
1436
1437
5.02M
                            cbp = cmd_read_rect(op & 0xf0, &state.rect, cbp);
1438
5.02M
                            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
5.02M
                            if_debug4m('L', mem, " x=%d y=%d w=%d h=%d\n",
1444
5.02M
                                       state.rect.x, state.rect.y,
1445
5.02M
                                       state.rect.width,state.rect.height);
1446
5.02M
                            rect_hl.p.x = int2fixed(state.rect.x - x0);
1447
5.02M
                            rect_hl.p.y = int2fixed(state.rect.y - y0);
1448
5.02M
                            rect_hl.q.x = int2fixed(state.rect.width) + rect_hl.p.x;
1449
5.02M
                            rect_hl.q.y = int2fixed(state.rect.height) + rect_hl.p.y;
1450
5.02M
                            code = dev_proc(tdev, fill_rectangle_hl_color) (tdev,
1451
5.02M
                                                        &rect_hl, NULL,
1452
5.02M
                                                        &fill_color, NULL);
1453
5.02M
                        }
1454
0
                        continue;
1455
15.0k
                    case cmd_opv_begin_image_rect:
1456
15.0k
                        cbuf.ptr = cbp;
1457
15.0k
                        code = read_begin_image(&cbuf, &image.c, pcs);
1458
15.0k
                        cbp = cbuf.ptr;
1459
15.0k
                        if (code < 0)
1460
0
                            goto out;
1461
15.0k
                        {
1462
15.0k
                            uint diff;
1463
1464
15.0k
                            cmd_getw(image_rect.p.x, cbp);
1465
15.0k
                            cmd_getw(image_rect.p.y, cbp);
1466
15.0k
                            cmd_getw(diff, cbp);
1467
15.0k
                            image_rect.q.x = image.d.Width - diff;
1468
15.0k
                            cmd_getw(diff, cbp);
1469
15.0k
                            image_rect.q.y = image.d.Height - diff;
1470
15.0k
                            if_debug4m('L', mem, " rect=(%d,%d),(%d,%d)",
1471
15.0k
                                       image_rect.p.x, image_rect.p.y,
1472
15.0k
                                       image_rect.q.x, image_rect.q.y);
1473
15.0k
                        }
1474
15.0k
                        goto ibegin;
1475
11.1k
                    case cmd_opv_begin_image:
1476
11.1k
                        cbuf.ptr = cbp;
1477
11.1k
                        code = read_begin_image(&cbuf, &image.c, pcs);
1478
11.1k
                        cbp = cbuf.ptr;
1479
11.1k
                        if (code < 0)
1480
0
                            goto out;
1481
11.1k
                        image_rect.p.x = 0;
1482
11.1k
                        image_rect.p.y = 0;
1483
11.1k
                        image_rect.q.x = image.d.Width;
1484
11.1k
                        image_rect.q.y = image.d.Height;
1485
11.1k
                        if_debug2m('L', mem, " size=(%d,%d)",
1486
11.1k
                                  image.d.Width, image.d.Height);
1487
26.1k
ibegin:                 if_debug0m('L', mem, "\n");
1488
26.1k
                        {
1489
                            /* Processing an image operation */
1490
26.1k
                            dev_proc(tdev, set_graphics_type_tag)(tdev, GS_IMAGE_TAG);/* FIXME: what about text bitmaps? */
1491
26.1k
                            image.i4.override_in_smask = 0;
1492
26.1k
                            code = (*dev_proc(tdev, begin_typed_image))
1493
26.1k
                                (tdev, &gs_gstate, NULL,
1494
26.1k
                                 (const gs_image_common_t *)&image,
1495
26.1k
                                 &image_rect, &fill_color, pcpath, mem,
1496
26.1k
                                 &image_info);
1497
26.1k
                        }
1498
26.1k
                        if (code < 0)
1499
0
                            goto out;
1500
26.1k
                        break;
1501
26.1k
                    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
118k
                    case cmd_opv_image_data:
1537
118k
                        cmd_getw(data_height, cbp);
1538
118k
                        if (data_height == 0) {
1539
26.1k
                            if_debug0m('L', mem, " done image\n");
1540
26.1k
                            code = gx_image_end(image_info, true);
1541
26.1k
                            if (code < 0)
1542
0
                                goto out;
1543
26.1k
                            continue;
1544
26.1k
                        }
1545
92.7k
                        {
1546
92.7k
                            uint bytes_per_plane;
1547
92.7k
                            int plane;
1548
1549
92.7k
                            cmd_getw(bytes_per_plane, cbp);
1550
92.7k
                            if_debug2m('L', mem, " height=%u raster=%u\n",
1551
92.7k
                                       data_height, bytes_per_plane);
1552
92.7k
                            for (plane = 0;
1553
185k
                                 plane < image_info->num_planes;
1554
92.7k
                                 ++plane
1555
92.7k
                                 ) {
1556
92.7k
                                planes[plane].data_x = data_x;
1557
92.7k
                                planes[plane].raster = bytes_per_plane;
1558
92.7k
                            }
1559
92.7k
                        }
1560
92.7k
idata:                  data_size = 0;
1561
92.7k
                        {
1562
92.7k
                            int plane;
1563
1564
185k
                            for (plane = 0; plane < image_info->num_planes;
1565
92.7k
                                 ++plane)
1566
92.7k
                                data_size += planes[plane].raster;
1567
92.7k
                        }
1568
92.7k
                        data_size *= data_height;
1569
92.7k
                        data_on_heap = 0;
1570
92.7k
                        if (cbuf.end - cbp < data_size) {
1571
12.5k
                            code = top_up_cbuf(&cbuf, &cbp);
1572
12.5k
                            if (code < 0)
1573
0
                                goto top_up_failed;
1574
12.5k
                        }
1575
92.7k
                        if (cbuf.end - cbp >= data_size) {
1576
92.7k
                            planes[0].data = cbp;
1577
92.7k
                            cbp += data_size;
1578
92.7k
                        } 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
92.7k
                        {
1605
92.7k
                            int plane;
1606
92.7k
                            const byte *data = planes[0].data;
1607
1608
92.7k
                            for (plane = 0;
1609
185k
                                 plane < image_info->num_planes;
1610
92.7k
                                 ++plane
1611
92.7k
                                 ) {
1612
92.7k
                                if (planes[plane].raster == 0)
1613
0
                                    planes[plane].data = 0;
1614
92.7k
                                else {
1615
92.7k
                                    planes[plane].data = data;
1616
92.7k
                                    data += planes[plane].raster *
1617
92.7k
                                        data_height;
1618
92.7k
                                }
1619
92.7k
                            }
1620
92.7k
                        }
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
92.7k
                        code = gx_image_plane_data(image_info, planes,
1637
92.7k
                                                   data_height);
1638
92.7k
                        if (code < 0)
1639
0
                            gx_image_end(image_info, false);
1640
92.7k
                        if (data_on_heap)
1641
0
                            gs_free_object(mem, data_on_heap,
1642
92.7k
                                           "clist image_data");
1643
92.7k
                        data_x = 0;
1644
92.7k
                        if (code < 0)
1645
0
                            goto out;
1646
92.7k
                        continue;
1647
8.92M
                    case cmd_opv_extend:
1648
8.92M
                        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
306k
                            case cmd_opv_ext_composite:
1663
306k
                                if_debug0m('L', mem, " ext_composite\n");
1664
306k
                                cbuf.ptr = cbp;
1665
                                /*
1666
                                 * The screen phase may have been changed during
1667
                                 * the processing of masked images.
1668
                                 */
1669
306k
                                gx_gstate_setscreenphase(&gs_gstate,
1670
306k
                                            -x0, -y0, gs_color_select_all);
1671
306k
                                cbp -= 2; /* Step back to simplify the cycle invariant below. */
1672
3.97M
                                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
3.97M
                                    int len;
1678
1679
3.97M
                                    if (cbp >= cbuf.warn_limit) {
1680
28.5k
                                        code = top_up_cbuf(&cbuf, &cbp);
1681
28.5k
                                        if (code < 0)
1682
0
                                            goto out;
1683
28.5k
                                    }
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
3.97M
                                    if (cbp[0] == cmd_opv_extend && cbp[1] == cmd_opv_ext_composite) {
1694
2.23M
                                        gs_composite_t *pcomp, *pcomp_opening;
1695
2.23M
                                        gs_compositor_closing_state closing_state;
1696
1697
2.23M
                                        cbuf.ptr = cbp += 2;
1698
2.23M
                                        code = read_composite(&cbuf, mem, &pcomp);
1699
2.23M
                                        if (code < 0)
1700
0
                                            goto out;
1701
2.23M
                                        cbp = cbuf.ptr;
1702
2.23M
                                        if (pcomp == NULL)
1703
0
                                            continue;
1704
2.23M
                                        if (gs_is_pdf14trans_compositor(pcomp) &&
1705
2.23M
                                            playback_action == playback_action_render_no_pdf14) {
1706
                                            /* free the compositor object */
1707
0
                                            gs_free_object(mem, pcomp, "read_composite");
1708
0
                                            pcomp = NULL;
1709
0
                                            continue;
1710
0
                                        }
1711
2.23M
                                        pcomp_opening = pcomp_last;
1712
2.23M
                                        closing_state = pcomp->type->procs.is_closing(pcomp, &pcomp_opening, tdev);
1713
2.23M
                                        switch(closing_state)
1714
2.23M
                                        {
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
1.37M
                                        case COMP_ENQUEUE:
1721
                                            /* Enqueue. */
1722
1.37M
                                            enqueue_compositor(&pcomp_first, &pcomp_last, pcomp);
1723
1.37M
                                            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
40.1k
                                        case COMP_EXEC_QUEUE:
1733
                                            /* The opening command was executed. Execute the queue. */
1734
40.1k
                                            enqueue_compositor(&pcomp_first, &pcomp_last, pcomp);
1735
40.1k
                                            code = execute_compositor_queue(cdev, &target, &tdev,
1736
40.1k
                                                &gs_gstate, &pcomp_first, &pcomp_last, pcomp_first, x0, y0, mem, false);
1737
40.1k
                                            if (code < 0)
1738
0
                                                goto out;
1739
40.1k
                                            break;
1740
40.1k
                                        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
698k
                                        case COMP_REPLACE_CURR:
1749
                                            /* Replace specific compositor. */
1750
698k
                                            code = dequeue_compositor(&pcomp_first, &pcomp_last, pcomp_opening);
1751
698k
                                            if (code < 0)
1752
0
                                                goto out;
1753
698k
                                            enqueue_compositor(&pcomp_first, &pcomp_last, pcomp);
1754
698k
                                            free_compositor(pcomp_opening, mem);
1755
698k
                                            break;
1756
15.5k
                                        case COMP_DROP_QUEUE:
1757
                                            /* Annihilate the last compositors. */
1758
15.5k
                                            enqueue_compositor(&pcomp_first, &pcomp_last, pcomp);
1759
15.5k
                                            code = drop_compositor_queue(&pcomp_first, &pcomp_last, pcomp_opening, mem, x0, y0, &gs_gstate);
1760
15.5k
                                            if (code < 0)
1761
0
                                                goto out;
1762
15.5k
                                            break;
1763
102k
                                        case COMP_MARK_IDLE:
1764
                                            /* Mark as idle. */
1765
102k
                                            enqueue_compositor(&pcomp_first, &pcomp_last, pcomp);
1766
102k
                                            mark_as_idle(pcomp_opening, pcomp);
1767
2.23M
                                        }
1768
2.23M
                                    } else if (is_null_compositor_op(cbp, &len)) {
1769
1.29M
                                        cbuf.ptr = cbp += len;
1770
1.29M
                                    } else if (cbp[0] == cmd_opv_end_page) {
1771
                                        /* End page, drop the queue. */
1772
116k
                                        code = execute_compositor_queue(cdev, &target, &tdev,
1773
116k
                                                &gs_gstate, &pcomp_first, &pcomp_last, pcomp_first, x0, y0, mem, true);
1774
116k
                                        if (code < 0)
1775
0
                                            goto out;
1776
116k
                                        break;
1777
336k
                                    } else if (pcomp_last != NULL &&
1778
336k
                                            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
146k
                                        uint cb;
1787
1788
146k
                                        switch (*cbp++) {
1789
85.6k
                                            case cmd_opv_extend:
1790
85.6k
                                                switch (*cbp++) {
1791
28.5k
                                                    case cmd_opv_ext_put_halftone:
1792
28.5k
                                                        {
1793
28.5k
                                                            uint    ht_size;
1794
1795
28.5k
                                                            enc_u_getw(ht_size, cbp);
1796
28.5k
                                                            code = read_alloc_ht_buff(&ht_buff, ht_size, mem);
1797
28.5k
                                                            if (code < 0)
1798
0
                                                                goto out;
1799
28.5k
                                                        }
1800
28.5k
                                                        break;
1801
57.0k
                                                    case cmd_opv_ext_put_ht_seg:
1802
57.0k
                                                        cbuf.ptr = cbp;
1803
57.0k
                                                        code = read_ht_segment(&ht_buff, &cbuf,
1804
57.0k
                                                                               &gs_gstate, tdev,
1805
57.0k
                                                                               mem);
1806
57.0k
                                                        cbp = cbuf.ptr;
1807
57.0k
                                                        if (code < 0)
1808
0
                                                            goto out;
1809
57.0k
                                                        break;
1810
57.0k
                                                    default:
1811
0
                                                        code = gs_note_error(gs_error_unregistered); /* Must not happen. */
1812
0
                                                        goto out;
1813
85.6k
                                                }
1814
85.6k
                                                break;
1815
85.6k
                                            case cmd_opv_set_misc:
1816
60.7k
                                                cb = *cbp++;
1817
60.7k
                                                switch (cb >> 6) {
1818
60.7k
                                                    case cmd_set_misc_map >> 6:
1819
60.7k
                                                        cbuf.ptr = cbp;
1820
60.7k
                                                        code = read_set_misc_map(cb, &cbuf, &gs_gstate, mem);
1821
60.7k
                                                        if (code < 0)
1822
0
                                                            goto out;
1823
60.7k
                                                        cbp = cbuf.ptr;
1824
60.7k
                                                        break;
1825
0
                                                    default:
1826
0
                                                        code = gs_note_error(gs_error_unregistered); /* Must not happen. */
1827
0
                                                        goto out;
1828
60.7k
                                                }
1829
60.7k
                                                break;
1830
60.7k
                                            default:
1831
0
                                                code = gs_note_error(gs_error_unregistered); /* Must not happen. */
1832
0
                                                goto out;
1833
146k
                                        }
1834
190k
                                    } else {
1835
                                        /* A drawing command, execute entire queue. */
1836
190k
                                        code = execute_compositor_queue(cdev, &target, &tdev,
1837
190k
                                            &gs_gstate, &pcomp_first, &pcomp_last, pcomp_first, x0, y0, mem, false);
1838
190k
                                        if (code < 0)
1839
0
                                            goto out;
1840
190k
                                        break;
1841
190k
                                    }
1842
3.97M
                                }
1843
306k
                                if (pcomp_last != NULL) {
1844
0
                                    code = gs_note_error(gs_error_unregistered);
1845
0
                                    goto out;
1846
0
                                }
1847
306k
                                break;
1848
306k
                            case cmd_opv_ext_put_halftone:
1849
92.5k
                                {
1850
92.5k
                                    uint    ht_size;
1851
1852
92.5k
                                    if_debug0m('L', mem, " ext_put_halftone\n");
1853
92.5k
                                    enc_u_getw(ht_size, cbp);
1854
92.5k
                                    code = read_alloc_ht_buff(&ht_buff, ht_size, mem);
1855
92.5k
                                    if (code < 0)
1856
0
                                        goto out;
1857
92.5k
                                }
1858
92.5k
                                break;
1859
185k
                            case cmd_opv_ext_put_ht_seg:
1860
185k
                                if_debug0m('L', mem, " ext_put_ht_seg\n");
1861
185k
                                cbuf.ptr = cbp;
1862
185k
                                code = read_ht_segment(&ht_buff, &cbuf,
1863
185k
                                                       &gs_gstate, tdev,
1864
185k
                                                       mem);
1865
185k
                                cbp = cbuf.ptr;
1866
185k
                                if (code < 0)
1867
0
                                    goto out;
1868
185k
                                break;
1869
185k
                            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
248
                            case cmd_opv_ext_tile_rect_hl:
1878
                                /* Strip tile with devn colors */
1879
248
                                cbp = cmd_read_rect(op & 0xf0, &state.rect, cbp);
1880
248
                                if_debug4m('L', mem, " x=%d y=%d w=%d h=%d\n",
1881
248
                                           state.rect.x, state.rect.y,
1882
248
                                           state.rect.width,state.rect.height);
1883
248
                                code = (*dev_proc(tdev, strip_tile_rect_devn))
1884
248
                                    (tdev, &state_tile,
1885
248
                                     state.rect.x - x0, state.rect.y - y0,
1886
248
                                     state.rect.width, state.rect.height,
1887
248
                                     &(state.tile_color_devn[0]),
1888
248
                                     &(state.tile_color_devn[1]),
1889
248
                                     tile_phase.x, tile_phase.y);
1890
248
                                break;
1891
8.29M
                            case cmd_opv_ext_put_fill_dcolor:
1892
8.29M
                                pdcolor = &fill_color;
1893
8.29M
                                goto load_dcolor;
1894
44.8k
                            case cmd_opv_ext_put_stroke_dcolor:
1895
44.8k
                                pdcolor = &stroke_color;
1896
44.8k
                                goto load_dcolor;
1897
248
                            case cmd_opv_ext_put_tile_devn_color0:
1898
248
                                pdcolor = &set_dev_colors[0];
1899
248
                                goto load_dcolor;
1900
248
                            case cmd_opv_ext_put_tile_devn_color1:
1901
248
                                pdcolor = &set_dev_colors[1];
1902
8.34M
                    load_dcolor:{
1903
8.34M
                                    uint    color_size;
1904
8.34M
                                    int left, offset, l;
1905
8.34M
                                    const gx_device_color_type_t *  pdct;
1906
8.34M
                                    byte type_and_flag = *cbp++;
1907
8.34M
                                    byte is_continuation = type_and_flag & 0x80;
1908
1909
8.34M
                                    if_debug0m('L', mem, " cmd_opv_ext_put_drawing_color\n");
1910
8.34M
                                    pdct = gx_get_dc_type_from_index(type_and_flag & 0x7F);
1911
8.34M
                                    if (pdct == 0) {
1912
0
                                        code = gs_note_error(gs_error_rangecheck);
1913
0
                                        goto out;
1914
0
                                    }
1915
8.34M
                                    offset = 0;
1916
8.34M
                                    if (is_continuation)
1917
8.34M
                                        enc_u_getw(offset, cbp);
1918
8.34M
                                    enc_u_getw(color_size, cbp);
1919
8.34M
                                    left = color_size;
1920
8.34M
                                    if (!left) {
1921
                                        /* We still need to call pdct->read because it may change dev_color.type -
1922
                                           see gx_dc_null_read.*/
1923
37.8k
                                        code = pdct->read(pdcolor, &gs_gstate,
1924
37.8k
                                                          pdcolor, tdev, offset,
1925
37.8k
                                                          cbp, 0, mem, x0, y0);
1926
37.8k
                                        if (code < 0)
1927
0
                                            goto out;
1928
37.8k
                                    }
1929
19.5M
                                    while (left) {
1930
11.2M
                                        if (cbuf.warn_limit - cbp < (int)left) {  /* cbp can be past warn_limit */
1931
3.14M
                                            code = top_up_cbuf(&cbuf, &cbp);
1932
3.14M
                                            if (code < 0)
1933
0
                                                goto top_up_failed;
1934
3.14M
                                        }
1935
11.2M
                                        l = min(left, cbuf.end - cbp);
1936
11.2M
                                        code = pdct->read(pdcolor, &gs_gstate,
1937
11.2M
                                                          pdcolor, tdev, offset,
1938
11.2M
                                                          cbp, l, mem, x0, y0);
1939
11.2M
                                        if (code < 0)
1940
0
                                            goto out;
1941
11.2M
                                        l = code;
1942
11.2M
                                        cbp += l;
1943
11.2M
                                        offset += l;
1944
11.2M
                                        left -= l;
1945
11.2M
                                    }
1946
8.34M
                                    code = gx_color_load(pdcolor, &gs_gstate,
1947
8.34M
                                                         tdev);
1948
8.34M
                                    if (code < 0)
1949
0
                                        goto out;
1950
8.34M
                                }
1951
8.34M
                                break;
1952
8.34M
                            default:
1953
0
                                goto bad_op;
1954
8.92M
                        }
1955
8.92M
                        break;
1956
8.92M
                    default:
1957
0
                        goto bad_op;
1958
14.7M
                }
1959
9.31M
                continue;
1960
16.3M
            case cmd_op_segment >> 4:
1961
16.3M
                {
1962
16.3M
                    int i;
1963
16.3M
                    static const byte op_num_operands[] = {
1964
16.3M
                        cmd_segment_op_num_operands_values
1965
16.3M
                    };
1966
16.3M
                  rgapto:
1967
16.3M
                    if (!in_path) {
1968
1.62M
                        ppos.x = int2fixed(state.rect.x);
1969
1.62M
                        ppos.y = int2fixed(state.rect.y);
1970
1.62M
                        if_debug2m('L', mem, " (%d,%d)", state.rect.x,
1971
1.62M
                                   state.rect.y);
1972
1.62M
                        notes = sn_none;
1973
1.62M
                        in_path = true;
1974
1.62M
                    }
1975
45.3M
                    for (i = 0; i < op_num_operands[op & 0xf]; ++i) {
1976
28.9M
                        fixed v;
1977
28.9M
                        int b = *cbp;
1978
1979
28.9M
                        switch (b >> 5) {
1980
9.19M
                            case 0:
1981
18.0M
                            case 1:
1982
18.0M
                                vs[i++] =
1983
18.0M
                                    ((fixed) ((b ^ 0x20) - 0x20) << 13) +
1984
18.0M
                                    ((int)cbp[1] << 5) + (cbp[2] >> 3);
1985
18.0M
                                if_debug1m('L', mem, " %g", fixed2float(vs[i - 1]));
1986
18.0M
                                cbp += 2;
1987
18.0M
                                v = (int)((*cbp & 7) ^ 4) - 4;
1988
18.0M
                                break;
1989
3.72M
                            case 2:
1990
7.31M
                            case 3:
1991
7.31M
                                v = (b ^ 0x60) - 0x20;
1992
7.31M
                                break;
1993
15.1k
                            case 4:
1994
29.6k
                            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
29.6k
                                v = (((b ^ 0xa0) - 0x20) << 8) + (int)*++cbp;
2003
29.6k
                                break;
2004
3.47M
                            case 6:
2005
3.47M
                                v = (b ^ 0xd0) - 0x10;
2006
3.47M
                                vs[i] =
2007
3.47M
                                    ((v << 8) + cbp[1]) << (_fixed_shift - 2);
2008
3.47M
                                if_debug1m('L', mem, " %g", fixed2float(vs[i]));
2009
3.47M
                                cbp += 2;
2010
3.47M
                                continue;
2011
19.3k
                            default /*case 7 */ :
2012
19.3k
                                v = (int)(*++cbp ^ 0x80) - 0x80;
2013
38.7k
                                for (b = 0; b < sizeof(fixed) - 3; ++b)
2014
19.3k
                                    v = (v << 8) + *++cbp;
2015
19.3k
                                break;
2016
28.9M
                        }
2017
25.4M
                        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
25.4M
                        vs[i] = (v << 16) + (uint) (cbp[-2] << 8) + cbp[-1];
2022
25.4M
                        if_debug1m('L', mem, " %g", fixed2float(vs[i]));
2023
25.4M
                    }
2024
16.3M
                    if_debug0m('L', mem, "\n");
2025
16.3M
                    code = clist_decode_segment(&path, op, vs, &ppos,
2026
16.3M
                                                x0, y0, notes);
2027
16.3M
                    if (code < 0)
2028
0
                        goto out;
2029
16.3M
                }
2030
16.3M
                continue;
2031
16.3M
            case cmd_op_path >> 4:
2032
13.4M
                if (op == cmd_opv_rgapto)
2033
0
                    goto rgapto;
2034
13.4M
                else if (op == cmd_opv_lock_pattern) {
2035
396
                    gs_id id;
2036
396
                    int lock = *cbp++;
2037
396
                    cmd_get_value(id, cbp);
2038
396
                    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
396
                    code = gx_pattern_cache_entry_set_lock(&gs_gstate, id, lock);
2044
396
                    if (code == gs_error_undefined)
2045
0
                        code = 0;
2046
396
                    if (code < 0)
2047
0
                        goto out;
2048
396
                    continue;
2049
13.4M
                } else {
2050
13.4M
                    gx_path fpath;
2051
13.4M
                    gx_path *ppath = &path;
2052
2053
13.4M
                    if_debug0m('L', mem, "\n");
2054
                    /* if in clip, flatten path first */
2055
13.4M
                    if (in_clip) {
2056
77.8k
                        gx_path_init_local(&fpath, mem);
2057
77.8k
                        code = gx_path_add_flattened_accurate(&path, &fpath,
2058
77.8k
                                             gs_currentflat_inline(&gs_gstate),
2059
77.8k
                                             gs_gstate.accurate_curves);
2060
77.8k
                        if (code < 0)
2061
0
                            goto out;
2062
77.8k
                        ppath = &fpath;
2063
77.8k
                    }
2064
13.4M
                    switch (op) {
2065
1.66M
                        case cmd_opv_fill:
2066
1.66M
                            fill_params.rule = gx_rule_winding_number;
2067
1.66M
                            goto fill;
2068
6.21k
                        case cmd_opv_eofill:
2069
6.21k
                            fill_params.rule = gx_rule_even_odd;
2070
1.67M
                        fill:
2071
1.67M
                            fill_params.adjust = gs_gstate.fill_adjust;
2072
1.67M
                            fill_params.flatness = gs_gstate.flatness;
2073
1.67M
                            code = (*dev_proc(tdev, fill_path))(tdev, &gs_gstate, ppath,
2074
1.67M
                                                                &fill_params, &fill_color, pcpath);
2075
1.67M
                            break;
2076
9.40k
                        case cmd_opv_fill_stroke:
2077
9.40k
                            fill_params.rule = gx_rule_winding_number;
2078
9.40k
                            goto fill_stroke;
2079
1.03k
                        case cmd_opv_eofill_stroke:
2080
1.03k
                            fill_params.rule = gx_rule_even_odd;
2081
10.4k
                        fill_stroke:
2082
10.4k
                            fill_params.adjust = gs_gstate.fill_adjust;
2083
10.4k
                            fill_params.flatness = gs_gstate.flatness;
2084
10.4k
                            stroke_params.flatness = gs_gstate.flatness;
2085
10.4k
                            stroke_params.traditional = false;
2086
10.4k
                            code = (*dev_proc(tdev, fill_stroke_path))(tdev, &gs_gstate, ppath,
2087
10.4k
                                                                &fill_params, &fill_color,
2088
10.4k
                                                                &stroke_params, &stroke_color, pcpath);
2089
10.4k
                            break;
2090
56.5k
                        case cmd_opv_stroke:
2091
56.5k
                            stroke_params.flatness = gs_gstate.flatness;
2092
56.5k
                            stroke_params.traditional = false;
2093
56.5k
                            code = (*dev_proc(tdev, stroke_path))
2094
56.5k
                                                       (tdev, &gs_gstate,
2095
56.5k
                                                       ppath, &stroke_params,
2096
56.5k
                                                       &stroke_color, pcpath);
2097
56.5k
                            break;
2098
17.9k
                        case cmd_opv_polyfill:
2099
17.9k
                            code = clist_do_polyfill(tdev, ppath, &fill_color,
2100
17.9k
                                                     gs_gstate.log_op);
2101
17.9k
                            break;
2102
11.6M
                        case cmd_opv_fill_trapezoid:
2103
11.6M
                            {
2104
11.6M
                                gs_fixed_edge left, right;
2105
11.6M
                                fixed ybot, ytop;
2106
11.6M
                                int options, swap_axes, wh;
2107
11.6M
                                fixed x0f;
2108
11.6M
                                fixed y0f;
2109
11.6M
                                gx_device *ttdev = tdev;
2110
2111
11.6M
                                if (pcpath != NULL && !clipper_dev_open) {
2112
353
                                    gx_make_clip_device_on_stack(&clipper_dev, pcpath, tdev);
2113
353
                                    clipper_dev_open = true;
2114
353
                                }
2115
11.6M
                                if (clipper_dev_open)
2116
11.5M
                                    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
11.6M
                                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
11.6M
                                cmd_getw(left.start.x, cbp);
2132
11.6M
                                cmd_getw(left.start.y, cbp);
2133
11.6M
                                cmd_getw(left.end.x, cbp);
2134
11.6M
                                cmd_getw(left.end.y, cbp);
2135
11.6M
                                cmd_getw(right.start.x, cbp);
2136
11.6M
                                cmd_getw(right.start.y, cbp);
2137
11.6M
                                cmd_getw(right.end.x, cbp);
2138
11.6M
                                cmd_getw(right.end.y, cbp);
2139
11.6M
                                cmd_getw(options, cbp);
2140
11.6M
                                if (!(options & 4)) {
2141
11.6M
                                    cmd_getw(ybot, cbp);
2142
11.6M
                                    cmd_getw(ytop, cbp);
2143
11.6M
                                } else
2144
0
                                    ytop = ybot = 0; /* Unused, but quiet gcc warning. */
2145
11.6M
                                swap_axes = options & 1;
2146
11.6M
                                wh = swap_axes ? tdev->width : tdev->height;
2147
11.6M
                                x0f = int2fixed(swap_axes ? y0 : x0);
2148
11.6M
                                y0f = int2fixed(swap_axes ? x0 : y0);
2149
11.6M
                                left.start.x -= x0f;
2150
11.6M
                                left.start.y -= y0f;
2151
11.6M
                                left.end.x -= x0f;
2152
11.6M
                                left.end.y -= y0f;
2153
11.6M
                                right.start.x -= x0f;
2154
11.6M
                                right.start.y -= y0f;
2155
11.6M
                                right.end.x -= x0f;
2156
11.6M
                                right.end.y -= y0f;
2157
11.6M
                                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
11.6M
                                    code = gx_default_fill_trapezoid(ttdev, &left, &right,
2240
11.6M
                                        max(ybot - y0f, fixed_half),
2241
11.6M
                                        min(ytop - y0f, int2fixed(wh)), swap_axes,
2242
11.6M
                                        &fill_color, gs_gstate.log_op);
2243
11.6M
                            }
2244
11.6M
                           break;
2245
11.6M
                        default:
2246
0
                            goto bad_op;
2247
13.4M
                    }
2248
13.4M
                    if (ppath != &path)
2249
77.8k
                        gx_path_free(ppath, "clist_render_band");
2250
13.4M
                }
2251
13.4M
                if (in_path) {  /* path might be empty! */
2252
1.62M
                    state.rect.x = fixed2int_var(ppos.x);
2253
1.62M
                    state.rect.y = fixed2int_var(ppos.y);
2254
1.62M
                    in_path = false;
2255
1.62M
                }
2256
13.4M
                gx_path_free(&path, "clist_render_band");
2257
13.4M
                gx_path_init_local(&path, mem);
2258
13.4M
                if (code < 0)
2259
0
                    goto out;
2260
13.4M
                continue;
2261
13.4M
            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
48.5M
        }
2277
48.5M
        if_debug4m('L', mem, " x=%d y=%d w=%d h=%d\n",
2278
2.36M
                  state.rect.x, state.rect.y, state.rect.width,
2279
2.36M
                  state.rect.height);
2280
2.36M
        switch (op >> 4) {
2281
224k
            case cmd_op_fill_rect >> 4:
2282
224k
                if (state.rect.width == 0 && state.rect.height == 0 &&
2283
224k
                    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
138k
                    code = (dev_proc(tdev, fillpage) == NULL ? 0 :
2287
138k
                            (*dev_proc(tdev, fillpage))(tdev, &gs_gstate,
2288
138k
                                                        &fill_color));
2289
138k
                    break;
2290
138k
                }
2291
119k
            case cmd_op_fill_rect_short >> 4:
2292
611k
            case cmd_op_fill_rect_tiny >> 4:
2293
611k
                if (!state.lop_enabled) {
2294
611k
                    code = (*dev_proc(tdev, fill_rectangle))
2295
611k
                        (tdev, state.rect.x - x0, state.rect.y - y0,
2296
611k
                         state.rect.width, state.rect.height,
2297
611k
                         state.colors[1]);
2298
611k
                    break;
2299
611k
                }
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
14.8k
            case cmd_op_tile_rect >> 4:
2320
14.8k
                if (state.rect.width == 0 && state.rect.height == 0 &&
2321
14.8k
                    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
70.3k
            case cmd_op_tile_rect_short >> 4:
2326
152k
            case cmd_op_tile_rect_tiny >> 4:
2327
                /* Currently we don't use lop with strip_tile_rectangle. */
2328
152k
                code = (*dev_proc(tdev, strip_tile_rectangle))
2329
152k
                    (tdev, &state_tile,
2330
152k
                     state.rect.x - x0, state.rect.y - y0,
2331
152k
                     state.rect.width, state.rect.height,
2332
152k
                     state.tile_colors[0], state.tile_colors[1],
2333
152k
                     tile_phase.x, tile_phase.y);
2334
152k
                break;
2335
665k
            case cmd_op_copy_mono_planes >> 4:
2336
665k
                if (state.lop_enabled) {
2337
0
                    pcolor = state.colors;
2338
0
                    log_op = state.lop;
2339
0
                    goto do_rop;
2340
0
                }
2341
665k
                if ((op & cmd_copy_use_tile) || pcpath != NULL) {       /*
2342
                                                                         * This call of copy_mono originated as a call
2343
                                                                         * of fill_mask.
2344
                                                                         */
2345
649k
                    code = gx_image_fill_masked
2346
649k
                        (tdev, source, data_x, raster, gx_no_bitmap_id,
2347
649k
                         state.rect.x - x0, state.rect.y - y0,
2348
649k
                         state.rect.width - data_x, state.rect.height,
2349
649k
                         &fill_color, 1, gs_gstate.log_op, pcpath);
2350
649k
                } else {
2351
16.6k
                    if (plane_height == 0) {
2352
9.87k
                        code = (*dev_proc(tdev, copy_mono))
2353
9.87k
                             (tdev, source, data_x, raster, gx_no_bitmap_id,
2354
9.87k
                              state.rect.x - x0, state.rect.y - y0,
2355
9.87k
                              state.rect.width - data_x, state.rect.height,
2356
9.87k
                              state.colors[0], state.colors[1]);
2357
9.87k
                    } else {
2358
6.81k
                        code = (*dev_proc(tdev, copy_planes))
2359
6.81k
                             (tdev, source, data_x, raster, gx_no_bitmap_id,
2360
6.81k
                              state.rect.x - x0, state.rect.y - y0,
2361
6.81k
                              state.rect.width - data_x, state.rect.height,
2362
6.81k
                              plane_height);
2363
6.81k
                    }
2364
16.6k
                }
2365
665k
                plane_height = 0;
2366
665k
                data_x = 0;
2367
665k
                break;
2368
796k
            case cmd_op_copy_color_alpha >> 4:
2369
796k
                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
796k
                } else {
2386
796k
                    if (state.lop_enabled) {
2387
0
                        pcolor = NULL;
2388
0
                        log_op = state.lop;
2389
0
                        goto do_rop;
2390
0
                    }
2391
796k
                    code = (*dev_proc(tdev, copy_color))
2392
796k
                        (tdev, source, data_x, raster, gx_no_bitmap_id,
2393
796k
                         state.rect.x - x0, state.rect.y - y0,
2394
796k
                         state.rect.width - data_x, state.rect.height);
2395
796k
                }
2396
796k
                data_x = 0;
2397
796k
                break;
2398
0
            default:            /* can't happen */
2399
0
                goto bad_op;
2400
2.36M
        }
2401
2.36M
    }
2402
    /* Clean up before we exit. */
2403
144k
  out:
2404
144k
    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
144k
    ht_buff.ht_size = 0;
2410
144k
    ht_buff.read_size = 0;
2411
2412
144k
    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
144k
    gx_cpath_free(&clip_path, "clist_render_band exit");
2419
144k
    gx_path_free(&path, "clist_render_band exit");
2420
144k
    if (gs_gstate.pattern_cache != NULL) {
2421
4.22k
        gx_pattern_cache_free(gs_gstate.pattern_cache);
2422
4.22k
        gs_gstate.pattern_cache = NULL;
2423
4.22k
    }
2424
    /* Free the client color and device colors allocated upon entry */
2425
144k
    gs_free_object(mem, gs_gstate.color[0].ccolor, "clist_playback_band");
2426
144k
    gs_free_object(mem, gs_gstate.color[1].ccolor, "clist_playback_band");
2427
144k
    gs_free_object(mem, gs_gstate.color[0].dev_color, "clist_playback_band");
2428
144k
    gs_free_object(mem, gs_gstate.color[1].dev_color, "clist_playback_band");
2429
144k
    gs_gstate.color[0].ccolor = gs_gstate.color[1].ccolor = NULL;
2430
144k
    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
144k
    gx_monitor_enter(cdev->icc_cache_cl->lock);
2435
144k
    gs_gstate_release(&gs_gstate);
2436
144k
    gx_monitor_leave(cdev->icc_cache_cl->lock); /* done with increment, let everyone run */
2437
144k
    gs_free_object(mem, data_bits, "clist_playback_band(data_bits)");
2438
144k
    if (target != orig_target) {
2439
98.8k
        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
98.8k
        } else {
2448
            /* Ref count was 1. close the device and then free it */
2449
98.8k
            if (target->is_open)
2450
167
                dev_proc(target, close_device)(target);
2451
98.8k
            gs_free_object(target->memory, target, "gxclrast discard compositor");
2452
98.8k
        }
2453
98.8k
        target = orig_target;
2454
98.8k
    }
2455
144k
    if (code < 0) {
2456
0
        if (pfs.dev != NULL)
2457
0
            term_patch_fill_state(&pfs);
2458
0
        rc_decrement(gs_gstate.color[0].color_space, "clist_playback_band");
2459
0
        rc_decrement(gs_gstate.color[1].color_space, "clist_playback_band");
2460
0
        gs_free_object(mem, cbuf_storage, "clist_playback_band(cbuf_storage)");
2461
0
        gx_cpath_free(&clip_path, "clist_playback_band");
2462
0
        if (pcpath != &clip_path)
2463
0
            gx_cpath_free(pcpath, "clist_playback_band");
2464
0
        if (clipper_dev_open)
2465
0
            gx_destroy_clip_device_on_stack(&clipper_dev);
2466
0
        return_error(code);
2467
0
    }
2468
    /* Check whether we have more pages to process. */
2469
144k
    if ((playback_action != playback_action_setup &&
2470
144k
        (cbp < cbuf.end || !seofp(s)) && (op != cmd_opv_end_page) )
2471
144k
        )
2472
0
        goto in;
2473
144k
    if (pfs.dev != NULL)
2474
0
        term_patch_fill_state(&pfs);
2475
144k
    rc_decrement(gs_gstate.color[0].color_space, "clist_playback_band");
2476
144k
    rc_decrement(gs_gstate.color[1].color_space, "clist_playback_band");
2477
144k
    gs_free_object(mem, cbuf_storage, "clist_playback_band(cbuf_storage)");
2478
144k
    gx_cpath_free(&clip_path, "clist_playback_band");
2479
144k
    if (pcpath != &clip_path)
2480
130k
        gx_cpath_free(pcpath, "clist_playback_band");
2481
144k
    if (clipper_dev_open)
2482
132
        gx_destroy_clip_device_on_stack(&clipper_dev);
2483
144k
    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
144k
}
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
762
{
2506
762
    const byte *cbp = pcb->ptr;
2507
762
    uint rep_width, rep_height;
2508
762
    uint pdepth;
2509
762
    byte bd = *cbp++;
2510
2511
762
    bits->head.depth = cmd_code_to_depth(bd);
2512
762
    if (for_pattern)
2513
762
        cmd_getw(bits->id, cbp);
2514
762
    cmd_getw(rep_width, cbp);
2515
762
    cmd_getw(rep_height, cbp);
2516
762
    if (bd & 0x20) {
2517
762
        cmd_getw(bits->x_reps, cbp);
2518
762
        bits->width = rep_width * bits->x_reps;
2519
762
    } else {
2520
0
        bits->x_reps = 1;
2521
0
        bits->width = rep_width;
2522
0
    }
2523
762
    if (bd & 0x40) {
2524
302
        cmd_getw(bits->y_reps, cbp);
2525
302
        bits->height = rep_height * bits->y_reps;
2526
460
    } else {
2527
460
        bits->y_reps = 1;
2528
460
        bits->height = rep_height;
2529
460
    }
2530
762
    if (bd & 0x80)
2531
762
        cmd_getw(bits->rep_shift, cbp);
2532
762
    else
2533
762
        bits->rep_shift = 0;
2534
762
    if (bd & 0x10)
2535
0
        bits->num_planes = *cbp++;
2536
762
    else
2537
762
        bits->num_planes = 1;
2538
762
    if_debug7('L', " depth=%d size=(%d,%d), rep_size=(%d,%d), rep_shift=%d, num_planes=%d\n",
2539
762
              bits->head.depth, bits->width,
2540
762
              bits->height, rep_width,
2541
762
              rep_height, bits->rep_shift, bits->num_planes);
2542
762
    bits->shift =
2543
762
        (bits->rep_shift == 0 ? 0 :
2544
762
         (bits->rep_shift * (bits->height / rep_height)) % rep_width);
2545
762
    pdepth = bits->head.depth;
2546
762
    if (bits->num_planes != 1)
2547
0
        pdepth /= bits->num_planes;
2548
762
    bits->raster = bitmap_raster(bits->width * pdepth);
2549
762
    pcb->ptr = cbp;
2550
762
    return 0;
2551
762
}
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
208k
{
2558
208k
    const byte *cbp = pcb->ptr;
2559
208k
    uint rep_width = bits->width / bits->x_reps;
2560
208k
    uint rep_height = bits->height / bits->y_reps;
2561
208k
    uint index;
2562
208k
    ulong offset;
2563
208k
    uint width_bits;
2564
208k
    uint width_bytes;
2565
208k
    uint raster;
2566
208k
    uint bytes;
2567
208k
    byte *data;
2568
208k
    tile_slot *slot;
2569
208k
    uint depth = bits->head.depth;
2570
2571
208k
    if (bits->num_planes != 1)
2572
0
        depth /= bits->num_planes;
2573
208k
    width_bits = rep_width * depth;
2574
2575
208k
    bytes = clist_bitmap_bytes(width_bits, rep_height * bits->num_planes,
2576
208k
                               compress |
2577
208k
                               (rep_width < bits->width ?
2578
205k
                                decompress_spread : 0) |
2579
208k
                               decompress_elsewhere,
2580
208k
                               &width_bytes,
2581
208k
                               (uint *)&raster);
2582
2583
208k
    cmd_getw(index, cbp);
2584
208k
    cmd_getw(offset, cbp);
2585
208k
    if_debug2m('L', mem, " index=%d offset=%lu\n", index, offset);
2586
208k
    pcls->tile_index = index;
2587
208k
    cdev->tile_table[pcls->tile_index].offset = offset;
2588
208k
    slot = (tile_slot *)(cdev->cache_chunk->data + offset);
2589
208k
    *pslot = slot;
2590
208k
    *slot = *bits;
2591
208k
    tile->data = data = (byte *)(slot + 1);
2592
#ifdef DEBUG
2593
    slot->index = pcls->tile_index;
2594
#endif
2595
208k
    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
208k
    } 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
53.1k
        stream_cursor_read r;
2605
53.1k
        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
53.1k
        uint cleft = pcb->end - cbp;
2611
2612
53.1k
        if (cleft < bytes && !pcb->end_status) {
2613
725
            uint nread = cbuf_size - cleft;
2614
2615
725
            advance_buffer(pcb, cbp);
2616
725
            pcb->end_status = sgets(pcb->s, pcb->data + cleft, nread, &nread);
2617
725
            set_cb_end(pcb, pcb->data + cleft + nread);
2618
725
            cbp = pcb->data;
2619
725
        }
2620
53.1k
        r.ptr = cbp - 1;
2621
53.1k
        r.limit = pcb->end - 1;
2622
53.1k
        w.ptr = data - 1;
2623
53.1k
        w.limit = w.ptr + bytes;
2624
53.1k
        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
53.1k
        case cmd_compress_cfe:
2635
53.1k
            {
2636
53.1k
                stream_CFD_state sstate;
2637
2638
53.1k
                clist_cfd_init(&sstate,
2639
53.1k
                               width_bytes << 3 /*width_bits */ ,
2640
53.1k
                               rep_height, mem);
2641
53.1k
                (*s_CFD_template.process)
2642
53.1k
                    ((stream_state *)&sstate, &r, &w, true);
2643
53.1k
                (*s_CFD_template.release)
2644
53.1k
                    ((stream_state *)&sstate);
2645
53.1k
            }
2646
53.1k
            break;
2647
0
        default:
2648
0
            return_error(gs_error_unregistered);
2649
53.1k
        }
2650
53.1k
        cbp = r.ptr + 1;
2651
155k
    } else if (rep_height * bits->num_planes > 1 && width_bytes != bits->raster) {
2652
154k
        cbp = cmd_read_short_bits(pcb, data, bytes,
2653
154k
                                  width_bytes, rep_height * bits->num_planes,
2654
154k
                                  bits->raster, cbp);
2655
154k
    } else {
2656
980
        cbp = cmd_read_data(pcb, data, bytes, cbp);
2657
980
    }
2658
208k
    if (bits->width > rep_width)
2659
2.99k
        bits_replicate_horizontally(data,
2660
2.99k
                                    rep_width * depth, rep_height * bits->num_planes,
2661
2.99k
                                    bits->raster,
2662
2.99k
                                    bits->width * depth,
2663
2.99k
                                    bits->raster);
2664
208k
    if (bits->height > rep_height)
2665
634
        bits_replicate_vertically(data,
2666
634
                                  rep_height, bits->raster,
2667
634
                                  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
208k
    pcb->ptr = cbp;
2673
208k
    return 0;
2674
208k
}
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
121k
{
2680
    /* free the existing buffer, if any (usually none) */
2681
121k
    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
121k
    if (ht_size > cbuf_ht_seg_max_size) {
2691
121k
        pht_buff->pbuff = gs_alloc_bytes(mem, ht_size, "read_alloc_ht_buff");
2692
121k
        if (pht_buff->pbuff == 0)
2693
0
            return_error(gs_error_VMerror);
2694
121k
    }
2695
121k
    pht_buff->ht_size = ht_size;
2696
121k
    pht_buff->read_size = 0;
2697
121k
    pht_buff->pcurr = pht_buff->pbuff;
2698
121k
    return 0;
2699
121k
}
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
242k
{
2710
242k
    const byte *                cbp = pcb->ptr;
2711
242k
    const byte *                pbuff = 0;
2712
242k
    uint                        ht_size = pht_buff->ht_size, seg_size;
2713
242k
    int                         code = 0;
2714
2715
    /* get the segment size; refill command buffer if necessary */
2716
242k
    enc_u_getw(seg_size, cbp);
2717
242k
    if (pcb->warn_limit - cbp < (int)seg_size) { /* cbp can be past warn_limit */
2718
121k
        code = top_up_cbuf(pcb, &cbp);
2719
121k
        if (code < 0)
2720
0
            return code;
2721
121k
        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
121k
    }
2726
2727
242k
    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
242k
    } else {
2733
242k
        if (seg_size + pht_buff->read_size > pht_buff->ht_size)
2734
0
            return_error(gs_error_unknownerror);
2735
242k
        memcpy(pht_buff->pcurr, cbp, seg_size);
2736
242k
        pht_buff->pcurr += seg_size;
2737
242k
        if ((pht_buff->read_size += seg_size) == ht_size)
2738
121k
            pbuff = pht_buff->pbuff;
2739
242k
    }
2740
2741
    /* if everything has been read, convert back to a halftone */
2742
242k
    if (pbuff != 0) {
2743
121k
        code = gx_ht_read_and_install(pgs, dev, pbuff, ht_size, mem);
2744
2745
        /* release any buffered information */
2746
121k
        if (pht_buff->pbuff != 0) {
2747
121k
            gs_free_object(mem, pht_buff->pbuff, "read_alloc_ht_buff");
2748
121k
            pht_buff->pbuff = 0;
2749
121k
            pht_buff->pcurr = 0;
2750
121k
        }
2751
121k
        pht_buff->ht_size = 0;
2752
121k
        pht_buff->read_size = 0;
2753
121k
    }
2754
2755
    /* update the command buffer ponter */
2756
242k
    pcb->ptr = cbp + seg_size;
2757
2758
242k
    return code;
2759
242k
}
2760
2761
static int
2762
read_set_misc2(command_buf_t *pcb, gs_gstate *pgs, segment_notes *pnotes)
2763
115k
{
2764
115k
    const byte *cbp = pcb->ptr;
2765
115k
    uint mask, cb;
2766
2767
115k
    if_debug0m('L', pgs->memory, "\n");
2768
115k
    cmd_getw(mask, cbp);
2769
115k
    if (mask & cap_join_known) {
2770
10.2k
        cb = *cbp++;
2771
10.2k
        pgs->line_params.start_cap = (gs_line_cap)((cb >> 3) & 7);
2772
10.2k
        pgs->line_params.join = (gs_line_join)(cb & 7);
2773
10.2k
        if_debug2m('L', pgs->memory, "[L]      start_cap=%d join=%d\n",
2774
10.2k
                   pgs->line_params.start_cap, pgs->line_params.join);
2775
10.2k
        cb = *cbp++;
2776
10.2k
        pgs->line_params.end_cap = (gs_line_cap)((cb >> 3) & 7);
2777
10.2k
        pgs->line_params.dash_cap = (gs_line_cap)(cb & 7);
2778
10.2k
        if_debug2m('L', pgs->memory, "[L]      end_cap=%d dash_cap=%d\n",
2779
10.2k
                   pgs->line_params.end_cap, pgs->line_params.dash_cap);
2780
10.2k
    }
2781
115k
    if (mask & cj_ac_sa_known) {
2782
2.37k
        cb = *cbp++;
2783
2.37k
        pgs->line_params.curve_join = ((cb >> 2) & 7) - 1;
2784
2.37k
        pgs->accurate_curves = (cb & 2) != 0;
2785
2.37k
        pgs->stroke_adjust = cb & 1;
2786
2.37k
        if_debug3m('L', pgs->memory, "[L]      CJ=%d AC=%d SA=%d\n",
2787
2.37k
                   pgs->line_params.curve_join, pgs->accurate_curves,
2788
2.37k
                   pgs->stroke_adjust);
2789
2.37k
    }
2790
115k
    if (mask & flatness_known) {
2791
67.3k
        cmd_get_value(pgs->flatness, cbp);
2792
67.3k
        if_debug1m('L', pgs->memory, "[L]      flatness=%g\n", pgs->flatness);
2793
67.3k
    }
2794
115k
    if (mask & line_width_known) {
2795
24.7k
        float width;
2796
2797
24.7k
        cmd_get_value(width, cbp);
2798
24.7k
        if_debug1m('L', pgs->memory, "[L]      line_width=%g\n", width);
2799
24.7k
        gx_set_line_width(&pgs->line_params, width);
2800
24.7k
    }
2801
115k
    if (mask & miter_limit_known) {
2802
1.32k
        float limit;
2803
2804
1.32k
        cmd_get_value(limit, cbp);
2805
1.32k
        if_debug1m('L', pgs->memory, "[L]      miter_limit=%g\n", limit);
2806
1.32k
        gx_set_miter_limit(&pgs->line_params, limit);
2807
1.32k
    }
2808
115k
    if (mask & op_bm_tk_known) {
2809
69.9k
        cb = *cbp++;
2810
69.9k
        pgs->blend_mode = cb >> 3;
2811
69.9k
        pgs->text_knockout = cb & 1;
2812
        /* the following usually have no effect; see gxclpath.c */
2813
69.9k
        cb = *cbp++;
2814
69.9k
        pgs->overprint_mode = (cb >> 2) & 1;
2815
69.9k
        pgs->stroke_overprint = (cb >> 1) & 1;
2816
69.9k
        pgs->overprint = cb & 1;
2817
69.9k
        cb = *cbp++;
2818
69.9k
        pgs->renderingintent = cb;
2819
69.9k
        if_debug6m('L', pgs->memory, "[L]      BM=%d TK=%d OPM=%d OP=%d op=%d RI=%d\n",
2820
69.9k
                   pgs->blend_mode, pgs->text_knockout, pgs->overprint_mode,
2821
69.9k
                   pgs->stroke_overprint, pgs->overprint, pgs->renderingintent);
2822
69.9k
    }
2823
115k
    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
115k
    if (mask & ais_known) {
2829
737
        cmd_get_value(pgs->alphaisshape, cbp);
2830
737
        if_debug1m('L', pgs->memory, "[L]      alphaisshape=%d\n", pgs->alphaisshape);
2831
737
    }
2832
115k
    if (mask & stroke_alpha_known) {
2833
8.47k
        cmd_get_value(pgs->strokeconstantalpha, cbp);
2834
8.47k
        if_debug1m('L', pgs->memory, "[L]      strokeconstantalpha=%g\n", pgs->strokeconstantalpha);
2835
8.47k
    }
2836
115k
    if (mask & fill_alpha_known) {
2837
10.1k
        cmd_get_value(pgs->fillconstantalpha, cbp);
2838
10.1k
        if_debug1m('L', pgs->memory, "[L]      fillconstantalpha=%u\n", (uint)(pgs->fillconstantalpha));
2839
10.1k
    }
2840
115k
    pcb->ptr = cbp;
2841
115k
    return 0;
2842
115k
}
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
14.3k
{
2848
14.3k
    const byte *cbp = pcb->ptr;
2849
14.3k
    byte b = *cbp++;
2850
14.3k
    int index = b >> 4;
2851
14.3k
    gs_color_space *pcs;
2852
14.3k
    int code = 0;
2853
14.3k
    cmm_profile_t *picc_profile;
2854
14.3k
    clist_icc_color_t icc_information;
2855
2856
14.3k
    if_debug3m('L', mem, " %d%s%s\n", index,
2857
14.3k
               (b & 8 ? " (indexed)" : ""),
2858
14.3k
               (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
14.3k
    memcpy(&icc_information, cbp, sizeof(clist_icc_color_t));
2864
14.3k
    cbp = cbp + sizeof(clist_icc_color_t);
2865
14.3k
    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
14.3k
    case gs_color_space_index_ICC:
2876
        /* build the color space object */
2877
14.3k
        code = gs_cspace_build_ICC(&pcs, NULL, mem);
2878
        /* Don't bother getting the ICC stuff from the clist yet */
2879
14.3k
        picc_profile = gsicc_profile_new(NULL, cdev->memory, NULL, 0);
2880
14.3k
        if (picc_profile == NULL)
2881
0
            return gs_rethrow(-1, "Failed to find ICC profile during clist read");
2882
14.3k
        picc_profile->num_comps = icc_information.icc_num_components;
2883
14.3k
        picc_profile->hashcode = icc_information.icc_hash;
2884
14.3k
        picc_profile->hash_is_valid = true;
2885
14.3k
        picc_profile->islab = icc_information.is_lab;
2886
14.3k
        picc_profile->default_match = icc_information.default_match;
2887
14.3k
        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
14.3k
        picc_profile->dev = (gx_device*) cdev;
2893
        /* Assign it to the colorspace */
2894
14.3k
        code = gsicc_set_gscs_profile(pcs, picc_profile, mem);
2895
        /* And we no longer need our reference to the profile */
2896
14.3k
        gsicc_adjust_profile_rc(picc_profile, -1, "read_set_color_space");
2897
14.3k
        break;
2898
0
    default:
2899
0
        code = gs_note_error(gs_error_rangecheck);      /* others are NYI */
2900
0
        goto out;
2901
14.3k
    }
2902
2903
14.3k
    if (pcs == NULL) {
2904
0
        code = gs_note_error(gs_error_VMerror);
2905
0
        goto out;
2906
0
    }
2907
2908
14.3k
    if (b & 8) {
2909
1.15k
        bool use_proc = (b & 4) != 0;
2910
1.15k
        int hival;
2911
1.15k
        int num_values;
2912
1.15k
        byte *data;
2913
1.15k
        uint data_size;
2914
1.15k
        gs_color_space *pcs_indexed;
2915
2916
1.15k
        pcs_indexed = gs_cspace_alloc(mem, &gs_color_space_type_Indexed);
2917
1.15k
        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.15k
        pcs_indexed->base_space = pcs;
2923
1.15k
        pcs = pcs_indexed;
2924
1.15k
        pcs->params.indexed.use_proc = 0;
2925
1.15k
        pcs->params.indexed.lookup.table.data = 0;
2926
1.15k
        pcs->params.indexed.lookup.table.size = 0;
2927
1.15k
        cmd_getw(hival, cbp);
2928
1.15k
        pcs->params.indexed.n_comps = gs_color_space_num_components(pcs->base_space);
2929
1.15k
        num_values = (hival + 1) * pcs->params.indexed.n_comps;
2930
1.15k
        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.15k
        } else {
2943
1.15k
            byte *table = gs_alloc_string(mem, num_values, "color_space indexed table");
2944
2945
1.15k
            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.15k
            pcs->params.indexed.lookup.table.data = table;
2951
1.15k
            pcs->params.indexed.lookup.table.size = num_values;
2952
1.15k
            data = table;
2953
1.15k
            data_size = num_values;
2954
1.15k
        }
2955
1.15k
        cbp = cmd_read_data(pcb, data, data_size, cbp);
2956
1.15k
        pcs->params.indexed.hival = hival;
2957
1.15k
        pcs->params.indexed.use_proc = use_proc;
2958
1.15k
    }
2959
2960
    /* Release reference to old color space before installing new one. */
2961
14.3k
    if (pgs->color[0].color_space != NULL)
2962
14.3k
        rc_decrement_only_cs(pgs->color[0].color_space, "read_set_color_space");
2963
14.3k
    pgs->color[0].color_space = pcs;
2964
14.3k
out:
2965
14.3k
    pcb->ptr = cbp;
2966
14.3k
    return code;
2967
14.3k
}
2968
2969
static int
2970
read_begin_image(command_buf_t *pcb, gs_image_common_t *pic,
2971
                 gs_color_space *pcs)
2972
26.1k
{
2973
26.1k
    uint index = *(pcb->ptr)++;
2974
26.1k
    const gx_image_type_t *image_type = gx_image_type_table[index];
2975
26.1k
    stream s;
2976
26.1k
    int code;
2977
2978
    /* This is sloppy, but we don't have enough information to do better. */
2979
26.1k
    code = top_up_cbuf(pcb, &pcb->ptr);
2980
26.1k
    if (code < 0)
2981
0
        return code;
2982
26.1k
    s_init(&s, NULL);
2983
26.1k
    sread_string(&s, pcb->ptr, pcb->end - pcb->ptr);
2984
26.1k
    code = image_type->sget(pic, &s, pcs);
2985
26.1k
    pcb->ptr = sbufptr(&s);
2986
26.1k
    pic->imagematrices_are_untrustworthy = 0;
2987
26.1k
    return code;
2988
26.1k
}
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
2.23M
{
3086
2.23M
    const byte *                cbp = pcb->ptr;
3087
2.23M
    int                         comp_id = 0, code = 0;
3088
2.23M
    const gs_composite_type_t * pcomp_type = 0;
3089
3090
    /* fill the command buffer (see comment above) */
3091
2.23M
    if (pcb->end - cbp < MAX_CLIST_COMPOSITOR_SIZE + sizeof(comp_id)) {
3092
142k
        code = top_up_cbuf(pcb, &cbp);
3093
142k
        if (code < 0)
3094
0
            return code;
3095
142k
    }
3096
3097
    /* find the appropriate compositor method vector */
3098
2.23M
    comp_id = *cbp++;
3099
2.23M
    if ((pcomp_type = gs_find_compositor(comp_id)) == 0)
3100
0
        return_error(gs_error_unknownerror);
3101
3102
    /* de-serialize the compositor */
3103
2.23M
    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
2.23M
    if ( code > MAX_CLIST_COMPOSITOR_SIZE )
3107
0
        return_error(gs_error_rangecheck);
3108
3109
2.23M
    if (code > 0)
3110
2.23M
        cbp += code;
3111
2.23M
    pcb->ptr = cbp;
3112
2.23M
    return code;
3113
2.23M
}
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
1.44M
{
3119
1.44M
    gx_device *tdev = *ptarget;
3120
1.44M
    int code;
3121
3122
1.44M
    code = pcomp->type->procs.adjust_ctm(pcomp, x0, y0, pgs);
3123
1.44M
    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
1.44M
    code = dev_proc(tdev, composite)(tdev, &tdev, pcomp, pgs, mem, (gx_device*) cdev);
3130
1.44M
    if (code == 1) {
3131
        /* A new compositor was created that wrapped tdev. This should
3132
         * be our new target. */
3133
98.8k
        *ptarget = tdev;
3134
98.8k
        code = 0;
3135
98.8k
    }
3136
1.44M
    if (code < 0)
3137
0
        goto exit;
3138
3139
    /* Perform any updates for the clist device required */
3140
1.44M
    code = pcomp->type->procs.clist_compositor_read_update(pcomp,
3141
1.44M
                                        (gx_device *)cdev, tdev, pgs, mem);
3142
1.44M
exit:
3143
    /* free the compositor object */
3144
1.44M
    gs_free_object(mem, pcomp, "read_composite");
3145
3146
1.44M
    return code;
3147
1.44M
}
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
194k
{
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
194k
    cbp = cmd_read_data(pcb, data, tot_bytes, cbp);
3166
3167
    /* if needed, adjust buffer contents for dest raster > width_bytes */
3168
194k
    if (width_bytes < raster) {
3169
193k
        const byte *pdata = data /*src*/ + width_bytes * height;
3170
193k
        byte *udata = data /*dest*/ + height * raster;
3171
3172
2.42M
        while (--height > 0) { /* don't need to move the first line to itself */
3173
2.23M
            udata -= raster, pdata -= width_bytes;
3174
2.23M
            switch (width_bytes) {
3175
0
                default:
3176
0
                    memmove(udata, pdata, width_bytes);
3177
0
                    break;
3178
5.30k
                case 6:
3179
5.30k
                    udata[5] = pdata[5];
3180
12.9k
                case 5:
3181
12.9k
                    udata[4] = pdata[4];
3182
42.6k
                case 4:
3183
42.6k
                    udata[3] = pdata[3];
3184
467k
                case 3:
3185
467k
                    udata[2] = pdata[2];
3186
1.84M
                case 2:
3187
1.84M
                    udata[1] = pdata[1];
3188
2.23M
                case 1:
3189
2.23M
                    udata[0] = pdata[0];
3190
2.23M
                case 0:;            /* shouldn't happen */
3191
2.23M
            }
3192
2.23M
        }
3193
193k
    }
3194
194k
    return cbp;
3195
194k
}
3196
3197
/* Read a rectangle. */
3198
static const byte *
3199
cmd_read_rect(int op, gx_cmd_rect * prect, const byte * cbp)
3200
5.26M
{
3201
5.26M
    cmd_getw(prect->x, cbp);
3202
5.26M
    if (op & 0xf)
3203
27.1k
        prect->y += ((op >> 2) & 3) - 2;
3204
5.23M
    else {
3205
5.23M
        cmd_getw(prect->y, cbp);
3206
5.23M
    }
3207
5.26M
    cmd_getw(prect->width, cbp);
3208
5.26M
    if (op & 0xf)
3209
27.1k
        prect->height += (op & 3) - 2;
3210
5.23M
    else {
3211
5.23M
        cmd_getw(prect->height, cbp);
3212
5.23M
    }
3213
5.26M
    return cbp;
3214
5.26M
}
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
356k
{
3232
356k
    gx_transfer_map *map;
3233
356k
    gx_transfer_map **pmap;
3234
356k
    const char *cname;
3235
3236
356k
    *pcomp_num = NULL;          /* Only used for color transfer maps */
3237
356k
    switch (map_index) {
3238
118k
        case cmd_map_transfer:
3239
118k
            if_debug0m('L', mem, " transfer");
3240
118k
            rc_unshare_struct(pgs->set_transfer.gray, gx_transfer_map,
3241
118k
                &st_transfer_map, mem, return_error(gs_error_VMerror),
3242
118k
                "cmd_select_map(default_transfer)");
3243
118k
            map = pgs->set_transfer.gray;
3244
            /* Release all current maps */
3245
118k
            rc_decrement(pgs->set_transfer.red, "cmd_select_map(red)");
3246
118k
            pgs->set_transfer.red = NULL;
3247
118k
            pgs->set_transfer.red_component_num = -1;
3248
118k
            rc_decrement(pgs->set_transfer.green, "cmd_select_map(green)");
3249
118k
            pgs->set_transfer.green = NULL;
3250
118k
            pgs->set_transfer.green_component_num = -1;
3251
118k
            rc_decrement(pgs->set_transfer.blue, "cmd_select_map(blue)");
3252
118k
            pgs->set_transfer.blue = NULL;
3253
118k
            pgs->set_transfer.blue_component_num = -1;
3254
118k
            goto transfer2;
3255
12
        case cmd_map_transfer_0:
3256
12
            pmap = &pgs->set_transfer.red;
3257
12
            *pcomp_num = &pgs->set_transfer.red_component_num;
3258
12
            goto transfer1;
3259
12
        case cmd_map_transfer_1:
3260
12
            pmap = &pgs->set_transfer.green;
3261
12
            *pcomp_num = &pgs->set_transfer.green_component_num;
3262
12
            goto transfer1;
3263
12
        case cmd_map_transfer_2:
3264
12
            pmap = &pgs->set_transfer.blue;
3265
12
            *pcomp_num = &pgs->set_transfer.blue_component_num;
3266
12
            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
36
transfer1:  if_debug1m('L', mem, " transfer[%d]", (int)(map_index - cmd_map_transfer_0));
3271
36
            rc_unshare_struct(*pmap, gx_transfer_map, &st_transfer_map, mem,
3272
36
                return_error(gs_error_VMerror), "cmd_select_map(transfer)");
3273
36
            map = *pmap;
3274
3275
118k
transfer2:  if (cont != cmd_map_other) {
3276
0
                gx_set_identity_transfer(map);
3277
0
                *pmdata = 0;
3278
0
                *pcount = 0;
3279
0
                return 0;
3280
0
            }
3281
118k
            break;
3282
118k
        case cmd_map_black_generation:
3283
118k
            if_debug0m('L', mem, " black generation");
3284
118k
            pmap = &pgs->black_generation;
3285
118k
            cname = "cmd_select_map(black generation)";
3286
118k
            goto alloc;
3287
118k
        case cmd_map_undercolor_removal:
3288
118k
            if_debug0m('L', mem, " undercolor removal");
3289
118k
            pmap = &pgs->undercolor_removal;
3290
118k
            cname = "cmd_select_map(undercolor removal)";
3291
237k
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
237k
            rc_unshare_struct(*pmap, gx_transfer_map, &st_transfer_map,
3299
237k
                              mem, return_error(gs_error_VMerror), cname);
3300
237k
            map = *pmap;
3301
237k
            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
237k
            break;
3308
237k
        default:
3309
0
            *pmdata = 0;
3310
0
            return 0;
3311
356k
    }
3312
356k
    map->proc = gs_mapped_transfer;
3313
356k
    *pmdata = map->values;
3314
356k
    *pcount = sizeof(map->values);
3315
356k
    return 0;
3316
356k
}
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
16.3M
{
3401
16.3M
    fixed px = ppos->x - int2fixed(x0);
3402
16.3M
    fixed py = ppos->y - int2fixed(y0);
3403
16.3M
    int code;
3404
3405
25.4M
#define A vs[0]
3406
21.0M
#define B vs[1]
3407
16.9M
#define C vs[2]
3408
16.3M
#define D vs[3]
3409
19.7M
#define E vs[4]
3410
19.7M
#define F vs[5]
3411
3412
16.3M
    switch (op) {
3413
1.97M
        case cmd_opv_rmoveto:
3414
1.97M
            code = gx_path_add_point(ppath, px += A, py += B);
3415
1.97M
            break;
3416
1.18M
        case cmd_opv_rlineto:
3417
1.18M
            code = gx_path_add_line_notes(ppath, px += A, py += B, notes);
3418
1.18M
            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
2.26M
        case cmd_opv_hlineto:
3423
2.26M
            code = gx_path_add_line_notes(ppath, px += A, py, notes);
3424
2.26M
            break;
3425
3.24M
        case cmd_opv_vlineto:
3426
3.24M
            code = gx_path_add_line_notes(ppath, px, py += A, notes);
3427
3.24M
            break;
3428
88.6k
        case cmd_opv_rmlineto:
3429
88.6k
            if ((code = gx_path_add_point(ppath, px += A, py += B)) < 0)
3430
0
                break;
3431
88.6k
            code = gx_path_add_line_notes(ppath, px += C, py += D, notes);
3432
88.6k
            break;
3433
37.9k
        case cmd_opv_rm2lineto:
3434
37.9k
            if ((code = gx_path_add_point(ppath, px += A, py += B)) < 0 ||
3435
37.9k
                (code = gx_path_add_line_notes(ppath, px += C, py += D,
3436
37.9k
                                               notes)) < 0
3437
37.9k
                )
3438
0
                break;
3439
37.9k
            code = gx_path_add_line_notes(ppath, px += E, py += F, notes);
3440
37.9k
            break;
3441
16.8k
        case cmd_opv_rm3lineto:
3442
16.8k
            if ((code = gx_path_add_point(ppath, px += A, py += B)) < 0 ||
3443
16.8k
                (code = gx_path_add_line_notes(ppath, px += C, py += D,
3444
16.8k
                                               notes)) < 0 ||
3445
16.8k
                (code = gx_path_add_line_notes(ppath, px += E, py += F,
3446
16.8k
                                               notes)) < 0
3447
16.8k
                )
3448
0
                break;
3449
16.8k
            code = gx_path_add_line_notes(ppath, px -= C, py -= D, notes);
3450
16.8k
            break;
3451
4.15M
        case cmd_opv_rrcurveto: /* a b c d e f => a b a+c b+d a+c+e b+d+f */
3452
4.15M
rrc:        E += (C += A);
3453
4.15M
            F += (D += B);
3454
6.56M
curve:      code = gx_path_add_curve_notes(ppath, px + A, py + B,
3455
6.56M
                                           px + C, py + D,
3456
6.56M
                                           px + E, py + F, notes);
3457
6.56M
            px += E, py += F;
3458
6.56M
            break;
3459
1.18M
        case cmd_opv_hvcurveto: /* a b c d => a 0 a+b c a+b c+d */
3460
1.19M
hvc:        F = C + D, D = C, E = C = A + B, B = 0;
3461
1.19M
            goto curve;
3462
1.20M
        case cmd_opv_vhcurveto: /* a b c d => 0 a b a+c b+d a+c */
3463
1.21M
vhc:        E = B + D, F = D = A + C, C = B, B = A, A = 0;
3464
1.21M
            goto curve;
3465
360
        case cmd_opv_nrcurveto: /* a b c d => 0 0 a b a+c b+d */
3466
360
            F = B + D, E = A + C, D = B, C = A, B = A = 0;
3467
360
            goto curve;
3468
443
        case cmd_opv_rncurveto: /* a b c d => a b a+c b+d a+c b+d */
3469
443
            F = D += B, E = C += A;
3470
443
            goto curve;
3471
10.8k
        case cmd_opv_vqcurveto: /* a b => VH a b TS(a,b) TS(b,a) */
3472
10.8k
            if ((A ^ B) < 0)
3473
2.92k
                C = -B, D = -A;
3474
7.94k
            else
3475
7.94k
                C = B, D = A;
3476
10.8k
            goto vhc;
3477
4.82k
        case cmd_opv_hqcurveto: /* a b => HV a TS(a,b) b TS(b,a) */
3478
4.82k
            if ((A ^ B) < 0)
3479
924
                D = -A, C = B, B = -B;
3480
3.90k
            else
3481
3.90k
                D = A, C = B;
3482
4.82k
            goto hvc;
3483
2.84k
        case cmd_opv_scurveto: /* (a b c d e f) => */
3484
2.84k
            {
3485
2.84k
                fixed a = A, b = B;
3486
3487
                /* See gxclpath.h for details on the following. */
3488
2.84k
                if (A == 0) {
3489
                    /* Previous curve was vh or vv */
3490
1.64k
                    A = E - C, B = D - F, C = C - a, D = b - D, E = a, F = -b;
3491
1.64k
                } else {
3492
                    /* Previous curve was hv or hh */
3493
1.20k
                    A = C - E, B = F - D, C = a - C, D = D - b, E = -a, F = b;
3494
1.20k
                }
3495
2.84k
            }
3496
2.84k
            goto rrc;
3497
1.00M
        case cmd_opv_closepath:
3498
1.00M
            if ((code = gx_path_close_subpath(ppath)) < 0)
3499
1.00M
                return code;;
3500
1.00M
            if ((code = gx_path_current_point(ppath, (gs_fixed_point *) vs)) < 0)
3501
1.00M
                return code;;
3502
1.00M
            px = A, py = B;
3503
1.00M
            break;
3504
0
        default:
3505
0
            return_error(gs_error_rangecheck);
3506
16.3M
    }
3507
16.3M
#undef A
3508
16.3M
#undef B
3509
16.3M
#undef C
3510
16.3M
#undef D
3511
16.3M
#undef E
3512
16.3M
#undef F
3513
16.3M
    ppos->x = px + int2fixed(x0);
3514
16.3M
    ppos->y = py + int2fixed(y0);
3515
16.3M
    return code;
3516
16.3M
}
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
17.9k
{
3530
17.9k
    const subpath *psub = ppath->first_subpath;
3531
17.9k
    const segment *pseg1;
3532
17.9k
    const segment *pseg2;
3533
17.9k
    int code;
3534
3535
17.9k
    if (psub && (pseg1 = psub->next) != 0 && (pseg2 = pseg1->next) != 0) {
3536
17.9k
        fixed px = psub->pt.x, py = psub->pt.y;
3537
17.9k
        fixed ax = pseg1->pt.x - px, ay = pseg1->pt.y - py;
3538
17.9k
        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
17.9k
        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
17.9k
        if (pseg2->next && !(px == pseg2->next->pt.x && py == pseg2->next->pt.y)) {
3548
            /* Parallelogram */
3549
17.8k
            fill = dev_proc(dev, fill_parallelogram);
3550
17.8k
            bx = pseg2->pt.x - pseg1->pt.x;
3551
17.8k
            by = pseg2->pt.y - pseg1->pt.y;
3552
17.8k
        } else {
3553
            /* Triangle */
3554
24
            fill = dev_proc(dev, fill_triangle);
3555
24
            bx = pseg2->pt.x - px;
3556
24
            by = pseg2->pt.y - py;
3557
24
        }
3558
17.9k
        code = fill(dev, px, py, ax, ay, bx, by, pdcolor, lop);
3559
17.9k
    } else
3560
0
        code = 0;
3561
17.9k
    gx_path_new(ppath);
3562
17.9k
    return code;
3563
17.9k
}