Coverage Report

Created: 2025-06-10 07:27

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