xref: /plan9/sys/src/cmd/gs/src/zfunc3.c (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
1 /* Copyright (C) 1997, 1998, 1999 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: zfunc3.c,v 1.7 2004/08/04 19:36:13 stefan Exp $ */
18 /* PostScript language interface to LL3 Functions */
19 #include "memory_.h"
20 #include "ghost.h"
21 #include "oper.h"
22 #include "gsfunc3.h"
23 #include "gsstruct.h"
24 #include "stream.h"		/* for files.h */
25 #include "files.h"
26 #include "ialloc.h"
27 #include "idict.h"
28 #include "idparam.h"
29 #include "ifunc.h"
30 #include "store.h"
31 
32 /* Check prototypes */
33 build_function_proc(gs_build_function_2);
34 build_function_proc(gs_build_function_3);
35 
36 /* Finish building a FunctionType 2 (ExponentialInterpolation) function. */
37 int
gs_build_function_2(i_ctx_t * i_ctx_p,const ref * op,const gs_function_params_t * mnDR,int depth,gs_function_t ** ppfn,gs_memory_t * mem)38 gs_build_function_2(i_ctx_t *i_ctx_p, const ref *op, const gs_function_params_t * mnDR,
39 		    int depth, gs_function_t ** ppfn, gs_memory_t *mem)
40 {
41     gs_function_ElIn_params_t params;
42     int code, n0, n1;
43 
44     *(gs_function_params_t *)&params = *mnDR;
45     params.C0 = 0;
46     params.C1 = 0;
47     if ((code = dict_float_param(op, "N", 0.0, &params.N)) != 0 ||
48 	(code = n0 = fn_build_float_array_forced(op, "C0", false, &params.C0, mem)) < 0 ||
49 	(code = n1 = fn_build_float_array_forced(op, "C1", false, &params.C1, mem)) < 0
50 	)
51 	goto fail;
52     if (params.C0 == 0)
53 	n0 = 1;			/* C0 defaulted */
54     if (params.C1 == 0)
55 	n1 = 1;			/* C1 defaulted */
56     if (params.Range == 0)
57 	params.n = n0;		/* either one will do */
58     if (n0 != n1 || n0 != params.n)
59 	goto fail;
60     code = gs_function_ElIn_init(ppfn, &params, mem);
61     if (code >= 0)
62 	return 0;
63 fail:
64     gs_function_ElIn_free_params(&params, mem);
65     return (code < 0 ? code : gs_note_error(e_rangecheck));
66 }
67 
68 /* Finish building a FunctionType 3 (1-Input Stitching) function. */
69 int
gs_build_function_3(i_ctx_t * i_ctx_p,const ref * op,const gs_function_params_t * mnDR,int depth,gs_function_t ** ppfn,gs_memory_t * mem)70 gs_build_function_3(i_ctx_t *i_ctx_p, const ref *op, const gs_function_params_t * mnDR,
71 		    int depth, gs_function_t ** ppfn, gs_memory_t *mem)
72 {
73     gs_function_1ItSg_params_t params;
74     int code;
75 
76     *(gs_function_params_t *) & params = *mnDR;
77     params.Functions = 0;
78     params.Bounds = 0;
79     params.Encode = 0;
80     {
81 	ref *pFunctions;
82 	gs_function_t **ptr;
83 	int i;
84 
85 	if ((code = dict_find_string(op, "Functions", &pFunctions)) <= 0)
86 	    return (code < 0 ? code : gs_note_error(e_rangecheck));
87 	check_array_only(*pFunctions);
88 	params.k = r_size(pFunctions);
89 	code = alloc_function_array(params.k, &ptr, mem);
90 	if (code < 0)
91 	    return code;
92 	params.Functions = (const gs_function_t * const *)ptr;
93 	for (i = 0; i < params.k; ++i) {
94 	    ref subfn;
95 
96 	    array_get(mem, pFunctions, (long)i, &subfn);
97 	    code = fn_build_sub_function(i_ctx_p, &subfn, &ptr[i], depth, mem);
98 	    if (code < 0)
99 		goto fail;
100 	}
101     }
102     if ((code = fn_build_float_array(op, "Bounds", true, false, &params.Bounds, mem)) != params.k - 1 ||
103 	(code = fn_build_float_array(op, "Encode", true, true, &params.Encode, mem)) != 2 * params.k
104 	)
105 	goto fail;
106     if (params.Range == 0)
107 	params.n = params.Functions[0]->params.n;
108     code = gs_function_1ItSg_init(ppfn, &params, mem);
109     if (code >= 0)
110 	return 0;
111 fail:
112     gs_function_1ItSg_free_params(&params, mem);
113     return (code < 0 ? code : gs_note_error(e_rangecheck));
114 }
115