Coverage Report

Created: 2026-09-14 07:34

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