Coverage Report

Created: 2026-02-14 07:09

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