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 *)¶ms = *mnDR;
47 params.C0 = 0;
48 params.C1 = 0;
49 if ((code = dict_float_param(op, "N", 0.0, ¶ms.N)) != 0 ||
50 (code = n0 = fn_build_float_array(op, "C0", false, false, ¶ms.C0, mem)) < 0 ||
51 (code = n1 = fn_build_float_array(op, "C1", false, false, ¶ms.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, ¶ms, mem);
63 if (code >= 0)
64 return 0;
65 fail:
66 gs_function_ElIn_free_params(¶ms, 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, ¶ms.Bounds, mem)) != params.k - 1 ||
105 (code = fn_build_float_array(op, "Encode", true, true, ¶ms.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, ¶ms, mem);
111 if (code >= 0)
112 return 0;
113 fail:
114 gs_function_1ItSg_free_params(¶ms, mem);
115 return (code < 0 ? code : gs_note_error(e_rangecheck));
116 }
117