Coverage Report

Created: 2025-06-10 06:49

/src/ghostpdl/psi/zshade.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2001-2023 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
17
/* PostScript language interface to shading */
18
#include "memory_.h"
19
#include "ghost.h"
20
#include "oper.h"
21
#include "gscolor3.h"
22
#include "gscspace.h"
23
#include "gscolor2.h"   /* requires gscspace.h */
24
#include "gsfunc3.h"
25
#include "gsptype2.h"
26
#include "gsstruct.h"   /* must precede gsshade.h */
27
#include "gsshade.h"
28
#include "gsuid.h"
29
#include "gscie.h"
30
#include "stream.h"   /* for files.h */
31
#include "files.h"
32
#include "ialloc.h"
33
#include "idict.h"
34
#include "idparam.h"
35
#include "ifunc.h"
36
#include "igstate.h"
37
#include "ipcolor.h"
38
#include "store.h"
39
40
/* Forward references */
41
static int shading_param(const_os_ptr op, const gs_shading_t ** ppsh);
42
43
/* ---------------- Standard operators ---------------- */
44
45
/* - currentsmoothness <smoothness> */
46
static int
47
zcurrentsmoothness(i_ctx_t *i_ctx_p)
48
0
{
49
0
    os_ptr op = osp;
50
51
0
    push(1);
52
0
    make_real(op, gs_currentsmoothness(igs));
53
0
    return 0;
54
0
}
55
56
/* <smoothness> setsmoothness - */
57
static int
58
zsetsmoothness(i_ctx_t *i_ctx_p)
59
8.71k
{
60
8.71k
    os_ptr op = osp;
61
8.71k
    double smoothness;
62
8.71k
    int code;
63
64
8.71k
    check_op(1);
65
8.71k
    if (real_param(op, &smoothness) < 0)
66
8.71k
        return_op_typecheck(op);
67
8.71k
    if ((code = gs_setsmoothness(igs, smoothness)) < 0)
68
0
        return code;
69
8.71k
    pop(1);
70
8.71k
    return 0;
71
8.71k
}
72
73
/* <shading> .shfill - */
74
static int
75
zshfill(i_ctx_t *i_ctx_p)
76
0
{
77
0
    os_ptr op = osp;
78
0
    const gs_shading_t *psh;
79
0
    int code;
80
81
0
    check_op(1);
82
0
    code = shading_param(op, &psh);
83
0
    if (code < 0 || (code = gs_shfill(igs, psh)) < 0)
84
0
        return code;
85
0
    pop(1);
86
0
    return 0;
87
0
}
88
89
/* ------ Non-standard operators ------ */
90
91
/* <pattern> <matrix> <shading> .buildshadingpattern <pattern> <instance> */
92
static int
93
zbuildshadingpattern(i_ctx_t *i_ctx_p)
94
0
{
95
0
    os_ptr op = osp;
96
0
    os_ptr op2 = op - 2;
97
0
    gs_matrix mat;
98
0
    gs_pattern2_template_t templat;
99
0
    int_pattern *pdata;
100
0
    gs_client_color cc_instance;
101
0
    int code;
102
103
0
    check_op(3);
104
0
    check_type(*op2, t_dictionary);
105
0
    check_dict_read(*op2);
106
0
    gs_pattern2_init(&templat);
107
0
    if ((code = read_matrix(imemory, op - 1, &mat)) < 0 ||
108
0
        (code = dict_uid_param(op2, &templat.uid, 1, imemory, i_ctx_p)) != 1 ||
109
0
        (code = shading_param(op, &templat.Shading)) < 0 ||
110
0
        (code = int_pattern_alloc(&pdata, op2, imemory)) < 0
111
0
        )
112
0
        return_error((code < 0 ? code : gs_error_rangecheck));
113
0
    code = gs_make_pattern(&cc_instance,
114
0
                           (const gs_pattern_template_t *)&templat,
115
0
                           &mat, igs, imemory);
116
0
    if (code < 0) {
117
0
        ifree_object(pdata, "int_pattern");
118
0
        return code;
119
0
    }
120
0
    cc_instance.pattern->client_data = pdata;
121
0
    make_istruct(op - 1, a_readonly, cc_instance.pattern);
122
0
    pop(1);
123
0
    return code;
124
0
}
125
126
/* ------ Internal procedures ------ */
127
128
/* Get a shading parameter. */
129
static int
130
shading_param(const_os_ptr op, const gs_shading_t ** ppsh)
131
0
{ /*
132
         * Since shadings form a subclass hierarchy, we currently have
133
         * no way to check whether a structure is actually a shading.
134
         */
135
0
    if (!r_is_struct(op) ||
136
0
        r_has_masked_attrs(op, a_execute, a_all)
137
0
        )
138
0
        return_error(gs_error_typecheck);
139
0
    *ppsh = (gs_shading_t *) op->value.pstruct;
140
0
    return 0;
141
0
}
142
143
/* ---------------- Shading dictionaries ---------------- */
144
145
/* ------ Common code ------ */
146
147
extern_st(st_color_space);
148
149
typedef int (*build_shading_proc_t)
150
     (i_ctx_t *i_ctx_p, const ref *op, const gs_shading_params_t *params,
151
      gs_shading_t **ppsh, gs_memory_t *mem);
152
153
/* Operators */
154
155
/* Common framework for building shadings. */
156
static int
157
build_shading(i_ctx_t *i_ctx_p, build_shading_proc_t proc)
158
0
{
159
0
    os_ptr op = osp;
160
0
    int code;
161
0
    float box[4];
162
0
    gs_shading_params_t params;
163
0
    gs_shading_t *psh;
164
0
    ref *pvalue;
165
166
0
    check_type(*op, t_dictionary);
167
0
    params.ColorSpace = 0;
168
0
    params.cie_joint_caches = 0;
169
0
    params.Background = 0;
170
    /* Collect parameters common to all shading types. */
171
0
    {
172
0
        gs_color_space *pcs = gs_currentcolorspace(igs);
173
0
        int num_comp = gs_color_space_num_components(pcs);
174
175
0
        if (num_comp < 0) { /* Pattern color space */
176
0
            gs_errorinfo_put_pair_from_dict(i_ctx_p, op, "ColorSpace");
177
0
            return_error(gs_error_typecheck);
178
0
        }
179
0
        params.ColorSpace = pcs;
180
0
        rc_increment_cs(pcs);
181
0
        if (dict_find_string(op, "Background", &pvalue) > 0) {
182
0
            gs_client_color *pcc =
183
0
                ialloc_struct(gs_client_color, &st_client_color,
184
0
                              "build_shading");
185
186
0
            if (pcc == 0) {
187
0
                code = gs_note_error(gs_error_VMerror);
188
0
                goto fail;
189
0
            }
190
0
            pcc->pattern = 0;
191
0
            params.Background = pcc;
192
0
            code = dict_floats_param(imemory, op, "Background",
193
0
                                     gs_color_space_num_components(pcs),
194
0
                                     pcc->paint.values, NULL);
195
0
            if (code < 0) {
196
0
                gs_errorinfo_put_pair_from_dict(i_ctx_p, op, "Background");
197
0
                goto fail;
198
0
            }
199
0
        }
200
0
    }
201
0
    if (dict_find_string(op, "BBox", &pvalue) <= 0)
202
0
        params.have_BBox = false;
203
0
    else if ((code = dict_floats_param(imemory, op, "BBox",
204
0
                                       4, box, NULL)) == 4) {
205
        /* Adobe Interpreters accept denormalised BBox - bug 688937 */
206
0
        if (box[0] <= box[2]) {
207
0
            params.BBox.p.x = box[0];
208
0
            params.BBox.q.x = box[2];
209
0
        } else {
210
0
            params.BBox.p.x = box[2];
211
0
            params.BBox.q.x = box[0];
212
0
        }
213
0
        if (box[1] <= box[3]) {
214
0
            params.BBox.p.y = box[1];
215
0
            params.BBox.q.y = box[3];
216
0
        } else {
217
0
            params.BBox.p.y = box[3];
218
0
            params.BBox.q.y = box[1];
219
0
        }
220
0
        params.have_BBox = true;
221
0
    } else {
222
0
        gs_errorinfo_put_pair_from_dict(i_ctx_p, op, "BBox");
223
0
        goto fail;
224
0
    }
225
0
    code = dict_bool_param(op, "AntiAlias", false, &params.AntiAlias);
226
0
    if (code < 0) {
227
0
        gs_errorinfo_put_pair_from_dict(i_ctx_p, op, "AntiAlias");
228
0
        goto fail;
229
0
    }
230
    /* Finish building the shading. */
231
0
    code = (*proc)(i_ctx_p, op, &params, &psh, imemory);
232
0
    if (code < 0)
233
0
        goto fail;
234
0
    if (gx_color_space_needs_cie_caches(psh->params.ColorSpace)) {
235
0
        rc_decrement(psh->params.cie_joint_caches, "build_shading");
236
        /* gx_currentciecaches_for_mem passes us a new reference */
237
0
        psh->params.cie_joint_caches = gx_get_cie_caches_ref(igs, imemory);
238
0
        if (psh->params.cie_joint_caches == NULL)
239
0
            return gs_error_VMerror;
240
0
    }
241
0
    make_istruct_new(op, 0, psh);
242
0
    return code;
243
0
fail:
244
0
    gs_free_object(imemory, params.Background, "Background");
245
0
    if (params.ColorSpace) {
246
0
        rc_decrement_only_cs(params.ColorSpace, "build_shading");
247
0
    }
248
0
    return (code < 0 ? code : gs_note_error(gs_error_rangecheck));
249
0
}
250
251
/* Collect a Function value. */
252
static int
253
build_shading_function(i_ctx_t *i_ctx_p, const ref * op, gs_function_t ** ppfn,
254
                 int num_inputs, gs_memory_t *mem, const float *shading_domain)
255
0
{
256
0
    ref *pFunction;
257
0
    int code;
258
259
0
    *ppfn = 0;
260
0
    if (dict_find_string(op, "Function", &pFunction) <= 0)
261
0
        return 0;
262
0
    if (r_is_array(pFunction)) {
263
0
        uint size = r_size(pFunction);
264
0
        gs_function_t **Functions;
265
0
        uint i;
266
0
        gs_function_AdOt_params_t params;
267
268
0
        check_read(*pFunction);
269
0
        if (size == 0)
270
0
            return_error(gs_error_rangecheck);
271
0
        code = alloc_function_array(size, &Functions, mem);
272
0
        if (code < 0)
273
0
            return code;
274
0
        for (i = 0; i < size; ++i) {
275
0
            ref rsubfn;
276
277
0
            array_get(imemory, pFunction, (long)i, &rsubfn);
278
0
            code = fn_build_function(i_ctx_p, &rsubfn, &Functions[i], mem,
279
0
               shading_domain, num_inputs);
280
0
            if (code < 0)
281
0
                break;
282
0
        }
283
0
        params.m = num_inputs;
284
0
        params.Domain = 0;
285
0
        params.n = size;
286
0
        params.Range = 0;
287
0
        params.Functions = (const gs_function_t * const *)Functions;
288
0
        if (code >= 0)
289
0
            code = gs_function_AdOt_init(ppfn, &params, mem);
290
0
        if (code < 0)
291
0
            gs_function_AdOt_free_params(&params, mem);
292
0
    } else {
293
0
        code = fn_build_function(i_ctx_p, pFunction, ppfn, mem,
294
0
            shading_domain, num_inputs);
295
0
        if (code < 0)
296
0
            return code;
297
0
        if ((*ppfn)->params.m != num_inputs) {
298
0
            gs_function_free(*ppfn, true, mem);
299
0
            return_error(gs_error_rangecheck);
300
0
        }
301
0
    }
302
0
    return code;
303
0
}
304
305
/* According to PLRM 3rd ed, p. 264  "indexed color space is not
306
 * allowed in any shading whose color values are generated by a function;
307
 * this applies to any shading dictionary that contains a Function entry."
308
 * Adobe interpreters follow PLRM in this respect and we follow them.
309
 */
310
static int
311
check_indexed_vs_function(i_ctx_t *i_ctx_p, const ref *op,
312
                          const gs_color_space *pcs, const gs_function_t *funct)
313
0
{ if (funct && gs_color_space_get_index(pcs) == gs_color_space_index_Indexed) {
314
0
    static const char fn[] = "Function";
315
0
    ref *f;
316
0
    if (dict_find_string(op, fn, &f) > 0)
317
0
        gs_errorinfo_put_pair(i_ctx_p, fn, sizeof(fn) - 1, f);
318
0
    return_error(gs_error_typecheck);  /* CET 12-14a */
319
0
  }
320
0
  return 0;
321
0
}
322
323
/* ------ Build shadings ------ */
324
325
/* Build a ShadingType 1 (Function-based) shading. */
326
static int
327
build_shading_1(i_ctx_t *i_ctx_p, const ref * op, const gs_shading_params_t * pcommon,
328
                gs_shading_t ** ppsh, gs_memory_t *mem)
329
0
{
330
0
    gs_shading_Fb_params_t params;
331
0
    int code;
332
0
    static const float default_Domain[4] = {0, 1, 0, 1};
333
0
    ref *pmatrix;
334
335
0
    *(gs_shading_params_t *)&params = *pcommon;
336
0
    gs_make_identity(&params.Matrix);
337
0
    params.Function = 0;
338
0
    code = dict_floats_param_errorinfo(i_ctx_p, op, "Domain",
339
0
                                  4, params.Domain, default_Domain);
340
0
    if (code < 0)
341
0
        goto out;
342
0
    if (params.Domain[0] > params.Domain[1] || params.Domain[2] > params.Domain[3]) {
343
0
        gs_errorinfo_put_pair_from_dict(i_ctx_p, op, "Domain");
344
0
        code = gs_note_error(gs_error_rangecheck);
345
0
        goto out; /* CPSI 3017 and CET 12-14b reject un-normalised domain */
346
0
    }
347
0
    if (dict_find_string(op, "Matrix", &pmatrix) > 0 ) {
348
0
        code = read_matrix(imemory, pmatrix, &params.Matrix);
349
0
        if (code < 0) {
350
0
            gs_errorinfo_put_pair_from_dict(i_ctx_p, op, "Matrix");
351
0
            goto out;
352
0
        }
353
0
    }
354
0
    code = build_shading_function(i_ctx_p, op, &params.Function, 2, mem, params.Domain);
355
0
    if (code < 0)
356
0
        goto out;
357
0
    if (params.Function == 0) {  /* Function is required */
358
0
        code = gs_note_error(gs_error_undefined);
359
0
        gs_errorinfo_put_pair_from_dict(i_ctx_p, op, "Function");
360
0
        goto out;
361
0
    }
362
0
    code = check_indexed_vs_function(i_ctx_p, op, params.ColorSpace, params.Function);
363
0
    if (code < 0)
364
0
        goto out;
365
0
    code = gs_shading_Fb_init(ppsh, &params, mem);
366
0
 out:;
367
0
    if (code < 0 && params.Function)
368
0
        gs_free_object(mem, params.Function, "Function");
369
0
    return code;
370
0
}
371
/* <dict> .buildshading1 <shading_struct> */
372
static int
373
zbuildshading1(i_ctx_t *i_ctx_p)
374
0
{
375
0
    return build_shading(i_ctx_p, build_shading_1);
376
0
}
377
378
/* Collect parameters for an Axial or Radial shading. */
379
static int
380
build_directional_shading(i_ctx_t *i_ctx_p, const ref * op, float *Coords, int num_Coords,
381
                          float Domain[2], gs_function_t ** pFunction,
382
                          bool Extend[2], gs_memory_t *mem)
383
0
{
384
0
    int code = dict_floats_param(imemory, op, "Coords",
385
0
                                 num_Coords, Coords, NULL);
386
0
    static const float default_Domain[2] = {0, 1};
387
0
    ref *pExtend;
388
389
0
    if (code >= 0 && code < num_Coords) {
390
0
        code = gs_note_error(gs_error_rangecheck);
391
0
    }
392
393
0
    *pFunction = 0;
394
0
    if (code < 0 ||
395
0
        (code = dict_floats_param_errorinfo(i_ctx_p, op, "Domain", 2, Domain,
396
0
                                  default_Domain)) < 0 ||
397
0
        (code = build_shading_function(i_ctx_p, op, pFunction, 1, mem, Domain)) < 0
398
0
        )
399
0
        return code;
400
0
    if (!*pFunction)
401
0
        return_error(gs_error_undefined);
402
0
    if (dict_find_string(op, "Extend", &pExtend) <= 0)
403
0
        Extend[0] = Extend[1] = false;
404
0
    else {
405
0
        ref E0, E1;
406
407
0
        if (!r_is_array(pExtend))
408
0
            return_error(gs_error_typecheck);
409
0
        else if (r_size(pExtend) != 2)
410
0
            return_error(gs_error_rangecheck);
411
0
        else if ((array_get(imemory, pExtend, 0L, &E0),
412
0
                  !r_has_type(&E0, t_boolean)) ||
413
0
                 (array_get(imemory, pExtend, 1L, &E1),
414
0
                  !r_has_type(&E1, t_boolean))
415
0
            )
416
0
            return_error(gs_error_typecheck);
417
0
        Extend[0] = E0.value.boolval, Extend[1] = E1.value.boolval;
418
0
    }
419
0
    return 0;
420
0
}
421
422
/* Build a ShadingType 2 (Axial) shading. */
423
static int
424
build_shading_2(i_ctx_t *i_ctx_p, const ref * op, const gs_shading_params_t * pcommon,
425
                gs_shading_t ** ppsh, gs_memory_t *mem)
426
0
{
427
0
    gs_shading_A_params_t params;
428
0
    int code;
429
430
0
    check_op(1);
431
0
    *(gs_shading_params_t *)&params = *pcommon;
432
0
    if ((code = build_directional_shading(i_ctx_p, op, params.Coords, 4,
433
0
                                          params.Domain, &params.Function,
434
0
                                          params.Extend, mem)) < 0 ||
435
0
        (code = check_indexed_vs_function(i_ctx_p, op, params.ColorSpace, params.Function)) < 0 ||
436
0
        (code = gs_shading_A_init(ppsh, &params, mem)) < 0
437
0
        ) {
438
0
        gs_free_object(mem, params.Function, "Function");
439
0
    }
440
0
    return code;
441
0
}
442
/* <dict> .buildshading2 <shading_struct> */
443
static int
444
zbuildshading2(i_ctx_t *i_ctx_p)
445
0
{
446
0
    return build_shading(i_ctx_p, build_shading_2);
447
0
}
448
449
/* Build a ShadingType 3 (Radial) shading. */
450
static int
451
build_shading_3(i_ctx_t *i_ctx_p, const ref * op, const gs_shading_params_t * pcommon,
452
                gs_shading_t ** ppsh, gs_memory_t *mem)
453
0
{
454
0
    gs_shading_R_params_t params;
455
0
    int code;
456
457
0
    *(gs_shading_params_t *)&params = *pcommon;
458
0
    if ((code = build_directional_shading(i_ctx_p, op, params.Coords, 6,
459
0
                                          params.Domain, &params.Function,
460
0
                                          params.Extend, mem)) < 0 ||
461
0
        (code = check_indexed_vs_function(i_ctx_p, op, params.ColorSpace, params.Function)) < 0 ||
462
0
        (code = gs_shading_R_init(ppsh, &params, mem)) < 0
463
0
        ) {
464
0
        gs_free_object(mem, params.Function, "Function");
465
0
    }
466
0
    if (params.Function == 0)   /* Function is required */
467
0
        return_error(gs_error_undefined);
468
0
    return code;
469
0
}
470
/* <dict> .buildshading3 <shading_struct> */
471
static int
472
zbuildshading3(i_ctx_t *i_ctx_p)
473
0
{
474
0
    return build_shading(i_ctx_p, build_shading_3);
475
0
}
476
477
/* Collect parameters for a mesh shading. */
478
static int
479
build_mesh_shading(i_ctx_t *i_ctx_p, const ref * op,
480
                   gs_shading_mesh_params_t * params,
481
                   float **pDecode, gs_function_t ** pFunction,
482
                   gs_memory_t *mem)
483
0
{
484
0
    int code;
485
0
    float *data = 0;
486
0
    ref *pDataSource;
487
488
0
    *pDecode = 0;
489
0
    *pFunction = 0;
490
0
    if (dict_find_string(op, "DataSource", &pDataSource) <= 0)
491
0
        return_error(gs_error_rangecheck);
492
0
    if (r_is_array(pDataSource)) {
493
0
        uint size = r_size(pDataSource);
494
495
0
        data = (float *)gs_alloc_byte_array(mem, size, sizeof(float),
496
0
                                            "build_mesh_shading");
497
0
        if (data == 0)
498
0
            return_error(gs_error_VMerror);
499
0
        code = process_float_array(mem, pDataSource, size, data);
500
0
        if (code < 0) {
501
0
            gs_free_object(mem, data, "build_mesh_shading");
502
0
            return code;
503
0
        }
504
0
        data_source_init_floats(&params->DataSource, data, size);
505
0
    } else
506
0
        switch (r_type(pDataSource)) {
507
0
            case t_file: {
508
0
                stream *s;
509
510
0
                check_read_file(i_ctx_p, s, pDataSource);
511
0
                data_source_init_stream(&params->DataSource, s);
512
0
                break;
513
0
            }
514
0
            case t_string:
515
0
                check_read(*pDataSource);
516
0
                data_source_init_string2(&params->DataSource,
517
0
                                         pDataSource->value.bytes,
518
0
                                         r_size(pDataSource));
519
0
                break;
520
0
            default:
521
0
                return_error(gs_error_typecheck);
522
0
        }
523
0
    code = build_shading_function(i_ctx_p, op, pFunction, 1, mem, NULL);
524
0
    if (code < 0) {
525
0
        gs_free_object(mem, data, "build_mesh_shading");
526
0
        return code;
527
0
    }
528
0
    if (data_source_is_array(params->DataSource)) {
529
0
        params->BitsPerCoordinate = 0;
530
0
        params->BitsPerComponent = 0;
531
0
    } else {
532
0
        int num_decode = 4 +
533
0
            (*pFunction != 0 ? 1 :
534
0
             gs_color_space_num_components(params->ColorSpace)) * 2;
535
536
0
        if ((code = dict_int_param(op, "BitsPerCoordinate", 1, 32, 0,
537
0
                                   &params->BitsPerCoordinate)) >= 0 &&
538
0
            (code = dict_int_param(op, "BitsPerComponent", 1, 16, 0,
539
0
                                   &params->BitsPerComponent)) >= 0
540
0
            ) {
541
0
            *pDecode = (float *)
542
0
                gs_alloc_byte_array(mem, num_decode, sizeof(float),
543
0
                                    "build_mesh_shading");
544
0
            if (*pDecode == 0)
545
0
                code = gs_note_error(gs_error_VMerror);
546
0
            else {
547
0
                code = dict_floats_param(mem, op, "Decode", num_decode, *pDecode, NULL);
548
0
                if (code < 0) {
549
0
                    gs_free_object(mem, *pDecode, "build_mesh_shading");
550
0
                    *pDecode = 0;
551
0
                }
552
0
            }
553
0
        }
554
0
    }
555
0
    if (code < 0) {
556
0
        if (*pFunction != 0) {
557
0
            gs_function_free(*pFunction, true, mem);
558
0
            *pFunction = 0;
559
0
        }
560
0
        gs_free_object(mem, data, "build_mesh_shading");
561
0
    }
562
0
    return code;
563
0
}
564
565
/* Collect the BitsPerFlag parameter, if relevant. */
566
static int
567
flag_bits_param(const ref * op, const gs_shading_mesh_params_t * params,
568
                int *pBitsPerFlag)
569
0
{
570
0
    if (data_source_is_array(params->DataSource)) {
571
0
        *pBitsPerFlag = 0;
572
0
        return 0;
573
0
    } else {
574
0
        return dict_int_param(op, "BitsPerFlag", 2, 8, 0, pBitsPerFlag);
575
0
    }
576
0
}
577
578
/* Build a ShadingType 4 (Free-form Gouraud triangle mesh) shading. */
579
static int
580
build_shading_4(i_ctx_t *i_ctx_p, const ref * op, const gs_shading_params_t * pcommon,
581
                gs_shading_t ** ppsh, gs_memory_t *mem)
582
0
{
583
0
    gs_shading_FfGt_params_t params;
584
0
    int code;
585
586
0
    *(gs_shading_params_t *)&params = *pcommon;
587
0
    if ((code =
588
0
         build_mesh_shading(i_ctx_p, op, (gs_shading_mesh_params_t *)&params,
589
0
                            &params.Decode, &params.Function, mem)) < 0 ||
590
0
        (code = check_indexed_vs_function(i_ctx_p, op, params.ColorSpace, params.Function)) < 0 ||
591
0
        (code = flag_bits_param(op, (gs_shading_mesh_params_t *)&params,
592
0
                                &params.BitsPerFlag)) < 0 ||
593
0
        (code = gs_shading_FfGt_init(ppsh, &params, mem)) < 0
594
0
        ) {
595
0
        gs_free_object(mem, params.Function, "Function");
596
0
        gs_free_object(mem, params.Decode, "Decode");
597
0
    }
598
0
    return code;
599
0
}
600
/* <dict> .buildshading4 <shading_struct> */
601
static int
602
zbuildshading4(i_ctx_t *i_ctx_p)
603
0
{
604
0
    return build_shading(i_ctx_p, build_shading_4);
605
0
}
606
607
/* Build a ShadingType 5 (Lattice-form Gouraud triangle mesh) shading. */
608
static int
609
build_shading_5(i_ctx_t *i_ctx_p, const ref * op, const gs_shading_params_t * pcommon,
610
                gs_shading_t ** ppsh, gs_memory_t *mem)
611
0
{
612
0
    gs_shading_LfGt_params_t params;
613
0
    int code;
614
615
0
    *(gs_shading_params_t *)&params = *pcommon;
616
0
    if ((code =
617
0
         build_mesh_shading(i_ctx_p, op, (gs_shading_mesh_params_t *)&params,
618
0
                            &params.Decode, &params.Function, mem)) < 0 ||
619
0
        (code = check_indexed_vs_function(i_ctx_p, op, params.ColorSpace, params.Function)) < 0 ||
620
0
        (code = dict_int_param(op, "VerticesPerRow", 2, max_int, 0,
621
0
                               &params.VerticesPerRow)) < 0 ||
622
0
        (code = gs_shading_LfGt_init(ppsh, &params, mem)) < 0
623
0
        ) {
624
0
        gs_free_object(mem, params.Function, "Function");
625
0
        gs_free_object(mem, params.Decode, "Decode");
626
0
    }
627
0
    return code;
628
0
}
629
/* <dict> .buildshading5 <shading_struct> */
630
static int
631
zbuildshading5(i_ctx_t *i_ctx_p)
632
0
{
633
0
    return build_shading(i_ctx_p, build_shading_5);
634
0
}
635
636
/* Build a ShadingType 6 (Coons patch mesh) shading. */
637
static int
638
build_shading_6(i_ctx_t *i_ctx_p, const ref * op, const gs_shading_params_t * pcommon,
639
                gs_shading_t ** ppsh, gs_memory_t *mem)
640
0
{
641
0
    gs_shading_Cp_params_t params;
642
0
    int code;
643
644
0
    *(gs_shading_params_t *)&params = *pcommon;
645
0
    if ((code =
646
0
         build_mesh_shading(i_ctx_p, op, (gs_shading_mesh_params_t *)&params,
647
0
                            &params.Decode, &params.Function, mem)) < 0 ||
648
0
        (code = check_indexed_vs_function(i_ctx_p, op, params.ColorSpace, params.Function)) < 0 ||
649
0
        (code = flag_bits_param(op, (gs_shading_mesh_params_t *)&params,
650
0
                                &params.BitsPerFlag)) < 0 ||
651
0
        (code = gs_shading_Cp_init(ppsh, &params, mem)) < 0
652
0
        ) {
653
0
        gs_free_object(mem, params.Function, "Function");
654
0
        gs_free_object(mem, params.Decode, "Decode");
655
0
    }
656
0
    return code;
657
0
}
658
/* <dict> .buildshading6 <shading_struct> */
659
static int
660
zbuildshading6(i_ctx_t *i_ctx_p)
661
0
{
662
0
    return build_shading(i_ctx_p, build_shading_6);
663
0
}
664
665
/* Build a ShadingType 7 (Tensor product patch mesh) shading. */
666
static int
667
build_shading_7(i_ctx_t *i_ctx_p, const ref * op, const gs_shading_params_t * pcommon,
668
                gs_shading_t ** ppsh, gs_memory_t *mem)
669
0
{
670
0
    gs_shading_Tpp_params_t params;
671
0
    int code;
672
673
0
    *(gs_shading_params_t *)&params = *pcommon;
674
0
    if ((code =
675
0
         build_mesh_shading(i_ctx_p, op, (gs_shading_mesh_params_t *)&params,
676
0
                            &params.Decode, &params.Function, mem)) < 0 ||
677
0
        (code = check_indexed_vs_function(i_ctx_p, op, params.ColorSpace, params.Function)) < 0 ||
678
0
        (code = flag_bits_param(op, (gs_shading_mesh_params_t *)&params,
679
0
                                &params.BitsPerFlag)) < 0 ||
680
0
        (code = gs_shading_Tpp_init(ppsh, &params, mem)) < 0
681
0
        ) {
682
0
        gs_free_object(mem, params.Function, "Function");
683
0
        gs_free_object(mem, params.Decode, "Decode");
684
0
    }
685
0
    return code;
686
0
}
687
/* <dict> .buildshading7 <shading_struct> */
688
static int
689
zbuildshading7(i_ctx_t *i_ctx_p)
690
0
{
691
0
    return build_shading(i_ctx_p, build_shading_7);
692
0
}
693
694
/* ------ Initialization procedure ------ */
695
696
const op_def zshade_op_defs[] =
697
{
698
    op_def_begin_ll3(),
699
    {"0currentsmoothness", zcurrentsmoothness},
700
    {"1setsmoothness", zsetsmoothness},
701
    {"1.shfill", zshfill},
702
    {"1.buildshading1", zbuildshading1},
703
    {"1.buildshading2", zbuildshading2},
704
    {"1.buildshading3", zbuildshading3},
705
    {"1.buildshading4", zbuildshading4},
706
    {"1.buildshading5", zbuildshading5},
707
    {"1.buildshading6", zbuildshading6},
708
    {"1.buildshading7", zbuildshading7},
709
    {"3.buildshadingpattern", zbuildshadingpattern},
710
    op_def_end(0)
711
};