17dd7cddfSDavid du Colombier /* Copyright (C) 1992, 2000 Aladdin Enterprises. All rights reserved.
27dd7cddfSDavid du Colombier
3*593dc095SDavid du Colombier This software is provided AS-IS with no warranty, either express or
4*593dc095SDavid du Colombier implied.
57dd7cddfSDavid du Colombier
6*593dc095SDavid du Colombier This software is distributed under license and may not be copied,
7*593dc095SDavid du Colombier modified or distributed except as expressly authorized under the terms
8*593dc095SDavid du Colombier of the license contained in the file LICENSE in this distribution.
97dd7cddfSDavid du Colombier
10*593dc095SDavid du Colombier For more information about licensing, please refer to
11*593dc095SDavid du Colombier http://www.ghostscript.com/licensing/. For information on
12*593dc095SDavid du Colombier commercial licensing, go to http://www.artifex.com/licensing/ or
13*593dc095SDavid du Colombier contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14*593dc095SDavid du Colombier San Rafael, CA 94903, U.S.A., +1(415)492-9861.
157dd7cddfSDavid du Colombier */
167dd7cddfSDavid du Colombier
17*593dc095SDavid du Colombier /* $Id: zcie.c,v 1.13 2005/07/28 15:24:29 alexcher Exp $ */
187dd7cddfSDavid du Colombier /* CIE color operators */
197dd7cddfSDavid du Colombier #include "math_.h"
207dd7cddfSDavid du Colombier #include "memory_.h"
217dd7cddfSDavid du Colombier #include "ghost.h"
227dd7cddfSDavid du Colombier #include "oper.h"
237dd7cddfSDavid du Colombier #include "gsstruct.h"
247dd7cddfSDavid du Colombier #include "gxcspace.h" /* gscolor2.h requires gscspace.h */
257dd7cddfSDavid du Colombier #include "gscolor2.h"
267dd7cddfSDavid du Colombier #include "gscie.h"
277dd7cddfSDavid du Colombier #include "estack.h"
287dd7cddfSDavid du Colombier #include "ialloc.h"
297dd7cddfSDavid du Colombier #include "idict.h"
307dd7cddfSDavid du Colombier #include "idparam.h"
317dd7cddfSDavid du Colombier #include "igstate.h"
327dd7cddfSDavid du Colombier #include "icie.h"
337dd7cddfSDavid du Colombier #include "isave.h"
347dd7cddfSDavid du Colombier #include "ivmspace.h"
357dd7cddfSDavid du Colombier #include "store.h" /* for make_null */
367dd7cddfSDavid du Colombier
377dd7cddfSDavid du Colombier /* Empty procedures */
387dd7cddfSDavid du Colombier static const ref empty_procs[4] =
397dd7cddfSDavid du Colombier {
407dd7cddfSDavid du Colombier empty_ref_data(t_array, a_readonly | a_executable),
417dd7cddfSDavid du Colombier empty_ref_data(t_array, a_readonly | a_executable),
427dd7cddfSDavid du Colombier empty_ref_data(t_array, a_readonly | a_executable),
437dd7cddfSDavid du Colombier empty_ref_data(t_array, a_readonly | a_executable)
447dd7cddfSDavid du Colombier };
457dd7cddfSDavid du Colombier
467dd7cddfSDavid du Colombier /* ------ Parameter extraction utilities ------ */
477dd7cddfSDavid du Colombier
487dd7cddfSDavid du Colombier /* Get a range array parameter from a dictionary. */
497dd7cddfSDavid du Colombier /* We know that count <= 4. */
507dd7cddfSDavid du Colombier int
dict_ranges_param(const gs_memory_t * mem,const ref * pdref,const char * kstr,int count,gs_range * prange)51*593dc095SDavid du Colombier dict_ranges_param(const gs_memory_t *mem,
52*593dc095SDavid du Colombier const ref * pdref, const char *kstr, int count,
537dd7cddfSDavid du Colombier gs_range * prange)
547dd7cddfSDavid du Colombier {
55*593dc095SDavid du Colombier int code = dict_floats_param(mem, pdref, kstr, count * 2,
567dd7cddfSDavid du Colombier (float *)prange, NULL);
577dd7cddfSDavid du Colombier
587dd7cddfSDavid du Colombier if (code < 0)
597dd7cddfSDavid du Colombier return code;
607dd7cddfSDavid du Colombier else if (code == 0)
617dd7cddfSDavid du Colombier memcpy(prange, Range4_default.ranges, count * sizeof(gs_range));
627dd7cddfSDavid du Colombier return 0;
637dd7cddfSDavid du Colombier }
647dd7cddfSDavid du Colombier
657dd7cddfSDavid du Colombier /* Get an array of procedures from a dictionary. */
667dd7cddfSDavid du Colombier /* We know count <= countof(empty_procs). */
677dd7cddfSDavid du Colombier int
dict_proc_array_param(const gs_memory_t * mem,const ref * pdict,const char * kstr,uint count,ref * pparray)68*593dc095SDavid du Colombier dict_proc_array_param(const gs_memory_t *mem,
69*593dc095SDavid du Colombier const ref *pdict, const char *kstr,
707dd7cddfSDavid du Colombier uint count, ref *pparray)
717dd7cddfSDavid du Colombier {
727dd7cddfSDavid du Colombier ref *pvalue;
737dd7cddfSDavid du Colombier
747dd7cddfSDavid du Colombier if (dict_find_string(pdict, kstr, &pvalue) > 0) {
757dd7cddfSDavid du Colombier uint i;
767dd7cddfSDavid du Colombier
777dd7cddfSDavid du Colombier check_array_only(*pvalue);
787dd7cddfSDavid du Colombier if (r_size(pvalue) != count)
797dd7cddfSDavid du Colombier return_error(e_rangecheck);
807dd7cddfSDavid du Colombier for (i = 0; i < count; i++) {
817dd7cddfSDavid du Colombier ref proc;
827dd7cddfSDavid du Colombier
83*593dc095SDavid du Colombier array_get(mem, pvalue, (long)i, &proc);
847dd7cddfSDavid du Colombier check_proc_only(proc);
857dd7cddfSDavid du Colombier }
867dd7cddfSDavid du Colombier *pparray = *pvalue;
877dd7cddfSDavid du Colombier } else
887dd7cddfSDavid du Colombier make_const_array(pparray, a_readonly | avm_foreign,
897dd7cddfSDavid du Colombier count, &empty_procs[0]);
907dd7cddfSDavid du Colombier return 0;
917dd7cddfSDavid du Colombier }
927dd7cddfSDavid du Colombier
937dd7cddfSDavid du Colombier /* Get 3 ranges from a dictionary. */
947dd7cddfSDavid du Colombier int
dict_range3_param(const gs_memory_t * mem,const ref * pdref,const char * kstr,gs_range3 * prange3)95*593dc095SDavid du Colombier dict_range3_param(const gs_memory_t *mem,
96*593dc095SDavid du Colombier const ref *pdref, const char *kstr,
97*593dc095SDavid du Colombier gs_range3 *prange3)
987dd7cddfSDavid du Colombier {
99*593dc095SDavid du Colombier return dict_ranges_param(mem, pdref, kstr, 3, prange3->ranges);
1007dd7cddfSDavid du Colombier }
1017dd7cddfSDavid du Colombier
1027dd7cddfSDavid du Colombier /* Get a 3x3 matrix from a dictionary. */
1037dd7cddfSDavid du Colombier int
dict_matrix3_param(const gs_memory_t * mem,const ref * pdref,const char * kstr,gs_matrix3 * pmat3)104*593dc095SDavid du Colombier dict_matrix3_param(const gs_memory_t *mem,
105*593dc095SDavid du Colombier const ref *pdref, const char *kstr, gs_matrix3 *pmat3)
1067dd7cddfSDavid du Colombier {
1077dd7cddfSDavid du Colombier /*
1087dd7cddfSDavid du Colombier * We can't simply call dict_float_array_param with the matrix
1097dd7cddfSDavid du Colombier * cast to a 9-element float array, because compilers may insert
1107dd7cddfSDavid du Colombier * padding elements after each of the vectors. However, we can be
1117dd7cddfSDavid du Colombier * confident that there is no padding within a single vector.
1127dd7cddfSDavid du Colombier */
113*593dc095SDavid du Colombier float values[9], defaults[9];
1147dd7cddfSDavid du Colombier int code;
1157dd7cddfSDavid du Colombier
116*593dc095SDavid du Colombier memcpy(&defaults[0], &Matrix3_default.cu, 3 * sizeof(float));
117*593dc095SDavid du Colombier memcpy(&defaults[3], &Matrix3_default.cv, 3 * sizeof(float));
118*593dc095SDavid du Colombier memcpy(&defaults[6], &Matrix3_default.cw, 3 * sizeof(float));
119*593dc095SDavid du Colombier code = dict_floats_param(mem, pdref, kstr, 9, values, defaults);
1203ff48bf5SDavid du Colombier if (code < 0)
1213ff48bf5SDavid du Colombier return code;
1227dd7cddfSDavid du Colombier memcpy(&pmat3->cu, &values[0], 3 * sizeof(float));
1237dd7cddfSDavid du Colombier memcpy(&pmat3->cv, &values[3], 3 * sizeof(float));
1247dd7cddfSDavid du Colombier memcpy(&pmat3->cw, &values[6], 3 * sizeof(float));
1257dd7cddfSDavid du Colombier return 0;
1267dd7cddfSDavid du Colombier }
1277dd7cddfSDavid du Colombier
1287dd7cddfSDavid du Colombier /* Get 3 procedures from a dictionary. */
1297dd7cddfSDavid du Colombier int
dict_proc3_param(const gs_memory_t * mem,const ref * pdref,const char * kstr,ref proc3[3])130*593dc095SDavid du Colombier dict_proc3_param(const gs_memory_t *mem, const ref *pdref, const char *kstr, ref proc3[3])
1317dd7cddfSDavid du Colombier {
132*593dc095SDavid du Colombier return dict_proc_array_param(mem, pdref, kstr, 3, proc3);
1337dd7cddfSDavid du Colombier }
1347dd7cddfSDavid du Colombier
1357dd7cddfSDavid du Colombier /* Get WhitePoint and BlackPoint values. */
1367dd7cddfSDavid du Colombier int
cie_points_param(const gs_memory_t * mem,const ref * pdref,gs_cie_wb * pwb)137*593dc095SDavid du Colombier cie_points_param(const gs_memory_t *mem,
138*593dc095SDavid du Colombier const ref * pdref, gs_cie_wb * pwb)
1397dd7cddfSDavid du Colombier {
1407dd7cddfSDavid du Colombier int code;
1417dd7cddfSDavid du Colombier
142*593dc095SDavid du Colombier if ((code = dict_floats_param(mem, pdref, "WhitePoint", 3, (float *)&pwb->WhitePoint, NULL)) < 0 ||
143*593dc095SDavid du Colombier (code = dict_floats_param(mem, pdref, "BlackPoint", 3, (float *)&pwb->BlackPoint, (const float *)&BlackPoint_default)) < 0
1447dd7cddfSDavid du Colombier )
1453ff48bf5SDavid du Colombier return code;
1467dd7cddfSDavid du Colombier if (pwb->WhitePoint.u <= 0 ||
1477dd7cddfSDavid du Colombier pwb->WhitePoint.v != 1 ||
1487dd7cddfSDavid du Colombier pwb->WhitePoint.w <= 0 ||
1497dd7cddfSDavid du Colombier pwb->BlackPoint.u < 0 ||
1507dd7cddfSDavid du Colombier pwb->BlackPoint.v < 0 ||
1517dd7cddfSDavid du Colombier pwb->BlackPoint.w < 0
1527dd7cddfSDavid du Colombier )
1537dd7cddfSDavid du Colombier return_error(e_rangecheck);
1547dd7cddfSDavid du Colombier return 0;
1557dd7cddfSDavid du Colombier }
1567dd7cddfSDavid du Colombier
1577dd7cddfSDavid du Colombier /* Process a 3- or 4-dimensional lookup table from a dictionary. */
1587dd7cddfSDavid du Colombier /* The caller has set pclt->n and pclt->m. */
1597dd7cddfSDavid du Colombier /* ptref is known to be a readable array of size at least n+1. */
160*593dc095SDavid du Colombier private int cie_3d_table_param(const ref * ptable, uint count, uint nbytes,
161*593dc095SDavid du Colombier gs_const_string * strings);
1627dd7cddfSDavid du Colombier int
cie_table_param(const ref * ptref,gx_color_lookup_table * pclt,gs_memory_t * mem)1637dd7cddfSDavid du Colombier cie_table_param(const ref * ptref, gx_color_lookup_table * pclt,
1647dd7cddfSDavid du Colombier gs_memory_t * mem)
1657dd7cddfSDavid du Colombier {
1667dd7cddfSDavid du Colombier int n = pclt->n, m = pclt->m;
1677dd7cddfSDavid du Colombier const ref *pta = ptref->value.const_refs;
1687dd7cddfSDavid du Colombier int i;
1697dd7cddfSDavid du Colombier uint nbytes;
1707dd7cddfSDavid du Colombier int code;
1717dd7cddfSDavid du Colombier gs_const_string *table;
1727dd7cddfSDavid du Colombier
1737dd7cddfSDavid du Colombier for (i = 0; i < n; ++i) {
1747dd7cddfSDavid du Colombier check_type_only(pta[i], t_integer);
1757dd7cddfSDavid du Colombier if (pta[i].value.intval <= 1 || pta[i].value.intval > max_ushort)
1767dd7cddfSDavid du Colombier return_error(e_rangecheck);
1777dd7cddfSDavid du Colombier pclt->dims[i] = (int)pta[i].value.intval;
1787dd7cddfSDavid du Colombier }
1797dd7cddfSDavid du Colombier nbytes = m * pclt->dims[n - 2] * pclt->dims[n - 1];
1807dd7cddfSDavid du Colombier if (n == 3) {
1817dd7cddfSDavid du Colombier table =
1827dd7cddfSDavid du Colombier gs_alloc_struct_array(mem, pclt->dims[0], gs_const_string,
1837dd7cddfSDavid du Colombier &st_const_string_element, "cie_table_param");
1847dd7cddfSDavid du Colombier if (table == 0)
1857dd7cddfSDavid du Colombier return_error(e_VMerror);
1867dd7cddfSDavid du Colombier code = cie_3d_table_param(pta + 3, pclt->dims[0], nbytes, table);
1877dd7cddfSDavid du Colombier } else { /* n == 4 */
1887dd7cddfSDavid du Colombier int d0 = pclt->dims[0], d1 = pclt->dims[1];
1897dd7cddfSDavid du Colombier uint ntables = d0 * d1;
1907dd7cddfSDavid du Colombier const ref *psuba;
1917dd7cddfSDavid du Colombier
1927dd7cddfSDavid du Colombier check_read_type(pta[4], t_array);
1937dd7cddfSDavid du Colombier if (r_size(pta + 4) != d0)
1947dd7cddfSDavid du Colombier return_error(e_rangecheck);
1957dd7cddfSDavid du Colombier table =
1967dd7cddfSDavid du Colombier gs_alloc_struct_array(mem, ntables, gs_const_string,
1977dd7cddfSDavid du Colombier &st_const_string_element, "cie_table_param");
1987dd7cddfSDavid du Colombier if (table == 0)
1997dd7cddfSDavid du Colombier return_error(e_VMerror);
2007dd7cddfSDavid du Colombier psuba = pta[4].value.const_refs;
2017dd7cddfSDavid du Colombier /*
2027dd7cddfSDavid du Colombier * We know that d0 > 0, so code will always be set in the loop:
2037dd7cddfSDavid du Colombier * we initialize code to 0 here solely to pacify stupid compilers.
2047dd7cddfSDavid du Colombier */
2057dd7cddfSDavid du Colombier for (code = 0, i = 0; i < d0; ++i) {
2067dd7cddfSDavid du Colombier code = cie_3d_table_param(psuba + i, d1, nbytes, table + d1 * i);
2077dd7cddfSDavid du Colombier if (code < 0)
2087dd7cddfSDavid du Colombier break;
2097dd7cddfSDavid du Colombier }
2107dd7cddfSDavid du Colombier }
2117dd7cddfSDavid du Colombier if (code < 0) {
2127dd7cddfSDavid du Colombier gs_free_object(mem, table, "cie_table_param");
2137dd7cddfSDavid du Colombier return code;
2147dd7cddfSDavid du Colombier }
2157dd7cddfSDavid du Colombier pclt->table = table;
2167dd7cddfSDavid du Colombier return 0;
2177dd7cddfSDavid du Colombier }
2187dd7cddfSDavid du Colombier private int
cie_3d_table_param(const ref * ptable,uint count,uint nbytes,gs_const_string * strings)2197dd7cddfSDavid du Colombier cie_3d_table_param(const ref * ptable, uint count, uint nbytes,
2207dd7cddfSDavid du Colombier gs_const_string * strings)
2217dd7cddfSDavid du Colombier {
2227dd7cddfSDavid du Colombier const ref *rstrings;
2237dd7cddfSDavid du Colombier uint i;
2247dd7cddfSDavid du Colombier
2257dd7cddfSDavid du Colombier check_read_type(*ptable, t_array);
2267dd7cddfSDavid du Colombier if (r_size(ptable) != count)
2277dd7cddfSDavid du Colombier return_error(e_rangecheck);
2287dd7cddfSDavid du Colombier rstrings = ptable->value.const_refs;
2297dd7cddfSDavid du Colombier for (i = 0; i < count; ++i) {
2307dd7cddfSDavid du Colombier const ref *const prt2 = rstrings + i;
2317dd7cddfSDavid du Colombier
2327dd7cddfSDavid du Colombier check_read_type(*prt2, t_string);
2337dd7cddfSDavid du Colombier if (r_size(prt2) != nbytes)
2347dd7cddfSDavid du Colombier return_error(e_rangecheck);
2357dd7cddfSDavid du Colombier strings[i].data = prt2->value.const_bytes;
2367dd7cddfSDavid du Colombier strings[i].size = nbytes;
2377dd7cddfSDavid du Colombier }
2387dd7cddfSDavid du Colombier return 0;
2397dd7cddfSDavid du Colombier }
2407dd7cddfSDavid du Colombier
2417dd7cddfSDavid du Colombier /* ------ CIE setcolorspace ------ */
2427dd7cddfSDavid du Colombier
2437dd7cddfSDavid du Colombier /* Common code for the CIEBased* cases of setcolorspace. */
2447dd7cddfSDavid du Colombier private int
cie_lmnp_param(const gs_memory_t * mem,const ref * pdref,gs_cie_common * pcie,ref_cie_procs * pcprocs)245*593dc095SDavid du Colombier cie_lmnp_param(const gs_memory_t *mem, const ref * pdref, gs_cie_common * pcie, ref_cie_procs * pcprocs)
2467dd7cddfSDavid du Colombier {
2477dd7cddfSDavid du Colombier int code;
2487dd7cddfSDavid du Colombier
249*593dc095SDavid du Colombier if ((code = dict_range3_param(mem, pdref, "RangeLMN", &pcie->RangeLMN)) < 0 ||
250*593dc095SDavid du Colombier (code = dict_proc3_param(mem, pdref, "DecodeLMN", &pcprocs->DecodeLMN)) < 0 ||
251*593dc095SDavid du Colombier (code = dict_matrix3_param(mem, pdref, "MatrixLMN", &pcie->MatrixLMN)) < 0 ||
252*593dc095SDavid du Colombier (code = cie_points_param(mem, pdref, &pcie->points)) < 0
2537dd7cddfSDavid du Colombier )
2547dd7cddfSDavid du Colombier return code;
2557dd7cddfSDavid du Colombier pcie->DecodeLMN = DecodeLMN_default;
2567dd7cddfSDavid du Colombier return 0;
2577dd7cddfSDavid du Colombier }
2587dd7cddfSDavid du Colombier
2597dd7cddfSDavid du Colombier /* Common code for the CIEBasedABC/DEF[G] cases of setcolorspace. */
2607dd7cddfSDavid du Colombier private int
cie_abc_param(const gs_memory_t * mem,const ref * pdref,gs_cie_abc * pcie,ref_cie_procs * pcprocs)261*593dc095SDavid du Colombier cie_abc_param(const gs_memory_t *mem, const ref * pdref, gs_cie_abc * pcie, ref_cie_procs * pcprocs)
2627dd7cddfSDavid du Colombier {
2637dd7cddfSDavid du Colombier int code;
2647dd7cddfSDavid du Colombier
265*593dc095SDavid du Colombier if ((code = dict_range3_param(mem, pdref, "RangeABC", &pcie->RangeABC)) < 0 ||
266*593dc095SDavid du Colombier (code = dict_proc3_param(mem, pdref, "DecodeABC", &pcprocs->Decode.ABC)) < 0 ||
267*593dc095SDavid du Colombier (code = dict_matrix3_param(mem, pdref, "MatrixABC", &pcie->MatrixABC)) < 0 ||
268*593dc095SDavid du Colombier (code = cie_lmnp_param(mem, pdref, &pcie->common, pcprocs)) < 0
2697dd7cddfSDavid du Colombier )
2707dd7cddfSDavid du Colombier return code;
2717dd7cddfSDavid du Colombier pcie->DecodeABC = DecodeABC_default;
2727dd7cddfSDavid du Colombier return 0;
2737dd7cddfSDavid du Colombier }
2747dd7cddfSDavid du Colombier
2757dd7cddfSDavid du Colombier /* Finish setting a CIE space (successful or not). */
2763ff48bf5SDavid du Colombier int
cie_set_finish(i_ctx_t * i_ctx_p,gs_color_space * pcs,const ref_cie_procs * pcprocs,int edepth,int code)2773ff48bf5SDavid du Colombier cie_set_finish(i_ctx_t *i_ctx_p, gs_color_space * pcs,
2787dd7cddfSDavid du Colombier const ref_cie_procs * pcprocs, int edepth, int code)
2797dd7cddfSDavid du Colombier {
2807dd7cddfSDavid du Colombier if (code >= 0)
2817dd7cddfSDavid du Colombier code = gs_setcolorspace(igs, pcs);
2827dd7cddfSDavid du Colombier /* Delete the extra reference to the parameter tables. */
2837dd7cddfSDavid du Colombier gs_cspace_release(pcs);
2847dd7cddfSDavid du Colombier /* Free the top-level object, which was copied by gs_setcolorspace. */
2853ff48bf5SDavid du Colombier gs_free_object(gs_state_memory(igs), pcs, "cie_set_finish");
2867dd7cddfSDavid du Colombier if (code < 0) {
2877dd7cddfSDavid du Colombier ref_stack_pop_to(&e_stack, edepth);
2887dd7cddfSDavid du Colombier return code;
2897dd7cddfSDavid du Colombier }
2907dd7cddfSDavid du Colombier istate->colorspace.procs.cie = *pcprocs;
2917dd7cddfSDavid du Colombier pop(1);
2927dd7cddfSDavid du Colombier return (ref_stack_count(&e_stack) == edepth ? 0 : o_push_estack);
2937dd7cddfSDavid du Colombier }
2947dd7cddfSDavid du Colombier
2957dd7cddfSDavid du Colombier /* Forward references */
296*593dc095SDavid du Colombier private int cache_common(i_ctx_t *, gs_cie_common *, const ref_cie_procs *,
297*593dc095SDavid du Colombier void *, gs_ref_memory_t *);
298*593dc095SDavid du Colombier private int cache_abc_common(i_ctx_t *, gs_cie_abc *, const ref_cie_procs *,
299*593dc095SDavid du Colombier void *, gs_ref_memory_t *);
3007dd7cddfSDavid du Colombier
3017dd7cddfSDavid du Colombier /* <dict> .setciedefgspace - */
302*593dc095SDavid du Colombier private int cie_defg_finish(i_ctx_t *);
3037dd7cddfSDavid du Colombier private int
zsetciedefgspace(i_ctx_t * i_ctx_p)3047dd7cddfSDavid du Colombier zsetciedefgspace(i_ctx_t *i_ctx_p)
3057dd7cddfSDavid du Colombier {
3067dd7cddfSDavid du Colombier os_ptr op = osp;
3077dd7cddfSDavid du Colombier int edepth = ref_stack_count(&e_stack);
3087dd7cddfSDavid du Colombier gs_memory_t *mem = gs_state_memory(igs);
3097dd7cddfSDavid du Colombier gs_ref_memory_t *imem = (gs_ref_memory_t *)mem;
3107dd7cddfSDavid du Colombier gs_color_space *pcs;
3117dd7cddfSDavid du Colombier ref_cie_procs procs;
3127dd7cddfSDavid du Colombier gs_cie_defg *pcie;
3137dd7cddfSDavid du Colombier int code;
3147dd7cddfSDavid du Colombier ref *ptref;
3157dd7cddfSDavid du Colombier
3167dd7cddfSDavid du Colombier check_type(*op, t_dictionary);
3177dd7cddfSDavid du Colombier check_dict_read(*op);
3187dd7cddfSDavid du Colombier if ((code = dict_find_string(op, "Table", &ptref)) <= 0)
3197dd7cddfSDavid du Colombier return (code < 0 ? code : gs_note_error(e_rangecheck));
3207dd7cddfSDavid du Colombier check_read_type(*ptref, t_array);
3217dd7cddfSDavid du Colombier if (r_size(ptref) != 5)
3227dd7cddfSDavid du Colombier return_error(e_rangecheck);
3237dd7cddfSDavid du Colombier procs = istate->colorspace.procs.cie;
3247dd7cddfSDavid du Colombier code = gs_cspace_build_CIEDEFG(&pcs, NULL, mem);
3257dd7cddfSDavid du Colombier if (code < 0)
3267dd7cddfSDavid du Colombier return code;
3277dd7cddfSDavid du Colombier pcie = pcs->params.defg;
3287dd7cddfSDavid du Colombier pcie->Table.n = 4;
3297dd7cddfSDavid du Colombier pcie->Table.m = 3;
330*593dc095SDavid du Colombier if ((code = dict_ranges_param(mem, op, "RangeDEFG", 4, pcie->RangeDEFG.ranges)) < 0 ||
331*593dc095SDavid du Colombier (code = dict_proc_array_param(mem, op, "DecodeDEFG", 4, &procs.PreDecode.DEFG)) < 0 ||
332*593dc095SDavid du Colombier (code = dict_ranges_param(mem, op, "RangeHIJK", 4, pcie->RangeHIJK.ranges)) < 0 ||
3337dd7cddfSDavid du Colombier (code = cie_table_param(ptref, &pcie->Table, mem)) < 0 ||
334*593dc095SDavid du Colombier (code = cie_abc_param(imemory, op, (gs_cie_abc *) pcie, &procs)) < 0 ||
3357dd7cddfSDavid du Colombier (code = cie_cache_joint(i_ctx_p, &istate->colorrendering.procs, (gs_cie_common *)pcie, igs)) < 0 || /* do this last */
3367dd7cddfSDavid du Colombier (code = cie_cache_push_finish(i_ctx_p, cie_defg_finish, imem, pcie)) < 0 ||
3377dd7cddfSDavid du Colombier (code = cie_prepare_cache4(i_ctx_p, &pcie->RangeDEFG,
3387dd7cddfSDavid du Colombier procs.PreDecode.DEFG.value.const_refs,
3397dd7cddfSDavid du Colombier &pcie->caches_defg.DecodeDEFG[0],
3407dd7cddfSDavid du Colombier pcie, imem, "Decode.DEFG")) < 0 ||
3417dd7cddfSDavid du Colombier (code = cache_abc_common(i_ctx_p, (gs_cie_abc *)pcie, &procs, pcie, imem)) < 0
3427dd7cddfSDavid du Colombier )
3437dd7cddfSDavid du Colombier DO_NOTHING;
3443ff48bf5SDavid du Colombier return cie_set_finish(i_ctx_p, pcs, &procs, edepth, code);
3457dd7cddfSDavid du Colombier }
3467dd7cddfSDavid du Colombier private int
cie_defg_finish(i_ctx_t * i_ctx_p)3477dd7cddfSDavid du Colombier cie_defg_finish(i_ctx_t *i_ctx_p)
3487dd7cddfSDavid du Colombier {
3497dd7cddfSDavid du Colombier os_ptr op = osp;
3507dd7cddfSDavid du Colombier gs_cie_defg *pcie = r_ptr(op, gs_cie_defg);
3517dd7cddfSDavid du Colombier
3527dd7cddfSDavid du Colombier pcie->DecodeDEFG = DecodeDEFG_from_cache;
353*593dc095SDavid du Colombier pcie->DecodeABC = DecodeABC_from_cache;
3547dd7cddfSDavid du Colombier pcie->common.DecodeLMN = DecodeLMN_from_cache;
3557dd7cddfSDavid du Colombier gs_cie_defg_complete(pcie);
3567dd7cddfSDavid du Colombier pop(1);
3577dd7cddfSDavid du Colombier return 0;
3587dd7cddfSDavid du Colombier }
3597dd7cddfSDavid du Colombier
3607dd7cddfSDavid du Colombier /* <dict> .setciedefspace - */
361*593dc095SDavid du Colombier private int cie_def_finish(i_ctx_t *);
3627dd7cddfSDavid du Colombier private int
zsetciedefspace(i_ctx_t * i_ctx_p)3637dd7cddfSDavid du Colombier zsetciedefspace(i_ctx_t *i_ctx_p)
3647dd7cddfSDavid du Colombier {
3657dd7cddfSDavid du Colombier os_ptr op = osp;
3667dd7cddfSDavid du Colombier int edepth = ref_stack_count(&e_stack);
3677dd7cddfSDavid du Colombier gs_memory_t *mem = gs_state_memory(igs);
3687dd7cddfSDavid du Colombier gs_ref_memory_t *imem = (gs_ref_memory_t *)mem;
3697dd7cddfSDavid du Colombier gs_color_space *pcs;
3707dd7cddfSDavid du Colombier ref_cie_procs procs;
3717dd7cddfSDavid du Colombier gs_cie_def *pcie;
3727dd7cddfSDavid du Colombier int code;
3737dd7cddfSDavid du Colombier ref *ptref;
3747dd7cddfSDavid du Colombier
3757dd7cddfSDavid du Colombier check_type(*op, t_dictionary);
3767dd7cddfSDavid du Colombier check_dict_read(*op);
3777dd7cddfSDavid du Colombier if ((code = dict_find_string(op, "Table", &ptref)) <= 0)
3787dd7cddfSDavid du Colombier return (code < 0 ? code : gs_note_error(e_rangecheck));
3797dd7cddfSDavid du Colombier check_read_type(*ptref, t_array);
3807dd7cddfSDavid du Colombier if (r_size(ptref) != 4)
3817dd7cddfSDavid du Colombier return_error(e_rangecheck);
3827dd7cddfSDavid du Colombier procs = istate->colorspace.procs.cie;
3837dd7cddfSDavid du Colombier code = gs_cspace_build_CIEDEF(&pcs, NULL, mem);
3847dd7cddfSDavid du Colombier if (code < 0)
3857dd7cddfSDavid du Colombier return code;
3867dd7cddfSDavid du Colombier pcie = pcs->params.def;
3877dd7cddfSDavid du Colombier pcie->Table.n = 3;
3887dd7cddfSDavid du Colombier pcie->Table.m = 3;
389*593dc095SDavid du Colombier if ((code = dict_range3_param(mem, op, "RangeDEF", &pcie->RangeDEF)) < 0 ||
390*593dc095SDavid du Colombier (code = dict_proc3_param(mem, op, "DecodeDEF", &procs.PreDecode.DEF)) < 0 ||
391*593dc095SDavid du Colombier (code = dict_range3_param(mem, op, "RangeHIJ", &pcie->RangeHIJ)) < 0 ||
3927dd7cddfSDavid du Colombier (code = cie_table_param(ptref, &pcie->Table, mem)) < 0 ||
393*593dc095SDavid du Colombier (code = cie_abc_param(imemory, op, (gs_cie_abc *) pcie, &procs)) < 0 ||
3947dd7cddfSDavid du Colombier (code = cie_cache_joint(i_ctx_p, &istate->colorrendering.procs, (gs_cie_common *)pcie, igs)) < 0 || /* do this last */
3957dd7cddfSDavid du Colombier (code = cie_cache_push_finish(i_ctx_p, cie_def_finish, imem, pcie)) < 0 ||
3967dd7cddfSDavid du Colombier (code = cie_prepare_cache3(i_ctx_p, &pcie->RangeDEF,
3977dd7cddfSDavid du Colombier procs.PreDecode.DEF.value.const_refs,
3987dd7cddfSDavid du Colombier &pcie->caches_def.DecodeDEF[0],
3997dd7cddfSDavid du Colombier pcie, imem, "Decode.DEF")) < 0 ||
4007dd7cddfSDavid du Colombier (code = cache_abc_common(i_ctx_p, (gs_cie_abc *)pcie, &procs, pcie, imem)) < 0
4017dd7cddfSDavid du Colombier )
4027dd7cddfSDavid du Colombier DO_NOTHING;
4033ff48bf5SDavid du Colombier return cie_set_finish(i_ctx_p, pcs, &procs, edepth, code);
4047dd7cddfSDavid du Colombier }
4057dd7cddfSDavid du Colombier private int
cie_def_finish(i_ctx_t * i_ctx_p)4067dd7cddfSDavid du Colombier cie_def_finish(i_ctx_t *i_ctx_p)
4077dd7cddfSDavid du Colombier {
4087dd7cddfSDavid du Colombier os_ptr op = osp;
4097dd7cddfSDavid du Colombier gs_cie_def *pcie = r_ptr(op, gs_cie_def);
4107dd7cddfSDavid du Colombier
4117dd7cddfSDavid du Colombier pcie->DecodeDEF = DecodeDEF_from_cache;
412*593dc095SDavid du Colombier pcie->DecodeABC = DecodeABC_from_cache;
4137dd7cddfSDavid du Colombier pcie->common.DecodeLMN = DecodeLMN_from_cache;
4147dd7cddfSDavid du Colombier gs_cie_def_complete(pcie);
4157dd7cddfSDavid du Colombier pop(1);
4167dd7cddfSDavid du Colombier return 0;
4177dd7cddfSDavid du Colombier }
4187dd7cddfSDavid du Colombier
4197dd7cddfSDavid du Colombier /* <dict> .setcieabcspace - */
420*593dc095SDavid du Colombier private int cie_abc_finish(i_ctx_t *);
4217dd7cddfSDavid du Colombier private int
zsetcieabcspace(i_ctx_t * i_ctx_p)4227dd7cddfSDavid du Colombier zsetcieabcspace(i_ctx_t *i_ctx_p)
4237dd7cddfSDavid du Colombier {
4247dd7cddfSDavid du Colombier os_ptr op = osp;
4257dd7cddfSDavid du Colombier int edepth = ref_stack_count(&e_stack);
4267dd7cddfSDavid du Colombier gs_memory_t *mem = gs_state_memory(igs);
4277dd7cddfSDavid du Colombier gs_ref_memory_t *imem = (gs_ref_memory_t *)mem;
4287dd7cddfSDavid du Colombier gs_color_space *pcs;
4297dd7cddfSDavid du Colombier ref_cie_procs procs;
4307dd7cddfSDavid du Colombier gs_cie_abc *pcie;
4317dd7cddfSDavid du Colombier int code;
4327dd7cddfSDavid du Colombier
4337dd7cddfSDavid du Colombier check_type(*op, t_dictionary);
4347dd7cddfSDavid du Colombier check_dict_read(*op);
4357dd7cddfSDavid du Colombier procs = istate->colorspace.procs.cie;
4367dd7cddfSDavid du Colombier code = gs_cspace_build_CIEABC(&pcs, NULL, mem);
4377dd7cddfSDavid du Colombier if (code < 0)
4387dd7cddfSDavid du Colombier return code;
4397dd7cddfSDavid du Colombier pcie = pcs->params.abc;
440*593dc095SDavid du Colombier code = cie_abc_param(imemory, op, pcie, &procs);
4417dd7cddfSDavid du Colombier if (code < 0 ||
4427dd7cddfSDavid du Colombier (code = cie_cache_joint(i_ctx_p, &istate->colorrendering.procs, (gs_cie_common *)pcie, igs)) < 0 || /* do this last */
4437dd7cddfSDavid du Colombier (code = cie_cache_push_finish(i_ctx_p, cie_abc_finish, imem, pcie)) < 0 ||
4447dd7cddfSDavid du Colombier (code = cache_abc_common(i_ctx_p, pcie, &procs, pcie, imem)) < 0
4457dd7cddfSDavid du Colombier )
4467dd7cddfSDavid du Colombier DO_NOTHING;
4473ff48bf5SDavid du Colombier return cie_set_finish(i_ctx_p, pcs, &procs, edepth, code);
4487dd7cddfSDavid du Colombier }
4497dd7cddfSDavid du Colombier private int
cie_abc_finish(i_ctx_t * i_ctx_p)4507dd7cddfSDavid du Colombier cie_abc_finish(i_ctx_t *i_ctx_p)
4517dd7cddfSDavid du Colombier {
4527dd7cddfSDavid du Colombier os_ptr op = osp;
4537dd7cddfSDavid du Colombier gs_cie_abc *pcie = r_ptr(op, gs_cie_abc);
4547dd7cddfSDavid du Colombier
4557dd7cddfSDavid du Colombier pcie->DecodeABC = DecodeABC_from_cache;
4567dd7cddfSDavid du Colombier pcie->common.DecodeLMN = DecodeLMN_from_cache;
4577dd7cddfSDavid du Colombier gs_cie_abc_complete(pcie);
4587dd7cddfSDavid du Colombier pop(1);
4597dd7cddfSDavid du Colombier return 0;
4607dd7cddfSDavid du Colombier }
4617dd7cddfSDavid du Colombier
4627dd7cddfSDavid du Colombier /* <dict> .setcieaspace - */
463*593dc095SDavid du Colombier private int cie_a_finish(i_ctx_t *);
4647dd7cddfSDavid du Colombier private int
zsetcieaspace(i_ctx_t * i_ctx_p)4657dd7cddfSDavid du Colombier zsetcieaspace(i_ctx_t *i_ctx_p)
4667dd7cddfSDavid du Colombier {
4677dd7cddfSDavid du Colombier os_ptr op = osp;
4687dd7cddfSDavid du Colombier int edepth = ref_stack_count(&e_stack);
4697dd7cddfSDavid du Colombier gs_memory_t *mem = gs_state_memory(igs);
4707dd7cddfSDavid du Colombier gs_ref_memory_t *imem = (gs_ref_memory_t *)mem;
4717dd7cddfSDavid du Colombier gs_color_space *pcs;
4727dd7cddfSDavid du Colombier ref_cie_procs procs;
4737dd7cddfSDavid du Colombier gs_cie_a *pcie;
4747dd7cddfSDavid du Colombier int code;
4757dd7cddfSDavid du Colombier
4767dd7cddfSDavid du Colombier check_type(*op, t_dictionary);
4777dd7cddfSDavid du Colombier check_dict_read(*op);
4787dd7cddfSDavid du Colombier procs = istate->colorspace.procs.cie;
4797dd7cddfSDavid du Colombier if ((code = dict_proc_param(op, "DecodeA", &procs.Decode.A, true)) < 0)
4807dd7cddfSDavid du Colombier return code;
4817dd7cddfSDavid du Colombier code = gs_cspace_build_CIEA(&pcs, NULL, mem);
4827dd7cddfSDavid du Colombier if (code < 0)
4837dd7cddfSDavid du Colombier return code;
4847dd7cddfSDavid du Colombier pcie = pcs->params.a;
485*593dc095SDavid du Colombier if ((code = dict_floats_param(imemory, op, "RangeA", 2, (float *)&pcie->RangeA, (const float *)&RangeA_default)) < 0 ||
486*593dc095SDavid du Colombier (code = dict_floats_param(imemory, op, "MatrixA", 3, (float *)&pcie->MatrixA, (const float *)&MatrixA_default)) < 0 ||
487*593dc095SDavid du Colombier (code = cie_lmnp_param(imemory, op, &pcie->common, &procs)) < 0 ||
4887dd7cddfSDavid du Colombier (code = cie_cache_joint(i_ctx_p, &istate->colorrendering.procs, (gs_cie_common *)pcie, igs)) < 0 || /* do this last */
4897dd7cddfSDavid du Colombier (code = cie_cache_push_finish(i_ctx_p, cie_a_finish, imem, pcie)) < 0 ||
4907dd7cddfSDavid du Colombier (code = cie_prepare_cache(i_ctx_p, &pcie->RangeA, &procs.Decode.A, &pcie->caches.DecodeA.floats, pcie, imem, "Decode.A")) < 0 ||
4917dd7cddfSDavid du Colombier (code = cache_common(i_ctx_p, &pcie->common, &procs, pcie, imem)) < 0
4927dd7cddfSDavid du Colombier )
4937dd7cddfSDavid du Colombier DO_NOTHING;
4947dd7cddfSDavid du Colombier pcie->DecodeA = DecodeA_default;
4953ff48bf5SDavid du Colombier return cie_set_finish(i_ctx_p, pcs, &procs, edepth, code);
4967dd7cddfSDavid du Colombier }
4977dd7cddfSDavid du Colombier private int
cie_a_finish(i_ctx_t * i_ctx_p)4987dd7cddfSDavid du Colombier cie_a_finish(i_ctx_t *i_ctx_p)
4997dd7cddfSDavid du Colombier {
5007dd7cddfSDavid du Colombier os_ptr op = osp;
5017dd7cddfSDavid du Colombier gs_cie_a *pcie = r_ptr(op, gs_cie_a);
5027dd7cddfSDavid du Colombier
5037dd7cddfSDavid du Colombier pcie->DecodeA = DecodeA_from_cache;
5047dd7cddfSDavid du Colombier pcie->common.DecodeLMN = DecodeLMN_from_cache;
5057dd7cddfSDavid du Colombier gs_cie_a_complete(pcie);
5067dd7cddfSDavid du Colombier pop(1);
5077dd7cddfSDavid du Colombier return 0;
5087dd7cddfSDavid du Colombier }
5097dd7cddfSDavid du Colombier
5107dd7cddfSDavid du Colombier /* Common cache code */
5117dd7cddfSDavid du Colombier
5127dd7cddfSDavid du Colombier private int
cache_abc_common(i_ctx_t * i_ctx_p,gs_cie_abc * pcie,const ref_cie_procs * pcprocs,void * container,gs_ref_memory_t * imem)5137dd7cddfSDavid du Colombier cache_abc_common(i_ctx_t *i_ctx_p, gs_cie_abc * pcie,
5147dd7cddfSDavid du Colombier const ref_cie_procs * pcprocs,
5157dd7cddfSDavid du Colombier void *container, gs_ref_memory_t * imem)
5167dd7cddfSDavid du Colombier {
5177dd7cddfSDavid du Colombier int code =
5187dd7cddfSDavid du Colombier cie_prepare_cache3(i_ctx_p, &pcie->RangeABC,
5197dd7cddfSDavid du Colombier pcprocs->Decode.ABC.value.const_refs,
520*593dc095SDavid du Colombier pcie->caches.DecodeABC.caches, pcie, imem,
5217dd7cddfSDavid du Colombier "Decode.ABC");
5227dd7cddfSDavid du Colombier
5237dd7cddfSDavid du Colombier return (code < 0 ? code :
5247dd7cddfSDavid du Colombier cache_common(i_ctx_p, &pcie->common, pcprocs, pcie, imem));
5257dd7cddfSDavid du Colombier }
5267dd7cddfSDavid du Colombier
5277dd7cddfSDavid du Colombier private int
cache_common(i_ctx_t * i_ctx_p,gs_cie_common * pcie,const ref_cie_procs * pcprocs,void * container,gs_ref_memory_t * imem)5287dd7cddfSDavid du Colombier cache_common(i_ctx_t *i_ctx_p, gs_cie_common * pcie,
5297dd7cddfSDavid du Colombier const ref_cie_procs * pcprocs,
5307dd7cddfSDavid du Colombier void *container, gs_ref_memory_t * imem)
5317dd7cddfSDavid du Colombier {
5327dd7cddfSDavid du Colombier return cie_prepare_cache3(i_ctx_p, &pcie->RangeLMN,
5337dd7cddfSDavid du Colombier pcprocs->DecodeLMN.value.const_refs,
5347dd7cddfSDavid du Colombier &pcie->caches.DecodeLMN[0], container, imem,
5357dd7cddfSDavid du Colombier "Decode.LMN");
5367dd7cddfSDavid du Colombier }
5377dd7cddfSDavid du Colombier
5387dd7cddfSDavid du Colombier /* ------ Internal routines ------ */
5397dd7cddfSDavid du Colombier
5407dd7cddfSDavid du Colombier /* Prepare to cache the values for one or more procedures. */
541*593dc095SDavid du Colombier private int cie_cache_finish1(i_ctx_t *);
542*593dc095SDavid du Colombier private int cie_cache_finish(i_ctx_t *);
5437dd7cddfSDavid du Colombier int
cie_prepare_cache(i_ctx_t * i_ctx_p,const gs_range * domain,const ref * proc,cie_cache_floats * pcache,void * container,gs_ref_memory_t * imem,client_name_t cname)5447dd7cddfSDavid du Colombier cie_prepare_cache(i_ctx_t *i_ctx_p, const gs_range * domain, const ref * proc,
5457dd7cddfSDavid du Colombier cie_cache_floats * pcache, void *container,
5467dd7cddfSDavid du Colombier gs_ref_memory_t * imem, client_name_t cname)
5477dd7cddfSDavid du Colombier {
5487dd7cddfSDavid du Colombier int space = imemory_space(imem);
549*593dc095SDavid du Colombier gs_sample_loop_params_t lp;
5507dd7cddfSDavid du Colombier es_ptr ep;
5517dd7cddfSDavid du Colombier
552*593dc095SDavid du Colombier gs_cie_cache_init(&pcache->params, &lp, domain, cname);
5537dd7cddfSDavid du Colombier pcache->params.is_identity = r_size(proc) == 0;
5547dd7cddfSDavid du Colombier check_estack(9);
5557dd7cddfSDavid du Colombier ep = esp;
556*593dc095SDavid du Colombier make_real(ep + 9, lp.A);
557*593dc095SDavid du Colombier make_int(ep + 8, lp.N);
558*593dc095SDavid du Colombier make_real(ep + 7, lp.B);
5597dd7cddfSDavid du Colombier ep[6] = *proc;
5607dd7cddfSDavid du Colombier r_clear_attrs(ep + 6, a_executable);
5617dd7cddfSDavid du Colombier make_op_estack(ep + 5, zcvx);
562*593dc095SDavid du Colombier make_op_estack(ep + 4, zfor_samples);
5637dd7cddfSDavid du Colombier make_op_estack(ep + 3, cie_cache_finish);
5647dd7cddfSDavid du Colombier esp += 9;
5657dd7cddfSDavid du Colombier /*
5667dd7cddfSDavid du Colombier * The caches are embedded in the middle of other
5677dd7cddfSDavid du Colombier * structures, so we represent the pointer to the cache
5687dd7cddfSDavid du Colombier * as a pointer to the container plus an offset.
5697dd7cddfSDavid du Colombier */
5707dd7cddfSDavid du Colombier make_int(ep + 2, (char *)pcache - (char *)container);
5717dd7cddfSDavid du Colombier make_struct(ep + 1, space, container);
5727dd7cddfSDavid du Colombier return o_push_estack;
5737dd7cddfSDavid du Colombier }
5747dd7cddfSDavid du Colombier /* Note that pc3 may be 0, indicating that there are only 3 caches to load. */
5757dd7cddfSDavid du Colombier int
cie_prepare_caches_4(i_ctx_t * i_ctx_p,const gs_range * domains,const ref * procs,cie_cache_floats * pc0,cie_cache_floats * pc1,cie_cache_floats * pc2,cie_cache_floats * pc3,void * container,gs_ref_memory_t * imem,client_name_t cname)5767dd7cddfSDavid du Colombier cie_prepare_caches_4(i_ctx_t *i_ctx_p, const gs_range * domains,
5777dd7cddfSDavid du Colombier const ref * procs,
5787dd7cddfSDavid du Colombier cie_cache_floats * pc0, cie_cache_floats * pc1,
5797dd7cddfSDavid du Colombier cie_cache_floats * pc2, cie_cache_floats * pc3,
5807dd7cddfSDavid du Colombier void *container,
5817dd7cddfSDavid du Colombier gs_ref_memory_t * imem, client_name_t cname)
5827dd7cddfSDavid du Colombier {
5837dd7cddfSDavid du Colombier cie_cache_floats *pcn[4];
5847dd7cddfSDavid du Colombier int i, n, code = 0;
5857dd7cddfSDavid du Colombier
5867dd7cddfSDavid du Colombier pcn[0] = pc0, pcn[1] = pc1, pcn[2] = pc2;
5877dd7cddfSDavid du Colombier if (pc3 == 0)
5887dd7cddfSDavid du Colombier n = 3;
5897dd7cddfSDavid du Colombier else
5907dd7cddfSDavid du Colombier pcn[3] = pc3, n = 4;
5917dd7cddfSDavid du Colombier for (i = 0; i < n && code >= 0; ++i)
5927dd7cddfSDavid du Colombier code = cie_prepare_cache(i_ctx_p, domains + i, procs + i, pcn[i],
5937dd7cddfSDavid du Colombier container, imem, cname);
5947dd7cddfSDavid du Colombier return code;
5957dd7cddfSDavid du Colombier }
5967dd7cddfSDavid du Colombier
5977dd7cddfSDavid du Colombier /* Store the result of caching one procedure. */
5987dd7cddfSDavid du Colombier private int
cie_cache_finish_store(i_ctx_t * i_ctx_p,bool replicate)5997dd7cddfSDavid du Colombier cie_cache_finish_store(i_ctx_t *i_ctx_p, bool replicate)
6007dd7cddfSDavid du Colombier {
6017dd7cddfSDavid du Colombier os_ptr op = osp;
6027dd7cddfSDavid du Colombier cie_cache_floats *pcache;
6037dd7cddfSDavid du Colombier int code;
6047dd7cddfSDavid du Colombier
6057dd7cddfSDavid du Colombier check_esp(2);
6067dd7cddfSDavid du Colombier /* See above for the container + offset representation of */
6077dd7cddfSDavid du Colombier /* the pointer to the cache. */
6087dd7cddfSDavid du Colombier pcache = (cie_cache_floats *) (r_ptr(esp - 1, char) + esp->value.intval);
6097dd7cddfSDavid du Colombier
6107dd7cddfSDavid du Colombier pcache->params.is_identity = false; /* cache_set_linear computes this */
6117dd7cddfSDavid du Colombier if_debug3('c', "[c]cache 0x%lx base=%g, factor=%g:\n",
6127dd7cddfSDavid du Colombier (ulong) pcache, pcache->params.base, pcache->params.factor);
6137dd7cddfSDavid du Colombier if (replicate ||
6147dd7cddfSDavid du Colombier (code = float_params(op, gx_cie_cache_size, &pcache->values[0])) < 0
6157dd7cddfSDavid du Colombier ) {
6167dd7cddfSDavid du Colombier /* We might have underflowed the current stack block. */
6177dd7cddfSDavid du Colombier /* Handle the parameters one-by-one. */
6187dd7cddfSDavid du Colombier uint i;
6197dd7cddfSDavid du Colombier
6207dd7cddfSDavid du Colombier for (i = 0; i < gx_cie_cache_size; i++) {
6217dd7cddfSDavid du Colombier code = float_param(ref_stack_index(&o_stack,
6227dd7cddfSDavid du Colombier (replicate ? 0 : gx_cie_cache_size - 1 - i)),
6237dd7cddfSDavid du Colombier &pcache->values[i]);
6247dd7cddfSDavid du Colombier if (code < 0)
6257dd7cddfSDavid du Colombier return code;
6267dd7cddfSDavid du Colombier }
6277dd7cddfSDavid du Colombier }
6287dd7cddfSDavid du Colombier #ifdef DEBUG
6297dd7cddfSDavid du Colombier if (gs_debug_c('c')) {
6307dd7cddfSDavid du Colombier int i;
6317dd7cddfSDavid du Colombier
6327dd7cddfSDavid du Colombier for (i = 0; i < gx_cie_cache_size; i += 4)
6337dd7cddfSDavid du Colombier dlprintf5("[c] cache[%3d]=%g, %g, %g, %g\n", i,
6347dd7cddfSDavid du Colombier pcache->values[i], pcache->values[i + 1],
6357dd7cddfSDavid du Colombier pcache->values[i + 2], pcache->values[i + 3]);
6367dd7cddfSDavid du Colombier }
6377dd7cddfSDavid du Colombier #endif
6387dd7cddfSDavid du Colombier ref_stack_pop(&o_stack, (replicate ? 1 : gx_cie_cache_size));
6397dd7cddfSDavid du Colombier esp -= 2; /* pop pointer to cache */
6407dd7cddfSDavid du Colombier return o_pop_estack;
6417dd7cddfSDavid du Colombier }
6427dd7cddfSDavid du Colombier private int
cie_cache_finish(i_ctx_t * i_ctx_p)6437dd7cddfSDavid du Colombier cie_cache_finish(i_ctx_t *i_ctx_p)
6447dd7cddfSDavid du Colombier {
6457dd7cddfSDavid du Colombier return cie_cache_finish_store(i_ctx_p, false);
6467dd7cddfSDavid du Colombier }
6477dd7cddfSDavid du Colombier private int
cie_cache_finish1(i_ctx_t * i_ctx_p)6487dd7cddfSDavid du Colombier cie_cache_finish1(i_ctx_t *i_ctx_p)
6497dd7cddfSDavid du Colombier {
6507dd7cddfSDavid du Colombier return cie_cache_finish_store(i_ctx_p, true);
6517dd7cddfSDavid du Colombier }
6527dd7cddfSDavid du Colombier
6537dd7cddfSDavid du Colombier /* Push a finishing procedure on the e-stack. */
6547dd7cddfSDavid du Colombier /* ptr will be the top element of the o-stack. */
6557dd7cddfSDavid du Colombier int
cie_cache_push_finish(i_ctx_t * i_ctx_p,op_proc_t finish_proc,gs_ref_memory_t * imem,void * data)6567dd7cddfSDavid du Colombier cie_cache_push_finish(i_ctx_t *i_ctx_p, op_proc_t finish_proc,
6577dd7cddfSDavid du Colombier gs_ref_memory_t * imem, void *data)
6587dd7cddfSDavid du Colombier {
6597dd7cddfSDavid du Colombier check_estack(2);
6607dd7cddfSDavid du Colombier push_op_estack(finish_proc);
6617dd7cddfSDavid du Colombier ++esp;
6627dd7cddfSDavid du Colombier make_struct(esp, imemory_space(imem), data);
6637dd7cddfSDavid du Colombier return o_push_estack;
6647dd7cddfSDavid du Colombier }
6657dd7cddfSDavid du Colombier
6667dd7cddfSDavid du Colombier /* ------ Initialization procedure ------ */
6677dd7cddfSDavid du Colombier
6687dd7cddfSDavid du Colombier const op_def zcie_l2_op_defs[] =
6697dd7cddfSDavid du Colombier {
6707dd7cddfSDavid du Colombier op_def_begin_level2(),
6717dd7cddfSDavid du Colombier {"1.setcieaspace", zsetcieaspace},
6727dd7cddfSDavid du Colombier {"1.setcieabcspace", zsetcieabcspace},
6737dd7cddfSDavid du Colombier {"1.setciedefspace", zsetciedefspace},
6747dd7cddfSDavid du Colombier {"1.setciedefgspace", zsetciedefgspace},
6757dd7cddfSDavid du Colombier /* Internal operators */
6767dd7cddfSDavid du Colombier {"1%cie_defg_finish", cie_defg_finish},
6777dd7cddfSDavid du Colombier {"1%cie_def_finish", cie_def_finish},
6787dd7cddfSDavid du Colombier {"1%cie_abc_finish", cie_abc_finish},
6797dd7cddfSDavid du Colombier {"1%cie_a_finish", cie_a_finish},
6807dd7cddfSDavid du Colombier {"0%cie_cache_finish", cie_cache_finish},
6817dd7cddfSDavid du Colombier {"1%cie_cache_finish1", cie_cache_finish1},
6827dd7cddfSDavid du Colombier op_def_end(0)
6837dd7cddfSDavid du Colombier };
684