/* 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, ¶ms.Bounds, mem)) != params.k - 1 || (code = fn_build_float_array(op, "Encode", true, true, ¶ms.Encode, mem)) != 2 * params.k ) goto fail; if (params.Range == 0) params.n = params.Functions[0]->params.n; code = gs_function_1ItSg_init(ppfn, ¶ms, mem); if (code >= 0) return 0; fail: gs_function_1ItSg_free_params(¶ms, 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, ¶ms.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, ¶ms.Encode, mem)) != 2 * params.k) goto fail; if (params.Range == 0) params.n = params.Functions[0]->params.n; code = gs_function_1ItSg_init(ppfn, ¶ms, mem); if (code >= 0) return 0; fail: gs_function_1ItSg_free_params(¶ms, mem); return (code < 0 ? code : gs_note_error(e_rangecheck)); }