Example #1
0
/* Evaluate an Arrayed Output function. */
static int
fn_AdOt_evaluate(const gs_function_t *pfn_common, const float *in0, float *out)
{
    const gs_function_AdOt_t *const pfn =
	(const gs_function_AdOt_t *)pfn_common;
    const float *in = in0;
#define MAX_ADOT_IN 16
    float in_buf[MAX_ADOT_IN];
    int i;

    /*
     * We have to take special care to handle the case where in and out
     * overlap.  For the moment, handle it only for a limited number of
     * input values.
     */
    if (in <= out + (pfn->params.n - 1) && out <= in + (pfn->params.m - 1)) {
	if (pfn->params.m > MAX_ADOT_IN)
	    return_error(gs_error_rangecheck);
	memcpy(in_buf, in, pfn->params.m * sizeof(*in));
	in = in_buf;
    }
    for (i = 0; i < pfn->params.n; ++i) {
	int code =
	    gs_function_evaluate(pfn->params.Functions[i], in, out + i);

	if (code < 0)
	    return code;
    }
    return 0;
#undef MAX_ADOT_IN
}
Example #2
0
/* Evaluate a 1-Input Stitching function. */
static int
fn_1ItSg_evaluate(const gs_function_t * pfn_common, const float *in, float *out)
{
    const gs_function_1ItSg_t *const pfn =
	(const gs_function_1ItSg_t *)pfn_common;
    float arg = in[0], b0, b1, e0, encoded;
    int k = pfn->params.k;
    int i;

    if (arg < pfn->params.Domain[0]) {
	arg = pfn->params.Domain[0];
	i = 0;
    } else if (arg > pfn->params.Domain[1]) {
	arg = pfn->params.Domain[1];
	i = k - 1;
    } else {
	for (i = 0; i < k - 1; ++i)
	    if (arg <= pfn->params.Bounds[i])
		break;
    }
    b0 = (i == 0 ? pfn->params.Domain[0] : pfn->params.Bounds[i - 1]);
    b1 = (i == k - 1 ? pfn->params.Domain[1] : pfn->params.Bounds[i]);
    e0 = pfn->params.Encode[2 * i];
    if (b1 == b0)
	encoded = e0;
    else
	encoded =
	    (arg - b0) * (pfn->params.Encode[2 * i + 1] - e0) / (b1 - b0) + e0;
    if_debug3('~', "[~]1ItSg %g in %d => %g\n", arg, i, encoded);
    return gs_function_evaluate(pfn->params.Functions[i], &encoded, out);
}
Example #3
0
/* Map a DeviceN color using a Function. */
int
map_devn_using_function(const float *in, float *out,
                        const gs_imager_state *pis, void *data)

{
    gs_function_t *const pfn = data;

    return gs_function_evaluate(pfn, in, out);
}
Example #4
0
static int
Gt_next_vertex(const gs_shading_mesh_t * psh, shade_coord_stream_t * cs,
	       shading_vertex_t * vertex, patch_color_t *c)
{
    int code = shade_next_vertex(cs, vertex, c);
 
    if (code >= 0 && psh->params.Function) {
	c->t[0] = c->cc.paint.values[0];
	c->t[1] = 0;
	/* Decode the color with the function. */
	code = gs_function_evaluate(psh->params.Function, c->t,
				    c->cc.paint.values);
    } else
	psh->params.ColorSpace->type->restrict_color(&c->cc, psh->params.ColorSpace);
    return code;
}
Example #5
0
/* <in1> ... <function_struct> %execfunction <out1> ... */
int
zexecfunction(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;

        /*
         * Since this operator's name begins with %, the name is not defined
         * in systemdict.  The only place this operator can ever appear is
         * in the execute-only closure created by .buildfunction.
         * Therefore, in principle it is unnecessary to check the argument.
         * However, we do a little checking anyway just on general
         * principles.  Note that since the argument may be an instance of
         * any subclass of gs_function_t, we currently have no way to check
         * its type.
         */
    if (!r_is_struct(op) ||
        !r_has_masked_attrs(op, a_executable | a_execute, a_executable | a_all)
        )
        return_error(gs_error_typecheck);
    {
        gs_function_t *pfn = (gs_function_t *) op->value.pstruct;
        int m = pfn->params.m, n = pfn->params.n;
        int diff = n - (m + 1);

        if (diff > 0)
            check_ostack(diff);
        {
            float params[20];	/* arbitrary size, just to avoid allocs */
            float *in;
            float *out;
            int code = 0;

            if (m + n <= countof(params)) {
                in = params;
            } else {
                in = (float *)ialloc_byte_array(m + n, sizeof(float),
                                                "%execfunction(in/out)");
                if (in == 0)
                    code = gs_note_error(gs_error_VMerror);
            }
            out = in + m;
            if (code < 0 ||
                (code = float_params(op - 1, m, in)) < 0 ||
                (code = gs_function_evaluate(pfn, in, out)) < 0
                )
                DO_NOTHING;
            else {
                if (diff > 0)
                    push(diff);	/* can't fail */
                else if (diff < 0) {
                    pop(-diff);
                    op = osp;
                }
                code = make_floats(op + 1 - n, out, n);
            }
            if (in != params)
                ifree_object(in, "%execfunction(in)");
            return code;
        }
    }
}
Example #6
0
/* Create a Separation or DeviceN color space (internal). */
static int
pdf_separation_color_space(gx_device_pdf *pdev,
                           cos_array_t *pca, const char *csname,
                           const cos_value_t *snames,
                           const gs_color_space *alt_space,
                           const gs_function_t *pfn,
                           const pdf_color_space_names_t *pcsn,
                           const cos_value_t *v_attributes)
{
    cos_value_t v;
    const gs_range_t *ranges;
    int code, csi;

    /* We need to think about the alternate space. If we are producing
     * PDF/X or PDF/A we can't produce some device spaces, and the code in
     * pdf_color_space_named always allows device spaces. We could alter
     * that code, but by then we don't know its an Alternate space, and have
     * lost the tin transform procedure. So instead we check here.
     */
    csi = gs_color_space_get_index(alt_space);
    /* Note that if csi is ICC, check to see if this was one of
       the default substitutes that we introduced for DeviceGray,
       DeviceRGB or DeviceCMYK.  If it is, then just write
       the default color.  Depending upon the flavor of PDF,
       or other options, we may want to actually have all
       the colors defined by ICC profiles and not do the following
       substituion of the Device space. */
    if (csi == gs_color_space_index_ICC) {
        csi = gsicc_get_default_type(alt_space->cmm_icc_profile_data);
    }
    if (csi == gs_color_space_index_DeviceRGB && (pdev->PDFX ||
            (pdev->PDFA && (pdev->pcm_color_info_index == gs_color_space_index_DeviceCMYK)))) {

        /* We have a DeviceRGB alternate, but are producing either PDF/X or
         * PDF/A with a DeviceCMYK process color model. So we need to convert
         * the alternate space into CMYK. We do this by evaluating the function
         * at each end of the Separation space (0 and 1), convert the resulting
         * RGB colours into CMYK and create a new function which linearly
         * interpolates between these points.
         */
        gs_function_t *new_pfn = 0;
        float in[1] = {0.0f};
        float out_low[4];
        float out_high[4];

        code = gs_function_evaluate(pfn, in, out_low);
        if (code < 0)
            return code;
        pdf_SepRGB_ConvertToCMYK((float *)&out_low, (float *)&out_low);

        in[0] = 1.0f;
        code = gs_function_evaluate(pfn, in, out_high);
        if (code < 0)
            return code;
        pdf_SepRGB_ConvertToCMYK((float *)&out_high, (float *)&out_high);

        code = pdf_make_base_space_function(pdev, &new_pfn, 4, out_low, out_high);
        if (code < 0)
            return code;
        if ((code = cos_array_add(pca, cos_c_string_value(&v, csname))) < 0 ||
                (code = cos_array_add_no_copy(pca, snames)) < 0 ||
                (code = (int)cos_c_string_value(&v, (const char *)pcsn->DeviceCMYK)) < 0 ||
                (code = cos_array_add(pca, &v)) < 0 ||
                (code = pdf_function_scaled(pdev, new_pfn, 0x00, &v)) < 0 ||
                (code = cos_array_add(pca, &v)) < 0 ||
                (v_attributes != NULL ? code = cos_array_add(pca, v_attributes) : 0) < 0
           ) {}
        pdf_delete_base_space_function(pdev, new_pfn);
        return code;
    }
    if (csi == gs_color_space_index_DeviceCMYK &&
            (pdev->PDFA && (pdev->pcm_color_info_index == gs_color_space_index_DeviceRGB))) {
        /* We have a DeviceCMYK alternate, but are producingPDF/A with a
         * DeviceRGB process color model. See comment above re DviceRGB.
         */
        gs_function_t *new_pfn = 0;
        float in[1] = {0.0f};
        float out_low[4];
        float out_high[4];

        code = gs_function_evaluate(pfn, in, out_low);
        if (code < 0)
            return code;
        pdf_SepCMYK_ConvertToRGB((float *)&out_low, (float *)&out_low);

        in[0] = 1.0f;
        code = gs_function_evaluate(pfn, in, out_high);
        if (code < 0)
            return code;
        pdf_SepCMYK_ConvertToRGB((float *)&out_high, (float *)&out_high);

        code = pdf_make_base_space_function(pdev, &new_pfn, 3, out_low, out_high);
        if (code < 0)
            return code;
        if ((code = cos_array_add(pca, cos_c_string_value(&v, csname))) < 0 ||
                (code = cos_array_add_no_copy(pca, snames)) < 0 ||
                (code = (int)cos_c_string_value(&v, pcsn->DeviceRGB)) < 0 ||
                (code = cos_array_add(pca, &v)) < 0 ||
                (code = pdf_function_scaled(pdev, new_pfn, 0x00, &v)) < 0 ||
                (code = cos_array_add(pca, &v)) < 0 ||
                (v_attributes != NULL ? code = cos_array_add(pca, v_attributes) : 0) < 0
           ) {}
        pdf_delete_base_space_function(pdev, new_pfn);
        return code;
    }

    if ((code = cos_array_add(pca, cos_c_string_value(&v, csname))) < 0 ||
            (code = cos_array_add_no_copy(pca, snames)) < 0 ||
            (code = pdf_color_space_named(pdev, &v, &ranges, alt_space, pcsn, false, NULL, 0)) < 0 ||
            (code = cos_array_add(pca, &v)) < 0 ||
            (code = pdf_function_scaled(pdev, pfn, ranges, &v)) < 0 ||
            (code = cos_array_add(pca, &v)) < 0 ||
            (v_attributes != NULL ? code = cos_array_add(pca, v_attributes) : 0) < 0
       )
        return code;
    return 0;
}