Coverage Report

Created: 2026-09-14 07:34

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ghostpdl/pdf/pdf_shading.c
Line
Count
Source
1
/* Copyright (C) 2018-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
/* Shading operations for the PDF interpreter */
17
18
#include "pdf_int.h"
19
#include "pdf_stack.h"
20
#include "pdf_font_types.h"
21
#include "pdf_gstate.h"
22
#include "pdf_shading.h"
23
#include "pdf_dict.h"
24
#include "pdf_array.h"
25
#include "pdf_func.h"
26
#include "pdf_file.h"
27
#include "pdf_loop_detect.h"
28
#include "pdf_colour.h"
29
#include "pdf_trans.h"
30
#include "pdf_optcontent.h"
31
#include "pdf_doc.h"
32
#include "pdf_misc.h"
33
34
#include "gsfunc3.h"    /* for gs_function_Ad0t_params_t */
35
#include "gxshade.h"
36
#include "gsptype2.h"
37
#include "gsfunc0.h"    /* For gs_function */
38
#include "gscolor3.h"   /* For gs_shfill() */
39
#include "gsstate.h"    /* For gs_setoverprintmode */
40
#include "gxdevsop.h"               /* For special ops */
41
42
static int pdfi_build_shading_function(pdf_context *ctx, gs_function_t **ppfn, const float *shading_domain, int num_inputs, pdf_dict *shading_dict, pdf_dict *page_dict)
43
21.0k
{
44
21.0k
    int code;
45
21.0k
    int64_t type;
46
21.0k
    pdf_obj *o = NULL;
47
21.0k
    pdf_obj * rsubfn = NULL;
48
21.0k
    gs_function_AdOt_params_t params;
49
50
21.0k
    memset(&params, 0x00, sizeof(params));
51
52
21.0k
    code = pdfi_loop_detector_mark(ctx);
53
21.0k
    if (code < 0)
54
0
        return code;
55
56
21.0k
    code = pdfi_dict_get_int(ctx, shading_dict, "ShadingType", &type);
57
21.0k
    if (code < 0)
58
0
        goto build_shading_function_error;
59
60
21.0k
    code = pdfi_dict_get(ctx, shading_dict, "Function", &o);
61
21.0k
    if (code < 0)
62
2.55k
        goto build_shading_function_error;
63
64
18.5k
    if (pdfi_type_of(o) != PDF_DICT && pdfi_type_of(o) != PDF_STREAM) {
65
10
        uint size;
66
10
        pdf_obj *rsubfn;
67
10
        gs_function_t **Functions;
68
10
        int64_t i;
69
70
10
        if (pdfi_type_of(o) != PDF_ARRAY) {
71
3
            code = gs_error_typecheck;
72
3
            goto build_shading_function_error;
73
3
        }
74
7
        size = pdfi_array_size(((pdf_array *)o));
75
76
7
        if (size == 0) {
77
0
            code = gs_error_rangecheck;
78
0
            goto build_shading_function_error;
79
0
        }
80
7
        code = alloc_function_array(size, &Functions, ctx->memory);
81
7
        if (code < 0)
82
0
            goto build_shading_function_error;
83
84
7
        for (i = 0; i < size; ++i) {
85
7
            code = pdfi_array_get(ctx, (pdf_array *)o, i, &rsubfn);
86
7
            if (code == 0) {
87
7
                if (pdfi_type_of(rsubfn) != PDF_DICT && pdfi_type_of(rsubfn) != PDF_STREAM)
88
7
                    code = gs_note_error(gs_error_typecheck);
89
7
            }
90
7
            if (code < 0) {
91
7
                int j;
92
93
7
                for (j = 0;j < i; j++) {
94
0
                    pdfi_free_function(ctx, Functions[j]);
95
0
                    Functions[j] = NULL;
96
0
                }
97
7
                gs_free_object(ctx->memory, Functions, "function array error, freeing functions");
98
7
                goto build_shading_function_error;
99
7
            }
100
0
            code = pdfi_build_function(ctx, &Functions[i], shading_domain, num_inputs, rsubfn, page_dict);
101
0
            if (code < 0)
102
0
                goto build_shading_function_error;
103
            /* If we have an array of functions then it must be an array of 'n' 2-in, 1-out functions */
104
0
            if ((type == 1 && Functions[i]->params.m != 2) || (type > 1 && Functions[i]->params.m != 1) || Functions[i]->params.n != 1) {
105
0
                code = gs_note_error(gs_error_rangecheck);
106
0
                goto build_shading_function_error;
107
0
            }
108
0
            pdfi_countdown(rsubfn);
109
0
            rsubfn = NULL;
110
0
        }
111
0
        params.m = num_inputs;
112
0
        params.Domain = 0;
113
0
        params.n = size;
114
0
        params.Range = 0;
115
0
        params.Functions = (const gs_function_t * const *)Functions;
116
0
        code = gs_function_AdOt_init(ppfn, &params, ctx->memory);
117
0
        if (code < 0)
118
0
            goto build_shading_function_error;
119
18.5k
    } else {
120
18.5k
        code = pdfi_build_function(ctx, ppfn, shading_domain, num_inputs, o, page_dict);
121
18.5k
        if (code < 0)
122
1.39k
            goto build_shading_function_error;
123
18.5k
    }
124
125
17.1k
    (void)pdfi_loop_detector_cleartomark(ctx);
126
17.1k
    pdfi_countdown(o);
127
17.1k
    return code;
128
129
3.95k
build_shading_function_error:
130
3.95k
    gs_function_AdOt_free_params(&params, ctx->memory);
131
3.95k
    pdfi_countdown(rsubfn);
132
3.95k
    pdfi_countdown(o);
133
3.95k
    (void)pdfi_loop_detector_cleartomark(ctx);
134
3.95k
    return code;
135
18.5k
}
136
137
static int pdfi_shading1(pdf_context *ctx, gs_shading_params_t *pcommon,
138
                  gs_shading_t **ppsh,
139
                  pdf_obj *Shading, pdf_dict *stream_dict, pdf_dict *page_dict)
140
11
{
141
11
    pdf_obj *o = NULL;
142
11
    int code, i;
143
11
    gs_shading_Fb_params_t params;
144
11
    static const float default_Domain[4] = {0, 1, 0, 1};
145
11
    pdf_dict *shading_dict;
146
147
11
    if (pdfi_type_of(Shading) != PDF_DICT)
148
0
        return_error(gs_error_typecheck);
149
11
    shading_dict = (pdf_dict *)Shading;
150
151
11
    memset(&params, 0, sizeof(params));
152
11
    *(gs_shading_params_t *)&params = *pcommon;
153
11
    gs_make_identity(&params.Matrix);
154
11
    params.Function = 0;
155
156
11
    code = fill_domain_from_dict(ctx, (float *)&params.Domain, 4, shading_dict);
157
11
    if (code < 0) {
158
6
        if (code == gs_error_undefined) {
159
30
            for (i = 0; i < 4; i++) {
160
24
                params.Domain[i] = default_Domain[i];
161
24
            }
162
6
        } else
163
0
            return code;
164
6
    }
165
166
11
    code = fill_matrix_from_dict(ctx, (float *)&params.Matrix, shading_dict);
167
11
    if (code < 0 && code != gs_error_undefined)
168
0
        return code;
169
170
11
    code = pdfi_build_shading_function(ctx, &params.Function, (const float *)&params.Domain, 2, (pdf_dict *)shading_dict, page_dict);
171
11
    if (code < 0){
172
11
        pdfi_countdown(o);
173
11
        return code;
174
11
    }
175
0
    code = gs_shading_Fb_init(ppsh, &params, ctx->memory);
176
0
    if (code < 0) {
177
0
        gs_function_free(params.Function, true, ctx->memory);
178
0
        params.Function = NULL;
179
0
        pdfi_countdown(o);
180
0
    }
181
0
    return code;
182
11
}
183
184
static int pdfi_shading2(pdf_context *ctx, gs_shading_params_t *pcommon,
185
                  gs_shading_t **ppsh,
186
                  pdf_obj *Shading, pdf_dict *stream_dict, pdf_dict *page_dict)
187
19.3k
{
188
19.3k
    pdf_obj *o = NULL;
189
19.3k
    gs_shading_A_params_t params;
190
19.3k
    static const float default_Domain[2] = {0, 1};
191
19.3k
    int code, i;
192
19.3k
    pdf_dict *shading_dict;
193
194
19.3k
    if (pdfi_type_of(Shading) != PDF_DICT)
195
0
        return_error(gs_error_typecheck);
196
19.3k
    shading_dict = (pdf_dict *)Shading;
197
198
19.3k
    memset(&params, 0, sizeof(params));
199
19.3k
    *(gs_shading_params_t *)&params = *pcommon;
200
201
19.3k
    code = fill_float_array_from_dict(ctx, (float *)&params.Coords, 4, shading_dict, "Coords");
202
19.3k
    if (code < 0)
203
15
        return code;
204
19.3k
    code = fill_domain_from_dict(ctx, (float *)&params.Domain, 2, shading_dict);
205
19.3k
    if (code < 0) {
206
6.48k
        if (code == gs_error_undefined) {
207
19.4k
            for (i = 0; i < 2; i++) {
208
12.9k
                params.Domain[i] = default_Domain[i];
209
12.9k
            }
210
6.46k
        } else
211
12
            return code;
212
6.48k
    }
213
214
19.3k
    code = fill_bool_array_from_dict(ctx, (bool *)&params.Extend, 2, shading_dict, "Extend");
215
19.3k
    if (code < 0) {
216
328
        if (code == gs_error_undefined) {
217
322
            params.Extend[0] = params.Extend[1] = false;
218
322
        } else
219
6
            return code;
220
328
    }
221
222
19.3k
    code = pdfi_build_shading_function(ctx, &params.Function, (const float *)&params.Domain, 1, (pdf_dict *)shading_dict, page_dict);
223
19.3k
    if (code < 0){
224
2.75k
        pdfi_countdown(o);
225
2.75k
        return code;
226
2.75k
    }
227
16.5k
    code = gs_shading_A_init(ppsh, &params, ctx->memory);
228
16.5k
    if (code < 0){
229
6
        gs_function_free(params.Function, true, ctx->memory);
230
6
        params.Function = NULL;
231
6
        pdfi_countdown(o);
232
6
        return code;
233
6
    }
234
235
16.5k
    return 0;
236
16.5k
}
237
238
static int pdfi_shading3(pdf_context *ctx,  gs_shading_params_t *pcommon,
239
                  gs_shading_t **ppsh,
240
                  pdf_obj *Shading, pdf_dict *stream_dict, pdf_dict *page_dict)
241
218
{
242
218
    pdf_obj *o = NULL;
243
218
    gs_shading_R_params_t params;
244
218
    static const float default_Domain[2] = {0, 1};
245
218
    int code, i;
246
218
    pdf_dict *shading_dict;
247
248
218
    if (pdfi_type_of(Shading) != PDF_DICT)
249
1
        return_error(gs_error_typecheck);
250
217
    shading_dict = (pdf_dict *)Shading;
251
252
217
    memset(&params, 0, sizeof(params));
253
217
    *(gs_shading_params_t *)&params = *pcommon;
254
255
217
    code = fill_float_array_from_dict(ctx, (float *)&params.Coords, 6, shading_dict, "Coords");
256
217
    if (code < 0)
257
3
        return code;
258
214
    code = fill_domain_from_dict(ctx, (float *)&params.Domain, 4, shading_dict);
259
214
    if (code < 0) {
260
145
        if (code == gs_error_undefined) {
261
435
            for (i = 0; i < 2; i++) {
262
290
                params.Domain[i] = default_Domain[i];
263
290
            }
264
145
        } else
265
0
            return code;
266
145
    }
267
268
214
    code = fill_bool_array_from_dict(ctx, (bool *)&params.Extend, 2, shading_dict, "Extend");
269
214
    if (code < 0) {
270
3
        if (code == gs_error_undefined) {
271
3
            params.Extend[0] = params.Extend[1] = false;
272
3
        } else
273
0
            return code;
274
3
    }
275
276
214
    code = pdfi_build_shading_function(ctx, &params.Function, (const float *)&params.Domain, 1, (pdf_dict *)shading_dict, page_dict);
277
214
    if (code < 0){
278
43
        pdfi_countdown(o);
279
43
        return code;
280
43
    }
281
171
    code = gs_shading_R_init(ppsh, &params, ctx->memory);
282
171
    if (code < 0){
283
0
        gs_function_free(params.Function, true, ctx->memory);
284
0
        params.Function = NULL;
285
0
        pdfi_countdown(o);
286
0
        return code;
287
0
    }
288
289
171
    return 0;
290
171
}
291
292
static int pdfi_build_mesh_shading(pdf_context *ctx, gs_shading_mesh_params_t *params,
293
                  pdf_obj *Shading, pdf_dict *stream_dict, pdf_dict *page_dict)
294
1.55k
{
295
1.55k
    int num_decode = 4, code;
296
1.55k
    byte *data_source_buffer = NULL;
297
1.55k
    pdf_c_stream *shading_stream = NULL;
298
1.55k
    int64_t i;
299
1.55k
    pdf_dict *shading_dict;
300
301
1.55k
    if (pdfi_type_of(Shading) != PDF_STREAM)
302
10
        return_error(gs_error_typecheck);
303
304
1.54k
    code = pdfi_dict_from_obj(ctx, Shading, &shading_dict);
305
1.54k
    if (code < 0)
306
0
        return code;
307
308
1.54k
    params->Function = NULL;
309
1.54k
    params->Decode = NULL;
310
311
1.54k
    code = pdfi_open_memory_stream_from_filtered_stream(ctx, (pdf_stream *)Shading, &data_source_buffer, &shading_stream, false);
312
1.54k
    if (code < 0) {
313
16
        return code;
314
16
    }
315
316
1.52k
    data_source_init_stream(&params->DataSource, shading_stream->s);
317
318
    /* We need to clear up the PDF stream, but leave the underlying stream alone, that's now
319
     * pointed to by the params.DataSource member.
320
     */
321
1.52k
    gs_free_object(ctx->memory, shading_stream, "discard memory stream(pdf_stream)");
322
323
1.52k
    code = pdfi_build_shading_function(ctx, &params->Function, (const float *)NULL, 1,
324
1.52k
                                       shading_dict, page_dict);
325
1.52k
    if (code < 0 && code != gs_error_undefined)
326
37
        goto build_mesh_shading_error;
327
328
1.49k
    code = pdfi_dict_get_int(ctx, shading_dict, "BitsPerCoordinate", &i);
329
1.49k
    if (code < 0)
330
4
        goto build_mesh_shading_error;
331
332
1.48k
    if (i != 1 && i != 2 && i != 4 && i != 8 && i != 12 && i != 16 && i != 24 && i != 32) {
333
8
        code = gs_error_rangecheck;
334
8
        goto build_mesh_shading_error;
335
8
    }
336
337
1.48k
    params->BitsPerCoordinate = i;
338
339
1.48k
    code = pdfi_dict_get_int(ctx, shading_dict, "BitsPerComponent", &i);
340
1.48k
    if (code < 0)
341
4
        goto build_mesh_shading_error;
342
343
1.47k
    if (i != 1 && i != 2 && i != 4 && i != 8 && i != 12 && i != 16) {
344
0
        code = gs_error_rangecheck;
345
0
        goto build_mesh_shading_error;
346
0
    }
347
348
1.47k
    params->BitsPerComponent = i;
349
350
1.47k
    if (params->Function != NULL)
351
377
        num_decode += 2;
352
1.09k
    else
353
1.09k
        num_decode += gs_color_space_num_components(params->ColorSpace) * 2;
354
355
1.47k
    params->Decode = (float *) gs_alloc_byte_array(ctx->memory, num_decode, sizeof(float),
356
1.47k
                            "build_mesh_shading");
357
1.47k
    if (params->Decode == NULL) {
358
0
        code = gs_error_VMerror;
359
0
        goto build_mesh_shading_error;
360
0
    }
361
362
1.47k
    code = fill_float_array_from_dict(ctx, (float *)params->Decode, num_decode, shading_dict, "Decode");
363
1.47k
    if (code < 0)
364
15
        goto build_mesh_shading_error;
365
366
1.46k
    return 0;
367
368
68
build_mesh_shading_error:
369
68
    if (params->Function) {
370
10
        pdfi_free_function(ctx, params->Function);
371
10
        params->Function = NULL;
372
10
    }
373
68
    if (params->DataSource.data.strm != NULL) {
374
68
        s_close_filters(&params->DataSource.data.strm, params->DataSource.data.strm->strm);
375
        /* s_close_filters() sets the pointer to NULL so we don't need to */
376
68
    }
377
68
    gs_free_object(ctx->memory, params->Decode, "Decode");
378
68
    params->Decode = NULL;
379
68
    return code;
380
1.47k
}
381
382
static int pdfi_shading4(pdf_context *ctx, gs_shading_params_t *pcommon,
383
                  gs_shading_t **ppsh,
384
                  pdf_obj *Shading, pdf_dict *stream_dict, pdf_dict *page_dict)
385
322
{
386
322
    gs_shading_FfGt_params_t params;
387
322
    int code;
388
322
    int64_t i;
389
322
    pdf_dict *shading_dict;
390
391
322
    memset(&params, 0, sizeof(params));
392
322
    *(gs_shading_params_t *)&params = *pcommon;
393
394
322
    code = pdfi_build_mesh_shading(ctx, (gs_shading_mesh_params_t *)&params, Shading, stream_dict, page_dict);
395
322
    if (code < 0)
396
27
        goto error;
397
398
    /* pdfi_build_mesh_shading checks the type of the Shading object, so we don't need to here */
399
295
    code = pdfi_dict_from_obj(ctx, Shading, &shading_dict);
400
295
    if (code < 0)
401
0
        goto error;
402
403
295
    code = pdfi_dict_get_int(ctx, shading_dict, "BitsPerFlag", &i);
404
295
    if (code < 0)
405
2
        goto error;
406
407
293
    if (i != 2 && i != 4 && i != 8) {
408
8
        code = gs_note_error(gs_error_rangecheck);
409
8
        goto error;
410
8
    }
411
412
285
    params.BitsPerFlag = i;
413
414
285
    code = gs_shading_FfGt_init(ppsh, &params, ctx->memory);
415
285
    if (code < 0)
416
0
        goto error;
417
285
    return 0;
418
419
37
error:
420
37
    if (params.Function) {
421
0
        pdfi_free_function(ctx, params.Function);
422
0
        params.Function = NULL;
423
0
    }
424
37
    if (params.DataSource.data.strm != NULL) {
425
10
        s_close_filters(&params.DataSource.data.strm, params.DataSource.data.strm->strm);
426
        /* s_close_filters() sets the pointer to NULL so we don't need to */
427
10
    }
428
37
    gs_free_object(ctx->memory, params.Decode, "Decode");
429
37
    params.Decode = NULL;
430
37
    return code;
431
285
}
432
433
static int pdfi_shading5(pdf_context *ctx, gs_shading_params_t *pcommon,
434
                  gs_shading_t **ppsh,
435
                  pdf_obj *Shading, pdf_dict *stream_dict, pdf_dict *page_dict)
436
329
{
437
329
    gs_shading_LfGt_params_t params;
438
329
    int code;
439
329
    int64_t i;
440
329
    pdf_dict *shading_dict;
441
442
329
    memset(&params, 0, sizeof(params));
443
329
    *(gs_shading_params_t *)&params = *pcommon;
444
445
329
    code = pdfi_build_mesh_shading(ctx, (gs_shading_mesh_params_t *)&params, Shading, stream_dict, page_dict);
446
329
    if (code < 0)
447
43
        goto error;
448
449
    /* pdfi_build_mesh_shading checks the type of the Shading object, so we don't need to here */
450
286
    code = pdfi_dict_from_obj(ctx, Shading, &shading_dict);
451
286
    if (code < 0)
452
0
        goto error;
453
454
286
    code = pdfi_dict_get_int(ctx, shading_dict, "VerticesPerRow", &i);
455
286
    if (code < 0)
456
2
        goto error;
457
458
284
    if (i < 2) {
459
0
        code = gs_note_error(gs_error_rangecheck);
460
0
        goto error;
461
0
    }
462
463
284
    params.VerticesPerRow = i;
464
465
284
    code = gs_shading_LfGt_init(ppsh, &params, ctx->memory);
466
284
    if (code < 0)
467
0
        goto error;
468
469
284
    return 0;
470
471
45
error:
472
45
    if (params.Function) {
473
2
        pdfi_free_function(ctx, params.Function);
474
2
        params.Function = NULL;
475
2
    }
476
45
    if (params.DataSource.data.strm != NULL) {
477
2
        s_close_filters(&params.DataSource.data.strm, params.DataSource.data.strm->strm);
478
        /* s_close_filters() sets the pointer to NULL so we don't need to */
479
2
    }
480
45
    gs_free_object(ctx->memory, params.Decode, "Decode");
481
45
    params.Decode = NULL;
482
45
    return code;
483
284
}
484
485
static int pdfi_shading6(pdf_context *ctx, gs_shading_params_t *pcommon,
486
                  gs_shading_t **ppsh,
487
                  pdf_obj *Shading, pdf_dict *stream_dict, pdf_dict *page_dict)
488
171
{
489
171
    gs_shading_Cp_params_t params;
490
171
    int code;
491
171
    int64_t i;
492
171
    pdf_dict *shading_dict;
493
494
171
    memset(&params, 0, sizeof(params));
495
171
    *(gs_shading_params_t *)&params = *pcommon;
496
497
171
    code = pdfi_build_mesh_shading(ctx, (gs_shading_mesh_params_t *)&params, Shading, stream_dict, page_dict);
498
171
    if (code < 0)
499
14
        goto error;
500
501
    /* pdfi_build_mesh_shading checks the type of the Shading object, so we don't need to here */
502
157
    code = pdfi_dict_from_obj(ctx, Shading, &shading_dict);
503
157
    if (code < 0)
504
0
        goto error;
505
506
157
    code = pdfi_dict_get_int(ctx, shading_dict, "BitsPerFlag", &i);
507
157
    if (code < 0)
508
3
        goto error;
509
510
154
    if (i != 2 && i != 4 && i != 8) {
511
1
        code = gs_note_error(gs_error_rangecheck);
512
1
        goto error;
513
1
    }
514
515
153
    params.BitsPerFlag = i;
516
517
153
    code = gs_shading_Cp_init(ppsh, &params, ctx->memory);
518
153
    if (code < 0)
519
0
        goto error;
520
153
    return 0;
521
522
18
error:
523
18
    if (params.Function) {
524
0
        pdfi_free_function(ctx, params.Function);
525
0
        params.Function = NULL;
526
0
    }
527
18
    if (params.DataSource.data.strm != NULL) {
528
4
        s_close_filters(&params.DataSource.data.strm, params.DataSource.data.strm->strm);
529
        /* s_close_filters() sets the pointer to NULL so we don't need to */
530
4
    }
531
18
    gs_free_object(ctx->memory, params.Decode, "Decode");
532
18
    params.Decode = NULL;
533
18
    return code;
534
153
}
535
536
static int pdfi_shading7(pdf_context *ctx, gs_shading_params_t *pcommon,
537
                  gs_shading_t **ppsh,
538
                  pdf_obj *Shading, pdf_dict *stream_dict, pdf_dict *page_dict)
539
733
{
540
733
    gs_shading_Tpp_params_t params;
541
733
    int code;
542
733
    int64_t i;
543
733
    pdf_dict *shading_dict;
544
545
733
    memset(&params, 0, sizeof(params));
546
733
    *(gs_shading_params_t *)&params = *pcommon;
547
548
733
    code = pdfi_build_mesh_shading(ctx, (gs_shading_mesh_params_t *)&params, Shading, stream_dict, page_dict);
549
733
    if (code < 0)
550
10
        goto error;
551
552
    /* pdfi_build_mesh_shading checks the type of the Shading object, so we don't need to here */
553
723
    code = pdfi_dict_from_obj(ctx, Shading, &shading_dict);
554
723
    if (code < 0)
555
0
        return code;
556
557
723
    code = pdfi_dict_get_int(ctx, shading_dict, "BitsPerFlag", &i);
558
723
    if (code < 0)
559
0
        goto error;
560
561
723
    if (i != 2 && i != 4 && i != 8) {
562
0
        code = gs_note_error(gs_error_rangecheck);
563
0
        goto error;
564
0
    }
565
566
723
    params.BitsPerFlag = i;
567
568
723
    code = gs_shading_Tpp_init(ppsh, &params, ctx->memory);
569
723
    if (code < 0)
570
0
        goto error;
571
723
    return 0;
572
573
10
error:
574
10
    if (params.Function) {
575
0
        pdfi_free_function(ctx, params.Function);
576
0
        params.Function = NULL;
577
0
    }
578
10
    if (params.DataSource.data.strm != NULL) {
579
0
        s_close_filters(&params.DataSource.data.strm, params.DataSource.data.strm->strm);
580
        /* s_close_filters() sets the pointer to NULL so we don't need to */
581
0
    }
582
10
    gs_free_object(ctx->memory, params.Decode, "Decode");
583
10
    params.Decode = NULL;
584
10
    return code;
585
723
}
586
587
static int get_shading_common(pdf_context *ctx, pdf_dict *shading_dict, gs_shading_params_t *params)
588
21.2k
{
589
21.2k
    gs_color_space *pcs = gs_currentcolorspace(ctx->pgs);
590
21.2k
    int code, num_comp = gs_color_space_num_components(pcs);
591
21.2k
    pdf_array *a = NULL;
592
21.2k
    double *temp;
593
594
21.2k
    if (num_comp < 0)  /* Pattern color space */
595
0
        return_error(gs_error_typecheck);
596
597
21.2k
    params->ColorSpace = pcs;
598
21.2k
    params->Background = NULL;
599
21.2k
    rc_increment_cs(pcs);
600
601
21.2k
    code = pdfi_dict_get_type(ctx, shading_dict, "Background", PDF_ARRAY, (pdf_obj **)&a);
602
21.2k
    if (code < 0 && code != gs_error_undefined)
603
0
        return code;
604
605
21.2k
    if (code >= 0) {
606
108
        uint64_t i;
607
108
        gs_client_color *pcc = NULL;
608
609
108
        if (pdfi_array_size(a) < num_comp) {
610
0
            code = gs_error_rangecheck;
611
0
            goto get_shading_common_error;
612
0
        }
613
614
108
        pcc = gs_alloc_struct(ctx->memory, gs_client_color, &st_client_color, "get_shading_common");
615
108
        if (pcc == 0) {
616
0
            code = gs_error_VMerror;
617
0
            goto get_shading_common_error;
618
0
        }
619
620
108
        pcc->pattern = 0;
621
108
        params->Background = pcc;
622
623
108
        temp = (double *)gs_alloc_bytes(ctx->memory, (size_t)num_comp * sizeof(double), "temporary array of doubles");
624
108
        if (temp == NULL) {
625
0
            code = gs_error_VMerror;
626
0
            goto get_shading_common_error;
627
0
        }
628
426
        for(i=0;i<num_comp;i++) {
629
321
            code = pdfi_array_get_number(ctx, a, i, &temp[i]);
630
321
            if (code < 0) {
631
3
                gs_free_object(ctx->memory, temp, "free workign array (error)");
632
3
                goto get_shading_common_error;
633
3
            }
634
318
            pcc->paint.values[i] = temp[i];
635
318
        }
636
105
        pdfi_countdown((pdf_obj *)a);
637
105
        a = NULL;
638
105
        gs_free_object(ctx->memory, temp, "free workign array (done)");
639
105
    }
640
641
642
21.2k
    code = pdfi_dict_get_type(ctx, shading_dict, "BBox", PDF_ARRAY, (pdf_obj **)&a);
643
21.2k
    if (code < 0 && code != gs_error_undefined)
644
0
        goto get_shading_common_error;
645
646
21.2k
    if (code >= 0) {
647
90
        double box[4];
648
90
        uint64_t i;
649
650
90
        if (pdfi_array_size(a) < 4) {
651
0
            code = gs_error_rangecheck;
652
0
            goto get_shading_common_error;
653
0
        }
654
655
450
        for(i=0;i<4;i++) {
656
360
            code = pdfi_array_get_number(ctx, a, i, &box[i]);
657
360
            if (code < 0)
658
0
                goto get_shading_common_error;
659
360
        }
660
        /* Adobe Interpreters accept denormalised BBox - bug 688937 */
661
90
        if (box[0] <= box[2]) {
662
90
            params->BBox.p.x = box[0];
663
90
            params->BBox.q.x = box[2];
664
90
        } else {
665
0
            params->BBox.p.x = box[2];
666
0
            params->BBox.q.x = box[0];
667
0
        }
668
90
        if (box[1] <= box[3]) {
669
90
            params->BBox.p.y = box[1];
670
90
            params->BBox.q.y = box[3];
671
90
        } else {
672
0
            params->BBox.p.y = box[3];
673
0
            params->BBox.q.y = box[1];
674
0
        }
675
90
        params->have_BBox = true;
676
21.1k
    } else {
677
21.1k
        params->have_BBox = false;
678
21.1k
    }
679
21.2k
    pdfi_countdown(a);
680
21.2k
    a = NULL;
681
682
21.2k
    code = pdfi_dict_get_bool(ctx, shading_dict, "AntiAlias", &params->AntiAlias);
683
21.2k
    if (code < 0 && code != gs_error_undefined)
684
0
        goto get_shading_common_error;
685
686
21.2k
    return 0;
687
3
get_shading_common_error:
688
3
    pdfi_countdown((pdf_obj *)a);
689
3
    gs_free_object(ctx->memory, params->Background, "Background (common_shading_error)");
690
3
    params->Background = NULL;
691
3
    return code;
692
21.2k
}
693
694
/* Build gs_shading_t object from a Shading Dict */
695
int
696
pdfi_shading_build(pdf_context *ctx, pdf_dict *stream_dict, pdf_dict *page_dict,
697
                   pdf_obj *Shading, gs_shading_t **ppsh)
698
24.2k
{
699
24.2k
    gs_shading_params_t params;
700
24.2k
    gs_shading_t *psh = NULL;
701
24.2k
    pdf_obj *cspace = NULL;
702
24.2k
    int64_t type = 0;
703
24.2k
    int code = 0;
704
24.2k
    pdf_dict *sdict = NULL;
705
706
24.2k
    memset(&params, 0, sizeof(params));
707
708
24.2k
    params.ColorSpace = 0;
709
24.2k
    params.cie_joint_caches = 0;
710
24.2k
    params.Background = 0;
711
24.2k
    params.have_BBox = 0;
712
24.2k
    params.AntiAlias = 0;
713
714
24.2k
    code = pdfi_dict_from_obj(ctx, Shading, &sdict);
715
24.2k
    if (code < 0)
716
3
        return code;
717
718
24.2k
    code = pdfi_dict_get(ctx, sdict, "ColorSpace", &cspace);
719
24.2k
    if (code < 0)
720
1.43k
        goto shading_error;
721
722
22.7k
    code = pdfi_setcolorspace(ctx, cspace, stream_dict, page_dict);
723
22.7k
    if (code < 0)
724
1.58k
        goto shading_error;
725
726
21.2k
    code = get_shading_common(ctx, sdict, &params);
727
21.2k
    if (code < 0)
728
3
        goto shading_error;
729
730
21.2k
    code = pdfi_dict_get_int(ctx, sdict, "ShadingType", &type);
731
21.2k
    if (code < 0)
732
49
        goto shading_error;
733
734
21.1k
    switch(type){
735
11
    case 1:
736
11
        code = pdfi_shading1(ctx, &params, &psh, Shading, stream_dict, page_dict);
737
11
        break;
738
19.3k
    case 2:
739
19.3k
        code = pdfi_shading2(ctx, &params, &psh, Shading, stream_dict, page_dict);
740
19.3k
        break;
741
218
    case 3:
742
218
        code = pdfi_shading3(ctx, &params, &psh, Shading, stream_dict, page_dict);
743
218
        break;
744
322
    case 4:
745
322
        code = pdfi_shading4(ctx, &params, &psh, Shading, stream_dict, page_dict);
746
322
        break;
747
329
    case 5:
748
329
        code = pdfi_shading5(ctx, &params, &psh, Shading, stream_dict, page_dict);
749
329
        break;
750
171
    case 6:
751
171
        code = pdfi_shading6(ctx, &params, &psh, Shading, stream_dict, page_dict);
752
171
        break;
753
733
    case 7:
754
733
        code = pdfi_shading7(ctx, &params, &psh, Shading, stream_dict, page_dict);
755
733
        break;
756
9
    default:
757
9
        code = gs_note_error(gs_error_rangecheck);
758
9
        break;
759
21.1k
    }
760
21.1k
    if (code < 0)
761
2.97k
        goto shading_error;
762
763
18.1k
    pdfi_countdown(cspace);
764
18.1k
    *ppsh = psh;
765
18.1k
    return code;
766
767
6.04k
 shading_error:
768
6.04k
    if (cspace != NULL)
769
4.60k
        pdfi_countdown(cspace);
770
6.04k
    if (params.ColorSpace != NULL) {
771
3.02k
        rc_decrement_only(params.ColorSpace, "ColorSpace (shading_build_error)");
772
3.02k
        params.ColorSpace = NULL;
773
3.02k
    }
774
6.04k
    if (params.Background != NULL) {
775
41
        gs_free_object(ctx->memory, params.Background, "Background (shading_build_error)");
776
41
        params.Background = NULL;
777
41
    }
778
6.04k
    return code;
779
21.1k
}
780
781
/* Free stuff associated with a gs_shading_t.
782
 */
783
void
784
pdfi_shading_free(pdf_context *ctx, gs_shading_t *psh)
785
18.1k
{
786
18.1k
    gs_shading_params_t *params = &psh->params;
787
788
18.1k
    rc_decrement_cs(params->ColorSpace, "pdfi_shading_free(ColorSpace)");
789
18.1k
    params->ColorSpace = NULL;
790
791
18.1k
    if (params->Background != NULL) {
792
64
        gs_free_object(ctx->memory, params->Background, "pdfi_shading_free(Background)");
793
64
        params->Background = NULL;
794
64
    }
795
796
18.1k
    if (psh->head.type > 3) {
797
1.44k
        gs_shading_mesh_params_t *mesh_params = (gs_shading_mesh_params_t *)params;
798
799
1.44k
        if (mesh_params->Decode != NULL) {
800
1.44k
            gs_free_object(ctx->memory, mesh_params->Decode, "release mesh shading Decode array");
801
1.44k
            mesh_params->Decode = NULL;
802
1.44k
        }
803
1.44k
        if (mesh_params->DataSource.data.strm != NULL) {
804
1.44k
            s_close_filters(&mesh_params->DataSource.data.strm, mesh_params->DataSource.data.strm->strm);
805
            /* s_close_filters() sets the pointer to NULL so we don't need to */
806
1.44k
        }
807
1.44k
    }
808
809
18.1k
    switch(psh->head.type) {
810
0
    case 1:
811
0
        if (((gs_shading_Fb_params_t *)&psh->params)->Function != NULL)
812
0
            pdfi_free_function(ctx, ((gs_shading_Fb_params_t *)&psh->params)->Function);
813
0
        break;
814
16.5k
    case 2:
815
16.5k
        if (((gs_shading_A_params_t *)&psh->params)->Function != NULL)
816
16.5k
            pdfi_free_function(ctx, ((gs_shading_A_params_t *)&psh->params)->Function);
817
16.5k
        break;
818
171
    case 3:
819
171
        if (((gs_shading_R_params_t *)&psh->params)->Function != NULL)
820
171
            pdfi_free_function(ctx, ((gs_shading_R_params_t *)&psh->params)->Function);
821
171
        break;
822
285
    case 4:
823
285
        if (((gs_shading_FfGt_params_t *)&psh->params)->Function != NULL)
824
5
            pdfi_free_function(ctx, ((gs_shading_FfGt_params_t *)&psh->params)->Function);
825
285
        break;
826
284
    case 5:
827
284
        if (((gs_shading_LfGt_params_t *)&psh->params)->Function != NULL)
828
276
            pdfi_free_function(ctx, ((gs_shading_LfGt_params_t *)&psh->params)->Function);
829
284
        break;
830
153
    case 6:
831
153
        if (((gs_shading_Cp_params_t *)&psh->params)->Function != NULL)
832
92
            pdfi_free_function(ctx, ((gs_shading_Cp_params_t *)&psh->params)->Function);
833
153
        break;
834
723
    case 7:
835
723
        if (((gs_shading_Tpp_params_t *)&psh->params)->Function != NULL)
836
2
            pdfi_free_function(ctx, ((gs_shading_Tpp_params_t *)&psh->params)->Function);
837
723
        break;
838
0
    default:
839
0
        break;
840
18.1k
    }
841
18.1k
    gs_free_object(ctx->memory, psh, "Free shading, finished");
842
18.1k
}
843
844
/* Setup for transparency (see pdf_draw.ps/sh) */
845
static int
846
pdfi_shading_setup_trans(pdf_context *ctx, pdfi_trans_state_t *state, pdf_obj *Shading)
847
620
{
848
620
    int code;
849
620
    gs_rect bbox, *box = NULL;
850
620
    pdf_array *BBox = NULL;
851
620
    pdf_dict *shading_dict;
852
853
620
    code = pdfi_dict_from_obj(ctx, Shading, &shading_dict);
854
620
    if (code < 0)
855
0
        return code;
856
857
620
    code = pdfi_dict_knownget_type(ctx, shading_dict, "BBox", PDF_ARRAY, (pdf_obj **)&BBox);
858
620
    if (code < 0)
859
0
        goto exit;
860
861
620
    if (code > 0) {
862
0
        code = pdfi_array_to_gs_rect(ctx, BBox, &bbox);
863
0
        if (code >= 0)
864
0
            box = &bbox;
865
0
    }
866
867
    /* If we didn't get a BBox for the shading, then we need to create one, in order to
868
     * pass it to the transparency setup, which (potentially, at least, uses it to set
869
     * up a transparency group.
870
     * In the absence of anything better, we take the current clip, turn that into a path
871
     * and then get the bounding box of that path. Obviously we don't want to disturb the
872
     * current path in the graphics state, so we do a gsave/grestore round it.
873
     */
874
620
    if (box == NULL) {
875
620
        code = pdfi_gsave(ctx);
876
620
        if (code < 0)
877
0
            goto exit;
878
879
620
        code = gs_newpath(ctx->pgs);
880
620
        if (code < 0)
881
0
            goto bbox_error;
882
883
620
        code = gs_clippath(ctx->pgs);
884
620
        if (code < 0)
885
0
            goto bbox_error;
886
887
620
        code = pdfi_get_current_bbox(ctx, &bbox, false);
888
889
620
bbox_error:
890
620
        pdfi_grestore(ctx);
891
892
620
        if (code < 0)
893
16
            goto exit;
894
895
604
        box = &bbox;
896
604
    }
897
604
    code = pdfi_trans_setup(ctx, state, box, TRANSPARENCY_Caller_Other);
898
899
620
 exit:
900
620
    pdfi_countdown(BBox);
901
620
    return code;
902
604
}
903
904
int pdfi_shading(pdf_context *ctx, pdf_dict *stream_dict, pdf_dict *page_dict)
905
59.3k
{
906
59.3k
    int code, code1;
907
59.3k
    pdf_name *n = NULL;
908
59.3k
    pdf_obj *Shading = NULL;
909
59.3k
    gs_shading_t *psh = NULL;
910
59.3k
    gs_offset_t savedoffset;
911
59.3k
    pdfi_trans_state_t trans_state;
912
59.3k
    int trans_required;
913
914
59.3k
    if (pdfi_count_stack(ctx) < 1)
915
441
        return_error(gs_error_stackunderflow);
916
917
58.9k
    if (ctx->text.BlockDepth != 0) {
918
269
        ctx->text.BlockDepth = 0;
919
269
        if (ctx->text.TextClip) {
920
0
            gx_device *dev = gs_currentdevice_inline(ctx->pgs);
921
922
0
            ctx->text.TextClip = false;
923
0
            (void)dev_proc(dev, dev_spec_op)(dev, gxdso_hilevel_text_clip, (void *)0, 1);
924
0
        }
925
269
        code = pdfi_set_warning_stop(ctx, gs_note_error(gs_error_syntaxerror), NULL, W_PDF_OPINVALIDINTEXT, "pdfi_shading", NULL);
926
269
        if (code < 0)
927
0
            return code;
928
269
    }
929
930
58.9k
    if (pdfi_oc_is_off(ctx)) {
931
14
        pdfi_pop(ctx, 1);
932
14
        return 0;
933
14
    }
934
935
58.8k
    savedoffset = pdfi_tell(ctx->main_stream);
936
937
58.8k
    n = (pdf_name *)ctx->stack_top[-1];
938
58.8k
    pdfi_countup(n);
939
58.8k
    pdfi_pop(ctx, 1);
940
941
58.8k
    if (pdfi_type_of(n) != PDF_NAME) {
942
926
        pdfi_countdown(n);
943
926
        return gs_note_error(gs_error_typecheck);
944
926
    }
945
946
57.9k
    code = pdfi_loop_detector_mark(ctx);
947
57.9k
    if (code < 0) {
948
0
        pdfi_countdown(n);
949
0
        return code;
950
0
    }
951
952
57.9k
    code = pdfi_op_q(ctx);
953
57.9k
    if (code < 0)
954
0
        goto exit1;
955
956
57.9k
    code = pdfi_find_resource(ctx, (unsigned char *)"Shading", n, (pdf_dict *)stream_dict, page_dict,
957
57.9k
                              &Shading);
958
57.9k
    if (code < 0)
959
35.4k
        goto exit2;
960
961
22.4k
    if (pdfi_type_of(Shading) != PDF_DICT && pdfi_type_of(Shading) != PDF_STREAM) {
962
232
        code = gs_note_error(gs_error_typecheck);
963
232
        goto exit2;
964
232
    }
965
966
22.2k
    code = pdfi_trans_set_params(ctx);
967
22.2k
    if (code < 0)
968
33
        goto exit2;
969
970
    /* Shadings fills can't use overprint mode */
971
22.2k
    code = gs_setoverprintmode(ctx->pgs, 0);
972
22.2k
    if (code < 0)
973
0
        goto exit2;
974
975
22.2k
    code = pdfi_shading_build(ctx, stream_dict, page_dict, Shading, &psh);
976
22.2k
    if (code < 0)
977
5.47k
        goto exit2;
978
979
16.7k
    trans_required = pdfi_trans_required(ctx);
980
981
16.7k
    if (trans_required) {
982
620
        code = pdfi_shading_setup_trans(ctx, &trans_state, Shading);
983
620
        if (code < 0)
984
16
            goto exit2;
985
620
    }
986
987
16.7k
    code = gs_shfill(ctx->pgs, psh);
988
16.7k
    if (code < 0) {
989
471
        pdfi_set_warning(ctx, 0, NULL, W_PDF_BADSHADING, "pdfi_shading", (char *)"ERROR: ignoring invalid smooth shading object, output may be incorrect");
990
471
        code = 0;
991
471
    }
992
993
16.7k
    if (trans_required) {
994
604
        code1 = pdfi_trans_teardown(ctx, &trans_state);
995
604
        if (code == 0)
996
604
            code = code1;
997
604
    }
998
999
57.9k
 exit2:
1000
57.9k
    if (psh)
1001
16.7k
        pdfi_shading_free(ctx, psh);
1002
1003
57.9k
    pdfi_countdown(Shading);
1004
57.9k
    code1 = pdfi_op_Q(ctx);
1005
57.9k
    if (code == 0)
1006
16.7k
        code = code1;
1007
57.9k
 exit1:
1008
57.9k
    pdfi_countdown(n);
1009
57.9k
    (void)pdfi_loop_detector_cleartomark(ctx);
1010
    pdfi_seek(ctx, ctx->main_stream, savedoffset, SEEK_SET);
1011
57.9k
    return code;
1012
57.9k
}