Coverage Report

Created: 2026-08-08 08:00

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