Coverage Report

Created: 2025-08-28 07:06

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