Coverage Report

Created: 2026-08-08 08:00

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