Coverage Report

Created: 2026-02-14 07:09

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