Exemple #1
0
/* Finish building a FunctionType 3 (1-Input Stitching) function. */
int
gs_build_function_3(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_1ItSg_params_t params;
    int code;

    *(gs_function_params_t *) & params = *mnDR;
    params.Functions = 0;
    params.Bounds = 0;
    params.Encode = 0;
    {
	ref *pFunctions;
	gs_function_t **ptr;
	int i;

	if ((code = dict_find_string(op, "Functions", &pFunctions)) <= 0)
	    return (code < 0 ? code : gs_note_error(e_rangecheck));
	check_array_only(*pFunctions);
	params.k = r_size(pFunctions);
	code = alloc_function_array(params.k, &ptr, mem);
	if (code < 0)
	    return code;
	params.Functions = (const gs_function_t * const *)ptr;
	for (i = 0; i < params.k; ++i) {
	    ref subfn;

	    array_get(mem, pFunctions, (long)i, &subfn);
	    code = fn_build_sub_function(i_ctx_p, &subfn, &ptr[i], depth, mem);
	    if (code < 0)
		goto fail;
	}
    }
    if ((code = fn_build_float_array(op, "Bounds", true, false, &params.Bounds, mem)) != params.k - 1 ||
	(code = fn_build_float_array(op, "Encode", true, true, &params.Encode, mem)) != 2 * params.k
	)
	goto fail;
    if (params.Range == 0)
	params.n = params.Functions[0]->params.n;
    code = gs_function_1ItSg_init(ppfn, &params, mem);
    if (code >= 0)
	return 0;
fail:
    gs_function_1ItSg_free_params(&params, mem);
    return (code < 0 ? code : gs_note_error(e_rangecheck));
}
static int
zmatchmedia(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    os_ptr preq = op - 3;
    os_ptr pattr = op - 2;
    os_ptr ppol = op - 1;
    os_ptr pkeys = op;		/* *const */
    int policy_default;
    float best_mismatch = (float)max_long;	/* adhoc */
    float mepos_penalty;
    float mbest = best_mismatch;
    match_record_t match;
    ref no_priority;
    ref *ppriority;
    int mepos, orient;
    bool roll;
    int code;
    int ai;
    struct mkd_ {
	ref key, dict;
    } aelt;
    if (r_has_type(pattr, t_null)) {
	check_op(4);
	make_null(op - 3);
	make_true(op - 2);
	pop(2);
	return 0;
    }
    check_type(*preq, t_dictionary);
    check_dict_read(*preq);
    check_type(*pattr, t_dictionary);
    check_dict_read(*pattr);
    check_type(*ppol, t_dictionary);
    check_dict_read(*ppol);
    check_array(*pkeys);
    check_read(*pkeys);
    switch (code = dict_int_null_param(preq, "MediaPosition", 0, 0x7fff,
				       0, &mepos)) {
	default:
	    return code;
	case 2:
	case 1:
	    mepos = -1;
	case 0:;
    }
    switch (code = dict_int_null_param(preq, "Orientation", 0, 3,
				       0, &orient)) {
	default:
	    return code;
	case 2:
	case 1:
	    orient = -1;
	case 0:;
    }
    code = dict_bool_param(preq, "RollFedMedia", false, &roll);
    if (code < 0)
	return code;
    code = dict_int_param(ppol, "PolicyNotFound", 0, 7, 0,
			  &policy_default);
    if (code < 0)
	return code;
    if (dict_find_string(pattr, "Priority", &ppriority) > 0) {
	check_array_only(*ppriority);
	check_read(*ppriority);
    } else {
	make_empty_array(&no_priority, a_readonly);
	ppriority = &no_priority;
    }
    match.no_match_priority = r_size(ppriority);
    reset_match(&match);
    for (ai = dict_first(pattr);
	 (ai = dict_next(pattr, ai, (ref * /*[2]*/)&aelt)) >= 0;
	 ) {
	if (r_has_type(&aelt.dict, t_dictionary) &&
	    r_has_attr(dict_access_ref(&aelt.dict), a_read) &&
	    r_has_type(&aelt.key, t_integer)
	    ) {
	    bool match_all;
	    uint ki, pi;

	    code = dict_bool_param(&aelt.dict, "MatchAll", false,
				   &match_all);
	    if (code < 0)
		return code;
	    for (ki = 0; ki < r_size(pkeys); ki++) {
		ref key;
		ref kstr;
		ref *prvalue;
		ref *pmvalue;
		ref *ppvalue;
		int policy;

		array_get(imemory, pkeys, ki, &key);
		if (dict_find(&aelt.dict, &key, &pmvalue) <= 0)
		    continue;
		if (dict_find(preq, &key, &prvalue) <= 0 ||
		    r_has_type(prvalue, t_null)
		    ) {
		    if (match_all)
			goto no;
		    else
			continue;
		}
		/* Look for the Policies entry for this key. */
		if (dict_find(ppol, &key, &ppvalue) > 0) {
		    check_type_only(*ppvalue, t_integer);
		    policy = ppvalue->value.intval;
		} else
		    policy = policy_default;
	/*
	 * Match a requested attribute value with the attribute value in the
	 * description of a medium.  For all attributes except PageSize,
	 * matching means equality.  PageSize is special; see match_page_size
	 * below.
	 */
		if (r_has_type(&key, t_name) &&
		    (name_string_ref(imemory, &key, &kstr),
		     r_size(&kstr) == 8 &&
		     !memcmp(kstr.value.bytes, "PageSize", 8))
		    ) {
		    gs_matrix ignore_mat;
		    gs_point ignore_msize;

		    if (zmatch_page_size(imemory, prvalue, pmvalue,
					 policy, orient, roll,
					 &best_mismatch,
					 &ignore_mat,
					 &ignore_msize)
			<= 0)
			goto no;
		} else if (!obj_eq(imemory, prvalue, pmvalue))
		    goto no;
	    }

	    mepos_penalty = (mepos < 0 || aelt.key.value.intval == mepos) ?
		0 : .001;

	    /* We have a match. Save the match in case no better match is found */
	    if (r_has_type(&match.match_key, t_null)) 
		match.match_key = aelt.key;
	    /*
	     * If it is a better match than the current best it supersedes it 
	     * regardless of priority. If the match is the same, then update 
	     * to the current only if the key value is lower.
	     */
	    if (best_mismatch + mepos_penalty <= mbest) {
		if (best_mismatch + mepos_penalty < mbest  ||
		    (r_has_type(&match.match_key, t_integer) &&
		     match.match_key.value.intval > aelt.key.value.intval)) {
		    reset_match(&match);
		    match.match_key = aelt.key;
		    mbest = best_mismatch + mepos_penalty;
		}
	    }
	    /* In case of a tie, see if the new match has priority. */
	    for (pi = match.priority; pi > 0;) {
		ref pri;

		pi--;
		array_get(imemory, ppriority, pi, &pri);
		if (obj_eq(imemory, &aelt.key, &pri)) {	/* Yes, higher priority. */
		    match.best_key = aelt.key;
		    match.priority = pi;
		    break;
		}
	    }
no:;
	}
    }
    if (r_has_type(&match.match_key, t_null)) {
	make_false(op - 3);
	pop(3);
    } else {
	if (r_has_type(&match.best_key, t_null))
	    op[-3] = match.match_key;
	else
	    op[-3] = match.best_key;
	make_true(op - 2);
	pop(2);
    }
    return 0;
}
/* Finish building a FunctionType 3 (1-Input Stitching) function. */
int
gs_build_function_3(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_1ItSg_params_t params;
    int code;
    extern bool CPSI_mode;

    *(gs_function_params_t *) & params = *mnDR;
    params.Functions = 0;
    params.Bounds = 0;
    params.Encode = 0;
    {
	ref *pFunctions;
	gs_function_t **ptr;
	int i;

	if ((code = dict_find_string(op, "Functions", &pFunctions)) <= 0)
	    return (code < 0 ? code : gs_note_error(e_rangecheck));
	check_array_only(*pFunctions);
	params.k = r_size(pFunctions);
	code = alloc_function_array(params.k, &ptr, mem);
	if (code < 0)
	    return code;
	params.Functions = (const gs_function_t * const *)ptr;
	for (i = 0; i < params.k; ++i) {
	    ref subfn;

	    array_get(mem, pFunctions, (long)i, &subfn);
	    code = fn_build_sub_function(i_ctx_p, &subfn, &ptr[i], depth, mem, 0, 0);
	    if (code < 0)
		goto fail;
	}
    }
    if ((code = fn_build_float_array(op, "Bounds", true, false, &params.Bounds, mem)) != params.k - 1)
	goto fail;
    if (CPSI_mode) {
	/* Adobe implementation doesn't check the Encode length. */
	/* Extra elements are ignored; missing elements are filled with 0. */
	/* CET 12-14m.ps depends on this bug */
	uint sz, k2 = 2 * params.k;
	ref *encode;
	float *p = (float *)gs_alloc_byte_array(mem, k2, sizeof(float), "Encode");

	params.Encode = p;
	if (p == 0) {
	    code = gs_note_error(e_VMerror);
	    goto fail;
	}
	if (dict_find_string(op, "Encode", &encode) <= 0) {
	    code = gs_note_error(e_undefined);
	    goto fail;
	}
	if (!r_is_array(encode)) {
	    code = gs_note_error(e_typecheck);
	    goto fail;
	}
	sz =  min(k2, r_size(encode));
	code = process_float_array(mem, encode, sz, p);
	if (code < 0)
	    goto fail;
	while (sz < k2)
	    p[sz++] = 0.0;
    } else if ((code = fn_build_float_array(op, "Encode", true, true, &params.Encode, mem)) != 2 * params.k)
	goto fail;
    if (params.Range == 0)
	params.n = params.Functions[0]->params.n;
    code = gs_function_1ItSg_init(ppfn, &params, mem);
    if (code >= 0)
	return 0;
fail:
    gs_function_1ItSg_free_params(&params, mem);
    return (code < 0 ? code : gs_note_error(e_rangecheck));
}