Example #1
0
/* Ws Bs Wd Bd Ps .transformPQR_scale_wb[012] Pd

   The default TransformPQR procedure is implemented in C, rather than
   PostScript, as a speed optimization.

   This TransformPQR implements a relative colorimetric intent by scaling
   the XYZ values relative to the white and black points.
*/
static int
ztpqr_scale_wb_common(i_ctx_t *i_ctx_p, int idx)
{
    os_ptr op = osp;
    double a[4], Ps; /* a[0] = ws, a[1] = bs, a[2] = wd, a[3] = bd */
    double result;
    int code;
    int i;

    code = real_param(op, &Ps);
    if (code < 0) return code;

    for (i = 0; i < 4; i++) {
	ref tmp;

	code = array_get(imemory, op - 4 + i, idx, &tmp);
	if (code >= 0)
	    code = real_param(&tmp, &a[i]);
	if (code < 0) return code;
    }

    if (a[0] == a[1])
	return_error(e_undefinedresult);
    result = a[3] + (a[2] - a[3]) * (Ps - a[1]) / (a[0] - a[1]);
    make_real(op - 4, result);
    pop(4);
    return 0;
}
Example #2
0
/* <angle> <matrix> rotate <matrix> */
static int
zrotate(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    int code;
    double ang;

    if ((code = real_param(op, &ang)) >= 0) {
        code = gs_rotate(igs, ang);
        if (code < 0)
            return code;
    } else {			/* matrix operand */
        gs_matrix mat;

        /* The num_params failure might be a stack underflow. */
        check_op(1);
        if ((code = num_params(op - 1, 1, &ang)) < 0 ||
            (code = gs_make_rotation(ang, &mat)) < 0 ||
            (code = write_matrix(op, &mat)) < 0
            ) {			/* Might be a stack underflow. */
            check_op(2);
            return code;
        }
        op[-1] = *op;
    }
    pop(1);
    return code;
}
Example #3
0
int
float_param(const ref * op, float *pparam)
{
    double dval;
    int code = real_param(op, &dval);

    if (code >= 0)
	*pparam = (float)dval;	/* can't overflow */
    return code;
}
Example #4
0
/* <font> <scale> scalefont <new_font> */
static int
zscalefont(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    int code;
    double scale;
    gs_matrix mat;

    if ((code = real_param(op, &scale)) < 0)
        return code;
    if ((code = gs_make_scaling(scale, scale, &mat)) < 0)
        return code;
    return make_font(i_ctx_p, &mat);
}
Example #5
0
static int
zset_real(i_ctx_t *i_ctx_p, int (*set_proc)(gs_state *, floatp))
{
    os_ptr op = osp;
    double param;
    int code = real_param(op, &param);

    if (code < 0)
	return_op_typecheck(op);
    code = set_proc(igs, param);
    if (!code)
	pop(1);
    return code;
}
Example #6
0
/* <alpha> setalpha - */
static int
zsetalpha(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    double alpha;
    int code;

    if (real_param(op, &alpha) < 0)
        return_op_typecheck(op);
    if ((code = gs_setalpha(igs, alpha)) < 0)
        return code;
    pop(1);
    return 0;
}
Example #7
0
/* <smoothness> setsmoothness - */
static int
zsetsmoothness(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    double smoothness;
    int code;

    if (real_param(op, &smoothness) < 0)
	return_op_typecheck(op);
    if ((code = gs_setsmoothness(igs, smoothness)) < 0)
	return code;
    pop(1);
    return 0;
}
Example #8
0
/* Continuation procedure for processing sampled pixels. */
static int
set_screen_continue(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    double value;
    int code = real_param(op, &value);

    if (code < 0)
        return code;
    code = gs_screen_next(senum, value);
    if (code < 0)
        return code;
    pop(1);
    return screen_sample(i_ctx_p);
}
Example #9
0
/* <num> <bool> .setdotlength - */
static int
zsetdotlength(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    double length;
    int code = real_param(op - 1, &length);

    if (code < 0)
	return code;
    check_type(*op, t_boolean);
    code = gs_setdotlength(igs, length, op->value.boolval);
    if (code < 0)
	return code;
    pop(2);
    return 0;
}
Example #10
0
/*   dissolve - */
static int
zdissolve(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    gs_composite_alpha_params_t params;
    double delta;
    int code = real_param(op, &delta);

    if (code < 0)
        return code;
    if (delta < 0 || delta > 1)
        return_error(e_rangecheck);
    params.op = composite_Dissolve;
    params.delta = delta;
    return composite_image(i_ctx_p, &params);
}
Example #11
0
/* <num> setlinewidth - */
static int
zsetlinewidth(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
	/*
	 * The Red Book doesn't say anything about this, but Adobe
	 * interpreters return (or perhaps store) the absolute value
	 * of the width.
	 */
    double width;
    int code = real_param(op, &width);

    if (code < 0)
	return_op_typecheck(op);
    code = gs_setlinewidth(igs, fabs(width));
    if (code >= 0)
	pop(1);
    return code;
}
Example #12
0
/* <array> <offset> setdash - */
static int
zsetdash(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    os_ptr op1 = op - 1;
    double offset;
    int code = real_param(op, &offset);
    uint i, n;
    gs_memory_t *mem = imemory;
    float *pattern;

    if (code < 0)
	return_op_typecheck(op);
    if (!r_is_array(op1))
	return_op_typecheck(op1);
    /* Adobe interpreters apparently don't check the array for */
    /* read access, so we won't either. */
    /*check_read(*op1); */
    /* Unpack the dash pattern and check it */
    n = r_size(op1);
    pattern =
	(float *)gs_alloc_byte_array(mem, n, sizeof(float), "setdash");

    if (pattern == 0)
	return_error(e_VMerror);
    for (i = 0, code = 0; i < n && code >= 0; ++i) {
	ref element;

	array_get(mem, op1, (long)i, &element);
	code = float_param(&element, &pattern[i]);
    }
    if (code >= 0)
	code = gs_setdash(igs, pattern, n, offset);
    gs_free_object(mem, pattern, "setdash");	/* gs_setdash copies this */
    if (code < 0)
	return code;
    ref_assign(&istate->dash_pattern_array, op1);
    pop(2);
    return code;
}
Example #13
0
/* <mark> <x0> <y0> ... <xn> <yn> .pdfinkpath - */
static int
zpdfinkpath(i_ctx_t *i_ctx_p)
{
    os_ptr optr, op = osp;
    uint count = ref_stack_counttomark(&o_stack);

    uint i, ocount;
    int code;
    double x0, y0, x1, y1, x2, y2, x3, y3, xc1, yc1, xc2, yc2, xc3, yc3;
    double len1, len2, len3, k1, k2, xm1, ym1, xm2, ym2;
    double ctrl1_x, ctrl1_y, ctrl2_x, ctrl2_y;
    const double smooth_value = 1; /* from 0..1 range */

    if (count == 0)
        return_error(e_unmatchedmark);
    if ((count & 1) == 0 || count < 3)
        return_error(e_rangecheck);

    ocount = count - 1;
    optr = op - ocount + 1;

    if ((code = real_param(optr, &x1)) < 0)
        return code;
    if ((code = real_param(optr + 1, &y1)) < 0)
        return code;
    if ((code = gs_moveto(igs, x1, y1)) < 0)
        return code;
    if (ocount == 2)
          goto pop;

    if ((code = real_param(optr + 2, &x2)) < 0)
        return code;
    if ((code = real_param(optr + 3, &y2)) < 0)
        return code;
    if (ocount == 4) {
        if((code = gs_lineto(igs, x2, y2)) < 0)
            return code;
        goto pop;
    }
    x0 = 2*x1 - x2;
    y0 = 2*y1 - y2;

    for (i = 4; i <= ocount; i += 2) {
        if (i < ocount) {
            if ((code = real_param(optr + i, &x3)) < 0)
                return code;
            if ((code = real_param(optr + i + 1, &y3)) < 0)
                return code;
        } else {
            x3 = 2*x2 - x1;
            y3 = 2*y2 - y1;
        }

        xc1 = (x0 + x1) / 2.0;
        yc1 = (y0 + y1) / 2.0;
        xc2 = (x1 + x2) / 2.0;
        yc2 = (y1 + y2) / 2.0;
        xc3 = (x2 + x3) / 2.0;
        yc3 = (y2 + y3) / 2.0;

        len1 = hypot(x1 - x0, y1 - y0);
        len2 = hypot(x2 - x1, y2 - y1);
        len3 = hypot(x3 - x2, y3 - y2);

        k1 = len1 / (len1 + len2);
        k2 = len2 / (len2 + len3);

        xm1 = xc1 + (xc2 - xc1) * k1;
        ym1 = yc1 + (yc2 - yc1) * k1;

        xm2 = xc2 + (xc3 - xc2) * k2;
        ym2 = yc2 + (yc3 - yc2) * k2;

        ctrl1_x = xm1 + (xc2 - xm1) * smooth_value + x1 - xm1;
        ctrl1_y = ym1 + (yc2 - ym1) * smooth_value + y1 - ym1;

        ctrl2_x = xm2 + (xc2 - xm2) * smooth_value + x2 - xm2;
        ctrl2_y = ym2 + (yc2 - ym2) * smooth_value + y2 - ym2;

        code = gs_curveto(igs, ctrl1_x, ctrl1_y, ctrl2_x, ctrl2_y, x2, y2);
        if (code < 0)
            return code;
        x0 = x1, x1 = x2, x2 = x3;
        y0 = y1, y1 = y2, y2 = y3;
    }
  pop:
    ref_stack_pop(&o_stack, count);
    return 0;
}
Example #14
0
/*
 * Continuation procedure for processing sampled values.
 */
static int
sampled_data_continue(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    gs_sampled_data_enum *penum = senum;
    gs_function_Sd_params_t * params =
            (gs_function_Sd_params_t *)&penum->pfn->params;
    int i, j, num_out = params->n;
    int code = 0;
    byte * data_ptr;
    double sampled_data_value_max = (double)((1 << params->BitsPerSample) - 1);
    int bps = bits2bytes(params->BitsPerSample), stack_depth_adjust = 0;

    /*
     * Check to make sure that the procedure produced the correct number of
     * values.  If not, move the stack back to where it belongs and abort
     */
    if (num_out + O_STACK_PAD + penum->o_stack_depth != ref_stack_count(&o_stack)) {
        stack_depth_adjust = ref_stack_count(&o_stack) - penum->o_stack_depth;

        if (stack_depth_adjust < 0) {
            /*
             * If we get to here then there were major problems.  The function
             * removed too many items off of the stack.  We had placed extra
             * (unused) stack stack space to allow for this but the function
             * exceeded even that.  Data on the stack may have been lost.
             * The only thing that we can do is move the stack pointer back and
             * hope.  (We have not seen real Postscript files that have this
             * problem.)
             */
            push(-stack_depth_adjust);
            ifree_object(penum->pfn, "sampled_data_continue(pfn)");
            ifree_object(penum, "sampled_data_continue((enum)");
            return_error(e_undefinedresult);
        }
    }

    /* Save data from the given function */
    data_ptr = cube_ptr_from_index(params, penum->indexes);
    for (i=0; i < num_out; i++) {
        ulong cv;
        double value;
        double rmin = params->Range[2 * i];
        double rmax = params->Range[2 * i + 1];

        code = real_param(op + i - num_out + 1, &value);
        if (code < 0)
            return code;
        if (value < rmin)
            value = rmin;
        else if (value > rmax)
            value = rmax;
        value = (value - rmin) / (rmax - rmin);		/* Convert to 0 to 1.0 */
        cv = (int) (value * sampled_data_value_max + 0.5);
        for (j = 0; j < bps; j++)
            data_ptr[bps * i + j] = (byte)(cv >> ((bps - 1 - j) * 8));	/* MSB first */
    }
    pop(num_out);		    /* Move op to base of result values */

    /* Check if we are done collecting data. */

    if (increment_cube_indexes(params, penum->indexes)) {
        if (stack_depth_adjust == 0)
            pop(O_STACK_PAD);	    /* Remove spare stack space */
        else
            pop(stack_depth_adjust - num_out);
        /* Execute the closing procedure, if given */
        code = 0;
        if (esp_finish_proc != 0)
            code = esp_finish_proc(i_ctx_p);

        return code;
    } else {
        if (stack_depth_adjust) {
            stack_depth_adjust -= num_out;
            push(O_STACK_PAD - stack_depth_adjust);
            for (i=0;i<O_STACK_PAD - stack_depth_adjust;i++)
                make_null(op - i);
        }
    }

    /* Now get the data for the next location */

    return sampled_data_sample(i_ctx_p);
}