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