Coverage Report

Created: 2022-10-31 07:00

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