Coverage Report

Created: 2025-06-10 07:27

/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
218k
{
57
218k
    const char **p;
58
59
297k
    for (p = blend_mode_names; *p; ++p) {
60
296k
        if (pdfi_name_is(name, *p)) {
61
217k
            *mode = p - blend_mode_names;
62
217k
            return 0;
63
217k
        }
64
296k
    }
65
733
    return -1;
66
218k
}
67
68
void pdfi_gstate_smask_install(pdfi_int_gstate *igs, gs_memory_t *memory, pdf_dict *SMask, gs_gstate *gstate)
69
64.9M
{
70
64.9M
    void *client_data_save;
71
72
64.9M
    if (!SMask)
73
64.8M
        return;
74
72.9k
    igs->memory = memory;
75
72.9k
    igs->SMask = SMask;
76
72.9k
    pdfi_countup(SMask);
77
72.9k
    client_data_save = gstate->client_data;
78
72.9k
    gstate->client_data = NULL;
79
72.9k
    igs->GroupGState = gs_gstate_copy(gstate, memory);
80
72.9k
    gstate->client_data = client_data_save;
81
72.9k
}
82
83
void pdfi_gstate_smask_free(pdfi_int_gstate *igs)
84
98.5M
{
85
98.5M
    if (!igs->SMask)
86
98.4M
        return;
87
72.9k
    pdfi_countdown(igs->SMask);
88
72.9k
    igs->SMask = NULL;
89
72.9k
    if (igs->GroupGState)
90
72.9k
        gs_gstate_free(igs->GroupGState);
91
72.9k
    igs->GroupGState = NULL;
92
72.9k
}
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
33.5M
{
99
33.5M
    pdfi_int_gstate *igs;
100
101
33.5M
    igs = (pdfi_int_gstate *)gs_alloc_bytes(mem, sizeof(pdfi_int_gstate), "pdfi_gstate_alloc");
102
33.5M
    if (igs == NULL)
103
0
        return NULL;
104
33.5M
    memset(igs, 0, sizeof(pdfi_int_gstate));
105
33.5M
    return igs;
106
33.5M
}
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
64.9M
{
112
64.9M
    const pdfi_int_gstate *igs_from = (const pdfi_int_gstate *)from;
113
64.9M
    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
64.9M
    if (igs_to != NULL) {
119
64.9M
        pdfi_gstate_smask_free(igs_to);
120
64.9M
        pdfi_countdown(igs_to->current_font);
121
64.9M
        *(pdfi_int_gstate *) igs_to = *igs_from;
122
64.9M
        pdfi_countup(igs_to->current_font);
123
64.9M
        pdfi_gstate_smask_install(igs_to, igs_from->memory, igs_from->SMask, igs_from->GroupGState);
124
64.9M
    }
125
64.9M
    return 0;
126
64.9M
}
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
33.5M
{
132
33.5M
    pdfi_int_gstate *igs = (pdfi_int_gstate *)old;
133
33.5M
    if (old == NULL)
134
0
        return;
135
33.5M
    pdfi_gstate_smask_free(igs);
136
33.5M
    pdfi_countdown(igs->current_font);
137
    /* We need to use the graphics state memory, in case we are running under Ghostscript. */
138
33.5M
    gs_free_object(pgs->memory, igs, "pdfi_gstate_free");
139
33.5M
}
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
503k
{
151
503k
    pdfi_int_gstate *igs;
152
153
    /* We need to use the graphics state memory, in case we are running under Ghostscript. */
154
503k
    igs = pdfi_gstate_alloc_cb(pgs->memory);
155
503k
    if (igs == NULL)
156
0
        return_error(gs_error_VMerror);
157
503k
    igs->ctx = ctx;
158
503k
    gs_gstate_set_client(pgs, igs, &pdfi_gstate_procs, true /* TODO: client_has_pattern_streams ? */);
159
503k
    return 0;
160
503k
}
161
162
int pdfi_concat(pdf_context *ctx)
163
3.53M
{
164
3.53M
    int code;
165
3.53M
    double Values[6];
166
3.53M
    gs_matrix m;
167
168
3.53M
    if (pdfi_count_stack(ctx) < 6) {
169
339k
        pdfi_clearstack(ctx);
170
339k
        return_error(gs_error_stackunderflow);
171
339k
    }
172
173
3.19M
    if (ctx->text.BlockDepth != 0)
174
31.4k
        pdfi_set_warning(ctx, 0, NULL, W_PDF_OPINVALIDINTEXT, "pdfi_concat", NULL);
175
176
3.19M
    code = pdfi_destack_reals(ctx, Values, 6);
177
3.19M
    if (code < 0)
178
7.58k
        return code;
179
180
3.18M
    m.xx = (float)Values[0];
181
3.18M
    m.xy = (float)Values[1];
182
3.18M
    m.yx = (float)Values[2];
183
3.18M
    m.yy = (float)Values[3];
184
3.18M
    m.tx = (float)Values[4];
185
3.18M
    m.ty = (float)Values[5];
186
187
3.18M
    return gs_concat(ctx->pgs, (const gs_matrix *)&m);
188
3.19M
}
189
190
int pdfi_op_q(pdf_context *ctx)
191
5.42M
{
192
5.42M
    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.42M
    code = pdfi_gsave(ctx);
198
199
5.42M
    if (code < 0)
200
0
        return code;
201
5.42M
    else {
202
5.42M
        if (ctx->page.has_transparency)
203
1.98M
            return gs_push_transparency_state(ctx->pgs);
204
5.42M
    }
205
3.43M
    return 0;
206
5.42M
}
207
208
int pdfi_op_Q(pdf_context *ctx)
209
5.54M
{
210
5.54M
    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.54M
    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
389k
        pdfi_set_warning(ctx, 0, NULL, W_PDF_TOOMANYQ, "pdfi_op_Q", (char *)"ignoring Q");
218
389k
        return 0;
219
389k
    }
220
5.15M
    if (ctx->page.has_transparency) {
221
1.91M
        code = gs_pop_transparency_state(ctx->pgs, false);
222
1.91M
        if (code < 0)
223
0
            return code;
224
1.91M
    }
225
226
5.15M
    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.15M
    if (code >= 0 && ctx->device_state.preserve_tr_mode && ctx->text.TextClip && gs_currenttextrenderingmode(ctx->pgs) < 4) {
233
5
        gx_device *dev = gs_currentdevice_inline(ctx->pgs);
234
235
5
        ctx->text.TextClip = 0;
236
5
        dev_proc(dev, dev_spec_op)(dev, gxdso_hilevel_text_clip, (void *)0, 1);
237
5
    }
238
239
5.15M
    return code;
240
5.15M
}
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.6M
{
247
12.6M
    return gs_gsave(ctx->pgs);
248
12.6M
}
249
250
int pdfi_grestore(pdf_context *ctx)
251
12.6M
{
252
12.6M
    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.6M
    if (ctx->pgs->level > ctx->current_stream_save.gsave_level) {
258
12.6M
        code = gs_grestore(ctx->pgs);
259
12.6M
    } 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.6M
    return code;
264
12.6M
}
265
266
int pdfi_gs_setgstate(gs_gstate * pgs, const gs_gstate * pfrom)
267
62.4k
{
268
62.4k
    int code = 0;
269
270
62.4k
    code = gs_setgstate(pgs, pfrom);
271
62.4k
    if (code < 0)
272
0
        return code;
273
274
62.4k
    return code;
275
62.4k
}
276
277
int pdfi_setlinewidth(pdf_context *ctx)
278
2.75M
{
279
2.75M
    int code;
280
2.75M
    double d1;
281
282
2.75M
    if (pdfi_count_stack(ctx) < 1)
283
35.9k
        return_error(gs_error_stackunderflow);
284
285
2.72M
    code = pdfi_destack_real(ctx, &d1);
286
2.72M
    if (code < 0)
287
24.3k
        return code;
288
289
2.69M
    return gs_setlinewidth(ctx->pgs, d1);
290
2.72M
}
291
292
int pdfi_setlinejoin(pdf_context *ctx)
293
1.02M
{
294
1.02M
    int code;
295
1.02M
    int64_t i;
296
297
1.02M
    if (pdfi_count_stack(ctx) < 1)
298
32.1k
        return_error(gs_error_stackunderflow);
299
300
988k
    code = pdfi_destack_int(ctx, &i);
301
988k
    if (code < 0)
302
14.1k
        return code;
303
304
974k
    return gs_setlinejoin(ctx->pgs, (int)i);
305
988k
}
306
307
int pdfi_setlinecap(pdf_context *ctx)
308
1.15M
{
309
1.15M
    int code;
310
1.15M
    int64_t i;
311
312
1.15M
    if (pdfi_count_stack(ctx) < 1)
313
30.6k
        return_error(gs_error_stackunderflow);
314
315
1.11M
    code = pdfi_destack_int(ctx, &i);
316
1.11M
    if (code < 0)
317
16.2k
        return code;
318
319
1.10M
    return gs_setlinecap(ctx->pgs, i);
320
1.11M
}
321
322
int pdfi_setflat(pdf_context *ctx)
323
328k
{
324
328k
    int code;
325
328k
    double d1;
326
327
328k
    if (pdfi_count_stack(ctx) < 1)
328
6.78k
        return_error(gs_error_stackunderflow);
329
330
321k
    code = pdfi_destack_real(ctx, &d1);
331
321k
    if (code < 0)
332
4.73k
        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
316k
    if (d1 > 1.0)
341
6.96k
        d1 = 1.0;
342
316k
    return gs_setflat(ctx->pgs, d1);
343
321k
}
344
345
int pdfi_setdash_impl(pdf_context *ctx, pdf_array *a, double phase_d)
346
874k
{
347
874k
    float *dash_array;
348
874k
    double temp;
349
874k
    int i, code;
350
351
874k
    dash_array = (float *)gs_alloc_bytes(ctx->memory, pdfi_array_size(a) * sizeof (float),
352
874k
                                         "temporary float array for setdash");
353
874k
    if (dash_array == NULL)
354
0
        return_error(gs_error_VMerror);
355
356
930k
    for (i=0;i < pdfi_array_size(a);i++){
357
55.6k
        code = pdfi_array_get_number(ctx, a, (uint64_t)i, &temp);
358
55.6k
        if (code < 0) {
359
9
            gs_free_object(ctx->memory, dash_array, "error in setdash");
360
9
            return code;
361
9
        }
362
55.6k
        dash_array[i] = (float)temp;
363
55.6k
    }
364
874k
    code = gs_setdash(ctx->pgs, dash_array, pdfi_array_size(a), phase_d);
365
874k
    gs_free_object(ctx->memory, dash_array, "error in setdash");
366
874k
    return code;
367
874k
}
368
369
int pdfi_setdash(pdf_context *ctx)
370
924k
{
371
924k
    pdf_array *a;
372
924k
    double phase_d;
373
924k
    int code;
374
375
924k
    if (pdfi_count_stack(ctx) < 2) {
376
24.6k
        pdfi_clearstack(ctx);
377
24.6k
        return_error(gs_error_stackunderflow);
378
24.6k
    }
379
380
899k
    code = pdfi_destack_real(ctx, &phase_d);
381
899k
    if (code < 0) {
382
3.60k
        pdfi_pop(ctx, 1);
383
3.60k
        return code;
384
3.60k
    }
385
386
895k
    a = (pdf_array *)ctx->stack_top[-1];
387
895k
    pdfi_countup(a);
388
895k
    pdfi_pop(ctx, 1);
389
390
895k
    if (pdfi_type_of(a) != PDF_ARRAY) {
391
24.2k
        pdfi_countdown(a);
392
24.2k
        return_error(gs_error_typecheck);
393
24.2k
    }
394
395
871k
    code = pdfi_setdash_impl(ctx, a, phase_d);
396
871k
    pdfi_countdown(a);
397
871k
    return code;
398
895k
}
399
400
int pdfi_setmiterlimit(pdf_context *ctx)
401
45.6k
{
402
45.6k
    int code;
403
45.6k
    double d1;
404
405
45.6k
    if (pdfi_count_stack(ctx) < 1)
406
8.94k
        return_error(gs_error_stackunderflow);
407
408
36.7k
    code = pdfi_destack_real(ctx, &d1);
409
36.7k
    if (code < 0)
410
1.02k
        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
35.7k
    if (d1 < 1.0)
418
404
        d1 = 1.0;
419
420
35.7k
    return gs_setmiterlimit(ctx->pgs, d1);
421
36.7k
}
422
423
static int GS_LW(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
424
298
{
425
298
    double d1;
426
298
    int code;
427
428
298
    code = pdfi_dict_get_number(ctx, GS, "LW", &d1);
429
298
    if (code < 0)
430
0
        return code;
431
432
298
    code = gs_setlinewidth(ctx->pgs, d1);
433
298
    return code;
434
298
}
435
436
static int GS_LC(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
437
522
{
438
522
    int64_t i;
439
522
    int code;
440
441
522
    code = pdfi_dict_get_int(ctx, GS, "LC", &i);
442
522
    if (code < 0)
443
0
        return code;
444
445
522
    code = gs_setlinecap(ctx->pgs, i);
446
522
    return code;
447
522
}
448
449
static int GS_LJ(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
450
443
{
451
443
    int64_t i;
452
443
    int code;
453
454
443
    code = pdfi_dict_get_int(ctx, GS, "LJ", &i);
455
443
    if (code < 0)
456
0
        return code;
457
458
443
    code = gs_setlinejoin(ctx->pgs, i);
459
443
    return code;
460
443
}
461
462
static int GS_ML(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
463
333
{
464
333
    int code;
465
333
    double d1;
466
467
333
    code = pdfi_dict_get_number(ctx, GS, "ML", &d1);
468
333
    if (code < 0)
469
34
        return code;
470
471
299
    code = gs_setmiterlimit(ctx->pgs, d1);
472
299
    return code;
473
333
}
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
136k
{
520
136k
    bool b;
521
136k
    int code;
522
136k
    bool known=false;
523
524
136k
    code = pdfi_dict_get_bool(ctx, GS, "OP", &b);
525
136k
    if (code < 0)
526
69
        return code;
527
528
136k
    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
136k
    code = pdfi_dict_known(ctx, GS, "op", &known);
534
136k
    if (!known)
535
21.6k
        gs_setfilloverprint(ctx->pgs, b);
536
537
136k
    return 0;
538
136k
}
539
540
static int GS_op(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
541
116k
{
542
116k
    bool b;
543
116k
    int code;
544
545
116k
    code = pdfi_dict_get_bool(ctx, GS, "op", &b);
546
116k
    if (code < 0)
547
0
        return code;
548
549
116k
    gs_setfilloverprint(ctx->pgs, b);
550
116k
    return 0;
551
116k
}
552
553
static int GS_OPM(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
554
151k
{
555
151k
    int64_t i;
556
151k
    int code;
557
558
151k
    code = pdfi_dict_get_int(ctx, GS, "OPM", &i);
559
151k
    if (code < 0)
560
0
        return code;
561
562
151k
    code = gs_setoverprintmode(ctx->pgs, i);
563
151k
    return code;
564
151k
}
565
566
static int GS_Font(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
567
3
{
568
3
    pdf_array *font_array = NULL;
569
3
    pdf_dict *font_dict = NULL;
570
3
    int code = 0;
571
3
    double point_size = 0.0;
572
573
3
    code = pdfi_dict_get_type(ctx, GS, "Font", PDF_ARRAY, (pdf_obj **)&font_array);
574
3
    if (code < 0)
575
3
        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.7k
{
598
16.7k
    int code = 0, i;
599
16.7k
    gs_function_t *pfn;
600
601
16.7k
    switch (pdfi_type_of(obj)) {
602
16.5k
        case PDF_NAME:
603
16.5k
            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.5k
            } else {
606
16.5k
                if (pdfi_name_is((const pdf_name *)obj, "Identity"))
607
0
                    code = gs_setblackgeneration_remap(ctx->pgs, gs_identity_transfer, false);
608
16.5k
                else if (pdfi_name_is((const pdf_name *)obj, "Default")) {
609
16.5k
                    code = gs_setblackgeneration_remap(ctx->pgs, ctx->page.DefaultBG.proc, false);
610
16.5k
                    memcpy(ctx->pgs->black_generation->values, ctx->page.DefaultBG.values, transfer_map_size * sizeof(frac));
611
16.5k
                } 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.5k
            }
614
16.5k
            goto exit;
615
616
8
        case PDF_DICT:
617
171
        case PDF_STREAM:
618
171
            code = pdfi_build_function(ctx, &pfn, NULL, 1, obj, page_dict);
619
171
            if (code < 0)
620
12
                return code;
621
622
159
            if (pfn->params.n != 1) {
623
8
                pdfi_free_function(ctx, pfn);
624
8
                return_error(gs_error_rangecheck);
625
8
            }
626
627
151
            gs_setblackgeneration_remap(ctx->pgs, gs_mapped_transfer, false);
628
38.8k
            for (i = 0; i < transfer_map_size; i++) {
629
38.6k
                float v, f;
630
631
38.6k
                f = (1.0f / (transfer_map_size - 1)) * i;
632
633
38.6k
                code = gs_function_evaluate(pfn, (const float *)&f, &v);
634
38.6k
                if (code < 0) {
635
0
                    pdfi_free_function(ctx, pfn);
636
0
                    return code;
637
0
                }
638
639
38.6k
                ctx->pgs->black_generation->values[i] =
640
38.6k
                    (v < 0.0 ? float2frac(0.0) :
641
38.6k
                     v >= 1.0 ? frac_1 :
642
38.6k
                     float2frac(v));
643
38.6k
            }
644
151
            code = pdfi_free_function(ctx, pfn);
645
151
            break;
646
647
0
        default:
648
0
            return_error(gs_error_typecheck);
649
16.7k
    }
650
16.6k
exit:
651
16.6k
    return code;
652
16.7k
}
653
654
static int GS_BG(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
655
200
{
656
200
    int code;
657
200
    pdf_obj *obj = NULL;
658
659
    /* If the dictionary also has a BG2, then we must use that */
660
200
    code = pdfi_dict_get(ctx, GS, "BG2", &obj);
661
200
    if (code == 0) {
662
0
        pdfi_countdown(obj);
663
0
        return 0;
664
0
    }
665
666
200
    code = pdfi_dict_get(ctx, GS, "BG", &obj);
667
200
    if (code < 0)
668
20
        return code;
669
670
180
    code = pdfi_set_blackgeneration(ctx, obj, page_dict, true);
671
672
180
    pdfi_countdown(obj);
673
674
180
    return code;
675
200
}
676
677
static int GS_BG2(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
678
16.5k
{
679
16.5k
    int code;
680
16.5k
    pdf_obj *obj = NULL;
681
682
16.5k
    code = pdfi_dict_get(ctx, GS, "BG2", &obj);
683
16.5k
    if (code < 0)
684
0
        return code;
685
686
16.5k
    code = pdfi_set_blackgeneration(ctx, obj, page_dict, false);
687
688
16.5k
    pdfi_countdown(obj);
689
690
16.5k
    return code;
691
16.5k
}
692
693
static int pdfi_set_undercolorremoval(pdf_context *ctx, pdf_obj *obj, pdf_dict *page_dict, bool is_UCR)
694
16.6k
{
695
16.6k
    int code = 0, i;
696
16.6k
    gs_function_t *pfn;
697
698
16.6k
    switch (pdfi_type_of(obj)) {
699
16.5k
        case PDF_NAME:
700
16.5k
            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.5k
            } else {
703
16.5k
                if (pdfi_name_is((const pdf_name *)obj, "Identity")) {
704
0
                    code = gs_setundercolorremoval_remap(ctx->pgs, gs_identity_transfer, false);
705
16.5k
                } else if (pdfi_name_is((const pdf_name *)obj, "Default")) {
706
16.5k
                    code = gs_setundercolorremoval_remap(ctx->pgs, ctx->page.DefaultUCR.proc, false);
707
16.5k
                    memcpy(ctx->pgs->undercolor_removal->values, ctx->page.DefaultUCR.values, transfer_map_size * sizeof(frac));
708
16.5k
                } else {
709
8
                    code = pdfi_set_error_stop(ctx, gs_note_error(gs_error_rangecheck), NULL, E_PDF_UCR_ISNAME, "pdfi_set_undercolorremoval", "");
710
8
                }
711
16.5k
            }
712
16.5k
            goto exit;
713
714
0
        case PDF_DICT:
715
147
        case PDF_STREAM:
716
147
            code = pdfi_build_function(ctx, &pfn, NULL, 1, obj, page_dict);
717
147
            if (code < 0)
718
0
                return code;
719
720
147
            if (pfn->params.n == 1) {
721
147
                gs_setundercolorremoval_remap(ctx->pgs, gs_mapped_transfer, false);
722
37.7k
                for (i = 0; i < transfer_map_size; i++) {
723
37.6k
                    float v, f;
724
725
37.6k
                    f = (1.0f / (transfer_map_size - 1)) * i;
726
727
37.6k
                    code = gs_function_evaluate(pfn, (const float *)&f, &v);
728
37.6k
                    if (code < 0) {
729
0
                        pdfi_free_function(ctx, pfn);
730
0
                        return code;
731
0
                    }
732
733
37.6k
                    ctx->pgs->undercolor_removal->values[i] =
734
37.6k
                        (v < 0.0 ? float2frac(0.0) :
735
37.6k
                         v >= 1.0 ? frac_1 :
736
37.3k
                         float2frac(v));
737
37.6k
                }
738
147
                code = pdfi_free_function(ctx, pfn);
739
147
            }
740
0
            else {
741
0
                (void)pdfi_free_function(ctx, pfn);
742
0
                code = gs_note_error(gs_error_rangecheck);
743
0
            }
744
147
            break;
745
746
147
        default:
747
0
            return_error(gs_error_typecheck);
748
16.6k
    }
749
16.6k
exit:
750
16.6k
    return code;
751
16.6k
}
752
753
static int GS_UCR(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
754
160
{
755
160
    int code;
756
160
    pdf_obj *obj = NULL;
757
758
    /* If the dictionary also has a UCR2, then we must use that and ignore the UCR */
759
160
    code = pdfi_dict_get(ctx, GS, "UCR2", &obj);
760
160
    if (code == 0) {
761
0
        pdfi_countdown(obj);
762
0
        return 0;
763
0
    }
764
765
160
    code = pdfi_dict_get(ctx, GS, "UCR", &obj);
766
160
    if (code < 0)
767
4
        return code;
768
769
156
    code = pdfi_set_undercolorremoval(ctx, obj, page_dict, true);
770
771
156
    pdfi_countdown(obj);
772
773
156
    return code;
774
160
}
775
776
static int GS_UCR2(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
777
16.5k
{
778
16.5k
    int code;
779
16.5k
    pdf_obj *obj = NULL;
780
781
16.5k
    code = pdfi_dict_get(ctx, GS, "UCR2", &obj);
782
16.5k
    if (code < 0)
783
0
        return code;
784
785
16.5k
    code = pdfi_set_undercolorremoval(ctx, obj, page_dict, false);
786
787
16.5k
    pdfi_countdown(obj);
788
789
16.5k
    return code;
790
16.5k
}
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
226
{
803
226
    int code = 0, i, j;
804
226
    pdf_obj *o = NULL;
805
226
    int proc_types[4];
806
226
    gs_mapping_proc map_procs[4];
807
226
    gs_function_t *pfn[4];
808
809
226
    memset(pfn, 0x00, 4 * sizeof(gs_function_t *));
810
226
    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
683
    for (i = 0; i < 4; i++) {
816
592
        code = pdfi_array_get(ctx, a, (uint64_t)i, &o);
817
592
        if (code < 0)
818
69
            goto exit;
819
523
        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
514
            case PDF_STREAM:
834
520
            case PDF_DICT:
835
520
                proc_types[i] = E_FUNCTION;
836
520
                map_procs[i] = gs_mapped_transfer;
837
520
                code = pdfi_build_function(ctx, &pfn[i], NULL, 1, o, page_dict);
838
520
                if (code < 0) {
839
63
                    pdfi_countdown(o);
840
63
                    goto exit;
841
63
                }
842
457
                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
457
                break;
848
457
            default:
849
3
                pdfi_countdown(o);
850
3
                code = gs_note_error(gs_error_typecheck);
851
3
                goto exit;
852
523
        }
853
457
        pdfi_countdown(o);
854
457
    }
855
91
    code = gs_setcolortransfer_remap(ctx->pgs, map_procs[0], map_procs[1], map_procs[2], map_procs[3], false);
856
91
    if (code < 0)
857
0
        goto exit;
858
859
    /* Second pass is to evaluate and set the transfer maps */
860
455
    for (j = 0; j < 4; j++) {
861
364
        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
364
        if (proc_types[j] == E_FUNCTION) {
878
93.5k
            for (i = 0; i < transfer_map_size; i++) {
879
93.1k
                float v, f;
880
93.1k
                frac value;
881
882
93.1k
                f = (1.0f / (transfer_map_size - 1)) * i;
883
884
93.1k
                code = gs_function_evaluate(pfn[j], (const float *)&f, &v);
885
93.1k
                if (code < 0)
886
0
                    goto exit;
887
888
93.1k
                value =
889
93.1k
                    (v < 0.0 ? float2frac(0.0) :
890
93.1k
                     v >= 1.0 ? frac_1 :
891
93.1k
                     float2frac(v));
892
93.1k
                switch(j) {
893
23.2k
                    case 0:
894
23.2k
                        ctx->pgs->set_transfer.red->values[i] = value;
895
23.2k
                        break;
896
23.2k
                    case 1:
897
23.2k
                        ctx->pgs->set_transfer.green->values[i] = value;
898
23.2k
                        break;
899
23.2k
                    case 2:
900
23.2k
                        ctx->pgs->set_transfer.blue->values[i] = value;
901
23.2k
                        break;
902
23.2k
                    case 3:
903
23.2k
                        ctx->pgs->set_transfer.gray->values[i] = value;
904
23.2k
                        break;
905
93.1k
                }
906
93.1k
            }
907
364
        }
908
364
    }
909
226
 exit:
910
1.13k
    for (i = 0; i < 4; i++) {
911
904
        pdfi_free_function(ctx, pfn[i]);
912
904
    }
913
226
    return code;
914
91
}
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
27.8k
{
955
27.8k
    int code = 0;
956
957
27.8k
    if (pdfi_type_of(obj) == PDF_NAME) {
958
27.6k
        if (pdfi_name_is((const pdf_name *)obj, "Identity")) {
959
15.4k
            code = gs_settransfer_remap(ctx->pgs, gs_identity_transfer, false);
960
15.4k
            goto exit;
961
15.4k
        } else {
962
12.2k
            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.2k
            } else {
966
12.2k
                if (pdfi_name_is((const pdf_name *)obj, "Default")) {
967
12.1k
                    code = gs_settransfer_remap(ctx->pgs, ctx->page.DefaultTransfers[3].proc, false);
968
12.1k
                    memcpy(ctx->pgs->set_transfer.gray->values, ctx->page.DefaultTransfers[3].values, transfer_map_size * sizeof(frac));
969
12.1k
                    goto exit;
970
12.1k
                } else {
971
44
                    code = pdfi_set_error_stop(ctx, gs_note_error(gs_error_rangecheck), NULL, E_PDF_TR_NAME_NOT_IDENTITY, "pdfi_set_undercolorremoval", "");
972
44
                    goto exit;
973
44
                }
974
12.2k
            }
975
12.2k
        }
976
27.6k
    }
977
978
226
    if (pdfi_type_of(obj) == PDF_ARRAY) {
979
226
        if (pdfi_array_size((pdf_array *)obj) != 4) {
980
0
            code = gs_note_error(gs_error_rangecheck);
981
0
            goto exit;
982
226
        } else {
983
226
            code = pdfi_set_all_transfers(ctx, (pdf_array *)obj, page_dict, false);
984
226
        }
985
226
    } else
986
0
        code = pdfi_set_gray_transfer(ctx, obj, page_dict);
987
988
27.8k
exit:
989
27.8k
    return code;
990
226
}
991
992
static int GS_TR(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
993
15.6k
{
994
15.6k
    int code;
995
15.6k
    pdf_obj *obj = NULL;
996
997
15.6k
    code = pdfi_dict_get(ctx, GS, "TR", &obj);
998
15.6k
    if (code < 0)
999
0
        return code;
1000
1001
15.6k
    code = pdfi_set_transfer(ctx, obj, page_dict, true);
1002
1003
15.6k
    pdfi_countdown(obj);
1004
1005
15.6k
    return code;
1006
15.6k
}
1007
1008
static int GS_TR2(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
1009
12.2k
{
1010
12.2k
    int code;
1011
12.2k
    pdf_obj *obj = NULL;
1012
12.2k
    code = pdfi_dict_get(ctx, GS, "TR2", &obj);
1013
12.2k
    if (code < 0)
1014
0
        return code;
1015
1016
12.2k
    code = pdfi_set_transfer(ctx, obj, page_dict, false);
1017
1018
12.2k
    pdfi_countdown(obj);
1019
1020
12.2k
    return code;
1021
12.2k
}
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
20.0k
{
1129
20.0k
    int code, i, j;
1130
20.0k
    pdf_obj *obj = NULL, *transfer = NULL;
1131
20.0k
    double f, a;
1132
20.0k
    float values[2] = {0, 0}, domain[4] = {-1, 1, -1, 1}, out;
1133
20.0k
    gs_function_t *pfn = NULL;
1134
20.0k
    gx_ht_order *order = NULL;
1135
20.0k
    gs_screen_enum *penum = NULL;
1136
20.0k
    gs_point pt;
1137
20.0k
    gx_transfer_map *pmap = NULL;
1138
20.0k
    bool as;
1139
1140
20.0k
    code = pdfi_dict_get_number(ctx, halftone_dict, "Frequency", &f);
1141
20.0k
    if (code < 0)
1142
0
        return code;
1143
1144
20.0k
    code = pdfi_dict_get_number(ctx, halftone_dict, "Angle", &a);
1145
20.0k
    if (code < 0)
1146
8
        return code;
1147
1148
20.0k
    code = pdfi_dict_get(ctx, halftone_dict, "SpotFunction", &obj);
1149
20.0k
    if (code < 0)
1150
0
        return code;
1151
1152
20.0k
    code = pdfi_dict_get_bool(ctx, halftone_dict, "AccurateScreens", &as);
1153
20.0k
    if (code == gs_error_undefined)
1154
20.0k
        as = 0;
1155
0
    else if (code < 0)
1156
0
        return code;
1157
1158
20.0k
    order = (gx_ht_order *)gs_alloc_bytes(ctx->memory, sizeof(gx_ht_order), "build_type1_halftone");
1159
20.0k
    if (order == NULL) {
1160
0
        code = gs_note_error(gs_error_VMerror);
1161
0
        goto error;
1162
0
    }
1163
20.0k
    memset(order, 0x00, sizeof(gx_ht_order));
1164
1165
20.0k
    switch (pdfi_type_of(obj)) {
1166
20.0k
        case PDF_NAME:
1167
20.0k
            if (pdfi_name_is((pdf_name *)obj, "Default")) {
1168
0
                i = 0;
1169
20.0k
            } else {
1170
220k
                for (i = 0; i < (sizeof(spot_table) / sizeof (char *)); i++) {
1171
220k
                    if (pdfi_name_is((pdf_name *)obj, spot_table[i]))
1172
20.0k
                        break;
1173
220k
                }
1174
20.0k
                if (i >= (sizeof(spot_table) / sizeof (char *))) {
1175
0
                    code = gs_note_error(gs_error_rangecheck);
1176
0
                    goto error;
1177
0
                }
1178
20.0k
            }
1179
20.0k
            code = pdfi_build_halftone_function(ctx, &pfn, (byte *)spot_functions[i], strlen(spot_functions[i]));
1180
20.0k
            if (code < 0)
1181
0
                goto error;
1182
20.0k
            break;
1183
20.0k
        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
20.0k
    }
1230
1231
20.0k
    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
20.0k
    phtc->params.spot.screen.frequency = f;
1250
20.0k
    phtc->params.spot.screen.angle = a;
1251
20.0k
    phtc->params.spot.screen.spot_function = pdfi_spot1_dummy;
1252
20.0k
    phtc->params.spot.transfer = (code > 0 ? (gs_mapping_proc) 0 : gs_identity_transfer);
1253
20.0k
    phtc->params.spot.transfer_closure.proc = 0;
1254
20.0k
    phtc->params.spot.transfer_closure.data = 0;
1255
20.0k
    phtc->params.spot.accurate_screens = as;
1256
20.0k
    phtc->type = ht_type_spot;
1257
20.0k
    code = pdfi_get_name_index(ctx, name, len, (unsigned int *)&phtc->cname);
1258
20.0k
    if (code < 0)
1259
0
        goto error;
1260
1261
20.0k
    if (comp_num == -1)
1262
20.0k
        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
20.0k
    code = gs_screen_order_init_memory(order, ctx->pgs, &phtc->params.spot.screen,
1267
20.0k
                                       gs_currentaccuratescreens(ctx->memory), ctx->memory);
1268
20.0k
    if (code < 0)
1269
0
        goto error;
1270
1271
20.0k
    penum = gs_screen_enum_alloc(ctx->memory, "build_type1_halftone");
1272
20.0k
    if (penum == 0) {
1273
0
        code = gs_error_VMerror;
1274
0
        goto error;
1275
0
    }
1276
1277
20.0k
    code = gs_screen_enum_init_memory(penum, order, ctx->pgs, &phtc->params.spot.screen, ctx->memory);
1278
20.0k
    if (code < 0)
1279
0
        goto error;
1280
1281
180k
    do {
1282
        /* Generate x and y, the parameteric variables */
1283
180k
        code = gs_screen_currentpoint(penum, &pt);
1284
180k
        if (code < 0)
1285
0
            goto error;
1286
1287
180k
        if (code == 1)
1288
20.0k
            break;
1289
1290
        /* Process sample */
1291
160k
        values[0] = pt.x, values[1] = pt.y;
1292
160k
        code = gs_function_evaluate(pfn, (const float *)&values, &out);
1293
160k
        if (code < 0)
1294
0
            goto error;
1295
1296
        /* Store the sample */
1297
160k
        code = gs_screen_next(penum, out);
1298
160k
        if (code < 0)
1299
0
            goto error;
1300
1301
160k
    } while (1);
1302
20.0k
    code = 0;
1303
20.0k
    *porder = penum->order;
1304
20.0k
    (*porder).transfer = pmap;
1305
1306
20.0k
error:
1307
20.0k
    pdfi_countdown(transfer);
1308
20.0k
    pdfi_countdown(obj);
1309
20.0k
    pdfi_free_function(ctx, pfn);
1310
20.0k
    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
20.0k
    if (code < 0 && pmap != NULL)
1315
20.0k
        rc_decrement(pmap, "pdfi process_transfer");
1316
20.0k
    gs_free_object(ctx->memory, order, "build_type1_halftone");
1317
20.0k
    gs_free_object(ctx->memory, penum, "build_type1_halftone");
1318
20.0k
    return code;
1319
20.0k
}
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
20.0k
{
1509
20.0k
    int i=0;
1510
20.0k
    gs_halftone *pht = (gs_halftone *)data;
1511
20.0k
    gs_halftone_component comp;
1512
1513
40.0k
    for (i=0;i< pht->params.multiple.num_comp;i++) {
1514
20.0k
        comp = pht->params.multiple.components[i];
1515
20.0k
        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
20.0k
            default:
1525
20.0k
                break;
1526
20.0k
        }
1527
20.0k
    }
1528
20.0k
    gs_free_object(memory, pht->params.multiple.components, "pdfi_free_halftone");
1529
20.0k
    gs_free_object(memory, pht, "pdfi_free_halftone");
1530
20.0k
}
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
20.0k
{
1790
20.0k
    int code;
1791
20.0k
    char *str = NULL;
1792
20.0k
    int64_t type;
1793
20.0k
    gs_halftone *pht = NULL;
1794
20.0k
    gx_device_halftone *pdht = NULL;
1795
20.0k
    gs_halftone_component *phtc = NULL;
1796
20.0k
    pdf_obj *Key = NULL, *Value = NULL, *transfer = NULL;
1797
20.0k
    pdf_dict *halftone_dict = NULL;
1798
20.0k
    gx_transfer_map *pmap = NULL;
1799
1800
20.0k
    code = pdfi_dict_from_obj(ctx, halftone_obj, &halftone_dict);
1801
20.0k
    if (code < 0)
1802
0
        return code;
1803
1804
20.0k
    code = pdfi_dict_get_int(ctx, halftone_dict, "HalftoneType", &type);
1805
20.0k
    if (code < 0)
1806
0
        return code;
1807
1808
20.0k
    pht = (gs_halftone *)gs_alloc_bytes(ctx->memory, sizeof(gs_halftone), "pdfi_do_halftone");
1809
20.0k
    if (pht == 0) {
1810
0
        code = gs_note_error(gs_error_VMerror);
1811
0
        goto error;
1812
0
    }
1813
20.0k
    memset(pht, 0x00, sizeof(gs_halftone));
1814
20.0k
    pht->rc.memory = ctx->memory;
1815
20.0k
    pht->rc.free = pdfi_free_halftone;
1816
1817
20.0k
    pdht = (gx_device_halftone *)gs_alloc_bytes(ctx->memory, sizeof(gx_device_halftone), "pdfi_do_halftone");
1818
20.0k
    if (pdht == 0) {
1819
0
        code = gs_note_error(gs_error_VMerror);
1820
0
        goto error;
1821
0
    }
1822
20.0k
    memset(pdht, 0x00, sizeof(gx_device_halftone));
1823
20.0k
    pdht->num_dev_comp = ctx->pgs->device->color_info.num_components;
1824
20.0k
    pdht->rc.memory = ctx->memory;
1825
1826
20.0k
    switch(type) {
1827
20.0k
        case 1:
1828
20.0k
            phtc = (gs_halftone_component *)gs_alloc_bytes(ctx->memory, sizeof(gs_halftone_component), "pdfi_do_halftone");
1829
20.0k
            if (phtc == 0) {
1830
0
                code = gs_note_error(gs_error_VMerror);
1831
0
                goto error;
1832
0
            }
1833
1834
20.0k
            code = build_type1_halftone(ctx, halftone_dict, page_dict, &pdht->order, phtc, (char *)"Default", 7, -1);
1835
20.0k
            if (code < 0)
1836
8
                goto error;
1837
1838
20.0k
            pht->type = ht_type_multiple;
1839
20.0k
            pht->params.multiple.components = phtc;
1840
20.0k
            pht->params.multiple.num_comp = 1;
1841
20.0k
            pht->params.multiple.get_colorname_string = pdfi_separation_name_from_index;
1842
20.0k
            code = gx_gstate_dev_ht_install(ctx->pgs, pdht, pht->type, gs_currentdevice_inline(ctx->pgs), HT_OBJTYPE_DEFAULT);
1843
20.0k
            if (code < 0)
1844
0
                goto error;
1845
1846
20.0k
            gx_device_halftone_release(pdht, pdht->rc.memory);
1847
20.0k
            rc_decrement(ctx->pgs->halftone, "pdfi_do_halftone(halftone)");
1848
20.0k
            ctx->pgs->halftone = pht;
1849
20.0k
            rc_increment(ctx->pgs->halftone);
1850
20.0k
            gx_unset_both_dev_colors(ctx->pgs);
1851
20.0k
            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
20.0k
    }
2044
20.0k
    gs_free_object(ctx->memory, pdht, "pdfi_do_halftone");
2045
20.0k
    return 0;
2046
2047
8
error:
2048
8
    if (pdht != NULL)
2049
8
        gx_device_halftone_release(pdht, pdht->rc.memory);
2050
8
    gs_free_object(ctx->memory, str, "pdfi_string_from_name");
2051
8
    pdfi_countdown(Key);
2052
8
    pdfi_countdown(Value);
2053
8
    gs_free_object(ctx->memory, pht, "pdfi_do_halftone");
2054
8
    gs_free_object(ctx->memory, phtc, "pdfi_do_halftone");
2055
8
    gs_free_object(ctx->memory, pdht, "pdfi_do_halftone");
2056
8
    return code;
2057
20.0k
}
2058
2059
static int GS_HT(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
2060
21.8k
{
2061
21.8k
    int code;
2062
21.8k
    pdf_obj *obj = NULL;
2063
2064
21.8k
    code = pdfi_dict_get(ctx, GS, "HT", &obj);
2065
21.8k
    if (code < 0)
2066
0
        return code;
2067
2068
2069
21.8k
    if (pdfi_type_of(obj) == PDF_NAME) {
2070
1.84k
        if (pdfi_name_is((const pdf_name *)obj, "Default")) {
2071
1.84k
            goto exit;
2072
1.84k
        } else {
2073
0
            code = gs_note_error(gs_error_rangecheck);
2074
0
            goto exit;
2075
0
        }
2076
20.0k
    } else {
2077
20.0k
        code = pdfi_do_halftone(ctx, obj, page_dict);
2078
20.0k
    }
2079
20.0k
    if (code < 0) {
2080
8
        code = pdfi_set_error_stop(ctx, code, NULL, E_BAD_HALFTONE, "GS_HT", "Halftone will be ignored");
2081
8
    }
2082
2083
21.8k
exit:
2084
21.8k
    pdfi_countdown(obj);
2085
21.8k
    return code;
2086
20.0k
}
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
44.3k
{
2103
44.3k
    int code;
2104
44.3k
    double d1;
2105
2106
44.3k
    code = pdfi_dict_get_number(ctx, GS, "SM", &d1);
2107
44.3k
    if (code < 0)
2108
0
        return code;
2109
2110
44.3k
    code = gs_setsmoothness(ctx->pgs, d1);
2111
44.3k
    return code;
2112
44.3k
}
2113
2114
static int GS_SA(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
2115
150k
{
2116
150k
    bool b;
2117
150k
    int code;
2118
2119
150k
    code = pdfi_dict_get_bool(ctx, GS, "SA", &b);
2120
150k
    if (code < 0)
2121
14
        return code;
2122
2123
150k
    return gs_setstrokeadjust(ctx->pgs, b);
2124
150k
}
2125
2126
static int GS_BM(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
2127
218k
{
2128
218k
    pdf_name *n;
2129
218k
    int code;
2130
218k
    gs_blend_mode_t mode = 0; /* Start with /Normal */
2131
2132
218k
    code = pdfi_dict_get(ctx, GS, "BM", (pdf_obj **)&n);
2133
218k
    if (code < 0)
2134
0
        return code;
2135
2136
218k
    if (pdfi_type_of(n) == PDF_ARRAY) {
2137
44
        int i;
2138
44
        pdf_array *a = (pdf_array *)n;
2139
2140
44
        for (i=0;i < pdfi_array_size(a);i++){
2141
44
            code = pdfi_array_get_type(ctx, a, i, PDF_NAME, (pdf_obj **)&n);
2142
44
            if (code < 0)
2143
0
                continue;
2144
44
            code = pdfi_get_blend_mode(ctx, n, &mode);
2145
44
            pdfi_countdown(n);
2146
44
            if (code == 0)
2147
44
                break;
2148
44
        }
2149
44
        pdfi_countdown(a);
2150
44
        return gs_setblendmode(ctx->pgs, mode);
2151
44
    }
2152
2153
218k
    if (pdfi_type_of(n) == PDF_NAME) {
2154
218k
        code = pdfi_get_blend_mode(ctx, n, &mode);
2155
218k
        pdfi_countdown(n);
2156
218k
        if (code == 0)
2157
217k
            return gs_setblendmode(ctx->pgs, mode);
2158
218k
        return_error(gs_error_undefined);
2159
218k
    }
2160
218k
    return_error(gs_error_typecheck);
2161
218k
}
2162
2163
static int GS_SMask(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
2164
115k
{
2165
115k
    pdf_obj *o = NULL;
2166
115k
    pdfi_int_gstate *igs = (pdfi_int_gstate *)ctx->pgs->client_data;
2167
115k
    int code;
2168
115k
    bool Processed;
2169
2170
115k
    if (ctx->page.has_transparency == false || ctx->args.notransparency == true)
2171
24.7k
        return 0;
2172
2173
90.7k
    code = pdfi_dict_get(ctx, GS, "SMask", (pdf_obj **)&o);
2174
90.7k
    if (code < 0)
2175
305
        return code;
2176
2177
90.4k
    switch (pdfi_type_of(o)) {
2178
84.8k
        case PDF_NAME:
2179
84.8k
        {
2180
84.8k
            pdf_name *n = (pdf_name *)o;
2181
2182
84.8k
            if (pdfi_name_is(n, "None")) {
2183
84.7k
                if (igs->SMask) {
2184
6.77k
                    pdfi_gstate_smask_free(igs);
2185
6.77k
                    code = pdfi_trans_end_smask_notify(ctx);
2186
6.77k
                }
2187
84.7k
                goto exit;
2188
84.7k
            }
2189
59
            code = pdfi_find_resource(ctx, (unsigned char *)"ExtGState", n, stream_dict, page_dict, &o);
2190
59
            pdfi_countdown(n);
2191
59
            if (code < 0)
2192
59
                return code;
2193
0
            break;
2194
59
        }
2195
2196
5.63k
        case PDF_DICT:
2197
5.63k
        {
2198
5.63k
            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.63k
            if (code > 0 && Processed) {
2205
280
                code = pdfi_dict_put_bool(ctx, (pdf_dict *)o, "Processed", false);
2206
280
                if (code < 0)
2207
0
                    return code;
2208
280
            }
2209
5.63k
            if (igs->SMask)
2210
1.83k
                pdfi_gstate_smask_free(igs);
2211
            /* We need to use the graphics state memory, in case we are running under Ghostscript. */
2212
5.63k
            pdfi_gstate_smask_install(igs, ctx->pgs->memory, (pdf_dict *)o, ctx->pgs);
2213
5.63k
            break;
2214
5.63k
        }
2215
2216
15
        default:
2217
15
            break;
2218
90.4k
    }
2219
2220
90.4k
 exit:
2221
90.4k
    pdfi_countdown(o);
2222
90.4k
    return 0;
2223
90.4k
}
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
287
        pdfi_set_warning(ctx, 0, NULL, W_PDF_CA_OUTOFRANGE, "GS_CA", NULL);
2236
287
        d1 = 1.0;
2237
287
    }
2238
2239
228k
    if (d1 < 0.0) {
2240
30
        pdfi_set_warning(ctx, 0, NULL, W_PDF_CA_OUTOFRANGE, "GS_CA", NULL);
2241
30
        d1 = 0.0;
2242
30
    }
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
209
        pdfi_set_warning(ctx, 0, NULL, W_PDF_CA_OUTOFRANGE, "GS_ca", NULL);
2259
209
        d1 = 1.0;
2260
209
    }
2261
2262
226k
    if (d1 < 0.0) {
2263
29
        pdfi_set_warning(ctx, 0, NULL, W_PDF_CA_OUTOFRANGE, "GS_ca", NULL);
2264
29
        d1 = 0.0;
2265
29
    }
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
112k
{
2273
112k
    bool b;
2274
112k
    int code;
2275
2276
112k
    code = pdfi_dict_get_bool(ctx, GS, "AIS", &b);
2277
112k
    if (code < 0)
2278
0
        return code;
2279
2280
112k
    return gs_setalphaisshape(ctx->pgs, b);
2281
112k
}
2282
2283
static int GS_TK(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
2284
11.5k
{
2285
11.5k
    bool b;
2286
11.5k
    int code;
2287
2288
11.5k
    code = pdfi_dict_get_bool(ctx, GS, "TK", &b);
2289
11.5k
    if (code < 0)
2290
0
        return code;
2291
2292
11.5k
    return gs_settextknockout(ctx->pgs, b);
2293
11.5k
}
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
379k
{
2338
379k
    int code, i, limit = sizeof(ExtGStateTable) / sizeof (GS_Func_t);
2339
379k
    bool known;
2340
2341
10.2M
    for (i=0;i < limit; i++) {
2342
9.86M
        code = pdfi_dict_known(ctx, gstate_dict, ExtGStateTable[i].Name, &known);
2343
9.86M
        if (code < 0)
2344
0
            break;
2345
9.86M
        if (known) {
2346
1.59M
            code = ExtGStateTable[i].proc(ctx, gstate_dict, NULL, page_dict);
2347
1.59M
            if (code < 0)
2348
1.47k
                break;
2349
1.59M
        }
2350
9.86M
    }
2351
379k
    return code;
2352
379k
}
2353
2354
int pdfi_setgstate(pdf_context *ctx, pdf_dict *stream_dict, pdf_dict *page_dict)
2355
545k
{
2356
545k
    pdf_name *n = NULL;
2357
545k
    pdf_obj *o = NULL;
2358
545k
    int code=0, code1 = 0;
2359
2360
545k
    code = pdfi_loop_detector_mark(ctx);
2361
545k
    if (code < 0)
2362
0
        return code;
2363
2364
545k
    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
525k
    n = (pdf_name *)ctx->stack_top[-1];
2369
525k
    pdfi_countup(n);
2370
525k
    pdfi_pop(ctx, 1);
2371
2372
525k
    if (pdfi_type_of(n) != PDF_NAME) {
2373
11.5k
        code = gs_note_error(gs_error_typecheck);
2374
11.5k
        goto setgstate_error;
2375
11.5k
    }
2376
2377
513k
    code = pdfi_find_resource(ctx, (unsigned char *)"ExtGState", n, (pdf_dict *)stream_dict,
2378
513k
                              page_dict, &o);
2379
513k
    if (code < 0)
2380
130k
        goto setgstate_error;
2381
2382
382k
    if (pdfi_type_of(o) != PDF_DICT) {
2383
3.16k
        code = gs_note_error(gs_error_typecheck);
2384
3.16k
        goto setgstate_error;
2385
3.16k
    }
2386
2387
379k
    code = pdfi_set_ExtGState(ctx, stream_dict, page_dict, (pdf_dict *)o);
2388
2389
545k
setgstate_error:
2390
545k
    code1 = pdfi_loop_detector_cleartomark(ctx);
2391
545k
    if (code == 0) code = code1;
2392
2393
545k
    pdfi_countdown(n);
2394
545k
    pdfi_countdown(o);
2395
545k
    return code;
2396
379k
}
2397
2398
2399
int pdfi_free_DefaultQState(pdf_context *ctx)
2400
870k
{
2401
870k
    if (ctx->DefaultQState)
2402
674k
        gs_gstate_free(ctx->DefaultQState);
2403
870k
    ctx->DefaultQState = NULL;
2404
870k
    return 0;
2405
870k
}
2406
2407
int pdfi_set_DefaultQState(pdf_context *ctx, gs_gstate *pgs)
2408
674k
{
2409
674k
    pdfi_free_DefaultQState(ctx);
2410
    /* We need to use the graphics state memory, in case we are running under Ghostscript. */
2411
674k
    ctx->DefaultQState = gs_gstate_copy(pgs, ctx->pgs->memory);
2412
674k
    if (ctx->DefaultQState == NULL)
2413
0
        return_error(gs_error_VMerror);
2414
674k
    return 0;
2415
674k
}
2416
2417
gs_gstate *pdfi_get_DefaultQState(pdf_context *ctx)
2418
31.7k
{
2419
31.7k
    return ctx->DefaultQState;
2420
31.7k
}
2421
2422
int pdfi_copy_DefaultQState(pdf_context *ctx, gs_gstate **pgs)
2423
285k
{
2424
    /* We need to use the graphics state memory, in case we are running under Ghostscript. */
2425
285k
    *pgs = gs_gstate_copy(ctx->DefaultQState, ctx->pgs->memory);
2426
285k
    if (*pgs == NULL)
2427
0
        return_error(gs_error_VMerror);
2428
285k
    return 0;
2429
285k
}
2430
2431
int pdfi_restore_DefaultQState(pdf_context *ctx, gs_gstate **pgs)
2432
285k
{
2433
285k
    int code;
2434
2435
285k
    code = pdfi_set_DefaultQState(ctx, *pgs);
2436
285k
    gs_gstate_free(*pgs);
2437
285k
    *pgs = NULL;
2438
285k
    return code;
2439
285k
}