Coverage Report

Created: 2026-04-01 07:17

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
111k
{
57
111k
    const char **p;
58
59
182k
    for (p = blend_mode_names; *p; ++p) {
60
182k
        if (pdfi_name_is(name, *p)) {
61
110k
            *mode = p - blend_mode_names;
62
110k
            return 0;
63
110k
        }
64
182k
    }
65
649
    return -1;
66
111k
}
67
68
void pdfi_gstate_smask_install(pdfi_int_gstate *igs, gs_memory_t *memory, pdf_dict *SMask, gs_gstate *gstate)
69
46.3M
{
70
46.3M
    void *client_data_save;
71
72
46.3M
    if (!SMask)
73
46.2M
        return;
74
55.5k
    igs->memory = memory;
75
55.5k
    igs->SMask = SMask;
76
55.5k
    pdfi_countup(SMask);
77
55.5k
    client_data_save = gstate->client_data;
78
55.5k
    gstate->client_data = NULL;
79
55.5k
    igs->GroupGState = gs_gstate_copy(gstate, memory);
80
55.5k
    gstate->client_data = client_data_save;
81
55.5k
}
82
83
void pdfi_gstate_smask_free(pdfi_int_gstate *igs)
84
70.5M
{
85
70.5M
    if (!igs->SMask)
86
70.4M
        return;
87
55.5k
    pdfi_countdown(igs->SMask);
88
55.5k
    igs->SMask = NULL;
89
55.5k
    if (igs->GroupGState)
90
55.5k
        gs_gstate_free(igs->GroupGState);
91
55.5k
    igs->GroupGState = NULL;
92
55.5k
}
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
24.1M
{
99
24.1M
    pdfi_int_gstate *igs;
100
101
24.1M
    igs = (pdfi_int_gstate *)gs_alloc_bytes(mem, sizeof(pdfi_int_gstate), "pdfi_gstate_alloc");
102
24.1M
    if (igs == NULL)
103
0
        return NULL;
104
24.1M
    memset(igs, 0, sizeof(pdfi_int_gstate));
105
24.1M
    return igs;
106
24.1M
}
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
46.3M
{
112
46.3M
    const pdfi_int_gstate *igs_from = (const pdfi_int_gstate *)from;
113
46.3M
    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
46.3M
    if (igs_to != NULL) {
119
46.3M
        pdfi_gstate_smask_free(igs_to);
120
46.3M
        pdfi_countdown(igs_to->current_font);
121
46.3M
        *(pdfi_int_gstate *) igs_to = *igs_from;
122
46.3M
        pdfi_countup(igs_to->current_font);
123
46.3M
        pdfi_gstate_smask_install(igs_to, igs_from->memory, igs_from->SMask, igs_from->GroupGState);
124
46.3M
    }
125
46.3M
    return 0;
126
46.3M
}
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
24.1M
{
132
24.1M
    pdfi_int_gstate *igs = (pdfi_int_gstate *)old;
133
24.1M
    if (old == NULL)
134
0
        return;
135
24.1M
    pdfi_gstate_smask_free(igs);
136
24.1M
    pdfi_countdown(igs->current_font);
137
    /* We need to use the graphics state memory, in case we are running under Ghostscript. */
138
24.1M
    gs_free_object(pgs->memory, igs, "pdfi_gstate_free");
139
24.1M
}
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
532k
{
151
532k
    pdfi_int_gstate *igs;
152
153
    /* We need to use the graphics state memory, in case we are running under Ghostscript. */
154
532k
    igs = pdfi_gstate_alloc_cb(pgs->memory);
155
532k
    if (igs == NULL)
156
0
        return_error(gs_error_VMerror);
157
532k
    igs->ctx = ctx;
158
532k
    gs_gstate_set_client(pgs, igs, &pdfi_gstate_procs, true /* TODO: client_has_pattern_streams ? */);
159
532k
    return 0;
160
532k
}
161
162
int pdfi_concat(pdf_context *ctx)
163
2.70M
{
164
2.70M
    int code;
165
2.70M
    double Values[6];
166
2.70M
    gs_matrix m;
167
168
2.70M
    if (pdfi_count_stack(ctx) < 6) {
169
305k
        pdfi_clearstack(ctx);
170
305k
        return_error(gs_error_stackunderflow);
171
305k
    }
172
173
2.39M
    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.73k
        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.73k
        code = pdfi_set_warning_stop(ctx, gs_note_error(gs_error_syntaxerror), NULL, W_PDF_OPINVALIDINTEXT, "pdfi_concat", NULL);
184
9.73k
        if (code < 0)
185
0
            return code;
186
9.73k
    }
187
188
2.39M
    code = pdfi_destack_reals(ctx, Values, 6);
189
2.39M
    if (code < 0)
190
8.45k
        return code;
191
192
2.38M
    m.xx = (float)Values[0];
193
2.38M
    m.xy = (float)Values[1];
194
2.38M
    m.yx = (float)Values[2];
195
2.38M
    m.yy = (float)Values[3];
196
2.38M
    m.tx = (float)Values[4];
197
2.38M
    m.ty = (float)Values[5];
198
199
2.38M
    return gs_concat(ctx->pgs, (const gs_matrix *)&m);
200
2.39M
}
201
202
int pdfi_op_q(pdf_context *ctx)
203
3.97M
{
204
3.97M
    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.97M
    code = pdfi_gsave(ctx);
210
211
3.97M
    if (code < 0)
212
0
        return code;
213
3.97M
    else {
214
3.97M
        if (ctx->page.has_transparency)
215
974k
            return gs_push_transparency_state(ctx->pgs);
216
3.97M
    }
217
2.99M
    return 0;
218
3.97M
}
219
220
int pdfi_op_Q(pdf_context *ctx)
221
3.86M
{
222
3.86M
    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.86M
    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
140k
        pdfi_set_warning(ctx, 0, NULL, W_PDF_TOOMANYQ, "pdfi_op_Q", (char *)"ignoring Q");
230
140k
        return 0;
231
140k
    }
232
3.72M
    if (ctx->page.has_transparency) {
233
934k
        code = gs_pop_transparency_state(ctx->pgs, false);
234
934k
        if (code < 0)
235
0
            return code;
236
934k
    }
237
238
3.72M
    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.72M
    if (code >= 0 && ctx->device_state.preserve_tr_mode && ctx->text.TextClip && gs_currenttextrenderingmode(ctx->pgs) < 4) {
245
2
        gx_device *dev = gs_currentdevice_inline(ctx->pgs);
246
247
2
        ctx->text.TextClip = false;
248
2
        code = dev_proc(dev, dev_spec_op)(dev, gxdso_hilevel_text_clip, (void *)0, 1);
249
2
        if (code < 0 && code == gs_error_undefined)
250
2
            code = 0;
251
2
    }
252
253
3.72M
    return code;
254
3.72M
}
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
10.1M
{
261
10.1M
    return gs_gsave(ctx->pgs);
262
10.1M
}
263
264
int pdfi_grestore(pdf_context *ctx)
265
10.1M
{
266
10.1M
    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
10.1M
    if (ctx->pgs->level > ctx->current_stream_save.gsave_level) {
272
10.1M
        code = gs_grestore(ctx->pgs);
273
10.1M
    } 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
10.1M
    return code;
278
10.1M
}
279
280
int pdfi_gs_setgstate(gs_gstate * pgs, const gs_gstate * pfrom)
281
39.9k
{
282
39.9k
    int code = 0;
283
284
39.9k
    code = gs_setgstate(pgs, pfrom);
285
39.9k
    if (code < 0)
286
0
        return code;
287
288
39.9k
    return code;
289
39.9k
}
290
291
int pdfi_setlinewidth(pdf_context *ctx)
292
2.19M
{
293
2.19M
    int code;
294
2.19M
    double d1;
295
296
2.19M
    if (pdfi_count_stack(ctx) < 1)
297
38.2k
        return_error(gs_error_stackunderflow);
298
299
2.15M
    code = pdfi_destack_real(ctx, &d1);
300
2.15M
    if (code < 0)
301
24.8k
        return code;
302
303
2.13M
    return gs_setlinewidth(ctx->pgs, d1);
304
2.15M
}
305
306
int pdfi_setlinejoin(pdf_context *ctx)
307
834k
{
308
834k
    int code;
309
834k
    int64_t i;
310
311
834k
    if (pdfi_count_stack(ctx) < 1)
312
31.9k
        return_error(gs_error_stackunderflow);
313
314
802k
    code = pdfi_destack_int(ctx, &i);
315
802k
    if (code < 0)
316
9.81k
        return code;
317
318
792k
    return gs_setlinejoin(ctx->pgs, (int)i);
319
802k
}
320
321
int pdfi_setlinecap(pdf_context *ctx)
322
968k
{
323
968k
    int code;
324
968k
    int64_t i;
325
326
968k
    if (pdfi_count_stack(ctx) < 1)
327
28.5k
        return_error(gs_error_stackunderflow);
328
329
939k
    code = pdfi_destack_int(ctx, &i);
330
939k
    if (code < 0)
331
16.5k
        return code;
332
333
923k
    return gs_setlinecap(ctx->pgs, i);
334
939k
}
335
336
int pdfi_setflat(pdf_context *ctx)
337
156k
{
338
156k
    int code;
339
156k
    double d1;
340
341
156k
    if (pdfi_count_stack(ctx) < 1)
342
8.26k
        return_error(gs_error_stackunderflow);
343
344
148k
    code = pdfi_destack_real(ctx, &d1);
345
148k
    if (code < 0)
346
4.56k
        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
143k
    if (d1 > 1.0)
355
7.39k
        d1 = 1.0;
356
143k
    return gs_setflat(ctx->pgs, d1);
357
148k
}
358
359
int pdfi_setdash_impl(pdf_context *ctx, pdf_array *a, double phase_d)
360
788k
{
361
788k
    float *dash_array;
362
788k
    double temp;
363
788k
    int i, code;
364
365
788k
    dash_array = (float *)gs_alloc_bytes(ctx->memory, (size_t)pdfi_array_size(a) * sizeof (float),
366
788k
                                         "temporary float array for setdash");
367
788k
    if (dash_array == NULL)
368
0
        return_error(gs_error_VMerror);
369
370
822k
    for (i=0;i < pdfi_array_size(a);i++){
371
33.7k
        code = pdfi_array_get_number(ctx, a, (uint64_t)i, &temp);
372
33.7k
        if (code < 0) {
373
18
            gs_free_object(ctx->memory, dash_array, "error in setdash");
374
18
            return code;
375
18
        }
376
33.7k
        dash_array[i] = (float)temp;
377
33.7k
    }
378
788k
    code = gs_setdash(ctx->pgs, dash_array, pdfi_array_size(a), phase_d);
379
788k
    gs_free_object(ctx->memory, dash_array, "error in setdash");
380
788k
    return code;
381
788k
}
382
383
int pdfi_setdash(pdf_context *ctx)
384
844k
{
385
844k
    pdf_array *a;
386
844k
    double phase_d;
387
844k
    int code;
388
389
844k
    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
820k
    code = pdfi_destack_real(ctx, &phase_d);
395
820k
    if (code < 0) {
396
3.26k
        pdfi_pop(ctx, 1);
397
3.26k
        return code;
398
3.26k
    }
399
400
817k
    a = (pdf_array *)ctx->stack_top[-1];
401
817k
    pdfi_countup(a);
402
817k
    pdfi_pop(ctx, 1);
403
404
817k
    if (pdfi_type_of(a) != PDF_ARRAY) {
405
32.2k
        pdfi_countdown(a);
406
32.2k
        return_error(gs_error_typecheck);
407
32.2k
    }
408
409
784k
    code = pdfi_setdash_impl(ctx, a, phase_d);
410
784k
    pdfi_countdown(a);
411
784k
    return code;
412
817k
}
413
414
int pdfi_setmiterlimit(pdf_context *ctx)
415
43.2k
{
416
43.2k
    int code;
417
43.2k
    double d1;
418
419
43.2k
    if (pdfi_count_stack(ctx) < 1)
420
10.6k
        return_error(gs_error_stackunderflow);
421
422
32.6k
    code = pdfi_destack_real(ctx, &d1);
423
32.6k
    if (code < 0)
424
560
        return code;
425
426
    /* PostScript (and therefore the graphics library) impose a minimum
427
     * value of 1.0 on miter limit. PDF does not specify a minimum, but less
428
     * than 1 doesn't make a lot of sense. This code brought over from the old
429
     * PDF interpreter which silently clamped the value to 1.
430
     */
431
32.0k
    if (d1 < 1.0)
432
450
        d1 = 1.0;
433
434
32.0k
    return gs_setmiterlimit(ctx->pgs, d1);
435
32.6k
}
436
437
static int GS_LW(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
438
342
{
439
342
    double d1;
440
342
    int code;
441
442
342
    code = pdfi_dict_get_number(ctx, GS, "LW", &d1);
443
342
    if (code < 0)
444
0
        return code;
445
446
342
    code = gs_setlinewidth(ctx->pgs, d1);
447
342
    return code;
448
342
}
449
450
static int GS_LC(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
451
603
{
452
603
    int64_t i;
453
603
    int code;
454
455
603
    code = pdfi_dict_get_int(ctx, GS, "LC", &i);
456
603
    if (code < 0)
457
0
        return code;
458
459
603
    code = gs_setlinecap(ctx->pgs, i);
460
603
    return code;
461
603
}
462
463
static int GS_LJ(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
464
484
{
465
484
    int64_t i;
466
484
    int code;
467
468
484
    code = pdfi_dict_get_int(ctx, GS, "LJ", &i);
469
484
    if (code < 0)
470
0
        return code;
471
472
484
    code = gs_setlinejoin(ctx->pgs, i);
473
484
    return code;
474
484
}
475
476
static int GS_ML(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
477
361
{
478
361
    int code;
479
361
    double d1;
480
481
361
    code = pdfi_dict_get_number(ctx, GS, "ML", &d1);
482
361
    if (code < 0)
483
17
        return code;
484
485
344
    code = gs_setmiterlimit(ctx->pgs, d1);
486
344
    return code;
487
361
}
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
103k
{
534
103k
    bool b;
535
103k
    int code;
536
103k
    bool known=false;
537
538
103k
    code = pdfi_dict_get_bool(ctx, GS, "OP", &b);
539
103k
    if (code < 0)
540
57
        return code;
541
542
102k
    gs_setstrokeoverprint(ctx->pgs, b);
543
544
    /* If op not in the dict, then also set it with OP
545
     * Because that's what gs does pdf_draw.ps/gsparamdict/OP
546
     */
547
102k
    code = pdfi_dict_known(ctx, GS, "op", &known);
548
102k
    if (!known)
549
33.6k
        gs_setfilloverprint(ctx->pgs, b);
550
551
102k
    return 0;
552
103k
}
553
554
static int GS_op(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
555
71.0k
{
556
71.0k
    bool b;
557
71.0k
    int code;
558
559
71.0k
    code = pdfi_dict_get_bool(ctx, GS, "op", &b);
560
71.0k
    if (code < 0)
561
0
        return code;
562
563
71.0k
    gs_setfilloverprint(ctx->pgs, b);
564
71.0k
    return 0;
565
71.0k
}
566
567
static int GS_OPM(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
568
76.6k
{
569
76.6k
    int64_t i;
570
76.6k
    int code;
571
572
76.6k
    code = pdfi_dict_get_int(ctx, GS, "OPM", &i);
573
76.6k
    if (code < 0)
574
0
        return code;
575
576
76.6k
    code = gs_setoverprintmode(ctx->pgs, i);
577
76.6k
    return code;
578
76.6k
}
579
580
static int GS_Font(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
581
5
{
582
5
    pdf_array *font_array = NULL;
583
5
    pdf_dict *font_dict = NULL;
584
5
    int code = 0;
585
5
    double point_size = 0.0;
586
587
5
    code = pdfi_dict_get_type(ctx, GS, "Font", PDF_ARRAY, (pdf_obj **)&font_array);
588
5
    if (code < 0)
589
5
        return code;
590
591
0
    if (pdfi_array_size(font_array) != 2)
592
0
        return_error(gs_error_rangecheck);
593
594
0
    code = pdfi_array_get(ctx, font_array, 0, (pdf_obj **)&font_dict);
595
0
    if (code < 0)
596
0
        goto GS_Font_error;
597
598
0
    code = pdfi_array_get_number(ctx, font_array, 1, &point_size);
599
0
    if (code < 0)
600
0
        goto GS_Font_error;
601
602
0
    code = pdfi_load_dict_font(ctx, stream_dict, page_dict, font_dict, point_size);
603
604
0
GS_Font_error:
605
0
    pdfi_countdown(font_array);
606
0
    pdfi_countdown(font_dict);
607
0
    return code;
608
0
}
609
610
static int pdfi_set_blackgeneration(pdf_context *ctx, pdf_obj *obj, pdf_dict *page_dict, bool is_BG)
611
13.6k
{
612
13.6k
    int code = 0, i;
613
13.6k
    gs_function_t *pfn;
614
615
13.6k
    switch (pdfi_type_of(obj)) {
616
13.4k
        case PDF_NAME:
617
13.4k
            if (is_BG) {
618
8
                code = pdfi_set_error_stop(ctx, gs_note_error(gs_error_typecheck), NULL, E_PDF_BG_ISNAME, "pdfi_set_blackgeneration", "");
619
13.4k
            } else {
620
13.4k
                if (pdfi_name_is((const pdf_name *)obj, "Identity"))
621
0
                    code = gs_setblackgeneration_remap(ctx->pgs, gs_identity_transfer, false);
622
13.4k
                else if (pdfi_name_is((const pdf_name *)obj, "Default")) {
623
13.4k
                    code = gs_setblackgeneration_remap(ctx->pgs, ctx->page.DefaultBG.proc, false);
624
13.4k
                    memcpy(ctx->pgs->black_generation->values, ctx->page.DefaultBG.values, transfer_map_size * sizeof(frac));
625
13.4k
                } else
626
0
                    code = pdfi_set_error_stop(ctx, gs_note_error(gs_error_rangecheck), NULL, E_PDF_BG_ISNAME, "pdfi_set_blackgeneration", "");
627
13.4k
            }
628
13.4k
            goto exit;
629
630
10
        case PDF_DICT:
631
206
        case PDF_STREAM:
632
206
            code = pdfi_build_function(ctx, &pfn, NULL, 1, obj, page_dict);
633
206
            if (code < 0)
634
22
                return code;
635
636
184
            if (pfn->params.n != 1) {
637
10
                pdfi_free_function(ctx, pfn);
638
10
                return_error(gs_error_rangecheck);
639
10
            }
640
641
174
            gs_setblackgeneration_remap(ctx->pgs, gs_mapped_transfer, false);
642
44.7k
            for (i = 0; i < transfer_map_size; i++) {
643
44.5k
                float v, f;
644
645
44.5k
                f = (1.0f / (transfer_map_size - 1)) * i;
646
647
44.5k
                code = gs_function_evaluate(pfn, (const float *)&f, &v);
648
44.5k
                if (code < 0) {
649
0
                    pdfi_free_function(ctx, pfn);
650
0
                    return code;
651
0
                }
652
653
44.5k
                ctx->pgs->black_generation->values[i] =
654
44.5k
                    (v < 0.0 ? float2frac(0.0) :
655
44.5k
                     v >= 1.0 ? frac_1 :
656
44.5k
                     float2frac(v));
657
44.5k
            }
658
174
            code = pdfi_free_function(ctx, pfn);
659
174
            break;
660
661
0
        default:
662
0
            return_error(gs_error_typecheck);
663
13.6k
    }
664
13.6k
exit:
665
13.6k
    return code;
666
13.6k
}
667
668
static int GS_BG(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
669
240
{
670
240
    int code;
671
240
    pdf_obj *obj = NULL;
672
673
    /* If the dictionary also has a BG2, then we must use that */
674
240
    code = pdfi_dict_get(ctx, GS, "BG2", &obj);
675
240
    if (code == 0) {
676
0
        pdfi_countdown(obj);
677
0
        return 0;
678
0
    }
679
680
240
    code = pdfi_dict_get(ctx, GS, "BG", &obj);
681
240
    if (code < 0)
682
26
        return code;
683
684
214
    code = pdfi_set_blackgeneration(ctx, obj, page_dict, true);
685
686
214
    pdfi_countdown(obj);
687
688
214
    return code;
689
240
}
690
691
static int GS_BG2(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
692
13.4k
{
693
13.4k
    int code;
694
13.4k
    pdf_obj *obj = NULL;
695
696
13.4k
    code = pdfi_dict_get(ctx, GS, "BG2", &obj);
697
13.4k
    if (code < 0)
698
0
        return code;
699
700
13.4k
    code = pdfi_set_blackgeneration(ctx, obj, page_dict, false);
701
702
13.4k
    pdfi_countdown(obj);
703
704
13.4k
    return code;
705
13.4k
}
706
707
static int pdfi_set_undercolorremoval(pdf_context *ctx, pdf_obj *obj, pdf_dict *page_dict, bool is_UCR)
708
13.6k
{
709
13.6k
    int code = 0, i;
710
13.6k
    gs_function_t *pfn;
711
712
13.6k
    switch (pdfi_type_of(obj)) {
713
13.4k
        case PDF_NAME:
714
13.4k
            if (is_UCR) {
715
8
                code = pdfi_set_error_stop(ctx, gs_note_error(gs_error_typecheck), NULL, E_PDF_UCR_ISNAME, "pdfi_set_undercolorremoval", "");
716
13.4k
            } else {
717
13.4k
                if (pdfi_name_is((const pdf_name *)obj, "Identity")) {
718
0
                    code = gs_setundercolorremoval_remap(ctx->pgs, gs_identity_transfer, false);
719
13.4k
                } else if (pdfi_name_is((const pdf_name *)obj, "Default")) {
720
13.4k
                    code = gs_setundercolorremoval_remap(ctx->pgs, ctx->page.DefaultUCR.proc, false);
721
13.4k
                    memcpy(ctx->pgs->undercolor_removal->values, ctx->page.DefaultUCR.values, transfer_map_size * sizeof(frac));
722
13.4k
                } else {
723
9
                    code = pdfi_set_error_stop(ctx, gs_note_error(gs_error_rangecheck), NULL, E_PDF_UCR_ISNAME, "pdfi_set_undercolorremoval", "");
724
9
                }
725
13.4k
            }
726
13.4k
            goto exit;
727
728
0
        case PDF_DICT:
729
168
        case PDF_STREAM:
730
168
            code = pdfi_build_function(ctx, &pfn, NULL, 1, obj, page_dict);
731
168
            if (code < 0)
732
0
                return code;
733
734
168
            if (pfn->params.n == 1) {
735
168
                gs_setundercolorremoval_remap(ctx->pgs, gs_mapped_transfer, false);
736
43.1k
                for (i = 0; i < transfer_map_size; i++) {
737
43.0k
                    float v, f;
738
739
43.0k
                    f = (1.0f / (transfer_map_size - 1)) * i;
740
741
43.0k
                    code = gs_function_evaluate(pfn, (const float *)&f, &v);
742
43.0k
                    if (code < 0) {
743
0
                        pdfi_free_function(ctx, pfn);
744
0
                        return code;
745
0
                    }
746
747
43.0k
                    ctx->pgs->undercolor_removal->values[i] =
748
43.0k
                        (v < 0.0 ? float2frac(0.0) :
749
43.0k
                         v >= 1.0 ? frac_1 :
750
42.4k
                         float2frac(v));
751
43.0k
                }
752
168
                code = pdfi_free_function(ctx, pfn);
753
168
            }
754
0
            else {
755
0
                (void)pdfi_free_function(ctx, pfn);
756
0
                code = gs_note_error(gs_error_rangecheck);
757
0
            }
758
168
            break;
759
760
168
        default:
761
0
            return_error(gs_error_typecheck);
762
13.6k
    }
763
13.6k
exit:
764
13.6k
    return code;
765
13.6k
}
766
767
static int GS_UCR(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
768
182
{
769
182
    int code;
770
182
    pdf_obj *obj = NULL;
771
772
    /* If the dictionary also has a UCR2, then we must use that and ignore the UCR */
773
182
    code = pdfi_dict_get(ctx, GS, "UCR2", &obj);
774
182
    if (code == 0) {
775
0
        pdfi_countdown(obj);
776
0
        return 0;
777
0
    }
778
779
182
    code = pdfi_dict_get(ctx, GS, "UCR", &obj);
780
182
    if (code < 0)
781
6
        return code;
782
783
176
    code = pdfi_set_undercolorremoval(ctx, obj, page_dict, true);
784
785
176
    pdfi_countdown(obj);
786
787
176
    return code;
788
182
}
789
790
static int GS_UCR2(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
791
13.4k
{
792
13.4k
    int code;
793
13.4k
    pdf_obj *obj = NULL;
794
795
13.4k
    code = pdfi_dict_get(ctx, GS, "UCR2", &obj);
796
13.4k
    if (code < 0)
797
0
        return code;
798
799
13.4k
    code = pdfi_set_undercolorremoval(ctx, obj, page_dict, false);
800
801
13.4k
    pdfi_countdown(obj);
802
803
13.4k
    return code;
804
13.4k
}
805
806
typedef enum {
807
    E_IDENTITY,
808
    E_DEFAULT,
809
    E_FUNCTION
810
} pdf_transfer_function_type_e;
811
812
/* We use this for both TR and TR2, is_TR is true if this is a TR, in which case we don't want
813
 * to permit /Default names for fucntions.
814
 */
815
static int pdfi_set_all_transfers(pdf_context *ctx, pdf_array *a, pdf_dict *page_dict, bool is_TR)
816
217
{
817
217
    int code = 0, i, j;
818
217
    pdf_obj *o = NULL;
819
217
    int proc_types[4];
820
217
    gs_mapping_proc map_procs[4];
821
217
    gs_function_t *pfn[4];
822
823
217
    memset(pfn, 0x00, 4 * sizeof(gs_function_t *));
824
217
    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
669
    for (i = 0; i < 4; i++) {
830
579
        code = pdfi_array_get(ctx, a, (uint64_t)i, &o);
831
579
        if (code < 0)
832
59
            goto exit;
833
520
        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
512
            case PDF_STREAM:
848
517
            case PDF_DICT:
849
517
                proc_types[i] = E_FUNCTION;
850
517
                map_procs[i] = gs_mapped_transfer;
851
517
                code = pdfi_build_function(ctx, &pfn[i], NULL, 1, o, page_dict);
852
517
                if (code < 0) {
853
65
                    pdfi_countdown(o);
854
65
                    goto exit;
855
65
                }
856
452
                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
452
                break;
862
452
            default:
863
3
                pdfi_countdown(o);
864
3
                code = gs_note_error(gs_error_typecheck);
865
3
                goto exit;
866
520
        }
867
452
        pdfi_countdown(o);
868
452
    }
869
90
    code = gs_setcolortransfer_remap(ctx->pgs, map_procs[0], map_procs[1], map_procs[2], map_procs[3], false);
870
90
    if (code < 0)
871
0
        goto exit;
872
873
    /* Second pass is to evaluate and set the transfer maps */
874
450
    for (j = 0; j < 4; j++) {
875
360
        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
360
        if (proc_types[j] == E_FUNCTION) {
892
92.5k
            for (i = 0; i < transfer_map_size; i++) {
893
92.1k
                float v, f;
894
92.1k
                frac value;
895
896
92.1k
                f = (1.0f / (transfer_map_size - 1)) * i;
897
898
92.1k
                code = gs_function_evaluate(pfn[j], (const float *)&f, &v);
899
92.1k
                if (code < 0)
900
0
                    goto exit;
901
902
92.1k
                value =
903
92.1k
                    (v < 0.0 ? float2frac(0.0) :
904
92.1k
                     v >= 1.0 ? frac_1 :
905
92.1k
                     float2frac(v));
906
92.1k
                switch(j) {
907
23.0k
                    case 0:
908
23.0k
                        ctx->pgs->set_transfer.red->values[i] = value;
909
23.0k
                        break;
910
23.0k
                    case 1:
911
23.0k
                        ctx->pgs->set_transfer.green->values[i] = value;
912
23.0k
                        break;
913
23.0k
                    case 2:
914
23.0k
                        ctx->pgs->set_transfer.blue->values[i] = value;
915
23.0k
                        break;
916
23.0k
                    case 3:
917
23.0k
                        ctx->pgs->set_transfer.gray->values[i] = value;
918
23.0k
                        break;
919
92.1k
                }
920
92.1k
            }
921
360
        }
922
360
    }
923
217
 exit:
924
1.08k
    for (i = 0; i < 4; i++) {
925
868
        pdfi_free_function(ctx, pfn[i]);
926
868
    }
927
217
    return code;
928
90
}
929
930
static int pdfi_set_gray_transfer(pdf_context *ctx, pdf_obj *tr_obj, pdf_dict *page_dict)
931
0
{
932
0
    int code = 0, i;
933
0
    gs_function_t *pfn;
934
935
0
    if (pdfi_type_of(tr_obj) != PDF_DICT && pdfi_type_of(tr_obj) != PDF_STREAM)
936
0
        return_error(gs_error_typecheck);
937
938
0
    code = pdfi_build_function(ctx, &pfn, NULL, 1, tr_obj, page_dict);
939
0
    if (code < 0)
940
0
        return code;
941
942
0
    if (pfn->params.m != 1 || pfn->params.n != 1) {
943
0
        (void)pdfi_free_function(ctx, pfn);
944
0
        return_error(gs_error_rangecheck);
945
0
    }
946
947
0
    gs_settransfer_remap(ctx->pgs, gs_mapped_transfer, false);
948
0
    for (i = 0; i < transfer_map_size; i++) {
949
0
        float v, f;
950
951
0
        f = (1.0f / (transfer_map_size - 1)) * i;
952
953
0
        code = gs_function_evaluate(pfn, (const float *)&f, &v);
954
0
        if (code < 0) {
955
0
            pdfi_free_function(ctx, pfn);
956
0
            return code;
957
0
        }
958
959
0
        ctx->pgs->set_transfer.gray->values[i] =
960
0
            (v < 0.0 ? float2frac(0.0) :
961
0
             v >= 1.0 ? frac_1 :
962
0
             float2frac(v));
963
0
    }
964
0
    return pdfi_free_function(ctx, pfn);
965
0
}
966
967
static int pdfi_set_transfer(pdf_context *ctx, pdf_obj *obj, pdf_dict *page_dict, bool is_TR)
968
17.4k
{
969
17.4k
    int code = 0;
970
971
17.4k
    if (pdfi_type_of(obj) == PDF_NAME) {
972
17.2k
        if (pdfi_name_is((const pdf_name *)obj, "Identity")) {
973
6.98k
            code = gs_settransfer_remap(ctx->pgs, gs_identity_transfer, false);
974
6.98k
            goto exit;
975
10.2k
        } else {
976
10.2k
            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.2k
            } else {
980
10.2k
                if (pdfi_name_is((const pdf_name *)obj, "Default")) {
981
10.2k
                    code = gs_settransfer_remap(ctx->pgs, ctx->page.DefaultTransfers[3].proc, false);
982
10.2k
                    memcpy(ctx->pgs->set_transfer.gray->values, ctx->page.DefaultTransfers[3].values, transfer_map_size * sizeof(frac));
983
10.2k
                    goto exit;
984
10.2k
                } else {
985
59
                    code = pdfi_set_error_stop(ctx, gs_note_error(gs_error_rangecheck), NULL, E_PDF_TR_NAME_NOT_IDENTITY, "pdfi_set_undercolorremoval", "");
986
59
                    goto exit;
987
59
                }
988
10.2k
            }
989
10.2k
        }
990
17.2k
    }
991
992
217
    if (pdfi_type_of(obj) == PDF_ARRAY) {
993
217
        if (pdfi_array_size((pdf_array *)obj) != 4) {
994
0
            code = gs_note_error(gs_error_rangecheck);
995
0
            goto exit;
996
217
        } else {
997
217
            code = pdfi_set_all_transfers(ctx, (pdf_array *)obj, page_dict, false);
998
217
        }
999
217
    } else
1000
0
        code = pdfi_set_gray_transfer(ctx, obj, page_dict);
1001
1002
17.4k
exit:
1003
17.4k
    return code;
1004
217
}
1005
1006
static int GS_TR(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
1007
7.19k
{
1008
7.19k
    int code;
1009
7.19k
    pdf_obj *obj = NULL;
1010
1011
7.19k
    code = pdfi_dict_get(ctx, GS, "TR", &obj);
1012
7.19k
    if (code < 0)
1013
0
        return code;
1014
1015
7.19k
    code = pdfi_set_transfer(ctx, obj, page_dict, true);
1016
1017
7.19k
    pdfi_countdown(obj);
1018
1019
7.19k
    return code;
1020
7.19k
}
1021
1022
static int GS_TR2(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
1023
10.2k
{
1024
10.2k
    int code;
1025
10.2k
    pdf_obj *obj = NULL;
1026
10.2k
    code = pdfi_dict_get(ctx, GS, "TR2", &obj);
1027
10.2k
    if (code < 0)
1028
0
        return code;
1029
1030
10.2k
    code = pdfi_set_transfer(ctx, obj, page_dict, false);
1031
1032
10.2k
    pdfi_countdown(obj);
1033
1034
10.2k
    return code;
1035
10.2k
}
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
31.3k
{
1143
31.3k
    int code, i, j;
1144
31.3k
    pdf_obj *obj = NULL, *transfer = NULL;
1145
31.3k
    double f, a;
1146
31.3k
    float values[2] = {0, 0}, domain[4] = {-1, 1, -1, 1}, out;
1147
31.3k
    gs_function_t *pfn = NULL;
1148
31.3k
    gx_ht_order *order = NULL;
1149
31.3k
    gs_screen_enum *penum = NULL;
1150
31.3k
    gs_point pt;
1151
31.3k
    gx_transfer_map *pmap = NULL;
1152
31.3k
    bool as;
1153
1154
31.3k
    code = pdfi_dict_get_number(ctx, halftone_dict, "Frequency", &f);
1155
31.3k
    if (code < 0)
1156
0
        return code;
1157
1158
31.3k
    code = pdfi_dict_get_number(ctx, halftone_dict, "Angle", &a);
1159
31.3k
    if (code < 0)
1160
8
        return code;
1161
1162
31.3k
    code = pdfi_dict_get(ctx, halftone_dict, "SpotFunction", &obj);
1163
31.3k
    if (code < 0)
1164
0
        return code;
1165
1166
31.3k
    code = pdfi_dict_get_bool(ctx, halftone_dict, "AccurateScreens", &as);
1167
31.3k
    if (code == gs_error_undefined)
1168
31.3k
        as = 0;
1169
0
    else if (code < 0)
1170
0
        return code;
1171
1172
31.3k
    order = (gx_ht_order *)gs_alloc_bytes(ctx->memory, sizeof(gx_ht_order), "build_type1_halftone");
1173
31.3k
    if (order == NULL) {
1174
0
        code = gs_note_error(gs_error_VMerror);
1175
0
        goto error;
1176
0
    }
1177
31.3k
    memset(order, 0x00, sizeof(gx_ht_order));
1178
1179
31.3k
    switch (pdfi_type_of(obj)) {
1180
31.3k
        case PDF_NAME:
1181
31.3k
            if (pdfi_name_is((pdf_name *)obj, "Default")) {
1182
0
                i = 0;
1183
31.3k
            } else {
1184
345k
                for (i = 0; i < (sizeof(spot_table) / sizeof (char *)); i++) {
1185
345k
                    if (pdfi_name_is((pdf_name *)obj, spot_table[i]))
1186
31.3k
                        break;
1187
345k
                }
1188
31.3k
                if (i >= (sizeof(spot_table) / sizeof (char *))) {
1189
0
                    code = gs_note_error(gs_error_rangecheck);
1190
0
                    goto error;
1191
0
                }
1192
31.3k
            }
1193
31.3k
            code = pdfi_build_halftone_function(ctx, &pfn, (byte *)spot_functions[i], strlen(spot_functions[i]));
1194
31.3k
            if (code < 0)
1195
0
                goto error;
1196
31.3k
            break;
1197
31.3k
        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
31.3k
    }
1244
1245
31.3k
    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
31.3k
    phtc->params.spot.screen.frequency = f;
1264
31.3k
    phtc->params.spot.screen.angle = a;
1265
31.3k
    phtc->params.spot.screen.spot_function = pdfi_spot1_dummy;
1266
31.3k
    phtc->params.spot.transfer = (code > 0 ? (gs_mapping_proc) 0 : gs_identity_transfer);
1267
31.3k
    phtc->params.spot.transfer_closure.proc = 0;
1268
31.3k
    phtc->params.spot.transfer_closure.data = 0;
1269
31.3k
    phtc->params.spot.accurate_screens = as;
1270
31.3k
    phtc->type = ht_type_spot;
1271
31.3k
    code = pdfi_get_name_index(ctx, name, len, (unsigned int *)&phtc->cname);
1272
31.3k
    if (code < 0)
1273
0
        goto error;
1274
1275
31.3k
    if (comp_num == -1)
1276
31.3k
        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
31.3k
    code = gs_screen_order_init_memory(order, ctx->pgs, &phtc->params.spot.screen,
1281
31.3k
                                       gs_currentaccuratescreens(ctx->memory), ctx->memory);
1282
31.3k
    if (code < 0)
1283
0
        goto error;
1284
1285
31.3k
    penum = gs_screen_enum_alloc(ctx->memory, "build_type1_halftone");
1286
31.3k
    if (penum == 0) {
1287
0
        code = gs_error_VMerror;
1288
0
        goto error;
1289
0
    }
1290
1291
31.3k
    code = gs_screen_enum_init_memory(penum, order, ctx->pgs, &phtc->params.spot.screen, ctx->memory);
1292
31.3k
    if (code < 0)
1293
0
        goto error;
1294
1295
282k
    do {
1296
        /* Generate x and y, the parameteric variables */
1297
282k
        code = gs_screen_currentpoint(penum, &pt);
1298
282k
        if (code < 0)
1299
0
            goto error;
1300
1301
282k
        if (code == 1)
1302
31.3k
            break;
1303
1304
        /* Process sample */
1305
251k
        values[0] = pt.x, values[1] = pt.y;
1306
251k
        code = gs_function_evaluate(pfn, (const float *)&values, &out);
1307
251k
        if (code < 0)
1308
0
            goto error;
1309
1310
        /* Store the sample */
1311
251k
        code = gs_screen_next(penum, out);
1312
251k
        if (code < 0)
1313
0
            goto error;
1314
1315
251k
    } while (1);
1316
31.3k
    code = 0;
1317
31.3k
    *porder = penum->order;
1318
31.3k
    (*porder).transfer = pmap;
1319
1320
31.3k
error:
1321
31.3k
    pdfi_countdown(transfer);
1322
31.3k
    pdfi_countdown(obj);
1323
31.3k
    pdfi_free_function(ctx, pfn);
1324
31.3k
    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
31.3k
    if (code < 0 && pmap != NULL)
1329
31.3k
        rc_decrement(pmap, "pdfi process_transfer");
1330
31.3k
    gs_free_object(ctx->memory, order, "build_type1_halftone");
1331
31.3k
    gs_free_object(ctx->memory, penum, "build_type1_halftone");
1332
31.3k
    return code;
1333
31.3k
}
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
31.3k
{
1548
31.3k
    int i=0;
1549
31.3k
    gs_halftone *pht = (gs_halftone *)data;
1550
31.3k
    gs_halftone_component comp;
1551
1552
62.7k
    for (i=0;i< pht->params.multiple.num_comp;i++) {
1553
31.3k
        comp = pht->params.multiple.components[i];
1554
31.3k
        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
31.3k
            default:
1564
31.3k
                break;
1565
31.3k
        }
1566
31.3k
    }
1567
31.3k
    gs_free_object(memory, pht->params.multiple.components, "pdfi_free_halftone");
1568
31.3k
    gs_free_object(memory, pht, "pdfi_free_halftone");
1569
31.3k
}
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
31.3k
{
1838
31.3k
    int code;
1839
31.3k
    char *str = NULL;
1840
31.3k
    int64_t type;
1841
31.3k
    gs_halftone *pht = NULL;
1842
31.3k
    gx_device_halftone *pdht = NULL;
1843
31.3k
    gs_halftone_component *phtc = NULL;
1844
31.3k
    pdf_obj *Key = NULL, *Value = NULL, *transfer = NULL;
1845
31.3k
    pdf_dict *halftone_dict = NULL;
1846
31.3k
    gx_transfer_map *pmap = NULL;
1847
1848
31.3k
    code = pdfi_dict_from_obj(ctx, halftone_obj, &halftone_dict);
1849
31.3k
    if (code < 0)
1850
0
        return code;
1851
1852
31.3k
    code = pdfi_dict_get_int(ctx, halftone_dict, "HalftoneType", &type);
1853
31.3k
    if (code < 0)
1854
0
        return code;
1855
1856
31.3k
    pht = (gs_halftone *)gs_alloc_bytes(ctx->memory, sizeof(gs_halftone), "pdfi_do_halftone");
1857
31.3k
    if (pht == 0) {
1858
0
        code = gs_note_error(gs_error_VMerror);
1859
0
        goto error;
1860
0
    }
1861
31.3k
    memset(pht, 0x00, sizeof(gs_halftone));
1862
31.3k
    pht->rc.memory = ctx->memory;
1863
31.3k
    pht->rc.free = pdfi_free_halftone;
1864
1865
31.3k
    pdht = (gx_device_halftone *)gs_alloc_bytes(ctx->memory, sizeof(gx_device_halftone), "pdfi_do_halftone");
1866
31.3k
    if (pdht == 0) {
1867
0
        code = gs_note_error(gs_error_VMerror);
1868
0
        goto error;
1869
0
    }
1870
31.3k
    memset(pdht, 0x00, sizeof(gx_device_halftone));
1871
31.3k
    pdht->num_dev_comp = ctx->pgs->device->color_info.num_components;
1872
31.3k
    pdht->rc.memory = ctx->memory;
1873
1874
31.3k
    switch(type) {
1875
31.3k
        case 1:
1876
31.3k
            phtc = (gs_halftone_component *)gs_alloc_bytes(ctx->memory, sizeof(gs_halftone_component), "pdfi_do_halftone");
1877
31.3k
            if (phtc == 0) {
1878
0
                code = gs_note_error(gs_error_VMerror);
1879
0
                goto error;
1880
0
            }
1881
1882
31.3k
            code = build_type1_halftone(ctx, halftone_dict, page_dict, &pdht->order, phtc, (char *)"Default", 7, -1);
1883
31.3k
            if (code < 0)
1884
8
                goto error;
1885
1886
31.3k
            pht->type = ht_type_multiple;
1887
31.3k
            pht->params.multiple.components = phtc;
1888
31.3k
            pht->params.multiple.num_comp = 1;
1889
31.3k
            pht->params.multiple.get_colorname_string = pdfi_separation_name_from_index;
1890
31.3k
            code = gx_gstate_dev_ht_install(ctx->pgs, pdht, pht->type, gs_currentdevice_inline(ctx->pgs), HT_OBJTYPE_DEFAULT);
1891
31.3k
            if (code < 0)
1892
0
                goto error;
1893
1894
31.3k
            gx_device_halftone_release(pdht, pdht->rc.memory);
1895
31.3k
            rc_decrement(ctx->pgs->halftone, "pdfi_do_halftone(halftone)");
1896
31.3k
            ctx->pgs->halftone = pht;
1897
31.3k
            rc_increment(ctx->pgs->halftone);
1898
31.3k
            gx_unset_both_dev_colors(ctx->pgs);
1899
31.3k
            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
31.3k
    }
2092
31.3k
    gs_free_object(ctx->memory, pdht, "pdfi_do_halftone");
2093
31.3k
    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
31.3k
}
2106
2107
static int GS_HT(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
2108
33.8k
{
2109
33.8k
    int code;
2110
33.8k
    pdf_obj *obj = NULL;
2111
2112
33.8k
    code = pdfi_dict_get(ctx, GS, "HT", &obj);
2113
33.8k
    if (code < 0)
2114
0
        return code;
2115
2116
2117
33.8k
    if (pdfi_type_of(obj) == PDF_NAME) {
2118
2.49k
        if (pdfi_name_is((const pdf_name *)obj, "Default")) {
2119
2.49k
            goto exit;
2120
2.49k
        } else {
2121
0
            code = gs_note_error(gs_error_rangecheck);
2122
0
            goto exit;
2123
0
        }
2124
31.3k
    } else {
2125
31.3k
        code = pdfi_do_halftone(ctx, obj, page_dict);
2126
31.3k
    }
2127
31.3k
    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
33.8k
exit:
2132
33.8k
    pdfi_countdown(obj);
2133
33.8k
    return code;
2134
31.3k
}
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.8k
{
2151
27.8k
    int code;
2152
27.8k
    double d1;
2153
2154
27.8k
    code = pdfi_dict_get_number(ctx, GS, "SM", &d1);
2155
27.8k
    if (code < 0)
2156
0
        return code;
2157
2158
27.8k
    code = gs_setsmoothness(ctx->pgs, d1);
2159
27.8k
    return code;
2160
27.8k
}
2161
2162
static int GS_SA(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
2163
111k
{
2164
111k
    bool b;
2165
111k
    int code;
2166
2167
111k
    code = pdfi_dict_get_bool(ctx, GS, "SA", &b);
2168
111k
    if (code < 0)
2169
0
        return code;
2170
2171
111k
    return gs_setstrokeadjust(ctx->pgs, b);
2172
111k
}
2173
2174
static int GS_BM(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
2175
111k
{
2176
111k
    pdf_name *n;
2177
111k
    int code;
2178
111k
    gs_blend_mode_t mode = 0; /* Start with /Normal */
2179
2180
111k
    code = pdfi_dict_get(ctx, GS, "BM", (pdf_obj **)&n);
2181
111k
    if (code < 0)
2182
0
        return code;
2183
2184
111k
    if (pdfi_type_of(n) == PDF_ARRAY) {
2185
52
        int i;
2186
52
        pdf_array *a = (pdf_array *)n;
2187
2188
52
        for (i=0;i < pdfi_array_size(a);i++){
2189
52
            code = pdfi_array_get_type(ctx, a, i, PDF_NAME, (pdf_obj **)&n);
2190
52
            if (code < 0)
2191
0
                continue;
2192
52
            code = pdfi_get_blend_mode(ctx, n, &mode);
2193
52
            pdfi_countdown(n);
2194
52
            if (code == 0)
2195
52
                break;
2196
52
        }
2197
52
        pdfi_countdown(a);
2198
52
        return gs_setblendmode(ctx->pgs, mode);
2199
52
    }
2200
2201
111k
    if (pdfi_type_of(n) == PDF_NAME) {
2202
111k
        code = pdfi_get_blend_mode(ctx, n, &mode);
2203
111k
        pdfi_countdown(n);
2204
111k
        if (code == 0)
2205
110k
            return gs_setblendmode(ctx->pgs, mode);
2206
111k
        return_error(gs_error_undefined);
2207
111k
    }
2208
111k
    return_error(gs_error_typecheck);
2209
111k
}
2210
2211
static int GS_SMask(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
2212
64.5k
{
2213
64.5k
    pdf_obj *o = NULL;
2214
64.5k
    pdfi_int_gstate *igs = (pdfi_int_gstate *)ctx->pgs->client_data;
2215
64.5k
    int code;
2216
64.5k
    bool Processed;
2217
2218
64.5k
    if (ctx->page.has_transparency == false || ctx->args.notransparency == true)
2219
17.4k
        return 0;
2220
2221
47.0k
    code = pdfi_dict_get(ctx, GS, "SMask", (pdf_obj **)&o);
2222
47.0k
    if (code < 0)
2223
302
        return code;
2224
2225
46.7k
    switch (pdfi_type_of(o)) {
2226
42.9k
        case PDF_NAME:
2227
42.9k
        {
2228
42.9k
            pdf_name *n = (pdf_name *)o;
2229
2230
42.9k
            if (pdfi_name_is(n, "None")) {
2231
42.8k
                if (igs->SMask) {
2232
4.92k
                    pdfi_gstate_smask_free(igs);
2233
4.92k
                    code = pdfi_trans_end_smask_notify(ctx);
2234
4.92k
                }
2235
42.8k
                goto exit;
2236
42.8k
            }
2237
73
            code = pdfi_find_resource(ctx, (unsigned char *)"ExtGState", n, stream_dict, page_dict, &o);
2238
73
            pdfi_countdown(n);
2239
73
            if (code < 0)
2240
73
                return code;
2241
0
            break;
2242
73
        }
2243
2244
3.84k
        case PDF_DICT:
2245
3.84k
        {
2246
3.84k
            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.84k
            if (code > 0 && Processed) {
2253
146
                code = pdfi_dict_put_bool(ctx, (pdf_dict *)o, "Processed", false);
2254
146
                if (code < 0)
2255
0
                    return code;
2256
146
            }
2257
3.84k
            if (igs->SMask)
2258
1.31k
                pdfi_gstate_smask_free(igs);
2259
            /* We need to use the graphics state memory, in case we are running under Ghostscript. */
2260
3.84k
            pdfi_gstate_smask_install(igs, ctx->pgs->memory, (pdf_dict *)o, ctx->pgs);
2261
3.84k
            break;
2262
3.84k
        }
2263
2264
13
        default:
2265
13
            break;
2266
46.7k
    }
2267
2268
46.6k
 exit:
2269
46.6k
    pdfi_countdown(o);
2270
46.6k
    return 0;
2271
46.7k
}
2272
2273
static int GS_CA(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
2274
135k
{
2275
135k
    int code;
2276
135k
    double d1;
2277
2278
135k
    code = pdfi_dict_get_number(ctx, GS, "CA", &d1);
2279
135k
    if (code < 0)
2280
4
        return code;
2281
2282
135k
    if (d1 > 1.0) {
2283
230
        pdfi_set_warning(ctx, 0, NULL, W_PDF_CA_OUTOFRANGE, "GS_CA", NULL);
2284
230
        d1 = 1.0;
2285
230
    }
2286
2287
135k
    if (d1 < 0.0) {
2288
30
        pdfi_set_warning(ctx, 0, NULL, W_PDF_CA_OUTOFRANGE, "GS_CA", NULL);
2289
30
        d1 = 0.0;
2290
30
    }
2291
2292
135k
    code = gs_setstrokeconstantalpha(ctx->pgs, d1);
2293
135k
    return code;
2294
135k
}
2295
2296
static int GS_ca(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
2297
132k
{
2298
132k
    int code;
2299
132k
    double d1;
2300
2301
132k
    code = pdfi_dict_get_number(ctx, GS, "ca", &d1);
2302
132k
    if (code < 0)
2303
0
        return code;
2304
2305
132k
    if (d1 > 1.0) {
2306
210
        pdfi_set_warning(ctx, 0, NULL, W_PDF_CA_OUTOFRANGE, "GS_ca", NULL);
2307
210
        d1 = 1.0;
2308
210
    }
2309
2310
132k
    if (d1 < 0.0) {
2311
30
        pdfi_set_warning(ctx, 0, NULL, W_PDF_CA_OUTOFRANGE, "GS_ca", NULL);
2312
30
        d1 = 0.0;
2313
30
    }
2314
2315
132k
    code = gs_setfillconstantalpha(ctx->pgs, d1);
2316
132k
    return code;
2317
132k
}
2318
2319
static int GS_AIS(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
2320
71.4k
{
2321
71.4k
    bool b;
2322
71.4k
    int code;
2323
2324
71.4k
    code = pdfi_dict_get_bool(ctx, GS, "AIS", &b);
2325
71.4k
    if (code < 0)
2326
0
        return code;
2327
2328
71.4k
    return gs_setalphaisshape(ctx->pgs, b);
2329
71.4k
}
2330
2331
static int GS_TK(pdf_context *ctx, pdf_dict *GS, pdf_dict *stream_dict, pdf_dict *page_dict)
2332
6.45k
{
2333
6.45k
    bool b;
2334
6.45k
    int code;
2335
2336
6.45k
    code = pdfi_dict_get_bool(ctx, GS, "TK", &b);
2337
6.45k
    if (code < 0)
2338
0
        return code;
2339
2340
6.45k
    return gs_settextknockout(ctx->pgs, b);
2341
6.45k
}
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
234k
{
2386
234k
    int code, i, limit = sizeof(ExtGStateTable) / sizeof (GS_Func_t);
2387
234k
    bool known;
2388
2389
6.31M
    for (i=0;i < limit; i++) {
2390
6.08M
        code = pdfi_dict_known(ctx, gstate_dict, ExtGStateTable[i].Name, &known);
2391
6.08M
        if (code < 0)
2392
0
            break;
2393
6.08M
        if (known) {
2394
992k
            code = ExtGStateTable[i].proc(ctx, gstate_dict, NULL, page_dict);
2395
992k
            if (code < 0)
2396
1.38k
                break;
2397
992k
        }
2398
6.08M
    }
2399
234k
    return code;
2400
234k
}
2401
2402
int pdfi_setgstate(pdf_context *ctx, pdf_dict *stream_dict, pdf_dict *page_dict)
2403
365k
{
2404
365k
    pdf_name *n = NULL;
2405
365k
    pdf_obj *o = NULL;
2406
365k
    int code=0, code1 = 0;
2407
2408
365k
    code = pdfi_loop_detector_mark(ctx);
2409
365k
    if (code < 0)
2410
0
        return code;
2411
2412
365k
    if (pdfi_count_stack(ctx) < 1) {
2413
8.32k
        code = gs_note_error(gs_error_stackunderflow);
2414
8.32k
        goto setgstate_error;
2415
8.32k
    }
2416
356k
    n = (pdf_name *)ctx->stack_top[-1];
2417
356k
    pdfi_countup(n);
2418
356k
    pdfi_pop(ctx, 1);
2419
2420
356k
    if (pdfi_type_of(n) != PDF_NAME) {
2421
8.26k
        code = gs_note_error(gs_error_typecheck);
2422
8.26k
        goto setgstate_error;
2423
8.26k
    }
2424
2425
348k
    code = pdfi_find_resource(ctx, (unsigned char *)"ExtGState", n, (pdf_dict *)stream_dict,
2426
348k
                              page_dict, &o);
2427
348k
    if (code < 0)
2428
110k
        goto setgstate_error;
2429
2430
237k
    if (pdfi_type_of(o) != PDF_DICT) {
2431
3.35k
        code = gs_note_error(gs_error_typecheck);
2432
3.35k
        goto setgstate_error;
2433
3.35k
    }
2434
2435
234k
    code = pdfi_set_ExtGState(ctx, stream_dict, page_dict, (pdf_dict *)o);
2436
2437
365k
setgstate_error:
2438
365k
    code1 = pdfi_loop_detector_cleartomark(ctx);
2439
365k
    if (code == 0) code = code1;
2440
2441
365k
    pdfi_countdown(n);
2442
365k
    pdfi_countdown(o);
2443
365k
    return code;
2444
234k
}
2445
2446
2447
int pdfi_free_DefaultQState(pdf_context *ctx)
2448
904k
{
2449
904k
    if (ctx->DefaultQState)
2450
692k
        gs_gstate_free(ctx->DefaultQState);
2451
904k
    ctx->DefaultQState = NULL;
2452
904k
    return 0;
2453
904k
}
2454
2455
int pdfi_set_DefaultQState(pdf_context *ctx, gs_gstate *pgs)
2456
692k
{
2457
692k
    pdfi_free_DefaultQState(ctx);
2458
    /* We need to use the graphics state memory, in case we are running under Ghostscript. */
2459
692k
    ctx->DefaultQState = gs_gstate_copy(pgs, ctx->pgs->memory);
2460
692k
    if (ctx->DefaultQState == NULL)
2461
0
        return_error(gs_error_VMerror);
2462
692k
    return 0;
2463
692k
}
2464
2465
gs_gstate *pdfi_get_DefaultQState(pdf_context *ctx)
2466
21.0k
{
2467
21.0k
    return ctx->DefaultQState;
2468
21.0k
}
2469
2470
int pdfi_copy_DefaultQState(pdf_context *ctx, gs_gstate **pgs)
2471
294k
{
2472
    /* We need to use the graphics state memory, in case we are running under Ghostscript. */
2473
294k
    *pgs = gs_gstate_copy(ctx->DefaultQState, ctx->pgs->memory);
2474
294k
    if (*pgs == NULL)
2475
0
        return_error(gs_error_VMerror);
2476
294k
    return 0;
2477
294k
}
2478
2479
int pdfi_restore_DefaultQState(pdf_context *ctx, gs_gstate **pgs)
2480
294k
{
2481
294k
    int code;
2482
2483
294k
    code = pdfi_set_DefaultQState(ctx, *pgs);
2484
294k
    gs_gstate_free(*pgs);
2485
    *pgs = NULL;
2486
294k
    return code;
2487
294k
}