Coverage Report

Created: 2025-08-28 07:06

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