Coverage Report

Created: 2025-11-16 07:40

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ghostpdl/pdf/pdf_gstate.c
Line
Count
Source
1
/* Copyright (C) 2001-2025 Artifex Software, Inc.
2
   All Rights Reserved.
3
4
   This software is provided AS-IS with no warranty, either express or
5
   implied.
6
7
   This software is distributed under license and may not be copied,
8
   modified or distributed except as expressly authorized under the terms
9
   of the license contained in the file LICENSE in this distribution.
10
11
   Refer to licensing information at http://www.artifex.com or contact
12
   Artifex Software, Inc.,  39 Mesa Street, Suite 108A, San Francisco,
13
   CA 94129, USA, for further information.
14
*/
15
16
/* Graphics state operations for the PDF interpreter */
17
18
#include "pdf_int.h"
19
#include "pdf_doc.h"
20
#include "pdf_font_types.h"
21
#include "pdf_gstate.h"
22
#include "pdf_stack.h"
23
#include "pdf_dict.h"
24
#include "pdf_array.h"
25
#include "pdf_func.h"
26
#include "pdf_file.h"
27
#include "pdf_misc.h"
28
#include "pdf_loop_detect.h"
29
#include "pdf_image.h"
30
#include "pdf_pattern.h"
31
#include "pdf_font.h"
32
#include "pdf_colour.h"
33
#include "pdf_trans.h"
34
35
#include "gsstate.h"        /* For gs_gstate */
36
#include "gsmatrix.h"
37
#include "gslparam.h"
38
#include "gstparam.h"
39
40
#include "gxdht.h"
41
#include "gxht.h"
42
#include "gzht.h"
43
#include "gsht.h"
44
#include "gscoord.h"        /* For gs_concat() */
45
#include "gsutil.h"         /* For gs_next_ids() */
46
#include "gscolor3.h"       /* For gs_setsmoothness() */
47
#include "gzpath.h"
48
#include "gspenum.h"
49
#include "gxdevsop.h"               /* For special ops */
50
51
static const char *blend_mode_names[] = {
52
    GS_BLEND_MODE_NAMES, 0
53
};
54
55
int pdfi_get_blend_mode(pdf_context *ctx, pdf_name *name, gs_blend_mode_t *mode)
56
309k
{
57
309k
    const char **p;
58
59
414k
    for (p = blend_mode_names; *p; ++p) {
60
413k
        if (pdfi_name_is(name, *p)) {
61
308k
            *mode = p - blend_mode_names;
62
308k
            return 0;
63
308k
        }
64
413k
    }
65
946
    return -1;
66
309k
}
67
68
void pdfi_gstate_smask_install(pdfi_int_gstate *igs, gs_memory_t *memory, pdf_dict *SMask, gs_gstate *gstate)
69
88.0M
{
70
88.0M
    void *client_data_save;
71
72
88.0M
    if (!SMask)
73
87.9M
        return;
74
104k
    igs->memory = memory;
75
104k
    igs->SMask = SMask;
76
104k
    pdfi_countup(SMask);
77
104k
    client_data_save = gstate->client_data;
78
104k
    gstate->client_data = NULL;
79
104k
    igs->GroupGState = gs_gstate_copy(gstate, memory);
80
104k
    gstate->client_data = client_data_save;
81
104k
}
82
83
void pdfi_gstate_smask_free(pdfi_int_gstate *igs)
84
133M
{
85
133M
    if (!igs->SMask)
86
133M
        return;
87
104k
    pdfi_countdown(igs->SMask);
88
104k
    igs->SMask = NULL;
89
104k
    if (igs->GroupGState)
90
104k
        gs_gstate_free(igs->GroupGState);
91
104k
    igs->GroupGState = NULL;
92
104k
}
93
94
95
/* Allocate the interpreter's part of a graphics state. */
96
static void *
97
pdfi_gstate_alloc_cb(gs_memory_t * mem)
98
45.4M
{
99
45.4M
    pdfi_int_gstate *igs;
100
101
45.4M
    igs = (pdfi_int_gstate *)gs_alloc_bytes(mem, sizeof(pdfi_int_gstate), "pdfi_gstate_alloc");
102
45.4M
    if (igs == NULL)
103
0
        return NULL;
104
45.4M
    memset(igs, 0, sizeof(pdfi_int_gstate));
105
45.4M
    return igs;
106
45.4M
}
107
108
/* Copy the interpreter's part of a graphics state. */
109
static int
110
pdfi_gstate_copy_cb(void *to, const void *from)
111
88.0M
{
112
88.0M
    const pdfi_int_gstate *igs_from = (const pdfi_int_gstate *)from;
113
88.0M
    pdfi_int_gstate *igs_to = (pdfi_int_gstate *)to;
114
115
    /* Need to free destination contents before overwriting.
116
     *  On grestore, they might be non-empty.
117
     */
118
88.0M
    if (igs_to != NULL) {
119
88.0M
        pdfi_gstate_smask_free(igs_to);
120
88.0M
        pdfi_countdown(igs_to->current_font);
121
88.0M
        *(pdfi_int_gstate *) igs_to = *igs_from;
122
88.0M
        pdfi_countup(igs_to->current_font);
123
88.0M
        pdfi_gstate_smask_install(igs_to, igs_from->memory, igs_from->SMask, igs_from->GroupGState);
124
88.0M
    }
125
88.0M
    return 0;
126
88.0M
}
127
128
/* Free the interpreter's part of a graphics state. */
129
static void
130
pdfi_gstate_free_cb(void *old, gs_memory_t * mem, gs_gstate *pgs)
131
45.4M
{
132
45.4M
    pdfi_int_gstate *igs = (pdfi_int_gstate *)old;
133
45.4M
    if (old == NULL)
134
0
        return;
135
45.4M
    pdfi_gstate_smask_free(igs);
136
45.4M
    pdfi_countdown(igs->current_font);
137
    /* We need to use the graphics state memory, in case we are running under Ghostscript. */
138
45.4M
    gs_free_object(pgs->memory, igs, "pdfi_gstate_free");
139
45.4M
}
140
141
static const gs_gstate_client_procs pdfi_gstate_procs = {
142
    pdfi_gstate_alloc_cb,
143
    pdfi_gstate_copy_cb,
144
    pdfi_gstate_free_cb,
145
    NULL, /* copy_for */
146
};
147
148
int
149
pdfi_gstate_set_client(pdf_context *ctx, gs_gstate *pgs)
150
644k
{
151
644k
    pdfi_int_gstate *igs;
152
153
    /* We need to use the graphics state memory, in case we are running under Ghostscript. */
154
644k
    igs = pdfi_gstate_alloc_cb(pgs->memory);
155
644k
    if (igs == NULL)
156
0
        return_error(gs_error_VMerror);
157
644k
    igs->ctx = ctx;
158
644k
    gs_gstate_set_client(pgs, igs, &pdfi_gstate_procs, true /* TODO: client_has_pattern_streams ? */);
159
644k
    return 0;
160
644k
}
161
162
int pdfi_concat(pdf_context *ctx)
163
4.88M
{
164
4.88M
    int code;
165
4.88M
    double Values[6];
166
4.88M
    gs_matrix m;
167
168
4.88M
    if (pdfi_count_stack(ctx) < 6) {
169
440k
        pdfi_clearstack(ctx);
170
440k
        return_error(gs_error_stackunderflow);
171
440k
    }
172
173
4.44M
    if (ctx->text.BlockDepth != 0)
174
42.9k
        pdfi_set_warning(ctx, 0, NULL, W_PDF_OPINVALIDINTEXT, "pdfi_concat", NULL);
175
176
4.44M
    code = pdfi_destack_reals(ctx, Values, 6);
177
4.44M
    if (code < 0)
178
11.4k
        return code;
179
180
4.42M
    m.xx = (float)Values[0];
181
4.42M
    m.xy = (float)Values[1];
182
4.42M
    m.yx = (float)Values[2];
183
4.42M
    m.yy = (float)Values[3];
184
4.42M
    m.tx = (float)Values[4];
185
4.42M
    m.ty = (float)Values[5];
186
187
4.42M
    return gs_concat(ctx->pgs, (const gs_matrix *)&m);
188
4.44M
}
189
190
int pdfi_op_q(pdf_context *ctx)
191
7.40M
{
192
7.40M
    int code;
193
194
#if DEBUG_GSAVE
195
    dbgmprintf(ctx->memory, "(doing q)\n"); /* TODO: Spammy, delete me at some point */
196
#endif
197
7.40M
    code = pdfi_gsave(ctx);
198
199
7.40M
    if (code < 0)
200
0
        return code;
201
7.40M
    else {
202
7.40M
        if (ctx->page.has_transparency)
203
2.67M
            return gs_push_transparency_state(ctx->pgs);
204
7.40M
    }
205
4.72M
    return 0;
206
7.40M
}
207
208
int pdfi_op_Q(pdf_context *ctx)
209
7.46M
{
210
7.46M
    int code = 0;
211
212
#if DEBUG_GSAVE
213
    dbgmprintf(ctx->memory, "(doing Q)\n"); /* TODO: Spammy, delete me at some point */
214
#endif
215
7.46M
    if (ctx->pgs->level <= ctx->current_stream_save.gsave_level) {
216
        /* We don't throw an error here, we just ignore it and continue */
217
414k
        pdfi_set_warning(ctx, 0, NULL, W_PDF_TOOMANYQ, "pdfi_op_Q", (char *)"ignoring Q");
218
414k
        return 0;
219
414k
    }
220
7.04M
    if (ctx->page.has_transparency) {
221
2.58M
        code = gs_pop_transparency_state(ctx->pgs, false);
222
2.58M
        if (code < 0)
223
0
            return code;
224
2.58M
    }
225
226
7.04M
    code = pdfi_grestore(ctx);
227
228
    /* Special hackery for pdfwrite. If we have started doing text with a clip render mode
229
     * and the output is pdfwrite, and the current (restored gstate does not have a text clipping
230
     * render mode, then we need to tell pdfwrite that it must emit a 'Q'.
231
     */
232
7.04M
    if (code >= 0 && ctx->device_state.preserve_tr_mode && ctx->text.TextClip && gs_currenttextrenderingmode(ctx->pgs) < 4) {
233
6
        gx_device *dev = gs_currentdevice_inline(ctx->pgs);
234
235
6
        ctx->text.TextClip = 0;
236
6
        dev_proc(dev, dev_spec_op)(dev, gxdso_hilevel_text_clip, (void *)0, 1);
237
6
    }
238
239
7.04M
    return code;
240
7.04M
}
241
242
/* We want pdfi_grestore() so we can track and warn of "too many Qs"
243
 * in the interests of symmetry, we also have pdfi_gsave()
244
 */
245
int pdfi_gsave(pdf_context *ctx)
246
17.5M
{
247
17.5M
    return gs_gsave(ctx->pgs);
248
17.5M
}
249
250
int pdfi_grestore(pdf_context *ctx)
251
17.5M
{
252
17.5M
    int code = 0;
253
254
    /* Make sure we have encountered as many gsave operations in this
255
     * stream as grestores. If not, log an error
256
     */
257
17.5M
    if (ctx->pgs->level > ctx->current_stream_save.gsave_level) {
258
17.5M
        code = gs_grestore(ctx->pgs);
259
17.5M
    } else {
260
        /* We don't throw an error here, we just ignore it and continue */
261
0
        pdfi_set_warning(ctx, 0, NULL, W_PDF_TOOMANYQ, "pdfi_grestore", (char *)"ignoring q");
262
0
    }
263
17.5M
    return code;
264
17.5M
}
265
266
int pdfi_gs_setgstate(gs_gstate * pgs, const gs_gstate * pfrom)
267
79.5k
{
268
79.5k
    int code = 0;
269
270
79.5k
    code = gs_setgstate(pgs, pfrom);
271
79.5k
    if (code < 0)
272
0
        return code;
273
274
79.5k
    return code;
275
79.5k
}
276
277
int pdfi_setlinewidth(pdf_context *ctx)
278
3.70M
{
279
3.70M
    int code;
280
3.70M
    double d1;
281
282
3.70M
    if (pdfi_count_stack(ctx) < 1)
283
55.8k
        return_error(gs_error_stackunderflow);
284
285
3.64M
    code = pdfi_destack_real(ctx, &d1);
286
3.64M
    if (code < 0)
287
37.9k
        return code;
288
289
3.60M
    return gs_setlinewidth(ctx->pgs, d1);
290
3.64M
}
291
292
int pdfi_setlinejoin(pdf_context *ctx)
293
1.34M
{
294
1.34M
    int code;
295
1.34M
    int64_t i;
296
297
1.34M
    if (pdfi_count_stack(ctx) < 1)
298
40.2k
        return_error(gs_error_stackunderflow);
299
300
1.30M
    code = pdfi_destack_int(ctx, &i);
301
1.30M
    if (code < 0)
302
21.4k
        return code;
303
304
1.28M
    return gs_setlinejoin(ctx->pgs, (int)i);
305
1.30M
}
306
307
int pdfi_setlinecap(pdf_context *ctx)
308
1.56M
{
309
1.56M
    int code;
310
1.56M
    int64_t i;
311
312
1.56M
    if (pdfi_count_stack(ctx) < 1)
313
41.9k
        return_error(gs_error_stackunderflow);
314
315
1.52M
    code = pdfi_destack_int(ctx, &i);
316
1.52M
    if (code < 0)
317
21.9k
        return code;
318
319
1.50M
    return gs_setlinecap(ctx->pgs, i);
320
1.52M
}
321
322
int pdfi_setflat(pdf_context *ctx)
323
436k
{
324
436k
    int code;
325
436k
    double d1;
326
327
436k
    if (pdfi_count_stack(ctx) < 1)
328
9.39k
        return_error(gs_error_stackunderflow);
329
330
427k
    code = pdfi_destack_real(ctx, &d1);
331
427k
    if (code < 0)
332
6.13k
        return code;
333
334
    /* PDF spec says the value is 1-100, with 0 meaning "use the default"
335
     * But gs code (and now our code) forces the value to be <= 1
336
     * This matches what Adobe and evince seem to do (see Bug 555657).
337
     * Apparently mupdf implements this as a no-op, which is essentially
338
     * what this does now.
339
     */
340
421k
    if (d1 > 1.0)
341
11.1k
        d1 = 1.0;
342
421k
    return gs_setflat(ctx->pgs, d1);
343
427k
}
344
345
int pdfi_setdash_impl(pdf_context *ctx, pdf_array *a, double phase_d)
346
1.20M
{
347
1.20M
    float *dash_array;
348
1.20M
    double temp;
349
1.20M
    int i, code;
350
351
1.20M
    dash_array = (float *)gs_alloc_bytes(ctx->memory, (size_t)pdfi_array_size(a) * sizeof (float),
352
1.20M
                                         "temporary float array for setdash");
353
1.20M
    if (dash_array == NULL)
354
0
        return_error(gs_error_VMerror);
355
356
1.28M
    for (i=0;i < pdfi_array_size(a);i++){
357
78.0k
        code = pdfi_array_get_number(ctx, a, (uint64_t)i, &temp);
358
78.0k
        if (code < 0) {
359
34
            gs_free_object(ctx->memory, dash_array, "error in setdash");
360
34
            return code;
361
34
        }
362
77.9k
        dash_array[i] = (float)temp;
363
77.9k
    }
364
1.20M
    code = gs_setdash(ctx->pgs, dash_array, pdfi_array_size(a), phase_d);
365
1.20M
    gs_free_object(ctx->memory, dash_array, "error in setdash");
366
1.20M
    return code;
367
1.20M
}
368
369
int pdfi_setdash(pdf_context *ctx)
370
1.27M
{
371
1.27M
    pdf_array *a;
372
1.27M
    double phase_d;
373
1.27M
    int code;
374
375
1.27M
    if (pdfi_count_stack(ctx) < 2) {
376
31.1k
        pdfi_clearstack(ctx);
377
31.1k
        return_error(gs_error_stackunderflow);
378
31.1k
    }
379
380
1.24M
    code = pdfi_destack_real(ctx, &phase_d);
381
1.24M
    if (code < 0) {
382
4.63k
        pdfi_pop(ctx, 1);
383
4.63k
        return code;
384
4.63k
    }
385
386
1.23M
    a = (pdf_array *)ctx->stack_top[-1];
387
1.23M
    pdfi_countup(a);
388
1.23M
    pdfi_pop(ctx, 1);
389
390
1.23M
    if (pdfi_type_of(a) != PDF_ARRAY) {
391
40.6k
        pdfi_countdown(a);
392
40.6k
        return_error(gs_error_typecheck);
393
40.6k
    }
394
395
1.19M
    code = pdfi_setdash_impl(ctx, a, phase_d);
396
1.19M
    pdfi_countdown(a);
397
1.19M
    return code;
398
1.23M
}
399
400
int pdfi_setmiterlimit(pdf_context *ctx)
401
63.2k
{
402
63.2k
    int code;
403
63.2k
    double d1;
404
405
63.2k
    if (pdfi_count_stack(ctx) < 1)
406
11.3k
        return_error(gs_error_stackunderflow);
407
408
51.9k
    code = pdfi_destack_real(ctx, &d1);
409
51.9k
    if (code < 0)
410
1.33k
        return code;
411
412
    /* PostScript (and therefore the graphics library) impose a minimum
413
     * value of 1.0 on miter limit. PDF does not specify a minimum, but less
414
     * than 1 doesn't make a lot of sense. This code brought over from the old
415
     * PDF interpreter which silently clamped the value to 1.
416
     */
417
50.6k
    if (d1 < 1.0)
418
696
        d1 = 1.0;
419
420
50.6k
    return gs_setmiterlimit(ctx->pgs, d1);
421
51.9k
}
422
423
static int GS_LW(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
424
397
{
425
397
    double d1;
426
397
    int code;
427
428
397
    code = pdfi_dict_get_number(ctx, GS, "LW", &d1);
429
397
    if (code < 0)
430
0
        return code;
431
432
397
    code = gs_setlinewidth(ctx->pgs, d1);
433
397
    return code;
434
397
}
435
436
static int GS_LC(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
437
705
{
438
705
    int64_t i;
439
705
    int code;
440
441
705
    code = pdfi_dict_get_int(ctx, GS, "LC", &i);
442
705
    if (code < 0)
443
0
        return code;
444
445
705
    code = gs_setlinecap(ctx->pgs, i);
446
705
    return code;
447
705
}
448
449
static int GS_LJ(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
450
546
{
451
546
    int64_t i;
452
546
    int code;
453
454
546
    code = pdfi_dict_get_int(ctx, GS, "LJ", &i);
455
546
    if (code < 0)
456
0
        return code;
457
458
546
    code = gs_setlinejoin(ctx->pgs, i);
459
546
    return code;
460
546
}
461
462
static int GS_ML(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
463
416
{
464
416
    int code;
465
416
    double d1;
466
467
416
    code = pdfi_dict_get_number(ctx, GS, "ML", &d1);
468
416
    if (code < 0)
469
17
        return code;
470
471
399
    code = gs_setmiterlimit(ctx->pgs, d1);
472
399
    return code;
473
416
}
474
475
static int GS_D(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
476
3
{
477
3
    pdf_array *a, *a1;
478
3
    double d;
479
3
    int code;
480
481
3
    code = pdfi_dict_get_type(ctx, GS, "D", PDF_ARRAY, (pdf_obj **)&a);
482
3
    if (code < 0)
483
0
        return code;
484
485
3
    code = pdfi_array_get_type(ctx, a, (int64_t)0, PDF_ARRAY, (pdf_obj **)&a1);
486
3
    if (code < 0) {
487
1
        pdfi_countdown(a);
488
1
        return code;
489
1
    }
490
491
2
    code = pdfi_array_get_number(ctx, a, (int64_t)1, &d);
492
2
    if (code < 0) {
493
0
        pdfi_countdown(a1);
494
0
        pdfi_countdown(a);
495
0
        return code;
496
0
    }
497
498
2
    code = pdfi_setdash_impl(ctx, a1, d);
499
2
    pdfi_countdown(a1);
500
2
    pdfi_countdown(a);
501
2
    return code;
502
2
}
503
504
static int GS_RI(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
505
79
{
506
79
    pdf_name *n;
507
79
    int code;
508
509
79
    code = pdfi_dict_get_type(ctx, GS, "RI", PDF_NAME, (pdf_obj **)&n);
510
79
    if (code < 0)
511
0
        return code;
512
513
79
    code = pdfi_setrenderingintent(ctx, n);
514
79
    pdfi_countdown(n);
515
79
    return code;
516
79
}
517
518
static int GS_OP(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
519
216k
{
520
216k
    bool b;
521
216k
    int code;
522
216k
    bool known=false;
523
524
216k
    code = pdfi_dict_get_bool(ctx, GS, "OP", &b);
525
216k
    if (code < 0)
526
68
        return code;
527
528
216k
    gs_setstrokeoverprint(ctx->pgs, b);
529
530
    /* If op not in the dict, then also set it with OP
531
     * Because that's what gs does pdf_draw.ps/gsparamdict/OP
532
     */
533
216k
    code = pdfi_dict_known(ctx, GS, "op", &known);
534
216k
    if (!known)
535
46.2k
        gs_setfilloverprint(ctx->pgs, b);
536
537
216k
    return 0;
538
216k
}
539
540
static int GS_op(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
541
171k
{
542
171k
    bool b;
543
171k
    int code;
544
545
171k
    code = pdfi_dict_get_bool(ctx, GS, "op", &b);
546
171k
    if (code < 0)
547
2
        return code;
548
549
171k
    gs_setfilloverprint(ctx->pgs, b);
550
171k
    return 0;
551
171k
}
552
553
static int GS_OPM(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
554
216k
{
555
216k
    int64_t i;
556
216k
    int code;
557
558
216k
    code = pdfi_dict_get_int(ctx, GS, "OPM", &i);
559
216k
    if (code < 0)
560
0
        return code;
561
562
216k
    code = gs_setoverprintmode(ctx->pgs, i);
563
216k
    return code;
564
216k
}
565
566
static int GS_Font(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
567
10
{
568
10
    pdf_array *font_array = NULL;
569
10
    pdf_dict *font_dict = NULL;
570
10
    int code = 0;
571
10
    double point_size = 0.0;
572
573
10
    code = pdfi_dict_get_type(ctx, GS, "Font", PDF_ARRAY, (pdf_obj **)&font_array);
574
10
    if (code < 0)
575
8
        return code;
576
577
2
    if (pdfi_array_size(font_array) != 2)
578
0
        return_error(gs_error_rangecheck);
579
580
2
    code = pdfi_array_get(ctx, font_array, 0, (pdf_obj **)&font_dict);
581
2
    if (code < 0)
582
1
        goto GS_Font_error;
583
584
1
    code = pdfi_array_get_number(ctx, font_array, 1, &point_size);
585
1
    if (code < 0)
586
0
        goto GS_Font_error;
587
588
1
    code = pdfi_load_dict_font(ctx, stream_dict, page_dict, font_dict, point_size);
589
590
2
GS_Font_error:
591
2
    pdfi_countdown(font_array);
592
2
    pdfi_countdown(font_dict);
593
2
    return code;
594
1
}
595
596
static int pdfi_set_blackgeneration(pdf_context *ctx, pdf_obj *obj, pdf_dict *page_dict, bool is_BG)
597
27.9k
{
598
27.9k
    int code = 0, i;
599
27.9k
    gs_function_t *pfn;
600
601
27.9k
    switch (pdfi_type_of(obj)) {
602
27.7k
        case PDF_NAME:
603
27.7k
            if (is_BG) {
604
10
                code = pdfi_set_error_stop(ctx, gs_note_error(gs_error_typecheck), NULL, E_PDF_BG_ISNAME, "pdfi_set_blackgeneration", "");
605
27.7k
            } else {
606
27.7k
                if (pdfi_name_is((const pdf_name *)obj, "Identity"))
607
0
                    code = gs_setblackgeneration_remap(ctx->pgs, gs_identity_transfer, false);
608
27.7k
                else if (pdfi_name_is((const pdf_name *)obj, "Default")) {
609
27.7k
                    code = gs_setblackgeneration_remap(ctx->pgs, ctx->page.DefaultBG.proc, false);
610
27.7k
                    memcpy(ctx->pgs->black_generation->values, ctx->page.DefaultBG.values, transfer_map_size * sizeof(frac));
611
27.7k
                } else
612
0
                    code = pdfi_set_error_stop(ctx, gs_note_error(gs_error_rangecheck), NULL, E_PDF_BG_ISNAME, "pdfi_set_blackgeneration", "");
613
27.7k
            }
614
27.7k
            goto exit;
615
616
12
        case PDF_DICT:
617
233
        case PDF_STREAM:
618
233
            code = pdfi_build_function(ctx, &pfn, NULL, 1, obj, page_dict);
619
233
            if (code < 0)
620
20
                return code;
621
622
213
            if (pfn->params.n != 1) {
623
12
                pdfi_free_function(ctx, pfn);
624
12
                return_error(gs_error_rangecheck);
625
12
            }
626
627
201
            gs_setblackgeneration_remap(ctx->pgs, gs_mapped_transfer, false);
628
51.6k
            for (i = 0; i < transfer_map_size; i++) {
629
51.4k
                float v, f;
630
631
51.4k
                f = (1.0f / (transfer_map_size - 1)) * i;
632
633
51.4k
                code = gs_function_evaluate(pfn, (const float *)&f, &v);
634
51.4k
                if (code < 0) {
635
0
                    pdfi_free_function(ctx, pfn);
636
0
                    return code;
637
0
                }
638
639
51.4k
                ctx->pgs->black_generation->values[i] =
640
51.4k
                    (v < 0.0 ? float2frac(0.0) :
641
51.4k
                     v >= 1.0 ? frac_1 :
642
51.4k
                     float2frac(v));
643
51.4k
            }
644
201
            code = pdfi_free_function(ctx, pfn);
645
201
            break;
646
647
0
        default:
648
0
            return_error(gs_error_typecheck);
649
27.9k
    }
650
27.9k
exit:
651
27.9k
    return code;
652
27.9k
}
653
654
static int GS_BG(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
655
267
{
656
267
    int code;
657
267
    pdf_obj *obj = NULL;
658
659
    /* If the dictionary also has a BG2, then we must use that */
660
267
    code = pdfi_dict_get(ctx, GS, "BG2", &obj);
661
267
    if (code == 0) {
662
0
        pdfi_countdown(obj);
663
0
        return 0;
664
0
    }
665
666
267
    code = pdfi_dict_get(ctx, GS, "BG", &obj);
667
267
    if (code < 0)
668
24
        return code;
669
670
243
    code = pdfi_set_blackgeneration(ctx, obj, page_dict, true);
671
672
243
    pdfi_countdown(obj);
673
674
243
    return code;
675
267
}
676
677
static int GS_BG2(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
678
27.7k
{
679
27.7k
    int code;
680
27.7k
    pdf_obj *obj = NULL;
681
682
27.7k
    code = pdfi_dict_get(ctx, GS, "BG2", &obj);
683
27.7k
    if (code < 0)
684
0
        return code;
685
686
27.7k
    code = pdfi_set_blackgeneration(ctx, obj, page_dict, false);
687
688
27.7k
    pdfi_countdown(obj);
689
690
27.7k
    return code;
691
27.7k
}
692
693
static int pdfi_set_undercolorremoval(pdf_context *ctx, pdf_obj *obj, pdf_dict *page_dict, bool is_UCR)
694
27.9k
{
695
27.9k
    int code = 0, i;
696
27.9k
    gs_function_t *pfn;
697
698
27.9k
    switch (pdfi_type_of(obj)) {
699
27.7k
        case PDF_NAME:
700
27.7k
            if (is_UCR) {
701
10
                code = pdfi_set_error_stop(ctx, gs_note_error(gs_error_typecheck), NULL, E_PDF_UCR_ISNAME, "pdfi_set_undercolorremoval", "");
702
27.7k
            } else {
703
27.7k
                if (pdfi_name_is((const pdf_name *)obj, "Identity")) {
704
0
                    code = gs_setundercolorremoval_remap(ctx->pgs, gs_identity_transfer, false);
705
27.7k
                } else if (pdfi_name_is((const pdf_name *)obj, "Default")) {
706
27.6k
                    code = gs_setundercolorremoval_remap(ctx->pgs, ctx->page.DefaultUCR.proc, false);
707
27.6k
                    memcpy(ctx->pgs->undercolor_removal->values, ctx->page.DefaultUCR.values, transfer_map_size * sizeof(frac));
708
27.6k
                } else {
709
8
                    code = pdfi_set_error_stop(ctx, gs_note_error(gs_error_rangecheck), NULL, E_PDF_UCR_ISNAME, "pdfi_set_undercolorremoval", "");
710
8
                }
711
27.7k
            }
712
27.7k
            goto exit;
713
714
0
        case PDF_DICT:
715
191
        case PDF_STREAM:
716
191
            code = pdfi_build_function(ctx, &pfn, NULL, 1, obj, page_dict);
717
191
            if (code < 0)
718
0
                return code;
719
720
191
            if (pfn->params.n == 1) {
721
191
                gs_setundercolorremoval_remap(ctx->pgs, gs_mapped_transfer, false);
722
49.0k
                for (i = 0; i < transfer_map_size; i++) {
723
48.8k
                    float v, f;
724
725
48.8k
                    f = (1.0f / (transfer_map_size - 1)) * i;
726
727
48.8k
                    code = gs_function_evaluate(pfn, (const float *)&f, &v);
728
48.8k
                    if (code < 0) {
729
0
                        pdfi_free_function(ctx, pfn);
730
0
                        return code;
731
0
                    }
732
733
48.8k
                    ctx->pgs->undercolor_removal->values[i] =
734
48.8k
                        (v < 0.0 ? float2frac(0.0) :
735
48.8k
                         v >= 1.0 ? frac_1 :
736
48.3k
                         float2frac(v));
737
48.8k
                }
738
191
                code = pdfi_free_function(ctx, pfn);
739
191
            }
740
0
            else {
741
0
                (void)pdfi_free_function(ctx, pfn);
742
0
                code = gs_note_error(gs_error_rangecheck);
743
0
            }
744
191
            break;
745
746
191
        default:
747
0
            return_error(gs_error_typecheck);
748
27.9k
    }
749
27.9k
exit:
750
27.9k
    return code;
751
27.9k
}
752
753
static int GS_UCR(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
754
211
{
755
211
    int code;
756
211
    pdf_obj *obj = NULL;
757
758
    /* If the dictionary also has a UCR2, then we must use that and ignore the UCR */
759
211
    code = pdfi_dict_get(ctx, GS, "UCR2", &obj);
760
211
    if (code == 0) {
761
0
        pdfi_countdown(obj);
762
0
        return 0;
763
0
    }
764
765
211
    code = pdfi_dict_get(ctx, GS, "UCR", &obj);
766
211
    if (code < 0)
767
10
        return code;
768
769
201
    code = pdfi_set_undercolorremoval(ctx, obj, page_dict, true);
770
771
201
    pdfi_countdown(obj);
772
773
201
    return code;
774
211
}
775
776
static int GS_UCR2(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
777
27.7k
{
778
27.7k
    int code;
779
27.7k
    pdf_obj *obj = NULL;
780
781
27.7k
    code = pdfi_dict_get(ctx, GS, "UCR2", &obj);
782
27.7k
    if (code < 0)
783
0
        return code;
784
785
27.7k
    code = pdfi_set_undercolorremoval(ctx, obj, page_dict, false);
786
787
27.7k
    pdfi_countdown(obj);
788
789
27.7k
    return code;
790
27.7k
}
791
792
typedef enum {
793
    E_IDENTITY,
794
    E_DEFAULT,
795
    E_FUNCTION
796
} pdf_transfer_function_type_e;
797
798
/* We use this for both TR and TR2, is_TR is true if this is a TR, in which case we don't want
799
 * to permit /Default names for fucntions.
800
 */
801
static int pdfi_set_all_transfers(pdf_context *ctx, pdf_array *a, pdf_dict *page_dict, bool is_TR)
802
244
{
803
244
    int code = 0, i, j;
804
244
    pdf_obj *o = NULL;
805
244
    int proc_types[4];
806
244
    gs_mapping_proc map_procs[4];
807
244
    gs_function_t *pfn[4];
808
809
244
    memset(pfn, 0x00, 4 * sizeof(gs_function_t *));
810
244
    memset(map_procs, 0x00, 4 * sizeof(gs_mapping_proc *));
811
812
    /* Two passes, the first one is to find the appropriate transfer procedures
813
     * and do the majorty of the error checking;
814
     */
815
771
    for (i = 0; i < 4; i++) {
816
663
        code = pdfi_array_get(ctx, a, (uint64_t)i, &o);
817
663
        if (code < 0)
818
68
            goto exit;
819
595
        switch (pdfi_type_of(o)) {
820
0
            case PDF_NAME:
821
0
                if (pdfi_name_is((const pdf_name *)o, "Identity")) {
822
0
                    proc_types[i] = E_IDENTITY;
823
0
                    map_procs[i] = gs_identity_transfer;
824
0
                } else if (!is_TR && pdfi_name_is((const pdf_name *)o, "Default")) {
825
0
                    proc_types[i] = E_DEFAULT;
826
0
                    map_procs[i] = ctx->page.DefaultTransfers[i].proc;
827
0
                } else {
828
0
                    pdfi_countdown(o);
829
0
                    code = gs_note_error(gs_error_typecheck);
830
0
                    goto exit;
831
0
                }
832
0
                break;
833
587
            case PDF_STREAM:
834
592
            case PDF_DICT:
835
592
                proc_types[i] = E_FUNCTION;
836
592
                map_procs[i] = gs_mapped_transfer;
837
592
                code = pdfi_build_function(ctx, &pfn[i], NULL, 1, o, page_dict);
838
592
                if (code < 0) {
839
65
                    pdfi_countdown(o);
840
65
                    goto exit;
841
65
                }
842
527
                if (pfn[i]->params.m != 1 || pfn[i]->params.n != 1) {
843
0
                    pdfi_countdown(o);
844
0
                    code = gs_note_error(gs_error_rangecheck);
845
0
                    goto exit;
846
0
                }
847
527
                break;
848
527
            default:
849
3
                pdfi_countdown(o);
850
3
                code = gs_note_error(gs_error_typecheck);
851
3
                goto exit;
852
595
        }
853
527
        pdfi_countdown(o);
854
527
    }
855
108
    code = gs_setcolortransfer_remap(ctx->pgs, map_procs[0], map_procs[1], map_procs[2], map_procs[3], false);
856
108
    if (code < 0)
857
0
        goto exit;
858
859
    /* Second pass is to evaluate and set the transfer maps */
860
540
    for (j = 0; j < 4; j++) {
861
432
        if (proc_types[j] == E_DEFAULT) {
862
0
            switch(j) {
863
0
                case 0:
864
0
                    memcpy(ctx->pgs->set_transfer.red->values, ctx->page.DefaultTransfers[j].values, transfer_map_size * sizeof(frac));
865
0
                    break;
866
0
                case 1:
867
0
                    memcpy(ctx->pgs->set_transfer.green->values, ctx->page.DefaultTransfers[j].values, transfer_map_size * sizeof(frac));
868
0
                    break;
869
0
                case 2:
870
0
                    memcpy(ctx->pgs->set_transfer.blue->values, ctx->page.DefaultTransfers[j].values, transfer_map_size * sizeof(frac));
871
0
                    break;
872
0
                case 3:
873
0
                    memcpy(ctx->pgs->set_transfer.gray->values, ctx->page.DefaultTransfers[j].values, transfer_map_size * sizeof(frac));
874
0
                    break;
875
0
            }
876
0
        }
877
432
        if (proc_types[j] == E_FUNCTION) {
878
111k
            for (i = 0; i < transfer_map_size; i++) {
879
110k
                float v, f;
880
110k
                frac value;
881
882
110k
                f = (1.0f / (transfer_map_size - 1)) * i;
883
884
110k
                code = gs_function_evaluate(pfn[j], (const float *)&f, &v);
885
110k
                if (code < 0)
886
0
                    goto exit;
887
888
110k
                value =
889
110k
                    (v < 0.0 ? float2frac(0.0) :
890
110k
                     v >= 1.0 ? frac_1 :
891
110k
                     float2frac(v));
892
110k
                switch(j) {
893
27.6k
                    case 0:
894
27.6k
                        ctx->pgs->set_transfer.red->values[i] = value;
895
27.6k
                        break;
896
27.6k
                    case 1:
897
27.6k
                        ctx->pgs->set_transfer.green->values[i] = value;
898
27.6k
                        break;
899
27.6k
                    case 2:
900
27.6k
                        ctx->pgs->set_transfer.blue->values[i] = value;
901
27.6k
                        break;
902
27.6k
                    case 3:
903
27.6k
                        ctx->pgs->set_transfer.gray->values[i] = value;
904
27.6k
                        break;
905
110k
                }
906
110k
            }
907
432
        }
908
432
    }
909
244
 exit:
910
1.22k
    for (i = 0; i < 4; i++) {
911
976
        pdfi_free_function(ctx, pfn[i]);
912
976
    }
913
244
    return code;
914
108
}
915
916
static int pdfi_set_gray_transfer(pdf_context *ctx, pdf_obj *tr_obj, pdf_dict *page_dict)
917
1
{
918
1
    int code = 0, i;
919
1
    gs_function_t *pfn;
920
921
1
    if (pdfi_type_of(tr_obj) != PDF_DICT && pdfi_type_of(tr_obj) != PDF_STREAM)
922
1
        return_error(gs_error_typecheck);
923
924
0
    code = pdfi_build_function(ctx, &pfn, NULL, 1, tr_obj, page_dict);
925
0
    if (code < 0)
926
0
        return code;
927
928
0
    if (pfn->params.m != 1 || pfn->params.n != 1) {
929
0
        (void)pdfi_free_function(ctx, pfn);
930
0
        return_error(gs_error_rangecheck);
931
0
    }
932
933
0
    gs_settransfer_remap(ctx->pgs, gs_mapped_transfer, false);
934
0
    for (i = 0; i < transfer_map_size; i++) {
935
0
        float v, f;
936
937
0
        f = (1.0f / (transfer_map_size - 1)) * i;
938
939
0
        code = gs_function_evaluate(pfn, (const float *)&f, &v);
940
0
        if (code < 0) {
941
0
            pdfi_free_function(ctx, pfn);
942
0
            return code;
943
0
        }
944
945
0
        ctx->pgs->set_transfer.gray->values[i] =
946
0
            (v < 0.0 ? float2frac(0.0) :
947
0
             v >= 1.0 ? frac_1 :
948
0
             float2frac(v));
949
0
    }
950
0
    return pdfi_free_function(ctx, pfn);
951
0
}
952
953
static int pdfi_set_transfer(pdf_context *ctx, pdf_obj *obj, pdf_dict *page_dict, bool is_TR)
954
38.6k
{
955
38.6k
    int code = 0;
956
957
38.6k
    if (pdfi_type_of(obj) == PDF_NAME) {
958
38.4k
        if (pdfi_name_is((const pdf_name *)obj, "Identity")) {
959
20.2k
            code = gs_settransfer_remap(ctx->pgs, gs_identity_transfer, false);
960
20.2k
            goto exit;
961
20.2k
        } else {
962
18.1k
            if (is_TR) {
963
1
                code = pdfi_set_error_stop(ctx, gs_note_error(gs_error_rangecheck), NULL, E_PDF_TR_NAME_NOT_IDENTITY, "pdfi_set_undercolorremoval", "");
964
1
                goto exit;
965
18.1k
            } else {
966
18.1k
                if (pdfi_name_is((const pdf_name *)obj, "Default")) {
967
18.0k
                    code = gs_settransfer_remap(ctx->pgs, ctx->page.DefaultTransfers[3].proc, false);
968
18.0k
                    memcpy(ctx->pgs->set_transfer.gray->values, ctx->page.DefaultTransfers[3].values, transfer_map_size * sizeof(frac));
969
18.0k
                    goto exit;
970
18.0k
                } else {
971
57
                    code = pdfi_set_error_stop(ctx, gs_note_error(gs_error_rangecheck), NULL, E_PDF_TR_NAME_NOT_IDENTITY, "pdfi_set_undercolorremoval", "");
972
57
                    goto exit;
973
57
                }
974
18.1k
            }
975
18.1k
        }
976
38.4k
    }
977
978
245
    if (pdfi_type_of(obj) == PDF_ARRAY) {
979
244
        if (pdfi_array_size((pdf_array *)obj) != 4) {
980
0
            code = gs_note_error(gs_error_rangecheck);
981
0
            goto exit;
982
244
        } else {
983
244
            code = pdfi_set_all_transfers(ctx, (pdf_array *)obj, page_dict, false);
984
244
        }
985
244
    } else
986
1
        code = pdfi_set_gray_transfer(ctx, obj, page_dict);
987
988
38.6k
exit:
989
38.6k
    return code;
990
245
}
991
992
static int GS_TR(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
993
20.5k
{
994
20.5k
    int code;
995
20.5k
    pdf_obj *obj = NULL;
996
997
20.5k
    code = pdfi_dict_get(ctx, GS, "TR", &obj);
998
20.5k
    if (code < 0)
999
0
        return code;
1000
1001
20.5k
    code = pdfi_set_transfer(ctx, obj, page_dict, true);
1002
1003
20.5k
    pdfi_countdown(obj);
1004
1005
20.5k
    return code;
1006
20.5k
}
1007
1008
static int GS_TR2(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
1009
18.1k
{
1010
18.1k
    int code;
1011
18.1k
    pdf_obj *obj = NULL;
1012
18.1k
    code = pdfi_dict_get(ctx, GS, "TR2", &obj);
1013
18.1k
    if (code < 0)
1014
0
        return code;
1015
1016
18.1k
    code = pdfi_set_transfer(ctx, obj, page_dict, false);
1017
1018
18.1k
    pdfi_countdown(obj);
1019
1020
18.1k
    return code;
1021
18.1k
}
1022
1023
static const char *spot_functions[] = {
1024
    "{dup mul exch dup mul add 1 exch sub}",        /* SimpleDot */
1025
    "{dup mul exch dup mul add 1 sub}",             /* InvertedSimpleDot */
1026
    "{360 mul sin 2 div exch 360 mul sin 2 div add",/* DoubleDot */
1027
    "360 mul sin 2 div exch 360 mul\
1028
     sin 2 div add neg}",                           /* InvertedDoubleDot */
1029
    "{180 mul cos exch 180 mul cos add 2 div}",     /* CosineDot */
1030
    "{360 mul sin 2 div exch 2 div \
1031
     360 mul sin 2 div add}",                       /* Double */
1032
    "{360 mul sin 2 div exch 2 div \
1033
     360 mul sin 2 div add neg}",                   /* InvertedDouble */
1034
    "{exch pop abs neg}",                           /* Line */
1035
    "{pop}",                                        /* LineX */
1036
    "{exch pop}",                                   /* LineY */
1037
    "{abs exch abs 2 copy add 1.0 le\
1038
     {dup mul exch dup mul add 1 exch sub}\
1039
     {1 sub dup mul exch 1 sub dup mul add 1 sub}\
1040
     ifelse}",                                      /* Round */
1041
    "{abs exch abs 2 copy 3 mul exch 4 mul\
1042
     add 3 sub dup 0 lt\
1043
     {pop dup mul exch 0.75 div dup mul add\
1044
     4 div 1 exch sub}\
1045
     {dup 1 gt\
1046
     {pop 1 exch sub dup mul exch 1 exch sub\
1047
     0.75 div dup mul add 4 div 1 sub}\
1048
     {0.5 exch sub exch pop exch pop}}\
1049
     ifelse}ifelse}}",                              /* Ellipse */
1050
    "{dup mul 0.9 mul exch dup mul add 1 exch sub}",/* EllipseA */
1051
    "{dup mul 0.9 mul exch dup mul add 1 sub}",     /* InvertedEllipseA */
1052
    "{dup 5 mul 8 div mul exch dup mul exch add\
1053
     sqrt 1 exch sub}",                             /* EllipseB */
1054
    "{dup mul exch dup mul 0.9 mul add 1 exch sub}",/* EllipseC */
1055
    "{dup mul exch dup mul 0.9 mul add 1 sub}",     /* InvertedEllipseC */
1056
    "{abs exch abs 2 copy lt {exch} if pop neg}",   /* Square */
1057
    "{abs exch abs 2 copy gt {exch} if pop neg}",   /* Cross */
1058
    "{abs exch abs 0.9 mul add 2 div}",             /* Rhomboid */
1059
    "{abs exch abs 2 copy add 0.75 le\
1060
     {dup mul exch dup mul add 1 exch sub}\
1061
     {2 copy add 1.23 le\
1062
     {0.85 mul add 1 exch sub}\
1063
     {1 sub dup mul exch 1 sub dup mul add 1 sub}\
1064
     ifelse} ifelse}"                               /* Diamond */
1065
};
1066
1067
static const char *spot_table[] = {
1068
    "SimpleDot",
1069
    "InvertedSimpleDot",
1070
    "DoubleDot",
1071
    "InvertedDoubleDot",
1072
    "CosineDot",
1073
    "Double",
1074
    "InvertedDouble",
1075
    "Line",
1076
    "LineX",
1077
    "LineY",
1078
    "Round",
1079
    "Ellipse",
1080
    "EllipseA",
1081
    "InvertedEllipseA",
1082
    "EllipseB",
1083
    "EllipseC",
1084
    "InvertedEllipseC",
1085
    "Square",
1086
    "Cross",
1087
    "Rhomboid",
1088
    "Diamond"
1089
};
1090
1091
/* Dummy spot function */
1092
static float
1093
pdfi_spot1_dummy(double x, double y)
1094
0
{
1095
0
    return (x + y) / 2;
1096
0
}
1097
1098
static int pdfi_evaluate_transfer(pdf_context *ctx, pdf_obj *transfer, pdf_dict *page_dict, gx_transfer_map **pmap)
1099
0
{
1100
0
    int t_ix = 0, code = 0;
1101
0
    float value, out;
1102
0
    gs_function_t *transfer_fn = NULL;
1103
1104
0
    rc_alloc_struct_1(*pmap, gx_transfer_map, &st_transfer_map, ctx->memory,
1105
0
          return_error(gs_error_VMerror),
1106
0
          "pdfi process_transfer");
1107
0
    (*pmap)->proc = gs_mapped_transfer;   /* 0 => use closure */
1108
0
    (*pmap)->closure.proc = NULL;
1109
0
    (*pmap)->closure.data = NULL;
1110
0
    (*pmap)->id = gs_next_ids(ctx->memory, 1);
1111
1112
0
    code = pdfi_build_function(ctx, &transfer_fn, (const float *)NULL, 1, transfer, page_dict);
1113
0
    if (code >= 0) {
1114
0
        for (t_ix = 0;t_ix < 256;t_ix++) {
1115
0
            value = (float)t_ix * 1.0f / 255.0f;
1116
0
            code = gs_function_evaluate(transfer_fn, (const float *)&value, &out);
1117
0
            if (code < 0)
1118
0
                goto error;
1119
0
            (*pmap)->values[t_ix] =  float2frac(out);
1120
0
        }
1121
0
    }
1122
0
error:
1123
0
    pdfi_free_function(ctx, transfer_fn);
1124
0
    return code;
1125
0
}
1126
1127
static int build_type1_halftone(pdf_context *ctx, pdf_dict *halftone_dict, pdf_dict *page_dict, gx_ht_order *porder, gs_halftone_component *phtc, char *name, int len, int comp_num)
1128
43.1k
{
1129
43.1k
    int code, i, j;
1130
43.1k
    pdf_obj *obj = NULL, *transfer = NULL;
1131
43.1k
    double f, a;
1132
43.1k
    float values[2] = {0, 0}, domain[4] = {-1, 1, -1, 1}, out;
1133
43.1k
    gs_function_t *pfn = NULL;
1134
43.1k
    gx_ht_order *order = NULL;
1135
43.1k
    gs_screen_enum *penum = NULL;
1136
43.1k
    gs_point pt;
1137
43.1k
    gx_transfer_map *pmap = NULL;
1138
43.1k
    bool as;
1139
1140
43.1k
    code = pdfi_dict_get_number(ctx, halftone_dict, "Frequency", &f);
1141
43.1k
    if (code < 0)
1142
0
        return code;
1143
1144
43.1k
    code = pdfi_dict_get_number(ctx, halftone_dict, "Angle", &a);
1145
43.1k
    if (code < 0)
1146
12
        return code;
1147
1148
43.1k
    code = pdfi_dict_get(ctx, halftone_dict, "SpotFunction", &obj);
1149
43.1k
    if (code < 0)
1150
0
        return code;
1151
1152
43.1k
    code = pdfi_dict_get_bool(ctx, halftone_dict, "AccurateScreens", &as);
1153
43.1k
    if (code == gs_error_undefined)
1154
43.1k
        as = 0;
1155
0
    else if (code < 0)
1156
0
        return code;
1157
1158
43.1k
    order = (gx_ht_order *)gs_alloc_bytes(ctx->memory, sizeof(gx_ht_order), "build_type1_halftone");
1159
43.1k
    if (order == NULL) {
1160
0
        code = gs_note_error(gs_error_VMerror);
1161
0
        goto error;
1162
0
    }
1163
43.1k
    memset(order, 0x00, sizeof(gx_ht_order));
1164
1165
43.1k
    switch (pdfi_type_of(obj)) {
1166
43.1k
        case PDF_NAME:
1167
43.1k
            if (pdfi_name_is((pdf_name *)obj, "Default")) {
1168
0
                i = 0;
1169
43.1k
            } else {
1170
474k
                for (i = 0; i < (sizeof(spot_table) / sizeof (char *)); i++) {
1171
474k
                    if (pdfi_name_is((pdf_name *)obj, spot_table[i]))
1172
43.1k
                        break;
1173
474k
                }
1174
43.1k
                if (i >= (sizeof(spot_table) / sizeof (char *))) {
1175
0
                    code = gs_note_error(gs_error_rangecheck);
1176
0
                    goto error;
1177
0
                }
1178
43.1k
            }
1179
43.1k
            code = pdfi_build_halftone_function(ctx, &pfn, (byte *)spot_functions[i], strlen(spot_functions[i]));
1180
43.1k
            if (code < 0)
1181
0
                goto error;
1182
43.1k
            break;
1183
43.1k
        case PDF_DICT:
1184
0
        case PDF_STREAM:
1185
0
            code = pdfi_build_function(ctx, &pfn, (const float *)domain, 2, obj, page_dict);
1186
0
            if (code < 0)
1187
0
                goto error;
1188
0
            break;
1189
0
        case PDF_ARRAY:
1190
0
            for (j = 0; j < pdfi_array_size((pdf_array *)obj); j++) {
1191
0
                pdf_name *n = NULL;
1192
1193
0
                code = pdfi_array_get(ctx, (pdf_array *)obj, j, (pdf_obj **)&n);
1194
0
                if (code < 0)
1195
0
                    goto error;
1196
0
                if (pdfi_type_of(n) != PDF_NAME) {
1197
0
                    if ((code = pdfi_set_error_stop(ctx, gs_note_error(gs_error_typecheck), NULL, E_PDF_BAD_TYPE, "build_type1_halftone", "Halftone array element is not a name")) < 0) {
1198
0
                        pdfi_countdown(n);
1199
0
                        goto error;
1200
0
                    }
1201
0
                }
1202
0
                else {
1203
0
                    for (i = 0; i < (sizeof(spot_table) / sizeof (char *)); i++) {
1204
0
                        if (pdfi_name_is((pdf_name *)n, spot_table[i])) {
1205
0
                            pdfi_countdown(n);
1206
0
                            n = NULL;
1207
0
                            code = pdfi_build_halftone_function(ctx, &pfn, (byte *)spot_functions[i], strlen(spot_functions[i]));
1208
0
                            if (code < 0)
1209
0
                                goto error;
1210
0
                            break;
1211
0
                        }
1212
0
                    }
1213
0
                    if (i >= (sizeof(spot_table) / sizeof (char *))) {
1214
0
                        pdfi_countdown(n);
1215
0
                        n = NULL;
1216
0
                    } else
1217
0
                        break;
1218
0
                }
1219
0
                pdfi_countdown(n);
1220
0
            }
1221
0
            if (j >= pdfi_array_size((pdf_array *)obj)) {
1222
0
                code = gs_note_error(gs_error_rangecheck);
1223
0
                goto error;
1224
0
            }
1225
0
            break;
1226
0
        default:
1227
0
            code = gs_note_error(gs_error_typecheck);
1228
0
            goto error;
1229
43.1k
    }
1230
1231
43.1k
    if (pdfi_dict_knownget(ctx, halftone_dict, "TransferFunction", &transfer) > 0) {
1232
0
        switch (pdfi_type_of(transfer)) {
1233
0
            case PDF_NAME:
1234
                /* As far as I can tell, only /Identity is valid as a name, so we can just ignore
1235
                 * names, if it's not Identity it would be an error (which we would ignore) and if
1236
                 * it is, it has no effect. So what's the point ?
1237
                 */
1238
0
                break;
1239
0
            case PDF_STREAM:
1240
0
                pdfi_evaluate_transfer(ctx, transfer, page_dict, &pmap);
1241
0
                break;
1242
0
            default:
1243
                /* should be an error, but we can just ignore it */
1244
0
                pdfi_set_warning(ctx, 0, NULL, W_PDF_TYPECHECK, "build_type1_halftone", NULL);
1245
0
                break;
1246
0
        }
1247
0
    }
1248
1249
43.1k
    phtc->params.spot.screen.frequency = f;
1250
43.1k
    phtc->params.spot.screen.angle = a;
1251
43.1k
    phtc->params.spot.screen.spot_function = pdfi_spot1_dummy;
1252
43.1k
    phtc->params.spot.transfer = (code > 0 ? (gs_mapping_proc) 0 : gs_identity_transfer);
1253
43.1k
    phtc->params.spot.transfer_closure.proc = 0;
1254
43.1k
    phtc->params.spot.transfer_closure.data = 0;
1255
43.1k
    phtc->params.spot.accurate_screens = as;
1256
43.1k
    phtc->type = ht_type_spot;
1257
43.1k
    code = pdfi_get_name_index(ctx, name, len, (unsigned int *)&phtc->cname);
1258
43.1k
    if (code < 0)
1259
0
        goto error;
1260
1261
43.1k
    if (comp_num == -1)
1262
43.1k
        phtc->comp_number = gs_cname_to_colorant_number(ctx->pgs, (byte *)name, len, 1);
1263
0
    else
1264
0
        phtc->comp_number = comp_num;
1265
1266
43.1k
    code = gs_screen_order_init_memory(order, ctx->pgs, &phtc->params.spot.screen,
1267
43.1k
                                       gs_currentaccuratescreens(ctx->memory), ctx->memory);
1268
43.1k
    if (code < 0)
1269
0
        goto error;
1270
1271
43.1k
    penum = gs_screen_enum_alloc(ctx->memory, "build_type1_halftone");
1272
43.1k
    if (penum == 0) {
1273
0
        code = gs_error_VMerror;
1274
0
        goto error;
1275
0
    }
1276
1277
43.1k
    code = gs_screen_enum_init_memory(penum, order, ctx->pgs, &phtc->params.spot.screen, ctx->memory);
1278
43.1k
    if (code < 0)
1279
0
        goto error;
1280
1281
388k
    do {
1282
        /* Generate x and y, the parameteric variables */
1283
388k
        code = gs_screen_currentpoint(penum, &pt);
1284
388k
        if (code < 0)
1285
0
            goto error;
1286
1287
388k
        if (code == 1)
1288
43.1k
            break;
1289
1290
        /* Process sample */
1291
345k
        values[0] = pt.x, values[1] = pt.y;
1292
345k
        code = gs_function_evaluate(pfn, (const float *)&values, &out);
1293
345k
        if (code < 0)
1294
0
            goto error;
1295
1296
        /* Store the sample */
1297
345k
        code = gs_screen_next(penum, out);
1298
345k
        if (code < 0)
1299
0
            goto error;
1300
1301
345k
    } while (1);
1302
43.1k
    code = 0;
1303
43.1k
    *porder = penum->order;
1304
43.1k
    (*porder).transfer = pmap;
1305
1306
43.1k
error:
1307
43.1k
    pdfi_countdown(transfer);
1308
43.1k
    pdfi_countdown(obj);
1309
43.1k
    pdfi_free_function(ctx, pfn);
1310
43.1k
    if (code < 0 && order != NULL) {
1311
0
        gs_free_object(ctx->memory, order->bit_data, "build_type1_halftone error");
1312
0
        gs_free_object(ctx->memory, order->levels, "build_type1_halftone error");
1313
0
    }
1314
43.1k
    if (code < 0 && pmap != NULL)
1315
43.1k
        rc_decrement(pmap, "pdfi process_transfer");
1316
43.1k
    gs_free_object(ctx->memory, order, "build_type1_halftone");
1317
43.1k
    gs_free_object(ctx->memory, penum, "build_type1_halftone");
1318
43.1k
    return code;
1319
43.1k
}
1320
1321
static int build_type6_halftone(pdf_context *ctx, pdf_stream *halftone_stream, pdf_dict *page_dict,
1322
                                gx_ht_order *porder, gs_halftone_component *phtc, char *name, int len)
1323
0
{
1324
0
    int code;
1325
0
    int64_t w, h, length = 0;
1326
0
    gs_threshold2_halftone *ptp = &phtc->params.threshold2;
1327
0
    pdf_dict *halftone_dict = NULL;
1328
1329
0
    code = pdfi_dict_from_obj(ctx, (pdf_obj *)halftone_stream, &halftone_dict);
1330
0
    if (code < 0)
1331
0
        return code;
1332
1333
0
    ptp->thresholds.data = NULL;
1334
0
    ptp->thresholds.size = 0;
1335
1336
0
    code = pdfi_dict_get_int(ctx, halftone_dict, "Width", &w);
1337
0
    if (code < 0)
1338
0
        return code;
1339
0
    ptp->width = w;
1340
0
    ptp->width2 = 0;
1341
1342
0
    code = pdfi_dict_get_int(ctx, halftone_dict, "Height", &h);
1343
0
    if (code < 0)
1344
0
        return code;
1345
0
    ptp->height = h;
1346
0
    ptp->height2 = 0;
1347
1348
0
    if (ptp->width < 1 || w > max_int ||
1349
0
        ptp->height < 1 || h > max_int)
1350
0
        return_error(gs_error_rangecheck);
1351
1352
0
    ptp->bytes_per_sample = 1;
1353
0
    ptp->transfer = 0;
1354
0
    ptp->transfer_closure.proc = 0;
1355
0
    ptp->transfer_closure.data = 0;
1356
1357
0
    code = pdfi_get_name_index(ctx, name, len, (unsigned int *)&phtc->cname);
1358
0
    if (code < 0)
1359
0
        goto error;
1360
1361
0
    phtc->comp_number = gs_cname_to_colorant_number(ctx->pgs, (byte *)name, len, 1);
1362
1363
0
    length = w * h;
1364
0
    code = pdfi_stream_to_buffer(ctx, halftone_stream,
1365
0
                                 (byte **)&ptp->thresholds.data, &length);
1366
0
    if (code < 0)
1367
0
        goto error;
1368
1369
    /* Guard against a returned buffer larger than a gs_const_bytestring can hold */
1370
0
    if (length > max_uint) {
1371
0
        code = gs_note_error(gs_error_rangecheck);
1372
0
        goto error;
1373
0
    }
1374
1375
0
    ptp->thresholds.size = length;
1376
0
    phtc->type = ht_type_threshold2;
1377
0
    return code;
1378
1379
0
error:
1380
0
    gs_free_object(ctx->memory, (byte *)ptp->thresholds.data, "build_type6_halftone");
1381
0
    return code;
1382
0
}
1383
1384
static int build_type10_halftone(pdf_context *ctx, pdf_stream *halftone_stream, pdf_dict *page_dict, gx_ht_order *porder, gs_halftone_component *phtc, char *name, int len)
1385
0
{
1386
0
    int code;
1387
0
    int64_t w, h, length = 0;
1388
0
    gs_threshold2_halftone *ptp = &phtc->params.threshold2;
1389
0
    pdf_dict *halftone_dict = NULL;
1390
1391
0
    code = pdfi_dict_from_obj(ctx, (pdf_obj *)halftone_stream, &halftone_dict);
1392
1393
0
    ptp->thresholds.data = NULL;
1394
0
    ptp->thresholds.size = 0;
1395
1396
0
    code = pdfi_dict_get_int(ctx, halftone_dict, "Xsquare", &w);
1397
0
    if (code < 0)
1398
0
        return code;
1399
0
    ptp->width = ptp->height = w;
1400
1401
0
    code = pdfi_dict_get_int(ctx, halftone_dict, "Ysquare", &h);
1402
0
    if (code < 0)
1403
0
        return code;
1404
0
    ptp->width2 = ptp->height2 = h;
1405
1406
0
    if (w < 1 || w > max_int ||
1407
0
        h < 1 || h > max_int)
1408
0
        return_error(gs_error_rangecheck);
1409
1410
0
    ptp->bytes_per_sample = 1;
1411
0
    ptp->transfer = 0;
1412
0
    ptp->transfer_closure.proc = 0;
1413
0
    ptp->transfer_closure.data = 0;
1414
1415
0
    code = pdfi_get_name_index(ctx, name, len, (unsigned int *)&phtc->cname);
1416
0
    if (code < 0)
1417
0
        goto error;
1418
1419
0
    phtc->comp_number = gs_cname_to_colorant_number(ctx->pgs, (byte *)name, len, 1);
1420
1421
0
    length = (w * w) + (h * h);
1422
0
    code = pdfi_stream_to_buffer(ctx, halftone_stream,
1423
0
                                 (byte **)&ptp->thresholds.data, &length);
1424
0
    if (code < 0)
1425
0
        goto error;
1426
1427
    /* Guard against a returned buffer larger than a gs_const_bytestring can hold */
1428
0
    if (length > max_uint) {
1429
0
        code = gs_note_error(gs_error_rangecheck);
1430
0
        goto error;
1431
0
    }
1432
1433
0
    ptp->thresholds.size = length;
1434
0
    phtc->type = ht_type_threshold2;
1435
0
    return code;
1436
1437
0
error:
1438
0
    gs_free_object(ctx->memory, (byte *)ptp->thresholds.data, "build_type10_halftone");
1439
0
    return code;
1440
0
}
1441
1442
static int build_type16_halftone(pdf_context *ctx, pdf_stream *halftone_stream, pdf_dict *page_dict, gx_ht_order *porder, gs_halftone_component *phtc, char *name, int len)
1443
0
{
1444
0
    int code;
1445
0
    int64_t w, h, length = 0;
1446
0
    gs_threshold2_halftone *ptp = &phtc->params.threshold2;
1447
0
    pdf_dict *halftone_dict = NULL;
1448
1449
0
    code = pdfi_dict_from_obj(ctx, (pdf_obj *)halftone_stream, &halftone_dict);
1450
0
    if (code < 0)
1451
0
        return code;
1452
1453
0
    ptp->thresholds.data = NULL;
1454
0
    ptp->thresholds.size = 0;
1455
1456
0
    code = pdfi_dict_get_int(ctx, halftone_dict, "Width", &w);
1457
0
    if (code < 0)
1458
0
        return code;
1459
0
    ptp->width = w;
1460
1461
0
    code = pdfi_dict_get_int(ctx, halftone_dict, "Height", &h);
1462
0
    if (code < 0)
1463
0
        return code;
1464
0
    ptp->height = h;
1465
1466
0
    if (ptp->width < 1 || w > max_int ||
1467
0
        ptp->height < 1 || h > max_int)
1468
0
        return_error(gs_error_rangecheck);
1469
1470
0
    w = 0;
1471
0
    code = pdfi_dict_get_int(ctx, halftone_dict, "Width2", &w);
1472
0
    if (code < 0 && code != gs_error_undefined)
1473
0
        return code;
1474
0
    ptp->width2 = w;
1475
1476
0
    h = 0;
1477
0
    code = pdfi_dict_get_int(ctx, halftone_dict, "Height2", &h);
1478
0
    if (code < 0 && code != gs_error_undefined)
1479
0
        return code;
1480
0
    ptp->height2 = h;
1481
1482
0
    if (ptp->width2 < 0 || w > max_int ||
1483
0
        ptp->height2 < 0 || h > max_int)
1484
0
        return_error(gs_error_rangecheck);
1485
1486
0
    ptp->bytes_per_sample = 2;
1487
0
    ptp->transfer = 0;
1488
0
    ptp->transfer_closure.proc = 0;
1489
0
    ptp->transfer_closure.data = 0;
1490
1491
0
    code = pdfi_get_name_index(ctx, name, len, (unsigned int *)&phtc->cname);
1492
0
    if (code < 0)
1493
0
        goto error;
1494
1495
0
    phtc->comp_number = gs_cname_to_colorant_number(ctx->pgs, (byte *)name, len, 1);
1496
1497
0
    if (ptp->width2 != 0 && ptp->height2 != 0) {
1498
0
        length = (((int64_t)ptp->width * ptp->height) + ((int64_t)ptp->width2 * ptp->height2)) * 2;
1499
0
    } else {
1500
0
        length = (int64_t)ptp->width * (int64_t)ptp->height * 2;
1501
0
    }
1502
1503
0
    code = pdfi_stream_to_buffer(ctx, halftone_stream,
1504
0
                                 (byte **)&ptp->thresholds.data, &length);
1505
0
    if (code < 0)
1506
0
        goto error;
1507
1508
    /* Guard against a returned buffer larger than a gs_const_bytestring can hold */
1509
0
    if (length > max_uint) {
1510
0
        code = gs_note_error(gs_error_rangecheck);
1511
0
        goto error;
1512
0
    }
1513
1514
0
    ptp->thresholds.size = length;
1515
0
    phtc->type = ht_type_threshold2;
1516
0
    return code;
1517
1518
0
error:
1519
0
    gs_free_object(ctx->memory, (byte *)ptp->thresholds.data, "build_type16_halftone");
1520
0
    return code;
1521
0
}
1522
1523
static void pdfi_free_halftone(gs_memory_t *memory, void *data, client_name_t cname)
1524
43.1k
{
1525
43.1k
    int i=0;
1526
43.1k
    gs_halftone *pht = (gs_halftone *)data;
1527
43.1k
    gs_halftone_component comp;
1528
1529
86.3k
    for (i=0;i< pht->params.multiple.num_comp;i++) {
1530
43.1k
        comp = pht->params.multiple.components[i];
1531
43.1k
        switch(comp.type) {
1532
0
            case ht_type_threshold:
1533
0
                if (comp.params.threshold.thresholds.data != NULL)
1534
0
                    gs_free_object(memory, (byte *)comp.params.threshold.thresholds.data, "pdfi_free_halftone - thresholds");
1535
0
                break;
1536
0
            case ht_type_threshold2:
1537
0
                if (comp.params.threshold2.thresholds.data != NULL)
1538
0
                    gs_free_object(memory, (byte *)comp.params.threshold2.thresholds.data, "pdfi_free_halftone - thresholds");
1539
0
                break;
1540
43.1k
            default:
1541
43.1k
                break;
1542
43.1k
        }
1543
43.1k
    }
1544
43.1k
    gs_free_object(memory, pht->params.multiple.components, "pdfi_free_halftone");
1545
43.1k
    gs_free_object(memory, pht, "pdfi_free_halftone");
1546
43.1k
}
1547
1548
static int build_type5_halftone(pdf_context *ctx, pdf_dict *halftone_dict, pdf_dict *page_dict, gx_device_halftone *pdht, gs_halftone *pht)
1549
0
{
1550
0
    int code, code1, str_len, comp_number;
1551
0
    int64_t type;
1552
0
    char *str = NULL;
1553
0
    bool known = false;
1554
0
    gs_halftone_component *phtc = NULL, *phtc1;
1555
0
    gx_ht_order_component *pocs = 0;
1556
0
    pdf_obj *Key = NULL, *Value = NULL;
1557
0
    uint64_t index = 0, ix = 0;
1558
0
    int NumComponents = 0;
1559
0
    gx_ht_order *porder1 = NULL;
1560
0
    pdf_dict *subdict = NULL;
1561
1562
    /* The only case involving multiple halftones, we need to enumerate each entry
1563
     * in the dictionary
1564
     */
1565
    /* Type 5 halftone dictionaries are required to have a Default */
1566
0
    code = pdfi_dict_known(ctx, halftone_dict, "Default", &known);
1567
0
    if (code < 0)
1568
0
        return code;
1569
0
    if (!known) {
1570
0
        code = gs_note_error(gs_error_undefined);
1571
0
        return code;
1572
0
    }
1573
1574
0
    code = pdfi_loop_detector_mark(ctx);
1575
0
    if (code < 0)
1576
0
        goto error;
1577
0
    code = pdfi_dict_first(ctx, halftone_dict, &Key, &Value, &index);
1578
0
    code1 = pdfi_loop_detector_cleartomark(ctx);
1579
0
    if (code < 0)
1580
0
        goto error;
1581
0
    if (code1 < 0) {
1582
0
        code = code1;
1583
0
        goto error;
1584
0
    }
1585
1586
    /* First establish the number of components from the halftone which we will use.
1587
     * If the component number is GX_DEVICE_COLOR_MAX_COMPONENTS then its the default,
1588
     * if its < 0 then its not available in the device. Otherwise its a colorant which is
1589
     * being rendered, so we need to set that halftone component. The Default will be
1590
     * stored in the device halftone order rather than in the component array order
1591
     * members.
1592
     */
1593
0
    do {
1594
0
        if (pdfi_type_of(Key) != PDF_NAME) {
1595
0
            code = gs_note_error(gs_error_typecheck);
1596
0
            goto error;
1597
0
        }
1598
0
        if (!pdfi_name_is((const pdf_name *)Key, "HalftoneName") && !pdfi_name_is((const pdf_name *)Key, "HalftoneType") && !pdfi_name_is((const pdf_name *)Key, "Type")) {
1599
0
            code = pdfi_string_from_name(ctx, (pdf_name *)Key, &str, &str_len);
1600
0
            if (code < 0)
1601
0
                goto error;
1602
1603
0
            comp_number = gs_cname_to_colorant_number(ctx->pgs, (byte *)str, str_len,
1604
0
                                        ht_type_multiple);
1605
0
            if (comp_number >= 0)
1606
0
                NumComponents++;
1607
0
            gs_free_object(ctx->memory, str, "pdfi_string_from_name");
1608
0
            str = NULL;
1609
0
        }
1610
1611
0
        pdfi_countdown(Key);
1612
0
        pdfi_countdown(Value);
1613
0
        Key = Value = NULL;
1614
1615
0
        code = pdfi_loop_detector_mark(ctx);
1616
0
        if (code < 0)
1617
0
            goto error;
1618
0
        code = pdfi_dict_next(ctx, halftone_dict, &Key, &Value, &index);
1619
0
        code1 = pdfi_loop_detector_cleartomark(ctx);
1620
0
        if (code < 0  && code != gs_error_undefined)
1621
0
            goto error;
1622
0
        else if (code1 < 0) {
1623
0
            code = code1;
1624
0
            goto error;
1625
0
        }
1626
0
    } while (code >= 0);
1627
1628
0
    if (NumComponents == 0) {
1629
0
        code = gs_note_error(gs_error_syntaxerror);
1630
0
        goto error;
1631
0
    }
1632
1633
0
    pocs = gs_alloc_struct_array(ctx->memory, NumComponents,
1634
0
                                 gx_ht_order_component,
1635
0
                                 &st_ht_order_component_element,
1636
0
                                 "gs_sethalftone");
1637
0
    if (pocs == NULL)
1638
0
        goto error;
1639
1640
0
    memset(pocs, 0x00, NumComponents * sizeof(gx_ht_order_component));
1641
0
    pdht->components = pocs;
1642
0
    pdht->num_comp = NumComponents;
1643
0
    phtc = (gs_halftone_component *)gs_alloc_bytes(ctx->memory, (size_t)sizeof(gs_halftone_component) * NumComponents, "pdfi_do_halftone");
1644
0
    if (phtc == 0) {
1645
0
        code = gs_note_error(gs_error_VMerror);
1646
0
        goto error;
1647
0
    }
1648
1649
0
    code = pdfi_loop_detector_mark(ctx);
1650
0
    if (code < 0)
1651
0
        goto error;
1652
0
    code = pdfi_dict_first(ctx, halftone_dict, &Key, &Value, &index);
1653
0
    code1 = pdfi_loop_detector_cleartomark(ctx);
1654
0
    if (code < 0)
1655
0
        goto error;
1656
0
    else if (code1 < 0) {
1657
0
        code = code1;
1658
0
        goto error;
1659
0
    }
1660
1661
    /* index 0 in the component array is reserved for the Default, we can't get here without
1662
     * having a /Default, so we just leave room for it and start filing the other inks from
1663
     * index 1.
1664
     */
1665
0
    ix = 1;
1666
0
    do {
1667
0
        if (pdfi_type_of(Key) != PDF_NAME) {
1668
0
            code = gs_note_error(gs_error_typecheck);
1669
0
            goto error;
1670
0
        }
1671
0
        if (!pdfi_name_is((const pdf_name *)Key, "HalftoneName") && !pdfi_name_is((const pdf_name *)Key, "HalftoneType") && !pdfi_name_is((const pdf_name *)Key, "Type")) {
1672
0
            if (!pdfi_name_is((const pdf_name *)Key, "HalftoneName") && !pdfi_name_is((const pdf_name *)Key, "HalftoneType") && !pdfi_name_is((const pdf_name *)Key, "Type")) {
1673
0
                code = pdfi_dict_from_obj(ctx, Value, &subdict);
1674
0
                if (code < 0)
1675
0
                    goto error;
1676
1677
0
                code = pdfi_string_from_name(ctx, (pdf_name *)Key, &str, &str_len);
1678
0
                if (code < 0)
1679
0
                    goto error;
1680
1681
0
                comp_number = gs_cname_to_colorant_number(ctx->pgs, (byte *)str, str_len,
1682
0
                                            ht_type_multiple);
1683
0
                if (comp_number >= 0) {
1684
                    /* If comp_number == GX_DEVICE_COLOR_MAX_COMPONENTS then it is the /Default
1685
                     * In that case we want to store it in index 0 of the halftone components array
1686
                     */
1687
0
                    if (comp_number == GX_DEVICE_COLOR_MAX_COMPONENTS) {
1688
0
                        phtc[0].comp_number = comp_number;
1689
0
                        porder1 = &(pdht->components[0].corder);
1690
0
                        pdht->components[0].comp_number = comp_number;
1691
0
                        phtc1 = &phtc[0];
1692
0
                    } else {
1693
0
                        phtc[ix].comp_number = comp_number;
1694
0
                        porder1 = &(pdht->components[ix].corder);
1695
0
                        pdht->components[ix].comp_number = phtc[ix].comp_number;
1696
0
                        phtc1 = &phtc[ix++];
1697
0
                    }
1698
1699
0
                    code = pdfi_dict_get_int(ctx, subdict, "HalftoneType", &type);
1700
0
                    if (code < 0)
1701
0
                        goto error;
1702
1703
0
                    switch(type) {
1704
0
                        case 1:
1705
0
                            code = build_type1_halftone(ctx, (pdf_dict *)Value, page_dict, porder1, phtc1, str, str_len, comp_number);
1706
0
                            if (code < 0)
1707
0
                                goto error;
1708
0
                            break;
1709
0
                        case 6:
1710
0
                            if (pdfi_type_of(Value) != PDF_STREAM) {
1711
0
                                code = gs_note_error(gs_error_typecheck);
1712
0
                                goto error;
1713
0
                            }
1714
0
                            code = build_type6_halftone(ctx, (pdf_stream *)Value, page_dict, porder1, phtc1, str, str_len);
1715
0
                            if (code < 0)
1716
0
                                goto error;
1717
0
                            break;
1718
0
                        case 10:
1719
0
                            if (pdfi_type_of(Value) != PDF_STREAM) {
1720
0
                                code = gs_note_error(gs_error_typecheck);
1721
0
                                goto error;
1722
0
                            }
1723
0
                            code = build_type10_halftone(ctx, (pdf_stream *)Value, page_dict, porder1, phtc1, str, str_len);
1724
0
                            if (code < 0)
1725
0
                                goto error;
1726
0
                            break;
1727
0
                        case 16:
1728
0
                            if (pdfi_type_of(Value) != PDF_STREAM) {
1729
0
                                code = gs_note_error(gs_error_typecheck);
1730
0
                                goto error;
1731
0
                            }
1732
0
                            code = build_type16_halftone(ctx, (pdf_stream *)Value, page_dict, porder1, phtc1, str, str_len);
1733
0
                            if (code < 0)
1734
0
                                goto error;
1735
0
                            break;
1736
0
                        default:
1737
0
                            code = gs_note_error(gs_error_rangecheck);
1738
0
                            goto error;
1739
0
                            break;
1740
1741
0
                    }
1742
0
                    gs_free_object(ctx->memory, str, "pdfi_string_from_name");
1743
0
                    str = NULL;
1744
0
                } else {
1745
0
                    gs_free_object(ctx->memory, str, "pdfi_string_from_name");
1746
0
                    str = NULL;
1747
0
                }
1748
0
            }
1749
0
        }
1750
1751
0
        pdfi_countdown(Key);
1752
0
        pdfi_countdown(Value);
1753
0
        Key = Value = NULL;
1754
1755
0
        code = pdfi_loop_detector_mark(ctx);
1756
0
        if (code < 0)
1757
0
            goto error;
1758
0
        code = pdfi_dict_next(ctx, halftone_dict, &Key, &Value, &index);
1759
0
        code1 = pdfi_loop_detector_cleartomark(ctx);
1760
0
        if (code < 0 && code != gs_error_undefined)
1761
0
            goto error;
1762
0
        else if (code1 < 0) {
1763
0
            code = code1;
1764
0
            goto error;
1765
0
        }
1766
0
    } while (code >= 0);
1767
0
    code = 0;
1768
1769
    /* If we only had one component, it must be the Default, in which case we
1770
     * do not need the components array. So we can copy the order from the 0th
1771
     * index of the components array (Default is stored at index 0) to the
1772
     * device halftone order, and free the components array.
1773
     */
1774
0
    pdht->order = pdht->components[0].corder;
1775
0
    if (ix == 1) {
1776
0
        gs_free_object(ctx->memory, pocs, "pdfi_build_type5_halftone");
1777
0
        pdht->components = 0;
1778
0
        pdht->num_comp = 0;
1779
0
    } else {
1780
0
        pdht->components = pocs;
1781
0
        pdht->num_comp = ix;
1782
0
    }
1783
1784
0
    pht->type = ht_type_multiple;
1785
0
    pht->params.multiple.components = phtc;
1786
0
    pht->params.multiple.num_comp = NumComponents;
1787
0
    pht->params.multiple.get_colorname_string = pdfi_separation_name_from_index;
1788
1789
0
    return 0;
1790
1791
0
error:
1792
0
    pdfi_countdown(Key);
1793
0
    pdfi_countdown(Value);
1794
0
    gs_free_object(ctx->memory, str, "pdfi_string_from_name");
1795
0
    gs_free_object(ctx->memory, pocs, "pdfi_build_type5_halftone");
1796
0
    gs_free_object(ctx->memory, phtc, "pdfi_build_type5_halftone");
1797
0
    pht->params.multiple.components = NULL;
1798
0
    pht->params.multiple.num_comp = 0;
1799
0
    pdht->components = NULL;
1800
0
    pdht->num_comp = 0;
1801
0
    return code;
1802
0
}
1803
1804
static int pdfi_do_halftone(pdf_context *ctx, pdf_obj *halftone_obj, pdf_dict *page_dict)
1805
43.1k
{
1806
43.1k
    int code;
1807
43.1k
    char *str = NULL;
1808
43.1k
    int64_t type;
1809
43.1k
    gs_halftone *pht = NULL;
1810
43.1k
    gx_device_halftone *pdht = NULL;
1811
43.1k
    gs_halftone_component *phtc = NULL;
1812
43.1k
    pdf_obj *Key = NULL, *Value = NULL, *transfer = NULL;
1813
43.1k
    pdf_dict *halftone_dict = NULL;
1814
43.1k
    gx_transfer_map *pmap = NULL;
1815
1816
43.1k
    code = pdfi_dict_from_obj(ctx, halftone_obj, &halftone_dict);
1817
43.1k
    if (code < 0)
1818
0
        return code;
1819
1820
43.1k
    code = pdfi_dict_get_int(ctx, halftone_dict, "HalftoneType", &type);
1821
43.1k
    if (code < 0)
1822
0
        return code;
1823
1824
43.1k
    pht = (gs_halftone *)gs_alloc_bytes(ctx->memory, sizeof(gs_halftone), "pdfi_do_halftone");
1825
43.1k
    if (pht == 0) {
1826
0
        code = gs_note_error(gs_error_VMerror);
1827
0
        goto error;
1828
0
    }
1829
43.1k
    memset(pht, 0x00, sizeof(gs_halftone));
1830
43.1k
    pht->rc.memory = ctx->memory;
1831
43.1k
    pht->rc.free = pdfi_free_halftone;
1832
1833
43.1k
    pdht = (gx_device_halftone *)gs_alloc_bytes(ctx->memory, sizeof(gx_device_halftone), "pdfi_do_halftone");
1834
43.1k
    if (pdht == 0) {
1835
0
        code = gs_note_error(gs_error_VMerror);
1836
0
        goto error;
1837
0
    }
1838
43.1k
    memset(pdht, 0x00, sizeof(gx_device_halftone));
1839
43.1k
    pdht->num_dev_comp = ctx->pgs->device->color_info.num_components;
1840
43.1k
    pdht->rc.memory = ctx->memory;
1841
1842
43.1k
    switch(type) {
1843
43.1k
        case 1:
1844
43.1k
            phtc = (gs_halftone_component *)gs_alloc_bytes(ctx->memory, sizeof(gs_halftone_component), "pdfi_do_halftone");
1845
43.1k
            if (phtc == 0) {
1846
0
                code = gs_note_error(gs_error_VMerror);
1847
0
                goto error;
1848
0
            }
1849
1850
43.1k
            code = build_type1_halftone(ctx, halftone_dict, page_dict, &pdht->order, phtc, (char *)"Default", 7, -1);
1851
43.1k
            if (code < 0)
1852
12
                goto error;
1853
1854
43.1k
            pht->type = ht_type_multiple;
1855
43.1k
            pht->params.multiple.components = phtc;
1856
43.1k
            pht->params.multiple.num_comp = 1;
1857
43.1k
            pht->params.multiple.get_colorname_string = pdfi_separation_name_from_index;
1858
43.1k
            code = gx_gstate_dev_ht_install(ctx->pgs, pdht, pht->type, gs_currentdevice_inline(ctx->pgs), HT_OBJTYPE_DEFAULT);
1859
43.1k
            if (code < 0)
1860
0
                goto error;
1861
1862
43.1k
            gx_device_halftone_release(pdht, pdht->rc.memory);
1863
43.1k
            rc_decrement(ctx->pgs->halftone, "pdfi_do_halftone(halftone)");
1864
43.1k
            ctx->pgs->halftone = pht;
1865
43.1k
            rc_increment(ctx->pgs->halftone);
1866
43.1k
            gx_unset_both_dev_colors(ctx->pgs);
1867
43.1k
            break;
1868
1869
0
        case 5:
1870
0
            code = build_type5_halftone(ctx, halftone_dict, page_dict, pdht, pht);
1871
0
            if (code < 0)
1872
0
                goto error;
1873
1874
            /* build_type5_halftone does the work of gs_sethalftone_prepare as well, so we don't need that here */
1875
1876
0
            code = gx_gstate_dev_ht_install(ctx->pgs, pdht, pht->type, gs_currentdevice_inline(ctx->pgs), HT_OBJTYPE_DEFAULT);
1877
0
            if (code < 0)
1878
0
                goto error;
1879
1880
0
            gx_device_halftone_release(pdht, pdht->rc.memory);
1881
0
            rc_decrement(ctx->pgs->halftone, "");
1882
0
            ctx->pgs->halftone = pht;
1883
0
            rc_increment(ctx->pgs->halftone);
1884
0
            gx_unset_both_dev_colors(ctx->pgs);
1885
0
            break;
1886
1887
0
        case 6:
1888
0
            if (pdfi_type_of(halftone_obj) != PDF_STREAM)
1889
0
                return_error(gs_error_typecheck);
1890
0
            phtc = (gs_halftone_component *)gs_alloc_bytes(ctx->memory, sizeof(gs_halftone_component), "pdfi_do_halftone");
1891
0
            if (phtc == 0) {
1892
0
                code = gs_note_error(gs_error_VMerror);
1893
0
                goto error;
1894
0
            }
1895
1896
0
            code = build_type6_halftone(ctx, (pdf_stream *)halftone_obj, page_dict, &pdht->order, phtc, (char *)"Default", 7);
1897
0
            if (code < 0)
1898
0
                goto error;
1899
1900
0
            pht->type = ht_type_multiple;
1901
0
            pht->params.multiple.components = phtc;
1902
0
            pht->params.multiple.num_comp = 1;
1903
0
            pht->params.multiple.get_colorname_string = pdfi_separation_name_from_index;
1904
1905
0
            code = gs_sethalftone_prepare(ctx->pgs, pht, pdht);
1906
0
            if (code < 0)
1907
0
                goto error;
1908
1909
            /* Transfer function pdht->order->transfer */
1910
0
            if (pdfi_dict_knownget(ctx, ((pdf_stream *)halftone_obj)->stream_dict, "TransferFunction", &transfer) > 0) {
1911
0
                switch (pdfi_type_of(transfer)) {
1912
0
                    case PDF_NAME:
1913
                        /* As far as I can tell, only /Identity is valid as a name, so we can just ignore
1914
                         * names, if it's not Identity it would be an error (which we would ignore) and if
1915
                         * it is, it has no effect. So what's the point ?
1916
                         */
1917
0
                        break;
1918
0
                    case PDF_STREAM:
1919
                        /* If we get an error here, we can just ignore it, and not apply the transfer */
1920
0
                        code = pdfi_evaluate_transfer(ctx, transfer, page_dict, &pmap);
1921
0
                        if (code >= 0) {
1922
0
                            pdht->order.transfer = pmap;
1923
0
                        }
1924
0
                        break;
1925
0
                    default:
1926
                        /* should be an error, but we can just ignore it */
1927
0
                        pdfi_set_warning(ctx, 0, NULL, W_PDF_TYPECHECK, "do_halftone", NULL);
1928
0
                        break;
1929
0
                }
1930
0
                pdfi_countdown(transfer);
1931
0
            }
1932
1933
0
            code = gx_gstate_dev_ht_install(ctx->pgs, pdht, pht->type, gs_currentdevice_inline(ctx->pgs), HT_OBJTYPE_DEFAULT);
1934
0
            if (code < 0)
1935
0
                goto error;
1936
1937
0
            gx_device_halftone_release(pdht, pdht->rc.memory);
1938
0
            rc_decrement(ctx->pgs->halftone, "pdfi_do_halftone(halftone)");
1939
0
            ctx->pgs->halftone = pht;
1940
0
            rc_increment(ctx->pgs->halftone);
1941
0
            gx_unset_both_dev_colors(ctx->pgs);
1942
0
            break;
1943
0
        case 10:
1944
0
            if (pdfi_type_of(halftone_obj) != PDF_STREAM)
1945
0
                return_error(gs_error_typecheck);
1946
0
            phtc = (gs_halftone_component *)gs_alloc_bytes(ctx->memory, sizeof(gs_halftone_component), "pdfi_do_halftone");
1947
0
            if (phtc == 0) {
1948
0
                code = gs_note_error(gs_error_VMerror);
1949
0
                goto error;
1950
0
            }
1951
1952
0
            code = build_type10_halftone(ctx, (pdf_stream *)halftone_obj, page_dict, &pdht->order, phtc, (char *)"Default", 7);
1953
0
            if (code < 0)
1954
0
                goto error;
1955
1956
0
            pht->type = ht_type_multiple;
1957
0
            pht->params.multiple.components = phtc;
1958
0
            pht->params.multiple.num_comp = 1;
1959
0
            pht->params.multiple.get_colorname_string = pdfi_separation_name_from_index;
1960
1961
0
            code = gs_sethalftone_prepare(ctx->pgs, pht, pdht);
1962
0
            if (code < 0)
1963
0
                goto error;
1964
1965
            /* Transfer function pdht->order->transfer */
1966
0
            if (pdfi_dict_knownget(ctx, ((pdf_stream *)halftone_obj)->stream_dict, "TransferFunction", &transfer) > 0) {
1967
0
                switch (pdfi_type_of(transfer)) {
1968
0
                    case PDF_NAME:
1969
                        /* As far as I can tell, only /Identity is valid as a name, so we can just ignore
1970
                         * names, if it's not Identity it would be an error (which we would ignore) and if
1971
                         * it is, it has no effect. So what's the point ?
1972
                         */
1973
0
                        break;
1974
0
                    case PDF_STREAM:
1975
                        /* If we get an error here, we can just ignore it, and not apply the transfer */
1976
0
                        code = pdfi_evaluate_transfer(ctx, transfer, page_dict, &pmap);
1977
0
                        if (code >= 0) {
1978
0
                            pdht->order.transfer = pmap;
1979
0
                        }
1980
0
                        break;
1981
0
                    default:
1982
                        /* should be an error, but we can just ignore it */
1983
0
                        pdfi_set_warning(ctx, 0, NULL, W_PDF_TYPECHECK, "do_halftone", NULL);
1984
0
                        break;
1985
0
                }
1986
0
                pdfi_countdown(transfer);
1987
0
            }
1988
1989
0
            code = gx_gstate_dev_ht_install(ctx->pgs, pdht, pht->type, gs_currentdevice_inline(ctx->pgs), HT_OBJTYPE_DEFAULT);
1990
0
            if (code < 0)
1991
0
                goto error;
1992
1993
0
            gx_device_halftone_release(pdht, pdht->rc.memory);
1994
0
            rc_decrement(ctx->pgs->halftone, "pdfi_do_halftone(halftone)");
1995
0
            ctx->pgs->halftone = pht;
1996
0
            rc_increment(ctx->pgs->halftone);
1997
0
            gx_unset_both_dev_colors(ctx->pgs);
1998
0
            break;
1999
0
        case 16:
2000
0
            if (pdfi_type_of(halftone_obj) != PDF_STREAM)
2001
0
                return_error(gs_error_typecheck);
2002
0
            phtc = (gs_halftone_component *)gs_alloc_bytes(ctx->memory, sizeof(gs_halftone_component), "pdfi_do_halftone");
2003
0
            if (phtc == 0) {
2004
0
                code = gs_note_error(gs_error_VMerror);
2005
0
                goto error;
2006
0
            }
2007
2008
0
            code = build_type16_halftone(ctx, (pdf_stream *)halftone_obj, page_dict, &pdht->order, phtc, (char *)"Default", 7);
2009
0
            if (code < 0)
2010
0
                goto error;
2011
2012
0
            pht->type = ht_type_multiple;
2013
0
            pht->params.multiple.components = phtc;
2014
0
            pht->params.multiple.num_comp = 1;
2015
0
            pht->params.multiple.get_colorname_string = pdfi_separation_name_from_index;
2016
2017
0
            code = gs_sethalftone_prepare(ctx->pgs, pht, pdht);
2018
0
            if (code < 0)
2019
0
                goto error;
2020
2021
            /* Transfer function pdht->order->transfer */
2022
0
            if (pdfi_dict_knownget(ctx, ((pdf_stream *)halftone_obj)->stream_dict, "TransferFunction", &transfer) > 0) {
2023
0
                switch (pdfi_type_of(transfer)) {
2024
0
                    case PDF_NAME:
2025
                        /* As far as I can tell, only /Identity is valid as a name, so we can just ignore
2026
                         * names, if it's not Identity it would be an error (which we would ignore) and if
2027
                         * it is, it has no effect. So what's the point ?
2028
                         */
2029
0
                        break;
2030
0
                    case PDF_STREAM:
2031
                        /* If we get an error here, we can just ignore it, and not apply the transfer */
2032
0
                        code = pdfi_evaluate_transfer(ctx, transfer, page_dict, &pmap);
2033
0
                        if (code >= 0) {
2034
0
                            pdht->order.transfer = pmap;
2035
0
                        }
2036
0
                        break;
2037
0
                    default:
2038
                        /* should be an error, but we can just ignore it */
2039
0
                        pdfi_set_warning(ctx, 0, NULL, W_PDF_TYPECHECK, "do_halftone", NULL);
2040
0
                        break;
2041
0
                }
2042
0
                pdfi_countdown(transfer);
2043
0
            }
2044
2045
0
            code = gx_gstate_dev_ht_install(ctx->pgs, pdht, pht->type, gs_currentdevice_inline(ctx->pgs), HT_OBJTYPE_DEFAULT);
2046
0
            if (code < 0)
2047
0
                goto error;
2048
2049
0
            gx_device_halftone_release(pdht, pdht->rc.memory);
2050
0
            rc_decrement(ctx->pgs->halftone, "pdfi_do_halftone(halftone)");
2051
0
            ctx->pgs->halftone = pht;
2052
0
            rc_increment(ctx->pgs->halftone);
2053
0
            gx_unset_both_dev_colors(ctx->pgs);
2054
0
            break;
2055
0
        default:
2056
0
            code = gs_note_error(gs_error_rangecheck);
2057
0
            goto error;
2058
0
            break;
2059
43.1k
    }
2060
43.1k
    gs_free_object(ctx->memory, pdht, "pdfi_do_halftone");
2061
43.1k
    return 0;
2062
2063
12
error:
2064
12
    if (pdht != NULL)
2065
12
        gx_device_halftone_release(pdht, pdht->rc.memory);
2066
12
    gs_free_object(ctx->memory, str, "pdfi_string_from_name");
2067
12
    pdfi_countdown(Key);
2068
12
    pdfi_countdown(Value);
2069
12
    gs_free_object(ctx->memory, pht, "pdfi_do_halftone");
2070
12
    gs_free_object(ctx->memory, phtc, "pdfi_do_halftone");
2071
12
    gs_free_object(ctx->memory, pdht, "pdfi_do_halftone");
2072
12
    return code;
2073
43.1k
}
2074
2075
static int GS_HT(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
2076
46.3k
{
2077
46.3k
    int code;
2078
46.3k
    pdf_obj *obj = NULL;
2079
2080
46.3k
    code = pdfi_dict_get(ctx, GS, "HT", &obj);
2081
46.3k
    if (code < 0)
2082
0
        return code;
2083
2084
2085
46.3k
    if (pdfi_type_of(obj) == PDF_NAME) {
2086
3.22k
        if (pdfi_name_is((const pdf_name *)obj, "Default")) {
2087
3.22k
            goto exit;
2088
3.22k
        } else {
2089
0
            code = gs_note_error(gs_error_rangecheck);
2090
0
            goto exit;
2091
0
        }
2092
43.1k
    } else {
2093
43.1k
        code = pdfi_do_halftone(ctx, obj, page_dict);
2094
43.1k
    }
2095
43.1k
    if (code < 0) {
2096
12
        code = pdfi_set_error_stop(ctx, code, NULL, E_BAD_HALFTONE, "GS_HT", "Halftone will be ignored");
2097
12
    }
2098
2099
46.3k
exit:
2100
46.3k
    pdfi_countdown(obj);
2101
46.3k
    return code;
2102
43.1k
}
2103
2104
static int GS_FL(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
2105
1
{
2106
1
    int code;
2107
1
    double d1;
2108
2109
1
    code = pdfi_dict_get_number(ctx, GS, "FL", &d1);
2110
1
    if (code < 0)
2111
0
        return code;
2112
2113
1
    code = gs_setflat(ctx->pgs, d1);
2114
1
    return code;
2115
1
}
2116
2117
static int GS_SM(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
2118
63.1k
{
2119
63.1k
    int code;
2120
63.1k
    double d1;
2121
2122
63.1k
    code = pdfi_dict_get_number(ctx, GS, "SM", &d1);
2123
63.1k
    if (code < 0)
2124
0
        return code;
2125
2126
63.1k
    code = gs_setsmoothness(ctx->pgs, d1);
2127
63.1k
    return code;
2128
63.1k
}
2129
2130
static int GS_SA(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
2131
235k
{
2132
235k
    bool b;
2133
235k
    int code;
2134
2135
235k
    code = pdfi_dict_get_bool(ctx, GS, "SA", &b);
2136
235k
    if (code < 0)
2137
28
        return code;
2138
2139
235k
    return gs_setstrokeadjust(ctx->pgs, b);
2140
235k
}
2141
2142
static int GS_BM(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
2143
309k
{
2144
309k
    pdf_name *n;
2145
309k
    int code;
2146
309k
    gs_blend_mode_t mode = 0; /* Start with /Normal */
2147
2148
309k
    code = pdfi_dict_get(ctx, GS, "BM", (pdf_obj **)&n);
2149
309k
    if (code < 0)
2150
0
        return code;
2151
2152
309k
    if (pdfi_type_of(n) == PDF_ARRAY) {
2153
56
        int i;
2154
56
        pdf_array *a = (pdf_array *)n;
2155
2156
56
        for (i=0;i < pdfi_array_size(a);i++){
2157
56
            code = pdfi_array_get_type(ctx, a, i, PDF_NAME, (pdf_obj **)&n);
2158
56
            if (code < 0)
2159
0
                continue;
2160
56
            code = pdfi_get_blend_mode(ctx, n, &mode);
2161
56
            pdfi_countdown(n);
2162
56
            if (code == 0)
2163
56
                break;
2164
56
        }
2165
56
        pdfi_countdown(a);
2166
56
        return gs_setblendmode(ctx->pgs, mode);
2167
56
    }
2168
2169
309k
    if (pdfi_type_of(n) == PDF_NAME) {
2170
309k
        code = pdfi_get_blend_mode(ctx, n, &mode);
2171
309k
        pdfi_countdown(n);
2172
309k
        if (code == 0)
2173
308k
            return gs_setblendmode(ctx->pgs, mode);
2174
309k
        return_error(gs_error_undefined);
2175
309k
    }
2176
309k
    return_error(gs_error_typecheck);
2177
309k
}
2178
2179
static int GS_SMask(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
2180
168k
{
2181
168k
    pdf_obj *o = NULL;
2182
168k
    pdfi_int_gstate *igs = (pdfi_int_gstate *)ctx->pgs->client_data;
2183
168k
    int code;
2184
168k
    bool Processed;
2185
2186
168k
    if (ctx->page.has_transparency == false || ctx->args.notransparency == true)
2187
37.5k
        return 0;
2188
2189
131k
    code = pdfi_dict_get(ctx, GS, "SMask", (pdf_obj **)&o);
2190
131k
    if (code < 0)
2191
414
        return code;
2192
2193
130k
    switch (pdfi_type_of(o)) {
2194
123k
        case PDF_NAME:
2195
123k
        {
2196
123k
            pdf_name *n = (pdf_name *)o;
2197
2198
123k
            if (pdfi_name_is(n, "None")) {
2199
123k
                if (igs->SMask) {
2200
9.58k
                    pdfi_gstate_smask_free(igs);
2201
9.58k
                    code = pdfi_trans_end_smask_notify(ctx);
2202
9.58k
                }
2203
123k
                goto exit;
2204
123k
            }
2205
92
            code = pdfi_find_resource(ctx, (unsigned char *)"ExtGState", n, stream_dict, page_dict, &o);
2206
92
            pdfi_countdown(n);
2207
92
            if (code < 0)
2208
92
                return code;
2209
0
            break;
2210
92
        }
2211
2212
7.78k
        case PDF_DICT:
2213
7.78k
        {
2214
7.78k
            code = pdfi_dict_knownget_bool(ctx, (pdf_dict *)o, "Processed", &Processed);
2215
            /* Need to clear the Processed flag in the SMask if another value is set
2216
             * (even if it's the same SMask?)
2217
             * TODO: I think there is a better way to do this that doesn't require sticking this
2218
             * flag in the SMask dictionary.  But for now, let's get correct behavior.
2219
             */
2220
7.78k
            if (code > 0 && Processed) {
2221
353
                code = pdfi_dict_put_bool(ctx, (pdf_dict *)o, "Processed", false);
2222
353
                if (code < 0)
2223
0
                    return code;
2224
353
            }
2225
7.78k
            if (igs->SMask)
2226
2.55k
                pdfi_gstate_smask_free(igs);
2227
            /* We need to use the graphics state memory, in case we are running under Ghostscript. */
2228
7.78k
            pdfi_gstate_smask_install(igs, ctx->pgs->memory, (pdf_dict *)o, ctx->pgs);
2229
7.78k
            break;
2230
7.78k
        }
2231
2232
17
        default:
2233
17
            break;
2234
130k
    }
2235
2236
130k
 exit:
2237
130k
    pdfi_countdown(o);
2238
130k
    return 0;
2239
130k
}
2240
2241
static int GS_CA(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
2242
323k
{
2243
323k
    int code;
2244
323k
    double d1;
2245
2246
323k
    code = pdfi_dict_get_number(ctx, GS, "CA", &d1);
2247
323k
    if (code < 0)
2248
6
        return code;
2249
2250
323k
    if (d1 > 1.0) {
2251
419
        pdfi_set_warning(ctx, 0, NULL, W_PDF_CA_OUTOFRANGE, "GS_CA", NULL);
2252
419
        d1 = 1.0;
2253
419
    }
2254
2255
323k
    if (d1 < 0.0) {
2256
34
        pdfi_set_warning(ctx, 0, NULL, W_PDF_CA_OUTOFRANGE, "GS_CA", NULL);
2257
34
        d1 = 0.0;
2258
34
    }
2259
2260
323k
    code = gs_setstrokeconstantalpha(ctx->pgs, d1);
2261
323k
    return code;
2262
323k
}
2263
2264
static int GS_ca(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
2265
321k
{
2266
321k
    int code;
2267
321k
    double d1;
2268
2269
321k
    code = pdfi_dict_get_number(ctx, GS, "ca", &d1);
2270
321k
    if (code < 0)
2271
2
        return code;
2272
2273
321k
    if (d1 > 1.0) {
2274
290
        pdfi_set_warning(ctx, 0, NULL, W_PDF_CA_OUTOFRANGE, "GS_ca", NULL);
2275
290
        d1 = 1.0;
2276
290
    }
2277
2278
321k
    if (d1 < 0.0) {
2279
36
        pdfi_set_warning(ctx, 0, NULL, W_PDF_CA_OUTOFRANGE, "GS_ca", NULL);
2280
36
        d1 = 0.0;
2281
36
    }
2282
2283
321k
    code = gs_setfillconstantalpha(ctx->pgs, d1);
2284
321k
    return code;
2285
321k
}
2286
2287
static int GS_AIS(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
2288
166k
{
2289
166k
    bool b;
2290
166k
    int code;
2291
2292
166k
    code = pdfi_dict_get_bool(ctx, GS, "AIS", &b);
2293
166k
    if (code < 0)
2294
0
        return code;
2295
2296
166k
    return gs_setalphaisshape(ctx->pgs, b);
2297
166k
}
2298
2299
static int GS_TK(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
2300
18.7k
{
2301
18.7k
    bool b;
2302
18.7k
    int code;
2303
2304
18.7k
    code = pdfi_dict_get_bool(ctx, GS, "TK", &b);
2305
18.7k
    if (code < 0)
2306
0
        return code;
2307
2308
18.7k
    return gs_settextknockout(ctx->pgs, b);
2309
18.7k
}
2310
2311
typedef int (*GS_proc)(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict);
2312
2313
typedef struct GS_Func {
2314
    const char *Name;
2315
    GS_proc proc;
2316
} GS_Func_t;
2317
2318
GS_Func_t ExtGStateTable[] = {
2319
    {"LW", GS_LW},
2320
    {"LC", GS_LC},
2321
    {"LJ", GS_LJ},
2322
    {"ML", GS_ML},
2323
    {"D", GS_D},
2324
    {"RI", GS_RI},
2325
    {"OP", GS_OP},
2326
    {"op", GS_op},
2327
    {"OPM", GS_OPM},
2328
    {"Font", GS_Font},
2329
    {"BG", GS_BG},
2330
    {"BG2", GS_BG2},
2331
    {"UCR", GS_UCR},
2332
    {"UCR2", GS_UCR2},
2333
    {"TR", GS_TR},
2334
    {"TR2", GS_TR2},
2335
    {"HT", GS_HT},
2336
    {"FL", GS_FL},
2337
    {"SM", GS_SM},
2338
    {"SA", GS_SA},
2339
    {"BM", GS_BM},
2340
    {"SMask", GS_SMask},
2341
    {"CA", GS_CA},
2342
    {"ca", GS_ca},
2343
    {"AIS", GS_AIS},
2344
    {"TK", GS_TK},
2345
};
2346
2347
/* Set gstate from dictionary
2348
 * NOTE: stream_dict may not be needed and can currently be NULL.
2349
 * If we decide it can't be NULL, check Patterns implementation to refactor it to pass that param.
2350
 */
2351
int pdfi_set_ExtGState(pdf_context *ctx, pdf_dict *stream_dict,
2352
                       pdf_dict *page_dict, pdf_dict *gstate_dict)
2353
536k
{
2354
536k
    int code, i, limit = sizeof(ExtGStateTable) / sizeof (GS_Func_t);
2355
536k
    bool known;
2356
2357
14.4M
    for (i=0;i < limit; i++) {
2358
13.9M
        code = pdfi_dict_known(ctx, gstate_dict, ExtGStateTable[i].Name, &known);
2359
13.9M
        if (code < 0)
2360
0
            break;
2361
13.9M
        if (known) {
2362
2.35M
            code = ExtGStateTable[i].proc(ctx, gstate_dict, NULL, page_dict);
2363
2.35M
            if (code < 0)
2364
1.90k
                break;
2365
2.35M
        }
2366
13.9M
    }
2367
536k
    return code;
2368
536k
}
2369
2370
int pdfi_setgstate(pdf_context *ctx, pdf_dict *stream_dict, pdf_dict *page_dict)
2371
759k
{
2372
759k
    pdf_name *n = NULL;
2373
759k
    pdf_obj *o = NULL;
2374
759k
    int code=0, code1 = 0;
2375
2376
759k
    code = pdfi_loop_detector_mark(ctx);
2377
759k
    if (code < 0)
2378
0
        return code;
2379
2380
759k
    if (pdfi_count_stack(ctx) < 1) {
2381
23.8k
        code = gs_note_error(gs_error_stackunderflow);
2382
23.8k
        goto setgstate_error;
2383
23.8k
    }
2384
735k
    n = (pdf_name *)ctx->stack_top[-1];
2385
735k
    pdfi_countup(n);
2386
735k
    pdfi_pop(ctx, 1);
2387
2388
735k
    if (pdfi_type_of(n) != PDF_NAME) {
2389
14.4k
        code = gs_note_error(gs_error_typecheck);
2390
14.4k
        goto setgstate_error;
2391
14.4k
    }
2392
2393
721k
    code = pdfi_find_resource(ctx, (unsigned char *)"ExtGState", n, (pdf_dict *)stream_dict,
2394
721k
                              page_dict, &o);
2395
721k
    if (code < 0)
2396
180k
        goto setgstate_error;
2397
2398
540k
    if (pdfi_type_of(o) != PDF_DICT) {
2399
4.63k
        code = gs_note_error(gs_error_typecheck);
2400
4.63k
        goto setgstate_error;
2401
4.63k
    }
2402
2403
536k
    code = pdfi_set_ExtGState(ctx, stream_dict, page_dict, (pdf_dict *)o);
2404
2405
759k
setgstate_error:
2406
759k
    code1 = pdfi_loop_detector_cleartomark(ctx);
2407
759k
    if (code == 0) code = code1;
2408
2409
759k
    pdfi_countdown(n);
2410
759k
    pdfi_countdown(o);
2411
759k
    return code;
2412
536k
}
2413
2414
2415
int pdfi_free_DefaultQState(pdf_context *ctx)
2416
1.28M
{
2417
1.28M
    if (ctx->DefaultQState)
2418
1.02M
        gs_gstate_free(ctx->DefaultQState);
2419
1.28M
    ctx->DefaultQState = NULL;
2420
1.28M
    return 0;
2421
1.28M
}
2422
2423
int pdfi_set_DefaultQState(pdf_context *ctx, gs_gstate *pgs)
2424
1.02M
{
2425
1.02M
    pdfi_free_DefaultQState(ctx);
2426
    /* We need to use the graphics state memory, in case we are running under Ghostscript. */
2427
1.02M
    ctx->DefaultQState = gs_gstate_copy(pgs, ctx->pgs->memory);
2428
1.02M
    if (ctx->DefaultQState == NULL)
2429
0
        return_error(gs_error_VMerror);
2430
1.02M
    return 0;
2431
1.02M
}
2432
2433
gs_gstate *pdfi_get_DefaultQState(pdf_context *ctx)
2434
40.4k
{
2435
40.4k
    return ctx->DefaultQState;
2436
40.4k
}
2437
2438
int pdfi_copy_DefaultQState(pdf_context *ctx, gs_gstate **pgs)
2439
446k
{
2440
    /* We need to use the graphics state memory, in case we are running under Ghostscript. */
2441
446k
    *pgs = gs_gstate_copy(ctx->DefaultQState, ctx->pgs->memory);
2442
446k
    if (*pgs == NULL)
2443
0
        return_error(gs_error_VMerror);
2444
446k
    return 0;
2445
446k
}
2446
2447
int pdfi_restore_DefaultQState(pdf_context *ctx, gs_gstate **pgs)
2448
446k
{
2449
446k
    int code;
2450
2451
446k
    code = pdfi_set_DefaultQState(ctx, *pgs);
2452
446k
    gs_gstate_free(*pgs);
2453
    *pgs = NULL;
2454
446k
    return code;
2455
446k
}