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