Coverage Report

Created: 2025-06-24 07:01

/src/ghostpdl/pdf/pdf_gstate.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2018-2024 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
224k
{
57
224k
    const char **p;
58
59
306k
    for (p = blend_mode_names; *p; ++p) {
60
305k
        if (pdfi_name_is(name, *p)) {
61
223k
            *mode = p - blend_mode_names;
62
223k
            return 0;
63
223k
        }
64
305k
    }
65
785
    return -1;
66
224k
}
67
68
void pdfi_gstate_smask_install(pdfi_int_gstate *igs, gs_memory_t *memory, pdf_dict *SMask, gs_gstate *gstate)
69
66.5M
{
70
66.5M
    void *client_data_save;
71
72
66.5M
    if (!SMask)
73
66.4M
        return;
74
73.8k
    igs->memory = memory;
75
73.8k
    igs->SMask = SMask;
76
73.8k
    pdfi_countup(SMask);
77
73.8k
    client_data_save = gstate->client_data;
78
73.8k
    gstate->client_data = NULL;
79
73.8k
    igs->GroupGState = gs_gstate_copy(gstate, memory);
80
73.8k
    gstate->client_data = client_data_save;
81
73.8k
}
82
83
void pdfi_gstate_smask_free(pdfi_int_gstate *igs)
84
100M
{
85
100M
    if (!igs->SMask)
86
100M
        return;
87
73.8k
    pdfi_countdown(igs->SMask);
88
73.8k
    igs->SMask = NULL;
89
73.8k
    if (igs->GroupGState)
90
73.8k
        gs_gstate_free(igs->GroupGState);
91
73.8k
    igs->GroupGState = NULL;
92
73.8k
}
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
34.2M
{
99
34.2M
    pdfi_int_gstate *igs;
100
101
34.2M
    igs = (pdfi_int_gstate *)gs_alloc_bytes(mem, sizeof(pdfi_int_gstate), "pdfi_gstate_alloc");
102
34.2M
    if (igs == NULL)
103
0
        return NULL;
104
34.2M
    memset(igs, 0, sizeof(pdfi_int_gstate));
105
34.2M
    return igs;
106
34.2M
}
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
66.5M
{
112
66.5M
    const pdfi_int_gstate *igs_from = (const pdfi_int_gstate *)from;
113
66.5M
    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
66.5M
    if (igs_to != NULL) {
119
66.5M
        pdfi_gstate_smask_free(igs_to);
120
66.5M
        pdfi_countdown(igs_to->current_font);
121
66.5M
        *(pdfi_int_gstate *) igs_to = *igs_from;
122
66.5M
        pdfi_countup(igs_to->current_font);
123
66.5M
        pdfi_gstate_smask_install(igs_to, igs_from->memory, igs_from->SMask, igs_from->GroupGState);
124
66.5M
    }
125
66.5M
    return 0;
126
66.5M
}
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
34.2M
{
132
34.2M
    pdfi_int_gstate *igs = (pdfi_int_gstate *)old;
133
34.2M
    if (old == NULL)
134
0
        return;
135
34.2M
    pdfi_gstate_smask_free(igs);
136
34.2M
    pdfi_countdown(igs->current_font);
137
    /* We need to use the graphics state memory, in case we are running under Ghostscript. */
138
34.2M
    gs_free_object(pgs->memory, igs, "pdfi_gstate_free");
139
34.2M
}
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
513k
{
151
513k
    pdfi_int_gstate *igs;
152
153
    /* We need to use the graphics state memory, in case we are running under Ghostscript. */
154
513k
    igs = pdfi_gstate_alloc_cb(pgs->memory);
155
513k
    if (igs == NULL)
156
0
        return_error(gs_error_VMerror);
157
513k
    igs->ctx = ctx;
158
513k
    gs_gstate_set_client(pgs, igs, &pdfi_gstate_procs, true /* TODO: client_has_pattern_streams ? */);
159
513k
    return 0;
160
513k
}
161
162
int pdfi_concat(pdf_context *ctx)
163
3.26M
{
164
3.26M
    int code;
165
3.26M
    double Values[6];
166
3.26M
    gs_matrix m;
167
168
3.26M
    if (pdfi_count_stack(ctx) < 6) {
169
323k
        pdfi_clearstack(ctx);
170
323k
        return_error(gs_error_stackunderflow);
171
323k
    }
172
173
2.94M
    if (ctx->text.BlockDepth != 0)
174
33.5k
        pdfi_set_warning(ctx, 0, NULL, W_PDF_OPINVALIDINTEXT, "pdfi_concat", NULL);
175
176
2.94M
    code = pdfi_destack_reals(ctx, Values, 6);
177
2.94M
    if (code < 0)
178
8.04k
        return code;
179
180
2.93M
    m.xx = (float)Values[0];
181
2.93M
    m.xy = (float)Values[1];
182
2.93M
    m.yx = (float)Values[2];
183
2.93M
    m.yy = (float)Values[3];
184
2.93M
    m.tx = (float)Values[4];
185
2.93M
    m.ty = (float)Values[5];
186
187
2.93M
    return gs_concat(ctx->pgs, (const gs_matrix *)&m);
188
2.94M
}
189
190
int pdfi_op_q(pdf_context *ctx)
191
5.39M
{
192
5.39M
    int code;
193
194
#if DEBUG_GSAVE
195
    dbgmprintf(ctx->memory, "(doing q)\n"); /* TODO: Spammy, delete me at some point */
196
#endif
197
5.39M
    code = pdfi_gsave(ctx);
198
199
5.39M
    if (code < 0)
200
0
        return code;
201
5.39M
    else {
202
5.39M
        if (ctx->page.has_transparency)
203
1.99M
            return gs_push_transparency_state(ctx->pgs);
204
5.39M
    }
205
3.40M
    return 0;
206
5.39M
}
207
208
int pdfi_op_Q(pdf_context *ctx)
209
5.43M
{
210
5.43M
    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
5.43M
    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
327k
        pdfi_set_warning(ctx, 0, NULL, W_PDF_TOOMANYQ, "pdfi_op_Q", (char *)"ignoring Q");
218
327k
        return 0;
219
327k
    }
220
5.10M
    if (ctx->page.has_transparency) {
221
1.92M
        code = gs_pop_transparency_state(ctx->pgs, false);
222
1.92M
        if (code < 0)
223
0
            return code;
224
1.92M
    }
225
226
5.10M
    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
5.10M
    if (code >= 0 && ctx->device_state.preserve_tr_mode && ctx->text.TextClip && gs_currenttextrenderingmode(ctx->pgs) < 4) {
233
0
        gx_device *dev = gs_currentdevice_inline(ctx->pgs);
234
235
0
        ctx->text.TextClip = 0;
236
0
        dev_proc(dev, dev_spec_op)(dev, gxdso_hilevel_text_clip, (void *)0, 1);
237
0
    }
238
239
5.10M
    return code;
240
5.10M
}
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
12.3M
{
247
12.3M
    return gs_gsave(ctx->pgs);
248
12.3M
}
249
250
int pdfi_grestore(pdf_context *ctx)
251
12.3M
{
252
12.3M
    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
12.3M
    if (ctx->pgs->level > ctx->current_stream_save.gsave_level) {
258
12.3M
        code = gs_grestore(ctx->pgs);
259
12.3M
    } 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
12.3M
    return code;
264
12.3M
}
265
266
int pdfi_gs_setgstate(gs_gstate * pgs, const gs_gstate * pfrom)
267
60.2k
{
268
60.2k
    int code = 0;
269
270
60.2k
    code = gs_setgstate(pgs, pfrom);
271
60.2k
    if (code < 0)
272
0
        return code;
273
274
60.2k
    return code;
275
60.2k
}
276
277
int pdfi_setlinewidth(pdf_context *ctx)
278
2.72M
{
279
2.72M
    int code;
280
2.72M
    double d1;
281
282
2.72M
    if (pdfi_count_stack(ctx) < 1)
283
36.8k
        return_error(gs_error_stackunderflow);
284
285
2.68M
    code = pdfi_destack_real(ctx, &d1);
286
2.68M
    if (code < 0)
287
25.2k
        return code;
288
289
2.66M
    return gs_setlinewidth(ctx->pgs, d1);
290
2.68M
}
291
292
int pdfi_setlinejoin(pdf_context *ctx)
293
1.04M
{
294
1.04M
    int code;
295
1.04M
    int64_t i;
296
297
1.04M
    if (pdfi_count_stack(ctx) < 1)
298
33.2k
        return_error(gs_error_stackunderflow);
299
300
1.01M
    code = pdfi_destack_int(ctx, &i);
301
1.01M
    if (code < 0)
302
14.3k
        return code;
303
304
995k
    return gs_setlinejoin(ctx->pgs, (int)i);
305
1.01M
}
306
307
int pdfi_setlinecap(pdf_context *ctx)
308
1.16M
{
309
1.16M
    int code;
310
1.16M
    int64_t i;
311
312
1.16M
    if (pdfi_count_stack(ctx) < 1)
313
33.8k
        return_error(gs_error_stackunderflow);
314
315
1.13M
    code = pdfi_destack_int(ctx, &i);
316
1.13M
    if (code < 0)
317
16.7k
        return code;
318
319
1.11M
    return gs_setlinecap(ctx->pgs, i);
320
1.13M
}
321
322
int pdfi_setflat(pdf_context *ctx)
323
321k
{
324
321k
    int code;
325
321k
    double d1;
326
327
321k
    if (pdfi_count_stack(ctx) < 1)
328
7.47k
        return_error(gs_error_stackunderflow);
329
330
313k
    code = pdfi_destack_real(ctx, &d1);
331
313k
    if (code < 0)
332
4.86k
        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
308k
    if (d1 > 1.0)
341
6.71k
        d1 = 1.0;
342
308k
    return gs_setflat(ctx->pgs, d1);
343
313k
}
344
345
int pdfi_setdash_impl(pdf_context *ctx, pdf_array *a, double phase_d)
346
888k
{
347
888k
    float *dash_array;
348
888k
    double temp;
349
888k
    int i, code;
350
351
888k
    dash_array = (float *)gs_alloc_bytes(ctx->memory, pdfi_array_size(a) * sizeof (float),
352
888k
                                         "temporary float array for setdash");
353
888k
    if (dash_array == NULL)
354
0
        return_error(gs_error_VMerror);
355
356
942k
    for (i=0;i < pdfi_array_size(a);i++){
357
53.9k
        code = pdfi_array_get_number(ctx, a, (uint64_t)i, &temp);
358
53.9k
        if (code < 0) {
359
10
            gs_free_object(ctx->memory, dash_array, "error in setdash");
360
10
            return code;
361
10
        }
362
53.9k
        dash_array[i] = (float)temp;
363
53.9k
    }
364
888k
    code = gs_setdash(ctx->pgs, dash_array, pdfi_array_size(a), phase_d);
365
888k
    gs_free_object(ctx->memory, dash_array, "error in setdash");
366
888k
    return code;
367
888k
}
368
369
int pdfi_setdash(pdf_context *ctx)
370
938k
{
371
938k
    pdf_array *a;
372
938k
    double phase_d;
373
938k
    int code;
374
375
938k
    if (pdfi_count_stack(ctx) < 2) {
376
25.1k
        pdfi_clearstack(ctx);
377
25.1k
        return_error(gs_error_stackunderflow);
378
25.1k
    }
379
380
913k
    code = pdfi_destack_real(ctx, &phase_d);
381
913k
    if (code < 0) {
382
3.39k
        pdfi_pop(ctx, 1);
383
3.39k
        return code;
384
3.39k
    }
385
386
909k
    a = (pdf_array *)ctx->stack_top[-1];
387
909k
    pdfi_countup(a);
388
909k
    pdfi_pop(ctx, 1);
389
390
909k
    if (pdfi_type_of(a) != PDF_ARRAY) {
391
24.5k
        pdfi_countdown(a);
392
24.5k
        return_error(gs_error_typecheck);
393
24.5k
    }
394
395
885k
    code = pdfi_setdash_impl(ctx, a, phase_d);
396
885k
    pdfi_countdown(a);
397
885k
    return code;
398
909k
}
399
400
int pdfi_setmiterlimit(pdf_context *ctx)
401
48.5k
{
402
48.5k
    int code;
403
48.5k
    double d1;
404
405
48.5k
    if (pdfi_count_stack(ctx) < 1)
406
11.0k
        return_error(gs_error_stackunderflow);
407
408
37.4k
    code = pdfi_destack_real(ctx, &d1);
409
37.4k
    if (code < 0)
410
1.07k
        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
36.3k
    if (d1 < 1.0)
418
424
        d1 = 1.0;
419
420
36.3k
    return gs_setmiterlimit(ctx->pgs, d1);
421
37.4k
}
422
423
static int GS_LW(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
424
340
{
425
340
    double d1;
426
340
    int code;
427
428
340
    code = pdfi_dict_get_number(ctx, GS, "LW", &d1);
429
340
    if (code < 0)
430
0
        return code;
431
432
340
    code = gs_setlinewidth(ctx->pgs, d1);
433
340
    return code;
434
340
}
435
436
static int GS_LC(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
437
552
{
438
552
    int64_t i;
439
552
    int code;
440
441
552
    code = pdfi_dict_get_int(ctx, GS, "LC", &i);
442
552
    if (code < 0)
443
0
        return code;
444
445
552
    code = gs_setlinecap(ctx->pgs, i);
446
552
    return code;
447
552
}
448
449
static int GS_LJ(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
450
473
{
451
473
    int64_t i;
452
473
    int code;
453
454
473
    code = pdfi_dict_get_int(ctx, GS, "LJ", &i);
455
473
    if (code < 0)
456
0
        return code;
457
458
473
    code = gs_setlinejoin(ctx->pgs, i);
459
473
    return code;
460
473
}
461
462
static int GS_ML(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
463
375
{
464
375
    int code;
465
375
    double d1;
466
467
375
    code = pdfi_dict_get_number(ctx, GS, "ML", &d1);
468
375
    if (code < 0)
469
34
        return code;
470
471
341
    code = gs_setmiterlimit(ctx->pgs, d1);
472
341
    return code;
473
375
}
474
475
static int GS_D(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
476
0
{
477
0
    pdf_array *a, *a1;
478
0
    double d;
479
0
    int code;
480
481
0
    code = pdfi_dict_get_type(ctx, GS, "D", PDF_ARRAY, (pdf_obj **)&a);
482
0
    if (code < 0)
483
0
        return code;
484
485
0
    code = pdfi_array_get_type(ctx, a, (int64_t)0, PDF_ARRAY, (pdf_obj **)&a1);
486
0
    if (code < 0) {
487
0
        pdfi_countdown(a);
488
0
        return code;
489
0
    }
490
491
0
    code = pdfi_array_get_number(ctx, a, (int64_t)1, &d);
492
0
    if (code < 0) {
493
0
        pdfi_countdown(a1);
494
0
        pdfi_countdown(a);
495
0
        return code;
496
0
    }
497
498
0
    code = pdfi_setdash_impl(ctx, a1, d);
499
0
    pdfi_countdown(a1);
500
0
    pdfi_countdown(a);
501
0
    return code;
502
0
}
503
504
static int GS_RI(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
505
0
{
506
0
    pdf_name *n;
507
0
    int code;
508
509
0
    code = pdfi_dict_get_type(ctx, GS, "RI", PDF_NAME, (pdf_obj **)&n);
510
0
    if (code < 0)
511
0
        return code;
512
513
0
    code = pdfi_setrenderingintent(ctx, n);
514
0
    pdfi_countdown(n);
515
0
    return code;
516
0
}
517
518
static int GS_OP(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
519
137k
{
520
137k
    bool b;
521
137k
    int code;
522
137k
    bool known=false;
523
524
137k
    code = pdfi_dict_get_bool(ctx, GS, "OP", &b);
525
137k
    if (code < 0)
526
44
        return code;
527
528
137k
    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
137k
    code = pdfi_dict_known(ctx, GS, "op", &known);
534
137k
    if (!known)
535
20.8k
        gs_setfilloverprint(ctx->pgs, b);
536
537
137k
    return 0;
538
137k
}
539
540
static int GS_op(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
541
118k
{
542
118k
    bool b;
543
118k
    int code;
544
545
118k
    code = pdfi_dict_get_bool(ctx, GS, "op", &b);
546
118k
    if (code < 0)
547
0
        return code;
548
549
118k
    gs_setfilloverprint(ctx->pgs, b);
550
118k
    return 0;
551
118k
}
552
553
static int GS_OPM(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
554
155k
{
555
155k
    int64_t i;
556
155k
    int code;
557
558
155k
    code = pdfi_dict_get_int(ctx, GS, "OPM", &i);
559
155k
    if (code < 0)
560
0
        return code;
561
562
155k
    code = gs_setoverprintmode(ctx->pgs, i);
563
155k
    return code;
564
155k
}
565
566
static int GS_Font(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
567
5
{
568
5
    pdf_array *font_array = NULL;
569
5
    pdf_dict *font_dict = NULL;
570
5
    int code = 0;
571
5
    double point_size = 0.0;
572
573
5
    code = pdfi_dict_get_type(ctx, GS, "Font", PDF_ARRAY, (pdf_obj **)&font_array);
574
5
    if (code < 0)
575
5
        return code;
576
577
0
    if (pdfi_array_size(font_array) != 2)
578
0
        return_error(gs_error_rangecheck);
579
580
0
    code = pdfi_array_get(ctx, font_array, 0, (pdf_obj **)&font_dict);
581
0
    if (code < 0)
582
0
        goto GS_Font_error;
583
584
0
    code = pdfi_array_get_number(ctx, font_array, 1, &point_size);
585
0
    if (code < 0)
586
0
        goto GS_Font_error;
587
588
0
    code = pdfi_load_dict_font(ctx, stream_dict, page_dict, font_dict, point_size);
589
590
0
GS_Font_error:
591
0
    pdfi_countdown(font_array);
592
0
    pdfi_countdown(font_dict);
593
0
    return code;
594
0
}
595
596
static int pdfi_set_blackgeneration(pdf_context *ctx, pdf_obj *obj, pdf_dict *page_dict, bool is_BG)
597
16.9k
{
598
16.9k
    int code = 0, i;
599
16.9k
    gs_function_t *pfn;
600
601
16.9k
    switch (pdfi_type_of(obj)) {
602
16.7k
        case PDF_NAME:
603
16.7k
            if (is_BG) {
604
9
                code = pdfi_set_error_stop(ctx, gs_note_error(gs_error_typecheck), NULL, E_PDF_BG_ISNAME, "pdfi_set_blackgeneration", "");
605
16.7k
            } else {
606
16.7k
                if (pdfi_name_is((const pdf_name *)obj, "Identity"))
607
0
                    code = gs_setblackgeneration_remap(ctx->pgs, gs_identity_transfer, false);
608
16.7k
                else if (pdfi_name_is((const pdf_name *)obj, "Default")) {
609
16.7k
                    code = gs_setblackgeneration_remap(ctx->pgs, ctx->page.DefaultBG.proc, false);
610
16.7k
                    memcpy(ctx->pgs->black_generation->values, ctx->page.DefaultBG.values, transfer_map_size * sizeof(frac));
611
16.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
16.7k
            }
614
16.7k
            goto exit;
615
616
10
        case PDF_DICT:
617
187
        case PDF_STREAM:
618
187
            code = pdfi_build_function(ctx, &pfn, NULL, 1, obj, page_dict);
619
187
            if (code < 0)
620
22
                return code;
621
622
165
            if (pfn->params.n != 1) {
623
10
                pdfi_free_function(ctx, pfn);
624
10
                return_error(gs_error_rangecheck);
625
10
            }
626
627
155
            gs_setblackgeneration_remap(ctx->pgs, gs_mapped_transfer, false);
628
39.8k
            for (i = 0; i < transfer_map_size; i++) {
629
39.6k
                float v, f;
630
631
39.6k
                f = (1.0f / (transfer_map_size - 1)) * i;
632
633
39.6k
                code = gs_function_evaluate(pfn, (const float *)&f, &v);
634
39.6k
                if (code < 0) {
635
0
                    pdfi_free_function(ctx, pfn);
636
0
                    return code;
637
0
                }
638
639
39.6k
                ctx->pgs->black_generation->values[i] =
640
39.6k
                    (v < 0.0 ? float2frac(0.0) :
641
39.6k
                     v >= 1.0 ? frac_1 :
642
39.6k
                     float2frac(v));
643
39.6k
            }
644
155
            code = pdfi_free_function(ctx, pfn);
645
155
            break;
646
647
0
        default:
648
0
            return_error(gs_error_typecheck);
649
16.9k
    }
650
16.9k
exit:
651
16.9k
    return code;
652
16.9k
}
653
654
static int GS_BG(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
655
214
{
656
214
    int code;
657
214
    pdf_obj *obj = NULL;
658
659
    /* If the dictionary also has a BG2, then we must use that */
660
214
    code = pdfi_dict_get(ctx, GS, "BG2", &obj);
661
214
    if (code == 0) {
662
0
        pdfi_countdown(obj);
663
0
        return 0;
664
0
    }
665
666
214
    code = pdfi_dict_get(ctx, GS, "BG", &obj);
667
214
    if (code < 0)
668
18
        return code;
669
670
196
    code = pdfi_set_blackgeneration(ctx, obj, page_dict, true);
671
672
196
    pdfi_countdown(obj);
673
674
196
    return code;
675
214
}
676
677
static int GS_BG2(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
678
16.7k
{
679
16.7k
    int code;
680
16.7k
    pdf_obj *obj = NULL;
681
682
16.7k
    code = pdfi_dict_get(ctx, GS, "BG2", &obj);
683
16.7k
    if (code < 0)
684
0
        return code;
685
686
16.7k
    code = pdfi_set_blackgeneration(ctx, obj, page_dict, false);
687
688
16.7k
    pdfi_countdown(obj);
689
690
16.7k
    return code;
691
16.7k
}
692
693
static int pdfi_set_undercolorremoval(pdf_context *ctx, pdf_obj *obj, pdf_dict *page_dict, bool is_UCR)
694
16.9k
{
695
16.9k
    int code = 0, i;
696
16.9k
    gs_function_t *pfn;
697
698
16.9k
    switch (pdfi_type_of(obj)) {
699
16.7k
        case PDF_NAME:
700
16.7k
            if (is_UCR) {
701
9
                code = pdfi_set_error_stop(ctx, gs_note_error(gs_error_typecheck), NULL, E_PDF_UCR_ISNAME, "pdfi_set_undercolorremoval", "");
702
16.7k
            } else {
703
16.7k
                if (pdfi_name_is((const pdf_name *)obj, "Identity")) {
704
0
                    code = gs_setundercolorremoval_remap(ctx->pgs, gs_identity_transfer, false);
705
16.7k
                } else if (pdfi_name_is((const pdf_name *)obj, "Default")) {
706
16.7k
                    code = gs_setundercolorremoval_remap(ctx->pgs, ctx->page.DefaultUCR.proc, false);
707
16.7k
                    memcpy(ctx->pgs->undercolor_removal->values, ctx->page.DefaultUCR.values, transfer_map_size * sizeof(frac));
708
16.7k
                } else {
709
9
                    code = pdfi_set_error_stop(ctx, gs_note_error(gs_error_rangecheck), NULL, E_PDF_UCR_ISNAME, "pdfi_set_undercolorremoval", "");
710
9
                }
711
16.7k
            }
712
16.7k
            goto exit;
713
714
0
        case PDF_DICT:
715
151
        case PDF_STREAM:
716
151
            code = pdfi_build_function(ctx, &pfn, NULL, 1, obj, page_dict);
717
151
            if (code < 0)
718
0
                return code;
719
720
151
            if (pfn->params.n == 1) {
721
151
                gs_setundercolorremoval_remap(ctx->pgs, gs_mapped_transfer, false);
722
38.8k
                for (i = 0; i < transfer_map_size; i++) {
723
38.6k
                    float v, f;
724
725
38.6k
                    f = (1.0f / (transfer_map_size - 1)) * i;
726
727
38.6k
                    code = gs_function_evaluate(pfn, (const float *)&f, &v);
728
38.6k
                    if (code < 0) {
729
0
                        pdfi_free_function(ctx, pfn);
730
0
                        return code;
731
0
                    }
732
733
38.6k
                    ctx->pgs->undercolor_removal->values[i] =
734
38.6k
                        (v < 0.0 ? float2frac(0.0) :
735
38.6k
                         v >= 1.0 ? frac_1 :
736
38.4k
                         float2frac(v));
737
38.6k
                }
738
151
                code = pdfi_free_function(ctx, pfn);
739
151
            }
740
0
            else {
741
0
                (void)pdfi_free_function(ctx, pfn);
742
0
                code = gs_note_error(gs_error_rangecheck);
743
0
            }
744
151
            break;
745
746
151
        default:
747
0
            return_error(gs_error_typecheck);
748
16.9k
    }
749
16.9k
exit:
750
16.9k
    return code;
751
16.9k
}
752
753
static int GS_UCR(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
754
164
{
755
164
    int code;
756
164
    pdf_obj *obj = NULL;
757
758
    /* If the dictionary also has a UCR2, then we must use that and ignore the UCR */
759
164
    code = pdfi_dict_get(ctx, GS, "UCR2", &obj);
760
164
    if (code == 0) {
761
0
        pdfi_countdown(obj);
762
0
        return 0;
763
0
    }
764
765
164
    code = pdfi_dict_get(ctx, GS, "UCR", &obj);
766
164
    if (code < 0)
767
4
        return code;
768
769
160
    code = pdfi_set_undercolorremoval(ctx, obj, page_dict, true);
770
771
160
    pdfi_countdown(obj);
772
773
160
    return code;
774
164
}
775
776
static int GS_UCR2(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
777
16.7k
{
778
16.7k
    int code;
779
16.7k
    pdf_obj *obj = NULL;
780
781
16.7k
    code = pdfi_dict_get(ctx, GS, "UCR2", &obj);
782
16.7k
    if (code < 0)
783
0
        return code;
784
785
16.7k
    code = pdfi_set_undercolorremoval(ctx, obj, page_dict, false);
786
787
16.7k
    pdfi_countdown(obj);
788
789
16.7k
    return code;
790
16.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
221
{
803
221
    int code = 0, i, j;
804
221
    pdf_obj *o = NULL;
805
221
    int proc_types[4];
806
221
    gs_mapping_proc map_procs[4];
807
221
    gs_function_t *pfn[4];
808
809
221
    memset(pfn, 0x00, 4 * sizeof(gs_function_t *));
810
221
    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
704
    for (i = 0; i < 4; i++) {
816
604
        code = pdfi_array_get(ctx, a, (uint64_t)i, &o);
817
604
        if (code < 0)
818
64
            goto exit;
819
540
        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
530
            case PDF_STREAM:
834
537
            case PDF_DICT:
835
537
                proc_types[i] = E_FUNCTION;
836
537
                map_procs[i] = gs_mapped_transfer;
837
537
                code = pdfi_build_function(ctx, &pfn[i], NULL, 1, o, page_dict);
838
537
                if (code < 0) {
839
54
                    pdfi_countdown(o);
840
54
                    goto exit;
841
54
                }
842
483
                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
483
                break;
848
483
            default:
849
3
                pdfi_countdown(o);
850
3
                code = gs_note_error(gs_error_typecheck);
851
3
                goto exit;
852
540
        }
853
483
        pdfi_countdown(o);
854
483
    }
855
100
    code = gs_setcolortransfer_remap(ctx->pgs, map_procs[0], map_procs[1], map_procs[2], map_procs[3], false);
856
100
    if (code < 0)
857
0
        goto exit;
858
859
    /* Second pass is to evaluate and set the transfer maps */
860
500
    for (j = 0; j < 4; j++) {
861
400
        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
400
        if (proc_types[j] == E_FUNCTION) {
878
102k
            for (i = 0; i < transfer_map_size; i++) {
879
102k
                float v, f;
880
102k
                frac value;
881
882
102k
                f = (1.0f / (transfer_map_size - 1)) * i;
883
884
102k
                code = gs_function_evaluate(pfn[j], (const float *)&f, &v);
885
102k
                if (code < 0)
886
0
                    goto exit;
887
888
102k
                value =
889
102k
                    (v < 0.0 ? float2frac(0.0) :
890
102k
                     v >= 1.0 ? frac_1 :
891
102k
                     float2frac(v));
892
102k
                switch(j) {
893
25.6k
                    case 0:
894
25.6k
                        ctx->pgs->set_transfer.red->values[i] = value;
895
25.6k
                        break;
896
25.6k
                    case 1:
897
25.6k
                        ctx->pgs->set_transfer.green->values[i] = value;
898
25.6k
                        break;
899
25.6k
                    case 2:
900
25.6k
                        ctx->pgs->set_transfer.blue->values[i] = value;
901
25.6k
                        break;
902
25.6k
                    case 3:
903
25.6k
                        ctx->pgs->set_transfer.gray->values[i] = value;
904
25.6k
                        break;
905
102k
                }
906
102k
            }
907
400
        }
908
400
    }
909
221
 exit:
910
1.10k
    for (i = 0; i < 4; i++) {
911
884
        pdfi_free_function(ctx, pfn[i]);
912
884
    }
913
221
    return code;
914
100
}
915
916
static int pdfi_set_gray_transfer(pdf_context *ctx, pdf_obj *tr_obj, pdf_dict *page_dict)
917
0
{
918
0
    int code = 0, i;
919
0
    gs_function_t *pfn;
920
921
0
    if (pdfi_type_of(tr_obj) != PDF_DICT && pdfi_type_of(tr_obj) != PDF_STREAM)
922
0
        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
29.5k
{
955
29.5k
    int code = 0;
956
957
29.5k
    if (pdfi_type_of(obj) == PDF_NAME) {
958
29.3k
        if (pdfi_name_is((const pdf_name *)obj, "Identity")) {
959
16.7k
            code = gs_settransfer_remap(ctx->pgs, gs_identity_transfer, false);
960
16.7k
            goto exit;
961
16.7k
        } else {
962
12.6k
            if (is_TR) {
963
0
                code = pdfi_set_error_stop(ctx, gs_note_error(gs_error_rangecheck), NULL, E_PDF_TR_NAME_NOT_IDENTITY, "pdfi_set_undercolorremoval", "");
964
0
                goto exit;
965
12.6k
            } else {
966
12.6k
                if (pdfi_name_is((const pdf_name *)obj, "Default")) {
967
12.5k
                    code = gs_settransfer_remap(ctx->pgs, ctx->page.DefaultTransfers[3].proc, false);
968
12.5k
                    memcpy(ctx->pgs->set_transfer.gray->values, ctx->page.DefaultTransfers[3].values, transfer_map_size * sizeof(frac));
969
12.5k
                    goto exit;
970
12.5k
                } else {
971
46
                    code = pdfi_set_error_stop(ctx, gs_note_error(gs_error_rangecheck), NULL, E_PDF_TR_NAME_NOT_IDENTITY, "pdfi_set_undercolorremoval", "");
972
46
                    goto exit;
973
46
                }
974
12.6k
            }
975
12.6k
        }
976
29.3k
    }
977
978
221
    if (pdfi_type_of(obj) == PDF_ARRAY) {
979
221
        if (pdfi_array_size((pdf_array *)obj) != 4) {
980
0
            code = gs_note_error(gs_error_rangecheck);
981
0
            goto exit;
982
221
        } else {
983
221
            code = pdfi_set_all_transfers(ctx, (pdf_array *)obj, page_dict, false);
984
221
        }
985
221
    } else
986
0
        code = pdfi_set_gray_transfer(ctx, obj, page_dict);
987
988
29.5k
exit:
989
29.5k
    return code;
990
221
}
991
992
static int GS_TR(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
993
16.9k
{
994
16.9k
    int code;
995
16.9k
    pdf_obj *obj = NULL;
996
997
16.9k
    code = pdfi_dict_get(ctx, GS, "TR", &obj);
998
16.9k
    if (code < 0)
999
0
        return code;
1000
1001
16.9k
    code = pdfi_set_transfer(ctx, obj, page_dict, true);
1002
1003
16.9k
    pdfi_countdown(obj);
1004
1005
16.9k
    return code;
1006
16.9k
}
1007
1008
static int GS_TR2(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
1009
12.6k
{
1010
12.6k
    int code;
1011
12.6k
    pdf_obj *obj = NULL;
1012
12.6k
    code = pdfi_dict_get(ctx, GS, "TR2", &obj);
1013
12.6k
    if (code < 0)
1014
0
        return code;
1015
1016
12.6k
    code = pdfi_set_transfer(ctx, obj, page_dict, false);
1017
1018
12.6k
    pdfi_countdown(obj);
1019
1020
12.6k
    return code;
1021
12.6k
}
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
19.2k
{
1129
19.2k
    int code, i, j;
1130
19.2k
    pdf_obj *obj = NULL, *transfer = NULL;
1131
19.2k
    double f, a;
1132
19.2k
    float values[2] = {0, 0}, domain[4] = {-1, 1, -1, 1}, out;
1133
19.2k
    gs_function_t *pfn = NULL;
1134
19.2k
    gx_ht_order *order = NULL;
1135
19.2k
    gs_screen_enum *penum = NULL;
1136
19.2k
    gs_point pt;
1137
19.2k
    gx_transfer_map *pmap = NULL;
1138
19.2k
    bool as;
1139
1140
19.2k
    code = pdfi_dict_get_number(ctx, halftone_dict, "Frequency", &f);
1141
19.2k
    if (code < 0)
1142
0
        return code;
1143
1144
19.2k
    code = pdfi_dict_get_number(ctx, halftone_dict, "Angle", &a);
1145
19.2k
    if (code < 0)
1146
12
        return code;
1147
1148
19.2k
    code = pdfi_dict_get(ctx, halftone_dict, "SpotFunction", &obj);
1149
19.2k
    if (code < 0)
1150
0
        return code;
1151
1152
19.2k
    code = pdfi_dict_get_bool(ctx, halftone_dict, "AccurateScreens", &as);
1153
19.2k
    if (code == gs_error_undefined)
1154
19.2k
        as = 0;
1155
0
    else if (code < 0)
1156
0
        return code;
1157
1158
19.2k
    order = (gx_ht_order *)gs_alloc_bytes(ctx->memory, sizeof(gx_ht_order), "build_type1_halftone");
1159
19.2k
    if (order == NULL) {
1160
0
        code = gs_note_error(gs_error_VMerror);
1161
0
        goto error;
1162
0
    }
1163
19.2k
    memset(order, 0x00, sizeof(gx_ht_order));
1164
1165
19.2k
    switch (pdfi_type_of(obj)) {
1166
19.2k
        case PDF_NAME:
1167
19.2k
            if (pdfi_name_is((pdf_name *)obj, "Default")) {
1168
0
                i = 0;
1169
19.2k
            } else {
1170
212k
                for (i = 0; i < (sizeof(spot_table) / sizeof (char *)); i++) {
1171
212k
                    if (pdfi_name_is((pdf_name *)obj, spot_table[i]))
1172
19.2k
                        break;
1173
212k
                }
1174
19.2k
                if (i >= (sizeof(spot_table) / sizeof (char *))) {
1175
0
                    code = gs_note_error(gs_error_rangecheck);
1176
0
                    goto error;
1177
0
                }
1178
19.2k
            }
1179
19.2k
            code = pdfi_build_halftone_function(ctx, &pfn, (byte *)spot_functions[i], strlen(spot_functions[i]));
1180
19.2k
            if (code < 0)
1181
0
                goto error;
1182
19.2k
            break;
1183
19.2k
        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
19.2k
    }
1230
1231
19.2k
    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
19.2k
    phtc->params.spot.screen.frequency = f;
1250
19.2k
    phtc->params.spot.screen.angle = a;
1251
19.2k
    phtc->params.spot.screen.spot_function = pdfi_spot1_dummy;
1252
19.2k
    phtc->params.spot.transfer = (code > 0 ? (gs_mapping_proc) 0 : gs_identity_transfer);
1253
19.2k
    phtc->params.spot.transfer_closure.proc = 0;
1254
19.2k
    phtc->params.spot.transfer_closure.data = 0;
1255
19.2k
    phtc->params.spot.accurate_screens = as;
1256
19.2k
    phtc->type = ht_type_spot;
1257
19.2k
    code = pdfi_get_name_index(ctx, name, len, (unsigned int *)&phtc->cname);
1258
19.2k
    if (code < 0)
1259
0
        goto error;
1260
1261
19.2k
    if (comp_num == -1)
1262
19.2k
        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
19.2k
    code = gs_screen_order_init_memory(order, ctx->pgs, &phtc->params.spot.screen,
1267
19.2k
                                       gs_currentaccuratescreens(ctx->memory), ctx->memory);
1268
19.2k
    if (code < 0)
1269
0
        goto error;
1270
1271
19.2k
    penum = gs_screen_enum_alloc(ctx->memory, "build_type1_halftone");
1272
19.2k
    if (penum == 0) {
1273
0
        code = gs_error_VMerror;
1274
0
        goto error;
1275
0
    }
1276
1277
19.2k
    code = gs_screen_enum_init_memory(penum, order, ctx->pgs, &phtc->params.spot.screen, ctx->memory);
1278
19.2k
    if (code < 0)
1279
0
        goto error;
1280
1281
173k
    do {
1282
        /* Generate x and y, the parameteric variables */
1283
173k
        code = gs_screen_currentpoint(penum, &pt);
1284
173k
        if (code < 0)
1285
0
            goto error;
1286
1287
173k
        if (code == 1)
1288
19.2k
            break;
1289
1290
        /* Process sample */
1291
154k
        values[0] = pt.x, values[1] = pt.y;
1292
154k
        code = gs_function_evaluate(pfn, (const float *)&values, &out);
1293
154k
        if (code < 0)
1294
0
            goto error;
1295
1296
        /* Store the sample */
1297
154k
        code = gs_screen_next(penum, out);
1298
154k
        if (code < 0)
1299
0
            goto error;
1300
1301
154k
    } while (1);
1302
19.2k
    code = 0;
1303
19.2k
    *porder = penum->order;
1304
19.2k
    (*porder).transfer = pmap;
1305
1306
19.2k
error:
1307
19.2k
    pdfi_countdown(transfer);
1308
19.2k
    pdfi_countdown(obj);
1309
19.2k
    pdfi_free_function(ctx, pfn);
1310
19.2k
    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
19.2k
    if (code < 0 && pmap != NULL)
1315
19.2k
        rc_decrement(pmap, "pdfi process_transfer");
1316
19.2k
    gs_free_object(ctx->memory, order, "build_type1_halftone");
1317
19.2k
    gs_free_object(ctx->memory, penum, "build_type1_halftone");
1318
19.2k
    return code;
1319
19.2k
}
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
    ptp->bytes_per_sample = 1;
1349
0
    ptp->transfer = 0;
1350
0
    ptp->transfer_closure.proc = 0;
1351
0
    ptp->transfer_closure.data = 0;
1352
1353
0
    code = pdfi_get_name_index(ctx, name, len, (unsigned int *)&phtc->cname);
1354
0
    if (code < 0)
1355
0
        goto error;
1356
1357
0
    phtc->comp_number = gs_cname_to_colorant_number(ctx->pgs, (byte *)name, len, 1);
1358
1359
0
    length = w * h;
1360
0
    code = pdfi_stream_to_buffer(ctx, halftone_stream,
1361
0
                                 (byte **)&ptp->thresholds.data, &length);
1362
0
    if (code < 0)
1363
0
        goto error;
1364
1365
    /* Guard against a returned buffer larger than a gs_const_bytestring can hold */
1366
0
    if (length > max_uint) {
1367
0
        code = gs_note_error(gs_error_rangecheck);
1368
0
        goto error;
1369
0
    }
1370
1371
0
    ptp->thresholds.size = length;
1372
0
    phtc->type = ht_type_threshold2;
1373
0
    return code;
1374
1375
0
error:
1376
0
    gs_free_object(ctx->memory, (byte *)ptp->thresholds.data, "build_type6_halftone");
1377
0
    return code;
1378
0
}
1379
1380
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)
1381
0
{
1382
0
    int code;
1383
0
    int64_t w, h, length = 0;
1384
0
    gs_threshold2_halftone *ptp = &phtc->params.threshold2;
1385
0
    pdf_dict *halftone_dict = NULL;
1386
1387
0
    code = pdfi_dict_from_obj(ctx, (pdf_obj *)halftone_stream, &halftone_dict);
1388
1389
0
    ptp->thresholds.data = NULL;
1390
0
    ptp->thresholds.size = 0;
1391
1392
0
    code = pdfi_dict_get_int(ctx, halftone_dict, "Xsquare", &w);
1393
0
    if (code < 0)
1394
0
        return code;
1395
0
    ptp->width = ptp->height = w;
1396
1397
0
    code = pdfi_dict_get_int(ctx, halftone_dict, "Ysquare", &h);
1398
0
    if (code < 0)
1399
0
        return code;
1400
0
    ptp->width2 = ptp->height2 = h;
1401
1402
0
    ptp->bytes_per_sample = 1;
1403
0
    ptp->transfer = 0;
1404
0
    ptp->transfer_closure.proc = 0;
1405
0
    ptp->transfer_closure.data = 0;
1406
1407
0
    code = pdfi_get_name_index(ctx, name, len, (unsigned int *)&phtc->cname);
1408
0
    if (code < 0)
1409
0
        goto error;
1410
1411
0
    phtc->comp_number = gs_cname_to_colorant_number(ctx->pgs, (byte *)name, len, 1);
1412
1413
0
    length = (w * w) + (h * h);
1414
0
    code = pdfi_stream_to_buffer(ctx, halftone_stream,
1415
0
                                 (byte **)&ptp->thresholds.data, &length);
1416
0
    if (code < 0)
1417
0
        goto error;
1418
1419
    /* Guard against a returned buffer larger than a gs_const_bytestring can hold */
1420
0
    if (length > max_uint) {
1421
0
        code = gs_note_error(gs_error_rangecheck);
1422
0
        goto error;
1423
0
    }
1424
1425
0
    ptp->thresholds.size = length;
1426
0
    phtc->type = ht_type_threshold2;
1427
0
    return code;
1428
1429
0
error:
1430
0
    gs_free_object(ctx->memory, (byte *)ptp->thresholds.data, "build_type10_halftone");
1431
0
    return code;
1432
0
}
1433
1434
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)
1435
0
{
1436
0
    int code;
1437
0
    int64_t w, h, length = 0;
1438
0
    gs_threshold2_halftone *ptp = &phtc->params.threshold2;
1439
0
    pdf_dict *halftone_dict = NULL;
1440
1441
0
    code = pdfi_dict_from_obj(ctx, (pdf_obj *)halftone_stream, &halftone_dict);
1442
0
    if (code < 0)
1443
0
        return code;
1444
1445
0
    ptp->thresholds.data = NULL;
1446
0
    ptp->thresholds.size = 0;
1447
1448
0
    code = pdfi_dict_get_int(ctx, halftone_dict, "Width", &w);
1449
0
    if (code < 0)
1450
0
        return code;
1451
0
    ptp->width = w;
1452
1453
0
    code = pdfi_dict_get_int(ctx, halftone_dict, "Height", &h);
1454
0
    if (code < 0)
1455
0
        return code;
1456
0
    ptp->height = h;
1457
1458
0
    w = 0;
1459
0
    code = pdfi_dict_get_int(ctx, halftone_dict, "Width2", &w);
1460
0
    if (code < 0 && code != gs_error_undefined)
1461
0
        return code;
1462
0
    ptp->width2 = w;
1463
1464
0
    h = 0;
1465
0
    code = pdfi_dict_get_int(ctx, halftone_dict, "Height2", &h);
1466
0
    if (code < 0 && code != gs_error_undefined)
1467
0
        return code;
1468
0
    ptp->height2 = h;
1469
1470
0
    ptp->bytes_per_sample = 2;
1471
0
    ptp->transfer = 0;
1472
0
    ptp->transfer_closure.proc = 0;
1473
0
    ptp->transfer_closure.data = 0;
1474
1475
0
    code = pdfi_get_name_index(ctx, name, len, (unsigned int *)&phtc->cname);
1476
0
    if (code < 0)
1477
0
        goto error;
1478
1479
0
    phtc->comp_number = gs_cname_to_colorant_number(ctx->pgs, (byte *)name, len, 1);
1480
1481
0
    if (ptp->width2 != 0 && ptp->height2 != 0) {
1482
0
        length = ((ptp->width * ptp->height) + (ptp->width2 * ptp->height2)) * 2;
1483
0
    } else {
1484
0
        length = (int64_t)ptp->width * (int64_t)ptp->height * 2;
1485
0
    }
1486
1487
0
    code = pdfi_stream_to_buffer(ctx, halftone_stream,
1488
0
                                 (byte **)&ptp->thresholds.data, &length);
1489
0
    if (code < 0)
1490
0
        goto error;
1491
1492
    /* Guard against a returned buffer larger than a gs_const_bytestring can hold */
1493
0
    if (length > max_uint) {
1494
0
        code = gs_note_error(gs_error_rangecheck);
1495
0
        goto error;
1496
0
    }
1497
1498
0
    ptp->thresholds.size = length;
1499
0
    phtc->type = ht_type_threshold2;
1500
0
    return code;
1501
1502
0
error:
1503
0
    gs_free_object(ctx->memory, (byte *)ptp->thresholds.data, "build_type16_halftone");
1504
0
    return code;
1505
0
}
1506
1507
static void pdfi_free_halftone(gs_memory_t *memory, void *data, client_name_t cname)
1508
19.2k
{
1509
19.2k
    int i=0;
1510
19.2k
    gs_halftone *pht = (gs_halftone *)data;
1511
19.2k
    gs_halftone_component comp;
1512
1513
38.5k
    for (i=0;i< pht->params.multiple.num_comp;i++) {
1514
19.2k
        comp = pht->params.multiple.components[i];
1515
19.2k
        switch(comp.type) {
1516
0
            case ht_type_threshold:
1517
0
                if (comp.params.threshold.thresholds.data != NULL)
1518
0
                    gs_free_object(memory, (byte *)comp.params.threshold.thresholds.data, "pdfi_free_halftone - thresholds");
1519
0
                break;
1520
0
            case ht_type_threshold2:
1521
0
                if (comp.params.threshold2.thresholds.data != NULL)
1522
0
                    gs_free_object(memory, (byte *)comp.params.threshold2.thresholds.data, "pdfi_free_halftone - thresholds");
1523
0
                break;
1524
19.2k
            default:
1525
19.2k
                break;
1526
19.2k
        }
1527
19.2k
    }
1528
19.2k
    gs_free_object(memory, pht->params.multiple.components, "pdfi_free_halftone");
1529
19.2k
    gs_free_object(memory, pht, "pdfi_free_halftone");
1530
19.2k
}
1531
1532
static int build_type5_halftone(pdf_context *ctx, pdf_dict *halftone_dict, pdf_dict *page_dict, gx_device_halftone *pdht, gs_halftone *pht)
1533
0
{
1534
0
    int code, code1, str_len, comp_number;
1535
0
    int64_t type;
1536
0
    char *str = NULL;
1537
0
    bool known = false;
1538
0
    gs_halftone_component *phtc = NULL, *phtc1;
1539
0
    gx_ht_order_component *pocs = 0;
1540
0
    pdf_obj *Key = NULL, *Value = NULL;
1541
0
    uint64_t index = 0, ix = 0;
1542
0
    int NumComponents = 0;
1543
0
    gx_ht_order *porder1 = NULL;
1544
0
    pdf_dict *subdict = NULL;
1545
1546
    /* The only case involving multiple halftones, we need to enumerate each entry
1547
     * in the dictionary
1548
     */
1549
    /* Type 5 halftone dictionaries are required to have a Default */
1550
0
    code = pdfi_dict_known(ctx, halftone_dict, "Default", &known);
1551
0
    if (code < 0)
1552
0
        return code;
1553
0
    if (!known) {
1554
0
        code = gs_note_error(gs_error_undefined);
1555
0
        return code;
1556
0
    }
1557
1558
0
    code = pdfi_loop_detector_mark(ctx);
1559
0
    if (code < 0)
1560
0
        goto error;
1561
0
    code = pdfi_dict_first(ctx, halftone_dict, &Key, &Value, &index);
1562
0
    code1 = pdfi_loop_detector_cleartomark(ctx);
1563
0
    if (code < 0)
1564
0
        goto error;
1565
0
    if (code1 < 0) {
1566
0
        code = code1;
1567
0
        goto error;
1568
0
    }
1569
1570
    /* First establish the number of components from the halftone which we will use.
1571
     * If the component number is GX_DEVICE_COLOR_MAX_COMPONENTS then its the default,
1572
     * if its < 0 then its not available in the device. Otherwise its a colorant which is
1573
     * being rendered, so we need to set that halftone component. The Default will be
1574
     * stored in the device halftone order rather than in the component array order
1575
     * members.
1576
     */
1577
0
    do {
1578
0
        if (pdfi_type_of(Key) != PDF_NAME) {
1579
0
            code = gs_note_error(gs_error_typecheck);
1580
0
            goto error;
1581
0
        }
1582
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")) {
1583
0
            code = pdfi_string_from_name(ctx, (pdf_name *)Key, &str, &str_len);
1584
0
            if (code < 0)
1585
0
                goto error;
1586
1587
0
            comp_number = gs_cname_to_colorant_number(ctx->pgs, (byte *)str, str_len,
1588
0
                                        ht_type_multiple);
1589
0
            if (comp_number >= 0)
1590
0
                NumComponents++;
1591
0
            gs_free_object(ctx->memory, str, "pdfi_string_from_name");
1592
0
            str = NULL;
1593
0
        }
1594
1595
0
        pdfi_countdown(Key);
1596
0
        pdfi_countdown(Value);
1597
0
        Key = Value = NULL;
1598
1599
0
        code = pdfi_loop_detector_mark(ctx);
1600
0
        if (code < 0)
1601
0
            goto error;
1602
0
        code = pdfi_dict_next(ctx, halftone_dict, &Key, &Value, &index);
1603
0
        code1 = pdfi_loop_detector_cleartomark(ctx);
1604
0
        if (code < 0  && code != gs_error_undefined)
1605
0
            goto error;
1606
0
        else if (code1 < 0) {
1607
0
            code = code1;
1608
0
            goto error;
1609
0
        }
1610
0
    } while (code >= 0);
1611
1612
0
    if (NumComponents == 0) {
1613
0
        code = gs_note_error(gs_error_syntaxerror);
1614
0
        goto error;
1615
0
    }
1616
1617
0
    pocs = gs_alloc_struct_array(ctx->memory, NumComponents,
1618
0
                                 gx_ht_order_component,
1619
0
                                 &st_ht_order_component_element,
1620
0
                                 "gs_sethalftone");
1621
0
    if (pocs == NULL)
1622
0
        goto error;
1623
1624
0
    memset(pocs, 0x00, NumComponents * sizeof(gx_ht_order_component));
1625
0
    pdht->components = pocs;
1626
0
    pdht->num_comp = NumComponents;
1627
0
    phtc = (gs_halftone_component *)gs_alloc_bytes(ctx->memory, sizeof(gs_halftone_component) * NumComponents, "pdfi_do_halftone");
1628
0
    if (phtc == 0) {
1629
0
        code = gs_note_error(gs_error_VMerror);
1630
0
        goto error;
1631
0
    }
1632
1633
0
    code = pdfi_loop_detector_mark(ctx);
1634
0
    if (code < 0)
1635
0
        goto error;
1636
0
    code = pdfi_dict_first(ctx, halftone_dict, &Key, &Value, &index);
1637
0
    code1 = pdfi_loop_detector_cleartomark(ctx);
1638
0
    if (code < 0)
1639
0
        goto error;
1640
0
    else if (code1 < 0) {
1641
0
        code = code1;
1642
0
        goto error;
1643
0
    }
1644
1645
    /* index 0 in the component array is reserved for the Default, we can't get here without
1646
     * having a /Default, so we just leave room for it and start filing the other inks from
1647
     * index 1.
1648
     */
1649
0
    ix = 1;
1650
0
    do {
1651
0
        if (pdfi_type_of(Key) != PDF_NAME) {
1652
0
            code = gs_note_error(gs_error_typecheck);
1653
0
            goto error;
1654
0
        }
1655
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")) {
1656
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")) {
1657
0
                code = pdfi_dict_from_obj(ctx, Value, &subdict);
1658
0
                if (code < 0)
1659
0
                    goto error;
1660
1661
0
                code = pdfi_string_from_name(ctx, (pdf_name *)Key, &str, &str_len);
1662
0
                if (code < 0)
1663
0
                    goto error;
1664
1665
0
                comp_number = gs_cname_to_colorant_number(ctx->pgs, (byte *)str, str_len,
1666
0
                                            ht_type_multiple);
1667
0
                if (comp_number >= 0) {
1668
                    /* If comp_number == GX_DEVICE_COLOR_MAX_COMPONENTS then it is the /Default
1669
                     * In that case we want to store it in index 0 of the halftone components array
1670
                     */
1671
0
                    if (comp_number == GX_DEVICE_COLOR_MAX_COMPONENTS) {
1672
0
                        phtc[0].comp_number = comp_number;
1673
0
                        porder1 = &(pdht->components[0].corder);
1674
0
                        pdht->components[0].comp_number = comp_number;
1675
0
                        phtc1 = &phtc[0];
1676
0
                    } else {
1677
0
                        phtc[ix].comp_number = comp_number;
1678
0
                        porder1 = &(pdht->components[ix].corder);
1679
0
                        pdht->components[ix].comp_number = phtc[ix].comp_number;
1680
0
                        phtc1 = &phtc[ix++];
1681
0
                    }
1682
1683
0
                    code = pdfi_dict_get_int(ctx, subdict, "HalftoneType", &type);
1684
0
                    if (code < 0)
1685
0
                        goto error;
1686
1687
0
                    switch(type) {
1688
0
                        case 1:
1689
0
                            code = build_type1_halftone(ctx, (pdf_dict *)Value, page_dict, porder1, phtc1, str, str_len, comp_number);
1690
0
                            if (code < 0)
1691
0
                                goto error;
1692
0
                            break;
1693
0
                        case 6:
1694
0
                            if (pdfi_type_of(Value) != PDF_STREAM) {
1695
0
                                code = gs_note_error(gs_error_typecheck);
1696
0
                                goto error;
1697
0
                            }
1698
0
                            code = build_type6_halftone(ctx, (pdf_stream *)Value, page_dict, porder1, phtc1, str, str_len);
1699
0
                            if (code < 0)
1700
0
                                goto error;
1701
0
                            break;
1702
0
                        case 10:
1703
0
                            if (pdfi_type_of(Value) != PDF_STREAM) {
1704
0
                                code = gs_note_error(gs_error_typecheck);
1705
0
                                goto error;
1706
0
                            }
1707
0
                            code = build_type10_halftone(ctx, (pdf_stream *)Value, page_dict, porder1, phtc1, str, str_len);
1708
0
                            if (code < 0)
1709
0
                                goto error;
1710
0
                            break;
1711
0
                        case 16:
1712
0
                            if (pdfi_type_of(Value) != PDF_STREAM) {
1713
0
                                code = gs_note_error(gs_error_typecheck);
1714
0
                                goto error;
1715
0
                            }
1716
0
                            code = build_type16_halftone(ctx, (pdf_stream *)Value, page_dict, porder1, phtc1, str, str_len);
1717
0
                            if (code < 0)
1718
0
                                goto error;
1719
0
                            break;
1720
0
                        default:
1721
0
                            code = gs_note_error(gs_error_rangecheck);
1722
0
                            goto error;
1723
0
                            break;
1724
1725
0
                    }
1726
0
                    gs_free_object(ctx->memory, str, "pdfi_string_from_name");
1727
0
                    str = NULL;
1728
0
                } else {
1729
0
                    gs_free_object(ctx->memory, str, "pdfi_string_from_name");
1730
0
                    str = NULL;
1731
0
                }
1732
0
            }
1733
0
        }
1734
1735
0
        pdfi_countdown(Key);
1736
0
        pdfi_countdown(Value);
1737
0
        Key = Value = NULL;
1738
1739
0
        code = pdfi_loop_detector_mark(ctx);
1740
0
        if (code < 0)
1741
0
            goto error;
1742
0
        code = pdfi_dict_next(ctx, halftone_dict, &Key, &Value, &index);
1743
0
        code1 = pdfi_loop_detector_cleartomark(ctx);
1744
0
        if (code < 0 && code != gs_error_undefined)
1745
0
            goto error;
1746
0
        else if (code1 < 0) {
1747
0
            code = code1;
1748
0
            goto error;
1749
0
        }
1750
0
    } while (code >= 0);
1751
0
    code = 0;
1752
1753
    /* If we only had one component, it must be the Default, in which case we
1754
     * do not need the components array. So we can copy the order from the 0th
1755
     * index of the components array (Default is stored at index 0) to the
1756
     * device halftone order, and free the components array.
1757
     */
1758
0
    pdht->order = pdht->components[0].corder;
1759
0
    if (ix == 1) {
1760
0
        gs_free_object(ctx->memory, pocs, "pdfi_build_type5_halftone");
1761
0
        pdht->components = 0;
1762
0
        pdht->num_comp = 0;
1763
0
    } else {
1764
0
        pdht->components = pocs;
1765
0
        pdht->num_comp = ix;
1766
0
    }
1767
1768
0
    pht->type = ht_type_multiple;
1769
0
    pht->params.multiple.components = phtc;
1770
0
    pht->params.multiple.num_comp = NumComponents;
1771
0
    pht->params.multiple.get_colorname_string = pdfi_separation_name_from_index;
1772
1773
0
    return 0;
1774
1775
0
error:
1776
0
    pdfi_countdown(Key);
1777
0
    pdfi_countdown(Value);
1778
0
    gs_free_object(ctx->memory, str, "pdfi_string_from_name");
1779
0
    gs_free_object(ctx->memory, pocs, "pdfi_build_type5_halftone");
1780
0
    gs_free_object(ctx->memory, phtc, "pdfi_build_type5_halftone");
1781
0
    pht->params.multiple.components = NULL;
1782
0
    pht->params.multiple.num_comp = 0;
1783
0
    pdht->components = NULL;
1784
0
    pdht->num_comp = 0;
1785
0
    return code;
1786
0
}
1787
1788
static int pdfi_do_halftone(pdf_context *ctx, pdf_obj *halftone_obj, pdf_dict *page_dict)
1789
19.2k
{
1790
19.2k
    int code;
1791
19.2k
    char *str = NULL;
1792
19.2k
    int64_t type;
1793
19.2k
    gs_halftone *pht = NULL;
1794
19.2k
    gx_device_halftone *pdht = NULL;
1795
19.2k
    gs_halftone_component *phtc = NULL;
1796
19.2k
    pdf_obj *Key = NULL, *Value = NULL, *transfer = NULL;
1797
19.2k
    pdf_dict *halftone_dict = NULL;
1798
19.2k
    gx_transfer_map *pmap = NULL;
1799
1800
19.2k
    code = pdfi_dict_from_obj(ctx, halftone_obj, &halftone_dict);
1801
19.2k
    if (code < 0)
1802
0
        return code;
1803
1804
19.2k
    code = pdfi_dict_get_int(ctx, halftone_dict, "HalftoneType", &type);
1805
19.2k
    if (code < 0)
1806
0
        return code;
1807
1808
19.2k
    pht = (gs_halftone *)gs_alloc_bytes(ctx->memory, sizeof(gs_halftone), "pdfi_do_halftone");
1809
19.2k
    if (pht == 0) {
1810
0
        code = gs_note_error(gs_error_VMerror);
1811
0
        goto error;
1812
0
    }
1813
19.2k
    memset(pht, 0x00, sizeof(gs_halftone));
1814
19.2k
    pht->rc.memory = ctx->memory;
1815
19.2k
    pht->rc.free = pdfi_free_halftone;
1816
1817
19.2k
    pdht = (gx_device_halftone *)gs_alloc_bytes(ctx->memory, sizeof(gx_device_halftone), "pdfi_do_halftone");
1818
19.2k
    if (pdht == 0) {
1819
0
        code = gs_note_error(gs_error_VMerror);
1820
0
        goto error;
1821
0
    }
1822
19.2k
    memset(pdht, 0x00, sizeof(gx_device_halftone));
1823
19.2k
    pdht->num_dev_comp = ctx->pgs->device->color_info.num_components;
1824
19.2k
    pdht->rc.memory = ctx->memory;
1825
1826
19.2k
    switch(type) {
1827
19.2k
        case 1:
1828
19.2k
            phtc = (gs_halftone_component *)gs_alloc_bytes(ctx->memory, sizeof(gs_halftone_component), "pdfi_do_halftone");
1829
19.2k
            if (phtc == 0) {
1830
0
                code = gs_note_error(gs_error_VMerror);
1831
0
                goto error;
1832
0
            }
1833
1834
19.2k
            code = build_type1_halftone(ctx, halftone_dict, page_dict, &pdht->order, phtc, (char *)"Default", 7, -1);
1835
19.2k
            if (code < 0)
1836
12
                goto error;
1837
1838
19.2k
            pht->type = ht_type_multiple;
1839
19.2k
            pht->params.multiple.components = phtc;
1840
19.2k
            pht->params.multiple.num_comp = 1;
1841
19.2k
            pht->params.multiple.get_colorname_string = pdfi_separation_name_from_index;
1842
19.2k
            code = gx_gstate_dev_ht_install(ctx->pgs, pdht, pht->type, gs_currentdevice_inline(ctx->pgs), HT_OBJTYPE_DEFAULT);
1843
19.2k
            if (code < 0)
1844
0
                goto error;
1845
1846
19.2k
            gx_device_halftone_release(pdht, pdht->rc.memory);
1847
19.2k
            rc_decrement(ctx->pgs->halftone, "pdfi_do_halftone(halftone)");
1848
19.2k
            ctx->pgs->halftone = pht;
1849
19.2k
            rc_increment(ctx->pgs->halftone);
1850
19.2k
            gx_unset_both_dev_colors(ctx->pgs);
1851
19.2k
            break;
1852
1853
0
        case 5:
1854
0
            code = build_type5_halftone(ctx, halftone_dict, page_dict, pdht, pht);
1855
0
            if (code < 0)
1856
0
                goto error;
1857
1858
            /* build_type5_halftone does the work of gs_sethalftone_prepare as well, so we don't need that here */
1859
1860
0
            code = gx_gstate_dev_ht_install(ctx->pgs, pdht, pht->type, gs_currentdevice_inline(ctx->pgs), HT_OBJTYPE_DEFAULT);
1861
0
            if (code < 0)
1862
0
                goto error;
1863
1864
0
            gx_device_halftone_release(pdht, pdht->rc.memory);
1865
0
            rc_decrement(ctx->pgs->halftone, "");
1866
0
            ctx->pgs->halftone = pht;
1867
0
            rc_increment(ctx->pgs->halftone);
1868
0
            gx_unset_both_dev_colors(ctx->pgs);
1869
0
            break;
1870
1871
0
        case 6:
1872
0
            if (pdfi_type_of(halftone_obj) != PDF_STREAM)
1873
0
                return_error(gs_error_typecheck);
1874
0
            phtc = (gs_halftone_component *)gs_alloc_bytes(ctx->memory, sizeof(gs_halftone_component), "pdfi_do_halftone");
1875
0
            if (phtc == 0) {
1876
0
                code = gs_note_error(gs_error_VMerror);
1877
0
                goto error;
1878
0
            }
1879
1880
0
            code = build_type6_halftone(ctx, (pdf_stream *)halftone_obj, page_dict, &pdht->order, phtc, (char *)"Default", 7);
1881
0
            if (code < 0)
1882
0
                goto error;
1883
1884
0
            pht->type = ht_type_multiple;
1885
0
            pht->params.multiple.components = phtc;
1886
0
            pht->params.multiple.num_comp = 1;
1887
0
            pht->params.multiple.get_colorname_string = pdfi_separation_name_from_index;
1888
1889
0
            code = gs_sethalftone_prepare(ctx->pgs, pht, pdht);
1890
0
            if (code < 0)
1891
0
                goto error;
1892
1893
            /* Transfer function pdht->order->transfer */
1894
0
            if (pdfi_dict_knownget(ctx, ((pdf_stream *)halftone_obj)->stream_dict, "TransferFunction", &transfer) > 0) {
1895
0
                switch (pdfi_type_of(transfer)) {
1896
0
                    case PDF_NAME:
1897
                        /* As far as I can tell, only /Identity is valid as a name, so we can just ignore
1898
                         * names, if it's not Identity it would be an error (which we would ignore) and if
1899
                         * it is, it has no effect. So what's the point ?
1900
                         */
1901
0
                        break;
1902
0
                    case PDF_STREAM:
1903
                        /* If we get an error here, we can just ignore it, and not apply the transfer */
1904
0
                        code = pdfi_evaluate_transfer(ctx, transfer, page_dict, &pmap);
1905
0
                        if (code >= 0) {
1906
0
                            pdht->order.transfer = pmap;
1907
0
                        }
1908
0
                        break;
1909
0
                    default:
1910
                        /* should be an error, but we can just ignore it */
1911
0
                        pdfi_set_warning(ctx, 0, NULL, W_PDF_TYPECHECK, "do_halftone", NULL);
1912
0
                        break;
1913
0
                }
1914
0
                pdfi_countdown(transfer);
1915
0
            }
1916
1917
0
            code = gx_gstate_dev_ht_install(ctx->pgs, pdht, pht->type, gs_currentdevice_inline(ctx->pgs), HT_OBJTYPE_DEFAULT);
1918
0
            if (code < 0)
1919
0
                goto error;
1920
1921
0
            gx_device_halftone_release(pdht, pdht->rc.memory);
1922
0
            rc_decrement(ctx->pgs->halftone, "pdfi_do_halftone(halftone)");
1923
0
            ctx->pgs->halftone = pht;
1924
0
            rc_increment(ctx->pgs->halftone);
1925
0
            gx_unset_both_dev_colors(ctx->pgs);
1926
0
            break;
1927
0
        case 10:
1928
0
            if (pdfi_type_of(halftone_obj) != PDF_STREAM)
1929
0
                return_error(gs_error_typecheck);
1930
0
            phtc = (gs_halftone_component *)gs_alloc_bytes(ctx->memory, sizeof(gs_halftone_component), "pdfi_do_halftone");
1931
0
            if (phtc == 0) {
1932
0
                code = gs_note_error(gs_error_VMerror);
1933
0
                goto error;
1934
0
            }
1935
1936
0
            code = build_type10_halftone(ctx, (pdf_stream *)halftone_obj, page_dict, &pdht->order, phtc, (char *)"Default", 7);
1937
0
            if (code < 0)
1938
0
                goto error;
1939
1940
0
            pht->type = ht_type_multiple;
1941
0
            pht->params.multiple.components = phtc;
1942
0
            pht->params.multiple.num_comp = 1;
1943
0
            pht->params.multiple.get_colorname_string = pdfi_separation_name_from_index;
1944
1945
0
            code = gs_sethalftone_prepare(ctx->pgs, pht, pdht);
1946
0
            if (code < 0)
1947
0
                goto error;
1948
1949
            /* Transfer function pdht->order->transfer */
1950
0
            if (pdfi_dict_knownget(ctx, ((pdf_stream *)halftone_obj)->stream_dict, "TransferFunction", &transfer) > 0) {
1951
0
                switch (pdfi_type_of(transfer)) {
1952
0
                    case PDF_NAME:
1953
                        /* As far as I can tell, only /Identity is valid as a name, so we can just ignore
1954
                         * names, if it's not Identity it would be an error (which we would ignore) and if
1955
                         * it is, it has no effect. So what's the point ?
1956
                         */
1957
0
                        break;
1958
0
                    case PDF_STREAM:
1959
                        /* If we get an error here, we can just ignore it, and not apply the transfer */
1960
0
                        code = pdfi_evaluate_transfer(ctx, transfer, page_dict, &pmap);
1961
0
                        if (code >= 0) {
1962
0
                            pdht->order.transfer = pmap;
1963
0
                        }
1964
0
                        break;
1965
0
                    default:
1966
                        /* should be an error, but we can just ignore it */
1967
0
                        pdfi_set_warning(ctx, 0, NULL, W_PDF_TYPECHECK, "do_halftone", NULL);
1968
0
                        break;
1969
0
                }
1970
0
                pdfi_countdown(transfer);
1971
0
            }
1972
1973
0
            code = gx_gstate_dev_ht_install(ctx->pgs, pdht, pht->type, gs_currentdevice_inline(ctx->pgs), HT_OBJTYPE_DEFAULT);
1974
0
            if (code < 0)
1975
0
                goto error;
1976
1977
0
            gx_device_halftone_release(pdht, pdht->rc.memory);
1978
0
            rc_decrement(ctx->pgs->halftone, "pdfi_do_halftone(halftone)");
1979
0
            ctx->pgs->halftone = pht;
1980
0
            rc_increment(ctx->pgs->halftone);
1981
0
            gx_unset_both_dev_colors(ctx->pgs);
1982
0
            break;
1983
0
        case 16:
1984
0
            if (pdfi_type_of(halftone_obj) != PDF_STREAM)
1985
0
                return_error(gs_error_typecheck);
1986
0
            phtc = (gs_halftone_component *)gs_alloc_bytes(ctx->memory, sizeof(gs_halftone_component), "pdfi_do_halftone");
1987
0
            if (phtc == 0) {
1988
0
                code = gs_note_error(gs_error_VMerror);
1989
0
                goto error;
1990
0
            }
1991
1992
0
            code = build_type16_halftone(ctx, (pdf_stream *)halftone_obj, page_dict, &pdht->order, phtc, (char *)"Default", 7);
1993
0
            if (code < 0)
1994
0
                goto error;
1995
1996
0
            pht->type = ht_type_multiple;
1997
0
            pht->params.multiple.components = phtc;
1998
0
            pht->params.multiple.num_comp = 1;
1999
0
            pht->params.multiple.get_colorname_string = pdfi_separation_name_from_index;
2000
2001
0
            code = gs_sethalftone_prepare(ctx->pgs, pht, pdht);
2002
0
            if (code < 0)
2003
0
                goto error;
2004
2005
            /* Transfer function pdht->order->transfer */
2006
0
            if (pdfi_dict_knownget(ctx, ((pdf_stream *)halftone_obj)->stream_dict, "TransferFunction", &transfer) > 0) {
2007
0
                switch (pdfi_type_of(transfer)) {
2008
0
                    case PDF_NAME:
2009
                        /* As far as I can tell, only /Identity is valid as a name, so we can just ignore
2010
                         * names, if it's not Identity it would be an error (which we would ignore) and if
2011
                         * it is, it has no effect. So what's the point ?
2012
                         */
2013
0
                        break;
2014
0
                    case PDF_STREAM:
2015
                        /* If we get an error here, we can just ignore it, and not apply the transfer */
2016
0
                        code = pdfi_evaluate_transfer(ctx, transfer, page_dict, &pmap);
2017
0
                        if (code >= 0) {
2018
0
                            pdht->order.transfer = pmap;
2019
0
                        }
2020
0
                        break;
2021
0
                    default:
2022
                        /* should be an error, but we can just ignore it */
2023
0
                        pdfi_set_warning(ctx, 0, NULL, W_PDF_TYPECHECK, "do_halftone", NULL);
2024
0
                        break;
2025
0
                }
2026
0
                pdfi_countdown(transfer);
2027
0
            }
2028
2029
0
            code = gx_gstate_dev_ht_install(ctx->pgs, pdht, pht->type, gs_currentdevice_inline(ctx->pgs), HT_OBJTYPE_DEFAULT);
2030
0
            if (code < 0)
2031
0
                goto error;
2032
2033
0
            gx_device_halftone_release(pdht, pdht->rc.memory);
2034
0
            rc_decrement(ctx->pgs->halftone, "pdfi_do_halftone(halftone)");
2035
0
            ctx->pgs->halftone = pht;
2036
0
            rc_increment(ctx->pgs->halftone);
2037
0
            gx_unset_both_dev_colors(ctx->pgs);
2038
0
            break;
2039
0
        default:
2040
0
            code = gs_note_error(gs_error_rangecheck);
2041
0
            goto error;
2042
0
            break;
2043
19.2k
    }
2044
19.2k
    gs_free_object(ctx->memory, pdht, "pdfi_do_halftone");
2045
19.2k
    return 0;
2046
2047
12
error:
2048
12
    if (pdht != NULL)
2049
12
        gx_device_halftone_release(pdht, pdht->rc.memory);
2050
12
    gs_free_object(ctx->memory, str, "pdfi_string_from_name");
2051
12
    pdfi_countdown(Key);
2052
12
    pdfi_countdown(Value);
2053
12
    gs_free_object(ctx->memory, pht, "pdfi_do_halftone");
2054
12
    gs_free_object(ctx->memory, phtc, "pdfi_do_halftone");
2055
12
    gs_free_object(ctx->memory, pdht, "pdfi_do_halftone");
2056
12
    return code;
2057
19.2k
}
2058
2059
static int GS_HT(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
2060
21.0k
{
2061
21.0k
    int code;
2062
21.0k
    pdf_obj *obj = NULL;
2063
2064
21.0k
    code = pdfi_dict_get(ctx, GS, "HT", &obj);
2065
21.0k
    if (code < 0)
2066
0
        return code;
2067
2068
2069
21.0k
    if (pdfi_type_of(obj) == PDF_NAME) {
2070
1.78k
        if (pdfi_name_is((const pdf_name *)obj, "Default")) {
2071
1.78k
            goto exit;
2072
1.78k
        } else {
2073
0
            code = gs_note_error(gs_error_rangecheck);
2074
0
            goto exit;
2075
0
        }
2076
19.2k
    } else {
2077
19.2k
        code = pdfi_do_halftone(ctx, obj, page_dict);
2078
19.2k
    }
2079
19.2k
    if (code < 0) {
2080
12
        code = pdfi_set_error_stop(ctx, code, NULL, E_BAD_HALFTONE, "GS_HT", "Halftone will be ignored");
2081
12
    }
2082
2083
21.0k
exit:
2084
21.0k
    pdfi_countdown(obj);
2085
21.0k
    return code;
2086
19.2k
}
2087
2088
static int GS_FL(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
2089
0
{
2090
0
    int code;
2091
0
    double d1;
2092
2093
0
    code = pdfi_dict_get_number(ctx, GS, "FL", &d1);
2094
0
    if (code < 0)
2095
0
        return code;
2096
2097
0
    code = gs_setflat(ctx->pgs, d1);
2098
0
    return code;
2099
0
}
2100
2101
static int GS_SM(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
2102
46.4k
{
2103
46.4k
    int code;
2104
46.4k
    double d1;
2105
2106
46.4k
    code = pdfi_dict_get_number(ctx, GS, "SM", &d1);
2107
46.4k
    if (code < 0)
2108
0
        return code;
2109
2110
46.4k
    code = gs_setsmoothness(ctx->pgs, d1);
2111
46.4k
    return code;
2112
46.4k
}
2113
2114
static int GS_SA(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
2115
153k
{
2116
153k
    bool b;
2117
153k
    int code;
2118
2119
153k
    code = pdfi_dict_get_bool(ctx, GS, "SA", &b);
2120
153k
    if (code < 0)
2121
14
        return code;
2122
2123
153k
    return gs_setstrokeadjust(ctx->pgs, b);
2124
153k
}
2125
2126
static int GS_BM(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
2127
224k
{
2128
224k
    pdf_name *n;
2129
224k
    int code;
2130
224k
    gs_blend_mode_t mode = 0; /* Start with /Normal */
2131
2132
224k
    code = pdfi_dict_get(ctx, GS, "BM", (pdf_obj **)&n);
2133
224k
    if (code < 0)
2134
0
        return code;
2135
2136
224k
    if (pdfi_type_of(n) == PDF_ARRAY) {
2137
46
        int i;
2138
46
        pdf_array *a = (pdf_array *)n;
2139
2140
46
        for (i=0;i < pdfi_array_size(a);i++){
2141
46
            code = pdfi_array_get_type(ctx, a, i, PDF_NAME, (pdf_obj **)&n);
2142
46
            if (code < 0)
2143
0
                continue;
2144
46
            code = pdfi_get_blend_mode(ctx, n, &mode);
2145
46
            pdfi_countdown(n);
2146
46
            if (code == 0)
2147
46
                break;
2148
46
        }
2149
46
        pdfi_countdown(a);
2150
46
        return gs_setblendmode(ctx->pgs, mode);
2151
46
    }
2152
2153
224k
    if (pdfi_type_of(n) == PDF_NAME) {
2154
224k
        code = pdfi_get_blend_mode(ctx, n, &mode);
2155
224k
        pdfi_countdown(n);
2156
224k
        if (code == 0)
2157
223k
            return gs_setblendmode(ctx->pgs, mode);
2158
224k
        return_error(gs_error_undefined);
2159
224k
    }
2160
224k
    return_error(gs_error_typecheck);
2161
224k
}
2162
2163
static int GS_SMask(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
2164
118k
{
2165
118k
    pdf_obj *o = NULL;
2166
118k
    pdfi_int_gstate *igs = (pdfi_int_gstate *)ctx->pgs->client_data;
2167
118k
    int code;
2168
118k
    bool Processed;
2169
2170
118k
    if (ctx->page.has_transparency == false || ctx->args.notransparency == true)
2171
26.3k
        return 0;
2172
2173
92.6k
    code = pdfi_dict_get(ctx, GS, "SMask", (pdf_obj **)&o);
2174
92.6k
    if (code < 0)
2175
322
        return code;
2176
2177
92.2k
    switch (pdfi_type_of(o)) {
2178
86.4k
        case PDF_NAME:
2179
86.4k
        {
2180
86.4k
            pdf_name *n = (pdf_name *)o;
2181
2182
86.4k
            if (pdfi_name_is(n, "None")) {
2183
86.4k
                if (igs->SMask) {
2184
6.66k
                    pdfi_gstate_smask_free(igs);
2185
6.66k
                    code = pdfi_trans_end_smask_notify(ctx);
2186
6.66k
                }
2187
86.4k
                goto exit;
2188
86.4k
            }
2189
54
            code = pdfi_find_resource(ctx, (unsigned char *)"ExtGState", n, stream_dict, page_dict, &o);
2190
54
            pdfi_countdown(n);
2191
54
            if (code < 0)
2192
54
                return code;
2193
0
            break;
2194
54
        }
2195
2196
5.78k
        case PDF_DICT:
2197
5.78k
        {
2198
5.78k
            code = pdfi_dict_knownget_bool(ctx, (pdf_dict *)o, "Processed", &Processed);
2199
            /* Need to clear the Processed flag in the SMask if another value is set
2200
             * (even if it's the same SMask?)
2201
             * TODO: I think there is a better way to do this that doesn't require sticking this
2202
             * flag in the SMask dictionary.  But for now, let's get correct behavior.
2203
             */
2204
5.78k
            if (code > 0 && Processed) {
2205
281
                code = pdfi_dict_put_bool(ctx, (pdf_dict *)o, "Processed", false);
2206
281
                if (code < 0)
2207
0
                    return code;
2208
281
            }
2209
5.78k
            if (igs->SMask)
2210
1.88k
                pdfi_gstate_smask_free(igs);
2211
            /* We need to use the graphics state memory, in case we are running under Ghostscript. */
2212
5.78k
            pdfi_gstate_smask_install(igs, ctx->pgs->memory, (pdf_dict *)o, ctx->pgs);
2213
5.78k
            break;
2214
5.78k
        }
2215
2216
16
        default:
2217
16
            break;
2218
92.2k
    }
2219
2220
92.2k
 exit:
2221
92.2k
    pdfi_countdown(o);
2222
92.2k
    return 0;
2223
92.2k
}
2224
2225
static int GS_CA(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
2226
228k
{
2227
228k
    int code;
2228
228k
    double d1;
2229
2230
228k
    code = pdfi_dict_get_number(ctx, GS, "CA", &d1);
2231
228k
    if (code < 0)
2232
0
        return code;
2233
2234
228k
    if (d1 > 1.0) {
2235
295
        pdfi_set_warning(ctx, 0, NULL, W_PDF_CA_OUTOFRANGE, "GS_CA", NULL);
2236
295
        d1 = 1.0;
2237
295
    }
2238
2239
228k
    if (d1 < 0.0) {
2240
31
        pdfi_set_warning(ctx, 0, NULL, W_PDF_CA_OUTOFRANGE, "GS_CA", NULL);
2241
31
        d1 = 0.0;
2242
31
    }
2243
2244
228k
    code = gs_setstrokeconstantalpha(ctx->pgs, d1);
2245
228k
    return code;
2246
228k
}
2247
2248
static int GS_ca(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
2249
226k
{
2250
226k
    int code;
2251
226k
    double d1;
2252
2253
226k
    code = pdfi_dict_get_number(ctx, GS, "ca", &d1);
2254
226k
    if (code < 0)
2255
0
        return code;
2256
2257
226k
    if (d1 > 1.0) {
2258
218
        pdfi_set_warning(ctx, 0, NULL, W_PDF_CA_OUTOFRANGE, "GS_ca", NULL);
2259
218
        d1 = 1.0;
2260
218
    }
2261
2262
226k
    if (d1 < 0.0) {
2263
30
        pdfi_set_warning(ctx, 0, NULL, W_PDF_CA_OUTOFRANGE, "GS_ca", NULL);
2264
30
        d1 = 0.0;
2265
30
    }
2266
2267
226k
    code = gs_setfillconstantalpha(ctx->pgs, d1);
2268
226k
    return code;
2269
226k
}
2270
2271
static int GS_AIS(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
2272
114k
{
2273
114k
    bool b;
2274
114k
    int code;
2275
2276
114k
    code = pdfi_dict_get_bool(ctx, GS, "AIS", &b);
2277
114k
    if (code < 0)
2278
0
        return code;
2279
2280
114k
    return gs_setalphaisshape(ctx->pgs, b);
2281
114k
}
2282
2283
static int GS_TK(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
2284
12.0k
{
2285
12.0k
    bool b;
2286
12.0k
    int code;
2287
2288
12.0k
    code = pdfi_dict_get_bool(ctx, GS, "TK", &b);
2289
12.0k
    if (code < 0)
2290
0
        return code;
2291
2292
12.0k
    return gs_settextknockout(ctx->pgs, b);
2293
12.0k
}
2294
2295
typedef int (*GS_proc)(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict);
2296
2297
typedef struct GS_Func {
2298
    const char *Name;
2299
    GS_proc proc;
2300
} GS_Func_t;
2301
2302
GS_Func_t ExtGStateTable[] = {
2303
    {"LW", GS_LW},
2304
    {"LC", GS_LC},
2305
    {"LJ", GS_LJ},
2306
    {"ML", GS_ML},
2307
    {"D", GS_D},
2308
    {"RI", GS_RI},
2309
    {"OP", GS_OP},
2310
    {"op", GS_op},
2311
    {"OPM", GS_OPM},
2312
    {"Font", GS_Font},
2313
    {"BG", GS_BG},
2314
    {"BG2", GS_BG2},
2315
    {"UCR", GS_UCR},
2316
    {"UCR2", GS_UCR2},
2317
    {"TR", GS_TR},
2318
    {"TR2", GS_TR2},
2319
    {"HT", GS_HT},
2320
    {"FL", GS_FL},
2321
    {"SM", GS_SM},
2322
    {"SA", GS_SA},
2323
    {"BM", GS_BM},
2324
    {"SMask", GS_SMask},
2325
    {"CA", GS_CA},
2326
    {"ca", GS_ca},
2327
    {"AIS", GS_AIS},
2328
    {"TK", GS_TK},
2329
};
2330
2331
/* Set gstate from dictionary
2332
 * NOTE: stream_dict may not be needed and can currently be NULL.
2333
 * If we decide it can't be NULL, check Patterns implementation to refactor it to pass that param.
2334
 */
2335
int pdfi_set_ExtGState(pdf_context *ctx, pdf_dict *stream_dict,
2336
                       pdf_dict *page_dict, pdf_dict *gstate_dict)
2337
383k
{
2338
383k
    int code, i, limit = sizeof(ExtGStateTable) / sizeof (GS_Func_t);
2339
383k
    bool known;
2340
2341
10.3M
    for (i=0;i < limit; i++) {
2342
9.96M
        code = pdfi_dict_known(ctx, gstate_dict, ExtGStateTable[i].Name, &known);
2343
9.96M
        if (code < 0)
2344
0
            break;
2345
9.96M
        if (known) {
2346
1.62M
            code = ExtGStateTable[i].proc(ctx, gstate_dict, NULL, page_dict);
2347
1.62M
            if (code < 0)
2348
1.50k
                break;
2349
1.62M
        }
2350
9.96M
    }
2351
383k
    return code;
2352
383k
}
2353
2354
int pdfi_setgstate(pdf_context *ctx, pdf_dict *stream_dict, pdf_dict *page_dict)
2355
557k
{
2356
557k
    pdf_name *n = NULL;
2357
557k
    pdf_obj *o = NULL;
2358
557k
    int code=0, code1 = 0;
2359
2360
557k
    code = pdfi_loop_detector_mark(ctx);
2361
557k
    if (code < 0)
2362
0
        return code;
2363
2364
557k
    if (pdfi_count_stack(ctx) < 1) {
2365
20.4k
        code = gs_note_error(gs_error_stackunderflow);
2366
20.4k
        goto setgstate_error;
2367
20.4k
    }
2368
536k
    n = (pdf_name *)ctx->stack_top[-1];
2369
536k
    pdfi_countup(n);
2370
536k
    pdfi_pop(ctx, 1);
2371
2372
536k
    if (pdfi_type_of(n) != PDF_NAME) {
2373
13.6k
        code = gs_note_error(gs_error_typecheck);
2374
13.6k
        goto setgstate_error;
2375
13.6k
    }
2376
2377
522k
    code = pdfi_find_resource(ctx, (unsigned char *)"ExtGState", n, (pdf_dict *)stream_dict,
2378
522k
                              page_dict, &o);
2379
522k
    if (code < 0)
2380
136k
        goto setgstate_error;
2381
2382
386k
    if (pdfi_type_of(o) != PDF_DICT) {
2383
3.22k
        code = gs_note_error(gs_error_typecheck);
2384
3.22k
        goto setgstate_error;
2385
3.22k
    }
2386
2387
383k
    code = pdfi_set_ExtGState(ctx, stream_dict, page_dict, (pdf_dict *)o);
2388
2389
557k
setgstate_error:
2390
557k
    code1 = pdfi_loop_detector_cleartomark(ctx);
2391
557k
    if (code == 0) code = code1;
2392
2393
557k
    pdfi_countdown(n);
2394
557k
    pdfi_countdown(o);
2395
557k
    return code;
2396
383k
}
2397
2398
2399
int pdfi_free_DefaultQState(pdf_context *ctx)
2400
871k
{
2401
871k
    if (ctx->DefaultQState)
2402
672k
        gs_gstate_free(ctx->DefaultQState);
2403
871k
    ctx->DefaultQState = NULL;
2404
871k
    return 0;
2405
871k
}
2406
2407
int pdfi_set_DefaultQState(pdf_context *ctx, gs_gstate *pgs)
2408
672k
{
2409
672k
    pdfi_free_DefaultQState(ctx);
2410
    /* We need to use the graphics state memory, in case we are running under Ghostscript. */
2411
672k
    ctx->DefaultQState = gs_gstate_copy(pgs, ctx->pgs->memory);
2412
672k
    if (ctx->DefaultQState == NULL)
2413
0
        return_error(gs_error_VMerror);
2414
672k
    return 0;
2415
672k
}
2416
2417
gs_gstate *pdfi_get_DefaultQState(pdf_context *ctx)
2418
30.6k
{
2419
30.6k
    return ctx->DefaultQState;
2420
30.6k
}
2421
2422
int pdfi_copy_DefaultQState(pdf_context *ctx, gs_gstate **pgs)
2423
283k
{
2424
    /* We need to use the graphics state memory, in case we are running under Ghostscript. */
2425
283k
    *pgs = gs_gstate_copy(ctx->DefaultQState, ctx->pgs->memory);
2426
283k
    if (*pgs == NULL)
2427
0
        return_error(gs_error_VMerror);
2428
283k
    return 0;
2429
283k
}
2430
2431
int pdfi_restore_DefaultQState(pdf_context *ctx, gs_gstate **pgs)
2432
283k
{
2433
283k
    int code;
2434
2435
283k
    code = pdfi_set_DefaultQState(ctx, *pgs);
2436
283k
    gs_gstate_free(*pgs);
2437
283k
    *pgs = NULL;
2438
283k
    return code;
2439
283k
}