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