Coverage Report

Created: 2025-11-16 07:40

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