/* Finish building a FunctionType 0 (Sampled) function. */ 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) { gs_function_Sd_params_t params; ref *pDataSource; int code; *(gs_function_params_t *) & params = *mnDR; params.Encode = 0; params.Decode = 0; params.Size = 0; if ((code = dict_find_string(op, "DataSource", &pDataSource)) <= 0) return (code < 0 ? code : gs_note_error(e_rangecheck)); switch (r_type(pDataSource)) { case t_string: data_source_init_string2(¶ms.DataSource, pDataSource->value.const_bytes, r_size(pDataSource)); break; case t_file: { stream *s; check_read_known_file_else(s, pDataSource, return_error, return_error(e_invalidfileaccess)); if (!(s->modes & s_mode_seek)) return_error(e_ioerror); data_source_init_stream(¶ms.DataSource, s); break; } default: return_error(e_rangecheck); } if ((code = dict_int_param(op, "Order", 1, 3, 1, ¶ms.Order)) < 0 || (code = dict_int_param(op, "BitsPerSample", 1, 32, 0, ¶ms.BitsPerSample)) < 0 || ((code = fn_build_float_array(op, "Encode", false, true, ¶ms.Encode, mem)) != 2 * params.m && (code != 0 || params.Encode != 0)) || ((code = fn_build_float_array(op, "Decode", false, true, ¶ms.Decode, mem)) != 2 * params.n && (code != 0 || params.Decode != 0)) ) { goto fail; } { int *ptr = (int *) gs_alloc_byte_array(mem, params.m, sizeof(int), "Size"); if (ptr == 0) { code = gs_note_error(e_VMerror); goto fail; } params.Size = ptr; code = dict_ints_param(op, "Size", params.m, ptr); if (code != params.m) goto fail; } code = gs_function_Sd_init(ppfn, ¶ms, mem); if (code >= 0) return 0; fail: gs_function_Sd_free_params(¶ms, mem); return (code < 0 ? code : gs_note_error(e_rangecheck)); }
/* * Fill in the data for a function type 0 parameter object to be used while * we collect the data for the data cube. At the end of the process, we * will create a function type 0 object to be used to calculate values * as a replacement for the original function. */ static int cube_build_func0(const ref * pdict, gs_function_Sd_params_t * params, gs_memory_t *mem) { byte * bytes = 0; int code, i; int total_size; if ((code = dict_int_param(pdict, "Order", 1, 3, 1, ¶ms->Order)) < 0 || (code = dict_int_param(pdict, "BitsPerSample", 1, 32, 0, ¶ms->BitsPerSample)) < 0 || ((code = params->m = fn_build_float_array(pdict, "Domain", false, true, ¶ms->Domain, mem)) < 0 ) || ((code = params->n = fn_build_float_array(pdict, "Range", false, true, ¶ms->Range, mem)) < 0) ) { goto fail; } /* * The previous logic set the size of m and n to the size of the Domain * and Range arrays. This is twice the actual size. Correct this and * check for valid values. */ params->m >>= 1; params->n >>= 1; if (params->m == 0 || params->n == 0 || params->m > MAX_NUM_INPUTS || params->n > MAX_NUM_OUTPUTS) { code = gs_note_error(e_rangecheck); goto fail; } /* * The Size array may or not be specified. If it is not specified then * we need to determine a set of default values for the Size array. */ { int *ptr = (int *) gs_alloc_byte_array(mem, params->m, sizeof(int), "Size"); if (ptr == NULL) { code = gs_note_error(e_VMerror); goto fail; } params->Size = ptr; code = dict_ints_param(mem, pdict, "Size", params->m, ptr); if (code < 0) goto fail; if (code == 0) { /* * The Size array has not been specified. Determine a default * set of values. */ code = determine_sampled_data_size(params->m, params->n, params->BitsPerSample, (int *)params->Size); if (code < 0) goto fail; } else { /* Size array specified - verify valid */ if (code != params->m || !valid_cube_size(params->m, params->n, params->BitsPerSample, params->Size)) code = gs_note_error(e_rangecheck); goto fail; } } /* * Determine space required for the sample data storage. */ total_size = params->n * bits2bytes(params->BitsPerSample); for (i = 0; i < params->m; i++) total_size *= params->Size[i]; /* * Allocate space for the data cube itself. */ bytes = gs_alloc_byte_array(mem, total_size, 1, "cube_build_func0(bytes)"); if (!bytes) { code = gs_note_error(e_VMerror); goto fail; } data_source_init_bytes(¶ms->DataSource, (const unsigned char *)bytes, total_size); return 0; fail: gs_function_Sd_free_params(params, mem); return (code < 0 ? code : gs_note_error(e_rangecheck)); }