Coverage Report

Created: 2026-07-24 07:44

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