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: gsfunc.h,v 1.4.6.1.2.1 2003/01/17 00:49:02 giles Exp $ */
20 /* Generic definitions for Functions */
21 
22 #ifndef gsfunc_INCLUDED
23 #  define gsfunc_INCLUDED
24 
25 /* ---------------- Types and structures ---------------- */
26 
27 /*
28  * gs_function_type_t is defined as equivalent to int, rather than as an
29  * enum type, because we can't enumerate all its possible values here in the
30  * generic definitions.
31  */
32 typedef int gs_function_type_t;
33 
34 /*
35  * Define information common to all Function types.
36  * We separate the private part from the parameters so that
37  * clients can create statically initialized parameter structures.
38  */
39 #define gs_function_params_common\
40     int m;			/* # of inputs */\
41     const float *Domain;	/* 2 x m */\
42     int n;			/* # of outputs */\
43     const float *Range		/* 2 x n, optional except for type 0 */
44 
45 /* Define calculation effort values (currently only used for monotonicity). */
46 typedef enum {
47     EFFORT_EASY = 0,
48     EFFORT_MODERATE = 1,
49     EFFORT_ESSENTIAL = 2
50 } gs_function_effort_t;
51 
52 /* Define abstract types. */
53 #ifndef gs_data_source_DEFINED
54 #  define gs_data_source_DEFINED
55 typedef struct gs_data_source_s gs_data_source_t;
56 #endif
57 #ifndef gs_param_list_DEFINED
58 #  define gs_param_list_DEFINED
59 typedef struct gs_param_list_s gs_param_list;
60 #endif
61 
62 /* Define a generic function, for use as the target type of pointers. */
63 typedef struct gs_function_params_s {
64     gs_function_params_common;
65 } gs_function_params_t;
66 #ifndef gs_function_DEFINED
67 typedef struct gs_function_s gs_function_t;
68 #  define gs_function_DEFINED
69 #endif
70 typedef struct gs_function_info_s {
71     const gs_data_source_t *DataSource;
72     ulong data_size;
73     const gs_function_t *const *Functions;
74     int num_Functions;
75 } gs_function_info_t;
76 
77 /* Evaluate a function. */
78 #define FN_EVALUATE_PROC(proc)\
79   int proc(P3(const gs_function_t * pfn, const float *in, float *out))
80 typedef FN_EVALUATE_PROC((*fn_evaluate_proc_t));
81 
82 /* Test whether a function is monotonic. */
83 #define FN_IS_MONOTONIC_PROC(proc)\
84   int proc(P4(const gs_function_t * pfn, const float *lower,\
85 	      const float *upper, gs_function_effort_t effort))
86 typedef FN_IS_MONOTONIC_PROC((*fn_is_monotonic_proc_t));
87 
88 /* Get function information. */
89 #define FN_GET_INFO_PROC(proc)\
90   void proc(P2(const gs_function_t *pfn, gs_function_info_t *pfi))
91 typedef FN_GET_INFO_PROC((*fn_get_info_proc_t));
92 
93 /* Put function parameters on a parameter list. */
94 #define FN_GET_PARAMS_PROC(proc)\
95   int proc(P2(const gs_function_t *pfn, gs_param_list *plist))
96 typedef FN_GET_PARAMS_PROC((*fn_get_params_proc_t));
97 
98 /* Free function parameters. */
99 #define FN_FREE_PARAMS_PROC(proc)\
100   void proc(P2(gs_function_params_t * params, gs_memory_t * mem))
101 typedef FN_FREE_PARAMS_PROC((*fn_free_params_proc_t));
102 
103 /* Free a function. */
104 #define FN_FREE_PROC(proc)\
105   void proc(P3(gs_function_t * pfn, bool free_params, gs_memory_t * mem))
106 typedef FN_FREE_PROC((*fn_free_proc_t));
107 
108 /* Define the generic function structures. */
109 typedef struct gs_function_procs_s {
110     fn_evaluate_proc_t evaluate;
111     fn_is_monotonic_proc_t is_monotonic;
112     fn_get_info_proc_t get_info;
113     fn_get_params_proc_t get_params;
114     fn_free_params_proc_t free_params;
115     fn_free_proc_t free;
116 } gs_function_procs_t;
117 typedef struct gs_function_head_s {
118     gs_function_type_t type;
119     gs_function_procs_t procs;
120     int is_monotonic;		/* cached when function is created */
121 } gs_function_head_t;
122 struct gs_function_s {
123     gs_function_head_t head;
124     gs_function_params_t params;
125 };
126 
127 #define FunctionType(pfn) ((pfn)->head.type)
128 
129 /*
130  * Each specific function type has a definition in its own header file
131  * for its parameter record.  In order to keep names from overflowing
132  * various compilers' limits, we take the name of the function type and
133  * reduce it to the first and last letter of each word, e.g., for
134  * Sampled functions, XxYy is Sd.
135 
136 typedef struct gs_function_XxYy_params_s {
137      gs_function_params_common;
138     << P additional members >>
139 } gs_function_XxYy_params_t;
140 #define private_st_function_XxYy()\
141   gs_private_st_suffix_addP(st_function_XxYy, gs_function_XxYy_t,\
142     "gs_function_XxYy_t", function_XxYy_enum_ptrs, function_XxYy_reloc_ptrs,\
143     st_function, <<params.additional_members>>)
144 
145  */
146 
147 /* ---------------- Procedures ---------------- */
148 
149 /*
150  * Each specific function type has a pair of procedures in its own
151  * header file, one to allocate and initialize an instance of that type,
152  * and one to free the parameters of that type.
153 
154 int gs_function_XxYy_init(P3(gs_function_t **ppfn,
155 			     const gs_function_XxYy_params_t *params,
156 			     gs_memory_t *mem));
157 
158 void gs_function_XxYy_free_params(P2(gs_function_XxYy_params_t *params,
159 				     gs_memory_t *mem));
160 
161  */
162 
163 /* Evaluate a function. */
164 #define gs_function_evaluate(pfn, in, out)\
165   ((pfn)->head.procs.evaluate)(pfn, in, out)
166 
167 /*
168  * Test whether a function is monotonic on a given (closed) interval.  If
169  * the test requires too much effort, the procedure may return
170  * gs_error_undefined; normally, it returns 0 for false, >0 for true,
171  * gs_error_rangecheck if any part of the interval is outside the function's
172  * domain.  If lower[i] > upper[i], the result is not defined.
173  */
174 #define gs_function_is_monotonic(pfn, lower, upper, effort)\
175   ((pfn)->head.procs.is_monotonic)(pfn, lower, upper, effort)
176 /*
177  * If the function is monotonic, is_monotonic returns the direction of
178  * monotonicity for output value N in bits 2N and 2N+1.  (Functions with
179  * more than sizeof(int) * 4 - 1 outputs are never identified as monotonic.)
180  */
181 #define FN_MONOTONIC_INCREASING 1
182 #define FN_MONOTONIC_DECREASING 2
183 
184 /* Get function information. */
185 #define gs_function_get_info(pfn, pfi)\
186   ((pfn)->head.procs.get_info(pfn, pfi))
187 
188 /* Write function parameters. */
189 #define gs_function_get_params(pfn, plist)\
190   ((pfn)->head.procs.get_params(pfn, plist))
191 
192 /* Free function parameters. */
193 #define gs_function_free_params(pfn, mem)\
194   ((pfn)->head.procs.free_params(&(pfn)->params, mem))
195 
196 /* Free a function's implementation, optionally including its parameters. */
197 #define gs_function_free(pfn, free_params, mem)\
198   ((pfn)->head.procs.free(pfn, free_params, mem))
199 
200 #endif /* gsfunc_INCLUDED */
201