Coverage Report

Created: 2026-10-28 08:05

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