Coverage Report

Created: 2026-07-24 07:44

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ghostpdl/base/gxclrast.c
Line
Count
Source
1
/* Copyright (C) 2001-2026 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
788M
  BEGIN\
91
788M
    if ( *p < 0x80 ) var = *p++;\
92
788M
    else { const byte *_cbp; var = cmd_get_w(p, &_cbp); p = _cbp; }\
93
788M
  END
94
95
static long
96
cmd_get_w(const byte * p, const byte ** rp)
97
647M
{
98
647M
    int val = *p++ & 0x7f;
99
647M
    int shift = 7;
100
101
1.23G
    for (; val |= (int)(*p & 0x7f) << shift, *p++ > 0x7f; shift += 7);
102
647M
    *rp = p;
103
647M
    return val;
104
647M
}
105
106
/* Get a variable-length fractional operand. */
107
#define cmd_getfrac(var, p)\
108
4.87M
  BEGIN\
109
4.87M
    if ( !(*p & 1) ) var = (*p++) << 24;\
110
4.87M
    else { const byte *_cbp; var = cmd_get_frac31(p, &_cbp); p = _cbp; }\
111
4.87M
  END
112
static frac31
113
cmd_get_frac31(const byte * p, const byte ** rp)
114
1.87M
{
115
1.87M
    frac31 val = (*p++ & 0xFE) << 24;
116
1.87M
    int shift = 24 - 7;
117
118
1.91M
    for (; val |= (frac31)(*p & 0xFE) << shift, *p++ & 1; shift -= 7);
119
1.87M
    *rp = p;
120
1.87M
    return val;
121
1.87M
}
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
34.3M
{
144
34.3M
    pcb->end = end;
145
34.3M
    pcb->warn_limit = pcb->data + (pcb->size - cmd_largest_size + 1);
146
34.3M
    if ( pcb->warn_limit > pcb->end )
147
1.93M
        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
34.3M
}
151
152
static inline void
153
advance_buffer(command_buf_t *pcb, const byte *cbp)
154
32.3M
{
155
#ifdef DEBUG
156
    stream_state *st = pcb->s->state;
157
158
    top_up_offset_map(st, pcb->data, cbp, pcb->end);
159
#endif
160
32.3M
    memmove(pcb->data, cbp, pcb->end - cbp);
161
32.3M
}
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
40.9M
{
177
40.9M
    uint nread;
178
40.9M
    const byte *cbp = *pcbp;
179
40.9M
    byte *cb_top = pcb->data + (pcb->end - cbp);
180
181
40.9M
    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
40.9M
    if (seofp(pcb->s)) {
187
        /* Can't use offset_map, because s_close resets s->state. Don't top up. */
188
8.59M
        pcb->end_status = pcb->s->end_status;
189
8.59M
        return 0;
190
8.59M
    }
191
32.3M
    advance_buffer(pcb, cbp);
192
32.3M
    nread = pcb->end - cb_top;
193
32.3M
    pcb->end_status = sgets(pcb->s, cb_top, nread, &nread);
194
32.3M
    if ( nread == 0 ) {
195
        /* No data for this band at all. */
196
64
        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
64
        *cb_top = cmd_opv_end_run;
203
64
        nread = 1;
204
64
    }
205
32.3M
    set_cb_end(pcb, cb_top + nread);
206
32.3M
    process_interrupts(pcb->s->memory);
207
32.3M
    *pcbp = pcb->data;
208
32.3M
    return 0;
209
32.3M
}
210
211
/* Read data from the command buffer and stream. */
212
/* From the command_buffer pcb, read rsize bytes to ptr, starting from cbp.
213
 * Return the new value for pcb->ptr. */
214
static const byte *
215
cmd_read_data(command_buf_t *pcb, byte *ptr, uint rsize, const byte *cbp)
216
12.6M
{
217
12.6M
    if (pcb->end - cbp >= rsize) {
218
12.6M
        memmove(ptr, cbp, rsize);
219
12.6M
        return cbp + rsize;
220
12.6M
    } else {
221
27.5k
        uint cleft = pcb->end - cbp;
222
27.5k
        uint rleft = rsize - cleft;
223
224
27.5k
        memmove(ptr, cbp, cleft);
225
27.5k
        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
27.5k
        return pcb->end;
234
27.5k
    }
235
12.6M
}
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.67M
{
241
1.67M
    memcpy(pvar, cbp, var_size);
242
1.67M
    return cbp + var_size;
243
1.67M
}
244
#define cmd_get_value(var, cbp)\
245
1.67M
  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
123M
{
304
123M
    if (*ppcomp_last == NULL) {
305
7.99M
        pcomp->prev = pcomp->next = NULL;
306
7.99M
        *ppcomp_last = *ppcomp_first = pcomp;
307
115M
    } else {
308
115M
        (*ppcomp_last)->next = pcomp;
309
115M
        pcomp->prev = *ppcomp_last;
310
115M
        pcomp->next = NULL;
311
115M
        *ppcomp_last = pcomp;
312
115M
    }
313
123M
}
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
123M
{
350
123M
    if (*ppcomp_last == *ppcomp_first) {
351
7.99M
        if (*ppcomp_last == pcomp) {
352
7.99M
            *ppcomp_last = *ppcomp_first = NULL;
353
7.99M
            return 0;
354
7.99M
        } else
355
0
            return_error(gs_error_unregistered); /* Must not happen. */
356
115M
    } else {
357
115M
        gs_composite_t *pcomp_next = pcomp->next, *pcomp_prev = pcomp->prev;
358
359
115M
        if (*ppcomp_last == pcomp)
360
5.26M
            *ppcomp_last = pcomp->prev;
361
109M
        else
362
109M
            pcomp_next->prev = pcomp_prev;
363
115M
        if (*ppcomp_first == pcomp)
364
109M
            *ppcomp_first = pcomp->next;
365
5.26M
        else
366
5.26M
            pcomp_prev->next = pcomp_next;
367
115M
        pcomp->next = pcomp->prev = NULL;
368
115M
        return 0;
369
115M
    }
370
123M
}
371
372
static inline void
373
free_compositor(gs_composite_t *pcomp, gs_memory_t *mem)
374
8.15M
{
375
8.15M
    gs_free_object(mem, pcomp, "free_compositor");
376
8.15M
}
377
378
static inline bool
379
is_null_compositor_op(const byte *cbp, int *length)
380
68.3M
{
381
68.3M
    if (cbp[0] == cmd_opv_end_run) {
382
61.5M
        *length = 1;
383
61.5M
        return true;
384
61.5M
    }
385
6.75M
    return false;
386
68.3M
}
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.29M
{
393
121M
    while (pcomp_from != NULL) {
394
114M
        gs_composite_t *pcomp = pcomp_from;
395
114M
        int code;
396
397
114M
        pcomp_from = pcomp->next;
398
114M
        code = dequeue_compositor(ppcomp_first, ppcomp_last, pcomp);
399
114M
        if (code < 0)
400
0
            return code;
401
114M
        pcomp->idle |= idle;
402
114M
        code = apply_composite(cdev, pgs, mem, pcomp, x0, y0, target); /* Releases the compositor. */
403
114M
        if (code < 0)
404
14
            return code;
405
114M
        *tdev = *target;
406
114M
    }
407
6.29M
    return 0;
408
6.29M
}
409
410
static void
411
mark_as_idle(gs_composite_t *pcomp_start, gs_composite_t *pcomp_end)
412
1.24M
{
413
1.24M
    gs_composite_t *pcomp = pcomp_start;
414
415
2.93M
    while (pcomp != NULL) {
416
2.93M
        pcomp->idle = true;
417
2.93M
        if (pcomp == pcomp_end)
418
1.24M
            break;
419
1.68M
        pcomp = pcomp->next;
420
1.68M
    }
421
1.24M
}
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
92.0k
{
428
92.0k
    gs_composite_t *pcomp;
429
430
526k
    do {
431
526k
        int code;
432
433
526k
        pcomp = *ppcomp_last;
434
526k
        if (pcomp == NULL)
435
0
            return 0;
436
526k
        dequeue_compositor(ppcomp_first, ppcomp_last, *ppcomp_last);
437
526k
        code = pcomp->type->procs.adjust_ctm(pcomp, x0, y0, pgs);
438
526k
        if (code < 0)
439
0
            return code;
440
526k
        free_compositor(pcomp, mem);
441
526k
    } while (pcomp != pcomp_from);
442
92.0k
    return 0;
443
92.0k
}
444
445
static int
446
read_set_misc_map(byte cb, command_buf_t *pcb, gs_gstate *pgs, gs_memory_t *mem)
447
4.58M
{
448
4.58M
    const byte *cbp = pcb->ptr;
449
4.58M
    frac *mdata;
450
4.58M
    int *pcomp_num;
451
4.58M
    uint count = 0;   /* quiet compiler */
452
4.58M
    cmd_map_contents cont =
453
4.58M
        (cmd_map_contents)(cb & 0x30) >> 4;
454
4.58M
    int code;
455
456
4.58M
    code = cmd_select_map(cb & 0xf, cont,
457
4.58M
                          pgs,
458
4.58M
                          &pcomp_num,
459
4.58M
                          &mdata, &count, mem);
460
461
4.58M
    if (code < 0)
462
0
        return code;
463
    /* Get component number if relevant */
464
4.58M
    if (pcomp_num == NULL)
465
4.58M
        cbp++;
466
639
    else {
467
639
        *pcomp_num = (int) *cbp++;
468
639
        if_debug1m('L', mem, " comp_num=%d", *pcomp_num);
469
639
    }
470
4.58M
    if (cont == cmd_map_other) {
471
3.70M
        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
3.70M
    }
485
    /* Recompute the effective transfer, */
486
    /* in case this was a transfer map. */
487
4.58M
    gx_gstate_set_effective_xfer(pgs);
488
4.58M
    pcb->ptr = cbp;
489
4.58M
    return 0;
490
4.58M
}
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
1.94M
{
516
1.94M
    byte *cbuf_storage;
517
1.94M
    command_buf_t cbuf;
518
    /* data_bits is for short copy_* bits and copy_* compressed, */
519
    /* must be aligned */
520
1.94M
    byte *data_bits = 0;
521
1.94M
    const byte *cbp;
522
1.94M
    int dev_depth;              /* May vary due to compositing devices */
523
1.94M
    int dev_depth_bytes;
524
1.94M
    int odd_delta_shift;
525
1.94M
    int num_zero_bytes;
526
1.94M
    gx_device *tdev;
527
1.94M
    gx_clist_state state;
528
1.94M
    gx_color_index *set_colors;
529
1.94M
    gx_device_color *set_dev_colors;
530
1.94M
    tile_slot *state_slot;
531
1.94M
    gx_strip_bitmap state_tile; /* parameters for reading tiles */
532
1.94M
    tile_slot tile_bits;        /* parameters of current tile */
533
1.94M
    gs_int_point tile_phase;
534
1.94M
    gx_path path;
535
1.94M
    bool in_path;
536
1.94M
    gs_fixed_point ppos;
537
1.94M
    gx_clip_path clip_path;
538
1.94M
    bool use_clip;
539
1.94M
    gx_clip_path *pcpath;
540
1.94M
    gx_device_cpath_accum clip_accum;
541
1.94M
    gs_fixed_rect target_box;
542
1.94M
    struct _cas {
543
1.94M
        bool lop_enabled;
544
1.94M
        gx_device_color dcolor;
545
1.94M
        gs_fixed_point fa_save;
546
1.94M
    } clip_save;
547
1.94M
    bool in_clip = false;
548
1.94M
    gs_gstate gs_gstate;
549
1.94M
    gx_device_color fill_color = { 0 };
550
1.94M
    gx_device_color stroke_color = { 0 };
551
1.94M
    float dash_pattern[cmd_max_dash];
552
1.94M
    gx_fill_params fill_params;
553
1.94M
    gx_stroke_params stroke_params;
554
#ifdef DEBUG
555
    gs_halftone_type halftone_type;
556
#endif
557
1.94M
    union im_ {
558
1.94M
        gs_image_common_t c;
559
1.94M
        gs_data_image_t d;
560
1.94M
        gs_image1_t i1;
561
1.94M
        gs_image4_t i4;
562
1.94M
    } image;
563
1.94M
    gs_int_rect image_rect;
564
1.94M
    gs_color_space *pcs = NULL;
565
1.94M
    gx_image_enum_common_t *image_info;
566
1.94M
    gx_image_plane_t planes[32];
567
1.94M
    uint data_height;
568
1.94M
    uint data_size;
569
1.94M
    byte *data_on_heap;
570
1.94M
    fixed vs[6];
571
1.94M
    segment_notes notes;
572
1.94M
    int data_x;
573
1.94M
    int code = 0;
574
1.94M
    ht_buff_t  ht_buff;
575
1.94M
    gx_device *const orig_target = target;
576
1.94M
    gx_device_clip clipper_dev;
577
1.94M
    bool clipper_dev_open = false;
578
1.94M
    patch_fill_state_t pfs;
579
1.94M
    int op = 0;
580
1.94M
    int plane_height = 0;
581
582
#ifdef DEBUG
583
    stream_state *st = s->state; /* Save because s_close resets s->state. */
584
#endif
585
1.94M
    gs_composite_t *pcomp_first = NULL, *pcomp_last = NULL;
586
1.94M
    tile_slot bits;             /* parameters for reading bits */
587
588
    /* pad the cbuf data area a bit (just in case) */
589
1.94M
    if ((cbuf_storage = gs_alloc_bytes(mem, cbuf_size + sizeof(double),
590
1.94M
                               "clist_playback_band(cbuf_storage)")) == NULL) {
591
0
        return_error(gs_error_VMerror);
592
0
    }
593
1.94M
    cbuf.data = (byte *)cbuf_storage;
594
1.94M
    cbuf.size = cbuf_size;
595
1.94M
    cbuf.s = s;
596
1.94M
    cbuf.end_status = 0;
597
1.94M
    set_cb_end(&cbuf, cbuf.data + cbuf.size);
598
1.94M
    cbp = cbuf.end;
599
600
1.94M
    pfs.dev = NULL; /* Indicate "not initialized". */
601
1.94M
    memset(&ht_buff, 0, sizeof(ht_buff));
602
603
    /* The following initializations are to quiet gcc warnings. */
604
1.94M
    memset(&bits, 0, sizeof(bits));
605
1.94M
    memset(&tile_bits, 0, sizeof(tile_bits));
606
1.94M
    memset(&clip_save, 0, sizeof(clip_save));
607
1.94M
    memset(&state_slot, 0, sizeof(state_slot));
608
1.94M
    ppos.x = ppos.y = 0;
609
610
1.94M
in:                             /* Initialize for a new page. */
611
1.94M
    tdev = target;
612
1.94M
    set_colors = state.colors;
613
1.94M
    set_dev_colors = state.tile_color_devn;
614
1.94M
    use_clip = false;
615
1.94M
    pcpath = NULL;
616
1.94M
    if (clipper_dev_open)
617
0
        gx_destroy_clip_device_on_stack(&clipper_dev);
618
1.94M
    clipper_dev_open = false;
619
1.94M
    notes = sn_none;
620
1.94M
    data_x = 0;
621
1.94M
    {
622
1.94M
        static const gx_clist_state cls_initial = { cls_initial_values };
623
624
1.94M
        state = cls_initial;
625
1.94M
    }
626
1.94M
    state_tile.id = gx_no_bitmap_id;
627
1.94M
    state_tile.shift = state_tile.rep_shift = 0;
628
1.94M
    state_tile.size.x = state_tile.size.y = 0;
629
1.94M
    state_tile.num_planes = 1;
630
1.94M
    tile_phase.x = x0;
631
1.94M
    tile_phase.y = y0;
632
1.94M
    gx_path_init_local(&path, mem);
633
1.94M
    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
1.94M
    {
639
1.94M
        gs_fixed_rect cbox;
640
641
1.94M
        gx_cpath_init_local(&clip_path, mem);
642
1.94M
        cbox.p.x = 0;
643
1.94M
        cbox.p.y = 0;
644
1.94M
        cbox.q.x = cdev->width;
645
1.94M
        cbox.q.y = cdev->height;
646
1.94M
        gx_cpath_from_rectangle(&clip_path, &cbox);
647
1.94M
    }
648
1.94M
    if (target != 0)
649
1.94M
        (*dev_proc(target, get_clipping_box))(target, &target_box);
650
1.94M
    memset(&gs_gstate, 0, sizeof(gs_gstate));
651
1.94M
    GS_STATE_INIT_VALUES_CLIST((&gs_gstate));
652
1.94M
    code = gs_gstate_initialize(&gs_gstate, mem);
653
1.94M
    if (code < 0)
654
0
        goto out;
655
1.94M
    gs_gstate.device = tdev;
656
1.94M
    gs_gstate.view_clip = NULL; /* Avoid issues in pdf14 fill stroke */
657
1.94M
    gs_gstate.clip_path = &clip_path;
658
1.94M
    pcs = gs_cspace_new_DeviceGray(mem);
659
1.94M
    if (pcs == NULL) {
660
0
        code = gs_note_error(gs_error_VMerror);
661
0
        goto out;
662
0
    }
663
1.94M
    code = pcs->type->install_cspace(pcs, &gs_gstate);
664
1.94M
    if (code < 0) {
665
0
        rc_decrement(pcs, "clist_playback_band");
666
0
        goto out;
667
0
    }
668
1.94M
    if (gs_gstate.icc_manager != NULL) {
669
1.94M
        gs_gstate.icc_manager->srcgtag_profile = cdev->srcgtag;
670
1.94M
        rc_increment(cdev->srcgtag);
671
1.94M
    }
672
673
1.94M
    gs_gstate.color[0].color_space = pcs; /* we already have one ref */
674
1.94M
    gs_gstate.color[1].color_space = pcs;
675
1.94M
    rc_increment_cs(pcs); /* increment for second ref */
676
    /* Initialize client color and device color */
677
1.94M
    gs_gstate.color[0].ccolor =
678
1.94M
        gs_alloc_struct(mem, gs_client_color, &st_client_color, "clist_playback_band");
679
1.94M
    gs_gstate.color[1].ccolor =
680
1.94M
        gs_alloc_struct(mem, gs_client_color, &st_client_color, "clist_playback_band");
681
1.94M
    gs_gstate.color[0].dev_color =
682
1.94M
        gs_alloc_struct(mem, gx_device_color, &st_device_color, "clist_playback_band");
683
1.94M
    gs_gstate.color[1].dev_color =
684
1.94M
        gs_alloc_struct(mem, gx_device_color, &st_device_color, "clist_playback_band");
685
1.94M
    if (gs_gstate.color[0].ccolor == 0 || gs_gstate.color[0].dev_color == 0 ||
686
1.94M
        gs_gstate.color[1].ccolor == 0 || gs_gstate.color[1].dev_color == 0
687
1.94M
        ) {
688
0
        gs_free_object(mem, gs_gstate.color[0].ccolor, "clist_playback_band");
689
0
        gs_free_object(mem, gs_gstate.color[1].ccolor, "clist_playback_band");
690
0
        gs_free_object(mem, gs_gstate.color[0].dev_color, "clist_playback_band");
691
0
        gs_free_object(mem, gs_gstate.color[1].dev_color, "clist_playback_band");
692
0
        if (clipper_dev_open)
693
0
            gx_destroy_clip_device_on_stack(&clipper_dev);
694
0
        return_error(gs_error_VMerror);
695
0
    }
696
1.94M
    gs_gstate.color[0].color_space->pclient_color_space_data =
697
1.94M
        pcs->pclient_color_space_data;
698
1.94M
    cs_full_init_color(gs_gstate.color[0].ccolor, pcs);
699
1.94M
    gx_unset_dev_color(&gs_gstate);
700
701
1.94M
    gs_gstate.color[1].color_space->pclient_color_space_data =
702
1.94M
        pcs->pclient_color_space_data;
703
1.94M
    cs_full_init_color(gs_gstate.color[1].ccolor, pcs);
704
1.94M
    gx_unset_dev_color(&gs_gstate);
705
706
    /* Remove the ICC link cache and replace with the device link cache
707
       so that we share the cache across bands */
708
1.94M
    rc_decrement(gs_gstate.icc_link_cache,"clist_playback_band");
709
1.94M
    gs_gstate.icc_link_cache = cdev->icc_cache_cl;
710
    /* Need to lock during the increment of the link cache */
711
1.94M
    gx_monitor_enter(cdev->icc_cache_cl->lock);
712
1.94M
    rc_increment(cdev->icc_cache_cl);
713
1.94M
    gx_monitor_leave(cdev->icc_cache_cl->lock); /* let everyone run */
714
1.94M
    if (code < 0)
715
0
        goto out;
716
717
1.94M
    gs_gstate.line_params.dash.pattern = dash_pattern;
718
1.94M
    if (tdev != 0) {
719
1.94M
        gx_set_cmap_procs(&gs_gstate, tdev);
720
1.94M
    }
721
1.94M
    gx_gstate_setscreenphase(&gs_gstate, -x0, -y0, gs_color_select_all);
722
#ifdef DEBUG
723
    halftone_type = ht_type_none;
724
#endif
725
1.94M
    fill_color.ccolor_valid = false;
726
1.94M
    color_unset(&fill_color);
727
1.94M
    data_bits = gs_alloc_bytes(mem, data_bits_size,
728
1.94M
                               "clist_playback_band(data_bits)");
729
1.94M
    if (data_bits == 0) {
730
0
        code = gs_note_error(gs_error_VMerror);
731
0
        goto out;
732
0
    }
733
284M
    while (code >= 0) {
734
284M
        int compress;
735
284M
        int depth = 0x7badf00d; /* Initialize against indeterminizm. */
736
284M
        int raster = 0x7badf00d; /* Initialize against indeterminizm. */
737
284M
        byte *source = NULL;  /* Initialize against indeterminizm. */
738
284M
        gx_color_index colors[2];
739
284M
        gx_color_index *pcolor;
740
284M
        gx_device_color *pdcolor = NULL;
741
284M
        gs_logical_operation_t log_op;
742
743
        /* Make sure the buffer contains a full command. */
744
284M
        if (cbp >= cbuf.warn_limit) {
745
2.88M
            if (cbuf.end_status < 0) {  /* End of file or error. */
746
14.9k
                if (cbp >= cbuf.end) {
747
0
                    code = (cbuf.end_status == EOFC ? 0 :
748
0
                            gs_note_error(gs_error_ioerror));
749
0
                    break;
750
0
                }
751
2.87M
            } else {
752
2.87M
                code = top_up_cbuf(&cbuf, &cbp);
753
2.87M
                if (code < 0)
754
0
                    goto top_up_failed;
755
2.87M
            }
756
2.88M
        }
757
284M
        op = *cbp++;
758
#ifdef DEBUG
759
        if (gs_debug_c('L')) {
760
            int64_t offset = clist_file_offset(st, cbp - 1 - cbuf.data);
761
762
            dmlprintf1(mem, "[L] %"PRIu64":", offset);
763
            clist_debug_op(mem, cbp-1);
764
        }
765
#endif
766
284M
        switch (op >> 4) {
767
35.4M
            case cmd_op_misc >> 4:
768
35.4M
                switch (op) {
769
6.62M
                    case cmd_opv_end_run:
770
6.62M
                        if_debug0m('L', mem, "\n");
771
6.62M
                        continue;
772
3.12k
                    case cmd_opv_set_tile_size:
773
3.12k
                        cbuf.ptr = cbp;
774
3.12k
                        code = read_set_tile_size(&cbuf, &tile_bits,
775
3.12k
                                    gx_device_is_pattern_clist((gx_device *)cdev));
776
3.12k
                        cbp = cbuf.ptr;
777
3.12k
                        if (code < 0)
778
0
                            goto out;
779
3.12k
                        continue;
780
25.9k
                    case cmd_opv_set_tile_phase:
781
25.9k
                        cmd_getw(state.tile_phase.x, cbp);
782
25.9k
                        cmd_getw(state.tile_phase.y, cbp);
783
25.9k
                        if_debug2m('L', mem, " (%d,%d)\n",
784
25.9k
                                   state.tile_phase.x,
785
25.9k
                                   state.tile_phase.y);
786
25.9k
                        goto set_tile_phase;
787
75.0k
                    case cmd_opv_set_screen_phaseT:
788
75.0k
                        cmd_getw(state.screen_phase[gs_color_select_texture].x, cbp);
789
75.0k
                        cmd_getw(state.screen_phase[gs_color_select_texture].y, cbp);
790
75.0k
                        if_debug2m('L', mem, " (%d,%d)\n",
791
75.0k
                                   state.screen_phase[0].x,
792
75.0k
                                   state.screen_phase[gs_color_select_texture].y);
793
75.0k
                        gx_gstate_setscreenphase(&gs_gstate,
794
75.0k
                                                 state.screen_phase[gs_color_select_texture].x - x0,
795
75.0k
                                                 state.screen_phase[gs_color_select_texture].y - y0,
796
75.0k
                                                 gs_color_select_texture);
797
75.0k
                        continue;
798
0
                    case cmd_opv_set_screen_phaseS:
799
0
                        cmd_getw(state.screen_phase[gs_color_select_source].x, cbp);
800
0
                        cmd_getw(state.screen_phase[gs_color_select_source].y, cbp);
801
0
                        if_debug2m('L', mem, " (%d,%d)\n",
802
0
                                   state.screen_phase[gs_color_select_source].x,
803
0
                                   state.screen_phase[gs_color_select_source].y);
804
0
                        gx_gstate_setscreenphase(&gs_gstate,
805
0
                                                 state.screen_phase[gs_color_select_source].x - x0,
806
0
                                                 state.screen_phase[gs_color_select_source].y - y0,
807
0
                                                 gs_color_select_source);
808
0
                        continue;
809
12.2k
                    case cmd_opv_set_tile_bits:
810
12.2k
                        bits = tile_bits;
811
12.2k
                        compress = 0;
812
7.05M
                      stb:
813
7.05M
                        cbuf.ptr = cbp;
814
7.05M
                        code = read_set_bits(&cbuf, &bits, compress,
815
7.05M
                                             &state, &state_tile, &state_slot,
816
7.05M
                                             cdev, mem);
817
7.05M
                        cbp = cbuf.ptr;
818
7.05M
                        if (code < 0)
819
0
                            goto out;
820
7.05M
                        goto stp;
821
7.05M
                    case cmd_opv_set_bits:
822
7.04M
do_opv_set_bits:
823
7.04M
                        compress = *cbp & 3;
824
7.04M
                        bits.head.depth = *cbp++ >> 2;
825
7.04M
                        cmd_getw(bits.width, cbp);
826
7.04M
                        cmd_getw(bits.height, cbp);
827
7.04M
                        if (op == cmd_opv_set_bits_planar)
828
7.04M
                            cmd_getw(bits.num_planes, cbp);
829
7.04M
                        else
830
7.04M
                            bits.num_planes = 1;
831
7.04M
                        if_debug5m('L', mem, " compress=%d depth=%d size=(%d,%d) planes=%d",
832
7.04M
                                   compress, bits.head.depth,
833
7.04M
                                   bits.width, bits.height, bits.num_planes);
834
7.04M
                        bits.raster =
835
7.04M
                            bitmap_raster(bits.width * bits.head.depth);
836
7.04M
                        bits.x_reps = bits.y_reps = 1;
837
7.04M
                        bits.shift = bits.rep_shift = 0;
838
7.04M
                        goto stb;
839
173k
                    case cmd_opv_set_tile_color:
840
173k
                        set_colors = state.tile_colors;
841
173k
                        if_debug0m('L', mem, "\n");
842
173k
                        continue;
843
4.80M
                    case cmd_opv_set_misc:
844
4.80M
                        {
845
4.80M
                            uint cb = *cbp++;
846
847
4.80M
                            switch (cb >> 6) {
848
582k
                                case cmd_set_misc_lop >> 6:
849
582k
                                    cmd_getw(state.lop, cbp);
850
582k
                                    state.lop = (state.lop << 6) + (cb & 0x3f);
851
582k
                                    if_debug1m('L', mem, " lop=0x%x\n", state.lop);
852
582k
                                    if (state.lop_enabled)
853
427k
                                        gs_gstate.log_op = state.lop;
854
582k
                                    break;
855
262k
                                case cmd_set_misc_data_x >> 6:
856
262k
                                    if (cb & 0x20)
857
262k
                                        cmd_getw(data_x, cbp);
858
262k
                                    else
859
262k
                                        data_x = 0;
860
262k
                                    data_x = (data_x << 5) + (cb & 0x1f);
861
262k
                                    if_debug1m('L', mem, " data_x=%d\n", data_x);
862
262k
                                    break;
863
3.95M
                                case cmd_set_misc_map >> 6:
864
3.95M
                                    cbuf.ptr = cbp;
865
3.95M
                                    code = read_set_misc_map(cb, &cbuf, &gs_gstate, mem);
866
3.95M
                                    if (code < 0)
867
0
                                        goto out;
868
3.95M
                                    cbp = cbuf.ptr;
869
3.95M
                                    break;
870
0
                                case cmd_set_misc_halftone >> 6: {
871
0
                                    uint num_comp;
872
#ifdef DEBUG
873
                                    halftone_type = cb & 0x3f;
874
#endif
875
0
                                    cmd_getw(num_comp, cbp);
876
#ifdef DEBUG
877
                                    if_debug2m('L', mem, " halftone type=%d num_comp=%u\n",
878
                                               halftone_type, num_comp);
879
#endif
880
0
                                    code = cmd_resize_halftone(
881
0
                                                        &gs_gstate.dev_ht[HT_OBJTYPE_DEFAULT],
882
0
                                                        num_comp, mem);
883
0
                                    if (code < 0)
884
0
                                        goto out;
885
0
                                    break;
886
0
                                }
887
0
                                default:
888
0
                                    goto bad_op;
889
4.80M
                            }
890
4.80M
                        }
891
4.80M
                        continue;
892
4.80M
                    case cmd_opv_enable_lop:
893
155k
                        state.lop_enabled = true;
894
155k
                        gs_gstate.log_op = state.lop;
895
155k
                        if_debug0m('L', mem, "\n");
896
155k
                        continue;
897
76.5k
                    case cmd_opv_disable_lop:
898
76.5k
                        state.lop_enabled = false;
899
76.5k
                        gs_gstate.log_op = lop_default;
900
76.5k
                        if_debug0m('L', mem, "\n");
901
76.5k
                        continue;
902
1.94M
                    case cmd_opv_end_page:
903
1.94M
                        if_debug0m('L', mem, "\n");
904
                        /*
905
                         * Do end-of-page cleanup, then reinitialize if
906
                         * there are more pages to come.
907
                         */
908
1.94M
                        goto out;
909
0
                    case cmd_opv_delta_color0:
910
0
                        pcolor = &set_colors[0];
911
0
                        goto delta2_c;
912
14.4M
                    case cmd_opv_delta_color1:
913
14.4M
                        pcolor = &set_colors[1];
914
14.4M
                      delta2_c:set_colors = state.colors;
915
                        /* See comments for cmd_put_color() in gxclutil.c. */
916
14.4M
                        {
917
14.4M
                            gx_color_index delta = 0;
918
14.4M
                            uint data;
919
920
14.4M
                            dev_depth = (tdev->color_info.depth <= 8*sizeof(gx_color_index) ?
921
14.4M
                                         tdev->color_info.depth : 8*sizeof(gx_color_index));
922
14.4M
                            dev_depth_bytes = (dev_depth + 7) >> 3;
923
14.4M
                            switch (dev_depth_bytes) {
924
                                /* For cases with an even number of bytes */
925
0
                                case 8:
926
0
                                    data = *cbp++;
927
0
                                    delta = (((gx_color_index)
928
0
                                        ((data & 0xf0) << 4) + (data & 0x0f)) << 24) << 24;
929
                                    /* fall through */
930
0
                                case 6:
931
0
                                    data = *cbp++;
932
0
                                    delta |= (((gx_color_index)
933
0
                                        ((data & 0xf0) << 4) + (data & 0x0f)) << 16) << 16;
934
                                    /* fall through */
935
8.08M
                                case 4:
936
8.08M
                                    data = *cbp++;
937
8.08M
                                    delta |= ((gx_color_index)
938
8.08M
                                        ((data & 0xf0) << 4) + (data & 0x0f)) << 16;
939
                                    /* fall through */
940
8.08M
                                case 2:
941
8.08M
                                    data = *cbp++;
942
8.08M
                                    delta |= ((gx_color_index)
943
8.08M
                                        ((data & 0xf0) << 4) + (data & 0x0f));
944
8.08M
                                    break;
945
                                /* For cases with an odd number of bytes */
946
0
                                case 7:
947
0
                                    data = *cbp++;
948
0
                                    delta = ((gx_color_index)
949
0
                                        ((data & 0xf0) << 4) + (data & 0x0f)) << 16;
950
                                    /* fall through */
951
0
                                case 5:
952
0
                                    data = *cbp++;
953
0
                                    delta |= ((gx_color_index)
954
0
                                        ((data & 0xf0) << 4) + (data & 0x0f));
955
                                    /* fall through */
956
6.39M
                                case 3:
957
6.39M
                                    data = *cbp++;
958
6.39M
                                    odd_delta_shift = (dev_depth_bytes - 3) * 8;
959
6.39M
                                    delta |= ((gx_color_index)
960
6.39M
                                        ((data & 0xe0) << 3) + (data & 0x1f)) << odd_delta_shift;
961
6.39M
                                    data = *cbp++;
962
6.39M
                                    delta |= ((gx_color_index) ((data & 0xf8) << 2) + (data & 0x07))
963
6.39M
                                                        << (odd_delta_shift + 11);
964
14.4M
                            }
965
14.4M
                            *pcolor += delta - cmd_delta_offsets[dev_depth_bytes];
966
14.4M
                        }
967
14.4M
                        if (sizeof(*pcolor) <= sizeof(ulong))
968
14.4M
                            if_debug1m('L', mem, " 0x%lx\n", (ulong)*pcolor);
969
0
                        else
970
14.4M
                            if_debug2m('L', mem, " 0x%8lx%08lx\n",
971
14.4M
                                       (ulong)(*pcolor >> 8*(sizeof(*pcolor) - sizeof(ulong))), (ulong)*pcolor);
972
14.4M
                        continue;
973
0
                    case cmd_opv_set_copy_color:
974
0
                        state.color_is_alpha = 0;
975
0
                        if_debug0m('L', mem, "\n");
976
0
                        continue;
977
0
                    case cmd_opv_set_copy_alpha:
978
0
                        state.color_is_alpha = 1;
979
0
                        if_debug0m('L', mem, "\n");
980
0
                        continue;
981
0
                    default:
982
0
                        goto bad_op;
983
35.4M
                }
984
                /*NOTREACHED */
985
95.0k
            case cmd_op_set_color0 >> 4:
986
95.0k
                pcolor = &set_colors[0];
987
95.0k
                goto set_color;
988
9.78M
            case cmd_op_set_color1 >> 4:
989
9.78M
                pcolor = &set_colors[1];
990
9.88M
              set_color:set_colors = state.colors;
991
                /*
992
                 * We have a special case for gx_no_color_index. If the low
993
                 * order 4 bits are "cmd_no_color_index" then we really
994
                 * have a value of gx_no_color_index.  Otherwise the these
995
                 * bits indicate the number of low order zero bytes in the
996
                 * value.  See comments for cmd_put_color() in gxclutil.c.
997
                 */
998
9.88M
                num_zero_bytes = op & 0x0f;
999
1000
9.88M
                if (num_zero_bytes == cmd_no_color_index)
1001
17
                    *pcolor = gx_no_color_index;
1002
9.88M
                else {
1003
9.88M
                    gx_color_index color = 0;
1004
1005
9.88M
                    dev_depth = (tdev->color_info.depth < 8*sizeof(gx_color_index) ?
1006
9.88M
                                 tdev->color_info.depth : 8*sizeof(gx_color_index));
1007
9.88M
                    dev_depth_bytes = (dev_depth + 7) >> 3;
1008
9.88M
                    switch (dev_depth_bytes - num_zero_bytes) {
1009
0
                        case 8:
1010
0
                            color = (gx_color_index) * cbp++;
1011
0
                        case 7:
1012
0
                            color = (color << 8) | (gx_color_index) * cbp++;
1013
0
                        case 6:
1014
0
                            color = (color << 8) | (gx_color_index) * cbp++;
1015
0
                        case 5:
1016
0
                            color = (color << 8) | (gx_color_index) * cbp++;
1017
728k
                        case 4:
1018
728k
                            color = (color << 8) | (gx_color_index) * cbp++;
1019
2.26M
                        case 3:
1020
2.26M
                            color = (color << 8) | (gx_color_index) * cbp++;
1021
2.76M
                        case 2:
1022
2.76M
                            color = (color << 8) | (gx_color_index) * cbp++;
1023
9.27M
                        case 1:
1024
9.27M
                            color = (color << 8) | (gx_color_index) * cbp++;
1025
9.88M
                        default:
1026
9.88M
                            break;
1027
9.88M
                    }
1028
9.88M
                    color <<= num_zero_bytes * 8;
1029
9.88M
                    *pcolor = color;
1030
9.88M
                }
1031
9.88M
                if (sizeof(*pcolor) <= sizeof(ulong))
1032
9.88M
                    if_debug1m('L', mem, " 0x%lx\n", (ulong)*pcolor);
1033
0
                else
1034
9.88M
                    if_debug2m('L', mem, " 0x%8lx%08lx\n",
1035
9.88M
                               (ulong)(*pcolor >> 8*(sizeof(*pcolor) - sizeof(ulong))), (ulong)*pcolor);
1036
9.88M
                continue;
1037
3.62M
            case cmd_op_fill_rect >> 4:
1038
3.72M
            case cmd_op_tile_rect >> 4:
1039
3.72M
                cbp = cmd_read_rect(op, &state.rect, cbp);
1040
3.72M
                break;
1041
3.85M
            case cmd_op_fill_rect_short >> 4:
1042
4.67M
            case cmd_op_tile_rect_short >> 4:
1043
4.67M
                state.rect.x += *cbp + cmd_min_short;
1044
4.67M
                state.rect.width += cbp[1] + cmd_min_short;
1045
4.67M
                if (op & 0xf) {
1046
2.86M
                    state.rect.height += (op & 0xf) + cmd_min_dxy_tiny;
1047
2.86M
                    cbp += 2;
1048
2.86M
                } else {
1049
1.81M
                    state.rect.y += cbp[2] + cmd_min_short;
1050
1.81M
                    state.rect.height += cbp[3] + cmd_min_short;
1051
1.81M
                    cbp += 4;
1052
1.81M
                }
1053
4.67M
                break;
1054
30.5M
            case cmd_op_fill_rect_tiny >> 4:
1055
31.5M
            case cmd_op_tile_rect_tiny >> 4:
1056
31.5M
                if (op & 8)
1057
21.6M
                    state.rect.x += state.rect.width;
1058
9.92M
                else {
1059
9.92M
                    int txy = *cbp++;
1060
1061
9.92M
                    state.rect.x += (txy >> 4) + cmd_min_dxy_tiny;
1062
9.92M
                    state.rect.y += (txy & 0xf) + cmd_min_dxy_tiny;
1063
9.92M
                }
1064
31.5M
                state.rect.width += (op & 7) + cmd_min_dw_tiny;
1065
31.5M
                break;
1066
20.8M
            case cmd_op_copy_mono_planes >> 4:
1067
20.8M
                cmd_getw(plane_height, cbp);
1068
20.8M
                if (plane_height == 0) {
1069
                    /* We are doing a copy mono */
1070
20.8M
                    depth = 1;
1071
20.8M
                } else {
1072
6.91k
                    depth = tdev->color_info.depth;
1073
6.91k
                }
1074
20.8M
                if_debug1m('L', mem, " plane_height=0x%x", plane_height);
1075
20.8M
                goto copy;
1076
2.55M
            case cmd_op_copy_color_alpha >> 4:
1077
2.55M
                if (state.color_is_alpha) {
1078
0
                    if (!(op & 8))
1079
0
                        depth = *cbp++;
1080
0
                } else
1081
2.55M
                    depth = tdev->color_info.depth;
1082
2.55M
                plane_height = 0;
1083
23.4M
              copy:cmd_getw(state.rect.x, cbp);
1084
23.4M
                cmd_getw(state.rect.y, cbp);
1085
23.4M
                if (op & cmd_copy_use_tile) {   /* Use the current "tile". */
1086
#ifdef DEBUG
1087
                    if (state_slot->index != state.tile_index) {
1088
                        mlprintf2(mem, "state_slot->index = %d, state.tile_index = %d!\n",
1089
                                  state_slot->index,
1090
                                  state.tile_index);
1091
                        code = gs_note_error(gs_error_ioerror);
1092
                        goto out;
1093
                    }
1094
#endif
1095
20.3M
                    depth = state_slot->head.depth;
1096
20.3M
                    state.rect.width = state_slot->width;
1097
20.3M
                    state.rect.height = state_slot->height;
1098
20.3M
                    if (state.rect.y + state.rect.height > cdev->height)
1099
25.9k
                        state.rect.height = cdev->height - state.rect.y; /* clamp as writer did */
1100
20.3M
                    raster = state_slot->raster;
1101
20.3M
                    source = (byte *) (state_slot + 1);
1102
20.3M
                } else {        /* Read width, height, bits. */
1103
                    /* depth was set already. */
1104
3.07M
                    uint width_bits, width_bytes;
1105
3.07M
                    uint bytes;
1106
3.07M
                    uchar planes = 1;
1107
3.07M
                    uint plane_depth = depth;
1108
3.07M
                    uint pln;
1109
3.07M
                    byte compression = op & 3;
1110
3.07M
                    uint out_bytes;
1111
1112
3.07M
                    cmd_getw(state.rect.width, cbp);
1113
3.07M
                    cmd_getw(state.rect.height, cbp);
1114
3.07M
                    if (plane_height != 0) {
1115
6.91k
                        planes = tdev->color_info.num_components;
1116
6.91k
                        plane_depth /= planes;
1117
6.91k
                    }
1118
3.07M
                    width_bits = state.rect.width * plane_depth;
1119
3.07M
                    bytes = clist_bitmap_bytes(width_bits,
1120
3.07M
                                               state.rect.height,
1121
3.07M
                                               op & 3, &width_bytes,
1122
3.07M
                                               (uint *)&raster);
1123
3.07M
                    if (planes > 1) {
1124
6.91k
                        out_bytes = raster * state.rect.height;
1125
6.91k
                        plane_height = state.rect.height;
1126
3.06M
                    } else {
1127
3.06M
                        out_bytes = bytes;
1128
3.06M
                    }
1129
                    /* copy_mono and copy_color/alpha */
1130
                    /* ensure that the bits will fit in a single buffer, */
1131
                    /* even after decompression if compressed. */
1132
#ifdef DEBUG
1133
                    if (planes * out_bytes > data_bits_size) {
1134
                        mlprintf6(mem, "bitmap size exceeds buffer!  width=%d raster=%d height=%d\n    file pos %"PRId64" buf pos %d/%d\n",
1135
                                  state.rect.width, raster,
1136
                                  state.rect.height,
1137
                                  stell(s), (int)(cbp - cbuf.data),
1138
                                  (int)(cbuf.end - cbuf.data));
1139
                        code = gs_note_error(gs_error_ioerror);
1140
                        goto out;
1141
                    }
1142
#endif
1143
6.16M
                    for (pln = 0; pln < planes; pln++) {
1144
3.09M
                        byte *plane_bits = data_bits + pln * plane_height * raster;
1145
1146
                        /* Fill the cbuf if needed to get the data for the plane */
1147
3.09M
                        if (cbp + out_bytes >= cbuf.warn_limit) {
1148
42.7k
                            code = top_up_cbuf(&cbuf, &cbp);
1149
42.7k
                            if (code < 0)
1150
0
                                goto top_up_failed;
1151
42.7k
                        }
1152
3.09M
                        if (pln)
1153
20.7k
                            compression = *cbp++;
1154
1155
3.09M
                        if (compression == cmd_compress_const) {
1156
0
                            cbp = cmd_read_data(&cbuf, plane_bits, 1, cbp);
1157
0
                            if (width_bytes > 0 && state.rect.height > 0)
1158
0
                                memset(plane_bits+1, *plane_bits, width_bytes * state.rect.height - 1);
1159
0
                            if (pln == 0)
1160
0
                                source = data_bits;
1161
1162
3.09M
                        } else if (compression) {       /* Decompress the image data. */
1163
696
                            stream_cursor_read r;
1164
696
                            stream_cursor_write w;
1165
1166
                            /* We don't know the data length a priori, */
1167
                            /* so to be conservative, we read */
1168
                            /* the uncompressed size. */
1169
696
                            uint cleft = cbuf.end - cbp;
1170
1171
696
                            if (cleft < bytes  && !cbuf.end_status) {
1172
0
                                uint nread = cbuf_size - cleft;
1173
1174
0
                                advance_buffer(&cbuf, cbp);
1175
0
                                cbuf.end_status = sgets(s, cbuf.data + cleft, nread, &nread);
1176
0
                                set_cb_end(&cbuf, cbuf.data + cleft + nread);
1177
0
                                cbp = cbuf.data;
1178
0
                            }
1179
696
                            r.ptr = cbp - 1;
1180
696
                            r.limit = cbuf.end - 1;
1181
696
                            w.ptr = plane_bits - 1;
1182
696
                            w.limit = w.ptr + data_bits_size;
1183
696
                            switch (compression) {
1184
0
                                case cmd_compress_rle:
1185
0
                                    {
1186
0
                                        stream_RLD_state sstate;
1187
1188
0
                                        clist_rld_init(&sstate);
1189
                                        /* The process procedure can't fail. */
1190
0
                                        (*s_RLD_template.process)
1191
0
                                            ((stream_state *)&sstate, &r, &w, true);
1192
0
                                    }
1193
0
                                    break;
1194
696
                                case cmd_compress_cfe:
1195
696
                                    {
1196
696
                                        stream_CFD_state sstate;
1197
1198
696
                                        clist_cfd_init(&sstate,
1199
696
                                        width_bytes << 3 /*state.rect.width */ ,
1200
696
                                                       state.rect.height, mem);
1201
                                        /* The process procedure can't fail. */
1202
696
                                        (*s_CFD_template.process)
1203
696
                                            ((stream_state *)&sstate, &r, &w, true);
1204
696
                                        (*s_CFD_template.release)
1205
696
                                            ((stream_state *)&sstate);
1206
696
                                    }
1207
696
                                    break;
1208
0
                                default:
1209
0
                                    goto bad_op;
1210
696
                            }
1211
696
                            cbp = r.ptr + 1;
1212
696
                            if (pln == 0)
1213
696
                                source = data_bits;
1214
3.09M
                        } else if ((state.rect.height > 1 && width_bytes != raster) ||
1215
2.99M
                                   (plane_height != 0)) {
1216
123k
                            cbp = cmd_read_short_bits(&cbuf, plane_bits, bytes, width_bytes,
1217
123k
                                                      state.rect.height, raster, cbp);
1218
123k
                            if (pln == 0)
1219
102k
                                source = data_bits;
1220
2.96M
                        } else {
1221
                            /* Never used for planar data */
1222
2.96M
                            cbp = cmd_read_data(&cbuf, cbuf.data, bytes, cbp);
1223
2.96M
                            source = cbuf.data;
1224
2.96M
                        }
1225
3.09M
                    }
1226
#ifdef DEBUG
1227
                    if (gs_debug_c('L')) {
1228
                        dmprintf2(mem, " depth=%d, data_x=%d\n",
1229
                                  depth, data_x);
1230
                        cmd_print_bits(mem, source, state.rect.width,
1231
                                       state.rect.height, raster);
1232
                    }
1233
#endif
1234
3.07M
                }
1235
23.4M
                break;
1236
23.4M
            case cmd_op_delta_tile_index >> 4:
1237
4.56M
                state.tile_index += (int)(op & 0xf) - 8;
1238
4.56M
                goto sti;
1239
8.28M
            case cmd_op_set_tile_index >> 4:
1240
8.28M
                state.tile_index =
1241
8.28M
                    ((op & 0xf) << 8) + *cbp++;
1242
12.8M
              sti:state_slot =
1243
12.8M
                    (tile_slot *) (cdev->cache_chunk->data +
1244
12.8M
                                 cdev->tile_table[state.tile_index].offset);
1245
12.8M
                if_debug2m('L', mem, " index=%u offset=%lu\n",
1246
12.8M
                           state.tile_index,
1247
12.8M
                           cdev->tile_table[state.tile_index].offset);
1248
12.8M
                state_tile.data = (byte *) (state_slot + 1);
1249
19.9M
              stp:state_tile.size.x = state_slot->width;
1250
19.9M
                state_tile.size.y = state_slot->height;
1251
19.9M
                state_tile.raster = state_slot->raster;
1252
19.9M
                state_tile.rep_width = state_tile.size.x /
1253
19.9M
                    state_slot->x_reps;
1254
19.9M
                state_tile.rep_height = state_tile.size.y /
1255
19.9M
                    state_slot->y_reps;
1256
19.9M
                state_tile.rep_shift = state_slot->rep_shift;
1257
19.9M
                state_tile.shift = state_slot->shift;
1258
19.9M
                state_tile.id = state_slot->id;
1259
19.9M
                state_tile.num_planes = state_slot->num_planes;
1260
19.9M
set_tile_phase:
1261
19.9M
                if (state_tile.size.x)
1262
19.9M
                    tile_phase.x =
1263
19.9M
                        (state.tile_phase.x + x0) % state_tile.size.x;
1264
                /*
1265
                 * The true tile height for shifted tiles is not
1266
                 * size.y: see gxbitmap.h for the computation.
1267
                 */
1268
19.9M
                if (state_tile.size.y) {
1269
19.9M
                    int full_height;
1270
1271
19.9M
                    if (state_tile.shift == 0)
1272
19.9M
                        full_height = state_tile.size.y;
1273
0
                    else
1274
0
                        full_height = state_tile.rep_height *
1275
0
                                    (state_tile.rep_width /
1276
0
                                     igcd(state_tile.rep_shift,
1277
0
                                          state_tile.rep_width));
1278
19.9M
                    tile_phase.y = (state.tile_phase.y + y0) % full_height;
1279
19.9M
                }
1280
19.9M
                continue;
1281
51.0M
            case cmd_op_misc2 >> 4:
1282
51.0M
                switch (op) {
1283
0
                    case cmd_opv_set_bits_planar:
1284
0
                        goto do_opv_set_bits;
1285
92.4k
                    case cmd_opv_set_fill_adjust:
1286
92.4k
                        cmd_get_value(gs_gstate.fill_adjust.x, cbp);
1287
92.4k
                        cmd_get_value(gs_gstate.fill_adjust.y, cbp);
1288
92.4k
                        if_debug2m('L', mem, " (%g,%g)\n",
1289
92.4k
                                   fixed2float(gs_gstate.fill_adjust.x),
1290
92.4k
                                   fixed2float(gs_gstate.fill_adjust.y));
1291
92.4k
                        continue;
1292
4.10M
                    case cmd_opv_set_ctm:
1293
4.10M
                        {
1294
4.10M
                            gs_matrix mat;
1295
1296
4.10M
                            cbp = cmd_read_matrix(&mat, cbp);
1297
4.10M
                            if_debug6m('L', mem, " [%g %g %g %g %g %g]\n",
1298
4.10M
                                       mat.xx, mat.xy, mat.yx, mat.yy,
1299
4.10M
                                       mat.tx, mat.ty);
1300
4.10M
                            mat.tx -= x0;
1301
4.10M
                            mat.ty -= y0;
1302
4.10M
                            gs_gstate_setmatrix(&gs_gstate, &mat);
1303
4.10M
                        }
1304
4.10M
                        continue;
1305
1.32M
                    case cmd_opv_set_misc2:
1306
1.32M
                        cbuf.ptr = cbp;
1307
1.32M
                        code = read_set_misc2(&cbuf, &gs_gstate, &notes);
1308
1.32M
                        cbp = cbuf.ptr;
1309
1.32M
                        if (code < 0)
1310
0
                            goto out;
1311
1.32M
                        continue;
1312
1.32M
                    case cmd_opv_set_dash:
1313
183k
                        {
1314
183k
                            int nb = *cbp++;
1315
183k
                            int n = nb & 0x3f;
1316
183k
                            float dot_length, offset;
1317
1318
183k
                            cmd_get_value(dot_length, cbp);
1319
183k
                            cmd_get_value(offset, cbp);
1320
183k
                            memcpy(dash_pattern, cbp, n * sizeof(float));
1321
1322
183k
                            gx_set_dash(&gs_gstate.line_params.dash,
1323
183k
                                        dash_pattern, n, offset,
1324
183k
                                        NULL);
1325
183k
                            gx_set_dash_adapt(&gs_gstate.line_params.dash,
1326
183k
                                              (nb & 0x80) != 0);
1327
183k
                            gx_set_dot_length(&gs_gstate.line_params,
1328
183k
                                              dot_length,
1329
183k
                                              (nb & 0x40) != 0);
1330
#ifdef DEBUG
1331
                            if (gs_debug_c('L')) {
1332
                                int i;
1333
1334
                                dmprintf4(mem, " dot=%g(mode %d) adapt=%d offset=%g [",
1335
                                         dot_length,
1336
                                         (nb & 0x40) != 0,
1337
                                         (nb & 0x80) != 0, offset);
1338
                                for (i = 0; i < n; ++i)
1339
                                    dmprintf1(mem, "%g ", dash_pattern[i]);
1340
                                dmputs(mem, "]\n");
1341
                            }
1342
#endif
1343
183k
                            cbp += n * sizeof(float);
1344
183k
                        }
1345
183k
                        break;
1346
6.77k
                    case cmd_opv_enable_clip:
1347
6.77k
                        pcpath = (use_clip ? &clip_path : NULL);
1348
6.77k
                        if (pcpath) {
1349
325
                            code = gx_cpath_ensure_path_list(pcpath);
1350
325
                            if (code < 0)
1351
0
                                goto out;
1352
325
                        }
1353
6.77k
                        if (clipper_dev_open)
1354
0
                            gx_destroy_clip_device_on_stack(&clipper_dev);
1355
6.77k
                        clipper_dev_open = false;
1356
6.77k
                        if_debug0m('L', mem, "\n");
1357
6.77k
                        break;
1358
9.89k
                    case cmd_opv_disable_clip:
1359
9.89k
                        pcpath = NULL;
1360
9.89k
                        if (clipper_dev_open)
1361
12
                            gx_destroy_clip_device_on_stack(&clipper_dev);
1362
9.89k
                        clipper_dev_open = false;
1363
9.89k
                        if_debug0m('L', mem, "\n");
1364
9.89k
                        break;
1365
2.81M
                    case cmd_opv_begin_clip:
1366
2.81M
                        pcpath = NULL;
1367
2.81M
                        if (clipper_dev_open)
1368
852
                            gx_destroy_clip_device_on_stack(&clipper_dev);
1369
2.81M
                        clipper_dev_open = false;
1370
2.81M
                        in_clip = true;
1371
2.81M
                        if_debug0m('L', mem, "\n");
1372
2.81M
                        code = gx_cpath_reset(&clip_path);
1373
2.81M
                        if (code < 0)
1374
0
                            goto out;
1375
2.81M
                        gx_cpath_accum_begin(&clip_accum, mem, false);
1376
2.81M
                        gx_cpath_accum_set_cbox(&clip_accum,
1377
2.81M
                                                &target_box);
1378
2.81M
                        tdev = (gx_device *)&clip_accum;
1379
2.81M
                        clip_save.lop_enabled = state.lop_enabled;
1380
2.81M
                        clip_save.dcolor = fill_color;
1381
2.81M
                        clip_save.fa_save.x = gs_gstate.fill_adjust.x;
1382
2.81M
                        clip_save.fa_save.y = gs_gstate.fill_adjust.y;
1383
2.81M
                        cmd_getw(gs_gstate.fill_adjust.x, cbp);
1384
2.81M
                        cmd_getw(gs_gstate.fill_adjust.y, cbp);
1385
                        /* temporarily set a solid color */
1386
2.81M
                        color_set_pure(&fill_color, (gx_color_index)1);
1387
2.81M
                        state.lop_enabled = false;
1388
2.81M
                        gs_gstate.log_op = lop_default;
1389
2.81M
                        break;
1390
2.81M
                    case cmd_opv_end_clip:
1391
2.81M
                        if_debug0m('L', mem, "\n");
1392
2.81M
                        gx_cpath_accum_end(&clip_accum, &clip_path);
1393
2.81M
                        tdev = target;
1394
                        /*
1395
                         * If the entire band falls within the clip
1396
                         * path, no clipping is needed.
1397
                         */
1398
2.81M
                        {
1399
2.81M
                            gs_fixed_rect cbox;
1400
1401
2.81M
                            gx_cpath_inner_box(&clip_path, &cbox);
1402
2.81M
                            use_clip =
1403
2.81M
                                !(cbox.p.x <= target_box.p.x &&
1404
2.02M
                                  cbox.q.x >= target_box.q.x &&
1405
1.00M
                                  cbox.p.y <= target_box.p.y &&
1406
1.00M
                                  cbox.q.y >= target_box.q.y);
1407
2.81M
                        }
1408
2.81M
                        pcpath = (use_clip ? &clip_path : NULL);
1409
2.81M
                        if (pcpath) {
1410
1.81M
                            code = gx_cpath_ensure_path_list(pcpath);
1411
1.81M
                            if (code < 0)
1412
0
                                goto out;
1413
1.81M
                        }
1414
2.81M
                        if (clipper_dev_open)
1415
0
                            gx_destroy_clip_device_on_stack(&clipper_dev);
1416
2.81M
                        clipper_dev_open = false;
1417
2.81M
                        state.lop_enabled = clip_save.lop_enabled;
1418
2.81M
                        gs_gstate.log_op =
1419
2.81M
                            (state.lop_enabled ? state.lop :
1420
2.81M
                             lop_default);
1421
2.81M
                        fill_color = clip_save.dcolor;
1422
                        /* restore the fill_adjust if it was changed by begin_clip */
1423
2.81M
                        gs_gstate.fill_adjust.x = clip_save.fa_save.x;
1424
2.81M
                        gs_gstate.fill_adjust.y = clip_save.fa_save.y;
1425
2.81M
                        in_clip = false;
1426
2.81M
                        break;
1427
295k
                    case cmd_opv_set_color_space:
1428
295k
                        cbuf.ptr = cbp;
1429
295k
                        code = read_set_color_space(&cbuf, &gs_gstate, cdev, mem);
1430
295k
                        pcs = gs_gstate.color[0].color_space;
1431
295k
                        cbp = cbuf.ptr;
1432
295k
                        if (code < 0) {
1433
0
                            if (code == gs_error_rangecheck)
1434
0
                                goto bad_op;
1435
0
                            goto out;
1436
0
                        }
1437
295k
                        break;
1438
9.82M
                    case cmd_op_fill_rect_hl:
1439
9.82M
                        {
1440
9.82M
                            gs_fixed_rect rect_hl;
1441
1442
9.82M
                            cbp = cmd_read_rect(op & 0xf0, &state.rect, cbp);
1443
9.82M
                            if (fill_color.type != gx_dc_type_devn) {
1444
0
                                if_debug0m('L', mem, "hl rect fill without devn color\n");
1445
0
                                code = gs_note_error(gs_error_typecheck);
1446
0
                                goto out;
1447
0
                            }
1448
9.82M
                            if_debug4m('L', mem, " x=%d y=%d w=%d h=%d\n",
1449
9.82M
                                       state.rect.x, state.rect.y,
1450
9.82M
                                       state.rect.width,state.rect.height);
1451
9.82M
                            rect_hl.p.x = int2fixed(state.rect.x - x0);
1452
9.82M
                            rect_hl.p.y = int2fixed(state.rect.y - y0);
1453
9.82M
                            rect_hl.q.x = int2fixed(state.rect.width) + rect_hl.p.x;
1454
9.82M
                            rect_hl.q.y = int2fixed(state.rect.height) + rect_hl.p.y;
1455
9.82M
                            code = dev_proc(tdev, fill_rectangle_hl_color) (tdev,
1456
9.82M
                                                        &rect_hl, NULL,
1457
9.82M
                                                        &fill_color, NULL);
1458
9.82M
                        }
1459
0
                        continue;
1460
304k
                    case cmd_opv_begin_image_rect:
1461
304k
                        cbuf.ptr = cbp;
1462
304k
                        code = read_begin_image(&cbuf, &image.c, pcs);
1463
304k
                        cbp = cbuf.ptr;
1464
304k
                        if (code < 0)
1465
0
                            goto out;
1466
304k
                        {
1467
304k
                            uint diff;
1468
1469
304k
                            cmd_getw(image_rect.p.x, cbp);
1470
304k
                            cmd_getw(image_rect.p.y, cbp);
1471
304k
                            cmd_getw(diff, cbp);
1472
304k
                            image_rect.q.x = image.d.Width - diff;
1473
304k
                            cmd_getw(diff, cbp);
1474
304k
                            image_rect.q.y = image.d.Height - diff;
1475
304k
                            if_debug4m('L', mem, " rect=(%d,%d),(%d,%d)",
1476
304k
                                       image_rect.p.x, image_rect.p.y,
1477
304k
                                       image_rect.q.x, image_rect.q.y);
1478
304k
                        }
1479
304k
                        goto ibegin;
1480
92.9k
                    case cmd_opv_begin_image:
1481
92.9k
                        cbuf.ptr = cbp;
1482
92.9k
                        code = read_begin_image(&cbuf, &image.c, pcs);
1483
92.9k
                        cbp = cbuf.ptr;
1484
92.9k
                        if (code < 0)
1485
0
                            goto out;
1486
92.9k
                        image_rect.p.x = 0;
1487
92.9k
                        image_rect.p.y = 0;
1488
92.9k
                        image_rect.q.x = image.d.Width;
1489
92.9k
                        image_rect.q.y = image.d.Height;
1490
92.9k
                        if_debug2m('L', mem, " size=(%d,%d)",
1491
92.9k
                                  image.d.Width, image.d.Height);
1492
397k
ibegin:                 if_debug0m('L', mem, "\n");
1493
397k
                        {
1494
                            /* Processing an image operation */
1495
397k
                            dev_proc(tdev, set_graphics_type_tag)(tdev, GS_IMAGE_TAG);/* FIXME: what about text bitmaps? */
1496
397k
                            image.i4.override_in_smask = 0;
1497
397k
                            code = (*dev_proc(tdev, begin_typed_image))
1498
397k
                                (tdev, &gs_gstate, NULL,
1499
397k
                                 (const gs_image_common_t *)&image,
1500
397k
                                 &image_rect, &fill_color, pcpath, mem,
1501
397k
                                 &image_info);
1502
397k
                        }
1503
397k
                        if (code < 0)
1504
11
                            goto out;
1505
397k
                        break;
1506
397k
                    case cmd_opv_image_plane_data:
1507
0
                        cmd_getw(data_height, cbp);
1508
0
                        if (data_height == 0) {
1509
0
                            if_debug0m('L', mem, " done image\n");
1510
0
                            code = gx_image_end(image_info, true);
1511
0
                            if (code < 0)
1512
0
                                goto out;
1513
0
                            continue;
1514
0
                        }
1515
0
                        {
1516
0
                            uint flags;
1517
0
                            int plane;
1518
0
                            uint raster1 = 0xbaadf00d; /* Initialize against indeterminizm. */
1519
1520
0
                            cmd_getw(flags, cbp);
1521
0
                            for (plane = 0;
1522
0
                                 plane < image_info->num_planes;
1523
0
                                 ++plane, flags >>= 1) {
1524
0
                                if (flags & 1) {
1525
0
                                    if (cbuf.end - cbp <
1526
0
                                        2 * cmd_max_intsize(sizeof(uint))) {
1527
0
                                        code = top_up_cbuf(&cbuf, &cbp);
1528
0
                                        if (code < 0)
1529
0
                                            goto top_up_failed;
1530
0
                                    }
1531
0
                                    cmd_getw(planes[plane].raster, cbp);
1532
0
                                    if ((raster1 = planes[plane].raster) != 0)
1533
0
                                        cmd_getw(data_x, cbp);
1534
0
                                } else {
1535
0
                                    planes[plane].raster = raster1;
1536
0
                                }
1537
0
                                planes[plane].data_x = data_x;
1538
0
                            }
1539
0
                        }
1540
0
                        goto idata;
1541
2.06M
                    case cmd_opv_image_data:
1542
2.06M
                        cmd_getw(data_height, cbp);
1543
2.06M
                        if (data_height == 0) {
1544
397k
                            if_debug0m('L', mem, " done image\n");
1545
397k
                            code = gx_image_end(image_info, true);
1546
397k
                            if (code < 0)
1547
0
                                goto out;
1548
397k
                            continue;
1549
397k
                        }
1550
1.66M
                        {
1551
1.66M
                            uint bytes_per_plane;
1552
1.66M
                            int plane;
1553
1554
1.66M
                            cmd_getw(bytes_per_plane, cbp);
1555
1.66M
                            if_debug2m('L', mem, " height=%u raster=%u\n",
1556
1.66M
                                       data_height, bytes_per_plane);
1557
1.66M
                            for (plane = 0;
1558
3.32M
                                 plane < image_info->num_planes;
1559
1.66M
                                 ++plane
1560
1.66M
                                 ) {
1561
1.66M
                                planes[plane].data_x = data_x;
1562
1.66M
                                planes[plane].raster = bytes_per_plane;
1563
1.66M
                            }
1564
1.66M
                        }
1565
1.66M
idata:                  data_size = 0;
1566
1.66M
                        {
1567
1.66M
                            int plane;
1568
1569
3.32M
                            for (plane = 0; plane < image_info->num_planes;
1570
1.66M
                                 ++plane)
1571
1.66M
                                data_size += planes[plane].raster;
1572
1.66M
                        }
1573
1.66M
                        data_size *= data_height;
1574
1.66M
                        data_on_heap = 0;
1575
1.66M
                        if (cbuf.end - cbp < data_size) {
1576
362k
                            code = top_up_cbuf(&cbuf, &cbp);
1577
362k
                            if (code < 0)
1578
0
                                goto top_up_failed;
1579
362k
                        }
1580
1.66M
                        if (cbuf.end - cbp >= data_size) {
1581
1.65M
                            planes[0].data = cbp;
1582
1.65M
                            cbp += data_size;
1583
1.65M
                        } else {
1584
9.49k
                            uint cleft = cbuf.end - cbp;
1585
9.49k
                            uint rleft = data_size - cleft;
1586
9.49k
                            byte *rdata;
1587
1588
9.49k
                            if (data_size > cbuf.end - cbuf.data) {
1589
                                /* Allocate a separate buffer. */
1590
9.49k
                                rdata = data_on_heap =
1591
9.49k
                                    gs_alloc_bytes(mem, data_size,
1592
9.49k
                                                   "clist image_data");
1593
9.49k
                                if (rdata == 0) {
1594
0
                                    code = gs_note_error(gs_error_VMerror);
1595
0
                                    goto out;
1596
0
                                }
1597
9.49k
                            } else
1598
0
                                rdata = cbuf.data;
1599
9.49k
                            memmove(rdata, cbp, cleft);
1600
9.49k
                            if (data_on_heap)
1601
9.49k
                                next_is_skip(&cbuf);
1602
9.49k
                            if (sgets(s, rdata + cleft, rleft, &rleft) < 0) {
1603
0
                                code = gs_note_error(gs_error_unregistered); /* Must not happen. */
1604
0
                                goto out;
1605
0
                            }
1606
9.49k
                            planes[0].data = rdata;
1607
9.49k
                            cbp = cbuf.end;     /* force refill */
1608
9.49k
                        }
1609
1.66M
                        {
1610
1.66M
                            int plane;
1611
1.66M
                            const byte *data = planes[0].data;
1612
1613
1.66M
                            for (plane = 0;
1614
3.32M
                                 plane < image_info->num_planes;
1615
1.66M
                                 ++plane
1616
1.66M
                                 ) {
1617
1.66M
                                if (planes[plane].raster == 0)
1618
0
                                    planes[plane].data = 0;
1619
1.66M
                                else {
1620
1.66M
                                    planes[plane].data = data;
1621
1.66M
                                    data += planes[plane].raster *
1622
1.66M
                                        data_height;
1623
1.66M
                                }
1624
1.66M
                            }
1625
1.66M
                        }
1626
#ifdef DEBUG
1627
                        if (gs_debug_c('L')) {
1628
                            int plane;
1629
1630
                            for (plane = 0; plane < image_info->num_planes;
1631
                                 ++plane)
1632
                                if (planes[plane].data != 0)
1633
                                    cmd_print_bits(mem,
1634
                                                   planes[plane].data,
1635
                                                   image_rect.q.x -
1636
                                                   image_rect.p.x,
1637
                                                   data_height,
1638
                                                   planes[plane].raster);
1639
                        }
1640
#endif
1641
1.66M
                        code = gx_image_plane_data(image_info, planes,
1642
1.66M
                                                   data_height);
1643
1.66M
                        if (code < 0)
1644
0
                            gx_image_end(image_info, false);
1645
1.66M
                        if (data_on_heap)
1646
9.49k
                            gs_free_object(mem, data_on_heap,
1647
1.66M
                                           "clist image_data");
1648
1.66M
                        data_x = 0;
1649
1.66M
                        if (code < 0)
1650
0
                            goto out;
1651
1.66M
                        continue;
1652
27.1M
                    case cmd_opv_extend:
1653
27.1M
                        switch (*cbp++) {
1654
0
                            case cmd_opv_ext_put_params:
1655
0
                                if_debug0m('L', mem, "put_params\n");
1656
0
                                cbuf.ptr = cbp;
1657
0
                                code = read_put_params(&cbuf, &gs_gstate,
1658
0
                                                        cdev, mem);
1659
0
                                cbp = cbuf.ptr;
1660
0
                                if (code > 0)
1661
0
                                    break; /* empty list */
1662
0
                                if (code < 0)
1663
0
                                    goto out;
1664
0
                                if (playback_action == playback_action_setup)
1665
0
                                    goto out;
1666
0
                                break;
1667
5.56M
                            case cmd_opv_ext_composite:
1668
5.56M
                                if_debug0m('L', mem, " ext_composite\n");
1669
5.56M
                                cbuf.ptr = cbp;
1670
                                /*
1671
                                 * The screen phase may have been changed during
1672
                                 * the processing of masked images.
1673
                                 */
1674
5.56M
                                gx_gstate_setscreenphase(&gs_gstate,
1675
5.56M
                                            -x0, -y0, gs_color_select_all);
1676
5.56M
                                cbp -= 2; /* Step back to simplify the cycle invariant below. */
1677
196M
                                for (;;) {
1678
                                    /* This internal loop looks ahead for compositor commands and
1679
                                       copies them into a temporary queue. Compositors, which do not paint something,
1680
                                       are marked as idle and later executed with a reduced functionality
1681
                                       for reducing time and memory expense. */
1682
196M
                                    int len;
1683
1684
196M
                                    if (cbp >= cbuf.warn_limit) {
1685
155k
                                        code = top_up_cbuf(&cbuf, &cbp);
1686
155k
                                        if (code < 0)
1687
0
                                            goto out;
1688
155k
                                    }
1689
#ifdef DEBUG
1690
                                    if (gs_debug_c('L')) {
1691
                                       long offset = (long)clist_file_offset(st, cbp - cbuf.data);
1692
1693
                                       dmlprintf1(mem, "[L]  %ld:", offset);
1694
                                       clist_debug_op(mem, cbp);
1695
                                       dmlprintf(mem, "\n");
1696
                                    }
1697
#endif
1698
196M
                                    if (cbp[0] == cmd_opv_extend && cbp[1] == cmd_opv_ext_composite) {
1699
128M
                                        gs_composite_t *pcomp, *pcomp_opening;
1700
128M
                                        gs_compositor_closing_state closing_state;
1701
1702
128M
                                        cbuf.ptr = cbp += 2;
1703
128M
                                        code = read_composite(&cbuf, mem, &pcomp);
1704
128M
                                        if (code < 0)
1705
0
                                            goto out;
1706
128M
                                        cbp = cbuf.ptr;
1707
128M
                                        if (pcomp == NULL)
1708
0
                                            continue;
1709
128M
                                        if (gs_is_pdf14trans_compositor(pcomp) &&
1710
32.8M
                                            playback_action == playback_action_render_no_pdf14) {
1711
                                            /* free the compositor object */
1712
5.06M
                                            gs_free_object(mem, pcomp, "read_composite");
1713
5.06M
                                            pcomp = NULL;
1714
5.06M
                                            continue;
1715
5.06M
                                        }
1716
123M
                                        pcomp_opening = pcomp_last;
1717
123M
                                        closing_state = pcomp->type->procs.is_closing(pcomp, &pcomp_opening, tdev);
1718
123M
                                        switch(closing_state)
1719
123M
                                        {
1720
0
                                        default:
1721
0
                                            code = (int)closing_state;
1722
0
                                            if (code >= 0)
1723
0
                                                code = gs_note_error(gs_error_unregistered); /* Must not happen. */
1724
0
                                            goto out;
1725
113M
                                        case COMP_ENQUEUE:
1726
                                            /* Enqueue. */
1727
113M
                                            enqueue_compositor(&pcomp_first, &pcomp_last, pcomp);
1728
113M
                                            break;
1729
0
                                        case COMP_EXEC_IDLE:
1730
                                            /* Execute idle. */
1731
0
                                            enqueue_compositor(&pcomp_first, &pcomp_last, pcomp);
1732
0
                                            code = execute_compositor_queue(cdev, &target, &tdev,
1733
0
                                                &gs_gstate, &pcomp_first, &pcomp_last, pcomp_opening, x0, y0, mem, true);
1734
0
                                            if (code < 0)
1735
0
                                                goto out;
1736
0
                                            break;
1737
733k
                                        case COMP_EXEC_QUEUE:
1738
                                            /* The opening command was executed. Execute the queue. */
1739
733k
                                            enqueue_compositor(&pcomp_first, &pcomp_last, pcomp);
1740
733k
                                            code = execute_compositor_queue(cdev, &target, &tdev,
1741
733k
                                                &gs_gstate, &pcomp_first, &pcomp_last, pcomp_first, x0, y0, mem, false);
1742
733k
                                            if (code < 0)
1743
2
                                                goto out;
1744
733k
                                            break;
1745
733k
                                        case COMP_REPLACE_PREV:
1746
                                            /* Replace last compositors. */
1747
0
                                            code = execute_compositor_queue(cdev, &target, &tdev,
1748
0
                                                &gs_gstate, &pcomp_first, &pcomp_last, pcomp_opening, x0, y0, mem, true);
1749
0
                                            if (code < 0)
1750
0
                                                goto out;
1751
0
                                            enqueue_compositor(&pcomp_first, &pcomp_last, pcomp);
1752
0
                                            break;
1753
7.62M
                                        case COMP_REPLACE_CURR:
1754
                                            /* Replace specific compositor. */
1755
7.62M
                                            code = dequeue_compositor(&pcomp_first, &pcomp_last, pcomp_opening);
1756
7.62M
                                            if (code < 0)
1757
0
                                                goto out;
1758
7.62M
                                            enqueue_compositor(&pcomp_first, &pcomp_last, pcomp);
1759
7.62M
                                            free_compositor(pcomp_opening, mem);
1760
7.62M
                                            break;
1761
92.0k
                                        case COMP_DROP_QUEUE:
1762
                                            /* Annihilate the last compositors. */
1763
92.0k
                                            enqueue_compositor(&pcomp_first, &pcomp_last, pcomp);
1764
92.0k
                                            code = drop_compositor_queue(&pcomp_first, &pcomp_last, pcomp_opening, mem, x0, y0, &gs_gstate);
1765
92.0k
                                            if (code < 0)
1766
0
                                                goto out;
1767
92.0k
                                            break;
1768
1.24M
                                        case COMP_MARK_IDLE:
1769
                                            /* Mark as idle. */
1770
1.24M
                                            enqueue_compositor(&pcomp_first, &pcomp_last, pcomp);
1771
1.24M
                                            mark_as_idle(pcomp_opening, pcomp);
1772
123M
                                        }
1773
123M
                                    } else if (is_null_compositor_op(cbp, &len)) {
1774
61.5M
                                        cbuf.ptr = cbp += len;
1775
61.5M
                                    } else if (cbp[0] == cmd_opv_end_page) {
1776
                                        /* End page, drop the queue. */
1777
1.48M
                                        code = execute_compositor_queue(cdev, &target, &tdev,
1778
1.48M
                                                &gs_gstate, &pcomp_first, &pcomp_last, pcomp_first, x0, y0, mem, true);
1779
1.48M
                                        if (code < 0)
1780
10
                                            goto out;
1781
1.48M
                                        break;
1782
5.26M
                                    } else if (pcomp_last != NULL &&
1783
4.67M
                                            pcomp_last->type->procs.is_friendly(pcomp_last, cbp[0], cbp[1])) {
1784
                                        /* Immediately execute friendly commands
1785
                                           inside the compositor lookahead loop.
1786
                                           Currently there are few friendly commands for the pdf14 compositor only
1787
                                           due to the logic defined in c_pdf14trans_is_friendly.
1788
                                           This code duplicates some code portions from the main loop,
1789
                                           but we have no better idea with no slowdown to the main loop.
1790
                                         */
1791
1.19M
                                        uint cb;
1792
1793
1.19M
                                        switch (*cbp++) {
1794
570k
                                            case cmd_opv_extend:
1795
570k
                                                switch (*cbp++) {
1796
221k
                                                    case cmd_opv_ext_put_halftone:
1797
221k
                                                        {
1798
221k
                                                            uint    ht_size;
1799
1800
221k
                                                            enc_u_getw(ht_size, cbp);
1801
221k
                                                            code = read_alloc_ht_buff(&ht_buff, ht_size, mem);
1802
221k
                                                            if (code < 0)
1803
0
                                                                goto out;
1804
221k
                                                        }
1805
221k
                                                        break;
1806
348k
                                                    case cmd_opv_ext_put_ht_seg:
1807
348k
                                                        cbuf.ptr = cbp;
1808
348k
                                                        code = read_ht_segment(&ht_buff, &cbuf,
1809
348k
                                                                               &gs_gstate, tdev,
1810
348k
                                                                               mem);
1811
348k
                                                        cbp = cbuf.ptr;
1812
348k
                                                        if (code < 0)
1813
0
                                                            goto out;
1814
348k
                                                        break;
1815
348k
                                                    default:
1816
0
                                                        code = gs_note_error(gs_error_unregistered); /* Must not happen. */
1817
0
                                                        goto out;
1818
570k
                                                }
1819
570k
                                                break;
1820
627k
                                            case cmd_opv_set_misc:
1821
627k
                                                cb = *cbp++;
1822
627k
                                                switch (cb >> 6) {
1823
627k
                                                    case cmd_set_misc_map >> 6:
1824
627k
                                                        cbuf.ptr = cbp;
1825
627k
                                                        code = read_set_misc_map(cb, &cbuf, &gs_gstate, mem);
1826
627k
                                                        if (code < 0)
1827
0
                                                            goto out;
1828
627k
                                                        cbp = cbuf.ptr;
1829
627k
                                                        break;
1830
0
                                                    default:
1831
0
                                                        code = gs_note_error(gs_error_unregistered); /* Must not happen. */
1832
0
                                                        goto out;
1833
627k
                                                }
1834
627k
                                                break;
1835
627k
                                            default:
1836
0
                                                code = gs_note_error(gs_error_unregistered); /* Must not happen. */
1837
0
                                                goto out;
1838
1.19M
                                        }
1839
4.07M
                                    } else {
1840
                                        /* A drawing command, execute entire queue. */
1841
4.07M
                                        code = execute_compositor_queue(cdev, &target, &tdev,
1842
4.07M
                                            &gs_gstate, &pcomp_first, &pcomp_last, pcomp_first, x0, y0, mem, false);
1843
4.07M
                                        if (code < 0)
1844
2
                                            goto out;
1845
4.07M
                                        break;
1846
4.07M
                                    }
1847
196M
                                }
1848
5.56M
                                if (pcomp_last != NULL) {
1849
0
                                    code = gs_note_error(gs_error_unregistered);
1850
0
                                    goto out;
1851
0
                                }
1852
5.56M
                                break;
1853
5.56M
                            case cmd_opv_ext_put_halftone:
1854
530k
                                {
1855
530k
                                    uint    ht_size;
1856
1857
530k
                                    if_debug0m('L', mem, " ext_put_halftone\n");
1858
530k
                                    enc_u_getw(ht_size, cbp);
1859
530k
                                    code = read_alloc_ht_buff(&ht_buff, ht_size, mem);
1860
530k
                                    if (code < 0)
1861
0
                                        goto out;
1862
530k
                                }
1863
530k
                                break;
1864
820k
                            case cmd_opv_ext_put_ht_seg:
1865
820k
                                if_debug0m('L', mem, " ext_put_ht_seg\n");
1866
820k
                                cbuf.ptr = cbp;
1867
820k
                                code = read_ht_segment(&ht_buff, &cbuf,
1868
820k
                                                       &gs_gstate, tdev,
1869
820k
                                                       mem);
1870
820k
                                cbp = cbuf.ptr;
1871
820k
                                if (code < 0)
1872
0
                                    goto out;
1873
820k
                                break;
1874
820k
                            case cmd_opv_ext_set_color_is_devn:
1875
0
                                state.color_is_devn = true;
1876
0
                                if_debug0m('L', mem, " ext_set_color_is_devn\n");
1877
0
                                break;
1878
0
                            case cmd_opv_ext_unset_color_is_devn:
1879
0
                                state.color_is_devn = false;
1880
0
                                if_debug0m('L', mem, " ext_unset_color_is_devn\n");
1881
0
                                break;
1882
248
                            case cmd_opv_ext_tile_rect_hl:
1883
                                /* Strip tile with devn colors */
1884
248
                                cbp = cmd_read_rect(op & 0xf0, &state.rect, cbp);
1885
248
                                if_debug4m('L', mem, " x=%d y=%d w=%d h=%d\n",
1886
248
                                           state.rect.x, state.rect.y,
1887
248
                                           state.rect.width,state.rect.height);
1888
248
                                code = (*dev_proc(tdev, strip_tile_rect_devn))
1889
248
                                    (tdev, &state_tile,
1890
248
                                     state.rect.x - x0, state.rect.y - y0,
1891
248
                                     state.rect.width, state.rect.height,
1892
248
                                     &(state.tile_color_devn[0]),
1893
248
                                     &(state.tile_color_devn[1]),
1894
248
                                     tile_phase.x, tile_phase.y);
1895
248
                                break;
1896
19.5M
                            case cmd_opv_ext_put_fill_dcolor:
1897
19.5M
                                pdcolor = &fill_color;
1898
19.5M
                                goto load_dcolor;
1899
714k
                            case cmd_opv_ext_put_stroke_dcolor:
1900
714k
                                pdcolor = &stroke_color;
1901
714k
                                goto load_dcolor;
1902
248
                            case cmd_opv_ext_put_tile_devn_color0:
1903
248
                                pdcolor = &set_dev_colors[0];
1904
248
                                goto load_dcolor;
1905
248
                            case cmd_opv_ext_put_tile_devn_color1:
1906
248
                                pdcolor = &set_dev_colors[1];
1907
20.2M
                    load_dcolor:{
1908
20.2M
                                    uint    color_size;
1909
20.2M
                                    int left, offset, l;
1910
20.2M
                                    const gx_device_color_type_t *  pdct;
1911
20.2M
                                    byte type_and_flag = *cbp++;
1912
20.2M
                                    byte is_continuation = type_and_flag & 0x80;
1913
1914
20.2M
                                    if_debug0m('L', mem, " cmd_opv_ext_put_drawing_color\n");
1915
20.2M
                                    pdct = gx_get_dc_type_from_index(type_and_flag & 0x7F);
1916
20.2M
                                    if (pdct == 0) {
1917
0
                                        code = gs_note_error(gs_error_rangecheck);
1918
0
                                        goto out;
1919
0
                                    }
1920
20.2M
                                    offset = 0;
1921
20.2M
                                    if (is_continuation)
1922
20.2M
                                        enc_u_getw(offset, cbp);
1923
20.2M
                                    enc_u_getw(color_size, cbp);
1924
20.2M
                                    left = color_size;
1925
20.2M
                                    if (!left) {
1926
                                        /* We still need to call pdct->read because it may change dev_color.type -
1927
                                           see gx_dc_null_read.*/
1928
483k
                                        code = pdct->read(pdcolor, &gs_gstate,
1929
483k
                                                          pdcolor, tdev, offset,
1930
483k
                                                          cbp, 0, mem, x0, y0);
1931
483k
                                        if (code < 0)
1932
0
                                            goto out;
1933
483k
                                    }
1934
66.4M
                                    while (left) {
1935
46.1M
                                        if (cbuf.warn_limit - cbp < (int)left) {  /* cbp can be past warn_limit */
1936
27.8M
                                            code = top_up_cbuf(&cbuf, &cbp);
1937
27.8M
                                            if (code < 0)
1938
0
                                                goto top_up_failed;
1939
27.8M
                                        }
1940
46.1M
                                        l = min(left, cbuf.end - cbp);
1941
46.1M
                                        code = pdct->read(pdcolor, &gs_gstate,
1942
46.1M
                                                          pdcolor, tdev, offset,
1943
46.1M
                                                          cbp, l, mem, x0, y0);
1944
46.1M
                                        if (code < 0)
1945
0
                                            goto out;
1946
46.1M
                                        l = code;
1947
46.1M
                                        cbp += l;
1948
46.1M
                                        offset += l;
1949
46.1M
                                        left -= l;
1950
46.1M
                                    }
1951
20.2M
                                    code = gx_color_load(pdcolor, &gs_gstate,
1952
20.2M
                                                         tdev);
1953
20.2M
                                    if (code < 0)
1954
0
                                        goto out;
1955
20.2M
                                }
1956
20.2M
                                break;
1957
20.2M
                            default:
1958
0
                                goto bad_op;
1959
27.1M
                        }
1960
27.1M
                        break;
1961
27.1M
                    default:
1962
0
                        goto bad_op;
1963
51.0M
                }
1964
33.6M
                continue;
1965
44.9M
            case cmd_op_segment >> 4:
1966
44.9M
                {
1967
44.9M
                    int i;
1968
44.9M
                    static const byte op_num_operands[] = {
1969
44.9M
                        cmd_segment_op_num_operands_values
1970
44.9M
                    };
1971
44.9M
                  rgapto:
1972
44.9M
                    if (!in_path) {
1973
6.96M
                        ppos.x = int2fixed(state.rect.x);
1974
6.96M
                        ppos.y = int2fixed(state.rect.y);
1975
6.96M
                        if_debug2m('L', mem, " (%d,%d)", state.rect.x,
1976
6.96M
                                   state.rect.y);
1977
6.96M
                        notes = sn_none;
1978
6.96M
                        in_path = true;
1979
6.96M
                    }
1980
119M
                    for (i = 0; i < op_num_operands[op & 0xf]; ++i) {
1981
74.8M
                        fixed v;
1982
74.8M
                        int b = *cbp;
1983
1984
74.8M
                        switch (b >> 5) {
1985
20.8M
                            case 0:
1986
38.7M
                            case 1:
1987
38.7M
                                vs[i++] =
1988
38.7M
                                    ((fixed) ((b ^ 0x20) - 0x20) << 13) +
1989
38.7M
                                    ((int)cbp[1] << 5) + (cbp[2] >> 3);
1990
38.7M
                                if_debug1m('L', mem, " %g", fixed2float(vs[i - 1]));
1991
38.7M
                                cbp += 2;
1992
38.7M
                                v = (int)((*cbp & 7) ^ 4) - 4;
1993
38.7M
                                break;
1994
11.9M
                            case 2:
1995
22.9M
                            case 3:
1996
22.9M
                                v = (b ^ 0x60) - 0x20;
1997
22.9M
                                break;
1998
2.34M
                            case 4:
1999
4.43M
                            case 5:
2000
                                /*
2001
                                 * Without the following cast, C's
2002
                                 * brain-damaged coercion rules cause the
2003
                                 * result to be considered unsigned, and not
2004
                                 * sign-extended on machines where
2005
                                 * sizeof(long) > sizeof(int).
2006
                                 */
2007
4.43M
                                v = (((b ^ 0xa0) - 0x20) << 8) + (int)*++cbp;
2008
4.43M
                                break;
2009
7.40M
                            case 6:
2010
7.40M
                                v = (b ^ 0xd0) - 0x10;
2011
7.40M
                                vs[i] =
2012
7.40M
                                    ((v << 8) + cbp[1]) << (_fixed_shift - 2);
2013
7.40M
                                if_debug1m('L', mem, " %g", fixed2float(vs[i]));
2014
7.40M
                                cbp += 2;
2015
7.40M
                                continue;
2016
1.41M
                            default /*case 7 */ :
2017
1.41M
                                v = (int)(*++cbp ^ 0x80) - 0x80;
2018
2.82M
                                for (b = 0; b < sizeof(fixed) - 3; ++b)
2019
1.41M
                                    v = (v << 8) + *++cbp;
2020
1.41M
                                break;
2021
74.8M
                        }
2022
67.4M
                        cbp += 3;
2023
                        /* Absent the cast in the next statement, */
2024
                        /* the Borland C++ 4.5 compiler incorrectly */
2025
                        /* sign-extends the result of the shift. */
2026
67.4M
                        vs[i] = (v << 16) + (uint) (cbp[-2] << 8) + cbp[-1];
2027
67.4M
                        if_debug1m('L', mem, " %g", fixed2float(vs[i]));
2028
67.4M
                    }
2029
44.9M
                    if_debug0m('L', mem, "\n");
2030
44.9M
                    code = clist_decode_segment(&path, op, vs, &ppos,
2031
44.9M
                                                x0, y0, notes);
2032
44.9M
                    if (code < 0)
2033
0
                        goto out;
2034
44.9M
                }
2035
44.9M
                continue;
2036
67.3M
            case cmd_op_path >> 4:
2037
67.3M
                if (op == cmd_opv_rgapto)
2038
0
                    goto rgapto;
2039
67.3M
                else if (op == cmd_opv_lock_pattern) {
2040
1.96k
                    gs_id id;
2041
1.96k
                    int lock = *cbp++;
2042
1.96k
                    cmd_get_value(id, cbp);
2043
1.96k
                    if_debug2m('L', mem, "id=0x%lx, lock=%d\n", id, lock);
2044
                    /* We currently lock the pattern in all the bands, even in ones
2045
                     * where we haven't used the pattern. This can cause the following
2046
                     * call to return with 'undefined' because the pattern is not
2047
                     * found. Just swallow this error and continue. */
2048
1.96k
                    code = gx_pattern_cache_entry_set_lock(&gs_gstate, id, lock);
2049
1.96k
                    if (code == gs_error_undefined)
2050
0
                        code = 0;
2051
1.96k
                    if (code < 0)
2052
0
                        goto out;
2053
1.96k
                    continue;
2054
67.3M
                } else {
2055
67.3M
                    gx_path fpath;
2056
67.3M
                    gx_path *ppath = &path;
2057
2058
67.3M
                    if_debug0m('L', mem, "\n");
2059
                    /* if in clip, flatten path first */
2060
67.3M
                    if (in_clip) {
2061
1.05M
                        gx_path_init_local(&fpath, mem);
2062
1.05M
                        code = gx_path_add_flattened_accurate(&path, &fpath,
2063
1.05M
                                             gs_currentflat_inline(&gs_gstate),
2064
1.05M
                                             gs_gstate.accurate_curves);
2065
1.05M
                        if (code < 0)
2066
0
                            goto out;
2067
1.05M
                        ppath = &fpath;
2068
1.05M
                    }
2069
67.3M
                    switch (op) {
2070
5.07M
                        case cmd_opv_fill:
2071
5.07M
                            fill_params.rule = gx_rule_winding_number;
2072
5.07M
                            goto fill;
2073
233k
                        case cmd_opv_eofill:
2074
233k
                            fill_params.rule = gx_rule_even_odd;
2075
5.31M
                        fill:
2076
5.31M
                            fill_params.adjust = gs_gstate.fill_adjust;
2077
5.31M
                            fill_params.flatness = gs_gstate.flatness;
2078
5.31M
                            code = (*dev_proc(tdev, fill_path))(tdev, &gs_gstate, ppath,
2079
5.31M
                                                                &fill_params, &fill_color, pcpath);
2080
5.31M
                            break;
2081
101k
                        case cmd_opv_fill_stroke:
2082
101k
                            fill_params.rule = gx_rule_winding_number;
2083
101k
                            goto fill_stroke;
2084
17.9k
                        case cmd_opv_eofill_stroke:
2085
17.9k
                            fill_params.rule = gx_rule_even_odd;
2086
119k
                        fill_stroke:
2087
119k
                            fill_params.adjust = gs_gstate.fill_adjust;
2088
119k
                            fill_params.flatness = gs_gstate.flatness;
2089
119k
                            stroke_params.flatness = gs_gstate.flatness;
2090
119k
                            stroke_params.traditional = false;
2091
119k
                            code = (*dev_proc(tdev, fill_stroke_path))(tdev, &gs_gstate, ppath,
2092
119k
                                                                &fill_params, &fill_color,
2093
119k
                                                                &stroke_params, &stroke_color, pcpath);
2094
119k
                            break;
2095
5.32M
                        case cmd_opv_stroke:
2096
5.32M
                            stroke_params.flatness = gs_gstate.flatness;
2097
5.32M
                            stroke_params.traditional = false;
2098
5.32M
                            code = (*dev_proc(tdev, stroke_path))
2099
5.32M
                                                       (tdev, &gs_gstate,
2100
5.32M
                                                       ppath, &stroke_params,
2101
5.32M
                                                       &stroke_color, pcpath);
2102
5.32M
                            break;
2103
311k
                        case cmd_opv_polyfill:
2104
311k
                            code = clist_do_polyfill(tdev, ppath, &fill_color,
2105
311k
                                                     gs_gstate.log_op);
2106
311k
                            break;
2107
56.2M
                        case cmd_opv_fill_trapezoid:
2108
56.2M
                            {
2109
56.2M
                                gs_fixed_edge left, right;
2110
56.2M
                                fixed ybot, ytop;
2111
56.2M
                                int options, swap_axes, wh;
2112
56.2M
                                fixed x0f;
2113
56.2M
                                fixed y0f;
2114
56.2M
                                gx_device *ttdev = tdev;
2115
2116
56.2M
                                if (pcpath != NULL && !clipper_dev_open) {
2117
1.88k
                                    gx_make_clip_device_on_stack(&clipper_dev, pcpath, tdev);
2118
1.88k
                                    clipper_dev_open = true;
2119
1.88k
                                }
2120
56.2M
                                if (clipper_dev_open)
2121
34.2M
                                    ttdev = (gx_device *)&clipper_dev;
2122
                                /* Note that if we have transparency present, the clipper device may need to have
2123
                                   its color information updated to be synced up with the target device.
2124
                                   This can occur if we had fills of a path first with a transparency mask to get
2125
                                   an XPS opacity followed by a fill with a transparency group. This occurs in
2126
                                   the XPS gradient code */
2127
56.2M
                                if (tdev->color_info.num_components != ttdev->color_info.num_components){
2128
                                    /* Reset the clipper device color information. Only worry about
2129
                                       the information that is used in the trap code */
2130
0
                                    ttdev->color_info.num_components = tdev->color_info.num_components;
2131
0
                                    ttdev->color_info.depth = tdev->color_info.depth;
2132
0
                                    ttdev->color_info.polarity = tdev->color_info.polarity;
2133
0
                                    memcpy(&(ttdev->color_info.comp_bits),&(tdev->color_info.comp_bits),GX_DEVICE_COLOR_MAX_COMPONENTS);
2134
0
                                    memcpy(&(ttdev->color_info.comp_shift),&(tdev->color_info.comp_shift),GX_DEVICE_COLOR_MAX_COMPONENTS);
2135
0
                                }
2136
56.2M
                                cmd_getw(left.start.x, cbp);
2137
56.2M
                                cmd_getw(left.start.y, cbp);
2138
56.2M
                                cmd_getw(left.end.x, cbp);
2139
56.2M
                                cmd_getw(left.end.y, cbp);
2140
56.2M
                                cmd_getw(right.start.x, cbp);
2141
56.2M
                                cmd_getw(right.start.y, cbp);
2142
56.2M
                                cmd_getw(right.end.x, cbp);
2143
56.2M
                                cmd_getw(right.end.y, cbp);
2144
56.2M
                                cmd_getw(options, cbp);
2145
56.2M
                                if (!(options & 4)) {
2146
55.8M
                                    cmd_getw(ybot, cbp);
2147
55.8M
                                    cmd_getw(ytop, cbp);
2148
55.8M
                                } else
2149
430k
                                    ytop = ybot = 0; /* Unused, but quiet gcc warning. */
2150
56.2M
                                swap_axes = options & 1;
2151
56.2M
                                wh = swap_axes ? tdev->width : tdev->height;
2152
56.2M
                                x0f = int2fixed(swap_axes ? y0 : x0);
2153
56.2M
                                y0f = int2fixed(swap_axes ? x0 : y0);
2154
56.2M
                                left.start.x -= x0f;
2155
56.2M
                                left.start.y -= y0f;
2156
56.2M
                                left.end.x -= x0f;
2157
56.2M
                                left.end.y -= y0f;
2158
56.2M
                                right.start.x -= x0f;
2159
56.2M
                                right.start.y -= y0f;
2160
56.2M
                                right.end.x -= x0f;
2161
56.2M
                                right.end.y -= y0f;
2162
56.2M
                                if (options & 2) {
2163
535k
                                    uchar num_components = tdev->color_info.num_components;
2164
535k
                                    frac31 c[4][GX_DEVICE_COLOR_MAX_COMPONENTS], *cc[4];
2165
535k
                                    byte colors_mask, i, j, m = 1;
2166
535k
                                    gs_fill_attributes fa;
2167
535k
                                    gs_fixed_rect clip;
2168
535k
                                    fixed hh = int2fixed(swap_axes ? target->width : target->height);
2169
2170
535k
                                    if (cbuf.end - cbp < 5 * cmd_max_intsize(sizeof(frac31))) {
2171
285
                                        code = top_up_cbuf(&cbuf, &cbp);
2172
285
                                        if (code < 0)
2173
0
                                            goto top_up_failed;
2174
285
                                    }
2175
535k
                                    cmd_getw(clip.p.x, cbp);
2176
535k
                                    cmd_getw(clip.p.y, cbp);
2177
535k
                                    cmd_getw(clip.q.x, cbp);
2178
535k
                                    cmd_getw(clip.q.y, cbp);
2179
535k
                                    clip.p.x -= x0f;
2180
535k
                                    clip.p.y -= y0f;
2181
535k
                                    clip.q.x -= x0f;
2182
535k
                                    clip.q.y -= y0f;
2183
535k
                                    if (clip.p.y < 0)
2184
186k
                                        clip.p.y = 0;
2185
535k
                                    if (clip.q.y > hh)
2186
370k
                                        clip.q.y = hh;
2187
535k
                                    fa.clip = &clip;
2188
535k
                                    fa.swap_axes = swap_axes;
2189
535k
                                    fa.ht = NULL;
2190
535k
                                    fa.lop = lop_default; /* fgixme: gs_gstate.log_op; */
2191
535k
                                    fa.ystart = ybot - y0f;
2192
535k
                                    fa.yend = ytop - y0f;
2193
535k
                                    cmd_getw(colors_mask, cbp);
2194
2.67M
                                    for (i = 0; i < 4; i++, m <<= 1) {
2195
2.14M
                                        if (colors_mask & m) {
2196
1.50M
                                            if (cbuf.end - cbp < num_components * cmd_max_intsize(sizeof(frac31))) {
2197
1.46k
                                                code = top_up_cbuf(&cbuf, &cbp);
2198
1.46k
                                                if (code < 0)
2199
0
                                                    goto top_up_failed;
2200
1.46k
                                            }
2201
1.50M
                                            cc[i] = c[i];
2202
3.93M
                                            for (j = 0; j < num_components; j++)
2203
2.43M
                                                cmd_getfrac(c[i][j], cbp);
2204
1.50M
                                        } else
2205
640k
                                            cc[i] = NULL;
2206
2.14M
                                    }
2207
535k
                                    if (options & 4) {
2208
430k
#                                       if 1 /* Disable to debug gx_fill_triangle_small. */
2209
430k
                                        code = dev_proc(ttdev, fill_linear_color_triangle)(ttdev, &fa,
2210
430k
                                                        &left.start, &left.end, &right.start,
2211
430k
                                                        cc[0], cc[1], cc[2]);
2212
#                                       else
2213
                                        code = 0;
2214
#                                       endif
2215
430k
                                        if (code == 0) {
2216
                                            /* The target device didn't fill the trapezoid and
2217
                                               requests a decomposition. Subdivide into smaller triangles : */
2218
0
                                            if (pfs.dev == NULL)
2219
0
                                                code = gx_init_patch_fill_state_for_clist(tdev, &pfs, mem);
2220
0
                                            if (code >= 0) {
2221
0
                                                pfs.dev = ttdev;
2222
0
                                                pfs.rect = clip; /* fixme: eliminate 'clip'. */
2223
0
                                                fa.pfs = &pfs;
2224
0
                                                code = gx_fill_triangle_small(ttdev, &fa,
2225
0
                                                            &left.start, &left.end, &right.start,
2226
0
                                                            cc[0], cc[1], cc[2]);
2227
0
                                            }
2228
0
                                        }
2229
430k
                                    } else {
2230
105k
                                        code = dev_proc(ttdev, fill_linear_color_trapezoid)(ttdev, &fa,
2231
105k
                                                        &left.start, &left.end, &right.start, &right.end,
2232
105k
                                                        cc[0], cc[1], cc[2], cc[3]);
2233
105k
                                        if (code == 0) {
2234
                                            /* Fixme : The target device didn't fill the trapezoid and
2235
                                               requests a decomposition.
2236
                                               Currently we never call it with 4 colors (see gxshade6.c)
2237
                                               and 2 colors must not return 0 - see comment to
2238
                                               dev_t_proc_fill_linear_color_trapezoid in gxdevcli.c .
2239
                                               Must not happen. */
2240
0
                                            code = gs_note_error(gs_error_unregistered);
2241
0
                                        }
2242
105k
                                    }
2243
535k
                                } else
2244
55.7M
                                    code = gx_default_fill_trapezoid(ttdev, &left, &right,
2245
55.7M
                                        max(ybot - y0f, fixed_half),
2246
55.7M
                                        min(ytop - y0f, int2fixed(wh)), swap_axes,
2247
55.7M
                                        &fill_color, gs_gstate.log_op);
2248
56.2M
                            }
2249
56.2M
                           break;
2250
56.2M
                        default:
2251
0
                            goto bad_op;
2252
67.3M
                    }
2253
67.3M
                    if (ppath != &path)
2254
1.05M
                        gx_path_free(ppath, "clist_render_band");
2255
67.3M
                }
2256
67.3M
                if (in_path) {  /* path might be empty! */
2257
6.96M
                    state.rect.x = fixed2int_var(ppos.x);
2258
6.96M
                    state.rect.y = fixed2int_var(ppos.y);
2259
6.96M
                    in_path = false;
2260
6.96M
                }
2261
67.3M
                gx_path_free(&path, "clist_render_band");
2262
67.3M
                gx_path_init_local(&path, mem);
2263
67.3M
                if (code < 0)
2264
2
                    goto out;
2265
67.3M
                continue;
2266
67.3M
            default:
2267
0
              bad_op:mlprintf5(mem, "Bad op %02x band y0 = %d file pos %"PRId64" buf pos %d/%d\n",
2268
0
                 op, y0, stell(s), (int)(cbp - cbuf.data), (int)(cbuf.end - cbuf.data));
2269
0
                {
2270
0
                    const byte *pp;
2271
2272
0
                    for (pp = cbuf.data; pp < cbuf.end; pp += 10) {
2273
0
                        dmlprintf1(mem, "%4d:", (int)(pp - cbuf.data));
2274
0
                        dmprintf10(mem, " %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
2275
0
                                  pp[0], pp[1], pp[2], pp[3], pp[4],
2276
0
                                  pp[5], pp[6], pp[7], pp[8], pp[9]);
2277
0
                    }
2278
0
                }
2279
0
                code = gs_note_error(gs_error_Fatal);
2280
0
                goto out;
2281
284M
        }
2282
284M
        if_debug4m('L', mem, " x=%d y=%d w=%d h=%d\n",
2283
63.3M
                  state.rect.x, state.rect.y, state.rect.width,
2284
63.3M
                  state.rect.height);
2285
63.3M
        switch (op >> 4) {
2286
3.62M
            case cmd_op_fill_rect >> 4:
2287
3.62M
                if (state.rect.width == 0 && state.rect.height == 0 &&
2288
1.92M
                    state.rect.x == 0 && state.rect.y == 0) {
2289
                    /* FIXME: This test should be unnecessary. Bug 692076
2290
                     * is open pending a proper fix. */
2291
1.92M
                    code = (dev_proc(tdev, fillpage) == NULL ? 0 :
2292
1.92M
                            (*dev_proc(tdev, fillpage))(tdev, &gs_gstate,
2293
1.92M
                                                        &fill_color));
2294
1.92M
                    break;
2295
1.92M
                }
2296
5.56M
            case cmd_op_fill_rect_short >> 4:
2297
36.1M
            case cmd_op_fill_rect_tiny >> 4:
2298
36.1M
                if (!state.lop_enabled) {
2299
36.1M
                    code = (*dev_proc(tdev, fill_rectangle))
2300
36.1M
                        (tdev, state.rect.x - x0, state.rect.y - y0,
2301
36.1M
                         state.rect.width, state.rect.height,
2302
36.1M
                         state.colors[1]);
2303
36.1M
                    break;
2304
36.1M
                }
2305
0
                source = NULL;
2306
0
                data_x = 0;
2307
0
                raster = 0;
2308
0
                colors[0] = colors[1] = state.colors[1];
2309
0
                log_op = state.lop;
2310
0
                pcolor = colors;
2311
0
         do_rop:code = (*dev_proc(tdev, strip_copy_rop2))
2312
0
                                (tdev, source, data_x, raster, gx_no_bitmap_id,
2313
0
                                 pcolor, &state_tile,
2314
0
                                 (state.tile_colors[0] == gx_no_color_index &&
2315
0
                                  state.tile_colors[1] == gx_no_color_index ?
2316
0
                                  NULL : state.tile_colors),
2317
0
                                 state.rect.x - x0, state.rect.y - y0,
2318
0
                                 state.rect.width - data_x, state.rect.height,
2319
0
                                 tile_phase.x, tile_phase.y, log_op,
2320
0
                                 plane_height);
2321
0
                     plane_height = 0;
2322
0
                data_x = 0;
2323
0
                break;
2324
98.6k
            case cmd_op_tile_rect >> 4:
2325
98.6k
                if (state.rect.width == 0 && state.rect.height == 0 &&
2326
0
                    state.rect.x == 0 && state.rect.y == 0) {
2327
0
                    code = (*dev_proc(tdev, fillpage))(tdev, &gs_gstate, &fill_color);
2328
0
                    break;
2329
0
                }
2330
915k
            case cmd_op_tile_rect_short >> 4:
2331
1.92M
            case cmd_op_tile_rect_tiny >> 4:
2332
                /* Currently we don't use lop with strip_tile_rectangle. */
2333
1.92M
                code = (*dev_proc(tdev, strip_tile_rectangle))
2334
1.92M
                    (tdev, &state_tile,
2335
1.92M
                     state.rect.x - x0, state.rect.y - y0,
2336
1.92M
                     state.rect.width, state.rect.height,
2337
1.92M
                     state.tile_colors[0], state.tile_colors[1],
2338
1.92M
                     tile_phase.x, tile_phase.y);
2339
1.92M
                break;
2340
20.8M
            case cmd_op_copy_mono_planes >> 4:
2341
20.8M
                if (state.lop_enabled) {
2342
0
                    pcolor = state.colors;
2343
0
                    log_op = state.lop;
2344
0
                    goto do_rop;
2345
0
                }
2346
20.8M
                if ((op & cmd_copy_use_tile) || pcpath != NULL) {       /*
2347
                                                                         * This call of copy_mono originated as a call
2348
                                                                         * of fill_mask.
2349
                                                                         */
2350
20.3M
                    code = gx_image_fill_masked
2351
20.3M
                        (tdev, source, data_x, raster, gx_no_bitmap_id,
2352
20.3M
                         state.rect.x - x0, state.rect.y - y0,
2353
20.3M
                         state.rect.width - data_x, state.rect.height,
2354
20.3M
                         &fill_color, 1, gs_gstate.log_op, pcpath);
2355
20.3M
                } else {
2356
514k
                    if (plane_height == 0) {
2357
508k
                        code = (*dev_proc(tdev, copy_mono))
2358
508k
                             (tdev, source, data_x, raster, gx_no_bitmap_id,
2359
508k
                              state.rect.x - x0, state.rect.y - y0,
2360
508k
                              state.rect.width - data_x, state.rect.height,
2361
508k
                              state.colors[0], state.colors[1]);
2362
508k
                    } else {
2363
6.91k
                        code = (*dev_proc(tdev, copy_planes))
2364
6.91k
                             (tdev, source, data_x, raster, gx_no_bitmap_id,
2365
6.91k
                              state.rect.x - x0, state.rect.y - y0,
2366
6.91k
                              state.rect.width - data_x, state.rect.height,
2367
6.91k
                              plane_height);
2368
6.91k
                    }
2369
514k
                }
2370
20.8M
                plane_height = 0;
2371
20.8M
                data_x = 0;
2372
20.8M
                break;
2373
2.55M
            case cmd_op_copy_color_alpha >> 4:
2374
2.55M
                if (state.color_is_alpha) {
2375
/****** CAN'T DO ROP WITH ALPHA ******/
2376
0
                    if (state.color_is_devn &&
2377
0
                        dev_proc(tdev, copy_alpha_hl_color) != gx_default_no_copy_alpha_hl_color) { /* FIXME */
2378
0
                        code = (*dev_proc(tdev, copy_alpha_hl_color))
2379
0
                            (tdev, source, data_x, raster, gx_no_bitmap_id,
2380
0
                             state.rect.x - x0, state.rect.y - y0,
2381
0
                             state.rect.width - data_x, state.rect.height,
2382
0
                             &fill_color, depth);
2383
0
                    } else {
2384
0
                        code = (*dev_proc(tdev, copy_alpha))
2385
0
                            (tdev, source, data_x, raster, gx_no_bitmap_id,
2386
0
                             state.rect.x - x0, state.rect.y - y0,
2387
0
                             state.rect.width - data_x, state.rect.height,
2388
0
                             state.colors[1], depth);
2389
0
                    }
2390
2.55M
                } else {
2391
2.55M
                    if (state.lop_enabled) {
2392
0
                        pcolor = NULL;
2393
0
                        log_op = state.lop;
2394
0
                        goto do_rop;
2395
0
                    }
2396
2.55M
                    code = (*dev_proc(tdev, copy_color))
2397
2.55M
                        (tdev, source, data_x, raster, gx_no_bitmap_id,
2398
2.55M
                         state.rect.x - x0, state.rect.y - y0,
2399
2.55M
                         state.rect.width - data_x, state.rect.height);
2400
2.55M
                }
2401
2.55M
                data_x = 0;
2402
2.55M
                break;
2403
0
            default:            /* can't happen */
2404
0
                goto bad_op;
2405
63.3M
        }
2406
63.3M
    }
2407
    /* Clean up before we exit. */
2408
1.94M
  out:
2409
2410
1.94M
    if(gs_gstate.icc_manager != NULL) {
2411
1.94M
        rc_decrement(gs_gstate.icc_manager->srcgtag_profile, "clist_playback_band");
2412
1.94M
        gs_gstate.icc_manager->srcgtag_profile = NULL;
2413
1.94M
    }
2414
1.94M
    if (ht_buff.pbuff != 0) {
2415
0
        gs_free_object(mem, ht_buff.pbuff, "clist_playback_band(ht_buff)");
2416
0
        ht_buff.pbuff = 0;
2417
0
        ht_buff.pcurr = 0;
2418
0
    }
2419
1.94M
    ht_buff.ht_size = 0;
2420
1.94M
    ht_buff.read_size = 0;
2421
2422
1.94M
    if (pcomp_last != NULL) {
2423
0
        int code1 = drop_compositor_queue(&pcomp_first, &pcomp_last, NULL, mem, x0, y0, &gs_gstate);
2424
2425
0
        if (code == 0)
2426
0
            code = code1;
2427
0
    }
2428
1.94M
    gx_cpath_free(&clip_path, "clist_render_band exit");
2429
1.94M
    gx_path_free(&path, "clist_render_band exit");
2430
1.94M
    if (gs_gstate.pattern_cache != NULL) {
2431
53.8k
        gx_pattern_cache_free(gs_gstate.pattern_cache);
2432
53.8k
        gs_gstate.pattern_cache = NULL;
2433
53.8k
    }
2434
    /* Free the client color and device colors allocated upon entry */
2435
1.94M
    gs_free_object(mem, gs_gstate.color[0].ccolor, "clist_playback_band");
2436
1.94M
    gs_free_object(mem, gs_gstate.color[1].ccolor, "clist_playback_band");
2437
1.94M
    gs_free_object(mem, gs_gstate.color[0].dev_color, "clist_playback_band");
2438
1.94M
    gs_free_object(mem, gs_gstate.color[1].dev_color, "clist_playback_band");
2439
1.94M
    gs_gstate.color[0].ccolor = gs_gstate.color[1].ccolor = NULL;
2440
1.94M
    gs_gstate.color[0].dev_color = gs_gstate.color[1].dev_color = NULL;
2441
2442
    /* The imager state release will decrement the icc link cache.  To avoid
2443
       race conditions lock the cache */
2444
1.94M
    gx_monitor_enter(cdev->icc_cache_cl->lock);
2445
1.94M
    gs_gstate_release(&gs_gstate);
2446
1.94M
    gx_monitor_leave(cdev->icc_cache_cl->lock); /* done with increment, let everyone run */
2447
1.94M
    gs_free_object(mem, data_bits, "clist_playback_band(data_bits)");
2448
1.94M
    if (target != orig_target) {
2449
948k
        if (target->rc.ref_count != 1) {
2450
            /* This can occur if we are coming from a pattern clist that
2451
               includes transparency.  In this case, we do not want to
2452
               free the compositor since it is really the main target that
2453
               we are tiling into.  i.e. the tile itself does not have
2454
               a pdf14 device, but rather we push a trans group, draw and
2455
               then pop the group to properly blend */
2456
0
            rc_decrement(target, "gxclrast(target compositor)");
2457
948k
        } else {
2458
            /* Ref count was 1. close the device and then free it */
2459
948k
            if (target->is_open)
2460
304
                dev_proc(target, close_device)(target);
2461
948k
            gs_free_object(target->memory, target, "gxclrast discard compositor");
2462
948k
        }
2463
948k
        target = orig_target;
2464
948k
    }
2465
1.94M
    if (code < 0) {
2466
27
        if (pfs.dev != NULL)
2467
0
            term_patch_fill_state(&pfs);
2468
27
        rc_decrement(gs_gstate.color[0].color_space, "clist_playback_band");
2469
27
        rc_decrement(gs_gstate.color[1].color_space, "clist_playback_band");
2470
27
        gs_free_object(mem, cbuf_storage, "clist_playback_band(cbuf_storage)");
2471
27
        gx_cpath_free(&clip_path, "clist_playback_band");
2472
27
        if (pcpath != &clip_path)
2473
17
            gx_cpath_free(pcpath, "clist_playback_band");
2474
27
        if (clipper_dev_open)
2475
0
            gx_destroy_clip_device_on_stack(&clipper_dev);
2476
27
        return_error(code);
2477
27
    }
2478
    /* Check whether we have more pages to process. */
2479
1.94M
    if ((playback_action != playback_action_setup &&
2480
1.94M
        (cbp < cbuf.end || !seofp(s)) && (op != cmd_opv_end_page) )
2481
1.94M
        )
2482
0
        goto in;
2483
1.94M
    if (pfs.dev != NULL)
2484
0
        term_patch_fill_state(&pfs);
2485
1.94M
    rc_decrement(gs_gstate.color[0].color_space, "clist_playback_band");
2486
1.94M
    rc_decrement(gs_gstate.color[1].color_space, "clist_playback_band");
2487
1.94M
    gs_free_object(mem, cbuf_storage, "clist_playback_band(cbuf_storage)");
2488
1.94M
    gx_cpath_free(&clip_path, "clist_playback_band");
2489
1.94M
    if (pcpath != &clip_path)
2490
1.66M
        gx_cpath_free(pcpath, "clist_playback_band");
2491
1.94M
    if (clipper_dev_open)
2492
1.01k
        gx_destroy_clip_device_on_stack(&clipper_dev);
2493
1.94M
    return code;
2494
0
top_up_failed:
2495
0
    gx_cpath_free(&clip_path, "clist_playback_band");
2496
0
    if (pcpath != &clip_path)
2497
0
        gx_cpath_free(pcpath, "clist_playback_band");
2498
0
    if (clipper_dev_open)
2499
0
        gx_destroy_clip_device_on_stack(&clipper_dev);
2500
0
    return code;
2501
1.94M
}
2502
2503
/* ---------------- Individual commands ---------------- */
2504
2505
/*
2506
 * These single-use procedures implement a few large individual commands,
2507
 * primarily for readability but also to avoid overflowing compilers'
2508
 * optimization limits.  They all take the command buffer as their first
2509
 * parameter (pcb), assume that the current buffer pointer is in pcb->ptr,
2510
 * and update it there.
2511
 */
2512
2513
static int
2514
read_set_tile_size(command_buf_t *pcb, tile_slot *bits, bool for_pattern)
2515
3.12k
{
2516
3.12k
    const byte *cbp = pcb->ptr;
2517
3.12k
    uint rep_width, rep_height;
2518
3.12k
    uint pdepth;
2519
3.12k
    byte bd = *cbp++;
2520
2521
3.12k
    bits->head.depth = cmd_code_to_depth(bd);
2522
3.12k
    if (for_pattern)
2523
3.12k
        cmd_getw(bits->id, cbp);
2524
3.12k
    cmd_getw(rep_width, cbp);
2525
3.12k
    cmd_getw(rep_height, cbp);
2526
3.12k
    if (bd & 0x20) {
2527
3.10k
        cmd_getw(bits->x_reps, cbp);
2528
3.10k
        bits->width = rep_width * bits->x_reps;
2529
3.10k
    } else {
2530
20
        bits->x_reps = 1;
2531
20
        bits->width = rep_width;
2532
20
    }
2533
3.12k
    if (bd & 0x40) {
2534
1.00k
        cmd_getw(bits->y_reps, cbp);
2535
1.00k
        bits->height = rep_height * bits->y_reps;
2536
2.12k
    } else {
2537
2.12k
        bits->y_reps = 1;
2538
2.12k
        bits->height = rep_height;
2539
2.12k
    }
2540
3.12k
    if (bd & 0x80)
2541
3.12k
        cmd_getw(bits->rep_shift, cbp);
2542
3.12k
    else
2543
3.12k
        bits->rep_shift = 0;
2544
3.12k
    if (bd & 0x10)
2545
0
        bits->num_planes = *cbp++;
2546
3.12k
    else
2547
3.12k
        bits->num_planes = 1;
2548
3.12k
    if_debug7('L', " depth=%d size=(%d,%d), rep_size=(%d,%d), rep_shift=%d, num_planes=%d\n",
2549
3.12k
              bits->head.depth, bits->width,
2550
3.12k
              bits->height, rep_width,
2551
3.12k
              rep_height, bits->rep_shift, bits->num_planes);
2552
3.12k
    bits->shift =
2553
3.12k
        (bits->rep_shift == 0 ? 0 :
2554
3.12k
         (bits->rep_shift * (bits->height / rep_height)) % rep_width);
2555
3.12k
    pdepth = bits->head.depth;
2556
3.12k
    if (bits->num_planes != 1)
2557
0
        pdepth /= bits->num_planes;
2558
3.12k
    bits->raster = bitmap_raster(bits->width * pdepth);
2559
3.12k
    pcb->ptr = cbp;
2560
3.12k
    return 0;
2561
3.12k
}
2562
2563
static int
2564
read_set_bits(command_buf_t *pcb, tile_slot *bits, int compress,
2565
              gx_clist_state *pcls, gx_strip_bitmap *tile, tile_slot **pslot,
2566
              gx_device_clist_reader *cdev, gs_memory_t *mem)
2567
7.05M
{
2568
7.05M
    const byte *cbp = pcb->ptr;
2569
7.05M
    uint rep_width = bits->width / bits->x_reps;
2570
7.05M
    uint rep_height = bits->height / bits->y_reps;
2571
7.05M
    uint index;
2572
7.05M
    ulong offset;
2573
7.05M
    uint width_bits;
2574
7.05M
    uint width_bytes;
2575
7.05M
    uint raster;
2576
7.05M
    uint bytes;
2577
7.05M
    byte *data;
2578
7.05M
    tile_slot *slot;
2579
7.05M
    uint depth = bits->head.depth;
2580
2581
7.05M
    if (bits->num_planes != 1)
2582
0
        depth /= bits->num_planes;
2583
7.05M
    width_bits = rep_width * depth;
2584
2585
7.05M
    bytes = clist_bitmap_bytes(width_bits, rep_height * bits->num_planes,
2586
7.05M
                               compress |
2587
7.05M
                               (rep_width < bits->width ?
2588
7.04M
                                decompress_spread : 0) |
2589
7.05M
                               decompress_elsewhere,
2590
7.05M
                               &width_bytes,
2591
7.05M
                               (uint *)&raster);
2592
2593
7.05M
    cmd_getw(index, cbp);
2594
7.05M
    cmd_getw(offset, cbp);
2595
7.05M
    if_debug2m('L', mem, " index=%d offset=%lu\n", index, offset);
2596
7.05M
    pcls->tile_index = index;
2597
7.05M
    cdev->tile_table[pcls->tile_index].offset = offset;
2598
7.05M
    slot = (tile_slot *)(cdev->cache_chunk->data + offset);
2599
7.05M
    *pslot = slot;
2600
7.05M
    *slot = *bits;
2601
7.05M
    tile->data = data = (byte *)(slot + 1);
2602
#ifdef DEBUG
2603
    slot->index = pcls->tile_index;
2604
#endif
2605
7.05M
    if (compress == cmd_compress_const) {
2606
0
        cbp = cmd_read_data(pcb, data, 1, cbp);
2607
0
        if (width_bytes > 0 && rep_height > 0)
2608
0
            memset(data+1, *data, width_bytes * rep_height - 1);
2609
7.05M
    } else if (compress) {
2610
        /*
2611
         * Decompress the image data.  We'd like to share this code with the
2612
         * similar code in copy_*, but right now we don't see how.
2613
         */
2614
1.20M
        stream_cursor_read r;
2615
1.20M
        stream_cursor_write w;
2616
        /*
2617
         * We don't know the data length a priori, so to be conservative, we
2618
         * read the uncompressed size.
2619
         */
2620
1.20M
        uint cleft = pcb->end - cbp;
2621
2622
1.20M
        if (cleft < bytes && !pcb->end_status) {
2623
10.9k
            uint nread = cbuf_size - cleft;
2624
2625
10.9k
            advance_buffer(pcb, cbp);
2626
10.9k
            pcb->end_status = sgets(pcb->s, pcb->data + cleft, nread, &nread);
2627
10.9k
            set_cb_end(pcb, pcb->data + cleft + nread);
2628
10.9k
            cbp = pcb->data;
2629
10.9k
        }
2630
1.20M
        r.ptr = cbp - 1;
2631
1.20M
        r.limit = pcb->end - 1;
2632
1.20M
        w.ptr = data - 1;
2633
1.20M
        w.limit = w.ptr + bytes;
2634
1.20M
        switch (compress) {
2635
0
        case cmd_compress_rle:
2636
0
            {
2637
0
                stream_RLD_state sstate;
2638
2639
0
                clist_rld_init(&sstate);
2640
0
                (*s_RLD_template.process)
2641
0
                    ((stream_state *)&sstate, &r, &w, true);
2642
0
            }
2643
0
            break;
2644
1.20M
        case cmd_compress_cfe:
2645
1.20M
            {
2646
1.20M
                stream_CFD_state sstate;
2647
2648
1.20M
                clist_cfd_init(&sstate,
2649
1.20M
                               width_bytes << 3 /*width_bits */ ,
2650
1.20M
                               rep_height, mem);
2651
1.20M
                (*s_CFD_template.process)
2652
1.20M
                    ((stream_state *)&sstate, &r, &w, true);
2653
1.20M
                (*s_CFD_template.release)
2654
1.20M
                    ((stream_state *)&sstate);
2655
1.20M
            }
2656
1.20M
            break;
2657
0
        default:
2658
0
            return_error(gs_error_unregistered);
2659
1.20M
        }
2660
1.20M
        cbp = r.ptr + 1;
2661
5.85M
    } else if (rep_height * bits->num_planes > 1 && width_bytes != bits->raster) {
2662
5.81M
        cbp = cmd_read_short_bits(pcb, data, bytes,
2663
5.81M
                                  width_bytes, rep_height * bits->num_planes,
2664
5.81M
                                  bits->raster, cbp);
2665
5.81M
    } else {
2666
42.5k
        cbp = cmd_read_data(pcb, data, bytes, cbp);
2667
42.5k
    }
2668
7.05M
    if (bits->width > rep_width)
2669
12.2k
        bits_replicate_horizontally(data,
2670
12.2k
                                    rep_width * depth, rep_height * bits->num_planes,
2671
12.2k
                                    bits->raster,
2672
12.2k
                                    bits->width * depth,
2673
12.2k
                                    bits->raster);
2674
7.05M
    if (bits->height > rep_height)
2675
2.03k
        bits_replicate_vertically(data,
2676
2.03k
                                  rep_height, bits->raster,
2677
2.03k
                                  bits->height);
2678
#ifdef DEBUG
2679
    if (gs_debug_c('L'))
2680
        cmd_print_bits(mem, data, bits->width, bits->height, bits->raster);
2681
#endif
2682
7.05M
    pcb->ptr = cbp;
2683
7.05M
    return 0;
2684
7.05M
}
2685
2686
/* if necessary, allocate a buffer to hold a serialized halftone */
2687
static int
2688
read_alloc_ht_buff(ht_buff_t * pht_buff, uint ht_size, gs_memory_t * mem)
2689
751k
{
2690
    /* free the existing buffer, if any (usually none) */
2691
751k
    if (pht_buff->pbuff != 0) {
2692
0
        gs_free_object(mem, pht_buff->pbuff, "read_alloc_ht_buff");
2693
0
        pht_buff->pbuff = 0;
2694
0
    }
2695
2696
    /*
2697
     * If the serialized halftone fits in the command buffer, no
2698
     * additional buffer is required.
2699
     */
2700
751k
    if (ht_size > cbuf_ht_seg_max_size) {
2701
413k
        pht_buff->pbuff = gs_alloc_bytes(mem, ht_size, "read_alloc_ht_buff");
2702
413k
        if (pht_buff->pbuff == 0)
2703
0
            return_error(gs_error_VMerror);
2704
413k
    }
2705
751k
    pht_buff->ht_size = ht_size;
2706
751k
    pht_buff->read_size = 0;
2707
751k
    pht_buff->pcurr = pht_buff->pbuff;
2708
751k
    return 0;
2709
751k
}
2710
2711
/* read a halftone segment; if it is the final segment, build the halftone */
2712
static int
2713
read_ht_segment(
2714
    ht_buff_t *                 pht_buff,
2715
    command_buf_t *             pcb,
2716
    gs_gstate *           pgs,
2717
    gx_device *                 dev,
2718
    gs_memory_t *               mem )
2719
1.16M
{
2720
1.16M
    const byte *                cbp = pcb->ptr;
2721
1.16M
    const byte *                pbuff = 0;
2722
1.16M
    uint                        ht_size = pht_buff->ht_size, seg_size;
2723
1.16M
    int                         code = 0;
2724
2725
    /* get the segment size; refill command buffer if necessary */
2726
1.16M
    enc_u_getw(seg_size, cbp);
2727
1.16M
    if (pcb->warn_limit - cbp < (int)seg_size) { /* cbp can be past warn_limit */
2728
422k
        code = top_up_cbuf(pcb, &cbp);
2729
422k
        if (code < 0)
2730
0
            return code;
2731
422k
        if (pcb->end - cbp < (int)seg_size) {
2732
0
            emprintf(mem, " *** ht segment size doesn't fit in buffer ***\n");
2733
0
            return_error(gs_error_unknownerror);
2734
0
        }
2735
422k
    }
2736
2737
1.16M
    if (pht_buff->pbuff == 0) {
2738
        /* if not separate buffer, must be only one segment */
2739
338k
        if (seg_size != ht_size)
2740
0
            return_error(gs_error_unknownerror);
2741
338k
        pbuff = cbp;
2742
830k
    } else {
2743
830k
        if (seg_size + pht_buff->read_size > pht_buff->ht_size)
2744
0
            return_error(gs_error_unknownerror);
2745
830k
        memcpy(pht_buff->pcurr, cbp, seg_size);
2746
830k
        pht_buff->pcurr += seg_size;
2747
830k
        if ((pht_buff->read_size += seg_size) == ht_size)
2748
413k
            pbuff = pht_buff->pbuff;
2749
830k
    }
2750
2751
    /* if everything has been read, convert back to a halftone */
2752
1.16M
    if (pbuff != 0) {
2753
751k
        code = gx_ht_read_and_install(pgs, dev, pbuff, ht_size, mem);
2754
2755
        /* release any buffered information */
2756
751k
        if (pht_buff->pbuff != 0) {
2757
413k
            gs_free_object(mem, pht_buff->pbuff, "read_alloc_ht_buff");
2758
413k
            pht_buff->pbuff = 0;
2759
413k
            pht_buff->pcurr = 0;
2760
413k
        }
2761
751k
        pht_buff->ht_size = 0;
2762
751k
        pht_buff->read_size = 0;
2763
751k
    }
2764
2765
    /* update the command buffer ponter */
2766
1.16M
    pcb->ptr = cbp + seg_size;
2767
2768
1.16M
    return code;
2769
1.16M
}
2770
2771
static int
2772
read_set_misc2(command_buf_t *pcb, gs_gstate *pgs, segment_notes *pnotes)
2773
1.32M
{
2774
1.32M
    const byte *cbp = pcb->ptr;
2775
1.32M
    uint mask, cb;
2776
2777
1.32M
    if_debug0m('L', pgs->memory, "\n");
2778
1.32M
    cmd_getw(mask, cbp);
2779
1.32M
    if (mask & cap_join_known) {
2780
201k
        cb = *cbp++;
2781
201k
        pgs->line_params.start_cap = (gs_line_cap)((cb >> 3) & 7);
2782
201k
        pgs->line_params.join = (gs_line_join)(cb & 7);
2783
201k
        if_debug2m('L', pgs->memory, "[L]      start_cap=%d join=%d\n",
2784
201k
                   pgs->line_params.start_cap, pgs->line_params.join);
2785
201k
        cb = *cbp++;
2786
201k
        pgs->line_params.end_cap = (gs_line_cap)((cb >> 3) & 7);
2787
201k
        pgs->line_params.dash_cap = (gs_line_cap)(cb & 7);
2788
201k
        if_debug2m('L', pgs->memory, "[L]      end_cap=%d dash_cap=%d\n",
2789
201k
                   pgs->line_params.end_cap, pgs->line_params.dash_cap);
2790
201k
    }
2791
1.32M
    if (mask & cj_ac_sa_known) {
2792
88.0k
        cb = *cbp++;
2793
88.0k
        pgs->line_params.curve_join = ((cb >> 2) & 7) - 1;
2794
88.0k
        pgs->accurate_curves = (cb & 2) != 0;
2795
88.0k
        pgs->stroke_adjust = cb & 1;
2796
88.0k
        if_debug3m('L', pgs->memory, "[L]      CJ=%d AC=%d SA=%d\n",
2797
88.0k
                   pgs->line_params.curve_join, pgs->accurate_curves,
2798
88.0k
                   pgs->stroke_adjust);
2799
88.0k
    }
2800
1.32M
    if (mask & flatness_known) {
2801
97.3k
        cmd_get_value(pgs->flatness, cbp);
2802
97.3k
        if_debug1m('L', pgs->memory, "[L]      flatness=%g\n", pgs->flatness);
2803
97.3k
    }
2804
1.32M
    if (mask & line_width_known) {
2805
548k
        float width;
2806
2807
548k
        cmd_get_value(width, cbp);
2808
548k
        if_debug1m('L', pgs->memory, "[L]      line_width=%g\n", width);
2809
548k
        gx_set_line_width(&pgs->line_params, width);
2810
548k
    }
2811
1.32M
    if (mask & miter_limit_known) {
2812
17.2k
        float limit;
2813
2814
17.2k
        cmd_get_value(limit, cbp);
2815
17.2k
        if_debug1m('L', pgs->memory, "[L]      miter_limit=%g\n", limit);
2816
17.2k
        gx_set_miter_limit(&pgs->line_params, limit);
2817
17.2k
    }
2818
1.32M
    if (mask & op_bm_tk_known) {
2819
814k
        cb = *cbp++;
2820
814k
        pgs->blend_mode = cb >> 3;
2821
814k
        pgs->text_knockout = cb & 1;
2822
        /* the following usually have no effect; see gxclpath.c */
2823
814k
        cb = *cbp++;
2824
814k
        pgs->overprint_mode = (cb >> 2) & 1;
2825
814k
        pgs->stroke_overprint = (cb >> 1) & 1;
2826
814k
        pgs->overprint = cb & 1;
2827
814k
        cb = *cbp++;
2828
814k
        pgs->renderingintent = cb;
2829
814k
        if_debug6m('L', pgs->memory, "[L]      BM=%d TK=%d OPM=%d OP=%d op=%d RI=%d\n",
2830
814k
                   pgs->blend_mode, pgs->text_knockout, pgs->overprint_mode,
2831
814k
                   pgs->stroke_overprint, pgs->overprint, pgs->renderingintent);
2832
814k
    }
2833
1.32M
    if (mask & segment_notes_known) {
2834
734
        cb = *cbp++;
2835
734
        *pnotes = (segment_notes)(cb & 0x3f);
2836
734
        if_debug1m('L', pgs->memory, "[L]      notes=%d\n", *pnotes);
2837
734
    }
2838
1.32M
    if (mask & ais_known) {
2839
51.0k
        cmd_get_value(pgs->alphaisshape, cbp);
2840
51.0k
        if_debug1m('L', pgs->memory, "[L]      alphaisshape=%d\n", pgs->alphaisshape);
2841
51.0k
    }
2842
1.32M
    if (mask & stroke_alpha_known) {
2843
187k
        cmd_get_value(pgs->strokeconstantalpha, cbp);
2844
187k
        if_debug1m('L', pgs->memory, "[L]      strokeconstantalpha=%g\n", pgs->strokeconstantalpha);
2845
187k
    }
2846
1.32M
    if (mask & fill_alpha_known) {
2847
220k
        cmd_get_value(pgs->fillconstantalpha, cbp);
2848
220k
        if_debug1m('L', pgs->memory, "[L]      fillconstantalpha=%u\n", (uint)(pgs->fillconstantalpha));
2849
220k
    }
2850
1.32M
    pcb->ptr = cbp;
2851
1.32M
    return 0;
2852
1.32M
}
2853
2854
static int
2855
read_set_color_space(command_buf_t *pcb, gs_gstate *pgs,
2856
                     gx_device_clist_reader *cdev, gs_memory_t *mem)
2857
295k
{
2858
295k
    const byte *cbp = pcb->ptr;
2859
295k
    byte b = *cbp++;
2860
295k
    int index = b >> 4;
2861
295k
    gs_color_space *pcs;
2862
295k
    int code = 0;
2863
295k
    cmm_profile_t *picc_profile;
2864
295k
    clist_icc_color_t icc_information;
2865
2866
295k
    if_debug3m('L', mem, " %d%s%s\n", index,
2867
295k
               (b & 8 ? " (indexed)" : ""),
2868
295k
               (b & 4 ? "(proc)" : ""));
2869
    /* They all store the ICC information.  Even if it is NULL
2870
       it is used in the ICC case to avoid reading from the
2871
       serialized profile data which is stored elsewhere in the
2872
       clist.  Hence we avoid jumping around in the file. */
2873
295k
    memcpy(&icc_information, cbp, sizeof(clist_icc_color_t));
2874
295k
    cbp = cbp + sizeof(clist_icc_color_t);
2875
295k
    switch (index) {
2876
0
    case gs_color_space_index_DeviceGray:
2877
0
        pcs = gs_cspace_new_DeviceGray(mem);
2878
0
        break;
2879
0
    case gs_color_space_index_DeviceRGB:
2880
0
        pcs = gs_cspace_new_DeviceRGB(mem);
2881
0
        break;
2882
0
    case gs_color_space_index_DeviceCMYK:
2883
0
        pcs = gs_cspace_new_DeviceCMYK(mem);
2884
0
        break;
2885
295k
    case gs_color_space_index_ICC:
2886
        /* build the color space object */
2887
295k
        code = gs_cspace_build_ICC(&pcs, NULL, mem);
2888
        /* Don't bother getting the ICC stuff from the clist yet */
2889
295k
        picc_profile = gsicc_profile_new(NULL, cdev->memory, NULL, 0);
2890
295k
        if (picc_profile == NULL)
2891
0
            return gs_rethrow(-1, "Failed to find ICC profile during clist read");
2892
295k
        picc_profile->num_comps = icc_information.icc_num_components;
2893
295k
        picc_profile->hashcode = icc_information.icc_hash;
2894
295k
        picc_profile->hash_is_valid = true;
2895
295k
        picc_profile->islab = icc_information.is_lab;
2896
295k
        picc_profile->default_match = icc_information.default_match;
2897
295k
        picc_profile->data_cs = icc_information.data_cs;
2898
        /* Store the clist reader address in the profile
2899
           structure so that we can get to the buffer
2900
           data if we really neeed it.  Ideally, we
2901
           will use a cached link and only access this once. */
2902
295k
        picc_profile->dev = (gx_device*) cdev;
2903
        /* Assign it to the colorspace */
2904
295k
        code = gsicc_set_gscs_profile(pcs, picc_profile, mem);
2905
        /* And we no longer need our reference to the profile */
2906
295k
        gsicc_adjust_profile_rc(picc_profile, -1, "read_set_color_space");
2907
295k
        break;
2908
0
    default:
2909
0
        code = gs_note_error(gs_error_rangecheck);      /* others are NYI */
2910
0
        goto out;
2911
295k
    }
2912
2913
295k
    if (pcs == NULL) {
2914
0
        code = gs_note_error(gs_error_VMerror);
2915
0
        goto out;
2916
0
    }
2917
2918
295k
    if (b & 8) {
2919
13.4k
        bool use_proc = (b & 4) != 0;
2920
13.4k
        int hival;
2921
13.4k
        int num_values;
2922
13.4k
        byte *data;
2923
13.4k
        uint data_size;
2924
13.4k
        gs_color_space *pcs_indexed;
2925
2926
13.4k
        pcs_indexed = gs_cspace_alloc(mem, &gs_color_space_type_Indexed);
2927
13.4k
        if (pcs_indexed == 0) {
2928
0
            rc_decrement_cs(pcs, "read_set_color_space");
2929
0
            code = gs_note_error(gs_error_VMerror);
2930
0
            goto out;
2931
0
        }
2932
13.4k
        pcs_indexed->base_space = pcs;
2933
13.4k
        pcs = pcs_indexed;
2934
13.4k
        pcs->params.indexed.use_proc = 0;
2935
13.4k
        pcs->params.indexed.lookup.table.data = 0;
2936
13.4k
        pcs->params.indexed.lookup.table.size = 0;
2937
13.4k
        cmd_getw(hival, cbp);
2938
13.4k
        pcs->params.indexed.n_comps = gs_color_space_num_components(pcs->base_space);
2939
13.4k
        num_values = (hival + 1) * pcs->params.indexed.n_comps;
2940
13.4k
        if (use_proc) {
2941
0
            gs_indexed_map *map;
2942
2943
0
            code = alloc_indexed_map(&map, num_values, mem, "indexed map");
2944
0
            if (code < 0) {
2945
0
                rc_decrement_cs(pcs, "read_set_color_space");
2946
0
                goto out;
2947
0
            }
2948
0
            map->proc.lookup_index = lookup_indexed_map;
2949
0
            pcs->params.indexed.lookup.map = map;
2950
0
            data = (byte *)map->values;
2951
0
            data_size = num_values * sizeof(map->values[0]);
2952
13.4k
        } else {
2953
13.4k
            byte *table = gs_alloc_string(mem, num_values, "color_space indexed table");
2954
2955
13.4k
            if (table == 0) {
2956
0
                code = gs_note_error(gs_error_VMerror);
2957
0
                rc_decrement_cs(pcs, "read_set_color_space");
2958
0
                goto out;
2959
0
            }
2960
13.4k
            pcs->params.indexed.lookup.table.data = table;
2961
13.4k
            pcs->params.indexed.lookup.table.size = num_values;
2962
13.4k
            data = table;
2963
13.4k
            data_size = num_values;
2964
13.4k
        }
2965
13.4k
        cbp = cmd_read_data(pcb, data, data_size, cbp);
2966
13.4k
        pcs->params.indexed.hival = hival;
2967
13.4k
        pcs->params.indexed.use_proc = use_proc;
2968
13.4k
    }
2969
2970
    /* Release reference to old color space before installing new one. */
2971
295k
    if (pgs->color[0].color_space != NULL)
2972
295k
        rc_decrement_only_cs(pgs->color[0].color_space, "read_set_color_space");
2973
295k
    pgs->color[0].color_space = pcs;
2974
295k
out:
2975
295k
    pcb->ptr = cbp;
2976
295k
    return code;
2977
295k
}
2978
2979
static int
2980
read_begin_image(command_buf_t *pcb, gs_image_common_t *pic,
2981
                 gs_color_space *pcs)
2982
397k
{
2983
397k
    uint index = *(pcb->ptr)++;
2984
397k
    const gx_image_type_t *image_type = gx_image_type_table[index];
2985
397k
    stream s;
2986
397k
    int code;
2987
2988
    /* This is sloppy, but we don't have enough information to do better. */
2989
397k
    code = top_up_cbuf(pcb, &pcb->ptr);
2990
397k
    if (code < 0)
2991
0
        return code;
2992
397k
    s_init(&s, NULL);
2993
397k
    sread_string(&s, pcb->ptr, pcb->end - pcb->ptr);
2994
397k
    code = image_type->sget(pic, &s, pcs);
2995
397k
    pcb->ptr = sbufptr(&s);
2996
397k
    pic->imagematrices_are_untrustworthy = 0;
2997
397k
    return code;
2998
397k
}
2999
3000
static int
3001
read_put_params(command_buf_t *pcb, gs_gstate *pgs,
3002
                gx_device_clist_reader *cdev, gs_memory_t *mem)
3003
0
{
3004
0
    const byte *cbp = pcb->ptr;
3005
0
    gs_c_param_list param_list;
3006
0
    uint cleft;
3007
0
    uint rleft;
3008
0
    bool alloc_data_on_heap = false;
3009
0
    byte *param_buf;
3010
0
    uint param_length;
3011
0
    int code;
3012
3013
0
    cmd_get_value(param_length, cbp);
3014
0
    if_debug1m('L', mem, " length=%d\n", param_length);
3015
0
    if (param_length == 0) {
3016
0
        code = 1;               /* empty list */
3017
0
        goto out;
3018
0
    }
3019
3020
    /* Make sure entire serialized param list is in cbuf */
3021
    /* + force void* alignment */
3022
0
    code = top_up_cbuf(pcb, &cbp);
3023
0
    if (code < 0)
3024
0
        return code;
3025
0
    if (pcb->end - cbp >= param_length) {
3026
0
        param_buf = (byte *)cbp;
3027
0
        cbp += param_length;
3028
0
    } else {
3029
        /* NOTE: param_buf must be maximally aligned */
3030
0
        param_buf = gs_alloc_bytes(mem, param_length,
3031
0
                                   "clist put_params");
3032
0
        if (param_buf == 0) {
3033
0
            code = gs_note_error(gs_error_VMerror);
3034
0
            goto out;
3035
0
        }
3036
0
        alloc_data_on_heap = true;
3037
0
        cleft = pcb->end - cbp;
3038
0
        rleft = param_length - cleft;
3039
0
        memmove(param_buf, cbp, cleft);
3040
0
        next_is_skip(pcb);
3041
0
        pcb->end_status = sgets(pcb->s, param_buf + cleft, rleft, &rleft);
3042
0
        cbp = pcb->end;  /* force refill */
3043
0
    }
3044
3045
    /*
3046
     * Create a gs_c_param_list & expand into it.
3047
     * NB that gs_c_param_list doesn't copy objects into
3048
     * it, but rather keeps *pointers* to what's passed.
3049
     * That's OK because the serialized format keeps enough
3050
     * space to hold expanded versions of the structures,
3051
     * but this means we cannot deallocate source buffer
3052
     * until the gs_c_param_list is deleted.
3053
     */
3054
0
    gs_c_param_list_write(&param_list, mem);
3055
0
    code = gs_param_list_unserialize
3056
0
        ( (gs_param_list *)&param_list, param_buf );
3057
0
    if (code >= 0 && code != param_length)
3058
0
        code = gs_error_unknownerror;  /* must match */
3059
0
    if (code >= 0) {
3060
0
        gs_c_param_list_read(&param_list);
3061
0
        code = gs_gstate_putdeviceparams(pgs, (gx_device *)cdev,
3062
0
                                         (gs_param_list *)&param_list);
3063
0
    }
3064
0
    gs_c_param_list_release(&param_list);
3065
0
    if (alloc_data_on_heap)
3066
0
        gs_free_object(mem, param_buf, "clist put_params");
3067
3068
0
out:
3069
0
    pcb->ptr = cbp;
3070
0
    return code;
3071
0
}
3072
3073
/*
3074
 * Read a "composite" command, and execute the command.
3075
 *
3076
 * This code assumes that a the largest create compositor command,
3077
 * including the compositor name size, is smaller than the data buffer
3078
 * size. This assumption is inherent in the basic design of the coding
3079
 * and the de-serializer interface, as no length field is provided.
3080
 *
3081
 * At the time of this writing, no compositor violates this assumption.
3082
 * The largest composite is currently 1275 bytes, while the command
3083
 * data buffer is 4096 bytes.
3084
 *
3085
 * In the event that this assumption is violated, a change in the encoding
3086
 * would be called for.
3087
 *
3088
 * See comment in gdevp14.c c_pdf14trans_read PDF14_BEGIN_TRANS_MASK case.
3089
 */
3090
extern_gs_find_compositor();
3091
3092
static int
3093
read_composite(
3094
    command_buf_t *pcb,  gs_memory_t *mem, gs_composite_t **ppcomp)
3095
128M
{
3096
128M
    const byte *                cbp = pcb->ptr;
3097
128M
    int                         comp_id = 0, code = 0;
3098
128M
    const gs_composite_type_t * pcomp_type = 0;
3099
3100
    /* fill the command buffer (see comment above) */
3101
128M
    if (pcb->end - cbp < MAX_CLIST_COMPOSITOR_SIZE + sizeof(comp_id)) {
3102
8.79M
        code = top_up_cbuf(pcb, &cbp);
3103
8.79M
        if (code < 0)
3104
0
            return code;
3105
8.79M
    }
3106
3107
    /* find the appropriate compositor method vector */
3108
128M
    comp_id = *cbp++;
3109
128M
    if ((pcomp_type = gs_find_compositor(comp_id)) == 0)
3110
0
        return_error(gs_error_unknownerror);
3111
3112
    /* de-serialize the compositor */
3113
128M
    code = pcomp_type->procs.read(ppcomp, cbp, pcb->end - cbp, mem);
3114
3115
    /* If we read more than the maximum expected, return a rangecheck error */
3116
128M
    if ( code > MAX_CLIST_COMPOSITOR_SIZE )
3117
0
        return_error(gs_error_rangecheck);
3118
3119
128M
    if (code > 0)
3120
128M
        cbp += code;
3121
128M
    pcb->ptr = cbp;
3122
128M
    return code;
3123
128M
}
3124
3125
static int apply_composite(gx_device_clist_reader *cdev, gs_gstate *pgs,
3126
                                   gs_memory_t *mem, gs_composite_t *pcomp,
3127
                                   int x0, int y0, gx_device **ptarget)
3128
114M
{
3129
114M
    gx_device *tdev = *ptarget;
3130
114M
    int code;
3131
3132
114M
    code = pcomp->type->procs.adjust_ctm(pcomp, x0, y0, pgs);
3133
114M
    if (code < 0)
3134
0
        goto exit;
3135
    /*
3136
     * Apply the compositor to the target device; note that this may
3137
     * change the target device.
3138
     */
3139
114M
    code = dev_proc(tdev, composite)(tdev, &tdev, pcomp, pgs, mem, (gx_device*) cdev);
3140
114M
    if (code == 1) {
3141
        /* A new compositor was created that wrapped tdev. This should
3142
         * be our new target. */
3143
948k
        *ptarget = tdev;
3144
948k
        code = 0;
3145
948k
    }
3146
114M
    if (code < 0)
3147
14
        goto exit;
3148
3149
    /* Perform any updates for the clist device required */
3150
114M
    code = pcomp->type->procs.clist_compositor_read_update(pcomp,
3151
114M
                                        (gx_device *)cdev, tdev, pgs, mem);
3152
114M
exit:
3153
    /* free the compositor object */
3154
114M
    gs_free_object(mem, pcomp, "read_composite");
3155
3156
114M
    return code;
3157
114M
}
3158
3159
/* ---------------- Utilities ---------------- */
3160
3161
/* Read and unpack a short bitmap */
3162
/*
3163
 * The 'raster' in the dest buffer may be larger than the 'width_bytes'
3164
 * in the src, so after reading we memmove data down to the proper
3165
 * alignment from the last line backwards.
3166
 * THIS RELIES on width_bytes <= raster to work.
3167
 */
3168
static const byte *
3169
cmd_read_short_bits(command_buf_t *pcb, byte *data, int tot_bytes,
3170
                    int width_bytes, int height, uint raster, const byte *cbp)
3171
5.93M
{
3172
    /* Note the following may read from the file past the end of the buffer */
3173
    /* leaving cbp at pcb->end. No further reading using cbp can be done    */
3174
    /* without top_up_cbuf to reload the buffer.                            */
3175
5.93M
    cbp = cmd_read_data(pcb, data, tot_bytes, cbp);
3176
3177
    /* if needed, adjust buffer contents for dest raster > width_bytes */
3178
5.93M
    if (width_bytes < raster) {
3179
5.93M
        const byte *pdata = data /*src*/ + width_bytes * height;
3180
5.93M
        byte *udata = data /*dest*/ + height * raster;
3181
3182
95.9M
        while (--height > 0) { /* don't need to move the first line to itself */
3183
90.0M
            udata -= raster, pdata -= width_bytes;
3184
90.0M
            switch (width_bytes) {
3185
0
                default:
3186
0
                    memmove(udata, pdata, width_bytes);
3187
0
                    break;
3188
350k
                case 6:
3189
350k
                    udata[5] = pdata[5];
3190
1.06M
                case 5:
3191
1.06M
                    udata[4] = pdata[4];
3192
3.56M
                case 4:
3193
3.56M
                    udata[3] = pdata[3];
3194
18.7M
                case 3:
3195
18.7M
                    udata[2] = pdata[2];
3196
72.1M
                case 2:
3197
72.1M
                    udata[1] = pdata[1];
3198
90.0M
                case 1:
3199
90.0M
                    udata[0] = pdata[0];
3200
90.0M
                case 0:;            /* shouldn't happen */
3201
90.0M
            }
3202
90.0M
        }
3203
5.93M
    }
3204
5.93M
    return cbp;
3205
5.93M
}
3206
3207
/* Read a rectangle. */
3208
static const byte *
3209
cmd_read_rect(int op, gx_cmd_rect * prect, const byte * cbp)
3210
13.5M
{
3211
13.5M
    cmd_getw(prect->x, cbp);
3212
13.5M
    if (op & 0xf)
3213
695k
        prect->y += ((op >> 2) & 3) - 2;
3214
12.8M
    else {
3215
12.8M
        cmd_getw(prect->y, cbp);
3216
12.8M
    }
3217
13.5M
    cmd_getw(prect->width, cbp);
3218
13.5M
    if (op & 0xf)
3219
695k
        prect->height += (op & 3) - 2;
3220
12.8M
    else {
3221
12.8M
        cmd_getw(prect->height, cbp);
3222
12.8M
    }
3223
13.5M
    return cbp;
3224
13.5M
}
3225
3226
/*
3227
 * Select a map for loading with data.
3228
 *
3229
 * This routine has three outputs:
3230
 *   *pmdata - points to the map data.
3231
 *   *pcomp_num - points to a component number if the map is a transfer
3232
 *               map which has been set via the setcolortransfer operator.
3233
 *               A. value of NULL indicates that no component number is to
3234
 *               be sent for this map.
3235
 *   *pcount - the size of the map (in bytes).
3236
 */
3237
static int
3238
cmd_select_map(cmd_map_index map_index, cmd_map_contents cont,
3239
               gs_gstate * pgs, int ** pcomp_num, frac ** pmdata,
3240
               uint * pcount, gs_memory_t * mem)
3241
4.58M
{
3242
4.58M
    gx_transfer_map *map;
3243
4.58M
    gx_transfer_map **pmap;
3244
4.58M
    const char *cname;
3245
3246
4.58M
    *pcomp_num = NULL;          /* Only used for color transfer maps */
3247
4.58M
    switch (map_index) {
3248
1.52M
        case cmd_map_transfer:
3249
1.52M
            if_debug0m('L', mem, " transfer");
3250
1.52M
            rc_unshare_struct(pgs->set_transfer.gray, gx_transfer_map,
3251
1.52M
                &st_transfer_map, mem, return_error(gs_error_VMerror),
3252
1.52M
                "cmd_select_map(default_transfer)");
3253
1.52M
            map = pgs->set_transfer.gray;
3254
            /* Release all current maps */
3255
1.52M
            rc_decrement(pgs->set_transfer.red, "cmd_select_map(red)");
3256
1.52M
            pgs->set_transfer.red = NULL;
3257
1.52M
            pgs->set_transfer.red_component_num = -1;
3258
1.52M
            rc_decrement(pgs->set_transfer.green, "cmd_select_map(green)");
3259
1.52M
            pgs->set_transfer.green = NULL;
3260
1.52M
            pgs->set_transfer.green_component_num = -1;
3261
1.52M
            rc_decrement(pgs->set_transfer.blue, "cmd_select_map(blue)");
3262
1.52M
            pgs->set_transfer.blue = NULL;
3263
1.52M
            pgs->set_transfer.blue_component_num = -1;
3264
1.52M
            goto transfer2;
3265
213
        case cmd_map_transfer_0:
3266
213
            pmap = &pgs->set_transfer.red;
3267
213
            *pcomp_num = &pgs->set_transfer.red_component_num;
3268
213
            goto transfer1;
3269
213
        case cmd_map_transfer_1:
3270
213
            pmap = &pgs->set_transfer.green;
3271
213
            *pcomp_num = &pgs->set_transfer.green_component_num;
3272
213
            goto transfer1;
3273
213
        case cmd_map_transfer_2:
3274
213
            pmap = &pgs->set_transfer.blue;
3275
213
            *pcomp_num = &pgs->set_transfer.blue_component_num;
3276
213
            goto transfer1;
3277
0
        case cmd_map_transfer_3:
3278
0
            pmap = &pgs->set_transfer.gray;
3279
0
            *pcomp_num = &pgs->set_transfer.gray_component_num;
3280
639
transfer1:  if_debug1m('L', mem, " transfer[%d]", (int)(map_index - cmd_map_transfer_0));
3281
639
            rc_unshare_struct(*pmap, gx_transfer_map, &st_transfer_map, mem,
3282
639
                return_error(gs_error_VMerror), "cmd_select_map(transfer)");
3283
639
            map = *pmap;
3284
3285
1.52M
transfer2:  if (cont != cmd_map_other) {
3286
876k
                gx_set_identity_transfer(map);
3287
876k
                *pmdata = 0;
3288
876k
                *pcount = 0;
3289
876k
                return 0;
3290
876k
            }
3291
651k
            break;
3292
1.52M
        case cmd_map_black_generation:
3293
1.52M
            if_debug0m('L', mem, " black generation");
3294
1.52M
            pmap = &pgs->black_generation;
3295
1.52M
            cname = "cmd_select_map(black generation)";
3296
1.52M
            goto alloc;
3297
1.52M
        case cmd_map_undercolor_removal:
3298
1.52M
            if_debug0m('L', mem, " undercolor removal");
3299
1.52M
            pmap = &pgs->undercolor_removal;
3300
1.52M
            cname = "cmd_select_map(undercolor removal)";
3301
3.05M
alloc:      if (cont == cmd_map_none) {
3302
0
                rc_decrement(*pmap, cname);
3303
0
                *pmap = 0;
3304
0
                *pmdata = 0;
3305
0
                *pcount = 0;
3306
0
                return 0;
3307
0
            }
3308
3.05M
            rc_unshare_struct(*pmap, gx_transfer_map, &st_transfer_map,
3309
3.05M
                              mem, return_error(gs_error_VMerror), cname);
3310
3.05M
            map = *pmap;
3311
3.05M
            if (cont == cmd_map_identity) {
3312
0
                gx_set_identity_transfer(map);
3313
0
                *pmdata = 0;
3314
0
                *pcount = 0;
3315
0
                return 0;
3316
0
            }
3317
3.05M
            break;
3318
3.05M
        default:
3319
0
            *pmdata = 0;
3320
0
            return 0;
3321
4.58M
    }
3322
3.70M
    map->proc = gs_mapped_transfer;
3323
3.70M
    *pmdata = map->values;
3324
3.70M
    *pcount = sizeof(map->values);
3325
3.70M
    return 0;
3326
4.58M
}
3327
3328
/* Create a device halftone for the imager if necessary. */
3329
static int
3330
cmd_create_dev_ht(gx_device_halftone **ppdht, gs_memory_t *mem)
3331
0
{
3332
0
    gx_device_halftone *pdht = *ppdht;
3333
3334
0
    if (pdht == 0) {
3335
0
        rc_header rc;
3336
3337
0
        rc_alloc_struct_1(pdht, gx_device_halftone, &st_device_halftone, mem,
3338
0
                          return_error(gs_error_VMerror),
3339
0
                          "cmd_create_dev_ht");
3340
0
        rc = pdht->rc;
3341
0
        memset(pdht, 0, sizeof(*pdht));
3342
0
        pdht->rc = rc;
3343
0
        *ppdht = pdht;
3344
0
    }
3345
0
    return 0;
3346
0
}
3347
3348
/* Resize the halftone components array if necessary. */
3349
static int
3350
cmd_resize_halftone(gx_device_halftone **ppdht, uint num_comp,
3351
                    gs_memory_t * mem)
3352
0
{
3353
0
    int code = cmd_create_dev_ht(ppdht, mem);
3354
0
    gx_device_halftone *pdht = *ppdht;
3355
3356
0
    if (code < 0)
3357
0
        return code;
3358
0
    if (num_comp != pdht->num_comp) {
3359
0
        gx_ht_order_component *pcomp;
3360
3361
        /*
3362
         * We must be careful not to shrink or free the components array
3363
         * before releasing any relevant elements.
3364
         */
3365
0
        if (num_comp < pdht->num_comp) {
3366
0
            uint i;
3367
3368
            /* Don't release the default order. */
3369
0
            for (i = pdht->num_comp; i-- > num_comp;)
3370
0
                if (pdht->components[i].corder.bit_data != pdht->order.bit_data)
3371
0
                    gx_ht_order_release(&pdht->components[i].corder, mem, true);
3372
0
            if (num_comp == 0) {
3373
0
                gs_free_object(mem, pdht->components, "cmd_resize_halftone");
3374
0
                pcomp = 0;
3375
0
            } else {
3376
0
                pcomp = gs_resize_object(mem, pdht->components, num_comp,
3377
0
                                         "cmd_resize_halftone");
3378
0
                if (pcomp == 0) {
3379
0
                    pdht->num_comp = num_comp;  /* attempt consistency */
3380
0
                    return_error(gs_error_VMerror);
3381
0
                }
3382
0
            }
3383
0
        } else {
3384
            /* num_comp > pdht->num_comp */
3385
0
            if (pdht->num_comp == 0)
3386
0
                pcomp = gs_alloc_struct_array(mem, num_comp,
3387
0
                                              gx_ht_order_component,
3388
0
                                              &st_ht_order_component_element,
3389
0
                                              "cmd_resize_halftone");
3390
0
            else
3391
0
                pcomp = gs_resize_object(mem, pdht->components, num_comp,
3392
0
                                         "cmd_resize_halftone");
3393
0
            if (pcomp == 0)
3394
0
                return_error(gs_error_VMerror);
3395
0
            memset(&pcomp[pdht->num_comp], 0,
3396
0
                   sizeof(*pcomp) * (num_comp - pdht->num_comp));
3397
0
        }
3398
0
        pdht->num_comp = num_comp;
3399
0
        pdht->components = pcomp;
3400
0
    }
3401
0
    return 0;
3402
0
}
3403
3404
/* ------ Path operations ------ */
3405
3406
/* Decode a path segment. */
3407
static int
3408
clist_decode_segment(gx_path * ppath, int op, fixed vs[6],
3409
                 gs_fixed_point * ppos, int x0, int y0, segment_notes notes)
3410
44.9M
{
3411
44.9M
    fixed px = ppos->x - int2fixed(x0);
3412
44.9M
    fixed py = ppos->y - int2fixed(y0);
3413
44.9M
    int code;
3414
3415
58.6M
#define A vs[0]
3416
44.9M
#define B vs[1]
3417
44.9M
#define C vs[2]
3418
44.9M
#define D vs[3]
3419
44.9M
#define E vs[4]
3420
44.9M
#define F vs[5]
3421
3422
44.9M
    switch (op) {
3423
6.92M
        case cmd_opv_rmoveto:
3424
6.92M
            code = gx_path_add_point(ppath, px += A, py += B);
3425
6.92M
            break;
3426
4.86M
        case cmd_opv_rlineto:
3427
4.86M
            code = gx_path_add_line_notes(ppath, px += A, py += B, notes);
3428
4.86M
            break;
3429
0
        case cmd_opv_rgapto:
3430
0
            code = gx_path_add_gap_notes(ppath, px += A, py += B, notes);
3431
0
            break;
3432
6.74M
        case cmd_opv_hlineto:
3433
6.74M
            code = gx_path_add_line_notes(ppath, px += A, py, notes);
3434
6.74M
            break;
3435
9.28M
        case cmd_opv_vlineto:
3436
9.28M
            code = gx_path_add_line_notes(ppath, px, py += A, notes);
3437
9.28M
            break;
3438
1.53M
        case cmd_opv_rmlineto:
3439
1.53M
            if ((code = gx_path_add_point(ppath, px += A, py += B)) < 0)
3440
0
                break;
3441
1.53M
            code = gx_path_add_line_notes(ppath, px += C, py += D, notes);
3442
1.53M
            break;
3443
609k
        case cmd_opv_rm2lineto:
3444
609k
            if ((code = gx_path_add_point(ppath, px += A, py += B)) < 0 ||
3445
609k
                (code = gx_path_add_line_notes(ppath, px += C, py += D,
3446
609k
                                               notes)) < 0
3447
609k
                )
3448
0
                break;
3449
609k
            code = gx_path_add_line_notes(ppath, px += E, py += F, notes);
3450
609k
            break;
3451
238k
        case cmd_opv_rm3lineto:
3452
238k
            if ((code = gx_path_add_point(ppath, px += A, py += B)) < 0 ||
3453
238k
                (code = gx_path_add_line_notes(ppath, px += C, py += D,
3454
238k
                                               notes)) < 0 ||
3455
238k
                (code = gx_path_add_line_notes(ppath, px += E, py += F,
3456
238k
                                               notes)) < 0
3457
238k
                )
3458
0
                break;
3459
238k
            code = gx_path_add_line_notes(ppath, px -= C, py -= D, notes);
3460
238k
            break;
3461
9.05M
        case cmd_opv_rrcurveto: /* a b c d e f => a b a+c b+d a+c+e b+d+f */
3462
9.10M
rrc:        E += (C += A);
3463
9.10M
            F += (D += B);
3464
11.2M
curve:      code = gx_path_add_curve_notes(ppath, px + A, py + B,
3465
11.2M
                                           px + C, py + D,
3466
11.2M
                                           px + E, py + F, notes);
3467
11.2M
            px += E, py += F;
3468
11.2M
            break;
3469
912k
        case cmd_opv_hvcurveto: /* a b c d => a 0 a+b c a+b c+d */
3470
934k
hvc:        F = C + D, D = C, E = C = A + B, B = 0;
3471
934k
            goto curve;
3472
920k
        case cmd_opv_vhcurveto: /* a b c d => 0 a b a+c b+d a+c */
3473
965k
vhc:        E = B + D, F = D = A + C, C = B, B = A, A = 0;
3474
965k
            goto curve;
3475
101k
        case cmd_opv_nrcurveto: /* a b c d => 0 0 a b a+c b+d */
3476
101k
            F = B + D, E = A + C, D = B, C = A, B = A = 0;
3477
101k
            goto curve;
3478
129k
        case cmd_opv_rncurveto: /* a b c d => a b a+c b+d a+c b+d */
3479
129k
            F = D += B, E = C += A;
3480
129k
            goto curve;
3481
44.5k
        case cmd_opv_vqcurveto: /* a b => VH a b TS(a,b) TS(b,a) */
3482
44.5k
            if ((A ^ B) < 0)
3483
14.2k
                C = -B, D = -A;
3484
30.3k
            else
3485
30.3k
                C = B, D = A;
3486
44.5k
            goto vhc;
3487
21.5k
        case cmd_opv_hqcurveto: /* a b => HV a TS(a,b) b TS(b,a) */
3488
21.5k
            if ((A ^ B) < 0)
3489
7.22k
                D = -A, C = B, B = -B;
3490
14.3k
            else
3491
14.3k
                D = A, C = B;
3492
21.5k
            goto hvc;
3493
45.3k
        case cmd_opv_scurveto: /* (a b c d e f) => */
3494
45.3k
            {
3495
45.3k
                fixed a = A, b = B;
3496
3497
                /* See gxclpath.h for details on the following. */
3498
45.3k
                if (A == 0) {
3499
                    /* Previous curve was vh or vv */
3500
41.5k
                    A = E - C, B = D - F, C = C - a, D = b - D, E = a, F = -b;
3501
41.5k
                } else {
3502
                    /* Previous curve was hv or hh */
3503
3.81k
                    A = C - E, B = F - D, C = a - C, D = D - b, E = -a, F = b;
3504
3.81k
                }
3505
45.3k
            }
3506
45.3k
            goto rrc;
3507
3.52M
        case cmd_opv_closepath:
3508
3.52M
            if ((code = gx_path_close_subpath(ppath)) < 0)
3509
3.52M
                return code;;
3510
3.52M
            if ((code = gx_path_current_point(ppath, (gs_fixed_point *) vs)) < 0)
3511
3.52M
                return code;;
3512
3.52M
            px = A, py = B;
3513
3.52M
            break;
3514
0
        default:
3515
0
            return_error(gs_error_rangecheck);
3516
44.9M
    }
3517
44.9M
#undef A
3518
44.9M
#undef B
3519
44.9M
#undef C
3520
44.9M
#undef D
3521
44.9M
#undef E
3522
44.9M
#undef F
3523
44.9M
    ppos->x = px + int2fixed(x0);
3524
44.9M
    ppos->y = py + int2fixed(y0);
3525
44.9M
    return code;
3526
44.9M
}
3527
3528
/*
3529
 * Execute a polyfill -- either a fill_parallelogram or a fill_triangle.
3530
 *
3531
 * Note that degenerate parallelograms or triangles may collapse into
3532
 * a single line or point.  We must check for this so we don't try to
3533
 * access non-existent segments.
3534
 */
3535
static int
3536
clist_do_polyfill(gx_device *dev, gx_path *ppath,
3537
                  const gx_drawing_color *pdcolor,
3538
                  gs_logical_operation_t lop)
3539
311k
{
3540
311k
    const subpath *psub = ppath->first_subpath;
3541
311k
    const segment *pseg1;
3542
311k
    const segment *pseg2;
3543
311k
    int code;
3544
3545
311k
    if (psub && (pseg1 = psub->next) != 0 && (pseg2 = pseg1->next) != 0) {
3546
311k
        fixed px = psub->pt.x, py = psub->pt.y;
3547
311k
        fixed ax = pseg1->pt.x - px, ay = pseg1->pt.y - py;
3548
311k
        fixed bx, by;
3549
        /*
3550
         * We take advantage of the fact that the parameter lists for
3551
         * fill_parallelogram and fill_triangle are identical.
3552
         */
3553
311k
        dev_proc_fill_parallelogram((*fill));
3554
3555
        /* close_path of 3 point triangle adds 4th point, detected here.*/
3556
        /* close_path on parallelogram adds 5th point also ignored. */
3557
311k
        if (pseg2->next && !(px == pseg2->next->pt.x && py == pseg2->next->pt.y)) {
3558
            /* Parallelogram */
3559
287k
            fill = dev_proc(dev, fill_parallelogram);
3560
287k
            bx = pseg2->pt.x - pseg1->pt.x;
3561
287k
            by = pseg2->pt.y - pseg1->pt.y;
3562
287k
        } else {
3563
            /* Triangle */
3564
24.1k
            fill = dev_proc(dev, fill_triangle);
3565
24.1k
            bx = pseg2->pt.x - px;
3566
24.1k
            by = pseg2->pt.y - py;
3567
24.1k
        }
3568
311k
        code = fill(dev, px, py, ax, ay, bx, by, pdcolor, lop);
3569
311k
    } else
3570
0
        code = 0;
3571
311k
    gx_path_new(ppath);
3572
311k
    return code;
3573
311k
}