Coverage Report

Created: 2026-10-28 08:05

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