1
/* Copyright (C) 2001-2006 Artifex Software, Inc.
4
This software is provided AS-IS with no warranty, either express or
7
This software is distributed under license and may not be copied, modified
8
or distributed except as expressly authorized under the terms of that
9
license. Refer to licensing information at http://www.artifex.com/
10
or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
11
San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
14
/* $Id: gsfunc.c 8022 2007-06-05 22:23:38Z giles $ */
15
/* Generic Function support */
25
gs_private_st_ptr(st_function_ptr, gs_function_t *, "gs_function_t *",
26
function_ptr_enum_ptrs, function_ptr_reloc_ptrs);
27
gs_private_st_element(st_function_ptr_element, gs_function_t *,
28
"gs_function_t *[]", function_ptr_element_enum_ptrs,
29
function_ptr_element_reloc_ptrs, st_function_ptr);
31
/* Allocate an array of function pointers. */
33
alloc_function_array(uint count, gs_function_t *** pFunctions,
39
return_error(gs_error_rangecheck);
40
ptr = gs_alloc_struct_array(mem, count, gs_function_t *,
41
&st_function_ptr_element, "Functions");
43
return_error(gs_error_VMerror);
44
memset(ptr, 0, sizeof(*ptr) * count);
49
/* Generic free_params implementation. */
51
fn_common_free_params(gs_function_params_t * params, gs_memory_t * mem)
53
gs_free_const_object(mem, params->Range, "Range");
54
gs_free_const_object(mem, params->Domain, "Domain");
57
/* Generic free implementation. */
59
fn_common_free(gs_function_t * pfn, bool free_params, gs_memory_t * mem)
62
gs_function_free_params(pfn, mem);
63
gs_free_object(mem, pfn, "fn_common_free");
66
/* Check the values of m, n, Domain, and (if supplied) Range. */
68
fn_check_mnDR(const gs_function_params_t * params, int m, int n)
73
return_error(gs_error_rangecheck);
74
for (i = 0; i < m; ++i)
75
if (params->Domain[2 * i] > params->Domain[2 * i + 1])
76
return_error(gs_error_rangecheck);
77
if (params->Range != 0)
78
for (i = 0; i < n; ++i)
79
if (params->Range[2 * i] > params->Range[2 * i + 1])
80
return_error(gs_error_rangecheck);
84
/* Return default function information. */
86
gs_function_get_info_default(const gs_function_t *pfn, gs_function_info_t *pfi)
93
* Write generic parameters (FunctionType, Domain, Range) on a parameter list.
96
fn_common_get_params(const gs_function_t *pfn, gs_param_list *plist)
98
int ecode = param_write_int(plist, "FunctionType", &FunctionType(pfn));
101
if (pfn->params.Domain) {
102
code = param_write_float_values(plist, "Domain", pfn->params.Domain,
103
2 * pfn->params.m, false);
107
if (pfn->params.Range) {
108
code = param_write_float_values(plist, "Range", pfn->params.Range,
109
2 * pfn->params.n, false);
117
* Copy an array of numeric values when scaling a function.
120
fn_copy_values(const void *pvalues, int count, int size, gs_memory_t *mem)
123
void *values = gs_alloc_byte_array(mem, count, size, "fn_copy_values");
126
memcpy(values, pvalues, count * size);
129
return 0; /* caller must check */
133
* If necessary, scale the Range or Decode array for fn_make_scaled.
134
* Note that we must always allocate a new array.
137
fn_scale_pairs(const float **ppvalues, const float *pvalues, int npairs,
138
const gs_range_t *pranges, gs_memory_t *mem)
143
float *out = (float *)
144
gs_alloc_byte_array(mem, 2 * npairs, sizeof(*pvalues),
149
return_error(gs_error_VMerror);
151
/* Allocate and compute scaled ranges. */
153
for (i = 0; i < npairs; ++i) {
154
double base = pranges[i].rmin, factor = pranges[i].rmax - base;
156
out[2 * i] = pvalues[2 * i] * factor + base;
157
out[2 * i + 1] = pvalues[2 * i + 1] * factor + base;
160
memcpy(out, pvalues, 2 * sizeof(*pvalues) * npairs);
166
* Scale the generic part of a function (Domain and Range).
167
* The client must have copied the parameters already.
170
fn_common_scale(gs_function_t *psfn, const gs_function_t *pfn,
171
const gs_range_t *pranges, gs_memory_t *mem)
175
psfn->head = pfn->head;
176
psfn->params.Domain = 0; /* in case of failure */
177
psfn->params.Range = 0;
178
if ((code = fn_scale_pairs(&psfn->params.Domain, pfn->params.Domain,
179
pfn->params.m, NULL, mem)) < 0 ||
180
(code = fn_scale_pairs(&psfn->params.Range, pfn->params.Range,
181
pfn->params.n, pranges, mem)) < 0)
188
fn_common_serialize(const gs_function_t * pfn, stream *s)
191
const gs_function_params_t * p = &pfn->params;
192
int code = sputs(s, (const byte *)&pfn->head.type, sizeof(pfn->head.type), &n);
193
const float dummy[8] = {0, 0, 0, 0, 0, 0, 0, 0};
197
code = sputs(s, (const byte *)&p->m, sizeof(p->m), &n);
200
code = sputs(s, (const byte *)&p->Domain[0], sizeof(p->Domain[0]) * p->m * 2, &n);
203
code = sputs(s, (const byte *)&p->n, sizeof(p->n), &n);
206
if (p->Range == NULL && p->n * 2 > count_of(dummy))
207
return_error(gs_error_unregistered); /* Unimplemented. */
208
return sputs(s, (const byte *)(p->Range != NULL ? &p->Range[0] : dummy),
209
sizeof(p->Range[0]) * p->n * 2, &n);