summaryrefslogtreecommitdiff
blob: 0875b923fcb921dd17b6e8933633b34601aee4ea (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
/* Copyright (C) 2001-2019 Artifex Software, Inc.
   All Rights Reserved.

   This software is provided AS-IS with no warranty, either express or
   implied.

   This software is distributed under license and may not be copied,
   modified or distributed except as expressly authorized under the terms
   of the license contained in the file LICENSE in this distribution.

   Refer to licensing information at http://www.artifex.com or contact
   Artifex Software, Inc.,  1305 Grant Avenue - Suite 200, Novato,
   CA 94945, U.S.A., +1(415)492-9861, for further information.
*/


/* Generic definitions for Functions */

#ifndef gsfunc_INCLUDED
#  define gsfunc_INCLUDED

#include "std.h"
#include "memento.h" /* Because we use 'free' below */
#include "gstypes.h"		/* for gs_range_t */
#include "scommon.h"
#include "gsparam.h"
#include "gsdsrc.h"

/* ---------------- Types and structures ---------------- */

/*
 * gs_function_type_t is defined as equivalent to int, rather than as an
 * enum type, because we can't enumerate all its possible values here in the
 * generic definitions.
 */
typedef int gs_function_type_t;

/*
 * Define information common to all Function types.
 * We separate the private part from the parameters so that
 * clients can create statically initialized parameter structures.
 */
#define gs_function_params_common\
    int m;			/* # of inputs */\
    const float *Domain;	/* 2 x m */\
    int n;			/* # of outputs */\
    const float *Range		/* 2 x n, optional except for type 0 */

/* Define a generic function, for use as the target type of pointers. */
typedef struct gs_function_params_s {
    gs_function_params_common;
} gs_function_params_t;
typedef struct gs_function_s gs_function_t;
typedef struct gs_function_info_s {
    const gs_data_source_t *DataSource;
    ulong data_size;
    const gs_function_t *const *Functions;
    int num_Functions;
} gs_function_info_t;

/* Evaluate a function. */
#define FN_EVALUATE_PROC(proc)\
  int proc(const gs_function_t * pfn, const float *in, float *out)
typedef FN_EVALUATE_PROC((*fn_evaluate_proc_t));

/* Test whether a function is monotonic. */
#define FN_IS_MONOTONIC_PROC(proc)\
  int proc(const gs_function_t * pfn, const float *lower,\
           const float *upper, uint *mask)
typedef FN_IS_MONOTONIC_PROC((*fn_is_monotonic_proc_t));

/* Get function information. */
#define FN_GET_INFO_PROC(proc)\
  void proc(const gs_function_t *pfn, gs_function_info_t *pfi)
typedef FN_GET_INFO_PROC((*fn_get_info_proc_t));

/* Put function parameters on a parameter list. */
#define FN_GET_PARAMS_PROC(proc)\
  int proc(const gs_function_t *pfn, gs_param_list *plist)
typedef FN_GET_PARAMS_PROC((*fn_get_params_proc_t));

/*
 * Create a new function with scaled output.  The i'th output value is
 * transformed linearly so that [0 .. 1] are mapped to [pranges[i].rmin ..
 * pranges[i].rmax].  Any necessary parameters or subfunctions of the
 * original function are copied, not shared, even if their values aren't
 * changed, so that the new function can be freed without having to worry
 * about freeing data that should be kept.  Note that if there is a "data
 * source", it is shared, not copied: this should not be a problem, since
 * gs_function_free does not free the data source.
 */
#define FN_MAKE_SCALED_PROC(proc)\
  int proc(const gs_function_t *pfn, gs_function_t **ppsfn,\
           const gs_range_t *pranges, gs_memory_t *mem)
typedef FN_MAKE_SCALED_PROC((*fn_make_scaled_proc_t));

/* Free function parameters. */
#define FN_FREE_PARAMS_PROC(proc)\
  void proc(gs_function_params_t * params, gs_memory_t * mem)
typedef FN_FREE_PARAMS_PROC((*fn_free_params_proc_t));

/* Free a function. */
#define FN_FREE_PROC(proc)\
  void proc(gs_function_t * pfn, bool free_params, gs_memory_t * mem)
typedef FN_FREE_PROC((*fn_free_proc_t));

/* Serialize a function. */
#define FN_SERIALIZE_PROC(proc)\
  int proc(const gs_function_t * pfn, stream *s)
typedef FN_SERIALIZE_PROC((*fn_serialize_proc_t));

/* Define the generic function structures. */
typedef struct gs_function_procs_s {
    fn_evaluate_proc_t evaluate;
    fn_is_monotonic_proc_t is_monotonic;
    fn_get_info_proc_t get_info;
    fn_get_params_proc_t get_params;
    fn_make_scaled_proc_t make_scaled;
    fn_free_params_proc_t free_params;
    fn_free_proc_t free;
    fn_serialize_proc_t serialize;
} gs_function_procs_t;
typedef struct gs_function_head_s {
    gs_function_type_t type;
    gs_function_procs_t procs;
} gs_function_head_t;
struct gs_function_s {
    gs_function_head_t head;
    gs_function_params_t params;
};

#define FunctionType(pfn) ((pfn)->head.type)

/*
 * Each specific function type has a definition in its own header file
 * for its parameter record.  In order to keep names from overflowing
 * various compilers' limits, we take the name of the function type and
 * reduce it to the first and last letter of each word, e.g., for
 * Sampled functions, XxYy is Sd.

typedef struct gs_function_XxYy_params_s {
     gs_function_params_common;
    << P additional members >>
} gs_function_XxYy_params_t;
#define private_st_function_XxYy()\
  gs_private_st_suffix_addP(st_function_XxYy, gs_function_XxYy_t,\
    "gs_function_XxYy_t", function_XxYy_enum_ptrs, function_XxYy_reloc_ptrs,\
    st_function, <<params.additional_members>>)

 */

/* ---------------- Procedures ---------------- */

/*
 * Each specific function type has a pair of procedures in its own
 * header file, one to allocate and initialize an instance of that type,
 * and one to free the parameters of that type.

int gs_function_XxYy_init(gs_function_t **ppfn,
                          const gs_function_XxYy_params_t *params,
                          gs_memory_t *mem));

void gs_function_XxYy_free_params(gs_function_XxYy_params_t *params,
                                  gs_memory_t *mem);

 */

/* Allocate an array of function pointers. */
int alloc_function_array(uint count, gs_function_t *** pFunctions,
                         gs_memory_t *mem);

/* Evaluate a function. */
#define gs_function_evaluate(pfn, in, out)\
  ((pfn)->head.procs.evaluate)(pfn, in, out)

/*
 * Test whether a function is monotonic on a given (closed) interval.
 * return 1 = monotonic, 0 = not or don't know, <0 = error..
 * Sets mask : 1 bit per dimension :
 *    1 - non-monotonic or don't know,
 *    0 - monotonic.
 * If lower[i] > upper[i], the result may be not defined.
 */
#define gs_function_is_monotonic(pfn, lower, upper, mask)\
  ((pfn)->head.procs.is_monotonic)(pfn, lower, upper, mask)

/* Get function information. */
#define gs_function_get_info(pfn, pfi)\
  ((pfn)->head.procs.get_info(pfn, pfi))

/* Write function parameters. */
#define gs_function_get_params(pfn, plist)\
  ((pfn)->head.procs.get_params(pfn, plist))

/* Create a scaled function. */
#define gs_function_make_scaled(pfn, ppsfn, pranges, mem)\
  ((pfn)->head.procs.make_scaled(pfn, ppsfn, pranges, mem))

/* Free function parameters. */
#define gs_function_free_params(pfn, mem)\
  ((pfn)->head.procs.free_params(&(pfn)->params, mem))

/* Free a function's implementation, optionally including its parameters. */
#define gs_function_free(pfn, free_params, mem)\
  ((pfn)->head.procs.free(pfn, free_params, mem))

/* Serialize a function. */
#define gs_function_serialize(pfn, s)\
  ((pfn)->head.procs.serialize(pfn, s))

#endif /* gsfunc_INCLUDED */