Coverage Report

Created: 2026-04-01 07:17

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