1 /* Copyright (C) 2001-2006 Artifex Software, Inc.
2    All Rights Reserved.
3 
4    This software is provided AS-IS with no warranty, either express or
5    implied.
6 
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.
12 */
13 
14 /* $Id: zfunc0.c 9043 2008-08-28 22:48:19Z giles $ */
15 /* PostScript language interface to FunctionType 0 (Sampled) Functions */
16 #include "memory_.h"
17 #include "ghost.h"
18 #include "oper.h"
19 #include "gsdsrc.h"
20 #include "gsfunc.h"
21 #include "gsfunc0.h"
22 #include "stream.h"		/* for files.h */
23 #include "files.h"
24 #include "ialloc.h"
25 #include "idict.h"
26 #include "idparam.h"
27 #include "ifunc.h"
28 
29 /* Check prototype */
30 build_function_proc(gs_build_function_0);
31 
32 /* Finish building a FunctionType 0 (Sampled) function. */
33 int
gs_build_function_0(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)34 gs_build_function_0(i_ctx_t *i_ctx_p, const ref *op, const gs_function_params_t * mnDR,
35 		    int depth, gs_function_t ** ppfn, gs_memory_t *mem)
36 {
37     gs_function_Sd_params_t params;
38     ref *pDataSource;
39     int code;
40 
41     *(gs_function_params_t *) & params = *mnDR;
42     params.Encode = params.Decode = NULL;
43     params.pole = NULL;
44     params.Size = params.array_step = params.stream_step = NULL;
45     if ((code = dict_find_string(op, "DataSource", &pDataSource)) <= 0)
46 	return (code < 0 ? code : gs_note_error(e_rangecheck));
47     switch (r_type(pDataSource)) {
48 	case t_string:
49 	    data_source_init_string2(&params.DataSource,
50 				     pDataSource->value.const_bytes,
51 				     r_size(pDataSource));
52 	    break;
53 	case t_file: {
54 	    stream *s;
55 
56 	    check_read_known_file_else(s, pDataSource, return_error,
57 				       return_error(e_invalidfileaccess));
58 	    if (!(s->modes & s_mode_seek))
59 		return_error(e_ioerror);
60 	    data_source_init_stream(&params.DataSource, s);
61 	    break;
62 	}
63 	default:
64 	    return_error(e_rangecheck);
65     }
66     if ((code = dict_int_param(op, "Order", 1, 3, 1, &params.Order)) < 0 ||
67 	(code = dict_int_param(op, "BitsPerSample", 1, 32, 0,
68 			       &params.BitsPerSample)) < 0 ||
69 	((code = fn_build_float_array(op, "Encode", false, true, &params.Encode, mem)) != 2 * params.m && (code != 0 || params.Encode != 0)) ||
70 	((code = fn_build_float_array(op, "Decode", false, true, &params.Decode, mem)) != 2 * params.n && (code != 0 || params.Decode != 0))
71 	) {
72 	goto fail;
73     } {
74 	int *ptr = (int *)
75 	    gs_alloc_byte_array(mem, params.m, sizeof(int), "Size");
76 
77 	if (ptr == 0) {
78 	    code = gs_note_error(e_VMerror);
79 	    goto fail;
80 	}
81 	params.Size = ptr;
82 	code = dict_ints_param(mem, op, "Size", params.m, ptr);
83 	if (code != params.m)
84 	    goto fail;
85     }
86     code = gs_function_Sd_init(ppfn, &params, mem);
87     if (code >= 0)
88 	return 0;
89 fail:
90     gs_function_Sd_free_params(&params, mem);
91     return (code < 0 ? code : gs_note_error(e_rangecheck));
92 }
93