Coverage Report

Created: 2025-08-28 07:06

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