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