Coverage Report

Created: 2025-12-31 07:31

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