Coverage Report

Created: 2025-06-10 07:26

/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
221M
  BEGIN\
91
221M
    if ( *p < 0x80 ) var = *p++;\
92
221M
    else { const byte *_cbp; var = cmd_get_w(p, &_cbp); p = _cbp; }\
93
221M
  END
94
95
static long
96
cmd_get_w(const byte * p, const byte ** rp)
97
186M
{
98
186M
    int val = *p++ & 0x7f;
99
186M
    int shift = 7;
100
101
358M
    for (; val |= (int)(*p & 0x7f) << shift, *p++ > 0x7f; shift += 7);
102
186M
    *rp = p;
103
186M
    return val;
104
186M
}
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
9.45M
{
144
9.45M
    pcb->end = end;
145
9.45M
    pcb->warn_limit = pcb->data + (pcb->size - cmd_largest_size + 1);
146
9.45M
    if ( pcb->warn_limit > pcb->end )
147
276k
        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
9.45M
}
151
152
static inline void
153
advance_buffer(command_buf_t *pcb, const byte *cbp)
154
9.17M
{
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
9.17M
    memmove(pcb->data, cbp, pcb->end - cbp);
161
9.17M
}
162
163
static inline void
164
next_is_skip(command_buf_t *pcb)
165
2.34k
{
166
#ifdef DEBUG
167
    stream_state *st = pcb->s->state;
168
169
    offset_map_next_data_out_of_band(st);
170
#endif
171
2.34k
}
172
173
/* Read more data into a command buffer. */
174
static int
175
top_up_cbuf(command_buf_t *pcb, const byte **pcbp)
176
9.40M
{
177
9.40M
    uint nread;
178
9.40M
    const byte *cbp = *pcbp;
179
9.40M
    byte *cb_top = pcb->data + (pcb->end - cbp);
180
181
9.40M
    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
9.40M
    if (seofp(pcb->s)) {
187
        /* Can't use offset_map, because s_close resets s->state. Don't top up. */
188
237k
        pcb->end_status = pcb->s->end_status;
189
237k
        return 0;
190
237k
    }
191
9.16M
    advance_buffer(pcb, cbp);
192
9.16M
    nread = pcb->end - cb_top;
193
9.16M
    pcb->end_status = sgets(pcb->s, cb_top, nread, &nread);
194
9.16M
    if ( nread == 0 ) {
195
        /* No data for this band at all. */
196
1
        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
1
        *cb_top = cmd_opv_end_run;
203
1
        nread = 1;
204
1
    }
205
9.16M
    set_cb_end(pcb, cb_top + nread);
206
9.16M
    process_interrupts(pcb->s->memory);
207
9.16M
    *pcbp = pcb->data;
208
9.16M
    return 0;
209
9.16M
}
210
211
/* Read data from the command buffer and stream. */
212
/* From the command_buffer pcb, read rsize bytes to ptr, starting from cbp.
213
 * Return the new value for pcb->ptr. */
214
static const byte *
215
cmd_read_data(command_buf_t *pcb, byte *ptr, uint rsize, const byte *cbp)
216
4.14M
{
217
4.14M
    if (pcb->end - cbp >= rsize) {
218
4.14M
        memmove(ptr, cbp, rsize);
219
4.14M
        return cbp + rsize;
220
4.14M
    } else {
221
1.11k
        uint cleft = pcb->end - cbp;
222
1.11k
        uint rleft = rsize - cleft;
223
224
1.11k
        memmove(ptr, cbp, cleft);
225
1.11k
        sgets(pcb->s, ptr + cleft, rleft, &rleft);
226
#ifdef DEBUG
227
        {
228
            stream_state *st = pcb->s->state;
229
230
            adjust_offset_map_for_skipped_data(st, (uint)(pcb->end - pcb->data), rleft);
231
        }
232
#endif
233
1.11k
        return pcb->end;
234
1.11k
    }
235
4.14M
}
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
403k
{
241
403k
    memcpy(pvar, cbp, var_size);
242
403k
    return cbp + var_size;
243
403k
}
244
#define cmd_get_value(var, cbp)\
245
403k
  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
26.5M
{
304
26.5M
    if (*ppcomp_last == NULL) {
305
2.29M
        pcomp->prev = pcomp->next = NULL;
306
2.29M
        *ppcomp_last = *ppcomp_first = pcomp;
307
24.2M
    } else {
308
24.2M
        (*ppcomp_last)->next = pcomp;
309
24.2M
        pcomp->prev = *ppcomp_last;
310
24.2M
        pcomp->next = NULL;
311
24.2M
        *ppcomp_last = pcomp;
312
24.2M
    }
313
26.5M
}
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
26.5M
{
350
26.5M
    if (*ppcomp_last == *ppcomp_first) {
351
2.29M
        if (*ppcomp_last == pcomp) {
352
2.29M
            *ppcomp_last = *ppcomp_first = NULL;
353
2.29M
            return 0;
354
2.29M
        } else
355
0
            return_error(gs_error_unregistered); /* Must not happen. */
356
24.2M
    } else {
357
24.2M
        gs_composite_t *pcomp_next = pcomp->next, *pcomp_prev = pcomp->prev;
358
359
24.2M
        if (*ppcomp_last == pcomp)
360
2.27M
            *ppcomp_last = pcomp->prev;
361
22.0M
        else
362
22.0M
            pcomp_next->prev = pcomp_prev;
363
24.2M
        if (*ppcomp_first == pcomp)
364
22.0M
            *ppcomp_first = pcomp->next;
365
2.27M
        else
366
2.27M
            pcomp_prev->next = pcomp_next;
367
24.2M
        pcomp->next = pcomp->prev = NULL;
368
24.2M
        return 0;
369
24.2M
    }
370
26.5M
}
371
372
static inline void
373
free_compositor(gs_composite_t *pcomp, gs_memory_t *mem)
374
3.41M
{
375
3.41M
    gs_free_object(mem, pcomp, "free_compositor");
376
3.41M
}
377
378
static inline bool
379
is_null_compositor_op(const byte *cbp, int *length)
380
14.4M
{
381
14.4M
    if (cbp[0] == cmd_opv_end_run) {
382
13.0M
        *length = 1;
383
13.0M
        return true;
384
13.0M
    }
385
1.47M
    return false;
386
14.4M
}
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.22M
{
393
24.4M
    while (pcomp_from != NULL) {
394
23.1M
        gs_composite_t *pcomp = pcomp_from;
395
23.1M
        int code;
396
397
23.1M
        pcomp_from = pcomp->next;
398
23.1M
        code = dequeue_compositor(ppcomp_first, ppcomp_last, pcomp);
399
23.1M
        if (code < 0)
400
0
            return code;
401
23.1M
        pcomp->idle |= idle;
402
23.1M
        code = apply_composite(cdev, pgs, mem, pcomp, x0, y0, target); /* Releases the compositor. */
403
23.1M
        if (code < 0)
404
0
            return code;
405
23.1M
        *tdev = *target;
406
23.1M
    }
407
1.22M
    return 0;
408
1.22M
}
409
410
static void
411
mark_as_idle(gs_composite_t *pcomp_start, gs_composite_t *pcomp_end)
412
426k
{
413
426k
    gs_composite_t *pcomp = pcomp_start;
414
415
1.01M
    while (pcomp != NULL) {
416
1.01M
        pcomp->idle = true;
417
1.01M
        if (pcomp == pcomp_end)
418
426k
            break;
419
592k
        pcomp = pcomp->next;
420
592k
    }
421
426k
}
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
27.1k
{
428
27.1k
    gs_composite_t *pcomp;
429
430
169k
    do {
431
169k
        int code;
432
433
169k
        pcomp = *ppcomp_last;
434
169k
        if (pcomp == NULL)
435
0
            return 0;
436
169k
        dequeue_compositor(ppcomp_first, ppcomp_last, *ppcomp_last);
437
169k
        code = pcomp->type->procs.adjust_ctm(pcomp, x0, y0, pgs);
438
169k
        if (code < 0)
439
0
            return code;
440
169k
        free_compositor(pcomp, mem);
441
169k
    } while (pcomp != pcomp_from);
442
27.1k
    return 0;
443
27.1k
}
444
445
static int
446
read_set_misc_map(byte cb, command_buf_t *pcb, gs_gstate *pgs, gs_memory_t *mem)
447
684k
{
448
684k
    const byte *cbp = pcb->ptr;
449
684k
    frac *mdata;
450
684k
    int *pcomp_num;
451
684k
    uint count = 0;   /* quiet compiler */
452
684k
    cmd_map_contents cont =
453
684k
        (cmd_map_contents)(cb & 0x30) >> 4;
454
684k
    int code;
455
456
684k
    code = cmd_select_map(cb & 0xf, cont,
457
684k
                          pgs,
458
684k
                          &pcomp_num,
459
684k
                          &mdata, &count, mem);
460
461
684k
    if (code < 0)
462
0
        return code;
463
    /* Get component number if relevant */
464
684k
    if (pcomp_num == NULL)
465
684k
        cbp++;
466
18
    else {
467
18
        *pcomp_num = (int) *cbp++;
468
18
        if_debug1m('L', mem, " comp_num=%d", *pcomp_num);
469
18
    }
470
684k
    if (cont == cmd_map_other) {
471
684k
        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
684k
    }
485
    /* Recompute the effective transfer, */
486
    /* in case this was a transfer map. */
487
684k
    gx_gstate_set_effective_xfer(pgs);
488
684k
    pcb->ptr = cbp;
489
684k
    return 0;
490
684k
}
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
278k
{
516
278k
    byte *cbuf_storage;
517
278k
    command_buf_t cbuf;
518
    /* data_bits is for short copy_* bits and copy_* compressed, */
519
    /* must be aligned */
520
278k
    byte *data_bits = 0;
521
278k
    const byte *cbp;
522
278k
    int dev_depth;              /* May vary due to compositing devices */
523
278k
    int dev_depth_bytes;
524
278k
    int odd_delta_shift;
525
278k
    int num_zero_bytes;
526
278k
    gx_device *tdev;
527
278k
    gx_clist_state state;
528
278k
    gx_color_index *set_colors;
529
278k
    gx_device_color *set_dev_colors;
530
278k
    tile_slot *state_slot;
531
278k
    gx_strip_bitmap state_tile; /* parameters for reading tiles */
532
278k
    tile_slot tile_bits;        /* parameters of current tile */
533
278k
    gs_int_point tile_phase;
534
278k
    gx_path path;
535
278k
    bool in_path;
536
278k
    gs_fixed_point ppos;
537
278k
    gx_clip_path clip_path;
538
278k
    bool use_clip;
539
278k
    gx_clip_path *pcpath;
540
278k
    gx_device_cpath_accum clip_accum;
541
278k
    gs_fixed_rect target_box;
542
278k
    struct _cas {
543
278k
        bool lop_enabled;
544
278k
        gx_device_color dcolor;
545
278k
        gs_fixed_point fa_save;
546
278k
    } clip_save;
547
278k
    bool in_clip = false;
548
278k
    gs_gstate gs_gstate;
549
278k
    gx_device_color fill_color = { 0 };
550
278k
    gx_device_color stroke_color = { 0 };
551
278k
    float dash_pattern[cmd_max_dash];
552
278k
    gx_fill_params fill_params;
553
278k
    gx_stroke_params stroke_params;
554
#ifdef DEBUG
555
    gs_halftone_type halftone_type;
556
#endif
557
278k
    union im_ {
558
278k
        gs_image_common_t c;
559
278k
        gs_data_image_t d;
560
278k
        gs_image1_t i1;
561
278k
        gs_image4_t i4;
562
278k
    } image;
563
278k
    gs_int_rect image_rect;
564
278k
    gs_color_space *pcs = NULL;
565
278k
    gx_image_enum_common_t *image_info;
566
278k
    gx_image_plane_t planes[32];
567
278k
    uint data_height;
568
278k
    uint data_size;
569
278k
    byte *data_on_heap;
570
278k
    fixed vs[6];
571
278k
    segment_notes notes;
572
278k
    int data_x;
573
278k
    int code = 0;
574
278k
    ht_buff_t  ht_buff;
575
278k
    gx_device *const orig_target = target;
576
278k
    gx_device_clip clipper_dev;
577
278k
    bool clipper_dev_open = false;
578
278k
    patch_fill_state_t pfs;
579
278k
    int op = 0;
580
278k
    int plane_height = 0;
581
582
#ifdef DEBUG
583
    stream_state *st = s->state; /* Save because s_close resets s->state. */
584
#endif
585
278k
    gs_composite_t *pcomp_first = NULL, *pcomp_last = NULL;
586
278k
    tile_slot bits;             /* parameters for reading bits */
587
588
    /* pad the cbuf data area a bit (just in case) */
589
278k
    if ((cbuf_storage = gs_alloc_bytes(mem, cbuf_size + sizeof(double),
590
278k
                               "clist_playback_band(cbuf_storage)")) == NULL) {
591
0
        return_error(gs_error_VMerror);
592
0
    }
593
278k
    cbuf.data = (byte *)cbuf_storage;
594
278k
    cbuf.size = cbuf_size;
595
278k
    cbuf.s = s;
596
278k
    cbuf.end_status = 0;
597
278k
    set_cb_end(&cbuf, cbuf.data + cbuf.size);
598
278k
    cbp = cbuf.end;
599
600
278k
    pfs.dev = NULL; /* Indicate "not initialized". */
601
278k
    memset(&ht_buff, 0, sizeof(ht_buff));
602
603
    /* The following initializations are to quiet gcc warnings. */
604
278k
    memset(&bits, 0, sizeof(bits));
605
278k
    memset(&tile_bits, 0, sizeof(tile_bits));
606
278k
    memset(&clip_save, 0, sizeof(clip_save));
607
278k
    memset(&state_slot, 0, sizeof(state_slot));
608
278k
    ppos.x = ppos.y = 0;
609
610
278k
in:                             /* Initialize for a new page. */
611
278k
    tdev = target;
612
278k
    set_colors = state.colors;
613
278k
    set_dev_colors = state.tile_color_devn;
614
278k
    use_clip = false;
615
278k
    pcpath = NULL;
616
278k
    if (clipper_dev_open)
617
0
        gx_destroy_clip_device_on_stack(&clipper_dev);
618
278k
    clipper_dev_open = false;
619
278k
    notes = sn_none;
620
278k
    data_x = 0;
621
278k
    {
622
278k
        static const gx_clist_state cls_initial = { cls_initial_values };
623
624
278k
        state = cls_initial;
625
278k
    }
626
278k
    state_tile.id = gx_no_bitmap_id;
627
278k
    state_tile.shift = state_tile.rep_shift = 0;
628
278k
    state_tile.size.x = state_tile.size.y = 0;
629
278k
    state_tile.num_planes = 1;
630
278k
    tile_phase.x = x0;
631
278k
    tile_phase.y = y0;
632
278k
    gx_path_init_local(&path, mem);
633
278k
    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
278k
    {
639
278k
        gs_fixed_rect cbox;
640
641
278k
        gx_cpath_init_local(&clip_path, mem);
642
278k
        cbox.p.x = 0;
643
278k
        cbox.p.y = 0;
644
278k
        cbox.q.x = cdev->width;
645
278k
        cbox.q.y = cdev->height;
646
278k
        gx_cpath_from_rectangle(&clip_path, &cbox);
647
278k
    }
648
278k
    if (target != 0)
649
278k
        (*dev_proc(target, get_clipping_box))(target, &target_box);
650
278k
    memset(&gs_gstate, 0, sizeof(gs_gstate));
651
278k
    GS_STATE_INIT_VALUES_CLIST((&gs_gstate));
652
278k
    code = gs_gstate_initialize(&gs_gstate, mem);
653
278k
    if (code < 0)
654
0
        goto out;
655
278k
    gs_gstate.device = tdev;
656
278k
    gs_gstate.view_clip = NULL; /* Avoid issues in pdf14 fill stroke */
657
278k
    gs_gstate.clip_path = &clip_path;
658
278k
    pcs = gs_cspace_new_DeviceGray(mem);
659
278k
    if (pcs == NULL) {
660
0
        code = gs_note_error(gs_error_VMerror);
661
0
        goto out;
662
0
    }
663
278k
    code = pcs->type->install_cspace(pcs, &gs_gstate);
664
278k
    if (code < 0) {
665
0
        rc_decrement(pcs, "clist_playback_band");
666
0
        goto out;
667
0
    }
668
278k
    gs_gstate.color[0].color_space = pcs; /* we already have one ref */
669
278k
    gs_gstate.color[1].color_space = pcs;
670
278k
    rc_increment_cs(pcs); /* increment for second ref */
671
    /* Initialize client color and device color */
672
278k
    gs_gstate.color[0].ccolor =
673
278k
        gs_alloc_struct(mem, gs_client_color, &st_client_color, "clist_playback_band");
674
278k
    gs_gstate.color[1].ccolor =
675
278k
        gs_alloc_struct(mem, gs_client_color, &st_client_color, "clist_playback_band");
676
278k
    gs_gstate.color[0].dev_color =
677
278k
        gs_alloc_struct(mem, gx_device_color, &st_device_color, "clist_playback_band");
678
278k
    gs_gstate.color[1].dev_color =
679
278k
        gs_alloc_struct(mem, gx_device_color, &st_device_color, "clist_playback_band");
680
278k
    if (gs_gstate.color[0].ccolor == 0 || gs_gstate.color[0].dev_color == 0 ||
681
278k
        gs_gstate.color[1].ccolor == 0 || gs_gstate.color[1].dev_color == 0
682
278k
        ) {
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
278k
    gs_gstate.color[0].color_space->pclient_color_space_data =
692
278k
        pcs->pclient_color_space_data;
693
278k
    cs_full_init_color(gs_gstate.color[0].ccolor, pcs);
694
278k
    gx_unset_dev_color(&gs_gstate);
695
696
278k
    gs_gstate.color[1].color_space->pclient_color_space_data =
697
278k
        pcs->pclient_color_space_data;
698
278k
    cs_full_init_color(gs_gstate.color[1].ccolor, pcs);
699
278k
    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
278k
    rc_decrement(gs_gstate.icc_link_cache,"clist_playback_band");
704
278k
    gs_gstate.icc_link_cache = cdev->icc_cache_cl;
705
    /* Need to lock during the increment of the link cache */
706
278k
    gx_monitor_enter(cdev->icc_cache_cl->lock);
707
278k
    rc_increment(cdev->icc_cache_cl);
708
278k
    gx_monitor_leave(cdev->icc_cache_cl->lock); /* let everyone run */
709
278k
    if (code < 0)
710
0
        goto out;
711
712
278k
    gs_gstate.line_params.dash.pattern = dash_pattern;
713
278k
    if (tdev != 0) {
714
278k
        gx_set_cmap_procs(&gs_gstate, tdev);
715
278k
    }
716
278k
    gx_gstate_setscreenphase(&gs_gstate, -x0, -y0, gs_color_select_all);
717
#ifdef DEBUG
718
    halftone_type = ht_type_none;
719
#endif
720
278k
    fill_color.ccolor_valid = false;
721
278k
    color_unset(&fill_color);
722
278k
    data_bits = gs_alloc_bytes(mem, data_bits_size,
723
278k
                               "clist_playback_band(data_bits)");
724
278k
    if (data_bits == 0) {
725
0
        code = gs_note_error(gs_error_VMerror);
726
0
        goto out;
727
0
    }
728
66.7M
    while (code >= 0) {
729
66.7M
        int compress;
730
66.7M
        int depth = 0x7badf00d; /* Initialize against indeterminizm. */
731
66.7M
        int raster = 0x7badf00d; /* Initialize against indeterminizm. */
732
66.7M
        byte *source = NULL;  /* Initialize against indeterminizm. */
733
66.7M
        gx_color_index colors[2];
734
66.7M
        gx_color_index *pcolor;
735
66.7M
        gx_device_color *pdcolor = NULL;
736
66.7M
        gs_logical_operation_t log_op;
737
738
        /* Make sure the buffer contains a full command. */
739
66.7M
        if (cbp >= cbuf.warn_limit) {
740
615k
            if (cbuf.end_status < 0) {  /* End of file or error. */
741
986
                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
614k
            } else {
747
614k
                code = top_up_cbuf(&cbuf, &cbp);
748
614k
                if (code < 0)
749
0
                    goto top_up_failed;
750
614k
            }
751
615k
        }
752
66.7M
        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
66.7M
        switch (op >> 4) {
762
7.74M
            case cmd_op_misc >> 4:
763
7.74M
                switch (op) {
764
1.53M
                    case cmd_opv_end_run:
765
1.53M
                        if_debug0m('L', mem, "\n");
766
1.53M
                        continue;
767
891
                    case cmd_opv_set_tile_size:
768
891
                        cbuf.ptr = cbp;
769
891
                        code = read_set_tile_size(&cbuf, &tile_bits,
770
891
                                    gx_device_is_pattern_clist((gx_device *)cdev));
771
891
                        cbp = cbuf.ptr;
772
891
                        if (code < 0)
773
0
                            goto out;
774
891
                        continue;
775
8.35k
                    case cmd_opv_set_tile_phase:
776
8.35k
                        cmd_getw(state.tile_phase.x, cbp);
777
8.35k
                        cmd_getw(state.tile_phase.y, cbp);
778
8.35k
                        if_debug2m('L', mem, " (%d,%d)\n",
779
8.35k
                                   state.tile_phase.x,
780
8.35k
                                   state.tile_phase.y);
781
8.35k
                        goto set_tile_phase;
782
24.4k
                    case cmd_opv_set_screen_phaseT:
783
24.4k
                        cmd_getw(state.screen_phase[gs_color_select_texture].x, cbp);
784
24.4k
                        cmd_getw(state.screen_phase[gs_color_select_texture].y, cbp);
785
24.4k
                        if_debug2m('L', mem, " (%d,%d)\n",
786
24.4k
                                   state.screen_phase[0].x,
787
24.4k
                                   state.screen_phase[gs_color_select_texture].y);
788
24.4k
                        gx_gstate_setscreenphase(&gs_gstate,
789
24.4k
                                                 state.screen_phase[gs_color_select_texture].x - x0,
790
24.4k
                                                 state.screen_phase[gs_color_select_texture].y - y0,
791
24.4k
                                                 gs_color_select_texture);
792
24.4k
                        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
6.10k
                    case cmd_opv_set_tile_bits:
805
6.10k
                        bits = tile_bits;
806
6.10k
                        compress = 0;
807
1.85M
                      stb:
808
1.85M
                        cbuf.ptr = cbp;
809
1.85M
                        code = read_set_bits(&cbuf, &bits, compress,
810
1.85M
                                             &state, &state_tile, &state_slot,
811
1.85M
                                             cdev, mem);
812
1.85M
                        cbp = cbuf.ptr;
813
1.85M
                        if (code < 0)
814
0
                            goto out;
815
1.85M
                        goto stp;
816
1.85M
                    case cmd_opv_set_bits:
817
1.84M
do_opv_set_bits:
818
1.84M
                        compress = *cbp & 3;
819
1.84M
                        bits.head.depth = *cbp++ >> 2;
820
1.84M
                        cmd_getw(bits.width, cbp);
821
1.84M
                        cmd_getw(bits.height, cbp);
822
1.84M
                        if (op == cmd_opv_set_bits_planar)
823
1.84M
                            cmd_getw(bits.num_planes, cbp);
824
1.84M
                        else
825
1.84M
                            bits.num_planes = 1;
826
1.84M
                        if_debug5m('L', mem, " compress=%d depth=%d size=(%d,%d) planes=%d",
827
1.84M
                                   compress, bits.head.depth,
828
1.84M
                                   bits.width, bits.height, bits.num_planes);
829
1.84M
                        bits.raster =
830
1.84M
                            bitmap_raster(bits.width * bits.head.depth);
831
1.84M
                        bits.x_reps = bits.y_reps = 1;
832
1.84M
                        bits.shift = bits.rep_shift = 0;
833
1.84M
                        goto stb;
834
35.4k
                    case cmd_opv_set_tile_color:
835
35.4k
                        set_colors = state.tile_colors;
836
35.4k
                        if_debug0m('L', mem, "\n");
837
35.4k
                        continue;
838
942k
                    case cmd_opv_set_misc:
839
942k
                        {
840
942k
                            uint cb = *cbp++;
841
842
942k
                            switch (cb >> 6) {
843
98.5k
                                case cmd_set_misc_lop >> 6:
844
98.5k
                                    cmd_getw(state.lop, cbp);
845
98.5k
                                    state.lop = (state.lop << 6) + (cb & 0x3f);
846
98.5k
                                    if_debug1m('L', mem, " lop=0x%x\n", state.lop);
847
98.5k
                                    if (state.lop_enabled)
848
56.2k
                                        gs_gstate.log_op = state.lop;
849
98.5k
                                    break;
850
321k
                                case cmd_set_misc_data_x >> 6:
851
321k
                                    if (cb & 0x20)
852
321k
                                        cmd_getw(data_x, cbp);
853
321k
                                    else
854
321k
                                        data_x = 0;
855
321k
                                    data_x = (data_x << 5) + (cb & 0x1f);
856
321k
                                    if_debug1m('L', mem, " data_x=%d\n", data_x);
857
321k
                                    break;
858
522k
                                case cmd_set_misc_map >> 6:
859
522k
                                    cbuf.ptr = cbp;
860
522k
                                    code = read_set_misc_map(cb, &cbuf, &gs_gstate, mem);
861
522k
                                    if (code < 0)
862
0
                                        goto out;
863
522k
                                    cbp = cbuf.ptr;
864
522k
                                    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
942k
                            }
885
942k
                        }
886
942k
                        continue;
887
942k
                    case cmd_opv_enable_lop:
888
42.2k
                        state.lop_enabled = true;
889
42.2k
                        gs_gstate.log_op = state.lop;
890
42.2k
                        if_debug0m('L', mem, "\n");
891
42.2k
                        continue;
892
33.6k
                    case cmd_opv_disable_lop:
893
33.6k
                        state.lop_enabled = false;
894
33.6k
                        gs_gstate.log_op = lop_default;
895
33.6k
                        if_debug0m('L', mem, "\n");
896
33.6k
                        continue;
897
278k
                    case cmd_opv_end_page:
898
278k
                        if_debug0m('L', mem, "\n");
899
                        /*
900
                         * Do end-of-page cleanup, then reinitialize if
901
                         * there are more pages to come.
902
                         */
903
278k
                        goto out;
904
0
                    case cmd_opv_delta_color0:
905
0
                        pcolor = &set_colors[0];
906
0
                        goto delta2_c;
907
2.98M
                    case cmd_opv_delta_color1:
908
2.98M
                        pcolor = &set_colors[1];
909
2.98M
                      delta2_c:set_colors = state.colors;
910
                        /* See comments for cmd_put_color() in gxclutil.c. */
911
2.98M
                        {
912
2.98M
                            gx_color_index delta = 0;
913
2.98M
                            uint data;
914
915
2.98M
                            dev_depth = (tdev->color_info.depth <= 8*sizeof(gx_color_index) ?
916
2.98M
                                         tdev->color_info.depth : 8*sizeof(gx_color_index));
917
2.98M
                            dev_depth_bytes = (dev_depth + 7) >> 3;
918
2.98M
                            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
921k
                                case 4:
931
921k
                                    data = *cbp++;
932
921k
                                    delta |= ((gx_color_index)
933
921k
                                        ((data & 0xf0) << 4) + (data & 0x0f)) << 16;
934
                                    /* fall through */
935
921k
                                case 2:
936
921k
                                    data = *cbp++;
937
921k
                                    delta |= ((gx_color_index)
938
921k
                                        ((data & 0xf0) << 4) + (data & 0x0f));
939
921k
                                    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.06M
                                case 3:
952
2.06M
                                    data = *cbp++;
953
2.06M
                                    odd_delta_shift = (dev_depth_bytes - 3) * 8;
954
2.06M
                                    delta |= ((gx_color_index)
955
2.06M
                                        ((data & 0xe0) << 3) + (data & 0x1f)) << odd_delta_shift;
956
2.06M
                                    data = *cbp++;
957
2.06M
                                    delta |= ((gx_color_index) ((data & 0xf8) << 2) + (data & 0x07))
958
2.06M
                                                        << (odd_delta_shift + 11);
959
2.98M
                            }
960
2.98M
                            *pcolor += delta - cmd_delta_offsets[dev_depth_bytes];
961
2.98M
                        }
962
2.98M
                        if (sizeof(*pcolor) <= sizeof(ulong))
963
2.98M
                            if_debug1m('L', mem, " 0x%lx\n", (ulong)*pcolor);
964
0
                        else
965
2.98M
                            if_debug2m('L', mem, " 0x%8lx%08lx\n",
966
2.98M
                                       (ulong)(*pcolor >> 8*(sizeof(*pcolor) - sizeof(ulong))), (ulong)*pcolor);
967
2.98M
                        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
7.74M
                }
979
                /*NOTREACHED */
980
18.3k
            case cmd_op_set_color0 >> 4:
981
18.3k
                pcolor = &set_colors[0];
982
18.3k
                goto set_color;
983
2.42M
            case cmd_op_set_color1 >> 4:
984
2.42M
                pcolor = &set_colors[1];
985
2.44M
              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
2.44M
                num_zero_bytes = op & 0x0f;
994
995
2.44M
                if (num_zero_bytes == cmd_no_color_index)
996
3
                    *pcolor = gx_no_color_index;
997
2.44M
                else {
998
2.44M
                    gx_color_index color = 0;
999
1000
2.44M
                    dev_depth = (tdev->color_info.depth < 8*sizeof(gx_color_index) ?
1001
2.44M
                                 tdev->color_info.depth : 8*sizeof(gx_color_index));
1002
2.44M
                    dev_depth_bytes = (dev_depth + 7) >> 3;
1003
2.44M
                    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
189k
                        case 4:
1013
189k
                            color = (color << 8) | (gx_color_index) * cbp++;
1014
951k
                        case 3:
1015
951k
                            color = (color << 8) | (gx_color_index) * cbp++;
1016
1.10M
                        case 2:
1017
1.10M
                            color = (color << 8) | (gx_color_index) * cbp++;
1018
2.28M
                        case 1:
1019
2.28M
                            color = (color << 8) | (gx_color_index) * cbp++;
1020
2.44M
                        default:
1021
2.44M
                            break;
1022
2.44M
                    }
1023
2.44M
                    color <<= num_zero_bytes * 8;
1024
2.44M
                    *pcolor = color;
1025
2.44M
                }
1026
2.44M
                if (sizeof(*pcolor) <= sizeof(ulong))
1027
2.44M
                    if_debug1m('L', mem, " 0x%lx\n", (ulong)*pcolor);
1028
0
                else
1029
2.44M
                    if_debug2m('L', mem, " 0x%8lx%08lx\n",
1030
2.44M
                               (ulong)(*pcolor >> 8*(sizeof(*pcolor) - sizeof(ulong))), (ulong)*pcolor);
1031
2.44M
                continue;
1032
720k
            case cmd_op_fill_rect >> 4:
1033
737k
            case cmd_op_tile_rect >> 4:
1034
737k
                cbp = cmd_read_rect(op, &state.rect, cbp);
1035
737k
                break;
1036
1.56M
            case cmd_op_fill_rect_short >> 4:
1037
1.71M
            case cmd_op_tile_rect_short >> 4:
1038
1.71M
                state.rect.x += *cbp + cmd_min_short;
1039
1.71M
                state.rect.width += cbp[1] + cmd_min_short;
1040
1.71M
                if (op & 0xf) {
1041
988k
                    state.rect.height += (op & 0xf) + cmd_min_dxy_tiny;
1042
988k
                    cbp += 2;
1043
988k
                } else {
1044
728k
                    state.rect.y += cbp[2] + cmd_min_short;
1045
728k
                    state.rect.height += cbp[3] + cmd_min_short;
1046
728k
                    cbp += 4;
1047
728k
                }
1048
1.71M
                break;
1049
7.93M
            case cmd_op_fill_rect_tiny >> 4:
1050
8.16M
            case cmd_op_tile_rect_tiny >> 4:
1051
8.16M
                if (op & 8)
1052
4.60M
                    state.rect.x += state.rect.width;
1053
3.56M
                else {
1054
3.56M
                    int txy = *cbp++;
1055
1056
3.56M
                    state.rect.x += (txy >> 4) + cmd_min_dxy_tiny;
1057
3.56M
                    state.rect.y += (txy & 0xf) + cmd_min_dxy_tiny;
1058
3.56M
                }
1059
8.16M
                state.rect.width += (op & 7) + cmd_min_dw_tiny;
1060
8.16M
                break;
1061
6.60M
            case cmd_op_copy_mono_planes >> 4:
1062
6.60M
                cmd_getw(plane_height, cbp);
1063
6.60M
                if (plane_height == 0) {
1064
                    /* We are doing a copy mono */
1065
6.60M
                    depth = 1;
1066
6.60M
                } else {
1067
0
                    depth = tdev->color_info.depth;
1068
0
                }
1069
6.60M
                if_debug1m('L', mem, " plane_height=0x%x", plane_height);
1070
6.60M
                goto copy;
1071
1.93M
            case cmd_op_copy_color_alpha >> 4:
1072
1.93M
                if (state.color_is_alpha) {
1073
0
                    if (!(op & 8))
1074
0
                        depth = *cbp++;
1075
0
                } else
1076
1.93M
                    depth = tdev->color_info.depth;
1077
1.93M
                plane_height = 0;
1078
8.53M
              copy:cmd_getw(state.rect.x, cbp);
1079
8.53M
                cmd_getw(state.rect.y, cbp);
1080
8.53M
                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
6.56M
                    depth = state_slot->head.depth;
1091
6.56M
                    state.rect.width = state_slot->width;
1092
6.56M
                    state.rect.height = state_slot->height;
1093
6.56M
                    if (state.rect.y + state.rect.height > cdev->height)
1094
2.87k
                        state.rect.height = cdev->height - state.rect.y; /* clamp as writer did */
1095
6.56M
                    raster = state_slot->raster;
1096
6.56M
                    source = (byte *) (state_slot + 1);
1097
6.56M
                } else {        /* Read width, height, bits. */
1098
                    /* depth was set already. */
1099
1.97M
                    uint width_bits, width_bytes;
1100
1.97M
                    uint bytes;
1101
1.97M
                    uchar planes = 1;
1102
1.97M
                    uint plane_depth = depth;
1103
1.97M
                    uint pln;
1104
1.97M
                    byte compression = op & 3;
1105
1.97M
                    uint out_bytes;
1106
1107
1.97M
                    cmd_getw(state.rect.width, cbp);
1108
1.97M
                    cmd_getw(state.rect.height, cbp);
1109
1.97M
                    if (plane_height != 0) {
1110
0
                        planes = tdev->color_info.num_components;
1111
0
                        plane_depth /= planes;
1112
0
                    }
1113
1.97M
                    width_bits = state.rect.width * plane_depth;
1114
1.97M
                    bytes = clist_bitmap_bytes(width_bits,
1115
1.97M
                                               state.rect.height,
1116
1.97M
                                               op & 3, &width_bytes,
1117
1.97M
                                               (uint *)&raster);
1118
1.97M
                    if (planes > 1) {
1119
0
                        out_bytes = raster * state.rect.height;
1120
0
                        plane_height = state.rect.height;
1121
1.97M
                    } else {
1122
1.97M
                        out_bytes = bytes;
1123
1.97M
                    }
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
3.94M
                    for (pln = 0; pln < planes; pln++) {
1139
1.97M
                        byte *plane_bits = data_bits + pln * plane_height * raster;
1140
1141
                        /* Fill the cbuf if needed to get the data for the plane */
1142
1.97M
                        if (cbp + out_bytes >= cbuf.warn_limit) {
1143
7.76k
                            code = top_up_cbuf(&cbuf, &cbp);
1144
7.76k
                            if (code < 0)
1145
0
                                goto top_up_failed;
1146
7.76k
                        }
1147
1.97M
                        if (pln)
1148
0
                            compression = *cbp++;
1149
1150
1.97M
                        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
1.97M
                        } else if (compression) {       /* Decompress the image data. */
1158
0
                            stream_cursor_read r;
1159
0
                            stream_cursor_write w;
1160
1161
                            /* We don't know the data length a priori, */
1162
                            /* so to be conservative, we read */
1163
                            /* the uncompressed size. */
1164
0
                            uint cleft = cbuf.end - cbp;
1165
1166
0
                            if (cleft < bytes  && !cbuf.end_status) {
1167
0
                                uint nread = cbuf_size - cleft;
1168
1169
0
                                advance_buffer(&cbuf, cbp);
1170
0
                                cbuf.end_status = sgets(s, cbuf.data + cleft, nread, &nread);
1171
0
                                set_cb_end(&cbuf, cbuf.data + cleft + nread);
1172
0
                                cbp = cbuf.data;
1173
0
                            }
1174
0
                            r.ptr = cbp - 1;
1175
0
                            r.limit = cbuf.end - 1;
1176
0
                            w.ptr = plane_bits - 1;
1177
0
                            w.limit = w.ptr + data_bits_size;
1178
0
                            switch (compression) {
1179
0
                                case cmd_compress_rle:
1180
0
                                    {
1181
0
                                        stream_RLD_state sstate;
1182
1183
0
                                        clist_rld_init(&sstate);
1184
                                        /* The process procedure can't fail. */
1185
0
                                        (*s_RLD_template.process)
1186
0
                                            ((stream_state *)&sstate, &r, &w, true);
1187
0
                                    }
1188
0
                                    break;
1189
0
                                case cmd_compress_cfe:
1190
0
                                    {
1191
0
                                        stream_CFD_state sstate;
1192
1193
0
                                        clist_cfd_init(&sstate,
1194
0
                                        width_bytes << 3 /*state.rect.width */ ,
1195
0
                                                       state.rect.height, mem);
1196
                                        /* The process procedure can't fail. */
1197
0
                                        (*s_CFD_template.process)
1198
0
                                            ((stream_state *)&sstate, &r, &w, true);
1199
0
                                        (*s_CFD_template.release)
1200
0
                                            ((stream_state *)&sstate);
1201
0
                                    }
1202
0
                                    break;
1203
0
                                default:
1204
0
                                    goto bad_op;
1205
0
                            }
1206
0
                            cbp = r.ptr + 1;
1207
0
                            if (pln == 0)
1208
0
                                source = data_bits;
1209
1.97M
                        } else if ((state.rect.height > 1 && width_bytes != raster) ||
1210
1.97M
                                   (plane_height != 0)) {
1211
33.8k
                            cbp = cmd_read_short_bits(&cbuf, plane_bits, bytes, width_bytes,
1212
33.8k
                                                      state.rect.height, raster, cbp);
1213
33.8k
                            if (pln == 0)
1214
33.8k
                                source = data_bits;
1215
1.94M
                        } else {
1216
                            /* Never used for planar data */
1217
1.94M
                            cbp = cmd_read_data(&cbuf, cbuf.data, bytes, cbp);
1218
1.94M
                            source = cbuf.data;
1219
1.94M
                        }
1220
1.97M
                    }
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
1.97M
                }
1230
8.53M
                break;
1231
8.53M
            case cmd_op_delta_tile_index >> 4:
1232
1.59M
                state.tile_index += (int)(op & 0xf) - 8;
1233
1.59M
                goto sti;
1234
3.04M
            case cmd_op_set_tile_index >> 4:
1235
3.04M
                state.tile_index =
1236
3.04M
                    ((op & 0xf) << 8) + *cbp++;
1237
4.63M
              sti:state_slot =
1238
4.63M
                    (tile_slot *) (cdev->cache_chunk->data +
1239
4.63M
                                 cdev->tile_table[state.tile_index].offset);
1240
4.63M
                if_debug2m('L', mem, " index=%u offset=%lu\n",
1241
4.63M
                           state.tile_index,
1242
4.63M
                           cdev->tile_table[state.tile_index].offset);
1243
4.63M
                state_tile.data = (byte *) (state_slot + 1);
1244
6.49M
              stp:state_tile.size.x = state_slot->width;
1245
6.49M
                state_tile.size.y = state_slot->height;
1246
6.49M
                state_tile.raster = state_slot->raster;
1247
6.49M
                state_tile.rep_width = state_tile.size.x /
1248
6.49M
                    state_slot->x_reps;
1249
6.49M
                state_tile.rep_height = state_tile.size.y /
1250
6.49M
                    state_slot->y_reps;
1251
6.49M
                state_tile.rep_shift = state_slot->rep_shift;
1252
6.49M
                state_tile.shift = state_slot->shift;
1253
6.49M
                state_tile.id = state_slot->id;
1254
6.49M
                state_tile.num_planes = state_slot->num_planes;
1255
6.49M
set_tile_phase:
1256
6.49M
                if (state_tile.size.x)
1257
6.49M
                    tile_phase.x =
1258
6.49M
                        (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
6.49M
                if (state_tile.size.y) {
1264
6.49M
                    int full_height;
1265
1266
6.49M
                    if (state_tile.shift == 0)
1267
6.49M
                        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
6.49M
                    tile_phase.y = (state.tile_phase.y + y0) % full_height;
1274
6.49M
                }
1275
6.49M
                continue;
1276
7.02M
            case cmd_op_misc2 >> 4:
1277
7.02M
                switch (op) {
1278
0
                    case cmd_opv_set_bits_planar:
1279
0
                        goto do_opv_set_bits;
1280
10.5k
                    case cmd_opv_set_fill_adjust:
1281
10.5k
                        cmd_get_value(gs_gstate.fill_adjust.x, cbp);
1282
10.5k
                        cmd_get_value(gs_gstate.fill_adjust.y, cbp);
1283
10.5k
                        if_debug2m('L', mem, " (%g,%g)\n",
1284
10.5k
                                   fixed2float(gs_gstate.fill_adjust.x),
1285
10.5k
                                   fixed2float(gs_gstate.fill_adjust.y));
1286
10.5k
                        continue;
1287
430k
                    case cmd_opv_set_ctm:
1288
430k
                        {
1289
430k
                            gs_matrix mat;
1290
1291
430k
                            cbp = cmd_read_matrix(&mat, cbp);
1292
430k
                            if_debug6m('L', mem, " [%g %g %g %g %g %g]\n",
1293
430k
                                       mat.xx, mat.xy, mat.yx, mat.yy,
1294
430k
                                       mat.tx, mat.ty);
1295
430k
                            mat.tx -= x0;
1296
430k
                            mat.ty -= y0;
1297
430k
                            gs_gstate_setmatrix(&gs_gstate, &mat);
1298
430k
                        }
1299
430k
                        continue;
1300
325k
                    case cmd_opv_set_misc2:
1301
325k
                        cbuf.ptr = cbp;
1302
325k
                        code = read_set_misc2(&cbuf, &gs_gstate, &notes);
1303
325k
                        cbp = cbuf.ptr;
1304
325k
                        if (code < 0)
1305
0
                            goto out;
1306
325k
                        continue;
1307
325k
                    case cmd_opv_set_dash:
1308
29.8k
                        {
1309
29.8k
                            int nb = *cbp++;
1310
29.8k
                            int n = nb & 0x3f;
1311
29.8k
                            float dot_length, offset;
1312
1313
29.8k
                            cmd_get_value(dot_length, cbp);
1314
29.8k
                            cmd_get_value(offset, cbp);
1315
29.8k
                            memcpy(dash_pattern, cbp, n * sizeof(float));
1316
1317
29.8k
                            gx_set_dash(&gs_gstate.line_params.dash,
1318
29.8k
                                        dash_pattern, n, offset,
1319
29.8k
                                        NULL);
1320
29.8k
                            gx_set_dash_adapt(&gs_gstate.line_params.dash,
1321
29.8k
                                              (nb & 0x80) != 0);
1322
29.8k
                            gx_set_dot_length(&gs_gstate.line_params,
1323
29.8k
                                              dot_length,
1324
29.8k
                                              (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
29.8k
                            cbp += n * sizeof(float);
1339
29.8k
                        }
1340
29.8k
                        break;
1341
1.07k
                    case cmd_opv_enable_clip:
1342
1.07k
                        pcpath = (use_clip ? &clip_path : NULL);
1343
1.07k
                        if (pcpath) {
1344
95
                            code = gx_cpath_ensure_path_list(pcpath);
1345
95
                            if (code < 0)
1346
0
                                goto out;
1347
95
                        }
1348
1.07k
                        if (clipper_dev_open)
1349
0
                            gx_destroy_clip_device_on_stack(&clipper_dev);
1350
1.07k
                        clipper_dev_open = false;
1351
1.07k
                        if_debug0m('L', mem, "\n");
1352
1.07k
                        break;
1353
1.97k
                    case cmd_opv_disable_clip:
1354
1.97k
                        pcpath = NULL;
1355
1.97k
                        if (clipper_dev_open)
1356
7
                            gx_destroy_clip_device_on_stack(&clipper_dev);
1357
1.97k
                        clipper_dev_open = false;
1358
1.97k
                        if_debug0m('L', mem, "\n");
1359
1.97k
                        break;
1360
542k
                    case cmd_opv_begin_clip:
1361
542k
                        pcpath = NULL;
1362
542k
                        if (clipper_dev_open)
1363
226
                            gx_destroy_clip_device_on_stack(&clipper_dev);
1364
542k
                        clipper_dev_open = false;
1365
542k
                        in_clip = true;
1366
542k
                        if_debug0m('L', mem, "\n");
1367
542k
                        code = gx_cpath_reset(&clip_path);
1368
542k
                        if (code < 0)
1369
0
                            goto out;
1370
542k
                        gx_cpath_accum_begin(&clip_accum, mem, false);
1371
542k
                        gx_cpath_accum_set_cbox(&clip_accum,
1372
542k
                                                &target_box);
1373
542k
                        tdev = (gx_device *)&clip_accum;
1374
542k
                        clip_save.lop_enabled = state.lop_enabled;
1375
542k
                        clip_save.dcolor = fill_color;
1376
542k
                        clip_save.fa_save.x = gs_gstate.fill_adjust.x;
1377
542k
                        clip_save.fa_save.y = gs_gstate.fill_adjust.y;
1378
542k
                        cmd_getw(gs_gstate.fill_adjust.x, cbp);
1379
542k
                        cmd_getw(gs_gstate.fill_adjust.y, cbp);
1380
                        /* temporarily set a solid color */
1381
542k
                        color_set_pure(&fill_color, (gx_color_index)1);
1382
542k
                        state.lop_enabled = false;
1383
542k
                        gs_gstate.log_op = lop_default;
1384
542k
                        break;
1385
542k
                    case cmd_opv_end_clip:
1386
542k
                        if_debug0m('L', mem, "\n");
1387
542k
                        gx_cpath_accum_end(&clip_accum, &clip_path);
1388
542k
                        tdev = target;
1389
                        /*
1390
                         * If the entire band falls within the clip
1391
                         * path, no clipping is needed.
1392
                         */
1393
542k
                        {
1394
542k
                            gs_fixed_rect cbox;
1395
1396
542k
                            gx_cpath_inner_box(&clip_path, &cbox);
1397
542k
                            use_clip =
1398
542k
                                !(cbox.p.x <= target_box.p.x &&
1399
542k
                                  cbox.q.x >= target_box.q.x &&
1400
542k
                                  cbox.p.y <= target_box.p.y &&
1401
542k
                                  cbox.q.y >= target_box.q.y);
1402
542k
                        }
1403
542k
                        pcpath = (use_clip ? &clip_path : NULL);
1404
542k
                        if (pcpath) {
1405
311k
                            code = gx_cpath_ensure_path_list(pcpath);
1406
311k
                            if (code < 0)
1407
0
                                goto out;
1408
311k
                        }
1409
542k
                        if (clipper_dev_open)
1410
0
                            gx_destroy_clip_device_on_stack(&clipper_dev);
1411
542k
                        clipper_dev_open = false;
1412
542k
                        state.lop_enabled = clip_save.lop_enabled;
1413
542k
                        gs_gstate.log_op =
1414
542k
                            (state.lop_enabled ? state.lop :
1415
542k
                             lop_default);
1416
542k
                        fill_color = clip_save.dcolor;
1417
                        /* restore the fill_adjust if it was changed by begin_clip */
1418
542k
                        gs_gstate.fill_adjust.x = clip_save.fa_save.x;
1419
542k
                        gs_gstate.fill_adjust.y = clip_save.fa_save.y;
1420
542k
                        in_clip = false;
1421
542k
                        break;
1422
78.5k
                    case cmd_opv_set_color_space:
1423
78.5k
                        cbuf.ptr = cbp;
1424
78.5k
                        code = read_set_color_space(&cbuf, &gs_gstate, cdev, mem);
1425
78.5k
                        pcs = gs_gstate.color[0].color_space;
1426
78.5k
                        cbp = cbuf.ptr;
1427
78.5k
                        if (code < 0) {
1428
0
                            if (code == gs_error_rangecheck)
1429
0
                                goto bad_op;
1430
0
                            goto out;
1431
0
                        }
1432
78.5k
                        break;
1433
78.5k
                    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
77.4k
                    case cmd_opv_begin_image_rect:
1456
77.4k
                        cbuf.ptr = cbp;
1457
77.4k
                        code = read_begin_image(&cbuf, &image.c, pcs);
1458
77.4k
                        cbp = cbuf.ptr;
1459
77.4k
                        if (code < 0)
1460
0
                            goto out;
1461
77.4k
                        {
1462
77.4k
                            uint diff;
1463
1464
77.4k
                            cmd_getw(image_rect.p.x, cbp);
1465
77.4k
                            cmd_getw(image_rect.p.y, cbp);
1466
77.4k
                            cmd_getw(diff, cbp);
1467
77.4k
                            image_rect.q.x = image.d.Width - diff;
1468
77.4k
                            cmd_getw(diff, cbp);
1469
77.4k
                            image_rect.q.y = image.d.Height - diff;
1470
77.4k
                            if_debug4m('L', mem, " rect=(%d,%d),(%d,%d)",
1471
77.4k
                                       image_rect.p.x, image_rect.p.y,
1472
77.4k
                                       image_rect.q.x, image_rect.q.y);
1473
77.4k
                        }
1474
77.4k
                        goto ibegin;
1475
12.7k
                    case cmd_opv_begin_image:
1476
12.7k
                        cbuf.ptr = cbp;
1477
12.7k
                        code = read_begin_image(&cbuf, &image.c, pcs);
1478
12.7k
                        cbp = cbuf.ptr;
1479
12.7k
                        if (code < 0)
1480
0
                            goto out;
1481
12.7k
                        image_rect.p.x = 0;
1482
12.7k
                        image_rect.p.y = 0;
1483
12.7k
                        image_rect.q.x = image.d.Width;
1484
12.7k
                        image_rect.q.y = image.d.Height;
1485
12.7k
                        if_debug2m('L', mem, " size=(%d,%d)",
1486
12.7k
                                  image.d.Width, image.d.Height);
1487
90.2k
ibegin:                 if_debug0m('L', mem, "\n");
1488
90.2k
                        {
1489
                            /* Processing an image operation */
1490
90.2k
                            dev_proc(tdev, set_graphics_type_tag)(tdev, GS_IMAGE_TAG);/* FIXME: what about text bitmaps? */
1491
90.2k
                            image.i4.override_in_smask = 0;
1492
90.2k
                            code = (*dev_proc(tdev, begin_typed_image))
1493
90.2k
                                (tdev, &gs_gstate, NULL,
1494
90.2k
                                 (const gs_image_common_t *)&image,
1495
90.2k
                                 &image_rect, &fill_color, pcpath, mem,
1496
90.2k
                                 &image_info);
1497
90.2k
                        }
1498
90.2k
                        if (code < 0)
1499
0
                            goto out;
1500
90.2k
                        break;
1501
90.2k
                    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
564k
                    case cmd_opv_image_data:
1537
564k
                        cmd_getw(data_height, cbp);
1538
564k
                        if (data_height == 0) {
1539
90.2k
                            if_debug0m('L', mem, " done image\n");
1540
90.2k
                            code = gx_image_end(image_info, true);
1541
90.2k
                            if (code < 0)
1542
0
                                goto out;
1543
90.2k
                            continue;
1544
90.2k
                        }
1545
474k
                        {
1546
474k
                            uint bytes_per_plane;
1547
474k
                            int plane;
1548
1549
474k
                            cmd_getw(bytes_per_plane, cbp);
1550
474k
                            if_debug2m('L', mem, " height=%u raster=%u\n",
1551
474k
                                       data_height, bytes_per_plane);
1552
474k
                            for (plane = 0;
1553
948k
                                 plane < image_info->num_planes;
1554
474k
                                 ++plane
1555
474k
                                 ) {
1556
474k
                                planes[plane].data_x = data_x;
1557
474k
                                planes[plane].raster = bytes_per_plane;
1558
474k
                            }
1559
474k
                        }
1560
474k
idata:                  data_size = 0;
1561
474k
                        {
1562
474k
                            int plane;
1563
1564
948k
                            for (plane = 0; plane < image_info->num_planes;
1565
474k
                                 ++plane)
1566
474k
                                data_size += planes[plane].raster;
1567
474k
                        }
1568
474k
                        data_size *= data_height;
1569
474k
                        data_on_heap = 0;
1570
474k
                        if (cbuf.end - cbp < data_size) {
1571
98.4k
                            code = top_up_cbuf(&cbuf, &cbp);
1572
98.4k
                            if (code < 0)
1573
0
                                goto top_up_failed;
1574
98.4k
                        }
1575
474k
                        if (cbuf.end - cbp >= data_size) {
1576
472k
                            planes[0].data = cbp;
1577
472k
                            cbp += data_size;
1578
472k
                        } else {
1579
2.34k
                            uint cleft = cbuf.end - cbp;
1580
2.34k
                            uint rleft = data_size - cleft;
1581
2.34k
                            byte *rdata;
1582
1583
2.34k
                            if (data_size > cbuf.end - cbuf.data) {
1584
                                /* Allocate a separate buffer. */
1585
2.34k
                                rdata = data_on_heap =
1586
2.34k
                                    gs_alloc_bytes(mem, data_size,
1587
2.34k
                                                   "clist image_data");
1588
2.34k
                                if (rdata == 0) {
1589
0
                                    code = gs_note_error(gs_error_VMerror);
1590
0
                                    goto out;
1591
0
                                }
1592
2.34k
                            } else
1593
0
                                rdata = cbuf.data;
1594
2.34k
                            memmove(rdata, cbp, cleft);
1595
2.34k
                            if (data_on_heap)
1596
2.34k
                                next_is_skip(&cbuf);
1597
2.34k
                            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
2.34k
                            planes[0].data = rdata;
1602
2.34k
                            cbp = cbuf.end;     /* force refill */
1603
2.34k
                        }
1604
474k
                        {
1605
474k
                            int plane;
1606
474k
                            const byte *data = planes[0].data;
1607
1608
474k
                            for (plane = 0;
1609
948k
                                 plane < image_info->num_planes;
1610
474k
                                 ++plane
1611
474k
                                 ) {
1612
474k
                                if (planes[plane].raster == 0)
1613
0
                                    planes[plane].data = 0;
1614
474k
                                else {
1615
474k
                                    planes[plane].data = data;
1616
474k
                                    data += planes[plane].raster *
1617
474k
                                        data_height;
1618
474k
                                }
1619
474k
                            }
1620
474k
                        }
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
474k
                        code = gx_image_plane_data(image_info, planes,
1637
474k
                                                   data_height);
1638
474k
                        if (code < 0)
1639
0
                            gx_image_end(image_info, false);
1640
474k
                        if (data_on_heap)
1641
2.34k
                            gs_free_object(mem, data_on_heap,
1642
474k
                                           "clist image_data");
1643
474k
                        data_x = 0;
1644
474k
                        if (code < 0)
1645
0
                            goto out;
1646
474k
                        continue;
1647
4.40M
                    case cmd_opv_extend:
1648
4.40M
                        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.08M
                            case cmd_opv_ext_composite:
1663
1.08M
                                if_debug0m('L', mem, " ext_composite\n");
1664
1.08M
                                cbuf.ptr = cbp;
1665
                                /*
1666
                                 * The screen phase may have been changed during
1667
                                 * the processing of masked images.
1668
                                 */
1669
1.08M
                                gx_gstate_setscreenphase(&gs_gstate,
1670
1.08M
                                            -x0, -y0, gs_color_select_all);
1671
1.08M
                                cbp -= 2; /* Step back to simplify the cycle invariant below. */
1672
41.0M
                                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
41.0M
                                    int len;
1678
1679
41.0M
                                    if (cbp >= cbuf.warn_limit) {
1680
76.9k
                                        code = top_up_cbuf(&cbuf, &cbp);
1681
76.9k
                                        if (code < 0)
1682
0
                                            goto out;
1683
76.9k
                                    }
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
41.0M
                                    if (cbp[0] == cmd_opv_extend && cbp[1] == cmd_opv_ext_composite) {
1694
26.5M
                                        gs_composite_t *pcomp, *pcomp_opening;
1695
26.5M
                                        gs_compositor_closing_state closing_state;
1696
1697
26.5M
                                        cbuf.ptr = cbp += 2;
1698
26.5M
                                        code = read_composite(&cbuf, mem, &pcomp);
1699
26.5M
                                        if (code < 0)
1700
0
                                            goto out;
1701
26.5M
                                        cbp = cbuf.ptr;
1702
26.5M
                                        if (pcomp == NULL)
1703
0
                                            continue;
1704
26.5M
                                        if (gs_is_pdf14trans_compositor(pcomp) &&
1705
26.5M
                                            playback_action == playback_action_render_no_pdf14) {
1706
                                            /* free the compositor object */
1707
0
                                            gs_free_object(mem, pcomp, "read_composite");
1708
0
                                            pcomp = NULL;
1709
0
                                            continue;
1710
0
                                        }
1711
26.5M
                                        pcomp_opening = pcomp_last;
1712
26.5M
                                        closing_state = pcomp->type->procs.is_closing(pcomp, &pcomp_opening, tdev);
1713
26.5M
                                        switch(closing_state)
1714
26.5M
                                        {
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
22.7M
                                        case COMP_ENQUEUE:
1721
                                            /* Enqueue. */
1722
22.7M
                                            enqueue_compositor(&pcomp_first, &pcomp_last, pcomp);
1723
22.7M
                                            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
145k
                                        case COMP_EXEC_QUEUE:
1733
                                            /* The opening command was executed. Execute the queue. */
1734
145k
                                            enqueue_compositor(&pcomp_first, &pcomp_last, pcomp);
1735
145k
                                            code = execute_compositor_queue(cdev, &target, &tdev,
1736
145k
                                                &gs_gstate, &pcomp_first, &pcomp_last, pcomp_first, x0, y0, mem, false);
1737
145k
                                            if (code < 0)
1738
0
                                                goto out;
1739
145k
                                            break;
1740
145k
                                        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.24M
                                        case COMP_REPLACE_CURR:
1749
                                            /* Replace specific compositor. */
1750
3.24M
                                            code = dequeue_compositor(&pcomp_first, &pcomp_last, pcomp_opening);
1751
3.24M
                                            if (code < 0)
1752
0
                                                goto out;
1753
3.24M
                                            enqueue_compositor(&pcomp_first, &pcomp_last, pcomp);
1754
3.24M
                                            free_compositor(pcomp_opening, mem);
1755
3.24M
                                            break;
1756
27.1k
                                        case COMP_DROP_QUEUE:
1757
                                            /* Annihilate the last compositors. */
1758
27.1k
                                            enqueue_compositor(&pcomp_first, &pcomp_last, pcomp);
1759
27.1k
                                            code = drop_compositor_queue(&pcomp_first, &pcomp_last, pcomp_opening, mem, x0, y0, &gs_gstate);
1760
27.1k
                                            if (code < 0)
1761
0
                                                goto out;
1762
27.1k
                                            break;
1763
426k
                                        case COMP_MARK_IDLE:
1764
                                            /* Mark as idle. */
1765
426k
                                            enqueue_compositor(&pcomp_first, &pcomp_last, pcomp);
1766
426k
                                            mark_as_idle(pcomp_opening, pcomp);
1767
26.5M
                                        }
1768
26.5M
                                    } else if (is_null_compositor_op(cbp, &len)) {
1769
13.0M
                                        cbuf.ptr = cbp += len;
1770
13.0M
                                    } else if (cbp[0] == cmd_opv_end_page) {
1771
                                        /* End page, drop the queue. */
1772
220k
                                        code = execute_compositor_queue(cdev, &target, &tdev,
1773
220k
                                                &gs_gstate, &pcomp_first, &pcomp_last, pcomp_first, x0, y0, mem, true);
1774
220k
                                        if (code < 0)
1775
0
                                            goto out;
1776
220k
                                        break;
1777
1.25M
                                    } else if (pcomp_last != NULL &&
1778
1.25M
                                            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
393k
                                        uint cb;
1787
1788
393k
                                        switch (*cbp++) {
1789
230k
                                            case cmd_opv_extend:
1790
230k
                                                switch (*cbp++) {
1791
76.9k
                                                    case cmd_opv_ext_put_halftone:
1792
76.9k
                                                        {
1793
76.9k
                                                            uint    ht_size;
1794
1795
76.9k
                                                            enc_u_getw(ht_size, cbp);
1796
76.9k
                                                            code = read_alloc_ht_buff(&ht_buff, ht_size, mem);
1797
76.9k
                                                            if (code < 0)
1798
0
                                                                goto out;
1799
76.9k
                                                        }
1800
76.9k
                                                        break;
1801
153k
                                                    case cmd_opv_ext_put_ht_seg:
1802
153k
                                                        cbuf.ptr = cbp;
1803
153k
                                                        code = read_ht_segment(&ht_buff, &cbuf,
1804
153k
                                                                               &gs_gstate, tdev,
1805
153k
                                                                               mem);
1806
153k
                                                        cbp = cbuf.ptr;
1807
153k
                                                        if (code < 0)
1808
0
                                                            goto out;
1809
153k
                                                        break;
1810
153k
                                                    default:
1811
0
                                                        code = gs_note_error(gs_error_unregistered); /* Must not happen. */
1812
0
                                                        goto out;
1813
230k
                                                }
1814
230k
                                                break;
1815
230k
                                            case cmd_opv_set_misc:
1816
162k
                                                cb = *cbp++;
1817
162k
                                                switch (cb >> 6) {
1818
162k
                                                    case cmd_set_misc_map >> 6:
1819
162k
                                                        cbuf.ptr = cbp;
1820
162k
                                                        code = read_set_misc_map(cb, &cbuf, &gs_gstate, mem);
1821
162k
                                                        if (code < 0)
1822
0
                                                            goto out;
1823
162k
                                                        cbp = cbuf.ptr;
1824
162k
                                                        break;
1825
0
                                                    default:
1826
0
                                                        code = gs_note_error(gs_error_unregistered); /* Must not happen. */
1827
0
                                                        goto out;
1828
162k
                                                }
1829
162k
                                                break;
1830
162k
                                            default:
1831
0
                                                code = gs_note_error(gs_error_unregistered); /* Must not happen. */
1832
0
                                                goto out;
1833
393k
                                        }
1834
864k
                                    } else {
1835
                                        /* A drawing command, execute entire queue. */
1836
864k
                                        code = execute_compositor_queue(cdev, &target, &tdev,
1837
864k
                                            &gs_gstate, &pcomp_first, &pcomp_last, pcomp_first, x0, y0, mem, false);
1838
864k
                                        if (code < 0)
1839
0
                                            goto out;
1840
864k
                                        break;
1841
864k
                                    }
1842
41.0M
                                }
1843
1.08M
                                if (pcomp_last != NULL) {
1844
0
                                    code = gs_note_error(gs_error_unregistered);
1845
0
                                    goto out;
1846
0
                                }
1847
1.08M
                                break;
1848
1.08M
                            case cmd_opv_ext_put_halftone:
1849
185k
                                {
1850
185k
                                    uint    ht_size;
1851
1852
185k
                                    if_debug0m('L', mem, " ext_put_halftone\n");
1853
185k
                                    enc_u_getw(ht_size, cbp);
1854
185k
                                    code = read_alloc_ht_buff(&ht_buff, ht_size, mem);
1855
185k
                                    if (code < 0)
1856
0
                                        goto out;
1857
185k
                                }
1858
185k
                                break;
1859
354k
                            case cmd_opv_ext_put_ht_seg:
1860
354k
                                if_debug0m('L', mem, " ext_put_ht_seg\n");
1861
354k
                                cbuf.ptr = cbp;
1862
354k
                                code = read_ht_segment(&ht_buff, &cbuf,
1863
354k
                                                       &gs_gstate, tdev,
1864
354k
                                                       mem);
1865
354k
                                cbp = cbuf.ptr;
1866
354k
                                if (code < 0)
1867
0
                                    goto out;
1868
354k
                                break;
1869
354k
                            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
2.58M
                            case cmd_opv_ext_put_fill_dcolor:
1892
2.58M
                                pdcolor = &fill_color;
1893
2.58M
                                goto load_dcolor;
1894
194k
                            case cmd_opv_ext_put_stroke_dcolor:
1895
194k
                                pdcolor = &stroke_color;
1896
194k
                                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
2.78M
                    load_dcolor:{
1903
2.78M
                                    uint    color_size;
1904
2.78M
                                    int left, offset, l;
1905
2.78M
                                    const gx_device_color_type_t *  pdct;
1906
2.78M
                                    byte type_and_flag = *cbp++;
1907
2.78M
                                    byte is_continuation = type_and_flag & 0x80;
1908
1909
2.78M
                                    if_debug0m('L', mem, " cmd_opv_ext_put_drawing_color\n");
1910
2.78M
                                    pdct = gx_get_dc_type_from_index(type_and_flag & 0x7F);
1911
2.78M
                                    if (pdct == 0) {
1912
0
                                        code = gs_note_error(gs_error_rangecheck);
1913
0
                                        goto out;
1914
0
                                    }
1915
2.78M
                                    offset = 0;
1916
2.78M
                                    if (is_continuation)
1917
2.78M
                                        enc_u_getw(offset, cbp);
1918
2.78M
                                    enc_u_getw(color_size, cbp);
1919
2.78M
                                    left = color_size;
1920
2.78M
                                    if (!left) {
1921
                                        /* We still need to call pdct->read because it may change dev_color.type -
1922
                                           see gx_dc_null_read.*/
1923
52.5k
                                        code = pdct->read(pdcolor, &gs_gstate,
1924
52.5k
                                                          pdcolor, tdev, offset,
1925
52.5k
                                                          cbp, 0, mem, x0, y0);
1926
52.5k
                                        if (code < 0)
1927
0
                                            goto out;
1928
52.5k
                                    }
1929
12.8M
                                    while (left) {
1930
10.1M
                                        if (cbuf.warn_limit - cbp < (int)left) {  /* cbp can be past warn_limit */
1931
7.93M
                                            code = top_up_cbuf(&cbuf, &cbp);
1932
7.93M
                                            if (code < 0)
1933
0
                                                goto top_up_failed;
1934
7.93M
                                        }
1935
10.1M
                                        l = min(left, cbuf.end - cbp);
1936
10.1M
                                        code = pdct->read(pdcolor, &gs_gstate,
1937
10.1M
                                                          pdcolor, tdev, offset,
1938
10.1M
                                                          cbp, l, mem, x0, y0);
1939
10.1M
                                        if (code < 0)
1940
0
                                            goto out;
1941
10.1M
                                        l = code;
1942
10.1M
                                        cbp += l;
1943
10.1M
                                        offset += l;
1944
10.1M
                                        left -= l;
1945
10.1M
                                    }
1946
2.78M
                                    code = gx_color_load(pdcolor, &gs_gstate,
1947
2.78M
                                                         tdev);
1948
2.78M
                                    if (code < 0)
1949
0
                                        goto out;
1950
2.78M
                                }
1951
2.78M
                                break;
1952
2.78M
                            default:
1953
0
                                goto bad_op;
1954
4.40M
                        }
1955
4.40M
                        break;
1956
4.40M
                    default:
1957
0
                        goto bad_op;
1958
7.02M
                }
1959
5.69M
                continue;
1960
7.67M
            case cmd_op_segment >> 4:
1961
7.67M
                {
1962
7.67M
                    int i;
1963
7.67M
                    static const byte op_num_operands[] = {
1964
7.67M
                        cmd_segment_op_num_operands_values
1965
7.67M
                    };
1966
7.67M
                  rgapto:
1967
7.67M
                    if (!in_path) {
1968
1.31M
                        ppos.x = int2fixed(state.rect.x);
1969
1.31M
                        ppos.y = int2fixed(state.rect.y);
1970
1.31M
                        if_debug2m('L', mem, " (%d,%d)", state.rect.x,
1971
1.31M
                                   state.rect.y);
1972
1.31M
                        notes = sn_none;
1973
1.31M
                        in_path = true;
1974
1.31M
                    }
1975
18.7M
                    for (i = 0; i < op_num_operands[op & 0xf]; ++i) {
1976
11.0M
                        fixed v;
1977
11.0M
                        int b = *cbp;
1978
1979
11.0M
                        switch (b >> 5) {
1980
2.75M
                            case 0:
1981
5.05M
                            case 1:
1982
5.05M
                                vs[i++] =
1983
5.05M
                                    ((fixed) ((b ^ 0x20) - 0x20) << 13) +
1984
5.05M
                                    ((int)cbp[1] << 5) + (cbp[2] >> 3);
1985
5.05M
                                if_debug1m('L', mem, " %g", fixed2float(vs[i - 1]));
1986
5.05M
                                cbp += 2;
1987
5.05M
                                v = (int)((*cbp & 7) ^ 4) - 4;
1988
5.05M
                                break;
1989
2.43M
                            case 2:
1990
4.60M
                            case 3:
1991
4.60M
                                v = (b ^ 0x60) - 0x20;
1992
4.60M
                                break;
1993
308k
                            case 4:
1994
585k
                            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
585k
                                v = (((b ^ 0xa0) - 0x20) << 8) + (int)*++cbp;
2003
585k
                                break;
2004
700k
                            case 6:
2005
700k
                                v = (b ^ 0xd0) - 0x10;
2006
700k
                                vs[i] =
2007
700k
                                    ((v << 8) + cbp[1]) << (_fixed_shift - 2);
2008
700k
                                if_debug1m('L', mem, " %g", fixed2float(vs[i]));
2009
700k
                                cbp += 2;
2010
700k
                                continue;
2011
98.8k
                            default /*case 7 */ :
2012
98.8k
                                v = (int)(*++cbp ^ 0x80) - 0x80;
2013
197k
                                for (b = 0; b < sizeof(fixed) - 3; ++b)
2014
98.8k
                                    v = (v << 8) + *++cbp;
2015
98.8k
                                break;
2016
11.0M
                        }
2017
10.3M
                        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
10.3M
                        vs[i] = (v << 16) + (uint) (cbp[-2] << 8) + cbp[-1];
2022
10.3M
                        if_debug1m('L', mem, " %g", fixed2float(vs[i]));
2023
10.3M
                    }
2024
7.67M
                    if_debug0m('L', mem, "\n");
2025
7.67M
                    code = clist_decode_segment(&path, op, vs, &ppos,
2026
7.67M
                                                x0, y0, notes);
2027
7.67M
                    if (code < 0)
2028
0
                        goto out;
2029
7.67M
                }
2030
7.67M
                continue;
2031
18.0M
            case cmd_op_path >> 4:
2032
18.0M
                if (op == cmd_opv_rgapto)
2033
0
                    goto rgapto;
2034
18.0M
                else if (op == cmd_opv_lock_pattern) {
2035
365
                    gs_id id;
2036
365
                    int lock = *cbp++;
2037
365
                    cmd_get_value(id, cbp);
2038
365
                    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
365
                    code = gx_pattern_cache_entry_set_lock(&gs_gstate, id, lock);
2044
365
                    if (code == gs_error_undefined)
2045
0
                        code = 0;
2046
365
                    if (code < 0)
2047
0
                        goto out;
2048
365
                    continue;
2049
18.0M
                } else {
2050
18.0M
                    gx_path fpath;
2051
18.0M
                    gx_path *ppath = &path;
2052
2053
18.0M
                    if_debug0m('L', mem, "\n");
2054
                    /* if in clip, flatten path first */
2055
18.0M
                    if (in_clip) {
2056
191k
                        gx_path_init_local(&fpath, mem);
2057
191k
                        code = gx_path_add_flattened_accurate(&path, &fpath,
2058
191k
                                             gs_currentflat_inline(&gs_gstate),
2059
191k
                                             gs_gstate.accurate_curves);
2060
191k
                        if (code < 0)
2061
0
                            goto out;
2062
191k
                        ppath = &fpath;
2063
191k
                    }
2064
18.0M
                    switch (op) {
2065
924k
                        case cmd_opv_fill:
2066
924k
                            fill_params.rule = gx_rule_winding_number;
2067
924k
                            goto fill;
2068
31.8k
                        case cmd_opv_eofill:
2069
31.8k
                            fill_params.rule = gx_rule_even_odd;
2070
956k
                        fill:
2071
956k
                            fill_params.adjust = gs_gstate.fill_adjust;
2072
956k
                            fill_params.flatness = gs_gstate.flatness;
2073
956k
                            code = (*dev_proc(tdev, fill_path))(tdev, &gs_gstate, ppath,
2074
956k
                                                                &fill_params, &fill_color, pcpath);
2075
956k
                            break;
2076
14.8k
                        case cmd_opv_fill_stroke:
2077
14.8k
                            fill_params.rule = gx_rule_winding_number;
2078
14.8k
                            goto fill_stroke;
2079
1.78k
                        case cmd_opv_eofill_stroke:
2080
1.78k
                            fill_params.rule = gx_rule_even_odd;
2081
16.6k
                        fill_stroke:
2082
16.6k
                            fill_params.adjust = gs_gstate.fill_adjust;
2083
16.6k
                            fill_params.flatness = gs_gstate.flatness;
2084
16.6k
                            stroke_params.flatness = gs_gstate.flatness;
2085
16.6k
                            stroke_params.traditional = false;
2086
16.6k
                            code = (*dev_proc(tdev, fill_stroke_path))(tdev, &gs_gstate, ppath,
2087
16.6k
                                                                &fill_params, &fill_color,
2088
16.6k
                                                                &stroke_params, &stroke_color, pcpath);
2089
16.6k
                            break;
2090
630k
                        case cmd_opv_stroke:
2091
630k
                            stroke_params.flatness = gs_gstate.flatness;
2092
630k
                            stroke_params.traditional = false;
2093
630k
                            code = (*dev_proc(tdev, stroke_path))
2094
630k
                                                       (tdev, &gs_gstate,
2095
630k
                                                       ppath, &stroke_params,
2096
630k
                                                       &stroke_color, pcpath);
2097
630k
                            break;
2098
26.9k
                        case cmd_opv_polyfill:
2099
26.9k
                            code = clist_do_polyfill(tdev, ppath, &fill_color,
2100
26.9k
                                                     gs_gstate.log_op);
2101
26.9k
                            break;
2102
16.4M
                        case cmd_opv_fill_trapezoid:
2103
16.4M
                            {
2104
16.4M
                                gs_fixed_edge left, right;
2105
16.4M
                                fixed ybot, ytop;
2106
16.4M
                                int options, swap_axes, wh;
2107
16.4M
                                fixed x0f;
2108
16.4M
                                fixed y0f;
2109
16.4M
                                gx_device *ttdev = tdev;
2110
2111
16.4M
                                if (pcpath != NULL && !clipper_dev_open) {
2112
475
                                    gx_make_clip_device_on_stack(&clipper_dev, pcpath, tdev);
2113
475
                                    clipper_dev_open = true;
2114
475
                                }
2115
16.4M
                                if (clipper_dev_open)
2116
10.1M
                                    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
16.4M
                                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
16.4M
                                cmd_getw(left.start.x, cbp);
2132
16.4M
                                cmd_getw(left.start.y, cbp);
2133
16.4M
                                cmd_getw(left.end.x, cbp);
2134
16.4M
                                cmd_getw(left.end.y, cbp);
2135
16.4M
                                cmd_getw(right.start.x, cbp);
2136
16.4M
                                cmd_getw(right.start.y, cbp);
2137
16.4M
                                cmd_getw(right.end.x, cbp);
2138
16.4M
                                cmd_getw(right.end.y, cbp);
2139
16.4M
                                cmd_getw(options, cbp);
2140
16.4M
                                if (!(options & 4)) {
2141
16.4M
                                    cmd_getw(ybot, cbp);
2142
16.4M
                                    cmd_getw(ytop, cbp);
2143
16.4M
                                } else
2144
0
                                    ytop = ybot = 0; /* Unused, but quiet gcc warning. */
2145
16.4M
                                swap_axes = options & 1;
2146
16.4M
                                wh = swap_axes ? tdev->width : tdev->height;
2147
16.4M
                                x0f = int2fixed(swap_axes ? y0 : x0);
2148
16.4M
                                y0f = int2fixed(swap_axes ? x0 : y0);
2149
16.4M
                                left.start.x -= x0f;
2150
16.4M
                                left.start.y -= y0f;
2151
16.4M
                                left.end.x -= x0f;
2152
16.4M
                                left.end.y -= y0f;
2153
16.4M
                                right.start.x -= x0f;
2154
16.4M
                                right.start.y -= y0f;
2155
16.4M
                                right.end.x -= x0f;
2156
16.4M
                                right.end.y -= y0f;
2157
16.4M
                                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
16.4M
                                    code = gx_default_fill_trapezoid(ttdev, &left, &right,
2240
16.4M
                                        max(ybot - y0f, fixed_half),
2241
16.4M
                                        min(ytop - y0f, int2fixed(wh)), swap_axes,
2242
16.4M
                                        &fill_color, gs_gstate.log_op);
2243
16.4M
                            }
2244
16.4M
                           break;
2245
16.4M
                        default:
2246
0
                            goto bad_op;
2247
18.0M
                    }
2248
18.0M
                    if (ppath != &path)
2249
191k
                        gx_path_free(ppath, "clist_render_band");
2250
18.0M
                }
2251
18.0M
                if (in_path) {  /* path might be empty! */
2252
1.31M
                    state.rect.x = fixed2int_var(ppos.x);
2253
1.31M
                    state.rect.y = fixed2int_var(ppos.y);
2254
1.31M
                    in_path = false;
2255
1.31M
                }
2256
18.0M
                gx_path_free(&path, "clist_render_band");
2257
18.0M
                gx_path_init_local(&path, mem);
2258
18.0M
                if (code < 0)
2259
0
                    goto out;
2260
18.0M
                continue;
2261
18.0M
            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
66.7M
        }
2277
66.7M
        if_debug4m('L', mem, " x=%d y=%d w=%d h=%d\n",
2278
19.1M
                  state.rect.x, state.rect.y, state.rect.width,
2279
19.1M
                  state.rect.height);
2280
19.1M
        switch (op >> 4) {
2281
720k
            case cmd_op_fill_rect >> 4:
2282
720k
                if (state.rect.width == 0 && state.rect.height == 0 &&
2283
720k
                    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
278k
                    code = (dev_proc(tdev, fillpage) == NULL ? 0 :
2287
278k
                            (*dev_proc(tdev, fillpage))(tdev, &gs_gstate,
2288
278k
                                                        &fill_color));
2289
278k
                    break;
2290
278k
                }
2291
2.01M
            case cmd_op_fill_rect_short >> 4:
2292
9.94M
            case cmd_op_fill_rect_tiny >> 4:
2293
9.94M
                if (!state.lop_enabled) {
2294
9.94M
                    code = (*dev_proc(tdev, fill_rectangle))
2295
9.94M
                        (tdev, state.rect.x - x0, state.rect.y - y0,
2296
9.94M
                         state.rect.width, state.rect.height,
2297
9.94M
                         state.colors[1]);
2298
9.94M
                    break;
2299
9.94M
                }
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
17.3k
            case cmd_op_tile_rect >> 4:
2320
17.3k
                if (state.rect.width == 0 && state.rect.height == 0 &&
2321
17.3k
                    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
166k
            case cmd_op_tile_rect_short >> 4:
2326
395k
            case cmd_op_tile_rect_tiny >> 4:
2327
                /* Currently we don't use lop with strip_tile_rectangle. */
2328
395k
                code = (*dev_proc(tdev, strip_tile_rectangle))
2329
395k
                    (tdev, &state_tile,
2330
395k
                     state.rect.x - x0, state.rect.y - y0,
2331
395k
                     state.rect.width, state.rect.height,
2332
395k
                     state.tile_colors[0], state.tile_colors[1],
2333
395k
                     tile_phase.x, tile_phase.y);
2334
395k
                break;
2335
6.60M
            case cmd_op_copy_mono_planes >> 4:
2336
6.60M
                if (state.lop_enabled) {
2337
0
                    pcolor = state.colors;
2338
0
                    log_op = state.lop;
2339
0
                    goto do_rop;
2340
0
                }
2341
6.60M
                if ((op & cmd_copy_use_tile) || pcpath != NULL) {       /*
2342
                                                                         * This call of copy_mono originated as a call
2343
                                                                         * of fill_mask.
2344
                                                                         */
2345
6.56M
                    code = gx_image_fill_masked
2346
6.56M
                        (tdev, source, data_x, raster, gx_no_bitmap_id,
2347
6.56M
                         state.rect.x - x0, state.rect.y - y0,
2348
6.56M
                         state.rect.width - data_x, state.rect.height,
2349
6.56M
                         &fill_color, 1, gs_gstate.log_op, pcpath);
2350
6.56M
                } else {
2351
40.3k
                    if (plane_height == 0) {
2352
40.3k
                        code = (*dev_proc(tdev, copy_mono))
2353
40.3k
                             (tdev, source, data_x, raster, gx_no_bitmap_id,
2354
40.3k
                              state.rect.x - x0, state.rect.y - y0,
2355
40.3k
                              state.rect.width - data_x, state.rect.height,
2356
40.3k
                              state.colors[0], state.colors[1]);
2357
40.3k
                    } 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
40.3k
                }
2365
6.60M
                plane_height = 0;
2366
6.60M
                data_x = 0;
2367
6.60M
                break;
2368
1.93M
            case cmd_op_copy_color_alpha >> 4:
2369
1.93M
                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
1.93M
                } else {
2386
1.93M
                    if (state.lop_enabled) {
2387
0
                        pcolor = NULL;
2388
0
                        log_op = state.lop;
2389
0
                        goto do_rop;
2390
0
                    }
2391
1.93M
                    code = (*dev_proc(tdev, copy_color))
2392
1.93M
                        (tdev, source, data_x, raster, gx_no_bitmap_id,
2393
1.93M
                         state.rect.x - x0, state.rect.y - y0,
2394
1.93M
                         state.rect.width - data_x, state.rect.height);
2395
1.93M
                }
2396
1.93M
                data_x = 0;
2397
1.93M
                break;
2398
0
            default:            /* can't happen */
2399
0
                goto bad_op;
2400
19.1M
        }
2401
19.1M
    }
2402
    /* Clean up before we exit. */
2403
278k
  out:
2404
278k
    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
278k
    ht_buff.ht_size = 0;
2410
278k
    ht_buff.read_size = 0;
2411
2412
278k
    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
278k
    gx_cpath_free(&clip_path, "clist_render_band exit");
2419
278k
    gx_path_free(&path, "clist_render_band exit");
2420
278k
    if (gs_gstate.pattern_cache != NULL) {
2421
15.4k
        gx_pattern_cache_free(gs_gstate.pattern_cache);
2422
15.4k
        gs_gstate.pattern_cache = NULL;
2423
15.4k
    }
2424
    /* Free the client color and device colors allocated upon entry */
2425
278k
    gs_free_object(mem, gs_gstate.color[0].ccolor, "clist_playback_band");
2426
278k
    gs_free_object(mem, gs_gstate.color[1].ccolor, "clist_playback_band");
2427
278k
    gs_free_object(mem, gs_gstate.color[0].dev_color, "clist_playback_band");
2428
278k
    gs_free_object(mem, gs_gstate.color[1].dev_color, "clist_playback_band");
2429
278k
    gs_gstate.color[0].ccolor = gs_gstate.color[1].ccolor = NULL;
2430
278k
    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
278k
    gx_monitor_enter(cdev->icc_cache_cl->lock);
2435
278k
    gs_gstate_release(&gs_gstate);
2436
278k
    gx_monitor_leave(cdev->icc_cache_cl->lock); /* done with increment, let everyone run */
2437
278k
    gs_free_object(mem, data_bits, "clist_playback_band(data_bits)");
2438
278k
    if (target != orig_target) {
2439
193k
        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
193k
        } else {
2448
            /* Ref count was 1. close the device and then free it */
2449
193k
            if (target->is_open)
2450
0
                dev_proc(target, close_device)(target);
2451
193k
            gs_free_object(target->memory, target, "gxclrast discard compositor");
2452
193k
        }
2453
193k
        target = orig_target;
2454
193k
    }
2455
278k
    if (code < 0) {
2456
0
        if (pfs.dev != NULL)
2457
0
            term_patch_fill_state(&pfs);
2458
0
        rc_decrement(gs_gstate.color[0].color_space, "clist_playback_band");
2459
0
        rc_decrement(gs_gstate.color[1].color_space, "clist_playback_band");
2460
0
        gs_free_object(mem, cbuf_storage, "clist_playback_band(cbuf_storage)");
2461
0
        gx_cpath_free(&clip_path, "clist_playback_band");
2462
0
        if (pcpath != &clip_path)
2463
0
            gx_cpath_free(pcpath, "clist_playback_band");
2464
0
        if (clipper_dev_open)
2465
0
            gx_destroy_clip_device_on_stack(&clipper_dev);
2466
0
        return_error(code);
2467
0
    }
2468
    /* Check whether we have more pages to process. */
2469
278k
    if ((playback_action != playback_action_setup &&
2470
278k
        (cbp < cbuf.end || !seofp(s)) && (op != cmd_opv_end_page) )
2471
278k
        )
2472
0
        goto in;
2473
278k
    if (pfs.dev != NULL)
2474
0
        term_patch_fill_state(&pfs);
2475
278k
    rc_decrement(gs_gstate.color[0].color_space, "clist_playback_band");
2476
278k
    rc_decrement(gs_gstate.color[1].color_space, "clist_playback_band");
2477
278k
    gs_free_object(mem, cbuf_storage, "clist_playback_band(cbuf_storage)");
2478
278k
    gx_cpath_free(&clip_path, "clist_playback_band");
2479
278k
    if (pcpath != &clip_path)
2480
226k
        gx_cpath_free(pcpath, "clist_playback_band");
2481
278k
    if (clipper_dev_open)
2482
242
        gx_destroy_clip_device_on_stack(&clipper_dev);
2483
278k
    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
278k
}
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
891
{
2506
891
    const byte *cbp = pcb->ptr;
2507
891
    uint rep_width, rep_height;
2508
891
    uint pdepth;
2509
891
    byte bd = *cbp++;
2510
2511
891
    bits->head.depth = cmd_code_to_depth(bd);
2512
891
    if (for_pattern)
2513
891
        cmd_getw(bits->id, cbp);
2514
891
    cmd_getw(rep_width, cbp);
2515
891
    cmd_getw(rep_height, cbp);
2516
891
    if (bd & 0x20) {
2517
851
        cmd_getw(bits->x_reps, cbp);
2518
851
        bits->width = rep_width * bits->x_reps;
2519
851
    } else {
2520
40
        bits->x_reps = 1;
2521
40
        bits->width = rep_width;
2522
40
    }
2523
891
    if (bd & 0x40) {
2524
282
        cmd_getw(bits->y_reps, cbp);
2525
282
        bits->height = rep_height * bits->y_reps;
2526
609
    } else {
2527
609
        bits->y_reps = 1;
2528
609
        bits->height = rep_height;
2529
609
    }
2530
891
    if (bd & 0x80)
2531
891
        cmd_getw(bits->rep_shift, cbp);
2532
891
    else
2533
891
        bits->rep_shift = 0;
2534
891
    if (bd & 0x10)
2535
0
        bits->num_planes = *cbp++;
2536
891
    else
2537
891
        bits->num_planes = 1;
2538
891
    if_debug7('L', " depth=%d size=(%d,%d), rep_size=(%d,%d), rep_shift=%d, num_planes=%d\n",
2539
891
              bits->head.depth, bits->width,
2540
891
              bits->height, rep_width,
2541
891
              rep_height, bits->rep_shift, bits->num_planes);
2542
891
    bits->shift =
2543
891
        (bits->rep_shift == 0 ? 0 :
2544
891
         (bits->rep_shift * (bits->height / rep_height)) % rep_width);
2545
891
    pdepth = bits->head.depth;
2546
891
    if (bits->num_planes != 1)
2547
0
        pdepth /= bits->num_planes;
2548
891
    bits->raster = bitmap_raster(bits->width * pdepth);
2549
891
    pcb->ptr = cbp;
2550
891
    return 0;
2551
891
}
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.85M
{
2558
1.85M
    const byte *cbp = pcb->ptr;
2559
1.85M
    uint rep_width = bits->width / bits->x_reps;
2560
1.85M
    uint rep_height = bits->height / bits->y_reps;
2561
1.85M
    uint index;
2562
1.85M
    ulong offset;
2563
1.85M
    uint width_bits;
2564
1.85M
    uint width_bytes;
2565
1.85M
    uint raster;
2566
1.85M
    uint bytes;
2567
1.85M
    byte *data;
2568
1.85M
    tile_slot *slot;
2569
1.85M
    uint depth = bits->head.depth;
2570
2571
1.85M
    if (bits->num_planes != 1)
2572
0
        depth /= bits->num_planes;
2573
1.85M
    width_bits = rep_width * depth;
2574
2575
1.85M
    bytes = clist_bitmap_bytes(width_bits, rep_height * bits->num_planes,
2576
1.85M
                               compress |
2577
1.85M
                               (rep_width < bits->width ?
2578
1.84M
                                decompress_spread : 0) |
2579
1.85M
                               decompress_elsewhere,
2580
1.85M
                               &width_bytes,
2581
1.85M
                               (uint *)&raster);
2582
2583
1.85M
    cmd_getw(index, cbp);
2584
1.85M
    cmd_getw(offset, cbp);
2585
1.85M
    if_debug2m('L', mem, " index=%d offset=%lu\n", index, offset);
2586
1.85M
    pcls->tile_index = index;
2587
1.85M
    cdev->tile_table[pcls->tile_index].offset = offset;
2588
1.85M
    slot = (tile_slot *)(cdev->cache_chunk->data + offset);
2589
1.85M
    *pslot = slot;
2590
1.85M
    *slot = *bits;
2591
1.85M
    tile->data = data = (byte *)(slot + 1);
2592
#ifdef DEBUG
2593
    slot->index = pcls->tile_index;
2594
#endif
2595
1.85M
    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.85M
    } 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
374k
        stream_cursor_read r;
2605
374k
        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
374k
        uint cleft = pcb->end - cbp;
2611
2612
374k
        if (cleft < bytes && !pcb->end_status) {
2613
3.50k
            uint nread = cbuf_size - cleft;
2614
2615
3.50k
            advance_buffer(pcb, cbp);
2616
3.50k
            pcb->end_status = sgets(pcb->s, pcb->data + cleft, nread, &nread);
2617
3.50k
            set_cb_end(pcb, pcb->data + cleft + nread);
2618
3.50k
            cbp = pcb->data;
2619
3.50k
        }
2620
374k
        r.ptr = cbp - 1;
2621
374k
        r.limit = pcb->end - 1;
2622
374k
        w.ptr = data - 1;
2623
374k
        w.limit = w.ptr + bytes;
2624
374k
        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
374k
        case cmd_compress_cfe:
2635
374k
            {
2636
374k
                stream_CFD_state sstate;
2637
2638
374k
                clist_cfd_init(&sstate,
2639
374k
                               width_bytes << 3 /*width_bits */ ,
2640
374k
                               rep_height, mem);
2641
374k
                (*s_CFD_template.process)
2642
374k
                    ((stream_state *)&sstate, &r, &w, true);
2643
374k
                (*s_CFD_template.release)
2644
374k
                    ((stream_state *)&sstate);
2645
374k
            }
2646
374k
            break;
2647
0
        default:
2648
0
            return_error(gs_error_unregistered);
2649
374k
        }
2650
374k
        cbp = r.ptr + 1;
2651
1.48M
    } else if (rep_height * bits->num_planes > 1 && width_bytes != bits->raster) {
2652
1.47M
        cbp = cmd_read_short_bits(pcb, data, bytes,
2653
1.47M
                                  width_bytes, rep_height * bits->num_planes,
2654
1.47M
                                  bits->raster, cbp);
2655
1.47M
    } else {
2656
8.09k
        cbp = cmd_read_data(pcb, data, bytes, cbp);
2657
8.09k
    }
2658
1.85M
    if (bits->width > rep_width)
2659
6.06k
        bits_replicate_horizontally(data,
2660
6.06k
                                    rep_width * depth, rep_height * bits->num_planes,
2661
6.06k
                                    bits->raster,
2662
6.06k
                                    bits->width * depth,
2663
6.06k
                                    bits->raster);
2664
1.85M
    if (bits->height > rep_height)
2665
662
        bits_replicate_vertically(data,
2666
662
                                  rep_height, bits->raster,
2667
662
                                  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.85M
    pcb->ptr = cbp;
2673
1.85M
    return 0;
2674
1.85M
}
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
262k
{
2680
    /* free the existing buffer, if any (usually none) */
2681
262k
    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
262k
    if (ht_size > cbuf_ht_seg_max_size) {
2691
245k
        pht_buff->pbuff = gs_alloc_bytes(mem, ht_size, "read_alloc_ht_buff");
2692
245k
        if (pht_buff->pbuff == 0)
2693
0
            return_error(gs_error_VMerror);
2694
245k
    }
2695
262k
    pht_buff->ht_size = ht_size;
2696
262k
    pht_buff->read_size = 0;
2697
262k
    pht_buff->pcurr = pht_buff->pbuff;
2698
262k
    return 0;
2699
262k
}
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
508k
{
2710
508k
    const byte *                cbp = pcb->ptr;
2711
508k
    const byte *                pbuff = 0;
2712
508k
    uint                        ht_size = pht_buff->ht_size, seg_size;
2713
508k
    int                         code = 0;
2714
2715
    /* get the segment size; refill command buffer if necessary */
2716
508k
    enc_u_getw(seg_size, cbp);
2717
508k
    if (pcb->warn_limit - cbp < (int)seg_size) { /* cbp can be past warn_limit */
2718
247k
        code = top_up_cbuf(pcb, &cbp);
2719
247k
        if (code < 0)
2720
0
            return code;
2721
247k
        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
247k
    }
2726
2727
508k
    if (pht_buff->pbuff == 0) {
2728
        /* if not separate buffer, must be only one segment */
2729
17.2k
        if (seg_size != ht_size)
2730
0
            return_error(gs_error_unknownerror);
2731
17.2k
        pbuff = cbp;
2732
491k
    } else {
2733
491k
        if (seg_size + pht_buff->read_size > pht_buff->ht_size)
2734
0
            return_error(gs_error_unknownerror);
2735
491k
        memcpy(pht_buff->pcurr, cbp, seg_size);
2736
491k
        pht_buff->pcurr += seg_size;
2737
491k
        if ((pht_buff->read_size += seg_size) == ht_size)
2738
245k
            pbuff = pht_buff->pbuff;
2739
491k
    }
2740
2741
    /* if everything has been read, convert back to a halftone */
2742
508k
    if (pbuff != 0) {
2743
262k
        code = gx_ht_read_and_install(pgs, dev, pbuff, ht_size, mem);
2744
2745
        /* release any buffered information */
2746
262k
        if (pht_buff->pbuff != 0) {
2747
245k
            gs_free_object(mem, pht_buff->pbuff, "read_alloc_ht_buff");
2748
245k
            pht_buff->pbuff = 0;
2749
245k
            pht_buff->pcurr = 0;
2750
245k
        }
2751
262k
        pht_buff->ht_size = 0;
2752
262k
        pht_buff->read_size = 0;
2753
262k
    }
2754
2755
    /* update the command buffer ponter */
2756
508k
    pcb->ptr = cbp + seg_size;
2757
2758
508k
    return code;
2759
508k
}
2760
2761
static int
2762
read_set_misc2(command_buf_t *pcb, gs_gstate *pgs, segment_notes *pnotes)
2763
325k
{
2764
325k
    const byte *cbp = pcb->ptr;
2765
325k
    uint mask, cb;
2766
2767
325k
    if_debug0m('L', pgs->memory, "\n");
2768
325k
    cmd_getw(mask, cbp);
2769
325k
    if (mask & cap_join_known) {
2770
42.4k
        cb = *cbp++;
2771
42.4k
        pgs->line_params.start_cap = (gs_line_cap)((cb >> 3) & 7);
2772
42.4k
        pgs->line_params.join = (gs_line_join)(cb & 7);
2773
42.4k
        if_debug2m('L', pgs->memory, "[L]      start_cap=%d join=%d\n",
2774
42.4k
                   pgs->line_params.start_cap, pgs->line_params.join);
2775
42.4k
        cb = *cbp++;
2776
42.4k
        pgs->line_params.end_cap = (gs_line_cap)((cb >> 3) & 7);
2777
42.4k
        pgs->line_params.dash_cap = (gs_line_cap)(cb & 7);
2778
42.4k
        if_debug2m('L', pgs->memory, "[L]      end_cap=%d dash_cap=%d\n",
2779
42.4k
                   pgs->line_params.end_cap, pgs->line_params.dash_cap);
2780
42.4k
    }
2781
325k
    if (mask & cj_ac_sa_known) {
2782
17.0k
        cb = *cbp++;
2783
17.0k
        pgs->line_params.curve_join = ((cb >> 2) & 7) - 1;
2784
17.0k
        pgs->accurate_curves = (cb & 2) != 0;
2785
17.0k
        pgs->stroke_adjust = cb & 1;
2786
17.0k
        if_debug3m('L', pgs->memory, "[L]      CJ=%d AC=%d SA=%d\n",
2787
17.0k
                   pgs->line_params.curve_join, pgs->accurate_curves,
2788
17.0k
                   pgs->stroke_adjust);
2789
17.0k
    }
2790
325k
    if (mask & flatness_known) {
2791
24.1k
        cmd_get_value(pgs->flatness, cbp);
2792
24.1k
        if_debug1m('L', pgs->memory, "[L]      flatness=%g\n", pgs->flatness);
2793
24.1k
    }
2794
325k
    if (mask & line_width_known) {
2795
119k
        float width;
2796
2797
119k
        cmd_get_value(width, cbp);
2798
119k
        if_debug1m('L', pgs->memory, "[L]      line_width=%g\n", width);
2799
119k
        gx_set_line_width(&pgs->line_params, width);
2800
119k
    }
2801
325k
    if (mask & miter_limit_known) {
2802
2.24k
        float limit;
2803
2804
2.24k
        cmd_get_value(limit, cbp);
2805
2.24k
        if_debug1m('L', pgs->memory, "[L]      miter_limit=%g\n", limit);
2806
2.24k
        gx_set_miter_limit(&pgs->line_params, limit);
2807
2.24k
    }
2808
325k
    if (mask & op_bm_tk_known) {
2809
159k
        cb = *cbp++;
2810
159k
        pgs->blend_mode = cb >> 3;
2811
159k
        pgs->text_knockout = cb & 1;
2812
        /* the following usually have no effect; see gxclpath.c */
2813
159k
        cb = *cbp++;
2814
159k
        pgs->overprint_mode = (cb >> 2) & 1;
2815
159k
        pgs->stroke_overprint = (cb >> 1) & 1;
2816
159k
        pgs->overprint = cb & 1;
2817
159k
        cb = *cbp++;
2818
159k
        pgs->renderingintent = cb;
2819
159k
        if_debug6m('L', pgs->memory, "[L]      BM=%d TK=%d OPM=%d OP=%d op=%d RI=%d\n",
2820
159k
                   pgs->blend_mode, pgs->text_knockout, pgs->overprint_mode,
2821
159k
                   pgs->stroke_overprint, pgs->overprint, pgs->renderingintent);
2822
159k
    }
2823
325k
    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
325k
    if (mask & ais_known) {
2829
11.3k
        cmd_get_value(pgs->alphaisshape, cbp);
2830
11.3k
        if_debug1m('L', pgs->memory, "[L]      alphaisshape=%d\n", pgs->alphaisshape);
2831
11.3k
    }
2832
325k
    if (mask & stroke_alpha_known) {
2833
71.3k
        cmd_get_value(pgs->strokeconstantalpha, cbp);
2834
71.3k
        if_debug1m('L', pgs->memory, "[L]      strokeconstantalpha=%g\n", pgs->strokeconstantalpha);
2835
71.3k
    }
2836
325k
    if (mask & fill_alpha_known) {
2837
94.0k
        cmd_get_value(pgs->fillconstantalpha, cbp);
2838
94.0k
        if_debug1m('L', pgs->memory, "[L]      fillconstantalpha=%u\n", (uint)(pgs->fillconstantalpha));
2839
94.0k
    }
2840
325k
    pcb->ptr = cbp;
2841
325k
    return 0;
2842
325k
}
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
78.5k
{
2848
78.5k
    const byte *cbp = pcb->ptr;
2849
78.5k
    byte b = *cbp++;
2850
78.5k
    int index = b >> 4;
2851
78.5k
    gs_color_space *pcs;
2852
78.5k
    int code = 0;
2853
78.5k
    cmm_profile_t *picc_profile;
2854
78.5k
    clist_icc_color_t icc_information;
2855
2856
78.5k
    if_debug3m('L', mem, " %d%s%s\n", index,
2857
78.5k
               (b & 8 ? " (indexed)" : ""),
2858
78.5k
               (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
78.5k
    memcpy(&icc_information, cbp, sizeof(clist_icc_color_t));
2864
78.5k
    cbp = cbp + sizeof(clist_icc_color_t);
2865
78.5k
    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
78.5k
    case gs_color_space_index_ICC:
2876
        /* build the color space object */
2877
78.5k
        code = gs_cspace_build_ICC(&pcs, NULL, mem);
2878
        /* Don't bother getting the ICC stuff from the clist yet */
2879
78.5k
        picc_profile = gsicc_profile_new(NULL, cdev->memory, NULL, 0);
2880
78.5k
        if (picc_profile == NULL)
2881
0
            return gs_rethrow(-1, "Failed to find ICC profile during clist read");
2882
78.5k
        picc_profile->num_comps = icc_information.icc_num_components;
2883
78.5k
        picc_profile->hashcode = icc_information.icc_hash;
2884
78.5k
        picc_profile->hash_is_valid = true;
2885
78.5k
        picc_profile->islab = icc_information.is_lab;
2886
78.5k
        picc_profile->default_match = icc_information.default_match;
2887
78.5k
        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
78.5k
        picc_profile->dev = (gx_device*) cdev;
2893
        /* Assign it to the colorspace */
2894
78.5k
        code = gsicc_set_gscs_profile(pcs, picc_profile, mem);
2895
        /* And we no longer need our reference to the profile */
2896
78.5k
        gsicc_adjust_profile_rc(picc_profile, -1, "read_set_color_space");
2897
78.5k
        break;
2898
0
    default:
2899
0
        code = gs_note_error(gs_error_rangecheck);      /* others are NYI */
2900
0
        goto out;
2901
78.5k
    }
2902
2903
78.5k
    if (pcs == NULL) {
2904
0
        code = gs_note_error(gs_error_VMerror);
2905
0
        goto out;
2906
0
    }
2907
2908
78.5k
    if (b & 8) {
2909
6.54k
        bool use_proc = (b & 4) != 0;
2910
6.54k
        int hival;
2911
6.54k
        int num_values;
2912
6.54k
        byte *data;
2913
6.54k
        uint data_size;
2914
6.54k
        gs_color_space *pcs_indexed;
2915
2916
6.54k
        pcs_indexed = gs_cspace_alloc(mem, &gs_color_space_type_Indexed);
2917
6.54k
        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
6.54k
        pcs_indexed->base_space = pcs;
2923
6.54k
        pcs = pcs_indexed;
2924
6.54k
        pcs->params.indexed.use_proc = 0;
2925
6.54k
        pcs->params.indexed.lookup.table.data = 0;
2926
6.54k
        pcs->params.indexed.lookup.table.size = 0;
2927
6.54k
        cmd_getw(hival, cbp);
2928
6.54k
        pcs->params.indexed.n_comps = gs_color_space_num_components(pcs->base_space);
2929
6.54k
        num_values = (hival + 1) * pcs->params.indexed.n_comps;
2930
6.54k
        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
6.54k
        } else {
2943
6.54k
            byte *table = gs_alloc_string(mem, num_values, "color_space indexed table");
2944
2945
6.54k
            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
6.54k
            pcs->params.indexed.lookup.table.data = table;
2951
6.54k
            pcs->params.indexed.lookup.table.size = num_values;
2952
6.54k
            data = table;
2953
6.54k
            data_size = num_values;
2954
6.54k
        }
2955
6.54k
        cbp = cmd_read_data(pcb, data, data_size, cbp);
2956
6.54k
        pcs->params.indexed.hival = hival;
2957
6.54k
        pcs->params.indexed.use_proc = use_proc;
2958
6.54k
    }
2959
2960
    /* Release reference to old color space before installing new one. */
2961
78.5k
    if (pgs->color[0].color_space != NULL)
2962
78.5k
        rc_decrement_only_cs(pgs->color[0].color_space, "read_set_color_space");
2963
78.5k
    pgs->color[0].color_space = pcs;
2964
78.5k
out:
2965
78.5k
    pcb->ptr = cbp;
2966
78.5k
    return code;
2967
78.5k
}
2968
2969
static int
2970
read_begin_image(command_buf_t *pcb, gs_image_common_t *pic,
2971
                 gs_color_space *pcs)
2972
90.2k
{
2973
90.2k
    uint index = *(pcb->ptr)++;
2974
90.2k
    const gx_image_type_t *image_type = gx_image_type_table[index];
2975
90.2k
    stream s;
2976
90.2k
    int code;
2977
2978
    /* This is sloppy, but we don't have enough information to do better. */
2979
90.2k
    code = top_up_cbuf(pcb, &pcb->ptr);
2980
90.2k
    if (code < 0)
2981
0
        return code;
2982
90.2k
    s_init(&s, NULL);
2983
90.2k
    sread_string(&s, pcb->ptr, pcb->end - pcb->ptr);
2984
90.2k
    code = image_type->sget(pic, &s, pcs);
2985
90.2k
    pcb->ptr = sbufptr(&s);
2986
90.2k
    pic->imagematrices_are_untrustworthy = 0;
2987
90.2k
    return code;
2988
90.2k
}
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
26.5M
{
3086
26.5M
    const byte *                cbp = pcb->ptr;
3087
26.5M
    int                         comp_id = 0, code = 0;
3088
26.5M
    const gs_composite_type_t * pcomp_type = 0;
3089
3090
    /* fill the command buffer (see comment above) */
3091
26.5M
    if (pcb->end - cbp < MAX_CLIST_COMPOSITOR_SIZE + sizeof(comp_id)) {
3092
337k
        code = top_up_cbuf(pcb, &cbp);
3093
337k
        if (code < 0)
3094
0
            return code;
3095
337k
    }
3096
3097
    /* find the appropriate compositor method vector */
3098
26.5M
    comp_id = *cbp++;
3099
26.5M
    if ((pcomp_type = gs_find_compositor(comp_id)) == 0)
3100
0
        return_error(gs_error_unknownerror);
3101
3102
    /* de-serialize the compositor */
3103
26.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
26.5M
    if ( code > MAX_CLIST_COMPOSITOR_SIZE )
3107
0
        return_error(gs_error_rangecheck);
3108
3109
26.5M
    if (code > 0)
3110
26.5M
        cbp += code;
3111
26.5M
    pcb->ptr = cbp;
3112
26.5M
    return code;
3113
26.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
23.1M
{
3119
23.1M
    gx_device *tdev = *ptarget;
3120
23.1M
    int code;
3121
3122
23.1M
    code = pcomp->type->procs.adjust_ctm(pcomp, x0, y0, pgs);
3123
23.1M
    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
23.1M
    code = dev_proc(tdev, composite)(tdev, &tdev, pcomp, pgs, mem, (gx_device*) cdev);
3130
23.1M
    if (code == 1) {
3131
        /* A new compositor was created that wrapped tdev. This should
3132
         * be our new target. */
3133
193k
        *ptarget = tdev;
3134
193k
        code = 0;
3135
193k
    }
3136
23.1M
    if (code < 0)
3137
0
        goto exit;
3138
3139
    /* Perform any updates for the clist device required */
3140
23.1M
    code = pcomp->type->procs.clist_compositor_read_update(pcomp,
3141
23.1M
                                        (gx_device *)cdev, tdev, pgs, mem);
3142
23.1M
exit:
3143
    /* free the compositor object */
3144
23.1M
    gs_free_object(mem, pcomp, "read_composite");
3145
3146
23.1M
    return code;
3147
23.1M
}
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.50M
{
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.50M
    cbp = cmd_read_data(pcb, data, tot_bytes, cbp);
3166
3167
    /* if needed, adjust buffer contents for dest raster > width_bytes */
3168
1.50M
    if (width_bytes < raster) {
3169
1.50M
        const byte *pdata = data /*src*/ + width_bytes * height;
3170
1.50M
        byte *udata = data /*dest*/ + height * raster;
3171
3172
23.0M
        while (--height > 0) { /* don't need to move the first line to itself */
3173
21.5M
            udata -= raster, pdata -= width_bytes;
3174
21.5M
            switch (width_bytes) {
3175
0
                default:
3176
0
                    memmove(udata, pdata, width_bytes);
3177
0
                    break;
3178
7.92k
                case 6:
3179
7.92k
                    udata[5] = pdata[5];
3180
23.7k
                case 5:
3181
23.7k
                    udata[4] = pdata[4];
3182
167k
                case 4:
3183
167k
                    udata[3] = pdata[3];
3184
3.48M
                case 3:
3185
3.48M
                    udata[2] = pdata[2];
3186
16.9M
                case 2:
3187
16.9M
                    udata[1] = pdata[1];
3188
21.5M
                case 1:
3189
21.5M
                    udata[0] = pdata[0];
3190
21.5M
                case 0:;            /* shouldn't happen */
3191
21.5M
            }
3192
21.5M
        }
3193
1.50M
    }
3194
1.50M
    return cbp;
3195
1.50M
}
3196
3197
/* Read a rectangle. */
3198
static const byte *
3199
cmd_read_rect(int op, gx_cmd_rect * prect, const byte * cbp)
3200
737k
{
3201
737k
    cmd_getw(prect->x, cbp);
3202
737k
    if (op & 0xf)
3203
184k
        prect->y += ((op >> 2) & 3) - 2;
3204
553k
    else {
3205
553k
        cmd_getw(prect->y, cbp);
3206
553k
    }
3207
737k
    cmd_getw(prect->width, cbp);
3208
737k
    if (op & 0xf)
3209
184k
        prect->height += (op & 3) - 2;
3210
553k
    else {
3211
553k
        cmd_getw(prect->height, cbp);
3212
553k
    }
3213
737k
    return cbp;
3214
737k
}
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
684k
{
3232
684k
    gx_transfer_map *map;
3233
684k
    gx_transfer_map **pmap;
3234
684k
    const char *cname;
3235
3236
684k
    *pcomp_num = NULL;          /* Only used for color transfer maps */
3237
684k
    switch (map_index) {
3238
228k
        case cmd_map_transfer:
3239
228k
            if_debug0m('L', mem, " transfer");
3240
228k
            rc_unshare_struct(pgs->set_transfer.gray, gx_transfer_map,
3241
228k
                &st_transfer_map, mem, return_error(gs_error_VMerror),
3242
228k
                "cmd_select_map(default_transfer)");
3243
228k
            map = pgs->set_transfer.gray;
3244
            /* Release all current maps */
3245
228k
            rc_decrement(pgs->set_transfer.red, "cmd_select_map(red)");
3246
228k
            pgs->set_transfer.red = NULL;
3247
228k
            pgs->set_transfer.red_component_num = -1;
3248
228k
            rc_decrement(pgs->set_transfer.green, "cmd_select_map(green)");
3249
228k
            pgs->set_transfer.green = NULL;
3250
228k
            pgs->set_transfer.green_component_num = -1;
3251
228k
            rc_decrement(pgs->set_transfer.blue, "cmd_select_map(blue)");
3252
228k
            pgs->set_transfer.blue = NULL;
3253
228k
            pgs->set_transfer.blue_component_num = -1;
3254
228k
            goto transfer2;
3255
6
        case cmd_map_transfer_0:
3256
6
            pmap = &pgs->set_transfer.red;
3257
6
            *pcomp_num = &pgs->set_transfer.red_component_num;
3258
6
            goto transfer1;
3259
6
        case cmd_map_transfer_1:
3260
6
            pmap = &pgs->set_transfer.green;
3261
6
            *pcomp_num = &pgs->set_transfer.green_component_num;
3262
6
            goto transfer1;
3263
6
        case cmd_map_transfer_2:
3264
6
            pmap = &pgs->set_transfer.blue;
3265
6
            *pcomp_num = &pgs->set_transfer.blue_component_num;
3266
6
            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
18
transfer1:  if_debug1m('L', mem, " transfer[%d]", (int)(map_index - cmd_map_transfer_0));
3271
18
            rc_unshare_struct(*pmap, gx_transfer_map, &st_transfer_map, mem,
3272
18
                return_error(gs_error_VMerror), "cmd_select_map(transfer)");
3273
18
            map = *pmap;
3274
3275
228k
transfer2:  if (cont != cmd_map_other) {
3276
0
                gx_set_identity_transfer(map);
3277
0
                *pmdata = 0;
3278
0
                *pcount = 0;
3279
0
                return 0;
3280
0
            }
3281
228k
            break;
3282
228k
        case cmd_map_black_generation:
3283
228k
            if_debug0m('L', mem, " black generation");
3284
228k
            pmap = &pgs->black_generation;
3285
228k
            cname = "cmd_select_map(black generation)";
3286
228k
            goto alloc;
3287
228k
        case cmd_map_undercolor_removal:
3288
228k
            if_debug0m('L', mem, " undercolor removal");
3289
228k
            pmap = &pgs->undercolor_removal;
3290
228k
            cname = "cmd_select_map(undercolor removal)";
3291
456k
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
456k
            rc_unshare_struct(*pmap, gx_transfer_map, &st_transfer_map,
3299
456k
                              mem, return_error(gs_error_VMerror), cname);
3300
456k
            map = *pmap;
3301
456k
            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
456k
            break;
3308
456k
        default:
3309
0
            *pmdata = 0;
3310
0
            return 0;
3311
684k
    }
3312
684k
    map->proc = gs_mapped_transfer;
3313
684k
    *pmdata = map->values;
3314
684k
    *pcount = sizeof(map->values);
3315
684k
    return 0;
3316
684k
}
3317
3318
/* Create a device halftone for the imager if necessary. */
3319
static int
3320
cmd_create_dev_ht(gx_device_halftone **ppdht, gs_memory_t *mem)
3321
0
{
3322
0
    gx_device_halftone *pdht = *ppdht;
3323
3324
0
    if (pdht == 0) {
3325
0
        rc_header rc;
3326
3327
0
        rc_alloc_struct_1(pdht, gx_device_halftone, &st_device_halftone, mem,
3328
0
                          return_error(gs_error_VMerror),
3329
0
                          "cmd_create_dev_ht");
3330
0
        rc = pdht->rc;
3331
0
        memset(pdht, 0, sizeof(*pdht));
3332
0
        pdht->rc = rc;
3333
0
        *ppdht = pdht;
3334
0
    }
3335
0
    return 0;
3336
0
}
3337
3338
/* Resize the halftone components array if necessary. */
3339
static int
3340
cmd_resize_halftone(gx_device_halftone **ppdht, uint num_comp,
3341
                    gs_memory_t * mem)
3342
0
{
3343
0
    int code = cmd_create_dev_ht(ppdht, mem);
3344
0
    gx_device_halftone *pdht = *ppdht;
3345
3346
0
    if (code < 0)
3347
0
        return code;
3348
0
    if (num_comp != pdht->num_comp) {
3349
0
        gx_ht_order_component *pcomp;
3350
3351
        /*
3352
         * We must be careful not to shrink or free the components array
3353
         * before releasing any relevant elements.
3354
         */
3355
0
        if (num_comp < pdht->num_comp) {
3356
0
            uint i;
3357
3358
            /* Don't release the default order. */
3359
0
            for (i = pdht->num_comp; i-- > num_comp;)
3360
0
                if (pdht->components[i].corder.bit_data != pdht->order.bit_data)
3361
0
                    gx_ht_order_release(&pdht->components[i].corder, mem, true);
3362
0
            if (num_comp == 0) {
3363
0
                gs_free_object(mem, pdht->components, "cmd_resize_halftone");
3364
0
                pcomp = 0;
3365
0
            } else {
3366
0
                pcomp = gs_resize_object(mem, pdht->components, num_comp,
3367
0
                                         "cmd_resize_halftone");
3368
0
                if (pcomp == 0) {
3369
0
                    pdht->num_comp = num_comp;  /* attempt consistency */
3370
0
                    return_error(gs_error_VMerror);
3371
0
                }
3372
0
            }
3373
0
        } else {
3374
            /* num_comp > pdht->num_comp */
3375
0
            if (pdht->num_comp == 0)
3376
0
                pcomp = gs_alloc_struct_array(mem, num_comp,
3377
0
                                              gx_ht_order_component,
3378
0
                                              &st_ht_order_component_element,
3379
0
                                              "cmd_resize_halftone");
3380
0
            else
3381
0
                pcomp = gs_resize_object(mem, pdht->components, num_comp,
3382
0
                                         "cmd_resize_halftone");
3383
0
            if (pcomp == 0)
3384
0
                return_error(gs_error_VMerror);
3385
0
            memset(&pcomp[pdht->num_comp], 0,
3386
0
                   sizeof(*pcomp) * (num_comp - pdht->num_comp));
3387
0
        }
3388
0
        pdht->num_comp = num_comp;
3389
0
        pdht->components = pcomp;
3390
0
    }
3391
0
    return 0;
3392
0
}
3393
3394
/* ------ Path operations ------ */
3395
3396
/* Decode a path segment. */
3397
static int
3398
clist_decode_segment(gx_path * ppath, int op, fixed vs[6],
3399
                 gs_fixed_point * ppos, int x0, int y0, segment_notes notes)
3400
7.67M
{
3401
7.67M
    fixed px = ppos->x - int2fixed(x0);
3402
7.67M
    fixed py = ppos->y - int2fixed(y0);
3403
7.67M
    int code;
3404
3405
9.34M
#define A vs[0]
3406
7.67M
#define B vs[1]
3407
7.67M
#define C vs[2]
3408
7.67M
#define D vs[3]
3409
7.67M
#define E vs[4]
3410
7.67M
#define F vs[5]
3411
3412
7.67M
    switch (op) {
3413
1.34M
        case cmd_opv_rmoveto:
3414
1.34M
            code = gx_path_add_point(ppath, px += A, py += B);
3415
1.34M
            break;
3416
738k
        case cmd_opv_rlineto:
3417
738k
            code = gx_path_add_line_notes(ppath, px += A, py += B, notes);
3418
738k
            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.60M
        case cmd_opv_hlineto:
3423
1.60M
            code = gx_path_add_line_notes(ppath, px += A, py, notes);
3424
1.60M
            break;
3425
1.73M
        case cmd_opv_vlineto:
3426
1.73M
            code = gx_path_add_line_notes(ppath, px, py += A, notes);
3427
1.73M
            break;
3428
124k
        case cmd_opv_rmlineto:
3429
124k
            if ((code = gx_path_add_point(ppath, px += A, py += B)) < 0)
3430
0
                break;
3431
124k
            code = gx_path_add_line_notes(ppath, px += C, py += D, notes);
3432
124k
            break;
3433
76.7k
        case cmd_opv_rm2lineto:
3434
76.7k
            if ((code = gx_path_add_point(ppath, px += A, py += B)) < 0 ||
3435
76.7k
                (code = gx_path_add_line_notes(ppath, px += C, py += D,
3436
76.7k
                                               notes)) < 0
3437
76.7k
                )
3438
0
                break;
3439
76.7k
            code = gx_path_add_line_notes(ppath, px += E, py += F, notes);
3440
76.7k
            break;
3441
13.8k
        case cmd_opv_rm3lineto:
3442
13.8k
            if ((code = gx_path_add_point(ppath, px += A, py += B)) < 0 ||
3443
13.8k
                (code = gx_path_add_line_notes(ppath, px += C, py += D,
3444
13.8k
                                               notes)) < 0 ||
3445
13.8k
                (code = gx_path_add_line_notes(ppath, px += E, py += F,
3446
13.8k
                                               notes)) < 0
3447
13.8k
                )
3448
0
                break;
3449
13.8k
            code = gx_path_add_line_notes(ppath, px -= C, py -= D, notes);
3450
13.8k
            break;
3451
1.08M
        case cmd_opv_rrcurveto: /* a b c d e f => a b a+c b+d a+c+e b+d+f */
3452
1.09M
rrc:        E += (C += A);
3453
1.09M
            F += (D += B);
3454
1.35M
curve:      code = gx_path_add_curve_notes(ppath, px + A, py + B,
3455
1.35M
                                           px + C, py + D,
3456
1.35M
                                           px + E, py + F, notes);
3457
1.35M
            px += E, py += F;
3458
1.35M
            break;
3459
111k
        case cmd_opv_hvcurveto: /* a b c d => a 0 a+b c a+b c+d */
3460
117k
hvc:        F = C + D, D = C, E = C = A + B, B = 0;
3461
117k
            goto curve;
3462
106k
        case cmd_opv_vhcurveto: /* a b c d => 0 a b a+c b+d a+c */
3463
119k
vhc:        E = B + D, F = D = A + C, C = B, B = A, A = 0;
3464
119k
            goto curve;
3465
11.0k
        case cmd_opv_nrcurveto: /* a b c d => 0 0 a b a+c b+d */
3466
11.0k
            F = B + D, E = A + C, D = B, C = A, B = A = 0;
3467
11.0k
            goto curve;
3468
12.6k
        case cmd_opv_rncurveto: /* a b c d => a b a+c b+d a+c b+d */
3469
12.6k
            F = D += B, E = C += A;
3470
12.6k
            goto curve;
3471
12.4k
        case cmd_opv_vqcurveto: /* a b => VH a b TS(a,b) TS(b,a) */
3472
12.4k
            if ((A ^ B) < 0)
3473
3.38k
                C = -B, D = -A;
3474
9.07k
            else
3475
9.07k
                C = B, D = A;
3476
12.4k
            goto vhc;
3477
5.56k
        case cmd_opv_hqcurveto: /* a b => HV a TS(a,b) b TS(b,a) */
3478
5.56k
            if ((A ^ B) < 0)
3479
1.52k
                D = -A, C = B, B = -B;
3480
4.04k
            else
3481
4.04k
                D = A, C = B;
3482
5.56k
            goto hvc;
3483
5.31k
        case cmd_opv_scurveto: /* (a b c d e f) => */
3484
5.31k
            {
3485
5.31k
                fixed a = A, b = B;
3486
3487
                /* See gxclpath.h for details on the following. */
3488
5.31k
                if (A == 0) {
3489
                    /* Previous curve was vh or vv */
3490
4.95k
                    A = E - C, B = D - F, C = C - a, D = b - D, E = a, F = -b;
3491
4.95k
                } else {
3492
                    /* Previous curve was hv or hh */
3493
363
                    A = C - E, B = F - D, C = a - C, D = D - b, E = -a, F = b;
3494
363
                }
3495
5.31k
            }
3496
5.31k
            goto rrc;
3497
679k
        case cmd_opv_closepath:
3498
679k
            if ((code = gx_path_close_subpath(ppath)) < 0)
3499
679k
                return code;;
3500
679k
            if ((code = gx_path_current_point(ppath, (gs_fixed_point *) vs)) < 0)
3501
679k
                return code;;
3502
679k
            px = A, py = B;
3503
679k
            break;
3504
0
        default:
3505
0
            return_error(gs_error_rangecheck);
3506
7.67M
    }
3507
7.67M
#undef A
3508
7.67M
#undef B
3509
7.67M
#undef C
3510
7.67M
#undef D
3511
7.67M
#undef E
3512
7.67M
#undef F
3513
7.67M
    ppos->x = px + int2fixed(x0);
3514
7.67M
    ppos->y = py + int2fixed(y0);
3515
7.67M
    return code;
3516
7.67M
}
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
26.9k
{
3530
26.9k
    const subpath *psub = ppath->first_subpath;
3531
26.9k
    const segment *pseg1;
3532
26.9k
    const segment *pseg2;
3533
26.9k
    int code;
3534
3535
26.9k
    if (psub && (pseg1 = psub->next) != 0 && (pseg2 = pseg1->next) != 0) {
3536
26.9k
        fixed px = psub->pt.x, py = psub->pt.y;
3537
26.9k
        fixed ax = pseg1->pt.x - px, ay = pseg1->pt.y - py;
3538
26.9k
        fixed bx, by;
3539
        /*
3540
         * We take advantage of the fact that the parameter lists for
3541
         * fill_parallelogram and fill_triangle are identical.
3542
         */
3543
26.9k
        dev_proc_fill_parallelogram((*fill));
3544
3545
        /* close_path of 3 point triangle adds 4th point, detected here.*/
3546
        /* close_path on parallelogram adds 5th point also ignored. */
3547
26.9k
        if (pseg2->next && !(px == pseg2->next->pt.x && py == pseg2->next->pt.y)) {
3548
            /* Parallelogram */
3549
22.6k
            fill = dev_proc(dev, fill_parallelogram);
3550
22.6k
            bx = pseg2->pt.x - pseg1->pt.x;
3551
22.6k
            by = pseg2->pt.y - pseg1->pt.y;
3552
22.6k
        } else {
3553
            /* Triangle */
3554
4.37k
            fill = dev_proc(dev, fill_triangle);
3555
4.37k
            bx = pseg2->pt.x - px;
3556
4.37k
            by = pseg2->pt.y - py;
3557
4.37k
        }
3558
26.9k
        code = fill(dev, px, py, ax, ay, bx, by, pdcolor, lop);
3559
26.9k
    } else
3560
0
        code = 0;
3561
26.9k
    gx_path_new(ppath);
3562
26.9k
    return code;
3563
26.9k
}