Coverage Report

Created: 2022-10-31 07:00

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