Coverage Report

Created: 2026-04-09 07:06

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