Пример #1
0
/* Make a scaled copy of an Arrayed Output function. */
static int
fn_AdOt_make_scaled(const gs_function_AdOt_t *pfn, gs_function_AdOt_t **ppsfn,
		    const gs_range_t *pranges, gs_memory_t *mem)
{
    gs_function_AdOt_t *psfn =
	gs_alloc_struct(mem, gs_function_AdOt_t, &st_function_AdOt,
			"fn_AdOt_make_scaled");
    int code;

    if (psfn == 0)
	return_error(gs_error_VMerror);
    psfn->params = pfn->params;
    psfn->params.Functions = 0;	/* in case of failure */
    if ((code = fn_common_scale((gs_function_t *)psfn,
				(const gs_function_t *)pfn,
				pranges, mem)) < 0 ||
	(code = fn_scale_functions((gs_function_t ***)&psfn->params.Functions,
				   pfn->params.Functions,
				   pfn->params.n, pranges, true, mem)) < 0) {
	gs_function_free((gs_function_t *)psfn, true, mem);
	return code;
    }
    *ppsfn = psfn;
    return 0;
}
Пример #2
0
/* Make a scaled copy of a 1-Input Stitching function. */
static int
fn_1ItSg_make_scaled(const gs_function_1ItSg_t *pfn,
		     gs_function_1ItSg_t **ppsfn,
		     const gs_range_t *pranges, gs_memory_t *mem)
{
    gs_function_1ItSg_t *psfn =
	gs_alloc_struct(mem, gs_function_1ItSg_t, &st_function_1ItSg,
			"fn_1ItSg_make_scaled");
    int code;

    if (psfn == 0)
	return_error(gs_error_VMerror);
    psfn->params = pfn->params;
    psfn->params.Functions = 0;	/* in case of failure */
    psfn->params.Bounds =
	fn_copy_values(pfn->params.Bounds, pfn->params.k - 1, sizeof(float),
		       mem);
    psfn->params.Encode =
	fn_copy_values(pfn->params.Encode, 2 * pfn->params.k, sizeof(float),
		       mem);
    if ((code = (psfn->params.Bounds == 0 || psfn->params.Encode == 0 ?
		 gs_note_error(gs_error_VMerror) : 0)) < 0 ||
	(code = fn_common_scale((gs_function_t *)psfn,
				(const gs_function_t *)pfn,
				pranges, mem)) < 0 ||
	(code = fn_scale_functions((gs_function_t ***)&psfn->params.Functions,
				   pfn->params.Functions,
				   pfn->params.n, pranges, false, mem)) < 0) {
	gs_function_free((gs_function_t *)psfn, true, mem);
	return code;
    }
    *ppsfn = psfn;
    return 0;
}
Пример #3
0
/*
 * Free an array of subsidiary Functions.  Note that this may be called
 * before the Functions array has been fully initialized.  Note also that
 * its argument conforms to the Functions array in the parameter structure,
 * but it (necessarily) deconstifies it.
 */
static void
fn_free_functions(const gs_function_t *const * Functions, int count,
		  gs_memory_t * mem)
{
    int i;

    for (i = count; --i >= 0;)
	if (Functions[i])
	    gs_function_free((gs_function_t *)Functions[i], true, mem);
    gs_free_const_object(mem, Functions, "Functions");
}
Пример #4
0
/* Collect a Function value. */
static int
build_shading_function(i_ctx_t *i_ctx_p, const ref * op, gs_function_t ** ppfn,
                 int num_inputs, gs_memory_t *mem, const float *shading_domain)
{
    ref *pFunction;
    int code;

    *ppfn = 0;
    if (dict_find_string(op, "Function", &pFunction) <= 0)
        return 0;
    if (r_is_array(pFunction)) {
        uint size = r_size(pFunction);
        gs_function_t **Functions;
        uint i;
        gs_function_AdOt_params_t params;

        check_read(*pFunction);
        if (size == 0)
            return_error(gs_error_rangecheck);
        code = alloc_function_array(size, &Functions, mem);
        if (code < 0)
            return code;
        for (i = 0; i < size; ++i) {
            ref rsubfn;

            array_get(imemory, pFunction, (long)i, &rsubfn);
            code = fn_build_function(i_ctx_p, &rsubfn, &Functions[i], mem,
               shading_domain, num_inputs);
            if (code < 0)
                break;
        }
        params.m = num_inputs;
        params.Domain = 0;
        params.n = size;
        params.Range = 0;
        params.Functions = (const gs_function_t * const *)Functions;
        if (code >= 0)
            code = gs_function_AdOt_init(ppfn, &params, mem);
        if (code < 0)
            gs_function_AdOt_free_params(&params, mem);
    } else {
        code = fn_build_function(i_ctx_p, pFunction, ppfn, mem,
            shading_domain, num_inputs);
        if (code < 0)
            return code;
        if ((*ppfn)->params.m != num_inputs) {
            gs_function_free(*ppfn, true, mem);
            return_error(gs_error_rangecheck);
        }
    }
    return code;
}
Пример #5
0
/* <dict> .buildfunction <function_proc> */
static int
zbuildfunction(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    gs_function_t *pfn;
    int code = fn_build_function(i_ctx_p, op, &pfn, imemory, 0, 0);

    if (code < 0)
        return code;
    code = make_function_proc(i_ctx_p, op, pfn);
    if (code < 0)
        gs_function_free(pfn, true, imemory);
    return 0;
}
Пример #6
0
/* <function_proc> <array> .scalefunction <function_proc> */
static int
zscalefunction(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    gs_function_t *pfn;
    gs_function_t *psfn;
    gs_range_t *ranges;
    int code;
    uint i;

    check_proc(op[-1]);
    pfn = ref_function(op - 1);
    if (pfn == 0 || !r_is_array(op))
        return_error(gs_error_typecheck);
    if (r_size(op) != 2 * pfn->params.n)
        return_error(gs_error_rangecheck);
    ranges = (gs_range_t *)
        gs_alloc_byte_array(imemory, pfn->params.n, sizeof(gs_range_t),
                            "zscalefunction");
    if (ranges == 0)
        return_error(gs_error_VMerror);
    for (i = 0; i < pfn->params.n; ++i) {
        ref rval[2];
        float val[2];

        if ((code = array_get(op, 2 * i, &rval[0])) < 0 ||
            (code = array_get(op, 2 * i + 1, &rval[1])) < 0 ||
            (code = float_params(rval + 1, 2, val)) < 0)
            return code;
        ranges[i].rmin = val[0];
        ranges[i].rmax = val[1];
    }
    code = gs_function_make_scaled(pfn, &psfn, ranges, imemory);
    gs_free_object(imemory, ranges, "zscalefunction");
    if (code < 0 ||
        (code = make_function_proc(i_ctx_p, op - 1, psfn)) < 0) {
        gs_function_free(psfn, true, imemory);
        return code;
    }
    pop(1);
    return 0;
}
Пример #7
0
int buildfunction(i_ctx_t * i_ctx_p, ref *arr, ref *pproc, int type)
{
    os_ptr op = osp;
    gs_function_t *pfn=NULL;
    int code=0;

    switch(type) {
        case 0:
            code = make_sampled_function(i_ctx_p, arr, pproc, &pfn);
            break;
        case 4:
            code = make_type4_function(i_ctx_p, arr, pproc, &pfn);
            if (code == 0) {
                code = make_function_proc(i_ctx_p, op, pfn);
                if (code < 0) {
                    gs_function_free(pfn, true, imemory);
                }
            }
            break;
    }
    return code;
}
Пример #8
0
/* Make a scaled copy of an Exponential Interpolation function. */
static int
fn_ElIn_make_scaled(const gs_function_ElIn_t *pfn,
		     gs_function_ElIn_t **ppsfn,
		     const gs_range_t *pranges, gs_memory_t *mem)
{
    gs_function_ElIn_t *psfn =
	gs_alloc_struct(mem, gs_function_ElIn_t, &st_function_ElIn,
			"fn_ElIn_make_scaled");
    float *c0;
    float *c1;
    int code, i;

    if (psfn == 0)
	return_error(gs_error_VMerror);
    psfn->params = pfn->params;
    psfn->params.C0 = c0 =
	fn_copy_values(pfn->params.C0, pfn->params.n, sizeof(float), mem);
    psfn->params.C1 = c1 =
	fn_copy_values(pfn->params.C1, pfn->params.n, sizeof(float), mem);
    if ((code = ((c0 == 0 && pfn->params.C0 != 0) ||
		 (c1 == 0 && pfn->params.C1 != 0) ?
		 gs_note_error(gs_error_VMerror) : 0)) < 0 ||
	(code = fn_common_scale((gs_function_t *)psfn,
				(const gs_function_t *)pfn,
				pranges, mem)) < 0) {
	gs_function_free((gs_function_t *)psfn, true, mem);
	return code;
    }
    for (i = 0; i < pfn->params.n; ++i) {
	double base = pranges[i].rmin, factor = pranges[i].rmax - base;

	c1[i] = c1[i] * factor + base;
	c0[i] = c0[i] * factor + base;
    }
    *ppsfn = psfn;
    return 0;
}
Пример #9
0
/* Allocate and initialize an Arrayed Output function. */
int
gs_function_AdOt_init(gs_function_t ** ppfn,
		const gs_function_AdOt_params_t * params, gs_memory_t * mem)
{
    static const gs_function_head_t function_AdOt_head = {
	function_type_ArrayedOutput,
	{
	    (fn_evaluate_proc_t) fn_AdOt_evaluate,
	    (fn_is_monotonic_proc_t) fn_AdOt_is_monotonic,
	    (fn_get_info_proc_t) fn_AdOt_get_info,
	    fn_common_get_params,	/****** WHAT TO DO ABOUT THIS? ******/
	    (fn_make_scaled_proc_t) fn_AdOt_make_scaled,
	    (fn_free_params_proc_t) gs_function_AdOt_free_params,
	    fn_common_free,
	    (fn_serialize_proc_t) gs_function_AdOt_serialize,
	}
    };
    int m = params->m, n = params->n;

    *ppfn = 0;			/* in case of error */
    if (m <= 0 || n <= 0)
	return_error(gs_error_rangecheck);
    {
	gs_function_AdOt_t *pfn =
	    gs_alloc_struct(mem, gs_function_AdOt_t, &st_function_AdOt,
			    "gs_function_AdOt_init");
	float *domain = (float *)
	    gs_alloc_byte_array(mem, 2 * m, sizeof(float),
				"gs_function_AdOt_init(Domain)");
	int i, j;

	if (pfn == 0)
	    return_error(gs_error_VMerror);
	pfn->params = *params;
	pfn->params.Domain = domain;
	pfn->params.Range = 0;
	pfn->head = function_AdOt_head;
	if (domain == 0) {
	    gs_function_free((gs_function_t *)pfn, true, mem);
	    return_error(gs_error_VMerror);
	}
	/*
	 * We compute the Domain as the intersection of the Domains of
	 * the individual subfunctions.  This isn't quite right: some
	 * subfunction might actually make use of a larger domain of
	 * input values.  However, the only place that Arrayed Output
	 * functions are used is in Shading and similar dictionaries,
	 * where the input values are clamped to the intersection of
	 * the individual Domains anyway.
	 */
	memcpy(domain, params->Functions[0]->params.Domain,
	       2 * sizeof(float) * m);
	for (i = 1; i < n; ++i) {
	    const float *dom = params->Functions[i]->params.Domain;

	    for (j = 0; j < 2 * m; j += 2, dom += 2) {
		domain[j] = max(domain[j], dom[0]);
		domain[j + 1] = min(domain[j + 1], dom[1]);
	    }
	}
	*ppfn = (gs_function_t *) pfn;
    }
    return 0;
}
Пример #10
0
/* Collect parameters for a mesh shading. */
static int
build_mesh_shading(i_ctx_t *i_ctx_p, const ref * op,
                   gs_shading_mesh_params_t * params,
                   float **pDecode, gs_function_t ** pFunction,
                   gs_memory_t *mem)
{
    int code;
    float *data = 0;
    ref *pDataSource;

    *pDecode = 0;
    *pFunction = 0;
    if (dict_find_string(op, "DataSource", &pDataSource) <= 0)
        return_error(gs_error_rangecheck);
    if (r_is_array(pDataSource)) {
        uint size = r_size(pDataSource);

        data = (float *)gs_alloc_byte_array(mem, size, sizeof(float),
                                            "build_mesh_shading");
        if (data == 0)
            return_error(gs_error_VMerror);
        code = process_float_array(mem, pDataSource, size, data);
        if (code < 0) {
            gs_free_object(mem, data, "build_mesh_shading");
            return code;
        }
        data_source_init_floats(&params->DataSource, data, size);
    } else
        switch (r_type(pDataSource)) {
            case t_file: {
                stream *s;

                check_read_file(i_ctx_p, s, pDataSource);
                data_source_init_stream(&params->DataSource, s);
                break;
            }
            case t_string:
                check_read(*pDataSource);
                data_source_init_string2(&params->DataSource,
                                         pDataSource->value.bytes,
                                         r_size(pDataSource));
                break;
            default:
                return_error(gs_error_typecheck);
        }
    code = build_shading_function(i_ctx_p, op, pFunction, 1, mem, NULL);
    if (code < 0) {
        gs_free_object(mem, data, "build_mesh_shading");
        return code;
    }
    if (data_source_is_array(params->DataSource)) {
        params->BitsPerCoordinate = 0;
        params->BitsPerComponent = 0;
    } else {
        int num_decode = 4 +
            (*pFunction != 0 ? 1 :
             gs_color_space_num_components(params->ColorSpace)) * 2;

        if ((code = dict_int_param(op, "BitsPerCoordinate", 1, 32, 0,
                                   &params->BitsPerCoordinate)) >= 0 &&
            (code = dict_int_param(op, "BitsPerComponent", 1, 16, 0,
                                   &params->BitsPerComponent)) >= 0
            ) {
            *pDecode = (float *)
                gs_alloc_byte_array(mem, num_decode, sizeof(float),
                                    "build_mesh_shading");
            if (*pDecode == 0)
                code = gs_note_error(gs_error_VMerror);
            else {
                code = dict_floats_param(mem, op, "Decode", num_decode, *pDecode, NULL);
                if (code < 0) {
                    gs_free_object(mem, *pDecode, "build_mesh_shading");
                    *pDecode = 0;
                }
            }
        }
    }
    if (code < 0) {
        if (*pFunction != 0) {
            gs_function_free(*pFunction, true, mem);
            *pFunction = 0;
        }
        gs_free_object(mem, data, "build_mesh_shading");
    }
    return code;
}