Coverage Report

Created: 2026-02-14 07:09

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