/* Get N numeric parameters (as floating point numbers) from an array */ int process_float_array(const gs_memory_t *mem, const ref * parray, int count, float * pval) { int code = 0, indx0 = 0; /* we assume parray is an array of some type, of adequate length */ if (r_has_type(parray, t_array)) return float_params(parray->value.refs + count - 1, count, pval); /* short/mixed array; convert the entries to refs */ while (count > 0 && code >= 0) { int i, subcount; ref ref_buff[20]; /* 20 is arbitrary */ subcount = (count > countof(ref_buff) ? countof(ref_buff) : count); for (i = 0; i < subcount && code >= 0; i++) code = array_get(mem, parray, (long)(i + indx0), &ref_buff[i]); if (code >= 0) code = float_params(ref_buff + subcount - 1, subcount, pval); count -= subcount; pval += subcount; indx0 += subcount; } return code; }
/* Return 0 if OK, error code if not. */ int read_matrix(const gs_memory_t *mem, const ref * op, gs_matrix * pmat) { int code; ref values[6]; const ref *pvalues; switch (r_type(op)) { case t_array: pvalues = op->value.refs; break; case t_mixedarray: case t_shortarray: { int i; for (i = 0; i < 6; ++i) { code = array_get(mem, op, (long)i, &values[i]); if (code < 0) return code; } pvalues = values; } break; default: return_op_typecheck(op); } check_read(*op); if (r_size(op) != 6) return_error(e_rangecheck); code = float_params(pvalues + 5, 6, (float *)pmat); return (code < 0 ? code : 0); }
int zfor(i_ctx_t *i_ctx_p) { os_ptr op = osp; register es_ptr ep; int code; float params[3]; /* Mostly undocumented, and somewhat bizarre Adobe behavior discovered */ /* with the CET (28-05) and FTS (124-01) is that the proc is not run */ /* if BOTH the initial value and increment are zero. */ if ((code = float_params(op - 1, 3, params)) < 0) return code; if ( params[0] == 0.0 && params[1] == 0.0 ) { pop(4); /* don't run the proc */ return 0; } check_estack(7); ep = esp + 6; check_proc(*op); /* Push a mark, the control variable set to the initial value, */ /* the increment, the limit, and the procedure, */ /* and invoke the continuation operator. */ if (r_has_type(op - 3, t_integer) && r_has_type(op - 2, t_integer) ) { make_int(ep - 4, op[-3].value.intval); make_int(ep - 3, op[-2].value.intval); switch (r_type(op - 1)) { case t_integer: make_int(ep - 2, op[-1].value.intval); break; case t_real: make_int(ep - 2, (long)op[-1].value.realval); break; default: return_op_typecheck(op - 1); } if (ep[-3].value.intval >= 0) make_op_estack(ep, for_pos_int_continue); else make_op_estack(ep, for_neg_int_continue); } else { make_real(ep - 4, params[0]); make_real(ep - 3, params[1]); make_real(ep - 2, params[2]); make_op_estack(ep, for_real_continue); } make_mark_estack(ep - 5, es_for, no_cleanup); ref_assign(ep - 1, op); esp = ep; pop(4); return o_push_estack; }
/* <xx> <xy> <yx> <yy> <tx> <ty> .setmatrix - */ static int zsetmatrix(i_ctx_t *i_ctx_p) { os_ptr op = osp; gs_matrix mat; int code = float_params(op, 6, &mat.xx); if (code < 0) return code; if ((code = gs_setmatrix(igs, &mat)) < 0) return code; pop(6); return 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; }
/* <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; } } }