Coverage Report

Created: 2026-07-24 07:44

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
24.8k
{
44
24.8k
    int code;
45
24.8k
    pdf_obj *o = NULL;
46
24.8k
    pdf_obj * rsubfn = NULL;
47
24.8k
    gs_function_AdOt_params_t params;
48
49
24.8k
    memset(&params, 0x00, sizeof(params));
50
51
24.8k
    code = pdfi_loop_detector_mark(ctx);
52
24.8k
    if (code < 0)
53
0
        return code;
54
55
24.8k
    code = pdfi_dict_get(ctx, shading_dict, "Function", &o);
56
24.8k
    if (code < 0)
57
2.83k
        goto build_shading_function_error;
58
59
22.0k
    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
22.0k
    } else {
110
22.0k
        code = pdfi_build_function(ctx, ppfn, shading_domain, num_inputs, o, page_dict);
111
22.0k
        if (code < 0)
112
1.50k
            goto build_shading_function_error;
113
22.0k
    }
114
115
20.5k
    (void)pdfi_loop_detector_cleartomark(ctx);
116
20.5k
    pdfi_countdown(o);
117
20.5k
    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
22.0k
}
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
23.1k
{
178
23.1k
    pdf_obj *o = NULL;
179
23.1k
    gs_shading_A_params_t params;
180
23.1k
    static const float default_Domain[2] = {0, 1};
181
23.1k
    int code, i;
182
23.1k
    pdf_dict *shading_dict;
183
184
23.1k
    if (pdfi_type_of(Shading) != PDF_DICT)
185
0
        return_error(gs_error_typecheck);
186
23.1k
    shading_dict = (pdf_dict *)Shading;
187
188
23.1k
    memset(&params, 0, sizeof(params));
189
23.1k
    *(gs_shading_params_t *)&params = *pcommon;
190
191
23.1k
    code = fill_float_array_from_dict(ctx, (float *)&params.Coords, 4, shading_dict, "Coords");
192
23.1k
    if (code < 0)
193
25
        return code;
194
23.1k
    code = fill_domain_from_dict(ctx, (float *)&params.Domain, 2, shading_dict);
195
23.1k
    if (code < 0) {
196
6.19k
        if (code == gs_error_undefined) {
197
18.5k
            for (i = 0; i < 2; i++) {
198
12.3k
                params.Domain[i] = default_Domain[i];
199
12.3k
            }
200
6.17k
        } else
201
18
            return code;
202
6.19k
    }
203
204
23.1k
    code = fill_bool_array_from_dict(ctx, (bool *)&params.Extend, 2, shading_dict, "Extend");
205
23.1k
    if (code < 0) {
206
362
        if (code == gs_error_undefined) {
207
356
            params.Extend[0] = params.Extend[1] = false;
208
356
        } else
209
6
            return code;
210
362
    }
211
212
23.1k
    code = pdfi_build_shading_function(ctx, &params.Function, (const float *)&params.Domain, 1, (pdf_dict *)shading_dict, page_dict);
213
23.1k
    if (code < 0){
214
3.07k
        pdfi_countdown(o);
215
3.07k
        return code;
216
3.07k
    }
217
20.0k
    code = gs_shading_A_init(ppsh, &params, ctx->memory);
218
20.0k
    if (code < 0){
219
6
        gs_function_free(params.Function, true, ctx->memory);
220
6
        params.Function = NULL;
221
6
        pdfi_countdown(o);
222
6
        return code;
223
6
    }
224
225
20.0k
    return 0;
226
20.0k
}
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
156
{
232
156
    pdf_obj *o = NULL;
233
156
    gs_shading_R_params_t params;
234
156
    static const float default_Domain[2] = {0, 1};
235
156
    int code, i;
236
156
    pdf_dict *shading_dict;
237
238
156
    if (pdfi_type_of(Shading) != PDF_DICT)
239
1
        return_error(gs_error_typecheck);
240
155
    shading_dict = (pdf_dict *)Shading;
241
242
155
    memset(&params, 0, sizeof(params));
243
155
    *(gs_shading_params_t *)&params = *pcommon;
244
245
155
    code = fill_float_array_from_dict(ctx, (float *)&params.Coords, 6, shading_dict, "Coords");
246
155
    if (code < 0)
247
3
        return code;
248
152
    code = fill_domain_from_dict(ctx, (float *)&params.Domain, 4, shading_dict);
249
152
    if (code < 0) {
250
91
        if (code == gs_error_undefined) {
251
273
            for (i = 0; i < 2; i++) {
252
182
                params.Domain[i] = default_Domain[i];
253
182
            }
254
91
        } else
255
0
            return code;
256
91
    }
257
258
152
    code = fill_bool_array_from_dict(ctx, (bool *)&params.Extend, 2, shading_dict, "Extend");
259
152
    if (code < 0) {
260
6
        if (code == gs_error_undefined) {
261
3
            params.Extend[0] = params.Extend[1] = false;
262
3
        } else
263
3
            return code;
264
6
    }
265
266
149
    code = pdfi_build_shading_function(ctx, &params.Function, (const float *)&params.Domain, 1, (pdf_dict *)shading_dict, page_dict);
267
149
    if (code < 0){
268
50
        pdfi_countdown(o);
269
50
        return code;
270
50
    }
271
99
    code = gs_shading_R_init(ppsh, &params, ctx->memory);
272
99
    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
99
    return 0;
280
99
}
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.63k
{
285
1.63k
    int num_decode = 4, code;
286
1.63k
    byte *data_source_buffer = NULL;
287
1.63k
    pdf_c_stream *shading_stream = NULL;
288
1.63k
    int64_t i;
289
1.63k
    pdf_dict *shading_dict;
290
291
1.63k
    if (pdfi_type_of(Shading) != PDF_STREAM)
292
10
        return_error(gs_error_typecheck);
293
294
1.62k
    code = pdfi_dict_from_obj(ctx, Shading, &shading_dict);
295
1.62k
    if (code < 0)
296
0
        return code;
297
298
1.62k
    params->Function = NULL;
299
1.62k
    params->Decode = NULL;
300
301
1.62k
    code = pdfi_open_memory_stream_from_filtered_stream(ctx, (pdf_stream *)Shading, &data_source_buffer, &shading_stream, false);
302
1.62k
    if (code < 0) {
303
21
        return code;
304
21
    }
305
306
1.60k
    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.60k
    gs_free_object(ctx->memory, shading_stream, "discard memory stream(pdf_stream)");
312
313
1.60k
    code = pdfi_build_shading_function(ctx, &params->Function, (const float *)NULL, 1,
314
1.60k
                                       shading_dict, page_dict);
315
1.60k
    if (code < 0 && code != gs_error_undefined)
316
41
        goto build_mesh_shading_error;
317
318
1.56k
    code = pdfi_dict_get_int(ctx, shading_dict, "BitsPerCoordinate", &i);
319
1.56k
    if (code < 0)
320
4
        goto build_mesh_shading_error;
321
322
1.56k
    if (i != 1 && i != 2 && i != 4 && i != 8 && i != 12 && i != 16 && i != 24 && i != 32) {
323
9
        code = gs_error_rangecheck;
324
9
        goto build_mesh_shading_error;
325
9
    }
326
327
1.55k
    params->BitsPerCoordinate = i;
328
329
1.55k
    code = pdfi_dict_get_int(ctx, shading_dict, "BitsPerComponent", &i);
330
1.55k
    if (code < 0)
331
8
        goto build_mesh_shading_error;
332
333
1.54k
    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.54k
    params->BitsPerComponent = i;
339
340
1.54k
    if (params->Function != NULL)
341
378
        num_decode += 2;
342
1.16k
    else
343
1.16k
        num_decode += gs_color_space_num_components(params->ColorSpace) * 2;
344
345
1.54k
    params->Decode = (float *) gs_alloc_byte_array(ctx->memory, num_decode, sizeof(float),
346
1.54k
                            "build_mesh_shading");
347
1.54k
    if (params->Decode == NULL) {
348
0
        code = gs_error_VMerror;
349
0
        goto build_mesh_shading_error;
350
0
    }
351
352
1.54k
    code = fill_float_array_from_dict(ctx, (float *)params->Decode, num_decode, shading_dict, "Decode");
353
1.54k
    if (code < 0)
354
19
        goto build_mesh_shading_error;
355
356
1.52k
    return 0;
357
358
81
build_mesh_shading_error:
359
81
    if (params->Function) {
360
14
        pdfi_free_function(ctx, params->Function);
361
14
        params->Function = NULL;
362
14
    }
363
81
    if (params->DataSource.data.strm != NULL) {
364
81
        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
81
    }
367
81
    gs_free_object(ctx->memory, params->Decode, "Decode");
368
81
    params->Decode = NULL;
369
81
    return code;
370
1.54k
}
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
367
{
376
367
    gs_shading_FfGt_params_t params;
377
367
    int code;
378
367
    int64_t i;
379
367
    pdf_dict *shading_dict;
380
381
367
    memset(&params, 0, sizeof(params));
382
367
    *(gs_shading_params_t *)&params = *pcommon;
383
384
367
    code = pdfi_build_mesh_shading(ctx, (gs_shading_mesh_params_t *)&params, Shading, stream_dict, page_dict);
385
367
    if (code < 0)
386
30
        goto error;
387
388
    /* pdfi_build_mesh_shading checks the type of the Shading object, so we don't need to here */
389
337
    code = pdfi_dict_from_obj(ctx, Shading, &shading_dict);
390
337
    if (code < 0)
391
0
        goto error;
392
393
337
    code = pdfi_dict_get_int(ctx, shading_dict, "BitsPerFlag", &i);
394
337
    if (code < 0)
395
3
        goto error;
396
397
334
    if (i != 2 && i != 4 && i != 8) {
398
9
        code = gs_note_error(gs_error_rangecheck);
399
9
        goto error;
400
9
    }
401
402
325
    params.BitsPerFlag = i;
403
404
325
    code = gs_shading_FfGt_init(ppsh, &params, ctx->memory);
405
325
    if (code < 0)
406
0
        goto error;
407
325
    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
12
        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
12
    }
418
42
    gs_free_object(ctx->memory, params.Decode, "Decode");
419
42
    params.Decode = NULL;
420
42
    return code;
421
325
}
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
343
{
427
343
    gs_shading_LfGt_params_t params;
428
343
    int code;
429
343
    int64_t i;
430
343
    pdf_dict *shading_dict;
431
432
343
    memset(&params, 0, sizeof(params));
433
343
    *(gs_shading_params_t *)&params = *pcommon;
434
435
343
    code = pdfi_build_mesh_shading(ctx, (gs_shading_mesh_params_t *)&params, Shading, stream_dict, page_dict);
436
343
    if (code < 0)
437
52
        goto error;
438
439
    /* pdfi_build_mesh_shading checks the type of the Shading object, so we don't need to here */
440
291
    code = pdfi_dict_from_obj(ctx, Shading, &shading_dict);
441
291
    if (code < 0)
442
0
        goto error;
443
444
291
    code = pdfi_dict_get_int(ctx, shading_dict, "VerticesPerRow", &i);
445
291
    if (code < 0)
446
2
        goto error;
447
448
289
    if (i < 2) {
449
0
        code = gs_note_error(gs_error_rangecheck);
450
0
        goto error;
451
0
    }
452
453
289
    params.VerticesPerRow = i;
454
455
289
    code = gs_shading_LfGt_init(ppsh, &params, ctx->memory);
456
289
    if (code < 0)
457
0
        goto error;
458
459
289
    return 0;
460
461
54
error:
462
54
    if (params.Function) {
463
2
        pdfi_free_function(ctx, params.Function);
464
2
        params.Function = NULL;
465
2
    }
466
54
    if (params.DataSource.data.strm != NULL) {
467
2
        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
2
    }
470
54
    gs_free_object(ctx->memory, params.Decode, "Decode");
471
54
    params.Decode = NULL;
472
54
    return code;
473
289
}
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
172
{
479
172
    gs_shading_Cp_params_t params;
480
172
    int code;
481
172
    int64_t i;
482
172
    pdf_dict *shading_dict;
483
484
172
    memset(&params, 0, sizeof(params));
485
172
    *(gs_shading_params_t *)&params = *pcommon;
486
487
172
    code = pdfi_build_mesh_shading(ctx, (gs_shading_mesh_params_t *)&params, Shading, stream_dict, page_dict);
488
172
    if (code < 0)
489
20
        goto error;
490
491
    /* pdfi_build_mesh_shading checks the type of the Shading object, so we don't need to here */
492
152
    code = pdfi_dict_from_obj(ctx, Shading, &shading_dict);
493
152
    if (code < 0)
494
0
        goto error;
495
496
152
    code = pdfi_dict_get_int(ctx, shading_dict, "BitsPerFlag", &i);
497
152
    if (code < 0)
498
2
        goto error;
499
500
150
    if (i != 2 && i != 4 && i != 8) {
501
0
        code = gs_note_error(gs_error_rangecheck);
502
0
        goto error;
503
0
    }
504
505
150
    params.BitsPerFlag = i;
506
507
150
    code = gs_shading_Cp_init(ppsh, &params, ctx->memory);
508
150
    if (code < 0)
509
0
        goto error;
510
150
    return 0;
511
512
22
error:
513
22
    if (params.Function) {
514
0
        pdfi_free_function(ctx, params.Function);
515
0
        params.Function = NULL;
516
0
    }
517
22
    if (params.DataSource.data.strm != NULL) {
518
2
        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
2
    }
521
22
    gs_free_object(ctx->memory, params.Decode, "Decode");
522
22
    params.Decode = NULL;
523
22
    return code;
524
150
}
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
757
{
530
757
    gs_shading_Tpp_params_t params;
531
757
    int code;
532
757
    int64_t i;
533
757
    pdf_dict *shading_dict;
534
535
757
    memset(&params, 0, sizeof(params));
536
757
    *(gs_shading_params_t *)&params = *pcommon;
537
538
757
    code = pdfi_build_mesh_shading(ctx, (gs_shading_mesh_params_t *)&params, Shading, stream_dict, page_dict);
539
757
    if (code < 0)
540
10
        goto error;
541
542
    /* pdfi_build_mesh_shading checks the type of the Shading object, so we don't need to here */
543
747
    code = pdfi_dict_from_obj(ctx, Shading, &shading_dict);
544
747
    if (code < 0)
545
0
        return code;
546
547
747
    code = pdfi_dict_get_int(ctx, shading_dict, "BitsPerFlag", &i);
548
747
    if (code < 0)
549
0
        goto error;
550
551
747
    if (i != 2 && i != 4 && i != 8) {
552
0
        code = gs_note_error(gs_error_rangecheck);
553
0
        goto error;
554
0
    }
555
556
747
    params.BitsPerFlag = i;
557
558
747
    code = gs_shading_Tpp_init(ppsh, &params, ctx->memory);
559
747
    if (code < 0)
560
0
        goto error;
561
747
    return 0;
562
563
10
error:
564
10
    if (params.Function) {
565
0
        pdfi_free_function(ctx, params.Function);
566
0
        params.Function = NULL;
567
0
    }
568
10
    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
10
    gs_free_object(ctx->memory, params.Decode, "Decode");
573
10
    params.Decode = NULL;
574
10
    return code;
575
747
}
576
577
static int get_shading_common(pdf_context *ctx, pdf_dict *shading_dict, gs_shading_params_t *params)
578
25.0k
{
579
25.0k
    gs_color_space *pcs = gs_currentcolorspace(ctx->pgs);
580
25.0k
    int code, num_comp = gs_color_space_num_components(pcs);
581
25.0k
    pdf_array *a = NULL;
582
25.0k
    double *temp;
583
584
25.0k
    if (num_comp < 0)  /* Pattern color space */
585
0
        return_error(gs_error_typecheck);
586
587
25.0k
    params->ColorSpace = pcs;
588
25.0k
    params->Background = NULL;
589
25.0k
    rc_increment_cs(pcs);
590
591
25.0k
    code = pdfi_dict_get_type(ctx, shading_dict, "Background", PDF_ARRAY, (pdf_obj **)&a);
592
25.0k
    if (code < 0 && code != gs_error_undefined)
593
0
        return code;
594
595
25.0k
    if (code >= 0) {
596
117
        uint64_t i;
597
117
        gs_client_color *pcc = NULL;
598
599
117
        if (pdfi_array_size(a) < num_comp) {
600
0
            code = gs_error_rangecheck;
601
0
            goto get_shading_common_error;
602
0
        }
603
604
117
        pcc = gs_alloc_struct(ctx->memory, gs_client_color, &st_client_color, "get_shading_common");
605
117
        if (pcc == 0) {
606
0
            code = gs_error_VMerror;
607
0
            goto get_shading_common_error;
608
0
        }
609
610
117
        pcc->pattern = 0;
611
117
        params->Background = pcc;
612
613
117
        temp = (double *)gs_alloc_bytes(ctx->memory, (size_t)num_comp * sizeof(double), "temporary array of doubles");
614
117
        if (temp == NULL) {
615
0
            code = gs_error_VMerror;
616
0
            goto get_shading_common_error;
617
0
        }
618
462
        for(i=0;i<num_comp;i++) {
619
348
            code = pdfi_array_get_number(ctx, a, i, &temp[i]);
620
348
            if (code < 0) {
621
3
                gs_free_object(ctx->memory, temp, "free workign array (error)");
622
3
                goto get_shading_common_error;
623
3
            }
624
345
            pcc->paint.values[i] = temp[i];
625
345
        }
626
114
        pdfi_countdown((pdf_obj *)a);
627
114
        a = NULL;
628
114
        gs_free_object(ctx->memory, temp, "free workign array (done)");
629
114
    }
630
631
632
25.0k
    code = pdfi_dict_get_type(ctx, shading_dict, "BBox", PDF_ARRAY, (pdf_obj **)&a);
633
25.0k
    if (code < 0 && code != gs_error_undefined)
634
0
        goto get_shading_common_error;
635
636
25.0k
    if (code >= 0) {
637
93
        double box[4];
638
93
        uint64_t i;
639
640
93
        if (pdfi_array_size(a) < 4) {
641
0
            code = gs_error_rangecheck;
642
0
            goto get_shading_common_error;
643
0
        }
644
645
465
        for(i=0;i<4;i++) {
646
372
            code = pdfi_array_get_number(ctx, a, i, &box[i]);
647
372
            if (code < 0)
648
0
                goto get_shading_common_error;
649
372
        }
650
        /* Adobe Interpreters accept denormalised BBox - bug 688937 */
651
93
        if (box[0] <= box[2]) {
652
93
            params->BBox.p.x = box[0];
653
93
            params->BBox.q.x = box[2];
654
93
        } else {
655
0
            params->BBox.p.x = box[2];
656
0
            params->BBox.q.x = box[0];
657
0
        }
658
93
        if (box[1] <= box[3]) {
659
93
            params->BBox.p.y = box[1];
660
93
            params->BBox.q.y = box[3];
661
93
        } else {
662
0
            params->BBox.p.y = box[3];
663
0
            params->BBox.q.y = box[1];
664
0
        }
665
93
        params->have_BBox = true;
666
24.9k
    } else {
667
24.9k
        params->have_BBox = false;
668
24.9k
    }
669
25.0k
    pdfi_countdown(a);
670
25.0k
    a = NULL;
671
672
25.0k
    code = pdfi_dict_get_bool(ctx, shading_dict, "AntiAlias", &params->AntiAlias);
673
25.0k
    if (code < 0 && code != gs_error_undefined)
674
0
        goto get_shading_common_error;
675
676
25.0k
    return 0;
677
3
get_shading_common_error:
678
3
    pdfi_countdown((pdf_obj *)a);
679
3
    gs_free_object(ctx->memory, params->Background, "Background (common_shading_error)");
680
3
    params->Background = NULL;
681
3
    return code;
682
25.0k
}
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
28.2k
{
689
28.2k
    gs_shading_params_t params;
690
28.2k
    gs_shading_t *psh = NULL;
691
28.2k
    pdf_obj *cspace = NULL;
692
28.2k
    int64_t type = 0;
693
28.2k
    int code = 0;
694
28.2k
    pdf_dict *sdict = NULL;
695
696
28.2k
    memset(&params, 0, sizeof(params));
697
698
28.2k
    params.ColorSpace = 0;
699
28.2k
    params.cie_joint_caches = 0;
700
28.2k
    params.Background = 0;
701
28.2k
    params.have_BBox = 0;
702
28.2k
    params.AntiAlias = 0;
703
704
28.2k
    code = pdfi_dict_from_obj(ctx, Shading, &sdict);
705
28.2k
    if (code < 0)
706
1
        return code;
707
708
28.2k
    code = pdfi_dict_get(ctx, sdict, "ColorSpace", &cspace);
709
28.2k
    if (code < 0)
710
1.45k
        goto shading_error;
711
712
26.8k
    code = pdfi_setcolorspace(ctx, cspace, stream_dict, page_dict);
713
26.8k
    if (code < 0)
714
1.76k
        goto shading_error;
715
716
25.0k
    code = get_shading_common(ctx, sdict, &params);
717
25.0k
    if (code < 0)
718
3
        goto shading_error;
719
720
25.0k
    code = pdfi_dict_get_int(ctx, sdict, "ShadingType", &type);
721
25.0k
    if (code < 0)
722
42
        goto shading_error;
723
724
24.9k
    switch(type){
725
10
    case 1:
726
10
        code = pdfi_shading1(ctx, &params, &psh, Shading, stream_dict, page_dict);
727
10
        break;
728
23.1k
    case 2:
729
23.1k
        code = pdfi_shading2(ctx, &params, &psh, Shading, stream_dict, page_dict);
730
23.1k
        break;
731
156
    case 3:
732
156
        code = pdfi_shading3(ctx, &params, &psh, Shading, stream_dict, page_dict);
733
156
        break;
734
367
    case 4:
735
367
        code = pdfi_shading4(ctx, &params, &psh, Shading, stream_dict, page_dict);
736
367
        break;
737
343
    case 5:
738
343
        code = pdfi_shading5(ctx, &params, &psh, Shading, stream_dict, page_dict);
739
343
        break;
740
172
    case 6:
741
172
        code = pdfi_shading6(ctx, &params, &psh, Shading, stream_dict, page_dict);
742
172
        break;
743
757
    case 7:
744
757
        code = pdfi_shading7(ctx, &params, &psh, Shading, stream_dict, page_dict);
745
757
        break;
746
10
    default:
747
10
        code = gs_note_error(gs_error_rangecheck);
748
10
        break;
749
24.9k
    }
750
24.9k
    if (code < 0)
751
3.33k
        goto shading_error;
752
753
21.6k
    pdfi_countdown(cspace);
754
21.6k
    *ppsh = psh;
755
21.6k
    return code;
756
757
6.60k
 shading_error:
758
6.60k
    if (cspace != NULL)
759
5.14k
        pdfi_countdown(cspace);
760
6.60k
    if (params.ColorSpace != NULL) {
761
3.38k
        rc_decrement_only(params.ColorSpace, "ColorSpace (shading_build_error)");
762
3.38k
        params.ColorSpace = NULL;
763
3.38k
    }
764
6.60k
    if (params.Background != NULL) {
765
49
        gs_free_object(ctx->memory, params.Background, "Background (shading_build_error)");
766
49
        params.Background = NULL;
767
49
    }
768
6.60k
    return code;
769
24.9k
}
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
21.6k
{
776
21.6k
    gs_shading_params_t *params = &psh->params;
777
778
21.6k
    rc_decrement_cs(params->ColorSpace, "pdfi_shading_free(ColorSpace)");
779
21.6k
    params->ColorSpace = NULL;
780
781
21.6k
    if (params->Background != NULL) {
782
65
        gs_free_object(ctx->memory, params->Background, "pdfi_shading_free(Background)");
783
65
        params->Background = NULL;
784
65
    }
785
786
21.6k
    if (psh->head.type > 3) {
787
1.51k
        gs_shading_mesh_params_t *mesh_params = (gs_shading_mesh_params_t *)params;
788
789
1.51k
        if (mesh_params->Decode != NULL) {
790
1.51k
            gs_free_object(ctx->memory, mesh_params->Decode, "release mesh shading Decode array");
791
1.51k
            mesh_params->Decode = NULL;
792
1.51k
        }
793
1.51k
        if (mesh_params->DataSource.data.strm != NULL) {
794
1.51k
            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.51k
        }
797
1.51k
    }
798
799
21.6k
    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
20.0k
    case 2:
805
20.0k
        if (((gs_shading_A_params_t *)&psh->params)->Function != NULL)
806
20.0k
            pdfi_free_function(ctx, ((gs_shading_A_params_t *)&psh->params)->Function);
807
20.0k
        break;
808
99
    case 3:
809
99
        if (((gs_shading_R_params_t *)&psh->params)->Function != NULL)
810
99
            pdfi_free_function(ctx, ((gs_shading_R_params_t *)&psh->params)->Function);
811
99
        break;
812
325
    case 4:
813
325
        if (((gs_shading_FfGt_params_t *)&psh->params)->Function != NULL)
814
7
            pdfi_free_function(ctx, ((gs_shading_FfGt_params_t *)&psh->params)->Function);
815
325
        break;
816
289
    case 5:
817
289
        if (((gs_shading_LfGt_params_t *)&psh->params)->Function != NULL)
818
277
            pdfi_free_function(ctx, ((gs_shading_LfGt_params_t *)&psh->params)->Function);
819
289
        break;
820
150
    case 6:
821
150
        if (((gs_shading_Cp_params_t *)&psh->params)->Function != NULL)
822
90
            pdfi_free_function(ctx, ((gs_shading_Cp_params_t *)&psh->params)->Function);
823
150
        break;
824
747
    case 7:
825
747
        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
747
        break;
828
0
    default:
829
0
        break;
830
21.6k
    }
831
21.6k
    gs_free_object(ctx->memory, psh, "Free shading, finished");
832
21.6k
}
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
932
{
838
932
    int code;
839
932
    gs_rect bbox, *box = NULL;
840
932
    pdf_array *BBox = NULL;
841
932
    pdf_dict *shading_dict;
842
843
932
    code = pdfi_dict_from_obj(ctx, Shading, &shading_dict);
844
932
    if (code < 0)
845
0
        return code;
846
847
932
    code = pdfi_dict_knownget_type(ctx, shading_dict, "BBox", PDF_ARRAY, (pdf_obj **)&BBox);
848
932
    if (code < 0)
849
0
        goto exit;
850
851
932
    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
932
    if (box == NULL) {
865
932
        code = pdfi_gsave(ctx);
866
932
        if (code < 0)
867
0
            goto exit;
868
869
932
        code = gs_newpath(ctx->pgs);
870
932
        if (code < 0)
871
0
            goto bbox_error;
872
873
932
        code = gs_clippath(ctx->pgs);
874
932
        if (code < 0)
875
0
            goto bbox_error;
876
877
932
        code = pdfi_get_current_bbox(ctx, &bbox, false);
878
879
932
bbox_error:
880
932
        pdfi_grestore(ctx);
881
882
932
        if (code < 0)
883
16
            goto exit;
884
885
916
        box = &bbox;
886
916
    }
887
916
    code = pdfi_trans_setup(ctx, state, box, TRANSPARENCY_Caller_Other);
888
889
932
 exit:
890
932
    pdfi_countdown(BBox);
891
932
    return code;
892
916
}
893
894
int pdfi_shading(pdf_context *ctx, pdf_dict *stream_dict, pdf_dict *page_dict)
895
64.1k
{
896
64.1k
    int code, code1;
897
64.1k
    pdf_name *n = NULL;
898
64.1k
    pdf_obj *Shading = NULL;
899
64.1k
    gs_shading_t *psh = NULL;
900
64.1k
    gs_offset_t savedoffset;
901
64.1k
    pdfi_trans_state_t trans_state;
902
64.1k
    int trans_required;
903
904
64.1k
    if (pdfi_count_stack(ctx) < 1)
905
524
        return_error(gs_error_stackunderflow);
906
907
63.6k
    if (ctx->text.BlockDepth != 0) {
908
316
        ctx->text.BlockDepth = 0;
909
316
        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
316
        code = pdfi_set_warning_stop(ctx, gs_note_error(gs_error_syntaxerror), NULL, W_PDF_OPINVALIDINTEXT, "pdfi_shading", NULL);
916
316
        if (code < 0)
917
0
            return code;
918
316
    }
919
920
63.6k
    if (pdfi_oc_is_off(ctx)) {
921
12
        pdfi_pop(ctx, 1);
922
12
        return 0;
923
12
    }
924
925
63.6k
    savedoffset = pdfi_tell(ctx->main_stream);
926
927
63.6k
    n = (pdf_name *)ctx->stack_top[-1];
928
63.6k
    pdfi_countup(n);
929
63.6k
    pdfi_pop(ctx, 1);
930
931
63.6k
    if (pdfi_type_of(n) != PDF_NAME) {
932
975
        pdfi_countdown(n);
933
975
        return gs_note_error(gs_error_typecheck);
934
975
    }
935
936
62.6k
    code = pdfi_loop_detector_mark(ctx);
937
62.6k
    if (code < 0) {
938
0
        pdfi_countdown(n);
939
0
        return code;
940
0
    }
941
942
62.6k
    code = pdfi_op_q(ctx);
943
62.6k
    if (code < 0)
944
0
        goto exit1;
945
946
62.6k
    code = pdfi_find_resource(ctx, (unsigned char *)"Shading", n, (pdf_dict *)stream_dict, page_dict,
947
62.6k
                              &Shading);
948
62.6k
    if (code < 0)
949
36.1k
        goto exit2;
950
951
26.4k
    if (pdfi_type_of(Shading) != PDF_DICT && pdfi_type_of(Shading) != PDF_STREAM) {
952
247
        code = gs_note_error(gs_error_typecheck);
953
247
        goto exit2;
954
247
    }
955
956
26.2k
    code = pdfi_trans_set_params(ctx);
957
26.2k
    if (code < 0)
958
45
        goto exit2;
959
960
    /* Shadings fills can't use overprint mode */
961
26.1k
    code = gs_setoverprintmode(ctx->pgs, 0);
962
26.1k
    if (code < 0)
963
0
        goto exit2;
964
965
26.1k
    code = pdfi_shading_build(ctx, stream_dict, page_dict, Shading, &psh);
966
26.1k
    if (code < 0)
967
5.95k
        goto exit2;
968
969
20.2k
    trans_required = pdfi_trans_required(ctx);
970
971
20.2k
    if (trans_required) {
972
932
        code = pdfi_shading_setup_trans(ctx, &trans_state, Shading);
973
932
        if (code < 0)
974
16
            goto exit2;
975
932
    }
976
977
20.2k
    code = gs_shfill(ctx->pgs, psh);
978
20.2k
    if (code < 0) {
979
479
        pdfi_set_warning(ctx, 0, NULL, W_PDF_BADSHADING, "pdfi_shading", (char *)"ERROR: ignoring invalid smooth shading object, output may be incorrect");
980
479
        code = 0;
981
479
    }
982
983
20.2k
    if (trans_required) {
984
916
        code1 = pdfi_trans_teardown(ctx, &trans_state);
985
916
        if (code == 0)
986
916
            code = code1;
987
916
    }
988
989
62.6k
 exit2:
990
62.6k
    if (psh)
991
20.2k
        pdfi_shading_free(ctx, psh);
992
993
62.6k
    pdfi_countdown(Shading);
994
62.6k
    code1 = pdfi_op_Q(ctx);
995
62.6k
    if (code == 0)
996
20.2k
        code = code1;
997
62.6k
 exit1:
998
62.6k
    pdfi_countdown(n);
999
62.6k
    (void)pdfi_loop_detector_cleartomark(ctx);
1000
    pdfi_seek(ctx, ctx->main_stream, savedoffset, SEEK_SET);
1001
62.6k
    return code;
1002
62.6k
}