Coverage Report

Created: 2022-10-31 07:00

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