Coverage Report

Created: 2026-04-09 07:06

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