/* Free the parameters of an Exponential Interpolation function. */ void gs_function_ElIn_free_params(gs_function_ElIn_params_t * params, gs_memory_t * mem) { gs_free_const_object(mem, params->C1, "C1"); gs_free_const_object(mem, params->C0, "C0"); fn_common_free_params((gs_function_params_t *) params, mem); }
/* Free the parameters of a 1-Input Stitching function. */ void gs_function_1ItSg_free_params(gs_function_1ItSg_params_t * params, gs_memory_t * mem) { gs_free_const_object(mem, params->Encode, "Encode"); gs_free_const_object(mem, params->Bounds, "Bounds"); fn_free_functions(params->Functions, params->k, mem); fn_common_free_params((gs_function_params_t *) params, mem); }
/* * Restore state after finishing, or unwinding from an error within, a show * operation. Note that we assume op == osp, and may reset osp. */ static int op_show_restore(i_ctx_t *i_ctx_p, bool for_error) { register es_ptr ep = esp + snumpush; gs_text_enum_t *penum = esenum(ep); int saved_level = esgslevel(ep).value.intval; int code = 0; if (for_error) { #if 0 /* Disabled for CPSI compatibility for 13-12-4. CPSI doesn't remove cshow, kshow proc operands. */ uint saved_count = esodepth(ep).value.intval; uint count = ref_stack_count(&o_stack); if (count > saved_count) /* if <, we're in trouble */ ref_stack_pop(&o_stack, count - saved_count); #endif if (ep[1].value.opproc == op_show_continue && penum->enum_client_data != NULL) { /* Replace the continuation operaton on estack with the right operator : */ op_proc_t proc; *(void **)&proc = penum->enum_client_data; make_op_estack(ep + 1, proc); } } if (SHOW_IS_STRINGWIDTH(penum) && igs->text_rendering_mode != 3) { /* stringwidth does an extra gsave */ --saved_level; } if (penum->text.operation & TEXT_REPLACE_WIDTHS) { gs_free_const_object(penum->memory, penum->text.y_widths, "y_widths"); if (penum->text.x_widths != penum->text.y_widths) gs_free_const_object(penum->memory, penum->text.x_widths, "x_widths"); } /* * We might have been inside a cshow, in which case currentfont was * reset temporarily, as though we were inside a BuildChar/ BuildGlyph * procedure. To handle this case, set currentfont back to its original * state. NOTE: this code previously used fstack[0] in the enumerator * for the root font: we aren't sure that this change is correct. */ gs_set_currentfont(igs, penum->orig_font); while (igs->level > saved_level && code >= 0) { if (igs->saved == 0 || igs->saved->saved == 0) { /* * Bad news: we got an error inside a save inside a BuildChar or * BuildGlyph. Don't attempt to recover. */ code = gs_note_error(e_Fatal); } else code = gs_grestore(igs); } gs_text_release(penum, "op_show_restore"); return code; }
/* * Free an array of subsidiary Functions. Note that this may be called * before the Functions array has been fully initialized. Note also that * its argument conforms to the Functions array in the parameter structure, * but it (necessarily) deconstifies it. */ static void fn_free_functions(const gs_function_t *const * Functions, int count, gs_memory_t * mem) { int i; for (i = count; --i >= 0;) if (Functions[i]) gs_function_free((gs_function_t *)Functions[i], true, mem); gs_free_const_object(mem, Functions, "Functions"); }
/* * Finalization for devices: do any special finalization first, then * close the device if it is open, and finally free the structure * descriptor if it is dynamic. */ void gx_device_finalize(void *vptr) { gx_device * const dev = (gx_device *)vptr; if (dev->finalize) dev->finalize(dev); discard(gs_closedevice(dev)); if (dev->stype_is_dynamic) gs_free_const_object(dev->memory->non_gc_memory, dev->stype, "gx_device_finalize"); }
/* * Finalization for devices: do any special finalization first, then * close the device if it is open, and finally free the structure * descriptor if it is dynamic. */ void gx_device_finalize(const gs_memory_t *cmem, void *vptr) { gx_device * const dev = (gx_device *)vptr; (void)cmem; /* unused */ if (dev->icc_struct != NULL) { rc_decrement(dev->icc_struct, "gx_device_finalize(icc_profile)"); } if (dev->finalize) dev->finalize(dev); discard(gs_closedevice(dev)); if (dev->stype_is_dynamic) gs_free_const_object(dev->memory->non_gc_memory, dev->stype, "gx_device_finalize"); }
/* Generic free_params implementation. */ void fn_common_free_params(gs_function_params_t * params, gs_memory_t * mem) { gs_free_const_object(mem, params->Range, "Range"); gs_free_const_object(mem, params->Domain, "Domain"); }
int fn_build_sub_function(i_ctx_t *i_ctx_p, const ref * op, gs_function_t ** ppfn, int depth, gs_memory_t *mem, const float *shading_domain, const int num_inputs) { int j, code, type; uint i; gs_function_params_t params; if (depth > MAX_SUB_FUNCTION_DEPTH) return_error(gs_error_limitcheck); check_type(*op, t_dictionary); code = dict_int_param(op, "FunctionType", 0, max_int, -1, &type); if (code < 0) return code; for (i = 0; i < build_function_type_table_count; ++i) if (build_function_type_table[i].type == type) break; if (i == build_function_type_table_count) return_error(gs_error_rangecheck); /* Collect parameters common to all function types. */ params.Domain = 0; params.Range = 0; code = fn_build_float_array(op, "Domain", true, true, ¶ms.Domain, mem); if (code < 0) { gs_errorinfo_put_pair_from_dict(i_ctx_p, op, "Domain"); goto fail; } params.m = code >> 1; for (j = 0; j < params.m << 1; j += 2) { if (params.Domain[j] >= params.Domain[j + 1]) { code = gs_note_error(gs_error_rangecheck); gs_errorinfo_put_pair_from_dict(i_ctx_p, op, "Domain"); goto fail; } } if (shading_domain) { /* Each function dictionary's domain must be a superset of that of * the shading dictionary. PLRM3 p.265. CET 12-14c. We do this check * here because Adobe checks Domain before checking other parameters. */ if (num_inputs != params.m) code = gs_note_error(gs_error_rangecheck); for (j = 0; j < 2*num_inputs && code >= 0; j += 2) { if (params.Domain[j] > shading_domain[j] || params.Domain[j+1] < shading_domain[j+1] ) { code = gs_note_error(gs_error_rangecheck); } } if (code < 0) { gs_errorinfo_put_pair_from_dict(i_ctx_p, op, "Domain"); goto fail; } } code = fn_build_float_array(op, "Range", false, true, ¶ms.Range, mem); if (code < 0) goto fail; params.n = code >> 1; /* Finish building the function. */ /* If this fails, it will free all the parameters. */ return (*build_function_type_table[i].proc) (i_ctx_p, op, ¶ms, depth + 1, ppfn, mem); fail: gs_free_const_object(mem, params.Range, "Range"); gs_free_const_object(mem, params.Domain, "Domain"); return code; }
int make_sampled_function(i_ctx_t * i_ctx_p, ref *arr, ref *pproc, gs_function_t **func) { int code = 0, *ptr, i, total_size, num_components, CIESubst; byte * bytes = 0; float *fptr; gs_function_t *pfn = *func; gs_function_Sd_params_t params = {0}; ref alternatespace, *palternatespace = &alternatespace; PS_colour_space_t *space, *altspace; code = get_space_object(i_ctx_p, arr, &space); if (code < 0) return code; if (!space->alternateproc) return e_typecheck; code = space->alternateproc(i_ctx_p, arr, &palternatespace, &CIESubst); if (code < 0) return code; code = get_space_object(i_ctx_p, palternatespace, &altspace); if (code < 0) return code; /* * Set up the hyper cube function data structure. */ params.Order = 3; params.BitsPerSample = 16; code = space->numcomponents(i_ctx_p, arr, &num_components); if (code < 0) return code; fptr = (float *)gs_alloc_byte_array(imemory, num_components * 2, sizeof(float), "make_sampled_function(Domain)"); if (!fptr) return e_VMerror; code = space->domain(i_ctx_p, arr, fptr); if (code < 0) { gs_free_const_object(imemory, fptr, "make_sampled_function(Domain)"); return code; } params.Domain = fptr; params.m = num_components; code = altspace->numcomponents(i_ctx_p, palternatespace, &num_components); if (code < 0) { gs_free_const_object(imemory, params.Domain, "make_type4_function(Domain)"); return code; } fptr = (float *)gs_alloc_byte_array(imemory, num_components * 2, sizeof(float), "make_sampled_function(Range)"); if (!fptr) { gs_free_const_object(imemory, params.Domain, "make_sampled_function(Domain)"); return e_VMerror; } code = altspace->range(i_ctx_p, palternatespace, fptr); if (code < 0) { gs_free_const_object(imemory, params.Domain, "make_sampled_function(Domain)"); gs_free_const_object(imemory, fptr, "make_sampled_function(Range)"); return code; } params.Range = fptr; params.n = num_components; /* * The Size array may or not be specified. If it is not specified then * we need to determine a set of default values for the Size array. */ ptr = (int *)gs_alloc_byte_array(imemory, params.m, sizeof(int), "Size"); if (ptr == NULL) { code = gs_note_error(e_VMerror); goto fail; } params.Size = ptr; /* * Determine a default * set of values. */ code = determine_sampled_data_size(params.m, params.n, params.BitsPerSample, (int *)params.Size); if (code < 0) goto fail; /* * Determine space required for the sample data storage. */ total_size = params.n * bits2bytes(params.BitsPerSample); for (i = 0; i < params.m; i++) total_size *= params.Size[i]; /* * Allocate space for the data cube itself. */ bytes = gs_alloc_byte_array(imemory, total_size, 1, "cube_build_func0(bytes)"); if (!bytes) { code = gs_note_error(e_VMerror); goto fail; } data_source_init_bytes(¶ms.DataSource, (const unsigned char *)bytes, total_size); /* * This is temporary. We will call gs_function_Sd_init again after * we have collected the cube data. We are doing it now because we need * a function structure created (along with its GC enumeration stuff) * that we can use while collecting the cube data. We will call * the routine again after the cube data is collected to correctly * initialize the function. */ code = gs_function_Sd_init(&pfn, ¶ms, imemory); if (code < 0) return code; /* * Now setup to collect the sample data. */ return sampled_data_setup(i_ctx_p, pfn, pproc, sampled_data_finish, imemory); fail: gs_function_Sd_free_params(¶ms, imemory); return (code < 0 ? code : gs_note_error(e_rangecheck)); }