Coverage Report

Created: 2025-06-10 06:59

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