static int pdf_make_base_space_function(gx_device_pdf *pdev, gs_function_t **pfn, int ncomp, float *data_low, float *data_high) { gs_function_ElIn_params_t params; float *ptr1, *ptr2; int i, code; ptr1 = (float *) gs_alloc_byte_array(pdev->memory, 2, sizeof(float), "pdf_make_function(Domain)"); if (ptr1 == 0) { return gs_note_error(gs_error_VMerror); } ptr2 = (float *) gs_alloc_byte_array(pdev->memory, 2 * ncomp, sizeof(float), "pdf_make_function(Range)"); if (ptr2 == 0) { gs_free_object(pdev->memory, (void *)ptr1, "pdf_make_function(Range)"); return gs_note_error(gs_error_VMerror); } params.m = 1; params.n = ncomp; params.N = 1.0f; ptr1[0] = 0.0f; ptr1[1] = 1.0f; for (i=0; i<ncomp; i++) { ptr2[i*2] = 0.0f; ptr2[(i*2) + 1] = 1.0f; } params.Domain = ptr1; params.Range = ptr2; ptr1 = (float *)gs_alloc_byte_array(pdev->memory, ncomp, sizeof(float), "pdf_make_function(C0)"); if (ptr1 == 0) { gs_free_object(pdev->memory, (void *)params.Domain, "pdf_make_function(C0)"); gs_free_object(pdev->memory, (void *)params.Range, "pdf_make_function(C0)"); return gs_note_error(gs_error_VMerror); } ptr2 = (float *)gs_alloc_byte_array(pdev->memory, ncomp, sizeof(float), "pdf_make_function(C1)"); if (ptr2 == 0) { gs_free_object(pdev->memory, (void *)params.Domain, "pdf_make_function(C1)"); gs_free_object(pdev->memory, (void *)params.Range, "pdf_make_function(C1)"); gs_free_object(pdev->memory, (void *)ptr1, "pdf_make_function(C1)"); return gs_note_error(gs_error_VMerror); } for (i=0; i<ncomp; i++) { ptr1[i] = data_low[i]; ptr2[i] = data_high[i]; } params.C0 = ptr1; params.C1 = ptr2; code = gs_function_ElIn_init(pfn, ¶ms, pdev->memory); if (code < 0) { gs_free_object(pdev->memory, (void *)params.Domain, "pdf_make_function"); gs_free_object(pdev->memory, (void *)params.Range, "pdf_make_function"); gs_free_object(pdev->memory, (void *)params.C0, "pdf_make_function"); gs_free_object(pdev->memory, (void *)params.C1, "pdf_make_function"); } return code; }
/* the dictionary parameter for the BoundedHuffman filters. */ static int zcomputecodes(i_ctx_t *i_ctx_p) { os_ptr op = osp; os_ptr op1 = op - 1; uint asize; hc_definition def; ushort *data; long *freqs; int code = 0; check_type(*op, t_integer); check_write_type(*op1, t_array); asize = r_size(op1); if (op->value.intval < 1 || op->value.intval > max_hc_length) return_error(e_rangecheck); def.num_counts = op->value.intval; if (asize < def.num_counts + 2) return_error(e_rangecheck); def.num_values = asize - (def.num_counts + 1); data = (ushort *) gs_alloc_byte_array(imemory, asize, sizeof(ushort), "zcomputecodes"); freqs = (long *)gs_alloc_byte_array(imemory, def.num_values, sizeof(long), "zcomputecodes(freqs)"); if (data == 0 || freqs == 0) code = gs_note_error(e_VMerror); else { uint i; def.counts = data; def.values = data + (def.num_counts + 1); for (i = 0; i < def.num_values; i++) { const ref *pf = op1->value.const_refs + i + def.num_counts + 1; if (!r_has_type(pf, t_integer)) { code = gs_note_error(e_typecheck); break; } freqs[i] = pf->value.intval; } if (!code) { code = hc_compute(&def, freqs, imemory); if (code >= 0) { /* Copy back results. */ for (i = 0; i < asize; i++) make_int(op1->value.refs + i, data[i]); } } } gs_free_object(imemory, freqs, "zcomputecodes(freqs)"); gs_free_object(imemory, data, "zcomputecodes"); if (code < 0) return code; pop(1); return code; }
/* -------------------- public routines below ----------------- */ int pxJR3BeginImage(px_args_t * par, px_state_t * pxs) { int code = 0; if (!par->source.available) { px_vendor_state_t *v_state = gs_alloc_struct(pxs->memory, px_vendor_state_t, &st_px_vendor_state, "pxJR3BeginImage(vendor_state)"); byte *row; UINT16 *qvalues; if (v_state == 0) return_error(errorInsufficientMemory); if (par->pv[8]) { /* SourceWidth */ v_state->SourceWidth = par->pv[8]->value.i; v_state->data_per_row = par->pv[8]->value.i; v_state->color_space = pxs->pxgs->color_space; if (v_state->color_space != eGraySub) v_state->data_per_row *= 3; } v_state->state = vu_blank; v_state->rowwritten = 0; row = gs_alloc_byte_array(pxs->memory, 1, v_state->data_per_row, "pxJR3BeginImage(row)"); if (row == 0) return_error(errorInsufficientMemory); qvalues = (UINT16 *) gs_alloc_byte_array(pxs->memory, 192, sizeof(UINT16), "pxJR3BeginImage(qvalues)"); if (qvalues == 0) return_error(errorInsufficientMemory); pxs->vendor_state = v_state; pxs->vendor_state->row = row; pxs->vendor_state->qvalues = qvalues; pxs->vendor_state->qcount = 0; } if (par->pv[1]) { ulong len = par->pv[1]->value.i; /* zero or two payloads */ if (len) { code = vu_tag_dispatch(par, pxs); /* Multiple payloads, reset to read 2nd */ if (code == 0 && par->source.position < len) code = vu_tag_dispatch(par, pxs); } } return code; }
/* Finish building a FunctionType 0 (Sampled) function. */ int gs_build_function_0(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_Sd_params_t params; ref *pDataSource; int code; *(gs_function_params_t *) & params = *mnDR; params.Encode = 0; params.Decode = 0; params.Size = 0; if ((code = dict_find_string(op, "DataSource", &pDataSource)) <= 0) return (code < 0 ? code : gs_note_error(e_rangecheck)); switch (r_type(pDataSource)) { case t_string: data_source_init_string2(¶ms.DataSource, pDataSource->value.const_bytes, r_size(pDataSource)); break; case t_file: { stream *s; check_read_known_file_else(s, pDataSource, return_error, return_error(e_invalidfileaccess)); if (!(s->modes & s_mode_seek)) return_error(e_ioerror); data_source_init_stream(¶ms.DataSource, s); break; } default: return_error(e_rangecheck); } if ((code = dict_int_param(op, "Order", 1, 3, 1, ¶ms.Order)) < 0 || (code = dict_int_param(op, "BitsPerSample", 1, 32, 0, ¶ms.BitsPerSample)) < 0 || ((code = fn_build_float_array(op, "Encode", false, true, ¶ms.Encode, mem)) != 2 * params.m && (code != 0 || params.Encode != 0)) || ((code = fn_build_float_array(op, "Decode", false, true, ¶ms.Decode, mem)) != 2 * params.n && (code != 0 || params.Decode != 0)) ) { goto fail; } { int *ptr = (int *) gs_alloc_byte_array(mem, params.m, sizeof(int), "Size"); if (ptr == 0) { code = gs_note_error(e_VMerror); goto fail; } params.Size = ptr; code = dict_ints_param(op, "Size", params.m, ptr); if (code != params.m) goto fail; } code = gs_function_Sd_init(ppfn, ¶ms, mem); if (code >= 0) return 0; fail: gs_function_Sd_free_params(¶ms, mem); return (code < 0 ? code : gs_note_error(e_rangecheck)); }
/* * If necessary, scale the Range or Decode array for fn_make_scaled. * Note that we must always allocate a new array. */ int fn_scale_pairs(const float **ppvalues, const float *pvalues, int npairs, const gs_range_t *pranges, gs_memory_t *mem) { if (pvalues == 0) *ppvalues = 0; else { float *out = (float *) gs_alloc_byte_array(mem, 2 * npairs, sizeof(*pvalues), "fn_scale_pairs"); *ppvalues = out; if (out == 0) return_error(gs_error_VMerror); if (pranges) { /* Allocate and compute scaled ranges. */ int i; for (i = 0; i < npairs; ++i) { double base = pranges[i].rmin, factor = pranges[i].rmax - base; out[2 * i] = pvalues[2 * i] * factor + base; out[2 * i + 1] = pvalues[2 * i + 1] * factor + base; } } else memcpy(out, pvalues, 2 * sizeof(*pvalues) * npairs); } return 0; }
/* * Collect a heap-allocated array of floats. If the key is missing, set * *pparray = 0 and return 0; otherwise set *pparray and return the number * of elements. Note that 0-length arrays are acceptable, so if the value * returned is 0, the caller must check whether *pparray == 0. */ int fn_build_float_array(const ref * op, const char *kstr, bool required, bool even, const float **pparray, gs_memory_t *mem) { ref *par; int code; *pparray = 0; if (dict_find_string(op, kstr, &par) <= 0) return (required ? gs_note_error(gs_error_rangecheck) : 0); if (!r_is_array(par)) return_error(gs_error_typecheck); { uint size = r_size(par); float *ptr = (float *) gs_alloc_byte_array(mem, size, sizeof(float), kstr); if (ptr == 0) return_error(gs_error_VMerror); code = dict_float_array_check_param(mem, op, kstr, size, ptr, NULL, 0, gs_error_rangecheck); if (code < 0 || (even && (code & 1) != 0)) { gs_free_object(mem, ptr, kstr); return(code < 0 ? code : gs_note_error(gs_error_rangecheck)); } *pparray = ptr; } return code; }
static int ref_param_read_float_array(gs_param_list * plist, gs_param_name pkey, gs_param_float_array * pvalue) { iparam_list *const iplist = (iparam_list *) plist; iparam_loc loc; ref aref, elt; int code = ref_param_read_array(iplist, pkey, &loc); float *pfv; uint size; long i; if (code != 0) return code; size = r_size(loc.pvalue); pfv = (float *)gs_alloc_byte_array(plist->memory, size, sizeof(float), "ref_param_read_float_array"); if (pfv == 0) return_error(e_VMerror); aref = *loc.pvalue; loc.pvalue = &elt; for (i = 0; code >= 0 && i < size; i++) { array_get(plist->memory, &aref, i, &elt); code = float_param(&elt, pfv + i); } if (code < 0) { gs_free_object(plist->memory, pfv, "ref_read_float_array_param"); return (*loc.presult = code); } pvalue->data = pfv; pvalue->size = size; pvalue->persistent = true; return 0; }
void* _cmsCalloc(unsigned int nelts, unsigned int size) { void *ptr; ptr = gs_alloc_byte_array(gs_lib_ctx_get_non_gc_memory_t(), nelts, size, "lcms"); gs_warn2("lcms calloc (%d) at 0x%x",nelts*size,ptr); return ptr; }
/* Initialize the filter. */ static int s_ISpecialDownScale_init(stream_state * st) { stream_ISpecialDownScale_state *const ss = (stream_ISpecialDownScale_state *) st; gs_memory_t *mem = ss->memory; ss->sizeofPixelIn = ss->params.BitsPerComponentIn / 8; ss->sizeofPixelOut = ss->params.BitsPerComponentOut / 8; ss->src_size = ss->params.WidthIn * ss->sizeofPixelIn * ss->params.spp_interp; ss->dst_size = ss->params.WidthOut * ss->sizeofPixelOut * ss->params.spp_interp; /* Initialize destination DDAs. */ ss->dst_x = 0; ss->src_offset = ss->dst_offset = 0; dda_init(ss->dda_x, 0, ss->params.WidthIn, ss->params.WidthOut); ss->dda_x_init = ss->dda_x; ss->src_y = ss->dst_y = 0; dda_init(ss->dda_y, 0, ss->params.HeightOut, ss->params.HeightIn); /* create intermediate image to hold horizontal zoom */ ss->tmp = gs_alloc_byte_array(mem, ss->params.WidthOut * ss->params.spp_interp, ss->sizeofPixelIn, "image_scale tmp"); /* Allocate buffers for 1 row of source and destination. */ ss->dst = gs_alloc_byte_array(mem, ss->params.WidthOut * ss->params.spp_interp, ss->sizeofPixelOut, "image_scale dst"); ss->src = gs_alloc_byte_array(mem, ss->params.WidthIn * ss->params.spp_interp, ss->sizeofPixelIn, "image_scale src"); if (ss->tmp == 0 || ss->dst == 0 || ss->src == 0) { s_ISpecialDownScale_release(st); return ERRC; /****** WRONG ******/ } return 0; }
/* * Copy an array of numeric values when scaling a function. */ void * fn_copy_values(const void *pvalues, int count, int size, gs_memory_t *mem) { if (pvalues) { void *values = gs_alloc_byte_array(mem, count, size, "fn_copy_values"); if (values) memcpy(values, pvalues, count * size); return values; } else return 0; /* caller must check */ }
RELOC_PTRS_END /* ------ Public procedures ------ */ /* * Create a new DeviceN colorspace. */ int gs_cspace_new_DeviceN( gs_color_space **ppcs, uint num_components, gs_color_space *palt_cspace, gs_memory_t *pmem ) { gs_color_space *pcs; gs_device_n_params *pcsdevn; gs_separation_name *pnames; int code; if (palt_cspace == 0 || !palt_cspace->type->can_be_alt_space) return_error(gs_error_rangecheck); pcs = gs_cspace_alloc(pmem, &gs_color_space_type_DeviceN); if (pcs == NULL) return_error(gs_error_VMerror); pcsdevn = &pcs->params.device_n; pcsdevn->names = NULL; pcsdevn->map = NULL; pcsdevn->colorants = NULL; /* Allocate space for color names list. */ code = alloc_device_n_map(&pcsdevn->map, pmem, "gs_cspace_build_DeviceN"); if (code < 0) { gs_free_object(pmem, pcs, "gs_cspace_new_DeviceN"); return code; } /* Allocate space for color names list. */ pnames = (gs_separation_name *) gs_alloc_byte_array(pmem, num_components, sizeof(gs_separation_name), ".gs_cspace_build_DeviceN(names)"); if (pnames == 0) { gs_free_object(pmem, pcsdevn->map, ".gs_cspace_build_DeviceN(map)"); gs_free_object(pmem, pcs, "gs_cspace_new_DeviceN"); return_error(gs_error_VMerror); } pcs->base_space = palt_cspace; rc_increment_cs(palt_cspace); pcsdevn->names = pnames; pcsdevn->num_components = num_components; *ppcs = pcs; return 0; }
void* _cmsCalloc(unsigned int nelts, unsigned int size) { void *ptr; #if defined(SHARE_LCMS) && SHARE_LCMS==1 ptr = malloc(nelts * size); #else ptr = gs_alloc_byte_array(gs_lib_ctx_get_non_gc_memory_t(), nelts, size, "lcms"); #endif if (ptr != NULL) memset(ptr, 0, nelts * size); return ptr; }
gs_color_index_cache_t * gs_color_index_cache_create(gs_memory_t *memory, const gs_color_space *direct_space, gx_device *dev, gs_imager_state *pis, bool need_frac, gx_device *trans_dev) { int client_num_components = cs_num_components(direct_space); int device_num_components = trans_dev->color_info.num_components; gs_color_index_cache_elem_t *buf = ( gs_color_index_cache_elem_t *)gs_alloc_byte_array(memory, COLOR_INDEX_CACHE_SIZE, sizeof(gs_color_index_cache_elem_t), "gs_color_index_cache_create"); float *paint_values = (float *)gs_alloc_byte_array(memory, COLOR_INDEX_CACHE_SIZE * client_num_components, sizeof(float), "gs_color_index_cache_create"); frac31 *frac_values = (need_frac ? (frac31 *)gs_alloc_byte_array(memory, COLOR_INDEX_CACHE_SIZE * device_num_components, sizeof(frac31), "gs_color_index_cache_create") : NULL); gs_color_index_cache_t *pcic = gs_alloc_struct(memory, gs_color_index_cache_t, &st_color_index_cache, "gs_color_index_cache_create"); if (buf == NULL || paint_values == NULL || (need_frac && frac_values == NULL) || pcic == NULL) { gs_free_object(memory, buf, "gs_color_index_cache_create"); gs_free_object(memory, paint_values, "gs_color_index_cache_create"); gs_free_object(memory, frac_values, "gs_color_index_cache_create"); gs_free_object(memory, pcic, "gs_color_index_cache_create"); return NULL; } memset(pcic, 0, sizeof(*pcic)); memset(buf, 0, COLOR_INDEX_CACHE_SIZE * sizeof(gs_color_index_cache_elem_t)); pcic->direct_space = direct_space; pcic->pis = pis; pcic->dev = dev; pcic->trans_dev = trans_dev; pcic->device_num_components = device_num_components; pcic->client_num_components = client_num_components; pcic->memory = memory; pcic->used = 1; /* Never use the 0th element. */ pcic->buf = buf; pcic->recent_touch = MYNULL; pcic->paint_values = paint_values; pcic->frac_values = frac_values; return pcic; }
static int ref_param_read_string_array(gs_param_list * plist, gs_param_name pkey, gs_param_string_array * pvalue) { iparam_list *const iplist = (iparam_list *) plist; iparam_loc loc; ref aref; int code = ref_param_read_array(iplist, pkey, &loc); gs_param_string *psv; uint size; long i; if (code != 0) return code; size = r_size(loc.pvalue); psv = (gs_param_string *) gs_alloc_byte_array(plist->memory, size, sizeof(gs_param_string), "ref_param_read_string_array"); if (psv == 0) return_error(e_VMerror); aref = *loc.pvalue; if (r_has_type(&aref, t_array)) { for (i = 0; code >= 0 && i < size; i++) { loc.pvalue = aref.value.refs + i; code = ref_param_read_string_value(plist->memory, &loc, psv + i); } } else { ref elt; loc.pvalue = &elt; for (i = 0; code >= 0 && i < size; i++) { array_get(plist->memory, &aref, i, &elt); code = ref_param_read_string_value(plist->memory, &loc, psv + i); } } if (code < 0) { gs_free_object(plist->memory, psv, "ref_param_read_string_array"); return (*loc.presult = code); } pvalue->data = psv; pvalue->size = size; pvalue->persistent = true; 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; }
/* See pxoper.h for details. */ static int px_save_array(px_value_t * pv, px_state_t * pxs, client_name_t cname, uint nbytes) { if (pv->type & pxd_on_heap) { /* Turn off the "on heap" bit, to prevent freeing. */ pv->type &= ~pxd_on_heap; } else { /* Allocate a heap copy. Only the first nbytes bytes */ /* of the data are valid. */ uint num_elements = pv->value.array.size; uint elt_size = value_size(pv); byte *copy = gs_alloc_byte_array(pxs->memory, num_elements, elt_size, cname); if (copy == 0) return_error(errorInsufficientMemory); memcpy(copy, pv->value.array.data, nbytes); pv->value.array.data = copy; } return 0; }
/* * Similar to fn_build_float_array() except * - numeric parameter is accepted and converted to 1-element array * - number of elements is not checked for even/odd */ int fn_build_float_array_forced(const ref * op, const char *kstr, bool required, const float **pparray, gs_memory_t *mem) { ref *par; int code; uint size; float *ptr; *pparray = 0; if (dict_find_string(op, kstr, &par) <= 0) return (required ? gs_note_error(gs_error_rangecheck) : 0); if( r_is_array(par) ) size = r_size(par); else if(r_type(par) == t_integer || r_type(par) == t_real) size = 1; else return_error(gs_error_typecheck); ptr = (float *)gs_alloc_byte_array(mem, size, sizeof(float), kstr); if (ptr == 0) return_error(gs_error_VMerror); if(r_is_array(par) ) code = dict_float_array_check_param(mem, op, kstr, size, ptr, NULL, 0, gs_error_rangecheck); else { code = dict_float_param(op, kstr, 0., ptr); /* defailt cannot happen */ if( code == 0 ) code = 1; } if (code < 0 ) { gs_free_object(mem, ptr, kstr); return code; } *pparray = ptr; return code; }
/* <array> <offset> setdash - */ static int zsetdash(i_ctx_t *i_ctx_p) { os_ptr op = osp; os_ptr op1 = op - 1; double offset; int code = real_param(op, &offset); uint i, n; gs_memory_t *mem = imemory; float *pattern; if (code < 0) return_op_typecheck(op); if (!r_is_array(op1)) return_op_typecheck(op1); /* Adobe interpreters apparently don't check the array for */ /* read access, so we won't either. */ /*check_read(*op1); */ /* Unpack the dash pattern and check it */ n = r_size(op1); pattern = (float *)gs_alloc_byte_array(mem, n, sizeof(float), "setdash"); if (pattern == 0) return_error(e_VMerror); for (i = 0, code = 0; i < n && code >= 0; ++i) { ref element; array_get(mem, op1, (long)i, &element); code = float_param(&element, &pattern[i]); } if (code >= 0) code = gs_setdash(igs, pattern, n, offset); gs_free_object(mem, pattern, "setdash"); /* gs_setdash copies this */ if (code < 0) return code; ref_assign(&istate->dash_pattern_array, op1); pop(2); return code; }
static int ref_param_read_int_array(gs_param_list * plist, gs_param_name pkey, gs_param_int_array * pvalue) { iparam_list *const iplist = (iparam_list *) plist; iparam_loc loc; int code = ref_param_read_array(iplist, pkey, &loc); int *piv; uint size; long i; if (code != 0) return code; size = r_size(loc.pvalue); piv = (int *)gs_alloc_byte_array(plist->memory, size, sizeof(int), "ref_param_read_int_array"); if (piv == 0) return_error(e_VMerror); for (i = 0; i < size; i++) { ref elt; array_get(plist->memory, loc.pvalue, i, &elt); if (!r_has_type(&elt, t_integer)) { code = gs_note_error(e_typecheck); break; } piv[i] = (int)elt.value.intval; } if (code < 0) { gs_free_object(plist->memory, piv, "ref_param_read_int_array"); return (*loc.presult = code); } pvalue->data = piv; pvalue->size = size; pvalue->persistent = true; return 0; }
/* * Allocate an indexed map for an Indexed or Separation color space. */ int alloc_indexed_map(gs_indexed_map ** ppmap, int nvals, gs_memory_t * pmem, client_name_t cname) { gs_indexed_map *pimap; rc_alloc_struct_1(pimap, gs_indexed_map, &st_indexed_map, pmem, return_error(gs_error_VMerror), cname); if (nvals > 0) { pimap->values = (float *)gs_alloc_byte_array(pmem, nvals, sizeof(float), cname); if (pimap->values == 0) { gs_free_object(pmem, pimap, cname); return_error(gs_error_VMerror); } } else pimap->values = 0; pimap->rc.free = free_indexed_map; pimap->proc_data = 0; /* for GC */ pimap->num_values = nvals; *ppmap = pimap; return 0; }
/* Initialize for reading parameters. */ static int ref_param_read_init(iparam_list * plist, uint count, const ref * ppolicies, bool require_all, gs_ref_memory_t *imem) { gs_param_list_init((gs_param_list *)plist, &ref_read_procs, (gs_memory_t *)imem); plist->ref_memory = imem; if (ppolicies == 0) make_null(&plist->u.r.policies); else plist->u.r.policies = *ppolicies; plist->u.r.require_all = require_all; plist->count = count; plist->results = (int *) gs_alloc_byte_array(plist->memory, count, sizeof(int), "ref_param_read_init"); if (plist->results == 0) return_error(e_VMerror); memset(plist->results, 0, count * sizeof(int)); plist->int_keys = false; return 0; }
void* _cmsCalloc(unsigned int nelts, unsigned int size) { return gs_alloc_byte_array(gs_lib_ctx_get_non_gc_memory_t(), nelts, size, "lcms"); }
/* Send the page to the printer. For now, just send the whole image. */ static int ljet5_print_page(gx_device_printer * pdev, FILE * prn_stream) { gs_memory_t *mem = pdev->memory; uint line_size = gdev_mem_bytes_per_scan_line((gx_device *) pdev); uint line_size_words = (line_size + W - 1) / W; uint out_size = line_size + (line_size / 127) + 1; word *line = (word *)gs_alloc_byte_array(mem, line_size_words, W, "ljet5(line)"); byte *out = gs_alloc_bytes(mem, out_size, "ljet5(out)"); int code = 0; int lnum; stream fs; stream *const s = &fs; byte buf[200]; /* arbitrary */ if (line == 0 || out == 0) { code = gs_note_error(gs_error_VMerror); goto done; } s_init(s, mem); swrite_file(s, prn_stream, buf, sizeof(buf)); /* Write the page header. */ { static const byte page_header[] = { pxtBeginPage, DUSP(0, 0), DA(pxaPoint), pxtSetCursor }; static const byte mono_header[] = { DUB(eGray), DA(pxaColorSpace), DUB(e8Bit), DA(pxaPaletteDepth), pxt_ubyte_array, pxt_ubyte, 2, 0xff, 0x00, DA(pxaPaletteData), pxtSetColorSpace }; static const byte gray_header[] = { DUB(eGray), DA(pxaColorSpace), pxtSetColorSpace }; px_write_page_header(s, (gx_device *)pdev); px_write_select_media(s, (gx_device *)pdev, NULL, NULL, 0, false, false); PX_PUT_LIT(s, page_header); if (pdev->color_info.depth == 1) PX_PUT_LIT(s, mono_header); else PX_PUT_LIT(s, gray_header); } /* Write the image header. */ { static const byte mono_image_header[] = { DA(pxaDestinationSize), DUB(eIndexedPixel), DA(pxaColorMapping), DUB(e1Bit), DA(pxaColorDepth), pxtBeginImage }; static const byte gray_image_header[] = { DA(pxaDestinationSize), DUB(eDirectPixel), DA(pxaColorMapping), DUB(e8Bit), DA(pxaColorDepth), pxtBeginImage }; px_put_us(s, pdev->width); px_put_a(s, pxaSourceWidth); px_put_us(s, pdev->height); px_put_a(s, pxaSourceHeight); px_put_usp(s, pdev->width, pdev->height); if (pdev->color_info.depth == 1) PX_PUT_LIT(s, mono_image_header); else PX_PUT_LIT(s, gray_image_header); } /* Write the image data, compressing each line. */ for (lnum = 0; lnum < pdev->height; ++lnum) { int ncompr; static const byte line_header[] = { DA(pxaStartLine), DUS(1), DA(pxaBlockHeight), DUB(eRLECompression), DA(pxaCompressMode), pxtReadImage }; code = gdev_prn_copy_scan_lines(pdev, lnum, (byte *) line, line_size); if (code < 0) goto fin; px_put_us(s, lnum); PX_PUT_LIT(s, line_header); ncompr = gdev_pcl_mode2compress_padded(line, line + line_size_words, out, true); px_put_data_length(s, ncompr); px_put_bytes(s, out, ncompr); } /* Finish up. */ fin: spputc(s, pxtEndImage); spputc(s, pxtEndPage); sflush(s); done: gs_free_object(mem, out, "ljet5(out)"); gs_free_object(mem, line, "ljet5(line)"); return code; }
/* Set up and start the render threads */ static int clist_setup_render_threads(gx_device *dev, int y) { gx_device_printer *pdev = (gx_device_printer *)dev; gx_device_clist *cldev = (gx_device_clist *)dev; gx_device_clist_common *cdev = (gx_device_clist_common *)cldev; gx_device_clist_reader *crdev = &cldev->reader; gs_memory_t *mem = cdev->bandlist_memory; gx_device *protodev; gs_c_param_list paramlist; int i, code, band; int band_count = cdev->nbands; char fmode[4]; crdev->num_render_threads = pdev->num_render_threads_requested; if(gs_debug[':'] != 0) dprintf1("%% %d rendering threads requested.\n", pdev->num_render_threads_requested); if (crdev->num_render_threads > band_count) crdev->num_render_threads = band_count; /* don't bother starting more threads than bands */ /* Allocate and initialize an array of thread control structures */ crdev->render_threads = (clist_render_thread_control_t *) gs_alloc_byte_array(mem, crdev->num_render_threads, sizeof(clist_render_thread_control_t), "clist_setup_render_threads" ); /* fallback to non-threaded if allocation fails */ if (crdev->render_threads == NULL) { eprintf(" VMerror prevented threads from starting.\n"); return_error(gs_error_VMerror); } memset(crdev->render_threads, 0, crdev->num_render_threads * sizeof(clist_render_thread_control_t)); crdev->main_thread_data = cdev->data; /* save data area */ /* Based on the line number requested, decide the order of band rendering */ /* Almost all devices go in increasing line order (except the bmp* devices ) */ crdev->thread_lookahead_direction = (y < (cdev->height - 1)) ? 1 : -1; band = y / crdev->page_info.band_params.BandHeight; /* Close the files so we can open them in multiple threads */ if ((code = cdev->page_info.io_procs->fclose(cdev->page_cfile, cdev->page_cfname, false)) < 0 || (code = cdev->page_info.io_procs->fclose(cdev->page_bfile, cdev->page_bfname, false)) < 0) { gs_free_object(mem, crdev->render_threads, "clist_setup_render_threads"); crdev->render_threads = NULL; eprintf("Closing clist files prevented threads from starting.\n"); return_error(gs_error_unknownerror); /* shouldn't happen */ } cdev->page_cfile = cdev->page_bfile = NULL; strcpy(fmode, "r"); /* read access for threads */ strncat(fmode, gp_fmode_binary_suffix, 1); /* Find the prototype for this device (needed so we can copy from it) */ for (i=0; (protodev = (gx_device *)gs_getdevice(i)) != NULL; i++) if (strcmp(protodev->dname, dev->dname) == 0) break; if (protodev == NULL) { eprintf("Could not find prototype device. Rendering threads not started.\n"); return gs_error_rangecheck; } gs_c_param_list_write(¶mlist, mem); if ((code = gs_getdeviceparams(dev, (gs_param_list *)¶mlist)) < 0) { eprintf1("Error getting device params, code=%d. Rendering threads not started.\n", code); return code; } /* Loop creating the devices and semaphores for each thread, then start them */ for (i=0; (i < crdev->num_render_threads) && (band >= 0) && (band < band_count); i++, band += crdev->thread_lookahead_direction) { gx_device *ndev; gx_device_clist *ncldev; gx_device_clist_common *ncdev; clist_render_thread_control_t *thread = &(crdev->render_threads[i]); /* Every thread will have a 'chunk allocator' to reduce the interaction * with the 'base' allocator which has 'mutex' (locking) protection. * This improves performance of the threads. */ if ((code = gs_memory_chunk_wrap(&(thread->memory), mem )) < 0) { eprintf1("chunk_wrap returned error code: %d\n", code); break; } thread->band = -1; /* a value that won't match any valid band */ if ((code = gs_copydevice((gx_device **) &ndev, protodev, thread->memory)) < 0) { code = 0; /* even though we failed, no cleanup needed */ break; } ncldev = (gx_device_clist *)ndev; ncdev = (gx_device_clist_common *)ndev; gx_device_fill_in_procs(ndev); ((gx_device_printer *)ncdev)->buffer_memory = ncdev->memory = ncdev->bandlist_memory = thread->memory; gs_c_param_list_read(¶mlist); ndev->PageCount = dev->PageCount; /* copy to prevent mismatch error */ if ((code = gs_putdeviceparams(ndev, (gs_param_list *)¶mlist)) < 0) break; ncdev->page_uses_transparency = cdev->page_uses_transparency; /* gdev_prn_allocate_memory sets the clist for writing, creating new files. * We need to unlink those files and open the main thread's files, then * reset the clist state for reading/rendering */ if ((code = gdev_prn_allocate_memory(ndev, NULL, ndev->width, ndev->height)) < 0) break; thread->cdev = ndev; /* close and unlink the temp files just created */ cdev->page_info.io_procs->fclose(ncdev->page_cfile, ncdev->page_cfname, true); cdev->page_info.io_procs->fclose(ncdev->page_bfile, ncdev->page_bfname, true); /* open the main thread's files for this thread */ if ((code=cdev->page_info.io_procs->fopen(cdev->page_cfname, fmode, &ncdev->page_cfile, thread->memory, thread->memory, true)) < 0 || (code=cdev->page_info.io_procs->fopen(cdev->page_bfname, fmode, &ncdev->page_bfile, thread->memory, thread->memory, false)) < 0) break; clist_render_init(ncldev); /* Initialize clist device for reading */ ncdev->page_bfile_end_pos = cdev->page_bfile_end_pos; /* create the buf device for this thread, and allocate the semaphores */ if ((code = gdev_create_buf_device(cdev->buf_procs.create_buf_device, &(thread->bdev), cdev->target, band*crdev->page_band_height, NULL, thread->memory, clist_get_band_complexity(dev,y)) < 0)) break; if ((thread->sema_this = gx_semaphore_alloc(thread->memory)) == NULL || (thread->sema_group = gx_semaphore_alloc(thread->memory)) == NULL) { code = gs_error_VMerror; break; } /* Start thread 'i' to do band */ if ((code = clist_start_render_thread(dev, i, band)) < 0) break; } gs_c_param_list_release(¶mlist); /* If the code < 0, the last thread creation failed -- clean it up */ if (code < 0) { /* the following relies on 'free' ignoring NULL pointers */ gx_semaphore_free(crdev->render_threads[i].sema_group); gx_semaphore_free(crdev->render_threads[i].sema_this); if (crdev->render_threads[i].bdev != NULL) cdev->buf_procs.destroy_buf_device(crdev->render_threads[i].bdev); if (crdev->render_threads[i].cdev != NULL) { gx_device_clist_common *thread_cdev = (gx_device_clist_common *)crdev->render_threads[i].cdev; /* Close the file handles, but don't delete (unlink) the files */ thread_cdev->page_info.io_procs->fclose(thread_cdev->page_bfile, thread_cdev->page_bfname, false); thread_cdev->page_info.io_procs->fclose(thread_cdev->page_cfile, thread_cdev->page_cfname, false); thread_cdev->do_not_open_or_close_bandfiles = true; /* we already closed the files */ gdev_prn_free_memory((gx_device *)thread_cdev); gs_free_object(crdev->render_threads[i].memory, thread_cdev, "clist_setup_render_threads"); } if (crdev->render_threads[i].memory != NULL) gs_memory_chunk_release(crdev->render_threads[i].memory); } /* If we weren't able to create at least one thread, punt */ /* Although a single thread isn't any more efficient, the */ /* machinery still works, so that's OK. */ if (i == 0) { if (crdev->render_threads[0].memory != NULL) gs_memory_chunk_release(crdev->render_threads[0].memory); gs_free_object(mem, crdev->render_threads, "clist_setup_render_threads"); crdev->render_threads = NULL; /* restore the file pointers */ if (cdev->page_cfile == NULL) { char fmode[4]; strcpy(fmode, "a+"); /* file already exists and we want to re-use it */ strncat(fmode, gp_fmode_binary_suffix, 1); cdev->page_info.io_procs->fopen(cdev->page_cfname, fmode, &cdev->page_cfile, mem, cdev->bandlist_memory, true); cdev->page_info.io_procs->fseek(cdev->page_cfile, 0, SEEK_SET, cdev->page_cfname); cdev->page_info.io_procs->fopen(cdev->page_bfname, fmode, &cdev->page_bfile, mem, cdev->bandlist_memory, false); cdev->page_info.io_procs->fseek(cdev->page_bfile, 0, SEEK_SET, cdev->page_bfname); } eprintf1("Rendering threads not started, code=%d.\n", code); return_error(code); } crdev->num_render_threads = i; crdev->curr_render_thread = 0; if(gs_debug[':'] != 0) dprintf1("%% Using %d rendering threads\n", i); return 0; }
int gs_shading_LfGt_fill_rectangle(const gs_shading_t * psh0, const gs_rect * rect, const gs_fixed_rect * rect_clip, gx_device * dev, gs_imager_state * pis) { const gs_shading_LfGt_t * const psh = (const gs_shading_LfGt_t *)psh0; patch_fill_state_t pfs; const gs_shading_mesh_t *pshm = (const gs_shading_mesh_t *)psh; shade_coord_stream_t cs; shading_vertex_t *vertex = NULL; byte *color_buffer = NULL; patch_color_t **color_buffer_ptrs = NULL; /* non-const access to vertex[i].c */ shading_vertex_t next; int per_row = psh->params.VerticesPerRow; patch_color_t *c, *cn; /* cn == next.c always, provides a non-contst access. */ int i, code; if (VD_TRACE_TRIANGLE_PATCH && vd_allowed('s')) { vd_get_dc('s'); vd_set_shift(0, 0); vd_set_scale(0.01); vd_set_origin(0, 0); } shade_init_fill_state((shading_fill_state_t *)&pfs, (const gs_shading_t *)psh, dev, pis); pfs.Function = pshm->params.Function; pfs.rect = *rect_clip; code = init_patch_fill_state(&pfs); if (code < 0) goto out; reserve_colors(&pfs, &cn, 1); /* Can't fail. */ next.c = cn; shade_next_init(&cs, (const gs_shading_mesh_params_t *)&psh->params, pis); vertex = (shading_vertex_t *) gs_alloc_byte_array(pis->memory, per_row, sizeof(*vertex), "gs_shading_LfGt_render"); if (vertex == NULL) { code = gs_note_error(gs_error_VMerror); goto out; } color_buffer = gs_alloc_bytes(pis->memory, pfs.color_stack_step * per_row, "gs_shading_LfGt_fill_rectangle"); if (color_buffer == NULL) { code = gs_note_error(gs_error_VMerror); goto out; } color_buffer_ptrs = (patch_color_t **)gs_alloc_bytes(pis->memory, sizeof(patch_color_t *) * per_row, "gs_shading_LfGt_fill_rectangle"); if (color_buffer_ptrs == NULL) { code = gs_note_error(gs_error_VMerror); goto out; } /* CET 09-47K.PS SpecialTestJ02Test05 needs the color data alignment. */ for (i = 0; i < per_row; ++i) { color_buffer_ptrs[i] = (patch_color_t *)(color_buffer + pfs.color_stack_step * i); vertex[i].c = color_buffer_ptrs[i]; if ((code = Gt_next_vertex(pshm, &cs, &vertex[i], color_buffer_ptrs[i])) < 0) goto out; } while (!seofp(cs.s)) { code = Gt_next_vertex(pshm, &cs, &next, cn); if (code < 0) goto out; for (i = 1; i < per_row; ++i) { code = Gt_fill_triangle(&pfs, &vertex[i - 1], &vertex[i], &next); if (code < 0) goto out; c = color_buffer_ptrs[i - 1]; vertex[i - 1] = next; color_buffer_ptrs[i - 1] = cn; next.c = cn = c; code = Gt_next_vertex(pshm, &cs, &next, cn); if (code < 0) goto out; code = Gt_fill_triangle(&pfs, &vertex[i], &vertex[i - 1], &next); if (code < 0) goto out; } c = color_buffer_ptrs[per_row - 1]; vertex[per_row - 1] = next; color_buffer_ptrs[per_row - 1] = cn; next.c = cn = c; } out: if (VD_TRACE_TRIANGLE_PATCH && vd_allowed('s')) vd_release_dc; gs_free_object(pis->memory, vertex, "gs_shading_LfGt_render"); gs_free_object(pis->memory, color_buffer, "gs_shading_LfGt_render"); gs_free_object(pis->memory, color_buffer_ptrs, "gs_shading_LfGt_render"); release_colors(&pfs, pfs.color_stack, 1); if (term_patch_fill_state(&pfs)) return_error(gs_error_unregistered); /* Must not happen. */ if (pfs.icclink != NULL) gsicc_release_link(pfs.icclink); return code; }
/* Set up and start the render threads */ static int clist_setup_render_threads(gx_device *dev, int y, gx_process_page_options_t *options) { gx_device_printer *pdev = (gx_device_printer *)dev; gx_device_clist *cldev = (gx_device_clist *)dev; gx_device_clist_common *cdev = (gx_device_clist_common *)cldev; gx_device_clist_reader *crdev = &cldev->reader; gs_memory_t *mem = cdev->bandlist_memory; gs_memory_t *chunk_base_mem = mem->thread_safe_memory; gs_memory_status_t mem_status; int i, band; int code = 0; int band_count = cdev->nbands; int band_height = crdev->page_info.band_params.BandHeight; crdev->num_render_threads = pdev->num_render_threads_requested; if(gs_debug[':'] != 0) dmprintf1(mem, "%% %d rendering threads requested.\n", pdev->num_render_threads_requested); if (crdev->num_render_threads > band_count) crdev->num_render_threads = band_count; /* don't bother starting more threads than bands */ /* Allocate and initialize an array of thread control structures */ crdev->render_threads = (clist_render_thread_control_t *) gs_alloc_byte_array(mem, crdev->num_render_threads, sizeof(clist_render_thread_control_t), "clist_setup_render_threads" ); /* fallback to non-threaded if allocation fails */ if (crdev->render_threads == NULL) { emprintf(mem, " VMerror prevented threads from starting.\n"); return_error(gs_error_VMerror); } memset(crdev->render_threads, 0, crdev->num_render_threads * sizeof(clist_render_thread_control_t)); crdev->main_thread_data = cdev->data; /* save data area */ /* Based on the line number requested, decide the order of band rendering */ /* Almost all devices go in increasing line order (except the bmp* devices ) */ crdev->thread_lookahead_direction = (y < (cdev->height - 1)) ? 1 : -1; band = y / band_height; /* If the 'mem' is not thread safe, we need to wrap it in a locking memory */ gs_memory_status(chunk_base_mem, &mem_status); if (mem_status.is_thread_safe == false) { return_error(gs_error_VMerror); } /* If we don't have one large enough already, create an icc cache list */ if (crdev->num_render_threads > crdev->icc_cache_list_len) { void *old = crdev->icc_cache_list; crdev->icc_cache_list = gs_alloc_byte_array(mem->thread_safe_memory, crdev->num_render_threads, sizeof(void*), "clist_render_setup_threads"); if (crdev->icc_cache_list == NULL) { crdev->icc_cache_list = NULL; return_error(gs_error_VMerror); } if (crdev->icc_cache_list_len > 0) memcpy(crdev->icc_cache_list, old, sizeof(void *)*crdev->icc_cache_list_len); memset(&crdev->icc_cache_list[crdev->icc_cache_list_len], 0, (crdev->num_render_threads - crdev->icc_cache_list_len) * sizeof(void *)); crdev->icc_cache_list_len = crdev->num_render_threads; gs_free_object(mem, old, "clist_render_setup_threads"); } /* Loop creating the devices and semaphores for each thread, then start them */ for (i=0; (i < crdev->num_render_threads) && (band >= 0) && (band < band_count); i++, band += crdev->thread_lookahead_direction) { gx_device *ndev; clist_render_thread_control_t *thread = &(crdev->render_threads[i]); ndev = setup_device_and_mem_for_thread(chunk_base_mem, dev, false, &crdev->icc_cache_list[i]); if (ndev == NULL) { code = gs_error_VMerror; /* set code to an error for cleanup after the loop */ break; } thread->cdev = ndev; thread->memory = ndev->memory; thread->band = -1; /* a value that won't match any valid band */ thread->options = options; thread->buffer = NULL; if (options && options->init_buffer_fn) { code = options->init_buffer_fn(options->arg, dev, thread->memory, dev->width, band_height, &thread->buffer); if (code < 0) break; } /* create the buf device for this thread, and allocate the semaphores */ if ((code = gdev_create_buf_device(cdev->buf_procs.create_buf_device, &(thread->bdev), ndev, band*crdev->page_band_height, NULL, thread->memory, &(crdev->color_usage_array[0])) < 0)) break; if ((thread->sema_this = gx_semaphore_alloc(thread->memory)) == NULL || (thread->sema_group = gx_semaphore_alloc(thread->memory)) == NULL) { code = gs_error_VMerror; break; } /* Start thread 'i' to do band */ if ((code = clist_start_render_thread(dev, i, band)) < 0) break; } /* If the code < 0, the last thread creation failed -- clean it up */ if (code < 0) { band -= crdev->thread_lookahead_direction; /* update for 'next_band' usage */ /* the following relies on 'free' ignoring NULL pointers */ gx_semaphore_free(crdev->render_threads[i].sema_group); gx_semaphore_free(crdev->render_threads[i].sema_this); if (crdev->render_threads[i].bdev != NULL) cdev->buf_procs.destroy_buf_device(crdev->render_threads[i].bdev); if (crdev->render_threads[i].cdev != NULL) { gx_device_clist_common *thread_cdev = (gx_device_clist_common *)crdev->render_threads[i].cdev; /* Close the file handles, but don't delete (unlink) the files */ thread_cdev->page_info.io_procs->fclose(thread_cdev->page_info.bfile, thread_cdev->page_info.bfname, false); thread_cdev->page_info.io_procs->fclose(thread_cdev->page_info.cfile, thread_cdev->page_info.cfname, false); thread_cdev->do_not_open_or_close_bandfiles = true; /* we already closed the files */ gdev_prn_free_memory((gx_device *)thread_cdev); gs_free_object(crdev->render_threads[i].memory, thread_cdev, "clist_setup_render_threads"); } if (crdev->render_threads[i].buffer != NULL && options && options->free_buffer_fn != NULL) { options->free_buffer_fn(options->arg, dev, crdev->render_threads[i].memory, crdev->render_threads[i].buffer); crdev->render_threads[i].buffer = NULL; } if (crdev->render_threads[i].memory != NULL) { gs_memory_chunk_release(crdev->render_threads[i].memory); crdev->render_threads[i].memory = NULL; } } /* If we weren't able to create at least one thread, punt */ /* Although a single thread isn't any more efficient, the */ /* machinery still works, so that's OK. */ if (i == 0) { if (crdev->render_threads[0].memory != NULL) { gs_memory_chunk_release(crdev->render_threads[0].memory); /* free up the locking wrapper if we allocated one */ if (chunk_base_mem != mem) { gs_memory_locked_release((gs_memory_locked_t *)chunk_base_mem); gs_free_object(mem, chunk_base_mem, "clist_setup_render_threads(locked allocator)"); } } gs_free_object(mem, crdev->render_threads, "clist_setup_render_threads"); crdev->render_threads = NULL; /* restore the file pointers */ if (cdev->page_info.cfile == NULL) { char fmode[4]; strcpy(fmode, "a+"); /* file already exists and we want to re-use it */ strncat(fmode, gp_fmode_binary_suffix, 1); cdev->page_info.io_procs->fopen(cdev->page_info.cfname, fmode, &cdev->page_info.cfile, mem, cdev->bandlist_memory, true); cdev->page_info.io_procs->fseek(cdev->page_info.cfile, 0, SEEK_SET, cdev->page_info.cfname); cdev->page_info.io_procs->fopen(cdev->page_info.bfname, fmode, &cdev->page_info.bfile, mem, cdev->bandlist_memory, false); cdev->page_info.io_procs->fseek(cdev->page_info.bfile, 0, SEEK_SET, cdev->page_info.bfname); } emprintf1(mem, "Rendering threads not started, code=%d.\n", code); return_error(code); } crdev->num_render_threads = i; crdev->curr_render_thread = 0; crdev->next_band = band; if(gs_debug[':'] != 0) dmprintf1(mem, "%% Using %d rendering threads\n", i); return 0; }
/* * Create a PDF color space corresponding to a PostScript color space. * For parameterless color spaces, set *pvalue to a (literal) string with * the color space name; for other color spaces, create a cos_array_t if * necessary and set *pvalue to refer to it. In the latter case, if * by_name is true, return a string /Rxxxx rather than a reference to * the actual object. * * If ppranges is not NULL, then if the domain of the color space had * to be scaled (to convert a CIEBased space to ICCBased), store a pointer * to the ranges in *ppranges, otherwise set *ppranges to 0. */ int pdf_color_space_named(gx_device_pdf *pdev, cos_value_t *pvalue, const gs_range_t **ppranges, const gs_color_space *pcs, const pdf_color_space_names_t *pcsn, bool by_name, const byte *res_name, int name_length) { gs_color_space_index csi = gs_color_space_get_index(pcs); cos_array_t *pca; cos_dict_t *pcd; cos_value_t v; const gs_cie_common *pciec; gs_function_t *pfn; const gs_range_t *ranges = 0; uint serialized_size; byte *serialized = NULL, serialized0[100]; pdf_resource_t *pres = NULL; int code; if (ppranges) *ppranges = 0; /* default */ switch (csi) { case gs_color_space_index_DeviceGray: cos_c_string_value(pvalue, pcsn->DeviceGray); return 0; case gs_color_space_index_DeviceRGB: cos_c_string_value(pvalue, pcsn->DeviceRGB); return 0; case gs_color_space_index_DeviceCMYK: cos_c_string_value(pvalue, pcsn->DeviceCMYK); return 0; case gs_color_space_index_Pattern: if (!pcs->params.pattern.has_base_space) { cos_c_string_value(pvalue, "/Pattern"); return 0; } break; case gs_color_space_index_CIEICC: /* * Take a special early exit for unrecognized ICCBased color spaces, * or for PDF 1.2 output (ICCBased color spaces date from PDF 1.3). */ if (pcs->params.icc.picc_info->picc == 0 || pdev->CompatibilityLevel < 1.3 ) { if (res_name != NULL) return 0; /* Ignore .includecolorspace */ return pdf_color_space( pdev, pvalue, ppranges, pcs->base_space, pcsn, by_name); } break; default: break; } if (pdev->params.ColorConversionStrategy == ccs_CMYK && csi != gs_color_space_index_DeviceCMYK && csi != gs_color_space_index_DeviceGray && csi != gs_color_space_index_Pattern) return_error(gs_error_rangecheck); if (pdev->params.ColorConversionStrategy == ccs_sRGB && csi != gs_color_space_index_DeviceRGB && csi != gs_color_space_index_DeviceGray && csi != gs_color_space_index_Pattern) return_error(gs_error_rangecheck); if (pdev->params.ColorConversionStrategy == ccs_Gray && csi != gs_color_space_index_DeviceGray && csi != gs_color_space_index_Pattern) return_error(gs_error_rangecheck); /* Check whether we already have a PDF object for this color space. */ if (pcs->id != gs_no_id) pres = pdf_find_resource_by_gs_id(pdev, resourceColorSpace, pcs->id); if (pres == NULL) { stream s; s_init(&s, pdev->memory); swrite_position_only(&s); code = cs_serialize(pcs, &s); if (code < 0) return_error(gs_error_unregistered); /* Must not happen. */ serialized_size = stell(&s); sclose(&s); if (serialized_size <= sizeof(serialized0)) serialized = serialized0; else { serialized = gs_alloc_bytes(pdev->pdf_memory, serialized_size, "pdf_color_space"); if (serialized == NULL) return_error(gs_error_VMerror); } swrite_string(&s, serialized, serialized_size); code = cs_serialize(pcs, &s); if (code < 0) return_error(gs_error_unregistered); /* Must not happen. */ if (stell(&s) != serialized_size) return_error(gs_error_unregistered); /* Must not happen. */ sclose(&s); pres = pdf_find_cspace_resource(pdev, serialized, serialized_size); if (pres != NULL) { if (serialized != serialized0) gs_free_object(pdev->pdf_memory, serialized, "pdf_color_space"); serialized = NULL; } } if (pres) { const pdf_color_space_t *const ppcs = (const pdf_color_space_t *)pres; if (ppranges != 0 && ppcs->ranges != 0) *ppranges = ppcs->ranges; pca = (cos_array_t *)pres->object; goto ret; } /* Space has parameters -- create an array. */ pca = cos_array_alloc(pdev, "pdf_color_space"); if (pca == 0) return_error(gs_error_VMerror); switch (csi) { case gs_color_space_index_CIEICC: code = pdf_iccbased_color_space(pdev, pvalue, pcs, pca); break; case gs_color_space_index_CIEA: { /* Check that we can represent this as a CalGray space. */ const gs_cie_a *pcie = pcs->params.a; bool unitary = cie_ranges_are_0_1(&pcie->RangeA, 1); bool identityA = (pcie->MatrixA.u == 1 && pcie->MatrixA.v == 1 && pcie->MatrixA.w == 1); gs_vector3 expts; pciec = (const gs_cie_common *)pcie; if (!pcie->common.MatrixLMN.is_identity) { code = pdf_convert_cie_space(pdev, pca, pcs, "GRAY", pciec, &pcie->RangeA, ONE_STEP_NOT, NULL, &ranges); break; } if (unitary && identityA && CIE_CACHE_IS_IDENTITY(&pcie->caches.DecodeA) && CIE_SCALAR3_CACHE_IS_EXPONENTIAL(pcie->common.caches.DecodeLMN, expts) && expts.v == expts.u && expts.w == expts.u ) { DO_NOTHING; } else if (unitary && identityA && CIE_CACHE3_IS_IDENTITY(pcie->common.caches.DecodeLMN) && cie_vector_cache_is_exponential(&pcie->caches.DecodeA, &expts.u) ) { DO_NOTHING; } else { code = pdf_convert_cie_space(pdev, pca, pcs, "GRAY", pciec, &pcie->RangeA, ONE_STEP_NOT, NULL, &ranges); break; } code = cos_array_add(pca, cos_c_string_value(&v, "/CalGray")); if (code < 0) return code; pcd = cos_dict_alloc(pdev, "pdf_color_space(dict)"); if (pcd == 0) return_error(gs_error_VMerror); if (expts.u != 1) { code = cos_dict_put_c_key_real(pcd, "/Gamma", expts.u); if (code < 0) return code; } } cal: /* Finish handling a CIE-based color space (Calxxx or Lab). */ if (code < 0) return code; code = pdf_finish_cie_space(pca, pcd, pciec); break; case gs_color_space_index_CIEABC: { /* Check that we can represent this as a CalRGB space. */ const gs_cie_abc *pcie = pcs->params.abc; bool unitary = cie_ranges_are_0_1(pcie->RangeABC.ranges, 3); gs_vector3 expts; const gs_matrix3 *pmat = NULL; cie_cache_one_step_t one_step = cie_cached_abc_is_one_step(pcie, &pmat); pciec = (const gs_cie_common *)pcie; if (unitary) { switch (one_step) { case ONE_STEP_ABC: if (CIE_VECTOR3_CACHE_IS_EXPONENTIAL(pcie->caches.DecodeABC.caches, expts)) goto calrgb; break; case ONE_STEP_LMN: if (CIE_SCALAR3_CACHE_IS_EXPONENTIAL(pcie->common.caches.DecodeLMN, expts)) goto calrgb; default: break; } } if (cie_is_lab(pcie)) { /* Represent this as a Lab space. */ pcd = cos_dict_alloc(pdev, "pdf_color_space(dict)"); if (pcd == 0) return_error(gs_error_VMerror); code = pdf_put_lab_color_space(pca, pcd, pcie->RangeABC.ranges); goto cal; } else { code = pdf_convert_cie_space(pdev, pca, pcs, "RGB ", pciec, pcie->RangeABC.ranges, one_step, pmat, &ranges); break; } calrgb: code = cos_array_add(pca, cos_c_string_value(&v, "/CalRGB")); if (code < 0) return code; pcd = cos_dict_alloc(pdev, "pdf_color_space(dict)"); if (pcd == 0) return_error(gs_error_VMerror); if (expts.u != 1 || expts.v != 1 || expts.w != 1) { code = cos_dict_put_c_key_vector3(pcd, "/Gamma", &expts); if (code < 0) return code; } if (!pmat->is_identity) { cos_array_t *pcma = cos_array_alloc(pdev, "pdf_color_space(Matrix)"); if (pcma == 0) return_error(gs_error_VMerror); if ((code = cos_array_add_vector3(pcma, &pmat->cu)) < 0 || (code = cos_array_add_vector3(pcma, &pmat->cv)) < 0 || (code = cos_array_add_vector3(pcma, &pmat->cw)) < 0 || (code = cos_dict_put(pcd, (const byte *)"/Matrix", 7, COS_OBJECT_VALUE(&v, pcma))) < 0 ) return code; } } goto cal; case gs_color_space_index_CIEDEF: code = pdf_convert_cie_space(pdev, pca, pcs, "RGB ", (const gs_cie_common *)pcs->params.def, pcs->params.def->RangeDEF.ranges, ONE_STEP_NOT, NULL, &ranges); break; case gs_color_space_index_CIEDEFG: code = pdf_convert_cie_space(pdev, pca, pcs, "CMYK", (const gs_cie_common *)pcs->params.defg, pcs->params.defg->RangeDEFG.ranges, ONE_STEP_NOT, NULL, &ranges); break; case gs_color_space_index_Indexed: code = pdf_indexed_color_space(pdev, pvalue, pcs, pca); break; case gs_color_space_index_DeviceN: if (pdev->CompatibilityLevel < 1.3) return_error(gs_error_rangecheck); pfn = gs_cspace_get_devn_function(pcs); /****** CURRENTLY WE ONLY HANDLE Functions ******/ if (pfn == 0) return_error(gs_error_rangecheck); { cos_array_t *psna = cos_array_alloc(pdev, "pdf_color_space(DeviceN)"); int i; byte *name_string; uint name_string_length; cos_value_t v_attriburtes, *va = NULL; if (psna == 0) return_error(gs_error_VMerror); for (i = 0; i < pcs->params.device_n.num_components; ++i) { if ((code = pcs->params.device_n.get_colorname_string( pdev->memory, pcs->params.device_n.names[i], &name_string, &name_string_length)) < 0 || (code = pdf_string_to_cos_name(pdev, name_string, name_string_length, &v)) < 0 || (code = cos_array_add_no_copy(psna, &v)) < 0) return code; } COS_OBJECT_VALUE(&v, psna); if (pcs->params.device_n.colorants != NULL) { cos_dict_t *colorants = cos_dict_alloc(pdev, "pdf_color_space(DeviceN)"); cos_value_t v_colorants, v_separation, v_colorant_name; const gs_device_n_attributes *csa; pdf_resource_t *pres_attributes; if (colorants == NULL) return_error(gs_error_VMerror); code = pdf_alloc_resource(pdev, resourceOther, 0, &pres_attributes, -1); if (code < 0) return code; cos_become(pres_attributes->object, cos_type_dict); COS_OBJECT_VALUE(&v_colorants, colorants); code = cos_dict_put((cos_dict_t *)pres_attributes->object, (const byte *)"/Colorants", 10, &v_colorants); if (code < 0) return code; for (csa = pcs->params.device_n.colorants; csa != NULL; csa = csa->next) { code = pcs->params.device_n.get_colorname_string(pdev->memory, csa->colorant_name, &name_string, &name_string_length); if (code < 0) return code; code = pdf_color_space(pdev, &v_separation, NULL, csa->cspace, pcsn, false); if (code < 0) return code; code = pdf_string_to_cos_name(pdev, name_string, name_string_length, &v_colorant_name); if (code < 0) return code; code = cos_dict_put(colorants, v_colorant_name.contents.chars.data, v_colorant_name.contents.chars.size, &v_separation); if (code < 0) return code; } code = pdf_substitute_resource(pdev, &pres_attributes, resourceOther, NULL, true); if (code < 0) return code; va = &v_attriburtes; COS_OBJECT_VALUE(va, pres_attributes->object); } if ((code = pdf_separation_color_space(pdev, pca, "/DeviceN", &v, pcs->base_space, pfn, &pdf_color_space_names, va)) < 0) return code; } break; case gs_color_space_index_Separation: pfn = gs_cspace_get_sepr_function(pcs); /****** CURRENTLY WE ONLY HANDLE Functions ******/ if (pfn == 0) return_error(gs_error_rangecheck); { byte *name_string; uint name_string_length; if ((code = pcs->params.separation.get_colorname_string( pdev->memory, pcs->params.separation.sep_name, &name_string, &name_string_length)) < 0 || (code = pdf_string_to_cos_name(pdev, name_string, name_string_length, &v)) < 0 || (code = pdf_separation_color_space(pdev, pca, "/Separation", &v, pcs->base_space, pfn, &pdf_color_space_names, NULL)) < 0) return code; } break; case gs_color_space_index_Pattern: if ((code = pdf_color_space(pdev, pvalue, ppranges, pcs->base_space, &pdf_color_space_names, false)) < 0 || (code = cos_array_add(pca, cos_c_string_value(&v, "/Pattern"))) < 0 || (code = cos_array_add(pca, pvalue)) < 0 ) return code; break; default: return_error(gs_error_rangecheck); } /* * Register the color space as a resource, since it must be referenced * by name rather than directly. */ { pdf_color_space_t *ppcs; if (code < 0 || (code = pdf_alloc_resource(pdev, resourceColorSpace, pcs->id, &pres, -1)) < 0 ) { COS_FREE(pca, "pdf_color_space"); return code; } pdf_reserve_object_id(pdev, pres, 0); if (res_name != NULL) { int l = min(name_length, sizeof(pres->rname) - 1); memcpy(pres->rname, res_name, l); pres->rname[l] = 0; } ppcs = (pdf_color_space_t *)pres; if (serialized == serialized0) { serialized = gs_alloc_bytes(pdev->pdf_memory, serialized_size, "pdf_color_space"); if (serialized == NULL) return_error(gs_error_VMerror); memcpy(serialized, serialized0, serialized_size); } ppcs->serialized = serialized; ppcs->serialized_size = serialized_size; if (ranges) { int num_comp = gs_color_space_num_components(pcs); gs_range_t *copy_ranges = (gs_range_t *) gs_alloc_byte_array(pdev->pdf_memory, num_comp, sizeof(gs_range_t), "pdf_color_space"); if (copy_ranges == 0) { COS_FREE(pca, "pdf_color_space"); return_error(gs_error_VMerror); } memcpy(copy_ranges, ranges, num_comp * sizeof(gs_range_t)); ppcs->ranges = copy_ranges; if (ppranges) *ppranges = copy_ranges; } else ppcs->ranges = 0; pca->id = pres->object->id; COS_FREE(pres->object, "pdf_color_space"); pres->object = (cos_object_t *)pca; cos_write_object(COS_OBJECT(pca), pdev); } ret: if (by_name) { /* Return a resource name rather than an object reference. */ discard(COS_RESOURCE_VALUE(pvalue, pca)); } else discard(COS_OBJECT_VALUE(pvalue, pca)); if (pres != NULL) { pres->where_used |= pdev->used_mask; code = pdf_add_resource(pdev, pdev->substream_Resources, "/ColorSpace", pres); if (code < 0) return code; } return 0; }
int dljet_mono_print_page_copies(gx_device_printer * pdev, FILE * prn_stream, int num_copies, int dots_per_inch, int features, const char *odd_page_init, const char *even_page_init, bool tumble) { int line_size = gdev_mem_bytes_per_scan_line((gx_device *) pdev); int line_size_words = (line_size + W - 1) / W; uint storage_size_words = line_size_words * 8; /* data, out_row, out_row_alt, prev_row */ word *storage; word *data_words, *out_row_words, *out_row_alt_words, *prev_row_words; #define data ((byte *)data_words) #define out_row ((byte *)out_row_words) #define out_row_alt ((byte *)out_row_alt_words) #define prev_row ((byte *)prev_row_words) byte *out_data; int x_dpi = (int)pdev->x_pixels_per_inch; int y_dpi = (int)pdev->y_pixels_per_inch; int y_dots_per_pixel = dots_per_inch / y_dpi; int num_rows = dev_print_scan_lines(pdev); int out_count; int compression = -1; static const char *const from2to3 = "\033*b3M"; static const char *const from3to2 = "\033*b2M"; int penalty_from2to3 = strlen(from2to3); int penalty_from3to2 = strlen(from3to2); int paper_size = gdev_pcl_paper_size((gx_device *) pdev); int code = 0; bool dup = pdev->Duplex; bool dupset = pdev->Duplex_set >= 0; if (num_copies != 1 && !(features & PCL_CAN_PRINT_COPIES)) return gx_default_print_page_copies(pdev, prn_stream, num_copies); storage = (ulong *)gs_alloc_byte_array(pdev->memory, storage_size_words, W, "hpjet_print_page"); if (storage == 0) /* can't allocate working area */ return_error(gs_error_VMerror); data_words = storage; out_row_words = data_words + (line_size_words * 2); out_row_alt_words = out_row_words + (line_size_words * 2); prev_row_words = out_row_alt_words + (line_size_words * 2); /* Clear temp storage */ memset(data, 0, storage_size_words * W); /* Initialize printer. */ if (pdev->PageCount == 0) { if (features & HACK__IS_A_LJET4PJL) { fputs("\033%-12345X@PJL\r\n@PJL ENTER LANGUAGE = PCL\r\n", prn_stream); } fputs("\033E", prn_stream); /* reset printer */ /* If the printer supports it, set the paper size */ /* based on the actual requested size. */ if (features & PCL_CAN_SET_PAPER_SIZE) { fprintf(prn_stream, "\033&l%dA", paper_size); } /* If printer can duplex, set duplex mode appropriately. */ if (features & PCL_HAS_DUPLEX) { if (dupset && dup && !tumble) fputs("\033&l1S", prn_stream); else if (dupset && dup && tumble) fputs("\033&l2S", prn_stream); else if (dupset && !dup) fputs("\033&l0S", prn_stream); else /* default to duplex for this printer */ fputs("\033&l1S", prn_stream); } } /* Put out per-page initialization. */ if (features & PCL_CAN_SET_PAPER_SIZE){ fprintf(prn_stream, "\033&l%dA", paper_size); } fputs("\033&l0o0l0E", prn_stream); if ((features & PCL_HAS_DUPLEX) && dupset && dup) { /* We are printing duplex, so change margins as needed */ if ((pdev->PageCount%2)==0) fputs(odd_page_init, prn_stream); else fputs(even_page_init, prn_stream); } else fputs(odd_page_init, prn_stream); fprintf(prn_stream, "\033&l%dX", num_copies); /* # of copies */ /* End raster graphics, position cursor at top. */ fputs("\033*rB\033*p0x0Y", prn_stream); /* The DeskJet and DeskJet Plus reset everything upon */ /* receiving \033*rB, so we must reinitialize graphics mode. */ if (features & PCL_END_GRAPHICS_DOES_RESET) { fputs(odd_page_init, prn_stream); /* Assume this does the right thing */ fprintf(prn_stream, "\033&l%dX", num_copies); /* # of copies */ } /* Set resolution. */ fprintf(prn_stream, "\033*t%dR", x_dpi); /* Send each scan line in turn */ { int lnum; int num_blank_lines = 0; word rmask = ~(word) 0 << (-pdev->width & (W * 8 - 1)); /* Transfer raster graphics. */ for (lnum = 0; lnum < num_rows; lnum++) { register word *end_data = data_words + line_size_words; code = gdev_prn_copy_scan_lines(pdev, lnum, (byte *) data, line_size); if (code < 0) break; /* Mask off 1-bits beyond the line width. */ end_data[-1] &= rmask; /* Remove trailing 0s. */ while (end_data > data_words && end_data[-1] == 0) end_data--; if (end_data == data_words) { /* Blank line */ num_blank_lines++; continue; } /* We've reached a non-blank line. */ /* Put out a spacing command if necessary. */ if (num_blank_lines == lnum) { /* We're at the top of a page. */ if (features & PCL_ANY_SPACING) { if (num_blank_lines > 0) fprintf(prn_stream, "\033*p+%dY", num_blank_lines * y_dots_per_pixel); /* Start raster graphics. */ fputs("\033*r1A", prn_stream); } else if (features & PCL_MODE_3_COMPRESSION) { /* Start raster graphics. */ fputs("\033*r1A", prn_stream); #if 1 /* don't waste paper */ if (num_blank_lines > 0) fputs("\033*b0W", prn_stream); num_blank_lines = 0; #else for (; num_blank_lines; num_blank_lines--) fputs("\033*b0W", prn_stream); #endif } else { /* Start raster graphics. */ fputs("\033*r1A", prn_stream); for (; num_blank_lines; num_blank_lines--) fputs("\033*bW", prn_stream); } } /* Skip blank lines if any */ else if (num_blank_lines != 0) { /* * Moving down from current position causes head motion * on the DeskJet, so if the number of lines is small, * we're better off printing blanks. */ /* * For Canon LBP4i and some others, <ESC>*b<n>Y doesn't * properly clear the seed row if we are in compression mode * 3. */ if ((num_blank_lines < MIN_SKIP_LINES && compression != 3) || !(features & PCL_ANY_SPACING) ) { bool mode_3ns = (features & PCL_MODE_3_COMPRESSION) && !(features & PCL_ANY_SPACING); if (mode_3ns && compression != 2) { /* Switch to mode 2 */ fputs(from3to2, prn_stream); compression = 2; } if (features & PCL_MODE_3_COMPRESSION) { /* Must clear the seed row. */ fputs("\033*b1Y", prn_stream); num_blank_lines--; } if (mode_3ns) { for (; num_blank_lines; num_blank_lines--) fputs("\033*b0W", prn_stream); } else { for (; num_blank_lines; num_blank_lines--) fputs("\033*bW", prn_stream); } } else if (features & PCL3_SPACING) { fprintf(prn_stream, "\033*p+%dY", num_blank_lines * y_dots_per_pixel); } else { fprintf(prn_stream, "\033*b%dY", num_blank_lines); } /* Clear the seed row (only matters for */ /* mode 3 compression). */ memset(prev_row, 0, line_size); } num_blank_lines = 0; /* Choose the best compression mode */ /* for this particular line. */ if (features & PCL_MODE_3_COMPRESSION) { /* Compression modes 2 and 3 are both */ /* available. Try both and see which one */ /* produces the least output data. */ int count3 = gdev_pcl_mode3compress(line_size, data, prev_row, out_row); int count2 = gdev_pcl_mode2compress(data_words, end_data, out_row_alt); int penalty3 = (compression == 3 ? 0 : penalty_from2to3); int penalty2 = (compression == 2 ? 0 : penalty_from3to2); if (count3 + penalty3 < count2 + penalty2) { if (compression != 3) fputs(from2to3, prn_stream); compression = 3; out_data = out_row; out_count = count3; } else { if (compression != 2) fputs(from3to2, prn_stream); compression = 2; out_data = out_row_alt; out_count = count2; } } else if (features & PCL_MODE_2_COMPRESSION) { out_data = out_row; out_count = gdev_pcl_mode2compress(data_words, end_data, out_row); } else { out_data = data; out_count = (byte *) end_data - data; } /* Transfer the data */ fprintf(prn_stream, "\033*b%dW", out_count); fwrite(out_data, sizeof(byte), out_count, prn_stream); } } /* end raster graphics and eject page */ fputs("\033*rB\f", prn_stream); /* free temporary storage */ gs_free_object(pdev->memory, storage, "hpjet_print_page"); return code; }
/* Return the number of elements to pop (>0) if OK, <0 if error. */ static int rect_get(local_rects_t * plr, os_ptr op, gs_memory_t *mem) { int format, code; uint n, count; gs_rect *pr; double rv[4]; switch (r_type(op)) { case t_array: case t_mixedarray: case t_shortarray: case t_string: code = num_array_format(op); if (code < 0) return code; format = code; count = num_array_size(op, format); if (count % 4) return_error(e_typecheck); count /= 4; break; default: /* better be 4 numbers */ code = num_params(op, 4, rv); if (code < 0) return code; plr->pr = plr->rl; plr->count = 1; plr->rl[0].q.x = (plr->rl[0].p.x = rv[0]) + rv[2]; plr->rl[0].q.y = (plr->rl[0].p.y = rv[1]) + rv[3]; return 4; } plr->count = count; if (count <= MAX_LOCAL_RECTS) pr = plr->rl; else { pr = (gs_rect *)gs_alloc_byte_array(mem, count, sizeof(gs_rect), "rect_get"); if (pr == 0) return_error(e_VMerror); } plr->pr = pr; for (n = 0; n < count; n++, pr++) { ref rnum; int i; for (i = 0; i < 4; i++) { code = num_array_get(mem, (const ref *)op, format, (n << 2) + i, &rnum); switch (code) { case t_integer: rv[i] = rnum.value.intval; break; case t_real: rv[i] = rnum.value.realval; break; default: /* code < 0 */ return code; } } pr->q.x = (pr->p.x = rv[0]) + rv[2]; pr->q.y = (pr->p.y = rv[1]) + rv[3]; } return 1; }
/* 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)); }