Coverage Report

Created: 2025-06-10 07:15

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